aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog107
-rw-r--r--bfd/aix386-core.c8
-rw-r--r--bfd/aout-target.h129
-rw-r--r--bfd/aoutf1.h17
-rw-r--r--bfd/aoutx.h2118
-rw-r--r--bfd/bfd-in.h151
-rw-r--r--bfd/bfd-in2.h227
-rw-r--r--bfd/coff-a29k.c39
-rw-r--r--bfd/coffgen.c44
-rw-r--r--bfd/ecoff.c132
-rw-r--r--bfd/elf.c4
-rw-r--r--bfd/elf32-target.h13
-rw-r--r--bfd/elf64-target.h11
-rw-r--r--bfd/hosts/std-host.h2
-rw-r--r--bfd/hppabsd-core.c334
-rw-r--r--bfd/hpux-core.c318
-rw-r--r--bfd/irix-core.c292
-rw-r--r--bfd/libaout.h71
-rw-r--r--bfd/libbfd-in.h74
-rw-r--r--bfd/libbfd.c6
-rw-r--r--bfd/libbfd.h75
-rw-r--r--bfd/libelf.h3
-rw-r--r--bfd/osf-core.c298
-rw-r--r--bfd/ptrace-core.c303
-rw-r--r--bfd/reloc.c427
-rw-r--r--bfd/section.c24
-rw-r--r--bfd/srec.c128
-rw-r--r--bfd/targets.c28
-rw-r--r--bfd/trad-core.c28
29 files changed, 4752 insertions, 659 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index a0d0f0b..182f3c5 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -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
diff --git a/bfd/aix386-core.c b/bfd/aix386-core.c
index 3701367..ac0bba6 100644
--- a/bfd/aix386-core.c
+++ b/bfd/aix386-core.c
@@ -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
diff --git a/bfd/aout-target.h b/bfd/aout-target.h
index 8cf7429..70835c5 100644
--- a/bfd/aout-target.h
+++ b/bfd/aout-target.h
@@ -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 */
diff --git a/bfd/aoutf1.h b/bfd/aoutf1.h
index 076b0f2..2f4b728 100644
--- a/bfd/aoutf1.h
+++ b/bfd/aoutf1.h
@@ -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;
diff --git a/bfd/aoutx.h b/bfd/aoutx.h
index 1b096b2..57eeaa6 100644
--- a/bfd/aoutx.h
+++ b/bfd/aoutx.h
@@ -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;
}
/* 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;
}
@@ -2562,3 +2595,1704 @@ DEFUN(NAME(aout,sizeof_headers),(abfd, execable),
{
return adata(abfd).exec_bytes_size;
}
+
+/* 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;
+}
diff --git a/bfd/bfd-in.h b/bfd/bfd-in.h
index 1b44503..810e803 100644
--- a/bfd/bfd-in.h
+++ b/bfd/bfd-in.h
@@ -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;
-/** 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;
+/* 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));
+
/* 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
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 52a29b1..c5905a9 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -286,41 +286,32 @@ typedef struct sec *sec_ptr;
typedef struct stat stat_type;
-/** 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;
+/* 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));
+
/* 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 *
diff --git a/bfd/coff-a29k.c b/bfd/coff-a29k.c
index ef41bdb..7161d40 100644
--- a/bfd/coff-a29k.c
+++ b/bfd/coff-a29k.c
@@ -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);
}
diff --git a/bfd/coffgen.c b/bfd/coffgen.c
index dcdf9e9..ebc596f 100644
--- a/bfd/coffgen.c
+++ b/bfd/coffgen.c
@@ -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++;
}
}
diff --git a/bfd/ecoff.c b/bfd/ecoff.c
index 840d425..101adbd 100644
--- a/bfd/ecoff.c
+++ b/bfd/ecoff.c
@@ -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);
}
/* 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++)
diff --git a/bfd/elf.c b/bfd/elf.c
index 02b3b33..bfb3898 100644
--- 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
diff --git a/bfd/elf32-target.h b/bfd/elf32-target.h
index ed1f417..bdbb4a5 100644
--- a/bfd/elf32-target.h
+++ b/bfd/elf32-target.h
@@ -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
diff --git a/bfd/elf64-target.h b/bfd/elf64-target.h
index 8450179..7fdfa26 100644
--- a/bfd/elf64-target.h
+++ b/bfd/elf64-target.h
@@ -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
diff --git a/bfd/hosts/std-host.h b/bfd/hosts/std-host.h
index dc16af0..a0db98c 100644
--- a/bfd/hosts/std-host.h
+++ b/bfd/hosts/std-host.h
@@ -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
index 0000000..b6ecc30
--- /dev/null
+++ b/bfd/hppabsd-core.c
@@ -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;
+}
+
+
+/* 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
index 0000000..afda813
--- /dev/null
+++ b/bfd/hpux-core.c
@@ -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 */
+}
+
+/* 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
index 0000000..b0482a4
--- /dev/null
+++ b/bfd/irix-core.c
@@ -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 */
diff --git a/bfd/libaout.h b/bfd/libaout.h
index f063817..1f89385 100644
--- a/bfd/libaout.h
+++ b/bfd/libaout.h
@@ -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); \
\
diff --git a/bfd/libbfd-in.h b/bfd/libbfd-in.h
index 0f9a2cd..5ba73fe 100644
--- a/bfd/libbfd-in.h
+++ b/bfd/libbfd-in.h
@@ -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));
-
+
+/* 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 *));
+
/* 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 */
diff --git a/bfd/libbfd.c b/bfd/libbfd.c
index 74a28af..10e9a9d 100644
--- a/bfd/libbfd.c
+++ b/bfd/libbfd.c
@@ -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) \
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index 34f1968..e9b0560 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -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));
-
+
+/* 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 *));
+
/* 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
diff --git a/bfd/libelf.h b/bfd/libelf.h
index 838df6c..311bb1f 100644
--- a/bfd/libelf.h
+++ b/bfd/libelf.h
@@ -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
index 0000000..c8c988c
--- /dev/null
+++ b/bfd/osf-core.c
@@ -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 */
+}
+
+/* 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
index 0000000..5b07ea1
--- /dev/null
+++ b/bfd/ptrace-core.c
@@ -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;
+}
+
+/* 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 */
diff --git a/bfd/reloc.c b/bfd/reloc.c
index 0f05cbe..20dd050 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -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;
diff --git a/bfd/section.c b/bfd/section.c
index daccf2eb..374e2fa 100644
--- a/bfd/section.c
+++ b/bfd/section.c
@@ -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 ;
.
.
diff --git a/bfd/srec.c b/bfd/srec.c
index b37d207..02a49fb 100644
--- a/bfd/srec.c
+++ b/bfd/srec.c
@@ -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,
diff --git a/bfd/targets.c b/bfd/targets.c
index adfc530..8f10ef3 100644
--- a/bfd/targets.c
+++ b/bfd/targets.c
@@ -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;
diff --git a/bfd/trad-core.c b/bfd/trad-core.c
index d3e5fdd..f059a88 100644
--- a/bfd/trad-core.c
+++ b/bfd/trad-core.c
@@ -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 */