*** empty log message ***
[deliverable/binutils-gdb.git] / bfd / aoutx.h
index f62228d884c0d5c570febd7368efdd1a56f30af1..7eebb168fc7be21b6d18f49e7d7608a1d8bbc786 100644 (file)
@@ -1,28 +1,29 @@
 /* BFD semi-generic back-end for a.out binaries.
-   Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
+   Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000,
+   2001, 2002
+   Free Software Foundation, Inc.
    Written by Cygnus Support.
 
-This file is part of BFD, the Binary File Descriptor library.
+   This file is part of BFD, the Binary File Descriptor library.
 
-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
-(at your option) any later version.
+   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
+   (at your option) any later version.
 
-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.
+   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., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+   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.  */
 
 /*
 SECTION
        a.out backends
 
-
 DESCRIPTION
 
        BFD supports a number of different flavours of a.out format,
@@ -117,12 +118,11 @@ DESCRIPTION
    (Just want to make these explicit, so the conditions tested in this
    file make sense if you're more familiar with a.out than with BFD.)  */
 
-#define KEEPIT flags
-#define KEEPITTYPE int
+#define KEEPIT udata.i
 
-#include <string.h>            /* For strchr and friends */
 #include "bfd.h"
-#include <sysdep.h>
+#include "sysdep.h"
+#include "safe-ctype.h"
 #include "bfdlink.h"
 
 #include "libaout.h"
@@ -136,6 +136,11 @@ 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 *));
+reloc_howto_type * NAME(aout,reloc_type_lookup)
+  PARAMS ((bfd *, bfd_reloc_code_real_type));
 
 /*
 SUBSECTION
@@ -153,25 +158,42 @@ DESCRIPTION
 */
 #ifndef CTOR_TABLE_RELOC_HOWTO
 #define CTOR_TABLE_RELOC_IDX 2
-#define CTOR_TABLE_RELOC_HOWTO(BFD) ((obj_reloc_entry_size(BFD) == RELOC_EXT_SIZE \
-            ? howto_table_ext : howto_table_std) \
-           + CTOR_TABLE_RELOC_IDX)
+#define CTOR_TABLE_RELOC_HOWTO(BFD)                                    \
+  ((obj_reloc_entry_size (BFD) == RELOC_EXT_SIZE                       \
+    ? howto_table_ext : howto_table_std)                               \
+   + CTOR_TABLE_RELOC_IDX)
 #endif
 
 #ifndef MY_swap_std_reloc_in
 #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
+
+#ifndef MY_relocate_contents
+#define MY_relocate_contents _bfd_relocate_contents
+#endif
+
 #define howto_table_ext NAME(aout,ext_howto_table)
 #define howto_table_std NAME(aout,std_howto_table)
 
 reloc_howto_type howto_table_ext[] =
 {
-  /* type           rs   size bsz  pcrel bitpos ovrf                  sf name          part_inpl readmask setmask pcdone */
+  /* type           rs   size bsz  pcrel bitpos ovrf                  sf name          part_inpl readmask setmask pcdone */
   HOWTO(RELOC_8,      0,  0,   8,  false, 0, complain_overflow_bitfield,0,"8",        false, 0,0x000000ff, false),
   HOWTO(RELOC_16,     0,  1,   16, false, 0, complain_overflow_bitfield,0,"16",       false, 0,0x0000ffff, false),
   HOWTO(RELOC_32,     0,  2,   32, false, 0, complain_overflow_bitfield,0,"32",       false, 0,0xffffffff, false),
@@ -186,68 +208,80 @@ 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_PC10,   0,  2,   10, false, 0, complain_overflow_bitfield,0,"PC10",      false, 0,0x000003ff, false),
-  HOWTO(RELOC_PC22,   0,  2,   22, false, 0, complain_overflow_bitfield,0,"PC22",      false, 0,0x003fffff, false),
-  HOWTO(RELOC_JMP_TBL,0,  2,   32, false, 0, complain_overflow_bitfield,0,"JMP_TBL",   false, 0,0xffffffff, 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),
   HOWTO(RELOC_SEGOFF16,0, 2,   0,  false, 0, complain_overflow_bitfield,0,"SEGOFF16",  false, 0,0x00000000, false),
   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).  */
 
 reloc_howto_type howto_table_std[] = {
-  /* type              rs size bsz  pcrel bitpos ovrf                     sf name     part_inpl readmask  setmask    pcdone */
-HOWTO( 0,             0,  0,   8,  false, 0, complain_overflow_bitfield,0,"8",         true, 0x000000ff,0x000000ff, false),
-HOWTO( 1,             0,  1,   16, false, 0, complain_overflow_bitfield,0,"16",        true, 0x0000ffff,0x0000ffff, false),
-HOWTO( 2,             0,  2,   32, false, 0, complain_overflow_bitfield,0,"32",        true, 0xffffffff,0xffffffff, false),
-HOWTO( 3,             0,  4,   64, false, 0, complain_overflow_bitfield,0,"64",        true, 0xdeaddead,0xdeaddead, false),
-HOWTO( 4,             0,  0,   8,  true,  0, complain_overflow_signed,  0,"DISP8",     true, 0x000000ff,0x000000ff, false),
-HOWTO( 5,             0,  1,   16, true,  0, complain_overflow_signed,  0,"DISP16",    true, 0x0000ffff,0x0000ffff, false),
-HOWTO( 6,             0,  2,   32, true,  0, complain_overflow_signed,  0,"DISP32",    true, 0xffffffff,0xffffffff, false),
-HOWTO( 7,             0,  4,   64, true,  0, complain_overflow_signed,  0,"DISP64",    true, 0xfeedface,0xfeedface, false),
-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 },
-  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 },
-  HOWTO(32,           0,  2,    0, false, 0, complain_overflow_bitfield,0,"RELATIVE",  false,         0,0x00000000, false),
-{ -1 },
-{ -1 },
-{ -1 },
-{ -1 },
-{ -1 },
-{ -1 },
-{ -1 },
-  HOWTO(40,           0,  2,    0, false, 0, complain_overflow_bitfield,0,"BASEREL",   false,         0,0x00000000, false),
+  /* type              rs size bsz  pcrel bitpos ovrf                     sf name     part_inpl readmask  setmask    pcdone.  */
+HOWTO ( 0,            0,  0,   8,  false, 0, complain_overflow_bitfield,0,"8",         true, 0x000000ff,0x000000ff, false),
+HOWTO ( 1,            0,  1,   16, false, 0, complain_overflow_bitfield,0,"16",        true, 0x0000ffff,0x0000ffff, false),
+HOWTO ( 2,            0,  2,   32, false, 0, complain_overflow_bitfield,0,"32",        true, 0xffffffff,0xffffffff, false),
+HOWTO ( 3,            0,  4,   64, false, 0, complain_overflow_bitfield,0,"64",        true, 0xdeaddead,0xdeaddead, false),
+HOWTO ( 4,            0,  0,   8,  true,  0, complain_overflow_signed,  0,"DISP8",     true, 0x000000ff,0x000000ff, false),
+HOWTO ( 5,            0,  1,   16, true,  0, complain_overflow_signed,  0,"DISP16",    true, 0x0000ffff,0x0000ffff, false),
+HOWTO ( 6,            0,  2,   32, true,  0, complain_overflow_signed,  0,"DISP32",    true, 0xffffffff,0xffffffff, false),
+HOWTO ( 7,            0,  4,   64, true,  0, complain_overflow_signed,  0,"DISP64",    true, 0xfeedface,0xfeedface, false),
+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),
+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),
+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),
+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),
 };
 
-#define TABLE_SIZE(TABLE)      (sizeof(TABLE)/sizeof(TABLE[0]))
+#define TABLE_SIZE(TABLE)      (sizeof (TABLE) / sizeof (TABLE[0]))
 
-CONST struct reloc_howto_struct *
+reloc_howto_type *
 NAME(aout,reloc_type_lookup) (abfd,code)
      bfd *abfd;
      bfd_reloc_code_real_type code;
 {
-#define EXT(i,j)       case i: return &howto_table_ext[j]
-#define STD(i,j)       case i: return &howto_table_std[j]
+#define EXT(i, j)      case i: return &howto_table_ext[j]
+#define STD(i, j)      case i: return &howto_table_std[j]
   int ext = obj_reloc_entry_size (abfd) == RELOC_EXT_SIZE;
+
   if (code == BFD_RELOC_CTOR)
     switch (bfd_get_arch_info (abfd)->bits_per_address)
       {
@@ -258,20 +292,30 @@ NAME(aout,reloc_type_lookup) (abfd,code)
        code = BFD_RELOC_64;
        break;
       }
+
   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);
        EXT (BFD_RELOC_32_PCREL_S2, 6);
        EXT (BFD_RELOC_SPARC_WDISP22, 7);
        EXT (BFD_RELOC_SPARC13, 10);
+       EXT (BFD_RELOC_SPARC_GOT10, 14);
        EXT (BFD_RELOC_SPARC_BASE13, 15);
-      default: return (CONST struct reloc_howto_struct *) 0;
+       EXT (BFD_RELOC_SPARC_GOT13, 15);
+       EXT (BFD_RELOC_SPARC_GOT22, 16);
+       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
-    /* std relocs */
+    /* std relocs */
     switch (code)
       {
        STD (BFD_RELOC_16, 1);
@@ -281,7 +325,7 @@ NAME(aout,reloc_type_lookup) (abfd,code)
        STD (BFD_RELOC_32_PCREL, 6);
        STD (BFD_RELOC_16_BASEREL, 9);
        STD (BFD_RELOC_32_BASEREL, 10);
-      default: return (CONST struct reloc_howto_struct *) 0;
+      default: return (reloc_howto_type *) NULL;
       }
 }
 
@@ -324,10 +368,10 @@ NAME(aout,swap_exec_header_in) (abfd, raw_bytes, execp)
   /* The internal_exec structure has some fields that are unused in this
      configuration (IE for i960), so ensure that all such uninitialized
      fields are zero'd out.  There are places where two of these structs
-     are memcmp'd, and thus the contents do matter. */
+     are memcmp'd, and thus the contents do matter.  */
   memset ((PTR) execp, 0, sizeof (struct internal_exec));
   /* Now fill in fields in the execp, from the bytes in the raw data.  */
-  execp->a_info   = bfd_h_get_32 (abfd, bytes->e_info);
+  execp->a_info   = H_GET_32 (abfd, bytes->e_info);
   execp->a_text   = GET_WORD (abfd, bytes->e_text);
   execp->a_data   = GET_WORD (abfd, bytes->e_data);
   execp->a_bss    = GET_WORD (abfd, bytes->e_bss);
@@ -361,8 +405,8 @@ NAME(aout,swap_exec_header_out) (abfd, execp, raw_bytes)
 {
   struct external_exec *bytes = (struct external_exec *)raw_bytes;
 
-  /* Now fill in fields in the raw data, from the fields in the exec struct. */
-  bfd_h_put_32 (abfd, execp->a_info  , bytes->e_info);
+  /* Now fill in fields in the raw data, from the fields in the exec struct.  */
+  H_PUT_32 (abfd, execp->a_info  , bytes->e_info);
   PUT_WORD (abfd, execp->a_text  , bytes->e_text);
   PUT_WORD (abfd, execp->a_data  , bytes->e_data);
   PUT_WORD (abfd, execp->a_bss   , bytes->e_bss);
@@ -397,7 +441,7 @@ FUNCTION
 SYNOPSIS
        const bfd_target *aout_@var{size}_some_aout_object_p
         (bfd *abfd,
-         const bfd_target *(*callback_to_real_object_p)());
+         const bfd_target *(*callback_to_real_object_p) ());
 
 DESCRIPTION
        Some a.out variant thinks that the file open in @var{abfd}
@@ -415,12 +459,11 @@ NAME(aout,some_aout_object_p) (abfd, execp, callback_to_real_object_p)
 {
   struct aout_data_struct *rawptr, *oldrawptr;
   const bfd_target *result;
+  bfd_size_type amt = sizeof (struct aout_data_struct);
 
-  rawptr = (struct aout_data_struct  *) bfd_zalloc (abfd, sizeof (struct aout_data_struct ));
-  if (rawptr == NULL) {
-    bfd_set_error (bfd_error_no_memory);
+  rawptr = (struct aout_data_struct  *) bfd_zalloc (abfd, amt);
+  if (rawptr == NULL)
     return 0;
-  }
 
   oldrawptr = abfd->tdata.aout_data;
   abfd->tdata.aout_data = rawptr;
@@ -433,17 +476,18 @@ NAME(aout,some_aout_object_p) (abfd, execp, callback_to_real_object_p)
     *abfd->tdata.aout_data = *oldrawptr;
 
   abfd->tdata.aout_data->a.hdr = &rawptr->e;
-  *(abfd->tdata.aout_data->a.hdr) = *execp;    /* Copy in the internal_exec struct */
+  /* Copy in the internal_exec struct.  */
+  *(abfd->tdata.aout_data->a.hdr) = *execp;
   execp = abfd->tdata.aout_data->a.hdr;
 
-  /* Set the file flags */
-  abfd->flags = NO_FLAGS;
+  /* Set the file 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 */
+  /* Setting of EXEC_P has been deferred to the bottom of this function */
   if (execp->a_syms)
     abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS;
-  if (N_DYNAMIC(*execp))
+  if (N_DYNAMIC (*execp))
     abfd->flags |= DYNAMIC;
 
   if (N_MAGIC (*execp) == ZMAGIC)
@@ -480,15 +524,19 @@ NAME(aout,some_aout_object_p) (abfd, execp, callback_to_real_object_p)
   /* The default relocation entry size is that of traditional V7 Unix.  */
   obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
 
-  /* The default symbol entry size is that of traditional Unix. */
+  /* The default symbol entry size is that of traditional Unix.  */
   obj_symbol_entry_size (abfd) = EXTERNAL_NLIST_SIZE;
 
+#ifdef USE_MMAP
+  bfd_init_window (&obj_aout_sym_window (abfd));
+  bfd_init_window (&obj_aout_string_window (abfd));
+#endif
   obj_aout_external_syms (abfd) = NULL;
   obj_aout_external_strings (abfd) = NULL;
   obj_aout_sym_hashes (abfd) = NULL;
 
   if (! NAME(aout,make_sections) (abfd))
-    return NULL;
+    goto error_ret;
 
   obj_datasec (abfd)->_raw_size = execp->a_data;
   obj_bsssec (abfd)->_raw_size = execp->a_bss;
@@ -516,37 +564,38 @@ NAME(aout,some_aout_object_p) (abfd, execp, callback_to_real_object_p)
 
   struct exec *execp = exec_hdr (abfd);
 
-  obj_textsec (abfd)->size = N_TXTSIZE(*execp);
-  obj_textsec (abfd)->raw_size = N_TXTSIZE(*execp);
-  /* data and bss are already filled in since they're so standard */
+  obj_textsec (abfd)->size = N_TXTSIZE (*execp);
+  obj_textsec (abfd)->raw_size = N_TXTSIZE (*execp);
+  /* Data and bss are already filled in since they're so standard.  */
 
-  /* The virtual memory addresses of the sections */
-  obj_textsec (abfd)->vma = N_TXTADDR(*execp);
-  obj_datasec (abfd)->vma = N_DATADDR(*execp);
-  obj_bsssec  (abfd)->vma = N_BSSADDR(*execp);
+  /* The virtual memory addresses of the sections */
+  obj_textsec (abfd)->vma = N_TXTADDR (*execp);
+  obj_datasec (abfd)->vma = N_DATADDR (*execp);
+  obj_bsssec  (abfd)->vma = N_BSSADDR (*execp);
 
-  /* The file offsets of the sections */
-  obj_textsec (abfd)->filepos = N_TXTOFF(*execp);
-  obj_datasec (abfd)->filepos = N_DATOFF(*execp);
+  /* The file offsets of the sections */
+  obj_textsec (abfd)->filepos = N_TXTOFF (*execp);
+  obj_datasec (abfd)->filepos = N_DATOFF (*execp);
 
-  /* The file offsets of the relocation info */
-  obj_textsec (abfd)->rel_filepos = N_TRELOFF(*execp);
-  obj_datasec (abfd)->rel_filepos = N_DRELOFF(*execp);
+  /* The file offsets of the relocation info */
+  obj_textsec (abfd)->rel_filepos = N_TRELOFF (*execp);
+  obj_datasec (abfd)->rel_filepos = N_DRELOFF (*execp);
 
   /* The file offsets of the string table and symbol table.  */
   obj_str_filepos (abfd) = N_STROFF (*execp);
   obj_sym_filepos (abfd) = N_SYMOFF (*execp);
 
   /* Determine the architecture and machine type of the object file.  */
-  switch (N_MACHTYPE (*exec_hdr (abfd))) {
-  default:
-    abfd->obj_arch = bfd_arch_obscure;
-    break;
-  }
+  switch (N_MACHTYPE (*exec_hdr (abfd)))
+    {
+    default:
+      abfd->obj_arch = bfd_arch_obscure;
+      break;
+    }
 
-  adata(abfd)->page_size = PAGE_SIZE;
-  adata(abfd)->segment_size = SEGMENT_SIZE;
-  adata(abfd)->exec_bytes_size = EXEC_BYTES_SIZE;
+  adata (abfd)->page_size = TARGET_PAGE_SIZE;
+  adata (abfd)->segment_size = SEGMENT_SIZE;
+  adata (abfd)->exec_bytes_size = EXEC_BYTES_SIZE;
 
   return abfd->xvec;
 
@@ -560,37 +609,48 @@ NAME(aout,some_aout_object_p) (abfd, execp, callback_to_real_object_p)
      header, should cope with them in this callback as well.  */
 #endif                         /* DOCUMENTATION */
 
-  result = (*callback_to_real_object_p)(abfd);
+  result = (*callback_to_real_object_p) (abfd);
 
-#ifdef STAT_FOR_EXEC
-  /* The original heuristic doesn't work in some important cases. The
-   * a.out file has no information about the text start address. For
-   * files (like kernels) linked to non-standard addresses (ld -Ttext
-   * nnn) the entry point may not be between 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.
-   */
-  {
-    struct stat stat_buf;
-    if (abfd->iostream
-       && (fstat(fileno((FILE *) (abfd->iostream)), &stat_buf) == 0)
-       && ((stat_buf.st_mode & 0111) != 0))
-      abfd->flags |= EXEC_P;
-  }
-#else /* ! defined (STAT_FOR_EXEC) */
   /* Now that the segment addresses have been worked out, take a better
      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.)
+     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.
 
-     At some point we should probably break down and stat the file and
-     declare it executable if (one of) its 'x' bits are on...  */
-  if ((execp->a_entry >= obj_textsec(abfd)->vma) &&
-      (execp->a_entry < obj_textsec(abfd)->vma + obj_textsec(abfd)->_raw_size))
+     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;
-#endif /* ! defined (STAT_FOR_EXEC) */
+#ifdef STAT_FOR_EXEC
+  else
+    {
+      struct stat stat_buf;
+
+      /* The original heuristic doesn't work in some important cases.
+        The a.out file has no information about the text start
+        address.  For files (like kernels) linked to non-standard
+        addresses (ld -Ttext nnn) the entry point may not be between
+        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 != 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;
+    }
+#endif /* STAT_FOR_EXEC */
+
   if (result)
     {
 #if 0 /* These should be set correctly anyways.  */
@@ -598,13 +658,13 @@ NAME(aout,some_aout_object_p) (abfd, execp, callback_to_real_object_p)
       obj_textsec (abfd)->next = obj_datasec (abfd);
       obj_datasec (abfd)->next = obj_bsssec (abfd);
 #endif
+      return result;
     }
-  else
-    {
-      free (rawptr);
-      abfd->tdata.aout_data = oldrawptr;
-    }
-  return result;
+
+ error_ret:
+  bfd_release (abfd, rawptr);
+  abfd->tdata.aout_data = oldrawptr;
+  return NULL;
 }
 
 /*
@@ -622,29 +682,25 @@ boolean
 NAME(aout,mkobject) (abfd)
      bfd *abfd;
 {
-  struct aout_data_struct  *rawptr;
+  struct aout_data_struct *rawptr;
+  bfd_size_type amt = sizeof (struct aout_data_struct);
 
   bfd_set_error (bfd_error_system_call);
 
-  /* Use an intermediate variable for clarity */
-  rawptr = (struct aout_data_struct *)bfd_zalloc (abfd, sizeof (struct aout_data_struct ));
-
-  if (rawptr == NULL) {
-    bfd_set_error (bfd_error_no_memory);
+  rawptr = (struct aout_data_struct *) bfd_zalloc (abfd, amt);
+  if (rawptr == NULL)
     return false;
-  }
 
   abfd->tdata.aout_data = rawptr;
   exec_hdr (abfd) = &(rawptr->e);
 
-  obj_textsec (abfd) = (asection *)NULL;
-  obj_datasec (abfd) = (asection *)NULL;
-  obj_bsssec (abfd) = (asection *)NULL;
+  obj_textsec (abfd) = (asection *) NULL;
+  obj_datasec (abfd) = (asection *) NULL;
+  obj_bsssec (abfd) = (asection *) NULL;
 
   return true;
 }
 
