daily update
[deliverable/binutils-gdb.git] / gdb / osabi.c
index 57af407f5024f4ba486f9e5970c5395f93de7670..a123ea05bce253dd07c71d8d818d9a0e877dc0a4 100644 (file)
@@ -1,7 +1,6 @@
 /* OS ABI variant handling for GDB.
 
-   Copyright (C) 2001, 2002, 2003, 2004, 2007, 2008, 2009, 2010
-   Free Software Foundation, Inc.
+   Copyright (C) 2001-2013 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -73,6 +72,9 @@ static const char * const gdb_osabi_names[] =
   "DICOS",
   "Darwin",
   "Symbian",
+  "OpenVMS",
+  "LynxOS178",
+  "Newlib",
 
   "<invalid>"
 };
@@ -184,7 +186,7 @@ gdbarch_register_osabi (enum bfd_architecture arch, unsigned long machine,
 }
 \f
 
-/* 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
@@ -370,14 +372,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);
@@ -424,14 +435,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, &sectsize, "GNU", 16, NT_GNU_ABI_TAG))
        {
          unsigned int abi_tag = bfd_h_get_32 (abfd, note + 16);
 
@@ -458,15 +473,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, &sectsize, "FreeBSD", 4,
+                     NT_FREEBSD_ABI_TAG))
        {
          /* There is no need to check the version yet.  */
          *osabi = GDB_OSABI_FREEBSD_ELF;
@@ -478,7 +495,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, &sectsize, "NetBSD", 4, NT_NETBSD_IDENT))
     {
       /* There is no need to check the version yet.  */
       *osabi = GDB_OSABI_NETBSD_ELF;
@@ -487,7 +504,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, &sectsize, "OpenBSD", 4,
+                    NT_OPENBSD_IDENT))
     {
       /* There is no need to check the version yet.  */
       *osabi = GDB_OSABI_OPENBSD_ELF;
@@ -513,11 +531,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);
@@ -531,14 +553,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;
@@ -553,6 +567,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)
@@ -588,6 +606,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)
          {
@@ -614,7 +633,8 @@ show_osabi (struct ui_file *file, int from_tty, struct cmd_list_element *c,
 {
   if (user_osabi_state == osabi_auto)
     fprintf_filtered (file,
-                     _("The current OS ABI is \"auto\" (currently \"%s\").\n"),
+                     _("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"),
@@ -642,11 +662,10 @@ _initialize_gdb_osabi (void)
 
   /* Register the "set osabi" command.  */
   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,
+                       &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;
 }
This page took 0.026617 seconds and 4 git commands to generate.