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/RegisterContext.h"
19 #include "lldb/Target/Target.h"
20 #include "lldb/Target/Thread.h"
21 #include "lldb/Target/ThreadPlanRunToAddress.h"
22 #include "lldb/Target/StackFrame.h"
23 
24 #include "DynamicLoaderMacOSXDYLD.h"
25 #include "DynamicLoaderMacOSXDYLDLog.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 
39 /// FIXME - The ObjC Runtime trampoline handler doesn't really belong here.
40 /// I am putting it here so I can invoke it in the Trampoline code here, but
41 /// it should be moved to the ObjC Runtime support when it is set up.
42 
43 //----------------------------------------------------------------------
44 // Create an instance of this class. This function is filled into
45 // the plugin info class that gets handed out by the plugin factory and
46 // allows the lldb to instantiate an instance of this class.
47 //----------------------------------------------------------------------
48 DynamicLoader *
49 DynamicLoaderMacOSXDYLD::CreateInstance (Process* process)
50 {
51     return new DynamicLoaderMacOSXDYLD (process);
52 }
53 
54 //----------------------------------------------------------------------
55 // Constructor
56 //----------------------------------------------------------------------
57 DynamicLoaderMacOSXDYLD::DynamicLoaderMacOSXDYLD (Process* process) :
58     DynamicLoader(process),
59     m_dyld(),
60     m_dyld_all_image_infos_addr(LLDB_INVALID_ADDRESS),
61     m_dyld_all_image_infos(),
62     m_break_id(LLDB_INVALID_BREAK_ID),
63     m_dyld_image_infos(),
64     m_mutex(Mutex::eMutexTypeRecursive),
65     m_objc_trampoline_handler_ap(NULL)
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 == MH_DYLINKER)
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(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);
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->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->SectionLoaded (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->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->SectionLoaded (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->SectionUnloaded (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 = 2 * sizeof(uint32_t) + // version + dylib_info_count
412                              addr_size * 2 +        // dylib_info_addr + notification
413                              2 + addr_size - 2 +    // processDetachedFromSharedRegion + libSystemInitialized + pad
414                              addr_size;             // dyldImageLoadAddress
415         Error error;
416         const size_t bytes_read = m_process->ReadMemory (m_dyld_all_image_infos_addr, buf, count, error);
417         if (bytes_read == count)
418         {
419             DataExtractor data(buf, count, endian, addr_size);
420             uint32_t offset = 0;
421             m_dyld_all_image_infos.version = data.GetU32(&offset);
422             m_dyld_all_image_infos.dylib_info_count = data.GetU32(&offset);
423             m_dyld_all_image_infos.dylib_info_addr = data.GetPointer(&offset);
424             m_dyld_all_image_infos.notification = data.GetPointer(&offset);
425             m_dyld_all_image_infos.processDetachedFromSharedRegion = data.GetU8(&offset);
426             if (m_dyld_all_image_infos.version >= 2)
427             {
428                 m_dyld_all_image_infos.libSystemInitialized = data.GetU8(&offset);
429                 // Adjust for padding.
430                 offset += addr_size - 2;
431                 m_dyld_all_image_infos.dyldImageLoadAddress = data.GetPointer(&offset);
432             }
433             return true;
434         }
435     }
436     return false;
437 }
438 
439 //----------------------------------------------------------------------
440 // If we have found where the "_dyld_all_image_infos" lives in memory,
441 // read the current info from it, and then update all image load
442 // addresses (or lack thereof).
443 //----------------------------------------------------------------------
444 uint32_t
445 DynamicLoaderMacOSXDYLD::UpdateAllImageInfos()
446 {
447     if (ReadAllImageInfosStructure ())
448     {
449         Mutex::Locker locker(m_mutex);
450         uint32_t idx;
451         Error error;
452         uint32_t i = 0;
453         DYLDImageInfo::collection old_dyld_all_image_infos;
454         old_dyld_all_image_infos.swap(m_dyld_image_infos);
455 
456         // If we made it here, we are assuming that the all dylib info data should
457         // be valid, lets read the info array.
458         const ByteOrder endian = m_process->GetByteOrder();
459         const uint32_t addr_size = m_process->GetAddressByteSize();
460 
461         if (m_dyld_all_image_infos.dylib_info_count > 0)
462         {
463             if (m_dyld_all_image_infos.dylib_info_addr == 0)
464             {
465                 // DYLD is updating the images right now...
466             }
467             else
468             {
469                 m_dyld_image_infos.resize(m_dyld_all_image_infos.dylib_info_count);
470                 const size_t count = m_dyld_image_infos.size() * 3 * addr_size;
471                 DataBufferHeap info_data(count, 0);
472                 Error error;
473                 const size_t bytes_read = m_process->ReadMemory (m_dyld_all_image_infos.dylib_info_addr,
474                                                                  info_data.GetBytes(),
475                                                                  info_data.GetByteSize(),
476                                                                  error);
477                 if (bytes_read == count)
478                 {
479                     uint32_t info_data_offset = 0;
480                     DataExtractor info_data_ref(info_data.GetBytes(), info_data.GetByteSize(), endian, addr_size);
481                     for (i = 0; info_data_ref.ValidOffset(info_data_offset); i++)
482                     {
483                         assert (i < m_dyld_image_infos.size());
484                         m_dyld_image_infos[i].address = info_data_ref.GetPointer(&info_data_offset);
485                         lldb::addr_t path_addr = info_data_ref.GetPointer(&info_data_offset);
486                         m_dyld_image_infos[i].mod_date = info_data_ref.GetPointer(&info_data_offset);
487 
488                         char raw_path[PATH_MAX];
489                         m_process->ReadMemory (path_addr, raw_path, sizeof(raw_path), error);
490                         m_dyld_image_infos[i].file_spec.SetFile(raw_path);
491                     }
492                     assert(i == m_dyld_all_image_infos.dylib_info_count);
493 
494                     UpdateAllImageInfosHeaderAndLoadCommands();
495                 }
496                 else
497                 {
498                     DEBUG_PRINTF( "unable to read all data for all_dylib_infos.");
499                     m_dyld_image_infos.clear();
500                 }
501             }
502         }
503         else
504         {
505             m_dyld_image_infos.clear();
506         }
507 
508         // If our new list is smaller than our old list, we have unloaded
509         // some shared libraries
510         if (m_dyld_image_infos.size() < old_dyld_all_image_infos.size())
511         {
512             ModuleList unloaded_module_list;
513             for (idx = m_dyld_image_infos.size(); idx < old_dyld_all_image_infos.size(); ++idx)
514             {
515                 ModuleSP unload_image_module_sp(m_process->GetTarget().GetImages().FindFirstModuleForFileSpec (old_dyld_all_image_infos[idx].file_spec));
516                 if (unload_image_module_sp.get())
517                 {
518                     if (UnloadImageLoadAddress (unload_image_module_sp.get(), old_dyld_all_image_infos[idx]))
519                         unloaded_module_list.AppendInNeeded (unload_image_module_sp);
520                 }
521             }
522             if (unloaded_module_list.GetSize() > 0)
523                 m_process->GetTarget().ModulesDidUnload (unloaded_module_list);
524         }
525     }
526     else
527     {
528         m_dyld_image_infos.clear();
529     }
530 
531     const uint32_t num_dylibs = m_dyld_image_infos.size();
532     if (num_dylibs > 0)
533     {
534         ModuleList loaded_module_list;
535         for (uint32_t idx = 0; idx<num_dylibs; ++idx)
536         {
537             ArchSpec arch_spec(m_dyld_image_infos[idx].header.cputype, m_dyld_image_infos[idx].header.cpusubtype);
538             ModuleSP image_module_sp(m_process->GetTarget().GetImages().FindFirstModuleForFileSpec (m_dyld_image_infos[idx].file_spec));
539             if (image_module_sp.get() == NULL || image_module_sp->GetArchitecture() != arch_spec)
540             {
541                 image_module_sp = m_process->GetTarget().GetSharedModule (m_dyld_image_infos[idx].file_spec,
542                                                                           arch_spec,
543                                                                           &m_dyld_image_infos[idx].uuid);
544             }
545 
546             if (image_module_sp)
547             {
548                 ObjectFile *objfile = image_module_sp->GetObjectFile ();
549                 if (objfile)
550                 {
551                     SectionList *sections = objfile->GetSectionList();
552                     if (sections)
553                     {
554                         ConstString commpage_dbstr("__commpage");
555                         Section *commpage_section = sections->FindSectionByName(commpage_dbstr).get();
556                         if (commpage_section)
557                         {
558                             FileSpec objfile_file_spec(objfile->GetFileSpec());
559                             ModuleSP commpage_image_module_sp(m_process->GetTarget().GetImages().FindFirstModuleForFileSpec (objfile_file_spec, &commpage_dbstr));
560                             if (commpage_image_module_sp.get() == NULL)
561                             {
562                                 commpage_image_module_sp = m_process->GetTarget().GetSharedModule (m_dyld_image_infos[idx].file_spec,
563                                                                                                    arch_spec,
564                                                                                                    &m_dyld_image_infos[idx].uuid,
565                                                                                                    &commpage_dbstr,
566                                                                                                    objfile->GetOffset() + commpage_section->GetOffset());
567                                 UpdateCommPageLoadAddress(commpage_image_module_sp.get());
568                             }
569                         }
570                     }
571                 }
572 
573                 // UpdateImageLoadAddress will return true if any segments
574                 // change load address. We need to check this so we don't
575                 // mention that all loaded shared libraries are newly loaded
576                 // each time we hit out dyld breakpoint since dyld will list all
577                 // shared libraries each time.
578                 if (UpdateImageLoadAddress (image_module_sp.get(), m_dyld_image_infos[idx]))
579                 {
580                     loaded_module_list.AppendInNeeded (image_module_sp);
581                 }
582             }
583         }
584         PutToLog(DynamicLoaderMacOSXDYLDLog::GetLogIfAllCategoriesSet (1));
585         if (loaded_module_list.GetSize() > 0)
586         {
587             // FIXME: This should really be in the Runtime handlers class, which should get
588             // called by the target's ModulesDidLoad, but we're doing it all locally for now
589             // to save time.
590             // Also, I'm assuming there can be only one libobjc dylib loaded...
591 
592             if (m_objc_trampoline_handler_ap.get() == NULL)
593             {
594                 size_t num_modules = loaded_module_list.GetSize();
595                 for (int i = 0; i < num_modules; i++)
596                 {
597                     if (ObjCTrampolineHandler::ModuleIsObjCLibrary (loaded_module_list.GetModuleAtIndex (i)))
598                     {
599                         m_objc_trampoline_handler_ap.reset (new ObjCTrampolineHandler(m_process->GetSP(), loaded_module_list.GetModuleAtIndex (i)));
600                         break;
601                     }
602                 }
603             }
604             m_process->GetTarget().ModulesDidLoad (loaded_module_list);
605         }
606     }
607     return m_dyld_image_infos.size();
608 }
609 
610 //----------------------------------------------------------------------
611 // Read a mach_header at ADDR into HEADER, and also fill in the load
612 // command data into LOAD_COMMAND_DATA if it is non-NULL.
613 //
614 // Returns true if we succeed, false if we fail for any reason.
615 //----------------------------------------------------------------------
616 bool
617 DynamicLoaderMacOSXDYLD::ReadMachHeader (lldb::addr_t addr, struct mach_header *header, DataExtractor *load_command_data)
618 {
619     DataBufferHeap header_bytes(sizeof(struct mach_header), 0);
620     Error error;
621     size_t bytes_read = m_process->ReadMemory (addr,
622                                                header_bytes.GetBytes(),
623                                                header_bytes.GetByteSize(),
624                                                error);
625     if (bytes_read == sizeof(struct mach_header))
626     {
627         uint32_t offset = 0;
628         ::memset (header, 0, sizeof(header));
629 
630         // Get the magic byte unswapped so we can figure out what we are dealing with
631         DataExtractor data(header_bytes.GetBytes(), header_bytes.GetByteSize(), eByteOrderHost, 4);
632         header->magic = data.GetU32(&offset);
633         lldb::addr_t load_cmd_addr = addr;
634         data.SetByteOrder(DynamicLoaderMacOSXDYLD::GetByteOrderFromMagic(header->magic));
635         switch (header->magic)
636         {
637         case MH_MAGIC:
638         case MH_CIGAM:
639             data.SetAddressByteSize(4);
640             load_cmd_addr += sizeof(struct mach_header);
641             break;
642 
643         case MH_MAGIC_64:
644         case MH_CIGAM_64:
645             data.SetAddressByteSize(8);
646             load_cmd_addr += sizeof(struct mach_header_64);
647             break;
648 
649         default:
650             return false;
651         }
652 
653         // Read the rest of dyld's mach header
654         if (data.GetU32(&offset, &header->cputype, (sizeof(struct mach_header)/sizeof(uint32_t)) - 1))
655         {
656             if (load_command_data == NULL)
657                 return true; // We were able to read the mach_header and weren't asked to read the load command bytes
658 
659             DataBufferSP load_cmd_data_sp(new DataBufferHeap(header->sizeofcmds, 0));
660 
661             size_t load_cmd_bytes_read = m_process->ReadMemory (load_cmd_addr,
662                                                                 load_cmd_data_sp->GetBytes(),
663                                                                 load_cmd_data_sp->GetByteSize(),
664                                                                 error);
665 
666             if (load_cmd_bytes_read == header->sizeofcmds)
667             {
668                 // Set the load command data and also set the correct endian
669                 // swap settings and the correct address size
670                 load_command_data->SetData(load_cmd_data_sp, 0, header->sizeofcmds);
671                 load_command_data->SetByteOrder(data.GetByteOrder());
672                 load_command_data->SetAddressByteSize(data.GetAddressByteSize());
673                 return true; // We successfully read the mach_header and the load command data
674             }
675 
676             return false; // We weren't able to read the load command data
677         }
678     }
679     return false; // We failed the read the mach_header
680 }
681 
682 
683 //----------------------------------------------------------------------
684 // Parse the load commands for an image
685 //----------------------------------------------------------------------
686 uint32_t
687 DynamicLoaderMacOSXDYLD::ParseLoadCommands (const DataExtractor& data, struct DYLDImageInfo& dylib_info, FileSpec *lc_id_dylinker)
688 {
689     uint32_t offset = 0;
690     uint32_t cmd_idx;
691     Segment segment;
692     dylib_info.Clear (true);
693 
694     for (cmd_idx = 0; cmd_idx < dylib_info.header.ncmds; cmd_idx++)
695     {
696         // Clear out any load command specific data from DYLIB_INFO since
697         // we are about to read it.
698 
699         if (data.ValidOffsetForDataOfSize (offset, sizeof(struct load_command)))
700         {
701             struct load_command load_cmd;
702             uint32_t load_cmd_offset = offset;
703             load_cmd.cmd = data.GetU32 (&offset);
704             load_cmd.cmdsize = data.GetU32 (&offset);
705             switch (load_cmd.cmd)
706             {
707             case LC_SEGMENT:
708                 {
709                     segment.name.SetTrimmedCStringWithLength ((const char *)data.GetData(&offset, 16), 16);
710                     segment.addr = data.GetU32 (&offset);
711                     segment.size = data.GetU32 (&offset);
712                     dylib_info.segments.push_back (segment);
713                 }
714                 break;
715 
716             case LC_SEGMENT_64:
717                 {
718                     segment.name.SetTrimmedCStringWithLength ((const char *)data.GetData(&offset, 16), 16);
719                     segment.addr = data.GetU64 (&offset);
720                     segment.size = data.GetU64 (&offset);
721                     dylib_info.segments.push_back (segment);
722                 }
723                 break;
724 
725             case LC_ID_DYLINKER:
726                 if (lc_id_dylinker)
727                 {
728                     uint32_t name_offset = load_cmd_offset + data.GetU32 (&offset);
729                     const char *path = data.PeekCStr (name_offset);
730                     lc_id_dylinker->SetFile (path);
731                 }
732                 break;
733 
734             case LC_UUID:
735                 dylib_info.uuid.SetBytes(data.GetData (&offset, 16));
736                 break;
737 
738             default:
739                 break;
740             }
741             // Set offset to be the beginning of the next load command.
742             offset = load_cmd_offset + load_cmd.cmdsize;
743         }
744     }
745     return cmd_idx;
746 }
747 
748 //----------------------------------------------------------------------
749 // Read the mach_header and load commands for each image that the
750 // _dyld_all_image_infos structure points to and cache the results.
751 //----------------------------------------------------------------------
752 void
753 DynamicLoaderMacOSXDYLD::UpdateAllImageInfosHeaderAndLoadCommands()
754 {
755     uint32_t exe_idx = UINT32_MAX;
756     // Read any UUID values that we can get
757     for (uint32_t i = 0; i < m_dyld_all_image_infos.dylib_info_count; i++)
758     {
759         if (!m_dyld_image_infos[i].UUIDValid())
760         {
761             DataExtractor data; // Load command data
762             if (!ReadMachHeader (m_dyld_image_infos[i].address, &m_dyld_image_infos[i].header, &data))
763                 continue;
764 
765             ParseLoadCommands (data, m_dyld_image_infos[i], NULL);
766 
767             if (m_dyld_image_infos[i].header.filetype == MH_EXECUTE)
768                 exe_idx = i;
769         }
770     }
771 
772     if (exe_idx < m_dyld_image_infos.size())
773     {
774         bool set_executable = false;
775         ArchSpec dyld_exe_arch_spec(m_dyld_image_infos[exe_idx].header.cputype, m_dyld_image_infos[exe_idx].header.cpusubtype);
776         ModuleSP exe_module_sp(m_process->GetTarget().GetExecutableModule());
777         if (exe_module_sp.get())
778         {
779             if (exe_module_sp->GetFileSpec() != m_dyld_image_infos[exe_idx].file_spec ||
780                 exe_module_sp->GetArchitecture() != dyld_exe_arch_spec)
781                 set_executable = true;
782         }
783         else
784             set_executable = true;
785 
786         if (set_executable)
787         {
788             exe_module_sp = m_process->GetTarget().GetSharedModule (m_dyld_image_infos[exe_idx].file_spec,
789                                                                     dyld_exe_arch_spec,
790                                                                     &m_dyld_image_infos[exe_idx].uuid);
791             if (exe_module_sp.get())
792             {
793                 // If we found the file where it purported to be, then it should
794                 // be safe to load dependent images.
795                 bool get_dependent_images = exe_module_sp->GetFileSpec() == m_dyld_image_infos[exe_idx].file_spec;
796 
797                 m_process->GetTarget().SetExecutableModule (exe_module_sp, get_dependent_images);
798             }
799         }
800     }
801 }
802 
803 //----------------------------------------------------------------------
804 // Dump a Segment to the file handle provided.
805 //----------------------------------------------------------------------
806 void
807 DynamicLoaderMacOSXDYLD::Segment::PutToLog (Log *log, lldb::addr_t slide) const
808 {
809     if (log)
810         log->Printf("\t\t%16s [0x%16.16llx - 0x%16.16llx)", name.AsCString(""), addr + slide, addr + slide + size);
811 }
812 
813 const DynamicLoaderMacOSXDYLD::Segment *
814 DynamicLoaderMacOSXDYLD::DYLDImageInfo::FindSegment (const ConstString &name) const
815 {
816     const size_t num_segments = segments.size();
817     for (size_t i=0; i<num_segments; ++i)
818     {
819         if (segments[i].name == name)
820             return &segments[i];
821     }
822     return NULL;
823 }
824 
825 
826 //----------------------------------------------------------------------
827 // Dump an image info structure to the file handle provided.
828 //----------------------------------------------------------------------
829 void
830 DynamicLoaderMacOSXDYLD::DYLDImageInfo::PutToLog (Log *log) const
831 {
832     if (log == NULL)
833         return;
834     uint8_t *u = (uint8_t *)uuid.GetBytes();
835 
836     if (address == LLDB_INVALID_ADDRESS)
837     {
838         if (u)
839         {
840             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)",
841                         mod_date,
842                         u[ 0], u[ 1], u[ 2], u[ 3],
843                         u[ 4], u[ 5], u[ 6], u[ 7],
844                         u[ 8], u[ 9], u[10], u[11],
845                         u[12], u[13], u[14], u[15],
846                         file_spec.GetDirectory().AsCString(),
847                         file_spec.GetFilename().AsCString());
848         }
849         else
850             log->Printf("\t                           modtime=0x%8.8llx path='%s/%s' (UNLOADED)",
851                         mod_date,
852                         file_spec.GetDirectory().AsCString(),
853                         file_spec.GetFilename().AsCString());
854     }
855     else
856     {
857         if (u)
858         {
859             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'",
860                         address,
861                         mod_date,
862                         u[ 0], u[ 1], u[ 2], u[ 3],
863                         u[ 4], u[ 5], u[ 6], u[ 7],
864                         u[ 8], u[ 9], u[10], u[11],
865                         u[12], u[13], u[14], u[15],
866                         file_spec.GetDirectory().AsCString(),
867                         file_spec.GetFilename().AsCString());
868         }
869         else
870         {
871             log->Printf("\taddress=0x%16.16llx modtime=0x%8.8llx path='%s/%s'",
872                         address,
873                         mod_date,
874                         file_spec.GetDirectory().AsCString(),
875                         file_spec.GetFilename().AsCString());
876 
877         }
878         for (uint32_t i=0; i<segments.size(); ++i)
879             segments[i].PutToLog(log, slide);
880     }
881 }
882 
883 //----------------------------------------------------------------------
884 // Dump the _dyld_all_image_infos members and all current image infos
885 // that we have parsed to the file handle provided.
886 //----------------------------------------------------------------------
887 void
888 DynamicLoaderMacOSXDYLD::PutToLog(Log *log) const
889 {
890     if (log == NULL)
891         return;
892 
893     Mutex::Locker locker(m_mutex);
894     log->Printf("dyld_all_image_infos = { version=%d, count=%d, addr=0x%8.8llx, notify=0x%8.8llx }",
895                     m_dyld_all_image_infos.version,
896                     m_dyld_all_image_infos.dylib_info_count,
897                     (uint64_t)m_dyld_all_image_infos.dylib_info_addr,
898                     (uint64_t)m_dyld_all_image_infos.notification);
899     size_t i;
900     const size_t count = m_dyld_image_infos.size();
901     if (count > 0)
902     {
903         log->Printf("\tdyld_image_infos");
904         for (i = 0; i<count; i++)
905             m_dyld_image_infos[i].PutToLog(log);
906     }
907 }
908 
909 //----------------------------------------------------------------------
910 // Static callback function that gets called when the process state
911 // changes.
912 //----------------------------------------------------------------------
913 void
914 DynamicLoaderMacOSXDYLD::Initialize(void *baton, Process *process)
915 {
916     ((DynamicLoaderMacOSXDYLD*)baton)->PrivateInitialize(process);
917 }
918 
919 void
920 DynamicLoaderMacOSXDYLD::PrivateInitialize(Process *process)
921 {
922     DEBUG_PRINTF("DynamicLoaderMacOSXDYLD::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState()));
923     Clear(true);
924     m_process = process;
925 }
926 
927 
928 //----------------------------------------------------------------------
929 // Static callback function that gets called when the process state
930 // changes.
931 //----------------------------------------------------------------------
932 void
933 DynamicLoaderMacOSXDYLD::ProcessStateChanged(void *baton, Process *process, StateType state)
934 {
935     ((DynamicLoaderMacOSXDYLD*)baton)->PrivateProcessStateChanged(process, state);
936 }
937 
938 bool
939 DynamicLoaderMacOSXDYLD::SetNotificationBreakpoint ()
940 {
941     DEBUG_PRINTF("DynamicLoaderMacOSXDYLD::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState()));
942     if (m_break_id == LLDB_INVALID_BREAK_ID)
943     {
944         if (m_dyld_all_image_infos.notification != LLDB_INVALID_ADDRESS)
945         {
946             Address so_addr;
947             // Set the notification breakpoint and install a breakpoint
948             // callback function that will get called each time the
949             // breakpoint gets hit. We will use this to track when shared
950             // libraries get loaded/unloaded.
951 
952             if (m_process->ResolveLoadAddress(m_dyld_all_image_infos.notification, so_addr))
953             {
954                 Breakpoint *dyld_break = m_process->GetTarget().CreateBreakpoint (so_addr, true).get();
955                 dyld_break->SetCallback (DynamicLoaderMacOSXDYLD::NotifyBreakpointHit, this, true);
956                 m_break_id = dyld_break->GetID();
957             }
958         }
959     }
960     return m_break_id != LLDB_INVALID_BREAK_ID;
961 }
962 
963 //----------------------------------------------------------------------Target.h
964 
965 // Member function that gets called when the process state changes.
966 //----------------------------------------------------------------------
967 void
968 DynamicLoaderMacOSXDYLD::PrivateProcessStateChanged (Process *process, StateType state)
969 {
970     DEBUG_PRINTF("DynamicLoaderMacOSXDYLD::%s(%s)\n", __FUNCTION__, StateAsCString(state));
971     switch (state)
972     {
973     case eStateAttaching:
974     case eStateLaunching:
975     case eStateInvalid:
976     case eStateUnloaded:
977     case eStateExited:
978     case eStateDetached:
979         Clear(false);
980         break;
981 
982     case eStateStopped:
983         // Keep trying find dyld and set our notification breakpoint each time
984         // we stop until we succeed
985         if (!DidSetNotificationBreakpoint () && m_process->IsAlive())
986         {
987             if (NeedToLocateDYLD ())
988                 LocateDYLD ();
989 
990             SetNotificationBreakpoint ();
991         }
992         break;
993 
994     case eStateRunning:
995     case eStateStepping:
996     case eStateCrashed:
997     case eStateSuspended:
998         break;
999 
1000     default:
1001         break;
1002     }
1003 }
1004 
1005 ThreadPlanSP
1006 DynamicLoaderMacOSXDYLD::GetStepThroughTrampolinePlan (Thread &thread, bool stop_others)
1007 {
1008     ThreadPlanSP thread_plan_sp;
1009     StackFrame *current_frame = thread.GetStackFrameAtIndex(0).get();
1010     const SymbolContext &current_context = current_frame->GetSymbolContext(eSymbolContextSymbol);
1011     Symbol *current_symbol = current_context.symbol;
1012 
1013     if (current_symbol != NULL)
1014     {
1015         if (current_symbol->IsTrampoline())
1016         {
1017             const ConstString &trampoline_name = current_symbol->GetMangled().GetName();
1018             if (trampoline_name)
1019             {
1020                 SymbolContextList target_symbols;
1021                 ModuleList &images = thread.GetProcess().GetTarget().GetImages();
1022                 images.FindSymbolsWithNameAndType(trampoline_name, eSymbolTypeCode, target_symbols);
1023                 // FIXME - Make the Run to Address take multiple addresses, and
1024                 // run to any of them.
1025                 if (target_symbols.GetSize() == 1)
1026                 {
1027                     SymbolContext context;
1028                     AddressRange addr_range;
1029                     if (target_symbols.GetContextAtIndex(0, context))
1030                     {
1031                         context.GetAddressRange (eSymbolContextEverything, addr_range);
1032                         thread_plan_sp.reset (new ThreadPlanRunToAddress (thread, addr_range.GetBaseAddress(), stop_others));
1033                     }
1034                 }
1035                 else if (target_symbols.GetSize() > 1)
1036                 {
1037                     Log *log = DynamicLoaderMacOSXDYLDLog::GetLogIfAllCategoriesSet (1);
1038                     if (log)
1039                     {
1040                         log->Printf ("Found more than one symbol for trampoline target: \"%s\"", trampoline_name.AsCString());
1041                     }
1042                 }
1043                 else
1044                 {
1045                     Log *log = DynamicLoaderMacOSXDYLDLog::GetLogIfAllCategoriesSet (1);
1046                     if (log)
1047                     {
1048                         log->Printf ("Could not find symbol for trampoline target: \"%s\"", trampoline_name.AsCString());
1049                     }
1050                 }
1051             }
1052         }
1053     }
1054 
1055     if (thread_plan_sp == NULL && m_objc_trampoline_handler_ap.get())
1056         thread_plan_sp = m_objc_trampoline_handler_ap->GetStepThroughDispatchPlan (thread, stop_others);
1057 
1058     return thread_plan_sp;
1059 }
1060 
1061 void
1062 DynamicLoaderMacOSXDYLD::Initialize()
1063 {
1064     PluginManager::RegisterPlugin (GetPluginNameStatic(),
1065                                    GetPluginDescriptionStatic(),
1066                                    CreateInstance);
1067 }
1068 
1069 void
1070 DynamicLoaderMacOSXDYLD::Terminate()
1071 {
1072     PluginManager::UnregisterPlugin (CreateInstance);
1073 }
1074 
1075 
1076 const char *
1077 DynamicLoaderMacOSXDYLD::GetPluginNameStatic()
1078 {
1079     return "dynamic-loader.macosx-dyld";
1080 }
1081 
1082 const char *
1083 DynamicLoaderMacOSXDYLD::GetPluginDescriptionStatic()
1084 {
1085     return "Dynamic loader plug-in that watches for shared library loads/unloads in MacOSX user processes.";
1086 }
1087 
1088 
1089 //------------------------------------------------------------------
1090 // PluginInterface protocol
1091 //------------------------------------------------------------------
1092 const char *
1093 DynamicLoaderMacOSXDYLD::GetPluginName()
1094 {
1095     return "DynamicLoaderMacOSXDYLD";
1096 }
1097 
1098 const char *
1099 DynamicLoaderMacOSXDYLD::GetShortPluginName()
1100 {
1101     return GetPluginNameStatic();
1102 }
1103 
1104 uint32_t
1105 DynamicLoaderMacOSXDYLD::GetPluginVersion()
1106 {
1107     return 1;
1108 }
1109 
1110 void
1111 DynamicLoaderMacOSXDYLD::GetPluginCommandHelp (const char *command, Stream *strm)
1112 {
1113 }
1114 
1115 Error
1116 DynamicLoaderMacOSXDYLD::ExecutePluginCommand (Args &command, Stream *strm)
1117 {
1118     Error error;
1119     error.SetErrorString("No plug-in command are currently supported.");
1120     return error;
1121 }
1122 
1123 Log *
1124 DynamicLoaderMacOSXDYLD::EnablePluginLogging (Stream *strm, Args &command)
1125 {
1126     return NULL;
1127 }
1128 
1129 
1130