Extensive changes to move the bulk of the linker into BFD so that
authorIan Lance Taylor <ian@airs.com>
Thu, 30 Dec 1993 19:56:50 +0000 (19:56 +0000)
committerIan Lance Taylor <ian@airs.com>
Thu, 30 Dec 1993 19:56:50 +0000 (19:56 +0000)
more efficient backend code can be written for specific object
files.  Only existing efficient backend is a.out.
* seclet.c, seclet.h: Removed.
* hash.c, linker.c, genlink.h: New files.
* bfd-in.h: Removed bfd_error_vector.  Declared hash table
structures and functions.
(JUMP_TABLE): Removed bfd_seclet_link, added
bfd_link_hash_table_create, bfd_link_add_symbols and
bfd_final_link.
* All backends: Changed accordingly.
* bfd-in2.h: Rebuilt.
* bfd.c (struct _bfd): Added link_next and archive_pass fields.
Removed ld_symbols field.
(bfd_nonrepresentable_section, bfd_undefined_symbol,
bfd_reloc_value_truncated, bfd_reloc_is_dangerous,
bfd_error_vector): Removed.
(bfd_default_error_trap, bfd_error_trap,
bfd_error_nonrepresentabltrap): Removed.
(bfd_get_relocated_section_contents): Pass link_info.  Pass
link_order instead of seclet.  Pass symbols.
(bfd_relax_section): Pass link_info.
(bfd_seclet_link): Removed.
(bfd_link_hash_table_create, bfd_link_add_symbols,
bfd_final_link): New macros.
* libbfd-in.h: If __GNUC__ is defined and alloca is not, define
alloca as __builtin_alloca.  Declare internal linking functions.
* libbfd.h: Rebuilt.
* libbfd.c (bfd_seek): Comment out fseek assertion.  It's worked
for months.
* reloc.c (reloc_howto_type): Added error_message argument to
special_function field.  Changed all callers and all definitions.
(bfd_get_reloc_size): Make argument a const pointer.
(bfd_perform_relocation): Add error_message argument to hold
string set if return value if bfd_reloc_dangerous.  Changed all
callers.
(_bfd_final_link_relocate, _bfd_relocate_contents): New functions.
* section.c (asection): Renamed seclets_head and seclets_tail to
link_order_head and link_order_tail.
* targets.c (bfd_target): Replaced seclet argument with link_info
and link_order and symbols arguments in
bfd_get_relocated_section_contents.  Added symbols argument to
bfd_relax_section.  Removed bfd_seclet_link.  Added
bfd_link_hash_table_create, bfd_link_add_symbols and
bfd_final_link.
* libaout.h (struct aoutdata): Added external_syms,
external_sym_count, external_strings, sym_hashes fields.
(obj_aout_external_syms, obj_aout_external_sym_count,
obj_aout_external_strings, obj_aout_sym_hashes): New accessor
macros.
(WRITE_HEADERS): Only output symbols if outsymbols is not NULL.
* aoutx.h: Wrote new back end linker routines.
(translate_to_native_sym_flags): Return boolean value.  Don't use
bfd_error_vector.
(NAME(aout,write_syms)): Return boolean value.  Check return value
of translate_to_native_sym_flags and bfd_write.
* aout-target.h (final_link_callback): New function.
(MY_bfd_final_link): New function.
* aout-adobe.c (aout_adobe_write_object_contents): Check return
value of aout_32_write_syms.
* hp300hpux.c (MY(write_object_contents)): Likewise.
* i386lynx.c (WRITE_HEADERS): Likewise.
* libaout.h (WRITE_HEADERS): Likewise.
* bout.c: Changed functions to use link_info->callbacks rather
than bfd_error_vector, and link_orders rather than seclets.
* coff-alpha.c: Likewise.
* coff-h8300.c: Likewise.
* coff-h8500.c: Likewise.
* coff-sh.c: Likewise.
* coff-z8k.c: Likewise.
* elf32-hppa.c: Likewise.
* reloc16.c: Likewise.
* coff-alpha.c (alpha_ecoff_get_relocated_section_contents): Look
up _gp in the hash table rather than in outsymbols.
* coff-a29k.c (a29k_reloc): Pass errors back in new error_message
argument rather than printing them.
* coffcode.h (bfd_coff_reloc16_extra_cases): Take link_info and
link_order arguments rather than seclet.  Changed all uses and
definitions.
(bfd_coff_reloc16_estimate): Pass link_info arguments.  Changed
all uses and definitions.
* libcoff.h: Rebuilt.
* ecoff.c (ecoff_get_extr): If symbol is defined by linker, but
not by ECOFF, make it scAbs.
(ecoff_bfd_final_link): Renamed from ecoff_bfd_seclet_link and
rewritten.
* elf32-mips.c (mips_elf_final_link): Renamed from
mips_elf_seclet_link and rewritten.
* elf32-hppa.c (elf32_hppa_stub_description): Added link_info
field.
(new_stub, add_stub_by_name, hppa_elf_build_arg_reloc_stub,
hppa_elf_build_long_branch_stub, hppa_look_for_stubs_in_section):
Added link_info arguments.  Changed all callers.
* elfcode.h (elf_slurp_symbol_table): Don't quit if outsymbols is
not NULL.
* oasys.c (oasys_write_sections): Return boolean value rather than
using bfd_error_vector.
(oasys_write_object_contents): Check return value of
oasys_write_sections.
* hosts/std-host.h: Don't declare qsort or strtol.
* Makefile.in: Rebuild dependencies.
(BFD_LIBS): Removed seclet.o.  Added hash.o and linker.o.
(CFILES): Removed seclet.c.  Added hash.c and linker.c.
(HFILES): Removed seclet.h.  Added genlink.h.

29 files changed:
bfd/ChangeLog
bfd/aix386-core.c
bfd/aout-target.h
bfd/aoutf1.h
bfd/aoutx.h
bfd/bfd-in.h
bfd/bfd-in2.h
bfd/coff-a29k.c
bfd/coffgen.c
bfd/ecoff.c
bfd/elf.c
bfd/elf32-target.h
bfd/elf64-target.h
bfd/hosts/std-host.h
bfd/hppabsd-core.c [new file with mode: 0644]
bfd/hpux-core.c [new file with mode: 0644]
bfd/irix-core.c [new file with mode: 0644]
bfd/libaout.h
bfd/libbfd-in.h
bfd/libbfd.c
bfd/libbfd.h
bfd/libelf.h
bfd/osf-core.c [new file with mode: 0644]
bfd/ptrace-core.c [new file with mode: 0644]
bfd/reloc.c
bfd/section.c
bfd/srec.c
bfd/targets.c
bfd/trad-core.c

index a0d0f0b..182f3c5 100644 (file)
@@ -1,3 +1,110 @@
+Thu Dec 30 13:37:24 1993  Ian Lance Taylor  (ian@tweedledumb.cygnus.com)
+
+       Extensive changes to move the bulk of the linker into BFD so that
+       more efficient backend code can be written for specific object
+       files.  Only existing efficient backend is a.out.
+       * seclet.c, seclet.h: Removed.
+       * hash.c, linker.c, genlink.h: New files.
+       * bfd-in.h: Removed bfd_error_vector.  Declared hash table
+       structures and functions.
+       (JUMP_TABLE): Removed bfd_seclet_link, added
+       bfd_link_hash_table_create, bfd_link_add_symbols and
+       bfd_final_link.
+       * All backends: Changed accordingly.
+       * bfd-in2.h: Rebuilt.
+       * bfd.c (struct _bfd): Added link_next and archive_pass fields.
+       Removed ld_symbols field.
+       (bfd_nonrepresentable_section, bfd_undefined_symbol,
+       bfd_reloc_value_truncated, bfd_reloc_is_dangerous,
+       bfd_error_vector): Removed.
+       (bfd_default_error_trap, bfd_error_trap,
+       bfd_error_nonrepresentabltrap): Removed.
+       (bfd_get_relocated_section_contents): Pass link_info.  Pass
+       link_order instead of seclet.  Pass symbols.
+       (bfd_relax_section): Pass link_info.
+       (bfd_seclet_link): Removed.
+       (bfd_link_hash_table_create, bfd_link_add_symbols,
+       bfd_final_link): New macros.
+       * libbfd-in.h: If __GNUC__ is defined and alloca is not, define
+       alloca as __builtin_alloca.  Declare internal linking functions.
+       * libbfd.h: Rebuilt.
+       * libbfd.c (bfd_seek): Comment out fseek assertion.  It's worked
+       for months.
+       * reloc.c (reloc_howto_type): Added error_message argument to
+       special_function field.  Changed all callers and all definitions.
+       (bfd_get_reloc_size): Make argument a const pointer.
+       (bfd_perform_relocation): Add error_message argument to hold
+       string set if return value if bfd_reloc_dangerous.  Changed all
+       callers.
+       (_bfd_final_link_relocate, _bfd_relocate_contents): New functions.
+       * section.c (asection): Renamed seclets_head and seclets_tail to
+       link_order_head and link_order_tail.
+       * targets.c (bfd_target): Replaced seclet argument with link_info
+       and link_order and symbols arguments in
+       bfd_get_relocated_section_contents.  Added symbols argument to
+       bfd_relax_section.  Removed bfd_seclet_link.  Added
+       bfd_link_hash_table_create, bfd_link_add_symbols and
+       bfd_final_link.
+       * libaout.h (struct aoutdata): Added external_syms,
+       external_sym_count, external_strings, sym_hashes fields.
+       (obj_aout_external_syms, obj_aout_external_sym_count,
+       obj_aout_external_strings, obj_aout_sym_hashes): New accessor
+       macros.
+       (WRITE_HEADERS): Only output symbols if outsymbols is not NULL.
+       * aoutx.h: Wrote new back end linker routines.
+       (translate_to_native_sym_flags): Return boolean value.  Don't use
+       bfd_error_vector.
+       (NAME(aout,write_syms)): Return boolean value.  Check return value
+       of translate_to_native_sym_flags and bfd_write.
+       * aout-target.h (final_link_callback): New function.
+       (MY_bfd_final_link): New function.
+       * aout-adobe.c (aout_adobe_write_object_contents): Check return
+       value of aout_32_write_syms.
+       * hp300hpux.c (MY(write_object_contents)): Likewise.
+       * i386lynx.c (WRITE_HEADERS): Likewise.
+       * libaout.h (WRITE_HEADERS): Likewise.
+       * bout.c: Changed functions to use link_info->callbacks rather
+       than bfd_error_vector, and link_orders rather than seclets.
+       * coff-alpha.c: Likewise.
+       * coff-h8300.c: Likewise.
+       * coff-h8500.c: Likewise.
+       * coff-sh.c: Likewise.
+       * coff-z8k.c: Likewise.
+       * elf32-hppa.c: Likewise.
+       * reloc16.c: Likewise.
+       * coff-alpha.c (alpha_ecoff_get_relocated_section_contents): Look
+       up _gp in the hash table rather than in outsymbols.
+       * coff-a29k.c (a29k_reloc): Pass errors back in new error_message
+       argument rather than printing them.
+       * coffcode.h (bfd_coff_reloc16_extra_cases): Take link_info and
+       link_order arguments rather than seclet.  Changed all uses and
+       definitions.
+       (bfd_coff_reloc16_estimate): Pass link_info arguments.  Changed
+       all uses and definitions.
+       * libcoff.h: Rebuilt.
+       * ecoff.c (ecoff_get_extr): If symbol is defined by linker, but
+       not by ECOFF, make it scAbs.
+       (ecoff_bfd_final_link): Renamed from ecoff_bfd_seclet_link and
+       rewritten.
+       * elf32-mips.c (mips_elf_final_link): Renamed from
+       mips_elf_seclet_link and rewritten.
+       * elf32-hppa.c (elf32_hppa_stub_description): Added link_info
+       field.
+       (new_stub, add_stub_by_name, hppa_elf_build_arg_reloc_stub,
+       hppa_elf_build_long_branch_stub, hppa_look_for_stubs_in_section):
+       Added link_info arguments.  Changed all callers.
+       * elfcode.h (elf_slurp_symbol_table): Don't quit if outsymbols is
+       not NULL.
+       * oasys.c (oasys_write_sections): Return boolean value rather than
+       using bfd_error_vector.
+       (oasys_write_object_contents): Check return value of
+       oasys_write_sections.
+       * hosts/std-host.h: Don't declare qsort or strtol.
+       * Makefile.in: Rebuild dependencies.
+       (BFD_LIBS): Removed seclet.o.  Added hash.o and linker.o.
+       (CFILES): Removed seclet.c.  Added hash.c and linker.c.
+       (HFILES): Removed seclet.h.  Added genlink.h.
+
 Thu Dec 30 07:41:36 1993  Peter Schauer  (pes@regent.e-technik.tu-muenchen.de)
 
        * section.c (bfd_get_section_contents):  Return zero filled buffer
index 3701367..ac0bba6 100644 (file)
@@ -290,12 +290,16 @@ DEFUN(aix386_core_file_matches_executable_p, (core_bfd, exec_bfd),
        (bfd *, struct sec *))) bfd_void
 #define aix386_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents
 #define aix386_bfd_relax_section bfd_generic_relax_section
-#define aix386_bfd_seclet_link \
-  ((boolean (*) PARAMS ((bfd *, PTR, boolean))) bfd_false)
 #define aix386_bfd_reloc_type_lookup \
   ((CONST struct reloc_howto_struct *(*) PARAMS ((bfd *, bfd_reloc_code_real_type))) bfd_nullvoidptr)
 #define aix386_bfd_make_debug_symbol \
   ((asymbol *(*) PARAMS ((bfd *, void *, unsigned long))) bfd_nullvoidptr)
+#define aix386_bfd_link_hash_table_create \
+  ((struct bfd_link_hash_table *(*) PARAMS ((bfd *))) bfd_nullvoidptr)
+#define aix386_bfd_link_add_symbols \
+  ((boolean (*) PARAMS ((bfd *, struct bfd_link_info *))) bfd_false)
+#define aix386_bfd_final_link \
+  ((boolean (*) PARAMS ((bfd *, struct bfd_link_info *))) bfd_false)
 
 /* If somebody calls any byte-swapping routines, shoot them.  */
 void
index 8cf7429..70835c5 100644 (file)
@@ -1,5 +1,5 @@
 /* Define a target vector and some small routines for a variant of a.out.
-   Copyright (C) 1990-1991 Free Software Foundation, Inc.
+   Copyright (C) 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
 
 This file is part of BFD, the Binary File Descriptor library.
 
@@ -93,9 +93,16 @@ DEFUN(MY(object_p),(abfd),
     return 0;
   }
 
+#ifdef NO_SWAP_MAGIC
+  memcpy (&exec.a_info, exec_bytes.e_info, sizeof(exec.a_info));
+#else
   exec.a_info = bfd_h_get_32 (abfd, exec_bytes.e_info);
+#endif /* NO_SWAP_MAGIC */
 
   if (N_BADMAG (exec)) return 0;
+#ifdef MACHTYPE_OK
+  if (!(MACHTYPE_OK (N_MACHTYPE (exec)))) return 0;
+#endif
 
   NAME(aout,swap_exec_header_in)(abfd, &exec_bytes, &exec);
   target = NAME(aout,some_aout_object_p) (abfd, &exec, MY(callback));
@@ -199,6 +206,38 @@ static CONST struct aout_backend_data MY(backend_data) = {
 #define MY_backend_data &MY(backend_data)
 #endif
 
+#ifndef MY_bfd_final_link
+
+/* Final link routine.  We need to use a call back to get the correct
+   offsets in the output file.  */
+
+static void final_link_callback
+  PARAMS ((bfd *, file_ptr *, file_ptr *, file_ptr *));
+
+static void
+final_link_callback (abfd, ptreloff, pdreloff, psymoff)
+     bfd *abfd;
+     file_ptr *ptreloff;
+     file_ptr *pdreloff;
+     file_ptr *psymoff;
+{
+  struct internal_exec *execp = exec_hdr (abfd);
+
+  *ptreloff = N_TRELOFF (*execp);
+  *pdreloff = N_DRELOFF (*execp);
+  *psymoff = N_SYMOFF (*execp);
+}
+
+static boolean
+MY_bfd_final_link (abfd, info)
+     bfd *abfd;
+     struct bfd_link_info *info;
+{
+  return NAME(aout,final_link) (abfd, info, final_link_callback);
+}
+
+#endif
+
 /* We assume BFD generic archive files.  */
 #ifndef        MY_openr_next_archived_file
 #define        MY_openr_next_archived_file     bfd_generic_openr_next_archived_file
@@ -296,6 +335,9 @@ static CONST struct aout_backend_data MY(backend_data) = {
 #ifndef MY_print_symbol
 #define MY_print_symbol NAME(aout,print_symbol)
 #endif
+#ifndef MY_get_symbol_info
+#define MY_get_symbol_info NAME(aout,get_symbol_info)
+#endif
 #ifndef MY_get_lineno
 #define MY_get_lineno NAME(aout,get_lineno)
 #endif
@@ -314,20 +356,24 @@ static CONST struct aout_backend_data MY(backend_data) = {
 #ifndef MY_sizeof_headers
 #define MY_sizeof_headers NAME(aout,sizeof_headers)
 #endif
-#ifndef MY_bfd_debug_info_start
-#define MY_bfd_debug_info_start NAME(aout,bfd_debug_info_start)
+#ifndef MY_bfd_get_relocated_section_contents
+#define MY_bfd_get_relocated_section_contents \
+                       bfd_generic_get_relocated_section_contents
 #endif
-#ifndef MY_bfd_debug_info_end
-#define MY_bfd_debug_info_end NAME(aout,bfd_debug_info_end)
+#ifndef MY_bfd_relax_section
+#define MY_bfd_relax_section bfd_generic_relax_section
+#endif
+#ifndef MY_bfd_reloc_type_lookup
+#define MY_bfd_reloc_type_lookup NAME(aout,reloc_type_lookup)
 #endif
-#ifndef MY_bfd_debug_info_accumulat
-#define MY_bfd_debug_info_accumulat NAME(aout,bfd_debug_info_accumulat)
+#ifndef MY_bfd_make_debug_symbol
+#define MY_bfd_make_debug_symbol 0
 #endif
-#ifndef MY_reloc_howto_type_lookup
-#define MY_reloc_howto_type_lookup NAME(aout,reloc_type_lookup)
+#ifndef MY_bfd_link_hash_table_create
+#define MY_bfd_link_hash_table_create NAME(aout,link_hash_table_create)
 #endif
-#ifndef MY_make_debug_symbol
-#define MY_make_debug_symbol 0
+#ifndef MY_bfd_link_add_symbols
+#define MY_bfd_link_add_symbols NAME(aout,link_add_symbols)
 #endif
 
 /* Aout symbols normally have leading underscores */
@@ -335,6 +381,12 @@ static CONST struct aout_backend_data MY(backend_data) = {
 #define MY_symbol_leading_char '_'
 #endif
 
+/* Aout archives normally use spaces for padding */
+#ifndef AR_PAD_CHAR
+#define AR_PAD_CHAR ' '
+#endif
+
+#ifndef MY_BFD_TARGET
 bfd_target MY(vec) =
 {
   TARGETNAME,          /* name */
@@ -348,18 +400,26 @@ bfd_target MY(vec) =
 #endif
   (HAS_RELOC | EXEC_P |                /* object flags */
    HAS_LINENO | HAS_DEBUG |
-   HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
+   HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
   MY_symbol_leading_char,
-  ' ',                         /* ar_pad_char */
+  AR_PAD_CHAR,                 /* ar_pad_char */
   15,                          /* ar_max_namelen */
-  1,                           /* minimum alignment */
+  3,                           /* minimum alignment */
 #ifdef TARGET_IS_BIG_ENDIAN_P
-  _do_getb64, _do_putb64,      _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* data */
-  _do_getb64, _do_putb64,      _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* hdrs */
+  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+     bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+     bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
+  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+     bfd_getb32, bfd_getb_signed_32, bfd_putb32,
+     bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
 #else
-  _do_getl64, _do_putl64,      _do_getl32, _do_putl32, _do_getl16, _do_putl16, /* data */
-  _do_getl64, _do_putl64,      _do_getl32, _do_putl32, _do_getl16, _do_putl16, /* hdrs */
+  bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+     bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+     bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
+  bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+     bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+     bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
 #endif
     {_bfd_dummy_target, MY_object_p, /* bfd_check_format */
        bfd_generic_archive_p, MY_core_file_p},
@@ -368,36 +428,7 @@ bfd_target MY(vec) =
     {bfd_false, MY_write_object_contents, /* bfd_write_contents */
        _bfd_write_archive_contents, bfd_false},
 
-  MY_core_file_failing_command,
-  MY_core_file_failing_signal,
-  MY_core_file_matches_executable_p,
-  MY_slurp_armap,
-  MY_slurp_extended_name_table,
-  MY_truncate_arname,
-  MY_write_armap,
-  MY_close_and_cleanup,
-  MY_set_section_contents,
-  MY_get_section_contents,
-  MY_new_section_hook,
-  MY_get_symtab_upper_bound,
-  MY_get_symtab,
-  MY_get_reloc_upper_bound,
-  MY_canonicalize_reloc,
-  MY_make_empty_symbol,
-  MY_print_symbol,
-  MY_get_lineno,
-  MY_set_arch_mach,
-  MY_openr_next_archived_file,
-  MY_find_nearest_line,
-  MY_generic_stat_arch_elt,
-  MY_sizeof_headers,
-  MY_bfd_debug_info_start,
-  MY_bfd_debug_info_end,
-  MY_bfd_debug_info_accumulate,
-  bfd_generic_get_relocated_section_contents,
-  bfd_generic_relax_section,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,        /* COFF stuff?! */
-  MY_reloc_howto_type_lookup,
-  MY_make_debug_symbol,
+  JUMP_TABLE (MY),
   (PTR) MY_backend_data,
 };
+#endif /* MY_BFD_TARGET */
index 076b0f2..2f4b728 100644 (file)
@@ -1,5 +1,5 @@
 /* A.out "format 1" file handling code for BFD.
-   Copyright 1990, 1991, 1992 Free Software Foundation, Inc.
+   Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
    Written by Cygnus Support.
 
 This file is part of BFD, the Binary File Descriptor library.
@@ -30,8 +30,12 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "aout/ar.h"
 
 /* This is needed to reject a NewsOS file, e.g. in
-   gdb/testsuite/gdb.t10/crossload.exp.  */
-#define MACHTYPE_OK(mtype) ((mtype) == M_68010 || (mtype) == M_68020 \
+   gdb/testsuite/gdb.t10/crossload.exp. <kingdon@cygnus.com>
+   I needed to add M_UNKNOWN to recognize a 68000 object, so this will
+   probably no longer reject a NewsOS object.  <ian@cygnus.com>. */
+#define MACHTYPE_OK(mtype) ((mtype) == M_UNKNOWN \
+                           || (mtype) == M_68010 \
+                           || (mtype) == M_68020 \
                            || (mtype) == M_SPARC)
 
 /*
@@ -56,8 +60,6 @@ The name put into the target vector.
 
 */
 
-void (*bfd_error_trap)();
-
 /*SUPPRESS558*/
 /*SUPPRESS529*/
 
@@ -72,9 +74,9 @@ DEFUN(NAME(sunos,set_arch_mach), (abfd, machtype),
 
   case M_UNKNOWN:
       /* Some Sun3s make magic numbers without cpu types in them, so
-        we'll default to the 68020. */
+        we'll default to the 68000. */
     arch = bfd_arch_m68k;
-    machine = 68020;
+    machine = 68000;
     break;
     
   case M_68010:
@@ -95,6 +97,7 @@ DEFUN(NAME(sunos,set_arch_mach), (abfd, machtype),
     break;
     
   case M_386:
+  case M_386_DYNIX:
     arch = bfd_arch_i386;
     machine = 0;
     break;
index 1b096b2..57eeaa6 100644 (file)
@@ -93,17 +93,18 @@ DESCRIPTION
 |        HOST_TEXT_START_ADDR
 |        HOST_STACK_END_ADDR
 
-       in the file <<../include/sys/h-XXX.h>> (for your host).  These
-       values, plus the structures and macros defined in <<a.out.h>> on
+       in the file @file{../include/sys/h-@var{XXX}.h} (for your host).  These
+       values, plus the structures and macros defined in @file{a.out.h} on
        your host system, will produce a BFD target that will access
        ordinary a.out files on your host. To configure a new machine
-       to use <<host-aout.c>., specify:
+       to use @file{host-aout.c}, specify:
 
 |      TDEFAULTS = -DDEFAULT_VECTOR=host_aout_big_vec
 |      TDEPFILES= host-aout.o trad-core.o
 
-       in the <<config/mt-XXX>> file, and modify @file{configure.in} to use the
-       <<mt-XXX>> file (by setting "<<bfd_target=XXX>>") when your
+       in the @file{config/@var{XXX}.mt} file, and modify @file{configure.in}
+       to use the
+       @file{@var{XXX}.mt} file (by setting "<<bfd_target=XXX>>") when your
        configuration is selected.
 
 */
@@ -125,6 +126,7 @@ DESCRIPTION
 #include "bfd.h"
 #include <sysdep.h>
 #include <ansidecl.h>
+#include "bfdlink.h"
 
 struct external_exec;
 #include "libaout.h"
@@ -133,11 +135,9 @@ struct external_exec;
 #include "aout/stab_gnu.h"
 #include "aout/ar.h"
 
-extern void (*bfd_error_trap)();
-
 /*
 SUBSECTION
-       relocations
+       Relocations
 
 DESCRIPTION
        The file @file{aoutx.h} provides for both the @emph{standard}
@@ -156,7 +156,7 @@ DESCRIPTION
 
 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,7 +186,7 @@ reloc_howto_type howto_table_ext[] =
 /* 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 */
+  /* 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),
@@ -242,11 +242,9 @@ DEFUN(NAME(aout,reloc_type_lookup),(abfd,code),
       }
 }
 
-extern bfd_error_vector_type bfd_error_vector;
-
 /*
 SUBSECTION
-       Internal Entry Points
+       Internal entry points
 
 DESCRIPTION
        @file{aoutx.h} exports several routines for accessing the
@@ -681,29 +679,199 @@ DEFUN(NAME(aout,set_arch_mach),(abfd, arch, machine),
   return (*aout_backend_info(abfd)->set_sizes) (abfd);
 }
 
+static void
+adjust_o_magic (abfd, execp)
+     bfd *abfd;
+     struct internal_exec *execp;
+{
+  file_ptr pos = adata (abfd).exec_bytes_size;
+  bfd_vma vma = 0;
+  int pad = 0;
+
+  /* Text.  */
+  obj_textsec(abfd)->filepos = pos;
+  pos += obj_textsec(abfd)->_raw_size;
+  vma += obj_textsec(abfd)->_raw_size;
+
+  /* Data.  */
+  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;
+#endif
+      obj_textsec(abfd)->_raw_size += pad;
+      pos += pad;
+      vma += pad;
+      obj_datasec(abfd)->vma = 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 0
+      pad = align_power (vma, obj_bsssec(abfd)->alignment_power) - vma;
+#endif
+      obj_datasec(abfd)->_raw_size += pad;
+      pos += pad;
+      vma += pad;
+      obj_bsssec(abfd)->vma = vma;
+    }
+  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;
+  N_SET_MAGIC (*execp, OMAGIC);
+}
+
+static void
+adjust_z_magic (abfd, execp)
+     bfd *abfd;
+     struct internal_exec *execp;
+{
+  bfd_size_type data_pad, text_pad;
+  file_ptr text_end;
+  CONST struct aout_backend_data *abdp;
+  int ztih;                    /* Nonzero if text includes exec header.  */
+  bfd_vma data_vma;
+  
+  abdp = aout_backend_info (abfd);
+
+  /* Text.  */
+  ztih = abdp && abdp->text_includes_header;
+  obj_textsec(abfd)->filepos = (ztih
+                               ? adata(abfd).exec_bytes_size
+                               : adata(abfd).page_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));
+  /* Could take strange alignment of text section into account here?  */
+  
+  /* Find start of data.  */
+  text_end = obj_textsec(abfd)->filepos + obj_textsec(abfd)->_raw_size;
+  text_pad = BFD_ALIGN (text_end, adata(abfd).page_size) - text_end;
+  obj_textsec(abfd)->_raw_size += text_pad;
+  text_end += text_pad;
+
+  /* Data.  */
+  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);
+    }
+  data_vma = obj_datasec(abfd)->vma;
+  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;
+    }
+  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;
+  if (ztih && (!abdp || (abdp && !abdp->exec_header_not_counted)))
+    execp->a_text += adata(abfd).exec_bytes_size;
+  N_SET_MAGIC (*execp, ZMAGIC);
+  /* Spec says data section should be rounded up to page boundary.  */
+  /* If extra space in page is left after data section, fudge data
+     in the header so that the bss section looks smaller by that
+     amount.  We'll start the bss section there, and lie to the OS.  */
+  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);
+  execp->a_bss = (data_pad > obj_bsssec(abfd)->_raw_size) ? 0 :
+    obj_bsssec(abfd)->_raw_size - data_pad;
+}
+
+static void
+adjust_n_magic (abfd, execp)
+     bfd *abfd;
+     struct internal_exec *execp;
+{
+  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;
+  else
+    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;
+  
+  /* 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;
+
+  /* BSS.  */
+  if (!obj_bsssec(abfd)->user_set_vma)
+    obj_bsssec(abfd)->vma = vma;
+  else
+    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;
+  N_SET_MAGIC (*execp, NMAGIC);
+}
+
 boolean
-DEFUN (NAME (aout,adjust_sizes_and_vmas), (abfd, text_size, text_end),
+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)
 {
   struct internal_exec *execp = exec_hdr (abfd);
+
   if ((obj_textsec (abfd) == NULL) || (obj_datasec (abfd) == NULL))
     {
       bfd_error = invalid_operation;
       return false;
     }
   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);
 
   *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
-   * 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. */
+     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
+     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. */
 
   /* 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
@@ -712,17 +880,15 @@ DEFUN (NAME (aout,adjust_sizes_and_vmas), (abfd, text_size, text_end),
      other magic, that it was a little hard for me to understand.  I think
      I understand it better now, but I haven't time to do the cleanup this
      minute.  */
