DynamicLoaderMacOSXDYLD.cpp revision 6e3dc10663891a232585968ddd3b19df563dbb96
1//===-- DynamicLoaderMacOSXDYLD.cpp -----------------------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lldb/Breakpoint/StoppointCallbackContext.h"
11#include "lldb/Core/DataBuffer.h"
12#include "lldb/Core/DataBufferHeap.h"
13#include "lldb/Core/Log.h"
14#include "lldb/Core/Module.h"
15#include "lldb/Core/PluginManager.h"
16#include "lldb/Core/State.h"
17#include "lldb/Symbol/ObjectFile.h"
18#include "lldb/Target/ObjCLanguageRuntime.h"
19#include "lldb/Target/RegisterContext.h"
20#include "lldb/Target/Target.h"
21#include "lldb/Target/Thread.h"
22#include "lldb/Target/ThreadPlanRunToAddress.h"
23#include "lldb/Target/StackFrame.h"
24
25#include "DynamicLoaderMacOSXDYLD.h"
26
27//#define ENABLE_DEBUG_PRINTF // COMMENT THIS LINE OUT PRIOR TO CHECKIN
28#ifdef ENABLE_DEBUG_PRINTF
29#include <stdio.h>
30#define DEBUG_PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__)
31#else
32#define DEBUG_PRINTF(fmt, ...)
33#endif
34
35using namespace lldb;
36using namespace lldb_private;
37
38/// FIXME - The ObjC Runtime trampoline handler doesn't really belong here.
39/// I am putting it here so I can invoke it in the Trampoline code here, but
40/// it should be moved to the ObjC Runtime support when it is set up.
41
42
43DynamicLoaderMacOSXDYLD::DYLDImageInfo *
44DynamicLoaderMacOSXDYLD::GetImageInfo (Module *module)
45{
46    const UUID &module_uuid = module->GetUUID();
47    DYLDImageInfo::collection::iterator pos, end = m_dyld_image_infos.end();
48
49    // First try just by UUID as it is the safest.
50    if (module_uuid.IsValid())
51    {
52        for (pos = m_dyld_image_infos.begin(); pos != end; ++pos)
53        {
54            if (pos->uuid == module_uuid)
55                return &(*pos);
56        }
57
58        if (m_dyld.uuid == module_uuid)
59            return &m_dyld;
60    }
61
62    // Next try by platform path only for things that don't have a valid UUID
63    // since if a file has a valid UUID in real life it should also in the
64    // dyld info. This is the next safest because the paths in the dyld info
65    // are platform paths, not local paths. For local debugging platform == local
66    // paths.
67    const FileSpec &platform_file_spec = module->GetPlatformFileSpec();
68    for (pos = m_dyld_image_infos.begin(); pos != end; ++pos)
69    {
70        if (pos->file_spec == platform_file_spec && pos->uuid.IsValid() == false)
71            return &(*pos);
72    }
73
74    if (m_dyld.file_spec == platform_file_spec && m_dyld.uuid.IsValid() == false)
75        return &m_dyld;
76
77    return NULL;
78}
79
80//----------------------------------------------------------------------
81// Create an instance of this class. This function is filled into
82// the plugin info class that gets handed out by the plugin factory and
83// allows the lldb to instantiate an instance of this class.
84//----------------------------------------------------------------------
85DynamicLoader *
86DynamicLoaderMacOSXDYLD::CreateInstance (Process* process, bool force)
87{
88    bool create = force;
89    if (!create)
90    {
91        const llvm::Triple &triple_ref = process->GetTarget().GetArchitecture().GetTriple();
92        if (triple_ref.getOS() == llvm::Triple::Darwin && triple_ref.getVendor() == llvm::Triple::Apple)
93            create = true;
94    }
95
96    if (create)
97        return new DynamicLoaderMacOSXDYLD (process);
98    return NULL;
99}
100
101//----------------------------------------------------------------------
102// Constructor
103//----------------------------------------------------------------------
104DynamicLoaderMacOSXDYLD::DynamicLoaderMacOSXDYLD (Process* process) :
105    DynamicLoader(process),
106    m_dyld(),
107    m_dyld_all_image_infos_addr(LLDB_INVALID_ADDRESS),
108    m_dyld_all_image_infos(),
109    m_dyld_all_image_infos_stop_id (UINT32_MAX),
110    m_break_id(LLDB_INVALID_BREAK_ID),
111    m_dyld_image_infos(),
112    m_dyld_image_infos_stop_id (UINT32_MAX),
113    m_mutex(Mutex::eMutexTypeRecursive)
114{
115}
116
117//----------------------------------------------------------------------
118// Destructor
119//----------------------------------------------------------------------
120DynamicLoaderMacOSXDYLD::~DynamicLoaderMacOSXDYLD()
121{
122    Clear(true);
123}
124
125//------------------------------------------------------------------
126/// Called after attaching a process.
127///
128/// Allow DynamicLoader plug-ins to execute some code after
129/// attaching to a process.
130//------------------------------------------------------------------
131void
132DynamicLoaderMacOSXDYLD::DidAttach ()
133{
134    PrivateInitialize(m_process);
135    LocateDYLD ();
136    SetNotificationBreakpoint ();
137}
138
139//------------------------------------------------------------------
140/// Called after attaching a process.
141///
142/// Allow DynamicLoader plug-ins to execute some code after
143/// attaching to a process.
144//------------------------------------------------------------------
145void
146DynamicLoaderMacOSXDYLD::DidLaunch ()
147{
148    PrivateInitialize(m_process);
149    LocateDYLD ();
150    SetNotificationBreakpoint ();
151}
152
153
154//----------------------------------------------------------------------
155// Clear out the state of this class.
156//----------------------------------------------------------------------
157void
158DynamicLoaderMacOSXDYLD::Clear (bool clear_process)
159{
160    Mutex::Locker locker(m_mutex);
161
162    if (m_process->IsAlive() && LLDB_BREAK_ID_IS_VALID(m_break_id))
163        m_process->ClearBreakpointSiteByID(m_break_id);
164
165    if (clear_process)
166        m_process = NULL;
167    m_dyld.Clear(false);
168    m_dyld_all_image_infos_addr = LLDB_INVALID_ADDRESS;
169    m_dyld_all_image_infos.Clear();
170    m_break_id = LLDB_INVALID_BREAK_ID;
171    m_dyld_image_infos.clear();
172}
173
174//----------------------------------------------------------------------
175// Check if we have found DYLD yet
176//----------------------------------------------------------------------
177bool
178DynamicLoaderMacOSXDYLD::DidSetNotificationBreakpoint() const
179{
180    return LLDB_BREAK_ID_IS_VALID (m_break_id);
181}
182
183//----------------------------------------------------------------------
184// Try and figure out where dyld is by first asking the Process
185// if it knows (which currently calls down in the the lldb::Process
186// to get the DYLD info (available on SnowLeopard only). If that fails,
187// then check in the default addresses.
188//----------------------------------------------------------------------
189bool
190DynamicLoaderMacOSXDYLD::LocateDYLD()
191{
192    if (m_dyld_all_image_infos_addr == LLDB_INVALID_ADDRESS)
193        m_dyld_all_image_infos_addr = m_process->GetImageInfoAddress ();
194
195    if (m_dyld_all_image_infos_addr != LLDB_INVALID_ADDRESS)
196    {
197        if (ReadAllImageInfosStructure ())
198        {
199            if (m_dyld_all_image_infos.dyldImageLoadAddress != LLDB_INVALID_ADDRESS)
200                return ReadDYLDInfoFromMemoryAndSetNotificationCallback (m_dyld_all_image_infos.dyldImageLoadAddress);
201            else
202                return ReadDYLDInfoFromMemoryAndSetNotificationCallback (m_dyld_all_image_infos_addr & 0xfffffffffff00000ull);
203        }
204    }
205
206    // Check some default values
207    Module *executable = m_process->GetTarget().GetExecutableModule().get();
208
209    if (executable)
210    {
211        if (executable->GetArchitecture().GetAddressByteSize() == 8)
212        {
213            return ReadDYLDInfoFromMemoryAndSetNotificationCallback(0x7fff5fc00000ull);
214        }
215#if defined (__arm__)
216        else
217        {
218            ArchSpec arm_arch("arm");
219            if (arm_arch == executable->Arch())
220                return ReadDYLDInfoFromMemoryAndSetNotificationCallback(0x2fe00000);
221        }
222#endif
223        return ReadDYLDInfoFromMemoryAndSetNotificationCallback(0x8fe00000);
224    }
225    return false;
226}
227
228ModuleSP
229DynamicLoaderMacOSXDYLD::FindTargetModuleForDYLDImageInfo (const DYLDImageInfo &image_info, bool can_create, bool *did_create_ptr)
230{
231    if (did_create_ptr)
232        *did_create_ptr = false;
233    ModuleSP module_sp;
234    ModuleList &target_images = m_process->GetTarget().GetImages();
235    const bool image_info_uuid_is_valid = image_info.uuid.IsValid();
236    if (image_info_uuid_is_valid)
237        module_sp = target_images.FindModule(image_info.uuid);
238
239    if (!module_sp)
240    {
241        ArchSpec arch(image_info.GetArchitecture ());
242
243        module_sp = target_images.FindFirstModuleForFileSpec (image_info.file_spec, &arch, NULL);
244
245        if (can_create && !module_sp)
246        {
247            module_sp = m_process->GetTarget().GetSharedModule (image_info.file_spec,
248                                                                arch,
249                                                                image_info_uuid_is_valid ? &image_info.uuid : NULL);
250            if (did_create_ptr)
251                *did_create_ptr = module_sp;
252        }
253    }
254    return module_sp;
255}
256
257//----------------------------------------------------------------------
258// Assume that dyld is in memory at ADDR and try to parse it's load
259// commands
260//----------------------------------------------------------------------
261bool
262DynamicLoaderMacOSXDYLD::ReadDYLDInfoFromMemoryAndSetNotificationCallback(lldb::addr_t addr)
263{
264    DataExtractor data; // Load command data
265    if (ReadMachHeader (addr, &m_dyld.header, &data))
266    {
267        if (m_dyld.header.filetype == llvm::MachO::HeaderFileTypeDynamicLinkEditor)
268        {
269            m_dyld.address = addr;
270            ModuleSP dyld_module_sp;
271            if (ParseLoadCommands (data, m_dyld, &m_dyld.file_spec))
272            {
273                if (m_dyld.file_spec)
274                {
275                    dyld_module_sp = FindTargetModuleForDYLDImageInfo (m_dyld, true, NULL);
276
277                    if (dyld_module_sp)
278                        UpdateImageLoadAddress (dyld_module_sp.get(), m_dyld);
279                }
280            }
281
282            if (m_dyld_all_image_infos_addr == LLDB_INVALID_ADDRESS && dyld_module_sp.get())
283            {
284                static ConstString g_dyld_all_image_infos ("dyld_all_image_infos");
285                const Symbol *symbol = dyld_module_sp->FindFirstSymbolWithNameAndType (g_dyld_all_image_infos, eSymbolTypeData);
286                if (symbol)
287                    m_dyld_all_image_infos_addr = symbol->GetValue().GetLoadAddress(&m_process->GetTarget());
288            }
289
290            // Update all image infos
291            UpdateAllImageInfos();
292
293            // If we didn't have an executable before, but now we do, then the
294            // dyld module shared pointer might be unique and we may need to add
295            // it again (since Target::SetExecutableModule() will clear the
296            // images). So append the dyld module back to the list if it is
297            /// unique!
298            if (dyld_module_sp && m_process->GetTarget().GetImages().AppendIfNeeded (dyld_module_sp))
299                UpdateImageLoadAddress(dyld_module_sp.get(), m_dyld);
300
301            return true;
302        }
303    }
304    return false;
305}
306
307bool
308DynamicLoaderMacOSXDYLD::NeedToLocateDYLD () const
309{
310    return m_dyld_all_image_infos_addr == LLDB_INVALID_ADDRESS;
311}
312
313bool
314DynamicLoaderMacOSXDYLD::UpdateCommPageLoadAddress(Module *module)
315{
316    bool changed = false;
317    if (module)
318    {
319        ObjectFile *image_object_file = module->GetObjectFile();
320        if (image_object_file)
321        {
322            SectionList *section_list = image_object_file->GetSectionList ();
323            if (section_list)
324            {
325                uint32_t num_sections = section_list->GetSize();
326                for (uint32_t i=0; i<num_sections; ++i)
327                {
328                    Section* section = section_list->GetSectionAtIndex (i).get();
329                    if (section)
330                    {
331                        const addr_t new_section_load_addr = section->GetFileAddress ();
332                        const addr_t old_section_load_addr = m_process->GetTarget().GetSectionLoadList().GetSectionLoadAddress (section);
333                        if (old_section_load_addr == LLDB_INVALID_ADDRESS ||
334                            old_section_load_addr != new_section_load_addr)
335                        {
336                            if (m_process->GetTarget().GetSectionLoadList().SetSectionLoadAddress (section, section->GetFileAddress ()))
337                                changed = true;
338                        }
339                    }
340                }
341            }
342        }
343    }
344    return changed;
345}
346
347//----------------------------------------------------------------------
348// Update the load addresses for all segments in MODULE using the
349// updated INFO that is passed in.
350//----------------------------------------------------------------------
351bool
352DynamicLoaderMacOSXDYLD::UpdateImageLoadAddress (Module *module, DYLDImageInfo& info)
353{
354    bool changed = false;
355    if (module)
356    {
357        ObjectFile *image_object_file = module->GetObjectFile();
358        if (image_object_file)
359        {
360            SectionList *section_list = image_object_file->GetSectionList ();
361            if (section_list)
362            {
363                // We now know the slide amount, so go through all sections
364                // and update the load addresses with the correct values.
365                uint32_t num_segments = info.segments.size();
366                for (uint32_t i=0; i<num_segments; ++i)
367                {
368                    SectionSP section_sp(section_list->FindSectionByName(info.segments[i].name));
369                    assert (section_sp.get() != NULL);
370                    const addr_t new_section_load_addr = info.segments[i].vmaddr + info.slide;
371                    const addr_t old_section_load_addr = m_process->GetTarget().GetSectionLoadList().GetSectionLoadAddress (section_sp.get());
372                    if (old_section_load_addr == LLDB_INVALID_ADDRESS ||
373                        old_section_load_addr != new_section_load_addr)
374                    {
375                        if (m_process->GetTarget().GetSectionLoadList().SetSectionLoadAddress (section_sp.get(), new_section_load_addr))
376                            changed = true;
377                    }
378                }
379            }
380        }
381    }
382    return changed;
383}
384
385//----------------------------------------------------------------------
386// Update the load addresses for all segments in MODULE using the
387// updated INFO that is passed in.
388//----------------------------------------------------------------------
389bool
390DynamicLoaderMacOSXDYLD::UnloadImageLoadAddress (Module *module, DYLDImageInfo& info)
391{
392    bool changed = false;
393    if (module)
394    {
395        ObjectFile *image_object_file = module->GetObjectFile();
396        if (image_object_file)
397        {
398            SectionList *section_list = image_object_file->GetSectionList ();
399            if (section_list)
400            {
401                uint32_t num_segments = info.segments.size();
402                for (uint32_t i=0; i<num_segments; ++i)
403                {
404                    SectionSP section_sp(section_list->FindSectionByName(info.segments[i].name));
405                    assert (section_sp.get() != NULL);
406                    const addr_t old_section_load_addr = info.segments[i].vmaddr + info.slide;
407                    if (m_process->GetTarget().GetSectionLoadList().SetSectionUnloaded (section_sp.get(), old_section_load_addr))
408                        changed = true;
409                }
410            }
411        }
412    }
413    return changed;
414}
415
416
417//----------------------------------------------------------------------
418// Static callback function that gets called when our DYLD notification
419// breakpoint gets hit. We update all of our image infos and then
420// let our super class DynamicLoader class decide if we should stop
421// or not (based on global preference).
422//----------------------------------------------------------------------
423bool
424DynamicLoaderMacOSXDYLD::NotifyBreakpointHit (void *baton, StoppointCallbackContext *context, lldb::user_id_t break_id, lldb::user_id_t break_loc_id)
425{
426    // Let the event know that the images have changed
427    DynamicLoaderMacOSXDYLD* dyld_instance = (DynamicLoaderMacOSXDYLD*) baton;
428    dyld_instance->UpdateAllImageInfos();
429    // Return true to stop the target, false to just let the target run
430    return dyld_instance->GetStopWhenImagesChange();
431}
432
433bool
434DynamicLoaderMacOSXDYLD::ReadAllImageInfosStructure ()
435{
436    Mutex::Locker locker(m_mutex);
437
438    // the all image infos is already valid for this process stop ID
439    if (m_process->GetStopID() == m_dyld_all_image_infos_stop_id)
440        return true;
441
442    m_dyld_all_image_infos.Clear();
443    if (m_dyld_all_image_infos_addr != LLDB_INVALID_ADDRESS)
444    {
445        ByteOrder byte_order = m_process->GetTarget().GetArchitecture().GetByteOrder();
446        uint32_t addr_size = 4;
447        if (m_dyld_all_image_infos_addr > UINT32_MAX)
448            addr_size = 8;
449
450        uint8_t buf[256];
451        DataExtractor data (buf, sizeof(buf), byte_order, addr_size);
452        uint32_t offset = 0;
453
454        const size_t count_v2 =  sizeof (uint32_t) + // version
455                                 sizeof (uint32_t) + // infoArrayCount
456                                 addr_size +         // infoArray
457                                 addr_size +         // notification
458                                 addr_size +         // processDetachedFromSharedRegion + libSystemInitialized + pad
459                                 addr_size;          // dyldImageLoadAddress
460        const size_t count_v11 = count_v2 +
461                                 addr_size +         // jitInfo
462                                 addr_size +         // dyldVersion
463                                 addr_size +         // errorMessage
464                                 addr_size +         // terminationFlags
465                                 addr_size +         // coreSymbolicationShmPage
466                                 addr_size +         // systemOrderFlag
467                                 addr_size +         // uuidArrayCount
468                                 addr_size +         // uuidArray
469                                 addr_size +         // dyldAllImageInfosAddress
470                                 addr_size +         // initialImageCount
471                                 addr_size +         // errorKind
472                                 addr_size +         // errorClientOfDylibPath
473                                 addr_size +         // errorTargetDylibPath
474                                 addr_size;          // errorSymbol
475        assert (sizeof (buf) > count_v11);
476
477        int count;
478        Error error;
479        if (m_process->ReadMemory (m_dyld_all_image_infos_addr, buf, 4, error) == 4)
480        {
481            m_dyld_all_image_infos.version = data.GetU32(&offset);
482            // If anything in the high byte is set, we probably got the byte
483            // order incorrect (the process might not have it set correctly
484            // yet due to attaching to a program without a specified file).
485            if (m_dyld_all_image_infos.version & 0xff000000)
486            {
487                // We have guessed the wrong byte order. Swap it and try
488                // reading the version again.
489                if (byte_order == eByteOrderLittle)
490                    byte_order = eByteOrderBig;
491                else
492                    byte_order = eByteOrderLittle;
493
494                data.SetByteOrder (byte_order);
495                offset = 0;
496                m_dyld_all_image_infos.version = data.GetU32(&offset);
497            }
498        }
499        else
500        {
501            return false;
502        }
503
504        if (m_dyld_all_image_infos.version >= 11)
505            count = count_v11;
506        else
507            count = count_v2;
508
509        const size_t bytes_read = m_process->ReadMemory (m_dyld_all_image_infos_addr, buf, count, error);
510        if (bytes_read == count)
511        {
512            offset = 0;
513            m_dyld_all_image_infos.version = data.GetU32(&offset);
514            m_dyld_all_image_infos.dylib_info_count = data.GetU32(&offset);
515            m_dyld_all_image_infos.dylib_info_addr = data.GetPointer(&offset);
516            m_dyld_all_image_infos.notification = data.GetPointer(&offset);
517            m_dyld_all_image_infos.processDetachedFromSharedRegion = data.GetU8(&offset);
518            m_dyld_all_image_infos.libSystemInitialized = data.GetU8(&offset);
519            // Adjust for padding.
520            offset += addr_size - 2;
521            m_dyld_all_image_infos.dyldImageLoadAddress = data.GetPointer(&offset);
522            if (m_dyld_all_image_infos.version >= 11)
523            {
524                offset += addr_size * 8;
525                uint64_t dyld_all_image_infos_addr = data.GetPointer(&offset);
526
527                // When we started, we were given the actual address of the all_image_infos
528                // struct (probably via TASK_DYLD_INFO) in memory - this address is stored in
529                // m_dyld_all_image_infos_addr and is the most accurate address we have.
530
531                // We read the dyld_all_image_infos struct from memory; it contains its own address.
532                // If the address in the struct does not match the actual address,
533                // the dyld we're looking at has been loaded at a different location (slid) from
534                // where it intended to load.  The addresses in the dyld_all_image_infos struct
535                // are the original, non-slid addresses, and need to be adjusted.  Most importantly
536                // the address of dyld and the notification address need to be adjusted.
537
538                if (dyld_all_image_infos_addr != m_dyld_all_image_infos_addr)
539                {
540                    uint64_t image_infos_offset = dyld_all_image_infos_addr - m_dyld_all_image_infos.dyldImageLoadAddress;
541                    uint64_t notification_offset = m_dyld_all_image_infos.notification - m_dyld_all_image_infos.dyldImageLoadAddress;
542                    m_dyld_all_image_infos.dyldImageLoadAddress = m_dyld_all_image_infos_addr - image_infos_offset;
543                    m_dyld_all_image_infos.notification = m_dyld_all_image_infos.dyldImageLoadAddress + notification_offset;
544                }
545            }
546            m_dyld_all_image_infos_stop_id = m_process->GetStopID();
547            return true;
548        }
549    }
550    return false;
551}
552
553//----------------------------------------------------------------------
554// If we have found where the "_dyld_all_image_infos" lives in memory,
555// read the current info from it, and then update all image load
556// addresses (or lack thereof).
557//----------------------------------------------------------------------
558uint32_t
559DynamicLoaderMacOSXDYLD::UpdateAllImageInfos()
560{
561    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
562    ModuleList& target_images = m_process->GetTarget().GetImages();
563
564    if (ReadAllImageInfosStructure ())
565    {
566        Mutex::Locker locker(m_mutex);
567        if (m_process->GetStopID() == m_dyld_image_infos_stop_id)
568            m_dyld_image_infos.size();
569
570        uint32_t idx;
571        uint32_t i = 0;
572        // Since we can't downsize a vector, we must do this using the swap method
573        DYLDImageInfo::collection old_dyld_all_image_infos;
574        old_dyld_all_image_infos.swap(m_dyld_image_infos);
575
576        // If we made it here, we are assuming that the all dylib info data should
577        // be valid, lets read the info array.
578        const ByteOrder endian = m_dyld.GetByteOrder();
579        const uint32_t addr_size = m_dyld.GetAddressByteSize();
580
581        if (m_dyld_all_image_infos.dylib_info_count > 0)
582        {
583            if (m_dyld_all_image_infos.dylib_info_addr == 0)
584            {
585                // DYLD is updating the images right now...
586            }
587            else
588            {
589                m_dyld_image_infos.resize(m_dyld_all_image_infos.dylib_info_count);
590                const size_t count = m_dyld_image_infos.size() * 3 * addr_size;
591                DataBufferHeap info_data(count, 0);
592                Error error;
593                const size_t bytes_read = m_process->ReadMemory (m_dyld_all_image_infos.dylib_info_addr,
594                                                                 info_data.GetBytes(),
595                                                                 info_data.GetByteSize(),
596                                                                 error);
597                if (bytes_read == count)
598                {
599                    uint32_t info_data_offset = 0;
600                    DataExtractor info_data_ref(info_data.GetBytes(), info_data.GetByteSize(), endian, addr_size);
601                    for (i = 0; info_data_ref.ValidOffset(info_data_offset); i++)
602                    {
603                        assert (i < m_dyld_image_infos.size());
604                        m_dyld_image_infos[i].address = info_data_ref.GetPointer(&info_data_offset);
605                        lldb::addr_t path_addr = info_data_ref.GetPointer(&info_data_offset);
606                        m_dyld_image_infos[i].mod_date = info_data_ref.GetPointer(&info_data_offset);
607
608                        char raw_path[PATH_MAX];
609                        m_process->ReadCStringFromMemory (path_addr, raw_path, sizeof(raw_path));
610                        char raw_path2[PATH_MAX];// TODO: remove after assertion doesn't assert
611                        m_process->ReadMemory (path_addr, raw_path2, sizeof(raw_path2), error);// TODO: remove after assertion doesn't assert
612                        assert (strcmp (raw_path, raw_path2) == 0);// TODO: remove after assertion doesn't assert
613                        m_dyld_image_infos[i].file_spec.SetFile(raw_path, true);
614                    }
615                    assert(i == m_dyld_all_image_infos.dylib_info_count);
616
617                    UpdateAllImageInfosHeaderAndLoadCommands();
618                }
619                else
620                {
621                    DEBUG_PRINTF( "unable to read all data for all_dylib_infos.");
622                    m_dyld_image_infos.clear();
623                }
624            }
625        }
626
627        // If our new list is smaller than our old list, we have unloaded
628        // some shared libraries
629        if (m_dyld_image_infos.size() != old_dyld_all_image_infos.size())
630        {
631            ModuleList unloaded_module_list;
632            if (old_dyld_all_image_infos.size() == 0)
633            {
634                // This is the first time we are loading shared libraries,
635                // we need to make sure to trim anything that isn't in the
636                // m_dyld_image_infos out of the target module list since
637                // we might have shared libraries that got loaded from
638                // elsewhere due to DYLD_FRAMEWORK_PATH, or DYLD_LIBRARY_PATH
639                // environment variables...
640                const size_t num_images = target_images.GetSize();
641                for (idx = 0; idx < num_images; ++idx)
642                {
643                    ModuleSP module_sp (target_images.GetModuleAtIndex (idx));
644
645                    if (GetImageInfo (module_sp.get()) == NULL)
646                        unloaded_module_list.AppendIfNeeded (module_sp);
647                }
648            }
649            else
650            {
651                uint32_t old_idx;
652                for (idx = 0; idx < old_dyld_all_image_infos.size(); ++idx)
653                {
654                    for (old_idx = idx; old_idx < old_dyld_all_image_infos.size(); ++old_idx)
655                    {
656                        if (m_dyld_image_infos[idx].file_spec == old_dyld_all_image_infos[old_idx].file_spec)
657                        {
658                            old_dyld_all_image_infos[old_idx].address = LLDB_INVALID_ADDRESS;
659                            break;
660                        }
661                    }
662                }
663
664                for (old_idx = 0; old_idx < old_dyld_all_image_infos.size(); ++old_idx)
665                {
666                    if (old_dyld_all_image_infos[old_idx].address != LLDB_INVALID_ADDRESS)
667                    {
668                        if (log)
669                            old_dyld_all_image_infos[old_idx].PutToLog (log.get());
670                        ModuleSP unload_image_module_sp (FindTargetModuleForDYLDImageInfo (old_dyld_all_image_infos[old_idx], false, NULL));
671                        if (unload_image_module_sp.get())
672                        {
673                            if (UnloadImageLoadAddress (unload_image_module_sp.get(), old_dyld_all_image_infos[old_idx]))
674                                unloaded_module_list.AppendIfNeeded (unload_image_module_sp);
675                        }
676                    }
677                }
678            }
679
680            if (unloaded_module_list.GetSize() > 0)
681            {
682                if (log)
683                {
684                    log->PutCString("Unloaded:");
685                    unloaded_module_list.LogUUIDAndPaths (log, "DynamicLoaderMacOSXDYLD::ModulesDidUnload");
686                }
687                m_process->GetTarget().ModulesDidUnload (unloaded_module_list);
688            }
689        }
690        else
691        {
692            if (log)
693                PutToLog(log.get());
694        }
695        m_dyld_image_infos_stop_id = m_process->GetStopID();
696    }
697    else
698    {
699        m_dyld_image_infos.clear();
700    }
701
702    const uint32_t num_dylibs = m_dyld_image_infos.size();
703    if (num_dylibs > 0)
704    {
705        ModuleList loaded_module_list;
706        for (uint32_t idx = 0; idx<num_dylibs; ++idx)
707        {
708            ModuleSP image_module_sp (FindTargetModuleForDYLDImageInfo (m_dyld_image_infos[idx], true, NULL));
709
710            if (image_module_sp)
711            {
712                if (m_dyld_image_infos[idx].header.filetype == llvm::MachO::HeaderFileTypeDynamicLinkEditor)
713                    image_module_sp->SetIsDynamicLinkEditor (true);
714
715                ObjectFile *objfile = image_module_sp->GetObjectFile ();
716                if (objfile)
717                {
718                    SectionList *sections = objfile->GetSectionList();
719                    if (sections)
720                    {
721                        ConstString commpage_dbstr("__commpage");
722                        Section *commpage_section = sections->FindSectionByName(commpage_dbstr).get();
723                        if (commpage_section)
724                        {
725                            const FileSpec objfile_file_spec = objfile->GetFileSpec();
726                            ArchSpec arch (m_dyld_image_infos[idx].GetArchitecture ());
727                            ModuleSP commpage_image_module_sp(target_images.FindFirstModuleForFileSpec (objfile_file_spec, &arch, &commpage_dbstr));
728                            if (!commpage_image_module_sp)
729                            {
730                                commpage_image_module_sp = m_process->GetTarget().GetSharedModule (m_dyld_image_infos[idx].file_spec,
731                                                                                                   arch,
732                                                                                                   NULL,
733                                                                                                   &commpage_dbstr,
734                                                                                                   objfile->GetOffset() + commpage_section->GetFileOffset());
735                            }
736                            if (commpage_image_module_sp)
737                                UpdateCommPageLoadAddress (commpage_image_module_sp.get());
738                        }
739                    }
740                }
741
742                // UpdateImageLoadAddress will return true if any segments
743                // change load address. We need to check this so we don't
744                // mention that all loaded shared libraries are newly loaded
745                // each time we hit out dyld breakpoint since dyld will list all
746                // shared libraries each time.
747                if (UpdateImageLoadAddress (image_module_sp.get(), m_dyld_image_infos[idx]))
748                {
749                    loaded_module_list.AppendIfNeeded (image_module_sp);
750                }
751            }
752        }
753        if (loaded_module_list.GetSize() > 0)
754        {
755            // FIXME: This should really be in the Runtime handlers class, which should get
756            // called by the target's ModulesDidLoad, but we're doing it all locally for now
757            // to save time.
758            // Also, I'm assuming there can be only one libobjc dylib loaded...
759
760            ObjCLanguageRuntime *objc_runtime = m_process->GetObjCLanguageRuntime();
761            if (objc_runtime != NULL && !objc_runtime->HasReadObjCLibrary())
762            {
763                size_t num_modules = loaded_module_list.GetSize();
764                for (int i = 0; i < num_modules; i++)
765                {
766                    if (objc_runtime->IsModuleObjCLibrary (loaded_module_list.GetModuleAtIndex (i)))
767                    {
768                        objc_runtime->ReadObjCLibrary (loaded_module_list.GetModuleAtIndex (i));
769                        break;
770                    }
771                }
772            }
773            if (log)
774                loaded_module_list.LogUUIDAndPaths (log, "DynamicLoaderMacOSXDYLD::ModulesDidLoad");
775            m_process->GetTarget().ModulesDidLoad (loaded_module_list);
776        }
777    }
778    return m_dyld_image_infos.size();
779}
780
781//----------------------------------------------------------------------
782// Read a mach_header at ADDR into HEADER, and also fill in the load
783// command data into LOAD_COMMAND_DATA if it is non-NULL.
784//
785// Returns true if we succeed, false if we fail for any reason.
786//----------------------------------------------------------------------
787bool
788DynamicLoaderMacOSXDYLD::ReadMachHeader (lldb::addr_t addr, llvm::MachO::mach_header *header, DataExtractor *load_command_data)
789{
790    DataBufferHeap header_bytes(sizeof(llvm::MachO::mach_header), 0);
791    Error error;
792    size_t bytes_read = m_process->ReadMemory (addr,
793                                               header_bytes.GetBytes(),
794                                               header_bytes.GetByteSize(),
795                                               error);
796    if (bytes_read == sizeof(llvm::MachO::mach_header))
797    {
798        uint32_t offset = 0;
799        ::memset (header, 0, sizeof(header));
800
801        // Get the magic byte unswapped so we can figure out what we are dealing with
802        DataExtractor data(header_bytes.GetBytes(), header_bytes.GetByteSize(), lldb::endian::InlHostByteOrder(), 4);
803        header->magic = data.GetU32(&offset);
804        lldb::addr_t load_cmd_addr = addr;
805        data.SetByteOrder(DynamicLoaderMacOSXDYLD::GetByteOrderFromMagic(header->magic));
806        switch (header->magic)
807        {
808        case llvm::MachO::HeaderMagic32:
809        case llvm::MachO::HeaderMagic32Swapped:
810            data.SetAddressByteSize(4);
811            load_cmd_addr += sizeof(llvm::MachO::mach_header);
812            break;
813
814        case llvm::MachO::HeaderMagic64:
815        case llvm::MachO::HeaderMagic64Swapped:
816            data.SetAddressByteSize(8);
817            load_cmd_addr += sizeof(llvm::MachO::mach_header_64);
818            break;
819
820        default:
821            return false;
822        }
823
824        // Read the rest of dyld's mach header
825        if (data.GetU32(&offset, &header->cputype, (sizeof(llvm::MachO::mach_header)/sizeof(uint32_t)) - 1))
826        {
827            if (load_command_data == NULL)
828                return true; // We were able to read the mach_header and weren't asked to read the load command bytes
829
830            DataBufferSP load_cmd_data_sp(new DataBufferHeap(header->sizeofcmds, 0));
831
832            size_t load_cmd_bytes_read = m_process->ReadMemory (load_cmd_addr,
833                                                                load_cmd_data_sp->GetBytes(),
834                                                                load_cmd_data_sp->GetByteSize(),
835                                                                error);
836
837            if (load_cmd_bytes_read == header->sizeofcmds)
838            {
839                // Set the load command data and also set the correct endian
840                // swap settings and the correct address size
841                load_command_data->SetData(load_cmd_data_sp, 0, header->sizeofcmds);
842                load_command_data->SetByteOrder(data.GetByteOrder());
843                load_command_data->SetAddressByteSize(data.GetAddressByteSize());
844                return true; // We successfully read the mach_header and the load command data
845            }
846
847            return false; // We weren't able to read the load command data
848        }
849    }
850    return false; // We failed the read the mach_header
851}
852
853
854//----------------------------------------------------------------------
855// Parse the load commands for an image
856//----------------------------------------------------------------------
857uint32_t
858DynamicLoaderMacOSXDYLD::ParseLoadCommands (const DataExtractor& data, DYLDImageInfo& dylib_info, FileSpec *lc_id_dylinker)
859{
860    uint32_t offset = 0;
861    uint32_t cmd_idx;
862    Segment segment;
863    dylib_info.Clear (true);
864
865    for (cmd_idx = 0; cmd_idx < dylib_info.header.ncmds; cmd_idx++)
866    {
867        // Clear out any load command specific data from DYLIB_INFO since
868        // we are about to read it.
869
870        if (data.ValidOffsetForDataOfSize (offset, sizeof(llvm::MachO::load_command)))
871        {
872            llvm::MachO::load_command load_cmd;
873            uint32_t load_cmd_offset = offset;
874            load_cmd.cmd = data.GetU32 (&offset);
875            load_cmd.cmdsize = data.GetU32 (&offset);
876            switch (load_cmd.cmd)
877            {
878            case llvm::MachO::LoadCommandSegment32:
879                {
880                    segment.name.SetTrimmedCStringWithLength ((const char *)data.GetData(&offset, 16), 16);
881                    // We are putting 4 uint32_t values 4 uint64_t values so
882                    // we have to use multiple 32 bit gets below.
883                    segment.vmaddr = data.GetU32 (&offset);
884                    segment.vmsize = data.GetU32 (&offset);
885                    segment.fileoff = data.GetU32 (&offset);
886                    segment.filesize = data.GetU32 (&offset);
887                    // Extract maxprot, initprot, nsects and flags all at once
888                    data.GetU32(&offset, &segment.maxprot, 4);
889                    dylib_info.segments.push_back (segment);
890                }
891                break;
892
893            case llvm::MachO::LoadCommandSegment64:
894                {
895                    segment.name.SetTrimmedCStringWithLength ((const char *)data.GetData(&offset, 16), 16);
896                    // Extract vmaddr, vmsize, fileoff, and filesize all at once
897                    data.GetU64(&offset, &segment.vmaddr, 4);
898                    // Extract maxprot, initprot, nsects and flags all at once
899                    data.GetU32(&offset, &segment.maxprot, 4);
900                    dylib_info.segments.push_back (segment);
901                }
902                break;
903
904            case llvm::MachO::LoadCommandDynamicLinkerIdent:
905                if (lc_id_dylinker)
906                {
907                    uint32_t name_offset = load_cmd_offset + data.GetU32 (&offset);
908                    const char *path = data.PeekCStr (name_offset);
909                    lc_id_dylinker->SetFile (path, true);
910                }
911                break;
912
913            case llvm::MachO::LoadCommandUUID:
914                dylib_info.uuid.SetBytes(data.GetData (&offset, 16));
915                break;
916
917            default:
918                break;
919            }
920            // Set offset to be the beginning of the next load command.
921            offset = load_cmd_offset + load_cmd.cmdsize;
922        }
923    }
924
925    // All sections listed in the dyld image info structure will all
926    // either be fixed up already, or they will all be off by a single
927    // slide amount that is determined by finding the first segment
928    // that is at file offset zero which also has bytes (a file size
929    // that is greater than zero) in the object file.
930
931    // Determine the slide amount (if any)
932    const size_t num_sections = dylib_info.segments.size();
933    for (size_t i = 0; i < num_sections; ++i)
934    {
935        // Iterate through the object file sections to find the
936        // first section that starts of file offset zero and that
937        // has bytes in the file...
938        if (dylib_info.segments[i].fileoff == 0 && dylib_info.segments[i].filesize > 0)
939        {
940            dylib_info.slide = dylib_info.address - dylib_info.segments[i].vmaddr;
941            // We have found the slide amount, so we can exit
942            // this for loop.
943            break;
944        }
945    }
946    return cmd_idx;
947}
948
949//----------------------------------------------------------------------
950// Read the mach_header and load commands for each image that the
951// _dyld_all_image_infos structure points to and cache the results.
952//----------------------------------------------------------------------
953void
954DynamicLoaderMacOSXDYLD::UpdateAllImageInfosHeaderAndLoadCommands()
955{
956    uint32_t exe_idx = UINT32_MAX;
957    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
958    // Read any UUID values that we can get
959    for (uint32_t i = 0; i < m_dyld_all_image_infos.dylib_info_count; i++)
960    {
961        if (!m_dyld_image_infos[i].UUIDValid())
962        {
963            DataExtractor data; // Load command data
964            if (!ReadMachHeader (m_dyld_image_infos[i].address, &m_dyld_image_infos[i].header, &data))
965                continue;
966
967            ParseLoadCommands (data, m_dyld_image_infos[i], NULL);
968
969            if (m_dyld_image_infos[i].header.filetype == llvm::MachO::HeaderFileTypeExecutable)
970                exe_idx = i;
971
972            if (log)
973                m_dyld_image_infos[i].PutToLog (log.get());
974        }
975    }
976
977    if (exe_idx < m_dyld_image_infos.size())
978    {
979        ModuleSP exe_module_sp (FindTargetModuleForDYLDImageInfo (m_dyld_image_infos[exe_idx], false, NULL));
980
981        if (!exe_module_sp)
982        {
983            ArchSpec exe_arch_spec (m_dyld_image_infos[exe_idx].GetArchitecture ());
984            exe_module_sp = m_process->GetTarget().GetSharedModule (m_dyld_image_infos[exe_idx].file_spec,
985                                                                    exe_arch_spec,
986                                                                    &m_dyld_image_infos[exe_idx].uuid);
987        }
988
989        if (exe_module_sp)
990        {
991            if (exe_module_sp.get() != m_process->GetTarget().GetExecutableModule().get())
992            {
993                // Don't load dependent images since we are in dyld where we will know
994                // and find out about all images that are loaded
995                bool get_dependent_images = false;
996                m_process->GetTarget().SetExecutableModule (exe_module_sp,
997                                                            get_dependent_images);
998            }
999        }
1000    }
1001}
1002
1003//----------------------------------------------------------------------
1004// Dump a Segment to the file handle provided.
1005//----------------------------------------------------------------------
1006void
1007DynamicLoaderMacOSXDYLD::Segment::PutToLog (Log *log, lldb::addr_t slide) const
1008{
1009    if (log)
1010    {
1011        if (slide == 0)
1012            log->Printf ("\t\t%16s [0x%16.16llx - 0x%16.16llx)",
1013                         name.AsCString(""),
1014                         vmaddr + slide,
1015                         vmaddr + slide + vmsize);
1016        else
1017            log->Printf ("\t\t%16s [0x%16.16llx - 0x%16.16llx) slide = 0x%llx",
1018                         name.AsCString(""),
1019                         vmaddr + slide,
1020                         vmaddr + slide + vmsize,
1021                         slide);
1022    }
1023}
1024
1025const DynamicLoaderMacOSXDYLD::Segment *
1026DynamicLoaderMacOSXDYLD::DYLDImageInfo::FindSegment (const ConstString &name) const
1027{
1028    const size_t num_segments = segments.size();
1029    for (size_t i=0; i<num_segments; ++i)
1030    {
1031        if (segments[i].name == name)
1032            return &segments[i];
1033    }
1034    return NULL;
1035}
1036
1037
1038//----------------------------------------------------------------------
1039// Dump an image info structure to the file handle provided.
1040//----------------------------------------------------------------------
1041void
1042DynamicLoaderMacOSXDYLD::DYLDImageInfo::PutToLog (Log *log) const
1043{
1044    if (log == NULL)
1045        return;
1046    uint8_t *u = (uint8_t *)uuid.GetBytes();
1047
1048    if (address == LLDB_INVALID_ADDRESS)
1049    {
1050        if (u)
1051        {
1052            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)",
1053                        mod_date,
1054                        u[ 0], u[ 1], u[ 2], u[ 3],
1055                        u[ 4], u[ 5], u[ 6], u[ 7],
1056                        u[ 8], u[ 9], u[10], u[11],
1057                        u[12], u[13], u[14], u[15],
1058                        file_spec.GetDirectory().AsCString(),
1059                        file_spec.GetFilename().AsCString());
1060        }
1061        else
1062            log->Printf("\t                           modtime=0x%8.8llx path='%s/%s' (UNLOADED)",
1063                        mod_date,
1064                        file_spec.GetDirectory().AsCString(),
1065                        file_spec.GetFilename().AsCString());
1066    }
1067    else
1068    {
1069        if (u)
1070        {
1071            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'",
1072                        address,
1073                        mod_date,
1074                        u[ 0], u[ 1], u[ 2], u[ 3],
1075                        u[ 4], u[ 5], u[ 6], u[ 7],
1076                        u[ 8], u[ 9], u[10], u[11],
1077                        u[12], u[13], u[14], u[15],
1078                        file_spec.GetDirectory().AsCString(),
1079                        file_spec.GetFilename().AsCString());
1080        }
1081        else
1082        {
1083            log->Printf("\taddress=0x%16.16llx modtime=0x%8.8llx path='%s/%s'",
1084                        address,
1085                        mod_date,
1086                        file_spec.GetDirectory().AsCString(),
1087                        file_spec.GetFilename().AsCString());
1088
1089        }
1090        for (uint32_t i=0; i<segments.size(); ++i)
1091            segments[i].PutToLog(log, slide);
1092    }
1093}
1094
1095//----------------------------------------------------------------------
1096// Dump the _dyld_all_image_infos members and all current image infos
1097// that we have parsed to the file handle provided.
1098//----------------------------------------------------------------------
1099void
1100DynamicLoaderMacOSXDYLD::PutToLog(Log *log) const
1101{
1102    if (log == NULL)
1103        return;
1104
1105    Mutex::Locker locker(m_mutex);
1106    log->Printf("dyld_all_image_infos = { version=%d, count=%d, addr=0x%8.8llx, notify=0x%8.8llx }",
1107                    m_dyld_all_image_infos.version,
1108                    m_dyld_all_image_infos.dylib_info_count,
1109                    (uint64_t)m_dyld_all_image_infos.dylib_info_addr,
1110                    (uint64_t)m_dyld_all_image_infos.notification);
1111    size_t i;
1112    const size_t count = m_dyld_image_infos.size();
1113    if (count > 0)
1114    {
1115        log->PutCString("Loaded:");
1116        for (i = 0; i<count; i++)
1117            m_dyld_image_infos[i].PutToLog(log);
1118    }
1119}
1120
1121void
1122DynamicLoaderMacOSXDYLD::PrivateInitialize(Process *process)
1123{
1124    DEBUG_PRINTF("DynamicLoaderMacOSXDYLD::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState()));
1125    Clear(true);
1126    m_process = process;
1127    m_process->GetTarget().GetSectionLoadList().Clear();
1128}
1129
1130bool
1131DynamicLoaderMacOSXDYLD::SetNotificationBreakpoint ()
1132{
1133    DEBUG_PRINTF("DynamicLoaderMacOSXDYLD::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState()));
1134    if (m_break_id == LLDB_INVALID_BREAK_ID)
1135    {
1136        if (m_dyld_all_image_infos.notification != LLDB_INVALID_ADDRESS)
1137        {
1138            Address so_addr;
1139            // Set the notification breakpoint and install a breakpoint
1140            // callback function that will get called each time the
1141            // breakpoint gets hit. We will use this to track when shared
1142            // libraries get loaded/unloaded.
1143
1144            if (m_process->GetTarget().GetSectionLoadList().ResolveLoadAddress(m_dyld_all_image_infos.notification, so_addr))
1145            {
1146                Breakpoint *dyld_break = m_process->GetTarget().CreateBreakpoint (so_addr, true).get();
1147                dyld_break->SetCallback (DynamicLoaderMacOSXDYLD::NotifyBreakpointHit, this, true);
1148                m_break_id = dyld_break->GetID();
1149            }
1150        }
1151    }
1152    return m_break_id != LLDB_INVALID_BREAK_ID;
1153}
1154
1155//----------------------------------------------------------------------
1156// Member function that gets called when the process state changes.
1157//----------------------------------------------------------------------
1158void
1159DynamicLoaderMacOSXDYLD::PrivateProcessStateChanged (Process *process, StateType state)
1160{
1161    DEBUG_PRINTF("DynamicLoaderMacOSXDYLD::%s(%s)\n", __FUNCTION__, StateAsCString(state));
1162    switch (state)
1163    {
1164    case eStateConnected:
1165    case eStateAttaching:
1166    case eStateLaunching:
1167    case eStateInvalid:
1168    case eStateUnloaded:
1169    case eStateExited:
1170    case eStateDetached:
1171        Clear(false);
1172        break;
1173
1174    case eStateStopped:
1175        // Keep trying find dyld and set our notification breakpoint each time
1176        // we stop until we succeed
1177        if (!DidSetNotificationBreakpoint () && m_process->IsAlive())
1178        {
1179            if (NeedToLocateDYLD ())
1180                LocateDYLD ();
1181
1182            SetNotificationBreakpoint ();
1183        }
1184        break;
1185
1186    case eStateRunning:
1187    case eStateStepping:
1188    case eStateCrashed:
1189    case eStateSuspended:
1190        break;
1191
1192    default:
1193        break;
1194    }
1195}
1196
1197ThreadPlanSP
1198DynamicLoaderMacOSXDYLD::GetStepThroughTrampolinePlan (Thread &thread, bool stop_others)
1199{
1200    ThreadPlanSP thread_plan_sp;
1201    StackFrame *current_frame = thread.GetStackFrameAtIndex(0).get();
1202    const SymbolContext &current_context = current_frame->GetSymbolContext(eSymbolContextSymbol);
1203    Symbol *current_symbol = current_context.symbol;
1204    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
1205
1206    if (current_symbol != NULL)
1207    {
1208        if (current_symbol->IsTrampoline())
1209        {
1210            const ConstString &trampoline_name = current_symbol->GetMangled().GetName(Mangled::ePreferMangled);
1211
1212            if (trampoline_name)
1213            {
1214                SymbolContextList target_symbols;
1215                ModuleList &images = thread.GetProcess().GetTarget().GetImages();
1216                images.FindSymbolsWithNameAndType(trampoline_name, eSymbolTypeCode, target_symbols);
1217                // FIXME - Make the Run to Address take multiple addresses, and
1218                // run to any of them.
1219                uint32_t num_symbols = target_symbols.GetSize();
1220                if (num_symbols == 1)
1221                {
1222                    SymbolContext context;
1223                    AddressRange addr_range;
1224                    if (target_symbols.GetContextAtIndex(0, context))
1225                    {
1226                        context.GetAddressRange (eSymbolContextEverything, 0, false, addr_range);
1227                        thread_plan_sp.reset (new ThreadPlanRunToAddress (thread, addr_range.GetBaseAddress(), stop_others));
1228                    }
1229                    else
1230                    {
1231                        if (log)
1232                            log->Printf ("Couldn't resolve the symbol context.");
1233                    }
1234                }
1235                else if (num_symbols > 1)
1236                {
1237                    std::vector<lldb::addr_t>  addresses;
1238                    addresses.resize (num_symbols);
1239                    for (uint32_t i = 0; i < num_symbols; i++)
1240                    {
1241                        SymbolContext context;
1242                        AddressRange addr_range;
1243                        if (target_symbols.GetContextAtIndex(i, context))
1244                        {
1245                            context.GetAddressRange (eSymbolContextEverything, 0, false, addr_range);
1246                            lldb::addr_t load_addr = addr_range.GetBaseAddress().GetLoadAddress(&thread.GetProcess().GetTarget());
1247                            addresses[i] = load_addr;
1248                        }
1249                    }
1250                    if (addresses.size() > 0)
1251                        thread_plan_sp.reset (new ThreadPlanRunToAddress (thread, addresses, stop_others));
1252                    else
1253                    {
1254                        if (log)
1255                            log->Printf ("Couldn't resolve the symbol contexts.");
1256                    }
1257                }
1258                else
1259                {
1260                    if (log)
1261                    {
1262                        log->Printf ("Could not find symbol for trampoline target: \"%s\"", trampoline_name.AsCString());
1263                    }
1264                }
1265            }
1266        }
1267    }
1268    else
1269    {
1270        if (log)
1271            log->Printf ("Could not find symbol for step through.");
1272    }
1273
1274    return thread_plan_sp;
1275}
1276
1277Error
1278DynamicLoaderMacOSXDYLD::CanLoadImage ()
1279{
1280    Error error;
1281    // In order for us to tell if we can load a shared library we verify that
1282    // the dylib_info_addr isn't zero (which means no shared libraries have
1283    // been set yet, or dyld is currently mucking with the shared library list).
1284    if (ReadAllImageInfosStructure ())
1285    {
1286        // TODO: also check the _dyld_global_lock_held variable in libSystem.B.dylib?
1287        // TODO: check the malloc lock?
1288        // TODO: check the objective C lock?
1289        if (m_dyld_all_image_infos.dylib_info_addr != 0)
1290            return error; // Success
1291    }
1292
1293    error.SetErrorString("unsafe to load or unload shared libraries");
1294    return error;
1295}
1296
1297void
1298DynamicLoaderMacOSXDYLD::Initialize()
1299{
1300    PluginManager::RegisterPlugin (GetPluginNameStatic(),
1301                                   GetPluginDescriptionStatic(),
1302                                   CreateInstance);
1303}
1304
1305void
1306DynamicLoaderMacOSXDYLD::Terminate()
1307{
1308    PluginManager::UnregisterPlugin (CreateInstance);
1309}
1310
1311
1312const char *
1313DynamicLoaderMacOSXDYLD::GetPluginNameStatic()
1314{
1315    return "dynamic-loader.macosx-dyld";
1316}
1317
1318const char *
1319DynamicLoaderMacOSXDYLD::GetPluginDescriptionStatic()
1320{
1321    return "Dynamic loader plug-in that watches for shared library loads/unloads in MacOSX user processes.";
1322}
1323
1324
1325//------------------------------------------------------------------
1326// PluginInterface protocol
1327//------------------------------------------------------------------
1328const char *
1329DynamicLoaderMacOSXDYLD::GetPluginName()
1330{
1331    return "DynamicLoaderMacOSXDYLD";
1332}
1333
1334const char *
1335DynamicLoaderMacOSXDYLD::GetShortPluginName()
1336{
1337    return GetPluginNameStatic();
1338}
1339
1340uint32_t
1341DynamicLoaderMacOSXDYLD::GetPluginVersion()
1342{
1343    return 1;
1344}
1345
1346