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