-
 /*
 FUNCTION
        aout_@var{size}_machine_type
@@ -675,53 +731,102 @@ NAME(aout,machine_type) (arch, machine, unknown)
   arch_flags = M_UNKNOWN;
   *unknown = true;
 
-  switch (arch) {
-  case bfd_arch_sparc:
-    if (machine == 0)  arch_flags = M_SPARC;
-    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;
-    }
-    break;
-
-  case bfd_arch_i386:
-    if (machine == 0)  arch_flags = M_386;
-    break;
-
-  case bfd_arch_a29k:
-    if (machine == 0)  arch_flags = M_29K;
-    break;
-
-  case bfd_arch_mips:
-    switch (machine) {
-    case 0:
-    case 2000:
-    case 3000:          arch_flags = M_MIPS1; break;
-    case 4000:
-    case 4400:
-    case 6000:          arch_flags = M_MIPS2; break;
-    default:            arch_flags = M_UNKNOWN; break;
-    }
-    break;
-
-  case bfd_arch_ns32k:
-    switch (machine) {
-    case 0:                    arch_flags = M_NS32532; break;
-    case 32032:                arch_flags = M_NS32032; break;
-    case 32532:                arch_flags = M_NS32532; break;
-    default:           arch_flags = M_UNKNOWN; break;
-    }
-    break;
+  switch (arch)
+    {
+    case bfd_arch_sparc:
+      if (machine == 0
+         || machine == bfd_mach_sparc
+         || 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;
 
-  default:
-    arch_flags = M_UNKNOWN;
-  }
+    case bfd_arch_m68k:
+      switch (machine)
+       {
+       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;
+
+    case bfd_arch_i386:
+      if (machine == 0)
+       arch_flags = M_386;
+      break;
+
+    case bfd_arch_a29k:
+      if (machine == 0)
+       arch_flags = M_29K;
+      break;
+
+    case bfd_arch_arm:
+      if (machine == 0)
+       arch_flags = M_ARM;
+      break;
+
+    case bfd_arch_mips:
+      switch (machine)
+       {
+       case 0:
+       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_mips12000:
+       case bfd_mach_mips16:
+       case bfd_mach_mipsisa32:
+       case bfd_mach_mips5:
+       case bfd_mach_mipsisa64:
+       case bfd_mach_mips_sb1:
+         /* FIXME: These should be MIPS3, MIPS4, MIPS16, MIPS32, etc.  */
+         arch_flags = M_MIPS2;
+         break;
+       default:
+         arch_flags = M_UNKNOWN;
+         break;
+       }
+      break;
+
+    case bfd_arch_ns32k:
+      switch (machine)
+       {
+       case 0:         arch_flags = M_NS32532; break;
+       case 32032:     arch_flags = M_NS32032; break;
+       case 32532:     arch_flags = M_NS32532; break;
+       default:        arch_flags = M_UNKNOWN; break;
+       }
+      break;
+
+    case bfd_arch_vax:
+      *unknown = false;
+      break;
+
+    case bfd_arch_cris:
+      if (machine == 0 || machine == 255)
+       arch_flags = M_CRIS;
+      break;
+
+    default:
+      arch_flags = M_UNKNOWN;
+    }
 
   if (arch_flags != M_UNKNOWN)
     *unknown = false;
@@ -729,7 +834,6 @@ NAME(aout,machine_type) (arch, machine, unknown)
   return arch_flags;
 }
 
-
 /*
 FUNCTION
        aout_@var{size}_set_arch_mach
@@ -764,19 +868,20 @@ NAME(aout,set_arch_mach) (abfd, arch, machine)
        return false;
     }
 
-  /* Determine the size of a relocation entry */
-  switch (arch) {
-  case bfd_arch_sparc:
-  case bfd_arch_a29k:
-  case bfd_arch_mips:
-    obj_reloc_entry_size (abfd) = RELOC_EXT_SIZE;
-    break;
-  default:
-    obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
-    break;
-  }
+  /* Determine the size of a relocation entry.  */
+  switch (arch)
+    {
+    case bfd_arch_sparc:
+    case bfd_arch_a29k:
+    case bfd_arch_mips:
+      obj_reloc_entry_size (abfd) = RELOC_EXT_SIZE;
+      break;
+    default:
+      obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
+      break;
+    }
 
-  return (*aout_backend_info(abfd)->set_sizes) (abfd);
+  return (*aout_backend_info (abfd)->set_sizes) (abfd);
 }
 
 static void
@@ -789,39 +894,46 @@ adjust_o_magic (abfd, execp)
   int pad = 0;
 
   /* Text.  */
-  obj_textsec(abfd)->filepos = pos;
-  pos += obj_textsec(abfd)->_raw_size;
-  vma += obj_textsec(abfd)->_raw_size;
+  obj_textsec (abfd)->filepos = pos;
+  if (!obj_textsec (abfd)->user_set_vma)
+    obj_textsec (abfd)->vma = vma;
+  else
+    vma = obj_textsec (abfd)->vma;
+
+  pos += obj_textsec (abfd)->_raw_size;
+  vma += obj_textsec (abfd)->_raw_size;
 
   /* Data.  */
-  if (!obj_datasec(abfd)->user_set_vma)
+  if (!obj_datasec (abfd)->user_set_vma)
     {
-#if 0      /* ?? Does alignment in the file image really matter? */
-      pad = align_power (vma, obj_datasec(abfd)->alignment_power) - vma;
+#if 0      /* ?? Does alignment in the file image really matter?  */
+      pad = align_power (vma, obj_datasec (abfd)->alignment_power) - vma;
 #endif
-      obj_textsec(abfd)->_raw_size += pad;
+      obj_textsec (abfd)->_raw_size += pad;
       pos += pad;
       vma += pad;
-      obj_datasec(abfd)->vma = vma;
+      obj_datasec (abfd)->vma = vma;
     }
-  obj_datasec(abfd)->filepos = pos;
-  pos += obj_datasec(abfd)->_raw_size;
-  vma += obj_datasec(abfd)->_raw_size;
+  else
+    vma = obj_datasec (abfd)->vma;
+  obj_datasec (abfd)->filepos = pos;
+  pos += obj_datasec (abfd)->_raw_size;
+  vma += obj_datasec (abfd)->_raw_size;
 
   /* BSS.  */
-  if (!obj_bsssec(abfd)->user_set_vma)
+  if (!obj_bsssec (abfd)->user_set_vma)
     {
 #if 0
-      pad = align_power (vma, obj_bsssec(abfd)->alignment_power) - vma;
+      pad = align_power (vma, obj_bsssec (abfd)->alignment_power) - vma;
 #endif
-      obj_datasec(abfd)->_raw_size += pad;
+      obj_datasec (abfd)->_raw_size += pad;
       pos += pad;
       vma += pad;
-      obj_bsssec(abfd)->vma = vma;
+      obj_bsssec (abfd)->vma = vma;
     }
   else
     {
-      /* The VMA of the .bss section is set by the the VMA of the
+      /* The VMA of the .bss section is set by the VMA of the
          .data section plus the size of the .data section.  We may
          need to add padding bytes to make this true.  */
       pad = obj_bsssec (abfd)->vma - vma;
@@ -831,12 +943,12 @@ adjust_o_magic (abfd, execp)
          pos += pad;
        }
     }
-  obj_bsssec(abfd)->filepos = pos;
+  obj_bsssec (abfd)->filepos = pos;
 
   /* Fix up the exec header.  */
-  execp->a_text = obj_textsec(abfd)->_raw_size;
-  execp->a_data = obj_datasec(abfd)->_raw_size;
-  execp->a_bss = obj_bsssec(abfd)->_raw_size;
+  execp->a_text = obj_textsec (abfd)->_raw_size;
+  execp->a_data = obj_datasec (abfd)->_raw_size;
+  execp->a_bss = obj_bsssec (abfd)->_raw_size;
   N_SET_MAGIC (*execp, OMAGIC);
 }
 
@@ -847,27 +959,27 @@ adjust_z_magic (abfd, execp)
 {
   bfd_size_type data_pad, text_pad;
   file_ptr text_end;
-  CONST struct aout_backend_data *abdp;
+  const struct aout_backend_data *abdp;
   int ztih;                    /* Nonzero if text includes exec header.  */
-  
+
   abdp = aout_backend_info (abfd);
 
   /* Text.  */
   ztih = (abdp != NULL
          && (abdp->text_includes_header
              || obj_aout_subformat (abfd) == q_magic_format));
-  obj_textsec(abfd)->filepos = (ztih
-                               ? adata(abfd).exec_bytes_size
-                               : adata(abfd).zmagic_disk_block_size);
-  if (! obj_textsec(abfd)->user_set_vma)
+  obj_textsec (abfd)->filepos = (ztih
+                                ? adata (abfd).exec_bytes_size
+                                : adata (abfd).zmagic_disk_block_size);
+  if (! obj_textsec (abfd)->user_set_vma)
     {
       /* ?? Do we really need to check for relocs here?  */
-      obj_textsec(abfd)->vma = ((abfd->flags & HAS_RELOC)
-                               ? 0
-                               : (ztih
-                                  ? (abdp->default_text_vma
-                                     + adata(abfd).exec_bytes_size)
-                                  : abdp->default_text_vma));
+      obj_textsec (abfd)->vma = ((abfd->flags & HAS_RELOC)
+                                ? 0
+                                : (ztih
+                                   ? (abdp->default_text_vma
+                                      + adata (abfd).exec_bytes_size)
+                                   : abdp->default_text_vma));
       text_pad = 0;
     }
   else
@@ -898,47 +1010,51 @@ adjust_z_magic (abfd, execp)
       text_pad += BFD_ALIGN (text_end, adata (abfd).page_size) - text_end;
       text_end += obj_textsec (abfd)->filepos;
     }
-  obj_textsec(abfd)->_raw_size += text_pad;
+  obj_textsec (abfd)->_raw_size += text_pad;
   text_end += text_pad;
 
   /* Data.  */
-  if (!obj_datasec(abfd)->user_set_vma)
+  if (!obj_datasec (abfd)->user_set_vma)
     {
       bfd_vma vma;
-      vma = obj_textsec(abfd)->vma + obj_textsec(abfd)->_raw_size;
-      obj_datasec(abfd)->vma = BFD_ALIGN (vma, adata(abfd).segment_size);
+      vma = obj_textsec (abfd)->vma + obj_textsec (abfd)->_raw_size;
+      obj_datasec (abfd)->vma = BFD_ALIGN (vma, adata (abfd).segment_size);
     }
   if (abdp && abdp->zmagic_mapped_contiguous)
     {
-      text_pad = (obj_datasec(abfd)->vma
-                 - obj_textsec(abfd)->vma
-                 - obj_textsec(abfd)->_raw_size);
-      obj_textsec(abfd)->_raw_size += text_pad;
+      asection * text = obj_textsec (abfd);
+      asection * data = obj_datasec (abfd);
+
+      text_pad = data->vma - (text->vma + text->_raw_size);
+      /* Only pad the text section if the data
+        section is going to be placed after it.  */
+      if (text_pad > 0)
+       text->_raw_size += text_pad;
     }
-  obj_datasec(abfd)->filepos = (obj_textsec(abfd)->filepos
-                               + obj_textsec(abfd)->_raw_size);
-  
+  obj_datasec (abfd)->filepos = (obj_textsec (abfd)->filepos
+                                + obj_textsec (abfd)->_raw_size);
+
   /* Fix up exec header while we're at it.  */
-  execp->a_text = obj_textsec(abfd)->_raw_size;
+  execp->a_text = obj_textsec (abfd)->_raw_size;
   if (ztih && (!abdp || (abdp && !abdp->exec_header_not_counted)))
-    execp->a_text += adata(abfd).exec_bytes_size;
+    execp->a_text += adata (abfd).exec_bytes_size;
   if (obj_aout_subformat (abfd) == q_magic_format)
     N_SET_MAGIC (*execp, QMAGIC);
   else
     N_SET_MAGIC (*execp, ZMAGIC);
 
   /* Spec says data section should be rounded up to page boundary.  */
-  obj_datasec(abfd)->_raw_size
-    = align_power (obj_datasec(abfd)->_raw_size,
-                  obj_bsssec(abfd)->alignment_power);
-  execp->a_data = BFD_ALIGN (obj_datasec(abfd)->_raw_size,
-                            adata(abfd).page_size);
-  data_pad = execp->a_data - obj_datasec(abfd)->_raw_size;
+  obj_datasec (abfd)->_raw_size
+    = align_power (obj_datasec (abfd)->_raw_size,
+                  obj_bsssec (abfd)->alignment_power);
+  execp->a_data = BFD_ALIGN (obj_datasec (abfd)->_raw_size,
+                            adata (abfd).page_size);
+  data_pad = execp->a_data - obj_datasec (abfd)->_raw_size;
 
   /* BSS.  */
-  if (!obj_bsssec(abfd)->user_set_vma)
-    obj_bsssec(abfd)->vma = (obj_datasec(abfd)->vma
-                            + obj_datasec(abfd)->_raw_size);
+  if (!obj_bsssec (abfd)->user_set_vma)
+    obj_bsssec (abfd)->vma = (obj_datasec (abfd)->vma
+                             + obj_datasec (abfd)->_raw_size);
   /* If the BSS immediately follows the data section and extra space
      in the page is left after the data section, fudge data
      in the header so that the bss section looks smaller by that
@@ -946,12 +1062,12 @@ adjust_z_magic (abfd, execp)
      (Note that a linker script, as well as the above assignment,
      could have explicitly set the BSS vma to immediately follow
      the data section.)  */
-  if (align_power (obj_bsssec(abfd)->vma, obj_bsssec(abfd)->alignment_power)
-      == obj_datasec(abfd)->vma + obj_datasec(abfd)->_raw_size)
-    execp->a_bss = (data_pad > obj_bsssec(abfd)->_raw_size) ? 0 :
-      obj_bsssec(abfd)->_raw_size - data_pad;
+  if (align_power (obj_bsssec (abfd)->vma, obj_bsssec (abfd)->alignment_power)
+      == obj_datasec (abfd)->vma + obj_datasec (abfd)->_raw_size)
+    execp->a_bss = (data_pad > obj_bsssec (abfd)->_raw_size
+                   ? 0 : obj_bsssec (abfd)->_raw_size - data_pad);
   else
-    execp->a_bss = obj_bsssec(abfd)->_raw_size;
+    execp->a_bss = obj_bsssec (abfd)->_raw_size;
 }
 
 static void
@@ -959,41 +1075,41 @@ adjust_n_magic (abfd, execp)
      bfd *abfd;
      struct internal_exec *execp;
 {
-  file_ptr pos = adata(abfd).exec_bytes_size;
+  file_ptr pos = adata (abfd).exec_bytes_size;
   bfd_vma vma = 0;
   int pad;
-  
+
   /* Text.  */
-  obj_textsec(abfd)->filepos = pos;
-  if (!obj_textsec(abfd)->user_set_vma)
-    obj_textsec(abfd)->vma = vma;
+  obj_textsec (abfd)->filepos = pos;
+  if (!obj_textsec (abfd)->user_set_vma)
+    obj_textsec (abfd)->vma = vma;
   else
-    vma = obj_textsec(abfd)->vma;
-  pos += obj_textsec(abfd)->_raw_size;
-  vma += obj_textsec(abfd)->_raw_size;
+    vma = obj_textsec (abfd)->vma;
+  pos += obj_textsec (abfd)->_raw_size;
+  vma += obj_textsec (abfd)->_raw_size;
 
   /* Data.  */
-  obj_datasec(abfd)->filepos = pos;
-  if (!obj_datasec(abfd)->user_set_vma)
-    obj_datasec(abfd)->vma = BFD_ALIGN (vma, adata(abfd).segment_size);
-  vma = obj_datasec(abfd)->vma;
-  
+  obj_datasec (abfd)->filepos = pos;
+  if (!obj_datasec (abfd)->user_set_vma)
+    obj_datasec (abfd)->vma = BFD_ALIGN (vma, adata (abfd).segment_size);
+  vma = obj_datasec (abfd)->vma;
+
   /* Since BSS follows data immediately, see if it needs alignment.  */
-  vma += obj_datasec(abfd)->_raw_size;
-  pad = align_power (vma, obj_bsssec(abfd)->alignment_power) - vma;
-  obj_datasec(abfd)->_raw_size += pad;
-  pos += obj_datasec(abfd)->_raw_size;
+  vma += obj_datasec (abfd)->_raw_size;
+  pad = align_power (vma, obj_bsssec (abfd)->alignment_power) - vma;
+  obj_datasec (abfd)->_raw_size += pad;
+  pos += obj_datasec (abfd)->_raw_size;
 
   /* BSS.  */
-  if (!obj_bsssec(abfd)->user_set_vma)
-    obj_bsssec(abfd)->vma = vma;
+  if (!obj_bsssec (abfd)->user_set_vma)
+    obj_bsssec (abfd)->vma = vma;
   else
-    vma = obj_bsssec(abfd)->vma;
+    vma = obj_bsssec (abfd)->vma;
 
   /* Fix up exec header.  */
-  execp->a_text = obj_textsec(abfd)->_raw_size;
-  execp->a_data = obj_datasec(abfd)->_raw_size;
-  execp->a_bss = obj_bsssec(abfd)->_raw_size;
+  execp->a_text = obj_textsec (abfd)->_raw_size;
+  execp->a_data = obj_datasec (abfd)->_raw_size;
+  execp->a_bss = obj_bsssec (abfd)->_raw_size;
   N_SET_MAGIC (*execp, NMAGIC);
 }
 
@@ -1001,28 +1117,28 @@ 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);
 
   if (! NAME(aout,make_sections) (abfd))
     return false;
 
-  if (adata(abfd).magic != undecided_magic)
+  if (adata (abfd).magic != undecided_magic)
     return true;
 
-  obj_textsec(abfd)->_raw_size =
-    align_power(obj_textsec(abfd)->_raw_size,
-               obj_textsec(abfd)->alignment_power);
+  obj_textsec (abfd)->_raw_size =
+    align_power (obj_textsec (abfd)->_raw_size,
+                obj_textsec (abfd)->alignment_power);
 
   *text_size = obj_textsec (abfd)->_raw_size;
   /* Rule (heuristic) for when to pad to a new page.  Note that there
      are (at least) two ways demand-paged (ZMAGIC) files have been
      handled.  Most Berkeley-based systems start the text segment at
-     (PAGE_SIZE).  However, newer versions of SUNOS start the text
+     (TARGET_PAGE_SIZE).  However, newer versions of SUNOS start the text
      segment right after the exec header; the latter is counted in the
      text segment size, and is paged in by the kernel with the rest of
-     the text. */
+     the text.  */
 
   /* This perhaps isn't the right way to do this, but made it simpler for me
      to understand enough to implement it.  Better would probably be to go
@@ -1034,34 +1150,35 @@ NAME(aout,adjust_sizes_and_vmas) (abfd, text_size, text_end)
 
   if (abfd->flags & D_PAGED)
     /* Whether or not WP_TEXT is set -- let D_PAGED override.  */
-    adata(abfd).magic = z_magic;
+    adata (abfd).magic = z_magic;
   else if (abfd->flags & WP_TEXT)
-    adata(abfd).magic = n_magic;
+    adata (abfd).magic = n_magic;
   else
