diff options
author | Alan Hayward <alan.hayward@arm.com> | 2018-04-18 20:09:12 +0100 |
---|---|---|
committer | Alan Hayward <alan.hayward@arm.com> | 2018-04-18 20:44:39 +0100 |
commit | e98577a9dc4da048ded601920dc6471dcab375aa (patch) | |
tree | 375ce804dcb3c8308b95542b7a8e16ed5d4803e1 /gdb/common | |
parent | ad7fc756d12a841d4b8dd707568426d875e26755 (diff) | |
download | gdb-e98577a9dc4da048ded601920dc6471dcab375aa.zip gdb-e98577a9dc4da048ded601920dc6471dcab375aa.tar.gz gdb-e98577a9dc4da048ded601920dc6471dcab375aa.tar.bz2 |
Create xml from target descriptions
Add a print_xml_feature visitor class which turns a
target description into xml. Both gdb and gdbserver can do this.
gdb/
* common/tdesc.c (print_xml_feature::visit_pre): Add xml parsing.
(print_xml_feature::visit_post): Likewise.
(print_xml_feature::visit): Likewise.
* common/tdesc.h (tdesc_get_features_xml): Use const tdesc.
(print_xml_feature): Add new class.
* regformats/regdat.sh: Null xmltarget on feature targets.
* target-descriptions.c (struct target_desc): Add xmltarget.
(maintenance_check_tdesc_xml_convert): Add unittest function.
(tdesc_get_features_xml): Add function to get xml.
(maintenance_check_xml_descriptions): Test xml generation.
* xml-tdesc.c (string_read_description_xml): Add function.
* xml-tdesc.h (string_read_description_xml): Add declaration.
gdbserver/
* gdb/gdbserver/server.c (get_features_xml): Remove cast.
* 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.
* tdesc.h (struct target_desc): Make xmltarget mutable.
(tdesc_get_features_xml): Remove declaration.
Diffstat (limited to 'gdb/common')
-rw-r--r-- | gdb/common/tdesc.c | 109 | ||||
-rw-r--r-- | gdb/common/tdesc.h | 26 |
2 files changed, 135 insertions, 0 deletions
diff --git a/gdb/common/tdesc.c b/gdb/common/tdesc.c index b9e9ddb..68584a7 100644 --- a/gdb/common/tdesc.c +++ b/gdb/common/tdesc.c @@ -290,3 +290,112 @@ tdesc_add_enum_value (tdesc_type_with_fields *type, int value, tdesc_predefined_type (TDESC_TYPE_INT32), value, -1); } + +void print_xml_feature::visit_pre (const tdesc_feature *e) +{ + string_appendf (*m_buffer, "<feature name=\"%s\">\n", e->name.c_str ()); +} + +void print_xml_feature::visit_post (const tdesc_feature *e) +{ + string_appendf (*m_buffer, "</feature>\n"); +} + +void print_xml_feature::visit (const tdesc_type_builtin *t) +{ + error (_("xml output is not supported for type \"%s\"."), t->name.c_str ()); +} + +void print_xml_feature::visit (const tdesc_type_vector *t) +{ + string_appendf (*m_buffer, "<vector id=\"%s\" type=\"%s\" count=\"%d\"/>\n", + t->name.c_str (), t->element_type->name.c_str (), t->count); +} + +void print_xml_feature::visit (const tdesc_type_with_fields *t) +{ + struct tdesc_type_field *f; + const static char *types[] = { "struct", "union", "flags", "enum" }; + + gdb_assert (t->kind >= TDESC_TYPE_STRUCT && t->kind <= TDESC_TYPE_ENUM); + + string_appendf (*m_buffer, + "<%s id=\"%s\"", types[t->kind - TDESC_TYPE_STRUCT], + t->name.c_str ()); + + switch (t->kind) + { + case TDESC_TYPE_STRUCT: + case TDESC_TYPE_FLAGS: + if (t->size > 0) + string_appendf (*m_buffer, " size=\"%d\"", t->size); + string_appendf (*m_buffer, ">\n"); + + for (const tdesc_type_field &f : t->fields) + { + string_appendf (*m_buffer, " <field name=\"%s\" ", f.name.c_str ()); + if (f.start == -1) + string_appendf (*m_buffer, "type=\"%s\"/>\n", + f.type->name.c_str ()); + else + string_appendf (*m_buffer, "start=\"%d\" end=\"%d\"/>\n", f.start, + f.end); + } + break; + + case TDESC_TYPE_ENUM: + string_appendf (*m_buffer, ">\n"); + for (const tdesc_type_field &f : t->fields) + string_appendf (*m_buffer, " <field name=\"%s\" start=\"%d\"/>\n", + f.name.c_str (), f.start); + break; + + case TDESC_TYPE_UNION: + string_appendf (*m_buffer, ">\n"); + for (const tdesc_type_field &f : t->fields) + string_appendf (*m_buffer, " <field name=\"%s\" type=\"%s\"/>\n", + f.name.c_str (), f.type->name.c_str ()); + break; + + default: + error (_("xml output is not supported for type \"%s\"."), + t->name.c_str ()); + } + + string_appendf (*m_buffer, "</%s>\n", types[t->kind - TDESC_TYPE_STRUCT]); +} + +void print_xml_feature::visit (const tdesc_reg *r) +{ + string_appendf (*m_buffer, + "<reg name=\"%s\" bitsize=\"%d\" type=\"%s\" regnum=\"%ld\"", + r->name.c_str (), r->bitsize, r->type.c_str (), + r->target_regnum); + + if (r->group.length () > 0) + string_appendf (*m_buffer, " group=\"%s\"", r->group.c_str ()); + + if (r->save_restore == 0) + string_appendf (*m_buffer, " save-restore=\"no\""); + + string_appendf (*m_buffer, "/>\n"); +} + +void print_xml_feature::visit_pre (const target_desc *e) +{ +#ifndef IN_PROCESS_AGENT + string_appendf (*m_buffer, "<?xml version=\"1.0\"?>\n"); + string_appendf (*m_buffer, "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">\n"); + string_appendf (*m_buffer, "<target>\n<architecture>%s</architecture>\n", + tdesc_architecture_name (e)); + + const char *osabi = tdesc_osabi_name (e); + if (osabi != nullptr) + string_appendf (*m_buffer, "<osabi>%s</osabi>", osabi); +#endif +} + +void print_xml_feature::visit_post (const target_desc *e) +{ + string_appendf (*m_buffer, "</target>\n"); +} diff --git a/gdb/common/tdesc.h b/gdb/common/tdesc.h index 8b826ec..6868bf4 100644 --- a/gdb/common/tdesc.h +++ b/gdb/common/tdesc.h @@ -380,4 +380,30 @@ 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 (const 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_) + {} + + 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 */ |