forked from OSchip/llvm-project
Fix accounting of tbss.
We were correctly computing the size contribution of a .tbss input section (it is none), but we were incorrectly considering the alignment of the output section: it was advancing Dot instead of ThreadBssOffset. As far as I can tell this was always wrong in our linkerscript implementation, but that became more visible now that the code is shared with the non linker script case. llvm-svn: 302107
This commit is contained in:
parent
ae1dd58e05
commit
7c4eafa3ee
|
@ -495,17 +495,22 @@ void LinkerScript::addOrphanSections(OutputSectionFactory &Factory) {
|
|||
}
|
||||
}
|
||||
|
||||
static bool isTbss(OutputSection *Sec) {
|
||||
return (Sec->Flags & SHF_TLS) && Sec->Type == SHT_NOBITS;
|
||||
uint64_t LinkerScript::advance(uint64_t Size, unsigned Align) {
|
||||
bool IsTbss = (CurOutSec->Flags & SHF_TLS) && CurOutSec->Type == SHT_NOBITS;
|
||||
uint64_t Start = IsTbss ? Dot + ThreadBssOffset : Dot;
|
||||
Start = alignTo(Start, Align);
|
||||
uint64_t End = Start + Size;
|
||||
|
||||
if (IsTbss)
|
||||
ThreadBssOffset = End - Dot;
|
||||
else
|
||||
Dot = End;
|
||||
return End;
|
||||
}
|
||||
|
||||
void LinkerScript::output(InputSection *S) {
|
||||
bool IsTbss = isTbss(CurOutSec);
|
||||
|
||||
uint64_t Pos = IsTbss ? Dot + ThreadBssOffset : Dot;
|
||||
Pos = alignTo(Pos, S->Alignment);
|
||||
S->OutSecOff = Pos - CurOutSec->Addr;
|
||||
Pos += S->getSize();
|
||||
uint64_t Pos = advance(S->getSize(), S->Alignment);
|
||||
S->OutSecOff = Pos - S->getSize() - CurOutSec->Addr;
|
||||
|
||||
// Update output section size after adding each section. This is so that
|
||||
// SIZEOF works correctly in the case below:
|
||||
|
@ -524,11 +529,6 @@ void LinkerScript::output(InputSection *S) {
|
|||
" bytes");
|
||||
}
|
||||
}
|
||||
|
||||
if (IsTbss)
|
||||
ThreadBssOffset = Pos - Dot;
|
||||
else
|
||||
Dot = Pos;
|
||||
}
|
||||
|
||||
void LinkerScript::switchTo(OutputSection *Sec) {
|
||||
|
@ -536,9 +536,7 @@ void LinkerScript::switchTo(OutputSection *Sec) {
|
|||
return;
|
||||
|
||||
CurOutSec = Sec;
|
||||
|
||||
Dot = alignTo(Dot, CurOutSec->Alignment);
|
||||
CurOutSec->Addr = isTbss(CurOutSec) ? Dot + ThreadBssOffset : Dot;
|
||||
CurOutSec->Addr = advance(0, CurOutSec->Alignment);
|
||||
|
||||
// If neither AT nor AT> is specified for an allocatable section, the linker
|
||||
// will set the LMA such that the difference between VMA and LMA for the
|
||||
|
|
|
@ -228,6 +228,7 @@ protected:
|
|||
MemoryRegion *findMemoryRegion(OutputSectionCommand *Cmd);
|
||||
|
||||
void switchTo(OutputSection *Sec);
|
||||
uint64_t advance(uint64_t Size, unsigned Align);
|
||||
void output(InputSection *Sec);
|
||||
void process(BaseCommand &Base);
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
// RUN: .tbss : { *(.tbss) } \
|
||||
// RUN: .data.rel.ro : { *(.data.rel.ro) } \
|
||||
// RUN: }" > %t.script
|
||||
// RUN: ld.lld -T %t.script %t -o %tout2
|
||||
// RUN: ld.lld -T %t.script %t -o %tout2
|
||||
// RUN: echo SCRIPT
|
||||
// RUN: llvm-readobj -s %tout2 | FileCheck %s
|
||||
.global _start
|
||||
|
@ -61,6 +61,6 @@ _start:
|
|||
// CHECK-NEXT: SHF_ALLOC
|
||||
// CHECK-NEXT: SHF_WRITE
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: Address: 0x202010
|
||||
// CHECK-NEXT: Offset: 0x2010
|
||||
// CHECK-NEXT: Address: 0x202004
|
||||
// CHECK-NEXT: Offset: 0x2004
|
||||
// CHECK-NEXT: Size: 4
|
||||
|
|
Loading…
Reference in New Issue