-    adata(abfd).magic = o_magic;
+    adata (abfd).magic = o_magic;
 
 #ifdef BFD_AOUT_DEBUG /* requires gcc2 */
 #if __GNUC__ >= 2
   fprintf (stderr, "%s text=<%x,%x,%x> data=<%x,%x,%x> bss=<%x,%x,%x>\n",
           ({ char *str;
-             switch (adata(abfd).magic) {
-             case n_magic: str = "NMAGIC"; break;
-             case o_magic: str = "OMAGIC"; break;
-             case z_magic: str = "ZMAGIC"; break;
-             default: abort ();
-             }
+             switch (adata (abfd).magic)
+               {
+               case n_magic: str = "NMAGIC"; break;
+               case o_magic: str = "OMAGIC"; break;
+               case z_magic: str = "ZMAGIC"; break;
+               default: abort ();
+               }
              str;
            }),
-          obj_textsec(abfd)->vma, obj_textsec(abfd)->_raw_size,
-               obj_textsec(abfd)->alignment_power,
-          obj_datasec(abfd)->vma, obj_datasec(abfd)->_raw_size,
-               obj_datasec(abfd)->alignment_power,
-          obj_bsssec(abfd)->vma, obj_bsssec(abfd)->_raw_size,
-               obj_bsssec(abfd)->alignment_power);
+          obj_textsec (abfd)->vma, obj_textsec (abfd)->_raw_size,
+               obj_textsec (abfd)->alignment_power,
+          obj_datasec (abfd)->vma, obj_datasec (abfd)->_raw_size,
+               obj_datasec (abfd)->alignment_power,
+          obj_bsssec (abfd)->vma, obj_bsssec (abfd)->_raw_size,
+               obj_bsssec (abfd)->alignment_power);
 #endif
 #endif
 
-  switch (adata(abfd).magic)
+  switch (adata (abfd).magic)
     {
     case o_magic:
       adjust_o_magic (abfd, execp);
@@ -1078,11 +1195,11 @@ NAME(aout,adjust_sizes_and_vmas) (abfd, text_size, text_end)
 
 #ifdef BFD_AOUT_DEBUG
   fprintf (stderr, "       text=<%x,%x,%x> data=<%x,%x,%x> bss=<%x,%x>\n",
-          obj_textsec(abfd)->vma, obj_textsec(abfd)->_raw_size,
-               obj_textsec(abfd)->filepos,
-          obj_datasec(abfd)->vma, obj_datasec(abfd)->_raw_size,
-               obj_datasec(abfd)->filepos,
-          obj_bsssec(abfd)->vma, obj_bsssec(abfd)->_raw_size);
+          obj_textsec (abfd)->vma, obj_textsec (abfd)->_raw_size,
+               obj_textsec (abfd)->filepos,
+          obj_datasec (abfd)->vma, obj_datasec (abfd)->_raw_size,
+               obj_datasec (abfd)->filepos,
+          obj_bsssec (abfd)->vma, obj_bsssec (abfd)->_raw_size);
 #endif
 
   return true;
@@ -1106,33 +1223,34 @@ NAME(aout,new_section_hook) (abfd, newsect)
      bfd *abfd;
      asection *newsect;
 {
-  /* align to double at least */
-  newsect->alignment_power = bfd_get_arch_info(abfd)->section_align_power;
-
+  /* Align to double at least.  */
+  newsect->alignment_power = bfd_get_arch_info (abfd)->section_align_power;
 
   if (bfd_get_format (abfd) == bfd_object)
-  {
-    if (obj_textsec(abfd) == NULL && !strcmp(newsect->name, ".text")) {
-       obj_textsec(abfd)= newsect;
-       newsect->target_index = N_TEXT;
-       return true;
-      }
-
-    if (obj_datasec(abfd) == NULL && !strcmp(newsect->name, ".data")) {
-       obj_datasec(abfd) = newsect;
-       newsect->target_index = N_DATA;
-       return true;
-      }
+    {
+      if (obj_textsec (abfd) == NULL && !strcmp (newsect->name, ".text"))
+       {
+         obj_textsec (abfd)= newsect;
+         newsect->target_index = N_TEXT;
+         return true;
+       }
 
-    if (obj_bsssec(abfd) == NULL && !strcmp(newsect->name, ".bss")) {
-       obj_bsssec(abfd) = newsect;
-       newsect->target_index = N_BSS;
-       return true;
-      }
+      if (obj_datasec (abfd) == NULL && !strcmp (newsect->name, ".data"))
+       {
+         obj_datasec (abfd) = newsect;
+         newsect->target_index = N_DATA;
+         return true;
+       }
 
-  }
+      if (obj_bsssec (abfd) == NULL && !strcmp (newsect->name, ".bss"))
+       {
+         obj_bsssec (abfd) = newsect;
+         newsect->target_index = N_BSS;
+         return true;
+       }
+    }
 
-  /* We allow more than three sections internally */
+  /* We allow more than three sections internally */
   return true;
 }
 
@@ -1147,26 +1265,35 @@ NAME(aout,set_section_contents) (abfd, section, location, offset, count)
   file_ptr text_end;
   bfd_size_type text_size;
 
-  if (abfd->output_has_begun == false)
-      {
-       if (NAME(aout,adjust_sizes_and_vmas) (abfd,
-                                             &text_size,
-                                             &text_end) == false)
-         return false;
-      }
+  if (! abfd->output_has_begun)
+    {
+      if (! NAME(aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end))
+       return false;
+    }
 
-  /* regardless, once we know what we're doing, we might as well get going */
-  if (section != obj_bsssec(abfd))
-      {
-       if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0)
-         return false;
+  if (section == obj_bsssec (abfd))
+    {
+      bfd_set_error (bfd_error_no_contents);
+      return false;
+    }
+
+  if (section != obj_textsec (abfd)
+      && section != obj_datasec (abfd))
+    {
+      (*_bfd_error_handler)
+       (_("%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;
+    }
+
+  if (count != 0)
+    {
+      if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0
+         || bfd_bwrite (location, count, abfd) != count)
+       return false;
+    }
 
-       if (count) {
-         return (bfd_write ((PTR)location, 1, count, abfd) == count) ?
-           true : false;
-       }
-       return true;
-      }
   return true;
 }
 \f
@@ -1180,68 +1307,76 @@ aout_get_external_symbols (abfd)
     {
       bfd_size_type count;
       struct external_nlist *syms;
+      bfd_size_type amt;
 
       count = exec_hdr (abfd)->a_syms / EXTERNAL_NLIST_SIZE;
 
+#ifdef USE_MMAP
+      if (! bfd_get_file_window (abfd, obj_sym_filepos (abfd),
+                                exec_hdr (abfd)->a_syms,
+                                &obj_aout_sym_window (abfd), true))
+       return false;
+      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 (count * EXTERNAL_NLIST_SIZE));
       if (syms == (struct external_nlist *) NULL && count != 0)
-       {
-         bfd_set_error (bfd_error_no_memory);
-         return false;
-       }
+       return false;
 
+      amt = exec_hdr (abfd)->a_syms;
       if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0
-         || (bfd_read (syms, 1, exec_hdr (abfd)->a_syms, abfd)
-             != exec_hdr (abfd)->a_syms))
+         || bfd_bread (syms, amt, abfd) != amt)
        {
          free (syms);
          return false;
        }
+#endif
 
       obj_aout_external_syms (abfd) = syms;
       obj_aout_external_sym_count (abfd) = count;
     }
-      
+
   if (obj_aout_external_strings (abfd) == NULL
       && exec_hdr (abfd)->a_syms != 0)
     {
       unsigned char string_chars[BYTES_IN_WORD];
       bfd_size_type stringsize;
       char *strings;
+      bfd_size_type amt = BYTES_IN_WORD;
 
       /* Get the size of the strings.  */
       if (bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET) != 0
-         || (bfd_read ((PTR) string_chars, BYTES_IN_WORD, 1, abfd)
-             != BYTES_IN_WORD))
+         || bfd_bread ((PTR) string_chars, amt, abfd) != amt)
        return false;
       stringsize = GET_WORD (abfd, string_chars);
 
-      strings = (char *) malloc ((size_t) stringsize + 1);
+#ifdef USE_MMAP
+      if (! bfd_get_file_window (abfd, obj_str_filepos (abfd), stringsize,
+                                &obj_aout_string_window (abfd), true))
+       return false;
+      strings = (char *) obj_aout_string_window (abfd).data;
+#else
+      strings = (char *) bfd_malloc (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.  */
-      if (bfd_read (strings + BYTES_IN_WORD, 1, stringsize - BYTES_IN_WORD,
-                   abfd)
-         != stringsize - BYTES_IN_WORD)
+      amt = stringsize - BYTES_IN_WORD;
+      if (bfd_bread (strings + BYTES_IN_WORD, amt, abfd) != amt)
        {
          free (strings);
          return false;
        }
+#endif
 
       /* Ensure that a zero index yields an empty string.  */
       strings[0] = '\0';
 
-      /* Sanity preservation.  */
-      strings[stringsize] = '\0';
+      strings[stringsize - 1] = 0;
 
       obj_aout_external_strings (abfd) = strings;
       obj_aout_external_string_size (abfd) = stringsize;
@@ -1268,7 +1403,6 @@ translate_from_native_sym_flags (abfd, cache_ptr)
       asection *sec;
 
       /* This is a debugging symbol.  */
-
       cache_ptr->symbol.flags = BSF_DEBUGGING;
 
       /* Work out the symbol section.  */
@@ -1355,9 +1489,14 @@ 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;
+       bfd_size_type amt;
 
        /* This is a set symbol.  The name of the symbol is the name
           of the set (e.g., __CTOR_LIST__).  The value of the symbol
@@ -1374,12 +1513,10 @@ translate_from_native_sym_flags (abfd, cache_ptr)
          {
            char *copy;
 
-           copy = bfd_alloc (abfd, strlen (cache_ptr->symbol.name) + 1);
+           amt = strlen (cache_ptr->symbol.name) + 1;
+           copy = bfd_alloc (abfd, amt);
            if (copy == NULL)
-             {
-               bfd_set_error (bfd_error_no_memory);
-               return false;
-             }
+             return false;
 
            strcpy (copy, cache_ptr->symbol.name);
            section = bfd_make_section (abfd, copy);
@@ -1387,12 +1524,10 @@ translate_from_native_sym_flags (abfd, cache_ptr)
              return false;
          }
 
-       reloc = (arelent_chain *) bfd_alloc (abfd, sizeof (arelent_chain));
+       amt = sizeof (arelent_chain);
+       reloc = (arelent_chain *) bfd_alloc (abfd, amt);
        if (reloc == NULL)
-         {
-           bfd_set_error (bfd_error_no_memory);
-           return false;
-         }
+         return false;
 
        /* Build a relocation entry for the constructor.  */
        switch (cache_ptr->type & N_TYPE)
@@ -1435,7 +1570,25 @@ translate_from_native_sym_flags (abfd, cache_ptr)
        reloc->relent.address = section->_raw_size;
        section->_raw_size += BYTES_IN_WORD;
 
-       reloc->relent.howto = CTOR_TABLE_RELOC_HOWTO(abfd);
+       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;
       }
@@ -1446,16 +1599,7 @@ translate_from_native_sym_flags (abfd, cache_ptr)
         symbol is the symbol to associate the warning with.  If a
         reference is made to that symbol, a warning is issued.  */
       cache_ptr->symbol.flags = BSF_DEBUGGING | BSF_WARNING;
-
-      /* @@ Stuffing pointers into integers is a no-no.  We can
-        usually get away with it if the integer is large enough
-        though.  */
-      if (sizeof (cache_ptr + 1) > sizeof (bfd_vma))
-       abort ();
-      cache_ptr->symbol.value = (bfd_vma) (cache_ptr + 1);
-
       cache_ptr->symbol.section = bfd_abs_section_ptr;
-
       break;
 
     case N_INDR: case N_INDR | N_EXT:
@@ -1464,16 +1608,7 @@ translate_from_native_sym_flags (abfd, cache_ptr)
         symbol is the name of the target.  A reference to the first
         symbol becomes a reference to the second.  */
       cache_ptr->symbol.flags = BSF_DEBUGGING | BSF_INDIRECT | visible;
-
-      /* @@ Stuffing pointers into integers is a no-no.  We can
-        usually get away with it if the integer is large enough
-        though.  */
-      if (sizeof (cache_ptr + 1) > sizeof (bfd_vma))
-       abort ();
-      cache_ptr->symbol.value = (bfd_vma) (cache_ptr + 1);
-
       cache_ptr->symbol.section = bfd_ind_section_ptr;
-
       break;
 
     case N_WEAKU:
