This revision was automatically updated to reflect the committed changes.
Closed by commit rG8a26ba6a02f1: Load binary by UUID from qProcessInfo packet
fields (authored by jasonmolenda).
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D116211/new/
https://reviews.llvm.org/D116211
Files:
lldb/docs/lldb-gdb-remote.txt
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
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
@@ -561,6 +561,94 @@
}
}
+ // The remote stub may know about the "main binary" in
+ // the context of a firmware debug session, and can
+ // give us a UUID and an address/slide of where the
+ // binary is loaded in memory.
+ UUID standalone_uuid;
+ addr_t standalone_value;
+ 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()) {
+ ModuleSpec module_spec;
+ module_spec.GetUUID() = standalone_uuid;
+
+ // Look up UUID in global module cache before attempting
+ // a more expensive search.
+ Status error = ModuleList::GetSharedModule(module_spec, module_sp,
+ nullptr, nullptr, nullptr);
+
+ if (!module_sp) {
+ // Force a an external lookup, if that tool is available.
+ if (!module_spec.GetSymbolFileSpec())
+ Symbols::DownloadObjectAndSymbolFile(module_spec, 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() && standalone_value != LLDB_INVALID_ADDRESS &&
+ !standalone_value_is_offset) {
+ char namebuf[80];
+ snprintf(namebuf, sizeof(namebuf), "mem-image-0x%" PRIx64,
+ standalone_value);
+ module_sp =
+ ReadModuleFromMemory(FileSpec(namebuf), standalone_value);
+ }
+
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(
+ LIBLLDB_LOG_DYNAMIC_LOADER));
+ if (module_sp.get()) {
+ target.GetImages().AppendIfNeeded(module_sp, false);
+
+ bool changed = false;
+ if (module_sp->GetObjectFile()) {
+ if (standalone_value != LLDB_INVALID_ADDRESS) {
+ if (log)
+ log->Printf("Loading binary UUID %s at %s 0x%" PRIx64,
+ standalone_uuid.GetAsString().c_str(),
+ standalone_value_is_offset ? "offset" : "address",
+ standalone_value);
+ module_sp->SetLoadAddress(target, standalone_value,
+ standalone_value_is_offset, changed);
+ } else {
+ // No address/offset/slide, load the binary at file address,
+ // offset 0.
+ if (log)
+ log->Printf("Loading binary UUID %s at file address",
+ standalone_uuid.GetAsString().c_str());
+ const bool value_is_slide = true;
+ module_sp->SetLoadAddress(target, 0, value_is_slide, changed);
+ }
+ } else {
+ // In-memory image, load at its true address, offset 0.
+ if (log)
+ log->Printf("Loading binary UUID %s from memory",
+ standalone_uuid.GetAsString().c_str());
+ const bool value_is_slide = true;
+ module_sp->SetLoadAddress(target, 0, value_is_slide, changed);
+ }
+
+ ModuleList added_module;
+ added_module.Append(module_sp, false);
+ target.ModulesDidLoad(added_module);
+ } else {
+ if (log)
+ log->Printf("Unable to find binary with UUID %s and load it at "
+ "%s 0x%" PRIx64,
+ standalone_uuid.GetAsString().c_str(),
+ standalone_value_is_offset ? "offset" : "address",
+ standalone_value);
+ }
+ }
+ }
+
const StateType state = SetThreadStopInfo(response);
if (state != eStateInvalid) {
SetPrivateState(state);
Index: lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
===================================================================
--- lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
+++ lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
@@ -217,6 +217,9 @@
const ArchSpec &GetProcessArchitecture();
+ bool GetProcessStandaloneBinary(UUID &uuid, lldb::addr_t &value,
+ bool &value_is_offset);
+
void GetRemoteQSupported();
bool GetVContSupported(char flavor);
@@ -584,6 +587,9 @@
ArchSpec m_host_arch;
ArchSpec m_process_arch;
+ UUID m_process_standalone_uuid;
+ lldb::addr_t m_process_standalone_value = LLDB_INVALID_ADDRESS;
+ bool m_process_standalone_value_is_offset = false;
llvm::VersionTuple m_os_version;
llvm::VersionTuple m_maccatalyst_version;
std::string m_os_build;
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
@@ -1006,6 +1006,23 @@
return m_process_arch;
}
+bool GDBRemoteCommunicationClient::GetProcessStandaloneBinary(
+ UUID &uuid, addr_t &value, bool &value_is_offset) {
+ if (m_qProcessInfo_is_valid == eLazyBoolCalculate)
+ GetCurrentProcessInfo();
+
+ // Return true if we have a UUID or an address/offset of the
+ // main standalone / firmware binary being used.
+ if (!m_process_standalone_uuid.IsValid() &&
+ m_process_standalone_value == LLDB_INVALID_ADDRESS)
+ return false;
+
+ uuid = m_process_standalone_uuid;
+ value = m_process_standalone_value;
+ value_is_offset = m_process_standalone_value_is_offset;
+ return true;
+}
+
bool GDBRemoteCommunicationClient::GetGDBServerVersion() {
if (m_qGDBServerVersion_is_valid == eLazyBoolCalculate) {
m_gdb_server_name.clear();
@@ -2147,6 +2164,25 @@
} else if (name.equals("elf_abi")) {
elf_abi = std::string(value);
++num_keys_decoded;
+ } else if (name.equals("main-binary-uuid")) {
+ m_process_standalone_uuid.SetFromStringRef(value);
+ ++num_keys_decoded;
+ } else if (name.equals("main-binary-slide")) {
+ StringExtractor extractor(value);
+ m_process_standalone_value =
+ extractor.GetU64(LLDB_INVALID_ADDRESS, 16);
+ if (m_process_standalone_value != LLDB_INVALID_ADDRESS) {
+ m_process_standalone_value_is_offset = true;
+ ++num_keys_decoded;
+ }
+ } else if (name.equals("main-binary-address")) {
+ StringExtractor extractor(value);
+ m_process_standalone_value =
+ extractor.GetU64(LLDB_INVALID_ADDRESS, 16);
+ if (m_process_standalone_value != LLDB_INVALID_ADDRESS) {
+ m_process_standalone_value_is_offset = false;
+ ++num_keys_decoded;
+ }
}
}
if (num_keys_decoded > 0)
Index: lldb/docs/lldb-gdb-remote.txt
===================================================================
--- lldb/docs/lldb-gdb-remote.txt
+++ lldb/docs/lldb-gdb-remote.txt
@@ -1003,6 +1003,9 @@
endian: is one of "little", "big", or "pdp"
ptrsize: is a number that represents how big pointers are in bytes
+main-binary-uuid: is the UUID of a firmware type binary that the gdb stub knows about
+main-binary-address: is the load address of the firmware type binary
+main-binary-slide: is the slide of the firmware type binary, if address isn't known
//----------------------------------------------------------------------
// "qShlibInfoAddr"
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits