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