@@ -1517,50 +1652,59 @@ translate_to_native_sym_flags (abfd, cache_ptr, sym_pointer)
      struct external_nlist *sym_pointer;
 {
   bfd_vma value = cache_ptr->value;
+  asection *sec;
+  bfd_vma off;
 
   /* Mask out any existing type bits in case copying from one section
      to another.  */
   sym_pointer->e_type[0] &= ~N_TYPE;
 
-  if (bfd_is_abs_section (bfd_get_section (cache_ptr)))
-    sym_pointer->e_type[0] |= N_ABS;
-  else if (bfd_get_section (cache_ptr) == obj_textsec (abfd)
-          || (bfd_get_section (cache_ptr)->output_section
-              == obj_textsec (abfd)))
-    sym_pointer->e_type[0] |= N_TEXT;
-  else if (bfd_get_section (cache_ptr) == obj_datasec (abfd)
-          || (bfd_get_section (cache_ptr)->output_section
-              == obj_datasec (abfd)))
-    sym_pointer->e_type[0] |= N_DATA;
-  else if (bfd_get_section (cache_ptr) == obj_bsssec (abfd)
-          || (bfd_get_section (cache_ptr)->output_section
-              == obj_bsssec (abfd)))
-    sym_pointer->e_type[0] |= N_BSS;
-  else if (bfd_get_section (cache_ptr) == NULL)
+  sec = bfd_get_section (cache_ptr);
+  off = 0;
+
+  if (sec == NULL)
     {
-      /* Protect the bfd_is_com_section call.  This case occurs, e.g.,
-        for the *DEBUG* section of a COFF file.  */
+      /* This case occurs, e.g., for the *DEBUG* section of a COFF
+        file.  */
+      (*_bfd_error_handler)
+       (_("%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;
     }
-  else if (bfd_is_und_section (bfd_get_section (cache_ptr)))
+
+  if (sec->output_section != NULL)
+    {
+      off = sec->output_offset;
+      sec = sec->output_section;
+    }
+
+  if (bfd_is_abs_section (sec))
+    sym_pointer->e_type[0] |= N_ABS;
+  else if (sec == obj_textsec (abfd))
+    sym_pointer->e_type[0] |= N_TEXT;
+  else if (sec == obj_datasec (abfd))
+    sym_pointer->e_type[0] |= N_DATA;
+  else if (sec == obj_bsssec (abfd))
+    sym_pointer->e_type[0] |= N_BSS;
+  else if (bfd_is_und_section (sec))
     sym_pointer->e_type[0] = N_UNDF | N_EXT;
-  else if (bfd_is_ind_section (bfd_get_section (cache_ptr)))
+  else if (bfd_is_ind_section (sec))
     sym_pointer->e_type[0] = N_INDR;
-  else if (bfd_is_com_section (bfd_get_section (cache_ptr)))
+  else if (bfd_is_com_section (sec))
     sym_pointer->e_type[0] = N_UNDF | N_EXT;
   else
     {
+      (*_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));
       bfd_set_error (bfd_error_nonrepresentable_section);
       return false;
     }
 
-  /* Turn the symbol from section relative to absolute again */
-  if (cache_ptr->section->output_section != NULL)
-    value += (cache_ptr->section->output_section->vma
-             + cache_ptr->section->output_offset);
-  else
-    value += cache_ptr->section->vma;
+  /* Turn the symbol from section relative to absolute again.  */
+  value += sec->vma + off;
 
   if ((cache_ptr->flags & BSF_WARNING) != 0)
     sym_pointer->e_type[0] = N_WARNING;
@@ -1569,10 +1713,13 @@ translate_to_native_sym_flags (abfd, cache_ptr, sym_pointer)
     sym_pointer->e_type[0] = ((aout_symbol_type *) cache_ptr)->type;
   else if ((cache_ptr->flags & BSF_GLOBAL) != 0)
     sym_pointer->e_type[0] |= N_EXT;
+  else if ((cache_ptr->flags & BSF_LOCAL) != 0)
+    sym_pointer->e_type[0] &= ~N_EXT;
 
   if ((cache_ptr->flags & BSF_CONSTRUCTOR) != 0)
     {
       int type = ((aout_symbol_type *) cache_ptr)->type;
+
       switch (type)
        {
        case N_ABS:     type = N_SETA; break;
@@ -1599,24 +1746,21 @@ translate_to_native_sym_flags (abfd, cache_ptr, sym_pointer)
       sym_pointer->e_type[0] = type;
     }
 
-  PUT_WORD(abfd, value, sym_pointer->e_value);
+  PUT_WORD (abfd, value, sym_pointer->e_value);
 
   return true;
 }
 \f
-/* Native-level interface to symbols. */
+/* Native-level interface to symbols.  */
 
 asymbol *
 NAME(aout,make_empty_symbol) (abfd)
      bfd *abfd;
 {
-  aout_symbol_type  *new =
-    (aout_symbol_type *)bfd_zalloc (abfd, sizeof (aout_symbol_type));
+  bfd_size_type amt = sizeof (aout_symbol_type);
+  aout_symbol_type *new = (aout_symbol_type *) bfd_zalloc (abfd, amt);
   if (!new)
-    {
-      bfd_set_error (bfd_error_no_memory);
-      return NULL;
-    }
+    return NULL;
   new->symbol.the_bfd = abfd;
 
   return &new->symbol;
@@ -1657,10 +1801,10 @@ NAME(aout,translate_symbol_table) (abfd, in, ext, count, str, strsize, dynamic)
        return false;
 
       in->symbol.value = GET_SWORD (abfd,  ext->e_value);
-      in->desc = bfd_h_get_16 (abfd, ext->e_desc);
-      in->other = bfd_h_get_8 (abfd, ext->e_other);
-      in->type = bfd_h_get_8 (abfd,  ext->e_type);
-      in->symbol.udata = 0;
+      in->desc = H_GET_16 (abfd, ext->e_desc);
+      in->other = H_GET_8 (abfd, ext->e_other);
+      in->type = H_GET_8 (abfd,  ext->e_type);
+      in->symbol.udata.p = NULL;
 
       if (! translate_from_native_sym_flags (abfd, in))
        return false;
@@ -1674,7 +1818,7 @@ NAME(aout,translate_symbol_table) (abfd, in, ext, count, str, strsize, dynamic)
 
 /* We read the symbols into a buffer, which is discarded when this
    function exits.  We read the strings into a buffer large enough to
-   hold them all plus all the cached symbol entries. */
+   hold them all plus all the cached symbol entries.  */
 
 boolean
 NAME(aout,slurp_symbol_table) (abfd)
@@ -1682,9 +1826,9 @@ NAME(aout,slurp_symbol_table) (abfd)
 {
   struct external_nlist *old_external_syms;
   aout_symbol_type *cached;
-  size_t cached_size;
+  bfd_size_type cached_size;
 
-  /* If there's no work to be done, don't do any */
+  /* If there's no work to be done, don't do any */
   if (obj_aout_symbols (abfd) != (aout_symbol_type *) NULL)
     return true;
 
@@ -1693,21 +1837,11 @@ NAME(aout,slurp_symbol_table) (abfd)
   if (! aout_get_external_symbols (abfd))
     return false;
 
-  if (obj_aout_external_sym_count (abfd) == 0)
-    {
-      bfd_set_error (bfd_error_no_symbols);
-      return false;
-    }
-
-  cached_size = (obj_aout_external_sym_count (abfd)
-                * sizeof (aout_symbol_type));
-  cached = (aout_symbol_type *) malloc (cached_size);
-  if (cached == NULL)
-    {
-      bfd_set_error (bfd_error_no_memory);
-      return false;
-    }
-  memset (cached, 0, cached_size);
+  cached_size = obj_aout_external_sym_count (abfd);
+  cached_size *= sizeof (aout_symbol_type);
+  cached = (aout_symbol_type *) bfd_zmalloc (cached_size);
+  if (cached == NULL && cached_size != 0)
+    return false;
 
   /* Convert from external symbol information to internal.  */
   if (! (NAME(aout,translate_symbol_table)
@@ -1733,7 +1867,11 @@ NAME(aout,slurp_symbol_table) (abfd)
   if (old_external_syms == (struct external_nlist *) NULL
       && obj_aout_external_syms (abfd) != (struct external_nlist *) NULL)
     {
+#ifdef USE_MMAP
+      bfd_free_window (&obj_aout_sym_window (abfd));
+#else
       free (obj_aout_external_syms (abfd));
+#endif
       obj_aout_external_syms (abfd) = NULL;
     }
 
@@ -1764,9 +1902,10 @@ add_to_stringtab (abfd, tab, str, copy)
      boolean copy;
 {
   boolean hash;
+  bfd_size_type index;
 
   /* An index of 0 always means the empty string.  */
-  if (*str == '\0')
+  if (str == 0 || *str == '\0')
     return 0;
 
   /* Don't hash if BFD_TRADITIONAL_FORMAT is set, because SunOS dbx
@@ -1775,9 +1914,16 @@ add_to_stringtab (abfd, tab, str, copy)
   if ((abfd->flags & BFD_TRADITIONAL_FORMAT) != 0)
     hash = false;
 
-  /* Add BYTES_IN_WORD to the return value to account for the space
-     taken up by the count.  */
-  return BYTES_IN_WORD + _bfd_stringtab_add (tab, str, hash, copy);
+  index = _bfd_stringtab_add (tab, str, hash, copy);
+
+  if (index != (bfd_size_type) -1)
+    {
+      /* Add BYTES_IN_WORD to the return value to account for the
+        space taken up by the string table size.  */
+      index += BYTES_IN_WORD;
+    }
+
+  return index;
 }
 
 /* Write out a strtab.  ABFD is already at the right location in the
@@ -1789,10 +1935,11 @@ emit_stringtab (abfd, tab)
      struct bfd_strtab_hash *tab;
 {
   bfd_byte buffer[BYTES_IN_WORD];
+  bfd_size_type amt = BYTES_IN_WORD;
 
   /* The string table starts with the size.  */
   PUT_WORD (abfd, _bfd_stringtab_size (tab) + BYTES_IN_WORD, buffer);
-  if (bfd_write ((PTR) buffer, 1, BYTES_IN_WORD, abfd) != BYTES_IN_WORD)
+  if (bfd_bwrite ((PTR) buffer, amt, abfd) != amt)
     return false;
 
   return _bfd_stringtab_emit (abfd, tab);
@@ -1815,33 +1962,34 @@ NAME(aout,write_syms) (abfd)
       asymbol *g = generic[count];
       bfd_size_type indx;
       struct external_nlist nsp;
+      bfd_size_type amt;
 
       indx = add_to_stringtab (abfd, strtab, g->name, false);
       if (indx == (bfd_size_type) -1)
        goto error_return;
       PUT_WORD (abfd, indx, (bfd_byte *) nsp.e_strx);
 
-      if (bfd_asymbol_flavour(g) == abfd->xvec->flavour)
+      if (bfd_asymbol_flavour (g) == abfd->xvec->flavour)
        {
-         bfd_h_put_16(abfd, aout_symbol(g)->desc,  nsp.e_desc);
-         bfd_h_put_8(abfd, aout_symbol(g)->other,  nsp.e_other);
-         bfd_h_put_8(abfd, aout_symbol(g)->type,  nsp.e_type);
+         H_PUT_16 (abfd, aout_symbol (g)->desc,  nsp.e_desc);
+         H_PUT_8  (abfd, aout_symbol (g)->other, nsp.e_other);
+         H_PUT_8  (abfd, aout_symbol (g)->type,  nsp.e_type);
        }
       else
        {
-         bfd_h_put_16(abfd,0, nsp.e_desc);
-         bfd_h_put_8(abfd, 0, nsp.e_other);
-         bfd_h_put_8(abfd, 0, nsp.e_type);
+         H_PUT_16 (abfd, 0, nsp.e_desc);
+         H_PUT_8  (abfd, 0, nsp.e_other);
+         H_PUT_8  (abfd, 0, nsp.e_type);
        }
 
       if (! translate_to_native_sym_flags (abfd, g, &nsp))
        goto error_return;
 
-      if (bfd_write((PTR)&nsp,1,EXTERNAL_NLIST_SIZE, abfd)
-         != EXTERNAL_NLIST_SIZE)
+      amt = EXTERNAL_NLIST_SIZE;
+      if (bfd_bwrite ((PTR) &nsp, amt, abfd) != amt)
        goto error_return;
 
-      /* NB: `KEEPIT' currently overlays `flags', so set this only
+      /* NB: `KEEPIT' currently overlays `udata.p', so set this only
         here, at the end.  */
       g->KEEPIT = count;
     }
@@ -1857,7 +2005,6 @@ error_return:
   _bfd_stringtab_free (strtab);
   return false;
 }
-
 \f
 long
 NAME(aout,get_symtab) (abfd, location)
@@ -1867,18 +2014,22 @@ NAME(aout,get_symtab) (abfd, location)
     unsigned int counter = 0;
     aout_symbol_type *symbase;
 
-    if (!NAME(aout,slurp_symbol_table)(abfd))
+    if (!NAME(aout,slurp_symbol_table) (abfd))
       return -1;
 
-    for (symbase = obj_aout_symbols(abfd); counter++ < bfd_get_symcount (abfd);)
-      *(location++) = (asymbol *)( symbase++);
+    for (symbase = obj_aout_symbols (abfd);
+        counter++ < bfd_get_symcount (abfd);
+        )
+      *(location++) = (asymbol *) (symbase++);
     *location++ =0;
     return bfd_get_symcount (abfd);
 }
-
 \f
-/* Standard reloc stuff */
-/* Output standard relocation information to a file in target byte order. */
+/* 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)
@@ -1894,10 +2045,10 @@ NAME(aout,swap_std_reloc_out) (abfd, g, natptr)
   int r_baserel, r_jmptable, r_relative;
   asection *output_section = sym->section->output_section;
 
-  PUT_WORD(abfd, g->address, natptr->r_address);
+  PUT_WORD (abfd, g->address, natptr->r_address);
 
-  r_length = g->howto->size ;  /* Size as a power of two */
-  r_pcrel  = (int) g->howto->pc_relative; /* Relative to PC? */
+  r_length = g->howto->size ;  /* Size as a power of two */
+  r_pcrel  = (int) g->howto->pc_relative; /* Relative to PC?  */
   /* XXX This relies on relocs coming from a.out files.  */
   r_baserel = (g->howto->type & 8) != 0;
   r_jmptable = (g->howto->type & 16) != 0;
@@ -1908,72 +2059,72 @@ NAME(aout,swap_std_reloc_out) (abfd, g, natptr)
   r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
 #endif
 
-  /* name was clobbered by aout_write_syms to be symbol index */
+  /* Name was clobbered by aout_write_syms to be symbol index.  */
 
   /* If this relocation is relative to a symbol then set the
      r_index to the symbols index, and the r_extern bit.
 
      Absolute symbols can come in in two ways, either as an offset
      from the abs section, or as a symbol which has an abs value.
-     check for that here
-     */
-
+     check for that here.  */
 
   if (bfd_is_com_section (output_section)
       || bfd_is_abs_section (output_section)
       || bfd_is_und_section (output_section))
     {
       if (bfd_abs_section_ptr->symbol == sym)
-      {
-       /* Whoops, looked like an abs symbol, but is really an offset
-          from the abs section */
-       r_index = 0;
-       r_extern = 0;
-       }
+       {
+         /* Whoops, looked like an abs symbol, but is
+            really an offset from the abs section.  */
+         r_index = N_ABS;
+         r_extern = 0;
+       }
       else
-      {
-       /* Fill in symbol */
-       r_extern = 1;
-       r_index =  stoi((*(g->sym_ptr_ptr))->KEEPIT);
-
-      }
+       {
+         /* Fill in symbol.  */
+         r_extern = 1;
+         r_index = (*(g->sym_ptr_ptr))->KEEPIT;
+       }
     }
   else
     {
-      /* Just an ordinary section */
+      /* Just an ordinary section */
       r_extern = 0;
       r_index  = output_section->target_index;
     }
 
-  /* now the fun stuff */
-  if (abfd->xvec->header_byteorder_big_p != false) {
+  /* Now the fun stuff.  */
+  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;
-      natptr->r_type[0] =
-       (r_extern?    RELOC_STD_BITS_EXTERN_BIG: 0)
-       | (r_pcrel?     RELOC_STD_BITS_PCREL_BIG: 0)
-        | (r_baserel?   RELOC_STD_BITS_BASEREL_BIG: 0)
-         | (r_jmptable?  RELOC_STD_BITS_JMPTABLE_BIG: 0)
-          | (r_relative?  RELOC_STD_BITS_RELATIVE_BIG: 0)
-           | (r_length <<  RELOC_STD_BITS_LENGTH_SH_BIG);
-    } else {
-       natptr->r_index[2] = r_index >> 16;
-       natptr->r_index[1] = r_index >> 8;
-       natptr->r_index[0] = r_index;
-       natptr->r_type[0] =
-        (r_extern?    RELOC_STD_BITS_EXTERN_LITTLE: 0)
-         | (r_pcrel?     RELOC_STD_BITS_PCREL_LITTLE: 0)
-          | (r_baserel?   RELOC_STD_BITS_BASEREL_LITTLE: 0)
-           | (r_jmptable?  RELOC_STD_BITS_JMPTABLE_LITTLE: 0)
-            | (r_relative?  RELOC_STD_BITS_RELATIVE_LITTLE: 0)
-             | (r_length <<  RELOC_STD_BITS_LENGTH_SH_LITTLE);
-      }
+      natptr->r_type[0] = ((r_extern ? RELOC_STD_BITS_EXTERN_BIG : 0)
+                          | (r_pcrel ? RELOC_STD_BITS_PCREL_BIG : 0)
+                          | (r_baserel ? RELOC_STD_BITS_BASEREL_BIG : 0)
+                          | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_BIG : 0)
+                          | (r_relative ? RELOC_STD_BITS_RELATIVE_BIG : 0)
+                          | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG));
+    }
+  else
+    {
+      natptr->r_index[2] = r_index >> 16;
+      natptr->r_index[1] = r_index >> 8;
+      natptr->r_index[0] = r_index;
+      natptr->r_type[0] = ((r_extern ? RELOC_STD_BITS_EXTERN_LITTLE : 0)
+                          | (r_pcrel ? RELOC_STD_BITS_PCREL_LITTLE : 0)
+                          | (r_baserel ? RELOC_STD_BITS_BASEREL_LITTLE : 0)
+                          | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_LITTLE : 0)
+                          | (r_relative ? RELOC_STD_BITS_RELATIVE_LITTLE : 0)
+                          | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE));
+    }
 }
 
+/* Extended stuff.  */
+/* Output extended relocation information to a file in target byte order.  */
 
-/* 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)
@@ -1984,7 +2135,7 @@ NAME(aout,swap_ext_reloc_out) (abfd, g, natptr)
   int r_index;
   int r_extern;
   unsigned int r_type;
-  unsigned int r_addend;
+  bfd_vma r_addend;
   asymbol *sym = *(g->sym_ptr_ptr);
   asection *output_section = sym->section->output_section;
 
@@ -1992,7 +2143,9 @@ NAME(aout,swap_ext_reloc_out) (abfd, g, natptr)
 
   r_type = (unsigned int) g->howto->type;
 
-  r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
+  r_addend = g->addend;
+  if ((sym->flags & BSF_SECTION_SYM) != 0)
+    r_addend += (*(g->sym_ptr_ptr))->section->output_section->vma;
 
   /* If this relocation is relative to a symbol then set the
      r_index to the symbols index, and the r_extern bit.
@@ -2000,47 +2153,44 @@ NAME(aout,swap_ext_reloc_out) (abfd, g, natptr)
      Absolute symbols can come in in two ways, either as an offset
      from the abs section, or as a symbol which has an abs value.
      check for that here.  */
-
-  if (bfd_is_com_section (output_section)
-      || bfd_is_abs_section (output_section)
-      || bfd_is_und_section (output_section))
-  {
-    if (bfd_abs_section_ptr->symbol == sym)
+  if (bfd_is_abs_section (bfd_get_section (sym)))
     {
-      /* Whoops, looked like an abs symbol, but is really an offset
-        from the abs section */
-      r_index = 0;
       r_extern = 0;
-     }
-    else
+      r_index = N_ABS;
+    }
+  else if ((sym->flags & BSF_SECTION_SYM) == 0)
     {
-      r_extern = 1;
-      r_index =  stoi((*(g->sym_ptr_ptr))->KEEPIT);
+      if (bfd_is_und_section (bfd_get_section (sym))
+         || (sym->flags & BSF_GLOBAL) != 0)
+       r_extern = 1;
+      else
+       r_extern = 0;
+      r_index = (*(g->sym_ptr_ptr))->KEEPIT;
     }
-  }
   else
-  {
-    /* Just an ordinary section */
-    r_extern = 0;
-    r_index  = output_section->target_index;
-  }
+    {
+      /* Just an ordinary section.  */
+      r_extern = 0;
+      r_index = output_section->target_index;
+    }
 
-  /* now the fun stuff */
-  if (abfd->xvec->header_byteorder_big_p != false) {
-    natptr->r_index[0] = r_index >> 16;
-    natptr->r_index[1] = r_index >> 8;
-    natptr->r_index[2] = r_index;
-    natptr->r_type[0] =
-      ((r_extern? RELOC_EXT_BITS_EXTERN_BIG: 0)
-       | (r_type << RELOC_EXT_BITS_TYPE_SH_BIG));
-  } else {
-    natptr->r_index[2] = r_index >> 16;
-    natptr->r_index[1] = r_index >> 8;
-    natptr->r_index[0] = r_index;
-    natptr->r_type[0] =
-     (r_extern? RELOC_EXT_BITS_EXTERN_LITTLE: 0)
-      | (r_type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
-  }
+  /* Now the fun stuff.  */
+  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;
+      natptr->r_type[0] = ((r_extern ? RELOC_EXT_BITS_EXTERN_BIG : 0)
+                          | (r_type << RELOC_EXT_BITS_TYPE_SH_BIG));
+    }
+  else
+    {
+      natptr->r_index[2] = r_index >> 16;
+      natptr->r_index[1] = r_index >> 8;
+      natptr->r_index[0] = r_index;
+      natptr->r_type[0] = ((r_extern ? RELOC_EXT_BITS_EXTERN_LITTLE : 0)
+                          | (r_type << RELOC_EXT_BITS_TYPE_SH_LITTLE));
+    }
 
   PUT_WORD (abfd, r_addend, natptr->r_addend);
 }
@@ -2051,126 +2201,168 @@ NAME(aout,swap_ext_reloc_out) (abfd, g, natptr)
 
    Aout keeps all it's symbols based from zero, so the symbol would
    contain 60. This macro subs the base of each section from the value
-   to give the true offset from the section */
-
-
-#define MOVE_ADDRESS(ad)                                                       \
-  if (r_extern) {                                                      \
-   /* undefined symbol */                                              \
-     cache_ptr->sym_ptr_ptr = symbols + r_index;                       \
-     cache_ptr->addend = ad;                                           \
-     } else {                                                          \
-    /* defined, section relative. replace symbol with pointer to       \
-       symbol which points to section  */                              \
-    switch (r_index) {                                                 \
-    case N_TEXT:                                                       \
-    case N_TEXT | N_EXT:                                               \
-      cache_ptr->sym_ptr_ptr  = obj_textsec(abfd)->symbol_ptr_ptr;     \
-      cache_ptr->addend = ad  - su->textsec->vma;                      \
-      break;                                                           \
-    case N_DATA:                                                       \
-    case N_DATA | N_EXT:                                               \
-      cache_ptr->sym_ptr_ptr  = obj_datasec(abfd)->symbol_ptr_ptr;     \
-      cache_ptr->addend = ad - su->datasec->vma;                       \
-      break;                                                           \
-    case N_BSS:                                                                \
-    case N_BSS | N_EXT:                                                        \
-      cache_ptr->sym_ptr_ptr  = obj_bsssec(abfd)->symbol_ptr_ptr;      \
-      cache_ptr->addend = ad - su->bsssec->vma;                                \
-      break;                                                           \
-    default:                                                           \
-    case N_ABS:                                                                \
-    case N_ABS | N_EXT:                                                        \
-     cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;     \
+   to give the true offset from the section.  */
+
+#define MOVE_ADDRESS(ad)                                               \
+  if (r_extern)                                                                \
+    {                                                                  \
+      /* Undefined symbol.  */                                         \
+      cache_ptr->sym_ptr_ptr = symbols + r_index;                      \
       cache_ptr->addend = ad;                                          \
-      break;                                                           \
     }                                                                  \
-  }                                                                    \
+   else                                                                        \
+    {                                                                  \
+      /* Defined, section relative.  Replace symbol with pointer to    \
+        symbol which points to section.  */                            \
+      switch (r_index)                                                 \
+       {                                                               \
+       case N_TEXT:                                                    \
+       case N_TEXT | N_EXT:                                            \
+         cache_ptr->sym_ptr_ptr = obj_textsec (abfd)->symbol_ptr_ptr;  \
+         cache_ptr->addend = ad - su->textsec->vma;                    \
+         break;                                                        \
+       case N_DATA:                                                    \
+       case N_DATA | N_EXT:                                            \
+         cache_ptr->sym_ptr_ptr = obj_datasec (abfd)->symbol_ptr_ptr;  \
+         cache_ptr->addend = ad - su->datasec->vma;                    \
+         break;                                                        \
+       case N_BSS:                                                     \
+       case N_BSS | N_EXT:                                             \
+         cache_ptr->sym_ptr_ptr = obj_bsssec (abfd)->symbol_ptr_ptr;   \
+         cache_ptr->addend = ad - su->bsssec->vma;                     \
+         break;                                                        \
+       default:                                                        \
+       case N_ABS:                                                     \
+       case N_ABS | N_EXT:                                             \
+         cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; \
+         cache_ptr->addend = ad;                                       \
+         break;                                                        \
+       }                                                               \
+    }
 
 void
-NAME(aout,swap_ext_reloc_in) (abfd, bytes, cache_ptr, symbols)
+NAME(aout,swap_ext_reloc_in) (abfd, bytes, cache_ptr, symbols, symcount)
      bfd *abfd;
      struct reloc_ext_external *bytes;
      arelent *cache_ptr;
      asymbol **symbols;
+     bfd_size_type symcount;
 {
-  int r_index;
+  unsigned int r_index;
   int r_extern;
   unsigned int r_type;
   struct aoutdata *su = &(abfd->tdata.aout_data->a);
 
   cache_ptr->address = (GET_SWORD (abfd, bytes->r_address));
 
-  /* now the fun stuff */
-  if (abfd->xvec->header_byteorder_big_p != false) {
-    r_index =  (bytes->r_index[0] << 16)
-            | (bytes->r_index[1] << 8)
-            |  bytes->r_index[2];
-    r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_BIG));
-    r_type   =       (bytes->r_type[0] & RELOC_EXT_BITS_TYPE_BIG)
-                                     >> RELOC_EXT_BITS_TYPE_SH_BIG;
-  } else {
-    r_index =  (bytes->r_index[2] << 16)
-            | (bytes->r_index[1] << 8)
-            |  bytes->r_index[0];
-    r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_LITTLE));
-    r_type   =       (bytes->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE)
-                                     >> RELOC_EXT_BITS_TYPE_SH_LITTLE;
-  }
+  /* Now the fun stuff.  */
+  if (bfd_header_big_endian (abfd))
+    {
+      r_index = ((bytes->r_index[0] << 16)
+                | (bytes->r_index[1] << 8)
+                | bytes->r_index[2]);
+      r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_BIG));
+      r_type = ((bytes->r_type[0] & RELOC_EXT_BITS_TYPE_BIG)
+               >> RELOC_EXT_BITS_TYPE_SH_BIG);
+    }
+  else
+    {
+      r_index =  ((bytes->r_index[2] << 16)
+                 | (bytes->r_index[1] << 8)
+                 | bytes->r_index[0]);
+      r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_LITTLE));
+      r_type = ((bytes->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE)
+               >> RELOC_EXT_BITS_TYPE_SH_LITTLE);
+    }
 
   cache_ptr->howto =  howto_table_ext + r_type;
