* wince-stub.c (FREE): New macro.
[deliverable/binutils-gdb.git] / bfd / aoutx.h
index 91ee8d833f4227bfb1e4d43632b868bebeab6737..01dd9eee4c05d9d23966de2947aa9e033408dc19 100644 (file)
@@ -1,5 +1,6 @@
 /* BFD semi-generic back-end for a.out binaries.
-   Copyright 1990, 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+   Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 98, 1999
+   Free Software Foundation, Inc.
    Written by Cygnus Support.
 
 This file is part of BFD, the Binary File Descriptor library.
@@ -119,9 +120,9 @@ DESCRIPTION
 
 #define KEEPIT udata.i
 
-#include <string.h>            /* For strchr and friends */
+#include <ctype.h>
 #include "bfd.h"
-#include <sysdep.h>
+#include "sysdep.h"
 #include "bfdlink.h"
 
 #include "libaout.h"
@@ -135,6 +136,9 @@ static boolean translate_from_native_sym_flags
   PARAMS ((bfd *, aout_symbol_type *));
 static boolean translate_to_native_sym_flags
   PARAMS ((bfd *, asymbol *, struct external_nlist *));
+static void adjust_o_magic PARAMS ((bfd *, struct internal_exec *));
+static void adjust_z_magic PARAMS ((bfd *, struct internal_exec *));
+static void adjust_n_magic PARAMS ((bfd *, struct internal_exec *));
 
 /*
 SUBSECTION
@@ -161,10 +165,18 @@ DESCRIPTION
 #define MY_swap_std_reloc_in NAME(aout,swap_std_reloc_in)
 #endif
 
+#ifndef MY_swap_ext_reloc_in
+#define MY_swap_ext_reloc_in NAME(aout,swap_ext_reloc_in)
+#endif
+
 #ifndef MY_swap_std_reloc_out
 #define MY_swap_std_reloc_out NAME(aout,swap_std_reloc_out)
 #endif
 
+#ifndef MY_swap_ext_reloc_out
+#define MY_swap_ext_reloc_out NAME(aout,swap_ext_reloc_out)
+#endif
+
 #ifndef MY_final_link_relocate
 #define MY_final_link_relocate _bfd_final_link_relocate
 #endif
@@ -193,9 +205,9 @@ reloc_howto_type howto_table_ext[] =
   HOWTO(RELOC_LO10,   0,  2,   10, false, 0, complain_overflow_dont,0,"LO10",     false, 0,0x000003ff, false),
   HOWTO(RELOC_SFA_BASE,0, 2,   32, false, 0, complain_overflow_bitfield,0,"SFA_BASE", false, 0,0xffffffff, false),
   HOWTO(RELOC_SFA_OFF13,0,2,   32, false, 0, complain_overflow_bitfield,0,"SFA_OFF13",false, 0,0xffffffff, false),
-  HOWTO(RELOC_BASE10, 0,  2,   16, false, 0, complain_overflow_bitfield,0,"BASE10",   false, 0,0x0000ffff, false),
-  HOWTO(RELOC_BASE13, 0,  2,   13, false, 0, complain_overflow_bitfield,0,"BASE13",   false, 0,0x00001fff, false),
-  HOWTO(RELOC_BASE22, 0,  2,   0,  false, 0, complain_overflow_bitfield,0,"BASE22",   false, 0,0x00000000, false),
+  HOWTO(RELOC_BASE10, 0,  2,   10, false, 0, complain_overflow_dont,0,"BASE10",   false, 0,0x000003ff, false),
+  HOWTO(RELOC_BASE13, 0,  2,   13, false, 0, complain_overflow_signed,0,"BASE13",   false, 0,0x00001fff, false),
+  HOWTO(RELOC_BASE22, 10, 2,   22, false, 0, complain_overflow_bitfield,0,"BASE22",   false, 0,0x003fffff, false),
   HOWTO(RELOC_PC10,   0,  2,   10, true,  0, complain_overflow_dont,0,"PC10",  false, 0,0x000003ff, true),
   HOWTO(RELOC_PC22,   10,  2,  22, true,  0, complain_overflow_signed,0,"PC22", false, 0,0x003fffff, true),
   HOWTO(RELOC_JMP_TBL,2,  2,   30, true,  0, complain_overflow_signed,0,"JMP_TBL",     false, 0,0x3fffffff, false),
@@ -203,6 +215,10 @@ reloc_howto_type howto_table_ext[] =
   HOWTO(RELOC_GLOB_DAT,0, 2,   0,  false, 0, complain_overflow_bitfield,0,"GLOB_DAT",  false, 0,0x00000000, false),
   HOWTO(RELOC_JMP_SLOT,0, 2,   0,  false, 0, complain_overflow_bitfield,0,"JMP_SLOT",  false, 0,0x00000000, false),
   HOWTO(RELOC_RELATIVE,0, 2,   0,  false, 0, complain_overflow_bitfield,0,"RELATIVE",  false, 0,0x00000000, false),
+  HOWTO(0,  0, 0,    0,  false, 0, complain_overflow_dont, 0, "R_SPARC_NONE",    false,0,0x00000000,true),
+  HOWTO(0,  0, 0,    0,  false, 0, complain_overflow_dont, 0, "R_SPARC_NONE",    false,0,0x00000000,true),
+#define RELOC_SPARC_REV32 RELOC_WDISP19
+  HOWTO(RELOC_SPARC_REV32,    0,  2,   32, false, 0, complain_overflow_dont,0,"R_SPARC_REV32",       false, 0,0xffffffff, false),
 };
 
 /* Convert standard reloc records to "arelent" format (incl byte swap).  */
@@ -220,28 +236,35 @@ HOWTO( 7,        0,  4,   64, true,  0, complain_overflow_signed,  0,"DISP64",    tr
 HOWTO( 8,             0,  2,    0, false, 0, complain_overflow_bitfield,0,"GOT_REL",   false,         0,0x00000000, false),
 HOWTO( 9,             0,  1,   16, false, 0, complain_overflow_bitfield,0,"BASE16",    false,0xffffffff,0xffffffff, false),
 HOWTO(10,             0,  2,   32, false, 0, complain_overflow_bitfield,0,"BASE32",    false,0xffffffff,0xffffffff, false),
-{ -1 },
-{ -1 },
-{ -1 },
-{ -1 },
-{ -1 },
+EMPTY_HOWTO (-1),
+EMPTY_HOWTO (-1),
+EMPTY_HOWTO (-1),
+EMPTY_HOWTO (-1),
+EMPTY_HOWTO (-1),
   HOWTO(16,           0,  2,    0, false, 0, complain_overflow_bitfield,0,"JMP_TABLE", false,         0,0x00000000, false),
-{ -1 },
-{ -1 },
-{ -1 },
-{ -1 },
-{ -1 },
-{ -1 },
-{ -1 },
-{ -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 },
+EMPTY_HOWTO (-1),
+EMPTY_HOWTO (-1),
+EMPTY_HOWTO (-1),
+EMPTY_HOWTO (-1),
+EMPTY_HOWTO (-1),
+EMPTY_HOWTO (-1),
+EMPTY_HOWTO (-1),
+EMPTY_HOWTO (-1),
+EMPTY_HOWTO (-1),
+EMPTY_HOWTO (-1),
+EMPTY_HOWTO (-1),
+EMPTY_HOWTO (-1),
+EMPTY_HOWTO (-1),
+EMPTY_HOWTO (-1),
+EMPTY_HOWTO (-1),
   HOWTO(32,           0,  2,    0, false, 0, complain_overflow_bitfield,0,"RELATIVE",  false,         0,0x00000000, false),
-{ -1 },
-{ -1 },
-{ -1 },
-{ -1 },
-{ -1 },
-{ -1 },
-{ -1 },
+EMPTY_HOWTO (-1),
+EMPTY_HOWTO (-1),
+EMPTY_HOWTO (-1),
+EMPTY_HOWTO (-1),
+EMPTY_HOWTO (-1),
+EMPTY_HOWTO (-1),
+EMPTY_HOWTO (-1),
   HOWTO(40,           0,  2,    0, false, 0, complain_overflow_bitfield,0,"BASEREL",   false,         0,0x00000000, false),
 };
 
