forked from OSchip/llvm-project
Round up the memsize of PT_TLS.
This is cleaner than computing relocations as if we had done it. While at it, keep a single Phdr variable instead of multiple fields of it. llvm-svn: 252352
This commit is contained in:
parent
8121b3f684
commit
ea7a1e9092
|
@ -660,7 +660,7 @@ typename ELFFile<ELFT>::uintX_t lld::elf2::getSymVA(const SymbolBody &S) {
|
|||
InputSectionBase<ELFT> &SC = DR.Section;
|
||||
if (DR.Sym.getType() == STT_TLS)
|
||||
return SC.OutSec->getVA() + SC.getOffset(DR.Sym) -
|
||||
Out<ELFT>::TlsInitImageVA;
|
||||
Out<ELFT>::TlsPhdr->p_vaddr;
|
||||
return SC.OutSec->getVA() + SC.getOffset(DR.Sym);
|
||||
}
|
||||
case SymbolBody::DefinedCommonKind:
|
||||
|
|
|
@ -352,6 +352,7 @@ private:
|
|||
// until Writer is initialized.
|
||||
template <class ELFT> struct Out {
|
||||
typedef typename llvm::object::ELFFile<ELFT>::uintX_t uintX_t;
|
||||
typedef typename llvm::object::ELFFile<ELFT>::Elf_Phdr Elf_Phdr;
|
||||
static DynamicSection<ELFT> *Dynamic;
|
||||
static GnuHashTableSection<ELFT> *GnuHashTab;
|
||||
static GotPltSection<ELFT> *GotPlt;
|
||||
|
@ -369,8 +370,7 @@ template <class ELFT> struct Out {
|
|||
static StringTableSection<ELFT> *StrTab;
|
||||
static SymbolTableSection<ELFT> *DynSymTab;
|
||||
static SymbolTableSection<ELFT> *SymTab;
|
||||
static uintX_t TlsInitImageVA;
|
||||
static size_t TlsInitImageAlignedSize;
|
||||
static Elf_Phdr *TlsPhdr;
|
||||
};
|
||||
|
||||
template <class ELFT> DynamicSection<ELFT> *Out<ELFT>::Dynamic;
|
||||
|
@ -390,8 +390,7 @@ template <class ELFT> StringTableSection<ELFT> *Out<ELFT>::ShStrTab;
|
|||
template <class ELFT> StringTableSection<ELFT> *Out<ELFT>::StrTab;
|
||||
template <class ELFT> SymbolTableSection<ELFT> *Out<ELFT>::DynSymTab;
|
||||
template <class ELFT> SymbolTableSection<ELFT> *Out<ELFT>::SymTab;
|
||||
template <class ELFT> typename Out<ELFT>::uintX_t Out<ELFT>::TlsInitImageVA;
|
||||
template <class ELFT> size_t Out<ELFT>::TlsInitImageAlignedSize;
|
||||
template <class ELFT> typename Out<ELFT>::Elf_Phdr *Out<ELFT>::TlsPhdr;
|
||||
|
||||
} // namespace elf2
|
||||
} // namespace lld
|
||||
|
|
|
@ -351,7 +351,7 @@ void X86_64TargetInfo::relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type,
|
|||
write32le(Loc, SA);
|
||||
break;
|
||||
case R_X86_64_TPOFF32: {
|
||||
uint64_t Val = SA - Out<ELF64LE>::TlsInitImageAlignedSize;
|
||||
uint64_t Val = SA - Out<ELF64LE>::TlsPhdr->p_memsz;
|
||||
if (!isInt<32>(Val))
|
||||
error("R_X86_64_TPOFF32 out of range");
|
||||
write32le(Loc, Val);
|
||||
|
|
|
@ -715,10 +715,8 @@ template <class ELFT> void Writer<ELFT>::assignAddresses() {
|
|||
}
|
||||
|
||||
if (Sec->getFlags() & SHF_TLS) {
|
||||
if (!TlsPhdr.p_vaddr) {
|
||||
if (!TlsPhdr.p_vaddr)
|
||||
setPhdr(&TlsPhdr, PT_TLS, PF_R, FileOff, VA, 0, Sec->getAlign());
|
||||
Out<ELFT>::TlsInitImageVA = VA;
|
||||
}
|
||||
if (Sec->getType() != SHT_NOBITS)
|
||||
VA = RoundUpToAlignment(VA, Sec->getAlign());
|
||||
uintX_t TVA = RoundUpToAlignment(VA + ThreadBSSOffset, Sec->getAlign());
|
||||
|
@ -750,9 +748,11 @@ template <class ELFT> void Writer<ELFT>::assignAddresses() {
|
|||
}
|
||||
|
||||
if (TlsPhdr.p_vaddr) {
|
||||
// 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.
|
||||
TlsPhdr.p_memsz = RoundUpToAlignment(TlsPhdr.p_memsz, TlsPhdr.p_align);
|
||||
Phdrs[++PhdrIdx] = TlsPhdr;
|
||||
Out<ELFT>::TlsInitImageAlignedSize =
|
||||
RoundUpToAlignment(TlsPhdr.p_memsz, TlsPhdr.p_align);
|
||||
Out<ELFT>::TlsPhdr = &Phdrs[PhdrIdx];
|
||||
}
|
||||
|
||||
// Add an entry for .dynamic.
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
// REQUIRES: x86
|
||||
// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
|
||||
// RUN: ld.lld2 %t -o %tout -shared
|
||||
// RUN: llvm-readobj -program-headers %tout | FileCheck %s
|
||||
|
||||
.section .tbss,"awT",@nobits
|
||||
.align 8
|
||||
.long 0
|
||||
|
||||
// CHECK: ProgramHeader {
|
||||
// CHECK: Type: PT_TLS
|
||||
// CHECK-NEXT: Offset:
|
||||
// CHECK-NEXT: VirtualAddress:
|
||||
// CHECK-NEXT: PhysicalAddress:
|
||||
// CHECK-NEXT: FileSize: 0
|
||||
// CHECK-NEXT: MemSize: 8
|
||||
// CHECK-NEXT: Flags [
|
||||
// CHECK-NEXT: PF_R (0x4)
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: Alignment: 8
|
||||
// CHECK-NEXT: }
|
Loading…
Reference in New Issue