https://github.com/JDevlieghere created https://github.com/llvm/llvm-project/pull/214372
LoadBinaryWithUUIDAndAddress both searched for a binary and registered it with the Target. Split it into LocateBinaries, which only searches, and LoadBinaryInTarget, which mutates the Target, with LocateAndLoadBinary keeping the single binary case a one-liner. The eight binary parameters and the results of the search are bundled in a new BinarySpec struct, and both entry points return an llvm::Expected. NFC, except for some small improvements to the error handling because we don't write to the async output stream directly (and fixed the newline). The motivation is a follow-up that runs LocateBinaries in parallel on the thread pool. NFC except for the error reporting. >From af4efebb900f77b2ea722d9debba054f08e92558 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere <[email protected]> Date: Wed, 5 Aug 2026 12:42:25 -0700 Subject: [PATCH] [lldb] Split DynamicLoader binary loading into locate and load (NFCI) LoadBinaryWithUUIDAndAddress both searched for a binary and registered it with the Target. Split it into LocateBinaries, which only searches, and LoadBinaryInTarget, which mutates the Target, with LocateAndLoadBinary keeping the single binary case a one-liner. The eight binary parameters and the results of the search are bundled in a new BinarySpec struct, and both entry points return an llvm::Expected. NFC, except for some small improvements to the error handling because we don't write to the async output stream directly (and fixed the newline). The motivation is a follow-up that runs LocateBinaries in parallel on the thread pool. NFC except for the error reporting. --- lldb/include/lldb/Target/DynamicLoader.h | 180 ++++++---- lldb/source/Core/DynamicLoader.cpp | 313 ++++++++++-------- .../ObjectFile/Mach-O/ObjectFileMachO.cpp | 29 +- .../Process/gdb-remote/ProcessGDBRemote.cpp | 41 +-- .../Process/mach-core/ProcessMachCore.cpp | 67 ++-- 5 files changed, 377 insertions(+), 253 deletions(-) diff --git a/lldb/include/lldb/Target/DynamicLoader.h b/lldb/include/lldb/Target/DynamicLoader.h index e85036c2887d1..e5500a5f0a2f1 100644 --- a/lldb/include/lldb/Target/DynamicLoader.h +++ b/lldb/include/lldb/Target/DynamicLoader.h @@ -20,8 +20,12 @@ #include "lldb/lldb-private-enumerations.h" #include "lldb/lldb-types.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/Support/Error.h" + #include <cstddef> #include <cstdint> +#include <string> namespace lldb_private { class ModuleList; class Process; @@ -212,72 +216,132 @@ class DynamicLoader : public PluginInterface { lldb::addr_t base_addr, bool base_addr_is_offset); - /// Find/load a binary into lldb given a UUID and the address where it is - /// loaded in memory, or a slide to be applied to the file address. - /// May force an expensive search on the computer to find the binary by - /// UUID, should not be used for a large number of binaries - intended for - /// an environment where there may be one, or a few, binaries resident in - /// memory. + /// A binary to find and load into a Target, and the state that finding it + /// produces. + /// + /// Loading a binary is split into LocateBinaries and LoadBinaryInTarget so + /// that a caller with many binaries can search for all of them before adding + /// any of them to the Target. + struct BinarySpec { + /// Name of the binary, if available. If no matching binary can be found on + /// the debug host, a module may be created out of live memory and given + /// this name. If empty, a name is constructed from the address the binary + /// is loaded at. + std::string name; + + /// UUID of the binary to be loaded. May be empty, in which case, if a load + /// address is supplied, the binary is read out of memory to get a UUID to + /// look for. There is a performance cost to doing this, it is not + /// preferable. + UUID uuid; + + /// Address where the binary should be loaded, or read out of memory. Or a + /// slide value, to be applied to the file addresses of the binary. + lldb::addr_t value = LLDB_INVALID_ADDRESS; + + /// A flag indicating that \a value is an address, or an offset to be + /// applied to the file addresses. + bool value_is_offset = false; + + /// Allow the search to do a possibly expensive external search for the + /// ObjectFile and/or SymbolFile. + bool force_symbol_search = false; + + /// Whether ModulesDidLoad should be called once the binary has been added + /// to the Target. A caller loading several binaries may prefer to batch + /// those up. + bool notify = false; + + /// Whether the address of the binary should be set in the Target if it is + /// added. A caller that wants to set the section addresses individually + /// leaves this clear, and is then responsible for setting the load address + /// for the binary or its segments in the Target. + bool set_address_in_target = false; + + /// If no better binary image can be found, allow reading the binary out of + /// memory, if possible, and create the Module based on that. May be slow + /// to read a binary out of memory, and for unusual environments, there may + /// be no symbols mapped in memory at all. + bool allow_memory_image_last_resort = false; + + /// The module the binary was found as, or empty if it was not found. It is + /// not registered with the Target until LoadBinaryInTarget. + lldb::ModuleSP module_sp; + + /// The binary as it was read out of the process' memory, if it had to be, + /// so that it is not read a second time. + lldb::ModuleSP memory_module_sp; + + /// What an external symbol server had to say about this binary. The search + /// records it rather than reporting it, so that it reaches the user in the + /// caller's order. + Status error; + }; + + /// Find a binary and load it into a Target. + /// + /// Given a UUID, search for a binary and load it at the address provided, or + /// with the slide applied, or at the file address unslid. + /// + /// Given an address, try to read the binary out of memory, get the UUID, find + /// the file if possible and load it unslid, or add the memory module. + /// + /// May force an expensive search on the computer to find the binary by UUID. + /// To load more than one binary, use LocateBinaries and LoadBinaryInTarget. + /// + /// \param[in] process + /// The process to add this binary to. + /// + /// \param[in,out] bin_spec + /// The binary to find and load, with its input fields filled in by the + /// caller. + /// + /// \return + /// The module that was added to the Target, or an error saying why the + /// binary could not be found and loaded. + static llvm::Expected<lldb::ModuleSP> + LocateAndLoadBinary(Process *process, BinarySpec &bin_spec); + + /// Search for a batch of binaries, without mutating the Target. + /// + /// The entries are independent: a binary that cannot be found leaves its + /// BinarySpec::module_sp empty and has no effect on the others. Nothing is + /// registered with the Target, see LoadBinaryInTarget. + /// + /// \param[in] process + /// The process the binaries belong to. Used to read a binary's header + /// out of memory when its UUID isn't known, and otherwise only read from. + /// + /// \param[in,out] bin_specs + /// The binaries to search for, with their input fields filled in by the + /// caller. + static void LocateBinaries(Process *process, + llvm::MutableArrayRef<BinarySpec> bin_specs); + + /// Add a binary that LocateBinaries searched for to the Target, and set its + /// load address. /// - /// Given a UUID, search for a binary and load it at the address provided, - /// or with the slide applied, or at the file address unslid. + /// This mutates the Target and may read the process' memory, so it has to be + /// called for one binary at a time. Call it in the caller's own order rather + /// than in the order the searches finished: the order decides the Target's + /// module order, which binary gets to set the Target's architecture, and the + /// order in which messages reach the user. /// - /// Given an address, try to read the binary out of memory, get the UUID, - /// find the file if possible and load it unslid, or add the memory module. + /// Whether a failure is worth telling the user about is left to the caller, + /// which knows whether it went looking for a binary that has to be there. A + /// symbol server's word on a binary that was found anyway is reported here. /// /// \param[in] process /// The process to add this binary to. /// - /// \param[in] name - /// Name of the binary, if available. If this method cannot find a - /// matching binary on the debug host, it may create a memory module - /// out of live memory, and the provided name will be used. If an - /// empty StringRef is provided, a name will be constructed for the module - /// based on the address it is loaded at. - /// - /// \param[in] uuid - /// UUID of the binary to be loaded. UUID may be empty, and if a - /// load address is supplied, will read the binary from memory, get - /// a UUID and try to find a local binary. There is a performance - /// cost to doing this, it is not preferable. - /// - /// \param[in] value - /// Address where the binary should be loaded, or read out of memory. - /// Or a slide value, to be applied to the file addresses of the binary. - /// - /// \param[in] value_is_offset - /// A flag indicating that \p value is an address, or an offset to - /// be applied to the file addresses. - /// - /// \param[in] force_symbol_search - /// Allow the search to do a possibly expensive external search for - /// the ObjectFile and/or SymbolFile. - /// - /// \param[in] notify - /// Whether ModulesDidLoad should be called when a binary has been added - /// to the Target. The caller may prefer to batch up these when loading - /// multiple binaries. - /// - /// \param[in] set_address_in_target - /// Whether the address of the binary should be set in the Target if it - /// is added. The caller may want to set the section addresses - /// individually, instead of loading the binary the entire based on the - /// start address or slide. The caller is responsible for setting the - /// load address for the binary or its segments in the Target if it passes - /// true. - /// - /// \param[in] allow_memory_image_last_resort - /// If no better binary image can be found, allow reading the binary - /// out of memory, if possible, and create the Module based on that. - /// May be slow to read a binary out of memory, and for unusual - /// environments, may be no symbols mapped in memory at all. + /// \param[in,out] bin_spec + /// A binary that LocateBinaries has searched for. /// /// \return - /// Returns a shared pointer for the Module that has been added. - static lldb::ModuleSP LoadBinaryWithUUIDAndAddress( - Process *process, llvm::StringRef name, UUID uuid, lldb::addr_t value, - bool value_is_offset, bool force_symbol_search, bool notify, - bool set_address_in_target, bool allow_memory_image_last_resort); + /// The module that was added to the Target, or an error saying why the + /// binary could not be found and loaded. + static llvm::Expected<lldb::ModuleSP> + LoadBinaryInTarget(Process *process, BinarySpec &bin_spec); /// Get information about the shared cache for a process, if possible. /// diff --git a/lldb/source/Core/DynamicLoader.cpp b/lldb/source/Core/DynamicLoader.cpp index ac260607f6c86..96da588a0d644 100644 --- a/lldb/source/Core/DynamicLoader.cpp +++ b/lldb/source/Core/DynamicLoader.cpp @@ -26,8 +26,10 @@ #include "lldb/lldb-private-interfaces.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/Error.h" #include <memory> +#include <string> #include <cassert> @@ -211,172 +213,205 @@ static ModuleSP ReadUnnamedMemoryModule(Process *process, addr_t addr, return *module_sp_or_err; } -ModuleSP DynamicLoader::LoadBinaryWithUUIDAndAddress( - Process *process, llvm::StringRef name, UUID uuid, addr_t value, - bool value_is_offset, bool force_symbol_search, bool notify, - bool set_address_in_target, bool allow_memory_image_last_resort) { - ModuleSP memory_module_sp; - ModuleSP module_sp; - PlatformSP platform_sp = process->GetTarget().GetPlatform(); - Target &target = process->GetTarget(); - Status error; - - StreamString prog_str; - if (!name.empty()) { - prog_str << name.str() << " "; +static std::string +GetBinaryDescription(const DynamicLoader::BinarySpec &bin_spec) { + StreamString desc; + if (!bin_spec.name.empty()) + desc << bin_spec.name << " "; + if (bin_spec.uuid.IsValid()) + desc << bin_spec.uuid.GetAsString(); + if (!bin_spec.value_is_offset && bin_spec.value != LLDB_INVALID_ADDRESS) { + desc << " at 0x"; + desc.PutHex64(bin_spec.value); } - if (uuid.IsValid()) - prog_str << uuid.GetAsString(); - if (value_is_offset == 0 && value != LLDB_INVALID_ADDRESS) { - prog_str << " at 0x"; - prog_str.PutHex64(value); - } - - if (!uuid.IsValid() && !value_is_offset) { - memory_module_sp = ReadUnnamedMemoryModule(process, value, name); + return desc.GetString().str(); +} - if (memory_module_sp) { - uuid = memory_module_sp->GetUUID(); - if (uuid.IsValid()) { - prog_str << " "; - prog_str << uuid.GetAsString(); - } - } +static std::string +GetBinaryNotFoundMessage(const DynamicLoader::BinarySpec &bin_spec) { + StreamString msg; + msg << "Unable to find file"; + if (!bin_spec.name.empty()) + msg << " " << bin_spec.name; + if (bin_spec.uuid.IsValid()) + msg << " with UUID " << bin_spec.uuid.GetAsString(); + if (bin_spec.value != LLDB_INVALID_ADDRESS) { + if (bin_spec.value_is_offset) + msg.Printf(" with slide 0x%" PRIx64, bin_spec.value); + else + msg.Printf(" at address 0x%" PRIx64, bin_spec.value); } + return msg.GetString().str(); +} + +/// Search for a binary with a known UUID, and create a module for it. +/// +/// Does not mutate the Target, but does read from it, and reaches the global +/// shared module list, the symbol locator plugins, and a locate module callback +/// the user may have installed. +static void SearchForBinary(Target &target, DynamicLoader::BinarySpec &bin_spec, + const FileSpecList &search_paths) { ModuleSpec module_spec; module_spec.SetTarget(target.shared_from_this()); - module_spec.GetUUID() = uuid; - FileSpec name_filespec(name); + module_spec.GetUUID() = bin_spec.uuid; + FileSpec name_filespec(bin_spec.name); if (FileSystem::Instance().Exists(name_filespec)) module_spec.GetFileSpec() = name_filespec; - if (uuid.IsValid()) { - Progress progress("Locating binary", prog_str.GetString().str()); - - // Has lldb already seen a module with this UUID? - // Or have external lookup enabled in DebugSymbols on macOS. - if (!module_sp) - error = - ModuleList::GetSharedModule(module_spec, module_sp, nullptr, nullptr); - - // Can lldb's symbol/executable location schemes - // find an executable and symbol file. - if (!module_sp) { - FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths(); - StatisticsMap symbol_locator_map; - module_spec.GetSymbolFileSpec() = - PluginManager::LocateExecutableSymbolFile(module_spec, search_paths, - symbol_locator_map); - ModuleSpec objfile_module_spec = - PluginManager::LocateExecutableObjectFile(module_spec, - symbol_locator_map); - module_spec.GetFileSpec() = objfile_module_spec.GetFileSpec(); - if (FileSystem::Instance().Exists(module_spec.GetFileSpec()) && - FileSystem::Instance().Exists(module_spec.GetSymbolFileSpec())) { - module_sp = std::make_shared<Module>(module_spec); - } + // Has lldb already seen a module with this UUID? + // Or have external lookup enabled in DebugSymbols on macOS. + Status error = ModuleList::GetSharedModule(module_spec, bin_spec.module_sp, + nullptr, nullptr); + + // Can lldb's symbol/executable location schemes find an executable and + // symbol file. + if (!bin_spec.module_sp) { + StatisticsMap symbol_locator_map; + module_spec.GetSymbolFileSpec() = PluginManager::LocateExecutableSymbolFile( + module_spec, search_paths, symbol_locator_map); + ModuleSpec objfile_module_spec = PluginManager::LocateExecutableObjectFile( + module_spec, symbol_locator_map); + module_spec.GetFileSpec() = objfile_module_spec.GetFileSpec(); + if (FileSystem::Instance().Exists(module_spec.GetFileSpec()) && + FileSystem::Instance().Exists(module_spec.GetSymbolFileSpec())) { + bin_spec.module_sp = std::make_shared<Module>(module_spec); + } - if (module_sp) { - module_sp->GetSymbolLocatorStatistics().merge(symbol_locator_map); - } + if (bin_spec.module_sp) { + bin_spec.module_sp->GetSymbolLocatorStatistics().merge( + symbol_locator_map); } + } - // If we haven't found a binary, or we don't have a SymbolFile, see - // if there is an external search tool that can find it. - if (!module_sp || !module_sp->GetSymbolFileFileSpec()) { - PluginManager::DownloadObjectAndSymbolFile(module_spec, error, - force_symbol_search); - if (FileSystem::Instance().Exists(module_spec.GetFileSpec())) { - module_sp = std::make_shared<Module>(module_spec); - } else if (force_symbol_search && error.AsCString("") && - error.AsCString("")[0] != '\0') { - *target.GetDebugger().GetAsyncErrorStream() << error.AsCString(); - } + // If we haven't found a binary, or we don't have a SymbolFile, see + // if there is an external search tool that can find it. + if (!bin_spec.module_sp || !bin_spec.module_sp->GetSymbolFileFileSpec()) { + PluginManager::DownloadObjectAndSymbolFile(module_spec, error, + bin_spec.force_symbol_search); + if (FileSystem::Instance().Exists(module_spec.GetFileSpec())) { + bin_spec.module_sp = std::make_shared<Module>(module_spec); + } else if (bin_spec.force_symbol_search && error.Fail()) { + bin_spec.error = std::move(error); } + } + + // If we only found the executable, create a Module based on that. + if (!bin_spec.module_sp && + FileSystem::Instance().Exists(module_spec.GetFileSpec())) + bin_spec.module_sp = std::make_shared<Module>(module_spec); +} - // If we only found the executable, create a Module based on that. - if (!module_sp && FileSystem::Instance().Exists(module_spec.GetFileSpec())) - module_sp = std::make_shared<Module>(module_spec); +static void FindBinaryUUIDInMemory(Process *process, + DynamicLoader::BinarySpec &bin_spec) { + bin_spec.memory_module_sp = + ReadUnnamedMemoryModule(process, bin_spec.value, bin_spec.name); + if (bin_spec.memory_module_sp) + bin_spec.uuid = bin_spec.memory_module_sp->GetUUID(); +} + +void DynamicLoader::LocateBinaries( + Process *process, llvm::MutableArrayRef<BinarySpec> bin_specs) { + Target &target = process->GetTarget(); + const FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths(); + + for (BinarySpec &bin_spec : bin_specs) { + if (!bin_spec.uuid.IsValid() && !bin_spec.value_is_offset) + FindBinaryUUIDInMemory(process, bin_spec); + if (!bin_spec.uuid.IsValid()) + continue; + Progress progress("Locating binary", GetBinaryDescription(bin_spec)); + SearchForBinary(target, bin_spec, search_paths); } +} + +llvm::Expected<ModuleSP> +DynamicLoader::LoadBinaryInTarget(Process *process, BinarySpec &bin_spec) { + Target &target = process->GetTarget(); + + // The error belongs to this function now: every path below either reports it + // or folds it into the failure. + llvm::Error search_error = bin_spec.error.takeError(); // If we couldn't find the binary anywhere else, as a last resort, // read it out of memory. - if (allow_memory_image_last_resort && !module_sp.get() && - value != LLDB_INVALID_ADDRESS && !value_is_offset) { - if (!memory_module_sp) - memory_module_sp = ReadUnnamedMemoryModule(process, value, name); - if (memory_module_sp) - module_sp = memory_module_sp; + if (bin_spec.allow_memory_image_last_resort && !bin_spec.module_sp && + bin_spec.value != LLDB_INVALID_ADDRESS && !bin_spec.value_is_offset) { + if (!bin_spec.memory_module_sp) + bin_spec.memory_module_sp = + ReadUnnamedMemoryModule(process, bin_spec.value, bin_spec.name); + if (bin_spec.memory_module_sp) + bin_spec.module_sp = bin_spec.memory_module_sp; } 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; - if (set_address_in_target) { - if (module_sp->GetObjectFile()) { - if (value != LLDB_INVALID_ADDRESS) { - LLDB_LOGF(log, - "DynamicLoader::LoadBinaryWithUUIDAndAddress Loading " - "binary %s UUID %s at %s 0x%" PRIx64, - name.str().c_str(), uuid.GetAsString().c_str(), - value_is_offset ? "offset" : "address", value); - module_sp->SetLoadAddress(target, value, value_is_offset, changed); - } else { - // No address/offset/slide, load the binary at file address, - // offset 0. - LLDB_LOGF(log, - "DynamicLoader::LoadBinaryWithUUIDAndAddress Loading " - "binary %s UUID %s at file address", - name.str().c_str(), uuid.GetAsString().c_str()); - module_sp->SetLoadAddress(target, 0, true /* value_is_slide */, - changed); - } + if (!bin_spec.module_sp) { + std::string message = GetBinaryNotFoundMessage(bin_spec); + LLDB_LOG(log, "{0}", message); + llvm::Error error = llvm::createStringError(message); + if (search_error) + return llvm::joinErrors(std::move(search_error), std::move(error)); + return std::move(error); + } + + // A binary was found, but a symbol server may still have had something to say + // about its symbols. + if (search_error) + *target.GetDebugger().GetAsyncErrorStream() + << llvm::toString(std::move(search_error)) << "\n"; + + // 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(bin_spec.module_sp->GetArchitecture()); + target.GetImages().AppendIfNeeded(bin_spec.module_sp, false); + + bool changed = false; + if (bin_spec.set_address_in_target) { + if (bin_spec.module_sp->GetObjectFile()) { + if (bin_spec.value != LLDB_INVALID_ADDRESS) { + LLDB_LOGF(log, + "DynamicLoader::LoadBinaryInTarget Loading " + "binary %s UUID %s at %s 0x%" PRIx64, + bin_spec.name.c_str(), bin_spec.uuid.GetAsString().c_str(), + bin_spec.value_is_offset ? "offset" : "address", + bin_spec.value); + bin_spec.module_sp->SetLoadAddress(target, bin_spec.value, + bin_spec.value_is_offset, changed); } else { - // In-memory image, load at its true address, offset 0. + // No address/offset/slide, load the binary at file address, + // offset 0. LLDB_LOGF(log, - "DynamicLoader::LoadBinaryWithUUIDAndAddress Loading binary " - "%s UUID %s from memory at address 0x%" PRIx64, - name.str().c_str(), uuid.GetAsString().c_str(), value); - module_sp->SetLoadAddress(target, 0, true /* value_is_slide */, - changed); + "DynamicLoader::LoadBinaryInTarget Loading " + "binary %s UUID %s at file address", + bin_spec.name.c_str(), bin_spec.uuid.GetAsString().c_str()); + bin_spec.module_sp->SetLoadAddress(target, 0, true /* value_is_slide */, + changed); } + } else { + // In-memory image, load at its true address, offset 0. + LLDB_LOGF(log, + "DynamicLoader::LoadBinaryInTarget Loading binary " + "%s UUID %s from memory at address 0x%" PRIx64, + bin_spec.name.c_str(), bin_spec.uuid.GetAsString().c_str(), + bin_spec.value); + bin_spec.module_sp->SetLoadAddress(target, 0, true /* value_is_slide */, + changed); } + } - if (notify) { - ModuleList added_module; - added_module.Append(module_sp, false); - target.ModulesDidLoad(added_module); - } - } else { - if (force_symbol_search) { - lldb::StreamUP s = target.GetDebugger().GetAsyncErrorStream(); - s->PutCString("Unable to find file"); - if (!name.empty()) - s->Printf(" %s", name.str().c_str()); - if (uuid.IsValid()) - s->Printf(" with UUID %s", uuid.GetAsString().c_str()); - if (value != LLDB_INVALID_ADDRESS) { - if (value_is_offset) - s->Printf(" with slide 0x%" PRIx64, value); - else - s->Printf(" at address 0x%" PRIx64, value); - } - s->PutCString("\n"); - } - LLDB_LOGF(log, - "Unable to find binary %s with UUID %s and load it at " - "%s 0x%" PRIx64, - name.str().c_str(), uuid.GetAsString().c_str(), - value_is_offset ? "offset" : "address", value); + if (bin_spec.notify) { + ModuleList added_module; + added_module.Append(bin_spec.module_sp, false); + target.ModulesDidLoad(added_module); } - return module_sp; + return bin_spec.module_sp; +} + +llvm::Expected<ModuleSP> +DynamicLoader::LocateAndLoadBinary(Process *process, BinarySpec &bin_spec) { + LocateBinaries(process, bin_spec); + return LoadBinaryInTarget(process, bin_spec); } int64_t DynamicLoader::ReadUnsignedIntWithSizeInBytes(addr_t addr, diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp index 60b90309bee00..0ae87a8e77f90 100644 --- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp +++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp @@ -6709,16 +6709,29 @@ bool ObjectFileMachO::LoadCoreFileImages(lldb_private::Process &process) { // and can try to read load commands and find a UUID. if (image.uuid.IsValid() || (!value_is_offset && value != LLDB_INVALID_ADDRESS)) { - const bool set_load_address = image.segment_load_addresses.size() == 0; - const bool notify = false; + DynamicLoader::BinarySpec bin_spec; + bin_spec.name = image.filename; + bin_spec.uuid = image.uuid; + bin_spec.value = value; + bin_spec.value_is_offset = value_is_offset; + bin_spec.force_symbol_search = image.currently_executing; + bin_spec.notify = false; // Userland Darwin binaries will have segment load addresses via // the `all image infos` LC_NOTE. - const bool allow_memory_image_last_resort = - image.segment_load_addresses.size(); - module_sp = DynamicLoader::LoadBinaryWithUUIDAndAddress( - &process, image.filename, image.uuid, value, value_is_offset, - image.currently_executing, notify, set_load_address, - allow_memory_image_last_resort); + bin_spec.set_address_in_target = image.segment_load_addresses.empty(); + bin_spec.allow_memory_image_last_resort = + !image.segment_load_addresses.empty(); + if (llvm::Expected<ModuleSP> located = + DynamicLoader::LocateAndLoadBinary(&process, bin_spec)) { + module_sp = *located; + } else if (bin_spec.force_symbol_search) { + *process.GetTarget().GetDebugger().GetAsyncErrorStream() + << llvm::toString(located.takeError()) << "\n"; + } else { + // A corefile image that isn't on this machine is routine, and + // LocateAndLoadBinary has already logged it. + llvm::consumeError(located.takeError()); + } } // We have a ModuleSP to load in the Target. Load it at the diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index 724e7f2e71bd8..1e2788b3c081b 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -1167,17 +1167,19 @@ void ProcessGDBRemote::LoadStubBinaries() { bool standalone_value_is_offset; if (m_gdb_comm.GetProcessStandaloneBinary(standalone_uuid, standalone_value, standalone_value_is_offset)) { - ModuleSP module_sp; - if (standalone_uuid.IsValid()) { - const bool force_symbol_search = true; - const bool notify = true; - const bool set_address_in_target = true; - const bool allow_memory_image_last_resort = false; - DynamicLoader::LoadBinaryWithUUIDAndAddress( - this, "", standalone_uuid, standalone_value, - standalone_value_is_offset, force_symbol_search, notify, - set_address_in_target, allow_memory_image_last_resort); + DynamicLoader::BinarySpec bin_spec; + bin_spec.uuid = standalone_uuid; + bin_spec.value = standalone_value; + bin_spec.value_is_offset = standalone_value_is_offset; + bin_spec.force_symbol_search = true; + bin_spec.notify = true; + bin_spec.set_address_in_target = true; + llvm::Expected<ModuleSP> module = + DynamicLoader::LocateAndLoadBinary(this, bin_spec); + if (!module) + *GetTarget().GetDebugger().GetAsyncErrorStream() + << llvm::toString(module.takeError()) << "\n"; } } @@ -1191,8 +1193,6 @@ void ProcessGDBRemote::LoadStubBinaries() { std::vector<addr_t> bin_addrs = m_gdb_comm.GetProcessStandaloneBinaries(); if (bin_addrs.size()) { - UUID uuid; - const bool value_is_slide = false; for (addr_t addr : bin_addrs) { const bool notify = true; // First see if this is a special platform @@ -1204,14 +1204,17 @@ void ProcessGDBRemote::LoadStubBinaries() { .LoadPlatformBinaryAndSetup(this, addr, notify)) continue; - const bool force_symbol_search = true; - const bool set_address_in_target = true; - const bool allow_memory_image_last_resort = false; // Second manually load this binary into the Target. - DynamicLoader::LoadBinaryWithUUIDAndAddress( - this, llvm::StringRef(), uuid, addr, value_is_slide, - force_symbol_search, notify, set_address_in_target, - allow_memory_image_last_resort); + DynamicLoader::BinarySpec bin_spec; + bin_spec.value = addr; + bin_spec.force_symbol_search = true; + bin_spec.notify = notify; + bin_spec.set_address_in_target = true; + llvm::Expected<ModuleSP> module = + DynamicLoader::LocateAndLoadBinary(this, bin_spec); + if (!module) + *GetTarget().GetDebugger().GetAsyncErrorStream() + << llvm::toString(module.takeError()) << "\n"; } } } diff --git a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp index d0b9de0091511..91a977bb69bdc 100644 --- a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp +++ b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp @@ -262,17 +262,20 @@ bool ProcessMachCore::LoadBinaryViaLowmemUUID() { uuid.GetAsString().c_str(), addr); // We have no address specified, only a UUID. Load it at the file // address. - const bool value_is_offset = true; - const bool force_symbol_search = true; - const bool notify = true; - const bool set_address_in_target = true; - const bool allow_memory_image_last_resort = false; - if (DynamicLoader::LoadBinaryWithUUIDAndAddress( - this, llvm::StringRef(), uuid, 0, value_is_offset, - force_symbol_search, notify, set_address_in_target, - allow_memory_image_last_resort)) { + DynamicLoader::BinarySpec bin_spec; + bin_spec.uuid = uuid; + bin_spec.value = 0; + bin_spec.value_is_offset = true; + bin_spec.force_symbol_search = true; + bin_spec.notify = true; + bin_spec.set_address_in_target = true; + llvm::Expected<ModuleSP> module = + DynamicLoader::LocateAndLoadBinary(this, bin_spec); + if (module) m_dyld_plugin_name = DynamicLoaderStatic::GetPluginNameStatic(); - } + else + *GetTarget().GetDebugger().GetAsyncErrorStream() + << llvm::toString(module.takeError()) << "\n"; // We found metadata saying which binary should be loaded; don't // try an exhaustive search. return true; @@ -325,17 +328,20 @@ bool ProcessMachCore::LoadBinariesViaMetadata() { m_dyld_all_image_infos_addr = objfile_binary_value; m_dyld_plugin_name = DynamicLoaderMacOSXDYLD::GetPluginNameStatic(); } else { - const bool force_symbol_search = true; - const bool notify = true; - const bool set_address_in_target = true; - const bool allow_memory_image_last_resort = false; - if (DynamicLoader::LoadBinaryWithUUIDAndAddress( - this, llvm::StringRef(), objfile_binary_uuid, - objfile_binary_value, objfile_binary_value_is_offset, - force_symbol_search, notify, set_address_in_target, - allow_memory_image_last_resort)) { + DynamicLoader::BinarySpec bin_spec; + bin_spec.uuid = objfile_binary_uuid; + bin_spec.value = objfile_binary_value; + bin_spec.value_is_offset = objfile_binary_value_is_offset; + bin_spec.force_symbol_search = true; + bin_spec.notify = true; + bin_spec.set_address_in_target = true; + llvm::Expected<ModuleSP> module = + DynamicLoader::LocateAndLoadBinary(this, bin_spec); + if (module) m_dyld_plugin_name = DynamicLoaderStatic::GetPluginNameStatic(); - } + else + *GetTarget().GetDebugger().GetAsyncErrorStream() + << llvm::toString(module.takeError()) << "\n"; } } @@ -382,17 +388,20 @@ bool ProcessMachCore::LoadBinariesViaMetadata() { } else if (ident_uuid.IsValid()) { // We have no address specified, only a UUID. Load it at the file // address. - const bool value_is_offset = false; - const bool force_symbol_search = true; - const bool notify = true; - const bool set_address_in_target = true; - const bool allow_memory_image_last_resort = false; - if (DynamicLoader::LoadBinaryWithUUIDAndAddress( - this, llvm::StringRef(), ident_uuid, ident_binary_addr, - value_is_offset, force_symbol_search, notify, - set_address_in_target, allow_memory_image_last_resort)) { + DynamicLoader::BinarySpec bin_spec; + bin_spec.uuid = ident_uuid; + bin_spec.value = ident_binary_addr; + bin_spec.force_symbol_search = true; + bin_spec.notify = true; + bin_spec.set_address_in_target = true; + llvm::Expected<ModuleSP> module = + DynamicLoader::LocateAndLoadBinary(this, bin_spec); + if (module) { found_binary_spec_in_metadata = true; m_dyld_plugin_name = DynamicLoaderStatic::GetPluginNameStatic(); + } else { + *GetTarget().GetDebugger().GetAsyncErrorStream() + << llvm::toString(module.takeError()) << "\n"; } } _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
