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 #include "DynamicLoaderMacOSXDYLDLog.h"
27 
28 //#define ENABLE_DEBUG_PRINTF // COMMENT THIS LINE OUT PRIOR TO CHECKIN
29 #ifdef ENABLE_DEBUG_PRINTF
30 #include <stdio.h>
31 #define DEBUG_PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__)
32 #else
33 #define DEBUG_PRINTF(fmt, ...)
34 #endif
35 
36 using namespace lldb;
37 using namespace lldb_private;
38 using namespace llvm::MachO;
39 
40 /// FIXME - The ObjC Runtime trampoline handler doesn't really belong here.
41 /// I am putting it here so I can invoke it in the Trampoline code here, but
42 /// it should be moved to the ObjC Runtime support when it is set up.
43 
44 //----------------------------------------------------------------------
45 // Create an instance of this class. This function is filled into
46 // the plugin info class that gets handed out by the plugin factory and
47 // allows the lldb to instantiate an instance of this class.
48 //----------------------------------------------------------------------
49 DynamicLoader *
50 DynamicLoaderMacOSXDYLD::CreateInstance (Process* process)
51 {
52     return new DynamicLoaderMacOSXDYLD (process);
53 }
54 
55 //----------------------------------------------------------------------
56 // Constructor
57 //----------------------------------------------------------------------
58 DynamicLoaderMacOSXDYLD::DynamicLoaderMacOSXDYLD (Process* process) :
59     DynamicLoader(process),
60     m_dyld(),
61     m_dyld_all_image_infos_addr(LLDB_INVALID_ADDRESS),
62     m_dyld_all_image_infos(),
63     m_break_id(LLDB_INVALID_BREAK_ID),
64     m_dyld_image_infos(),
65     m_mutex(Mutex::eMutexTypeRecursive)
66 {
67 }
68 
69 //----------------------------------------------------------------------
70 // Destructor
71 //----------------------------------------------------------------------
72 DynamicLoaderMacOSXDYLD::~DynamicLoaderMacOSXDYLD()
73 {
74     Clear(true);
75 }
76 
77 //------------------------------------------------------------------
78 /// Called after attaching a process.
79 ///
80 /// Allow DynamicLoader plug-ins to execute some code after
81 /// attaching to a process.
82 //------------------------------------------------------------------
83 void
84 DynamicLoaderMacOSXDYLD::DidAttach ()
85 {
86     PrivateInitialize(m_process);
87     if (NeedToLocateDYLD ())
88         LocateDYLD ();
89     SetNotificationBreakpoint ();
90     UpdateAllImageInfos();
91 }
92 
93 //------------------------------------------------------------------
94 /// Called after attaching a process.
95 ///
96 /// Allow DynamicLoader plug-ins to execute some code after
97 /// attaching to a process.
98 //------------------------------------------------------------------
99 void
100 DynamicLoaderMacOSXDYLD::DidLaunch ()
101 {
102     PrivateInitialize(m_process);
103     if (NeedToLocateDYLD ())
104         LocateDYLD ();
105     SetNotificationBreakpoint ();
106     UpdateAllImageInfos();
107 }
108 
109 
110 //----------------------------------------------------------------------
111 // Clear out the state of this class.
112 //----------------------------------------------------------------------
113 void
114 DynamicLoaderMacOSXDYLD::Clear (bool clear_process)
115 {
116     Mutex::Locker locker(m_mutex);
117 
118     if (m_process->IsAlive() && LLDB_BREAK_ID_IS_VALID(m_break_id))
119         m_process->ClearBreakpointSiteByID(m_break_id);
120 
121     if (clear_process)
122         m_process = NULL;
123     m_dyld.Clear(false);
124     m_dyld_all_image_infos_addr = LLDB_INVALID_ADDRESS;
125     m_dyld_all_image_infos.Clear();
126     m_break_id = LLDB_INVALID_BREAK_ID;
127     m_dyld_image_infos.clear();
128 }
129 
130 //----------------------------------------------------------------------
131 // Check if we have found DYLD yet
132 //----------------------------------------------------------------------
133 bool
134 DynamicLoaderMacOSXDYLD::DidSetNotificationBreakpoint() const
135 {
136     return LLDB_BREAK_ID_IS_VALID (m_break_id);
137 }
138 
139 //----------------------------------------------------------------------
140 // Try and figure out where dyld is by first asking the Process
141 // if it knows (which currently calls down in the the lldb::Process
142 // to get the DYLD info (available on SnowLeopard only). If that fails,
143 // then check in the default addresses.
144 //----------------------------------------------------------------------
145 bool
146 DynamicLoaderMacOSXDYLD::LocateDYLD()
147 {
148     if (m_dyld_all_image_infos_addr == LLDB_INVALID_ADDRESS)
149         m_dyld_all_image_infos_addr = m_process->GetImageInfoAddress ();
150 
151     if (m_dyld_all_image_infos_addr != LLDB_INVALID_ADDRESS)
152     {
153         if (ReadAllImageInfosStructure ())
154         {
155             if (m_dyld_all_image_infos.dyldImageLoadAddress != LLDB_INVALID_ADDRESS)
156                 return ReadDYLDInfoFromMemoryAndSetNotificationCallback (m_dyld_all_image_infos.dyldImageLoadAddress);
157             else
158                 return ReadDYLDInfoFromMemoryAndSetNotificationCallback (m_dyld_all_image_infos_addr & 0xfffffffffff00000ull);
159         }
160     }
161 
162     // Check some default values
163     Module *executable = m_process->GetTarget().GetExecutableModule().get();
164 
165     if (executable)
166     {
167         if (executable->GetArchitecture().GetAddressByteSize() == 8)
168         {
169             return ReadDYLDInfoFromMemoryAndSetNotificationCallback(0x7fff5fc00000ull);
170         }
171 #if defined (__arm__)
172         else
173         {
174             ArchSpec arm_arch("arm");
175             if (arm_arch == executable->Arch())
176                 return ReadDYLDInfoFromMemoryAndSetNotificationCallback(0x2fe00000);
177         }
178 #endif
179         return ReadDYLDInfoFromMemoryAndSetNotificationCallback(0x8fe00000);
180     }
181     return false;
182 }
183 
184 //----------------------------------------------------------------------
185 // Assume that dyld is in memory at ADDR and try to parse it's load
186 // commands
187 //----------------------------------------------------------------------
188 bool
189 DynamicLoaderMacOSXDYLD::ReadDYLDInfoFromMemoryAndSetNotificationCallback(lldb::addr_t addr)
190 {
191     DataExtractor data; // Load command data
192     if (ReadMachHeader (addr, &m_dyld.header, &data))
193     {
194         if (m_dyld.header.filetype == HeaderFileTypeDynamicLinkEditor)
195         {
196             m_dyld.address = addr;
197             ModuleSP dyld_module_sp;
198             if (ParseLoadCommands (data, m_dyld, &m_dyld.file_spec))
199             {
200                 if (m_dyld.file_spec)
201                 {
202                     ArchSpec dyld_arch(eArchTypeMachO, m_dyld.header.cputype, m_dyld.header.cpusubtype);
203                     dyld_module_sp = m_process->GetTarget().GetImages().FindFirstModuleForFileSpec (m_dyld.file_spec);
204 
205                     if (dyld_module_sp.get() == NULL || dyld_module_sp->GetArchitecture() != dyld_arch)
206                     {
207                         dyld_module_sp = m_process->GetTarget().GetSharedModule (m_dyld.file_spec,
208                                                                                  dyld_arch,
209                                                                                  &m_dyld.uuid);
210                     }
211 
212                     UpdateImageLoadAddress(dyld_module_sp.get(), m_dyld);
213                 }
214             }
215 
216             if (m_dyld_all_image_infos_addr == LLDB_INVALID_ADDRESS && dyld_module_sp.get())
217             {
218                 static ConstString g_dyld_all_image_infos ("dyld_all_image_infos");
219                 const Symbol *symbol = dyld_module_sp->FindFirstSymbolWithNameAndType (g_dyld_all_image_infos, eSymbolTypeData);
220                 if (symbol)
221                     m_dyld_all_image_infos_addr = symbol->GetValue().GetLoadAddress(&m_process->GetTarget());
222             }
223 
224             // Update all image infos
225             UpdateAllImageInfos();
226 
227             // If we didn't have an executable before, but now we do, then the
228             // dyld module shared pointer might be unique and we may need to add
229             // it again (since Target::SetExecutableModule() will clear the
230             // images). So append the dyld module back to the list if it is
231             /// unique!
232             if (m_process->GetTarget().GetImages().AppendInNeeded (dyld_module_sp))
233                 UpdateImageLoadAddress(dyld_module_sp.get(), m_dyld);
234 
235             return true;
236         }
237     }
238     return false;
239 }
240 
241 bool
242 DynamicLoaderMacOSXDYLD::NeedToLocateDYLD () const
243 {
244     return m_dyld_all_image_infos_addr == LLDB_INVALID_ADDRESS;
245 }
246 
247 bool
248 DynamicLoaderMacOSXDYLD::UpdateCommPageLoadAddress(Module *module)
249 {
250     bool changed = false;
251     if (module)
252     {
253         ObjectFile *image_object_file = module->GetObjectFile();
254         if (image_object_file)
255         {
256             SectionList *section_list = image_object_file->GetSectionList ();
257             if (section_list)
258             {
259                 uint32_t num_sections = section_list->GetSize();
260                 for (uint32_t i=0; i<num_sections; ++i)
261                 {
262                     Section* section = section_list->GetSectionAtIndex (i).get();
263                     if (section)
264                     {
265                         const addr_t new_section_load_addr = section->GetFileAddress ();
266                         const addr_t old_section_load_addr = m_process->GetTarget().GetSectionLoadList().GetSectionLoadAddress (section);
267                         if (old_section_load_addr == LLDB_INVALID_ADDRESS ||
268                             old_section_load_addr != new_section_load_addr)
269                         {
270                             if (m_process->GetTarget().GetSectionLoadList().SetSectionLoadAddress (section, section->GetFileAddress ()))
271                                 changed = true;
272                         }
273                     }
274                 }
275             }
276         }
277     }
278     return changed;
279 }
280 
281 //----------------------------------------------------------------------
282 // Update the load addresses for all segments in MODULE using the
283 // updated INFO that is passed in.
284 //----------------------------------------------------------------------
285 bool
286 DynamicLoaderMacOSXDYLD::UpdateImageLoadAddress (Module *module, struct DYLDImageInfo& info)
287 {
288     bool changed = false;
289     if (module)
290     {
291         ObjectFile *image_object_file = module->GetObjectFile();
292         if (image_object_file)
293         {
294             SectionList *section_list = image_object_file->GetSectionList ();
295             if (section_list)
296             {
297                 // All sections listed in the dyld image info structure will all
298                 // either be fixed up already, or they will all be off by a single
299                 // slide amount that is determined by finding the first segment
300                 // that is at file offset zero which also has bytes (a file size
301                 // that is greater than zero) in the object file.
302 
303                 // Determine the slide amount (if any)
304                 info.slide = 0;
305                 const size_t num_sections = section_list->GetSize();
306                 size_t sect_idx = 0;
307                 for (sect_idx = 0; sect_idx < num_sections; ++sect_idx)
308                 {
309                     // Iterate through the object file sections to find the
310                     // first section that starts of file offset zero and that
311                     // has bytes in the file...
312                     Section *section = section_list->GetSectionAtIndex (sect_idx).get();
313                     if (section)
314                     {
315                         // Find the first section that begins at file offset zero
316                         // a file size (skip page zero).
317                         if (section->GetFileOffset() == 0 && section->GetFileSize() > 0)
318                         {
319                             // We have now found the section, lets match it up
320                             // with the section in the dyld image info structure.
321                             const Segment *dyld_segment = info.FindSegment (section->GetName());
322                             if (dyld_segment)
323                                 info.slide = info.address - dyld_segment->addr;
324                             // We have found the slide amount, so we can exit
325                             // this for loop.
326                             break;
327                         }
328                     }
329                 }
330 
331                 // We now know the slide amount, so go through all sections
332                 // and update the load addresses with the correct values.
333                 uint32_t num_segments = info.segments.size();
334                 for (uint32_t i=0; i<num_segments; ++i)
335                 {
336                     SectionSP section_sp(section_list->FindSectionByName(info.segments[i].name));
337                     assert (section_sp.get() != NULL);
338                     const addr_t new_section_load_addr = info.segments[i].addr + info.slide;
339                     const addr_t old_section_load_addr = m_process->GetTarget().GetSectionLoadList().GetSectionLoadAddress (section_sp.get());
340                     if (old_section_load_addr == LLDB_INVALID_ADDRESS ||
341                         old_section_load_addr != new_section_load_addr)
342                     {
343                         if (m_process->GetTarget().GetSectionLoadList().SetSectionLoadAddress (section_sp.get(), new_section_load_addr))
344                             changed = true;
345                     }
346                 }
347             }
348         }
349     }
350     return changed;
351 }
352 
353 //----------------------------------------------------------------------
354 // Update the load addresses for all segments in MODULE using the
355 // updated INFO that is passed in.
356 //----------------------------------------------------------------------
357 bool
358 DynamicLoaderMacOSXDYLD::UnloadImageLoadAddress (Module *module, struct DYLDImageInfo& info)
359 {
360     bool changed = false;
361     if (module)
362     {
363         ObjectFile *image_object_file = module->GetObjectFile();
364         if (image_object_file)
365         {
366             SectionList *section_list = image_object_file->GetSectionList ();
367             if (section_list)
368             {
369                 uint32_t num_segments = info.segments.size();
370                 for (uint32_t i=0; i<num_segments; ++i)
371                 {
372                     SectionSP section_sp(section_list->FindSectionByName(info.segments[i].name));
373                     assert (section_sp.get() != NULL);
374                     const addr_t old_section_load_addr = info.segments[i].addr + info.slide;
375                     if (m_process->GetTarget().GetSectionLoadList().SetSectionUnloaded (section_sp.get(), old_section_load_addr))
376                         changed = true;
377                 }
378             }
379         }
380     }
381     return changed;
382 }
383 
384 
385 //----------------------------------------------------------------------
386 // Static callback function that gets called when our DYLD notification
387 // breakpoint gets hit. We update all of our image infos and then
388 // let our super class DynamicLoader class decide if we should stop
389 // or not (based on global preference).
390 //----------------------------------------------------------------------
391 bool
392 DynamicLoaderMacOSXDYLD::NotifyBreakpointHit (void *baton, StoppointCallbackContext *context, lldb::user_id_t break_id, lldb::user_id_t break_loc_id)
393 {
394     // Let the event know that the images have changed
395     DynamicLoaderMacOSXDYLD* dyld_instance = (DynamicLoaderMacOSXDYLD*) baton;
396     dyld_instance->UpdateAllImageInfos();
397     // Return true to stop the target, false to just let the target run
398     return dyld_instance->GetStopWhenImagesChange();
399 }
400 
401 bool
402 DynamicLoaderMacOSXDYLD::ReadAllImageInfosStructure ()
403 {
404     Mutex::Locker locker(m_mutex);
405     m_dyld_all_image_infos.Clear();
406     if (m_dyld_all_image_infos_addr != LLDB_INVALID_ADDRESS)
407     {
408         const ByteOrder endian = m_process->GetByteOrder();
409         const uint32_t addr_size = m_process->GetAddressByteSize();
410         uint8_t buf[256];
411         const size_t count_v2 =  sizeof (uint32_t) + // version
412                                  sizeof (uint32_t) + // infoArrayCount
413                                  addr_size +         // infoArray
414                                  addr_size +         // notification
415                                  addr_size +         // processDetachedFromSharedRegion + libSystemInitialized + pad
416                                  addr_size;          // dyldImageLoadAddress
417         const size_t count_v11 = count_v2 +
418                                  addr_size +         // jitInfo
419                                  addr_size +         // dyldVersion
420                                  addr_size +         // errorMessage
421                                  addr_size +         // terminationFlags
422                                  addr_size +         // coreSymbolicationShmPage
423                                  addr_size +         // systemOrderFlag
424                                  addr_size +         // uuidArrayCount
425                                  addr_size +         // uuidArray
426                                  addr_size +         // dyldAllImageInfosAddress
427                                  addr_size +         // initialImageCount
428                                  addr_size +         // errorKind
429                                  addr_size +         // errorClientOfDylibPath
430                                  addr_size +         // errorTargetDylibPath
431                                  addr_size;          // errorSymbol
432         assert (sizeof (buf) > count_v11);
433 
434         int count;
435         Error error;
436         if (m_process->ReadMemory (m_dyld_all_image_infos_addr, buf, 4, error) == 4)
437         {
438             DataExtractor data(buf, 4, endian, addr_size);
439             uint32_t offset = 0;
440             m_dyld_all_image_infos.version = data.GetU32(&offset);
441         }
442         else
443         {
444             return false;
445         }
446 
447         if (m_dyld_all_image_infos.version >= 11)
448             count = count_v11;
449         else
450             count = count_v2;
451 
452         const size_t bytes_read = m_process->ReadMemory (m_dyld_all_image_infos_addr, buf, count, error);
453         if (bytes_read == count)
454         {
455             DataExtractor data(buf, count, endian, addr_size);
456             uint32_t offset = 0;
457             m_dyld_all_image_infos.version = data.GetU32(&offset);
458             m_dyld_all_image_infos.dylib_info_count = data.GetU32(&offset);
459             m_dyld_all_image_infos.dylib_info_addr = data.GetPointer(&offset);
460             m_dyld_all_image_infos.notification = data.GetPointer(&offset);
461             m_dyld_all_image_infos.processDetachedFromSharedRegion = data.GetU8(&offset);
462             m_dyld_all_image_infos.libSystemInitialized = data.GetU8(&offset);
463             // Adjust for padding.
464             offset += addr_size - 2;
465             m_dyld_all_image_infos.dyldImageLoadAddress = data.GetPointer(&offset);
466             if (m_dyld_all_image_infos.version >= 11)
467             {
468                 offset += addr_size * 8;
469                 uint64_t dyld_all_image_infos_addr = data.GetPointer(&offset);
470 
471                 // When we started, we were given the actual address of the all_image_infos
472                 // struct (probably via TASK_DYLD_INFO) in memory - this address is stored in
473                 // m_dyld_all_image_infos_addr and is the most accurate address we have.
474 
475                 // We read the dyld_all_image_infos struct from memory; it contains its own address.
476                 // If the address in the struct does not match the actual address,
477                 // the dyld we're looking at has been loaded at a different location (slid) from
478                 // where it intended to load.  The addresses in the dyld_all_image_infos struct
479                 // are the original, non-slid addresses, and need to be adjusted.  Most importantly
480                 // the address of dyld and the notification address need to be adjusted.
481 
482                 if (dyld_all_image_infos_addr != m_dyld_all_image_infos_addr)
483                 {
484                     uint64_t image_infos_offset = dyld_all_image_infos_addr - m_dyld_all_image_infos.dyldImageLoadAddress;
485                     uint64_t notification_offset = m_dyld_all_image_infos.notification - m_dyld_all_image_infos.dyldImageLoadAddress;
486                     m_dyld_all_image_infos.dyldImageLoadAddress = m_dyld_all_image_infos_addr - image_infos_offset;
487                     m_dyld_all_image_infos.notification = m_dyld_all_image_infos.dyldImageLoadAddress + notification_offset;
488                 }
489             }
490             return true;
491         }
492     }
493     return false;
494 }
495 
496 //----------------------------------------------------------------------
497 // If we have found where the "_dyld_all_image_infos" lives in memory,
498 // read the current info from it, and then update all image load
499 // addresses (or lack thereof).
500 //----------------------------------------------------------------------
501 uint32_t
502 DynamicLoaderMacOSXDYLD::UpdateAllImageInfos()
503 {
504     if (ReadAllImageInfosStructure ())
505     {
506         Mutex::Locker locker(m_mutex);
507         uint32_t idx;
508         uint32_t i = 0;
509         DYLDImageInfo::collection old_dyld_all_image_infos;
510         old_dyld_all_image_infos.swap(m_dyld_image_infos);
511 
512         // If we made it here, we are assuming that the all dylib info data should
513         // be valid, lets read the info array.
514         const ByteOrder endian = m_process->GetByteOrder();
515         const uint32_t addr_size = m_process->GetAddressByteSize();
516 
517         if (m_dyld_all_image_infos.dylib_info_count > 0)
518         {
519             if (m_dyld_all_image_infos.dylib_info_addr == 0)
520             {
521                 // DYLD is updating the images right now...
522             }
523             else
524             {
525                 m_dyld_image_infos.resize(m_dyld_all_image_infos.dylib_info_count);
526                 const size_t count = m_dyld_image_infos.size() * 3 * addr_size;
527                 DataBufferHeap info_data(count, 0);
528                 Error error;
529                 const size_t bytes_read = m_process->ReadMemory (m_dyld_all_image_infos.dylib_info_addr,
530                                                                  info_data.GetBytes(),
531                                                                  info_data.GetByteSize(),
532                                                                  error);
533                 if (bytes_read == count)
534                 {
535                     uint32_t info_data_offset = 0;
536                     DataExtractor info_data_ref(info_data.GetBytes(), info_data.GetByteSize(), endian, addr_size);
537                     for (i = 0; info_data_ref.ValidOffset(info_data_offset); i++)
538                     {
539                         assert (i < m_dyld_image_infos.size());
540                         m_dyld_image_infos[i].address = info_data_ref.GetPointer(&info_data_offset);
541                         lldb::addr_t path_addr = info_data_ref.GetPointer(&info_data_offset);
542                         m_dyld_image_infos[i].mod_date = info_data_ref.GetPointer(&info_data_offset);
543 
544                         char raw_path[PATH_MAX];
545                         m_process->ReadMemory (path_addr, raw_path, sizeof(raw_path), error);
546                         m_dyld_image_infos[i].file_spec.SetFile(raw_path, true);
547                     }
548                     assert(i == m_dyld_all_image_infos.dylib_info_count);
549 
550                     UpdateAllImageInfosHeaderAndLoadCommands();
551                 }
552                 else
553                 {
554                     DEBUG_PRINTF( "unable to read all data for all_dylib_infos.");
555                     m_dyld_image_infos.clear();
556                 }
557             }
558         }
559         else
560         {
561             m_dyld_image_infos.clear();
562         }
563 
564         // If our new list is smaller than our old list, we have unloaded
565         // some shared libraries
566         if (m_dyld_image_infos.size() < old_dyld_all_image_infos.size())
567         {
568             ModuleList unloaded_module_list;
569             for (idx = m_dyld_image_infos.size(); idx < old_dyld_all_image_infos.size(); ++idx)
570             {
571                 ModuleSP unload_image_module_sp(m_process->GetTarget().GetImages().FindFirstModuleForFileSpec (old_dyld_all_image_infos[idx].file_spec));
572                 if (unload_image_module_sp.get())
573                 {
574                     if (UnloadImageLoadAddress (unload_image_module_sp.get(), old_dyld_all_image_infos[idx]))
575                         unloaded_module_list.AppendInNeeded (unload_image_module_sp);
576                 }
577             }
578             if (unloaded_module_list.GetSize() > 0)
579                 m_process->GetTarget().ModulesDidUnload (unloaded_module_list);
580         }
581     }
582     else
583     {
584         m_dyld_image_infos.clear();
585     }
586 
587     const uint32_t num_dylibs = m_dyld_image_infos.size();
588     if (num_dylibs > 0)
589     {
590         ModuleList loaded_module_list;
591         for (uint32_t idx = 0; idx<num_dylibs; ++idx)
592         {
593             ArchSpec arch_spec(eArchTypeMachO, m_dyld_image_infos[idx].header.cputype, m_dyld_image_infos[idx].header.cpusubtype);
594             ModuleSP image_module_sp(m_process->GetTarget().GetImages().FindFirstModuleForFileSpec (m_dyld_image_infos[idx].file_spec));
595             if (image_module_sp.get() == NULL || image_module_sp->GetArchitecture() != arch_spec)
596             {
597                 image_module_sp = m_process->GetTarget().GetSharedModule (m_dyld_image_infos[idx].file_spec,
598                                                                           arch_spec,
599                                                                           &m_dyld_image_infos[idx].uuid);
600             }
601 
602             if (image_module_sp)
603             {
604                 if (m_dyld_image_infos[idx].header.filetype == HeaderFileTypeDynamicLinkEditor)
605                     image_module_sp->SetIsDynamicLinkEditor (true);
606 
607                 ObjectFile *objfile = image_module_sp->GetObjectFile ();
608                 if (objfile)
609                 {
610                     SectionList *sections = objfile->GetSectionList();
611                     if (sections)
612                     {
613                         ConstString commpage_dbstr("__commpage");
614                         Section *commpage_section = sections->FindSectionByName(commpage_dbstr).get();
615                         if (commpage_section)
616                         {
617                             FileSpec objfile_file_spec(objfile->GetFileSpec());
618                             ModuleSP commpage_image_module_sp(m_process->GetTarget().GetImages().FindFirstModuleForFileSpec (objfile_file_spec, &commpage_dbstr));
619                             if (commpage_image_module_sp.get() == NULL)
620                             {
621                                 commpage_image_module_sp = m_process->GetTarget().GetSharedModule (m_dyld_image_infos[idx].file_spec,
622                                                                                                    arch_spec,
623                                                                                                    &m_dyld_image_infos[idx].uuid,
624                                                                                                    &commpage_dbstr,
625                                                                                                    objfile->GetOffset() + commpage_section->GetOffset());
626                                 UpdateCommPageLoadAddress(commpage_image_module_sp.get());
627                             }
628                         }
629                     }
630                 }
631 
632                 // UpdateImageLoadAddress will return true if any segments
633                 // change load address. We need to check this so we don't
634                 // mention that all loaded shared libraries are newly loaded
635                 // each time we hit out dyld breakpoint since dyld will list all
636                 // shared libraries each time.
637                 if (UpdateImageLoadAddress (image_module_sp.get(), m_dyld_image_infos[idx]))
638                 {
639                     loaded_module_list.AppendInNeeded (image_module_sp);
640                 }
641             }
642         }
643         PutToLog(DynamicLoaderMacOSXDYLDLog::GetLogIfAllCategoriesSet (1));
644         if (loaded_module_list.GetSize() > 0)
645         {
646             // FIXME: This should really be in the Runtime handlers class, which should get
647             // called by the target's ModulesDidLoad, but we're doing it all locally for now
648             // to save time.
649             // Also, I'm assuming there can be only one libobjc dylib loaded...
650 
651             ObjCLanguageRuntime *objc_runtime = m_process->GetObjCLanguageRuntime();
652             if (objc_runtime != NULL && !objc_runtime->HasReadObjCLibrary())
653             {
654                 size_t num_modules = loaded_module_list.GetSize();
655                 for (int i = 0; i < num_modules; i++)
656                 {
657                     if (objc_runtime->IsModuleObjCLibrary (loaded_module_list.GetModuleAtIndex (i)))
658                     {
659                         objc_runtime->ReadObjCLibrary (loaded_module_list.GetModuleAtIndex (i));
660                         break;
661                     }
662                 }
663             }
664             m_process->GetTarget().ModulesDidLoad (loaded_module_list);
665         }
666     }
667     return m_dyld_image_infos.size();
668 }
669 
670 //----------------------------------------------------------------------
671 // Read a mach_header at ADDR into HEADER, and also fill in the load
672 // command data into LOAD_COMMAND_DATA if it is non-NULL.
673 //
674 // Returns true if we succeed, false if we fail for any reason.
675 //----------------------------------------------------------------------
676 bool
677 DynamicLoaderMacOSXDYLD::ReadMachHeader (lldb::addr_t addr, mach_header *header, DataExtractor *load_command_data)
678 {
679     DataBufferHeap header_bytes(sizeof(mach_header), 0);
680     Error error;
681     size_t bytes_read = m_process->ReadMemory (addr,
682                                                header_bytes.GetBytes(),
683                                                header_bytes.GetByteSize(),
684                                                error);
685     if (bytes_read == sizeof(mach_header))
686     {
687         uint32_t offset = 0;
688         ::memset (header, 0, sizeof(header));
689 
690         // Get the magic byte unswapped so we can figure out what we are dealing with
691         DataExtractor data(header_bytes.GetBytes(), header_bytes.GetByteSize(), eByteOrderHost, 4);
692         header->magic = data.GetU32(&offset);
693         lldb::addr_t load_cmd_addr = addr;
694         data.SetByteOrder(DynamicLoaderMacOSXDYLD::GetByteOrderFromMagic(header->magic));
695         switch (header->magic)
696         {
697         case llvm::MachO::HeaderMagic32:
698         case llvm::MachO::HeaderMagic32Swapped:
699             data.SetAddressByteSize(4);
700             load_cmd_addr += sizeof(mach_header);
701             break;
702 
703         case llvm::MachO::HeaderMagic64:
704         case llvm::MachO::HeaderMagic64Swapped:
705             data.SetAddressByteSize(8);
706             load_cmd_addr += sizeof(mach_header_64);
707             break;
708 
709         default:
710             return false;
711         }
712 
713         // Read the rest of dyld's mach header
714         if (data.GetU32(&offset, &header->cputype, (sizeof(mach_header)/sizeof(uint32_t)) - 1))
715         {
716             if (load_command_data == NULL)
717                 return true; // We were able to read the mach_header and weren't asked to read the load command bytes
718 
719             DataBufferSP load_cmd_data_sp(new DataBufferHeap(header->sizeofcmds, 0));
720 
721             size_t load_cmd_bytes_read = m_process->ReadMemory (load_cmd_addr,
722                                                                 load_cmd_data_sp->GetBytes(),
723                                                                 load_cmd_data_sp->GetByteSize(),
724                                                                 error);
725 
726             if (load_cmd_bytes_read == header->sizeofcmds)
727             {
728                 // Set the load command data and also set the correct endian
729                 // swap settings and the correct address size
730                 load_command_data->SetData(load_cmd_data_sp, 0, header->sizeofcmds);
731                 load_command_data->SetByteOrder(data.GetByteOrder());
732                 load_command_data->SetAddressByteSize(data.GetAddressByteSize());
733                 return true; // We successfully read the mach_header and the load command data
734             }
735 
736             return false; // We weren't able to read the load command data
737         }
738     }
739     return false; // We failed the read the mach_header
740 }
741 
742 
743 //----------------------------------------------------------------------
744 // Parse the load commands for an image
745 //----------------------------------------------------------------------
746 uint32_t
747 DynamicLoaderMacOSXDYLD::ParseLoadCommands (const DataExtractor& data, struct DYLDImageInfo& dylib_info, FileSpec *lc_id_dylinker)
748 {
749     uint32_t offset = 0;
750     uint32_t cmd_idx;
751     Segment segment;
752     dylib_info.Clear (true);
753 
754     for (cmd_idx = 0; cmd_idx < dylib_info.header.ncmds; cmd_idx++)
755     {
756         // Clear out any load command specific data from DYLIB_INFO since
757         // we are about to read it.
758 
759         if (data.ValidOffsetForDataOfSize (offset, sizeof(load_command)))
760         {
761             load_command load_cmd;
762             uint32_t load_cmd_offset = offset;
763             load_cmd.cmd = data.GetU32 (&offset);
764             load_cmd.cmdsize = data.GetU32 (&offset);
765             switch (load_cmd.cmd)
766             {
767             case LoadCommandSegment32:
768                 {
769                     segment.name.SetTrimmedCStringWithLength ((const char *)data.GetData(&offset, 16), 16);
770                     segment.addr = data.GetU32 (&offset);
771                     segment.size = data.GetU32 (&offset);
772                     dylib_info.segments.push_back (segment);
773                 }
774                 break;
775 
776             case LoadCommandSegment64:
777                 {
778                     segment.name.SetTrimmedCStringWithLength ((const char *)data.GetData(&offset, 16), 16);
779                     segment.addr = data.GetU64 (&offset);
780                     segment.size = data.GetU64 (&offset);
781                     dylib_info.segments.push_back (segment);
782                 }
783                 break;
784 
785             case LoadCommandDynamicLinkerIdent:
786                 if (lc_id_dylinker)
787                 {
788                     uint32_t name_offset = load_cmd_offset + data.GetU32 (&offset);
789                     const char *path = data.PeekCStr (name_offset);
790                     lc_id_dylinker->SetFile (path, true);
791                 }
792                 break;
793 
794             case LoadCommandUUID:
795                 dylib_info.uuid.SetBytes(data.GetData (&offset, 16));
796                 break;
797 
798             default:
799                 break;
800             }
801             // Set offset to be the beginning of the next load command.
802             offset = load_cmd_offset + load_cmd.cmdsize;
803         }
804     }
805     return cmd_idx;
806 }
807 
808 //----------------------------------------------------------------------
809 // Read the mach_header and load commands for each image that the
810 // _dyld_all_image_infos structure points to and cache the results.
811 //----------------------------------------------------------------------
812 void
813 DynamicLoaderMacOSXDYLD::UpdateAllImageInfosHeaderAndLoadCommands()
814 {
815     uint32_t exe_idx = UINT32_MAX;
816     // Read any UUID values that we can get
817     for (uint32_t i = 0; i < m_dyld_all_image_infos.dylib_info_count; i++)
818     {
819         if (!m_dyld_image_infos[i].UUIDValid())
820         {
821             DataExtractor data; // Load command data
822             if (!ReadMachHeader (m_dyld_image_infos[i].address, &m_dyld_image_infos[i].header, &data))
823                 continue;
824 
825             ParseLoadCommands (data, m_dyld_image_infos[i], NULL);
826 
827             if (m_dyld_image_infos[i].header.filetype == HeaderFileTypeExecutable)
828                 exe_idx = i;
829         }
830     }
831 
832     if (exe_idx < m_dyld_image_infos.size())
833     {
834         bool set_executable = false;
835         ArchSpec dyld_exe_arch_spec(eArchTypeMachO, m_dyld_image_infos[exe_idx].header.cputype, m_dyld_image_infos[exe_idx].header.cpusubtype);
836         ModuleSP exe_module_sp(m_process->GetTarget().GetExecutableModule());
837         if (exe_module_sp.get())
838         {
839             if (exe_module_sp->GetFileSpec() != m_dyld_image_infos[exe_idx].file_spec ||
840                 exe_module_sp->GetArchitecture() != dyld_exe_arch_spec)
841                 set_executable = true;
842         }
843         else
844             set_executable = true;
845 
846         if (set_executable)
847         {
848             exe_module_sp = m_process->GetTarget().GetSharedModule (m_dyld_image_infos[exe_idx].file_spec,
849                                                                     dyld_exe_arch_spec,
850                                                                     &m_dyld_image_infos[exe_idx].uuid);
851             if (exe_module_sp.get())
852             {
853                 // If we found the file where it purported to be, then it should
854                 // be safe to load dependent images.
855                 bool get_dependent_images = exe_module_sp->GetFileSpec() == m_dyld_image_infos[exe_idx].file_spec;
856 
857                 m_process->GetTarget().SetExecutableModule (exe_module_sp, get_dependent_images);
858             }
859         }
860     }
861 }
862 
863 //----------------------------------------------------------------------
864 // Dump a Segment to the file handle provided.
865 //----------------------------------------------------------------------
866 void
867 DynamicLoaderMacOSXDYLD::Segment::PutToLog (Log *log, lldb::addr_t slide) const
868 {
869     if (log)
870         log->Printf("\t\t%16s [0x%16.16llx - 0x%16.16llx)", name.AsCString(""), addr + slide, addr + slide + size);
871 }
872 
873 const DynamicLoaderMacOSXDYLD::Segment *
874 DynamicLoaderMacOSXDYLD::DYLDImageInfo::FindSegment (const ConstString &name) const
875 {
876     const size_t num_segments = segments.size();
877     for (size_t i=0; i<num_segments; ++i)
878     {
879         if (segments[i].name == name)
880             return &segments[i];
881     }
882     return NULL;
883 }
884 
885 
886 //----------------------------------------------------------------------
887 // Dump an image info structure to the file handle provided.
888 //----------------------------------------------------------------------
889 void
890 DynamicLoaderMacOSXDYLD::DYLDImageInfo::PutToLog (Log *log) const
891 {
892     if (log == NULL)
893         return;
894     uint8_t *u = (uint8_t *)uuid.GetBytes();
895 
896     if (address == LLDB_INVALID_ADDRESS)
897     {
898         if (u)
899         {
900             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)",
901                         mod_date,
902                         u[ 0], u[ 1], u[ 2], u[ 3],
903                         u[ 4], u[ 5], u[ 6], u[ 7],
904                         u[ 8], u[ 9], u[10], u[11],
905                         u[12], u[13], u[14], u[15],
906                         file_spec.GetDirectory().AsCString(),
907                         file_spec.GetFilename().AsCString());
908         }
909         else
910             log->Printf("\t                           modtime=0x%8.8llx path='%s/%s' (UNLOADED)",
911                         mod_date,
912                         file_spec.GetDirectory().AsCString(),
913                         file_spec.GetFilename().AsCString());
914     }
915     else
916     {
917         if (u)
918         {
919             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'",
920                         address,
921                         mod_date,
922                         u[ 0], u[ 1], u[ 2], u[ 3],
923                         u[ 4], u[ 5], u[ 6], u[ 7],
924                         u[ 8], u[ 9], u[10], u[11],
925                         u[12], u[13], u[14], u[15],
926                         file_spec.GetDirectory().AsCString(),
927                         file_spec.GetFilename().AsCString());
928         }
929         else
930         {
931             log->Printf("\taddress=0x%16.16llx modtime=0x%8.8llx path='%s/%s'",
932                         address,
933                         mod_date,
934                         file_spec.GetDirectory().AsCString(),
935                         file_spec.GetFilename().AsCString());
936 
937         }
938         for (uint32_t i=0; i<segments.size(); ++i)
939             segments[i].PutToLog(log, slide);
940     }
941 }
942 
943 //----------------------------------------------------------------------
944 // Dump the _dyld_all_image_infos members and all current image infos
945 // that we have parsed to the file handle provided.
946 //----------------------------------------------------------------------
947 void
948 DynamicLoaderMacOSXDYLD::PutToLog(Log *log) const
949 {
950     if (log == NULL)
951         return;
952 
953     Mutex::Locker locker(m_mutex);
954     log->Printf("dyld_all_image_infos = { version=%d, count=%d, addr=0x%8.8llx, notify=0x%8.8llx }",
955                     m_dyld_all_image_infos.version,
956                     m_dyld_all_image_infos.dylib_info_count,
957                     (uint64_t)m_dyld_all_image_infos.dylib_info_addr,
958                     (uint64_t)m_dyld_all_image_infos.notification);
959     size_t i;
960     const size_t count = m_dyld_image_infos.size();
961     if (count > 0)
962     {
963         log->Printf("\tdyld_image_infos");
964         for (i = 0; i<count; i++)
965             m_dyld_image_infos[i].PutToLog(log);
966     }
967 }
968 
969 //----------------------------------------------------------------------
970 // Static callback function that gets called when the process state
971 // changes.
972 //----------------------------------------------------------------------
973 void
974 DynamicLoaderMacOSXDYLD::Initialize(void *baton, Process *process)
975 {
976     ((DynamicLoaderMacOSXDYLD*)baton)->PrivateInitialize(process);
977 }
978 
979 void
980 DynamicLoaderMacOSXDYLD::PrivateInitialize(Process *process)
981 {
982     DEBUG_PRINTF("DynamicLoaderMacOSXDYLD::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState()));
983     Clear(true);
984     m_process = process;
985 }
986 
987 
988 //----------------------------------------------------------------------
989 // Static callback function that gets called when the process state
990 // changes.
991 //----------------------------------------------------------------------
992 void
993 DynamicLoaderMacOSXDYLD::ProcessStateChanged(void *baton, Process *process, StateType state)
994 {
995     ((DynamicLoaderMacOSXDYLD*)baton)->PrivateProcessStateChanged(process, state);
996 }
997 
998 bool
999 DynamicLoaderMacOSXDYLD::SetNotificationBreakpoint ()
1000 {
1001     DEBUG_PRINTF("DynamicLoaderMacOSXDYLD::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState()));
1002     if (m_break_id == LLDB_INVALID_BREAK_ID)
1003     {
1004         if (m_dyld_all_image_infos.notification != LLDB_INVALID_ADDRESS)
1005         {
1006             Address so_addr;
1007             // Set the notification breakpoint and install a breakpoint
1008             // callback function that will get called each time the
1009             // breakpoint gets hit. We will use this to track when shared
1010             // libraries get loaded/unloaded.
1011 
1012             if (m_process->GetTarget().GetSectionLoadList().ResolveLoadAddress(m_dyld_all_image_infos.notification, so_addr))
1013             {
1014                 Breakpoint *dyld_break = m_process->GetTarget().CreateBreakpoint (so_addr, true).get();
1015                 dyld_break->SetCallback (DynamicLoaderMacOSXDYLD::NotifyBreakpointHit, this, true);
1016                 m_break_id = dyld_break->GetID();
1017             }
1018         }
1019     }
1020     return m_break_id != LLDB_INVALID_BREAK_ID;
1021 }
1022 
1023 //----------------------------------------------------------------------
1024 // Member function that gets called when the process state changes.
1025 //----------------------------------------------------------------------
1026 void
1027 DynamicLoaderMacOSXDYLD::PrivateProcessStateChanged (Process *process, StateType state)
1028 {
1029     DEBUG_PRINTF("DynamicLoaderMacOSXDYLD::%s(%s)\n", __FUNCTION__, StateAsCString(state));
1030     switch (state)
1031     {
1032     case eStateAttaching:
1033     case eStateLaunching:
1034     case eStateInvalid:
1035     case eStateUnloaded:
1036     case eStateExited:
1037     case eStateDetached:
1038         Clear(false);
1039         break;
1040 
1041     case eStateStopped:
1042         // Keep trying find dyld and set our notification breakpoint each time
1043         // we stop until we succeed
1044         if (!DidSetNotificationBreakpoint () && m_process->IsAlive())
1045         {
1046             if (NeedToLocateDYLD ())
1047                 LocateDYLD ();
1048 
1049             SetNotificationBreakpoint ();
1050         }
1051         break;
1052 
1053     case eStateRunning:
1054     case eStateStepping:
1055     case eStateCrashed:
1056     case eStateSuspended:
1057         break;
1058 
1059     default:
1060         break;
1061     }
1062 }
1063 
1064 ThreadPlanSP
1065 DynamicLoaderMacOSXDYLD::GetStepThroughTrampolinePlan (Thread &thread, bool stop_others)
1066 {
1067     ThreadPlanSP thread_plan_sp;
1068     StackFrame *current_frame = thread.GetStackFrameAtIndex(0).get();
1069     const SymbolContext &current_context = current_frame->GetSymbolContext(eSymbolContextSymbol);
1070     Symbol *current_symbol = current_context.symbol;
1071     Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
1072 
1073     if (current_symbol != NULL)
1074     {
1075         if (current_symbol->IsTrampoline())
1076         {
1077             const ConstString &trampoline_name = current_symbol->GetMangled().GetName(Mangled::ePreferMangled);
1078 
1079             if (trampoline_name)
1080             {
1081                 SymbolContextList target_symbols;
1082                 ModuleList &images = thread.GetProcess().GetTarget().GetImages();
1083                 images.FindSymbolsWithNameAndType(trampoline_name, eSymbolTypeCode, target_symbols);
1084                 // FIXME - Make the Run to Address take multiple addresses, and
1085                 // run to any of them.
1086                 uint32_t num_symbols = target_symbols.GetSize();
1087                 if (num_symbols == 1)
1088                 {
1089                     SymbolContext context;
1090                     AddressRange addr_range;
1091                     if (target_symbols.GetContextAtIndex(0, context))
1092                     {
1093                         context.GetAddressRange (eSymbolContextEverything, addr_range);
1094                         thread_plan_sp.reset (new ThreadPlanRunToAddress (thread, addr_range.GetBaseAddress(), stop_others));
1095                     }
1096                     else
1097                     {
1098                         if (log)
1099                             log->Printf ("Couldn't resolve the symbol context.");
1100                     }
1101                 }
1102                 else if (num_symbols > 1)
1103                 {
1104                     std::vector<lldb::addr_t>  addresses;
1105                     addresses.resize (num_symbols);
1106                     for (uint32_t i = 0; i < num_symbols; i++)
1107                     {
1108                         SymbolContext context;
1109                         AddressRange addr_range;
1110                         if (target_symbols.GetContextAtIndex(i, context))
1111                         {
1112                             context.GetAddressRange (eSymbolContextEverything, addr_range);
1113                             lldb::addr_t load_addr = addr_range.GetBaseAddress().GetLoadAddress(&thread.GetProcess().GetTarget());
1114                             addresses[i] = load_addr;
1115                         }
1116                     }
1117                     if (addresses.size() > 0)
1118                         thread_plan_sp.reset (new ThreadPlanRunToAddress (thread, addresses, stop_others));
1119                     else
1120                     {
1121                         if (log)
1122                             log->Printf ("Couldn't resolve the symbol contexts.");
1123                     }
1124                 }
1125                 else
1126                 {
1127                     if (log)
1128                     {
1129                         log->Printf ("Could not find symbol for trampoline target: \"%s\"", trampoline_name.AsCString());
1130                     }
1131                 }
1132             }
1133         }
1134     }
1135     else
1136     {
1137         if (log)
1138             log->Printf ("Could not find symbol for step through.");
1139     }
1140 
1141     return thread_plan_sp;
1142 }
1143 
1144 void
1145 DynamicLoaderMacOSXDYLD::Initialize()
1146 {
1147     PluginManager::RegisterPlugin (GetPluginNameStatic(),
1148                                    GetPluginDescriptionStatic(),
1149                                    CreateInstance);
1150 }
1151 
1152 void
1153 DynamicLoaderMacOSXDYLD::Terminate()
1154 {
1155     PluginManager::UnregisterPlugin (CreateInstance);
1156 }
1157 
1158 
1159 const char *
1160 DynamicLoaderMacOSXDYLD::GetPluginNameStatic()
1161 {
1162     return "dynamic-loader.macosx-dyld";
1163 }
1164 
1165 const char *
1166 DynamicLoaderMacOSXDYLD::GetPluginDescriptionStatic()
1167 {
1168     return "Dynamic loader plug-in that watches for shared library loads/unloads in MacOSX user processes.";
1169 }
1170 
1171 
1172 //------------------------------------------------------------------
1173 // PluginInterface protocol
1174 //------------------------------------------------------------------
1175 const char *
1176 DynamicLoaderMacOSXDYLD::GetPluginName()
1177 {
1178     return "DynamicLoaderMacOSXDYLD";
1179 }
1180 
1181 const char *
1182 DynamicLoaderMacOSXDYLD::GetShortPluginName()
1183 {
1184     return GetPluginNameStatic();
1185 }
1186 
1187 uint32_t
1188 DynamicLoaderMacOSXDYLD::GetPluginVersion()
1189 {
1190     return 1;
1191 }
1192 
1193 void
1194 DynamicLoaderMacOSXDYLD::GetPluginCommandHelp (const char *command, Stream *strm)
1195 {
1196 }
1197 
1198 Error
1199 DynamicLoaderMacOSXDYLD::ExecutePluginCommand (Args &command, Stream *strm)
1200 {
1201     Error error;
1202     error.SetErrorString("No plug-in command are currently supported.");
1203     return error;
1204 }
1205 
1206 Log *
1207 DynamicLoaderMacOSXDYLD::EnablePluginLogging (Stream *strm, Args &command)
1208 {
1209     return NULL;
1210 }
1211 
1212 
1213