-  MOVE_ADDRESS(GET_SWORD(abfd, bytes->r_addend));
+
+  /* Base relative relocs are always against the symbol table,
+     regardless of the setting of r_extern.  r_extern just reflects
+     whether the symbol the reloc is against is local or global.  */
+  if (r_type == RELOC_BASE10
+      || r_type == RELOC_BASE13
+      || r_type == RELOC_BASE22)
+    r_extern = 1;
+
+  if (r_extern && r_index > symcount)
+    {
+      /* We could arrange to return an error, but it might be useful
+         to see the file even if it is bad.  */
+      r_extern = 0;
+      r_index = N_ABS;
+    }
+
+  MOVE_ADDRESS (GET_SWORD (abfd, bytes->r_addend));
 }
 
 void
-NAME(aout,swap_std_reloc_in) (abfd, bytes, cache_ptr, symbols)
+NAME(aout,swap_std_reloc_in) (abfd, bytes, cache_ptr, symbols, symcount)
      bfd *abfd;
      struct reloc_std_external *bytes;
      arelent *cache_ptr;
      asymbol **symbols;
+     bfd_size_type symcount;
 {
-  int r_index;
+  unsigned int r_index;
   int r_extern;
   unsigned int r_length;
   int r_pcrel;
   int r_baserel, r_jmptable, r_relative;
   struct aoutdata  *su = &(abfd->tdata.aout_data->a);
-  int howto_idx;
-
-  cache_ptr->address = bfd_h_get_32 (abfd, bytes->r_address);
-
-  /* now the fun stuff */
-  if (abfd->xvec->header_byteorder_big_p != false) {
-    r_index =  (bytes->r_index[0] << 16)
-      | (bytes->r_index[1] << 8)
-       |  bytes->r_index[2];
-    r_extern  = (0 != (bytes->r_type[0] & RELOC_STD_BITS_EXTERN_BIG));
-    r_pcrel   = (0 != (bytes->r_type[0] & RELOC_STD_BITS_PCREL_BIG));
-    r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_BIG));
-    r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG));
-    r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_BIG));
-    r_length  =       (bytes->r_type[0] & RELOC_STD_BITS_LENGTH_BIG)
-                       >> RELOC_STD_BITS_LENGTH_SH_BIG;
-  } else {
-    r_index =  (bytes->r_index[2] << 16)
-      | (bytes->r_index[1] << 8)
-       |  bytes->r_index[0];
-    r_extern  = (0 != (bytes->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE));
-    r_pcrel   = (0 != (bytes->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
-    r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_LITTLE));
-    r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_LITTLE));
-    r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_LITTLE));
-    r_length  =       (bytes->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE)
-                       >> RELOC_STD_BITS_LENGTH_SH_LITTLE;
-  }
+  unsigned int howto_idx;
+
+  cache_ptr->address = H_GET_32 (abfd, bytes->r_address);
+
+  /* Now the fun stuff.  */
+  if (bfd_header_big_endian (abfd))
+    {
+      r_index = ((bytes->r_index[0] << 16)
+                | (bytes->r_index[1] << 8)
+                | bytes->r_index[2]);
+      r_extern  = (0 != (bytes->r_type[0] & RELOC_STD_BITS_EXTERN_BIG));
+      r_pcrel   = (0 != (bytes->r_type[0] & RELOC_STD_BITS_PCREL_BIG));
+      r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_BIG));
+      r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG));
+      r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_BIG));
+      r_length  = ((bytes->r_type[0] & RELOC_STD_BITS_LENGTH_BIG)
+                  >> RELOC_STD_BITS_LENGTH_SH_BIG);
+    }
+  else
+    {
+      r_index = ((bytes->r_index[2] << 16)
+                | (bytes->r_index[1] << 8)
+                | bytes->r_index[0]);
+      r_extern  = (0 != (bytes->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE));
+      r_pcrel   = (0 != (bytes->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
+      r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_LITTLE));
+      r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_LITTLE));
+      r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_LITTLE));
+      r_length  = ((bytes->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE)
+                  >> RELOC_STD_BITS_LENGTH_SH_LITTLE);
+    }
 
-  howto_idx = r_length + 4 * r_pcrel + 8 * r_baserel
-             + 16 * r_jmptable + 32 * r_relative;
+  howto_idx = (r_length + 4 * r_pcrel + 8 * r_baserel
+              + 16 * r_jmptable + 32 * r_relative);
   BFD_ASSERT (howto_idx < TABLE_SIZE (howto_table_std));
   cache_ptr->howto =  howto_table_std + howto_idx;
-  BFD_ASSERT (cache_ptr->howto->type != -1);
+  BFD_ASSERT (cache_ptr->howto->type != (unsigned int) -1);
+
+  /* Base relative relocs are always against the symbol table,
+     regardless of the setting of r_extern.  r_extern just reflects
+     whether the symbol the reloc is against is local or global.  */
+  if (r_baserel)
+    r_extern = 1;
+
+  if (r_extern && r_index > symcount)
+    {
+      /* We could arrange to return an error, but it might be useful
+         to see the file even if it is bad.  */
+      r_extern = 0;
+      r_index = N_ABS;
+    }
 
-  MOVE_ADDRESS(0);
+  MOVE_ADDRESS (0);
 }
 
 /* Read and swap the relocs for a section.  */
@@ -2181,13 +2373,14 @@ NAME(aout,slurp_reloc_table) (abfd, asect, symbols)
      sec_ptr asect;
      asymbol **symbols;
 {
-  unsigned int count;
+  bfd_size_type count;
   bfd_size_type reloc_size;
   PTR relocs;
   arelent *reloc_cache;
   size_t each_size;
   unsigned int counter = 0;
   arelent *cache_ptr;
+  bfd_size_type amt;
 
   if (asect->relocation)
     return true;
@@ -2196,9 +2389,9 @@ NAME(aout,slurp_reloc_table) (abfd, asect, symbols)
     return true;
 
   if (asect == obj_datasec (abfd))
-    reloc_size = exec_hdr(abfd)->a_drsize;
+    reloc_size = exec_hdr (abfd)->a_drsize;
   else if (asect == obj_textsec (abfd))
-    reloc_size = exec_hdr(abfd)->a_trsize;
+    reloc_size = exec_hdr (abfd)->a_trsize;
   else if (asect == obj_bsssec (abfd))
     reloc_size = 0;
   else
@@ -2214,23 +2407,19 @@ NAME(aout,slurp_reloc_table) (abfd, asect, symbols)
 
   count = reloc_size / each_size;
 
-  reloc_cache = (arelent *) malloc ((size_t) (count * sizeof (arelent)));
+  amt = count * sizeof (arelent);
+  reloc_cache = (arelent *) bfd_zmalloc (amt);
   if (reloc_cache == NULL && count != 0)
-    {
-      bfd_set_error (bfd_error_no_memory);
-      return false;
-    }
-  memset (reloc_cache, 0, count * sizeof (arelent));
+    return false;
 
-  relocs = malloc (reloc_size);
+  relocs = bfd_malloc (reloc_size);
   if (relocs == NULL && reloc_size != 0)
     {
       free (reloc_cache);
-      bfd_set_error (bfd_error_no_memory);
       return false;
     }
 
-  if (bfd_read (relocs, 1, reloc_size, abfd) != reloc_size)
+  if (bfd_bread (relocs, reloc_size, abfd) != reloc_size)
     {
       free (relocs);
       free (reloc_cache);
@@ -2240,19 +2429,19 @@ NAME(aout,slurp_reloc_table) (abfd, asect, symbols)
   cache_ptr = reloc_cache;
   if (each_size == RELOC_EXT_SIZE)
     {
-      register struct reloc_ext_external *rptr =
-       (struct reloc_ext_external *) relocs;
+      struct reloc_ext_external *rptr = (struct reloc_ext_external *) relocs;
 
       for (; counter < count; counter++, rptr++, cache_ptr++)
-       NAME(aout,swap_ext_reloc_in) (abfd, rptr, cache_ptr, symbols);
+       MY_swap_ext_reloc_in (abfd, rptr, cache_ptr, symbols,
+                             (bfd_size_type) bfd_get_symcount (abfd));
     }
   else
     {
-      register struct reloc_std_external *rptr =
-       (struct reloc_std_external *) relocs;
+      struct reloc_std_external *rptr = (struct reloc_std_external *) relocs;
 
       for (; counter < count; counter++, rptr++, cache_ptr++)
-       MY_swap_std_reloc_in(abfd, rptr, cache_ptr, symbols);
+       MY_swap_std_reloc_in (abfd, rptr, cache_ptr, symbols,
+                             (bfd_size_type) bfd_get_symcount (abfd));
     }
 
   free (relocs);
@@ -2275,17 +2464,16 @@ NAME(aout,squirt_out_relocs) (abfd, section)
   size_t each_size;
 
   unsigned int count = section->reloc_count;
-  size_t natsize;
+  bfd_size_type 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;
+  natsize = (bfd_size_type) each_size * count;
   native = (unsigned char *) bfd_zalloc (abfd, natsize);
-  if (!native) {
-    bfd_set_error (bfd_error_no_memory);
+  if (!native)
     return false;
-  }
 
   generic = section->orelocation;
 
@@ -2294,26 +2482,30 @@ 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
     {
       for (natptr = native;
           count != 0;
           --count, natptr += each_size, ++generic)
-       MY_swap_std_reloc_out(abfd, *generic, (struct reloc_std_external *)natptr);
+       MY_swap_std_reloc_out (abfd, *generic,
+                              (struct reloc_std_external *) natptr);
     }
 
-  if ( bfd_write ((PTR) native, 1, natsize, abfd) != natsize) {
-    bfd_release(abfd, native);
-    return false;
-  }
+  if (bfd_bwrite ((PTR) native, natsize, abfd) != natsize)
+    {
+      bfd_release (abfd, native);
+      return false;
+    }
   bfd_release (abfd, native);
 
   return true;
 }
 
-/* This is stupid.  This function should be a boolean predicate */
+/* This is stupid.  This function should be a boolean predicate.  */
+
 long
 NAME(aout,canonicalize_reloc) (abfd, section, relptr, symbols)
      bfd *abfd;
@@ -2330,24 +2522,27 @@ NAME(aout,canonicalize_reloc) (abfd, section, relptr, symbols)
       return 0;
     }
 
-  if (!(tblptr || NAME(aout,slurp_reloc_table)(abfd, section, symbols)))
+  if (!(tblptr || NAME(aout,slurp_reloc_table) (abfd, section, symbols)))
     return -1;
 
