Don't include NOBITS TLS in PT_LOAD.
They don't count for the memory or file size, so this is mostly just a simplification. The only noticeable difference should be fewer empty program headers. llvm-svn: 260465
This commit is contained in:
parent
82f68a88b5
commit
ef762f2639
|
@ -1184,8 +1184,16 @@ void Writer<ELFT>::addStartStopSymbols(OutputSectionBase<ELFT> *Sec) {
|
||||||
Symtab.addSynthetic(Stop, *Sec, Sec->getSize());
|
Symtab.addSynthetic(Stop, *Sec, Sec->getSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT> static bool needsPhdr(OutputSectionBase<ELFT> *Sec) {
|
template <class ELFT> static bool needsPtLoad(OutputSectionBase<ELFT> *Sec) {
|
||||||
return Sec->getFlags() & SHF_ALLOC;
|
if (!(Sec->getFlags() & SHF_ALLOC))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
if (Sec->getFlags() & SHF_TLS && Sec->getType() == SHT_NOBITS)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t toPhdrFlags(uint64_t Flags) {
|
static uint32_t toPhdrFlags(uint64_t Flags) {
|
||||||
|
@ -1241,9 +1249,18 @@ template <class ELFT> void Writer<ELFT>::createPhdrs() {
|
||||||
Phdr TlsHdr(PT_TLS, PF_R);
|
Phdr TlsHdr(PT_TLS, PF_R);
|
||||||
Phdr RelRo(PT_GNU_RELRO, PF_R);
|
Phdr RelRo(PT_GNU_RELRO, PF_R);
|
||||||
for (OutputSectionBase<ELFT> *Sec : OutputSections) {
|
for (OutputSectionBase<ELFT> *Sec : OutputSections) {
|
||||||
if (!needsPhdr<ELFT>(Sec))
|
if (!(Sec->getFlags() & SHF_ALLOC))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// If we meet TLS section then we create TLS header
|
||||||
|
// and put all TLS sections inside for futher use when
|
||||||
|
// assign addresses.
|
||||||
|
if (Sec->getFlags() & SHF_TLS)
|
||||||
|
AddSec(TlsHdr, Sec);
|
||||||
|
|
||||||
|
if (!needsPtLoad<ELFT>(Sec))
|
||||||
|
continue;
|
||||||
|
|
||||||
// If flags changed then we want new load segment.
|
// If flags changed then we want new load segment.
|
||||||
uintX_t NewFlags = toPhdrFlags(Sec->getFlags());
|
uintX_t NewFlags = toPhdrFlags(Sec->getFlags());
|
||||||
if (Flags != NewFlags) {
|
if (Flags != NewFlags) {
|
||||||
|
@ -1252,14 +1269,6 @@ template <class ELFT> void Writer<ELFT>::createPhdrs() {
|
||||||
Load = AddHdr(LoadType, NewFlags);
|
Load = AddHdr(LoadType, NewFlags);
|
||||||
Flags = NewFlags;
|
Flags = NewFlags;
|
||||||
}
|
}
|
||||||
// If we meet TLS section then we create TLS header
|
|
||||||
// and put all TLS sections inside for futher use when
|
|
||||||
// assign addresses.
|
|
||||||
if (Sec->getFlags() & SHF_TLS) {
|
|
||||||
AddSec(TlsHdr, Sec);
|
|
||||||
if (Sec->getType() == SHT_NOBITS)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
AddSec(*Load, Sec);
|
AddSec(*Load, Sec);
|
||||||
|
|
||||||
|
@ -1307,18 +1316,15 @@ template <class ELFT> void Writer<ELFT>::assignAddresses() {
|
||||||
SmallPtrSet<OutputSectionBase<ELFT> *, 4> PageAlign;
|
SmallPtrSet<OutputSectionBase<ELFT> *, 4> PageAlign;
|
||||||
for (const Phdr &P : Phdrs) {
|
for (const Phdr &P : Phdrs) {
|
||||||
if (P.H.p_type == PT_GNU_RELRO) {
|
if (P.H.p_type == PT_GNU_RELRO) {
|
||||||
// Find the first section after PT_GNU_RELRO. If it is in a PT_LOAD
|
// Find the first section after PT_GNU_RELRO. If it is in a PT_LOAD we
|
||||||
// and is not tls, we have to align it to a page. We don't have to
|
// have to align it to a page.
|
||||||
// align tls since TLS NOBITS takes no space.
|
|
||||||
auto I = std::find(OutputSections.begin(), OutputSections.end(), P.Last);
|
auto I = std::find(OutputSections.begin(), OutputSections.end(), P.Last);
|
||||||
++I;
|
++I;
|
||||||
if (I != OutputSections.end() && needsPhdr(*I) &&
|
if (I != OutputSections.end() && needsPtLoad(*I))
|
||||||
!((*I)->getFlags() & SHF_TLS))
|
|
||||||
PageAlign.insert(*I);
|
PageAlign.insert(*I);
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: why create empty PT_LOAD?
|
if (P.H.p_type == PT_LOAD)
|
||||||
if (P.H.p_type == PT_LOAD && P.First)
|
|
||||||
PageAlign.insert(P.First);
|
PageAlign.insert(P.First);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1337,21 +1343,15 @@ template <class ELFT> void Writer<ELFT>::assignAddresses() {
|
||||||
FileOff += Sec->getSize();
|
FileOff += Sec->getSize();
|
||||||
|
|
||||||
// We only assign VAs to allocated sections.
|
// We only assign VAs to allocated sections.
|
||||||
if (needsPhdr<ELFT>(Sec)) {
|
if (needsPtLoad<ELFT>(Sec)) {
|
||||||
// Don't allocate VA space for TLS NOBITS sections. The PT_TLS PHDR is
|
VA = alignTo(VA, Align);
|
||||||
// responsible for allocating space for them, not the PT_LOAD that
|
Sec->setVA(VA);
|
||||||
// contains the TLS initialization image.
|
VA += Sec->getSize();
|
||||||
bool IsTls = Sec->getFlags() & SHF_TLS;
|
} else if (Sec->getFlags() & SHF_TLS && Sec->getType() == SHT_NOBITS) {
|
||||||
if (IsTls && Sec->getType() == SHT_NOBITS) {
|
uintX_t TVA = VA + ThreadBssOffset;
|
||||||
uintX_t TVA = VA + ThreadBssOffset;
|
TVA = alignTo(TVA, Align);
|
||||||
TVA = alignTo(TVA, Align);
|
Sec->setVA(TVA);
|
||||||
Sec->setVA(TVA);
|
ThreadBssOffset = TVA - VA + Sec->getSize();
|
||||||
ThreadBssOffset = TVA - VA + Sec->getSize();
|
|
||||||
} else {
|
|
||||||
VA = alignTo(VA, Align);
|
|
||||||
Sec->setVA(VA);
|
|
||||||
VA += Sec->getSize();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
// REQUIRES: x86
|
||||||
|
// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
|
||||||
|
// RUN: ld.lld %t -o %tout
|
||||||
|
// RUN: llvm-readobj -program-headers %tout | FileCheck %s
|
||||||
|
|
||||||
|
.global _start
|
||||||
|
_start:
|
||||||
|
retq
|
||||||
|
|
||||||
|
.section .tbss,"awT",@nobits
|
||||||
|
.zero 4
|
||||||
|
// FIXME: Test that we don't create unecessary empty PT_LOAD and PT_GNU_RELRO
|
||||||
|
// for the .tbss section.
|
||||||
|
|
||||||
|
// CHECK: ProgramHeaders [
|
||||||
|
// CHECK-NEXT: ProgramHeader {
|
||||||
|
// CHECK-NEXT: Type: PT_PHDR (0x6)
|
||||||
|
// CHECK-NEXT: Offset: 0x40
|
||||||
|
// CHECK-NEXT: VirtualAddress: 0x10040
|
||||||
|
// CHECK-NEXT: PhysicalAddress: 0x10040
|
||||||
|
// CHECK-NEXT: FileSize: 280
|
||||||
|
// CHECK-NEXT: MemSize: 280
|
||||||
|
// CHECK-NEXT: Flags [ (0x4)
|
||||||
|
// CHECK-NEXT: PF_R (0x4)
|
||||||
|
// CHECK-NEXT: ]
|
||||||
|
// CHECK-NEXT: Alignment: 8
|
||||||
|
// CHECK-NEXT: }
|
||||||
|
// CHECK-NEXT: ProgramHeader {
|
||||||
|
// CHECK-NEXT: Type: PT_LOAD (0x1)
|
||||||
|
// CHECK-NEXT: Offset: 0x0
|
||||||
|
// CHECK-NEXT: VirtualAddress: 0x10000
|
||||||
|
// CHECK-NEXT: PhysicalAddress: 0x10000
|
||||||
|
// CHECK-NEXT: FileSize: 344
|
||||||
|
// CHECK-NEXT: MemSize: 344
|
||||||
|
// CHECK-NEXT: Flags [ (0x4)
|
||||||
|
// CHECK-NEXT: PF_R (0x4)
|
||||||
|
// CHECK-NEXT: ]
|
||||||
|
// CHECK-NEXT: Alignment: 4096
|
||||||
|
// CHECK-NEXT: }
|
||||||
|
// CHECK-NEXT: ProgramHeader {
|
||||||
|
// CHECK-NEXT: Type: PT_LOAD (0x1)
|
||||||
|
// CHECK-NEXT: Offset: 0x1000
|
||||||
|
// CHECK-NEXT: VirtualAddress: 0x11000
|
||||||
|
// CHECK-NEXT: PhysicalAddress: 0x11000
|
||||||
|
// CHECK-NEXT: FileSize: 1
|
||||||
|
// CHECK-NEXT: MemSize: 1
|
||||||
|
// CHECK-NEXT: Flags [ (0x5)
|
||||||
|
// CHECK-NEXT: PF_R (0x4)
|
||||||
|
// CHECK-NEXT: PF_X (0x1)
|
||||||
|
// CHECK-NEXT: ]
|
||||||
|
// CHECK-NEXT: Alignment: 4096
|
||||||
|
// CHECK-NEXT: }
|
||||||
|
// CHECK-NEXT: ProgramHeader {
|
||||||
|
// CHECK-NEXT: Type: PT_TLS (0x7)
|
||||||
|
// CHECK-NEXT: Offset: 0x1001
|
||||||
|
// CHECK-NEXT: VirtualAddress: 0x11001
|
||||||
|
// CHECK-NEXT: PhysicalAddress: 0x11001
|
||||||
|
// CHECK-NEXT: FileSize: 0
|
||||||
|
// CHECK-NEXT: MemSize: 4
|
||||||
|
// CHECK-NEXT: Flags [ (0x4)
|
||||||
|
// CHECK-NEXT: PF_R (0x4)
|
||||||
|
// CHECK-NEXT: ]
|
||||||
|
// CHECK-NEXT: Alignment: 1
|
||||||
|
// CHECK-NEXT: }
|
||||||
|
// CHECK-NEXT: ProgramHeader {
|
||||||
|
// CHECK-NEXT: Type: PT_GNU_STACK (0x6474E551)
|
||||||
|
// CHECK-NEXT: Offset: 0x0
|
||||||
|
// CHECK-NEXT: VirtualAddress: 0x0
|
||||||
|
// CHECK-NEXT: PhysicalAddress: 0x0
|
||||||
|
// CHECK-NEXT: FileSize: 0
|
||||||
|
// CHECK-NEXT: MemSize: 0
|
||||||
|
// CHECK-NEXT: Flags [ (0x6)
|
||||||
|
// CHECK-NEXT: PF_R (0x4)
|
||||||
|
// CHECK-NEXT: PF_W (0x2)
|
||||||
|
// CHECK-NEXT: ]
|
||||||
|
// CHECK-NEXT: Alignment: 0
|
||||||
|
// CHECK-NEXT: }
|
||||||
|
// CHECK-NEXT: ]
|
Loading…
Reference in New Issue