/* OS ABI variant handling for GDB.
- Copyright (C) 2001-2015 Free Software Foundation, Inc.
+ Copyright (C) 2001-2023 Free Software Foundation, Inc.
This file is part of GDB.
#include "arch-utils.h"
#include "gdbcmd.h"
#include "command.h"
+#include "gdb_bfd.h"
#include "elf-bfd.h"
them in sync. */
static const struct osabi_names gdb_osabi_names[] =
{
+ { "unknown", NULL },
{ "none", NULL },
{ "SVR4", NULL },
{ "GNU/Hurd", NULL },
{ "Solaris", NULL },
- { "GNU/Linux", "linux(-gnu)?" },
- { "FreeBSD a.out", NULL },
- { "FreeBSD ELF", NULL },
- { "NetBSD a.out", NULL },
- { "NetBSD ELF", NULL },
- { "OpenBSD ELF", NULL },
- { "Windows CE", NULL },
+ { "GNU/Linux", "linux(-gnu[^-]*)?" },
+ { "FreeBSD", NULL },
+ { "NetBSD", NULL },
+ { "OpenBSD", NULL },
+ { "WindowsCE", NULL },
{ "DJGPP", NULL },
- { "Irix", NULL },
- { "HP/UX ELF", NULL },
- { "HP/UX SOM", NULL },
- { "QNX Neutrino", NULL },
+ { "QNX-Neutrino", NULL },
{ "Cygwin", NULL },
+ { "Windows", NULL },
{ "AIX", NULL },
{ "DICOS", NULL },
{ "Darwin", NULL },
- { "Symbian", NULL },
{ "OpenVMS", NULL },
{ "LynxOS178", NULL },
{ "Newlib", NULL },
{ "SDE", NULL },
+ { "PikeOS", NULL },
{ "<invalid>", NULL }
};
if (osabi == GDB_OSABI_UNKNOWN)
{
internal_error
- (__FILE__, __LINE__,
- _("gdbarch_register_osabi: An attempt to register a handler for "
+ (_("gdbarch_register_osabi: An attempt to register a handler for "
"OS ABI \"%s\" for architecture %s was made. The handler will "
"not be registered"),
gdbarch_osabi_name (osabi),
&& (*handler_p)->osabi == osabi)
{
internal_error
- (__FILE__, __LINE__,
- _("gdbarch_register_osabi: A handler for OS ABI \"%s\" "
+ (_("gdbarch_register_osabi: A handler for OS ABI \"%s\" "
"has already been registered for architecture %s"),
gdbarch_osabi_name (osabi),
arch_info->printable_name);
if (osabi < GDB_OSABI_UNKNOWN || osabi >= GDB_OSABI_INVALID)
{
internal_error
- (__FILE__, __LINE__,
- _("gdbarch_lookup_osabi: invalid OS ABI (%d) from sniffer "
+ (_("gdbarch_lookup_osabi: invalid OS ABI (%d) from sniffer "
"for architecture %s flavour %d"),
(int) osabi,
bfd_printable_arch_mach (bfd_get_arch (abfd), 0),
|| (!match_specific && sniffer->arch == bfd_arch_unknown))
{
internal_error
- (__FILE__, __LINE__,
- _("gdbarch_lookup_osabi: multiple %sspecific OS ABI "
+ (_("gdbarch_lookup_osabi: multiple %sspecific OS ABI "
"match for architecture %s flavour %d: first "
"match \"%s\", second match \"%s\""),
match_specific ? "" : "non-",
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;
- if (info.osabi == GDB_OSABI_UNKNOWN)
- {
- /* Don't complain about an unknown OSABI. Assume the user knows
- what they are doing. */
- return;
- }
+ gdb_assert (info.osabi != GDB_OSABI_UNKNOWN);
for (handler = gdb_osabi_handler_list; handler != NULL;
handler = handler->next)
continue;
/* If the architecture described by ARCH_INFO can run code for
- the architcture we registered the handler for, then the
+ the architecture we registered the handler for, then the
handler is applicable. Note, though, that if the handler is
for an architecture that is a superset of ARCH_INFO, we can't
use that --- it would be perfectly correct for it to install
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)
+ {
+ /* Don't complain about no OSABI. Assume the user knows
+ what they are doing. */
+ return;
}
warning
/* If this assertion triggers, increase MAX_NOTESZ. */
gdb_assert (notesz <= MAX_NOTESZ);
- /* Check whether SECT is big enough to comtain the complete note. */
- if (notesz > bfd_section_size (abfd, sect))
+ /* Check whether SECT is big enough to contain the complete note. */
+ if (notesz > bfd_section_size (sect))
return 0;
/* Check the note name. */
/* Generic sniffer for ELF flavoured files. */
void
-generic_elf_osabi_sniff_abi_tag_sections (bfd *abfd, asection *sect, void *obj)
+generic_elf_osabi_sniff_abi_tag_sections (bfd *abfd, asection *sect,
+ enum gdb_osabi *osabi)
{
- enum gdb_osabi *osabi = (enum gdb_osabi *) obj;
const char *name;
unsigned int sectsize;
char *note;
- name = bfd_get_section_name (abfd, sect);
- sectsize = bfd_section_size (abfd, sect);
+ name = bfd_section_name (sect);
+ sectsize = bfd_section_size (sect);
/* Limit the amount of data to read. */
if (sectsize > MAX_NOTESZ)
break;
case GNU_ABI_TAG_FREEBSD:
- *osabi = GDB_OSABI_FREEBSD_ELF;
+ *osabi = GDB_OSABI_FREEBSD;
break;
case GNU_ABI_TAG_NETBSD:
- *osabi = GDB_OSABI_NETBSD_ELF;
+ *osabi = GDB_OSABI_NETBSD;
break;
default:
NT_FREEBSD_ABI_TAG))
{
/* There is no need to check the version yet. */
- *osabi = GDB_OSABI_FREEBSD_ELF;
+ *osabi = GDB_OSABI_FREEBSD;
return;
}
&& check_note (abfd, sect, note, §size, "NetBSD", 4, NT_NETBSD_IDENT))
{
/* There is no need to check the version yet. */
- *osabi = GDB_OSABI_NETBSD_ELF;
+ *osabi = GDB_OSABI_NETBSD;
return;
}
NT_OPENBSD_IDENT))
{
/* There is no need to check the version yet. */
- *osabi = GDB_OSABI_OPENBSD_ELF;
+ *osabi = GDB_OSABI_OPENBSD;
return;
}
/* .note.netbsdcore.procinfo notes, used by NetBSD. */
if (strcmp (name, ".note.netbsdcore.procinfo") == 0)
{
- *osabi = GDB_OSABI_NETBSD_ELF;
+ *osabi = GDB_OSABI_NETBSD;
return;
}
}
{
case ELFOSABI_NONE:
case ELFOSABI_GNU:
+ case ELFOSABI_HPUX:
/* When the EI_OSABI field in the ELF header is ELFOSABI_NONE
(0), then the ELF structures in the file are conforming to
the base specification for that machine (there are no
The same applies for ELFOSABI_GNU: this can mean GNU/Hurd,
GNU/Linux, and possibly more. */
- bfd_map_over_sections (abfd,
- generic_elf_osabi_sniff_abi_tag_sections,
- &osabi);
+
+ /* And likewise ELFOSABI_HPUX. For some reason the default
+ value for the EI_OSABI field is ELFOSABI_HPUX for all PA-RISC
+ targets (with the exception of GNU/Linux). */
+ for (asection *sect : gdb_bfd_sections (abfd))
+ generic_elf_osabi_sniff_abi_tag_sections (abfd, sect, &osabi);
break;
case ELFOSABI_FREEBSD:
- osabi = GDB_OSABI_FREEBSD_ELF;
+ osabi = GDB_OSABI_FREEBSD;
break;
case ELFOSABI_NETBSD:
- osabi = GDB_OSABI_NETBSD_ELF;
+ osabi = GDB_OSABI_NETBSD;
break;
case ELFOSABI_SOLARIS:
osabi = GDB_OSABI_SOLARIS;
break;
- case ELFOSABI_HPUX:
- /* For some reason the default value for the EI_OSABI field is
- ELFOSABI_HPUX for all PA-RISC targets (with the exception of
- GNU/Linux). We use HP-UX ELF as the default, but let any
- OS-specific notes override this. */
- osabi = GDB_OSABI_HPUX_ELF;
- bfd_map_over_sections (abfd,
- generic_elf_osabi_sniff_abi_tag_sections,
- &osabi);
- break;
-
case ELFOSABI_OPENVMS:
osabi = GDB_OSABI_OPENVMS;
break;
header to "brand" their ELF binaries in FreeBSD 3.x. */
if (memcmp (&elf_elfheader (abfd)->e_ident[8],
"FreeBSD", sizeof ("FreeBSD")) == 0)
- osabi = GDB_OSABI_FREEBSD_ELF;
+ osabi = GDB_OSABI_FREEBSD;
}
return osabi;
}
\f
static void
-set_osabi (char *args, int from_tty, struct cmd_list_element *c)
+set_osabi (const char *args, int from_tty, struct cmd_list_element *c)
{
- struct gdbarch_info info;
-
if (strcmp (set_osabi_string, "auto") == 0)
user_osabi_state = osabi_auto;
else if (strcmp (set_osabi_string, "default") == 0)
user_selected_osabi = GDB_OSABI_DEFAULT;
user_osabi_state = osabi_user;
}
- else if (strcmp (set_osabi_string, "none") == 0)
- {
- user_selected_osabi = GDB_OSABI_UNKNOWN;
- user_osabi_state = osabi_user;
- }
else
{
int i;
for (i = 1; i < GDB_OSABI_INVALID; i++)
- {
+ {
enum gdb_osabi osabi = (enum gdb_osabi) i;
if (strcmp (set_osabi_string, gdbarch_osabi_name (osabi)) == 0)
}
}
if (i == GDB_OSABI_INVALID)
- internal_error (__FILE__, __LINE__,
- _("Invalid OS ABI \"%s\" passed to command handler."),
+ internal_error (_("Invalid OS ABI \"%s\" passed to command handler."),
set_osabi_string);
}
/* NOTE: At some point (true multiple architectures) we'll need to be more
graceful here. */
- gdbarch_info_init (&info);
+ gdbarch_info info;
if (! gdbarch_update_p (info))
- internal_error (__FILE__, __LINE__, _("Updating OS ABI failed."));
+ internal_error (_("Updating OS ABI failed."));
}
static void
const char *value)
{
if (user_osabi_state == osabi_auto)
- fprintf_filtered (file,
- _("The current OS ABI is \"auto\" "
- "(currently \"%s\").\n"),
- gdbarch_osabi_name (gdbarch_osabi (get_current_arch ())));
+ gdb_printf (file,
+ _("The current OS ABI is \"auto\" "
+ "(currently \"%s\").\n"),
+ gdbarch_osabi_name (gdbarch_osabi (get_current_arch ())));
else
- fprintf_filtered (file, _("The current OS ABI is \"%s\".\n"),
- gdbarch_osabi_name (user_selected_osabi));
+ gdb_printf (file, _("The current OS ABI is \"%s\".\n"),
+ gdbarch_osabi_name (user_selected_osabi));
if (GDB_OSABI_DEFAULT != GDB_OSABI_UNKNOWN)
- fprintf_filtered (file, _("The default OS ABI is \"%s\".\n"),
- gdbarch_osabi_name (GDB_OSABI_DEFAULT));
+ gdb_printf (file, _("The default OS ABI is \"%s\".\n"),
+ gdbarch_osabi_name (GDB_OSABI_DEFAULT));
}
-\f
-extern initialize_file_ftype _initialize_gdb_osabi; /* -Wmissing-prototype */
+void _initialize_gdb_osabi ();
void
-_initialize_gdb_osabi (void)
+_initialize_gdb_osabi ()
{
if (strcmp (gdb_osabi_names[GDB_OSABI_INVALID].pretty, "<invalid>") != 0)
internal_error
- (__FILE__, __LINE__,
- _("_initialize_gdb_osabi: gdb_osabi_names[] is inconsistent"));
+ (_("_initialize_gdb_osabi: gdb_osabi_names[] is inconsistent"));
/* Register a generic sniffer for ELF flavoured files. */
gdbarch_register_osabi_sniffer (bfd_arch_unknown,
generic_elf_osabi_sniffer);
/* Register the "set osabi" command. */
+ user_osabi_state = osabi_auto;
+ set_osabi_string = gdb_osabi_available_names[0];
+ gdb_assert (strcmp (set_osabi_string, "auto") == 0);
add_setshow_enum_cmd ("osabi", class_support, gdb_osabi_available_names,
&set_osabi_string,
_("Set OS ABI of target."),
_("Show OS ABI of target."),
NULL, set_osabi, show_osabi,
&setlist, &showlist);
- user_osabi_state = osabi_auto;
}