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.
This commit is contained in:
Ian Lance Taylor 1993-12-30 19:56:50 +00:00
parent 4a6afc88bb
commit 4c3721d514
29 changed files with 4752 additions and 659 deletions

View File

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

View File

@ -290,12 +290,16 @@ DEFUN(aix386_core_file_matches_executable_p, (core_bfd, exec_bfd),
(bfd *, struct sec *))) bfd_void
#define aix386_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents
#define aix386_bfd_relax_section bfd_generic_relax_section
#define aix386_bfd_seclet_link \
((boolean (*) PARAMS ((bfd *, PTR, boolean))) bfd_false)
#define aix386_bfd_reloc_type_lookup \
((CONST struct reloc_howto_struct *(*) PARAMS ((bfd *, bfd_reloc_code_real_type))) bfd_nullvoidptr)
#define aix386_bfd_make_debug_symbol \
((asymbol *(*) PARAMS ((bfd *, void *, unsigned long))) bfd_nullvoidptr)
#define aix386_bfd_link_hash_table_create \
((struct bfd_link_hash_table *(*) PARAMS ((bfd *))) bfd_nullvoidptr)
#define aix386_bfd_link_add_symbols \
((boolean (*) PARAMS ((bfd *, struct bfd_link_info *))) bfd_false)
#define aix386_bfd_final_link \
((boolean (*) PARAMS ((bfd *, struct bfd_link_info *))) bfd_false)
/* If somebody calls any byte-swapping routines, shoot them. */
void

View File