-  if (section->flags & SEC_CONSTRUCTOR) {
-    arelent_chain *chain = section->constructor_chain;
-    for (count = 0; count < section->reloc_count; count ++) {
-      *relptr ++ = &chain->relent;
-      chain = chain->next;
+  if (section->flags & SEC_CONSTRUCTOR)
+    {
+      arelent_chain *chain = section->constructor_chain;
+      for (count = 0; count < section->reloc_count; count ++)
+       {
+         *relptr ++ = &chain->relent;
+         chain = chain->next;
+       }
     }
-  }
-  else {
-    tblptr = section->relocation;
+  else
+    {
+      tblptr = section->relocation;
 
-    for (count = 0; count++ < section->reloc_count;)
-      {
-       *relptr++ = tblptr++;
-      }
-  }
+      for (count = 0; count++ < section->reloc_count; )
+       {
+         *relptr++ = tblptr++;
+       }
+    }
   *relptr = 0;
 
   return section->reloc_count;
@@ -2358,22 +2553,23 @@ NAME(aout,get_reloc_upper_bound) (abfd, asect)
      bfd *abfd;
      sec_ptr asect;
 {
-  if (bfd_get_format (abfd) != bfd_object) {
-    bfd_set_error (bfd_error_invalid_operation);
-    return -1;
-  }
-  if (asect->flags & SEC_CONSTRUCTOR) {
+  if (bfd_get_format (abfd) != bfd_object)
+    {
+      bfd_set_error (bfd_error_invalid_operation);
+      return -1;
+    }
+
+  if (asect->flags & SEC_CONSTRUCTOR)
     return (sizeof (arelent *) * (asect->reloc_count+1));
-  }
 
   if (asect == obj_datasec (abfd))
     return (sizeof (arelent *)
-           * ((exec_hdr(abfd)->a_drsize / obj_reloc_entry_size (abfd))
+           * ((exec_hdr (abfd)->a_drsize / obj_reloc_entry_size (abfd))
               + 1));
 
   if (asect == obj_textsec (abfd))
     return (sizeof (arelent *)
-           * ((exec_hdr(abfd)->a_trsize / obj_reloc_entry_size (abfd))
+           * ((exec_hdr (abfd)->a_trsize / obj_reloc_entry_size (abfd))
               + 1));
 
   if (asect == obj_bsssec (abfd))
@@ -2385,31 +2581,28 @@ NAME(aout,get_reloc_upper_bound) (abfd, asect)
   bfd_set_error (bfd_error_invalid_operation);
   return -1;
 }
-
 \f
 long
 NAME(aout,get_symtab_upper_bound) (abfd)
      bfd *abfd;
 {
-  if (!NAME(aout,slurp_symbol_table)(abfd))
+  if (!NAME(aout,slurp_symbol_table) (abfd))
     return -1;
 
   return (bfd_get_symcount (abfd)+1) * (sizeof (aout_symbol_type *));
 }
 
-/*ARGSUSED*/
- alent *
+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;
 {
@@ -2417,66 +2610,137 @@ 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);
+      int type_code = aout_symbol (symbol)->type & 0xff;
+      const char *stab_name = bfd_get_stab_name (type_code);
       static char buf[10];
 
       if (stab_name == NULL)
        {
-         sprintf(buf, "(%d)", type_code);
+         sprintf (buf, "(%d)", type_code);
          stab_name = buf;
        }
       ret->type = '-';
-      ret->stab_other = (unsigned)(aout_symbol(symbol)->other & 0xff);
-      ret->stab_desc = (unsigned)(aout_symbol(symbol)->desc & 0xffff);
+      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;
     }
 }
 
-/*ARGSUSED*/
 void
-NAME(aout,print_symbol) (ignore_abfd, afile, symbol, how)
-     bfd *ignore_abfd;
+NAME(aout,print_symbol) (abfd, afile, symbol, how)
+     bfd *abfd;
      PTR afile;
      asymbol *symbol;
      bfd_print_symbol_type how;
 {
   FILE *file = (FILE *)afile;
 
-  switch (how) {
-  case bfd_print_symbol_name:
-    if (symbol->name)
-      fprintf(file,"%s", symbol->name);
-    break;
-  case bfd_print_symbol_more:
-    fprintf(file,"%4x %2x %2x",(unsigned)(aout_symbol(symbol)->desc & 0xffff),
-           (unsigned)(aout_symbol(symbol)->other & 0xff),
-           (unsigned)(aout_symbol(symbol)->type));
-    break;
-  case bfd_print_symbol_all:
+  switch (how)
     {
-   CONST char *section_name = symbol->section->name;
+    case bfd_print_symbol_name:
+      if (symbol->name)
+       fprintf (file,"%s", symbol->name);
+      break;
+    case bfd_print_symbol_more:
+      fprintf (file,"%4x %2x %2x",
+              (unsigned) (aout_symbol (symbol)->desc & 0xffff),
+              (unsigned) (aout_symbol (symbol)->other & 0xff),
+              (unsigned) (aout_symbol (symbol)->type));
+      break;
+    case bfd_print_symbol_all:
+      {
+       const char *section_name = symbol->section->name;
 
+       bfd_print_symbol_vandf (abfd, (PTR)file, symbol);
 
-      bfd_print_symbol_vandf((PTR)file,symbol);
+       fprintf (file," %-5s %04x %02x %02x",
+                section_name,
+                (unsigned) (aout_symbol (symbol)->desc & 0xffff),
+                (unsigned) (aout_symbol (symbol)->other & 0xff),
+                (unsigned) (aout_symbol (symbol)->type & 0xff));
+       if (symbol->name)
+         fprintf (file," %s", symbol->name);
+      }
+      break;
+    }
+}
 
-      fprintf(file," %-5s %04x %02x %02x",
-             section_name,
-             (unsigned)(aout_symbol(symbol)->desc & 0xffff),
-             (unsigned)(aout_symbol(symbol)->other & 0xff),
-             (unsigned)(aout_symbol(symbol)->type  & 0xff));
-      if (symbol->name)
-        fprintf(file," %s", symbol->name);
+/* If we don't have to allocate more than 1MB to hold the generic
+   symbols, we use the generic minisymbol methord: it's faster, since
+   it only translates the symbols once, not multiple times.  */
+#define MINISYM_THRESHOLD (1000000 / sizeof (asymbol))
+
+/* Read minisymbols.  For minisymbols, we use the unmodified a.out
+   symbols.  The minisymbol_to_symbol function translates these into
+   BFD asymbol structures.  */
+
+long
+NAME(aout,read_minisymbols) (abfd, dynamic, minisymsp, sizep)
+     bfd *abfd;
+     boolean dynamic;
+     PTR *minisymsp;
+     unsigned int *sizep;
+{
+  if (dynamic)
+    {
+      /* We could handle the dynamic symbols here as well, but it's
+         easier to hand them off.  */
+      return _bfd_generic_read_minisymbols (abfd, dynamic, minisymsp, sizep);
     }
-    break;
-  }
+
+  if (! aout_get_external_symbols (abfd))
+    return -1;
+
+  if (obj_aout_external_sym_count (abfd) < MINISYM_THRESHOLD)
+    return _bfd_generic_read_minisymbols (abfd, dynamic, minisymsp, sizep);
+
+  *minisymsp = (PTR) obj_aout_external_syms (abfd);
+
+  /* By passing the external symbols back from this routine, we are
+     giving up control over the memory block.  Clear
+     obj_aout_external_syms, so that we do not try to free it
+     ourselves.  */
+  obj_aout_external_syms (abfd) = NULL;
+
+  *sizep = EXTERNAL_NLIST_SIZE;
+  return obj_aout_external_sym_count (abfd);
 }
 
-/*
- provided a BFD, a section and an offset into the section, calculate
- and return the name of the source file and the line nearest to the
- wanted location.
-*/
+/* Convert a minisymbol to a BFD asymbol.  A minisymbol is just an
+   unmodified a.out symbol.  The SYM argument is a structure returned
+   by bfd_make_empty_symbol, which we fill in here.  */
+
+asymbol *
+NAME(aout,minisymbol_to_symbol) (abfd, dynamic, minisym, sym)
+     bfd *abfd;
+     boolean dynamic;
+     const PTR minisym;
+     asymbol *sym;
+{
+  if (dynamic
+      || obj_aout_external_sym_count (abfd) < MINISYM_THRESHOLD)
+    return _bfd_generic_minisymbol_to_symbol (abfd, dynamic, minisym, sym);
+
+  memset (sym, 0, sizeof (aout_symbol_type));
+
+  /* We call translate_symbol_table to translate a single symbol.  */
+  if (! (NAME(aout,translate_symbol_table)
+        (abfd,
+         (aout_symbol_type *) sym,
+         (struct external_nlist *) minisym,
+         (bfd_size_type) 1,
+         obj_aout_external_strings (abfd),
+         obj_aout_external_string_size (abfd),
+         false)))
+    return NULL;
+
+  return sym;
+}
+
+/* Provided a BFD, a section and an offset into the section, calculate
+   and return the name of the source file and the line nearest to the
+   wanted location.  */
 
 boolean
 NAME(aout,find_nearest_line)
@@ -2485,121 +2749,204 @@ NAME(aout,find_nearest_line)
      asection *section;
      asymbol **symbols;
      bfd_vma offset;
-     CONST char **filename_ptr;
-     CONST char **functionname_ptr;
+     const char **filename_ptr;
+     const char **functionname_ptr;
      unsigned int *line_ptr;
 {
-  /* Run down the file looking for the filename, function and linenumber */
+  /* Run down the file looking for the filename, function and linenumber */
   asymbol **p;
-  static  char buffer[100];
-  static  char filename_buffer[200];
-  CONST char *directory_name = NULL;
-  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. */
-  bfd_vma high_line_vma = ~0;
+  const char *directory_name = NULL;
+  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;
+  bfd_size_type filelen, funclen;
+  char *buf;
+
   *filename_ptr = abfd->filename;
   *functionname_ptr = 0;
   *line_ptr = 0;
-  if (symbols != (asymbol **)NULL) {
-    for (p = symbols; *p; p++) {
-      aout_symbol_type  *q = (aout_symbol_type *)(*p);
-    next:
-      switch (q->type){
-      case N_SO:
-       main_file_name = current_file_name = q->symbol.name;
-       /* Look ahead to next symbol to check if that too is an N_SO. */
-       p++;
-       if (*p == NULL)
-         break;
-       q = (aout_symbol_type *)(*p);
-       if (q->type != (int)N_SO)
-         goto next;
-
-       /* Found a second N_SO  First is directory; second is filename. */
-       directory_name = current_file_name;
-       main_file_name = current_file_name = q->symbol.name;
-       if (obj_textsec(abfd) != section)
-         goto done;
-       break;
-      case N_SOL:
-       current_file_name = q->symbol.name;
-       break;
 
-      case N_SLINE:
-
-      case N_DSLINE:
-      case N_BSLINE:
-       /* We'll keep this if it resolves nearer than the one we have already */
-       if (q->symbol.value >= offset &&
-           q->symbol.value < high_line_vma) {
-         *line_ptr = q->desc;
-         high_line_vma = q->symbol.value;
-         line_file_name = current_file_name;
-       }
-       break;
-      case N_FUN:
+  if (symbols != (asymbol **)NULL)
+    {
+      for (p = symbols; *p; p++)
        {
-         /* We'll keep this if it is nearer than the one we have already */
-         if (q->symbol.value >= low_func_vma &&
-             q->symbol.value <= offset) {
-           low_func_vma = q->symbol.value;
-           func = (asymbol *)q;
-         }
-         if (*line_ptr && func) {
-           CONST char *function = func->name;
-           char *p;
-
-           /* The caller expects a symbol name.  We actually have a
-              function name, without the leading underscore.  Put the
-              underscore back in, so that the caller gets a symbol
-              name.  */
-           if (bfd_get_symbol_leading_char (abfd) == '\0')
-             strncpy (buffer, function, sizeof (buffer) - 1);
-           else
+         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++;
+             if (*p == NULL)
+               break;
+             q = (aout_symbol_type *) (*p);
+             if (q->type != (int)N_SO)
+               goto next;
+
+             /* Found a second N_SO  First is directory; second is filename.  */
+             directory_name = current_file_name;
+             main_file_name = current_file_name = q->symbol.name;
+             if (obj_textsec (abfd) != section)
+               goto done;
+             break;
+           case N_SOL:
+             current_file_name = q->symbol.name;
+             break;
+
+           case N_SLINE:
+
+           case N_DSLINE:
+           case N_BSLINE:
+             /* We'll keep this if it resolves nearer than the one we have
+                already.  */
+             if (q->symbol.value >= low_line_vma
+                 && q->symbol.value <= offset)
+               {
+                 *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:
              {
-               buffer[0] = bfd_get_symbol_leading_char (abfd);
-               strncpy (buffer + 1, function, sizeof (buffer) - 2);
+               /* We'll keep this if it is nearer than the one we have already.  */
+               if (q->symbol.value >= low_func_vma &&
+                   q->symbol.value <= offset)
+                 {
+                   low_func_vma = q->symbol.value;
+                   func = (asymbol *)q;
+                 }
+               else if (q->symbol.value > offset)
+                 goto done;
              }
-           buffer[sizeof(buffer)-1] = 0;
-           /* Have to remove : stuff */
-           p = strchr(buffer,':');
-           if (p != NULL) { *p = '\0'; }
-           *functionname_ptr = buffer;
-           goto done;
-
-         }
+             break;
+           }
        }
-       break;
-      }
     }
-  }
 
  done:
-  if (*line_ptr)
-    main_file_name = line_file_name;
-  if (main_file_name) {
-      if (main_file_name[0] == '/' || directory_name == NULL)
-         *filename_ptr = main_file_name;
-      else {
-         sprintf(filename_buffer, "%.140s%.50s",
-                 directory_name, main_file_name);
-         *filename_ptr = filename_buffer;
-      }
-  }
-  return true;
+  if (*line_ptr != 0)
+    {
+      main_file_name = line_file_name;
+      directory_name = line_directory_name;
+    }
+
+  if (main_file_name == NULL
+      || IS_ABSOLUTE_PATH (main_file_name)
+      || directory_name == NULL)
+    filelen = 0;
+  else
+    filelen = strlen (directory_name) + strlen (main_file_name);
+
+  if (func == NULL)
+    funclen = 0;
+  else
+    funclen = strlen (bfd_asymbol_name (func));
+
+  if (adata (abfd).line_buf != NULL)
+    free (adata (abfd).line_buf);
 
+  if (filelen + funclen == 0)
+    adata (abfd).line_buf = buf = NULL;
+  else
+    {
+      buf = (char *) bfd_malloc (filelen + funclen + 3);
+      adata (abfd).line_buf = buf;
+      if (buf == NULL)
+       return false;
+    }
+
+  if (main_file_name != NULL)
+    {
+      if (IS_ABSOLUTE_PATH (main_file_name) || directory_name == NULL)
+       *filename_ptr = main_file_name;
+      else
+       {
+         sprintf (buf, "%s%s", directory_name, main_file_name);
+         *filename_ptr = buf;
+         buf += filelen + 1;
+       }
+    }
+
+  if (func)
+    {
+      const char *function = func->name;
+      char *colon;
+
+      /* The caller expects a symbol name.  We actually have a
+        function name, without the leading underscore.  Put the
+        underscore back in, so that the caller gets a symbol name.  */
+      if (bfd_get_symbol_leading_char (abfd) == '\0')
+       strcpy (buf, function);
+      else
+       {
+         buf[0] = bfd_get_symbol_leading_char (abfd);
+         strcpy (buf + 1, function);
+       }
+      /* Have to remove : stuff.  */
+      colon = strchr (buf, ':');
+      if (colon != NULL)
+       *colon = '\0';
+      *functionname_ptr = buf;
+    }
+
+  return true;
 }
 
-/*ARGSUSED*/
 int
 NAME(aout,sizeof_headers) (abfd, execable)
      bfd *abfd;
-     boolean execable;
+     boolean execable ATTRIBUTE_UNUSED;
 {
-  return adata(abfd).exec_bytes_size;
+  return adata (abfd).exec_bytes_size;
 }
 
 /* Free all information we have cached for this BFD.  We can always
@@ -2611,13 +2958,21 @@ NAME(aout,bfd_free_cached_info) (abfd)
 {
   asection *o;
 
-  if (bfd_get_format (abfd) != bfd_object)
+  if (bfd_get_format (abfd) != bfd_object
+      || abfd->tdata.aout_data == NULL)
     return true;
 
 #define BFCI_FREE(x) if (x != NULL) { free (x); x = NULL; }
   BFCI_FREE (obj_aout_symbols (abfd));
+#ifdef USE_MMAP
+  obj_aout_external_syms (abfd) = 0;
+  bfd_free_window (&obj_aout_sym_window (abfd));
+  bfd_free_window (&obj_aout_string_window (abfd));
+  obj_aout_external_strings (abfd) = 0;
+#else
   BFCI_FREE (obj_aout_external_syms (abfd));
   BFCI_FREE (obj_aout_external_strings (abfd));
+#endif
   for (o = abfd->sections; o != (asection *) NULL; o = o->next)
     BFCI_FREE (o->relocation);
 #undef BFCI_FREE
@@ -2653,10 +3008,7 @@ NAME(aout,link_hash_newfunc) (entry, table, string)
     ret = ((struct aout_link_hash_entry *)
           bfd_hash_allocate (table, sizeof (struct aout_link_hash_entry)));
   if (ret == (struct aout_link_hash_entry *) NULL)
-    {
-      bfd_set_error (bfd_error_no_memory);
-      return (struct bfd_hash_entry *) ret;
-    }
+    return (struct bfd_hash_entry *) ret;
 
   /* Call the allocation method of the superclass.  */
   ret = ((struct aout_link_hash_entry *)
@@ -2692,14 +3044,11 @@ NAME(aout,link_hash_table_create) (abfd)
      bfd *abfd;
 {
   struct aout_link_hash_table *ret;
+  bfd_size_type amt = sizeof (struct aout_link_hash_table);
 
-  ret = ((struct aout_link_hash_table *)
-        malloc (sizeof (struct aout_link_hash_table)));
-  if (ret == (struct aout_link_hash_table *) NULL)
-      {
-       bfd_set_error (bfd_error_no_memory);
-       return (struct bfd_link_hash_table *) NULL;
-      }
+  ret = (struct aout_link_hash_table *) bfd_alloc (abfd, amt);
+  if (ret == NULL)
+    return (struct bfd_link_hash_table *) NULL;
   if (! NAME(aout,link_hash_table_init) (ret, abfd,
                                         NAME(aout,link_hash_newfunc)))
     {
@@ -2789,12 +3138,20 @@ aout_link_free_symbols (abfd)
 {
   if (obj_aout_external_syms (abfd) != (struct external_nlist *) NULL)
     {
+#ifdef USE_MMAP
+      bfd_free_window (&obj_aout_sym_window (abfd));
+#else
       free ((PTR) obj_aout_external_syms (abfd));
+#endif
       obj_aout_external_syms (abfd) = (struct external_nlist *) NULL;
     }
   if (obj_aout_external_strings (abfd) != (char *) NULL)
     {
+#ifdef USE_MMAP
+      bfd_free_window (&obj_aout_string_window (abfd));
+#else
       free ((PTR) obj_aout_external_strings (abfd));
+#endif
       obj_aout_external_strings (abfd) = (char *) NULL;
     }
   return true;
@@ -2825,7 +3182,7 @@ aout_link_check_ar_symbols (abfd, info, pneeded)
   strings = obj_aout_external_strings (abfd);
   for (; p < pend; p++)
     {
-      int type = bfd_h_get_8 (abfd, p->e_type);
+      int type = H_GET_8 (abfd, p->e_type);
       const char *name;
       struct bfd_link_hash_entry *h;
 
@@ -2868,19 +3225,43 @@ aout_link_check_ar_symbols (abfd, info, pneeded)
        {
          /* This object file defines this symbol.  We must link it
             in.  This is true regardless of whether the current
-            definition of the symbol is undefined or common.  If the
-            current definition is common, we have a case in which we
-            have already seen an object file including
+            definition of the symbol is undefined or common.
+
+             If the current definition is common, we have a case in
+            which we have already seen an object file including:
                 int a;
-            and this object file from the archive includes
+            and this object file from the archive includes:
                 int a = 5;
-            In such a case we must include this object file.
+            In such a case, whether to include this object is target
+             dependant for backward compatability.
 
             FIXME: The SunOS 4.1.3 linker will pull in the archive
             element if the symbol is defined in the .data section,
             but not if it is defined in the .text section.  That
-            seems a bit crazy to me, and I haven't implemented it.
-            However, it might be correct.  */
+            seems a bit crazy to me, and it has not been implemented
+            yet.  However, it might be correct.  */
+         if (h->type == bfd_link_hash_common)
+           {
+             int skip = 0;
+
+             switch (info->common_skip_ar_aymbols)
+               {
+               case bfd_link_common_skip_text:
+                 skip = (type == (N_TEXT | N_EXT));
+                 break;
+               case bfd_link_common_skip_data:
+                 skip = (type == (N_DATA | N_EXT));
+                 break;
+               default:
+               case bfd_link_common_skip_all:
+                 skip = 1;
+                 break;
+               }
+
+             if (skip)
+               continue;
+           }
+
          if (! (*info->callbacks->add_archive_element) (info, abfd, name))
            return false;
          *pneeded = true;
@@ -2918,13 +3299,13 @@ aout_link_check_ar_symbols (abfd, info, pneeded)
                  /* Turn the current link symbol into a common
                     symbol.  It is already on the undefs list.  */
                  h->type = bfd_link_hash_common;
+                 h->u.c.p = ((struct bfd_link_hash_common_entry *)
+                             bfd_hash_allocate (&info->hash->table,
+                                 sizeof (struct bfd_link_hash_common_entry)));
+                 if (h->u.c.p == NULL)
+                   return false;
+
                  h->u.c.size = value;
-                 if (h->u.c.size != value)
-                   {
-                     /* The size did not fit in the bitfield.  */
-                     bfd_set_error (bfd_error_bad_value);
-                     return false;
-                   }
 
                  /* FIXME: This isn't quite right.  The maximum
                     alignment of a common symbol should be set by the
@@ -2933,10 +3314,10 @@ aout_link_check_ar_symbols (abfd, info, pneeded)
                  power = bfd_log2 (value);
                  if (power > bfd_get_arch_info (abfd)->section_align_power)
                    power = bfd_get_arch_info (abfd)->section_align_power;
-                 h->u.c.alignment_power = power;
+                 h->u.c.p->alignment_power = power;
 
-                 h->u.c.section = bfd_make_section_old_way (symbfd,
-                                                            "COMMON");
+                 h->u.c.p->section = bfd_make_section_old_way (symbfd,
+                                                               "COMMON");
                }
              else
                {
@@ -2982,13 +3363,16 @@ aout_link_add_symbols (abfd, info)
                                     bfd_vma, const char *, boolean,
                                     boolean,
                                     struct bfd_link_hash_entry **));
+  struct external_nlist *syms;
   bfd_size_type sym_count;
   char *strings;
   boolean copy;
   struct aout_link_hash_entry **sym_hash;
   register struct external_nlist *p;
   struct external_nlist *pend;
+  bfd_size_type amt;
 
+  syms = obj_aout_external_syms (abfd);
   sym_count = obj_aout_external_sym_count (abfd);
   strings = obj_aout_external_strings (abfd);
   if (info->keep_memory)
@@ -2996,33 +3380,28 @@ aout_link_add_symbols (abfd, info)
   else
     copy = true;
 
+  if (aout_backend_info (abfd)->add_dynamic_symbols != NULL)
+    {
+      if (! ((*aout_backend_info (abfd)->add_dynamic_symbols)
+            (abfd, info, &syms, &sym_count, &strings)))
+       return false;
+    }
+
   /* We keep a list of the linker hash table entries that correspond
      to particular symbols.  We could just look them up in the hash
      table, but keeping the list is more efficient.  Perhaps this
      should be conditional on info->keep_memory.  */
-  sym_hash = ((struct aout_link_hash_entry **)
-             bfd_alloc (abfd,
-                        ((size_t) sym_count
-                         * sizeof (struct aout_link_hash_entry *))));
+  amt = sym_count * sizeof (struct aout_link_hash_entry *);
+  sym_hash = (struct aout_link_hash_entry **) bfd_alloc (abfd, amt);
   if (sym_hash == NULL && sym_count != 0)
-    {
-      bfd_set_error (bfd_error_no_memory);
-      return false;
-    }
+    return false;
   obj_aout_sym_hashes (abfd) = sym_hash;
 
-  if ((abfd->flags & DYNAMIC) != 0
-      && aout_backend_info (abfd)->add_dynamic_symbols != NULL)
-    {
-      if (! (*aout_backend_info (abfd)->add_dynamic_symbols) (abfd, info))
-       return false;
-    }
-
   add_one_symbol = aout_backend_info (abfd)->add_one_symbol;
   if (add_one_symbol == NULL)
     add_one_symbol = _bfd_generic_link_add_one_symbol;
 
-  p = obj_aout_external_syms (abfd);
+  p = syms;
   pend = p + sym_count;
   for (; p < pend; p++, sym_hash++)
     {
@@ -3035,7 +3414,7 @@ aout_link_add_symbols (abfd, info)
 
       *sym_hash = NULL;
 
-      type = bfd_h_get_8 (abfd, p->e_type);
+      type = H_GET_8 (abfd, p->e_type);
 
       /* Ignore debugging symbols.  */
       if ((type & N_STAB) != 0)
@@ -3171,9 +3550,9 @@ aout_link_add_symbols (abfd, info)
         This isn't quite right: it should use the architecture of the
         output file, not the input files.  */
       if ((*sym_hash)->root.type == bfd_link_hash_common
-         && ((*sym_hash)->root.u.c.alignment_power >
+         && ((*sym_hash)->root.u.c.p->alignment_power >
              bfd_get_arch_info (abfd)->section_align_power))
-       (*sym_hash)->root.u.c.alignment_power =
+       (*sym_hash)->root.u.c.p->alignment_power =
          bfd_get_arch_info (abfd)->section_align_power;
 
       /* If this is a set symbol, and we are not building sets, then
@@ -3191,6 +3570,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.  */
@@ -3207,6 +3617,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.  */
@@ -3217,6 +3629,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
@@ -3241,6 +3655,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
@@ -3255,21 +3701,33 @@ 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;
-  size_t max_relocs_size;
-  size_t max_sym_count;
+  bfd_size_type max_contents_size;
+  bfd_size_type max_relocs_size;
+  bfd_size_type max_sym_count;
   bfd_size_type text_size;
   file_ptr text_end;
   register struct bfd_link_order *p;
   asection *o;
   boolean have_link_order_relocs;
 
+  if (info->shared)
+    abfd->flags |= DYNAMIC;
+
   aout_info.info = info;
   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.  */
@@ -3280,7 +3738,7 @@ NAME(aout,final_link) (abfd, info, callback)
   max_sym_count = 0;
   for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
     {
-      size_t sz;
+      bfd_size_type sz;
 
       if (info->relocateable)
        {
@@ -3295,27 +3753,35 @@ NAME(aout,final_link) (abfd, info, callback)
                 and call get_reloc_upper_bound and canonicalize_reloc to
                 work out the number of relocs needed, and then multiply
                 by the reloc size.  */
-             abort ();
+             (*_bfd_error_handler)
+               (_("%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);
+             goto error_return;
            }
        }
 
-      sz = bfd_section_size (sub, obj_textsec (sub));
-      if (sz > max_contents_size)
-       max_contents_size = sz;
-      sz = bfd_section_size (sub, obj_datasec (sub));
-      if (sz > max_contents_size)
-       max_contents_size = sz;
-
-      sz = exec_hdr (sub)->a_trsize;
-      if (sz > max_relocs_size)
-       max_relocs_size = sz;
-      sz = exec_hdr (sub)->a_drsize;
-      if (sz > max_relocs_size)
-       max_relocs_size = sz;
-
-      sz = obj_aout_external_sym_count (sub);
-      if (sz > max_sym_count)
-       max_sym_count = sz;
+      if (bfd_get_flavour (sub) == bfd_target_aout_flavour)
+       {
+         sz = bfd_section_size (sub, obj_textsec (sub));
+         if (sz > max_contents_size)
+           max_contents_size = sz;
+         sz = bfd_section_size (sub, obj_datasec (sub));
+         if (sz > max_contents_size)
+           max_contents_size = sz;
+
+         sz = exec_hdr (sub)->a_trsize;
+         if (sz > max_relocs_size)
+           max_relocs_size = sz;
+         sz = exec_hdr (sub)->a_drsize;
+         if (sz > max_relocs_size)
+           max_relocs_size = sz;
+
+         sz = obj_aout_external_sym_count (sub);
+         if (sz > max_sym_count)
+           max_sym_count = sz;
+       }
     }
 
   if (info->relocateable)
@@ -3364,20 +3830,30 @@ 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
+     hack, but it's easier than exporting everything which would be
+     needed.  */
+  {
+    struct aout_link_hash_entry *h;
+
+    h = aout_link_hash_lookup (aout_hash_table (info), "__DYNAMIC",
+                              false, false, false);
+    if (h != NULL)
+      aout_link_write_other_symbol (h, &aout_info);
+  }
 
   /* The most time efficient way to do the link would be to read all
      the input object files into memory and then sort out the
@@ -3403,6 +3879,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)
     {
@@ -3485,6 +3974,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)
@@ -3502,10 +3996,27 @@ 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;
+      file_ptr pos;
+
+      b = 0;
+      pos = obj_datasec (abfd)->filepos + exec_hdr (abfd)->a_data - 1;
+      if (bfd_seek (abfd, pos, SEEK_SET) != 0
+         || bfd_bwrite (&b, (bfd_size_type) 1, abfd) != 1)
+       goto error_return;
+    }
+
+  return true;
 
  error_return:
   if (aout_info.contents != NULL)
@@ -3516,6 +4027,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;
 }
 
@@ -3551,16 +4064,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
@@ -3594,7 +4116,7 @@ aout_link_write_symbols (finfo, input_bfd)
   struct aout_link_hash_entry **sym_hash;
   int *symbol_map;
   boolean pass;
-  boolean skip_indirect;
+  boolean skip_next;
 
   output_bfd = finfo->output_bfd;
   sym_count = obj_aout_external_sym_count (input_bfd);
@@ -3611,9 +4133,9 @@ aout_link_write_symbols (finfo, input_bfd)
                              false, false) != NULL)
       && discard != discard_all)
     {
-      bfd_h_put_8 (output_bfd, N_TEXT, outsym->e_type);
-      bfd_h_put_8 (output_bfd, 0, outsym->e_other);
-      bfd_h_put_16 (output_bfd, (bfd_vma) 0, outsym->e_desc);
+      H_PUT_8 (output_bfd, N_TEXT, outsym->e_type);
+      H_PUT_8 (output_bfd, 0, outsym->e_other);
+      H_PUT_16 (output_bfd, 0, outsym->e_desc);
       strtab_index = add_to_stringtab (output_bfd, finfo->strtab,
                                       input_bfd->filename, false);
       if (strtab_index == (bfd_size_type) -1)
@@ -3629,11 +4151,12 @@ aout_link_write_symbols (finfo, input_bfd)
     }
 
   pass = false;
-  skip_indirect = false;
+  skip_next = false;
   sym = obj_aout_external_syms (input_bfd);
   sym_end = sym + sym_count;
   sym_hash = obj_aout_sym_hashes (input_bfd);
   symbol_map = finfo->symbol_map;
+  memset (symbol_map, 0, (size_t) sym_count * sizeof *symbol_map);
   for (; sym < sym_end; sym++, sym_hash++, symbol_map++)
     {
       const char *name;
@@ -3644,9 +4167,19 @@ 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);
+      type = H_GET_8 (input_bfd, sym->e_type);
       name = strings + GET_WORD (input_bfd, sym->e_strx);
 
       h = NULL;
@@ -3658,12 +4191,12 @@ aout_link_write_symbols (finfo, input_bfd)
          val = GET_WORD (input_bfd, sym->e_value);
          pass = false;
        }
-      else if (skip_indirect)
+      else if (skip_next)
        {
          /* Skip this symbol, which is the target of an indirect
             symbol that we have changed to no longer be an indirect
             symbol.  */
-         skip_indirect = false;
+         skip_next = false;
          continue;
        }
       else
@@ -3673,9 +4206,15 @@ aout_link_write_symbols (finfo, input_bfd)
          /* We have saved the hash table entry for this symbol, if
             there is one.  Note that we could just look it up again
             in the hash table, provided we first check that it is an
-            external symbol. */
+            external symbol.  */
          h = *sym_hash;
 
+         /* Use the name from the hash table, in case the symbol was
+             wrapped.  */
+         if (h != NULL
+             && h->root.type != bfd_link_hash_warning)
+           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
@@ -3695,11 +4234,11 @@ aout_link_write_symbols (finfo, input_bfd)
 
          /* If the symbol has already been written out, skip it.  */
          if (h != (struct aout_link_hash_entry *) NULL
-             && h->root.type != bfd_link_hash_warning
              && h->written)
            {
-             if ((type & N_TYPE) == N_INDR)
-               skip_indirect = true;
+             if ((type & N_TYPE) == N_INDR
+                 || type == N_WARNING)
+               skip_next = true;
              *symbol_map = h->indx;
              continue;
            }
@@ -3746,6 +4285,7 @@ aout_link_write_symbols (finfo, input_bfd)
          else if (((type & N_TYPE) == N_INDR
                    && (hresolve == (struct aout_link_hash_entry *) NULL
                        || (hresolve->root.type != bfd_link_hash_defined
+                           && hresolve->root.type != bfd_link_hash_defweak
                            && hresolve->root.type != bfd_link_hash_common)))
                   || type == N_WARNING)
            {
@@ -3770,7 +4310,7 @@ aout_link_write_symbols (finfo, input_bfd)
                 a case we do not want to output the next symbol,
                 which is the target of the indirection.  */
              if ((type & N_TYPE) == N_INDR)
-               skip_indirect = true;
+               skip_next = true;
 
              symsec = NULL;
 
@@ -3798,13 +4338,14 @@ aout_link_write_symbols (finfo, input_bfd)
                      break;
                    }
                }
-             else if (hresolve->root.type == bfd_link_hash_defined)
+             else if (hresolve->root.type == bfd_link_hash_defined
+                      || hresolve->root.type == bfd_link_hash_defweak)
                {
                  asection *input_section;
                  asection *output_section;
 
-                 /* This case means a common symbol which was turned
-                    into a defined symbol.  */
+                 /* This case usually means a common symbol which was
+                    turned into a defined symbol.  */
                  input_section = hresolve->root.u.def.section;
                  output_section = input_section->output_section;
                  BFD_ASSERT (bfd_is_abs_section (output_section)
@@ -3825,17 +4366,25 @@ aout_link_write_symbols (finfo, input_bfd)
                  type &=~ N_TYPE;
 
                  if (output_section == obj_textsec (output_bfd))
-                   type |= N_TEXT;
+                   type |= (hresolve->root.type == bfd_link_hash_defined
+                            ? N_TEXT
+                            : N_WEAKT);
                  else if (output_section == obj_datasec (output_bfd))
-                   type |= N_DATA;
+                   type |= (hresolve->root.type == bfd_link_hash_defined
+                            ? N_DATA
+                            : N_WEAKD);
                  else if (output_section == obj_bsssec (output_bfd))
-                   type |= N_BSS;
+                   type |= (hresolve->root.type == bfd_link_hash_defined
+                            ? N_BSS
+                            : N_WEAKB);
                  else
-                   type |= N_ABS;
+                   type |= (hresolve->root.type == bfd_link_hash_defined
+                            ? N_ABS
+                            : N_WEAKA);
                }
              else if (hresolve->root.type == bfd_link_hash_common)
                val = hresolve->root.u.c.size;
-             else if (hresolve->root.type == bfd_link_hash_weak)
+             else if (hresolve->root.type == bfd_link_hash_undefweak)
                {
                  val = 0;
                  type = N_WEAKU;
@@ -3864,12 +4413,11 @@ aout_link_write_symbols (finfo, input_bfd)
              switch (discard)
                {
                case discard_none:
+               case discard_sec_merge:
                  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:
@@ -3882,15 +4430,119 @@ 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 = 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 (*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 = 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
         write out.  */
-      bfd_h_put_8 (output_bfd, type, outsym->e_type);
-      bfd_h_put_8 (output_bfd, bfd_h_get_8 (input_bfd, sym->e_other),
-                  outsym->e_other);
-      bfd_h_put_16 (output_bfd, bfd_h_get_16 (input_bfd, sym->e_desc),
-                   outsym->e_desc);
+      H_PUT_8 (output_bfd, type, outsym->e_type);
+      H_PUT_8 (output_bfd, H_GET_8 (input_bfd, sym->e_other), outsym->e_other);
+      H_PUT_16 (output_bfd, H_GET_16 (input_bfd, sym->e_desc), outsym->e_desc);
       copy = false;
       if (! finfo->info->keep_memory)
        {
@@ -3916,17 +4568,16 @@ aout_link_write_symbols (finfo, input_bfd)
   /* Write out the output symbols we have just constructed.  */
   if (outsym > finfo->output_syms)
     {
-      bfd_size_type outsym_count;
+      bfd_size_type outsym_size;
 
       if (bfd_seek (output_bfd, finfo->symoff, SEEK_SET) != 0)
        return false;
-      outsym_count = outsym - finfo->output_syms;
-      if (bfd_write ((PTR) finfo->output_syms,
-                    (bfd_size_type) EXTERNAL_NLIST_SIZE,
-                    (bfd_size_type) outsym_count, output_bfd)
-         != outsym_count * EXTERNAL_NLIST_SIZE)
+      outsym_size = outsym - finfo->output_syms;
+      outsym_size *= EXTERNAL_NLIST_SIZE;
+      if (bfd_bwrite ((PTR) finfo->output_syms, outsym_size, output_bfd)
+         != outsym_size)
        return false;
-      finfo->symoff += outsym_count * EXTERNAL_NLIST_SIZE;
+      finfo->symoff += outsym_size;
     }
 
   return true;
@@ -3946,6 +4597,14 @@ aout_link_write_other_symbol (h, data)
   bfd_vma val;
   struct external_nlist outsym;
   bfd_size_type indx;
+  bfd_size_type amt;
+
+  if (h->root.type == bfd_link_hash_warning)
+    {
+      h = (struct aout_link_hash_entry *) h->root.u.i.link;
+      if (h->root.type == bfd_link_hash_new)
+       return true;
+    }
 
   output_bfd = finfo->output_bfd;
 
@@ -3964,15 +4623,18 @@ aout_link_write_other_symbol (h, data)
 
   h->written = true;
 
-  if (finfo->info->strip == strip_all
-      || (finfo->info->strip == strip_some
-         && bfd_hash_lookup (finfo->info->keep_hash, h->root.root.string,
-                             false, false) == NULL))
+  /* An indx of -2 means the symbol must be written.  */
+  if (h->indx != -2
+      && (finfo->info->strip == strip_all
+         || (finfo->info->strip == strip_some
+             && bfd_hash_lookup (finfo->info->keep_hash, h->root.root.string,
+                                 false, false) == NULL)))
     return true;
 
   switch (h->root.type)
     {
     default:
+    case bfd_link_hash_warning:
       abort ();
       /* Avoid variable not initialized warnings.  */
       return true;
@@ -3985,6 +4647,7 @@ aout_link_write_other_symbol (h, data)
       val = 0;
       break;
     case bfd_link_hash_defined:
+    case bfd_link_hash_defweak:
       {
        asection *sec;
 
@@ -3992,13 +4655,14 @@ aout_link_write_other_symbol (h, data)
        BFD_ASSERT (bfd_is_abs_section (sec)
                    || sec->owner == output_bfd);
        if (sec == obj_textsec (output_bfd))
-         type = N_TEXT | N_EXT;
+         type = h->root.type == bfd_link_hash_defined ? N_TEXT : N_WEAKT;
        else if (sec == obj_datasec (output_bfd))
-         type = N_DATA | N_EXT;
+         type = h->root.type == bfd_link_hash_defined ? N_DATA : N_WEAKD;
        else if (sec == obj_bsssec (output_bfd))
-         type = N_BSS | N_EXT;
+         type = h->root.type == bfd_link_hash_defined ? N_BSS : N_WEAKB;
        else
-         type = N_ABS | N_EXT;
+         type = h->root.type == bfd_link_hash_defined ? N_ABS : N_WEAKA;
+       type |= N_EXT;
        val = (h->root.u.def.value
               + sec->vma
               + h->root.u.def.section->output_offset);
@@ -4008,22 +4672,21 @@ aout_link_write_other_symbol (h, data)
       type = N_UNDF | N_EXT;
       val = h->root.u.c.size;
       break;
-    case bfd_link_hash_weak:
+    case bfd_link_hash_undefweak:
       type = N_WEAKU;
       val = 0;
     case bfd_link_hash_indirect:
-    case bfd_link_hash_warning:
-      /* FIXME: Ignore these for now.  The circumstances under which
-        they should be written out are not clear to me.  */
+      /* We ignore these symbols, since the indirected symbol is
+        already in the hash table.  */
       return true;
     }
 
-  bfd_h_put_8 (output_bfd, type, outsym.e_type);
-  bfd_h_put_8 (output_bfd, 0, outsym.e_other);
-  bfd_h_put_16 (output_bfd, 0, outsym.e_desc);
+  H_PUT_8 (output_bfd, type, outsym.e_type);
+  H_PUT_8 (output_bfd, 0, outsym.e_other);
+  H_PUT_16 (output_bfd, 0, outsym.e_desc);
   indx = add_to_stringtab (output_bfd, finfo->strtab, h->root.root.string,
                           false);
-  if (indx == (bfd_size_type) -1)
+  if (indx == - (bfd_size_type) 1)
     {
       /* FIXME: No way to handle errors.  */
       abort ();
@@ -4031,9 +4694,9 @@ aout_link_write_other_symbol (h, data)
   PUT_WORD (output_bfd, indx, outsym.e_strx);
   PUT_WORD (output_bfd, val, outsym.e_value);
 
+  amt = EXTERNAL_NLIST_SIZE;
   if (bfd_seek (output_bfd, finfo->symoff, SEEK_SET) != 0
-      || bfd_write ((PTR) &outsym, (bfd_size_type) EXTERNAL_NLIST_SIZE,
-                   (bfd_size_type) 1, output_bfd) != EXTERNAL_NLIST_SIZE)
+      || bfd_bwrite ((PTR) &outsym, amt, output_bfd) != amt)
     {
       /* FIXME: No way to handle errors.  */
       abort ();
@@ -4074,9 +4737,12 @@ aout_link_input_section (finfo, input_bfd, input_section, reloff_ptr,
   else
     {
       relocs = finfo->relocs;
-      if (bfd_seek (input_bfd, input_section->rel_filepos, SEEK_SET) != 0
-         || bfd_read (relocs, 1, rel_size, input_bfd) != rel_size)
-       return false;
+      if (rel_size > 0)
+       {
+         if (bfd_seek (input_bfd, input_section->rel_filepos, SEEK_SET) != 0
+             || bfd_bread (relocs, rel_size, input_bfd) != rel_size)
+           return false;
+       }
     }
 
   /* Relocate the section contents.  */
@@ -4099,18 +4765,17 @@ aout_link_input_section (finfo, input_bfd, input_section, reloff_ptr,
   if (! bfd_set_section_contents (finfo->output_bfd,
                                  input_section->output_section,
                                  (PTR) finfo->contents,
-                                 input_section->output_offset,
+                                 (file_ptr) input_section->output_offset,
                                  input_size))
     return false;
 
   /* If we are producing relocateable output, the relocs were
      modified, and we now write them out.  */
-  if (finfo->info->relocateable)
+  if (finfo->info->relocateable && rel_size > 0)
     {
       if (bfd_seek (finfo->output_bfd, *reloff_ptr, SEEK_SET) != 0)
        return false;
-      if (bfd_write (relocs, (bfd_size_type) 1, rel_size, finfo->output_bfd)
-         != rel_size)
+      if (bfd_bwrite (relocs, rel_size, finfo->output_bfd) != rel_size)
        return false;
       *reloff_ptr += rel_size;
 
@@ -4147,6 +4812,8 @@ aout_reloc_index_to_section (abfd, indx)
     default:
       abort ();
     }
+  /*NOTREACHED*/
+  return NULL;
 }
 
 /* Relocate an a.out section using standard a.out relocs.  */
@@ -4164,7 +4831,8 @@ aout_link_input_section_std (finfo, input_bfd, input_section, relocs,
   boolean (*check_dynamic_reloc) PARAMS ((struct bfd_link_info *,
                                          bfd *, asection *,
                                          struct aout_link_hash_entry *,
-                                         PTR, boolean *));
+                                         PTR, bfd_byte *, boolean *,
+                                         bfd_vma *));
   bfd *output_bfd;
   boolean relocateable;
   struct external_nlist *syms;
@@ -4179,8 +4847,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);
@@ -4197,51 +4865,58 @@ aout_link_input_section_std (finfo, input_bfd, input_section, relocs,
       int r_index;
       int r_extern;
       int r_pcrel;
-      int r_baserel;
-      int r_jmptable;
-      int r_relative;
-      int r_length;
-      int howto_idx;
+      int r_baserel = 0;
       reloc_howto_type *howto;
+      struct aout_link_hash_entry *h = NULL;
       bfd_vma relocation;
       bfd_reloc_status_type r;
 
       r_addr = GET_SWORD (input_bfd, rel->r_address);
 
 #ifdef MY_reloc_howto
-      howto = MY_reloc_howto(input_bfd, rel, r_index, r_extern, r_pcrel);
-#else      
-      if (input_bfd->xvec->header_byteorder_big_p)
-       {
-         r_index   =  ((rel->r_index[0] << 16)
-                       | (rel->r_index[1] << 8)
-                       | rel->r_index[2]);
-         r_extern  = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_BIG));
-         r_pcrel   = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_BIG));
-         r_baserel = (0 != (rel->r_type[0] & RELOC_STD_BITS_BASEREL_BIG));
-         r_jmptable= (0 != (rel->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG));
-         r_relative= (0 != (rel->r_type[0] & RELOC_STD_BITS_RELATIVE_BIG));
-         r_length  = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_BIG)
-                      >> RELOC_STD_BITS_LENGTH_SH_BIG);
-       }
-      else
-       {
-         r_index   = ((rel->r_index[2] << 16)
-                      | (rel->r_index[1] << 8)
-                      | rel->r_index[0]);
-         r_extern  = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE));
-         r_pcrel   = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
-         r_baserel = (0 != (rel->r_type[0] & RELOC_STD_BITS_BASEREL_LITTLE));
-         r_jmptable= (0 != (rel->r_type[0] & RELOC_STD_BITS_JMPTABLE_LITTLE));
-         r_relative= (0 != (rel->r_type[0] & RELOC_STD_BITS_RELATIVE_LITTLE));
-         r_length  = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE)
-                      >> RELOC_STD_BITS_LENGTH_SH_LITTLE);
-       }
+      howto = MY_reloc_howto (input_bfd, rel, r_index, r_extern, r_pcrel);
+#else
+      {
+       int r_jmptable;
+       int r_relative;
+       int r_length;
+       unsigned int howto_idx;
+
+       if (bfd_header_big_endian (input_bfd))
+         {
+           r_index   =  ((rel->r_index[0] << 16)
+                         | (rel->r_index[1] << 8)
+                         | rel->r_index[2]);
+           r_extern  = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_BIG));
+           r_pcrel   = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_BIG));
+           r_baserel = (0 != (rel->r_type[0] & RELOC_STD_BITS_BASEREL_BIG));
+           r_jmptable= (0 != (rel->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG));
+           r_relative= (0 != (rel->r_type[0] & RELOC_STD_BITS_RELATIVE_BIG));
+           r_length  = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_BIG)
+                        >> RELOC_STD_BITS_LENGTH_SH_BIG);
+         }
+       else
+         {
+           r_index   = ((rel->r_index[2] << 16)
+                        | (rel->r_index[1] << 8)
+                        | rel->r_index[0]);
+           r_extern  = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE));
+           r_pcrel   = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
+           r_baserel = (0 != (rel->r_type[0]
+                              & RELOC_STD_BITS_BASEREL_LITTLE));
+           r_jmptable= (0 != (rel->r_type[0]
+                              & RELOC_STD_BITS_JMPTABLE_LITTLE));
+           r_relative= (0 != (rel->r_type[0]
+                              & RELOC_STD_BITS_RELATIVE_LITTLE));
+           r_length  = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE)
+                        >> RELOC_STD_BITS_LENGTH_SH_LITTLE);
+         }
 
