Index: ELF/LinkerScript.cpp =================================================================== --- ELF/LinkerScript.cpp +++ ELF/LinkerScript.cpp @@ -406,15 +406,8 @@ } // Add input sections to an output section. - unsigned Pos = 0; - for (InputSectionBase *S : V) { - // The actual offset will be computed during - // assignAddresses. For now, use the index as a very crude - // approximation so that it is at least easy for other code to - // know the section order. - cast(S)->OutSecOff = Pos++; + for (InputSectionBase *S : V) Factory.addInputSec(S, Cmd->Name, Cmd->Sec); - } } } CurOutSec = nullptr; @@ -641,6 +634,11 @@ Dot = CurMemRegion->Offset; switchTo(Sec); + // We do not support custom layout for compressed debug sectons. + // At this point we already know their size and have compressed content. + if (CurOutSec->Flags & SHF_COMPRESSED) + return; + for (BaseCommand *C : Cmd->Commands) process(*C); } Index: ELF/OutputSections.cpp =================================================================== --- ELF/OutputSections.cpp +++ ELF/OutputSections.cpp @@ -139,12 +139,24 @@ this->Info = S->OutSec->SectionIndex; } +static uint64_t updateOffset(uint64_t Off, InputSection *S) { + Off = alignTo(Off, S->Alignment); + S->OutSecOff = Off; + return Off + S->getSize(); +} + void OutputSection::addSection(InputSection *S) { assert(S->Live); Sections.push_back(S); S->OutSec = this; this->updateAlignment(S->Alignment); + // The actual offsets will be computed by assignAddresses. For now, use + // crude approximation so that it is at least easy for other code to know the + // section order. It is also used to calculate the output section size early + // for compressed debug sections. + this->Size = updateOffset(Size, S); + // If this section contains a table of fixed-size entries, sh_entsize // holds the element size. Consequently, if this contains two or more // input sections, all of them must have the same sh_entsize. However, @@ -159,11 +171,8 @@ // and scan relocations to setup sections' offsets. void OutputSection::assignOffsets() { uint64_t Off = 0; - for (InputSection *S : Sections) { - Off = alignTo(Off, S->Alignment); - S->OutSecOff = Off; - Off += S->getSize(); - } + for (InputSection *S : Sections) + Off = updateOffset(Off, S); this->Size = Off; } Index: test/ELF/linkerscript/Inputs/compress-debug-sections.s =================================================================== --- test/ELF/linkerscript/Inputs/compress-debug-sections.s +++ test/ELF/linkerscript/Inputs/compress-debug-sections.s @@ -0,0 +1,3 @@ +.section .debug_str + .asciz "CCC" + .asciz "DDD" Index: test/ELF/linkerscript/compress-debug-sections.s =================================================================== --- test/ELF/linkerscript/compress-debug-sections.s +++ test/ELF/linkerscript/compress-debug-sections.s @@ -0,0 +1,36 @@ +# REQUIRES: x86, zlib + +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \ +# RUN: %S/Inputs/compress-debug-sections.s -o %t1.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t2.o + +## .debug_str section is mergeable. LLD would combine all of them into single +## mergeable synthetic section. We use -O0 here to disable merging, that +## allows to check that input sections has correctly assigned offsets. + +# RUN: echo "SECTIONS { }" > %t.script +# RUN: ld.lld -O0 %t1.o %t2.o %t.script -o %t1 --compress-debug-sections=zlib +# RUN: llvm-dwarfdump %t1 | FileCheck %s +# RUN: llvm-readobj -s %t1 | FileCheck %s --check-prefix=ZLIBFLAGS + +# RUN: echo "SECTIONS { .debug_str 0 : { *(.debug_str) } }" > %t2.script +# RUN: ld.lld -O0 %t1.o %t2.o %t2.script -o %t2 --compress-debug-sections=zlib +# RUN: llvm-dwarfdump %t2 | FileCheck %s +# RUN: llvm-readobj -s %t2 | FileCheck %s --check-prefix=ZLIBFLAGS + +# CHECK: .debug_str contents: +# CHECK-NEXT: CCC +# CHECK-NEXT: DDD +# CHECK-NEXT: AAA +# CHECK-NEXT: BBB + +# ZLIBFLAGS: Section { +# ZLIBFLAGS: Index: +# ZLIBFLAGS: Name: .debug_str +# ZLIBFLAGS-NEXT: Type: SHT_PROGBITS +# ZLIBFLAGS-NEXT: Flags [ +# ZLIBFLAGS-NEXT: SHF_COMPRESSED + +.section .debug_str + .asciz "AAA" + .asciz "BBB"