Commonise tdesc_reg and makes use of it in gdbserver tdesc

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

gdbserver/
	* Makefile.in: Add common/tdesc.c
	* tdesc.c (init_target_desc): init all reg_defs from register vector.
	(tdesc_create_reg): Create tdesc_reg.
	* tdesc.h (tdesc_feature): Add register vector.
This commit is contained in:
Alan Hayward 2018-04-18 11:28:51 +01:00
parent a7504f87d4
commit ea3e7d7179
10 changed files with 190 additions and 129 deletions

View File

@ -1,3 +1,17 @@
2018-04-18 Alan Hayward <alan.hayward@arm.com>
* Makefile.in: Add arch/tdesc.c
* common/tdesc.c: New file.
* common/tdesc.h (tdesc_element_visitor): Move to here.
(tdesc_element): Likewise.
(tdesc_reg): Likewise.
(tdesc_reg_up): Likewise.
* regformats/regdef.h (reg): Add offset to constructors.
* target-descriptions.c (tdesc_element_visitor): Move from here.
(tdesc_element): Likewise.
(tdesc_reg): Likewise.
(tdesc_reg_up): Likewise.
2018-04-17 Tom Tromey <tom@tromey.com>
* dwarf2read.c (quirk_rust_enum): Conditionally drop the

View File

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

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

@ -0,0 +1,35 @@
/* Target description support for GDB.
Copyright (C) 2018 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/>. */
#include "common-defs.h"
#include "common/tdesc.h"
tdesc_reg::tdesc_reg (struct tdesc_feature *feature, const std::string &name_,
int regnum, int save_restore_, const char *group_,
int bitsize_, const char *type_)
: name (name_), target_regnum (regnum),
save_restore (save_restore_),
group (group_ != NULL ? group_ : ""),
bitsize (bitsize_),
type (type_ != NULL ? type_ : "<unknown>")
{
/* If the register's type is target-defined, look it up now. We may not
have easy access to the containing feature when we want it later. */
tdesc_type = tdesc_named_type (feature, type.c_str ());
}

View File

@ -26,6 +26,111 @@ struct tdesc_type_with_fields;
struct tdesc_reg;
struct target_desc;
/* The interface to visit different elements of target description. */
class tdesc_element_visitor
{
public:
virtual void visit_pre (const target_desc *e)
{}
virtual void visit_post (const target_desc *e)
{}
virtual void visit_pre (const tdesc_feature *e)
{}
virtual void visit_post (const tdesc_feature *e)
{}
virtual void visit (const tdesc_type_builtin *e)
{}
virtual void visit (const tdesc_type_vector *e)
{}
virtual void visit (const tdesc_type_with_fields *e)
{}
virtual void visit (const tdesc_reg *e)
{}
};
class tdesc_element
{
public:
virtual void accept (tdesc_element_visitor &v) const = 0;
};
/* An individual register from a target description. */
struct tdesc_reg : tdesc_element
{
tdesc_reg (struct tdesc_feature *feature, const std::string &name_,
int regnum, int save_restore_, const char *group_,
int bitsize_, const char *type_);
virtual ~tdesc_reg () = default;
DISABLE_COPY_AND_ASSIGN (tdesc_reg);
/* The name of this register. In standard features, it may be
recognized by the architecture support code, or it may be purely
for the user. */
std::string name;
/* The register number used by this target to refer to this
register. This is used for remote p/P packets and to determine
the ordering of registers in the remote g/G packets. */
long target_regnum;
/* If this flag is set, GDB should save and restore this register
around calls to an inferior function. */
int save_restore;
/* The name of the register group containing this register, or empty
if the group should be automatically determined from the
register's type. If this is "general", "float", or "vector", the
corresponding "info" command should display this register's
value. It can be an arbitrary string, but should be limited to
alphanumeric characters and internal hyphens. Currently other
strings are ignored (treated as empty). */
std::string group;
/* The size of the register, in bits. */
int bitsize;
/* The type of the register. This string corresponds to either
a named type from the target description or a predefined
type from GDB. */
std::string type;
/* The target-described type corresponding to TYPE, if found. */
struct tdesc_type *tdesc_type;
void accept (tdesc_element_visitor &v) const override
{
v.visit (this);
}
bool operator== (const tdesc_reg &other) const
{
return (name == other.name
&& target_regnum == other.target_regnum
&& save_restore == other.save_restore
&& bitsize == other.bitsize
&& group == other.group
&& type == other.type);
}
bool operator!= (const tdesc_reg &other) const
{
return !(*this == other);
}
};
typedef std::unique_ptr<tdesc_reg> tdesc_reg_up;
/* Allocate a new target_desc. */
target_desc *allocate_target_description (void);

View File

@ -1,3 +1,11 @@
2018-04-18 Alan Hayward <alan.hayward@arm.com>
* Makefile.in: Add common/tdesc.c
* tdesc.c (init_target_desc): init all reg_defs from register
vector.
(tdesc_create_reg): Create tdesc_reg.
* tdesc.h (tdesc_feature): Add register vector.
2018-03-30 Simon Marchi <simon.marchi@polymtl.ca>
* tdesc.h (struct target_desc) <features>: Change type to

