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