Index: ELF/Symbols.cpp =================================================================== --- ELF/Symbols.cpp +++ ELF/Symbols.cpp @@ -94,7 +94,7 @@ if (!Out::TlsPhdr) fatal(toString(D.File) + " has an STT_TLS symbol but doesn't have an SHF_TLS section"); - return VA - Out::TlsPhdr->p_vaddr; + return VA - Out::TlsPhdr->FirstSec->Addr; } return VA; } Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -1650,6 +1650,12 @@ Phdrs = Script->hasPhdrsCommands() ? Script->createPhdrs() : createPhdrs(); addPtArmExid(Phdrs); Out::ProgramHeaders->Size = sizeof(Elf_Phdr) * Phdrs.size(); + + for (PhdrEntry *P : Phdrs) + if (P->p_type == PT_TLS && P->FirstSec) { + Out::TlsPhdr = P; + break; + } } // Some symbols are defined in term of program headers. Now that we @@ -2089,11 +2095,8 @@ // The TLS pointer goes after PT_TLS. At least glibc will align it, // so round up the size to make sure the offsets are correct. - if (P->p_type == PT_TLS) { - Out::TlsPhdr = P; - if (P->p_memsz) - P->p_memsz = alignTo(P->p_memsz, P->p_align); - } + if (P->p_type == PT_TLS && P->p_memsz) + P->p_memsz = alignTo(P->p_memsz, P->p_align); } } Index: test/ELF/pack-dyn-relocs-tls-aarch64.s =================================================================== --- /dev/null +++ test/ELF/pack-dyn-relocs-tls-aarch64.s @@ -0,0 +1,34 @@ +// REQUIRES: aarch64 + +// RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-linux %s -o %t.o +// RUN: ld.lld -shared --pack-dyn-relocs=android %t.o -o %t.so +// RUN: llvm-readobj -relocations %t.so | FileCheck %s + +// Bug 37841: Symbol::getVA must work on TLS symbols during the layout loop in +// finalizeSections. + + .global foo +foo: + adrp x0, :tlsdesc:tlsvar1 + ldr x1, [x0, :tlsdesc_lo12:tlsvar1] + add x0, x0, :tlsdesc_lo12:tlsvar1 + .tlsdesccall tlsvar1 + +// Also test an atypical IE access from a shared object to a local TLS symbol. + + .global bar +bar: + adrp x0, :gottprel:tlsvar2 + ldr x0, [x0, #:gottprel_lo12:tlsvar2] + + .section .tdata,"awT",@progbits + .space 0x1234 +tlsvar1: + .word 42 +tlsvar2: + .word 17 + +// CHECK: Section ({{.+}}) .rela.dyn { +// CHECK-NEXT: R_AARCH64_TLSDESC - 0x1234 +// CHECK-NEXT: R_AARCH64_TLS_TPREL64 - 0x1238 +// CHECK-NEXT: } Index: test/ELF/pack-dyn-relocs-tls-x86-64.s =================================================================== --- /dev/null +++ test/ELF/pack-dyn-relocs-tls-x86-64.s @@ -0,0 +1,23 @@ +// REQUIRES: x86 + +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +// RUN: ld.lld -shared --pack-dyn-relocs=android %t.o -o %t.so +// RUN: llvm-readobj -relocations %t.so | FileCheck %s + +// Bug 37841: Symbol::getVA must work on TLS symbols during the layout loop in +// finalizeSections. This test uses an atypical IE access in a shared object to +// access a local TLS symbol, because a more typical access would avoid the +// bug. + + .globl foo +foo: + movq tlsvar@GOTTPOFF(%rip), %rcx + + .section .tdata,"awT",@progbits + .space 0x1234 +tlsvar: + .word 42 + +// CHECK: Section ({{.+}}) .rela.dyn { +// CHECK-NEXT: R_X86_64_TPOFF64 - 0x1234 +// CHECK-NEXT: }