mgorny updated this revision to Diff 369130.
mgorny added a comment.
Remove unnecessary include.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D108831/new/
https://reviews.llvm.org/D108831
Files:
lldb/source/Plugins/Process/gdb-remote/CMakeLists.txt
lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h
lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext_x86_64.cpp
lldb/test/API/functionalities/gdb_remote_client/TestGDBServerTargetXML.py
Index: lldb/test/API/functionalities/gdb_remote_client/TestGDBServerTargetXML.py
===================================================================
--- lldb/test/API/functionalities/gdb_remote_client/TestGDBServerTargetXML.py
+++ lldb/test/API/functionalities/gdb_remote_client/TestGDBServerTargetXML.py
@@ -9,8 +9,8 @@
@skipIfXmlSupportMissing
@skipIfRemote
- def test_x86_64_vec_regs(self):
- """Test rendering of x86_64 vector registers from gdbserver."""
+ def test_x86_64_regs(self):
+ """Test grabbing various x86_64 registers from gdbserver."""
class MyResponder(MockGDBServerResponder):
def qXferRead(self, obj, annex, offset, length):
if annex == "target.xml":
@@ -112,8 +112,6 @@
["rdi = 0x3837363534333231"])
self.match("register read fp",
["rbp = 0x4847464544434241"])
- self.match("register read sp",
- ["rsp = 0x5857565554535251"])
self.match("register read arg5",
["r8 = 0x6867666564636261"])
self.match("register read arg6",
@@ -123,6 +121,26 @@
self.match("register read flags",
["eflags = 0x94939291"])
+ # test pseudo-registers
+ self.match("register read ecx",
+ ["ecx = 0x04030201"])
+ self.match("register read cx",
+ ["cx = 0x0201"])
+ self.match("register read ch",
+ ["ch = 0x02"])
+ self.match("register read cl",
+ ["cl = 0x01"])
+ self.match("register read r8d",
+ ["r8d = 0x64636261"])
+ self.match("register read r8w",
+ ["r8w = 0x6261"])
+ self.match("register read r8l",
+ ["r8l = 0x61"])
+ self.match("register read mm0",
+ ["mm0 = 0x0807060504030201"])
+ self.match("register read mm1",
+ ["mm1 = 0x1817161514131211"])
+
# both stX and xmmX should be displayed as vectors
self.match("register read st0",
["st0 = {0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0a}"])
Index: lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext_x86_64.cpp
===================================================================
--- /dev/null
+++ lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext_x86_64.cpp
@@ -0,0 +1,193 @@
+//===-- GDBRemoteRegisterContext.cpp --------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "GDBRemoteRegisterContext.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::process_gdb_remote;
+
+enum PartialGPRRegKind {
+ eRegKind32,
+ eRegKind16,
+ eRegKind8h,
+ eRegKind8l,
+
+ eRegKindCount
+};
+
+struct PartialGPRReg {
+ const char *name;
+
+ // extra storage used for pointers
+ uint32_t value_regs[2];
+ uint32_t invalidate_regs[eRegKindCount];
+};
+
+struct PartialGPRRegSet {
+ const char *reg64;
+ PartialGPRReg r[eRegKindCount];
+};
+
+static std::array<PartialGPRRegSet, 16> partial_gpr_regs = {{
+ {"rax", {{"eax"}, {"ax"}, {"ah"}, {"al"}}},
+ {"rbx", {{"ebx"}, {"bx"}, {"bh"}, {"bl"}}},
+ {"rcx", {{"ecx"}, {"cx"}, {"ch"}, {"cl"}}},
+ {"rdx", {{"edx"}, {"dx"}, {"dh"}, {"dl"}}},
+ {"rdi", {{"edi"}, {"di"}, {nullptr}, {"dil"}}},
+ {"rsi", {{"esi"}, {"si"}, {nullptr}, {"sil"}}},
+ {"rbp", {{"ebp"}, {"bp"}, {nullptr}, {"bpl"}}},
+ {"rsp", {{"esp"}, {"sp"}, {nullptr}, {"spl"}}},
+ {"r8", {{"r8d"}, {"r8w"}, {nullptr}, {"r8l"}}},
+ {"r9", {{"r9d"}, {"r9w"}, {nullptr}, {"r9l"}}},
+ {"r10", {{"r10d"}, {"r10w"}, {nullptr}, {"r10l"}}},
+ {"r11", {{"r11d"}, {"r11w"}, {nullptr}, {"r11l"}}},
+ {"r12", {{"r12d"}, {"r12w"}, {nullptr}, {"r12l"}}},
+ {"r13", {{"r13d"}, {"r13w"}, {nullptr}, {"r13l"}}},
+ {"r14", {{"r14d"}, {"r14w"}, {nullptr}, {"r14l"}}},
+ {"r15", {{"r15d"}, {"r15w"}, {nullptr}, {"r15l"}}},
+}};
+
+static uint32_t partial_gpr_sizes[eRegKindCount] = {4, 2, 1, 1};
+
+struct MMReg {
+ const char *streg;
+ const char *name;
+
+ // extra storage used for pointers
+ uint32_t value_regs[2];
+};
+
+static std::array<MMReg, 16> mm_regs = {{
+ {"st0", "mm0"},
+ {"st1", "mm1"},
+ {"st2", "mm2"},
+ {"st3", "mm3"},
+ {"st4", "mm4"},
+ {"st5", "mm5"},
+ {"st6", "mm6"},
+ {"st7", "mm7"},
+}};
+
+void GDBRemoteDynamicRegisterInfo::PreFinalize_x86_64() {
+ uint32_t max_regnum = 0;
+ uint32_t next_regindex = m_regs.size();
+ for (const RegisterInfo ® : m_regs)
+ max_regnum = std::max(max_regnum, reg.kinds[eRegisterKindProcessPlugin]);
+
+ ConstString group;
+ group.SetCString("partial registers");
+
+ for (PartialGPRRegSet &partial_regset : partial_gpr_regs) {
+ const RegisterInfo *reg64 = GetRegisterInfo(partial_regset.reg64);
+ if (!reg64)
+ continue;
+ assert(reg64->byte_size == 8);
+
+ const RegisterInfo *reginfo[eRegKindCount];
+ uint32_t regno[eRegKindCount];
+
+ for (int i = 0; i < eRegKindCount; i++) {
+ if (!partial_regset.r[i].name)
+ continue;
+
+ reginfo[i] = GetRegisterInfo(partial_regset.r[i].name);
+ if (reginfo[i])
+ regno[i] = reginfo[i]->kinds[eRegisterKindProcessPlugin];
+ else
+ regno[i] = ++max_regnum;
+ }
+
+ for (int i = 0; i < eRegKindCount; i++) {
+ if (!partial_regset.r[i].name)
+ continue;
+
+ partial_regset.r[i].value_regs[0] =
+ reg64->kinds[eRegisterKindProcessPlugin];
+ partial_regset.r[i].value_regs[1] = LLDB_INVALID_REGNUM;
+
+ int k = 0;
+ for (int j = 0; j < eRegKindCount; j++) {
+ if (i != j && partial_regset.r[j].name)
+ partial_regset.r[i].invalidate_regs[k++] = regno[j];
+ }
+ partial_regset.r[i].invalidate_regs[k] = LLDB_INVALID_REGNUM;
+
+ struct RegisterInfo new_reg {
+ partial_regset.r[i].name, nullptr, partial_gpr_sizes[i],
+ LLDB_INVALID_INDEX32, reg64->encoding, reg64->format,
+ {
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, regno[i],
+ next_regindex++,
+ },
+ partial_regset.r[i].value_regs, partial_regset.r[i].invalidate_regs,
+ nullptr, 0
+ };
+
+ ConstString name;
+ ConstString alt_name;
+ name.SetCString(new_reg.name);
+ AddRegister(new_reg, name, alt_name, group);
+ }
+ }
+
+ for (MMReg &mmreg : mm_regs) {
+ const RegisterInfo *streg = GetRegisterInfo(mmreg.streg);
+ if (!streg)
+ continue;
+ assert(streg->byte_size == 10);
+
+ if (GetRegisterInfo(mmreg.name))
+ continue;
+
+ mmreg.value_regs[0] = streg->kinds[eRegisterKindProcessPlugin];
+ mmreg.value_regs[1] = LLDB_INVALID_REGNUM;
+
+ struct RegisterInfo new_reg {
+ mmreg.name, nullptr, 8, LLDB_INVALID_INDEX32, eEncodingUint, eFormatHex,
+ {
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ ++max_regnum, next_regindex++,
+ },
+ mmreg.value_regs, nullptr, nullptr, 0
+ };
+
+ ConstString name;
+ ConstString alt_name;
+ name.SetCString(new_reg.name);
+ AddRegister(new_reg, name, alt_name, group);
+ }
+}
+
+void GDBRemoteDynamicRegisterInfo::PostFinalize_x86_64() {
+ for (PartialGPRRegSet &partial_regset : partial_gpr_regs) {
+ if (!partial_regset.r[eRegKind8h].name)
+ continue;
+
+ llvm::StringRef reg8h_name = partial_regset.r[eRegKind8h].name;
+ const RegisterInfo *reg8h = GetRegisterInfo(reg8h_name);
+ const RegisterInfo *reg8l =
+ GetRegisterInfo(partial_regset.r[eRegKind8l].name);
+ if (!reg8h || !reg8l)
+ continue;
+ assert(reg8h->byte_size == 1);
+ assert(reg8l->byte_size == 1);
+
+ // we currently have no way of indicating offset via value_regs, so we
+ // instead increment it after Finalize() assigns byte offsets
+ if (reg8h->byte_offset == reg8l->byte_offset) {
+ for (auto ®_info : m_regs) {
+ if (reg_info.name == reg8h_name) {
+ reg_info.byte_offset++;
+ break;
+ }
+ }
+ }
+ }
+}
Index: lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h
===================================================================
--- lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h
+++ lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h
@@ -40,6 +40,10 @@
void HardcodeARMRegisters(bool from_scratch);
bool UpdateARM64SVERegistersInfos(uint64_t vg);
+ void Finalize(const lldb_private::ArchSpec &arch);
+
+ void PreFinalize_x86_64();
+ void PostFinalize_x86_64();
};
class GDBRemoteRegisterContext : public RegisterContext {
Index: lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
===================================================================
--- lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
+++ lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
@@ -1064,3 +1064,28 @@
}
}
}
+
+void GDBRemoteDynamicRegisterInfo::Finalize(const ArchSpec &arch) {
+ if (m_finalized)
+ return;
+
+ switch (arch.GetMachine()) {
+ case llvm::Triple::x86_64:
+ PreFinalize_x86_64();
+ break;
+
+ default:
+ break;
+ }
+
+ DynamicRegisterInfo::Finalize(arch);
+
+ switch (arch.GetMachine()) {
+ case llvm::Triple::x86_64:
+ PostFinalize_x86_64();
+ break;
+
+ default:
+ break;
+ }
+}
Index: lldb/source/Plugins/Process/gdb-remote/CMakeLists.txt
===================================================================
--- lldb/source/Plugins/Process/gdb-remote/CMakeLists.txt
+++ lldb/source/Plugins/Process/gdb-remote/CMakeLists.txt
@@ -26,6 +26,7 @@
GDBRemoteCommunicationServerLLGS.cpp
GDBRemoteCommunicationServerPlatform.cpp
GDBRemoteRegisterContext.cpp
+ GDBRemoteRegisterContext_x86_64.cpp
ProcessGDBRemote.cpp
ProcessGDBRemoteLog.cpp
ThreadGDBRemote.cpp
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits