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