-  if (adata(abfd).magic == undecided_magic)
-    {
-      if (abfd->flags & D_PAGED)
-       /* Whether or not WP_TEXT is set -- let D_PAGED override.  */
-       /* @@ What about QMAGIC?  */
-       adata(abfd).magic = z_magic;
-      else if (abfd->flags & WP_TEXT)
-       adata(abfd).magic = n_magic;
-      else
-       adata(abfd).magic = o_magic;
-    }
+
+  if (abfd->flags & D_PAGED)
+    /* Whether or not WP_TEXT is set -- let D_PAGED override.  */
+    /* @@ What about QMAGIC?  */
+    adata(abfd).magic = z_magic;
+  else if (abfd->flags & WP_TEXT)
+    adata(abfd).magic = n_magic;
+  else
+    adata(abfd).magic = o_magic;
 
 #ifdef BFD_AOUT_DEBUG /* requires gcc2 */
 #if __GNUC__ >= 2
@@ -736,167 +902,39 @@ DEFUN (NAME (aout,adjust_sizes_and_vmas), (abfd, text_size, text_end),
              }
              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)
     {
     case o_magic:
-      {
-       file_ptr pos = adata (abfd).exec_bytes_size;
-       bfd_vma vma = 0;
-       int pad = 0;
-
-       obj_textsec(abfd)->filepos = pos;
-       pos += obj_textsec(abfd)->_raw_size;
-       vma += obj_textsec(abfd)->_raw_size;
-       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;
-#endif
-           obj_textsec(abfd)->_raw_size += pad;
-           pos += pad;
-           vma += pad;
-           obj_datasec(abfd)->vma = vma;
-         }
-       obj_datasec(abfd)->filepos = pos;
-       pos += obj_datasec(abfd)->_raw_size;
-       vma += obj_datasec(abfd)->_raw_size;
-       if (!obj_bsssec(abfd)->user_set_vma)
-         {
-#if 0
-           pad = align_power (vma, obj_bsssec(abfd)->alignment_power) - vma;
-#endif
-           obj_datasec(abfd)->_raw_size += pad;
-           pos += pad;
-           vma += pad;
-           obj_bsssec(abfd)->vma = vma;
-         }
-       obj_bsssec(abfd)->filepos = pos;
-       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);
-      }
+      adjust_o_magic (abfd, execp);
       break;
     case z_magic:
-      {
-       bfd_size_type data_pad, text_pad;
-       file_ptr text_end;
-       CONST struct aout_backend_data *abdp;
-       int ztih;
-       bfd_vma data_vma;
-
-       abdp = aout_backend_info (abfd);
-       ztih = abdp && abdp->text_includes_header;
-       obj_textsec(abfd)->filepos = (ztih
-                                     ? adata(abfd).exec_bytes_size
-                                     : adata(abfd).page_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));
-       /* Could take strange alignment of text section into account here?  */
-
-       /* Find start of data.  */
-       text_end = obj_textsec(abfd)->filepos + obj_textsec(abfd)->_raw_size;
-       text_pad = BFD_ALIGN (text_end, adata(abfd).page_size) - text_end;
-       obj_textsec(abfd)->_raw_size += text_pad;
-       text_end += text_pad;
-
-       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);
-         }
-       data_vma = obj_datasec(abfd)->vma;
-       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;
-         }
-       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;
-       if (ztih && (!abdp || (abdp && !abdp->exec_header_not_counted)))
-         execp->a_text += adata(abfd).exec_bytes_size;
-       N_SET_MAGIC (*execp, ZMAGIC);
-       /* Spec says data section should be rounded up to page boundary.  */
-       /* If extra space in page is left after data section, fudge data
-          in the header so that the bss section looks smaller by that
-          amount.  We'll start the bss section there, and lie to the OS.  */
-       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;
-
-       if (!obj_bsssec(abfd)->user_set_vma)
-         obj_bsssec(abfd)->vma = (obj_datasec(abfd)->vma
-                                  + obj_datasec(abfd)->_raw_size);
-       if (data_pad > obj_bsssec(abfd)->_raw_size)
-         execp->a_bss = 0;
-       else
-         execp->a_bss = obj_bsssec(abfd)->_raw_size - data_pad;
-      }
+      adjust_z_magic (abfd, execp);
       break;
     case n_magic:
-      {
-       file_ptr pos = adata(abfd).exec_bytes_size;
-       bfd_vma vma = 0;
-       int pad;
-
-       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;
-       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;
-
-       if (!obj_bsssec(abfd)->user_set_vma)
-         obj_bsssec(abfd)->vma = vma;
-       else
-         vma = obj_bsssec(abfd)->vma;
-      }
-      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);
+      adjust_n_magic (abfd, execp);
       break;
     default:
       abort ();
     }
+
 #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_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;
 }
 
@@ -1163,7 +1201,6 @@ DEFUN (translate_from_native_sym_flags, (sym_pointer, cache_ptr, abfd),
              break;
            default:
            case N_ABS:
-
              cache_ptr->symbol.section = &bfd_abs_section;
              break;
            }
@@ -1231,7 +1268,7 @@ DEFUN (translate_from_native_sym_flags, (sym_pointer, cache_ptr, abfd),
 
 
 
-static void
+static boolean
 DEFUN(translate_to_native_sym_flags,(sym_pointer, cache_ptr, abfd),
      struct external_nlist *sym_pointer AND
      asymbol *cache_ptr AND
@@ -1270,19 +1307,8 @@ DEFUN(translate_to_native_sym_flags,(sym_pointer, cache_ptr, abfd),
     sym_pointer->e_type[0] = (N_UNDF | N_EXT);
   }
   else {
-    if (cache_ptr->section->output_section)
-      {
-
-       bfd_error_vector.nonrepresentable_section(abfd,
-                                                 bfd_get_output_section(cache_ptr)->name);
-      }
-    else
-      {
-       bfd_error_vector.nonrepresentable_section(abfd,
-                                                 cache_ptr->section->name);
-
-      }
-
+    bfd_error = bfd_error_nonrepresentable_section;
+    return false;
   }
   /* Turn the symbol from section relative to absolute again */
 
@@ -1312,6 +1338,8 @@ DEFUN(translate_to_native_sym_flags,(sym_pointer, cache_ptr, abfd),
   }
 
   PUT_WORD(abfd, value, sym_pointer->e_value);
+
+  return true;
 }
 \f
 /* Native-level interface to symbols. */
@@ -1804,7 +1832,7 @@ emit_strtab (abfd, tab)
     } */
 }
 
-void
+boolean
 DEFUN(NAME(aout,write_syms),(abfd),
       bfd *abfd)
 {
@@ -1838,9 +1866,12 @@ DEFUN(NAME(aout,write_syms),(abfd),
          bfd_h_put_8(abfd, 0, nsp.e_type);
        }
 
-      translate_to_native_sym_flags (&nsp, g, abfd);
+      if (! translate_to_native_sym_flags (&nsp, g, abfd))
+       return false;
 
-      bfd_write((PTR)&nsp,1,EXTERNAL_NLIST_SIZE, abfd);
+      if (bfd_write((PTR)&nsp,1,EXTERNAL_NLIST_SIZE, abfd)
+         != EXTERNAL_NLIST_SIZE)
+       return false;
 
       /* NB: `KEEPIT' currently overlays `flags', so set this only
         here, at the end.  */
@@ -1848,6 +1879,8 @@ DEFUN(NAME(aout,write_syms),(abfd),
     }
 
   emit_strtab (abfd, &strtab);
+
+  return true;
 }
 
 \f
@@ -2562,3 +2595,1704 @@ DEFUN(NAME(aout,sizeof_headers),(abfd, execable),
 {
   return adata(abfd).exec_bytes_size;
 }
+\f
+/* a.out link code.  */
+
+/* a.out linker hash table entries.  */
+
+struct aout_link_hash_entry
+{
+  struct bfd_link_hash_entry root;
+  /* Symbol index in output file.  */
+  int indx;
+};
+
+/* a.out linker hash table.  */
+
+struct aout_link_hash_table
+{
+  struct bfd_link_hash_table root;
+};
+
+static struct bfd_hash_entry *aout_link_hash_newfunc
+  PARAMS ((struct bfd_hash_entry *entry,
+          struct bfd_hash_table *table,
+          const char *string));
+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));
+static boolean aout_link_add_symbols
+  PARAMS ((bfd *, struct bfd_link_info *));
+
+/* Routine to create an entry in an a.out link hash table.  */
+
+static struct bfd_hash_entry *
+aout_link_hash_newfunc (entry, table, string)
+     struct bfd_hash_entry *entry;
+     struct bfd_hash_table *table;
+     const char *string;
+{
+  struct aout_link_hash_entry *ret = (struct aout_link_hash_entry *) entry;
+
+  /* Allocate the structure if it has not already been allocated by a
+     subclass.  */
+  if (ret == (struct aout_link_hash_entry *) NULL)
+    ret = ((struct aout_link_hash_entry *)
+          bfd_hash_allocate (table, sizeof (struct aout_link_hash_entry)));
+
+  /* Call the allocation method of the superclass.  */
+  ret = ((struct aout_link_hash_entry *)
+        _bfd_link_hash_newfunc ((struct bfd_hash_entry *) ret,
+                                table, string));
+
+  /* Set local fields.  */
+  ret->indx = -1;
+
+  return (struct bfd_hash_entry *) ret;
+}
+
+/* Create an a.out link hash table.  */
+
+struct bfd_link_hash_table *
+NAME(aout,link_hash_table_create) (abfd)
+     bfd *abfd;
+{
+  struct aout_link_hash_table *ret;
+
+  ret = ((struct aout_link_hash_table *)
+        bfd_xmalloc (sizeof (struct aout_link_hash_table)));
+  if (! _bfd_link_hash_table_init (&ret->root, abfd,
+                                  aout_link_hash_newfunc))
+    {
+      free (ret);
+      return (struct bfd_link_hash_table *) NULL;
+    }
+  return &ret->root;
+}
+
+/* Look up an entry in an a.out link hash table.  */
+
+#define aout_link_hash_lookup(table, string, create, copy, follow) \
+  ((struct aout_link_hash_entry *) \
+   bfd_link_hash_lookup (&(table)->root, (string), (create), (copy), (follow)))
+
+/* Traverse an a.out link hash table.  */
+
+#define aout_link_hash_traverse(table, func, info)                     \
+  (bfd_link_hash_traverse                                              \
+   (&(table)->root,                                                    \
+    (boolean (*) PARAMS ((struct bfd_link_hash_entry *, PTR))) (func), \
+    (info)))
+
+/* Get the a.out link hash table from the info structure.  This is
+   just a cast.  */
+
+#define aout_hash_table(p) ((struct aout_link_hash_table *) ((p)->hash))
+
+/* Given an a.out BFD, add symbols to the global hash table as
+   appropriate.  */
+
+boolean
+NAME(aout,link_add_symbols) (abfd, info)
+     bfd *abfd;
+     struct bfd_link_info *info;
+{
+  switch (bfd_get_format (abfd))
+    {
+    case bfd_object:
+      return aout_link_add_object_symbols (abfd, info);
+    case bfd_archive:
+      return _bfd_generic_link_add_archive_symbols
+       (abfd, info, aout_link_check_archive_element);
+    default:
+      bfd_error = wrong_format;
+      return false;
+    }
+}
+
+/* Add symbols from an a.out object file.  */
+
+static boolean
+aout_link_add_object_symbols (abfd, info)
+     bfd *abfd;
+     struct bfd_link_info *info;
+{
+  if (! aout_link_get_symbols (abfd))
+    return false;
+  if (! aout_link_add_symbols (abfd, info))
+    return false;
+  if (! info->keep_memory)
+    {
+      if (! aout_link_free_symbols (abfd))
+       return false;
+    }
+  return true;
+}
+
+/* Check a single archive element to see if we need to include it in
+   the link.  *PNEEDED is set according to whether this element is
+   needed in the link or not.  This is called from
+   _bfd_generic_link_add_archive_symbols.  */
+
+static boolean
+aout_link_check_archive_element (abfd, info, pneeded)
+     bfd *abfd;
+     struct bfd_link_info *info;
+     boolean *pneeded;
+{
+  if (! aout_link_get_symbols (abfd))
+    return false;
+
+  if (! aout_link_check_ar_symbols (abfd, info, pneeded))
+    return false;
+
+  if (*pneeded)
+    {
+      if (! aout_link_add_symbols (abfd, info))
+       return false;
+    }
+
+  /* We keep around the symbols even if we aren't going to use this
+     object file, because we may want to reread it.  This doesn't
+     waste too much memory, because it isn't all that common to read
+     an archive element but not need it.  */
+  if (! info->keep_memory)
+    {
+      if (! aout_link_free_symbols (abfd))
+       return false;
+    }
+
+  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 bfd_xmalloc 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 *)
+         bfd_xmalloc ((size_t) count * EXTERNAL_NLIST_SIZE));
+
+  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 *) bfd_xmalloc ((size_t) stringsize);
+
+  /* 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
+aout_link_free_symbols (abfd)
+     bfd *abfd;
+{
+  if (obj_aout_external_syms (abfd) != (struct external_nlist *) NULL)
+    {
+      free ((PTR) obj_aout_external_syms (abfd));
+      obj_aout_external_syms (abfd) = (struct external_nlist *) NULL;
+    }
+  if (obj_aout_external_strings (abfd) != (char *) NULL)
+    {
+      free ((PTR) obj_aout_external_strings (abfd));
+      obj_aout_external_strings (abfd) = (char *) NULL;
+    }
+  return true;
+}
+
+/* Look through the internal symbols to see if this object file should
+   be included in the link.  We should include this object file if it
+   defines any symbols which are currently undefined.  If this object
+   file defines a common symbol, then we may adjust the size of the
+   known symbol but we do not include the object file in the link
+   (unless there is some other reason to include it).  */
+
+static boolean
+aout_link_check_ar_symbols (abfd, info, pneeded)
+     bfd *abfd;
+     struct bfd_link_info *info;
+     boolean *pneeded;
+{
+  register struct external_nlist *p;
+  struct external_nlist *pend;
+  char *strings;
+
+  *pneeded = false;
+
+  /* Look through all the symbols.  */
+  p = obj_aout_external_syms (abfd);
+  pend = p + obj_aout_external_sym_count (abfd);
+  strings = obj_aout_external_strings (abfd);
+  for (; p < pend; p++)
+    {
+      int type = bfd_h_get_8 (abfd, p->e_type);
+      const char *name;
+      struct bfd_link_hash_entry *h;
+
+      /* Ignore symbols that are not externally visible.  */
+      if ((type & N_EXT) == 0)
+       continue;
+
+      name = strings + GET_WORD (abfd, p->e_strx);
+      h = bfd_link_hash_lookup (info->hash, name, false, false, true);
+
+      /* We are only interested in symbols that are currently
+        undefined or common.  */
+      if (h == (struct bfd_link_hash_entry *) NULL
+         || (h->type != bfd_link_hash_undefined
+             && h->type != bfd_link_hash_common))
+       continue;
+
+      if ((type & (N_TEXT | N_DATA | N_BSS)) != 0)
+       {
+         /* 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
+                int a;
+            and this object file from the archive includes
+                int a = 5;
+            In such a case we must include this object file.  */
+         if (! (*info->callbacks->add_archive_element) (info, abfd, name))
+           return false;
+         *pneeded = true;
+         return true;
+       }
+
+      if (type == (N_EXT | N_UNDF))
+       {
+         bfd_vma value;
+
+         value = GET_WORD (abfd, p->e_value);
+         if (value != 0)
+           {
+             /* This symbol is common in the object from the archive
+                file.  */
+             if (h->type == bfd_link_hash_undefined)
+               {
+                 bfd *symbfd;
+
+                 symbfd = h->u.undef.abfd;
+                 if (symbfd == (bfd *) NULL)
+                   {
+                     /* This symbol was created as undefined from
+                        outside BFD.  We assume that we should link
+                        in the object file.  This is done for the -u
+                        option in the linker.  */
+                     if (! (*info->callbacks->add_archive_element) (info,
+                                                                    abfd,
+                                                                    name))
+                       return false;
+                     *pneeded = true;
+                     return true;
+                   }
+                 /* 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.size = value;
+                 h->u.c.section = bfd_make_section_old_way (symbfd,
+                                                            "COMMON");
+               }
+             else
+               {
+                 /* Adjust the size of the common symbol if
+                    necessary.  */
+                 if (value > h->u.c.size)
+                   h->u.c.size = value;
+               }
+           }
+       }
+    }
+
+  /* We do not need this object file.  */
+  return true;
+}
+
+/* Add all symbols from an object file to the hash table.  */
+
+static boolean
+aout_link_add_symbols (abfd, info)
+     bfd *abfd;
+     struct bfd_link_info *info;
+{
+  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;
+
+  sym_count = obj_aout_external_sym_count (abfd);
+  strings = obj_aout_external_strings (abfd);
+  if (info->keep_memory)
+    copy = false;
+  else
+    copy = true;
+
+
+  /* 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 *))));
+  obj_aout_sym_hashes (abfd) = sym_hash;
+
+  p = obj_aout_external_syms (abfd);
+  pend = p + sym_count;
+  for (; p < pend; p++, sym_hash++)
+    {
+      int type;
+      const char *name;
+      bfd_vma value;
+      asection *section;
+      flagword flags;
+      const char *string;
+
+      *sym_hash = NULL;
+
+      type = bfd_h_get_8 (abfd, p->e_type);
+
+      /* Ignore debugging symbols.  */
+      if ((type & N_STAB) != 0)
+       continue;
+
+      /* Ignore symbols that are not external.  */
+      if ((type & N_EXT) == 0
+         && type != N_WARNING
+         && type != N_SETA
+         && type != N_SETT
+         && type != N_SETD
+         && type != N_SETB)
+       {
+         /* If this is an N_INDR symbol we must skip the next entry,
+            which is the symbol to indirect to (actually, an N_INDR
+            symbol without N_EXT set is pretty useless).  */
+         if (type == N_INDR)
+           ++p;
+         continue;
+       }
+
+      /* Ignore N_FN symbols (these appear to have N_EXT set).  */
+      if (type == N_FN)
+       continue;
+
+      name = strings + GET_WORD (abfd, p->e_strx);
+      value = GET_WORD (abfd, p->e_value);
+      flags = BSF_GLOBAL;
+      string = NULL;
+      switch (type)
+       {
+       default:
+         abort ();
+       case N_UNDF | N_EXT:
+         if (value != 0)
+           section = &bfd_com_section;
+         else
+           section = &bfd_und_section;
+         break;
+       case N_ABS | N_EXT:
+         section = &bfd_abs_section;
+         break;
+       case N_TEXT | N_EXT:
+         section = obj_textsec (abfd);
+         value -= bfd_get_section_vma (abfd, section);
+         break;
+       case N_DATA | N_EXT:
+         section = obj_datasec (abfd);
+         value -= bfd_get_section_vma (abfd, section);
+         break;
+       case N_BSS | N_EXT:
+         section = obj_bsssec (abfd);
+         value -= bfd_get_section_vma (abfd, section);
+         break;
+       case N_INDR | N_EXT:
+         /* An indirect symbol.  The next symbol is the symbol
+            which this one really is.  */
+         BFD_ASSERT (p + 1 < pend);
+         ++p;
+         string = strings + GET_WORD (abfd, p->e_strx);
+         section = &bfd_ind_section;
+         flags |= BSF_INDIRECT;
+         break;
+       case N_COMM | N_EXT:
+         section = &bfd_com_section;
+         break;
+       case N_SETA:
+         section = &bfd_abs_section;
+         flags |= BSF_CONSTRUCTOR;
+         break;
+       case N_SETT:
+         section = obj_textsec (abfd);
+         flags |= BSF_CONSTRUCTOR;
+         value -= bfd_get_section_vma (abfd, section);
+         break;
+       case N_SETD:
+         section = obj_datasec (abfd);
+         flags |= BSF_CONSTRUCTOR;
+         value -= bfd_get_section_vma (abfd, section);
+         break;
+       case N_SETB:
+         section = obj_bsssec (abfd);
+         flags |= BSF_CONSTRUCTOR;
+         value -= bfd_get_section_vma (abfd, section);
+         break;
+       case N_WARNING:
+         /* A warning symbol.  The next symbol is the one to warn
+            about.  */
+         BFD_ASSERT (p + 1 < pend);
+         ++p;
+         string = name;
+         name = strings + GET_WORD (abfd, p->e_strx);
+         section = &bfd_und_section;
+         flags |= BSF_WARNING;
+         break;
+       }
+
+      if (! (_bfd_generic_link_add_one_symbol
+            (info, abfd, name, flags, section, value, string, copy,
+             (struct bfd_link_hash_entry **) sym_hash)))
+       return false;
+    }
+
+  return true;
+}
+
+/* During the final link step we need to pass around a bunch of
+   information, so we do it in an instance of this structure.  */
+
+struct aout_final_link_info
+{
+  /* General link information.  */
+  struct bfd_link_info *info;
+  /* Output bfd.  */
+  bfd *output_bfd;
+  /* Reloc file positions.  */
+  file_ptr treloff, dreloff;
+  /* File position of symbols.  */
+  file_ptr symoff;
+  /* String table.  */
+  struct stringtab_data strtab;
+};
+
+static boolean aout_link_input_bfd
+  PARAMS ((struct aout_final_link_info *, bfd *input_bfd));
+static boolean aout_link_write_symbols
+  PARAMS ((struct aout_final_link_info *, bfd *input_bfd, int *symbol_map));
+static boolean aout_link_write_other_symbol
+  PARAMS ((struct aout_link_hash_entry *, PTR));
+static boolean aout_link_input_section
+  PARAMS ((struct aout_final_link_info *, bfd *input_bfd,
+          asection *input_section, file_ptr *reloff_ptr,
+          bfd_size_type rel_size, int *symbol_map));
+static boolean aout_link_input_section_std
+  PARAMS ((struct aout_final_link_info *, bfd *input_bfd,
+          asection *input_section, struct reloc_std_external *,
+          bfd_size_type rel_size, bfd_byte *contents, int *symbol_map));
+static boolean aout_link_input_section_ext
+  PARAMS ((struct aout_final_link_info *, bfd *input_bfd,
+          asection *input_section, struct reloc_ext_external *,
+          bfd_size_type rel_size, bfd_byte *contents, int *symbol_map));
+static INLINE asection *aout_reloc_index_to_section
+  PARAMS ((bfd *, int));
+
+/* 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
+   in the output.  Also, each section in ABFD should point to a list
+   of bfd_link_order structures which list all the input sections for
+   the output section.  */
+
+boolean
+NAME(aout,final_link) (abfd, info, callback)
+     bfd *abfd;
+     struct bfd_link_info *info;
+     void (*callback) PARAMS ((bfd *, file_ptr *, file_ptr *, file_ptr *));
+{
+  struct aout_final_link_info aout_info;
+  register bfd *sub;
+  bfd_size_type text_size;
+  file_ptr text_end;
+  register struct bfd_link_order *p;
+  asection *o;
+
+  aout_info.info = info;
+  aout_info.output_bfd = abfd;
+
+  if (! info->relocateable)
+    {
+      exec_hdr (abfd)->a_trsize = 0;
+      exec_hdr (abfd)->a_drsize = 0;
+    }
+  else
+    {
+      bfd_size_type trsize, drsize;
+
+      /* Count up the relocation sizes.  */
+      trsize = 0;
+      drsize = 0;
+      for (sub = info->input_bfds; sub != (bfd *) NULL; sub = sub->link_next)
+       {
+         if (bfd_get_flavour (abfd) == bfd_target_aout_flavour)
+           {
+             trsize += exec_hdr (sub)->a_trsize;
+             drsize += exec_hdr (sub)->a_drsize;
+           }
+         else
+           {
+             /* FIXME: We need to identify the .text and .data sections
+                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 ();
+           }
+       }
+      exec_hdr (abfd)->a_trsize = trsize;
+      exec_hdr (abfd)->a_drsize = drsize;
+    }
+
+  /* Adjust the section sizes and vmas according to the magic number.
+     This sets a_text, a_data and a_bss in the exec_hdr and sets the
+     filepos for each section.  */
+  if (! NAME(aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end))
+    return false;
+
+  /* The relocation and symbol file positions differ among a.out
+     targets.  We are passed a callback routine from the backend
+     specific code to handle this.
+     FIXME: At this point we do not know how much space the symbol
+     table will require.  This will not work for any (nonstandard)
+     a.out target that needs to know the symbol table size before it
+     can compute the relocation file positions.  This may or may not
+     be the case for the hp300hpux target, for example.  */
+  (*callback) (abfd, &aout_info.treloff, &aout_info.dreloff,
+              &aout_info.symoff);
+  obj_textsec (abfd)->rel_filepos = aout_info.treloff;
+  obj_datasec (abfd)->rel_filepos = aout_info.dreloff;
+  obj_sym_filepos (abfd) = aout_info.symoff;
+
+  /* We keep a count of the symbols as we output them.  */
+  obj_aout_external_sym_count (abfd) = 0;
+
+  /* We accumulate the string table as we write out the symbols.  */
+  stringtab_init (&aout_info.strtab);
+
+  /* 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
+     information into the output file.  Unfortunately, that will
+     probably use too much memory.  Another method would be to step
+     through everything that composes the text section and write it
+     out, and then everything that composes the data section and write
+     it out, and then write out the relocs, and then write out the
+     symbols.  Unfortunately, that requires reading stuff from each
+     input file several times, and we will not be able to keep all the
+     input files open simultaneously, and reopening them will be slow.
+
+     What we do is basically process one input file at a time.  We do
+     everything we need to do with an input file once--copy over the
+     section contents, handle the relocation information, and write
+     out the symbols--and then we throw away the information we read
+     from it.  This approach requires a lot of lseeks of the output
+     file, which is unfortunate but still faster than reopening a lot
+     of files.
+
+     We use the output_has_begun field of the input BFDs to see
+     whether we have already handled it.  */
+  for (sub = info->input_bfds; sub != (bfd *) NULL; sub = sub->link_next)
+    sub->output_has_begun = false;
+
+  for (o = abfd->sections; o != (asection *) NULL; o = o->next)
+    {
+      bfd *input_bfd;
+
+      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
+         switch (p->type)
+           {
+           case bfd_indirect_link_order:
+             input_bfd = p->u.indirect.section->owner;
+             if (bfd_get_flavour (input_bfd) == bfd_target_aout_flavour)
+               {
+                 if (! input_bfd->output_has_begun)
+                   {
+                     if (! aout_link_input_bfd (&aout_info, input_bfd))
+                       return false;
+                     input_bfd->output_has_begun = true;
+                   }
+               }
+             else
+               {
+                 /* FIXME.  */
+                 abort ();
+               }
+             break;
+           default:
+             if (! _bfd_default_link_order (abfd, info, o, p))
+               return false;
+           }
+       }
+    }
+
+  /* Write out any symbols that we have not already written out.  */
+  aout_link_hash_traverse (aout_hash_table (info),
+                          aout_link_write_other_symbol,
+                          (PTR) &aout_info);
+
+  /* Update the header information.  */
+  abfd->symcount = obj_aout_external_sym_count (abfd);
+  exec_hdr (abfd)->a_syms = abfd->symcount * EXTERNAL_NLIST_SIZE;
+  obj_str_filepos (abfd) = obj_sym_filepos (abfd) + exec_hdr (abfd)->a_syms;
+  obj_textsec (abfd)->reloc_count =
+    exec_hdr (abfd)->a_trsize / obj_reloc_entry_size (abfd);
+  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)
+    return false;
+  emit_strtab (abfd, &aout_info.strtab);
+
+  return true;
+}
+
+/* Link an a.out input BFD into the output file.  */
+
+static boolean
+aout_link_input_bfd (finfo, input_bfd)
+     struct aout_final_link_info *finfo;
+     bfd *input_bfd;
+{
+  bfd_size_type sym_count;
+  int *symbol_map;
+
+  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))
+    return false;
+
+  sym_count = obj_aout_external_sym_count (input_bfd);
+  symbol_map = (int *) alloca ((size_t) sym_count * sizeof (int));
+
+  /* Write out the symbols and get a map of the new indices.  */
+  if (! aout_link_write_symbols (finfo, input_bfd, symbol_map))
+    return false;
+
+  /* Relocate and write out the sections.  */
+  if (! aout_link_input_section (finfo, input_bfd,
+                                obj_textsec (input_bfd),
+                                &finfo->treloff,
+                                exec_hdr (input_bfd)->a_trsize,
+                                symbol_map)
+      || ! aout_link_input_section (finfo, input_bfd,
+                                   obj_datasec (input_bfd),
+                                   &finfo->dreloff,
+                                   exec_hdr (input_bfd)->a_drsize,
+                                   symbol_map))
+    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
+     strings in the hash table point into them.  */
+  if (! finfo->info->keep_memory)
+    {
+      if (! aout_link_free_symbols (input_bfd))
+       return false;
+    }
+
+  return true;
+}
+
+/* Adjust and write out the symbols for an a.out file.  Set the new
+   symbol indices into a symbol_map.  */
+
+static boolean
+aout_link_write_symbols (finfo, input_bfd, symbol_map)
+     struct aout_final_link_info *finfo;
+     bfd *input_bfd;
+     int *symbol_map;
+{
+  bfd *output_bfd;
+  bfd_size_type sym_count;
+  char *strings;
+  enum bfd_link_strip strip;
+  enum bfd_link_discard discard;
+  struct external_nlist *output_syms;
+  struct external_nlist *outsym;
+  register struct external_nlist *sym;
+  struct external_nlist *sym_end;
+  struct aout_link_hash_entry **sym_hash;
+  boolean pass;
+
+  output_bfd = finfo->output_bfd;
+  sym_count = obj_aout_external_sym_count (input_bfd);
+  strings = obj_aout_external_strings (input_bfd);
+  strip = finfo->info->strip;
+  discard = finfo->info->discard;
+  output_syms = ((struct external_nlist *)
+                alloca ((size_t) (sym_count + 1) * EXTERNAL_NLIST_SIZE));
+  outsym = output_syms;
+
+  /* First write out a symbol for this object file, unless we are
+     discarding such symbols.  */
+  if (strip != strip_all
+      && (strip != strip_some
+         || bfd_hash_lookup (finfo->info->keep_hash, input_bfd->filename,
+                             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);
+      PUT_WORD (output_bfd,
+               add_to_stringtab (output_bfd, input_bfd->filename,
+                                 &finfo->strtab),
+               outsym->e_strx);
+      PUT_WORD (output_bfd,
+               bfd_get_section_vma (input_bfd, obj_textsec (input_bfd)),
+               outsym->e_value);
+      ++obj_aout_external_sym_count (output_bfd);
+      ++outsym;
+    }
+
+  pass = false;
+  sym = obj_aout_external_syms (input_bfd);
+  sym_end = sym + sym_count;
+  sym_hash = obj_aout_sym_hashes (input_bfd);
+  for (; sym < sym_end; sym++, sym_hash++, symbol_map++)
+    {
+      const char *name;
+      int type;
+      boolean skip;
+      asection *symsec;
+      bfd_vma val = 0;
+
+      *symbol_map = -1;
+
+      type = bfd_h_get_8 (input_bfd, sym->e_type);
+      name = strings + GET_WORD (input_bfd, sym->e_strx);
+
+      if (pass)
+       {
+         /* Pass this symbol through.  */
+         val = GET_WORD (input_bfd, sym->e_value);
+         pass = false;
+       }
+      else
+       {
+         struct aout_link_hash_entry *h;
+
+         /* 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. */
+         h = *sym_hash;
+
+         /* If the symbol has already been written out, skip it.  */
+         if (h != (struct aout_link_hash_entry *) NULL
+             && h->root.written)
+           {
+             *symbol_map = h->indx;
+             continue;
+           }
+
+         /* See if we are stripping this symbol.  */
+         skip = false;
+         switch (strip)
+           {
+           case strip_none:
+             break;
+           case strip_debugger:
+             if ((type & N_STAB) != 0)
+               skip = true;
+             break;
+           case strip_some:
+             if (bfd_hash_lookup (finfo->info->keep_hash, name, false, false)
+                 == NULL)
+               skip = true;
+             break;
+           case strip_all:
+             skip = true;
+             break;
+           }
+         if (skip)
+           {
+             if (h != (struct aout_link_hash_entry *) NULL)
+               h->root.written = true;
+             continue;
+           }
+
+         /* Get the value of the symbol.  */
+         if ((type & N_TYPE) == N_TEXT)
+           symsec = obj_textsec (input_bfd);
+         else if ((type & N_TYPE) == N_DATA)
+           symsec = obj_datasec (input_bfd);
+         else if ((type & N_TYPE) == N_BSS)
+           symsec = obj_bsssec (input_bfd);
+         else if ((type & N_TYPE) == N_ABS)
+           symsec = &bfd_abs_section;
+         else if ((type & N_TYPE) == N_INDR
+                  || type == N_WARNING)
+           {
+             /* Pass the next symbol through unchanged.  */
+             pass = true;
+             val = GET_WORD (input_bfd, sym->e_value);
+             symsec = NULL;
+           }
+         else if ((type & N_STAB) != 0)
+           {
+             val = GET_WORD (input_bfd, sym->e_value);
+             symsec = NULL;
+           }
+         else
+           {
+             if (h == (struct aout_link_hash_entry *) NULL)
+               val = 0;
+             else if (h->root.type == bfd_link_hash_defined)
+               {
+                 asection *output_section;
+
+                 /* This case means a common symbol which was turned
+                    into a defined symbol.  */
+                 output_section = h->root.u.def.section->output_section;
+                 BFD_ASSERT (output_section == &bfd_abs_section
+                             || output_section->owner == output_bfd);
+                 val = (h->root.u.def.value
+                        + bfd_get_section_vma (output_bfd, output_section)
+                        + h->root.u.def.section->output_offset);
+
+                 /* Get the correct type based on the section.  If
+                    this is a constructed set, force it to be
+                    globally visible.  */
+                 if (type == N_SETT
+                     || type == N_SETD
+                     || type == N_SETB
+                     || type == N_SETA)
+                   type |= N_EXT;
+
+                 type &=~ N_TYPE;
+
+                 if (output_section == obj_textsec (output_bfd))
+                   type |= N_TEXT;
+                 else if (output_section == obj_datasec (output_bfd))
+                   type |= N_DATA;
+                 else if (output_section == obj_bsssec (output_bfd))
+                   type |= N_BSS;
+                 else
+                   type |= N_ABS;
+               }
+             else if (h->root.type == bfd_link_hash_common)
+               val = h->root.u.c.size;
+             else
+               val = 0;
+
+             symsec = NULL;
+           }
+         if (symsec != (asection *) NULL)
+           val = (symsec->output_section->vma
+                  + symsec->output_offset
+                  + (GET_WORD (input_bfd, sym->e_value)
+                     - symsec->vma));
+
+         /* If this is a global symbol set the written flag, and if
+            it is a local symbol see if we should discard it.  */
+         if (h != (struct aout_link_hash_entry *) NULL)
+           {
+             h->root.written = true;
+             h->indx = obj_aout_external_sym_count (output_bfd);
+           }
+         else
+           {
+             switch (discard)
+               {
+               case discard_none:
+                 break;
+               case discard_l:
+                 if (*name == *finfo->info->lprefix
+                     && (finfo->info->lprefix_len == 1
+                         || strncmp (name, finfo->info->lprefix,
+                                     finfo->info->lprefix_len) == 0))
+                   skip = true;
+                 break;
+               case discard_all:
+                 skip = true;
+                 break;
+               }
+             if (skip)
+               {
+                 pass = false;
+                 continue;
+               }
+           }
+       }
+
+      /* 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);
+      PUT_WORD (output_bfd,
+               add_to_stringtab (output_bfd, name, &finfo->strtab),
+               outsym->e_strx);
+      PUT_WORD (output_bfd, val, outsym->e_value);
+      *symbol_map = obj_aout_external_sym_count (output_bfd);
+      ++obj_aout_external_sym_count (output_bfd);
+      ++outsym;
+    }
+
+  /* Write out the output symbols we have just constructed.  */
+  if (outsym > output_syms)
+    {
+      bfd_size_type outsym_count;
+
+      if (bfd_seek (output_bfd, finfo->symoff, SEEK_SET) != 0)
+       return false;
+      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;
+      finfo->symoff += outsym_count * EXTERNAL_NLIST_SIZE;
+    }
+
+  return true;
+}
+
+/* Write out a symbol that was not associated with an a.out input
+   object.  */
+
+static boolean
+aout_link_write_other_symbol (h, data)
+     struct aout_link_hash_entry *h;
+     PTR data;
+{
+  struct aout_final_link_info *finfo = (struct aout_final_link_info *) data;
+  bfd *output_bfd;
+  int type;
+  bfd_vma val;
+  struct external_nlist outsym;
+
+  if (h->root.written)
+    return true;
+
+  output_bfd = finfo->output_bfd;
+
+  switch (h->root.type)
+    {
+    default:
+    case bfd_link_hash_new:
+      abort ();
+      /* Avoid variable not initialized warnings.  */
+      return true;
+    case bfd_link_hash_undefined:
+      type = N_UNDF | N_EXT;
+      val = 0;
+      break;
+    case bfd_link_hash_defined:
+      {
+       asection *sec;
+
+       sec = h->root.u.def.section;
+       BFD_ASSERT (sec == &bfd_abs_section
+                   || sec->owner == output_bfd);
+       if (sec == obj_textsec (output_bfd))
+         type = N_TEXT | N_EXT;
+       else if (sec == obj_datasec (output_bfd))
+         type = N_DATA | N_EXT;
+       else if (sec == obj_bsssec (output_bfd))
+         type = N_BSS | N_EXT;
+       else
+         type = N_ABS | N_EXT;
+       val = (h->root.u.def.value
+              + sec->output_section->vma
+              + sec->output_offset);
+      }
+      break;
+    case bfd_link_hash_common:
+      type = N_UNDF | N_EXT;
+      val = h->root.u.c.size;
+      break;
+    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.  */
+      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);
+  PUT_WORD (output_bfd,
+           add_to_stringtab (output_bfd, h->root.root.string, &finfo->strtab),
+           outsym.e_strx);
+  PUT_WORD (output_bfd, val, outsym.e_value);
+
+  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)
+    {
+      /* FIXME: No way to handle errors.  */
+      abort ();
+    }
+
+  finfo->symoff += EXTERNAL_NLIST_SIZE;
+  h->indx = obj_aout_external_sym_count (output_bfd);
+  ++obj_aout_external_sym_count (output_bfd);
+
+  return true;
+}
+
+/* Link an a.out section into the output file.  */
+
+static boolean
+aout_link_input_section (finfo, input_bfd, input_section, reloff_ptr,
+                        rel_size, symbol_map)
+     struct aout_final_link_info *finfo;
+     bfd *input_bfd;
+     asection *input_section;
+     file_ptr *reloff_ptr;
+     bfd_size_type rel_size;
+     int *symbol_map;
+{
+  bfd_size_type input_size;
+  bfd_byte *contents;
+  PTR relocs;
+
+  /* Get the section contents.  */
+  input_size = bfd_section_size (input_bfd, input_section);
+  contents = (bfd_byte *) alloca (input_size);
+  if (! bfd_get_section_contents (input_bfd, input_section, contents,
+                                 (file_ptr) 0, input_size))
+    return false;
+
+  /* Read in the relocs.  */
+  relocs = (PTR) alloca (rel_size);
+  if (bfd_seek (input_bfd, input_section->rel_filepos, SEEK_SET) != 0
+      || bfd_read (relocs, 1, rel_size, input_bfd) != rel_size)
+    return false;
+
+  /* Relocate the section contents.  */
+  if (obj_reloc_entry_size (input_bfd) == RELOC_STD_SIZE)
+    {
+      if (! aout_link_input_section_std (finfo, input_bfd, input_section,
+                                        (struct reloc_std_external *) relocs,
+                                        rel_size, contents, symbol_map))
+       return false;
+    }
+  else
+    {
+      if (! aout_link_input_section_ext (finfo, input_bfd, input_section,
+                                        (struct reloc_ext_external *) relocs,
+                                        rel_size, contents, symbol_map))
+       return false;
+    }
+
+  /* Write out the section contents.  */
+  if (! bfd_set_section_contents (finfo->output_bfd,
+                                 input_section->output_section,
+                                 contents, 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 (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)
+       return false;
+      *reloff_ptr += rel_size;
+
+      /* Assert that the relocs have not run into the symbols, and
+        that if these are the text relocs they 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;
+}
+
+/* Get the section corresponding to a reloc index.  */
+
+static INLINE asection *
+aout_reloc_index_to_section (abfd, indx)
+     bfd *abfd;
+     int indx;
+{
+  switch (indx & N_TYPE)
+    {
+    case N_TEXT:
+      return obj_textsec (abfd);
+    case N_DATA:
+      return obj_datasec (abfd);
+    case N_BSS:
+      return obj_bsssec (abfd);
+    case N_ABS:
+      return &bfd_abs_section;
+    default:
+      abort ();
+    }
+}
+
+/* Relocate an a.out section using standard a.out relocs.  */
+
+static boolean
+aout_link_input_section_std (finfo, input_bfd, input_section, relocs,
+                            rel_size, contents, symbol_map)
+     struct aout_final_link_info *finfo;
+     bfd *input_bfd;
+     asection *input_section;
+     struct reloc_std_external *relocs;
+     bfd_size_type rel_size;
+     bfd_byte *contents;
+     int *symbol_map;
+{
+  bfd *output_bfd;
+  boolean relocateable;
+  struct external_nlist *syms;
+  char *strings;
+  struct aout_link_hash_entry **sym_hashes;
+  bfd_size_type reloc_count;
+  register struct reloc_std_external *rel;
+  struct reloc_std_external *rel_end;
+
+  output_bfd = finfo->output_bfd;
+
+  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);
+
+  relocateable = finfo->info->relocateable;
+  syms = obj_aout_external_syms (input_bfd);
+  strings = obj_aout_external_strings (input_bfd);
+  sym_hashes = obj_aout_sym_hashes (input_bfd);
+
+  reloc_count = rel_size / RELOC_STD_SIZE;
+  rel = relocs;
+  rel_end = rel + reloc_count;
+  for (; rel < rel_end; rel++)
+    {
+      bfd_vma r_addr;
+      int r_index;
+      int r_extern;
+      int r_pcrel;
+      int r_baserel;
+      int r_jmptable;
+      int r_relative;
+      int r_length;
+      int howto_idx;
+      bfd_vma relocation;
+      bfd_reloc_status_type r;
+
+      r_addr = GET_SWORD (input_bfd, rel->r_address);
+
+      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_idx = r_length + 4 * r_pcrel + 8 * r_baserel;
+      BFD_ASSERT (howto_idx < TABLE_SIZE (howto_table_std));
+      BFD_ASSERT (r_jmptable == 0);
+      BFD_ASSERT (r_relative == 0);
+
+      if (relocateable)
+       {
+         /* We are generating a relocateable output file, and must
+            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)
+               {
+                 asection *output_section;
+
+                 /* Change the r_extern value.  */
+                 if (output_bfd->xvec->header_byteorder_big_p)
+                   rel->r_type[0] &=~ RELOC_STD_BITS_EXTERN_BIG;
+                 else
+                   rel->r_type[0] &=~ RELOC_STD_BITS_EXTERN_LITTLE;
+
+                 /* Compute a new r_index.  */
+                 output_section = h->root.u.def.section->output_section;
+                 if (output_section == obj_textsec (output_bfd))
+                   r_index = N_TEXT;
+                 else if (output_section == obj_datasec (output_bfd))
+                   r_index = N_DATA;
+                 else if (output_section == obj_bsssec (output_bfd))
+                   r_index = N_BSS;
+                 else
+                   r_index = N_ABS;
+
+                 /* Add the symbol value and the section VMA to the
+                    addend stored in the contents.  */
+                 relocation = (h->root.u.def.value
+                               + output_section->vma
+                               + h->root.u.def.section->output_offset);
+               }
+             else
+               {
+                 /* We must change r_index according to the symbol
+                    map.  */
+                 r_index = symbol_map[r_index];
+
+                 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;
+                   }
+
+                 relocation = 0;
+               }
+
+             /* Write out the new r_index value.  */
+             if (output_bfd->xvec->header_byteorder_big_p)
+               {
+                 rel->r_index[0] = r_index >> 16;
+                 rel->r_index[1] = r_index >> 8;
+                 rel->r_index[2] = r_index;
+               }
+             else
+               {
+                 rel->r_index[2] = r_index >> 16;
+                 rel->r_index[1] = r_index >> 8;
+                 rel->r_index[0] = r_index;
+               }
+           }
+         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);
+           }
+
+         /* Change the address of the relocation.  */
+         PUT_WORD (output_bfd,
+                   r_addr + input_section->output_offset,
+                   rel->r_address);
+
+         /* Adjust a PC relative relocation by removing the reference
+            to the original address in the section and then including
+            the reference to the new address.  */
+         if (r_pcrel)
+           {
+             relocation += input_section->vma;
+             relocation -= (input_section->output_section->vma
+                            + input_section->output_offset);
+           }
+
+         if (relocation == 0)
+           r = bfd_reloc_ok;
+         else
+           r = _bfd_relocate_contents (howto_table_std + howto_idx,
+                                       input_bfd, relocation,
+                                       contents + r_addr);
+       }
+      else
+       {
+         /* We are generating an executable, and must do a full
+            relocation.  */
+         if (r_extern)
+           {
+             struct aout_link_hash_entry *h;
+
+             h = sym_hashes[r_index];
+             if (h != (struct aout_link_hash_entry *) NULL
+                 && h->root.type == bfd_link_hash_defined)
+               {
+                 relocation = (h->root.u.def.value
+                               + h->root.u.def.section->output_section->vma
+                               + h->root.u.def.section->output_offset);
+               }
+             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;
+                 relocation = 0;
+               }
+           }
+         else
+           {
+             asection *section;
+
+             section = aout_reloc_index_to_section (input_bfd, r_index);
+             relocation = (section->output_section->vma
+                           + section->output_offset
+                           - section->vma);
+           }
+
+
+         r = _bfd_final_link_relocate (howto_table_std + howto_idx,
+                                       input_bfd, input_section,
+                                       contents, r_addr, relocation,
+                                       (bfd_vma) 0);
+       }
+
+      if (r != bfd_reloc_ok)
+       {
+         switch (r)
+           {
+           default:
+           case bfd_reloc_outofrange:
+             abort ();
+           case bfd_reloc_overflow:
+             if (! ((*finfo->info->callbacks->reloc_overflow)
+                    (finfo->info, input_bfd, input_section, r_addr)))
+               return false;
+             break;
+           }
+       }
+    }
+
+  return true;
+}
+
+/* Relocate an a.out section using extended a.out relocs.  */
+
+static boolean
+aout_link_input_section_ext (finfo, input_bfd, input_section, relocs,
+                            rel_size, contents, symbol_map)
+     struct aout_final_link_info *finfo;
+     bfd *input_bfd;
+     asection *input_section;
+     struct reloc_ext_external *relocs;
+     bfd_size_type rel_size;
+     bfd_byte *contents;
+     int *symbol_map;
+{
+  bfd *output_bfd;
+  boolean relocateable;
+  struct external_nlist *syms;
+  char *strings;
+  struct aout_link_hash_entry **sym_hashes;
+  bfd_size_type reloc_count;
+  register struct reloc_ext_external *rel;
+  struct reloc_ext_external *rel_end;
+
+  output_bfd = finfo->output_bfd;
+
+  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);
+
+  relocateable = finfo->info->relocateable;
+  syms = obj_aout_external_syms (input_bfd);
+  strings = obj_aout_external_strings (input_bfd);
+  sym_hashes = obj_aout_sym_hashes (input_bfd);
+
+  reloc_count = rel_size / RELOC_EXT_SIZE;
+  rel = relocs;
+  rel_end = rel + reloc_count;
+  for (; rel < rel_end; rel++)
+    {
+      bfd_vma r_addr;
+      int r_index;
+      int r_extern;
+      int r_type;
+      bfd_vma r_addend;
+      bfd_vma relocation;
+
+      r_addr = GET_SWORD (input_bfd, rel->r_address);
+
+      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_EXT_BITS_EXTERN_BIG));
+         r_type   = ((rel->r_type[0] & RELOC_EXT_BITS_TYPE_BIG)
+                     >> RELOC_EXT_BITS_TYPE_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_EXT_BITS_EXTERN_LITTLE));
+         r_type   = ((rel->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE)
+                     >> RELOC_EXT_BITS_TYPE_SH_LITTLE);
+       }
+
+      r_addend = GET_SWORD (input_bfd, rel->r_addend);
+
+      if (relocateable)
+       {
+         /* We are generating a relocateable output file, and must
+            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)
+               {
+                 asection *output_section;
+
+                 /* Change the r_extern value.  */
+                 if (output_bfd->xvec->header_byteorder_big_p)
+                   rel->r_type[0] &=~ RELOC_EXT_BITS_EXTERN_BIG;
+                 else
+                   rel->r_type[0] &=~ RELOC_EXT_BITS_EXTERN_LITTLE;
+
+                 /* Compute a new r_index.  */
+                 output_section = h->root.u.def.section->output_section;
+                 if (output_section == obj_textsec (output_bfd))
+                   r_index = N_TEXT;
+                 else if (output_section == obj_datasec (output_bfd))
+                   r_index = N_DATA;
+                 else if (output_section == obj_bsssec (output_bfd))
+                   r_index = N_BSS;
+                 else
+                   r_index = N_ABS;
+
+                 /* Add the symbol value and the section VMA to the
+                    addend.  */
+                 relocation = (h->root.u.def.value
+                               + output_section->vma
+                               + h->root.u.def.section->output_offset);
+               }
+             else
+               {
+                 /* We must change r_index according to the symbol
+                    map.  */
+                 r_index = symbol_map[r_index];
+
+                 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;
+                   }
+
+                 relocation = 0;
+               }
+
+             /* Write out the new r_index value.  */
+             if (output_bfd->xvec->header_byteorder_big_p)
+               {
+                 rel->r_index[0] = r_index >> 16;
+                 rel->r_index[1] = r_index >> 8;
+                 rel->r_index[2] = r_index;
+               }
+             else
+               {
+                 rel->r_index[2] = r_index >> 16;
+                 rel->r_index[1] = r_index >> 8;
+                 rel->r_index[0] = r_index;
+               }
+           }
+         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);
+           }
+
+         /* Adjust a PC relative relocation by removing the reference
+            to the original address in the section and then including
+            the reference to the new address.  */
+         if (howto_table_ext[r_type].pc_relative
+             && ! howto_table_ext[r_type].pcrel_offset)
+           {
+             relocation += input_section->vma;
+             relocation -= (input_section->output_section->vma
+                            + input_section->output_offset);
+           }
+
+         /* Change the addend if necessary.  */
+         if (relocation != 0)
+           PUT_WORD (output_bfd, r_addend + relocation, rel->r_addend);
+
+         /* Change the address of the relocation.  */
+         PUT_WORD (output_bfd,
+                   r_addr + input_section->output_offset,
+                   rel->r_address);
+       }
+      else
+       {
+         bfd_reloc_status_type r;
+
+         /* We are generating an executable, and must do a full
+            relocation.  */
+         if (r_extern)
+           {
+             struct aout_link_hash_entry *h;
+
+             h = sym_hashes[r_index];
+             if (h != (struct aout_link_hash_entry *) NULL
+                 && h->root.type == bfd_link_hash_defined)
+               {
+                 relocation = (h->root.u.def.value
+                               + h->root.u.def.section->output_section->vma
+                               + h->root.u.def.section->output_offset);
+               }
+             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;
+                 relocation = 0;
+               }
+           }
+         else
+           {
+             asection *section;
+
+             section = aout_reloc_index_to_section (input_bfd, r_index);
+             relocation = (section->output_section->vma
+                           + section->output_offset
+                           - section->vma);
+           }
+
+         BFD_ASSERT (r_type >= 0
+                     && r_type < TABLE_SIZE (howto_table_ext));
+
+         r = _bfd_final_link_relocate (howto_table_ext + r_type,
+                                       input_bfd, input_section,
+                                       contents, r_addr, relocation,
+                                       r_addend);
+         if (r != bfd_reloc_ok)
+           {
+             switch (r)
+               {
+               default:
+               case bfd_reloc_outofrange:
+                 abort ();
+               case bfd_reloc_overflow:
+                 if (! ((*finfo->info->callbacks->reloc_overflow)
+                        (finfo->info, input_bfd, input_section, r_addr)))
+                   return false;
+                 break;
+               }
+           }
+       }
+    }
+
+  return true;
+}
index 1b44503..810e803 100644 (file)
@@ -114,8 +114,8 @@ typedef unsigned HOST_64_BIT uint64_type;
 #if !defined (uint64_type) && defined (__GNUC__)
 #define uint64_type unsigned long long
 #define int64_type long long
