Compare commits

...

10 Commits

Author SHA1 Message Date
Alan Hayward
d50aeadb1c Remove xml files from gdbserver
For ports which use new target descriptions, this patch removes
the xml files from being built into gdbserver,

Alan.

2018-03-21 Alan Hayward  <alan.hayward@arm.com>

gdbserver/
	* configure.srv (aarch64*-*-linux*): Don't include xml.
	(i[34567]86-*-cygwin*): Likewise.
	(i[34567]86-*-linux*): Likewise.
	(i[34567]86-*-lynxos*): Likewise.
	(i[34567]86-*-mingw32ce*): Likewise.
	(i[34567]86-*-mingw*): Likewise.
	(i[34567]86-*-nto*): Likewise.
	(tic6x-*-uclinux): Likewise.
	(x86_64-*-linux*): Likewise.
	(x86_64-*-mingw*): Likewise.
	(x86_64-*-cygwin*): Likewise.
2018-03-21 15:57:17 +00:00
Alan Hayward
423cbc737c Remove xml file references from target descriptions.
We no longer need to know the name of the xml file for targets using the
new target descriptions. This patch removes the references and regenerates
the C files.

This patch is identical to the V3 version.

Alan.

2018-03-21  Alan Hayward  <alan.hayward@arm.com>

gdb/
	* common/tdesc.h (tdesc_create_feature): Remove xml filename parameter.
	* features/aarch64-core.c (create_feature_aarch64_core): Regenerate.
	* features/aarch64-fpu.c (create_feature_aarch64_fpu): Likewise.
	* features/i386/32bit-avx.c (create_feature_i386_32bit_avx): Likewise.
	* features/i386/32bit-avx512.c (create_feature_i386_32bit_avx512):
	Likewise.
	* features/i386/32bit-core.c (create_feature_i386_32bit_core):
	Likewise.
	* features/i386/32bit-linux.c (create_feature_i386_32bit_linux):
	Likewise.
	* features/i386/32bit-mpx.c (create_feature_i386_32bit_mpx): Likewise.
	* features/i386/32bit-pkeys.c (create_feature_i386_32bit_pkeys):
	Likewise.
	* features/i386/32bit-sse.c (create_feature_i386_32bit_sse): Likewise.
	* features/i386/64bit-avx.c (create_feature_i386_64bit_avx): Likewise.
	* features/i386/64bit-avx512.c (create_feature_i386_64bit_avx512):
	Likewise.
	* features/i386/64bit-core.c (create_feature_i386_64bit_core):
	Likewise.
	* features/i386/64bit-linux.c (create_feature_i386_64bit_linux):
	Likewise.
	* features/i386/64bit-mpx.c (create_feature_i386_64bit_mpx): Likewise.
	* features/i386/64bit-pkeys.c (create_feature_i386_64bit_pkeys):
	Likewise.
	* features/i386/64bit-segments.c (create_feature_i386_64bit_segments):
	Likewise.
	* features/i386/64bit-sse.c (create_feature_i386_64bit_sse): Likewise.
	* features/i386/x32-core.c (create_feature_i386_x32_core): Likewise.
	* features/tic6x-c6xp.c (create_feature_tic6x_c6xp): Likewise.
	* features/tic6x-core.c (create_feature_tic6x_core): Likewise.
	* features/tic6x-gp.c (create_feature_tic6x_gp): Likewise.
	* target-descriptions.c: In generated code, don't pass xml filename.

gdbserver/
	* gdbserver/tdesc.c: Remove xml parameter.
2018-03-21 15:57:15 +00:00
Alan Hayward
124b7afa5d Create xml from target descriptions
This patch adds a print_xml_feature visitor class which turns a C
target description into xml. Both gdb and gdbserver can do this.

An accept function is added to gdbserver tdesc to allow it to use
vistor classes.

Tests are added to maintenance_check_xml_descriptions which takes
each pair of tested descriptions, turns them both into xml, then back
again, and confirms the descriptions still match.

Differences from V3 are:

I now use string_appendf to print to the buffer.

regdat.sh ensures tdesc->xmltarget is null for all targets with new
style target descriptions. tdesc_get_features_xml() will only generate
xml if xmltarget is null. This ensures older targets continue to send
just the name of the xml file.

Added a save_restore check when parsing registers.

Alan.

2018-03-21  Alan Hayward  <alan.hayward@arm.com>

gdb/
	* common/tdesc.c (print_xml_feature::visit_post): Add xml parsing.
	(print_xml_feature::visit_pre): Likewise.
	(print_xml_feature::visit_post): Likewise.
	(print_xml_feature::visit): Likewise.
	(print_xml_feature::visit): Likewise.
	(print_xml_feature::visit): Likewise.
	(print_xml_feature::visit): Likewise.
	* common/tdesc.h (print_xml_feature): Add new class.
	* regformats/regdat.sh: Null xmltarget on feature targets.
	* target-descriptions.c (struct target_desc): Add xmltarget.
	(print_xml_feature::visit_pre): Add xml vistor.
	(tdesc_get_features_xml): Add function to get xml.
	(maintenance_check_xml_descriptions): Test xml generation.
	* xml-tdesc.c (target_read_description_xml_string): Add function.
	* xml-tdesc.h (target_read_description_xml_string): Add declaration.

gdbserver/
	* tdesc.c (void target_desc::accept): Fill in function.
	(tdesc_get_features_xml): Remove old xml creation.
	(print_xml_feature::visit_pre): Add xml vistor.
2018-03-21 15:57:13 +00:00
Alan Hayward
26faeefc54 Add feature reference in .dat files
For all targets which use the newer style target descriptions, add a
"feature" marker in the dat files.
Update regdat.sh to parse feature, but do not use it (yet).

In the xml printer patch we want to ensure that only targets which
use the newer style descriptions dynamically generate xml. Other targets
should continue to return the name of the xml file.
The "feature" marker will enable this.

Alan.

2018-03-21  Alan Hayward  <alan.hayward@arm.com>

	* features/Makefile: Add feature marker to targets with new style
	target descriptions.
	* regformats/aarch64.dat: Regenerate.
	* regformats/i386/amd64-avx-avx512-linux.dat: Likewise.
	* regformats/i386/amd64-avx-linux.dat: Likewise.
	* regformats/i386/amd64-avx-mpx-avx512-pku-linux.dat: Likewise.
	* regformats/i386/amd64-avx-mpx-linux.dat: Likewise.
	* regformats/i386/amd64-linux.dat: Likewise.
	* regformats/i386/amd64-mpx-linux.dat: Likewise.
	* regformats/i386/amd64.dat: Likewise.
	* regformats/i386/i386-avx-avx512-linux.dat: Likewise.
	* regformats/i386/i386-avx-linux.dat: Likewise.
	* regformats/i386/i386-avx-mpx-avx512-pku-linux.dat: Likewise.
	* regformats/i386/i386-avx-mpx-linux.dat: Likewise.
	* regformats/i386/i386-linux.dat: Likewise.
	* regformats/i386/i386-mmx-linux.dat: Likewise.
	* regformats/i386/i386-mpx-linux.dat: Likewise.
	* regformats/i386/i386.dat: Likewise.
	* regformats/i386/x32-avx-avx512-linux.dat: Likewise.
	* regformats/i386/x32-avx-linux.dat: Likewise.
	* regformats/i386/x32-linux.dat: Likewise.
	* regformats/tic6x-c62x-linux.dat: Likewise.
	* regformats/tic6x-c64x-linux.dat: Likewise.
	* regformats/tic6x-c64xp-linux.dat: Likewise.
	* regformats/regdat.sh: Parse feature marker.
2018-03-21 15:57:10 +00:00
Alan Hayward
bc21797516 Add tdesc osabi and architecture functions
Add functions to access to printable names for osabi and architecture in
target_desc.

I wanted to add these as member functions of target_desc, but cannot until
target_desc is moved into the header files.

Identical to V3 version.

Alan.

2018-03-21  Alan Hayward  <alan.hayward@arm.com>

gdb/
	* common/tdesc.h (tdesc_architecture_name): Add new declaration.
	(tdesc_osabi_name): Likewise.
	* target-descriptions.c (tdesc_architecture_name): Add new function.
	(tdesc_osabi_name): Likewise.

gdb/gdbserver/
	* tdesc.c (tdesc_architecture_name): Add new function.
	(tdesc_osabi_name): Likewise.
	(tdesc_get_features_xml): Use new functions.
2018-03-21 15:57:08 +00:00
Alan Hayward
ca76ad4fae Commonise tdesc types
This patch moves all the various tdesc types to common code.

It also commonises all the tdesc_ functions that are stubbed
out in gdbserver.

This is a lot of code to move across, but it is the simplest
way of getting gdbserver to retain the target description
information.

With this patch, gdb and gdbserver will now parse a target
description in the same way.

Identical to V3 version.

Alan.

2018-03-21  Alan Hayward  <alan.hayward@arm.com>

gdb/
	* common/tdesc.c (tdesc_predefined_type): Move to here.
	(tdesc_named_type): Likewise.
	(tdesc_create_vector): Likewise.
	(tdesc_create_struct): Likewise.
	(tdesc_set_struct_size): Likewise.
	(tdesc_create_union): Likewise.
	(tdesc_create_flags): Likewise.
	(tdesc_create_enum): Likewise.
	(tdesc_add_field): Likewise.
	(tdesc_add_typed_bitfield): Likewise.
	(tdesc_add_bitfield): Likewise.
	(tdesc_add_flag): Likewise.
	(tdesc_add_enum_value): Likewise.
	* common/tdesc.h (tdesc_type_builtin): Likewise.
	(tdesc_type_vector): Likewise.
	(tdesc_type_field): Likewise.
	(tdesc_type_with_fields): Likewise.
	* target-descriptions.c (tdesc_type_field): Move from here.
	(tdesc_type_builtin): Likewise.
	(tdesc_type_vector): Likewise.
	(tdesc_type_with_fields): Likewise.
	(tdesc_predefined_types): Likewise.
	(tdesc_named_type): Likewise.
	(tdesc_create_vector): Likewise.
	(tdesc_create_struct): Likewise.
	(tdesc_set_struct_size): Likewise.
	(tdesc_create_union): Likewise.
	(tdesc_create_flags): Likewise.
	(tdesc_create_enum): Likewise.
	(tdesc_add_field): Likewise.
	(tdesc_add_typed_bitfield): Likewise.
	(tdesc_add_bitfield): Likewise.
	(tdesc_add_flag): Likewise.
	(tdesc_add_enum_value): Likewise.

gdbserver/
	* tdesc.c (tdesc_create_flags): Remove.
	(tdesc_add_flag): Likewise.
	(tdesc_named_type): Likewise.
	(tdesc_create_union): Likewise.
	(tdesc_create_struct): Likewise.
	(tdesc_create_vector): Likewise.
	(tdesc_add_bitfield): Likewise.
	(tdesc_add_field): Likewise.
	(tdesc_set_struct_size): Likewise.
2018-03-21 15:57:06 +00:00
Alan Hayward
0f29596d1f Commonise tdesc_feature
This patch commonises tdesc_feature and makes use of it in gdbserver tdesc.

Previously in gdbserver, target_desc was interchangeable with tdesc_feature.
Now gdbserver target_desc contains a vector of tdesc_feature.

I am now able to commonise tdesc_create_reg (wanted to do this in the
previous patch).

I also had to commonise tdesc_type. This is ok, because I will need them
in the next patch.

Identical to V3 except for removal of "struct type;" at the top of
common/tdesc.h

Alan.

