]> Git Repo - binutils.git/blobdiff - bfd/aoutx.h
Remove sanitization of PowerPC NetWare.
[binutils.git] / bfd / aoutx.h
index d5698dc43bf89edb30374f387475c993d20c49c6..c65924d0c8faa5075e0b99d85e11516065586711 100644 (file)
@@ -121,11 +121,9 @@ DESCRIPTION
 #define KEEPIT flags
 #define KEEPITTYPE int
 
-#include <assert.h>
 #include <string.h>            /* For strchr and friends */
 #include "bfd.h"
 #include <sysdep.h>
-#include <ansidecl.h>
 #include "bfdlink.h"
 
 #include "libaout.h"
@@ -134,11 +132,7 @@ DESCRIPTION
 #include "aout/stab_gnu.h"
 #include "aout/ar.h"
 
-static boolean translate_symbol_table PARAMS ((bfd *, aout_symbol_type *,
-                                              struct external_nlist *,
-                                              bfd_size_type, char *,
-                                              bfd_size_type,
-                                              boolean dynamic));
+static boolean aout_get_external_symbols PARAMS ((bfd *));
 
 /*
 SUBSECTION
@@ -203,14 +197,37 @@ HOWTO( 7,        0,  4,   64, true,  0, complain_overflow_signed,  0,"DISP64",    tr
 { -1 },
 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),
 };
 
 #define TABLE_SIZE(TABLE)      (sizeof(TABLE)/sizeof(TABLE[0]))
 
 CONST struct reloc_howto_struct *
-DEFUN(NAME(aout,reloc_type_lookup),(abfd,code),
-      bfd *abfd AND
-      bfd_reloc_code_real_type code)
+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]
@@ -221,6 +238,9 @@ DEFUN(NAME(aout,reloc_type_lookup),(abfd,code),
       case 32:
        code = BFD_RELOC_32;
        break;
+      case 64:
+       code = BFD_RELOC_64;
+       break;
       }
   if (ext)
     switch (code)
@@ -230,6 +250,8 @@ DEFUN(NAME(aout,reloc_type_lookup),(abfd,code),
        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_BASE13, 15);
       default: return (CONST struct reloc_howto_struct *) 0;
       }
   else
@@ -276,10 +298,10 @@ DESCRIPTION
 
 #ifndef NAME_swap_exec_header_in
 void
-DEFUN(NAME(aout,swap_exec_header_in),(abfd, raw_bytes, execp),
-      bfd *abfd AND
-      struct external_exec *raw_bytes AND
-      struct internal_exec *execp)
+NAME(aout,swap_exec_header_in) (abfd, raw_bytes, execp)
+     bfd *abfd;
+     struct external_exec *raw_bytes;
+     struct internal_exec *execp;
 {
   struct external_exec *bytes = (struct external_exec *)raw_bytes;
 
@@ -287,7 +309,7 @@ DEFUN(NAME(aout,swap_exec_header_in),(abfd, raw_bytes, execp),
      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. */
-  memset (execp, 0, sizeof (struct internal_exec));
+  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_text   = GET_WORD (abfd, bytes->e_text);
@@ -316,10 +338,10 @@ DESCRIPTION
        @var{execp} into the buffer @var{raw_bytes} ready for writing to disk.
 */
 void
