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