s/get_regcache_arch (regcache)/regcache->arch ()/g
[deliverable/binutils-gdb.git] / gdb / target-descriptions.c
index 333cbd89ab7c1337af35dc611da1f012f94c8931..4f5e9d60a6d98b5855d6ee4ffeaa9fd7149d6395 100644 (file)
@@ -35,6 +35,8 @@
 #include "hashtab.h"
 #include "inferior.h"
 #include <algorithm>
+#include "completer.h"
+#include "readline/tilde.h" /* tilde_expand */
 
 /* The interface to visit different elements of target description.  */
 
@@ -91,9 +93,7 @@ typedef struct tdesc_reg : tdesc_element
     xfree (group);
   }
 
-  /* Disable copying.  */
-  tdesc_reg (const tdesc_reg &) = delete;
-  tdesc_reg &operator= (const tdesc_reg &) = delete;
+  DISABLE_COPY_AND_ASSIGN (tdesc_reg);
 
   /* The name of this register.  In standard features, it may be
      recognized by the architecture support code, or it may be purely
@@ -134,6 +134,20 @@ typedef struct tdesc_reg : tdesc_element
     v.visit (this);
   }
 
+  bool operator== (const tdesc_reg &other) const
+  {
+    return (streq (name, other.name)
+           && target_regnum == other.target_regnum
+           && save_restore == other.save_restore
+           && bitsize == other.bitsize
+           && (group == other.group || streq (group, other.group))
+           && streq (type, other.type));
+  }
+
+  bool operator!= (const tdesc_reg &other) const
+  {
+    return !(*this == other);
+  }
 } *tdesc_reg_p;
 DEF_VEC_P(tdesc_reg_p);
 
@@ -213,9 +227,8 @@ typedef struct tdesc_type : tdesc_element
       }
     xfree ((char *) name);
   }
-  /* Disable copying.  */
-  tdesc_type (const tdesc_type &) = delete;
-  tdesc_type &operator= (const tdesc_type &) = delete;
+
+  DISABLE_COPY_AND_ASSIGN (tdesc_type);
 
   /* The name of this type.  If this type is a built-in type, this is
      a pointer to a constant string.  Otherwise, it's a
@@ -248,6 +261,15 @@ typedef struct tdesc_type : tdesc_element
     v.visit (this);
   }
 
+  bool operator== (const tdesc_type &other) const
+  {
+    return (streq (name, other.name) && kind == other.kind);
+  }
+
+  bool operator!= (const tdesc_type &other) const
+  {
+    return !(*this == other);
+  }
 } *tdesc_type_p;
 DEF_VEC_P(tdesc_type_p);
 
@@ -277,9 +299,7 @@ typedef struct tdesc_feature : tdesc_element
     xfree (name);
   }
 
-  /* Disable copying.  */
-  tdesc_feature (const tdesc_feature &) = delete;
-  tdesc_feature &operator= (const tdesc_feature &) = delete;
+  DISABLE_COPY_AND_ASSIGN (tdesc_feature);
 
   /* The name of this feature.  It may be recognized by the architecture
      support code.  */
@@ -312,6 +332,54 @@ typedef struct tdesc_feature : tdesc_element
 
     v.visit_post (this);
   }
+
+  bool operator== (const tdesc_feature &other) const
+  {
+    if (strcmp (name, other.name) != 0)
+      return false;
+
+    if (VEC_length (tdesc_reg_p, registers)
+       != VEC_length (tdesc_reg_p, other.registers))
+      return false;
+
+    struct tdesc_reg *reg;
+
+    for (int ix = 0;
+        VEC_iterate (tdesc_reg_p, registers, ix, reg);
+        ix++)
+      {
+       tdesc_reg *reg2
+         = VEC_index (tdesc_reg_p, other.registers, ix);
+
+       if (reg != reg2 && *reg != *reg2)
+         return false;
+      }
+
+    if (VEC_length (tdesc_type_p, types)
+       != VEC_length (tdesc_type_p, other.types))
+      return false;
+
+    tdesc_type *type;
+
+    for (int ix = 0;
+        VEC_iterate (tdesc_type_p, types, ix, type);
+        ix++)
+      {
+       tdesc_type *type2
+         = VEC_index (tdesc_type_p, other.types, ix);
+
+       if (type != type2 && *type != *type2)
+         return false;
+      }
+
+    return true;
+  }
+
+  bool operator!= (const tdesc_feature &other) const
+  {
+    return !(*this == other);
+  }
+
 } *tdesc_feature_p;
 DEF_VEC_P(tdesc_feature_p);
 
