From patchwork Wed Jan 24 09:29:50 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Hayward X-Patchwork-Id: 25491 Received: (qmail 76911 invoked by alias); 24 Jan 2018 09:30:37 -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 18884 invoked by uid 89); 24 Jan 2018 09:29:58 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.8 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=2884, UD:dtd, DOCTYPE, !DOCTYPE X-HELO: EUR01-VE1-obe.outbound.protection.outlook.com Received: from mail-ve1eur01on0078.outbound.protection.outlook.com (HELO EUR01-VE1-obe.outbound.protection.outlook.com) (104.47.1.78) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 24 Jan 2018 09:29:55 +0000 Received: from DB3PR08MB0106.eurprd08.prod.outlook.com (10.161.56.20) by DB3PR08MB0105.eurprd08.prod.outlook.com (10.161.56.19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.428.17; Wed, 24 Jan 2018 09:29:50 +0000 Received: from DB3PR08MB0106.eurprd08.prod.outlook.com ([fe80::958e:90c2:6108:af75]) by DB3PR08MB0106.eurprd08.prod.outlook.com ([fe80::958e:90c2:6108:af75%14]) with mapi id 15.20.0428.019; Wed, 24 Jan 2018 09:29:50 +0000 From: Alan Hayward To: "gdb-patches@sourceware.org" CC: nd Subject: [PATCH v2 6/8] Create xml from target descriptions Date: Wed, 24 Jan 2018 09:29:50 +0000 Message-ID: References: <7C97CC6A-92CB-4702-820D-206022F07102@arm.com> In-Reply-To: <7C97CC6A-92CB-4702-820D-206022F07102@arm.com> authentication-results: spf=none (sender IP is ) smtp.mailfrom=Alan.Hayward@arm.com; x-ms-publictraffictype: Email x-microsoft-exchange-diagnostics: 1; DB3PR08MB0105; 6:zwTcxGZrvauq0+MGOIndoEmY7GgPrjwmW7E8o0YhajdxX+bTYyVEeLY1JDh1pnkvHsCcA/qdQNYl60MwRkg90O6pi1gWWcsPeAyVXlkJryrTHAMDI+IBNZ81tuny+7iwrErgfQbijZITCcK0Sl0mwW99jEvE3eGlBKBIXMejY4bV4FCisLuSSIpu7MMYX0THtbSMEZIVq5QVK1DSVjjlligAvNgm78WUa+mVnqtNKs8PvO4CE61DFwi80Z1m2/d2U/3LVjnCFBAOWg7G9fBJ5SJjGSWeNuUxPqN2JLvy5RF4Oj6DEOPw3GeS+sPXMU14fxmJBoWnJiTneiucSdC1PwV/PoxymvbfYtpjEEVVso4/vh7iWpVf51TDPsPbLfzj; 5:rf6e5H7hzTwNX3AbDr7qTifkG/P324wZUTF7gbHQEO6NS+N8H/0bXcQuYqc1nXcoIWyW4of6S26mirax1iEvKAg0lJ35xDY0+Rqo09SbcILvGBMRod2fA9E1YErRQQqTGQaix7v9xgkdfU2T2xYOQZpD5OOZWO6pmjntOhHDxKc=; 24:rBf7ZMw++FtYpSszM13QRTivU1xTzqVywiO/IUJUxPxAqq+oGNWVbralvCCoqXVztYKvDahdw2pqiRSvjkG8EeVCDFaZ1vwZ7Mx+n70YuJw=; 7:5lKZOMrELsio4MJggcmbMw+LQYNmGQ0NRvLrj5YnACt4dK6wWGKoEeP8cnjAB9eV/Nn8uXBIUQCNv6gSRtSiJfvccvm3yRm0igFcZEHoheGJ/LOvW0QRSjG5nwCCrn4iFMz0/Xi5jSeKILA0li80lDHwnSP71E3/fKcspZozvXhp5V3qioSEYUOHYFBajMPEI1UNri29rb5xN/vhLTmDjnC7m48qn19LPt6gAlezWQok4fPqMwEKNwDmiDmytpFU x-ms-exchange-antispam-srfa-diagnostics: SSOS; x-ms-office365-filtering-ht: Tenant x-ms-office365-filtering-correlation-id: 2b9ada93-55b2-47c3-133b-08d5630d04b7 x-microsoft-antispam: UriScan:; BCL:0; PCL:0; RULEID:(7020095)(4652020)(48565401081)(4534165)(4627221)(201703031133081)(201702281549075)(5600026)(4604075)(3008032)(2017052603307)(7153060)(7193020); SRVR:DB3PR08MB0105; x-ms-traffictypediagnostic: DB3PR08MB0105: nodisclaimer: True x-microsoft-antispam-prvs: x-exchange-antispam-report-test: UriScan:(180628864354917)(131327999870524); x-exchange-antispam-report-cfa-test: BCL:0; PCL:0; RULEID:(6040501)(2401047)(8121501046)(5005006)(93006095)(93001095)(3002001)(10201501046)(3231023)(2400081)(944501161)(6055026)(6041288)(20161123562045)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123558120)(20161123560045)(20161123564045)(6072148)(201708071742011); SRVR:DB3PR08MB0105; BCL:0; PCL:0; RULEID:; SRVR:DB3PR08MB0105; x-forefront-prvs: 056297E276 x-forefront-antispam-report: SFV:NSPM; SFS:(10009020)(366004)(346002)(396003)(39380400002)(376002)(39860400002)(377424004)(199004)(189003)(36756003)(4326008)(66066001)(2351001)(2906002)(68736007)(2900100001)(3280700002)(72206003)(106356001)(26005)(575784001)(86362001)(81156014)(8936002)(81166006)(3660700001)(6916009)(2950100002)(478600001)(8676002)(83716003)(14454004)(305945005)(3846002)(99286004)(4743002)(7736002)(105586002)(316002)(6506007)(5660300001)(97736004)(102836004)(6436002)(82746002)(6116002)(6512007)(25786009)(76176011)(6486002)(59450400001)(5250100002)(2501003)(33656002)(5640700003)(53936002); DIR:OUT; SFP:1101; SCL:1; SRVR:DB3PR08MB0105; H:DB3PR08MB0106.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: XbksuOPiVFHxhUozlQy47s+Z/SUx1VIi/RYy/ZpA6mI1t4PRVjhKJxVOe++YCt5kmKCqt7OKPfnMAz0pFST6BQ== spamdiagnosticoutput: 1:99 spamdiagnosticmetadata: NSPM Content-ID: <3AC6E84BB7831645A2CF79EFA3DE461A@eurprd08.prod.outlook.com> MIME-Version: 1.0 X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-Network-Message-Id: 2b9ada93-55b2-47c3-133b-08d5630d04b7 X-MS-Exchange-CrossTenant-originalarrivaltime: 24 Jan 2018 09:29:50.6843 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: f34e5979-57d9-4aaa-ad4d-b122a662184d X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB3PR08MB0105 X-IsSubscribed: yes This patch adds a print_xml_feature visitor class which turns a C target description into xml. An accept function is added to gdbserver tdesc to allow it to use vistor classes. 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. Alan. 2018-01-24 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. (maintenance_check_xml_descriptions): Test xml generation. * 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 9a5bf6f11b670e04e2b51f8334bc0adaf0b43962..b2e99c5ce1f7da0e6a194ca721eea96082e1fa68 100644 --- a/gdb/arch/tdesc.h +++ b/gdb/arch/tdesc.h @@ -195,7 +195,7 @@ struct tdesc_type_builtin : tdesc_type : tdesc_type (name, kind) {} - void accept (tdesc_element_visitor &v) const override; + void accept (tdesc_element_visitor &v) const override { v.visit (this); } @@ -366,4 +366,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 9518571d03d394ee7cbf78b31974818201c889cd..388c6af1b93d40cf7cb5fb97c55912b91601814b 100644 --- a/gdb/arch/tdesc.c +++ b/gdb/arch/tdesc.c @@ -288,4 +288,138 @@ tdesc_add_enum_value (tdesc_type_with_fields *type, int value, type->fields.emplace_back (name, tdesc_predefined_type (TDESC_TYPE_INT32), value, -1); -} \ No newline at end of file +} + +void print_xml_feature::visit_post (const target_desc *e) +{ + *m_buffer += "\n"; +} + +void print_xml_feature::visit_pre (const tdesc_feature *e) +{ + *m_buffer += "name; + *m_buffer += "\">\n"; +} + +void print_xml_feature::visit_post (const tdesc_feature *e) +{ + *m_buffer += "\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 += "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 += " 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 += " \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 += " name; + *m_buffer += "\"/>\n"; + } + break; + + default: + error (_("xml output is not supported type \"%s\"."), + type->name.c_str ()); + } + + *m_buffer += "kind - TDESC_TYPE_STRUCT]; + *m_buffer += ">\n"; +} + +void print_xml_feature::visit (const tdesc_reg *reg) +{ + *m_buffer += "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"; +} diff --git a/gdb/gdbserver/tdesc.h b/gdb/gdbserver/tdesc.h index 8ae6cddc1896af99d86206d159fb952a0f666043..6a86f66cf2aaf9aa2b20203cad1d272d70026822 100644 --- a/gdb/gdbserver/tdesc.h +++ b/gdb/gdbserver/tdesc.h @@ -27,7 +27,7 @@ /* A target description. Inherit from tdesc_feature so that target_desc can be used as tdesc_feature. */ -struct target_desc +struct target_desc : tdesc_element { /* A vector of elements of register definitions that describe the inferior's register set. */ @@ -72,7 +72,10 @@ public: { return !(*this == other); } + #endif + + void accept (tdesc_element_visitor &v) const; }; /* Copy target description SRC to DEST. */ diff --git a/gdb/gdbserver/tdesc.c b/gdb/gdbserver/tdesc.c index f0bd266a54601484df74ee1c5f8dce6fe04661c4..42a657f6827ed06c9d98275c7566d0c02890e7b3 100644 --- a/gdb/gdbserver/tdesc.c +++ b/gdb/gdbserver/tdesc.c @@ -59,6 +59,18 @@ bool target_desc::operator== (const target_desc &other) const #endif +void target_desc::accept (tdesc_element_visitor &v) const +{ +#ifndef IN_PROCESS_AGENT + v.visit_pre (this); + + for (const tdesc_feature_up &feature : features) + feature->accept (v); + + v.visit_post (this); +#endif +} + void init_target_desc (struct target_desc *tdesc) { @@ -155,30 +167,9 @@ tdesc_get_features_xml (target_desc *tdesc) if (tdesc->xmltarget == NULL) { - std::string buffer ("@"); - - buffer += ""; - buffer += ""; - buffer += ""; - buffer += tdesc->arch; - buffer += ""; - - if (tdesc->osabi != nullptr) - { - buffer += ""; - buffer += tdesc->osabi; - buffer += ""; - } - - for (const tdesc_feature_up &feature : tdesc->features) - { - buffer += "name; - buffer += "\"/>"; - } - - buffer += ""; - + std::string buffer (""); + print_xml_feature v (&buffer); + tdesc->accept (v); tdesc->xmltarget = xstrdup (buffer.c_str ()); } @@ -211,3 +202,22 @@ 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 + *m_buffer += "@\n"; + *m_buffer += "\n"; + *m_buffer += "\n"; + *m_buffer += ""; + *m_buffer += e->arch; + *m_buffer += "\n"; + + if (e->osabi != nullptr) + { + *m_buffer += ""; + *m_buffer += e->osabi; + *m_buffer += "\n"; + } +#endif + } diff --git a/gdb/regformats/regdat.sh b/gdb/regformats/regdat.sh index 8c6e191596350fb4e983f8736985d9832f41e2d3..e6e06bdab0bdecc579686f3525e9f93555e0dd83 100755 --- a/gdb/regformats/regdat.sh +++ b/gdb/regformats/regdat.sh @@ -180,7 +180,6 @@ echo cat <expedite_regs = expedite_regs_${name}; - result->xmltarget = xmltarget_${name}; #endif init_target_desc (result); diff --git a/gdb/target-descriptions.c b/gdb/target-descriptions.c index 4f11120dce4092f15de99680a7c4868c4a2f4493..68a85758f7f63e6b862afa29697adee77e776d89 100644 --- a/gdb/target-descriptions.c +++ b/gdb/target-descriptions.c @@ -316,6 +316,8 @@ struct target_desc : tdesc_element /* The features associated with this target. */ std::vector features; + char *xmltarget = nullptr; + void accept (tdesc_element_visitor &v) const override { v.visit_pre (this); @@ -1633,6 +1635,39 @@ private: int m_next_regnum = 0; }; +void print_xml_feature::visit_pre (const target_desc *e) +{ + *m_buffer += "\n"; + *m_buffer += "\n"; + *m_buffer += "\n"; + *m_buffer += ""; + *m_buffer += tdesc_architecture (e)->printable_name; + *m_buffer += "\n"; + + if (e->osabi != GDB_OSABI_UNKNOWN) + { + *m_buffer += ""; + *m_buffer += gdbarch_osabi_name (tdesc_osabi (e)); + *m_buffer += "\n"; + } +} + +/* Return a string which is of XML format, including XML target + description to be sent to GDB. */ + +const char * +tdesc_get_features_xml (target_desc *tdesc) +{ + if (tdesc->xmltarget == nullptr) + { + std::string buffer (""); + print_xml_feature v (&buffer); + tdesc->accept (v); + tdesc->xmltarget = xstrdup (buffer.c_str ()); + } + return tdesc->xmltarget; +} + static void maint_print_c_tdesc_cmd (const char *args, int from_tty) { @@ -1726,7 +1761,34 @@ maintenance_check_xml_descriptions (const char *dir, int from_tty) = file_read_description_xml (tdesc_xml.data ()); if (tdesc == NULL || *tdesc != *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 all + descriptions are identical. */ + + const char *xml = tdesc_get_features_xml ((target_desc *) tdesc); + const char *xml2 = tdesc_get_features_xml ((target_desc *) e.second); + const target_desc *t_trans = target_read_description_xml_string (xml); + const target_desc *t_trans2 = target_read_description_xml_string (xml2); + + if (t_trans == NULL || t_trans2 == NULL) + { + printf_filtered ( + _("Could not convert descriptions for %s back to xml (%p %p)\n"), + e.first, t_trans, t_trans2); + failed++; + } + else if (*tdesc != *t_trans || *tdesc != *t_trans2) + { + printf_filtered + (_("Translated descriptions for %s do not match (%d %d)\n"), + e.first, *tdesc == *t_trans, *tdesc == *t_trans2); + failed++; + } } printf_filtered (_("Tested %lu XML files, %d failed\n"), (long) selftests::xml_tdesc.size (), failed); diff --git a/gdb/xml-tdesc.h b/gdb/xml-tdesc.h index 8f0679707ad0f1e04d803f955f7fb98b4cc0c8c8..fee60e86dd10e1543b935c3cebce505d4dc828e2 100644 --- a/gdb/xml-tdesc.h +++ b/gdb/xml-tdesc.h @@ -44,5 +44,10 @@ const struct target_desc *target_read_description_xml (struct 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..f793f07c96847a3d61188fff1c5d63952cc37565 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); +}