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 \
|
agent.c \
|
||||||
annotate.c \
|
annotate.c \
|
||||||
arch-utils.c \
|
arch-utils.c \
|
||||||
|
arch/tdesc.c \
|
||||||
auto-load.c \
|
auto-load.c \
|
||||||
auxv.c \
|
auxv.c \
|
||||||
ax-gdb.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
|
#ifndef ARCH_TDESC_H
|
||||||
#define ARCH_TDESC_H 1
|
#define ARCH_TDESC_H 1
|
||||||
|
|
||||||
|
#ifdef GDBSERVER
|
||||||
|
#include "server.h"
|
||||||
|
#else
|
||||||
|
#include "defs.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
struct tdesc_feature;
|
struct tdesc_feature;
|
||||||
struct tdesc_type;
|
struct tdesc_type;
|
||||||
struct tdesc_type_builtin;
|
struct tdesc_type_builtin;
|
||||||
@@ -25,6 +31,274 @@ struct tdesc_type_vector;
|
|||||||
struct tdesc_type_with_fields;
|
struct tdesc_type_with_fields;
|
||||||
struct tdesc_reg;
|
struct tdesc_reg;
|
||||||
struct target_desc;
|
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. */
|
/* Allocate a new target_desc. */
|
||||||
target_desc *allocate_target_description (void);
|
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. */
|
/* Return the created feature named NAME in target description TDESC. */
|
||||||
struct tdesc_feature *tdesc_create_feature (struct target_desc *tdesc,
|
struct tdesc_feature *tdesc_create_feature (struct target_desc *tdesc,
|
||||||
const char *name,
|
const char *name);
|
||||||
const char *xml = nullptr);
|
|
||||||
|
|
||||||
|
|
||||||
/* Return the created vector tdesc_type named NAME in FEATURE. */
|
/* Return the created vector tdesc_type named NAME in FEATURE. */
|
||||||
struct tdesc_type *tdesc_create_vector (struct tdesc_feature *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 regnum, int save_restore, const char *group,
|
||||||
int bitsize, const char *type);
|
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 */
|
#endif /* ARCH_TDESC_H */
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ create_feature_aarch64_core (struct target_desc *result, long regnum)
|
|||||||
{
|
{
|
||||||
struct tdesc_feature *feature;
|
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;
|
tdesc_type_with_fields *type_with_fields;
|
||||||
type_with_fields = tdesc_create_flags (feature, "cpsr_flags", 4);
|
type_with_fields = tdesc_create_flags (feature, "cpsr_flags", 4);
|
||||||
tdesc_add_flag (type_with_fields, 0, "SP");
|
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;
|
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;
|
tdesc_type *element_type;
|
||||||
element_type = tdesc_named_type (feature, "ieee_double");
|
element_type = tdesc_named_type (feature, "ieee_double");
|
||||||
tdesc_create_vector (feature, "v2d", element_type, 2);
|
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;
|
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, "ymm0h", regnum++, 1, NULL, 128, "uint128");
|
||||||
tdesc_create_reg (feature, "ymm1h", 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");
|
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;
|
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;
|
tdesc_type *element_type;
|
||||||
element_type = tdesc_named_type (feature, "uint128");
|
element_type = tdesc_named_type (feature, "uint128");
|
||||||
tdesc_create_vector (feature, "v2ui128", element_type, 2);
|
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;
|
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;
|
tdesc_type_with_fields *type_with_fields;
|
||||||
type_with_fields = tdesc_create_flags (feature, "i386_eflags", 4);
|
type_with_fields = tdesc_create_flags (feature, "i386_eflags", 4);
|
||||||
tdesc_add_flag (type_with_fields, 0, "CF");
|
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;
|
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;
|
regnum = 41;
|
||||||
tdesc_create_reg (feature, "orig_eax", regnum++, 1, NULL, 32, "int");
|
tdesc_create_reg (feature, "orig_eax", regnum++, 1, NULL, 32, "int");
|
||||||
return regnum;
|
return regnum;
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ create_feature_i386_32bit_mpx (struct target_desc *result, long regnum)
|
|||||||
{
|
{
|
||||||
struct tdesc_feature *feature;
|
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;
|
tdesc_type_with_fields *type_with_fields;
|
||||||
type_with_fields = tdesc_create_struct (feature, "br128");
|
type_with_fields = tdesc_create_struct (feature, "br128");
|
||||||
tdesc_type *field_type;
|
tdesc_type *field_type;
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ create_feature_i386_32bit_pkeys (struct target_desc *result, long regnum)
|
|||||||
{
|
{
|
||||||
struct tdesc_feature *feature;
|
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");
|
tdesc_create_reg (feature, "pkru", regnum++, 1, NULL, 32, "uint32");
|
||||||
return regnum;
|
return regnum;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ create_feature_i386_32bit_sse (struct target_desc *result, long regnum)
|
|||||||
{
|
{
|
||||||
struct tdesc_feature *feature;
|
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;
|
tdesc_type *element_type;
|
||||||
element_type = tdesc_named_type (feature, "ieee_single");
|
element_type = tdesc_named_type (feature, "ieee_single");
|
||||||
tdesc_create_vector (feature, "v4f", element_type, 4);
|
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;
|
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, "ymm0h", regnum++, 1, NULL, 128, "uint128");
|
||||||
tdesc_create_reg (feature, "ymm1h", 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");
|
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;
|
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;
|
tdesc_type *element_type;
|
||||||
element_type = tdesc_named_type (feature, "ieee_single");
|
element_type = tdesc_named_type (feature, "ieee_single");
|
||||||
tdesc_create_vector (feature, "v4f", element_type, 4);
|
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;
|
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;
|
tdesc_type_with_fields *type_with_fields;
|
||||||
type_with_fields = tdesc_create_flags (feature, "i386_eflags", 4);
|
type_with_fields = tdesc_create_flags (feature, "i386_eflags", 4);
|
||||||
tdesc_add_flag (type_with_fields, 0, "CF");
|
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;
|
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;
|
regnum = 57;
|
||||||
tdesc_create_reg (feature, "orig_rax", regnum++, 1, NULL, 64, "int");
|
tdesc_create_reg (feature, "orig_rax", regnum++, 1, NULL, 64, "int");
|
||||||
return regnum;
|
return regnum;
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ create_feature_i386_64bit_mpx (struct target_desc *result, long regnum)
|
|||||||
{
|
{
|
||||||
struct tdesc_feature *feature;
|
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;
|
tdesc_type_with_fields *type_with_fields;
|
||||||
type_with_fields = tdesc_create_struct (feature, "br128");
|
type_with_fields = tdesc_create_struct (feature, "br128");
|
||||||
tdesc_type *field_type;
|
tdesc_type *field_type;
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ create_feature_i386_64bit_pkeys (struct target_desc *result, long regnum)
|
|||||||
{
|
{
|
||||||
struct tdesc_feature *feature;
|
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");
|
tdesc_create_reg (feature, "pkru", regnum++, 1, NULL, 32, "uint32");
|
||||||
return regnum;
|
return regnum;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ create_feature_i386_64bit_segments (struct target_desc *result, long regnum)
|
|||||||
{
|
{
|
||||||
struct tdesc_feature *feature;
|
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, "fs_base", regnum++, 1, NULL, 64, "int");
|
||||||
tdesc_create_reg (feature, "gs_base", regnum++, 1, NULL, 64, "int");
|
tdesc_create_reg (feature, "gs_base", regnum++, 1, NULL, 64, "int");
|
||||||
return regnum;
|
return regnum;
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ create_feature_i386_64bit_sse (struct target_desc *result, long regnum)
|
|||||||
{
|
{
|
||||||
struct tdesc_feature *feature;
|
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;
|
tdesc_type *element_type;
|
||||||
element_type = tdesc_named_type (feature, "ieee_single");
|
element_type = tdesc_named_type (feature, "ieee_single");
|
||||||
tdesc_create_vector (feature, "v4f", element_type, 4);
|
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;
|
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;
|
tdesc_type_with_fields *type_with_fields;
|
||||||
type_with_fields = tdesc_create_flags (feature, "i386_eflags", 4);
|
type_with_fields = tdesc_create_flags (feature, "i386_eflags", 4);
|
||||||
tdesc_add_flag (type_with_fields, 0, "CF");
|
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;
|
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, "TSR", regnum++, 1, NULL, 32, "uint32");
|
||||||
tdesc_create_reg (feature, "ILC", 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");
|
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;
|
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, "A0", regnum++, 1, NULL, 32, "uint32");
|
||||||
tdesc_create_reg (feature, "A1", 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");
|
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;
|
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, "A16", regnum++, 1, NULL, 32, "uint32");
|
||||||
tdesc_create_reg (feature, "A17", 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");
|
tdesc_create_reg (feature, "A18", regnum++, 1, NULL, 32, "uint32");
|
||||||
|
|||||||
@@ -194,6 +194,7 @@ SFILES = \
|
|||||||
$(srcdir)/arch/arm.c \
|
$(srcdir)/arch/arm.c \
|
||||||
$(srcdir)/arch/arm-get-next-pcs.c \
|
$(srcdir)/arch/arm-get-next-pcs.c \
|
||||||
$(srcdir)/arch/arm-linux.c \
|
$(srcdir)/arch/arm-linux.c \
|
||||||
|
$(srcdir)/../arch/tdesc.c \
|
||||||
$(srcdir)/common/btrace-common.c \
|
$(srcdir)/common/btrace-common.c \
|
||||||
$(srcdir)/common/buffer.c \
|
$(srcdir)/common/buffer.c \
|
||||||
$(srcdir)/common/cleanups.c \
|
$(srcdir)/common/cleanups.c \
|
||||||
@@ -232,6 +233,7 @@ TAGFILES = $(SOURCES) ${HFILES} ${ALLPARAM} ${POSSLIBS}
|
|||||||
|
|
||||||
OBS = \
|
OBS = \
|
||||||
agent.o \
|
agent.o \
|
||||||
|
arch/tdesc.o \
|
||||||
ax.o \
|
ax.o \
|
||||||
btrace-common.o \
|
btrace-common.o \
|
||||||
buffer.o \
|
buffer.o \
|
||||||
@@ -391,6 +393,7 @@ gdbreplay$(EXEEXT): $(GDBREPLAY_OBS) $(LIBGNU) $(LIBIBERTY)
|
|||||||
$(XM_CLIBS) $(LIBGNU) $(LIBIBERTY)
|
$(XM_CLIBS) $(LIBGNU) $(LIBIBERTY)
|
||||||
|
|
||||||
IPA_OBJS = \
|
IPA_OBJS = \
|
||||||
|
arch/tdesc-ipa.o \
|
||||||
ax-ipa.o \
|
ax-ipa.o \
|
||||||
common-utils-ipa.o \
|
common-utils-ipa.o \
|
||||||
errors-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"
|
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
|
# Linux object files. This is so we don't have to repeat
|
||||||
# these files over and over again.
|
# 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"
|
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 arch/aarch64.o"
|
||||||
srv_tgtobj="$srv_tgtobj linux-aarch64-tdesc.o"
|
srv_tgtobj="$srv_tgtobj linux-aarch64-tdesc.o"
|
||||||
srv_tgtobj="${srv_tgtobj} $srv_linux_obj"
|
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_regsets=yes
|
||||||
srv_linux_thread_db=yes
|
srv_linux_thread_db=yes
|
||||||
ipa_obj="linux-aarch64-ipa.o"
|
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.o"
|
||||||
srv_tgtobj="${srv_tgtobj} arch/arm-linux.o"
|
srv_tgtobj="${srv_tgtobj} arch/arm-linux.o"
|
||||||
srv_tgtobj="${srv_tgtobj} arch/arm-get-next-pcs.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_usrregs=yes
|
||||||
srv_linux_regsets=yes
|
srv_linux_regsets=yes
|
||||||
srv_linux_thread_db=yes
|
srv_linux_thread_db=yes
|
||||||
@@ -121,13 +100,10 @@ case "${target}" in
|
|||||||
i[34567]86-*-cygwin*) srv_regobj=""
|
i[34567]86-*-cygwin*) srv_regobj=""
|
||||||
srv_tgtobj="x86-low.o x86-dregs.o win32-low.o win32-i386-low.o"
|
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} arch/i386.o"
|
||||||
srv_xmlfiles="$srv_i386_xmlfiles"
|
|
||||||
;;
|
;;
|
||||||
i[34567]86-*-linux*) srv_regobj="$srv_i386_linux_regobj"
|
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
|
if test "$gdb_cv_i386_is_x86_64" = yes ; then
|
||||||
srv_regobj="$srv_regobj $srv_amd64_linux_regobj"
|
srv_regobj="$srv_regobj $srv_amd64_linux_regobj"
|
||||||
srv_xmlfiles="${srv_xmlfiles} $srv_amd64_linux_xmlfiles"
|
|
||||||
srv_tgtobj="amd64-linux-siginfo.o"
|
srv_tgtobj="amd64-linux-siginfo.o"
|
||||||
fi
|
fi
|
||||||
srv_tgtobj="${srv_tgtobj} arch/i386.o"
|
srv_tgtobj="${srv_tgtobj} arch/i386.o"
|
||||||
@@ -145,9 +121,6 @@ case "${target}" in
|
|||||||
i[34567]86-*-lynxos*) srv_regobj=""
|
i[34567]86-*-lynxos*) srv_regobj=""
|
||||||
srv_tgtobj="lynx-low.o lynx-i386-low.o fork-child.o fork-inferior.o"
|
srv_tgtobj="lynx-low.o lynx-i386-low.o fork-child.o fork-inferior.o"
|
||||||
srv_tgtobj="${srv_tgtobj} arch/i386.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
|
srv_lynxos=yes
|
||||||
;;
|
;;
|
||||||
i[34567]86-*-mingw32ce*)
|
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="x86-low.o x86-dregs.o win32-low.o win32-i386-low.o"
|
||||||
srv_tgtobj="${srv_tgtobj} arch/i386.o"
|
srv_tgtobj="${srv_tgtobj} arch/i386.o"
|
||||||
srv_tgtobj="${srv_tgtobj} wincecompat.o"
|
srv_tgtobj="${srv_tgtobj} wincecompat.o"
|
||||||
srv_xmlfiles="$srv_i386_xmlfiles"
|
|
||||||
# hostio_last_error implementation is in win32-low.c
|
# hostio_last_error implementation is in win32-low.c
|
||||||
srv_hostio_err_objs=""
|
srv_hostio_err_objs=""
|
||||||
srv_mingw=yes
|
srv_mingw=yes
|
||||||
@@ -164,12 +136,10 @@ case "${target}" in
|
|||||||
i[34567]86-*-mingw*) srv_regobj=""
|
i[34567]86-*-mingw*) srv_regobj=""
|
||||||
srv_tgtobj="x86-low.o x86-dregs.o win32-low.o win32-i386-low.o"
|
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} arch/i386.o"
|
||||||
srv_xmlfiles="$srv_i386_xmlfiles"
|
|
||||||
srv_mingw=yes
|
srv_mingw=yes
|
||||||
;;
|
;;
|
||||||
i[34567]86-*-nto*) srv_regobj=""
|
i[34567]86-*-nto*) srv_regobj=""
|
||||||
srv_tgtobj="nto-low.o nto-x86-low.o arch/i386.o"
|
srv_tgtobj="nto-low.o nto-x86-low.o arch/i386.o"
|
||||||
srv_xmlfiles="$srv_i386_xmlfiles"
|
|
||||||
srv_qnx="yes"
|
srv_qnx="yes"
|
||||||
;;
|
;;
|
||||||
ia64-*-linux*) srv_regobj=reg-ia64.o
|
ia64-*-linux*) srv_regobj=reg-ia64.o
|
||||||
@@ -370,9 +340,6 @@ case "${target}" in
|
|||||||
else
|
else
|
||||||
srv_regobj=""
|
srv_regobj=""
|
||||||
fi
|
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_linux_obj linux-tic6x-low.o"
|
||||||
srv_tgtobj="${srv_tgtobj} arch/tic6x.o"
|
srv_tgtobj="${srv_tgtobj} arch/tic6x.o"
|
||||||
srv_linux_regsets=yes
|
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} linux-btrace.o x86-linux.o"
|
||||||
srv_tgtobj="${srv_tgtobj} x86-linux-dregs.o"
|
srv_tgtobj="${srv_tgtobj} x86-linux-dregs.o"
|
||||||
srv_tgtobj="${srv_tgtobj} amd64-linux-siginfo.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_usrregs=yes # This is for i386 progs.
|
||||||
srv_linux_regsets=yes
|
srv_linux_regsets=yes
|
||||||
srv_linux_thread_db=yes
|
srv_linux_thread_db=yes
|
||||||
@@ -397,13 +363,11 @@ case "${target}" in
|
|||||||
x86_64-*-mingw*) srv_regobj=""
|
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="x86-low.o x86-dregs.o i387-fp.o win32-low.o win32-i386-low.o"
|
||||||
srv_tgtobj="${srv_tgtobj} arch/amd64.o"
|
srv_tgtobj="${srv_tgtobj} arch/amd64.o"
|
||||||
srv_xmlfiles="$srv_i386_xmlfiles $srv_amd64_xmlfiles"
|
|
||||||
srv_mingw=yes
|
srv_mingw=yes
|
||||||
;;
|
;;
|
||||||
x86_64-*-cygwin*) srv_regobj=""
|
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="x86-low.o x86-dregs.o i387-fp.o win32-low.o win32-i386-low.o"
|
||||||
srv_tgtobj="${srv_tgtobj} arch/amd64.o"
|
srv_tgtobj="${srv_tgtobj} arch/amd64.o"
|
||||||
srv_xmlfiles="$srv_i386_xmlfiles"
|
|
||||||
;;
|
;;
|
||||||
|
|
||||||
xtensa*-*-linux*) srv_regobj=reg-xtensa.o
|
xtensa*-*-linux*) srv_regobj=reg-xtensa.o
|
||||||
|
|||||||
@@ -19,14 +19,85 @@
|
|||||||
#include "tdesc.h"
|
#include "tdesc.h"
|
||||||
#include "regdef.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
|
void
|
||||||
init_target_desc (struct target_desc *tdesc)
|
init_target_desc (struct target_desc *tdesc)
|
||||||
{
|
{
|
||||||
int offset = 0;
|
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;
|
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;
|
offset += reg->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,37 +162,14 @@ tdesc_get_features_xml (target_desc *tdesc)
|
|||||||
{
|
{
|
||||||
/* Either .xmltarget or .features is not NULL. */
|
/* Either .xmltarget or .features is not NULL. */
|
||||||
gdb_assert (tdesc->xmltarget != NULL
|
gdb_assert (tdesc->xmltarget != NULL
|
||||||
|| (tdesc->features != NULL
|
|| (!tdesc->features.empty ()
|
||||||
&& tdesc->arch != NULL));
|
&& tdesc->arch != NULL));
|
||||||
|
|
||||||
if (tdesc->xmltarget == NULL)
|
if (tdesc->xmltarget == NULL)
|
||||||
{
|
{
|
||||||
std::string buffer ("@<?xml version=\"1.0\"?>");
|
std::string buffer ("");
|
||||||
|
print_xml_feature v (&buffer);
|
||||||
buffer += "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">";
|
tdesc->accept (v);
|
||||||
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>";
|
|
||||||
|
|
||||||
tdesc->xmltarget = xstrdup (buffer.c_str ());
|
tdesc->xmltarget = xstrdup (buffer.c_str ());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,113 +177,46 @@ tdesc_get_features_xml (target_desc *tdesc)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct tdesc_type
|
|
||||||
{};
|
|
||||||
|
|
||||||
/* See arch/tdesc.h. */
|
/* See arch/tdesc.h. */
|
||||||
|
|
||||||
struct tdesc_feature *
|
struct tdesc_feature *
|
||||||
tdesc_create_feature (struct target_desc *tdesc, const char *name,
|
tdesc_create_feature (struct target_desc *tdesc, const char *name)
|
||||||
const char *xml)
|
{
|
||||||
|
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
|
#ifndef IN_PROCESS_AGENT
|
||||||
VEC_safe_push (char_ptr, tdesc->features, xstrdup (xml));
|
*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";
|
||||||
|
|
||||||
|
if (e->osabi != nullptr)
|
||||||
|
{
|
||||||
|
*m_buffer += "<osabi>";
|
||||||
|
*m_buffer += e->osabi;
|
||||||
|
*m_buffer += "</osabi>\n";
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
return tdesc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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)
|
|
||||||
{
|
|
||||||
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 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 "regdef.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
struct tdesc_feature
|
|
||||||
{};
|
|
||||||
|
|
||||||
/* A target description. Inherit from tdesc_feature so that target_desc
|
/* A target description. Inherit from tdesc_feature so that target_desc
|
||||||
can be used as tdesc_feature. */
|
can be used as tdesc_feature. */
|
||||||
|
|
||||||
struct target_desc : tdesc_feature
|
struct target_desc : tdesc_element
|
||||||
{
|
{
|
||||||
/* A vector of elements of register definitions that
|
/* A vector of elements of register definitions that
|
||||||
describe the inferior's register set. */
|
describe the inferior's register set. */
|
||||||
@@ -39,6 +36,9 @@ struct target_desc : tdesc_feature
|
|||||||
/* The register cache size, in bytes. */
|
/* The register cache size, in bytes. */
|
||||||
int registers_size;
|
int registers_size;
|
||||||
|
|
||||||
|
/* XML features in this target description. */
|
||||||
|
std::vector<tdesc_feature_up> features;
|
||||||
|
|
||||||
#ifndef IN_PROCESS_AGENT
|
#ifndef IN_PROCESS_AGENT
|
||||||
/* An array of register names. These are the "expedite" registers:
|
/* An array of register names. These are the "expedite" registers:
|
||||||
registers whose values are sent along with stop replies. */
|
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. */
|
fields features, arch, and osabi in tdesc_get_features_xml. */
|
||||||
const char *xmltarget = NULL;
|
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. */
|
/* The value of <architecture> element in the XML, replying GDB. */
|
||||||
const char *arch = NULL;
|
const char *arch = NULL;
|
||||||
|
|
||||||
@@ -67,55 +64,18 @@ public:
|
|||||||
: registers_size (0)
|
: registers_size (0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
~target_desc ()
|
~target_desc ();
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (reg *reg : reg_defs)
|
bool operator== (const target_desc &other) const;
|
||||||
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);
|
return !(*this == other);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void accept (tdesc_element_visitor &v) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Copy target description SRC to DEST. */
|
/* Copy target description SRC to DEST. */
|
||||||
|
|||||||
@@ -131,7 +131,7 @@ do
|
|||||||
echo "{"
|
echo "{"
|
||||||
echo " static struct target_desc tdesc_${name}_s;"
|
echo " static struct target_desc tdesc_${name}_s;"
|
||||||
echo " struct target_desc *result = &tdesc_${name}_s;"
|
echo " struct target_desc *result = &tdesc_${name}_s;"
|
||||||
|
echo " struct tdesc_feature *feature = tdesc_create_feature (result, \"${name}\");"
|
||||||
continue
|
continue
|
||||||
elif test "${type}" = "xmltarget"; then
|
elif test "${type}" = "xmltarget"; then
|
||||||
xmltarget="${entry}"
|
xmltarget="${entry}"
|
||||||
@@ -149,7 +149,7 @@ do
|
|||||||
echo "$0: $1 does not specify \`\`name''." 1>&2
|
echo "$0: $1 does not specify \`\`name''." 1>&2
|
||||||
exit 1
|
exit 1
|
||||||
else
|
else
|
||||||
echo " tdesc_create_reg ((struct tdesc_feature *) result, \"${entry}\","
|
echo " tdesc_create_reg (feature, \"${entry}\","
|
||||||
echo " 0, 0, NULL, ${type}, NULL);"
|
echo " 0, 0, NULL, ${type}, NULL);"
|
||||||
|
|
||||||
offset=`expr ${offset} + ${type}`
|
offset=`expr ${offset} + ${type}`
|
||||||
@@ -180,7 +180,6 @@ echo
|
|||||||
cat <<EOF
|
cat <<EOF
|
||||||
#ifndef IN_PROCESS_AGENT
|
#ifndef IN_PROCESS_AGENT
|
||||||
result->expedite_regs = expedite_regs_${name};
|
result->expedite_regs = expedite_regs_${name};
|
||||||
result->xmltarget = xmltarget_${name};
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
init_target_desc (result);
|
init_target_desc (result);
|
||||||
|
|||||||
@@ -38,30 +38,6 @@
|
|||||||
#include "completer.h"
|
#include "completer.h"
|
||||||
#include "readline/tilde.h" /* tilde_expand */
|
#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. */
|
/* Types. */
|
||||||
|
|
||||||
struct property
|
struct property
|
||||||
@@ -74,176 +50,9 @@ struct property
|
|||||||
std::string value;
|
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)
|
switch (this->kind)
|
||||||
{
|
{
|
||||||
@@ -317,23 +126,9 @@ struct tdesc_type_builtin : tdesc_type
|
|||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
/* tdesc_type for vector types. */
|
type *
|
||||||
|
tdesc_type_vector::make_gdb_type (struct gdbarch *gdbarch) const
|
||||||
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
|
|
||||||
{
|
{
|
||||||
type *vector_gdb_type = tdesc_find_type (gdbarch, this->name.c_str ());
|
type *vector_gdb_type = tdesc_find_type (gdbarch, this->name.c_str ());
|
||||||
if (vector_gdb_type != NULL)
|
if (vector_gdb_type != NULL)
|
||||||
@@ -346,25 +141,8 @@ struct tdesc_type_vector : tdesc_type
|
|||||||
return vector_gdb_type;
|
return vector_gdb_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct tdesc_type *element_type;
|
type *
|
||||||
int count;
|
tdesc_type_with_fields::make_gdb_type_struct (struct gdbarch *gdbarch) const
|
||||||
};
|
|
||||||
|
|
||||||
/* 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 *struct_gdb_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
|
type *struct_gdb_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
|
||||||
TYPE_NAME (struct_gdb_type) = xstrdup (this->name.c_str ());
|
TYPE_NAME (struct_gdb_type) = xstrdup (this->name.c_str ());
|
||||||
@@ -422,7 +200,8 @@ struct tdesc_type_with_fields : tdesc_type
|
|||||||
return struct_gdb_type;
|
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 *union_gdb_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_UNION);
|
||||||
TYPE_NAME (union_gdb_type) = xstrdup (this->name.c_str ());
|
TYPE_NAME (union_gdb_type) = xstrdup (this->name.c_str ());
|
||||||
@@ -443,7 +222,8 @@ struct tdesc_type_with_fields : tdesc_type
|
|||||||
return union_gdb_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 (),
|
type *flags_gdb_type = arch_flags_type (gdbarch, this->name.c_str (),
|
||||||
this->size * TARGET_CHAR_BIT);
|
this->size * TARGET_CHAR_BIT);
|
||||||
@@ -461,7 +241,8 @@ struct tdesc_type_with_fields : tdesc_type
|
|||||||
return flags_gdb_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,
|
type *enum_gdb_type = arch_type (gdbarch, TYPE_CODE_ENUM,
|
||||||
this->size * TARGET_CHAR_BIT,
|
this->size * TARGET_CHAR_BIT,
|
||||||
@@ -481,7 +262,8 @@ struct tdesc_type_with_fields : tdesc_type
|
|||||||
return enum_gdb_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 ());
|
type *gdb_type = tdesc_find_type (gdbarch, this->name.c_str ());
|
||||||
if (gdb_type != NULL)
|
if (gdb_type != NULL)
|
||||||
@@ -506,86 +288,6 @@ struct tdesc_type_with_fields : tdesc_type
|
|||||||
return NULL;
|
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. */
|
/* A target description. */
|
||||||
|
|
||||||
struct target_desc : tdesc_element
|
struct target_desc : tdesc_element
|
||||||
@@ -614,6 +316,8 @@ struct target_desc : tdesc_element
|
|||||||
/* The features associated with this target. */
|
/* The features associated with this target. */
|
||||||
std::vector<tdesc_feature_up> features;
|
std::vector<tdesc_feature_up> features;
|
||||||
|
|
||||||
|
char *xmltarget = nullptr;
|
||||||
|
|
||||||
void accept (tdesc_element_visitor &v) const override
|
void accept (tdesc_element_visitor &v) const override
|
||||||
{
|
{
|
||||||
v.visit_pre (this);
|
v.visit_pre (this);
|
||||||
@@ -957,58 +661,6 @@ tdesc_feature_name (const struct tdesc_feature *feature)
|
|||||||
return feature->name.c_str ();
|
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. */
|
/* Lookup type associated with ID. */
|
||||||
|
|
||||||
struct type *
|
struct type *
|
||||||
@@ -1440,167 +1092,11 @@ tdesc_use_registers (struct gdbarch *gdbarch,
|
|||||||
tdesc_remote_register_number);
|
tdesc_remote_register_number);
|
||||||
set_gdbarch_register_reggroup_p (gdbarch, tdesc_register_reggroup_p);
|
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. */
|
/* See arch/tdesc.h. */
|
||||||
|
|
||||||
struct tdesc_feature *
|
struct tdesc_feature *
|
||||||
tdesc_create_feature (struct target_desc *tdesc, const char *name,
|
tdesc_create_feature (struct target_desc *tdesc, const char *name)
|
||||||
const char *xml)
|
|
||||||
{
|
{
|
||||||
struct tdesc_feature *new_feature = new tdesc_feature (name);
|
struct tdesc_feature *new_feature = new tdesc_feature (name);
|
||||||
|
|
||||||
@@ -2068,8 +1564,8 @@ public:
|
|||||||
printf_unfiltered (" struct tdesc_feature *feature;\n");
|
printf_unfiltered (" struct tdesc_feature *feature;\n");
|
||||||
|
|
||||||
printf_unfiltered
|
printf_unfiltered
|
||||||
("\n feature = tdesc_create_feature (result, \"%s\", \"%s\");\n",
|
("\n feature = tdesc_create_feature (result, \"%s\");\n",
|
||||||
e->name.c_str (), lbasename (m_filename_after_features.c_str ()));
|
e->name.c_str ());
|
||||||
}
|
}
|
||||||
|
|
||||||
void visit_post (const tdesc_feature *e) override
|
void visit_post (const tdesc_feature *e) override
|
||||||
@@ -2138,6 +1634,39 @@ private:
|
|||||||
int m_next_regnum = 0;
|
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
|
static void
|
||||||
maint_print_c_tdesc_cmd (const char *args, int from_tty)
|
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 ());
|
= file_read_description_xml (tdesc_xml.data ());
|
||||||
|
|
||||||
if (tdesc == NULL || *tdesc != *e.second)
|
if (tdesc == NULL || *tdesc != *e.second)
|
||||||
|
{
|
||||||
|
printf_filtered ( _("Descriptions for %s do not match\n"), e.first);
|
||||||
failed++;
|
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"),
|
printf_filtered (_("Tested %lu XML files, %d failed\n"),
|
||||||
(long) selftests::xml_tdesc.size (), failed);
|
(long) selftests::xml_tdesc.size (), failed);
|
||||||
|
|||||||
@@ -752,3 +752,12 @@ target_fetch_description_xml (struct target_ops *ops)
|
|||||||
return output;
|
return output;
|
||||||
#endif
|
#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. */
|
otherwise. */
|
||||||
gdb::optional<std::string> target_fetch_description_xml (target_ops *ops);
|
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 */
|
#endif /* XML_TDESC_H */
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user