[Lldb-commits] [lldb] 1a608cf - Recognize a platform binary in ProcessGDBRemote which determines plugins
Jason Molenda via lldb-commits
lldb-commits at lists.llvm.org
Fri Sep 9 14:57:20 PDT 2022
Author: Jason Molenda
Date: 2022-09-09T14:57:08-07:00
New Revision: 1a608cfb5ca81d7b1d8ebd6b21c6be9db59c837a
URL: https://github.com/llvm/llvm-project/commit/1a608cfb5ca81d7b1d8ebd6b21c6be9db59c837a
DIFF: https://github.com/llvm/llvm-project/commit/1a608cfb5ca81d7b1d8ebd6b21c6be9db59c837a.diff
LOG: Recognize a platform binary in ProcessGDBRemote which determines plugins
Complete support of the binary-addresses key in the qProcessInfo packet
in ProcessGDBRemote, for detecting if one of the binaries needs to be
handled by a Platform plugin, and can be used to set the Process'
DynamicLoader plugin and the Target's Platform plugin.
Implement this method in PlatformDarwinKernel to recognize a kernel
fileset at that address, find the actual kernel address in the
fileset, set DynamicLoaderDarwinKernel and PlatformDarwinKernel
in the Process/Target; register the kernel address with the dynamic
loader so it will be loaded later during attach.
This patch only addresses the live debug scenario with a gdb remote
serial protocol connection. I'll handle corefiles in a subsequent
patch that builds on this.
Differential Revision: https://reviews.llvm.org/D133534
rdar://98754861
Added:
Modified:
lldb/include/lldb/Target/Platform.h
lldb/include/lldb/Target/Process.h
lldb/source/Core/DynamicLoader.cpp
lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
lldb/source/Plugins/Platform/MacOSX/CMakeLists.txt
lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp
lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.h
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
lldb/source/Target/Platform.cpp
lldb/source/Target/Process.cpp
Removed:
################################################################################
diff --git a/lldb/include/lldb/Target/Platform.h b/lldb/include/lldb/Target/Platform.h
index 868f10689bb18..5f8cd467847de 100644
--- a/lldb/include/lldb/Target/Platform.h
+++ b/lldb/include/lldb/Target/Platform.h
@@ -846,6 +846,34 @@ class Platform : public PluginInterface {
return nullptr;
}
+ /// Detect a binary in memory that will determine which Platform and
+ /// DynamicLoader should be used in this target/process, and update
+ /// the Platform/DynamicLoader.
+ /// The binary will be loaded into the Target, or will be registered with
+ /// the DynamicLoader so that it will be loaded at a later stage. Returns
+ /// true to indicate that this is a platform binary and has been
+ /// loaded/registered, no further action should be taken by the caller.
+ ///
+ /// \param[in] process
+ /// Process read memory from, a Process must be provided.
+ ///
+ /// \param[in] addr
+ /// Address of a binary in memory.
+ ///
+ /// \param[in] notify
+ /// Whether ModulesDidLoad should be called, if a binary is loaded.
+ /// Caller may prefer to call ModulesDidLoad for multiple binaries
+ /// that were loaded at the same time.
+ ///
+ /// \return
+ /// Returns true if the binary was loaded in the target (or will be
+ /// via a DynamicLoader). Returns false if the binary was not
+ /// loaded/registered, and the caller must load it into the target.
+ virtual bool LoadPlatformBinaryAndSetup(Process *process, lldb::addr_t addr,
+ bool notify) {
+ return false;
+ }
+
virtual CompilerType GetSiginfoType(const llvm::Triple &triple);
virtual Args GetExtraStartupCommands();
@@ -1026,6 +1054,32 @@ class PlatformList {
lldb::PlatformSP Create(llvm::StringRef name);
+ /// Detect a binary in memory that will determine which Platform and
+ /// DynamicLoader should be used in this target/process, and update
+ /// the Platform/DynamicLoader.
+ /// The binary will be loaded into the Target, or will be registered with
+ /// the DynamicLoader so that it will be loaded at a later stage. Returns
+ /// true to indicate that this is a platform binary and has been
+ /// loaded/registered, no further action should be taken by the caller.
+ ///
+ /// \param[in] process
+ /// Process read memory from, a Process must be provided.
+ ///
+ /// \param[in] addr
+ /// Address of a binary in memory.
+ ///
+ /// \param[in] notify
+ /// Whether ModulesDidLoad should be called, if a binary is loaded.
+ /// Caller may prefer to call ModulesDidLoad for multiple binaries
+ /// that were loaded at the same time.
+ ///
+ /// \return
+ /// Returns true if the binary was loaded in the target (or will be
+ /// via a DynamicLoader). Returns false if the binary was not
+ /// loaded/registered, and the caller must load it into the target.
+ bool LoadPlatformBinaryAndSetup(Process *process, lldb::addr_t addr,
+ bool notify);
+
protected:
typedef std::vector<lldb::PlatformSP> collection;
mutable std::recursive_mutex m_mutex;
diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h
index 5bca9f076cb58..4f5ae45a431ec 100644
--- a/lldb/include/lldb/Target/Process.h
+++ b/lldb/include/lldb/Target/Process.h
@@ -641,6 +641,8 @@ class Process : public std::enable_shared_from_this<Process>,
/// plug-in.
virtual DynamicLoader *GetDynamicLoader();
+ void SetDynamicLoader(lldb::DynamicLoaderUP dyld);
+
// Returns AUXV structure found in many ELF-based environments.
//
// The default action is to return an empty data buffer.
diff --git a/lldb/source/Core/DynamicLoader.cpp b/lldb/source/Core/DynamicLoader.cpp
index 1fe60e000c6d5..f987023a16074 100644
--- a/lldb/source/Core/DynamicLoader.cpp
+++ b/lldb/source/Core/DynamicLoader.cpp
@@ -230,6 +230,10 @@ ModuleSP DynamicLoader::LoadBinaryWithUUIDAndAddress(Process *process,
Log *log = GetLog(LLDBLog::DynamicLoader);
if (module_sp.get()) {
+ // Ensure the Target has an architecture set in case
+ // we need it while processing this binary/eh_frame/debug info.
+ if (!target.GetArchitecture().IsValid())
+ target.SetArchitecture(module_sp->GetArchitecture());
target.GetImages().AppendIfNeeded(module_sp, false);
bool changed = false;
diff --git a/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp b/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
index c76fb2a8d7c95..533585a9b8d18 100644
--- a/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
+++ b/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
@@ -130,6 +130,20 @@ static DynamicLoaderDarwinKernelProperties &GetGlobalProperties() {
return g_settings;
}
+static bool is_kernel(Module *module) {
+ if (!module)
+ return false;
+ ObjectFile *objfile = module->GetObjectFile();
+ if (!objfile)
+ return false;
+ if (objfile->GetType() != ObjectFile::eTypeExecutable)
+ return false;
+ if (objfile->GetStrata() != ObjectFile::eStrataKernel)
+ return false;
+
+ return true;
+}
+
// 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.
@@ -138,15 +152,8 @@ DynamicLoader *DynamicLoaderDarwinKernel::CreateInstance(Process *process,
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 nullptr;
- }
- }
- }
+ if (!is_kernel(process->GetTarget().GetExecutableModulePointer()))
+ return nullptr;
// If the target's architecture does not look like an Apple environment,
// this plugin should not create an instance.
@@ -176,7 +183,6 @@ DynamicLoader *DynamicLoaderDarwinKernel::CreateInstance(Process *process,
// 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);
@@ -188,18 +194,15 @@ DynamicLoader *DynamicLoaderDarwinKernel::CreateInstance(Process *process,
lldb::addr_t
DynamicLoaderDarwinKernel::SearchForDarwinKernel(Process *process) {
addr_t kernel_load_address = process->GetImageInfoAddress();
- if (kernel_load_address == LLDB_INVALID_ADDRESS) {
+ 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);
- }
- }
- }
- }
+ 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;
}
@@ -209,16 +212,11 @@ DynamicLoaderDarwinKernel::SearchForDarwinKernel(Process *process) {
lldb::addr_t
DynamicLoaderDarwinKernel::SearchForKernelAtSameLoadAddr(Process *process) {
Module *exe_module = process->GetTarget().GetExecutableModulePointer();
- if (exe_module == nullptr)
- return LLDB_INVALID_ADDRESS;
- ObjectFile *exe_objfile = exe_module->GetObjectFile();
- if (exe_objfile == nullptr)
+ if (!is_kernel(process->GetTarget().GetExecutableModulePointer()))
return LLDB_INVALID_ADDRESS;
- if (exe_objfile->GetType() != ObjectFile::eTypeExecutable ||
- exe_objfile->GetStrata() != ObjectFile::eStrataKernel)
- return LLDB_INVALID_ADDRESS;
+ ObjectFile *exe_objfile = exe_module->GetObjectFile();
if (!exe_objfile->GetBaseAddress().IsValid())
return LLDB_INVALID_ADDRESS;
@@ -475,8 +473,7 @@ DynamicLoaderDarwinKernel::CheckForKernelImageAtAddress(lldb::addr_t addr,
return UUID();
}
- if (exe_objfile->GetType() == ObjectFile::eTypeExecutable &&
- exe_objfile->GetStrata() == ObjectFile::eStrataKernel) {
+ if (is_kernel(memory_module_sp.get())) {
ArchSpec kernel_arch(eArchTypeMachO, header.cputype, header.cpusubtype);
if (!process->GetTarget().GetArchitecture().IsCompatibleMatch(
kernel_arch)) {
@@ -525,10 +522,10 @@ void DynamicLoaderDarwinKernel::UpdateIfNeeded() {
LoadKernelModuleIfNeeded();
SetNotificationBreakpointIfNeeded();
}
-/// Called after attaching a process.
-///
-/// Allow DynamicLoader plug-ins to execute some code after
-/// attaching to a process.
+
+/// We've attached to a remote connection, or read a corefile.
+/// Now load the kernel binary and potentially the kexts, add
+/// them to the Target.
void DynamicLoaderDarwinKernel::DidAttach() {
PrivateInitialize(m_process);
UpdateIfNeeded();
@@ -574,14 +571,7 @@ bool DynamicLoaderDarwinKernel::KextImageInfo::LoadImageAtFileAddress(
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;
- }
- }
+ m_kernel_image = is_kernel(module_sp.get());
}
ModuleSP DynamicLoaderDarwinKernel::KextImageInfo::GetModule() {
@@ -671,18 +661,7 @@ bool DynamicLoaderDarwinKernel::KextImageInfo::ReadMemoryModule(
if (memory_module_sp.get() == nullptr)
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;
- }
- }
+ bool this_is_kernel = is_kernel(memory_module_sp.get());
// 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
@@ -707,8 +686,8 @@ bool DynamicLoaderDarwinKernel::KextImageInfo::ReadMemoryModule(
}
m_memory_module_sp = memory_module_sp;
- m_kernel_image = is_kernel;
- if (is_kernel) {
+ m_kernel_image = this_is_kernel;
+ if (this_is_kernel) {
if (log) {
// This is unusual and probably not intended
LLDB_LOGF(log,
@@ -718,22 +697,6 @@ bool DynamicLoaderDarwinKernel::KextImageInfo::ReadMemoryModule(
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
diff erent 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;
@@ -771,6 +734,17 @@ bool DynamicLoaderDarwinKernel::KextImageInfo::LoadImageUsingMemoryModule(
Stream &s = target.GetDebugger().GetOutputStream();
s.Printf("Kernel UUID: %s\n", m_uuid.GetAsString().c_str());
s.Printf("Load Address: 0x%" PRIx64 "\n", m_load_address);
+
+ // Start of a kernel debug session, we have the UUID of the kernel.
+ // Go through the target's list of modules and if there are any kernel
+ // modules with non-matching UUIDs, remove them. The user may have added
+ // the wrong kernel binary manually and it will only confuse things.
+ ModuleList incorrect_kernels;
+ for (ModuleSP module_sp : target.GetImages().Modules()) {
+ if (is_kernel(module_sp.get()) && module_sp->GetUUID() != m_uuid)
+ incorrect_kernels.Append(module_sp);
+ }
+ target.GetImages().Remove(incorrect_kernels);
}
if (!m_module_sp) {
@@ -841,10 +815,6 @@ bool DynamicLoaderDarwinKernel::KextImageInfo::LoadImageUsingMemoryModule(
if (m_module_sp) {
if (m_uuid.IsValid() && m_module_sp->GetUUID() == m_uuid) {
target.GetImages().AppendIfNeeded(m_module_sp, false);
- if (IsKernel() &&
- target.GetExecutableModulePointer() != m_module_sp.get()) {
- target.SetExecutableModule(m_module_sp, eLoadDependentsNo);
- }
}
}
}
@@ -980,8 +950,11 @@ DynamicLoaderDarwinKernel::KextImageInfo::GetArchitecture() const {
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);
+ ModuleSP module_sp = m_process->GetTarget().GetExecutableModule();
+ if (is_kernel(module_sp.get())) {
+ m_kernel.SetModule(module_sp);
+ m_kernel.SetIsKernel(true);
+ }
ConstString kernel_name("mach_kernel");
if (m_kernel.GetModule().get() && m_kernel.GetModule()->GetObjectFile() &&
diff --git a/lldb/source/Plugins/Platform/MacOSX/CMakeLists.txt b/lldb/source/Plugins/Platform/MacOSX/CMakeLists.txt
index 3b43598741ed4..7435bef2cd1f2 100644
--- a/lldb/source/Plugins/Platform/MacOSX/CMakeLists.txt
+++ b/lldb/source/Plugins/Platform/MacOSX/CMakeLists.txt
@@ -44,6 +44,8 @@ add_lldb_library(lldbPluginPlatformMacOSX PLUGIN
lldbSymbol
lldbTarget
lldbUtility
+ lldbPluginDynamicLoaderDarwinKernel
+ lldbPluginObjectContainerMachOFileset
lldbPluginPlatformPOSIX
${OBJC_LIBS}
CLANG_LIBS
diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp
index 337e3bb2f9723..8ae211f102cb3 100644
--- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp
@@ -12,6 +12,7 @@
// source/Host/macosx/cfcpp utilities
#include "lldb/Breakpoint/BreakpointLocation.h"
+#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleList.h"
#include "lldb/Core/ModuleSpec.h"
@@ -26,6 +27,7 @@
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/ArchSpec.h"
+#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"
@@ -39,6 +41,8 @@
#include <memory>
#include "Host/macosx/cfcpp/CFCBundle.h"
+#include "Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h"
+#include "Plugins/ObjectContainer/Mach-O-Fileset/ObjectContainerMachOFileset.h"
using namespace lldb;
using namespace lldb_private;
@@ -724,23 +728,28 @@ Status PlatformDarwinKernel::GetSharedModule(
// "com.apple.driver.AppleIRController") and search our kext index.
std::string kext_bundle_id = platform_file.GetPath();
- if (!kext_bundle_id.empty() && module_spec.GetUUID().IsValid()) {
- if (kext_bundle_id == "mach_kernel") {
- return GetSharedModuleKernel(module_spec, process, module_sp,
- module_search_paths_ptr, old_modules,
- did_create_ptr);
+ if (module_spec.GetUUID().IsValid()) {
+ // DynamicLoaderDarwinKernel uses the magic name mach_kernel,
+ // UUID search can get here with no name - and it may be a kernel.
+ if (kext_bundle_id == "mach_kernel" || kext_bundle_id.empty()) {
+ error = GetSharedModuleKernel(module_spec, process, module_sp,
+ module_search_paths_ptr, old_modules,
+ did_create_ptr);
+ if (error.Success() && module_sp) {
+ return error;
+ }
} else {
return GetSharedModuleKext(module_spec, process, module_sp,
module_search_paths_ptr, old_modules,
did_create_ptr);
}
- } else {
- // Give the generic methods, including possibly calling into DebugSymbols
- // framework on macOS systems, a chance.
- return PlatformDarwin::GetSharedModule(module_spec, process, module_sp,
- module_search_paths_ptr, old_modules,
- did_create_ptr);
}
+
+ // Give the generic methods, including possibly calling into DebugSymbols
+ // framework on macOS systems, a chance.
+ return PlatformDarwin::GetSharedModule(module_spec, process, module_sp,
+ module_search_paths_ptr, old_modules,
+ did_create_ptr);
}
Status PlatformDarwinKernel::GetSharedModuleKext(
@@ -798,7 +807,8 @@ Status PlatformDarwinKernel::GetSharedModuleKernel(
module_sp->MatchesModuleSpec(kern_spec)) {
// module_sp is an actual kernel binary we want to add.
if (process) {
- process->GetTarget().GetImages().AppendIfNeeded(module_sp);
+ const bool notify = false;
+ process->GetTarget().GetImages().AppendIfNeeded(module_sp, notify);
error.Clear();
return error;
} else {
@@ -830,7 +840,8 @@ Status PlatformDarwinKernel::GetSharedModuleKernel(
module_sp->MatchesModuleSpec(kern_spec)) {
// module_sp is an actual kernel binary we want to add.
if (process) {
- process->GetTarget().GetImages().AppendIfNeeded(module_sp);
+ const bool notify = false;
+ process->GetTarget().GetImages().AppendIfNeeded(module_sp, notify);
error.Clear();
return error;
} else {
@@ -908,6 +919,70 @@ Status PlatformDarwinKernel::ExamineKextForMatchingUUID(
return {};
}
+static addr_t find_kernel_in_macho_fileset(Process *process,
+ addr_t input_addr) {
+ Status error;
+ WritableDataBufferSP header_data(new DataBufferHeap(512, 0));
+ if (!process->ReadMemory(input_addr, header_data->GetBytes(),
+ header_data->GetByteSize(), error) ||
+ !error.Success())
+ return LLDB_INVALID_ADDRESS;
+ ModuleSP module_sp(new Module(ModuleSpec()));
+ ObjectContainerSP container_sp(
+ ObjectContainerMachOFileset::CreateMemoryInstance(
+ module_sp, header_data, process->shared_from_this(), input_addr));
+ if (!container_sp)
+ return LLDB_INVALID_ADDRESS;
+
+ ObjectContainerMachOFileset *fileset_container =
+ static_cast<ObjectContainerMachOFileset *>(container_sp.get());
+ ObjectContainerMachOFileset::Entry *entry =
+ fileset_container->FindEntry("com.apple.kernel");
+ if (entry)
+ return entry->vmaddr;
+ return LLDB_INVALID_ADDRESS;
+}
+
+bool PlatformDarwinKernel::LoadPlatformBinaryAndSetup(Process *process,
+ lldb::addr_t input_addr,
+ bool notify) {
+ Log *log =
+ GetLog(LLDBLog::Platform | LLDBLog::DynamicLoader | LLDBLog::Process);
+
+ if (!process)
+ return false;
+
+ addr_t actual_address = find_kernel_in_macho_fileset(process, input_addr);
+
+ LLDB_LOGF(log,
+ "PlatformDarwinKernel::%s check address 0x%" PRIx64 " for "
+ "a macho fileset, got back kernel address 0x%" PRIx64,
+ __FUNCTION__, input_addr, actual_address);
+
+ if (actual_address == LLDB_INVALID_ADDRESS)
+ return false;
+
+ // We have a xnu kernel binary, this is a kernel debug session.
+ // Set the Target's Platform to be PlatformDarwinKernel, and the
+ // Process' DynamicLoader to be DynamicLoaderDarwinKernel.
+
+ PlatformSP platform_sp =
+ process->GetTarget().GetDebugger().GetPlatformList().Create(
+ PlatformDarwinKernel::GetPluginNameStatic());
+ if (platform_sp)
+ process->GetTarget().SetPlatform(platform_sp);
+
+ DynamicLoaderUP dyld_up =
+ std::make_unique<DynamicLoaderDarwinKernel>(process, actual_address);
+ if (!dyld_up)
+ return false;
+
+ // Process owns it now
+ process->SetDynamicLoader(std::move(dyld_up));
+
+ return true;
+}
+
std::vector<ArchSpec> PlatformDarwinKernel::GetSupportedArchitectures(
const ArchSpec &process_host_arch) {
std::vector<ArchSpec> result;
diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.h b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.h
index c135c53348d60..1b0708cd9f8dc 100644
--- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.h
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.h
@@ -154,6 +154,9 @@ class PlatformDarwinKernel : public PlatformDarwin {
const UUID &uuid, const ArchSpec &arch,
lldb::ModuleSP &exe_module_sp);
+ bool LoadPlatformBinaryAndSetup(Process *process, lldb::addr_t addr,
+ bool notify) override;
+
// Most of the ivars are assembled under FileSystem::EnumerateDirectory calls
// where the function being called for each file/directory must be static.
// We'll pass a this pointer as a baton and access the ivars directly.
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index 4bc61394cfaef..7e4688030c5b2 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -2206,12 +2206,13 @@ bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) {
++num_keys_decoded;
}
} else if (name.equals("binary-addresses")) {
- addr_t addr;
- while (!value.empty()) {
- llvm::StringRef addr_str;
- std::tie(addr_str, value) = value.split(',');
- if (!addr_str.getAsInteger(16, addr))
- m_binary_addresses.push_back(addr);
+ m_binary_addresses.clear();
+ ++num_keys_decoded;
+ for (llvm::StringRef x : llvm::split(value, ',')) {
+ addr_t vmaddr;
+ x.consume_front("0x");
+ if (llvm::to_integer(x, vmaddr, 16))
+ m_binary_addresses.push_back(vmaddr);
}
}
}
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 2987ba5265ff0..d0f98462f1e09 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -593,8 +593,19 @@ Status ProcessGDBRemote::DoConnectRemote(llvm::StringRef remote_url) {
UUID uuid;
const bool value_is_slide = false;
for (addr_t addr : bin_addrs) {
- const bool force_symbol_search = true;
const bool notify = true;
+ // First see if this is a special platform
+ // binary that may determine the DynamicLoader and
+ // Platform to be used in this Process/Target in the
+ // process of loading it.
+ if (GetTarget()
+ .GetDebugger()
+ .GetPlatformList()
+ .LoadPlatformBinaryAndSetup(this, addr, notify))
+ continue;
+
+ const bool force_symbol_search = true;
+ // Second manually load this binary into the Target.
DynamicLoader::LoadBinaryWithUUIDAndAddress(
this, uuid, addr, value_is_slide, force_symbol_search, notify);
}
diff --git a/lldb/source/Target/Platform.cpp b/lldb/source/Target/Platform.cpp
index 5be2ff36f35c1..4e09a6cf35627 100644
--- a/lldb/source/Target/Platform.cpp
+++ b/lldb/source/Target/Platform.cpp
@@ -2079,3 +2079,21 @@ PlatformSP PlatformList::Create(llvm::StringRef name) {
m_platforms.push_back(platform_sp);
return platform_sp;
}
+
+bool PlatformList::LoadPlatformBinaryAndSetup(Process *process,
+ lldb::addr_t addr, bool notify) {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+
+ PlatformCreateInstance create_callback;
+ for (int idx = 0;
+ (create_callback = PluginManager::GetPlatformCreateCallbackAtIndex(idx));
+ ++idx) {
+ ArchSpec arch;
+ PlatformSP platform_sp = create_callback(true, &arch);
+ if (platform_sp) {
+ if (platform_sp->LoadPlatformBinaryAndSetup(process, addr, notify))
+ return true;
+ }
+ }
+ return false;
+}
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index 68d0321b15bb6..31e15d42a2e3f 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -2653,6 +2653,10 @@ DynamicLoader *Process::GetDynamicLoader() {
return m_dyld_up.get();
}
+void Process::SetDynamicLoader(DynamicLoaderUP dyld_up) {
+ m_dyld_up = std::move(dyld_up);
+}
+
DataExtractor Process::GetAuxvData() { return DataExtractor(); }
llvm::Expected<bool> Process::SaveCore(llvm::StringRef outfile) {
More information about the lldb-commits
mailing list