summaryrefslogtreecommitdiff
path: root/lldb/source/Core/DynamicLoader.cpp
diff options
context:
space:
mode:
authorJason Molenda <jason@molenda.com>2022-08-02 13:46:18 -0700
committerJason Molenda <jason@molenda.com>2022-08-02 13:49:30 -0700
commitd8879fba8825b9799166ba0ea552d4027bfb8ad1 (patch)
tree4510a38b0028d9f09246c229926fca47fd7b958c /lldb/source/Core/DynamicLoader.cpp
parent40eec27618d0db2e2753abdf3b84832056d508a6 (diff)
Allow firmware binaries to be specified only by load address
Add support to Mach-O corefiles and to live gdb remote serial protocol connections for the corefile/remote stub to provide a list of load addresses of binaries that should be found & loaded by lldb, and nothing else. lldb will try to parse the binary out of memory, and if it can find a UUID, try to find a binary & its debug information based on the UUID, falling back to using the memory image if it must. A bit of code unification from three parts of lldb that were loading individual binaries already, so there is a shared method in DynamicLoader to handle all of the variations they were doing. Differential Revision: https://reviews.llvm.org/D130813 rdar://94249937 rdar://94249384
Diffstat (limited to 'lldb/source/Core/DynamicLoader.cpp')
-rw-r--r--lldb/source/Core/DynamicLoader.cpp98
1 files changed, 98 insertions, 0 deletions
diff --git a/lldb/source/Core/DynamicLoader.cpp b/lldb/source/Core/DynamicLoader.cpp
index 96e0d4ec6555..1fe60e000c6d 100644
--- a/lldb/source/Core/DynamicLoader.cpp
+++ b/lldb/source/Core/DynamicLoader.cpp
@@ -13,11 +13,15 @@
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Section.h"
+#include "lldb/Symbol/LocateSymbolFile.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/MemoryRegionInfo.h"
+#include "lldb/Target/Platform.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/ConstString.h"
+#include "lldb/Utility/LLDBLog.h"
+#include "lldb/Utility/Log.h"
#include "lldb/lldb-private-interfaces.h"
#include "llvm/ADT/StringRef.h"
@@ -171,6 +175,100 @@ ModuleSP DynamicLoader::LoadModuleAtAddress(const FileSpec &file,
return nullptr;
}
+static ModuleSP ReadUnnamedMemoryModule(Process *process, addr_t addr) {
+ char namebuf[80];
+ snprintf(namebuf, sizeof(namebuf), "memory-image-0x%" PRIx64, addr);
+ return process->ReadModuleFromMemory(FileSpec(namebuf), addr);
+}
+
+ModuleSP DynamicLoader::LoadBinaryWithUUIDAndAddress(Process *process,
+ UUID uuid, addr_t value,
+ bool value_is_offset,
+ bool force_symbol_search,
+ bool notify) {
+ ModuleSP memory_module_sp;
+ ModuleSP module_sp;
+ PlatformSP platform_sp = process->GetTarget().GetPlatform();
+ Target &target = process->GetTarget();
+ Status error;
+ ModuleSpec module_spec;
+ module_spec.GetUUID() = uuid;
+
+ if (!uuid.IsValid() && !value_is_offset) {
+ memory_module_sp = ReadUnnamedMemoryModule(process, value);
+
+ if (memory_module_sp)
+ uuid = memory_module_sp->GetUUID();
+ }
+
+ if (uuid.IsValid()) {
+ ModuleSpec module_spec;
+ module_spec.GetUUID() = uuid;
+
+ if (!module_sp)
+ module_sp = target.GetOrCreateModule(module_spec, false, &error);
+
+ // 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 (force_symbol_search &&
+ (!module_sp || !module_sp->GetSymbolFileFileSpec())) {
+ Symbols::DownloadObjectAndSymbolFile(module_spec, error, true);
+ if (FileSystem::Instance().Exists(module_spec.GetFileSpec())) {
+ module_sp = std::make_shared<Module>(module_spec);
+ }
+ }
+ }
+
+ // If we couldn't find the binary anywhere else, as a last resort,
+ // read it out of memory.
+ if (!module_sp.get() && value != LLDB_INVALID_ADDRESS && !value_is_offset) {
+ if (!memory_module_sp)
+ memory_module_sp = ReadUnnamedMemoryModule(process, value);
+ if (memory_module_sp)
+ module_sp = memory_module_sp;
+ }
+
+ Log *log = GetLog(LLDBLog::DynamicLoader);
+ if (module_sp.get()) {
+ target.GetImages().AppendIfNeeded(module_sp, false);
+
+ bool changed = false;
+ if (module_sp->GetObjectFile()) {
+ if (value != LLDB_INVALID_ADDRESS) {
+ LLDB_LOGF(log, "Loading binary UUID %s at %s 0x%" PRIx64,
+ 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, "Loading binary UUID %s at file address",
+ uuid.GetAsString().c_str());
+ module_sp->SetLoadAddress(target, 0, true /* value_is_slide */,
+ changed);
+ }
+ } else {
+ // In-memory image, load at its true address, offset 0.
+ LLDB_LOGF(log, "Loading binary UUID %s from memory at address 0x%" PRIx64,
+ uuid.GetAsString().c_str(), value);
+ 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 {
+ LLDB_LOGF(log, "Unable to find binary with UUID %s and load it at "
+ "%s 0x%" PRIx64,
+ uuid.GetAsString().c_str(),
+ value_is_offset ? "offset" : "address", value);
+ }
+
+ return module_sp;
+}
+
int64_t DynamicLoader::ReadUnsignedIntWithSizeInBytes(addr_t addr,
int size_in_bytes) {
Status error;