PatriosTheGreat updated this revision to Diff 243579.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D74217/new/
https://reviews.llvm.org/D74217
Files:
lldb/packages/Python/lldbsuite/test/tools/lldb-server/registers-target-xml-reading/Makefile
lldb/packages/Python/lldbsuite/test/tools/lldb-server/registers-target-xml-reading/TestGdbRemoteTargetXmlPacket.py
lldb/packages/Python/lldbsuite/test/tools/lldb-server/registers-target-xml-reading/main.cpp
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
Index: lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
===================================================================
--- lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
+++ lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
@@ -377,6 +377,87 @@
}
}
+static std::string GetEncodingNameOrEmpty(const RegisterInfo *reg_info) {
+ switch (reg_info->encoding) {
+ case eEncodingUint:
+ return "uint";
+ case eEncodingSint:
+ return "sint";
+ case eEncodingIEEE754:
+ return "ieee754";
+ case eEncodingVector:
+ return "vector";
+ default:
+ return "";
+ }
+}
+
+static std::string GetFormatNameOrEmpty(const RegisterInfo *reg_info) {
+ switch (reg_info->format) {
+ case eFormatBinary:
+ return "binary";
+ case eFormatDecimal:
+ return "decimal";
+ case eFormatHex:
+ return "hex";
+ case eFormatFloat:
+ return "float";
+ case eFormatVectorOfSInt8:
+ return "vector-sint8";
+ case eFormatVectorOfUInt8:
+ return "vector-uint8";
+ case eFormatVectorOfSInt16:
+ return "vector-sint16";
+ case eFormatVectorOfUInt16:
+ return "vector-uint16";
+ case eFormatVectorOfSInt32:
+ return "vector-sint32";
+ case eFormatVectorOfUInt32:
+ return "vector-uint32";
+ case eFormatVectorOfFloat32:
+ return "vector-float32";
+ case eFormatVectorOfUInt64:
+ return "vector-uint64";
+ case eFormatVectorOfUInt128:
+ return "vector-uint128";
+ default:
+ return "";
+ };
+}
+
+static std::string GetKindGenericOrEmpty(const RegisterInfo *reg_info) {
+ switch (reg_info->kinds[RegisterKind::eRegisterKindGeneric]) {
+ case LLDB_REGNUM_GENERIC_PC:
+ return "pc";
+ case LLDB_REGNUM_GENERIC_SP:
+ return "sp";
+ case LLDB_REGNUM_GENERIC_FP:
+ return "fp";
+ case LLDB_REGNUM_GENERIC_RA:
+ return "ra";
+ case LLDB_REGNUM_GENERIC_FLAGS:
+ return "flags";
+ case LLDB_REGNUM_GENERIC_ARG1:
+ return "arg1";
+ case LLDB_REGNUM_GENERIC_ARG2:
+ return "arg2";
+ case LLDB_REGNUM_GENERIC_ARG3:
+ return "arg3";
+ case LLDB_REGNUM_GENERIC_ARG4:
+ return "arg4";
+ case LLDB_REGNUM_GENERIC_ARG5:
+ return "arg5";
+ case LLDB_REGNUM_GENERIC_ARG6:
+ return "arg6";
+ case LLDB_REGNUM_GENERIC_ARG7:
+ return "arg7";
+ case LLDB_REGNUM_GENERIC_ARG8:
+ return "arg8";
+ default:
+ return "";
+ }
+}
+
static void WriteRegisterValueInHexFixedWidth(
StreamString &response, NativeRegisterContext ®_ctx,
const RegisterInfo ®_info, const RegisterValue *reg_value_p,
@@ -1699,66 +1780,19 @@
response.Printf("bitsize:%" PRIu32 ";offset:%" PRIu32 ";",
reg_info->byte_size * 8, reg_info->byte_offset);
- switch (reg_info->encoding) {
- case eEncodingUint:
- response.PutCString("encoding:uint;");
- break;
- case eEncodingSint:
- response.PutCString("encoding:sint;");
- break;
- case eEncodingIEEE754:
- response.PutCString("encoding:ieee754;");
- break;
- case eEncodingVector:
- response.PutCString("encoding:vector;");
- break;
- default:
- break;
+ std::string encoding = GetEncodingNameOrEmpty(reg_info);
+ if (!encoding.empty()) {
+ response.PutCString("encoding:");
+ response.PutCString(encoding.c_str());
+ response.PutChar(';');
}
- switch (reg_info->format) {
- case eFormatBinary:
- response.PutCString("format:binary;");
- break;
- case eFormatDecimal:
- response.PutCString("format:decimal;");
- break;
- case eFormatHex:
- response.PutCString("format:hex;");
- break;
- case eFormatFloat:
- response.PutCString("format:float;");
- break;
- case eFormatVectorOfSInt8:
- response.PutCString("format:vector-sint8;");
- break;
- case eFormatVectorOfUInt8:
- response.PutCString("format:vector-uint8;");
- break;
- case eFormatVectorOfSInt16:
- response.PutCString("format:vector-sint16;");
- break;
- case eFormatVectorOfUInt16:
- response.PutCString("format:vector-uint16;");
- break;
- case eFormatVectorOfSInt32:
- response.PutCString("format:vector-sint32;");
- break;
- case eFormatVectorOfUInt32:
- response.PutCString("format:vector-uint32;");
- break;
- case eFormatVectorOfFloat32:
- response.PutCString("format:vector-float32;");
- break;
- case eFormatVectorOfUInt64:
- response.PutCString("format:vector-uint64;");
- break;
- case eFormatVectorOfUInt128:
- response.PutCString("format:vector-uint128;");
- break;
- default:
- break;
- };
+ std::string format = GetFormatNameOrEmpty(reg_info);
+ if (!format.empty()) {
+ response.PutCString("format:");
+ response.PutCString(format.c_str());
+ response.PutChar(';');
+ }
const char *const register_set_name =
reg_context.GetRegisterSetNameForRegisterAtIndex(reg_index);
@@ -1777,48 +1811,11 @@
response.Printf("dwarf:%" PRIu32 ";",
reg_info->kinds[RegisterKind::eRegisterKindDWARF]);
- switch (reg_info->kinds[RegisterKind::eRegisterKindGeneric]) {
- case LLDB_REGNUM_GENERIC_PC:
- response.PutCString("generic:pc;");
- break;
- case LLDB_REGNUM_GENERIC_SP:
- response.PutCString("generic:sp;");
- break;
- case LLDB_REGNUM_GENERIC_FP:
- response.PutCString("generic:fp;");
- break;
- case LLDB_REGNUM_GENERIC_RA:
- response.PutCString("generic:ra;");
- break;
- case LLDB_REGNUM_GENERIC_FLAGS:
- response.PutCString("generic:flags;");
- break;
- case LLDB_REGNUM_GENERIC_ARG1:
- response.PutCString("generic:arg1;");
- break;
- case LLDB_REGNUM_GENERIC_ARG2:
- response.PutCString("generic:arg2;");
- break;
- case LLDB_REGNUM_GENERIC_ARG3:
- response.PutCString("generic:arg3;");
- break;
- case LLDB_REGNUM_GENERIC_ARG4:
- response.PutCString("generic:arg4;");
- break;
- case LLDB_REGNUM_GENERIC_ARG5:
- response.PutCString("generic:arg5;");
- break;
- case LLDB_REGNUM_GENERIC_ARG6:
- response.PutCString("generic:arg6;");
- break;
- case LLDB_REGNUM_GENERIC_ARG7:
- response.PutCString("generic:arg7;");
- break;
- case LLDB_REGNUM_GENERIC_ARG8:
- response.PutCString("generic:arg8;");
- break;
- default:
- break;
+ std::string kind_generic = GetKindGenericOrEmpty(reg_info);
+ if (!kind_generic.empty()) {
+ response.PutCString("generic:");
+ response.PutCString(kind_generic.c_str());
+ response.PutChar(';');
}
if (reg_info->value_regs && reg_info->value_regs[0] != LLDB_INVALID_REGNUM) {
@@ -2786,6 +2783,132 @@
return MemoryBuffer::getMemBufferCopy(response.GetString(), __FUNCTION__);
}
+ if (object == "features" && annex == "target.xml") {
+ // Make sure we have a valid process.
+ if (!m_debugged_process_up ||
+ (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) {
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "No process available");
+ }
+
+ // Ensure we have a thread.
+ NativeThreadProtocol *thread = m_debugged_process_up->GetThreadAtIndex(0);
+ if (!thread)
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "No thread available");
+
+ Log *log(
+ GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
+ // Get the register context for the first thread.
+ NativeRegisterContext ®_context = thread->GetRegisterContext();
+
+ StreamString response;
+
+ response.Printf("<?xml version=\"1.0\"?>");
+ response.Printf("<target version=\"1.0\">");
+
+ response.Printf("<architecture>%s</architecture>",
+ m_debugged_process_up->GetArchitecture()
+ .GetTriple()
+ .getArchName()
+ .str()
+ .c_str());
+
+ response.Printf("<feature>");
+
+ const int registers_count = reg_context.GetUserRegisterCount();
+ for (int reg_index = 0; reg_index < registers_count; reg_index++) {
+ const RegisterInfo *reg_info =
+ reg_context.GetRegisterInfoAtIndex(reg_index);
+
+ if (!reg_info) {
+ LLDB_LOGF(log,
+ "%s failed to get register info for register index %" PRIu32,
+ "target.xml", reg_index);
+ continue;
+ }
+
+ response.Printf("<reg name=\"%s\" bitsize=\"%" PRIu32
+ "\" offset=\"%" PRIu32 "\" regnum=\"%d\" ",
+ reg_info->name, reg_info->byte_size * 8,
+ reg_info->byte_offset, reg_index);
+
+ if (reg_info->alt_name && reg_info->alt_name[0]) {
+ response.Printf("altname=\"%s\" ", reg_info->alt_name);
+ }
+
+ std::string encoding = GetEncodingNameOrEmpty(reg_info);
+ if (!encoding.empty()) {
+ response.Printf("encoding=\"%s\" ", encoding.c_str());
+ }
+
+ std::string format = GetFormatNameOrEmpty(reg_info);
+ if (!format.empty()) {
+ response.Printf("format=\"%s\" ", format.c_str());
+ }
+
+ const char *const register_set_name =
+ reg_context.GetRegisterSetNameForRegisterAtIndex(reg_index);
+ if (register_set_name) {
+ response.Printf("group=\"%s\" ", register_set_name);
+ }
+
+ if (reg_info->kinds[RegisterKind::eRegisterKindEHFrame] !=
+ LLDB_INVALID_REGNUM)
+ response.Printf("ehframe_regnum=\"%" PRIu32 "\" ",
+ reg_info->kinds[RegisterKind::eRegisterKindEHFrame]);
+
+ if (reg_info->kinds[RegisterKind::eRegisterKindDWARF] !=
+ LLDB_INVALID_REGNUM)
+ response.Printf("dwarf_regnum=\"%" PRIu32 "\" ",
+ reg_info->kinds[RegisterKind::eRegisterKindDWARF]);
+
+ std::string kind_generic = GetKindGenericOrEmpty(reg_info);
+ if (!kind_generic.empty()) {
+ response.Printf("generic=\"%s\" ", kind_generic.c_str());
+ }
+
+ if (reg_info->value_regs &&
+ reg_info->value_regs[0] != LLDB_INVALID_REGNUM) {
+ response.PutCString("value_regnums=\"");
+ int i = 0;
+ for (const uint32_t *reg_num = reg_info->value_regs;
+ *reg_num != LLDB_INVALID_REGNUM; ++reg_num, ++i) {
+ if (i > 0)
+ response.PutChar(',');
+ response.Printf("%" PRIx32, *reg_num);
+ }
+ response.Printf("\" ");
+ }
+
+ if (reg_info->invalidate_regs && reg_info->invalidate_regs[0]) {
+ response.PutCString("invalidate_regnums=\"");
+ int i = 0;
+ for (const uint32_t *reg_num = reg_info->invalidate_regs;
+ *reg_num != LLDB_INVALID_REGNUM; ++reg_num, ++i) {
+ if (i > 0)
+ response.PutChar(',');
+ response.Printf("%" PRIx32, *reg_num);
+ }
+ response.Printf("\" ");
+ }
+
+ if (reg_info->dynamic_size_dwarf_expr_bytes) {
+ const size_t dwarf_opcode_len = reg_info->dynamic_size_dwarf_len;
+ response.PutCString("dynamic_size_dwarf_expr_bytes=\"");
+ for (uint32_t i = 0; i < dwarf_opcode_len; ++i)
+ response.PutHex8(reg_info->dynamic_size_dwarf_expr_bytes[i]);
+ response.Printf("\" ");
+ }
+
+ response.Printf("/>");
+ }
+
+ response.Printf("</feature>");
+ response.Printf("</target>");
+ return MemoryBuffer::getMemBufferCopy(response.GetString(), "target.xml");
+ }
+
return llvm::make_error<PacketUnimplementedError>(
"Xfer object not supported");
}
Index: lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
===================================================================
--- lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
+++ lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
@@ -846,6 +846,7 @@
#if defined(__linux__) || defined(__NetBSD__)
response.PutCString(";QPassSignals+");
response.PutCString(";qXfer:auxv:read+");
+ response.PutCString(";qXfer:features:read+");
response.PutCString(";qXfer:libraries-svr4:read+");
#endif
Index: lldb/packages/Python/lldbsuite/test/tools/lldb-server/registers-target-xml-reading/main.cpp
===================================================================
--- /dev/null
+++ lldb/packages/Python/lldbsuite/test/tools/lldb-server/registers-target-xml-reading/main.cpp
@@ -0,0 +1,54 @@
+#include <cstdint>
+
+int main() {
+#if defined(__x86_64__)
+ struct alignas(16) xmm_t {
+ uint64_t a, b;
+ };
+ uint64_t r8 = 0x0102030405060708;
+ uint64_t r9 = 0x1112131415161718;
+ uint64_t r10 = 0x2122232425262728;
+ uint64_t r11 = 0x3132333435363738;
+ uint64_t r12 = 0x4142434445464748;
+ uint64_t r13 = 0x5152535455565758;
+ uint64_t r14 = 0x6162636465666768;
+ uint64_t r15 = 0x7172737475767778;
+
+ xmm_t xmm8 = {0x020406080A0C0E01, 0x030507090B0D0F00};
+ xmm_t xmm9 = {0x121416181A1C1E11, 0x131517191B1D1F10};
+ xmm_t xmm10 = {0x222426282A2C2E21, 0x232527292B2D2F20};
+ xmm_t xmm11 = {0x323436383A3C3E31, 0x333537393B3D3F30};
+ xmm_t xmm12 = {0x424446484A4C4E41, 0x434547494B4D4F40};
+ xmm_t xmm13 = {0x525456585A5C5E51, 0x535557595B5D5F50};
+ xmm_t xmm14 = {0x626466686A6C6E61, 0x636567696B6D6F60};
+ xmm_t xmm15 = {0x727476787A7C7E71, 0x737577797B7D7F70};
+
+ asm volatile("movq %0, %%r8\n\t"
+ "movq %1, %%r9\n\t"
+ "movq %2, %%r10\n\t"
+ "movq %3, %%r11\n\t"
+ "movq %4, %%r12\n\t"
+ "movq %5, %%r13\n\t"
+ "movq %6, %%r14\n\t"
+ "movq %7, %%r15\n\t"
+ "\n\t"
+ "movaps %8, %%xmm8\n\t"
+ "movaps %9, %%xmm9\n\t"
+ "movaps %10, %%xmm10\n\t"
+ "movaps %11, %%xmm11\n\t"
+ "movaps %12, %%xmm12\n\t"
+ "movaps %13, %%xmm13\n\t"
+ "movaps %14, %%xmm14\n\t"
+ "movaps %15, %%xmm15\n\t"
+ "\n\t"
+ "int3"
+ :
+ : "g"(r8), "g"(r9), "g"(r10), "g"(r11), "g"(r12), "g"(r13),
+ "g"(r14), "g"(r15), "m"(xmm8), "m"(xmm9), "m"(xmm10),
+ "m"(xmm11), "m"(xmm12), "m"(xmm13), "m"(xmm14), "m"(xmm15)
+ : "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
+ "%xmm8", "%xmm9", "%xmm10", "%xmm11", "%xmm12", "%xmm13",
+ "%xmm14", "%xmm15");
+#endif
+ return 0;
+}
Index: lldb/packages/Python/lldbsuite/test/tools/lldb-server/registers-target-xml-reading/TestGdbRemoteTargetXmlPacket.py
===================================================================
--- /dev/null
+++ lldb/packages/Python/lldbsuite/test/tools/lldb-server/registers-target-xml-reading/TestGdbRemoteTargetXmlPacket.py
@@ -0,0 +1,69 @@
+
+
+import gdbremote_testcase
+import textwrap
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+import re
+import xml.etree.ElementTree as ET
+
+class TestGdbRemoteTargetXmlPacket(gdbremote_testcase.GdbRemoteTestCaseBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @expectedFailureNetBSD
+ @llgs_test
+ def test_g_target_xml_returns_correct_data(self):
+ self.init_llgs_test()
+ self.build()
+ self.set_inferior_startup_launch()
+
+ procs = self.prep_debug_monitor_and_inferior()
+
+ OFFSET = 0
+ LENGTH = 0x1ffff0
+ self.test_sequence.add_log_lines([
+ "read packet: $qXfer:features:read:target.xml:{:x},{:x}#00".format(
+ OFFSET,
+ LENGTH),
+ {
+ "direction": "send",
+ "regex": re.compile("^\$l(.+)#[0-9a-fA-F]{2}$"),
+ "capture": {1: "target_xml"}
+ }],
+ True)
+ context = self.expect_gdbremote_sequence()
+
+ target_xml = context.get("target_xml")
+
+ root = ET.fromstring(target_xml)
+ self.assertIsNotNone(root)
+ self.assertEqual(root.tag, "target")
+
+ architecture = root.find("architecture")
+ self.assertIsNotNone(architecture)
+ self.assertEqual(architecture.text, self.getArchitecture())
+
+ feature = root.find("feature")
+ self.assertIsNotNone(feature)
+
+ target_xml_registers = feature.findall("reg")
+ self.assertTrue(len(target_xml_registers) > 0)
+
+ # registers info collected by qRegisterInfo
+ self.add_register_info_collection_packets()
+ context = self.expect_gdbremote_sequence()
+ self.assertIsNotNone(context)
+ q_info_registers = self.parse_register_info_packets(context)
+
+ self.assertTrue(len(target_xml_registers) == len(q_info_registers))
+ for register in zip(target_xml_registers, q_info_registers):
+ xml_info_reg = register[0]
+ q_info_reg = register[1]
+ self.assertEqual(q_info_reg["name"], xml_info_reg.get("name"))
+ self.assertEqual(q_info_reg["set"], xml_info_reg.get("group"))
+ self.assertEqual(q_info_reg["format"], xml_info_reg.get("format"))
+ self.assertEqual(q_info_reg["bitsize"], xml_info_reg.get("bitsize"))
+ self.assertEqual(q_info_reg["offset"], xml_info_reg.get("offset"))
+ self.assertEqual(q_info_reg["encoding"], xml_info_reg.get("encoding"))
\ No newline at end of file
Index: lldb/packages/Python/lldbsuite/test/tools/lldb-server/registers-target-xml-reading/Makefile
===================================================================
--- /dev/null
+++ lldb/packages/Python/lldbsuite/test/tools/lldb-server/registers-target-xml-reading/Makefile
@@ -0,0 +1,3 @@
+CXX_SOURCES := main.cpp
+
+include Makefile.rules
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits