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->GetTarget().RemoveBreakpointByID (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             lldb::offset_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                 const size_t num_sections = section_list->GetSize();
453                 for (size_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                 const size_t num_segments = info.segments.size();
494                 for (size_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                 const size_t num_segments = info.segments.size();
589                 for (size_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         lldb::offset_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         Error error;
744         if (m_process->ReadMemory (m_dyld_all_image_infos_addr, buf, 4, error) == 4)
745         {
746             m_dyld_all_image_infos.version = data.GetU32(&offset);
747             // If anything in the high byte is set, we probably got the byte
748             // order incorrect (the process might not have it set correctly
749             // yet due to attaching to a program without a specified file).
750             if (m_dyld_all_image_infos.version & 0xff000000)
751             {
752                 // We have guessed the wrong byte order. Swap it and try
753                 // reading the version again.
754                 if (byte_order == eByteOrderLittle)
755                     byte_order = eByteOrderBig;
756                 else
757                     byte_order = eByteOrderLittle;
758 
759                 data.SetByteOrder (byte_order);
760                 offset = 0;
761                 m_dyld_all_image_infos.version = data.GetU32(&offset);
762             }
763         }
764         else
765         {
766             return false;
767         }
768 
769         const size_t count = (m_dyld_all_image_infos.version >= 11) ? count_v11 : count_v2;
770 
771         const size_t bytes_read = m_process->ReadMemory (m_dyld_all_image_infos_addr, buf, count, error);
772         if (bytes_read == count)
773         {
774             offset = 0;
775             m_dyld_all_image_infos.version = data.GetU32(&offset);
776             m_dyld_all_image_infos.dylib_info_count = data.GetU32(&offset);
777             m_dyld_all_image_infos.dylib_info_addr = data.GetPointer(&offset);
778             m_dyld_all_image_infos.notification = data.GetPointer(&offset);
779             m_dyld_all_image_infos.processDetachedFromSharedRegion = data.GetU8(&offset);
780             m_dyld_all_image_infos.libSystemInitialized = data.GetU8(&offset);
781             // Adjust for padding.
782             offset += addr_size - 2;
783             m_dyld_all_image_infos.dyldImageLoadAddress = data.GetPointer(&offset);
784             if (m_dyld_all_image_infos.version >= 11)
785             {
786                 offset += addr_size * 8;
787                 uint64_t dyld_all_image_infos_addr = data.GetPointer(&offset);
788 
789                 // When we started, we were given the actual address of the all_image_infos
790                 // struct (probably via TASK_DYLD_INFO) in memory - this address is stored in
791                 // m_dyld_all_image_infos_addr and is the most accurate address we have.
792 
793                 // We read the dyld_all_image_infos struct from memory; it contains its own address.
794                 // If the address in the struct does not match the actual address,
795                 // the dyld we're looking at has been loaded at a different location (slid) from
796                 // where it intended to load.  The addresses in the dyld_all_image_infos struct
797                 // are the original, non-slid addresses, and need to be adjusted.  Most importantly
798                 // the address of dyld and the notification address need to be adjusted.
799 
800                 if (dyld_all_image_infos_addr != m_dyld_all_image_infos_addr)
801                 {
802                     uint64_t image_infos_offset = dyld_all_image_infos_addr - m_dyld_all_image_infos.dyldImageLoadAddress;
803                     uint64_t notification_offset = m_dyld_all_image_infos.notification - m_dyld_all_image_infos.dyldImageLoadAddress;
804                     m_dyld_all_image_infos.dyldImageLoadAddress = m_dyld_all_image_infos_addr - image_infos_offset;
805                     m_dyld_all_image_infos.notification = m_dyld_all_image_infos.dyldImageLoadAddress + notification_offset;
806                 }
807             }
808             m_dyld_all_image_infos_stop_id = m_process->GetStopID();
809             return true;
810         }
811     }
812     return false;
813 }
814 
815 
816 bool
817 DynamicLoaderMacOSXDYLD::AddModulesUsingImageInfosAddress (lldb::addr_t image_infos_addr, uint32_t image_infos_count)
818 {
819     DYLDImageInfo::collection image_infos;
820     LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
821     if (log)
822         log->Printf ("Adding %d modules.\n", image_infos_count);
823 
824     Mutex::Locker locker(m_mutex);
825     if (m_process->GetStopID() == m_dyld_image_infos_stop_id)
826         return true;
827 
828     if (!ReadImageInfos (image_infos_addr, image_infos_count, image_infos))
829         return false;
830 
831     UpdateImageInfosHeaderAndLoadCommands (image_infos, image_infos_count, false);
832     bool return_value = AddModulesUsingImageInfos (image_infos);
833     m_dyld_image_infos_stop_id = m_process->GetStopID();
834     return return_value;
835 }
836 
837 // Adds the modules in image_infos to m_dyld_image_infos.
838 // NB don't call this passing in m_dyld_image_infos.
839 
840 bool
841 DynamicLoaderMacOSXDYLD::AddModulesUsingImageInfos (DYLDImageInfo::collection &image_infos)
842 {
843     // Now add these images to the main list.
844     ModuleList loaded_module_list;
845     LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
846 
847     for (uint32_t idx = 0; idx < image_infos.size(); ++idx)
848     {
849         if (log)
850         {
851             log->Printf ("Adding new image at address=0x%16.16" PRIx64 ".", image_infos[idx].address);
852             image_infos[idx].PutToLog (log.get());
853         }
854 
855         m_dyld_image_infos.push_back(image_infos[idx]);
856 
857         ModuleSP image_module_sp (FindTargetModuleForDYLDImageInfo (image_infos[idx], true, NULL));
858 
859         if (image_module_sp)
860         {
861             if (image_infos[idx].header.filetype == llvm::MachO::HeaderFileTypeDynamicLinkEditor)
862                 image_module_sp->SetIsDynamicLinkEditor (true);
863 
864             ObjectFile *objfile = image_module_sp->GetObjectFile ();
865             if (objfile)
866             {
867                 SectionList *sections = objfile->GetSectionList();
868                 if (sections)
869                 {
870                     ConstString commpage_dbstr("__commpage");
871                     Section *commpage_section = sections->FindSectionByName(commpage_dbstr).get();
872                     if (commpage_section)
873                     {
874                         const ModuleList& target_images = m_process->GetTarget().GetImages();
875                         ModuleSpec module_spec (objfile->GetFileSpec(), image_infos[idx].GetArchitecture ());
876                         module_spec.GetObjectName() = commpage_dbstr;
877                         ModuleSP commpage_image_module_sp(target_images.FindFirstModule (module_spec));
878                         if (!commpage_image_module_sp)
879                         {
880                             module_spec.SetObjectOffset (objfile->GetOffset() + commpage_section->GetFileOffset());
881                             commpage_image_module_sp  = m_process->GetTarget().GetSharedModule (module_spec);
882                             if (!commpage_image_module_sp || commpage_image_module_sp->GetObjectFile() == NULL)
883                             {
884                                 const bool add_image_to_target = true;
885                                 const bool load_image_sections_in_target = false;
886                                 commpage_image_module_sp = m_process->ReadModuleFromMemory (image_infos[idx].file_spec,
887                                                                                             image_infos[idx].address,
888                                                                                             add_image_to_target,
889                                                                                             load_image_sections_in_target);
890                             }
891                         }
892                         if (commpage_image_module_sp)
893                             UpdateCommPageLoadAddress (commpage_image_module_sp.get());
894                     }
895                 }
896             }
897 
898             // UpdateImageLoadAddress will return true if any segments
899             // change load address. We need to check this so we don't
900             // mention that all loaded shared libraries are newly loaded
901             // each time we hit out dyld breakpoint since dyld will list all
902             // shared libraries each time.
903             if (UpdateImageLoadAddress (image_module_sp.get(), image_infos[idx]))
904             {
905                 loaded_module_list.AppendIfNeeded (image_module_sp);
906             }
907         }
908     }
909 
910     if (loaded_module_list.GetSize() > 0)
911     {
912         // FIXME: This should really be in the Runtime handlers class, which should get
913         // called by the target's ModulesDidLoad, but we're doing it all locally for now
914         // to save time.
915         // Also, I'm assuming there can be only one libobjc dylib loaded...
916 
917         ObjCLanguageRuntime *objc_runtime = m_process->GetObjCLanguageRuntime(true);
918         if (objc_runtime != NULL && !objc_runtime->HasReadObjCLibrary())
919         {
920             size_t num_modules = loaded_module_list.GetSize();
921             for (int i = 0; i < num_modules; i++)
922             {
923                 if (objc_runtime->IsModuleObjCLibrary (loaded_module_list.GetModuleAtIndex (i)))
924                 {
925                     objc_runtime->ReadObjCLibrary (loaded_module_list.GetModuleAtIndex (i));
926                     break;
927                 }
928             }
929         }
930         if (log)
931             loaded_module_list.LogUUIDAndPaths (log, "DynamicLoaderMacOSXDYLD::ModulesDidLoad");
932         m_process->GetTarget().ModulesDidLoad (loaded_module_list);
933     }
934     return true;
935 }
936 
937 bool
938 DynamicLoaderMacOSXDYLD::RemoveModulesUsingImageInfosAddress (lldb::addr_t image_infos_addr, uint32_t image_infos_count)
939 {
940     DYLDImageInfo::collection image_infos;
941     LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
942 
943     Mutex::Locker locker(m_mutex);
944     if (m_process->GetStopID() == m_dyld_image_infos_stop_id)
945         return true;
946 
947     // First read in the image_infos for the removed modules, and their headers & load commands.
948     if (!ReadImageInfos (image_infos_addr, image_infos_count, image_infos))
949     {
950         if (log)
951             log->PutCString ("Failed reading image infos array.");
952         return false;
953     }
954 
955     if (log)
956         log->Printf ("Removing %d modules.", image_infos_count);
957 
958     ModuleList unloaded_module_list;
959     for (uint32_t idx = 0; idx < image_infos.size(); ++idx)
960     {
961         if (log)
962         {
963             log->Printf ("Removing module at address=0x%16.16" PRIx64 ".", image_infos[idx].address);
964             image_infos[idx].PutToLog (log.get());
965         }
966 
967         // Remove this image_infos from the m_all_image_infos.  We do the comparision by address
968         // rather than by file spec because we can have many modules with the same "file spec" in the
969         // case that they are modules loaded from memory.
970         //
971         // Also copy over the uuid from the old entry to the removed entry so we can
972         // use it to lookup the module in the module list.
973 
974         DYLDImageInfo::collection::iterator pos, end = m_dyld_image_infos.end();
975         for (pos = m_dyld_image_infos.begin(); pos != end; pos++)
976         {
977             if (image_infos[idx].address == (*pos).address)
978             {
979                 image_infos[idx].uuid = (*pos).uuid;
980 
981                 // Add the module from this image_info to the "unloaded_module_list".  We'll remove them all at
982                 // one go later on.
983 
984                 ModuleSP unload_image_module_sp (FindTargetModuleForDYLDImageInfo (image_infos[idx], false, NULL));
985                 if (unload_image_module_sp.get())
986                 {
987                     // When we unload, be sure to use the image info from the old list,
988                     // since that has sections correctly filled in.
989                     UnloadImageLoadAddress (unload_image_module_sp.get(), *pos);
990                     unloaded_module_list.AppendIfNeeded (unload_image_module_sp);
991                 }
992                 else
993                 {
994                     if (log)
995                     {
996                         log->Printf ("Could not find module for unloading info entry:");
997                         image_infos[idx].PutToLog(log.get());
998                     }
999                 }
1000 
1001                 // Then remove it from the m_dyld_image_infos:
1002 
1003                 m_dyld_image_infos.erase(pos);
1004                 break;
1005             }
1006         }
1007 
1008         if (pos == end)
1009         {
1010             if (log)
1011             {
1012                 log->Printf ("Could not find image_info entry for unloading image:");
1013                 image_infos[idx].PutToLog(log.get());
1014             }
1015         }
1016     }
1017     if (unloaded_module_list.GetSize() > 0)
1018     {
1019         if (log)
1020         {
1021             log->PutCString("Unloaded:");
1022             unloaded_module_list.LogUUIDAndPaths (log, "DynamicLoaderMacOSXDYLD::ModulesDidUnload");
1023         }
1024         m_process->GetTarget().GetImages().Remove (unloaded_module_list);
1025     }
1026     m_dyld_image_infos_stop_id = m_process->GetStopID();
1027     return true;
1028 }
1029 
1030 bool
1031 DynamicLoaderMacOSXDYLD::ReadImageInfos (lldb::addr_t image_infos_addr,
1032                                          uint32_t image_infos_count,
1033                                          DYLDImageInfo::collection &image_infos)
1034 {
1035     const ByteOrder endian = m_dyld.GetByteOrder();
1036     const uint32_t addr_size = m_dyld.GetAddressByteSize();
1037 
1038     image_infos.resize(image_infos_count);
1039     const size_t count = image_infos.size() * 3 * addr_size;
1040     DataBufferHeap info_data(count, 0);
1041     Error error;
1042     const size_t bytes_read = m_process->ReadMemory (image_infos_addr,
1043                                                      info_data.GetBytes(),
1044                                                      info_data.GetByteSize(),
1045                                                      error);
1046     if (bytes_read == count)
1047     {
1048         lldb::offset_t info_data_offset = 0;
1049         DataExtractor info_data_ref(info_data.GetBytes(), info_data.GetByteSize(), endian, addr_size);
1050         for (int i = 0; i < image_infos.size() && info_data_ref.ValidOffset(info_data_offset); i++)
1051         {
1052             image_infos[i].address = info_data_ref.GetPointer(&info_data_offset);
1053             lldb::addr_t path_addr = info_data_ref.GetPointer(&info_data_offset);
1054             image_infos[i].mod_date = info_data_ref.GetPointer(&info_data_offset);
1055 
1056             char raw_path[PATH_MAX];
1057             m_process->ReadCStringFromMemory (path_addr, raw_path, sizeof(raw_path), error);
1058             // don't resolve the path
1059             if (error.Success())
1060             {
1061                 const bool resolve_path = false;
1062                 image_infos[i].file_spec.SetFile(raw_path, resolve_path);
1063             }
1064         }
1065         return true;
1066     }
1067     else
1068     {
1069         return false;
1070     }
1071 }
1072 
1073 //----------------------------------------------------------------------
1074 // If we have found where the "_dyld_all_image_infos" lives in memory,
1075 // read the current info from it, and then update all image load
1076 // addresses (or lack thereof).  Only do this if this is the first time
1077 // we're reading the dyld infos.  Return true if we actually read anything,
1078 // and false otherwise.
1079 //----------------------------------------------------------------------
1080 bool
1081 DynamicLoaderMacOSXDYLD::InitializeFromAllImageInfos ()
1082 {
1083     LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
1084 
1085     Mutex::Locker locker(m_mutex);
1086     if (m_process->GetStopID() == m_dyld_image_infos_stop_id
1087           || m_dyld_image_infos.size() != 0)
1088         return false;
1089 
1090     if (ReadAllImageInfosStructure ())
1091     {
1092         // Nothing to load or unload?
1093         if (m_dyld_all_image_infos.dylib_info_count == 0)
1094             return true;
1095 
1096         if (m_dyld_all_image_infos.dylib_info_addr == 0)
1097         {
1098             // DYLD is updating the images now.  So we should say we have no images, and then we'll
1099             // figure it out when we hit the added breakpoint.
1100             return false;
1101         }
1102         else
1103         {
1104             if (!AddModulesUsingImageInfosAddress (m_dyld_all_image_infos.dylib_info_addr,
1105                                                    m_dyld_all_image_infos.dylib_info_count))
1106             {
1107                 DEBUG_PRINTF("%s", "unable to read all data for all_dylib_infos.");
1108                 m_dyld_image_infos.clear();
1109             }
1110         }
1111 
1112         // Now we have one more bit of business.  If there is a library left in the images for our target that
1113         // doesn't have a load address, then it must be something that we were expecting to load (for instance we
1114         // read a load command for it) but it didn't in fact load - probably because DYLD_*_PATH pointed
1115         // to an equivalent version.  We don't want it to stay in the target's module list or it will confuse
1116         // us, so unload it here.
1117         Target &target = m_process->GetTarget();
1118         const ModuleList &target_modules = target.GetImages();
1119         ModuleList not_loaded_modules;
1120         Mutex::Locker modules_locker(target_modules.GetMutex());
1121 
1122         size_t num_modules = target_modules.GetSize();
1123         for (size_t i = 0; i < num_modules; i++)
1124         {
1125             ModuleSP module_sp = target_modules.GetModuleAtIndexUnlocked (i);
1126             if (!module_sp->IsLoadedInTarget (&target))
1127             {
1128                 if (log)
1129                 {
1130                     StreamString s;
1131                     module_sp->GetDescription (&s);
1132                     log->Printf ("Unloading pre-run module: %s.", s.GetData ());
1133                 }
1134                 not_loaded_modules.Append (module_sp);
1135             }
1136         }
1137 
1138         if (not_loaded_modules.GetSize() != 0)
1139         {
1140             target.GetImages().Remove(not_loaded_modules);
1141         }
1142 
1143         return true;
1144     }
1145     else
1146         return false;
1147 }
1148 
1149 //----------------------------------------------------------------------
1150 // Read a mach_header at ADDR into HEADER, and also fill in the load
1151 // command data into LOAD_COMMAND_DATA if it is non-NULL.
1152 //
1153 // Returns true if we succeed, false if we fail for any reason.
1154 //----------------------------------------------------------------------
1155 bool
1156 DynamicLoaderMacOSXDYLD::ReadMachHeader (lldb::addr_t addr, llvm::MachO::mach_header *header, DataExtractor *load_command_data)
1157 {
1158     DataBufferHeap header_bytes(sizeof(llvm::MachO::mach_header), 0);
1159     Error error;
1160     size_t bytes_read = m_process->ReadMemory (addr,
1161                                                header_bytes.GetBytes(),
1162                                                header_bytes.GetByteSize(),
1163                                                error);
1164     if (bytes_read == sizeof(llvm::MachO::mach_header))
1165     {
1166         lldb::offset_t offset = 0;
1167         ::memset (header, 0, sizeof(llvm::MachO::mach_header));
1168 
1169         // Get the magic byte unswapped so we can figure out what we are dealing with
1170         DataExtractor data(header_bytes.GetBytes(), header_bytes.GetByteSize(), lldb::endian::InlHostByteOrder(), 4);
1171         header->magic = data.GetU32(&offset);
1172         lldb::addr_t load_cmd_addr = addr;
1173         data.SetByteOrder(DynamicLoaderMacOSXDYLD::GetByteOrderFromMagic(header->magic));
1174         switch (header->magic)
1175         {
1176         case llvm::MachO::HeaderMagic32:
1177         case llvm::MachO::HeaderMagic32Swapped:
1178             data.SetAddressByteSize(4);
1179             load_cmd_addr += sizeof(llvm::MachO::mach_header);
1180             break;
1181 
1182         case llvm::MachO::HeaderMagic64:
1183         case llvm::MachO::HeaderMagic64Swapped:
1184             data.SetAddressByteSize(8);
1185             load_cmd_addr += sizeof(llvm::MachO::mach_header_64);
1186             break;
1187 
1188         default:
1189             return false;
1190         }
1191 
1192         // Read the rest of dyld's mach header
1193         if (data.GetU32(&offset, &header->cputype, (sizeof(llvm::MachO::mach_header)/sizeof(uint32_t)) - 1))
1194         {
1195             if (load_command_data == NULL)
1196                 return true; // We were able to read the mach_header and weren't asked to read the load command bytes
1197 
1198             DataBufferSP load_cmd_data_sp(new DataBufferHeap(header->sizeofcmds, 0));
1199 
1200             size_t load_cmd_bytes_read = m_process->ReadMemory (load_cmd_addr,
1201                                                                 load_cmd_data_sp->GetBytes(),
1202                                                                 load_cmd_data_sp->GetByteSize(),
1203                                                                 error);
1204 
1205             if (load_cmd_bytes_read == header->sizeofcmds)
1206             {
1207                 // Set the load command data and also set the correct endian
1208                 // swap settings and the correct address size
1209                 load_command_data->SetData(load_cmd_data_sp, 0, header->sizeofcmds);
1210                 load_command_data->SetByteOrder(data.GetByteOrder());
1211                 load_command_data->SetAddressByteSize(data.GetAddressByteSize());
1212                 return true; // We successfully read the mach_header and the load command data
1213             }
1214 
1215             return false; // We weren't able to read the load command data
1216         }
1217     }
1218     return false; // We failed the read the mach_header
1219 }
1220 
1221 
1222 //----------------------------------------------------------------------
1223 // Parse the load commands for an image
1224 //----------------------------------------------------------------------
1225 uint32_t
1226 DynamicLoaderMacOSXDYLD::ParseLoadCommands (const DataExtractor& data, DYLDImageInfo& dylib_info, FileSpec *lc_id_dylinker)
1227 {
1228     lldb::offset_t offset = 0;
1229     uint32_t cmd_idx;
1230     Segment segment;
1231     dylib_info.Clear (true);
1232 
1233     for (cmd_idx = 0; cmd_idx < dylib_info.header.ncmds; cmd_idx++)
1234     {
1235         // Clear out any load command specific data from DYLIB_INFO since
1236         // we are about to read it.
1237 
1238         if (data.ValidOffsetForDataOfSize (offset, sizeof(llvm::MachO::load_command)))
1239         {
1240             llvm::MachO::load_command load_cmd;
1241             lldb::offset_t load_cmd_offset = offset;
1242             load_cmd.cmd = data.GetU32 (&offset);
1243             load_cmd.cmdsize = data.GetU32 (&offset);
1244             switch (load_cmd.cmd)
1245             {
1246             case llvm::MachO::LoadCommandSegment32:
1247                 {
1248                     segment.name.SetTrimmedCStringWithLength ((const char *)data.GetData(&offset, 16), 16);
1249                     // We are putting 4 uint32_t values 4 uint64_t values so
1250                     // we have to use multiple 32 bit gets below.
1251                     segment.vmaddr = data.GetU32 (&offset);
1252                     segment.vmsize = data.GetU32 (&offset);
1253                     segment.fileoff = data.GetU32 (&offset);
1254                     segment.filesize = data.GetU32 (&offset);
1255                     // Extract maxprot, initprot, nsects and flags all at once
1256                     data.GetU32(&offset, &segment.maxprot, 4);
1257                     dylib_info.segments.push_back (segment);
1258                 }
1259                 break;
1260 
1261             case llvm::MachO::LoadCommandSegment64:
1262                 {
1263                     segment.name.SetTrimmedCStringWithLength ((const char *)data.GetData(&offset, 16), 16);
1264                     // Extract vmaddr, vmsize, fileoff, and filesize all at once
1265                     data.GetU64(&offset, &segment.vmaddr, 4);
1266                     // Extract maxprot, initprot, nsects and flags all at once
1267                     data.GetU32(&offset, &segment.maxprot, 4);
1268                     dylib_info.segments.push_back (segment);
1269                 }
1270                 break;
1271 
1272             case llvm::MachO::LoadCommandDynamicLinkerIdent:
1273                 if (lc_id_dylinker)
1274                 {
1275                     const lldb::offset_t name_offset = load_cmd_offset + data.GetU32 (&offset);
1276                     const char *path = data.PeekCStr (name_offset);
1277                     lc_id_dylinker->SetFile (path, true);
1278                 }
1279                 break;
1280 
1281             case llvm::MachO::LoadCommandUUID:
1282                 dylib_info.uuid.SetBytes(data.GetData (&offset, 16));
1283                 break;
1284 
1285             default:
1286                 break;
1287             }
1288             // Set offset to be the beginning of the next load command.
1289             offset = load_cmd_offset + load_cmd.cmdsize;
1290         }
1291     }
1292 
1293     // All sections listed in the dyld image info structure will all
1294     // either be fixed up already, or they will all be off by a single
1295     // slide amount that is determined by finding the first segment
1296     // that is at file offset zero which also has bytes (a file size
1297     // that is greater than zero) in the object file.
1298 
1299     // Determine the slide amount (if any)
1300     const size_t num_sections = dylib_info.segments.size();
1301     for (size_t i = 0; i < num_sections; ++i)
1302     {
1303         // Iterate through the object file sections to find the
1304         // first section that starts of file offset zero and that
1305         // has bytes in the file...
1306         if (dylib_info.segments[i].fileoff == 0 && dylib_info.segments[i].filesize > 0)
1307         {
1308             dylib_info.slide = dylib_info.address - dylib_info.segments[i].vmaddr;
1309             // We have found the slide amount, so we can exit
1310             // this for loop.
1311             break;
1312         }
1313     }
1314     return cmd_idx;
1315 }
1316 
1317 //----------------------------------------------------------------------
1318 // Read the mach_header and load commands for each image that the
1319 // _dyld_all_image_infos structure points to and cache the results.
1320 //----------------------------------------------------------------------
1321 
1322 void
1323 DynamicLoaderMacOSXDYLD::UpdateImageInfosHeaderAndLoadCommands(DYLDImageInfo::collection &image_infos,
1324                                                                uint32_t infos_count,
1325                                                                bool update_executable)
1326 {
1327     uint32_t exe_idx = UINT32_MAX;
1328     LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
1329     // Read any UUID values that we can get
1330     for (uint32_t i = 0; i < infos_count; i++)
1331     {
1332         if (!image_infos[i].UUIDValid())
1333         {
1334             DataExtractor data; // Load command data
1335             if (!ReadMachHeader (image_infos[i].address, &image_infos[i].header, &data))
1336                 continue;
1337 
1338             ParseLoadCommands (data, image_infos[i], NULL);
1339 
1340             if (image_infos[i].header.filetype == llvm::MachO::HeaderFileTypeExecutable)
1341                 exe_idx = i;
1342 
1343         }
1344     }
1345 
1346     if (exe_idx < image_infos.size())
1347     {
1348         const bool can_create = true;
1349         ModuleSP exe_module_sp (FindTargetModuleForDYLDImageInfo (image_infos[exe_idx], can_create, NULL));
1350 
1351         if (!exe_module_sp)
1352         {
1353             ArchSpec exe_arch_spec (image_infos[exe_idx].GetArchitecture ());
1354             ModuleSpec module_spec (image_infos[exe_idx].file_spec,
1355                                     image_infos[exe_idx].GetArchitecture ());
1356             module_spec.GetUUID() = image_infos[exe_idx].uuid;
1357             exe_module_sp = m_process->GetTarget().GetSharedModule (module_spec);
1358             if (!exe_module_sp || exe_module_sp->GetObjectFile() == NULL)
1359             {
1360                 const bool add_image_to_target = true;
1361                 const bool load_image_sections_in_target = false;
1362                 exe_module_sp = m_process->ReadModuleFromMemory (image_infos[exe_idx].file_spec,
1363                                                                  image_infos[exe_idx].address,
1364                                                                  add_image_to_target,
1365                                                                  load_image_sections_in_target);
1366             }
1367         }
1368 
1369         if (exe_module_sp)
1370         {
1371             if (exe_module_sp.get() != m_process->GetTarget().GetExecutableModulePointer())
1372             {
1373                 // Don't load dependent images since we are in dyld where we will know
1374                 // and find out about all images that are loaded
1375                 const bool get_dependent_images = false;
1376                 m_process->GetTarget().SetExecutableModule (exe_module_sp,
1377                                                             get_dependent_images);
1378             }
1379         }
1380     }
1381 }
1382 
1383 //----------------------------------------------------------------------
1384 // On Mac OS X libobjc (the Objective-C runtime) has several critical dispatch
1385 // functions written in hand-written assembly, and also have hand-written unwind
1386 // information in the eh_frame section.  Normally we prefer analyzing the
1387 // assembly instructions of a curently executing frame to unwind from that frame --
1388 // but on hand-written functions this profiling can fail.  We should use the
1389 // eh_frame instructions for these functions all the time.
1390 //
1391 // As an aside, it would be better if the eh_frame entries had a flag (or were
1392 // extensible so they could have an Apple-specific flag) which indicates that
1393 // the instructions are asynchronous -- accurate at every instruction, instead
1394 // of our normal default assumption that they are not.
1395 //----------------------------------------------------------------------
1396 
1397 bool
1398 DynamicLoaderMacOSXDYLD::AlwaysRelyOnEHUnwindInfo (SymbolContext &sym_ctx)
1399 {
1400     ModuleSP module_sp;
1401     if (sym_ctx.symbol)
1402     {
1403         module_sp = sym_ctx.symbol->GetAddress().GetModule();
1404     }
1405     if (module_sp.get() == NULL && sym_ctx.function)
1406     {
1407         module_sp = sym_ctx.function->GetAddressRange().GetBaseAddress().GetModule();
1408     }
1409     if (module_sp.get() == NULL)
1410         return false;
1411 
1412     ObjCLanguageRuntime *objc_runtime = m_process->GetObjCLanguageRuntime();
1413     if (objc_runtime != NULL && objc_runtime->IsModuleObjCLibrary (module_sp))
1414     {
1415         return true;
1416     }
1417 
1418     return false;
1419 }
1420 
1421 
1422 
1423 //----------------------------------------------------------------------
1424 // Dump a Segment to the file handle provided.
1425 //----------------------------------------------------------------------
1426 void
1427 DynamicLoaderMacOSXDYLD::Segment::PutToLog (Log *log, lldb::addr_t slide) const
1428 {
1429     if (log)
1430     {
1431         if (slide == 0)
1432             log->Printf ("\t\t%16s [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ")",
1433                          name.AsCString(""),
1434                          vmaddr + slide,
1435                          vmaddr + slide + vmsize);
1436         else
1437             log->Printf ("\t\t%16s [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ") slide = 0x%" PRIx64,
1438                          name.AsCString(""),
1439                          vmaddr + slide,
1440                          vmaddr + slide + vmsize,
1441                          slide);
1442     }
1443 }
1444 
1445 const DynamicLoaderMacOSXDYLD::Segment *
1446 DynamicLoaderMacOSXDYLD::DYLDImageInfo::FindSegment (const ConstString &name) const
1447 {
1448     const size_t num_segments = segments.size();
1449     for (size_t i=0; i<num_segments; ++i)
1450     {
1451         if (segments[i].name == name)
1452             return &segments[i];
1453     }
1454     return NULL;
1455 }
1456 
1457 
1458 //----------------------------------------------------------------------
1459 // Dump an image info structure to the file handle provided.
1460 //----------------------------------------------------------------------
1461 void
1462 DynamicLoaderMacOSXDYLD::DYLDImageInfo::PutToLog (Log *log) const
1463 {
1464     if (log == NULL)
1465         return;
1466     uint8_t *u = (uint8_t *)uuid.GetBytes();
1467 
1468     if (address == LLDB_INVALID_ADDRESS)
1469     {
1470         if (u)
1471         {
1472             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)",
1473                         mod_date,
1474                         u[ 0], u[ 1], u[ 2], u[ 3],
1475                         u[ 4], u[ 5], u[ 6], u[ 7],
1476                         u[ 8], u[ 9], u[10], u[11],
1477                         u[12], u[13], u[14], u[15],
1478                         file_spec.GetDirectory().AsCString(),
1479                         file_spec.GetFilename().AsCString());
1480         }
1481         else
1482             log->Printf("\t                           modtime=0x%8.8" PRIx64 " path='%s/%s' (UNLOADED)",
1483                         mod_date,
1484                         file_spec.GetDirectory().AsCString(),
1485                         file_spec.GetFilename().AsCString());
1486     }
1487     else
1488     {
1489         if (u)
1490         {
1491             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'",
1492                         address,
1493                         mod_date,
1494                         u[ 0], u[ 1], u[ 2], u[ 3],
1495                         u[ 4], u[ 5], u[ 6], u[ 7],
1496                         u[ 8], u[ 9], u[10], u[11],
1497                         u[12], u[13], u[14], u[15],
1498                         file_spec.GetDirectory().AsCString(),
1499                         file_spec.GetFilename().AsCString());
1500         }
1501         else
1502         {
1503             log->Printf("\taddress=0x%16.16" PRIx64 " modtime=0x%8.8" PRIx64 " path='%s/%s'",
1504                         address,
1505                         mod_date,
1506                         file_spec.GetDirectory().AsCString(),
1507                         file_spec.GetFilename().AsCString());
1508 
1509         }
1510         for (uint32_t i=0; i<segments.size(); ++i)
1511             segments[i].PutToLog(log, slide);
1512     }
1513 }
1514 
1515 //----------------------------------------------------------------------
1516 // Dump the _dyld_all_image_infos members and all current image infos
1517 // that we have parsed to the file handle provided.
1518 //----------------------------------------------------------------------
1519 void
1520 DynamicLoaderMacOSXDYLD::PutToLog(Log *log) const
1521 {
1522     if (log == NULL)
1523         return;
1524 
1525     Mutex::Locker locker(m_mutex);
1526     log->Printf("dyld_all_image_infos = { version=%d, count=%d, addr=0x%8.8" PRIx64 ", notify=0x%8.8" PRIx64 " }",
1527                     m_dyld_all_image_infos.version,
1528                     m_dyld_all_image_infos.dylib_info_count,
1529                     (uint64_t)m_dyld_all_image_infos.dylib_info_addr,
1530                     (uint64_t)m_dyld_all_image_infos.notification);
1531     size_t i;
1532     const size_t count = m_dyld_image_infos.size();
1533     if (count > 0)
1534     {
1535         log->PutCString("Loaded:");
1536         for (i = 0; i<count; i++)
1537             m_dyld_image_infos[i].PutToLog(log);
1538     }
1539 }
1540 
1541 void
1542 DynamicLoaderMacOSXDYLD::PrivateInitialize(Process *process)
1543 {
1544     DEBUG_PRINTF("DynamicLoaderMacOSXDYLD::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState()));
1545     Clear(true);
1546     m_process = process;
1547     m_process->GetTarget().GetSectionLoadList().Clear();
1548 }
1549 
1550 bool
1551 DynamicLoaderMacOSXDYLD::SetNotificationBreakpoint ()
1552 {
1553     DEBUG_PRINTF("DynamicLoaderMacOSXDYLD::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState()));
1554     if (m_break_id == LLDB_INVALID_BREAK_ID)
1555     {
1556         if (m_dyld_all_image_infos.notification != LLDB_INVALID_ADDRESS)
1557         {
1558             Address so_addr;
1559             // Set the notification breakpoint and install a breakpoint
1560             // callback function that will get called each time the
1561             // breakpoint gets hit. We will use this to track when shared
1562             // libraries get loaded/unloaded.
1563 
1564             if (m_process->GetTarget().GetSectionLoadList().ResolveLoadAddress(m_dyld_all_image_infos.notification, so_addr))
1565             {
1566                 Breakpoint *dyld_break = m_process->GetTarget().CreateBreakpoint (so_addr, true).get();
1567                 dyld_break->SetCallback (DynamicLoaderMacOSXDYLD::NotifyBreakpointHit, this, true);
1568                 dyld_break->SetBreakpointKind ("shared-library-event");
1569                 m_break_id = dyld_break->GetID();
1570             }
1571         }
1572     }
1573     return m_break_id != LLDB_INVALID_BREAK_ID;
1574 }
1575 
1576 //----------------------------------------------------------------------
1577 // Member function that gets called when the process state changes.
1578 //----------------------------------------------------------------------
1579 void
1580 DynamicLoaderMacOSXDYLD::PrivateProcessStateChanged (Process *process, StateType state)
1581 {
1582     DEBUG_PRINTF("DynamicLoaderMacOSXDYLD::%s(%s)\n", __FUNCTION__, StateAsCString(state));
1583     switch (state)
1584     {
1585     case eStateConnected:
1586     case eStateAttaching:
1587     case eStateLaunching:
1588     case eStateInvalid:
1589     case eStateUnloaded:
1590     case eStateExited:
1591     case eStateDetached:
1592         Clear(false);
1593         break;
1594 
1595     case eStateStopped:
1596         // Keep trying find dyld and set our notification breakpoint each time
1597         // we stop until we succeed
1598         if (!DidSetNotificationBreakpoint () && m_process->IsAlive())
1599         {
1600             if (NeedToLocateDYLD ())
1601                 LocateDYLD ();
1602 
1603             SetNotificationBreakpoint ();
1604         }
1605         break;
1606 
1607     case eStateRunning:
1608     case eStateStepping:
1609     case eStateCrashed:
1610     case eStateSuspended:
1611         break;
1612     }
1613 }
1614 
1615 // This bit in the n_desc field of the mach file means that this is a
1616 // stub that runs arbitrary code to determine the trampoline target.
1617 // We've established a naming convention with the CoreOS folks for the
1618 // equivalent symbols they will use for this (which the objc guys didn't follow...)
1619 // For now we'll just look for all symbols matching that naming convention...
1620 
1621 #define MACH_O_N_SYMBOL_RESOLVER 0x100
1622 
1623 ThreadPlanSP
1624 DynamicLoaderMacOSXDYLD::GetStepThroughTrampolinePlan (Thread &thread, bool stop_others)
1625 {
1626     ThreadPlanSP thread_plan_sp;
1627     StackFrame *current_frame = thread.GetStackFrameAtIndex(0).get();
1628     const SymbolContext &current_context = current_frame->GetSymbolContext(eSymbolContextSymbol);
1629     Symbol *current_symbol = current_context.symbol;
1630     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
1631 
1632     if (current_symbol != NULL)
1633     {
1634         if (current_symbol->IsTrampoline())
1635         {
1636             const ConstString &trampoline_name = current_symbol->GetMangled().GetName(Mangled::ePreferMangled);
1637 
1638             if (trampoline_name)
1639             {
1640                 SymbolContextList target_symbols;
1641                 TargetSP target_sp (thread.CalculateTarget());
1642                 const ModuleList &images = target_sp->GetImages();
1643 
1644                 images.FindSymbolsWithNameAndType(trampoline_name, eSymbolTypeCode, target_symbols);
1645 
1646                 size_t num_original_symbols = target_symbols.GetSize();
1647                 // FIXME: The resolver symbol is only valid in object files.  In binaries it is reused for the
1648                 // shared library slot number.  So we'll have to look this up in the dyld info.
1649                 // For now, just turn this off.
1650 
1651                 // bool orig_is_resolver = (current_symbol->GetFlags() & MACH_O_N_SYMBOL_RESOLVER) == MACH_O_N_SYMBOL_RESOLVER;
1652                 // FIXME: Actually that isn't true, the N_SYMBOL_RESOLVER bit is only valid in .o files.  You can't use
1653                 // the symbol flags to tell whether something is a symbol resolver in a linked image.
1654                 bool orig_is_resolver = false;
1655 
1656                 if (num_original_symbols > 0)
1657                 {
1658                     // We found symbols that look like they are the targets to our symbol.  Now look through the
1659                     // modules containing our symbols to see if there are any for our symbol.
1660 
1661                     ModuleList modules_to_search;
1662 
1663                     for (size_t i = 0; i < num_original_symbols; i++)
1664                     {
1665                         SymbolContext sc;
1666                         target_symbols.GetContextAtIndex(i, sc);
1667 
1668                         ModuleSP module_sp (sc.symbol->CalculateSymbolContextModule());
1669                         if (module_sp)
1670                              modules_to_search.AppendIfNeeded(module_sp);
1671                     }
1672 
1673                     // If the original stub symbol is a resolver, then we don't want to break on the symbol with the
1674                     // original name, but instead on all the symbols it could resolve to since otherwise we would stop
1675                     // in the middle of the resolution...
1676                     // Note that the stub is not of the resolver type it will point to the equivalent symbol,
1677                     // not the original name, so in that case we don't need to do anything.
1678 
1679                     if (orig_is_resolver)
1680                     {
1681                         target_symbols.Clear();
1682 
1683                         FindEquivalentSymbols (current_symbol, modules_to_search, target_symbols);
1684                     }
1685 
1686                     // FIXME - Make the Run to Address take multiple addresses, and
1687                     // run to any of them.
1688                     uint32_t num_symbols = target_symbols.GetSize();
1689                     if (num_symbols > 0)
1690                     {
1691                         std::vector<lldb::addr_t>  addresses;
1692                         addresses.resize (num_symbols);
1693                         for (uint32_t i = 0; i < num_symbols; i++)
1694                         {
1695                             SymbolContext context;
1696                             AddressRange addr_range;
1697                             if (target_symbols.GetContextAtIndex(i, context))
1698                             {
1699                                 context.GetAddressRange (eSymbolContextEverything, 0, false, addr_range);
1700                                 lldb::addr_t load_addr = addr_range.GetBaseAddress().GetLoadAddress(target_sp.get());
1701                                 addresses[i] = load_addr;
1702                             }
1703                         }
1704                         if (addresses.size() > 0)
1705                             thread_plan_sp.reset (new ThreadPlanRunToAddress (thread, addresses, stop_others));
1706                         else
1707                         {
1708                             if (log)
1709                                 log->Printf ("Couldn't resolve the symbol contexts.");
1710                         }
1711                     }
1712                     else
1713                     {
1714                         if (log)
1715                         {
1716                             log->Printf ("Found a resolver stub for: \"%s\" but could not find any symbols it resolves to.",
1717                                          trampoline_name.AsCString());
1718                         }
1719                     }
1720                 }
1721                 else
1722                 {
1723                     if (log)
1724                     {
1725                         log->Printf ("Could not find symbol for trampoline target: \"%s\"", trampoline_name.AsCString());
1726                     }
1727                 }
1728             }
1729         }
1730     }
1731     else
1732     {
1733         if (log)
1734             log->Printf ("Could not find symbol for step through.");
1735     }
1736 
1737     return thread_plan_sp;
1738 }
1739 
1740 size_t
1741 DynamicLoaderMacOSXDYLD::FindEquivalentSymbols (lldb_private::Symbol *original_symbol,
1742                                                lldb_private::ModuleList &images,
1743                                                lldb_private::SymbolContextList &equivalent_symbols)
1744 {
1745     const ConstString &trampoline_name = original_symbol->GetMangled().GetName(Mangled::ePreferMangled);
1746     if (!trampoline_name)
1747         return 0;
1748 
1749     size_t initial_size = equivalent_symbols.GetSize();
1750 
1751     static const char *resolver_name_regex = "(_gc|_non_gc|\\$[A-Z0-9]+)$";
1752     std::string equivalent_regex_buf("^");
1753     equivalent_regex_buf.append (trampoline_name.GetCString());
1754     equivalent_regex_buf.append (resolver_name_regex);
1755 
1756     RegularExpression equivalent_name_regex (equivalent_regex_buf.c_str());
1757     const bool append = true;
1758     images.FindSymbolsMatchingRegExAndType (equivalent_name_regex, eSymbolTypeCode, equivalent_symbols, append);
1759 
1760     return equivalent_symbols.GetSize() - initial_size;
1761 }
1762 
1763 Error
1764 DynamicLoaderMacOSXDYLD::CanLoadImage ()
1765 {
1766     Error error;
1767     // In order for us to tell if we can load a shared library we verify that
1768     // the dylib_info_addr isn't zero (which means no shared libraries have
1769     // been set yet, or dyld is currently mucking with the shared library list).
1770     if (ReadAllImageInfosStructure ())
1771     {
1772         // TODO: also check the _dyld_global_lock_held variable in libSystem.B.dylib?
1773         // TODO: check the malloc lock?
1774         // TODO: check the objective C lock?
1775         if (m_dyld_all_image_infos.dylib_info_addr != 0)
1776             return error; // Success
1777     }
1778 
1779     error.SetErrorString("unsafe to load or unload shared libraries");
1780     return error;
1781 }
1782 
1783 void
1784 DynamicLoaderMacOSXDYLD::Initialize()
1785 {
1786     PluginManager::RegisterPlugin (GetPluginNameStatic(),
1787                                    GetPluginDescriptionStatic(),
1788                                    CreateInstance);
1789 }
1790 
1791 void
1792 DynamicLoaderMacOSXDYLD::Terminate()
1793 {
1794     PluginManager::UnregisterPlugin (CreateInstance);
1795 }
1796 
1797 
1798 const char *
1799 DynamicLoaderMacOSXDYLD::GetPluginNameStatic()
1800 {
1801     return "dynamic-loader.macosx-dyld";
1802 }
1803 
1804 const char *
1805 DynamicLoaderMacOSXDYLD::GetPluginDescriptionStatic()
1806 {
1807     return "Dynamic loader plug-in that watches for shared library loads/unloads in MacOSX user processes.";
1808 }
1809 
1810 
1811 //------------------------------------------------------------------
1812 // PluginInterface protocol
1813 //------------------------------------------------------------------
1814 const char *
1815 DynamicLoaderMacOSXDYLD::GetPluginName()
1816 {
1817     return "DynamicLoaderMacOSXDYLD";
1818 }
1819 
1820 const char *
1821 DynamicLoaderMacOSXDYLD::GetShortPluginName()
1822 {
1823     return GetPluginNameStatic();
1824 }
1825 
1826 uint32_t
1827 DynamicLoaderMacOSXDYLD::GetPluginVersion()
1828 {
1829     return 1;
1830 }
1831 
1832 uint32_t
1833 DynamicLoaderMacOSXDYLD::AddrByteSize()
1834 {
1835     switch (m_dyld.header.magic)
1836     {
1837         case llvm::MachO::HeaderMagic32:
1838         case llvm::MachO::HeaderMagic32Swapped:
1839             return 4;
1840 
1841         case llvm::MachO::HeaderMagic64:
1842         case llvm::MachO::HeaderMagic64Swapped:
1843             return 8;
1844 
1845         default:
1846             break;
1847     }
1848     return 0;
1849 }
1850 
1851 lldb::ByteOrder
1852 DynamicLoaderMacOSXDYLD::GetByteOrderFromMagic (uint32_t magic)
1853 {
1854     switch (magic)
1855     {
1856         case llvm::MachO::HeaderMagic32:
1857         case llvm::MachO::HeaderMagic64:
1858             return lldb::endian::InlHostByteOrder();
1859 
1860         case llvm::MachO::HeaderMagic32Swapped:
1861         case llvm::MachO::HeaderMagic64Swapped:
1862             if (lldb::endian::InlHostByteOrder() == lldb::eByteOrderBig)
1863                 return lldb::eByteOrderLittle;
1864             else
1865                 return lldb::eByteOrderBig;
1866 
1867         default:
1868             break;
1869     }
1870     return lldb::eByteOrderInvalid;
1871 }
1872 
1873 lldb::ByteOrder
1874 DynamicLoaderMacOSXDYLD::DYLDImageInfo::GetByteOrder()
1875 {
1876     return DynamicLoaderMacOSXDYLD::GetByteOrderFromMagic(header.magic);
1877 }
1878 
1879