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