/* Target description support for GDB.
- Copyright (C) 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+ Copyright (C) 2006-2017 Free Software Foundation, Inc.
Contributed by CodeSourcery.
#include "xml-tdesc.h"
#include "osabi.h"
-#include "gdb_assert.h"
#include "gdb_obstack.h"
#include "hashtab.h"
+#include "inferior.h"
/* Types. */
{
char *name;
struct tdesc_type *type;
+ /* For non-enum-values, either both are -1 (non-bitfield), or both are
+ not -1 (bitfield). For enum values, start is the value (which could be
+ -1), end is -1. */
int start, end;
} tdesc_type_field;
DEF_VEC_O(tdesc_type_field);
-typedef struct tdesc_type_flag
-{
- char *name;
- int start;
-} tdesc_type_flag;
-DEF_VEC_O(tdesc_type_flag);
+enum tdesc_type_kind
+{
+ /* Predefined types. */
+ TDESC_TYPE_BOOL,
+ TDESC_TYPE_INT8,
+ TDESC_TYPE_INT16,
+ TDESC_TYPE_INT32,
+ TDESC_TYPE_INT64,
+ TDESC_TYPE_INT128,
+ TDESC_TYPE_UINT8,
+ TDESC_TYPE_UINT16,
+ TDESC_TYPE_UINT32,
+ TDESC_TYPE_UINT64,
+ TDESC_TYPE_UINT128,
+ TDESC_TYPE_CODE_PTR,
+ TDESC_TYPE_DATA_PTR,
+ TDESC_TYPE_IEEE_SINGLE,
+ TDESC_TYPE_IEEE_DOUBLE,
+ TDESC_TYPE_ARM_FPA_EXT,
+ TDESC_TYPE_I387_EXT,
+
+ /* Types defined by a target feature. */
+ TDESC_TYPE_VECTOR,
+ TDESC_TYPE_STRUCT,
+ TDESC_TYPE_UNION,
+ TDESC_TYPE_FLAGS,
+ TDESC_TYPE_ENUM
+};
typedef struct tdesc_type
{
char *name;
/* Identify the kind of this type. */
- enum
- {
- /* Predefined types. */
- TDESC_TYPE_INT8,
- TDESC_TYPE_INT16,
- TDESC_TYPE_INT32,
- TDESC_TYPE_INT64,
- TDESC_TYPE_INT128,
- TDESC_TYPE_UINT8,
- TDESC_TYPE_UINT16,
- TDESC_TYPE_UINT32,
- TDESC_TYPE_UINT64,
- TDESC_TYPE_UINT128,
- TDESC_TYPE_CODE_PTR,
- TDESC_TYPE_DATA_PTR,
- TDESC_TYPE_IEEE_SINGLE,
- TDESC_TYPE_IEEE_DOUBLE,
- TDESC_TYPE_ARM_FPA_EXT,
- TDESC_TYPE_I387_EXT,
-
- /* Types defined by a target feature. */
- TDESC_TYPE_VECTOR,
- TDESC_TYPE_STRUCT,
- TDESC_TYPE_UNION,
- TDESC_TYPE_FLAGS
- } kind;
+ enum tdesc_type_kind kind;
/* Kind-specific data. */
union
int count;
} v;
- /* Struct or union type. */
+ /* Struct, union, flags, or enum type. */
struct
{
VEC(tdesc_type_field) *fields;
- LONGEST size;
+ int size;
} u;
-
- /* Flags type. */
- struct
- {
- VEC(tdesc_type_flag) *flags;
- LONGEST size;
- } f;
} u;
} *tdesc_type_p;
DEF_VEC_P(tdesc_type_p);
gdbarch_register_reggroup_p_ftype *pseudo_register_reggroup_p;
};
-/* Global state. These variables are associated with the current
- target; if GDB adds support for multiple simultaneous targets, then
- these variables should become target-specific data. */
+/* Info about an inferior's target description. There's one of these
+ for each inferior. */
-/* A flag indicating that a description has already been fetched from
- the current target, so it should not be queried again. */
+struct target_desc_info
+{
+ /* A flag indicating that a description has already been fetched
+ from the target, so it should not be queried again. */
-static int target_desc_fetched;
+ int fetched;
-/* The description fetched from the current target, or NULL if the
- current target did not supply any description. Only valid when
- target_desc_fetched is set. Only the description initialization
- code should access this; normally, the description should be
- accessed through the gdbarch object. */
+ /* The description fetched from the target, or NULL if the target
+ did not supply any description. Only valid when
+ target_desc_fetched is set. Only the description initialization
+ code should access this; normally, the description should be
+ accessed through the gdbarch object. */
-static const struct target_desc *current_target_desc;
+ const struct target_desc *tdesc;
+
+ /* The filename to read a target description from, as set by "set
+ tdesc filename ..." */
-/* Other global variables. */
+ char *filename;
+};
-/* The filename to read a target description from. */
+/* Get the inferior INF's target description info, allocating one on
+ the stop if necessary. */
-static char *target_description_filename;
+static struct target_desc_info *
+get_tdesc_info (struct inferior *inf)
+{
+ if (inf->tdesc_info == NULL)
+ inf->tdesc_info = XCNEW (struct target_desc_info);
+ return inf->tdesc_info;
+}
/* A handle for architecture-specific data associated with the
target description (see struct tdesc_arch_data). */
static struct gdbarch_data *tdesc_data;
+/* See target-descriptions.h. */
+
+int
+target_desc_info_from_user_p (struct target_desc_info *info)
+{
+ return info != NULL && info->filename != NULL;
+}
+
+/* See target-descriptions.h. */
+
+void
+copy_inferior_target_desc_info (struct inferior *destinf, struct inferior *srcinf)
+{
+ struct target_desc_info *src = get_tdesc_info (srcinf);
+ struct target_desc_info *dest = get_tdesc_info (destinf);
+
+ dest->fetched = src->fetched;
+ dest->tdesc = src->tdesc;
+ dest->filename = src->filename != NULL ? xstrdup (src->filename) : NULL;
+}
+
+/* See target-descriptions.h. */
+
+void
+target_desc_info_free (struct target_desc_info *tdesc_info)
+{
+ if (tdesc_info != NULL)
+ {
+ xfree (tdesc_info->filename);
+ xfree (tdesc_info);
+ }
+}
+
+/* Convenience helper macros. */
+
+#define target_desc_fetched \
+ get_tdesc_info (current_inferior ())->fetched
+#define current_target_desc \
+ get_tdesc_info (current_inferior ())->tdesc
+#define target_description_filename \
+ get_tdesc_info (current_inferior ())->filename
+
+/* The string manipulated by the "set tdesc filename ..." command. */
+
+static char *tdesc_filename_cmd_string;
+
/* Fetch the current target's description, and switch the current
architecture to one which incorporates that description. */
/* The current architecture should not have any target description
specified. It should have been cleared, e.g. when we
disconnected from the previous target. */
- gdb_assert (gdbarch_target_desc (target_gdbarch) == NULL);
+ gdb_assert (gdbarch_target_desc (target_gdbarch ()) == NULL);
/* First try to fetch an XML description from the user-specified
file. */
{
struct tdesc_arch_data *data;
- data = gdbarch_data (target_gdbarch, tdesc_data);
+ data = ((struct tdesc_arch_data *)
+ gdbarch_data (target_gdbarch (), tdesc_data));
if (tdesc_has_registers (current_target_desc)
&& data->arch_regs == NULL)
warning (_("Target-supplied registers are not supported "
/* Predefined types. */
static struct tdesc_type tdesc_predefined_types[] =
{
+ { "bool", TDESC_TYPE_BOOL },
{ "int8", TDESC_TYPE_INT8 },
{ "int16", TDESC_TYPE_INT16 },
{ "int32", TDESC_TYPE_INT32 },
{ "i387_ext", TDESC_TYPE_I387_EXT }
};
+/* Lookup a predefined type. */
+
+static struct tdesc_type *
+tdesc_predefined_type (enum tdesc_type_kind kind)
+{
+ int ix;
+ struct tdesc_type *type;
+
+ for (ix = 0; ix < ARRAY_SIZE (tdesc_predefined_types); ix++)
+ if (tdesc_predefined_types[ix].kind == kind)
+ return &tdesc_predefined_types[ix];
+
+ gdb_assert_not_reached ("bad predefined tdesc type");
+}
+
/* Return the type associated with ID in the context of FEATURE, or
NULL if none. */
struct tdesc_arch_data *data;
int i, num_regs;
- data = gdbarch_data (gdbarch, tdesc_data);
+ data = (struct tdesc_arch_data *) gdbarch_data (gdbarch, tdesc_data);
num_regs = VEC_length (tdesc_arch_reg, data->arch_regs);
for (i = 0; i < num_regs; i++)
{
switch (tdesc_type->kind)
{
/* Predefined types. */
+ case TDESC_TYPE_BOOL:
+ return builtin_type (gdbarch)->builtin_bool;
+
case TDESC_TYPE_INT8:
return builtin_type (gdbarch)->builtin_int8;
VEC_iterate (tdesc_type_field, tdesc_type->u.u.fields, ix, f);
ix++)
{
- if (f->type == NULL)
+ if (f->start != -1 && f->end != -1)
{
/* Bitfield. */
struct field *fld;
struct type *field_type;
int bitsize, total_size;
- /* This invariant should be preserved while creating
- types. */
+ /* This invariant should be preserved while creating types. */
gdb_assert (tdesc_type->u.u.size != 0);
- if (tdesc_type->u.u.size > 4)
+ if (f->type != NULL)
+ field_type = tdesc_gdb_type (gdbarch, f->type);
+ else if (tdesc_type->u.u.size > 4)
field_type = builtin_type (gdbarch)->builtin_uint64;
else
field_type = builtin_type (gdbarch)->builtin_uint32;
bitsize = f->end - f->start + 1;
total_size = tdesc_type->u.u.size * TARGET_CHAR_BIT;
if (gdbarch_bits_big_endian (gdbarch))
- FIELD_BITPOS (fld[0]) = total_size - f->start - bitsize;
+ SET_FIELD_BITPOS (fld[0], total_size - f->start - bitsize);
else
- FIELD_BITPOS (fld[0]) = f->start;
+ SET_FIELD_BITPOS (fld[0], f->start);
FIELD_BITSIZE (fld[0]) = bitsize;
}
else
{
+ gdb_assert (f->start == -1 && f->end == -1);
field_type = tdesc_gdb_type (gdbarch, f->type);
append_composite_type_field (type, xstrdup (f->name),
field_type);
case TDESC_TYPE_FLAGS:
{
- struct tdesc_type_flag *f;
+ struct tdesc_type_field *f;
+ int ix;
+
+ type = arch_flags_type (gdbarch, tdesc_type->name,
+ tdesc_type->u.u.size);
+ for (ix = 0;
+ VEC_iterate (tdesc_type_field, tdesc_type->u.u.fields, ix, f);
+ ix++)
+ {
+ struct type *field_type;
+ int bitsize = f->end - f->start + 1;
+
+ gdb_assert (f->type != NULL);
+ field_type = tdesc_gdb_type (gdbarch, f->type);
+ append_flags_type_field (type, f->start, bitsize,
+ field_type, f->name);
+ }
+
+ return type;
+ }
+
+ case TDESC_TYPE_ENUM:
+ {
+ struct tdesc_type_field *f;
int ix;
- type = arch_flags_type (gdbarch, xstrdup (tdesc_type->name),
- tdesc_type->u.f.size);
+ type = arch_type (gdbarch, TYPE_CODE_ENUM,
+ tdesc_type->u.u.size, tdesc_type->name);
+ TYPE_UNSIGNED (type) = 1;
for (ix = 0;
- VEC_iterate (tdesc_type_flag, tdesc_type->u.f.flags, ix, f);
+ VEC_iterate (tdesc_type_field, tdesc_type->u.u.fields, ix, f);
ix++)
- /* Note that contrary to the function name, this call will
- just set the properties of an already-allocated
- field. */
- append_flags_type_flag (type, f->start,
- *f->name ? f->name : NULL);
+ {
+ struct field *fld
+ = append_composite_type_field_raw (type, xstrdup (f->name),
+ NULL);
+
+ SET_FIELD_BITPOS (fld[0], f->start);
+ }
return type;
}
struct tdesc_arch_data *
tdesc_data_alloc (void)
{
- return XZALLOC (struct tdesc_arch_data);
+ return XCNEW (struct tdesc_arch_data);
}
/* Free something allocated by tdesc_data_alloc, if it is not going
void
tdesc_data_cleanup (void *data_untyped)
{
- struct tdesc_arch_data *data = data_untyped;
+ struct tdesc_arch_data *data = (struct tdesc_arch_data *) data_untyped;
VEC_free (tdesc_arch_reg, data->arch_regs);
xfree (data);
{
struct tdesc_arch_data *data;
- data = gdbarch_data (gdbarch, tdesc_data);
+ data = (struct tdesc_arch_data *) gdbarch_data (gdbarch, tdesc_data);
if (regno < VEC_length (tdesc_arch_reg, data->arch_regs))
return VEC_index (tdesc_arch_reg, data->arch_regs, regno);
else
if (regno >= num_regs && regno < num_regs + num_pseudo_regs)
{
- struct tdesc_arch_data *data = gdbarch_data (gdbarch, tdesc_data);
+ struct tdesc_arch_data *data
+ = (struct tdesc_arch_data *) gdbarch_data (gdbarch, tdesc_data);
gdb_assert (data->pseudo_register_name != NULL);
return data->pseudo_register_name (gdbarch, regno);
if (reg == NULL && regno >= num_regs && regno < num_regs + num_pseudo_regs)
{
- struct tdesc_arch_data *data = gdbarch_data (gdbarch, tdesc_data);
+ struct tdesc_arch_data *data
+ = (struct tdesc_arch_data *) gdbarch_data (gdbarch, tdesc_data);
gdb_assert (data->pseudo_register_type != NULL);
return data->pseudo_register_type (gdbarch, regno);
else if (reg->bitsize == gdbarch_long_long_bit (gdbarch))
arch_reg->type = builtin_type (gdbarch)->builtin_long_long;
else if (reg->bitsize == gdbarch_ptr_bit (gdbarch))
- /* A bit desperate by this point... */
+ /* A bit desperate by this point... */
arch_reg->type = builtin_type (gdbarch)->builtin_data_ptr;
else
{
if (regno >= num_regs && regno < num_regs + num_pseudo_regs)
{
- struct tdesc_arch_data *data = gdbarch_data (gdbarch, tdesc_data);
+ struct tdesc_arch_data *data
+ = (struct tdesc_arch_data *) gdbarch_data (gdbarch, tdesc_data);
if (data->pseudo_register_reggroup_p != NULL)
return data->pseudo_register_reggroup_p (gdbarch, regno, reggroup);
set_tdesc_pseudo_register_name (struct gdbarch *gdbarch,
gdbarch_register_name_ftype *pseudo_name)
{
- struct tdesc_arch_data *data = gdbarch_data (gdbarch, tdesc_data);
+ struct tdesc_arch_data *data
+ = (struct tdesc_arch_data *) gdbarch_data (gdbarch, tdesc_data);
data->pseudo_register_name = pseudo_name;
}
set_tdesc_pseudo_register_type (struct gdbarch *gdbarch,
gdbarch_register_type_ftype *pseudo_type)
{
- struct tdesc_arch_data *data = gdbarch_data (gdbarch, tdesc_data);
+ struct tdesc_arch_data *data
+ = (struct tdesc_arch_data *) gdbarch_data (gdbarch, tdesc_data);
data->pseudo_register_type = pseudo_type;
}
(struct gdbarch *gdbarch,
gdbarch_register_reggroup_p_ftype *pseudo_reggroup_p)
{
- struct tdesc_arch_data *data = gdbarch_data (gdbarch, tdesc_data);
+ struct tdesc_arch_data *data
+ = (struct tdesc_arch_data *) gdbarch_data (gdbarch, tdesc_data);
data->pseudo_register_reggroup_p = pseudo_reggroup_p;
}
included. */
gdb_assert (tdesc_has_registers (target_desc));
- data = gdbarch_data (gdbarch, tdesc_data);
+ data = (struct tdesc_arch_data *) gdbarch_data (gdbarch, tdesc_data);
data->arch_regs = early_data->arch_regs;
xfree (early_data);
int regnum, int save_restore, const char *group,
int bitsize, const char *type)
{
- struct tdesc_reg *reg = XZALLOC (struct tdesc_reg);
+ struct tdesc_reg *reg = XCNEW (struct tdesc_reg);
reg->name = xstrdup (name);
reg->target_regnum = regnum;
VEC_safe_push (tdesc_reg_p, feature->registers, reg);
}
+/* Subroutine of tdesc_free_feature to simplify it.
+ Note: We do not want to free any referenced types here (e.g., types of
+ fields of a struct). All types of a feature are recorded in
+ feature->types and are freed that way. */
+
static void
tdesc_free_type (struct tdesc_type *type)
{
{
case TDESC_TYPE_STRUCT:
case TDESC_TYPE_UNION:
+ case TDESC_TYPE_FLAGS:
+ case TDESC_TYPE_ENUM:
{
struct tdesc_type_field *f;
int ix;
}
break;
- case TDESC_TYPE_FLAGS:
- {
- struct tdesc_type_flag *f;
- int ix;
-
- for (ix = 0;
- VEC_iterate (tdesc_type_flag, type->u.f.flags, ix, f);
- ix++)
- xfree (f->name);
-
- VEC_free (tdesc_type_flag, type->u.f.flags);
- }
- break;
-
default:
break;
}
tdesc_create_vector (struct tdesc_feature *feature, const char *name,
struct tdesc_type *field_type, int count)
{
- struct tdesc_type *type = XZALLOC (struct tdesc_type);
+ struct tdesc_type *type = XCNEW (struct tdesc_type);
type->name = xstrdup (name);
type->kind = TDESC_TYPE_VECTOR;
struct tdesc_type *
tdesc_create_struct (struct tdesc_feature *feature, const char *name)
{
- struct tdesc_type *type = XZALLOC (struct tdesc_type);
+ struct tdesc_type *type = XCNEW (struct tdesc_type);
type->name = xstrdup (name);
type->kind = TDESC_TYPE_STRUCT;
suffice. */
void
-tdesc_set_struct_size (struct tdesc_type *type, LONGEST size)
+tdesc_set_struct_size (struct tdesc_type *type, int size)
{
gdb_assert (type->kind == TDESC_TYPE_STRUCT);
+ gdb_assert (size > 0);
type->u.u.size = size;
}
struct tdesc_type *
tdesc_create_union (struct tdesc_feature *feature, const char *name)
{
- struct tdesc_type *type = XZALLOC (struct tdesc_type);
+ struct tdesc_type *type = XCNEW (struct tdesc_type);
type->name = xstrdup (name);
type->kind = TDESC_TYPE_UNION;
struct tdesc_type *
tdesc_create_flags (struct tdesc_feature *feature, const char *name,
- LONGEST size)
+ int size)
{
- struct tdesc_type *type = XZALLOC (struct tdesc_type);
+ struct tdesc_type *type = XCNEW (struct tdesc_type);
+
+ gdb_assert (size > 0);
type->name = xstrdup (name);
type->kind = TDESC_TYPE_FLAGS;
- type->u.f.size = size;
+ type->u.u.size = size;
+
+ VEC_safe_push (tdesc_type_p, feature->types, type);
+ return type;
+}
+
+struct tdesc_type *
+tdesc_create_enum (struct tdesc_feature *feature, const char *name,
+ int size)
+{
+ struct tdesc_type *type = XCNEW (struct tdesc_type);
+
+ gdb_assert (size > 0);
+
+ type->name = xstrdup (name);
+ type->kind = TDESC_TYPE_ENUM;
+ type->u.u.size = size;
VEC_safe_push (tdesc_type_p, feature->types, type);
return type;
}
-/* Add a new field. Return a temporary pointer to the field, which
- is only valid until the next call to tdesc_add_field (the vector
- might be reallocated). */
+/* Add a new field to TYPE. */
void
tdesc_add_field (struct tdesc_type *type, const char *field_name,
f.name = xstrdup (field_name);
f.type = field_type;
+ /* Initialize these values so we know this is not a bit-field
+ when we print-c-tdesc. */
+ f.start = -1;
+ f.end = -1;
VEC_safe_push (tdesc_type_field, type->u.u.fields, &f);
}
-/* Add a new bitfield. */
+/* Add a new typed bitfield to TYPE. */
void
-tdesc_add_bitfield (struct tdesc_type *type, const char *field_name,
- int start, int end)
+tdesc_add_typed_bitfield (struct tdesc_type *type, const char *field_name,
+ int start, int end, struct tdesc_type *field_type)
{
struct tdesc_type_field f = { 0 };
- gdb_assert (type->kind == TDESC_TYPE_STRUCT);
+ gdb_assert (type->kind == TDESC_TYPE_STRUCT
+ || type->kind == TDESC_TYPE_FLAGS);
+ gdb_assert (start >= 0 && end >= start);
f.name = xstrdup (field_name);
f.start = start;
f.end = end;
+ f.type = field_type;
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. */
+
+void
+tdesc_add_bitfield (struct tdesc_type *type, const char *field_name,
+ int start, int end)
+{
+ struct tdesc_type *field_type;
+
+ gdb_assert (start >= 0 && end >= start);
+
+ if (type->u.u.size > 4)
+ field_type = tdesc_predefined_type (TDESC_TYPE_UINT64);
+ else
+ field_type = tdesc_predefined_type (TDESC_TYPE_UINT32);
+
+ 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. */
+
void
tdesc_add_flag (struct tdesc_type *type, int start,
const char *flag_name)
{
- struct tdesc_type_flag f = { 0 };
+ struct tdesc_type_field f = { 0 };
- gdb_assert (type->kind == TDESC_TYPE_FLAGS);
+ gdb_assert (type->kind == TDESC_TYPE_FLAGS
+ || type->kind == TDESC_TYPE_STRUCT);
f.name = xstrdup (flag_name);
f.start = start;
+ f.end = start;
+ f.type = tdesc_predefined_type (TDESC_TYPE_BOOL);
+
+ VEC_safe_push (tdesc_type_field, type->u.u.fields, &f);
+}
+
+void
+tdesc_add_enum_value (struct tdesc_type *type, int value,
+ const char *name)
+{
+ struct tdesc_type_field f = { 0 };
+
+ gdb_assert (type->kind == TDESC_TYPE_ENUM);
- VEC_safe_push (tdesc_type_flag, type->u.f.flags, &f);
+ f.name = xstrdup (name);
+ f.start = value;
+ f.end = -1;
+ f.type = tdesc_predefined_type (TDESC_TYPE_INT32);
+
+ VEC_safe_push (tdesc_type_field, type->u.u.fields, &f);
}
static void
struct tdesc_feature *
tdesc_create_feature (struct target_desc *tdesc, const char *name)
{
- struct tdesc_feature *new_feature = XZALLOC (struct tdesc_feature);
+ struct tdesc_feature *new_feature = XCNEW (struct tdesc_feature);
new_feature->name = xstrdup (name);
struct target_desc *
allocate_target_description (void)
{
- return XZALLOC (struct target_desc);
+ return XCNEW (struct target_desc);
}
static void
free_target_description (void *arg)
{
- struct target_desc *target_desc = arg;
+ struct target_desc *target_desc = (struct target_desc *) arg;
struct tdesc_feature *feature;
struct property *prop;
int ix;
static void
set_tdesc_cmd (char *args, int from_tty)
{
- help_list (tdesc_set_cmdlist, "set tdesc ", -1, gdb_stdout);
+ help_list (tdesc_set_cmdlist, "set tdesc ", all_commands, gdb_stdout);
}
static void
static void
unset_tdesc_cmd (char *args, int from_tty)
{
- help_list (tdesc_unset_cmdlist, "unset tdesc ", -1, gdb_stdout);
+ help_list (tdesc_unset_cmdlist, "unset tdesc ", all_commands, gdb_stdout);
}
static void
set_tdesc_filename_cmd (char *args, int from_tty,
struct cmd_list_element *c)
{
+ xfree (target_description_filename);
+ target_description_filename = xstrdup (tdesc_filename_cmd_string);
+
target_clear_description ();
target_find_description ();
}
struct cmd_list_element *c,
const char *value)
{
+ value = target_description_filename;
+
if (value != NULL && *value != '\0')
- printf_filtered (_("\
-The target description will be read from \"%s\".\n"),
+ printf_filtered (_("The target description will be read from \"%s\".\n"),
value);
else
- printf_filtered (_("\
-The target description will be read from the target.\n"));
+ printf_filtered (_("The target description will be "
+ "read from the target.\n"));
}
static void
struct tdesc_reg *reg;
struct tdesc_type *type;
struct tdesc_type_field *f;
- struct tdesc_type_flag *flag;
int ix, ix2, ix3;
+ int printed_field_type = 0;
/* Use the global target-supplied description, not the current
architecture's. This lets a GDB for one architecture generate C
error (_("The current target description did not come from an XML file."));
filename = lbasename (target_description_filename);
- function = alloca (strlen (filename) + 1);
+ function = (char *) alloca (strlen (filename) + 1);
for (inp = filename, outp = function; *inp != '\0'; inp++)
if (*inp == '.')
break;
*outp = '\0';
/* Standard boilerplate. */
- printf_unfiltered ("/* THIS FILE IS GENERATED. Original: %s */\n\n",
- filename);
+ printf_unfiltered ("/* THIS FILE IS GENERATED. "
+ "-*- buffer-read-only: t -*- vi"
+ ":set ro:\n");
+ printf_unfiltered (" Original: %s */\n\n", filename);
printf_unfiltered ("#include \"defs.h\"\n");
printf_unfiltered ("#include \"osabi.h\"\n");
printf_unfiltered ("#include \"target-descriptions.h\"\n");
printf_unfiltered
(" struct target_desc *result = allocate_target_description ();\n");
printf_unfiltered (" struct tdesc_feature *feature;\n");
- printf_unfiltered (" struct tdesc_type *field_type, *type;\n");
+
+ /* Now we do some "filtering" in order to know which variables to
+ declare. This is needed because otherwise we would declare unused
+ variables `field_type' and `type'. */
+ for (ix = 0;
+ VEC_iterate (tdesc_feature_p, tdesc->features, ix, feature);
+ ix++)
+ {
+ int printed_desc_type = 0;
+
+ for (ix2 = 0;
+ VEC_iterate (tdesc_type_p, feature->types, ix2, type);
+ ix2++)
+ {
+ if (!printed_field_type)
+ {
+ printf_unfiltered (" struct tdesc_type *field_type;\n");
+ printed_field_type = 1;
+ }
+
+ if ((type->kind == TDESC_TYPE_UNION
+ || type->kind == TDESC_TYPE_STRUCT
+ || type->kind == TDESC_TYPE_FLAGS
+ || type->kind == TDESC_TYPE_ENUM)
+ && VEC_length (tdesc_type_field, type->u.u.fields) > 0)
+ {
+ printf_unfiltered (" struct tdesc_type *type;\n");
+ printed_desc_type = 1;
+ break;
+ }
+ }
+
+ if (printed_desc_type)
+ break;
+ }
+
printf_unfiltered ("\n");
if (tdesc_architecture (tdesc) != NULL)
VEC_iterate (tdesc_feature_p, tdesc->features, ix, feature);
ix++)
{
- printf_unfiltered (" feature = tdesc_create_feature (result, \"%s\");\n",
+ printf_unfiltered (" \
+feature = tdesc_create_feature (result, \"%s\");\n",
feature->name);
for (ix2 = 0;
(" tdesc_create_vector (feature, \"%s\", field_type, %d);\n",
type->name, type->u.v.count);
break;
+ case TDESC_TYPE_STRUCT:
+ case TDESC_TYPE_FLAGS:
+ if (type->kind == TDESC_TYPE_STRUCT)
+ {
+ printf_unfiltered
+ (" type = tdesc_create_struct (feature, \"%s\");\n",
+ type->name);
+ if (type->u.u.size != 0)
+ printf_unfiltered
+ (" tdesc_set_struct_size (type, %d);\n",
+ type->u.u.size);
+ }
+ else
+ {
+ printf_unfiltered
+ (" type = tdesc_create_flags (feature, \"%s\", %d);\n",
+ type->name, type->u.u.size);
+ }
+ for (ix3 = 0;
+ VEC_iterate (tdesc_type_field, type->u.u.fields, ix3, f);
+ ix3++)
+ {
+ const char *type_name;
+
+ gdb_assert (f->type != NULL);
+ type_name = f->type->name;
+
+ /* To minimize changes to generated files, don't emit type
+ info for fields that have defaulted types. */
+ if (f->start != -1)
+ {
+ gdb_assert (f->end != -1);
+ if (f->type->kind == TDESC_TYPE_BOOL)
+ {
+ gdb_assert (f->start == f->end);
+ printf_unfiltered
+ (" tdesc_add_flag (type, %d, \"%s\");\n",
+ f->start, f->name);
+ }
+ else if ((type->u.u.size == 4
+ && f->type->kind == TDESC_TYPE_UINT32)
+ || (type->u.u.size == 8
+ && f->type->kind == TDESC_TYPE_UINT64))
+ {
+ printf_unfiltered
+ (" tdesc_add_bitfield (type, \"%s\", %d, %d);\n",
+ f->name, f->start, f->end);
+ }
+ else
+ {
+ printf_unfiltered
+ (" field_type = tdesc_named_type (feature,"
+ " \"%s\");\n",
+ type_name);
+ printf_unfiltered
+ (" tdesc_add_typed_bitfield (type, \"%s\","
+ " %d, %d, field_type);\n",
+ f->name, f->start, f->end);
+ }
+ }
+ else /* Not a bitfield. */
+ {
+ gdb_assert (f->end == -1);
+ gdb_assert (type->kind == TDESC_TYPE_STRUCT);
+ printf_unfiltered
+ (" field_type = tdesc_named_type (feature,"
+ " \"%s\");\n",
+ type_name);
+ printf_unfiltered
+ (" tdesc_add_field (type, \"%s\", field_type);\n",
+ f->name);
+ }
+ }
+ break;
case TDESC_TYPE_UNION:
printf_unfiltered
(" type = tdesc_create_union (feature, \"%s\");\n",
f->name);
}
break;
- case TDESC_TYPE_FLAGS:
+ case TDESC_TYPE_ENUM:
printf_unfiltered
- (" field_type = tdesc_create_flags (feature, \"%s\", %d);\n",
- type->name, (int) type->u.f.size);
+ (" type = tdesc_create_enum (feature, \"%s\", %d);\n",
+ type->name, type->u.u.size);
for (ix3 = 0;
- VEC_iterate (tdesc_type_flag, type->u.f.flags, ix3,
- flag);
+ VEC_iterate (tdesc_type_field, type->u.u.fields, ix3, f);
ix3++)
printf_unfiltered
- (" tdesc_add_flag (field_type, %d, \"%s\");\n",
- flag->start, flag->name);
+ (" tdesc_add_enum_value (type, %d, \"%s\");\n",
+ f->start, f->name);
break;
default:
error (_("C output is not supported type \"%s\"."), type->name);
0 /* allow-unknown */, &unsetlist);
add_setshow_filename_cmd ("filename", class_obscure,
- &target_description_filename,
+ &tdesc_filename_cmd_string,
_("\
Set the file to read for an XML target description"), _("\
Show the file to read for an XML target description"), _("\