-DEFUN(NAME(aout,swap_exec_header_out),(abfd, execp, raw_bytes),
-     bfd *abfd AND
-     struct internal_exec *execp AND
-     struct external_exec *raw_bytes)
+NAME(aout,swap_exec_header_out) (abfd, execp, raw_bytes)
+     bfd *abfd;
+     struct internal_exec *execp;
+     struct external_exec *raw_bytes;
 {
   struct external_exec *bytes = (struct external_exec *)raw_bytes;
 
@@ -334,7 +356,23 @@ DEFUN(NAME(aout,swap_exec_header_out),(abfd, execp, raw_bytes),
   PUT_WORD (abfd, execp->a_drsize, bytes->e_drsize);
 }
 
+/* Make all the section for an a.out file.  */
 
+boolean
+NAME(aout,make_sections) (abfd)
+     bfd *abfd;
+{
+  if (obj_textsec (abfd) == (asection *) NULL
+      && bfd_make_section (abfd, ".text") == (asection *) NULL)
+    return false;
+  if (obj_datasec (abfd) == (asection *) NULL
+      && bfd_make_section (abfd, ".data") == (asection *) NULL)
+    return false;
+  if (obj_bsssec (abfd) == (asection *) NULL
+      && bfd_make_section (abfd, ".bss") == (asection *) NULL)
+    return false;
+  return true;
+}
 
 /*
 FUNCTION
@@ -354,17 +392,17 @@ DESCRIPTION
 */
 
 bfd_target *
-DEFUN(NAME(aout,some_aout_object_p),(abfd, execp, callback_to_real_object_p),
-      bfd *abfd AND
-      struct internal_exec *execp AND
-      bfd_target *(*callback_to_real_object_p) PARAMS ((bfd *)))
+NAME(aout,some_aout_object_p) (abfd, execp, callback_to_real_object_p)
+     bfd *abfd;
+     struct internal_exec *execp;
+     bfd_target *(*callback_to_real_object_p) PARAMS ((bfd *));
 {
   struct aout_data_struct *rawptr, *oldrawptr;
   bfd_target *result;
 
   rawptr = (struct aout_data_struct  *) bfd_zalloc (abfd, sizeof (struct aout_data_struct ));
   if (rawptr == NULL) {
-    bfd_error = no_memory;
+    bfd_set_error (bfd_error_no_memory);
     return 0;
   }
 
@@ -420,18 +458,8 @@ DEFUN(NAME(aout,some_aout_object_p),(abfd, execp, callback_to_real_object_p),
   obj_aout_external_strings (abfd) = NULL;
   obj_aout_sym_hashes (abfd) = NULL;
 
-  /* Create the sections.  This is raunchy, but bfd_close wants to reclaim
-     them.  */
-
-  obj_textsec (abfd) = bfd_make_section_old_way (abfd, ".text");
-  obj_datasec (abfd) = bfd_make_section_old_way (abfd, ".data");
-  obj_bsssec (abfd) = bfd_make_section_old_way (abfd, ".bss");
-
-#if 0
-  (void)bfd_make_section (abfd, ".text");
-  (void)bfd_make_section (abfd, ".data");
-  (void)bfd_make_section (abfd, ".bss");
-#endif
+  if (! NAME(aout,make_sections) (abfd))
+    return NULL;
 
   obj_datasec (abfd)->_raw_size = execp->a_data;
   obj_bsssec (abfd)->_raw_size = execp->a_bss;
@@ -547,35 +575,27 @@ DESCRIPTION
 */
 
 boolean
-DEFUN(NAME(aout,mkobject),(abfd),
-     bfd *abfd)
+NAME(aout,mkobject) (abfd)
+     bfd *abfd;
 {
   struct aout_data_struct  *rawptr;
 
-  bfd_error = system_call_error;
+  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_error = no_memory;
+    bfd_set_error (bfd_error_no_memory);
     return false;
   }
 
   abfd->tdata.aout_data = rawptr;
   exec_hdr (abfd) = &(rawptr->e);
 
-  /* For simplicity's sake we just make all the sections right here. */
-
   obj_textsec (abfd) = (asection *)NULL;
   obj_datasec (abfd) = (asection *)NULL;
   obj_bsssec (abfd) = (asection *)NULL;
-  bfd_make_section (abfd, ".text");
-  bfd_make_section (abfd, ".data");
-  bfd_make_section (abfd, ".bss");
-  bfd_make_section (abfd, BFD_ABS_SECTION_NAME);
-  bfd_make_section (abfd, BFD_UND_SECTION_NAME);
-  bfd_make_section (abfd, BFD_COM_SECTION_NAME);
 
   return true;
 }
@@ -601,9 +621,9 @@ DESCRIPTION
 */
 
 enum machine_type
-DEFUN(NAME(aout,machine_type),(arch, machine),
-      enum bfd_architecture arch AND
-      unsigned long machine)
+NAME(aout,machine_type) (arch, machine)
+     enum bfd_architecture arch;
+     unsigned long machine;
 {
   enum machine_type arch_flags;
 
@@ -668,10 +688,10 @@ DESCRIPTION
 */
 
 boolean
-DEFUN(NAME(aout,set_arch_mach),(abfd, arch, machine),
-      bfd *abfd AND
-      enum bfd_architecture arch AND
-      unsigned long machine)
+NAME(aout,set_arch_mach) (abfd, arch, machine)
+     bfd *abfd;
+     enum bfd_architecture arch;
+     unsigned long machine;
 {
   if (! bfd_default_set_arch_mach (abfd, arch, machine))
     return false;
@@ -871,16 +891,16 @@ adjust_n_magic (abfd, execp)
 }
 
 boolean
-DEFUN (NAME(aout,adjust_sizes_and_vmas), (abfd, text_size, text_end),
-       bfd *abfd AND bfd_size_type *text_size AND file_ptr *text_end)
+NAME(aout,adjust_sizes_and_vmas) (abfd, text_size, text_end)
+     bfd *abfd;
+     bfd_size_type *text_size;
+     file_ptr *text_end;
 {
   struct internal_exec *execp = exec_hdr (abfd);
 
-  if ((obj_textsec (abfd) == NULL) || (obj_datasec (abfd) == NULL))
-    {
-      bfd_error = invalid_operation;
-      return false;
-    }
+  if (! NAME(aout,make_sections) (abfd))
+    return false;
+
   if (adata(abfd).magic != undecided_magic) return true;
 
   obj_textsec(abfd)->_raw_size =
@@ -975,9 +995,9 @@ DESCRIPTION
        request.
 */
 boolean
-DEFUN(NAME(aout,new_section_hook),(abfd, newsect),
-       bfd *abfd AND
-       asection *newsect)
+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;
@@ -987,19 +1007,19 @@ DEFUN(NAME(aout,new_section_hook),(abfd, newsect),
   {
     if (obj_textsec(abfd) == NULL && !strcmp(newsect->name, ".text")) {
        obj_textsec(abfd)= newsect;
-       newsect->target_index = N_TEXT | N_EXT;
+       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 | N_EXT;
+       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 | N_EXT;
+       newsect->target_index = N_BSS;
        return true;
       }
 
@@ -1010,12 +1030,12 @@ DEFUN(NAME(aout,new_section_hook),(abfd, newsect),
 }
 
 boolean
-DEFUN(NAME(aout,set_section_contents),(abfd, section, location, offset, count),
-      bfd *abfd AND
-      sec_ptr section AND
-      PTR location AND
-      file_ptr offset AND
-      bfd_size_type count)
+NAME(aout,set_section_contents) (abfd, section, location, offset, count)
+     bfd *abfd;
+     sec_ptr section;
+     PTR location;
+     file_ptr offset;
+     bfd_size_type count;
 {
   file_ptr text_end;
   bfd_size_type text_size;
@@ -1031,7 +1051,8 @@ DEFUN(NAME(aout,set_section_contents),(abfd, section, location, offset, count),
   /* regardless, once we know what we're doing, we might as well get going */
   if (section != obj_bsssec(abfd))
       {
-       bfd_seek (abfd, section->filepos + offset, SEEK_SET);
+       if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0)
+         return false;
 
        if (count) {
          return (bfd_write ((PTR)location, 1, count, abfd) == count) ?
@@ -1080,14 +1101,90 @@ DEFUN(NAME(aout,set_section_contents),(abfd, section, location, offset, count),
 #define sym_is_indirect(sym) \
   (((sym)->type & N_ABS)== N_ABS)
 
+/* Read the external symbols from an a.out file.  */
+
+static boolean
+aout_get_external_symbols (abfd)
+     bfd *abfd;
+{
+  if (obj_aout_external_syms (abfd) == (struct external_nlist *) NULL)
+    {
+      bfd_size_type count;
+      struct external_nlist *syms;
+
+      count = exec_hdr (abfd)->a_syms / EXTERNAL_NLIST_SIZE;
+
+      /* We allocate using malloc to make the values easy to free
+        later on.  If we put them on the obstack it might not be
+        possible to free them.  */
+      syms = ((struct external_nlist *)
+             malloc ((size_t) count * EXTERNAL_NLIST_SIZE));
+      if (syms == (struct external_nlist *) NULL && count != 0)
+       {
+         bfd_set_error (bfd_error_no_memory);
+         return false;
+       }
+
+      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))
+       {
+         free (syms);
+         return false;
+       }
+
+      obj_aout_external_syms (abfd) = syms;
+      obj_aout_external_sym_count (abfd) = count;
+    }
+      
+  if (obj_aout_external_strings (abfd) == NULL)
+    {
+      unsigned char string_chars[BYTES_IN_WORD];
+      bfd_size_type stringsize;
+      char *strings;
+
+      /* 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))
+       return false;
+      stringsize = GET_WORD (abfd, string_chars);
+
+      strings = (char *) malloc ((size_t) stringsize + 1);
+      if (strings == NULL)
+       {
+         bfd_set_error (bfd_error_no_memory);
+         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)
+       {
+         free (strings);
+         return false;
+       }
+
+      /* Sanity preservation.  */
+      strings[stringsize] = '\0';
+
+      obj_aout_external_strings (abfd) = strings;
+      obj_aout_external_string_size (abfd) = stringsize;
+    }
+
+  return true;
+}
+
 /* Only in their own functions for ease of debugging; when sym flags have
   stabilised these should be inlined into their (single) caller */
 
 static boolean
-DEFUN (translate_from_native_sym_flags, (sym_pointer, cache_ptr, abfd),
-       struct external_nlist *sym_pointer AND
-       aout_symbol_type * cache_ptr AND
-       bfd * abfd)
+translate_from_native_sym_flags (sym_pointer, cache_ptr, abfd)
+     struct external_nlist *sym_pointer;
+     aout_symbol_type * cache_ptr;
+     bfd * abfd;
 {
   cache_ptr->symbol.section = 0;
   switch (cache_ptr->type & N_TYPE)
@@ -1104,7 +1201,7 @@ DEFUN (translate_from_native_sym_flags, (sym_pointer, cache_ptr, abfd),
 
        if (!copy || !reloc)
          {
-           bfd_error = no_memory;
+           bfd_set_error (bfd_error_no_memory);
            return false;
          }
 
@@ -1136,7 +1233,7 @@ DEFUN (translate_from_native_sym_flags, (sym_pointer, cache_ptr, abfd),
            cache_ptr->type = N_BSS;
            break;
          default:
-           bfd_error = bad_value;
+           bfd_set_error (bfd_error_bad_value);
            return false;
          }
 
@@ -1154,7 +1251,7 @@ DEFUN (translate_from_native_sym_flags, (sym_pointer, cache_ptr, abfd),
           pointer to the symbol. Build a reloc entry to relocate to this
           symbol attached to this section.  */
 
-       section->flags = SEC_CONSTRUCTOR;
+       section->flags = SEC_CONSTRUCTOR | SEC_RELOC;
 
 
        section->reloc_count++;
@@ -1304,10 +1401,10 @@ DEFUN (translate_from_native_sym_flags, (sym_pointer, cache_ptr, abfd),
 
 
 static boolean
-DEFUN(translate_to_native_sym_flags,(sym_pointer, cache_ptr, abfd),
-     struct external_nlist *sym_pointer AND
-     asymbol *cache_ptr AND
-     bfd *abfd)
+translate_to_native_sym_flags (sym_pointer, cache_ptr, abfd)
+     struct external_nlist *sym_pointer;
+     asymbol *cache_ptr;
+     bfd *abfd;
 {
   bfd_vma value = cache_ptr->value;
 
@@ -1338,14 +1435,14 @@ DEFUN(translate_to_native_sym_flags,(sym_pointer, cache_ptr, abfd),
   else if (bfd_get_output_section(cache_ptr) == NULL) {
     /* Protect the bfd_is_com_section call.
        This case occurs, e.g., for the *DEBUG* section of a COFF file.  */
-    bfd_error = nonrepresentable_section;
+    bfd_set_error (bfd_error_nonrepresentable_section);
     return false;
   }
   else if (bfd_is_com_section (bfd_get_output_section (cache_ptr))) {
     sym_pointer->e_type[0] = (N_UNDF | N_EXT);
   }
   else {
-    bfd_error = nonrepresentable_section;
+    bfd_set_error (bfd_error_nonrepresentable_section);
     return false;
   }
 
@@ -1386,14 +1483,14 @@ DEFUN(translate_to_native_sym_flags,(sym_pointer, cache_ptr, abfd),
 
 
 asymbol *
-DEFUN(NAME(aout,make_empty_symbol),(abfd),
-      bfd *abfd)
+NAME(aout,make_empty_symbol) (abfd)
+     bfd *abfd;
 {
   aout_symbol_type  *new =
     (aout_symbol_type *)bfd_zalloc (abfd, sizeof (aout_symbol_type));
   if (!new)
     {
-      bfd_error = no_memory;
+      bfd_set_error (bfd_error_no_memory);
       return NULL;
     }
   new->symbol.the_bfd = abfd;
@@ -1403,8 +1500,8 @@ DEFUN(NAME(aout,make_empty_symbol),(abfd),
 
 /* Translate a set of internal symbols into external symbols.  */
 
-static boolean
-translate_symbol_table (abfd, in, ext, count, str, strsize, dynamic)
+boolean
+NAME(aout,translate_symbol_table) (abfd, in, ext, count, str, strsize, dynamic)
      bfd *abfd;
      aout_symbol_type *in;
      struct external_nlist *ext;
@@ -1456,98 +1553,69 @@ translate_symbol_table (abfd, in, ext, count, str, strsize, dynamic)
    hold them all plus all the cached symbol entries. */
 
 boolean
-DEFUN(NAME(aout,slurp_symbol_table),(abfd),
-      bfd *abfd)
+NAME(aout,slurp_symbol_table) (abfd)
+     bfd *abfd;
 {
-  bfd_size_type symbol_size;
-  bfd_size_type string_size;
-  unsigned char string_chars[BYTES_IN_WORD];
-  struct external_nlist *syms;
-  char *strings;
+  struct external_nlist *old_external_syms;
   aout_symbol_type *cached;
-  bfd_size_type dynsym_count = 0;
-  struct external_nlist *dynsyms = NULL;
-  char *dynstrs = NULL;
-  bfd_size_type dynstr_size;
+  size_t cached_size;
 
   /* If there's no work to be done, don't do any */
-  if (obj_aout_symbols (abfd) != (aout_symbol_type *)NULL) return true;
-  symbol_size = exec_hdr(abfd)->a_syms;
-  if (symbol_size == 0)
-    {
-      bfd_error = no_symbols;
-      return false;
-    }
+  if (obj_aout_symbols (abfd) != (aout_symbol_type *) NULL)
+    return true;
+
+  old_external_syms = obj_aout_external_syms (abfd);
 
-  bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET);
-  if (bfd_read ((PTR)string_chars, BYTES_IN_WORD, 1, abfd) != BYTES_IN_WORD)
+  if (! aout_get_external_symbols (abfd))
     return false;
-  string_size = GET_WORD (abfd, string_chars);
 
-  /* If this is a dynamic object, see if we can get the dynamic symbol
-     table.  */
-  if ((bfd_get_file_flags (abfd) & DYNAMIC) != 0
-      && aout_backend_info (abfd)->read_dynamic_symbols)
+  if (obj_aout_external_sym_count (abfd) == 0)
     {
-      dynsym_count = ((*aout_backend_info (abfd)->read_dynamic_symbols)
-                     (abfd, &dynsyms, &dynstrs, &dynstr_size));
-      if (dynsym_count == (bfd_size_type) -1)
-       return false;
+      bfd_set_error (bfd_error_no_symbols);
+      return false;
     }
 
-  strings = (char *) bfd_alloc (abfd, string_size + 1);
-  cached = ((aout_symbol_type *)
-           bfd_zalloc (abfd,
-                       ((bfd_get_symcount (abfd) + dynsym_count)
-                        * sizeof (aout_symbol_type))));
+  cached_size = (obj_aout_external_sym_count (abfd)
+                * sizeof (aout_symbol_type));
+  cached = (aout_symbol_type *) malloc (cached_size);
+  memset (cached, 0, cached_size);
 
-  /* Don't allocate on the obstack, so we can free it easily.  */
-  syms = (struct external_nlist *) malloc(symbol_size);
-  if (!strings || !cached || !syms)
+  if (cached == NULL)
     {
-      bfd_error = no_memory;
+      bfd_set_error (bfd_error_no_memory);
       return false;
     }
-  bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET);
-  if (bfd_read ((PTR)syms, 1, symbol_size, abfd) != symbol_size)
+
+  /* Convert from external symbol information to internal.  */
+  if (! (NAME(aout,translate_symbol_table)
+        (abfd, cached,
+         obj_aout_external_syms (abfd),
+         obj_aout_external_sym_count (abfd),
+         obj_aout_external_strings (abfd),
+         obj_aout_external_string_size (abfd),
+         false)))
     {
-    bailout:
-      if (syms)
-       free (syms);
-      if (cached)
-       bfd_release (abfd, cached);
-      if (strings)
-       bfd_release (abfd, strings);
+      free (cached);
       return false;
     }
 
-  bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET);
-  if (bfd_read ((PTR)strings, 1, string_size, abfd) != string_size)
-    {
-      goto bailout;
-    }
-  strings[string_size] = 0; /* Just in case. */
+  bfd_get_symcount (abfd) = obj_aout_external_sym_count (abfd);
 
-  /* OK, now walk the new symtable, cacheing symbol properties */
-  if (! translate_symbol_table (abfd, cached, syms, bfd_get_symcount (abfd),
-                               strings, string_size, false))
-    goto bailout;
-  if (dynsym_count > 0)
-    {
-      if (! translate_symbol_table (abfd, cached + bfd_get_symcount (abfd),
-                                   dynsyms, dynsym_count, dynstrs,
-                                   dynstr_size, true))
-       goto bailout;
+  obj_aout_symbols (abfd) = cached;
 
-      bfd_get_symcount (abfd) += dynsym_count;
+  /* It is very likely that anybody who calls this function will not
+     want the external symbol information, so if it was allocated
+     because of our call to aout_get_external_symbols, we free it up
+     right away to save space.  */
+  if (old_external_syms == (struct external_nlist *) NULL
+      && obj_aout_external_syms (abfd) != (struct external_nlist *) NULL)
+    {
+      free (obj_aout_external_syms (abfd));
+      obj_aout_external_syms (abfd) = NULL;
     }
 
-  obj_aout_symbols (abfd) =  cached;
-  free((PTR)syms);
-
   return true;
 }
-
 \f
 /* Possible improvements:
    + look for strings matching trailing substrings of other strings
@@ -1843,7 +1911,7 @@ add_to_stringtab (abfd, str, tab)
     bfd_alloc_by_size_t (abfd, sizeof (struct stringtab_entry));
   if (!entry)
     {
-      bfd_error = no_memory;
+      bfd_set_error (bfd_error_no_memory);
       abort();                 /* FIXME */
     }
 
@@ -1856,22 +1924,22 @@ add_to_stringtab (abfd, str, tab)
   entry->count = 1;
 #endif
 
-  assert (*tab->end == 0);
+  BFD_ASSERT (*tab->end == 0);
   *(tab->end) = entry;
   tab->end = &entry->next_to_output;
-  assert (*tab->end == 0);
+  BFD_ASSERT (*tab->end == 0);
 
   {
     tab->index += len + 1;
     if (len == 0)
       tab->empty_string_index = entry->index;
   }
-  assert (*ep == 0);
+  BFD_ASSERT (*ep == 0);
   *ep = entry;
   return entry->index;
 }
 
-static void
+static boolean
 emit_strtab (abfd, tab)
      bfd *abfd;
      struct stringtab_data *tab;
@@ -1886,11 +1954,16 @@ emit_strtab (abfd, tab)
   char buffer[BYTES_IN_WORD];
 
   PUT_WORD (abfd, tab->index, (unsigned char *) buffer);
-  bfd_write ((PTR) buffer, 1, BYTES_IN_WORD, abfd);
+  if (bfd_write ((PTR) buffer, 1, BYTES_IN_WORD, abfd) != BYTES_IN_WORD)
+    return false;
 
   for (entry = tab->output_order; entry; entry = entry->next_to_output)
     {
-      bfd_write ((PTR) entry->string, 1, strlen (entry->string) + 1, abfd);
+      size_t len = strlen (entry->string) + 1;
+
+      if (bfd_write ((PTR) entry->string, 1, len, abfd) != len)
+       return false;
+
 #ifdef GATHER_STATISTICS
       count++;
 #endif
@@ -1938,11 +2011,13 @@ emit_strtab (abfd, tab)
        }
       g->KEEPIT = (KEEPITTYPE) count;
     } */
+
+  return true;
 }
 
 boolean
-DEFUN(NAME(aout,write_syms),(abfd),
-      bfd *abfd)
+NAME(aout,write_syms) (abfd)
+     bfd *abfd;
 {
   unsigned int count ;
   asymbol **generic = bfd_get_outsymbols (abfd);
@@ -1986,21 +2061,20 @@ DEFUN(NAME(aout,write_syms),(abfd),
       g->KEEPIT = count;
     }
 
-  emit_strtab (abfd, &strtab);
-
-  return true;
+  return emit_strtab (abfd, &strtab);
 }
 
 \f
-unsigned int
-DEFUN(NAME(aout,get_symtab),(abfd, location),
-      bfd *abfd AND
-      asymbol **location)
+long
+NAME(aout,get_symtab) (abfd, location)
+     bfd *abfd;
+     asymbol **location;
 {
     unsigned int counter = 0;
     aout_symbol_type *symbase;
 
-    if (!NAME(aout,slurp_symbol_table)(abfd)) return 0;
+    if (!NAME(aout,slurp_symbol_table)(abfd))
+      return -1;
 
     for (symbase = obj_aout_symbols(abfd); counter++ < bfd_get_symcount (abfd);)
       *(location++) = (asymbol *)( symbase++);
@@ -2013,10 +2087,10 @@ DEFUN(NAME(aout,get_symtab),(abfd, location),
 /* Output standard relocation information to a file in target byte order. */
 
 void
-DEFUN(NAME(aout,swap_std_reloc_out),(abfd, g, natptr),
-      bfd *abfd AND
-      arelent *g AND
-      struct reloc_std_external *natptr)
+NAME(aout,swap_std_reloc_out) (abfd, g, natptr)
+     bfd *abfd;
+     arelent *g;
+     struct reloc_std_external *natptr;
 {
   int r_index;
   asymbol *sym = *(g->sym_ptr_ptr);
@@ -2032,9 +2106,8 @@ DEFUN(NAME(aout,swap_std_reloc_out),(abfd, g, natptr),
   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, r_relative???  FIXME-soon */
-  r_jmptable = 0;
-  r_relative = 0;
+  r_jmptable = (g->howto->type & 16) != 0;
+  r_relative = (g->howto->type & 32) != 0;
 
 #if 0
   /* For a standard reloc, the addend is in the object file.  */
@@ -2109,10 +2182,10 @@ DEFUN(NAME(aout,swap_std_reloc_out),(abfd, g, natptr),
 /* Output extended relocation information to a file in target byte order. */
 
 void
-DEFUN(NAME(aout,swap_ext_reloc_out),(abfd, g, natptr),
-      bfd *abfd AND
-      arelent *g AND
-      register struct reloc_ext_external *natptr)
+NAME(aout,swap_ext_reloc_out) (abfd, g, natptr)
+     bfd *abfd;
+     arelent *g;
+     register struct reloc_ext_external *natptr;
 {
   int r_index;
   int r_extern;
@@ -2221,11 +2294,11 @@ DEFUN(NAME(aout,swap_ext_reloc_out),(abfd, g, natptr),
   }                                                                    \
 
 void
-DEFUN(NAME(aout,swap_ext_reloc_in), (abfd, bytes, cache_ptr, symbols),
-      bfd *abfd AND
-      struct reloc_ext_external *bytes AND
-      arelent *cache_ptr AND
-      asymbol **symbols)
+NAME(aout,swap_ext_reloc_in) (abfd, bytes, cache_ptr, symbols)
+     bfd *abfd;
+     struct reloc_ext_external *bytes;
+     arelent *cache_ptr;
+     asymbol **symbols;
 {
   int r_index;
   int r_extern;
@@ -2256,11 +2329,11 @@ DEFUN(NAME(aout,swap_ext_reloc_in), (abfd, bytes, cache_ptr, symbols),
 }
 
 void
-DEFUN(NAME(aout,swap_std_reloc_in), (abfd, bytes, cache_ptr, symbols),
-  bfd *abfd AND
-  struct reloc_std_external *bytes AND
-  arelent *cache_ptr AND
-  asymbol **symbols)
+NAME(aout,swap_std_reloc_in) (abfd, bytes, cache_ptr, symbols)
+     bfd *abfd;
+     struct reloc_std_external *bytes;
+     arelent *cache_ptr;
+     asymbol **symbols;
 {
   int r_index;
   int r_extern;
@@ -2297,38 +2370,36 @@ DEFUN(NAME(aout,swap_std_reloc_in), (abfd, bytes, cache_ptr, symbols),
                        >> RELOC_STD_BITS_LENGTH_SH_LITTLE;
   }
 
-  howto_idx = r_length + 4 * r_pcrel + 8 * r_baserel;
+  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 (r_jmptable == 0);
-  BFD_ASSERT (r_relative == 0);
-  /* FIXME-soon:  Roll jmptable, relative bits into howto setting */
 
   MOVE_ADDRESS(0);
 }
 
-/* Reloc hackery */
+/* Read and swap the relocs for a section.  */
 
 boolean
-DEFUN(NAME(aout,slurp_reloc_table),(abfd, asect, symbols),
-      bfd *abfd AND
-      sec_ptr asect AND
-      asymbol **symbols)
+NAME(aout,slurp_reloc_table) (abfd, asect, symbols)
+     bfd *abfd;
+     sec_ptr asect;
+     asymbol **symbols;
 {
   unsigned int count;
   bfd_size_type reloc_size;
   PTR relocs;
-  bfd_size_type dynrel_count = 0;
-  PTR dynrels = NULL;
   arelent *reloc_cache;
   size_t each_size;
   unsigned int counter = 0;
   arelent *cache_ptr;
 
-  if (asect->relocation) return true;
+  if (asect->relocation)
+    return true;
 
-  if (asect->flags & SEC_CONSTRUCTOR) return true;
+  if (asect->flags & SEC_CONSTRUCTOR)
+    return true;
 
   if (asect == obj_datasec (abfd))
     reloc_size = exec_hdr(abfd)->a_drsize;
@@ -2336,47 +2407,37 @@ DEFUN(NAME(aout,slurp_reloc_table),(abfd, asect, symbols),
     reloc_size = exec_hdr(abfd)->a_trsize;
   else
     {
-      bfd_error = invalid_operation;
+      bfd_set_error (bfd_error_invalid_operation);
       return false;
     }
 
-  if ((bfd_get_file_flags (abfd) & DYNAMIC) != 0
-      && aout_backend_info (abfd)->read_dynamic_relocs)
-    {
-      dynrel_count = ((*aout_backend_info (abfd)->read_dynamic_relocs)
-                     (abfd, &dynrels));
-      if (dynrel_count == (bfd_size_type) -1)
-       return false;
-    }
+  if (bfd_seek (abfd, asect->rel_filepos, SEEK_SET) != 0)
+    return false;
 
-  bfd_seek (abfd, asect->rel_filepos, SEEK_SET);
   each_size = obj_reloc_entry_size (abfd);
 
   count = reloc_size / each_size;
 
-  reloc_cache = ((arelent *)
-                bfd_zalloc (abfd,
-                            (size_t) ((count + dynrel_count)
-                                      * sizeof (arelent))));
-  if (!reloc_cache)
+  reloc_cache = (arelent *) malloc ((size_t) (count * sizeof (arelent)));
+  if (reloc_cache == NULL && count != 0)
     {
-    nomem:
-      bfd_error = no_memory;
+      bfd_set_error (bfd_error_no_memory);
       return false;
     }
+  memset (reloc_cache, 0, count * sizeof (arelent));
 
-  relocs = (PTR) bfd_alloc (abfd, reloc_size);
-  if (!relocs)
+  relocs = malloc (reloc_size);
+  if (relocs == NULL && reloc_size != 0)
     {
-      bfd_release (abfd, reloc_cache);
-      goto nomem;
+      free (reloc_cache);
+      bfd_set_error (bfd_error_no_memory);
+      return false;
     }
 
   if (bfd_read (relocs, 1, reloc_size, abfd) != reloc_size)
     {
-      bfd_release (abfd, relocs);
-      bfd_release (abfd, reloc_cache);
-      bfd_error = system_call_error;
+      free (relocs);
+      free (reloc_cache);
       return false;
     }
 
@@ -2391,68 +2452,27 @@ DEFUN(NAME(aout,slurp_reloc_table),(abfd, asect, symbols),
     }
   else
     {
-      register struct reloc_std_external *rptr
-       (struct reloc_std_external *) relocs;
+      register struct reloc_std_external *rptr =
+       (struct reloc_std_external *) relocs;
 
       for (; counter < count; counter++, rptr++, cache_ptr++)
        NAME(aout,swap_std_reloc_in) (abfd, rptr, cache_ptr, symbols);
     }
 
-  if (dynrel_count > 0)
-    {
-      asymbol **dynsyms;
-
-      /* The dynamic symbols are at the end of the symbol table.  */
-      for (dynsyms = symbols;
-          *dynsyms != NULL && ((*dynsyms)->flags & BSF_DYNAMIC) == 0;
-          ++dynsyms)
-       ;
-
-      /* Swap in the dynamic relocs.  These relocs may be for either
-        section, so we must discard ones we don't want.  */
-      counter = 0;
-      if (each_size == RELOC_EXT_SIZE)
-       {
-         register struct reloc_ext_external *rptr
-           = (struct reloc_ext_external *) dynrels;
+  free (relocs);
 
-         for (; counter < dynrel_count; counter++, rptr++, cache_ptr++)
-           {
-             NAME(aout,swap_ext_reloc_in) (abfd, rptr, cache_ptr, dynsyms);
-             cache_ptr->address -= bfd_get_section_vma (abfd, asect);
-             if (cache_ptr->address >= bfd_section_size (abfd, asect))
-               --cache_ptr;
-           }
-       }
-      else
-       {
-         register struct reloc_std_external *rptr
-           = (struct reloc_std_external *) dynrels;
-
-         for (; counter < dynrel_count; counter++, rptr++, cache_ptr++)
-           {
-             NAME(aout,swap_std_reloc_in) (abfd, rptr, cache_ptr, dynsyms);
-             cache_ptr->address -= bfd_get_section_vma (abfd, asect);
-             if (cache_ptr->address >= bfd_section_size (abfd, asect))
-               --cache_ptr;
-           }
-       }
-    }
-
-  bfd_release (abfd,relocs);
   asect->relocation = reloc_cache;
   asect->reloc_count = cache_ptr - reloc_cache;
+
   return true;
 }
 
-
-
 /* Write out a relocation section into an object file.  */
 
 boolean
-DEFUN(NAME(aout,squirt_out_relocs),(abfd, section),
-      bfd *abfd AND
-      asection *section)
+NAME(aout,squirt_out_relocs) (abfd, section)
+     bfd *abfd;
+     asection *section;
 {
   arelent **generic;
   unsigned char *native, *natptr;
@@ -2467,7 +2487,7 @@ DEFUN(NAME(aout,squirt_out_relocs),(abfd, section),
   natsize = each_size * count;
   native = (unsigned char *) bfd_zalloc (abfd, natsize);
   if (!native) {
-    bfd_error = no_memory;
+    bfd_set_error (bfd_error_no_memory);
     return false;
   }
 
@@ -2498,18 +2518,18 @@ DEFUN(NAME(aout,squirt_out_relocs),(abfd, section),
 }
 
 /* This is stupid.  This function should be a boolean predicate */
-unsigned int
-DEFUN(NAME(aout,canonicalize_reloc),(abfd, section, relptr, symbols),
-      bfd *abfd AND
-      sec_ptr section AND
-      arelent **relptr AND
-      asymbol **symbols)
+long
+NAME(aout,canonicalize_reloc) (abfd, section, relptr, symbols)
+     bfd *abfd;
+     sec_ptr section;
+     arelent **relptr;
+     asymbol **symbols;
 {
   arelent *tblptr = section->relocation;
   unsigned int count;
 
   if (!(tblptr || NAME(aout,slurp_reloc_table)(abfd, section, symbols)))
-    return 0;
+    return -1;
 
   if (section->flags & SEC_CONSTRUCTOR) {
     arelent_chain *chain = section->constructor_chain;
@@ -2520,7 +2540,6 @@ DEFUN(NAME(aout,canonicalize_reloc),(abfd, section, relptr, symbols),
   }
   else {
     tblptr = section->relocation;
-    if (!tblptr) return 0;
 
     for (count = 0; count++ < section->reloc_count;)
       {
@@ -2532,71 +2551,59 @@ DEFUN(NAME(aout,canonicalize_reloc),(abfd, section, relptr, symbols),
   return section->reloc_count;
 }
 
-unsigned int
-DEFUN(NAME(aout,get_reloc_upper_bound),(abfd, asect),
-     bfd *abfd AND
-     sec_ptr asect)
+long
+NAME(aout,get_reloc_upper_bound) (abfd, asect)
+     bfd *abfd;
+     sec_ptr asect;
 {
-  bfd_size_type dynrel_count = 0;
-
   if (bfd_get_format (abfd) != bfd_object) {
-    bfd_error = invalid_operation;
-    return 0;
+    bfd_set_error (bfd_error_invalid_operation);
+    return -1;
   }
   if (asect->flags & SEC_CONSTRUCTOR) {
     return (sizeof (arelent *) * (asect->reloc_count+1));
   }
 
-  if ((bfd_get_file_flags (abfd) & DYNAMIC) != 0
-      && aout_backend_info (abfd)->read_dynamic_relocs)
-    {
-      PTR dynrels;
-
-      dynrel_count = ((*aout_backend_info (abfd)->read_dynamic_relocs)
-                     (abfd, &dynrels));
-      if (dynrel_count == (bfd_size_type) -1)
-       return 0;
-    }
-
   if (asect == obj_datasec (abfd))
-    return (sizeof (arelent *) *
-           ((exec_hdr(abfd)->a_drsize / obj_reloc_entry_size (abfd))
-            + dynrel_count + 1));
+    return (sizeof (arelent *)
+           ((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))
-            + dynrel_count + 1));
+    return (sizeof (arelent *)
+           ((exec_hdr(abfd)->a_trsize / obj_reloc_entry_size (abfd))
+              + 1));
 
-  bfd_error = invalid_operation;
-  return 0;
+  bfd_set_error (bfd_error_invalid_operation);
+  return -1;
 }
 
 \f
- unsigned int
-DEFUN(NAME(aout,get_symtab_upper_bound),(abfd),
-     bfd *abfd)
+long
+NAME(aout,get_symtab_upper_bound) (abfd)
+     bfd *abfd;
 {
-  if (!NAME(aout,slurp_symbol_table)(abfd)) return 0;
+  if (!NAME(aout,slurp_symbol_table)(abfd))
+    return -1;
 
   return (bfd_get_symcount (abfd)+1) * (sizeof (aout_symbol_type *));
 }
 
 /*ARGSUSED*/
  alent *
-DEFUN(NAME(aout,get_lineno),(ignore_abfd, ignore_symbol),
-      bfd *ignore_abfd AND
-      asymbol *ignore_symbol)
+NAME(aout,get_lineno) (ignore_abfd, ignore_symbol)
+     bfd *ignore_abfd;
+     asymbol *ignore_symbol;
 {
 return (alent *)NULL;
 }
 
 /*ARGSUSED*/
 void
-DEFUN(NAME(aout,get_symbol_info),(ignore_abfd, symbol, ret),
-      bfd *ignore_abfd AND
-      asymbol *symbol AND
-      symbol_info *ret)
+NAME(aout,get_symbol_info) (ignore_abfd, symbol, ret)
+     bfd *ignore_abfd;
+     asymbol *symbol;
+     symbol_info *ret;
 {
   bfd_symbol_info (symbol, ret);
 
@@ -2620,11 +2627,11 @@ DEFUN(NAME(aout,get_symbol_info),(ignore_abfd, symbol, ret),
 
 /*ARGSUSED*/
 void
-DEFUN(NAME(aout,print_symbol),(ignore_abfd, afile, symbol, how),
-      bfd *ignore_abfd AND
-      PTR afile AND
-      asymbol *symbol AND
-      bfd_print_symbol_type how)
+NAME(aout,print_symbol) (ignore_abfd, afile, symbol, how)
+     bfd *ignore_abfd;
+     PTR afile;
+     asymbol *symbol;
+     bfd_print_symbol_type how;
 {
   FILE *file = (FILE *)afile;
 
@@ -2664,20 +2671,15 @@ DEFUN(NAME(aout,print_symbol),(ignore_abfd, afile, symbol, how),
 */
 
 boolean
-DEFUN(NAME(aout,find_nearest_line),(abfd,
-                                    section,
-                                    symbols,
-                                    offset,
-                                    filename_ptr,
-                                    functionname_ptr,
-                                    line_ptr),
-      bfd *abfd AND
-      asection *section AND
-      asymbol **symbols AND
-      bfd_vma offset AND
-      CONST char **filename_ptr AND
-      CONST char **functionname_ptr AND
-      unsigned int *line_ptr)
+NAME(aout,find_nearest_line)
+     (abfd, section, symbols, offset, filename_ptr, functionname_ptr, line_ptr)
+     bfd *abfd;
+     asection *section;
+     asymbol **symbols;
+     bfd_vma offset;
+     CONST char **filename_ptr;
+     CONST char **functionname_ptr;
+     unsigned int *line_ptr;
 {
   /* Run down the file looking for the filename, function and linenumber */
   asymbol **p;
@@ -2741,7 +2743,18 @@ DEFUN(NAME(aout,find_nearest_line),(abfd,
          if (*line_ptr && func) {
            CONST char *function = func->name;
            char *p;
-           strncpy(buffer, function, sizeof(buffer)-1);
+
+           /* 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
+             {
+               buffer[0] = bfd_get_symbol_leading_char (abfd);
+               strncpy (buffer + 1, function, sizeof (buffer) - 2);
+             }
            buffer[sizeof(buffer)-1] = 0;
            /* Have to remove : stuff */
            p = strchr(buffer,':');
@@ -2774,12 +2787,35 @@ DEFUN(NAME(aout,find_nearest_line),(abfd,
 
 /*ARGSUSED*/
 int
-DEFUN(NAME(aout,sizeof_headers),(abfd, execable),
-      bfd *abfd AND
-      boolean execable)
+NAME(aout,sizeof_headers) (abfd, execable)
+     bfd *abfd;
+     boolean execable;
 {
   return adata(abfd).exec_bytes_size;
 }
+
+/* Free all information we have cached for this BFD.  We can always
+   read it again later if we need it.  */
+
+boolean
+NAME(aout,bfd_free_cached_info) (abfd)
+     bfd *abfd;
+{
+  asection *o;
+
+  if (bfd_get_format (abfd) != bfd_object)
+    return true;
+
+#define FREE(x) if (x != NULL) { free (x); x = NULL; }
+  FREE (obj_aout_symbols (abfd));
+  FREE (obj_aout_external_syms (abfd));
+  FREE (obj_aout_external_strings (abfd));
+  for (o = abfd->sections; o != (asection *) NULL; o = o->next)
+    FREE (o->relocation);
+#undef FREE
+
+  return true;
+}
 \f
 /* a.out link code.  */
 
@@ -2807,7 +2843,6 @@ static boolean aout_link_add_object_symbols
   PARAMS ((bfd *, struct bfd_link_info *));
 static boolean aout_link_check_archive_element
   PARAMS ((bfd *, struct bfd_link_info *, boolean *));
-static boolean aout_link_get_symbols PARAMS ((bfd *));
 static boolean aout_link_free_symbols PARAMS ((bfd *));
 static boolean aout_link_check_ar_symbols
   PARAMS ((bfd *, struct bfd_link_info *, boolean *pneeded));
@@ -2831,7 +2866,7 @@ aout_link_hash_newfunc (entry, table, string)
           bfd_hash_allocate (table, sizeof (struct aout_link_hash_entry)));
   if (ret == (struct aout_link_hash_entry *) NULL)
     {
-      bfd_error = no_memory;
+      bfd_set_error (bfd_error_no_memory);
       return (struct bfd_hash_entry *) ret;
     }
 
@@ -2858,7 +2893,7 @@ NAME(aout,link_hash_table_create) (abfd)
         malloc (sizeof (struct aout_link_hash_table)));
   if (ret == (struct aout_link_hash_table *) NULL)
       {
-       bfd_error = no_memory;
+       bfd_set_error (bfd_error_no_memory);
        return (struct bfd_link_hash_table *) NULL;
       }
   if (! _bfd_link_hash_table_init (&ret->root, abfd,
@@ -2905,7 +2940,7 @@ NAME(aout,link_add_symbols) (abfd, info)
       return _bfd_generic_link_add_archive_symbols
        (abfd, info, aout_link_check_archive_element);
     default:
-      bfd_error = wrong_format;
+      bfd_set_error (bfd_error_wrong_format);
       return false;
     }
 }
@@ -2917,7 +2952,7 @@ aout_link_add_object_symbols (abfd, info)
      bfd *abfd;
      struct bfd_link_info *info;
 {
-  if (! aout_link_get_symbols (abfd))
+  if (! aout_get_external_symbols (abfd))
     return false;
   if (! aout_link_add_symbols (abfd, info))
     return false;
@@ -2940,7 +2975,7 @@ aout_link_check_archive_element (abfd, info, pneeded)
      struct bfd_link_info *info;
      boolean *pneeded;
 {
-  if (! aout_link_get_symbols (abfd))
+  if (! aout_get_external_symbols (abfd))
     return false;
 
   if (! aout_link_check_ar_symbols (abfd, info, pneeded))
@@ -2965,69 +3000,6 @@ aout_link_check_archive_element (abfd, info, pneeded)
   return true;
 }
 
-/* Read the internal symbols from an a.out file.  */
-
-static boolean
-aout_link_get_symbols (abfd)
-     bfd *abfd;
-{
-  bfd_size_type count;
-  struct external_nlist *syms;
-  unsigned char string_chars[BYTES_IN_WORD];
-  bfd_size_type stringsize;
-  char *strings;
-
-  if (obj_aout_external_syms (abfd) != (struct external_nlist *) NULL)
-    {
-      /* We already have them.  */
-      return true;
-    }
-
-  count = exec_hdr (abfd)->a_syms / EXTERNAL_NLIST_SIZE;
-
-  /* We allocate using malloc to make the values easy to free
-     later on.  If we put them on the obstack it might not be possible
-     to free them.  */
-  syms = ((struct external_nlist *)
-         malloc ((size_t) count * EXTERNAL_NLIST_SIZE));
-  if (syms == (struct external_nlist *) NULL)
-    {
-      bfd_error = no_memory;
-      return false;
-    }
-
-  if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0
-      || (bfd_read ((PTR) syms, 1, exec_hdr (abfd)->a_syms, abfd)
-         != exec_hdr (abfd)->a_syms))
-    return false;
-
-  /* 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))
-    return false;
-  stringsize = GET_WORD (abfd, string_chars);
-  strings = (char *) malloc ((size_t) stringsize);
-  if (strings == NULL)
-    {
-      bfd_error = no_memory;
-      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)
-    return false;
-
-  /* Save the data.  */
-  obj_aout_external_syms (abfd) = syms;
-  obj_aout_external_sym_count (abfd) = count;
-  obj_aout_external_strings (abfd) = strings;
-
-  return true;
-}
-
 /* Free up the internal symbols read from an a.out file.  */
 
 static boolean
@@ -3200,7 +3172,7 @@ aout_link_add_symbols (abfd, info)
                          * sizeof (struct aout_link_hash_entry *))));
   if (!sym_hash)
     {
-      bfd_error = no_memory;
+      bfd_set_error (bfd_error_no_memory);
       return false;
     }
   obj_aout_sym_hashes (abfd) = sym_hash;
@@ -3321,7 +3293,7 @@ aout_link_add_symbols (abfd, info)
 
       if (! (_bfd_generic_link_add_one_symbol
             (info, abfd, name, flags, section, value, string, copy, false,
-             ARCH_SIZE, (struct bfd_link_hash_entry **) sym_hash)))
+             (struct bfd_link_hash_entry **) sym_hash)))
        return false;
 
       if (type == (N_INDR | N_EXT) || type == N_WARNING)
@@ -3368,6 +3340,9 @@ static boolean aout_link_input_section_ext
           bfd_size_type rel_size, bfd_byte *contents, int *symbol_map));
 static INLINE asection *aout_reloc_index_to_section
   PARAMS ((bfd *, int));
+static boolean aout_link_reloc_link_order
+  PARAMS ((struct aout_final_link_info *, asection *,
+          struct bfd_link_order *));
 
 /* 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
@@ -3388,6 +3363,7 @@ NAME(aout,final_link) (abfd, info, callback)
   file_ptr text_end;
   register struct bfd_link_order *p;
   asection *o;
+  boolean have_link_order_relocs;
 
   aout_info.info = info;
   aout_info.output_bfd = abfd;
@@ -3420,7 +3396,15 @@ NAME(aout,final_link) (abfd, info, callback)
              abort ();
            }
        }
+      if (obj_textsec (abfd) != (asection *) NULL)
+       trsize += (_bfd_count_link_order_relocs (obj_textsec (abfd)
+                                                ->link_order_head)
+                  * obj_reloc_entry_size (abfd));
       exec_hdr (abfd)->a_trsize = trsize;
+      if (obj_datasec (abfd) != (asection *) NULL)
+       drsize += (_bfd_count_link_order_relocs (obj_datasec (abfd)
+                                                ->link_order_head)
+                  * obj_reloc_entry_size (abfd));
       exec_hdr (abfd)->a_drsize = drsize;
     }
 
@@ -3476,19 +3460,13 @@ NAME(aout,final_link) (abfd, info, callback)
   for (sub = info->input_bfds; sub != (bfd *) NULL; sub = sub->link_next)
     sub->output_has_begun = false;
 
+  have_link_order_relocs = false;
   for (o = abfd->sections; o != (asection *) NULL; o = o->next)
     {
       for (p = o->link_order_head;
           p != (struct bfd_link_order *) NULL;
           p = p->next)
        {
-         /* If we might be using the C based alloca function, we need
-            to dump the memory allocated by aout_link_input_bfd.  */
-#ifndef __GNUC__
-#ifndef alloca
-         (void) alloca (0);
-#endif
-#endif
          if (p->type == bfd_indirect_link_order
              && (bfd_get_flavour (p->u.indirect.section->owner)
                  == bfd_target_aout_flavour))
@@ -3503,6 +3481,12 @@ NAME(aout,final_link) (abfd, info, callback)
                  input_bfd->output_has_begun = true;
                }
            }
+         else if (p->type == bfd_section_reloc_link_order
+                  || p->type == bfd_symbol_reloc_link_order)
+           {
+             /* These are handled below.  */
+             have_link_order_relocs = true;
+           }
          else
            {
              if (! _bfd_default_link_order (abfd, info, o, p))
@@ -3516,6 +3500,28 @@ NAME(aout,final_link) (abfd, info, callback)
                           aout_link_write_other_symbol,
                           (PTR) &aout_info);
 
+  /* Now handle any relocs we were asked to create by the linker.
+     These did not come from any input file.  We must do these after
+     we have written out all the symbols, so that we know the symbol
+     indices to use.  */
+  if (have_link_order_relocs)
+    {
+      for (o = abfd->sections; o != (asection *) NULL; o = o->next)
+       {
+         for (p = o->link_order_head;
+              p != (struct bfd_link_order *) NULL;
+              p = p->next)
+           {
+             if (p->type == bfd_section_reloc_link_order
+                 || p->type == bfd_symbol_reloc_link_order)
+               {
+                 if (! aout_link_reloc_link_order (&aout_info, o, p))
+                   return false;
+               }
+           }
+       }
+    }
+
   /* Update the header information.  */
   abfd->symcount = obj_aout_external_sym_count (abfd);
   exec_hdr (abfd)->a_syms = abfd->symcount * EXTERNAL_NLIST_SIZE;
@@ -3528,9 +3534,7 @@ NAME(aout,final_link) (abfd, info, callback)
   /* Write out the string table.  */
   if (bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET) != 0)
     return false;
-  emit_strtab (abfd, &aout_info.strtab);
-
-  return true;
+  return emit_strtab (abfd, &aout_info.strtab);
 }
 
 /* Link an a.out input BFD into the output file.  */
@@ -3541,21 +3545,26 @@ aout_link_input_bfd (finfo, input_bfd)
      bfd *input_bfd;
 {
   bfd_size_type sym_count;
-  int *symbol_map;
+  int *symbol_map = NULL;
 
   BFD_ASSERT (bfd_get_format (input_bfd) == bfd_object);
 
   /* Get the symbols.  We probably have them already, unless
      finfo->info->keep_memory is false.  */
-  if (! aout_link_get_symbols (input_bfd))
+  if (! aout_get_external_symbols (input_bfd))
     return false;
 
   sym_count = obj_aout_external_sym_count (input_bfd);
-  symbol_map = (int *) alloca ((size_t) sym_count * sizeof (int));
+  symbol_map = (int *) malloc ((size_t) sym_count * sizeof (int));
+  if (symbol_map == NULL && sym_count != 0)
+    {
+      bfd_set_error (bfd_error_no_memory);
+      return false;
+    }
 
   /* Write out the symbols and get a map of the new indices.  */
   if (! aout_link_write_symbols (finfo, input_bfd, symbol_map))
-    return false;
+    goto error_return;
 
   /* Relocate and write out the sections.  */
   if (! aout_link_input_section (finfo, input_bfd,
@@ -3568,7 +3577,7 @@ aout_link_input_bfd (finfo, input_bfd)
                                    &finfo->dreloff,
                                    exec_hdr (input_bfd)->a_drsize,
                                    symbol_map))
-    return false;
+    goto error_return;
 
   /* 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
@@ -3576,10 +3585,16 @@ aout_link_input_bfd (finfo, input_bfd)
   if (! finfo->info->keep_memory)
     {
       if (! aout_link_free_symbols (input_bfd))
-       return false;
+       goto error_return;
     }
 
+  if (symbol_map != NULL)
+    free (symbol_map);
   return true;
+ error_return:
+  if (symbol_map != NULL)
+    free (symbol_map);
+  return false;
 }
 
 /* Adjust and write out the symbols for an a.out file.  Set the new
@@ -3596,7 +3611,7 @@ aout_link_write_symbols (finfo, input_bfd, symbol_map)
   char *strings;
   enum bfd_link_strip strip;
   enum bfd_link_discard discard;
-  struct external_nlist *output_syms;
+  struct external_nlist *output_syms = NULL;
   struct external_nlist *outsym;
   register struct external_nlist *sym;
   struct external_nlist *sym_end;
@@ -3610,7 +3625,12 @@ aout_link_write_symbols (finfo, input_bfd, symbol_map)
   strip = finfo->info->strip;
   discard = finfo->info->discard;
   output_syms = ((struct external_nlist *)
-                alloca ((size_t) (sym_count + 1) * EXTERNAL_NLIST_SIZE));
+                malloc ((size_t) (sym_count + 1) * EXTERNAL_NLIST_SIZE));
+  if (output_syms == NULL)
+    {
+      bfd_set_error (bfd_error_no_memory);
+      goto error_return;
+    }
   outsym = output_syms;
 
   /* First write out a symbol for this object file, unless we are
@@ -3646,6 +3666,7 @@ aout_link_write_symbols (finfo, input_bfd, symbol_map)
     {
       const char *name;
       int type;
+      struct aout_link_hash_entry *h;
       boolean skip;
       asection *symsec;
       bfd_vma val = 0;
@@ -3655,6 +3676,8 @@ aout_link_write_symbols (finfo, input_bfd, symbol_map)
       type = bfd_h_get_8 (input_bfd, sym->e_type);
       name = strings + GET_WORD (input_bfd, sym->e_strx);
 
+      h = NULL;
+
       if (pass)
        {
          /* Pass this symbol through.  It is the target of an
@@ -3672,7 +3695,6 @@ aout_link_write_symbols (finfo, input_bfd, symbol_map)
        }
       else
        {
-         struct aout_link_hash_entry *h;
          struct aout_link_hash_entry *hresolve;
 
          /* We have saved the hash table entry for this symbol, if
@@ -3861,6 +3883,22 @@ aout_link_write_symbols (finfo, input_bfd, symbol_map)
                   outsym->e_other);
       bfd_h_put_16 (output_bfd, bfd_h_get_16 (input_bfd, sym->e_desc),
                    outsym->e_desc);
+      if (! finfo->info->keep_memory)
+       {
+         /* name points into a string table which we are going to
+            free.  If there is a hash table entry, use that string.
+            Otherwise, copy name into memory.  */
+         if (h != (struct aout_link_hash_entry *) NULL)
+           name = (*sym_hash)->root.root.string;
+         else
+           {
+             char *n;
+
+             n = bfd_alloc (output_bfd, strlen (name) + 1);
+             strcpy (n, name);
+             name = n;
+           }
+       }
       PUT_WORD (output_bfd,
                add_to_stringtab (output_bfd, name, &finfo->strtab),
                outsym->e_strx);
@@ -3876,16 +3914,22 @@ aout_link_write_symbols (finfo, input_bfd, symbol_map)
       bfd_size_type outsym_count;
 
       if (bfd_seek (output_bfd, finfo->symoff, SEEK_SET) != 0)
-       return false;
+       goto error_return;
       outsym_count = outsym - output_syms;
       if (bfd_write ((PTR) output_syms, (bfd_size_type) EXTERNAL_NLIST_SIZE,
                     (bfd_size_type) outsym_count, output_bfd)
          != outsym_count * EXTERNAL_NLIST_SIZE)
-       return false;
+       goto error_return;
       finfo->symoff += outsym_count * EXTERNAL_NLIST_SIZE;
     }
 
+  if (output_syms != NULL)
+    free (output_syms);
   return true;
+ error_return:
+  if (output_syms != NULL)
+    free (output_syms);
+  return false;
 }
 
 /* Write out a symbol that was not associated with an a.out input
@@ -3993,21 +4037,31 @@ aout_link_input_section (finfo, input_bfd, input_section, reloff_ptr,
      int *symbol_map;
 {
   bfd_size_type input_size;
-  bfd_byte *contents;
-  PTR relocs;
+  bfd_byte *contents = NULL;
+  PTR relocs = NULL;
 
   /* Get the section contents.  */
   input_size = bfd_section_size (input_bfd, input_section);
-  contents = (bfd_byte *) alloca (input_size);
+  contents = (bfd_byte *) malloc (input_size);
+  if (contents == NULL && input_size != 0)
+    {
+      bfd_set_error (bfd_error_no_memory);
+      goto error_return;
+    }
   if (! bfd_get_section_contents (input_bfd, input_section, (PTR) contents,
                                  (file_ptr) 0, input_size))
-    return false;
+    goto error_return;
 
   /* Read in the relocs.  */
-  relocs = (PTR) alloca (rel_size);
+  relocs = (PTR) malloc (rel_size);
+  if (relocs == NULL && rel_size != 0)
+    {
+      bfd_set_error (bfd_error_no_memory);
+      goto error_return;
+    }
   if (bfd_seek (input_bfd, input_section->rel_filepos, SEEK_SET) != 0
       || bfd_read (relocs, 1, rel_size, input_bfd) != rel_size)
-    return false;
+    goto error_return;
 
   /* Relocate the section contents.  */
   if (obj_reloc_entry_size (input_bfd) == RELOC_STD_SIZE)
@@ -4015,14 +4069,14 @@ aout_link_input_section (finfo, input_bfd, input_section, reloff_ptr,
       if (! aout_link_input_section_std (finfo, input_bfd, input_section,
                                         (struct reloc_std_external *) relocs,
                                         rel_size, contents, symbol_map))
-       return false;
+       goto error_return;
     }
   else
     {
       if (! aout_link_input_section_ext (finfo, input_bfd, input_section,
                                         (struct reloc_ext_external *) relocs,
                                         rel_size, contents, symbol_map))
-       return false;
+       goto error_return;
     }
 
   /* Write out the section contents.  */
@@ -4031,17 +4085,17 @@ aout_link_input_section (finfo, input_bfd, input_section, reloff_ptr,
                                  (PTR) contents,
                                  input_section->output_offset,
                                  input_size))
-    return false;
+    goto error_return;
 
   /* If we are producing relocateable output, the relocs were
      modified, and we now write them out.  */
   if (finfo->info->relocateable)
     {
       if (bfd_seek (finfo->output_bfd, *reloff_ptr, SEEK_SET) != 0)
-       return false;
+       goto error_return;
       if (bfd_write (relocs, (bfd_size_type) 1, rel_size, finfo->output_bfd)
          != rel_size)
-       return false;
+       goto error_return;
       *reloff_ptr += rel_size;
 
       /* Assert that the relocs have not run into the symbols, and
@@ -4053,7 +4107,17 @@ aout_link_input_section (finfo, input_bfd, input_section, reloff_ptr,
                          <= obj_datasec (finfo->output_bfd)->rel_filepos)));
     }
 
+  if (relocs != NULL)
+    free (relocs);
+  if (contents != NULL)
+    free (contents);
   return true;
+ error_return:
+  if (relocs != NULL)
+    free (relocs);
+  if (contents != NULL)
+    free (contents);
+  return false;
 }
 
 /* Get the section corresponding to a reloc index.  */
@@ -4158,10 +4222,9 @@ aout_link_input_section_std (finfo, input_bfd, input_section, relocs,
                       >> RELOC_STD_BITS_LENGTH_SH_LITTLE);
        }
 
-      howto_idx = r_length + 4 * r_pcrel + 8 * r_baserel;
+      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));
-      BFD_ASSERT (r_jmptable == 0);
-      BFD_ASSERT (r_relative == 0);
 
       if (relocateable)
        {
@@ -4652,3 +4715,211 @@ aout_link_input_section_ext (finfo, input_bfd, input_section, relocs,
 
   return true;
 }
+
+/* Handle a link order which is supposed to generate a reloc.  */
+
+static boolean
+aout_link_reloc_link_order (finfo, o, p)
+     struct aout_final_link_info *finfo;
+     asection *o;
+     struct bfd_link_order *p;
+{
+  struct bfd_link_order_reloc *pr;
+  int r_index;
+  int r_extern;
+  const reloc_howto_type *howto;
+  file_ptr *reloff_ptr;
+  struct reloc_std_external srel;
+  struct reloc_ext_external erel;
+  PTR rel_ptr;
+
+  pr = p->u.reloc.p;
+
+  if (p->type == bfd_section_reloc_link_order)
+    {
+      r_extern = 0;
+      if (pr->u.section == &bfd_abs_section)
+       r_index = N_ABS | N_EXT;
+      else
+       {
+         BFD_ASSERT (pr->u.section->owner == finfo->output_bfd);
+         r_index = pr->u.section->target_index;
+       }
+    }
+  else
+    {
+      struct aout_link_hash_entry *h;
+
+      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);
+      if (h != (struct aout_link_hash_entry *) NULL
+         && h->indx == -1)
+       r_index = h->indx;
+      else
+       {
+         if (! ((*finfo->info->callbacks->unattached_reloc)
+                (finfo->info, pr->u.name, (bfd *) NULL,
+                 (asection *) NULL, (bfd_vma) 0)))
+           return false;
+         r_index = 0;
+       }
+    }
+
+  howto = bfd_reloc_type_lookup (finfo->output_bfd, pr->reloc);
+  if (howto == (const reloc_howto_type *) NULL)
+    {
+      bfd_set_error (bfd_error_bad_value);
+      return false;
+    }
+
+  if (o == obj_textsec (finfo->output_bfd))
+    reloff_ptr = &finfo->treloff;
+  else if (o == obj_datasec (finfo->output_bfd))
+    reloff_ptr = &finfo->dreloff;
+  else
+    abort ();
+
+  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;
+
+      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));
+       }
+
+      rel_ptr = (PTR) &srel;
+
+      /* We have to write the addend into the object file, since
+        standard a.out relocs are in place.  It would be more
+        reliable if we had the current contents of the file here,
+        rather than assuming zeroes, but we can't read the file since
+        it was opened using bfd_openw.  */
+      if (pr->addend != 0)
+       {
+         bfd_size_type size;
+         bfd_reloc_status_type r;
+         bfd_byte *buf;
+         boolean ok;
+
+         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);
+         switch (r)
+           {
+           case bfd_reloc_ok:
+             break;
+           default:
+           case bfd_reloc_outofrange:
+             abort ();
+           case bfd_reloc_overflow:
+             if (! ((*finfo->info->callbacks->reloc_overflow)
+                    (finfo->info,
+                     (p->type == bfd_section_reloc_link_order
+                      ? bfd_section_name (finfo->output_bfd,
+                                          pr->u.section)
+                      : pr->u.name),
+                     howto->name, pr->addend, (bfd *) NULL,
+                     (asection *) NULL, (bfd_vma) 0)))
+               {
+                 free (buf);
+                 return false;
+               }
+             break;
+           }
+         ok = bfd_set_section_contents (finfo->output_bfd, o,
+                                        (PTR) buf,
+                                        (file_ptr) p->offset,
+                                        size);
+         free (buf);
+         if (! ok)
+           return false;
+       }
+    }
+  else
+    {
+      PUT_WORD (finfo->output_bfd, p->offset, erel.r_address);
+
+      if (finfo->output_bfd->xvec->header_byteorder_big_p)
+       {
+         erel.r_index[0] = r_index >> 16;
+         erel.r_index[1] = r_index >> 8;
+         erel.r_index[2] = r_index;
+         erel.r_type[0] =
+           ((r_extern ? RELOC_EXT_BITS_EXTERN_BIG : 0)
+            | (howto->type << RELOC_EXT_BITS_TYPE_SH_BIG));
+       }
+      else
+       {
+         erel.r_index[2] = r_index >> 16;
+         erel.r_index[1] = r_index >> 8;
+         erel.r_index[0] = r_index;
+         erel.r_type[0] =
+           (r_extern ? RELOC_EXT_BITS_EXTERN_LITTLE : 0)
+             | (howto->type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
+       }
+
+      PUT_WORD (finfo->output_bfd, pr->addend, erel.r_addend);
+
+      rel_ptr = (PTR) &erel;
+    }
+
+  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)))
+    return false;
+
+  *reloff_ptr += obj_reloc_entry_size (finfo->output_bfd);
+
+  /* Assert that the relocs have not run into the symbols, and that n
+     the text relocs have not run into the data relocs.  */
+  BFD_ASSERT (*reloff_ptr <= obj_sym_filepos (finfo->output_bfd)
+             && (reloff_ptr != &finfo->treloff
+                 || (*reloff_ptr
+                     <= obj_datasec (finfo->output_bfd)->rel_filepos)));
+
+  return true;
+}
This page took 0.083764 seconds and 4 git commands to generate.