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