Index: ELF/LinkerScript.h =================================================================== --- ELF/LinkerScript.h +++ ELF/LinkerScript.h @@ -209,7 +209,7 @@ bool hasLMA(StringRef Name); bool shouldKeep(InputSectionBase *S); void assignOffsets(OutputSectionCommand *Cmd); - void assignAddresses(std::vector> &Phdrs); + void assignAddresses(std::vector> *Phdrs); bool hasPhdrsCommands(); uint64_t getOutputSectionAddress(StringRef Name) override; uint64_t getOutputSectionSize(StringRef Name) override; Index: ELF/LinkerScript.cpp =================================================================== --- ELF/LinkerScript.cpp +++ ELF/LinkerScript.cpp @@ -567,7 +567,7 @@ } template -void LinkerScript::assignAddresses(std::vector> &Phdrs) { +void LinkerScript::assignAddresses(std::vector> *Phdrs) { // Orphan sections are sections present in the input files which // are not explicitly placed into the output file by the linker script. // We place orphan sections at end of file. @@ -633,6 +633,9 @@ assignOffsets(Cmd); } + if (Config->Relocatable) + return; + uintX_t MinVA = std::numeric_limits::max(); for (OutputSectionBase *Sec : *OutputSections) { if (Sec->getFlags() & SHF_ALLOC) @@ -643,10 +646,10 @@ uintX_t HeaderSize = getHeaderSize(); auto FirstPTLoad = - std::find_if(Phdrs.begin(), Phdrs.end(), [](const PhdrEntry &E) { + std::find_if(Phdrs->begin(), Phdrs->end(), [](const PhdrEntry &E) { return E.H.p_type == PT_LOAD; }); - if (HeaderSize <= MinVA && FirstPTLoad != Phdrs.end()) { + if (HeaderSize <= MinVA && FirstPTLoad != Phdrs->end()) { // ELF and Program headers need to be right before the first section in // memory. Set their addresses accordingly. MinVA = alignDown(MinVA - HeaderSize, Target->PageSize); Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -270,13 +270,17 @@ return; if (Config->Relocatable) { + if (ScriptConfig->HasSections) + Script::X->assignAddresses(nullptr); assignFileOffsets(); + for (OutputSectionBase *Sec : OutputSections) + Sec->setVA(0); } else { Phdrs = Script::X->hasPhdrsCommands() ? Script::X->createPhdrs() : createPhdrs(); fixHeaders(); if (ScriptConfig->HasSections) { - Script::X->assignAddresses(Phdrs); + Script::X->assignAddresses(&Phdrs); } else { fixSectionAlignments(); assignAddresses(); Index: test/ELF/linkerscript/relocatable.s =================================================================== --- test/ELF/linkerscript/relocatable.s +++ test/ELF/linkerscript/relocatable.s @@ -0,0 +1,34 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t + +# RUN: echo "SECTIONS { foo : { *(.foo*) } }" > %t.script +# RUN: ld.lld -r -o %t.out --script %t.script %t +# RUN: llvm-objdump -section-headers %t.out | FileCheck %s + +# CHECK: Sections: +# CHECK-NEXT: Idx Name Size Address Type +# CHECK-NEXT: 0 00000000 0000000000000000 +# CHECK-NEXT: 1 foo 00000008 0000000000000000 DATA +# CHECK-NEXT: 2 .text 00000001 0000000000000000 TEXT DATA +# CHECK-NEXT: 3 .bar1 00000004 0000000000000000 DATA +# CHECK-NEXT: 4 .bar2 00000004 0000000000000000 DATA + +.global _start +_start: + nop + +.section .foo1, "a" +foo1: + .long 1 + +.section .foo2, "a" +foo2: + .long 1 + +.section .bar1, "aw" +bar1: + .long 1 + +.section .bar2, "aw" +bar2: + .long 1