summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2017-05-04 03:00:27 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2017-05-04 03:00:27 +0000
commit7c4eafa3ee6d28d6755f6af18f5e91c22ede87c7 (patch)
treea08e9f50848d6f152d754d61387963c1fa1417ec
parentae1dd58e054e44230ecf3f9eb3ab2363ecf1926c (diff)
downloadbcm5719-llvm-7c4eafa3ee6d28d6755f6af18f5e91c22ede87c7.tar.gz
bcm5719-llvm-7c4eafa3ee6d28d6755f6af18f5e91c22ede87c7.zip
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
-rw-r--r--lld/ELF/LinkerScript.cpp30
-rw-r--r--lld/ELF/LinkerScript.h1
-rw-r--r--lld/test/ELF/tls-offset.s6
3 files changed, 18 insertions, 19 deletions
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index 3f872c65897..35b88254304 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -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
diff --git a/lld/ELF/LinkerScript.h b/lld/ELF/LinkerScript.h
index dd96d335a66..b4ca6535891 100644
--- a/lld/ELF/LinkerScript.h
+++ b/lld/ELF/LinkerScript.h
@@ -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);
diff --git a/lld/test/ELF/tls-offset.s b/lld/test/ELF/tls-offset.s
index 062def4e14f..75d9af7f5b7 100644
--- a/lld/test/ELF/tls-offset.s
+++ b/lld/test/ELF/tls-offset.s
@@ -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
OpenPOWER on IntegriCloud