@ -1,5 +1,5 @@
/* Define a target vector and some small routines for a variant of a.out.
Copyright (C) 1990-1991 Free Software Foundation, Inc.
Copyright (C) 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
@ -93,9 +93,16 @@ DEFUN(MY(object_p),(abfd),
return 0;
}
#ifdef NO_SWAP_MAGIC
memcpy (&exec.a_info, exec_bytes.e_info, sizeof(exec.a_info));
#else
exec.a_info = bfd_h_get_32 (abfd, exec_bytes.e_info);
#endif /* NO_SWAP_MAGIC */
if (N_BADMAG (exec)) return 0;
#ifdef MACHTYPE_OK
if (!(MACHTYPE_OK (N_MACHTYPE (exec)))) return 0;
#endif
NAME(aout,swap_exec_header_in)(abfd, &exec_bytes, &exec);
target = NAME(aout,some_aout_object_p) (abfd, &exec, MY(callback));
@ -199,6 +206,38 @@ static CONST struct aout_backend_data MY(backend_data) = {
#define MY_backend_data &MY(backend_data)
#endif
#ifndef MY_bfd_final_link
/* Final link routine. We need to use a call back to get the correct
offsets in the output file. */
static void final_link_callback
PARAMS ((bfd *, file_ptr *, file_ptr *, file_ptr *));
static void
final_link_callback (abfd, ptreloff, pdreloff, psymoff)
bfd *abfd;
file_ptr *ptreloff;
file_ptr *pdreloff;
file_ptr *psymoff;
{
struct internal_exec *execp = exec_hdr (abfd);
*ptreloff = N_TRELOFF (*execp);
*pdreloff = N_DRELOFF (*execp);
*psymoff = N_SYMOFF (*execp);
}
static boolean
MY_bfd_final_link (abfd, info)
bfd *abfd;
struct bfd_link_info *info;
{
return NAME(aout,final_link) (abfd, info, final_link_callback);
}
#endif
/* We assume BFD generic archive files. */
#ifndef MY_openr_next_archived_file
#define MY_openr_next_archived_file bfd_generic_openr_next_archived_file
@ -296,6 +335,9 @@ static CONST struct aout_backend_data MY(backend_data) = {
#ifndef MY_print_symbol
#define MY_print_symbol NAME(aout,print_symbol)
#endif
#ifndef MY_get_symbol_info
#define MY_get_symbol_info NAME(aout,get_symbol_info)
#endif
#ifndef MY_get_lineno
#define MY_get_lineno NAME(aout,get_lineno)
#endif
@ -314,20 +356,24 @@ static CONST struct aout_backend_data MY(backend_data) = {
#ifndef MY_sizeof_headers
#define MY_sizeof_headers NAME(aout,sizeof_headers)
#endif
#ifndef MY_bfd_debug_info_start
#define MY_bfd_debug_info_start NAME(aout,bfd_debug_info_start)
#ifndef MY_bfd_get_relocated_section_contents
#define MY_bfd_get_relocated_section_contents \
bfd_generic_get_relocated_section_contents
#endif
#ifndef MY_bfd_debug_info_end
#define MY_bfd_debug_info_end NAME(aout,bfd_debug_info_end)
#ifndef MY_bfd_relax_section
#define MY_bfd_relax_section bfd_generic_relax_section
#endif
#ifndef MY_bfd_debug_info_accumulat
#define MY_bfd_debug_info_accumulat NAME(aout,bfd_debug_info_accumulat)
#ifndef MY_bfd_reloc_type_lookup
#define MY_bfd_reloc_type_lookup NAME(aout,reloc_type_lookup)
#endif
#ifndef MY_reloc_howto_type_lookup
#define MY_reloc_howto_type_lookup NAME(aout,reloc_type_lookup)
#ifndef MY_bfd_make_debug_symbol
#define MY_bfd_make_debug_symbol 0
#endif
#ifndef MY_make_debug_symbol
#define MY_make_debug_symbol 0
#ifndef MY_bfd_link_hash_table_create
#define MY_bfd_link_hash_table_create NAME(aout,link_hash_table_create)
#endif
#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 */

View File

@ -1,5 +1,5 @@
/* A.out "format 1" file handling code for BFD.
Copyright 1990, 1991, 1992 Free Software Foundation, Inc.
Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
Written by Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
@ -30,8 +30,12 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "aout/ar.h"
/* This is needed to reject a NewsOS file, e.g. in
gdb/testsuite/gdb.t10/crossload.exp. */
#define MACHTYPE_OK(mtype) ((mtype) == M_68010 || (mtype) == M_68020 \
gdb/testsuite/gdb.t10/crossload.exp. <kingdon@cygnus.com>
I needed to add M_UNKNOWN to recognize a 68000 object, so this will
probably no longer reject a NewsOS object. <ian@cygnus.com>. */
#define MACHTYPE_OK(mtype) ((mtype) == M_UNKNOWN \
|| (mtype) == M_68010 \
|| (mtype) == M_68020 \
|| (mtype) == M_SPARC)
/*
@ -56,8 +60,6 @@ The name put into the target vector.
*/
void (*bfd_error_trap)();
/*SUPPRESS558*/
/*SUPPRESS529*/
@ -72,9 +74,9 @@ DEFUN(NAME(sunos,set_arch_mach), (abfd, machtype),
case M_UNKNOWN:
/* Some Sun3s make magic numbers without cpu types in them, so
we'll default to the 68020. */
we'll default to the 68000. */
arch = bfd_arch_m68k;
machine = 68020;
machine = 68000;
break;
case M_68010:
@ -95,6 +97,7 @@ DEFUN(NAME(sunos,set_arch_mach), (abfd, machtype),
break;
case M_386:
case M_386_DYNIX:
arch = bfd_arch_i386;
machine = 0;
break;

File diff suppressed because it is too large Load Diff

View File

@ -114,8 +114,8 @@ typedef unsigned HOST_64_BIT uint64_type;
#if !defined (uint64_type) && defined (__GNUC__)
#define uint64_type unsigned long long
#define int64_type long long
#define uint64_typeLOW(x) (unsigned long)(((x) & 0xffffffff))
#define uint64_typeHIGH(x) (unsigned long)(((x) >> 32) & 0xffffffff)
#define uint64_typeLOW(x) ((unsigned long)(((x) & 0xffffffff)))
#define uint64_typeHIGH(x) ((unsigned long)(((x) >> 32) & 0xffffffff))
#endif
typedef unsigned HOST_64_BIT bfd_vma;
@ -123,9 +123,9 @@ typedef HOST_64_BIT bfd_signed_vma;
typedef unsigned HOST_64_BIT bfd_size_type;
typedef unsigned HOST_64_BIT symvalue;
#define fprintf_vma(s,x) \
fprintf(s,"%08x%08x", uint64_typeHIGH(x), uint64_typeLOW(x))
fprintf(s,"%08lx%08lx", uint64_typeHIGH(x), uint64_typeLOW(x))
#define sprintf_vma(s,x) \
sprintf(s,"%08x%08x", uint64_typeHIGH(x), uint64_typeLOW(x))
sprintf(s,"%08lx%08lx", uint64_typeHIGH(x), uint64_typeLOW(x))
#else /* not BFD64 */
/* Represent a target address. Also used as a generic unsigned type
@ -286,41 +286,32 @@ typedef struct sec *sec_ptr;
typedef struct stat stat_type;
/** Error handling */
/* 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;
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;
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));
void (* reloc_dangerous) PARAMS ((CONST struct reloc_cache_entry *rel,
CONST struct bfd_seclet *sec));
} bfd_error_vector_type;
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

View File

@ -286,41 +286,32 @@ typedef struct sec *sec_ptr;
typedef struct stat stat_type;
/** Error handling */
/* 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;
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;
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));
void (* reloc_dangerous) PARAMS ((CONST struct reloc_cache_entry *rel,
CONST struct bfd_seclet *sec));
} bfd_error_vector_type;
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));
boolean (*_bfd_relax_section) PARAMS ((bfd *, struct sec *,
struct bfd_link_info *, struct bfd_link_order *,
bfd_byte *data, boolean relocateable,
struct symbol_cache_entry **));
boolean (*_bfd_seclet_link) PARAMS ((bfd *, PTR data,
boolean relocateable));
boolean (*_bfd_relax_section) PARAMS ((bfd *, struct sec *,
struct bfd_link_info *, struct symbol_cache_entry **));
/* 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 *

View File

@ -28,6 +28,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "coff/internal.h"
#include "libcoff.h"
static long get_symbol_value PARAMS ((asymbol *));
static bfd_reloc_status_type a29k_reloc
PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
#define INSERT_HWORD(WORD,HWORD) \
(((WORD) & 0xff00ff00) | (((HWORD) & 0xff00) << 8) | ((HWORD)& 0xff))
#define EXTRACT_HWORD(WORD) \
@ -36,9 +40,9 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
((HWORD) & 0x8000 ? (HWORD)|0xffff0000 : (HWORD))
/* Provided the symbol, returns the value reffed */
static long
get_symbol_value(symbol)
asymbol *symbol;
static long
get_symbol_value (symbol)
asymbol *symbol;
{
long relocation = 0;
@ -59,13 +63,15 @@ asymbol *symbol;
/* this function is in charge of performing all the 29k relocations */
static bfd_reloc_status_type
DEFUN(a29k_reloc,(abfd, reloc_entry, symbol_in, data, input_section, output_bfd),
bfd *abfd AND
arelent *reloc_entry AND
asymbol *symbol_in AND
PTR data AND
asection *input_section AND
bfd *output_bfd)
a29k_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd,
error_message)
bfd *abfd;
arelent *reloc_entry;
asymbol *symbol_in;
PTR data;
asection *input_section;
bfd *output_bfd;
char **error_message;
{
/* the consth relocation comes in two parts, we have to remember
the state between calls, in these variables */
@ -103,9 +109,8 @@ DEFUN(a29k_reloc,(abfd, reloc_entry, symbol_in, data, input_section, output_bfd)
if ((part1_consth_active) && (r_type != R_IHCONST))
{
fprintf(stderr,"Relocation problem : ");
fprintf(stderr,"Missing IHCONST in module %s\n",abfd->filename);
part1_consth_active = false;
*error_message = (char *) "Missing IHCONST";
return(bfd_reloc_dangerous);
}
@ -133,7 +138,7 @@ DEFUN(a29k_reloc,(abfd, reloc_entry, symbol_in, data, input_section, output_bfd)
signed_value -= (input_section->output_section->vma
+ input_section->output_offset);
if (signed_value>0x1ffff || signed_value<-0x20000)
return(bfd_reloc_outofrange);
return(bfd_reloc_overflow);
}
signed_value >>= 2;
insn = INSERT_HWORD(insn, signed_value);
@ -159,9 +164,7 @@ DEFUN(a29k_reloc,(abfd, reloc_entry, symbol_in, data, input_section, output_bfd)
/* consth, part 2
Now relocate the reference */
if (part1_consth_active == false) {
fprintf(stderr,"Relocation problem : ");
fprintf(stderr,"IHIHALF missing in module %s\n",
abfd->filename);
*error_message = (char *) "Missing IHIHALF";
return(bfd_reloc_dangerous);
}
/* sym_ptr_ptr = r_symndx, in coff_slurp_reloc_table() */
@ -202,9 +205,7 @@ DEFUN(a29k_reloc,(abfd, reloc_entry, symbol_in, data, input_section, output_bfd)
bfd_put_32(abfd, insn, hit_data);
break;
default:
fprintf(stderr,"Relocation problem : ");
fprintf(stderr,"Unrecognized reloc type %d, in module %s\n",
r_type,abfd->filename);
*error_message = "Unrecognized reloc";
return (bfd_reloc_dangerous);
}

View File

@ -39,7 +39,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "sysdep.h"
#include "libbfd.h"
#include "coff/internal.h"
#include "seclet.h"
#include "libcoff.h"
static asection bfd_debug_section = { "*DEBUG*" };
@ -67,6 +66,13 @@ DEFUN(make_a_section_from_file,(abfd, hdr, target_index),
return_section = bfd_make_section(abfd, name);
if (return_section == NULL)
return_section = bfd_coff_make_section_hook (abfd, name);
/* Handle several sections of the same name. For example, if an executable
has two .bss sections, GDB better be able to find both of them
(PR 3562). */
if (return_section == NULL)
return_section = bfd_make_section_anyway (abfd, name);
if (return_section == NULL)
return false;
@ -904,10 +910,7 @@ coff_section_symbol (abfd, name)
combined_entry_type *csym;
sym = sec->symbol;
if (coff_symbol_from (abfd, sym))
csym = coff_symbol_from (abfd, sym)->native;
else
csym = 0;
csym = coff_symbol_from (abfd, sym)->native;
/* Make sure back-end COFF stuff is there. */
if (csym == 0)
{
@ -924,18 +927,16 @@ coff_section_symbol (abfd, name)
csym[0].u.syment.n_sclass = C_STAT;
csym[0].u.syment.n_numaux = 1;
/* SF_SET_STATICS (sym); @@ ??? */
if (sec)
csym[1].u.auxent.x_scn.x_scnlen = sec->_raw_size;
csym[1].u.auxent.x_scn.x_nreloc = sec->reloc_count;
csym[1].u.auxent.x_scn.x_nlinno = sec->lineno_count;
if (sec->output_section == NULL)
{
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 = 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++;
}
}

View File

@ -21,8 +21,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "bfd.h"
#include "sysdep.h"
#include "bfdlink.h"
#include "libbfd.h"
#include "seclet.h"
#include "aout/ar.h"
#include "aout/ranlib.h"
@ -111,6 +111,8 @@ ecoff_mkobject_hook (abfd, filehdr, aouthdr)
regsec = bfd_make_section (abfd, REGINFO);
if (regsec == NULL)
return NULL;
/* Tell the linker to leave this section completely alone. */
regsec->flags = SEC_SHARED_LIBRARY;
if (internal_a != (struct internal_aouthdr *) NULL)
{
@ -1322,7 +1324,7 @@ ecoff_type_to_string (abfd, aux_ptr, indx, bigendian)
case btStruct: /* Structure (Record) */
ecoff_swap_rndx_in (bigendian, &aux_ptr[indx].a_rndx, &rndx);
ecoff_emit_aggregate (abfd, p1, &rndx,
AUX_GET_ISYM (bigendian, &aux_ptr[indx+1]),
(long) AUX_GET_ISYM (bigendian, &aux_ptr[indx+1]),
"struct");
indx++; /* skip aux words */
break;
@ -1334,7 +1336,7 @@ ecoff_type_to_string (abfd, aux_ptr, indx, bigendian)
case btUnion: /* Union */
ecoff_swap_rndx_in (bigendian, &aux_ptr[indx].a_rndx, &rndx);
ecoff_emit_aggregate (abfd, p1, &rndx,
AUX_GET_ISYM (bigendian, &aux_ptr[indx+1]),
(long) AUX_GET_ISYM (bigendian, &aux_ptr[indx+1]),
"union");
indx++; /* skip aux words */
break;
@ -1346,7 +1348,7 @@ ecoff_type_to_string (abfd, aux_ptr, indx, bigendian)
case btEnum: /* Enumeration */
ecoff_swap_rndx_in (bigendian, &aux_ptr[indx].a_rndx, &rndx);
ecoff_emit_aggregate (abfd, p1, &rndx,
AUX_GET_ISYM (bigendian, &aux_ptr[indx+1]),
(long) AUX_GET_ISYM (bigendian, &aux_ptr[indx+1]),
"enum");
indx++; /* skip aux words */
break;
@ -2040,8 +2042,9 @@ ecoff_find_nearest_line (abfd,
/* We can't use the generic linking routines for ECOFF, because we
have to handle all the debugging information. The generic link
routine just works out the section contents and attaches a list of
symbols. We find each input BFD by looping over all the seclets.
We accumulate the debugging information for each input BFD. */
symbols. We find each input BFD by looping over all the link_order
information. We accumulate the debugging information for each
input BFD. */
/* Get ECOFF EXTR information for an external symbol. This function
is passed to bfd_ecoff_debug_externals. */
@ -2084,6 +2087,14 @@ ecoff_get_extr (sym, esym)
(*(ecoff_backend (input_bfd)->debug_swap.swap_ext_in))
(input_bfd, ecoff_sym_ptr->native, esym);
/* If the symbol was defined by the linker, then esym will be
undefined but sym will not be. Get a better class for such a
symbol. */
if ((esym->asym.sc == scUndefined
|| esym->asym.sc == scSUndefined)
&& bfd_get_section (sym) != &bfd_und_section)
esym->asym.sc = scAbs;
/* Adjust the FDR index for the symbol by that used for the input
BFD. */
esym->ifd += ecoff_data (input_bfd)->debug_info.ifdbase;
@ -2107,16 +2118,15 @@ ecoff_set_index (sym, indx)
link. */
boolean
ecoff_bfd_seclet_link (abfd, data, relocateable)
ecoff_bfd_final_link (abfd, info)
bfd *abfd;
PTR data;
boolean relocateable;
struct bfd_link_info *info;
{
const struct ecoff_backend_data * const backend = ecoff_backend (abfd);
struct ecoff_debug_info * const debug = &ecoff_data (abfd)->debug_info;
HDRR *symhdr;
register asection *o;
register bfd_seclet_type *p;
register bfd *input_bfd;
asection *o;
/* We accumulate the debugging information counts in the symbolic
header. */
@ -2147,69 +2157,49 @@ ecoff_bfd_seclet_link (abfd, data, relocateable)
debug->external_fdr = debug->external_fdr_end = NULL;
debug->external_rfd = debug->external_rfd_end = NULL;
/* We need to accumulate the debugging symbols from each input BFD.
We do this by looking through all the seclets to gather all the
input BFD's. We use the output_has_begun field to avoid
including a particular input BFD more than once. */
/* 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)
{
boolean ret;
/* 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. */
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);
if (! ret)
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];
}
/* Don't let the generic routine link the .reginfo sections. */
for (o = abfd->sections; o != (asection *) NULL; o = o->next)
{
for (p = o->seclets_head;
p != (bfd_seclet_type *) NULL;
p = p->next)
{
bfd *input_bfd;
boolean ret;
if (p->type != bfd_indirect_seclet)
continue;
input_bfd = p->u.indirect.section->owner;
if (input_bfd->output_has_begun)
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, 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;
}
/* Don't bother to do any linking of .reginfo sections. */
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++)

View File

@ -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

View File

@ -47,11 +47,18 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#define bfd_elf32_bfd_get_relocated_section_contents \
bfd_generic_get_relocated_section_contents
#define bfd_elf32_bfd_relax_section bfd_generic_relax_section
#ifndef bfd_elf32_bfd_seclet_link
#define bfd_elf32_bfd_seclet_link bfd_generic_seclet_link
#endif
#define bfd_elf32_bfd_make_debug_symbol \
((asymbol *(*) PARAMS ((bfd *, void *, unsigned long))) bfd_nullvoidptr)
#ifndef bfd_elf32_bfd_link_hash_table_create
#define bfd_elf32_bfd_link_hash_table_create \
_bfd_generic_link_hash_table_create
#endif
#ifndef bfd_elf32_bfd_link_add_symbols
#define bfd_elf32_bfd_link_add_symbols _bfd_generic_link_add_symbols
#endif
#ifndef bfd_elf32_bfd_final_link
#define bfd_elf32_bfd_final_link _bfd_generic_final_link
#endif
#ifndef elf_info_to_howto_rel
#define elf_info_to_howto_rel 0

View File

@ -47,9 +47,18 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#define bfd_elf64_bfd_get_relocated_section_contents \
bfd_generic_get_relocated_section_contents
#define bfd_elf64_bfd_relax_section bfd_generic_relax_section
#define bfd_elf64_bfd_seclet_link bfd_generic_seclet_link
#define bfd_elf64_bfd_make_debug_symbol \
((asymbol *(*) PARAMS ((bfd *, void *, unsigned long))) bfd_nullvoidptr)
#ifndef bfd_elf64_bfd_link_hash_table_create
#define bfd_elf64_bfd_link_hash_table_create \
_bfd_generic_link_hash_table_create
#endif
#ifndef bfd_elf64_bfd_link_add_symbols
#define bfd_elf64_bfd_link_add_symbols _bfd_generic_link_add_symbols
#endif
#ifndef bfd_elf64_bfd_final_link
#define bfd_elf64_bfd_final_link _bfd_generic_final_link
#endif
#ifndef elf_info_to_howto_rel
#define elf_info_to_howto_rel 0

View File

@ -26,7 +26,6 @@ extern int fflush ();
extern int write ();
extern void abort ();
extern int close ();
extern int qsort ();
extern void exit ();
extern int fseek ();
extern int fclose ();
@ -70,7 +69,6 @@ extern char *strrchr();
extern int chmod();
extern int fstat();
extern int stat();
extern int strtol();
extern char *strrchr();
extern char *ctime();

334
bfd/hppabsd-core.c Normal file
View File

@ -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

318
bfd/hpux-core.c Normal file
View File

@ -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 */
};

292
bfd/irix-core.c Normal file
View File

@ -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 */

View File

@ -26,7 +26,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
for a 32-bit architecture or a 64-bit architecture. */
#if ARCH_SIZE==64
#define GET_WORD bfd_h_get_64
#define GET_SWORD (int64_type)GET_WORD
#define GET_SWORD bfd_h_get_signed_64
#define PUT_WORD bfd_h_put_64
#ifndef NAME
#define NAME(x,y) CAT3(x,_64_,y)
@ -35,7 +35,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#define BYTES_IN_WORD 8
#else /* ARCH_SIZE == 32 */
#define GET_WORD bfd_h_get_32
#define GET_SWORD (int32_type)GET_WORD
#define GET_SWORD bfd_h_get_signed_32
#define PUT_WORD bfd_h_put_32
#ifndef NAME
#define NAME(x,y) CAT3(x,_32_,y)
@ -111,6 +111,12 @@ struct internal_exec
3130292827262524232221201918171615141312111009080706050403020100
< FLAGS >< MACHINE TYPE >< MAGIC NUMBER >
*/
/* Magic number for NetBSD is
<MSB >
3130292827262524232221201918171615141312111009080706050403020100
< FLAGS >< >< MAGIC NUMBER >
*/
enum machine_type {
M_UNKNOWN = 0,
M_68010 = 1,
@ -119,6 +125,8 @@ enum machine_type {
/* skip a bunch so we don't run into any of suns numbers */
M_386 = 100,
M_29K = 101, /* AMD 29000 */
M_386_DYNIX = 102, /* Sequent running dynix */
M_386_NETBSD = 134, /* NetBSD/386 binary */
M_MIPS1 = 151, /* MIPS R2000/R3000 binary */
M_MIPS2 = 152, /* MIPS R4000/R6000 binary */
M_HP200 = 200, /* HP 200 (68010) BSD binary */
@ -128,24 +136,41 @@ enum machine_type {
#define N_DYNAMIC(exec) ((exec).a_info & 0x8000000)
#define N_MAGIC(exec) ((exec).a_info & 0xffff)
#define N_MACHTYPE(exec) ((enum machine_type)(((exec).a_info >> 16) & 0xff))
#define N_FLAGS(exec) (((exec).a_info >> 24) & 0xff)
#define N_SET_INFO(exec, magic, type, flags) \
#ifndef N_MAGIC
# define N_MAGIC(exec) ((exec).a_info & 0xffff)
#endif
#ifndef N_MACHTYPE
# define N_MACHTYPE(exec) ((enum machine_type)(((exec).a_info >> 16) & 0xff))
#endif
#ifndef N_FLAGS
# define N_FLAGS(exec) (((exec).a_info >> 24) & 0xff)
#endif
#ifndef N_SET_INFO
# define N_SET_INFO(exec, magic, type, flags) \
((exec).a_info = ((magic) & 0xffff) \
| (((int)(type) & 0xff) << 16) \
| (((flags) & 0xff) << 24))
#endif
#define N_SET_MAGIC(exec, magic) \
#ifndef N_SET_MAGIC
# define N_SET_MAGIC(exec, magic) \
((exec).a_info = (((exec).a_info & 0xffff0000) | ((magic) & 0xffff)))
#endif
#define N_SET_MACHTYPE(exec, machtype) \
#ifndef N_SET_MACHTYPE
# define N_SET_MACHTYPE(exec, machtype) \
((exec).a_info = \
((exec).a_info&0xff00ffff) | ((((int)(machtype))&0xff) << 16))
#endif
#define N_SET_FLAGS(exec, flags) \
#ifndef N_SET_FLAGS
# define N_SET_FLAGS(exec, flags) \
((exec).a_info = \
((exec).a_info&0x00ffffff) | (((flags) & 0xff) << 24))
#endif
typedef struct aout_symbol {
asymbol symbol;
@ -197,6 +222,12 @@ struct aoutdata {
z_magic,
o_magic,
n_magic } magic;
/* The external symbol information. */
struct external_nlist *external_syms;
bfd_size_type external_sym_count;
char *external_strings;
struct aout_link_hash_entry **sym_hashes;
};
struct aout_data_struct {
@ -215,6 +246,10 @@ struct aout_data_struct {
#define obj_reloc_entry_size(bfd) (adata(bfd).reloc_entry_size)
#define obj_symbol_entry_size(bfd) (adata(bfd).symbol_entry_size)
#define obj_aout_subformat(bfd) (adata(bfd).subformat)
#define obj_aout_external_syms(bfd) (adata(bfd).external_syms)
#define obj_aout_external_sym_count(bfd) (adata(bfd).external_sym_count)
#define obj_aout_external_strings(bfd) (adata(bfd).external_strings)
#define obj_aout_sym_hashes(bfd) (adata(bfd).sym_hashes)
/* We take the address of the first element of an asymbol to ensure that the
macro is only ever applied to an asymbol */
@ -254,7 +289,7 @@ NAME(aout,make_empty_symbol) PARAMS ((bfd *abfd));
boolean
NAME(aout,slurp_symbol_table) PARAMS ((bfd *abfd));
void
boolean
NAME(aout,write_syms) PARAMS ((bfd *abfd));
void
@ -314,6 +349,17 @@ void
NAME(aout,swap_exec_header_out) PARAMS ((bfd *abfd,
struct internal_exec *execp, struct external_exec *raw_bytes));
struct bfd_link_hash_table *
NAME(aout,link_hash_table_create) PARAMS ((bfd *));
boolean
NAME(aout,link_add_symbols) PARAMS ((bfd *, struct bfd_link_info *));
boolean
NAME(aout,final_link) PARAMS ((bfd *, struct bfd_link_info *,
void (*) (bfd *, file_ptr *, file_ptr *,
file_ptr *)));
/* Prototypes for functions in stab-syms.c. */
CONST char *
@ -351,11 +397,12 @@ aout_stab_name PARAMS ((int code));
bfd_write ((PTR) &exec_bytes, 1, EXEC_BYTES_SIZE, abfd); \
/* Now write out reloc info, followed by syms and strings */ \
\
if (bfd_get_symcount (abfd) != 0) \
if (bfd_get_outsymbols (abfd) != (asymbol **) NULL \
&& bfd_get_symcount (abfd) != 0) \
{ \
bfd_seek (abfd, (file_ptr)(N_SYMOFF(*execp)), SEEK_SET); \
\
NAME(aout,write_syms)(abfd); \
if (! NAME(aout,write_syms)(abfd)) return false; \
\
bfd_seek (abfd, (file_ptr)(N_TRELOFF(*execp)), SEEK_SET); \
\

View File

@ -19,6 +19,12 @@ You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Use builtin alloca for gcc. */
#ifdef __GNUC__
#ifndef alloca
#define alloca __builtin_alloca
#endif
#endif
/* Align an address upward to a boundary, expressed as a number of bytes.
E.g. align to an 8-byte boundary with argument of 8. */
@ -44,7 +50,8 @@ struct artdata {
carsym *symdefs; /* the symdef entries */
symindex symdef_count; /* how many there are */
char *extended_names; /* clever intel extension */
time_t armap_timestamp; /* Timestamp value written into armap.
/* when more compilers are standard C, this can be a time_t */
long armap_timestamp; /* Timestamp value written into armap.
This is used for BSD archives to check
that the timestamp is recent enough
for the BSD linker to not complain,
@ -88,6 +95,9 @@ int bfd_seek PARAMS ((bfd* CONST abfd, CONST file_ptr fp,
CONST int direction));
long bfd_tell PARAMS ((bfd *abfd));
int bfd_flush PARAMS ((bfd *abfd));
int bfd_stat PARAMS ((bfd *abfd, struct stat *));
bfd * _bfd_create_empty_archive_element_shell PARAMS ((bfd *obfd));
bfd * look_for_bfd_in_cache PARAMS ((bfd *arch_bfd, file_ptr index));
boolean _bfd_generic_mkarchive PARAMS ((bfd *abfd));
@ -99,7 +109,7 @@ boolean bfd_slurp_bsd_armap_f2 PARAMS ((bfd *abfd));
#define bfd_slurp_coff_armap bfd_slurp_armap
boolean _bfd_slurp_extended_name_table PARAMS ((bfd *abfd));
boolean _bfd_write_archive_contents PARAMS ((bfd *abfd));
bfd * new_bfd PARAMS (());
bfd * new_bfd PARAMS ((void));
#define DEFAULT_STRING_SPACE_SIZE 0x2000
boolean bfd_add_to_string_table PARAMS ((char **table, char *new_string,
@ -146,7 +156,60 @@ boolean bfd_generic_get_section_contents PARAMS ((bfd *abfd, sec_ptr section,
boolean bfd_generic_set_section_contents PARAMS ((bfd *abfd, sec_ptr section,
PTR location, file_ptr offset,
bfd_size_type count));
/* 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 */

View File

@ -1,5 +1,5 @@
/* Assorted BFD support routines, only used internally.
Copyright 1990, 1991, 1992 Free Software Foundation, Inc.
Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
Written by Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
@ -310,7 +310,7 @@ DEFUN(bfd_seek,(abfd, position, direction),
#ifdef FILE_OFFSET_IS_CHAR_INDEX
if (abfd->format != bfd_archive && abfd->my_archive == 0)
{
#ifndef NDEBUG
#if 0
/* Explanation for this code: I'm only about 95+% sure that the above
conditions are sufficient and that all i/o calls are properly
adjusting the `where' field. So this is sort of an `assert'
@ -461,7 +461,7 @@ DESCRIPTION
.{* Byte swapping macros for user section data. *}
.
.#define bfd_put_8(abfd, val, ptr) \
. (*((unsigned char *)(ptr)) = (unsigned char)val)
. (*((unsigned char *)(ptr)) = (unsigned char)(val))
.#define bfd_put_signed_8 \
. bfd_put_8
.#define bfd_get_8(abfd, ptr) \

View File

@ -19,6 +19,12 @@ You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Use builtin alloca for gcc. */
#ifdef __GNUC__
#ifndef alloca
#define alloca __builtin_alloca
#endif
#endif
/* Align an address upward to a boundary, expressed as a number of bytes.
E.g. align to an 8-byte boundary with argument of 8. */
@ -103,7 +109,7 @@ boolean bfd_slurp_bsd_armap_f2 PARAMS ((bfd *abfd));
#define bfd_slurp_coff_armap bfd_slurp_armap
boolean _bfd_slurp_extended_name_table PARAMS ((bfd *abfd));
boolean _bfd_write_archive_contents PARAMS ((bfd *abfd));
bfd * new_bfd PARAMS (());
bfd * new_bfd PARAMS ((void));
#define DEFAULT_STRING_SPACE_SIZE 0x2000
boolean bfd_add_to_string_table PARAMS ((char **table, char *new_string,
@ -150,7 +156,60 @@ boolean bfd_generic_get_section_contents PARAMS ((bfd *abfd, sec_ptr section,
boolean bfd_generic_set_section_contents PARAMS ((bfd *abfd, sec_ptr section,
PTR location, file_ptr offset,
bfd_size_type count));
/* 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

View File

@ -241,7 +241,8 @@ extern bfd_reloc_status_type bfd_elf_generic_reloc PARAMS ((bfd *,
asymbol *,
PTR,
asection *,
bfd *));
bfd *,
char **));
extern boolean bfd_elf_mkobject PARAMS ((bfd *));
extern Elf_Internal_Shdr *bfd_elf_find_section PARAMS ((bfd *, char *));

298
bfd/osf-core.c Normal file
View File

@ -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 */
};

303
bfd/ptrace-core.c Normal file
View File

@ -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 */

View File

@ -43,8 +43,8 @@ SECTION
*/
#include "bfd.h"
#include "sysdep.h"
#include "bfdlink.h"
#include "libbfd.h"
#include "seclet.h"
/*
DOCDD
INODE
@ -82,7 +82,8 @@ CODE_FRAGMENT
.
. {* The relocation was performed, but may not be ok - presently
. generated only when linking i960 coff files with i960 b.out
. symbols. *}
. symbols. If this type is returned, the error_message argument
. to bfd_perform_relocation will be set. *}
. bfd_reloc_dangerous
. }
. bfd_reloc_status_type;
@ -100,7 +101,7 @@ CODE_FRAGMENT
. bfd_vma addend;
.
. {* Pointer to how to perform the required relocation *}
. CONST struct reloc_howto_struct *howto;
. const struct reloc_howto_struct *howto;
.
.} arelent;
@ -189,7 +190,7 @@ DESCRIPTION
|offset type value
|00000002 HVRT16 _foo+0x12340000
|00000006 LVRT16 _foo+0x12340000
|
|00000000 5da05678 ; or.u r13,r0,0x5678
|00000004 1c4d5678 ; ld.b r2,r13,0x5678
|00000008 f400c001 ; jmp r1
@ -214,7 +215,7 @@ DESCRIPTION
| ret
| restore
Both relocs contains a pointer to <<foo>>, and the offsets
Both relocs contain a pointer to <<foo>>, and the offsets
contain junk.
@ -222,7 +223,7 @@ DESCRIPTION
|offset type value
|00000004 HI22 _foo+0x12345678
|00000008 LO10 _foo+0x12345678
|
|00000000 9de3bf90 ; save %sp,-112,%sp
|00000004 05000000 ; sethi %hi(_foo+0),%g2
|00000008 f048a000 ; ldsb [%g2+%lo(_foo+0)],%i0
@ -296,16 +297,8 @@ CODE_FRAGMENT
. unsigned int rightshift;
.
. {* The size of the item to be relocated. This is *not* a
. power-of-two measure.
. 0 : one byte
. 1 : two bytes
. 2 : four bytes
. 3 : nothing done (unless special_function is nonzero)
. 4 : eight bytes
. -2 : two bytes, result should be subtracted from the
. data instead of added
. There is currently no trivial way to extract a "number of
. bytes" from a howto pointer. *}
. power-of-two measure. To get the number of bytes operated
. on by a type of relocation, use bfd_get_reloc_size. *}
. int size;
.
. {* The number of bits in the item to be relocated. This is used
@ -336,7 +329,8 @@ CODE_FRAGMENT
. struct symbol_cache_entry *symbol,
. PTR data,
. asection *input_section,
. bfd *output_bfd));
. bfd *output_bfd,
. char **error_message));
.
. {* The textual name of the relocation type. *}
. char *name;
@ -407,6 +401,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_overflow:
if (! ((*link_info->callbacks->reloc_overflow)
(link_info, 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);
break;
default:
abort();
break;

View File

@ -112,23 +112,23 @@ SUBSECTION
SUBSECTION
Seclets
Link orders
The data within a section is stored in a @dfn{seclet}. These
are much like the fixups in <<gas>>. The seclet abstraction
allows a section to grow and shrink within itself.
The data within a section is stored in a @dfn{link_order}.
These are much like the fixups in <<gas>>. The link_order
abstraction allows a section to grow and shrink within itself.
A seclet knows how big it is, and which is the next seclet and
where the raw data for it is; it also points to a list of
relocations which apply to it.
A link_order knows how big it is, and which is the next
link_order and where the raw data for it is; it also points to
a list of relocations which apply to it.
The seclet is used by the linker to perform relaxing on final
code. The compiler creates code which is as big as
The link_order is used by the linker to perform relaxing on
final code. The compiler creates code which is as big as
necessary to make it work without relaxing, and the user can
select whether to relax. Sometimes relaxing takes a lot of
time. The linker runs around the relocations to see if any
are attached to data which can be shrunk, if so it does it on
a seclet by seclet basis.
a link_order by link_order basis.
*/
@ -361,8 +361,8 @@ CODE_FRAGMENT
. struct symbol_cache_entry *symbol;
. struct symbol_cache_entry **symbol_ptr_ptr;
.
. struct bfd_seclet *seclets_head;
. struct bfd_seclet *seclets_tail;
. struct bfd_link_order *link_order_head;
. struct bfd_link_order *link_order_tail;
.} asection ;
.
.

View File

@ -279,7 +279,7 @@ unsigned int length)
static int white(x)
char x;
{
return (x== ' ' || x == '\t' || x == '\n' || x == '\r');
return (x== ' ' || x == '\t' || x == '\n' || x == '\r');
}
static int
skipwhite(src,abfd)
@ -309,12 +309,11 @@ DEFUN(srec_mkobject, (abfd),
}
static void
DEFUN(pass_over,(abfd, func, symbolfunc, section),
bfd *abfd AND
void (*func)() AND
void (*symbolfunc)() AND
asection *section)
static void pass_over(abfd, func, symbolfunc, section)
bfd *abfd;
void (*func)();
void (*symbolfunc)();
asection *section;
{
unsigned int bytes_on_line;
boolean eof = false;
@ -348,45 +347,46 @@ DEFUN(pass_over,(abfd, func, symbolfunc, section),
case ' ':
/* spaces - maybe just before a symbol */
while (*src != '\n' && white(*src)) {
eof = skipwhite(src, abfd);
{
int val = 0;
int slen = 0;
char symbol[MAXCHUNK];
/* get the symbol part */
while (!eof && !white(*src) && slen < MAXCHUNK)
while (*src != '\n' && *src != '\r' && white(*src))
{
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);
}
eof = skipwhite(src, abfd);
/* Scan off the hex number */
while (isxdigit(*src ))
{
val *= 16;
if (isdigit(*src))
val += *src - '0';
else if (isupper(*src)) {
val += *src - 'A' + 10;
{
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,

View File

@ -130,7 +130,10 @@ DESCRIPTION
. bfd_target_tekhex_flavour,
. bfd_target_srec_flavour,
. bfd_target_som_flavour};
.
.{* Forward declaration. *}
.typedef struct bfd_link_info _bfd_link_info;
.
.typedef struct bfd_target
.{
@ -290,15 +293,13 @@ Symbols and relocations.
. void (*_bfd_debug_info_accumulate) PARAMS ((bfd *, struct sec *));
.
. bfd_byte * (*_bfd_get_relocated_section_contents) PARAMS ((bfd *,
. struct bfd_seclet *, bfd_byte *data,
. boolean relocateable));
.
. boolean (*_bfd_relax_section) PARAMS ((bfd *, struct sec *,
. struct bfd_link_info *, struct bfd_link_order *,
. bfd_byte *data, boolean relocateable,
. struct symbol_cache_entry **));
.
. boolean (*_bfd_seclet_link) PARAMS ((bfd *, PTR data,
. boolean relocateable));
. boolean (*_bfd_relax_section) PARAMS ((bfd *, struct sec *,
. struct bfd_link_info *, struct symbol_cache_entry **));
.
. {* 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;

View File

@ -80,6 +80,12 @@ trad_unix_core_file_p (abfd)
int val;
struct user u;
#ifdef TRAD_CORE_USER_OFFSET
/* If defined, this macro is the file position of the user struct. */
if (bfd_seek (abfd, TRAD_CORE_USER_OFFSET, SEEK_SET) == 0)
return 0;
#endif
val = bfd_read ((void *)&u, 1, sizeof u, abfd);
if (val != sizeof u)
{
@ -116,6 +122,7 @@ trad_unix_core_file_p (abfd)
bfd_error = file_truncated;
return 0;
}
#ifndef TRAD_CORE_ALLOW_ANY_EXTRA_SIZE
if (NBPG * (UPAGES + u.u_dsize + u.u_ssize)
#ifdef TRAD_CORE_EXTRA_SIZE_ALLOWED
/* Some systems write the file too big. */
@ -128,6 +135,7 @@ trad_unix_core_file_p (abfd)
bfd_error = wrong_format;
return 0;
}
#endif
}
/* OK, we believe you. You're a core file (sure, sure). */
@ -186,7 +194,13 @@ trad_unix_core_file_p (abfd)
#else
core_datasec (abfd)->vma = HOST_TEXT_START_ADDR + (NBPG * u.u_tsize);
#endif
#ifdef HOST_STACK_START_ADDR
core_stacksec (abfd)->vma = HOST_STACK_START_ADDR;
#else
core_stacksec (abfd)->vma = HOST_STACK_END_ADDR - (NBPG * u.u_ssize);
#endif
/* This is tricky. As the "register section", we give them the entire
upage and stack. u.u_ar0 points to where "register 0" is stored.
There are two tricks with this, though. One is that the rest of the
@ -204,7 +218,11 @@ trad_unix_core_file_p (abfd)
core_regsec (abfd)->vma = 0 - (int) u.u_ar0;
core_datasec (abfd)->filepos = NBPG * UPAGES;
#ifdef TRAD_CORE_STACK_FILEPOS
core_stacksec (abfd)->filepos = TRAD_CORE_STACK_FILEPOS;
#else
core_stacksec (abfd)->filepos = (NBPG * UPAGES) + NBPG * u.u_dsize;
#endif
core_regsec (abfd)->filepos = 0; /* Register segment is the upage */
/* Align to word at least */
@ -303,12 +321,16 @@ trad_unix_core_file_matches_executable_p (core_bfd, exec_bfd)
((bfd *, struct sec *))) bfd_void
#define trad_unix_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents
#define trad_unix_bfd_relax_section bfd_generic_relax_section
#define trad_unix_bfd_seclet_link \
((boolean (*) PARAMS ((bfd *, PTR, boolean))) bfd_false)
#define trad_unix_bfd_reloc_type_lookup \
((CONST struct reloc_howto_struct *(*) PARAMS ((bfd *, bfd_reloc_code_real_type))) bfd_nullvoidptr)
#define trad_unix_bfd_make_debug_symbol \
((asymbol *(*) PARAMS ((bfd *, void *, unsigned long))) bfd_nullvoidptr)
#define trad_unix_bfd_link_hash_table_create \
((struct bfd_link_hash_table *(*) PARAMS ((bfd *))) bfd_nullvoidptr)
#define trad_unix_bfd_link_add_symbols \
((boolean (*) PARAMS ((bfd *, struct bfd_link_info *))) bfd_false)
#define trad_unix_bfd_final_link \
((boolean (*) PARAMS ((bfd *, struct bfd_link_info *))) bfd_false)
/* If somebody calls any byte-swapping routines, shoot them. */
void
@ -328,7 +350,7 @@ bfd_target trad_core_vec =
true, /* target headers byte order */
(HAS_RELOC | EXEC_P | /* object flags */
HAS_LINENO | HAS_DEBUG |
HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
(SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
0, /* symbol prefix */
' ', /* ar_pad_char */