• R/O
  • HTTP
  • SSH
  • HTTPS

提交

標籤
無標籤

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

GNU Binutils with patches for OS216


Commit MetaInfo

修訂96ff42812e3d7fc7f2640990331185ffccb4eeb0 (tree)
時間2017-06-20 19:34:12
作者Yao Qi <yao.qi@lina...>
CommiterYao Qi

Log Message

Add "maint check xml-descriptions" to test builtin xml target descriptions

Now, GDB is able to dynamically create i386-linux target descriptions
from features, instead of using pre-generated target descriptions. These
pre-generated target descriptions are no longer used by GDB (note that
they are still used by GDBserver).

This patch add a new maint command "maint check xml-descriptions" to test
dynamically generated tdesc are identical to these generated from xml files.

gdb:

2017-06-06 Yao Qi <yao.qi@linaro.org>

* cli/cli-cmds.c (maintenancechecklist): New variable.
* gdbcmd.h (maintenancechecklist): Declare it.
* i386-linux-tdep.c (_initialize_i386_linux_tdep) [GDB_SELF_TEST]:
Call i386_linux_read_description with different masks.
* maint.c (maintenance_check_command): New function.
(_initialize_maint_cmds): Call add_prefix_cmd.
* target-descriptions.c (tdesc_reg): override operator != and ==.
(tdesc_type): Likewise.
(tdesc_feature): Likewise.
(target_desc): Likewise.
[GDB_SELF_TEST] (selftests::record_xml_tdesc): New function.
(maintenance_check_xml_descriptions): New function.
(_initialize_target_descriptions) Add command "xml-descriptions".
* target-descriptions.h (selftests::record_xml_tdesc): Declare.

gdb/testsuite:

2017-06-06 Yao Qi <yao.qi@linaro.org>

* gdb.gdb/unittest.exp: Invoke command
"maintenance check xml-descriptions".

gdb/doc:

2017-06-06 Yao Qi <yao.qi@linaro.org>

* gdb.texinfo (Maintenance Commands): Document command
"maint check xml-descriptions".

Change Summary

差異

