Segfaults in elflink.h
Alan Modra
alan@linuxcare.com.au
Sat Oct 7 06:48:00 GMT 2000
This patch cures some segfaults exposed when running the ld testsuite on
hppa64-linux. The root cause of the problem is that elf64-hppa.c always
creates dynamic sections, and the linker script ld-scripts/weak.t merrily
discards all sections bar .text and .data, breaking assumptions made in
various places in elflink.h.
bfd/ChangeLog
* elflink.h (size_dynamic_sections): Don't create various tags if
.dynstr is excluded from the link. Don't set first dynsym entry
if dynsymcount is zero.
(elf_bfd_final_link): Don't try to swap out dynamic syms if
.dynsym excluded from the link. Don't try to write any dynamic
sections excluded from the link.
Alan Modra
--
Linuxcare. Support for the Revolution.
Index: bfd/elflink.h
===================================================================
RCS file: /cvs/src/src/bfd/elflink.h,v
retrieving revision 1.72
diff -u -p -w -r1.72 elflink.h
--- elflink.h 2000/09/29 13:15:03 1.72
+++ elflink.h 2000/10/07 12:57:24
@@ -2897,7 +2897,7 @@ NAME(bfd_elf,size_dynamic_sections) (out
{
struct elf_info_failed eif;
struct elf_link_hash_entry *h;
- bfd_size_type strsize;
+ asection *dynstr;
*sinterpptr = bfd_get_section_by_name (dynobj, ".interp");
BFD_ASSERT (*sinterpptr != NULL || info->shared);
@@ -3026,6 +3026,15 @@ NAME(bfd_elf,size_dynamic_sections) (out
return false;
}
+ dynstr = bfd_get_section_by_name (dynobj, ".dynstr");
+ /* If .dynstr is excluded from the link, we don't want any of
+ these tags. Strictly, we should be checking each section
+ individually; This quick check covers for the case where
+ someone does a /DISCARD/ : { *(*) }. */
+ if (dynstr != NULL && dynstr->output_section != bfd_abs_section_ptr)
+ {
+ bfd_size_type strsize;
+
strsize = _bfd_stringtab_size (elf_hash_table (info)->dynstr);
if (! elf_add_dynamic_entry (info, DT_HASH, 0)
|| ! elf_add_dynamic_entry (info, DT_STRTAB, 0)
@@ -3035,6 +3044,7 @@ NAME(bfd_elf,size_dynamic_sections) (out
sizeof (Elf_External_Sym)))
return false;
}
+ }
/* The backend must work out the sizes of all the other dynamic
sections. */
@@ -3047,7 +3057,6 @@ NAME(bfd_elf,size_dynamic_sections) (out
size_t dynsymcount;
asection *s;
size_t bucketcount = 0;
- Elf_Internal_Sym isym;
size_t hash_entry_size;
/* Set up the version definition section. */
@@ -3384,6 +3393,10 @@ NAME(bfd_elf,size_dynamic_sections) (out
if (s->contents == NULL && s->_raw_size != 0)
return false;
+ if (dynsymcount != 0)
+ {
+ Elf_Internal_Sym isym;
+
/* The first entry in .dynsym is a dummy symbol. */
isym.st_value = 0;
isym.st_size = 0;
@@ -3393,6 +3406,7 @@ NAME(bfd_elf,size_dynamic_sections) (out
isym.st_shndx = 0;
elf_swap_symbol_out (output_bfd, &isym,
(PTR) (Elf_External_Sym *) s->contents);
+ }
/* Compute the size of the hashing table. As a side effect this
computes the hash values for all the names we export. */
@@ -4602,7 +4616,8 @@ elf_bfd_final_link (abfd, info)
/* The sh_info field records the index of the first non local symbol. */
symtab_hdr->sh_info = bfd_get_symcount (abfd);
- if (dynamic)
+ if (dynamic
+ && finfo.dynsym_sec->output_section != bfd_abs_section_ptr)
{
Elf_Internal_Sym sym;
Elf_External_Sym *dynsym =
@@ -4867,7 +4882,8 @@ elf_bfd_final_link (abfd, info)
for (o = dynobj->sections; o != NULL; o = o->next)
{
if ((o->flags & SEC_HAS_CONTENTS) == 0
- || o->_raw_size == 0)
+ || o->_raw_size == 0
+ || o->output_section == bfd_abs_section_ptr)
continue;
if ((o->flags & SEC_LINKER_CREATED) == 0)
{
More information about the Binutils
mailing list