[RFC 6/7] Lazily and dynamically create i386-linux target descriptions

Yao Qi qiyaoltc@gmail.com
Thu May 11 15:55:00 GMT 2017


Instead of using pre-generated target descriptions, this patch
changes GDB to lazily and dynamically create target descriptions
according to the target hardware capability (xcr0 in i386).
This support any combination of target features.

This patch also adds a unit test to make sure dynamically generated
tdesc are identical to these generated from xml files.

gdb:

2017-04-27  Yao Qi  <yao.qi@linaro.org>

	* i386-linux-tdep.c (i386_linux_read_description): Generate
	target description if it doesn't exist.
        [GDB_SELF_TEST] (i386_linux_read_description_test): New unit test.
        (_initialize_i386_linux_tdep) [GDB_SELF_TEST]: Register unit test.
---
 gdb/i386-linux-tdep.c | 85 ++++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 67 insertions(+), 18 deletions(-)

diff --git a/gdb/i386-linux-tdep.c b/gdb/i386-linux-tdep.c
index 1bc1a6f..615cca5 100644
--- a/gdb/i386-linux-tdep.c
+++ b/gdb/i386-linux-tdep.c
@@ -681,27 +681,50 @@ i386_linux_core_read_xcr0 (bfd *abfd)
 const struct target_desc *
 i386_linux_read_description (uint64_t xcr0)
 {
-  switch ((xcr0 & X86_XSTATE_ALL_MASK))
+  if (xcr0 == 0)
+    return NULL;
+
+  static struct target_desc *i386_linux_tdescs \
+    [2/*X87*/][2/*SSE*/][2/*AVX*/][2/*MPX*/][2/*AVX512*/][2/*PKRU*/] = {};
+  struct target_desc **tdesc;
+
+  tdesc = &i386_linux_tdescs[(xcr0 & X86_XSTATE_X87) ? 1 : 0]
+    [(xcr0 & X86_XSTATE_SSE) ? 1 : 0]
+    [(xcr0 & X86_XSTATE_AVX) ? 1 : 0]
+    [(xcr0 & X86_XSTATE_MPX) ? 1 : 0]
+    [(xcr0 & X86_XSTATE_AVX512) ? 1 : 0]
+    [(xcr0 & X86_XSTATE_PKRU) ? 1 : 0];
+
+  if (*tdesc == NULL)
     {
-    case X86_XSTATE_AVX_MPX_AVX512_PKU_MASK:
-      return tdesc_i386_avx_mpx_avx512_pku_linux;
-    case X86_XSTATE_AVX_AVX512_MASK:
-      return tdesc_i386_avx_avx512_linux;
-    case X86_XSTATE_MPX_MASK:
-      return tdesc_i386_mpx_linux;
-    case X86_XSTATE_AVX_MPX_MASK:
-      return tdesc_i386_avx_mpx_linux;
-    case X86_XSTATE_AVX_MASK:
-      return tdesc_i386_avx_linux;
-    case X86_XSTATE_SSE_MASK:
-      return tdesc_i386_linux;
-    case X86_XSTATE_X87_MASK:
-      return tdesc_i386_mmx_linux;
-    default:
-      break;
+      *tdesc = allocate_target_description ();
+      set_tdesc_architecture (*tdesc, bfd_scan_arch ("i386"));
+      set_tdesc_osabi (*tdesc, osabi_from_tdesc_string ("GNU/Linux"));
+
+      long regnum = 0;
+
+      if (xcr0 & X86_XSTATE_X87)
+	regnum = create_feature_org_gnu_gdb_i386_core_i386 (*tdesc, regnum);
+
+      if (xcr0 & X86_XSTATE_SSE)
+	regnum = create_feature_org_gnu_gdb_i386_sse (*tdesc, regnum);
+
+      regnum = create_feature_org_gnu_gdb_i386_linux (*tdesc, regnum);
+
+      if (xcr0 & X86_XSTATE_AVX)
+	regnum = create_feature_org_gnu_gdb_i386_avx (*tdesc, regnum);
+
+      if (xcr0 & X86_XSTATE_MPX)
+	regnum = create_feature_org_gnu_gdb_i386_mpx (*tdesc, regnum);
+
+      if (xcr0 & X86_XSTATE_AVX512)
+	regnum = create_feature_org_gnu_gdb_i386_avx512 (*tdesc, regnum);
+
+      if (xcr0 & X86_XSTATE_PKRU)
+	regnum = create_feature_org_gnu_gdb_i386_pkeys (*tdesc, regnum);
     }
 
-  return NULL;
+  return *tdesc;
 }
 
 /* Get Linux/x86 target description from core dump.  */
@@ -1101,4 +1124,30 @@ _initialize_i386_linux_tdep (void)
   initialize_tdesc_i386_avx_mpx_linux ();
   initialize_tdesc_i386_avx_avx512_linux ();
   initialize_tdesc_i386_avx_mpx_avx512_pku_linux ();
+
+#if GDB_SELF_TEST
+  struct xml_and_mask
+  {
+    const char *xml_file_name;
+    uint64_t mask;
+  };
+
+  struct xml_and_mask array[] = {
+    { "i386/i386-linux.xml", X86_XSTATE_SSE_MASK },
+    { "i386/i386-mmx-linux.xml", X86_XSTATE_X87_MASK },
+    { "i386/i386-avx-linux.xml", X86_XSTATE_AVX_MASK },
+    { "i386/i386-mpx-linux.xml", X86_XSTATE_MPX_MASK },
+    { "i386/i386-avx-mpx-linux.xml", X86_XSTATE_AVX_MPX_MASK },
+    { "i386/i386-avx-avx512-linux.xml", X86_XSTATE_AVX_AVX512_MASK },
+    { "i386/i386-avx-mpx-avx512-pku-linux.xml",
+      X86_XSTATE_AVX_MPX_AVX512_PKU_MASK },
+  };
+
+  for (auto &a : array)
+    {
+      auto tdesc = i386_linux_read_description (a.mask);
+
+      selftests::record_xml_tdesc (a.xml_file_name, tdesc);
+    }
+#endif /* GDB_SELF_TEST */
 }
-- 
1.9.1



More information about the Gdb-patches mailing list