[lld] r316583 - [ELF] - Implement --orphan-handling option.

George Rimar via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 25 08:20:30 PDT 2017


Author: grimar
Date: Wed Oct 25 08:20:30 2017
New Revision: 316583

URL: http://llvm.org/viewvc/llvm-project?rev=316583&view=rev
Log:
[ELF] - Implement --orphan-handling option.

It is PR34946.

Spec (http://man7.org/linux/man-pages/man1/ld.1.html) tells about
--orphan-handling=MODE, option where MODE can be one of four:
"place", "discard", "warn", "error".
Currently we already report orphans when -verbose given,
what becomes excessive with option implemented.

Patch stops reporting orphans when -versbose is given,
and support "place", "warn" and "error" modes.
It is not yet clear that "discard" mode is useful so it is not supported.

Differential revision: https://reviews.llvm.org/D39000

Modified:
    lld/trunk/ELF/Config.h
    lld/trunk/ELF/Driver.cpp
    lld/trunk/ELF/LinkerScript.cpp
    lld/trunk/ELF/Options.td
    lld/trunk/test/ELF/linkerscript/orphan-report.s

Modified: lld/trunk/ELF/Config.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Config.h?rev=316583&r1=316582&r2=316583&view=diff
==============================================================================
--- lld/trunk/ELF/Config.h (original)
+++ lld/trunk/ELF/Config.h Wed Oct 25 08:20:30 2017
@@ -46,6 +46,9 @@ enum class StripPolicy { None, All, Debu
 // For --unresolved-symbols.
 enum class UnresolvedPolicy { ReportError, Warn, Ignore, IgnoreAll };
 
+// For --orphan-handling.
+enum class OrphanHandlingPolicy { Place, Warn, Error };
+
 // For --sort-section and linkerscript sorting rules.
 enum class SortSectionPolicy { Default, None, Alignment, Name, Priority };
 
@@ -155,6 +158,7 @@ struct Configuration {
   bool ExitEarly;
   bool ZWxneeded;
   DiscardPolicy Discard;
+  OrphanHandlingPolicy OrphanHandling;
   SortSectionPolicy SortSection;
   StripPolicy Strip;
   UnresolvedPolicy UnresolvedSymbols;

Modified: lld/trunk/ELF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=316583&r1=316582&r2=316583&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.cpp (original)
+++ lld/trunk/ELF/Driver.cpp Wed Oct 25 08:20:30 2017
@@ -554,6 +554,17 @@ static SortSectionPolicy getSortSection(
   return SortSectionPolicy::Default;
 }
 
+static OrphanHandlingPolicy getOrphanHandling(opt::InputArgList &Args) {
+  StringRef S = Args.getLastArgValue(OPT_orphan_handling, "place");
+  if (S == "warn")
+    return OrphanHandlingPolicy::Warn;
+  if (S == "error")
+    return OrphanHandlingPolicy::Error;
+  if (S != "place")
+    error("unknown --orphan-handling mode: " + S);
+  return OrphanHandlingPolicy::Place;
+}
+
 // Parse --build-id or --build-id=<style>. We handle "tree" as a
 // synonym for "sha1" because all our hash functions including
 // -build-id=sha1 are actually tree hashes for performance reasons.
@@ -656,6 +667,7 @@ void LinkerDriver::readConfigs(opt::Inpu
   Config->OptRemarksFilename = Args.getLastArgValue(OPT_opt_remarks_filename);
   Config->OptRemarksWithHotness = Args.hasArg(OPT_opt_remarks_with_hotness);
   Config->Optimize = getInteger(Args, OPT_O, 1);
+  Config->OrphanHandling = getOrphanHandling(Args);
   Config->OutputFile = Args.getLastArgValue(OPT_o);
   Config->Pie = Args.hasFlag(OPT_pie, OPT_nopie, false);
   Config->PrintGcSections = Args.hasArg(OPT_print_gc_sections);

Modified: lld/trunk/ELF/LinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=316583&r1=316582&r2=316583&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.cpp (original)
+++ lld/trunk/ELF/LinkerScript.cpp Wed Oct 25 08:20:30 2017
@@ -457,6 +457,13 @@ static OutputSection *findByName(ArrayRe
   return nullptr;
 }
 
+static void reportOrphan(InputSectionBase *IS, StringRef Name) {
+  if (Config->OrphanHandling == OrphanHandlingPolicy::Error)
+    error(toString(IS) + " is being placed in '" + Name + "'");
+  else if (Config->OrphanHandling == OrphanHandlingPolicy::Warn)
+    warn(toString(IS) + " is being placed in '" + Name + "'");
+}
+
 // Add sections that didn't match any sections command.
 void LinkerScript::addOrphanSections(OutputSectionFactory &Factory) {
   unsigned End = SectionCommands.size();
@@ -466,7 +473,7 @@ void LinkerScript::addOrphanSections(Out
       continue;
 
     StringRef Name = getOutputSectionName(S->Name);
-    log(toString(S) + " is being placed in '" + Name + "'");
+    reportOrphan(S, Name);
 
     if (OutputSection *Sec =
             findByName(makeArrayRef(SectionCommands).slice(0, End), Name)) {

Modified: lld/trunk/ELF/Options.td
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Options.td?rev=316583&r1=316582&r2=316583&view=diff
==============================================================================
--- lld/trunk/ELF/Options.td (original)
+++ lld/trunk/ELF/Options.td Wed Oct 25 08:20:30 2017
@@ -219,6 +219,9 @@ def oformat: Separate<["--"], "oformat">
 def omagic: Flag<["--"], "omagic">, MetaVarName<"<magic>">,
   HelpText<"Set the text and data sections to be readable and writable">;
 
+defm orphan_handling: Eq<"orphan-handling">, 
+  HelpText<"Control how orphan sections are handled when linker script used">;
+
 def pie: F<"pie">, HelpText<"Create a position independent executable">;
 
 def print_gc_sections: F<"print-gc-sections">,

Modified: lld/trunk/test/ELF/linkerscript/orphan-report.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/orphan-report.s?rev=316583&r1=316582&r2=316583&view=diff
==============================================================================
--- lld/trunk/test/ELF/linkerscript/orphan-report.s (original)
+++ lld/trunk/test/ELF/linkerscript/orphan-report.s Wed Oct 25 08:20:30 2017
@@ -1,31 +1,51 @@
 # REQUIRES: x86
 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
 # RUN: echo "SECTIONS { .text : { *(.text.1) } }" > %t.script
-# RUN: ld.lld --hash-style=sysv -shared -o %t.out --script %t.script %t.o --verbose | FileCheck %s
 
-# CHECK:      {{.*}}.o:(.text) is being placed in '.text'
-# CHECK-NEXT: {{.*}}.o:(.text.2) is being placed in '.text'
-# CHECK-NEXT: <internal>:(.comment) is being placed in '.comment'
-# CHECK-NEXT: <internal>:(.bss) is being placed in '.bss'
-# CHECK-NEXT: <internal>:(.bss.rel.ro) is being placed in '.bss.rel.ro'
-# CHECK-NEXT: <internal>:(.dynsym) is being placed in '.dynsym'
-# CHECK-NEXT: <internal>:(.gnu.version) is being placed in '.gnu.version'
-# CHECK-NEXT: <internal>:(.gnu.version_r) is being placed in '.gnu.version_r'
-# CHECK-NEXT: <internal>:(.hash) is being placed in '.hash'
-# CHECK-NEXT: <internal>:(.dynamic) is being placed in '.dynamic'
-# CHECK-NEXT: <internal>:(.dynstr) is being placed in '.dynstr'
-# CHECK-NEXT: <internal>:(.rela.dyn) is being placed in '.rela.dyn'
-# CHECK-NEXT: <internal>:(.got) is being placed in '.got'
-# CHECK-NEXT: <internal>:(.got.plt) is being placed in '.got.plt'
-# CHECK-NEXT: <internal>:(.got.plt) is being placed in '.got.plt'
-# CHECK-NEXT: <internal>:(.rela.plt) is being placed in '.rela.plt'
-# CHECK-NEXT: <internal>:(.rela.plt) is being placed in '.rela.plt'
-# CHECK-NEXT: <internal>:(.plt) is being placed in '.plt'
-# CHECK-NEXT: <internal>:(.plt) is being placed in '.plt'
-# CHECK-NEXT: <internal>:(.eh_frame) is being placed in '.eh_frame'
-# CHECK-NEXT: <internal>:(.symtab) is being placed in '.symtab'
-# CHECK-NEXT: <internal>:(.shstrtab) is being placed in '.shstrtab'
-# CHECK-NEXT: <internal>:(.strtab) is being placed in '.strtab'
+## Check we do not report orphans by default even with -verbose.
+# RUN: ld.lld -shared -o %t.out --script %t.script %t.o 2>&1 -verbose \
+# RUN:   | FileCheck %s --check-prefix=DEFAULT
+# DEFAULT-NOT: placed
+
+## Check --orphan-handling=place has the same behavior as default.
+# RUN: ld.lld -shared --orphan-handling=place -o %t.out --script %t.script \
+# 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 %t.out --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>:(.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.plt) is being placed in '.rela.plt'
+# REPORT-NEXT: <internal>:(.plt) is being placed in '.plt'
+# REPORT-NEXT: <internal>:(.plt) is being placed in '.plt'
+# REPORT-NEXT: <internal>:(.eh_frame) is being placed in '.eh_frame'
+# REPORT-NEXT: <internal>:(.symtab) is being placed in '.symtab'
+# REPORT-NEXT: <internal>:(.shstrtab) is being placed in '.shstrtab'
+# REPORT-NEXT: <internal>:(.strtab) is being placed in '.strtab'
+
+## 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: not ld.lld --orphan-handling=foo -o %t.out --script %t.script %t.o 2>&1 \
+# RUN:   | FileCheck %s --check-prefix=UNKNOWN
+# UNKNOWN: unknown --orphan-handling mode: foo
 
 .section .text.1,"a"
  nop




More information about the llvm-commits mailing list