@@ -382,6 +450,39 @@ struct target_desc : tdesc_element
 
     v.visit_post (this);
   }
+
+  bool operator== (const target_desc &other) const
+  {
+    if (arch != other.arch)
+      return false;
+
+    if (osabi != other.osabi)
+      return false;
+
+    if (VEC_length (tdesc_feature_p, features)
+       != VEC_length (tdesc_feature_p, other.features))
+      return false;
+
+    struct tdesc_feature *feature;
+
+    for (int ix = 0;
+        VEC_iterate (tdesc_feature_p, features, ix, feature);
+        ix++)
+      {
+       struct tdesc_feature *feature2
+         = VEC_index (tdesc_feature_p, other.features, ix);
+
+       if (feature != feature2 && *feature != *feature2)
+         return false;
+      }
+
+    return true;
+  }
+
+  bool operator!= (const target_desc &other) const
+  {
+    return !(*this == other);
+  }
 };
 
 /* Per-architecture data associated with a target description.  The
@@ -740,8 +841,7 @@ tdesc_predefined_type (enum tdesc_type_kind kind)
   gdb_assert_not_reached ("bad predefined tdesc type");
 }
 
-/* Return the type associated with ID in the context of FEATURE, or
-   NULL if none.  */
+/* See arch/tdesc.h.  */
 
 struct tdesc_type *
 tdesc_named_type (const struct tdesc_feature *feature, const char *id)
@@ -967,7 +1067,7 @@ tdesc_gdb_type (struct gdbarch *gdbarch, struct tdesc_type *tdesc_type)
        int ix;
 
        type = arch_flags_type (gdbarch, tdesc_type->name,
-                               tdesc_type->u.u.size);
+                               tdesc_type->u.u.size * TARGET_CHAR_BIT);
        for (ix = 0;
             VEC_iterate (tdesc_type_field, tdesc_type->u.u.fields, ix, f);
             ix++)