2018-03-21  Alan Hayward  <alan.hayward@arm.com>

gdb/
	* common/tdesc.c (tdesc_feature::accept): Move to here.
	(tdesc_feature::operator==): Likewise.
	(tdesc_create_reg): Likewise.
	* common/tdesc.h (tdesc_type_kind): Likewise.
	(struct tdesc_type): Likewise.
	(struct tdesc_feature): Likewise.
	* regformats/regdat.sh: Create a feature.
	* target-descriptions.c (tdesc_type_kind): Move from here.
	(tdesc_type): Likewise.
	(tdesc_type_up): Likewise.
	(tdesc_feature): Likewise.
	(tdesc_create_reg): Likewise.

gdbserver/
	* tdesc.c (~target_desc): Remove implictly deleted items.
	(init_target_desc): Iterate all features.
	(tdesc_get_features_xml): Use vector.
	(tdesc_create_feature): Create feature.
	* tdesc.h (tdesc_feature) Remove
	(target_desc): Add features.
2018-03-21 15:57:04 +00:00
Alan Hayward
81a0b69af5 Commonise tdesc_reg
This patch commonises tdesc_reg and makes use of it in gdbserver tdesc.

gdbserver tdesc_create_reg is changed to create a tdesc_reg instead of
a reg_defs entry. The vector of tdesc_reg is held inside tdesc_feature.

However, other modules in gdbserver directly access the reg_defs structure.
To work around this, init_target_desc fills in reg_defs by parsing the
tdesc_reg vector.
The long term goal is to remove reg_defs, replacing with accessor funcs.

I wanted to make tdesc_create_reg common, but I cannot do that until
the next patch.

I also had to commonise tdesc_element_visitor and tdesc_element.

This patch only differs from the V3 version in init_target_desc(),
where I now use reg_def references as introduced in the previous patch.

2018-03-21  Alan Hayward  <alan.hayward@arm.com>

gdb/
	* Makefile.in: Add arch/tdesc.c
	* common/tdesc.c: New file.
	* common/tdesc.h (tdesc_element_visitor): Move to here.
	(tdesc_element): Likewise.
	(tdesc_reg): Likewise.
	(tdesc_reg_up): Likewise.
	* target-descriptions.c: (tdesc_element_visitor): Move from here.
	(tdesc_element): Likewise.
	(tdesc_reg): Likewise.
	(tdesc_reg_up): Likewise.

gdbserver/
	* Makefile.in: Add common/tdesc.c
	* tdesc.c (init_target_desc): init all reg_defs from register vector.
	(tdesc_create_reg): Create tdesc_reg.
	* tdesc.h (tdesc_feature): Add register vector.
2018-03-21 15:57:02 +00:00
Alan Hayward
4bfb01e50e Make gdbserver reg_defs a vector of objects
Following a suggestion from Philipp, this patch changes reg_defs in
gdbserver tdesc so that it is a vector of objects instead of a vector
of pointers. Updated uses of reg_defs to use references.

This change reduces the number of small hunks allocated when building
reg_defs.

find_register_by_number() is only used by regcache, therefore I made
it a static function and moved it earlier in the file so that find_regno()
could use it. The eventual plan is to replace this with accessor functions
in a common tdesc class.

Alan.

2018-03-21  Alan Hayward  <alan.hayward@arm.com>

gdb/gdbserver/
	* regcache.c (find_register_by_number): Make static and return a ref.
	(find_regno): Use find_register_by_number
	(register_size): Use references.
	(register_data): Likewise.
	* regcache.h (struct reg): Remove declaration.
	* tdesc.c (target_desc::~target_desc): Remove free calls.
	(target_desc::operator==): Use references.
	(init_target_desc): Likewise.
	(tdesc_create_reg): Use references and resize in a single call.
	* tdesc.h (struct target_desc): Replace pointer with object.
2018-03-21 15:57:00 +00:00
Alan Hayward
2f3a377ccc Move tdesc header funcs to c file
Move the destructor and equals operator for gdbserver tdesc from the .h
to the .c file. Both functions are too long to be inlined and make the
header look messy. Patch does not change any functionality.
Patch identical to V3 version.

2018-03-21  Alan Hayward  <alan.hayward@arm.com>

gdbserver/
	* tdesc.c (target_desc::~target_desc): Move to here.
	(target_desc::operator==): Likewise.
	* tdesc.h (target_desc::~target_desc): Move from here.
	(target_desc::operator==): Likewise.
2018-03-21 15:56:50 +00:00
57 changed files with 976 additions and 792 deletions

View File

@@ -967,6 +967,7 @@ COMMON_SFILES = \
common/run-time-clock.c \
common/signals.c \
common/signals-state-save-restore.c \
common/tdesc.c \
common/vec.c \
common/xml-utils.c \
complaints.c \
@@ -1444,6 +1445,7 @@ HFILES_NO_SRCDIR = \
common/run-time-clock.h \
common/signals-state-save-restore.h \
common/symbol.h \
common/tdesc.h \
common/vec.h \
common/version.h \
common/x86-xstate.h \

397
gdb/common/tdesc.c Normal file
View File

