[ELF] - Linkerscript: support combination of linkerscript and --compress-debug-sections.

Previously it was impossible to use linkerscript with --compress-debug-sections 
because of assert failture:
Assertion failed: isFinalized(), file C:\llvm\lib\MC\StringTableBuilder.cpp, line 64

Patch fixes the issue

llvm-svn: 302413
This commit is contained in:
George Rimar 2017-05-08 10:18:12 +00:00
parent 810c6257f1
commit d86a4e505b
4 changed files with 59 additions and 13 deletions

View File

@ -406,15 +406,8 @@ void LinkerScript::processCommands(OutputSectionFactory &Factory) {
}
// 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<InputSection>(S)->OutSecOff = Pos++;
for (InputSectionBase *S : V)
Factory.addInputSec(S, Cmd->Name, Cmd->Sec);
}
if (OutputSection *Sec = Cmd->Sec) {
assert(Sec->SectionIndex == INT_MAX);
Sec->SectionIndex = I;
@ -648,6 +641,11 @@ void LinkerScript::assignOffsets(OutputSectionCommand *Cmd) {
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);
}

View File

@ -140,12 +140,24 @@ template <class ELFT> void OutputSection::finalize() {
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,
@ -160,11 +172,8 @@ void OutputSection::addSection(InputSection *S) {
// 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;
}

View File

@ -0,0 +1,3 @@
.section .debug_str
.asciz "CCC"
.asciz "DDD"

View File

@ -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"