This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: Binutils 2.29.1 breaks libpcap on sparc32 by filling .got
- From: Alan Modra <amodra at gmail dot com>
- To: Rolf Eike Beer <eb at emlix dot com>
- Cc: binutils at sourceware dot org
- Date: Fri, 8 Dec 2017 11:49:38 +1030
- Subject: Re: Binutils 2.29.1 breaks libpcap on sparc32 by filling .got
- Authentication-results: sourceware.org; auth=none
- References: <13757039.pIICRVicT9@devpool21> <20171208005012.GM13179@bubble.grove.modra.org>
On Fri, Dec 08, 2017 at 11:20:12AM +1030, Alan Modra wrote:
> So it looks like sparc and sparc64 ld needs to be sure to zero section
> contents whenever a RELATIVE relocation is emitted, to avoid this
> glibc bug.
Please test this.
* elfxx-sparc.c (_bfd_sparc_elf_relocate_section): When emitting
dynamic R_SPARC_RELATIVE for GOT entries, ensure the section
contents are zeroed.
diff --git a/bfd/elfxx-sparc.c b/bfd/elfxx-sparc.c
index adc9ed3..9885059 100644
--- a/bfd/elfxx-sparc.c
+++ b/bfd/elfxx-sparc.c
@@ -3212,10 +3212,6 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd,
off &= ~1;
else
{
- SPARC_ELF_PUT_WORD (htab, output_bfd, relocation,
- htab->elf.sgot->contents + off);
- h->got.offset |= 1;
-
if (h->dynindx == -1
&& !h->forced_local
&& h->root.type != bfd_link_hash_undefweak
@@ -3225,6 +3221,10 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd,
generate R_SPARC_RELATIVE here. */
relative_reloc = TRUE;
}
+ else
+ SPARC_ELF_PUT_WORD (htab, output_bfd, relocation,
+ htab->elf.sgot->contents + off);
+ h->got.offset |= 1;
}
}
else
@@ -3245,12 +3245,10 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd,
else
{
if (bfd_link_pic (info))
- {
- relative_reloc = TRUE;
- }
-
- SPARC_ELF_PUT_WORD (htab, output_bfd, relocation,
- htab->elf.sgot->contents + off);
+ relative_reloc = TRUE;
+ else
+ SPARC_ELF_PUT_WORD (htab, output_bfd, relocation,
+ htab->elf.sgot->contents + off);
local_got_offsets[r_symndx] |= 1;
}
}
@@ -3271,8 +3269,14 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd,
outrel.r_info = SPARC_ELF_R_INFO (htab, NULL,
0, R_SPARC_RELATIVE);
outrel.r_addend = relocation;
- relocation = 0;
sparc_elf_append_rela (output_bfd, s, &outrel);
+ /* Versions of glibc ld.so at least up to 2.26 wrongly
+ add the section contents to the value calculated for
+ a RELATIVE reloc. Zero the contents to work around
+ this bug. */
+ relocation = 0;
+ SPARC_ELF_PUT_WORD (htab, output_bfd, relocation,
+ htab->elf.sgot->contents + off);
}
relocation = htab->elf.sgot->output_offset + off - got_base;
--
Alan Modra
Australia Development Lab, IBM