X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gdb%2Fosabi.c;h=cdba812fbde1f294bdbe3d44a923a644ac9cde6a;hb=dadef93096fd397c3acf2078bcf6b526ff4e0da4;hp=5014edd5cb39526b2d343814fc653c1fdaf78d32;hpb=e2e0b3e57f11bb2539724fc955af7e22380613c1;p=platform%2Fupstream%2Fbinutils.git diff --git a/gdb/osabi.c b/gdb/osabi.c index 5014edd..cdba812 100644 --- a/gdb/osabi.c +++ b/gdb/osabi.c @@ -1,29 +1,24 @@ /* OS ABI variant handling for GDB. - Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 2001-2014 Free Software Foundation, Inc. This file is part of GDB. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + along with this program. If not, see . */ #include "defs.h" -#include "gdb_assert.h" -#include "gdb_string.h" - #include "osabi.h" #include "arch-utils.h" #include "gdbcmd.h" @@ -64,19 +59,18 @@ static const char * const gdb_osabi_names[] = "OpenBSD ELF", "Windows CE", "DJGPP", - "NetWare", "Irix", - "LynxOS", - "Interix", "HP/UX ELF", "HP/UX SOM", - - "ARM EABI v1", - "ARM EABI v2", - "ARM APCS", "QNX Neutrino", - "Cygwin", + "AIX", + "DICOS", + "Darwin", + "Symbian", + "OpenVMS", + "LynxOS178", + "Newlib", "" }; @@ -90,6 +84,30 @@ gdbarch_osabi_name (enum gdb_osabi osabi) return gdb_osabi_names[GDB_OSABI_INVALID]; } +/* Lookup the OS ABI corresponding to the specified target description + string. */ + +enum gdb_osabi +osabi_from_tdesc_string (const char *name) +{ + int i; + + for (i = 0; i < ARRAY_SIZE (gdb_osabi_names); i++) + if (strcmp (name, gdb_osabi_names[i]) == 0) + { + /* See note above: the name table matches the indices assigned + to enum gdb_osabi. */ + enum gdb_osabi osabi = (enum gdb_osabi) i; + + if (osabi == GDB_OSABI_INVALID) + return GDB_OSABI_UNKNOWN; + else + return osabi; + } + + return GDB_OSABI_UNKNOWN; +} + /* Handler for a given architecture/OS ABI pair. There should be only one handler for a given OS ABI each architecture family. */ struct gdb_osabi_handler @@ -164,7 +182,7 @@ gdbarch_register_osabi (enum bfd_architecture arch, unsigned long machine, } -/* Sniffer to find the OS ABI for a given file's architecture and flavour. +/* Sniffer to find the OS ABI for a given file's architecture and flavour. It is legal to have multiple sniffers for each arch/flavour pair, to disambiguate one OS's a.out from another, for example. The first sniffer to return something other than GDB_OSABI_UNKNOWN wins, so a sniffer should @@ -208,15 +226,11 @@ gdbarch_lookup_osabi (bfd *abfd) if (user_osabi_state == osabi_user) return user_selected_osabi; - /* If we don't have a binary, return the default OS ABI (if set) or - an inconclusive result (otherwise). */ + /* If we don't have a binary, just return unknown. The caller may + have other sources the OSABI can be extracted from, e.g., the + target description. */ if (abfd == NULL) - { - if (GDB_OSABI_DEFAULT != GDB_OSABI_UNKNOWN) - return GDB_OSABI_DEFAULT; - else - return GDB_OSABI_UNINITIALIZED; - } + return GDB_OSABI_UNKNOWN; match = GDB_OSABI_UNKNOWN; match_specific = 0; @@ -277,12 +291,7 @@ gdbarch_lookup_osabi (bfd *abfd) } } - /* If we didn't find a match, but a default was specified at configure - time, return the default. */ - if (GDB_OSABI_DEFAULT != GDB_OSABI_UNKNOWN && match == GDB_OSABI_UNKNOWN) - return GDB_OSABI_DEFAULT; - else - return match; + return match; } @@ -359,14 +368,23 @@ gdbarch_init_osabi (struct gdbarch_info info, struct gdbarch *gdbarch) /* Limit on the amount of data to be read. */ #define MAX_NOTESZ 128 -/* Return non-zero if NOTE matches NAME, DESCSZ and TYPE. */ +/* Return non-zero if NOTE matches NAME, DESCSZ and TYPE. If + *SECTSIZE is non-zero, then this reads that many bytes from + the start of the section and clears *SECTSIZE. */ static int -check_note (bfd *abfd, asection *sect, const char *note, +check_note (bfd *abfd, asection *sect, char *note, unsigned int *sectsize, const char *name, unsigned long descsz, unsigned long type) { unsigned long notesz; + if (*sectsize) + { + if (!bfd_get_section_contents (abfd, sect, note, 0, *sectsize)) + return 0; + *sectsize = 0; + } + /* Calculate the size of this note. */ notesz = strlen (name) + 1; notesz = ((notesz + 3) & ~3); @@ -413,14 +431,18 @@ generic_elf_osabi_sniff_abi_tag_sections (bfd *abfd, asection *sect, void *obj) if (sectsize > MAX_NOTESZ) sectsize = MAX_NOTESZ; + /* We lazily read the section data here. Since we use + BFD_DECOMPRESS, we can't use bfd_get_section_contents on a + compressed section. But, since note sections are not compressed, + deferring the reading until we recognize the section avoids any + error. */ note = alloca (sectsize); - bfd_get_section_contents (abfd, sect, note, 0, sectsize); /* .note.ABI-tag notes, used by GNU/Linux and FreeBSD. */ if (strcmp (name, ".note.ABI-tag") == 0) { /* GNU. */ - if (check_note (abfd, sect, note, "GNU", 16, NT_GNU_ABI_TAG)) + if (check_note (abfd, sect, note, §size, "GNU", 16, NT_GNU_ABI_TAG)) { unsigned int abi_tag = bfd_h_get_32 (abfd, note + 16); @@ -447,15 +469,17 @@ generic_elf_osabi_sniff_abi_tag_sections (bfd *abfd, asection *sect, void *obj) break; default: - internal_error (__FILE__, __LINE__, _("\ -generic_elf_osabi_sniff_abi_tag_sections: unknown OS number %d"), + internal_error (__FILE__, __LINE__, + _("generic_elf_osabi_sniff_abi_tag_sections: " + "unknown OS number %d"), abi_tag); } return; } /* FreeBSD. */ - if (check_note (abfd, sect, note, "FreeBSD", 4, NT_FREEBSD_ABI_TAG)) + if (check_note (abfd, sect, note, §size, "FreeBSD", 4, + NT_FREEBSD_ABI_TAG)) { /* There is no need to check the version yet. */ *osabi = GDB_OSABI_FREEBSD_ELF; @@ -467,7 +491,7 @@ generic_elf_osabi_sniff_abi_tag_sections: unknown OS number %d"), /* .note.netbsd.ident notes, used by NetBSD. */ if (strcmp (name, ".note.netbsd.ident") == 0 - && check_note (abfd, sect, note, "NetBSD", 4, NT_NETBSD_IDENT)) + && 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; @@ -476,7 +500,8 @@ generic_elf_osabi_sniff_abi_tag_sections: unknown OS number %d"), /* .note.openbsd.ident notes, used by OpenBSD. */ if (strcmp (name, ".note.openbsd.ident") == 0 - && check_note (abfd, sect, note, "OpenBSD", 4, NT_OPENBSD_IDENT)) + && check_note (abfd, sect, note, §size, "OpenBSD", 4, + NT_OPENBSD_IDENT)) { /* There is no need to check the version yet. */ *osabi = GDB_OSABI_OPENBSD_ELF; @@ -502,11 +527,15 @@ generic_elf_osabi_sniffer (bfd *abfd) switch (elfosabi) { case ELFOSABI_NONE: + case ELFOSABI_GNU: /* 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 OS-specific extensions). In order to determine the real OS - in use we must look for OS-specific notes. */ + in use, we must look for OS-specific notes. + + 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); @@ -520,14 +549,6 @@ generic_elf_osabi_sniffer (bfd *abfd) osabi = GDB_OSABI_NETBSD_ELF; break; - case ELFOSABI_LINUX: - osabi = GDB_OSABI_LINUX; - break; - - case ELFOSABI_HURD: - osabi = GDB_OSABI_HURD; - break; - case ELFOSABI_SOLARIS: osabi = GDB_OSABI_SOLARIS; break; @@ -542,6 +563,10 @@ generic_elf_osabi_sniffer (bfd *abfd) generic_elf_osabi_sniff_abi_tag_sections, &osabi); break; + + case ELFOSABI_OPENVMS: + osabi = GDB_OSABI_OPENVMS; + break; } if (osabi == GDB_OSABI_UNKNOWN) @@ -549,7 +574,8 @@ generic_elf_osabi_sniffer (bfd *abfd) /* The FreeBSD folks have been naughty; they stored the string "FreeBSD" in the padding of the e_ident field of the ELF header to "brand" their ELF binaries in FreeBSD 3.x. */ - if (strcmp (&elf_elfheader (abfd)->e_ident[8], "FreeBSD") == 0) + if (memcmp (&elf_elfheader (abfd)->e_ident[8], + "FreeBSD", sizeof ("FreeBSD")) == 0) osabi = GDB_OSABI_FREEBSD_ELF; } @@ -576,6 +602,7 @@ set_osabi (char *args, int from_tty, struct cmd_list_element *c) else { int i; + for (i = 1; i < GDB_OSABI_INVALID; i++) if (strcmp (set_osabi_string, gdbarch_osabi_name (i)) == 0) { @@ -597,18 +624,21 @@ set_osabi (char *args, int from_tty, struct cmd_list_element *c) } static void -show_osabi (char *args, int from_tty) +show_osabi (struct ui_file *file, int from_tty, struct cmd_list_element *c, + const char *value) { if (user_osabi_state == osabi_auto) - printf_filtered ("The current OS ABI is \"auto\" (currently \"%s\").\n", - gdbarch_osabi_name (gdbarch_osabi (current_gdbarch))); + fprintf_filtered (file, + _("The current OS ABI is \"auto\" " + "(currently \"%s\").\n"), + gdbarch_osabi_name (gdbarch_osabi (get_current_arch ()))); else - printf_filtered ("The current OS ABI is \"%s\".\n", - gdbarch_osabi_name (user_selected_osabi)); + fprintf_filtered (file, _("The current OS ABI is \"%s\".\n"), + gdbarch_osabi_name (user_selected_osabi)); if (GDB_OSABI_DEFAULT != GDB_OSABI_UNKNOWN) - printf_filtered ("The default OS ABI is \"%s\".\n", - gdbarch_osabi_name (GDB_OSABI_DEFAULT)); + fprintf_filtered (file, _("The default OS ABI is \"%s\".\n"), + gdbarch_osabi_name (GDB_OSABI_DEFAULT)); } extern initialize_file_ftype _initialize_gdb_osabi; /* -Wmissing-prototype */ @@ -616,8 +646,6 @@ extern initialize_file_ftype _initialize_gdb_osabi; /* -Wmissing-prototype */ void _initialize_gdb_osabi (void) { - struct cmd_list_element *c; - if (strcmp (gdb_osabi_names[GDB_OSABI_INVALID], "") != 0) internal_error (__FILE__, __LINE__, @@ -629,11 +657,11 @@ _initialize_gdb_osabi (void) generic_elf_osabi_sniffer); /* Register the "set osabi" command. */ - c = add_set_enum_cmd ("osabi", class_support, gdb_osabi_available_names, - &set_osabi_string, "Set OS ABI of target.", &setlist); - - set_cmd_sfunc (c, set_osabi); - add_cmd ("osabi", class_support, show_osabi, "Show OS/ABI of target.", - &showlist); + 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; }