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