diff options
author | Ian Lance Taylor <ian@airs.com> | 1993-12-30 19:56:50 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@airs.com> | 1993-12-30 19:56:50 +0000 |
commit | 4c3721d5147489f4ba880871de0eafb025a4543f (patch) | |
tree | 724d86a479004d18377504718db9af69e6b6e660 /bfd/ecoff.c | |
parent | 4a6afc88bb00a7da893e2437d1d3c068c435a85e (diff) | |
download | gdb-4c3721d5147489f4ba880871de0eafb025a4543f.zip gdb-4c3721d5147489f4ba880871de0eafb025a4543f.tar.gz gdb-4c3721d5147489f4ba880871de0eafb025a4543f.tar.bz2 |
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.
Diffstat (limited to 'bfd/ecoff.c')
-rw-r--r-- | bfd/ecoff.c | 132 |
1 files changed, 62 insertions, 70 deletions
diff --git a/bfd/ecoff.c b/bfd/ecoff.c index 840d425..101adbd 100644 --- a/bfd/ecoff.c +++ b/bfd/ecoff.c @@ -21,8 +21,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "bfd.h" #include "sysdep.h" +#include "bfdlink.h" #include "libbfd.h" -#include "seclet.h" #include "aout/ar.h" #include "aout/ranlib.h" @@ -111,6 +111,8 @@ ecoff_mkobject_hook (abfd, filehdr, aouthdr) regsec = bfd_make_section (abfd, REGINFO); if (regsec == NULL) return NULL; + /* Tell the linker to leave this section completely alone. */ + regsec->flags = SEC_SHARED_LIBRARY; if (internal_a != (struct internal_aouthdr *) NULL) { @@ -1322,7 +1324,7 @@ ecoff_type_to_string (abfd, aux_ptr, indx, bigendian) case btStruct: /* Structure (Record) */ ecoff_swap_rndx_in (bigendian, &aux_ptr[indx].a_rndx, &rndx); ecoff_emit_aggregate (abfd, p1, &rndx, - AUX_GET_ISYM (bigendian, &aux_ptr[indx+1]), + (long) AUX_GET_ISYM (bigendian, &aux_ptr[indx+1]), "struct"); indx++; /* skip aux words */ break; @@ -1334,7 +1336,7 @@ ecoff_type_to_string (abfd, aux_ptr, indx, bigendian) case btUnion: /* Union */ ecoff_swap_rndx_in (bigendian, &aux_ptr[indx].a_rndx, &rndx); ecoff_emit_aggregate (abfd, p1, &rndx, - AUX_GET_ISYM (bigendian, &aux_ptr[indx+1]), + (long) AUX_GET_ISYM (bigendian, &aux_ptr[indx+1]), "union"); indx++; /* skip aux words */ break; @@ -1346,7 +1348,7 @@ ecoff_type_to_string (abfd, aux_ptr, indx, bigendian) case btEnum: /* Enumeration */ ecoff_swap_rndx_in (bigendian, &aux_ptr[indx].a_rndx, &rndx); ecoff_emit_aggregate (abfd, p1, &rndx, - AUX_GET_ISYM (bigendian, &aux_ptr[indx+1]), + (long) AUX_GET_ISYM (bigendian, &aux_ptr[indx+1]), "enum"); indx++; /* skip aux words */ break; @@ -2040,8 +2042,9 @@ ecoff_find_nearest_line (abfd, /* We can't use the generic linking routines for ECOFF, because we have to handle all the debugging information. The generic link routine just works out the section contents and attaches a list of - symbols. We find each input BFD by looping over all the seclets. - We accumulate the debugging information for each input BFD. */ + symbols. We find each input BFD by looping over all the link_order + information. We accumulate the debugging information for each + input BFD. */ /* Get ECOFF EXTR information for an external symbol. This function is passed to bfd_ecoff_debug_externals. */ @@ -2084,6 +2087,14 @@ ecoff_get_extr (sym, esym) (*(ecoff_backend (input_bfd)->debug_swap.swap_ext_in)) (input_bfd, ecoff_sym_ptr->native, esym); + /* If the symbol was defined by the linker, then esym will be + undefined but sym will not be. Get a better class for such a + symbol. */ + if ((esym->asym.sc == scUndefined + || esym->asym.sc == scSUndefined) + && bfd_get_section (sym) != &bfd_und_section) + esym->asym.sc = scAbs; + /* Adjust the FDR index for the symbol by that used for the input BFD. */ esym->ifd += ecoff_data (input_bfd)->debug_info.ifdbase; @@ -2107,16 +2118,15 @@ ecoff_set_index (sym, indx) link. */ boolean -ecoff_bfd_seclet_link (abfd, data, relocateable) +ecoff_bfd_final_link (abfd, info) bfd *abfd; - PTR data; - boolean relocateable; + struct bfd_link_info *info; { const struct ecoff_backend_data * const backend = ecoff_backend (abfd); struct ecoff_debug_info * const debug = &ecoff_data (abfd)->debug_info; HDRR *symhdr; - register asection *o; - register bfd_seclet_type *p; + register bfd *input_bfd; + asection *o; /* We accumulate the debugging information counts in the symbolic header. */ @@ -2147,69 +2157,49 @@ ecoff_bfd_seclet_link (abfd, data, relocateable) debug->external_fdr = debug->external_fdr_end = NULL; debug->external_rfd = debug->external_rfd_end = NULL; - /* We need to accumulate the debugging symbols from each input BFD. - We do this by looking through all the seclets to gather all the - input BFD's. We use the output_has_begun field to avoid - including a particular input BFD more than once. */ - - /* Clear the output_has_begun fields. */ - for (o = abfd->sections; o != (asection *) NULL; o = o->next) - for (p = o->seclets_head; - p != (bfd_seclet_type *) NULL; - p = p->next) - if (p->type == bfd_indirect_seclet) - p->u.indirect.section->owner->output_has_begun = false; - - /* Add in each input BFD. */ - for (o = abfd->sections; o != (asection *) NULL; o = o->next) + /* We accumulate the debugging symbols from each input BFD. */ + for (input_bfd = info->input_bfds; + input_bfd != (bfd *) NULL; + input_bfd = input_bfd->link_next) { - for (p = o->seclets_head; - p != (bfd_seclet_type *) NULL; - p = p->next) - { - bfd *input_bfd; - boolean ret; + boolean ret; - if (p->type != bfd_indirect_seclet) - continue; + if (bfd_get_flavour (input_bfd) == bfd_target_ecoff_flavour) + ret = (bfd_ecoff_debug_accumulate + (abfd, debug, &backend->debug_swap, + input_bfd, &ecoff_data (input_bfd)->debug_info, + &ecoff_backend (input_bfd)->debug_swap, info->relocateable)); + else + ret = bfd_ecoff_debug_link_other (abfd, + debug, + &backend->debug_swap, + input_bfd); - input_bfd = p->u.indirect.section->owner; - if (input_bfd->output_has_begun) - continue; + if (! ret) + return false; - if (bfd_get_flavour (input_bfd) == bfd_target_ecoff_flavour) - ret = (bfd_ecoff_debug_accumulate - (abfd, debug, &backend->debug_swap, - input_bfd, &ecoff_data (input_bfd)->debug_info, - &ecoff_backend (input_bfd)->debug_swap, relocateable)); - else - ret = bfd_ecoff_debug_link_other (abfd, - debug, - &backend->debug_swap, - input_bfd); - - if (ret == false) - return false; - - /* Combine the register masks. */ - ecoff_data (abfd)->gprmask |= ecoff_data (input_bfd)->gprmask; - ecoff_data (abfd)->fprmask |= ecoff_data (input_bfd)->fprmask; - ecoff_data (abfd)->cprmask[0] |= ecoff_data (input_bfd)->cprmask[0]; - ecoff_data (abfd)->cprmask[1] |= ecoff_data (input_bfd)->cprmask[1]; - ecoff_data (abfd)->cprmask[2] |= ecoff_data (input_bfd)->cprmask[2]; - ecoff_data (abfd)->cprmask[3] |= ecoff_data (input_bfd)->cprmask[3]; - - input_bfd->output_has_begun = true; - } + /* Combine the register masks. */ + ecoff_data (abfd)->gprmask |= ecoff_data (input_bfd)->gprmask; + ecoff_data (abfd)->fprmask |= ecoff_data (input_bfd)->fprmask; + ecoff_data (abfd)->cprmask[0] |= ecoff_data (input_bfd)->cprmask[0]; + ecoff_data (abfd)->cprmask[1] |= ecoff_data (input_bfd)->cprmask[1]; + ecoff_data (abfd)->cprmask[2] |= ecoff_data (input_bfd)->cprmask[2]; + ecoff_data (abfd)->cprmask[3] |= ecoff_data (input_bfd)->cprmask[3]; + } - /* Don't bother to do any linking of .reginfo sections. */ + /* Don't let the generic routine link the .reginfo sections. */ + for (o = abfd->sections; o != (asection *) NULL; o = o->next) + { if (strcmp (o->name, REGINFO) == 0) - o->seclets_head = (bfd_seclet_type *) NULL; + { + o->link_order_head = (struct bfd_link_order *) NULL; + break; + } } /* Let the generic link routine handle writing out the section contents. */ - return bfd_generic_seclet_link (abfd, data, relocateable); + return _bfd_generic_final_link (abfd, info); } /* Set the architecture. The supported architecture is stored in the @@ -2279,7 +2269,7 @@ ecoff_get_section_contents (abfd, section, location, offset, count) size is reasonable. We don't have to worry about swapping or any such thing; the .reginfo section is defined such that the contents are an ecoff_reginfo structure as seen on the host. */ - memcpy (location, ((char *) &s) + offset, count); + memcpy (location, ((char *) &s) + offset, (size_t) count); return true; } @@ -2382,7 +2372,7 @@ ecoff_set_section_contents (abfd, section, location, offset, count) swapping or any such thing; the .reginfo section is defined such that the contents are an ecoff_reginfo structure as seen on the host. */ - memcpy (((char *) &s) + offset, location, count); + memcpy (((char *) &s) + offset, location, (size_t) count); tdata->gp = s.gp_value; tdata->gprmask = s.gprmask; @@ -3134,7 +3124,7 @@ ecoff_write_armap (abfd, elength, map, orl_count, stridx) != sizeof (struct ar_hdr)) return false; - bfd_h_put_32 (abfd, hashsize, temp); + bfd_h_put_32 (abfd, (bfd_vma) hashsize, temp); if (bfd_write (temp, 1, 4, abfd) != 4) return false; @@ -3178,8 +3168,10 @@ ecoff_write_armap (abfd, elength, map, orl_count, stridx) hash = srch; } - bfd_h_put_32 (abfd, map[i].namidx, (PTR) (hashtable + hash * 8)); - bfd_h_put_32 (abfd, firstreal, (PTR) (hashtable + hash * 8 + 4)); + bfd_h_put_32 (abfd, (bfd_vma) map[i].namidx, + (PTR) (hashtable + hash * 8)); + bfd_h_put_32 (abfd, (bfd_vma) firstreal, + (PTR) (hashtable + hash * 8 + 4)); } if (bfd_write (hashtable, 1, symdefsize, abfd) != symdefsize) @@ -3188,7 +3180,7 @@ ecoff_write_armap (abfd, elength, map, orl_count, stridx) bfd_release (abfd, hashtable); /* Now write the strings. */ - bfd_h_put_32 (abfd, stringsize, temp); + bfd_h_put_32 (abfd, (bfd_vma) stringsize, temp); if (bfd_write (temp, 1, 4, abfd) != 4) return false; for (i = 0; i < orl_count; i++) |