@@ -268,6 +291,8 @@ NAME(aout,reloc_type_lookup) (abfd,code)
   if (ext)
     switch (code)
       {
+       EXT (BFD_RELOC_8, 0);
+       EXT (BFD_RELOC_16, 1);
        EXT (BFD_RELOC_32, 2);
        EXT (BFD_RELOC_HI22, 8);
        EXT (BFD_RELOC_LO10, 11);
@@ -281,6 +306,7 @@ NAME(aout,reloc_type_lookup) (abfd,code)
        EXT (BFD_RELOC_SPARC_PC10, 17);
        EXT (BFD_RELOC_SPARC_PC22, 18);
        EXT (BFD_RELOC_SPARC_WPLT30, 19);
+       EXT (BFD_RELOC_SPARC_REV32, 26);
       default: return (reloc_howto_type *) NULL;
       }
   else
@@ -448,7 +474,7 @@ NAME(aout,some_aout_object_p) (abfd, execp, callback_to_real_object_p)
   execp = abfd->tdata.aout_data->a.hdr;
 
   /* Set the file flags */
-  abfd->flags = NO_FLAGS;
+  abfd->flags = BFD_NO_FLAGS;
   if (execp->a_drsize || execp->a_trsize)
     abfd->flags |= HAS_RELOC;
   /* Setting of EXEC_P has been deferred to the bottom of this function */
@@ -581,9 +607,20 @@ NAME(aout,some_aout_object_p) (abfd, execp, callback_to_real_object_p)
      guess at whether the file is executable.  If the entry point
      is within the text segment, assume it is.  (This makes files
      executable even if their entry point address is 0, as long as
-     their text starts at zero.).  */
-  if ((execp->a_entry >= obj_textsec(abfd)->vma) &&
-      (execp->a_entry < obj_textsec(abfd)->vma + obj_textsec(abfd)->_raw_size))
+     their text starts at zero.).
+
+     This test had to be changed to deal with systems where the text segment
+     runs at a different location than the default.  The problem is that the
+     entry address can appear to be outside the text segment, thus causing an
+     erroneous conclusion that the file isn't executable.
+
+     To fix this, we now accept any non-zero entry point as an indication of
+     executability.  This will work most of the time, since only the linker
+     sets the entry point, and that is likely to be non-zero for most systems. */
+
+  if (execp->a_entry != 0
+      || (execp->a_entry >= obj_textsec(abfd)->vma
+         && execp->a_entry < obj_textsec(abfd)->vma + obj_textsec(abfd)->_raw_size))
     abfd->flags |= EXEC_P;
 #ifdef STAT_FOR_EXEC
   else
@@ -597,7 +634,8 @@ NAME(aout,some_aout_object_p) (abfd, execp, callback_to_real_object_p)
         the default text start (obj_textsec(abfd)->vma) and
         (obj_textsec(abfd)->vma) + text size.  This is not just a mach
         issue.  Many kernels are loaded at non standard addresses.  */
-      if (abfd->iostream
+      if (abfd->iostream != NULL
+         && (abfd->flags & BFD_IN_MEMORY) == 0
          && (fstat(fileno((FILE *) (abfd->iostream)), &stat_buf) == 0)
          && ((stat_buf.st_mode & 0111) != 0))
        abfd->flags |= EXEC_P;
@@ -690,17 +728,21 @@ NAME(aout,machine_type) (arch, machine, unknown)
   case bfd_arch_sparc:
     if (machine == 0
        || machine == bfd_mach_sparc
-       || machine == bfd_mach_sparc64)
+       || machine == bfd_mach_sparc_sparclite
+       || machine == bfd_mach_sparc_sparclite_le
+       || machine == bfd_mach_sparc_v9)
       arch_flags = M_SPARC;
+    else if (machine == bfd_mach_sparc_sparclet)
+      arch_flags = M_SPARCLET;
     break;
 
   case bfd_arch_m68k:
     switch (machine) {
-    case 0:            arch_flags = M_68010; break;
-    case 68000:                arch_flags = M_UNKNOWN; *unknown = false; break;
-    case 68010:                arch_flags = M_68010; break;
-    case 68020:                arch_flags = M_68020; break;
-    default:           arch_flags = M_UNKNOWN; break;
+    case 0:              arch_flags = M_68010; break;
+    case bfd_mach_m68000: arch_flags = M_UNKNOWN; *unknown = false; break;
+    case bfd_mach_m68010: arch_flags = M_68010; break;
+    case bfd_mach_m68020: arch_flags = M_68020; break;
+    default:             arch_flags = M_UNKNOWN; break;
     }
     break;
 
@@ -719,14 +761,29 @@ NAME(aout,machine_type) (arch, machine, unknown)
   case bfd_arch_mips:
     switch (machine) {
     case 0:
-    case 2000:
-    case 3000:          arch_flags = M_MIPS1; break;
-    case 4000: /* mips3 */
-    case 4400:
-    case 8000: /* mips4 */
-      /* real mips2: */
-    case 6000:          arch_flags = M_MIPS2; break;
-    default:            arch_flags = M_UNKNOWN; break;
+    case bfd_mach_mips3000:
+    case bfd_mach_mips3900:
+      arch_flags = M_MIPS1;
+      break;
+    case bfd_mach_mips6000:
+      arch_flags = M_MIPS2;
+      break;
+    case bfd_mach_mips4000:
+    case bfd_mach_mips4010:
+    case bfd_mach_mips4100:
+    case bfd_mach_mips4300:
+    case bfd_mach_mips4400:
+    case bfd_mach_mips4600:
+    case bfd_mach_mips4650:
+    case bfd_mach_mips8000:
+    case bfd_mach_mips10000:
+    case bfd_mach_mips16:
+      /* FIXME: These should be MIPS3 or MIPS4.  */
+      arch_flags = M_MIPS2;
+      break;
+    default:
+      arch_flags = M_UNKNOWN;
+      break;
     }
     break;
 
@@ -743,12 +800,6 @@ NAME(aout,machine_type) (arch, machine, unknown)
     *unknown = false;
     break;
 
-    /* start-sanitize-rce */
-  case bfd_arch_rce:
-    arch_flags = M_RCE;
-    break;
-    /* end-sanitize-rce */
-
   default:
     arch_flags = M_UNKNOWN;
   }
@@ -1038,7 +1089,7 @@ boolean
 NAME(aout,adjust_sizes_and_vmas) (abfd, text_size, text_end)
      bfd *abfd;
      bfd_size_type *text_size;