-#define uint64_typeLOW(x) (unsigned long)(((x) & 0xffffffff))
-#define uint64_typeHIGH(x) (unsigned long)(((x) >> 32) & 0xffffffff)
+#define uint64_typeLOW(x) ((unsigned long)(((x) & 0xffffffff)))
+#define uint64_typeHIGH(x) ((unsigned long)(((x) >> 32) & 0xffffffff))
 #endif
 
 typedef unsigned HOST_64_BIT bfd_vma;
@@ -123,9 +123,9 @@ typedef HOST_64_BIT bfd_signed_vma;
 typedef unsigned HOST_64_BIT bfd_size_type;
 typedef unsigned HOST_64_BIT symvalue;
 #define fprintf_vma(s,x) \
-               fprintf(s,"%08x%08x", uint64_typeHIGH(x), uint64_typeLOW(x))
+               fprintf(s,"%08lx%08lx", uint64_typeHIGH(x), uint64_typeLOW(x))
 #define sprintf_vma(s,x) \
-               sprintf(s,"%08x%08x", uint64_typeHIGH(x), uint64_typeLOW(x))
+               sprintf(s,"%08lx%08lx", uint64_typeHIGH(x), uint64_typeLOW(x))
 #else /* not BFD64  */
 
 /* Represent a target address.  Also used as a generic unsigned type
@@ -286,41 +286,32 @@ typedef struct sec *sec_ptr;
 
 typedef struct stat stat_type; 
 \f
-/** Error handling */
-
-typedef enum bfd_error {
-             no_error = 0, system_call_error, invalid_target,
-             wrong_format, invalid_operation, no_memory,
-             no_symbols, no_relocation_info,
-             no_more_archived_files, malformed_archive,
-             symbol_not_found, file_not_recognized,
-             file_ambiguously_recognized, no_contents,
-             bfd_error_nonrepresentable_section,
-             no_debug_section, bad_value,
-
-             /* An input file is shorter than expected.  */
-             file_truncated,
-             
-             invalid_error_code} bfd_ec;
+/* Error handling */
 
-extern bfd_ec bfd_error;
-struct reloc_cache_entry;
-struct bfd_seclet;
-
-
-typedef struct bfd_error_vector {
-  void (* nonrepresentable_section ) PARAMS ((CONST bfd  *CONST abfd,
-                                             CONST char *CONST name));
-  void (* undefined_symbol) PARAMS ((CONST struct reloc_cache_entry *rel,
-                                    CONST struct bfd_seclet *sec));
-  void (* reloc_value_truncated) PARAMS ((CONST struct
-                                         reloc_cache_entry *rel,
-                                         struct bfd_seclet *sec));
+typedef enum bfd_error
+{
+  no_error = 0,
+  system_call_error,
+  invalid_target,
+  wrong_format,
+  invalid_operation,
+  no_memory,
+  no_symbols,
+  no_relocation_info,
+  no_more_archived_files,
+  malformed_archive,
+  symbol_not_found,
+  file_not_recognized,
+  file_ambiguously_recognized,
+  no_contents,
+  bfd_error_nonrepresentable_section,
+  no_debug_section,
+  bad_value,
+  file_truncated,
+  invalid_error_code
+} bfd_ec;
 
-  void (* reloc_dangerous) PARAMS ((CONST struct reloc_cache_entry *rel,
-                                   CONST struct bfd_seclet *sec));
-  
-} bfd_error_vector_type;
+extern bfd_ec bfd_error;
 
 CONST char *bfd_errmsg PARAMS ((bfd_ec error_tag));
 void bfd_perror PARAMS ((CONST char *message));
@@ -346,6 +337,86 @@ typedef struct _symbol_info
   CONST char *stab_name;
 } symbol_info;
 \f
+/* Hash table routines.  There is no way to free up a hash table.  */
+
+/* An element in the hash table.  Most uses will actually use a larger
+   structure, and an instance of this will be the first field.  */
+
+struct bfd_hash_entry
+{
+  /* Next entry for this hash code.  */
+  struct bfd_hash_entry *next;
+  /* String being hashed.  */
+  const char *string;
+  /* Hash code.  This is the full hash code, not the index into the
+     table.  */
+  unsigned long hash;
+};
+
+/* A hash table.  */
+
+struct bfd_hash_table
+{
+  /* The hash array.  */
+  struct bfd_hash_entry **table;
+  /* The number of slots in the hash table.  */
+  unsigned int size;
+  /* A function used to create new elements in the hash table.  The
+     first entry is itself a pointer to an element.  When this
+     function is first invoked, this pointer will be NULL.  However,
+     having the pointer permits a hierarchy of method functions to be
+     built each of which calls the function in the superclass.  Thus
+     each function should be written to allocate a new block of memory
+     only if the argument is NULL.  */
+  struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *,
+                                            struct bfd_hash_table *,
+                                            const char *));
+  /* An obstack for this hash table.  */
+  struct obstack memory;
+};
+
+/* Initialize a hash table.  */
+extern boolean bfd_hash_table_init
+  PARAMS ((struct bfd_hash_table *,
+          struct bfd_hash_entry *(*) (struct bfd_hash_entry *,
+                                      struct bfd_hash_table *,
+                                      const char *)));
+
+/* Initialize a hash table specifying a size.  */
+extern boolean bfd_hash_table_init_n
+  PARAMS ((struct bfd_hash_table *,
+          struct bfd_hash_entry *(*) (struct bfd_hash_entry *,
+                                      struct bfd_hash_table *,
+                                      const char *),
+          unsigned int size));
+
+/* Free up a hash table.  */
+extern void bfd_hash_table_free PARAMS ((struct bfd_hash_table *));
+
+/* Look up a string in a hash table.  If CREATE is true, a new entry
+   will be created for this string if one does not already exist.  The
+   COPY argument must be true if this routine should copy the string
+   into newly allocated memory when adding an entry.  */
+extern struct bfd_hash_entry *bfd_hash_lookup
+  PARAMS ((struct bfd_hash_table *, const char *, boolean create,
+          boolean copy));
+
+/* Base method for creating a hash table entry.  */
+extern struct bfd_hash_entry *bfd_hash_newfunc
+  PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *,
+          const char *));
+
+/* Grab some space for a hash table entry.  */
+extern PTR bfd_hash_allocate PARAMS ((struct bfd_hash_table *, size_t));
+
+/* Traverse a hash table in a random order, calling a function on each
+   element.  If the function returns false, the traversal stops.  The
+   INFO argument is passed to the function.  */
+extern void bfd_hash_traverse PARAMS ((struct bfd_hash_table *,
+                                      boolean (*) (struct bfd_hash_entry *,
+                                                   PTR),
+                                      PTR info));
+\f
 /* The code that implements targets can initialize a jump table with this
    macro.  It must name all its routines the same way (a prefix plus
    the standard routine suffix), or it must #define the routines that
@@ -406,9 +477,11 @@ CAT(NAME,_bfd_debug_info_end),\
 CAT(NAME,_bfd_debug_info_accumulate),\
 CAT(NAME,_bfd_get_relocated_section_contents),\
 CAT(NAME,_bfd_relax_section),\
-CAT(NAME,_bfd_seclet_link),\
 CAT(NAME,_bfd_reloc_type_lookup),\
-CAT(NAME,_bfd_make_debug_symbol)
+CAT(NAME,_bfd_make_debug_symbol),\
+CAT(NAME,_bfd_link_hash_table_create),\
+CAT(NAME,_bfd_link_add_symbols),\
+CAT(NAME,_bfd_final_link)
 
 #define COFF_SWAP_TABLE (PTR) &bfd_coff_std_swap_table
 
index 52a29b1..c5905a9 100644 (file)
@@ -286,41 +286,32 @@ typedef struct sec *sec_ptr;
 
 typedef struct stat stat_type; 
 \f
-/** Error handling */
-
-typedef enum bfd_error {
-             no_error = 0, system_call_error, invalid_target,
-             wrong_format, invalid_operation, no_memory,
-             no_symbols, no_relocation_info,
-             no_more_archived_files, malformed_archive,
-             symbol_not_found, file_not_recognized,
-             file_ambiguously_recognized, no_contents,
-             bfd_error_nonrepresentable_section,
-             no_debug_section, bad_value,
-
-             /* An input file is shorter than expected.  */
-             file_truncated,
-             
-             invalid_error_code} bfd_ec;
+/* Error handling */
 
