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