ld/ARM: Fix IFUNC and TLS descriptors in the same shared object

Combining TLS descriptors and GNU indirect functions in the same
object could lead to assertions or multiple dynamic relocations
for the same GOT slot. Fix the bookkeeping so this doesn't happen.

This allows building and make checking glibc with -mtls-dialect=gnu2.

bfd/ChangeLog:

2014-06-16  Will Newton  <will.newton@linaro.org>

	* elf32-arm.c (elf32_arm_allocate_plt_entry): Increment
	htab->next_tls_desc_index in the non-IPLT case.
	Calculate GOT offset correctly for the non-IPLT case.
	(allocate_dynrelocs_for_symbol): Don't increment
	htab->next_tls_desc_index here.

ld/testsuite/ChangeLog:

2014-06-16  Will Newton  <will.newton@linaro.org>

	* ld-arm/arm-elf.exp: Add ifunc-gdesc test.
	* ld-arm/ifunc-gdesc.r: New file.
	* ld-arm/ifunc-gdesc.s: Likewise.
	* ld-arm/ifunc-gdesc.ver: Likewise.
This commit is contained in:
Will Newton 2014-06-16 15:49:07 +01:00
parent d03de42190
commit 9f19ab6dfa
7 changed files with 63 additions and 3 deletions

View File

@ -1,3 +1,11 @@
2014-06-16 Will Newton <will.newton@linaro.org>
* elf32-arm.c (elf32_arm_allocate_plt_entry): Increment
htab->next_tls_desc_index in the non-IPLT case.
Calculate GOT offset correctly for the non-IPLT case.
(allocate_dynrelocs_for_symbol): Don't increment
htab->next_tls_desc_index here.
2014-06-16 Alan Modra <amodra@gmail.com>
* elf32-vax.c (elf_vax_size_dynamic_sections): Clear linker

View File

@ -7522,6 +7522,8 @@ elf32_arm_allocate_plt_entry (struct bfd_link_info *info,
first entry. */
if (splt->size == 0)
splt->size += htab->plt_header_size;
htab->next_tls_desc_index++;
}
/* Allocate the PLT entry itself, including any leading Thumb stub. */
@ -7534,7 +7536,10 @@ elf32_arm_allocate_plt_entry (struct bfd_link_info *info,
{
/* We also need to make an entry in the .got.plt section, which
will be placed in the .got section by the linker script. */
arm_plt->got_offset = sgotplt->size - 8 * htab->num_tls_desc;
if (is_iplt_entry)
arm_plt->got_offset = sgotplt->size;
else
arm_plt->got_offset = sgotplt->size - 8 * htab->num_tls_desc;
sgotplt->size += 4;
}
}
@ -13360,8 +13365,6 @@ allocate_dynrelocs_for_symbol (struct elf_link_hash_entry *h, void * inf)
h->target_internal = ST_BRANCH_TO_ARM;
}
htab->next_tls_desc_index++;
/* VxWorks executables have a second set of relocations for
each PLT entry. They go in a separate relocation section,
which is processed by the kernel loader. */

View File

@ -1,3 +1,10 @@
2014-06-16 Will Newton <will.newton@linaro.org>
* ld-arm/arm-elf.exp: Add ifunc-gdesc test.
* ld-arm/ifunc-gdesc.r: New file.
* ld-arm/ifunc-gdesc.s: Likewise.
* ld-arm/ifunc-gdesc.ver: Likewise.
2014-06-09 Ryan Mansfield <rmansfield@qnx.com>
* config/default.exp (GASP): Remove.

View File

@ -460,6 +460,9 @@ set armelftests_nonacl {
"" {long-plt-format.s}
{{objdump "-d -j .plt" long-plt-format.d}}
"long-plt-format"}
{"IFUNC and TLS descriptor shared library" "-shared -T arm-lib.ld --version-script=ifunc-gdesc.ver" "" "" {ifunc-gdesc.s}
{{objdump "-Rw" ifunc-gdesc.r}}
"ifunc-gdesc.so"}
}
run_ld_link_tests $armelftests_common

View File

@ -0,0 +1,6 @@
tmpdir/ifunc-gdesc.so: file format elf32-(big|little)arm
DYNAMIC RELOCATION RECORDS
OFFSET TYPE VALUE
0000825c R_ARM_IRELATIVE \*ABS\*
00008248 R_ARM_TLS_DESC \*ABS\*
00008250 R_ARM_TLS_DESC \*ABS\*

View File

@ -0,0 +1,29 @@
.arm
foo:
bl ifunc1(PLT)
ldr r0,1f
2: bl loc1(tlscall)
nop
1: .word loc1(tlsdesc) + (. - 2b)
ldr r0,1f
2: bl loc2(tlscall)
nop
1: .word loc2(tlsdesc) + (. - 2b)
.type ifunc1,%gnu_indirect_function
.global ifunc1
ifunc1:
mov pc,lr
.size ifunc1,.-ifunc1
.section .tdata,"awT",%progbits
.space 8
.type loc1, %object
loc1: .space 4
.type loc2, %object
loc2: .space 4

View File

@ -0,0 +1,4 @@
{
global: foo;
local: *;
};