diff options
Diffstat (limited to 'gdb/disasm-selftests.c')
-rw-r--r-- | gdb/disasm-selftests.c | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/gdb/disasm-selftests.c b/gdb/disasm-selftests.c index ffd25bd..3ccc174 100644 --- a/gdb/disasm-selftests.c +++ b/gdb/disasm-selftests.c @@ -21,6 +21,7 @@ #include "gdbsupport/selftest.h" #include "selftest-arch.h" #include "gdbarch.h" +#include "disasm-selftests.h" namespace selftests { @@ -329,6 +330,92 @@ memory_error_test (struct gdbarch *gdbarch) SELF_CHECK (saw_memory_error); } +/* Disassemble INSN (a GDBARCH insn), and return the result. */ + +static std::string +disassemble_one_insn_to_string (struct gdbarch *gdbarch, + gdb::array_view<const gdb_byte> insn) +{ + string_file buffer; + + class gdb_disassembler_test : public gdb_disassembler + { + public: + + explicit gdb_disassembler_test (struct gdbarch *gdbarch, + gdb::array_view<const gdb_byte> insn, + string_file &buffer) + : gdb_disassembler (gdbarch, + &buffer, + gdb_disassembler_test::read_memory), + m_insn (insn) + { + } + + int + print_insn (CORE_ADDR memaddr) + { + try + { + return gdb_disassembler::print_insn (memaddr); + } + catch (const gdb_exception_error &) + { + return -1; + } + } + + private: + gdb::array_view<const gdb_byte> m_insn; + + static int read_memory (bfd_vma memaddr, gdb_byte *myaddr, + unsigned int len, + struct disassemble_info *info) noexcept + { + gdb_disassembler_test *self + = static_cast<gdb_disassembler_test *>(info->application_data); + + if (len > self->m_insn.size ()) + return -1; + + for (size_t i = 0; i < len; i++) + myaddr[i] = self->m_insn[i]; + + return 0; + } + }; + + gdb_disassembler_test di (gdbarch, insn, buffer); + if (di.print_insn (0) != insn.size ()) + return ""; + + return buffer.string (); +} + +/* See disasm-selftests.h. */ + +void +disassemble_insn (gdbarch *gdbarch, gdb::byte_vector &insn, + const std::string &expected) +{ + std::string buffer + = disassemble_one_insn_to_string (gdbarch, insn); + + bool check_ok = buffer == expected; + + if (run_verbose () || !check_ok) + { + for (gdb_byte b : insn) + debug_printf ("0x%02x ", b); + debug_printf ("-> %s\n", buffer.c_str ()); + } + + if (!check_ok) + debug_printf ("expected: %s\n", expected.c_str ()); + + SELF_CHECK (check_ok); +} + } /* namespace selftests */ void _initialize_disasm_selftests (); |