From ce12121b63145322b4961bbb2b94b939cb916ba7 Mon Sep 17 00:00:00 2001 From: Tamar Christina Date: Thu, 11 Apr 2019 11:27:28 +0100 Subject: [PATCH] AArch64: When DF_BIND_NOW don't use TLSDESC GOT value. When using DF_BIND_NOW on AArch64 we don't reserve the GOT slot for a TLSDESC, but we still emitted DT_TLSDESC_GOT and DT_TLSDESC_PLT. This caused random memory corruption as the "special" value of (bfd_vma)-1 would be set for dt_tlsdesc_got. Since we don't have a value of dt_tlsdesc_got I also don't emit DT_TLSDESC_PLT now becuase it would point to an incomplete PLT. To be able to write the PLT entry DT_TLSDESC_GOT is needed and since we don't have one we can't write the PLT entry either. It is my understanding that GLIBC doesn't need these two entries when not lazy loading. Conversely AArch32 does not reserve neither the GOT not the PLT slot when doing DF_BIND_NOW. AArch32 does not need these checks because these values are initialized to 0 and so the if (...) checks don't pass, but on AArch64 these are initialized to (bfd_vma)-1 and thus we need some extra checks. bfd/ChangeLog: PR ld/24302 * elfnn-aarch64.c (elfNN_aarch64_size_dynamic_sections): Don't emit DT_TLSDESC_GOT and DT_TLSDESC_PLT when DF_BIND_NOW. (elfNN_aarch64_finish_dynamic_sections): Don't write PLT if DF_BIND_NOW. ld/ChangeLog: PR ld/24302 * testsuite/ld-aarch64/aarch64-elf.exp: Add new test. * testsuite/ld-aarch64/tls-relax-gdesc-le-now.d: New test. --- bfd/ChangeLog | 7 +++++++ bfd/elfnn-aarch64.c | 13 ++++++++----- ld/ChangeLog | 6 ++++++ ld/testsuite/ld-aarch64/aarch64-elf.exp | 1 + .../ld-aarch64/tls-relax-gdesc-le-now.d | 19 +++++++++++++++++++ 5 files changed, 41 insertions(+), 5 deletions(-) create mode 100644 ld/testsuite/ld-aarch64/tls-relax-gdesc-le-now.d diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 03cab045da6..022e7c3f083 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,10 @@ +2019-04-11 Tamar Christina + + PR ld/24302 + * elfnn-aarch64.c (elfNN_aarch64_size_dynamic_sections): Don't emit + DT_TLSDESC_GOT and DT_TLSDESC_PLT when DF_BIND_NOW. + (elfNN_aarch64_finish_dynamic_sections): Don't write PLT if DF_BIND_NOW. + 2019-04-10 Michael Forney PR 24427 diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c index 57a723d5477..9d4df11f9d4 100644 --- a/bfd/elfnn-aarch64.c +++ b/bfd/elfnn-aarch64.c @@ -9064,13 +9064,13 @@ elfNN_aarch64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, if (htab->root.splt->size == 0) htab->root.splt->size += htab->plt_header_size; - htab->tlsdesc_plt = htab->root.splt->size; - htab->root.splt->size += htab->tlsdesc_plt_entry_size; - /* If we're not using lazy TLS relocations, don't generate the - GOT entry required. */ + GOT and PLT entry required. */ if (!(info->flags & DF_BIND_NOW)) { + htab->tlsdesc_plt = htab->root.splt->size; + htab->root.splt->size += htab->tlsdesc_plt_entry_size; + htab->dt_tlsdesc_got = htab->root.sgot->size; htab->root.sgot->size += GOT_ENTRY_SIZE; } @@ -9174,6 +9174,7 @@ elfNN_aarch64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, return FALSE; if (htab->tlsdesc_plt + && !(info->flags & DF_BIND_NOW) && (!add_dynamic_entry (DT_TLSDESC_PLT, 0) || !add_dynamic_entry (DT_TLSDESC_GOT, 0))) return FALSE; @@ -9686,6 +9687,7 @@ elfNN_aarch64_finish_dynamic_sections (bfd *output_bfd, case DT_TLSDESC_GOT: s = htab->root.sgot; + BFD_ASSERT (htab->dt_tlsdesc_got != (bfd_vma)-1); dyn.d_un.d_ptr = s->output_section->vma + s->output_offset + htab->dt_tlsdesc_got; break; @@ -9705,8 +9707,9 @@ elfNN_aarch64_finish_dynamic_sections (bfd *output_bfd, this_hdr.sh_entsize = htab->plt_entry_size; - if (htab->tlsdesc_plt) + if (htab->tlsdesc_plt && !(info->flags & DF_BIND_NOW)) { + BFD_ASSERT (htab->dt_tlsdesc_got != (bfd_vma)-1); bfd_put_NN (output_bfd, (bfd_vma) 0, htab->root.sgot->contents + htab->dt_tlsdesc_got); diff --git a/ld/ChangeLog b/ld/ChangeLog index 4abb467e59b..e63f2be1789 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,9 @@ +2019-04-11 Tamar Christina + + PR ld/24302 + * testsuite/ld-aarch64/aarch64-elf.exp: Add new test. + * testsuite/ld-aarch64/tls-relax-gdesc-le-now.d: New test. + 2019-04-10 H.J. Lu * scripttempl/elf.sc (CREATE_PIC): New. Set for CREATE_SHLIB or diff --git a/ld/testsuite/ld-aarch64/aarch64-elf.exp b/ld/testsuite/ld-aarch64/aarch64-elf.exp index ba3ce36191f..e69aedd0d4d 100644 --- a/ld/testsuite/ld-aarch64/aarch64-elf.exp +++ b/ld/testsuite/ld-aarch64/aarch64-elf.exp @@ -256,6 +256,7 @@ run_dump_test "tls-relax-all-ilp32" run_dump_test "tls-relax-gd-le" run_dump_test "tls-relax-gd-le-ilp32" run_dump_test "tls-relax-gdesc-le" +run_dump_test "tls-relax-gdesc-le-now" run_dump_test "tls-relax-gdesc-le-ilp32" run_dump_test "tls-relax-gd-ie" run_dump_test "tls-relax-gd-ie-ilp32" diff --git a/ld/testsuite/ld-aarch64/tls-relax-gdesc-le-now.d b/ld/testsuite/ld-aarch64/tls-relax-gdesc-le-now.d new file mode 100644 index 00000000000..f1565e9c11f --- /dev/null +++ b/ld/testsuite/ld-aarch64/tls-relax-gdesc-le-now.d @@ -0,0 +1,19 @@ +#source: tls-relax-gdesc-le.s +#ld: -shared -z now +#readelf: -dr +#... + 0x.+ \(STRTAB\) \s+0x.+ + 0x.+ \(SYMTAB\) \s+0x.+ + 0x.+ \(STRSZ\) \s+.+ \(bytes\) + 0x.+ \(SYMENT\) \s+.+ \(bytes\) + 0x.+ \(PLTGOT\) \s+0x.+ + 0x.+ \(PLTRELSZ\) \s+.+ \(bytes\) + 0x.+ \(PLTREL\) \s+RELA + 0x.+ \(JMPREL\) \s+0x.+ + 0x.+ \(BIND_NOW\) \s+ + 0x.+ \(FLAGS_1\) \s+ Flags: NOW + 0x.+ \(NULL\) \s+ 0x0 + +Relocation section '\.rela\.plt' at offset .+ contains 1 entry: + Offset Info Type Sym\. Value Sym\. Name \+ Addend +.+ .+ R_AARCH64_TLSDESC 0 -- 2.30.2