View File

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

View File

@ -54,10 +54,19 @@ init_target_desc (struct target_desc *tdesc)
{
int offset = 0;
for (reg &reg : tdesc->reg_defs)
/* Go through all the features and populate reg_defs. */
for (const tdesc_reg_up &treg : tdesc->registers)
{
reg.offset = offset;
offset += reg.size;
int regnum = treg->target_regnum;
/* Register number will increase (possibly with gaps) or be zero. */
gdb_assert (regnum == 0 || regnum >= tdesc->reg_defs.size ());
if (regnum != 0)
tdesc->reg_defs.resize (regnum, reg (offset));
tdesc->reg_defs.emplace_back (treg->name.c_str (), offset, treg->bitsize);
offset += treg->bitsize;
}
tdesc->registers_size = offset / 8;
@ -222,12 +231,10 @@ tdesc_create_reg (struct tdesc_feature *feature, const char *name,
{
struct target_desc *tdesc = (struct target_desc *) feature;
gdb_assert (regnum == 0 || regnum >= tdesc->reg_defs.size ());
tdesc_reg *reg = new tdesc_reg (feature, name, regnum, save_restore,
group, bitsize, type);
if (regnum != 0)
tdesc->reg_defs.resize (regnum);
tdesc->reg_defs.emplace_back (name, bitsize);
tdesc->registers.emplace_back (reg);
}
/* See common/tdesc.h. */

View File

@ -25,7 +25,10 @@
#include <vector>
struct tdesc_feature
{};
{
/* The registers associated with this feature. */
std::vector<tdesc_reg_up> registers;
};
/* A target description. Inherit from tdesc_feature so that target_desc
can be used as tdesc_feature. */

View File

@ -21,15 +21,15 @@
struct reg
{
reg ()
reg (int _offset)
: name (""),
offset (0),
offset (_offset),
size (0)
{}
reg (const char *_name, int _size)
reg (const char *_name, int _offset, int _size)
: name (_name),
offset (0),
offset (_offset),
size (_size)
{}

View File

@ -38,44 +38,6 @@
#include "completer.h"
#include "readline/tilde.h" /* tilde_expand */
static type *make_gdb_type (struct gdbarch *gdbarch, struct tdesc_type *ttype);
/* The interface to visit different elements of target description. */
class tdesc_element_visitor
{
public:
virtual void visit_pre (const target_desc *e)
{}
virtual void visit_post (const target_desc *e)
{}
virtual void visit_pre (const tdesc_feature *e)
{}
virtual void visit_post (const tdesc_feature *e)
{}
virtual void visit (const tdesc_type_builtin *e)
{}
virtual void visit (const tdesc_type_vector *e)
{}
virtual void visit (const tdesc_type_with_fields *e)
{}
virtual void visit (const tdesc_reg *e)
{}
};
class tdesc_element
{
public:
virtual void accept (tdesc_element_visitor &v) const = 0;
};
/* Types. */
struct property
@ -88,84 +50,6 @@ struct property
std::string value;
};
/* An individual register from a target description. */
struct tdesc_reg : tdesc_element
{
tdesc_reg (struct tdesc_feature *feature, const std::string &name_,
int regnum, int save_restore_, const char *group_,
int bitsize_, const char *type_)
: name (name_), target_regnum (regnum),
save_restore (save_restore_),
group (group_ != NULL ? group_ : ""),
bitsize (bitsize_),
type (type_ != NULL ? type_ : "<unknown>")
{
/* If the register's type is target-defined, look it up now. We may not
have easy access to the containing feature when we want it later. */
tdesc_type = tdesc_named_type (feature, type.c_str ());
}
virtual ~tdesc_reg () = default;
DISABLE_COPY_AND_ASSIGN (tdesc_reg);
/* The name of this register. In standard features, it may be
recognized by the architecture support code, or it may be purely
for the user. */
std::string name;
/* The register number used by this target to refer to this
register. This is used for remote p/P packets and to determine
the ordering of registers in the remote g/G packets. */
long target_regnum;
/* If this flag is set, GDB should save and restore this register
around calls to an inferior function. */
int save_restore;
/* The name of the register group containing this register, or empty
if the group should be automatically determined from the register's
type. This is traditionally "general", "float", "vector" but can
also be an arbitrary string. If defined the corresponding "info"
command should display this register's value. The string should be
limited to alphanumeric characters and internal hyphens. */
std::string group;
/* The size of the register, in bits. */
int bitsize;
/* The type of the register. This string corresponds to either
a named type from the target description or a predefined
type from GDB. */
std::string type;
/* The target-described type corresponding to TYPE, if found. */
struct tdesc_type *tdesc_type;
void accept (tdesc_element_visitor &v) const override
{
v.visit (this);
}
bool operator== (const tdesc_reg &other) const
{
return (name == other.name
&& target_regnum == other.target_regnum
&& save_restore == other.save_restore
&& bitsize == other.bitsize
&& group == other.group
&& type == other.type);
}
bool operator!= (const tdesc_reg &other) const
{
return !(*this == other);
}
};
typedef std::unique_ptr<tdesc_reg> tdesc_reg_up;
/* A named type from a target description. */
struct tdesc_type_field