@@ -0,0 +1,397 @@
/* Target description support for GDB.
Copyright (C) 2017 Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#ifdef GDBSERVER
#include "server.h"
#else
#include "defs.h"
#endif
#include "common/tdesc.h"
tdesc_reg::tdesc_reg (struct tdesc_feature *feature, const std::string &name_,
int regnum, int save_restore_, const char *group_,
int bitsize_, const char *type_)
: name (name_), target_regnum (regnum),
save_restore (save_restore_),
group (group_ != NULL ? group_ : ""),
bitsize (bitsize_),
type (type_ != NULL ? type_ : "<unknown>")
{
/* If the register's type is target-defined, look it up now. We may not
have easy access to the containing feature when we want it later. */
tdesc_type = tdesc_named_type (feature, type.c_str ());
}
/* Predefined types. */
static tdesc_type_builtin tdesc_predefined_types[] =
{
{ "bool", TDESC_TYPE_BOOL },
{ "int8", TDESC_TYPE_INT8 },
{ "int16", TDESC_TYPE_INT16 },
{ "int32", TDESC_TYPE_INT32 },
{ "int64", TDESC_TYPE_INT64 },
{ "int128", TDESC_TYPE_INT128 },
{ "uint8", TDESC_TYPE_UINT8 },
{ "uint16", TDESC_TYPE_UINT16 },
{ "uint32", TDESC_TYPE_UINT32 },
{ "uint64", TDESC_TYPE_UINT64 },
{ "uint128", TDESC_TYPE_UINT128 },
{ "code_ptr", TDESC_TYPE_CODE_PTR },
{ "data_ptr", TDESC_TYPE_DATA_PTR },
{ "ieee_single", TDESC_TYPE_IEEE_SINGLE },
{ "ieee_double", TDESC_TYPE_IEEE_DOUBLE },
{ "arm_fpa_ext", TDESC_TYPE_ARM_FPA_EXT },
{ "i387_ext", TDESC_TYPE_I387_EXT }
};
void tdesc_feature::accept (tdesc_element_visitor &v) const
{
v.visit_pre (this);
for (const tdesc_type_up &type : types)
type->accept (v);
for (const tdesc_reg_up &reg : registers)
reg->accept (v);
v.visit_post (this);
}
bool tdesc_feature::operator== (const tdesc_feature &other) const
{
if (name != other.name)
return false;
if (registers.size () != other.registers.size ())
return false;
for (int ix = 0; ix < registers.size (); ix++)
{
const tdesc_reg_up &reg1 = registers[ix];
const tdesc_reg_up &reg2 = other.registers[ix];
if (reg1 != reg2 && *reg1 != *reg2)
return false;
}
if (types.size () != other.types.size ())
return false;
for (int ix = 0; ix < types.size (); ix++)
{
const tdesc_type_up &type1 = types[ix];
const tdesc_type_up &type2 = other.types[ix];
if (type1 != type2 && *type1 != *type2)
return false;
}
return true;
}
/* Lookup a predefined type. */
static struct tdesc_type *
tdesc_predefined_type (enum tdesc_type_kind kind)
{
for (int 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");
}
/* See common/tdesc.h. */
struct tdesc_type *
tdesc_named_type (const struct tdesc_feature *feature, const char *id)
{
/* First try target-defined types. */
for (const tdesc_type_up &type : feature->types)
if (type->name == id)
return type.get ();
/* Next try the predefined types. */
for (int ix = 0; ix < ARRAY_SIZE (tdesc_predefined_types); ix++)
if (tdesc_predefined_types[ix].name == id)
return &tdesc_predefined_types[ix];
return NULL;
}
/* See common/tdesc.h. */
void
tdesc_create_reg (struct tdesc_feature *feature, const char *name,
int regnum, int save_restore, const char *group,
int bitsize, const char *type)
{
tdesc_reg *reg = new tdesc_reg (feature, name, regnum, save_restore,
group, bitsize, type);
feature->registers.emplace_back (reg);
}
/* See common/tdesc.h. */
struct tdesc_type *
tdesc_create_vector (struct tdesc_feature *feature, const char *name,
struct tdesc_type *field_type, int count)
{
tdesc_type_vector *type = new tdesc_type_vector (name, field_type, count);
feature->types.emplace_back (type);
return type;
}
/* See common/tdesc.h. */
tdesc_type_with_fields *
tdesc_create_struct (struct tdesc_feature *feature, const char *name)
{
tdesc_type_with_fields *type
= new tdesc_type_with_fields (name, TDESC_TYPE_STRUCT);
feature->types.emplace_back (type);
return type;
}
/* See common/tdesc.h. */
void
tdesc_set_struct_size (tdesc_type_with_fields *type, int size)
{
gdb_assert (type->kind == TDESC_TYPE_STRUCT);
gdb_assert (size > 0);
type->size = size;
}
/* See common/tdesc.h. */
tdesc_type_with_fields *
tdesc_create_union (struct tdesc_feature *feature, const char *name)
{
tdesc_type_with_fields *type
= new tdesc_type_with_fields (name, TDESC_TYPE_UNION);
feature->types.emplace_back (type);
return type;
}
/* See common/tdesc.h. */
tdesc_type_with_fields *
tdesc_create_flags (struct tdesc_feature *feature, const char *name,
int size)
{
gdb_assert (size > 0);
tdesc_type_with_fields *type
= new tdesc_type_with_fields (name, TDESC_TYPE_FLAGS, size);
feature->types.emplace_back (type);
return type;
}
tdesc_type_with_fields *
tdesc_create_enum (struct tdesc_feature *feature, const char *name,
int size)
{
gdb_assert (size > 0);
tdesc_type_with_fields *type
= new tdesc_type_with_fields (name, TDESC_TYPE_ENUM, size);
feature->types.emplace_back (type);
return type;
}
/* See common/tdesc.h. */
void
tdesc_add_field (tdesc_type_with_fields *type, const char *field_name,
struct tdesc_type *field_type)
{
gdb_assert (type->kind == TDESC_TYPE_UNION
|| type->kind == TDESC_TYPE_STRUCT);
/* Initialize start and end so we know this is not a bit-field
when we print-c-tdesc. */
type->fields.emplace_back (field_name, field_type, -1, -1);
}
void
tdesc_add_typed_bitfield (tdesc_type_with_fields *type, const char *field_name,
int start, int end, struct tdesc_type *field_type)
{
gdb_assert (type->kind == TDESC_TYPE_STRUCT
|| type->kind == TDESC_TYPE_FLAGS);
gdb_assert (start >= 0 && end >= start);
type->fields.emplace_back (field_name, field_type, start, end);
}
/* See common/tdesc.h. */
void
tdesc_add_bitfield (tdesc_type_with_fields *type, const char *field_name,
int start, int end)
{
struct tdesc_type *field_type;
gdb_assert (start >= 0 && end >= start);
if (type->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);
}
/* See common/tdesc.h. */
void
tdesc_add_flag (tdesc_type_with_fields *type, int start,
const char *flag_name)
{
gdb_assert (type->kind == TDESC_TYPE_FLAGS
|| type->kind == TDESC_TYPE_STRUCT);
type->fields.emplace_back (flag_name,
tdesc_predefined_type (TDESC_TYPE_BOOL),
start, start);
}
void
tdesc_add_enum_value (tdesc_type_with_fields *type, int value,
const char *name)
{
gdb_assert (type->kind == TDESC_TYPE_ENUM);
type->fields.emplace_back (name,
tdesc_predefined_type (TDESC_TYPE_INT32),
value, -1);
}
void print_xml_feature::visit_pre (const tdesc_feature *e)
{
string_appendf (m_buffer, "<feature name=\"%s\">\n", e->name.c_str ());
}
void print_xml_feature::visit_post (const tdesc_feature *e)
{
string_appendf (m_buffer, "</feature>\n");
}
void print_xml_feature::visit (const tdesc_type_builtin *t)
{
error (_("xml output is not supported type \"%s\"."), t->name.c_str ());
}
void print_xml_feature::visit (const tdesc_type_vector *t)
{
string_appendf (m_buffer, "<vector id=\"%s\" type=\"%s\" count=\"%d\"/>\n",
t->name.c_str (), t->element_type->name.c_str (), t->count);
}
void print_xml_feature::visit (const tdesc_type_with_fields *t)
{
struct tdesc_type_field *f;
const static char *types[] = { "struct", "union", "flags", "enum" };
gdb_assert (t->kind >= TDESC_TYPE_STRUCT && t->kind <= TDESC_TYPE_ENUM);
string_appendf (m_buffer, "<%s id=\"%s\"", types[t->kind - TDESC_TYPE_STRUCT],
t->name.c_str ());
switch (t->kind)
{
case TDESC_TYPE_STRUCT:
case TDESC_TYPE_FLAGS:
if (t->size > 0)
string_appendf (m_buffer, " size=\"%d\"", t->size);
string_appendf (m_buffer, ">\n");
for (const tdesc_type_field &f : t->fields)
{
string_appendf (m_buffer, " <field name=\"%s\" ", f.name.c_str ());
if (f.start == -1)
string_appendf (m_buffer, "type=\"%s\"/>\n", f.type->name.c_str ());
else
string_appendf (m_buffer, "start=\"%d\" end=\"%d\"/>\n", f.start,
f.end);
}
break;
case TDESC_TYPE_ENUM:
string_appendf (m_buffer, ">\n");
for (const tdesc_type_field &f : t->fields)
string_appendf (m_buffer, " <field name=\"%s\" start=\"%d\"/>\n",
f.name.c_str (), f.start);
break;
case TDESC_TYPE_UNION:
string_appendf (m_buffer, ">\n");
for (const tdesc_type_field &f : t->fields)
string_appendf (m_buffer, " <field name=\"%s\" type=\"%s\"/>\n",
f.name.c_str (), f.type->name.c_str ());
break;
default:
error (_("xml output is not supported type \"%s\"."), t->name.c_str ());
}
string_appendf (m_buffer, "</%s>\n", types[t->kind - TDESC_TYPE_STRUCT]);
}
void print_xml_feature::visit (const tdesc_reg *r)
{
string_appendf (m_buffer,
"<reg name=\"%s\" bitsize=\"%d\" type=\"%s\" regnum=\"%ld\"",
r->name.c_str (), r->bitsize, r->type.c_str (),
r->target_regnum);
if (r->group.length () > 0)
string_appendf (m_buffer, " group=\"%s\"", r->group.c_str ());
if (r->save_restore == 0)
string_appendf (m_buffer, " save-restore=\"no\"");
string_appendf (m_buffer, "/>\n");
}
void print_xml_feature::visit_pre (const target_desc *e)
{
#ifndef IN_PROCESS_AGENT
string_appendf (m_buffer, "<?xml version=\"1.0\"?>\n");
string_appendf (m_buffer, "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">\n");
string_appendf (m_buffer, "<target>\n<architecture>%s</architecture>\n",
tdesc_architecture_name (e));
const char *osabi = tdesc_osabi_name (e);
if (osabi != nullptr)
string_appendf (m_buffer, "<osabi>%s</osabi>", osabi);
#endif
}
void print_xml_feature::visit_post (const target_desc *e)
{
string_appendf (m_buffer, "</target>\n");
}

View File

@@ -18,6 +18,12 @@
#ifndef ARCH_TDESC_H
#define ARCH_TDESC_H 1
#ifdef GDBSERVER
#include "server.h"
#else
#include "defs.h"
#endif
struct tdesc_feature;
struct tdesc_type;
struct tdesc_type_builtin;
@@ -26,6 +32,270 @@ struct tdesc_type_with_fields;
struct tdesc_reg;
struct target_desc;
/* The interface to visit different elements of target description. */
class tdesc_element_visitor
{
public:
virtual void visit_pre (const target_desc *e)
{}
virtual void visit_post (const target_desc *e)
{}
virtual void visit_pre (const tdesc_feature *e)
{}
virtual void visit_post (const tdesc_feature *e)
{}
virtual void visit (const tdesc_type_builtin *e)
{}
virtual void visit (const tdesc_type_vector *e)
{}
virtual void visit (const tdesc_type_with_fields *e)
{}
virtual void visit (const tdesc_reg *e)
{}
};
class tdesc_element
{
public:
virtual void accept (tdesc_element_visitor &v) const = 0;
};
/* An individual register from a target description. */
struct tdesc_reg : tdesc_element
{
tdesc_reg (struct tdesc_feature *feature, const std::string &name_,
int regnum, int save_restore_, const char *group_,
int bitsize_, const char *type_);
virtual ~tdesc_reg () = default;
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
for the user. */
std::string name;
/* The register number used by this target to refer to this
register. This is used for remote p/P packets and to determine
the ordering of registers in the remote g/G packets. */
long target_regnum;
/* If this flag is set, GDB should save and restore this register
around calls to an inferior function. */
int save_restore;
/* The name of the register group containing this register, or empty
if the group should be automatically determined from the
register's type. If this is "general", "float", or "vector", the
corresponding "info" command should display this register's
value. It can be an arbitrary string, but should be limited to
alphanumeric characters and internal hyphens. Currently other
strings are ignored (treated as empty). */
std::string group;
/* The size of the register, in bits. */
int bitsize;
/* The type of the register. This string corresponds to either
a named type from the target description or a predefined
type from GDB. */
std::string type;
/* The target-described type corresponding to TYPE, if found. */
struct tdesc_type *tdesc_type;
void accept (tdesc_element_visitor &v) const override
{
v.visit (this);
}
bool operator== (const tdesc_reg &other) const
{
return (name == other.name
&& target_regnum == other.target_regnum
&& save_restore == other.save_restore
&& bitsize == other.bitsize
&& group == other.group
&& type == other.type);
}
bool operator!= (const tdesc_reg &other) const
{
return !(*this == other);
}
};
typedef std::unique_ptr<tdesc_reg> tdesc_reg_up;
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
};
struct tdesc_type : tdesc_element
{
tdesc_type (const std::string &name_, enum tdesc_type_kind kind_)
: name (name_), kind (kind_)
{}
virtual ~tdesc_type () = default;
DISABLE_COPY_AND_ASSIGN (tdesc_type);
/* The name of this type. */
std::string name;
/* Identify the kind of this type. */
enum tdesc_type_kind kind;
bool operator== (const tdesc_type &other) const
{
return name == other.name && kind == other.kind;
}
bool operator!= (const tdesc_type &other) const
{
return !(*this == other);
}
};
typedef std::unique_ptr<tdesc_type> tdesc_type_up;
struct tdesc_type_builtin : tdesc_type
{
tdesc_type_builtin (const std::string &name, enum tdesc_type_kind kind)
: tdesc_type (name, kind)
{}
void accept (tdesc_element_visitor &v) const override
{
v.visit (this);
}
};
/* tdesc_type for vector types. */
struct tdesc_type_vector : tdesc_type
{
tdesc_type_vector (const std::string &name, tdesc_type *element_type_,
int count_)
: tdesc_type (name, TDESC_TYPE_VECTOR),
element_type (element_type_), count (count_)
{}
void accept (tdesc_element_visitor &v) const override
{
v.visit (this);
}
struct tdesc_type *element_type;
int count;
};
/* A named type from a target description. */
struct tdesc_type_field
{
tdesc_type_field (const std::string &name_, tdesc_type *type_,
int start_, int end_)
: name (name_), type (type_), start (start_), end (end_)
{}
std::string 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 for struct, union, flags, and enum types. */
struct tdesc_type_with_fields : tdesc_type
{
tdesc_type_with_fields (const std::string &name, tdesc_type_kind kind,
int size_ = 0)
: tdesc_type (name, kind), size (size_)
{}
void accept (tdesc_element_visitor &v) const override
{
v.visit (this);
}
std::vector<tdesc_type_field> fields;
int size;
};
/* A feature from a target description. Each feature is a collection
of other elements, e.g. registers and types. */
struct tdesc_feature : tdesc_element
{
tdesc_feature (const std::string &name_)
: name (name_)
{}
virtual ~tdesc_feature () = default;
DISABLE_COPY_AND_ASSIGN (tdesc_feature);
/* The name of this feature. It may be recognized by the architecture
support code. */
std::string name;
/* The registers associated with this feature. */
std::vector<tdesc_reg_up> registers;
/* The types associated with this feature. */
std::vector<tdesc_type_up> types;
void accept (tdesc_element_visitor &v) const override;
bool operator== (const tdesc_feature &other) const;
bool operator!= (const tdesc_feature &other) const
{
return !(*this == other);
}
};
typedef std::unique_ptr<tdesc_feature> tdesc_feature_up;
/* Allocate a new target_desc. */
target_desc *allocate_target_description (void);
@@ -33,9 +303,18 @@ target_desc *allocate_target_description (void);
void set_tdesc_architecture (target_desc *target_desc,
const char *name);
/* Return the architecture associated with this target description as a string,
or NULL if no architecture was specified. */
const char *tdesc_architecture_name (const struct target_desc *target_desc);
/* Set TARGET_DESC's osabi by NAME. */
void set_tdesc_osabi (target_desc *target_desc, const char *name);
/* Return the osabi associated with this target description as a string,
or NULL if no osabi was specified. */
const char *
tdesc_osabi_name (const struct target_desc *target_desc);
/* Return the type associated with ID in the context of FEATURE, or
NULL if none. */
struct tdesc_type *tdesc_named_type (const struct tdesc_feature *feature,
@@ -43,9 +322,7 @@ struct tdesc_type *tdesc_named_type (const struct tdesc_feature *feature,
/* Return the created feature named NAME in target description TDESC. */
struct tdesc_feature *tdesc_create_feature (struct target_desc *tdesc,
const char *name,
const char *xml = nullptr);
const char *name);
/* Return the created vector tdesc_type named NAME in FEATURE. */
struct tdesc_type *tdesc_create_vector (struct tdesc_feature *feature,
@@ -92,4 +369,33 @@ void tdesc_create_reg (struct tdesc_feature *feature, const char *name,
int regnum, int save_restore, const char *group,
int bitsize, const char *type);
/* Return the tdesc in string XML format. */
const char *tdesc_get_features_xml (target_desc *tdesc);
/* Print target description as xml. */
class print_xml_feature : public tdesc_element_visitor
{
public:
print_xml_feature (std::string &buffer_)
: m_buffer (buffer_)
{}
~print_xml_feature ()
{}
void visit_pre (const target_desc *e) override;
void visit_post (const target_desc *e) override;
void visit_pre (const tdesc_feature *e) override;
void visit_post (const tdesc_feature *e) override;
void visit (const tdesc_type_builtin *type) override;
void visit (const tdesc_type_vector *type) override;
void visit (const tdesc_type_with_fields *type) override;
void visit (const tdesc_reg *reg) override;
private:
std::string &m_buffer;
};
#endif /* ARCH_TDESC_H */

View File

@@ -193,12 +193,18 @@ XMLTOC = \
TDESC_CFILES = $(patsubst %.xml,%.c,$(XMLTOC))
GDB = false
#Targets which use feature based target descriptions.
aarch64-feature = 1
i386-feature = 1
tic6x-feature = 1
all: $(OUTPUTS)
$(outdir)/%.dat: %.xml number-regs.xsl sort-regs.xsl gdbserver-regs.xsl
echo "# THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi :set ro:" > $(outdir)/$*.tmp
echo "# Generated from: $<" >> $(outdir)/$*.tmp
echo "name:`echo $(notdir $*) | sed 's/-/_/g'`" >> $(outdir)/$*.tmp
$(if $($(firstword $(subst /, ,$(subst -, ,$*)))-feature), echo "feature:1") >> $(outdir)/$*.tmp
echo "xmltarget:$(<F)" >> $(outdir)/$*.tmp
echo "expedite:$(if $($*-expedite),$($*-expedite),$($(firstword $(subst -, ,$(notdir $*)))-expedite))" \
>> $(outdir)/$*.tmp

View File

@@ -8,7 +8,7 @@ create_feature_aarch64_core (struct target_desc *result, long regnum)
{
struct tdesc_feature *feature;
feature = tdesc_create_feature (result, "org.gnu.gdb.aarch64.core", "aarch64-core.xml");
feature = tdesc_create_feature (result, "org.gnu.gdb.aarch64.core");
tdesc_type_with_fields *type_with_fields;
type_with_fields = tdesc_create_flags (feature, "cpsr_flags", 4);
tdesc_add_flag (type_with_fields, 0, "SP");

View File

@@ -8,7 +8,7 @@ create_feature_aarch64_fpu (struct target_desc *result, long regnum)
{
struct tdesc_feature *feature;
feature = tdesc_create_feature (result, "org.gnu.gdb.aarch64.fpu", "aarch64-fpu.xml");
feature = tdesc_create_feature (result, "org.gnu.gdb.aarch64.fpu");
tdesc_type *element_type;
element_type = tdesc_named_type (feature, "ieee_double");
tdesc_create_vector (feature, "v2d", element_type, 2);

View File

@@ -8,7 +8,7 @@ create_feature_i386_32bit_avx (struct target_desc *result, long regnum)
{
struct tdesc_feature *feature;
feature = tdesc_create_feature (result, "org.gnu.gdb.i386.avx", "32bit-avx.xml");
feature = tdesc_create_feature (result, "org.gnu.gdb.i386.avx");
tdesc_create_reg (feature, "ymm0h", regnum++, 1, NULL, 128, "uint128");
tdesc_create_reg (feature, "ymm1h", regnum++, 1, NULL, 128, "uint128");
tdesc_create_reg (feature, "ymm2h", regnum++, 1, NULL, 128, "uint128");

View File

@@ -8,7 +8,7 @@ create_feature_i386_32bit_avx512 (struct target_desc *result, long regnum)
{
struct tdesc_feature *feature;
feature = tdesc_create_feature (result, "org.gnu.gdb.i386.avx512", "32bit-avx512.xml");
feature = tdesc_create_feature (result, "org.gnu.gdb.i386.avx512");
tdesc_type *element_type;
element_type = tdesc_named_type (feature, "uint128");
tdesc_create_vector (feature, "v2ui128", element_type, 2);

View File

@@ -8,7 +8,7 @@ create_feature_i386_32bit_core (struct target_desc *result, long regnum)
{
struct tdesc_feature *feature;
feature = tdesc_create_feature (result, "org.gnu.gdb.i386.core", "32bit-core.xml");
feature = tdesc_create_feature (result, "org.gnu.gdb.i386.core");
tdesc_type_with_fields *type_with_fields;
type_with_fields = tdesc_create_flags (feature, "i386_eflags", 4);
tdesc_add_flag (type_with_fields, 0, "CF");

View File

@@ -8,7 +8,7 @@ create_feature_i386_32bit_linux (struct target_desc *result, long regnum)
{
struct tdesc_feature *feature;
feature = tdesc_create_feature (result, "org.gnu.gdb.i386.linux", "32bit-linux.xml");
feature = tdesc_create_feature (result, "org.gnu.gdb.i386.linux");
regnum = 41;
tdesc_create_reg (feature, "orig_eax", regnum++, 1, NULL, 32, "int");
return regnum;

View File

@@ -8,7 +8,7 @@ create_feature_i386_32bit_mpx (struct target_desc *result, long regnum)
{
struct tdesc_feature *feature;
feature = tdesc_create_feature (result, "org.gnu.gdb.i386.mpx", "32bit-mpx.xml");
feature = tdesc_create_feature (result, "org.gnu.gdb.i386.mpx");
tdesc_type_with_fields *type_with_fields;
type_with_fields = tdesc_create_struct (feature, "br128");
tdesc_type *field_type;

View File

@@ -8,7 +8,7 @@ create_feature_i386_32bit_pkeys (struct target_desc *result, long regnum)
{
struct tdesc_feature *feature;
feature = tdesc_create_feature (result, "org.gnu.gdb.i386.pkeys", "32bit-pkeys.xml");
feature = tdesc_create_feature (result, "org.gnu.gdb.i386.pkeys");
tdesc_create_reg (feature, "pkru", regnum++, 1, NULL, 32, "uint32");
return regnum;
}

View File

@@ -8,7 +8,7 @@ create_feature_i386_32bit_sse (struct target_desc *result, long regnum)
{
struct tdesc_feature *feature;
feature = tdesc_create_feature (result, "org.gnu.gdb.i386.sse", "32bit-sse.xml");
feature = tdesc_create_feature (result, "org.gnu.gdb.i386.sse");
tdesc_type *element_type;
element_type = tdesc_named_type (feature, "ieee_single");
tdesc_create_vector (feature, "v4f", element_type, 4);

View File

@@ -8,7 +8,7 @@ create_feature_i386_64bit_avx (struct target_desc *result, long regnum)
{
struct tdesc_feature *feature;
feature = tdesc_create_feature (result, "org.gnu.gdb.i386.avx", "64bit-avx.xml");
feature = tdesc_create_feature (result, "org.gnu.gdb.i386.avx");
tdesc_create_reg (feature, "ymm0h", regnum++, 1, NULL, 128, "uint128");
tdesc_create_reg (feature, "ymm1h", regnum++, 1, NULL, 128, "uint128");
tdesc_create_reg (feature, "ymm2h", regnum++, 1, NULL, 128, "uint128");

View File

@@ -8,7 +8,7 @@ create_feature_i386_64bit_avx512 (struct target_desc *result, long regnum)
{
struct tdesc_feature *feature;
feature = tdesc_create_feature (result, "org.gnu.gdb.i386.avx512", "64bit-avx512.xml");
feature = tdesc_create_feature (result, "org.gnu.gdb.i386.avx512");
tdesc_type *element_type;
element_type = tdesc_named_type (feature, "ieee_single");
tdesc_create_vector (feature, "v4f", element_type, 4);

View File

@@ -8,7 +8,7 @@ create_feature_i386_64bit_core (struct target_desc *result, long regnum)
{
struct tdesc_feature *feature;
feature = tdesc_create_feature (result, "org.gnu.gdb.i386.core", "64bit-core.xml");
feature = tdesc_create_feature (result, "org.gnu.gdb.i386.core");
tdesc_type_with_fields *type_with_fields;
type_with_fields = tdesc_create_flags (feature, "i386_eflags", 4);
tdesc_add_flag (type_with_fields, 0, "CF");

View File

@@ -8,7 +8,7 @@ create_feature_i386_64bit_linux (struct target_desc *result, long regnum)
{
struct tdesc_feature *feature;
feature = tdesc_create_feature (result, "org.gnu.gdb.i386.linux", "64bit-linux.xml");
feature = tdesc_create_feature (result, "org.gnu.gdb.i386.linux");
regnum = 57;
tdesc_create_reg (feature, "orig_rax", regnum++, 1, NULL, 64, "int");
return regnum;

View File

@@ -8,7 +8,7 @@ create_feature_i386_64bit_mpx (struct target_desc *result, long regnum)
{
struct tdesc_feature *feature;
feature = tdesc_create_feature (result, "org.gnu.gdb.i386.mpx", "64bit-mpx.xml");
feature = tdesc_create_feature (result, "org.gnu.gdb.i386.mpx");
tdesc_type_with_fields *type_with_fields;
type_with_fields = tdesc_create_struct (feature, "br128");
tdesc_type *field_type;

View File

@@ -8,7 +8,7 @@ create_feature_i386_64bit_pkeys (struct target_desc *result, long regnum)
{
struct tdesc_feature *feature;
feature = tdesc_create_feature (result, "org.gnu.gdb.i386.pkeys", "64bit-pkeys.xml");
feature = tdesc_create_feature (result, "org.gnu.gdb.i386.pkeys");
tdesc_create_reg (feature, "pkru", regnum++, 1, NULL, 32, "uint32");
return regnum;
}

View File

@@ -8,7 +8,7 @@ create_feature_i386_64bit_segments (struct target_desc *result, long regnum)
{
struct tdesc_feature *feature;
feature = tdesc_create_feature (result, "org.gnu.gdb.i386.segments", "64bit-segments.xml");
feature = tdesc_create_feature (result, "org.gnu.gdb.i386.segments");
tdesc_create_reg (feature, "fs_base", regnum++, 1, NULL, 64, "int");
tdesc_create_reg (feature, "gs_base", regnum++, 1, NULL, 64, "int");
return regnum;

View File

@@ -8,7 +8,7 @@ create_feature_i386_64bit_sse (struct target_desc *result, long regnum)
{
struct tdesc_feature *feature;
feature = tdesc_create_feature (result, "org.gnu.gdb.i386.sse", "64bit-sse.xml");
feature = tdesc_create_feature (result, "org.gnu.gdb.i386.sse");
tdesc_type *element_type;
element_type = tdesc_named_type (feature, "ieee_single");
tdesc_create_vector (feature, "v4f", element_type, 4);

View File

@@ -8,7 +8,7 @@ create_feature_i386_x32_core (struct target_desc *result, long regnum)
{
struct tdesc_feature *feature;
feature = tdesc_create_feature (result, "org.gnu.gdb.i386.core", "x32-core.xml");
feature = tdesc_create_feature (result, "org.gnu.gdb.i386.core");
tdesc_type_with_fields *type_with_fields;
type_with_fields = tdesc_create_flags (feature, "i386_eflags", 4);
tdesc_add_flag (type_with_fields, 0, "CF");

View File

@@ -8,7 +8,7 @@ create_feature_tic6x_c6xp (struct target_desc *result, long regnum)
{
struct tdesc_feature *feature;
feature = tdesc_create_feature (result, "org.gnu.gdb.tic6x.c6xp", "tic6x-c6xp.xml");
feature = tdesc_create_feature (result, "org.gnu.gdb.tic6x.c6xp");
tdesc_create_reg (feature, "TSR", regnum++, 1, NULL, 32, "uint32");
tdesc_create_reg (feature, "ILC", regnum++, 1, NULL, 32, "uint32");
tdesc_create_reg (feature, "RILC", regnum++, 1, NULL, 32, "uint32");

View File

@@ -8,7 +8,7 @@ create_feature_tic6x_core (struct target_desc *result, long regnum)
{
struct tdesc_feature *feature;
feature = tdesc_create_feature (result, "org.gnu.gdb.tic6x.core", "tic6x-core.xml");
feature = tdesc_create_feature (result, "org.gnu.gdb.tic6x.core");
tdesc_create_reg (feature, "A0", regnum++, 1, NULL, 32, "uint32");
tdesc_create_reg (feature, "A1", regnum++, 1, NULL, 32, "uint32");
tdesc_create_reg (feature, "A2", regnum++, 1, NULL, 32, "uint32");

View File

@@ -8,7 +8,7 @@ create_feature_tic6x_gp (struct target_desc *result, long regnum)
{
struct tdesc_feature *feature;
feature = tdesc_create_feature (result, "org.gnu.gdb.tic6x.gp", "tic6x-gp.xml");
feature = tdesc_create_feature (result, "org.gnu.gdb.tic6x.gp");
tdesc_create_reg (feature, "A16", regnum++, 1, NULL, 32, "uint32");
tdesc_create_reg (feature, "A17", regnum++, 1, NULL, 32, "uint32");
tdesc_create_reg (feature, "A18", regnum++, 1, NULL, 32, "uint32");

View File

@@ -215,6 +215,7 @@ SFILES = \
$(srcdir)/common/print-utils.c \
$(srcdir)/common/ptid.c \
$(srcdir)/common/rsp-low.c \
$(srcdir)/common/tdesc.c \
$(srcdir)/common/vec.c \
$(srcdir)/common/xml-utils.c \
$(srcdir)/nat/linux-btrace.c \
@@ -258,6 +259,7 @@ OBS = \
common/rsp-low.o \
common/signals.o \
common/signals-state-save-restore.o \
common/tdesc.o \
common/vec.o \
common/xml-utils.o \
debug.o \
@@ -403,6 +405,7 @@ IPA_OBJS = \
common/format-ipa.o \
common/print-utils-ipa.o \
common/rsp-low-ipa.o \
common/tdesc-ipa.o \
common/vec-ipa.o \
regcache-ipa.o \
remote-utils-ipa.o \

View File

@@ -34,14 +34,6 @@ fi
ipa_ppc_linux_regobj="powerpc-32l-ipa.o powerpc-altivec32l-ipa.o powerpc-cell32l-ipa.o powerpc-vsx32l-ipa.o powerpc-isa205-32l-ipa.o powerpc-isa205-altivec32l-ipa.o powerpc-isa205-vsx32l-ipa.o powerpc-e500l-ipa.o powerpc-64l-ipa.o powerpc-altivec64l-ipa.o powerpc-cell64l-ipa.o powerpc-vsx64l-ipa.o powerpc-isa205-64l-ipa.o powerpc-isa205-altivec64l-ipa.o powerpc-isa205-vsx64l-ipa.o"
srv_i386_32bit_xmlfiles="i386/32bit-core.xml i386/32bit-sse.xml i386/32bit-avx.xml i386/32bit-avx512.xml i386/32bit-mpx.xml i386/32bit-pkeys.xml"
srv_i386_64bit_xmlfiles="i386/64bit-core.xml i386/64bit-segments.xml i386/64bit-sse.xml i386/64bit-avx.xml i386/64bit-avx512.xml i386/x32-core.xml i386/64bit-mpx.xml i386/64bit-pkeys.xml"
srv_i386_xmlfiles="i386/i386.xml $srv_i386_32bit_xmlfiles"
srv_amd64_xmlfiles="i386/amd64.xml $srv_i386_64bit_xmlfiles"
srv_i386_linux_xmlfiles="i386/32bit-linux.xml $srv_i386_32bit_xmlfiles"
srv_amd64_linux_xmlfiles="i386/64bit-linux.xml $srv_i386_64bit_xmlfiles"
# Linux object files. This is so we don't have to repeat
# these files over and over again.
srv_linux_obj="linux-low.o linux-osdata.o linux-procfs.o linux-ptrace.o linux-waitpid.o linux-personality.o linux-namespaces.o fork-child.o fork-inferior.o"
@@ -63,11 +55,6 @@ case "${target}" in
srv_tgtobj="$srv_tgtobj arch/aarch64.o"
srv_tgtobj="$srv_tgtobj linux-aarch64-tdesc.o"
srv_tgtobj="${srv_tgtobj} $srv_linux_obj"
srv_xmlfiles="aarch64.xml"
srv_xmlfiles="${srv_xmlfiles} aarch64-core.xml"
srv_xmlfiles="${srv_xmlfiles} aarch64-fpu.xml"
srv_xmlfiles="${srv_xmlfiles} arm/arm-core.xml arm/arm-vfpv3.xml"
srv_xmlfiles="${srv_xmlfiles} arm/arm-with-neon.xml"
srv_linux_regsets=yes
srv_linux_thread_db=yes
ipa_obj="linux-aarch64-ipa.o"
@@ -121,13 +108,10 @@ case "${target}" in
i[34567]86-*-cygwin*) srv_regobj=""
srv_tgtobj="x86-low.o x86-dregs.o win32-low.o win32-i386-low.o"
srv_tgtobj="${srv_tgtobj} arch/i386.o"
srv_xmlfiles="$srv_i386_xmlfiles"
;;
i[34567]86-*-linux*) srv_regobj="$srv_i386_linux_regobj"
srv_xmlfiles="$srv_i386_linux_xmlfiles"
if test "$gdb_cv_i386_is_x86_64" = yes ; then
srv_regobj="$srv_regobj $srv_amd64_linux_regobj"
srv_xmlfiles="${srv_xmlfiles} $srv_amd64_linux_xmlfiles"
srv_tgtobj="amd64-linux-siginfo.o"
fi
srv_tgtobj="${srv_tgtobj} arch/i386.o"
@@ -145,9 +129,6 @@ case "${target}" in
i[34567]86-*-lynxos*) srv_regobj=""
srv_tgtobj="lynx-low.o lynx-i386-low.o fork-child.o fork-inferior.o"
srv_tgtobj="${srv_tgtobj} arch/i386.o"
srv_xmlfiles="i386/i386.xml"
srv_xmlfiles="${srv_xmlfiles} i386/32bit-core.xml"
srv_xmlfiles="${srv_xmlfiles} i386/32bit-sse.xml"
srv_lynxos=yes
;;
i[34567]86-*-mingw32ce*)
@@ -155,7 +136,6 @@ case "${target}" in
srv_tgtobj="x86-low.o x86-dregs.o win32-low.o win32-i386-low.o"
srv_tgtobj="${srv_tgtobj} arch/i386.o"
srv_tgtobj="${srv_tgtobj} wincecompat.o"
srv_xmlfiles="$srv_i386_xmlfiles"
# hostio_last_error implementation is in win32-low.c
srv_hostio_err_objs=""
srv_mingw=yes
@@ -164,12 +144,10 @@ case "${target}" in
i[34567]86-*-mingw*) srv_regobj=""
srv_tgtobj="x86-low.o x86-dregs.o win32-low.o win32-i386-low.o"
srv_tgtobj="${srv_tgtobj} arch/i386.o"
srv_xmlfiles="$srv_i386_xmlfiles"
srv_mingw=yes
;;
i[34567]86-*-nto*) srv_regobj=""
srv_tgtobj="nto-low.o nto-x86-low.o arch/i386.o"
srv_xmlfiles="$srv_i386_xmlfiles"
srv_qnx="yes"
;;
ia64-*-linux*) srv_regobj=reg-ia64.o
@@ -370,9 +348,6 @@ case "${target}" in
else
srv_regobj=""
fi
srv_xmlfiles="${srv_xmlfiles} tic6x-core.xml"
srv_xmlfiles="${srv_xmlfiles} tic6x-gp.xml"
srv_xmlfiles="${srv_xmlfiles} tic6x-c6xp.xml"
srv_tgtobj="$srv_linux_obj linux-tic6x-low.o"
srv_tgtobj="${srv_tgtobj} arch/tic6x.o"
srv_linux_regsets=yes
@@ -386,7 +361,6 @@ case "${target}" in
srv_tgtobj="${srv_tgtobj} linux-btrace.o x86-linux.o"
srv_tgtobj="${srv_tgtobj} x86-linux-dregs.o"
srv_tgtobj="${srv_tgtobj} amd64-linux-siginfo.o"
srv_xmlfiles="$srv_i386_linux_xmlfiles $srv_amd64_linux_xmlfiles"
srv_linux_usrregs=yes # This is for i386 progs.
srv_linux_regsets=yes
srv_linux_thread_db=yes
@@ -397,13 +371,11 @@ case "${target}" in
x86_64-*-mingw*) srv_regobj=""
srv_tgtobj="x86-low.o x86-dregs.o i387-fp.o win32-low.o win32-i386-low.o"
srv_tgtobj="${srv_tgtobj} arch/amd64.o"
srv_xmlfiles="$srv_i386_xmlfiles $srv_amd64_xmlfiles"
srv_mingw=yes
;;
x86_64-*-cygwin*) srv_regobj=""
srv_tgtobj="x86-low.o x86-dregs.o i387-fp.o win32-low.o win32-i386-low.o"
srv_tgtobj="${srv_tgtobj} arch/amd64.o"
srv_xmlfiles="$srv_i386_xmlfiles"
;;
xtensa*-*-linux*) srv_regobj=reg-xtensa.o

View File

@@ -196,6 +196,13 @@ regcache_cpy (struct regcache *dst, struct regcache *src)
dst->registers_valid = src->registers_valid;
}
/* Return a reference to the description of register ``n''. */
static const struct reg &
find_register_by_number (const struct target_desc *tdesc, int n)
{
return tdesc->reg_defs[n];
}
#ifndef IN_PROCESS_AGENT
@@ -243,25 +250,13 @@ int
find_regno (const struct target_desc *tdesc, const char *name)
{
for (int i = 0; i < tdesc->reg_defs.size (); ++i)
{
struct reg *reg = tdesc->reg_defs[i];
if (strcmp (name, find_register_by_number (tdesc, i).name) == 0)
return i;
if (strcmp (name, reg->name) == 0)
return i;
}
internal_error (__FILE__, __LINE__, "Unknown register %s requested",
name);
}
#endif
struct reg *
find_register_by_number (const struct target_desc *tdesc, int n)
{
return tdesc->reg_defs[n];
}
#ifndef IN_PROCESS_AGENT
static void
free_register_cache_thread (struct thread_info *thread)
{
@@ -292,7 +287,7 @@ register_cache_size (const struct target_desc *tdesc)
int
register_size (const struct target_desc *tdesc, int n)
{
return find_register_by_number (tdesc, n)->size / 8;
return find_register_by_number (tdesc, n).size / 8;
}
/* See common/common-regcache.h. */
@@ -307,7 +302,7 @@ static unsigned char *
register_data (struct regcache *regcache, int n, int fetch)
{
return (regcache->registers
+ find_register_by_number (regcache->tdesc, n)->offset / 8);
+ find_register_by_number (regcache->tdesc, n).offset / 8);
}
/* Supply register N, whose contents are stored in BUF, to REGCACHE.

View File

@@ -94,10 +94,6 @@ void registers_from_string (struct regcache *regcache, char *buf);
void regcache_write_pc (struct regcache *regcache, CORE_ADDR pc);
/* Return a pointer to the description of register ``n''. */
struct reg *find_register_by_number (const struct target_desc *tdesc, int n);
int register_cache_size (const struct target_desc *tdesc);
int register_size (const struct target_desc *tdesc, int n);

View File

@@ -19,16 +19,91 @@
#include "tdesc.h"
#include "regdef.h"
#ifndef IN_PROCESS_AGENT
target_desc::~target_desc ()
{
xfree ((char *) arch);
xfree ((char *) osabi);
}
bool target_desc::operator== (const target_desc &other) const
{
if (reg_defs.size () != other.reg_defs.size ())
return false;
for (int i = 0; i < reg_defs.size (); ++i)
{
struct reg reg = reg_defs[i];
struct reg reg2 = other.reg_defs[i];
if (&reg != &reg2 && reg != reg2)
return false;
}
/* Compare expedite_regs. */
int i = 0;
for (; expedite_regs[i] != NULL; i++)
{
if (strcmp (expedite_regs[i], other.expedite_regs[i]) != 0)
return false;
}
if (other.expedite_regs[i] != NULL)
return false;
return true;
}
#endif
void target_desc::accept (tdesc_element_visitor &v) const
{
#ifndef IN_PROCESS_AGENT
v.visit_pre (this);
for (const tdesc_feature_up &feature : features)
feature->accept (v);
v.visit_post (this);
#endif
}
void
init_target_desc (struct target_desc *tdesc)
{
int offset = 0;
for (reg *reg : tdesc->reg_defs)
{
reg->offset = offset;
offset += reg->size;
}
/* Go through all the features and populate reg_defs. */
for (const tdesc_feature_up &feature : tdesc->features)
for (const tdesc_reg_up &treg : feature->registers)
{
int current_size = tdesc->reg_defs.size ();
/* Register number will either increase (possibly with gaps) or be
zero. */
gdb_assert (treg->target_regnum == 0
|| treg->target_regnum >= current_size);
tdesc->reg_defs.resize (treg->target_regnum != 0
? treg->target_regnum + 1
: current_size + 1);
/* Fill in any blank spaces. */
while (current_size < treg->target_regnum)
{
struct reg *reg = &tdesc->reg_defs[current_size];
reg->name = "";
reg->size = 0;
reg->offset = offset;
current_size++;
}
struct reg *reg = &tdesc->reg_defs.back ();
reg->name = treg->name.c_str ();
reg->size = treg->bitsize;
reg->offset = offset;
offset += reg->size;
}
tdesc->registers_size = offset / 8;
@@ -68,6 +143,14 @@ current_target_desc (void)
/* See common/tdesc.h. */
const char *
tdesc_architecture_name (const struct target_desc *target_desc)
{
return target_desc->arch;
}
/* See common/tdesc.h. */
void
set_tdesc_architecture (struct target_desc *target_desc,
const char *name)
@@ -77,51 +160,35 @@ set_tdesc_architecture (struct target_desc *target_desc,
/* See common/tdesc.h. */
const char *
tdesc_osabi_name (const struct target_desc *target_desc)
{
return target_desc->osabi;
}
/* See common/tdesc.h. */
void
set_tdesc_osabi (struct target_desc *target_desc, const char *name)
{
target_desc->osabi = xstrdup (name);
}
/* Return a string which is of XML format, including XML target
description to be sent to GDB. */
/* See common/tdesc.h. */
const char *
tdesc_get_features_xml (target_desc *tdesc)
{
/* Either .xmltarget or .features is not NULL. */
gdb_assert (tdesc->xmltarget != NULL
|| (tdesc->features != NULL
|| (!tdesc->features.empty ()
&& tdesc->arch != NULL));
if (tdesc->xmltarget == NULL)
{
std::string buffer ("@<?xml version=\"1.0\"?>");
buffer += "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">";
buffer += "<target>";
buffer += "<architecture>";
buffer += tdesc->arch;
buffer += "</architecture>";
if (tdesc->osabi != nullptr)
{
buffer += "<osabi>";
buffer += tdesc->osabi;
buffer += "</osabi>";
}
char *xml;
for (int i = 0; VEC_iterate (char_ptr, tdesc->features, i, xml); i++)
{
buffer += "<xi:include href=\"";
buffer += xml;
buffer += "\"/>";
}
buffer += "</target>";
std::string buffer ("@");
print_xml_feature v (buffer);
tdesc->accept (v);
tdesc->xmltarget = xstrdup (buffer.c_str ());
}
@@ -129,113 +196,12 @@ tdesc_get_features_xml (target_desc *tdesc)
}
#endif
struct tdesc_type
{};
/* See common/tdesc.h. */
struct tdesc_feature *
tdesc_create_feature (struct target_desc *tdesc, const char *name,
const char *xml)
{
#ifndef IN_PROCESS_AGENT
VEC_safe_push (char_ptr, tdesc->features, xstrdup (xml));
#endif
return tdesc;
}
/* See common/tdesc.h. */
tdesc_type_with_fields *
tdesc_create_flags (struct tdesc_feature *feature, const char *name,
int size)
{
return NULL;
}
/* See common/tdesc.h. */
void
tdesc_add_flag (tdesc_type_with_fields *type, int start,
const char *flag_name)
{}
/* See common/tdesc.h. */
struct tdesc_type *
tdesc_named_type (const struct tdesc_feature *feature, const char *id)
{
return NULL;
}
/* See common/tdesc.h. */
tdesc_type_with_fields *
tdesc_create_union (struct tdesc_feature *feature, const char *id)
{
return NULL;
}
/* See common/tdesc.h. */
tdesc_type_with_fields *
tdesc_create_struct (struct tdesc_feature *feature, const char *id)
{
return NULL;
}
/* See common/tdesc.h. */
void
tdesc_create_reg (struct tdesc_feature *feature, const char *name,
int regnum, int save_restore, const char *group,
int bitsize, const char *type)
{
struct target_desc *tdesc = (struct target_desc *) feature;
while (tdesc->reg_defs.size () < regnum)
{
struct reg *reg = XCNEW (struct reg);
reg->name = "";
reg->size = 0;
tdesc->reg_defs.push_back (reg);
}
gdb_assert (regnum == 0
|| regnum == tdesc->reg_defs.size ());
struct reg *reg = XCNEW (struct reg);
reg->name = name;
reg->size = bitsize;
tdesc->reg_defs.push_back (reg);
}
/* See common/tdesc.h. */
struct tdesc_type *
tdesc_create_vector (struct tdesc_feature *feature, const char *name,
struct tdesc_type *field_type, int count)
{
return NULL;
}
void
tdesc_add_bitfield (tdesc_type_with_fields *type, const char *field_name,
int start, int end)
{}
/* See common/tdesc.h. */
void
tdesc_add_field (tdesc_type_with_fields *type, const char *field_name,
struct tdesc_type *field_type)
{}
/* See common/tdesc.h. */
void
tdesc_set_struct_size (tdesc_type_with_fields *type, int size)
tdesc_create_feature (struct target_desc *tdesc, const char *name)
{
struct tdesc_feature *new_feature = new tdesc_feature (name);
tdesc->features.emplace_back (new_feature);
return new_feature;
}

View File

@@ -24,21 +24,21 @@
#include "regdef.h"
#include <vector>
struct tdesc_feature
{};
/* A target description. Inherit from tdesc_feature so that target_desc
can be used as tdesc_feature. */
struct target_desc : tdesc_feature
struct target_desc : tdesc_element
{
/* A vector of elements of register definitions that
describe the inferior's register set. */
std::vector<struct reg *> reg_defs;
std::vector<struct reg> reg_defs;
/* The register cache size, in bytes. */
int registers_size;
/* XML features in this target description. */
std::vector<tdesc_feature_up> features;
#ifndef IN_PROCESS_AGENT
/* An array of register names. These are the "expedite" registers:
registers whose values are sent along with stop replies. */
@@ -53,9 +53,6 @@ struct target_desc : tdesc_feature
fields features, arch, and osabi in tdesc_get_features_xml. */
const char *xmltarget = NULL;
/* XML features in this target description. */
VEC (char_ptr) *features = NULL;
/* The value of <architecture> element in the XML, replying GDB. */
const char *arch = NULL;
@@ -67,55 +64,17 @@ public:
: registers_size (0)
{}
~target_desc ()
{
int i;
~target_desc ();
for (reg *reg : reg_defs)
xfree (reg);
xfree ((char *) arch);
xfree ((char *) osabi);
char *f;
for (i = 0; VEC_iterate (char_ptr, features, i, f); i++)
xfree (f);
VEC_free (char_ptr, features);
}
bool operator== (const target_desc &other) const
{
if (reg_defs.size () != other.reg_defs.size ())
return false;
for (int i = 0; i < reg_defs.size (); ++i)
{
struct reg *reg = reg_defs[i];
struct reg *reg2 = other.reg_defs[i];
if (reg != reg2 && *reg != *reg2)
return false;
}
/* Compare expedite_regs. */
int i = 0;
for (; expedite_regs[i] != NULL; i++)
{
if (strcmp (expedite_regs[i], other.expedite_regs[i]) != 0)
return false;
}
if (other.expedite_regs[i] != NULL)
return false;
return true;
}
bool operator== (const target_desc &other) const;
bool operator!= (const target_desc &other) const
{
return !(*this == other);
}
#endif
void accept (tdesc_element_visitor &v) const;
};
/* Copy target description SRC to DEST. */

View File

@@ -1,6 +1,7 @@
# THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi :set ro:
# Generated from: aarch64.xml
name:aarch64
feature:1
xmltarget:aarch64.xml
expedite:x29,sp,pc
64:x0

View File

@@ -1,6 +1,7 @@
# THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi :set ro:
# Generated from: i386/amd64-avx-avx512-linux.xml
name:amd64_avx_avx512_linux
feature:1
xmltarget:amd64-avx-avx512-linux.xml
expedite:rbp,rsp,rip
64:rax

View File

@@ -1,6 +1,7 @@
# THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi :set ro:
# Generated from: i386/amd64-avx-linux.xml
name:amd64_avx_linux
feature:1
xmltarget:amd64-avx-linux.xml
expedite:rbp,rsp,rip
64:rax

View File

@@ -1,6 +1,7 @@
# THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi :set ro:
# Generated from: i386/amd64-avx-mpx-avx512-pku-linux.xml
name:amd64_avx_mpx_avx512_pku_linux
feature:1
xmltarget:amd64-avx-mpx-avx512-pku-linux.xml
expedite:rbp,rsp,rip
64:rax

View File

@@ -1,6 +1,7 @@
# THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi :set ro:
# Generated from: i386/amd64-avx-mpx-linux.xml
name:amd64_avx_mpx_linux
feature:1
xmltarget:amd64-avx-mpx-linux.xml
expedite:rbp,rsp,rip
64:rax

View File

@@ -1,6 +1,7 @@
# THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi :set ro:
# Generated from: i386/amd64-linux.xml
name:amd64_linux
feature:1
xmltarget:amd64-linux.xml
expedite:rbp,rsp,rip
64:rax

View File

@@ -1,6 +1,7 @@
# THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi :set ro:
# Generated from: i386/amd64-mpx-linux.xml
name:amd64_mpx_linux
feature:1
xmltarget:amd64-mpx-linux.xml
expedite:rbp,rsp,rip
64:rax

View File

@@ -1,6 +1,7 @@
# THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi :set ro:
# Generated from: i386/amd64.xml
name:amd64
feature:1
xmltarget:amd64.xml
expedite:rbp,rsp,rip
64:rax

View File

@@ -1,6 +1,7 @@
# THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi :set ro:
# Generated from: i386/i386-avx-avx512-linux.xml
name:i386_avx_avx512_linux
feature:1
xmltarget:i386-avx-avx512-linux.xml
expedite:ebp,esp,eip
32:eax

View File

@@ -1,6 +1,7 @@
# THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi :set ro:
# Generated from: i386/i386-avx-linux.xml
name:i386_avx_linux
feature:1
xmltarget:i386-avx-linux.xml
expedite:ebp,esp,eip
32:eax

View File

@@ -1,6 +1,7 @@
# THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi :set ro:
# Generated from: i386/i386-avx-mpx-avx512-pku-linux.xml
name:i386_avx_mpx_avx512_pku_linux
feature:1
xmltarget:i386-avx-mpx-avx512-pku-linux.xml
expedite:ebp,esp,eip
32:eax

View File

@@ -1,6 +1,7 @@
# THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi :set ro:
# Generated from: i386/i386-avx-mpx-linux.xml
name:i386_avx_mpx_linux
feature:1
xmltarget:i386-avx-mpx-linux.xml
expedite:ebp,esp,eip
32:eax

View File

@@ -1,6 +1,7 @@
# THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi :set ro:
# Generated from: i386/i386-linux.xml
name:i386_linux
feature:1
xmltarget:i386-linux.xml
expedite:ebp,esp,eip
32:eax

View File

@@ -1,6 +1,7 @@
# THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi :set ro:
# Generated from: i386/i386-mmx-linux.xml
name:i386_mmx_linux
feature:1
xmltarget:i386-mmx-linux.xml
expedite:ebp,esp,eip
32:eax

View File

@@ -1,6 +1,7 @@
# THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi :set ro:
# Generated from: i386/i386-mpx-linux.xml
name:i386_mpx_linux
feature:1
xmltarget:i386-mpx-linux.xml
expedite:ebp,esp,eip
32:eax

View File

@@ -1,6 +1,7 @@
# THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi :set ro:
# Generated from: i386/i386.xml
name:i386
feature:1
xmltarget:i386.xml
expedite:ebp,esp,eip
32:eax

View File

@@ -1,6 +1,7 @@
# THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi :set ro:
# Generated from: i386/x32-avx-avx512-linux.xml
name:x32_avx_avx512_linux
feature:1
xmltarget:x32-avx-avx512-linux.xml
expedite:rbp,rsp,rip
64:rax

View File

@@ -1,6 +1,7 @@
# THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi :set ro:
# Generated from: i386/x32-avx-linux.xml
name:x32_avx_linux
feature:1
xmltarget:x32-avx-linux.xml
expedite:rbp,rsp,rip
64:rax

View File

@@ -1,6 +1,7 @@
# THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi :set ro:
# Generated from: i386/x32-linux.xml
name:x32_linux
feature:1
xmltarget:x32-linux.xml
expedite:rbp,rsp,rip
64:rax

View File

@@ -118,6 +118,7 @@ xmltarget=x
xmlarch=x
xmlosabi=x
expedite=x
feature=x
exec < $1
while do_read
do
@@ -131,7 +132,7 @@ do
echo "{"
echo " static struct target_desc tdesc_${name}_s;"
echo " struct target_desc *result = &tdesc_${name}_s;"
echo " struct tdesc_feature *feature = tdesc_create_feature (result, \"${name}\");"
continue
elif test "${type}" = "xmltarget"; then
xmltarget="${entry}"
@@ -145,11 +146,14 @@ do
elif test "${type}" = "expedite"; then
expedite="${entry}"
continue
elif test "${type}" = "feature"; then
feature="${entry}"
continue
elif test "${name}" = x; then
echo "$0: $1 does not specify \`\`name''." 1>&2
exit 1
else
echo " tdesc_create_reg ((struct tdesc_feature *) result, \"${entry}\","
echo " tdesc_create_reg (feature, \"${entry}\","
echo " 0, 0, NULL, ${type}, NULL);"
offset=`expr ${offset} + ${type}`
@@ -159,7 +163,9 @@ done
echo
echo "static const char *expedite_regs_${name}[] = { \"`echo ${expedite} | sed 's/,/", "/g'`\", 0 };"
if test "${xmltarget}" = x; then
if test "${feature}" != x; then
echo "static const char *xmltarget_${name} = 0;"
elif test "${xmltarget}" = x; then
if test "${xmlarch}" = x && test "${xmlosabi}" = x; then
echo "static const char *xmltarget_${name} = 0;"
else

View File

@@ -1,6 +1,7 @@
# THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi :set ro:
# Generated from: tic6x-c62x-linux.xml
name:tic6x_c62x_linux
feature:1
xmltarget:tic6x-c62x-linux.xml
expedite:A15,PC
32:A0

View File

@@ -1,6 +1,7 @@
# THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi :set ro:
# Generated from: tic6x-c64x-linux.xml
name:tic6x_c64x_linux
feature:1
xmltarget:tic6x-c64x-linux.xml
expedite:A15,PC
32:A0

View File

@@ -1,6 +1,7 @@
# THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi :set ro:
# Generated from: tic6x-c64xp-linux.xml
name:tic6x_c64xp_linux
feature:1
xmltarget:tic6x-c64xp-linux.xml
expedite:A15,PC
32:A0

View File

@@ -38,44 +38,6 @@
#include "completer.h"
#include "readline/tilde.h" /* tilde_expand */
static type *make_gdb_type (struct gdbarch *gdbarch, struct tdesc_type *ttype);
/* The interface to visit different elements of target description. */
class tdesc_element_visitor
{
public:
virtual void visit_pre (const target_desc *e)
{}
virtual void visit_post (const target_desc *e)
{}
virtual void visit_pre (const tdesc_feature *e)
{}
virtual void visit_post (const tdesc_feature *e)
{}
virtual void visit (const tdesc_type_builtin *e)
{}
virtual void visit (const tdesc_type_vector *e)
{}
virtual void visit (const tdesc_type_with_fields *e)
{}
virtual void visit (const tdesc_reg *e)
{}
};
class tdesc_element
{
public:
virtual void accept (tdesc_element_visitor &v) const = 0;
};
/* Types. */
struct property
@@ -88,207 +50,6 @@ struct property
std::string value;
};
/* An individual register from a target description. */
struct tdesc_reg : tdesc_element
{
tdesc_reg (struct tdesc_feature *feature, const std::string &name_,
int regnum, int save_restore_, const char *group_,
int bitsize_, const char *type_)
: name (name_), target_regnum (regnum),
save_restore (save_restore_),
group (group_ != NULL ? group_ : ""),
bitsize (bitsize_),
type (type_ != NULL ? type_ : "<unknown>")
{
/* If the register's type is target-defined, look it up now. We may not
have easy access to the containing feature when we want it later. */
tdesc_type = tdesc_named_type (feature, type.c_str ());
}
virtual ~tdesc_reg () = default;
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
for the user. */
std::string name;
/* The register number used by this target to refer to this
register. This is used for remote p/P packets and to determine
the ordering of registers in the remote g/G packets. */
long target_regnum;
/* If this flag is set, GDB should save and restore this register
around calls to an inferior function. */
int save_restore;
/* The name of the register group containing this register, or empty
if the group should be automatically determined from the register's
type. This is traditionally "general", "float", "vector" but can
also be an arbitrary string. If defined the corresponding "info"
command should display this register's value. The string should be
limited to alphanumeric characters and internal hyphens. */
std::string group;
/* The size of the register, in bits. */
int bitsize;
/* The type of the register. This string corresponds to either
a named type from the target description or a predefined
type from GDB. */
std::string type;
/* The target-described type corresponding to TYPE, if found. */
struct tdesc_type *tdesc_type;
void accept (tdesc_element_visitor &v) const override
{
v.visit (this);
}
bool operator== (const tdesc_reg &other) const
{
return (name == other.name
&& target_regnum == other.target_regnum
&& save_restore == other.save_restore
&& bitsize == other.bitsize
&& group == other.group
&& type == other.type);
}
bool operator!= (const tdesc_reg &other) const
{
return !(*this == other);
}
};
typedef std::unique_ptr<tdesc_reg> tdesc_reg_up;
/* A named type from a target description. */
struct tdesc_type_field
{
tdesc_type_field (const std::string &name_, tdesc_type *type_,
int start_, int end_)
: name (name_), type (type_), start (start_), end (end_)
{}
std::string 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;
};
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
};
struct tdesc_type : tdesc_element
{
tdesc_type (const std::string &name_, enum tdesc_type_kind kind_)
: name (name_), kind (kind_)
{}
virtual ~tdesc_type () = default;
DISABLE_COPY_AND_ASSIGN (tdesc_type);
/* The name of this type. */
std::string name;
/* Identify the kind of this type. */
enum tdesc_type_kind kind;
bool operator== (const tdesc_type &other) const
{
return name == other.name && kind == other.kind;
}
bool operator!= (const tdesc_type &other) const
{
return !(*this == other);
}
};
typedef std::unique_ptr<tdesc_type> tdesc_type_up;
struct tdesc_type_builtin : tdesc_type
{
tdesc_type_builtin (const std::string &name, enum tdesc_type_kind kind)
: tdesc_type (name, kind)
{}
void accept (tdesc_element_visitor &v) const override
{
v.visit (this);
}
};
/* tdesc_type for vector types. */
struct tdesc_type_vector : tdesc_type
{
tdesc_type_vector (const std::string &name, tdesc_type *element_type_, int count_)
: tdesc_type (name, TDESC_TYPE_VECTOR),
element_type (element_type_), count (count_)
{}
void accept (tdesc_element_visitor &v) const override
{
v.visit (this);
}
struct tdesc_type *element_type;
int count;
};
/* tdesc_type for struct, union, flags, and enum types. */
struct tdesc_type_with_fields : tdesc_type
{
tdesc_type_with_fields (const std::string &name, tdesc_type_kind kind,
int size_ = 0)
: tdesc_type (name, kind), size (size_)
{}
void accept (tdesc_element_visitor &v) const override
{
v.visit (this);
}
std::vector<tdesc_type_field> fields;
int size;
};
/* Convert a tdesc_type to a gdb type. */
static type *
@@ -544,82 +305,6 @@ make_gdb_type (struct gdbarch *gdbarch, struct tdesc_type *ttype)
return gdb_type.get_type ();
}
/* A feature from a target description. Each feature is a collection
of other elements, e.g. registers and types. */
struct tdesc_feature : tdesc_element
{
tdesc_feature (const std::string &name_)
: name (name_)
{}
virtual ~tdesc_feature () = default;
DISABLE_COPY_AND_ASSIGN (tdesc_feature);
/* The name of this feature. It may be recognized by the architecture
support code. */
std::string name;
/* The registers associated with this feature. */
std::vector<tdesc_reg_up> registers;
/* The types associated with this feature. */
std::vector<tdesc_type_up> types;
void accept (tdesc_element_visitor &v) const override
{
v.visit_pre (this);
for (const tdesc_type_up &type : types)
type->accept (v);
for (const tdesc_reg_up &reg : registers)
reg->accept (v);
v.visit_post (this);
}
bool operator== (const tdesc_feature &other) const
{
if (name != other.name)
return false;
if (registers.size () != other.registers.size ())
return false;
for (int ix = 0; ix < registers.size (); ix++)
{
const tdesc_reg_up &reg1 = registers[ix];
const tdesc_reg_up &reg2 = other.registers[ix];
if (reg1 != reg2 && *reg1 != *reg2)
return false;
}
if (types.size () != other.types.size ())
return false;
for (int ix = 0; ix < types.size (); ix++)
{
const tdesc_type_up &type1 = types[ix];
const tdesc_type_up &type2 = other.types[ix];
if (type1 != type2 && *type1 != *type2)
return false;
}
return true;
}
bool operator!= (const tdesc_feature &other) const
{
return !(*this == other);
}
};
typedef std::unique_ptr<tdesc_feature> tdesc_feature_up;
/* A target description. */
struct target_desc : tdesc_element
@@ -648,6 +333,8 @@ struct target_desc : tdesc_element
/* The features associated with this target. */
std::vector<tdesc_feature_up> features;
char *xmltarget = nullptr;
void accept (tdesc_element_visitor &v) const override
{
v.visit_pre (this);
@@ -943,6 +630,14 @@ tdesc_architecture (const struct target_desc *target_desc)
return target_desc->arch;
}
/* See common/tdesc.h. */
const char *
tdesc_architecture_name (const struct target_desc *target_desc)
{
return target_desc->arch->printable_name;
}
/* Return the OSABI associated with this target description, or
GDB_OSABI_UNKNOWN if no osabi was specified. */
@@ -952,7 +647,16 @@ tdesc_osabi (const struct target_desc *target_desc)
return target_desc->osabi;
}
/* See common/tdesc.h. */
const char *
tdesc_osabi_name (const struct target_desc *target_desc)
{
enum gdb_osabi osabi = tdesc_osabi (target_desc);
if (osabi > GDB_OSABI_UNKNOWN && osabi < GDB_OSABI_INVALID)
return gdbarch_osabi_name (osabi);
return nullptr;
}
/* Return 1 if this target description includes any registers. */
@@ -991,58 +695,6 @@ tdesc_feature_name (const struct tdesc_feature *feature)
return feature->name.c_str ();
}
/* Predefined types. */
static tdesc_type_builtin tdesc_predefined_types[] =
{
{ "bool", TDESC_TYPE_BOOL },
{ "int8", TDESC_TYPE_INT8 },
{ "int16", TDESC_TYPE_INT16 },
{ "int32", TDESC_TYPE_INT32 },
{ "int64", TDESC_TYPE_INT64 },
{ "int128", TDESC_TYPE_INT128 },
{ "uint8", TDESC_TYPE_UINT8 },
{ "uint16", TDESC_TYPE_UINT16 },
{ "uint32", TDESC_TYPE_UINT32 },
{ "uint64", TDESC_TYPE_UINT64 },
{ "uint128", TDESC_TYPE_UINT128 },
{ "code_ptr", TDESC_TYPE_CODE_PTR },
{ "data_ptr", TDESC_TYPE_DATA_PTR },
{ "ieee_single", TDESC_TYPE_IEEE_SINGLE },
{ "ieee_double", TDESC_TYPE_IEEE_DOUBLE },
{ "arm_fpa_ext", TDESC_TYPE_ARM_FPA_EXT },
{ "i387_ext", TDESC_TYPE_I387_EXT }
};
/* Lookup a predefined type. */
static struct tdesc_type *
tdesc_predefined_type (enum tdesc_type_kind kind)
{
for (int 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");
}
/* See common/tdesc.h. */
struct tdesc_type *
tdesc_named_type (const struct tdesc_feature *feature, const char *id)
{
/* First try target-defined types. */
for (const tdesc_type_up &type : feature->types)
if (type->name == id)
return type.get ();
/* Next try the predefined types. */
for (int ix = 0; ix < ARRAY_SIZE (tdesc_predefined_types); ix++)
if (tdesc_predefined_types[ix].name == id)
return &tdesc_predefined_types[ix];
return NULL;
}
/* Lookup type associated with ID. */
struct type *
@@ -1474,167 +1126,11 @@ tdesc_use_registers (struct gdbarch *gdbarch,
tdesc_remote_register_number);
set_gdbarch_register_reggroup_p (gdbarch, tdesc_register_reggroup_p);
}
/* See common/tdesc.h. */
void
tdesc_create_reg (struct tdesc_feature *feature, const char *name,
int regnum, int save_restore, const char *group,
int bitsize, const char *type)
{
tdesc_reg *reg = new tdesc_reg (feature, name, regnum, save_restore,
group, bitsize, type);
feature->registers.emplace_back (reg);
}
/* See common/tdesc.h. */
struct tdesc_type *
tdesc_create_vector (struct tdesc_feature *feature, const char *name,
struct tdesc_type *field_type, int count)
{
tdesc_type_vector *type = new tdesc_type_vector (name, field_type, count);
feature->types.emplace_back (type);
return type;
}
/* See common/tdesc.h. */
tdesc_type_with_fields *
tdesc_create_struct (struct tdesc_feature *feature, const char *name)
{
tdesc_type_with_fields *type
= new tdesc_type_with_fields (name, TDESC_TYPE_STRUCT);
feature->types.emplace_back (type);
return type;
}
/* See common/tdesc.h. */
void
tdesc_set_struct_size (tdesc_type_with_fields *type, int size)
{
gdb_assert (type->kind == TDESC_TYPE_STRUCT);
gdb_assert (size > 0);
type->size = size;
}
/* See common/tdesc.h. */
tdesc_type_with_fields *
tdesc_create_union (struct tdesc_feature *feature, const char *name)
{
tdesc_type_with_fields *type
= new tdesc_type_with_fields (name, TDESC_TYPE_UNION);
feature->types.emplace_back (type);
return type;
}
/* See common/tdesc.h. */
tdesc_type_with_fields *
tdesc_create_flags (struct tdesc_feature *feature, const char *name,
int size)
{
gdb_assert (size > 0);
tdesc_type_with_fields *type
= new tdesc_type_with_fields (name, TDESC_TYPE_FLAGS, size);
feature->types.emplace_back (type);
return type;
}
tdesc_type_with_fields *
tdesc_create_enum (struct tdesc_feature *feature, const char *name,
int size)
{
gdb_assert (size > 0);
tdesc_type_with_fields *type
= new tdesc_type_with_fields (name, TDESC_TYPE_ENUM, size);
feature->types.emplace_back (type);
return type;
}
/* See common/tdesc.h. */
void
tdesc_add_field (tdesc_type_with_fields *type, const char *field_name,
struct tdesc_type *field_type)
{
gdb_assert (type->kind == TDESC_TYPE_UNION
|| type->kind == TDESC_TYPE_STRUCT);
/* Initialize start and end so we know this is not a bit-field
when we print-c-tdesc. */
type->fields.emplace_back (field_name, field_type, -1, -1);
}
void
tdesc_add_typed_bitfield (tdesc_type_with_fields *type, const char *field_name,
int start, int end, struct tdesc_type *field_type)
{
gdb_assert (type->kind == TDESC_TYPE_STRUCT
|| type->kind == TDESC_TYPE_FLAGS);
gdb_assert (start >= 0 && end >= start);
type->fields.emplace_back (field_name, field_type, start, end);
}
/* See common/tdesc.h. */
void
tdesc_add_bitfield (tdesc_type_with_fields *type, const char *field_name,
int start, int end)
{
struct tdesc_type *field_type;
gdb_assert (start >= 0 && end >= start);
if (type->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);
}
/* See common/tdesc.h. */
void
tdesc_add_flag (tdesc_type_with_fields *type, int start,
const char *flag_name)
{
gdb_assert (type->kind == TDESC_TYPE_FLAGS
|| type->kind == TDESC_TYPE_STRUCT);
type->fields.emplace_back (flag_name,
tdesc_predefined_type (TDESC_TYPE_BOOL),
start, start);
}
void
tdesc_add_enum_value (tdesc_type_with_fields *type, int value,
const char *name)
{
gdb_assert (type->kind == TDESC_TYPE_ENUM);
type->fields.emplace_back (name,
tdesc_predefined_type (TDESC_TYPE_INT32),
value, -1);
}
/* See common/tdesc.h. */
struct tdesc_feature *
tdesc_create_feature (struct target_desc *tdesc, const char *name,
const char *xml)
tdesc_create_feature (struct target_desc *tdesc, const char *name)
{
struct tdesc_feature *new_feature = new tdesc_feature (name);
@@ -2102,8 +1598,8 @@ public:
printf_unfiltered (" struct tdesc_feature *feature;\n");
printf_unfiltered
("\n feature = tdesc_create_feature (result, \"%s\", \"%s\");\n",
e->name.c_str (), lbasename (m_filename_after_features.c_str ()));
("\n feature = tdesc_create_feature (result, \"%s\");\n",
e->name.c_str ());
}
void visit_post (const tdesc_feature *e) override
@@ -2172,6 +1668,21 @@ private:
int m_next_regnum = 0;
};
/* See common/tdesc.h. */
const char *
tdesc_get_features_xml (target_desc *tdesc)
{
if (tdesc->xmltarget == nullptr)
{
std::string buffer ("@");
print_xml_feature v (buffer);
tdesc->accept (v);
tdesc->xmltarget = xstrdup (buffer.c_str ());
}
return tdesc->xmltarget;
}
static void
maint_print_c_tdesc_cmd (const char *args, int from_tty)
{
@@ -2265,7 +1776,36 @@ maintenance_check_xml_descriptions (const char *dir, int from_tty)
= file_read_description_xml (tdesc_xml.data ());
if (tdesc == NULL || *tdesc != *e.second)
failed++;
{
printf_filtered ( _("Descriptions for %s do not match\n"), e.first);
failed++;
continue;
}
/* Convert both descriptions to xml, and then back again. Confirm all
descriptions are identical. */
const char *xml = tdesc_get_features_xml ((target_desc *) tdesc);
const char *xml2 = tdesc_get_features_xml ((target_desc *) e.second);
gdb_assert (*xml == '@');
gdb_assert (*xml2 == '@');
const target_desc *t_trans = target_read_description_xml_string (xml+1);
const target_desc *t_trans2 = target_read_description_xml_string (xml2+1);
if (t_trans == NULL || t_trans2 == NULL)
{
printf_filtered (
_("Could not convert descriptions for %s back to xml (%p %p)\n"),
e.first, t_trans, t_trans2);
failed++;
}
else if (*tdesc != *t_trans || *tdesc != *t_trans2)
{
printf_filtered
(_("Translated descriptions for %s do not match (%d %d)\n"),
e.first, *tdesc == *t_trans, *tdesc == *t_trans2);
failed++;
}
}
printf_filtered (_("Tested %lu XML files, %d failed\n"),
(long) selftests::xml_tdesc.size (), failed);

View File

@@ -752,3 +752,12 @@ target_fetch_description_xml (struct target_ops *ops)
return output;
#endif
}
/* Take an xml string, parse it, and return the parsed description. Does not
handle a string containing includes. */
const struct target_desc *
target_read_description_xml_string (const char *xml_str)
{
return tdesc_parse_xml (xml_str, nullptr, nullptr);
}

View File

@@ -44,5 +44,10 @@ const struct target_desc *target_read_description_xml (struct target_ops *);
otherwise. */
gdb::optional<std::string> target_fetch_description_xml (target_ops *ops);
/* Take an xml string, parse it, and return the parsed description. Does not
handle a string containing includes. */
const struct target_desc *target_read_description_xml_string (const char *);
#endif /* XML_TDESC_H */