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