labath updated this revision to Diff 246196.
labath marked 4 inline comments as done.
labath added a comment.
Add some comments and documentation.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D74598/new/
https://reviews.llvm.org/D74598
Files:
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
lldb/test/API/functionalities/gdb_remote_client/TestqOffsets.py
lldb/test/API/functionalities/gdb_remote_client/gdbclientutils.py
lldb/test/API/functionalities/gdb_remote_client/qOffsets.yaml
lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp
Index: lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp
===================================================================
--- lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp
+++ lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp
@@ -552,3 +552,24 @@
incorrect_custom_params2);
ASSERT_FALSE(result4.get().Success());
}
+
+TEST_F(GDBRemoteCommunicationClientTest, GetOffsets) {
+ const auto &GetExecutableOffset = [&](llvm::StringRef response) {
+ std::future<Optional<addr_t>> result = std::async(
+ std::launch::async, [&] { return client.GetExecutableOffset(); });
+
+ HandlePacket(server, "qOffsets", response);
+ return result.get();
+ };
+ EXPECT_EQ(addr_t(0x1234), GetExecutableOffset("Text=1234;Data=1234"));
+ EXPECT_EQ(addr_t(0x1234),
+ GetExecutableOffset("Text=1234;Data=1234;Bss=1234"));
+ EXPECT_EQ(addr_t(0x1234), GetExecutableOffset("TextSeg=1234;DataSeg=1234"));
+
+ EXPECT_EQ(llvm::None, GetExecutableOffset("E05"));
+ EXPECT_EQ(llvm::None, GetExecutableOffset("Text=bogus"));
+
+ // NB: These are technically correct responses, but we don't handle them yet.
+ EXPECT_EQ(llvm::None, GetExecutableOffset("Text=1234;Data=4321"));
+ EXPECT_EQ(llvm::None, GetExecutableOffset("TextSeg=1234;DataSeg=4321"));
+}
Index: lldb/test/API/functionalities/gdb_remote_client/qOffsets.yaml
===================================================================
--- /dev/null
+++ lldb/test/API/functionalities/gdb_remote_client/qOffsets.yaml
@@ -0,0 +1,19 @@
+!ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_EXEC
+ Machine: EM_AARCH64
+Sections:
+ - Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Address: 0x1000
+ AddressAlign: 0x4
+ Content: "c3c3c3c3"
+ - Name: .note.ABI-tag
+ Type: SHT_NOTE
+ Flags: [ SHF_ALLOC ]
+ Address: 0x1004
+ AddressAlign: 0x4
+ Content: 040000001000000001000000474e550000000000030000000700000000000000
Index: lldb/test/API/functionalities/gdb_remote_client/gdbclientutils.py
===================================================================
--- lldb/test/API/functionalities/gdb_remote_client/gdbclientutils.py
+++ lldb/test/API/functionalities/gdb_remote_client/gdbclientutils.py
@@ -172,6 +172,8 @@
return self.qHostInfo()
if packet == "qGetWorkingDir":
return self.qGetWorkingDir()
+ if packet == "qOffsets":
+ return self.qOffsets();
if packet == "qsProcessInfo":
return self.qsProcessInfo()
if packet.startswith("qfProcessInfo"):
@@ -188,6 +190,9 @@
def qGetWorkingDir(self):
return "2f"
+ def qOffsets(self):
+ return ""
+
def qHostInfo(self):
return "ptrsize:8;endian:little;"
Index: lldb/test/API/functionalities/gdb_remote_client/TestqOffsets.py
===================================================================
--- /dev/null
+++ lldb/test/API/functionalities/gdb_remote_client/TestqOffsets.py
@@ -0,0 +1,28 @@
+import lldb
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test.decorators import *
+from gdbclientutils import *
+
+
+class TestqOffsets(GDBRemoteTestBase):
+
+ class Responder(MockGDBServerResponder):
+ def qOffsets(self):
+ return 'Text=470000;Data=470000'
+
+ def setUp(self):
+ super(TestqOffsets, self).setUp()
+ self._initial_platform = lldb.DBG.GetSelectedPlatform()
+
+ def tearDown(self):
+ lldb.DBG.SetSelectedPlatform(self._initial_platform)
+ super(TestqOffsets, self).tearDown()
+
+ def test(self):
+ self.server.responder = TestqOffsets.Responder()
+ target = self.createTarget("qOffsets.yaml")
+ text = target.modules[0].FindSection(".text")
+ self.assertEquals(text.GetLoadAddress(target), lldb.LLDB_INVALID_ADDRESS)
+
+ process = self.connect(target)
+ self.assertEquals(text.GetLoadAddress(target), 0x471000)
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
@@ -1102,6 +1102,20 @@
}
}
+ if (ModuleSP module_sp = GetTarget().GetExecutableModule()) {
+ // TODO: Handle qOffsets packets with non-uniform offsets.
+ if (llvm::Optional<addr_t> offset = m_gdb_comm.GetExecutableOffset()) {
+ bool changed = false;
+ module_sp->SetLoadAddress(GetTarget(), *offset, /*value_is_offset=*/true,
+ changed);
+ if (changed) {
+ ModuleList list;
+ list.Append(module_sp);
+ m_process->GetTarget().ModulesDidLoad(list);
+ }
+ }
+ }
+
// Find out which StructuredDataPlugins are supported by the debug monitor.
// These plugins transmit data over async $J packets.
if (StructuredData::Array *supported_packets =
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
@@ -425,6 +425,11 @@
bool GetSharedCacheInfoSupported();
+ /// Use qOffsets to query the offset used when relocating the target
+ /// executable. Currently, we only support relocating all sections by the same
+ /// amount.
+ llvm::Optional<lldb::addr_t> GetExecutableOffset();
+
bool GetModuleInfo(const FileSpec &module_file_spec,
const ArchSpec &arch_spec, ModuleSpec &module_spec);
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
@@ -3531,6 +3531,33 @@
return error;
}
+llvm::Optional<addr_t> GDBRemoteCommunicationClient::GetExecutableOffset() {
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(
+ "qOffsets", response, /*send_async=*/false) != PacketResult::Success)
+ return llvm::None;
+ if (!response.IsNormalResponse())
+ return llvm::None;
+
+ llvm::Optional<addr_t> offset;
+ llvm::SmallVector<llvm::StringRef, 3> pairs;
+ response.GetStringRef().split(pairs, ';');
+ for (llvm::StringRef pair : pairs) {
+ llvm::StringRef name, value;
+ std::tie(name, value) = pair.split('=');
+
+ addr_t cur_offset;
+ if (!to_integer(value, cur_offset, 16))
+ return llvm::None;
+
+ // We only support relocating all sections by the same offset.
+ if (offset && *offset != cur_offset)
+ return llvm::None;
+ offset = cur_offset;
+ }
+ return offset;
+}
+
bool GDBRemoteCommunicationClient::GetModuleInfo(
const FileSpec &module_file_spec, const lldb_private::ArchSpec &arch_spec,
ModuleSpec &module_spec) {
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits