1 //===-- DynamicLoaderMacOSXDYLD.cpp -----------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 
11 #include "llvm/Support/MachO.h"
12 
13 #include "lldb/Breakpoint/StoppointCallbackContext.h"
14 #include "lldb/Core/DataBuffer.h"
15 #include "lldb/Core/DataBufferHeap.h"
16 #include "lldb/Core/Log.h"
17 #include "lldb/Core/Module.h"
18 #include "lldb/Core/ModuleSpec.h"
19 #include "lldb/Core/PluginManager.h"
20 #include "lldb/Core/Section.h"
21 #include "lldb/Core/State.h"
22 #include "lldb/Symbol/Function.h"
23 #include "lldb/Symbol/ObjectFile.h"
24 #include "lldb/Target/ObjCLanguageRuntime.h"
25 #include "lldb/Target/RegisterContext.h"
26 #include "lldb/Target/Target.h"
27 #include "lldb/Target/Thread.h"
28 #include "lldb/Target/ThreadPlanRunToAddress.h"
29 #include "lldb/Target/StackFrame.h"
30 
31 #include "DynamicLoaderMacOSXDYLD.h"
32 
33 //#define ENABLE_DEBUG_PRINTF // COMMENT THIS LINE OUT PRIOR TO CHECKIN
34 #ifdef ENABLE_DEBUG_PRINTF
35 #include <stdio.h>
36 #define DEBUG_PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__)
37 #else
38 #define DEBUG_PRINTF(fmt, ...)
39 #endif
40 
41 using namespace lldb;
42 using namespace lldb_private;
43 
44 /// FIXME - The ObjC Runtime trampoline handler doesn't really belong here.
45 /// I am putting it here so I can invoke it in the Trampoline code here, but
46 /// it should be moved to the ObjC Runtime support when it is set up.
47 
48 
49 DynamicLoaderMacOSXDYLD::DYLDImageInfo *
50 DynamicLoaderMacOSXDYLD::GetImageInfo (Module *module)
51 {
52     const UUID &module_uuid = module->GetUUID();
53     DYLDImageInfo::collection::iterator pos, end = m_dyld_image_infos.end();
54 
55     // First try just by UUID as it is the safest.
56     if (module_uuid.IsValid())
57     {
58         for (pos = m_dyld_image_infos.begin(); pos != end; ++pos)
59         {
60             if (pos->uuid == module_uuid)
61                 return &(*pos);
62         }
63 
64         if (m_dyld.uuid == module_uuid)
65             return &m_dyld;
66     }
67 
68     // Next try by platform path only for things that don't have a valid UUID
69     // since if a file has a valid UUID in real life it should also in the
70     // dyld info. This is the next safest because the paths in the dyld info
71     // are platform paths, not local paths. For local debugging platform == local
72     // paths.
73     const FileSpec &platform_file_spec = module->GetPlatformFileSpec();
74     for (pos = m_dyld_image_infos.begin(); pos != end; ++pos)
75     {
76         if (pos->file_spec == platform_file_spec && pos->uuid.IsValid() == false)
77             return &(*pos);
78     }
79 
80     if (m_dyld.file_spec == platform_file_spec && m_dyld.uuid.IsValid() == false)
81         return &m_dyld;
82 
83     return NULL;
84 }
85 
86 //----------------------------------------------------------------------
87 // Create an instance of this class. This function is filled into
88 // the plugin info class that gets handed out by the plugin factory and
89 // allows the lldb to instantiate an instance of this class.
90 //----------------------------------------------------------------------
91 DynamicLoader *
92 DynamicLoaderMacOSXDYLD::CreateInstance (Process* process, bool force)
93 {
94     bool create = force;
95     if (!create)
96     {
97         create = true;
98         Module* exe_module = process->GetTarget().GetExecutableModulePointer();
99         if (exe_module)
100         {
101             ObjectFile *object_file = exe_module->GetObjectFile();
102             if (object_file)
103             {
104                 create = (object_file->GetStrata() == ObjectFile::eStrataUser);
105             }
106         }
107 
108         if (create)
109         {
110             const llvm::Triple &triple_ref = process->GetTarget().GetArchitecture().GetTriple();
111             switch (triple_ref.getOS())
112             {
113                 case llvm::Triple::Darwin:
114                 case llvm::Triple::MacOSX:
115                 case llvm::Triple::IOS:
116                     create = triple_ref.getVendor() == llvm::Triple::Apple;
117                     break;
118                 default:
119                     create = false;
120                     break;
121             }
122         }
123     }
124 
125     if (create)
126         return new DynamicLoaderMacOSXDYLD (process);
127     return NULL;
128 }
129 
130 //----------------------------------------------------------------------
131 // Constructor
132 //----------------------------------------------------------------------
133 DynamicLoaderMacOSXDYLD::DynamicLoaderMacOSXDYLD (Process* process) :
134     DynamicLoader(process),
135     m_dyld(),
136     m_dyld_all_image_infos_addr(LLDB_INVALID_ADDRESS),
137     m_dyld_all_image_infos(),
138     m_dyld_all_image_infos_stop_id (UINT32_MAX),
139     m_break_id(LLDB_INVALID_BREAK_ID),
140     m_dyld_image_infos(),
141     m_dyld_image_infos_stop_id (UINT32_MAX),
142     m_mutex(Mutex::eMutexTypeRecursive)
143 {
144 }
145 
146 //----------------------------------------------------------------------
147 // Destructor
148 //----------------------------------------------------------------------
149 DynamicLoaderMacOSXDYLD::~DynamicLoaderMacOSXDYLD()
150 {
151     Clear(true);
152 }
153 
154 //------------------------------------------------------------------
155 /// Called after attaching a process.
156 ///
157 /// Allow DynamicLoader plug-ins to execute some code after
158 /// attaching to a process.
159 //------------------------------------------------------------------
160 void
161 DynamicLoaderMacOSXDYLD::DidAttach ()
162 {
163     PrivateInitialize(m_process);
164     LocateDYLD ();
165     SetNotificationBreakpoint ();
166 }
167 
168 //------------------------------------------------------------------
169 /// Called after attaching a process.
170 ///
171 /// Allow DynamicLoader plug-ins to execute some code after
172 /// attaching to a process.
173 //------------------------------------------------------------------
174 void
175 DynamicLoaderMacOSXDYLD::DidLaunch ()
176 {
177     PrivateInitialize(m_process);
178     LocateDYLD ();
179     SetNotificationBreakpoint ();
180 }
181 
182 
183 //----------------------------------------------------------------------
184 // Clear out the state of this class.
185 //----------------------------------------------------------------------
186 void
187 DynamicLoaderMacOSXDYLD::Clear (bool clear_process)
188 {
189     Mutex::Locker locker(m_mutex);
190 
191     if (m_process->IsAlive() && LLDB_BREAK_ID_IS_VALID(m_break_id))
192         m_process->ClearBreakpointSiteByID(m_break_id);
193 
194     if (clear_process)
195         m_process = NULL;
196     m_dyld.Clear(false);
197     m_dyld_all_image_infos_addr = LLDB_INVALID_ADDRESS;
198     m_dyld_all_image_infos.Clear();
199     m_break_id = LLDB_INVALID_BREAK_ID;
200     m_dyld_image_infos.clear();
201 }
202 
203 //----------------------------------------------------------------------
204 // Check if we have found DYLD yet
205 //----------------------------------------------------------------------
206 bool
207 DynamicLoaderMacOSXDYLD::DidSetNotificationBreakpoint() const
208 {
209     return LLDB_BREAK_ID_IS_VALID (m_break_id);
210 }
211 
212 //----------------------------------------------------------------------
213 // Try and figure out where dyld is by first asking the Process
214 // if it knows (which currently calls down in the the lldb::Process
215 // to get the DYLD info (available on SnowLeopard only). If that fails,
216 // then check in the default addresses.
217 //----------------------------------------------------------------------
218 bool
219 DynamicLoaderMacOSXDYLD::LocateDYLD()
220 {
221     if (m_dyld_all_image_infos_addr == LLDB_INVALID_ADDRESS)
222     {
223         // Check the image info addr as it might point to the
224         // mach header for dyld, or it might point to the
225         // dyld_all_image_infos struct
226         const addr_t shlib_addr = m_process->GetImageInfoAddress ();
227 
228         ByteOrder byte_order = m_process->GetTarget().GetArchitecture().GetByteOrder();
229         uint8_t buf[4];
230         DataExtractor data (buf, sizeof(buf), byte_order, 4);
231         Error error;
232         if (m_process->ReadMemory (shlib_addr, buf, 4, error) == 4)
233         {
234             uint32_t offset = 0;
235             uint32_t magic = data.GetU32 (&offset);
236             switch (magic)
237             {
238             case llvm::MachO::HeaderMagic32:
239             case llvm::MachO::HeaderMagic64:
240             case llvm::MachO::HeaderMagic32Swapped:
241             case llvm::MachO::HeaderMagic64Swapped:
242                 return ReadDYLDInfoFromMemoryAndSetNotificationCallback(shlib_addr);
243 
244             default:
245                 break;
246             }
247         }
248         // Maybe it points to the all image infos?
249         m_dyld_all_image_infos_addr = shlib_addr;
250     }
251 
252     if (m_dyld_all_image_infos_addr != LLDB_INVALID_ADDRESS)
253     {
254         if (ReadAllImageInfosStructure ())
255         {
256             if (m_dyld_all_image_infos.dyldImageLoadAddress != LLDB_INVALID_ADDRESS)
257                 return ReadDYLDInfoFromMemoryAndSetNotificationCallback (m_dyld_all_image_infos.dyldImageLoadAddress);
258             else
259                 return ReadDYLDInfoFromMemoryAndSetNotificationCallback (m_dyld_all_image_infos_addr & 0xfffffffffff00000ull);
260         }
261     }
262 
263     // Check some default values
264     Module *executable = m_process->GetTarget().GetExecutableModulePointer();
265 
266     if (executable)
267     {
268         const ArchSpec &exe_arch = executable->GetArchitecture();
269         if (exe_arch.GetAddressByteSize() == 8)
270         {
271             return ReadDYLDInfoFromMemoryAndSetNotificationCallback(0x7fff5fc00000ull);
272         }
273         else if (exe_arch.GetMachine() == llvm::Triple::arm || exe_arch.GetMachine() == llvm::Triple::thumb)
274         {
275             return ReadDYLDInfoFromMemoryAndSetNotificationCallback(0x2fe00000);
276         }
277         else
278         {
279             return ReadDYLDInfoFromMemoryAndSetNotificationCallback(0x8fe00000);
280         }
281     }
282     return false;
283 }
284 
285 ModuleSP
286 DynamicLoaderMacOSXDYLD::FindTargetModuleForDYLDImageInfo (const DYLDImageInfo &image_info, bool can_create, bool *did_create_ptr)
287 {
288     if (did_create_ptr)
289         *did_create_ptr = false;
290     ModuleList &target_images = m_process->GetTarget().GetImages();
291     ModuleSpec module_spec (image_info.file_spec, image_info.GetArchitecture ());
292     module_spec.GetUUID() = image_info.uuid;
293     ModuleSP module_sp (target_images.FindFirstModule (module_spec));
294 
295     if (module_sp && !module_spec.GetUUID().IsValid() && !module_sp->GetUUID().IsValid())
296     {
297         // No UUID, we must rely upon the cached module modification
298         // time and the modification time of the file on disk
299         if (module_sp->GetModificationTime() != module_sp->GetFileSpec().GetModificationTime())
300             module_sp.reset();
301     }
302 
303     if (!module_sp)
304     {
305         if (can_create)
306         {
307             module_sp = m_process->GetTarget().GetSharedModule (module_spec);
308             if (!module_sp || module_sp->GetObjectFile() == NULL)
309             {
310                 const bool add_image_to_target = true;
311                 const bool load_image_sections_in_target = false;
312                 module_sp = m_process->ReadModuleFromMemory (image_info.file_spec,
313                                                              image_info.address,
314                                                              add_image_to_target,
315                                                              load_image_sections_in_target);
316             }
317 
318             if (did_create_ptr)
319                 *did_create_ptr = (bool) module_sp;
320         }
321     }
322     return module_sp;
323 }
324 
325 //----------------------------------------------------------------------
326 // Assume that dyld is in memory at ADDR and try to parse it's load
327 // commands
328 //----------------------------------------------------------------------
329 bool
330 DynamicLoaderMacOSXDYLD::ReadDYLDInfoFromMemoryAndSetNotificationCallback(lldb::addr_t addr)
331 {
332     DataExtractor data; // Load command data
333     if (ReadMachHeader (addr, &m_dyld.header, &data))
334     {
335         if (m_dyld.header.filetype == llvm::MachO::HeaderFileTypeDynamicLinkEditor)
336         {
337             m_dyld.address = addr;
338             ModuleSP dyld_module_sp;
339             if (ParseLoadCommands (data, m_dyld, &m_dyld.file_spec))
340             {
341                 if (m_dyld.file_spec)
342                 {
343                     dyld_module_sp = FindTargetModuleForDYLDImageInfo (m_dyld, true, NULL);
344 
345                     if (dyld_module_sp)
346                         UpdateImageLoadAddress (dyld_module_sp.get(), m_dyld);
347                 }
348             }
349 
350             if (m_dyld_all_image_infos_addr == LLDB_INVALID_ADDRESS && dyld_module_sp.get())
351             {
352                 static ConstString g_dyld_all_image_infos ("dyld_all_image_infos");
353                 const Symbol *symbol = dyld_module_sp->FindFirstSymbolWithNameAndType (g_dyld_all_image_infos, eSymbolTypeData);
354                 if (symbol)
355                     m_dyld_all_image_infos_addr = symbol->GetAddress().GetLoadAddress(&m_process->GetTarget());
356             }
357 
358             // Update all image infos
359             InitializeFromAllImageInfos ();
360 
361             // If we didn't have an executable before, but now we do, then the
362             // dyld module shared pointer might be unique and we may need to add
363             // it again (since Target::SetExecutableModule() will clear the
364             // images). So append the dyld module back to the list if it is
365             /// unique!
366             if (dyld_module_sp && m_process->GetTarget().GetImages().AppendIfNeeded (dyld_module_sp))
367                 UpdateImageLoadAddress(dyld_module_sp.get(), m_dyld);
368 
369             return true;
370         }
371     }
372     return false;
373 }
374 
375 bool
376 DynamicLoaderMacOSXDYLD::NeedToLocateDYLD () const
377 {
378     return m_dyld_all_image_infos_addr == LLDB_INVALID_ADDRESS;
379 }
380 
381 bool
382 DynamicLoaderMacOSXDYLD::UpdateCommPageLoadAddress(Module *module)
383 {
384     bool changed = false;
385     if (module)
386     {
387         ObjectFile *image_object_file = module->GetObjectFile();
388         if (image_object_file)
389         {
390             SectionList *section_list = image_object_file->GetSectionList ();
391             if (section_list)
392             {
393                 uint32_t num_sections = section_list->GetSize();
394                 for (uint32_t i=0; i<num_sections; ++i)
395                 {
396                     SectionSP section_sp (section_list->GetSectionAtIndex (i));
397                     if (section_sp)
398                     {
399                         const addr_t new_section_load_addr = section_sp->GetFileAddress ();
400                         const addr_t old_section_load_addr = m_process->GetTarget().GetSectionLoadList().GetSectionLoadAddress (section_sp);
401                         if (old_section_load_addr == LLDB_INVALID_ADDRESS ||
402                             old_section_load_addr != new_section_load_addr)
403                         {
404                             if (m_process->GetTarget().GetSectionLoadList().SetSectionLoadAddress (section_sp, section_sp->GetFileAddress ()))
405                                 changed = true;
406                         }
407                     }
408                 }
409             }
410         }
411     }
412     return changed;
413 }
414 
415 //----------------------------------------------------------------------
416 // Update the load addresses for all segments in MODULE using the
417 // updated INFO that is passed in.
418 //----------------------------------------------------------------------
419 bool
420 DynamicLoaderMacOSXDYLD::UpdateImageLoadAddress (Module *module, DYLDImageInfo& info)
421 {
422     bool changed = false;
423     if (module)
424     {
425         ObjectFile *image_object_file = module->GetObjectFile();
426         if (image_object_file)
427         {
428             SectionList *section_list = image_object_file->GetSectionList ();
429             if (section_list)
430             {
431                 std::vector<uint32_t> inaccessible_segment_indexes;
432                 // We now know the slide amount, so go through all sections
433                 // and update the load addresses with the correct values.
434                 uint32_t num_segments = info.segments.size();
435                 for (uint32_t i=0; i<num_segments; ++i)
436                 {
437                     // Only load a segment if it has protections. Things like
438                     // __PAGEZERO don't have any protections, and they shouldn't
439                     // be slid
440                     SectionSP section_sp(section_list->FindSectionByName(info.segments[i].name));
441 
442                     if (info.segments[i].maxprot == 0)
443                     {
444                         inaccessible_segment_indexes.push_back(i);
445                     }
446                     else
447                     {
448                         const addr_t new_section_load_addr = info.segments[i].vmaddr + info.slide;
449                         static ConstString g_section_name_LINKEDIT ("__LINKEDIT");
450 
451                         if (section_sp)
452                         {
453                             // __LINKEDIT sections from files in the shared cache
454                             // can overlap so check to see what the segment name is
455                             // and pass "false" so we don't warn of overlapping
456                             // "Section" objects, and "true" for all other sections.
457                             const bool warn_multiple = section_sp->GetName() != g_section_name_LINKEDIT;
458 
459                             const addr_t old_section_load_addr = m_process->GetTarget().GetSectionLoadList().GetSectionLoadAddress (section_sp);
460                             if (old_section_load_addr == LLDB_INVALID_ADDRESS ||
461                                 old_section_load_addr != new_section_load_addr)
462                             {
463                                 if (m_process->GetTarget().GetSectionLoadList().SetSectionLoadAddress (section_sp, new_section_load_addr, warn_multiple))
464                                     changed = true;
465                             }
466                         }
467                         else
468                         {
469                             Host::SystemLog (Host::eSystemLogWarning,
470                                              "warning: unable to find and load segment named '%s' at 0x%llx in '%s/%s' in macosx dynamic loader plug-in.\n",
471                                              info.segments[i].name.AsCString("<invalid>"),
472                                              (uint64_t)new_section_load_addr,
473                                              image_object_file->GetFileSpec().GetDirectory().AsCString(),
474                                              image_object_file->GetFileSpec().GetFilename().AsCString());
475                         }
476                     }
477                 }
478 
479                 // If the loaded the file (it changed) and we have segments that
480                 // are not readable or writeable, add them to the invalid memory
481                 // region cache for the process. This will typically only be
482                 // the __PAGEZERO segment in the main executable. We might be able
483                 // to apply this more generally to more sections that have no
484                 // protections in the future, but for now we are going to just
485                 // do __PAGEZERO.
486                 if (changed && !inaccessible_segment_indexes.empty())
487                 {
488                     for (uint32_t i=0; i<inaccessible_segment_indexes.size(); ++i)
489                     {
490                         const uint32_t seg_idx = inaccessible_segment_indexes[i];
491                         SectionSP section_sp(section_list->FindSectionByName(info.segments[seg_idx].name));
492 
493                         if (section_sp)
494                         {
495                             static ConstString g_pagezero_section_name("__PAGEZERO");
496                             if (g_pagezero_section_name == section_sp->GetName())
497                             {
498                                 // __PAGEZERO never slides...
499                                 const lldb::addr_t vmaddr = info.segments[seg_idx].vmaddr;
500                                 const lldb::addr_t vmsize = info.segments[seg_idx].vmsize;
501                                 Process::LoadRange pagezero_range (vmaddr, vmsize);
502                                 m_process->AddInvalidMemoryRegion(pagezero_range);
503                             }
504                         }
505                     }
506                 }
507             }
508         }
509     }
510     return changed;
511 }
512 
513 //----------------------------------------------------------------------
514 // Update the load addresses for all segments in MODULE using the
515 // updated INFO that is passed in.
516 //----------------------------------------------------------------------
517 bool
518 DynamicLoaderMacOSXDYLD::UnloadImageLoadAddress (Module *module, DYLDImageInfo& info)
519 {
520     bool changed = false;
521     if (module)
522     {
523         ObjectFile *image_object_file = module->GetObjectFile();
524         if (image_object_file)
525         {
526             SectionList *section_list = image_object_file->GetSectionList ();
527             if (section_list)
528             {
529                 uint32_t num_segments = info.segments.size();
530                 for (uint32_t i=0; i<num_segments; ++i)
531                 {
532                     SectionSP section_sp(section_list->FindSectionByName(info.segments[i].name));
533                     if (section_sp)
534                     {
535                         const addr_t old_section_load_addr = info.segments[i].vmaddr + info.slide;
536                         if (m_process->GetTarget().GetSectionLoadList().SetSectionUnloaded (section_sp, old_section_load_addr))
537                             changed = true;
538                     }
539                     else
540                     {
541                         Host::SystemLog (Host::eSystemLogWarning,
542                                          "warning: unable to find and unload segment named '%s' in '%s/%s' in macosx dynamic loader plug-in.\n",
543                                          info.segments[i].name.AsCString("<invalid>"),
544                                          image_object_file->GetFileSpec().GetDirectory().AsCString(),
545                                          image_object_file->GetFileSpec().GetFilename().AsCString());
546                     }
547                 }
548             }
549         }
550     }
551     return changed;
552 }
553 
554 
555 //----------------------------------------------------------------------
556 // Static callback function that gets called when our DYLD notification
557 // breakpoint gets hit. We update all of our image infos and then
558 // let our super class DynamicLoader class decide if we should stop
559 // or not (based on global preference).
560 //----------------------------------------------------------------------
561 bool
562 DynamicLoaderMacOSXDYLD::NotifyBreakpointHit (void *baton,
563                                               StoppointCallbackContext *context,
564                                               lldb::user_id_t break_id,
565                                               lldb::user_id_t break_loc_id)
566 {
567     // Let the event know that the images have changed
568     // DYLD passes three arguments to the notification breakpoint.
569     // Arg1: enum dyld_image_mode mode - 0 = adding, 1 = removing
570     // Arg2: uint32_t infoCount        - Number of shared libraries added
571     // Arg3: dyld_image_info info[]    - Array of structs of the form:
572     //                                     const struct mach_header *imageLoadAddress
573     //                                     const char               *imageFilePath
574     //                                     uintptr_t                 imageFileModDate (a time_t)
575 
576     DynamicLoaderMacOSXDYLD* dyld_instance = (DynamicLoaderMacOSXDYLD*) baton;
577 
578     // First step is to see if we've already initialized the all image infos.  If we haven't then this function
579     // will do so and return true.  In the course of initializing the all_image_infos it will read the complete
580     // current state, so we don't need to figure out what has changed from the data passed in to us.
581 
582     if (dyld_instance->InitializeFromAllImageInfos())
583         return dyld_instance->GetStopWhenImagesChange();
584 
585     ExecutionContext exe_ctx (context->exe_ctx_ref);
586     Process *process = exe_ctx.GetProcessPtr();
587     const lldb::ABISP &abi = process->GetABI();
588     if (abi)
589     {
590         // Build up the value array to store the three arguments given above, then get the values from the ABI:
591 
592         ClangASTContext *clang_ast_context = process->GetTarget().GetScratchClangASTContext();
593         ValueList argument_values;
594         Value input_value;
595 
596         void *clang_void_ptr_type = clang_ast_context->GetVoidPtrType(false);
597         void *clang_uint32_type   = clang_ast_context->GetBuiltinTypeForEncodingAndBitSize(lldb::eEncodingUint, 32);
598         input_value.SetValueType (Value::eValueTypeScalar);
599         input_value.SetContext (Value::eContextTypeClangType, clang_uint32_type);
600         argument_values.PushValue(input_value);
601         argument_values.PushValue(input_value);
602         input_value.SetContext (Value::eContextTypeClangType, clang_void_ptr_type);
603         argument_values.PushValue (input_value);
604 
605         if (abi->GetArgumentValues (exe_ctx.GetThreadRef(), argument_values))
606         {
607             uint32_t dyld_mode = argument_values.GetValueAtIndex(0)->GetScalar().UInt (-1);
608             if (dyld_mode != -1)
609             {
610                 // Okay the mode was right, now get the number of elements, and the array of new elements...
611                 uint32_t image_infos_count = argument_values.GetValueAtIndex(1)->GetScalar().UInt (-1);
612                 if (image_infos_count != -1)
613                 {
614                     // Got the number added, now go through the array of added elements, putting out the mach header
615                     // address, and adding the image.
616                     // Note, I'm not putting in logging here, since the AddModules & RemoveModules functions do
617                     // all the logging internally.
618 
619                     lldb::addr_t image_infos_addr = argument_values.GetValueAtIndex(2)->GetScalar().ULongLong();
620                     if (dyld_mode == 0)
621                     {
622                         // This is add:
623                         dyld_instance->AddModulesUsingImageInfosAddress (image_infos_addr, image_infos_count);
624                     }
625                     else
626                     {
627                         // This is remove:
628                         dyld_instance->RemoveModulesUsingImageInfosAddress (image_infos_addr, image_infos_count);
629                     }
630 
631                 }
632             }
633         }
634     }
635 
636     // Return true to stop the target, false to just let the target run
637     return dyld_instance->GetStopWhenImagesChange();
638 }
639 
640 bool
641 DynamicLoaderMacOSXDYLD::ReadAllImageInfosStructure ()
642 {
643     Mutex::Locker locker(m_mutex);
644 
645     // the all image infos is already valid for this process stop ID
646     if (m_process->GetStopID() == m_dyld_all_image_infos_stop_id)
647         return true;
648 
649     m_dyld_all_image_infos.Clear();
650     if (m_dyld_all_image_infos_addr != LLDB_INVALID_ADDRESS)
651     {
652         ByteOrder byte_order = m_process->GetTarget().GetArchitecture().GetByteOrder();
653         uint32_t addr_size = 4;
654         if (m_dyld_all_image_infos_addr > UINT32_MAX)
655             addr_size = 8;
656 
657         uint8_t buf[256];
658         DataExtractor data (buf, sizeof(buf), byte_order, addr_size);
659         uint32_t offset = 0;
660 
661         const size_t count_v2 =  sizeof (uint32_t) + // version
662                                  sizeof (uint32_t) + // infoArrayCount
663                                  addr_size +         // infoArray
664                                  addr_size +         // notification
665                                  addr_size +         // processDetachedFromSharedRegion + libSystemInitialized + pad
666                                  addr_size;          // dyldImageLoadAddress
667         const size_t count_v11 = count_v2 +
668                                  addr_size +         // jitInfo
669                                  addr_size +         // dyldVersion
670                                  addr_size +         // errorMessage
671                                  addr_size +         // terminationFlags
672                                  addr_size +         // coreSymbolicationShmPage
673                                  addr_size +         // systemOrderFlag
674                                  addr_size +         // uuidArrayCount
675                                  addr_size +         // uuidArray
676                                  addr_size +         // dyldAllImageInfosAddress
677                                  addr_size +         // initialImageCount
678                                  addr_size +         // errorKind
679                                  addr_size +         // errorClientOfDylibPath
680                                  addr_size +         // errorTargetDylibPath
681                                  addr_size;          // errorSymbol
682         assert (sizeof (buf) >= count_v11);
683 
684         int count;
685         Error error;
686         if (m_process->ReadMemory (m_dyld_all_image_infos_addr, buf, 4, error) == 4)
687         {
688             m_dyld_all_image_infos.version = data.GetU32(&offset);
689             // If anything in the high byte is set, we probably got the byte
690             // order incorrect (the process might not have it set correctly
691             // yet due to attaching to a program without a specified file).
692             if (m_dyld_all_image_infos.version & 0xff000000)
693             {
694                 // We have guessed the wrong byte order. Swap it and try
695                 // reading the version again.
696                 if (byte_order == eByteOrderLittle)
697                     byte_order = eByteOrderBig;
698                 else
699                     byte_order = eByteOrderLittle;
700 
701                 data.SetByteOrder (byte_order);
702                 offset = 0;
703                 m_dyld_all_image_infos.version = data.GetU32(&offset);
704             }
705         }
706         else
707         {
708             return false;
709         }
710 
711         if (m_dyld_all_image_infos.version >= 11)
712             count = count_v11;
713         else
714             count = count_v2;
715 
716         const size_t bytes_read = m_process->ReadMemory (m_dyld_all_image_infos_addr, buf, count, error);
717         if (bytes_read == count)
718         {
719             offset = 0;
720             m_dyld_all_image_infos.version = data.GetU32(&offset);
721             m_dyld_all_image_infos.dylib_info_count = data.GetU32(&offset);
722             m_dyld_all_image_infos.dylib_info_addr = data.GetPointer(&offset);
723             m_dyld_all_image_infos.notification = data.GetPointer(&offset);
724             m_dyld_all_image_infos.processDetachedFromSharedRegion = data.GetU8(&offset);
725             m_dyld_all_image_infos.libSystemInitialized = data.GetU8(&offset);
726             // Adjust for padding.
727             offset += addr_size - 2;
728             m_dyld_all_image_infos.dyldImageLoadAddress = data.GetPointer(&offset);
729             if (m_dyld_all_image_infos.version >= 11)
730             {
731                 offset += addr_size * 8;
732                 uint64_t dyld_all_image_infos_addr = data.GetPointer(&offset);
733 
734                 // When we started, we were given the actual address of the all_image_infos
735                 // struct (probably via TASK_DYLD_INFO) in memory - this address is stored in
736                 // m_dyld_all_image_infos_addr and is the most accurate address we have.
737 
738                 // We read the dyld_all_image_infos struct from memory; it contains its own address.
739                 // If the address in the struct does not match the actual address,
740                 // the dyld we're looking at has been loaded at a different location (slid) from
741                 // where it intended to load.  The addresses in the dyld_all_image_infos struct
742                 // are the original, non-slid addresses, and need to be adjusted.  Most importantly
743                 // the address of dyld and the notification address need to be adjusted.
744 
745                 if (dyld_all_image_infos_addr != m_dyld_all_image_infos_addr)
746                 {
747                     uint64_t image_infos_offset = dyld_all_image_infos_addr - m_dyld_all_image_infos.dyldImageLoadAddress;
748                     uint64_t notification_offset = m_dyld_all_image_infos.notification - m_dyld_all_image_infos.dyldImageLoadAddress;
749                     m_dyld_all_image_infos.dyldImageLoadAddress = m_dyld_all_image_infos_addr - image_infos_offset;
750                     m_dyld_all_image_infos.notification = m_dyld_all_image_infos.dyldImageLoadAddress + notification_offset;
751                 }
752             }
753             m_dyld_all_image_infos_stop_id = m_process->GetStopID();
754             return true;
755         }
756     }
757     return false;
758 }
759 
760 
761 bool
762 DynamicLoaderMacOSXDYLD::AddModulesUsingImageInfosAddress (lldb::addr_t image_infos_addr, uint32_t image_infos_count)
763 {
764     DYLDImageInfo::collection image_infos;
765     LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
766     if (log)
767         log->Printf ("Adding %d modules.\n", image_infos_count);
768 
769     Mutex::Locker locker(m_mutex);
770     if (m_process->GetStopID() == m_dyld_image_infos_stop_id)
771         return true;
772 
773     if (!ReadImageInfos (image_infos_addr, image_infos_count, image_infos))
774         return false;
775 
776     UpdateImageInfosHeaderAndLoadCommands (image_infos, image_infos_count, false);
777     bool return_value = AddModulesUsingImageInfos (image_infos);
778     m_dyld_image_infos_stop_id = m_process->GetStopID();
779     return return_value;
780 }
781 
782 // Adds the modules in image_infos to m_dyld_image_infos.
783 // NB don't call this passing in m_dyld_image_infos.
784 
785 bool
786 DynamicLoaderMacOSXDYLD::AddModulesUsingImageInfos (DYLDImageInfo::collection &image_infos)
787 {
788     // Now add these images to the main list.
789     ModuleList loaded_module_list;
790     LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
791 
792     for (uint32_t idx = 0; idx < image_infos.size(); ++idx)
793     {
794         if (log)
795         {
796             log->Printf ("Adding new image at address=0x%16.16llx.", image_infos[idx].address);
797             image_infos[idx].PutToLog (log.get());
798         }
799 
800         m_dyld_image_infos.push_back(image_infos[idx]);
801 
802         ModuleSP image_module_sp (FindTargetModuleForDYLDImageInfo (image_infos[idx], true, NULL));
803 
804         if (image_module_sp)
805         {
806             if (image_infos[idx].header.filetype == llvm::MachO::HeaderFileTypeDynamicLinkEditor)
807                 image_module_sp->SetIsDynamicLinkEditor (true);
808 
809             ObjectFile *objfile = image_module_sp->GetObjectFile ();
810             if (objfile)
811             {
812                 SectionList *sections = objfile->GetSectionList();
813                 if (sections)
814                 {
815                     ConstString commpage_dbstr("__commpage");
816                     Section *commpage_section = sections->FindSectionByName(commpage_dbstr).get();
817                     if (commpage_section)
818                     {
819                         ModuleList& target_images = m_process->GetTarget().GetImages();
820                         ModuleSpec module_spec (objfile->GetFileSpec(), image_infos[idx].GetArchitecture ());
821                         module_spec.GetObjectName() = commpage_dbstr;
822                         ModuleSP commpage_image_module_sp(target_images.FindFirstModule (module_spec));
823                         if (!commpage_image_module_sp)
824                         {
825                             module_spec.SetObjectOffset (objfile->GetOffset() + commpage_section->GetFileOffset());
826                             commpage_image_module_sp  = m_process->GetTarget().GetSharedModule (module_spec);
827                             if (!commpage_image_module_sp || commpage_image_module_sp->GetObjectFile() == NULL)
828                             {
829                                 const bool add_image_to_target = true;
830                                 const bool load_image_sections_in_target = false;
831                                 commpage_image_module_sp = m_process->ReadModuleFromMemory (image_infos[idx].file_spec,
832                                                                                             image_infos[idx].address,
833                                                                                             add_image_to_target,
834                                                                                             load_image_sections_in_target);
835                             }
836                         }
837                         if (commpage_image_module_sp)
838                             UpdateCommPageLoadAddress (commpage_image_module_sp.get());
839                     }
840                 }
841             }
842 
843             // UpdateImageLoadAddress will return true if any segments
844             // change load address. We need to check this so we don't
845             // mention that all loaded shared libraries are newly loaded
846             // each time we hit out dyld breakpoint since dyld will list all
847             // shared libraries each time.
848             if (UpdateImageLoadAddress (image_module_sp.get(), image_infos[idx]))
849             {
850                 loaded_module_list.AppendIfNeeded (image_module_sp);
851             }
852         }
853     }
854 
855     if (loaded_module_list.GetSize() > 0)
856     {
857         // FIXME: This should really be in the Runtime handlers class, which should get
858         // called by the target's ModulesDidLoad, but we're doing it all locally for now
859         // to save time.
860         // Also, I'm assuming there can be only one libobjc dylib loaded...
861 
862         ObjCLanguageRuntime *objc_runtime = m_process->GetObjCLanguageRuntime(true);
863         if (objc_runtime != NULL && !objc_runtime->HasReadObjCLibrary())
864         {
865             size_t num_modules = loaded_module_list.GetSize();
866             for (int i = 0; i < num_modules; i++)
867             {
868                 if (objc_runtime->IsModuleObjCLibrary (loaded_module_list.GetModuleAtIndex (i)))
869                 {
870                     objc_runtime->ReadObjCLibrary (loaded_module_list.GetModuleAtIndex (i));
871                     break;
872                 }
873             }
874         }
875         if (log)
876             loaded_module_list.LogUUIDAndPaths (log, "DynamicLoaderMacOSXDYLD::ModulesDidLoad");
877         m_process->GetTarget().ModulesDidLoad (loaded_module_list);
878     }
879     return true;
880 }
881 
882 bool
883 DynamicLoaderMacOSXDYLD::RemoveModulesUsingImageInfosAddress (lldb::addr_t image_infos_addr, uint32_t image_infos_count)
884 {
885     DYLDImageInfo::collection image_infos;
886     LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
887 
888     Mutex::Locker locker(m_mutex);
889     if (m_process->GetStopID() == m_dyld_image_infos_stop_id)
890         return true;
891 
892     // First read in the image_infos for the removed modules, and their headers & load commands.
893     if (!ReadImageInfos (image_infos_addr, image_infos_count, image_infos))
894     {
895         if (log)
896             log->PutCString ("Failed reading image infos array.");
897         return false;
898     }
899 
900     if (log)
901         log->Printf ("Removing %d modules.", image_infos_count);
902 
903     ModuleList unloaded_module_list;
904     for (uint32_t idx = 0; idx < image_infos.size(); ++idx)
905     {
906         if (log)
907         {
908             log->Printf ("Removing module at address=0x%16.16llx.", image_infos[idx].address);
909             image_infos[idx].PutToLog (log.get());
910         }
911 
912         // Remove this image_infos from the m_all_image_infos.  We do the comparision by address
913         // rather than by file spec because we can have many modules with the same "file spec" in the
914         // case that they are modules loaded from memory.
915         //
916         // Also copy over the uuid from the old entry to the removed entry so we can
917         // use it to lookup the module in the module list.
918 
919         DYLDImageInfo::collection::iterator pos, end = m_dyld_image_infos.end();
920         for (pos = m_dyld_image_infos.begin(); pos != end; pos++)
921         {
922             if (image_infos[idx].address == (*pos).address)
923             {
924                 image_infos[idx].uuid = (*pos).uuid;
925 
926                 // Add the module from this image_info to the "unloaded_module_list".  We'll remove them all at
927                 // one go later on.
928 
929                 ModuleSP unload_image_module_sp (FindTargetModuleForDYLDImageInfo (image_infos[idx], false, NULL));
930                 if (unload_image_module_sp.get())
931                 {
932                     // When we unload, be sure to use the image info from the old list,
933                     // since that has sections correctly filled in.
934                     UnloadImageLoadAddress (unload_image_module_sp.get(), *pos);
935                     unloaded_module_list.AppendIfNeeded (unload_image_module_sp);
936                 }
937                 else
938                 {
939                     if (log)
940                     {
941                         log->Printf ("Could not find module for unloading info entry:");
942                         image_infos[idx].PutToLog(log.get());
943                     }
944                 }
945 
946                 // Then remove it from the m_dyld_image_infos:
947 
948                 m_dyld_image_infos.erase(pos);
949                 break;
950             }
951         }
952 
953         if (pos == end)
954         {
955             if (log)
956             {
957                 log->Printf ("Could not find image_info entry for unloading image:");
958                 image_infos[idx].PutToLog(log.get());
959             }
960         }
961     }
962     if (unloaded_module_list.GetSize() > 0)
963     {
964         if (log)
965         {
966             log->PutCString("Unloaded:");
967             unloaded_module_list.LogUUIDAndPaths (log, "DynamicLoaderMacOSXDYLD::ModulesDidUnload");
968         }
969         m_process->GetTarget().ModulesDidUnload (unloaded_module_list);
970     }
971     m_dyld_image_infos_stop_id = m_process->GetStopID();
972     return true;
973 }
974 
975 bool
976 DynamicLoaderMacOSXDYLD::ReadImageInfos (lldb::addr_t image_infos_addr,
977                                          uint32_t image_infos_count,
978                                          DYLDImageInfo::collection &image_infos)
979 {
980     const ByteOrder endian = m_dyld.GetByteOrder();
981     const uint32_t addr_size = m_dyld.GetAddressByteSize();
982 
983     image_infos.resize(image_infos_count);
984     const size_t count = image_infos.size() * 3 * addr_size;
985     DataBufferHeap info_data(count, 0);
986     Error error;
987     const size_t bytes_read = m_process->ReadMemory (image_infos_addr,
988                                                      info_data.GetBytes(),
989                                                      info_data.GetByteSize(),
990                                                      error);
991     if (bytes_read == count)
992     {
993         uint32_t info_data_offset = 0;
994         DataExtractor info_data_ref(info_data.GetBytes(), info_data.GetByteSize(), endian, addr_size);
995         for (int i = 0; i < image_infos.size() && info_data_ref.ValidOffset(info_data_offset); i++)
996         {
997             image_infos[i].address = info_data_ref.GetPointer(&info_data_offset);
998             lldb::addr_t path_addr = info_data_ref.GetPointer(&info_data_offset);
999             image_infos[i].mod_date = info_data_ref.GetPointer(&info_data_offset);
1000 
1001             char raw_path[PATH_MAX];
1002             m_process->ReadCStringFromMemory (path_addr, raw_path, sizeof(raw_path), error);
1003             // don't resolve the path
1004             if (error.Success())
1005             {
1006                 const bool resolve_path = false;
1007                 image_infos[i].file_spec.SetFile(raw_path, resolve_path);
1008             }
1009         }
1010         return true;
1011     }
1012     else
1013     {
1014         return false;
1015     }
1016 }
1017 
1018 //----------------------------------------------------------------------
1019 // If we have found where the "_dyld_all_image_infos" lives in memory,
1020 // read the current info from it, and then update all image load
1021 // addresses (or lack thereof).  Only do this if this is the first time
1022 // we're reading the dyld infos.  Return true if we actually read anything,
1023 // and false otherwise.
1024 //----------------------------------------------------------------------
1025 bool
1026 DynamicLoaderMacOSXDYLD::InitializeFromAllImageInfos ()
1027 {
1028     LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
1029 
1030     Mutex::Locker locker(m_mutex);
1031     if (m_process->GetStopID() == m_dyld_image_infos_stop_id
1032           || m_dyld_image_infos.size() != 0)
1033         return false;
1034 
1035     if (ReadAllImageInfosStructure ())
1036     {
1037         // Nothing to load or unload?
1038         if (m_dyld_all_image_infos.dylib_info_count == 0)
1039             return true;
1040 
1041         if (m_dyld_all_image_infos.dylib_info_addr == 0)
1042         {
1043             // DYLD is updating the images now.  So we should say we have no images, and then we'll
1044             // figure it out when we hit the added breakpoint.
1045             return false;
1046         }
1047         else
1048         {
1049             if (!AddModulesUsingImageInfosAddress (m_dyld_all_image_infos.dylib_info_addr,
1050                                                    m_dyld_all_image_infos.dylib_info_count))
1051             {
1052                 DEBUG_PRINTF( "unable to read all data for all_dylib_infos.");
1053                 m_dyld_image_infos.clear();
1054             }
1055         }
1056 
1057         // Now we have one more bit of business.  If there is a library left in the images for our target that
1058         // doesn't have a load address, then it must be something that we were expecting to load (for instance we
1059         // read a load command for it) but it didn't in fact load - probably because DYLD_*_PATH pointed
1060         // to an equivalent version.  We don't want it to stay in the target's module list or it will confuse
1061         // us, so unload it here.
1062         Target &target = m_process->GetTarget();
1063         ModuleList &target_modules = target.GetImages();
1064         ModuleList not_loaded_modules;
1065         Mutex::Locker modules_locker(target_modules.GetMutex());
1066 
1067         size_t num_modules = target_modules.GetSize();
1068         for (size_t i = 0; i < num_modules; i++)
1069         {
1070             ModuleSP module_sp = target_modules.GetModuleAtIndexUnlocked (i);
1071             if (!module_sp->IsLoadedInTarget (&target))
1072             {
1073                 if (log)
1074                 {
1075                     StreamString s;
1076                     module_sp->GetDescription (&s);
1077                     log->Printf ("Unloading pre-run module: %s.", s.GetData ());
1078                 }
1079                 not_loaded_modules.Append (module_sp);
1080             }
1081         }
1082 
1083         if (not_loaded_modules.GetSize() != 0)
1084         {
1085             target.ModulesDidUnload(not_loaded_modules);
1086         }
1087 
1088         return true;
1089     }
1090     else
1091         return false;
1092 }
1093 
1094 //----------------------------------------------------------------------
1095 // Read a mach_header at ADDR into HEADER, and also fill in the load
1096 // command data into LOAD_COMMAND_DATA if it is non-NULL.
1097 //
1098 // Returns true if we succeed, false if we fail for any reason.
1099 //----------------------------------------------------------------------
1100 bool
1101 DynamicLoaderMacOSXDYLD::ReadMachHeader (lldb::addr_t addr, llvm::MachO::mach_header *header, DataExtractor *load_command_data)
1102 {
1103     DataBufferHeap header_bytes(sizeof(llvm::MachO::mach_header), 0);
1104     Error error;
1105     size_t bytes_read = m_process->ReadMemory (addr,
1106                                                header_bytes.GetBytes(),
1107                                                header_bytes.GetByteSize(),
1108                                                error);
1109     if (bytes_read == sizeof(llvm::MachO::mach_header))
1110     {
1111         uint32_t offset = 0;
1112         ::memset (header, 0, sizeof(llvm::MachO::mach_header));
1113 
1114         // Get the magic byte unswapped so we can figure out what we are dealing with
1115         DataExtractor data(header_bytes.GetBytes(), header_bytes.GetByteSize(), lldb::endian::InlHostByteOrder(), 4);
1116         header->magic = data.GetU32(&offset);
1117         lldb::addr_t load_cmd_addr = addr;
1118         data.SetByteOrder(DynamicLoaderMacOSXDYLD::GetByteOrderFromMagic(header->magic));
1119         switch (header->magic)
1120         {
1121         case llvm::MachO::HeaderMagic32:
1122         case llvm::MachO::HeaderMagic32Swapped:
1123             data.SetAddressByteSize(4);
1124             load_cmd_addr += sizeof(llvm::MachO::mach_header);
1125             break;
1126 
1127         case llvm::MachO::HeaderMagic64:
1128         case llvm::MachO::HeaderMagic64Swapped:
1129             data.SetAddressByteSize(8);
1130             load_cmd_addr += sizeof(llvm::MachO::mach_header_64);
1131             break;
1132 
1133         default:
1134             return false;
1135         }
1136 
1137         // Read the rest of dyld's mach header
1138         if (data.GetU32(&offset, &header->cputype, (sizeof(llvm::MachO::mach_header)/sizeof(uint32_t)) - 1))
1139         {
1140             if (load_command_data == NULL)
1141                 return true; // We were able to read the mach_header and weren't asked to read the load command bytes
1142 
1143             DataBufferSP load_cmd_data_sp(new DataBufferHeap(header->sizeofcmds, 0));
1144 
1145             size_t load_cmd_bytes_read = m_process->ReadMemory (load_cmd_addr,
1146                                                                 load_cmd_data_sp->GetBytes(),
1147                                                                 load_cmd_data_sp->GetByteSize(),
1148                                                                 error);
1149 
1150             if (load_cmd_bytes_read == header->sizeofcmds)
1151             {
1152                 // Set the load command data and also set the correct endian
1153                 // swap settings and the correct address size
1154                 load_command_data->SetData(load_cmd_data_sp, 0, header->sizeofcmds);
1155                 load_command_data->SetByteOrder(data.GetByteOrder());
1156                 load_command_data->SetAddressByteSize(data.GetAddressByteSize());
1157                 return true; // We successfully read the mach_header and the load command data
1158             }
1159 
1160             return false; // We weren't able to read the load command data
1161         }
1162     }
1163     return false; // We failed the read the mach_header
1164 }
1165 
1166 
1167 //----------------------------------------------------------------------
1168 // Parse the load commands for an image
1169 //----------------------------------------------------------------------
1170 uint32_t
1171 DynamicLoaderMacOSXDYLD::ParseLoadCommands (const DataExtractor& data, DYLDImageInfo& dylib_info, FileSpec *lc_id_dylinker)
1172 {
1173     uint32_t offset = 0;
1174     uint32_t cmd_idx;
1175     Segment segment;
1176     dylib_info.Clear (true);
1177 
1178     for (cmd_idx = 0; cmd_idx < dylib_info.header.ncmds; cmd_idx++)
1179     {
1180         // Clear out any load command specific data from DYLIB_INFO since
1181         // we are about to read it.
1182 
1183         if (data.ValidOffsetForDataOfSize (offset, sizeof(llvm::MachO::load_command)))
1184         {
1185             llvm::MachO::load_command load_cmd;
1186             uint32_t load_cmd_offset = offset;
1187             load_cmd.cmd = data.GetU32 (&offset);
1188             load_cmd.cmdsize = data.GetU32 (&offset);
1189             switch (load_cmd.cmd)
1190             {
1191             case llvm::MachO::LoadCommandSegment32:
1192                 {
1193                     segment.name.SetTrimmedCStringWithLength ((const char *)data.GetData(&offset, 16), 16);
1194                     // We are putting 4 uint32_t values 4 uint64_t values so
1195                     // we have to use multiple 32 bit gets below.
1196                     segment.vmaddr = data.GetU32 (&offset);
1197                     segment.vmsize = data.GetU32 (&offset);
1198                     segment.fileoff = data.GetU32 (&offset);
1199                     segment.filesize = data.GetU32 (&offset);
1200                     // Extract maxprot, initprot, nsects and flags all at once
1201                     data.GetU32(&offset, &segment.maxprot, 4);
1202                     dylib_info.segments.push_back (segment);
1203                 }
1204                 break;
1205 
1206             case llvm::MachO::LoadCommandSegment64:
1207                 {
1208                     segment.name.SetTrimmedCStringWithLength ((const char *)data.GetData(&offset, 16), 16);
1209                     // Extract vmaddr, vmsize, fileoff, and filesize all at once
1210                     data.GetU64(&offset, &segment.vmaddr, 4);
1211                     // Extract maxprot, initprot, nsects and flags all at once
1212                     data.GetU32(&offset, &segment.maxprot, 4);
1213                     dylib_info.segments.push_back (segment);
1214                 }
1215                 break;
1216 
1217             case llvm::MachO::LoadCommandDynamicLinkerIdent:
1218                 if (lc_id_dylinker)
1219                 {
1220                     uint32_t name_offset = load_cmd_offset + data.GetU32 (&offset);
1221                     const char *path = data.PeekCStr (name_offset);
1222                     lc_id_dylinker->SetFile (path, true);
1223                 }
1224                 break;
1225 
1226             case llvm::MachO::LoadCommandUUID:
1227                 dylib_info.uuid.SetBytes(data.GetData (&offset, 16));
1228                 break;
1229 
1230             default:
1231                 break;
1232             }
1233             // Set offset to be the beginning of the next load command.
1234             offset = load_cmd_offset + load_cmd.cmdsize;
1235         }
1236     }
1237 
1238     // All sections listed in the dyld image info structure will all
1239     // either be fixed up already, or they will all be off by a single
1240     // slide amount that is determined by finding the first segment
1241     // that is at file offset zero which also has bytes (a file size
1242     // that is greater than zero) in the object file.
1243 
1244     // Determine the slide amount (if any)
1245     const size_t num_sections = dylib_info.segments.size();
1246     for (size_t i = 0; i < num_sections; ++i)
1247     {
1248         // Iterate through the object file sections to find the
1249         // first section that starts of file offset zero and that
1250         // has bytes in the file...
1251         if (dylib_info.segments[i].fileoff == 0 && dylib_info.segments[i].filesize > 0)
1252         {
1253             dylib_info.slide = dylib_info.address - dylib_info.segments[i].vmaddr;
1254             // We have found the slide amount, so we can exit
1255             // this for loop.
1256             break;
1257         }
1258     }
1259     return cmd_idx;
1260 }
1261 
1262 //----------------------------------------------------------------------
1263 // Read the mach_header and load commands for each image that the
1264 // _dyld_all_image_infos structure points to and cache the results.
1265 //----------------------------------------------------------------------
1266 
1267 void
1268 DynamicLoaderMacOSXDYLD::UpdateImageInfosHeaderAndLoadCommands(DYLDImageInfo::collection &image_infos,
1269                                                                uint32_t infos_count,
1270                                                                bool update_executable)
1271 {
1272     uint32_t exe_idx = UINT32_MAX;
1273     LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
1274     // Read any UUID values that we can get
1275     for (uint32_t i = 0; i < infos_count; i++)
1276     {
1277         if (!image_infos[i].UUIDValid())
1278         {
1279             DataExtractor data; // Load command data
1280             if (!ReadMachHeader (image_infos[i].address, &image_infos[i].header, &data))
1281                 continue;
1282 
1283             ParseLoadCommands (data, image_infos[i], NULL);
1284 
1285             if (image_infos[i].header.filetype == llvm::MachO::HeaderFileTypeExecutable)
1286                 exe_idx = i;
1287 
1288         }
1289     }
1290 
1291     if (exe_idx < image_infos.size())
1292     {
1293         const bool can_create = true;
1294         ModuleSP exe_module_sp (FindTargetModuleForDYLDImageInfo (image_infos[exe_idx], can_create, NULL));
1295 
1296         if (!exe_module_sp)
1297         {
1298             ArchSpec exe_arch_spec (image_infos[exe_idx].GetArchitecture ());
1299             ModuleSpec module_spec (image_infos[exe_idx].file_spec,
1300                                     image_infos[exe_idx].GetArchitecture ());
1301             module_spec.GetUUID() = image_infos[exe_idx].uuid;
1302             exe_module_sp = m_process->GetTarget().GetSharedModule (module_spec);
1303             if (!exe_module_sp || exe_module_sp->GetObjectFile() == NULL)
1304             {
1305                 const bool add_image_to_target = true;
1306                 const bool load_image_sections_in_target = false;
1307                 exe_module_sp = m_process->ReadModuleFromMemory (image_infos[exe_idx].file_spec,
1308                                                                  image_infos[exe_idx].address,
1309                                                                  add_image_to_target,
1310                                                                  load_image_sections_in_target);
1311             }
1312         }
1313 
1314         if (exe_module_sp)
1315         {
1316             if (exe_module_sp.get() != m_process->GetTarget().GetExecutableModulePointer())
1317             {
1318                 // Don't load dependent images since we are in dyld where we will know
1319                 // and find out about all images that are loaded
1320                 const bool get_dependent_images = false;
1321                 m_process->GetTarget().SetExecutableModule (exe_module_sp,
1322                                                             get_dependent_images);
1323             }
1324         }
1325     }
1326 }
1327 
1328 //----------------------------------------------------------------------
1329 // On Mac OS X libobjc (the Objective-C runtime) has several critical dispatch
1330 // functions written in hand-written assembly, and also have hand-written unwind
1331 // information in the eh_frame section.  Normally we prefer analyzing the
1332 // assembly instructions of a curently executing frame to unwind from that frame --
1333 // but on hand-written functions this profiling can fail.  We should use the
1334 // eh_frame instructions for these functions all the time.
1335 //
1336 // As an aside, it would be better if the eh_frame entries had a flag (or were
1337 // extensible so they could have an Apple-specific flag) which indicates that
1338 // the instructions are asynchronous -- accurate at every instruction, instead
1339 // of our normal default assumption that they are not.
1340 //----------------------------------------------------------------------
1341 
1342 bool
1343 DynamicLoaderMacOSXDYLD::AlwaysRelyOnEHUnwindInfo (SymbolContext &sym_ctx)
1344 {
1345     ModuleSP module_sp;
1346     if (sym_ctx.symbol)
1347     {
1348         module_sp = sym_ctx.symbol->GetAddress().GetModule();
1349     }
1350     if (module_sp.get() == NULL && sym_ctx.function)
1351     {
1352         module_sp = sym_ctx.function->GetAddressRange().GetBaseAddress().GetModule();
1353     }
1354     if (module_sp.get() == NULL)
1355         return false;
1356 
1357     ObjCLanguageRuntime *objc_runtime = m_process->GetObjCLanguageRuntime();
1358     if (objc_runtime != NULL && objc_runtime->IsModuleObjCLibrary (module_sp))
1359     {
1360         return true;
1361     }
1362 
1363     return false;
1364 }
1365 
1366 
1367 
1368 //----------------------------------------------------------------------
1369 // Dump a Segment to the file handle provided.
1370 //----------------------------------------------------------------------
1371 void
1372 DynamicLoaderMacOSXDYLD::Segment::PutToLog (Log *log, lldb::addr_t slide) const
1373 {
1374     if (log)
1375     {
1376         if (slide == 0)
1377             log->Printf ("\t\t%16s [0x%16.16llx - 0x%16.16llx)",
1378                          name.AsCString(""),
1379                          vmaddr + slide,
1380                          vmaddr + slide + vmsize);
1381         else
1382             log->Printf ("\t\t%16s [0x%16.16llx - 0x%16.16llx) slide = 0x%llx",
1383                          name.AsCString(""),
1384                          vmaddr + slide,
1385                          vmaddr + slide + vmsize,
1386                          slide);
1387     }
1388 }
1389 
1390 const DynamicLoaderMacOSXDYLD::Segment *
1391 DynamicLoaderMacOSXDYLD::DYLDImageInfo::FindSegment (const ConstString &name) const
1392 {
1393     const size_t num_segments = segments.size();
1394     for (size_t i=0; i<num_segments; ++i)
1395     {
1396         if (segments[i].name == name)
1397             return &segments[i];
1398     }
1399     return NULL;
1400 }
1401 
1402 
1403 //----------------------------------------------------------------------
1404 // Dump an image info structure to the file handle provided.
1405 //----------------------------------------------------------------------
1406 void
1407 DynamicLoaderMacOSXDYLD::DYLDImageInfo::PutToLog (Log *log) const
1408 {
1409     if (log == NULL)
1410         return;
1411     uint8_t *u = (uint8_t *)uuid.GetBytes();
1412 
1413     if (address == LLDB_INVALID_ADDRESS)
1414     {
1415         if (u)
1416         {
1417             log->Printf("\t                           modtime=0x%8.8llx uuid=%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X path='%s/%s' (UNLOADED)",
1418                         mod_date,
1419                         u[ 0], u[ 1], u[ 2], u[ 3],
1420                         u[ 4], u[ 5], u[ 6], u[ 7],
1421                         u[ 8], u[ 9], u[10], u[11],
1422                         u[12], u[13], u[14], u[15],
1423                         file_spec.GetDirectory().AsCString(),
1424                         file_spec.GetFilename().AsCString());
1425         }
1426         else
1427             log->Printf("\t                           modtime=0x%8.8llx path='%s/%s' (UNLOADED)",
1428                         mod_date,
1429                         file_spec.GetDirectory().AsCString(),
1430                         file_spec.GetFilename().AsCString());
1431     }
1432     else
1433     {
1434         if (u)
1435         {
1436             log->Printf("\taddress=0x%16.16llx modtime=0x%8.8llx uuid=%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X path='%s/%s'",
1437                         address,
1438                         mod_date,
1439                         u[ 0], u[ 1], u[ 2], u[ 3],
1440                         u[ 4], u[ 5], u[ 6], u[ 7],
1441                         u[ 8], u[ 9], u[10], u[11],
1442                         u[12], u[13], u[14], u[15],
1443                         file_spec.GetDirectory().AsCString(),
1444                         file_spec.GetFilename().AsCString());
1445         }
1446         else
1447         {
1448             log->Printf("\taddress=0x%16.16llx modtime=0x%8.8llx path='%s/%s'",
1449                         address,
1450                         mod_date,
1451                         file_spec.GetDirectory().AsCString(),
1452                         file_spec.GetFilename().AsCString());
1453 
1454         }
1455         for (uint32_t i=0; i<segments.size(); ++i)
1456             segments[i].PutToLog(log, slide);
1457     }
1458 }
1459 
1460 //----------------------------------------------------------------------
1461 // Dump the _dyld_all_image_infos members and all current image infos
1462 // that we have parsed to the file handle provided.
1463 //----------------------------------------------------------------------
1464 void
1465 DynamicLoaderMacOSXDYLD::PutToLog(Log *log) const
1466 {
1467     if (log == NULL)
1468         return;
1469 
1470     Mutex::Locker locker(m_mutex);
1471     log->Printf("dyld_all_image_infos = { version=%d, count=%d, addr=0x%8.8llx, notify=0x%8.8llx }",
1472                     m_dyld_all_image_infos.version,
1473                     m_dyld_all_image_infos.dylib_info_count,
1474                     (uint64_t)m_dyld_all_image_infos.dylib_info_addr,
1475                     (uint64_t)m_dyld_all_image_infos.notification);
1476     size_t i;
1477     const size_t count = m_dyld_image_infos.size();
1478     if (count > 0)
1479     {
1480         log->PutCString("Loaded:");
1481         for (i = 0; i<count; i++)
1482             m_dyld_image_infos[i].PutToLog(log);
1483     }
1484 }
1485 
1486 void
1487 DynamicLoaderMacOSXDYLD::PrivateInitialize(Process *process)
1488 {
1489     DEBUG_PRINTF("DynamicLoaderMacOSXDYLD::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState()));
1490     Clear(true);
1491     m_process = process;
1492     m_process->GetTarget().GetSectionLoadList().Clear();
1493 }
1494 
1495 bool
1496 DynamicLoaderMacOSXDYLD::SetNotificationBreakpoint ()
1497 {
1498     DEBUG_PRINTF("DynamicLoaderMacOSXDYLD::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState()));
1499     if (m_break_id == LLDB_INVALID_BREAK_ID)
1500     {
1501         if (m_dyld_all_image_infos.notification != LLDB_INVALID_ADDRESS)
1502         {
1503             Address so_addr;
1504             // Set the notification breakpoint and install a breakpoint
1505             // callback function that will get called each time the
1506             // breakpoint gets hit. We will use this to track when shared
1507             // libraries get loaded/unloaded.
1508 
1509             if (m_process->GetTarget().GetSectionLoadList().ResolveLoadAddress(m_dyld_all_image_infos.notification, so_addr))
1510             {
1511                 Breakpoint *dyld_break = m_process->GetTarget().CreateBreakpoint (so_addr, true).get();
1512                 dyld_break->SetCallback (DynamicLoaderMacOSXDYLD::NotifyBreakpointHit, this, true);
1513                 m_break_id = dyld_break->GetID();
1514             }
1515         }
1516     }
1517     return m_break_id != LLDB_INVALID_BREAK_ID;
1518 }
1519 
1520 //----------------------------------------------------------------------
1521 // Member function that gets called when the process state changes.
1522 //----------------------------------------------------------------------
1523 void
1524 DynamicLoaderMacOSXDYLD::PrivateProcessStateChanged (Process *process, StateType state)
1525 {
1526     DEBUG_PRINTF("DynamicLoaderMacOSXDYLD::%s(%s)\n", __FUNCTION__, StateAsCString(state));
1527     switch (state)
1528     {
1529     case eStateConnected:
1530     case eStateAttaching:
1531     case eStateLaunching:
1532     case eStateInvalid:
1533     case eStateUnloaded:
1534     case eStateExited:
1535     case eStateDetached:
1536         Clear(false);
1537         break;
1538 
1539     case eStateStopped:
1540         // Keep trying find dyld and set our notification breakpoint each time
1541         // we stop until we succeed
1542         if (!DidSetNotificationBreakpoint () && m_process->IsAlive())
1543         {
1544             if (NeedToLocateDYLD ())
1545                 LocateDYLD ();
1546 
1547             SetNotificationBreakpoint ();
1548         }
1549         break;
1550 
1551     case eStateRunning:
1552     case eStateStepping:
1553     case eStateCrashed:
1554     case eStateSuspended:
1555         break;
1556 
1557     default:
1558         break;
1559     }
1560 }
1561 
1562 // This bit in the n_desc field of the mach file means that this is a
1563 // stub that runs arbitrary code to determine the trampoline target.
1564 // We've established a naming convention with the CoreOS folks for the
1565 // equivalent symbols they will use for this (which the objc guys didn't follow...)
1566 // For now we'll just look for all symbols matching that naming convention...
1567 
1568 #define MACH_O_N_SYMBOL_RESOLVER 0x100
1569 
1570 ThreadPlanSP
1571 DynamicLoaderMacOSXDYLD::GetStepThroughTrampolinePlan (Thread &thread, bool stop_others)
1572 {
1573     ThreadPlanSP thread_plan_sp;
1574     StackFrame *current_frame = thread.GetStackFrameAtIndex(0).get();
1575     const SymbolContext &current_context = current_frame->GetSymbolContext(eSymbolContextSymbol);
1576     Symbol *current_symbol = current_context.symbol;
1577     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
1578 
1579     if (current_symbol != NULL)
1580     {
1581         if (current_symbol->IsTrampoline())
1582         {
1583             const ConstString &trampoline_name = current_symbol->GetMangled().GetName(Mangled::ePreferMangled);
1584 
1585             if (trampoline_name)
1586             {
1587                 SymbolContextList target_symbols;
1588                 TargetSP target_sp (thread.CalculateTarget());
1589                 ModuleList &images = target_sp->GetImages();
1590 
1591                 images.FindSymbolsWithNameAndType(trampoline_name, eSymbolTypeCode, target_symbols);
1592 
1593                 size_t num_original_symbols = target_symbols.GetSize();
1594                 // FIXME: The resolver symbol is only valid in object files.  In binaries it is reused for the
1595                 // shared library slot number.  So we'll have to look this up in the dyld info.
1596                 // For now, just turn this off.
1597 
1598                 // bool orig_is_resolver = (current_symbol->GetFlags() & MACH_O_N_SYMBOL_RESOLVER) == MACH_O_N_SYMBOL_RESOLVER;
1599                 bool orig_is_resolver = false;
1600 
1601                 if (num_original_symbols > 0)
1602                 {
1603                     // We found symbols that look like they are the targets to our symbol.  Now look through the
1604                     // modules containing our symbols to see if there are any for our symbol.
1605 
1606                     ModuleList modules_to_search;
1607 
1608                     for (size_t i = 0; i < num_original_symbols; i++)
1609                     {
1610                         SymbolContext sc;
1611                         target_symbols.GetContextAtIndex(i, sc);
1612 
1613                         ModuleSP module_sp (sc.symbol->CalculateSymbolContextModule());
1614                         if (module_sp)
1615                              modules_to_search.AppendIfNeeded(module_sp);
1616                     }
1617 
1618                     // If the original stub symbol is a resolver, then we don't want to break on the symbol with the
1619                     // original name, but instead on all the symbols it could resolve to since otherwise we would stop
1620                     // in the middle of the resolution...
1621                     // Note that the stub is not of the resolver type it will point to the equivalent symbol,
1622                     // not the original name, so in that case we don't need to do anything.
1623 
1624                     if (orig_is_resolver)
1625                     {
1626                         target_symbols.Clear();
1627 
1628                         FindEquivalentSymbols (current_symbol, modules_to_search, target_symbols);
1629                     }
1630 
1631                     // FIXME - Make the Run to Address take multiple addresses, and
1632                     // run to any of them.
1633                     uint32_t num_symbols = target_symbols.GetSize();
1634                     if (num_symbols > 0)
1635                     {
1636                         std::vector<lldb::addr_t>  addresses;
1637                         addresses.resize (num_symbols);
1638                         for (uint32_t i = 0; i < num_symbols; i++)
1639                         {
1640                             SymbolContext context;
1641                             AddressRange addr_range;
1642                             if (target_symbols.GetContextAtIndex(i, context))
1643                             {
1644                                 context.GetAddressRange (eSymbolContextEverything, 0, false, addr_range);
1645                                 lldb::addr_t load_addr = addr_range.GetBaseAddress().GetLoadAddress(target_sp.get());
1646                                 addresses[i] = load_addr;
1647                             }
1648                         }
1649                         if (addresses.size() > 0)
1650                             thread_plan_sp.reset (new ThreadPlanRunToAddress (thread, addresses, stop_others));
1651                         else
1652                         {
1653                             if (log)
1654                                 log->Printf ("Couldn't resolve the symbol contexts.");
1655                         }
1656                     }
1657                     else
1658                     {
1659                         if (log)
1660                         {
1661                             log->Printf ("Found a resolver stub for: \"%s\" but could not find any symbols it resolves to.",
1662                                          trampoline_name.AsCString());
1663                         }
1664                     }
1665                 }
1666                 else
1667                 {
1668                     if (log)
1669                     {
1670                         log->Printf ("Could not find symbol for trampoline target: \"%s\"", trampoline_name.AsCString());
1671                     }
1672                 }
1673             }
1674         }
1675     }
1676     else
1677     {
1678         if (log)
1679             log->Printf ("Could not find symbol for step through.");
1680     }
1681 
1682     return thread_plan_sp;
1683 }
1684 
1685 size_t
1686 DynamicLoaderMacOSXDYLD::FindEquivalentSymbols (lldb_private::Symbol *original_symbol,
1687                                                lldb_private::ModuleList &images,
1688                                                lldb_private::SymbolContextList &equivalent_symbols)
1689 {
1690     const ConstString &trampoline_name = original_symbol->GetMangled().GetName(Mangled::ePreferMangled);
1691     if (!trampoline_name)
1692         return 0;
1693 
1694     size_t initial_size = equivalent_symbols.GetSize();
1695 
1696     static const char *resolver_name_regex = "(_gc|_non_gc|\\$[A-Z0-9]+)$";
1697     std::string equivalent_regex_buf("^");
1698     equivalent_regex_buf.append (trampoline_name.GetCString());
1699     equivalent_regex_buf.append (resolver_name_regex);
1700 
1701     RegularExpression equivalent_name_regex (equivalent_regex_buf.c_str());
1702     const bool append = true;
1703     images.FindSymbolsMatchingRegExAndType (equivalent_name_regex, eSymbolTypeCode, equivalent_symbols, append);
1704 
1705     return equivalent_symbols.GetSize() - initial_size;
1706 }
1707 
1708 Error
1709 DynamicLoaderMacOSXDYLD::CanLoadImage ()
1710 {
1711     Error error;
1712     // In order for us to tell if we can load a shared library we verify that
1713     // the dylib_info_addr isn't zero (which means no shared libraries have
1714     // been set yet, or dyld is currently mucking with the shared library list).
1715     if (ReadAllImageInfosStructure ())
1716     {
1717         // TODO: also check the _dyld_global_lock_held variable in libSystem.B.dylib?
1718         // TODO: check the malloc lock?
1719         // TODO: check the objective C lock?
1720         if (m_dyld_all_image_infos.dylib_info_addr != 0)
1721             return error; // Success
1722     }
1723 
1724     error.SetErrorString("unsafe to load or unload shared libraries");
1725     return error;
1726 }
1727 
1728 void
1729 DynamicLoaderMacOSXDYLD::Initialize()
1730 {
1731     PluginManager::RegisterPlugin (GetPluginNameStatic(),
1732                                    GetPluginDescriptionStatic(),
1733                                    CreateInstance);
1734 }
1735 
1736 void
1737 DynamicLoaderMacOSXDYLD::Terminate()
1738 {
1739     PluginManager::UnregisterPlugin (CreateInstance);
1740 }
1741 
1742 
1743 const char *
1744 DynamicLoaderMacOSXDYLD::GetPluginNameStatic()
1745 {
1746     return "dynamic-loader.macosx-dyld";
1747 }
1748 
1749 const char *
1750 DynamicLoaderMacOSXDYLD::GetPluginDescriptionStatic()
1751 {
1752     return "Dynamic loader plug-in that watches for shared library loads/unloads in MacOSX user processes.";
1753 }
1754 
1755 
1756 //------------------------------------------------------------------
1757 // PluginInterface protocol
1758 //------------------------------------------------------------------
1759 const char *
1760 DynamicLoaderMacOSXDYLD::GetPluginName()
1761 {
1762     return "DynamicLoaderMacOSXDYLD";
1763 }
1764 
1765 const char *
1766 DynamicLoaderMacOSXDYLD::GetShortPluginName()
1767 {
1768     return GetPluginNameStatic();
1769 }
1770 
1771 uint32_t
1772 DynamicLoaderMacOSXDYLD::GetPluginVersion()
1773 {
1774     return 1;
1775 }
1776 
1777 uint32_t
1778 DynamicLoaderMacOSXDYLD::AddrByteSize()
1779 {
1780     switch (m_dyld.header.magic)
1781     {
1782         case llvm::MachO::HeaderMagic32:
1783         case llvm::MachO::HeaderMagic32Swapped:
1784             return 4;
1785 
1786         case llvm::MachO::HeaderMagic64:
1787         case llvm::MachO::HeaderMagic64Swapped:
1788             return 8;
1789 
1790         default:
1791             break;
1792     }
1793     return 0;
1794 }
1795 
1796 lldb::ByteOrder
1797 DynamicLoaderMacOSXDYLD::GetByteOrderFromMagic (uint32_t magic)
1798 {
1799     switch (magic)
1800     {
1801         case llvm::MachO::HeaderMagic32:
1802         case llvm::MachO::HeaderMagic64:
1803             return lldb::endian::InlHostByteOrder();
1804 
1805         case llvm::MachO::HeaderMagic32Swapped:
1806         case llvm::MachO::HeaderMagic64Swapped:
1807             if (lldb::endian::InlHostByteOrder() == lldb::eByteOrderBig)
1808                 return lldb::eByteOrderLittle;
1809             else
1810                 return lldb::eByteOrderBig;
1811 
1812         default:
1813             break;
1814     }
1815     return lldb::eByteOrderInvalid;
1816 }
1817 
1818 lldb::ByteOrder
1819 DynamicLoaderMacOSXDYLD::DYLDImageInfo::GetByteOrder()
1820 {
1821     return DynamicLoaderMacOSXDYLD::GetByteOrderFromMagic(header.magic);
1822 }
1823 
1824