diff options
author | Daniel Jacobowitz <drow@false.org> | 2007-10-15 19:19:18 +0000 |
---|---|---|
committer | Daniel Jacobowitz <drow@false.org> | 2007-10-15 19:19:18 +0000 |
commit | 81adfcedc899da6e7641d2c2d6aad68f60d97735 (patch) | |
tree | e1137ec77293084d14043866ea01c9ad0badf798 /gdb/target-descriptions.c | |
parent | d5d7db8e2faa95d6265cadc66bb0788ee922d9b1 (diff) | |
download | gdb-81adfcedc899da6e7641d2c2d6aad68f60d97735.zip gdb-81adfcedc899da6e7641d2c2d6aad68f60d97735.tar.gz gdb-81adfcedc899da6e7641d2c2d6aad68f60d97735.tar.bz2 |
* 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.c | 214 |
1 files changed, 179 insertions, 35 deletions
diff --git a/gdb/target-descriptions.c b/gdb/target-descriptions.c index 3d530e1..2f1b82e 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); } |