-extern bfd_ec bfd_error;
-struct reloc_cache_entry;
-struct bfd_seclet;
-
-
-typedef struct bfd_error_vector {
-  void (* nonrepresentable_section ) PARAMS ((CONST bfd  *CONST abfd,
-                                             CONST char *CONST name));
-  void (* undefined_symbol) PARAMS ((CONST struct reloc_cache_entry *rel,
-                                    CONST struct bfd_seclet *sec));
-  void (* reloc_value_truncated) PARAMS ((CONST struct
-                                         reloc_cache_entry *rel,
-                                         struct bfd_seclet *sec));
+typedef enum bfd_error
+{
+  no_error = 0,
+  system_call_error,
+  invalid_target,
+  wrong_format,
+  invalid_operation,
+  no_memory,
+  no_symbols,
+  no_relocation_info,
+  no_more_archived_files,
+  malformed_archive,
+  symbol_not_found,
+  file_not_recognized,
+  file_ambiguously_recognized,
+  no_contents,
+  bfd_error_nonrepresentable_section,
+  no_debug_section,
+  bad_value,
+  file_truncated,
+  invalid_error_code
+} bfd_ec;
 
-  void (* reloc_dangerous) PARAMS ((CONST struct reloc_cache_entry *rel,
-                                   CONST struct bfd_seclet *sec));
-  
-} bfd_error_vector_type;
+extern bfd_ec bfd_error;
 
 CONST char *bfd_errmsg PARAMS ((bfd_ec error_tag));
 void bfd_perror PARAMS ((CONST char *message));
@@ -346,6 +337,86 @@ typedef struct _symbol_info
   CONST char *stab_name;
 } symbol_info;
 \f
+/* Hash table routines.  There is no way to free up a hash table.  */
+
+/* An element in the hash table.  Most uses will actually use a larger
+   structure, and an instance of this will be the first field.  */
+
+struct bfd_hash_entry
+{
+  /* Next entry for this hash code.  */
+  struct bfd_hash_entry *next;
+  /* String being hashed.  */
+  const char *string;
+  /* Hash code.  This is the full hash code, not the index into the
+     table.  */
+  unsigned long hash;
+};
+
+/* A hash table.  */
+
+struct bfd_hash_table
+{
+  /* The hash array.  */
+  struct bfd_hash_entry **table;
+  /* The number of slots in the hash table.  */
+  unsigned int size;
+  /* A function used to create new elements in the hash table.  The
+     first entry is itself a pointer to an element.  When this
+     function is first invoked, this pointer will be NULL.  However,
+     having the pointer permits a hierarchy of method functions to be
+     built each of which calls the function in the superclass.  Thus
+     each function should be written to allocate a new block of memory
+     only if the argument is NULL.  */
+  struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *,
+                                            struct bfd_hash_table *,
+                                            const char *));
+  /* An obstack for this hash table.  */
+  struct obstack memory;
+};
+
+/* Initialize a hash table.  */
+extern boolean bfd_hash_table_init
+  PARAMS ((struct bfd_hash_table *,
+          struct bfd_hash_entry *(*) (struct bfd_hash_entry *,
+                                      struct bfd_hash_table *,
+                                      const char *)));
+
+/* Initialize a hash table specifying a size.  */
+extern boolean bfd_hash_table_init_n
+  PARAMS ((struct bfd_hash_table *,
+          struct bfd_hash_entry *(*) (struct bfd_hash_entry *,
+                                      struct bfd_hash_table *,
+                                      const char *),
+          unsigned int size));
+
+/* Free up a hash table.  */
+extern void bfd_hash_table_free PARAMS ((struct bfd_hash_table *));
+
+/* Look up a string in a hash table.  If CREATE is true, a new entry
+   will be created for this string if one does not already exist.  The
+   COPY argument must be true if this routine should copy the string
+   into newly allocated memory when adding an entry.  */
+extern struct bfd_hash_entry *bfd_hash_lookup
+  PARAMS ((struct bfd_hash_table *, const char *, boolean create,
+          boolean copy));
+
+/* Base method for creating a hash table entry.  */
+extern struct bfd_hash_entry *bfd_hash_newfunc
+  PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *,
+          const char *));
+
+/* Grab some space for a hash table entry.  */
+extern PTR bfd_hash_allocate PARAMS ((struct bfd_hash_table *, size_t));
+
+/* Traverse a hash table in a random order, calling a function on each
+   element.  If the function returns false, the traversal stops.  The
+   INFO argument is passed to the function.  */
+extern void bfd_hash_traverse PARAMS ((struct bfd_hash_table *,
+                                      boolean (*) (struct bfd_hash_entry *,
+                                                   PTR),
+                                      PTR info));
+\f
 /* The code that implements targets can initialize a jump table with this
    macro.  It must name all its routines the same way (a prefix plus
    the standard routine suffix), or it must #define the routines that
@@ -406,9 +477,11 @@ CAT(NAME,_bfd_debug_info_end),\
 CAT(NAME,_bfd_debug_info_accumulate),\
 CAT(NAME,_bfd_get_relocated_section_contents),\
 CAT(NAME,_bfd_relax_section),\
-CAT(NAME,_bfd_seclet_link),\
 CAT(NAME,_bfd_reloc_type_lookup),\
-CAT(NAME,_bfd_make_debug_symbol)
+CAT(NAME,_bfd_make_debug_symbol),\
+CAT(NAME,_bfd_link_hash_table_create),\
+CAT(NAME,_bfd_link_add_symbols),\
+CAT(NAME,_bfd_final_link)
 
 #define COFF_SWAP_TABLE (PTR) &bfd_coff_std_swap_table
 
@@ -807,8 +880,8 @@ typedef struct sec
    struct symbol_cache_entry *symbol;  
    struct symbol_cache_entry **symbol_ptr_ptr;
 
-   struct bfd_seclet *seclets_head;
-   struct bfd_seclet *seclets_tail;
+   struct bfd_link_order *link_order_head;
+   struct bfd_link_order *link_order_tail;
 } asection ;
 
 
@@ -1014,7 +1087,8 @@ typedef enum bfd_reloc_status
 
         /* The relocation was performed, but may not be ok - presently
           generated only when linking i960 coff files with i960 b.out
-          symbols. */
+          symbols.  If this type is returned, the error_message argument
+          to bfd_perform_relocation will be set.  */
   bfd_reloc_dangerous
  }
  bfd_reloc_status_type;
@@ -1068,16 +1142,8 @@ typedef struct reloc_howto_struct
   unsigned int rightshift;
 
         /*  The size of the item to be relocated.  This is *not* a
-           power-of-two measure.
-                0 : one byte
-                1 : two bytes
-                2 : four bytes
-                3 : nothing done (unless special_function is nonzero)
-                4 : eight bytes
-               -2 : two bytes, result should be subtracted from the
-                    data instead of added
-           There is currently no trivial way to extract a "number of
-           bytes" from a howto pointer.  */
+           power-of-two measure.  To get the number of bytes operated
+           on by a type of relocation, use bfd_get_reloc_size.  */
   int size;
 
         /*  The number of bits in the item to be relocated.  This is used
@@ -1108,7 +1174,8 @@ typedef struct reloc_howto_struct
                                             struct symbol_cache_entry *symbol,
                                             PTR data,
                                             asection *input_section, 
-                                            bfd *output_bfd));
+                                            bfd *output_bfd,
+                                            char **error_message));
 
         /* The textual name of the relocation type. */
   char *name;
@@ -1156,6 +1223,9 @@ typedef struct reloc_howto_struct
     }                                          \
   }                                            \
 }                      
+int 
+bfd_get_reloc_size  PARAMS ((const reloc_howto_type *));
+
 typedef unsigned char bfd_byte;
 
 typedef struct relent_chain {
@@ -1169,7 +1239,8 @@ bfd_perform_relocation
     arelent *reloc_entry,
     PTR data,
     asection *input_section,
-    bfd *output_bfd));
+    bfd *output_bfd,
+    char **error_message));
 
 typedef enum bfd_reloc_code_real 
 {
@@ -1625,6 +1696,13 @@ struct _bfd
     struct _bfd *archive_head;    /* The first BFD in the archive.  */
     boolean has_armap;           
 
+     /* A chain of BFD structures involved in a link.  */
+    struct _bfd *link_next;
+
+     /* A field used by _bfd_generic_link_add_archive_symbols.  This will
+       be used only for archive elements.  */
+    int archive_pass;
+
      /* Used by the back end to hold private data. */
 
     union 
@@ -1658,9 +1736,6 @@ struct _bfd
 
      /* Where all the allocated stuff under this BFD goes */
     struct obstack memory;
-
-     /* Is this really needed in addition to usrdata?  */
-    asymbol **ld_symbols;
 };
 
 unsigned int 
@@ -1723,14 +1798,23 @@ bfd_scan_vma PARAMS ((CONST char *string, CONST char **end, int base));
 #define bfd_set_arch_mach(abfd, arch, mach)\
         BFD_SEND ( abfd, _bfd_set_arch_mach, (abfd, arch, mach))
 
-#define bfd_get_relocated_section_contents(abfd, seclet, data, relocateable) \
-       BFD_SEND (abfd, _bfd_get_relocated_section_contents, (abfd, seclet, data, relocateable))
+#define bfd_get_relocated_section_contents(abfd, link_info, link_order, data, relocateable, symbols) \
+       BFD_SEND (abfd, _bfd_get_relocated_section_contents, \
+                 (abfd, link_info, link_order, data, relocateable, symbols))
  
-#define bfd_relax_section(abfd, section, symbols) \
-       BFD_SEND (abfd, _bfd_relax_section, (abfd, section, symbols))
+#define bfd_relax_section(abfd, section, link_info, symbols) \
+       BFD_SEND (abfd, _bfd_relax_section, \
+                 (abfd, section, link_info, symbols))
+
+#define bfd_link_hash_table_create(abfd) \
+       BFD_SEND (abfd, _bfd_link_hash_table_create, (abfd))
+
+#define bfd_link_add_symbols(abfd, info) \
+       BFD_SEND (abfd, _bfd_link_add_symbols, (abfd, info))
+
+#define bfd_final_link(abfd, info) \
+       BFD_SEND (abfd, _bfd_final_link, (abfd, info))
 
-#define bfd_seclet_link(abfd, data, relocateable) \
-       BFD_SEND (abfd, _bfd_seclet_link, (abfd, data, relocateable))
 symindex 
 bfd_get_next_mapent PARAMS ((bfd *abfd, symindex previous, carsym **sym));
 
@@ -1769,6 +1853,10 @@ enum bfd_flavour {
   bfd_target_tekhex_flavour,
   bfd_target_srec_flavour,
   bfd_target_som_flavour};
+
+ /* Forward declaration.  */
+typedef struct bfd_link_info _bfd_link_info;
+
 typedef struct bfd_target
 {
   char *name;
@@ -1856,14 +1944,13 @@ typedef struct bfd_target
   void       (*_bfd_debug_info_accumulate) PARAMS ((bfd *, struct sec *));
 
   bfd_byte * (*_bfd_get_relocated_section_contents) PARAMS ((bfd *,
-                    struct bfd_seclet *, bfd_byte *data,
-                    boolean relocateable));
+                    struct bfd_link_info *, struct bfd_link_order *,
+                    bfd_byte *data, boolean relocateable,
+                    struct symbol_cache_entry **));
 
   boolean    (*_bfd_relax_section) PARAMS ((bfd *, struct sec *,
-                    struct symbol_cache_entry **));
+                    struct bfd_link_info *, struct symbol_cache_entry **));
 
-  boolean    (*_bfd_seclet_link) PARAMS ((bfd *, PTR data,
-                     boolean relocateable));
   /* See documentation on reloc types.  */
  CONST struct reloc_howto_struct *
        (*reloc_type_lookup) PARAMS ((bfd *abfd,
@@ -1876,6 +1963,18 @@ typedef struct bfd_target
        bfd *abfd,
        void *ptr,
        unsigned long size));
+
+  /* Create a hash table for the linker.  Different backends store
+    different information in this table.  */
+ struct bfd_link_hash_table *(*_bfd_link_hash_table_create) PARAMS ((bfd *));
+
+  /* Add symbols from this object file into the hash table.  */
+ boolean (*_bfd_link_add_symbols) PARAMS ((bfd *, struct bfd_link_info *));
+
+  /* Do a link based on the link_order structures attached to each
+    section of the BFD.  */
+ boolean (*_bfd_final_link) PARAMS ((bfd *, struct bfd_link_info *));
+
  PTR backend_data;
 } bfd_target;
 bfd_target *
index ef41bdb..7161d40 100644 (file)
@@ -28,6 +28,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "coff/internal.h"
 #include "libcoff.h"
 
+static long get_symbol_value PARAMS ((asymbol *));
+static bfd_reloc_status_type a29k_reloc
+  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+
 #define INSERT_HWORD(WORD,HWORD)       \
     (((WORD) & 0xff00ff00) | (((HWORD) & 0xff00) << 8) | ((HWORD)& 0xff))
 #define EXTRACT_HWORD(WORD) \
@@ -36,9 +40,9 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
     ((HWORD) & 0x8000 ? (HWORD)|0xffff0000 : (HWORD))
 
 /* Provided the symbol, returns the value reffed */
