summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/ELF/LinkerScript.cpp23
-rw-r--r--lld/ELF/Writer.cpp2
-rw-r--r--lld/test/ELF/sectionstart-noallochdr.s23
3 files changed, 36 insertions, 12 deletions
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index 22a5b639469..3f872c65897 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -428,13 +428,12 @@ void LinkerScript::fabricateDefaultCommands(bool AllocateHeader) {
if (AllocateHeader)
StartAddr += elf::getHeaderSize();
- // The Sections with -T<section> are sorted in order of ascending address
- // we must use this if it is lower than StartAddr as calls to setDot() must
- // be monotonically increasing
- if (!Config->SectionStartMap.empty()) {
- uint64_t LowestSecStart = Config->SectionStartMap.begin()->second;
- StartAddr = std::min(StartAddr, LowestSecStart);
- }
+ // The Sections with -T<section> have been sorted in order of ascending
+ // address. We must lower StartAddr if the lowest -T<section address> as
+ // calls to setDot() must be monotonically increasing.
+ for (auto& KV : Config->SectionStartMap)
+ StartAddr = std::min(StartAddr, KV.second);
+
Commands.push_back(
make<SymbolAssignment>(".", [=] { return StartAddr; }, ""));
@@ -444,17 +443,19 @@ void LinkerScript::fabricateDefaultCommands(bool AllocateHeader) {
if (!(Sec->Flags & SHF_ALLOC))
continue;
+ auto *OSCmd = make<OutputSectionCommand>(Sec->Name);
+ OSCmd->Sec = Sec;
+
+ // Prefer user supplied address over additional alignment constraint
auto I = Config->SectionStartMap.find(Sec->Name);
if (I != Config->SectionStartMap.end())
Commands.push_back(
make<SymbolAssignment>(".", [=] { return I->second; }, ""));
-
- auto *OSCmd = make<OutputSectionCommand>(Sec->Name);
- OSCmd->Sec = Sec;
- if (Sec->PageAlign)
+ else if (Sec->PageAlign)
OSCmd->AddrExpr = [=] {
return alignTo(Script->getDot(), Config->MaxPageSize);
};
+
Commands.push_back(OSCmd);
if (Sec->Sections.size()) {
auto *ISD = make<InputSectionDescription>("");
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index e2ab48433a5..3de2596af27 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -252,7 +252,7 @@ template <class ELFT> void Writer<ELFT>::run() {
} else {
if (!Script->Opt.HasSections) {
fixSectionAlignments();
- Script->fabricateDefaultCommands(Config->MaxPageSize);
+ Script->fabricateDefaultCommands(AllocateHeader);
}
Script->synchronize();
Script->assignAddresses(Phdrs);
diff --git a/lld/test/ELF/sectionstart-noallochdr.s b/lld/test/ELF/sectionstart-noallochdr.s
new file mode 100644
index 00000000000..e9267a5372a
--- /dev/null
+++ b/lld/test/ELF/sectionstart-noallochdr.s
@@ -0,0 +1,23 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+# RUN: ld.lld %t.o --section-start .data=0x20 \
+# RUN: --section-start .bss=0x30 --section-start .text=0x10 -o %t1
+# RUN: llvm-objdump -section-headers %t1 | FileCheck %s
+
+# CHECK: Sections:
+# CHECK-NEXT: Idx Name Size Address Type
+# CHECK-NEXT: 0 00000000 0000000000000000
+# CHECK-NEXT: 1 .text 00000001 0000000000000010 TEXT DATA
+# CHECK-NEXT: 2 .data 00000004 0000000000000020 DATA
+# CHECK-NEXT: 3 .bss 00000004 0000000000000030 BSS
+
+.text
+.globl _start
+_start:
+ nop
+
+.data
+.long 0
+
+.bss
+.zero 4
OpenPOWER on IntegriCloud