--- arch-utils.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ exec.c | 21 ++++++++++++++++++--- 2 files changed, 74 insertions(+), 3 deletions(-) --- a/arch-utils.c +++ b/arch-utils.c @@ -32,6 +32,7 @@ #include "osabi.h" #include "target-descriptions.h" #include "objfiles.h" +#include "libbfd.h" #include "version.h" @@ -776,6 +777,36 @@ default_fast_tracepoint_valid_at (struct return 1; } +/* For cmd "set bfd". */ + +static const char **bfds; + +static const char *set_bfd_string; + +static void +show_bfd (struct ui_file *file, int from_tty, + struct cmd_list_element *c, const char *value) +{ + fprintf_filtered (file, _("\ +The default executable format is %s\n"), set_bfd_string); +} + +static void +set_bfd (char *ignore_args, int from_tty, struct cmd_list_element *c) +{ + int nr; + + for (nr = 0; bfd_target_vector[nr]; nr++) + { + if (bfd_target_vector[nr]->name == set_bfd_string) + { + bfd_associated_vector[0] = bfd_target_vector[nr]; + show_bfd (gdb_stdout, from_tty, NULL, NULL); + return; + } + } +} + /* */ extern initialize_file_ftype _initialize_gdbarch_utils; /* -Wmissing-prototypes */ @@ -790,4 +821,29 @@ Set endianness of target."), _("\ Show endianness of target."), NULL, set_endian, show_endian, &setlist, &showlist); + + /* Add cmd "set bfd". */ + if (bfd_associated_vector[0]) + { + int nr; + + /* Initialize bfds. */ + for (nr = 0; bfd_target_vector[nr]; nr++); + bfds = xcalloc (sizeof (char *), nr + 1); + for (nr = 0; bfd_target_vector[nr]; nr++) + bfds[nr] = bfd_target_vector[nr]->name; + bfds[nr + 1] = NULL; + + /* Initialize set_bfd_string. */ + set_bfd_string = bfd_associated_vector[0]->name; + + add_setshow_enum_cmd ("bfd", class_support, + bfds, &set_bfd_string, _("\ +Set the default executable format when more than \n\ +one executable format support for the object file."), _("\ +Show the default executable format when more than \n\ +one executable format support for the object file."), NULL, + set_bfd, show_bfd, + &setlist, &showlist); + } } --- a/exec.c +++ b/exec.c @@ -207,6 +207,8 @@ exec_file_clear (int from_tty) void exec_file_attach (char *filename, int from_tty) { + char **matching; + /* Remove any previous exec file. */ exec_close (); @@ -259,13 +261,26 @@ exec_file_attach (char *filename, int fr scratch_pathname = xstrdup (scratch_pathname); cleanups = make_cleanup (xfree, scratch_pathname); - if (!bfd_check_format (exec_bfd, bfd_object)) + if (!bfd_check_format_matches (exec_bfd, bfd_object, &matching)) { /* Make sure to close exec_bfd, or else "run" might try to use it. */ exec_close (); - error (_("\"%s\": not in executable format: %s"), - scratch_pathname, bfd_errmsg (bfd_get_error ())); + + if (bfd_get_error () == bfd_error_file_ambiguously_recognized) + { + char **p = matching; + fprintf_filtered (gdb_stderr, _("\"%s\":Matching formats:"), + scratch_pathname); + while (*p) + fprintf_filtered (gdb_stderr, " %s", *p++); + fprintf_filtered (gdb_stderr, "\n"); + free (matching); + error (_("Use command \"set bfd\" handle it.")); + } + else + error (_("\"%s\": not in executable format: %s"), + scratch_pathname, bfd_errmsg (bfd_get_error ())); } /* FIXME - This should only be run for RS6000, but the ifdef is a poor