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