This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: PATCH: Resolve size relocation against non-empty TLS symbol
- From: "H.J. Lu" <hongjiu dot lu at intel dot com>
- To: binutils at sourceware dot org
- Date: Fri, 18 Jan 2013 15:10:56 -0800
- Subject: Re: PATCH: Resolve size relocation against non-empty TLS symbol
- References: <20130118225931.GA30353@intel.com>
- Reply-to: "H.J. Lu" <hjl dot tools at gmail dot com>
On Fri, Jan 18, 2013 at 02:59:31PM -0800, H.J. Lu wrote:
> Hi,
>
> Run-time size relocations against TLS symbols don't always work:
>
> http://www.sourceware.org/bugzilla/show_bug.cgi?id=15030
>
> since size relocations don't count as TLS relocations. As the result,
> size relocations against TLS symbols may be resolved to 0. I checked
> in this patch to resolve size relocation against non-empty TLS symbols.
> As the consequence, if the TLS symbol size is changed at run-time,
> the TLS symbol size at link-time will still be used since it has been
> resolved at link-time.
>
>
> H.J.
> ---
> bfd/
>
> 2013-01-18 H.J. Lu <hongjiu.lu@intel.com>
>
> * 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/
>
> 2013-01-18 H.J. Lu <hongjiu.lu@intel.com>
>
> * 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.
>
Include the actual patch.
H.J.
---
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 85b411a..e60c472 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,14 @@
+2013-01-18 H.J. Lu <hongjiu.lu@intel.com>
+
+ * 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.
+
2013-01-18 Mike Frysinger <vapier@gentoo.org>
* elflink.c (bfd_elf_size_dynamic_sections): Only add DT_RPATH
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
index f8ad1d1..01e50a4 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:
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index 79b6dc6..71f33e2 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -2400,6 +2400,24 @@ elf_x86_64_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
@@ -3687,6 +3705,12 @@ elf_x86_64_relocate_section (bfd *output_bfd,
case R_X86_64_SIZE64:
/* 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;
+ }
goto direct;
case R_X86_64_PC8:
diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog
index 76d4585..70aa059 100644
--- a/ld/testsuite/ChangeLog
+++ b/ld/testsuite/ChangeLog
@@ -1,3 +1,13 @@
+2013-01-18 H.J. Lu <hongjiu.lu@intel.com>
+
+ * 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.
+
2013-01-17 H.J. Lu <hongjiu.lu@intel.com>
* ld-size/size-7.out: New file.
diff --git a/ld/testsuite/ld-size/size-10.rd b/ld/testsuite/ld-size/size-10.rd
index a5f8ee8..1cad47e 100644
--- a/ld/testsuite/ld-size/size-10.rd
+++ b/ld/testsuite/ld-size/size-10.rd
@@ -1,3 +1,4 @@
+#failif
+#...
+.* +R_.*_NONE +.*
#...
-[0-9a-f]+ +[0-9a-f]+ +R_.*_SIZE(32|64) +.*
-#pass
diff --git a/ld/testsuite/ld-size/size-8.rd b/ld/testsuite/ld-size/size-8.rd
index a5f8ee8..1cad47e 100644
--- a/ld/testsuite/ld-size/size-8.rd
+++ b/ld/testsuite/ld-size/size-8.rd
@@ -1,3 +1,4 @@
+#failif
+#...
+.* +R_.*_NONE +.*
#...
-[0-9a-f]+ +[0-9a-f]+ +R_.*_SIZE(32|64) +.*
-#pass
diff --git a/ld/testsuite/ld-size/size32-2-i386.d b/ld/testsuite/ld-size/size32-2-i386.d
index 2db0e1d..328006e 100644
--- a/ld/testsuite/ld-size/size32-2-i386.d
+++ b/ld/testsuite/ld-size/size32-2-i386.d
@@ -8,13 +8,11 @@
DYNAMIC RELOCATION RECORDS
OFFSET TYPE VALUE
-0+123c R_386_SIZE32 xxx
-0+1240 R_386_SIZE32 yyy
-0+1244 R_386_SIZE32 zzz
-0+1248 R_386_SIZE32 zzz
-0+124c R_386_SIZE32 zzz
+0+1234 R_386_SIZE32 zzz
+0+1238 R_386_SIZE32 zzz
+0+123c R_386_SIZE32 zzz
Contents of section .data:
- 123c 00000000 00000000 00000000 e2ffffff ................
- 124c 1e000000 ....
+ 122c 28000000 28000000 00000000 e2ffffff ................
+ 123c 1e000000 ....
diff --git a/ld/testsuite/ld-size/size32-2-x32.d b/ld/testsuite/ld-size/size32-2-x32.d
index 9c1eae2..5049c4a 100644
--- a/ld/testsuite/ld-size/size32-2-x32.d
+++ b/ld/testsuite/ld-size/size32-2-x32.d
@@ -8,13 +8,11 @@
DYNAMIC RELOCATION RECORDS
OFFSET TYPE VALUE
-0+200278 R_X86_64_SIZE32 xxx
-0+20027c R_X86_64_SIZE32 yyy
-0+200280 R_X86_64_SIZE32 zzz
-0+200284 R_X86_64_SIZE32 zzz-0x0000001e
-0+200288 R_X86_64_SIZE32 zzz\+0x0000001e
+0+200268 R_X86_64_SIZE32 zzz
+0+20026c R_X86_64_SIZE32 zzz-0x0000001e
+0+200270 R_X86_64_SIZE32 zzz\+0x0000001e
Contents of section .data:
- 200278 00000000 00000000 00000000 00000000 ................
- 200288 00000000 ....
+ 200260 28000000 28000000 00000000 00000000 ................
+ 200270 00000000 ....
diff --git a/ld/testsuite/ld-size/size32-2-x86-64.d b/ld/testsuite/ld-size/size32-2-x86-64.d
index 1851e0f..482b142 100644
--- a/ld/testsuite/ld-size/size32-2-x86-64.d
+++ b/ld/testsuite/ld-size/size32-2-x86-64.d
@@ -8,13 +8,11 @@
DYNAMIC RELOCATION RECORDS
OFFSET TYPE VALUE
-0+2003d8 R_X86_64_SIZE32 xxx
-0+2003dc R_X86_64_SIZE32 yyy
-0+2003e0 R_X86_64_SIZE32 zzz
-0+2003e4 R_X86_64_SIZE32 zzz-0x000000000000001e
-0+2003e8 R_X86_64_SIZE32 zzz\+0x000000000000001e
+0+2003b0 R_X86_64_SIZE32 zzz
+0+2003b4 R_X86_64_SIZE32 zzz-0x000000000000001e
+0+2003b8 R_X86_64_SIZE32 zzz\+0x000000000000001e
Contents of section .data:
- 2003d8 00000000 00000000 00000000 00000000 ................
- 2003e8 00000000 ....
+ 2003a8 28000000 28000000 00000000 00000000 ................
+ 2003b8 00000000 ....
diff --git a/ld/testsuite/ld-size/size64-2-x32.d b/ld/testsuite/ld-size/size64-2-x32.d
index 1a30c98..987f244 100644
--- a/ld/testsuite/ld-size/size64-2-x32.d
+++ b/ld/testsuite/ld-size/size64-2-x32.d
@@ -8,14 +8,12 @@
DYNAMIC RELOCATION RECORDS
OFFSET TYPE VALUE
-0+200278 R_X86_64_SIZE32 xxx
-0+200280 R_X86_64_SIZE32 yyy
-0+200288 R_X86_64_SIZE32 zzz
-0+200290 R_X86_64_SIZE64 zzz-0x0000001e
-0+200298 R_X86_64_SIZE64 zzz\+0x0000001e
+0+200270 R_X86_64_SIZE32 zzz
+0+200278 R_X86_64_SIZE64 zzz-0x0000001e
+0+200280 R_X86_64_SIZE64 zzz\+0x0000001e
Contents of section .data:
- 200278 00000000 00000000 00000000 00000000 ................
- 200288 00000000 00000000 00000000 00000000 ................
- 200298 00000000 00000000 ........
+ 200260 28000000 00000000 28000000 00000000 ................
+ 200270 00000000 00000000 00000000 00000000 ................
+ 200280 00000000 00000000 ........
diff --git a/ld/testsuite/ld-size/size64-2-x86-64.d b/ld/testsuite/ld-size/size64-2-x86-64.d
index 4cc11cf..72c6592 100644
--- a/ld/testsuite/ld-size/size64-2-x86-64.d
+++ b/ld/testsuite/ld-size/size64-2-x86-64.d
@@ -8,14 +8,12 @@
DYNAMIC RELOCATION RECORDS
OFFSET TYPE VALUE
-0+2003d8 R_X86_64_SIZE64 xxx
-0+2003e0 R_X86_64_SIZE64 yyy
-0+2003e8 R_X86_64_SIZE64 zzz
-0+2003f0 R_X86_64_SIZE64 zzz-0x000000000000001e
-0+2003f8 R_X86_64_SIZE64 zzz\+0x000000000000001e
+0+2003b8 R_X86_64_SIZE64 zzz
+0+2003c0 R_X86_64_SIZE64 zzz-0x000000000000001e
+0+2003c8 R_X86_64_SIZE64 zzz\+0x000000000000001e
Contents of section .data:
- 2003d8 00000000 00000000 00000000 00000000 ................
- 2003e8 00000000 00000000 00000000 00000000 ................
- 2003f8 00000000 00000000 ........
+ 2003a8 28000000 00000000 28000000 00000000 ................
+ 2003b8 00000000 00000000 00000000 00000000 ................
+ 2003c8 00000000 00000000 ........