Skip to content

Commit 4231940

Browse files
committed
[ELF] --orphan-handling=: don't warn/error for unused synthesized sections
This makes --orphan-handling= less noisy. This change also improves our compatibility with GNU ld. GNU ld special cases .symtab, .strtab and .shstrtab . We need output section descriptions for .symtab, .strtab and .shstrtab to suppress: <internal>:(.symtab) is being placed in '.symtab' <internal>:(.shstrtab) is being placed in '.shstrtab' <internal>:(.strtab) is being placed in '.strtab' With --strip-all, .symtab and .strtab can be omitted (note, --strip-all is not compatible with --emit-relocs). Reviewed By: nickdesaulniers Differential Revision: https://reviews.llvm.org/D75149
1 parent 2011d14 commit 4231940

File tree

4 files changed

+47
-37
lines changed

4 files changed

+47
-37
lines changed

lld/ELF/LinkerScript.cpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -681,13 +681,9 @@ void LinkerScript::addOrphanSections() {
681681
std::function<void(InputSectionBase *)> add;
682682
add = [&](InputSectionBase *s) {
683683
if (s->isLive() && !s->parent) {
684-
StringRef name = getOutputSectionName(s);
685-
686-
if (config->orphanHandling == OrphanHandlingPolicy::Error)
687-
error(toString(s) + " is being placed in '" + name + "'");
688-
else if (config->orphanHandling == OrphanHandlingPolicy::Warn)
689-
warn(toString(s) + " is being placed in '" + name + "'");
684+
orphanSections.push_back(s);
690685

686+
StringRef name = getOutputSectionName(s);
691687
if (OutputSection *sec = findByName(sectionCommands, name)) {
692688
sec->recordSection(s);
693689
} else {
@@ -732,6 +728,16 @@ void LinkerScript::addOrphanSections() {
732728
sectionCommands.insert(sectionCommands.begin(), v.begin(), v.end());
733729
}
734730

731+
void LinkerScript::diagnoseOrphanHandling() const {
732+
for (const InputSectionBase *sec : orphanSections) {
733+
StringRef name = getOutputSectionName(sec);
734+
if (config->orphanHandling == OrphanHandlingPolicy::Error)
735+
error(toString(sec) + " is being placed in '" + name + "'");
736+
else if (config->orphanHandling == OrphanHandlingPolicy::Warn)
737+
warn(toString(sec) + " is being placed in '" + name + "'");
738+
}
739+
}
740+
735741
uint64_t LinkerScript::advance(uint64_t size, unsigned alignment) {
736742
bool isTbss =
737743
(ctx->outSec->flags & SHF_TLS) && ctx->outSec->type == SHT_NOBITS;

lld/ELF/LinkerScript.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,7 @@ class LinkerScript final {
282282
ExprValue getSymbolValue(StringRef name, const Twine &loc);
283283

284284
void addOrphanSections();
285+
void diagnoseOrphanHandling() const;
285286
void adjustSectionsBeforeSorting();
286287
void adjustSectionsAfterSorting();
287288

@@ -321,6 +322,9 @@ class LinkerScript final {
321322
// to be reordered.
322323
std::vector<InsertCommand> insertCommands;
323324

325+
// Sections that will be warned/errored by --orphan-handling.
326+
std::vector<const InputSectionBase *> orphanSections;
327+
324328
// Sections whose addresses are not equal to their addrExpr values.
325329
std::vector<std::pair<const OutputSection *, uint64_t>>
326330
changedSectionAddresses;

lld/ELF/Writer.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1678,12 +1678,15 @@ static void removeUnusedSyntheticSections() {
16781678
if (!os || ss->isNeeded())
16791679
continue;
16801680

1681-
// If we reach here, then SS is an unused synthetic section and we want to
1682-
// remove it from corresponding input section description of output section.
1681+
// If we reach here, then ss is an unused synthetic section and we want to
1682+
// remove it from the corresponding input section description, and
1683+
// orphanSections.
16831684
for (BaseCommand *b : os->sectionCommands)
16841685
if (auto *isd = dyn_cast<InputSectionDescription>(b))
16851686
llvm::erase_if(isd->sections,
16861687
[=](InputSection *isec) { return isec == ss; });
1688+
llvm::erase_if(script->orphanSections,
1689+
[=](const InputSectionBase *isec) { return isec == ss; });
16871690
}
16881691
}
16891692

@@ -1830,6 +1833,7 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
18301833
in.mipsGot->build();
18311834

18321835
removeUnusedSyntheticSections();
1836+
script->diagnoseOrphanHandling();
18331837

18341838
sortSections();
18351839

lld/test/ELF/linkerscript/orphan-report.s

Lines changed: 25 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -12,37 +12,33 @@
1212
# RUN: %t.o 2>&1 -verbose -error-limit=0 | FileCheck %s --check-prefix=DEFAULT
1313

1414
## Check --orphan-handling=error reports errors about orphans.
15-
# RUN: not ld.lld -shared --orphan-handling=error -o /dev/null --script %t.script \
16-
# RUN: %t.o 2>&1 -verbose -error-limit=0 | FileCheck %s --check-prefix=REPORT
17-
# REPORT: {{.*}}.o:(.text) is being placed in '.text'
18-
# REPORT-NEXT: {{.*}}.o:(.text.2) is being placed in '.text'
19-
# REPORT-NEXT: <internal>:(.comment) is being placed in '.comment'
20-
# REPORT-NEXT: <internal>:(.bss) is being placed in '.bss'
21-
# REPORT-NEXT: <internal>:(.bss.rel.ro) is being placed in '.bss.rel.ro'
22-
# REPORT-NEXT: <internal>:(.dynsym) is being placed in '.dynsym'
23-
# REPORT-NEXT: <internal>:(.gnu.version) is being placed in '.gnu.version'
24-
# REPORT-NEXT: <internal>:(.gnu.version_r) is being placed in '.gnu.version_r'
25-
# REPORT-NEXT: <internal>:(.gnu.hash) is being placed in '.gnu.hash'
26-
# REPORT-NEXT: <internal>:(.hash) is being placed in '.hash'
27-
# REPORT-NEXT: <internal>:(.dynamic) is being placed in '.dynamic'
28-
# REPORT-NEXT: <internal>:(.dynstr) is being placed in '.dynstr'
29-
# REPORT-NEXT: <internal>:(.rela.dyn) is being placed in '.rela.dyn'
30-
# REPORT-NEXT: <internal>:(.eh_frame) is being placed in '.eh_frame'
31-
# REPORT-NEXT: <internal>:(.got) is being placed in '.got'
32-
# REPORT-NEXT: <internal>:(.got.plt) is being placed in '.got.plt'
33-
# REPORT-NEXT: <internal>:(.got.plt) is being placed in '.got.plt'
34-
# REPORT-NEXT: <internal>:(.rela.plt) is being placed in '.rela.plt'
35-
# REPORT-NEXT: <internal>:(.rela.dyn) is being placed in '.rela.dyn'
36-
# REPORT-NEXT: <internal>:(.plt) is being placed in '.plt'
37-
# REPORT-NEXT: <internal>:(.iplt) is being placed in '.iplt'
38-
# REPORT-NEXT: <internal>:(.symtab) is being placed in '.symtab'
39-
# REPORT-NEXT: <internal>:(.symtab_shndx) is being placed in '.symtab_shndx'
40-
# REPORT-NEXT: <internal>:(.shstrtab) is being placed in '.shstrtab'
41-
# REPORT-NEXT: <internal>:(.strtab) is being placed in '.strtab'
15+
# RUN: not ld.lld --orphan-handling=error -o /dev/null -T %t.script \
16+
# RUN: %t.o 2>&1 | FileCheck %s --check-prefixes=COMMON,SYMTAB
17+
18+
## --strip-all discards .strtab and .symtab sections. Don't error about them.
19+
# RUN: not ld.lld --orphan-handling=error --strip-all -o /dev/null -T %t.script \
20+
# RUN: %t.o 2>&1 | FileCheck %s --check-prefix=COMMON
21+
22+
## -shared enables some .dynsym related sections.
23+
# RUN: not ld.lld -shared --orphan-handling=error -o /dev/null -T %t.script \
24+
# RUN: %t.o 2>&1 | FileCheck %s --check-prefixes=COMMON,DYNSYM,SYMTAB
25+
26+
# COMMON: {{.*}}.o:(.text) is being placed in '.text'
27+
# COMMON-NEXT: {{.*}}.o:(.text.2) is being placed in '.text'
28+
# COMMON-NEXT: <internal>:(.comment) is being placed in '.comment'
29+
# DYNSYM-NEXT: <internal>:(.dynsym) is being placed in '.dynsym'
30+
# DYNSYM-NEXT: <internal>:(.gnu.hash) is being placed in '.gnu.hash'
31+
# DYNSYM-NEXT: <internal>:(.hash) is being placed in '.hash'
32+
# DYNSYM-NEXT: <internal>:(.dynamic) is being placed in '.dynamic'
33+
# DYNSYM-NEXT: <internal>:(.dynstr) is being placed in '.dynstr'
34+
# SYMTAB-NEXT: <internal>:(.symtab) is being placed in '.symtab'
35+
# COMMON-NEXT: <internal>:(.shstrtab) is being placed in '.shstrtab'
36+
# SYMTAB-NEXT: <internal>:(.strtab) is being placed in '.strtab'
37+
# COMMON-NOT: <internal>
4238

4339
## Check --orphan-handling=warn reports warnings about orphans.
44-
# RUN: ld.lld -shared --orphan-handling=warn -o %t.out --script %t.script \
45-
# RUN: %t.o 2>&1 -verbose | FileCheck %s --check-prefix=REPORT
40+
# RUN: ld.lld --orphan-handling=warn -o /dev/null -T %t.script \
41+
# RUN: %t.o 2>&1 | FileCheck %s --check-prefixes=COMMON,SYMTAB
4642

4743
# RUN: not ld.lld --orphan-handling=foo -o /dev/null --script %t.script %t.o 2>&1 \
4844
# RUN: | FileCheck %s --check-prefix=UNKNOWN

0 commit comments

Comments
 (0)