forked from OSchip/llvm-project
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
This commit is contained in:
parent
bd16ffb389
commit
1a608cfb5c
|
@ -846,6 +846,34 @@ public:
|
|||
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 @@ public:
|
|||
|
||||
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;
|
||||
|
|
|
@ -641,6 +641,8 @@ public:
|
|||
/// 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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
||||
if (!is_kernel(process->GetTarget().GetExecutableModulePointer()))
|
||||
return LLDB_INVALID_ADDRESS;
|
||||
|
||||
ObjectFile *exe_objfile = exe_module->GetObjectFile();
|
||||
if (exe_objfile == nullptr)
|
||||
return LLDB_INVALID_ADDRESS;
|
||||
|
||||
if (exe_objfile->GetType() != ObjectFile::eTypeExecutable ||
|
||||
exe_objfile->GetStrata() != ObjectFile::eStrataKernel)
|
||||
return LLDB_INVALID_ADDRESS;
|
||||
|
||||
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 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;
|
||||
|
@ -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() &&
|
||||
|
|
|
@ -44,6 +44,8 @@ add_lldb_library(lldbPluginPlatformMacOSX PLUGIN
|
|||
lldbSymbol
|
||||
lldbTarget
|
||||
lldbUtility
|
||||
lldbPluginDynamicLoaderDarwinKernel
|
||||
lldbPluginObjectContainerMachOFileset
|
||||
lldbPluginPlatformPOSIX
|
||||
${OBJC_LIBS}
|
||||
CLANG_LIBS
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -154,6 +154,9 @@ protected:
|
|||
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.
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue