summaryrefslogtreecommitdiff
path: root/gdb/target-descriptions.c
diff options
context:
space:
mode:
authorDaniel Jacobowitz <dan@debian.org>2007-10-15 19:19:18 +0000
committerDaniel Jacobowitz <dan@debian.org>2007-10-15 19:19:18 +0000
commit2c6a29997f7634fc60af72681acdb205d3f47ca9 (patch)
treef18abbc68c16fe1dc8b1d323722dba0c4e95d82d /gdb/target-descriptions.c
parent6bbbc68a14fa51ad1f72aa90831c9d3364efdbd7 (diff)
downloadgdb-2c6a29997f7634fc60af72681acdb205d3f47ca9.tar.gz
* target-descriptions.c (tdesc_predefined_types): New.
(tdesc_named_type): Use it. (tdesc_type_id, maint_print_c_tdesc_cmd): New functions. (_intialize_target_descriptions): Register "maint print c-tdesc". * features/Makefile (XMLTOC, CFILES, GDB): New macros. (cfiles, %.c): New rules. * features/arm-with-iwmmxt.c, features/mips-linux.c, features/mips64-linux.c: New generated files. * arm-linux-nat.c: Include preparsed description instead of "xml-support.h". (super_xfer_partial, arm_linux_xfer_partial): Remove. (arm_linux_read_description): New function. (_initialize_arm_linux_nat): Set to_read_description instead of to_xfer_partial. Initialize preparsed description. * config/arm/linux.mh (TDEP_XML): Delete. * mips-linux-nat.c: Include preparsed descriptions instead of "xml-support.h". (super_xfer_partial, mips_linux_xfer_partial): Remove. (mips_linux_read_description): New function. (_initialize_mips_linux_nat): Set to_read_description instead of to_xfer_partial. Initialize preparsed description. * config/mips/linux.mh (TDEP_XML): Delete. * Makefile.in (XMLFILES): Remove $(TDEP_XML). (features_headers, arm_with_iwmmxt_c, mips_linux_c) (mips64_linux_c): New macros. (arm-linux-nat.o, mips-linux-nat.o): Update. * gdb.texinfo (Maintenance Commands): Document "maint print c-tdesc".
Diffstat (limited to 'gdb/target-descriptions.c')
-rw-r--r--gdb/target-descriptions.c214
1 files changed, 179 insertions, 35 deletions
diff --git a/gdb/target-descriptions.c b/gdb/target-descriptions.c
index 3d530e10547..2f1b82e4c55 100644
--- a/gdb/target-descriptions.c
+++ b/gdb/target-descriptions.c
@@ -339,6 +339,28 @@ tdesc_feature_name (const struct tdesc_feature *feature)
return feature->name;
}
+/* Predefined types. Note that none of these types depend on the
+ current architecture; some of the builtin_type_foo variables are
+ swapped based on the architecture. */
+static struct
+{
+ const char *name;
+ struct type **type;
+} tdesc_predefined_types[] =
+ {
+ { "int8", &builtin_type_int8 },
+ { "int16", &builtin_type_int16 },
+ { "int32", &builtin_type_int32 },
+ { "int64", &builtin_type_int64 },
+ { "uint8", &builtin_type_uint8 },
+ { "uint16", &builtin_type_uint16 },
+ { "uint32", &builtin_type_uint32 },
+ { "uint64", &builtin_type_uint64 },
+ { "ieee_single", &builtin_type_ieee_single },
+ { "ieee_double", &builtin_type_ieee_double },
+ { "arm_fpa_ext", &builtin_type_arm_ext }
+ };
+
/* Return the type associated with ID in the context of FEATURE, or
NULL if none. */
@@ -353,41 +375,10 @@ tdesc_named_type (const struct tdesc_feature *feature, const char *id)
if (strcmp (TYPE_NAME (gdb_type), id) == 0)
return gdb_type;
- /* Next try some predefined types. Note that none of these types
- depend on the current architecture; some of the builtin_type_foo
- variables are swapped based on the architecture. */
- if (strcmp (id, "int8") == 0)
- return builtin_type_int8;
-
- if (strcmp (id, "int16") == 0)
- return builtin_type_int16;
-
- if (strcmp (id, "int32") == 0)
- return builtin_type_int32;
-
- if (strcmp (id, "int64") == 0)
- return builtin_type_int64;
-
- if (strcmp (id, "uint8") == 0)
- return builtin_type_uint8;
-
- if (strcmp (id, "uint16") == 0)
- return builtin_type_uint16;
-
- if (strcmp (id, "uint32") == 0)
- return builtin_type_uint32;
-
- if (strcmp (id, "uint64") == 0)
- return builtin_type_uint64;
-
- if (strcmp (id, "ieee_single") == 0)
- return builtin_type_ieee_single;
-
- if (strcmp (id, "ieee_double") == 0)
- return builtin_type_ieee_double;
-
- if (strcmp (id, "arm_fpa_ext") == 0)
- return builtin_type_arm_ext;
+ /* Next try the predefined types. */
+ for (ix = 0; ix < ARRAY_SIZE (tdesc_predefined_types); ix++)
+ if (strcmp (tdesc_predefined_types[ix].name, id) == 0)
+ return *tdesc_predefined_types[ix].type;
return NULL;
}
@@ -960,6 +951,155 @@ unset_tdesc_filename_cmd (char *args, int from_tty)
target_find_description ();
}
+static const char *
+tdesc_type_id (struct type *type)
+{
+ int ix;
+
+ for (ix = 0; ix < ARRAY_SIZE (tdesc_predefined_types); ix++)
+ if (TYPE_MAIN_TYPE (*tdesc_predefined_types[ix].type)
+ == TYPE_MAIN_TYPE (type))
+ return tdesc_predefined_types[ix].name;
+
+ return TYPE_NAME (type);
+}
+
+static void
+maint_print_c_tdesc_cmd (char *args, int from_tty)
+{
+ const struct target_desc *tdesc;
+ const char *filename, *inp;
+ char *function, *outp;
+ struct property *prop;
+ struct tdesc_feature *feature;
+ struct tdesc_reg *reg;
+ struct type *type;
+ int ix, ix2, ix3;
+
+ /* Use the global target-supplied description, not the current
+ architecture's. This lets a GDB for one architecture generate C
+ for another architecture's description, even though the gdbarch
+ initialization code will reject the new description. */
+ tdesc = current_target_desc;
+ if (tdesc == NULL)
+ error (_("There is no target description to print."));
+
+ if (target_description_filename == NULL)
+ error (_("The current target description did not come from an XML file."));
+
+ filename = lbasename (target_description_filename);
+ function = xmalloc (strlen (filename) + 1);
+ for (inp = filename, outp = function; *inp != '\0'; inp++)
+ if (*inp == '.')
+ break;
+ else if (*inp == '-')
+ *outp++ = '_';
+ else
+ *outp++ = *inp;
+ *outp = '\0';
+
+ /* Standard boilerplate. */
+ printf_unfiltered ("/* THIS FILE IS GENERATED. Original: %s */\n\n",
+ filename);
+ printf_unfiltered ("#include \"defs.h\"\n");
+ printf_unfiltered ("#include \"gdbtypes.h\"\n");
+ printf_unfiltered ("#include \"target-descriptions.h\"\n");
+ printf_unfiltered ("\n");
+
+ printf_unfiltered ("struct target_desc *tdesc_%s;\n", function);
+ printf_unfiltered ("static void\n");
+ printf_unfiltered ("initialize_tdesc_%s (void)\n", function);
+ printf_unfiltered ("{\n");
+ printf_unfiltered
+ (" struct target_desc *result = allocate_target_description ();\n");
+ printf_unfiltered (" struct tdesc_feature *feature;\n");
+ printf_unfiltered (" struct type *field_type, *type;\n");
+ printf_unfiltered ("\n");
+
+ if (tdesc_architecture (tdesc) != NULL)
+ {
+ printf_unfiltered
+ (" set_tdesc_architecture (result, bfd_scan_arch (\"%s\"));\n",
+ tdesc_architecture (tdesc)->printable_name);
+ printf_unfiltered ("\n");
+ }
+
+ for (ix = 0; VEC_iterate (property_s, tdesc->properties, ix, prop);
+ ix++)
+ {
+ printf_unfiltered (" set_tdesc_property (result, \"%s\", \"%s\");\n",
+ prop->key, prop->value);
+ }
+
+ for (ix = 0;
+ VEC_iterate (tdesc_feature_p, tdesc->features, ix, feature);
+ ix++)
+ {
+ printf_unfiltered (" feature = tdesc_create_feature (result, \"%s\");\n",
+ feature->name);
+
+ for (ix2 = 0;
+ VEC_iterate (type_p, feature->types, ix2, type);
+ ix2++)
+ {
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_ARRAY:
+ printf_unfiltered
+ (" field_type = tdesc_named_type (feature, \"%s\");\n",
+ tdesc_type_id (TYPE_TARGET_TYPE (type)));
+ printf_unfiltered
+ (" type = init_vector_type (field_type, %d);\n",
+ TYPE_LENGTH (type) / TYPE_LENGTH (TYPE_TARGET_TYPE (type)));
+ printf_unfiltered
+ (" TYPE_NAME (type) = xstrdup (\"%s\");\n", TYPE_NAME (type));
+ break;
+ case TYPE_CODE_UNION:
+ printf_unfiltered
+ (" type = init_composite_type (NULL, TYPE_CODE_UNION);\n");
+ printf_unfiltered
+ (" TYPE_NAME (type) = xstrdup (\"%s\");\n", TYPE_NAME (type));
+ for (ix3 = 0; ix3 < TYPE_NFIELDS (type); ix3++)
+ {
+ printf_unfiltered
+ (" field_type = tdesc_named_type (feature, \"%s\");\n",
+ tdesc_type_id (TYPE_FIELD_TYPE (type, ix3)));
+ printf_unfiltered
+ (" append_composite_type_field (type, "
+ "xstrdup (\"%s\"), field_type);\n",
+ TYPE_FIELD_NAME (type, ix3));
+ }
+ if (TYPE_VECTOR (type))
+ printf_unfiltered
+ (" TYPE_FLAGS (type) |= TYPE_FLAG_VECTOR;\n");
+ break;
+ default:
+ error (_("C output is not supported type \"%s\"."), TYPE_NAME (type));
+ }
+ printf_unfiltered (" tdesc_record_type (feature, type);\n");
+ printf_unfiltered ("\n");
+ }
+
+ for (ix2 = 0;
+ VEC_iterate (tdesc_reg_p, feature->registers, ix2, reg);
+ ix2++)
+ {
+ printf_unfiltered (" tdesc_create_reg (feature, \"%s\", %ld, %d, ",
+ reg->name, reg->target_regnum, reg->save_restore);
+ if (reg->group)
+ printf_unfiltered ("\"%s\", ", reg->group);
+ else
+ printf_unfiltered ("NULL, ");
+ printf_unfiltered ("%d, \"%s\");\n", reg->bitsize, reg->type);
+ }
+
+ printf_unfiltered ("\n");
+ }
+
+ printf_unfiltered (" tdesc_%s = result;\n", function);
+ printf_unfiltered ("}\n");
+}
+
void
_initialize_target_descriptions (void)
{
@@ -993,4 +1133,8 @@ file instead of querying the remote target."),
Unset the file to read for an XML target description. When unset,\n\
GDB will read the description from the target."),
&tdesc_unset_cmdlist);
+
+ add_cmd ("c-tdesc", class_maintenance, maint_print_c_tdesc_cmd, _("\
+Print the current target description as a C source file."),
+ &maintenanceprintlist);
}