[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