-     file_ptr *text_end;
+     file_ptr *text_end ATTRIBUTE_UNUSED;
 {
   struct internal_exec *execp = exec_hdr (abfd);
 
@@ -1200,7 +1251,7 @@ NAME(aout,set_section_contents) (abfd, section, location, offset, count)
       && section != obj_datasec (abfd))
     {
       (*_bfd_error_handler)
-       ("%s: can not represent section `%s' in a.out object file format",
+       (_("%s: can not represent section `%s' in a.out object file format"),
         bfd_get_filename (abfd), bfd_get_section_name (abfd, section));
       bfd_set_error (bfd_error_nonrepresentable_section);
       return false;
@@ -1237,15 +1288,12 @@ aout_get_external_symbols (abfd)
       syms = (struct external_nlist *) obj_aout_sym_window (abfd).data;
 #else
       /* We allocate using malloc to make the values easy to free
-        later on.  If we put them on the obstack it might not be
+        later on.  If we put them on the objalloc it might not be
         possible to free them.  */
       syms = ((struct external_nlist *)
-             malloc ((size_t) count * EXTERNAL_NLIST_SIZE));
+             bfd_malloc ((size_t) count * EXTERNAL_NLIST_SIZE));
       if (syms == (struct external_nlist *) NULL && count != 0)
-       {
-         bfd_set_error (bfd_error_no_memory);
-         return false;
-       }
+       return false;
 
       if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0
          || (bfd_read (syms, 1, exec_hdr (abfd)->a_syms, abfd)
@@ -1280,12 +1328,9 @@ aout_get_external_symbols (abfd)
        return false;
       strings = (char *) obj_aout_string_window (abfd).data;
 #else
-      strings = (char *) malloc ((size_t) stringsize + 1);
+      strings = (char *) bfd_malloc ((size_t) stringsize + 1);
       if (strings == NULL)
-       {
-         bfd_set_error (bfd_error_no_memory);
-         return false;
-       }
+       return false;
 
       /* Skip space for the string count in the buffer for convenience
         when using indexes.  */
@@ -1415,6 +1460,10 @@ translate_from_native_sym_flags (abfd, cache_ptr)
     case N_SETD: case N_SETD | N_EXT:
     case N_SETB: case N_SETB | N_EXT:
       {
+       /* This code is no longer needed.  It used to be used to make
+           the linker handle set symbols, but they are now handled in
+           the add_symbols routine instead.  */
+#if 0
        asection *section;
        arelent_chain *reloc;
        asection *into_section;
@@ -1491,6 +1540,24 @@ translate_from_native_sym_flags (abfd, cache_ptr)
 
        reloc->relent.howto = CTOR_TABLE_RELOC_HOWTO(abfd);
 
+#endif /* 0 */
+
+       switch (cache_ptr->type & N_TYPE)
+         {
+         case N_SETA:
+           cache_ptr->symbol.section = bfd_abs_section_ptr;
+           break;
+         case N_SETT:
+           cache_ptr->symbol.section = obj_textsec (abfd);
+           break;
+         case N_SETD:
+           cache_ptr->symbol.section = obj_datasec (abfd);
+           break;
+         case N_SETB:
+           cache_ptr->symbol.section = obj_bsssec (abfd);
+           break;
+         }
+
        cache_ptr->symbol.flags |= BSF_CONSTRUCTOR;
       }
       break;
@@ -1568,8 +1635,9 @@ translate_to_native_sym_flags (abfd, cache_ptr, sym_pointer)
       /* This case occurs, e.g., for the *DEBUG* section of a COFF
         file.  */
       (*_bfd_error_handler)
-       ("%s: can not represent section `%s' in a.out object file format",
-        bfd_get_filename (abfd), bfd_get_section_name (abfd, sec));
+       (_("%s: can not represent section for symbol `%s' in a.out object file format"),
+        bfd_get_filename (abfd), 
+        cache_ptr->name != NULL ? cache_ptr->name : _("*unknown*"));
       bfd_set_error (bfd_error_nonrepresentable_section);
       return false;
     }
@@ -1597,7 +1665,7 @@ translate_to_native_sym_flags (abfd, cache_ptr, sym_pointer)
   else
     {
       (*_bfd_error_handler)
-       ("%s: can not represent section `%s' in a.out object file format",
+       (_("%s: can not represent section `%s' in a.out object file format"),
         bfd_get_filename (abfd), bfd_get_section_name (abfd, sec));
       bfd_set_error (bfd_error_nonrepresentable_section);
       return false;
@@ -1736,12 +1804,9 @@ NAME(aout,slurp_symbol_table) (abfd)
 
   cached_size = (obj_aout_external_sym_count (abfd)
                 * sizeof (aout_symbol_type));
-  cached = (aout_symbol_type *) malloc (cached_size);
+  cached = (aout_symbol_type *) bfd_malloc (cached_size);
   if (cached == NULL && cached_size != 0)
-    {
-      bfd_set_error (bfd_error_no_memory);
-      return false;
-    }
+    return false;
   if (cached_size != 0)
     memset (cached, 0, cached_size);
 
@@ -1928,6 +1993,9 @@ NAME(aout,get_symtab) (abfd, location)
 /* Standard reloc stuff */
 /* Output standard relocation information to a file in target byte order. */
 
+extern void  NAME(aout,swap_std_reloc_out)
+  PARAMS ((bfd *, arelent *, struct reloc_std_external *));
+
 void
 NAME(aout,swap_std_reloc_out) (abfd, g, natptr)
      bfd *abfd;
@@ -1975,7 +2043,7 @@ NAME(aout,swap_std_reloc_out) (abfd, g, natptr)
       {
        /* Whoops, looked like an abs symbol, but is really an offset
           from the abs section */
-       r_index = 0;
+       r_index = N_ABS;
        r_extern = 0;
        }
       else
@@ -1994,7 +2062,7 @@ NAME(aout,swap_std_reloc_out) (abfd, g, natptr)
     }
 
   /* now the fun stuff */
-  if (abfd->xvec->header_byteorder_big_p != false) {
+  if (bfd_header_big_endian (abfd)) {
       natptr->r_index[0] = r_index >> 16;
       natptr->r_index[1] = r_index >> 8;
       natptr->r_index[2] = r_index;
@@ -2023,6 +2091,9 @@ NAME(aout,swap_std_reloc_out) (abfd, g, natptr)
 /* Extended stuff */
 /* Output extended relocation information to a file in target byte order. */
 
+extern void NAME(aout,swap_ext_reloc_out)
+  PARAMS ((bfd *, arelent *, struct reloc_ext_external *));
+
 void
 NAME(aout,swap_ext_reloc_out) (abfd, g, natptr)
      bfd *abfd;
@@ -2054,7 +2125,7 @@ NAME(aout,swap_ext_reloc_out) (abfd, g, natptr)
   if (bfd_is_abs_section (bfd_get_section (sym)))
     {
       r_extern = 0;
-      r_index = 0;
+      r_index = N_ABS;
     }
   else if ((sym->flags & BSF_SECTION_SYM) == 0)
     {
@@ -2073,7 +2144,7 @@ NAME(aout,swap_ext_reloc_out) (abfd, g, natptr)
     }
 
   /* now the fun stuff */
-  if (abfd->xvec->header_byteorder_big_p != false) {
+  if (bfd_header_big_endian (abfd)) {
     natptr->r_index[0] = r_index >> 16;
     natptr->r_index[1] = r_index >> 8;
     natptr->r_index[2] = r_index;
@@ -2150,7 +2221,7 @@ NAME(aout,swap_ext_reloc_in) (abfd, bytes, cache_ptr, symbols, symcount)
   cache_ptr->address = (GET_SWORD (abfd, bytes->r_address));
 
   /* now the fun stuff */
-  if (abfd->xvec->header_byteorder_big_p != false) {
+  if (bfd_header_big_endian (abfd)) {
     r_index =  (bytes->r_index[0] << 16)
             | (bytes->r_index[1] << 8)
             |  bytes->r_index[2];
@@ -2206,7 +2277,7 @@ NAME(aout,swap_std_reloc_in) (abfd, bytes, cache_ptr, symbols, symcount)
   cache_ptr->address = bfd_h_get_32 (abfd, bytes->r_address);
 
   /* now the fun stuff */
-  if (abfd->xvec->header_byteorder_big_p != false) {
+  if (bfd_header_big_endian (abfd)) {
     r_index =  (bytes->r_index[0] << 16)
       | (bytes->r_index[1] << 8)
        |  bytes->r_index[2];
@@ -2294,19 +2365,15 @@ NAME(aout,slurp_reloc_table) (abfd, asect, symbols)
 
   count = reloc_size / each_size;
 
-  reloc_cache = (arelent *) malloc ((size_t) (count * sizeof (arelent)));
+  reloc_cache = (arelent *) bfd_malloc ((size_t) (count * sizeof (arelent)));
   if (reloc_cache == NULL && count != 0)
-    {
-      bfd_set_error (bfd_error_no_memory);
-      return false;
-    }
+    return false;
   memset (reloc_cache, 0, count * sizeof (arelent));
 
-  relocs = malloc ((size_t) reloc_size);
+  relocs = bfd_malloc ((size_t) reloc_size);
   if (relocs == NULL && reloc_size != 0)
     {
       free (reloc_cache);
-      bfd_set_error (bfd_error_no_memory);
       return false;
     }
 
@@ -2324,8 +2391,8 @@ NAME(aout,slurp_reloc_table) (abfd, asect, symbols)
        (struct reloc_ext_external *) relocs;
 
       for (; counter < count; counter++, rptr++, cache_ptr++)
-       NAME(aout,swap_ext_reloc_in) (abfd, rptr, cache_ptr, symbols,
-                                     bfd_get_symcount (abfd));
+       MY_swap_ext_reloc_in (abfd, rptr, cache_ptr, symbols,
+                             bfd_get_symcount (abfd));
     }
   else
     {
@@ -2359,7 +2426,8 @@ NAME(aout,squirt_out_relocs) (abfd, section)
   unsigned int count = section->reloc_count;
   size_t natsize;
 
-  if (count == 0) return true;
+  if (count == 0 || section->orelocation == NULL)
+    return true;
 
   each_size = obj_reloc_entry_size (abfd);
   natsize = each_size * count;
@@ -2374,7 +2442,8 @@ NAME(aout,squirt_out_relocs) (abfd, section)
       for (natptr = native;
           count != 0;
           --count, natptr += each_size, ++generic)
-       NAME(aout,swap_ext_reloc_out) (abfd, *generic, (struct reloc_ext_external *)natptr);
+       MY_swap_ext_reloc_out (abfd, *generic,
+                              (struct reloc_ext_external *) natptr);
     }
   else
     {
@@ -2480,16 +2549,16 @@ NAME(aout,get_symtab_upper_bound) (abfd)
 /*ARGSUSED*/
  alent *
 NAME(aout,get_lineno) (ignore_abfd, ignore_symbol)
-     bfd *ignore_abfd;
-     asymbol *ignore_symbol;
+     bfd *ignore_abfd ATTRIBUTE_UNUSED;
+     asymbol *ignore_symbol ATTRIBUTE_UNUSED;
 {
-return (alent *)NULL;
+  return (alent *)NULL;
 }
 
 /*ARGSUSED*/
 void
 NAME(aout,get_symbol_info) (ignore_abfd, symbol, ret)
-     bfd *ignore_abfd;
+     bfd *ignore_abfd ATTRIBUTE_UNUSED;
      asymbol *symbol;
      symbol_info *ret;
 {
@@ -2498,7 +2567,7 @@ NAME(aout,get_symbol_info) (ignore_abfd, symbol, ret)
   if (ret->type == '?')
     {
       int type_code = aout_symbol(symbol)->type & 0xff;
-      CONST char *stab_name = aout_stab_name(type_code);
+      const char *stab_name = bfd_get_stab_name (type_code);
       static char buf[10];
 
       if (stab_name == NULL)
@@ -2507,6 +2576,7 @@ NAME(aout,get_symbol_info) (ignore_abfd, symbol, ret)
          stab_name = buf;
        }
       ret->type = '-';
+      ret->stab_type = type_code;
       ret->stab_other = (unsigned)(aout_symbol(symbol)->other & 0xff);
       ret->stab_desc = (unsigned)(aout_symbol(symbol)->desc & 0xffff);
       ret->stab_name = stab_name;
@@ -2516,7 +2586,7 @@ NAME(aout,get_symbol_info) (ignore_abfd, symbol, ret)
 /*ARGSUSED*/
 void
 NAME(aout,print_symbol) (ignore_abfd, afile, symbol, how)
-     bfd *ignore_abfd;
+     bfd *ignore_abfd ATTRIBUTE_UNUSED;
      PTR afile;
      asymbol *symbol;
      bfd_print_symbol_type how;
@@ -2647,6 +2717,7 @@ NAME(aout,find_nearest_line)
   CONST char *main_file_name = NULL;
   CONST char *current_file_name = NULL;
   CONST char *line_file_name = NULL; /* Value of current_file_name at line number. */
+  CONST char *line_directory_name = NULL; /* Value of directory_name at line number. */
   bfd_vma low_line_vma = 0;
   bfd_vma low_func_vma = 0;
   asymbol *func = 0;
@@ -2661,7 +2732,49 @@ NAME(aout,find_nearest_line)
       aout_symbol_type  *q = (aout_symbol_type *)(*p);
     next:
       switch (q->type){
+      case N_TEXT:
+       /* If this looks like a file name symbol, and it comes after
+           the line number we have found so far, but before the
+           offset, then we have probably not found the right line
+           number.  */
+       if (q->symbol.value <= offset
+           && ((q->symbol.value > low_line_vma
+                && (line_file_name != NULL
+                    || *line_ptr != 0))
+               || (q->symbol.value > low_func_vma
+                   && func != NULL)))
+         {
+           const char *symname;
+
+           symname = q->symbol.name;
+           if (strcmp (symname + strlen (symname) - 2, ".o") == 0)
+             {
+               if (q->symbol.value > low_line_vma)
+                 {
+                   *line_ptr = 0;
+                   line_file_name = NULL;
+                 }
+               if (q->symbol.value > low_func_vma)
+                 func = NULL;
+             }
+         }
+       break;
+
       case N_SO:
+       /* If this symbol is less than the offset, but greater than
+           the line number we have found so far, then we have not
+           found the right line number.  */
+       if (q->symbol.value <= offset)
+         {
+           if (q->symbol.value > low_line_vma)
+             {
+               *line_ptr = 0;
+               line_file_name = NULL;
+             }
+           if (q->symbol.value > low_func_vma)
+             func = NULL;
+         }
+
        main_file_name = current_file_name = q->symbol.name;
        /* Look ahead to next symbol to check if that too is an N_SO. */
        p++;
@@ -2693,6 +2806,7 @@ NAME(aout,find_nearest_line)
            *line_ptr = q->desc;
            low_line_vma = q->symbol.value;
            line_file_name = current_file_name;
+           line_directory_name = directory_name;
          }
        break;
       case N_FUN:
@@ -2713,7 +2827,10 @@ NAME(aout,find_nearest_line)
 
  done:
   if (*line_ptr != 0)
-    main_file_name = line_file_name;
+    {
+      main_file_name = line_file_name;
+      directory_name = line_directory_name;
+    }
 
   if (main_file_name == NULL
       || main_file_name[0] == '/'
@@ -2732,12 +2849,10 @@ NAME(aout,find_nearest_line)
     adata (abfd).line_buf = buf = NULL;
   else
     {
-      adata (abfd).line_buf = buf = (char *) malloc (filelen + funclen + 2);
-      if (adata (abfd).line_buf == NULL)
-       {
-         bfd_set_error (bfd_error_no_memory);
-         return false;
-       }
+      buf = (char *) bfd_malloc (filelen + funclen + 3);
+      adata (abfd).line_buf = buf;
+      if (buf == NULL)
+       return false;
     }
 
   if (main_file_name != NULL)
@@ -2781,7 +2896,7 @@ NAME(aout,find_nearest_line)
 int
 NAME(aout,sizeof_headers) (abfd, execable)
      bfd *abfd;
-     boolean execable;
+     boolean execable ATTRIBUTE_UNUSED;
 {
   return adata(abfd).exec_bytes_size;
 }
@@ -3191,8 +3306,7 @@ aout_link_add_symbols (abfd, info)
   else
     copy = true;
 
-  if ((abfd->flags & DYNAMIC) != 0
-      && aout_backend_info (abfd)->add_dynamic_symbols != NULL)
+  if (aout_backend_info (abfd)->add_dynamic_symbols != NULL)
     {
       if (! ((*aout_backend_info (abfd)->add_dynamic_symbols)
             (abfd, info, &syms, &sym_count, &strings)))
@@ -3384,6 +3498,37 @@ aout_link_add_symbols (abfd, info)
 
   return true;
 }
+\f
+/* A hash table used for header files with N_BINCL entries.  */
+
+struct aout_link_includes_table
+{
+  struct bfd_hash_table root;
+};
+
+/* A linked list of totals that we have found for a particular header
+   file.  */
+
+struct aout_link_includes_totals
+{
+  struct aout_link_includes_totals *next;
+  bfd_vma total;
+};
+
+/* An entry in the header file hash table.  */
+
+struct aout_link_includes_entry
+{
+  struct bfd_hash_entry root;
+  /* List of totals we have found for this file.  */
+  struct aout_link_includes_totals *totals;
+};
+
+/* Look up an entry in an the header file hash table.  */
+
+#define aout_link_includes_lookup(table, string, create, copy) \
+  ((struct aout_link_includes_entry *) \
+   bfd_hash_lookup (&(table)->root, (string), (create), (copy)))
 
 /* During the final link step we need to pass around a bunch of
    information, so we do it in an instance of this structure.  */
@@ -3400,6 +3545,8 @@ struct aout_final_link_info
   file_ptr symoff;
   /* String table.  */
   struct bfd_strtab_hash *strtab;
+  /* Header file hash table.  */
+  struct aout_link_includes_table includes;
   /* A buffer large enough to hold the contents of any section.  */
   bfd_byte *contents;
   /* A buffer large enough to hold the relocs of any section.  */
@@ -3410,6 +3557,8 @@ struct aout_final_link_info
   struct external_nlist *output_syms;
 };
 
+static struct bfd_hash_entry *aout_link_includes_newfunc
+  PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
 static boolean aout_link_input_bfd
   PARAMS ((struct aout_final_link_info *, bfd *input_bfd));
 static boolean aout_link_write_symbols
@@ -3434,6 +3583,38 @@ static boolean aout_link_reloc_link_order
   PARAMS ((struct aout_final_link_info *, asection *,
           struct bfd_link_order *));
 
+/* The function to create a new entry in the header file hash table.  */
+
+static struct bfd_hash_entry *
+aout_link_includes_newfunc (entry, table, string)
+     struct bfd_hash_entry *entry;
+     struct bfd_hash_table *table;
+     const char *string;
+{
+  struct aout_link_includes_entry *ret =
+    (struct aout_link_includes_entry *) entry;
+
+  /* Allocate the structure if it has not already been allocated by a
+     subclass.  */
+  if (ret == (struct aout_link_includes_entry *) NULL)
+    ret = ((struct aout_link_includes_entry *)
+          bfd_hash_allocate (table,
+                             sizeof (struct aout_link_includes_entry)));
+  if (ret == (struct aout_link_includes_entry *) NULL)
+    return (struct bfd_hash_entry *) ret;
+
+  /* Call the allocation method of the superclass.  */
+  ret = ((struct aout_link_includes_entry *)
+        bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
+  if (ret)
+    {
+      /* Set local fields.  */
+      ret->totals = NULL;
+    }
+
+  return (struct bfd_hash_entry *) ret;
+}
+
 /* Do the final link step.  This is called on the output BFD.  The
    INFO structure should point to a list of BFDs linked through the
    link_next field which can be used to find each BFD which takes part
@@ -3448,6 +3629,7 @@ NAME(aout,final_link) (abfd, info, callback)
      void (*callback) PARAMS ((bfd *, file_ptr *, file_ptr *, file_ptr *));
 {
   struct aout_final_link_info aout_info;
+  boolean includes_hash_initialized = false;
   register bfd *sub;
   bfd_size_type trsize, drsize;
   size_t max_contents_size;
@@ -3466,6 +3648,14 @@ NAME(aout,final_link) (abfd, info, callback)
   aout_info.output_bfd = abfd;
   aout_info.contents = NULL;
   aout_info.relocs = NULL;
+  aout_info.symbol_map = NULL;
+  aout_info.output_syms = NULL;
+
+  if (! bfd_hash_table_init_n (&aout_info.includes.root,
+                              aout_link_includes_newfunc,
+                              251))
+    goto error_return;
+  includes_hash_initialized = true;
 
   /* Figure out the largest section size.  Also, if generating
      relocateable output, count the relocs.  */
@@ -3492,7 +3682,7 @@ NAME(aout,final_link) (abfd, info, callback)
                 work out the number of relocs needed, and then multiply
                 by the reloc size.  */
              (*_bfd_error_handler)
-               ("%s: relocateable link from %s to %s not supported",
+               (_("%s: relocateable link from %s to %s not supported"),
                 bfd_get_filename (abfd),
                 sub->xvec->name, abfd->xvec->name);
              bfd_set_error (bfd_error_invalid_operation);
@@ -3568,20 +3758,17 @@ NAME(aout,final_link) (abfd, info, callback)
     goto error_return;
 
   /* Allocate buffers to hold section contents and relocs.  */
-  aout_info.contents = (bfd_byte *) malloc (max_contents_size);
-  aout_info.relocs = (PTR) malloc (max_relocs_size);
-  aout_info.symbol_map = (int *) malloc (max_sym_count * sizeof (int *));
+  aout_info.contents = (bfd_byte *) bfd_malloc (max_contents_size);
+  aout_info.relocs = (PTR) bfd_malloc (max_relocs_size);
+  aout_info.symbol_map = (int *) bfd_malloc (max_sym_count * sizeof (int *));
   aout_info.output_syms = ((struct external_nlist *)
-                          malloc ((max_sym_count + 1)
-                                  * sizeof (struct external_nlist)));
+                          bfd_malloc ((max_sym_count + 1)
+                                      * sizeof (struct external_nlist)));
   if ((aout_info.contents == NULL && max_contents_size != 0)
       || (aout_info.relocs == NULL && max_relocs_size != 0)
       || (aout_info.symbol_map == NULL && max_sym_count != 0)
       || aout_info.output_syms == NULL)
-    {
-      bfd_set_error (bfd_error_no_memory);
-      goto error_return;
-    }
+    goto error_return;
 
   /* If we have a symbol named __DYNAMIC, force it out now.  This is
      required by SunOS.  Doing this here rather than in sunos.c is a
@@ -3620,6 +3807,19 @@ NAME(aout,final_link) (abfd, info, callback)
   for (sub = info->input_bfds; sub != (bfd *) NULL; sub = sub->link_next)
     sub->output_has_begun = false;
 
+  /* Mark all sections which are to be included in the link.  This
+     will normally be every section.  We need to do this so that we
+     can identify any sections which the linker has decided to not
+     include.  */
+  for (o = abfd->sections; o != NULL; o = o->next)
+    {
+      for (p = o->link_order_head; p != NULL; p = p->next)
+       {
+         if (p->type == bfd_indirect_link_order)
+           p->u.indirect.section->linker_mark = true;
+       }
+    }
+
   have_link_order_relocs = false;
   for (o = abfd->sections; o != (asection *) NULL; o = o->next)
     {
@@ -3702,6 +3902,11 @@ NAME(aout,final_link) (abfd, info, callback)
       free (aout_info.output_syms);
       aout_info.output_syms = NULL;
     }
+  if (includes_hash_initialized)
+    {
+      bfd_hash_table_free (&aout_info.includes.root);
+      includes_hash_initialized = false;
+    }
 
   /* Finish up any dynamic linking we may be doing.  */
   if (aout_backend_info (abfd)->finish_dynamic_link != NULL)
@@ -3719,10 +3924,29 @@ NAME(aout,final_link) (abfd, info, callback)
   obj_datasec (abfd)->reloc_count =
     exec_hdr (abfd)->a_drsize / obj_reloc_entry_size (abfd);
 
-  /* Write out the string table.  */
-  if (bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET) != 0)
-    goto error_return;
-  return emit_stringtab (abfd, aout_info.strtab);
+  /* Write out the string table, unless there are no symbols.  */
+  if (abfd->symcount > 0)
+    {
+      if (bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET) != 0
+         || ! emit_stringtab (abfd, aout_info.strtab))
+       goto error_return;
+    }
+  else if (obj_textsec (abfd)->reloc_count == 0
+          && obj_datasec (abfd)->reloc_count == 0)
+    {
+      bfd_byte b;
+
+      b = 0;
+      if (bfd_seek (abfd,
+                   (obj_datasec (abfd)->filepos
+                    + exec_hdr (abfd)->a_data
+                    - 1),
+                   SEEK_SET) != 0
+         || bfd_write (&b, 1, 1, abfd) != 1)
+       goto error_return;
+    }
+
+  return true;
 
  error_return:
   if (aout_info.contents != NULL)
@@ -3733,6 +3957,8 @@ NAME(aout,final_link) (abfd, info, callback)
     free (aout_info.symbol_map);
   if (aout_info.output_syms != NULL)
     free (aout_info.output_syms);
+  if (includes_hash_initialized)
+    bfd_hash_table_free (&aout_info.includes.root);
   return false;
 }
 
@@ -3768,16 +3994,25 @@ aout_link_input_bfd (finfo, input_bfd)
     return false;
 
   /* Relocate and write out the sections.  These functions use the
-     symbol map created by aout_link_write_symbols.  */
-  if (! aout_link_input_section (finfo, input_bfd,
-                                obj_textsec (input_bfd),
-                                &finfo->treloff,
-                                exec_hdr (input_bfd)->a_trsize)
-      || ! aout_link_input_section (finfo, input_bfd,
-                                   obj_datasec (input_bfd),
-                                   &finfo->dreloff,
-                                   exec_hdr (input_bfd)->a_drsize))
-    return false;
+     symbol map created by aout_link_write_symbols.  The linker_mark
+     field will be set if these sections are to be included in the
+     link, which will normally be the case.  */
+  if (obj_textsec (input_bfd)->linker_mark)
+    {
+      if (! aout_link_input_section (finfo, input_bfd,
+                                    obj_textsec (input_bfd),
+                                    &finfo->treloff,
+                                    exec_hdr (input_bfd)->a_trsize))
+       return false;
+    }
+  if (obj_datasec (input_bfd)->linker_mark)
+    {
+      if (! aout_link_input_section (finfo, input_bfd,
+                                    obj_datasec (input_bfd),
+                                    &finfo->dreloff,
+                                    exec_hdr (input_bfd)->a_drsize))
+       return false;
+    }
 
   /* If we are not keeping memory, we don't need the symbols any
      longer.  We still need them if we are keeping memory, because the
@@ -3851,6 +4086,7 @@ aout_link_write_symbols (finfo, input_bfd)
   sym_end = sym + sym_count;
   sym_hash = obj_aout_sym_hashes (input_bfd);
   symbol_map = finfo->symbol_map;
+  memset (symbol_map, 0, sym_count * sizeof *symbol_map);
   for (; sym < sym_end; sym++, sym_hash++, symbol_map++)
     {
       const char *name;
@@ -3861,6 +4097,16 @@ aout_link_write_symbols (finfo, input_bfd)
       bfd_vma val = 0;
       boolean copy;
 
+      /* We set *symbol_map to 0 above for all symbols.  If it has
+         already been set to -1 for this symbol, it means that we are
+         discarding it because it appears in a duplicate header file.
+         See the N_BINCL code below.  */
+      if (*symbol_map == -1)
+       continue;
+
+      /* Initialize *symbol_map to -1, which means that the symbol was
+         not copied into the output file.  We will change it later if
+         we do copy the symbol over.  */
       *symbol_map = -1;
 
       type = bfd_h_get_8 (input_bfd, sym->e_type);
@@ -3893,6 +4139,11 @@ aout_link_write_symbols (finfo, input_bfd)
             external symbol. */
          h = *sym_hash;
 
+         /* Use the name from the hash table, in case the symbol was
+             wrapped.  */
+         if (h != NULL)
+           name = h->root.root.string;
+
          /* If this is an indirect or warning symbol, then change
             hresolve to the base symbol.  We also change *sym_hash so
             that the relocation routines relocate against the real
@@ -4094,10 +4345,8 @@ aout_link_write_symbols (finfo, input_bfd)
                case discard_none:
                  break;
                case discard_l:
-                 if (*name == *finfo->info->lprefix
-                     && (finfo->info->lprefix_len == 1
-                         || strncmp (name, finfo->info->lprefix,
-                                     finfo->info->lprefix_len) == 0))
+                 if ((type & N_STAB) == 0
+                     && bfd_is_local_label_name (input_bfd, name))
                    skip = true;
                  break;
                case discard_all:
@@ -4110,6 +4359,112 @@ aout_link_write_symbols (finfo, input_bfd)
                  continue;
                }
            }
+
+         /* An N_BINCL symbol indicates the start of the stabs
+            entries for a header file.  We need to scan ahead to the
+            next N_EINCL symbol, ignoring nesting, adding up all the
+            characters in the symbol names, not including the file
+            numbers in types (the first number after an open
+            parenthesis).  */
+         if (type == N_BINCL)
+           {
+             struct external_nlist *incl_sym;
+             int nest;
+             struct aout_link_includes_entry *incl_entry;
+             struct aout_link_includes_totals *t;
+
+             val = 0;
+             nest = 0;
+             for (incl_sym = sym + 1; incl_sym < sym_end; incl_sym++)
+               {
+                 int incl_type;
+
+                 incl_type = bfd_h_get_8 (input_bfd, incl_sym->e_type);
+                 if (incl_type == N_EINCL)
+                   {
+                     if (nest == 0)
+                       break;
+                     --nest;
+                   }
+                 else if (incl_type == N_BINCL)
+                   ++nest;
+                 else if (nest == 0)
+                   {
+                     const char *s;
+
+                     s = strings + GET_WORD (input_bfd, incl_sym->e_strx);
+                     for (; *s != '\0'; s++)
+                       {
+                         val += *s;
+                         if (*s == '(')
+                           {
+                             /* Skip the file number.  */
+                             ++s;
+                             while (isdigit ((unsigned char) *s))
+                               ++s;
+                             --s;
+                           }
+                       }
+                   }
+               }
+
+             /* If we have already included a header file with the
+                 same value, then replace this one with an N_EXCL
+                 symbol.  */
+             copy = ! finfo->info->keep_memory;
+             incl_entry = aout_link_includes_lookup (&finfo->includes,
+                                                     name, true, copy);
+             if (incl_entry == NULL)
+               return false;
+             for (t = incl_entry->totals; t != NULL; t = t->next)
+               if (t->total == val)
+                 break;
+             if (t == NULL)
+               {
+                 /* This is the first time we have seen this header
+                     file with this set of stabs strings.  */
+                 t = ((struct aout_link_includes_totals *)
+                      bfd_hash_allocate (&finfo->includes.root,
+                                         sizeof *t));
+                 if (t == NULL)
+                   return false;
+                 t->total = val;
+                 t->next = incl_entry->totals;
+                 incl_entry->totals = t;
+               }
+             else
+               {
+                 int *incl_map;
+
+                 /* This is a duplicate header file.  We must change
+                     it to be an N_EXCL entry, and mark all the
+                     included symbols to prevent outputting them.  */
+                 type = N_EXCL;
+
+                 nest = 0;
+                 for (incl_sym = sym + 1, incl_map = symbol_map + 1;
+                      incl_sym < sym_end;
+                      incl_sym++, incl_map++)
+                   {
+                     int incl_type;
+
+                     incl_type = bfd_h_get_8 (input_bfd, incl_sym->e_type);
+                     if (incl_type == N_EINCL)
+                       {
+                         if (nest == 0)
+                           {
+                             *incl_map = -1;
+                             break;
+                           }
+                         --nest;
+                       }
+                     else if (incl_type == N_BINCL)
+                       ++nest;
+                     else if (nest == 0)
+                       *incl_map = -1;
+                   }
+               }
+           }
        }
 
       /* Copy this symbol into the list of symbols we are going to
@@ -4382,6 +4737,8 @@ aout_reloc_index_to_section (abfd, indx)
     default:
       abort ();
     }
+  /*NOTREACHED*/
+  return NULL;
 }
 
 /* Relocate an a.out section using standard a.out relocs.  */
@@ -4415,8 +4772,8 @@ aout_link_input_section_std (finfo, input_bfd, input_section, relocs,
   check_dynamic_reloc = aout_backend_info (output_bfd)->check_dynamic_reloc;
 
   BFD_ASSERT (obj_reloc_entry_size (input_bfd) == RELOC_STD_SIZE);
-  BFD_ASSERT (input_bfd->xvec->header_byteorder_big_p
-             == output_bfd->xvec->header_byteorder_big_p);
+  BFD_ASSERT (input_bfd->xvec->header_byteorder
+             == output_bfd->xvec->header_byteorder);
 
   relocateable = finfo->info->relocateable;
   syms = obj_aout_external_syms (input_bfd);
@@ -4450,7 +4807,7 @@ aout_link_input_section_std (finfo, input_bfd, input_section, relocs,
        int r_length;
        unsigned int howto_idx;
 
-       if (input_bfd->xvec->header_byteorder_big_p)
+       if (bfd_header_big_endian (input_bfd))
          {
            r_index   =  ((rel->r_index[0] << 16)
                          | (rel->r_index[1] << 8)
@@ -4504,7 +4861,7 @@ aout_link_input_section_std (finfo, input_bfd, input_section, relocs,
                  asection *output_section;
 
                  /* Change the r_extern value.  */
-                 if (output_bfd->xvec->header_byteorder_big_p)
+                 if (bfd_header_big_endian (output_bfd))
                    rel->r_type[0] &=~ RELOC_STD_BITS_EXTERN_BIG;
                  else
                    rel->r_type[0] &=~ RELOC_STD_BITS_EXTERN_LITTLE;
@@ -4569,7 +4926,7 @@ aout_link_input_section_std (finfo, input_bfd, input_section, relocs,
                }
 
              /* Write out the new r_index value.  */
-             if (output_bfd->xvec->header_byteorder_big_p)
+             if (bfd_header_big_endian (output_bfd))
                {
                  rel->r_index[0] = r_index >> 16;
                  rel->r_index[1] = r_index >> 8;
@@ -4625,6 +4982,7 @@ aout_link_input_section_std (finfo, input_bfd, input_section, relocs,
          /* We are generating an executable, and must do a full
             relocation.  */
          hundef = false;
+
          if (r_extern)
            {
              h = sym_hashes[r_index];
@@ -4677,16 +5035,20 @@ aout_link_input_section_std (finfo, input_bfd, input_section, relocs,
            {
              const char *name;
 
-             name = strings + GET_WORD (input_bfd, syms[r_index].e_strx);
+             if (h != NULL)
+               name = h->root.root.string;
+             else
+               name = strings + GET_WORD (input_bfd, syms[r_index].e_strx);
              if (! ((*finfo->info->callbacks->undefined_symbol)
-                    (finfo->info, name, input_bfd, input_section, r_addr)))
+                    (finfo->info, name, input_bfd, input_section,
+                    r_addr, true)))
                return false;
            }
 
          r = MY_final_link_relocate (howto,
-                                       input_bfd, input_section,
-                                       contents, r_addr, relocation,
-                                       (bfd_vma) 0);
+                                     input_bfd, input_section,
+                                     contents, r_addr, relocation,
+                                     (bfd_vma) 0);
        }
 
       if (r != bfd_reloc_ok)
@@ -4700,7 +5062,9 @@ aout_link_input_section_std (finfo, input_bfd, input_section, relocs,
              {
                const char *name;
 
-               if (r_extern)
+               if (h != NULL)
+                 name = h->root.root.string;
+               else if (r_extern)
                  name = strings + GET_WORD (input_bfd,
                                             syms[r_index].e_strx);
                else
@@ -4754,8 +5118,8 @@ aout_link_input_section_ext (finfo, input_bfd, input_section, relocs,
   check_dynamic_reloc = aout_backend_info (output_bfd)->check_dynamic_reloc;
 
   BFD_ASSERT (obj_reloc_entry_size (input_bfd) == RELOC_EXT_SIZE);
-  BFD_ASSERT (input_bfd->xvec->header_byteorder_big_p
-             == output_bfd->xvec->header_byteorder_big_p);
+  BFD_ASSERT (input_bfd->xvec->header_byteorder
+             == output_bfd->xvec->header_byteorder);
 
   relocateable = finfo->info->relocateable;
   syms = obj_aout_external_syms (input_bfd);
@@ -4779,7 +5143,7 @@ aout_link_input_section_ext (finfo, input_bfd, input_section, relocs,
 
       r_addr = GET_SWORD (input_bfd, rel->r_address);
 
-      if (input_bfd->xvec->header_byteorder_big_p)
+      if (bfd_header_big_endian (input_bfd))
        {
          r_index  = ((rel->r_index[0] << 16)
                      | (rel->r_index[1] << 8)
@@ -4806,12 +5170,20 @@ aout_link_input_section_ext (finfo, input_bfd, input_section, relocs,
        {
          /* We are generating a relocateable output file, and must
             modify the reloc accordingly.  */
-         if (r_extern)
+         if (r_extern
+             || r_type == RELOC_BASE10
+             || r_type == RELOC_BASE13
+             || r_type == RELOC_BASE22)
            {
              /* If we know the symbol this relocation is against,
                 convert it into a relocation against a section.  This
                 is what the native linker does.  */
-             h = sym_hashes[r_index];
+             if (r_type == RELOC_BASE10
+                 || r_type == RELOC_BASE13
+                 || r_type == RELOC_BASE22)
+               h = NULL;
+             else
+               h = sym_hashes[r_index];
              if (h != (struct aout_link_hash_entry *) NULL
                  && (h->root.type == bfd_link_hash_defined
                      || h->root.type == bfd_link_hash_defweak))
@@ -4819,7 +5191,7 @@ aout_link_input_section_ext (finfo, input_bfd, input_section, relocs,
                  asection *output_section;
 
                  /* Change the r_extern value.  */
-                 if (output_bfd->xvec->header_byteorder_big_p)
+                 if (bfd_header_big_endian (output_bfd))
                    rel->r_type[0] &=~ RELOC_EXT_BITS_EXTERN_BIG;
                  else
                    rel->r_type[0] &=~ RELOC_EXT_BITS_EXTERN_LITTLE;
@@ -4897,7 +5269,7 @@ aout_link_input_section_ext (finfo, input_bfd, input_section, relocs,
                }
 
              /* Write out the new r_index value.  */
-             if (output_bfd->xvec->header_byteorder_big_p)
+             if (bfd_header_big_endian (output_bfd))
                {
                  rel->r_index[0] = r_index >> 16;
                  rel->r_index[1] = r_index >> 8;
@@ -4927,8 +5299,12 @@ aout_link_input_section_ext (finfo, input_bfd, input_section, relocs,
            }
 
          /* As described above, we must always adjust a PC relative
-            reloc by the change in VMA of the source.  */
-         if (howto_table_ext[r_type].pc_relative)
+            reloc by the change in VMA of the source.  However, if
+            pcrel_offset is set, then the addend does not include the
+            location within the section, in which case we don't need
+            to adjust anything.  */
+         if (howto_table_ext[r_type].pc_relative
+             && ! howto_table_ext[r_type].pcrel_offset)
            relocation -= (input_section->output_section->vma
                           + input_section->output_offset
                           - input_section->vma);
@@ -4950,6 +5326,7 @@ aout_link_input_section_ext (finfo, input_bfd, input_section, relocs,
          /* We are generating an executable, and must do a full
             relocation.  */
          hundef = false;
+
          if (r_extern)
            {
              h = sym_hashes[r_index];
@@ -5061,16 +5438,31 @@ aout_link_input_section_ext (finfo, input_bfd, input_section, relocs,
            {
              const char *name;
 
-             name = strings + GET_WORD (input_bfd, syms[r_index].e_strx);
+             if (h != NULL)
+               name = h->root.root.string;
+             else
+               name = strings + GET_WORD (input_bfd, syms[r_index].e_strx);
              if (! ((*finfo->info->callbacks->undefined_symbol)
-                    (finfo->info, name, input_bfd, input_section, r_addr)))
+                    (finfo->info, name, input_bfd, input_section,
+                    r_addr, true)))
                return false;
            }
 
-         r = MY_final_link_relocate (howto_table_ext + r_type,
+         if (r_type != RELOC_SPARC_REV32)
+           r = MY_final_link_relocate (howto_table_ext + r_type,
                                        input_bfd, input_section,
                                        contents, r_addr, relocation,
                                        r_addend);
+         else
+           {
+             bfd_vma x;
+
+             x = bfd_get_32 (input_bfd, contents + r_addr);
+             x = x + relocation + r_addend;
+             bfd_putl32 (/*input_bfd,*/ x, contents + r_addr);
+             r = bfd_reloc_ok;
+           }
+
          if (r != bfd_reloc_ok)
            {
              switch (r)
@@ -5082,10 +5474,12 @@ aout_link_input_section_ext (finfo, input_bfd, input_section, relocs,
                  {
                    const char *name;
 
-                   if (r_extern
-                       || r_type == RELOC_BASE10
-                       || r_type == RELOC_BASE13
-                       || r_type == RELOC_BASE22)
+                   if (h != NULL)
+                     name = h->root.root.string;
+                   else if (r_extern
+                            || r_type == RELOC_BASE10
+                            || r_type == RELOC_BASE13
+                            || r_type == RELOC_BASE22)
                      name = strings + GET_WORD (input_bfd,
                                                 syms[r_index].e_strx);
                    else
@@ -5121,7 +5515,7 @@ aout_link_reloc_link_order (finfo, o, p)
   int r_index;
   int r_extern;
   reloc_howto_type *howto;
-  file_ptr *reloff_ptr;
+  file_ptr *reloff_ptr = NULL;
   struct reloc_std_external srel;
   struct reloc_ext_external erel;
   PTR rel_ptr;
@@ -5145,8 +5539,9 @@ aout_link_reloc_link_order (finfo, o, p)
 
       BFD_ASSERT (p->type == bfd_symbol_reloc_link_order);
       r_extern = 1;
-      h = aout_link_hash_lookup (aout_hash_table (finfo->info),
-                                pr->u.name, false, false, true);
+      h = ((struct aout_link_hash_entry *)
+          bfd_wrapped_link_hash_lookup (finfo->output_bfd, finfo->info,
+                                        pr->u.name, false, false, true));
       if (h != (struct aout_link_hash_entry *) NULL
          && h->indx >= 0)
        r_index = h->indx;
@@ -5206,7 +5601,7 @@ aout_link_reloc_link_order (finfo, o, p)
        r_length = howto->size;
 
        PUT_WORD (finfo->output_bfd, p->offset, srel.r_address);
-       if (finfo->output_bfd->xvec->header_byteorder_big_p)
+       if (bfd_header_big_endian (finfo->output_bfd))
          {
            srel.r_index[0] = r_index >> 16;
            srel.r_index[1] = r_index >> 8;
@@ -5287,9 +5682,13 @@ aout_link_reloc_link_order (finfo, o, p)
     }
   else
     {
+#ifdef MY_put_ext_reloc
+      MY_put_ext_reloc (finfo->output_bfd, r_extern, r_index, p->offset,
+                       howto, &erel, pr->addend);
+#else
       PUT_WORD (finfo->output_bfd, p->offset, erel.r_address);
 
-      if (finfo->output_bfd->xvec->header_byteorder_big_p)
+      if (bfd_header_big_endian (finfo->output_bfd))
        {
          erel.r_index[0] = r_index >> 16;
          erel.r_index[1] = r_index >> 8;
@@ -5309,6 +5708,7 @@ aout_link_reloc_link_order (finfo, o, p)
        }
 
       PUT_WORD (finfo->output_bfd, pr->addend, erel.r_addend);
+#endif /* MY_put_ext_reloc */
 
       rel_ptr = (PTR) &erel;
     }
This page took 0.044478 seconds and 4 git commands to generate.