summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/DynamicLoader
diff options
context:
space:
mode:
authorKate Stone <katherine.stone@apple.com>2016-09-06 20:57:50 +0000
committerKate Stone <katherine.stone@apple.com>2016-09-06 20:57:50 +0000
commitb9c1b51e45b845debb76d8658edabca70ca56079 (patch)
treedfcb5a13ef2b014202340f47036da383eaee74aa /lldb/source/Plugins/DynamicLoader
parentd5aa73376966339caad04013510626ec2e42c760 (diff)
downloadbcm5719-llvm-b9c1b51e45b845debb76d8658edabca70ca56079.tar.gz
bcm5719-llvm-b9c1b51e45b845debb76d8658edabca70ca56079.zip
*** This commit represents a complete reformatting of the LLDB source code
*** to conform to clang-format’s LLVM style. This kind of mass change has *** two obvious implications: Firstly, merging this particular commit into a downstream fork may be a huge effort. Alternatively, it may be worth merging all changes up to this commit, performing the same reformatting operation locally, and then discarding the merge for this particular commit. The commands used to accomplish this reformatting were as follows (with current working directory as the root of the repository): find . \( -iname "*.c" -or -iname "*.cpp" -or -iname "*.h" -or -iname "*.mm" \) -exec clang-format -i {} + find . -iname "*.py" -exec autopep8 --in-place --aggressive --aggressive {} + ; The version of clang-format used was 3.9.0, and autopep8 was 1.2.4. Secondly, “blame” style tools will generally point to this commit instead of a meaningful prior commit. There are alternatives available that will attempt to look through this change and find the appropriate prior commit. YMMV. llvm-svn: 280751
Diffstat (limited to 'lldb/source/Plugins/DynamicLoader')
-rw-r--r--lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp2577
-rw-r--r--lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h549
-rw-r--r--lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp1033
-rw-r--r--lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.h227
-rw-r--r--lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.cpp572
-rw-r--r--lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.h412
-rw-r--r--lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp2011
-rw-r--r--lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.h438
-rw-r--r--lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp834
-rw-r--r--lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.h130
-rw-r--r--lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp2101
-rw-r--r--lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h302
-rw-r--r--lldb/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.cpp142
-rw-r--r--lldb/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.h129
-rw-r--r--lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp979
-rw-r--r--lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h399
-rw-r--r--lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp1135
-rw-r--r--lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h251
-rw-r--r--lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp230
-rw-r--r--lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.h76
-rw-r--r--lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp102
-rw-r--r--lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h35
22 files changed, 6854 insertions, 7810 deletions
diff --git a/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp b/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
index 18c8602c41e..db0d0644f09 100644
--- a/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
+++ b/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
@@ -1,4 +1,5 @@
-//===-- DynamicLoaderDarwinKernel.cpp -----------------------------*- C++ -*-===//
+//===-- DynamicLoaderDarwinKernel.cpp -----------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -9,6 +10,7 @@
#include "lldb/Utility/SafeMachO.h"
+#include "Plugins/Platform/MacOSX/PlatformDarwinKernel.h"
#include "lldb/Breakpoint/StoppointCallbackContext.h"
#include "lldb/Core/DataBuffer.h"
#include "lldb/Core/DataBufferHeap.h"
@@ -28,14 +30,13 @@
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadPlanRunToAddress.h"
-#include "Plugins/Platform/MacOSX/PlatformDarwinKernel.h"
#include "DynamicLoaderDarwinKernel.h"
//#define ENABLE_DEBUG_PRINTF // COMMENT THIS LINE OUT PRIOR TO CHECKIN
#ifdef ENABLE_DEBUG_PRINTF
#include <stdio.h>
-#define DEBUG_PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__)
+#define DEBUG_PRINTF(fmt, ...) printf(fmt, ##__VA_ARGS__)
#else
#define DEBUG_PRINTF(fmt, ...)
#endif
@@ -44,89 +45,79 @@ using namespace lldb;
using namespace lldb_private;
// Progressively greater amounts of scanning we will allow
-// For some targets very early in startup, we can't do any random reads of memory or we can crash the device
+// For some targets very early in startup, we can't do any random reads of
+// memory or we can crash the device
// so a setting is needed that can completely disable the KASLR scans.
-enum KASLRScanType
-{
- eKASLRScanNone = 0, // No reading into the inferior at all
- eKASLRScanLowgloAddresses, // Check one word of memory for a possible kernel addr, then see if a kernel is there
- eKASLRScanNearPC, // Scan backwards from the current $pc looking for kernel; checking at 96 locations total
- eKASLRScanExhaustiveScan // Scan through the entire possible kernel address range looking for a kernel
-};
-
-OptionEnumValueElement
-g_kaslr_kernel_scan_enum_values[] =
-{
- { eKASLRScanNone, "none", "Do not read memory looking for a Darwin kernel when attaching." },
- { eKASLRScanLowgloAddresses, "basic", "Check for the Darwin kernel's load addr in the lowglo page (boot-args=debug) only." },
- { eKASLRScanNearPC, "fast-scan", "Scan near the pc value on attach to find the Darwin kernel's load address."},
- { eKASLRScanExhaustiveScan, "exhaustive-scan", "Scan through the entire potential address range of Darwin kernel (only on 32-bit targets)."},
- { 0, NULL, NULL }
-};
-
-static PropertyDefinition
-g_properties[] =
-{
- { "load-kexts" , OptionValue::eTypeBoolean, true, true, NULL, NULL, "Automatically loads kext images when attaching to a kernel." },
- { "scan-type", OptionValue::eTypeEnum, true, eKASLRScanNearPC, NULL, g_kaslr_kernel_scan_enum_values, "Control how many reads lldb will make while searching for a Darwin kernel on attach." },
- { NULL , OptionValue::eTypeInvalid, false, 0 , NULL, NULL, NULL }
-};
-
-enum {
- ePropertyLoadKexts,
- ePropertyScanType
+enum KASLRScanType {
+ eKASLRScanNone = 0, // No reading into the inferior at all
+ eKASLRScanLowgloAddresses, // Check one word of memory for a possible kernel
+ // addr, then see if a kernel is there
+ eKASLRScanNearPC, // Scan backwards from the current $pc looking for kernel;
+ // checking at 96 locations total
+ eKASLRScanExhaustiveScan // Scan through the entire possible kernel address
+ // range looking for a kernel
};
-class DynamicLoaderDarwinKernelProperties : public Properties
-{
+OptionEnumValueElement g_kaslr_kernel_scan_enum_values[] = {
+ {eKASLRScanNone, "none",
+ "Do not read memory looking for a Darwin kernel when attaching."},
+ {eKASLRScanLowgloAddresses, "basic", "Check for the Darwin kernel's load "
+ "addr in the lowglo page "
+ "(boot-args=debug) only."},
+ {eKASLRScanNearPC, "fast-scan", "Scan near the pc value on attach to find "
+ "the Darwin kernel's load address."},
+ {eKASLRScanExhaustiveScan, "exhaustive-scan",
+ "Scan through the entire potential address range of Darwin kernel (only "
+ "on 32-bit targets)."},
+ {0, NULL, NULL}};
+
+static PropertyDefinition g_properties[] = {
+ {"load-kexts", OptionValue::eTypeBoolean, true, true, NULL, NULL,
+ "Automatically loads kext images when attaching to a kernel."},
+ {"scan-type", OptionValue::eTypeEnum, true, eKASLRScanNearPC, NULL,
+ g_kaslr_kernel_scan_enum_values, "Control how many reads lldb will make "
+ "while searching for a Darwin kernel on "
+ "attach."},
+ {NULL, OptionValue::eTypeInvalid, false, 0, NULL, NULL, NULL}};
+
+enum { ePropertyLoadKexts, ePropertyScanType };
+
+class DynamicLoaderDarwinKernelProperties : public Properties {
public:
-
- static ConstString &
- GetSettingName ()
- {
- static ConstString g_setting_name("darwin-kernel");
- return g_setting_name;
- }
-
- DynamicLoaderDarwinKernelProperties() :
- Properties ()
- {
- m_collection_sp.reset (new OptionValueProperties(GetSettingName()));
- m_collection_sp->Initialize(g_properties);
- }
-
- virtual
- ~DynamicLoaderDarwinKernelProperties()
- {
- }
-
- bool
- GetLoadKexts() const
- {
- const uint32_t idx = ePropertyLoadKexts;
- return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
- }
-
- KASLRScanType
- GetScanType() const
- {
- const uint32_t idx = ePropertyScanType;
- return (KASLRScanType) m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value);
- }
-
-
+ static ConstString &GetSettingName() {
+ static ConstString g_setting_name("darwin-kernel");
+ return g_setting_name;
+ }
+
+ DynamicLoaderDarwinKernelProperties() : Properties() {
+ m_collection_sp.reset(new OptionValueProperties(GetSettingName()));
+ m_collection_sp->Initialize(g_properties);
+ }
+
+ virtual ~DynamicLoaderDarwinKernelProperties() {}
+
+ bool GetLoadKexts() const {
+ const uint32_t idx = ePropertyLoadKexts;
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(
+ NULL, idx, g_properties[idx].default_uint_value != 0);
+ }
+
+ KASLRScanType GetScanType() const {
+ const uint32_t idx = ePropertyScanType;
+ return (KASLRScanType)m_collection_sp->GetPropertyAtIndexAsEnumeration(
+ NULL, idx, g_properties[idx].default_uint_value);
+ }
};
-typedef std::shared_ptr<DynamicLoaderDarwinKernelProperties> DynamicLoaderDarwinKernelPropertiesSP;
+typedef std::shared_ptr<DynamicLoaderDarwinKernelProperties>
+ DynamicLoaderDarwinKernelPropertiesSP;
-static const DynamicLoaderDarwinKernelPropertiesSP &
-GetGlobalProperties()
-{
- static DynamicLoaderDarwinKernelPropertiesSP g_settings_sp;
- if (!g_settings_sp)
- g_settings_sp.reset (new DynamicLoaderDarwinKernelProperties ());
- return g_settings_sp;
+static const DynamicLoaderDarwinKernelPropertiesSP &GetGlobalProperties() {
+ static DynamicLoaderDarwinKernelPropertiesSP g_settings_sp;
+ if (!g_settings_sp)
+ g_settings_sp.reset(new DynamicLoaderDarwinKernelProperties());
+ return g_settings_sp;
}
//----------------------------------------------------------------------
@@ -134,360 +125,345 @@ GetGlobalProperties()
// the plugin info class that gets handed out by the plugin factory and
// allows the lldb to instantiate an instance of this class.
//----------------------------------------------------------------------
-DynamicLoader *
-DynamicLoaderDarwinKernel::CreateInstance (Process* process, bool force)
-{
- if (!force)
- {
- // If the user provided an executable binary and it is not a kernel,
- // this plugin should not create an instance.
- Module* exe_module = process->GetTarget().GetExecutableModulePointer();
- if (exe_module)
- {
- ObjectFile *object_file = exe_module->GetObjectFile();
- if (object_file)
- {
- if (object_file->GetStrata() != ObjectFile::eStrataKernel)
- {
- return NULL;
- }
- }
- }
-
- // If the target's architecture does not look like an Apple environment,
- // this plugin should not create an instance.
- const llvm::Triple &triple_ref = process->GetTarget().GetArchitecture().GetTriple();
- switch (triple_ref.getOS())
- {
- case llvm::Triple::Darwin:
- case llvm::Triple::MacOSX:
- case llvm::Triple::IOS:
- case llvm::Triple::TvOS:
- case llvm::Triple::WatchOS:
- if (triple_ref.getVendor() != llvm::Triple::Apple)
- {
- return NULL;
- }
- break;
- // If we have triple like armv7-unknown-unknown, we should try looking for a Darwin kernel.
- case llvm::Triple::UnknownOS:
- break;
- default:
- return NULL;
- break;
+DynamicLoader *DynamicLoaderDarwinKernel::CreateInstance(Process *process,
+ bool force) {
+ if (!force) {
+ // If the user provided an executable binary and it is not a kernel,
+ // this plugin should not create an instance.
+ Module *exe_module = process->GetTarget().GetExecutableModulePointer();
+ if (exe_module) {
+ ObjectFile *object_file = exe_module->GetObjectFile();
+ if (object_file) {
+ if (object_file->GetStrata() != ObjectFile::eStrataKernel) {
+ return NULL;
}
+ }
}
- // At this point if there is an ExecutableModule, it is a kernel and the Target is some variant of an Apple system.
- // If the Process hasn't provided the kernel load address, we need to look around in memory to find it.
-
- const addr_t kernel_load_address = SearchForDarwinKernel (process);
- if (CheckForKernelImageAtAddress (kernel_load_address, process).IsValid())
- {
- process->SetCanRunCode(false);
- return new DynamicLoaderDarwinKernel (process, kernel_load_address);
+ // If the target's architecture does not look like an Apple environment,
+ // this plugin should not create an instance.
+ const llvm::Triple &triple_ref =
+ process->GetTarget().GetArchitecture().GetTriple();
+ switch (triple_ref.getOS()) {
+ case llvm::Triple::Darwin:
+ case llvm::Triple::MacOSX:
+ case llvm::Triple::IOS:
+ case llvm::Triple::TvOS:
+ case llvm::Triple::WatchOS:
+ if (triple_ref.getVendor() != llvm::Triple::Apple) {
+ return NULL;
+ }
+ break;
+ // If we have triple like armv7-unknown-unknown, we should try looking for a
+ // Darwin kernel.
+ case llvm::Triple::UnknownOS:
+ break;
+ default:
+ return NULL;
+ break;
}
- return NULL;
+ }
+
+ // At this point if there is an ExecutableModule, it is a kernel and the
+ // Target is some variant of an Apple system.
+ // If the Process hasn't provided the kernel load address, we need to look
+ // around in memory to find it.
+
+ const addr_t kernel_load_address = SearchForDarwinKernel(process);
+ if (CheckForKernelImageAtAddress(kernel_load_address, process).IsValid()) {
+ process->SetCanRunCode(false);
+ return new DynamicLoaderDarwinKernel(process, kernel_load_address);
+ }
+ return NULL;
}
lldb::addr_t
-DynamicLoaderDarwinKernel::SearchForDarwinKernel (Process *process)
-{
- addr_t kernel_load_address = process->GetImageInfoAddress();
- if (kernel_load_address == LLDB_INVALID_ADDRESS)
- {
- kernel_load_address = SearchForKernelAtSameLoadAddr (process);
- if (kernel_load_address == LLDB_INVALID_ADDRESS)
- {
- kernel_load_address = SearchForKernelWithDebugHints (process);
- if (kernel_load_address == LLDB_INVALID_ADDRESS)
- {
- kernel_load_address = SearchForKernelNearPC (process);
- if (kernel_load_address == LLDB_INVALID_ADDRESS)
- {
- kernel_load_address = SearchForKernelViaExhaustiveSearch (process);
- }
- }
+DynamicLoaderDarwinKernel::SearchForDarwinKernel(Process *process) {
+ addr_t kernel_load_address = process->GetImageInfoAddress();
+ if (kernel_load_address == LLDB_INVALID_ADDRESS) {
+ kernel_load_address = SearchForKernelAtSameLoadAddr(process);
+ if (kernel_load_address == LLDB_INVALID_ADDRESS) {
+ kernel_load_address = SearchForKernelWithDebugHints(process);
+ if (kernel_load_address == LLDB_INVALID_ADDRESS) {
+ kernel_load_address = SearchForKernelNearPC(process);
+ if (kernel_load_address == LLDB_INVALID_ADDRESS) {
+ kernel_load_address = SearchForKernelViaExhaustiveSearch(process);
}
+ }
}
- return kernel_load_address;
+ }
+ return kernel_load_address;
}
//----------------------------------------------------------------------
// Check if the kernel binary is loaded in memory without a slide.
// First verify that the ExecutableModule is a kernel before we proceed.
-// Returns the address of the kernel if one was found, else LLDB_INVALID_ADDRESS.
+// Returns the address of the kernel if one was found, else
+// LLDB_INVALID_ADDRESS.
//----------------------------------------------------------------------
lldb::addr_t
-DynamicLoaderDarwinKernel::SearchForKernelAtSameLoadAddr (Process *process)
-{
- Module *exe_module = process->GetTarget().GetExecutableModulePointer();
- if (exe_module == NULL)
- return LLDB_INVALID_ADDRESS;
+DynamicLoaderDarwinKernel::SearchForKernelAtSameLoadAddr(Process *process) {
+ Module *exe_module = process->GetTarget().GetExecutableModulePointer();
+ if (exe_module == NULL)
+ return LLDB_INVALID_ADDRESS;
- ObjectFile *exe_objfile = exe_module->GetObjectFile();
- if (exe_objfile == NULL)
- return LLDB_INVALID_ADDRESS;
+ ObjectFile *exe_objfile = exe_module->GetObjectFile();
+ if (exe_objfile == NULL)
+ return LLDB_INVALID_ADDRESS;
- if (exe_objfile->GetType() != ObjectFile::eTypeExecutable || exe_objfile->GetStrata() != ObjectFile::eStrataKernel)
- return LLDB_INVALID_ADDRESS;
+ if (exe_objfile->GetType() != ObjectFile::eTypeExecutable ||
+ exe_objfile->GetStrata() != ObjectFile::eStrataKernel)
+ return LLDB_INVALID_ADDRESS;
- if (!exe_objfile->GetHeaderAddress().IsValid())
- return LLDB_INVALID_ADDRESS;
+ if (!exe_objfile->GetHeaderAddress().IsValid())
+ return LLDB_INVALID_ADDRESS;
- if (CheckForKernelImageAtAddress (exe_objfile->GetHeaderAddress().GetFileAddress(), process) == exe_module->GetUUID())
- return exe_objfile->GetHeaderAddress().GetFileAddress();
+ if (CheckForKernelImageAtAddress(
+ exe_objfile->GetHeaderAddress().GetFileAddress(), process) ==
+ exe_module->GetUUID())
+ return exe_objfile->GetHeaderAddress().GetFileAddress();
- return LLDB_INVALID_ADDRESS;
+ return LLDB_INVALID_ADDRESS;
}
//----------------------------------------------------------------------
-// If the debug flag is included in the boot-args nvram setting, the kernel's load address
+// If the debug flag is included in the boot-args nvram setting, the kernel's
+// load address
// will be noted in the lowglo page at a fixed address
-// Returns the address of the kernel if one was found, else LLDB_INVALID_ADDRESS.
+// Returns the address of the kernel if one was found, else
+// LLDB_INVALID_ADDRESS.
//----------------------------------------------------------------------
lldb::addr_t
-DynamicLoaderDarwinKernel::SearchForKernelWithDebugHints (Process *process)
-{
- if (GetGlobalProperties()->GetScanType() == eKASLRScanNone)
- return LLDB_INVALID_ADDRESS;
-
- Error read_err;
- addr_t addr = LLDB_INVALID_ADDRESS;
- addr_t kernel_addresses_64[] = { 0xfffffff000004010ULL, // newest arm64 devices
- 0xffffff8000004010ULL, // 2014-2015-ish arm64 devices
- 0xffffff8000002010ULL, // oldest arm64 devices
- LLDB_INVALID_ADDRESS };
- addr_t kernel_addresses_32[] = { 0xffff0110,
- LLDB_INVALID_ADDRESS };
- for (size_t i = 0; kernel_addresses_64[i] != LLDB_INVALID_ADDRESS; i++)
- {
- addr = process->ReadUnsignedIntegerFromMemory (kernel_addresses_64[i], 8, LLDB_INVALID_ADDRESS, read_err);
- if (CheckForKernelImageAtAddress (addr, process).IsValid())
- {
- return addr;
- }
+DynamicLoaderDarwinKernel::SearchForKernelWithDebugHints(Process *process) {
+ if (GetGlobalProperties()->GetScanType() == eKASLRScanNone)
+ return LLDB_INVALID_ADDRESS;
+
+ Error read_err;
+ addr_t addr = LLDB_INVALID_ADDRESS;
+ addr_t kernel_addresses_64[] = {
+ 0xfffffff000004010ULL, // newest arm64 devices
+ 0xffffff8000004010ULL, // 2014-2015-ish arm64 devices
+ 0xffffff8000002010ULL, // oldest arm64 devices
+ LLDB_INVALID_ADDRESS};
+ addr_t kernel_addresses_32[] = {0xffff0110, LLDB_INVALID_ADDRESS};
+ for (size_t i = 0; kernel_addresses_64[i] != LLDB_INVALID_ADDRESS; i++) {
+ addr = process->ReadUnsignedIntegerFromMemory(
+ kernel_addresses_64[i], 8, LLDB_INVALID_ADDRESS, read_err);
+ if (CheckForKernelImageAtAddress(addr, process).IsValid()) {
+ return addr;
}
+ }
- for (size_t i = 0; kernel_addresses_32[i] != LLDB_INVALID_ADDRESS; i++)
- {
- addr = process->ReadUnsignedIntegerFromMemory (kernel_addresses_32[i], 4, LLDB_INVALID_ADDRESS, read_err);
- if (CheckForKernelImageAtAddress (addr, process).IsValid())
- {
- return addr;
- }
+ for (size_t i = 0; kernel_addresses_32[i] != LLDB_INVALID_ADDRESS; i++) {
+ addr = process->ReadUnsignedIntegerFromMemory(
+ kernel_addresses_32[i], 4, LLDB_INVALID_ADDRESS, read_err);
+ if (CheckForKernelImageAtAddress(addr, process).IsValid()) {
+ return addr;
}
+ }
- return LLDB_INVALID_ADDRESS;
+ return LLDB_INVALID_ADDRESS;
}
//----------------------------------------------------------------------
// If the kernel is currently executing when lldb attaches, and we don't have
// a better way of finding the kernel's load address, try searching backwards
// from the current pc value looking for the kernel's Mach header in memory.
-// Returns the address of the kernel if one was found, else LLDB_INVALID_ADDRESS.
+// Returns the address of the kernel if one was found, else
+// LLDB_INVALID_ADDRESS.
//----------------------------------------------------------------------
lldb::addr_t
-DynamicLoaderDarwinKernel::SearchForKernelNearPC (Process *process)
-{
- if (GetGlobalProperties()->GetScanType() == eKASLRScanNone
- || GetGlobalProperties()->GetScanType() == eKASLRScanLowgloAddresses)
- {
- return LLDB_INVALID_ADDRESS;
- }
+DynamicLoaderDarwinKernel::SearchForKernelNearPC(Process *process) {
+ if (GetGlobalProperties()->GetScanType() == eKASLRScanNone ||
+ GetGlobalProperties()->GetScanType() == eKASLRScanLowgloAddresses) {
+ return LLDB_INVALID_ADDRESS;
+ }
- ThreadSP thread = process->GetThreadList().GetSelectedThread ();
- if (thread.get() == NULL)
- return LLDB_INVALID_ADDRESS;
- addr_t pc = thread->GetRegisterContext ()->GetPC(LLDB_INVALID_ADDRESS);
-
- if (pc == LLDB_INVALID_ADDRESS)
- return LLDB_INVALID_ADDRESS;
-
- // The kernel will load at at one megabyte boundary (0x100000), or at that boundary plus
- // an offset of one page (0x1000) or two, or four (0x4000), depending on the device.
-
- // Round the current pc down to the nearest one megabyte boundary - the place where we will start searching.
- addr_t addr = pc & ~0xfffff;
-
- // Search backwards 32 megabytes, looking for the start of the kernel at each one-megabyte boundary.
- for (int i = 0; i < 32; i++, addr -= 0x100000)
- {
- if (CheckForKernelImageAtAddress (addr, process).IsValid())
- return addr;
- if (CheckForKernelImageAtAddress (addr + 0x1000, process).IsValid())
- return addr + 0x1000;
- if (CheckForKernelImageAtAddress (addr + 0x2000, process).IsValid())
- return addr + 0x2000;
- if (CheckForKernelImageAtAddress (addr + 0x4000, process).IsValid())
- return addr + 0x4000;
- }
+ ThreadSP thread = process->GetThreadList().GetSelectedThread();
+ if (thread.get() == NULL)
+ return LLDB_INVALID_ADDRESS;
+ addr_t pc = thread->GetRegisterContext()->GetPC(LLDB_INVALID_ADDRESS);
+ if (pc == LLDB_INVALID_ADDRESS)
return LLDB_INVALID_ADDRESS;
+
+ // The kernel will load at at one megabyte boundary (0x100000), or at that
+ // boundary plus
+ // an offset of one page (0x1000) or two, or four (0x4000), depending on the
+ // device.
+
+ // Round the current pc down to the nearest one megabyte boundary - the place
+ // where we will start searching.
+ addr_t addr = pc & ~0xfffff;
+
+ // Search backwards 32 megabytes, looking for the start of the kernel at each
+ // one-megabyte boundary.
+ for (int i = 0; i < 32; i++, addr -= 0x100000) {
+ if (CheckForKernelImageAtAddress(addr, process).IsValid())
+ return addr;
+ if (CheckForKernelImageAtAddress(addr + 0x1000, process).IsValid())
+ return addr + 0x1000;
+ if (CheckForKernelImageAtAddress(addr + 0x2000, process).IsValid())
+ return addr + 0x2000;
+ if (CheckForKernelImageAtAddress(addr + 0x4000, process).IsValid())
+ return addr + 0x4000;
+ }
+
+ return LLDB_INVALID_ADDRESS;
}
//----------------------------------------------------------------------
// Scan through the valid address range for a kernel binary.
// This is uselessly slow in 64-bit environments so we don't even try it.
// This scan is not enabled by default even for 32-bit targets.
-// Returns the address of the kernel if one was found, else LLDB_INVALID_ADDRESS.
+// Returns the address of the kernel if one was found, else
+// LLDB_INVALID_ADDRESS.
//----------------------------------------------------------------------
-lldb::addr_t
-DynamicLoaderDarwinKernel::SearchForKernelViaExhaustiveSearch (Process *process)
-{
- if (GetGlobalProperties()->GetScanType() != eKASLRScanExhaustiveScan)
- {
- return LLDB_INVALID_ADDRESS;
- }
-
- addr_t kernel_range_low, kernel_range_high;
- if (process->GetTarget().GetArchitecture().GetAddressByteSize() == 8)
- {
- kernel_range_low = 1ULL << 63;
- kernel_range_high = UINT64_MAX;
- }
- else
- {
- kernel_range_low = 1ULL << 31;
- kernel_range_high = UINT32_MAX;
- }
-
- // Stepping through memory at one-megabyte resolution looking for a kernel
- // rarely works (fast enough) with a 64-bit address space -- for now, let's
- // not even bother. We may be attaching to something which *isn't* a kernel
- // and we don't want to spin for minutes on-end looking for a kernel.
- if (process->GetTarget().GetArchitecture().GetAddressByteSize() == 8)
- return LLDB_INVALID_ADDRESS;
-
- addr_t addr = kernel_range_low;
-
- while (addr >= kernel_range_low && addr < kernel_range_high)
- {
- if (CheckForKernelImageAtAddress (addr, process).IsValid())
- return addr;
- if (CheckForKernelImageAtAddress (addr + 0x1000, process).IsValid())
- return addr + 0x1000;
- if (CheckForKernelImageAtAddress (addr + 0x2000, process).IsValid())
- return addr + 0x2000;
- if (CheckForKernelImageAtAddress (addr + 0x4000, process).IsValid())
- return addr + 0x4000;
- addr += 0x100000;
- }
+lldb::addr_t DynamicLoaderDarwinKernel::SearchForKernelViaExhaustiveSearch(
+ Process *process) {
+ if (GetGlobalProperties()->GetScanType() != eKASLRScanExhaustiveScan) {
return LLDB_INVALID_ADDRESS;
+ }
+
+ addr_t kernel_range_low, kernel_range_high;
+ if (process->GetTarget().GetArchitecture().GetAddressByteSize() == 8) {
+ kernel_range_low = 1ULL << 63;
+ kernel_range_high = UINT64_MAX;
+ } else {
+ kernel_range_low = 1ULL << 31;
+ kernel_range_high = UINT32_MAX;
+ }
+
+ // Stepping through memory at one-megabyte resolution looking for a kernel
+ // rarely works (fast enough) with a 64-bit address space -- for now, let's
+ // not even bother. We may be attaching to something which *isn't* a kernel
+ // and we don't want to spin for minutes on-end looking for a kernel.
+ if (process->GetTarget().GetArchitecture().GetAddressByteSize() == 8)
+ return LLDB_INVALID_ADDRESS;
+
+ addr_t addr = kernel_range_low;
+
+ while (addr >= kernel_range_low && addr < kernel_range_high) {
+ if (CheckForKernelImageAtAddress(addr, process).IsValid())
+ return addr;
+ if (CheckForKernelImageAtAddress(addr + 0x1000, process).IsValid())
+ return addr + 0x1000;
+ if (CheckForKernelImageAtAddress(addr + 0x2000, process).IsValid())
+ return addr + 0x2000;
+ if (CheckForKernelImageAtAddress(addr + 0x4000, process).IsValid())
+ return addr + 0x4000;
+ addr += 0x100000;
+ }
+ return LLDB_INVALID_ADDRESS;
}
//----------------------------------------------------------------------
// Given an address in memory, look to see if there is a kernel image at that
-// address.
-// Returns a UUID; if a kernel was not found at that address, UUID.IsValid() will be false.
+// address.
+// Returns a UUID; if a kernel was not found at that address, UUID.IsValid()
+// will be false.
//----------------------------------------------------------------------
lldb_private::UUID
-DynamicLoaderDarwinKernel::CheckForKernelImageAtAddress (lldb::addr_t addr, Process *process)
-{
- Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
- if (addr == LLDB_INVALID_ADDRESS)
- return UUID();
+DynamicLoaderDarwinKernel::CheckForKernelImageAtAddress(lldb::addr_t addr,
+ Process *process) {
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+ if (addr == LLDB_INVALID_ADDRESS)
+ return UUID();
- if (log)
- log->Printf ("DynamicLoaderDarwinKernel::CheckForKernelImageAtAddress: looking for kernel binary at 0x%" PRIx64, addr);
-
- // First try a quick test -- read the first 4 bytes and see if there is a valid Mach-O magic field there
- // (the first field of the mach_header/mach_header_64 struct).
-
- Error read_error;
- uint64_t result = process->ReadUnsignedIntegerFromMemory (addr, 4, LLDB_INVALID_ADDRESS, read_error);
- if (result != llvm::MachO::MH_MAGIC_64
- && result != llvm::MachO::MH_MAGIC
- && result != llvm::MachO::MH_CIGAM
- && result != llvm::MachO::MH_CIGAM_64)
- {
- return UUID();
- }
+ if (log)
+ log->Printf("DynamicLoaderDarwinKernel::CheckForKernelImageAtAddress: "
+ "looking for kernel binary at 0x%" PRIx64,
+ addr);
- // Read the mach header and see whether it looks like a kernel
- llvm::MachO::mach_header header;
- if (process->DoReadMemory (addr, &header, sizeof (header), read_error) != sizeof (header))
- return UUID();
-
- if (header.magic == llvm::MachO::MH_CIGAM ||
- header.magic == llvm::MachO::MH_CIGAM_64)
- {
- header.magic = llvm::ByteSwap_32 (header.magic);
- header.cputype = llvm::ByteSwap_32 (header.cputype);
- header.cpusubtype = llvm::ByteSwap_32 (header.cpusubtype);
- header.filetype = llvm::ByteSwap_32 (header.filetype);
- header.ncmds = llvm::ByteSwap_32 (header.ncmds);
- header.sizeofcmds = llvm::ByteSwap_32 (header.sizeofcmds);
- header.flags = llvm::ByteSwap_32 (header.flags);
- }
+ // First try a quick test -- read the first 4 bytes and see if there is a
+ // valid Mach-O magic field there
+ // (the first field of the mach_header/mach_header_64 struct).
- // A kernel is an executable which does not have the dynamic link object flag set.
- if (header.filetype == llvm::MachO::MH_EXECUTE
- && (header.flags & llvm::MachO::MH_DYLDLINK) == 0)
- {
- // Create a full module to get the UUID
- ModuleSP memory_module_sp = process->ReadModuleFromMemory (FileSpec ("temp_mach_kernel", false), addr);
- if (!memory_module_sp.get())
- return UUID();
-
- ObjectFile *exe_objfile = memory_module_sp->GetObjectFile();
- if (exe_objfile == NULL)
- return UUID();
-
- if (exe_objfile->GetType() == ObjectFile::eTypeExecutable && exe_objfile->GetStrata() == ObjectFile::eStrataKernel)
- {
- ArchSpec kernel_arch (eArchTypeMachO, header.cputype, header.cpusubtype);
- if (!process->GetTarget().GetArchitecture().IsCompatibleMatch(kernel_arch))
- {
- process->GetTarget().SetArchitecture (kernel_arch);
- }
- if (log)
- log->Printf ("DynamicLoaderDarwinKernel::CheckForKernelImageAtAddress: kernel binary image found at 0x%" PRIx64, addr);
- return memory_module_sp->GetUUID();
- }
- }
+ Error read_error;
+ uint64_t result = process->ReadUnsignedIntegerFromMemory(
+ addr, 4, LLDB_INVALID_ADDRESS, read_error);
+ if (result != llvm::MachO::MH_MAGIC_64 && result != llvm::MachO::MH_MAGIC &&
+ result != llvm::MachO::MH_CIGAM && result != llvm::MachO::MH_CIGAM_64) {
+ return UUID();
+ }
+ // Read the mach header and see whether it looks like a kernel
+ llvm::MachO::mach_header header;
+ if (process->DoReadMemory(addr, &header, sizeof(header), read_error) !=
+ sizeof(header))
return UUID();
+
+ if (header.magic == llvm::MachO::MH_CIGAM ||
+ header.magic == llvm::MachO::MH_CIGAM_64) {
+ header.magic = llvm::ByteSwap_32(header.magic);
+ header.cputype = llvm::ByteSwap_32(header.cputype);
+ header.cpusubtype = llvm::ByteSwap_32(header.cpusubtype);
+ header.filetype = llvm::ByteSwap_32(header.filetype);
+ header.ncmds = llvm::ByteSwap_32(header.ncmds);
+ header.sizeofcmds = llvm::ByteSwap_32(header.sizeofcmds);
+ header.flags = llvm::ByteSwap_32(header.flags);
+ }
+
+ // A kernel is an executable which does not have the dynamic link object flag
+ // set.
+ if (header.filetype == llvm::MachO::MH_EXECUTE &&
+ (header.flags & llvm::MachO::MH_DYLDLINK) == 0) {
+ // Create a full module to get the UUID
+ ModuleSP memory_module_sp = process->ReadModuleFromMemory(
+ FileSpec("temp_mach_kernel", false), addr);
+ if (!memory_module_sp.get())
+ return UUID();
+
+ ObjectFile *exe_objfile = memory_module_sp->GetObjectFile();
+ if (exe_objfile == NULL)
+ return UUID();
+
+ if (exe_objfile->GetType() == ObjectFile::eTypeExecutable &&
+ exe_objfile->GetStrata() == ObjectFile::eStrataKernel) {
+ ArchSpec kernel_arch(eArchTypeMachO, header.cputype, header.cpusubtype);
+ if (!process->GetTarget().GetArchitecture().IsCompatibleMatch(
+ kernel_arch)) {
+ process->GetTarget().SetArchitecture(kernel_arch);
+ }
+ if (log)
+ log->Printf("DynamicLoaderDarwinKernel::CheckForKernelImageAtAddress: "
+ "kernel binary image found at 0x%" PRIx64,
+ addr);
+ return memory_module_sp->GetUUID();
+ }
+ }
+
+ return UUID();
}
//----------------------------------------------------------------------
// Constructor
//----------------------------------------------------------------------
-DynamicLoaderDarwinKernel::DynamicLoaderDarwinKernel(Process *process, lldb::addr_t kernel_addr)
- : DynamicLoader(process),
- m_kernel_load_address(kernel_addr),
- m_kernel(),
- m_kext_summary_header_ptr_addr(),
- m_kext_summary_header_addr(),
- m_kext_summary_header(),
- m_known_kexts(),
- m_mutex(),
- m_break_id(LLDB_INVALID_BREAK_ID)
-{
- Error error;
- PlatformSP platform_sp(Platform::Create(PlatformDarwinKernel::GetPluginNameStatic(), error));
- // Only select the darwin-kernel Platform if we've been asked to load kexts.
- // It can take some time to scan over all of the kext info.plists and that
- // shouldn't be done if kext loading is explicitly disabled.
- if (platform_sp.get() && GetGlobalProperties()->GetLoadKexts())
- {
- process->GetTarget().SetPlatform(platform_sp);
- }
+DynamicLoaderDarwinKernel::DynamicLoaderDarwinKernel(Process *process,
+ lldb::addr_t kernel_addr)
+ : DynamicLoader(process), m_kernel_load_address(kernel_addr), m_kernel(),
+ m_kext_summary_header_ptr_addr(), m_kext_summary_header_addr(),
+ m_kext_summary_header(), m_known_kexts(), m_mutex(),
+ m_break_id(LLDB_INVALID_BREAK_ID) {
+ Error error;
+ PlatformSP platform_sp(
+ Platform::Create(PlatformDarwinKernel::GetPluginNameStatic(), error));
+ // Only select the darwin-kernel Platform if we've been asked to load kexts.
+ // It can take some time to scan over all of the kext info.plists and that
+ // shouldn't be done if kext loading is explicitly disabled.
+ if (platform_sp.get() && GetGlobalProperties()->GetLoadKexts()) {
+ process->GetTarget().SetPlatform(platform_sp);
+ }
}
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
-DynamicLoaderDarwinKernel::~DynamicLoaderDarwinKernel()
-{
- Clear(true);
-}
+DynamicLoaderDarwinKernel::~DynamicLoaderDarwinKernel() { Clear(true); }
-void
-DynamicLoaderDarwinKernel::UpdateIfNeeded()
-{
- LoadKernelModuleIfNeeded();
- SetNotificationBreakpointIfNeeded ();
+void DynamicLoaderDarwinKernel::UpdateIfNeeded() {
+ LoadKernelModuleIfNeeded();
+ SetNotificationBreakpointIfNeeded();
}
//------------------------------------------------------------------
/// Called after attaching a process.
@@ -495,11 +471,9 @@ DynamicLoaderDarwinKernel::UpdateIfNeeded()
/// Allow DynamicLoader plug-ins to execute some code after
/// attaching to a process.
//------------------------------------------------------------------
-void
-DynamicLoaderDarwinKernel::DidAttach ()
-{
- PrivateInitialize(m_process);
- UpdateIfNeeded();
+void DynamicLoaderDarwinKernel::DidAttach() {
+ PrivateInitialize(m_process);
+ UpdateIfNeeded();
}
//------------------------------------------------------------------
@@ -508,595 +482,528 @@ DynamicLoaderDarwinKernel::DidAttach ()
/// Allow DynamicLoader plug-ins to execute some code after
/// attaching to a process.
//------------------------------------------------------------------
-void
-DynamicLoaderDarwinKernel::DidLaunch ()
-{
- PrivateInitialize(m_process);
- UpdateIfNeeded();
+void DynamicLoaderDarwinKernel::DidLaunch() {
+ PrivateInitialize(m_process);
+ UpdateIfNeeded();
}
-
//----------------------------------------------------------------------
// Clear out the state of this class.
//----------------------------------------------------------------------
-void
-DynamicLoaderDarwinKernel::Clear (bool clear_process)
-{
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
-
- if (m_process->IsAlive() && LLDB_BREAK_ID_IS_VALID(m_break_id))
- m_process->ClearBreakpointSiteByID(m_break_id);
-
- if (clear_process)
- m_process = NULL;
- m_kernel.Clear();
- m_known_kexts.clear();
- m_kext_summary_header_ptr_addr.Clear();
- m_kext_summary_header_addr.Clear();
- m_break_id = LLDB_INVALID_BREAK_ID;
+void DynamicLoaderDarwinKernel::Clear(bool clear_process) {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+
+ if (m_process->IsAlive() && LLDB_BREAK_ID_IS_VALID(m_break_id))
+ m_process->ClearBreakpointSiteByID(m_break_id);
+
+ if (clear_process)
+ m_process = NULL;
+ m_kernel.Clear();
+ m_known_kexts.clear();
+ m_kext_summary_header_ptr_addr.Clear();
+ m_kext_summary_header_addr.Clear();
+ m_break_id = LLDB_INVALID_BREAK_ID;
}
+bool DynamicLoaderDarwinKernel::KextImageInfo::LoadImageAtFileAddress(
+ Process *process) {
+ if (IsLoaded())
+ return true;
-bool
-DynamicLoaderDarwinKernel::KextImageInfo::LoadImageAtFileAddress (Process *process)
-{
- if (IsLoaded())
- return true;
-
- if (m_module_sp)
- {
- bool changed = false;
- if (m_module_sp->SetLoadAddress (process->GetTarget(), 0, true, changed))
- m_load_process_stop_id = process->GetStopID();
- }
- return false;
+ if (m_module_sp) {
+ bool changed = false;
+ if (m_module_sp->SetLoadAddress(process->GetTarget(), 0, true, changed))
+ m_load_process_stop_id = process->GetStopID();
+ }
+ return false;
}
-void
-DynamicLoaderDarwinKernel::KextImageInfo::SetModule (ModuleSP module_sp)
-{
- m_module_sp = module_sp;
- if (module_sp.get() && module_sp->GetObjectFile())
- {
- if (module_sp->GetObjectFile()->GetType() == ObjectFile::eTypeExecutable
- && module_sp->GetObjectFile()->GetStrata() == ObjectFile::eStrataKernel)
- {
- m_kernel_image = true;
- }
- else
- {
- m_kernel_image = false;
- }
+void DynamicLoaderDarwinKernel::KextImageInfo::SetModule(ModuleSP module_sp) {
+ m_module_sp = module_sp;
+ if (module_sp.get() && module_sp->GetObjectFile()) {
+ if (module_sp->GetObjectFile()->GetType() == ObjectFile::eTypeExecutable &&
+ module_sp->GetObjectFile()->GetStrata() == ObjectFile::eStrataKernel) {
+ m_kernel_image = true;
+ } else {
+ m_kernel_image = false;
}
+ }
}
-ModuleSP
-DynamicLoaderDarwinKernel::KextImageInfo::GetModule ()
-{
- return m_module_sp;
+ModuleSP DynamicLoaderDarwinKernel::KextImageInfo::GetModule() {
+ return m_module_sp;
}
-void
-DynamicLoaderDarwinKernel::KextImageInfo::SetLoadAddress (addr_t load_addr)
-{
- m_load_address = load_addr;
+void DynamicLoaderDarwinKernel::KextImageInfo::SetLoadAddress(
+ addr_t load_addr) {
+ m_load_address = load_addr;
}
-addr_t
-DynamicLoaderDarwinKernel::KextImageInfo::GetLoadAddress () const
-{
- return m_load_address;
+addr_t DynamicLoaderDarwinKernel::KextImageInfo::GetLoadAddress() const {
+ return m_load_address;
}
-uint64_t
-DynamicLoaderDarwinKernel::KextImageInfo::GetSize () const
-{
- return m_size;
+uint64_t DynamicLoaderDarwinKernel::KextImageInfo::GetSize() const {
+ return m_size;
}
-void
-DynamicLoaderDarwinKernel::KextImageInfo::SetSize (uint64_t size)
-{
- m_size = size;
+void DynamicLoaderDarwinKernel::KextImageInfo::SetSize(uint64_t size) {
+ m_size = size;
}
-uint32_t
-DynamicLoaderDarwinKernel::KextImageInfo::GetProcessStopId () const
-{
- return m_load_process_stop_id;
+uint32_t DynamicLoaderDarwinKernel::KextImageInfo::GetProcessStopId() const {
+ return m_load_process_stop_id;
}
-void
-DynamicLoaderDarwinKernel::KextImageInfo::SetProcessStopId (uint32_t stop_id)
-{
- m_load_process_stop_id = stop_id;
+void DynamicLoaderDarwinKernel::KextImageInfo::SetProcessStopId(
+ uint32_t stop_id) {
+ m_load_process_stop_id = stop_id;
}
-bool
-DynamicLoaderDarwinKernel::KextImageInfo::operator== (const KextImageInfo &rhs)
-{
- if (m_uuid.IsValid() || rhs.GetUUID().IsValid())
- {
- if (m_uuid == rhs.GetUUID())
- {
- return true;
- }
- return false;
+bool DynamicLoaderDarwinKernel::KextImageInfo::
+operator==(const KextImageInfo &rhs) {
+ if (m_uuid.IsValid() || rhs.GetUUID().IsValid()) {
+ if (m_uuid == rhs.GetUUID()) {
+ return true;
}
+ return false;
+ }
- if (m_name == rhs.GetName() && m_load_address == rhs.GetLoadAddress())
- return true;
+ if (m_name == rhs.GetName() && m_load_address == rhs.GetLoadAddress())
+ return true;
- return false;
+ return false;
}
-void
-DynamicLoaderDarwinKernel::KextImageInfo::SetName (const char *name)
-{
- m_name = name;
+void DynamicLoaderDarwinKernel::KextImageInfo::SetName(const char *name) {
+ m_name = name;
}
-std::string
-DynamicLoaderDarwinKernel::KextImageInfo::GetName () const
-{
- return m_name;
+std::string DynamicLoaderDarwinKernel::KextImageInfo::GetName() const {
+ return m_name;
}
-void
-DynamicLoaderDarwinKernel::KextImageInfo::SetUUID (const UUID &uuid)
-{
- m_uuid = uuid;
+void DynamicLoaderDarwinKernel::KextImageInfo::SetUUID(const UUID &uuid) {
+ m_uuid = uuid;
}
-UUID
-DynamicLoaderDarwinKernel::KextImageInfo::GetUUID () const
-{
- return m_uuid;
+UUID DynamicLoaderDarwinKernel::KextImageInfo::GetUUID() const {
+ return m_uuid;
}
-// Given the m_load_address from the kext summaries, and a UUID, try to create an in-memory
-// Module at that address. Require that the MemoryModule have a matching UUID and detect
+// Given the m_load_address from the kext summaries, and a UUID, try to create
+// an in-memory
+// Module at that address. Require that the MemoryModule have a matching UUID
+// and detect
// if this MemoryModule is a kernel or a kext.
//
-// Returns true if m_memory_module_sp is now set to a valid Module.
-
-bool
-DynamicLoaderDarwinKernel::KextImageInfo::ReadMemoryModule (Process *process)
-{
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- if (m_memory_module_sp.get() != NULL)
- return true;
- if (m_load_address == LLDB_INVALID_ADDRESS)
- return false;
-
- FileSpec file_spec;
- file_spec.SetFile (m_name.c_str(), false);
-
- ModuleSP memory_module_sp = process->ReadModuleFromMemory (file_spec, m_load_address);
-
- if (memory_module_sp.get() == NULL)
- return false;
-
- bool is_kernel = false;
- if (memory_module_sp->GetObjectFile())
- {
- if (memory_module_sp->GetObjectFile()->GetType() == ObjectFile::eTypeExecutable
- && memory_module_sp->GetObjectFile()->GetStrata() == ObjectFile::eStrataKernel)
- {
- is_kernel = true;
- }
- else if (memory_module_sp->GetObjectFile()->GetType() == ObjectFile::eTypeSharedLibrary)
- {
- is_kernel = false;
- }
- }
+// Returns true if m_memory_module_sp is now set to a valid Module.
- // If this is a kext, and the kernel specified what UUID we should find at this
- // load address, require that the memory module have a matching UUID or something
- // has gone wrong and we should discard it.
- if (m_uuid.IsValid())
- {
- if (m_uuid != memory_module_sp->GetUUID())
- {
- if (log)
- {
- log->Printf ("KextImageInfo::ReadMemoryModule the kernel said to find uuid %s at 0x%" PRIx64 " but instead we found uuid %s, throwing it away", m_uuid.GetAsString().c_str(), m_load_address, memory_module_sp->GetUUID().GetAsString().c_str());
- }
- return false;
- }
- }
+bool DynamicLoaderDarwinKernel::KextImageInfo::ReadMemoryModule(
+ Process *process) {
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
+ if (m_memory_module_sp.get() != NULL)
+ return true;
+ if (m_load_address == LLDB_INVALID_ADDRESS)
+ return false;
- // If the in-memory Module has a UUID, let's use that.
- if (!m_uuid.IsValid() && memory_module_sp->GetUUID().IsValid())
- {
- m_uuid = memory_module_sp->GetUUID();
- }
+ FileSpec file_spec;
+ file_spec.SetFile(m_name.c_str(), false);
- m_memory_module_sp = memory_module_sp;
- m_kernel_image = is_kernel;
- if (is_kernel)
- {
- if (log)
- {
- // This is unusual and probably not intended
- log->Printf ("KextImageInfo::ReadMemoryModule read the kernel binary out of memory");
- }
- if (memory_module_sp->GetArchitecture().IsValid())
- {
- process->GetTarget().SetArchitecture(memory_module_sp->GetArchitecture());
- }
- if (m_uuid.IsValid())
- {
- ModuleSP exe_module_sp = process->GetTarget().GetExecutableModule();
- if (exe_module_sp.get() && exe_module_sp->GetUUID().IsValid())
- {
- if (m_uuid != exe_module_sp->GetUUID())
- {
- // The user specified a kernel binary that has a different UUID than
- // the kernel actually running in memory. This never ends well;
- // clear the user specified kernel binary from the Target.
-
- m_module_sp.reset();
-
- ModuleList user_specified_kernel_list;
- user_specified_kernel_list.Append (exe_module_sp);
- process->GetTarget().GetImages().Remove (user_specified_kernel_list);
- }
- }
+ ModuleSP memory_module_sp =
+ process->ReadModuleFromMemory(file_spec, m_load_address);
+
+ if (memory_module_sp.get() == NULL)
+ return false;
+
+ bool is_kernel = false;
+ if (memory_module_sp->GetObjectFile()) {
+ if (memory_module_sp->GetObjectFile()->GetType() ==
+ ObjectFile::eTypeExecutable &&
+ memory_module_sp->GetObjectFile()->GetStrata() ==
+ ObjectFile::eStrataKernel) {
+ is_kernel = true;
+ } else if (memory_module_sp->GetObjectFile()->GetType() ==
+ ObjectFile::eTypeSharedLibrary) {
+ is_kernel = false;
+ }
+ }
+
+ // If this is a kext, and the kernel specified what UUID we should find at
+ // this
+ // load address, require that the memory module have a matching UUID or
+ // something
+ // has gone wrong and we should discard it.
+ if (m_uuid.IsValid()) {
+ if (m_uuid != memory_module_sp->GetUUID()) {
+ if (log) {
+ log->Printf("KextImageInfo::ReadMemoryModule the kernel said to find "
+ "uuid %s at 0x%" PRIx64
+ " but instead we found uuid %s, throwing it away",
+ m_uuid.GetAsString().c_str(), m_load_address,
+ memory_module_sp->GetUUID().GetAsString().c_str());
+ }
+ return false;
+ }
+ }
+
+ // If the in-memory Module has a UUID, let's use that.
+ if (!m_uuid.IsValid() && memory_module_sp->GetUUID().IsValid()) {
+ m_uuid = memory_module_sp->GetUUID();
+ }
+
+ m_memory_module_sp = memory_module_sp;
+ m_kernel_image = is_kernel;
+ if (is_kernel) {
+ if (log) {
+ // This is unusual and probably not intended
+ log->Printf("KextImageInfo::ReadMemoryModule read the kernel binary out "
+ "of memory");
+ }
+ if (memory_module_sp->GetArchitecture().IsValid()) {
+ process->GetTarget().SetArchitecture(memory_module_sp->GetArchitecture());
+ }
+ if (m_uuid.IsValid()) {
+ ModuleSP exe_module_sp = process->GetTarget().GetExecutableModule();
+ if (exe_module_sp.get() && exe_module_sp->GetUUID().IsValid()) {
+ if (m_uuid != exe_module_sp->GetUUID()) {
+ // The user specified a kernel binary that has a different UUID than
+ // the kernel actually running in memory. This never ends well;
+ // clear the user specified kernel binary from the Target.
+
+ m_module_sp.reset();
+
+ ModuleList user_specified_kernel_list;
+ user_specified_kernel_list.Append(exe_module_sp);
+ process->GetTarget().GetImages().Remove(user_specified_kernel_list);
}
+ }
}
+ }
- return true;
+ return true;
}
-bool
-DynamicLoaderDarwinKernel::KextImageInfo::IsKernel () const
-{
- return m_kernel_image == true;
+bool DynamicLoaderDarwinKernel::KextImageInfo::IsKernel() const {
+ return m_kernel_image == true;
}
-void
-DynamicLoaderDarwinKernel::KextImageInfo::SetIsKernel (bool is_kernel)
-{
- m_kernel_image = is_kernel;
+void DynamicLoaderDarwinKernel::KextImageInfo::SetIsKernel(bool is_kernel) {
+ m_kernel_image = is_kernel;
}
-bool
-DynamicLoaderDarwinKernel::KextImageInfo::LoadImageUsingMemoryModule (Process *process)
-{
- if (IsLoaded())
- return true;
-
+bool DynamicLoaderDarwinKernel::KextImageInfo::LoadImageUsingMemoryModule(
+ Process *process) {
+ if (IsLoaded())
+ return true;
- Target &target = process->GetTarget();
+ Target &target = process->GetTarget();
- // If we don't have / can't create a memory module for this kext, don't try to load it - we won't
- // have the correct segment load addresses.
- if (!ReadMemoryModule (process))
- {
- Log *log(GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
- if (log)
- log->Printf("Unable to read '%s' from memory at address 0x%" PRIx64 " to get the segment load addresses.", m_name.c_str(), m_load_address);
- return false;
- }
+ // If we don't have / can't create a memory module for this kext, don't try to
+ // load it - we won't
+ // have the correct segment load addresses.
+ if (!ReadMemoryModule(process)) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+ if (log)
+ log->Printf("Unable to read '%s' from memory at address 0x%" PRIx64
+ " to get the segment load addresses.",
+ m_name.c_str(), m_load_address);
+ return false;
+ }
- bool uuid_is_valid = m_uuid.IsValid();
+ bool uuid_is_valid = m_uuid.IsValid();
- if (IsKernel() && uuid_is_valid && m_memory_module_sp.get())
- {
- Stream *s = target.GetDebugger().GetOutputFile().get();
- if (s)
- {
- s->Printf ("Kernel UUID: %s\n", m_memory_module_sp->GetUUID().GetAsString().c_str());
- s->Printf ("Load Address: 0x%" PRIx64 "\n", m_load_address);
- }
+ if (IsKernel() && uuid_is_valid && m_memory_module_sp.get()) {
+ Stream *s = target.GetDebugger().GetOutputFile().get();
+ if (s) {
+ s->Printf("Kernel UUID: %s\n",
+ m_memory_module_sp->GetUUID().GetAsString().c_str());
+ s->Printf("Load Address: 0x%" PRIx64 "\n", m_load_address);
}
-
- if (!m_module_sp)
- {
- // See if the kext has already been loaded into the target, probably by the user doing target modules add.
- const ModuleList &target_images = target.GetImages();
- m_module_sp = target_images.FindModule(m_uuid);
-
- // Search for the kext on the local filesystem via the UUID
- if (!m_module_sp && uuid_is_valid)
- {
- ModuleSpec module_spec;
- module_spec.GetUUID() = m_uuid;
- module_spec.GetArchitecture() = target.GetArchitecture();
-
- // For the kernel, we really do need an on-disk file copy of the binary to do anything useful.
- // This will force a clal to
- if (IsKernel())
- {
- if (Symbols::DownloadObjectAndSymbolFile (module_spec, true))
- {
- if (module_spec.GetFileSpec().Exists())
- {
- m_module_sp.reset(new Module (module_spec.GetFileSpec(), target.GetArchitecture()));
- if (m_module_sp.get() && m_module_sp->MatchesModuleSpec (module_spec))
- {
- ModuleList loaded_module_list;
- loaded_module_list.Append (m_module_sp);
- target.ModulesDidLoad (loaded_module_list);
- }
- }
- }
- }
-
- // If the current platform is PlatformDarwinKernel, create a ModuleSpec with the filename set
- // to be the bundle ID for this kext, e.g. "com.apple.filesystems.msdosfs", and ask the platform
- // to find it.
- PlatformSP platform_sp (target.GetPlatform());
- if (!m_module_sp && platform_sp)
- {
- ConstString platform_name (platform_sp->GetPluginName());
- static ConstString g_platform_name (PlatformDarwinKernel::GetPluginNameStatic());
- if (platform_name == g_platform_name)
- {
- ModuleSpec kext_bundle_module_spec(module_spec);
- FileSpec kext_filespec(m_name.c_str(), false);
- kext_bundle_module_spec.GetFileSpec() = kext_filespec;
- platform_sp->GetSharedModule (kext_bundle_module_spec, process, m_module_sp, &target.GetExecutableSearchPaths(), NULL, NULL);
- }
- }
-
- // Ask the Target to find this file on the local system, if possible.
- // This will search in the list of currently-loaded files, look in the
- // standard search paths on the system, and on a Mac it will try calling
- // the DebugSymbols framework with the UUID to find the binary via its
- // search methods.
- if (!m_module_sp)
- {
- m_module_sp = target.GetSharedModule (module_spec);
- }
-
- if (IsKernel() && !m_module_sp)
- {
- Stream *s = target.GetDebugger().GetOutputFile().get();
- if (s)
- {
- s->Printf ("WARNING: Unable to locate kernel binary on the debugger system.\n");
- }
+ }
+
+ if (!m_module_sp) {
+ // See if the kext has already been loaded into the target, probably by the
+ // user doing target modules add.
+ const ModuleList &target_images = target.GetImages();
+ m_module_sp = target_images.FindModule(m_uuid);
+
+ // Search for the kext on the local filesystem via the UUID
+ if (!m_module_sp && uuid_is_valid) {
+ ModuleSpec module_spec;
+ module_spec.GetUUID() = m_uuid;
+ module_spec.GetArchitecture() = target.GetArchitecture();
+
+ // For the kernel, we really do need an on-disk file copy of the binary to
+ // do anything useful.
+ // This will force a clal to
+ if (IsKernel()) {
+ if (Symbols::DownloadObjectAndSymbolFile(module_spec, true)) {
+ if (module_spec.GetFileSpec().Exists()) {
+ m_module_sp.reset(new Module(module_spec.GetFileSpec(),
+ target.GetArchitecture()));
+ if (m_module_sp.get() &&
+ m_module_sp->MatchesModuleSpec(module_spec)) {
+ ModuleList loaded_module_list;
+ loaded_module_list.Append(m_module_sp);
+ target.ModulesDidLoad(loaded_module_list);
}
+ }
}
-
- // If we managed to find a module, append it to the target's list of images.
- // If we also have a memory module, require that they have matching UUIDs
- if (m_module_sp)
- {
- bool uuid_match_ok = true;
- if (m_memory_module_sp)
- {
- if (m_module_sp->GetUUID() != m_memory_module_sp->GetUUID())
- {
- uuid_match_ok = false;
- }
- }
- if (uuid_match_ok)
- {
- target.GetImages().AppendIfNeeded(m_module_sp);
- if (IsKernel() && target.GetExecutableModulePointer() != m_module_sp.get())
- {
- target.SetExecutableModule (m_module_sp, false);
- }
- }
+ }
+
+ // If the current platform is PlatformDarwinKernel, create a ModuleSpec
+ // with the filename set
+ // to be the bundle ID for this kext, e.g.
+ // "com.apple.filesystems.msdosfs", and ask the platform
+ // to find it.
+ PlatformSP platform_sp(target.GetPlatform());
+ if (!m_module_sp && platform_sp) {
+ ConstString platform_name(platform_sp->GetPluginName());
+ static ConstString g_platform_name(
+ PlatformDarwinKernel::GetPluginNameStatic());
+ if (platform_name == g_platform_name) {
+ ModuleSpec kext_bundle_module_spec(module_spec);
+ FileSpec kext_filespec(m_name.c_str(), false);
+ kext_bundle_module_spec.GetFileSpec() = kext_filespec;
+ platform_sp->GetSharedModule(
+ kext_bundle_module_spec, process, m_module_sp,
+ &target.GetExecutableSearchPaths(), NULL, NULL);
}
- }
-
- if (!m_module_sp && !IsKernel() && m_uuid.IsValid() && !m_name.empty())
- {
+ }
+
+ // Ask the Target to find this file on the local system, if possible.
+ // This will search in the list of currently-loaded files, look in the
+ // standard search paths on the system, and on a Mac it will try calling
+ // the DebugSymbols framework with the UUID to find the binary via its
+ // search methods.
+ if (!m_module_sp) {
+ m_module_sp = target.GetSharedModule(module_spec);
+ }
+
+ if (IsKernel() && !m_module_sp) {
Stream *s = target.GetDebugger().GetOutputFile().get();
- if (s)
- {
- s->Printf ("warning: Can't find binary/dSYM for %s (%s)\n",
- m_name.c_str(), m_uuid.GetAsString().c_str());
+ if (s) {
+ s->Printf("WARNING: Unable to locate kernel binary on the debugger "
+ "system.\n");
}
+ }
}
- static ConstString g_section_name_LINKEDIT ("__LINKEDIT");
-
- if (m_memory_module_sp && m_module_sp)
- {
- if (m_module_sp->GetUUID() == m_memory_module_sp->GetUUID())
- {
- ObjectFile *ondisk_object_file = m_module_sp->GetObjectFile();
- ObjectFile *memory_object_file = m_memory_module_sp->GetObjectFile();
-
- if (memory_object_file && ondisk_object_file)
- {
- // The memory_module for kexts may have an invalid __LINKEDIT seg; skip it.
- const bool ignore_linkedit = !IsKernel ();
-
- SectionList *ondisk_section_list = ondisk_object_file->GetSectionList ();
- SectionList *memory_section_list = memory_object_file->GetSectionList ();
- if (memory_section_list && ondisk_section_list)
- {
- const uint32_t num_ondisk_sections = ondisk_section_list->GetSize();
- // There may be CTF sections in the memory image so we can't
- // always just compare the number of sections (which are actually
- // segments in mach-o parlance)
- uint32_t sect_idx = 0;
-
- // Use the memory_module's addresses for each section to set the
- // file module's load address as appropriate. We don't want to use
- // a single slide value for the entire kext - different segments may
- // be slid different amounts by the kext loader.
-
- uint32_t num_sections_loaded = 0;
- for (sect_idx=0; sect_idx<num_ondisk_sections; ++sect_idx)
- {
- SectionSP ondisk_section_sp(ondisk_section_list->GetSectionAtIndex(sect_idx));
- if (ondisk_section_sp)
- {
- // Don't ever load __LINKEDIT as it may or may not be actually
- // mapped into memory and there is no current way to tell.
- // I filed rdar://problem/12851706 to track being able to tell
- // if the __LINKEDIT is actually mapped, but until then, we need
- // to not load the __LINKEDIT
- if (ignore_linkedit && ondisk_section_sp->GetName() == g_section_name_LINKEDIT)
- continue;
-
- const Section *memory_section = memory_section_list->FindSectionByName(ondisk_section_sp->GetName()).get();
- if (memory_section)
- {
- target.SetSectionLoadAddress (ondisk_section_sp, memory_section->GetFileAddress());
- ++num_sections_loaded;
- }
- }
- }
- if (num_sections_loaded > 0)
- m_load_process_stop_id = process->GetStopID();
- else
- m_module_sp.reset(); // No sections were loaded
- }
- else
- m_module_sp.reset(); // One or both section lists
- }
- else
- m_module_sp.reset(); // One or both object files missing
+ // If we managed to find a module, append it to the target's list of images.
+ // If we also have a memory module, require that they have matching UUIDs
+ if (m_module_sp) {
+ bool uuid_match_ok = true;
+ if (m_memory_module_sp) {
+ if (m_module_sp->GetUUID() != m_memory_module_sp->GetUUID()) {
+ uuid_match_ok = false;
}
- else
- m_module_sp.reset(); // UUID mismatch
+ }
+ if (uuid_match_ok) {
+ target.GetImages().AppendIfNeeded(m_module_sp);
+ if (IsKernel() &&
+ target.GetExecutableModulePointer() != m_module_sp.get()) {
+ target.SetExecutableModule(m_module_sp, false);
+ }
+ }
}
+ }
- bool is_loaded = IsLoaded();
-
- if (is_loaded && m_module_sp && IsKernel())
- {
- Stream *s = target.GetDebugger().GetOutputFile().get();
- if (s)
- {
- ObjectFile *kernel_object_file = m_module_sp->GetObjectFile();
- if (kernel_object_file)
- {
- addr_t file_address = kernel_object_file->GetHeaderAddress().GetFileAddress();
- if (m_load_address != LLDB_INVALID_ADDRESS && file_address != LLDB_INVALID_ADDRESS)
- {
- s->Printf ("Kernel slid 0x%" PRIx64 " in memory.\n", m_load_address - file_address);
- }
- }
- {
- s->Printf ("Loaded kernel file %s\n",
- m_module_sp->GetFileSpec().GetPath().c_str());
+ if (!m_module_sp && !IsKernel() && m_uuid.IsValid() && !m_name.empty()) {
+ Stream *s = target.GetDebugger().GetOutputFile().get();
+ if (s) {
+ s->Printf("warning: Can't find binary/dSYM for %s (%s)\n", m_name.c_str(),
+ m_uuid.GetAsString().c_str());
+ }
+ }
+
+ static ConstString g_section_name_LINKEDIT("__LINKEDIT");
+
+ if (m_memory_module_sp && m_module_sp) {
+ if (m_module_sp->GetUUID() == m_memory_module_sp->GetUUID()) {
+ ObjectFile *ondisk_object_file = m_module_sp->GetObjectFile();
+ ObjectFile *memory_object_file = m_memory_module_sp->GetObjectFile();
+
+ if (memory_object_file && ondisk_object_file) {
+ // The memory_module for kexts may have an invalid __LINKEDIT seg; skip
+ // it.
+ const bool ignore_linkedit = !IsKernel();
+
+ SectionList *ondisk_section_list = ondisk_object_file->GetSectionList();
+ SectionList *memory_section_list = memory_object_file->GetSectionList();
+ if (memory_section_list && ondisk_section_list) {
+ const uint32_t num_ondisk_sections = ondisk_section_list->GetSize();
+ // There may be CTF sections in the memory image so we can't
+ // always just compare the number of sections (which are actually
+ // segments in mach-o parlance)
+ uint32_t sect_idx = 0;
+
+ // Use the memory_module's addresses for each section to set the
+ // file module's load address as appropriate. We don't want to use
+ // a single slide value for the entire kext - different segments may
+ // be slid different amounts by the kext loader.
+
+ uint32_t num_sections_loaded = 0;
+ for (sect_idx = 0; sect_idx < num_ondisk_sections; ++sect_idx) {
+ SectionSP ondisk_section_sp(
+ ondisk_section_list->GetSectionAtIndex(sect_idx));
+ if (ondisk_section_sp) {
+ // Don't ever load __LINKEDIT as it may or may not be actually
+ // mapped into memory and there is no current way to tell.
+ // I filed rdar://problem/12851706 to track being able to tell
+ // if the __LINKEDIT is actually mapped, but until then, we need
+ // to not load the __LINKEDIT
+ if (ignore_linkedit &&
+ ondisk_section_sp->GetName() == g_section_name_LINKEDIT)
+ continue;
+
+ const Section *memory_section =
+ memory_section_list
+ ->FindSectionByName(ondisk_section_sp->GetName())
+ .get();
+ if (memory_section) {
+ target.SetSectionLoadAddress(ondisk_section_sp,
+ memory_section->GetFileAddress());
+ ++num_sections_loaded;
+ }
}
- s->Flush ();
+ }
+ if (num_sections_loaded > 0)
+ m_load_process_stop_id = process->GetStopID();
+ else
+ m_module_sp.reset(); // No sections were loaded
+ } else
+ m_module_sp.reset(); // One or both section lists
+ } else
+ m_module_sp.reset(); // One or both object files missing
+ } else
+ m_module_sp.reset(); // UUID mismatch
+ }
+
+ bool is_loaded = IsLoaded();
+
+ if (is_loaded && m_module_sp && IsKernel()) {
+ Stream *s = target.GetDebugger().GetOutputFile().get();
+ if (s) {
+ ObjectFile *kernel_object_file = m_module_sp->GetObjectFile();
+ if (kernel_object_file) {
+ addr_t file_address =
+ kernel_object_file->GetHeaderAddress().GetFileAddress();
+ if (m_load_address != LLDB_INVALID_ADDRESS &&
+ file_address != LLDB_INVALID_ADDRESS) {
+ s->Printf("Kernel slid 0x%" PRIx64 " in memory.\n",
+ m_load_address - file_address);
}
+ }
+ {
+ s->Printf("Loaded kernel file %s\n",
+ m_module_sp->GetFileSpec().GetPath().c_str());
+ }
+ s->Flush();
}
- return is_loaded;
+ }
+ return is_loaded;
}
-uint32_t
-DynamicLoaderDarwinKernel::KextImageInfo::GetAddressByteSize ()
-{
- if (m_memory_module_sp)
- return m_memory_module_sp->GetArchitecture().GetAddressByteSize();
- if (m_module_sp)
- return m_module_sp->GetArchitecture().GetAddressByteSize();
- return 0;
+uint32_t DynamicLoaderDarwinKernel::KextImageInfo::GetAddressByteSize() {
+ if (m_memory_module_sp)
+ return m_memory_module_sp->GetArchitecture().GetAddressByteSize();
+ if (m_module_sp)
+ return m_module_sp->GetArchitecture().GetAddressByteSize();
+ return 0;
}
-lldb::ByteOrder
-DynamicLoaderDarwinKernel::KextImageInfo::GetByteOrder()
-{
- if (m_memory_module_sp)
- return m_memory_module_sp->GetArchitecture().GetByteOrder();
- if (m_module_sp)
- return m_module_sp->GetArchitecture().GetByteOrder();
- return endian::InlHostByteOrder();
+lldb::ByteOrder DynamicLoaderDarwinKernel::KextImageInfo::GetByteOrder() {
+ if (m_memory_module_sp)
+ return m_memory_module_sp->GetArchitecture().GetByteOrder();
+ if (m_module_sp)
+ return m_module_sp->GetArchitecture().GetByteOrder();
+ return endian::InlHostByteOrder();
}
lldb_private::ArchSpec
-DynamicLoaderDarwinKernel::KextImageInfo::GetArchitecture () const
-{
- if (m_memory_module_sp)
- return m_memory_module_sp->GetArchitecture();
- if (m_module_sp)
- return m_module_sp->GetArchitecture();
- return lldb_private::ArchSpec ();
+DynamicLoaderDarwinKernel::KextImageInfo::GetArchitecture() const {
+ if (m_memory_module_sp)
+ return m_memory_module_sp->GetArchitecture();
+ if (m_module_sp)
+ return m_module_sp->GetArchitecture();
+ return lldb_private::ArchSpec();
}
-
//----------------------------------------------------------------------
// Load the kernel module and initialize the "m_kernel" member. Return
// true _only_ if the kernel is loaded the first time through (subsequent
// calls to this function should return false after the kernel has been
// already loaded).
//----------------------------------------------------------------------
-void
-DynamicLoaderDarwinKernel::LoadKernelModuleIfNeeded()
-{
- if (!m_kext_summary_header_ptr_addr.IsValid())
- {
- m_kernel.Clear();
- m_kernel.SetModule (m_process->GetTarget().GetExecutableModule());
- m_kernel.SetIsKernel(true);
-
- ConstString kernel_name("mach_kernel");
- if (m_kernel.GetModule().get()
- && m_kernel.GetModule()->GetObjectFile()
- && !m_kernel.GetModule()->GetObjectFile()->GetFileSpec().GetFilename().IsEmpty())
- {
- kernel_name = m_kernel.GetModule()->GetObjectFile()->GetFileSpec().GetFilename();
- }
- m_kernel.SetName (kernel_name.AsCString());
-
- if (m_kernel.GetLoadAddress() == LLDB_INVALID_ADDRESS)
- {
- m_kernel.SetLoadAddress(m_kernel_load_address);
- if (m_kernel.GetLoadAddress() == LLDB_INVALID_ADDRESS && m_kernel.GetModule())
- {
- // We didn't get a hint from the process, so we will
- // try the kernel at the address that it exists at in
- // the file if we have one
- ObjectFile *kernel_object_file = m_kernel.GetModule()->GetObjectFile();
- if (kernel_object_file)
- {
- addr_t load_address = kernel_object_file->GetHeaderAddress().GetLoadAddress(&m_process->GetTarget());
- addr_t file_address = kernel_object_file->GetHeaderAddress().GetFileAddress();
- if (load_address != LLDB_INVALID_ADDRESS && load_address != 0)
- {
- m_kernel.SetLoadAddress (load_address);
- if (load_address != file_address)
- {
- // Don't accidentally relocate the kernel to the File address --
- // the Load address has already been set to its actual in-memory address.
- // Mark it as IsLoaded.
- m_kernel.SetProcessStopId (m_process->GetStopID());
- }
- }
- else
- {
- m_kernel.SetLoadAddress(file_address);
- }
- }
- }
- }
-
- if (m_kernel.GetLoadAddress() != LLDB_INVALID_ADDRESS)
- {
- if (!m_kernel.LoadImageUsingMemoryModule (m_process))
- {
- m_kernel.LoadImageAtFileAddress (m_process);
+void DynamicLoaderDarwinKernel::LoadKernelModuleIfNeeded() {
+ if (!m_kext_summary_header_ptr_addr.IsValid()) {
+ m_kernel.Clear();
+ m_kernel.SetModule(m_process->GetTarget().GetExecutableModule());
+ m_kernel.SetIsKernel(true);
+
+ ConstString kernel_name("mach_kernel");
+ if (m_kernel.GetModule().get() && m_kernel.GetModule()->GetObjectFile() &&
+ !m_kernel.GetModule()
+ ->GetObjectFile()
+ ->GetFileSpec()
+ .GetFilename()
+ .IsEmpty()) {
+ kernel_name =
+ m_kernel.GetModule()->GetObjectFile()->GetFileSpec().GetFilename();
+ }
+ m_kernel.SetName(kernel_name.AsCString());
+
+ if (m_kernel.GetLoadAddress() == LLDB_INVALID_ADDRESS) {
+ m_kernel.SetLoadAddress(m_kernel_load_address);
+ if (m_kernel.GetLoadAddress() == LLDB_INVALID_ADDRESS &&
+ m_kernel.GetModule()) {
+ // We didn't get a hint from the process, so we will
+ // try the kernel at the address that it exists at in
+ // the file if we have one
+ ObjectFile *kernel_object_file = m_kernel.GetModule()->GetObjectFile();
+ if (kernel_object_file) {
+ addr_t load_address =
+ kernel_object_file->GetHeaderAddress().GetLoadAddress(
+ &m_process->GetTarget());
+ addr_t file_address =
+ kernel_object_file->GetHeaderAddress().GetFileAddress();
+ if (load_address != LLDB_INVALID_ADDRESS && load_address != 0) {
+ m_kernel.SetLoadAddress(load_address);
+ if (load_address != file_address) {
+ // Don't accidentally relocate the kernel to the File address --
+ // the Load address has already been set to its actual in-memory
+ // address.
+ // Mark it as IsLoaded.
+ m_kernel.SetProcessStopId(m_process->GetStopID());
}
+ } else {
+ m_kernel.SetLoadAddress(file_address);
+ }
}
+ }
+ }
- if (m_kernel.IsLoaded() && m_kernel.GetModule())
- {
- static ConstString kext_summary_symbol ("gLoadedKextSummaries");
- const Symbol *symbol = m_kernel.GetModule()->FindFirstSymbolWithNameAndType (kext_summary_symbol, eSymbolTypeData);
- if (symbol)
- {
- m_kext_summary_header_ptr_addr = symbol->GetAddress();
- // Update all image infos
- ReadAllKextSummaries ();
- }
- }
- else
- {
- m_kernel.Clear();
- }
+ if (m_kernel.GetLoadAddress() != LLDB_INVALID_ADDRESS) {
+ if (!m_kernel.LoadImageUsingMemoryModule(m_process)) {
+ m_kernel.LoadImageAtFileAddress(m_process);
+ }
}
+
+ if (m_kernel.IsLoaded() && m_kernel.GetModule()) {
+ static ConstString kext_summary_symbol("gLoadedKextSummaries");
+ const Symbol *symbol =
+ m_kernel.GetModule()->FindFirstSymbolWithNameAndType(
+ kext_summary_symbol, eSymbolTypeData);
+ if (symbol) {
+ m_kext_summary_header_ptr_addr = symbol->GetAddress();
+ // Update all image infos
+ ReadAllKextSummaries();
+ }
+ } else {
+ m_kernel.Clear();
+ }
+ }
}
//----------------------------------------------------------------------
@@ -1105,591 +1012,531 @@ DynamicLoaderDarwinKernel::LoadKernelModuleIfNeeded()
// let our super class DynamicLoader class decide if we should stop
// or not (based on global preference).
//----------------------------------------------------------------------
-bool
-DynamicLoaderDarwinKernel::BreakpointHitCallback (void *baton,
- StoppointCallbackContext *context,
- user_id_t break_id,
- user_id_t break_loc_id)
-{
- return static_cast<DynamicLoaderDarwinKernel*>(baton)->BreakpointHit (context, break_id, break_loc_id);
+bool DynamicLoaderDarwinKernel::BreakpointHitCallback(
+ void *baton, StoppointCallbackContext *context, user_id_t break_id,
+ user_id_t break_loc_id) {
+ return static_cast<DynamicLoaderDarwinKernel *>(baton)->BreakpointHit(
+ context, break_id, break_loc_id);
}
-bool
-DynamicLoaderDarwinKernel::BreakpointHit (StoppointCallbackContext *context,
- user_id_t break_id,
- user_id_t break_loc_id)
-{
- Log *log(GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
- if (log)
- log->Printf ("DynamicLoaderDarwinKernel::BreakpointHit (...)\n");
+bool DynamicLoaderDarwinKernel::BreakpointHit(StoppointCallbackContext *context,
+ user_id_t break_id,
+ user_id_t break_loc_id) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+ if (log)
+ log->Printf("DynamicLoaderDarwinKernel::BreakpointHit (...)\n");
- ReadAllKextSummaries ();
-
- if (log)
- PutToLog(log);
+ ReadAllKextSummaries();
- return GetStopWhenImagesChange();
+ if (log)
+ PutToLog(log);
+
+ return GetStopWhenImagesChange();
}
+bool DynamicLoaderDarwinKernel::ReadKextSummaryHeader() {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+
+ // the all image infos is already valid for this process stop ID
-bool
-DynamicLoaderDarwinKernel::ReadKextSummaryHeader ()
-{
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
-
- // the all image infos is already valid for this process stop ID
-
- if (m_kext_summary_header_ptr_addr.IsValid())
- {
- const uint32_t addr_size = m_kernel.GetAddressByteSize ();
- const ByteOrder byte_order = m_kernel.GetByteOrder();
- Error error;
- // Read enough bytes for a "OSKextLoadedKextSummaryHeader" structure
- // which is currently 4 uint32_t and a pointer.
- uint8_t buf[24];
- DataExtractor data (buf, sizeof(buf), byte_order, addr_size);
- const size_t count = 4 * sizeof(uint32_t) + addr_size;
- const bool prefer_file_cache = false;
- if (m_process->GetTarget().ReadPointerFromMemory (m_kext_summary_header_ptr_addr,
- prefer_file_cache,
- error,
- m_kext_summary_header_addr))
- {
- // We got a valid address for our kext summary header and make sure it isn't NULL
- if (m_kext_summary_header_addr.IsValid() &&
- m_kext_summary_header_addr.GetFileAddress() != 0)
- {
- const size_t bytes_read = m_process->GetTarget().ReadMemory (m_kext_summary_header_addr, prefer_file_cache, buf, count, error);
- if (bytes_read == count)
- {
- lldb::offset_t offset = 0;
- m_kext_summary_header.version = data.GetU32(&offset);
- if (m_kext_summary_header.version > 128)
- {
- Stream *s = m_process->GetTarget().GetDebugger().GetOutputFile().get();
- s->Printf ("WARNING: Unable to read kext summary header, got improbable version number %u\n", m_kext_summary_header.version);
- // If we get an improbably large version number, we're probably getting bad memory.
- m_kext_summary_header_addr.Clear();
- return false;
- }
- if (m_kext_summary_header.version >= 2)
- {
- m_kext_summary_header.entry_size = data.GetU32(&offset);
- if (m_kext_summary_header.entry_size > 4096)
- {
- // If we get an improbably large entry_size, we're probably getting bad memory.
- Stream *s = m_process->GetTarget().GetDebugger().GetOutputFile().get();
- s->Printf ("WARNING: Unable to read kext summary header, got improbable entry_size %u\n", m_kext_summary_header.entry_size);
- m_kext_summary_header_addr.Clear();
- return false;
- }
- }
- else
- {
- // Versions less than 2 didn't have an entry size, it was hard coded
- m_kext_summary_header.entry_size = KERNEL_MODULE_ENTRY_SIZE_VERSION_1;
- }
- m_kext_summary_header.entry_count = data.GetU32(&offset);
- if (m_kext_summary_header.entry_count > 10000)
- {
- // If we get an improbably large number of kexts, we're probably getting bad memory.
- Stream *s = m_process->GetTarget().GetDebugger().GetOutputFile().get();
- s->Printf ("WARNING: Unable to read kext summary header, got improbable number of kexts %u\n", m_kext_summary_header.entry_count);
- m_kext_summary_header_addr.Clear();
- return false;
- }
- return true;
- }
+ if (m_kext_summary_header_ptr_addr.IsValid()) {
+ const uint32_t addr_size = m_kernel.GetAddressByteSize();
+ const ByteOrder byte_order = m_kernel.GetByteOrder();
+ Error error;
+ // Read enough bytes for a "OSKextLoadedKextSummaryHeader" structure
+ // which is currently 4 uint32_t and a pointer.
+ uint8_t buf[24];
+ DataExtractor data(buf, sizeof(buf), byte_order, addr_size);
+ const size_t count = 4 * sizeof(uint32_t) + addr_size;
+ const bool prefer_file_cache = false;
+ if (m_process->GetTarget().ReadPointerFromMemory(
+ m_kext_summary_header_ptr_addr, prefer_file_cache, error,
+ m_kext_summary_header_addr)) {
+ // We got a valid address for our kext summary header and make sure it
+ // isn't NULL
+ if (m_kext_summary_header_addr.IsValid() &&
+ m_kext_summary_header_addr.GetFileAddress() != 0) {
+ const size_t bytes_read = m_process->GetTarget().ReadMemory(
+ m_kext_summary_header_addr, prefer_file_cache, buf, count, error);
+ if (bytes_read == count) {
+ lldb::offset_t offset = 0;
+ m_kext_summary_header.version = data.GetU32(&offset);
+ if (m_kext_summary_header.version > 128) {
+ Stream *s =
+ m_process->GetTarget().GetDebugger().GetOutputFile().get();
+ s->Printf("WARNING: Unable to read kext summary header, got "
+ "improbable version number %u\n",
+ m_kext_summary_header.version);
+ // If we get an improbably large version number, we're probably
+ // getting bad memory.
+ m_kext_summary_header_addr.Clear();
+ return false;
+ }
+ if (m_kext_summary_header.version >= 2) {
+ m_kext_summary_header.entry_size = data.GetU32(&offset);
+ if (m_kext_summary_header.entry_size > 4096) {
+ // If we get an improbably large entry_size, we're probably
+ // getting bad memory.
+ Stream *s =
+ m_process->GetTarget().GetDebugger().GetOutputFile().get();
+ s->Printf("WARNING: Unable to read kext summary header, got "
+ "improbable entry_size %u\n",
+ m_kext_summary_header.entry_size);
+ m_kext_summary_header_addr.Clear();
+ return false;
}
+ } else {
+ // Versions less than 2 didn't have an entry size, it was hard coded
+ m_kext_summary_header.entry_size =
+ KERNEL_MODULE_ENTRY_SIZE_VERSION_1;
+ }
+ m_kext_summary_header.entry_count = data.GetU32(&offset);
+ if (m_kext_summary_header.entry_count > 10000) {
+ // If we get an improbably large number of kexts, we're probably
+ // getting bad memory.
+ Stream *s =
+ m_process->GetTarget().GetDebugger().GetOutputFile().get();
+ s->Printf("WARNING: Unable to read kext summary header, got "
+ "improbable number of kexts %u\n",
+ m_kext_summary_header.entry_count);
+ m_kext_summary_header_addr.Clear();
+ return false;
+ }
+ return true;
}
+ }
}
- m_kext_summary_header_addr.Clear();
- return false;
+ }
+ m_kext_summary_header_addr.Clear();
+ return false;
}
-// We've either (a) just attached to a new kernel, or (b) the kexts-changed breakpoint was hit
+// We've either (a) just attached to a new kernel, or (b) the kexts-changed
+// breakpoint was hit
// and we need to figure out what kexts have been added or removed.
-// Read the kext summaries from the inferior kernel memory, compare them against the
-// m_known_kexts vector and update the m_known_kexts vector as needed to keep in sync with the
+// Read the kext summaries from the inferior kernel memory, compare them against
+// the
+// m_known_kexts vector and update the m_known_kexts vector as needed to keep in
+// sync with the
// inferior.
-bool
-DynamicLoaderDarwinKernel::ParseKextSummaries (const Address &kext_summary_addr, uint32_t count)
-{
- KextImageInfo::collection kext_summaries;
- Log *log(GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
- if (log)
- log->Printf ("Kexts-changed breakpoint hit, there are %d kexts currently.\n", count);
-
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
+bool DynamicLoaderDarwinKernel::ParseKextSummaries(
+ const Address &kext_summary_addr, uint32_t count) {
+ KextImageInfo::collection kext_summaries;
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+ if (log)
+ log->Printf("Kexts-changed breakpoint hit, there are %d kexts currently.\n",
+ count);
- if (!ReadKextSummaries (kext_summary_addr, count, kext_summaries))
- return false;
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
- // read the plugin.dynamic-loader.darwin-kernel.load-kexts setting -- if the user requested no
- // kext loading, don't print any messages about kexts & don't try to read them.
- const bool load_kexts = GetGlobalProperties()->GetLoadKexts();
-
- // By default, all kexts we've loaded in the past are marked as "remove" and all of the kexts
- // we just found out about from ReadKextSummaries are marked as "add".
- std::vector<bool> to_be_removed(m_known_kexts.size(), true);
- std::vector<bool> to_be_added(count, true);
-
- int number_of_new_kexts_being_added = 0;
- int number_of_old_kexts_being_removed = m_known_kexts.size();
-
- const uint32_t new_kexts_size = kext_summaries.size();
- const uint32_t old_kexts_size = m_known_kexts.size();
-
- // The m_known_kexts vector may have entries that have been Cleared,
- // or are a kernel.
- for (uint32_t old_kext = 0; old_kext < old_kexts_size; old_kext++)
- {
- bool ignore = false;
- KextImageInfo &image_info = m_known_kexts[old_kext];
- if (image_info.IsKernel())
- {
- ignore = true;
- }
- else if (image_info.GetLoadAddress() == LLDB_INVALID_ADDRESS && !image_info.GetModule())
- {
- ignore = true;
- }
+ if (!ReadKextSummaries(kext_summary_addr, count, kext_summaries))
+ return false;
- if (ignore)
- {
- number_of_old_kexts_being_removed--;
- to_be_removed[old_kext] = false;
- }
+ // read the plugin.dynamic-loader.darwin-kernel.load-kexts setting -- if the
+ // user requested no
+ // kext loading, don't print any messages about kexts & don't try to read
+ // them.
+ const bool load_kexts = GetGlobalProperties()->GetLoadKexts();
+
+ // By default, all kexts we've loaded in the past are marked as "remove" and
+ // all of the kexts
+ // we just found out about from ReadKextSummaries are marked as "add".
+ std::vector<bool> to_be_removed(m_known_kexts.size(), true);
+ std::vector<bool> to_be_added(count, true);
+
+ int number_of_new_kexts_being_added = 0;
+ int number_of_old_kexts_being_removed = m_known_kexts.size();
+
+ const uint32_t new_kexts_size = kext_summaries.size();
+ const uint32_t old_kexts_size = m_known_kexts.size();
+
+ // The m_known_kexts vector may have entries that have been Cleared,
+ // or are a kernel.
+ for (uint32_t old_kext = 0; old_kext < old_kexts_size; old_kext++) {
+ bool ignore = false;
+ KextImageInfo &image_info = m_known_kexts[old_kext];
+ if (image_info.IsKernel()) {
+ ignore = true;
+ } else if (image_info.GetLoadAddress() == LLDB_INVALID_ADDRESS &&
+ !image_info.GetModule()) {
+ ignore = true;
}
- // Scan over the list of kexts we just read from the kernel, note those that
- // need to be added and those already loaded.
- for (uint32_t new_kext = 0; new_kext < new_kexts_size; new_kext++)
- {
- bool add_this_one = true;
- for (uint32_t old_kext = 0; old_kext < old_kexts_size; old_kext++)
- {
- if (m_known_kexts[old_kext] == kext_summaries[new_kext])
- {
- // We already have this kext, don't re-load it.
- to_be_added[new_kext] = false;
- // This kext is still present, do not remove it.
- to_be_removed[old_kext] = false;
-
- number_of_old_kexts_being_removed--;
- add_this_one = false;
- break;
- }
- }
- if (add_this_one)
- {
- number_of_new_kexts_being_added++;
- }
+ if (ignore) {
+ number_of_old_kexts_being_removed--;
+ to_be_removed[old_kext] = false;
}
-
- if (number_of_new_kexts_being_added == 0 && number_of_old_kexts_being_removed == 0)
- return true;
-
- Stream *s = m_process->GetTarget().GetDebugger().GetOutputFile().get();
- if (s && load_kexts)
- {
- if (number_of_new_kexts_being_added > 0 && number_of_old_kexts_being_removed > 0)
- {
- s->Printf ("Loading %d kext modules and unloading %d kext modules ", number_of_new_kexts_being_added, number_of_old_kexts_being_removed);
- }
- else if (number_of_new_kexts_being_added > 0)
- {
- s->Printf ("Loading %d kext modules ", number_of_new_kexts_being_added);
- }
- else if (number_of_old_kexts_being_removed > 0)
- {
- s->Printf ("Unloading %d kext modules ", number_of_old_kexts_being_removed);
- }
+ }
+
+ // Scan over the list of kexts we just read from the kernel, note those that
+ // need to be added and those already loaded.
+ for (uint32_t new_kext = 0; new_kext < new_kexts_size; new_kext++) {
+ bool add_this_one = true;
+ for (uint32_t old_kext = 0; old_kext < old_kexts_size; old_kext++) {
+ if (m_known_kexts[old_kext] == kext_summaries[new_kext]) {
+ // We already have this kext, don't re-load it.
+ to_be_added[new_kext] = false;
+ // This kext is still present, do not remove it.
+ to_be_removed[old_kext] = false;
+
+ number_of_old_kexts_being_removed--;
+ add_this_one = false;
+ break;
+ }
}
-
- if (log)
- {
- if (load_kexts)
- {
- log->Printf ("DynamicLoaderDarwinKernel::ParseKextSummaries: %d kexts added, %d kexts removed", number_of_new_kexts_being_added, number_of_old_kexts_being_removed);
- }
- else
- {
- log->Printf ("DynamicLoaderDarwinKernel::ParseKextSummaries kext loading is disabled, else would have %d kexts added, %d kexts removed", number_of_new_kexts_being_added, number_of_old_kexts_being_removed);
- }
+ if (add_this_one) {
+ number_of_new_kexts_being_added++;
}
+ }
+ if (number_of_new_kexts_being_added == 0 &&
+ number_of_old_kexts_being_removed == 0)
+ return true;
- if (number_of_new_kexts_being_added > 0)
- {
- ModuleList loaded_module_list;
-
- const uint32_t num_of_new_kexts = kext_summaries.size();
- for (uint32_t new_kext = 0; new_kext < num_of_new_kexts; new_kext++)
- {
- if (to_be_added[new_kext] == true)
- {
- KextImageInfo &image_info = kext_summaries[new_kext];
- if (load_kexts)
- {
- if (!image_info.LoadImageUsingMemoryModule (m_process))
- {
- image_info.LoadImageAtFileAddress (m_process);
- }
- }
+ Stream *s = m_process->GetTarget().GetDebugger().GetOutputFile().get();
+ if (s && load_kexts) {
+ if (number_of_new_kexts_being_added > 0 &&
+ number_of_old_kexts_being_removed > 0) {
+ s->Printf("Loading %d kext modules and unloading %d kext modules ",
+ number_of_new_kexts_being_added,
+ number_of_old_kexts_being_removed);
+ } else if (number_of_new_kexts_being_added > 0) {
+ s->Printf("Loading %d kext modules ", number_of_new_kexts_being_added);
+ } else if (number_of_old_kexts_being_removed > 0) {
+ s->Printf("Unloading %d kext modules ",
+ number_of_old_kexts_being_removed);
+ }
+ }
+
+ if (log) {
+ if (load_kexts) {
+ log->Printf("DynamicLoaderDarwinKernel::ParseKextSummaries: %d kexts "
+ "added, %d kexts removed",
+ number_of_new_kexts_being_added,
+ number_of_old_kexts_being_removed);
+ } else {
+ log->Printf(
+ "DynamicLoaderDarwinKernel::ParseKextSummaries kext loading is "
+ "disabled, else would have %d kexts added, %d kexts removed",
+ number_of_new_kexts_being_added, number_of_old_kexts_being_removed);
+ }
+ }
+
+ if (number_of_new_kexts_being_added > 0) {
+ ModuleList loaded_module_list;
+
+ const uint32_t num_of_new_kexts = kext_summaries.size();
+ for (uint32_t new_kext = 0; new_kext < num_of_new_kexts; new_kext++) {
+ if (to_be_added[new_kext] == true) {
+ KextImageInfo &image_info = kext_summaries[new_kext];
+ if (load_kexts) {
+ if (!image_info.LoadImageUsingMemoryModule(m_process)) {
+ image_info.LoadImageAtFileAddress(m_process);
+ }
+ }
- m_known_kexts.push_back(image_info);
+ m_known_kexts.push_back(image_info);
- if (image_info.GetModule() && m_process->GetStopID() == image_info.GetProcessStopId())
- loaded_module_list.AppendIfNeeded (image_info.GetModule());
+ if (image_info.GetModule() &&
+ m_process->GetStopID() == image_info.GetProcessStopId())
+ loaded_module_list.AppendIfNeeded(image_info.GetModule());
- if (s && load_kexts)
- s->Printf (".");
+ if (s && load_kexts)
+ s->Printf(".");
- if (log)
- kext_summaries[new_kext].PutToLog (log);
- }
- }
- m_process->GetTarget().ModulesDidLoad (loaded_module_list);
+ if (log)
+ kext_summaries[new_kext].PutToLog(log);
+ }
}
-
- if (number_of_old_kexts_being_removed > 0)
- {
- ModuleList loaded_module_list;
- const uint32_t num_of_old_kexts = m_known_kexts.size();
- for (uint32_t old_kext = 0; old_kext < num_of_old_kexts; old_kext++)
- {
- ModuleList unloaded_module_list;
- if (to_be_removed[old_kext])
- {
- KextImageInfo &image_info = m_known_kexts[old_kext];
- // You can't unload the kernel.
- if (!image_info.IsKernel())
- {
- if (image_info.GetModule())
- {
- unloaded_module_list.AppendIfNeeded (image_info.GetModule());
- }
- if (s)
- s->Printf (".");
- image_info.Clear();
- // should pull it out of the KextImageInfos vector but that would mutate the list and invalidate
- // the to_be_removed bool vector; leaving it in place once Cleared() is relatively harmless.
- }
- }
- m_process->GetTarget().ModulesDidUnload (unloaded_module_list, false);
+ m_process->GetTarget().ModulesDidLoad(loaded_module_list);
+ }
+
+ if (number_of_old_kexts_being_removed > 0) {
+ ModuleList loaded_module_list;
+ const uint32_t num_of_old_kexts = m_known_kexts.size();
+ for (uint32_t old_kext = 0; old_kext < num_of_old_kexts; old_kext++) {
+ ModuleList unloaded_module_list;
+ if (to_be_removed[old_kext]) {
+ KextImageInfo &image_info = m_known_kexts[old_kext];
+ // You can't unload the kernel.
+ if (!image_info.IsKernel()) {
+ if (image_info.GetModule()) {
+ unloaded_module_list.AppendIfNeeded(image_info.GetModule());
+ }
+ if (s)
+ s->Printf(".");
+ image_info.Clear();
+ // should pull it out of the KextImageInfos vector but that would
+ // mutate the list and invalidate
+ // the to_be_removed bool vector; leaving it in place once Cleared()
+ // is relatively harmless.
}
+ }
+ m_process->GetTarget().ModulesDidUnload(unloaded_module_list, false);
}
+ }
- if (s && load_kexts)
- {
- s->Printf (" done.\n");
- s->Flush ();
- }
+ if (s && load_kexts) {
+ s->Printf(" done.\n");
+ s->Flush();
+ }
- return true;
+ return true;
}
-uint32_t
-DynamicLoaderDarwinKernel::ReadKextSummaries (const Address &kext_summary_addr,
- uint32_t image_infos_count,
- KextImageInfo::collection &image_infos)
-{
- const ByteOrder endian = m_kernel.GetByteOrder();
- const uint32_t addr_size = m_kernel.GetAddressByteSize();
-
- image_infos.resize(image_infos_count);
- const size_t count = image_infos.size() * m_kext_summary_header.entry_size;
- DataBufferHeap data(count, 0);
- Error error;
-
- const bool prefer_file_cache = false;
- const size_t bytes_read = m_process->GetTarget().ReadMemory (kext_summary_addr,
- prefer_file_cache,
- data.GetBytes(),
- data.GetByteSize(),
- error);
- if (bytes_read == count)
- {
-
- DataExtractor extractor (data.GetBytes(), data.GetByteSize(), endian, addr_size);
- uint32_t i=0;
- for (uint32_t kext_summary_offset = 0;
- i < image_infos.size() && extractor.ValidOffsetForDataOfSize(kext_summary_offset, m_kext_summary_header.entry_size);
- ++i, kext_summary_offset += m_kext_summary_header.entry_size)
- {
- lldb::offset_t offset = kext_summary_offset;
- const void *name_data = extractor.GetData(&offset, KERNEL_MODULE_MAX_NAME);
- if (name_data == NULL)
- break;
- image_infos[i].SetName ((const char *) name_data);
- UUID uuid (extractor.GetData (&offset, 16), 16);
- image_infos[i].SetUUID (uuid);
- image_infos[i].SetLoadAddress (extractor.GetU64(&offset));
- image_infos[i].SetSize (extractor.GetU64(&offset));
- }
- if (i < image_infos.size())
- image_infos.resize(i);
- }
- else
- {
- image_infos.clear();
+uint32_t DynamicLoaderDarwinKernel::ReadKextSummaries(
+ const Address &kext_summary_addr, uint32_t image_infos_count,
+ KextImageInfo::collection &image_infos) {
+ const ByteOrder endian = m_kernel.GetByteOrder();
+ const uint32_t addr_size = m_kernel.GetAddressByteSize();
+
+ image_infos.resize(image_infos_count);
+ const size_t count = image_infos.size() * m_kext_summary_header.entry_size;
+ DataBufferHeap data(count, 0);
+ Error error;
+
+ const bool prefer_file_cache = false;
+ const size_t bytes_read = m_process->GetTarget().ReadMemory(
+ kext_summary_addr, prefer_file_cache, data.GetBytes(), data.GetByteSize(),
+ error);
+ if (bytes_read == count) {
+
+ DataExtractor extractor(data.GetBytes(), data.GetByteSize(), endian,
+ addr_size);
+ uint32_t i = 0;
+ for (uint32_t kext_summary_offset = 0;
+ i < image_infos.size() &&
+ extractor.ValidOffsetForDataOfSize(kext_summary_offset,
+ m_kext_summary_header.entry_size);
+ ++i, kext_summary_offset += m_kext_summary_header.entry_size) {
+ lldb::offset_t offset = kext_summary_offset;
+ const void *name_data =
+ extractor.GetData(&offset, KERNEL_MODULE_MAX_NAME);
+ if (name_data == NULL)
+ break;
+ image_infos[i].SetName((const char *)name_data);
+ UUID uuid(extractor.GetData(&offset, 16), 16);
+ image_infos[i].SetUUID(uuid);
+ image_infos[i].SetLoadAddress(extractor.GetU64(&offset));
+ image_infos[i].SetSize(extractor.GetU64(&offset));
}
- return image_infos.size();
+ if (i < image_infos.size())
+ image_infos.resize(i);
+ } else {
+ image_infos.clear();
+ }
+ return image_infos.size();
}
-bool
-DynamicLoaderDarwinKernel::ReadAllKextSummaries ()
-{
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
-
- if (ReadKextSummaryHeader ())
- {
- if (m_kext_summary_header.entry_count > 0 && m_kext_summary_header_addr.IsValid())
- {
- Address summary_addr (m_kext_summary_header_addr);
- summary_addr.Slide(m_kext_summary_header.GetSize());
- if (!ParseKextSummaries (summary_addr, m_kext_summary_header.entry_count))
- {
- m_known_kexts.clear();
- }
- return true;
- }
+bool DynamicLoaderDarwinKernel::ReadAllKextSummaries() {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+
+ if (ReadKextSummaryHeader()) {
+ if (m_kext_summary_header.entry_count > 0 &&
+ m_kext_summary_header_addr.IsValid()) {
+ Address summary_addr(m_kext_summary_header_addr);
+ summary_addr.Slide(m_kext_summary_header.GetSize());
+ if (!ParseKextSummaries(summary_addr,
+ m_kext_summary_header.entry_count)) {
+ m_known_kexts.clear();
+ }
+ return true;
}
- return false;
+ }
+ return false;
}
//----------------------------------------------------------------------
// Dump an image info structure to the file handle provided.
//----------------------------------------------------------------------
-void
-DynamicLoaderDarwinKernel::KextImageInfo::PutToLog (Log *log) const
-{
- if (log == NULL)
- return;
- const uint8_t *u = (uint8_t *) m_uuid.GetBytes();
-
- if (m_load_address == LLDB_INVALID_ADDRESS)
- {
- if (u)
- {
- log->Printf("\tuuid=%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 name=\"%s\" (UNLOADED)",
- u[ 0], u[ 1], u[ 2], u[ 3],
- u[ 4], u[ 5], u[ 6], u[ 7],
- u[ 8], u[ 9], u[10], u[11],
- u[12], u[13], u[14], u[15],
- m_name.c_str());
- }
- else
- log->Printf("\tname=\"%s\" (UNLOADED)", m_name.c_str());
- }
- else
- {
- if (u)
- {
- log->Printf("\taddr=0x%16.16" PRIx64 " size=0x%16.16" 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 name=\"%s\"",
- m_load_address, m_size,
- u[ 0], u[ 1], u[ 2], u[ 3], u[ 4], u[ 5], u[ 6], u[ 7],
- u[ 8], u[ 9], u[10], u[11], u[12], u[13], u[14], u[15],
- m_name.c_str());
- }
- else
- {
- log->Printf("\t[0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ") name=\"%s\"",
- m_load_address, m_load_address+m_size, m_name.c_str());
- }
+void DynamicLoaderDarwinKernel::KextImageInfo::PutToLog(Log *log) const {
+ if (log == NULL)
+ return;
+ const uint8_t *u = (uint8_t *)m_uuid.GetBytes();
+
+ if (m_load_address == LLDB_INVALID_ADDRESS) {
+ if (u) {
+ log->Printf("\tuuid=%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 name=\"%s\" (UNLOADED)",
+ u[0], u[1], u[2], u[3], u[4], u[5], u[6], u[7], u[8], u[9],
+ u[10], u[11], u[12], u[13], u[14], u[15], m_name.c_str());
+ } else
+ log->Printf("\tname=\"%s\" (UNLOADED)", m_name.c_str());
+ } else {
+ if (u) {
+ log->Printf("\taddr=0x%16.16" PRIx64 " size=0x%16.16" 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 name=\"%s\"",
+ m_load_address, m_size, u[0], u[1], u[2], u[3], u[4], u[5],
+ u[6], u[7], u[8], u[9], u[10], u[11], u[12], u[13], u[14],
+ u[15], m_name.c_str());
+ } else {
+ log->Printf("\t[0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ") name=\"%s\"",
+ m_load_address, m_load_address + m_size, m_name.c_str());
}
+ }
}
//----------------------------------------------------------------------
// Dump the _dyld_all_image_infos members and all current image infos
// that we have parsed to the file handle provided.
//----------------------------------------------------------------------
-void
-DynamicLoaderDarwinKernel::PutToLog(Log *log) const
-{
- if (log == NULL)
- return;
-
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- log->Printf("gLoadedKextSummaries = 0x%16.16" PRIx64 " { version=%u, entry_size=%u, entry_count=%u }",
- m_kext_summary_header_addr.GetFileAddress(),
- m_kext_summary_header.version,
- m_kext_summary_header.entry_size,
- m_kext_summary_header.entry_count);
-
- size_t i;
- const size_t count = m_known_kexts.size();
- if (count > 0)
- {
- log->PutCString("Loaded:");
- for (i = 0; i<count; i++)
- m_known_kexts[i].PutToLog(log);
- }
+void DynamicLoaderDarwinKernel::PutToLog(Log *log) const {
+ if (log == NULL)
+ return;
+
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ log->Printf("gLoadedKextSummaries = 0x%16.16" PRIx64
+ " { version=%u, entry_size=%u, entry_count=%u }",
+ m_kext_summary_header_addr.GetFileAddress(),
+ m_kext_summary_header.version, m_kext_summary_header.entry_size,
+ m_kext_summary_header.entry_count);
+
+ size_t i;
+ const size_t count = m_known_kexts.size();
+ if (count > 0) {
+ log->PutCString("Loaded:");
+ for (i = 0; i < count; i++)
+ m_known_kexts[i].PutToLog(log);
+ }
}
-void
-DynamicLoaderDarwinKernel::PrivateInitialize(Process *process)
-{
- DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState()));
- Clear(true);
- m_process = process;
+void DynamicLoaderDarwinKernel::PrivateInitialize(Process *process) {
+ DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s() process state = %s\n",
+ __FUNCTION__, StateAsCString(m_process->GetState()));
+ Clear(true);
+ m_process = process;
}
-void
-DynamicLoaderDarwinKernel::SetNotificationBreakpointIfNeeded ()
-{
- if (m_break_id == LLDB_INVALID_BREAK_ID && m_kernel.GetModule())
- {
- DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState()));
-
-
- const bool internal_bp = true;
- const bool hardware = false;
- const LazyBool skip_prologue = eLazyBoolNo;
- FileSpecList module_spec_list;
- module_spec_list.Append (m_kernel.GetModule()->GetFileSpec());
- Breakpoint *bp = m_process->GetTarget().CreateBreakpoint (&module_spec_list,
- NULL,
- "OSKextLoadedKextSummariesUpdated",
- eFunctionNameTypeFull,
- eLanguageTypeUnknown,
- 0,
- skip_prologue,
- internal_bp,
- hardware).get();
-
- bp->SetCallback (DynamicLoaderDarwinKernel::BreakpointHitCallback, this, true);
- m_break_id = bp->GetID();
- }
+void DynamicLoaderDarwinKernel::SetNotificationBreakpointIfNeeded() {
+ if (m_break_id == LLDB_INVALID_BREAK_ID && m_kernel.GetModule()) {
+ DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s() process state = %s\n",
+ __FUNCTION__, StateAsCString(m_process->GetState()));
+
+ const bool internal_bp = true;
+ const bool hardware = false;
+ const LazyBool skip_prologue = eLazyBoolNo;
+ FileSpecList module_spec_list;
+ module_spec_list.Append(m_kernel.GetModule()->GetFileSpec());
+ Breakpoint *bp =
+ m_process->GetTarget()
+ .CreateBreakpoint(&module_spec_list, NULL,
+ "OSKextLoadedKextSummariesUpdated",
+ eFunctionNameTypeFull, eLanguageTypeUnknown, 0,
+ skip_prologue, internal_bp, hardware)
+ .get();
+
+ bp->SetCallback(DynamicLoaderDarwinKernel::BreakpointHitCallback, this,
+ true);
+ m_break_id = bp->GetID();
+ }
}
//----------------------------------------------------------------------
// Member function that gets called when the process state changes.
//----------------------------------------------------------------------
-void
-DynamicLoaderDarwinKernel::PrivateProcessStateChanged (Process *process, StateType state)
-{
- DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s(%s)\n", __FUNCTION__, StateAsCString(state));
- switch (state)
- {
- case eStateConnected:
- case eStateAttaching:
- case eStateLaunching:
- case eStateInvalid:
- case eStateUnloaded:
- case eStateExited:
- case eStateDetached:
- Clear(false);
- break;
-
- case eStateStopped:
- UpdateIfNeeded();
- break;
-
- case eStateRunning:
- case eStateStepping:
- case eStateCrashed:
- case eStateSuspended:
- break;
- }
+void DynamicLoaderDarwinKernel::PrivateProcessStateChanged(Process *process,
+ StateType state) {
+ DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s(%s)\n", __FUNCTION__,
+ StateAsCString(state));
+ switch (state) {
+ case eStateConnected:
+ case eStateAttaching:
+ case eStateLaunching:
+ case eStateInvalid:
+ case eStateUnloaded:
+ case eStateExited:
+ case eStateDetached:
+ Clear(false);
+ break;
+
+ case eStateStopped:
+ UpdateIfNeeded();
+ break;
+
+ case eStateRunning:
+ case eStateStepping:
+ case eStateCrashed:
+ case eStateSuspended:
+ break;
+ }
}
ThreadPlanSP
-DynamicLoaderDarwinKernel::GetStepThroughTrampolinePlan (Thread &thread, bool stop_others)
-{
- ThreadPlanSP thread_plan_sp;
- Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
- if (log)
- log->Printf ("Could not find symbol for step through.");
- return thread_plan_sp;
+DynamicLoaderDarwinKernel::GetStepThroughTrampolinePlan(Thread &thread,
+ bool stop_others) {
+ ThreadPlanSP thread_plan_sp;
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
+ if (log)
+ log->Printf("Could not find symbol for step through.");
+ return thread_plan_sp;
}
-Error
-DynamicLoaderDarwinKernel::CanLoadImage ()
-{
- Error error;
- error.SetErrorString("always unsafe to load or unload shared libraries in the darwin kernel");
- return error;
+Error DynamicLoaderDarwinKernel::CanLoadImage() {
+ Error error;
+ error.SetErrorString(
+ "always unsafe to load or unload shared libraries in the darwin kernel");
+ return error;
}
-void
-DynamicLoaderDarwinKernel::Initialize()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- GetPluginDescriptionStatic(),
- CreateInstance,
- DebuggerInitialize);
+void DynamicLoaderDarwinKernel::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance,
+ DebuggerInitialize);
}
-void
-DynamicLoaderDarwinKernel::Terminate()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
+void DynamicLoaderDarwinKernel::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
}
-void
-DynamicLoaderDarwinKernel::DebuggerInitialize (lldb_private::Debugger &debugger)
-{
- if (!PluginManager::GetSettingForDynamicLoaderPlugin (debugger, DynamicLoaderDarwinKernelProperties::GetSettingName()))
- {
- const bool is_global_setting = true;
- PluginManager::CreateSettingForDynamicLoaderPlugin (debugger,
- GetGlobalProperties()->GetValueProperties(),
- ConstString ("Properties for the DynamicLoaderDarwinKernel plug-in."),
- is_global_setting);
- }
+void DynamicLoaderDarwinKernel::DebuggerInitialize(
+ lldb_private::Debugger &debugger) {
+ if (!PluginManager::GetSettingForDynamicLoaderPlugin(
+ debugger, DynamicLoaderDarwinKernelProperties::GetSettingName())) {
+ const bool is_global_setting = true;
+ PluginManager::CreateSettingForDynamicLoaderPlugin(
+ debugger, GetGlobalProperties()->GetValueProperties(),
+ ConstString("Properties for the DynamicLoaderDarwinKernel plug-in."),
+ is_global_setting);
+ }
}
-lldb_private::ConstString
-DynamicLoaderDarwinKernel::GetPluginNameStatic()
-{
- static ConstString g_name("darwin-kernel");
- return g_name;
+lldb_private::ConstString DynamicLoaderDarwinKernel::GetPluginNameStatic() {
+ static ConstString g_name("darwin-kernel");
+ return g_name;
}
-const char *
-DynamicLoaderDarwinKernel::GetPluginDescriptionStatic()
-{
- return "Dynamic loader plug-in that watches for shared library loads/unloads in the MacOSX kernel.";
+const char *DynamicLoaderDarwinKernel::GetPluginDescriptionStatic() {
+ return "Dynamic loader plug-in that watches for shared library loads/unloads "
+ "in the MacOSX kernel.";
}
-
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
-lldb_private::ConstString
-DynamicLoaderDarwinKernel::GetPluginName()
-{
- return GetPluginNameStatic();
+lldb_private::ConstString DynamicLoaderDarwinKernel::GetPluginName() {
+ return GetPluginNameStatic();
}
-uint32_t
-DynamicLoaderDarwinKernel::GetPluginVersion()
-{
- return 1;
-}
+uint32_t DynamicLoaderDarwinKernel::GetPluginVersion() { return 1; }
lldb::ByteOrder
-DynamicLoaderDarwinKernel::GetByteOrderFromMagic (uint32_t magic)
-{
- switch (magic)
- {
- case llvm::MachO::MH_MAGIC:
- case llvm::MachO::MH_MAGIC_64:
- return endian::InlHostByteOrder();
-
- case llvm::MachO::MH_CIGAM:
- case llvm::MachO::MH_CIGAM_64:
- if (endian::InlHostByteOrder() == lldb::eByteOrderBig)
- return lldb::eByteOrderLittle;
- else
- return lldb::eByteOrderBig;
-
- default:
- break;
- }
- return lldb::eByteOrderInvalid;
-}
+DynamicLoaderDarwinKernel::GetByteOrderFromMagic(uint32_t magic) {
+ switch (magic) {
+ case llvm::MachO::MH_MAGIC:
+ case llvm::MachO::MH_MAGIC_64:
+ return endian::InlHostByteOrder();
+ case llvm::MachO::MH_CIGAM:
+ case llvm::MachO::MH_CIGAM_64:
+ if (endian::InlHostByteOrder() == lldb::eByteOrderBig)
+ return lldb::eByteOrderLittle;
+ else
+ return lldb::eByteOrderBig;
+
+ default:
+ break;
+ }
+ return lldb::eByteOrderInvalid;
+}
diff --git a/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h b/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h
index 47fba086a4a..fc3216f7891 100644
--- a/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h
+++ b/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h
@@ -18,354 +18,289 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/Target/DynamicLoader.h"
+#include "lldb/Core/UUID.h"
#include "lldb/Host/FileSpec.h"
#include "lldb/Host/TimeValue.h"
-#include "lldb/Core/UUID.h"
+#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/Process.h"
-class DynamicLoaderDarwinKernel : public lldb_private::DynamicLoader
-{
+class DynamicLoaderDarwinKernel : public lldb_private::DynamicLoader {
public:
- DynamicLoaderDarwinKernel(lldb_private::Process *process, lldb::addr_t kernel_addr);
+ DynamicLoaderDarwinKernel(lldb_private::Process *process,
+ lldb::addr_t kernel_addr);
- ~DynamicLoaderDarwinKernel() override;
+ ~DynamicLoaderDarwinKernel() override;
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
- static void
- Initialize();
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+ static void Initialize();
- static void
- Terminate();
+ static void Terminate();
- static lldb_private::ConstString
- GetPluginNameStatic();
+ static lldb_private::ConstString GetPluginNameStatic();
- static const char *
- GetPluginDescriptionStatic();
+ static const char *GetPluginDescriptionStatic();
- static lldb_private::DynamicLoader *
- CreateInstance (lldb_private::Process *process, bool force);
+ static lldb_private::DynamicLoader *
+ CreateInstance(lldb_private::Process *process, bool force);
- static void
- DebuggerInitialize (lldb_private::Debugger &debugger);
+ static void DebuggerInitialize(lldb_private::Debugger &debugger);
- static lldb::addr_t
- SearchForDarwinKernel (lldb_private::Process *process);
+ static lldb::addr_t SearchForDarwinKernel(lldb_private::Process *process);
- //------------------------------------------------------------------
- /// Called after attaching a process.
- ///
- /// Allow DynamicLoader plug-ins to execute some code after
- /// attaching to a process.
- //------------------------------------------------------------------
- void
- DidAttach() override;
+ //------------------------------------------------------------------
+ /// Called after attaching a process.
+ ///
+ /// Allow DynamicLoader plug-ins to execute some code after
+ /// attaching to a process.
+ //------------------------------------------------------------------
+ void DidAttach() override;
- void
- DidLaunch() override;
+ void DidLaunch() override;
- lldb::ThreadPlanSP
- GetStepThroughTrampolinePlan(lldb_private::Thread &thread,
- bool stop_others) override;
+ lldb::ThreadPlanSP GetStepThroughTrampolinePlan(lldb_private::Thread &thread,
+ bool stop_others) override;
- lldb_private::Error
- CanLoadImage() override;
+ lldb_private::Error CanLoadImage() override;
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- lldb_private::ConstString
- GetPluginName() override;
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ lldb_private::ConstString GetPluginName() override;
- uint32_t
- GetPluginVersion() override;
+ uint32_t GetPluginVersion() override;
protected:
- void
- PrivateInitialize (lldb_private::Process *process);
+ void PrivateInitialize(lldb_private::Process *process);
+
+ void PrivateProcessStateChanged(lldb_private::Process *process,
+ lldb::StateType state);
+
+ void UpdateIfNeeded();
+
+ void LoadKernelModuleIfNeeded();
+
+ void Clear(bool clear_process);
+
+ void PutToLog(lldb_private::Log *log) const;
+
+ static bool
+ BreakpointHitCallback(void *baton,
+ lldb_private::StoppointCallbackContext *context,
+ lldb::user_id_t break_id, lldb::user_id_t break_loc_id);
+
+ bool BreakpointHit(lldb_private::StoppointCallbackContext *context,
+ lldb::user_id_t break_id, lldb::user_id_t break_loc_id);
+ uint32_t GetAddrByteSize() { return m_kernel.GetAddressByteSize(); }
+
+ static lldb::ByteOrder GetByteOrderFromMagic(uint32_t magic);
+
+ enum {
+ KERNEL_MODULE_MAX_NAME = 64u,
+ // Versions less than 2 didn't have an entry size,
+ // they had a 64 bit name, 16 byte UUID, 8 byte addr,
+ // 8 byte size, 8 byte version, 4 byte load tag, and
+ // 4 byte flags
+ KERNEL_MODULE_ENTRY_SIZE_VERSION_1 = 64u + 16u + 8u + 8u + 8u + 4u + 4u
+ };
+
+ // class KextImageInfo represents a single kext or kernel binary image.
+ // The class was designed to hold the information from the
+ // OSKextLoadedKextSummary
+ // structure (in libkern/libkern/OSKextLibPrivate.h from xnu). The kernel
+ // maintains
+ // a list of loded kexts in memory (the OSKextLoadedKextSummaryHeader
+ // structure,
+ // which points to an array of OSKextLoadedKextSummary's).
+ //
+ // A KextImageInfos may have -
+ //
+ // 1. The load address, name, UUID, and size of a kext/kernel binary in memory
+ // (read straight out of the kernel's list-of-kexts loaded)
+ // 2. A ModuleSP based on a MemoryModule read out of the kernel's memory
+ // (very unlikely to have any symbolic information)
+ // 3. A ModuleSP for an on-disk copy of the kext binary, possibly with debug
+ // info
+ // or a dSYM
+ //
+ // For performance reasons, the developer may prefer that lldb not load the
+ // kexts out
+ // of memory at the start of a kernel session. But we should build up /
+ // maintain a
+ // list of kexts that the kernel has told us about so we can relocate a kext
+ // module
+ // later if the user explicitly adds it to the target.
+
+ class KextImageInfo {
+ public:
+ KextImageInfo()
+ : m_name(), m_module_sp(), m_memory_module_sp(),
+ m_load_process_stop_id(UINT32_MAX), m_uuid(),
+ m_load_address(LLDB_INVALID_ADDRESS), m_size(0),
+ m_kernel_image(false) {}
+
+ void Clear() {
+ m_load_address = LLDB_INVALID_ADDRESS;
+ m_size = 0;
+ m_name.clear();
+ m_uuid.Clear();
+ m_module_sp.reset();
+ m_memory_module_sp.reset();
+ m_load_process_stop_id = UINT32_MAX;
+ }
+
+ bool LoadImageAtFileAddress(lldb_private::Process *process);
+
+ bool LoadImageUsingMemoryModule(lldb_private::Process *process);
+
+ bool IsLoaded() { return m_load_process_stop_id != UINT32_MAX; }
+
+ void SetLoadAddress(
+ lldb::addr_t load_addr); // Address of the Mach-O header for this binary
+
+ lldb::addr_t
+ GetLoadAddress() const; // Address of the Mach-O header for this binary
+
+ lldb_private::UUID GetUUID() const;
+
+ void SetUUID(const lldb_private::UUID &uuid);
- void
- PrivateProcessStateChanged (lldb_private::Process *process,
- lldb::StateType state);
+ void SetName(const char *);
- void
- UpdateIfNeeded();
+ std::string GetName() const;
- void
- LoadKernelModuleIfNeeded ();
+ void SetModule(lldb::ModuleSP module);
- void
- Clear (bool clear_process);
+ lldb::ModuleSP GetModule();
- void
- PutToLog (lldb_private::Log *log) const;
+ // try to fill in m_memory_module_sp from memory based on the m_load_address
+ bool ReadMemoryModule(lldb_private::Process *process);
- static bool
- BreakpointHitCallback (void *baton,
- lldb_private::StoppointCallbackContext *context,
- lldb::user_id_t break_id,
- lldb::user_id_t break_loc_id);
+ bool IsKernel()
+ const; // true if this is the mach_kernel; false if this is a kext
+
+ void SetIsKernel(bool is_kernel);
+
+ uint64_t GetSize() const;
+
+ void SetSize(uint64_t size);
- bool
- BreakpointHit (lldb_private::StoppointCallbackContext *context,
- lldb::user_id_t break_id,
- lldb::user_id_t break_loc_id);
uint32_t
- GetAddrByteSize()
- {
- return m_kernel.GetAddressByteSize();
+ GetProcessStopId() const; // the stop-id when this binary was first noticed
+
+ void SetProcessStopId(uint32_t stop_id);
+
+ bool operator==(const KextImageInfo &rhs);
+
+ uint32_t GetAddressByteSize(); // as determined by Mach-O header
+
+ lldb::ByteOrder GetByteOrder(); // as determined by Mach-O header
+
+ lldb_private::ArchSpec
+ GetArchitecture() const; // as determined by Mach-O header
+
+ void PutToLog(lldb_private::Log *log) const;
+
+ typedef std::vector<KextImageInfo> collection;
+ typedef collection::iterator iterator;
+ typedef collection::const_iterator const_iterator;
+
+ private:
+ std::string m_name;
+ lldb::ModuleSP m_module_sp;
+ lldb::ModuleSP m_memory_module_sp;
+ uint32_t m_load_process_stop_id; // the stop-id when this module was added
+ // to the Target
+ lldb_private::UUID
+ m_uuid; // UUID for this dylib if it has one, else all zeros
+ lldb::addr_t m_load_address;
+ uint64_t m_size;
+ bool m_kernel_image; // true if this is the kernel, false if this is a kext
+ };
+
+ struct OSKextLoadedKextSummaryHeader {
+ uint32_t version;
+ uint32_t entry_size;
+ uint32_t entry_count;
+ lldb::addr_t image_infos_addr;
+
+ OSKextLoadedKextSummaryHeader()
+ : version(0), entry_size(0), entry_count(0),
+ image_infos_addr(LLDB_INVALID_ADDRESS) {}
+
+ uint32_t GetSize() {
+ switch (version) {
+ case 0:
+ return 0; // Can't know the size without a valid version
+ case 1:
+ return 8; // Version 1 only had a version + entry_count
+ default:
+ break;
+ }
+ // Version 2 and above has version, entry_size, entry_count, and reserved
+ return 16;
}
- static lldb::ByteOrder
- GetByteOrderFromMagic (uint32_t magic);
-
- enum
- {
- KERNEL_MODULE_MAX_NAME = 64u,
- // Versions less than 2 didn't have an entry size,
- // they had a 64 bit name, 16 byte UUID, 8 byte addr,
- // 8 byte size, 8 byte version, 4 byte load tag, and
- // 4 byte flags
- KERNEL_MODULE_ENTRY_SIZE_VERSION_1 = 64u + 16u + 8u + 8u + 8u + 4u + 4u
- };
-
- // class KextImageInfo represents a single kext or kernel binary image.
- // The class was designed to hold the information from the OSKextLoadedKextSummary
- // structure (in libkern/libkern/OSKextLibPrivate.h from xnu). The kernel maintains
- // a list of loded kexts in memory (the OSKextLoadedKextSummaryHeader structure,
- // which points to an array of OSKextLoadedKextSummary's).
- //
- // A KextImageInfos may have -
- //
- // 1. The load address, name, UUID, and size of a kext/kernel binary in memory
- // (read straight out of the kernel's list-of-kexts loaded)
- // 2. A ModuleSP based on a MemoryModule read out of the kernel's memory
- // (very unlikely to have any symbolic information)
- // 3. A ModuleSP for an on-disk copy of the kext binary, possibly with debug info
- // or a dSYM
- //
- // For performance reasons, the developer may prefer that lldb not load the kexts out
- // of memory at the start of a kernel session. But we should build up / maintain a
- // list of kexts that the kernel has told us about so we can relocate a kext module
- // later if the user explicitly adds it to the target.
-
- class KextImageInfo
- {
- public:
- KextImageInfo () :
- m_name (),
- m_module_sp (),
- m_memory_module_sp (),
- m_load_process_stop_id (UINT32_MAX),
- m_uuid (),
- m_load_address (LLDB_INVALID_ADDRESS),
- m_size (0),
- m_kernel_image (false)
- { }
-
- void
- Clear ()
- {
- m_load_address = LLDB_INVALID_ADDRESS;
- m_size = 0;
- m_name.clear ();
- m_uuid.Clear();
- m_module_sp.reset();
- m_memory_module_sp.reset();
- m_load_process_stop_id = UINT32_MAX;
- }
-
- bool
- LoadImageAtFileAddress (lldb_private::Process *process);
-
- bool
- LoadImageUsingMemoryModule (lldb_private::Process *process);
-
- bool
- IsLoaded ()
- {
- return m_load_process_stop_id != UINT32_MAX;
- }
-
- void
- SetLoadAddress (lldb::addr_t load_addr); // Address of the Mach-O header for this binary
-
- lldb::addr_t
- GetLoadAddress () const; // Address of the Mach-O header for this binary
-
- lldb_private::UUID
- GetUUID () const;
-
- void
- SetUUID (const lldb_private::UUID &uuid);
-
- void
- SetName (const char *);
-
- std::string
- GetName () const;
-
- void
- SetModule (lldb::ModuleSP module);
-
- lldb::ModuleSP
- GetModule ();
-
- // try to fill in m_memory_module_sp from memory based on the m_load_address
- bool
- ReadMemoryModule (lldb_private::Process *process);
-
- bool
- IsKernel () const; // true if this is the mach_kernel; false if this is a kext
-
- void
- SetIsKernel (bool is_kernel);
-
- uint64_t
- GetSize () const;
-
- void
- SetSize (uint64_t size);
-
- uint32_t
- GetProcessStopId () const; // the stop-id when this binary was first noticed
-
- void
- SetProcessStopId (uint32_t stop_id);
-
- bool
- operator== (const KextImageInfo &rhs);
-
- uint32_t
- GetAddressByteSize (); // as determined by Mach-O header
-
- lldb::ByteOrder
- GetByteOrder(); // as determined by Mach-O header
-
- lldb_private::ArchSpec
- GetArchitecture () const; // as determined by Mach-O header
-
- void
- PutToLog (lldb_private::Log *log) const;
-
- typedef std::vector<KextImageInfo> collection;
- typedef collection::iterator iterator;
- typedef collection::const_iterator const_iterator;
-
- private:
- std::string m_name;
- lldb::ModuleSP m_module_sp;
- lldb::ModuleSP m_memory_module_sp;
- uint32_t m_load_process_stop_id; // the stop-id when this module was added to the Target
- lldb_private::UUID m_uuid; // UUID for this dylib if it has one, else all zeros
- lldb::addr_t m_load_address;
- uint64_t m_size;
- bool m_kernel_image; // true if this is the kernel, false if this is a kext
- };
-
- struct OSKextLoadedKextSummaryHeader
- {
- uint32_t version;
- uint32_t entry_size;
- uint32_t entry_count;
- lldb::addr_t image_infos_addr;
-
- OSKextLoadedKextSummaryHeader() :
- version (0),
- entry_size (0),
- entry_count (0),
- image_infos_addr (LLDB_INVALID_ADDRESS)
- {
- }
-
- uint32_t
- GetSize()
- {
- switch (version)
- {
- case 0: return 0; // Can't know the size without a valid version
- case 1: return 8; // Version 1 only had a version + entry_count
- default: break;
- }
- // Version 2 and above has version, entry_size, entry_count, and reserved
- return 16;
- }
-
- void
- Clear()
- {
- version = 0;
- entry_size = 0;
- entry_count = 0;
- image_infos_addr = LLDB_INVALID_ADDRESS;
- }
-
- bool
- IsValid() const
- {
- return version >= 1 || version <= 2;
- }
- };
-
- void
- RegisterNotificationCallbacks();
-
- void
- UnregisterNotificationCallbacks();
-
- void
- SetNotificationBreakpointIfNeeded ();
-
- bool
- ReadAllKextSummaries ();
-
- bool
- ReadKextSummaryHeader ();
-
- bool
- ParseKextSummaries (const lldb_private::Address &kext_summary_addr,
- uint32_t count);
-
- void
- UpdateImageInfosHeaderAndLoadCommands(KextImageInfo::collection &image_infos,
- uint32_t infos_count,
- bool update_executable);
+ void Clear() {
+ version = 0;
+ entry_size = 0;
+ entry_count = 0;
+ image_infos_addr = LLDB_INVALID_ADDRESS;
+ }
- uint32_t
- ReadKextSummaries (const lldb_private::Address &kext_summary_addr,
- uint32_t image_infos_count,
- KextImageInfo::collection &image_infos);
+ bool IsValid() const { return version >= 1 || version <= 2; }
+ };
+
+ void RegisterNotificationCallbacks();
+
+ void UnregisterNotificationCallbacks();
+
+ void SetNotificationBreakpointIfNeeded();
+
+ bool ReadAllKextSummaries();
+
+ bool ReadKextSummaryHeader();
+
+ bool ParseKextSummaries(const lldb_private::Address &kext_summary_addr,
+ uint32_t count);
+
+ void
+ UpdateImageInfosHeaderAndLoadCommands(KextImageInfo::collection &image_infos,
+ uint32_t infos_count,
+ bool update_executable);
+
+ uint32_t ReadKextSummaries(const lldb_private::Address &kext_summary_addr,
+ uint32_t image_infos_count,
+ KextImageInfo::collection &image_infos);
- static lldb::addr_t
- SearchForKernelAtSameLoadAddr (lldb_private::Process *process);
+ static lldb::addr_t
+ SearchForKernelAtSameLoadAddr(lldb_private::Process *process);
- static lldb::addr_t
- SearchForKernelWithDebugHints (lldb_private::Process *process);
+ static lldb::addr_t
+ SearchForKernelWithDebugHints(lldb_private::Process *process);
- static lldb::addr_t
- SearchForKernelNearPC (lldb_private::Process *process);
+ static lldb::addr_t SearchForKernelNearPC(lldb_private::Process *process);
- static lldb::addr_t
- SearchForKernelViaExhaustiveSearch (lldb_private::Process *process);
+ static lldb::addr_t
+ SearchForKernelViaExhaustiveSearch(lldb_private::Process *process);
- static lldb_private::UUID
- CheckForKernelImageAtAddress (lldb::addr_t addr, lldb_private::Process *process);
+ static lldb_private::UUID
+ CheckForKernelImageAtAddress(lldb::addr_t addr,
+ lldb_private::Process *process);
- lldb::addr_t m_kernel_load_address;
- KextImageInfo m_kernel; // Info about the current kernel image being used
+ lldb::addr_t m_kernel_load_address;
+ KextImageInfo m_kernel; // Info about the current kernel image being used
- lldb_private::Address m_kext_summary_header_ptr_addr;
- lldb_private::Address m_kext_summary_header_addr;
- OSKextLoadedKextSummaryHeader m_kext_summary_header;
- KextImageInfo::collection m_known_kexts;
- mutable std::recursive_mutex m_mutex;
- lldb::user_id_t m_break_id;
+ lldb_private::Address m_kext_summary_header_ptr_addr;
+ lldb_private::Address m_kext_summary_header_addr;
+ OSKextLoadedKextSummaryHeader m_kext_summary_header;
+ KextImageInfo::collection m_known_kexts;
+ mutable std::recursive_mutex m_mutex;
+ lldb::user_id_t m_break_id;
private:
- DISALLOW_COPY_AND_ASSIGN (DynamicLoaderDarwinKernel);
+ DISALLOW_COPY_AND_ASSIGN(DynamicLoaderDarwinKernel);
};
#endif // liblldb_DynamicLoaderDarwinKernel_h_
diff --git a/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp b/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp
index 0d398bfd8ba..1093ff5a578 100644
--- a/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp
+++ b/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp
@@ -10,17 +10,17 @@
// C Includes
// C++ Includes
// Other libraries and framework includes
-#include "lldb/Core/PluginManager.h"
+#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
+#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Section.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadPlanRunToAddress.h"
-#include "lldb/Breakpoint/BreakpointLocation.h"
#include "DynamicLoaderHexagonDYLD.h"
@@ -31,562 +31,490 @@ using namespace lldb_private;
//
// Notes about hexagon dynamic loading:
//
-// When we connect to a target we find the dyld breakpoint address. We put a
+// When we connect to a target we find the dyld breakpoint address. We put
+// a
// breakpoint there with a callback 'RendezvousBreakpointHit()'.
//
-// It is possible to find the dyld structure address from the ELF symbol table,
-// but in the case of the simulator it has not been initialized before the
+// It is possible to find the dyld structure address from the ELF symbol
+// table,
+// but in the case of the simulator it has not been initialized before the
// target calls dlinit().
//
-// We can only safely parse the dyld structure after we hit the dyld breakpoint
+// We can only safely parse the dyld structure after we hit the dyld
+// breakpoint
// since at that time we know dlinit() must have been called.
//
// Find the load address of a symbol
-static lldb::addr_t findSymbolAddress( Process *proc, ConstString findName )
-{
- assert( proc != nullptr );
-
- ModuleSP module = proc->GetTarget().GetExecutableModule();
- assert( module.get() != nullptr );
-
- ObjectFile *exe = module->GetObjectFile();
- assert( exe != nullptr );
-
- lldb_private::Symtab *symtab = exe->GetSymtab( );
- assert( symtab != nullptr );
-
- for ( size_t i = 0; i < symtab->GetNumSymbols( ); i++ )
- {
- const Symbol* sym = symtab->SymbolAtIndex( i );
- assert( sym != nullptr );
- const ConstString &symName = sym->GetName( );
-
- if ( ConstString::Compare( findName, symName ) == 0 )
- {
- Address addr = sym->GetAddress();
- return addr.GetLoadAddress( & proc->GetTarget() );
- }
- }
- return LLDB_INVALID_ADDRESS;
-}
+static lldb::addr_t findSymbolAddress(Process *proc, ConstString findName) {
+ assert(proc != nullptr);
-void
-DynamicLoaderHexagonDYLD::Initialize()
-{
- PluginManager::RegisterPlugin(GetPluginNameStatic(),
- GetPluginDescriptionStatic(),
- CreateInstance);
-}
+ ModuleSP module = proc->GetTarget().GetExecutableModule();
+ assert(module.get() != nullptr);
+
+ ObjectFile *exe = module->GetObjectFile();
+ assert(exe != nullptr);
+
+ lldb_private::Symtab *symtab = exe->GetSymtab();
+ assert(symtab != nullptr);
+
+ for (size_t i = 0; i < symtab->GetNumSymbols(); i++) {
+ const Symbol *sym = symtab->SymbolAtIndex(i);
+ assert(sym != nullptr);
+ const ConstString &symName = sym->GetName();
-void
-DynamicLoaderHexagonDYLD::Terminate()
-{
+ if (ConstString::Compare(findName, symName) == 0) {
+ Address addr = sym->GetAddress();
+ return addr.GetLoadAddress(&proc->GetTarget());
+ }
+ }
+ return LLDB_INVALID_ADDRESS;
}
-lldb_private::ConstString
-DynamicLoaderHexagonDYLD::GetPluginName()
-{
- return GetPluginNameStatic();
+void DynamicLoaderHexagonDYLD::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance);
}
-lldb_private::ConstString
-DynamicLoaderHexagonDYLD::GetPluginNameStatic()
-{
- static ConstString g_name("hexagon-dyld");
- return g_name;
+void DynamicLoaderHexagonDYLD::Terminate() {}
+
+lldb_private::ConstString DynamicLoaderHexagonDYLD::GetPluginName() {
+ return GetPluginNameStatic();
}
-const char *
-DynamicLoaderHexagonDYLD::GetPluginDescriptionStatic()
-{
- return "Dynamic loader plug-in that watches for shared library "
- "loads/unloads in Hexagon processes.";
+lldb_private::ConstString DynamicLoaderHexagonDYLD::GetPluginNameStatic() {
+ static ConstString g_name("hexagon-dyld");
+ return g_name;
}
-uint32_t
-DynamicLoaderHexagonDYLD::GetPluginVersion()
-{
- return 1;
+const char *DynamicLoaderHexagonDYLD::GetPluginDescriptionStatic() {
+ return "Dynamic loader plug-in that watches for shared library "
+ "loads/unloads in Hexagon processes.";
}
-DynamicLoader *
-DynamicLoaderHexagonDYLD::CreateInstance(Process *process, bool force)
-{
- bool create = force;
- if (!create)
- {
- const llvm::Triple &triple_ref = process->GetTarget().GetArchitecture().GetTriple();
- if (triple_ref.getArch() == llvm::Triple::hexagon)
- create = true;
- }
-
- if (create)
- return new DynamicLoaderHexagonDYLD(process);
- return NULL;
+uint32_t DynamicLoaderHexagonDYLD::GetPluginVersion() { return 1; }
+
+DynamicLoader *DynamicLoaderHexagonDYLD::CreateInstance(Process *process,
+ bool force) {
+ bool create = force;
+ if (!create) {
+ const llvm::Triple &triple_ref =
+ process->GetTarget().GetArchitecture().GetTriple();
+ if (triple_ref.getArch() == llvm::Triple::hexagon)
+ create = true;
+ }
+
+ if (create)
+ return new DynamicLoaderHexagonDYLD(process);
+ return NULL;
}
DynamicLoaderHexagonDYLD::DynamicLoaderHexagonDYLD(Process *process)
- : DynamicLoader(process)
- , m_rendezvous (process)
- , m_load_offset(LLDB_INVALID_ADDRESS)
- , m_entry_point(LLDB_INVALID_ADDRESS)
- , m_dyld_bid (LLDB_INVALID_BREAK_ID)
-{
+ : DynamicLoader(process), m_rendezvous(process),
+ m_load_offset(LLDB_INVALID_ADDRESS), m_entry_point(LLDB_INVALID_ADDRESS),
+ m_dyld_bid(LLDB_INVALID_BREAK_ID) {}
+
+DynamicLoaderHexagonDYLD::~DynamicLoaderHexagonDYLD() {
+ if (m_dyld_bid != LLDB_INVALID_BREAK_ID) {
+ m_process->GetTarget().RemoveBreakpointByID(m_dyld_bid);
+ m_dyld_bid = LLDB_INVALID_BREAK_ID;
+ }
}
-DynamicLoaderHexagonDYLD::~DynamicLoaderHexagonDYLD()
-{
- if (m_dyld_bid != LLDB_INVALID_BREAK_ID)
- {
- m_process->GetTarget().RemoveBreakpointByID (m_dyld_bid);
- m_dyld_bid = LLDB_INVALID_BREAK_ID;
- }
-}
+void DynamicLoaderHexagonDYLD::DidAttach() {
+ ModuleSP executable;
+ addr_t load_offset;
-void
-DynamicLoaderHexagonDYLD::DidAttach()
-{
- ModuleSP executable;
- addr_t load_offset;
-
- executable = GetTargetExecutable();
-
- // Find the difference between the desired load address in the elf file
- // and the real load address in memory
- load_offset = ComputeLoadOffset();
-
- // Check that there is a valid executable
- if ( executable.get( ) == nullptr )
- return;
-
- // Disable JIT for hexagon targets because its not supported
- m_process->SetCanJIT(false);
-
- // Enable Interpreting of function call expressions
- m_process->SetCanInterpretFunctionCalls(true);
-
- // Add the current executable to the module list
- ModuleList module_list;
- module_list.Append(executable);
-
- // Map the loaded sections of this executable
- if ( load_offset != LLDB_INVALID_ADDRESS )
- UpdateLoadedSections(executable, LLDB_INVALID_ADDRESS, load_offset, true);
-
- // AD: confirm this?
- // Load into LLDB all of the currently loaded executables in the stub
- LoadAllCurrentModules();
-
- // AD: confirm this?
- // Callback for the target to give it the loaded module list
- m_process->GetTarget().ModulesDidLoad(module_list);
-
- // Try to set a breakpoint at the rendezvous breakpoint.
- // DidLaunch uses ProbeEntry() instead. That sets a breakpoint,
- // at the dyld breakpoint address, with a callback so that when hit,
- // the dyld structure can be parsed.
- if (! SetRendezvousBreakpoint() )
- {
- // fail
- }
-}
+ executable = GetTargetExecutable();
+
+ // Find the difference between the desired load address in the elf file
+ // and the real load address in memory
+ load_offset = ComputeLoadOffset();
+
+ // Check that there is a valid executable
+ if (executable.get() == nullptr)
+ return;
+
+ // Disable JIT for hexagon targets because its not supported
+ m_process->SetCanJIT(false);
+
+ // Enable Interpreting of function call expressions
+ m_process->SetCanInterpretFunctionCalls(true);
-void
-DynamicLoaderHexagonDYLD::DidLaunch()
-{
+ // Add the current executable to the module list
+ ModuleList module_list;
+ module_list.Append(executable);
+
+ // Map the loaded sections of this executable
+ if (load_offset != LLDB_INVALID_ADDRESS)
+ UpdateLoadedSections(executable, LLDB_INVALID_ADDRESS, load_offset, true);
+
+ // AD: confirm this?
+ // Load into LLDB all of the currently loaded executables in the stub
+ LoadAllCurrentModules();
+
+ // AD: confirm this?
+ // Callback for the target to give it the loaded module list
+ m_process->GetTarget().ModulesDidLoad(module_list);
+
+ // Try to set a breakpoint at the rendezvous breakpoint.
+ // DidLaunch uses ProbeEntry() instead. That sets a breakpoint,
+ // at the dyld breakpoint address, with a callback so that when hit,
+ // the dyld structure can be parsed.
+ if (!SetRendezvousBreakpoint()) {
+ // fail
+ }
}
+void DynamicLoaderHexagonDYLD::DidLaunch() {}
+
/// Checks to see if the target module has changed, updates the target
/// accordingly and returns the target executable module.
-ModuleSP
-DynamicLoaderHexagonDYLD::GetTargetExecutable()
-{
- Target &target = m_process->GetTarget();
- ModuleSP executable = target.GetExecutableModule();
-
- // There is no executable
- if (! executable.get())
- return executable;
-
- // The target executable file does not exits
- if (! executable->GetFileSpec().Exists())
- return executable;
-
- // Prep module for loading
- ModuleSpec module_spec(executable->GetFileSpec(), executable->GetArchitecture());
- ModuleSP module_sp (new Module (module_spec));
-
- // Check if the executable has changed and set it to the target executable if they differ.
- if (module_sp.get() && module_sp->GetUUID().IsValid() && executable->GetUUID().IsValid())
- {
- // if the executable has changed ??
- if (module_sp->GetUUID() != executable->GetUUID())
- executable.reset();
- }
- else if (executable->FileHasChanged())
- executable.reset();
-
- if ( executable.get( ) )
- return executable;
-
- // TODO: What case is this code used?
- executable = target.GetSharedModule(module_spec);
- if (executable.get() != target.GetExecutableModulePointer())
- {
- // Don't load dependent images since we are in dyld where we will know
- // and find out about all images that are loaded
- const bool get_dependent_images = false;
- target.SetExecutableModule(executable, get_dependent_images);
- }
-
+ModuleSP DynamicLoaderHexagonDYLD::GetTargetExecutable() {
+ Target &target = m_process->GetTarget();
+ ModuleSP executable = target.GetExecutableModule();
+
+ // There is no executable
+ if (!executable.get())
+ return executable;
+
+ // The target executable file does not exits
+ if (!executable->GetFileSpec().Exists())
return executable;
-}
-//AD: Needs to be updated?
-Error
-DynamicLoaderHexagonDYLD::CanLoadImage()
-{
- return Error();
+ // Prep module for loading
+ ModuleSpec module_spec(executable->GetFileSpec(),
+ executable->GetArchitecture());
+ ModuleSP module_sp(new Module(module_spec));
+
+ // Check if the executable has changed and set it to the target executable if
+ // they differ.
+ if (module_sp.get() && module_sp->GetUUID().IsValid() &&
+ executable->GetUUID().IsValid()) {
+ // if the executable has changed ??
+ if (module_sp->GetUUID() != executable->GetUUID())
+ executable.reset();
+ } else if (executable->FileHasChanged())
+ executable.reset();
+
+ if (executable.get())
+ return executable;
+
+ // TODO: What case is this code used?
+ executable = target.GetSharedModule(module_spec);
+ if (executable.get() != target.GetExecutableModulePointer()) {
+ // Don't load dependent images since we are in dyld where we will know
+ // and find out about all images that are loaded
+ const bool get_dependent_images = false;
+ target.SetExecutableModule(executable, get_dependent_images);
+ }
+
+ return executable;
}
-void
-DynamicLoaderHexagonDYLD::UpdateLoadedSections(ModuleSP module,
- addr_t link_map_addr,
- addr_t base_addr,
- bool base_addr_is_offset)
-{
- Target &target = m_process->GetTarget();
- const SectionList *sections = GetSectionListFromModule(module);
+// AD: Needs to be updated?
+Error DynamicLoaderHexagonDYLD::CanLoadImage() { return Error(); }
- assert(sections && "SectionList missing from loaded module.");
+void DynamicLoaderHexagonDYLD::UpdateLoadedSections(ModuleSP module,
+ addr_t link_map_addr,
+ addr_t base_addr,
+ bool base_addr_is_offset) {
+ Target &target = m_process->GetTarget();
+ const SectionList *sections = GetSectionListFromModule(module);
- m_loaded_modules[module] = link_map_addr;
+ assert(sections && "SectionList missing from loaded module.");
- const size_t num_sections = sections->GetSize();
+ m_loaded_modules[module] = link_map_addr;
- for (unsigned i = 0; i < num_sections; ++i)
- {
- SectionSP section_sp (sections->GetSectionAtIndex(i));
- lldb::addr_t new_load_addr = section_sp->GetFileAddress() + base_addr;
+ const size_t num_sections = sections->GetSize();
- // AD: 02/05/14
- // since our memory map starts from address 0, we must not ignore
- // sections that load to address 0. This violates the reference
- // ELF spec, however is used for Hexagon.
+ for (unsigned i = 0; i < num_sections; ++i) {
+ SectionSP section_sp(sections->GetSectionAtIndex(i));
+ lldb::addr_t new_load_addr = section_sp->GetFileAddress() + base_addr;
- // If the file address of the section is zero then this is not an
- // allocatable/loadable section (property of ELF sh_addr). Skip it.
-// if (new_load_addr == base_addr)
-// continue;
+ // AD: 02/05/14
+ // since our memory map starts from address 0, we must not ignore
+ // sections that load to address 0. This violates the reference
+ // ELF spec, however is used for Hexagon.
- target.SetSectionLoadAddress(section_sp, new_load_addr);
- }
+ // If the file address of the section is zero then this is not an
+ // allocatable/loadable section (property of ELF sh_addr). Skip it.
+ // if (new_load_addr == base_addr)
+ // continue;
+
+ target.SetSectionLoadAddress(section_sp, new_load_addr);
+ }
}
/// Removes the loaded sections from the target in @p module.
///
/// @param module The module to traverse.
-void
-DynamicLoaderHexagonDYLD::UnloadSections(const ModuleSP module)
-{
- Target &target = m_process->GetTarget();
- const SectionList *sections = GetSectionListFromModule(module);
+void DynamicLoaderHexagonDYLD::UnloadSections(const ModuleSP module) {
+ Target &target = m_process->GetTarget();
+ const SectionList *sections = GetSectionListFromModule(module);
- assert(sections && "SectionList missing from unloaded module.");
+ assert(sections && "SectionList missing from unloaded module.");
- m_loaded_modules.erase(module);
+ m_loaded_modules.erase(module);
- const size_t num_sections = sections->GetSize();
- for (size_t i = 0; i < num_sections; ++i)
- {
- SectionSP section_sp (sections->GetSectionAtIndex(i));
- target.SetSectionUnloaded(section_sp);
- }
+ const size_t num_sections = sections->GetSize();
+ for (size_t i = 0; i < num_sections; ++i) {
+ SectionSP section_sp(sections->GetSectionAtIndex(i));
+ target.SetSectionUnloaded(section_sp);
+ }
}
// Place a breakpoint on <_rtld_debug_state>
-bool
-DynamicLoaderHexagonDYLD::SetRendezvousBreakpoint()
-{
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
-
- // This is the original code, which want to look in the rendezvous structure
- // to find the breakpoint address. Its backwards for us, since we can easily
- // find the breakpoint address, since it is exported in our executable.
- // We however know that we cant read the Rendezvous structure until we have hit
- // the breakpoint once.
- const ConstString dyldBpName( "_rtld_debug_state" );
- addr_t break_addr = findSymbolAddress( m_process, dyldBpName );
-
- Target &target = m_process->GetTarget();
-
- // Do not try to set the breakpoint if we don't know where to put it
- if ( break_addr == LLDB_INVALID_ADDRESS )
- {
- if ( log )
- log->Printf( "Unable to locate _rtld_debug_state breakpoint address" );
-
- return false;
- }
-
- // Save the address of the rendezvous structure
- m_rendezvous.SetBreakAddress( break_addr );
-
- // If we haven't set the breakpoint before then set it
- if (m_dyld_bid == LLDB_INVALID_BREAK_ID)
- {
- Breakpoint *dyld_break = target.CreateBreakpoint (break_addr, true, false).get();
- dyld_break->SetCallback(RendezvousBreakpointHit, this, true);
- dyld_break->SetBreakpointKind ("shared-library-event");
- m_dyld_bid = dyld_break->GetID();
-
- // Make sure our breakpoint is at the right address.
- assert
- (
- target.GetBreakpointByID(m_dyld_bid)->
- FindLocationByAddress(break_addr)->
- GetBreakpoint().GetID()
- == m_dyld_bid
- );
-
- if ( log && dyld_break == nullptr )
- log->Printf( "Failed to create _rtld_debug_state breakpoint" );
-
- // check we have successfully set bp
- return (dyld_break != nullptr);
- }
- else
- // rendezvous already set
- return true;
+bool DynamicLoaderHexagonDYLD::SetRendezvousBreakpoint() {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+
+ // This is the original code, which want to look in the rendezvous structure
+ // to find the breakpoint address. Its backwards for us, since we can easily
+ // find the breakpoint address, since it is exported in our executable.
+ // We however know that we cant read the Rendezvous structure until we have
+ // hit
+ // the breakpoint once.
+ const ConstString dyldBpName("_rtld_debug_state");
+ addr_t break_addr = findSymbolAddress(m_process, dyldBpName);
+
+ Target &target = m_process->GetTarget();
+
+ // Do not try to set the breakpoint if we don't know where to put it
+ if (break_addr == LLDB_INVALID_ADDRESS) {
+ if (log)
+ log->Printf("Unable to locate _rtld_debug_state breakpoint address");
+
+ return false;
+ }
+
+ // Save the address of the rendezvous structure
+ m_rendezvous.SetBreakAddress(break_addr);
+
+ // If we haven't set the breakpoint before then set it
+ if (m_dyld_bid == LLDB_INVALID_BREAK_ID) {
+ Breakpoint *dyld_break =
+ target.CreateBreakpoint(break_addr, true, false).get();
+ dyld_break->SetCallback(RendezvousBreakpointHit, this, true);
+ dyld_break->SetBreakpointKind("shared-library-event");
+ m_dyld_bid = dyld_break->GetID();
+
+ // Make sure our breakpoint is at the right address.
+ assert(target.GetBreakpointByID(m_dyld_bid)
+ ->FindLocationByAddress(break_addr)
+ ->GetBreakpoint()
+ .GetID() == m_dyld_bid);
+
+ if (log && dyld_break == nullptr)
+ log->Printf("Failed to create _rtld_debug_state breakpoint");
+
+ // check we have successfully set bp
+ return (dyld_break != nullptr);
+ } else
+ // rendezvous already set
+ return true;
}
// We have just hit our breakpoint at <_rtld_debug_state>
-bool
-DynamicLoaderHexagonDYLD::RendezvousBreakpointHit(void *baton,
- StoppointCallbackContext *context,
- user_id_t break_id,
- user_id_t break_loc_id)
-{
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+bool DynamicLoaderHexagonDYLD::RendezvousBreakpointHit(
+ void *baton, StoppointCallbackContext *context, user_id_t break_id,
+ user_id_t break_loc_id) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- if ( log )
- log->Printf( "Rendezvous breakpoint hit!" );
+ if (log)
+ log->Printf("Rendezvous breakpoint hit!");
- DynamicLoaderHexagonDYLD* dyld_instance = nullptr;
- dyld_instance = static_cast<DynamicLoaderHexagonDYLD*>(baton);
+ DynamicLoaderHexagonDYLD *dyld_instance = nullptr;
+ dyld_instance = static_cast<DynamicLoaderHexagonDYLD *>(baton);
- // if the dyld_instance is still not valid then
- // try to locate it on the symbol table
- if ( !dyld_instance->m_rendezvous.IsValid( ) )
- {
- Process *proc = dyld_instance->m_process;
+ // if the dyld_instance is still not valid then
+ // try to locate it on the symbol table
+ if (!dyld_instance->m_rendezvous.IsValid()) {
+ Process *proc = dyld_instance->m_process;
- const ConstString dyldStructName( "_rtld_debug" );
- addr_t structAddr = findSymbolAddress( proc, dyldStructName );
+ const ConstString dyldStructName("_rtld_debug");
+ addr_t structAddr = findSymbolAddress(proc, dyldStructName);
- if ( structAddr != LLDB_INVALID_ADDRESS )
- {
- dyld_instance->m_rendezvous.SetRendezvousAddress( structAddr );
+ if (structAddr != LLDB_INVALID_ADDRESS) {
+ dyld_instance->m_rendezvous.SetRendezvousAddress(structAddr);
- if ( log )
- log->Printf( "Found _rtld_debug structure @ 0x%08" PRIx64, structAddr );
- }
- else
- {
- if ( log )
- log->Printf( "Unable to resolve the _rtld_debug structure" );
- }
+ if (log)
+ log->Printf("Found _rtld_debug structure @ 0x%08" PRIx64, structAddr);
+ } else {
+ if (log)
+ log->Printf("Unable to resolve the _rtld_debug structure");
}
+ }
- dyld_instance->RefreshModules();
+ dyld_instance->RefreshModules();
- // Return true to stop the target, false to just let the target run.
- return dyld_instance->GetStopWhenImagesChange();
+ // Return true to stop the target, false to just let the target run.
+ return dyld_instance->GetStopWhenImagesChange();
}
/// Helper method for RendezvousBreakpointHit. Updates LLDB's current set
/// of loaded modules.
-void
-DynamicLoaderHexagonDYLD::RefreshModules()
-{
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
-
- if (!m_rendezvous.Resolve())
- return;
-
- HexagonDYLDRendezvous::iterator I;
- HexagonDYLDRendezvous::iterator E;
-
- ModuleList &loaded_modules = m_process->GetTarget().GetImages();
-
- if (m_rendezvous.ModulesDidLoad())
- {
- ModuleList new_modules;
-
- E = m_rendezvous.loaded_end();
- for (I = m_rendezvous.loaded_begin(); I != E; ++I)
- {
- FileSpec file(I->path.c_str(), true);
- ModuleSP module_sp = LoadModuleAtAddress(file, I->link_addr, I->base_addr, true);
- if (module_sp.get())
- {
- loaded_modules.AppendIfNeeded( module_sp );
- new_modules.Append(module_sp);
- }
-
- if (log)
- {
- log->Printf( "Target is loading '%s'", I->path.c_str() );
- if (! module_sp.get() )
- log->Printf( "LLDB failed to load '%s'", I->path.c_str() );
- else
- log->Printf( "LLDB successfully loaded '%s'", I->path.c_str() );
- }
-
- }
- m_process->GetTarget().ModulesDidLoad(new_modules);
+void DynamicLoaderHexagonDYLD::RefreshModules() {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+
+ if (!m_rendezvous.Resolve())
+ return;
+
+ HexagonDYLDRendezvous::iterator I;
+ HexagonDYLDRendezvous::iterator E;
+
+ ModuleList &loaded_modules = m_process->GetTarget().GetImages();
+
+ if (m_rendezvous.ModulesDidLoad()) {
+ ModuleList new_modules;
+
+ E = m_rendezvous.loaded_end();
+ for (I = m_rendezvous.loaded_begin(); I != E; ++I) {
+ FileSpec file(I->path.c_str(), true);
+ ModuleSP module_sp =
+ LoadModuleAtAddress(file, I->link_addr, I->base_addr, true);
+ if (module_sp.get()) {
+ loaded_modules.AppendIfNeeded(module_sp);
+ new_modules.Append(module_sp);
+ }
+
+ if (log) {
+ log->Printf("Target is loading '%s'", I->path.c_str());
+ if (!module_sp.get())
+ log->Printf("LLDB failed to load '%s'", I->path.c_str());
+ else
+ log->Printf("LLDB successfully loaded '%s'", I->path.c_str());
+ }
}
-
- if (m_rendezvous.ModulesDidUnload())
- {
- ModuleList old_modules;
-
- E = m_rendezvous.unloaded_end();
- for (I = m_rendezvous.unloaded_begin(); I != E; ++I)
- {
- FileSpec file(I->path.c_str(), true);
- ModuleSpec module_spec(file);
- ModuleSP module_sp = loaded_modules.FindFirstModule (module_spec);
-
- if (module_sp.get())
- {
- old_modules.Append(module_sp);
- UnloadSections(module_sp);
- }
-
- if (log)
- log->Printf( "Target is unloading '%s'", I->path.c_str() );
-
- }
- loaded_modules.Remove(old_modules);
- m_process->GetTarget().ModulesDidUnload(old_modules, false);
+ m_process->GetTarget().ModulesDidLoad(new_modules);
+ }
+
+ if (m_rendezvous.ModulesDidUnload()) {
+ ModuleList old_modules;
+
+ E = m_rendezvous.unloaded_end();
+ for (I = m_rendezvous.unloaded_begin(); I != E; ++I) {
+ FileSpec file(I->path.c_str(), true);
+ ModuleSpec module_spec(file);
+ ModuleSP module_sp = loaded_modules.FindFirstModule(module_spec);
+
+ if (module_sp.get()) {
+ old_modules.Append(module_sp);
+ UnloadSections(module_sp);
+ }
+
+ if (log)
+ log->Printf("Target is unloading '%s'", I->path.c_str());
}
+ loaded_modules.Remove(old_modules);
+ m_process->GetTarget().ModulesDidUnload(old_modules, false);
+ }
}
-//AD: This is very different to the Static Loader code.
+// AD: This is very different to the Static Loader code.
// It may be wise to look over this and its relation to stack
// unwinding.
ThreadPlanSP
-DynamicLoaderHexagonDYLD::GetStepThroughTrampolinePlan(Thread &thread, bool stop)
-{
- ThreadPlanSP thread_plan_sp;
-
- StackFrame *frame = thread.GetStackFrameAtIndex(0).get();
- const SymbolContext &context = frame->GetSymbolContext(eSymbolContextSymbol);
- Symbol *sym = context.symbol;
-
- if (sym == NULL || !sym->IsTrampoline())
- return thread_plan_sp;
-
- const ConstString sym_name = sym->GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled);
- if (!sym_name)
- return thread_plan_sp;
-
- SymbolContextList target_symbols;
- Target &target = thread.GetProcess()->GetTarget();
- const ModuleList &images = target.GetImages();
-
- images.FindSymbolsWithNameAndType(sym_name, eSymbolTypeCode, target_symbols);
- size_t num_targets = target_symbols.GetSize();
- if (!num_targets)
- return thread_plan_sp;
-
- typedef std::vector<lldb::addr_t> AddressVector;
- AddressVector addrs;
- for (size_t i = 0; i < num_targets; ++i)
- {
- SymbolContext context;
- AddressRange range;
- if (target_symbols.GetContextAtIndex(i, context))
- {
- context.GetAddressRange(eSymbolContextEverything, 0, false, range);
- lldb::addr_t addr = range.GetBaseAddress().GetLoadAddress(&target);
- if (addr != LLDB_INVALID_ADDRESS)
- addrs.push_back(addr);
- }
- }
+DynamicLoaderHexagonDYLD::GetStepThroughTrampolinePlan(Thread &thread,
+ bool stop) {
+ ThreadPlanSP thread_plan_sp;
- if (addrs.size() > 0)
- {
- AddressVector::iterator start = addrs.begin();
- AddressVector::iterator end = addrs.end();
+ StackFrame *frame = thread.GetStackFrameAtIndex(0).get();
+ const SymbolContext &context = frame->GetSymbolContext(eSymbolContextSymbol);
+ Symbol *sym = context.symbol;
- std::sort(start, end);
- addrs.erase(std::unique(start, end), end);
- thread_plan_sp.reset(new ThreadPlanRunToAddress(thread, addrs, stop));
- }
+ if (sym == NULL || !sym->IsTrampoline())
+ return thread_plan_sp;
+
+ const ConstString sym_name = sym->GetMangled().GetName(
+ lldb::eLanguageTypeUnknown, Mangled::ePreferMangled);
+ if (!sym_name)
+ return thread_plan_sp;
+
+ SymbolContextList target_symbols;
+ Target &target = thread.GetProcess()->GetTarget();
+ const ModuleList &images = target.GetImages();
+ images.FindSymbolsWithNameAndType(sym_name, eSymbolTypeCode, target_symbols);
+ size_t num_targets = target_symbols.GetSize();
+ if (!num_targets)
return thread_plan_sp;
+
+ typedef std::vector<lldb::addr_t> AddressVector;
+ AddressVector addrs;
+ for (size_t i = 0; i < num_targets; ++i) {
+ SymbolContext context;
+ AddressRange range;
+ if (target_symbols.GetContextAtIndex(i, context)) {
+ context.GetAddressRange(eSymbolContextEverything, 0, false, range);
+ lldb::addr_t addr = range.GetBaseAddress().GetLoadAddress(&target);
+ if (addr != LLDB_INVALID_ADDRESS)
+ addrs.push_back(addr);
+ }
+ }
+
+ if (addrs.size() > 0) {
+ AddressVector::iterator start = addrs.begin();
+ AddressVector::iterator end = addrs.end();
+
+ std::sort(start, end);
+ addrs.erase(std::unique(start, end), end);
+ thread_plan_sp.reset(new ThreadPlanRunToAddress(thread, addrs, stop));
+ }
+
+ return thread_plan_sp;
}
/// Helper for the entry breakpoint callback. Resolves the load addresses
/// of all dependent modules.
-void
-DynamicLoaderHexagonDYLD::LoadAllCurrentModules()
-{
- HexagonDYLDRendezvous::iterator I;
- HexagonDYLDRendezvous::iterator E;
- ModuleList module_list;
-
- if (!m_rendezvous.Resolve())
- {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- if (log)
- log->Printf("DynamicLoaderHexagonDYLD::%s unable to resolve rendezvous address", __FUNCTION__);
- return;
- }
+void DynamicLoaderHexagonDYLD::LoadAllCurrentModules() {
+ HexagonDYLDRendezvous::iterator I;
+ HexagonDYLDRendezvous::iterator E;
+ ModuleList module_list;
- // The rendezvous class doesn't enumerate the main module, so track
- // that ourselves here.
- ModuleSP executable = GetTargetExecutable();
- m_loaded_modules[executable] = m_rendezvous.GetLinkMapAddress();
-
-
- for (I = m_rendezvous.begin(), E = m_rendezvous.end(); I != E; ++I)
- {
- const char *module_path = I->path.c_str();
- FileSpec file(module_path, false);
- ModuleSP module_sp = LoadModuleAtAddress(file, I->link_addr, I->base_addr, true);
- if (module_sp.get())
- {
- module_list.Append(module_sp);
- }
- else
- {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- if (log)
- log->Printf("DynamicLoaderHexagonDYLD::%s failed loading module %s at 0x%" PRIx64,
- __FUNCTION__, module_path, I->base_addr);
- }
+ if (!m_rendezvous.Resolve()) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+ if (log)
+ log->Printf(
+ "DynamicLoaderHexagonDYLD::%s unable to resolve rendezvous address",
+ __FUNCTION__);
+ return;
+ }
+
+ // The rendezvous class doesn't enumerate the main module, so track
+ // that ourselves here.
+ ModuleSP executable = GetTargetExecutable();
+ m_loaded_modules[executable] = m_rendezvous.GetLinkMapAddress();
+
+ for (I = m_rendezvous.begin(), E = m_rendezvous.end(); I != E; ++I) {
+ const char *module_path = I->path.c_str();
+ FileSpec file(module_path, false);
+ ModuleSP module_sp =
+ LoadModuleAtAddress(file, I->link_addr, I->base_addr, true);
+ if (module_sp.get()) {
+ module_list.Append(module_sp);
+ } else {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+ if (log)
+ log->Printf("DynamicLoaderHexagonDYLD::%s failed loading module %s at "
+ "0x%" PRIx64,
+ __FUNCTION__, module_path, I->base_addr);
}
+ }
- m_process->GetTarget().ModulesDidLoad(module_list);
+ m_process->GetTarget().ModulesDidLoad(module_list);
}
/// Computes a value for m_load_offset returning the computed address on
/// success and LLDB_INVALID_ADDRESS on failure.
-addr_t
-DynamicLoaderHexagonDYLD::ComputeLoadOffset()
-{
- // Here we could send a GDB packet to know the load offset
- //
- // send: $qOffsets#4b
- // get: Text=0;Data=0;Bss=0
- //
- // Currently qOffsets is not supported by pluginProcessGDBRemote
- //
- return 0;
+addr_t DynamicLoaderHexagonDYLD::ComputeLoadOffset() {
+ // Here we could send a GDB packet to know the load offset
+ //
+ // send: $qOffsets#4b
+ // get: Text=0;Data=0;Bss=0
+ //
+ // Currently qOffsets is not supported by pluginProcessGDBRemote
+ //
+ return 0;
}
// Here we must try to read the entry point directly from
@@ -596,100 +524,97 @@ DynamicLoaderHexagonDYLD::ComputeLoadOffset()
// an alternative is to look at the PC if we can be sure
// that we have connected when the process is at the entry point.
// I dont think that is reliable for us.
-addr_t
-DynamicLoaderHexagonDYLD::GetEntryPoint()
-{
- if (m_entry_point != LLDB_INVALID_ADDRESS)
- return m_entry_point;
- // check we have a valid process
- if ( m_process == nullptr )
- return LLDB_INVALID_ADDRESS;
- // Get the current executable module
- Module & module = *( m_process->GetTarget( ).GetExecutableModule( ).get( ) );
- // Get the object file (elf file) for this module
- lldb_private::ObjectFile &object = *( module.GetObjectFile( ) );
- // Check if the file is executable (ie, not shared object or relocatable)
- if ( object.IsExecutable() )
- {
- // Get the entry point address for this object
- lldb_private::Address entry = object.GetEntryPointAddress( );
- // Return the entry point address
- return entry.GetFileAddress( );
- }
- // No idea so back out
+addr_t DynamicLoaderHexagonDYLD::GetEntryPoint() {
+ if (m_entry_point != LLDB_INVALID_ADDRESS)
+ return m_entry_point;
+ // check we have a valid process
+ if (m_process == nullptr)
return LLDB_INVALID_ADDRESS;
+ // Get the current executable module
+ Module &module = *(m_process->GetTarget().GetExecutableModule().get());
+ // Get the object file (elf file) for this module
+ lldb_private::ObjectFile &object = *(module.GetObjectFile());
+ // Check if the file is executable (ie, not shared object or relocatable)
+ if (object.IsExecutable()) {
+ // Get the entry point address for this object
+ lldb_private::Address entry = object.GetEntryPointAddress();
+ // Return the entry point address
+ return entry.GetFileAddress();
+ }
+ // No idea so back out
+ return LLDB_INVALID_ADDRESS;
}
-const SectionList *
-DynamicLoaderHexagonDYLD::GetSectionListFromModule(const ModuleSP module) const
-{
- SectionList *sections = nullptr;
- if (module.get())
- {
- ObjectFile *obj_file = module->GetObjectFile();
- if (obj_file)
- {
- sections = obj_file->GetSectionList();
- }
+const SectionList *DynamicLoaderHexagonDYLD::GetSectionListFromModule(
+ const ModuleSP module) const {
+ SectionList *sections = nullptr;
+ if (module.get()) {
+ ObjectFile *obj_file = module->GetObjectFile();
+ if (obj_file) {
+ sections = obj_file->GetSectionList();
}
- return sections;
+ }
+ return sections;
}
-static int ReadInt(Process *process, addr_t addr)
-{
- Error error;
- int value = (int)process->ReadUnsignedIntegerFromMemory(addr, sizeof(uint32_t), 0, error);
- if (error.Fail())
- return -1;
- else
- return value;
+static int ReadInt(Process *process, addr_t addr) {
+ Error error;
+ int value = (int)process->ReadUnsignedIntegerFromMemory(
+ addr, sizeof(uint32_t), 0, error);
+ if (error.Fail())
+ return -1;
+ else
+ return value;
}
lldb::addr_t
-DynamicLoaderHexagonDYLD::GetThreadLocalData(const lldb::ModuleSP module, const lldb::ThreadSP thread,
- lldb::addr_t tls_file_addr)
-{
- auto it = m_loaded_modules.find (module);
- if (it == m_loaded_modules.end())
- return LLDB_INVALID_ADDRESS;
-
- addr_t link_map = it->second;
- if (link_map == LLDB_INVALID_ADDRESS)
- return LLDB_INVALID_ADDRESS;
-
- const HexagonDYLDRendezvous::ThreadInfo &metadata = m_rendezvous.GetThreadInfo();
- if (!metadata.valid)
- return LLDB_INVALID_ADDRESS;
-
- // Get the thread pointer.
- addr_t tp = thread->GetThreadPointer ();
- if (tp == LLDB_INVALID_ADDRESS)
- return LLDB_INVALID_ADDRESS;
-
- // Find the module's modid.
- int modid = ReadInt (m_process, link_map + metadata.modid_offset);
- if (modid == -1)
- return LLDB_INVALID_ADDRESS;
-
- // Lookup the DTV structure for this thread.
- addr_t dtv_ptr = tp + metadata.dtv_offset;
- addr_t dtv = ReadPointer (dtv_ptr);
- if (dtv == LLDB_INVALID_ADDRESS)
- return LLDB_INVALID_ADDRESS;
-
- // Find the TLS block for this module.
- addr_t dtv_slot = dtv + metadata.dtv_slot_size*modid;
- addr_t tls_block = ReadPointer (dtv_slot + metadata.tls_offset);
-
- Module *mod = module.get();
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- if (log)
- log->Printf("DynamicLoaderHexagonDYLD::Performed TLS lookup: "
- "module=%s, link_map=0x%" PRIx64 ", tp=0x%" PRIx64 ", modid=%i, tls_block=0x%" PRIx64,
- mod->GetObjectName().AsCString(""), link_map, tp, modid, tls_block);
-
- if (tls_block == LLDB_INVALID_ADDRESS)
- return LLDB_INVALID_ADDRESS;
- else
- return tls_block + tls_file_addr;
+DynamicLoaderHexagonDYLD::GetThreadLocalData(const lldb::ModuleSP module,
+ const lldb::ThreadSP thread,
+ lldb::addr_t tls_file_addr) {
+ auto it = m_loaded_modules.find(module);
+ if (it == m_loaded_modules.end())
+ return LLDB_INVALID_ADDRESS;
+
+ addr_t link_map = it->second;
+ if (link_map == LLDB_INVALID_ADDRESS)
+ return LLDB_INVALID_ADDRESS;
+
+ const HexagonDYLDRendezvous::ThreadInfo &metadata =
+ m_rendezvous.GetThreadInfo();
+ if (!metadata.valid)
+ return LLDB_INVALID_ADDRESS;
+
+ // Get the thread pointer.
+ addr_t tp = thread->GetThreadPointer();
+ if (tp == LLDB_INVALID_ADDRESS)
+ return LLDB_INVALID_ADDRESS;
+
+ // Find the module's modid.
+ int modid = ReadInt(m_process, link_map + metadata.modid_offset);
+ if (modid == -1)
+ return LLDB_INVALID_ADDRESS;
+
+ // Lookup the DTV structure for this thread.
+ addr_t dtv_ptr = tp + metadata.dtv_offset;
+ addr_t dtv = ReadPointer(dtv_ptr);
+ if (dtv == LLDB_INVALID_ADDRESS)
+ return LLDB_INVALID_ADDRESS;
+
+ // Find the TLS block for this module.
+ addr_t dtv_slot = dtv + metadata.dtv_slot_size * modid;
+ addr_t tls_block = ReadPointer(dtv_slot + metadata.tls_offset);
+
+ Module *mod = module.get();
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+ if (log)
+ log->Printf("DynamicLoaderHexagonDYLD::Performed TLS lookup: "
+ "module=%s, link_map=0x%" PRIx64 ", tp=0x%" PRIx64
+ ", modid=%i, tls_block=0x%" PRIx64,
+ mod->GetObjectName().AsCString(""), link_map, tp, modid,
+ tls_block);
+
+ if (tls_block == LLDB_INVALID_ADDRESS)
+ return LLDB_INVALID_ADDRESS;
+ else
+ return tls_block + tls_file_addr;
}
diff --git a/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.h b/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.h
index 67c32887d09..1b4f7382541 100644
--- a/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.h
+++ b/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.h
@@ -19,150 +19,129 @@
#include "HexagonDYLDRendezvous.h"
-class DynamicLoaderHexagonDYLD : public lldb_private::DynamicLoader
-{
+class DynamicLoaderHexagonDYLD : public lldb_private::DynamicLoader {
public:
- DynamicLoaderHexagonDYLD(lldb_private::Process *process);
+ DynamicLoaderHexagonDYLD(lldb_private::Process *process);
- ~DynamicLoaderHexagonDYLD() override;
+ ~DynamicLoaderHexagonDYLD() override;
- static void
- Initialize();
+ static void Initialize();
- static void
- Terminate();
+ static void Terminate();
- static lldb_private::ConstString
- GetPluginNameStatic();
+ static lldb_private::ConstString GetPluginNameStatic();
- static const char *
- GetPluginDescriptionStatic();
+ static const char *GetPluginDescriptionStatic();
- static lldb_private::DynamicLoader *
- CreateInstance(lldb_private::Process *process, bool force);
+ static lldb_private::DynamicLoader *
+ CreateInstance(lldb_private::Process *process, bool force);
- //------------------------------------------------------------------
- // DynamicLoader protocol
- //------------------------------------------------------------------
+ //------------------------------------------------------------------
+ // DynamicLoader protocol
+ //------------------------------------------------------------------
- void
- DidAttach() override;
+ void DidAttach() override;
- void
- DidLaunch() override;
+ void DidLaunch() override;
- lldb::ThreadPlanSP
- GetStepThroughTrampolinePlan(lldb_private::Thread &thread,
- bool stop_others) override;
+ lldb::ThreadPlanSP GetStepThroughTrampolinePlan(lldb_private::Thread &thread,
+ bool stop_others) override;
- lldb_private::Error
- CanLoadImage() override;
+ lldb_private::Error CanLoadImage() override;
- lldb::addr_t
- GetThreadLocalData(const lldb::ModuleSP module, const lldb::ThreadSP thread, lldb::addr_t tls_file_addr) override;
+ lldb::addr_t GetThreadLocalData(const lldb::ModuleSP module,
+ const lldb::ThreadSP thread,
+ lldb::addr_t tls_file_addr) override;
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- lldb_private::ConstString
- GetPluginName() override;
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ lldb_private::ConstString GetPluginName() override;
- uint32_t
- GetPluginVersion() override;
+ uint32_t GetPluginVersion() override;
protected:
- /// Runtime linker rendezvous structure.
- HexagonDYLDRendezvous m_rendezvous;
-
- /// Virtual load address of the inferior process.
- lldb::addr_t m_load_offset;
-
- /// Virtual entry address of the inferior process.
- lldb::addr_t m_entry_point;
-
- /// Rendezvous breakpoint.
- lldb::break_id_t m_dyld_bid;
-
- /// Loaded module list. (link map for each module)
- std::map<lldb::ModuleWP, lldb::addr_t, std::owner_less<lldb::ModuleWP>> m_loaded_modules;
-
- /// Enables a breakpoint on a function called by the runtime
- /// linker each time a module is loaded or unloaded.
- bool
- SetRendezvousBreakpoint();
-
- /// Callback routine which updates the current list of loaded modules based
- /// on the information supplied by the runtime linker.
- static bool
- RendezvousBreakpointHit(void *baton,
- lldb_private::StoppointCallbackContext *context,
- lldb::user_id_t break_id,
- lldb::user_id_t break_loc_id);
-
- /// Helper method for RendezvousBreakpointHit. Updates LLDB's current set
- /// of loaded modules.
- void
- RefreshModules();
-
- /// Updates the load address of every allocatable section in @p module.
- ///
- /// @param module The module to traverse.
- ///
- /// @param link_map_addr The virtual address of the link map for the @p module.
- ///
- /// @param base_addr The virtual base address @p module is loaded at.
- void
- UpdateLoadedSections(lldb::ModuleSP module,
- lldb::addr_t link_map_addr,
- lldb::addr_t base_addr,
- bool base_addr_is_offset) override;
-
- /// Removes the loaded sections from the target in @p module.
- ///
- /// @param module The module to traverse.
- void
- UnloadSections(const lldb::ModuleSP module) override;
-
- /// Callback routine invoked when we hit the breakpoint on process entry.
- ///
- /// This routine is responsible for resolving the load addresses of all
- /// dependent modules required by the inferior and setting up the rendezvous
- /// breakpoint.
- static bool
- EntryBreakpointHit(void *baton,
- lldb_private::StoppointCallbackContext *context,
- lldb::user_id_t break_id,
- lldb::user_id_t break_loc_id);
-
- /// Helper for the entry breakpoint callback. Resolves the load addresses
- /// of all dependent modules.
- void
- LoadAllCurrentModules();
-
- /// Computes a value for m_load_offset returning the computed address on
- /// success and LLDB_INVALID_ADDRESS on failure.
- lldb::addr_t
- ComputeLoadOffset();
-
- /// Computes a value for m_entry_point returning the computed address on
- /// success and LLDB_INVALID_ADDRESS on failure.
- lldb::addr_t
- GetEntryPoint();
-
- /// Checks to see if the target module has changed, updates the target
- /// accordingly and returns the target executable module.
- lldb::ModuleSP
- GetTargetExecutable();
-
- /// return the address of the Rendezvous breakpoint
- lldb::addr_t
- FindRendezvousBreakpointAddress( );
+ /// Runtime linker rendezvous structure.
+ HexagonDYLDRendezvous m_rendezvous;
+
+ /// Virtual load address of the inferior process.
+ lldb::addr_t m_load_offset;
+
+ /// Virtual entry address of the inferior process.
+ lldb::addr_t m_entry_point;
+
+ /// Rendezvous breakpoint.
+ lldb::break_id_t m_dyld_bid;
+
+ /// Loaded module list. (link map for each module)
+ std::map<lldb::ModuleWP, lldb::addr_t, std::owner_less<lldb::ModuleWP>>
+ m_loaded_modules;
+
+ /// Enables a breakpoint on a function called by the runtime
+ /// linker each time a module is loaded or unloaded.
+ bool SetRendezvousBreakpoint();
+
+ /// Callback routine which updates the current list of loaded modules based
+ /// on the information supplied by the runtime linker.
+ static bool RendezvousBreakpointHit(
+ void *baton, lldb_private::StoppointCallbackContext *context,
+ lldb::user_id_t break_id, lldb::user_id_t break_loc_id);
+
+ /// Helper method for RendezvousBreakpointHit. Updates LLDB's current set
+ /// of loaded modules.
+ void RefreshModules();
+
+ /// Updates the load address of every allocatable section in @p module.
+ ///
+ /// @param module The module to traverse.
+ ///
+ /// @param link_map_addr The virtual address of the link map for the @p
+ /// module.
+ ///
+ /// @param base_addr The virtual base address @p module is loaded at.
+ void UpdateLoadedSections(lldb::ModuleSP module, lldb::addr_t link_map_addr,
+ lldb::addr_t base_addr,
+ bool base_addr_is_offset) override;
+
+ /// Removes the loaded sections from the target in @p module.
+ ///
+ /// @param module The module to traverse.
+ void UnloadSections(const lldb::ModuleSP module) override;
+
+ /// Callback routine invoked when we hit the breakpoint on process entry.
+ ///
+ /// This routine is responsible for resolving the load addresses of all
+ /// dependent modules required by the inferior and setting up the rendezvous
+ /// breakpoint.
+ static bool
+ EntryBreakpointHit(void *baton,
+ lldb_private::StoppointCallbackContext *context,
+ lldb::user_id_t break_id, lldb::user_id_t break_loc_id);
+
+ /// Helper for the entry breakpoint callback. Resolves the load addresses
+ /// of all dependent modules.
+ void LoadAllCurrentModules();
+
+ /// Computes a value for m_load_offset returning the computed address on
+ /// success and LLDB_INVALID_ADDRESS on failure.
+ lldb::addr_t ComputeLoadOffset();
+
+ /// Computes a value for m_entry_point returning the computed address on
+ /// success and LLDB_INVALID_ADDRESS on failure.
+ lldb::addr_t GetEntryPoint();
+
+ /// Checks to see if the target module has changed, updates the target
+ /// accordingly and returns the target executable module.
+ lldb::ModuleSP GetTargetExecutable();
+
+ /// return the address of the Rendezvous breakpoint
+ lldb::addr_t FindRendezvousBreakpointAddress();
private:
- const lldb_private::SectionList *
- GetSectionListFromModule(const lldb::ModuleSP module) const;
+ const lldb_private::SectionList *
+ GetSectionListFromModule(const lldb::ModuleSP module) const;
- DISALLOW_COPY_AND_ASSIGN(DynamicLoaderHexagonDYLD);
+ DISALLOW_COPY_AND_ASSIGN(DynamicLoaderHexagonDYLD);
};
#endif // liblldb_DynamicLoaderHexagonDYLD_h_
diff --git a/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.cpp b/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.cpp
index 61f9b3d441c..da0edc870f8 100644
--- a/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.cpp
+++ b/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.cpp
@@ -30,375 +30,343 @@ using namespace lldb_private;
/// Locates the address of the rendezvous structure. Returns the address on
/// success and LLDB_INVALID_ADDRESS on failure.
-static addr_t
-ResolveRendezvousAddress(Process *process)
-{
- addr_t info_location;
- addr_t info_addr;
- Error error;
+static addr_t ResolveRendezvousAddress(Process *process) {
+ addr_t info_location;
+ addr_t info_addr;
+ Error error;
- info_location = process->GetImageInfoAddress();
+ info_location = process->GetImageInfoAddress();
- if (info_location == LLDB_INVALID_ADDRESS)
- return LLDB_INVALID_ADDRESS;
+ if (info_location == LLDB_INVALID_ADDRESS)
+ return LLDB_INVALID_ADDRESS;
- info_addr = process->ReadPointerFromMemory(info_location, error);
- if (error.Fail())
- return LLDB_INVALID_ADDRESS;
+ info_addr = process->ReadPointerFromMemory(info_location, error);
+ if (error.Fail())
+ return LLDB_INVALID_ADDRESS;
- if (info_addr == 0)
- return LLDB_INVALID_ADDRESS;
+ if (info_addr == 0)
+ return LLDB_INVALID_ADDRESS;
- return info_addr;
+ return info_addr;
}
HexagonDYLDRendezvous::HexagonDYLDRendezvous(Process *process)
- : m_process(process),
- m_rendezvous_addr(LLDB_INVALID_ADDRESS),
- m_current(),
- m_previous(),
- m_soentries(),
- m_added_soentries(),
- m_removed_soentries()
-{
- m_thread_info.valid = false;
-
- // Cache a copy of the executable path
- if (m_process)
- {
- Module *exe_mod = m_process->GetTarget().GetExecutableModulePointer();
- if (exe_mod)
- exe_mod->GetFileSpec().GetPath(m_exe_path, PATH_MAX);
- }
+ : m_process(process), m_rendezvous_addr(LLDB_INVALID_ADDRESS), m_current(),
+ m_previous(), m_soentries(), m_added_soentries(), m_removed_soentries() {
+ m_thread_info.valid = false;
+
+ // Cache a copy of the executable path
+ if (m_process) {
+ Module *exe_mod = m_process->GetTarget().GetExecutableModulePointer();
+ if (exe_mod)
+ exe_mod->GetFileSpec().GetPath(m_exe_path, PATH_MAX);
+ }
}
-bool
-HexagonDYLDRendezvous::Resolve()
-{
- const size_t word_size = 4;
- Rendezvous info;
- size_t address_size;
- size_t padding;
- addr_t info_addr;
- addr_t cursor;
+bool HexagonDYLDRendezvous::Resolve() {
+ const size_t word_size = 4;
+ Rendezvous info;
+ size_t address_size;
+ size_t padding;
+ addr_t info_addr;
+ addr_t cursor;
- address_size = m_process->GetAddressByteSize();
- padding = address_size - word_size;
+ address_size = m_process->GetAddressByteSize();
+ padding = address_size - word_size;
- if (m_rendezvous_addr == LLDB_INVALID_ADDRESS)
- cursor = info_addr = ResolveRendezvousAddress(m_process);
- else
- cursor = info_addr = m_rendezvous_addr;
-
- if (cursor == LLDB_INVALID_ADDRESS)
- return false;
+ if (m_rendezvous_addr == LLDB_INVALID_ADDRESS)
+ cursor = info_addr = ResolveRendezvousAddress(m_process);
+ else
+ cursor = info_addr = m_rendezvous_addr;
- if (!(cursor = ReadWord(cursor, &info.version, word_size)))
- return false;
+ if (cursor == LLDB_INVALID_ADDRESS)
+ return false;
- if (!(cursor = ReadPointer(cursor + padding, &info.map_addr)))
- return false;
+ if (!(cursor = ReadWord(cursor, &info.version, word_size)))
+ return false;
+
+ if (!(cursor = ReadPointer(cursor + padding, &info.map_addr)))
+ return false;
- if (!(cursor = ReadPointer(cursor, &info.brk)))
- return false;
+ if (!(cursor = ReadPointer(cursor, &info.brk)))
+ return false;
- if (!(cursor = ReadWord(cursor, &info.state, word_size)))
- return false;
+ if (!(cursor = ReadWord(cursor, &info.state, word_size)))
+ return false;
- if (!(cursor = ReadPointer(cursor + padding, &info.ldbase)))
- return false;
+ if (!(cursor = ReadPointer(cursor + padding, &info.ldbase)))
+ return false;
- // The rendezvous was successfully read. Update our internal state.
- m_rendezvous_addr = info_addr;
- m_previous = m_current;
- m_current = info;
+ // The rendezvous was successfully read. Update our internal state.
+ m_rendezvous_addr = info_addr;
+ m_previous = m_current;
+ m_current = info;
- return UpdateSOEntries();
+ return UpdateSOEntries();
}
-void
-HexagonDYLDRendezvous::SetRendezvousAddress( lldb::addr_t addr )
-{
- m_rendezvous_addr = addr;
+void HexagonDYLDRendezvous::SetRendezvousAddress(lldb::addr_t addr) {
+ m_rendezvous_addr = addr;
}
-bool
-HexagonDYLDRendezvous::IsValid()
-{
- return m_rendezvous_addr != LLDB_INVALID_ADDRESS;
+bool HexagonDYLDRendezvous::IsValid() {
+ return m_rendezvous_addr != LLDB_INVALID_ADDRESS;
}
-bool
-HexagonDYLDRendezvous::UpdateSOEntries()
-{
- SOEntry entry;
-
- if (m_current.map_addr == 0)
- return false;
-
- // When the previous and current states are consistent this is the first
- // time we have been asked to update. Just take a snapshot of the currently
- // loaded modules.
- if (m_previous.state == eConsistent && m_current.state == eConsistent)
- return TakeSnapshot(m_soentries);
-
- // If we are about to add or remove a shared object clear out the current
- // state and take a snapshot of the currently loaded images.
- if (m_current.state == eAdd || m_current.state == eDelete)
- {
- // this is a fudge so that we can clear the assert below.
- m_previous.state = eConsistent;
- // We hit this assert on the 2nd run of this function after running the calc example
- assert(m_previous.state == eConsistent);
- m_soentries.clear();
- m_added_soentries.clear();
- m_removed_soentries.clear();
- return TakeSnapshot(m_soentries);
- }
- assert(m_current.state == eConsistent);
-
- // Otherwise check the previous state to determine what to expect and update
- // accordingly.
- if (m_previous.state == eAdd)
- return UpdateSOEntriesForAddition();
- else if (m_previous.state == eDelete)
- return UpdateSOEntriesForDeletion();
+bool HexagonDYLDRendezvous::UpdateSOEntries() {
+ SOEntry entry;
+ if (m_current.map_addr == 0)
return false;
+
+ // When the previous and current states are consistent this is the first
+ // time we have been asked to update. Just take a snapshot of the currently
+ // loaded modules.
+ if (m_previous.state == eConsistent && m_current.state == eConsistent)
+ return TakeSnapshot(m_soentries);
+
+ // If we are about to add or remove a shared object clear out the current
+ // state and take a snapshot of the currently loaded images.
+ if (m_current.state == eAdd || m_current.state == eDelete) {
+ // this is a fudge so that we can clear the assert below.
+ m_previous.state = eConsistent;
+ // We hit this assert on the 2nd run of this function after running the calc
+ // example
+ assert(m_previous.state == eConsistent);
+ m_soentries.clear();
+ m_added_soentries.clear();
+ m_removed_soentries.clear();
+ return TakeSnapshot(m_soentries);
+ }
+ assert(m_current.state == eConsistent);
+
+ // Otherwise check the previous state to determine what to expect and update
+ // accordingly.
+ if (m_previous.state == eAdd)
+ return UpdateSOEntriesForAddition();
+ else if (m_previous.state == eDelete)
+ return UpdateSOEntriesForDeletion();
+
+ return false;
}
-
-bool
-HexagonDYLDRendezvous::UpdateSOEntriesForAddition()
-{
- SOEntry entry;
- iterator pos;
-
- assert(m_previous.state == eAdd);
-
- if (m_current.map_addr == 0)
- return false;
-
- for (addr_t cursor = m_current.map_addr; cursor != 0; cursor = entry.next)
- {
- if (!ReadSOEntryFromMemory(cursor, entry))
- return false;
-
- // Only add shared libraries and not the executable.
- // On Linux this is indicated by an empty path in the entry.
- // On FreeBSD it is the name of the executable.
- if (entry.path.empty() || ::strcmp(entry.path.c_str(), m_exe_path) == 0)
- continue;
-
- pos = std::find(m_soentries.begin(), m_soentries.end(), entry);
- if (pos == m_soentries.end())
- {
- m_soentries.push_back(entry);
- m_added_soentries.push_back(entry);
- }
+
+bool HexagonDYLDRendezvous::UpdateSOEntriesForAddition() {
+ SOEntry entry;
+ iterator pos;
+
+ assert(m_previous.state == eAdd);
+
+ if (m_current.map_addr == 0)
+ return false;
+
+ for (addr_t cursor = m_current.map_addr; cursor != 0; cursor = entry.next) {
+ if (!ReadSOEntryFromMemory(cursor, entry))
+ return false;
+
+ // Only add shared libraries and not the executable.
+ // On Linux this is indicated by an empty path in the entry.
+ // On FreeBSD it is the name of the executable.
+ if (entry.path.empty() || ::strcmp(entry.path.c_str(), m_exe_path) == 0)
+ continue;
+
+ pos = std::find(m_soentries.begin(), m_soentries.end(), entry);
+ if (pos == m_soentries.end()) {
+ m_soentries.push_back(entry);
+ m_added_soentries.push_back(entry);
}
+ }
- return true;
+ return true;
}
-bool
-HexagonDYLDRendezvous::UpdateSOEntriesForDeletion()
-{
- SOEntryList entry_list;
- iterator pos;
+bool HexagonDYLDRendezvous::UpdateSOEntriesForDeletion() {
+ SOEntryList entry_list;
+ iterator pos;
- assert(m_previous.state == eDelete);
+ assert(m_previous.state == eDelete);
- if (!TakeSnapshot(entry_list))
- return false;
+ if (!TakeSnapshot(entry_list))
+ return false;
- for (iterator I = begin(); I != end(); ++I)
- {
- pos = std::find(entry_list.begin(), entry_list.end(), *I);
- if (pos == entry_list.end())
- m_removed_soentries.push_back(*I);
- }
+ for (iterator I = begin(); I != end(); ++I) {
+ pos = std::find(entry_list.begin(), entry_list.end(), *I);
+ if (pos == entry_list.end())
+ m_removed_soentries.push_back(*I);
+ }
- m_soentries = entry_list;
- return true;
+ m_soentries = entry_list;
+ return true;
}
-bool
-HexagonDYLDRendezvous::TakeSnapshot(SOEntryList &entry_list)
-{
- SOEntry entry;
+bool HexagonDYLDRendezvous::TakeSnapshot(SOEntryList &entry_list) {
+ SOEntry entry;
- if (m_current.map_addr == 0)
- return false;
+ if (m_current.map_addr == 0)
+ return false;
- for (addr_t cursor = m_current.map_addr; cursor != 0; cursor = entry.next)
- {
- if (!ReadSOEntryFromMemory(cursor, entry))
- return false;
+ for (addr_t cursor = m_current.map_addr; cursor != 0; cursor = entry.next) {
+ if (!ReadSOEntryFromMemory(cursor, entry))
+ return false;
- // Only add shared libraries and not the executable.
- // On Linux this is indicated by an empty path in the entry.
- // On FreeBSD it is the name of the executable.
- if (entry.path.empty() || ::strcmp(entry.path.c_str(), m_exe_path) == 0)
- continue;
+ // Only add shared libraries and not the executable.
+ // On Linux this is indicated by an empty path in the entry.
+ // On FreeBSD it is the name of the executable.
+ if (entry.path.empty() || ::strcmp(entry.path.c_str(), m_exe_path) == 0)
+ continue;
- entry_list.push_back(entry);
- }
+ entry_list.push_back(entry);
+ }
- return true;
+ return true;
}
-addr_t
-HexagonDYLDRendezvous::ReadWord(addr_t addr, uint64_t *dst, size_t size)
-{
- Error error;
+addr_t HexagonDYLDRendezvous::ReadWord(addr_t addr, uint64_t *dst,
+ size_t size) {
+ Error error;
- *dst = m_process->ReadUnsignedIntegerFromMemory(addr, size, 0, error);
- if (error.Fail())
- return 0;
+ *dst = m_process->ReadUnsignedIntegerFromMemory(addr, size, 0, error);
+ if (error.Fail())
+ return 0;
- return addr + size;
+ return addr + size;
}
-addr_t
-HexagonDYLDRendezvous::ReadPointer(addr_t addr, addr_t *dst)
-{
- Error error;
-
- *dst = m_process->ReadPointerFromMemory(addr, error);
- if (error.Fail())
- return 0;
+addr_t HexagonDYLDRendezvous::ReadPointer(addr_t addr, addr_t *dst) {
+ Error error;
+
+ *dst = m_process->ReadPointerFromMemory(addr, error);
+ if (error.Fail())
+ return 0;
- return addr + m_process->GetAddressByteSize();
+ return addr + m_process->GetAddressByteSize();
}
-std::string
-HexagonDYLDRendezvous::ReadStringFromMemory(addr_t addr)
-{
- std::string str;
- Error error;
- size_t size;
- char c;
-
- if (addr == LLDB_INVALID_ADDRESS)
- return std::string();
-
- for (;;) {
- size = m_process->DoReadMemory(addr, &c, 1, error);
- if (size != 1 || error.Fail())
- return std::string();
- if (c == 0)
- break;
- else {
- str.push_back(c);
- addr++;
- }
+std::string HexagonDYLDRendezvous::ReadStringFromMemory(addr_t addr) {
+ std::string str;
+ Error error;
+ size_t size;
+ char c;
+
+ if (addr == LLDB_INVALID_ADDRESS)
+ return std::string();
+
+ for (;;) {
+ size = m_process->DoReadMemory(addr, &c, 1, error);
+ if (size != 1 || error.Fail())
+ return std::string();
+ if (c == 0)
+ break;
+ else {
+ str.push_back(c);
+ addr++;
}
+ }
- return str;
+ return str;
}
-bool
-HexagonDYLDRendezvous::ReadSOEntryFromMemory(lldb::addr_t addr, SOEntry &entry)
-{
- entry.clear();
- entry.link_addr = addr;
-
- if (!(addr = ReadPointer(addr, &entry.base_addr)))
- return false;
-
- if (!(addr = ReadPointer(addr, &entry.path_addr)))
- return false;
-
- if (!(addr = ReadPointer(addr, &entry.dyn_addr)))
- return false;
-
- if (!(addr = ReadPointer(addr, &entry.next)))
- return false;
-
- if (!(addr = ReadPointer(addr, &entry.prev)))
- return false;
-
- entry.path = ReadStringFromMemory(entry.path_addr);
-
- return true;
-}
+bool HexagonDYLDRendezvous::ReadSOEntryFromMemory(lldb::addr_t addr,
+ SOEntry &entry) {
+ entry.clear();
+ entry.link_addr = addr;
+
+ if (!(addr = ReadPointer(addr, &entry.base_addr)))
+ return false;
-bool
-HexagonDYLDRendezvous::FindMetadata(const char *name, PThreadField field, uint32_t& value)
-{
- Target& target = m_process->GetTarget();
+ if (!(addr = ReadPointer(addr, &entry.path_addr)))
+ return false;
- SymbolContextList list;
- if (!target.GetImages().FindSymbolsWithNameAndType (ConstString(name), eSymbolTypeAny, list))
- return false;
+ if (!(addr = ReadPointer(addr, &entry.dyn_addr)))
+ return false;
- Address address = list[0].symbol->GetAddress();
- addr_t addr = address.GetLoadAddress (&target);
- if (addr == LLDB_INVALID_ADDRESS)
- return false;
+ if (!(addr = ReadPointer(addr, &entry.next)))
+ return false;
- Error error;
- value = (uint32_t)m_process->ReadUnsignedIntegerFromMemory(addr + field*sizeof(uint32_t), sizeof(uint32_t), 0, error);
- if (error.Fail())
- return false;
+ if (!(addr = ReadPointer(addr, &entry.prev)))
+ return false;
- if (field == eSize)
- value /= 8; // convert bits to bytes
+ entry.path = ReadStringFromMemory(entry.path_addr);
- return true;
+ return true;
}
-const HexagonDYLDRendezvous::ThreadInfo&
-HexagonDYLDRendezvous::GetThreadInfo()
-{
- if (!m_thread_info.valid)
- {
- bool ok = true;
+bool HexagonDYLDRendezvous::FindMetadata(const char *name, PThreadField field,
+ uint32_t &value) {
+ Target &target = m_process->GetTarget();
- ok &= FindMetadata ("_thread_db_pthread_dtvp", eOffset, m_thread_info.dtv_offset);
- ok &= FindMetadata ("_thread_db_dtv_dtv", eSize, m_thread_info.dtv_slot_size);
- ok &= FindMetadata ("_thread_db_link_map_l_tls_modid", eOffset, m_thread_info.modid_offset);
- ok &= FindMetadata ("_thread_db_dtv_t_pointer_val", eOffset, m_thread_info.tls_offset);
+ SymbolContextList list;
+ if (!target.GetImages().FindSymbolsWithNameAndType(ConstString(name),
+ eSymbolTypeAny, list))
+ return false;
- if (ok)
- m_thread_info.valid = true;
- }
+ Address address = list[0].symbol->GetAddress();
+ addr_t addr = address.GetLoadAddress(&target);
+ if (addr == LLDB_INVALID_ADDRESS)
+ return false;
+
+ Error error;
+ value = (uint32_t)m_process->ReadUnsignedIntegerFromMemory(
+ addr + field * sizeof(uint32_t), sizeof(uint32_t), 0, error);
+ if (error.Fail())
+ return false;
- return m_thread_info;
+ if (field == eSize)
+ value /= 8; // convert bits to bytes
+
+ return true;
}
-void
-HexagonDYLDRendezvous::DumpToLog(Log *log) const
-{
- int state = GetState();
-
- if (!log)
- return;
-
- log->PutCString("HexagonDYLDRendezvous:");
- log->Printf(" Address: %" PRIx64, GetRendezvousAddress());
- log->Printf(" Version: %" PRIu64, GetVersion());
- log->Printf(" Link : %" PRIx64, GetLinkMapAddress());
- log->Printf(" Break : %" PRIx64, GetBreakAddress());
- log->Printf(" LDBase : %" PRIx64, GetLDBase());
- log->Printf(" State : %s",
- (state == eConsistent) ? "consistent" :
- (state == eAdd) ? "add" :
- (state == eDelete) ? "delete" : "unknown");
-
- iterator I = begin();
- iterator E = end();
-
- if (I != E)
- log->PutCString("HexagonDYLDRendezvous SOEntries:");
-
- for (int i = 1; I != E; ++I, ++i)
- {
- log->Printf("\n SOEntry [%d] %s", i, I->path.c_str());
- log->Printf(" Base : %" PRIx64, I->base_addr);
- log->Printf(" Path : %" PRIx64, I->path_addr);
- log->Printf(" Dyn : %" PRIx64, I->dyn_addr);
- log->Printf(" Next : %" PRIx64, I->next);
- log->Printf(" Prev : %" PRIx64, I->prev);
- }
+const HexagonDYLDRendezvous::ThreadInfo &
+HexagonDYLDRendezvous::GetThreadInfo() {
+ if (!m_thread_info.valid) {
+ bool ok = true;
+
+ ok &= FindMetadata("_thread_db_pthread_dtvp", eOffset,
+ m_thread_info.dtv_offset);
+ ok &=
+ FindMetadata("_thread_db_dtv_dtv", eSize, m_thread_info.dtv_slot_size);
+ ok &= FindMetadata("_thread_db_link_map_l_tls_modid", eOffset,
+ m_thread_info.modid_offset);
+ ok &= FindMetadata("_thread_db_dtv_t_pointer_val", eOffset,
+ m_thread_info.tls_offset);
+
+ if (ok)
+ m_thread_info.valid = true;
+ }
+
+ return m_thread_info;
+}
+
+void HexagonDYLDRendezvous::DumpToLog(Log *log) const {
+ int state = GetState();
+
+ if (!log)
+ return;
+
+ log->PutCString("HexagonDYLDRendezvous:");
+ log->Printf(" Address: %" PRIx64, GetRendezvousAddress());
+ log->Printf(" Version: %" PRIu64, GetVersion());
+ log->Printf(" Link : %" PRIx64, GetLinkMapAddress());
+ log->Printf(" Break : %" PRIx64, GetBreakAddress());
+ log->Printf(" LDBase : %" PRIx64, GetLDBase());
+ log->Printf(" State : %s",
+ (state == eConsistent)
+ ? "consistent"
+ : (state == eAdd) ? "add" : (state == eDelete) ? "delete"
+ : "unknown");
+
+ iterator I = begin();
+ iterator E = end();
+
+ if (I != E)
+ log->PutCString("HexagonDYLDRendezvous SOEntries:");
+
+ for (int i = 1; I != E; ++I, ++i) {
+ log->Printf("\n SOEntry [%d] %s", i, I->path.c_str());
+ log->Printf(" Base : %" PRIx64, I->base_addr);
+ log->Printf(" Path : %" PRIx64, I->path_addr);
+ log->Printf(" Dyn : %" PRIx64, I->dyn_addr);
+ log->Printf(" Next : %" PRIx64, I->next);
+ log->Printf(" Prev : %" PRIx64, I->prev);
+ }
}
diff --git a/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.h b/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.h
index cd512133045..b68f89b9ce8 100644
--- a/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.h
+++ b/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.h
@@ -19,9 +19,8 @@
#include "lldb/lldb-defines.h"
#include "lldb/lldb-types.h"
-namespace lldb_private
-{
- class Process;
+namespace lldb_private {
+class Process;
}
/// @class HexagonDYLDRendezvous
@@ -31,249 +30,218 @@ namespace lldb_private
/// runtime liker each time a module is loaded or unloaded. This class provides
/// an interface to this structure and maintains a consistent snapshot of the
/// currently loaded modules.
-class HexagonDYLDRendezvous
-{
-
- // This structure is used to hold the contents of the debug rendezvous
- // information (struct r_debug) as found in the inferiors memory. Note that
- // the layout of this struct is not binary compatible, it is simply large
- // enough to hold the information on both 32 and 64 bit platforms.
- struct Rendezvous {
- uint64_t version;
- lldb::addr_t map_addr;
- lldb::addr_t brk;
- uint64_t state;
- lldb::addr_t ldbase;
-
- Rendezvous()
- : version (0)
- , map_addr(LLDB_INVALID_ADDRESS)
- , brk (LLDB_INVALID_ADDRESS)
- , state (0)
- , ldbase (0)
- { }
-
- };
+class HexagonDYLDRendezvous {
+
+ // This structure is used to hold the contents of the debug rendezvous
+ // information (struct r_debug) as found in the inferiors memory. Note that
+ // the layout of this struct is not binary compatible, it is simply large
+ // enough to hold the information on both 32 and 64 bit platforms.
+ struct Rendezvous {
+ uint64_t version;
+ lldb::addr_t map_addr;
+ lldb::addr_t brk;
+ uint64_t state;
+ lldb::addr_t ldbase;
+
+ Rendezvous()
+ : version(0), map_addr(LLDB_INVALID_ADDRESS), brk(LLDB_INVALID_ADDRESS),
+ state(0), ldbase(0) {}
+ };
public:
- // Various metadata supplied by the inferior's threading library to describe
- // the per-thread state.
- struct ThreadInfo {
- bool valid; // whether we read valid metadata
- uint32_t dtv_offset; // offset of DTV pointer within pthread
- uint32_t dtv_slot_size; // size of one DTV slot
- uint32_t modid_offset; // offset of module ID within link_map
- uint32_t tls_offset; // offset of TLS pointer within DTV slot
- };
-
- HexagonDYLDRendezvous(lldb_private::Process *process);
-
- /// Update the internal snapshot of runtime linker rendezvous and recompute
- /// the currently loaded modules.
- ///
- /// This method should be called once one start up, then once each time the
- /// runtime linker enters the function given by GetBreakAddress().
- ///
- /// @returns true on success and false on failure.
- ///
- /// @see GetBreakAddress().
- bool
- Resolve();
-
- /// @returns true if this rendezvous has been located in the inferiors
- /// address space and false otherwise.
- bool
- IsValid();
-
- /// @returns the address of the rendezvous structure in the inferiors
- /// address space.
- lldb::addr_t
- GetRendezvousAddress() const { return m_rendezvous_addr; }
-
- /// Provide the dyld structure address
- void
- SetRendezvousAddress( lldb::addr_t );
-
- /// @returns the version of the rendezvous protocol being used.
- uint64_t
- GetVersion() const { return m_current.version; }
-
- /// @returns address in the inferiors address space containing the linked
- /// list of shared object descriptors.
- lldb::addr_t
- GetLinkMapAddress() const { return m_current.map_addr; }
-
- /// A breakpoint should be set at this address and Resolve called on each
- /// hit.
- ///
- /// @returns the address of a function called by the runtime linker each
- /// time a module is loaded/unloaded, or about to be loaded/unloaded.
- ///
- /// @see Resolve()
- lldb::addr_t
- GetBreakAddress() const { return m_current.brk; }
-
- /// In hexagon it is possible that we can know the dyld breakpoint without
- /// having to find it from the rendezvous structure
- ///
- void
- SetBreakAddress( lldb::addr_t addr ) { m_current.brk = addr; }
-
- /// Returns the current state of the rendezvous structure.
- uint64_t
- GetState() const { return m_current.state; }
-
- /// @returns the base address of the runtime linker in the inferiors address
- /// space.
- lldb::addr_t
- GetLDBase() const { return m_current.ldbase; }
-
- /// @returns the thread layout metadata from the inferiors thread library.
- const ThreadInfo&
- GetThreadInfo();
-
- /// @returns true if modules have been loaded into the inferior since the
- /// last call to Resolve().
- bool
- ModulesDidLoad() const { return !m_added_soentries.empty(); }
-
- /// @returns true if modules have been unloaded from the inferior since the
- /// last call to Resolve().
- bool
- ModulesDidUnload() const { return !m_removed_soentries.empty(); }
-
- void
- DumpToLog(lldb_private::Log *log) const;
-
- /// @brief Constants describing the state of the rendezvous.
- ///
- /// @see GetState().
- enum RendezvousState
- {
- eConsistent = 0,
- eAdd ,
- eDelete ,
- };
-
- /// @brief Structure representing the shared objects currently loaded into
- /// the inferior process.
- ///
- /// This object is a rough analogue to the struct link_map object which
- /// actually lives in the inferiors memory.
- struct SOEntry {
- lldb::addr_t link_addr; ///< Address of this link_map.
- lldb::addr_t base_addr; ///< Base address of the loaded object.
- lldb::addr_t path_addr; ///< String naming the shared object.
- lldb::addr_t dyn_addr; ///< Dynamic section of shared object.
- lldb::addr_t next; ///< Address of next so_entry.
- lldb::addr_t prev; ///< Address of previous so_entry.
- std::string path; ///< File name of shared object.
-
- SOEntry() { clear(); }
-
- bool operator ==(const SOEntry &entry) {
- return this->path == entry.path;
- }
-
- void clear() {
- link_addr = 0;
- base_addr = 0;
- path_addr = 0;
- dyn_addr = 0;
- next = 0;
- prev = 0;
- path.clear();
- }
- };
+ // Various metadata supplied by the inferior's threading library to describe
+ // the per-thread state.
+ struct ThreadInfo {
+ bool valid; // whether we read valid metadata
+ uint32_t dtv_offset; // offset of DTV pointer within pthread
+ uint32_t dtv_slot_size; // size of one DTV slot
+ uint32_t modid_offset; // offset of module ID within link_map
+ uint32_t tls_offset; // offset of TLS pointer within DTV slot
+ };
+
+ HexagonDYLDRendezvous(lldb_private::Process *process);
+
+ /// Update the internal snapshot of runtime linker rendezvous and recompute
+ /// the currently loaded modules.
+ ///
+ /// This method should be called once one start up, then once each time the
+ /// runtime linker enters the function given by GetBreakAddress().
+ ///
+ /// @returns true on success and false on failure.
+ ///
+ /// @see GetBreakAddress().
+ bool Resolve();
+
+ /// @returns true if this rendezvous has been located in the inferiors
+ /// address space and false otherwise.
+ bool IsValid();
+
+ /// @returns the address of the rendezvous structure in the inferiors
+ /// address space.
+ lldb::addr_t GetRendezvousAddress() const { return m_rendezvous_addr; }
+
+ /// Provide the dyld structure address
+ void SetRendezvousAddress(lldb::addr_t);
+
+ /// @returns the version of the rendezvous protocol being used.
+ uint64_t GetVersion() const { return m_current.version; }
+
+ /// @returns address in the inferiors address space containing the linked
+ /// list of shared object descriptors.
+ lldb::addr_t GetLinkMapAddress() const { return m_current.map_addr; }
+
+ /// A breakpoint should be set at this address and Resolve called on each
+ /// hit.
+ ///
+ /// @returns the address of a function called by the runtime linker each
+ /// time a module is loaded/unloaded, or about to be loaded/unloaded.
+ ///
+ /// @see Resolve()
+ lldb::addr_t GetBreakAddress() const { return m_current.brk; }
+
+ /// In hexagon it is possible that we can know the dyld breakpoint without
+ /// having to find it from the rendezvous structure
+ ///
+ void SetBreakAddress(lldb::addr_t addr) { m_current.brk = addr; }
+
+ /// Returns the current state of the rendezvous structure.
+ uint64_t GetState() const { return m_current.state; }
+
+ /// @returns the base address of the runtime linker in the inferiors address
+ /// space.
+ lldb::addr_t GetLDBase() const { return m_current.ldbase; }
+
+ /// @returns the thread layout metadata from the inferiors thread library.
+ const ThreadInfo &GetThreadInfo();
+
+ /// @returns true if modules have been loaded into the inferior since the
+ /// last call to Resolve().
+ bool ModulesDidLoad() const { return !m_added_soentries.empty(); }
+
+ /// @returns true if modules have been unloaded from the inferior since the
+ /// last call to Resolve().
+ bool ModulesDidUnload() const { return !m_removed_soentries.empty(); }
+
+ void DumpToLog(lldb_private::Log *log) const;
+
+ /// @brief Constants describing the state of the rendezvous.
+ ///
+ /// @see GetState().
+ enum RendezvousState {
+ eConsistent = 0,
+ eAdd,
+ eDelete,
+ };
+
+ /// @brief Structure representing the shared objects currently loaded into
+ /// the inferior process.
+ ///
+ /// This object is a rough analogue to the struct link_map object which
+ /// actually lives in the inferiors memory.
+ struct SOEntry {
+ lldb::addr_t link_addr; ///< Address of this link_map.
+ lldb::addr_t base_addr; ///< Base address of the loaded object.
+ lldb::addr_t path_addr; ///< String naming the shared object.
+ lldb::addr_t dyn_addr; ///< Dynamic section of shared object.
+ lldb::addr_t next; ///< Address of next so_entry.
+ lldb::addr_t prev; ///< Address of previous so_entry.
+ std::string path; ///< File name of shared object.
+
+ SOEntry() { clear(); }
+
+ bool operator==(const SOEntry &entry) { return this->path == entry.path; }
+
+ void clear() {
+ link_addr = 0;
+ base_addr = 0;
+ path_addr = 0;
+ dyn_addr = 0;
+ next = 0;
+ prev = 0;
+ path.clear();
+ }
+ };
protected:
- typedef std::list<SOEntry> SOEntryList;
+ typedef std::list<SOEntry> SOEntryList;
public:
- typedef SOEntryList::const_iterator iterator;
-
- /// Iterators over all currently loaded modules.
- iterator begin() const { return m_soentries.begin(); }
- iterator end() const { return m_soentries.end(); }
-
- /// Iterators over all modules loaded into the inferior since the last call
- /// to Resolve().
- iterator loaded_begin() const { return m_added_soentries.begin(); }
- iterator loaded_end() const { return m_added_soentries.end(); }
-
- /// Iterators over all modules unloaded from the inferior since the last
- /// call to Resolve().
- iterator unloaded_begin() const { return m_removed_soentries.begin(); }
- iterator unloaded_end() const { return m_removed_soentries.end(); }
-
+ typedef SOEntryList::const_iterator iterator;
+
+ /// Iterators over all currently loaded modules.
+ iterator begin() const { return m_soentries.begin(); }
+ iterator end() const { return m_soentries.end(); }
+
+ /// Iterators over all modules loaded into the inferior since the last call
+ /// to Resolve().
+ iterator loaded_begin() const { return m_added_soentries.begin(); }
+ iterator loaded_end() const { return m_added_soentries.end(); }
+
+ /// Iterators over all modules unloaded from the inferior since the last
+ /// call to Resolve().
+ iterator unloaded_begin() const { return m_removed_soentries.begin(); }
+ iterator unloaded_end() const { return m_removed_soentries.end(); }
+
protected:
- lldb_private::Process *m_process;
+ lldb_private::Process *m_process;
- // Cached copy of executable pathname
- char m_exe_path[PATH_MAX];
+ // Cached copy of executable pathname
+ char m_exe_path[PATH_MAX];
- /// Location of the r_debug structure in the inferiors address space.
- lldb::addr_t m_rendezvous_addr;
+ /// Location of the r_debug structure in the inferiors address space.
+ lldb::addr_t m_rendezvous_addr;
- /// Current and previous snapshots of the rendezvous structure.
- Rendezvous m_current;
- Rendezvous m_previous;
+ /// Current and previous snapshots of the rendezvous structure.
+ Rendezvous m_current;
+ Rendezvous m_previous;
- /// List of SOEntry objects corresponding to the current link map state.
- SOEntryList m_soentries;
+ /// List of SOEntry objects corresponding to the current link map state.
+ SOEntryList m_soentries;
- /// List of SOEntry's added to the link map since the last call to Resolve().
- SOEntryList m_added_soentries;
+ /// List of SOEntry's added to the link map since the last call to Resolve().
+ SOEntryList m_added_soentries;
- /// List of SOEntry's removed from the link map since the last call to
- /// Resolve().
- SOEntryList m_removed_soentries;
+ /// List of SOEntry's removed from the link map since the last call to
+ /// Resolve().
+ SOEntryList m_removed_soentries;
- /// Threading metadata read from the inferior.
- ThreadInfo m_thread_info;
+ /// Threading metadata read from the inferior.
+ ThreadInfo m_thread_info;
- /// Reads an unsigned integer of @p size bytes from the inferior's address
- /// space starting at @p addr.
- ///
- /// @returns addr + size if the read was successful and false otherwise.
- lldb::addr_t
- ReadWord(lldb::addr_t addr, uint64_t *dst, size_t size);
+ /// Reads an unsigned integer of @p size bytes from the inferior's address
+ /// space starting at @p addr.
+ ///
+ /// @returns addr + size if the read was successful and false otherwise.
+ lldb::addr_t ReadWord(lldb::addr_t addr, uint64_t *dst, size_t size);
- /// Reads an address from the inferior's address space starting at @p addr.
- ///
- /// @returns addr + target address size if the read was successful and
- /// 0 otherwise.
- lldb::addr_t
- ReadPointer(lldb::addr_t addr, lldb::addr_t *dst);
+ /// Reads an address from the inferior's address space starting at @p addr.
+ ///
+ /// @returns addr + target address size if the read was successful and
+ /// 0 otherwise.
+ lldb::addr_t ReadPointer(lldb::addr_t addr, lldb::addr_t *dst);
- /// Reads a null-terminated C string from the memory location starting at @p
- /// addr.
- std::string
- ReadStringFromMemory(lldb::addr_t addr);
+ /// Reads a null-terminated C string from the memory location starting at @p
+ /// addr.
+ std::string ReadStringFromMemory(lldb::addr_t addr);
- /// Reads an SOEntry starting at @p addr.
- bool
- ReadSOEntryFromMemory(lldb::addr_t addr, SOEntry &entry);
+ /// Reads an SOEntry starting at @p addr.
+ bool ReadSOEntryFromMemory(lldb::addr_t addr, SOEntry &entry);
- /// Updates the current set of SOEntries, the set of added entries, and the
- /// set of removed entries.
- bool
- UpdateSOEntries();
+ /// Updates the current set of SOEntries, the set of added entries, and the
+ /// set of removed entries.
+ bool UpdateSOEntries();
- bool
- UpdateSOEntriesForAddition();
+ bool UpdateSOEntriesForAddition();
- bool
- UpdateSOEntriesForDeletion();
+ bool UpdateSOEntriesForDeletion();
- /// Reads the current list of shared objects according to the link map
- /// supplied by the runtime linker.
- bool
- TakeSnapshot(SOEntryList &entry_list);
+ /// Reads the current list of shared objects according to the link map
+ /// supplied by the runtime linker.
+ bool TakeSnapshot(SOEntryList &entry_list);
- enum PThreadField { eSize, eNElem, eOffset };
+ enum PThreadField { eSize, eNElem, eOffset };
- bool FindMetadata(const char *name, PThreadField field, uint32_t& value);
+ bool FindMetadata(const char *name, PThreadField field, uint32_t &value);
};
#endif // liblldb_HexagonDYLDRendezvous_H_
diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp
index b880bd0faf6..0dbdff3f86a 100644
--- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp
+++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp
@@ -35,7 +35,7 @@
//#define ENABLE_DEBUG_PRINTF // COMMENT THIS LINE OUT PRIOR TO CHECKIN
#ifdef ENABLE_DEBUG_PRINTF
#include <stdio.h>
-#define DEBUG_PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__)
+#define DEBUG_PRINTF(fmt, ...) printf(fmt, ##__VA_ARGS__)
#else
#define DEBUG_PRINTF(fmt, ...)
#endif
@@ -49,29 +49,18 @@
using namespace lldb;
using namespace lldb_private;
-
//----------------------------------------------------------------------
// Constructor
//----------------------------------------------------------------------
-DynamicLoaderDarwin::DynamicLoaderDarwin (Process* process)
- : DynamicLoader(process),
- m_dyld_module_wp(),
- m_libpthread_module_wp(),
- m_pthread_getspecific_addr(),
- m_tid_to_tls_map(),
- m_dyld_image_infos(),
- m_dyld_image_infos_stop_id(UINT32_MAX),
- m_dyld(),
- m_mutex()
-{
-}
+DynamicLoaderDarwin::DynamicLoaderDarwin(Process *process)
+ : DynamicLoader(process), m_dyld_module_wp(), m_libpthread_module_wp(),
+ m_pthread_getspecific_addr(), m_tid_to_tls_map(), m_dyld_image_infos(),
+ m_dyld_image_infos_stop_id(UINT32_MAX), m_dyld(), m_mutex() {}
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
-DynamicLoaderDarwin::~DynamicLoaderDarwin()
-{
-}
+DynamicLoaderDarwin::~DynamicLoaderDarwin() {}
//------------------------------------------------------------------
/// Called after attaching a process.
@@ -79,12 +68,10 @@ DynamicLoaderDarwin::~DynamicLoaderDarwin()
/// Allow DynamicLoader plug-ins to execute some code after
/// attaching to a process.
//------------------------------------------------------------------
-void
-DynamicLoaderDarwin::DidAttach ()
-{
- PrivateInitialize(m_process);
- DoInitialImageFetch ();
- SetNotificationBreakpoint ();
+void DynamicLoaderDarwin::DidAttach() {
+ PrivateInitialize(m_process);
+ DoInitialImageFetch();
+ SetNotificationBreakpoint();
}
//------------------------------------------------------------------
@@ -93,640 +80,618 @@ DynamicLoaderDarwin::DidAttach ()
/// Allow DynamicLoader plug-ins to execute some code after
/// attaching to a process.
//------------------------------------------------------------------
-void
-DynamicLoaderDarwin::DidLaunch ()
-{
- PrivateInitialize(m_process);
- DoInitialImageFetch ();
- SetNotificationBreakpoint ();
+void DynamicLoaderDarwin::DidLaunch() {
+ PrivateInitialize(m_process);
+ DoInitialImageFetch();
+ SetNotificationBreakpoint();
}
-
//----------------------------------------------------------------------
// Clear out the state of this class.
//----------------------------------------------------------------------
-void
-DynamicLoaderDarwin::Clear (bool clear_process)
-{
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- if (clear_process)
- m_process = NULL;
- m_dyld_image_infos.clear();
- m_dyld_image_infos_stop_id = UINT32_MAX;
- m_dyld.Clear(false);
+void DynamicLoaderDarwin::Clear(bool clear_process) {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ if (clear_process)
+ m_process = NULL;
+ m_dyld_image_infos.clear();
+ m_dyld_image_infos_stop_id = UINT32_MAX;
+ m_dyld.Clear(false);
}
-ModuleSP
-DynamicLoaderDarwin::FindTargetModuleForImageInfo (ImageInfo &image_info, bool can_create, bool *did_create_ptr)
-{
- if (did_create_ptr)
- *did_create_ptr = false;
-
- Target &target = m_process->GetTarget();
- const ModuleList &target_images = target.GetImages();
- ModuleSpec module_spec (image_info.file_spec);
- module_spec.GetUUID() = image_info.uuid;
- ModuleSP module_sp (target_images.FindFirstModule (module_spec));
-
- if (module_sp && !module_spec.GetUUID().IsValid() && !module_sp->GetUUID().IsValid())
- {
- // No UUID, we must rely upon the cached module modification
- // time and the modification time of the file on disk
- if (module_sp->GetModificationTime() != module_sp->GetFileSpec().GetModificationTime())
- module_sp.reset();
- }
-
- if (!module_sp)
- {
- if (can_create)
- {
- module_sp = target.GetSharedModule (module_spec);
- if (!module_sp || module_sp->GetObjectFile() == NULL)
- module_sp = m_process->ReadModuleFromMemory (image_info.file_spec, image_info.address);
-
- if (did_create_ptr)
- *did_create_ptr = (bool) module_sp;
- }
+ModuleSP DynamicLoaderDarwin::FindTargetModuleForImageInfo(
+ ImageInfo &image_info, bool can_create, bool *did_create_ptr) {
+ if (did_create_ptr)
+ *did_create_ptr = false;
+
+ Target &target = m_process->GetTarget();
+ const ModuleList &target_images = target.GetImages();
+ ModuleSpec module_spec(image_info.file_spec);
+ module_spec.GetUUID() = image_info.uuid;
+ ModuleSP module_sp(target_images.FindFirstModule(module_spec));
+
+ if (module_sp && !module_spec.GetUUID().IsValid() &&
+ !module_sp->GetUUID().IsValid()) {
+ // No UUID, we must rely upon the cached module modification
+ // time and the modification time of the file on disk
+ if (module_sp->GetModificationTime() !=
+ module_sp->GetFileSpec().GetModificationTime())
+ module_sp.reset();
+ }
+
+ if (!module_sp) {
+ if (can_create) {
+ module_sp = target.GetSharedModule(module_spec);
+ if (!module_sp || module_sp->GetObjectFile() == NULL)
+ module_sp = m_process->ReadModuleFromMemory(image_info.file_spec,
+ image_info.address);
+
+ if (did_create_ptr)
+ *did_create_ptr = (bool)module_sp;
}
- return module_sp;
+ }
+ return module_sp;
}
-void
-DynamicLoaderDarwin::UnloadImages (const std::vector<lldb::addr_t> &solib_addresses)
-{
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- if (m_process->GetStopID() == m_dyld_image_infos_stop_id)
- return;
-
- Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
- Target &target = m_process->GetTarget();
- if (log)
- log->Printf ("Removing %" PRId64 " modules.", (uint64_t) solib_addresses.size());
-
- ModuleList unloaded_module_list;
-
- for (addr_t solib_addr : solib_addresses)
- {
- Address header;
- if (header.SetLoadAddress (solib_addr, &target))
- {
- if (header.GetOffset() == 0)
- {
- ModuleSP module_to_remove (header.GetModule());
- if (module_to_remove.get())
- {
- if (log)
- log->Printf ("Removing module at address 0x%" PRIx64, solib_addr);
- // remove the sections from the Target
- UnloadSections (module_to_remove);
- // add this to the list of modules to remove
- unloaded_module_list.AppendIfNeeded (module_to_remove);
- // remove the entry from the m_dyld_image_infos
- ImageInfo::collection::iterator pos, end = m_dyld_image_infos.end();
- for (pos = m_dyld_image_infos.begin(); pos != end; pos++)
- {
- if (solib_addr == (*pos).address)
- {
- m_dyld_image_infos.erase(pos);
- break;
- }
- }
- }
+void DynamicLoaderDarwin::UnloadImages(
+ const std::vector<lldb::addr_t> &solib_addresses) {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ if (m_process->GetStopID() == m_dyld_image_infos_stop_id)
+ return;
+
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+ Target &target = m_process->GetTarget();
+ if (log)
+ log->Printf("Removing %" PRId64 " modules.",
+ (uint64_t)solib_addresses.size());
+
+ ModuleList unloaded_module_list;
+
+ for (addr_t solib_addr : solib_addresses) {
+ Address header;
+ if (header.SetLoadAddress(solib_addr, &target)) {
+ if (header.GetOffset() == 0) {
+ ModuleSP module_to_remove(header.GetModule());
+ if (module_to_remove.get()) {
+ if (log)
+ log->Printf("Removing module at address 0x%" PRIx64, solib_addr);
+ // remove the sections from the Target
+ UnloadSections(module_to_remove);
+ // add this to the list of modules to remove
+ unloaded_module_list.AppendIfNeeded(module_to_remove);
+ // remove the entry from the m_dyld_image_infos
+ ImageInfo::collection::iterator pos, end = m_dyld_image_infos.end();
+ for (pos = m_dyld_image_infos.begin(); pos != end; pos++) {
+ if (solib_addr == (*pos).address) {
+ m_dyld_image_infos.erase(pos);
+ break;
}
+ }
}
+ }
}
+ }
- if (unloaded_module_list.GetSize() > 0)
- {
- if (log)
- {
- log->PutCString("Unloaded:");
- unloaded_module_list.LogUUIDAndPaths (log, "DynamicLoaderDarwin::UnloadModules");
- }
- m_process->GetTarget().GetImages().Remove (unloaded_module_list);
- m_dyld_image_infos_stop_id = m_process->GetStopID();
+ if (unloaded_module_list.GetSize() > 0) {
+ if (log) {
+ log->PutCString("Unloaded:");
+ unloaded_module_list.LogUUIDAndPaths(
+ log, "DynamicLoaderDarwin::UnloadModules");
}
+ m_process->GetTarget().GetImages().Remove(unloaded_module_list);
+ m_dyld_image_infos_stop_id = m_process->GetStopID();
+ }
}
-void
-DynamicLoaderDarwin::UnloadAllImages ()
-{
- Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
- ModuleList unloaded_modules_list;
+void DynamicLoaderDarwin::UnloadAllImages() {
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+ ModuleList unloaded_modules_list;
- Target &target = m_process->GetTarget();
- const ModuleList &target_modules = target.GetImages();
- std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
-
- size_t num_modules = target_modules.GetSize();
- ModuleSP dyld_sp (GetDYLDModule());
-
- for (size_t i = 0; i < num_modules; i++)
- {
- ModuleSP module_sp = target_modules.GetModuleAtIndexUnlocked (i);
-
- // Don't remove dyld - else we'll lose our breakpoint notifying us about libraries
- // being re-loaded...
- if (module_sp.get() != nullptr
- && module_sp.get() != dyld_sp.get())
- {
- UnloadSections (module_sp);
- unloaded_modules_list.Append (module_sp);
- }
+ Target &target = m_process->GetTarget();
+ const ModuleList &target_modules = target.GetImages();
+ std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
+
+ size_t num_modules = target_modules.GetSize();
+ ModuleSP dyld_sp(GetDYLDModule());
+
+ for (size_t i = 0; i < num_modules; i++) {
+ ModuleSP module_sp = target_modules.GetModuleAtIndexUnlocked(i);
+
+ // Don't remove dyld - else we'll lose our breakpoint notifying us about
+ // libraries
+ // being re-loaded...
+ if (module_sp.get() != nullptr && module_sp.get() != dyld_sp.get()) {
+ UnloadSections(module_sp);
+ unloaded_modules_list.Append(module_sp);
}
+ }
- if (unloaded_modules_list.GetSize() != 0)
- {
- if (log)
- {
- log->PutCString("Unloaded:");
- unloaded_modules_list.LogUUIDAndPaths (log, "DynamicLoaderDarwin::UnloadAllImages");
- }
- target.GetImages().Remove(unloaded_modules_list);
- m_dyld_image_infos.clear();
- m_dyld_image_infos_stop_id = m_process->GetStopID();
+ if (unloaded_modules_list.GetSize() != 0) {
+ if (log) {
+ log->PutCString("Unloaded:");
+ unloaded_modules_list.LogUUIDAndPaths(
+ log, "DynamicLoaderDarwin::UnloadAllImages");
}
+ target.GetImages().Remove(unloaded_modules_list);
+ m_dyld_image_infos.clear();
+ m_dyld_image_infos_stop_id = m_process->GetStopID();
+ }
}
//----------------------------------------------------------------------
// Update the load addresses for all segments in MODULE using the
// updated INFO that is passed in.
//----------------------------------------------------------------------
-bool
-DynamicLoaderDarwin::UpdateImageLoadAddress (Module *module, ImageInfo& info)
-{
- bool changed = false;
- if (module)
- {
- ObjectFile *image_object_file = module->GetObjectFile();
- if (image_object_file)
- {
- SectionList *section_list = image_object_file->GetSectionList ();
- if (section_list)
- {
- std::vector<uint32_t> inaccessible_segment_indexes;
- // We now know the slide amount, so go through all sections
- // and update the load addresses with the correct values.
- const size_t num_segments = info.segments.size();
- for (size_t i=0; i<num_segments; ++i)
- {
- // Only load a segment if it has protections. Things like
- // __PAGEZERO don't have any protections, and they shouldn't
- // be slid
- SectionSP section_sp(section_list->FindSectionByName(info.segments[i].name));
-
- if (info.segments[i].maxprot == 0)
- {
- inaccessible_segment_indexes.push_back(i);
- }
- else
- {
- const addr_t new_section_load_addr = info.segments[i].vmaddr + info.slide;
- static ConstString g_section_name_LINKEDIT ("__LINKEDIT");
-
- if (section_sp)
- {
- // __LINKEDIT sections from files in the shared cache
- // can overlap so check to see what the segment name is
- // and pass "false" so we don't warn of overlapping
- // "Section" objects, and "true" for all other sections.
- const bool warn_multiple = section_sp->GetName() != g_section_name_LINKEDIT;
-
- changed = m_process->GetTarget().SetSectionLoadAddress (section_sp, new_section_load_addr, warn_multiple);
- }
- else
- {
- Host::SystemLog (Host::eSystemLogWarning,
- "warning: unable to find and load segment named '%s' at 0x%" PRIx64 " in '%s' in macosx dynamic loader plug-in.\n",
- info.segments[i].name.AsCString("<invalid>"),
- (uint64_t)new_section_load_addr,
- image_object_file->GetFileSpec().GetPath().c_str());
- }
- }
- }
-
- // If the loaded the file (it changed) and we have segments that
- // are not readable or writeable, add them to the invalid memory
- // region cache for the process. This will typically only be
- // the __PAGEZERO segment in the main executable. We might be able
- // to apply this more generally to more sections that have no
- // protections in the future, but for now we are going to just
- // do __PAGEZERO.
- if (changed && !inaccessible_segment_indexes.empty())
- {
- for (uint32_t i=0; i<inaccessible_segment_indexes.size(); ++i)
- {
- const uint32_t seg_idx = inaccessible_segment_indexes[i];
- SectionSP section_sp(section_list->FindSectionByName(info.segments[seg_idx].name));
-
- if (section_sp)
- {
- static ConstString g_pagezero_section_name("__PAGEZERO");
- if (g_pagezero_section_name == section_sp->GetName())
- {
- // __PAGEZERO never slides...
- const lldb::addr_t vmaddr = info.segments[seg_idx].vmaddr;
- const lldb::addr_t vmsize = info.segments[seg_idx].vmsize;
- Process::LoadRange pagezero_range (vmaddr, vmsize);
- m_process->AddInvalidMemoryRegion(pagezero_range);
- }
- }
- }
- }
+bool DynamicLoaderDarwin::UpdateImageLoadAddress(Module *module,
+ ImageInfo &info) {
+ bool changed = false;
+ if (module) {
+ ObjectFile *image_object_file = module->GetObjectFile();
+ if (image_object_file) {
+ SectionList *section_list = image_object_file->GetSectionList();
+ if (section_list) {
+ std::vector<uint32_t> inaccessible_segment_indexes;
+ // We now know the slide amount, so go through all sections
+ // and update the load addresses with the correct values.
+ const size_t num_segments = info.segments.size();
+ for (size_t i = 0; i < num_segments; ++i) {
+ // Only load a segment if it has protections. Things like
+ // __PAGEZERO don't have any protections, and they shouldn't
+ // be slid
+ SectionSP section_sp(
+ section_list->FindSectionByName(info.segments[i].name));
+
+ if (info.segments[i].maxprot == 0) {
+ inaccessible_segment_indexes.push_back(i);
+ } else {
+ const addr_t new_section_load_addr =
+ info.segments[i].vmaddr + info.slide;
+ static ConstString g_section_name_LINKEDIT("__LINKEDIT");
+
+ if (section_sp) {
+ // __LINKEDIT sections from files in the shared cache
+ // can overlap so check to see what the segment name is
+ // and pass "false" so we don't warn of overlapping
+ // "Section" objects, and "true" for all other sections.
+ const bool warn_multiple =
+ section_sp->GetName() != g_section_name_LINKEDIT;
+
+ changed = m_process->GetTarget().SetSectionLoadAddress(
+ section_sp, new_section_load_addr, warn_multiple);
+ } else {
+ Host::SystemLog(
+ Host::eSystemLogWarning,
+ "warning: unable to find and load segment named '%s' at "
+ "0x%" PRIx64 " in '%s' in macosx dynamic loader plug-in.\n",
+ info.segments[i].name.AsCString("<invalid>"),
+ (uint64_t)new_section_load_addr,
+ image_object_file->GetFileSpec().GetPath().c_str());
}
+ }
}
+
+ // If the loaded the file (it changed) and we have segments that
+ // are not readable or writeable, add them to the invalid memory
+ // region cache for the process. This will typically only be
+ // the __PAGEZERO segment in the main executable. We might be able
+ // to apply this more generally to more sections that have no
+ // protections in the future, but for now we are going to just
+ // do __PAGEZERO.
+ if (changed && !inaccessible_segment_indexes.empty()) {
+ for (uint32_t i = 0; i < inaccessible_segment_indexes.size(); ++i) {
+ const uint32_t seg_idx = inaccessible_segment_indexes[i];
+ SectionSP section_sp(
+ section_list->FindSectionByName(info.segments[seg_idx].name));
+
+ if (section_sp) {
+ static ConstString g_pagezero_section_name("__PAGEZERO");
+ if (g_pagezero_section_name == section_sp->GetName()) {
+ // __PAGEZERO never slides...
+ const lldb::addr_t vmaddr = info.segments[seg_idx].vmaddr;
+ const lldb::addr_t vmsize = info.segments[seg_idx].vmsize;
+ Process::LoadRange pagezero_range(vmaddr, vmsize);
+ m_process->AddInvalidMemoryRegion(pagezero_range);
+ }
+ }
+ }
+ }
+ }
}
- // We might have an in memory image that was loaded as soon as it was created
- if (info.load_stop_id == m_process->GetStopID())
- changed = true;
- else if (changed)
- {
- // Update the stop ID when this library was updated
- info.load_stop_id = m_process->GetStopID();
- }
- return changed;
+ }
+ // We might have an in memory image that was loaded as soon as it was created
+ if (info.load_stop_id == m_process->GetStopID())
+ changed = true;
+ else if (changed) {
+ // Update the stop ID when this library was updated
+ info.load_stop_id = m_process->GetStopID();
+ }
+ return changed;
}
//----------------------------------------------------------------------
// Unload the segments in MODULE using the INFO that is passed in.
//----------------------------------------------------------------------
-bool
-DynamicLoaderDarwin::UnloadModuleSections (Module *module, ImageInfo& info)
-{
- bool changed = false;
- if (module)
- {
- ObjectFile *image_object_file = module->GetObjectFile();
- if (image_object_file)
- {
- SectionList *section_list = image_object_file->GetSectionList ();
- if (section_list)
- {
- const size_t num_segments = info.segments.size();
- for (size_t i=0; i<num_segments; ++i)
- {
- SectionSP section_sp(section_list->FindSectionByName(info.segments[i].name));
- if (section_sp)
- {
- const addr_t old_section_load_addr = info.segments[i].vmaddr + info.slide;
- if (m_process->GetTarget().SetSectionUnloaded (section_sp, old_section_load_addr))
- changed = true;
- }
- else
- {
- Host::SystemLog (Host::eSystemLogWarning,
- "warning: unable to find and unload segment named '%s' in '%s' in macosx dynamic loader plug-in.\n",
- info.segments[i].name.AsCString("<invalid>"),
- image_object_file->GetFileSpec().GetPath().c_str());
- }
- }
- }
+bool DynamicLoaderDarwin::UnloadModuleSections(Module *module,
+ ImageInfo &info) {
+ bool changed = false;
+ if (module) {
+ ObjectFile *image_object_file = module->GetObjectFile();
+ if (image_object_file) {
+ SectionList *section_list = image_object_file->GetSectionList();
+ if (section_list) {
+ const size_t num_segments = info.segments.size();
+ for (size_t i = 0; i < num_segments; ++i) {
+ SectionSP section_sp(
+ section_list->FindSectionByName(info.segments[i].name));
+ if (section_sp) {
+ const addr_t old_section_load_addr =
+ info.segments[i].vmaddr + info.slide;
+ if (m_process->GetTarget().SetSectionUnloaded(
+ section_sp, old_section_load_addr))
+ changed = true;
+ } else {
+ Host::SystemLog(Host::eSystemLogWarning,
+ "warning: unable to find and unload segment named "
+ "'%s' in '%s' in macosx dynamic loader plug-in.\n",
+ info.segments[i].name.AsCString("<invalid>"),
+ image_object_file->GetFileSpec().GetPath().c_str());
+ }
}
+ }
}
- return changed;
+ }
+ return changed;
}
-
-// Given a JSON dictionary (from debugserver, most likely) of binary images loaded in the inferior
+// Given a JSON dictionary (from debugserver, most likely) of binary images
+// loaded in the inferior
// process, add the images to the ImageInfo collection.
-bool
-DynamicLoaderDarwin::JSONImageInformationIntoImageInfo (StructuredData::ObjectSP image_details, ImageInfo::collection &image_infos)
-{
- StructuredData::ObjectSP images_sp = image_details->GetAsDictionary()->GetValueForKey("images");
- if (images_sp.get() == nullptr)
- return false;
-
- image_infos.resize (images_sp->GetAsArray()->GetSize());
-
- for (size_t i = 0; i < image_infos.size(); i++)
- {
- StructuredData::ObjectSP image_sp = images_sp->GetAsArray()->GetItemAtIndex(i);
- if (image_sp.get() == nullptr || image_sp->GetAsDictionary() == nullptr)
- return false;
- StructuredData::Dictionary *image = image_sp->GetAsDictionary();
- if (image->HasKey("load_address") == false
- || image->HasKey("pathname") == false
- || image->HasKey("mod_date") == false
- || image->HasKey("mach_header") == false
- || image->GetValueForKey("mach_header")->GetAsDictionary() == nullptr
- || image->HasKey("segments") == false
- || image->GetValueForKey("segments")->GetAsArray() == nullptr
- || image->HasKey("uuid") == false )
- {
- return false;
- }
- image_infos[i].address = image->GetValueForKey("load_address")->GetAsInteger()->GetValue();
- image_infos[i].mod_date = image->GetValueForKey("mod_date")->GetAsInteger()->GetValue();
- image_infos[i].file_spec.SetFile(image->GetValueForKey("pathname")->GetAsString()->GetValue().c_str(), false);
-
- StructuredData::Dictionary *mh = image->GetValueForKey("mach_header")->GetAsDictionary();
- image_infos[i].header.magic = mh->GetValueForKey("magic")->GetAsInteger()->GetValue();
- image_infos[i].header.cputype = mh->GetValueForKey("cputype")->GetAsInteger()->GetValue();
- image_infos[i].header.cpusubtype = mh->GetValueForKey("cpusubtype")->GetAsInteger()->GetValue();
- image_infos[i].header.filetype = mh->GetValueForKey("filetype")->GetAsInteger()->GetValue();
-
- if (image->HasKey("min_version_os_name"))
- {
- std::string os_name = image->GetValueForKey("min_version_os_name")->GetAsString()->GetValue();
- if (os_name == "macosx")
- image_infos[i].os_type = llvm::Triple::MacOSX;
- else if (os_name == "ios" || os_name == "iphoneos")
- image_infos[i].os_type = llvm::Triple::IOS;
- else if (os_name == "tvos")
- image_infos[i].os_type = llvm::Triple::TvOS;
- else if (os_name == "watchos")
- image_infos[i].os_type = llvm::Triple::WatchOS;
- }
- if (image->HasKey("min_version_os_sdk"))
- {
- image_infos[i].min_version_os_sdk = image->GetValueForKey("min_version_os_sdk")->GetAsString()->GetValue();
- }
+bool DynamicLoaderDarwin::JSONImageInformationIntoImageInfo(
+ StructuredData::ObjectSP image_details,
+ ImageInfo::collection &image_infos) {
+ StructuredData::ObjectSP images_sp =
+ image_details->GetAsDictionary()->GetValueForKey("images");
+ if (images_sp.get() == nullptr)
+ return false;
- // Fields that aren't used by DynamicLoaderDarwin so debugserver doesn't currently send them
- // in the reply.
-
- if (mh->HasKey("flags"))
- image_infos[i].header.flags = mh->GetValueForKey("flags")->GetAsInteger()->GetValue();
- else
- image_infos[i].header.flags = 0;
-
- if (mh->HasKey("ncmds"))
- image_infos[i].header.ncmds = mh->GetValueForKey("ncmds")->GetAsInteger()->GetValue();
- else
- image_infos[i].header.ncmds = 0;
-
- if (mh->HasKey("sizeofcmds"))
- image_infos[i].header.sizeofcmds = mh->GetValueForKey("sizeofcmds")->GetAsInteger()->GetValue();
- else
- image_infos[i].header.sizeofcmds = 0;
-
- StructuredData::Array *segments = image->GetValueForKey("segments")->GetAsArray();
- uint32_t segcount = segments->GetSize();
- for (size_t j = 0; j < segcount; j++)
- {
- Segment segment;
- StructuredData::Dictionary *seg = segments->GetItemAtIndex(j)->GetAsDictionary();
- segment.name = ConstString(seg->GetValueForKey("name")->GetAsString()->GetValue().c_str());
- segment.vmaddr = seg->GetValueForKey("vmaddr")->GetAsInteger()->GetValue();
- segment.vmsize = seg->GetValueForKey("vmsize")->GetAsInteger()->GetValue();
- segment.fileoff = seg->GetValueForKey("fileoff")->GetAsInteger()->GetValue();
- segment.filesize = seg->GetValueForKey("filesize")->GetAsInteger()->GetValue();
- segment.maxprot = seg->GetValueForKey("maxprot")->GetAsInteger()->GetValue();
-
- // Fields that aren't used by DynamicLoaderDarwin so debugserver doesn't currently send them
- // in the reply.
-
- if (seg->HasKey("initprot"))
- segment.initprot = seg->GetValueForKey("initprot")->GetAsInteger()->GetValue();
- else
- segment.initprot = 0;
-
- if (seg->HasKey("flags"))
- segment.flags = seg->GetValueForKey("flags")->GetAsInteger()->GetValue();
- else
- segment.flags = 0;
-
- if (seg->HasKey("nsects"))
- segment.nsects = seg->GetValueForKey("nsects")->GetAsInteger()->GetValue();
- else
- segment.nsects = 0;
-
- image_infos[i].segments.push_back (segment);
- }
+ image_infos.resize(images_sp->GetAsArray()->GetSize());
+
+ for (size_t i = 0; i < image_infos.size(); i++) {
+ StructuredData::ObjectSP image_sp =
+ images_sp->GetAsArray()->GetItemAtIndex(i);
+ if (image_sp.get() == nullptr || image_sp->GetAsDictionary() == nullptr)
+ return false;
+ StructuredData::Dictionary *image = image_sp->GetAsDictionary();
+ if (image->HasKey("load_address") == false ||
+ image->HasKey("pathname") == false ||
+ image->HasKey("mod_date") == false ||
+ image->HasKey("mach_header") == false ||
+ image->GetValueForKey("mach_header")->GetAsDictionary() == nullptr ||
+ image->HasKey("segments") == false ||
+ image->GetValueForKey("segments")->GetAsArray() == nullptr ||
+ image->HasKey("uuid") == false) {
+ return false;
+ }
+ image_infos[i].address =
+ image->GetValueForKey("load_address")->GetAsInteger()->GetValue();
+ image_infos[i].mod_date =
+ image->GetValueForKey("mod_date")->GetAsInteger()->GetValue();
+ image_infos[i].file_spec.SetFile(
+ image->GetValueForKey("pathname")->GetAsString()->GetValue().c_str(),
+ false);
+
+ StructuredData::Dictionary *mh =
+ image->GetValueForKey("mach_header")->GetAsDictionary();
+ image_infos[i].header.magic =
+ mh->GetValueForKey("magic")->GetAsInteger()->GetValue();
+ image_infos[i].header.cputype =
+ mh->GetValueForKey("cputype")->GetAsInteger()->GetValue();
+ image_infos[i].header.cpusubtype =
+ mh->GetValueForKey("cpusubtype")->GetAsInteger()->GetValue();
+ image_infos[i].header.filetype =
+ mh->GetValueForKey("filetype")->GetAsInteger()->GetValue();
+
+ if (image->HasKey("min_version_os_name")) {
+ std::string os_name = image->GetValueForKey("min_version_os_name")
+ ->GetAsString()
+ ->GetValue();
+ if (os_name == "macosx")
+ image_infos[i].os_type = llvm::Triple::MacOSX;
+ else if (os_name == "ios" || os_name == "iphoneos")
+ image_infos[i].os_type = llvm::Triple::IOS;
+ else if (os_name == "tvos")
+ image_infos[i].os_type = llvm::Triple::TvOS;
+ else if (os_name == "watchos")
+ image_infos[i].os_type = llvm::Triple::WatchOS;
+ }
+ if (image->HasKey("min_version_os_sdk")) {
+ image_infos[i].min_version_os_sdk =
+ image->GetValueForKey("min_version_os_sdk")
+ ->GetAsString()
+ ->GetValue();
+ }
- image_infos[i].uuid.SetFromCString (image->GetValueForKey("uuid")->GetAsString()->GetValue().c_str());
-
- // All sections listed in the dyld image info structure will all
- // either be fixed up already, or they will all be off by a single
- // slide amount that is determined by finding the first segment
- // that is at file offset zero which also has bytes (a file size
- // that is greater than zero) in the object file.
-
- // Determine the slide amount (if any)
- const size_t num_sections = image_infos[i].segments.size();
- for (size_t k = 0; k < num_sections; ++k)
- {
- // Iterate through the object file sections to find the
- // first section that starts of file offset zero and that
- // has bytes in the file...
- if ((image_infos[i].segments[k].fileoff == 0 && image_infos[i].segments[k].filesize > 0)
- || (image_infos[i].segments[k].name == ConstString("__TEXT")))
- {
- image_infos[i].slide = image_infos[i].address - image_infos[i].segments[k].vmaddr;
- // We have found the slide amount, so we can exit
- // this for loop.
- break;
- }
- }
+ // Fields that aren't used by DynamicLoaderDarwin so debugserver doesn't
+ // currently send them
+ // in the reply.
+
+ if (mh->HasKey("flags"))
+ image_infos[i].header.flags =
+ mh->GetValueForKey("flags")->GetAsInteger()->GetValue();
+ else
+ image_infos[i].header.flags = 0;
+
+ if (mh->HasKey("ncmds"))
+ image_infos[i].header.ncmds =
+ mh->GetValueForKey("ncmds")->GetAsInteger()->GetValue();
+ else
+ image_infos[i].header.ncmds = 0;
+
+ if (mh->HasKey("sizeofcmds"))
+ image_infos[i].header.sizeofcmds =
+ mh->GetValueForKey("sizeofcmds")->GetAsInteger()->GetValue();
+ else
+ image_infos[i].header.sizeofcmds = 0;
+
+ StructuredData::Array *segments =
+ image->GetValueForKey("segments")->GetAsArray();
+ uint32_t segcount = segments->GetSize();
+ for (size_t j = 0; j < segcount; j++) {
+ Segment segment;
+ StructuredData::Dictionary *seg =
+ segments->GetItemAtIndex(j)->GetAsDictionary();
+ segment.name = ConstString(
+ seg->GetValueForKey("name")->GetAsString()->GetValue().c_str());
+ segment.vmaddr =
+ seg->GetValueForKey("vmaddr")->GetAsInteger()->GetValue();
+ segment.vmsize =
+ seg->GetValueForKey("vmsize")->GetAsInteger()->GetValue();
+ segment.fileoff =
+ seg->GetValueForKey("fileoff")->GetAsInteger()->GetValue();
+ segment.filesize =
+ seg->GetValueForKey("filesize")->GetAsInteger()->GetValue();
+ segment.maxprot =
+ seg->GetValueForKey("maxprot")->GetAsInteger()->GetValue();
+
+ // Fields that aren't used by DynamicLoaderDarwin so debugserver doesn't
+ // currently send them
+ // in the reply.
+
+ if (seg->HasKey("initprot"))
+ segment.initprot =
+ seg->GetValueForKey("initprot")->GetAsInteger()->GetValue();
+ else
+ segment.initprot = 0;
+
+ if (seg->HasKey("flags"))
+ segment.flags =
+ seg->GetValueForKey("flags")->GetAsInteger()->GetValue();
+ else
+ segment.flags = 0;
+
+ if (seg->HasKey("nsects"))
+ segment.nsects =
+ seg->GetValueForKey("nsects")->GetAsInteger()->GetValue();
+ else
+ segment.nsects = 0;
+
+ image_infos[i].segments.push_back(segment);
+ }
+
+ image_infos[i].uuid.SetFromCString(
+ image->GetValueForKey("uuid")->GetAsString()->GetValue().c_str());
+
+ // All sections listed in the dyld image info structure will all
+ // either be fixed up already, or they will all be off by a single
+ // slide amount that is determined by finding the first segment
+ // that is at file offset zero which also has bytes (a file size
+ // that is greater than zero) in the object file.
+
+ // Determine the slide amount (if any)
+ const size_t num_sections = image_infos[i].segments.size();
+ for (size_t k = 0; k < num_sections; ++k) {
+ // Iterate through the object file sections to find the
+ // first section that starts of file offset zero and that
+ // has bytes in the file...
+ if ((image_infos[i].segments[k].fileoff == 0 &&
+ image_infos[i].segments[k].filesize > 0) ||
+ (image_infos[i].segments[k].name == ConstString("__TEXT"))) {
+ image_infos[i].slide =
+ image_infos[i].address - image_infos[i].segments[k].vmaddr;
+ // We have found the slide amount, so we can exit
+ // this for loop.
+ break;
+ }
}
+ }
- return true;
+ return true;
}
-void
-DynamicLoaderDarwin::UpdateSpecialBinariesFromNewImageInfos (ImageInfo::collection &image_infos)
-{
- uint32_t exe_idx = UINT32_MAX;
- uint32_t dyld_idx = UINT32_MAX;
- Target &target = m_process->GetTarget();
- Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
- ConstString g_dyld_sim_filename ("dyld_sim");
-
- ArchSpec target_arch = target.GetArchitecture();
- const size_t image_infos_size = image_infos.size();
- for (size_t i = 0; i < image_infos_size; i++)
- {
- if (image_infos[i].header.filetype == llvm::MachO::MH_DYLINKER)
- {
- // In a "simulator" process (an x86 process that is ios/tvos/watchos)
- // we will have two dyld modules -- a "dyld" that we want to keep track of,
- // and a "dyld_sim" which we don't need to keep track of here.
- // If the target is an x86 system and the OS of the dyld binary is
- // ios/tvos/watchos, then we are looking at dyld_sym.
-
- // debugserver has only recently (late 2016) started sending up the
- // os type for each binary it sees -- so if we don't have an os
- // type, use a filename check as our next best guess.
- if (image_infos[i].os_type == llvm::Triple::OSType::UnknownOS)
- {
- if (image_infos[i].file_spec.GetFilename() != g_dyld_sim_filename)
- {
- dyld_idx = i;
- }
- }
- else if (target_arch.GetTriple().getArch() == llvm::Triple::x86
- || target_arch.GetTriple().getArch() == llvm::Triple::x86_64)
- {
- if (image_infos[i].os_type != llvm::Triple::OSType::IOS
- && image_infos[i].os_type != llvm::Triple::TvOS
- && image_infos[i].os_type != llvm::Triple::WatchOS)
- {
- dyld_idx = i;
- }
- }
+void DynamicLoaderDarwin::UpdateSpecialBinariesFromNewImageInfos(
+ ImageInfo::collection &image_infos) {
+ uint32_t exe_idx = UINT32_MAX;
+ uint32_t dyld_idx = UINT32_MAX;
+ Target &target = m_process->GetTarget();
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+ ConstString g_dyld_sim_filename("dyld_sim");
+
+ ArchSpec target_arch = target.GetArchitecture();
+ const size_t image_infos_size = image_infos.size();
+ for (size_t i = 0; i < image_infos_size; i++) {
+ if (image_infos[i].header.filetype == llvm::MachO::MH_DYLINKER) {
+ // In a "simulator" process (an x86 process that is ios/tvos/watchos)
+ // we will have two dyld modules -- a "dyld" that we want to keep track
+ // of,
+ // and a "dyld_sim" which we don't need to keep track of here.
+ // If the target is an x86 system and the OS of the dyld binary is
+ // ios/tvos/watchos, then we are looking at dyld_sym.
+
+ // debugserver has only recently (late 2016) started sending up the
+ // os type for each binary it sees -- so if we don't have an os
+ // type, use a filename check as our next best guess.
+ if (image_infos[i].os_type == llvm::Triple::OSType::UnknownOS) {
+ if (image_infos[i].file_spec.GetFilename() != g_dyld_sim_filename) {
+ dyld_idx = i;
}
- else if (image_infos[i].header.filetype == llvm::MachO::MH_EXECUTE)
- {
- exe_idx = i;
+ } else if (target_arch.GetTriple().getArch() == llvm::Triple::x86 ||
+ target_arch.GetTriple().getArch() == llvm::Triple::x86_64) {
+ if (image_infos[i].os_type != llvm::Triple::OSType::IOS &&
+ image_infos[i].os_type != llvm::Triple::TvOS &&
+ image_infos[i].os_type != llvm::Triple::WatchOS) {
+ dyld_idx = i;
}
+ }
+ } else if (image_infos[i].header.filetype == llvm::MachO::MH_EXECUTE) {
+ exe_idx = i;
}
-
- if (exe_idx != UINT32_MAX)
- {
- const bool can_create = true;
- ModuleSP exe_module_sp (FindTargetModuleForImageInfo (image_infos[exe_idx], can_create, NULL));
- if (exe_module_sp)
- {
- if (log)
- log->Printf ("Found executable module: %s", exe_module_sp->GetFileSpec().GetPath().c_str());
- target.GetImages().AppendIfNeeded (exe_module_sp);
- UpdateImageLoadAddress (exe_module_sp.get(), image_infos[exe_idx]);
- if (exe_module_sp.get() != target.GetExecutableModulePointer())
- {
- const bool get_dependent_images = false;
- target.SetExecutableModule (exe_module_sp, get_dependent_images);
- }
- }
+ }
+
+ if (exe_idx != UINT32_MAX) {
+ const bool can_create = true;
+ ModuleSP exe_module_sp(
+ FindTargetModuleForImageInfo(image_infos[exe_idx], can_create, NULL));
+ if (exe_module_sp) {
+ if (log)
+ log->Printf("Found executable module: %s",
+ exe_module_sp->GetFileSpec().GetPath().c_str());
+ target.GetImages().AppendIfNeeded(exe_module_sp);
+ UpdateImageLoadAddress(exe_module_sp.get(), image_infos[exe_idx]);
+ if (exe_module_sp.get() != target.GetExecutableModulePointer()) {
+ const bool get_dependent_images = false;
+ target.SetExecutableModule(exe_module_sp, get_dependent_images);
+ }
}
-
- if (dyld_idx != UINT32_MAX)
- {
- const bool can_create = true;
- ModuleSP dyld_sp = FindTargetModuleForImageInfo (image_infos[dyld_idx], can_create, NULL);
- if (dyld_sp.get())
- {
- if (log)
- log->Printf ("Found dyld module: %s", dyld_sp->GetFileSpec().GetPath().c_str());
- target.GetImages().AppendIfNeeded (dyld_sp);
- UpdateImageLoadAddress (dyld_sp.get(), image_infos[dyld_idx]);
- SetDYLDModule (dyld_sp);
- }
+ }
+
+ if (dyld_idx != UINT32_MAX) {
+ const bool can_create = true;
+ ModuleSP dyld_sp =
+ FindTargetModuleForImageInfo(image_infos[dyld_idx], can_create, NULL);
+ if (dyld_sp.get()) {
+ if (log)
+ log->Printf("Found dyld module: %s",
+ dyld_sp->GetFileSpec().GetPath().c_str());
+ target.GetImages().AppendIfNeeded(dyld_sp);
+ UpdateImageLoadAddress(dyld_sp.get(), image_infos[dyld_idx]);
+ SetDYLDModule(dyld_sp);
}
+ }
}
-void
-DynamicLoaderDarwin::UpdateDYLDImageInfoFromNewImageInfo (ImageInfo &image_info)
-{
- if (image_info.header.filetype == llvm::MachO::MH_DYLINKER)
- {
- const bool can_create = true;
- ModuleSP dyld_sp = FindTargetModuleForImageInfo (image_info, can_create, NULL);
- if (dyld_sp.get())
- {
- Target &target = m_process->GetTarget();
- target.GetImages().AppendIfNeeded (dyld_sp);
- UpdateImageLoadAddress (dyld_sp.get(), image_info);
- SetDYLDModule (dyld_sp);
- }
+void DynamicLoaderDarwin::UpdateDYLDImageInfoFromNewImageInfo(
+ ImageInfo &image_info) {
+ if (image_info.header.filetype == llvm::MachO::MH_DYLINKER) {
+ const bool can_create = true;
+ ModuleSP dyld_sp =
+ FindTargetModuleForImageInfo(image_info, can_create, NULL);
+ if (dyld_sp.get()) {
+ Target &target = m_process->GetTarget();
+ target.GetImages().AppendIfNeeded(dyld_sp);
+ UpdateImageLoadAddress(dyld_sp.get(), image_info);
+ SetDYLDModule(dyld_sp);
}
+ }
}
-void
-DynamicLoaderDarwin::SetDYLDModule (lldb::ModuleSP &dyld_module_sp)
-{
- m_dyld_module_wp = dyld_module_sp;
+void DynamicLoaderDarwin::SetDYLDModule(lldb::ModuleSP &dyld_module_sp) {
+ m_dyld_module_wp = dyld_module_sp;
}
-ModuleSP
-DynamicLoaderDarwin::GetDYLDModule ()
-{
- ModuleSP dyld_sp (m_dyld_module_wp.lock());
- return dyld_sp;
+ModuleSP DynamicLoaderDarwin::GetDYLDModule() {
+ ModuleSP dyld_sp(m_dyld_module_wp.lock());
+ return dyld_sp;
}
-bool
-DynamicLoaderDarwin::AddModulesUsingImageInfos (ImageInfo::collection &image_infos)
-{
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- // Now add these images to the main list.
- ModuleList loaded_module_list;
- Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
- Target &target = m_process->GetTarget();
- ModuleList& target_images = target.GetImages();
-
- for (uint32_t idx = 0; idx < image_infos.size(); ++idx)
- {
- if (log)
- {
- log->Printf ("Adding new image at address=0x%16.16" PRIx64 ".", image_infos[idx].address);
- image_infos[idx].PutToLog (log);
- }
-
- m_dyld_image_infos.push_back(image_infos[idx]);
-
- ModuleSP image_module_sp (FindTargetModuleForImageInfo (image_infos[idx], true, NULL));
-
- if (image_module_sp)
- {
- ObjectFile *objfile = image_module_sp->GetObjectFile ();
- if (objfile)
- {
- SectionList *sections = objfile->GetSectionList();
- if (sections)
- {
- ConstString commpage_dbstr("__commpage");
- Section *commpage_section = sections->FindSectionByName(commpage_dbstr).get();
- if (commpage_section)
- {
- ModuleSpec module_spec (objfile->GetFileSpec(), image_infos[idx].GetArchitecture ());
- module_spec.GetObjectName() = commpage_dbstr;
- ModuleSP commpage_image_module_sp(target_images.FindFirstModule (module_spec));
- if (!commpage_image_module_sp)
- {
- module_spec.SetObjectOffset (objfile->GetFileOffset() + commpage_section->GetFileOffset());
- module_spec.SetObjectSize (objfile->GetByteSize());
- commpage_image_module_sp = target.GetSharedModule (module_spec);
- if (!commpage_image_module_sp || commpage_image_module_sp->GetObjectFile() == NULL)
- {
- commpage_image_module_sp = m_process->ReadModuleFromMemory (image_infos[idx].file_spec,
- image_infos[idx].address);
- // Always load a memory image right away in the target in case
- // we end up trying to read the symbol table from memory... The
- // __LINKEDIT will need to be mapped so we can figure out where
- // the symbol table bits are...
- bool changed = false;
- UpdateImageLoadAddress (commpage_image_module_sp.get(), image_infos[idx]);
- target.GetImages().Append(commpage_image_module_sp);
- if (changed)
- {
- image_infos[idx].load_stop_id = m_process->GetStopID();
- loaded_module_list.AppendIfNeeded (commpage_image_module_sp);
- }
- }
- }
- }
- }
- }
+bool DynamicLoaderDarwin::AddModulesUsingImageInfos(
+ ImageInfo::collection &image_infos) {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ // Now add these images to the main list.
+ ModuleList loaded_module_list;
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+ Target &target = m_process->GetTarget();
+ ModuleList &target_images = target.GetImages();
+
+ for (uint32_t idx = 0; idx < image_infos.size(); ++idx) {
+ if (log) {
+ log->Printf("Adding new image at address=0x%16.16" PRIx64 ".",
+ image_infos[idx].address);
+ image_infos[idx].PutToLog(log);
+ }
- // UpdateImageLoadAddress will return true if any segments
- // change load address. We need to check this so we don't
- // mention that all loaded shared libraries are newly loaded
- // each time we hit out dyld breakpoint since dyld will list all
- // shared libraries each time.
- if (UpdateImageLoadAddress (image_module_sp.get(), image_infos[idx]))
- {
- target_images.AppendIfNeeded(image_module_sp);
- loaded_module_list.AppendIfNeeded (image_module_sp);
+ m_dyld_image_infos.push_back(image_infos[idx]);
+
+ ModuleSP image_module_sp(
+ FindTargetModuleForImageInfo(image_infos[idx], true, NULL));
+
+ if (image_module_sp) {
+ ObjectFile *objfile = image_module_sp->GetObjectFile();
+ if (objfile) {
+ SectionList *sections = objfile->GetSectionList();
+ if (sections) {
+ ConstString commpage_dbstr("__commpage");
+ Section *commpage_section =
+ sections->FindSectionByName(commpage_dbstr).get();
+ if (commpage_section) {
+ ModuleSpec module_spec(objfile->GetFileSpec(),
+ image_infos[idx].GetArchitecture());
+ module_spec.GetObjectName() = commpage_dbstr;
+ ModuleSP commpage_image_module_sp(
+ target_images.FindFirstModule(module_spec));
+ if (!commpage_image_module_sp) {
+ module_spec.SetObjectOffset(objfile->GetFileOffset() +
+ commpage_section->GetFileOffset());
+ module_spec.SetObjectSize(objfile->GetByteSize());
+ commpage_image_module_sp = target.GetSharedModule(module_spec);
+ if (!commpage_image_module_sp ||
+ commpage_image_module_sp->GetObjectFile() == NULL) {
+ commpage_image_module_sp = m_process->ReadModuleFromMemory(
+ image_infos[idx].file_spec, image_infos[idx].address);
+ // Always load a memory image right away in the target in case
+ // we end up trying to read the symbol table from memory... The
+ // __LINKEDIT will need to be mapped so we can figure out where
+ // the symbol table bits are...
+ bool changed = false;
+ UpdateImageLoadAddress(commpage_image_module_sp.get(),
+ image_infos[idx]);
+ target.GetImages().Append(commpage_image_module_sp);
+ if (changed) {
+ image_infos[idx].load_stop_id = m_process->GetStopID();
+ loaded_module_list.AppendIfNeeded(commpage_image_module_sp);
+ }
+ }
}
+ }
}
+ }
+
+ // UpdateImageLoadAddress will return true if any segments
+ // change load address. We need to check this so we don't
+ // mention that all loaded shared libraries are newly loaded
+ // each time we hit out dyld breakpoint since dyld will list all
+ // shared libraries each time.
+ if (UpdateImageLoadAddress(image_module_sp.get(), image_infos[idx])) {
+ target_images.AppendIfNeeded(image_module_sp);
+ loaded_module_list.AppendIfNeeded(image_module_sp);
+ }
}
-
- if (loaded_module_list.GetSize() > 0)
- {
- if (log)
- loaded_module_list.LogUUIDAndPaths (log, "DynamicLoaderDarwin::ModulesDidLoad");
- m_process->GetTarget().ModulesDidLoad (loaded_module_list);
- }
- return true;
-}
+ }
+ if (loaded_module_list.GetSize() > 0) {
+ if (log)
+ loaded_module_list.LogUUIDAndPaths(log,
+ "DynamicLoaderDarwin::ModulesDidLoad");
+ m_process->GetTarget().ModulesDidLoad(loaded_module_list);
+ }
+ return true;
+}
//----------------------------------------------------------------------
// On Mac OS X libobjc (the Objective-C runtime) has several critical dispatch
// functions written in hand-written assembly, and also have hand-written unwind
-// information in the eh_frame section. Normally we prefer analyzing the
-// assembly instructions of a currently executing frame to unwind from that frame --
+// information in the eh_frame section. Normally we prefer analyzing the
+// assembly instructions of a currently executing frame to unwind from that
+// frame --
// but on hand-written functions this profiling can fail. We should use the
// eh_frame instructions for these functions all the time.
//
@@ -736,532 +701,474 @@ DynamicLoaderDarwin::AddModulesUsingImageInfos (ImageInfo::collection &image_inf
// of our normal default assumption that they are not.
//----------------------------------------------------------------------
-bool
-DynamicLoaderDarwin::AlwaysRelyOnEHUnwindInfo (SymbolContext &sym_ctx)
-{
- ModuleSP module_sp;
- if (sym_ctx.symbol)
- {
- module_sp = sym_ctx.symbol->GetAddressRef().GetModule();
- }
- if (module_sp.get() == NULL && sym_ctx.function)
- {
- module_sp = sym_ctx.function->GetAddressRange().GetBaseAddress().GetModule();
- }
- if (module_sp.get() == NULL)
- return false;
-
- ObjCLanguageRuntime *objc_runtime = m_process->GetObjCLanguageRuntime();
- if (objc_runtime != NULL && objc_runtime->IsModuleObjCLibrary (module_sp))
- {
- return true;
- }
-
+bool DynamicLoaderDarwin::AlwaysRelyOnEHUnwindInfo(SymbolContext &sym_ctx) {
+ ModuleSP module_sp;
+ if (sym_ctx.symbol) {
+ module_sp = sym_ctx.symbol->GetAddressRef().GetModule();
+ }
+ if (module_sp.get() == NULL && sym_ctx.function) {
+ module_sp =
+ sym_ctx.function->GetAddressRange().GetBaseAddress().GetModule();
+ }
+ if (module_sp.get() == NULL)
return false;
-}
+ ObjCLanguageRuntime *objc_runtime = m_process->GetObjCLanguageRuntime();
+ if (objc_runtime != NULL && objc_runtime->IsModuleObjCLibrary(module_sp)) {
+ return true;
+ }
+ return false;
+}
//----------------------------------------------------------------------
// Dump a Segment to the file handle provided.
//----------------------------------------------------------------------
-void
-DynamicLoaderDarwin::Segment::PutToLog (Log *log, lldb::addr_t slide) const
-{
- if (log)
- {
- if (slide == 0)
- log->Printf ("\t\t%16s [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ")",
- name.AsCString(""),
- vmaddr + slide,
- vmaddr + slide + vmsize);
- else
- log->Printf ("\t\t%16s [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ") slide = 0x%" PRIx64,
- name.AsCString(""),
- vmaddr + slide,
- vmaddr + slide + vmsize,
- slide);
- }
+void DynamicLoaderDarwin::Segment::PutToLog(Log *log,
+ lldb::addr_t slide) const {
+ if (log) {
+ if (slide == 0)
+ log->Printf("\t\t%16s [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ")",
+ name.AsCString(""), vmaddr + slide, vmaddr + slide + vmsize);
+ else
+ log->Printf("\t\t%16s [0x%16.16" PRIx64 " - 0x%16.16" PRIx64
+ ") slide = 0x%" PRIx64,
+ name.AsCString(""), vmaddr + slide, vmaddr + slide + vmsize,
+ slide);
+ }
}
const DynamicLoaderDarwin::Segment *
-DynamicLoaderDarwin::ImageInfo::FindSegment (const ConstString &name) const
-{
- const size_t num_segments = segments.size();
- for (size_t i=0; i<num_segments; ++i)
- {
- if (segments[i].name == name)
- return &segments[i];
- }
- return NULL;
+DynamicLoaderDarwin::ImageInfo::FindSegment(const ConstString &name) const {
+ const size_t num_segments = segments.size();
+ for (size_t i = 0; i < num_segments; ++i) {
+ if (segments[i].name == name)
+ return &segments[i];
+ }
+ return NULL;
}
-
//----------------------------------------------------------------------
// Dump an image info structure to the file handle provided.
//----------------------------------------------------------------------
-void
-DynamicLoaderDarwin::ImageInfo::PutToLog (Log *log) const
-{
- if (log == NULL)
- return;
- const uint8_t *u = (const uint8_t *)uuid.GetBytes();
-
- if (address == LLDB_INVALID_ADDRESS)
- {
- if (u)
- {
- 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' (UNLOADED)",
- mod_date,
- u[ 0], u[ 1], u[ 2], u[ 3],
- u[ 4], u[ 5], u[ 6], u[ 7],
- u[ 8], u[ 9], u[10], u[11],
- u[12], u[13], u[14], u[15],
- file_spec.GetPath().c_str());
- }
- else
- log->Printf("\t modtime=0x%8.8" PRIx64 " path='%s' (UNLOADED)",
- mod_date,
- file_spec.GetPath().c_str());
- }
- else
- {
- if (u)
- {
- 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'",
- address,
- mod_date,
- u[ 0], u[ 1], u[ 2], u[ 3],
- u[ 4], u[ 5], u[ 6], u[ 7],
- u[ 8], u[ 9], u[10], u[11],
- u[12], u[13], u[14], u[15],
- file_spec.GetPath().c_str());
- }
- else
- {
- log->Printf("\taddress=0x%16.16" PRIx64 " modtime=0x%8.8" PRIx64 " path='%s'",
- address,
- mod_date,
- file_spec.GetPath().c_str());
-
- }
- for (uint32_t i=0; i<segments.size(); ++i)
- segments[i].PutToLog(log, slide);
+void DynamicLoaderDarwin::ImageInfo::PutToLog(Log *log) const {
+ if (log == NULL)
+ return;
+ const uint8_t *u = (const uint8_t *)uuid.GetBytes();
+
+ if (address == LLDB_INVALID_ADDRESS) {
+ if (u) {
+ 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' (UNLOADED)",
+ mod_date, u[0], u[1], u[2], u[3], u[4], u[5], u[6], u[7],
+ u[8], u[9], u[10], u[11], u[12], u[13], u[14], u[15],
+ file_spec.GetPath().c_str());
+ } else
+ log->Printf("\t modtime=0x%8.8" PRIx64
+ " path='%s' (UNLOADED)",
+ mod_date, file_spec.GetPath().c_str());
+ } else {
+ if (u) {
+ 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'",
+ address, mod_date, u[0], u[1], u[2], u[3], u[4], u[5], u[6],
+ u[7], u[8], u[9], u[10], u[11], u[12], u[13], u[14], u[15],
+ file_spec.GetPath().c_str());
+ } else {
+ log->Printf("\taddress=0x%16.16" PRIx64 " modtime=0x%8.8" PRIx64
+ " path='%s'",
+ address, mod_date, file_spec.GetPath().c_str());
}
+ for (uint32_t i = 0; i < segments.size(); ++i)
+ segments[i].PutToLog(log, slide);
+ }
}
-void
-DynamicLoaderDarwin::PrivateInitialize(Process *process)
-{
- DEBUG_PRINTF("DynamicLoaderDarwin::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState()));
- Clear(true);
- m_process = process;
- m_process->GetTarget().ClearAllLoadedSections();
+void DynamicLoaderDarwin::PrivateInitialize(Process *process) {
+ DEBUG_PRINTF("DynamicLoaderDarwin::%s() process state = %s\n", __FUNCTION__,
+ StateAsCString(m_process->GetState()));
+ Clear(true);
+ m_process = process;
+ m_process->GetTarget().ClearAllLoadedSections();
}
//----------------------------------------------------------------------
// Member function that gets called when the process state changes.
//----------------------------------------------------------------------
-void
-DynamicLoaderDarwin::PrivateProcessStateChanged (Process *process, StateType state)
-{
- DEBUG_PRINTF("DynamicLoaderDarwin::%s(%s)\n", __FUNCTION__, StateAsCString(state));
- switch (state)
- {
- case eStateConnected:
- case eStateAttaching:
- case eStateLaunching:
- case eStateInvalid:
- case eStateUnloaded:
- case eStateExited:
- case eStateDetached:
- Clear(false);
- break;
-
- case eStateStopped:
- // Keep trying find dyld and set our notification breakpoint each time
- // we stop until we succeed
- if (!DidSetNotificationBreakpoint () && m_process->IsAlive())
- {
- if (NeedToDoInitialImageFetch ())
- DoInitialImageFetch ();
-
- SetNotificationBreakpoint ();
- }
- break;
-
- case eStateRunning:
- case eStateStepping:
- case eStateCrashed:
- case eStateSuspended:
- break;
+void DynamicLoaderDarwin::PrivateProcessStateChanged(Process *process,
+ StateType state) {
+ DEBUG_PRINTF("DynamicLoaderDarwin::%s(%s)\n", __FUNCTION__,
+ StateAsCString(state));
+ switch (state) {
+ case eStateConnected:
+ case eStateAttaching:
+ case eStateLaunching:
+ case eStateInvalid:
+ case eStateUnloaded:
+ case eStateExited:
+ case eStateDetached:
+ Clear(false);
+ break;
+
+ case eStateStopped:
+ // Keep trying find dyld and set our notification breakpoint each time
+ // we stop until we succeed
+ if (!DidSetNotificationBreakpoint() && m_process->IsAlive()) {
+ if (NeedToDoInitialImageFetch())
+ DoInitialImageFetch();
+
+ SetNotificationBreakpoint();
}
+ break;
+
+ case eStateRunning:
+ case eStateStepping:
+ case eStateCrashed:
+ case eStateSuspended:
+ break;
+ }
}
ThreadPlanSP
-DynamicLoaderDarwin::GetStepThroughTrampolinePlan (Thread &thread, bool stop_others)
-{
- ThreadPlanSP thread_plan_sp;
- StackFrame *current_frame = thread.GetStackFrameAtIndex(0).get();
- const SymbolContext &current_context = current_frame->GetSymbolContext(eSymbolContextSymbol);
- Symbol *current_symbol = current_context.symbol;
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
- TargetSP target_sp (thread.CalculateTarget());
-
- if (current_symbol != NULL)
- {
- std::vector<Address> addresses;
-
- if (current_symbol->IsTrampoline())
- {
- const ConstString &trampoline_name = current_symbol->GetMangled().GetName(current_symbol->GetLanguage(), Mangled::ePreferMangled);
-
- if (trampoline_name)
- {
- const ModuleList &images = target_sp->GetImages();
-
- SymbolContextList code_symbols;
- images.FindSymbolsWithNameAndType(trampoline_name, eSymbolTypeCode, code_symbols);
- size_t num_code_symbols = code_symbols.GetSize();
-
- if (num_code_symbols > 0)
- {
- for (uint32_t i = 0; i < num_code_symbols; i++)
- {
- SymbolContext context;
- AddressRange addr_range;
- if (code_symbols.GetContextAtIndex(i, context))
- {
- context.GetAddressRange (eSymbolContextEverything, 0, false, addr_range);
- addresses.push_back(addr_range.GetBaseAddress());
- if (log)
- {
- addr_t load_addr = addr_range.GetBaseAddress().GetLoadAddress(target_sp.get());
-
- log->Printf ("Found a trampoline target symbol at 0x%" PRIx64 ".", load_addr);
- }
- }
- }
- }
-
- SymbolContextList reexported_symbols;
- images.FindSymbolsWithNameAndType(trampoline_name, eSymbolTypeReExported, reexported_symbols);
- size_t num_reexported_symbols = reexported_symbols.GetSize();
- if (num_reexported_symbols > 0)
- {
- for (uint32_t i = 0; i < num_reexported_symbols; i++)
- {
- SymbolContext context;
- if (reexported_symbols.GetContextAtIndex(i, context))
- {
- if (context.symbol)
- {
- Symbol *actual_symbol = context.symbol->ResolveReExportedSymbol(*target_sp.get());
- if (actual_symbol)
- {
- const Address actual_symbol_addr = actual_symbol->GetAddress();
- if (actual_symbol_addr.IsValid())
- {
- addresses.push_back(actual_symbol_addr);
- if (log)
- {
- lldb::addr_t load_addr = actual_symbol_addr.GetLoadAddress(target_sp.get());
- log->Printf ("Found a re-exported symbol: %s at 0x%" PRIx64 ".",
- actual_symbol->GetName().GetCString(), load_addr);
- }
- }
- }
- }
- }
- }
- }
-
- SymbolContextList indirect_symbols;
- images.FindSymbolsWithNameAndType(trampoline_name, eSymbolTypeResolver, indirect_symbols);
- size_t num_indirect_symbols = indirect_symbols.GetSize();
- if (num_indirect_symbols > 0)
- {
- for (uint32_t i = 0; i < num_indirect_symbols; i++)
- {
- SymbolContext context;
- AddressRange addr_range;
- if (indirect_symbols.GetContextAtIndex(i, context))
- {
- context.GetAddressRange (eSymbolContextEverything, 0, false, addr_range);
- addresses.push_back(addr_range.GetBaseAddress());
- if (log)
- {
- addr_t load_addr = addr_range.GetBaseAddress().GetLoadAddress(target_sp.get());
-
- log->Printf ("Found an indirect target symbol at 0x%" PRIx64 ".", load_addr);
- }
- }
- }
- }
+DynamicLoaderDarwin::GetStepThroughTrampolinePlan(Thread &thread,
+ bool stop_others) {
+ ThreadPlanSP thread_plan_sp;
+ StackFrame *current_frame = thread.GetStackFrameAtIndex(0).get();
+ const SymbolContext &current_context =
+ current_frame->GetSymbolContext(eSymbolContextSymbol);
+ Symbol *current_symbol = current_context.symbol;
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
+ TargetSP target_sp(thread.CalculateTarget());
+
+ if (current_symbol != NULL) {
+ std::vector<Address> addresses;
+
+ if (current_symbol->IsTrampoline()) {
+ const ConstString &trampoline_name = current_symbol->GetMangled().GetName(
+ current_symbol->GetLanguage(), Mangled::ePreferMangled);
+
+ if (trampoline_name) {
+ const ModuleList &images = target_sp->GetImages();
+
+ SymbolContextList code_symbols;
+ images.FindSymbolsWithNameAndType(trampoline_name, eSymbolTypeCode,
+ code_symbols);
+ size_t num_code_symbols = code_symbols.GetSize();
+
+ if (num_code_symbols > 0) {
+ for (uint32_t i = 0; i < num_code_symbols; i++) {
+ SymbolContext context;
+ AddressRange addr_range;
+ if (code_symbols.GetContextAtIndex(i, context)) {
+ context.GetAddressRange(eSymbolContextEverything, 0, false,
+ addr_range);
+ addresses.push_back(addr_range.GetBaseAddress());
+ if (log) {
+ addr_t load_addr =
+ addr_range.GetBaseAddress().GetLoadAddress(target_sp.get());
+
+ log->Printf("Found a trampoline target symbol at 0x%" PRIx64
+ ".",
+ load_addr);
+ }
}
+ }
}
- else if (current_symbol->GetType() == eSymbolTypeReExported)
- {
- // I am not sure we could ever end up stopped AT a re-exported symbol. But just in case:
-
- const Symbol *actual_symbol = current_symbol->ResolveReExportedSymbol(*(target_sp.get()));
- if (actual_symbol)
- {
- Address target_addr(actual_symbol->GetAddress());
- if (target_addr.IsValid())
- {
- if (log)
- log->Printf ("Found a re-exported symbol: %s pointing to: %s at 0x%" PRIx64 ".",
- current_symbol->GetName().GetCString(),
- actual_symbol->GetName().GetCString(),
- target_addr.GetLoadAddress(target_sp.get()));
- addresses.push_back (target_addr.GetLoadAddress(target_sp.get()));
-
+
+ SymbolContextList reexported_symbols;
+ images.FindSymbolsWithNameAndType(
+ trampoline_name, eSymbolTypeReExported, reexported_symbols);
+ size_t num_reexported_symbols = reexported_symbols.GetSize();
+ if (num_reexported_symbols > 0) {
+ for (uint32_t i = 0; i < num_reexported_symbols; i++) {
+ SymbolContext context;
+ if (reexported_symbols.GetContextAtIndex(i, context)) {
+ if (context.symbol) {
+ Symbol *actual_symbol =
+ context.symbol->ResolveReExportedSymbol(*target_sp.get());
+ if (actual_symbol) {
+ const Address actual_symbol_addr =
+ actual_symbol->GetAddress();
+ if (actual_symbol_addr.IsValid()) {
+ addresses.push_back(actual_symbol_addr);
+ if (log) {
+ lldb::addr_t load_addr =
+ actual_symbol_addr.GetLoadAddress(target_sp.get());
+ log->Printf(
+ "Found a re-exported symbol: %s at 0x%" PRIx64 ".",
+ actual_symbol->GetName().GetCString(), load_addr);
+ }
+ }
}
+ }
}
+ }
}
-
- if (addresses.size() > 0)
- {
- // First check whether any of the addresses point to Indirect symbols, and if they do, resolve them:
- std::vector<lldb::addr_t> load_addrs;
- for (Address address : addresses)
- {
- Symbol *symbol = address.CalculateSymbolContextSymbol();
- if (symbol && symbol->IsIndirect())
- {
- Error error;
- Address symbol_address = symbol->GetAddress();
- addr_t resolved_addr = thread.GetProcess()->ResolveIndirectFunction(&symbol_address, error);
- if (error.Success())
- {
- load_addrs.push_back(resolved_addr);
- if (log)
- log->Printf("ResolveIndirectFunction found resolved target for %s at 0x%" PRIx64 ".",
- symbol->GetName().GetCString(), resolved_addr);
- }
- }
- else
- {
- load_addrs.push_back(address.GetLoadAddress(target_sp.get()));
- }
-
+
+ SymbolContextList indirect_symbols;
+ images.FindSymbolsWithNameAndType(trampoline_name, eSymbolTypeResolver,
+ indirect_symbols);
+ size_t num_indirect_symbols = indirect_symbols.GetSize();
+ if (num_indirect_symbols > 0) {
+ for (uint32_t i = 0; i < num_indirect_symbols; i++) {
+ SymbolContext context;
+ AddressRange addr_range;
+ if (indirect_symbols.GetContextAtIndex(i, context)) {
+ context.GetAddressRange(eSymbolContextEverything, 0, false,
+ addr_range);
+ addresses.push_back(addr_range.GetBaseAddress());
+ if (log) {
+ addr_t load_addr =
+ addr_range.GetBaseAddress().GetLoadAddress(target_sp.get());
+
+ log->Printf("Found an indirect target symbol at 0x%" PRIx64 ".",
+ load_addr);
+ }
}
- thread_plan_sp.reset (new ThreadPlanRunToAddress (thread, load_addrs, stop_others));
+ }
+ }
+ }
+ } else if (current_symbol->GetType() == eSymbolTypeReExported) {
+ // I am not sure we could ever end up stopped AT a re-exported symbol.
+ // But just in case:
+
+ const Symbol *actual_symbol =
+ current_symbol->ResolveReExportedSymbol(*(target_sp.get()));
+ if (actual_symbol) {
+ Address target_addr(actual_symbol->GetAddress());
+ if (target_addr.IsValid()) {
+ if (log)
+ log->Printf(
+ "Found a re-exported symbol: %s pointing to: %s at 0x%" PRIx64
+ ".",
+ current_symbol->GetName().GetCString(),
+ actual_symbol->GetName().GetCString(),
+ target_addr.GetLoadAddress(target_sp.get()));
+ addresses.push_back(target_addr.GetLoadAddress(target_sp.get()));
}
+ }
}
- else
- {
- if (log)
- log->Printf ("Could not find symbol for step through.");
+
+ if (addresses.size() > 0) {
+ // First check whether any of the addresses point to Indirect symbols, and
+ // if they do, resolve them:
+ std::vector<lldb::addr_t> load_addrs;
+ for (Address address : addresses) {
+ Symbol *symbol = address.CalculateSymbolContextSymbol();
+ if (symbol && symbol->IsIndirect()) {
+ Error error;
+ Address symbol_address = symbol->GetAddress();
+ addr_t resolved_addr = thread.GetProcess()->ResolveIndirectFunction(
+ &symbol_address, error);
+ if (error.Success()) {
+ load_addrs.push_back(resolved_addr);
+ if (log)
+ log->Printf("ResolveIndirectFunction found resolved target for "
+ "%s at 0x%" PRIx64 ".",
+ symbol->GetName().GetCString(), resolved_addr);
+ }
+ } else {
+ load_addrs.push_back(address.GetLoadAddress(target_sp.get()));
+ }
+ }
+ thread_plan_sp.reset(
+ new ThreadPlanRunToAddress(thread, load_addrs, stop_others));
}
+ } else {
+ if (log)
+ log->Printf("Could not find symbol for step through.");
+ }
- return thread_plan_sp;
+ return thread_plan_sp;
}
-size_t
-DynamicLoaderDarwin::FindEquivalentSymbols (lldb_private::Symbol *original_symbol,
- lldb_private::ModuleList &images,
- lldb_private::SymbolContextList &equivalent_symbols)
-{
- const ConstString &trampoline_name = original_symbol->GetMangled().GetName(original_symbol->GetLanguage(), Mangled::ePreferMangled);
- if (!trampoline_name)
- return 0;
-
- size_t initial_size = equivalent_symbols.GetSize();
-
- static const char *resolver_name_regex = "(_gc|_non_gc|\\$[A-Za-z0-9\\$]+)$";
- std::string equivalent_regex_buf("^");
- equivalent_regex_buf.append (trampoline_name.GetCString());
- equivalent_regex_buf.append (resolver_name_regex);
-
- RegularExpression equivalent_name_regex (equivalent_regex_buf.c_str());
- const bool append = true;
- images.FindSymbolsMatchingRegExAndType (equivalent_name_regex, eSymbolTypeCode, equivalent_symbols, append);
-
- return equivalent_symbols.GetSize() - initial_size;
+size_t DynamicLoaderDarwin::FindEquivalentSymbols(
+ lldb_private::Symbol *original_symbol, lldb_private::ModuleList &images,
+ lldb_private::SymbolContextList &equivalent_symbols) {
+ const ConstString &trampoline_name = original_symbol->GetMangled().GetName(
+ original_symbol->GetLanguage(), Mangled::ePreferMangled);
+ if (!trampoline_name)
+ return 0;
+
+ size_t initial_size = equivalent_symbols.GetSize();
+
+ static const char *resolver_name_regex = "(_gc|_non_gc|\\$[A-Za-z0-9\\$]+)$";
+ std::string equivalent_regex_buf("^");
+ equivalent_regex_buf.append(trampoline_name.GetCString());
+ equivalent_regex_buf.append(resolver_name_regex);
+
+ RegularExpression equivalent_name_regex(equivalent_regex_buf.c_str());
+ const bool append = true;
+ images.FindSymbolsMatchingRegExAndType(equivalent_name_regex, eSymbolTypeCode,
+ equivalent_symbols, append);
+
+ return equivalent_symbols.GetSize() - initial_size;
}
-lldb::ModuleSP
-DynamicLoaderDarwin::GetPThreadLibraryModule()
-{
- ModuleSP module_sp = m_libpthread_module_wp.lock();
- if (!module_sp)
- {
- SymbolContextList sc_list;
- ModuleSpec module_spec;
- module_spec.GetFileSpec().GetFilename().SetCString("libsystem_pthread.dylib");
- ModuleList module_list;
- if (m_process->GetTarget().GetImages().FindModules(module_spec, module_list))
- {
- if (module_list.GetSize() == 1)
- {
- module_sp = module_list.GetModuleAtIndex(0);
- if (module_sp)
- m_libpthread_module_wp = module_sp;
- }
- }
+lldb::ModuleSP DynamicLoaderDarwin::GetPThreadLibraryModule() {
+ ModuleSP module_sp = m_libpthread_module_wp.lock();
+ if (!module_sp) {
+ SymbolContextList sc_list;
+ ModuleSpec module_spec;
+ module_spec.GetFileSpec().GetFilename().SetCString(
+ "libsystem_pthread.dylib");
+ ModuleList module_list;
+ if (m_process->GetTarget().GetImages().FindModules(module_spec,
+ module_list)) {
+ if (module_list.GetSize() == 1) {
+ module_sp = module_list.GetModuleAtIndex(0);
+ if (module_sp)
+ m_libpthread_module_wp = module_sp;
+ }
}
- return module_sp;
+ }
+ return module_sp;
}
-Address
-DynamicLoaderDarwin::GetPthreadSetSpecificAddress()
-{
- if (!m_pthread_getspecific_addr.IsValid())
- {
- ModuleSP module_sp = GetPThreadLibraryModule();
- if (module_sp)
- {
- lldb_private::SymbolContextList sc_list;
- module_sp->FindSymbolsWithNameAndType(ConstString("pthread_getspecific"), eSymbolTypeCode, sc_list);
- SymbolContext sc;
- if (sc_list.GetContextAtIndex(0, sc))
- {
- if (sc.symbol)
- m_pthread_getspecific_addr = sc.symbol->GetAddress();
- }
- }
+Address DynamicLoaderDarwin::GetPthreadSetSpecificAddress() {
+ if (!m_pthread_getspecific_addr.IsValid()) {
+ ModuleSP module_sp = GetPThreadLibraryModule();
+ if (module_sp) {
+ lldb_private::SymbolContextList sc_list;
+ module_sp->FindSymbolsWithNameAndType(ConstString("pthread_getspecific"),
+ eSymbolTypeCode, sc_list);
+ SymbolContext sc;
+ if (sc_list.GetContextAtIndex(0, sc)) {
+ if (sc.symbol)
+ m_pthread_getspecific_addr = sc.symbol->GetAddress();
+ }
}
- return m_pthread_getspecific_addr;
+ }
+ return m_pthread_getspecific_addr;
}
lldb::addr_t
-DynamicLoaderDarwin::GetThreadLocalData(const lldb::ModuleSP module_sp, const lldb::ThreadSP thread_sp,
- lldb::addr_t tls_file_addr)
-{
- if (!thread_sp || !module_sp)
- return LLDB_INVALID_ADDRESS;
-
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
-
- const uint32_t addr_size = m_process->GetAddressByteSize();
- uint8_t buf[sizeof(lldb::addr_t) * 3];
-
- lldb_private::Address tls_addr;
- if (module_sp->ResolveFileAddress(tls_file_addr, tls_addr))
- {
- Error error;
- const size_t tsl_data_size = addr_size * 3;
- Target &target = m_process->GetTarget();
- if (target.ReadMemory(tls_addr, false, buf, tsl_data_size, error) == tsl_data_size)
- {
- const ByteOrder byte_order = m_process->GetByteOrder();
- DataExtractor data(buf, sizeof(buf), byte_order, addr_size);
- lldb::offset_t offset = addr_size; // Skip the first pointer
- const lldb::addr_t pthread_key = data.GetAddress(&offset);
- const lldb::addr_t tls_offset = data.GetAddress(&offset);
- if (pthread_key != 0)
- {
- // First check to see if we have already figured out the location
- // of TLS data for the pthread_key on a specific thread yet. If we
- // have we can re-use it since its location will not change unless
- // the process execs.
- const tid_t tid = thread_sp->GetID();
- auto tid_pos = m_tid_to_tls_map.find(tid);
- if (tid_pos != m_tid_to_tls_map.end())
- {
- auto tls_pos = tid_pos->second.find(pthread_key);
- if (tls_pos != tid_pos->second.end())
- {
- return tls_pos->second + tls_offset;
- }
- }
- StackFrameSP frame_sp = thread_sp->GetStackFrameAtIndex(0);
- if (frame_sp)
- {
- ClangASTContext *clang_ast_context = target.GetScratchClangASTContext();
-
- if (!clang_ast_context)
- return LLDB_INVALID_ADDRESS;
-
- CompilerType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
- Address pthread_getspecific_addr = GetPthreadSetSpecificAddress();
- if (pthread_getspecific_addr.IsValid())
- {
- EvaluateExpressionOptions options;
-
- lldb::ThreadPlanSP thread_plan_sp(
- new ThreadPlanCallFunction(*thread_sp, pthread_getspecific_addr, clang_void_ptr_type,
- llvm::ArrayRef<lldb::addr_t>(pthread_key), options));
-
- DiagnosticManager execution_errors;
- ExecutionContext exe_ctx(thread_sp);
- lldb::ExpressionResults results =
- m_process->RunThreadPlan(exe_ctx, thread_plan_sp, options, execution_errors);
-
- if (results == lldb::eExpressionCompleted)
- {
- lldb::ValueObjectSP result_valobj_sp = thread_plan_sp->GetReturnValueObject();
- if (result_valobj_sp)
- {
- const lldb::addr_t pthread_key_data = result_valobj_sp->GetValueAsUnsigned(0);
- if (pthread_key_data)
- {
- m_tid_to_tls_map[tid].insert(std::make_pair(pthread_key, pthread_key_data));
- return pthread_key_data + tls_offset;
- }
- }
- }
- }
+DynamicLoaderDarwin::GetThreadLocalData(const lldb::ModuleSP module_sp,
+ const lldb::ThreadSP thread_sp,
+ lldb::addr_t tls_file_addr) {
+ if (!thread_sp || !module_sp)
+ return LLDB_INVALID_ADDRESS;
+
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+
+ const uint32_t addr_size = m_process->GetAddressByteSize();
+ uint8_t buf[sizeof(lldb::addr_t) * 3];
+
+ lldb_private::Address tls_addr;
+ if (module_sp->ResolveFileAddress(tls_file_addr, tls_addr)) {
+ Error error;
+ const size_t tsl_data_size = addr_size * 3;
+ Target &target = m_process->GetTarget();
+ if (target.ReadMemory(tls_addr, false, buf, tsl_data_size, error) ==
+ tsl_data_size) {
+ const ByteOrder byte_order = m_process->GetByteOrder();
+ DataExtractor data(buf, sizeof(buf), byte_order, addr_size);
+ lldb::offset_t offset = addr_size; // Skip the first pointer
+ const lldb::addr_t pthread_key = data.GetAddress(&offset);
+ const lldb::addr_t tls_offset = data.GetAddress(&offset);
+ if (pthread_key != 0) {
+ // First check to see if we have already figured out the location
+ // of TLS data for the pthread_key on a specific thread yet. If we
+ // have we can re-use it since its location will not change unless
+ // the process execs.
+ const tid_t tid = thread_sp->GetID();
+ auto tid_pos = m_tid_to_tls_map.find(tid);
+ if (tid_pos != m_tid_to_tls_map.end()) {
+ auto tls_pos = tid_pos->second.find(pthread_key);
+ if (tls_pos != tid_pos->second.end()) {
+ return tls_pos->second + tls_offset;
+ }
+ }
+ StackFrameSP frame_sp = thread_sp->GetStackFrameAtIndex(0);
+ if (frame_sp) {
+ ClangASTContext *clang_ast_context =
+ target.GetScratchClangASTContext();
+
+ if (!clang_ast_context)
+ return LLDB_INVALID_ADDRESS;
+
+ CompilerType clang_void_ptr_type =
+ clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
+ Address pthread_getspecific_addr = GetPthreadSetSpecificAddress();
+ if (pthread_getspecific_addr.IsValid()) {
+ EvaluateExpressionOptions options;
+
+ lldb::ThreadPlanSP thread_plan_sp(new ThreadPlanCallFunction(
+ *thread_sp, pthread_getspecific_addr, clang_void_ptr_type,
+ llvm::ArrayRef<lldb::addr_t>(pthread_key), options));
+
+ DiagnosticManager execution_errors;
+ ExecutionContext exe_ctx(thread_sp);
+ lldb::ExpressionResults results = m_process->RunThreadPlan(
+ exe_ctx, thread_plan_sp, options, execution_errors);
+
+ if (results == lldb::eExpressionCompleted) {
+ lldb::ValueObjectSP result_valobj_sp =
+ thread_plan_sp->GetReturnValueObject();
+ if (result_valobj_sp) {
+ const lldb::addr_t pthread_key_data =
+ result_valobj_sp->GetValueAsUnsigned(0);
+ if (pthread_key_data) {
+ m_tid_to_tls_map[tid].insert(
+ std::make_pair(pthread_key, pthread_key_data));
+ return pthread_key_data + tls_offset;
}
+ }
}
+ }
}
+ }
}
- return LLDB_INVALID_ADDRESS;
+ }
+ return LLDB_INVALID_ADDRESS;
}
-bool
-DynamicLoaderDarwin::UseDYLDSPI (Process *process)
-{
- Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
- uint32_t major, minor, update;
+bool DynamicLoaderDarwin::UseDYLDSPI(Process *process) {
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+ uint32_t major, minor, update;
- bool use_new_spi_interface = false;
+ bool use_new_spi_interface = false;
- if (process->GetHostOSVersion (major, minor, update))
- {
- const llvm::Triple::OSType os_type = process->GetTarget().GetArchitecture().GetTriple().getOS();
+ if (process->GetHostOSVersion(major, minor, update)) {
+ const llvm::Triple::OSType os_type =
+ process->GetTarget().GetArchitecture().GetTriple().getOS();
- // macOS 10.12 and newer
- if (os_type == llvm::Triple::MacOSX
- && (major >= 10 || (major == 10 && minor >= 12)))
- {
- use_new_spi_interface = true;
- }
-
- // iOS 10 and newer
- if (os_type == llvm::Triple::IOS && major >= 10)
- {
- use_new_spi_interface = true;
- }
-
- // tvOS 10 and newer
- if (os_type == llvm::Triple::TvOS && major >= 10)
- {
- use_new_spi_interface = true;
- }
+ // macOS 10.12 and newer
+ if (os_type == llvm::Triple::MacOSX &&
+ (major >= 10 || (major == 10 && minor >= 12))) {
+ use_new_spi_interface = true;
+ }
- // watchOS 3 and newer
- if (os_type == llvm::Triple::WatchOS && major >= 3)
- {
- use_new_spi_interface = true;
- }
+ // iOS 10 and newer
+ if (os_type == llvm::Triple::IOS && major >= 10) {
+ use_new_spi_interface = true;
}
+ // tvOS 10 and newer
+ if (os_type == llvm::Triple::TvOS && major >= 10) {
+ use_new_spi_interface = true;
+ }
- // FIXME: Temporarily force the use of the old DynamicLoader plugin until all
- // the different use cases have been tested & the updated SPIs are available
- // everywhere.
- use_new_spi_interface = false;
+ // watchOS 3 and newer
+ if (os_type == llvm::Triple::WatchOS && major >= 3) {
+ use_new_spi_interface = true;
+ }
+ }
- if (log)
- {
- if (use_new_spi_interface)
- log->Printf ("DynamicLoaderDarwin::UseDYLDSPI: Use new DynamicLoader plugin");
- else
- log->Printf ("DynamicLoaderDarwin::UseDYLDSPI: Use old DynamicLoader plugin");
+ // FIXME: Temporarily force the use of the old DynamicLoader plugin until all
+ // the different use cases have been tested & the updated SPIs are available
+ // everywhere.
+ use_new_spi_interface = false;
- }
- return use_new_spi_interface;
+ if (log) {
+ if (use_new_spi_interface)
+ log->Printf(
+ "DynamicLoaderDarwin::UseDYLDSPI: Use new DynamicLoader plugin");
+ else
+ log->Printf(
+ "DynamicLoaderDarwin::UseDYLDSPI: Use old DynamicLoader plugin");
+ }
+ return use_new_spi_interface;
}
diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.h b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.h
index 18195044be8..2daa58de0cf 100644
--- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.h
+++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.h
@@ -18,10 +18,10 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/Target/DynamicLoader.h"
-#include "lldb/Host/FileSpec.h"
#include "lldb/Core/StructuredData.h"
#include "lldb/Core/UUID.h"
+#include "lldb/Host/FileSpec.h"
+#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/Process.h"
#include "lldb/Utility/SafeMachO.h"
@@ -29,277 +29,215 @@
namespace lldb_private {
-class DynamicLoaderDarwin : public lldb_private::DynamicLoader
-{
+class DynamicLoaderDarwin : public lldb_private::DynamicLoader {
public:
- DynamicLoaderDarwin(lldb_private::Process *process);
+ DynamicLoaderDarwin(lldb_private::Process *process);
+
+ virtual ~DynamicLoaderDarwin() override;
- virtual ~DynamicLoaderDarwin() override;
+ //------------------------------------------------------------------
+ /// Called after attaching a process.
+ ///
+ /// Allow DynamicLoader plug-ins to execute some code after
+ /// attaching to a process.
+ //------------------------------------------------------------------
+ void DidAttach() override;
- //------------------------------------------------------------------
- /// Called after attaching a process.
- ///
- /// Allow DynamicLoader plug-ins to execute some code after
- /// attaching to a process.
- //------------------------------------------------------------------
- void
- DidAttach() override;
+ void DidLaunch() override;
- void
- DidLaunch() override;
+ lldb::ThreadPlanSP GetStepThroughTrampolinePlan(lldb_private::Thread &thread,
+ bool stop_others) override;
- lldb::ThreadPlanSP
- GetStepThroughTrampolinePlan(lldb_private::Thread &thread,
- bool stop_others) override;
+ size_t FindEquivalentSymbols(
+ lldb_private::Symbol *original_symbol,
+ lldb_private::ModuleList &module_list,
+ lldb_private::SymbolContextList &equivalent_symbols) override;
- size_t
- FindEquivalentSymbols(lldb_private::Symbol *original_symbol,
- lldb_private::ModuleList &module_list,
- lldb_private::SymbolContextList &equivalent_symbols) override;
-
- lldb::addr_t
- GetThreadLocalData(const lldb::ModuleSP module, const lldb::ThreadSP thread, lldb::addr_t tls_file_addr) override;
+ lldb::addr_t GetThreadLocalData(const lldb::ModuleSP module,
+ const lldb::ThreadSP thread,
+ lldb::addr_t tls_file_addr) override;
- bool
- AlwaysRelyOnEHUnwindInfo(lldb_private::SymbolContext &sym_ctx) override;
+ bool AlwaysRelyOnEHUnwindInfo(lldb_private::SymbolContext &sym_ctx) override;
- virtual void
- DoInitialImageFetch () = 0;
+ virtual void DoInitialImageFetch() = 0;
- virtual bool
- NeedToDoInitialImageFetch () = 0;
+ virtual bool NeedToDoInitialImageFetch() = 0;
protected:
- void
- PrivateInitialize (lldb_private::Process *process);
-
- void
- PrivateProcessStateChanged (lldb_private::Process *process,
- lldb::StateType state);
-
- void
- Clear (bool clear_process);
-
- // Clear method for classes derived from this one
- virtual void
- DoClear () = 0;
-
- void
- SetDYLDModule (lldb::ModuleSP &dyld_module_sp);
-
- lldb::ModuleSP
- GetDYLDModule ();
-
- class Segment
- {
- public:
- Segment() :
- name(),
- vmaddr(LLDB_INVALID_ADDRESS),
- vmsize(0),
- fileoff(0),
- filesize(0),
- maxprot(0),
- initprot(0),
- nsects(0),
- flags(0)
- {
- }
-
- lldb_private::ConstString name;
- lldb::addr_t vmaddr;
- lldb::addr_t vmsize;
- lldb::addr_t fileoff;
- lldb::addr_t filesize;
- uint32_t maxprot;
- uint32_t initprot;
- uint32_t nsects;
- uint32_t flags;
-
- bool
- operator==(const Segment& rhs) const
- {
- return name == rhs.name && vmaddr == rhs.vmaddr && vmsize == rhs.vmsize;
- }
-
- void
- PutToLog (lldb_private::Log *log,
- lldb::addr_t slide) const;
-
- };
-
- struct ImageInfo
- {
- lldb::addr_t address; // Address of mach header for this dylib
- lldb::addr_t slide; // The amount to slide all segments by if there is a global slide.
- lldb::addr_t mod_date; // Modification date for this dylib
- lldb_private::FileSpec file_spec; // Resolved path for this dylib
- lldb_private::UUID uuid; // UUID for this dylib if it has one, else all zeros
- llvm::MachO::mach_header header; // The mach header for this image
- std::vector<Segment> segments; // All segment vmaddr and vmsize pairs for this executable (from memory of inferior)
- uint32_t load_stop_id; // The process stop ID that the sections for this image were loaded
- llvm::Triple::OSType os_type; // LC_VERSION_MIN_... load command os type
- std::string min_version_os_sdk; // LC_VERSION_MIN_... sdk value
-
- ImageInfo() :
- address(LLDB_INVALID_ADDRESS),
- slide(0),
- mod_date(0),
- file_spec(),
- uuid(),
- header(),
- segments(),
- load_stop_id(0),
- os_type (llvm::Triple::OSType::UnknownOS),
- min_version_os_sdk()
- {
- }
-
- void
- Clear(bool load_cmd_data_only)
- {
- if (!load_cmd_data_only)
- {
- address = LLDB_INVALID_ADDRESS;
- slide = 0;
- mod_date = 0;
- file_spec.Clear();
- ::memset (&header, 0, sizeof(header));
- }
- uuid.Clear();
- segments.clear();
- load_stop_id = 0;
- os_type = llvm::Triple::OSType::UnknownOS;
- min_version_os_sdk.clear();
- }
-
- bool
- operator == (const ImageInfo& rhs) const
- {
- return address == rhs.address
- && slide == rhs.slide
- && mod_date == rhs.mod_date
- && file_spec == rhs.file_spec
- && uuid == rhs.uuid
- && memcmp(&header, &rhs.header, sizeof(header)) == 0
- && segments == rhs.segments
- && os_type == rhs.os_type;
- }
-
- bool
- UUIDValid() const
- {
- return uuid.IsValid();
- }
-
- uint32_t
- GetAddressByteSize ()
- {
- if (header.cputype)
- {
- if (header.cputype & llvm::MachO::CPU_ARCH_ABI64)
- return 8;
- else
- return 4;
- }
- return 0;
- }
-
- lldb_private::ArchSpec
- GetArchitecture () const
- {
- return lldb_private::ArchSpec (lldb_private::eArchTypeMachO, header.cputype, header.cpusubtype);
- }
-
- const Segment *
- FindSegment (const lldb_private::ConstString &name) const;
-
- void
- PutToLog (lldb_private::Log *log) const;
-
- typedef std::vector<ImageInfo> collection;
- typedef collection::iterator iterator;
- typedef collection::const_iterator const_iterator;
- };
-
- bool
- UpdateImageLoadAddress(lldb_private::Module *module, ImageInfo& info);
-
- bool
- UnloadModuleSections (lldb_private::Module *module, ImageInfo& info);
-
- lldb::ModuleSP
- FindTargetModuleForImageInfo (ImageInfo &image_info,
- bool can_create,
- bool *did_create_ptr);
-
- void
- UnloadImages (const std::vector<lldb::addr_t> &solib_addresses);
-
- void
- UnloadAllImages ();
-
- virtual bool
- SetNotificationBreakpoint () = 0;
-
- virtual void
- ClearNotificationBreakpoint () = 0;
-
- virtual bool
- DidSetNotificationBreakpoint () = 0;
-
- typedef std::map<uint64_t, lldb::addr_t> PthreadKeyToTLSMap;
- typedef std::map<lldb::user_id_t, PthreadKeyToTLSMap> ThreadIDToTLSMap;
-
- std::recursive_mutex &
- GetMutex () const
- {
- return m_mutex;
+ void PrivateInitialize(lldb_private::Process *process);
+
+ void PrivateProcessStateChanged(lldb_private::Process *process,
+ lldb::StateType state);
+
+ void Clear(bool clear_process);
+
+ // Clear method for classes derived from this one
+ virtual void DoClear() = 0;
+
+ void SetDYLDModule(lldb::ModuleSP &dyld_module_sp);
+
+ lldb::ModuleSP GetDYLDModule();
+
+ class Segment {
+ public:
+ Segment()
+ : name(), vmaddr(LLDB_INVALID_ADDRESS), vmsize(0), fileoff(0),
+ filesize(0), maxprot(0), initprot(0), nsects(0), flags(0) {}
+
+ lldb_private::ConstString name;
+ lldb::addr_t vmaddr;
+ lldb::addr_t vmsize;
+ lldb::addr_t fileoff;
+ lldb::addr_t filesize;
+ uint32_t maxprot;
+ uint32_t initprot;
+ uint32_t nsects;
+ uint32_t flags;
+
+ bool operator==(const Segment &rhs) const {
+ return name == rhs.name && vmaddr == rhs.vmaddr && vmsize == rhs.vmsize;
}
- lldb::ModuleSP
- GetPThreadLibraryModule();
+ void PutToLog(lldb_private::Log *log, lldb::addr_t slide) const;
+ };
+
+ struct ImageInfo {
+ lldb::addr_t address; // Address of mach header for this dylib
+ lldb::addr_t slide; // The amount to slide all segments by if there is a
+ // global slide.
+ lldb::addr_t mod_date; // Modification date for this dylib
+ lldb_private::FileSpec file_spec; // Resolved path for this dylib
+ lldb_private::UUID
+ uuid; // UUID for this dylib if it has one, else all zeros
+ llvm::MachO::mach_header header; // The mach header for this image
+ std::vector<Segment> segments; // All segment vmaddr and vmsize pairs for
+ // this executable (from memory of inferior)
+ uint32_t load_stop_id; // The process stop ID that the sections for this
+ // image were loaded
+ llvm::Triple::OSType os_type; // LC_VERSION_MIN_... load command os type
+ std::string min_version_os_sdk; // LC_VERSION_MIN_... sdk value
+
+ ImageInfo()
+ : address(LLDB_INVALID_ADDRESS), slide(0), mod_date(0), file_spec(),
+ uuid(), header(), segments(), load_stop_id(0),
+ os_type(llvm::Triple::OSType::UnknownOS), min_version_os_sdk() {}
+
+ void Clear(bool load_cmd_data_only) {
+ if (!load_cmd_data_only) {
+ address = LLDB_INVALID_ADDRESS;
+ slide = 0;
+ mod_date = 0;
+ file_spec.Clear();
+ ::memset(&header, 0, sizeof(header));
+ }
+ uuid.Clear();
+ segments.clear();
+ load_stop_id = 0;
+ os_type = llvm::Triple::OSType::UnknownOS;
+ min_version_os_sdk.clear();
+ }
+
+ bool operator==(const ImageInfo &rhs) const {
+ return address == rhs.address && slide == rhs.slide &&
+ mod_date == rhs.mod_date && file_spec == rhs.file_spec &&
+ uuid == rhs.uuid &&
+ memcmp(&header, &rhs.header, sizeof(header)) == 0 &&
+ segments == rhs.segments && os_type == rhs.os_type;
+ }
+
+ bool UUIDValid() const { return uuid.IsValid(); }
+
+ uint32_t GetAddressByteSize() {
+ if (header.cputype) {
+ if (header.cputype & llvm::MachO::CPU_ARCH_ABI64)
+ return 8;
+ else
+ return 4;
+ }
+ return 0;
+ }
+
+ lldb_private::ArchSpec GetArchitecture() const {
+ return lldb_private::ArchSpec(lldb_private::eArchTypeMachO,
+ header.cputype, header.cpusubtype);
+ }
+
+ const Segment *FindSegment(const lldb_private::ConstString &name) const;
+
+ void PutToLog(lldb_private::Log *log) const;
+
+ typedef std::vector<ImageInfo> collection;
+ typedef collection::iterator iterator;
+ typedef collection::const_iterator const_iterator;
+ };
+
+ bool UpdateImageLoadAddress(lldb_private::Module *module, ImageInfo &info);
+
+ bool UnloadModuleSections(lldb_private::Module *module, ImageInfo &info);
+
+ lldb::ModuleSP FindTargetModuleForImageInfo(ImageInfo &image_info,
+ bool can_create,
+ bool *did_create_ptr);
+
+ void UnloadImages(const std::vector<lldb::addr_t> &solib_addresses);
+
+ void UnloadAllImages();
+
+ virtual bool SetNotificationBreakpoint() = 0;
+
+ virtual void ClearNotificationBreakpoint() = 0;
+
+ virtual bool DidSetNotificationBreakpoint() = 0;
+
+ typedef std::map<uint64_t, lldb::addr_t> PthreadKeyToTLSMap;
+ typedef std::map<lldb::user_id_t, PthreadKeyToTLSMap> ThreadIDToTLSMap;
+
+ std::recursive_mutex &GetMutex() const { return m_mutex; }
+
+ lldb::ModuleSP GetPThreadLibraryModule();
- lldb_private::Address
- GetPthreadSetSpecificAddress();
+ lldb_private::Address GetPthreadSetSpecificAddress();
- bool
- JSONImageInformationIntoImageInfo (lldb_private::StructuredData::ObjectSP image_details, ImageInfo::collection &image_infos);
+ bool JSONImageInformationIntoImageInfo(
+ lldb_private::StructuredData::ObjectSP image_details,
+ ImageInfo::collection &image_infos);
- // If image_infos contains / may contain dyld or executable image, call this method
- // to keep our internal record keeping of the special binaries up-to-date.
- void
- UpdateSpecialBinariesFromNewImageInfos (ImageInfo::collection &image_infos);
+ // If image_infos contains / may contain dyld or executable image, call this
+ // method
+ // to keep our internal record keeping of the special binaries up-to-date.
+ void
+ UpdateSpecialBinariesFromNewImageInfos(ImageInfo::collection &image_infos);
- // if image_info is a dyld binary, call this method
- void
- UpdateDYLDImageInfoFromNewImageInfo (ImageInfo &image_info);
+ // if image_info is a dyld binary, call this method
+ void UpdateDYLDImageInfoFromNewImageInfo(ImageInfo &image_info);
- // If image_infos contains / may contain executable image, call this method
- // to keep our internal record keeping of the special dyld binary up-to-date.
- void
- AddExecutableModuleIfInImageInfos (ImageInfo::collection &image_infos);
+ // If image_infos contains / may contain executable image, call this method
+ // to keep our internal record keeping of the special dyld binary up-to-date.
+ void AddExecutableModuleIfInImageInfos(ImageInfo::collection &image_infos);
- bool
- AddModulesUsingImageInfos (ImageInfo::collection &image_infos);
+ bool AddModulesUsingImageInfos(ImageInfo::collection &image_infos);
- // Whether we should use the new dyld SPI to get shared library information, or read
- // it directly out of the dyld_all_image_infos. Whether we use the (newer) DynamicLoaderMacOS
- // plugin or the (older) DynamicLoaderMacOSX plugin.
- static bool
- UseDYLDSPI (lldb_private::Process *process);
+ // Whether we should use the new dyld SPI to get shared library information,
+ // or read
+ // it directly out of the dyld_all_image_infos. Whether we use the (newer)
+ // DynamicLoaderMacOS
+ // plugin or the (older) DynamicLoaderMacOSX plugin.
+ static bool UseDYLDSPI(lldb_private::Process *process);
- lldb::ModuleWP m_dyld_module_wp; // the dyld whose file type (mac, ios, etc) matches the process
- lldb::ModuleWP m_libpthread_module_wp;
- lldb_private::Address m_pthread_getspecific_addr;
- ThreadIDToTLSMap m_tid_to_tls_map;
- ImageInfo::collection m_dyld_image_infos; // Current shared libraries information
- uint32_t m_dyld_image_infos_stop_id; // The process stop ID that "m_dyld_image_infos" is valid for
- ImageInfo m_dyld;
- mutable std::recursive_mutex m_mutex;
+ lldb::ModuleWP m_dyld_module_wp; // the dyld whose file type (mac, ios, etc)
+ // matches the process
+ lldb::ModuleWP m_libpthread_module_wp;
+ lldb_private::Address m_pthread_getspecific_addr;
+ ThreadIDToTLSMap m_tid_to_tls_map;
+ ImageInfo::collection
+ m_dyld_image_infos; // Current shared libraries information
+ uint32_t m_dyld_image_infos_stop_id; // The process stop ID that
+ // "m_dyld_image_infos" is valid for
+ ImageInfo m_dyld;
+ mutable std::recursive_mutex m_mutex;
private:
- DISALLOW_COPY_AND_ASSIGN (DynamicLoaderDarwin);
+ DISALLOW_COPY_AND_ASSIGN(DynamicLoaderDarwin);
};
} // namespace lldb_private
diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp
index 718134ac4d7..70961c0e8e5 100644
--- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp
+++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp
@@ -15,158 +15,131 @@
#include "lldb/Core/Section.h"
#include "lldb/Core/State.h"
#include "lldb/Symbol/ClangASTContext.h"
-#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Target/ABI.h"
+#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
-#include "lldb/Target/StackFrame.h"
-#include "DynamicLoaderMacOS.h"
#include "DynamicLoaderDarwin.h"
+#include "DynamicLoaderMacOS.h"
using namespace lldb;
using namespace lldb_private;
-
//----------------------------------------------------------------------
// Create an instance of this class. This function is filled into
// the plugin info class that gets handed out by the plugin factory and
// allows the lldb to instantiate an instance of this class.
//----------------------------------------------------------------------
-DynamicLoader *
-DynamicLoaderMacOS::CreateInstance (Process* process, bool force)
-{
- bool create = force;
- if (!create)
- {
- create = true;
- Module* exe_module = process->GetTarget().GetExecutableModulePointer();
- if (exe_module)
- {
- ObjectFile *object_file = exe_module->GetObjectFile();
- if (object_file)
- {
- create = (object_file->GetStrata() == ObjectFile::eStrataUser);
- }
- }
-
- if (create)
- {
- const llvm::Triple &triple_ref = process->GetTarget().GetArchitecture().GetTriple();
- switch (triple_ref.getOS())
- {
- case llvm::Triple::Darwin:
- case llvm::Triple::MacOSX:
- case llvm::Triple::IOS:
- case llvm::Triple::TvOS:
- case llvm::Triple::WatchOS:
- create = triple_ref.getVendor() == llvm::Triple::Apple;
- break;
- default:
- create = false;
- break;
- }
- }
+DynamicLoader *DynamicLoaderMacOS::CreateInstance(Process *process,
+ bool force) {
+ bool create = force;
+ if (!create) {
+ create = true;
+ Module *exe_module = process->GetTarget().GetExecutableModulePointer();
+ if (exe_module) {
+ ObjectFile *object_file = exe_module->GetObjectFile();
+ if (object_file) {
+ create = (object_file->GetStrata() == ObjectFile::eStrataUser);
+ }
}
- if (UseDYLDSPI (process) == false)
- {
+ if (create) {
+ const llvm::Triple &triple_ref =
+ process->GetTarget().GetArchitecture().GetTriple();
+ switch (triple_ref.getOS()) {
+ case llvm::Triple::Darwin:
+ case llvm::Triple::MacOSX:
+ case llvm::Triple::IOS:
+ case llvm::Triple::TvOS:
+ case llvm::Triple::WatchOS:
+ create = triple_ref.getVendor() == llvm::Triple::Apple;
+ break;
+ default:
create = false;
+ break;
+ }
}
-
- if (create)
- return new DynamicLoaderMacOS (process);
- return NULL;
+ }
+
+ if (UseDYLDSPI(process) == false) {
+ create = false;
+ }
+
+ if (create)
+ return new DynamicLoaderMacOS(process);
+ return NULL;
}
//----------------------------------------------------------------------
// Constructor
//----------------------------------------------------------------------
-DynamicLoaderMacOS::DynamicLoaderMacOS (Process* process) :
- DynamicLoaderDarwin(process),
- m_image_infos_stop_id (UINT32_MAX),
- m_break_id(LLDB_INVALID_BREAK_ID),
- m_mutex()
-{
-}
+DynamicLoaderMacOS::DynamicLoaderMacOS(Process *process)
+ : DynamicLoaderDarwin(process), m_image_infos_stop_id(UINT32_MAX),
+ m_break_id(LLDB_INVALID_BREAK_ID), m_mutex() {}
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
-DynamicLoaderMacOS::~DynamicLoaderMacOS()
-{
- if (LLDB_BREAK_ID_IS_VALID(m_break_id))
- m_process->GetTarget().RemoveBreakpointByID (m_break_id);
+DynamicLoaderMacOS::~DynamicLoaderMacOS() {
+ if (LLDB_BREAK_ID_IS_VALID(m_break_id))
+ m_process->GetTarget().RemoveBreakpointByID(m_break_id);
}
-bool
-DynamicLoaderMacOS::ProcessDidExec ()
-{
- std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
- bool did_exec = false;
- if (m_process)
- {
- // If we are stopped after an exec, we will have only one thread...
- if (m_process->GetThreadList().GetSize() == 1)
- {
- // See if we are stopped at '_dyld_start'
- ThreadSP thread_sp (m_process->GetThreadList().GetThreadAtIndex(0));
- if (thread_sp)
- {
- lldb::StackFrameSP frame_sp (thread_sp->GetStackFrameAtIndex(0));
- if (frame_sp)
- {
- const Symbol *symbol = frame_sp->GetSymbolContext(eSymbolContextSymbol).symbol;
- if (symbol)
- {
- if (symbol->GetName() == ConstString("_dyld_start"))
- did_exec = true;
- }
- }
- }
-
+bool DynamicLoaderMacOS::ProcessDidExec() {
+ std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
+ bool did_exec = false;
+ if (m_process) {
+ // If we are stopped after an exec, we will have only one thread...
+ if (m_process->GetThreadList().GetSize() == 1) {
+ // See if we are stopped at '_dyld_start'
+ ThreadSP thread_sp(m_process->GetThreadList().GetThreadAtIndex(0));
+ if (thread_sp) {
+ lldb::StackFrameSP frame_sp(thread_sp->GetStackFrameAtIndex(0));
+ if (frame_sp) {
+ const Symbol *symbol =
+ frame_sp->GetSymbolContext(eSymbolContextSymbol).symbol;
+ if (symbol) {
+ if (symbol->GetName() == ConstString("_dyld_start"))
+ did_exec = true;
+ }
}
+ }
}
+ }
- if (did_exec)
- {
- m_libpthread_module_wp.reset();
- m_pthread_getspecific_addr.Clear();
- }
- return did_exec;
+ if (did_exec) {
+ m_libpthread_module_wp.reset();
+ m_pthread_getspecific_addr.Clear();
+ }
+ return did_exec;
}
//----------------------------------------------------------------------
// Clear out the state of this class.
//----------------------------------------------------------------------
-void
-DynamicLoaderMacOS::DoClear ()
-{
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
+void DynamicLoaderMacOS::DoClear() {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
- if (LLDB_BREAK_ID_IS_VALID(m_break_id))
- m_process->GetTarget().RemoveBreakpointByID (m_break_id);
+ if (LLDB_BREAK_ID_IS_VALID(m_break_id))
+ m_process->GetTarget().RemoveBreakpointByID(m_break_id);
- m_break_id = LLDB_INVALID_BREAK_ID;
+ m_break_id = LLDB_INVALID_BREAK_ID;
}
//----------------------------------------------------------------------
// Check if we have found DYLD yet
//----------------------------------------------------------------------
-bool
-DynamicLoaderMacOS::DidSetNotificationBreakpoint()
-{
- return LLDB_BREAK_ID_IS_VALID (m_break_id);
+bool DynamicLoaderMacOS::DidSetNotificationBreakpoint() {
+ return LLDB_BREAK_ID_IS_VALID(m_break_id);
}
-void
-DynamicLoaderMacOS::ClearNotificationBreakpoint ()
-{
- if (LLDB_BREAK_ID_IS_VALID (m_break_id))
- {
- m_process->GetTarget().RemoveBreakpointByID (m_break_id);
- }
+void DynamicLoaderMacOS::ClearNotificationBreakpoint() {
+ if (LLDB_BREAK_ID_IS_VALID(m_break_id)) {
+ m_process->GetTarget().RemoveBreakpointByID(m_break_id);
+ }
}
//----------------------------------------------------------------------
@@ -175,407 +148,376 @@ DynamicLoaderMacOS::ClearNotificationBreakpoint ()
// to get the DYLD info (available on SnowLeopard only). If that fails,
// then check in the default addresses.
//----------------------------------------------------------------------
-void
-DynamicLoaderMacOS::DoInitialImageFetch()
-{
- Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
-
- StructuredData::ObjectSP all_image_info_json_sp (m_process->GetLoadedDynamicLibrariesInfos ());
- ImageInfo::collection image_infos;
- if (all_image_info_json_sp.get()
- && all_image_info_json_sp->GetAsDictionary()
- && all_image_info_json_sp->GetAsDictionary()->HasKey("images")
- && all_image_info_json_sp->GetAsDictionary()->GetValueForKey("images")->GetAsArray())
- {
- if (JSONImageInformationIntoImageInfo (all_image_info_json_sp, image_infos))
- {
- if (log)
- log->Printf ("Initial module fetch: Adding %" PRId64 " modules.\n", (uint64_t) image_infos.size());
-
- UpdateSpecialBinariesFromNewImageInfos (image_infos);
- AddModulesUsingImageInfos (image_infos);
- }
+void DynamicLoaderMacOS::DoInitialImageFetch() {
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+
+ StructuredData::ObjectSP all_image_info_json_sp(
+ m_process->GetLoadedDynamicLibrariesInfos());
+ ImageInfo::collection image_infos;
+ if (all_image_info_json_sp.get() &&
+ all_image_info_json_sp->GetAsDictionary() &&
+ all_image_info_json_sp->GetAsDictionary()->HasKey("images") &&
+ all_image_info_json_sp->GetAsDictionary()
+ ->GetValueForKey("images")
+ ->GetAsArray()) {
+ if (JSONImageInformationIntoImageInfo(all_image_info_json_sp,
+ image_infos)) {
+ if (log)
+ log->Printf("Initial module fetch: Adding %" PRId64 " modules.\n",
+ (uint64_t)image_infos.size());
+
+ UpdateSpecialBinariesFromNewImageInfos(image_infos);
+ AddModulesUsingImageInfos(image_infos);
}
-
- m_dyld_image_infos_stop_id = m_process->GetStopID();
-}
+ }
-bool
-DynamicLoaderMacOS::NeedToDoInitialImageFetch ()
-{
- return true;
+ m_dyld_image_infos_stop_id = m_process->GetStopID();
}
+bool DynamicLoaderMacOS::NeedToDoInitialImageFetch() { return true; }
+
//----------------------------------------------------------------------
// Static callback function that gets called when our DYLD notification
// breakpoint gets hit. We update all of our image infos and then
// let our super class DynamicLoader class decide if we should stop
// or not (based on global preference).
//----------------------------------------------------------------------
-bool
-DynamicLoaderMacOS::NotifyBreakpointHit (void *baton,
- StoppointCallbackContext *context,
- lldb::user_id_t break_id,
- lldb::user_id_t break_loc_id)
-{
- // Let the event know that the images have changed
- // DYLD passes three arguments to the notification breakpoint.
- // Arg1: enum dyld_notify_mode mode - 0 = adding, 1 = removing, 2 = remove all
- // Arg2: unsigned long icount - Number of shared libraries added/removed
- // Arg3: uint64_t mach_headers[] - Array of load addresses of binaries added/removed
-
- DynamicLoaderMacOS* dyld_instance = (DynamicLoaderMacOS*) baton;
-
- ExecutionContext exe_ctx (context->exe_ctx_ref);
- Process *process = exe_ctx.GetProcessPtr();
-
- // This is a sanity check just in case this dyld_instance is an old dyld plugin's breakpoint still lying around.
- if (process != dyld_instance->m_process)
- return false;
-
- if (dyld_instance->m_image_infos_stop_id != UINT32_MAX
- && process->GetStopID() < dyld_instance->m_image_infos_stop_id)
- {
- return false;
- }
+bool DynamicLoaderMacOS::NotifyBreakpointHit(void *baton,
+ StoppointCallbackContext *context,
+ lldb::user_id_t break_id,
+ lldb::user_id_t break_loc_id) {
+ // Let the event know that the images have changed
+ // DYLD passes three arguments to the notification breakpoint.
+ // Arg1: enum dyld_notify_mode mode - 0 = adding, 1 = removing, 2 = remove all
+ // Arg2: unsigned long icount - Number of shared libraries
+ // added/removed
+ // Arg3: uint64_t mach_headers[] - Array of load addresses of binaries
+ // added/removed
+
+ DynamicLoaderMacOS *dyld_instance = (DynamicLoaderMacOS *)baton;
+
+ ExecutionContext exe_ctx(context->exe_ctx_ref);
+ Process *process = exe_ctx.GetProcessPtr();
+
+ // This is a sanity check just in case this dyld_instance is an old dyld
+ // plugin's breakpoint still lying around.
+ if (process != dyld_instance->m_process)
+ return false;
- const lldb::ABISP &abi = process->GetABI();
- if (abi)
- {
- // Build up the value array to store the three arguments given above, then get the values from the ABI:
-
- ClangASTContext *clang_ast_context = process->GetTarget().GetScratchClangASTContext();
- ValueList argument_values;
-
- Value mode_value; // enum dyld_notify_mode { dyld_notify_adding=0, dyld_notify_removing=1, dyld_notify_remove_all=2 };
- Value count_value; // unsigned long count
- Value headers_value; // uint64_t machHeaders[] (aka void*)
-
- CompilerType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
- CompilerType clang_uint32_type = clang_ast_context->GetBuiltinTypeForEncodingAndBitSize(lldb::eEncodingUint, 32);
- CompilerType clang_uint64_type = clang_ast_context->GetBuiltinTypeForEncodingAndBitSize(lldb::eEncodingUint, 32);
-
- mode_value.SetValueType (Value::eValueTypeScalar);
- mode_value.SetCompilerType (clang_uint32_type);
-
- if (process->GetTarget().GetArchitecture().GetAddressByteSize() == 4)
- {
- count_value.SetValueType (Value::eValueTypeScalar);
- count_value.SetCompilerType (clang_uint32_type);
- }
- else
- {
- count_value.SetValueType (Value::eValueTypeScalar);
- count_value.SetCompilerType (clang_uint64_type);
- }
+ if (dyld_instance->m_image_infos_stop_id != UINT32_MAX &&
+ process->GetStopID() < dyld_instance->m_image_infos_stop_id) {
+ return false;
+ }
+
+ const lldb::ABISP &abi = process->GetABI();
+ if (abi) {
+ // Build up the value array to store the three arguments given above, then
+ // get the values from the ABI:
+
+ ClangASTContext *clang_ast_context =
+ process->GetTarget().GetScratchClangASTContext();
+ ValueList argument_values;
+
+ Value mode_value; // enum dyld_notify_mode { dyld_notify_adding=0,
+ // dyld_notify_removing=1, dyld_notify_remove_all=2 };
+ Value count_value; // unsigned long count
+ Value headers_value; // uint64_t machHeaders[] (aka void*)
+
+ CompilerType clang_void_ptr_type =
+ clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
+ CompilerType clang_uint32_type =
+ clang_ast_context->GetBuiltinTypeForEncodingAndBitSize(
+ lldb::eEncodingUint, 32);
+ CompilerType clang_uint64_type =
+ clang_ast_context->GetBuiltinTypeForEncodingAndBitSize(
+ lldb::eEncodingUint, 32);
+
+ mode_value.SetValueType(Value::eValueTypeScalar);
+ mode_value.SetCompilerType(clang_uint32_type);
+
+ if (process->GetTarget().GetArchitecture().GetAddressByteSize() == 4) {
+ count_value.SetValueType(Value::eValueTypeScalar);
+ count_value.SetCompilerType(clang_uint32_type);
+ } else {
+ count_value.SetValueType(Value::eValueTypeScalar);
+ count_value.SetCompilerType(clang_uint64_type);
+ }
- headers_value.SetValueType (Value::eValueTypeScalar);
- headers_value.SetCompilerType (clang_void_ptr_type);
-
- argument_values.PushValue (mode_value);
- argument_values.PushValue (count_value);
- argument_values.PushValue (headers_value);
-
- if (abi->GetArgumentValues (exe_ctx.GetThreadRef(), argument_values))
- {
- uint32_t dyld_mode = argument_values.GetValueAtIndex(0)->GetScalar().UInt (-1);
- if (dyld_mode != static_cast<uint32_t>(-1))
- {
- // Okay the mode was right, now get the number of elements, and the array of new elements...
- uint32_t image_infos_count = argument_values.GetValueAtIndex(1)->GetScalar().UInt (-1);
- if (image_infos_count != static_cast<uint32_t>(-1))
- {
- addr_t header_array = argument_values.GetValueAtIndex(2)->GetScalar().ULongLong(-1);
- if (header_array != static_cast<uint64_t>(-1))
- {
- std::vector<addr_t> image_load_addresses;
- for (uint64_t i = 0; i < image_infos_count ; i++)
- {
- Error error;
- addr_t addr = process->ReadUnsignedIntegerFromMemory (header_array + (8 * i), 8, LLDB_INVALID_ADDRESS, error);
- if (addr != LLDB_INVALID_ADDRESS)
- {
- image_load_addresses.push_back (addr);
- }
- }
- if (dyld_mode == 0)
- {
- // dyld_notify_adding
- dyld_instance->AddBinaries (image_load_addresses);
- }
- else if (dyld_mode == 1)
- {
- // dyld_notify_removing
- dyld_instance->UnloadImages (image_load_addresses);
- }
- else if (dyld_mode == 2)
- {
- // dyld_notify_remove_all
- dyld_instance->UnloadAllImages ();
- }
- }
- }
+ headers_value.SetValueType(Value::eValueTypeScalar);
+ headers_value.SetCompilerType(clang_void_ptr_type);
+
+ argument_values.PushValue(mode_value);
+ argument_values.PushValue(count_value);
+ argument_values.PushValue(headers_value);
+
+ if (abi->GetArgumentValues(exe_ctx.GetThreadRef(), argument_values)) {
+ uint32_t dyld_mode =
+ argument_values.GetValueAtIndex(0)->GetScalar().UInt(-1);
+ if (dyld_mode != static_cast<uint32_t>(-1)) {
+ // Okay the mode was right, now get the number of elements, and the
+ // array of new elements...
+ uint32_t image_infos_count =
+ argument_values.GetValueAtIndex(1)->GetScalar().UInt(-1);
+ if (image_infos_count != static_cast<uint32_t>(-1)) {
+ addr_t header_array =
+ argument_values.GetValueAtIndex(2)->GetScalar().ULongLong(-1);
+ if (header_array != static_cast<uint64_t>(-1)) {
+ std::vector<addr_t> image_load_addresses;
+ for (uint64_t i = 0; i < image_infos_count; i++) {
+ Error error;
+ addr_t addr = process->ReadUnsignedIntegerFromMemory(
+ header_array + (8 * i), 8, LLDB_INVALID_ADDRESS, error);
+ if (addr != LLDB_INVALID_ADDRESS) {
+ image_load_addresses.push_back(addr);
+ }
+ }
+ if (dyld_mode == 0) {
+ // dyld_notify_adding
+ dyld_instance->AddBinaries(image_load_addresses);
+ } else if (dyld_mode == 1) {
+ // dyld_notify_removing
+ dyld_instance->UnloadImages(image_load_addresses);
+ } else if (dyld_mode == 2) {
+ // dyld_notify_remove_all
+ dyld_instance->UnloadAllImages();
}
+ }
}
+ }
}
- else
- {
- process->GetTarget().GetDebugger().GetAsyncErrorStream()->Printf("No ABI plugin located for triple %s -- shared libraries will not be registered!\n", process->GetTarget().GetArchitecture().GetTriple().getTriple().c_str());
- }
-
- // Return true to stop the target, false to just let the target run
- return dyld_instance->GetStopWhenImagesChange();
+ } else {
+ process->GetTarget().GetDebugger().GetAsyncErrorStream()->Printf(
+ "No ABI plugin located for triple %s -- shared libraries will not be "
+ "registered!\n",
+ process->GetTarget().GetArchitecture().GetTriple().getTriple().c_str());
+ }
+
+ // Return true to stop the target, false to just let the target run
+ return dyld_instance->GetStopWhenImagesChange();
}
-void
-DynamicLoaderMacOS::AddBinaries (const std::vector<lldb::addr_t> &load_addresses)
-{
- Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
- ImageInfo::collection image_infos;
-
- if (log)
- log->Printf ("Adding %" PRId64 " modules.", (uint64_t) load_addresses.size());
- StructuredData::ObjectSP binaries_info_sp = m_process->GetLoadedDynamicLibrariesInfos (load_addresses);
- if (binaries_info_sp.get()
- && binaries_info_sp->GetAsDictionary()
- && binaries_info_sp->GetAsDictionary()->HasKey("images")
- && binaries_info_sp->GetAsDictionary()->GetValueForKey("images")->GetAsArray()
- && binaries_info_sp->GetAsDictionary()->GetValueForKey("images")->GetAsArray()->GetSize() == load_addresses.size())
- {
- if (JSONImageInformationIntoImageInfo (binaries_info_sp, image_infos))
- {
- UpdateSpecialBinariesFromNewImageInfos (image_infos);
- AddModulesUsingImageInfos (image_infos);
- }
- m_dyld_image_infos_stop_id = m_process->GetStopID();
+void DynamicLoaderMacOS::AddBinaries(
+ const std::vector<lldb::addr_t> &load_addresses) {
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+ ImageInfo::collection image_infos;
+
+ if (log)
+ log->Printf("Adding %" PRId64 " modules.", (uint64_t)load_addresses.size());
+ StructuredData::ObjectSP binaries_info_sp =
+ m_process->GetLoadedDynamicLibrariesInfos(load_addresses);
+ if (binaries_info_sp.get() && binaries_info_sp->GetAsDictionary() &&
+ binaries_info_sp->GetAsDictionary()->HasKey("images") &&
+ binaries_info_sp->GetAsDictionary()
+ ->GetValueForKey("images")
+ ->GetAsArray() &&
+ binaries_info_sp->GetAsDictionary()
+ ->GetValueForKey("images")
+ ->GetAsArray()
+ ->GetSize() == load_addresses.size()) {
+ if (JSONImageInformationIntoImageInfo(binaries_info_sp, image_infos)) {
+ UpdateSpecialBinariesFromNewImageInfos(image_infos);
+ AddModulesUsingImageInfos(image_infos);
}
+ m_dyld_image_infos_stop_id = m_process->GetStopID();
+ }
}
-
// Dump the _dyld_all_image_infos members and all current image infos
// that we have parsed to the file handle provided.
//----------------------------------------------------------------------
-void
-DynamicLoaderMacOS::PutToLog(Log *log) const
-{
- if (log == NULL)
- return;
+void DynamicLoaderMacOS::PutToLog(Log *log) const {
+ if (log == NULL)
+ return;
}
-bool
-DynamicLoaderMacOS::SetNotificationBreakpoint ()
-{
- if (m_break_id == LLDB_INVALID_BREAK_ID)
- {
- ConstString g_symbol_name ("_dyld_debugger_notification");
- const Symbol *symbol = nullptr;
- ModuleSP dyld_sp (GetDYLDModule());
- if (dyld_sp)
- {
- symbol = dyld_sp->FindFirstSymbolWithNameAndType (g_symbol_name, eSymbolTypeCode);
- }
- if (symbol && (symbol->ValueIsAddress() || symbol->GetAddressRef().IsValid()))
- {
- addr_t symbol_address = symbol->GetAddressRef().GetOpcodeLoadAddress(&m_process->GetTarget());
- if (symbol_address != LLDB_INVALID_ADDRESS)
- {
- bool internal = true;
- bool hardware = false;
- Breakpoint *breakpoint = m_process->GetTarget().CreateBreakpoint(symbol_address, internal, hardware).get();
- breakpoint->SetCallback (DynamicLoaderMacOS::NotifyBreakpointHit, this, true);
- breakpoint->SetBreakpointKind ("shared-library-event");
- m_break_id = breakpoint->GetID();
- }
- }
+bool DynamicLoaderMacOS::SetNotificationBreakpoint() {
+ if (m_break_id == LLDB_INVALID_BREAK_ID) {
+ ConstString g_symbol_name("_dyld_debugger_notification");
+ const Symbol *symbol = nullptr;
+ ModuleSP dyld_sp(GetDYLDModule());
+ if (dyld_sp) {
+ symbol = dyld_sp->FindFirstSymbolWithNameAndType(g_symbol_name,
+ eSymbolTypeCode);
}
- return m_break_id != LLDB_INVALID_BREAK_ID;
+ if (symbol &&
+ (symbol->ValueIsAddress() || symbol->GetAddressRef().IsValid())) {
+ addr_t symbol_address =
+ symbol->GetAddressRef().GetOpcodeLoadAddress(&m_process->GetTarget());
+ if (symbol_address != LLDB_INVALID_ADDRESS) {
+ bool internal = true;
+ bool hardware = false;
+ Breakpoint *breakpoint =
+ m_process->GetTarget()
+ .CreateBreakpoint(symbol_address, internal, hardware)
+ .get();
+ breakpoint->SetCallback(DynamicLoaderMacOS::NotifyBreakpointHit, this,
+ true);
+ breakpoint->SetBreakpointKind("shared-library-event");
+ m_break_id = breakpoint->GetID();
+ }
+ }
+ }
+ return m_break_id != LLDB_INVALID_BREAK_ID;
}
-
addr_t
-DynamicLoaderMacOS::GetDyldLockVariableAddressFromModule (Module *module)
-{
- SymbolContext sc;
- SymbolVendor *sym_vendor = module->GetSymbolVendor ();
- Target &target = m_process->GetTarget ();
- if (sym_vendor)
- {
- Symtab *symtab = sym_vendor->GetSymtab();
- if (symtab)
- {
- std::vector<uint32_t> match_indexes;
- ConstString g_symbol_name ("_dyld_global_lock_held");
- uint32_t num_matches = 0;
- num_matches = symtab->AppendSymbolIndexesWithName (g_symbol_name, match_indexes);
- if (num_matches == 1)
- {
- Symbol *symbol = symtab->SymbolAtIndex (match_indexes[0]);
- if (symbol && (symbol->ValueIsAddress() || symbol->GetAddressRef().IsValid()))
- {
- return symbol->GetAddressRef().GetOpcodeLoadAddress(&target);
- }
- }
+DynamicLoaderMacOS::GetDyldLockVariableAddressFromModule(Module *module) {
+ SymbolContext sc;
+ SymbolVendor *sym_vendor = module->GetSymbolVendor();
+ Target &target = m_process->GetTarget();
+ if (sym_vendor) {
+ Symtab *symtab = sym_vendor->GetSymtab();
+ if (symtab) {
+ std::vector<uint32_t> match_indexes;
+ ConstString g_symbol_name("_dyld_global_lock_held");
+ uint32_t num_matches = 0;
+ num_matches =
+ symtab->AppendSymbolIndexesWithName(g_symbol_name, match_indexes);
+ if (num_matches == 1) {
+ Symbol *symbol = symtab->SymbolAtIndex(match_indexes[0]);
+ if (symbol &&
+ (symbol->ValueIsAddress() || symbol->GetAddressRef().IsValid())) {
+ return symbol->GetAddressRef().GetOpcodeLoadAddress(&target);
}
+ }
}
- return LLDB_INVALID_ADDRESS;
+ }
+ return LLDB_INVALID_ADDRESS;
}
// Look for this symbol:
//
-// int __attribute__((visibility("hidden"))) _dyld_global_lock_held = 0;
+// int __attribute__((visibility("hidden"))) _dyld_global_lock_held =
+// 0;
//
// in libdyld.dylib.
-Error
-DynamicLoaderMacOS::CanLoadImage ()
-{
- Error error;
- addr_t symbol_address = LLDB_INVALID_ADDRESS;
- Target &target = m_process->GetTarget ();
- const ModuleList &target_modules = target.GetImages();
- std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
- const size_t num_modules = target_modules.GetSize();
- ConstString g_libdyld_name ("libdyld.dylib");
-
- // Find any modules named "libdyld.dylib" and look for the symbol there first
- for (size_t i = 0; i < num_modules; i++)
- {
- Module *module_pointer = target_modules.GetModulePointerAtIndexUnlocked (i);
- if (module_pointer)
- {
- if (module_pointer->GetFileSpec().GetFilename() == g_libdyld_name)
- {
- symbol_address = GetDyldLockVariableAddressFromModule (module_pointer);
- if (symbol_address != LLDB_INVALID_ADDRESS)
- break;
- }
- }
+Error DynamicLoaderMacOS::CanLoadImage() {
+ Error error;
+ addr_t symbol_address = LLDB_INVALID_ADDRESS;
+ Target &target = m_process->GetTarget();
+ const ModuleList &target_modules = target.GetImages();
+ std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
+ const size_t num_modules = target_modules.GetSize();
+ ConstString g_libdyld_name("libdyld.dylib");
+
+ // Find any modules named "libdyld.dylib" and look for the symbol there first
+ for (size_t i = 0; i < num_modules; i++) {
+ Module *module_pointer = target_modules.GetModulePointerAtIndexUnlocked(i);
+ if (module_pointer) {
+ if (module_pointer->GetFileSpec().GetFilename() == g_libdyld_name) {
+ symbol_address = GetDyldLockVariableAddressFromModule(module_pointer);
+ if (symbol_address != LLDB_INVALID_ADDRESS)
+ break;
+ }
}
-
- // Search through all modules looking for the symbol in them
- if (symbol_address == LLDB_INVALID_ADDRESS)
- {
- for (size_t i = 0; i < num_modules; i++)
- {
- Module *module_pointer = target_modules.GetModulePointerAtIndexUnlocked (i);
- if (module_pointer)
- {
- addr_t symbol_address = GetDyldLockVariableAddressFromModule (module_pointer);
- if (symbol_address != LLDB_INVALID_ADDRESS)
- break;
- }
- }
+ }
+
+ // Search through all modules looking for the symbol in them
+ if (symbol_address == LLDB_INVALID_ADDRESS) {
+ for (size_t i = 0; i < num_modules; i++) {
+ Module *module_pointer =
+ target_modules.GetModulePointerAtIndexUnlocked(i);
+ if (module_pointer) {
+ addr_t symbol_address =
+ GetDyldLockVariableAddressFromModule(module_pointer);
+ if (symbol_address != LLDB_INVALID_ADDRESS)
+ break;
+ }
}
+ }
- // Default assumption is that it is OK to load images.
- // Only say that we cannot load images if we find the symbol in libdyld and it indicates that
- // we cannot.
+ // Default assumption is that it is OK to load images.
+ // Only say that we cannot load images if we find the symbol in libdyld and it
+ // indicates that
+ // we cannot.
- if (symbol_address != LLDB_INVALID_ADDRESS)
- {
- {
- int lock_held = m_process->ReadUnsignedIntegerFromMemory (symbol_address, 4, 0, error);
- if (lock_held != 0)
- {
- error.SetErrorToGenericError();
- }
- }
- }
- else
+ if (symbol_address != LLDB_INVALID_ADDRESS) {
{
- // If we were unable to find _dyld_global_lock_held in any modules, or it is not loaded into
- // memory yet, we may be at process startup (sitting at _dyld_start) - so we should not allow
- // dlopen calls.
+ int lock_held =
+ m_process->ReadUnsignedIntegerFromMemory(symbol_address, 4, 0, error);
+ if (lock_held != 0) {
error.SetErrorToGenericError();
+ }
}
- return error;
+ } else {
+ // If we were unable to find _dyld_global_lock_held in any modules, or it is
+ // not loaded into
+ // memory yet, we may be at process startup (sitting at _dyld_start) - so we
+ // should not allow
+ // dlopen calls.
+ error.SetErrorToGenericError();
+ }
+ return error;
}
-bool
-DynamicLoaderMacOS::GetSharedCacheInformation (lldb::addr_t &base_address,
- UUID &uuid,
- LazyBool &using_shared_cache,
- LazyBool &private_shared_cache)
-{
- base_address = LLDB_INVALID_ADDRESS;
- uuid.Clear();
- using_shared_cache = eLazyBoolCalculate;
- private_shared_cache = eLazyBoolCalculate;
-
- if (m_process)
- {
- StructuredData::ObjectSP info = m_process->GetSharedCacheInfo();
- StructuredData::Dictionary *info_dict = nullptr;
- if (info.get() && info->GetAsDictionary())
- {
- info_dict = info->GetAsDictionary();
- }
+bool DynamicLoaderMacOS::GetSharedCacheInformation(
+ lldb::addr_t &base_address, UUID &uuid, LazyBool &using_shared_cache,
+ LazyBool &private_shared_cache) {
+ base_address = LLDB_INVALID_ADDRESS;
+ uuid.Clear();
+ using_shared_cache = eLazyBoolCalculate;
+ private_shared_cache = eLazyBoolCalculate;
+
+ if (m_process) {
+ StructuredData::ObjectSP info = m_process->GetSharedCacheInfo();
+ StructuredData::Dictionary *info_dict = nullptr;
+ if (info.get() && info->GetAsDictionary()) {
+ info_dict = info->GetAsDictionary();
+ }
- // {"shared_cache_base_address":140735683125248,"shared_cache_uuid":"DDB8D70C-C9A2-3561-B2C8-BE48A4F33F96","no_shared_cache":false,"shared_cache_private_cache":false}
-
- if (info_dict
- && info_dict->HasKey("shared_cache_uuid")
- && info_dict->HasKey("no_shared_cache")
- && info_dict->HasKey("shared_cache_base_address"))
- {
- base_address = info_dict->GetValueForKey("shared_cache_base_address")->GetIntegerValue(LLDB_INVALID_ADDRESS);
- std::string uuid_str = info_dict->GetValueForKey("shared_cache_uuid")->GetStringValue().c_str();
- if (!uuid_str.empty())
- uuid.SetFromCString (uuid_str.c_str());
- if (info_dict->GetValueForKey("no_shared_cache")->GetBooleanValue() == false)
- using_shared_cache = eLazyBoolYes;
- else
- using_shared_cache = eLazyBoolNo;
- if (info_dict->GetValueForKey("shared_cache_private_cache")->GetBooleanValue())
- private_shared_cache = eLazyBoolYes;
- else
- private_shared_cache = eLazyBoolNo;
-
- return true;
- }
+ // {"shared_cache_base_address":140735683125248,"shared_cache_uuid":"DDB8D70C-C9A2-3561-B2C8-BE48A4F33F96","no_shared_cache":false,"shared_cache_private_cache":false}
+
+ if (info_dict && info_dict->HasKey("shared_cache_uuid") &&
+ info_dict->HasKey("no_shared_cache") &&
+ info_dict->HasKey("shared_cache_base_address")) {
+ base_address = info_dict->GetValueForKey("shared_cache_base_address")
+ ->GetIntegerValue(LLDB_INVALID_ADDRESS);
+ std::string uuid_str = info_dict->GetValueForKey("shared_cache_uuid")
+ ->GetStringValue()
+ .c_str();
+ if (!uuid_str.empty())
+ uuid.SetFromCString(uuid_str.c_str());
+ if (info_dict->GetValueForKey("no_shared_cache")->GetBooleanValue() ==
+ false)
+ using_shared_cache = eLazyBoolYes;
+ else
+ using_shared_cache = eLazyBoolNo;
+ if (info_dict->GetValueForKey("shared_cache_private_cache")
+ ->GetBooleanValue())
+ private_shared_cache = eLazyBoolYes;
+ else
+ private_shared_cache = eLazyBoolNo;
+
+ return true;
}
- return false;
+ }
+ return false;
}
-void
-DynamicLoaderMacOS::Initialize()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- GetPluginDescriptionStatic(),
- CreateInstance);
+void DynamicLoaderMacOS::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance);
}
-void
-DynamicLoaderMacOS::Terminate()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
+void DynamicLoaderMacOS::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
}
-
-lldb_private::ConstString
-DynamicLoaderMacOS::GetPluginNameStatic()
-{
- static ConstString g_name("macos-dyld");
- return g_name;
+lldb_private::ConstString DynamicLoaderMacOS::GetPluginNameStatic() {
+ static ConstString g_name("macos-dyld");
+ return g_name;
}
-const char *
-DynamicLoaderMacOS::GetPluginDescriptionStatic()
-{
- return "Dynamic loader plug-in that watches for shared library loads/unloads in MacOSX user processes.";
+const char *DynamicLoaderMacOS::GetPluginDescriptionStatic() {
+ return "Dynamic loader plug-in that watches for shared library loads/unloads "
+ "in MacOSX user processes.";
}
-
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
-lldb_private::ConstString
-DynamicLoaderMacOS::GetPluginName()
-{
- return GetPluginNameStatic();
+lldb_private::ConstString DynamicLoaderMacOS::GetPluginName() {
+ return GetPluginNameStatic();
}
-uint32_t
-DynamicLoaderMacOS::GetPluginVersion()
-{
- return 1;
-}
+uint32_t DynamicLoaderMacOS::GetPluginVersion() { return 1; }
diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.h b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.h
index 63d67308d69..93273b13bb7 100644
--- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.h
+++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.h
@@ -7,7 +7,8 @@
//
//===----------------------------------------------------------------------===//
-// This is the DynamicLoader plugin for Darwin (macOS / iPhoneOS / tvOS / watchOS)
+// This is the DynamicLoader plugin for Darwin (macOS / iPhoneOS / tvOS /
+// watchOS)
// platforms late 2016 and newer, where lldb will call dyld SPI functions to get
// information about shared libraries, information about the shared cache, and
// the _dyld_debugger_notification function we put a breakpoint on give us an
@@ -19,117 +20,98 @@
// C Includes
// C++ Includes
-#include <vector>
#include <mutex>
+#include <vector>
// Other libraries and framework includes
// Project includes
-#include "lldb/Target/DynamicLoader.h"
-#include "lldb/Host/FileSpec.h"
#include "lldb/Core/StructuredData.h"
#include "lldb/Core/UUID.h"
+#include "lldb/Host/FileSpec.h"
+#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/Process.h"
#include "lldb/Utility/SafeMachO.h"
#include "DynamicLoaderDarwin.h"
-class DynamicLoaderMacOS : public lldb_private::DynamicLoaderDarwin
-{
+class DynamicLoaderMacOS : public lldb_private::DynamicLoaderDarwin {
public:
- DynamicLoaderMacOS(lldb_private::Process *process);
+ DynamicLoaderMacOS(lldb_private::Process *process);
- virtual ~DynamicLoaderMacOS() override;
+ virtual ~DynamicLoaderMacOS() override;
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
- static void
- Initialize();
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+ static void Initialize();
- static void
- Terminate();
+ static void Terminate();
- static lldb_private::ConstString
- GetPluginNameStatic();
+ static lldb_private::ConstString GetPluginNameStatic();
- static const char *
- GetPluginDescriptionStatic();
+ static const char *GetPluginDescriptionStatic();
- static lldb_private::DynamicLoader *
- CreateInstance (lldb_private::Process *process, bool force);
+ static lldb_private::DynamicLoader *
+ CreateInstance(lldb_private::Process *process, bool force);
- //------------------------------------------------------------------
- /// Called after attaching a process.
- ///
- /// Allow DynamicLoader plug-ins to execute some code after
- /// attaching to a process.
- //------------------------------------------------------------------
- bool
- ProcessDidExec() override;
+ //------------------------------------------------------------------
+ /// Called after attaching a process.
+ ///
+ /// Allow DynamicLoader plug-ins to execute some code after
+ /// attaching to a process.
+ //------------------------------------------------------------------
+ bool ProcessDidExec() override;
- lldb_private::Error
- CanLoadImage() override;
+ lldb_private::Error CanLoadImage() override;
- bool
- GetSharedCacheInformation (lldb::addr_t &base_address,
- lldb_private::UUID &uuid,
- lldb_private::LazyBool &using_shared_cache,
- lldb_private::LazyBool &private_shared_cache) override;
+ bool GetSharedCacheInformation(
+ lldb::addr_t &base_address, lldb_private::UUID &uuid,
+ lldb_private::LazyBool &using_shared_cache,
+ lldb_private::LazyBool &private_shared_cache) override;
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- lldb_private::ConstString
- GetPluginName() override;
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ lldb_private::ConstString GetPluginName() override;
- uint32_t
- GetPluginVersion() override;
+ uint32_t GetPluginVersion() override;
protected:
- void
- PutToLog(lldb_private::Log *log) const;
+ void PutToLog(lldb_private::Log *log) const;
- void
- DoInitialImageFetch () override;
+ void DoInitialImageFetch() override;
- bool
- NeedToDoInitialImageFetch () override;
+ bool NeedToDoInitialImageFetch() override;
- bool
- DidSetNotificationBreakpoint () override;
+ bool DidSetNotificationBreakpoint() override;
- void
- AddBinaries (const std::vector<lldb::addr_t> &load_addresses);
+ void AddBinaries(const std::vector<lldb::addr_t> &load_addresses);
- void
- DoClear () override;
+ void DoClear() override;
- static bool
- NotifyBreakpointHit (void *baton,
- lldb_private::StoppointCallbackContext *context,
- lldb::user_id_t break_id,
- lldb::user_id_t break_loc_id);
+ static bool
+ NotifyBreakpointHit(void *baton,
+ lldb_private::StoppointCallbackContext *context,
+ lldb::user_id_t break_id, lldb::user_id_t break_loc_id);
- bool
- SetNotificationBreakpoint () override;
+ bool SetNotificationBreakpoint() override;
- void
- ClearNotificationBreakpoint () override;
+ void ClearNotificationBreakpoint() override;
- void
- UpdateImageInfosHeaderAndLoadCommands(ImageInfo::collection &image_infos,
- uint32_t infos_count,
- bool update_executable);
+ void UpdateImageInfosHeaderAndLoadCommands(ImageInfo::collection &image_infos,
+ uint32_t infos_count,
+ bool update_executable);
- lldb::addr_t
- GetDyldLockVariableAddressFromModule (lldb_private::Module *module);
+ lldb::addr_t
+ GetDyldLockVariableAddressFromModule(lldb_private::Module *module);
- uint32_t m_image_infos_stop_id; // The Stop ID the last time we loaded/unloaded images
- lldb::user_id_t m_break_id;
- mutable std::recursive_mutex m_mutex;
+ uint32_t m_image_infos_stop_id; // The Stop ID the last time we
+ // loaded/unloaded images
+ lldb::user_id_t m_break_id;
+ mutable std::recursive_mutex m_mutex;
private:
- DISALLOW_COPY_AND_ASSIGN (DynamicLoaderMacOS);
+ DISALLOW_COPY_AND_ASSIGN(DynamicLoaderMacOS);
};
#endif // liblldb_DynamicLoaderMacOS_h_
diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
index 6e2d625a9b5..bbaa1baec73 100644
--- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
+++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
@@ -20,21 +20,21 @@
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Target/ObjCLanguageRuntime.h"
#include "lldb/Target/ABI.h"
+#include "lldb/Target/ObjCLanguageRuntime.h"
#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadPlanRunToAddress.h"
-#include "lldb/Target/StackFrame.h"
-#include "DynamicLoaderMacOSXDYLD.h"
#include "DynamicLoaderDarwin.h"
+#include "DynamicLoaderMacOSXDYLD.h"
//#define ENABLE_DEBUG_PRINTF // COMMENT THIS LINE OUT PRIOR TO CHECKIN
#ifdef ENABLE_DEBUG_PRINTF
#include <stdio.h>
-#define DEBUG_PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__)
+#define DEBUG_PRINTF(fmt, ...) printf(fmt, ##__VA_ARGS__)
#else
#define DEBUG_PRINTF(fmt, ...)
#endif
@@ -48,169 +48,140 @@
using namespace lldb;
using namespace lldb_private;
-
//----------------------------------------------------------------------
// Create an instance of this class. This function is filled into
// the plugin info class that gets handed out by the plugin factory and
// allows the lldb to instantiate an instance of this class.
//----------------------------------------------------------------------
-DynamicLoader *
-DynamicLoaderMacOSXDYLD::CreateInstance (Process* process, bool force)
-{
- bool create = force;
- if (!create)
- {
- create = true;
- Module* exe_module = process->GetTarget().GetExecutableModulePointer();
- if (exe_module)
- {
- ObjectFile *object_file = exe_module->GetObjectFile();
- if (object_file)
- {
- create = (object_file->GetStrata() == ObjectFile::eStrataUser);
- }
- }
-
- if (create)
- {
- const llvm::Triple &triple_ref = process->GetTarget().GetArchitecture().GetTriple();
- switch (triple_ref.getOS())
- {
- case llvm::Triple::Darwin:
- case llvm::Triple::MacOSX:
- case llvm::Triple::IOS:
- case llvm::Triple::TvOS:
- case llvm::Triple::WatchOS:
- create = triple_ref.getVendor() == llvm::Triple::Apple;
- break;
- default:
- create = false;
- break;
- }
- }
+DynamicLoader *DynamicLoaderMacOSXDYLD::CreateInstance(Process *process,
+ bool force) {
+ bool create = force;
+ if (!create) {
+ create = true;
+ Module *exe_module = process->GetTarget().GetExecutableModulePointer();
+ if (exe_module) {
+ ObjectFile *object_file = exe_module->GetObjectFile();
+ if (object_file) {
+ create = (object_file->GetStrata() == ObjectFile::eStrataUser);
+ }
}
- if (UseDYLDSPI (process) == true)
- {
+ if (create) {
+ const llvm::Triple &triple_ref =
+ process->GetTarget().GetArchitecture().GetTriple();
+ switch (triple_ref.getOS()) {
+ case llvm::Triple::Darwin:
+ case llvm::Triple::MacOSX:
+ case llvm::Triple::IOS:
+ case llvm::Triple::TvOS:
+ case llvm::Triple::WatchOS:
+ create = triple_ref.getVendor() == llvm::Triple::Apple;
+ break;
+ default:
create = false;
+ break;
+ }
}
-
- if (create)
- return new DynamicLoaderMacOSXDYLD (process);
- return NULL;
+ }
+
+ if (UseDYLDSPI(process) == true) {
+ create = false;
+ }
+
+ if (create)
+ return new DynamicLoaderMacOSXDYLD(process);
+ return NULL;
}
//----------------------------------------------------------------------
// Constructor
//----------------------------------------------------------------------
-DynamicLoaderMacOSXDYLD::DynamicLoaderMacOSXDYLD (Process* process) :
- DynamicLoaderDarwin(process),
- m_dyld_all_image_infos_addr(LLDB_INVALID_ADDRESS),
- m_dyld_all_image_infos(),
- m_dyld_all_image_infos_stop_id (UINT32_MAX),
- m_break_id(LLDB_INVALID_BREAK_ID),
- m_mutex(),
- m_process_image_addr_is_all_images_infos (false)
-{
-}
+DynamicLoaderMacOSXDYLD::DynamicLoaderMacOSXDYLD(Process *process)
+ : DynamicLoaderDarwin(process),
+ m_dyld_all_image_infos_addr(LLDB_INVALID_ADDRESS),
+ m_dyld_all_image_infos(), m_dyld_all_image_infos_stop_id(UINT32_MAX),
+ m_break_id(LLDB_INVALID_BREAK_ID), m_mutex(),
+ m_process_image_addr_is_all_images_infos(false) {}
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
-DynamicLoaderMacOSXDYLD::~DynamicLoaderMacOSXDYLD()
-{
- if (LLDB_BREAK_ID_IS_VALID(m_break_id))
- m_process->GetTarget().RemoveBreakpointByID (m_break_id);
+DynamicLoaderMacOSXDYLD::~DynamicLoaderMacOSXDYLD() {
+ if (LLDB_BREAK_ID_IS_VALID(m_break_id))
+ m_process->GetTarget().RemoveBreakpointByID(m_break_id);
}
-bool
-DynamicLoaderMacOSXDYLD::ProcessDidExec ()
-{
- std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
- bool did_exec = false;
- if (m_process)
- {
- // If we are stopped after an exec, we will have only one thread...
- if (m_process->GetThreadList().GetSize() == 1)
- {
- // We know if a process has exec'ed if our "m_dyld_all_image_infos_addr"
- // value differs from the Process' image info address. When a process
- // execs itself it might cause a change if ASLR is enabled.
- const addr_t shlib_addr = m_process->GetImageInfoAddress ();
- if (m_process_image_addr_is_all_images_infos == true && shlib_addr != m_dyld_all_image_infos_addr)
- {
- // The image info address from the process is the 'dyld_all_image_infos'
- // address and it has changed.
- did_exec = true;
- }
- else if (m_process_image_addr_is_all_images_infos == false && shlib_addr == m_dyld.address)
- {
- // The image info address from the process is the mach_header
- // address for dyld and it has changed.
+bool DynamicLoaderMacOSXDYLD::ProcessDidExec() {
+ std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
+ bool did_exec = false;
+ if (m_process) {
+ // If we are stopped after an exec, we will have only one thread...
+ if (m_process->GetThreadList().GetSize() == 1) {
+ // We know if a process has exec'ed if our "m_dyld_all_image_infos_addr"
+ // value differs from the Process' image info address. When a process
+ // execs itself it might cause a change if ASLR is enabled.
+ const addr_t shlib_addr = m_process->GetImageInfoAddress();
+ if (m_process_image_addr_is_all_images_infos == true &&
+ shlib_addr != m_dyld_all_image_infos_addr) {
+ // The image info address from the process is the 'dyld_all_image_infos'
+ // address and it has changed.
+ did_exec = true;
+ } else if (m_process_image_addr_is_all_images_infos == false &&
+ shlib_addr == m_dyld.address) {
+ // The image info address from the process is the mach_header
+ // address for dyld and it has changed.
+ did_exec = true;
+ } else {
+ // ASLR might be disabled and dyld could have ended up in the same
+ // location. We should try and detect if we are stopped at '_dyld_start'
+ ThreadSP thread_sp(m_process->GetThreadList().GetThreadAtIndex(0));
+ if (thread_sp) {
+ lldb::StackFrameSP frame_sp(thread_sp->GetStackFrameAtIndex(0));
+ if (frame_sp) {
+ const Symbol *symbol =
+ frame_sp->GetSymbolContext(eSymbolContextSymbol).symbol;
+ if (symbol) {
+ if (symbol->GetName() == ConstString("_dyld_start"))
did_exec = true;
}
- else
- {
- // ASLR might be disabled and dyld could have ended up in the same
- // location. We should try and detect if we are stopped at '_dyld_start'
- ThreadSP thread_sp(m_process->GetThreadList().GetThreadAtIndex(0));
- if (thread_sp)
- {
- lldb::StackFrameSP frame_sp(thread_sp->GetStackFrameAtIndex(0));
- if (frame_sp)
- {
- const Symbol *symbol = frame_sp->GetSymbolContext(eSymbolContextSymbol).symbol;
- if (symbol)
- {
- if (symbol->GetName() == ConstString("_dyld_start"))
- did_exec = true;
- }
- }
- }
- }
-
- if (did_exec)
- {
- m_libpthread_module_wp.reset();
- m_pthread_getspecific_addr.Clear();
- }
+ }
}
+ }
+
+ if (did_exec) {
+ m_libpthread_module_wp.reset();
+ m_pthread_getspecific_addr.Clear();
+ }
}
- return did_exec;
+ }
+ return did_exec;
}
//----------------------------------------------------------------------
// Clear out the state of this class.
//----------------------------------------------------------------------
-void
-DynamicLoaderMacOSXDYLD::DoClear ()
-{
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
+void DynamicLoaderMacOSXDYLD::DoClear() {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
- if (LLDB_BREAK_ID_IS_VALID(m_break_id))
- m_process->GetTarget().RemoveBreakpointByID (m_break_id);
+ if (LLDB_BREAK_ID_IS_VALID(m_break_id))
+ m_process->GetTarget().RemoveBreakpointByID(m_break_id);
- m_dyld_all_image_infos_addr = LLDB_INVALID_ADDRESS;
- m_dyld_all_image_infos.Clear();
- m_break_id = LLDB_INVALID_BREAK_ID;
+ m_dyld_all_image_infos_addr = LLDB_INVALID_ADDRESS;
+ m_dyld_all_image_infos.Clear();
+ m_break_id = LLDB_INVALID_BREAK_ID;
}
//----------------------------------------------------------------------
// Check if we have found DYLD yet
//----------------------------------------------------------------------
-bool
-DynamicLoaderMacOSXDYLD::DidSetNotificationBreakpoint()
-{
- return LLDB_BREAK_ID_IS_VALID (m_break_id);
+bool DynamicLoaderMacOSXDYLD::DidSetNotificationBreakpoint() {
+ return LLDB_BREAK_ID_IS_VALID(m_break_id);
}
-void
-DynamicLoaderMacOSXDYLD::ClearNotificationBreakpoint ()
-{
- if (LLDB_BREAK_ID_IS_VALID (m_break_id))
- {
- m_process->GetTarget().RemoveBreakpointByID (m_break_id);
- }
+void DynamicLoaderMacOSXDYLD::ClearNotificationBreakpoint() {
+ if (LLDB_BREAK_ID_IS_VALID(m_break_id)) {
+ m_process->GetTarget().RemoveBreakpointByID(m_break_id);
+ }
}
//----------------------------------------------------------------------
@@ -219,143 +190,127 @@ DynamicLoaderMacOSXDYLD::ClearNotificationBreakpoint ()
// to get the DYLD info (available on SnowLeopard only). If that fails,
// then check in the default addresses.
//----------------------------------------------------------------------
-void
-DynamicLoaderMacOSXDYLD::DoInitialImageFetch()
-{
- if (m_dyld_all_image_infos_addr == LLDB_INVALID_ADDRESS)
- {
- // Check the image info addr as it might point to the
- // mach header for dyld, or it might point to the
- // dyld_all_image_infos struct
- const addr_t shlib_addr = m_process->GetImageInfoAddress ();
- if (shlib_addr != LLDB_INVALID_ADDRESS)
- {
- ByteOrder byte_order = m_process->GetTarget().GetArchitecture().GetByteOrder();
- uint8_t buf[4];
- DataExtractor data (buf, sizeof(buf), byte_order, 4);
- Error error;
- if (m_process->ReadMemory (shlib_addr, buf, 4, error) == 4)
- {
- lldb::offset_t offset = 0;
- uint32_t magic = data.GetU32 (&offset);
- switch (magic)
- {
- case llvm::MachO::MH_MAGIC:
- case llvm::MachO::MH_MAGIC_64:
- case llvm::MachO::MH_CIGAM:
- case llvm::MachO::MH_CIGAM_64:
- m_process_image_addr_is_all_images_infos = false;
- ReadDYLDInfoFromMemoryAndSetNotificationCallback(shlib_addr);
- return;
-
- default:
- break;
- }
- }
- // Maybe it points to the all image infos?
- m_dyld_all_image_infos_addr = shlib_addr;
- m_process_image_addr_is_all_images_infos = true;
- }
- }
+void DynamicLoaderMacOSXDYLD::DoInitialImageFetch() {
+ if (m_dyld_all_image_infos_addr == LLDB_INVALID_ADDRESS) {
+ // Check the image info addr as it might point to the
+ // mach header for dyld, or it might point to the
+ // dyld_all_image_infos struct
+ const addr_t shlib_addr = m_process->GetImageInfoAddress();
+ if (shlib_addr != LLDB_INVALID_ADDRESS) {
+ ByteOrder byte_order =
+ m_process->GetTarget().GetArchitecture().GetByteOrder();
+ uint8_t buf[4];
+ DataExtractor data(buf, sizeof(buf), byte_order, 4);
+ Error error;
+ if (m_process->ReadMemory(shlib_addr, buf, 4, error) == 4) {
+ lldb::offset_t offset = 0;
+ uint32_t magic = data.GetU32(&offset);
+ switch (magic) {
+ case llvm::MachO::MH_MAGIC:
+ case llvm::MachO::MH_MAGIC_64:
+ case llvm::MachO::MH_CIGAM:
+ case llvm::MachO::MH_CIGAM_64:
+ m_process_image_addr_is_all_images_infos = false;
+ ReadDYLDInfoFromMemoryAndSetNotificationCallback(shlib_addr);
+ return;
- if (m_dyld_all_image_infos_addr != LLDB_INVALID_ADDRESS)
- {
- if (ReadAllImageInfosStructure ())
- {
- if (m_dyld_all_image_infos.dyldImageLoadAddress != LLDB_INVALID_ADDRESS)
- ReadDYLDInfoFromMemoryAndSetNotificationCallback (m_dyld_all_image_infos.dyldImageLoadAddress);
- else
- ReadDYLDInfoFromMemoryAndSetNotificationCallback (m_dyld_all_image_infos_addr & 0xfffffffffff00000ull);
- return;
+ default:
+ break;
}
+ }
+ // Maybe it points to the all image infos?
+ m_dyld_all_image_infos_addr = shlib_addr;
+ m_process_image_addr_is_all_images_infos = true;
}
-
- // Check some default values
- Module *executable = m_process->GetTarget().GetExecutableModulePointer();
-
- if (executable)
- {
- const ArchSpec &exe_arch = executable->GetArchitecture();
- if (exe_arch.GetAddressByteSize() == 8)
- {
- ReadDYLDInfoFromMemoryAndSetNotificationCallback(0x7fff5fc00000ull);
- }
- else if (exe_arch.GetMachine() == llvm::Triple::arm || exe_arch.GetMachine() == llvm::Triple::thumb || exe_arch.GetMachine() == llvm::Triple::aarch64)
- {
- ReadDYLDInfoFromMemoryAndSetNotificationCallback(0x2fe00000);
- }
- else
- {
- ReadDYLDInfoFromMemoryAndSetNotificationCallback(0x8fe00000);
- }
+ }
+
+ if (m_dyld_all_image_infos_addr != LLDB_INVALID_ADDRESS) {
+ if (ReadAllImageInfosStructure()) {
+ if (m_dyld_all_image_infos.dyldImageLoadAddress != LLDB_INVALID_ADDRESS)
+ ReadDYLDInfoFromMemoryAndSetNotificationCallback(
+ m_dyld_all_image_infos.dyldImageLoadAddress);
+ else
+ ReadDYLDInfoFromMemoryAndSetNotificationCallback(
+ m_dyld_all_image_infos_addr & 0xfffffffffff00000ull);
+ return;
}
- return;
+ }
+
+ // Check some default values
+ Module *executable = m_process->GetTarget().GetExecutableModulePointer();
+
+ if (executable) {
+ const ArchSpec &exe_arch = executable->GetArchitecture();
+ if (exe_arch.GetAddressByteSize() == 8) {
+ ReadDYLDInfoFromMemoryAndSetNotificationCallback(0x7fff5fc00000ull);
+ } else if (exe_arch.GetMachine() == llvm::Triple::arm ||
+ exe_arch.GetMachine() == llvm::Triple::thumb ||
+ exe_arch.GetMachine() == llvm::Triple::aarch64) {
+ ReadDYLDInfoFromMemoryAndSetNotificationCallback(0x2fe00000);
+ } else {
+ ReadDYLDInfoFromMemoryAndSetNotificationCallback(0x8fe00000);
+ }
+ }
+ return;
}
//----------------------------------------------------------------------
// Assume that dyld is in memory at ADDR and try to parse it's load
// commands
//----------------------------------------------------------------------
-bool
-DynamicLoaderMacOSXDYLD::ReadDYLDInfoFromMemoryAndSetNotificationCallback(lldb::addr_t addr)
-{
- std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
- DataExtractor data; // Load command data
- static ConstString g_dyld_all_image_infos ("dyld_all_image_infos");
- if (ReadMachHeader (addr, &m_dyld.header, &data))
- {
- if (m_dyld.header.filetype == llvm::MachO::MH_DYLINKER)
- {
- m_dyld.address = addr;
- ModuleSP dyld_module_sp;
- if (ParseLoadCommands (data, m_dyld, &m_dyld.file_spec))
- {
- if (m_dyld.file_spec)
- {
- UpdateDYLDImageInfoFromNewImageInfo (m_dyld);
-
- }
- }
- dyld_module_sp = GetDYLDModule();
-
- Target &target = m_process->GetTarget();
-
- if (m_dyld_all_image_infos_addr == LLDB_INVALID_ADDRESS && dyld_module_sp.get())
- {
- const Symbol *symbol = dyld_module_sp->FindFirstSymbolWithNameAndType (g_dyld_all_image_infos, eSymbolTypeData);
- if (symbol)
- m_dyld_all_image_infos_addr = symbol->GetLoadAddress(&target);
- }
-
- // Update all image infos
- InitializeFromAllImageInfos ();
-
- // If we didn't have an executable before, but now we do, then the
- // dyld module shared pointer might be unique and we may need to add
- // it again (since Target::SetExecutableModule() will clear the
- // images). So append the dyld module back to the list if it is
- /// unique!
- if (dyld_module_sp)
- {
- target.GetImages().AppendIfNeeded (dyld_module_sp);
-
- // At this point we should have read in dyld's module, and so we should set breakpoints in it:
- ModuleList modules;
- modules.Append(dyld_module_sp);
- target.ModulesDidLoad(modules);
- SetDYLDModule (dyld_module_sp);
- }
-
- return true;
+bool DynamicLoaderMacOSXDYLD::ReadDYLDInfoFromMemoryAndSetNotificationCallback(
+ lldb::addr_t addr) {
+ std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
+ DataExtractor data; // Load command data
+ static ConstString g_dyld_all_image_infos("dyld_all_image_infos");
+ if (ReadMachHeader(addr, &m_dyld.header, &data)) {
+ if (m_dyld.header.filetype == llvm::MachO::MH_DYLINKER) {
+ m_dyld.address = addr;
+ ModuleSP dyld_module_sp;
+ if (ParseLoadCommands(data, m_dyld, &m_dyld.file_spec)) {
+ if (m_dyld.file_spec) {
+ UpdateDYLDImageInfoFromNewImageInfo(m_dyld);
}
+ }
+ dyld_module_sp = GetDYLDModule();
+
+ Target &target = m_process->GetTarget();
+
+ if (m_dyld_all_image_infos_addr == LLDB_INVALID_ADDRESS &&
+ dyld_module_sp.get()) {
+ const Symbol *symbol = dyld_module_sp->FindFirstSymbolWithNameAndType(
+ g_dyld_all_image_infos, eSymbolTypeData);
+ if (symbol)
+ m_dyld_all_image_infos_addr = symbol->GetLoadAddress(&target);
+ }
+
+ // Update all image infos
+ InitializeFromAllImageInfos();
+
+ // If we didn't have an executable before, but now we do, then the
+ // dyld module shared pointer might be unique and we may need to add
+ // it again (since Target::SetExecutableModule() will clear the
+ // images). So append the dyld module back to the list if it is
+ /// unique!
+ if (dyld_module_sp) {
+ target.GetImages().AppendIfNeeded(dyld_module_sp);
+
+ // At this point we should have read in dyld's module, and so we should
+ // set breakpoints in it:
+ ModuleList modules;
+ modules.Append(dyld_module_sp);
+ target.ModulesDidLoad(modules);
+ SetDYLDModule(dyld_module_sp);
+ }
+
+ return true;
}
- return false;
+ }
+ return false;
}
-bool
-DynamicLoaderMacOSXDYLD::NeedToDoInitialImageFetch ()
-{
- return m_dyld_all_image_infos_addr == LLDB_INVALID_ADDRESS;
+bool DynamicLoaderMacOSXDYLD::NeedToDoInitialImageFetch() {
+ return m_dyld_all_image_infos_addr == LLDB_INVALID_ADDRESS;
}
//----------------------------------------------------------------------
@@ -364,392 +319,398 @@ DynamicLoaderMacOSXDYLD::NeedToDoInitialImageFetch ()
// let our super class DynamicLoader class decide if we should stop
// or not (based on global preference).
//----------------------------------------------------------------------
-bool
-DynamicLoaderMacOSXDYLD::NotifyBreakpointHit (void *baton,
- StoppointCallbackContext *context,
- lldb::user_id_t break_id,
- lldb::user_id_t break_loc_id)
-{
- // Let the event know that the images have changed
- // DYLD passes three arguments to the notification breakpoint.
- // Arg1: enum dyld_image_mode mode - 0 = adding, 1 = removing
- // Arg2: uint32_t infoCount - Number of shared libraries added
- // Arg3: dyld_image_info info[] - Array of structs of the form:
- // const struct mach_header *imageLoadAddress
- // const char *imageFilePath
- // uintptr_t imageFileModDate (a time_t)
-
- DynamicLoaderMacOSXDYLD* dyld_instance = (DynamicLoaderMacOSXDYLD*) baton;
-
- // First step is to see if we've already initialized the all image infos. If we haven't then this function
- // will do so and return true. In the course of initializing the all_image_infos it will read the complete
- // current state, so we don't need to figure out what has changed from the data passed in to us.
-
- ExecutionContext exe_ctx (context->exe_ctx_ref);
- Process *process = exe_ctx.GetProcessPtr();
-
- // This is a sanity check just in case this dyld_instance is an old dyld plugin's breakpoint still lying around.
- if (process != dyld_instance->m_process)
- return false;
-
- if (dyld_instance->InitializeFromAllImageInfos())
- return dyld_instance->GetStopWhenImagesChange();
-
- const lldb::ABISP &abi = process->GetABI();
- if (abi)
- {
- // Build up the value array to store the three arguments given above, then get the values from the ABI:
-
- ClangASTContext *clang_ast_context = process->GetTarget().GetScratchClangASTContext();
- ValueList argument_values;
- Value input_value;
-
- CompilerType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
- CompilerType clang_uint32_type = clang_ast_context->GetBuiltinTypeForEncodingAndBitSize(lldb::eEncodingUint, 32);
- input_value.SetValueType (Value::eValueTypeScalar);
- input_value.SetCompilerType (clang_uint32_type);
-// input_value.SetContext (Value::eContextTypeClangType, clang_uint32_type);
- argument_values.PushValue (input_value);
- argument_values.PushValue (input_value);
- input_value.SetCompilerType (clang_void_ptr_type);
- // input_value.SetContext (Value::eContextTypeClangType, clang_void_ptr_type);
- argument_values.PushValue (input_value);
-
- if (abi->GetArgumentValues (exe_ctx.GetThreadRef(), argument_values))
- {
- uint32_t dyld_mode = argument_values.GetValueAtIndex(0)->GetScalar().UInt (-1);
- if (dyld_mode != static_cast<uint32_t>(-1))
- {
- // Okay the mode was right, now get the number of elements, and the array of new elements...
- uint32_t image_infos_count = argument_values.GetValueAtIndex(1)->GetScalar().UInt (-1);
- if (image_infos_count != static_cast<uint32_t>(-1))
- {
- // Got the number added, now go through the array of added elements, putting out the mach header
- // address, and adding the image.
- // Note, I'm not putting in logging here, since the AddModules & RemoveModules functions do
- // all the logging internally.
-
- lldb::addr_t image_infos_addr = argument_values.GetValueAtIndex(2)->GetScalar().ULongLong();
- if (dyld_mode == 0)
- {
- // This is add:
- dyld_instance->AddModulesUsingImageInfosAddress (image_infos_addr, image_infos_count);
- }
- else
- {
- // This is remove:
- dyld_instance->RemoveModulesUsingImageInfosAddress (image_infos_addr, image_infos_count);
- }
-
- }
- }
+bool DynamicLoaderMacOSXDYLD::NotifyBreakpointHit(
+ void *baton, StoppointCallbackContext *context, lldb::user_id_t break_id,
+ lldb::user_id_t break_loc_id) {
+ // Let the event know that the images have changed
+ // DYLD passes three arguments to the notification breakpoint.
+ // Arg1: enum dyld_image_mode mode - 0 = adding, 1 = removing
+ // Arg2: uint32_t infoCount - Number of shared libraries added
+ // Arg3: dyld_image_info info[] - Array of structs of the form:
+ // const struct mach_header
+ // *imageLoadAddress
+ // const char *imageFilePath
+ // uintptr_t imageFileModDate (a time_t)
+
+ DynamicLoaderMacOSXDYLD *dyld_instance = (DynamicLoaderMacOSXDYLD *)baton;
+
+ // First step is to see if we've already initialized the all image infos. If
+ // we haven't then this function
+ // will do so and return true. In the course of initializing the
+ // all_image_infos it will read the complete
+ // current state, so we don't need to figure out what has changed from the
+ // data passed in to us.
+
+ ExecutionContext exe_ctx(context->exe_ctx_ref);
+ Process *process = exe_ctx.GetProcessPtr();
+
+ // This is a sanity check just in case this dyld_instance is an old dyld
+ // plugin's breakpoint still lying around.
+ if (process != dyld_instance->m_process)
+ return false;
+
+ if (dyld_instance->InitializeFromAllImageInfos())
+ return dyld_instance->GetStopWhenImagesChange();
+
+ const lldb::ABISP &abi = process->GetABI();
+ if (abi) {
+ // Build up the value array to store the three arguments given above, then
+ // get the values from the ABI:
+
+ ClangASTContext *clang_ast_context =
+ process->GetTarget().GetScratchClangASTContext();
+ ValueList argument_values;
+ Value input_value;
+
+ CompilerType clang_void_ptr_type =
+ clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
+ CompilerType clang_uint32_type =
+ clang_ast_context->GetBuiltinTypeForEncodingAndBitSize(
+ lldb::eEncodingUint, 32);
+ input_value.SetValueType(Value::eValueTypeScalar);
+ input_value.SetCompilerType(clang_uint32_type);
+ // input_value.SetContext (Value::eContextTypeClangType,
+ // clang_uint32_type);
+ argument_values.PushValue(input_value);
+ argument_values.PushValue(input_value);
+ input_value.SetCompilerType(clang_void_ptr_type);
+ // input_value.SetContext (Value::eContextTypeClangType,
+ // clang_void_ptr_type);
+ argument_values.PushValue(input_value);
+
+ if (abi->GetArgumentValues(exe_ctx.GetThreadRef(), argument_values)) {
+ uint32_t dyld_mode =
+ argument_values.GetValueAtIndex(0)->GetScalar().UInt(-1);
+ if (dyld_mode != static_cast<uint32_t>(-1)) {
+ // Okay the mode was right, now get the number of elements, and the
+ // array of new elements...
+ uint32_t image_infos_count =
+ argument_values.GetValueAtIndex(1)->GetScalar().UInt(-1);
+ if (image_infos_count != static_cast<uint32_t>(-1)) {
+ // Got the number added, now go through the array of added elements,
+ // putting out the mach header
+ // address, and adding the image.
+ // Note, I'm not putting in logging here, since the AddModules &
+ // RemoveModules functions do
+ // all the logging internally.
+
+ lldb::addr_t image_infos_addr =
+ argument_values.GetValueAtIndex(2)->GetScalar().ULongLong();
+ if (dyld_mode == 0) {
+ // This is add:
+ dyld_instance->AddModulesUsingImageInfosAddress(image_infos_addr,
+ image_infos_count);
+ } else {
+ // This is remove:
+ dyld_instance->RemoveModulesUsingImageInfosAddress(
+ image_infos_addr, image_infos_count);
+ }
}
+ }
}
- else
- {
- process->GetTarget().GetDebugger().GetAsyncErrorStream()->Printf("No ABI plugin located for triple %s -- shared libraries will not be registered!\n", process->GetTarget().GetArchitecture().GetTriple().getTriple().c_str());
- }
-
- // Return true to stop the target, false to just let the target run
- return dyld_instance->GetStopWhenImagesChange();
+ } else {
+ process->GetTarget().GetDebugger().GetAsyncErrorStream()->Printf(
+ "No ABI plugin located for triple %s -- shared libraries will not be "
+ "registered!\n",
+ process->GetTarget().GetArchitecture().GetTriple().getTriple().c_str());
+ }
+
+ // Return true to stop the target, false to just let the target run
+ return dyld_instance->GetStopWhenImagesChange();
}
-bool
-DynamicLoaderMacOSXDYLD::ReadAllImageInfosStructure ()
-{
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
+bool DynamicLoaderMacOSXDYLD::ReadAllImageInfosStructure() {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
- // the all image infos is already valid for this process stop ID
- if (m_process->GetStopID() == m_dyld_all_image_infos_stop_id)
- return true;
+ // the all image infos is already valid for this process stop ID
+ if (m_process->GetStopID() == m_dyld_all_image_infos_stop_id)
+ return true;
- m_dyld_all_image_infos.Clear();
- if (m_dyld_all_image_infos_addr != LLDB_INVALID_ADDRESS)
- {
- ByteOrder byte_order = m_process->GetTarget().GetArchitecture().GetByteOrder();
- uint32_t addr_size = 4;
- if (m_dyld_all_image_infos_addr > UINT32_MAX)
- addr_size = 8;
+ m_dyld_all_image_infos.Clear();
+ if (m_dyld_all_image_infos_addr != LLDB_INVALID_ADDRESS) {
+ ByteOrder byte_order =
+ m_process->GetTarget().GetArchitecture().GetByteOrder();
+ uint32_t addr_size = 4;
+ if (m_dyld_all_image_infos_addr > UINT32_MAX)
+ addr_size = 8;
- uint8_t buf[256];
- DataExtractor data (buf, sizeof(buf), byte_order, addr_size);
- lldb::offset_t offset = 0;
+ uint8_t buf[256];
+ DataExtractor data(buf, sizeof(buf), byte_order, addr_size);
+ lldb::offset_t offset = 0;
- const size_t count_v2 = sizeof (uint32_t) + // version
- sizeof (uint32_t) + // infoArrayCount
- addr_size + // infoArray
- addr_size + // notification
- addr_size + // processDetachedFromSharedRegion + libSystemInitialized + pad
- addr_size; // dyldImageLoadAddress
- const size_t count_v11 = count_v2 +
- addr_size + // jitInfo
- addr_size + // dyldVersion
- addr_size + // errorMessage
- addr_size + // terminationFlags
- addr_size + // coreSymbolicationShmPage
- addr_size + // systemOrderFlag
- addr_size + // uuidArrayCount
- addr_size + // uuidArray
- addr_size + // dyldAllImageInfosAddress
- addr_size + // initialImageCount
- addr_size + // errorKind
- addr_size + // errorClientOfDylibPath
- addr_size + // errorTargetDylibPath
- addr_size; // errorSymbol
- const size_t count_v13 = count_v11 +
- addr_size + // sharedCacheSlide
- sizeof (uuid_t); // sharedCacheUUID
- UNUSED_IF_ASSERT_DISABLED(count_v13);
- assert (sizeof (buf) >= count_v13);
-
- Error error;
- if (m_process->ReadMemory (m_dyld_all_image_infos_addr, buf, 4, error) == 4)
- {
- m_dyld_all_image_infos.version = data.GetU32(&offset);
- // If anything in the high byte is set, we probably got the byte
- // order incorrect (the process might not have it set correctly
- // yet due to attaching to a program without a specified file).
- if (m_dyld_all_image_infos.version & 0xff000000)
- {
- // We have guessed the wrong byte order. Swap it and try
- // reading the version again.
- if (byte_order == eByteOrderLittle)
- byte_order = eByteOrderBig;
- else
- byte_order = eByteOrderLittle;
-
- data.SetByteOrder (byte_order);
- offset = 0;
- m_dyld_all_image_infos.version = data.GetU32(&offset);
- }
- }
+ const size_t count_v2 = sizeof(uint32_t) + // version
+ sizeof(uint32_t) + // infoArrayCount
+ addr_size + // infoArray
+ addr_size + // notification
+ addr_size + // processDetachedFromSharedRegion +
+ // libSystemInitialized + pad
+ addr_size; // dyldImageLoadAddress
+ const size_t count_v11 = count_v2 + addr_size + // jitInfo
+ addr_size + // dyldVersion
+ addr_size + // errorMessage
+ addr_size + // terminationFlags
+ addr_size + // coreSymbolicationShmPage
+ addr_size + // systemOrderFlag
+ addr_size + // uuidArrayCount
+ addr_size + // uuidArray
+ addr_size + // dyldAllImageInfosAddress
+ addr_size + // initialImageCount
+ addr_size + // errorKind
+ addr_size + // errorClientOfDylibPath
+ addr_size + // errorTargetDylibPath
+ addr_size; // errorSymbol
+ const size_t count_v13 = count_v11 + addr_size + // sharedCacheSlide
+ sizeof(uuid_t); // sharedCacheUUID
+ UNUSED_IF_ASSERT_DISABLED(count_v13);
+ assert(sizeof(buf) >= count_v13);
+
+ Error error;
+ if (m_process->ReadMemory(m_dyld_all_image_infos_addr, buf, 4, error) ==
+ 4) {
+ m_dyld_all_image_infos.version = data.GetU32(&offset);
+ // If anything in the high byte is set, we probably got the byte
+ // order incorrect (the process might not have it set correctly
+ // yet due to attaching to a program without a specified file).
+ if (m_dyld_all_image_infos.version & 0xff000000) {
+ // We have guessed the wrong byte order. Swap it and try
+ // reading the version again.
+ if (byte_order == eByteOrderLittle)
+ byte_order = eByteOrderBig;
else
- {
- return false;
- }
+ byte_order = eByteOrderLittle;
+
+ data.SetByteOrder(byte_order);
+ offset = 0;
+ m_dyld_all_image_infos.version = data.GetU32(&offset);
+ }
+ } else {
+ return false;
+ }
- const size_t count = (m_dyld_all_image_infos.version >= 11) ? count_v11 : count_v2;
-
- const size_t bytes_read = m_process->ReadMemory (m_dyld_all_image_infos_addr, buf, count, error);
- if (bytes_read == count)
- {
- offset = 0;
- m_dyld_all_image_infos.version = data.GetU32(&offset);
- m_dyld_all_image_infos.dylib_info_count = data.GetU32(&offset);
- m_dyld_all_image_infos.dylib_info_addr = data.GetPointer(&offset);
- m_dyld_all_image_infos.notification = data.GetPointer(&offset);
- m_dyld_all_image_infos.processDetachedFromSharedRegion = data.GetU8(&offset);
- m_dyld_all_image_infos.libSystemInitialized = data.GetU8(&offset);
- // Adjust for padding.
- offset += addr_size - 2;
- m_dyld_all_image_infos.dyldImageLoadAddress = data.GetPointer(&offset);
- if (m_dyld_all_image_infos.version >= 11)
- {
- offset += addr_size * 8;
- uint64_t dyld_all_image_infos_addr = data.GetPointer(&offset);
-
- // When we started, we were given the actual address of the all_image_infos
- // struct (probably via TASK_DYLD_INFO) in memory - this address is stored in
- // m_dyld_all_image_infos_addr and is the most accurate address we have.
-
- // We read the dyld_all_image_infos struct from memory; it contains its own address.
- // If the address in the struct does not match the actual address,
- // the dyld we're looking at has been loaded at a different location (slid) from
- // where it intended to load. The addresses in the dyld_all_image_infos struct
- // are the original, non-slid addresses, and need to be adjusted. Most importantly
- // the address of dyld and the notification address need to be adjusted.
-
- if (dyld_all_image_infos_addr != m_dyld_all_image_infos_addr)
- {
- uint64_t image_infos_offset = dyld_all_image_infos_addr - m_dyld_all_image_infos.dyldImageLoadAddress;
- uint64_t notification_offset = m_dyld_all_image_infos.notification - m_dyld_all_image_infos.dyldImageLoadAddress;
- m_dyld_all_image_infos.dyldImageLoadAddress = m_dyld_all_image_infos_addr - image_infos_offset;
- m_dyld_all_image_infos.notification = m_dyld_all_image_infos.dyldImageLoadAddress + notification_offset;
- }
- }
- m_dyld_all_image_infos_stop_id = m_process->GetStopID();
- return true;
+ const size_t count =
+ (m_dyld_all_image_infos.version >= 11) ? count_v11 : count_v2;
+
+ const size_t bytes_read =
+ m_process->ReadMemory(m_dyld_all_image_infos_addr, buf, count, error);
+ if (bytes_read == count) {
+ offset = 0;
+ m_dyld_all_image_infos.version = data.GetU32(&offset);
+ m_dyld_all_image_infos.dylib_info_count = data.GetU32(&offset);
+ m_dyld_all_image_infos.dylib_info_addr = data.GetPointer(&offset);
+ m_dyld_all_image_infos.notification = data.GetPointer(&offset);
+ m_dyld_all_image_infos.processDetachedFromSharedRegion =
+ data.GetU8(&offset);
+ m_dyld_all_image_infos.libSystemInitialized = data.GetU8(&offset);
+ // Adjust for padding.
+ offset += addr_size - 2;
+ m_dyld_all_image_infos.dyldImageLoadAddress = data.GetPointer(&offset);
+ if (m_dyld_all_image_infos.version >= 11) {
+ offset += addr_size * 8;
+ uint64_t dyld_all_image_infos_addr = data.GetPointer(&offset);
+
+ // When we started, we were given the actual address of the
+ // all_image_infos
+ // struct (probably via TASK_DYLD_INFO) in memory - this address is
+ // stored in
+ // m_dyld_all_image_infos_addr and is the most accurate address we have.
+
+ // We read the dyld_all_image_infos struct from memory; it contains its
+ // own address.
+ // If the address in the struct does not match the actual address,
+ // the dyld we're looking at has been loaded at a different location
+ // (slid) from
+ // where it intended to load. The addresses in the dyld_all_image_infos
+ // struct
+ // are the original, non-slid addresses, and need to be adjusted. Most
+ // importantly
+ // the address of dyld and the notification address need to be adjusted.
+
+ if (dyld_all_image_infos_addr != m_dyld_all_image_infos_addr) {
+ uint64_t image_infos_offset =
+ dyld_all_image_infos_addr -
+ m_dyld_all_image_infos.dyldImageLoadAddress;
+ uint64_t notification_offset =
+ m_dyld_all_image_infos.notification -
+ m_dyld_all_image_infos.dyldImageLoadAddress;
+ m_dyld_all_image_infos.dyldImageLoadAddress =
+ m_dyld_all_image_infos_addr - image_infos_offset;
+ m_dyld_all_image_infos.notification =
+ m_dyld_all_image_infos.dyldImageLoadAddress + notification_offset;
}
+ }
+ m_dyld_all_image_infos_stop_id = m_process->GetStopID();
+ return true;
}
- return false;
+ }
+ return false;
}
+bool DynamicLoaderMacOSXDYLD::AddModulesUsingImageInfosAddress(
+ lldb::addr_t image_infos_addr, uint32_t image_infos_count) {
+ ImageInfo::collection image_infos;
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+ if (log)
+ log->Printf("Adding %d modules.\n", image_infos_count);
-bool
-DynamicLoaderMacOSXDYLD::AddModulesUsingImageInfosAddress (lldb::addr_t image_infos_addr, uint32_t image_infos_count)
-{
- ImageInfo::collection image_infos;
- Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
- if (log)
- log->Printf ("Adding %d modules.\n", image_infos_count);
-
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
- if (m_process->GetStopID() == m_dyld_image_infos_stop_id)
- return true;
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
+ if (m_process->GetStopID() == m_dyld_image_infos_stop_id)
+ return true;
- StructuredData::ObjectSP image_infos_json_sp = m_process->GetLoadedDynamicLibrariesInfos (image_infos_addr, image_infos_count);
- if (image_infos_json_sp.get()
- && image_infos_json_sp->GetAsDictionary()
- && image_infos_json_sp->GetAsDictionary()->HasKey("images")
- && image_infos_json_sp->GetAsDictionary()->GetValueForKey("images")->GetAsArray()
- && image_infos_json_sp->GetAsDictionary()->GetValueForKey("images")->GetAsArray()->GetSize() == image_infos_count)
- {
- bool return_value = false;
- if (JSONImageInformationIntoImageInfo (image_infos_json_sp, image_infos))
- {
- UpdateSpecialBinariesFromNewImageInfos (image_infos);
- return_value = AddModulesUsingImageInfos (image_infos);
- }
- m_dyld_image_infos_stop_id = m_process->GetStopID();
- return return_value;
+ StructuredData::ObjectSP image_infos_json_sp =
+ m_process->GetLoadedDynamicLibrariesInfos(image_infos_addr,
+ image_infos_count);
+ if (image_infos_json_sp.get() && image_infos_json_sp->GetAsDictionary() &&
+ image_infos_json_sp->GetAsDictionary()->HasKey("images") &&
+ image_infos_json_sp->GetAsDictionary()
+ ->GetValueForKey("images")
+ ->GetAsArray() &&
+ image_infos_json_sp->GetAsDictionary()
+ ->GetValueForKey("images")
+ ->GetAsArray()
+ ->GetSize() == image_infos_count) {
+ bool return_value = false;
+ if (JSONImageInformationIntoImageInfo(image_infos_json_sp, image_infos)) {
+ UpdateSpecialBinariesFromNewImageInfos(image_infos);
+ return_value = AddModulesUsingImageInfos(image_infos);
}
-
- if (!ReadImageInfos (image_infos_addr, image_infos_count, image_infos))
- return false;
-
- UpdateImageInfosHeaderAndLoadCommands (image_infos, image_infos_count, false);
- bool return_value = AddModulesUsingImageInfos (image_infos);
m_dyld_image_infos_stop_id = m_process->GetStopID();
return return_value;
+ }
+
+ if (!ReadImageInfos(image_infos_addr, image_infos_count, image_infos))
+ return false;
+
+ UpdateImageInfosHeaderAndLoadCommands(image_infos, image_infos_count, false);
+ bool return_value = AddModulesUsingImageInfos(image_infos);
+ m_dyld_image_infos_stop_id = m_process->GetStopID();
+ return return_value;
}
-bool
-DynamicLoaderMacOSXDYLD::RemoveModulesUsingImageInfosAddress (lldb::addr_t image_infos_addr, uint32_t image_infos_count)
-{
- ImageInfo::collection image_infos;
- Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
-
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
- if (m_process->GetStopID() == m_dyld_image_infos_stop_id)
- return true;
+bool DynamicLoaderMacOSXDYLD::RemoveModulesUsingImageInfosAddress(
+ lldb::addr_t image_infos_addr, uint32_t image_infos_count) {
+ ImageInfo::collection image_infos;
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- // First read in the image_infos for the removed modules, and their headers & load commands.
- if (!ReadImageInfos (image_infos_addr, image_infos_count, image_infos))
- {
- if (log)
- log->PutCString ("Failed reading image infos array.");
- return false;
- }
-
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
+ if (m_process->GetStopID() == m_dyld_image_infos_stop_id)
+ return true;
+
+ // First read in the image_infos for the removed modules, and their headers &
+ // load commands.
+ if (!ReadImageInfos(image_infos_addr, image_infos_count, image_infos)) {
if (log)
- log->Printf ("Removing %d modules.", image_infos_count);
-
- ModuleList unloaded_module_list;
- for (uint32_t idx = 0; idx < image_infos.size(); ++idx)
- {
- if (log)
- {
- log->Printf ("Removing module at address=0x%16.16" PRIx64 ".", image_infos[idx].address);
- image_infos[idx].PutToLog (log);
- }
-
- // Remove this image_infos from the m_all_image_infos. We do the comparison by address
- // rather than by file spec because we can have many modules with the same "file spec" in the
- // case that they are modules loaded from memory.
- //
- // Also copy over the uuid from the old entry to the removed entry so we can
- // use it to lookup the module in the module list.
-
- ImageInfo::collection::iterator pos, end = m_dyld_image_infos.end();
- for (pos = m_dyld_image_infos.begin(); pos != end; pos++)
- {
- if (image_infos[idx].address == (*pos).address)
- {
- image_infos[idx].uuid = (*pos).uuid;
-
- // Add the module from this image_info to the "unloaded_module_list". We'll remove them all at
- // one go later on.
-
- ModuleSP unload_image_module_sp (FindTargetModuleForImageInfo (image_infos[idx], false, NULL));
- if (unload_image_module_sp.get())
- {
- // When we unload, be sure to use the image info from the old list,
- // since that has sections correctly filled in.
- UnloadModuleSections (unload_image_module_sp.get(), *pos);
- unloaded_module_list.AppendIfNeeded (unload_image_module_sp);
- }
- else
- {
- if (log)
- {
- log->Printf ("Could not find module for unloading info entry:");
- image_infos[idx].PutToLog(log);
- }
- }
-
- // Then remove it from the m_dyld_image_infos:
-
- m_dyld_image_infos.erase(pos);
- break;
- }
- }
-
- if (pos == end)
- {
- if (log)
- {
- log->Printf ("Could not find image_info entry for unloading image:");
- image_infos[idx].PutToLog(log);
- }
- }
+ log->PutCString("Failed reading image infos array.");
+ return false;
+ }
+
+ if (log)
+ log->Printf("Removing %d modules.", image_infos_count);
+
+ ModuleList unloaded_module_list;
+ for (uint32_t idx = 0; idx < image_infos.size(); ++idx) {
+ if (log) {
+ log->Printf("Removing module at address=0x%16.16" PRIx64 ".",
+ image_infos[idx].address);
+ image_infos[idx].PutToLog(log);
}
- if (unloaded_module_list.GetSize() > 0)
- {
- if (log)
- {
- log->PutCString("Unloaded:");
- unloaded_module_list.LogUUIDAndPaths (log, "DynamicLoaderMacOSXDYLD::ModulesDidUnload");
+
+ // Remove this image_infos from the m_all_image_infos. We do the comparison
+ // by address
+ // rather than by file spec because we can have many modules with the same
+ // "file spec" in the
+ // case that they are modules loaded from memory.
+ //
+ // Also copy over the uuid from the old entry to the removed entry so we can
+ // use it to lookup the module in the module list.
+
+ ImageInfo::collection::iterator pos, end = m_dyld_image_infos.end();
+ for (pos = m_dyld_image_infos.begin(); pos != end; pos++) {
+ if (image_infos[idx].address == (*pos).address) {
+ image_infos[idx].uuid = (*pos).uuid;
+
+ // Add the module from this image_info to the "unloaded_module_list".
+ // We'll remove them all at
+ // one go later on.
+
+ ModuleSP unload_image_module_sp(
+ FindTargetModuleForImageInfo(image_infos[idx], false, NULL));
+ if (unload_image_module_sp.get()) {
+ // When we unload, be sure to use the image info from the old list,
+ // since that has sections correctly filled in.
+ UnloadModuleSections(unload_image_module_sp.get(), *pos);
+ unloaded_module_list.AppendIfNeeded(unload_image_module_sp);
+ } else {
+ if (log) {
+ log->Printf("Could not find module for unloading info entry:");
+ image_infos[idx].PutToLog(log);
+ }
}
- m_process->GetTarget().GetImages().Remove (unloaded_module_list);
+
+ // Then remove it from the m_dyld_image_infos:
+
+ m_dyld_image_infos.erase(pos);
+ break;
+ }
}
- m_dyld_image_infos_stop_id = m_process->GetStopID();
- return true;
-}
-bool
-DynamicLoaderMacOSXDYLD::ReadImageInfos (lldb::addr_t image_infos_addr,
- uint32_t image_infos_count,
- ImageInfo::collection &image_infos)
-{
- std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
- const ByteOrder endian = GetByteOrderFromMagic (m_dyld.header.magic);
- const uint32_t addr_size = m_dyld.GetAddressByteSize();
-
- image_infos.resize(image_infos_count);
- const size_t count = image_infos.size() * 3 * addr_size;
- DataBufferHeap info_data(count, 0);
- Error error;
- const size_t bytes_read = m_process->ReadMemory (image_infos_addr,
- info_data.GetBytes(),
- info_data.GetByteSize(),
- error);
- if (bytes_read == count)
- {
- lldb::offset_t info_data_offset = 0;
- DataExtractor info_data_ref(info_data.GetBytes(), info_data.GetByteSize(), endian, addr_size);
- for (size_t i = 0; i < image_infos.size() && info_data_ref.ValidOffset(info_data_offset); i++)
- {
- image_infos[i].address = info_data_ref.GetPointer(&info_data_offset);
- lldb::addr_t path_addr = info_data_ref.GetPointer(&info_data_offset);
- image_infos[i].mod_date = info_data_ref.GetPointer(&info_data_offset);
-
- char raw_path[PATH_MAX];
- m_process->ReadCStringFromMemory (path_addr, raw_path, sizeof(raw_path), error);
- // don't resolve the path
- if (error.Success())
- {
- const bool resolve_path = false;
- image_infos[i].file_spec.SetFile(raw_path, resolve_path);
- }
- }
- return true;
+ if (pos == end) {
+ if (log) {
+ log->Printf("Could not find image_info entry for unloading image:");
+ image_infos[idx].PutToLog(log);
+ }
}
- else
- {
- return false;
+ }
+ if (unloaded_module_list.GetSize() > 0) {
+ if (log) {
+ log->PutCString("Unloaded:");
+ unloaded_module_list.LogUUIDAndPaths(
+ log, "DynamicLoaderMacOSXDYLD::ModulesDidUnload");
}
+ m_process->GetTarget().GetImages().Remove(unloaded_module_list);
+ }
+ m_dyld_image_infos_stop_id = m_process->GetStopID();
+ return true;
+}
+
+bool DynamicLoaderMacOSXDYLD::ReadImageInfos(
+ lldb::addr_t image_infos_addr, uint32_t image_infos_count,
+ ImageInfo::collection &image_infos) {
+ std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
+ const ByteOrder endian = GetByteOrderFromMagic(m_dyld.header.magic);
+ const uint32_t addr_size = m_dyld.GetAddressByteSize();
+
+ image_infos.resize(image_infos_count);
+ const size_t count = image_infos.size() * 3 * addr_size;
+ DataBufferHeap info_data(count, 0);
+ Error error;
+ const size_t bytes_read = m_process->ReadMemory(
+ image_infos_addr, info_data.GetBytes(), info_data.GetByteSize(), error);
+ if (bytes_read == count) {
+ lldb::offset_t info_data_offset = 0;
+ DataExtractor info_data_ref(info_data.GetBytes(), info_data.GetByteSize(),
+ endian, addr_size);
+ for (size_t i = 0;
+ i < image_infos.size() && info_data_ref.ValidOffset(info_data_offset);
+ i++) {
+ image_infos[i].address = info_data_ref.GetPointer(&info_data_offset);
+ lldb::addr_t path_addr = info_data_ref.GetPointer(&info_data_offset);
+ image_infos[i].mod_date = info_data_ref.GetPointer(&info_data_offset);
+
+ char raw_path[PATH_MAX];
+ m_process->ReadCStringFromMemory(path_addr, raw_path, sizeof(raw_path),
+ error);
+ // don't resolve the path
+ if (error.Success()) {
+ const bool resolve_path = false;
+ image_infos[i].file_spec.SetFile(raw_path, resolve_path);
+ }
+ }
+ return true;
+ } else {
+ return false;
+ }
}
//----------------------------------------------------------------------
@@ -759,74 +720,68 @@ DynamicLoaderMacOSXDYLD::ReadImageInfos (lldb::addr_t image_infos_addr,
// we're reading the dyld infos. Return true if we actually read anything,
// and false otherwise.
//----------------------------------------------------------------------
-bool
-DynamicLoaderMacOSXDYLD::InitializeFromAllImageInfos ()
-{
- Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
-
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
- if (m_process->GetStopID() == m_dyld_image_infos_stop_id
- || m_dyld_image_infos.size() != 0)
- return false;
-
- if (ReadAllImageInfosStructure ())
- {
- // Nothing to load or unload?
- if (m_dyld_all_image_infos.dylib_info_count == 0)
- return true;
-
- if (m_dyld_all_image_infos.dylib_info_addr == 0)
- {
- // DYLD is updating the images now. So we should say we have no images, and then we'll
- // figure it out when we hit the added breakpoint.
- return false;
- }
- else
- {
- if (!AddModulesUsingImageInfosAddress (m_dyld_all_image_infos.dylib_info_addr,
- m_dyld_all_image_infos.dylib_info_count))
- {
- DEBUG_PRINTF("%s", "unable to read all data for all_dylib_infos.");
- m_dyld_image_infos.clear();
- }
- }
+bool DynamicLoaderMacOSXDYLD::InitializeFromAllImageInfos() {
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- // Now we have one more bit of business. If there is a library left in the images for our target that
- // doesn't have a load address, then it must be something that we were expecting to load (for instance we
- // read a load command for it) but it didn't in fact load - probably because DYLD_*_PATH pointed
- // to an equivalent version. We don't want it to stay in the target's module list or it will confuse
- // us, so unload it here.
- Target &target = m_process->GetTarget();
- const ModuleList &target_modules = target.GetImages();
- ModuleList not_loaded_modules;
- std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
-
- size_t num_modules = target_modules.GetSize();
- for (size_t i = 0; i < num_modules; i++)
- {
- ModuleSP module_sp = target_modules.GetModuleAtIndexUnlocked (i);
- if (!module_sp->IsLoadedInTarget (&target))
- {
- if (log)
- {
- StreamString s;
- module_sp->GetDescription (&s);
- log->Printf ("Unloading pre-run module: %s.", s.GetData ());
- }
- not_loaded_modules.Append (module_sp);
- }
- }
-
- if (not_loaded_modules.GetSize() != 0)
- {
- target.GetImages().Remove(not_loaded_modules);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
+ if (m_process->GetStopID() == m_dyld_image_infos_stop_id ||
+ m_dyld_image_infos.size() != 0)
+ return false;
+
+ if (ReadAllImageInfosStructure()) {
+ // Nothing to load or unload?
+ if (m_dyld_all_image_infos.dylib_info_count == 0)
+ return true;
+
+ if (m_dyld_all_image_infos.dylib_info_addr == 0) {
+ // DYLD is updating the images now. So we should say we have no images,
+ // and then we'll
+ // figure it out when we hit the added breakpoint.
+ return false;
+ } else {
+ if (!AddModulesUsingImageInfosAddress(
+ m_dyld_all_image_infos.dylib_info_addr,
+ m_dyld_all_image_infos.dylib_info_count)) {
+ DEBUG_PRINTF("%s", "unable to read all data for all_dylib_infos.");
+ m_dyld_image_infos.clear();
+ }
+ }
+
+ // Now we have one more bit of business. If there is a library left in the
+ // images for our target that
+ // doesn't have a load address, then it must be something that we were
+ // expecting to load (for instance we
+ // read a load command for it) but it didn't in fact load - probably because
+ // DYLD_*_PATH pointed
+ // to an equivalent version. We don't want it to stay in the target's
+ // module list or it will confuse
+ // us, so unload it here.
+ Target &target = m_process->GetTarget();
+ const ModuleList &target_modules = target.GetImages();
+ ModuleList not_loaded_modules;
+ std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
+
+ size_t num_modules = target_modules.GetSize();
+ for (size_t i = 0; i < num_modules; i++) {
+ ModuleSP module_sp = target_modules.GetModuleAtIndexUnlocked(i);
+ if (!module_sp->IsLoadedInTarget(&target)) {
+ if (log) {
+ StreamString s;
+ module_sp->GetDescription(&s);
+ log->Printf("Unloading pre-run module: %s.", s.GetData());
}
+ not_loaded_modules.Append(module_sp);
+ }
+ }
- return true;
+ if (not_loaded_modules.GetSize() != 0) {
+ target.GetImages().Remove(not_loaded_modules);
}
- else
- return false;
+
+ return true;
+ } else
+ return false;
}
//----------------------------------------------------------------------
@@ -835,166 +790,161 @@ DynamicLoaderMacOSXDYLD::InitializeFromAllImageInfos ()
//
// Returns true if we succeed, false if we fail for any reason.
//----------------------------------------------------------------------
-bool
-DynamicLoaderMacOSXDYLD::ReadMachHeader (lldb::addr_t addr, llvm::MachO::mach_header *header, DataExtractor *load_command_data)
-{
- DataBufferHeap header_bytes(sizeof(llvm::MachO::mach_header), 0);
- Error error;
- size_t bytes_read = m_process->ReadMemory (addr,
- header_bytes.GetBytes(),
- header_bytes.GetByteSize(),
- error);
- if (bytes_read == sizeof(llvm::MachO::mach_header))
- {
- lldb::offset_t offset = 0;
- ::memset (header, 0, sizeof(llvm::MachO::mach_header));
-
- // Get the magic byte unswapped so we can figure out what we are dealing with
- DataExtractor data(header_bytes.GetBytes(), header_bytes.GetByteSize(), endian::InlHostByteOrder(), 4);
- header->magic = data.GetU32(&offset);
- lldb::addr_t load_cmd_addr = addr;
- data.SetByteOrder(DynamicLoaderMacOSXDYLD::GetByteOrderFromMagic(header->magic));
- switch (header->magic)
- {
- case llvm::MachO::MH_MAGIC:
- case llvm::MachO::MH_CIGAM:
- data.SetAddressByteSize(4);
- load_cmd_addr += sizeof(llvm::MachO::mach_header);
- break;
-
- case llvm::MachO::MH_MAGIC_64:
- case llvm::MachO::MH_CIGAM_64:
- data.SetAddressByteSize(8);
- load_cmd_addr += sizeof(llvm::MachO::mach_header_64);
- break;
-
- default:
- return false;
- }
-
- // Read the rest of dyld's mach header
- if (data.GetU32(&offset, &header->cputype, (sizeof(llvm::MachO::mach_header)/sizeof(uint32_t)) - 1))
- {
- if (load_command_data == NULL)
- return true; // We were able to read the mach_header and weren't asked to read the load command bytes
-
- DataBufferSP load_cmd_data_sp(new DataBufferHeap(header->sizeofcmds, 0));
-
- size_t load_cmd_bytes_read = m_process->ReadMemory (load_cmd_addr,
- load_cmd_data_sp->GetBytes(),
- load_cmd_data_sp->GetByteSize(),
- error);
-
- if (load_cmd_bytes_read == header->sizeofcmds)
- {
- // Set the load command data and also set the correct endian
- // swap settings and the correct address size
- load_command_data->SetData(load_cmd_data_sp, 0, header->sizeofcmds);
- load_command_data->SetByteOrder(data.GetByteOrder());
- load_command_data->SetAddressByteSize(data.GetAddressByteSize());
- return true; // We successfully read the mach_header and the load command data
- }
+bool DynamicLoaderMacOSXDYLD::ReadMachHeader(lldb::addr_t addr,
+ llvm::MachO::mach_header *header,
+ DataExtractor *load_command_data) {
+ DataBufferHeap header_bytes(sizeof(llvm::MachO::mach_header), 0);
+ Error error;
+ size_t bytes_read = m_process->ReadMemory(addr, header_bytes.GetBytes(),
+ header_bytes.GetByteSize(), error);
+ if (bytes_read == sizeof(llvm::MachO::mach_header)) {
+ lldb::offset_t offset = 0;
+ ::memset(header, 0, sizeof(llvm::MachO::mach_header));
+
+ // Get the magic byte unswapped so we can figure out what we are dealing
+ // with
+ DataExtractor data(header_bytes.GetBytes(), header_bytes.GetByteSize(),
+ endian::InlHostByteOrder(), 4);
+ header->magic = data.GetU32(&offset);
+ lldb::addr_t load_cmd_addr = addr;
+ data.SetByteOrder(
+ DynamicLoaderMacOSXDYLD::GetByteOrderFromMagic(header->magic));
+ switch (header->magic) {
+ case llvm::MachO::MH_MAGIC:
+ case llvm::MachO::MH_CIGAM:
+ data.SetAddressByteSize(4);
+ load_cmd_addr += sizeof(llvm::MachO::mach_header);
+ break;
+
+ case llvm::MachO::MH_MAGIC_64:
+ case llvm::MachO::MH_CIGAM_64:
+ data.SetAddressByteSize(8);
+ load_cmd_addr += sizeof(llvm::MachO::mach_header_64);
+ break;
+
+ default:
+ return false;
+ }
- return false; // We weren't able to read the load command data
- }
+ // Read the rest of dyld's mach header
+ if (data.GetU32(&offset, &header->cputype,
+ (sizeof(llvm::MachO::mach_header) / sizeof(uint32_t)) -
+ 1)) {
+ if (load_command_data == NULL)
+ return true; // We were able to read the mach_header and weren't asked
+ // to read the load command bytes
+
+ DataBufferSP load_cmd_data_sp(new DataBufferHeap(header->sizeofcmds, 0));
+
+ size_t load_cmd_bytes_read =
+ m_process->ReadMemory(load_cmd_addr, load_cmd_data_sp->GetBytes(),
+ load_cmd_data_sp->GetByteSize(), error);
+
+ if (load_cmd_bytes_read == header->sizeofcmds) {
+ // Set the load command data and also set the correct endian
+ // swap settings and the correct address size
+ load_command_data->SetData(load_cmd_data_sp, 0, header->sizeofcmds);
+ load_command_data->SetByteOrder(data.GetByteOrder());
+ load_command_data->SetAddressByteSize(data.GetAddressByteSize());
+ return true; // We successfully read the mach_header and the load
+ // command data
+ }
+
+ return false; // We weren't able to read the load command data
}
- return false; // We failed the read the mach_header
+ }
+ return false; // We failed the read the mach_header
}
-
//----------------------------------------------------------------------
// Parse the load commands for an image
//----------------------------------------------------------------------
-uint32_t
-DynamicLoaderMacOSXDYLD::ParseLoadCommands (const DataExtractor& data, ImageInfo& dylib_info, FileSpec *lc_id_dylinker)
-{
- lldb::offset_t offset = 0;
- uint32_t cmd_idx;
- Segment segment;
- dylib_info.Clear (true);
-
- for (cmd_idx = 0; cmd_idx < dylib_info.header.ncmds; cmd_idx++)
- {
- // Clear out any load command specific data from DYLIB_INFO since
- // we are about to read it.
-
- if (data.ValidOffsetForDataOfSize (offset, sizeof(llvm::MachO::load_command)))
- {
- llvm::MachO::load_command load_cmd;
- lldb::offset_t load_cmd_offset = offset;
- load_cmd.cmd = data.GetU32 (&offset);
- load_cmd.cmdsize = data.GetU32 (&offset);
- switch (load_cmd.cmd)
- {
- case llvm::MachO::LC_SEGMENT:
- {
- segment.name.SetTrimmedCStringWithLength ((const char *)data.GetData(&offset, 16), 16);
- // We are putting 4 uint32_t values 4 uint64_t values so
- // we have to use multiple 32 bit gets below.
- segment.vmaddr = data.GetU32 (&offset);
- segment.vmsize = data.GetU32 (&offset);
- segment.fileoff = data.GetU32 (&offset);
- segment.filesize = data.GetU32 (&offset);
- // Extract maxprot, initprot, nsects and flags all at once
- data.GetU32(&offset, &segment.maxprot, 4);
- dylib_info.segments.push_back (segment);
- }
- break;
-
- case llvm::MachO::LC_SEGMENT_64:
- {
- segment.name.SetTrimmedCStringWithLength ((const char *)data.GetData(&offset, 16), 16);
- // Extract vmaddr, vmsize, fileoff, and filesize all at once
- data.GetU64(&offset, &segment.vmaddr, 4);
- // Extract maxprot, initprot, nsects and flags all at once
- data.GetU32(&offset, &segment.maxprot, 4);
- dylib_info.segments.push_back (segment);
- }
- break;
-
- case llvm::MachO::LC_ID_DYLINKER:
- if (lc_id_dylinker)
- {
- const lldb::offset_t name_offset = load_cmd_offset + data.GetU32 (&offset);
- const char *path = data.PeekCStr (name_offset);
- lc_id_dylinker->SetFile (path, true);
- }
- break;
-
- case llvm::MachO::LC_UUID:
- dylib_info.uuid.SetBytes(data.GetData (&offset, 16));
- break;
-
- default:
- break;
- }
- // Set offset to be the beginning of the next load command.
- offset = load_cmd_offset + load_cmd.cmdsize;
+uint32_t DynamicLoaderMacOSXDYLD::ParseLoadCommands(const DataExtractor &data,
+ ImageInfo &dylib_info,
+ FileSpec *lc_id_dylinker) {
+ lldb::offset_t offset = 0;
+ uint32_t cmd_idx;
+ Segment segment;
+ dylib_info.Clear(true);
+
+ for (cmd_idx = 0; cmd_idx < dylib_info.header.ncmds; cmd_idx++) {
+ // Clear out any load command specific data from DYLIB_INFO since
+ // we are about to read it.
+
+ if (data.ValidOffsetForDataOfSize(offset,
+ sizeof(llvm::MachO::load_command))) {
+ llvm::MachO::load_command load_cmd;
+ lldb::offset_t load_cmd_offset = offset;
+ load_cmd.cmd = data.GetU32(&offset);
+ load_cmd.cmdsize = data.GetU32(&offset);
+ switch (load_cmd.cmd) {
+ case llvm::MachO::LC_SEGMENT: {
+ segment.name.SetTrimmedCStringWithLength(
+ (const char *)data.GetData(&offset, 16), 16);
+ // We are putting 4 uint32_t values 4 uint64_t values so
+ // we have to use multiple 32 bit gets below.
+ segment.vmaddr = data.GetU32(&offset);
+ segment.vmsize = data.GetU32(&offset);
+ segment.fileoff = data.GetU32(&offset);
+ segment.filesize = data.GetU32(&offset);
+ // Extract maxprot, initprot, nsects and flags all at once
+ data.GetU32(&offset, &segment.maxprot, 4);
+ dylib_info.segments.push_back(segment);
+ } break;
+
+ case llvm::MachO::LC_SEGMENT_64: {
+ segment.name.SetTrimmedCStringWithLength(
+ (const char *)data.GetData(&offset, 16), 16);
+ // Extract vmaddr, vmsize, fileoff, and filesize all at once
+ data.GetU64(&offset, &segment.vmaddr, 4);
+ // Extract maxprot, initprot, nsects and flags all at once
+ data.GetU32(&offset, &segment.maxprot, 4);
+ dylib_info.segments.push_back(segment);
+ } break;
+
+ case llvm::MachO::LC_ID_DYLINKER:
+ if (lc_id_dylinker) {
+ const lldb::offset_t name_offset =
+ load_cmd_offset + data.GetU32(&offset);
+ const char *path = data.PeekCStr(name_offset);
+ lc_id_dylinker->SetFile(path, true);
}
+ break;
+
+ case llvm::MachO::LC_UUID:
+ dylib_info.uuid.SetBytes(data.GetData(&offset, 16));
+ break;
+
+ default:
+ break;
+ }
+ // Set offset to be the beginning of the next load command.
+ offset = load_cmd_offset + load_cmd.cmdsize;
}
-
- // All sections listed in the dyld image info structure will all
- // either be fixed up already, or they will all be off by a single
- // slide amount that is determined by finding the first segment
- // that is at file offset zero which also has bytes (a file size
- // that is greater than zero) in the object file.
-
- // Determine the slide amount (if any)
- const size_t num_sections = dylib_info.segments.size();
- for (size_t i = 0; i < num_sections; ++i)
- {
- // Iterate through the object file sections to find the
- // first section that starts of file offset zero and that
- // has bytes in the file...
- if ((dylib_info.segments[i].fileoff == 0 && dylib_info.segments[i].filesize > 0) || (dylib_info.segments[i].name == ConstString("__TEXT")))
- {
- dylib_info.slide = dylib_info.address - dylib_info.segments[i].vmaddr;
- // We have found the slide amount, so we can exit
- // this for loop.
- break;
- }
+ }
+
+ // All sections listed in the dyld image info structure will all
+ // either be fixed up already, or they will all be off by a single
+ // slide amount that is determined by finding the first segment
+ // that is at file offset zero which also has bytes (a file size
+ // that is greater than zero) in the object file.
+
+ // Determine the slide amount (if any)
+ const size_t num_sections = dylib_info.segments.size();
+ for (size_t i = 0; i < num_sections; ++i) {
+ // Iterate through the object file sections to find the
+ // first section that starts of file offset zero and that
+ // has bytes in the file...
+ if ((dylib_info.segments[i].fileoff == 0 &&
+ dylib_info.segments[i].filesize > 0) ||
+ (dylib_info.segments[i].name == ConstString("__TEXT"))) {
+ dylib_info.slide = dylib_info.address - dylib_info.segments[i].vmaddr;
+ // We have found the slide amount, so we can exit
+ // this for loop.
+ break;
}
- return cmd_idx;
+ }
+ return cmd_idx;
}
//----------------------------------------------------------------------
@@ -1002,313 +952,278 @@ DynamicLoaderMacOSXDYLD::ParseLoadCommands (const DataExtractor& data, ImageInfo
// _dyld_all_image_infos structure points to and cache the results.
//----------------------------------------------------------------------
-void
-DynamicLoaderMacOSXDYLD::UpdateImageInfosHeaderAndLoadCommands(ImageInfo::collection &image_infos,
- uint32_t infos_count,
- bool update_executable)
-{
- uint32_t exe_idx = UINT32_MAX;
- // Read any UUID values that we can get
- for (uint32_t i = 0; i < infos_count; i++)
- {
- if (!image_infos[i].UUIDValid())
- {
- DataExtractor data; // Load command data
- if (!ReadMachHeader (image_infos[i].address, &image_infos[i].header, &data))
- continue;
-
- ParseLoadCommands (data, image_infos[i], NULL);
-
- if (image_infos[i].header.filetype == llvm::MachO::MH_EXECUTE)
- exe_idx = i;
-
- }
+void DynamicLoaderMacOSXDYLD::UpdateImageInfosHeaderAndLoadCommands(
+ ImageInfo::collection &image_infos, uint32_t infos_count,
+ bool update_executable) {
+ uint32_t exe_idx = UINT32_MAX;
+ // Read any UUID values that we can get
+ for (uint32_t i = 0; i < infos_count; i++) {
+ if (!image_infos[i].UUIDValid()) {
+ DataExtractor data; // Load command data
+ if (!ReadMachHeader(image_infos[i].address, &image_infos[i].header,
+ &data))
+ continue;
+
+ ParseLoadCommands(data, image_infos[i], NULL);
+
+ if (image_infos[i].header.filetype == llvm::MachO::MH_EXECUTE)
+ exe_idx = i;
}
-
- Target &target = m_process->GetTarget();
-
- if (exe_idx < image_infos.size())
- {
- const bool can_create = true;
- ModuleSP exe_module_sp (FindTargetModuleForImageInfo (image_infos[exe_idx], can_create, NULL));
-
- if (exe_module_sp)
- {
- UpdateImageLoadAddress (exe_module_sp.get(), image_infos[exe_idx]);
-
- if (exe_module_sp.get() != target.GetExecutableModulePointer())
- {
- // Don't load dependent images since we are in dyld where we will know
- // and find out about all images that are loaded. Also when setting the
- // executable module, it will clear the targets module list, and if we
- // have an in memory dyld module, it will get removed from the list
- // so we will need to add it back after setting the executable module,
- // so we first try and see if we already have a weak pointer to the
- // dyld module, make it into a shared pointer, then add the executable,
- // then re-add it back to make sure it is always in the list.
- ModuleSP dyld_module_sp(GetDYLDModule ());
-
- const bool get_dependent_images = false;
- m_process->GetTarget().SetExecutableModule (exe_module_sp,
- get_dependent_images);
-
- if (dyld_module_sp)
- {
- if(target.GetImages().AppendIfNeeded (dyld_module_sp))
- {
- std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
-
- // Also add it to the section list.
- UpdateImageLoadAddress(dyld_module_sp.get(), m_dyld);
- }
- }
- }
+ }
+
+ Target &target = m_process->GetTarget();
+
+ if (exe_idx < image_infos.size()) {
+ const bool can_create = true;
+ ModuleSP exe_module_sp(
+ FindTargetModuleForImageInfo(image_infos[exe_idx], can_create, NULL));
+
+ if (exe_module_sp) {
+ UpdateImageLoadAddress(exe_module_sp.get(), image_infos[exe_idx]);
+
+ if (exe_module_sp.get() != target.GetExecutableModulePointer()) {
+ // Don't load dependent images since we are in dyld where we will know
+ // and find out about all images that are loaded. Also when setting the
+ // executable module, it will clear the targets module list, and if we
+ // have an in memory dyld module, it will get removed from the list
+ // so we will need to add it back after setting the executable module,
+ // so we first try and see if we already have a weak pointer to the
+ // dyld module, make it into a shared pointer, then add the executable,
+ // then re-add it back to make sure it is always in the list.
+ ModuleSP dyld_module_sp(GetDYLDModule());
+
+ const bool get_dependent_images = false;
+ m_process->GetTarget().SetExecutableModule(exe_module_sp,
+ get_dependent_images);
+
+ if (dyld_module_sp) {
+ if (target.GetImages().AppendIfNeeded(dyld_module_sp)) {
+ std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
+
+ // Also add it to the section list.
+ UpdateImageLoadAddress(dyld_module_sp.get(), m_dyld);
+ }
}
+ }
}
+ }
}
-
//----------------------------------------------------------------------
// Dump the _dyld_all_image_infos members and all current image infos
// that we have parsed to the file handle provided.
//----------------------------------------------------------------------
-void
-DynamicLoaderMacOSXDYLD::PutToLog(Log *log) const
-{
- if (log == NULL)
- return;
-
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
- log->Printf("dyld_all_image_infos = { version=%d, count=%d, addr=0x%8.8" PRIx64 ", notify=0x%8.8" PRIx64 " }",
- m_dyld_all_image_infos.version,
- m_dyld_all_image_infos.dylib_info_count,
- (uint64_t)m_dyld_all_image_infos.dylib_info_addr,
- (uint64_t)m_dyld_all_image_infos.notification);
- size_t i;
- const size_t count = m_dyld_image_infos.size();
- if (count > 0)
- {
- log->PutCString("Loaded:");
- for (i = 0; i<count; i++)
- m_dyld_image_infos[i].PutToLog(log);
- }
-}
+void DynamicLoaderMacOSXDYLD::PutToLog(Log *log) const {
+ if (log == NULL)
+ return;
-bool
-DynamicLoaderMacOSXDYLD::SetNotificationBreakpoint ()
-{
- DEBUG_PRINTF("DynamicLoaderMacOSXDYLD::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState()));
- if (m_break_id == LLDB_INVALID_BREAK_ID)
- {
- if (m_dyld_all_image_infos.notification != LLDB_INVALID_ADDRESS)
- {
- Address so_addr;
- // Set the notification breakpoint and install a breakpoint
- // callback function that will get called each time the
- // breakpoint gets hit. We will use this to track when shared
- // libraries get loaded/unloaded.
- bool resolved = m_process->GetTarget().ResolveLoadAddress(m_dyld_all_image_infos.notification, so_addr);
- if (!resolved)
- {
- ModuleSP dyld_module_sp = GetDYLDModule();
- if (dyld_module_sp)
- {
- std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
-
- UpdateImageLoadAddress (dyld_module_sp.get(), m_dyld);
- resolved = m_process->GetTarget().ResolveLoadAddress(m_dyld_all_image_infos.notification, so_addr);
- }
- }
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
+ log->Printf(
+ "dyld_all_image_infos = { version=%d, count=%d, addr=0x%8.8" PRIx64
+ ", notify=0x%8.8" PRIx64 " }",
+ m_dyld_all_image_infos.version, m_dyld_all_image_infos.dylib_info_count,
+ (uint64_t)m_dyld_all_image_infos.dylib_info_addr,
+ (uint64_t)m_dyld_all_image_infos.notification);
+ size_t i;
+ const size_t count = m_dyld_image_infos.size();
+ if (count > 0) {
+ log->PutCString("Loaded:");
+ for (i = 0; i < count; i++)
+ m_dyld_image_infos[i].PutToLog(log);
+ }
+}
- if (resolved)
- {
- Breakpoint *dyld_break = m_process->GetTarget().CreateBreakpoint (so_addr, true, false).get();
- dyld_break->SetCallback (DynamicLoaderMacOSXDYLD::NotifyBreakpointHit, this, true);
- dyld_break->SetBreakpointKind ("shared-library-event");
- m_break_id = dyld_break->GetID();
- }
+bool DynamicLoaderMacOSXDYLD::SetNotificationBreakpoint() {
+ DEBUG_PRINTF("DynamicLoaderMacOSXDYLD::%s() process state = %s\n",
+ __FUNCTION__, StateAsCString(m_process->GetState()));
+ if (m_break_id == LLDB_INVALID_BREAK_ID) {
+ if (m_dyld_all_image_infos.notification != LLDB_INVALID_ADDRESS) {
+ Address so_addr;
+ // Set the notification breakpoint and install a breakpoint
+ // callback function that will get called each time the
+ // breakpoint gets hit. We will use this to track when shared
+ // libraries get loaded/unloaded.
+ bool resolved = m_process->GetTarget().ResolveLoadAddress(
+ m_dyld_all_image_infos.notification, so_addr);
+ if (!resolved) {
+ ModuleSP dyld_module_sp = GetDYLDModule();
+ if (dyld_module_sp) {
+ std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
+
+ UpdateImageLoadAddress(dyld_module_sp.get(), m_dyld);
+ resolved = m_process->GetTarget().ResolveLoadAddress(
+ m_dyld_all_image_infos.notification, so_addr);
}
+ }
+
+ if (resolved) {
+ Breakpoint *dyld_break =
+ m_process->GetTarget().CreateBreakpoint(so_addr, true, false).get();
+ dyld_break->SetCallback(DynamicLoaderMacOSXDYLD::NotifyBreakpointHit,
+ this, true);
+ dyld_break->SetBreakpointKind("shared-library-event");
+ m_break_id = dyld_break->GetID();
+ }
}
- return m_break_id != LLDB_INVALID_BREAK_ID;
+ }
+ return m_break_id != LLDB_INVALID_BREAK_ID;
}
-Error
-DynamicLoaderMacOSXDYLD::CanLoadImage ()
-{
- Error error;
- // In order for us to tell if we can load a shared library we verify that
- // the dylib_info_addr isn't zero (which means no shared libraries have
- // been set yet, or dyld is currently mucking with the shared library list).
- if (ReadAllImageInfosStructure ())
- {
- // TODO: also check the _dyld_global_lock_held variable in libSystem.B.dylib?
- // TODO: check the malloc lock?
- // TODO: check the objective C lock?
- if (m_dyld_all_image_infos.dylib_info_addr != 0)
- return error; // Success
- }
-
- error.SetErrorString("unsafe to load or unload shared libraries");
- return error;
+Error DynamicLoaderMacOSXDYLD::CanLoadImage() {
+ Error error;
+ // In order for us to tell if we can load a shared library we verify that
+ // the dylib_info_addr isn't zero (which means no shared libraries have
+ // been set yet, or dyld is currently mucking with the shared library list).
+ if (ReadAllImageInfosStructure()) {
+ // TODO: also check the _dyld_global_lock_held variable in
+ // libSystem.B.dylib?
+ // TODO: check the malloc lock?
+ // TODO: check the objective C lock?
+ if (m_dyld_all_image_infos.dylib_info_addr != 0)
+ return error; // Success
+ }
+
+ error.SetErrorString("unsafe to load or unload shared libraries");
+ return error;
}
-bool
-DynamicLoaderMacOSXDYLD::GetSharedCacheInformation (lldb::addr_t &base_address,
- UUID &uuid,
- LazyBool &using_shared_cache,
- LazyBool &private_shared_cache)
-{
- base_address = LLDB_INVALID_ADDRESS;
- uuid.Clear();
- using_shared_cache = eLazyBoolCalculate;
- private_shared_cache = eLazyBoolCalculate;
-
- if (m_process)
- {
- addr_t all_image_infos = m_process->GetImageInfoAddress();
-
- // The address returned by GetImageInfoAddress may be the address of dyld (don't want)
- // or it may be the address of the dyld_all_image_infos structure (want). The first four
- // bytes will be either the version field (all_image_infos) or a Mach-O file magic constant.
- // Version 13 and higher of dyld_all_image_infos is required to get the sharedCacheUUID field.
-
- Error err;
- uint32_t version_or_magic = m_process->ReadUnsignedIntegerFromMemory (all_image_infos, 4, -1, err);
- if (version_or_magic != static_cast<uint32_t>(-1)
- && version_or_magic != llvm::MachO::MH_MAGIC
- && version_or_magic != llvm::MachO::MH_CIGAM
- && version_or_magic != llvm::MachO::MH_MAGIC_64
- && version_or_magic != llvm::MachO::MH_CIGAM_64
- && version_or_magic >= 13)
- {
- addr_t sharedCacheUUID_address = LLDB_INVALID_ADDRESS;
- int wordsize = m_process->GetAddressByteSize();
- if (wordsize == 8)
- {
- sharedCacheUUID_address = all_image_infos + 160; // sharedCacheUUID <mach-o/dyld_images.h>
- }
- if (wordsize == 4)
- {
- sharedCacheUUID_address = all_image_infos + 84; // sharedCacheUUID <mach-o/dyld_images.h>
- }
- if (sharedCacheUUID_address != LLDB_INVALID_ADDRESS)
- {
- uuid_t shared_cache_uuid;
- if (m_process->ReadMemory (sharedCacheUUID_address, shared_cache_uuid, sizeof (uuid_t), err) == sizeof (uuid_t))
- {
- uuid.SetBytes (shared_cache_uuid);
- if (uuid.IsValid ())
- {
- using_shared_cache = eLazyBoolYes;
- }
- }
-
- if (version_or_magic >= 15)
- {
- // The sharedCacheBaseAddress field is the next one in the dyld_all_image_infos struct.
- addr_t sharedCacheBaseAddr_address = sharedCacheUUID_address + 16;
- Error error;
- base_address = m_process->ReadUnsignedIntegerFromMemory (sharedCacheBaseAddr_address, wordsize, LLDB_INVALID_ADDRESS, error);
- if (error.Fail())
- base_address = LLDB_INVALID_ADDRESS;
- }
-
- return true;
- }
+bool DynamicLoaderMacOSXDYLD::GetSharedCacheInformation(
+ lldb::addr_t &base_address, UUID &uuid, LazyBool &using_shared_cache,
+ LazyBool &private_shared_cache) {
+ base_address = LLDB_INVALID_ADDRESS;
+ uuid.Clear();
+ using_shared_cache = eLazyBoolCalculate;
+ private_shared_cache = eLazyBoolCalculate;
+
+ if (m_process) {
+ addr_t all_image_infos = m_process->GetImageInfoAddress();
+
+ // The address returned by GetImageInfoAddress may be the address of dyld
+ // (don't want)
+ // or it may be the address of the dyld_all_image_infos structure (want).
+ // The first four
+ // bytes will be either the version field (all_image_infos) or a Mach-O file
+ // magic constant.
+ // Version 13 and higher of dyld_all_image_infos is required to get the
+ // sharedCacheUUID field.
+
+ Error err;
+ uint32_t version_or_magic =
+ m_process->ReadUnsignedIntegerFromMemory(all_image_infos, 4, -1, err);
+ if (version_or_magic != static_cast<uint32_t>(-1) &&
+ version_or_magic != llvm::MachO::MH_MAGIC &&
+ version_or_magic != llvm::MachO::MH_CIGAM &&
+ version_or_magic != llvm::MachO::MH_MAGIC_64 &&
+ version_or_magic != llvm::MachO::MH_CIGAM_64 &&
+ version_or_magic >= 13) {
+ addr_t sharedCacheUUID_address = LLDB_INVALID_ADDRESS;
+ int wordsize = m_process->GetAddressByteSize();
+ if (wordsize == 8) {
+ sharedCacheUUID_address =
+ all_image_infos + 160; // sharedCacheUUID <mach-o/dyld_images.h>
+ }
+ if (wordsize == 4) {
+ sharedCacheUUID_address =
+ all_image_infos + 84; // sharedCacheUUID <mach-o/dyld_images.h>
+ }
+ if (sharedCacheUUID_address != LLDB_INVALID_ADDRESS) {
+ uuid_t shared_cache_uuid;
+ if (m_process->ReadMemory(sharedCacheUUID_address, shared_cache_uuid,
+ sizeof(uuid_t), err) == sizeof(uuid_t)) {
+ uuid.SetBytes(shared_cache_uuid);
+ if (uuid.IsValid()) {
+ using_shared_cache = eLazyBoolYes;
+ }
+ }
- //
- // add
- // NB: sharedCacheBaseAddress is the next field in dyld_all_image_infos after
- // sharedCacheUUID -- that is, 16 bytes after it, if we wanted to fetch it.
+ if (version_or_magic >= 15) {
+ // The sharedCacheBaseAddress field is the next one in the
+ // dyld_all_image_infos struct.
+ addr_t sharedCacheBaseAddr_address = sharedCacheUUID_address + 16;
+ Error error;
+ base_address = m_process->ReadUnsignedIntegerFromMemory(
+ sharedCacheBaseAddr_address, wordsize, LLDB_INVALID_ADDRESS,
+ error);
+ if (error.Fail())
+ base_address = LLDB_INVALID_ADDRESS;
}
+
+ return true;
+ }
+
+ //
+ // add
+ // NB: sharedCacheBaseAddress is the next field in dyld_all_image_infos
+ // after
+ // sharedCacheUUID -- that is, 16 bytes after it, if we wanted to fetch
+ // it.
}
- return false;
+ }
+ return false;
}
-void
-DynamicLoaderMacOSXDYLD::Initialize()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- GetPluginDescriptionStatic(),
- CreateInstance);
+void DynamicLoaderMacOSXDYLD::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance);
}
-void
-DynamicLoaderMacOSXDYLD::Terminate()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
+void DynamicLoaderMacOSXDYLD::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
}
-
-lldb_private::ConstString
-DynamicLoaderMacOSXDYLD::GetPluginNameStatic()
-{
- static ConstString g_name("macosx-dyld");
- return g_name;
+lldb_private::ConstString DynamicLoaderMacOSXDYLD::GetPluginNameStatic() {
+ static ConstString g_name("macosx-dyld");
+ return g_name;
}
-const char *
-DynamicLoaderMacOSXDYLD::GetPluginDescriptionStatic()
-{
- return "Dynamic loader plug-in that watches for shared library loads/unloads in MacOSX user processes.";
+const char *DynamicLoaderMacOSXDYLD::GetPluginDescriptionStatic() {
+ return "Dynamic loader plug-in that watches for shared library loads/unloads "
+ "in MacOSX user processes.";
}
-
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
-lldb_private::ConstString
-DynamicLoaderMacOSXDYLD::GetPluginName()
-{
- return GetPluginNameStatic();
+lldb_private::ConstString DynamicLoaderMacOSXDYLD::GetPluginName() {
+ return GetPluginNameStatic();
}
-uint32_t
-DynamicLoaderMacOSXDYLD::GetPluginVersion()
-{
- return 1;
-}
+uint32_t DynamicLoaderMacOSXDYLD::GetPluginVersion() { return 1; }
-uint32_t
-DynamicLoaderMacOSXDYLD::AddrByteSize()
-{
- std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
+uint32_t DynamicLoaderMacOSXDYLD::AddrByteSize() {
+ std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
- switch (m_dyld.header.magic)
- {
- case llvm::MachO::MH_MAGIC:
- case llvm::MachO::MH_CIGAM:
- return 4;
-
- case llvm::MachO::MH_MAGIC_64:
- case llvm::MachO::MH_CIGAM_64:
- return 8;
-
- default:
- break;
- }
- return 0;
+ switch (m_dyld.header.magic) {
+ case llvm::MachO::MH_MAGIC:
+ case llvm::MachO::MH_CIGAM:
+ return 4;
+
+ case llvm::MachO::MH_MAGIC_64:
+ case llvm::MachO::MH_CIGAM_64:
+ return 8;
+
+ default:
+ break;
+ }
+ return 0;
}
-lldb::ByteOrder
-DynamicLoaderMacOSXDYLD::GetByteOrderFromMagic(uint32_t magic)
-{
- switch (magic)
- {
- case llvm::MachO::MH_MAGIC:
- case llvm::MachO::MH_MAGIC_64:
- return endian::InlHostByteOrder();
-
- case llvm::MachO::MH_CIGAM:
- case llvm::MachO::MH_CIGAM_64:
- if (endian::InlHostByteOrder() == lldb::eByteOrderBig)
- return lldb::eByteOrderLittle;
- else
- return lldb::eByteOrderBig;
-
- default:
- break;
- }
- return lldb::eByteOrderInvalid;
+lldb::ByteOrder DynamicLoaderMacOSXDYLD::GetByteOrderFromMagic(uint32_t magic) {
+ switch (magic) {
+ case llvm::MachO::MH_MAGIC:
+ case llvm::MachO::MH_MAGIC_64:
+ return endian::InlHostByteOrder();
+
+ case llvm::MachO::MH_CIGAM:
+ case llvm::MachO::MH_CIGAM_64:
+ if (endian::InlHostByteOrder() == lldb::eByteOrderBig)
+ return lldb::eByteOrderLittle;
+ else
+ return lldb::eByteOrderBig;
+
+ default:
+ break;
+ }
+ return lldb::eByteOrderInvalid;
}
diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h
index 5c970218b9a..25ccf702e96 100644
--- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h
+++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h
@@ -7,10 +7,10 @@
//
//===----------------------------------------------------------------------===//
-
-// This is the DynamicLoader plugin for Darwin (macOS / iPhoneOS / tvOS / watchOS)
+// This is the DynamicLoader plugin for Darwin (macOS / iPhoneOS / tvOS /
+// watchOS)
// platforms earlier than 2016, where lldb would read the "dyld_all_image_infos"
-// dyld internal structure to understand where things were loaded and the
+// dyld internal structure to understand where things were loaded and the
// solib loaded/unloaded notification function we put a breakpoint on gives us
// an array of (load address, mod time, file path) tuples.
//
@@ -23,198 +23,164 @@
// C Includes
// C++ Includes
-#include <vector>
#include <mutex>
+#include <vector>
// Other libraries and framework includes
// Project includes
-#include "lldb/Target/DynamicLoader.h"
-#include "lldb/Host/FileSpec.h"
#include "lldb/Core/StructuredData.h"
#include "lldb/Core/UUID.h"
+#include "lldb/Host/FileSpec.h"
+#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/Process.h"
#include "lldb/Utility/SafeMachO.h"
#include "DynamicLoaderDarwin.h"
-class DynamicLoaderMacOSXDYLD : public lldb_private::DynamicLoaderDarwin
-{
+class DynamicLoaderMacOSXDYLD : public lldb_private::DynamicLoaderDarwin {
public:
- DynamicLoaderMacOSXDYLD(lldb_private::Process *process);
+ DynamicLoaderMacOSXDYLD(lldb_private::Process *process);
- virtual ~DynamicLoaderMacOSXDYLD() override;
+ virtual ~DynamicLoaderMacOSXDYLD() override;
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
- static void
- Initialize();
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+ static void Initialize();
- static void
- Terminate();
+ static void Terminate();
- static lldb_private::ConstString
- GetPluginNameStatic();
+ static lldb_private::ConstString GetPluginNameStatic();
- static const char *
- GetPluginDescriptionStatic();
+ static const char *GetPluginDescriptionStatic();
- static lldb_private::DynamicLoader *
- CreateInstance (lldb_private::Process *process, bool force);
+ static lldb_private::DynamicLoader *
+ CreateInstance(lldb_private::Process *process, bool force);
- //------------------------------------------------------------------
- /// Called after attaching a process.
- ///
- /// Allow DynamicLoader plug-ins to execute some code after
- /// attaching to a process.
- //------------------------------------------------------------------
- bool
- ProcessDidExec() override;
+ //------------------------------------------------------------------
+ /// Called after attaching a process.
+ ///
+ /// Allow DynamicLoader plug-ins to execute some code after
+ /// attaching to a process.
+ //------------------------------------------------------------------
+ bool ProcessDidExec() override;
- lldb_private::Error
- CanLoadImage() override;
+ lldb_private::Error CanLoadImage() override;
- bool
- GetSharedCacheInformation (lldb::addr_t &base_address,
- lldb_private::UUID &uuid,
- lldb_private::LazyBool &using_shared_cache,
- lldb_private::LazyBool &private_shared_cache) override;
+ bool GetSharedCacheInformation(
+ lldb::addr_t &base_address, lldb_private::UUID &uuid,
+ lldb_private::LazyBool &using_shared_cache,
+ lldb_private::LazyBool &private_shared_cache) override;
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- lldb_private::ConstString
- GetPluginName() override;
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ lldb_private::ConstString GetPluginName() override;
- uint32_t
- GetPluginVersion() override;
+ uint32_t GetPluginVersion() override;
protected:
- void
- PutToLog(lldb_private::Log *log) const;
-
- void
- DoInitialImageFetch () override;
-
- bool
- NeedToDoInitialImageFetch () override;
-
- bool
- DidSetNotificationBreakpoint () override;
-
- void
- DoClear () override;
-
- bool
- ReadDYLDInfoFromMemoryAndSetNotificationCallback (lldb::addr_t addr);
-
- static bool
- NotifyBreakpointHit (void *baton,
- lldb_private::StoppointCallbackContext *context,
- lldb::user_id_t break_id,
- lldb::user_id_t break_loc_id);
-
- uint32_t
- AddrByteSize();
-
- bool
- ReadMachHeader (lldb::addr_t addr,
- llvm::MachO::mach_header *header,
- lldb_private::DataExtractor *load_command_data);
-
- uint32_t
- ParseLoadCommands (const lldb_private::DataExtractor& data,
- ImageInfo& dylib_info,
- lldb_private::FileSpec *lc_id_dylinker);
-
- struct DYLDAllImageInfos
- {
- uint32_t version;
- uint32_t dylib_info_count; // Version >= 1
- lldb::addr_t dylib_info_addr; // Version >= 1
- lldb::addr_t notification; // Version >= 1
- bool processDetachedFromSharedRegion; // Version >= 1
- bool libSystemInitialized; // Version >= 2
- lldb::addr_t dyldImageLoadAddress; // Version >= 2
-
- DYLDAllImageInfos() :
- version (0),
- dylib_info_count (0),
- dylib_info_addr (LLDB_INVALID_ADDRESS),
- notification (LLDB_INVALID_ADDRESS),
- processDetachedFromSharedRegion (false),
- libSystemInitialized (false),
- dyldImageLoadAddress (LLDB_INVALID_ADDRESS)
- {
- }
-
- void
- Clear()
- {
- version = 0;
- dylib_info_count = 0;
- dylib_info_addr = LLDB_INVALID_ADDRESS;
- notification = LLDB_INVALID_ADDRESS;
- processDetachedFromSharedRegion = false;
- libSystemInitialized = false;
- dyldImageLoadAddress = LLDB_INVALID_ADDRESS;
- }
-
- bool
- IsValid() const
- {
- return version >= 1 || version <= 6;
- }
- };
-
- static lldb::ByteOrder
- GetByteOrderFromMagic(uint32_t magic);
-
- bool
- SetNotificationBreakpoint () override;
-
- void
- ClearNotificationBreakpoint () override;
-
- // There is a little tricky bit where you might initially attach while dyld is updating
- // the all_image_infos, and you can't read the infos, so you have to continue and pick it
- // up when you hit the update breakpoint. At that point, you need to run this initialize
- // function, but when you do it that way you DON'T need to do the extra work you would at
- // the breakpoint.
- // So this function will only do actual work if the image infos haven't been read yet.
- // If it does do any work, then it will return true, and false otherwise. That way you can
- // call it in the breakpoint action, and if it returns true you're done.
- bool
- InitializeFromAllImageInfos ();
-
- bool
- ReadAllImageInfosStructure ();
-
- bool
- AddModulesUsingImageInfosAddress (lldb::addr_t image_infos_addr, uint32_t image_infos_count);
-
- bool
- RemoveModulesUsingImageInfosAddress (lldb::addr_t image_infos_addr, uint32_t image_infos_count);
-
- void
- UpdateImageInfosHeaderAndLoadCommands(ImageInfo::collection &image_infos,
- uint32_t infos_count,
- bool update_executable);
-
- bool
- ReadImageInfos (lldb::addr_t image_infos_addr,
- uint32_t image_infos_count,
- ImageInfo::collection &image_infos);
-
- lldb::addr_t m_dyld_all_image_infos_addr;
- DYLDAllImageInfos m_dyld_all_image_infos;
- uint32_t m_dyld_all_image_infos_stop_id;
- lldb::user_id_t m_break_id;
- mutable std::recursive_mutex m_mutex;
- bool m_process_image_addr_is_all_images_infos;
+ void PutToLog(lldb_private::Log *log) const;
+
+ void DoInitialImageFetch() override;
+
+ bool NeedToDoInitialImageFetch() override;
+
+ bool DidSetNotificationBreakpoint() override;
+
+ void DoClear() override;
+
+ bool ReadDYLDInfoFromMemoryAndSetNotificationCallback(lldb::addr_t addr);
+
+ static bool
+ NotifyBreakpointHit(void *baton,
+ lldb_private::StoppointCallbackContext *context,
+ lldb::user_id_t break_id, lldb::user_id_t break_loc_id);
+
+ uint32_t AddrByteSize();
+
+ bool ReadMachHeader(lldb::addr_t addr, llvm::MachO::mach_header *header,
+ lldb_private::DataExtractor *load_command_data);
+
+ uint32_t ParseLoadCommands(const lldb_private::DataExtractor &data,
+ ImageInfo &dylib_info,
+ lldb_private::FileSpec *lc_id_dylinker);
+
+ struct DYLDAllImageInfos {
+ uint32_t version;
+ uint32_t dylib_info_count; // Version >= 1
+ lldb::addr_t dylib_info_addr; // Version >= 1
+ lldb::addr_t notification; // Version >= 1
+ bool processDetachedFromSharedRegion; // Version >= 1
+ bool libSystemInitialized; // Version >= 2
+ lldb::addr_t dyldImageLoadAddress; // Version >= 2
+
+ DYLDAllImageInfos()
+ : version(0), dylib_info_count(0),
+ dylib_info_addr(LLDB_INVALID_ADDRESS),
+ notification(LLDB_INVALID_ADDRESS),
+ processDetachedFromSharedRegion(false), libSystemInitialized(false),
+ dyldImageLoadAddress(LLDB_INVALID_ADDRESS) {}
+
+ void Clear() {
+ version = 0;
+ dylib_info_count = 0;
+ dylib_info_addr = LLDB_INVALID_ADDRESS;
+ notification = LLDB_INVALID_ADDRESS;
+ processDetachedFromSharedRegion = false;
+ libSystemInitialized = false;
+ dyldImageLoadAddress = LLDB_INVALID_ADDRESS;
+ }
+
+ bool IsValid() const { return version >= 1 || version <= 6; }
+ };
+
+ static lldb::ByteOrder GetByteOrderFromMagic(uint32_t magic);
+
+ bool SetNotificationBreakpoint() override;
+
+ void ClearNotificationBreakpoint() override;
+
+ // There is a little tricky bit where you might initially attach while dyld is
+ // updating
+ // the all_image_infos, and you can't read the infos, so you have to continue
+ // and pick it
+ // up when you hit the update breakpoint. At that point, you need to run this
+ // initialize
+ // function, but when you do it that way you DON'T need to do the extra work
+ // you would at
+ // the breakpoint.
+ // So this function will only do actual work if the image infos haven't been
+ // read yet.
+ // If it does do any work, then it will return true, and false otherwise.
+ // That way you can
+ // call it in the breakpoint action, and if it returns true you're done.
+ bool InitializeFromAllImageInfos();
+
+ bool ReadAllImageInfosStructure();
+
+ bool AddModulesUsingImageInfosAddress(lldb::addr_t image_infos_addr,
+ uint32_t image_infos_count);
+
+ bool RemoveModulesUsingImageInfosAddress(lldb::addr_t image_infos_addr,
+ uint32_t image_infos_count);
+
+ void UpdateImageInfosHeaderAndLoadCommands(ImageInfo::collection &image_infos,
+ uint32_t infos_count,
+ bool update_executable);
+
+ bool ReadImageInfos(lldb::addr_t image_infos_addr, uint32_t image_infos_count,
+ ImageInfo::collection &image_infos);
+
+ lldb::addr_t m_dyld_all_image_infos_addr;
+ DYLDAllImageInfos m_dyld_all_image_infos;
+ uint32_t m_dyld_all_image_infos_stop_id;
+ lldb::user_id_t m_break_id;
+ mutable std::recursive_mutex m_mutex;
+ bool m_process_image_addr_is_all_images_infos;
private:
- DISALLOW_COPY_AND_ASSIGN (DynamicLoaderMacOSXDYLD);
+ DISALLOW_COPY_AND_ASSIGN(DynamicLoaderMacOSXDYLD);
};
#endif // liblldb_DynamicLoaderMacOSXDYLD_h_
diff --git a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.cpp b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.cpp
index 04a6792fbf0..ec655c6f9b3 100644
--- a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.cpp
+++ b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.cpp
@@ -28,113 +28,92 @@
using namespace lldb;
using namespace lldb_private;
-static bool
-GetMaxU64(DataExtractor &data,
- lldb::offset_t *offset_ptr,
- uint64_t *value,
- unsigned int byte_size)
-{
- lldb::offset_t saved_offset = *offset_ptr;
- *value = data.GetMaxU64(offset_ptr, byte_size);
- return *offset_ptr != saved_offset;
+static bool GetMaxU64(DataExtractor &data, lldb::offset_t *offset_ptr,
+ uint64_t *value, unsigned int byte_size) {
+ lldb::offset_t saved_offset = *offset_ptr;
+ *value = data.GetMaxU64(offset_ptr, byte_size);
+ return *offset_ptr != saved_offset;
}
-static bool
-ParseAuxvEntry(DataExtractor &data,
- AuxVector::Entry &entry,
- lldb::offset_t *offset_ptr,
- unsigned int byte_size)
-{
- if (!GetMaxU64(data, offset_ptr, &entry.type, byte_size))
- return false;
+static bool ParseAuxvEntry(DataExtractor &data, AuxVector::Entry &entry,
+ lldb::offset_t *offset_ptr, unsigned int byte_size) {
+ if (!GetMaxU64(data, offset_ptr, &entry.type, byte_size))
+ return false;
- if (!GetMaxU64(data, offset_ptr, &entry.value, byte_size))
- return false;
+ if (!GetMaxU64(data, offset_ptr, &entry.value, byte_size))
+ return false;
- return true;
+ return true;
}
-DataBufferSP
-AuxVector::GetAuxvData()
-{
- if (m_process)
- return m_process->GetAuxvData ();
- else
- return DataBufferSP ();
+DataBufferSP AuxVector::GetAuxvData() {
+ if (m_process)
+ return m_process->GetAuxvData();
+ else
+ return DataBufferSP();
}
-void
-AuxVector::ParseAuxv(DataExtractor &data)
-{
- const unsigned int byte_size = m_process->GetAddressByteSize();
- lldb::offset_t offset = 0;
+void AuxVector::ParseAuxv(DataExtractor &data) {
+ const unsigned int byte_size = m_process->GetAddressByteSize();
+ lldb::offset_t offset = 0;
- for (;;)
- {
- Entry entry;
+ for (;;) {
+ Entry entry;
- if (!ParseAuxvEntry(data, entry, &offset, byte_size))
- break;
+ if (!ParseAuxvEntry(data, entry, &offset, byte_size))
+ break;
- if (entry.type == AT_NULL)
- break;
+ if (entry.type == AT_NULL)
+ break;
- if (entry.type == AT_IGNORE)
- continue;
+ if (entry.type == AT_IGNORE)
+ continue;
- m_auxv.push_back(entry);
- }
+ m_auxv.push_back(entry);
+ }
}
-AuxVector::AuxVector(Process *process)
- : m_process(process)
-{
- DataExtractor data;
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+AuxVector::AuxVector(Process *process) : m_process(process) {
+ DataExtractor data;
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+
+ data.SetData(GetAuxvData());
+ data.SetByteOrder(m_process->GetByteOrder());
+ data.SetAddressByteSize(m_process->GetAddressByteSize());
- data.SetData(GetAuxvData());
- data.SetByteOrder(m_process->GetByteOrder());
- data.SetAddressByteSize(m_process->GetAddressByteSize());
-
- ParseAuxv(data);
+ ParseAuxv(data);
- if (log)
- DumpToLog(log);
+ if (log)
+ DumpToLog(log);
}
-AuxVector::iterator
-AuxVector::FindEntry(EntryType type) const
-{
- for (iterator I = begin(); I != end(); ++I)
- {
- if (I->type == static_cast<uint64_t>(type))
- return I;
- }
+AuxVector::iterator AuxVector::FindEntry(EntryType type) const {
+ for (iterator I = begin(); I != end(); ++I) {
+ if (I->type == static_cast<uint64_t>(type))
+ return I;
+ }
- return end();
+ return end();
}
-void
-AuxVector::DumpToLog(Log *log) const
-{
- if (!log)
- return;
+void AuxVector::DumpToLog(Log *log) const {
+ if (!log)
+ return;
- log->PutCString("AuxVector: ");
- for (iterator I = begin(); I != end(); ++I)
- {
- log->Printf(" %s [%" PRIu64 "]: %" PRIx64, GetEntryName(*I), I->type, I->value);
- }
+ log->PutCString("AuxVector: ");
+ for (iterator I = begin(); I != end(); ++I) {
+ log->Printf(" %s [%" PRIu64 "]: %" PRIx64, GetEntryName(*I), I->type,
+ I->value);
+ }
}
-const char *
-AuxVector::GetEntryName(EntryType type)
-{
- const char *name = "AT_???";
+const char *AuxVector::GetEntryName(EntryType type) {
+ const char *name = "AT_???";
-#define ENTRY_NAME(_type) _type: name = #_type
- switch (type)
- {
+#define ENTRY_NAME(_type) \
+ _type: \
+ name = #_type
+ switch (type) {
case ENTRY_NAME(AT_NULL); break;
case ENTRY_NAME(AT_IGNORE); break;
case ENTRY_NAME(AT_EXECFD); break;
@@ -173,4 +152,3 @@ AuxVector::GetEntryName(EntryType type)
return name;
}
-
diff --git a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.h b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.h
index 2d39eddcacc..9c3e1b002a2 100644
--- a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.h
+++ b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.h
@@ -19,7 +19,7 @@
namespace lldb_private {
class DataExtractor;
-}
+}
/// @class AuxVector
/// @brief Represents a processes auxiliary vector.
@@ -31,85 +31,80 @@ class DataExtractor;
class AuxVector {
public:
- AuxVector(lldb_private::Process *process);
-
- struct Entry {
- uint64_t type;
- uint64_t value;
-
- Entry() : type(0), value(0) { }
- };
-
- /// Constants describing the type of entry.
- /// On Linux, running "LD_SHOW_AUXV=1 ./executable" will spew AUX information.
- enum EntryType {
- AT_NULL = 0, ///< End of auxv.
- AT_IGNORE = 1, ///< Ignore entry.
- AT_EXECFD = 2, ///< File descriptor of program.
- AT_PHDR = 3, ///< Program headers.
- AT_PHENT = 4, ///< Size of program header.
- AT_PHNUM = 5, ///< Number of program headers.
- AT_PAGESZ = 6, ///< Page size.
- AT_BASE = 7, ///< Interpreter base address.
- AT_FLAGS = 8, ///< Flags.
- AT_ENTRY = 9, ///< Program entry point.
- AT_NOTELF = 10, ///< Set if program is not an ELF.
- AT_UID = 11, ///< UID.
- AT_EUID = 12, ///< Effective UID.
- AT_GID = 13, ///< GID.
- AT_EGID = 14, ///< Effective GID.
- AT_CLKTCK = 17, ///< Clock frequency (e.g. times(2)).
- AT_PLATFORM = 15, ///< String identifying platform.
- AT_HWCAP = 16, ///< Machine dependent hints about processor capabilities.
- AT_FPUCW = 18, ///< Used FPU control word.
- AT_DCACHEBSIZE = 19, ///< Data cache block size.
- AT_ICACHEBSIZE = 20, ///< Instruction cache block size.
- AT_UCACHEBSIZE = 21, ///< Unified cache block size.
- AT_IGNOREPPC = 22, ///< Entry should be ignored.
- AT_SECURE = 23, ///< Boolean, was exec setuid-like?
- AT_BASE_PLATFORM = 24, ///< String identifying real platforms.
- AT_RANDOM = 25, ///< Address of 16 random bytes.
- AT_EXECFN = 31, ///< Filename of executable.
- AT_SYSINFO = 32, ///< Pointer to the global system page used for system calls and other nice things.
- AT_SYSINFO_EHDR = 33,
- AT_L1I_CACHESHAPE = 34, ///< Shapes of the caches.
- AT_L1D_CACHESHAPE = 35,
- AT_L2_CACHESHAPE = 36,
- AT_L3_CACHESHAPE = 37,
- };
+ AuxVector(lldb_private::Process *process);
+
+ struct Entry {
+ uint64_t type;
+ uint64_t value;
+
+ Entry() : type(0), value(0) {}
+ };
+
+ /// Constants describing the type of entry.
+ /// On Linux, running "LD_SHOW_AUXV=1 ./executable" will spew AUX information.
+ enum EntryType {
+ AT_NULL = 0, ///< End of auxv.
+ AT_IGNORE = 1, ///< Ignore entry.
+ AT_EXECFD = 2, ///< File descriptor of program.
+ AT_PHDR = 3, ///< Program headers.
+ AT_PHENT = 4, ///< Size of program header.
+ AT_PHNUM = 5, ///< Number of program headers.
+ AT_PAGESZ = 6, ///< Page size.
+ AT_BASE = 7, ///< Interpreter base address.
+ AT_FLAGS = 8, ///< Flags.
+ AT_ENTRY = 9, ///< Program entry point.
+ AT_NOTELF = 10, ///< Set if program is not an ELF.
+ AT_UID = 11, ///< UID.
+ AT_EUID = 12, ///< Effective UID.
+ AT_GID = 13, ///< GID.
+ AT_EGID = 14, ///< Effective GID.
+ AT_CLKTCK = 17, ///< Clock frequency (e.g. times(2)).
+ AT_PLATFORM = 15, ///< String identifying platform.
+ AT_HWCAP = 16, ///< Machine dependent hints about processor capabilities.
+ AT_FPUCW = 18, ///< Used FPU control word.
+ AT_DCACHEBSIZE = 19, ///< Data cache block size.
+ AT_ICACHEBSIZE = 20, ///< Instruction cache block size.
+ AT_UCACHEBSIZE = 21, ///< Unified cache block size.
+ AT_IGNOREPPC = 22, ///< Entry should be ignored.
+ AT_SECURE = 23, ///< Boolean, was exec setuid-like?
+ AT_BASE_PLATFORM = 24, ///< String identifying real platforms.
+ AT_RANDOM = 25, ///< Address of 16 random bytes.
+ AT_EXECFN = 31, ///< Filename of executable.
+ AT_SYSINFO = 32, ///< Pointer to the global system page used for system
+ ///calls and other nice things.
+ AT_SYSINFO_EHDR = 33,
+ AT_L1I_CACHESHAPE = 34, ///< Shapes of the caches.
+ AT_L1D_CACHESHAPE = 35,
+ AT_L2_CACHESHAPE = 36,
+ AT_L3_CACHESHAPE = 37,
+ };
private:
- typedef std::vector<Entry> EntryVector;
+ typedef std::vector<Entry> EntryVector;
public:
- typedef EntryVector::const_iterator iterator;
+ typedef EntryVector::const_iterator iterator;
- iterator begin() const { return m_auxv.begin(); }
- iterator end() const { return m_auxv.end(); }
+ iterator begin() const { return m_auxv.begin(); }
+ iterator end() const { return m_auxv.end(); }
- iterator
- FindEntry(EntryType type) const;
+ iterator FindEntry(EntryType type) const;
- static const char *
- GetEntryName(const Entry &entry) {
- return GetEntryName(static_cast<EntryType>(entry.type));
- }
+ static const char *GetEntryName(const Entry &entry) {
+ return GetEntryName(static_cast<EntryType>(entry.type));
+ }
- static const char *
- GetEntryName(EntryType type);
+ static const char *GetEntryName(EntryType type);
- void
- DumpToLog(lldb_private::Log *log) const;
+ void DumpToLog(lldb_private::Log *log) const;
private:
- lldb_private::Process *m_process;
- EntryVector m_auxv;
+ lldb_private::Process *m_process;
+ EntryVector m_auxv;
- lldb::DataBufferSP
- GetAuxvData();
+ lldb::DataBufferSP GetAuxvData();
- void
- ParseAuxv(lldb_private::DataExtractor &data);
+ void ParseAuxv(lldb_private::DataExtractor &data);
};
#endif
diff --git a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
index 443f97ed0ba..136bf6561a2 100644
--- a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
+++ b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
@@ -30,631 +30,582 @@ using namespace lldb_private;
/// Locates the address of the rendezvous structure. Returns the address on
/// success and LLDB_INVALID_ADDRESS on failure.
-static addr_t
-ResolveRendezvousAddress(Process *process)
-{
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- addr_t info_location;
- addr_t info_addr;
- Error error;
-
- if (!process)
- {
- if (log)
- log->Printf ("%s null process provided", __FUNCTION__);
- return LLDB_INVALID_ADDRESS;
- }
+static addr_t ResolveRendezvousAddress(Process *process) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+ addr_t info_location;
+ addr_t info_addr;
+ Error error;
- // Try to get it from our process. This might be a remote process and might
- // grab it via some remote-specific mechanism.
- info_location = process->GetImageInfoAddress();
+ if (!process) {
if (log)
- log->Printf ("%s info_location = 0x%" PRIx64, __FUNCTION__, info_location);
-
- // If the process fails to return an address, fall back to seeing if the local object file can help us find it.
- if (info_location == LLDB_INVALID_ADDRESS)
- {
- Target *target = &process->GetTarget();
- if (target)
- {
- ObjectFile *obj_file = target->GetExecutableModule()->GetObjectFile();
- Address addr = obj_file->GetImageInfoAddress(target);
-
- if (addr.IsValid())
- {
- info_location = addr.GetLoadAddress(target);
- if (log)
- log->Printf ("%s resolved via direct object file approach to 0x%" PRIx64, __FUNCTION__, info_location);
- }
- else
- {
- if (log)
- log->Printf ("%s FAILED - direct object file approach did not yield a valid address", __FUNCTION__);
- }
- }
- }
-
- if (info_location == LLDB_INVALID_ADDRESS)
- {
+ log->Printf("%s null process provided", __FUNCTION__);
+ return LLDB_INVALID_ADDRESS;
+ }
+
+ // Try to get it from our process. This might be a remote process and might
+ // grab it via some remote-specific mechanism.
+ info_location = process->GetImageInfoAddress();
+ if (log)
+ log->Printf("%s info_location = 0x%" PRIx64, __FUNCTION__, info_location);
+
+ // If the process fails to return an address, fall back to seeing if the local
+ // object file can help us find it.
+ if (info_location == LLDB_INVALID_ADDRESS) {
+ Target *target = &process->GetTarget();
+ if (target) {
+ ObjectFile *obj_file = target->GetExecutableModule()->GetObjectFile();
+ Address addr = obj_file->GetImageInfoAddress(target);
+
+ if (addr.IsValid()) {
+ info_location = addr.GetLoadAddress(target);
if (log)
- log->Printf ("%s FAILED - invalid info address", __FUNCTION__);
- return LLDB_INVALID_ADDRESS;
+ log->Printf(
+ "%s resolved via direct object file approach to 0x%" PRIx64,
+ __FUNCTION__, info_location);
+ } else {
+ if (log)
+ log->Printf("%s FAILED - direct object file approach did not yield a "
+ "valid address",
+ __FUNCTION__);
+ }
}
+ }
+ if (info_location == LLDB_INVALID_ADDRESS) {
if (log)
- log->Printf ("%s reading pointer (%" PRIu32 " bytes) from 0x%" PRIx64, __FUNCTION__, process->GetAddressByteSize(), info_location);
+ log->Printf("%s FAILED - invalid info address", __FUNCTION__);
+ return LLDB_INVALID_ADDRESS;
+ }
- info_addr = process->ReadPointerFromMemory(info_location, error);
- if (error.Fail())
- {
- if (log)
- log->Printf ("%s FAILED - could not read from the info location: %s", __FUNCTION__, error.AsCString ());
- return LLDB_INVALID_ADDRESS;
- }
+ if (log)
+ log->Printf("%s reading pointer (%" PRIu32 " bytes) from 0x%" PRIx64,
+ __FUNCTION__, process->GetAddressByteSize(), info_location);
- if (info_addr == 0)
- {
- if (log)
- log->Printf ("%s FAILED - the rendezvous address contained at 0x%" PRIx64 " returned a null value", __FUNCTION__, info_location);
- return LLDB_INVALID_ADDRESS;
- }
+ info_addr = process->ReadPointerFromMemory(info_location, error);
+ if (error.Fail()) {
+ if (log)
+ log->Printf("%s FAILED - could not read from the info location: %s",
+ __FUNCTION__, error.AsCString());
+ return LLDB_INVALID_ADDRESS;
+ }
- return info_addr;
+ if (info_addr == 0) {
+ if (log)
+ log->Printf("%s FAILED - the rendezvous address contained at 0x%" PRIx64
+ " returned a null value",
+ __FUNCTION__, info_location);
+ return LLDB_INVALID_ADDRESS;
+ }
+
+ return info_addr;
}
DYLDRendezvous::DYLDRendezvous(Process *process)
- : m_process(process),
- m_rendezvous_addr(LLDB_INVALID_ADDRESS),
- m_current(),
- m_previous(),
- m_loaded_modules(),
- m_soentries(),
- m_added_soentries(),
- m_removed_soentries()
-{
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
-
- m_thread_info.valid = false;
-
- // Cache a copy of the executable path
- if (m_process)
- {
- Module *exe_mod = m_process->GetTarget().GetExecutableModulePointer();
- if (exe_mod)
- {
- m_exe_file_spec = exe_mod->GetPlatformFileSpec();
- if (log)
- log->Printf ("DYLDRendezvous::%s exe module executable path set: '%s'",
- __FUNCTION__, m_exe_file_spec.GetCString());
- }
- else
- {
- if (log)
- log->Printf ("DYLDRendezvous::%s cannot cache exe module path: null executable module pointer", __FUNCTION__);
- }
+ : m_process(process), m_rendezvous_addr(LLDB_INVALID_ADDRESS), m_current(),
+ m_previous(), m_loaded_modules(), m_soentries(), m_added_soentries(),
+ m_removed_soentries() {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+
+ m_thread_info.valid = false;
+
+ // Cache a copy of the executable path
+ if (m_process) {
+ Module *exe_mod = m_process->GetTarget().GetExecutableModulePointer();
+ if (exe_mod) {
+ m_exe_file_spec = exe_mod->GetPlatformFileSpec();
+ if (log)
+ log->Printf("DYLDRendezvous::%s exe module executable path set: '%s'",
+ __FUNCTION__, m_exe_file_spec.GetCString());
+ } else {
+ if (log)
+ log->Printf("DYLDRendezvous::%s cannot cache exe module path: null "
+ "executable module pointer",
+ __FUNCTION__);
}
+ }
}
-bool
-DYLDRendezvous::Resolve()
-{
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+bool DYLDRendezvous::Resolve() {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+
+ const size_t word_size = 4;
+ Rendezvous info;
+ size_t address_size;
+ size_t padding;
+ addr_t info_addr;
+ addr_t cursor;
+
+ address_size = m_process->GetAddressByteSize();
+ padding = address_size - word_size;
+ if (log)
+ log->Printf("DYLDRendezvous::%s address size: %" PRIu64
+ ", padding %" PRIu64,
+ __FUNCTION__, uint64_t(address_size), uint64_t(padding));
+
+ if (m_rendezvous_addr == LLDB_INVALID_ADDRESS)
+ cursor = info_addr = ResolveRendezvousAddress(m_process);
+ else
+ cursor = info_addr = m_rendezvous_addr;
+ if (log)
+ log->Printf("DYLDRendezvous::%s cursor = 0x%" PRIx64, __FUNCTION__, cursor);
+
+ if (cursor == LLDB_INVALID_ADDRESS)
+ return false;
- const size_t word_size = 4;
- Rendezvous info;
- size_t address_size;
- size_t padding;
- addr_t info_addr;
- addr_t cursor;
+ if (!(cursor = ReadWord(cursor, &info.version, word_size)))
+ return false;
- address_size = m_process->GetAddressByteSize();
- padding = address_size - word_size;
- if (log)
- log->Printf ("DYLDRendezvous::%s address size: %" PRIu64 ", padding %" PRIu64, __FUNCTION__, uint64_t(address_size), uint64_t(padding));
+ if (!(cursor = ReadPointer(cursor + padding, &info.map_addr)))
+ return false;
- if (m_rendezvous_addr == LLDB_INVALID_ADDRESS)
- cursor = info_addr = ResolveRendezvousAddress(m_process);
- else
- cursor = info_addr = m_rendezvous_addr;
- if (log)
- log->Printf ("DYLDRendezvous::%s cursor = 0x%" PRIx64, __FUNCTION__, cursor);
+ if (!(cursor = ReadPointer(cursor, &info.brk)))
+ return false;
- if (cursor == LLDB_INVALID_ADDRESS)
- return false;
+ if (!(cursor = ReadWord(cursor, &info.state, word_size)))
+ return false;
- if (!(cursor = ReadWord(cursor, &info.version, word_size)))
- return false;
+ if (!(cursor = ReadPointer(cursor + padding, &info.ldbase)))
+ return false;
- if (!(cursor = ReadPointer(cursor + padding, &info.map_addr)))
- return false;
+ // The rendezvous was successfully read. Update our internal state.
+ m_rendezvous_addr = info_addr;
+ m_previous = m_current;
+ m_current = info;
- if (!(cursor = ReadPointer(cursor, &info.brk)))
- return false;
+ if (UpdateSOEntries(true))
+ return true;
- if (!(cursor = ReadWord(cursor, &info.state, word_size)))
- return false;
+ return UpdateSOEntries();
+}
- if (!(cursor = ReadPointer(cursor + padding, &info.ldbase)))
- return false;
+bool DYLDRendezvous::IsValid() {
+ return m_rendezvous_addr != LLDB_INVALID_ADDRESS;
+}
- // The rendezvous was successfully read. Update our internal state.
- m_rendezvous_addr = info_addr;
- m_previous = m_current;
- m_current = info;
+bool DYLDRendezvous::UpdateSOEntries(bool fromRemote) {
+ SOEntry entry;
+ LoadedModuleInfoList module_list;
- if (UpdateSOEntries (true))
- return true;
+ // If we can't get the SO info from the remote, return failure.
+ if (fromRemote && m_process->LoadModules(module_list) == 0)
+ return false;
- return UpdateSOEntries();
-}
+ if (!fromRemote && m_current.map_addr == 0)
+ return false;
-bool
-DYLDRendezvous::IsValid()
-{
- return m_rendezvous_addr != LLDB_INVALID_ADDRESS;
+ // When the previous and current states are consistent this is the first
+ // time we have been asked to update. Just take a snapshot of the currently
+ // loaded modules.
+ if (m_previous.state == eConsistent && m_current.state == eConsistent)
+ return fromRemote ? SaveSOEntriesFromRemote(module_list)
+ : TakeSnapshot(m_soentries);
+
+ // If we are about to add or remove a shared object clear out the current
+ // state and take a snapshot of the currently loaded images.
+ if (m_current.state == eAdd || m_current.state == eDelete) {
+ // Some versions of the android dynamic linker might send two
+ // notifications with state == eAdd back to back. Ignore them
+ // until we get an eConsistent notification.
+ if (!(m_previous.state == eConsistent ||
+ (m_previous.state == eAdd && m_current.state == eDelete)))
+ return false;
+
+ m_soentries.clear();
+ if (fromRemote)
+ return SaveSOEntriesFromRemote(module_list);
+
+ m_added_soentries.clear();
+ m_removed_soentries.clear();
+ return TakeSnapshot(m_soentries);
+ }
+ assert(m_current.state == eConsistent);
+
+ // Otherwise check the previous state to determine what to expect and update
+ // accordingly.
+ if (m_previous.state == eAdd)
+ return fromRemote ? AddSOEntriesFromRemote(module_list) : AddSOEntries();
+ else if (m_previous.state == eDelete)
+ return fromRemote ? RemoveSOEntriesFromRemote(module_list)
+ : RemoveSOEntries();
+
+ return false;
}
-bool
-DYLDRendezvous::UpdateSOEntries(bool fromRemote)
-{
- SOEntry entry;
- LoadedModuleInfoList module_list;
+bool DYLDRendezvous::FillSOEntryFromModuleInfo(
+ LoadedModuleInfoList::LoadedModuleInfo const &modInfo, SOEntry &entry) {
+ addr_t link_map_addr;
+ addr_t base_addr;
+ addr_t dyn_addr;
+ std::string name;
- // If we can't get the SO info from the remote, return failure.
- if (fromRemote && m_process->LoadModules (module_list) == 0)
- return false;
+ if (!modInfo.get_link_map(link_map_addr) || !modInfo.get_base(base_addr) ||
+ !modInfo.get_dynamic(dyn_addr) || !modInfo.get_name(name))
+ return false;
- if (!fromRemote && m_current.map_addr == 0)
- return false;
+ entry.link_addr = link_map_addr;
+ entry.base_addr = base_addr;
+ entry.dyn_addr = dyn_addr;
- // When the previous and current states are consistent this is the first
- // time we have been asked to update. Just take a snapshot of the currently
- // loaded modules.
- if (m_previous.state == eConsistent && m_current.state == eConsistent)
- return fromRemote ? SaveSOEntriesFromRemote(module_list) : TakeSnapshot(m_soentries);
-
- // If we are about to add or remove a shared object clear out the current
- // state and take a snapshot of the currently loaded images.
- if (m_current.state == eAdd || m_current.state == eDelete)
- {
- // Some versions of the android dynamic linker might send two
- // notifications with state == eAdd back to back. Ignore them
- // until we get an eConsistent notification.
- if (!(m_previous.state == eConsistent || (m_previous.state == eAdd && m_current.state == eDelete)))
- return false;
-
- m_soentries.clear();
- if (fromRemote)
- return SaveSOEntriesFromRemote(module_list);
-
- m_added_soentries.clear();
- m_removed_soentries.clear();
- return TakeSnapshot(m_soentries);
- }
- assert(m_current.state == eConsistent);
+ entry.file_spec.SetFile(name, false);
- // Otherwise check the previous state to determine what to expect and update
- // accordingly.
- if (m_previous.state == eAdd)
- return fromRemote ? AddSOEntriesFromRemote(module_list) : AddSOEntries();
- else if (m_previous.state == eDelete)
- return fromRemote ? RemoveSOEntriesFromRemote(module_list) : RemoveSOEntries();
+ UpdateBaseAddrIfNecessary(entry, name);
- return false;
+ // not needed if we're using ModuleInfos
+ entry.next = 0;
+ entry.prev = 0;
+ entry.path_addr = 0;
+
+ return true;
}
-bool
-DYLDRendezvous::FillSOEntryFromModuleInfo (LoadedModuleInfoList::LoadedModuleInfo const & modInfo,
- SOEntry &entry)
-{
- addr_t link_map_addr;
- addr_t base_addr;
- addr_t dyn_addr;
- std::string name;
-
- if (!modInfo.get_link_map (link_map_addr) ||
- !modInfo.get_base (base_addr) ||
- !modInfo.get_dynamic (dyn_addr) ||
- !modInfo.get_name (name))
- return false;
+bool DYLDRendezvous::SaveSOEntriesFromRemote(
+ LoadedModuleInfoList &module_list) {
+ for (auto const &modInfo : module_list.m_list) {
+ SOEntry entry;
+ if (!FillSOEntryFromModuleInfo(modInfo, entry))
+ return false;
- entry.link_addr = link_map_addr;
- entry.base_addr = base_addr;
- entry.dyn_addr = dyn_addr;
+ // Only add shared libraries and not the executable.
+ if (!SOEntryIsMainExecutable(entry))
+ m_soentries.push_back(entry);
+ }
- entry.file_spec.SetFile(name, false);
+ m_loaded_modules = module_list;
+ return true;
+}
- UpdateBaseAddrIfNecessary(entry, name);
+bool DYLDRendezvous::AddSOEntriesFromRemote(LoadedModuleInfoList &module_list) {
+ for (auto const &modInfo : module_list.m_list) {
+ bool found = false;
+ for (auto const &existing : m_loaded_modules.m_list) {
+ if (modInfo == existing) {
+ found = true;
+ break;
+ }
+ }
- // not needed if we're using ModuleInfos
- entry.next = 0;
- entry.prev = 0;
- entry.path_addr = 0;
+ if (found)
+ continue;
- return true;
+ SOEntry entry;
+ if (!FillSOEntryFromModuleInfo(modInfo, entry))
+ return false;
+
+ // Only add shared libraries and not the executable.
+ if (!SOEntryIsMainExecutable(entry))
+ m_soentries.push_back(entry);
+ }
+
+ m_loaded_modules = module_list;
+ return true;
}
-bool
-DYLDRendezvous::SaveSOEntriesFromRemote(LoadedModuleInfoList &module_list)
-{
- for (auto const & modInfo : module_list.m_list)
- {
- SOEntry entry;
- if (!FillSOEntryFromModuleInfo(modInfo, entry))
- return false;
-
- // Only add shared libraries and not the executable.
- if (!SOEntryIsMainExecutable(entry))
- m_soentries.push_back(entry);
+bool DYLDRendezvous::RemoveSOEntriesFromRemote(
+ LoadedModuleInfoList &module_list) {
+ for (auto const &existing : m_loaded_modules.m_list) {
+ bool found = false;
+ for (auto const &modInfo : module_list.m_list) {
+ if (modInfo == existing) {
+ found = true;
+ break;
+ }
}
- m_loaded_modules = module_list;
- return true;
+ if (found)
+ continue;
-}
+ SOEntry entry;
+ if (!FillSOEntryFromModuleInfo(existing, entry))
+ return false;
+
+ // Only add shared libraries and not the executable.
+ if (!SOEntryIsMainExecutable(entry)) {
+ auto pos = std::find(m_soentries.begin(), m_soentries.end(), entry);
+ if (pos == m_soentries.end())
+ return false;
-bool
-DYLDRendezvous::AddSOEntriesFromRemote(LoadedModuleInfoList &module_list)
-{
- for (auto const & modInfo : module_list.m_list)
- {
- bool found = false;
- for (auto const & existing : m_loaded_modules.m_list)
- {
- if (modInfo == existing)
- {
- found = true;
- break;
- }
- }
-
- if (found)
- continue;
-
- SOEntry entry;
- if (!FillSOEntryFromModuleInfo(modInfo, entry))
- return false;
-
- // Only add shared libraries and not the executable.
- if (!SOEntryIsMainExecutable(entry))
- m_soentries.push_back(entry);
+ m_soentries.erase(pos);
}
+ }
- m_loaded_modules = module_list;
- return true;
+ m_loaded_modules = module_list;
+ return true;
}
-bool
-DYLDRendezvous::RemoveSOEntriesFromRemote(LoadedModuleInfoList &module_list)
-{
- for (auto const & existing : m_loaded_modules.m_list)
- {
- bool found = false;
- for (auto const & modInfo : module_list.m_list)
- {
- if (modInfo == existing)
- {
- found = true;
- break;
- }
- }
-
- if (found)
- continue;
-
- SOEntry entry;
- if (!FillSOEntryFromModuleInfo(existing, entry))
- return false;
-
- // Only add shared libraries and not the executable.
- if (!SOEntryIsMainExecutable(entry))
- {
- auto pos = std::find(m_soentries.begin(), m_soentries.end(), entry);
- if (pos == m_soentries.end())
- return false;
-
- m_soentries.erase(pos);
- }
- }
+bool DYLDRendezvous::AddSOEntries() {
+ SOEntry entry;
+ iterator pos;
- m_loaded_modules = module_list;
- return true;
-}
+ assert(m_previous.state == eAdd);
-bool
-DYLDRendezvous::AddSOEntries()
-{
- SOEntry entry;
- iterator pos;
+ if (m_current.map_addr == 0)
+ return false;
- assert(m_previous.state == eAdd);
+ for (addr_t cursor = m_current.map_addr; cursor != 0; cursor = entry.next) {
+ if (!ReadSOEntryFromMemory(cursor, entry))
+ return false;
- if (m_current.map_addr == 0)
- return false;
+ // Only add shared libraries and not the executable.
+ if (SOEntryIsMainExecutable(entry))
+ continue;
- for (addr_t cursor = m_current.map_addr; cursor != 0; cursor = entry.next)
- {
- if (!ReadSOEntryFromMemory(cursor, entry))
- return false;
-
- // Only add shared libraries and not the executable.
- if (SOEntryIsMainExecutable(entry))
- continue;
-
- pos = std::find(m_soentries.begin(), m_soentries.end(), entry);
- if (pos == m_soentries.end())
- {
- m_soentries.push_back(entry);
- m_added_soentries.push_back(entry);
- }
+ pos = std::find(m_soentries.begin(), m_soentries.end(), entry);
+ if (pos == m_soentries.end()) {
+ m_soentries.push_back(entry);
+ m_added_soentries.push_back(entry);
}
+ }
- return true;
+ return true;
}
-bool
-DYLDRendezvous::RemoveSOEntries()
-{
- SOEntryList entry_list;
- iterator pos;
+bool DYLDRendezvous::RemoveSOEntries() {
+ SOEntryList entry_list;
+ iterator pos;
- assert(m_previous.state == eDelete);
+ assert(m_previous.state == eDelete);
- if (!TakeSnapshot(entry_list))
- return false;
+ if (!TakeSnapshot(entry_list))
+ return false;
- for (iterator I = begin(); I != end(); ++I)
- {
- pos = std::find(entry_list.begin(), entry_list.end(), *I);
- if (pos == entry_list.end())
- m_removed_soentries.push_back(*I);
- }
+ for (iterator I = begin(); I != end(); ++I) {
+ pos = std::find(entry_list.begin(), entry_list.end(), *I);
+ if (pos == entry_list.end())
+ m_removed_soentries.push_back(*I);
+ }
- m_soentries = entry_list;
- return true;
+ m_soentries = entry_list;
+ return true;
}
-bool
-DYLDRendezvous::SOEntryIsMainExecutable(const SOEntry &entry)
-{
- // On Linux the executable is indicated by an empty path in the entry. On
- // FreeBSD and on Android it is the full path to the executable.
-
- auto triple = m_process->GetTarget().GetArchitecture().GetTriple();
- switch (triple.getOS())
- {
- case llvm::Triple::FreeBSD:
- return entry.file_spec == m_exe_file_spec;
- case llvm::Triple::Linux:
- if (triple.isAndroid())
- return entry.file_spec == m_exe_file_spec;
- return !entry.file_spec;
- default:
- return false;
- }
+bool DYLDRendezvous::SOEntryIsMainExecutable(const SOEntry &entry) {
+ // On Linux the executable is indicated by an empty path in the entry. On
+ // FreeBSD and on Android it is the full path to the executable.
+
+ auto triple = m_process->GetTarget().GetArchitecture().GetTriple();
+ switch (triple.getOS()) {
+ case llvm::Triple::FreeBSD:
+ return entry.file_spec == m_exe_file_spec;
+ case llvm::Triple::Linux:
+ if (triple.isAndroid())
+ return entry.file_spec == m_exe_file_spec;
+ return !entry.file_spec;
+ default:
+ return false;
+ }
}
-bool
-DYLDRendezvous::TakeSnapshot(SOEntryList &entry_list)
-{
- SOEntry entry;
+bool DYLDRendezvous::TakeSnapshot(SOEntryList &entry_list) {
+ SOEntry entry;
- if (m_current.map_addr == 0)
- return false;
+ if (m_current.map_addr == 0)
+ return false;
- // Clear previous entries since we are about to obtain an up to date list.
- entry_list.clear();
+ // Clear previous entries since we are about to obtain an up to date list.
+ entry_list.clear();
- for (addr_t cursor = m_current.map_addr; cursor != 0; cursor = entry.next)
- {
- if (!ReadSOEntryFromMemory(cursor, entry))
- return false;
+ for (addr_t cursor = m_current.map_addr; cursor != 0; cursor = entry.next) {
+ if (!ReadSOEntryFromMemory(cursor, entry))
+ return false;
- // Only add shared libraries and not the executable.
- if (SOEntryIsMainExecutable(entry))
- continue;
+ // Only add shared libraries and not the executable.
+ if (SOEntryIsMainExecutable(entry))
+ continue;
- entry_list.push_back(entry);
- }
+ entry_list.push_back(entry);
+ }
- return true;
+ return true;
}
-addr_t
-DYLDRendezvous::ReadWord(addr_t addr, uint64_t *dst, size_t size)
-{
- Error error;
+addr_t DYLDRendezvous::ReadWord(addr_t addr, uint64_t *dst, size_t size) {
+ Error error;
- *dst = m_process->ReadUnsignedIntegerFromMemory(addr, size, 0, error);
- if (error.Fail())
- return 0;
+ *dst = m_process->ReadUnsignedIntegerFromMemory(addr, size, 0, error);
+ if (error.Fail())
+ return 0;
- return addr + size;
+ return addr + size;
}
-addr_t
-DYLDRendezvous::ReadPointer(addr_t addr, addr_t *dst)
-{
- Error error;
-
- *dst = m_process->ReadPointerFromMemory(addr, error);
- if (error.Fail())
- return 0;
+addr_t DYLDRendezvous::ReadPointer(addr_t addr, addr_t *dst) {
+ Error error;
- return addr + m_process->GetAddressByteSize();
+ *dst = m_process->ReadPointerFromMemory(addr, error);
+ if (error.Fail())
+ return 0;
+
+ return addr + m_process->GetAddressByteSize();
}
-std::string
-DYLDRendezvous::ReadStringFromMemory(addr_t addr)
-{
- std::string str;
- Error error;
+std::string DYLDRendezvous::ReadStringFromMemory(addr_t addr) {
+ std::string str;
+ Error error;
- if (addr == LLDB_INVALID_ADDRESS)
- return std::string();
+ if (addr == LLDB_INVALID_ADDRESS)
+ return std::string();
- m_process->ReadCStringFromMemory(addr, str, error);
+ m_process->ReadCStringFromMemory(addr, str, error);
- return str;
+ return str;
}
-// Returns true if the load bias reported by the linker is incorrect for the given entry. This
-// function is used to handle cases where we want to work around a bug in the system linker.
-static bool
-isLoadBiasIncorrect(Target& target, const std::string& file_path)
-{
- // On Android L (API 21, 22) the load address of the "/system/bin/linker" isn't filled in
- // correctly.
- uint32_t os_major = 0, os_minor = 0, os_update = 0;
- if (target.GetArchitecture().GetTriple().isAndroid() &&
- target.GetPlatform()->GetOSVersion(os_major, os_minor, os_update) &&
- (os_major == 21 || os_major == 22) &&
- (file_path == "/system/bin/linker" || file_path == "/system/bin/linker64"))
- {
- return true;
- }
+// Returns true if the load bias reported by the linker is incorrect for the
+// given entry. This
+// function is used to handle cases where we want to work around a bug in the
+// system linker.
+static bool isLoadBiasIncorrect(Target &target, const std::string &file_path) {
+ // On Android L (API 21, 22) the load address of the "/system/bin/linker"
+ // isn't filled in
+ // correctly.
+ uint32_t os_major = 0, os_minor = 0, os_update = 0;
+ if (target.GetArchitecture().GetTriple().isAndroid() &&
+ target.GetPlatform()->GetOSVersion(os_major, os_minor, os_update) &&
+ (os_major == 21 || os_major == 22) &&
+ (file_path == "/system/bin/linker" ||
+ file_path == "/system/bin/linker64")) {
+ return true;
+ }
- return false;
+ return false;
}
-void
-DYLDRendezvous::UpdateBaseAddrIfNecessary(SOEntry &entry, std::string const &file_path)
-{
- // If the load bias reported by the linker is incorrect then fetch the load address of the file
- // from the proc file system.
- if (isLoadBiasIncorrect(m_process->GetTarget(), file_path))
- {
- lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
- bool is_loaded = false;
- Error error = m_process->GetFileLoadAddress(entry.file_spec, is_loaded, load_addr);
- if (error.Success() && is_loaded)
- entry.base_addr = load_addr;
- }
+void DYLDRendezvous::UpdateBaseAddrIfNecessary(SOEntry &entry,
+ std::string const &file_path) {
+ // If the load bias reported by the linker is incorrect then fetch the load
+ // address of the file
+ // from the proc file system.
+ if (isLoadBiasIncorrect(m_process->GetTarget(), file_path)) {
+ lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
+ bool is_loaded = false;
+ Error error =
+ m_process->GetFileLoadAddress(entry.file_spec, is_loaded, load_addr);
+ if (error.Success() && is_loaded)
+ entry.base_addr = load_addr;
+ }
}
-bool
-DYLDRendezvous::ReadSOEntryFromMemory(lldb::addr_t addr, SOEntry &entry)
-{
- entry.clear();
+bool DYLDRendezvous::ReadSOEntryFromMemory(lldb::addr_t addr, SOEntry &entry) {
+ entry.clear();
- entry.link_addr = addr;
-
- if (!(addr = ReadPointer(addr, &entry.base_addr)))
- return false;
+ entry.link_addr = addr;
- // mips adds an extra load offset field to the link map struct on
- // FreeBSD and NetBSD (need to validate other OSes).
- // http://svnweb.freebsd.org/base/head/sys/sys/link_elf.h?revision=217153&view=markup#l57
- const ArchSpec &arch = m_process->GetTarget().GetArchitecture();
- if ((arch.GetTriple().getOS() == llvm::Triple::FreeBSD
- || arch.GetTriple().getOS() == llvm::Triple::NetBSD) &&
- (arch.GetMachine() == llvm::Triple::mips || arch.GetMachine() == llvm::Triple::mipsel
- || arch.GetMachine() == llvm::Triple::mips64 || arch.GetMachine() == llvm::Triple::mips64el))
- {
- addr_t mips_l_offs;
- if (!(addr = ReadPointer(addr, &mips_l_offs)))
- return false;
- if (mips_l_offs != 0 && mips_l_offs != entry.base_addr)
- return false;
- }
-
- if (!(addr = ReadPointer(addr, &entry.path_addr)))
- return false;
-
- if (!(addr = ReadPointer(addr, &entry.dyn_addr)))
- return false;
-
- if (!(addr = ReadPointer(addr, &entry.next)))
- return false;
-
- if (!(addr = ReadPointer(addr, &entry.prev)))
- return false;
+ if (!(addr = ReadPointer(addr, &entry.base_addr)))
+ return false;
- std::string file_path = ReadStringFromMemory(entry.path_addr);
- entry.file_spec.SetFile(file_path, false);
+ // mips adds an extra load offset field to the link map struct on
+ // FreeBSD and NetBSD (need to validate other OSes).
+ // http://svnweb.freebsd.org/base/head/sys/sys/link_elf.h?revision=217153&view=markup#l57
+ const ArchSpec &arch = m_process->GetTarget().GetArchitecture();
+ if ((arch.GetTriple().getOS() == llvm::Triple::FreeBSD ||
+ arch.GetTriple().getOS() == llvm::Triple::NetBSD) &&
+ (arch.GetMachine() == llvm::Triple::mips ||
+ arch.GetMachine() == llvm::Triple::mipsel ||
+ arch.GetMachine() == llvm::Triple::mips64 ||
+ arch.GetMachine() == llvm::Triple::mips64el)) {
+ addr_t mips_l_offs;
+ if (!(addr = ReadPointer(addr, &mips_l_offs)))
+ return false;
+ if (mips_l_offs != 0 && mips_l_offs != entry.base_addr)
+ return false;
+ }
+
+ if (!(addr = ReadPointer(addr, &entry.path_addr)))
+ return false;
- UpdateBaseAddrIfNecessary(entry, file_path);
+ if (!(addr = ReadPointer(addr, &entry.dyn_addr)))
+ return false;
- return true;
-}
+ if (!(addr = ReadPointer(addr, &entry.next)))
+ return false;
+ if (!(addr = ReadPointer(addr, &entry.prev)))
+ return false;
-bool
-DYLDRendezvous::FindMetadata(const char *name, PThreadField field, uint32_t& value)
-{
- Target& target = m_process->GetTarget();
+ std::string file_path = ReadStringFromMemory(entry.path_addr);
+ entry.file_spec.SetFile(file_path, false);
- SymbolContextList list;
- if (!target.GetImages().FindSymbolsWithNameAndType (ConstString(name), eSymbolTypeAny, list))
- return false;
+ UpdateBaseAddrIfNecessary(entry, file_path);
- Address address = list[0].symbol->GetAddress();
- addr_t addr = address.GetLoadAddress (&target);
- if (addr == LLDB_INVALID_ADDRESS)
- return false;
+ return true;
+}
- Error error;
- value = (uint32_t)m_process->ReadUnsignedIntegerFromMemory(addr + field*sizeof(uint32_t), sizeof(uint32_t), 0, error);
- if (error.Fail())
- return false;
+bool DYLDRendezvous::FindMetadata(const char *name, PThreadField field,
+ uint32_t &value) {
+ Target &target = m_process->GetTarget();
- if (field == eSize)
- value /= 8; // convert bits to bytes
+ SymbolContextList list;
+ if (!target.GetImages().FindSymbolsWithNameAndType(ConstString(name),
+ eSymbolTypeAny, list))
+ return false;
- return true;
+ Address address = list[0].symbol->GetAddress();
+ addr_t addr = address.GetLoadAddress(&target);
+ if (addr == LLDB_INVALID_ADDRESS)
+ return false;
+
+ Error error;
+ value = (uint32_t)m_process->ReadUnsignedIntegerFromMemory(
+ addr + field * sizeof(uint32_t), sizeof(uint32_t), 0, error);
+ if (error.Fail())
+ return false;
+
+ if (field == eSize)
+ value /= 8; // convert bits to bytes
+
+ return true;
}
-const DYLDRendezvous::ThreadInfo&
-DYLDRendezvous::GetThreadInfo()
-{
- if (!m_thread_info.valid)
- {
- bool ok = true;
+const DYLDRendezvous::ThreadInfo &DYLDRendezvous::GetThreadInfo() {
+ if (!m_thread_info.valid) {
+ bool ok = true;
- ok &= FindMetadata ("_thread_db_pthread_dtvp", eOffset, m_thread_info.dtv_offset);
- ok &= FindMetadata ("_thread_db_dtv_dtv", eSize, m_thread_info.dtv_slot_size);
- ok &= FindMetadata ("_thread_db_link_map_l_tls_modid", eOffset, m_thread_info.modid_offset);
- ok &= FindMetadata ("_thread_db_dtv_t_pointer_val", eOffset, m_thread_info.tls_offset);
+ ok &= FindMetadata("_thread_db_pthread_dtvp", eOffset,
+ m_thread_info.dtv_offset);
+ ok &=
+ FindMetadata("_thread_db_dtv_dtv", eSize, m_thread_info.dtv_slot_size);
+ ok &= FindMetadata("_thread_db_link_map_l_tls_modid", eOffset,
+ m_thread_info.modid_offset);
+ ok &= FindMetadata("_thread_db_dtv_t_pointer_val", eOffset,
+ m_thread_info.tls_offset);
- if (ok)
- m_thread_info.valid = true;
- }
+ if (ok)
+ m_thread_info.valid = true;
+ }
- return m_thread_info;
+ return m_thread_info;
}
-void
-DYLDRendezvous::DumpToLog(Log *log) const
-{
- int state = GetState();
-
- if (!log)
- return;
-
- log->PutCString("DYLDRendezvous:");
- log->Printf(" Address: %" PRIx64, GetRendezvousAddress());
- log->Printf(" Version: %" PRIu64, GetVersion());
- log->Printf(" Link : %" PRIx64, GetLinkMapAddress());
- log->Printf(" Break : %" PRIx64, GetBreakAddress());
- log->Printf(" LDBase : %" PRIx64, GetLDBase());
- log->Printf(" State : %s",
- (state == eConsistent) ? "consistent" :
- (state == eAdd) ? "add" :
- (state == eDelete) ? "delete" : "unknown");
-
- iterator I = begin();
- iterator E = end();
-
- if (I != E)
- log->PutCString("DYLDRendezvous SOEntries:");
-
- for (int i = 1; I != E; ++I, ++i)
- {
- log->Printf("\n SOEntry [%d] %s", i, I->file_spec.GetCString());
- log->Printf(" Base : %" PRIx64, I->base_addr);
- log->Printf(" Path : %" PRIx64, I->path_addr);
- log->Printf(" Dyn : %" PRIx64, I->dyn_addr);
- log->Printf(" Next : %" PRIx64, I->next);
- log->Printf(" Prev : %" PRIx64, I->prev);
- }
+void DYLDRendezvous::DumpToLog(Log *log) const {
+ int state = GetState();
+
+ if (!log)
+ return;
+
+ log->PutCString("DYLDRendezvous:");
+ log->Printf(" Address: %" PRIx64, GetRendezvousAddress());
+ log->Printf(" Version: %" PRIu64, GetVersion());
+ log->Printf(" Link : %" PRIx64, GetLinkMapAddress());
+ log->Printf(" Break : %" PRIx64, GetBreakAddress());
+ log->Printf(" LDBase : %" PRIx64, GetLDBase());
+ log->Printf(" State : %s",
+ (state == eConsistent)
+ ? "consistent"
+ : (state == eAdd) ? "add" : (state == eDelete) ? "delete"
+ : "unknown");
+
+ iterator I = begin();
+ iterator E = end();
+
+ if (I != E)
+ log->PutCString("DYLDRendezvous SOEntries:");
+
+ for (int i = 1; I != E; ++I, ++i) {
+ log->Printf("\n SOEntry [%d] %s", i, I->file_spec.GetCString());
+ log->Printf(" Base : %" PRIx64, I->base_addr);
+ log->Printf(" Path : %" PRIx64, I->path_addr);
+ log->Printf(" Dyn : %" PRIx64, I->dyn_addr);
+ log->Printf(" Next : %" PRIx64, I->next);
+ log->Printf(" Prev : %" PRIx64, I->prev);
+ }
}
diff --git a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h
index 8498116c808..55b8bd7fb49 100644
--- a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h
+++ b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h
@@ -16,9 +16,9 @@
#include <string>
// Other libraries and framework includes
+#include "lldb/Host/FileSpec.h"
#include "lldb/lldb-defines.h"
#include "lldb/lldb-types.h"
-#include "lldb/Host/FileSpec.h"
#include "lldb/Core/LoadedModuleInfoList.h"
@@ -37,251 +37,220 @@ class Process;
/// currently loaded modules.
class DYLDRendezvous {
- // This structure is used to hold the contents of the debug rendezvous
- // information (struct r_debug) as found in the inferiors memory. Note that
- // the layout of this struct is not binary compatible, it is simply large
- // enough to hold the information on both 32 and 64 bit platforms.
- struct Rendezvous {
- uint64_t version;
- lldb::addr_t map_addr;
- lldb::addr_t brk;
- uint64_t state;
- lldb::addr_t ldbase;
-
- Rendezvous()
- : version(0), map_addr(0), brk(0), state(0), ldbase(0) { }
- };
+ // This structure is used to hold the contents of the debug rendezvous
+ // information (struct r_debug) as found in the inferiors memory. Note that
+ // the layout of this struct is not binary compatible, it is simply large
+ // enough to hold the information on both 32 and 64 bit platforms.
+ struct Rendezvous {
+ uint64_t version;
+ lldb::addr_t map_addr;
+ lldb::addr_t brk;
+ uint64_t state;
+ lldb::addr_t ldbase;
+
+ Rendezvous() : version(0), map_addr(0), brk(0), state(0), ldbase(0) {}
+ };
public:
- // Various metadata supplied by the inferior's threading library to describe
- // the per-thread state.
- struct ThreadInfo {
- bool valid; // whether we read valid metadata
- uint32_t dtv_offset; // offset of DTV pointer within pthread
- uint32_t dtv_slot_size; // size of one DTV slot
- uint32_t modid_offset; // offset of module ID within link_map
- uint32_t tls_offset; // offset of TLS pointer within DTV slot
- };
-
- DYLDRendezvous(lldb_private::Process *process);
-
- /// Update the internal snapshot of runtime linker rendezvous and recompute
- /// the currently loaded modules.
- ///
- /// This method should be called once one start up, then once each time the
- /// runtime linker enters the function given by GetBreakAddress().
- ///
- /// @returns true on success and false on failure.
- ///
- /// @see GetBreakAddress().
- bool
- Resolve();
-
- /// @returns true if this rendezvous has been located in the inferiors
- /// address space and false otherwise.
- bool
- IsValid();
-
- /// @returns the address of the rendezvous structure in the inferiors
- /// address space.
- lldb::addr_t
- GetRendezvousAddress() const { return m_rendezvous_addr; }
-
- /// @returns the version of the rendezvous protocol being used.
- uint64_t
- GetVersion() const { return m_current.version; }
-
- /// @returns address in the inferiors address space containing the linked
- /// list of shared object descriptors.
- lldb::addr_t
- GetLinkMapAddress() const { return m_current.map_addr; }
-
- /// A breakpoint should be set at this address and Resolve called on each
- /// hit.
- ///
- /// @returns the address of a function called by the runtime linker each
- /// time a module is loaded/unloaded, or about to be loaded/unloaded.
- ///
- /// @see Resolve()
- lldb::addr_t
- GetBreakAddress() const { return m_current.brk; }
-
- /// Returns the current state of the rendezvous structure.
- uint64_t
- GetState() const { return m_current.state; }
-
- /// @returns the base address of the runtime linker in the inferiors address
- /// space.
- lldb::addr_t
- GetLDBase() const { return m_current.ldbase; }
-
- /// @returns the thread layout metadata from the inferiors thread library.
- const ThreadInfo&
- GetThreadInfo();
-
- /// @returns true if modules have been loaded into the inferior since the
- /// last call to Resolve().
- bool
- ModulesDidLoad() const { return !m_added_soentries.empty(); }
-
- /// @returns true if modules have been unloaded from the inferior since the
- /// last call to Resolve().
- bool
- ModulesDidUnload() const { return !m_removed_soentries.empty(); }
-
- void
- DumpToLog(lldb_private::Log *log) const;
-
- /// @brief Constants describing the state of the rendezvous.
- ///
- /// @see GetState().
- enum RendezvousState {
- eConsistent,
- eAdd,
- eDelete
- };
-
- /// @brief Structure representing the shared objects currently loaded into
- /// the inferior process.
- ///
- /// This object is a rough analogue to the struct link_map object which
- /// actually lives in the inferiors memory.
- struct SOEntry {
- lldb::addr_t link_addr; ///< Address of this link_map.
- lldb::addr_t base_addr; ///< Base address of the loaded object.
- lldb::addr_t path_addr; ///< String naming the shared object.
- lldb::addr_t dyn_addr; ///< Dynamic section of shared object.
- lldb::addr_t next; ///< Address of next so_entry.
- lldb::addr_t prev; ///< Address of previous so_entry.
- lldb_private::FileSpec file_spec; ///< File spec of shared object.
-
- SOEntry() { clear(); }
-
- bool operator ==(const SOEntry &entry) {
- return file_spec == entry.file_spec;
- }
-
- void clear() {
- link_addr = 0;
- base_addr = 0;
- path_addr = 0;
- dyn_addr = 0;
- next = 0;
- prev = 0;
- file_spec.Clear();
- }
- };
+ // Various metadata supplied by the inferior's threading library to describe
+ // the per-thread state.
+ struct ThreadInfo {
+ bool valid; // whether we read valid metadata
+ uint32_t dtv_offset; // offset of DTV pointer within pthread
+ uint32_t dtv_slot_size; // size of one DTV slot
+ uint32_t modid_offset; // offset of module ID within link_map
+ uint32_t tls_offset; // offset of TLS pointer within DTV slot
+ };
+
+ DYLDRendezvous(lldb_private::Process *process);
+
+ /// Update the internal snapshot of runtime linker rendezvous and recompute
+ /// the currently loaded modules.
+ ///
+ /// This method should be called once one start up, then once each time the
+ /// runtime linker enters the function given by GetBreakAddress().
+ ///
+ /// @returns true on success and false on failure.
+ ///
+ /// @see GetBreakAddress().
+ bool Resolve();
+
+ /// @returns true if this rendezvous has been located in the inferiors
+ /// address space and false otherwise.
+ bool IsValid();
+
+ /// @returns the address of the rendezvous structure in the inferiors
+ /// address space.
+ lldb::addr_t GetRendezvousAddress() const { return m_rendezvous_addr; }
+
+ /// @returns the version of the rendezvous protocol being used.
+ uint64_t GetVersion() const { return m_current.version; }
+
+ /// @returns address in the inferiors address space containing the linked
+ /// list of shared object descriptors.
+ lldb::addr_t GetLinkMapAddress() const { return m_current.map_addr; }
+
+ /// A breakpoint should be set at this address and Resolve called on each
+ /// hit.
+ ///
+ /// @returns the address of a function called by the runtime linker each
+ /// time a module is loaded/unloaded, or about to be loaded/unloaded.
+ ///
+ /// @see Resolve()
+ lldb::addr_t GetBreakAddress() const { return m_current.brk; }
+
+ /// Returns the current state of the rendezvous structure.
+ uint64_t GetState() const { return m_current.state; }
+
+ /// @returns the base address of the runtime linker in the inferiors address
+ /// space.
+ lldb::addr_t GetLDBase() const { return m_current.ldbase; }
+
+ /// @returns the thread layout metadata from the inferiors thread library.
+ const ThreadInfo &GetThreadInfo();
+
+ /// @returns true if modules have been loaded into the inferior since the
+ /// last call to Resolve().
+ bool ModulesDidLoad() const { return !m_added_soentries.empty(); }
+
+ /// @returns true if modules have been unloaded from the inferior since the
+ /// last call to Resolve().
+ bool ModulesDidUnload() const { return !m_removed_soentries.empty(); }
+
+ void DumpToLog(lldb_private::Log *log) const;
+
+ /// @brief Constants describing the state of the rendezvous.
+ ///
+ /// @see GetState().
+ enum RendezvousState { eConsistent, eAdd, eDelete };
+
+ /// @brief Structure representing the shared objects currently loaded into
+ /// the inferior process.
+ ///
+ /// This object is a rough analogue to the struct link_map object which
+ /// actually lives in the inferiors memory.
+ struct SOEntry {
+ lldb::addr_t link_addr; ///< Address of this link_map.
+ lldb::addr_t base_addr; ///< Base address of the loaded object.
+ lldb::addr_t path_addr; ///< String naming the shared object.
+ lldb::addr_t dyn_addr; ///< Dynamic section of shared object.
+ lldb::addr_t next; ///< Address of next so_entry.
+ lldb::addr_t prev; ///< Address of previous so_entry.
+ lldb_private::FileSpec file_spec; ///< File spec of shared object.
+
+ SOEntry() { clear(); }
+
+ bool operator==(const SOEntry &entry) {
+ return file_spec == entry.file_spec;
+ }
+
+ void clear() {
+ link_addr = 0;
+ base_addr = 0;
+ path_addr = 0;
+ dyn_addr = 0;
+ next = 0;
+ prev = 0;
+ file_spec.Clear();
+ }
+ };
protected:
- typedef std::list<SOEntry> SOEntryList;
+ typedef std::list<SOEntry> SOEntryList;
public:
- typedef SOEntryList::const_iterator iterator;
-
- /// Iterators over all currently loaded modules.
- iterator begin() const { return m_soentries.begin(); }
- iterator end() const { return m_soentries.end(); }
-
- /// Iterators over all modules loaded into the inferior since the last call
- /// to Resolve().
- iterator loaded_begin() const { return m_added_soentries.begin(); }
- iterator loaded_end() const { return m_added_soentries.end(); }
-
- /// Iterators over all modules unloaded from the inferior since the last
- /// call to Resolve().
- iterator unloaded_begin() const { return m_removed_soentries.begin(); }
- iterator unloaded_end() const { return m_removed_soentries.end(); }
-
+ typedef SOEntryList::const_iterator iterator;
+
+ /// Iterators over all currently loaded modules.
+ iterator begin() const { return m_soentries.begin(); }
+ iterator end() const { return m_soentries.end(); }
+
+ /// Iterators over all modules loaded into the inferior since the last call
+ /// to Resolve().
+ iterator loaded_begin() const { return m_added_soentries.begin(); }
+ iterator loaded_end() const { return m_added_soentries.end(); }
+
+ /// Iterators over all modules unloaded from the inferior since the last
+ /// call to Resolve().
+ iterator unloaded_begin() const { return m_removed_soentries.begin(); }
+ iterator unloaded_end() const { return m_removed_soentries.end(); }
+
protected:
- lldb_private::Process *m_process;
+ lldb_private::Process *m_process;
- // Cached copy of executable file spec
- lldb_private::FileSpec m_exe_file_spec;
+ // Cached copy of executable file spec
+ lldb_private::FileSpec m_exe_file_spec;
- /// Location of the r_debug structure in the inferiors address space.
- lldb::addr_t m_rendezvous_addr;
+ /// Location of the r_debug structure in the inferiors address space.
+ lldb::addr_t m_rendezvous_addr;
- /// Current and previous snapshots of the rendezvous structure.
- Rendezvous m_current;
- Rendezvous m_previous;
+ /// Current and previous snapshots of the rendezvous structure.
+ Rendezvous m_current;
+ Rendezvous m_previous;
- /// List of currently loaded SO modules
- LoadedModuleInfoList m_loaded_modules;
+ /// List of currently loaded SO modules
+ LoadedModuleInfoList m_loaded_modules;
- /// List of SOEntry objects corresponding to the current link map state.
- SOEntryList m_soentries;
+ /// List of SOEntry objects corresponding to the current link map state.
+ SOEntryList m_soentries;
- /// List of SOEntry's added to the link map since the last call to Resolve().
- SOEntryList m_added_soentries;
+ /// List of SOEntry's added to the link map since the last call to Resolve().
+ SOEntryList m_added_soentries;
- /// List of SOEntry's removed from the link map since the last call to
- /// Resolve().
- SOEntryList m_removed_soentries;
+ /// List of SOEntry's removed from the link map since the last call to
+ /// Resolve().
+ SOEntryList m_removed_soentries;
- /// Threading metadata read from the inferior.
- ThreadInfo m_thread_info;
+ /// Threading metadata read from the inferior.
+ ThreadInfo m_thread_info;
- /// Reads an unsigned integer of @p size bytes from the inferior's address
- /// space starting at @p addr.
- ///
- /// @returns addr + size if the read was successful and false otherwise.
- lldb::addr_t
- ReadWord(lldb::addr_t addr, uint64_t *dst, size_t size);
+ /// Reads an unsigned integer of @p size bytes from the inferior's address
+ /// space starting at @p addr.
+ ///
+ /// @returns addr + size if the read was successful and false otherwise.
+ lldb::addr_t ReadWord(lldb::addr_t addr, uint64_t *dst, size_t size);
- /// Reads an address from the inferior's address space starting at @p addr.
- ///
- /// @returns addr + target address size if the read was successful and
- /// 0 otherwise.
- lldb::addr_t
- ReadPointer(lldb::addr_t addr, lldb::addr_t *dst);
+ /// Reads an address from the inferior's address space starting at @p addr.
+ ///
+ /// @returns addr + target address size if the read was successful and
+ /// 0 otherwise.
+ lldb::addr_t ReadPointer(lldb::addr_t addr, lldb::addr_t *dst);
- /// Reads a null-terminated C string from the memory location starting at @p
- /// addr.
- std::string
- ReadStringFromMemory(lldb::addr_t addr);
+ /// Reads a null-terminated C string from the memory location starting at @p
+ /// addr.
+ std::string ReadStringFromMemory(lldb::addr_t addr);
- /// Reads an SOEntry starting at @p addr.
- bool
- ReadSOEntryFromMemory(lldb::addr_t addr, SOEntry &entry);
+ /// Reads an SOEntry starting at @p addr.
+ bool ReadSOEntryFromMemory(lldb::addr_t addr, SOEntry &entry);
- /// Updates the current set of SOEntries, the set of added entries, and the
- /// set of removed entries.
- bool
- UpdateSOEntries(bool fromRemote = false);
+ /// Updates the current set of SOEntries, the set of added entries, and the
+ /// set of removed entries.
+ bool UpdateSOEntries(bool fromRemote = false);
- bool
- FillSOEntryFromModuleInfo (LoadedModuleInfoList::LoadedModuleInfo const & modInfo,
- SOEntry &entry);
+ bool FillSOEntryFromModuleInfo(
+ LoadedModuleInfoList::LoadedModuleInfo const &modInfo, SOEntry &entry);
- bool
- SaveSOEntriesFromRemote(LoadedModuleInfoList &module_list);
+ bool SaveSOEntriesFromRemote(LoadedModuleInfoList &module_list);
- bool
- AddSOEntriesFromRemote(LoadedModuleInfoList &module_list);
+ bool AddSOEntriesFromRemote(LoadedModuleInfoList &module_list);
- bool
- RemoveSOEntriesFromRemote(LoadedModuleInfoList &module_list);
+ bool RemoveSOEntriesFromRemote(LoadedModuleInfoList &module_list);
- bool
- AddSOEntries();
+ bool AddSOEntries();
- bool
- RemoveSOEntries();
+ bool RemoveSOEntries();
- void
- UpdateBaseAddrIfNecessary(SOEntry &entry, std::string const &file_path);
+ void UpdateBaseAddrIfNecessary(SOEntry &entry, std::string const &file_path);
- bool
- SOEntryIsMainExecutable(const SOEntry &entry);
+ bool SOEntryIsMainExecutable(const SOEntry &entry);
- /// Reads the current list of shared objects according to the link map
- /// supplied by the runtime linker.
- bool
- TakeSnapshot(SOEntryList &entry_list);
+ /// Reads the current list of shared objects according to the link map
+ /// supplied by the runtime linker.
+ bool TakeSnapshot(SOEntryList &entry_list);
- enum PThreadField { eSize, eNElem, eOffset };
+ enum PThreadField { eSize, eNElem, eOffset };
- bool FindMetadata(const char *name, PThreadField field, uint32_t& value);
+ bool FindMetadata(const char *name, PThreadField field, uint32_t &value);
};
#endif
diff --git a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
index 772efc17c1e..cb27190cf33 100644
--- a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
+++ b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
@@ -14,19 +14,19 @@
#include "AuxVector.h"
// Other libraries and framework includes
-#include "lldb/Core/PluginManager.h"
+#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
-#include "lldb/Target/Platform.h"
+#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Section.h"
+#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Target/Platform.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadPlanRunToAddress.h"
-#include "lldb/Breakpoint/BreakpointLocation.h"
-#include "lldb/Symbol/Function.h"
// C++ Includes
// C Includes
@@ -34,258 +34,240 @@
using namespace lldb;
using namespace lldb_private;
-void
-DynamicLoaderPOSIXDYLD::Initialize()
-{
- PluginManager::RegisterPlugin(GetPluginNameStatic(),
- GetPluginDescriptionStatic(),
- CreateInstance);
-}
-
-void
-DynamicLoaderPOSIXDYLD::Terminate()
-{
+void DynamicLoaderPOSIXDYLD::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance);
}
-lldb_private::ConstString
-DynamicLoaderPOSIXDYLD::GetPluginName()
-{
- return GetPluginNameStatic();
-}
+void DynamicLoaderPOSIXDYLD::Terminate() {}
-lldb_private::ConstString
-DynamicLoaderPOSIXDYLD::GetPluginNameStatic()
-{
- static ConstString g_name("linux-dyld");
- return g_name;
+lldb_private::ConstString DynamicLoaderPOSIXDYLD::GetPluginName() {
+ return GetPluginNameStatic();
}
-const char *
-DynamicLoaderPOSIXDYLD::GetPluginDescriptionStatic()
-{
- return "Dynamic loader plug-in that watches for shared library "
- "loads/unloads in POSIX processes.";
+lldb_private::ConstString DynamicLoaderPOSIXDYLD::GetPluginNameStatic() {
+ static ConstString g_name("linux-dyld");
+ return g_name;
}
-uint32_t
-DynamicLoaderPOSIXDYLD::GetPluginVersion()
-{
- return 1;
+const char *DynamicLoaderPOSIXDYLD::GetPluginDescriptionStatic() {
+ return "Dynamic loader plug-in that watches for shared library "
+ "loads/unloads in POSIX processes.";
}
-DynamicLoader *
-DynamicLoaderPOSIXDYLD::CreateInstance(Process *process, bool force)
-{
- bool create = force;
- if (!create)
- {
- const llvm::Triple &triple_ref = process->GetTarget().GetArchitecture().GetTriple();
- if (triple_ref.getOS() == llvm::Triple::Linux ||
- triple_ref.getOS() == llvm::Triple::FreeBSD)
- create = true;
- }
-
- if (create)
- return new DynamicLoaderPOSIXDYLD (process);
- return NULL;
+uint32_t DynamicLoaderPOSIXDYLD::GetPluginVersion() { return 1; }
+
+DynamicLoader *DynamicLoaderPOSIXDYLD::CreateInstance(Process *process,
+ bool force) {
+ bool create = force;
+ if (!create) {
+ const llvm::Triple &triple_ref =
+ process->GetTarget().GetArchitecture().GetTriple();
+ if (triple_ref.getOS() == llvm::Triple::Linux ||
+ triple_ref.getOS() == llvm::Triple::FreeBSD)
+ create = true;
+ }
+
+ if (create)
+ return new DynamicLoaderPOSIXDYLD(process);
+ return NULL;
}
DynamicLoaderPOSIXDYLD::DynamicLoaderPOSIXDYLD(Process *process)
- : DynamicLoader(process),
- m_rendezvous(process),
- m_load_offset(LLDB_INVALID_ADDRESS),
- m_entry_point(LLDB_INVALID_ADDRESS),
- m_auxv(),
- m_dyld_bid(LLDB_INVALID_BREAK_ID),
- m_vdso_base(LLDB_INVALID_ADDRESS)
-{
+ : DynamicLoader(process), m_rendezvous(process),
+ m_load_offset(LLDB_INVALID_ADDRESS), m_entry_point(LLDB_INVALID_ADDRESS),
+ m_auxv(), m_dyld_bid(LLDB_INVALID_BREAK_ID),
+ m_vdso_base(LLDB_INVALID_ADDRESS) {}
+
+DynamicLoaderPOSIXDYLD::~DynamicLoaderPOSIXDYLD() {
+ if (m_dyld_bid != LLDB_INVALID_BREAK_ID) {
+ m_process->GetTarget().RemoveBreakpointByID(m_dyld_bid);
+ m_dyld_bid = LLDB_INVALID_BREAK_ID;
+ }
}
-DynamicLoaderPOSIXDYLD::~DynamicLoaderPOSIXDYLD()
-{
- if (m_dyld_bid != LLDB_INVALID_BREAK_ID)
- {
- m_process->GetTarget().RemoveBreakpointByID (m_dyld_bid);
- m_dyld_bid = LLDB_INVALID_BREAK_ID;
+void DynamicLoaderPOSIXDYLD::DidAttach() {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+ if (log)
+ log->Printf("DynamicLoaderPOSIXDYLD::%s() pid %" PRIu64, __FUNCTION__,
+ m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID);
+
+ m_auxv.reset(new AuxVector(m_process));
+ if (log)
+ log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 " reloaded auxv data",
+ __FUNCTION__,
+ m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID);
+
+ // ask the process if it can load any of its own modules
+ m_process->LoadModules();
+
+ ModuleSP executable_sp = GetTargetExecutable();
+ ResolveExecutableModule(executable_sp);
+
+ // find the main process load offset
+ addr_t load_offset = ComputeLoadOffset();
+ if (log)
+ log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
+ " executable '%s', load_offset 0x%" PRIx64,
+ __FUNCTION__,
+ m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID,
+ executable_sp ? executable_sp->GetFileSpec().GetPath().c_str()
+ : "<null executable>",
+ load_offset);
+
+ EvalVdsoStatus();
+
+ // if we dont have a load address we cant re-base
+ bool rebase_exec = (load_offset == LLDB_INVALID_ADDRESS) ? false : true;
+
+ // if we have a valid executable
+ if (executable_sp.get()) {
+ lldb_private::ObjectFile *obj = executable_sp->GetObjectFile();
+ if (obj) {
+ // don't rebase if the module already has a load address
+ Target &target = m_process->GetTarget();
+ Address addr = obj->GetImageInfoAddress(&target);
+ if (addr.GetLoadAddress(&target) != LLDB_INVALID_ADDRESS)
+ rebase_exec = false;
}
-}
-
-void
-DynamicLoaderPOSIXDYLD::DidAttach()
-{
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- if (log)
- log->Printf ("DynamicLoaderPOSIXDYLD::%s() pid %" PRIu64, __FUNCTION__, m_process ? m_process->GetID () : LLDB_INVALID_PROCESS_ID);
-
- m_auxv.reset(new AuxVector(m_process));
- if (log)
- log->Printf ("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 " reloaded auxv data", __FUNCTION__, m_process ? m_process->GetID () : LLDB_INVALID_PROCESS_ID);
+ } else {
+ // no executable, nothing to re-base
+ rebase_exec = false;
+ }
- // ask the process if it can load any of its own modules
- m_process->LoadModules ();
-
- ModuleSP executable_sp = GetTargetExecutable ();
- ResolveExecutableModule (executable_sp);
+ // if the target executable should be re-based
+ if (rebase_exec) {
+ ModuleList module_list;
- // find the main process load offset
- addr_t load_offset = ComputeLoadOffset ();
+ module_list.Append(executable_sp);
if (log)
- log->Printf ("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 " executable '%s', load_offset 0x%" PRIx64, __FUNCTION__, m_process ? m_process->GetID () : LLDB_INVALID_PROCESS_ID, executable_sp ? executable_sp->GetFileSpec().GetPath().c_str () : "<null executable>", load_offset);
-
- EvalVdsoStatus();
-
- // if we dont have a load address we cant re-base
- bool rebase_exec = (load_offset == LLDB_INVALID_ADDRESS) ? false : true;
-
- // if we have a valid executable
- if (executable_sp.get())
- {
- lldb_private::ObjectFile * obj = executable_sp->GetObjectFile();
- if (obj)
- {
- // don't rebase if the module already has a load address
- Target & target = m_process->GetTarget ();
- Address addr = obj->GetImageInfoAddress (&target);
- if (addr.GetLoadAddress (&target) != LLDB_INVALID_ADDRESS)
- rebase_exec = false;
- }
- }
- else
- {
- // no executable, nothing to re-base
- rebase_exec = false;
+ log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
+ " added executable '%s' to module load list",
+ __FUNCTION__,
+ m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID,
+ executable_sp->GetFileSpec().GetPath().c_str());
+
+ UpdateLoadedSections(executable_sp, LLDB_INVALID_ADDRESS, load_offset,
+ true);
+
+ // When attaching to a target, there are two possible states:
+ // (1) We already crossed the entry point and therefore the rendezvous
+ // structure is ready to be used and we can load the list of modules
+ // and place the rendezvous breakpoint.
+ // (2) We didn't cross the entry point yet, so these structures are not
+ // ready; we should behave as if we just launched the target and
+ // call ProbeEntry(). This will place a breakpoint on the entry
+ // point which itself will be hit after the rendezvous structure is
+ // set up and will perform actions described in (1).
+ if (m_rendezvous.Resolve()) {
+ if (log)
+ log->Printf("DynamicLoaderPOSIXDYLD::%s() pid %" PRIu64
+ " rendezvous could resolve: attach assuming dynamic loader "
+ "info is available now",
+ __FUNCTION__,
+ m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID);
+ LoadAllCurrentModules();
+ SetRendezvousBreakpoint();
+ } else {
+ if (log)
+ log->Printf("DynamicLoaderPOSIXDYLD::%s() pid %" PRIu64
+ " rendezvous could not yet resolve: adding breakpoint to "
+ "catch future rendezvous setup",
+ __FUNCTION__,
+ m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID);
+ ProbeEntry();
}
- // if the target executable should be re-based
- if (rebase_exec)
- {
- ModuleList module_list;
-
- module_list.Append(executable_sp);
- if (log)
- log->Printf ("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 " added executable '%s' to module load list",
- __FUNCTION__,
- m_process ? m_process->GetID () : LLDB_INVALID_PROCESS_ID,
- executable_sp->GetFileSpec().GetPath().c_str ());
-
- UpdateLoadedSections(executable_sp, LLDB_INVALID_ADDRESS, load_offset, true);
-
- // When attaching to a target, there are two possible states:
- // (1) We already crossed the entry point and therefore the rendezvous
- // structure is ready to be used and we can load the list of modules
- // and place the rendezvous breakpoint.
- // (2) We didn't cross the entry point yet, so these structures are not
- // ready; we should behave as if we just launched the target and
- // call ProbeEntry(). This will place a breakpoint on the entry
- // point which itself will be hit after the rendezvous structure is
- // set up and will perform actions described in (1).
- if (m_rendezvous.Resolve())
- {
- if (log)
- log->Printf ("DynamicLoaderPOSIXDYLD::%s() pid %" PRIu64 " rendezvous could resolve: attach assuming dynamic loader info is available now", __FUNCTION__, m_process ? m_process->GetID () : LLDB_INVALID_PROCESS_ID);
- LoadAllCurrentModules();
- SetRendezvousBreakpoint();
- }
- else
- {
- if (log)
- log->Printf ("DynamicLoaderPOSIXDYLD::%s() pid %" PRIu64 " rendezvous could not yet resolve: adding breakpoint to catch future rendezvous setup", __FUNCTION__, m_process ? m_process->GetID () : LLDB_INVALID_PROCESS_ID);
- ProbeEntry();
- }
-
- m_process->GetTarget().ModulesDidLoad(module_list);
- if (log)
- {
- log->Printf ("DynamicLoaderPOSIXDYLD::%s told the target about the modules that loaded:", __FUNCTION__);
- for (auto module_sp : module_list.Modules ())
- {
- log->Printf ("-- [module] %s (pid %" PRIu64 ")",
- module_sp ? module_sp->GetFileSpec().GetPath().c_str () : "<null>",
- m_process ? m_process->GetID () : LLDB_INVALID_PROCESS_ID);
- }
- }
+ m_process->GetTarget().ModulesDidLoad(module_list);
+ if (log) {
+ log->Printf("DynamicLoaderPOSIXDYLD::%s told the target about the "
+ "modules that loaded:",
+ __FUNCTION__);
+ for (auto module_sp : module_list.Modules()) {
+ log->Printf("-- [module] %s (pid %" PRIu64 ")",
+ module_sp ? module_sp->GetFileSpec().GetPath().c_str()
+ : "<null>",
+ m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID);
+ }
}
+ }
}
-void
-DynamicLoaderPOSIXDYLD::DidLaunch()
-{
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- if (log)
- log->Printf ("DynamicLoaderPOSIXDYLD::%s()", __FUNCTION__);
+void DynamicLoaderPOSIXDYLD::DidLaunch() {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+ if (log)
+ log->Printf("DynamicLoaderPOSIXDYLD::%s()", __FUNCTION__);
- ModuleSP executable;
- addr_t load_offset;
+ ModuleSP executable;
+ addr_t load_offset;
- m_auxv.reset(new AuxVector(m_process));
+ m_auxv.reset(new AuxVector(m_process));
- executable = GetTargetExecutable();
- load_offset = ComputeLoadOffset();
- EvalVdsoStatus();
+ executable = GetTargetExecutable();
+ load_offset = ComputeLoadOffset();
+ EvalVdsoStatus();
- if (executable.get() && load_offset != LLDB_INVALID_ADDRESS)
- {
- ModuleList module_list;
- module_list.Append(executable);
- UpdateLoadedSections(executable, LLDB_INVALID_ADDRESS, load_offset, true);
+ if (executable.get() && load_offset != LLDB_INVALID_ADDRESS) {
+ ModuleList module_list;
+ module_list.Append(executable);
+ UpdateLoadedSections(executable, LLDB_INVALID_ADDRESS, load_offset, true);
- if (log)
- log->Printf ("DynamicLoaderPOSIXDYLD::%s about to call ProbeEntry()", __FUNCTION__);
- ProbeEntry();
+ if (log)
+ log->Printf("DynamicLoaderPOSIXDYLD::%s about to call ProbeEntry()",
+ __FUNCTION__);
+ ProbeEntry();
- m_process->GetTarget().ModulesDidLoad(module_list);
- }
+ m_process->GetTarget().ModulesDidLoad(module_list);
+ }
}
-Error
-DynamicLoaderPOSIXDYLD::CanLoadImage()
-{
- return Error();
-}
+Error DynamicLoaderPOSIXDYLD::CanLoadImage() { return Error(); }
-void
-DynamicLoaderPOSIXDYLD::UpdateLoadedSections(ModuleSP module,
- addr_t link_map_addr,
- addr_t base_addr,
- bool base_addr_is_offset)
-{
- m_loaded_modules[module] = link_map_addr;
- UpdateLoadedSectionsCommon(module, base_addr, base_addr_is_offset);
+void DynamicLoaderPOSIXDYLD::UpdateLoadedSections(ModuleSP module,
+ addr_t link_map_addr,
+ addr_t base_addr,
+ bool base_addr_is_offset) {
+ m_loaded_modules[module] = link_map_addr;
+ UpdateLoadedSectionsCommon(module, base_addr, base_addr_is_offset);
}
-void
-DynamicLoaderPOSIXDYLD::UnloadSections(const ModuleSP module)
-{
- m_loaded_modules.erase(module);
+void DynamicLoaderPOSIXDYLD::UnloadSections(const ModuleSP module) {
+ m_loaded_modules.erase(module);
- UnloadSectionsCommon(module);
+ UnloadSectionsCommon(module);
}
-void
-DynamicLoaderPOSIXDYLD::ProbeEntry()
-{
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
-
- const addr_t entry = GetEntryPoint();
- if (entry == LLDB_INVALID_ADDRESS)
- {
- if (log)
- log->Printf ("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 " GetEntryPoint() returned no address, not setting entry breakpoint", __FUNCTION__, m_process ? m_process->GetID () : LLDB_INVALID_PROCESS_ID);
- return;
- }
+void DynamicLoaderPOSIXDYLD::ProbeEntry() {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+ const addr_t entry = GetEntryPoint();
+ if (entry == LLDB_INVALID_ADDRESS) {
if (log)
- log->Printf ("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 " GetEntryPoint() returned address 0x%" PRIx64 ", setting entry breakpoint", __FUNCTION__, m_process ? m_process->GetID () : LLDB_INVALID_PROCESS_ID, entry);
-
- if (m_process)
- {
- Breakpoint *const entry_break = m_process->GetTarget().CreateBreakpoint(entry, true, false).get();
- entry_break->SetCallback(EntryBreakpointHit, this, true);
- entry_break->SetBreakpointKind("shared-library-event");
-
- // Shoudn't hit this more than once.
- entry_break->SetOneShot (true);
- }
+ log->Printf(
+ "DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
+ " GetEntryPoint() returned no address, not setting entry breakpoint",
+ __FUNCTION__,
+ m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID);
+ return;
+ }
+
+ if (log)
+ log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
+ " GetEntryPoint() returned address 0x%" PRIx64
+ ", setting entry breakpoint",
+ __FUNCTION__,
+ m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID,
+ entry);
+
+ if (m_process) {
+ Breakpoint *const entry_break =
+ m_process->GetTarget().CreateBreakpoint(entry, true, false).get();
+ entry_break->SetCallback(EntryBreakpointHit, this, true);
+ entry_break->SetBreakpointKind("shared-library-event");
+
+ // Shoudn't hit this more than once.
+ entry_break->SetOneShot(true);
+ }
}
// The runtime linker has run and initialized the rendezvous structure once the
@@ -294,419 +276,422 @@ DynamicLoaderPOSIXDYLD::ProbeEntry()
// dependent modules for the process. Similarly, we can discover the runtime
// linker function and setup a breakpoint to notify us of any dynamically loaded
// modules (via dlopen).
-bool
-DynamicLoaderPOSIXDYLD::EntryBreakpointHit(void *baton,
- StoppointCallbackContext *context,
- user_id_t break_id,
- user_id_t break_loc_id)
-{
- assert(baton && "null baton");
- if (!baton)
- return false;
-
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- DynamicLoaderPOSIXDYLD *const dyld_instance = static_cast<DynamicLoaderPOSIXDYLD*>(baton);
- if (log)
- log->Printf ("DynamicLoaderPOSIXDYLD::%s called for pid %" PRIu64, __FUNCTION__, dyld_instance->m_process ? dyld_instance->m_process->GetID () : LLDB_INVALID_PROCESS_ID);
-
- // Disable the breakpoint --- if a stop happens right after this, which we've seen on occasion, we don't
- // want the breakpoint stepping thread-plan logic to show a breakpoint instruction at the disassembled
- // entry point to the program. Disabling it prevents it. (One-shot is not enough - one-shot removal logic
- // only happens after the breakpoint goes public, which wasn't happening in our scenario).
- if (dyld_instance->m_process)
- {
- BreakpointSP breakpoint_sp = dyld_instance->m_process->GetTarget().GetBreakpointByID (break_id);
- if (breakpoint_sp)
- {
- if (log)
- log->Printf ("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 " disabling breakpoint id %" PRIu64, __FUNCTION__, dyld_instance->m_process->GetID (), break_id);
- breakpoint_sp->SetEnabled (false);
- }
- else
- {
- if (log)
- log->Printf ("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 " failed to find breakpoint for breakpoint id %" PRIu64, __FUNCTION__, dyld_instance->m_process->GetID (), break_id);
- }
- }
- else
- {
- if (log)
- log->Printf ("DynamicLoaderPOSIXDYLD::%s breakpoint id %" PRIu64 " no Process instance! Cannot disable breakpoint", __FUNCTION__, break_id);
+bool DynamicLoaderPOSIXDYLD::EntryBreakpointHit(
+ void *baton, StoppointCallbackContext *context, user_id_t break_id,
+ user_id_t break_loc_id) {
+ assert(baton && "null baton");
+ if (!baton)
+ return false;
+
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+ DynamicLoaderPOSIXDYLD *const dyld_instance =
+ static_cast<DynamicLoaderPOSIXDYLD *>(baton);
+ if (log)
+ log->Printf("DynamicLoaderPOSIXDYLD::%s called for pid %" PRIu64,
+ __FUNCTION__,
+ dyld_instance->m_process ? dyld_instance->m_process->GetID()
+ : LLDB_INVALID_PROCESS_ID);
+
+ // Disable the breakpoint --- if a stop happens right after this, which we've
+ // seen on occasion, we don't
+ // want the breakpoint stepping thread-plan logic to show a breakpoint
+ // instruction at the disassembled
+ // entry point to the program. Disabling it prevents it. (One-shot is not
+ // enough - one-shot removal logic
+ // only happens after the breakpoint goes public, which wasn't happening in
+ // our scenario).
+ if (dyld_instance->m_process) {
+ BreakpointSP breakpoint_sp =
+ dyld_instance->m_process->GetTarget().GetBreakpointByID(break_id);
+ if (breakpoint_sp) {
+ if (log)
+ log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
+ " disabling breakpoint id %" PRIu64,
+ __FUNCTION__, dyld_instance->m_process->GetID(), break_id);
+ breakpoint_sp->SetEnabled(false);
+ } else {
+ if (log)
+ log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
+ " failed to find breakpoint for breakpoint id %" PRIu64,
+ __FUNCTION__, dyld_instance->m_process->GetID(), break_id);
}
-
- dyld_instance->LoadAllCurrentModules();
- dyld_instance->SetRendezvousBreakpoint();
- return false; // Continue running.
+ } else {
+ if (log)
+ log->Printf("DynamicLoaderPOSIXDYLD::%s breakpoint id %" PRIu64
+ " no Process instance! Cannot disable breakpoint",
+ __FUNCTION__, break_id);
+ }
+
+ dyld_instance->LoadAllCurrentModules();
+ dyld_instance->SetRendezvousBreakpoint();
+ return false; // Continue running.
}
-void
-DynamicLoaderPOSIXDYLD::SetRendezvousBreakpoint()
-{
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
-
- addr_t break_addr = m_rendezvous.GetBreakAddress();
- Target &target = m_process->GetTarget();
-
- if (m_dyld_bid == LLDB_INVALID_BREAK_ID)
- {
- if (log)
- log->Printf ("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 " setting rendezvous break address at 0x%" PRIx64, __FUNCTION__, m_process ? m_process->GetID () : LLDB_INVALID_PROCESS_ID, break_addr);
- Breakpoint *dyld_break = target.CreateBreakpoint (break_addr, true, false).get();
- dyld_break->SetCallback(RendezvousBreakpointHit, this, true);
- dyld_break->SetBreakpointKind ("shared-library-event");
- m_dyld_bid = dyld_break->GetID();
- }
- else
- {
- if (log)
- log->Printf ("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 " reusing break id %" PRIu32 ", address at 0x%" PRIx64, __FUNCTION__, m_process ? m_process->GetID () : LLDB_INVALID_PROCESS_ID, m_dyld_bid, break_addr);
- }
+void DynamicLoaderPOSIXDYLD::SetRendezvousBreakpoint() {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- // Make sure our breakpoint is at the right address.
- assert (target.GetBreakpointByID(m_dyld_bid)->FindLocationByAddress(break_addr)->GetBreakpoint().GetID() == m_dyld_bid);
-}
+ addr_t break_addr = m_rendezvous.GetBreakAddress();
+ Target &target = m_process->GetTarget();
-bool
-DynamicLoaderPOSIXDYLD::RendezvousBreakpointHit(void *baton,
- StoppointCallbackContext *context,
- user_id_t break_id,
- user_id_t break_loc_id)
-{
- assert (baton && "null baton");
- if (!baton)
- return false;
-
- Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- DynamicLoaderPOSIXDYLD *const dyld_instance = static_cast<DynamicLoaderPOSIXDYLD*>(baton);
+ if (m_dyld_bid == LLDB_INVALID_BREAK_ID) {
if (log)
- log->Printf ("DynamicLoaderPOSIXDYLD::%s called for pid %" PRIu64, __FUNCTION__, dyld_instance->m_process ? dyld_instance->m_process->GetID () : LLDB_INVALID_PROCESS_ID);
-
- dyld_instance->RefreshModules();
-
- // Return true to stop the target, false to just let the target run.
- const bool stop_when_images_change = dyld_instance->GetStopWhenImagesChange();
+ log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
+ " setting rendezvous break address at 0x%" PRIx64,
+ __FUNCTION__,
+ m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID,
+ break_addr);
+ Breakpoint *dyld_break =
+ target.CreateBreakpoint(break_addr, true, false).get();
+ dyld_break->SetCallback(RendezvousBreakpointHit, this, true);
+ dyld_break->SetBreakpointKind("shared-library-event");
+ m_dyld_bid = dyld_break->GetID();
+ } else {
if (log)
- log->Printf ("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 " stop_when_images_change=%s", __FUNCTION__, dyld_instance->m_process ? dyld_instance->m_process->GetID () : LLDB_INVALID_PROCESS_ID, stop_when_images_change ? "true" : "false");
- return stop_when_images_change;
+ log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
+ " reusing break id %" PRIu32 ", address at 0x%" PRIx64,
+ __FUNCTION__,
+ m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID,
+ m_dyld_bid, break_addr);
+ }
+
+ // Make sure our breakpoint is at the right address.
+ assert(target.GetBreakpointByID(m_dyld_bid)
+ ->FindLocationByAddress(break_addr)
+ ->GetBreakpoint()
+ .GetID() == m_dyld_bid);
}
-void
-DynamicLoaderPOSIXDYLD::RefreshModules()
-{
- if (!m_rendezvous.Resolve())
- return;
-
- DYLDRendezvous::iterator I;
- DYLDRendezvous::iterator E;
-
- ModuleList &loaded_modules = m_process->GetTarget().GetImages();
-
- if (m_rendezvous.ModulesDidLoad())
- {
- ModuleList new_modules;
-
- E = m_rendezvous.loaded_end();
- for (I = m_rendezvous.loaded_begin(); I != E; ++I)
- {
- ModuleSP module_sp = LoadModuleAtAddress(I->file_spec, I->link_addr, I->base_addr, true);
- if (module_sp.get())
- {
- loaded_modules.AppendIfNeeded(module_sp);
- new_modules.Append(module_sp);
- }
- }
- m_process->GetTarget().ModulesDidLoad(new_modules);
+bool DynamicLoaderPOSIXDYLD::RendezvousBreakpointHit(
+ void *baton, StoppointCallbackContext *context, user_id_t break_id,
+ user_id_t break_loc_id) {
+ assert(baton && "null baton");
+ if (!baton)
+ return false;
+
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+ DynamicLoaderPOSIXDYLD *const dyld_instance =
+ static_cast<DynamicLoaderPOSIXDYLD *>(baton);
+ if (log)
+ log->Printf("DynamicLoaderPOSIXDYLD::%s called for pid %" PRIu64,
+ __FUNCTION__,
+ dyld_instance->m_process ? dyld_instance->m_process->GetID()
+ : LLDB_INVALID_PROCESS_ID);
+
+ dyld_instance->RefreshModules();
+
+ // Return true to stop the target, false to just let the target run.
+ const bool stop_when_images_change = dyld_instance->GetStopWhenImagesChange();
+ if (log)
+ log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
+ " stop_when_images_change=%s",
+ __FUNCTION__,
+ dyld_instance->m_process ? dyld_instance->m_process->GetID()
+ : LLDB_INVALID_PROCESS_ID,
+ stop_when_images_change ? "true" : "false");
+ return stop_when_images_change;
+}
+
+void DynamicLoaderPOSIXDYLD::RefreshModules() {
+ if (!m_rendezvous.Resolve())
+ return;
+
+ DYLDRendezvous::iterator I;
+ DYLDRendezvous::iterator E;
+
+ ModuleList &loaded_modules = m_process->GetTarget().GetImages();
+
+ if (m_rendezvous.ModulesDidLoad()) {
+ ModuleList new_modules;
+
+ E = m_rendezvous.loaded_end();
+ for (I = m_rendezvous.loaded_begin(); I != E; ++I) {
+ ModuleSP module_sp =
+ LoadModuleAtAddress(I->file_spec, I->link_addr, I->base_addr, true);
+ if (module_sp.get()) {
+ loaded_modules.AppendIfNeeded(module_sp);
+ new_modules.Append(module_sp);
+ }
}
-
- if (m_rendezvous.ModulesDidUnload())
- {
- ModuleList old_modules;
-
- E = m_rendezvous.unloaded_end();
- for (I = m_rendezvous.unloaded_begin(); I != E; ++I)
- {
- ModuleSpec module_spec{I->file_spec};
- ModuleSP module_sp = loaded_modules.FindFirstModule (module_spec);
-
- if (module_sp.get())
- {
- old_modules.Append(module_sp);
- UnloadSections(module_sp);
- }
- }
- loaded_modules.Remove(old_modules);
- m_process->GetTarget().ModulesDidUnload(old_modules, false);
+ m_process->GetTarget().ModulesDidLoad(new_modules);
+ }
+
+ if (m_rendezvous.ModulesDidUnload()) {
+ ModuleList old_modules;
+
+ E = m_rendezvous.unloaded_end();
+ for (I = m_rendezvous.unloaded_begin(); I != E; ++I) {
+ ModuleSpec module_spec{I->file_spec};
+ ModuleSP module_sp = loaded_modules.FindFirstModule(module_spec);
+
+ if (module_sp.get()) {
+ old_modules.Append(module_sp);
+ UnloadSections(module_sp);
+ }
}
+ loaded_modules.Remove(old_modules);
+ m_process->GetTarget().ModulesDidUnload(old_modules, false);
+ }
}
ThreadPlanSP
-DynamicLoaderPOSIXDYLD::GetStepThroughTrampolinePlan(Thread &thread, bool stop)
-{
- ThreadPlanSP thread_plan_sp;
-
- StackFrame *frame = thread.GetStackFrameAtIndex(0).get();
- const SymbolContext &context = frame->GetSymbolContext(eSymbolContextSymbol);
- Symbol *sym = context.symbol;
-
- if (sym == NULL || !sym->IsTrampoline())
- return thread_plan_sp;
-
- ConstString sym_name = sym->GetName();
- if (!sym_name)
- return thread_plan_sp;
-
- SymbolContextList target_symbols;
- Target &target = thread.GetProcess()->GetTarget();
- const ModuleList &images = target.GetImages();
-
- images.FindSymbolsWithNameAndType(sym_name, eSymbolTypeCode, target_symbols);
- size_t num_targets = target_symbols.GetSize();
- if (!num_targets)
- return thread_plan_sp;
-
- typedef std::vector<lldb::addr_t> AddressVector;
- AddressVector addrs;
- for (size_t i = 0; i < num_targets; ++i)
- {
- SymbolContext context;
- AddressRange range;
- if (target_symbols.GetContextAtIndex(i, context))
- {
- context.GetAddressRange(eSymbolContextEverything, 0, false, range);
- lldb::addr_t addr = range.GetBaseAddress().GetLoadAddress(&target);
- if (addr != LLDB_INVALID_ADDRESS)
- addrs.push_back(addr);
- }
- }
+DynamicLoaderPOSIXDYLD::GetStepThroughTrampolinePlan(Thread &thread,
+ bool stop) {
+ ThreadPlanSP thread_plan_sp;
- if (addrs.size() > 0)
- {
- AddressVector::iterator start = addrs.begin();
- AddressVector::iterator end = addrs.end();
+ StackFrame *frame = thread.GetStackFrameAtIndex(0).get();
+ const SymbolContext &context = frame->GetSymbolContext(eSymbolContextSymbol);
+ Symbol *sym = context.symbol;
- std::sort(start, end);
- addrs.erase(std::unique(start, end), end);
- thread_plan_sp.reset(new ThreadPlanRunToAddress(thread, addrs, stop));
- }
+ if (sym == NULL || !sym->IsTrampoline())
+ return thread_plan_sp;
+ ConstString sym_name = sym->GetName();
+ if (!sym_name)
return thread_plan_sp;
-}
-void
-DynamicLoaderPOSIXDYLD::LoadAllCurrentModules()
-{
- DYLDRendezvous::iterator I;
- DYLDRendezvous::iterator E;
- ModuleList module_list;
-
- if (!m_rendezvous.Resolve())
- {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- if (log)
- log->Printf("DynamicLoaderPOSIXDYLD::%s unable to resolve POSIX DYLD rendezvous address",
- __FUNCTION__);
- return;
+ SymbolContextList target_symbols;
+ Target &target = thread.GetProcess()->GetTarget();
+ const ModuleList &images = target.GetImages();
+
+ images.FindSymbolsWithNameAndType(sym_name, eSymbolTypeCode, target_symbols);
+ size_t num_targets = target_symbols.GetSize();
+ if (!num_targets)
+ return thread_plan_sp;
+
+ typedef std::vector<lldb::addr_t> AddressVector;
+ AddressVector addrs;
+ for (size_t i = 0; i < num_targets; ++i) {
+ SymbolContext context;
+ AddressRange range;
+ if (target_symbols.GetContextAtIndex(i, context)) {
+ context.GetAddressRange(eSymbolContextEverything, 0, false, range);
+ lldb::addr_t addr = range.GetBaseAddress().GetLoadAddress(&target);
+ if (addr != LLDB_INVALID_ADDRESS)
+ addrs.push_back(addr);
}
+ }
+
+ if (addrs.size() > 0) {
+ AddressVector::iterator start = addrs.begin();
+ AddressVector::iterator end = addrs.end();
- // The rendezvous class doesn't enumerate the main module, so track
- // that ourselves here.
- ModuleSP executable = GetTargetExecutable();
- m_loaded_modules[executable] = m_rendezvous.GetLinkMapAddress();
- if (m_vdso_base != LLDB_INVALID_ADDRESS)
- {
- FileSpec file_spec("[vdso]", false);
- ModuleSP module_sp = LoadModuleAtAddress(file_spec, LLDB_INVALID_ADDRESS, m_vdso_base, false);
- if (module_sp.get())
- {
- module_list.Append(module_sp);
- }
+ std::sort(start, end);
+ addrs.erase(std::unique(start, end), end);
+ thread_plan_sp.reset(new ThreadPlanRunToAddress(thread, addrs, stop));
+ }
+
+ return thread_plan_sp;
+}
+
+void DynamicLoaderPOSIXDYLD::LoadAllCurrentModules() {
+ DYLDRendezvous::iterator I;
+ DYLDRendezvous::iterator E;
+ ModuleList module_list;
+
+ if (!m_rendezvous.Resolve()) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+ if (log)
+ log->Printf("DynamicLoaderPOSIXDYLD::%s unable to resolve POSIX DYLD "
+ "rendezvous address",
+ __FUNCTION__);
+ return;
+ }
+
+ // The rendezvous class doesn't enumerate the main module, so track
+ // that ourselves here.
+ ModuleSP executable = GetTargetExecutable();
+ m_loaded_modules[executable] = m_rendezvous.GetLinkMapAddress();
+ if (m_vdso_base != LLDB_INVALID_ADDRESS) {
+ FileSpec file_spec("[vdso]", false);
+ ModuleSP module_sp = LoadModuleAtAddress(file_spec, LLDB_INVALID_ADDRESS,
+ m_vdso_base, false);
+ if (module_sp.get()) {
+ module_list.Append(module_sp);
}
- for (I = m_rendezvous.begin(), E = m_rendezvous.end(); I != E; ++I)
- {
- ModuleSP module_sp = LoadModuleAtAddress(I->file_spec, I->link_addr, I->base_addr, true);
- if (module_sp.get())
- {
- module_list.Append(module_sp);
- }
- else
- {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- if (log)
- log->Printf("DynamicLoaderPOSIXDYLD::%s failed loading module %s at 0x%" PRIx64,
- __FUNCTION__, I->file_spec.GetCString(), I->base_addr);
- }
+ }
+ for (I = m_rendezvous.begin(), E = m_rendezvous.end(); I != E; ++I) {
+ ModuleSP module_sp =
+ LoadModuleAtAddress(I->file_spec, I->link_addr, I->base_addr, true);
+ if (module_sp.get()) {
+ module_list.Append(module_sp);
+ } else {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+ if (log)
+ log->Printf(
+ "DynamicLoaderPOSIXDYLD::%s failed loading module %s at 0x%" PRIx64,
+ __FUNCTION__, I->file_spec.GetCString(), I->base_addr);
}
+ }
- m_process->GetTarget().ModulesDidLoad(module_list);
+ m_process->GetTarget().ModulesDidLoad(module_list);
}
-addr_t
-DynamicLoaderPOSIXDYLD::ComputeLoadOffset()
-{
- addr_t virt_entry;
+addr_t DynamicLoaderPOSIXDYLD::ComputeLoadOffset() {
+ addr_t virt_entry;
- if (m_load_offset != LLDB_INVALID_ADDRESS)
- return m_load_offset;
+ if (m_load_offset != LLDB_INVALID_ADDRESS)
+ return m_load_offset;
- if ((virt_entry = GetEntryPoint()) == LLDB_INVALID_ADDRESS)
- return LLDB_INVALID_ADDRESS;
+ if ((virt_entry = GetEntryPoint()) == LLDB_INVALID_ADDRESS)
+ return LLDB_INVALID_ADDRESS;
- ModuleSP module = m_process->GetTarget().GetExecutableModule();
- if (!module)
- return LLDB_INVALID_ADDRESS;
+ ModuleSP module = m_process->GetTarget().GetExecutableModule();
+ if (!module)
+ return LLDB_INVALID_ADDRESS;
- ObjectFile *exe = module->GetObjectFile();
- if (!exe)
- return LLDB_INVALID_ADDRESS;
+ ObjectFile *exe = module->GetObjectFile();
+ if (!exe)
+ return LLDB_INVALID_ADDRESS;
- Address file_entry = exe->GetEntryPointAddress();
+ Address file_entry = exe->GetEntryPointAddress();
- if (!file_entry.IsValid())
- return LLDB_INVALID_ADDRESS;
-
- m_load_offset = virt_entry - file_entry.GetFileAddress();
- return m_load_offset;
-}
+ if (!file_entry.IsValid())
+ return LLDB_INVALID_ADDRESS;
-void
-DynamicLoaderPOSIXDYLD::EvalVdsoStatus()
-{
- AuxVector::iterator I = m_auxv->FindEntry(AuxVector::AT_SYSINFO_EHDR);
+ m_load_offset = virt_entry - file_entry.GetFileAddress();
+ return m_load_offset;
+}
- if (I != m_auxv->end())
- m_vdso_base = I->value;
+void DynamicLoaderPOSIXDYLD::EvalVdsoStatus() {
+ AuxVector::iterator I = m_auxv->FindEntry(AuxVector::AT_SYSINFO_EHDR);
+ if (I != m_auxv->end())
+ m_vdso_base = I->value;
}
-addr_t
-DynamicLoaderPOSIXDYLD::GetEntryPoint()
-{
- if (m_entry_point != LLDB_INVALID_ADDRESS)
- return m_entry_point;
+addr_t DynamicLoaderPOSIXDYLD::GetEntryPoint() {
+ if (m_entry_point != LLDB_INVALID_ADDRESS)
+ return m_entry_point;
- if (m_auxv.get() == NULL)
- return LLDB_INVALID_ADDRESS;
+ if (m_auxv.get() == NULL)
+ return LLDB_INVALID_ADDRESS;
- AuxVector::iterator I = m_auxv->FindEntry(AuxVector::AT_ENTRY);
+ AuxVector::iterator I = m_auxv->FindEntry(AuxVector::AT_ENTRY);
- if (I == m_auxv->end())
- return LLDB_INVALID_ADDRESS;
+ if (I == m_auxv->end())
+ return LLDB_INVALID_ADDRESS;
- m_entry_point = static_cast<addr_t>(I->value);
+ m_entry_point = static_cast<addr_t>(I->value);
- const ArchSpec &arch = m_process->GetTarget().GetArchitecture();
+ const ArchSpec &arch = m_process->GetTarget().GetArchitecture();
- // On ppc64, the entry point is actually a descriptor. Dereference it.
- if (arch.GetMachine() == llvm::Triple::ppc64)
- m_entry_point = ReadUnsignedIntWithSizeInBytes(m_entry_point, 8);
+ // On ppc64, the entry point is actually a descriptor. Dereference it.
+ if (arch.GetMachine() == llvm::Triple::ppc64)
+ m_entry_point = ReadUnsignedIntWithSizeInBytes(m_entry_point, 8);
- return m_entry_point;
+ return m_entry_point;
}
lldb::addr_t
-DynamicLoaderPOSIXDYLD::GetThreadLocalData(const lldb::ModuleSP module_sp, const lldb::ThreadSP thread,
- lldb::addr_t tls_file_addr)
-{
- auto it = m_loaded_modules.find (module_sp);
- if (it == m_loaded_modules.end())
- return LLDB_INVALID_ADDRESS;
-
- addr_t link_map = it->second;
- if (link_map == LLDB_INVALID_ADDRESS)
- return LLDB_INVALID_ADDRESS;
-
- const DYLDRendezvous::ThreadInfo &metadata = m_rendezvous.GetThreadInfo();
- if (!metadata.valid)
- return LLDB_INVALID_ADDRESS;
-
- // Get the thread pointer.
- addr_t tp = thread->GetThreadPointer ();
- if (tp == LLDB_INVALID_ADDRESS)
- return LLDB_INVALID_ADDRESS;
-
- // Find the module's modid.
- int modid_size = 4; // FIXME(spucci): This isn't right for big-endian 64-bit
- int64_t modid = ReadUnsignedIntWithSizeInBytes (link_map + metadata.modid_offset, modid_size);
- if (modid == -1)
- return LLDB_INVALID_ADDRESS;
-
- // Lookup the DTV structure for this thread.
- addr_t dtv_ptr = tp + metadata.dtv_offset;
- addr_t dtv = ReadPointer (dtv_ptr);
- if (dtv == LLDB_INVALID_ADDRESS)
- return LLDB_INVALID_ADDRESS;
-
- // Find the TLS block for this module.
- addr_t dtv_slot = dtv + metadata.dtv_slot_size*modid;
- addr_t tls_block = ReadPointer (dtv_slot + metadata.tls_offset);
-
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- if (log)
- log->Printf("DynamicLoaderPOSIXDYLD::Performed TLS lookup: "
- "module=%s, link_map=0x%" PRIx64 ", tp=0x%" PRIx64 ", modid=%" PRId64 ", tls_block=0x%" PRIx64 "\n",
- module_sp->GetObjectName().AsCString(""), link_map, tp, (int64_t)modid, tls_block);
-
- if (tls_block == LLDB_INVALID_ADDRESS)
- return LLDB_INVALID_ADDRESS;
- else
- return tls_block + tls_file_addr;
+DynamicLoaderPOSIXDYLD::GetThreadLocalData(const lldb::ModuleSP module_sp,
+ const lldb::ThreadSP thread,
+ lldb::addr_t tls_file_addr) {
+ auto it = m_loaded_modules.find(module_sp);
+ if (it == m_loaded_modules.end())
+ return LLDB_INVALID_ADDRESS;
+
+ addr_t link_map = it->second;
+ if (link_map == LLDB_INVALID_ADDRESS)
+ return LLDB_INVALID_ADDRESS;
+
+ const DYLDRendezvous::ThreadInfo &metadata = m_rendezvous.GetThreadInfo();
+ if (!metadata.valid)
+ return LLDB_INVALID_ADDRESS;
+
+ // Get the thread pointer.
+ addr_t tp = thread->GetThreadPointer();
+ if (tp == LLDB_INVALID_ADDRESS)
+ return LLDB_INVALID_ADDRESS;
+
+ // Find the module's modid.
+ int modid_size = 4; // FIXME(spucci): This isn't right for big-endian 64-bit
+ int64_t modid = ReadUnsignedIntWithSizeInBytes(
+ link_map + metadata.modid_offset, modid_size);
+ if (modid == -1)
+ return LLDB_INVALID_ADDRESS;
+
+ // Lookup the DTV structure for this thread.
+ addr_t dtv_ptr = tp + metadata.dtv_offset;
+ addr_t dtv = ReadPointer(dtv_ptr);
+ if (dtv == LLDB_INVALID_ADDRESS)
+ return LLDB_INVALID_ADDRESS;
+
+ // Find the TLS block for this module.
+ addr_t dtv_slot = dtv + metadata.dtv_slot_size * modid;
+ addr_t tls_block = ReadPointer(dtv_slot + metadata.tls_offset);
+
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+ if (log)
+ log->Printf("DynamicLoaderPOSIXDYLD::Performed TLS lookup: "
+ "module=%s, link_map=0x%" PRIx64 ", tp=0x%" PRIx64
+ ", modid=%" PRId64 ", tls_block=0x%" PRIx64 "\n",
+ module_sp->GetObjectName().AsCString(""), link_map, tp,
+ (int64_t)modid, tls_block);
+
+ if (tls_block == LLDB_INVALID_ADDRESS)
+ return LLDB_INVALID_ADDRESS;
+ else
+ return tls_block + tls_file_addr;
}
-void
-DynamicLoaderPOSIXDYLD::ResolveExecutableModule (lldb::ModuleSP &module_sp)
-{
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+void DynamicLoaderPOSIXDYLD::ResolveExecutableModule(
+ lldb::ModuleSP &module_sp) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
- if (m_process == nullptr)
- return;
+ if (m_process == nullptr)
+ return;
- auto &target = m_process->GetTarget ();
- const auto platform_sp = target.GetPlatform ();
+ auto &target = m_process->GetTarget();
+ const auto platform_sp = target.GetPlatform();
- ProcessInstanceInfo process_info;
- if (!m_process->GetProcessInfo(process_info))
- {
- if (log)
- log->Printf ("DynamicLoaderPOSIXDYLD::%s - failed to get process info for pid %" PRIu64,
- __FUNCTION__, m_process->GetID ());
- return;
- }
+ ProcessInstanceInfo process_info;
+ if (!m_process->GetProcessInfo(process_info)) {
+ if (log)
+ log->Printf("DynamicLoaderPOSIXDYLD::%s - failed to get process info for "
+ "pid %" PRIu64,
+ __FUNCTION__, m_process->GetID());
+ return;
+ }
+
+ if (log)
+ log->Printf("DynamicLoaderPOSIXDYLD::%s - got executable by pid %" PRIu64
+ ": %s",
+ __FUNCTION__, m_process->GetID(),
+ process_info.GetExecutableFile().GetPath().c_str());
+
+ ModuleSpec module_spec(process_info.GetExecutableFile(),
+ process_info.GetArchitecture());
+ if (module_sp && module_sp->MatchesModuleSpec(module_spec))
+ return;
+
+ const auto executable_search_paths(Target::GetDefaultExecutableSearchPaths());
+ auto error = platform_sp->ResolveExecutable(
+ module_spec, module_sp,
+ !executable_search_paths.IsEmpty() ? &executable_search_paths : nullptr);
+ if (error.Fail()) {
+ StreamString stream;
+ module_spec.Dump(stream);
if (log)
- log->Printf ("DynamicLoaderPOSIXDYLD::%s - got executable by pid %" PRIu64 ": %s",
- __FUNCTION__, m_process->GetID (), process_info.GetExecutableFile ().GetPath ().c_str ());
-
- ModuleSpec module_spec (process_info.GetExecutableFile (), process_info.GetArchitecture ());
- if (module_sp && module_sp->MatchesModuleSpec (module_spec))
- return;
-
- const auto executable_search_paths (Target::GetDefaultExecutableSearchPaths());
- auto error = platform_sp->ResolveExecutable (
- module_spec, module_sp, !executable_search_paths.IsEmpty() ? &executable_search_paths : nullptr);
- if (error.Fail ())
- {
- StreamString stream;
- module_spec.Dump (stream);
-
- if (log)
- log->Printf ("DynamicLoaderPOSIXDYLD::%s - failed to resolve executable with module spec \"%s\": %s",
- __FUNCTION__, stream.GetString ().c_str (), error.AsCString ());
- return;
- }
+ log->Printf("DynamicLoaderPOSIXDYLD::%s - failed to resolve executable "
+ "with module spec \"%s\": %s",
+ __FUNCTION__, stream.GetString().c_str(), error.AsCString());
+ return;
+ }
- target.SetExecutableModule (module_sp, false);
+ target.SetExecutableModule(module_sp, false);
}
-bool
-DynamicLoaderPOSIXDYLD::AlwaysRelyOnEHUnwindInfo(lldb_private::SymbolContext &sym_ctx)
-{
- ModuleSP module_sp;
- if (sym_ctx.symbol)
- module_sp = sym_ctx.symbol->GetAddressRef().GetModule();
- if (!module_sp && sym_ctx.function)
- module_sp = sym_ctx.function->GetAddressRange().GetBaseAddress().GetModule();
- if (!module_sp)
- return false;
-
- return module_sp->GetFileSpec().GetPath() == "[vdso]";
+bool DynamicLoaderPOSIXDYLD::AlwaysRelyOnEHUnwindInfo(
+ lldb_private::SymbolContext &sym_ctx) {
+ ModuleSP module_sp;
+ if (sym_ctx.symbol)
+ module_sp = sym_ctx.symbol->GetAddressRef().GetModule();
+ if (!module_sp && sym_ctx.function)
+ module_sp =
+ sym_ctx.function->GetAddressRange().GetBaseAddress().GetModule();
+ if (!module_sp)
+ return false;
+
+ return module_sp->GetFileSpec().GetPath() == "[vdso]";
}
diff --git a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h
index 1049e543256..1e8333fb099 100644
--- a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h
+++ b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h
@@ -21,162 +21,139 @@
class AuxVector;
-class DynamicLoaderPOSIXDYLD : public lldb_private::DynamicLoader
-{
+class DynamicLoaderPOSIXDYLD : public lldb_private::DynamicLoader {
public:
- DynamicLoaderPOSIXDYLD(lldb_private::Process *process);
+ DynamicLoaderPOSIXDYLD(lldb_private::Process *process);
- ~DynamicLoaderPOSIXDYLD() override;
+ ~DynamicLoaderPOSIXDYLD() override;
- static void
- Initialize();
+ static void Initialize();
- static void
- Terminate();
+ static void Terminate();
- static lldb_private::ConstString
- GetPluginNameStatic();
+ static lldb_private::ConstString GetPluginNameStatic();
- static const char *
- GetPluginDescriptionStatic();
+ static const char *GetPluginDescriptionStatic();
- static lldb_private::DynamicLoader *
- CreateInstance(lldb_private::Process *process, bool force);
+ static lldb_private::DynamicLoader *
+ CreateInstance(lldb_private::Process *process, bool force);
- //------------------------------------------------------------------
- // DynamicLoader protocol
- //------------------------------------------------------------------
+ //------------------------------------------------------------------
+ // DynamicLoader protocol
+ //------------------------------------------------------------------
- void
- DidAttach() override;
+ void DidAttach() override;
- void
- DidLaunch() override;
+ void DidLaunch() override;
- lldb::ThreadPlanSP
- GetStepThroughTrampolinePlan(lldb_private::Thread &thread,
- bool stop_others) override;
+ lldb::ThreadPlanSP GetStepThroughTrampolinePlan(lldb_private::Thread &thread,
+ bool stop_others) override;
- lldb_private::Error
- CanLoadImage() override;
+ lldb_private::Error CanLoadImage() override;
- lldb::addr_t
- GetThreadLocalData(const lldb::ModuleSP module, const lldb::ThreadSP thread, lldb::addr_t tls_file_addr) override;
+ lldb::addr_t GetThreadLocalData(const lldb::ModuleSP module,
+ const lldb::ThreadSP thread,
+ lldb::addr_t tls_file_addr) override;
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- lldb_private::ConstString
- GetPluginName() override;
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ lldb_private::ConstString GetPluginName() override;
- uint32_t
- GetPluginVersion() override;
+ uint32_t GetPluginVersion() override;
protected:
- /// Runtime linker rendezvous structure.
- DYLDRendezvous m_rendezvous;
-
- /// Virtual load address of the inferior process.
- lldb::addr_t m_load_offset;
-
- /// Virtual entry address of the inferior process.
- lldb::addr_t m_entry_point;
-
- /// Auxiliary vector of the inferior process.
- std::unique_ptr<AuxVector> m_auxv;
-
- /// Rendezvous breakpoint.
- lldb::break_id_t m_dyld_bid;
-
- /// Contains AT_SYSINFO_EHDR, which means a vDSO has been
- /// mapped to the address space
- lldb::addr_t m_vdso_base;
-
- /// Loaded module list. (link map for each module)
- std::map<lldb::ModuleWP, lldb::addr_t, std::owner_less<lldb::ModuleWP>> m_loaded_modules;
-
- /// Enables a breakpoint on a function called by the runtime
- /// linker each time a module is loaded or unloaded.
- virtual void
- SetRendezvousBreakpoint();
-
- /// Callback routine which updates the current list of loaded modules based
- /// on the information supplied by the runtime linker.
- static bool
- RendezvousBreakpointHit(void *baton,
- lldb_private::StoppointCallbackContext *context,
- lldb::user_id_t break_id,
- lldb::user_id_t break_loc_id);
-
- /// Helper method for RendezvousBreakpointHit. Updates LLDB's current set
- /// of loaded modules.
- void
- RefreshModules();
-
- /// Updates the load address of every allocatable section in @p module.
- ///
- /// @param module The module to traverse.
- ///
- /// @param link_map_addr The virtual address of the link map for the @p module.
- ///
- /// @param base_addr The virtual base address @p module is loaded at.
- void
- UpdateLoadedSections(lldb::ModuleSP module,
- lldb::addr_t link_map_addr,
- lldb::addr_t base_addr,
- bool base_addr_is_offset) override;
-
- /// Removes the loaded sections from the target in @p module.
- ///
- /// @param module The module to traverse.
- void
- UnloadSections(const lldb::ModuleSP module) override;
-
- /// Resolves the entry point for the current inferior process and sets a
- /// breakpoint at that address.
- void
- ProbeEntry();
-
- /// Callback routine invoked when we hit the breakpoint on process entry.
- ///
- /// This routine is responsible for resolving the load addresses of all
- /// dependent modules required by the inferior and setting up the rendezvous
- /// breakpoint.
- static bool
- EntryBreakpointHit(void *baton,
- lldb_private::StoppointCallbackContext *context,
- lldb::user_id_t break_id,
- lldb::user_id_t break_loc_id);
-
- /// Helper for the entry breakpoint callback. Resolves the load addresses
- /// of all dependent modules.
- virtual void
- LoadAllCurrentModules();
-
- /// Computes a value for m_load_offset returning the computed address on
- /// success and LLDB_INVALID_ADDRESS on failure.
- lldb::addr_t
- ComputeLoadOffset();
-
- /// Computes a value for m_entry_point returning the computed address on
- /// success and LLDB_INVALID_ADDRESS on failure.
- lldb::addr_t
- GetEntryPoint();
-
- /// Evaluate if Aux vectors contain vDSO information
- /// in case they do, read and assign the address to m_vdso_base
- void
- EvalVdsoStatus();
-
- /// Loads Module from inferior process.
- void
- ResolveExecutableModule(lldb::ModuleSP &module_sp);
-
- bool
- AlwaysRelyOnEHUnwindInfo(lldb_private::SymbolContext &sym_ctx) override;
+ /// Runtime linker rendezvous structure.
+ DYLDRendezvous m_rendezvous;
+
+ /// Virtual load address of the inferior process.
+ lldb::addr_t m_load_offset;
+
+ /// Virtual entry address of the inferior process.
+ lldb::addr_t m_entry_point;
+
+ /// Auxiliary vector of the inferior process.
+ std::unique_ptr<AuxVector> m_auxv;
+
+ /// Rendezvous breakpoint.
+ lldb::break_id_t m_dyld_bid;
+
+ /// Contains AT_SYSINFO_EHDR, which means a vDSO has been
+ /// mapped to the address space
+ lldb::addr_t m_vdso_base;
+
+ /// Loaded module list. (link map for each module)
+ std::map<lldb::ModuleWP, lldb::addr_t, std::owner_less<lldb::ModuleWP>>
+ m_loaded_modules;
+
+ /// Enables a breakpoint on a function called by the runtime
+ /// linker each time a module is loaded or unloaded.
+ virtual void SetRendezvousBreakpoint();
+
+ /// Callback routine which updates the current list of loaded modules based
+ /// on the information supplied by the runtime linker.
+ static bool RendezvousBreakpointHit(
+ void *baton, lldb_private::StoppointCallbackContext *context,
+ lldb::user_id_t break_id, lldb::user_id_t break_loc_id);
+
+ /// Helper method for RendezvousBreakpointHit. Updates LLDB's current set
+ /// of loaded modules.
+ void RefreshModules();
+
+ /// Updates the load address of every allocatable section in @p module.
+ ///
+ /// @param module The module to traverse.
+ ///
+ /// @param link_map_addr The virtual address of the link map for the @p
+ /// module.
+ ///
+ /// @param base_addr The virtual base address @p module is loaded at.
+ void UpdateLoadedSections(lldb::ModuleSP module, lldb::addr_t link_map_addr,
+ lldb::addr_t base_addr,
+ bool base_addr_is_offset) override;
+
+ /// Removes the loaded sections from the target in @p module.
+ ///
+ /// @param module The module to traverse.
+ void UnloadSections(const lldb::ModuleSP module) override;
+
+ /// Resolves the entry point for the current inferior process and sets a
+ /// breakpoint at that address.
+ void ProbeEntry();
+
+ /// Callback routine invoked when we hit the breakpoint on process entry.
+ ///
+ /// This routine is responsible for resolving the load addresses of all
+ /// dependent modules required by the inferior and setting up the rendezvous
+ /// breakpoint.
+ static bool
+ EntryBreakpointHit(void *baton,
+ lldb_private::StoppointCallbackContext *context,
+ lldb::user_id_t break_id, lldb::user_id_t break_loc_id);
+
+ /// Helper for the entry breakpoint callback. Resolves the load addresses
+ /// of all dependent modules.
+ virtual void LoadAllCurrentModules();
+
+ /// Computes a value for m_load_offset returning the computed address on
+ /// success and LLDB_INVALID_ADDRESS on failure.
+ lldb::addr_t ComputeLoadOffset();
+
+ /// Computes a value for m_entry_point returning the computed address on
+ /// success and LLDB_INVALID_ADDRESS on failure.
+ lldb::addr_t GetEntryPoint();
+
+ /// Evaluate if Aux vectors contain vDSO information
+ /// in case they do, read and assign the address to m_vdso_base
+ void EvalVdsoStatus();
+
+ /// Loads Module from inferior process.
+ void ResolveExecutableModule(lldb::ModuleSP &module_sp);
+
+ bool AlwaysRelyOnEHUnwindInfo(lldb_private::SymbolContext &sym_ctx) override;
private:
- DISALLOW_COPY_AND_ASSIGN(DynamicLoaderPOSIXDYLD);
+ DISALLOW_COPY_AND_ASSIGN(DynamicLoaderPOSIXDYLD);
};
#endif // liblldb_DynamicLoaderPOSIXDYLD_h_
diff --git a/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp b/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp
index daa21adf3a9..04f1f339057 100644
--- a/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp
+++ b/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp
@@ -23,50 +23,42 @@ using namespace lldb_private;
// the plugin info class that gets handed out by the plugin factory and
// allows the lldb to instantiate an instance of this class.
//----------------------------------------------------------------------
-DynamicLoader *
-DynamicLoaderStatic::CreateInstance (Process* process, bool force)
-{
- bool create = force;
- if (!create)
- {
- const llvm::Triple &triple_ref = process->GetTarget().GetArchitecture().GetTriple();
- const llvm::Triple::OSType os_type = triple_ref.getOS();
- if ((os_type == llvm::Triple::UnknownOS))
- create = true;
+DynamicLoader *DynamicLoaderStatic::CreateInstance(Process *process,
+ bool force) {
+ bool create = force;
+ if (!create) {
+ const llvm::Triple &triple_ref =
+ process->GetTarget().GetArchitecture().GetTriple();
+ const llvm::Triple::OSType os_type = triple_ref.getOS();
+ if ((os_type == llvm::Triple::UnknownOS))
+ create = true;
+ }
+
+ if (!create) {
+ Module *exe_module = process->GetTarget().GetExecutableModulePointer();
+ if (exe_module) {
+ ObjectFile *object_file = exe_module->GetObjectFile();
+ if (object_file) {
+ create = (object_file->GetStrata() == ObjectFile::eStrataRawImage);
+ }
}
-
- if (!create)
- {
- Module *exe_module = process->GetTarget().GetExecutableModulePointer();
- if (exe_module)
- {
- ObjectFile *object_file = exe_module->GetObjectFile();
- if (object_file)
- {
- create = (object_file->GetStrata() == ObjectFile::eStrataRawImage);
- }
- }
- }
-
- if (create)
- return new DynamicLoaderStatic (process);
- return NULL;
+ }
+
+ if (create)
+ return new DynamicLoaderStatic(process);
+ return NULL;
}
//----------------------------------------------------------------------
// Constructor
//----------------------------------------------------------------------
-DynamicLoaderStatic::DynamicLoaderStatic (Process* process) :
- DynamicLoader(process)
-{
-}
+DynamicLoaderStatic::DynamicLoaderStatic(Process *process)
+ : DynamicLoader(process) {}
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
-DynamicLoaderStatic::~DynamicLoaderStatic()
-{
-}
+DynamicLoaderStatic::~DynamicLoaderStatic() {}
//------------------------------------------------------------------
/// Called after attaching a process.
@@ -74,11 +66,7 @@ DynamicLoaderStatic::~DynamicLoaderStatic()
/// Allow DynamicLoader plug-ins to execute some code after
/// attaching to a process.
//------------------------------------------------------------------
-void
-DynamicLoaderStatic::DidAttach ()
-{
- LoadAllImagesAtFileAddresses();
-}
+void DynamicLoaderStatic::DidAttach() { LoadAllImagesAtFileAddresses(); }
//------------------------------------------------------------------
/// Called after attaching a process.
@@ -86,124 +74,94 @@ DynamicLoaderStatic::DidAttach ()
/// Allow DynamicLoader plug-ins to execute some code after
/// attaching to a process.
//------------------------------------------------------------------
-void
-DynamicLoaderStatic::DidLaunch ()
-{
- LoadAllImagesAtFileAddresses();
-}
-
-void
-DynamicLoaderStatic::LoadAllImagesAtFileAddresses ()
-{
- const ModuleList &module_list = m_process->GetTarget().GetImages();
-
- ModuleList loaded_module_list;
-
- // Disable JIT for static dynamic loader targets
- m_process->SetCanJIT(false);
-
- std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
-
- const size_t num_modules = module_list.GetSize();
- for (uint32_t idx = 0; idx < num_modules; ++idx)
- {
- ModuleSP module_sp (module_list.GetModuleAtIndexUnlocked (idx));
- if (module_sp)
- {
- bool changed = false;
- ObjectFile *image_object_file = module_sp->GetObjectFile();
- if (image_object_file)
- {
- SectionList *section_list = image_object_file->GetSectionList ();
- if (section_list)
- {
- // All sections listed in the dyld image info structure will all
- // either be fixed up already, or they will all be off by a single
- // slide amount that is determined by finding the first segment
- // that is at file offset zero which also has bytes (a file size
- // that is greater than zero) in the object file.
-
- // Determine the slide amount (if any)
- const size_t num_sections = section_list->GetSize();
- size_t sect_idx = 0;
- for (sect_idx = 0; sect_idx < num_sections; ++sect_idx)
- {
- // Iterate through the object file sections to find the
- // first section that starts of file offset zero and that
- // has bytes in the file...
- SectionSP section_sp (section_list->GetSectionAtIndex (sect_idx));
- if (section_sp)
- {
- if (m_process->GetTarget().SetSectionLoadAddress (section_sp, section_sp->GetFileAddress()))
- changed = true;
- }
- }
- }
+void DynamicLoaderStatic::DidLaunch() { LoadAllImagesAtFileAddresses(); }
+
+void DynamicLoaderStatic::LoadAllImagesAtFileAddresses() {
+ const ModuleList &module_list = m_process->GetTarget().GetImages();
+
+ ModuleList loaded_module_list;
+
+ // Disable JIT for static dynamic loader targets
+ m_process->SetCanJIT(false);
+
+ std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
+
+ const size_t num_modules = module_list.GetSize();
+ for (uint32_t idx = 0; idx < num_modules; ++idx) {
+ ModuleSP module_sp(module_list.GetModuleAtIndexUnlocked(idx));
+ if (module_sp) {
+ bool changed = false;
+ ObjectFile *image_object_file = module_sp->GetObjectFile();
+ if (image_object_file) {
+ SectionList *section_list = image_object_file->GetSectionList();
+ if (section_list) {
+ // All sections listed in the dyld image info structure will all
+ // either be fixed up already, or they will all be off by a single
+ // slide amount that is determined by finding the first segment
+ // that is at file offset zero which also has bytes (a file size
+ // that is greater than zero) in the object file.
+
+ // Determine the slide amount (if any)
+ const size_t num_sections = section_list->GetSize();
+ size_t sect_idx = 0;
+ for (sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
+ // Iterate through the object file sections to find the
+ // first section that starts of file offset zero and that
+ // has bytes in the file...
+ SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx));
+ if (section_sp) {
+ if (m_process->GetTarget().SetSectionLoadAddress(
+ section_sp, section_sp->GetFileAddress()))
+ changed = true;
}
-
- if (changed)
- loaded_module_list.AppendIfNeeded (module_sp);
+ }
}
+ }
+
+ if (changed)
+ loaded_module_list.AppendIfNeeded(module_sp);
}
+ }
- m_process->GetTarget().ModulesDidLoad (loaded_module_list);
+ m_process->GetTarget().ModulesDidLoad(loaded_module_list);
}
ThreadPlanSP
-DynamicLoaderStatic::GetStepThroughTrampolinePlan (Thread &thread, bool stop_others)
-{
- return ThreadPlanSP();
+DynamicLoaderStatic::GetStepThroughTrampolinePlan(Thread &thread,
+ bool stop_others) {
+ return ThreadPlanSP();
}
-Error
-DynamicLoaderStatic::CanLoadImage ()
-{
- Error error;
- error.SetErrorString ("can't load images on with a static debug session");
- return error;
+Error DynamicLoaderStatic::CanLoadImage() {
+ Error error;
+ error.SetErrorString("can't load images on with a static debug session");
+ return error;
}
-void
-DynamicLoaderStatic::Initialize()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- GetPluginDescriptionStatic(),
- CreateInstance);
+void DynamicLoaderStatic::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance);
}
-void
-DynamicLoaderStatic::Terminate()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
+void DynamicLoaderStatic::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
}
-
-lldb_private::ConstString
-DynamicLoaderStatic::GetPluginNameStatic()
-{
- static ConstString g_name("static");
- return g_name;
+lldb_private::ConstString DynamicLoaderStatic::GetPluginNameStatic() {
+ static ConstString g_name("static");
+ return g_name;
}
-const char *
-DynamicLoaderStatic::GetPluginDescriptionStatic()
-{
- return "Dynamic loader plug-in that will load any images at the static addresses contained in each image.";
+const char *DynamicLoaderStatic::GetPluginDescriptionStatic() {
+ return "Dynamic loader plug-in that will load any images at the static "
+ "addresses contained in each image.";
}
-
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
-lldb_private::ConstString
-DynamicLoaderStatic::GetPluginName()
-{
- return GetPluginNameStatic();
-}
-
-uint32_t
-DynamicLoaderStatic::GetPluginVersion()
-{
- return 1;
+lldb_private::ConstString DynamicLoaderStatic::GetPluginName() {
+ return GetPluginNameStatic();
}
+uint32_t DynamicLoaderStatic::GetPluginVersion() { return 1; }
diff --git a/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.h b/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.h
index 67694c96025..c6122edf50c 100644
--- a/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.h
+++ b/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.h
@@ -14,69 +14,57 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/Target/DynamicLoader.h"
-#include "lldb/Host/FileSpec.h"
#include "lldb/Core/UUID.h"
+#include "lldb/Host/FileSpec.h"
+#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/Process.h"
-class DynamicLoaderStatic : public lldb_private::DynamicLoader
-{
+class DynamicLoaderStatic : public lldb_private::DynamicLoader {
public:
- DynamicLoaderStatic(lldb_private::Process *process);
+ DynamicLoaderStatic(lldb_private::Process *process);
- ~DynamicLoaderStatic() override;
+ ~DynamicLoaderStatic() override;
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
- static void
- Initialize();
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+ static void Initialize();
- static void
- Terminate();
+ static void Terminate();
- static lldb_private::ConstString
- GetPluginNameStatic();
+ static lldb_private::ConstString GetPluginNameStatic();
- static const char *
- GetPluginDescriptionStatic();
+ static const char *GetPluginDescriptionStatic();
- static lldb_private::DynamicLoader *
- CreateInstance (lldb_private::Process *process, bool force);
+ static lldb_private::DynamicLoader *
+ CreateInstance(lldb_private::Process *process, bool force);
- //------------------------------------------------------------------
- /// Called after attaching a process.
- ///
- /// Allow DynamicLoader plug-ins to execute some code after
- /// attaching to a process.
- //------------------------------------------------------------------
- void
- DidAttach() override;
+ //------------------------------------------------------------------
+ /// Called after attaching a process.
+ ///
+ /// Allow DynamicLoader plug-ins to execute some code after
+ /// attaching to a process.
+ //------------------------------------------------------------------
+ void DidAttach() override;
- void
- DidLaunch() override;
+ void DidLaunch() override;
- lldb::ThreadPlanSP
- GetStepThroughTrampolinePlan(lldb_private::Thread &thread,
- bool stop_others) override;
+ lldb::ThreadPlanSP GetStepThroughTrampolinePlan(lldb_private::Thread &thread,
+ bool stop_others) override;
- lldb_private::Error
- CanLoadImage() override;
+ lldb_private::Error CanLoadImage() override;
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- lldb_private::ConstString
- GetPluginName() override;
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ lldb_private::ConstString GetPluginName() override;
- uint32_t
- GetPluginVersion() override;
+ uint32_t GetPluginVersion() override;
private:
- void
- LoadAllImagesAtFileAddresses ();
+ void LoadAllImagesAtFileAddresses();
- DISALLOW_COPY_AND_ASSIGN (DynamicLoaderStatic);
+ DISALLOW_COPY_AND_ASSIGN(DynamicLoaderStatic);
};
#endif // liblldb_DynamicLoaderStatic_h_
diff --git a/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp b/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp
index dd391b4ca4d..20bf3609f46 100644
--- a/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp
+++ b/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp
@@ -1,4 +1,5 @@
-//===-- DynamicLoaderWindowsDYLD.cpp --------------------------------*- C++ -*-===//
+//===-- DynamicLoaderWindowsDYLD.cpp --------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -19,86 +20,57 @@ using namespace lldb;
using namespace lldb_private;
DynamicLoaderWindowsDYLD::DynamicLoaderWindowsDYLD(Process *process)
- : DynamicLoader(process)
-{
-}
+ : DynamicLoader(process) {}
-DynamicLoaderWindowsDYLD::~DynamicLoaderWindowsDYLD()
-{
-}
+DynamicLoaderWindowsDYLD::~DynamicLoaderWindowsDYLD() {}
-void
-DynamicLoaderWindowsDYLD::Initialize()
-{
- PluginManager::RegisterPlugin(GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance);
+void DynamicLoaderWindowsDYLD::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance);
}
-void
-DynamicLoaderWindowsDYLD::Terminate()
-{
-}
+void DynamicLoaderWindowsDYLD::Terminate() {}
-ConstString
-DynamicLoaderWindowsDYLD::GetPluginNameStatic()
-{
- static ConstString g_plugin_name("windows-dyld");
- return g_plugin_name;
+ConstString DynamicLoaderWindowsDYLD::GetPluginNameStatic() {
+ static ConstString g_plugin_name("windows-dyld");
+ return g_plugin_name;
}
-const char *
-DynamicLoaderWindowsDYLD::GetPluginDescriptionStatic()
-{
- return "Dynamic loader plug-in that watches for shared library "
- "loads/unloads in Windows processes.";
+const char *DynamicLoaderWindowsDYLD::GetPluginDescriptionStatic() {
+ return "Dynamic loader plug-in that watches for shared library "
+ "loads/unloads in Windows processes.";
}
-DynamicLoader *
-DynamicLoaderWindowsDYLD::CreateInstance(Process *process, bool force)
-{
- bool should_create = force;
- if (!should_create)
- {
- const llvm::Triple &triple_ref = process->GetTarget().GetArchitecture().GetTriple();
- if (triple_ref.getOS() == llvm::Triple::Win32)
- should_create = true;
- }
-
- if (should_create)
- return new DynamicLoaderWindowsDYLD(process);
-
- return nullptr;
-}
+DynamicLoader *DynamicLoaderWindowsDYLD::CreateInstance(Process *process,
+ bool force) {
+ bool should_create = force;
+ if (!should_create) {
+ const llvm::Triple &triple_ref =
+ process->GetTarget().GetArchitecture().GetTriple();
+ if (triple_ref.getOS() == llvm::Triple::Win32)
+ should_create = true;
+ }
-void
-DynamicLoaderWindowsDYLD::DidAttach()
-{
-}
+ if (should_create)
+ return new DynamicLoaderWindowsDYLD(process);
-void
-DynamicLoaderWindowsDYLD::DidLaunch()
-{
+ return nullptr;
}
-Error
-DynamicLoaderWindowsDYLD::CanLoadImage()
-{
- return Error();
-}
+void DynamicLoaderWindowsDYLD::DidAttach() {}
-ConstString
-DynamicLoaderWindowsDYLD::GetPluginName()
-{
- return GetPluginNameStatic();
-}
+void DynamicLoaderWindowsDYLD::DidLaunch() {}
-uint32_t
-DynamicLoaderWindowsDYLD::GetPluginVersion()
-{
- return 1;
+Error DynamicLoaderWindowsDYLD::CanLoadImage() { return Error(); }
+
+ConstString DynamicLoaderWindowsDYLD::GetPluginName() {
+ return GetPluginNameStatic();
}
+uint32_t DynamicLoaderWindowsDYLD::GetPluginVersion() { return 1; }
+
ThreadPlanSP
-DynamicLoaderWindowsDYLD::GetStepThroughTrampolinePlan(Thread &thread, bool stop)
-{
- return ThreadPlanSP();
+DynamicLoaderWindowsDYLD::GetStepThroughTrampolinePlan(Thread &thread,
+ bool stop) {
+ return ThreadPlanSP();
}
diff --git a/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h b/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h
index 8c479819c53..3494082eea8 100644
--- a/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h
+++ b/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h
@@ -14,33 +14,32 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-forward.h"
#include "lldb/Target/DynamicLoader.h"
+#include "lldb/lldb-forward.h"
-namespace lldb_private
-{
+namespace lldb_private {
-class DynamicLoaderWindowsDYLD : public DynamicLoader
-{
+class DynamicLoaderWindowsDYLD : public DynamicLoader {
public:
- DynamicLoaderWindowsDYLD(Process *process);
+ DynamicLoaderWindowsDYLD(Process *process);
- ~DynamicLoaderWindowsDYLD() override;
+ ~DynamicLoaderWindowsDYLD() override;
- static void Initialize();
- static void Terminate();
- static ConstString GetPluginNameStatic();
- static const char *GetPluginDescriptionStatic();
+ static void Initialize();
+ static void Terminate();
+ static ConstString GetPluginNameStatic();
+ static const char *GetPluginDescriptionStatic();
- static DynamicLoader *CreateInstance(Process *process, bool force);
+ static DynamicLoader *CreateInstance(Process *process, bool force);
- void DidAttach() override;
- void DidLaunch() override;
- Error CanLoadImage() override;
- lldb::ThreadPlanSP GetStepThroughTrampolinePlan(Thread &thread, bool stop) override;
+ void DidAttach() override;
+ void DidLaunch() override;
+ Error CanLoadImage() override;
+ lldb::ThreadPlanSP GetStepThroughTrampolinePlan(Thread &thread,
+ bool stop) override;
- ConstString GetPluginName() override;
- uint32_t GetPluginVersion() override;
+ ConstString GetPluginName() override;
+ uint32_t GetPluginVersion() override;
};
} // namespace lldb_private
OpenPOWER on IntegriCloud