From: Yao Qi <qiyaoltc@gmail.com>
To: binutils@sourceware.org, gdb-patches@sourceware.org
Subject: [PATCH 3/8] Disassembly unit test: disassemble one instruction
Date: Tue, 10 Jan 2017 12:26:00 -0000 [thread overview]
Message-ID: <1484051178-16013-4-git-send-email-yao.qi@linaro.org> (raw)
In-Reply-To: <1484051178-16013-1-git-send-email-yao.qi@linaro.org>
This patch adds one unit test, which disassemble one instruction for
every gdbarch if available. The test needs one valid instruction of
each gdbarch, and most of them are got from breakpoint instruction.
For the rest gdbarch whose breakpoint instruction isn't a valid
instruction, I copy one instruction from the gas/testsuite/gas/
directory.
I get the valid instruction of most gdbarch except ia64, mep, mips,
tic6x, and xtensa. People familiar with these arch should be easy
to extend the test.
In order to achieve "do the unit test for every gdbarch", I extend
selftest.[c,h], so that we can register a function pointer, which
has one argument gdbarch. selftest.c will iterate over all gdbarches
to call the registered function pointer.
gdb:
2017-01-06 Yao Qi <yao.qi@linaro.org>
* disasm.c [GDB_SELF_TEST]: Include selftest.h.
(selftests::gdb_disassembler_print_one_insn_test): New function.
(_initialize_disasm): New function.
* selftest.c: Include "arch-utils.h".
(gdbarch_tests): New vector.
(register_self_test): New function.
(run_self_tests): Iterate each gdbarch and call functions in
gdbarch_tests.
* selftest.h (self_test_function_with_gdbarch): New typedef.
(register_self_test): Declare.
---
gdb/disasm.c | 148 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
gdb/selftest.c | 55 +++++++++++++++++++++
gdb/selftest.h | 3 ++
3 files changed, 206 insertions(+)
diff --git a/gdb/disasm.c b/gdb/disasm.c
index 6a3f3aa..6e403da 100644
--- a/gdb/disasm.c
+++ b/gdb/disasm.c
@@ -27,6 +27,10 @@
#include "source.h"
#include <algorithm>
+#if GDB_SELF_TEST
+#include "selftest.h"
+#endif /* GDB_SELF_TEST */
+
/* Disassemble functions.
FIXME: We should get rid of all the duplicate code in gdb that does
the same thing: disassemble_command() and the gdbtk variation. */
@@ -290,6 +294,139 @@ gdb_disassembler::pretty_print_insn (struct ui_out *uiout,
return size;
}
+#if GDB_SELF_TEST
+
+namespace selftests {
+
+/* Test disassembly one instruction. */
+
+static void
+gdb_disassembler_print_one_insn_test (struct gdbarch *gdbarch)
+{
+ int len = -1;
+ const gdb_byte *insn = NULL;
+
+ switch (gdbarch_bfd_arch_info (gdbarch)->arch)
+ {
+ case bfd_arch_bfin:
+ /* M3.L = 0xe117 */
+ insn = (const gdb_byte[]) {0x17, 0xe1, 0xff, 0xff};
+ len = 4;
+ break;
+ case bfd_arch_arm:
+ /* mov r0, #0 */
+ insn = (const gdb_byte[]) {0x0, 0x0, 0xa0, 0xe3};
+ len = 4;
+ break;
+ case bfd_arch_ia64:
+ case bfd_arch_mep:
+ case bfd_arch_mips:
+ case bfd_arch_tic6x:
+ case bfd_arch_xtensa:
+ return;
+ case bfd_arch_s390:
+ /* nopr %r7 */
+ insn = (const gdb_byte[]) {0x07, 0x07};
+ len = 2;
+ break;
+ case bfd_arch_xstormy16:
+ /* nop */
+ insn = (const gdb_byte[]) {0x0, 0x0};
+ len = 2;
+ break;
+ case bfd_arch_arc:
+ {
+ /* PR 21003 */
+ if (gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_arc_arc601)
+ return;
+ }
+ case bfd_arch_nios2:
+ case bfd_arch_score:
+ insn = gdbarch_sw_breakpoint_from_kind (gdbarch, 4, &len);
+ break;
+ case bfd_arch_sh:
+ insn = gdbarch_sw_breakpoint_from_kind (gdbarch, 2, &len);
+ break;
+ default:
+ {
+ /* Test disassemble breakpoint instruction. */
+ CORE_ADDR pc = 0;
+ int kind = gdbarch_breakpoint_kind_from_pc (gdbarch, &pc);
+
+ insn = gdbarch_sw_breakpoint_from_kind (gdbarch, kind,
+ &len);
+
+ break;
+ }
+ }
+ SELF_CHECK (len > 0);
+
+ /* Test gdb_disassembler for a given gdbarch by reading data from a
+ pre-allocated buffer. If you want to see the disassembled
+ instruction printed to gdb_stdout, define macro
+ DISASSEMBLER_TEST_VERBOSE. */
+
+ class gdb_disassembler_test : public gdb_disassembler
+ {
+ public:
+
+#ifndef DISASSEMBLER_TEST_VERBOSE
+ explicit gdb_disassembler_test (struct gdbarch *gdbarch,
+ const gdb_byte *insn)
+ : gdb_disassembler (gdbarch, ui_file_new (),
+ gdb_disassembler_test::read_memory),
+ m_insn (insn)
+ {
+ }
+
+ ~gdb_disassembler_test ()
+ {
+ ui_file_delete ((struct ui_file *) m_di.stream);
+ }
+#else
+ explicit gdb_disassembler_test (struct gdbarch *gdbarch,
+ const gdb_byte *insn)
+ : gdb_disassembler (gdbarch, gdb_stdout,
+ gdb_disassembler_test::read_memory),
+ m_insn (insn)
+ {
+ }
+
+ int
+ print_insn (CORE_ADDR memaddr)
+ {
+ fprintf_unfiltered (stream (), "%s ",
+ gdbarch_bfd_arch_info (arch ())->arch_name);
+
+ int len = gdb_disassembler::print_insn (memaddr);
+
+ fprintf_unfiltered (stream (), "\n");
+ return len;
+ }
+#endif /* DISASSEMBLER_TEST_VERBOSE */
+
+ private:
+ const gdb_byte *m_insn;
+
+ static int read_memory (bfd_vma memaddr, gdb_byte *myaddr,
+ unsigned int len, struct disassemble_info *info)
+ {
+ gdb_disassembler_test *self
+ = static_cast<gdb_disassembler_test *>(info->application_data);
+
+ memcpy (myaddr, self->m_insn, len);
+ return 0;
+ }
+ };
+
+ gdb_disassembler_test di (gdbarch, insn);
+
+ SELF_CHECK (di.print_insn (0) == len);
+}
+
+} // namespace selftests
+#endif /* GDB_SELF_TEST */
+
static int
dump_insns (struct ui_out *uiout, gdb_disassembler *di,
CORE_ADDR low, CORE_ADDR high,
@@ -937,3 +1074,14 @@ gdb_buffered_insn_length (struct gdbarch *gdbarch,
return gdbarch_print_insn (gdbarch, addr, &di);
}
+
+/* Suppress warning from -Wmissing-prototypes. */
+extern initialize_file_ftype _initialize_disasm;
+
+void
+_initialize_disasm (void)
+{
+#if GDB_SELF_TEST
+ register_self_test (selftests::gdb_disassembler_print_one_insn_test);
+#endif
+}
diff --git a/gdb/selftest.c b/gdb/selftest.c
index adc7dda..8835473 100644
--- a/gdb/selftest.c
+++ b/gdb/selftest.c
@@ -18,11 +18,13 @@
#include "defs.h"
#include "selftest.h"
+#include "arch-utils.h"
#include <vector>
/* All the tests that have been registered. */
static std::vector<self_test_function *> tests;
+static std::vector<self_test_function_with_gdbarch *> gdbarch_tests;
/* See selftest.h. */
@@ -32,6 +34,12 @@ register_self_test (self_test_function *function)
tests.push_back (function);
}
+void
+register_self_test (self_test_function_with_gdbarch *function)
+{
+ gdbarch_tests.push_back (function);
+}
+
/* See selftest.h. */
void
@@ -55,6 +63,53 @@ run_self_tests (void)
END_CATCH
}
+ for (const auto &f : gdbarch_tests)
+ {
+ const char **arches = gdbarch_printable_names ();
+ int i;
+
+ for (i = 0; arches[i] != NULL; i++)
+ {
+ if (strcmp ("fr300", arches[i]) == 0)
+ {
+ /* PR 20946 */
+ continue;
+ }
+ else if (strcmp ("powerpc:EC603e", arches[i]) == 0
+ || strcmp ("powerpc:e500mc", arches[i]) == 0
+ || strcmp ("powerpc:e500mc64", arches[i]) == 0
+ || strcmp ("powerpc:titan", arches[i]) == 0
+ || strcmp ("powerpc:vle", arches[i]) == 0
+ || strcmp ("powerpc:e5500", arches[i]) == 0
+ || strcmp ("powerpc:e6500", arches[i]) == 0)
+ {
+ /* PR 19797 */
+ continue;
+ }
+
+ QUIT;
+
+ TRY
+ {
+ struct gdbarch_info info;
+
+ gdbarch_info_init (&info);
+ info.bfd_arch_info = bfd_scan_arch (arches[i]);
+
+ struct gdbarch *gdbarch = gdbarch_find_by_info (info);
+ SELF_CHECK (gdbarch != NULL);
+ f (gdbarch);
+ }
+ CATCH (ex, RETURN_MASK_ERROR)
+ {
+ ++failed;
+ exception_fprintf (gdb_stderr, ex,
+ _("Self test failed: arch %s: "), arches[i]);
+ }
+ END_CATCH
+ }
+ }
+
printf_filtered (_("Ran %lu unit tests, %d failed\n"),
(long) tests.size (), failed);
}
diff --git a/gdb/selftest.h b/gdb/selftest.h
index 94684ff..4446780 100644
--- a/gdb/selftest.h
+++ b/gdb/selftest.h
@@ -24,9 +24,12 @@
typedef void self_test_function (void);
+typedef void self_test_function_with_gdbarch (struct gdbarch *);
+
/* Register a new self-test. */
extern void register_self_test (self_test_function *function);
+extern void register_self_test (self_test_function_with_gdbarch *function);
/* Run all the self tests. This print a message describing the number
of test and the number of failures. */
--
1.9.1
next prev parent reply other threads:[~2017-01-10 12:26 UTC|newest]
Thread overview: 79+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-01-10 12:26 [PATCH 0/8] Handle memory error on disassemble Yao Qi
2017-01-10 12:26 ` Yao Qi [this message]
2017-01-11 21:15 ` [PATCH 3/8] Disassembly unit test: disassemble one instruction Simon Marchi
2017-01-12 13:06 ` Pedro Alves
2017-01-12 17:03 ` Yao Qi
2017-01-12 17:43 ` Pedro Alves
2017-01-12 21:04 ` Yao Qi
2017-01-12 14:35 ` Pedro Alves
2017-01-12 15:15 ` Pedro Alves
2017-01-12 15:35 ` Yao Qi
2017-01-12 15:44 ` Pedro Alves
2017-01-12 16:06 ` Pedro Alves
2017-01-10 12:26 ` [PATCH 4/8] Return -1 on memory error in print_insn_msp430 Yao Qi
2017-01-11 21:54 ` Alan Modra
2017-01-12 9:43 ` Yao Qi
2017-01-10 12:26 ` [PATCH 7/8] Disassembly unit test: memory error Yao Qi
2017-01-10 12:26 ` [PATCH 5/8] Remove magic numbers in m68k-dis.c:print_insn_arg Yao Qi
2017-01-11 22:14 ` Alan Modra
2017-01-13 12:23 ` Yao Qi
2017-01-10 12:26 ` [PATCH 6/8] Return -1 on memory error in print_insn_m68k Yao Qi
2017-01-11 22:15 ` Alan Modra
2017-01-12 11:50 ` Yao Qi
2017-01-12 14:38 ` Alan Modra
2017-01-12 14:52 ` Yao Qi
2017-01-13 1:54 ` Alan Modra
2017-01-13 12:29 ` Yao Qi
2017-01-10 12:27 ` [PATCH 8/8] Don't throw exception in dis_asm_memory_error Yao Qi
2017-01-12 16:40 ` Pedro Alves
2017-01-12 21:09 ` Yao Qi
2017-01-10 12:27 ` [PATCH 2/8] Call print_insn_mep in mep_gdb_print_insn Yao Qi
2017-01-11 20:50 ` Simon Marchi
2017-01-12 12:21 ` Yao Qi
2017-01-10 12:27 ` [PATCH 1/8] Refactor disassembly code Yao Qi
2017-01-11 20:43 ` Simon Marchi
2017-01-12 12:19 ` Yao Qi
2017-01-12 12:36 ` Pedro Alves
2017-01-12 15:29 ` Simon Marchi
2017-01-16 10:03 ` [PATCH 0/6 v2] Handle memory error on disassemble Yao Qi
2017-01-16 10:03 ` [PATCH 3/6] Call print_insn_mep in mep_gdb_print_insn Yao Qi
2017-01-17 14:19 ` Luis Machado
2017-01-24 10:08 ` Yao Qi
2017-01-24 13:41 ` Luis Machado
2017-01-16 10:03 ` [PATCH 6/6] Don't throw exception in dis_asm_memory_error Yao Qi
2017-01-17 14:42 ` Luis Machado
2017-01-18 14:54 ` Yao Qi
2017-01-18 14:58 ` Luis Machado
2017-01-16 10:03 ` [PATCH 2/6] Refactor disassembly code Yao Qi
2017-01-17 14:14 ` Luis Machado
2017-01-18 16:34 ` Yao Qi
2017-01-18 16:53 ` Luis Machado
2017-01-16 10:03 ` [PATCH 5/6] Disassembly unit test: memory error Yao Qi
2017-01-17 14:38 ` Luis Machado
2017-01-24 15:33 ` Yao Qi
2017-01-20 0:08 ` Pedro Alves
2017-01-16 10:03 ` [PATCH 1/6] New function null_stream Yao Qi
2017-01-17 13:49 ` Luis Machado
2017-01-18 14:45 ` Yao Qi
2017-01-18 14:53 ` Luis Machado
2017-01-18 14:57 ` Simon Marchi
2017-01-18 15:02 ` Luis Machado
2017-01-18 15:18 ` Simon Marchi
2017-01-18 15:29 ` Luis Machado
2017-01-18 15:54 ` Simon Marchi
2017-01-18 16:36 ` Luis Machado
2017-01-16 10:03 ` [PATCH 4/6] Disassembly unit test: disassemble one instruction Yao Qi
2017-01-20 0:04 ` Pedro Alves
2017-01-24 15:23 ` Yao Qi
2017-02-02 16:46 ` Pedro Alves
2017-02-02 22:12 ` Yao Qi
2017-02-02 23:39 ` [pushed] Fix "maintenance selftest" printing stray instructions (Re: [PATCH 4/6] Disassembly unit test: disassemble one instruction) Pedro Alves
2017-01-25 8:38 ` [PATCH 0/6 v3] Handle memory error on disassembly Yao Qi
2017-01-25 8:38 ` [PATCH 3/6] Call print_insn_mep in mep_gdb_print_insn Yao Qi
2017-01-25 8:38 ` [PATCH 6/6] Don't throw exception in dis_asm_memory_error Yao Qi
2017-01-25 8:38 ` [PATCH 4/6] Disassembly unit test: disassemble one instruction Yao Qi
2017-01-25 8:38 ` [PATCH 1/6] New function null_stream Yao Qi
2017-01-25 8:38 ` [PATCH 5/6] Disassembly unit test: memory error Yao Qi
2017-01-25 8:38 ` [PATCH 2/6] Refactor disassembly code Yao Qi
2017-01-26 11:34 ` [PATCH 0/6 v3] Handle memory error on disassembly Pedro Alves
2017-01-26 15:00 ` Yao Qi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1484051178-16013-4-git-send-email-yao.qi@linaro.org \
--to=qiyaoltc@gmail.com \
--cc=binutils@sourceware.org \
--cc=gdb-patches@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox