Index: ELF/LinkerScript.cpp =================================================================== --- ELF/LinkerScript.cpp +++ ELF/LinkerScript.cpp @@ -398,7 +398,7 @@ CurOutSec = Sec; Dot = alignTo(Dot, CurOutSec->getAlignment()); - CurOutSec->setVA(Dot); + CurOutSec->setVA(Config->Relocatable ? 0 : Dot); } template void LinkerScript::process(BaseCommand &Base) { @@ -551,6 +551,12 @@ assignOffsets(Cmd); } + if (Config->Relocatable) { + Out::ElfHeader->setVA(0); + Out::ProgramHeaders->setVA(Out::ElfHeader->getSize()); + return; + } + uintX_t MinVA = std::numeric_limits::max(); for (OutputSectionBase *Sec : *OutputSections) { if (Sec->getFlags() & SHF_ALLOC) Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -266,6 +266,8 @@ return; if (Config->Relocatable) { + if (ScriptConfig->HasSections) + Script::X->assignAddresses(); assignFileOffsets(); } else { Phdrs = Script::X->hasPhdrsCommands() ? Script::X->createPhdrs() 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 00000048 0000000000000000 DATA +# CHECK-NEXT: 2 .text 00000049 0000000000000000 TEXT DATA +# CHECK-NEXT: 3 .bar1 0000004d 0000000000000000 DATA +# CHECK-NEXT: 4 .bar2 00000051 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