-static  long
-get_symbol_value(symbol)       
-asymbol *symbol;
+static long
+get_symbol_value (symbol)       
+     asymbol *symbol;
 {                                             
   long relocation = 0;
 
@@ -59,13 +63,15 @@ asymbol *symbol;
 /* this function is in charge of performing all the 29k relocations */
 
 static bfd_reloc_status_type
-DEFUN(a29k_reloc,(abfd, reloc_entry, symbol_in, data, input_section, output_bfd),
-      bfd *abfd AND
-      arelent *reloc_entry AND
-      asymbol *symbol_in AND
-      PTR data AND
-      asection *input_section AND
-      bfd *output_bfd)
+a29k_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd,
+           error_message)
+     bfd *abfd;
+     arelent *reloc_entry;
+     asymbol *symbol_in;
+     PTR data;
+     asection *input_section;
+     bfd *output_bfd;
+     char **error_message;
 {
   /* the consth relocation comes in two parts, we have to remember
      the state between calls, in these variables */
@@ -103,9 +109,8 @@ DEFUN(a29k_reloc,(abfd, reloc_entry, symbol_in, data, input_section, output_bfd)
 
   if ((part1_consth_active) && (r_type != R_IHCONST)) 
   {
-    fprintf(stderr,"Relocation problem : ");
-    fprintf(stderr,"Missing IHCONST in module %s\n",abfd->filename);
     part1_consth_active = false;
+    *error_message = (char *) "Missing IHCONST";
     return(bfd_reloc_dangerous);
   }
 
@@ -133,7 +138,7 @@ DEFUN(a29k_reloc,(abfd, reloc_entry, symbol_in, data, input_section, output_bfd)
       signed_value -= (input_section->output_section->vma
                       + input_section->output_offset);
       if (signed_value>0x1ffff || signed_value<-0x20000) 
-       return(bfd_reloc_outofrange);
+       return(bfd_reloc_overflow);
     }
     signed_value >>= 2;
     insn = INSERT_HWORD(insn, signed_value);
@@ -159,9 +164,7 @@ DEFUN(a29k_reloc,(abfd, reloc_entry, symbol_in, data, input_section, output_bfd)
     /* consth, part 2 
        Now relocate the reference */
     if (part1_consth_active == false) {
-      fprintf(stderr,"Relocation problem : ");
-      fprintf(stderr,"IHIHALF missing in module %s\n",
-             abfd->filename); 
+      *error_message = (char *) "Missing IHIHALF";
       return(bfd_reloc_dangerous);
     }
     /* sym_ptr_ptr = r_symndx, in coff_slurp_reloc_table() */
@@ -202,9 +205,7 @@ DEFUN(a29k_reloc,(abfd, reloc_entry, symbol_in, data, input_section, output_bfd)
     bfd_put_32(abfd, insn, hit_data);
     break;
    default:
-    fprintf(stderr,"Relocation problem : ");
-    fprintf(stderr,"Unrecognized reloc type %d, in module %s\n",
-           r_type,abfd->filename); 
+    *error_message = "Unrecognized reloc";
     return (bfd_reloc_dangerous);
   }
 
index dcdf9e9..ebc596f 100644 (file)
@@ -39,7 +39,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "sysdep.h"
 #include "libbfd.h"
 #include "coff/internal.h"
-#include "seclet.h"
 #include "libcoff.h"
 
 static asection bfd_debug_section = { "*DEBUG*" };
@@ -67,6 +66,13 @@ DEFUN(make_a_section_from_file,(abfd, hdr, target_index),
   return_section = bfd_make_section(abfd, name);
   if (return_section == NULL)
     return_section = bfd_coff_make_section_hook (abfd, name);
+
+  /* Handle several sections of the same name.  For example, if an executable
+     has two .bss sections, GDB better be able to find both of them
+     (PR 3562).  */
+  if (return_section == NULL)
+    return_section = bfd_make_section_anyway (abfd, name);
+
   if (return_section == NULL)
     return false;
 
@@ -904,10 +910,7 @@ coff_section_symbol (abfd, name)
   combined_entry_type *csym;
 
   sym = sec->symbol;
-  if (coff_symbol_from (abfd, sym))
-    csym = coff_symbol_from (abfd, sym)->native;
-  else
-    csym = 0;
+  csym = coff_symbol_from (abfd, sym)->native;
   /* Make sure back-end COFF stuff is there.  */
   if (csym == 0)
     {
@@ -924,18 +927,16 @@ coff_section_symbol (abfd, name)
   csym[0].u.syment.n_sclass = C_STAT;
   csym[0].u.syment.n_numaux = 1;
 /*  SF_SET_STATICS (sym);      @@ ??? */
-  if (sec)
-    {
-      csym[1].u.auxent.x_scn.x_scnlen = sec->_raw_size;
-      csym[1].u.auxent.x_scn.x_nreloc = sec->reloc_count;
-      csym[1].u.auxent.x_scn.x_nlinno = sec->lineno_count;
-    }
-  else
+  csym[1].u.auxent.x_scn.x_scnlen = sec->_raw_size;
+  csym[1].u.auxent.x_scn.x_nreloc = sec->reloc_count;
+  csym[1].u.auxent.x_scn.x_nlinno = sec->lineno_count;
+
+  if (sec->output_section == NULL)
     {
-      csym[1].u.auxent.x_scn.x_scnlen = 0;
-      csym[1].u.auxent.x_scn.x_nreloc = 0;
-      csym[1].u.auxent.x_scn.x_nlinno = 0;
+      sec->output_section = sec;
+      sec->output_offset = 0;
     }
+
   return sym;
 }
 
@@ -1326,13 +1327,13 @@ coff_print_symbol (abfd, filep, symbol, how)
          fprintf (file,"[%3d]", combined - root);
 
          fprintf (file,
-                  "(sc %2d)(fl 0x%02x)(ty %3x)(sc %3d) (nx %d) 0x%08x %s",
+                  "(sc %2d)(fl 0x%02x)(ty %3x)(sc %3d) (nx %d) 0x%08lx %s",
                   combined->u.syment.n_scnum,
                   combined->u.syment.n_flags,
                   combined->u.syment.n_type,
                   combined->u.syment.n_sclass,
                   combined->u.syment.n_numaux,
-                  combined->u.syment.n_value,
+                  (unsigned long) combined->u.syment.n_value,
                   symbol->name);
 
          for (aux = 0; aux < combined->u.syment.n_numaux; aux++) 
@@ -1353,7 +1354,7 @@ coff_print_symbol (abfd, filep, symbol, how)
                  break;
                default:
 
-                 fprintf (file, "AUX lnno %d size 0x%x tagndx %d",
+                 fprintf (file, "AUX lnno %d size 0x%x tagndx %ld",
                           auxp->u.auxent.x_sym.x_misc.x_lnsz.x_lnno,
                           auxp->u.auxent.x_sym.x_misc.x_lnsz.x_size,
                           tagndx);
@@ -1367,9 +1368,10 @@ coff_print_symbol (abfd, filep, symbol, how)
              l++;
              while (l->line_number) 
                {
-                 fprintf (file, "\n%4d : 0x%x",
-                         l->line_number,
-                         l->u.offset);
+                 fprintf (file, "\n%4d : 0x%lx",
+                          l->line_number,
+                          ((unsigned long)
+                           (l->u.offset + symbol->section->vma)));
                  l++;
                }
            }
index 840d425..101adbd 100644 (file)
@@ -21,8 +21,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 #include "bfd.h"
 #include "sysdep.h"
+#include "bfdlink.h"
 #include "libbfd.h"
-#include "seclet.h"
 #include "aout/ar.h"
 #include "aout/ranlib.h"
 
@@ -111,6 +111,8 @@ ecoff_mkobject_hook (abfd, filehdr, aouthdr)
   regsec = bfd_make_section (abfd, REGINFO);
   if (regsec == NULL)
     return NULL;
+  /* Tell the linker to leave this section completely alone.  */
+  regsec->flags = SEC_SHARED_LIBRARY;
 
   if (internal_a != (struct internal_aouthdr *) NULL)
     {
@@ -1322,7 +1324,7 @@ ecoff_type_to_string (abfd, aux_ptr, indx, bigendian)
     case btStruct:             /* Structure (Record) */
       ecoff_swap_rndx_in (bigendian, &aux_ptr[indx].a_rndx, &rndx);
       ecoff_emit_aggregate (abfd, p1, &rndx,
-                           AUX_GET_ISYM (bigendian, &aux_ptr[indx+1]),
+                           (long) AUX_GET_ISYM (bigendian, &aux_ptr[indx+1]),
                            "struct");
       indx++;                  /* skip aux words */
       break;
@@ -1334,7 +1336,7 @@ ecoff_type_to_string (abfd, aux_ptr, indx, bigendian)
     case btUnion:              /* Union */
       ecoff_swap_rndx_in (bigendian, &aux_ptr[indx].a_rndx, &rndx);
       ecoff_emit_aggregate (abfd, p1, &rndx,
-                           AUX_GET_ISYM (bigendian, &aux_ptr[indx+1]),
+                           (long) AUX_GET_ISYM (bigendian, &aux_ptr[indx+1]),
                            "union");
       indx++;                  /* skip aux words */
       break;
@@ -1346,7 +1348,7 @@ ecoff_type_to_string (abfd, aux_ptr, indx, bigendian)
     case btEnum:               /* Enumeration */
       ecoff_swap_rndx_in (bigendian, &aux_ptr[indx].a_rndx, &rndx);
       ecoff_emit_aggregate (abfd, p1, &rndx,
-                           AUX_GET_ISYM (bigendian, &aux_ptr[indx+1]),
+                           (long) AUX_GET_ISYM (bigendian, &aux_ptr[indx+1]),
                            "enum");
       indx++;                  /* skip aux words */
       break;
@@ -2040,8 +2042,9 @@ ecoff_find_nearest_line (abfd,
 /* We can't use the generic linking routines for ECOFF, because we
    have to handle all the debugging information.  The generic link
    routine just works out the section contents and attaches a list of
-   symbols.  We find each input BFD by looping over all the seclets.
-   We accumulate the debugging information for each input BFD.  */
+   symbols.  We find each input BFD by looping over all the link_order
+   information.  We accumulate the debugging information for each
+   input BFD.  */
 
 /* Get ECOFF EXTR information for an external symbol.  This function
    is passed to bfd_ecoff_debug_externals.  */
@@ -2084,6 +2087,14 @@ ecoff_get_extr (sym, esym)
   (*(ecoff_backend (input_bfd)->debug_swap.swap_ext_in))
     (input_bfd, ecoff_sym_ptr->native, esym);
 
+  /* If the symbol was defined by the linker, then esym will be
+     undefined but sym will not be.  Get a better class for such a
+     symbol.  */
+  if ((esym->asym.sc == scUndefined
+       || esym->asym.sc == scSUndefined)
+      && bfd_get_section (sym) != &bfd_und_section)
+    esym->asym.sc = scAbs;
+
   /* Adjust the FDR index for the symbol by that used for the input
      BFD.  */
   esym->ifd += ecoff_data (input_bfd)->debug_info.ifdbase;
@@ -2107,16 +2118,15 @@ ecoff_set_index (sym, indx)
    link.  */
 
 boolean
-ecoff_bfd_seclet_link (abfd, data, relocateable)
+ecoff_bfd_final_link (abfd, info)
      bfd *abfd;
-     PTR data;
-     boolean relocateable;
+     struct bfd_link_info *info;
 {
   const struct ecoff_backend_data * const backend = ecoff_backend (abfd);
   struct ecoff_debug_info * const debug = &ecoff_data (abfd)->debug_info;
   HDRR *symhdr;
-  register asection *o;
-  register bfd_seclet_type *p;
+  register bfd *input_bfd;
+  asection *o;
 
   /* We accumulate the debugging information counts in the symbolic
      header.  */
@@ -2147,69 +2157,49 @@ ecoff_bfd_seclet_link (abfd, data, relocateable)
   debug->external_fdr = debug->external_fdr_end = NULL;
   debug->external_rfd = debug->external_rfd_end = NULL;
 
-  /* We need to accumulate the debugging symbols from each input BFD.
-     We do this by looking through all the seclets to gather all the
-     input BFD's.  We use the output_has_begun field to avoid
-     including a particular input BFD more than once.  */
-
-  /* Clear the output_has_begun fields.  */
-  for (o = abfd->sections; o != (asection *) NULL; o = o->next)
-    for (p = o->seclets_head;
-        p != (bfd_seclet_type *) NULL;
-        p = p->next)
-      if (p->type == bfd_indirect_seclet)
-       p->u.indirect.section->owner->output_has_begun = false;
-  
-  /* Add in each input BFD.  */
-  for (o = abfd->sections; o != (asection *) NULL; o = o->next)
+  /* We accumulate the debugging symbols from each input BFD.  */
+  for (input_bfd = info->input_bfds;
+       input_bfd != (bfd *) NULL;
+       input_bfd = input_bfd->link_next)
     {
-      for (p = o->seclets_head;
-          p != (bfd_seclet_type *) NULL;
-          p = p->next)
-       {
-         bfd *input_bfd;
-         boolean ret;
+      boolean ret;
 
-         if (p->type != bfd_indirect_seclet)
-           continue;
+      if (bfd_get_flavour (input_bfd) == bfd_target_ecoff_flavour)
+       ret = (bfd_ecoff_debug_accumulate
+              (abfd, debug, &backend->debug_swap,
+               input_bfd, &ecoff_data (input_bfd)->debug_info,
+               &ecoff_backend (input_bfd)->debug_swap, info->relocateable));
+      else
+       ret = bfd_ecoff_debug_link_other (abfd,
+                                         debug,
+                                         &backend->debug_swap,
+                                         input_bfd);
 
-         input_bfd = p->u.indirect.section->owner;
-         if (input_bfd->output_has_begun)
-           continue;
+      if (! ret)
+       return false;
 
-         if (bfd_get_flavour (input_bfd) == bfd_target_ecoff_flavour)
-           ret = (bfd_ecoff_debug_accumulate
-                  (abfd, debug, &backend->debug_swap,
-                   input_bfd, &ecoff_data (input_bfd)->debug_info,
-                   &ecoff_backend (input_bfd)->debug_swap, relocateable));
-         else
-           ret = bfd_ecoff_debug_link_other (abfd,
-                                             debug,
-                                             &backend->debug_swap,
-                                             input_bfd);
-
-         if (ret == false)
-           return false;
-
-         /* Combine the register masks.  */
-         ecoff_data (abfd)->gprmask |= ecoff_data (input_bfd)->gprmask;
-         ecoff_data (abfd)->fprmask |= ecoff_data (input_bfd)->fprmask;
-         ecoff_data (abfd)->cprmask[0] |= ecoff_data (input_bfd)->cprmask[0];
-         ecoff_data (abfd)->cprmask[1] |= ecoff_data (input_bfd)->cprmask[1];
-         ecoff_data (abfd)->cprmask[2] |= ecoff_data (input_bfd)->cprmask[2];
-         ecoff_data (abfd)->cprmask[3] |= ecoff_data (input_bfd)->cprmask[3];
-
-         input_bfd->output_has_begun = true;
-       }
+      /* Combine the register masks.  */
+      ecoff_data (abfd)->gprmask |= ecoff_data (input_bfd)->gprmask;
+      ecoff_data (abfd)->fprmask |= ecoff_data (input_bfd)->fprmask;
+      ecoff_data (abfd)->cprmask[0] |= ecoff_data (input_bfd)->cprmask[0];
+      ecoff_data (abfd)->cprmask[1] |= ecoff_data (input_bfd)->cprmask[1];
+      ecoff_data (abfd)->cprmask[2] |= ecoff_data (input_bfd)->cprmask[2];
+      ecoff_data (abfd)->cprmask[3] |= ecoff_data (input_bfd)->cprmask[3];
+    }
 
-      /* Don't bother to do any linking of .reginfo sections.  */
+  /* Don't let the generic routine link the .reginfo sections.  */
+  for (o = abfd->sections; o != (asection *) NULL; o = o->next)
+    {
       if (strcmp (o->name, REGINFO) == 0)
-       o->seclets_head = (bfd_seclet_type *) NULL;
+       {
+         o->link_order_head = (struct bfd_link_order *) NULL;
+         break;
+       }
     }
 
   /* Let the generic link routine handle writing out the section
      contents.  */
-  return bfd_generic_seclet_link (abfd, data, relocateable);
+  return _bfd_generic_final_link (abfd, info);
 }
 \f
 /* Set the architecture.  The supported architecture is stored in the
@@ -2279,7 +2269,7 @@ ecoff_get_section_contents (abfd, section, location, offset, count)
      size is reasonable.  We don't have to worry about swapping or any
      such thing; the .reginfo section is defined such that the
      contents are an ecoff_reginfo structure as seen on the host.  */
-  memcpy (location, ((char *) &s) + offset, count);
+  memcpy (location, ((char *) &s) + offset, (size_t) count);
   return true;
 }
 
@@ -2382,7 +2372,7 @@ ecoff_set_section_contents (abfd, section, location, offset, count)
         swapping or any such thing; the .reginfo section is defined
         such that the contents are an ecoff_reginfo structure as seen
         on the host.  */
-      memcpy (((char *) &s) + offset, location, count);
+      memcpy (((char *) &s) + offset, location, (size_t) count);
 
       tdata->gp = s.gp_value;
       tdata->gprmask = s.gprmask;
@@ -3134,7 +3124,7 @@ ecoff_write_armap (abfd, elength, map, orl_count, stridx)
       != sizeof (struct ar_hdr))
     return false;
 
-  bfd_h_put_32 (abfd, hashsize, temp);
+  bfd_h_put_32 (abfd, (bfd_vma) hashsize, temp);
   if (bfd_write (temp, 1, 4, abfd) != 4)
     return false;
   
@@ -3178,8 +3168,10 @@ ecoff_write_armap (abfd, elength, map, orl_count, stridx)
          hash = srch;
        }
        
-      bfd_h_put_32 (abfd, map[i].namidx, (PTR) (hashtable + hash * 8));
-      bfd_h_put_32 (abfd, firstreal, (PTR) (hashtable + hash * 8 + 4));
+      bfd_h_put_32 (abfd, (bfd_vma) map[i].namidx,
+                   (PTR) (hashtable + hash * 8));
+      bfd_h_put_32 (abfd, (bfd_vma) firstreal,
+                   (PTR) (hashtable + hash * 8 + 4));
     }
 
   if (bfd_write (hashtable, 1, symdefsize, abfd) != symdefsize)
@@ -3188,7 +3180,7 @@ ecoff_write_armap (abfd, elength, map, orl_count, stridx)
   bfd_release (abfd, hashtable);
 
   /* Now write the strings.  */
-  bfd_h_put_32 (abfd, stringsize, temp);
+  bfd_h_put_32 (abfd, (bfd_vma) stringsize, temp);
   if (bfd_write (temp, 1, 4, abfd) != 4)
     return false;
   for (i = 0; i < orl_count; i++)
index 02b3b33..bfb3898 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -216,13 +216,15 @@ bfd_elf_generic_reloc (abfd,
                       symbol,
                       data,
                       input_section,
-                      output_bfd)
+                      output_bfd,
+                      error_message)
      bfd *abfd;
      arelent *reloc_entry;
      asymbol *symbol;
      PTR data;
      asection *input_section;
      bfd *output_bfd;
+     char **error_message;
 {
   if (output_bfd != (bfd *) NULL
       && (symbol->flags & BSF_SECTION_SYM) == 0
index ed1f417..bdbb4a5 100644 (file)
@@ -47,11 +47,18 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #define bfd_elf32_bfd_get_relocated_section_contents \
  bfd_generic_get_relocated_section_contents
 #define bfd_elf32_bfd_relax_section bfd_generic_relax_section
-#ifndef bfd_elf32_bfd_seclet_link
-#define bfd_elf32_bfd_seclet_link bfd_generic_seclet_link
-#endif
 #define bfd_elf32_bfd_make_debug_symbol \
   ((asymbol *(*) PARAMS ((bfd *, void *, unsigned long))) bfd_nullvoidptr)
+#ifndef bfd_elf32_bfd_link_hash_table_create
+#define bfd_elf32_bfd_link_hash_table_create \
+  _bfd_generic_link_hash_table_create
+#endif
+#ifndef bfd_elf32_bfd_link_add_symbols
+#define bfd_elf32_bfd_link_add_symbols _bfd_generic_link_add_symbols
+#endif
+#ifndef bfd_elf32_bfd_final_link
+#define bfd_elf32_bfd_final_link       _bfd_generic_final_link
+#endif
 
 #ifndef elf_info_to_howto_rel
 #define elf_info_to_howto_rel 0
index 8450179..7fdfa26 100644 (file)
@@ -47,9 +47,18 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #define bfd_elf64_bfd_get_relocated_section_contents \
  bfd_generic_get_relocated_section_contents
 #define bfd_elf64_bfd_relax_section bfd_generic_relax_section
-#define bfd_elf64_bfd_seclet_link bfd_generic_seclet_link
 #define bfd_elf64_bfd_make_debug_symbol \
   ((asymbol *(*) PARAMS ((bfd *, void *, unsigned long))) bfd_nullvoidptr)
+#ifndef bfd_elf64_bfd_link_hash_table_create
+#define bfd_elf64_bfd_link_hash_table_create \
+  _bfd_generic_link_hash_table_create
+#endif
+#ifndef bfd_elf64_bfd_link_add_symbols
+#define bfd_elf64_bfd_link_add_symbols _bfd_generic_link_add_symbols
+#endif
+#ifndef bfd_elf64_bfd_final_link
+#define bfd_elf64_bfd_final_link       _bfd_generic_final_link
+#endif
 
 #ifndef elf_info_to_howto_rel
 #define elf_info_to_howto_rel 0
index dc16af0..a0db98c 100644 (file)
@@ -26,7 +26,6 @@ extern int   fflush ();
 extern int   write ();
 extern void  abort ();
 extern int   close ();
-extern int   qsort ();
 extern void  exit ();
 extern int   fseek ();
 extern int   fclose ();
@@ -70,7 +69,6 @@ extern char *strrchr();
 extern int chmod();
 extern int fstat();
 extern int stat();
-extern int strtol();
 
 extern char *strrchr();
 extern char *ctime();
diff --git a/bfd/hppabsd-core.c b/bfd/hppabsd-core.c
new file mode 100644 (file)
index 0000000..b6ecc30
--- /dev/null
@@ -0,0 +1,334 @@
+/* BFD back-end for HPPA BSD core files.
+   Copyright 1993 Free Software Foundation, Inc.
+
+   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 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.
+
+   Written by the Center for Software Science at the University of Utah
+   and by Cygnus Support. 
+
+   The core file structure for the Utah 4.3BSD and OSF1 ports on the
+   PA is a mix between traditional cores and hpux cores -- just
+   different enough that supporting this format would tend to add
+   gross hacks to trad-core.c or hpux-core.c.  So instead we keep any
+   gross hacks isolated to this file.  */
+   
+
+/* This file can only be compiled on systems which use HPPA-BSD style
+   core files.  In the config/XXXXXX.mh file for such a system add
+   HDEFINES=-DHPPABSD_CORE
+   HDEPFILES=hppabsd-core.o
+
+   I would not expect this to be of use to any other host/target, but
+   you never know.  */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+#if defined (HOST_HPPABSD)
+
+#include "machine/vmparam.h"
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/dir.h>
+#include <signal.h>
+#include <machine/reg.h>
+#include <sys/user.h>          /* After a.out.h  */
+#include <sys/file.h>
+#include <errno.h>
+
+static asection *make_bfd_asection PARAMS ((bfd *, CONST char *,
+                                           flagword, bfd_size_type,
+                                           bfd_vma, unsigned int));
+static asymbol *hppabsd_core_make_empty_symbol PARAMS ((bfd *));
+static bfd_target *hppabsd_core_core_file_p PARAMS ((bfd *));
+static char *hppabsd_core_core_file_failing_command PARAMS ((bfd *));
+static int hppabsd_core_core_file_failing_signal PARAMS ((bfd *));
+static boolean hppabsd_core_core_file_matches_executable_p
+  PARAMS ((bfd *, bfd *));
+static void swap_abort PARAMS ((void));
+
+/* These are stored in the bfd's tdata.  */
+
+struct hppabsd_core_struct
+  {
+    int sig;
+    char cmd[MAXCOMLEN + 1];
+    asection *data_section;
+    asection *stack_section;
+    asection *reg_section;
+  };
+
+#define core_hdr(bfd) ((bfd)->tdata.hppabsd_core_data)
+#define core_signal(bfd) (core_hdr(bfd)->sig)
+#define core_command(bfd) (core_hdr(bfd)->cmd)
+#define core_datasec(bfd) (core_hdr(bfd)->data_section)
+#define core_stacksec(bfd) (core_hdr(bfd)->stack_section)
+#define core_regsec(bfd) (core_hdr(bfd)->reg_section)
+
+static asection *
+make_bfd_asection (abfd, name, flags, _raw_size, vma, alignment_power)
+     bfd *abfd;
+     CONST char *name;
+     flagword flags;
+     bfd_size_type _raw_size;
+     bfd_vma vma;
+     unsigned int alignment_power;
+{
+  asection *asect;
+
+  asect = bfd_make_section (abfd, name);
+  if (!asect)
+    return NULL;
+
+  asect->flags = flags;
+  asect->_raw_size = _raw_size;
+  asect->vma = vma;
+  asect->filepos = bfd_tell (abfd);
+  asect->alignment_power = alignment_power;
+
+  return asect;
+}
+
+static asymbol *
+hppabsd_core_make_empty_symbol (abfd)
+     bfd *abfd;
+{
+  asymbol *new = (asymbol *) bfd_zalloc (abfd, sizeof (asymbol));
+  new->the_bfd = abfd;
+  return new;
+}
+
+static bfd_target *
+hppabsd_core_core_file_p (abfd)
+     bfd *abfd;
+{
+  int val;
+  struct user u;
+  struct hppabsd_core_struct *coredata;
+  int clicksz;
+
+  /* Try to read in the u-area.  We will need information from this
+     to know how to grok the rest of the core structures.  */
+  val = bfd_read ((void *) &u, 1, sizeof u, abfd);
+  if (val != sizeof u)
+    {
+      bfd_error = wrong_format;
+      return NULL;
+    }
+
+  /* Get the page size out of the u structure.  This will be different
+     for PA 1.0 machines and PA 1.1 machines.   Yuk!  */
+  clicksz = u.u_pcb.pcb_pgsz;
+
+  /* Sanity checks.  Make sure the size of the core file matches the
+     the size computed from information within the core itself.  */
+  {
+    FILE *stream = bfd_cache_lookup (abfd);
+    struct stat statbuf;
+    if (stream == NULL || fstat (fileno (stream), &statbuf) < 0)
+      {
+       bfd_error = system_call_error;
+       return NULL;
+      }
+    if (NBPG * (UPAGES + u.u_dsize + u.u_ssize) > statbuf.st_size)
+      {
+       bfd_error = file_truncated;
+       return NULL;
+      }
+    if (clicksz * (UPAGES + u.u_dsize + u.u_ssize) < statbuf.st_size)
+      {
+       /* The file is too big.  Maybe it's not a core file
+          or we otherwise have bad values for u_dsize and u_ssize).  */
+       bfd_error = wrong_format;
+       return NULL;
+      }
+  }
+
+  /* OK, we believe you.  You're a core file (sure, sure).  */
+
+  coredata = (struct hppabsd_core_struct *)
+    bfd_zalloc (abfd, sizeof (struct hppabsd_core_struct));
+
+  /* Make the core data and available via the tdata part of the BFD.  */
+  abfd->tdata.hppabsd_core_data = coredata;
+
+  /* Create the sections.  */
+  core_stacksec (abfd) = make_bfd_asection (abfd, ".stack",
+                                          SEC_ALLOC + SEC_HAS_CONTENTS,
+                                          clicksz * u.u_ssize,
+                                          NBPG * (USIZE + KSTAKSIZE) 
+                                            + clicksz * u.u_dsize, 2);
+  core_stacksec (abfd)->vma = USRSTACK; 
+
+  core_datasec (abfd) = make_bfd_asection (abfd, ".data",
+                                         SEC_ALLOC + SEC_LOAD
+                                           + SEC_HAS_CONTENTS,
+                                         clicksz * u.u_dsize,
+                                         NBPG * (USIZE + KSTAKSIZE), 2);
+  core_datasec (abfd)->vma = UDATASEG;
+
+  core_regsec (abfd) = make_bfd_asection (abfd, ".reg",
+                                        SEC_ALLOC + SEC_HAS_CONTENTS,
+                                        KSTAKSIZE * NBPG,
+                                        NBPG * USIZE, 2);
+  core_regsec (abfd)->vma = 0;
+
+  strncpy (core_command (abfd), u.u_comm, MAXCOMLEN + 1);
+  core_signal (abfd) = u.u_code;
+  return abfd->xvec;
+}
+
+static char *
+hppabsd_core_core_file_failing_command (abfd)
+     bfd *abfd;
+{
+  return core_command (abfd);
+}
+
+/* ARGSUSED */
+static int
+hppabsd_core_core_file_failing_signal (abfd)
+     bfd *abfd;
+{
+  return core_signal (abfd);
+}
+
+/* ARGSUSED */
+static boolean
+hppabsd_core_core_file_matches_executable_p (core_bfd, exec_bfd)
+     bfd *core_bfd, *exec_bfd;
+{
+  /* There's no way to know this...  */
+  return true;
+}
+
+\f
+/* No archive file support via this BFD */
+#define        hppabsd_core_openr_next_archived_file \
+       bfd_generic_openr_next_archived_file
+#define        hppabsd_core_generic_stat_arch_elt      bfd_generic_stat_arch_elt
+#define        hppabsd_core_slurp_armap                bfd_false
+#define        hppabsd_core_slurp_extended_name_table  bfd_true
+#define        hppabsd_core_write_armap                (boolean (*) PARAMS     \
+    ((bfd *arch, unsigned int elength, struct orl *map, \
+      unsigned int orl_count, int stridx))) bfd_false
+#define        hppabsd_core_truncate_arname            bfd_dont_truncate_arname
+
+#define        hppabsd_core_close_and_cleanup          bfd_generic_close_and_cleanup
+#define        hppabsd_core_set_section_contents       (boolean (*) PARAMS     \
+        ((bfd *abfd, asection *section, PTR data, file_ptr offset,     \
+        bfd_size_type count))) bfd_false
+#define        hppabsd_core_get_section_contents \
+       bfd_generic_get_section_contents
+#define        hppabsd_core_new_section_hook           (boolean (*) PARAMS     \
+       ((bfd *, sec_ptr))) bfd_true
+#define        hppabsd_core_get_symtab_upper_bound     bfd_0u
+#define        hppabsd_core_get_symtab                 (unsigned int (*) PARAMS \
+        ((bfd *, struct symbol_cache_entry **))) bfd_0u
+#define        hppabsd_core_get_reloc_upper_bound      (unsigned int (*) PARAMS \
+       ((bfd *, sec_ptr))) bfd_0u
+#define        hppabsd_core_canonicalize_reloc         (unsigned int (*) PARAMS \
+       ((bfd *, sec_ptr, arelent **, struct symbol_cache_entry**))) bfd_0u
+#define        hppabsd_core_print_symbol               (void (*) PARAMS        \
+       ((bfd *, PTR, struct symbol_cache_entry  *,                     \
+       bfd_print_symbol_type))) bfd_false
+#define        hppabsd_core_get_symbol_info            (void (*) PARAMS        \
+       ((bfd *, struct symbol_cache_entry  *,                  \
+       symbol_info *))) bfd_false
+#define        hppabsd_core_get_lineno                 (alent * (*) PARAMS     \
+       ((bfd *, struct symbol_cache_entry *))) bfd_nullvoidptr
+#define        hppabsd_core_set_arch_mach              (boolean (*) PARAMS     \
+       ((bfd *, enum bfd_architecture, unsigned long))) bfd_false
+#define        hppabsd_core_find_nearest_line          (boolean (*) PARAMS     \
+        ((bfd *abfd, struct sec  *section,                             \
+         struct symbol_cache_entry  **symbols,bfd_vma offset,          \
+         CONST char **file, CONST char **func, unsigned int *line))) bfd_false
+#define        hppabsd_core_sizeof_headers             (int (*) PARAMS \
+       ((bfd *, boolean))) bfd_0
+
+#define hppabsd_core_bfd_debug_info_start      bfd_void
+#define hppabsd_core_bfd_debug_info_end                bfd_void
+#define hppabsd_core_bfd_debug_info_accumulate (void (*) PARAMS        \
+       ((bfd *, struct sec *))) bfd_void
+#define hppabsd_core_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents
+#define hppabsd_core_bfd_relax_section         bfd_generic_relax_section
+#define hppabsd_core_bfd_reloc_type_lookup \
+  ((CONST struct reloc_howto_struct *(*) PARAMS ((bfd *, bfd_reloc_code_real_type))) bfd_nullvoidptr)
+#define hppabsd_core_bfd_make_debug_symbol \
+  ((asymbol *(*) PARAMS ((bfd *, void *, unsigned long))) bfd_nullvoidptr)
+#define hppabsd_core_bfd_link_hash_table_create \
+  ((struct bfd_link_hash_table *(*) PARAMS ((bfd *))) bfd_nullvoidptr)
+#define hppabsd_core_bfd_link_add_symbols \
+  ((boolean (*) PARAMS ((bfd *, struct bfd_link_info *))) bfd_false)
+#define hppabsd_core_bfd_final_link \
+  ((boolean (*) PARAMS ((bfd *, struct bfd_link_info *))) bfd_false)
+
+/* If somebody calls any byte-swapping routines, shoot them.  */
+static void
+swap_abort ()
+{
+  /* This way doesn't require any declaration for ANSI to fuck up.  */
+  abort ();    
+}
+
+#define        NO_GET  ((bfd_vma (*) PARAMS ((         bfd_byte *))) swap_abort )
+#define        NO_PUT  ((void    (*) PARAMS ((bfd_vma, bfd_byte *))) swap_abort )
+#define        NO_SIGNED_GET ((bfd_signed_vma (*) PARAMS ((bfd_byte *))) swap_abort )
+
+bfd_target hppabsd_core_vec =
+  {
+    "hppabsd-core",
+    bfd_target_unknown_flavour,
+    true,                      /* target byte order */
+    true,                      /* target headers byte order */
+    (HAS_RELOC | EXEC_P |      /* object flags */
+     HAS_LINENO | HAS_DEBUG |
+     HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
+    (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
+    0,                                                    /* symbol prefix */
+    ' ',                                                  /* ar_pad_char */
+    16,                                                           /* ar_max_namelen */
+    3,                                                    /* minimum alignment power */
+    NO_GET, NO_SIGNED_GET, NO_PUT,     /* 64 bit data */
+    NO_GET, NO_SIGNED_GET, NO_PUT,     /* 32 bit data */
+    NO_GET, NO_SIGNED_GET, NO_PUT,     /* 16 bit data */
+    NO_GET, NO_SIGNED_GET, NO_PUT,     /* 64 bit hdrs */
+    NO_GET, NO_SIGNED_GET, NO_PUT,     /* 32 bit hdrs */
+    NO_GET, NO_SIGNED_GET, NO_PUT,     /* 16 bit hdrs */
+
+    {                          /* bfd_check_format */
+     _bfd_dummy_target,                /* unknown format */
+     _bfd_dummy_target,                /* object file */
+     _bfd_dummy_target,                /* archive */
+     hppabsd_core_core_file_p  /* a core file */
+    },
+    {                          /* bfd_set_format */
+     bfd_false, bfd_false,
+     bfd_false, bfd_false
+    },
+    {                          /* bfd_write_contents */
+     bfd_false, bfd_false,
+     bfd_false, bfd_false
+    },
+    
+    JUMP_TABLE(hppabsd_core),
+    (PTR) 0                    /* backend_data */
+};
+#endif
diff --git a/bfd/hpux-core.c b/bfd/hpux-core.c
new file mode 100644 (file)
index 0000000..afda813
--- /dev/null
@@ -0,0 +1,318 @@
+/* BFD back-end for HP/UX core files.
+   Copyright 1993 Free Software Foundation, Inc.
+   Written by Stu Grossman, Cygnus Support.
+   Converted to back-end form by Ian Lance Taylor, Cygnus SUpport
+
+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 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.  */
+
+/* This file can only be compiled on systems which use HP/UX style
+   core files.  In the config/XXXXXX.mh file for such a system add
+      HDEFINES=-DHPUX_CORE
+      HDEPFILES=hpux-core.o
+   */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+#if defined (HOST_HPPAHPUX) || defined (HOST_HP300HPUX)
+
+/* FIXME: sys/core.h doesn't exist for HPUX version 7.  HPUX version
+   5, 6, and 7 core files seem to be standard trad-core.c type core
+   files; can we just use trad-core.c in addition to this file?  */
+
+#include <sys/core.h>
+#include <sys/utsname.h>
+
+#endif /* HOST_HPPAHPUX */
+
+#ifdef HOST_HPPABSD
+
+/* Not a very swift place to put it, but that's where the BSD port
+   puts them.  */
+#include "/hpux/usr/include/sys/core.h"
+
+#endif /* HOST_HPPABSD */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/dir.h>
+#include <signal.h>
+#include <machine/reg.h>
+#include <sys/user.h>          /* After a.out.h  */
+#include <sys/file.h>
+#include <errno.h>
+
+/* These are stored in the bfd's tdata */
+
+struct hpux_core_struct 
+{
+  int sig;
+  char cmd[MAXCOMLEN + 1];
+  asection *data_section;
+  asection *stack_section;
+  asection *reg_section;
+};
+
+#define core_hdr(bfd) ((bfd)->tdata.hpux_core_data)
+#define core_signal(bfd) (core_hdr(bfd)->sig)
+#define core_command(bfd) (core_hdr(bfd)->cmd)
+#define core_datasec(bfd) (core_hdr(bfd)->data_section)
+#define core_stacksec(bfd) (core_hdr(bfd)->stack_section)
+#define core_regsec(bfd) (core_hdr(bfd)->reg_section)
+
+static asection *
+make_bfd_asection (abfd, name, flags, _raw_size, vma, alignment_power)
+     bfd *abfd;
+     CONST char *name;
+     flagword flags;
+     bfd_size_type _raw_size;
+     bfd_vma vma;
+     unsigned int alignment_power;
+{
+  asection *asect;
+
+  asect = bfd_make_section (abfd, name);
+  if (!asect)
+    return NULL;
+
+  asect->flags = flags;
+  asect->_raw_size = _raw_size;
+  asect->vma = vma;
+  asect->filepos = bfd_tell (abfd);
+  asect->alignment_power = alignment_power;
+
+  return asect;
+}
+
+static asymbol *
+hpux_core_make_empty_symbol (abfd)
+     bfd *abfd;
+{
+  asymbol *new = (asymbol *) bfd_zalloc (abfd, sizeof (asymbol));
+  new->the_bfd = abfd;
+  return new;
+}
+
+static bfd_target *
+hpux_core_core_file_p (abfd)
+     bfd *abfd;
+{
+  core_hdr (abfd) = (struct hpux_core_struct *)
+    bfd_zalloc (abfd, sizeof (struct hpux_core_struct));
+  if (!core_hdr (abfd))
+    return NULL;
+
+  while (1)
+    {
+      int val;
+      struct corehead core_header;
+
+      val = bfd_read ((void *) &core_header, 1, sizeof core_header, abfd);
+      if (val <= 0)
+       break;
+      switch (core_header.type)
+       {
+       case CORE_KERNEL:
+       case CORE_FORMAT:
+         bfd_seek (abfd, core_header.len, SEEK_CUR);   /* Just skip this */
+         break;
+       case CORE_EXEC:
+         {
+           struct proc_exec proc_exec;
+           bfd_read ((void *) &proc_exec, 1, core_header.len, abfd);
+           strncpy (core_command (abfd), proc_exec.cmd, MAXCOMLEN + 1);
+         }
+         break;
+       case CORE_PROC:
+         {
+           struct proc_info proc_info;
+           core_regsec (abfd) = make_bfd_asection (abfd, ".reg",
+                                              SEC_ALLOC + SEC_HAS_CONTENTS,
+                                                   core_header.len,
+                               (int) &proc_info - (int) &proc_info.hw_regs,
+                                                   2);
+           bfd_read (&proc_info, 1, core_header.len, abfd);
+           core_signal (abfd) = proc_info.sig;
+         }
+         if (!core_regsec (abfd))
+           return NULL;
+         break;
+       case CORE_DATA:
+         core_datasec (abfd) = make_bfd_asection (abfd, ".data",
+                                   SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS,
+                                                  core_header.len,
+                                                  core_header.addr,
+                                                  2);
+         if (!core_datasec (abfd))
+           return NULL;
+         bfd_seek (abfd, core_header.len, SEEK_CUR);
+         break;
+       case CORE_STACK:
+         core_stacksec (abfd) = make_bfd_asection (abfd, ".stack",
+                                   SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS,
+                                                   core_header.len,
+                                                   core_header.addr,
+                                                   2);
+         if (!core_stacksec (abfd))
+           return NULL;
+         bfd_seek (abfd, core_header.len, SEEK_CUR);
+         break;
+       default:
+         /* Falling into here is an error and should prevent this
+            target from matching.  That way systems which use hpux
+            cores along with other formats can still work.  */
+         return 0;
+       }
+    }
+
+  /* OK, we believe you.  You're a core file (sure, sure).  */
+
+  return abfd->xvec;
+}
+
+static char *
+hpux_core_core_file_failing_command (abfd)
+     bfd *abfd;
+{
+  return core_command (abfd);
+}
+
+/* ARGSUSED */
+static int
+hpux_core_core_file_failing_signal (abfd)
+     bfd *abfd;
+{
+  return core_signal (abfd);
+}
+
+/* ARGSUSED */
+static boolean
+hpux_core_core_file_matches_executable_p (core_bfd, exec_bfd)
+     bfd *core_bfd, *exec_bfd;
+{
+  return true;                 /* FIXME, We have no way of telling at this point */
+}
+\f
+/* No archive file support via this BFD */
+#define        hpux_core_openr_next_archived_file      bfd_generic_openr_next_archived_file
+#define        hpux_core_generic_stat_arch_elt         bfd_generic_stat_arch_elt
+#define        hpux_core_slurp_armap                   bfd_false
+#define        hpux_core_slurp_extended_name_table     bfd_true
+#define        hpux_core_write_armap                   (boolean (*) PARAMS     \
+    ((bfd *arch, unsigned int elength, struct orl *map, \
+      unsigned int orl_count, int stridx))) bfd_false
+#define        hpux_core_truncate_arname               bfd_dont_truncate_arname
+
+#define        hpux_core_close_and_cleanup             bfd_generic_close_and_cleanup
+#define        hpux_core_set_section_contents          (boolean (*) PARAMS     \
+        ((bfd *abfd, asection *section, PTR data, file_ptr offset,     \
+        bfd_size_type count))) bfd_false
+#define        hpux_core_get_section_contents          bfd_generic_get_section_contents
+#define        hpux_core_new_section_hook              (boolean (*) PARAMS     \
+       ((bfd *, sec_ptr))) bfd_true
+#define        hpux_core_get_symtab_upper_bound        bfd_0u
+#define        hpux_core_get_symtab                    (unsigned int (*) PARAMS \
+        ((bfd *, struct symbol_cache_entry **))) bfd_0u
+#define        hpux_core_get_reloc_upper_bound         (unsigned int (*) PARAMS \
+       ((bfd *, sec_ptr))) bfd_0u
+#define        hpux_core_canonicalize_reloc            (unsigned int (*) PARAMS \
+       ((bfd *, sec_ptr, arelent **, struct symbol_cache_entry**))) bfd_0u
+#define        hpux_core_print_symbol                  (void (*) PARAMS        \
+       ((bfd *, PTR, struct symbol_cache_entry  *,                     \
+       bfd_print_symbol_type))) bfd_false
+#define        hpux_core_get_symbol_info               (void (*) PARAMS        \
+       ((bfd *, struct symbol_cache_entry  *,                  \
+       symbol_info *))) bfd_false
+#define        hpux_core_get_lineno                    (alent * (*) PARAMS     \
+       ((bfd *, struct symbol_cache_entry *))) bfd_nullvoidptr
+#define        hpux_core_set_arch_mach                 (boolean (*) PARAMS     \
+       ((bfd *, enum bfd_architecture, unsigned long))) bfd_false
+#define        hpux_core_find_nearest_line             (boolean (*) PARAMS     \
+        ((bfd *abfd, struct sec  *section,                             \
+         struct symbol_cache_entry  **symbols,bfd_vma offset,          \
+         CONST char **file, CONST char **func, unsigned int *line))) bfd_false
+#define        hpux_core_sizeof_headers                (int (*) PARAMS \
+       ((bfd *, boolean))) bfd_0
+
+#define hpux_core_bfd_debug_info_start         bfd_void
+#define hpux_core_bfd_debug_info_end           bfd_void
+#define hpux_core_bfd_debug_info_accumulate    (void (*) PARAMS        \
+       ((bfd *, struct sec *))) bfd_void
+#define hpux_core_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents
+#define hpux_core_bfd_relax_section            bfd_generic_relax_section
+#define hpux_core_bfd_reloc_type_lookup \
+  ((CONST struct reloc_howto_struct *(*) PARAMS ((bfd *, bfd_reloc_code_real_type))) bfd_nullvoidptr)
+#define hpux_core_bfd_make_debug_symbol \
+  ((asymbol *(*) PARAMS ((bfd *, void *, unsigned long))) bfd_nullvoidptr)
+#define hpux_core_bfd_link_hash_table_create \
+  ((struct bfd_link_hash_table *(*) PARAMS ((bfd *))) bfd_nullvoidptr)
+#define hpux_core_bfd_link_add_symbols \
+  ((boolean (*) PARAMS ((bfd *, struct bfd_link_info *))) bfd_false)
+#define hpux_core_bfd_final_link \
+  ((boolean (*) PARAMS ((bfd *, struct bfd_link_info *))) bfd_false)
+
+/* If somebody calls any byte-swapping routines, shoot them.  */
+void
+swap_abort()
+{
+  abort(); /* This way doesn't require any declaration for ANSI to fuck up */
+}
+#define        NO_GET  ((bfd_vma (*) PARAMS ((         bfd_byte *))) swap_abort )
+#define        NO_PUT  ((void    (*) PARAMS ((bfd_vma, bfd_byte *))) swap_abort )
+#define        NO_SIGNED_GET ((bfd_signed_vma (*) PARAMS ((bfd_byte *))) swap_abort )
+
+bfd_target hpux_core_vec =
+  {
+    "hpux-core",
+    bfd_target_unknown_flavour,
+    true,                      /* target byte order */
+    true,                      /* target headers byte order */
+    (HAS_RELOC | EXEC_P |      /* object flags */
+     HAS_LINENO | HAS_DEBUG |
+     HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
+    (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
+    0,                                                    /* symbol prefix */
+    ' ',                                                  /* ar_pad_char */
+    16,                                                           /* ar_max_namelen */
+    3,                                                    /* minimum alignment power */
+    NO_GET, NO_SIGNED_GET, NO_PUT,     /* 64 bit data */
+    NO_GET, NO_SIGNED_GET, NO_PUT,     /* 32 bit data */
+    NO_GET, NO_SIGNED_GET, NO_PUT,     /* 16 bit data */
+    NO_GET, NO_SIGNED_GET, NO_PUT,     /* 64 bit hdrs */
+    NO_GET, NO_SIGNED_GET, NO_PUT,     /* 32 bit hdrs */
+    NO_GET, NO_SIGNED_GET, NO_PUT,     /* 16 bit hdrs */
+
+    {                          /* bfd_check_format */
+     _bfd_dummy_target,                /* unknown format */
+     _bfd_dummy_target,                /* object file */
+     _bfd_dummy_target,                /* archive */
+     hpux_core_core_file_p     /* a core file */
+    },
+    {                          /* bfd_set_format */
+     bfd_false, bfd_false,
+     bfd_false, bfd_false
+    },
+    {                          /* bfd_write_contents */
+     bfd_false, bfd_false,
+     bfd_false, bfd_false
+    },
+    
+    JUMP_TABLE(hpux_core),
+    (PTR) 0                    /* backend_data */
+};
diff --git a/bfd/irix-core.c b/bfd/irix-core.c
new file mode 100644 (file)
index 0000000..b0482a4
--- /dev/null
@@ -0,0 +1,292 @@
+/* BFD back-end for Irix core files.
+   Copyright 1993 Free Software Foundation, Inc.
+   Written by Stu Grossman, Cygnus Support.
+   Converted to back-end form by Ian Lance Taylor, Cygnus Support
+
+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 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.  */
+
+/* This file can only be compiled on systems which use Irix style core
+   files (namely, Irix 4 and Irix 5, so far).  In the config/XXXXXX.mh
+   file for such a system add
+      HDEFINES=-DIRIX_CORE
+      HDEPFILES=irix-core.o
+   */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+#ifdef IRIX_CORE
+
+#include <core.out.h>
+
+struct sgi_core_struct 
+{
+  int sig;
+  char cmd[CORE_NAMESIZE];
+};
+
+#define core_hdr(bfd) ((bfd)->tdata.sgi_core_data)
+#define core_signal(bfd) (core_hdr(bfd)->sig)
+#define core_command(bfd) (core_hdr(bfd)->cmd)
+
+static asection *
+make_bfd_asection (abfd, name, flags, _raw_size, vma, filepos)
+     bfd *abfd;
+     CONST char *name;
+     flagword flags;
+     bfd_size_type _raw_size;
+     bfd_vma vma;
+     file_ptr filepos;
+{
+  asection *asect;
+
+  asect = bfd_make_section_anyway (abfd, name);
+  if (!asect)
+    return NULL;
+
+  asect->flags = flags;
+  asect->_raw_size = _raw_size;
+  asect->vma = vma;
+  asect->filepos = filepos;
+  asect->alignment_power = 4;
+
+  return asect;
+}
+
+static bfd_target *
+irix_core_core_file_p (abfd)
+     bfd *abfd;
+{
+  int val;
+  int i;
+  char *secname;
+  struct coreout coreout;
+  struct idesc *idg, *idf, *ids;
+
+  val = bfd_read ((PTR)&coreout, 1, sizeof coreout, abfd);
+  if (val != sizeof coreout)
+    return 0;
+
+  if (coreout.c_magic != CORE_MAGIC
+      || coreout.c_version != CORE_VERSION1)
+    return 0;
+
+  core_hdr (abfd) = (struct sgi_core_struct *) bfd_zalloc (abfd, sizeof (struct sgi_core_struct));
+  if (!core_hdr (abfd))
+    return NULL;
+
+  strncpy (core_command (abfd), coreout.c_name, CORE_NAMESIZE);
+  core_signal (abfd) = coreout.c_sigcause;
+
+  bfd_seek (abfd, coreout.c_vmapoffset, SEEK_SET);
+
+  for (i = 0; i < coreout.c_nvmap; i++)
+    {
+      struct vmap vmap;
+
+      val = bfd_read ((PTR)&vmap, 1, sizeof vmap, abfd);
+      if (val != sizeof vmap)
+       break;
+
+      switch (vmap.v_type)
+       {
+       case VDATA:
+         secname = ".data";
+         break;
+       case VSTACK:
+         secname = ".stack";
+         break;
+#ifdef VMAPFILE
+       case VMAPFILE:
+         secname = ".mapfile";
+         break;
+#endif
+       default:
+         continue;
+       }
+
+      if (!make_bfd_asection (abfd, secname,
+                             SEC_ALLOC+SEC_LOAD+SEC_HAS_CONTENTS,
+                             vmap.v_len,
+                             vmap.v_vaddr,
+                             vmap.v_offset,
+                             2))
+       return NULL;
+    }
+
+  /* Make sure that the regs are contiguous within the core file. */
+
+  idg = &coreout.c_idesc[I_GPREGS];
+  idf = &coreout.c_idesc[I_FPREGS];
+  ids = &coreout.c_idesc[I_SPECREGS];
+
+  if (idg->i_offset + idg->i_len != idf->i_offset
+      || idf->i_offset + idf->i_len != ids->i_offset)
+    return 0;                  /* Can't deal with non-contig regs */
+
+  bfd_seek (abfd, idg->i_offset, SEEK_SET);
+
+  make_bfd_asection (abfd, ".reg",
+                    SEC_ALLOC+SEC_HAS_CONTENTS,
+                    idg->i_len + idf->i_len + ids->i_len,
+                    0,
+                    idg->i_offset);
+
+  /* OK, we believe you.  You're a core file (sure, sure).  */
+
+  return abfd->xvec;
+}
+
+static char *
+irix_core_core_file_failing_command (abfd)
+     bfd *abfd;
+{
+  return core_command (abfd);
+}
+
+static int
+irix_core_core_file_failing_signal (abfd)
+     bfd *abfd;
+{
+  return core_signal (abfd);
+}
+
+static boolean
+irix_core_core_file_matches_executable_p (core_bfd, exec_bfd)
+     bfd *core_bfd, *exec_bfd;
+{
+  return true;                 /* XXX - FIXME */
+}
+
+static asymbol *
+irix_core_make_empty_symbol (abfd)
+     bfd *abfd;
+{
+  asymbol *new = (asymbol *) bfd_zalloc (abfd, sizeof (asymbol));
+  new->the_bfd = abfd;
+  return new;
+}
+
+#define        irix_core_openr_next_archived_file      bfd_generic_openr_next_archived_file
+#define        irix_core_generic_stat_arch_elt         bfd_generic_stat_arch_elt
+#define        irix_core_slurp_armap                   bfd_false
+#define        irix_core_slurp_extended_name_table     bfd_true
+#define        irix_core_write_armap                   (boolean (*) PARAMS     \
+    ((bfd *arch, unsigned int elength, struct orl *map, \
+      unsigned int orl_count, int stridx))) bfd_false
+#define        irix_core_truncate_arname               bfd_dont_truncate_arname
+
+#define        irix_core_close_and_cleanup             bfd_generic_close_and_cleanup
+#define        irix_core_set_section_contents          (boolean (*) PARAMS     \
+        ((bfd *abfd, asection *section, PTR data, file_ptr offset,     \
+        bfd_size_type count))) bfd_false
+#define        irix_core_get_section_contents          bfd_generic_get_section_contents
+#define        irix_core_new_section_hook              (boolean (*) PARAMS     \
+       ((bfd *, sec_ptr))) bfd_true
+#define        irix_core_get_symtab_upper_bound        bfd_0u
+#define        irix_core_get_symtab                    (unsigned int (*) PARAMS \
+        ((bfd *, struct symbol_cache_entry **))) bfd_0u
+#define        irix_core_get_reloc_upper_bound         (unsigned int (*) PARAMS \
+       ((bfd *, sec_ptr))) bfd_0u
+#define        irix_core_canonicalize_reloc            (unsigned int (*) PARAMS \
+       ((bfd *, sec_ptr, arelent **, struct symbol_cache_entry**))) bfd_0u
+#define        irix_core_print_symbol                  (void (*) PARAMS        \
+       ((bfd *, PTR, struct symbol_cache_entry  *,                     \
+       bfd_print_symbol_type))) bfd_false
+#define        irix_core_get_symbol_info               (void (*) PARAMS        \
+       ((bfd *, struct symbol_cache_entry  *,                  \
+       symbol_info *))) bfd_false
+#define        irix_core_get_lineno                    (alent * (*) PARAMS     \
+       ((bfd *, struct symbol_cache_entry *))) bfd_nullvoidptr
+#define        irix_core_set_arch_mach                 (boolean (*) PARAMS     \
+       ((bfd *, enum bfd_architecture, unsigned long))) bfd_false
+#define        irix_core_find_nearest_line             (boolean (*) PARAMS     \
+        ((bfd *abfd, struct sec  *section,                             \
+         struct symbol_cache_entry  **symbols,bfd_vma offset,          \
+         CONST char **file, CONST char **func, unsigned int *line))) bfd_false
+#define        irix_core_sizeof_headers                (int (*) PARAMS \
+       ((bfd *, boolean))) bfd_0
+
+#define irix_core_bfd_debug_info_start         bfd_void
+#define irix_core_bfd_debug_info_end           bfd_void
+#define irix_core_bfd_debug_info_accumulate    (void (*) PARAMS        \
+       ((bfd *, struct sec *))) bfd_void
+#define irix_core_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents
+#define irix_core_bfd_relax_section            bfd_generic_relax_section
+#define irix_core_bfd_reloc_type_lookup \
+  ((CONST struct reloc_howto_struct *(*) PARAMS ((bfd *, bfd_reloc_code_real_type))) bfd_nullvoidptr)
+#define irix_core_bfd_make_debug_symbol \
+  ((asymbol *(*) PARAMS ((bfd *, void *, unsigned long))) bfd_nullvoidptr)
+#define irix_core_bfd_link_hash_table_create \
+  ((struct bfd_link_hash_table *(*) PARAMS ((bfd *))) bfd_nullvoidptr)
+#define irix_core_bfd_link_add_symbols \
+  ((boolean (*) PARAMS ((bfd *, struct bfd_link_info *))) bfd_false)
+#define irix_core_bfd_final_link \
+  ((boolean (*) PARAMS ((bfd *, struct bfd_link_info *))) bfd_false)
+
+/* If somebody calls any byte-swapping routines, shoot them.  */
+void
+swap_abort()
+{
+  abort(); /* This way doesn't require any declaration for ANSI to fuck up */
+}
+#define        NO_GET  ((bfd_vma (*) PARAMS ((         bfd_byte *))) swap_abort )
+#define        NO_PUT  ((void    (*) PARAMS ((bfd_vma, bfd_byte *))) swap_abort )
+#define        NO_SIGNED_GET ((bfd_signed_vma (*) PARAMS ((bfd_byte *))) swap_abort )
+
+bfd_target irix_core_vec =
+  {
+    "irix-core",
+    bfd_target_unknown_flavour,
+    true,                      /* target byte order */
+    true,                      /* target headers byte order */
+    (HAS_RELOC | EXEC_P |      /* object flags */
+     HAS_LINENO | HAS_DEBUG |
+     HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
+    (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
+    0,                                                    /* symbol prefix */
+    ' ',                                                  /* ar_pad_char */
+    16,                                                           /* ar_max_namelen */
+    3,                                                    /* minimum alignment power */
+    NO_GET, NO_SIGNED_GET, NO_PUT,     /* 64 bit data */
+    NO_GET, NO_SIGNED_GET, NO_PUT,     /* 32 bit data */
+    NO_GET, NO_SIGNED_GET, NO_PUT,     /* 16 bit data */
+    NO_GET, NO_SIGNED_GET, NO_PUT,     /* 64 bit hdrs */
+    NO_GET, NO_SIGNED_GET, NO_PUT,     /* 32 bit hdrs */
+    NO_GET, NO_SIGNED_GET, NO_PUT,     /* 16 bit hdrs */
+
+    {                          /* bfd_check_format */
+     _bfd_dummy_target,                /* unknown format */
+     _bfd_dummy_target,                /* object file */
+     _bfd_dummy_target,                /* archive */
+     irix_core_core_file_p     /* a core file */
+    },
+    {                          /* bfd_set_format */
+     bfd_false, bfd_false,
+     bfd_false, bfd_false
+    },
+    {                          /* bfd_write_contents */
+     bfd_false, bfd_false,
+     bfd_false, bfd_false
+    },
+    
+    JUMP_TABLE(irix_core),
+    (PTR) 0                    /* backend_data */
+};
+
+#endif /* IRIX_CORE */
index f063817..1f89385 100644 (file)
@@ -26,7 +26,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
    for a 32-bit architecture or a 64-bit architecture.  */
 #if ARCH_SIZE==64
 #define GET_WORD bfd_h_get_64
-#define GET_SWORD (int64_type)GET_WORD
+#define GET_SWORD bfd_h_get_signed_64
 #define PUT_WORD bfd_h_put_64
 #ifndef NAME
 #define NAME(x,y) CAT3(x,_64_,y)
@@ -35,7 +35,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #define BYTES_IN_WORD 8
 #else /* ARCH_SIZE == 32 */
 #define GET_WORD bfd_h_get_32
-#define GET_SWORD (int32_type)GET_WORD
+#define GET_SWORD bfd_h_get_signed_32
 #define PUT_WORD bfd_h_put_32
 #ifndef NAME
 #define NAME(x,y) CAT3(x,_32_,y)
@@ -111,6 +111,12 @@ struct internal_exec
 3130292827262524232221201918171615141312111009080706050403020100
 < FLAGS      >< MACHINE TYPE ><  MAGIC NUMBER                 >
 */
+/* Magic number for NetBSD is
+<MSB         >
+3130292827262524232221201918171615141312111009080706050403020100
+< FLAGS    ><                  ><  MAGIC NUMBER                >
+*/
+
 enum machine_type {
   M_UNKNOWN = 0,
   M_68010 = 1,
@@ -119,6 +125,8 @@ enum machine_type {
   /* skip a bunch so we don't run into any of suns numbers */
   M_386 = 100,
   M_29K = 101,          /* AMD 29000 */
+  M_386_DYNIX = 102,   /* Sequent running dynix */
+  M_386_NETBSD = 134,          /* NetBSD/386 binary */
   M_MIPS1 = 151,        /* MIPS R2000/R3000 binary */
   M_MIPS2 = 152,        /* MIPS R4000/R6000 binary */
   M_HP200 = 200,       /* HP 200 (68010) BSD binary */
@@ -128,24 +136,41 @@ enum machine_type {
 
 #define N_DYNAMIC(exec) ((exec).a_info & 0x8000000)
 
-#define N_MAGIC(exec) ((exec).a_info & 0xffff)
-#define N_MACHTYPE(exec) ((enum machine_type)(((exec).a_info >> 16) & 0xff))
-#define N_FLAGS(exec) (((exec).a_info >> 24) & 0xff)
-#define N_SET_INFO(exec, magic, type, flags) \
+#ifndef N_MAGIC
+# define N_MAGIC(exec) ((exec).a_info & 0xffff)
+#endif
+
+#ifndef N_MACHTYPE
+# define N_MACHTYPE(exec) ((enum machine_type)(((exec).a_info >> 16) & 0xff))
+#endif
+
+#ifndef N_FLAGS
+# define N_FLAGS(exec) (((exec).a_info >> 24) & 0xff)
+#endif
+
+#ifndef N_SET_INFO
+# define N_SET_INFO(exec, magic, type, flags) \
 ((exec).a_info = ((magic) & 0xffff) \
  | (((int)(type) & 0xff) << 16) \
  | (((flags) & 0xff) << 24))
+#endif
 
-#define N_SET_MAGIC(exec, magic) \
+#ifndef N_SET_MAGIC
+# define N_SET_MAGIC(exec, magic) \
 ((exec).a_info = (((exec).a_info & 0xffff0000) | ((magic) & 0xffff)))
+#endif
 
-#define N_SET_MACHTYPE(exec, machtype) \
+#ifndef N_SET_MACHTYPE
+# define N_SET_MACHTYPE(exec, machtype) \
 ((exec).a_info = \
  ((exec).a_info&0xff00ffff) | ((((int)(machtype))&0xff) << 16))
+#endif
 
-#define N_SET_FLAGS(exec, flags) \
+#ifndef N_SET_FLAGS
+# define N_SET_FLAGS(exec, flags) \
 ((exec).a_info = \
  ((exec).a_info&0x00ffffff) | (((flags) & 0xff) << 24))
+#endif
 
 typedef struct aout_symbol {
   asymbol symbol;
@@ -197,6 +222,12 @@ struct aoutdata {
     z_magic,
     o_magic,
     n_magic } magic;
+
+  /* The external symbol information.  */
+  struct external_nlist *external_syms;
+  bfd_size_type external_sym_count;
+  char *external_strings;
+  struct aout_link_hash_entry **sym_hashes;
 };
 
 struct  aout_data_struct {
@@ -215,6 +246,10 @@ struct  aout_data_struct {
 #define        obj_reloc_entry_size(bfd) (adata(bfd).reloc_entry_size)
 #define        obj_symbol_entry_size(bfd) (adata(bfd).symbol_entry_size)
 #define obj_aout_subformat(bfd)        (adata(bfd).subformat)
+#define obj_aout_external_syms(bfd) (adata(bfd).external_syms)
+#define obj_aout_external_sym_count(bfd) (adata(bfd).external_sym_count)
+#define obj_aout_external_strings(bfd) (adata(bfd).external_strings)
+#define obj_aout_sym_hashes(bfd) (adata(bfd).sym_hashes)
 
 /* We take the address of the first element of an asymbol to ensure that the
    macro is only ever applied to an asymbol */
@@ -254,7 +289,7 @@ NAME(aout,make_empty_symbol) PARAMS ((bfd *abfd));
 boolean
 NAME(aout,slurp_symbol_table) PARAMS ((bfd *abfd));
 
-void
+boolean
 NAME(aout,write_syms) PARAMS ((bfd *abfd));
 
 void
@@ -314,6 +349,17 @@ void
 NAME(aout,swap_exec_header_out) PARAMS ((bfd *abfd,
        struct internal_exec *execp, struct external_exec *raw_bytes));
 
+struct bfd_link_hash_table *
+NAME(aout,link_hash_table_create) PARAMS ((bfd *));
+
+boolean
+NAME(aout,link_add_symbols) PARAMS ((bfd *, struct bfd_link_info *));
+
+boolean
+NAME(aout,final_link) PARAMS ((bfd *, struct bfd_link_info *,
+                              void (*) (bfd *, file_ptr *, file_ptr *,
+                                        file_ptr *)));
+
 /* Prototypes for functions in stab-syms.c. */
 
 CONST char *
@@ -351,11 +397,12 @@ aout_stab_name PARAMS ((int code));
        bfd_write ((PTR) &exec_bytes, 1, EXEC_BYTES_SIZE, abfd);              \
        /* Now write out reloc info, followed by syms and strings */          \
                                                                              \
-       if (bfd_get_symcount (abfd) != 0)                                     \
+       if (bfd_get_outsymbols (abfd) != (asymbol **) NULL                    \
+           && bfd_get_symcount (abfd) != 0)                                  \
            {                                                                 \
              bfd_seek (abfd, (file_ptr)(N_SYMOFF(*execp)), SEEK_SET);        \
                                                                              \
-             NAME(aout,write_syms)(abfd);                                    \
+             if (! NAME(aout,write_syms)(abfd)) return false;                \
                                                                              \
              bfd_seek (abfd, (file_ptr)(N_TRELOFF(*execp)), SEEK_SET);       \
                                                                              \
index 0f9a2cd..5ba73fe 100644 (file)
@@ -19,6 +19,12 @@ 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.  */
 
+/* Use builtin alloca for gcc.  */
+#ifdef __GNUC__
+#ifndef alloca
+#define alloca __builtin_alloca
+#endif
+#endif
 
 /* Align an address upward to a boundary, expressed as a number of bytes.
    E.g. align to an 8-byte boundary with argument of 8.  */
@@ -44,7 +50,8 @@ struct artdata {
   carsym *symdefs;             /* the symdef entries */
   symindex symdef_count;             /* how many there are */
   char *extended_names;                /* clever intel extension */
-  time_t armap_timestamp;      /* Timestamp value written into armap.
+  /* when more compilers are standard C, this can be a time_t */
+  long  armap_timestamp;       /* Timestamp value written into armap.
                                   This is used for BSD archives to check
                                   that the timestamp is recent enough
                                   for the BSD linker to not complain,
@@ -88,6 +95,9 @@ int           bfd_seek  PARAMS ((bfd* CONST abfd, CONST file_ptr fp,
                                   CONST int direction));
 long           bfd_tell  PARAMS ((bfd *abfd));
 
+int            bfd_flush PARAMS ((bfd *abfd));
+int            bfd_stat  PARAMS ((bfd *abfd, struct stat *));
+
 bfd *  _bfd_create_empty_archive_element_shell PARAMS ((bfd *obfd));
 bfd *  look_for_bfd_in_cache PARAMS ((bfd *arch_bfd, file_ptr index));
 boolean        _bfd_generic_mkarchive PARAMS ((bfd *abfd));
@@ -99,7 +109,7 @@ boolean bfd_slurp_bsd_armap_f2 PARAMS ((bfd *abfd));
 #define bfd_slurp_coff_armap bfd_slurp_armap
 boolean        _bfd_slurp_extended_name_table PARAMS ((bfd *abfd));
 boolean        _bfd_write_archive_contents PARAMS ((bfd *abfd));
-bfd *  new_bfd PARAMS (());
+bfd *  new_bfd PARAMS ((void));
 
 #define DEFAULT_STRING_SPACE_SIZE 0x2000
 boolean        bfd_add_to_string_table PARAMS ((char **table, char *new_string,
@@ -146,7 +156,60 @@ boolean    bfd_generic_get_section_contents PARAMS ((bfd *abfd, sec_ptr section,
 boolean        bfd_generic_set_section_contents PARAMS ((bfd *abfd, sec_ptr section,
                                                  PTR location, file_ptr offset,
                                                  bfd_size_type count));
-
+\f
+/* A routine to create entries for a bfd_link_hash_table.  */
+extern struct bfd_hash_entry *_bfd_link_hash_newfunc
+  PARAMS ((struct bfd_hash_entry *entry,
+          struct bfd_hash_table *table,
+          const char *string));
+
+/* Initialize a bfd_link_hash_table.  */
+extern boolean _bfd_link_hash_table_init
+  PARAMS ((struct bfd_link_hash_table *, bfd *,
+          struct bfd_hash_entry *(*) (struct bfd_hash_entry *,
+                                      struct bfd_hash_table *,
+                                      const char *)));
+
+/* Generic link hash table creation routine.  */
+extern struct bfd_link_hash_table *_bfd_generic_link_hash_table_create
+  PARAMS ((bfd *));
+
+/* Generic add symbol routine.  */
+extern boolean _bfd_generic_link_add_symbols
+  PARAMS ((bfd *, struct bfd_link_info *));
+
+/* Generic archive add symbol routine.  */
+extern boolean _bfd_generic_link_add_archive_symbols
+  PARAMS ((bfd *, struct bfd_link_info *,
+          boolean (*checkfn) (bfd *, struct bfd_link_info *, boolean *)));
+
+/* Forward declaration to avoid prototype errors.  */
+typedef struct bfd_link_hash_entry _bfd_link_hash_entry;
+
+/* Generic routine to add a single symbol.  */
+extern boolean _bfd_generic_link_add_one_symbol
+  PARAMS ((struct bfd_link_info *, bfd *, const char *name, flagword,
+          asection *, bfd_vma, const char *, boolean copy,
+          struct bfd_link_hash_entry **));
+
+/* Generic link routine.  */
+extern boolean _bfd_generic_final_link
+  PARAMS ((bfd *, struct bfd_link_info *));
+
+/* Default link order processing routine.  */
+extern boolean _bfd_default_link_order
+  PARAMS ((bfd *, struct bfd_link_info *, asection *,
+          struct bfd_link_order *));
+
+/* Final link relocation routine.  */
+extern bfd_reloc_status_type _bfd_final_link_relocate
+  PARAMS ((const reloc_howto_type *, bfd *, asection *, bfd_byte *,
+          bfd_vma address, bfd_vma value, bfd_vma addend));
+
+/* Relocate a particular location by a howto and a value.  */
+extern bfd_reloc_status_type _bfd_relocate_contents
+  PARAMS ((const reloc_howto_type *, bfd *, bfd_vma, bfd_byte *));
+\f
 /* Macros to tell if bfds are read or write enabled.
 
    Note that bfds open for read may be scribbled into if the fd passed
@@ -183,5 +246,10 @@ extern bfd *bfd_last_cache;
 /* Generic routine for close_and_cleanup is really just bfd_true.  */
 #define        bfd_generic_close_and_cleanup   bfd_true
 
+/* List of supported target vectors, and the default vector (if
+   default_vector[0] is NULL, there is no default).  */
+extern bfd_target *target_vector[];
+extern bfd_target *default_vector[];
+
 /* And more follows */
 
index 74a28af..10e9a9d 100644 (file)
@@ -1,5 +1,5 @@
 /* Assorted BFD support routines, only used internally.
-   Copyright 1990, 1991, 1992 Free Software Foundation, Inc.
+   Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
    Written by Cygnus Support.
 
 This file is part of BFD, the Binary File Descriptor library.
@@ -310,7 +310,7 @@ DEFUN(bfd_seek,(abfd, position, direction),
 #ifdef FILE_OFFSET_IS_CHAR_INDEX
   if (abfd->format != bfd_archive && abfd->my_archive == 0)
     {
-#ifndef NDEBUG
+#if 0
       /* Explanation for this code: I'm only about 95+% sure that the above
         conditions are sufficient and that all i/o calls are properly
         adjusting the `where' field.  So this is sort of an `assert'
@@ -461,7 +461,7 @@ DESCRIPTION
 .{* Byte swapping macros for user section data.  *}
 .
 .#define bfd_put_8(abfd, val, ptr) \
-.                (*((unsigned char *)(ptr)) = (unsigned char)val)
+.                (*((unsigned char *)(ptr)) = (unsigned char)(val))
 .#define bfd_put_signed_8 \
 .              bfd_put_8
 .#define bfd_get_8(abfd, ptr) \
index 34f1968..e9b0560 100644 (file)
@@ -19,6 +19,12 @@ 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.  */
 
+/* Use builtin alloca for gcc.  */
+#ifdef __GNUC__
+#ifndef alloca
+#define alloca __builtin_alloca
+#endif
+#endif
 
 /* Align an address upward to a boundary, expressed as a number of bytes.
    E.g. align to an 8-byte boundary with argument of 8.  */
@@ -103,7 +109,7 @@ boolean bfd_slurp_bsd_armap_f2 PARAMS ((bfd *abfd));
 #define bfd_slurp_coff_armap bfd_slurp_armap
 boolean        _bfd_slurp_extended_name_table PARAMS ((bfd *abfd));
 boolean        _bfd_write_archive_contents PARAMS ((bfd *abfd));
-bfd *  new_bfd PARAMS (());
+bfd *  new_bfd PARAMS ((void));
 
 #define DEFAULT_STRING_SPACE_SIZE 0x2000
 boolean        bfd_add_to_string_table PARAMS ((char **table, char *new_string,
@@ -150,7 +156,60 @@ boolean    bfd_generic_get_section_contents PARAMS ((bfd *abfd, sec_ptr section,
 boolean        bfd_generic_set_section_contents PARAMS ((bfd *abfd, sec_ptr section,
                                                  PTR location, file_ptr offset,
                                                  bfd_size_type count));
-
+\f
+/* A routine to create entries for a bfd_link_hash_table.  */
+extern struct bfd_hash_entry *_bfd_link_hash_newfunc
+  PARAMS ((struct bfd_hash_entry *entry,
+          struct bfd_hash_table *table,
+          const char *string));
+
+/* Initialize a bfd_link_hash_table.  */
+extern boolean _bfd_link_hash_table_init
+  PARAMS ((struct bfd_link_hash_table *, bfd *,
+          struct bfd_hash_entry *(*) (struct bfd_hash_entry *,
+                                      struct bfd_hash_table *,
+                                      const char *)));
+
+/* Generic link hash table creation routine.  */
+extern struct bfd_link_hash_table *_bfd_generic_link_hash_table_create
+  PARAMS ((bfd *));
+
+/* Generic add symbol routine.  */
+extern boolean _bfd_generic_link_add_symbols
+  PARAMS ((bfd *, struct bfd_link_info *));
+
+/* Generic archive add symbol routine.  */
+extern boolean _bfd_generic_link_add_archive_symbols
+  PARAMS ((bfd *, struct bfd_link_info *,
+          boolean (*checkfn) (bfd *, struct bfd_link_info *, boolean *)));
+
+/* Forward declaration to avoid prototype errors.  */
+typedef struct bfd_link_hash_entry _bfd_link_hash_entry;
+
+/* Generic routine to add a single symbol.  */
+extern boolean _bfd_generic_link_add_one_symbol
+  PARAMS ((struct bfd_link_info *, bfd *, const char *name, flagword,
+          asection *, bfd_vma, const char *, boolean copy,
+          struct bfd_link_hash_entry **));
+
+/* Generic link routine.  */
+extern boolean _bfd_generic_final_link
+  PARAMS ((bfd *, struct bfd_link_info *));
+
+/* Default link order processing routine.  */
+extern boolean _bfd_default_link_order
+  PARAMS ((bfd *, struct bfd_link_info *, asection *,
+          struct bfd_link_order *));
+
+/* Final link relocation routine.  */
+extern bfd_reloc_status_type _bfd_final_link_relocate
+  PARAMS ((const reloc_howto_type *, bfd *, asection *, bfd_byte *,
+          bfd_vma address, bfd_vma value, bfd_vma addend));
+
+/* Relocate a particular location by a howto and a value.  */
+extern bfd_reloc_status_type _bfd_relocate_contents
+  PARAMS ((const reloc_howto_type *, bfd *, bfd_vma, bfd_byte *));
+\f
 /* Macros to tell if bfds are read or write enabled.
 
    Note that bfds open for read may be scribbled into if the fd passed
@@ -187,6 +246,11 @@ extern bfd *bfd_last_cache;
 /* Generic routine for close_and_cleanup is really just bfd_true.  */
 #define        bfd_generic_close_and_cleanup   bfd_true
 
+/* List of supported target vectors, and the default vector (if
+   default_vector[0] is NULL, there is no default).  */
+extern bfd_target *target_vector[];
+extern bfd_target *default_vector[];
+
 /* And more follows */
 
 void 
@@ -234,14 +298,17 @@ boolean
 bfd_generic_relax_section
  PARAMS ((bfd *abfd,
     asection *section,
+    struct bfd_link_info *,
     asymbol **symbols));
 
 bfd_byte *
 
 bfd_generic_get_relocated_section_contents  PARAMS ((bfd *abfd,
-    struct bfd_seclet *seclet,
+    struct bfd_link_info *link_info,
+    struct bfd_link_order *link_order,
     bfd_byte *data,
-    boolean relocateable));
+    boolean relocateable,
+    asymbol **symbols));
 
 boolean 
 bfd_generic_seclet_link
index 838df6c..311bb1f 100644 (file)
@@ -241,7 +241,8 @@ extern bfd_reloc_status_type bfd_elf_generic_reloc PARAMS ((bfd *,
                                                            asymbol *,
                                                            PTR,
                                                            asection *,
-                                                           bfd *));
+                                                           bfd *,
+                                                           char **));
 extern boolean bfd_elf_mkobject PARAMS ((bfd *));
 extern Elf_Internal_Shdr *bfd_elf_find_section PARAMS ((bfd *, char *));
 
diff --git a/bfd/osf-core.c b/bfd/osf-core.c
new file mode 100644 (file)
index 0000000..c8c988c
--- /dev/null
@@ -0,0 +1,298 @@
+/* BFD back-end for OSF/1 core files.
+   Copyright 1993 Free Software Foundation, Inc.
+
+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 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.  */
+
+/* This file can only be compiled on systems which use OSF/1 style
+   core files.  In the config/XXXXXX.mh file for such a system add
+      HDEFINES=-DOSF_CORE
+      HDEPFILES=osf-core.o
+   */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/user.h>
+#include <sys/core.h>
+
+/* forward declarations */
+
+static asection *
+make_bfd_asection PARAMS ((bfd *, CONST char *, flagword, bfd_size_type,
+                          bfd_vma, file_ptr));
+static asymbol *
+osf_core_make_empty_symbol PARAMS ((bfd *));
+static bfd_target *
+osf_core_core_file_p PARAMS ((bfd *));
+static char *
+osf_core_core_file_failing_command PARAMS ((bfd *));
+static int
+osf_core_core_file_failing_signal PARAMS ((bfd *));
+static boolean
+osf_core_core_file_matches_executable_p PARAMS ((bfd *, bfd *));
+static void
+swap_abort PARAMS ((void));
+
+/* These are stored in the bfd's tdata */
+
+struct osf_core_struct 
+{
+  int sig;
+  char cmd[MAXCOMLEN + 1];
+};
+
+#define core_hdr(bfd) ((bfd)->tdata.osf_core_data)
+#define core_signal(bfd) (core_hdr(bfd)->sig)
+#define core_command(bfd) (core_hdr(bfd)->cmd)
+
+static asection *
+make_bfd_asection (abfd, name, flags, _raw_size, vma, filepos)
+     bfd *abfd;
+     CONST char *name;
+     flagword flags;
+     bfd_size_type _raw_size;
+     bfd_vma vma;
+     file_ptr filepos;
+{
+  asection *asect;
+
+  asect = bfd_make_section (abfd, name);
+  if (!asect)
+    return NULL;
+
+  asect->flags = flags;
+  asect->_raw_size = _raw_size;
+  asect->vma = vma;
+  asect->filepos = filepos;
+  asect->alignment_power = 8;
+
+  return asect;
+}
+
+static asymbol *
+osf_core_make_empty_symbol (abfd)
+     bfd *abfd;
+{
+  asymbol *new = (asymbol *) bfd_zalloc (abfd, sizeof (asymbol));
+  new->the_bfd = abfd;
+  return new;
+}
+
+static bfd_target *
+osf_core_core_file_p (abfd)
+     bfd *abfd;
+{
+  int val;
+  int i;
+  char *secname;
+  struct core_filehdr core_header;
+  int dseccnt = 0;
+
+  val = bfd_read ((PTR)&core_header, 1, sizeof core_header, abfd);
+  if (val != sizeof core_header)
+    return NULL;
+
+  if (strncmp (core_header.magic, "Core", 4) != 0)
+    return NULL;
+
+  core_hdr (abfd) = (struct osf_core_struct *)
+    bfd_zalloc (abfd, sizeof (struct osf_core_struct));
+  if (!core_hdr (abfd))
+    return NULL;
+
+  strncpy (core_command (abfd), core_header.name, MAXCOMLEN + 1);
+  core_signal (abfd) = core_header.signo;
+
+  for (i = 0; i < core_header.nscns; i++)
+    {
+      struct core_scnhdr core_scnhdr;
+
+      val = bfd_read ((PTR)&core_scnhdr, 1, sizeof core_scnhdr, abfd);
+      if (val != sizeof core_scnhdr)
+       break;
+
+      /* Skip empty sections.  */
+      if (core_scnhdr.size == 0 || core_scnhdr.scnptr == 0)
+       continue;
+
+      switch (core_scnhdr.scntype)
+       {
+       case SCNRGN:
+         /* OSF/1 has multiple data sections (data, bss and data/bss sections
+            for shared libraries), but bfd doesn't permit data sections with
+            the same name. Construct a unique section name.  */
+         secname = bfd_alloc (abfd, 40);
+         sprintf (secname, ".data%d", dseccnt++);
+         break;
+       case SCNSTACK:
+         secname = ".stack";
+         break;
+       case SCNREGS:
+         secname = ".reg";
+         break;
+       default:
+         fprintf (stderr, "Unhandled OSF/1 core file section type %d\n",
+                  core_scnhdr.scntype);
+         continue;
+       }
+
+      if (!make_bfd_asection (abfd, secname,
+                             SEC_ALLOC+SEC_LOAD+SEC_HAS_CONTENTS,
+                             (bfd_size_type) core_scnhdr.size,
+                             (bfd_vma) core_scnhdr.vaddr,
+                             (file_ptr) core_scnhdr.scnptr))
+       return NULL;
+    }
+
+  /* OK, we believe you.  You're a core file (sure, sure).  */
+
+  return abfd->xvec;
+}
+
+static char *
+osf_core_core_file_failing_command (abfd)
+     bfd *abfd;
+{
+  return core_command (abfd);
+}
+
+/* ARGSUSED */
+static int
+osf_core_core_file_failing_signal (abfd)
+     bfd *abfd;
+{
+  return core_signal (abfd);
+}
+
+/* ARGSUSED */
+static boolean
+osf_core_core_file_matches_executable_p (core_bfd, exec_bfd)
+     bfd *core_bfd, *exec_bfd;
+{
+  return true;         /* FIXME, We have no way of telling at this point */
+}
+\f
+/* No archive file support via this BFD */
+#define        osf_core_openr_next_archived_file       bfd_generic_openr_next_archived_file
+#define        osf_core_generic_stat_arch_elt          bfd_generic_stat_arch_elt
+#define        osf_core_slurp_armap                    bfd_false
+#define        osf_core_slurp_extended_name_table      bfd_true
+#define        osf_core_write_armap                    (boolean (*) PARAMS     \
+    ((bfd *arch, unsigned int elength, struct orl *map, \
+      unsigned int orl_count, int stridx))) bfd_false
+#define        osf_core_truncate_arname                bfd_dont_truncate_arname
+
+#define        osf_core_close_and_cleanup              bfd_generic_close_and_cleanup
+#define        osf_core_set_section_contents           (boolean (*) PARAMS     \
+        ((bfd *abfd, asection *section, PTR data, file_ptr offset,     \
+        bfd_size_type count))) bfd_false
+#define        osf_core_get_section_contents           bfd_generic_get_section_contents
+#define        osf_core_new_section_hook               (boolean (*) PARAMS     \
+       ((bfd *, sec_ptr))) bfd_true
+#define        osf_core_get_symtab_upper_bound bfd_0u
+#define        osf_core_get_symtab                     (unsigned int (*) PARAMS \
+        ((bfd *, struct symbol_cache_entry **))) bfd_0u
+#define        osf_core_get_reloc_upper_bound          (unsigned int (*) PARAMS \
+       ((bfd *, sec_ptr))) bfd_0u
+#define        osf_core_canonicalize_reloc             (unsigned int (*) PARAMS \
+       ((bfd *, sec_ptr, arelent **, struct symbol_cache_entry**))) bfd_0u
+#define        osf_core_print_symbol                   (void (*) PARAMS        \
+       ((bfd *, PTR, struct symbol_cache_entry  *,                     \
+       bfd_print_symbol_type))) bfd_false
+#define        osf_core_get_symbol_info                (void (*) PARAMS        \
+       ((bfd *, struct symbol_cache_entry  *,                  \
+       symbol_info *))) bfd_false
+#define        osf_core_get_lineno                     (alent * (*) PARAMS     \
+       ((bfd *, struct symbol_cache_entry *))) bfd_nullvoidptr
+#define        osf_core_set_arch_mach                  (boolean (*) PARAMS     \
+       ((bfd *, enum bfd_architecture, unsigned long))) bfd_false
+#define        osf_core_find_nearest_line              (boolean (*) PARAMS     \
+        ((bfd *abfd, struct sec  *section,                             \
+         struct symbol_cache_entry  **symbols,bfd_vma offset,          \
+         CONST char **file, CONST char **func, unsigned int *line))) bfd_false
+#define        osf_core_sizeof_headers         (int (*) PARAMS \
+       ((bfd *, boolean))) bfd_0
+
+#define osf_core_bfd_debug_info_start          bfd_void
+#define osf_core_bfd_debug_info_end            bfd_void
+#define osf_core_bfd_debug_info_accumulate     (void (*) PARAMS        \
+       ((bfd *, struct sec *))) bfd_void
+#define osf_core_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents
+#define osf_core_bfd_relax_section             bfd_generic_relax_section
+#define osf_core_bfd_reloc_type_lookup \
+  ((CONST struct reloc_howto_struct *(*) PARAMS ((bfd *, bfd_reloc_code_real_type))) bfd_nullvoidptr)
+#define osf_core_bfd_make_debug_symbol \
+  ((asymbol *(*) PARAMS ((bfd *, void *, unsigned long))) bfd_nullvoidptr)
+#define osf_core_bfd_link_hash_table_create \
+  ((struct bfd_link_hash_table *(*) PARAMS ((bfd *))) bfd_nullvoidptr)
+#define osf_core_bfd_link_add_symbols \
+  ((boolean (*) PARAMS ((bfd *, struct bfd_link_info *))) bfd_false)
+#define osf_core_bfd_final_link \
+  ((boolean (*) PARAMS ((bfd *, struct bfd_link_info *))) bfd_false)
+
+/* If somebody calls any byte-swapping routines, shoot them.  */
+static void
+swap_abort()
+{
+  abort(); /* This way doesn't require any declaration for ANSI to fuck up */
+}
+#define        NO_GET  ((bfd_vma (*) PARAMS ((         bfd_byte *))) swap_abort )
+#define        NO_PUT  ((void    (*) PARAMS ((bfd_vma, bfd_byte *))) swap_abort )
+#define        NO_SIGNED_GET ((bfd_signed_vma (*) PARAMS ((bfd_byte *))) swap_abort )
+
+bfd_target osf_core_vec =
+  {
+    "osf-core",
+    bfd_target_unknown_flavour,
+    true,                      /* target byte order */
+    true,                      /* target headers byte order */
+    (HAS_RELOC | EXEC_P |      /* object flags */
+     HAS_LINENO | HAS_DEBUG |
+     HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
+    (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
+    0,                                                    /* symbol prefix */
+    ' ',                                                  /* ar_pad_char */
+    16,                                                           /* ar_max_namelen */
+    3,                                                    /* minimum alignment power */
+    NO_GET, NO_SIGNED_GET, NO_PUT,     /* 64 bit data */
+    NO_GET, NO_SIGNED_GET, NO_PUT,     /* 32 bit data */
+    NO_GET, NO_SIGNED_GET, NO_PUT,     /* 16 bit data */
+    NO_GET, NO_SIGNED_GET, NO_PUT,     /* 64 bit hdrs */
+    NO_GET, NO_SIGNED_GET, NO_PUT,     /* 32 bit hdrs */
+    NO_GET, NO_SIGNED_GET, NO_PUT,     /* 16 bit hdrs */
+
+    {                          /* bfd_check_format */
+     _bfd_dummy_target,                /* unknown format */
+     _bfd_dummy_target,                /* object file */
+     _bfd_dummy_target,                /* archive */
+     osf_core_core_file_p      /* a core file */
+    },
+    {                          /* bfd_set_format */
+     bfd_false, bfd_false,
+     bfd_false, bfd_false
+    },
+    {                          /* bfd_write_contents */
+     bfd_false, bfd_false,
+     bfd_false, bfd_false
+    },
+    
+    JUMP_TABLE(osf_core),
+    (PTR) 0                    /* backend_data */
+};
diff --git a/bfd/ptrace-core.c b/bfd/ptrace-core.c
new file mode 100644 (file)
index 0000000..5b07ea1
--- /dev/null
@@ -0,0 +1,303 @@
+/* BFD backend for core files which use the ptrace_user structure
+   Copyright 1993 Free Software Foundation, Inc.
+   The structure of this file is based on trad-core.c written by John Gilmore
+   of Cygnus Support.
+   Modified to work with the ptrace_user structure by Kevin A. Buettner.
+   (Longterm it may be better to merge this file with trad-core.c)
+
+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 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.
+
+   To use this file on a particular host, configure the host with these
+   parameters in the config/h-HOST file:
+
+       HDEFINES=-DPTRACE_CORE
+       HDEPFILES=ptrace-core.o
+
+*/
+
+#ifdef PTRACE_CORE
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/dir.h>
+#include <signal.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/ptrace.h>
+
+
+struct trad_core_struct
+  {
+    asection *data_section;
+    asection *stack_section;
+    asection *reg_section;
+    struct ptrace_user u;
+  } *rawptr;
+
+#define core_upage(bfd) (&((bfd)->tdata.trad_core_data->u))
+#define core_datasec(bfd) ((bfd)->tdata.trad_core_data->data_section)
+#define core_stacksec(bfd) ((bfd)->tdata.trad_core_data->stack_section)
+#define core_regsec(bfd) ((bfd)->tdata.trad_core_data->reg_section)
+
+/* forward declarations */
+
+bfd_target *   ptrace_unix_core_file_p PARAMS ((bfd *abfd));
+char *         ptrace_unix_core_file_failing_command PARAMS ((bfd *abfd));
+int            ptrace_unix_core_file_failing_signal PARAMS ((bfd *abfd));
+boolean                ptrace_unix_core_file_matches_executable_p
+                        PARAMS ((bfd *core_bfd, bfd *exec_bfd));
+
+/* ARGSUSED */
+bfd_target *
+ptrace_unix_core_file_p (abfd)
+     bfd *abfd;
+
+{
+  int val;
+  struct ptrace_user u;
+
+  val = bfd_read ((void *)&u, 1, sizeof u, abfd);
+  if (val != sizeof u || u.pt_magic != _BCS_PTRACE_MAGIC 
+      || u.pt_rev != _BCS_PTRACE_REV)
+    {
+      /* Too small to be a core file */
+      bfd_error = wrong_format;
+      return 0;
+    }
+
+  /* OK, we believe you.  You're a core file (sure, sure).  */
+
+  /* Allocate both the upage and the struct core_data at once, so
+     a single free() will free them both.  */
+  rawptr = (struct trad_core_struct *)
+               bfd_zalloc (abfd, sizeof (struct trad_core_struct));
+
+  if (rawptr == NULL) {
+    bfd_error = no_memory;
+    return 0;
+  }
+  
+  abfd->tdata.trad_core_data = rawptr;
+
+  rawptr->u = u; /*Copy the uarea into the tdata part of the bfd */
+
+  /* Create the sections.  This is raunchy, but bfd_close wants to free
+     them separately.  */
+
+  core_stacksec(abfd) = (asection *) zalloc (sizeof (asection));
+  if (core_stacksec (abfd) == NULL) {
+  loser:
+    bfd_error = no_memory;
+    free ((void *)rawptr);
+    return 0;
+  }
+  core_datasec (abfd) = (asection *) zalloc (sizeof (asection));
+  if (core_datasec (abfd) == NULL) {
+  loser1:
+    free ((void *)core_stacksec (abfd));
+    goto loser;
+  }
+  core_regsec (abfd) = (asection *) zalloc (sizeof (asection));
+  if (core_regsec (abfd) == NULL) {
+    free ((void *)core_datasec (abfd));
+    goto loser1;
+  }
+
+  core_stacksec (abfd)->name = ".stack";
+  core_datasec (abfd)->name = ".data";
+  core_regsec (abfd)->name = ".reg";
+
+  /* FIXME:  Need to worry about shared memory, library data, and library
+     text.  I don't think that any of these things are supported on the
+     system on which I am developing this for though. */
+
+
+  core_stacksec (abfd)->flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
+  core_datasec (abfd)->flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
+  core_regsec (abfd)->flags = SEC_ALLOC + SEC_HAS_CONTENTS;
+
+  core_datasec (abfd)->_raw_size =  u.pt_dsize;
+  core_stacksec (abfd)->_raw_size = u.pt_ssize;
+  core_regsec (abfd)->_raw_size = sizeof(u);
+
+  core_datasec (abfd)->vma = u.pt_o_data_start;
+  core_stacksec (abfd)->vma = USRSTACK - u.pt_ssize;
+  core_regsec (abfd)->vma = 0 - sizeof(u);     /* see trad-core.c */
+
+  core_datasec (abfd)->filepos = (int) u.pt_dataptr;
+  core_stacksec (abfd)->filepos = (int) (u.pt_dataptr + u.pt_dsize);
+  core_regsec (abfd)->filepos = 0; /* Register segment is ptrace_user */
+
+  /* Align to word at least */
+  core_stacksec (abfd)->alignment_power = 2;
+  core_datasec (abfd)->alignment_power = 2;
+  core_regsec (abfd)->alignment_power = 2;
+
+  abfd->sections = core_stacksec (abfd);
+  core_stacksec (abfd)->next = core_datasec (abfd);
+  core_datasec (abfd)->next = core_regsec (abfd);
+  abfd->section_count = 3;
+
+  return abfd->xvec;
+}
+
+char *
+ptrace_unix_core_file_failing_command (abfd)
+     bfd *abfd;
+{
+  char *com = abfd->tdata.trad_core_data->u.pt_comm;
+  if (*com)
+    return com;
+  else
+    return 0;
+}
+
+/* ARGSUSED */
+int
+ptrace_unix_core_file_failing_signal (abfd)
+     bfd *abfd;
+{
+  return abfd->tdata.trad_core_data->u.pt_sigframe.sig_num;
+}
+
+/* ARGSUSED */
+boolean
+ptrace_unix_core_file_matches_executable_p  (core_bfd, exec_bfd)
+     bfd *core_bfd, *exec_bfd;
+{
+  /* FIXME: Use pt_timdat field of the ptrace_user structure to match 
+     the date of the executable */
+  return true;
+}
+\f
+/* No archive file support via this BFD */
+#define        ptrace_unix_openr_next_archived_file    bfd_generic_openr_next_archived_file
+#define        ptrace_unix_generic_stat_arch_elt               bfd_generic_stat_arch_elt
+#define        ptrace_unix_slurp_armap                 bfd_false
+#define        ptrace_unix_slurp_extended_name_table   bfd_true
+#define        ptrace_unix_write_armap                 (boolean (*) PARAMS     \
+    ((bfd *arch, unsigned int elength, struct orl *map, \
+      unsigned int orl_count, int stridx))) bfd_false
+#define        ptrace_unix_truncate_arname             bfd_dont_truncate_arname
+#define        aout_32_openr_next_archived_file        bfd_generic_openr_next_archived_file
+
+#define        ptrace_unix_close_and_cleanup           bfd_generic_close_and_cleanup
+#define        ptrace_unix_set_section_contents                (boolean (*) PARAMS     \
+        ((bfd *abfd, asection *section, PTR data, file_ptr offset,     \
+        bfd_size_type count))) bfd_false
+#define        ptrace_unix_get_section_contents                bfd_generic_get_section_contents
+#define        ptrace_unix_new_section_hook            (boolean (*) PARAMS     \
+       ((bfd *, sec_ptr))) bfd_true
+#define        ptrace_unix_get_symtab_upper_bound      bfd_0u
+#define        ptrace_unix_get_symtab                  (unsigned int (*) PARAMS \
+        ((bfd *, struct symbol_cache_entry **))) bfd_0u
+#define        ptrace_unix_get_reloc_upper_bound               (unsigned int (*) PARAMS \
+       ((bfd *, sec_ptr))) bfd_0u
+#define        ptrace_unix_canonicalize_reloc          (unsigned int (*) PARAMS \
+       ((bfd *, sec_ptr, arelent **, struct symbol_cache_entry**))) bfd_0u
+#define        ptrace_unix_make_empty_symbol           (struct symbol_cache_entry * \
+       (*) PARAMS ((bfd *))) bfd_false
+#define        ptrace_unix_print_symbol                        (void (*) PARAMS        \
+       ((bfd *, PTR, struct symbol_cache_entry  *,                     \
+       bfd_print_symbol_type))) bfd_false
+#define        ptrace_unix_get_symbol_info             (void (*) PARAMS        \
+       ((bfd *, struct symbol_cache_entry  *,                  \
+       symbol_info *))) bfd_false
+#define        ptrace_unix_get_lineno                  (alent * (*) PARAMS     \
+       ((bfd *, struct symbol_cache_entry *))) bfd_nullvoidptr
+#define        ptrace_unix_set_arch_mach                       (boolean (*) PARAMS     \
+       ((bfd *, enum bfd_architecture, unsigned long))) bfd_false
+#define        ptrace_unix_find_nearest_line           (boolean (*) PARAMS     \
+        ((bfd *abfd, struct sec  *section,                             \
+         struct symbol_cache_entry  **symbols,bfd_vma offset,          \
+         CONST char **file, CONST char **func, unsigned int *line))) bfd_false
+#define        ptrace_unix_sizeof_headers              (int (*) PARAMS \
+       ((bfd *, boolean))) bfd_0
+
+#define ptrace_unix_bfd_debug_info_start               bfd_void
+#define ptrace_unix_bfd_debug_info_end         bfd_void
+#define ptrace_unix_bfd_debug_info_accumulate  (void (*) PARAMS        \
+       ((bfd *, struct sec *))) bfd_void
+#define ptrace_unix_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents
+#define ptrace_unix_bfd_relax_section          bfd_generic_relax_section
+#define ptrace_unix_bfd_reloc_type_lookup \
+  ((CONST struct reloc_howto_struct *(*) PARAMS ((bfd *, bfd_reloc_code_real_type))) bfd_nullvoidptr)
+#define ptrace_unix_bfd_make_debug_symbol \
+  ((asymbol *(*) PARAMS ((bfd *, void *, unsigned long))) bfd_nullvoidptr)
+#define ptrace_unix_bfd_link_hash_table_create \
+  ((struct bfd_link_hash_table *(*) PARAMS ((bfd *))) bfd_nullvoidptr)
+#define ptrace_unix_bfd_link_add_symbols \
+  ((boolean (*) PARAMS ((bfd *, struct bfd_link_info *))) bfd_false)
+#define ptrace_unix_bfd_final_link \
+  ((boolean (*) PARAMS ((bfd *, struct bfd_link_info *))) bfd_false)
+
+/* If somebody calls any byte-swapping routines, shoot them.  */
+void
+swap_abort()
+{
+  abort(); /* This way doesn't require any declaration for ANSI to fuck up */
+}
+#define        NO_GET  ((bfd_vma (*) PARAMS ((         bfd_byte *))) swap_abort )
+#define        NO_PUT  ((void    (*) PARAMS ((bfd_vma, bfd_byte *))) swap_abort )
+#define        NO_SIGNED_GET ((bfd_signed_vma (*) PARAMS ((bfd_byte *))) swap_abort )
+
+bfd_target ptrace_core_vec =
+  {
+    "trad-core",
+    bfd_target_unknown_flavour,
+    true,                      /* target byte order */
+    true,                      /* target headers byte order */
+    (HAS_RELOC | EXEC_P |      /* object flags */
+     HAS_LINENO | HAS_DEBUG |
+     HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
+    (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
+    0,                                                    /* symbol prefix */
+    ' ',                                                  /* ar_pad_char */
+    16,                                                           /* ar_max_namelen */
+    3,                                                    /* minimum alignment power */
+    NO_GET, NO_SIGNED_GET, NO_PUT,     /* 64 bit data */
+    NO_GET, NO_SIGNED_GET, NO_PUT,     /* 32 bit data */
+    NO_GET, NO_SIGNED_GET, NO_PUT,     /* 16 bit data */
+    NO_GET, NO_SIGNED_GET, NO_PUT,     /* 64 bit hdrs */
+    NO_GET, NO_SIGNED_GET, NO_PUT,     /* 32 bit hdrs */
+    NO_GET, NO_SIGNED_GET, NO_PUT,     /* 16 bit hdrs */
+
+    {                          /* bfd_check_format */
+     _bfd_dummy_target,                /* unknown format */
+     _bfd_dummy_target,                /* object file */
+     _bfd_dummy_target,                /* archive */
+     ptrace_unix_core_file_p   /* a core file */
+    },
+    {                          /* bfd_set_format */
+     bfd_false, bfd_false,
+     bfd_false, bfd_false
+    },
+    {                          /* bfd_write_contents */
+     bfd_false, bfd_false,
+     bfd_false, bfd_false
+    },
+    
+    JUMP_TABLE(ptrace_unix),
+    (PTR) 0                    /* backend_data */
+};
+
+#endif /* PTRACE_CORE */
index 0f05cbe..20dd050 100644 (file)
@@ -43,8 +43,8 @@ SECTION
 */
 #include "bfd.h"
 #include "sysdep.h"
+#include "bfdlink.h"
 #include "libbfd.h"
-#include "seclet.h"
 /*
 DOCDD
 INODE
@@ -82,7 +82,8 @@ CODE_FRAGMENT
 .
 .       {* The relocation was performed, but may not be ok - presently
 .          generated only when linking i960 coff files with i960 b.out
-.          symbols. *}
+.          symbols.  If this type is returned, the error_message argument
+.          to bfd_perform_relocation will be set.  *}
 .  bfd_reloc_dangerous
 . }
 . bfd_reloc_status_type;
@@ -100,7 +101,7 @@ CODE_FRAGMENT
 .  bfd_vma addend;    
 .
 .       {* Pointer to how to perform the required relocation *}
-.  CONST struct reloc_howto_struct *howto;
+.  const struct reloc_howto_struct *howto;
 .
 .} arelent;
 
@@ -189,7 +190,7 @@ DESCRIPTION
 |offset   type      value 
 |00000002 HVRT16    _foo+0x12340000
 |00000006 LVRT16    _foo+0x12340000
-
+|
 |00000000 5da05678           ; or.u r13,r0,0x5678
 |00000004 1c4d5678           ; ld.b r2,r13,0x5678
 |00000008 f400c001           ; jmp r1
@@ -214,7 +215,7 @@ DESCRIPTION
 |        ret
 |        restore
 
-        Both relocs contains a pointer to <<foo>>, and the offsets
+        Both relocs contain a pointer to <<foo>>, and the offsets
         contain junk.
 
 
@@ -222,7 +223,7 @@ DESCRIPTION
 |offset   type      value 
 |00000004 HI22      _foo+0x12345678
 |00000008 LO10      _foo+0x12345678
-
+|
 |00000000 9de3bf90     ; save %sp,-112,%sp
 |00000004 05000000     ; sethi %hi(_foo+0),%g2
 |00000008 f048a000     ; ldsb [%g2+%lo(_foo+0)],%i0
@@ -296,16 +297,8 @@ CODE_FRAGMENT
 .  unsigned int rightshift;
 .
 .      {*  The size of the item to be relocated.  This is *not* a
-.          power-of-two measure.
-.               0 : one byte
-.               1 : two bytes
-.               2 : four bytes
-.               3 : nothing done (unless special_function is nonzero)
-.               4 : eight bytes
-.              -2 : two bytes, result should be subtracted from the
-.                   data instead of added
-.          There is currently no trivial way to extract a "number of
-.          bytes" from a howto pointer.  *}
+.          power-of-two measure.  To get the number of bytes operated
+.          on by a type of relocation, use bfd_get_reloc_size.  *}
 .  int size;
 .
 .       {*  The number of bits in the item to be relocated.  This is used
@@ -336,7 +329,8 @@ CODE_FRAGMENT
 .                                            struct symbol_cache_entry *symbol,
 .                                            PTR data,
 .                                            asection *input_section, 
-.                                            bfd *output_bfd));
+.                                            bfd *output_bfd,
+.                                            char **error_message));
 .
 .       {* The textual name of the relocation type. *}
 .  char *name;
@@ -408,6 +402,33 @@ DESCRIPTION
 */
 
 /*
+FUNCTION
+       bfd_get_reloc_size
+
+SYNOPSIS
+       int bfd_get_reloc_size (const reloc_howto_type *);
+
+DESCRIPTION
+       For a reloc_howto_type that operates on a fixed number of bytes,
+       this returns the number of bytes operated on.
+ */
+
+int
+bfd_get_reloc_size (howto)
+     const reloc_howto_type *howto;
+{
+  switch (howto->size) {
+  case 0: return 1;
+  case 1: return 2;
+  case 2: return 4;
+  case 3: return 0;
+  case 4: return 8;
+  case -2: return 2;
+  default: abort ();
+  }
+}
+
+/*
 TYPEDEF
        arelent_chain
 
@@ -434,50 +455,50 @@ SYNOPSIS
        bfd_reloc_status_type
                 bfd_perform_relocation
                         (bfd *abfd,
-                        arelent *reloc_entry,
-                        PTR data,
-                        asection *input_section,
-                        bfd *output_bfd);
+                         arelent *reloc_entry,
+                         PTR data,
+                         asection *input_section,
+                         bfd *output_bfd,
+                        char **error_message);
 
 DESCRIPTION
-       If @var{output_bfd} is supplied to this function, the generated
-       image will be relocatable; the relocations are copied to the
-       output file after they have been changed to reflect the new
-       state of the world. There are two ways of reflecting the
-       results of partial linkage in an output file: by modifying the
-       output data in place, and by modifying the relocation record.
-       Some native formats (e.g., basic a.out and basic coff) have no
-       way of specifying an addend in the relocation type, so the
-       addend has to go in the output data.  This is no big deal
-       since in these formats the output data slot will always be big
-       enough for the addend. Complex reloc types with addends were
-       invented to solve just this problem.
+       If @var{output_bfd} is supplied to this function, the
+       generated image will be relocatable; the relocations are
+       copied to the output file after they have been changed to
+       reflect the new state of the world. There are two ways of
+       reflecting the results of partial linkage in an output file:
+       by modifying the output data in place, and by modifying the
+       relocation record.  Some native formats (e.g., basic a.out and
+       basic coff) have no way of specifying an addend in the
+       relocation type, so the addend has to go in the output data.
+       This is no big deal since in these formats the output data
+       slot will always be big enough for the addend. Complex reloc
+       types with addends were invented to solve just this problem.
+       The @var{error_message} argument is set to an error message if
+       this return @code{bfd_reloc_dangerous}.
 
 */
 
 
 bfd_reloc_status_type
-DEFUN(bfd_perform_relocation,(abfd,
-                              reloc_entry,
-                              data,
-                              input_section,
-                              output_bfd),
-      bfd *abfd AND
-      arelent *reloc_entry AND
-      PTR data AND
-      asection *input_section AND
-      bfd *output_bfd)
+bfd_perform_relocation (abfd, reloc_entry, data, input_section, output_bfd,
+                       error_message)
+     bfd *abfd;
+     arelent *reloc_entry;
+     PTR data;
+     asection *input_section;
+     bfd *output_bfd;
+     char **error_message;
 {
   bfd_vma relocation;
   bfd_reloc_status_type flag = bfd_reloc_ok;
   bfd_size_type addr = reloc_entry->address ;
   bfd_vma output_base = 0;
-  reloc_howto_type *howto = reloc_entry->howto;
-  asection *reloc_target_output_section ;
-
+  const reloc_howto_type *howto = reloc_entry->howto;
+  asection *reloc_target_output_section;
   asymbol *symbol;
 
-  symbol = *( reloc_entry->sym_ptr_ptr);
+  symbol = *(reloc_entry->sym_ptr_ptr);
   if ((symbol->section == &bfd_abs_section) 
       && output_bfd != (bfd *)NULL) 
     {
@@ -500,7 +521,8 @@ DEFUN(bfd_perform_relocation,(abfd,
     {
       bfd_reloc_status_type cont;
       cont = howto->special_function (abfd, reloc_entry, symbol, data,
-                                     input_section, output_bfd);
+                                     input_section, output_bfd,
+                                     error_message);
       if (cont != bfd_reloc_continue)
        return cont;
     }
@@ -891,7 +913,240 @@ space consuming.  For each target:
   return flag;
 }
 
+/* This relocation routine is used by some of the backend linkers.
+   They do not construct asymbol or arelent structures, so there is no
+   reason for them to use bfd_perform_relocation.  Also,
+   bfd_perform_relocation is so hacked up it is easier to write a new
+   function than to try to deal with it.
+
+   This routine does a final relocation.  It should not be used when
+   generating relocateable output.
+
+   FIXME: This routine ignores any special_function in the HOWTO,
+   since the existing special_function values have been written for
+   bfd_perform_relocation.
+
+   HOWTO is the reloc howto information.
+   INPUT_BFD is the BFD which the reloc applies to.
+   INPUT_SECTION is the section which the reloc applies to.
+   CONTENTS is the contents of the section.
+   ADDRESS is the address of the reloc within INPUT_SECTION.
+   VALUE is the value of the symbol the reloc refers to.
+   ADDEND is the addend of the reloc.  */
+
+bfd_reloc_status_type
+_bfd_final_link_relocate (howto, input_bfd, input_section, contents, address,
+                        value, addend)
+     const reloc_howto_type *howto;
+     bfd *input_bfd;
+     asection *input_section;
+     bfd_byte *contents;
+     bfd_vma address;
+     bfd_vma value;
+     bfd_vma addend;
+{
+  bfd_vma relocation;
 
+  /* Sanity check the address.  */
+  if (address > input_section->_cooked_size)
+    return bfd_reloc_outofrange;
+
+  /* This function assumes that we are dealing with a basic relocation
+     against a symbol.  We want to compute the value of the symbol to
+     relocate to.  This is just VALUE, the value of the symbol, plus
+     ADDEND, any addend associated with the reloc.  */
+  relocation = value + addend;
+
+  /* If the relocation is PC relative, we want to set RELOCATION to
+     the distance between the symbol (currently in RELOCATION) and the
+     location we are relocating.  Some targets (e.g., i386-aout)
+     arrange for the contents of the section to be the negative of the
+     offset of the location within the section; for such targets
+     pcrel_offset is false.  Other targets (e.g., m88kbcs or ELF)
+     simply leave the contents of the section as zero; for such
+     targets pcrel_offset is true.  If pcrel_offset is false we do not
+     need to subtract out the offset of the location within the
+     section (which is just ADDRESS).  */
+  if (howto->pc_relative)
+    {
+      relocation -= (input_section->output_section->vma
+                    + input_section->output_offset);
+      if (howto->pcrel_offset)
+       relocation -= address;
+    }
+  
+  return _bfd_relocate_contents (howto, input_bfd, relocation,
+                                contents + address);
+}
+
+/* Relocate a given location using a given value and howto.  */
+
+bfd_reloc_status_type
+_bfd_relocate_contents (howto, input_bfd, relocation, location)
+     const reloc_howto_type *howto;
+     bfd *input_bfd;
+     bfd_vma relocation;
+     bfd_byte *location;
+{
+  int size;
+  bfd_vma x;
+  boolean overflow;
+
+  /* If the size is negative, negate RELOCATION.  This isn't very
+     general.  */
+  if (howto->size < 0)
+    relocation = - relocation;
+
+  /* Get the value we are going to relocate.  */
+  size = bfd_get_reloc_size (howto);
+  switch (size)
+    {
+    default:
+    case 0:
+      abort ();
+    case 1:
+      x = bfd_get_8 (input_bfd, location);
+      break;
+    case 2:
+      x = bfd_get_16 (input_bfd, location);
+      break;
+    case 4:
+      x = bfd_get_32 (input_bfd, location);
+      break;
+    case 8:
+#ifdef BFD64
+      x = bfd_get_64 (input_bfd, location);
+#else
+      abort ();
+#endif
+      break;
+    }
+
+  /* Check for overflow.  FIXME: We may drop bits during the addition
+     which we don't check for.  We must either check at every single
+     operation, which would be tedious, or we must do the computations
+     in a type larger than bfd_vma, which would be inefficient.  */
+  overflow = false;
+  if (howto->complain_on_overflow != complain_overflow_dont)
+    {
+      bfd_vma check;
+      bfd_signed_vma signed_check;
+      bfd_vma add;
+
+      if (howto->rightshift == 0)
+       {
+         check = relocation;
+         signed_check = (bfd_signed_vma) relocation;
+       }
+      else
+       {
+         /* Drop unwanted bits from the value we are relocating to.  */
+         check = relocation >> howto->rightshift;
+
+         /* If this is a signed value, the rightshift just dropped
+            leading 1 bits (assuming twos complement).  */
+         if ((bfd_signed_vma) relocation >= 0)
+           signed_check = check;
+         else
+           signed_check = (check
+                           | ((bfd_vma) -1
+                              &~ ((bfd_vma) -1 >> howto->rightshift)));
+       }
+
+      /* Add in the value from the object file, shifted down so that
+        it is a straight number.  */
+      add = x & howto->src_mask;
+      if (howto->bitpos == 0)
+       {
+         check += add;
+         signed_check += add;
+       }
+      else
+       {
+         add >>= howto->bitpos;
+         check += add;
+         signed_check += (add
+                          | ((bfd_vma) -1
+                             &~ ((bfd_vma) -1 >> howto->bitpos)));
+       }
+
+      switch (howto->complain_on_overflow)
+       {
+       case complain_overflow_signed:
+         {
+           /* Assumes two's complement.  */
+           bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1;
+           bfd_signed_vma reloc_signed_min = ~ reloc_signed_max;
+
+           if (signed_check > reloc_signed_max
+               || signed_check < reloc_signed_min)
+             overflow = true;
+         }
+         break;
+       case complain_overflow_unsigned:
+         {
+           /* Assumes two's complement.  This expression avoids
+              overflow if howto->bitsize is the number of bits in
+              bfd_vma.  */
+           bfd_vma reloc_unsigned_max =
+             (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
+
+           if (check > reloc_unsigned_max)
+             overflow = true;
+         }
+         break;
+       case complain_overflow_bitfield:
+         {
+           /* Assumes two's complement.  This expression avoids
+              overflow if howto->bitsize is the number of bits in
+              bfd_vma.  */
+           bfd_vma reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
+
+           if ((check &~ reloc_bits) != 0
+               && (((bfd_vma) signed_check &~ reloc_bits)
+                   != (-1 &~ reloc_bits)))
+             overflow = true;
+         }
+         break;
+       default:
+         abort ();
+       }
+    }
+
+  /* Put RELOCATION in the right bits.  */
+  relocation >>= (bfd_vma) howto->rightshift;
+  relocation <<= (bfd_vma) howto->bitpos;
+
+  /* Add RELOCATION to the right bits of X.  */
+  x = ((x &~ howto->dst_mask)
+       | (((x & howto->src_mask) + relocation) & howto->dst_mask));
+
+  /* Put the relocated value back in the object file.  */
+  switch (size)
+    {
+    default:
+    case 0:
+      abort ();
+    case 1:
+      bfd_put_8 (input_bfd, x, location);
+      break;
+    case 2:
+      bfd_put_16 (input_bfd, x, location);
+      break;
+    case 4:
+      bfd_put_32 (input_bfd, x, location);
+      break;
+    case 8:
+#ifdef BFD64
+      bfd_put_64 (input_bfd, x, location);
+#else
+      abort ();
+#endif
+      break;
+    }
+
+  return overflow ? bfd_reloc_overflow : bfd_reloc_ok;
+}
 
 /*
 DOCDD
@@ -1147,18 +1402,18 @@ FUNCTION
        bfd_reloc_type_lookup
 
 SYNOPSIS
-       CONST struct reloc_howto_struct *
+       const struct reloc_howto_struct *
        bfd_reloc_type_lookup (bfd *abfd, bfd_reloc_code_real_type code);
 
 DESCRIPTION
-       Return a pointer to a howto struct which, when
+       Return a pointer to a howto structure which, when
        invoked, will perform the relocation @var{code} on data from the
        architecture noted.
 
 */
 
 
-CONST struct reloc_howto_struct *
+const struct reloc_howto_struct *
 DEFUN(bfd_reloc_type_lookup,(abfd, code),
       bfd *abfd AND
       bfd_reloc_code_real_type code)
@@ -1175,7 +1430,7 @@ INTERNAL_FUNCTION
        bfd_default_reloc_type_lookup
 
 SYNOPSIS
-       CONST struct reloc_howto_struct *bfd_default_reloc_type_lookup
+       const struct reloc_howto_struct *bfd_default_reloc_type_lookup
        (bfd *abfd AND
          bfd_reloc_code_real_type  code);
 
@@ -1185,7 +1440,7 @@ DESCRIPTION
 
 */
 
-CONST struct reloc_howto_struct *
+const struct reloc_howto_struct *
 DEFUN(bfd_default_reloc_type_lookup, (abfd, code),
       bfd *abfd AND
       bfd_reloc_code_real_type code)
@@ -1208,7 +1463,7 @@ DEFUN(bfd_default_reloc_type_lookup, (abfd, code),
     default:
       BFD_FAIL();
     }
-  return (CONST struct reloc_howto_struct *)NULL;
+  return (const struct reloc_howto_struct *)NULL;
 }
 
 
@@ -1220,6 +1475,7 @@ SYNOPSIS
        boolean bfd_generic_relax_section
         (bfd *abfd,
          asection *section,
+         struct bfd_link_info *,
          asymbol **symbols);
 
 DESCRIPTION
@@ -1228,16 +1484,14 @@ DESCRIPTION
 */
 
 boolean
-DEFUN(bfd_generic_relax_section,(abfd, section, symbols),
-      bfd *abfd AND
-      asection *section AND
-      asymbol **symbols)
+bfd_generic_relax_section (abfd, section, link_info, symbols)
+     bfd *abfd;
+     asection *section;
+     struct bfd_link_info *link_info;
+     asymbol **symbols;
 {
-  
   return false;
-  
 }
-
                
 /*
 INTERNAL_FUNCTION
@@ -1246,9 +1500,11 @@ INTERNAL_FUNCTION
 SYNOPSIS
        bfd_byte *
           bfd_generic_get_relocated_section_contents (bfd *abfd,
-            struct bfd_seclet *seclet,
+            struct bfd_link_info *link_info,
+            struct bfd_link_order *link_order,
             bfd_byte *data,
-            boolean relocateable);
+            boolean relocateable,
+            asymbol **symbols);
 
 DESCRIPTION
        Provides default handling of relocation effort for back ends
@@ -1257,20 +1513,18 @@ DESCRIPTION
 */
 
 bfd_byte *
-DEFUN(bfd_generic_get_relocated_section_contents,(abfd,
-                                                 seclet,
-                                                 data,
-                                                 relocateable),
-      bfd *abfd AND
-      struct bfd_seclet *seclet AND
-      bfd_byte *data AND
-      boolean relocateable)
+bfd_generic_get_relocated_section_contents (abfd, link_info, link_order, data,
+                                           relocateable, symbols)
+     bfd *abfd;
+     struct bfd_link_info *link_info;
+     struct bfd_link_order *link_order;
+     bfd_byte *data;
+     boolean relocateable;
+     asymbol **symbols;
 {
-  extern bfd_error_vector_type bfd_error_vector;
-
   /* Get enough memory to hold the stuff */
-  bfd *input_bfd = seclet->u.indirect.section->owner;
-  asection *input_section = seclet->u.indirect.section;
+  bfd *input_bfd = link_order->u.indirect.section->owner;
+  asection *input_section = link_order->u.indirect.section;
 
 
 
@@ -1292,18 +1546,20 @@ DEFUN(bfd_generic_get_relocated_section_contents,(abfd,
   if (bfd_canonicalize_reloc(input_bfd, 
                             input_section,
                             reloc_vector,
-                            seclet->u.indirect.symbols) )
+                            symbols) )
   {
     arelent **parent;
     for (parent = reloc_vector;  * parent != (arelent *)NULL;
         parent++) 
     { 
+      char *error_message = (char *) NULL;
       bfd_reloc_status_type r=
        bfd_perform_relocation(input_bfd,
                              *parent,
                              data,
                              input_section,
-                             relocateable ? abfd : (bfd *) NULL);
+                             relocateable ? abfd : (bfd *) NULL,
+                             &error_message);
       
       if (relocateable)
        {
@@ -1319,15 +1575,24 @@ DEFUN(bfd_generic_get_relocated_section_contents,(abfd,
        switch (r)
        {
        case bfd_reloc_undefined:
-         bfd_error_vector.undefined_symbol(*parent, seclet);
+         if (! ((*link_info->callbacks->undefined_symbol)
+                (link_info, bfd_asymbol_name (*(*parent)->sym_ptr_ptr),
+                 input_bfd, input_section, (*parent)->address)))
+           return NULL;
          break;
        case bfd_reloc_dangerous: 
-         bfd_error_vector.reloc_dangerous(*parent, seclet);
+         BFD_ASSERT (error_message != (char *) NULL);
+         if (! ((*link_info->callbacks->reloc_dangerous)
+                (link_info, error_message, input_bfd, input_section,
+                 (*parent)->address)))
+           return NULL;
          break;
-       case bfd_reloc_outofrange:
        case bfd_reloc_overflow:
-         bfd_error_vector.reloc_value_truncated(*parent, seclet);
+         if (! ((*link_info->callbacks->reloc_overflow)
+                (link_info, input_bfd, input_section, (*parent)->address)))
+           return NULL;
          break;
+       case bfd_reloc_outofrange:
        default:
          abort();
          break;
index daccf2e..374e2fa 100644 (file)
@@ -112,23 +112,23 @@ SUBSECTION
 
 
 SUBSECTION
-       Seclets
+       Link orders
 
-       The data within a section is stored in a @dfn{seclet}.  These
-       are much like the fixups in <<gas>>.  The seclet abstraction
-       allows a section to grow and shrink within itself.
+       The data within a section is stored in a @dfn{link_order}.
+       These are much like the fixups in <<gas>>.  The link_order
+       abstraction allows a section to grow and shrink within itself.
 
-       A seclet knows how big it is, and which is the next seclet and
-       where the raw data for it is; it also points to a list of
-       relocations which apply to it.
+       A link_order knows how big it is, and which is the next
+       link_order and where the raw data for it is; it also points to
+       a list of relocations which apply to it.
 
-       The seclet is used by the linker to perform relaxing on final
-       code.  The compiler creates code which is as big as
+       The link_order is used by the linker to perform relaxing on
+       final code.  The compiler creates code which is as big as
        necessary to make it work without relaxing, and the user can
        select whether to relax.  Sometimes relaxing takes a lot of
        time.  The linker runs around the relocations to see if any
        are attached to data which can be shrunk, if so it does it on
-       a seclet by seclet basis.
+       a link_order by link_order basis.
 
 */
 
@@ -361,8 +361,8 @@ CODE_FRAGMENT
 .   struct symbol_cache_entry *symbol;  
 .   struct symbol_cache_entry **symbol_ptr_ptr;
 .
-.   struct bfd_seclet *seclets_head;
-.   struct bfd_seclet *seclets_tail;
+.   struct bfd_link_order *link_order_head;
+.   struct bfd_link_order *link_order_tail;
 .} asection ;
 .
 .
index b37d207..02a49fb 100644 (file)
@@ -279,7 +279,7 @@ unsigned int length)
 static int white(x)
 char x;
 {
-return (x== ' ' || x == '\t' || x == '\n' || x == '\r');
+  return (x== ' ' || x == '\t' || x == '\n' || x == '\r');
 }
 static int
 skipwhite(src,abfd)
@@ -309,12 +309,11 @@ DEFUN(srec_mkobject, (abfd),
     
 }
 
-static void
-DEFUN(pass_over,(abfd, func, symbolfunc, section),
-      bfd *abfd AND
-      void (*func)() AND
-      void (*symbolfunc)() AND
-      asection *section)
+static void pass_over(abfd, func, symbolfunc, section)
+     bfd *abfd;
+     void (*func)();
+     void (*symbolfunc)();
+     asection *section;
 {
   unsigned int bytes_on_line;
   boolean eof = false;
@@ -348,45 +347,46 @@ DEFUN(pass_over,(abfd, func, symbolfunc, section),
 
      case ' ':
       /* spaces - maybe just before a symbol */
-      while (*src != '\n' && white(*src)) {
-      eof = skipwhite(src, abfd);
-
-{
-       int val = 0;
-       int slen = 0;
-       char symbol[MAXCHUNK];
-
-       /* get the symbol part */
-       while (!eof && !white(*src) && slen < MAXCHUNK)
-       {
-         symbol[slen++] = *src;
-         eof =  (boolean)(bfd_read(src, 1, 1, abfd) != 1);       
-       }
-       symbol[slen] = 0;
-       eof = skipwhite(src, abfd);
-       /* skip the $ for the hex value */
-       if (*src == '$') 
-       {
-         eof =  (boolean)(bfd_read(src, 1, 1, abfd) != 1);
-       }
-
-       /* Scan off the hex number */
-       while (isxdigit(*src ))
+      while (*src != '\n' && *src != '\r' && white(*src)) 
        {
-         val *= 16;
-         if (isdigit(*src))
-          val += *src - '0';
-         else if (isupper(*src)) {
-           val += *src - 'A' + 10;
+         eof = skipwhite(src, abfd);
+
+         {
+           int val = 0;
+           int slen = 0;
+           char symbol[MAXCHUNK];
+
+           /* get the symbol part */
+           while (!eof && !white(*src) && slen < MAXCHUNK)
+             {
+               symbol[slen++] = *src;
+               eof =  (boolean)(bfd_read(src, 1, 1, abfd) != 1);         
+             }
+           symbol[slen] = 0;
+           eof = skipwhite(src, abfd);
+           /* skip the $ for the hex value */
+           if (*src == '$') 
+             {
+               eof =  (boolean)(bfd_read(src, 1, 1, abfd) != 1);
+             }
+
+           /* Scan off the hex number */
+           while (isxdigit(*src ))
+             {
+               val *= 16;
+               if (isdigit(*src))
+                 val += *src - '0';
+               else if (isupper(*src)) {
+                 val += *src - 'A' + 10;
+               }
+               else {
+                 val += *src - 'a' + 10;
+               }
+               eof =  (boolean)(bfd_read(src, 1, 1, abfd) != 1);
+             }
+           symbolfunc(abfd, symbol, slen, val);
          }
-         else {
-           val += *src - 'a' + 10;
-         }
-         eof =  (boolean)(bfd_read(src, 1, 1, abfd) != 1);
        }
-       symbolfunc(abfd, symbol, slen, val);
-      }
-}
       break;
      case 'S':
       src++;
@@ -733,7 +733,7 @@ srec_write_symbols(abfd)
       if (len > 3 && s->name[len-2] == '.') 
       {
        int l;
-       sprintf(buffer, "$$ %s\n\r", s->name);
+       sprintf(buffer, "$$ %s\r\n", s->name);
        l = strlen(buffer);
        bfd_write(buffer, l, 1, abfd);
       }
@@ -749,13 +749,13 @@ srec_write_symbols(abfd)
        int l;
        char buf2[40], *p;
 
-       sprintf (buffer,"  %s $", s->name);
-       sprintf_vma (buf2, s->value + s->section->lma);
+       sprintf_vma (buf2,
+                    s->value + s->section->output_section->lma 
+                    + s->section->output_offset);
        p = buf2;
        while (p[0] == '0' && p[1] != 0)
          p++;
-       strcat (buffer, p);
-       strcat (buffer, "\n\r");
+       sprintf (buffer, "  %s $%s\r\n", s->name, p);
        l = strlen(buffer);
        bfd_write(buffer, l, 1,abfd);
       }
@@ -906,11 +906,13 @@ DEFUN(srec_print_symbol,(ignore_abfd, afile, symbol, how),
 #define srec_bfd_debug_info_accumulate  (FOO(void, (*), (bfd *,         asection *))) bfd_void
 #define srec_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents
 #define srec_bfd_relax_section bfd_generic_relax_section
-#define srec_bfd_seclet_link bfd_generic_seclet_link
 #define srec_bfd_reloc_type_lookup \
   ((CONST struct reloc_howto_struct *(*) PARAMS ((bfd *, bfd_reloc_code_real_type))) bfd_nullvoidptr)
 #define srec_bfd_make_debug_symbol \
   ((asymbol *(*) PARAMS ((bfd *, void *, unsigned long))) bfd_nullvoidptr)
+#define srec_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
+#define srec_bfd_link_add_symbols _bfd_generic_link_add_symbols
+#define srec_bfd_final_link _bfd_generic_final_link
 
 bfd_target srec_vec =
 {
@@ -920,19 +922,19 @@ bfd_target srec_vec =
     true,                      /* target headers byte order */
     (HAS_RELOC | EXEC_P |      /* object flags */
      HAS_LINENO | HAS_DEBUG |
-     HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
+     HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
     (SEC_CODE|SEC_DATA|SEC_ROM|SEC_HAS_CONTENTS
      |SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
      0,                                /* leading underscore */
     ' ',                       /* ar_pad_char */
     16,                                /* ar_max_namelen */
     1,                         /* minimum alignment */
-    _do_getb64, _do_getb_signed_64, _do_putb64,
-      _do_getb32, _do_getb_signed_32,     _do_putb32,
-      _do_getb16, _do_getb_signed_16, _do_putb16, /* data */
-    _do_getb64, _do_getb_signed_64, _do_putb64,
-      _do_getb32, _do_getb_signed_32,     _do_putb32,
-      _do_getb16, _do_getb_signed_16, _do_putb16, /* hdrs */
+    bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+      bfd_getb32, bfd_getb_signed_32,     bfd_putb32,
+      bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
+    bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+      bfd_getb32, bfd_getb_signed_32,     bfd_putb32,
+      bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
 
   {
       _bfd_dummy_target,
@@ -965,19 +967,19 @@ bfd_target symbolsrec_vec =
     true,                      /* target headers byte order */
     (HAS_RELOC | EXEC_P |      /* object flags */
      HAS_LINENO | HAS_DEBUG |
-     HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
+     HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
     (SEC_CODE|SEC_DATA|SEC_ROM|SEC_HAS_CONTENTS
      |SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
      0,                                /* leading underscore */
     ' ',                       /* ar_pad_char */
     16,                                /* ar_max_namelen */
     1,                         /* minimum alignment */
-    _do_getb64, _do_getb_signed_64, _do_putb64,
-      _do_getb32, _do_getb_signed_32,     _do_putb32,
-      _do_getb16, _do_getb_signed_16, _do_putb16, /* data */
-    _do_getb64, _do_getb_signed_64, _do_putb64,
-      _do_getb32, _do_getb_signed_32,     _do_putb32,
-      _do_getb16, _do_getb_signed_16, _do_putb16, /* hdrs */
+    bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+      bfd_getb32, bfd_getb_signed_32,     bfd_putb32,
+      bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
+    bfd_getb64, bfd_getb_signed_64, bfd_putb64,
+      bfd_getb32, bfd_getb_signed_32,     bfd_putb32,
+      bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
 
   {
       _bfd_dummy_target,
index adfc530..8f10ef3 100644 (file)
@@ -130,7 +130,10 @@ DESCRIPTION
 .  bfd_target_tekhex_flavour,
 .  bfd_target_srec_flavour,
 .  bfd_target_som_flavour};
-
+.
+.{* Forward declaration.  *}
+.typedef struct bfd_link_info _bfd_link_info;
+.
 .typedef struct bfd_target
 .{
 
@@ -290,15 +293,13 @@ Symbols and relocations.
 .  void       (*_bfd_debug_info_accumulate) PARAMS ((bfd *, struct sec *));
 .
 .  bfd_byte * (*_bfd_get_relocated_section_contents) PARAMS ((bfd *,
-.                    struct bfd_seclet *, bfd_byte *data,
-.                    boolean relocateable));
+.                    struct bfd_link_info *, struct bfd_link_order *,
+.                    bfd_byte *data, boolean relocateable,
+.                    struct symbol_cache_entry **));
 .
 .  boolean    (*_bfd_relax_section) PARAMS ((bfd *, struct sec *,
-.                    struct symbol_cache_entry **));
+.                    struct bfd_link_info *, struct symbol_cache_entry **));
 .
-.  boolean    (*_bfd_seclet_link) PARAMS ((bfd *, PTR data,
-.                     boolean relocateable));
-
 . {* See documentation on reloc types.  *}
 . CONST struct reloc_howto_struct *
 .       (*reloc_type_lookup) PARAMS ((bfd *abfd,
@@ -311,6 +312,18 @@ Symbols and relocations.
 .       bfd *abfd,
 .       void *ptr,
 .       unsigned long size));
+.
+. {* Create a hash table for the linker.  Different backends store
+.    different information in this table.  *}
+. struct bfd_link_hash_table *(*_bfd_link_hash_table_create) PARAMS ((bfd *));
+.
+. {* Add symbols from this object file into the hash table.  *}
+. boolean (*_bfd_link_add_symbols) PARAMS ((bfd *, struct bfd_link_info *));
+.
+. {* Do a link based on the link_order structures attached to each
+.    section of the BFD.  *}
+. boolean (*_bfd_final_link) PARAMS ((bfd *, struct bfd_link_info *));
+.
 
 Data for use by back-end routines, which isn't generic enough to belong
 in this structure.
@@ -376,6 +389,7 @@ extern bfd_target newsos3_vec;
 extern bfd_target nlm32_big_generic_vec;
 extern bfd_target nlm32_i386_vec;
 extern bfd_target nlm32_sparc_vec;
+extern bfd_target nlm32_alpha_vec;
 extern bfd_target nlm32_little_generic_vec;
 extern bfd_target nlm64_big_generic_vec;
 extern bfd_target nlm64_little_generic_vec;
index d3e5fdd..f059a88 100644 (file)
@@ -80,6 +80,12 @@ trad_unix_core_file_p (abfd)
   int val;
   struct user u;
 
+#ifdef TRAD_CORE_USER_OFFSET
+  /* If defined, this macro is the file position of the user struct.  */
+  if (bfd_seek (abfd, TRAD_CORE_USER_OFFSET, SEEK_SET) == 0)
+    return 0;
+#endif
+    
   val = bfd_read ((void *)&u, 1, sizeof u, abfd);
   if (val != sizeof u)
     {
@@ -116,6 +122,7 @@ trad_unix_core_file_p (abfd)
        bfd_error = file_truncated;
        return 0;
       }
+#ifndef TRAD_CORE_ALLOW_ANY_EXTRA_SIZE
     if (NBPG * (UPAGES + u.u_dsize + u.u_ssize)
 #ifdef TRAD_CORE_EXTRA_SIZE_ALLOWED
        /* Some systems write the file too big.  */
@@ -128,6 +135,7 @@ trad_unix_core_file_p (abfd)
        bfd_error = wrong_format;
        return 0;
       }
+#endif
   }
 
   /* OK, we believe you.  You're a core file (sure, sure).  */
@@ -186,7 +194,13 @@ trad_unix_core_file_p (abfd)
 #else
   core_datasec (abfd)->vma = HOST_TEXT_START_ADDR + (NBPG * u.u_tsize);
 #endif
+
+#ifdef HOST_STACK_START_ADDR
+  core_stacksec (abfd)->vma = HOST_STACK_START_ADDR;
+#else
   core_stacksec (abfd)->vma = HOST_STACK_END_ADDR - (NBPG * u.u_ssize);
+#endif
+
   /* This is tricky.  As the "register section", we give them the entire
      upage and stack.  u.u_ar0 points to where "register 0" is stored.
      There are two tricks with this, though.  One is that the rest of the
@@ -204,7 +218,11 @@ trad_unix_core_file_p (abfd)
   core_regsec (abfd)->vma = 0 - (int) u.u_ar0;
 
   core_datasec (abfd)->filepos = NBPG * UPAGES;
+#ifdef TRAD_CORE_STACK_FILEPOS
+  core_stacksec (abfd)->filepos = TRAD_CORE_STACK_FILEPOS;
+#else
   core_stacksec (abfd)->filepos = (NBPG * UPAGES) + NBPG * u.u_dsize;
+#endif
   core_regsec (abfd)->filepos = 0; /* Register segment is the upage */
 
   /* Align to word at least */
@@ -303,12 +321,16 @@ trad_unix_core_file_matches_executable_p  (core_bfd, exec_bfd)
        ((bfd *, struct sec *))) bfd_void
 #define trad_unix_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents
 #define trad_unix_bfd_relax_section            bfd_generic_relax_section
-#define trad_unix_bfd_seclet_link \
-  ((boolean (*) PARAMS ((bfd *, PTR, boolean))) bfd_false)
 #define trad_unix_bfd_reloc_type_lookup \
   ((CONST struct reloc_howto_struct *(*) PARAMS ((bfd *, bfd_reloc_code_real_type))) bfd_nullvoidptr)
 #define trad_unix_bfd_make_debug_symbol \
   ((asymbol *(*) PARAMS ((bfd *, void *, unsigned long))) bfd_nullvoidptr)
+#define trad_unix_bfd_link_hash_table_create \
+  ((struct bfd_link_hash_table *(*) PARAMS ((bfd *))) bfd_nullvoidptr)
+#define trad_unix_bfd_link_add_symbols \
+  ((boolean (*) PARAMS ((bfd *, struct bfd_link_info *))) bfd_false)
+#define trad_unix_bfd_final_link \
+  ((boolean (*) PARAMS ((bfd *, struct bfd_link_info *))) bfd_false)
 
 /* If somebody calls any byte-swapping routines, shoot them.  */
 void
@@ -328,7 +350,7 @@ bfd_target trad_core_vec =
     true,                      /* target headers byte order */
     (HAS_RELOC | EXEC_P |      /* object flags */
      HAS_LINENO | HAS_DEBUG |
-     HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
+     HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
     (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
     0,                                                    /* symbol prefix */
     ' ',                                                  /* ar_pad_char */