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 &reg_ctx,
     const RegisterInfo &reg_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 &reg_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
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to