mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-11-16 12:34:43 +00:00
Compare commits
8 Commits
binutils-2
...
users/ahay
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
59c10f023a | ||
|
|
5db4be8573 | ||
|
|
9374ab9e85 | ||
|
|
f736361e6d | ||
|
|
c0c6b1a936 | ||
|
|
707bac6b4c | ||
|
|
fff179643e | ||
|
|
75b9525ee2 |
@@ -912,6 +912,7 @@ COMMON_SFILES = \
|
||||
agent.c \
|
||||
annotate.c \
|
||||
arch-utils.c \
|
||||
arch/tdesc.c \
|
||||
auto-load.c \
|
||||
auxv.c \
|
||||
ax-gdb.c \
|
||||
|
||||
425
gdb/arch/tdesc.c
Normal file
425
gdb/arch/tdesc.c
Normal file
@@ -0,0 +1,425 @@
|
||||
/* 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 "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 ® : 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 ®1 = registers[ix];
|
||||
const tdesc_reg_up ®2 = 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 arch/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 arch/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 arch/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 arch/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 arch/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 arch/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 arch/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 arch/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 arch/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 arch/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_post (const target_desc *e)
|
||||
{
|
||||
*m_buffer += "</target>\n";
|
||||
}
|
||||
|
||||
void print_xml_feature::visit_pre (const tdesc_feature *e)
|
||||
{
|
||||
*m_buffer += "<feature name=\"";
|
||||
*m_buffer += e->name;
|
||||
*m_buffer += "\">\n";
|
||||
}
|
||||
|
||||
void print_xml_feature::visit_post (const tdesc_feature *e)
|
||||
{
|
||||
*m_buffer += "</feature>\n";
|
||||
}
|
||||
|
||||
void print_xml_feature::visit (const tdesc_type_builtin *type)
|
||||
{
|
||||
error (_("xml output is not supported type \"%s\"."), type->name.c_str ());
|
||||
}
|
||||
|
||||
void print_xml_feature::visit (const tdesc_type_vector *type)
|
||||
{
|
||||
*m_buffer += "<vector id=\"";
|
||||
*m_buffer += type->name;
|
||||
*m_buffer += "\" type=\"";
|
||||
*m_buffer += type->element_type->name;
|
||||
*m_buffer += "\" count=\"";
|
||||
*m_buffer += std::to_string (type->count);
|
||||
*m_buffer += "\"/>\n";
|
||||
}
|
||||
|
||||
void print_xml_feature::visit (const tdesc_type_with_fields *type)
|
||||
{
|
||||
struct tdesc_type_field *f;
|
||||
const static char *types[] = { "struct", "union", "flags", "enum" };
|
||||
|
||||
gdb_assert (type->kind >= TDESC_TYPE_STRUCT && type->kind <= TDESC_TYPE_ENUM);
|
||||
*m_buffer += "<";
|
||||
*m_buffer += types[type->kind - TDESC_TYPE_STRUCT];
|
||||
|
||||
switch (type->kind)
|
||||
{
|
||||
case TDESC_TYPE_STRUCT:
|
||||
case TDESC_TYPE_FLAGS:
|
||||
*m_buffer += " id=\"";
|
||||
*m_buffer += type->name;
|
||||
if (type->size > 0)
|
||||
{
|
||||
*m_buffer += "\" size=\"";
|
||||
*m_buffer += std::to_string (type->size);
|
||||
}
|
||||
*m_buffer += "\">\n";
|
||||
|
||||
for (const tdesc_type_field &f : type->fields)
|
||||
{
|
||||
*m_buffer += " <field name=\"";
|
||||
*m_buffer += f.name;
|
||||
if (f.start == -1)
|
||||
{
|
||||
*m_buffer += "\" type=\"";
|
||||
*m_buffer += f.type->name;
|
||||
}
|
||||
else
|
||||
{
|
||||
*m_buffer += "\" start=\"";
|
||||
*m_buffer += std::to_string (f.start);
|
||||
*m_buffer += "\" end=\"";
|
||||
*m_buffer += std::to_string (f.end);
|
||||
}
|
||||
|
||||
*m_buffer += "\"/>\n";
|
||||
}
|
||||
break;
|
||||
|
||||
case TDESC_TYPE_ENUM:
|
||||
*m_buffer += " id=\"";
|
||||
*m_buffer += type->name;
|
||||
*m_buffer += "\">\n";
|
||||
|
||||
for (const tdesc_type_field &f : type->fields)
|
||||
{
|
||||
*m_buffer += " <field name=\"";
|
||||
*m_buffer += f.name;
|
||||
*m_buffer += "\" start=\"";
|
||||
*m_buffer += std::to_string (f.start);
|
||||
*m_buffer += "\"/>\n";
|
||||
}
|
||||
break;
|
||||
|
||||
case TDESC_TYPE_UNION:
|
||||
*m_buffer += " id=\"";
|
||||
*m_buffer += type->name;
|
||||
*m_buffer += "\">\n";
|
||||
|
||||
for (const tdesc_type_field &f : type->fields)
|
||||
{
|
||||
*m_buffer += " <field name=\"";
|
||||
*m_buffer += f.name;
|
||||
*m_buffer += "\" type=\"";
|
||||
*m_buffer += f.type->name;
|
||||
*m_buffer += "\"/>\n";
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
error (_("xml output is not supported type \"%s\"."),
|
||||
type->name.c_str ());
|
||||
}
|
||||
|
||||
*m_buffer += "</";
|
||||
*m_buffer += types[type->kind - TDESC_TYPE_STRUCT];
|
||||
*m_buffer += ">\n";
|
||||
}
|
||||
|
||||
void print_xml_feature::visit (const tdesc_reg *reg)
|
||||
{
|
||||
*m_buffer += "<reg name=\"";
|
||||
*m_buffer += reg->name;
|
||||
*m_buffer += "\" bitsize=\"";
|
||||
*m_buffer += std::to_string (reg->bitsize);
|
||||
*m_buffer += "\" type=\"";
|
||||
*m_buffer += reg->type;
|
||||
*m_buffer += "\" regnum=\"";
|
||||
*m_buffer += std::to_string (reg->target_regnum);
|
||||
if (reg->group.length () > 0)
|
||||
{
|
||||
*m_buffer += "\" group=\"";
|
||||
*m_buffer += reg->group;
|
||||
}
|
||||
*m_buffer += "\"/>\n";
|
||||
}
|
||||
307
gdb/arch/tdesc.h
307
gdb/arch/tdesc.h
@@ -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;
|
||||
@@ -25,6 +31,274 @@ struct tdesc_type_vector;
|
||||
struct tdesc_type_with_fields;
|
||||
struct tdesc_reg;
|
||||
struct target_desc;
|
||||
struct type;
|
||||
|
||||
/* The interface to visit different elements of target description. */
|
||||
|
||||
class tdesc_element_visitor
|
||||
{
|
||||
public:
|
||||
virtual void visit_pre (const target_desc *e) = 0;
|
||||
virtual void visit_post (const target_desc *e) = 0;
|
||||
|
||||
virtual void visit_pre (const tdesc_feature *e) = 0;
|
||||
virtual void visit_post (const tdesc_feature *e) = 0;
|
||||
|
||||
virtual void visit (const tdesc_type_builtin *e) = 0;
|
||||
virtual void visit (const tdesc_type_vector *e) = 0;
|
||||
virtual void visit (const tdesc_type_with_fields *e) = 0;
|
||||
|
||||
virtual void visit (const tdesc_reg *e) = 0;
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/* Construct, if necessary, and return the GDB type implementing this
|
||||
target type for architecture GDBARCH. */
|
||||
|
||||
virtual type *make_gdb_type (struct gdbarch *gdbarch) const = 0;
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
type *make_gdb_type (struct gdbarch *gdbarch) const override;
|
||||
};
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
type *make_gdb_type (struct gdbarch *gdbarch) const override;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
type *make_gdb_type_struct (struct gdbarch *gdbarch) const;
|
||||
type *make_gdb_type_union (struct gdbarch *gdbarch) const;
|
||||
type *make_gdb_type_flags (struct gdbarch *gdbarch) const;
|
||||
type *make_gdb_type_enum (struct gdbarch *gdbarch) const;
|
||||
type *make_gdb_type (struct gdbarch *gdbarch) const override;
|
||||
|
||||
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);
|
||||
@@ -43,9 +317,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 +364,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 */
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -194,6 +194,7 @@ SFILES = \
|
||||
$(srcdir)/arch/arm.c \
|
||||
$(srcdir)/arch/arm-get-next-pcs.c \
|
||||
$(srcdir)/arch/arm-linux.c \
|
||||
$(srcdir)/../arch/tdesc.c \
|
||||
$(srcdir)/common/btrace-common.c \
|
||||
$(srcdir)/common/buffer.c \
|
||||
$(srcdir)/common/cleanups.c \
|
||||
@@ -232,6 +233,7 @@ TAGFILES = $(SOURCES) ${HFILES} ${ALLPARAM} ${POSSLIBS}
|
||||
|
||||
OBS = \
|
||||
agent.o \
|
||||
arch/tdesc.o \
|
||||
ax.o \
|
||||
btrace-common.o \
|
||||
buffer.o \
|
||||
@@ -391,6 +393,7 @@ gdbreplay$(EXEEXT): $(GDBREPLAY_OBS) $(LIBGNU) $(LIBIBERTY)
|
||||
$(XM_CLIBS) $(LIBGNU) $(LIBIBERTY)
|
||||
|
||||
IPA_OBJS = \
|
||||
arch/tdesc-ipa.o \
|
||||
ax-ipa.o \
|
||||
common-utils-ipa.o \
|
||||
errors-ipa.o \
|
||||
|
||||
@@ -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"
|
||||
@@ -83,14 +70,6 @@ case "${target}" in
|
||||
srv_tgtobj="${srv_tgtobj} arch/arm.o"
|
||||
srv_tgtobj="${srv_tgtobj} arch/arm-linux.o"
|
||||
srv_tgtobj="${srv_tgtobj} arch/arm-get-next-pcs.o"
|
||||
srv_xmlfiles="arm/arm-with-iwmmxt.xml"
|
||||
srv_xmlfiles="${srv_xmlfiles} arm/arm-with-vfpv2.xml"
|
||||
srv_xmlfiles="${srv_xmlfiles} arm/arm-with-vfpv3.xml"
|
||||
srv_xmlfiles="${srv_xmlfiles} arm/arm-with-neon.xml"
|
||||
srv_xmlfiles="${srv_xmlfiles} arm/arm-core.xml"
|
||||
srv_xmlfiles="${srv_xmlfiles} arm/xscale-iwmmxt.xml"
|
||||
srv_xmlfiles="${srv_xmlfiles} arm/arm-vfpv2.xml"
|
||||
srv_xmlfiles="${srv_xmlfiles} arm/arm-vfpv3.xml"
|
||||
srv_linux_usrregs=yes
|
||||
srv_linux_regsets=yes
|
||||
srv_linux_thread_db=yes
|
||||
@@ -121,13 +100,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 +121,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 +128,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 +136,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 +340,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 +353,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 +363,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
|
||||
|
||||
@@ -19,14 +19,85 @@
|
||||
#include "tdesc.h"
|
||||
#include "regdef.h"
|
||||
|
||||
#ifndef IN_PROCESS_AGENT
|
||||
|
||||
target_desc::~target_desc ()
|
||||
{
|
||||
for (reg *reg : reg_defs)
|
||||
xfree (reg);
|
||||
|
||||
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)
|
||||
/* 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)
|
||||
{
|
||||
/* Fill in any blank spaces. */
|
||||
while (tdesc->reg_defs.size () < treg->target_regnum)
|
||||
{
|
||||
struct reg *reg = XCNEW (struct reg);
|
||||
reg->name = "";
|
||||
reg->size = 0;
|
||||
reg->offset = offset;
|
||||
tdesc->reg_defs.push_back (reg);
|
||||
}
|
||||
|
||||
gdb_assert (treg->target_regnum == 0
|
||||
|| treg->target_regnum == tdesc->reg_defs.size ());
|
||||
|
||||
struct reg *reg = XCNEW (struct reg);
|
||||
reg->name = treg->name.c_str ();
|
||||
reg->size = treg->bitsize;
|
||||
reg->offset = offset;
|
||||
tdesc->reg_defs.push_back (reg);
|
||||
offset += reg->size;
|
||||
}
|
||||
|
||||
@@ -91,37 +162,14 @@ 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 +177,46 @@ tdesc_get_features_xml (target_desc *tdesc)
|
||||
}
|
||||
#endif
|
||||
|
||||
struct tdesc_type
|
||||
{};
|
||||
|
||||
/* See arch/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);
|
||||
tdesc->features.emplace_back (new_feature);
|
||||
return new_feature;
|
||||
}
|
||||
|
||||
type *tdesc_type_builtin::make_gdb_type (struct gdbarch *gdbarch) const
|
||||
{
|
||||
error (_("Cannot create gdbtypes."));
|
||||
}
|
||||
|
||||
type *tdesc_type_vector::make_gdb_type (struct gdbarch *gdbarch) const
|
||||
{
|
||||
error (_("Cannot create gdbtypes."));
|
||||
}
|
||||
|
||||
type *tdesc_type_with_fields::make_gdb_type (struct gdbarch *gdbarch) const
|
||||
{
|
||||
error (_("Cannot create gdbtypes."));
|
||||
}
|
||||
|
||||
void print_xml_feature::visit_pre (const target_desc *e)
|
||||
{
|
||||
#ifndef IN_PROCESS_AGENT
|
||||
VEC_safe_push (char_ptr, tdesc->features, xstrdup (xml));
|
||||
#endif
|
||||
return tdesc;
|
||||
}
|
||||
*m_buffer += "@<?xml version=\"1.0\"?>\n";
|
||||
*m_buffer += "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">\n";
|
||||
*m_buffer += "<target>\n";
|
||||
*m_buffer += "<architecture>";
|
||||
*m_buffer += e->arch;
|
||||
*m_buffer += "</architecture>\n";
|
||||
|
||||
/* See arch/tdesc.h. */
|
||||
|
||||
tdesc_type_with_fields *
|
||||
tdesc_create_flags (struct tdesc_feature *feature, const char *name,
|
||||
int size)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* See arch/tdesc.h. */
|
||||
|
||||
void
|
||||
tdesc_add_flag (tdesc_type_with_fields *type, int start,
|
||||
const char *flag_name)
|
||||
{}
|
||||
|
||||
/* See arch/tdesc.h. */
|
||||
|
||||
struct tdesc_type *
|
||||
tdesc_named_type (const struct tdesc_feature *feature, const char *id)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* See arch/tdesc.h. */
|
||||
|
||||
tdesc_type_with_fields *
|
||||
tdesc_create_union (struct tdesc_feature *feature, const char *id)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* See arch/tdesc.h. */
|
||||
|
||||
tdesc_type_with_fields *
|
||||
tdesc_create_struct (struct tdesc_feature *feature, const char *id)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* See arch/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)
|
||||
if (e->osabi != nullptr)
|
||||
{
|
||||
struct reg *reg = XCNEW (struct reg);
|
||||
|
||||
reg->name = "";
|
||||
reg->size = 0;
|
||||
tdesc->reg_defs.push_back (reg);
|
||||
*m_buffer += "<osabi>";
|
||||
*m_buffer += e->osabi;
|
||||
*m_buffer += "</osabi>\n";
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
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 arch/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 arch/tdesc.h. */
|
||||
|
||||
void
|
||||
tdesc_add_field (tdesc_type_with_fields *type, const char *field_name,
|
||||
struct tdesc_type *field_type)
|
||||
{}
|
||||
|
||||
/* See arch/tdesc.h. */
|
||||
|
||||
void
|
||||
tdesc_set_struct_size (tdesc_type_with_fields *type, int size)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -24,13 +24,10 @@
|
||||
#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. */
|
||||
@@ -39,6 +36,9 @@ struct target_desc : tdesc_feature
|
||||
/* 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,18 @@ 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. */
|
||||
|
||||
@@ -131,7 +131,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}"
|
||||
@@ -149,7 +149,7 @@ do
|
||||
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}`
|
||||
@@ -180,7 +180,6 @@ echo
|
||||
cat <<EOF
|
||||
#ifndef IN_PROCESS_AGENT
|
||||
result->expedite_regs = expedite_regs_${name};
|
||||
result->xmltarget = xmltarget_${name};
|
||||
#endif
|
||||
|
||||
init_target_desc (result);
|
||||
|
||||
@@ -38,30 +38,6 @@
|
||||
#include "completer.h"
|
||||
#include "readline/tilde.h" /* tilde_expand */
|
||||
|
||||
/* The interface to visit different elements of target description. */
|
||||
|
||||
class tdesc_element_visitor
|
||||
{
|
||||
public:
|
||||
virtual void visit_pre (const target_desc *e) = 0;
|
||||
virtual void visit_post (const target_desc *e) = 0;
|
||||
|
||||
virtual void visit_pre (const tdesc_feature *e) = 0;
|
||||
virtual void visit_post (const tdesc_feature *e) = 0;
|
||||
|
||||
virtual void visit (const tdesc_type_builtin *e) = 0;
|
||||
virtual void visit (const tdesc_type_vector *e) = 0;
|
||||
virtual void visit (const tdesc_type_with_fields *e) = 0;
|
||||
|
||||
virtual void visit (const tdesc_reg *e) = 0;
|
||||
};
|
||||
|
||||
class tdesc_element
|
||||
{
|
||||
public:
|
||||
virtual void accept (tdesc_element_visitor &v) const = 0;
|
||||
};
|
||||
|
||||
/* Types. */
|
||||
|
||||
struct property
|
||||
@@ -74,177 +50,10 @@ struct property
|
||||
std::string value;
|
||||
};
|
||||
|
||||
/* An individual register from a target description. */
|
||||
|
||||
struct tdesc_reg : tdesc_element
|
||||
type *
|
||||
tdesc_type_builtin::make_gdb_type (struct gdbarch *gdbarch) const
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
/* Construct, if necessary, and return the GDB type implementing this
|
||||
target type for architecture GDBARCH. */
|
||||
|
||||
virtual type *make_gdb_type (struct gdbarch *gdbarch) const = 0;
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
type *make_gdb_type (struct gdbarch *gdbarch) const override
|
||||
{
|
||||
switch (this->kind)
|
||||
{
|
||||
/* Predefined types. */
|
||||
@@ -316,25 +125,11 @@ struct tdesc_type_builtin : tdesc_type
|
||||
this->name.c_str (), this->kind);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/* tdesc_type for vector types. */
|
||||
|
||||
struct tdesc_type_vector : tdesc_type
|
||||
type *
|
||||
tdesc_type_vector::make_gdb_type (struct gdbarch *gdbarch) const
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
type *make_gdb_type (struct gdbarch *gdbarch) const override
|
||||
{
|
||||
type *vector_gdb_type = tdesc_find_type (gdbarch, this->name.c_str ());
|
||||
if (vector_gdb_type != NULL)
|
||||
return vector_gdb_type;
|
||||
@@ -344,28 +139,11 @@ struct tdesc_type_vector : tdesc_type
|
||||
TYPE_NAME (vector_gdb_type) = xstrdup (this->name.c_str ());
|
||||
|
||||
return vector_gdb_type;
|
||||
}
|
||||
}
|
||||
|
||||
struct tdesc_type *element_type;
|
||||
int count;
|
||||
};
|
||||
|
||||
/* tdesc_type for struct, union, flags, and enum types. */
|
||||
|
||||
struct tdesc_type_with_fields : tdesc_type
|
||||
type *
|
||||
tdesc_type_with_fields::make_gdb_type_struct (struct gdbarch *gdbarch) const
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
type *make_gdb_type_struct (struct gdbarch *gdbarch) const
|
||||
{
|
||||
type *struct_gdb_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
|
||||
TYPE_NAME (struct_gdb_type) = xstrdup (this->name.c_str ());
|
||||
TYPE_TAG_NAME (struct_gdb_type) = TYPE_NAME (struct_gdb_type);
|
||||
@@ -420,10 +198,11 @@ struct tdesc_type_with_fields : tdesc_type
|
||||
TYPE_LENGTH (struct_gdb_type) = this->size;
|
||||
|
||||
return struct_gdb_type;
|
||||
}
|
||||
}
|
||||
|
||||
type *make_gdb_type_union (struct gdbarch *gdbarch) const
|
||||
{
|
||||
type *
|
||||
tdesc_type_with_fields::make_gdb_type_union (struct gdbarch *gdbarch) const
|
||||
{
|
||||
type *union_gdb_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_UNION);
|
||||
TYPE_NAME (union_gdb_type) = xstrdup (this->name.c_str ());
|
||||
|
||||
@@ -441,10 +220,11 @@ struct tdesc_type_with_fields : tdesc_type
|
||||
}
|
||||
|
||||
return union_gdb_type;
|
||||
}
|
||||
}
|
||||
|
||||
type *make_gdb_type_flags (struct gdbarch *gdbarch) const
|
||||
{
|
||||
type *
|
||||
tdesc_type_with_fields::make_gdb_type_flags (struct gdbarch *gdbarch) const
|
||||
{
|
||||
type *flags_gdb_type = arch_flags_type (gdbarch, this->name.c_str (),
|
||||
this->size * TARGET_CHAR_BIT);
|
||||
|
||||
@@ -459,10 +239,11 @@ struct tdesc_type_with_fields : tdesc_type
|
||||
}
|
||||
|
||||
return flags_gdb_type;
|
||||
}
|
||||
}
|
||||
|
||||
type *make_gdb_type_enum (struct gdbarch *gdbarch) const
|
||||
{
|
||||
type *
|
||||
tdesc_type_with_fields::make_gdb_type_enum (struct gdbarch *gdbarch) const
|
||||
{
|
||||
type *enum_gdb_type = arch_type (gdbarch, TYPE_CODE_ENUM,
|
||||
this->size * TARGET_CHAR_BIT,
|
||||
this->name.c_str ());
|
||||
@@ -479,10 +260,11 @@ struct tdesc_type_with_fields : tdesc_type
|
||||
}
|
||||
|
||||
return enum_gdb_type;
|
||||
}
|
||||
}
|
||||
|
||||
type *make_gdb_type (struct gdbarch *gdbarch) const override
|
||||
{
|
||||
type *
|
||||
tdesc_type_with_fields::make_gdb_type (struct gdbarch *gdbarch) const
|
||||
{
|
||||
type *gdb_type = tdesc_find_type (gdbarch, this->name.c_str ());
|
||||
if (gdb_type != NULL)
|
||||
return gdb_type;
|
||||
@@ -504,87 +286,7 @@ struct tdesc_type_with_fields : tdesc_type
|
||||
this->name.c_str (), this->kind);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
v.visit_pre (this);
|
||||
|
||||
for (const tdesc_type_up &type : types)
|
||||
type->accept (v);
|
||||
|
||||
for (const tdesc_reg_up ® : 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 ®1 = registers[ix];
|
||||
const tdesc_reg_up ®2 = 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. */
|
||||
|
||||
@@ -614,6 +316,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);
|
||||
@@ -957,58 +661,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 arch/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 *
|
||||
@@ -1440,167 +1092,11 @@ tdesc_use_registers (struct gdbarch *gdbarch,
|
||||
tdesc_remote_register_number);
|
||||
set_gdbarch_register_reggroup_p (gdbarch, tdesc_register_reggroup_p);
|
||||
}
|
||||
|
||||
|
||||
/* See arch/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 arch/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 arch/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 arch/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 arch/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 arch/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 arch/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 arch/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 arch/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 arch/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);
|
||||
|
||||
@@ -2068,8 +1564,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
|
||||
@@ -2138,6 +1634,39 @@ private:
|
||||
int m_next_regnum = 0;
|
||||
};
|
||||
|
||||
void print_xml_feature::visit_pre (const target_desc *e)
|
||||
{
|
||||
*m_buffer += "<?xml version=\"1.0\"?>\n";
|
||||
*m_buffer += "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">\n";
|
||||
*m_buffer += "<target>\n";
|
||||
*m_buffer += "<architecture>";
|
||||
*m_buffer += tdesc_architecture (e)->printable_name;
|
||||
*m_buffer += "</architecture>\n";
|
||||
|
||||
if (e->osabi != GDB_OSABI_UNKNOWN)
|
||||
{
|
||||
*m_buffer += "<osabi>";
|
||||
*m_buffer += gdbarch_osabi_name (tdesc_osabi (e));
|
||||
*m_buffer += "</osabi>\n";
|
||||
}
|
||||
}
|
||||
|
||||
/* Return a string which is of XML format, including XML target
|
||||
description to be sent to GDB. */
|
||||
|
||||
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)
|
||||
{
|
||||
@@ -2231,7 +1760,34 @@ maintenance_check_xml_descriptions (const char *dir, int from_tty)
|
||||
= file_read_description_xml (tdesc_xml.data ());
|
||||
|
||||
if (tdesc == NULL || *tdesc != *e.second)
|
||||
{
|
||||
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);
|
||||
const target_desc *t_trans = target_read_description_xml_string (xml);
|
||||
const target_desc *t_trans2 = target_read_description_xml_string (xml2);
|
||||
|
||||
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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user