From patchwork Tue Jan 16 09:50:57 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Hayward X-Patchwork-Id: 25407 Received: (qmail 15136 invoked by alias); 16 Jan 2018 09:51:59 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 90641 invoked by uid 89); 16 Jan 2018 09:51:43 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.7 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_LOTSOFHASH, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_PASS, SPF_PASS autolearn=ham version=3.3.2 spammy=fend X-HELO: EUR02-HE1-obe.outbound.protection.outlook.com Received: from mail-eopbgr10065.outbound.protection.outlook.com (HELO EUR02-HE1-obe.outbound.protection.outlook.com) (40.107.1.65) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 16 Jan 2018 09:51:33 +0000 Received: from AM3PR08MB0101.eurprd08.prod.outlook.com (10.160.211.19) by AM3PR08MB0104.eurprd08.prod.outlook.com (10.160.211.22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.407.7; Tue, 16 Jan 2018 09:50:57 +0000 Received: from AM3PR08MB0101.eurprd08.prod.outlook.com ([fe80::11:d2e2:886:ac9d]) by AM3PR08MB0101.eurprd08.prod.outlook.com ([fe80::11:d2e2:886:ac9d%17]) with mapi id 15.20.0407.012; Tue, 16 Jan 2018 09:50:57 +0000 From: Alan Hayward To: "gdb-patches@sourceware.org" CC: nd Subject: [PATCH 1/6] : Commonise various target-descriptions.c functions Date: Tue, 16 Jan 2018 09:50:57 +0000 Message-ID: References: In-Reply-To: authentication-results: spf=none (sender IP is ) smtp.mailfrom=Alan.Hayward@arm.com; x-ms-publictraffictype: Email x-microsoft-exchange-diagnostics: 1; AM3PR08MB0104; 7:iMCDNZ6awGAYb2K4SDPt5d3R7UuAXkL7qAF6fRJy7K4kaFHmh/5VVvcUEQ0ZfPwUNkxDTn1EmPA5x5lJTCzD4Kj75zgoKrHOew9xJW/Skcgl2YHSHZbaidjyqQ2Y+mkmlr3L8AJpIptcYnYPKbzkQBImYIsNdnZuoCJezmrxK/Z+e18RexK9iL4gg1BoYXW7sgICL0oobPBoZHnN6O1Qpz7K3Nosxfo7Lva0mWerzbRy+64kq8B025k9FqzKfzlG x-ms-exchange-antispam-srfa-diagnostics: SSOS; x-ms-office365-filtering-correlation-id: d0c3ed3f-09c9-4a7d-b232-08d55cc6a466 x-ms-office365-filtering-ht: Tenant x-microsoft-antispam: UriScan:; BCL:0; PCL:0; RULEID:(7020095)(4652020)(5600026)(4604075)(3008032)(48565401081)(2017052603307)(7153060)(7193020); SRVR:AM3PR08MB0104; x-ms-traffictypediagnostic: AM3PR08MB0104: nodisclaimer: True x-microsoft-antispam-prvs: x-exchange-antispam-report-test: UriScan:(250305191791016)(180628864354917)(22074186197030)(131327999870524); x-exchange-antispam-report-cfa-test: BCL:0; PCL:0; RULEID:(6040470)(2401047)(8121501046)(5005006)(3002001)(3231023)(944501161)(93006095)(93001095)(10201501046)(6055026)(6041268)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123562045)(20161123564045)(20161123560045)(20161123558120)(6072148)(201708071742011); SRVR:AM3PR08MB0104; BCL:0; PCL:0; RULEID:(100000803101)(100110400095); SRVR:AM3PR08MB0104; x-forefront-prvs: 0554B1F54F x-forefront-antispam-report: SFV:NSPM; SFS:(10009020)(366004)(396003)(376002)(39380400002)(346002)(39860400002)(377424004)(189003)(199004)(82746002)(6916009)(53936002)(6306002)(2950100002)(16200700003)(53946003)(76176011)(68736007)(97736004)(6512007)(2900100001)(99286004)(305945005)(4326008)(7736002)(105586002)(4743002)(26005)(36756003)(5660300001)(6436002)(316002)(33656002)(72206003)(8676002)(81156014)(81166006)(5250100002)(8936002)(6486002)(2501003)(83716003)(6116002)(3846002)(14454004)(5640700003)(66066001)(3280700002)(106356001)(2351001)(25786009)(6506007)(2906002)(3660700001)(575784001)(86362001)(478600001)(102836004)(59450400001)(2004002)(569006); DIR:OUT; SFP:1101; SCL:1; SRVR:AM3PR08MB0104; H:AM3PR08MB0101.eurprd08.prod.outlook.com; FPR:; SPF:None; PTR:InfoNoRecords; MX:1; A:1; LANG:en; received-spf: None (protection.outlook.com: arm.com does not designate permitted sender hosts) x-microsoft-antispam-message-info: AE6X2BXvsXUuD9pgYaDnmkTbIuCP44Xzhsgbm9RgTvxnMQGK05qLHSLlvJ7Lb55vch8/Y2+oaC3Eqh94sK2/0Q== spamdiagnosticoutput: 1:99 spamdiagnosticmetadata: NSPM Content-ID: <907B16A40A5FED4CBD30C149A4A8DB42@eurprd08.prod.outlook.com> MIME-Version: 1.0 X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-Network-Message-Id: d0c3ed3f-09c9-4a7d-b232-08d55cc6a466 X-MS-Exchange-CrossTenant-originalarrivaltime: 16 Jan 2018 09:50:57.3485 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: f34e5979-57d9-4aaa-ad4d-b122a662184d X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM3PR08MB0104 X-IsSubscribed: yes This patch simply moves functionality from target-descriptions.c to the common files arch/tdesc.c and arch/tdesc.h. No functionality is changed. This will allow usage by gdbserver. The "#ifndef GDBSERVER" around the functions in arch/tdesc.h will be removed in the next patch. Alan. 2018-01-16 Alan Hayward * Makefile.in: Add new common tdesc file. * arch/tdesc.c: New file. * arch/tdesc.h (struct tdesc_reg): Moved from target-descriptions.c (enum tdesc_type_kind): Likewise. (struct tdesc_type): Likewise. (struct tdesc_type_builtin): Likewise. (struct tdesc_type_vector): Likewise. (struct tdesc_type_field): Likewise. (struct tdesc_type_with_fields): Likewise. (struct tdesc_feature): Likewise. (struct tdesc_arch_reg): Likewise. * target-descriptions.c (struct target_desc): Move to arch/tdesc.c/h (type *tdesc_type_builtin::make_gdb_type): Likewise. (type *tdesc_type_vector::make_gdb_type): Likewise. (type *tdesc_type_with_fields::make_gdb_type_struct): Likewise. (type *tdesc_type_with_fields::make_gdb_type_union): Likewise. (type *tdesc_type_with_fields::make_gdb_type_flags): Likewise. (type *tdesc_type_with_fields::make_gdb_type_enum): Likewise. (type *tdesc_type_with_fields::make_gdb_type): Likewise. (tdesc_predefined_type): Likewise. (tdesc_named_type): Likewise. (tdesc_create_reg): Likewise. (tdesc_create_vector): Likewise. (tdesc_create_struct): Likewise. (tdesc_set_struct_size): Likewise. (tdesc_create_union): Likewise. (tdesc_create_flags): Likewise. (tdesc_create_enum): Likewise. (tdesc_add_field): Likewise. (tdesc_add_typed_bitfield): Likewise. (tdesc_add_bitfield): Likewise. (tdesc_add_flag): Likewise. (tdesc_add_enum_value): Likewise. diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 0a4a06b242e0423218648fe77d53fc192456cd2f..386ab5c117ebf34e1ae927b5fe78fd4618012945 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -669,6 +669,7 @@ ALL_TARGET_OBS = \ arch/arm-get-next-pcs.o \ arch/arm-linux.o \ arch/i386.o \ + arch/tdesc.o \ arm-bsd-tdep.o \ arm-fbsd-tdep.o \ arm-linux-tdep.o \ diff --git a/gdb/arch/tdesc.h b/gdb/arch/tdesc.h index cc11651dcaa7abe81598b69f509ef34ff0d94dbf..22da5efa48f8cf5e94c33c9eed4739127467c356 100644 --- a/gdb/arch/tdesc.h +++ b/gdb/arch/tdesc.h @@ -18,6 +18,12 @@ #ifndef ARCH_TDESC_H #define ARCH_TDESC_H 1 +#ifdef GDBSERVER +#include "server.h" +#else +#include "defs.h" +#endif + struct tdesc_feature; struct tdesc_type; struct tdesc_type_builtin; @@ -25,6 +31,271 @@ struct tdesc_type_vector; struct tdesc_type_with_fields; struct tdesc_reg; struct target_desc; +struct type; + +#ifndef GDBSERVER + +/* 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; + + bool operator== (const tdesc_reg &other) const; + + bool operator!= (const tdesc_reg &other) const + { + return !(*this == other); + } +}; + +typedef std::unique_ptr 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; +}; + +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; + + 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; + + 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; + + 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 fields; + int size; +}; + +typedef std::unique_ptr tdesc_type_up; + +/* 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 registers; + + /* The types associated with this feature. */ + std::vector 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_up; + +/* Per-architecture data associated with a target description. The + target description may be shared by multiple architectures, but + this data is private to one gdbarch. */ + +struct tdesc_arch_reg +{ + tdesc_arch_reg (tdesc_reg *reg_, struct type *type_) + : reg (reg_), type (type_) + {} + + struct tdesc_reg *reg; + struct type *type; +}; + +#endif /* Allocate a new target_desc. */ target_desc *allocate_target_description (void); diff --git a/gdb/arch/tdesc.c b/gdb/arch/tdesc.c new file mode 100644 index 0000000000000000000000000000000000000000..e6005a75a7264bba4cd177e4ec1efd90809e25c8 --- /dev/null +++ b/gdb/arch/tdesc.c @@ -0,0 +1,325 @@ +/* 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 . */ + +#ifdef GDBSERVER +#include "server.h" + +typedef const char * (gdbarch_register_name_ftype) (struct gdbarch *gdbarch, int regnr); +typedef struct type * (gdbarch_register_type_ftype) (struct gdbarch *gdbarch, int reg_nr); + +#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_ : "") +{ + /* 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 ()); +} + +void tdesc_reg::accept (tdesc_element_visitor &v) const +{ + v.visit (this); +} + +bool tdesc_reg::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); +} + +/* 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_type_builtin::accept (tdesc_element_visitor &v) const +{ + v.visit (this); +} + +void tdesc_type_vector::accept (tdesc_element_visitor &v) const +{ + v.visit (this); +} + +void tdesc_type_with_fields::accept (tdesc_element_visitor &v) const +{ + v.visit (this); +} + +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); +} diff --git a/gdb/target-descriptions.c b/gdb/target-descriptions.c index 1b20a12d769718e591dea6df8183c2e9ecfac990..cef65a8fe61e22362e0bc4e6dbd7e3c0a0f4d1b4 100644 --- a/gdb/target-descriptions.c +++ b/gdb/target-descriptions.c @@ -38,30 +38,6 @@ #include "completer.h" #include "readline/tilde.h" /* tilde_expand */ -/* The interface to visit different elements of target description. */ - -class tdesc_element_visitor -{ -public: - virtual void visit_pre (const target_desc *e) = 0; - virtual void visit_post (const target_desc *e) = 0; - - virtual void visit_pre (const tdesc_feature *e) = 0; - virtual void visit_post (const tdesc_feature *e) = 0; - - virtual void visit (const tdesc_type_builtin *e) = 0; - virtual void visit (const tdesc_type_vector *e) = 0; - virtual void visit (const tdesc_type_with_fields *e) = 0; - - virtual void visit (const tdesc_reg *e) = 0; -}; - -class tdesc_element -{ -public: - virtual void accept (tdesc_element_visitor &v) const = 0; -}; - /* Types. */ struct property @@ -74,41 +50,20 @@ struct property std::string value; }; -/* An individual register from a target description. */ +/* A target description. */ -struct tdesc_reg : tdesc_element +struct target_desc : 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_ : "") - { - /* 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); + target_desc () + {} - /* 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; + virtual ~target_desc () = default; - /* 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; + target_desc (const target_desc &) = delete; + void operator= (const target_desc &) = delete; - /* If this flag is set, GDB should save and restore this register - around calls to an inferior function. */ - int save_restore; + /* The architecture reported by the target, if any. */ + const struct bfd_arch_info *arch = NULL; /* The name of the register group containing this register, or empty if the group should be automatically determined from the register's @@ -118,554 +73,290 @@ struct tdesc_reg : tdesc_element limited to alphanumeric characters and internal hyphens. */ std::string group; - /* The size of the register, in bits. */ - int bitsize; + /* The osabi reported by the target, if any; GDB_OSABI_UNKNOWN + otherwise. */ + enum gdb_osabi osabi = GDB_OSABI_UNKNOWN; + + /* The list of compatible architectures reported by the target. */ + std::vector compatible; - /* 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; + /* Any architecture-specific properties specified by the target. */ + std::vector properties; - /* The target-described type corresponding to TYPE, if found. */ - struct tdesc_type *tdesc_type; + /* The features associated with this target. */ + std::vector features; void accept (tdesc_element_visitor &v) const override { - v.visit (this); - } + v.visit_pre (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); - } + for (const tdesc_feature_up &feature : features) + feature->accept (v); - bool operator!= (const tdesc_reg &other) const - { - return !(*this == other); + v.visit_post (this); } -}; - -typedef std::unique_ptr 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_) - {} + bool operator== (const target_desc &other) const + { + if (arch != other.arch) + return false; - virtual ~tdesc_type () = default; + if (osabi != other.osabi) + return false; - DISABLE_COPY_AND_ASSIGN (tdesc_type); + if (features.size () != other.features.size ()) + return false; - /* The name of this type. */ - std::string name; + for (int ix = 0; ix < features.size (); ix++) + { + const tdesc_feature_up &feature1 = features[ix]; + const tdesc_feature_up &feature2 = other.features[ix]; - /* Identify the kind of this type. */ - enum tdesc_type_kind kind; + if (feature1 != feature2 && *feature1 != *feature2) + return false; + } - bool operator== (const tdesc_type &other) const - { - return name == other.name && kind == other.kind; + return true; } - bool operator!= (const tdesc_type &other) const + bool operator!= (const target_desc &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_up; - -struct tdesc_type_builtin : tdesc_type -{ - tdesc_type_builtin (const std::string &name, enum tdesc_type_kind kind) - : tdesc_type (name, kind) - {} - void accept (tdesc_element_visitor &v) const override - { - v.visit (this); - } - type *make_gdb_type (struct gdbarch *gdbarch) const override - { - switch (this->kind) - { - /* Predefined types. */ - case TDESC_TYPE_BOOL: - return builtin_type (gdbarch)->builtin_bool; +type *tdesc_type_builtin::make_gdb_type (struct gdbarch *gdbarch) const +{ + switch (this->kind) + { + /* Predefined types. */ + case TDESC_TYPE_BOOL: + return builtin_type (gdbarch)->builtin_bool; - case TDESC_TYPE_INT8: - return builtin_type (gdbarch)->builtin_int8; + case TDESC_TYPE_INT8: + return builtin_type (gdbarch)->builtin_int8; - case TDESC_TYPE_INT16: - return builtin_type (gdbarch)->builtin_int16; + case TDESC_TYPE_INT16: + return builtin_type (gdbarch)->builtin_int16; - case TDESC_TYPE_INT32: - return builtin_type (gdbarch)->builtin_int32; + case TDESC_TYPE_INT32: + return builtin_type (gdbarch)->builtin_int32; - case TDESC_TYPE_INT64: - return builtin_type (gdbarch)->builtin_int64; + case TDESC_TYPE_INT64: + return builtin_type (gdbarch)->builtin_int64; - case TDESC_TYPE_INT128: - return builtin_type (gdbarch)->builtin_int128; + case TDESC_TYPE_INT128: + return builtin_type (gdbarch)->builtin_int128; - case TDESC_TYPE_UINT8: - return builtin_type (gdbarch)->builtin_uint8; + case TDESC_TYPE_UINT8: + return builtin_type (gdbarch)->builtin_uint8; - case TDESC_TYPE_UINT16: - return builtin_type (gdbarch)->builtin_uint16; + case TDESC_TYPE_UINT16: + return builtin_type (gdbarch)->builtin_uint16; - case TDESC_TYPE_UINT32: - return builtin_type (gdbarch)->builtin_uint32; + case TDESC_TYPE_UINT32: + return builtin_type (gdbarch)->builtin_uint32; - case TDESC_TYPE_UINT64: - return builtin_type (gdbarch)->builtin_uint64; + case TDESC_TYPE_UINT64: + return builtin_type (gdbarch)->builtin_uint64; - case TDESC_TYPE_UINT128: - return builtin_type (gdbarch)->builtin_uint128; + case TDESC_TYPE_UINT128: + return builtin_type (gdbarch)->builtin_uint128; - case TDESC_TYPE_CODE_PTR: - return builtin_type (gdbarch)->builtin_func_ptr; + case TDESC_TYPE_CODE_PTR: + return builtin_type (gdbarch)->builtin_func_ptr; - case TDESC_TYPE_DATA_PTR: - return builtin_type (gdbarch)->builtin_data_ptr; - } + case TDESC_TYPE_DATA_PTR: + return builtin_type (gdbarch)->builtin_data_ptr; + } - type *gdb_type = tdesc_find_type (gdbarch, this->name.c_str ()); - if (gdb_type != NULL) - return gdb_type; + type *gdb_type = tdesc_find_type (gdbarch, this->name.c_str ()); + if (gdb_type != NULL) + return gdb_type; - switch (this->kind) - { - case TDESC_TYPE_IEEE_SINGLE: - return arch_float_type (gdbarch, -1, "builtin_type_ieee_single", - floatformats_ieee_single); + switch (this->kind) + { + case TDESC_TYPE_IEEE_SINGLE: + return arch_float_type (gdbarch, -1, "builtin_type_ieee_single", + floatformats_ieee_single); - case TDESC_TYPE_IEEE_DOUBLE: - return arch_float_type (gdbarch, -1, "builtin_type_ieee_double", - floatformats_ieee_double); + case TDESC_TYPE_IEEE_DOUBLE: + return arch_float_type (gdbarch, -1, "builtin_type_ieee_double", + floatformats_ieee_double); - case TDESC_TYPE_ARM_FPA_EXT: - return arch_float_type (gdbarch, -1, "builtin_type_arm_ext", - floatformats_arm_ext); + case TDESC_TYPE_ARM_FPA_EXT: + return arch_float_type (gdbarch, -1, "builtin_type_arm_ext", + floatformats_arm_ext); - case TDESC_TYPE_I387_EXT: - return arch_float_type (gdbarch, -1, "builtin_type_i387_ext", - floatformats_i387_ext); - } + case TDESC_TYPE_I387_EXT: + return arch_float_type (gdbarch, -1, "builtin_type_i387_ext", + floatformats_i387_ext); + } - internal_error (__FILE__, __LINE__, - "Type \"%s\" has an unknown kind %d", - this->name.c_str (), this->kind); + internal_error (__FILE__, __LINE__, + "Type \"%s\" has an unknown kind %d", + this->name.c_str (), this->kind); - return NULL; - } -}; - -/* tdesc_type for vector types. */ + return NULL; +} -struct tdesc_type_vector : tdesc_type +type *tdesc_type_vector::make_gdb_type (struct gdbarch *gdbarch) const { - tdesc_type_vector (const std::string &name, tdesc_type *element_type_, int count_) - : tdesc_type (name, TDESC_TYPE_VECTOR), - element_type (element_type_), count (count_) - {} - - void accept (tdesc_element_visitor &v) const override - { - v.visit (this); - } - - type *make_gdb_type (struct gdbarch *gdbarch) const override - { - type *vector_gdb_type = tdesc_find_type (gdbarch, this->name.c_str ()); - if (vector_gdb_type != NULL) - return vector_gdb_type; - - type *element_gdb_type = this->element_type->make_gdb_type (gdbarch); - vector_gdb_type = init_vector_type (element_gdb_type, this->count); - TYPE_NAME (vector_gdb_type) = xstrdup (this->name.c_str ()); - + type *vector_gdb_type = tdesc_find_type (gdbarch, this->name.c_str ()); + if (vector_gdb_type != NULL) return vector_gdb_type; - } - - struct tdesc_type *element_type; - int count; -}; -/* tdesc_type for struct, union, flags, and enum types. */ + type *element_gdb_type = this->element_type->make_gdb_type (gdbarch); + vector_gdb_type = init_vector_type (element_gdb_type, this->count); + TYPE_NAME (vector_gdb_type) = xstrdup (this->name.c_str ()); -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_) - {} + return vector_gdb_type; +} - void accept (tdesc_element_visitor &v) const override - { - v.visit (this); - } - type *make_gdb_type_struct (struct gdbarch *gdbarch) const - { - type *struct_gdb_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); - TYPE_NAME (struct_gdb_type) = xstrdup (this->name.c_str ()); - TYPE_TAG_NAME (struct_gdb_type) = TYPE_NAME (struct_gdb_type); +type *tdesc_type_with_fields::make_gdb_type_struct (struct gdbarch *gdbarch) const +{ + type *struct_gdb_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT); + TYPE_NAME (struct_gdb_type) = xstrdup (this->name.c_str ()); + TYPE_TAG_NAME (struct_gdb_type) = TYPE_NAME (struct_gdb_type); - for (const tdesc_type_field &f : this->fields) - { - if (f.start != -1 && f.end != -1) - { - /* Bitfield. */ - struct field *fld; - struct type *field_gdb_type; - int bitsize, total_size; - - /* This invariant should be preserved while creating types. */ - gdb_assert (this->size != 0); - if (f.type != NULL) - field_gdb_type = f.type->make_gdb_type (gdbarch); - else if (this->size > 4) - field_gdb_type = builtin_type (gdbarch)->builtin_uint64; - else - field_gdb_type = builtin_type (gdbarch)->builtin_uint32; - - fld = append_composite_type_field_raw - (struct_gdb_type, xstrdup (f.name.c_str ()), field_gdb_type); - - /* For little-endian, BITPOS counts from the LSB of - the structure and marks the LSB of the field. For - big-endian, BITPOS counts from the MSB of the - structure and marks the MSB of the field. Either - way, it is the number of bits to the "left" of the - field. To calculate this in big-endian, we need - the total size of the structure. */ - bitsize = f.end - f.start + 1; - total_size = this->size * TARGET_CHAR_BIT; - if (gdbarch_bits_big_endian (gdbarch)) - SET_FIELD_BITPOS (fld[0], total_size - f.start - bitsize); - else - SET_FIELD_BITPOS (fld[0], f.start); - FIELD_BITSIZE (fld[0]) = bitsize; - } - else - { - gdb_assert (f.start == -1 && f.end == -1); - type *field_gdb_type = f.type->make_gdb_type (gdbarch); - append_composite_type_field (struct_gdb_type, - xstrdup (f.name.c_str ()), - field_gdb_type); - } - } + for (const tdesc_type_field &f : this->fields) + { + if (f.start != -1 && f.end != -1) + { + /* Bitfield. */ + struct field *fld; + struct type *field_gdb_type; + int bitsize, total_size; + + /* This invariant should be preserved while creating types. */ + gdb_assert (this->size != 0); + if (f.type != NULL) + field_gdb_type = f.type->make_gdb_type (gdbarch); + else if (this->size > 4) + field_gdb_type = builtin_type (gdbarch)->builtin_uint64; + else + field_gdb_type = builtin_type (gdbarch)->builtin_uint32; + + fld = append_composite_type_field_raw + (struct_gdb_type, xstrdup (f.name.c_str ()), field_gdb_type); + + /* For little-endian, BITPOS counts from the LSB of + the structure and marks the LSB of the field. For + big-endian, BITPOS counts from the MSB of the + structure and marks the MSB of the field. Either + way, it is the number of bits to the "left" of the + field. To calculate this in big-endian, we need + the total size of the structure. */ + bitsize = f.end - f.start + 1; + total_size = this->size * TARGET_CHAR_BIT; + if (gdbarch_bits_big_endian (gdbarch)) + SET_FIELD_BITPOS (fld[0], total_size - f.start - bitsize); + else + SET_FIELD_BITPOS (fld[0], f.start); + FIELD_BITSIZE (fld[0]) = bitsize; + } + else + { + gdb_assert (f.start == -1 && f.end == -1); + type *field_gdb_type = f.type->make_gdb_type (gdbarch); + append_composite_type_field (struct_gdb_type, + xstrdup (f.name.c_str ()), + field_gdb_type); + } + } - if (this->size != 0) - TYPE_LENGTH (struct_gdb_type) = this->size; + if (this->size != 0) + TYPE_LENGTH (struct_gdb_type) = this->size; - return struct_gdb_type; - } + return struct_gdb_type; +} - type *make_gdb_type_union (struct gdbarch *gdbarch) const - { - type *union_gdb_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_UNION); - TYPE_NAME (union_gdb_type) = xstrdup (this->name.c_str ()); +type *tdesc_type_with_fields::make_gdb_type_union (struct gdbarch *gdbarch) const +{ + type *union_gdb_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_UNION); + TYPE_NAME (union_gdb_type) = xstrdup (this->name.c_str ()); - for (const tdesc_type_field &f : this->fields) - { - type* field_gdb_type = f.type->make_gdb_type (gdbarch); - append_composite_type_field (union_gdb_type, xstrdup (f.name.c_str ()), + for (const tdesc_type_field &f : this->fields) + { + type* field_gdb_type = f.type->make_gdb_type (gdbarch); + append_composite_type_field (union_gdb_type, xstrdup (f.name.c_str ()), field_gdb_type); - /* If any of the children of a union are vectors, flag the - union as a vector also. This allows e.g. a union of two - vector types to show up automatically in "info vector". */ - if (TYPE_VECTOR (field_gdb_type)) - TYPE_VECTOR (union_gdb_type) = 1; - } + /* If any of the children of a union are vectors, flag the + union as a vector also. This allows e.g. a union of two + vector types to show up automatically in "info vector". */ + if (TYPE_VECTOR (field_gdb_type)) + TYPE_VECTOR (union_gdb_type) = 1; + } - return union_gdb_type; - } + return union_gdb_type; +} - type *make_gdb_type_flags (struct gdbarch *gdbarch) const - { - type *flags_gdb_type = arch_flags_type (gdbarch, this->name.c_str (), +type *tdesc_type_with_fields::make_gdb_type_flags (struct gdbarch *gdbarch) const +{ + type *flags_gdb_type = arch_flags_type (gdbarch, this->name.c_str (), this->size * TARGET_CHAR_BIT); - for (const tdesc_type_field &f : this->fields) - { + for (const tdesc_type_field &f : this->fields) + { int bitsize = f.end - f.start + 1; gdb_assert (f.type != NULL); type *field_gdb_type = f.type->make_gdb_type (gdbarch); append_flags_type_field (flags_gdb_type, f.start, bitsize, field_gdb_type, f.name.c_str ()); - } + } - return flags_gdb_type; - } + return flags_gdb_type; +} - type *make_gdb_type_enum (struct gdbarch *gdbarch) const - { - type *enum_gdb_type = arch_type (gdbarch, TYPE_CODE_ENUM, +type *tdesc_type_with_fields::make_gdb_type_enum (struct gdbarch *gdbarch) const +{ + type *enum_gdb_type = arch_type (gdbarch, TYPE_CODE_ENUM, this->size * TARGET_CHAR_BIT, this->name.c_str ()); - TYPE_UNSIGNED (enum_gdb_type) = 1; - for (const tdesc_type_field &f : this->fields) - { + TYPE_UNSIGNED (enum_gdb_type) = 1; + for (const tdesc_type_field &f : this->fields) + { struct field *fld = append_composite_type_field_raw (enum_gdb_type, xstrdup (f.name.c_str ()), NULL); SET_FIELD_BITPOS (fld[0], f.start); - } - - return enum_gdb_type; - } - - type *make_gdb_type (struct gdbarch *gdbarch) const override - { - type *gdb_type = tdesc_find_type (gdbarch, this->name.c_str ()); - if (gdb_type != NULL) - return gdb_type; - - switch (this->kind) - { - case TDESC_TYPE_STRUCT: - return make_gdb_type_struct (gdbarch); - case TDESC_TYPE_UNION: - return make_gdb_type_union (gdbarch); - case TDESC_TYPE_FLAGS: - return make_gdb_type_flags (gdbarch); - case TDESC_TYPE_ENUM: - return make_gdb_type_enum (gdbarch); } - internal_error (__FILE__, __LINE__, - "Type \"%s\" has an unknown kind %d", - this->name.c_str (), this->kind); - - return NULL; - } - - std::vector 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 registers; - - /* The types associated with this feature. */ - std::vector 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_up; - -/* A target description. */ + return enum_gdb_type; +} -struct target_desc : tdesc_element +type *tdesc_type_with_fields::make_gdb_type (struct gdbarch *gdbarch) const { - target_desc () - {} - - virtual ~target_desc () = default; - - target_desc (const target_desc &) = delete; - void operator= (const target_desc &) = delete; - - /* The architecture reported by the target, if any. */ - const struct bfd_arch_info *arch = NULL; - - /* The osabi reported by the target, if any; GDB_OSABI_UNKNOWN - otherwise. */ - enum gdb_osabi osabi = GDB_OSABI_UNKNOWN; - - /* The list of compatible architectures reported by the target. */ - std::vector compatible; - - /* Any architecture-specific properties specified by the target. */ - std::vector properties; - - /* The features associated with this target. */ - std::vector features; - - void accept (tdesc_element_visitor &v) const override - { - v.visit_pre (this); - - for (const tdesc_feature_up &feature : features) - feature->accept (v); - - v.visit_post (this); - } - - bool operator== (const target_desc &other) const - { - if (arch != other.arch) - return false; - - if (osabi != other.osabi) - return false; - - if (features.size () != other.features.size ()) - return false; - - for (int ix = 0; ix < features.size (); ix++) - { - const tdesc_feature_up &feature1 = features[ix]; - const tdesc_feature_up &feature2 = other.features[ix]; - - if (feature1 != feature2 && *feature1 != *feature2) - return false; - } - - return true; - } - - bool operator!= (const target_desc &other) const - { - return !(*this == other); - } -}; + type *gdb_type = tdesc_find_type (gdbarch, this->name.c_str ()); + if (gdb_type != NULL) + return gdb_type; -/* Per-architecture data associated with a target description. The - target description may be shared by multiple architectures, but - this data is private to one gdbarch. */ + switch (this->kind) + { + case TDESC_TYPE_STRUCT: + return make_gdb_type_struct (gdbarch); + case TDESC_TYPE_UNION: + return make_gdb_type_union (gdbarch); + case TDESC_TYPE_FLAGS: + return make_gdb_type_flags (gdbarch); + case TDESC_TYPE_ENUM: + return make_gdb_type_enum (gdbarch); + } -struct tdesc_arch_reg -{ - tdesc_arch_reg (tdesc_reg *reg_, struct type *type_) - : reg (reg_), type (type_) - {} + internal_error (__FILE__, __LINE__, + "Type \"%s\" has an unknown kind %d", + this->name.c_str (), this->kind); - struct tdesc_reg *reg; - struct type *type; -}; + return NULL; +} struct tdesc_arch_data { @@ -957,58 +648,6 @@ tdesc_feature_name (const struct tdesc_feature *feature) return feature->name.c_str (); } -/* Predefined types. */ -static tdesc_type_builtin tdesc_predefined_types[] = -{ - { "bool", TDESC_TYPE_BOOL }, - { "int8", TDESC_TYPE_INT8 }, - { "int16", TDESC_TYPE_INT16 }, - { "int32", TDESC_TYPE_INT32 }, - { "int64", TDESC_TYPE_INT64 }, - { "int128", TDESC_TYPE_INT128 }, - { "uint8", TDESC_TYPE_UINT8 }, - { "uint16", TDESC_TYPE_UINT16 }, - { "uint32", TDESC_TYPE_UINT32 }, - { "uint64", TDESC_TYPE_UINT64 }, - { "uint128", TDESC_TYPE_UINT128 }, - { "code_ptr", TDESC_TYPE_CODE_PTR }, - { "data_ptr", TDESC_TYPE_DATA_PTR }, - { "ieee_single", TDESC_TYPE_IEEE_SINGLE }, - { "ieee_double", TDESC_TYPE_IEEE_DOUBLE }, - { "arm_fpa_ext", TDESC_TYPE_ARM_FPA_EXT }, - { "i387_ext", TDESC_TYPE_I387_EXT } -}; - -/* Lookup a predefined type. */ - -static struct tdesc_type * -tdesc_predefined_type (enum tdesc_type_kind kind) -{ - for (int ix = 0; ix < ARRAY_SIZE (tdesc_predefined_types); ix++) - if (tdesc_predefined_types[ix].kind == kind) - return &tdesc_predefined_types[ix]; - - gdb_assert_not_reached ("bad predefined tdesc type"); -} - -/* See arch/tdesc.h. */ - -struct tdesc_type * -tdesc_named_type (const struct tdesc_feature *feature, const char *id) -{ - /* First try target-defined types. */ - for (const tdesc_type_up &type : feature->types) - if (type->name == id) - return type.get (); - - /* Next try the predefined types. */ - for (int ix = 0; ix < ARRAY_SIZE (tdesc_predefined_types); ix++) - if (tdesc_predefined_types[ix].name == id) - return &tdesc_predefined_types[ix]; - - return NULL; -} - /* Lookup type associated with ID. */ struct type * @@ -1440,161 +1079,6 @@ tdesc_use_registers (struct gdbarch *gdbarch, tdesc_remote_register_number); set_gdbarch_register_reggroup_p (gdbarch, tdesc_register_reggroup_p); } - - -/* See arch/tdesc.h. */ - -void -tdesc_create_reg (struct tdesc_feature *feature, const char *name, - int regnum, int save_restore, const char *group, - int bitsize, const char *type) -{ - tdesc_reg *reg = new tdesc_reg (feature, name, regnum, save_restore, - group, bitsize, type); - - feature->registers.emplace_back (reg); -} - -/* See arch/tdesc.h. */ - -struct tdesc_type * -tdesc_create_vector (struct tdesc_feature *feature, const char *name, - struct tdesc_type *field_type, int count) -{ - tdesc_type_vector *type = new tdesc_type_vector (name, field_type, count); - feature->types.emplace_back (type); - - return type; -} - -/* See arch/tdesc.h. */ - -tdesc_type_with_fields * -tdesc_create_struct (struct tdesc_feature *feature, const char *name) -{ - tdesc_type_with_fields *type - = new tdesc_type_with_fields (name, TDESC_TYPE_STRUCT); - feature->types.emplace_back (type); - - return type; -} - -/* See arch/tdesc.h. */ - -void -tdesc_set_struct_size (tdesc_type_with_fields *type, int size) -{ - gdb_assert (type->kind == TDESC_TYPE_STRUCT); - gdb_assert (size > 0); - type->size = size; -} - -/* See arch/tdesc.h. */ - -tdesc_type_with_fields * -tdesc_create_union (struct tdesc_feature *feature, const char *name) -{ - tdesc_type_with_fields *type - = new tdesc_type_with_fields (name, TDESC_TYPE_UNION); - feature->types.emplace_back (type); - - return type; -} - -/* See arch/tdesc.h. */ - -tdesc_type_with_fields * -tdesc_create_flags (struct tdesc_feature *feature, const char *name, - int size) -{ - gdb_assert (size > 0); - - tdesc_type_with_fields *type - = new tdesc_type_with_fields (name, TDESC_TYPE_FLAGS, size); - feature->types.emplace_back (type); - - return type; -} - -tdesc_type_with_fields * -tdesc_create_enum (struct tdesc_feature *feature, const char *name, - int size) -{ - gdb_assert (size > 0); - - tdesc_type_with_fields *type - = new tdesc_type_with_fields (name, TDESC_TYPE_ENUM, size); - feature->types.emplace_back (type); - - return type; -} - -/* See arch/tdesc.h. */ - -void -tdesc_add_field (tdesc_type_with_fields *type, const char *field_name, - struct tdesc_type *field_type) -{ - gdb_assert (type->kind == TDESC_TYPE_UNION - || type->kind == TDESC_TYPE_STRUCT); - - /* Initialize start and end so we know this is not a bit-field - when we print-c-tdesc. */ - type->fields.emplace_back (field_name, field_type, -1, -1); -} - -void -tdesc_add_typed_bitfield (tdesc_type_with_fields *type, const char *field_name, - int start, int end, struct tdesc_type *field_type) -{ - gdb_assert (type->kind == TDESC_TYPE_STRUCT - || type->kind == TDESC_TYPE_FLAGS); - gdb_assert (start >= 0 && end >= start); - - type->fields.emplace_back (field_name, field_type, start, end); -} - -/* See arch/tdesc.h. */ - -void -tdesc_add_bitfield (tdesc_type_with_fields *type, const char *field_name, - int start, int end) -{ - struct tdesc_type *field_type; - - gdb_assert (start >= 0 && end >= start); - - if (type->size > 4) - field_type = tdesc_predefined_type (TDESC_TYPE_UINT64); - else - field_type = tdesc_predefined_type (TDESC_TYPE_UINT32); - - tdesc_add_typed_bitfield (type, field_name, start, end, field_type); -} - -/* See arch/tdesc.h. */ - -void -tdesc_add_flag (tdesc_type_with_fields *type, int start, - const char *flag_name) -{ - gdb_assert (type->kind == TDESC_TYPE_FLAGS - || type->kind == TDESC_TYPE_STRUCT); - - type->fields.emplace_back (flag_name, - tdesc_predefined_type (TDESC_TYPE_BOOL), - start, start); -} - -void -tdesc_add_enum_value (tdesc_type_with_fields *type, int value, - const char *name) -{ - gdb_assert (type->kind == TDESC_TYPE_ENUM); - type->fields.emplace_back (name, - tdesc_predefined_type (TDESC_TYPE_INT32), - value, -1); -} /* See arch/tdesc.h. */