From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 51524 invoked by alias); 16 Jan 2018 09:55:28 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 49788 invoked by uid 89); 16 Jan 2018 09:53:44 -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,RCVD_IN_DNSWL_NONE,SPF_HELO_PASS,SPF_PASS autolearn=ham version=3.3.2 spammy=UD:dtd, DOCTYPE, !DOCTYPE, fname X-HELO: EUR01-VE1-obe.outbound.protection.outlook.com Received: from mail-ve1eur01on0067.outbound.protection.outlook.com (HELO EUR01-VE1-obe.outbound.protection.outlook.com) (104.47.1.67) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 16 Jan 2018 09:53:33 +0000 Received: from AM3PR08MB0101.eurprd08.prod.outlook.com (10.160.211.19) by AM3PR08MB0103.eurprd08.prod.outlook.com (10.160.211.21) 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:53:30 +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:53:30 +0000 From: Alan Hayward To: "gdb-patches@sourceware.org" CC: nd Subject: [PATCH 4/6]: Create xml from target descriptions Date: Tue, 16 Jan 2018 09:55:00 -0000 Message-ID: <31767501-AFCF-4423-B2DD-B121924550D3@arm.com> 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;AM3PR08MB0103;7:HvA0zbLm3z6/mifb7TCSTcPJvE15FWcghJk1/e0J4t/NdHnOA8Q64YLx9WSa+f+eeGGMGOtCUXwwR0G8esZTrSWLhqrsdykBEPa4pQJ5PCRXg0t03GlveZnr7NlwbNp9Ns1IMxfJeS67ValreRSN1QzcqJGBYdoIxyzVq35VMX1BGQ0Sl+FKeE09BwPc6EL0A3XY72WYwhuxT6MtfkEifXQI0tEk68beEAFLFRmHz2R7hIz6njDRQ8W5K38T69w3 x-ms-exchange-antispam-srfa-diagnostics: SSOS; x-ms-office365-filtering-correlation-id: bef60808-99ab-40fe-d571-08d55cc6ff61 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:AM3PR08MB0103; x-ms-traffictypediagnostic: AM3PR08MB0103: nodisclaimer: True x-microsoft-antispam-prvs: x-exchange-antispam-report-test: UriScan:(180628864354917); x-exchange-antispam-report-cfa-test: BCL:0;PCL:0;RULEID:(6040470)(2401047)(8121501046)(5005006)(3231023)(944501161)(10201501046)(93006095)(93001095)(3002001)(6055026)(6041268)(20161123564045)(20161123560045)(20161123562045)(20161123558120)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(6072148)(201708071742011);SRVR:AM3PR08MB0103;BCL:0;PCL:0;RULEID:(100000803101)(100110400095);SRVR:AM3PR08MB0103; x-forefront-prvs: 0554B1F54F x-forefront-antispam-report: SFV:NSPM;SFS:(10009020)(376002)(39860400002)(366004)(39380400002)(346002)(396003)(199004)(189003)(377424004)(86362001)(575784001)(305945005)(72206003)(2906002)(7736002)(6916009)(4743002)(2950100002)(478600001)(106356001)(82746002)(105586002)(3846002)(6116002)(99286004)(3660700001)(36756003)(53936002)(83716003)(2351001)(66066001)(3280700002)(76176011)(5250100002)(33656002)(5640700003)(97736004)(68736007)(25786009)(2501003)(316002)(8936002)(5660300001)(6486002)(81166006)(8676002)(81156014)(14454004)(6512007)(102836004)(6436002)(2900100001)(59450400001)(4326008)(6506007)(26005);DIR:OUT;SFP:1101;SCL:1;SRVR:AM3PR08MB0103;H:AM3PR08MB0101.eurprd08.prod.outlook.com;FPR:;SPF:None;PTR:InfoNoRecords;A:1;MX:1;LANG:en; received-spf: None (protection.outlook.com: arm.com does not designate permitted sender hosts) x-microsoft-antispam-message-info: sGzQUJ8o8TGukHOVgWCGJFt4uc8g0vddkYRmMOiXjYw1nQj3ijeveNvZDILKU00mr3Qb4thcWugVHBnNhA+mBA== spamdiagnosticoutput: 1:99 spamdiagnosticmetadata: NSPM Content-Type: text/plain; charset="us-ascii" Content-ID: <35535D8B581CDC40BFB84B76E657F4B1@eurprd08.prod.outlook.com> Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-Network-Message-Id: bef60808-99ab-40fe-d571-08d55cc6ff61 X-MS-Exchange-CrossTenant-originalarrivaltime: 16 Jan 2018 09:53:30.0206 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: f34e5979-57d9-4aaa-ad4d-b122a662184d X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM3PR08MB0103 X-IsSubscribed: yes X-SW-Source: 2018-01/txt/msg00290.txt.bz2 This patch adds a print_xml_feature visitor class which turns a C target description into xml. Tests are added to maintenance_check_xml_descriptions which takes each pair of tested descriptions, turns them both into xml, then back again, and confirms the descriptions still match. I have added a new function void debug(const struct target_desc *) which simply prints a given target description out as xml. This follows the style of GCC which has debug functions for all major structure types (eg rtx). When debugging GCC I can usually take any tree or expression and just "call debug(x)" to get a nice dump of it, or sprinkle debug(x) calls through my failing code. I find this really useful, however I'm happy to remove (or rename) the function if people don't like it. Alan. 2018-01-16 Alan Hayward gdb/ * arch/tdesc.c (print_xml_feature::visit_post): Add xml parsing. (print_xml_feature::visit_pre): Likewise. (print_xml_feature::visit_post): Likewise. (print_xml_feature::visit): Likewise. (print_xml_feature::visit): Likewise. (print_xml_feature::visit): Likewise. (print_xml_feature::visit): Likewise. * arch/tdesc.h (print_xml_feature): Add new class. * regformats/regdat.sh: obtain xml. * target-descriptions.c (struct target_desc): Add xmltarget. (print_xml_feature::visit_pre): Add xml vistor. (tdesc_get_features_xml): Add function to get xml. (debug): Add target_desc debug function. (maintenance_check_xml_descriptions): Test xml generation. * target-descriptions.h (debug): Add declaration. * xml-tdesc.c (target_read_description_xml_string): Add function. * xml-tdesc.h (target_read_description_xml_string): Add declaration. gdbserver/ * tdesc.c (void target_desc::accept): Fill in function. (tdesc_get_features_xml): Remove old xml creation. (print_xml_feature::visit_pre): Add xml vistor. diff --git a/gdb/arch/tdesc.h b/gdb/arch/tdesc.h index 633853447d98c952cfed462939b486afd2738742..edd7de104973676fe69873ffe69= 6e99eb77fbc84 100644 --- a/gdb/arch/tdesc.h +++ b/gdb/arch/tdesc.h @@ -359,4 +359,33 @@ void tdesc_create_reg (struct tdesc_feature *feature, = const char *name, int regnum, int save_restore, const char *group, int bitsize, const char *type); +/* Return the tdesc in string XML format. */ + +const char *tdesc_get_features_xml (target_desc *tdesc); + +/* Print target description as xml. */ + +class print_xml_feature : public tdesc_element_visitor +{ +public: + print_xml_feature (std::string *buffer_) + : m_buffer (buffer_) + {} + + ~print_xml_feature () + {} + + void visit_pre (const target_desc *e) override; + void visit_post (const target_desc *e) override; + void visit_pre (const tdesc_feature *e) override; + void visit_post (const tdesc_feature *e) override; + void visit (const tdesc_type_builtin *type) override; + void visit (const tdesc_type_vector *type) override; + void visit (const tdesc_type_with_fields *type) override; + void visit (const tdesc_reg *reg) override; + +private: + std::string *m_buffer; +}; + #endif /* ARCH_TDESC_H */ diff --git a/gdb/arch/tdesc.c b/gdb/arch/tdesc.c index e6005a75a7264bba4cd177e4ec1efd90809e25c8..e43f37095d636cf680ce2b55c65= 3deedd2c59eae 100644 --- a/gdb/arch/tdesc.c +++ b/gdb/arch/tdesc.c @@ -323,3 +323,138 @@ tdesc_add_enum_value (tdesc_type_with_fields *type, i= nt value, tdesc_predefined_type (TDESC_TYPE_INT32), value, -1); } + + +void print_xml_feature::visit_post (const target_desc *e) +{ + *m_buffer +=3D "\n"; +} + +void print_xml_feature::visit_pre (const tdesc_feature *e) +{ + *m_buffer +=3D "name; + *m_buffer +=3D "\">\n"; +} + +void print_xml_feature::visit_post (const tdesc_feature *e) +{ + *m_buffer +=3D "\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 +=3D "name; + *m_buffer +=3D "\" type=3D\""; + *m_buffer +=3D type->element_type->name; + *m_buffer +=3D "\" count=3D\""; + *m_buffer +=3D std::to_string (type->count); + *m_buffer +=3D "\"/>\n"; +} + +void print_xml_feature::visit (const tdesc_type_with_fields *type) +{ + struct tdesc_type_field *f; + const static char *types[] =3D { "struct", "union", "flags", "enum" }; + + gdb_assert (type->kind >=3D TDESC_TYPE_STRUCT && type->kind <=3D TDESC_T= YPE_ENUM); + *m_buffer +=3D "<"; + *m_buffer +=3D types[type->kind - TDESC_TYPE_STRUCT]; + + switch (type->kind) + { + case TDESC_TYPE_STRUCT: + case TDESC_TYPE_FLAGS: + *m_buffer +=3D " id=3D\""; + *m_buffer +=3D type->name; + if (type->size > 0) + { + *m_buffer +=3D "\" size=3D\""; + *m_buffer +=3D std::to_string (type->size); + } + *m_buffer +=3D "\">\n"; + + for (const tdesc_type_field &f : type->fields) + { + *m_buffer +=3D " name; + } + else + { + *m_buffer +=3D "\" start=3D\""; + *m_buffer +=3D std::to_string (f.start); + *m_buffer +=3D "\" end=3D\""; + *m_buffer +=3D std::to_string (f.end); + } + + *m_buffer +=3D "\"/>\n"; + } + break; + + case TDESC_TYPE_ENUM: + *m_buffer +=3D " id=3D\""; + *m_buffer +=3D type->name; + *m_buffer +=3D "\">\n"; + + for (const tdesc_type_field &f : type->fields) + { + *m_buffer +=3D " \n"; + } + break; + + case TDESC_TYPE_UNION: + *m_buffer +=3D " id=3D\""; + *m_buffer +=3D type->name; + *m_buffer +=3D "\">\n"; + + for (const tdesc_type_field &f : type->fields) + { + *m_buffer +=3D " name; + *m_buffer +=3D "\"/>\n"; + } + break; + + default: + error (_("xml output is not supported type \"%s\"."), + type->name.c_str ()); + } + + *m_buffer +=3D "kind - TDESC_TYPE_STRUCT]; + *m_buffer +=3D ">\n"; +} + +void print_xml_feature::visit (const tdesc_reg *reg) +{ + *m_buffer +=3D "name; + *m_buffer +=3D "\" bitsize=3D\""; + *m_buffer +=3D std::to_string (reg->bitsize); + *m_buffer +=3D "\" type=3D\""; + *m_buffer +=3D reg->type; + *m_buffer +=3D "\" regnum=3D\""; + *m_buffer +=3D std::to_string (reg->target_regnum); + if (reg->group.length () > 0) + { + *m_buffer +=3D "\" group=3D\""; + *m_buffer +=3D reg->group; + } + *m_buffer +=3D "\"/>\n"; +} diff --git a/gdb/gdbserver/tdesc.c b/gdb/gdbserver/tdesc.c index a96b3f07e7aff81f32a160d6498c8012d18bd0c7..08b896ba790a0bbf7a47f359525= 55e278830800c 100644 --- a/gdb/gdbserver/tdesc.c +++ b/gdb/gdbserver/tdesc.c @@ -31,7 +31,16 @@ target_desc::~target_desc () } 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 +} bool target_desc::operator=3D=3D (const target_desc &other) const { @@ -158,30 +167,9 @@ tdesc_get_features_xml (target_desc *tdesc) if (tdesc->xmltarget =3D=3D NULL) { - std::string buffer ("@"); - - buffer +=3D ""; - buffer +=3D ""; - buffer +=3D ""; - buffer +=3D tdesc->arch; - buffer +=3D ""; - - if (tdesc->osabi !=3D nullptr) - { - buffer +=3D ""; - buffer +=3D tdesc->osabi; - buffer +=3D ""; - } - - for (const tdesc_feature_up &feature : tdesc->features) - { - buffer +=3D "name; - buffer +=3D "\"/>"; - } - - buffer +=3D ""; - + std::string buffer (""); + print_xml_feature v (&buffer); + tdesc->accept (v); tdesc->xmltarget =3D xstrdup (buffer.c_str ()); } @@ -213,4 +201,24 @@ type *tdesc_type_vector::make_gdb_type (struct gdbarch= *gdbarch) const type *tdesc_type_with_fields::make_gdb_type (struct gdbarch *gdbarch) const { error (_("Cannot create gdbtypes.")); -} \ No newline at end of file +} + +void print_xml_feature::visit_pre (const target_desc *e) +{ +#ifndef IN_PROCESS_AGENT + *m_buffer +=3D "@\n"; + *m_buffer +=3D "\n"; + *m_buffer +=3D "\n"; + *m_buffer +=3D ""; + *m_buffer +=3D e->arch; + *m_buffer +=3D "\n"; + + if (e->osabi !=3D nullptr) + { + *m_buffer +=3D ""; + *m_buffer +=3D e->osabi; + *m_buffer +=3D "\n"; + } +#endif + } + diff --git a/gdb/regformats/regdat.sh b/gdb/regformats/regdat.sh index 8341e11ba76031cc260d60fdc2071bc8a2188f8e..31312fae43dcd369d43e951ffa9= e63af4bef450d 100755 --- a/gdb/regformats/regdat.sh +++ b/gdb/regformats/regdat.sh @@ -189,7 +189,7 @@ fi cat <expedite_regs =3D expedite_regs_${name}; - result->xmltarget =3D xmltarget_${name}; + tdesc_get_features_xml (result); #endif init_target_desc (result); diff --git a/gdb/target-descriptions.h b/gdb/target-descriptions.h index 759fd34a0fe31f84a8531c799e5a3556e768c604..2a177d5b003c1461d837d22cc4f= d5d52c0482ccc 100644 --- a/gdb/target-descriptions.h +++ b/gdb/target-descriptions.h @@ -218,6 +218,8 @@ void tdesc_add_typed_bitfield (tdesc_type_with_fields *= type, const char *field_n void tdesc_add_enum_value (tdesc_type_with_fields *type, int value, const char *name); +void debug (const struct target_desc *); + #if GDB_SELF_TEST namespace selftests { diff --git a/gdb/target-descriptions.c b/gdb/target-descriptions.c index cef65a8fe61e22362e0bc4e6dbd7e3c0a0f4d1b4..6787848b287414cd218ad62e274= 707d5b4b5a368 100644 --- a/gdb/target-descriptions.c +++ b/gdb/target-descriptions.c @@ -86,6 +86,8 @@ struct target_desc : tdesc_element /* The features associated with this target. */ std::vector features; + char *xmltarget =3D nullptr; + void accept (tdesc_element_visitor &v) const override { v.visit_pre (this); @@ -1622,6 +1624,44 @@ private: int m_next_regnum =3D 0; }; +void print_xml_feature::visit_pre (const target_desc *e) +{ + *m_buffer +=3D "\n"; + *m_buffer +=3D "\n"; + *m_buffer +=3D "\n"; + *m_buffer +=3D ""; + *m_buffer +=3D tdesc_architecture (e)->printable_name; + *m_buffer +=3D "\n"; + + if (e->osabi !=3D GDB_OSABI_UNKNOWN) + { + *m_buffer +=3D ""; + *m_buffer +=3D gdbarch_osabi_name (tdesc_osabi (e)); + *m_buffer +=3D "\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 =3D=3D nullptr) + { + std::string buffer (""); + print_xml_feature v (&buffer); + tdesc->accept (v); + tdesc->xmltarget =3D xstrdup (buffer.c_str ()); + } + return tdesc->xmltarget; +} + +void debug (const struct target_desc *tdesc) +{ + printf_filtered (_("%s\n"), tdesc_get_features_xml ((target_desc*) tdesc= )); +} + static void maint_print_c_tdesc_cmd (const char *args, int from_tty) { @@ -1715,7 +1755,34 @@ maintenance_check_xml_descriptions (const char *dir,= int from_tty) =3D file_read_description_xml (tdesc_xml.data ()); if (tdesc =3D=3D NULL || *tdesc !=3D *e.second) - failed++; + { + printf_filtered ( _("Descriptions for %s do not match\n"), e.first); + failed++; + continue; + } + + /* Convert both descriptions to xml, and then back again. Confirm a= ll + descriptions are identical. */ + + const char *xml =3D tdesc_get_features_xml ((target_desc *) tdesc); + const char *xml2 =3D tdesc_get_features_xml ((target_desc *) e.secon= d); + const target_desc *t_trans =3D target_read_description_xml_string (x= ml); + const target_desc *t_trans2 =3D target_read_description_xml_string (= xml2); + + if (t_trans =3D=3D NULL || t_trans2 =3D=3D 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 !=3D *t_trans || *tdesc !=3D *t_trans2) + { + printf_filtered + (_("Translated descriptions for %s do not match (%d %d)\n"), + e.first, *tdesc =3D=3D *t_trans, *tdesc =3D=3D *t_trans2); + failed++; + } } printf_filtered (_("Tested %lu XML files, %d failed\n"), (long) selftests::xml_tdesc.size (), failed); diff --git a/gdb/xml-tdesc.h b/gdb/xml-tdesc.h index 8f0679707ad0f1e04d803f955f7fb98b4cc0c8c8..fee60e86dd10e1543b935c3cebc= e505d4dc828e2 100644 --- a/gdb/xml-tdesc.h +++ b/gdb/xml-tdesc.h @@ -44,5 +44,10 @@ const struct target_desc *target_read_description_xml (s= truct target_ops *); otherwise. */ gdb::optional 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 */ diff --git a/gdb/xml-tdesc.c b/gdb/xml-tdesc.c index 9190d5f3c64ffdc6d7987d651527f597d695c5a6..f793f07c96847a3d61188fff1c5= d63952cc37565 100644 --- a/gdb/xml-tdesc.c +++ b/gdb/xml-tdesc.c @@ -752,3 +752,12 @@ target_fetch_description_xml (struct target_ops *ops) return output; #endif } + +/* Take an xml string, parse it, and return the parsed description. Does = not + handle a string containing includes. */ + +const struct target_desc * +target_read_description_xml_string (const char *xml_str) +{ + return tdesc_parse_xml (xml_str, nullptr, nullptr); +}