jasonmolenda updated this revision to Diff 458970. jasonmolenda added a comment.
Update the patch to address Jim's comments/suggestions. Biggest change was to clean up how DynamicLoaderDarwinKernel filters out any kernels in the Target that don't match the UUID of the actually running kernel. There was a vague attempt at this before, checking the target's ExecutableModule, but that assumes there was only one module loaded and it was the wrong kernel. Easier to step through everything loaded in the target and eliminate these, and clearer what's being done. I had the same sequence for detecting if a module is a kernel in a bunch of places so I added `module_is_a_kernel()` as a static function there. I also renamed the method in Platform and PlatformList to `LoadSpecialBinaryAndSetDynamicLoader()`, to help make it clear that this is an uncommon use case, so someone doesn't try to use it for loading general binaries. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D133534/new/ https://reviews.llvm.org/D133534 Files: 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/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 lldb/unittests/Core/CMakeLists.txt lldb/unittests/Interpreter/CMakeLists.txt lldb/unittests/Platform/CMakeLists.txt lldb/unittests/Process/CMakeLists.txt lldb/unittests/SymbolFile/DWARF/CMakeLists.txt
Index: lldb/unittests/SymbolFile/DWARF/CMakeLists.txt =================================================================== --- lldb/unittests/SymbolFile/DWARF/CMakeLists.txt +++ lldb/unittests/SymbolFile/DWARF/CMakeLists.txt @@ -10,10 +10,12 @@ lldbCore lldbHost lldbSymbol + lldbPluginDynamicLoaderDarwinKernel lldbPluginObjectFilePECOFF lldbPluginSymbolFileDWARF lldbPluginSymbolFilePDB lldbPluginTypeSystemClang + lldbPluginObjectContainerMachOFileset lldbPluginPlatformMacOSX lldbUtilityHelpers lldbSymbolHelpers Index: lldb/unittests/Process/CMakeLists.txt =================================================================== --- lldb/unittests/Process/CMakeLists.txt +++ lldb/unittests/Process/CMakeLists.txt @@ -17,5 +17,7 @@ lldbUtility lldbUtilityHelpers lldbInterpreter + lldbPluginDynamicLoaderDarwinKernel + lldbPluginObjectContainerMachOFileset lldbPluginPlatformMacOSX ) Index: lldb/unittests/Platform/CMakeLists.txt =================================================================== --- lldb/unittests/Platform/CMakeLists.txt +++ lldb/unittests/Platform/CMakeLists.txt @@ -6,6 +6,8 @@ PlatformTest.cpp LINK_LIBS + lldbPluginDynamicLoaderDarwinKernel + lldbPluginObjectContainerMachOFileset lldbPluginPlatformFreeBSD lldbPluginPlatformLinux lldbPluginPlatformMacOSX Index: lldb/unittests/Interpreter/CMakeLists.txt =================================================================== --- lldb/unittests/Interpreter/CMakeLists.txt +++ lldb/unittests/Interpreter/CMakeLists.txt @@ -14,6 +14,8 @@ lldbUtility lldbUtilityHelpers lldbInterpreter + lldbPluginDynamicLoaderDarwinKernel + lldbPluginObjectContainerMachOFileset lldbPluginPlatformMacOSX LLVMTestingSupport ) Index: lldb/unittests/Core/CMakeLists.txt =================================================================== --- lldb/unittests/Core/CMakeLists.txt +++ lldb/unittests/Core/CMakeLists.txt @@ -14,9 +14,11 @@ LINK_LIBS lldbCore lldbHost + lldbPluginDynamicLoaderDarwinKernel lldbPluginObjectFileELF lldbPluginObjectFileMachO lldbPluginObjectFilePECOFF + lldbPluginObjectContainerMachOFileset lldbPluginPlatformMacOSX lldbPluginSymbolFileSymtab lldbSymbol Index: lldb/source/Target/Process.cpp =================================================================== --- lldb/source/Target/Process.cpp +++ lldb/source/Target/Process.cpp @@ -2653,6 +2653,10 @@ 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) { Index: lldb/source/Target/Platform.cpp =================================================================== --- lldb/source/Target/Platform.cpp +++ lldb/source/Target/Platform.cpp @@ -2079,3 +2079,23 @@ m_platforms.push_back(platform_sp); return platform_sp; } + +bool PlatformList::LoadSpecialBinaryAndSetDynamicLoader(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->LoadSpecialBinaryAndSetDynamicLoader(process, addr, + notify)) + return true; + } + } + return false; +} Index: lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp =================================================================== --- lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -593,8 +593,14 @@ UUID uuid; const bool value_is_slide = false; for (addr_t addr : bin_addrs) { - const bool force_symbol_search = true; const bool notify = true; + if (GetTarget() + .GetDebugger() + .GetPlatformList() + .LoadSpecialBinaryAndSetDynamicLoader(this, addr, notify)) + continue; + + const bool force_symbol_search = true; DynamicLoader::LoadBinaryWithUUIDAndAddress( this, uuid, addr, value_is_slide, force_symbol_search, notify); } Index: lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp =================================================================== --- lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -2206,12 +2206,13 @@ ++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); } } } Index: lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.h =================================================================== --- lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.h +++ lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.h @@ -154,6 +154,9 @@ const UUID &uuid, const ArchSpec &arch, lldb::ModuleSP &exe_module_sp); + bool LoadSpecialBinaryAndSetDynamicLoader(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. Index: lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp =================================================================== --- lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp +++ 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 @@ // "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 @@ 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 @@ 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,68 @@ 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)) + 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::LoadSpecialBinaryAndSetDynamicLoader( + 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.get()) + process->GetTarget().SetPlatform(platform_sp); + + DynamicLoaderUP dyld_up( + new 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; Index: lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp =================================================================== --- lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp +++ lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp @@ -130,6 +130,20 @@ return g_settings; } +static bool module_is_a_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 @@ 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 (!module_is_a_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 @@ // 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 @@ 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 @@ 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 (!module_is_a_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 @@ return UUID(); } - if (exe_objfile->GetType() == ObjectFile::eTypeExecutable && - exe_objfile->GetStrata() == ObjectFile::eStrataKernel) { + if (module_is_a_kernel(memory_module_sp.get())) { ArchSpec kernel_arch(eArchTypeMachO, header.cputype, header.cpusubtype); if (!process->GetTarget().GetArchitecture().IsCompatibleMatch( kernel_arch)) { @@ -525,10 +522,10 @@ 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,10 @@ 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; - } - } + if (module_is_a_kernel(module_sp.get())) + m_kernel_image = true; + else + m_kernel_image = false; } ModuleSP DynamicLoaderDarwinKernel::KextImageInfo::GetModule() { @@ -672,17 +665,8 @@ 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 (module_is_a_kernel(memory_module_sp.get())) + is_kernel = true; // 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 @@ -718,22 +702,6 @@ 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 +739,21 @@ 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 module_list = target.GetImages(); + std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex()); + const size_t num_modules = module_list.GetSize(); + ModuleList incorrect_kernels; + for (size_t i = 0; i < num_modules; i++) { + ModuleSP module_sp = module_list.GetModuleAtIndex(i); + if (module_is_a_kernel(module_sp.get()) && module_sp->GetUUID() != m_uuid) + incorrect_kernels.Append(module_sp); + } + module_list.Remove(incorrect_kernels); } if (!m_module_sp) { @@ -841,10 +824,6 @@ 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 +959,11 @@ 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 (module_is_a_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() && Index: lldb/source/Core/DynamicLoader.cpp =================================================================== --- lldb/source/Core/DynamicLoader.cpp +++ lldb/source/Core/DynamicLoader.cpp @@ -230,6 +230,10 @@ 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; Index: lldb/include/lldb/Target/Process.h =================================================================== --- lldb/include/lldb/Target/Process.h +++ lldb/include/lldb/Target/Process.h @@ -641,6 +641,8 @@ /// 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. Index: lldb/include/lldb/Target/Platform.h =================================================================== --- lldb/include/lldb/Target/Platform.h +++ lldb/include/lldb/Target/Platform.h @@ -846,6 +846,33 @@ return nullptr; } + /// When we have a Process, given an address of a binary in memory, + /// the platform may be able to set the correct DynamicLoader plugin that + /// should be used for this process, and register this binary with the + /// DynamicLoader so it will be loaded properly. May change the Process + /// DynamicLoader. + /// + /// \param[in] process + /// Process read memory from. + /// + /// \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 LoadSpecialBinaryAndSetDynamicLoader(Process *process, + lldb::addr_t addr, + bool notify) { + return false; + } + virtual CompilerType GetSiginfoType(const llvm::Triple &triple); virtual Args GetExtraStartupCommands(); @@ -1026,6 +1053,30 @@ lldb::PlatformSP Create(llvm::StringRef name); + /// When we have a Process, given an address of a binary in memory, + /// the platform may be able to set the correct DynamicLoader plugin that + /// should be used for this process, and register this binary with the + /// DynamicLoader so it will be loaded properly. May change the Process + /// DynamicLoader. + /// + /// \param[in] process + /// Process read memory from. + /// + /// \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 LoadSpecialBinaryAndSetDynamicLoader(Process *process, lldb::addr_t addr, + bool notify); + protected: typedef std::vector<lldb::PlatformSP> collection; mutable std::recursive_mutex m_mutex;
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits