Message ID | 1400854416-3764-1-git-send-email-will.newton@linaro.org |
---|---|
State | Accepted |
Headers | show |
On 23 May 2014 15:13, Will Newton <will.newton@linaro.org> wrote: > 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-05-21 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-05-21 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. > --- > bfd/elf32-arm.c | 9 ++++++--- > ld/testsuite/ld-arm/arm-elf.exp | 3 +++ > ld/testsuite/ld-arm/ifunc-gdesc.r | 6 ++++++ > ld/testsuite/ld-arm/ifunc-gdesc.s | 29 +++++++++++++++++++++++++++++ > ld/testsuite/ld-arm/ifunc-gdesc.ver | 4 ++++ > 5 files changed, 48 insertions(+), 3 deletions(-) > create mode 100644 ld/testsuite/ld-arm/ifunc-gdesc.r > create mode 100644 ld/testsuite/ld-arm/ifunc-gdesc.s > create mode 100644 ld/testsuite/ld-arm/ifunc-gdesc.ver Ping? > diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c > index 526d4f8..6a20baf 100644 > --- a/bfd/elf32-arm.c > +++ b/bfd/elf32-arm.c > @@ -7521,6 +7521,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. */ > @@ -7533,7 +7535,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; > } > } > @@ -13359,8 +13364,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. */ > diff --git a/ld/testsuite/ld-arm/arm-elf.exp b/ld/testsuite/ld-arm/arm-elf.exp > index c255587..2e7e164 100644 > --- a/ld/testsuite/ld-arm/arm-elf.exp > +++ b/ld/testsuite/ld-arm/arm-elf.exp > @@ -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 > diff --git a/ld/testsuite/ld-arm/ifunc-gdesc.r b/ld/testsuite/ld-arm/ifunc-gdesc.r > new file mode 100644 > index 0000000..a49dd2b > --- /dev/null > +++ b/ld/testsuite/ld-arm/ifunc-gdesc.r > @@ -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\* > diff --git a/ld/testsuite/ld-arm/ifunc-gdesc.s b/ld/testsuite/ld-arm/ifunc-gdesc.s > new file mode 100644 > index 0000000..a07a5d5 > --- /dev/null > +++ b/ld/testsuite/ld-arm/ifunc-gdesc.s > @@ -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 > + > diff --git a/ld/testsuite/ld-arm/ifunc-gdesc.ver b/ld/testsuite/ld-arm/ifunc-gdesc.ver > new file mode 100644 > index 0000000..a82ffc4 > --- /dev/null > +++ b/ld/testsuite/ld-arm/ifunc-gdesc.ver > @@ -0,0 +1,4 @@ > +{ > +global: foo; > +local: *; > +}; > \ No newline at end of file > -- > 1.9.0 >
Hi Will, > bfd/ChangeLog: > > 2014-05-21 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-05-21 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. Approved - please apply. Cheers Nick
diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c index 526d4f8..6a20baf 100644 --- a/bfd/elf32-arm.c +++ b/bfd/elf32-arm.c @@ -7521,6 +7521,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. */ @@ -7533,7 +7535,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; } } @@ -13359,8 +13364,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. */ diff --git a/ld/testsuite/ld-arm/arm-elf.exp b/ld/testsuite/ld-arm/arm-elf.exp index c255587..2e7e164 100644 --- a/ld/testsuite/ld-arm/arm-elf.exp +++ b/ld/testsuite/ld-arm/arm-elf.exp @@ -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 diff --git a/ld/testsuite/ld-arm/ifunc-gdesc.r b/ld/testsuite/ld-arm/ifunc-gdesc.r new file mode 100644 index 0000000..a49dd2b --- /dev/null +++ b/ld/testsuite/ld-arm/ifunc-gdesc.r @@ -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\* diff --git a/ld/testsuite/ld-arm/ifunc-gdesc.s b/ld/testsuite/ld-arm/ifunc-gdesc.s new file mode 100644 index 0000000..a07a5d5 --- /dev/null +++ b/ld/testsuite/ld-arm/ifunc-gdesc.s @@ -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 + diff --git a/ld/testsuite/ld-arm/ifunc-gdesc.ver b/ld/testsuite/ld-arm/ifunc-gdesc.ver new file mode 100644 index 0000000..a82ffc4 --- /dev/null +++ b/ld/testsuite/ld-arm/ifunc-gdesc.ver @@ -0,0 +1,4 @@ +{ +global: foo; +local: *; +};