diff options
-rw-r--r-- | gdb/disasm-selftests.c | 46 | ||||
-rw-r--r-- | gdb/osabi.c | 35 | ||||
-rw-r--r-- | gdb/osabi.h | 3 | ||||
-rw-r--r-- | gdb/selftest-arch.c | 1 |
4 files changed, 76 insertions, 9 deletions
diff --git a/gdb/disasm-selftests.c b/gdb/disasm-selftests.c index 928d26f..7daa013 100644 --- a/gdb/disasm-selftests.c +++ b/gdb/disasm-selftests.c @@ -101,12 +101,52 @@ print_one_insn_test (struct gdbarch *gdbarch) { /* Test disassemble breakpoint instruction. */ CORE_ADDR pc = 0; - int kind = gdbarch_breakpoint_kind_from_pc (gdbarch, &pc); + int kind; int bplen; - insn = gdbarch_sw_breakpoint_from_kind (gdbarch, kind, &bplen); - len = bplen; + struct gdbarch_info info; + info.bfd_arch_info = gdbarch_bfd_arch_info (gdbarch); + + enum gdb_osabi it; + bool found = false; + for (it = GDB_OSABI_UNKNOWN; it != GDB_OSABI_INVALID; + it = static_cast<enum gdb_osabi>(static_cast<int>(it) + 1)) + { + if (it == GDB_OSABI_UNKNOWN) + continue; + + info.osabi = it; + + if (it != GDB_OSABI_NONE) + { + if (!has_gdb_osabi_handler (info)) + /* Unsupported. Skip to prevent warnings like: + A handler for the OS ABI <x> is not built into this + configuration of GDB. Attempting to continue with the + default <y> settings. */ + continue; + } + + gdbarch = gdbarch_find_by_info (info); + SELF_CHECK (gdbarch != NULL); + + try + { + kind = gdbarch_breakpoint_kind_from_pc (gdbarch, &pc); + insn = gdbarch_sw_breakpoint_from_kind (gdbarch, kind, &bplen); + } + catch (...) + { + continue; + } + found = true; + break; + } + + /* Assert that we have found an instruction to disassemble. */ + SELF_CHECK (found); + len = bplen; break; } } diff --git a/gdb/osabi.c b/gdb/osabi.c index bbd7635..f1b7f22 100644 --- a/gdb/osabi.c +++ b/gdb/osabi.c @@ -332,9 +332,10 @@ can_run_code_for (const struct bfd_arch_info *a, const struct bfd_arch_info *b) return (a == b || a->compatible (a, b) == a); } +/* Return OS ABI handler for INFO. */ -void -gdbarch_init_osabi (struct gdbarch_info info, struct gdbarch *gdbarch) +static struct gdb_osabi_handler * +gdbarch_osabi_handler (struct gdbarch_info info) { struct gdb_osabi_handler *handler; @@ -367,10 +368,32 @@ gdbarch_init_osabi (struct gdbarch_info info, struct gdbarch *gdbarch) ISA"). BFD doesn't normally consider 32-bit and 64-bit "compatible" so it doesn't succeed. */ if (can_run_code_for (info.bfd_arch_info, handler->arch_info)) - { - (*handler->init_osabi) (info, gdbarch); - return; - } + return handler; + } + + return nullptr; +} + +/* See osabi.h. */ + +bool +has_gdb_osabi_handler (struct gdbarch_info info) +{ + return gdbarch_osabi_handler (info) != nullptr; +} + +void +gdbarch_init_osabi (struct gdbarch_info info, struct gdbarch *gdbarch) +{ + struct gdb_osabi_handler *handler; + + gdb_assert (info.osabi != GDB_OSABI_UNKNOWN); + handler = gdbarch_osabi_handler (info); + + if (handler != nullptr) + { + (*handler->init_osabi) (info, gdbarch); + return; } if (info.osabi == GDB_OSABI_NONE) diff --git a/gdb/osabi.h b/gdb/osabi.h index be01673..478a418 100644 --- a/gdb/osabi.h +++ b/gdb/osabi.h @@ -74,6 +74,9 @@ enum gdb_osabi gdbarch_lookup_osabi (bfd *); string. */ enum gdb_osabi osabi_from_tdesc_string (const char *text); +/* Return true if there's an OS ABI handler for INFO. */ +bool has_gdb_osabi_handler (struct gdbarch_info info); + /* Initialize the gdbarch for the specified OS ABI variant. */ void gdbarch_init_osabi (struct gdbarch_info, struct gdbarch *); diff --git a/gdb/selftest-arch.c b/gdb/selftest-arch.c index f434da7..1fe0b2d 100644 --- a/gdb/selftest-arch.c +++ b/gdb/selftest-arch.c @@ -68,6 +68,7 @@ foreach_arch_test_generator (const std::string &name, { struct gdbarch_info info; info.bfd_arch_info = bfd_scan_arch (arch); + info.osabi = GDB_OSABI_NONE; struct gdbarch *gdbarch = gdbarch_find_by_info (info); SELF_CHECK (gdbarch != NULL); function (gdbarch); |