-      howto_idx = r_length + 4 * r_pcrel + 8 * r_baserel
-                 + 16 * r_jmptable + 32 * r_relative;
-      BFD_ASSERT (howto_idx < TABLE_SIZE (howto_table_std));
-      howto = howto_table_std + howto_idx;
+       howto_idx = (r_length + 4 * r_pcrel + 8 * r_baserel
+                    + 16 * r_jmptable + 32 * r_relative);
+       BFD_ASSERT (howto_idx < TABLE_SIZE (howto_table_std));
+       howto = howto_table_std + howto_idx;
+      }
 #endif
 
       if (relocateable)
@@ -4250,19 +4925,18 @@ aout_link_input_section_std (finfo, input_bfd, input_section, relocs,
             modify the reloc accordingly.  */
          if (r_extern)
            {
-             struct aout_link_hash_entry *h;
-
              /* 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 (h != (struct aout_link_hash_entry *) NULL
-                 && h->root.type == bfd_link_hash_defined)
+                 && (h->root.type == bfd_link_hash_defined
+                     || h->root.type == bfd_link_hash_defweak))
                {
                  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;
@@ -4292,22 +4966,42 @@ aout_link_input_section_std (finfo, input_bfd, input_section, relocs,
 
                  if (r_index == -1)
                    {
-                     const char *name;
-
-                     name = strings + GET_WORD (input_bfd,
-                                                syms[r_index].e_strx);
-                     if (! ((*finfo->info->callbacks->unattached_reloc)
-                            (finfo->info, name, input_bfd, input_section,
-                             r_addr)))
-                       return false;
-                     r_index = 0;
+                     if (h != NULL)
+                       {
+                         /* We decided to strip this symbol, but it
+                             turns out that we can't.  Note that we
+                             lose the other and desc information here.
+                             I don't think that will ever matter for a
+                             global symbol.  */
+                         if (h->indx < 0)
+                           {
+                             h->indx = -2;
+                             h->written = false;
+                             if (! aout_link_write_other_symbol (h,
+                                                                 (PTR) finfo))
+                               return false;
+                           }
+                         r_index = h->indx;
+                       }
+                     else
+                       {
+                         const char *name;
+
+                         name = strings + GET_WORD (input_bfd,
+                                                    syms[r_index].e_strx);
+                         if (! ((*finfo->info->callbacks->unattached_reloc)
+                                (finfo->info, name, input_bfd, input_section,
+                                 r_addr)))
+                           return false;
+                         r_index = 0;
+                       }
                    }
 
                  relocation = 0;
                }
 
              /* 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;
@@ -4345,54 +5039,43 @@ aout_link_input_section_std (finfo, input_bfd, input_section, relocs,
                           + input_section->output_offset
                           - input_section->vma);
 
+#ifdef MY_relocatable_reloc
+         MY_relocatable_reloc (howto, output_bfd, rel, relocation, r_addr);
+#endif
+
          if (relocation == 0)
            r = bfd_reloc_ok;
          else
-           r = _bfd_relocate_contents (howto,
+           r = MY_relocate_contents (howto,
                                        input_bfd, relocation,
                                        contents + r_addr);
        }
       else
        {
+         boolean hundef;
+
          /* We are generating an executable, and must do a full
             relocation.  */
