summaryrefslogtreecommitdiff
path: root/bfd/elf32-i386.c
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2013-01-18 22:50:26 +0000
committerH.J. Lu <hjl.tools@gmail.com>2013-01-18 22:50:26 +0000
commit605f3766434cbed0e7a719545639b8a1e926e14c (patch)
tree25e16883f537117ea145d3b3e59f216aa2e60937 /bfd/elf32-i386.c
parent0e0646ad6f21c4d6230c31f452b73f133f4b5777 (diff)
downloadbinutils-redhat-605f3766434cbed0e7a719545639b8a1e926e14c.tar.gz
Resolve size relocation against non-zero TLS symbol
bfd/ * elf32-i386.c (elf_i386_allocate_dynrelocs): Clear pc_count for non-zero TLS symbol. (elf_i386_relocate_section): Resolve size relocation against non-zero TLS symbol. * elf64-x86-64.c (elf_x86_64_allocate_dynrelocs): Clear pc_count for non-zero TLS symbol. (elf_x86_64_relocate_section): Resolve size relocation against non-zero TLS symbol. ld/testsuite/ * ld-size/size-10.rd: Updated. * ld-size/size-8.rd: Likewise. * ld-size/size32-2-i386.d: Likewise. * ld-size/size32-2-x32.d: Likewise. * ld-size/size32-2-x86-64.d: Likewise. * ld-size/size64-2-x32.d: Likewise. * ld-size/size64-2-x86-64.d: Likewise.
Diffstat (limited to 'bfd/elf32-i386.c')
-rw-r--r--bfd/elf32-i386.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
index f8ad1d1c1f..01e50a41c6 100644
--- a/bfd/elf32-i386.c
+++ b/bfd/elf32-i386.c
@@ -2358,6 +2358,24 @@ elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
if (eh->dyn_relocs == NULL)
return TRUE;
+ /* Since pc_count for TLS symbol can only have size relocations and
+ we always resolve size relocation against non-zero TLS symbol, we
+ clear pc_count for non-zero TLS symbol. */
+ if (h->type == STT_TLS && h->size != 0)
+ {
+ struct elf_dyn_relocs **pp;
+
+ for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
+ {
+ p->count -= p->pc_count;
+ p->pc_count = 0;
+ if (p->count == 0)
+ *pp = p->next;
+ else
+ pp = &p->next;
+ }
+ }
+
/* In the shared -Bsymbolic case, discard space allocated for
dynamic pc-relative relocs against symbols which turn out to be
defined in regular objects. For the normal shared case, discard
@@ -3691,6 +3709,12 @@ elf_i386_relocate_section (bfd *output_bfd,
case R_386_SIZE32:
/* Set to symbol size. */
relocation = st_size;
+ if (h && h->type == STT_TLS && st_size != 0)
+ {
+ /* Resolve size relocation against non-zero TLS symbol. */
+ unresolved_reloc = FALSE;
+ break;
+ }
/* Fall through. */
case R_386_32: