[lld] r251872 - [elf2] Generate PT_TLS.
Michael J. Spencer via llvm-commits
llvm-commits at lists.llvm.org
Mon Nov 2 16:34:39 PST 2015
Author: mspencer
Date: Mon Nov 2 18:34:39 2015
New Revision: 251872
URL: http://llvm.org/viewvc/llvm-project?rev=251872&view=rev
Log:
[elf2] Generate PT_TLS.
Differential Revision: http://reviews.llvm.org/D14167
Modified:
lld/trunk/ELF/Writer.cpp
lld/trunk/test/elf2/tls.s
Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=251872&r1=251871&r2=251872&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Mon Nov 2 18:34:39 2015
@@ -644,15 +644,6 @@ static uint32_t toPhdrFlags(uint64_t Fla
return Ret;
}
-template <class ELFT>
-static bool consumesVirtualAddressSpace(OutputSectionBase<ELFT> *Sec) {
- return (Sec->getFlags() & SHF_ALLOC) &&
- // Don't allocate VA space for TLS NOBITS sections. The PT_TLS PHDR is
- // responsible for allocating space for them, not the PT_LOAD that
- // contains the TLS initialization image.
- !((Sec->getFlags() & SHF_TLS) && Sec->getType() == SHT_NOBITS);
-}
-
// Visits all sections to create PHDRs and to assign incremental,
// non-overlapping addresses to output sections.
template <class ELFT> void Writer<ELFT>::assignAddresses() {
@@ -679,6 +670,9 @@ template <class ELFT> void Writer<ELFT>:
setPhdr(&Phdrs[++PhdrIdx], PT_LOAD, PF_R, 0, getVAStart(), FileOff,
Target->getPageSize());
+ Elf_Phdr TlsPhdr;
+ std::memset(&TlsPhdr, 0, sizeof(Elf_Phdr));
+ uintX_t ThreadBSSOffset = 0;
// Create phdrs as we assign VAs and file offsets to all output sections.
SmallPtrSet<Elf_Phdr *, 8> Closed;
for (OutputSectionBase<ELFT> *Sec : OutputSections) {
@@ -701,17 +695,38 @@ template <class ELFT> void Writer<ELFT>:
}
}
- if (consumesVirtualAddressSpace<ELFT>(Sec)) {
+ if (Sec->getSize() && (Sec->getFlags() & SHF_ALLOC) &&
+ (Sec->getFlags() & SHF_TLS)) {
+ if (!TlsPhdr.p_vaddr) {
+ setPhdr(&TlsPhdr, PT_TLS, PF_R, FileOff, VA, 0, Sec->getAlign());
+ }
+ if (Sec->getType() != SHT_NOBITS)
+ VA = RoundUpToAlignment(VA, Sec->getAlign());
+ uintX_t TVA = RoundUpToAlignment(VA + ThreadBSSOffset, Sec->getAlign());
+ Sec->setVA(TVA);
+ TlsPhdr.p_memsz += Sec->getSize();
+ if (Sec->getType() == SHT_NOBITS)
+ ThreadBSSOffset = TVA - VA + Sec->getSize();
+ else {
+ TlsPhdr.p_filesz += Sec->getSize();
+ VA += Sec->getSize();
+ }
+ TlsPhdr.p_align = std::max<uintX_t>(TlsPhdr.p_align, Sec->getAlign());
+ } else if (Sec->getFlags() & SHF_ALLOC) {
VA = RoundUpToAlignment(VA, Sec->getAlign());
Sec->setVA(VA);
VA += Sec->getSize();
}
+
FileOff = RoundUpToAlignment(FileOff, Sec->getAlign());
Sec->setFileOffset(FileOff);
if (Sec->getType() != SHT_NOBITS)
FileOff += Sec->getSize();
}
+ if (TlsPhdr.p_vaddr)
+ Phdrs[++PhdrIdx] = TlsPhdr;
+
// Add an entry for .dynamic.
if (isOutputDynamic()) {
Elf_Phdr *PH = &Phdrs[++PhdrIdx];
@@ -732,6 +747,7 @@ template <class ELFT> void Writer<ELFT>:
// Returns the number of PHDR entries.
template <class ELFT> int Writer<ELFT>::getPhdrsNum() const {
+ bool Tls = false;
int I = 2; // 2 for PT_PHDR and the first PT_LOAD
if (needsInterpSection())
++I;
@@ -741,12 +757,16 @@ template <class ELFT> int Writer<ELFT>::
for (OutputSectionBase<ELFT> *Sec : OutputSections) {
if (!Sec->getSize() || !needsPhdr<ELFT>(Sec))
continue;
+ if (Sec->getFlags() & SHF_TLS)
+ Tls = true;
uintX_t Flags = toPhdrFlags(Sec->getFlags());
if (Last != Flags) {
Last = Flags;
++I;
}
}
+ if (Tls)
+ ++I;
return I;
}
Modified: lld/trunk/test/elf2/tls.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/tls.s?rev=251872&r1=251871&r2=251872&view=diff
==============================================================================
--- lld/trunk/test/elf2/tls.s (original)
+++ lld/trunk/test/elf2/tls.s Mon Nov 2 18:34:39 2015
@@ -25,7 +25,7 @@ _start:
// CHECK-NEXT: SHF_TLS
// CHECK-NEXT: SHF_WRITE
// CHECK-NEXT: ]
-// CHECK-NEXT: Address:
+// CHECK-NEXT: Address: [[TDATA_ADDR:0x.*]]
// CHECK-NEXT: Offset:
// CHECK-NEXT: Size: 4
// CHECK-NEXT: Link:
@@ -59,7 +59,7 @@ _start:
// CHECK-NEXT: SHF_TLS
// CHECK-NEXT: SHF_WRITE
// CHECK-NEXT: ]
-// CHECK-NEXT: Address:
+// CHECK-NEXT: Address: [[TBSS_ADDR:0x.*]]
// CHECK-NEXT: Offset:
// CHECK-NEXT: Size: 4
// CHECK-NEXT: Link:
@@ -76,9 +76,26 @@ _start:
// CHECK-NEXT: SHF_TLS
// CHECK-NEXT: SHF_WRITE
// CHECK-NEXT: ]
-// CHECK-NEXT: Address:
+
+// 0x1100C = TBSS_ADDR + 4
+
+// CHECK-NEXT: Address: 0x1100C
// CHECK-NEXT: Offset:
// CHECK-NEXT: Size: 4
+// CHECK-NEXT: Link:
+// CHECK-NEXT: Info:
+// CHECK-NEXT: AddressAlignment:
+// CHECK-NEXT: EntrySize:
+// CHECK-NEXT: }
+// CHECK-NEXT: Section {
+// CHECK-NEXT: Index:
+// CHECK-NEXT: Name:
+// CHECK-NEXT: Type:
+// CHECK-NEXT: Flags [
+// CHECK-NEXT: SHF_ALLOC
+// CHECK-NEXT: SHF_WRITE
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address: [[TBSS_ADDR]]
// Check that the TLS NOBITS sections weren't added to the R/W PT_LOAD's size.
@@ -91,3 +108,14 @@ _start:
// CHECK-NEXT: PF_R
// CHECK-NEXT: PF_W
// CHECK-NEXT: ]
+// CHECK: Type: PT_TLS
+// CHECK-NEXT: Offset:
+// CHECK-NEXT: VirtualAddress: [[TDATA_ADDR]]
+// CHECK-NEXT: PhysicalAddress: [[TDATA_ADDR]]
+// CHECK-NEXT: FileSize: 8
+// CHECK-NEXT: MemSize: 16
+// CHECK-NEXT: Flags [
+// CHECK-NEXT: PF_R
+// CHECK-NEXT: ]
+// CHECK-NEXT: Alignment:
+// CHECK-NEXT: }
More information about the llvm-commits
mailing list