+         hundef = false;
+
          if (r_extern)
            {
-             struct aout_link_hash_entry *h;
-
              h = sym_hashes[r_index];
 
-             if (check_dynamic_reloc != NULL)
-               {
-                 boolean skip;
-
-                 if (! ((*check_dynamic_reloc)
-                        (finfo->info, input_bfd, input_section, h,
-                         (PTR) rel, &skip)))
-                   return false;
-                 if (skip)
-                   continue;
-               }
-
              if (h != (struct aout_link_hash_entry *) NULL
-                 && h->root.type == bfd_link_hash_defined)
+                 && (h->root.type == bfd_link_hash_defined
+                     || h->root.type == bfd_link_hash_defweak))
                {
                  relocation = (h->root.u.def.value
                                + h->root.u.def.section->output_section->vma
                                + h->root.u.def.section->output_offset);
                }
              else if (h != (struct aout_link_hash_entry *) NULL
-                      && h->root.type == bfd_link_hash_weak)
+                      && h->root.type == bfd_link_hash_undefweak)
                relocation = 0;
              else
                {
-                 const char *name;
-
-                 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)))
-                   return false;
+                 hundef = true;
                  relocation = 0;
                }
            }
@@ -4408,10 +5091,39 @@ aout_link_input_section_std (finfo, input_bfd, input_section, relocs,
                relocation += input_section->vma;
            }
 
-         r = _bfd_final_link_relocate (howto,
-                                       input_bfd, input_section,
-                                       contents, r_addr, relocation,
-                                       (bfd_vma) 0);
+         if (check_dynamic_reloc != NULL)
+           {
+             boolean skip;
+
+             if (! ((*check_dynamic_reloc)
+                    (finfo->info, input_bfd, input_section, h,
+                     (PTR) rel, contents, &skip, &relocation)))
+               return false;
+             if (skip)
+               continue;
+           }
+
+         /* Now warn if a global symbol is undefined.  We could not
+             do this earlier, because check_dynamic_reloc might want
+             to skip this reloc.  */
+         if (hundef && ! finfo->info->shared && ! r_baserel)
+           {
+             const char *name;
+
+             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, true)))
+               return false;
+           }
+
+         r = MY_final_link_relocate (howto,
+                                     input_bfd, input_section,
+                                     contents, r_addr, relocation,
+                                     (bfd_vma) 0);
        }
 
       if (r != bfd_reloc_ok)
@@ -4425,7 +5137,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
@@ -4463,7 +5177,8 @@ aout_link_input_section_ext (finfo, input_bfd, input_section, relocs,
   boolean (*check_dynamic_reloc) PARAMS ((struct bfd_link_info *,
                                          bfd *, asection *,
                                          struct aout_link_hash_entry *,
-                                         PTR, boolean *));
+                                         PTR, bfd_byte *, boolean *,
+                                         bfd_vma *));
   bfd *output_bfd;
   boolean relocateable;
   struct external_nlist *syms;
@@ -4478,8 +5193,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);
@@ -4495,13 +5210,15 @@ aout_link_input_section_ext (finfo, input_bfd, input_section, relocs,
       bfd_vma r_addr;
       int r_index;
       int r_extern;
-      int r_type;
+      unsigned int r_type;
       bfd_vma r_addend;
+      struct aout_link_hash_entry *h = NULL;
+      asection *r_section = NULL;
       bfd_vma relocation;
 
       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)
@@ -4522,28 +5239,34 @@ aout_link_input_section_ext (finfo, input_bfd, input_section, relocs,
 
       r_addend = GET_SWORD (input_bfd, rel->r_addend);
 
-      BFD_ASSERT (r_type >= 0
-                 && r_type < TABLE_SIZE (howto_table_ext));
+      BFD_ASSERT (r_type < TABLE_SIZE (howto_table_ext));
 
       if (relocateable)
        {
          /* 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)
            {
-             struct aout_link_hash_entry *h;
-
              /* 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_defined
+                     || h->root.type == bfd_link_hash_defweak))
                {
                  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;
@@ -4581,15 +5304,35 @@ aout_link_input_section_ext (finfo, input_bfd, input_section, relocs,
 
                  if (r_index == -1)
                    {
-                     const char *name;
-
-                     name = (strings
-                             + GET_WORD (input_bfd, syms[r_index].e_strx));
-                     if (! ((*finfo->info->callbacks->unattached_reloc)
-                            (finfo->info, name, input_bfd, input_section,
-                             r_addr)))
-                       return false;
-                     r_index = 0;
+                     if (h != NULL)
+                       {
+                         /* We decided to strip this symbol, but it
+                             turns out that we can't.  Note that we
+                             lose the other and desc information here.
+                             I don't think that will ever matter for a
+                             global symbol.  */
+                         if (h->indx < 0)
+                           {
+                             h->indx = -2;
+                             h->written = false;
+                             if (! aout_link_write_other_symbol (h,
+                                                                 (PTR) finfo))
+                               return false;
+                           }
+                         r_index = h->indx;
+                       }
+                     else
+                       {
+                         const char *name;
+
+                         name = strings + GET_WORD (input_bfd,
+                                                    syms[r_index].e_strx);
+                         if (! ((*finfo->info->callbacks->unattached_reloc)
+                                (finfo->info, name, input_bfd, input_section,
+                                 r_addr)))
+                           return false;
+                         r_index = 0;
+                       }
                    }
 
                  relocation = 0;
@@ -4601,7 +5344,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;
@@ -4616,14 +5359,12 @@ aout_link_input_section_ext (finfo, input_bfd, input_section, relocs,
            }
          else
            {
-             asection *section;
-
              /* This is a relocation against a section.  We must
                 adjust by the amount that the section moved.  */
-             section = aout_reloc_index_to_section (input_bfd, r_index);
-             relocation = (section->output_section->vma
-                           + section->output_offset
-                           - section->vma);
+             r_section = aout_reloc_index_to_section (input_bfd, r_index);
+             relocation = (r_section->output_section->vma
+                           + r_section->output_offset
+                           - r_section->vma);
 
              /* If this is a PC relative reloc, then the addend is
                 the difference in VMA between the destination and the
@@ -4633,8 +5374,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);
@@ -4650,55 +5395,67 @@ aout_link_input_section_ext (finfo, input_bfd, input_section, relocs,
        }
       else
        {
+         boolean hundef;
          bfd_reloc_status_type r;
 
          /* We are generating an executable, and must do a full
             relocation.  */
+         hundef = false;
+
          if (r_extern)
            {
-             struct aout_link_hash_entry *h;
-
              h = sym_hashes[r_index];
 
-             if (check_dynamic_reloc != NULL)
-               {
-                 boolean skip;
-
-                 if (! ((*check_dynamic_reloc)
-                        (finfo->info, input_bfd, input_section, h,
-                         (PTR) rel, &skip)))
-                   return false;
-                 if (skip)
-                   continue;
-               }
-
              if (h != (struct aout_link_hash_entry *) NULL
-                 && h->root.type == bfd_link_hash_defined)
+                 && (h->root.type == bfd_link_hash_defined
+                     || h->root.type == bfd_link_hash_defweak))
                {
                  relocation = (h->root.u.def.value
                                + h->root.u.def.section->output_section->vma
                                + h->root.u.def.section->output_offset);
                }
              else if (h != (struct aout_link_hash_entry *) NULL
-                      && h->root.type == bfd_link_hash_weak)
+                      && h->root.type == bfd_link_hash_undefweak)
                relocation = 0;
              else
                {
-                 const char *name;
-
-                 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)))
-                   return false;
+                 hundef = true;
                  relocation = 0;
                }
            }
+         else if (r_type == RELOC_BASE10
+                  || r_type == RELOC_BASE13
+                  || r_type == RELOC_BASE22)
+           {
+             struct external_nlist *sym;
+             int type;
+
+             /* For base relative relocs, r_index is always an index
+                 into the symbol table, even if r_extern is 0.  */
+             sym = syms + r_index;
+             type = H_GET_8 (input_bfd, sym->e_type);
+             if ((type & N_TYPE) == N_TEXT
+                 || type == N_WEAKT)
+               r_section = obj_textsec (input_bfd);
+             else if ((type & N_TYPE) == N_DATA
+                      || type == N_WEAKD)
+               r_section = obj_datasec (input_bfd);
+             else if ((type & N_TYPE) == N_BSS
+                      || type == N_WEAKB)
+               r_section = obj_bsssec (input_bfd);
+             else if ((type & N_TYPE) == N_ABS
+                      || type == N_WEAKA)
+               r_section = bfd_abs_section_ptr;
+             else
+               abort ();
+             relocation = (r_section->output_section->vma
+                           + r_section->output_offset
+                           + (GET_WORD (input_bfd, sym->e_value)
+                              - r_section->vma));
+           }
          else
            {
-             asection *section;
-
-             section = aout_reloc_index_to_section (input_bfd, r_index);
+             r_section = aout_reloc_index_to_section (input_bfd, r_index);
 
              /* If this is a PC relative reloc, then R_ADDEND is the
                 difference between the two vmas, or
@@ -4726,17 +5483,61 @@ aout_link_input_section_ext (finfo, input_bfd, input_section, relocs,
                 RELOCATION to the change in the destination VMA, or
                   new_dest_sec - old_dest_sec
                 */
-             relocation = (section->output_section->vma
-                           + section->output_offset
-                           - section->vma);
+             relocation = (r_section->output_section->vma
+                           + r_section->output_offset
+                           - r_section->vma);
              if (howto_table_ext[r_type].pc_relative)
                relocation += input_section->vma;
            }
 
-         r = _bfd_final_link_relocate (howto_table_ext + r_type,
+         if (check_dynamic_reloc != NULL)
+           {
+             boolean skip;
+
+             if (! ((*check_dynamic_reloc)
+                    (finfo->info, input_bfd, input_section, h,
+                     (PTR) rel, contents, &skip, &relocation)))
+               return false;
+             if (skip)
+               continue;
+           }
+
+         /* Now warn if a global symbol is undefined.  We could not
+             do this earlier, because check_dynamic_reloc might want
+             to skip this reloc.  */
+         if (hundef
+             && ! finfo->info->shared
+             && r_type != RELOC_BASE10
+             && r_type != RELOC_BASE13
+             && r_type != RELOC_BASE22)
+           {
+             const char *name;
+
+             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, true)))
+               return false;
+           }
+
+         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)
@@ -4748,7 +5549,12 @@ aout_link_input_section_ext (finfo, input_bfd, input_section, relocs,
                  {
                    const char *name;
 
-                   if (r_extern)
+                   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
@@ -4783,11 +5589,12 @@ aout_link_reloc_link_order (finfo, o, p)
   struct bfd_link_order_reloc *pr;
   int r_index;
   int r_extern;
-  const reloc_howto_type *howto;
-  file_ptr *reloff_ptr;
+  reloc_howto_type *howto;
+  file_ptr *reloff_ptr = NULL;
   struct reloc_std_external srel;
   struct reloc_ext_external erel;
   PTR rel_ptr;
+  bfd_size_type amt;
 
   pr = p->u.reloc.p;
 
@@ -4808,11 +5615,24 @@ 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 == -1)
+         && h->indx >= 0)
        r_index = h->indx;
+      else if (h != NULL)
+       {
+         /* We decided to strip this symbol, but it turns out that we
+            can't.  Note that we lose the other and desc information
+            here.  I don't think that will ever matter for a global
+            symbol.  */
+         h->indx = -2;
+         h->written = false;
+         if (! aout_link_write_other_symbol (h, (PTR) finfo))
+           return false;
+         r_index = h->indx;
+       }
       else
        {
          if (! ((*finfo->info->callbacks->unattached_reloc)
@@ -4824,7 +5644,7 @@ aout_link_reloc_link_order (finfo, o, p)
     }
 
   howto = bfd_reloc_type_lookup (finfo->output_bfd, pr->reloc);
-  if (howto == (const reloc_howto_type *) NULL)
+  if (howto == 0)
     {
       bfd_set_error (bfd_error_bad_value);
       return false;
@@ -4839,48 +5659,51 @@ aout_link_reloc_link_order (finfo, o, p)
 
   if (obj_reloc_entry_size (finfo->output_bfd) == RELOC_STD_SIZE)
     {
-      int r_pcrel;
-      int r_baserel;
-      int r_jmptable;
-      int r_relative;
-      int r_length;
-
 #ifdef MY_put_reloc
-      MY_put_reloc(finfo->output_bfd, r_extern, r_index, p->offset, howto, &srel);
+      MY_put_reloc (finfo->output_bfd, r_extern, r_index, p->offset, howto,
+                   &srel);
 #else
-      r_pcrel = howto->pc_relative;
-      r_baserel = (howto->type & 8) != 0;
-      r_jmptable = (howto->type & 16) != 0;
-      r_relative = (howto->type & 32) != 0;
-      r_length = howto->size;
-
-      PUT_WORD (finfo->output_bfd, p->offset, srel.r_address);
-      if (finfo->output_bfd->xvec->header_byteorder_big_p)
-       {
-         srel.r_index[0] = r_index >> 16;
-         srel.r_index[1] = r_index >> 8;
-         srel.r_index[2] = r_index;
-         srel.r_type[0] =
-           ((r_extern ?     RELOC_STD_BITS_EXTERN_BIG : 0)
-            | (r_pcrel ?    RELOC_STD_BITS_PCREL_BIG : 0)
-            | (r_baserel ?  RELOC_STD_BITS_BASEREL_BIG : 0)
-            | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_BIG : 0)
-            | (r_relative ? RELOC_STD_BITS_RELATIVE_BIG : 0)
-            | (r_length <<  RELOC_STD_BITS_LENGTH_SH_BIG));
-       }
-      else
-       {
-         srel.r_index[2] = r_index >> 16;
-         srel.r_index[1] = r_index >> 8;
-         srel.r_index[0] = r_index;
-         srel.r_type[0] =
-           ((r_extern ?     RELOC_STD_BITS_EXTERN_LITTLE : 0)
-            | (r_pcrel ?    RELOC_STD_BITS_PCREL_LITTLE : 0)
-            | (r_baserel ?  RELOC_STD_BITS_BASEREL_LITTLE : 0)
-            | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_LITTLE : 0)
-            | (r_relative ? RELOC_STD_BITS_RELATIVE_LITTLE : 0)
-            | (r_length <<  RELOC_STD_BITS_LENGTH_SH_LITTLE));
-       }
+      {
+       int r_pcrel;
+       int r_baserel;
+       int r_jmptable;
+       int r_relative;
+       int r_length;
+
+       r_pcrel = howto->pc_relative;
+       r_baserel = (howto->type & 8) != 0;
+       r_jmptable = (howto->type & 16) != 0;
+       r_relative = (howto->type & 32) != 0;
+       r_length = howto->size;
+
+       PUT_WORD (finfo->output_bfd, p->offset, srel.r_address);
+       if (bfd_header_big_endian (finfo->output_bfd))
+         {
+           srel.r_index[0] = r_index >> 16;
+           srel.r_index[1] = r_index >> 8;
+           srel.r_index[2] = r_index;
+           srel.r_type[0] =
+             ((r_extern ?     RELOC_STD_BITS_EXTERN_BIG : 0)
+              | (r_pcrel ?    RELOC_STD_BITS_PCREL_BIG : 0)
+              | (r_baserel ?  RELOC_STD_BITS_BASEREL_BIG : 0)
+              | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_BIG : 0)
+              | (r_relative ? RELOC_STD_BITS_RELATIVE_BIG : 0)
+              | (r_length <<  RELOC_STD_BITS_LENGTH_SH_BIG));
+         }
+       else
+         {
+           srel.r_index[2] = r_index >> 16;
+           srel.r_index[1] = r_index >> 8;
+           srel.r_index[0] = r_index;
+           srel.r_type[0] =
+             ((r_extern ?     RELOC_STD_BITS_EXTERN_LITTLE : 0)
+              | (r_pcrel ?    RELOC_STD_BITS_PCREL_LITTLE : 0)
+              | (r_baserel ?  RELOC_STD_BITS_BASEREL_LITTLE : 0)
+              | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_LITTLE : 0)
+              | (r_relative ? RELOC_STD_BITS_RELATIVE_LITTLE : 0)
+              | (r_length <<  RELOC_STD_BITS_LENGTH_SH_LITTLE));
+         }
+      }
 #endif
       rel_ptr = (PTR) &srel;
 
@@ -4899,12 +5722,9 @@ aout_link_reloc_link_order (finfo, o, p)
          size = bfd_get_reloc_size (howto);
          buf = (bfd_byte *) bfd_zmalloc (size);
          if (buf == (bfd_byte *) NULL)
-           {
-             bfd_set_error (bfd_error_no_memory);
-             return false;
-           }
-         r = _bfd_relocate_contents (howto, finfo->output_bfd,
-                                     pr->addend, buf);
+           return false;
+         r = MY_relocate_contents (howto, finfo->output_bfd,
+                                   (bfd_vma) pr->addend, buf);
          switch (r)
            {
            case bfd_reloc_ok:
@@ -4927,10 +5747,8 @@ aout_link_reloc_link_order (finfo, o, p)
                }
              break;
            }
-         ok = bfd_set_section_contents (finfo->output_bfd, o,
-                                        (PTR) buf,
-                                        (file_ptr) p->offset,
-                                        size);
+         ok = bfd_set_section_contents (finfo->output_bfd, o, (PTR) buf,
+                                        (file_ptr) p->offset, size);
          free (buf);
          if (! ok)
            return false;
@@ -4938,9 +5756,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;
@@ -4959,16 +5781,15 @@ aout_link_reloc_link_order (finfo, o, p)
              | (howto->type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
        }
 
-      PUT_WORD (finfo->output_bfd, pr->addend, erel.r_addend);
+      PUT_WORD (finfo->output_bfd, (bfd_vma) pr->addend, erel.r_addend);
+#endif /* MY_put_ext_reloc */
 
       rel_ptr = (PTR) &erel;
     }
 
+  amt = obj_reloc_entry_size (finfo->output_bfd);
   if (bfd_seek (finfo->output_bfd, *reloff_ptr, SEEK_SET) != 0
-      || (bfd_write (rel_ptr, (bfd_size_type) 1,
-                    obj_reloc_entry_size (finfo->output_bfd),
-                    finfo->output_bfd)
-         != obj_reloc_entry_size (finfo->output_bfd)))
+      || bfd_bwrite (rel_ptr, amt, finfo->output_bfd) != amt)
     return false;
 
   *reloff_ptr += obj_reloc_entry_size (finfo->output_bfd);
This page took 0.179025 seconds and 4 git commands to generate.