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

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