summaryrefslogtreecommitdiff
path: root/gnu/usr.bin/binutils/bfd/elflink.h
diff options
context:
space:
mode:
authorNiklas Hallqvist <niklas@cvs.openbsd.org>1996-09-04 19:11:21 +0000
committerNiklas Hallqvist <niklas@cvs.openbsd.org>1996-09-04 19:11:21 +0000
commitc3c8d76890b592bf5acc1a9b7faeabd9b829dd71 (patch)
tree6358a23d0df9de73b6d5d6d3a75545ff35f05b47 /gnu/usr.bin/binutils/bfd/elflink.h
parent4ba440a6e788da3a64fa29b782c37150a3f5cc18 (diff)
Merge the Cygnus 960904 sources
Diffstat (limited to 'gnu/usr.bin/binutils/bfd/elflink.h')
-rw-r--r--gnu/usr.bin/binutils/bfd/elflink.h105
1 files changed, 73 insertions, 32 deletions
diff --git a/gnu/usr.bin/binutils/bfd/elflink.h b/gnu/usr.bin/binutils/bfd/elflink.h
index 7fb51a7bb4e..6326121dcd7 100644
--- a/gnu/usr.bin/binutils/bfd/elflink.h
+++ b/gnu/usr.bin/binutils/bfd/elflink.h
@@ -23,8 +23,6 @@ static boolean elf_link_add_object_symbols
PARAMS ((bfd *, struct bfd_link_info *));
static boolean elf_link_add_archive_symbols
PARAMS ((bfd *, struct bfd_link_info *));
-static Elf_Internal_Rela *elf_link_read_relocs
- PARAMS ((bfd *, asection *, PTR, Elf_Internal_Rela *, boolean));
static boolean elf_export_symbol
PARAMS ((struct elf_link_hash_entry *, PTR));
static boolean elf_adjust_dynamic_symbol
@@ -679,17 +677,25 @@ elf_link_add_object_symbols (abfd, info)
by some other object. If it has, we want to use the
existing definition, and we do not want to report a
multiple symbol definition error; we do this by
- clobbering sec to be bfd_und_section_ptr. */
+ clobbering sec to be bfd_und_section_ptr. We treat a
+ common symbol as a definition if the symbol in the shared
+ library is a function, since common symbols always
+ represent variables; this can cause confusion in
+ principle, but any such confusion would seem to indicate
+ an erroneous program or shared library. */
if (dynamic && definition)
{
if (h->root.type == bfd_link_hash_defined
|| h->root.type == bfd_link_hash_defweak
|| (h->root.type == bfd_link_hash_common
- && bind == STB_WEAK))
+ && (bind == STB_WEAK
+ || ELF_ST_TYPE (sym.st_info) == STT_FUNC)))
{
sec = bfd_und_section_ptr;
definition = false;
size_change_ok = true;
+ if (h->root.type == bfd_link_hash_common)
+ type_change_ok = true;
}
}
@@ -700,7 +706,10 @@ elf_link_add_object_symbols (abfd, info)
objects, even if they are defined after the dynamic
object in the link. */
if (! dynamic
- && definition
+ && (definition
+ || (bfd_is_com_section (sec)
+ && (h->root.type == bfd_link_hash_defweak
+ || h->type == STT_FUNC)))
&& (h->root.type == bfd_link_hash_defined
|| h->root.type == bfd_link_hash_defweak)
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0
@@ -715,6 +724,8 @@ elf_link_add_object_symbols (abfd, info)
h->root.type = bfd_link_hash_undefined;
h->root.u.undef.abfd = h->root.u.def.section->owner;
size_change_ok = true;
+ if (bfd_is_com_section (sec))
+ type_change_ok = true;
}
}
@@ -948,9 +959,10 @@ elf_link_add_object_symbols (abfd, info)
if ((o->flags & SEC_ALLOC) == 0)
continue;
- internal_relocs = elf_link_read_relocs (abfd, o, (PTR) NULL,
- (Elf_Internal_Rela *) NULL,
- info->keep_memory);
+ internal_relocs = (NAME(_bfd_elf,link_read_relocs)
+ (abfd, o, (PTR) NULL,
+ (Elf_Internal_Rela *) NULL,
+ info->keep_memory));
if (internal_relocs == NULL)
goto error_return;
@@ -1150,8 +1162,9 @@ elf_add_dynamic_entry (info, tag, val)
value is allocated using either malloc or bfd_alloc, according to
the KEEP_MEMORY argument. */
-static Elf_Internal_Rela *
-elf_link_read_relocs (abfd, o, external_relocs, internal_relocs, keep_memory)
+Elf_Internal_Rela *
+NAME(_bfd_elf,link_read_relocs) (abfd, o, external_relocs, internal_relocs,
+ keep_memory)
bfd *abfd;
asection *o;
PTR external_relocs;
@@ -1896,7 +1909,8 @@ elf_bfd_final_link (abfd, info)
zero. This is done in elf_fake_sections as well, but forcing
the VMA to 0 here will ensure that relocs against these
sections are handled correctly. */
- if ((o->flags & SEC_ALLOC) == 0)
+ if ((o->flags & SEC_ALLOC) == 0
+ && ! o->user_set_vma)
o->vma = 0;
}
@@ -2714,6 +2728,7 @@ elf_link_input_bfd (finfo, input_bfd)
Elf_Internal_Shdr *symtab_hdr;
size_t locsymcount;
size_t extsymoff;
+ Elf_External_Sym *external_syms;
Elf_External_Sym *esym;
Elf_External_Sym *esymend;
Elf_Internal_Sym *isym;
@@ -2744,16 +2759,23 @@ elf_link_input_bfd (finfo, input_bfd)
}
/* Read the local symbols. */
- if (locsymcount > 0
- && (bfd_seek (input_bfd, symtab_hdr->sh_offset, SEEK_SET) != 0
- || (bfd_read (finfo->external_syms, sizeof (Elf_External_Sym),
+ if (symtab_hdr->contents != NULL)
+ external_syms = (Elf_External_Sym *) symtab_hdr->contents;
+ else if (locsymcount == 0)
+ external_syms = NULL;
+ else
+ {
+ external_syms = finfo->external_syms;
+ if (bfd_seek (input_bfd, symtab_hdr->sh_offset, SEEK_SET) != 0
+ || (bfd_read (external_syms, sizeof (Elf_External_Sym),
locsymcount, input_bfd)
- != locsymcount * sizeof (Elf_External_Sym))))
- return false;
+ != locsymcount * sizeof (Elf_External_Sym)))
+ return false;
+ }
/* Swap in the local symbols and write out the ones which we know
are going into the output file. */
- esym = finfo->external_syms;
+ esym = external_syms;
esymend = esym + locsymcount;
isym = finfo->internal_syms;
pindex = finfo->indices;
@@ -2793,7 +2815,7 @@ elf_link_input_bfd (finfo, input_bfd)
*ppsection = isec;
/* Don't output the first, undefined, symbol. */
- if (esym == finfo->external_syms)
+ if (esym == external_syms)
continue;
/* If we are stripping all symbols, we don't want to output this
@@ -2859,6 +2881,8 @@ elf_link_input_bfd (finfo, input_bfd)
/* Relocate the contents of each section. */
for (o = input_bfd->sections; o != NULL; o = o->next)
{
+ bfd_byte *contents;
+
if (! o->linker_mark)
{
/* This section was omitted from the link. */
@@ -2877,20 +2901,28 @@ elf_link_input_bfd (finfo, input_bfd)
continue;
}
- /* Read the contents of the section. */
- if (! bfd_get_section_contents (input_bfd, o, finfo->contents,
- (file_ptr) 0, o->_raw_size))
- return false;
+ /* Get the contents of the section. They have been cached by a
+ relaxation routine. Note that o is a section in an input
+ file, so the contents field will not have been set by any of
+ the routines which work on output files. */
+ if (elf_section_data (o)->this_hdr.contents != NULL)
+ contents = elf_section_data (o)->this_hdr.contents;
+ else
+ {
+ contents = finfo->contents;
+ if (! bfd_get_section_contents (input_bfd, o, contents,
+ (file_ptr) 0, o->_raw_size))
+ return false;
+ }
if ((o->flags & SEC_RELOC) != 0)
{
Elf_Internal_Rela *internal_relocs;
/* Get the swapped relocs. */
- internal_relocs = elf_link_read_relocs (input_bfd, o,
- finfo->external_relocs,
- finfo->internal_relocs,
- false);
+ internal_relocs = (NAME(_bfd_elf,link_read_relocs)
+ (input_bfd, o, finfo->external_relocs,
+ finfo->internal_relocs, false));
if (internal_relocs == NULL
&& o->reloc_count > 0)
return false;
@@ -2916,8 +2948,7 @@ elf_link_input_bfd (finfo, input_bfd)
the addend to be adjusted. */
if (! (*relocate_section) (output_bfd, finfo->info,
- input_bfd, o,
- finfo->contents,
+ input_bfd, o, contents,
internal_relocs,
finfo->internal_syms,
finfo->sections))
@@ -3090,7 +3121,7 @@ elf_link_input_bfd (finfo, input_bfd)
if (elf_section_data (o)->stab_info == NULL)
{
if (! bfd_set_section_contents (output_bfd, o->output_section,
- finfo->contents, o->output_offset,
+ contents, o->output_offset,
(o->_cooked_size != 0
? o->_cooked_size
: o->_raw_size)))
@@ -3100,7 +3131,7 @@ elf_link_input_bfd (finfo, input_bfd)
{
if (! _bfd_write_section_stabs (output_bfd, o,
&elf_section_data (o)->stab_info,
- finfo->contents))
+ contents))
return false;
}
}
@@ -3360,15 +3391,25 @@ elf_create_pointer_linker_section (abfd, info, lsect, h, rel)
linker_section_ptr->written_address_p = false;
*ptr_linker_section_ptr = linker_section_ptr;
+#if 0
if (lsect->hole_size && lsect->hole_offset < lsect->max_hole_offset)
{
- linker_section_ptr->offset = lsect->section->_raw_size - lsect->hole_size;
+ linker_section_ptr->offset = lsect->section->_raw_size - lsect->hole_size + (ARCH_SIZE / 8);
lsect->hole_offset += ARCH_SIZE / 8;
lsect->sym_offset += ARCH_SIZE / 8;
if (lsect->sym_hash) /* Bump up symbol value if needed */
- lsect->sym_hash->root.u.def.value += ARCH_SIZE / 8;
+ {
+ lsect->sym_hash->root.u.def.value += ARCH_SIZE / 8;
+#ifdef DEBUG
+ fprintf (stderr, "Bump up %s by %ld, current value = %ld\n",
+ lsect->sym_hash->root.root.string,
+ (long)ARCH_SIZE / 8,
+ (long)lsect->sym_hash->root.u.def.value);
+#endif
+ }
}
else
+#endif
linker_section_ptr->offset = lsect->section->_raw_size;
lsect->section->_raw_size += ARCH_SIZE / 8;