@@ -990,7 +1090,8 @@ tdesc_gdb_type (struct gdbarch *gdbarch, struct tdesc_type *tdesc_type)
        int ix;
 
        type = arch_type (gdbarch, TYPE_CODE_ENUM,
-                         tdesc_type->u.u.size, tdesc_type->name);
+                         tdesc_type->u.u.size * TARGET_CHAR_BIT,
+                         tdesc_type->name);
        TYPE_UNSIGNED (type) = 1;
        for (ix = 0;
             VEC_iterate (tdesc_type_field, tdesc_type->u.u.fields, ix, f);
@@ -1460,6 +1561,8 @@ tdesc_use_registers (struct gdbarch *gdbarch,
 }
 \f
 
+/* See arch/tdesc.h.  */
+
 void
 tdesc_create_reg (struct tdesc_feature *feature, const char *name,
                  int regnum, int save_restore, const char *group,
@@ -1471,6 +1574,8 @@ tdesc_create_reg (struct tdesc_feature *feature, const char *name,
   VEC_safe_push (tdesc_reg_p, feature->registers, reg);
 }
 
+/* See arch/tdesc.h.  */
+
 struct tdesc_type *
 tdesc_create_vector (struct tdesc_feature *feature, const char *name,
                     struct tdesc_type *field_type, int count)
@@ -1484,6 +1589,8 @@ tdesc_create_vector (struct tdesc_feature *feature, const char *name,
   return type;
 }
 
+/* See arch/tdesc.h.  */
+
 struct tdesc_type *
 tdesc_create_struct (struct tdesc_feature *feature, const char *name)
 {
@@ -1493,9 +1600,7 @@ tdesc_create_struct (struct tdesc_feature *feature, const char *name)
   return type;
 }
 
-/* Set the total length of TYPE.  Structs which contain bitfields may
-   omit the reserved bits, so the end of the last field may not
-   suffice.  */
+/* See arch/tdesc.h.  */
 
 void
 tdesc_set_struct_size (struct tdesc_type *type, int size)
@@ -1505,6 +1610,8 @@ tdesc_set_struct_size (struct tdesc_type *type, int size)
   type->u.u.size = size;
 }
 
+/* See arch/tdesc.h.  */
+
 struct tdesc_type *
 tdesc_create_union (struct tdesc_feature *feature, const char *name)
 {
@@ -1514,6 +1621,8 @@ tdesc_create_union (struct tdesc_feature *feature, const char *name)
   return type;
 }
 
+/* See arch/tdesc.h.  */
+
 struct tdesc_type *
 tdesc_create_flags (struct tdesc_feature *feature, const char *name,
                    int size)
@@ -1542,7 +1651,7 @@ tdesc_create_enum (struct tdesc_feature *feature, const char *name,
   return type;
 }
 
-/* Add a new field to TYPE.  */
+/* See arch/tdesc.h.  */
 
 void
 tdesc_add_field (struct tdesc_type *type, const char *field_name,
@@ -1563,8 +1672,6 @@ tdesc_add_field (struct tdesc_type *type, const char *field_name,
   VEC_safe_push (tdesc_type_field, type->u.u.fields, &f);
 }
 
-/* Add a new typed bitfield to TYPE.  */
-
 void
 tdesc_add_typed_bitfield (struct tdesc_type *type, const char *field_name,
                          int start, int end, struct tdesc_type *field_type)
@@ -1583,9 +1690,7 @@ tdesc_add_typed_bitfield (struct tdesc_type *type, const char *field_name,
   VEC_safe_push (tdesc_type_field, type->u.u.fields, &f);
 }
 
-/* Add a new untyped bitfield to TYPE.
-   Untyped bitfields become either uint32 or uint64 depending on the size
-   of the underlying type.  */
+/* See arch/tdesc.h.  */
 
 void
 tdesc_add_bitfield (struct tdesc_type *type, const char *field_name,
@@ -1603,8 +1708,7 @@ tdesc_add_bitfield (struct tdesc_type *type, const char *field_name,
   tdesc_add_typed_bitfield (type, field_name, start, end, field_type);
 }
 
-/* A flag is just a typed(bool) single-bit bitfield.
-   This function is kept to minimize changes in generated files.  */
+/* See arch/tdesc.h.  */
 
 void
 tdesc_add_flag (struct tdesc_type *type, int start,
@@ -1639,8 +1743,11 @@ tdesc_add_enum_value (struct tdesc_type *type, int value,
   VEC_safe_push (tdesc_type_field, type->u.u.fields, &f);
 }
 
+/* See arch/tdesc.h.  */
+
 struct tdesc_feature *
-tdesc_create_feature (struct target_desc *tdesc, const char *name)
+tdesc_create_feature (struct target_desc *tdesc, const char *name,
+                     const char *xml)
 {
   struct tdesc_feature *new_feature = new tdesc_feature (name);
 
@@ -1712,6 +1819,15 @@ set_tdesc_property (struct target_desc *target_desc,
   VEC_safe_push (property_s, target_desc->properties, &new_prop);
 }
 
+/* See arch/tdesc.h.  */
+
+void
+set_tdesc_architecture (struct target_desc *target_desc,
+                       const char *name)
+{
+  set_tdesc_architecture (target_desc, bfd_scan_arch (name));
+}
+
 void
 set_tdesc_architecture (struct target_desc *target_desc,
                        const struct bfd_arch_info *arch)
@@ -1719,6 +1835,14 @@ set_tdesc_architecture (struct target_desc *target_desc,
   target_desc->arch = arch;
 }
 
+/* See arch/tdesc.h.  */
+
+void
+set_tdesc_osabi (struct target_desc *target_desc, const char *name)
+{
+  set_tdesc_osabi (target_desc, osabi_from_tdesc_string (name));
+}
+
 void
 set_tdesc_osabi (struct target_desc *target_desc, enum gdb_osabi osabi)
 {
@@ -1732,19 +1856,19 @@ static struct cmd_list_element *tdesc_unset_cmdlist;
 /* Helper functions for the CLI commands.  */
 
 static void
-set_tdesc_cmd (char *args, int from_tty)
+set_tdesc_cmd (const char *args, int from_tty)
 {
   help_list (tdesc_set_cmdlist, "set tdesc ", all_commands, gdb_stdout);
 }
 
 static void
-show_tdesc_cmd (char *args, int from_tty)
+show_tdesc_cmd (const char *args, int from_tty)
 {
   cmd_show_list (tdesc_show_cmdlist, from_tty, "");
 }
 
 static void
-unset_tdesc_cmd (char *args, int from_tty)
+unset_tdesc_cmd (const char *args, int from_tty)
 {
   help_list (tdesc_unset_cmdlist, "unset tdesc ", all_commands, gdb_stdout);
 }
@@ -1776,7 +1900,7 @@ show_tdesc_filename_cmd (struct ui_file *file, int from_tty,
 }
 
 static void
-unset_tdesc_filename_cmd (char *args, int from_tty)
+unset_tdesc_filename_cmd (const char *args, int from_tty)
 {
   xfree (target_description_filename);
   target_description_filename = NULL;
@@ -2069,7 +2193,7 @@ public:
     printf_unfiltered ("  Original: %s */\n\n",
                       lbasename (m_filename_after_features.c_str ()));
 
-    printf_unfiltered ("#include \"target-descriptions.h\"\n");
+    printf_unfiltered ("#include \"arch/tdesc.h\"\n");
     printf_unfiltered ("\n");
   }
 
@@ -2092,8 +2216,10 @@ public:
 
     printf_unfiltered ("{\n");
     printf_unfiltered ("  struct tdesc_feature *feature;\n");
-    printf_unfiltered ("\n  feature = tdesc_create_feature (result, \"%s\");\n",
-                      e->name);
+
+    printf_unfiltered
+      ("\n  feature = tdesc_create_feature (result, \"%s\", \"%s\");\n",
+       e->name, lbasename (m_filename_after_features.c_str ()));
   }
 
   void visit_post (const tdesc_feature *e) override
@@ -2163,7 +2289,7 @@ private:
 };
 
 static void
-maint_print_c_tdesc_cmd (char *args, int from_tty)
+maint_print_c_tdesc_cmd (const char *args, int from_tty)
 {
   const struct target_desc *tdesc;
   const char *filename;
@@ -2199,7 +2325,9 @@ maint_print_c_tdesc_cmd (char *args, int from_tty)
   /* Print c files for target features instead of target descriptions,
      because c files got from target features are more flexible than the
      counterparts.  */
-  if (startswith (filename_after_features.c_str (), "i386/32bit-"))
+  if (startswith (filename_after_features.c_str (), "i386/32bit-")
+      || startswith (filename_after_features.c_str (), "i386/64bit-")
+      || startswith (filename_after_features.c_str (), "i386/x32-core.xml"))
     {
       print_c_feature v (filename_after_features);
 
@@ -2213,8 +2341,49 @@ maint_print_c_tdesc_cmd (char *args, int from_tty)
     }
 }
 
-/* Provide a prototype to silence -Wmissing-prototypes.  */
-extern initialize_file_ftype _initialize_target_descriptions;
+namespace selftests {
+
+static std::vector<std::pair<const char*, const target_desc *>> xml_tdesc;
+
+#if GDB_SELF_TEST
+
+/* See target-descritpions.h.  */
+
+void
+record_xml_tdesc (const char *xml_file, const struct target_desc *tdesc)
+{
+  xml_tdesc.emplace_back (xml_file, tdesc);
+}
+#endif
+
+}
+
+/* Check that the target descriptions created dynamically by
+   architecture-specific code equal the descriptions created from XML files
+   found in the specified directory DIR.  */
+
+static void
+maintenance_check_xml_descriptions (const char *dir, int from_tty)
+{
+  if (dir == NULL)
+    error (_("Missing dir name"));
+
+  gdb::unique_xmalloc_ptr<char> dir1 (tilde_expand (dir));
+  std::string feature_dir (dir1.get ());
+  unsigned int failed = 0;
+
+  for (auto const &e : selftests::xml_tdesc)
+    {
+      std::string tdesc_xml = (feature_dir + SLASH_STRING + e.first);
+      const target_desc *tdesc
+       = file_read_description_xml (tdesc_xml.data ());
+
+      if (tdesc == NULL || *tdesc != *e.second)
+       failed++;
+    }
+  printf_filtered (_("Tested %lu XML files, %d failed\n"),
+                  (long) selftests::xml_tdesc.size (), failed);
+}
 
 void
 _initialize_target_descriptions (void)
@@ -2253,4 +2422,14 @@ GDB will read the description from the target."),
   add_cmd ("c-tdesc", class_maintenance, maint_print_c_tdesc_cmd, _("\
 Print the current target description as a C source file."),
           &maintenanceprintlist);
+
+  cmd_list_element *cmd;
+
+  cmd = add_cmd ("xml-descriptions", class_maintenance,
+                maintenance_check_xml_descriptions, _("\
+Check the target descriptions created in GDB equal the descriptions\n\
+created from XML files in the directory.\n\
+The parameter is the directory name."),
+                &maintenancechecklist);
+  set_cmd_completer (cmd, filename_completer);
 }
This page took 0.029197 seconds and 4 git commands to generate.