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