[lld] 6e2804c - [LLD] Add support for --unique option

David Bozier via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 10 05:20:46 PDT 2020


Author: David Bozier
Date: 2020-03-10T12:20:21Z
New Revision: 6e2804ce6baa3090399ccf67a2d672c50fd87447

URL: https://github.com/llvm/llvm-project/commit/6e2804ce6baa3090399ccf67a2d672c50fd87447
DIFF: https://github.com/llvm/llvm-project/commit/6e2804ce6baa3090399ccf67a2d672c50fd87447.diff

LOG: [LLD] Add support for --unique option

Summary:
Places orphan sections into a unique output section. This prevents the merging of orphan sections of the same name.
Matches behaviour of GNU ld --unique. --unique=pattern is not implemented.

Motivated user case shown in the test has 2 local symbols as they would appear if C++ source has been compiled with -ffunction-sections. The merging of these sections in the case of a partial link (-r) may limit the effectiveness of -gc-sections of a subsequent link.

Reviewers: espindola, jhenderson, bd1976llvm, edd, andrewng, JonChesterfield, MaskRay, grimar, ruiu, psmith

Reviewed By: MaskRay, grimar

Subscribers: emaste, arichardson, MaskRay, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D75536

Added: 
    lld/test/ELF/unique-orphans.s

Modified: 
    lld/ELF/Config.h
    lld/ELF/Driver.cpp
    lld/ELF/LinkerScript.cpp
    lld/ELF/Options.td
    lld/docs/ld.lld.1

Removed: 
    


################################################################################
diff  --git a/lld/ELF/Config.h b/lld/ELF/Config.h
index 81c42b6e8517..05f44a5fb7aa 100644
--- a/lld/ELF/Config.h
+++ b/lld/ELF/Config.h
@@ -194,6 +194,7 @@ struct Configuration {
   bool timeTraceEnabled;
   bool tocOptimize;
   bool undefinedVersion;
+  bool unique;
   bool useAndroidRelrTags = false;
   bool warnBackrefs;
   bool warnCommon;

diff  --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 8d919308126c..f9a1340e25d3 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -986,6 +986,7 @@ static void readConfigs(opt::InputArgList &args) {
   config->undefined = args::getStrings(args, OPT_undefined);
   config->undefinedVersion =
       args.hasFlag(OPT_undefined_version, OPT_no_undefined_version, true);
+  config->unique = args.hasArg(OPT_unique);
   config->useAndroidRelrTags = args.hasFlag(
       OPT_use_android_relr_tags, OPT_no_use_android_relr_tags, false);
   config->unresolvedSymbols = getUnresolvedSymbolPolicy(args);

diff  --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index 0aca7c132c87..2c71280d67c2 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -685,7 +685,9 @@ void LinkerScript::addOrphanSections() {
       orphanSections.push_back(s);
 
       StringRef name = getOutputSectionName(s);
-      if (OutputSection *sec = findByName(sectionCommands, name)) {
+      if (config->unique) {
+        v.push_back(createSection(s, name));
+      } else if (OutputSection *sec = findByName(sectionCommands, name)) {
         sec->recordSection(s);
       } else {
         if (OutputSection *os = addInputSec(map, s, name))

diff  --git a/lld/ELF/Options.td b/lld/ELF/Options.td
index 307c781b87e4..e1c489c4a1e3 100644
--- a/lld/ELF/Options.td
+++ b/lld/ELF/Options.td
@@ -374,6 +374,8 @@ defm undefined: Eq<"undefined", "Force undefined symbol during linking">,
 defm undefined_glob: Eq<"undefined-glob", "Force undefined symbol during linking">,
   MetaVarName<"<pattern>">;
 
+def unique: F<"unique">, HelpText<"Creates a separate output section for every orphan input section">;
+
 defm unresolved_symbols:
   Eq<"unresolved-symbols", "Determine how to handle unresolved symbols">;
 

diff  --git a/lld/docs/ld.lld.1 b/lld/docs/ld.lld.1
index 058c8ddc9000..238ac28a599c 100644
--- a/lld/docs/ld.lld.1
+++ b/lld/docs/ld.lld.1
@@ -553,6 +553,8 @@ matches the characters within brackets.
 All symbols that match
 a given pattern are handled as if they were given as arguments of
 .Fl -undefined .
+.It Fl -unique
+Creates a separate output section for every orphan input section.
 .It Fl -unresolved-symbols Ns = Ns Ar value
 Determine how to handle unresolved symbols.
 .It Fl -use-android-relr-tags

diff  --git a/lld/test/ELF/unique-orphans.s b/lld/test/ELF/unique-orphans.s
new file mode 100644
index 000000000000..d4623a91ecbc
--- /dev/null
+++ b/lld/test/ELF/unique-orphans.s
@@ -0,0 +1,26 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o
+
+.section .foo,"a", at progbits,unique,1
+.byte 1
+
+.section .foo,"a", at progbits,unique,2
+.byte 2
+
+.section .foo,"a", at progbits,unique,3
+.byte 3
+
+## We should have 3 instances of orphan section foo.
+## Test with -r
+# RUN: ld.lld %t.o -o %t.elf --unique 
+# RUN: llvm-readelf -S %t.elf | FileCheck %s
+
+# CHECK-COUNT-3: .foo
+# CHECK-NOT: .foo
+
+## Test that --unique does not affect sections specified in output section descriptions.
+# RUN: echo 'SECTIONS { .foo : { *(.foo) }}' > %t.script
+# RUN: ld.lld %t.o -o %t2.elf -T %t.script --unique 
+# RUN: llvm-readelf -S %t2.elf | FileCheck --check-prefix SCRIPT %s
+# SCRIPT: .foo
+# SCRIPT-NOT: .foo


        


More information about the llvm-commits mailing list