[lld] 4231940 - [ELF] --orphan-handling=: don't warn/error for unused synthesized sections
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Wed Feb 26 08:56:24 PST 2020
Author: Fangrui Song
Date: 2020-02-26T08:56:12-08:00
New Revision: 423194098b88dfea86cca6f8e203e9d88f70abc9
URL: https://github.com/llvm/llvm-project/commit/423194098b88dfea86cca6f8e203e9d88f70abc9
DIFF: https://github.com/llvm/llvm-project/commit/423194098b88dfea86cca6f8e203e9d88f70abc9.diff
LOG: [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
Added:
Modified:
lld/ELF/LinkerScript.cpp
lld/ELF/LinkerScript.h
lld/ELF/Writer.cpp
lld/test/ELF/linkerscript/orphan-report.s
Removed:
################################################################################
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index d78b4907a5be..e624eeda8e67 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -681,13 +681,9 @@ void LinkerScript::addOrphanSections() {
std::function<void(InputSectionBase *)> add;
add = [&](InputSectionBase *s) {
if (s->isLive() && !s->parent) {
- StringRef name = getOutputSectionName(s);
-
- if (config->orphanHandling == OrphanHandlingPolicy::Error)
- error(toString(s) + " is being placed in '" + name + "'");
- else if (config->orphanHandling == OrphanHandlingPolicy::Warn)
- warn(toString(s) + " is being placed in '" + name + "'");
+ orphanSections.push_back(s);
+ StringRef name = getOutputSectionName(s);
if (OutputSection *sec = findByName(sectionCommands, name)) {
sec->recordSection(s);
} else {
@@ -732,6 +728,16 @@ void LinkerScript::addOrphanSections() {
sectionCommands.insert(sectionCommands.begin(), v.begin(), v.end());
}
+void LinkerScript::diagnoseOrphanHandling() const {
+ for (const InputSectionBase *sec : orphanSections) {
+ StringRef name = getOutputSectionName(sec);
+ if (config->orphanHandling == OrphanHandlingPolicy::Error)
+ error(toString(sec) + " is being placed in '" + name + "'");
+ else if (config->orphanHandling == OrphanHandlingPolicy::Warn)
+ warn(toString(sec) + " is being placed in '" + name + "'");
+ }
+}
+
uint64_t LinkerScript::advance(uint64_t size, unsigned alignment) {
bool isTbss =
(ctx->outSec->flags & SHF_TLS) && ctx->outSec->type == SHT_NOBITS;
diff --git a/lld/ELF/LinkerScript.h b/lld/ELF/LinkerScript.h
index 1c981b4ba3e0..32b33b82f98e 100644
--- a/lld/ELF/LinkerScript.h
+++ b/lld/ELF/LinkerScript.h
@@ -282,6 +282,7 @@ class LinkerScript final {
ExprValue getSymbolValue(StringRef name, const Twine &loc);
void addOrphanSections();
+ void diagnoseOrphanHandling() const;
void adjustSectionsBeforeSorting();
void adjustSectionsAfterSorting();
@@ -321,6 +322,9 @@ class LinkerScript final {
// to be reordered.
std::vector<InsertCommand> insertCommands;
+ // Sections that will be warned/errored by --orphan-handling.
+ std::vector<const InputSectionBase *> orphanSections;
+
// Sections whose addresses are not equal to their addrExpr values.
std::vector<std::pair<const OutputSection *, uint64_t>>
changedSectionAddresses;
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index 8fd69af68fe7..013f7d066703 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -1678,12 +1678,15 @@ static void removeUnusedSyntheticSections() {
if (!os || ss->isNeeded())
continue;
- // If we reach here, then SS is an unused synthetic section and we want to
- // remove it from corresponding input section description of output section.
+ // If we reach here, then ss is an unused synthetic section and we want to
+ // remove it from the corresponding input section description, and
+ // orphanSections.
for (BaseCommand *b : os->sectionCommands)
if (auto *isd = dyn_cast<InputSectionDescription>(b))
llvm::erase_if(isd->sections,
[=](InputSection *isec) { return isec == ss; });
+ llvm::erase_if(script->orphanSections,
+ [=](const InputSectionBase *isec) { return isec == ss; });
}
}
@@ -1830,6 +1833,7 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
in.mipsGot->build();
removeUnusedSyntheticSections();
+ script->diagnoseOrphanHandling();
sortSections();
diff --git a/lld/test/ELF/linkerscript/orphan-report.s b/lld/test/ELF/linkerscript/orphan-report.s
index 071ddeb5359a..5203a6d20de2 100644
--- a/lld/test/ELF/linkerscript/orphan-report.s
+++ b/lld/test/ELF/linkerscript/orphan-report.s
@@ -12,37 +12,33 @@
# RUN: %t.o 2>&1 -verbose -error-limit=0 | FileCheck %s --check-prefix=DEFAULT
## Check --orphan-handling=error reports errors about orphans.
-# RUN: not ld.lld -shared --orphan-handling=error -o /dev/null --script %t.script \
-# RUN: %t.o 2>&1 -verbose -error-limit=0 | FileCheck %s --check-prefix=REPORT
-# REPORT: {{.*}}.o:(.text) is being placed in '.text'
-# REPORT-NEXT: {{.*}}.o:(.text.2) is being placed in '.text'
-# REPORT-NEXT: <internal>:(.comment) is being placed in '.comment'
-# REPORT-NEXT: <internal>:(.bss) is being placed in '.bss'
-# REPORT-NEXT: <internal>:(.bss.rel.ro) is being placed in '.bss.rel.ro'
-# REPORT-NEXT: <internal>:(.dynsym) is being placed in '.dynsym'
-# REPORT-NEXT: <internal>:(.gnu.version) is being placed in '.gnu.version'
-# REPORT-NEXT: <internal>:(.gnu.version_r) is being placed in '.gnu.version_r'
-# REPORT-NEXT: <internal>:(.gnu.hash) is being placed in '.gnu.hash'
-# REPORT-NEXT: <internal>:(.hash) is being placed in '.hash'
-# REPORT-NEXT: <internal>:(.dynamic) is being placed in '.dynamic'
-# REPORT-NEXT: <internal>:(.dynstr) is being placed in '.dynstr'
-# REPORT-NEXT: <internal>:(.rela.dyn) is being placed in '.rela.dyn'
-# REPORT-NEXT: <internal>:(.eh_frame) is being placed in '.eh_frame'
-# REPORT-NEXT: <internal>:(.got) is being placed in '.got'
-# REPORT-NEXT: <internal>:(.got.plt) is being placed in '.got.plt'
-# REPORT-NEXT: <internal>:(.got.plt) is being placed in '.got.plt'
-# REPORT-NEXT: <internal>:(.rela.plt) is being placed in '.rela.plt'
-# REPORT-NEXT: <internal>:(.rela.dyn) is being placed in '.rela.dyn'
-# REPORT-NEXT: <internal>:(.plt) is being placed in '.plt'
-# REPORT-NEXT: <internal>:(.iplt) is being placed in '.iplt'
-# REPORT-NEXT: <internal>:(.symtab) is being placed in '.symtab'
-# REPORT-NEXT: <internal>:(.symtab_shndx) is being placed in '.symtab_shndx'
-# REPORT-NEXT: <internal>:(.shstrtab) is being placed in '.shstrtab'
-# REPORT-NEXT: <internal>:(.strtab) is being placed in '.strtab'
+# RUN: not ld.lld --orphan-handling=error -o /dev/null -T %t.script \
+# RUN: %t.o 2>&1 | FileCheck %s --check-prefixes=COMMON,SYMTAB
+
+## --strip-all discards .strtab and .symtab sections. Don't error about them.
+# RUN: not ld.lld --orphan-handling=error --strip-all -o /dev/null -T %t.script \
+# RUN: %t.o 2>&1 | FileCheck %s --check-prefix=COMMON
+
+## -shared enables some .dynsym related sections.
+# RUN: not ld.lld -shared --orphan-handling=error -o /dev/null -T %t.script \
+# RUN: %t.o 2>&1 | FileCheck %s --check-prefixes=COMMON,DYNSYM,SYMTAB
+
+# COMMON: {{.*}}.o:(.text) is being placed in '.text'
+# COMMON-NEXT: {{.*}}.o:(.text.2) is being placed in '.text'
+# COMMON-NEXT: <internal>:(.comment) is being placed in '.comment'
+# DYNSYM-NEXT: <internal>:(.dynsym) is being placed in '.dynsym'
+# DYNSYM-NEXT: <internal>:(.gnu.hash) is being placed in '.gnu.hash'
+# DYNSYM-NEXT: <internal>:(.hash) is being placed in '.hash'
+# DYNSYM-NEXT: <internal>:(.dynamic) is being placed in '.dynamic'
+# DYNSYM-NEXT: <internal>:(.dynstr) is being placed in '.dynstr'
+# SYMTAB-NEXT: <internal>:(.symtab) is being placed in '.symtab'
+# COMMON-NEXT: <internal>:(.shstrtab) is being placed in '.shstrtab'
+# SYMTAB-NEXT: <internal>:(.strtab) is being placed in '.strtab'
+# COMMON-NOT: <internal>
## Check --orphan-handling=warn reports warnings about orphans.
-# RUN: ld.lld -shared --orphan-handling=warn -o %t.out --script %t.script \
-# RUN: %t.o 2>&1 -verbose | FileCheck %s --check-prefix=REPORT
+# RUN: ld.lld --orphan-handling=warn -o /dev/null -T %t.script \
+# RUN: %t.o 2>&1 | FileCheck %s --check-prefixes=COMMON,SYMTAB
# RUN: not ld.lld --orphan-handling=foo -o /dev/null --script %t.script %t.o 2>&1 \
# RUN: | FileCheck %s --check-prefix=UNKNOWN
More information about the llvm-commits
mailing list