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