[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