DynamicLoaderMacOSXDYLD.cpp revision 36da2aa6dc5ad9994b638ed09eb81c44cc05540b
145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org//===-- DynamicLoaderMacOSXDYLD.cpp -----------------------------*- C++ -*-===//
245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org//
345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org//                     The LLVM Compiler Infrastructure
445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org//
5a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org// This file is distributed under the University of Illinois Open Source
645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org// License. See LICENSE.TXT for details.
745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org//
845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org//===----------------------------------------------------------------------===//
945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
1045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
1145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "llvm/Support/MachO.h"
1245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
1345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "lldb/Breakpoint/StoppointCallbackContext.h"
1445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "lldb/Core/DataBuffer.h"
1545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "lldb/Core/DataBufferHeap.h"
1645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "lldb/Core/Log.h"
1745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "lldb/Core/Module.h"
1845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "lldb/Core/ModuleSpec.h"
1945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "lldb/Core/PluginManager.h"
2045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "lldb/Core/Section.h"
2145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "lldb/Core/State.h"
2245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "lldb/Symbol/Function.h"
2345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "lldb/Symbol/ObjectFile.h"
2445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "lldb/Target/ObjCLanguageRuntime.h"
2545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "lldb/Target/RegisterContext.h"
2645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "lldb/Target/Target.h"
2745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "lldb/Target/Thread.h"
2845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "lldb/Target/ThreadPlanRunToAddress.h"
2945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "lldb/Target/StackFrame.h"
3045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
3145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "DynamicLoaderMacOSXDYLD.h"
3245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
3345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org//#define ENABLE_DEBUG_PRINTF // COMMENT THIS LINE OUT PRIOR TO CHECKIN
3445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#ifdef ENABLE_DEBUG_PRINTF
3545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include <stdio.h>
3645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define DEBUG_PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__)
3745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#else
3845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define DEBUG_PRINTF(fmt, ...)
3945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#endif
4045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
4145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgusing namespace lldb;
4245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgusing namespace lldb_private;
4345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
4445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/// FIXME - The ObjC Runtime trampoline handler doesn't really belong here.
4545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/// I am putting it here so I can invoke it in the Trampoline code here, but
4645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/// it should be moved to the ObjC Runtime support when it is set up.
4745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
4845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
4945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgDynamicLoaderMacOSXDYLD::DYLDImageInfo *
5045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgDynamicLoaderMacOSXDYLD::GetImageInfo (Module *module)
5145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
5245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    const UUID &module_uuid = module->GetUUID();
5345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    DYLDImageInfo::collection::iterator pos, end = m_dyld_image_infos.end();
5445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
5545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    // First try just by UUID as it is the safest.
5645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (module_uuid.IsValid())
5745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    {
5845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        for (pos = m_dyld_image_infos.begin(); pos != end; ++pos)
5945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        {
6045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            if (pos->uuid == module_uuid)
6145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                return &(*pos);
6245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        }
6345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
6445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if (m_dyld.uuid == module_uuid)
6545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            return &m_dyld;
6645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
67a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org
6845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    // Next try by platform path only for things that don't have a valid UUID
6945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    // since if a file has a valid UUID in real life it should also in the
7045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    // dyld info. This is the next safest because the paths in the dyld info
7145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    // are platform paths, not local paths. For local debugging platform == local
7245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    // paths.
7345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    const FileSpec &platform_file_spec = module->GetPlatformFileSpec();
7445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    for (pos = m_dyld_image_infos.begin(); pos != end; ++pos)
7545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    {
7645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if (pos->file_spec == platform_file_spec && pos->uuid.IsValid() == false)
77a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org            return &(*pos);
7845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
7945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
8045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (m_dyld.file_spec == platform_file_spec && m_dyld.uuid.IsValid() == false)
8145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return &m_dyld;
8245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
8345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return NULL;
8445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
8545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
8645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org//----------------------------------------------------------------------
8745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org// Create an instance of this class. This function is filled into
8845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org// the plugin info class that gets handed out by the plugin factory and
8945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org// allows the lldb to instantiate an instance of this class.
9045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org//----------------------------------------------------------------------
9145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgDynamicLoader *
9245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgDynamicLoaderMacOSXDYLD::CreateInstance (Process* process, bool force)
9345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
9445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    bool create = force;
9545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (!create)
9645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    {
9745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        create = true;
9845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        Module* exe_module = process->GetTarget().GetExecutableModulePointer();
9945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if (exe_module)
10045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        {
10145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            ObjectFile *object_file = exe_module->GetObjectFile();
10245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            if (object_file)
103a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org            {
10445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                create = (object_file->GetStrata() == ObjectFile::eStrataUser);
10545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            }
10645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        }
10745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
10845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if (create)
10945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        {
11045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            const llvm::Triple &triple_ref = process->GetTarget().GetArchitecture().GetTriple();
111a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org            switch (triple_ref.getOS())
11245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            {
11345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                case llvm::Triple::Darwin:
11445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                case llvm::Triple::MacOSX:
11545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                case llvm::Triple::IOS:
116a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org                    create = triple_ref.getVendor() == llvm::Triple::Apple;
117a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org                    break;
118a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org                default:
11945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    create = false;
12045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    break;
12145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            }
12245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        }
12345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
12445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
12545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (create)
12645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return new DynamicLoaderMacOSXDYLD (process);
12745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return NULL;
12845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
12945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
13045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org//----------------------------------------------------------------------
13145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org// Constructor
13245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org//----------------------------------------------------------------------
13345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgDynamicLoaderMacOSXDYLD::DynamicLoaderMacOSXDYLD (Process* process) :
13445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    DynamicLoader(process),
13545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    m_dyld(),
13645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    m_dyld_all_image_infos_addr(LLDB_INVALID_ADDRESS),
13745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    m_dyld_all_image_infos(),
13845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    m_dyld_all_image_infos_stop_id (UINT32_MAX),
13945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    m_break_id(LLDB_INVALID_BREAK_ID),
14045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    m_dyld_image_infos(),
14145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    m_dyld_image_infos_stop_id (UINT32_MAX),
14245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    m_mutex(Mutex::eMutexTypeRecursive),
14345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    m_process_image_addr_is_all_images_infos (false)
14445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
14545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
14645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
14745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org//----------------------------------------------------------------------
14845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org// Destructor
14945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org//----------------------------------------------------------------------
15045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgDynamicLoaderMacOSXDYLD::~DynamicLoaderMacOSXDYLD()
15145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
15245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    Clear(true);
15345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
15445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
15545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org//------------------------------------------------------------------
15645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/// Called after attaching a process.
15745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org///
15845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/// Allow DynamicLoader plug-ins to execute some code after
15945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/// attaching to a process.
16045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org//------------------------------------------------------------------
16145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgvoid
16245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgDynamicLoaderMacOSXDYLD::DidAttach ()
16345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
16445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    PrivateInitialize(m_process);
16545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    LocateDYLD ();
16645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    SetNotificationBreakpoint ();
16745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
16845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
16945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org//------------------------------------------------------------------
17045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/// Called after attaching a process.
17145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org///
17245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/// Allow DynamicLoader plug-ins to execute some code after
17345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/// attaching to a process.
17445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org//------------------------------------------------------------------
17545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgvoid
17645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgDynamicLoaderMacOSXDYLD::DidLaunch ()
17745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
17845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    PrivateInitialize(m_process);
17945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    LocateDYLD ();
18045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    SetNotificationBreakpoint ();
18145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
18245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
18345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgbool
18445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgDynamicLoaderMacOSXDYLD::ProcessDidExec ()
18545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
18645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (m_process)
18745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    {
18845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        // If we are stopped after an exec, we will have only one thread...
18945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if (m_process->GetThreadList().GetSize() == 1)
19045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        {
19145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            // We know if a process has exec'ed if our "m_dyld_all_image_infos_addr"
19245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            // value differs from the Process' image info address. When a process
19345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            // execs itself it might cause a change if ASLR is enabled.
19445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            const addr_t shlib_addr = m_process->GetImageInfoAddress ();
195a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org            if (m_process_image_addr_is_all_images_infos == true && shlib_addr != m_dyld_all_image_infos_addr)
19645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            {
19745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                // The image info address from the process is the 'dyld_all_image_infos'
19845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                // address and it has changed.
199a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org                return true;
20045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            }
20145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
20245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            if (m_process_image_addr_is_all_images_infos == false && shlib_addr == m_dyld.address)
20345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            {
20445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                // The image info address from the process is the mach_header
20545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                // address for dyld and it has changed.
20645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                return true;
20745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            }
20845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
20945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            // ASLR might be disabled and dyld could have ended up in the same
21045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            // location. We should try and detect if we are stopped at '_dyld_start'
21145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            ThreadSP thread_sp (m_process->GetThreadList().GetThreadAtIndex(0));
21245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            if (thread_sp)
21345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            {
21445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                lldb::StackFrameSP frame_sp (thread_sp->GetStackFrameAtIndex(0));
21545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                if (frame_sp)
21645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                {
21745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    const Symbol *symbol = frame_sp->GetSymbolContext(eSymbolContextSymbol).symbol;
21845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    if (symbol)
21945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    {
22045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                        if (symbol->GetName() == ConstString("_dyld_start"))
22145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                            return true;
22245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    }
22345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                }
22445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            }
22545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        }
22645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
22745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return false;
22845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
22945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
23045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
23145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
23245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org//----------------------------------------------------------------------
23345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org// Clear out the state of this class.
23445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org//----------------------------------------------------------------------
23545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgvoid
23645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgDynamicLoaderMacOSXDYLD::Clear (bool clear_process)
23745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
23845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    Mutex::Locker locker(m_mutex);
23945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
24045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (m_process->IsAlive() && LLDB_BREAK_ID_IS_VALID(m_break_id))
24145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        m_process->ClearBreakpointSiteByID(m_break_id);
24245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
24345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (clear_process)
24445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        m_process = NULL;
24545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    m_dyld.Clear(false);
24645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    m_dyld_all_image_infos_addr = LLDB_INVALID_ADDRESS;
24745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    m_dyld_all_image_infos.Clear();
24845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    m_break_id = LLDB_INVALID_BREAK_ID;
24945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    m_dyld_image_infos.clear();
25045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
25145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
25245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org//----------------------------------------------------------------------
25345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org// Check if we have found DYLD yet
25445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org//----------------------------------------------------------------------
25545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgbool
25645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgDynamicLoaderMacOSXDYLD::DidSetNotificationBreakpoint() const
25745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
25845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return LLDB_BREAK_ID_IS_VALID (m_break_id);
25945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
26045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
26145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org//----------------------------------------------------------------------
26245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org// Try and figure out where dyld is by first asking the Process
26345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org// if it knows (which currently calls down in the the lldb::Process
26445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org// to get the DYLD info (available on SnowLeopard only). If that fails,
26545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org// then check in the default addresses.
26645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org//----------------------------------------------------------------------
26745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgbool
26845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgDynamicLoaderMacOSXDYLD::LocateDYLD()
26945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
27045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (m_dyld_all_image_infos_addr == LLDB_INVALID_ADDRESS)
27145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    {
27245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        // Check the image info addr as it might point to the
27345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        // mach header for dyld, or it might point to the
27445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        // dyld_all_image_infos struct
27545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        const addr_t shlib_addr = m_process->GetImageInfoAddress ();
27645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        ByteOrder byte_order = m_process->GetTarget().GetArchitecture().GetByteOrder();
27745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        uint8_t buf[4];
27845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        DataExtractor data (buf, sizeof(buf), byte_order, 4);
27945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        Error error;
28045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if (m_process->ReadMemory (shlib_addr, buf, 4, error) == 4)
28145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        {
28245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            lldb::offset_t offset = 0;
28345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            uint32_t magic = data.GetU32 (&offset);
28445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            switch (magic)
28545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            {
286a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org            case llvm::MachO::HeaderMagic32:
28745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            case llvm::MachO::HeaderMagic64:
28845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            case llvm::MachO::HeaderMagic32Swapped:
28945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            case llvm::MachO::HeaderMagic64Swapped:
29045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                m_process_image_addr_is_all_images_infos = false;
29145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                return ReadDYLDInfoFromMemoryAndSetNotificationCallback(shlib_addr);
29245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
29345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            default:
29445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                break;
29545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            }
29645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        }
29745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        // Maybe it points to the all image infos?
29845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        m_dyld_all_image_infos_addr = shlib_addr;
29945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        m_process_image_addr_is_all_images_infos = true;
30045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
30145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
30245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (m_dyld_all_image_infos_addr != LLDB_INVALID_ADDRESS)
30345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    {
30445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if (ReadAllImageInfosStructure ())
30545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        {
30645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            if (m_dyld_all_image_infos.dyldImageLoadAddress != LLDB_INVALID_ADDRESS)
30745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                return ReadDYLDInfoFromMemoryAndSetNotificationCallback (m_dyld_all_image_infos.dyldImageLoadAddress);
30845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            else
30945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                return ReadDYLDInfoFromMemoryAndSetNotificationCallback (m_dyld_all_image_infos_addr & 0xfffffffffff00000ull);
31045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        }
31145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
31245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
31345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    // Check some default values
31445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    Module *executable = m_process->GetTarget().GetExecutableModulePointer();
31545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
31645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (executable)
31745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    {
31845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        const ArchSpec &exe_arch = executable->GetArchitecture();
31945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if (exe_arch.GetAddressByteSize() == 8)
32045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        {
32145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            return ReadDYLDInfoFromMemoryAndSetNotificationCallback(0x7fff5fc00000ull);
32245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        }
32345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        else if (exe_arch.GetMachine() == llvm::Triple::arm || exe_arch.GetMachine() == llvm::Triple::thumb)
32445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        {
32545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            return ReadDYLDInfoFromMemoryAndSetNotificationCallback(0x2fe00000);
32645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        }
32745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        else
32845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        {
32945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            return ReadDYLDInfoFromMemoryAndSetNotificationCallback(0x8fe00000);
33045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        }
33145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
33245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return false;
33345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
33445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
33545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgModuleSP
33645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgDynamicLoaderMacOSXDYLD::FindTargetModuleForDYLDImageInfo (const DYLDImageInfo &image_info, bool can_create, bool *did_create_ptr)
33745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
33845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (did_create_ptr)
33945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        *did_create_ptr = false;
34045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
34145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
34245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    const ModuleList &target_images = m_process->GetTarget().GetImages();
34345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    ModuleSpec module_spec (image_info.file_spec, image_info.GetArchitecture ());
34445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    module_spec.GetUUID() = image_info.uuid;
34545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    ModuleSP module_sp (target_images.FindFirstModule (module_spec));
34645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
34745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (module_sp && !module_spec.GetUUID().IsValid() && !module_sp->GetUUID().IsValid())
34845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    {
34945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        // No UUID, we must rely upon the cached module modification
35045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        // time and the modification time of the file on disk
35145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if (module_sp->GetModificationTime() != module_sp->GetFileSpec().GetModificationTime())
35245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            module_sp.reset();
35345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
35445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
35545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (!module_sp)
35645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    {
35745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if (can_create)
35845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        {
35945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            module_sp = m_process->GetTarget().GetSharedModule (module_spec);
36045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            if (!module_sp || module_sp->GetObjectFile() == NULL)
36145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            {
36245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                const bool add_image_to_target = true;
36345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                const bool load_image_sections_in_target = false;
36445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                module_sp = m_process->ReadModuleFromMemory (image_info.file_spec,
365a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org                                                             image_info.address,
36645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                                             add_image_to_target,
36745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                                             load_image_sections_in_target);
36845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            }
36945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
37045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            if (did_create_ptr)
37145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                *did_create_ptr = (bool) module_sp;
37245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        }
37345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
37445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return module_sp;
37545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
37645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
37745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org//----------------------------------------------------------------------
37845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org// Assume that dyld is in memory at ADDR and try to parse it's load
37945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org// commands
38045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org//----------------------------------------------------------------------
38145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgbool
38245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgDynamicLoaderMacOSXDYLD::ReadDYLDInfoFromMemoryAndSetNotificationCallback(lldb::addr_t addr)
38345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
38445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    DataExtractor data; // Load command data
38545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (ReadMachHeader (addr, &m_dyld.header, &data))
38645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    {
38745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if (m_dyld.header.filetype == llvm::MachO::HeaderFileTypeDynamicLinkEditor)
38845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        {
38945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            m_dyld.address = addr;
39045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            ModuleSP dyld_module_sp;
39145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            if (ParseLoadCommands (data, m_dyld, &m_dyld.file_spec))
39245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            {
39345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                if (m_dyld.file_spec)
39445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                {
39545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    dyld_module_sp = FindTargetModuleForDYLDImageInfo (m_dyld, true, NULL);
39645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
39745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    if (dyld_module_sp)
39845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                        UpdateImageLoadAddress (dyld_module_sp.get(), m_dyld);
39945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                }
40045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            }
40145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
40245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            if (m_dyld_all_image_infos_addr == LLDB_INVALID_ADDRESS && dyld_module_sp.get())
40345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            {
40445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                static ConstString g_dyld_all_image_infos ("dyld_all_image_infos");
40545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                const Symbol *symbol = dyld_module_sp->FindFirstSymbolWithNameAndType (g_dyld_all_image_infos, eSymbolTypeData);
40645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                if (symbol)
40745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    m_dyld_all_image_infos_addr = symbol->GetAddress().GetLoadAddress(&m_process->GetTarget());
40845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            }
40945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
41045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            // Update all image infos
41145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            InitializeFromAllImageInfos ();
41245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
41345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            // If we didn't have an executable before, but now we do, then the
41445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            // dyld module shared pointer might be unique and we may need to add
41545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            // it again (since Target::SetExecutableModule() will clear the
41645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            // images). So append the dyld module back to the list if it is
41745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            /// unique!
418a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org            if (dyld_module_sp)
419a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org            {
420a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org                if (m_process->GetTarget().GetImages().AppendIfNeeded (dyld_module_sp))
421a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org                    UpdateImageLoadAddress(dyld_module_sp.get(), m_dyld);
422a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org
423a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org                // At this point we should have read in dyld's module, and so we should set breakpoints in it:
424a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org                ModuleList modules;
425a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org                modules.Append(dyld_module_sp);
426a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org                m_process->GetTarget().ModulesDidLoad(modules);
427a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org            }
428a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org            return true;
429a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org        }
430a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org    }
431a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org    return false;
43245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
433a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org
43445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgbool
43545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgDynamicLoaderMacOSXDYLD::NeedToLocateDYLD () const
43645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
43745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return m_dyld_all_image_infos_addr == LLDB_INVALID_ADDRESS;
43845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
43945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
44045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgbool
44145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgDynamicLoaderMacOSXDYLD::UpdateCommPageLoadAddress(Module *module)
44245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
44345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    bool changed = false;
44445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (module)
44545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    {
44645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        ObjectFile *image_object_file = module->GetObjectFile();
44745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if (image_object_file)
44845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        {
44945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            SectionList *section_list = image_object_file->GetSectionList ();
45045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            if (section_list)
45145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            {
45245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                const size_t num_sections = section_list->GetSize();
45345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                for (size_t i=0; i<num_sections; ++i)
45445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                {
45545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    SectionSP section_sp (section_list->GetSectionAtIndex (i));
45645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    if (section_sp)
45745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    {
45845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                        const addr_t new_section_load_addr = section_sp->GetFileAddress ();
45945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                        const addr_t old_section_load_addr = m_process->GetTarget().GetSectionLoadList().GetSectionLoadAddress (section_sp);
46045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                        if (old_section_load_addr == LLDB_INVALID_ADDRESS ||
46145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                            old_section_load_addr != new_section_load_addr)
46245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                        {
46345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                            if (m_process->GetTarget().GetSectionLoadList().SetSectionLoadAddress (section_sp, section_sp->GetFileAddress ()))
46445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                changed = true;
46545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                        }
46645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    }
46745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                }
46845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            }
46945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        }
47045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
47145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return changed;
47245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
47345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
47445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org//----------------------------------------------------------------------
47545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org// Update the load addresses for all segments in MODULE using the
47645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org// updated INFO that is passed in.
47745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org//----------------------------------------------------------------------
47845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgbool
47945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgDynamicLoaderMacOSXDYLD::UpdateImageLoadAddress (Module *module, DYLDImageInfo& info)
48045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
481a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org    bool changed = false;
48245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (module)
48345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    {
48445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        ObjectFile *image_object_file = module->GetObjectFile();
48545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if (image_object_file)
48645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        {
48745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            SectionList *section_list = image_object_file->GetSectionList ();
48845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            if (section_list)
48945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            {
49045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                std::vector<uint32_t> inaccessible_segment_indexes;
49145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                // We now know the slide amount, so go through all sections
49245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                // and update the load addresses with the correct values.
49345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                const size_t num_segments = info.segments.size();
49445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                for (size_t i=0; i<num_segments; ++i)
49545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                {
49645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    // Only load a segment if it has protections. Things like
49745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    // __PAGEZERO don't have any protections, and they shouldn't
498a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org                    // be slid
499a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org                    SectionSP section_sp(section_list->FindSectionByName(info.segments[i].name));
500a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org
501a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org                    if (info.segments[i].maxprot == 0)
502a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org                    {
50345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                        inaccessible_segment_indexes.push_back(i);
50445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    }
50545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    else
506a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org                    {
50745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                        const addr_t new_section_load_addr = info.segments[i].vmaddr + info.slide;
50845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                        static ConstString g_section_name_LINKEDIT ("__LINKEDIT");
509a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org
51045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                        if (section_sp)
51145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                        {
512a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org                            // __LINKEDIT sections from files in the shared cache
51345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                            // can overlap so check to see what the segment name is
51445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                            // and pass "false" so we don't warn of overlapping
515a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org                            // "Section" objects, and "true" for all other sections.
51645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                            const bool warn_multiple = section_sp->GetName() != g_section_name_LINKEDIT;
51745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
518a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org                            const addr_t old_section_load_addr = m_process->GetTarget().GetSectionLoadList().GetSectionLoadAddress (section_sp);
51945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                            if (old_section_load_addr == LLDB_INVALID_ADDRESS ||
52045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                old_section_load_addr != new_section_load_addr)
52145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                            {
522a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org                                if (m_process->GetTarget().GetSectionLoadList().SetSectionLoadAddress (section_sp, new_section_load_addr, warn_multiple))
52345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                    changed = true;
52445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                            }
52545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                        }
526a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org                        else
52745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                        {
52845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                            Host::SystemLog (Host::eSystemLogWarning,
529a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org                                             "warning: unable to find and load segment named '%s' at 0x%" PRIx64 " in '%s/%s' in macosx dynamic loader plug-in.\n",
53045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                             info.segments[i].name.AsCString("<invalid>"),
53145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                             (uint64_t)new_section_load_addr,
53245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                             image_object_file->GetFileSpec().GetDirectory().AsCString(),
53345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                             image_object_file->GetFileSpec().GetFilename().AsCString());
534a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org                        }
535a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org                    }
536a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org                }
537a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org
538a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org                // If the loaded the file (it changed) and we have segments that
539a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org                // are not readable or writeable, add them to the invalid memory
54045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                // region cache for the process. This will typically only be
54145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                // the __PAGEZERO segment in the main executable. We might be able
542a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org                // to apply this more generally to more sections that have no
54345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                // protections in the future, but for now we are going to just
54445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                // do __PAGEZERO.
54545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                if (changed && !inaccessible_segment_indexes.empty())
54645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                {
54745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    for (uint32_t i=0; i<inaccessible_segment_indexes.size(); ++i)
54845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    {
54945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                        const uint32_t seg_idx = inaccessible_segment_indexes[i];
55045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                        SectionSP section_sp(section_list->FindSectionByName(info.segments[seg_idx].name));
55145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
55245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                        if (section_sp)
55345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                        {
55445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                            static ConstString g_pagezero_section_name("__PAGEZERO");
55545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                            if (g_pagezero_section_name == section_sp->GetName())
556a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org                            {
55745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                // __PAGEZERO never slides...
558a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org                                const lldb::addr_t vmaddr = info.segments[seg_idx].vmaddr;
559a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org                                const lldb::addr_t vmsize = info.segments[seg_idx].vmsize;
56045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                Process::LoadRange pagezero_range (vmaddr, vmsize);
56145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                m_process->AddInvalidMemoryRegion(pagezero_range);
562a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org                            }
56345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                        }
56445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    }
56545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                }
56645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            }
56745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        }
56845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
56945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return changed;
57045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
57145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
57245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org//----------------------------------------------------------------------
57345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org// Update the load addresses for all segments in MODULE using the
57445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org// updated INFO that is passed in.
57545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org//----------------------------------------------------------------------
57645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgbool
57745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgDynamicLoaderMacOSXDYLD::UnloadImageLoadAddress (Module *module, DYLDImageInfo& info)
57845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
579a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org    bool changed = false;
580a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org    if (module)
58145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    {
58245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        ObjectFile *image_object_file = module->GetObjectFile();
583a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org        if (image_object_file)
58445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        {
58545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            SectionList *section_list = image_object_file->GetSectionList ();
586a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org            if (section_list)
58745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            {
58845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                const size_t num_segments = info.segments.size();
589a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org                for (size_t i=0; i<num_segments; ++i)
59045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                {
59145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    SectionSP section_sp(section_list->FindSectionByName(info.segments[i].name));
592a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org                    if (section_sp)
59345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    {
59445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                        const addr_t old_section_load_addr = info.segments[i].vmaddr + info.slide;
595a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org                        if (m_process->GetTarget().GetSectionLoadList().SetSectionUnloaded (section_sp, old_section_load_addr))
59645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                            changed = true;
59745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    }
59845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    else
59945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    {
600a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org                        Host::SystemLog (Host::eSystemLogWarning,
60145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                         "warning: unable to find and unload segment named '%s' in '%s/%s' in macosx dynamic loader plug-in.\n",
60245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                         info.segments[i].name.AsCString("<invalid>"),
603a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org                                         image_object_file->GetFileSpec().GetDirectory().AsCString(),
604a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org                                         image_object_file->GetFileSpec().GetFilename().AsCString());
605a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org                    }
60645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                }
60745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            }
608a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org        }
60945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
61045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return changed;
611a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org}
61245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
61345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
614a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org//----------------------------------------------------------------------
61545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org// Static callback function that gets called when our DYLD notification
61645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org// breakpoint gets hit. We update all of our image infos and then
617a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org// let our super class DynamicLoader class decide if we should stop
61845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org// or not (based on global preference).
61945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org//----------------------------------------------------------------------
620a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.orgbool
62145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgDynamicLoaderMacOSXDYLD::NotifyBreakpointHit (void *baton,
62245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                              StoppointCallbackContext *context,
623a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org                                              lldb::user_id_t break_id,
62445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                              lldb::user_id_t break_loc_id)
62545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
62645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    // Let the event know that the images have changed
62745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    // DYLD passes three arguments to the notification breakpoint.
62845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    // Arg1: enum dyld_image_mode mode - 0 = adding, 1 = removing
62945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    // Arg2: uint32_t infoCount        - Number of shared libraries added
630a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org    // Arg3: dyld_image_info info[]    - Array of structs of the form:
631a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org    //                                     const struct mach_header *imageLoadAddress
63245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    //                                     const char               *imageFilePath
63345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    //                                     uintptr_t                 imageFileModDate (a time_t)
63445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
63545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    DynamicLoaderMacOSXDYLD* dyld_instance = (DynamicLoaderMacOSXDYLD*) baton;
63645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
63745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    // First step is to see if we've already initialized the all image infos.  If we haven't then this function
63845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    // will do so and return true.  In the course of initializing the all_image_infos it will read the complete
63945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    // current state, so we don't need to figure out what has changed from the data passed in to us.
64045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
64145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (dyld_instance->InitializeFromAllImageInfos())
64245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return dyld_instance->GetStopWhenImagesChange();
64345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
64445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    ExecutionContext exe_ctx (context->exe_ctx_ref);
645a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org    Process *process = exe_ctx.GetProcessPtr();
646a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org    const lldb::ABISP &abi = process->GetABI();
647a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org    if (abi)
648a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org    {
649a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org        // Build up the value array to store the three arguments given above, then get the values from the ABI:
650a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org
65145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        ClangASTContext *clang_ast_context = process->GetTarget().GetScratchClangASTContext();
65245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        ValueList argument_values;
65345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        Value input_value;
65445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
65545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        void *clang_void_ptr_type = clang_ast_context->GetVoidPtrType(false);
65645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        void *clang_uint32_type   = clang_ast_context->GetBuiltinTypeForEncodingAndBitSize(lldb::eEncodingUint, 32);
65745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        input_value.SetValueType (Value::eValueTypeScalar);
65845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        input_value.SetContext (Value::eContextTypeClangType, clang_uint32_type);
65945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        argument_values.PushValue(input_value);
66045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        argument_values.PushValue(input_value);
66145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        input_value.SetContext (Value::eContextTypeClangType, clang_void_ptr_type);
66245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        argument_values.PushValue (input_value);
66345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
66445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if (abi->GetArgumentValues (exe_ctx.GetThreadRef(), argument_values))
66545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        {
66645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            uint32_t dyld_mode = argument_values.GetValueAtIndex(0)->GetScalar().UInt (-1);
667            if (dyld_mode != -1)
668            {
669                // Okay the mode was right, now get the number of elements, and the array of new elements...
670                uint32_t image_infos_count = argument_values.GetValueAtIndex(1)->GetScalar().UInt (-1);
671                if (image_infos_count != -1)
672                {
673                    // Got the number added, now go through the array of added elements, putting out the mach header
674                    // address, and adding the image.
675                    // Note, I'm not putting in logging here, since the AddModules & RemoveModules functions do
676                    // all the logging internally.
677
678                    lldb::addr_t image_infos_addr = argument_values.GetValueAtIndex(2)->GetScalar().ULongLong();
679                    if (dyld_mode == 0)
680                    {
681                        // This is add:
682                        dyld_instance->AddModulesUsingImageInfosAddress (image_infos_addr, image_infos_count);
683                    }
684                    else
685                    {
686                        // This is remove:
687                        dyld_instance->RemoveModulesUsingImageInfosAddress (image_infos_addr, image_infos_count);
688                    }
689
690                }
691            }
692        }
693    }
694
695    // Return true to stop the target, false to just let the target run
696    return dyld_instance->GetStopWhenImagesChange();
697}
698
699bool
700DynamicLoaderMacOSXDYLD::ReadAllImageInfosStructure ()
701{
702    Mutex::Locker locker(m_mutex);
703
704    // the all image infos is already valid for this process stop ID
705    if (m_process->GetStopID() == m_dyld_all_image_infos_stop_id)
706        return true;
707
708    m_dyld_all_image_infos.Clear();
709    if (m_dyld_all_image_infos_addr != LLDB_INVALID_ADDRESS)
710    {
711        ByteOrder byte_order = m_process->GetTarget().GetArchitecture().GetByteOrder();
712        uint32_t addr_size = 4;
713        if (m_dyld_all_image_infos_addr > UINT32_MAX)
714            addr_size = 8;
715
716        uint8_t buf[256];
717        DataExtractor data (buf, sizeof(buf), byte_order, addr_size);
718        lldb::offset_t offset = 0;
719
720        const size_t count_v2 =  sizeof (uint32_t) + // version
721                                 sizeof (uint32_t) + // infoArrayCount
722                                 addr_size +         // infoArray
723                                 addr_size +         // notification
724                                 addr_size +         // processDetachedFromSharedRegion + libSystemInitialized + pad
725                                 addr_size;          // dyldImageLoadAddress
726        const size_t count_v11 = count_v2 +
727                                 addr_size +         // jitInfo
728                                 addr_size +         // dyldVersion
729                                 addr_size +         // errorMessage
730                                 addr_size +         // terminationFlags
731                                 addr_size +         // coreSymbolicationShmPage
732                                 addr_size +         // systemOrderFlag
733                                 addr_size +         // uuidArrayCount
734                                 addr_size +         // uuidArray
735                                 addr_size +         // dyldAllImageInfosAddress
736                                 addr_size +         // initialImageCount
737                                 addr_size +         // errorKind
738                                 addr_size +         // errorClientOfDylibPath
739                                 addr_size +         // errorTargetDylibPath
740                                 addr_size;          // errorSymbol
741        assert (sizeof (buf) >= count_v11);
742
743        Error error;
744        if (m_process->ReadMemory (m_dyld_all_image_infos_addr, buf, 4, error) == 4)
745        {
746            m_dyld_all_image_infos.version = data.GetU32(&offset);
747            // If anything in the high byte is set, we probably got the byte
748            // order incorrect (the process might not have it set correctly
749            // yet due to attaching to a program without a specified file).
750            if (m_dyld_all_image_infos.version & 0xff000000)
751            {
752                // We have guessed the wrong byte order. Swap it and try
753                // reading the version again.
754                if (byte_order == eByteOrderLittle)
755                    byte_order = eByteOrderBig;
756                else
757                    byte_order = eByteOrderLittle;
758
759                data.SetByteOrder (byte_order);
760                offset = 0;
761                m_dyld_all_image_infos.version = data.GetU32(&offset);
762            }
763        }
764        else
765        {
766            return false;
767        }
768
769        const size_t count = (m_dyld_all_image_infos.version >= 11) ? count_v11 : count_v2;
770
771        const size_t bytes_read = m_process->ReadMemory (m_dyld_all_image_infos_addr, buf, count, error);
772        if (bytes_read == count)
773        {
774            offset = 0;
775            m_dyld_all_image_infos.version = data.GetU32(&offset);
776            m_dyld_all_image_infos.dylib_info_count = data.GetU32(&offset);
777            m_dyld_all_image_infos.dylib_info_addr = data.GetPointer(&offset);
778            m_dyld_all_image_infos.notification = data.GetPointer(&offset);
779            m_dyld_all_image_infos.processDetachedFromSharedRegion = data.GetU8(&offset);
780            m_dyld_all_image_infos.libSystemInitialized = data.GetU8(&offset);
781            // Adjust for padding.
782            offset += addr_size - 2;
783            m_dyld_all_image_infos.dyldImageLoadAddress = data.GetPointer(&offset);
784            if (m_dyld_all_image_infos.version >= 11)
785            {
786                offset += addr_size * 8;
787                uint64_t dyld_all_image_infos_addr = data.GetPointer(&offset);
788
789                // When we started, we were given the actual address of the all_image_infos
790                // struct (probably via TASK_DYLD_INFO) in memory - this address is stored in
791                // m_dyld_all_image_infos_addr and is the most accurate address we have.
792
793                // We read the dyld_all_image_infos struct from memory; it contains its own address.
794                // If the address in the struct does not match the actual address,
795                // the dyld we're looking at has been loaded at a different location (slid) from
796                // where it intended to load.  The addresses in the dyld_all_image_infos struct
797                // are the original, non-slid addresses, and need to be adjusted.  Most importantly
798                // the address of dyld and the notification address need to be adjusted.
799
800                if (dyld_all_image_infos_addr != m_dyld_all_image_infos_addr)
801                {
802                    uint64_t image_infos_offset = dyld_all_image_infos_addr - m_dyld_all_image_infos.dyldImageLoadAddress;
803                    uint64_t notification_offset = m_dyld_all_image_infos.notification - m_dyld_all_image_infos.dyldImageLoadAddress;
804                    m_dyld_all_image_infos.dyldImageLoadAddress = m_dyld_all_image_infos_addr - image_infos_offset;
805                    m_dyld_all_image_infos.notification = m_dyld_all_image_infos.dyldImageLoadAddress + notification_offset;
806                }
807            }
808            m_dyld_all_image_infos_stop_id = m_process->GetStopID();
809            return true;
810        }
811    }
812    return false;
813}
814
815
816bool
817DynamicLoaderMacOSXDYLD::AddModulesUsingImageInfosAddress (lldb::addr_t image_infos_addr, uint32_t image_infos_count)
818{
819    DYLDImageInfo::collection image_infos;
820    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
821    if (log)
822        log->Printf ("Adding %d modules.\n", image_infos_count);
823
824    Mutex::Locker locker(m_mutex);
825    if (m_process->GetStopID() == m_dyld_image_infos_stop_id)
826        return true;
827
828    if (!ReadImageInfos (image_infos_addr, image_infos_count, image_infos))
829        return false;
830
831    UpdateImageInfosHeaderAndLoadCommands (image_infos, image_infos_count, false);
832    bool return_value = AddModulesUsingImageInfos (image_infos);
833    m_dyld_image_infos_stop_id = m_process->GetStopID();
834    return return_value;
835}
836
837// Adds the modules in image_infos to m_dyld_image_infos.
838// NB don't call this passing in m_dyld_image_infos.
839
840bool
841DynamicLoaderMacOSXDYLD::AddModulesUsingImageInfos (DYLDImageInfo::collection &image_infos)
842{
843    // Now add these images to the main list.
844    ModuleList loaded_module_list;
845    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
846
847    for (uint32_t idx = 0; idx < image_infos.size(); ++idx)
848    {
849        if (log)
850        {
851            log->Printf ("Adding new image at address=0x%16.16" PRIx64 ".", image_infos[idx].address);
852            image_infos[idx].PutToLog (log.get());
853        }
854
855        m_dyld_image_infos.push_back(image_infos[idx]);
856
857        ModuleSP image_module_sp (FindTargetModuleForDYLDImageInfo (image_infos[idx], true, NULL));
858
859        if (image_module_sp)
860        {
861            if (image_infos[idx].header.filetype == llvm::MachO::HeaderFileTypeDynamicLinkEditor)
862                image_module_sp->SetIsDynamicLinkEditor (true);
863
864            ObjectFile *objfile = image_module_sp->GetObjectFile ();
865            if (objfile)
866            {
867                SectionList *sections = objfile->GetSectionList();
868                if (sections)
869                {
870                    ConstString commpage_dbstr("__commpage");
871                    Section *commpage_section = sections->FindSectionByName(commpage_dbstr).get();
872                    if (commpage_section)
873                    {
874                        const ModuleList& target_images = m_process->GetTarget().GetImages();
875                        ModuleSpec module_spec (objfile->GetFileSpec(), image_infos[idx].GetArchitecture ());
876                        module_spec.GetObjectName() = commpage_dbstr;
877                        ModuleSP commpage_image_module_sp(target_images.FindFirstModule (module_spec));
878                        if (!commpage_image_module_sp)
879                        {
880                            module_spec.SetObjectOffset (objfile->GetOffset() + commpage_section->GetFileOffset());
881                            commpage_image_module_sp  = m_process->GetTarget().GetSharedModule (module_spec);
882                            if (!commpage_image_module_sp || commpage_image_module_sp->GetObjectFile() == NULL)
883                            {
884                                const bool add_image_to_target = true;
885                                const bool load_image_sections_in_target = false;
886                                commpage_image_module_sp = m_process->ReadModuleFromMemory (image_infos[idx].file_spec,
887                                                                                            image_infos[idx].address,
888                                                                                            add_image_to_target,
889                                                                                            load_image_sections_in_target);
890                            }
891                        }
892                        if (commpage_image_module_sp)
893                            UpdateCommPageLoadAddress (commpage_image_module_sp.get());
894                    }
895                }
896            }
897
898            // UpdateImageLoadAddress will return true if any segments
899            // change load address. We need to check this so we don't
900            // mention that all loaded shared libraries are newly loaded
901            // each time we hit out dyld breakpoint since dyld will list all
902            // shared libraries each time.
903            if (UpdateImageLoadAddress (image_module_sp.get(), image_infos[idx]))
904            {
905                loaded_module_list.AppendIfNeeded (image_module_sp);
906            }
907        }
908    }
909
910    if (loaded_module_list.GetSize() > 0)
911    {
912        // FIXME: This should really be in the Runtime handlers class, which should get
913        // called by the target's ModulesDidLoad, but we're doing it all locally for now
914        // to save time.
915        // Also, I'm assuming there can be only one libobjc dylib loaded...
916
917        ObjCLanguageRuntime *objc_runtime = m_process->GetObjCLanguageRuntime(true);
918        if (objc_runtime != NULL && !objc_runtime->HasReadObjCLibrary())
919        {
920            size_t num_modules = loaded_module_list.GetSize();
921            for (int i = 0; i < num_modules; i++)
922            {
923                if (objc_runtime->IsModuleObjCLibrary (loaded_module_list.GetModuleAtIndex (i)))
924                {
925                    objc_runtime->ReadObjCLibrary (loaded_module_list.GetModuleAtIndex (i));
926                    break;
927                }
928            }
929        }
930        if (log)
931            loaded_module_list.LogUUIDAndPaths (log, "DynamicLoaderMacOSXDYLD::ModulesDidLoad");
932        m_process->GetTarget().ModulesDidLoad (loaded_module_list);
933    }
934    return true;
935}
936
937bool
938DynamicLoaderMacOSXDYLD::RemoveModulesUsingImageInfosAddress (lldb::addr_t image_infos_addr, uint32_t image_infos_count)
939{
940    DYLDImageInfo::collection image_infos;
941    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
942
943    Mutex::Locker locker(m_mutex);
944    if (m_process->GetStopID() == m_dyld_image_infos_stop_id)
945        return true;
946
947    // First read in the image_infos for the removed modules, and their headers & load commands.
948    if (!ReadImageInfos (image_infos_addr, image_infos_count, image_infos))
949    {
950        if (log)
951            log->PutCString ("Failed reading image infos array.");
952        return false;
953    }
954
955    if (log)
956        log->Printf ("Removing %d modules.", image_infos_count);
957
958    ModuleList unloaded_module_list;
959    for (uint32_t idx = 0; idx < image_infos.size(); ++idx)
960    {
961        if (log)
962        {
963            log->Printf ("Removing module at address=0x%16.16" PRIx64 ".", image_infos[idx].address);
964            image_infos[idx].PutToLog (log.get());
965        }
966
967        // Remove this image_infos from the m_all_image_infos.  We do the comparision by address
968        // rather than by file spec because we can have many modules with the same "file spec" in the
969        // case that they are modules loaded from memory.
970        //
971        // Also copy over the uuid from the old entry to the removed entry so we can
972        // use it to lookup the module in the module list.
973
974        DYLDImageInfo::collection::iterator pos, end = m_dyld_image_infos.end();
975        for (pos = m_dyld_image_infos.begin(); pos != end; pos++)
976        {
977            if (image_infos[idx].address == (*pos).address)
978            {
979                image_infos[idx].uuid = (*pos).uuid;
980
981                // Add the module from this image_info to the "unloaded_module_list".  We'll remove them all at
982                // one go later on.
983
984                ModuleSP unload_image_module_sp (FindTargetModuleForDYLDImageInfo (image_infos[idx], false, NULL));
985                if (unload_image_module_sp.get())
986                {
987                    // When we unload, be sure to use the image info from the old list,
988                    // since that has sections correctly filled in.
989                    UnloadImageLoadAddress (unload_image_module_sp.get(), *pos);
990                    unloaded_module_list.AppendIfNeeded (unload_image_module_sp);
991                }
992                else
993                {
994                    if (log)
995                    {
996                        log->Printf ("Could not find module for unloading info entry:");
997                        image_infos[idx].PutToLog(log.get());
998                    }
999                }
1000
1001                // Then remove it from the m_dyld_image_infos:
1002
1003                m_dyld_image_infos.erase(pos);
1004                break;
1005            }
1006        }
1007
1008        if (pos == end)
1009        {
1010            if (log)
1011            {
1012                log->Printf ("Could not find image_info entry for unloading image:");
1013                image_infos[idx].PutToLog(log.get());
1014            }
1015        }
1016    }
1017    if (unloaded_module_list.GetSize() > 0)
1018    {
1019        if (log)
1020        {
1021            log->PutCString("Unloaded:");
1022            unloaded_module_list.LogUUIDAndPaths (log, "DynamicLoaderMacOSXDYLD::ModulesDidUnload");
1023        }
1024        m_process->GetTarget().GetImages().Remove (unloaded_module_list);
1025    }
1026    m_dyld_image_infos_stop_id = m_process->GetStopID();
1027    return true;
1028}
1029
1030bool
1031DynamicLoaderMacOSXDYLD::ReadImageInfos (lldb::addr_t image_infos_addr,
1032                                         uint32_t image_infos_count,
1033                                         DYLDImageInfo::collection &image_infos)
1034{
1035    const ByteOrder endian = m_dyld.GetByteOrder();
1036    const uint32_t addr_size = m_dyld.GetAddressByteSize();
1037
1038    image_infos.resize(image_infos_count);
1039    const size_t count = image_infos.size() * 3 * addr_size;
1040    DataBufferHeap info_data(count, 0);
1041    Error error;
1042    const size_t bytes_read = m_process->ReadMemory (image_infos_addr,
1043                                                     info_data.GetBytes(),
1044                                                     info_data.GetByteSize(),
1045                                                     error);
1046    if (bytes_read == count)
1047    {
1048        lldb::offset_t info_data_offset = 0;
1049        DataExtractor info_data_ref(info_data.GetBytes(), info_data.GetByteSize(), endian, addr_size);
1050        for (int i = 0; i < image_infos.size() && info_data_ref.ValidOffset(info_data_offset); i++)
1051        {
1052            image_infos[i].address = info_data_ref.GetPointer(&info_data_offset);
1053            lldb::addr_t path_addr = info_data_ref.GetPointer(&info_data_offset);
1054            image_infos[i].mod_date = info_data_ref.GetPointer(&info_data_offset);
1055
1056            char raw_path[PATH_MAX];
1057            m_process->ReadCStringFromMemory (path_addr, raw_path, sizeof(raw_path), error);
1058            // don't resolve the path
1059            if (error.Success())
1060            {
1061                const bool resolve_path = false;
1062                image_infos[i].file_spec.SetFile(raw_path, resolve_path);
1063            }
1064        }
1065        return true;
1066    }
1067    else
1068    {
1069        return false;
1070    }
1071}
1072
1073//----------------------------------------------------------------------
1074// If we have found where the "_dyld_all_image_infos" lives in memory,
1075// read the current info from it, and then update all image load
1076// addresses (or lack thereof).  Only do this if this is the first time
1077// we're reading the dyld infos.  Return true if we actually read anything,
1078// and false otherwise.
1079//----------------------------------------------------------------------
1080bool
1081DynamicLoaderMacOSXDYLD::InitializeFromAllImageInfos ()
1082{
1083    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
1084
1085    Mutex::Locker locker(m_mutex);
1086    if (m_process->GetStopID() == m_dyld_image_infos_stop_id
1087          || m_dyld_image_infos.size() != 0)
1088        return false;
1089
1090    if (ReadAllImageInfosStructure ())
1091    {
1092        // Nothing to load or unload?
1093        if (m_dyld_all_image_infos.dylib_info_count == 0)
1094            return true;
1095
1096        if (m_dyld_all_image_infos.dylib_info_addr == 0)
1097        {
1098            // DYLD is updating the images now.  So we should say we have no images, and then we'll
1099            // figure it out when we hit the added breakpoint.
1100            return false;
1101        }
1102        else
1103        {
1104            if (!AddModulesUsingImageInfosAddress (m_dyld_all_image_infos.dylib_info_addr,
1105                                                   m_dyld_all_image_infos.dylib_info_count))
1106            {
1107                DEBUG_PRINTF("%s", "unable to read all data for all_dylib_infos.");
1108                m_dyld_image_infos.clear();
1109            }
1110        }
1111
1112        // Now we have one more bit of business.  If there is a library left in the images for our target that
1113        // doesn't have a load address, then it must be something that we were expecting to load (for instance we
1114        // read a load command for it) but it didn't in fact load - probably because DYLD_*_PATH pointed
1115        // to an equivalent version.  We don't want it to stay in the target's module list or it will confuse
1116        // us, so unload it here.
1117        Target &target = m_process->GetTarget();
1118        const ModuleList &target_modules = target.GetImages();
1119        ModuleList not_loaded_modules;
1120        Mutex::Locker modules_locker(target_modules.GetMutex());
1121
1122        size_t num_modules = target_modules.GetSize();
1123        for (size_t i = 0; i < num_modules; i++)
1124        {
1125            ModuleSP module_sp = target_modules.GetModuleAtIndexUnlocked (i);
1126            if (!module_sp->IsLoadedInTarget (&target))
1127            {
1128                if (log)
1129                {
1130                    StreamString s;
1131                    module_sp->GetDescription (&s);
1132                    log->Printf ("Unloading pre-run module: %s.", s.GetData ());
1133                }
1134                not_loaded_modules.Append (module_sp);
1135            }
1136        }
1137
1138        if (not_loaded_modules.GetSize() != 0)
1139        {
1140            target.GetImages().Remove(not_loaded_modules);
1141        }
1142
1143        return true;
1144    }
1145    else
1146        return false;
1147}
1148
1149//----------------------------------------------------------------------
1150// Read a mach_header at ADDR into HEADER, and also fill in the load
1151// command data into LOAD_COMMAND_DATA if it is non-NULL.
1152//
1153// Returns true if we succeed, false if we fail for any reason.
1154//----------------------------------------------------------------------
1155bool
1156DynamicLoaderMacOSXDYLD::ReadMachHeader (lldb::addr_t addr, llvm::MachO::mach_header *header, DataExtractor *load_command_data)
1157{
1158    DataBufferHeap header_bytes(sizeof(llvm::MachO::mach_header), 0);
1159    Error error;
1160    size_t bytes_read = m_process->ReadMemory (addr,
1161                                               header_bytes.GetBytes(),
1162                                               header_bytes.GetByteSize(),
1163                                               error);
1164    if (bytes_read == sizeof(llvm::MachO::mach_header))
1165    {
1166        lldb::offset_t offset = 0;
1167        ::memset (header, 0, sizeof(llvm::MachO::mach_header));
1168
1169        // Get the magic byte unswapped so we can figure out what we are dealing with
1170        DataExtractor data(header_bytes.GetBytes(), header_bytes.GetByteSize(), lldb::endian::InlHostByteOrder(), 4);
1171        header->magic = data.GetU32(&offset);
1172        lldb::addr_t load_cmd_addr = addr;
1173        data.SetByteOrder(DynamicLoaderMacOSXDYLD::GetByteOrderFromMagic(header->magic));
1174        switch (header->magic)
1175        {
1176        case llvm::MachO::HeaderMagic32:
1177        case llvm::MachO::HeaderMagic32Swapped:
1178            data.SetAddressByteSize(4);
1179            load_cmd_addr += sizeof(llvm::MachO::mach_header);
1180            break;
1181
1182        case llvm::MachO::HeaderMagic64:
1183        case llvm::MachO::HeaderMagic64Swapped:
1184            data.SetAddressByteSize(8);
1185            load_cmd_addr += sizeof(llvm::MachO::mach_header_64);
1186            break;
1187
1188        default:
1189            return false;
1190        }
1191
1192        // Read the rest of dyld's mach header
1193        if (data.GetU32(&offset, &header->cputype, (sizeof(llvm::MachO::mach_header)/sizeof(uint32_t)) - 1))
1194        {
1195            if (load_command_data == NULL)
1196                return true; // We were able to read the mach_header and weren't asked to read the load command bytes
1197
1198            DataBufferSP load_cmd_data_sp(new DataBufferHeap(header->sizeofcmds, 0));
1199
1200            size_t load_cmd_bytes_read = m_process->ReadMemory (load_cmd_addr,
1201                                                                load_cmd_data_sp->GetBytes(),
1202                                                                load_cmd_data_sp->GetByteSize(),
1203                                                                error);
1204
1205            if (load_cmd_bytes_read == header->sizeofcmds)
1206            {
1207                // Set the load command data and also set the correct endian
1208                // swap settings and the correct address size
1209                load_command_data->SetData(load_cmd_data_sp, 0, header->sizeofcmds);
1210                load_command_data->SetByteOrder(data.GetByteOrder());
1211                load_command_data->SetAddressByteSize(data.GetAddressByteSize());
1212                return true; // We successfully read the mach_header and the load command data
1213            }
1214
1215            return false; // We weren't able to read the load command data
1216        }
1217    }
1218    return false; // We failed the read the mach_header
1219}
1220
1221
1222//----------------------------------------------------------------------
1223// Parse the load commands for an image
1224//----------------------------------------------------------------------
1225uint32_t
1226DynamicLoaderMacOSXDYLD::ParseLoadCommands (const DataExtractor& data, DYLDImageInfo& dylib_info, FileSpec *lc_id_dylinker)
1227{
1228    lldb::offset_t offset = 0;
1229    uint32_t cmd_idx;
1230    Segment segment;
1231    dylib_info.Clear (true);
1232
1233    for (cmd_idx = 0; cmd_idx < dylib_info.header.ncmds; cmd_idx++)
1234    {
1235        // Clear out any load command specific data from DYLIB_INFO since
1236        // we are about to read it.
1237
1238        if (data.ValidOffsetForDataOfSize (offset, sizeof(llvm::MachO::load_command)))
1239        {
1240            llvm::MachO::load_command load_cmd;
1241            lldb::offset_t load_cmd_offset = offset;
1242            load_cmd.cmd = data.GetU32 (&offset);
1243            load_cmd.cmdsize = data.GetU32 (&offset);
1244            switch (load_cmd.cmd)
1245            {
1246            case llvm::MachO::LoadCommandSegment32:
1247                {
1248                    segment.name.SetTrimmedCStringWithLength ((const char *)data.GetData(&offset, 16), 16);
1249                    // We are putting 4 uint32_t values 4 uint64_t values so
1250                    // we have to use multiple 32 bit gets below.
1251                    segment.vmaddr = data.GetU32 (&offset);
1252                    segment.vmsize = data.GetU32 (&offset);
1253                    segment.fileoff = data.GetU32 (&offset);
1254                    segment.filesize = data.GetU32 (&offset);
1255                    // Extract maxprot, initprot, nsects and flags all at once
1256                    data.GetU32(&offset, &segment.maxprot, 4);
1257                    dylib_info.segments.push_back (segment);
1258                }
1259                break;
1260
1261            case llvm::MachO::LoadCommandSegment64:
1262                {
1263                    segment.name.SetTrimmedCStringWithLength ((const char *)data.GetData(&offset, 16), 16);
1264                    // Extract vmaddr, vmsize, fileoff, and filesize all at once
1265                    data.GetU64(&offset, &segment.vmaddr, 4);
1266                    // Extract maxprot, initprot, nsects and flags all at once
1267                    data.GetU32(&offset, &segment.maxprot, 4);
1268                    dylib_info.segments.push_back (segment);
1269                }
1270                break;
1271
1272            case llvm::MachO::LoadCommandDynamicLinkerIdent:
1273                if (lc_id_dylinker)
1274                {
1275                    const lldb::offset_t name_offset = load_cmd_offset + data.GetU32 (&offset);
1276                    const char *path = data.PeekCStr (name_offset);
1277                    lc_id_dylinker->SetFile (path, true);
1278                }
1279                break;
1280
1281            case llvm::MachO::LoadCommandUUID:
1282                dylib_info.uuid.SetBytes(data.GetData (&offset, 16));
1283                break;
1284
1285            default:
1286                break;
1287            }
1288            // Set offset to be the beginning of the next load command.
1289            offset = load_cmd_offset + load_cmd.cmdsize;
1290        }
1291    }
1292
1293    // All sections listed in the dyld image info structure will all
1294    // either be fixed up already, or they will all be off by a single
1295    // slide amount that is determined by finding the first segment
1296    // that is at file offset zero which also has bytes (a file size
1297    // that is greater than zero) in the object file.
1298
1299    // Determine the slide amount (if any)
1300    const size_t num_sections = dylib_info.segments.size();
1301    for (size_t i = 0; i < num_sections; ++i)
1302    {
1303        // Iterate through the object file sections to find the
1304        // first section that starts of file offset zero and that
1305        // has bytes in the file...
1306        if (dylib_info.segments[i].fileoff == 0 && dylib_info.segments[i].filesize > 0)
1307        {
1308            dylib_info.slide = dylib_info.address - dylib_info.segments[i].vmaddr;
1309            // We have found the slide amount, so we can exit
1310            // this for loop.
1311            break;
1312        }
1313    }
1314    return cmd_idx;
1315}
1316
1317//----------------------------------------------------------------------
1318// Read the mach_header and load commands for each image that the
1319// _dyld_all_image_infos structure points to and cache the results.
1320//----------------------------------------------------------------------
1321
1322void
1323DynamicLoaderMacOSXDYLD::UpdateImageInfosHeaderAndLoadCommands(DYLDImageInfo::collection &image_infos,
1324                                                               uint32_t infos_count,
1325                                                               bool update_executable)
1326{
1327    uint32_t exe_idx = UINT32_MAX;
1328    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
1329    // Read any UUID values that we can get
1330    for (uint32_t i = 0; i < infos_count; i++)
1331    {
1332        if (!image_infos[i].UUIDValid())
1333        {
1334            DataExtractor data; // Load command data
1335            if (!ReadMachHeader (image_infos[i].address, &image_infos[i].header, &data))
1336                continue;
1337
1338            ParseLoadCommands (data, image_infos[i], NULL);
1339
1340            if (image_infos[i].header.filetype == llvm::MachO::HeaderFileTypeExecutable)
1341                exe_idx = i;
1342
1343        }
1344    }
1345
1346    if (exe_idx < image_infos.size())
1347    {
1348        const bool can_create = true;
1349        ModuleSP exe_module_sp (FindTargetModuleForDYLDImageInfo (image_infos[exe_idx], can_create, NULL));
1350
1351        if (!exe_module_sp)
1352        {
1353            ArchSpec exe_arch_spec (image_infos[exe_idx].GetArchitecture ());
1354            ModuleSpec module_spec (image_infos[exe_idx].file_spec,
1355                                    image_infos[exe_idx].GetArchitecture ());
1356            module_spec.GetUUID() = image_infos[exe_idx].uuid;
1357            exe_module_sp = m_process->GetTarget().GetSharedModule (module_spec);
1358            if (!exe_module_sp || exe_module_sp->GetObjectFile() == NULL)
1359            {
1360                const bool add_image_to_target = true;
1361                const bool load_image_sections_in_target = false;
1362                exe_module_sp = m_process->ReadModuleFromMemory (image_infos[exe_idx].file_spec,
1363                                                                 image_infos[exe_idx].address,
1364                                                                 add_image_to_target,
1365                                                                 load_image_sections_in_target);
1366            }
1367        }
1368
1369        if (exe_module_sp)
1370        {
1371            if (exe_module_sp.get() != m_process->GetTarget().GetExecutableModulePointer())
1372            {
1373                // Don't load dependent images since we are in dyld where we will know
1374                // and find out about all images that are loaded
1375                const bool get_dependent_images = false;
1376                m_process->GetTarget().SetExecutableModule (exe_module_sp,
1377                                                            get_dependent_images);
1378            }
1379        }
1380    }
1381}
1382
1383//----------------------------------------------------------------------
1384// On Mac OS X libobjc (the Objective-C runtime) has several critical dispatch
1385// functions written in hand-written assembly, and also have hand-written unwind
1386// information in the eh_frame section.  Normally we prefer analyzing the
1387// assembly instructions of a curently executing frame to unwind from that frame --
1388// but on hand-written functions this profiling can fail.  We should use the
1389// eh_frame instructions for these functions all the time.
1390//
1391// As an aside, it would be better if the eh_frame entries had a flag (or were
1392// extensible so they could have an Apple-specific flag) which indicates that
1393// the instructions are asynchronous -- accurate at every instruction, instead
1394// of our normal default assumption that they are not.
1395//----------------------------------------------------------------------
1396
1397bool
1398DynamicLoaderMacOSXDYLD::AlwaysRelyOnEHUnwindInfo (SymbolContext &sym_ctx)
1399{
1400    ModuleSP module_sp;
1401    if (sym_ctx.symbol)
1402    {
1403        module_sp = sym_ctx.symbol->GetAddress().GetModule();
1404    }
1405    if (module_sp.get() == NULL && sym_ctx.function)
1406    {
1407        module_sp = sym_ctx.function->GetAddressRange().GetBaseAddress().GetModule();
1408    }
1409    if (module_sp.get() == NULL)
1410        return false;
1411
1412    ObjCLanguageRuntime *objc_runtime = m_process->GetObjCLanguageRuntime();
1413    if (objc_runtime != NULL && objc_runtime->IsModuleObjCLibrary (module_sp))
1414    {
1415        return true;
1416    }
1417
1418    return false;
1419}
1420
1421
1422
1423//----------------------------------------------------------------------
1424// Dump a Segment to the file handle provided.
1425//----------------------------------------------------------------------
1426void
1427DynamicLoaderMacOSXDYLD::Segment::PutToLog (Log *log, lldb::addr_t slide) const
1428{
1429    if (log)
1430    {
1431        if (slide == 0)
1432            log->Printf ("\t\t%16s [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ")",
1433                         name.AsCString(""),
1434                         vmaddr + slide,
1435                         vmaddr + slide + vmsize);
1436        else
1437            log->Printf ("\t\t%16s [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ") slide = 0x%" PRIx64,
1438                         name.AsCString(""),
1439                         vmaddr + slide,
1440                         vmaddr + slide + vmsize,
1441                         slide);
1442    }
1443}
1444
1445const DynamicLoaderMacOSXDYLD::Segment *
1446DynamicLoaderMacOSXDYLD::DYLDImageInfo::FindSegment (const ConstString &name) const
1447{
1448    const size_t num_segments = segments.size();
1449    for (size_t i=0; i<num_segments; ++i)
1450    {
1451        if (segments[i].name == name)
1452            return &segments[i];
1453    }
1454    return NULL;
1455}
1456
1457
1458//----------------------------------------------------------------------
1459// Dump an image info structure to the file handle provided.
1460//----------------------------------------------------------------------
1461void
1462DynamicLoaderMacOSXDYLD::DYLDImageInfo::PutToLog (Log *log) const
1463{
1464    if (log == NULL)
1465        return;
1466    uint8_t *u = (uint8_t *)uuid.GetBytes();
1467
1468    if (address == LLDB_INVALID_ADDRESS)
1469    {
1470        if (u)
1471        {
1472            log->Printf("\t                           modtime=0x%8.8" PRIx64 " 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)",
1473                        mod_date,
1474                        u[ 0], u[ 1], u[ 2], u[ 3],
1475                        u[ 4], u[ 5], u[ 6], u[ 7],
1476                        u[ 8], u[ 9], u[10], u[11],
1477                        u[12], u[13], u[14], u[15],
1478                        file_spec.GetDirectory().AsCString(),
1479                        file_spec.GetFilename().AsCString());
1480        }
1481        else
1482            log->Printf("\t                           modtime=0x%8.8" PRIx64 " path='%s/%s' (UNLOADED)",
1483                        mod_date,
1484                        file_spec.GetDirectory().AsCString(),
1485                        file_spec.GetFilename().AsCString());
1486    }
1487    else
1488    {
1489        if (u)
1490        {
1491            log->Printf("\taddress=0x%16.16" PRIx64 " modtime=0x%8.8" PRIx64 " 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'",
1492                        address,
1493                        mod_date,
1494                        u[ 0], u[ 1], u[ 2], u[ 3],
1495                        u[ 4], u[ 5], u[ 6], u[ 7],
1496                        u[ 8], u[ 9], u[10], u[11],
1497                        u[12], u[13], u[14], u[15],
1498                        file_spec.GetDirectory().AsCString(),
1499                        file_spec.GetFilename().AsCString());
1500        }
1501        else
1502        {
1503            log->Printf("\taddress=0x%16.16" PRIx64 " modtime=0x%8.8" PRIx64 " path='%s/%s'",
1504                        address,
1505                        mod_date,
1506                        file_spec.GetDirectory().AsCString(),
1507                        file_spec.GetFilename().AsCString());
1508
1509        }
1510        for (uint32_t i=0; i<segments.size(); ++i)
1511            segments[i].PutToLog(log, slide);
1512    }
1513}
1514
1515//----------------------------------------------------------------------
1516// Dump the _dyld_all_image_infos members and all current image infos
1517// that we have parsed to the file handle provided.
1518//----------------------------------------------------------------------
1519void
1520DynamicLoaderMacOSXDYLD::PutToLog(Log *log) const
1521{
1522    if (log == NULL)
1523        return;
1524
1525    Mutex::Locker locker(m_mutex);
1526    log->Printf("dyld_all_image_infos = { version=%d, count=%d, addr=0x%8.8" PRIx64 ", notify=0x%8.8" PRIx64 " }",
1527                    m_dyld_all_image_infos.version,
1528                    m_dyld_all_image_infos.dylib_info_count,
1529                    (uint64_t)m_dyld_all_image_infos.dylib_info_addr,
1530                    (uint64_t)m_dyld_all_image_infos.notification);
1531    size_t i;
1532    const size_t count = m_dyld_image_infos.size();
1533    if (count > 0)
1534    {
1535        log->PutCString("Loaded:");
1536        for (i = 0; i<count; i++)
1537            m_dyld_image_infos[i].PutToLog(log);
1538    }
1539}
1540
1541void
1542DynamicLoaderMacOSXDYLD::PrivateInitialize(Process *process)
1543{
1544    DEBUG_PRINTF("DynamicLoaderMacOSXDYLD::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState()));
1545    Clear(true);
1546    m_process = process;
1547    m_process->GetTarget().GetSectionLoadList().Clear();
1548}
1549
1550bool
1551DynamicLoaderMacOSXDYLD::SetNotificationBreakpoint ()
1552{
1553    DEBUG_PRINTF("DynamicLoaderMacOSXDYLD::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState()));
1554    if (m_break_id == LLDB_INVALID_BREAK_ID)
1555    {
1556        if (m_dyld_all_image_infos.notification != LLDB_INVALID_ADDRESS)
1557        {
1558            Address so_addr;
1559            // Set the notification breakpoint and install a breakpoint
1560            // callback function that will get called each time the
1561            // breakpoint gets hit. We will use this to track when shared
1562            // libraries get loaded/unloaded.
1563
1564            if (m_process->GetTarget().GetSectionLoadList().ResolveLoadAddress(m_dyld_all_image_infos.notification, so_addr))
1565            {
1566                Breakpoint *dyld_break = m_process->GetTarget().CreateBreakpoint (so_addr, true).get();
1567                dyld_break->SetCallback (DynamicLoaderMacOSXDYLD::NotifyBreakpointHit, this, true);
1568                m_break_id = dyld_break->GetID();
1569            }
1570        }
1571    }
1572    return m_break_id != LLDB_INVALID_BREAK_ID;
1573}
1574
1575//----------------------------------------------------------------------
1576// Member function that gets called when the process state changes.
1577//----------------------------------------------------------------------
1578void
1579DynamicLoaderMacOSXDYLD::PrivateProcessStateChanged (Process *process, StateType state)
1580{
1581    DEBUG_PRINTF("DynamicLoaderMacOSXDYLD::%s(%s)\n", __FUNCTION__, StateAsCString(state));
1582    switch (state)
1583    {
1584    case eStateConnected:
1585    case eStateAttaching:
1586    case eStateLaunching:
1587    case eStateInvalid:
1588    case eStateUnloaded:
1589    case eStateExited:
1590    case eStateDetached:
1591        Clear(false);
1592        break;
1593
1594    case eStateStopped:
1595        // Keep trying find dyld and set our notification breakpoint each time
1596        // we stop until we succeed
1597        if (!DidSetNotificationBreakpoint () && m_process->IsAlive())
1598        {
1599            if (NeedToLocateDYLD ())
1600                LocateDYLD ();
1601
1602            SetNotificationBreakpoint ();
1603        }
1604        break;
1605
1606    case eStateRunning:
1607    case eStateStepping:
1608    case eStateCrashed:
1609    case eStateSuspended:
1610        break;
1611    }
1612}
1613
1614// This bit in the n_desc field of the mach file means that this is a
1615// stub that runs arbitrary code to determine the trampoline target.
1616// We've established a naming convention with the CoreOS folks for the
1617// equivalent symbols they will use for this (which the objc guys didn't follow...)
1618// For now we'll just look for all symbols matching that naming convention...
1619
1620#define MACH_O_N_SYMBOL_RESOLVER 0x100
1621
1622ThreadPlanSP
1623DynamicLoaderMacOSXDYLD::GetStepThroughTrampolinePlan (Thread &thread, bool stop_others)
1624{
1625    ThreadPlanSP thread_plan_sp;
1626    StackFrame *current_frame = thread.GetStackFrameAtIndex(0).get();
1627    const SymbolContext &current_context = current_frame->GetSymbolContext(eSymbolContextSymbol);
1628    Symbol *current_symbol = current_context.symbol;
1629    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
1630
1631    if (current_symbol != NULL)
1632    {
1633        if (current_symbol->IsTrampoline())
1634        {
1635            const ConstString &trampoline_name = current_symbol->GetMangled().GetName(Mangled::ePreferMangled);
1636
1637            if (trampoline_name)
1638            {
1639                SymbolContextList target_symbols;
1640                TargetSP target_sp (thread.CalculateTarget());
1641                const ModuleList &images = target_sp->GetImages();
1642
1643                images.FindSymbolsWithNameAndType(trampoline_name, eSymbolTypeCode, target_symbols);
1644
1645                size_t num_original_symbols = target_symbols.GetSize();
1646                // FIXME: The resolver symbol is only valid in object files.  In binaries it is reused for the
1647                // shared library slot number.  So we'll have to look this up in the dyld info.
1648                // For now, just turn this off.
1649
1650                // bool orig_is_resolver = (current_symbol->GetFlags() & MACH_O_N_SYMBOL_RESOLVER) == MACH_O_N_SYMBOL_RESOLVER;
1651                // FIXME: Actually that isn't true, the N_SYMBOL_RESOLVER bit is only valid in .o files.  You can't use
1652                // the symbol flags to tell whether something is a symbol resolver in a linked image.
1653                bool orig_is_resolver = false;
1654
1655                if (num_original_symbols > 0)
1656                {
1657                    // We found symbols that look like they are the targets to our symbol.  Now look through the
1658                    // modules containing our symbols to see if there are any for our symbol.
1659
1660                    ModuleList modules_to_search;
1661
1662                    for (size_t i = 0; i < num_original_symbols; i++)
1663                    {
1664                        SymbolContext sc;
1665                        target_symbols.GetContextAtIndex(i, sc);
1666
1667                        ModuleSP module_sp (sc.symbol->CalculateSymbolContextModule());
1668                        if (module_sp)
1669                             modules_to_search.AppendIfNeeded(module_sp);
1670                    }
1671
1672                    // If the original stub symbol is a resolver, then we don't want to break on the symbol with the
1673                    // original name, but instead on all the symbols it could resolve to since otherwise we would stop
1674                    // in the middle of the resolution...
1675                    // Note that the stub is not of the resolver type it will point to the equivalent symbol,
1676                    // not the original name, so in that case we don't need to do anything.
1677
1678                    if (orig_is_resolver)
1679                    {
1680                        target_symbols.Clear();
1681
1682                        FindEquivalentSymbols (current_symbol, modules_to_search, target_symbols);
1683                    }
1684
1685                    // FIXME - Make the Run to Address take multiple addresses, and
1686                    // run to any of them.
1687                    uint32_t num_symbols = target_symbols.GetSize();
1688                    if (num_symbols > 0)
1689                    {
1690                        std::vector<lldb::addr_t>  addresses;
1691                        addresses.resize (num_symbols);
1692                        for (uint32_t i = 0; i < num_symbols; i++)
1693                        {
1694                            SymbolContext context;
1695                            AddressRange addr_range;
1696                            if (target_symbols.GetContextAtIndex(i, context))
1697                            {
1698                                context.GetAddressRange (eSymbolContextEverything, 0, false, addr_range);
1699                                lldb::addr_t load_addr = addr_range.GetBaseAddress().GetLoadAddress(target_sp.get());
1700                                addresses[i] = load_addr;
1701                            }
1702                        }
1703                        if (addresses.size() > 0)
1704                            thread_plan_sp.reset (new ThreadPlanRunToAddress (thread, addresses, stop_others));
1705                        else
1706                        {
1707                            if (log)
1708                                log->Printf ("Couldn't resolve the symbol contexts.");
1709                        }
1710                    }
1711                    else
1712                    {
1713                        if (log)
1714                        {
1715                            log->Printf ("Found a resolver stub for: \"%s\" but could not find any symbols it resolves to.",
1716                                         trampoline_name.AsCString());
1717                        }
1718                    }
1719                }
1720                else
1721                {
1722                    if (log)
1723                    {
1724                        log->Printf ("Could not find symbol for trampoline target: \"%s\"", trampoline_name.AsCString());
1725                    }
1726                }
1727            }
1728        }
1729    }
1730    else
1731    {
1732        if (log)
1733            log->Printf ("Could not find symbol for step through.");
1734    }
1735
1736    return thread_plan_sp;
1737}
1738
1739size_t
1740DynamicLoaderMacOSXDYLD::FindEquivalentSymbols (lldb_private::Symbol *original_symbol,
1741                                               lldb_private::ModuleList &images,
1742                                               lldb_private::SymbolContextList &equivalent_symbols)
1743{
1744    const ConstString &trampoline_name = original_symbol->GetMangled().GetName(Mangled::ePreferMangled);
1745    if (!trampoline_name)
1746        return 0;
1747
1748    size_t initial_size = equivalent_symbols.GetSize();
1749
1750    static const char *resolver_name_regex = "(_gc|_non_gc|\\$[A-Z0-9]+)$";
1751    std::string equivalent_regex_buf("^");
1752    equivalent_regex_buf.append (trampoline_name.GetCString());
1753    equivalent_regex_buf.append (resolver_name_regex);
1754
1755    RegularExpression equivalent_name_regex (equivalent_regex_buf.c_str());
1756    const bool append = true;
1757    images.FindSymbolsMatchingRegExAndType (equivalent_name_regex, eSymbolTypeCode, equivalent_symbols, append);
1758
1759    return equivalent_symbols.GetSize() - initial_size;
1760}
1761
1762Error
1763DynamicLoaderMacOSXDYLD::CanLoadImage ()
1764{
1765    Error error;
1766    // In order for us to tell if we can load a shared library we verify that
1767    // the dylib_info_addr isn't zero (which means no shared libraries have
1768    // been set yet, or dyld is currently mucking with the shared library list).
1769    if (ReadAllImageInfosStructure ())
1770    {
1771        // TODO: also check the _dyld_global_lock_held variable in libSystem.B.dylib?
1772        // TODO: check the malloc lock?
1773        // TODO: check the objective C lock?
1774        if (m_dyld_all_image_infos.dylib_info_addr != 0)
1775            return error; // Success
1776    }
1777
1778    error.SetErrorString("unsafe to load or unload shared libraries");
1779    return error;
1780}
1781
1782void
1783DynamicLoaderMacOSXDYLD::Initialize()
1784{
1785    PluginManager::RegisterPlugin (GetPluginNameStatic(),
1786                                   GetPluginDescriptionStatic(),
1787                                   CreateInstance);
1788}
1789
1790void
1791DynamicLoaderMacOSXDYLD::Terminate()
1792{
1793    PluginManager::UnregisterPlugin (CreateInstance);
1794}
1795
1796
1797const char *
1798DynamicLoaderMacOSXDYLD::GetPluginNameStatic()
1799{
1800    return "dynamic-loader.macosx-dyld";
1801}
1802
1803const char *
1804DynamicLoaderMacOSXDYLD::GetPluginDescriptionStatic()
1805{
1806    return "Dynamic loader plug-in that watches for shared library loads/unloads in MacOSX user processes.";
1807}
1808
1809
1810//------------------------------------------------------------------
1811// PluginInterface protocol
1812//------------------------------------------------------------------
1813const char *
1814DynamicLoaderMacOSXDYLD::GetPluginName()
1815{
1816    return "DynamicLoaderMacOSXDYLD";
1817}
1818
1819const char *
1820DynamicLoaderMacOSXDYLD::GetShortPluginName()
1821{
1822    return GetPluginNameStatic();
1823}
1824
1825uint32_t
1826DynamicLoaderMacOSXDYLD::GetPluginVersion()
1827{
1828    return 1;
1829}
1830
1831uint32_t
1832DynamicLoaderMacOSXDYLD::AddrByteSize()
1833{
1834    switch (m_dyld.header.magic)
1835    {
1836        case llvm::MachO::HeaderMagic32:
1837        case llvm::MachO::HeaderMagic32Swapped:
1838            return 4;
1839
1840        case llvm::MachO::HeaderMagic64:
1841        case llvm::MachO::HeaderMagic64Swapped:
1842            return 8;
1843
1844        default:
1845            break;
1846    }
1847    return 0;
1848}
1849
1850lldb::ByteOrder
1851DynamicLoaderMacOSXDYLD::GetByteOrderFromMagic (uint32_t magic)
1852{
1853    switch (magic)
1854    {
1855        case llvm::MachO::HeaderMagic32:
1856        case llvm::MachO::HeaderMagic64:
1857            return lldb::endian::InlHostByteOrder();
1858
1859        case llvm::MachO::HeaderMagic32Swapped:
1860        case llvm::MachO::HeaderMagic64Swapped:
1861            if (lldb::endian::InlHostByteOrder() == lldb::eByteOrderBig)
1862                return lldb::eByteOrderLittle;
1863            else
1864                return lldb::eByteOrderBig;
1865
1866        default:
1867            break;
1868    }
1869    return lldb::eByteOrderInvalid;
1870}
1871
1872lldb::ByteOrder
1873DynamicLoaderMacOSXDYLD::DYLDImageInfo::GetByteOrder()
1874{
1875    return DynamicLoaderMacOSXDYLD::GetByteOrderFromMagic(header.magic);
1876}
1877
1878