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
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to