diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h --- a/lld/ELF/Config.h +++ b/lld/ELF/Config.h @@ -194,6 +194,7 @@ 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 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -986,6 +986,7 @@ 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 --- a/lld/ELF/LinkerScript.cpp +++ b/lld/ELF/LinkerScript.cpp @@ -685,7 +685,9 @@ 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 --- a/lld/ELF/Options.td +++ b/lld/ELF/Options.td @@ -374,6 +374,8 @@ defm undefined_glob: Eq<"undefined-glob", "Force undefined symbol during linking">, MetaVarName<"">; +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 --- a/lld/docs/ld.lld.1 +++ b/lld/docs/ld.lld.1 @@ -553,6 +553,8 @@ 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 --- /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",@progbits,unique,1 +.byte 1 + +.section .foo,"a",@progbits,unique,2 +.byte 2 + +.section .foo,"a",@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