aboutsummaryrefslogtreecommitdiff
path: root/gdb/target-descriptions.c
diff options
context:
space:
mode:
authorYao Qi <yao.qi@linaro.org>2017-05-19 21:31:24 +0100
committerYao Qi <yao.qi@linaro.org>2017-06-20 11:34:11 +0100
commita8c099d1b6834606567cf32446a9e3b384a73209 (patch)
tree3fbbddc24ab8e1f43a4063cbd0772e76495f55fc /gdb/target-descriptions.c
parent7b162e155c0c39cad83d7542a61918114d130407 (diff)
downloadgdb-a8c099d1b6834606567cf32446a9e3b384a73209.zip
gdb-a8c099d1b6834606567cf32446a9e3b384a73209.tar.gz
gdb-a8c099d1b6834606567cf32446a9e3b384a73209.tar.bz2
Generate c for feature instead of tdesc
This patch changes Makefile and command "maint print c-files" so that GDB can print c files for features instead target description. Previously, we feed GDB a target description xml file, which generate c files including multiple features. With this patch, in Makefile, we wrap each feature xml file, and create a temp target description which include only one feature. Then, adjust the target description printer for them, and print a c function for each given feature, so that we can use these c functions later to create target description in a flexible way. Before GDB prints c-tdesc, we need to set tdesc. However, this involves some validations in each gdbarch on these target descriptions, and this make troubles to generate c file for each target feature when we feed GDB a target description only including an optional feature (without some mandatory feature), GDB just reject it, and don't print the c file. What we need here is to translate xml file to object target_desc, and translate the object target_desc to c file. We don't have to involve gdbarch validation in this process at all, so I modify command "maint print c-tdesc" to have an optional argument which is the filename of xml target description. If the file name is provided, parse the xml target description, create target_desc object, and print c file from it. gdb: 2017-05-22 Yao Qi <yao.qi@linaro.org> * features/Makefile (FEATURE_XMLFILES): New. (FEATURE_CFILES): New. New rules. * features/i386/32bit-avx.c: Generated. * features/i386/32bit-avx512.c: Generated. * features/i386/32bit-core.c: Generated. * features/i386/32bit-linux.c: Generated. * features/i386/32bit-mpx.c: Generated. * features/i386/32bit-pkeys.c: Generated. * features/i386/32bit-sse.c: Generated. * target-descriptions.c: Include algorithm. (tdesc_element_visitor): Add method visit_end. (print_c_tdesc): Implement visit_end. (print_c_tdesc:: m_filename_after_features): Move it to protected. (print_c_feature): New class. (maint_print_c_tdesc_cmd): Use print_c_feature if XML file name starts with "i386/32bit-". gdb/doc: 2017-06-08 Yao Qi <yao.qi@linaro.org> * gdb.texinfo (Maintenance Commands): Document optional argument of "maint print c-tdesc".
Diffstat (limited to 'gdb/target-descriptions.c')
-rw-r--r--gdb/target-descriptions.c114
1 files changed, 103 insertions, 11 deletions
diff --git a/gdb/target-descriptions.c b/gdb/target-descriptions.c
index 60bc4e5..10f3be1 100644
--- a/gdb/target-descriptions.c
+++ b/gdb/target-descriptions.c
@@ -34,6 +34,7 @@
#include "gdb_obstack.h"
#include "hashtab.h"
#include "inferior.h"
+#include <algorithm>
class tdesc_element_visitor
{
@@ -42,6 +43,8 @@ public:
virtual void visit_end (const target_desc *e) = 0;
virtual void visit (const tdesc_feature *e) = 0;
+ virtual void visit_end (const tdesc_feature *e) = 0;
+
virtual void visit (const tdesc_type *e) = 0;
virtual void visit (const tdesc_reg *e) = 0;
};
@@ -306,8 +309,9 @@ typedef struct tdesc_feature : tdesc_element
{
reg->accept (v);
}
- }
+ v.visit_end (this);
+ }
} *tdesc_feature_p;
DEF_VEC_P(tdesc_feature_p);
@@ -1872,6 +1876,9 @@ public:
e->name);
}
+ void visit_end (const tdesc_feature *e) override
+ {}
+
void visit_end (const target_desc *e) override
{
printf_unfiltered ("\n tdesc_%s = result;\n", m_function);
@@ -2030,38 +2037,123 @@ public:
printf_unfiltered ("%d, \"%s\");\n", reg->bitsize, reg->type);
}
+protected:
+ std::string m_filename_after_features;
+
private:
char *m_function;
- std::string m_filename_after_features;
bool m_printed_field_type = false;
bool m_printed_type = false;
};
+class print_c_feature : public print_c_tdesc
+{
+public:
+ print_c_feature (std::string &file)
+ : print_c_tdesc (file)
+ {
+ /* Trim ".tmp". */
+ auto const pos = m_filename_after_features.find_last_of ('.');
+
+ m_filename_after_features = m_filename_after_features.substr (0, pos);
+ }
+
+ void visit (const target_desc *e) override
+ {
+ printf_unfiltered ("#include \"defs.h\"\n");
+ printf_unfiltered ("#include \"osabi.h\"\n");
+ printf_unfiltered ("#include \"target-descriptions.h\"\n");
+ printf_unfiltered ("\n");
+ }
+
+ void visit_end (const target_desc *e) override
+ {}
+
+ void visit (const tdesc_feature *e) override
+ {
+ std::string name (m_filename_after_features);
+
+ auto pos = name.find_first_of ('.');
+
+ name = name.substr (0, pos);
+ std::replace (name.begin (), name.end (), '/', '_');
+ std::replace (name.begin (), name.end (), '-', '_');
+
+ printf_unfiltered ("static int\n");
+ printf_unfiltered ("create_feature_%s ", name.c_str ());
+ printf_unfiltered ("(struct target_desc *result, long regnum)\n");
+
+ printf_unfiltered ("{\n");
+ printf_unfiltered (" struct tdesc_feature *feature;\n");
+ printf_unfiltered ("\n feature = tdesc_create_feature (result, \"%s\");\n",
+ e->name);
+ }
+
+ void visit_end (const tdesc_feature *e) override
+ {
+ printf_unfiltered (" return regnum;\n");
+ printf_unfiltered ("}\n");
+ }
+
+ void visit (const tdesc_reg *reg) override
+ {
+ printf_unfiltered (" tdesc_create_reg (feature, \"%s\", regnum++, %d, ",
+ reg->name, reg->save_restore);
+ if (reg->group)
+ printf_unfiltered ("\"%s\", ", reg->group);
+ else
+ printf_unfiltered ("NULL, ");
+ printf_unfiltered ("%d, \"%s\");\n", reg->bitsize, reg->type);
+ }
+
+};
+
static void
maint_print_c_tdesc_cmd (char *args, int from_tty)
{
const struct target_desc *tdesc;
+ const char *filename;
+
+ if (args == NULL)
+ {
+ /* Use the global target-supplied description, not the current
+ architecture's. This lets a GDB for one architecture generate C
+ for another architecture's description, even though the gdbarch
+ initialization code will reject the new description. */
+ tdesc = current_target_desc;
+ filename = target_description_filename;
+ }
+ else
+ {
+ /* Use the target description from the XML file. */
+ filename = args;
+ tdesc = file_read_description_xml (filename);
+ }
- /* Use the global target-supplied description, not the current
- architecture's. This lets a GDB for one architecture generate C
- for another architecture's description, even though the gdbarch
- initialization code will reject the new description. */
- tdesc = current_target_desc;
if (tdesc == NULL)
error (_("There is no target description to print."));
- if (target_description_filename == NULL)
+ if (filename == NULL)
error (_("The current target description did not come from an XML file."));
- std::string filename_after_features (target_description_filename);
+ std::string filename_after_features (filename);
auto loc = filename_after_features.rfind ("/features/");
if (loc != std::string::npos)
filename_after_features = filename_after_features.substr (loc + 10);
- print_c_tdesc v (filename_after_features);
+ if (strncmp (filename_after_features.c_str(), "i386/32bit-", 11) == 0)
+ {
+ print_c_feature v (filename_after_features);
+
+ tdesc->accept (v);
+ }
+ else
+ {
+ print_c_tdesc v (filename_after_features);
- tdesc->accept (v);
+ tdesc->accept (v);
+ }
}
/* Provide a prototype to silence -Wmissing-prototypes. */