aboutsummaryrefslogtreecommitdiff
path: root/bfd/ecoff.c
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@airs.com>1993-12-30 19:56:50 +0000
committerIan Lance Taylor <ian@airs.com>1993-12-30 19:56:50 +0000
commit4c3721d5147489f4ba880871de0eafb025a4543f (patch)
tree724d86a479004d18377504718db9af69e6b6e660 /bfd/ecoff.c
parent4a6afc88bb00a7da893e2437d1d3c068c435a85e (diff)
downloadgdb-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.c132
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++)