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