diff options
| -rw-r--r-- | lld/ELF/LinkerScript.cpp | 23 | ||||
| -rw-r--r-- | lld/ELF/Writer.cpp | 2 | ||||
| -rw-r--r-- | lld/test/ELF/sectionstart-noallochdr.s | 23 |
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 |