--- a/gdb/cli/cli-cmds.c
+++ b/gdb/cli/cli-cmds.c
@@ -168,6 +168,10 @@ struct cmd_list_element *maintenanceinfolist;
168168
169169 struct cmd_list_element *maintenanceprintlist;
170170
171+/* Chain containing all defined "maintenance check" subcommands. */
172+
173+struct cmd_list_element *maintenancechecklist;
174+
171175 struct cmd_list_element *setprintlist;
172176
173177 struct cmd_list_element *showprintlist;
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -34698,6 +34698,11 @@ The created source file is built into @value{GDBN} when @value{GDBN} is
3469834698 built again. This command is used by developers after they add or
3469934699 modify XML target descriptions.
3470034700
34701+@kindex maint check xml-descriptions
34702+@item maint check xml-descriptions @var{dir}
34703+Check the target descriptions created by @value{GDBN} equal to these
34704+which are created from XML files in @var{dir}.
34705+
3470134706 @kindex maint print dummy-frames
3470234707 @item maint print dummy-frames
3470334708 Prints the contents of @value{GDBN}'s internal dummy-frame stack.
--- a/gdb/gdbcmd.h
+++ b/gdb/gdbcmd.h
@@ -95,6 +95,10 @@ extern struct cmd_list_element *maintenanceinfolist;
9595
9696 extern struct cmd_list_element *maintenanceprintlist;
9797
98+/* Chain containing all defined "maintenance check" subcommands. */
99+
100+extern struct cmd_list_element *maintenancechecklist;
101+
98102 /* Chain containing all defined "maintenance set" subcommands. */
99103
100104 extern struct cmd_list_element *maintenance_set_cmdlist;
--- a/gdb/i386-linux-tdep.c
+++ b/gdb/i386-linux-tdep.c
@@ -1114,4 +1114,24 @@ _initialize_i386_linux_tdep (void)
11141114 {
11151115 gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_LINUX,
11161116 i386_linux_init_abi);
1117+
1118+#if GDB_SELF_TEST
1119+ std::pair<const char *, uint64_t> xml_masks[] = {
1120+ { "i386/i386-linux.xml", X86_XSTATE_SSE_MASK },
1121+ { "i386/i386-mmx-linux.xml", X86_XSTATE_X87_MASK },
1122+ { "i386/i386-avx-linux.xml", X86_XSTATE_AVX_MASK },
1123+ { "i386/i386-mpx-linux.xml", X86_XSTATE_MPX_MASK },
1124+ { "i386/i386-avx-mpx-linux.xml", X86_XSTATE_AVX_MPX_MASK },
1125+ { "i386/i386-avx-avx512-linux.xml", X86_XSTATE_AVX_AVX512_MASK },
1126+ { "i386/i386-avx-mpx-avx512-pku-linux.xml",
1127+ X86_XSTATE_AVX_MPX_AVX512_PKU_MASK },
1128+ };
1129+
1130+ for (auto &a : xml_masks)
1131+ {
1132+ auto tdesc = i386_linux_read_description (a.second);
1133+
1134+ selftests::record_xml_tdesc (a.first, tdesc);
1135+ }
1136+#endif /* GDB_SELF_TEST */
11171137 }
--- a/gdb/maint.c
+++ b/gdb/maint.c
@@ -178,6 +178,19 @@ maintenance_info_command (char *arg, int from_tty)
178178 gdb_stdout);
179179 }
180180
181+/* The "maintenance check" command is defined as a prefix, with
182+ allow_unknown 0. Therefore, its own definition is called only for
183+ "maintenance check" with no args. */
184+
185+static void
186+maintenance_check_command (char *arg, int from_tty)
187+{
188+ printf_unfiltered (_("\"maintenance check\" must be followed "
189+ "by the name of a check command.\n"));
190+ help_list (maintenancechecklist, "maintenance check ", all_commands,
191+ gdb_stdout);
192+}
193+
181194 /* Mini tokenizing lexer for 'maint info sections' command. */
182195
183196 static int
@@ -1104,6 +1117,11 @@ Print the internal architecture configuration.\n\
11041117 Takes an optional file parameter."),
11051118 &maintenanceprintlist);
11061119
1120+ add_prefix_cmd ("check", class_maintenance, maintenance_check_command, _("\
1121+Commands for checking internal gdb state."),
1122+ &maintenancechecklist, "maintenance check ", 0,
1123+ &maintenancelist);
1124+
11071125 add_cmd ("translate-address", class_maintenance,
11081126 maintenance_translate_address,
11091127 _("Translate a section name and address to a symbol."),
--- a/gdb/target-descriptions.c
+++ b/gdb/target-descriptions.c
@@ -132,6 +132,20 @@ typedef struct tdesc_reg : tdesc_element
132132 v.visit (this);
133133 }
134134
135+ bool operator== (const tdesc_reg &other) const
136+ {
137+ return (streq (name, other.name)
138+ && target_regnum == other.target_regnum
139+ && save_restore == other.save_restore
140+ && bitsize == other.bitsize
141+ && (group == other.group || streq (group, other.group))
142+ && streq (type, other.type));
143+ }
144+
145+ bool operator!= (const tdesc_reg &other) const
146+ {
147+ return !(*this == other);
148+ }
135149 } *tdesc_reg_p;
136150 DEF_VEC_P(tdesc_reg_p);
137151
@@ -245,6 +259,15 @@ typedef struct tdesc_type : tdesc_element
245259 v.visit (this);
246260 }
247261
262+ bool operator== (const tdesc_type &other) const
263+ {
264+ return (streq (name, other.name) && kind == other.kind);
265+ }
266+
267+ bool operator!= (const tdesc_type &other) const
268+ {
269+ return !(*this == other);
270+ }
248271 } *tdesc_type_p;
249272 DEF_VEC_P(tdesc_type_p);
250273
@@ -312,6 +335,53 @@ typedef struct tdesc_feature : tdesc_element
312335
313336 v.visit_end (this);
314337 }
338+ bool operator!= (const tdesc_feature &other) const
339+ {
340+ if (strcmp (name, other.name) != 0)
341+ return true;
342+
343+ if (VEC_length (tdesc_reg_p, registers)
344+ != VEC_length (tdesc_reg_p, other.registers))
345+ return true;
346+
347+ struct tdesc_reg *reg;
348+
349+ for (int ix = 0;
350+ VEC_iterate (tdesc_reg_p, registers, ix, reg);
351+ ix++)
352+ {
353+ struct tdesc_reg *reg2
354+ = VEC_index (tdesc_reg_p, other.registers, ix);
355+
356+ if (reg != reg2 && *reg != *reg2)
357+ return true;
358+ }
359+
360+ if (VEC_length (tdesc_type_p, types)
361+ != VEC_length (tdesc_type_p, other.types))
362+ return true;
363+
364+ struct tdesc_type *type;
365+
366+ for (int ix = 0;
367+ VEC_iterate (tdesc_type_p, types, ix, type);
368+ ix++)
369+ {
370+ struct tdesc_type *type2
371+ = VEC_index (tdesc_type_p, other.types, ix);
372+
373+ if (type != type2 && *type != *type2)
374+ return true;
375+ }
376+
377+ return false;
378+ }
379+
380+ bool operator== (const tdesc_feature &other) const
381+ {
382+ return !(*this != other);
383+ }
384+
315385 } *tdesc_feature_p;
316386 DEF_VEC_P(tdesc_feature_p);
317387
@@ -382,6 +452,39 @@ public:
382452
383453 v.visit_end (this);
384454 }
455+
456+ bool operator!= (const target_desc &other) const
457+ {
458+ if (arch != other.arch)
459+ return true;
460+
461+ if (osabi != other.osabi)
462+ return true;
463+
464+ if (VEC_length (tdesc_feature_p, features)
465+ != VEC_length (tdesc_feature_p, other.features))
466+ return true;
467+
468+ struct tdesc_feature *feature;
469+
470+ for (int ix = 0;
471+ VEC_iterate (tdesc_feature_p, features, ix, feature);
472+ ix++)
473+ {
474+ struct tdesc_feature *feature2
475+ = VEC_index (tdesc_feature_p, other.features, ix);
476+
477+ if (feature != feature2 && *feature != *feature2)
478+ return true;
479+ }
480+
481+ return false;
482+ }
483+
484+ bool operator== (const target_desc &other) const
485+ {
486+ return !(*this != other);
487+ }
385488 };
386489
387490 /* Per-architecture data associated with a target description. The
@@ -2167,6 +2270,45 @@ maint_print_c_tdesc_cmd (char *args, int from_tty)
21672270 }
21682271 }
21692272
2273+namespace selftests {
2274+
2275+static std::vector<std::pair<const char*, const target_desc *>> xml_tdesc;
2276+
2277+#if GDB_SELF_TEST
2278+void
2279+record_xml_tdesc (const char *xml_file, const struct target_desc *tdesc)
2280+{
2281+ xml_tdesc.emplace_back (xml_file, tdesc);
2282+}
2283+#endif
2284+
2285+}
2286+
2287+/* Test these GDB builtin target descriptions equal to these which
2288+ are generated by the corresponding xml files. */
2289+
2290+static void
2291+maintenance_check_xml_descriptions (char *name, int from_tty)
2292+{
2293+ if (name == NULL)
2294+ error (_("Missing dir name"));
2295+
2296+ std::string feature_dir (name);
2297+ unsigned int failed = 0;
2298+
2299+ for (auto const &e : selftests::xml_tdesc)
2300+ {
2301+ std::string tdesc_xml = (feature_dir + SLASH_STRING + e.first);
2302+ const target_desc *tdesc
2303+ = file_read_description_xml (tdesc_xml.data ());
2304+
2305+ if (tdesc == NULL || *tdesc != *e.second)
2306+ failed++;
2307+ }
2308+ printf_filtered (_("%lu XML are tested, %d failed\n"),
2309+ (long) selftests::xml_tdesc.size (), failed);
2310+}
2311+
21702312 /* Provide a prototype to silence -Wmissing-prototypes. */
21712313 extern initialize_file_ftype _initialize_target_descriptions;
21722314
@@ -2207,4 +2349,10 @@ GDB will read the description from the target."),
22072349 add_cmd ("c-tdesc", class_maintenance, maint_print_c_tdesc_cmd, _("\
22082350 Print the current target description as a C source file."),
22092351 &maintenanceprintlist);
2352+
2353+ add_cmd ("xml-descriptions", class_maintenance,
2354+ maintenance_check_xml_descriptions, _("\
2355+Check the target descriptions.\n\
2356+Takes a directory parameter."),
2357+ &maintenancechecklist);
22102358 }
--- a/gdb/target-descriptions.h
+++ b/gdb/target-descriptions.h
@@ -253,4 +253,14 @@ void tdesc_create_reg (struct tdesc_feature *feature, const char *name,
253253 int regnum, int save_restore, const char *group,
254254 int bitsize, const char *type);
255255
256+#if GDB_SELF_TEST
257+namespace selftests {
258+
259+/* Record the target description TDESC generated by XML_FILE. */
260+
261+void record_xml_tdesc (const char *xml_file,
262+ const struct target_desc *tdesc);
263+}
264+#endif
265+
256266 #endif /* TARGET_DESCRIPTIONS_H */
--- a/gdb/testsuite/gdb.gdb/unittest.exp
+++ b/gdb/testsuite/gdb.gdb/unittest.exp
@@ -15,3 +15,8 @@
1515
1616 gdb_start
1717 gdb_test "maintenance selftest" "Ran $decimal unit tests, 0 failed"
18+
19+if { ![is_remote host] } {
20+ gdb_test "maintenance check xml-descriptions ${srcdir}/../features" \
21+ "$decimal XML are tested, 0 failed"
22+}