[lld] r325125 - [ELF] Add warnings for various symbols that cannot be ordered
James Henderson via llvm-commits
llvm-commits at lists.llvm.org
Wed Feb 14 05:36:22 PST 2018
Author: jhenderson
Date: Wed Feb 14 05:36:22 2018
New Revision: 325125
URL: http://llvm.org/viewvc/llvm-project?rev=325125&view=rev
Log:
[ELF] Add warnings for various symbols that cannot be ordered
There are a number of different situations when symbols are requested
to be ordered in the --symbol-ordering-file that cannot be ordered for
some reason. To assist with identifying these symbols, and either
tidying up the order file, or the inputs, a number of warnings have
been added. As some users may find these warnings unhelpful, due to how
they use the symbol ordering file, a switch has also been added to
disable these warnings.
The cases where we now warn are:
* Entries in the order file that don't correspond to any symbol in the input
* Undefined symbols
* Absolute symbols
* Symbols imported from shared objects
* Symbols that are discarded, due to e.g. --gc-sections or /DISCARD/ linker script sections
* Multiple of the same entry in the order file
Reviewed by: rafael, ruiu
Differential Revision: https://reviews.llvm.org/D42475
Added:
lld/trunk/test/ELF/Inputs/symbol-ordering-file-warnings1.s
lld/trunk/test/ELF/Inputs/symbol-ordering-file-warnings2.s
lld/trunk/test/ELF/symbol-ordering-file-warnings.s
Modified:
lld/trunk/ELF/Config.h
lld/trunk/ELF/Driver.cpp
lld/trunk/ELF/Options.td
lld/trunk/ELF/Writer.cpp
Modified: lld/trunk/ELF/Config.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Config.h?rev=325125&r1=325124&r2=325125&view=diff
==============================================================================
--- lld/trunk/ELF/Config.h (original)
+++ lld/trunk/ELF/Config.h Wed Feb 14 05:36:22 2018
@@ -152,6 +152,7 @@ struct Configuration {
bool UndefinedVersion;
bool WarnCommon;
bool WarnMissingEntry;
+ bool WarnSymbolOrdering;
bool WriteAddends;
bool ZCombreloc;
bool ZExecstack;
Modified: lld/trunk/ELF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=325125&r1=325124&r2=325125&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.cpp (original)
+++ lld/trunk/ELF/Driver.cpp Wed Feb 14 05:36:22 2018
@@ -45,6 +45,7 @@
#include "lld/Common/TargetOptionsCommandFlags.h"
#include "lld/Common/Threads.h"
#include "lld/Common/Version.h"
+#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/CommandLine.h"
@@ -589,6 +590,16 @@ static int parseInt(StringRef S, opt::Ar
return V;
}
+// Parse the symbol ordering file and warn for any duplicate entries.
+static std::vector<StringRef> getSymbolOrderingFile(MemoryBufferRef MB) {
+ SetVector<StringRef> Names;
+ for (StringRef S : args::getLines(MB))
+ if (!Names.insert(S) && Config->WarnSymbolOrdering)
+ warn(MB.getBufferIdentifier() + ": duplicate ordered symbol: " + S);
+
+ return Names.takeVector();
+}
+
// Initializes Config members by the command line options.
void LinkerDriver::readConfigs(opt::InputArgList &Args) {
errorHandler().Verbose = Args.hasArg(OPT_verbose);
@@ -677,6 +688,8 @@ void LinkerDriver::readConfigs(opt::Inpu
Args.hasFlag(OPT_undefined_version, OPT_no_undefined_version, true);
Config->UnresolvedSymbols = getUnresolvedSymbolPolicy(Args);
Config->WarnCommon = Args.hasFlag(OPT_warn_common, OPT_no_warn_common, false);
+ Config->WarnSymbolOrdering =
+ Args.hasFlag(OPT_warn_symbol_ordering, OPT_no_warn_symbol_ordering, true);
Config->ZCombreloc = !hasZOption(Args, "nocombreloc");
Config->ZExecstack = hasZOption(Args, "execstack");
Config->ZNocopyreloc = hasZOption(Args, "nocopyreloc");
@@ -767,7 +780,7 @@ void LinkerDriver::readConfigs(opt::Inpu
if (auto *Arg = Args.getLastArg(OPT_symbol_ordering_file))
if (Optional<MemoryBufferRef> Buffer = readFile(Arg->getValue()))
- Config->SymbolOrderingFile = args::getLines(*Buffer);
+ Config->SymbolOrderingFile = getSymbolOrderingFile(*Buffer);
// If --retain-symbol-file is used, we'll keep only the symbols listed in
// the file and discard all others.
Modified: lld/trunk/ELF/Options.td
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Options.td?rev=325125&r1=325124&r2=325125&view=diff
==============================================================================
--- lld/trunk/ELF/Options.td (original)
+++ lld/trunk/ELF/Options.td Wed Feb 14 05:36:22 2018
@@ -324,6 +324,10 @@ defm warn_common: B<"warn-common",
"Warn about duplicate common symbols",
"Do not warn about duplicate common symbols">;
+defm warn_symbol_ordering : B<"warn-symbol-ordering",
+ "Warn about problems with the symbol ordering file",
+ "Do not warn about problems with the symbol ordering file">;
+
def warn_unresolved_symbols: F<"warn-unresolved-symbols">,
HelpText<"Report unresolved symbols as warnings">;
Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=325125&r1=325124&r2=325125&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Wed Feb 14 05:36:22 2018
@@ -1022,25 +1022,58 @@ static DenseMap<const InputSectionBase *
if (Config->SymbolOrderingFile.empty())
return SectionOrder;
+ struct SymbolOrderEntry {
+ int Priority;
+ bool Present;
+ };
+
// Build a map from symbols to their priorities. Symbols that didn't
// appear in the symbol ordering file have the lowest priority 0.
// All explicitly mentioned symbols have negative (higher) priorities.
- DenseMap<StringRef, int> SymbolOrder;
+ DenseMap<StringRef, SymbolOrderEntry> SymbolOrder;
int Priority = -Config->SymbolOrderingFile.size();
for (StringRef S : Config->SymbolOrderingFile)
- SymbolOrder.insert({S, Priority++});
+ SymbolOrder.insert({S, {Priority++, false}});
// Build a map from sections to their priorities.
for (InputFile *File : ObjectFiles) {
for (Symbol *Sym : File->getSymbols()) {
- if (auto *D = dyn_cast<Defined>(Sym)) {
- if (auto *Sec = dyn_cast_or_null<InputSectionBase>(D->Section)) {
- int &Priority = SectionOrder[Sec];
- Priority = std::min(Priority, SymbolOrder.lookup(D->getName()));
- }
+ auto It = SymbolOrder.find(Sym->getName());
+ if (It == SymbolOrder.end())
+ continue;
+ SymbolOrderEntry &Ent = It->second;
+ Ent.Present = true;
+
+ auto *D = dyn_cast<Defined>(Sym);
+ if (Config->WarnSymbolOrdering) {
+ if (Sym->isUndefined())
+ warn(File->getName() +
+ ": unable to order undefined symbol: " + Sym->getName());
+ else if (Sym->isShared())
+ warn(File->getName() +
+ ": unable to order shared symbol: " + Sym->getName());
+ else if (D && !D->Section)
+ warn(File->getName() +
+ ": unable to order absolute symbol: " + Sym->getName());
+ else if (D && !D->Section->Live)
+ warn(File->getName() +
+ ": unable to order discarded symbol: " + Sym->getName());
+ }
+ if (!D)
+ continue;
+
+ if (auto *Sec = dyn_cast_or_null<InputSectionBase>(D->Section)) {
+ int &Priority = SectionOrder[Sec];
+ Priority = std::min(Priority, Ent.Priority);
}
}
}
+
+ if (Config->WarnSymbolOrdering)
+ for (auto OrderEntry : SymbolOrder)
+ if (!OrderEntry.second.Present)
+ warn("symbol ordering file: no such symbol: " + OrderEntry.first);
+
return SectionOrder;
}
Added: lld/trunk/test/ELF/Inputs/symbol-ordering-file-warnings1.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/Inputs/symbol-ordering-file-warnings1.s?rev=325125&view=auto
==============================================================================
--- lld/trunk/test/ELF/Inputs/symbol-ordering-file-warnings1.s (added)
+++ lld/trunk/test/ELF/Inputs/symbol-ordering-file-warnings1.s Wed Feb 14 05:36:22 2018
@@ -0,0 +1,19 @@
+# This is a "bad" (absolute) instance of the symbol
+multi = 1234
+
+.text
+.global shared
+.type shared, @function
+shared:
+ movq %rax, multi
+ ret
+
+.section .text.comdat,"axG", at progbits,comdat,comdat
+.weak comdat
+comdat:
+ ret
+
+.section .text.glob_or_wk,"ax", at progbits
+.global glob_or_wk
+glob_or_wk:
+ ret
Added: lld/trunk/test/ELF/Inputs/symbol-ordering-file-warnings2.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/Inputs/symbol-ordering-file-warnings2.s?rev=325125&view=auto
==============================================================================
--- lld/trunk/test/ELF/Inputs/symbol-ordering-file-warnings2.s (added)
+++ lld/trunk/test/ELF/Inputs/symbol-ordering-file-warnings2.s Wed Feb 14 05:36:22 2018
@@ -0,0 +1,6 @@
+.text
+.global missing
+missing:
+ callq undefined
+ # This is a "bad" (undefined) instance of the symbol
+ callq multi
Added: lld/trunk/test/ELF/symbol-ordering-file-warnings.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/symbol-ordering-file-warnings.s?rev=325125&view=auto
==============================================================================
--- lld/trunk/test/ELF/symbol-ordering-file-warnings.s (added)
+++ lld/trunk/test/ELF/symbol-ordering-file-warnings.s Wed Feb 14 05:36:22 2018
@@ -0,0 +1,140 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/symbol-ordering-file-warnings1.s -o %t2.o
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/symbol-ordering-file-warnings2.s -o %t3.o
+# RUN: ld.lld -shared %t2.o -o %t.so
+
+# Check that a warning is emitted for entries in the file that are not present in any used input.
+# RUN: echo "missing" > %t-order-missing.txt
+# RUN: ld.lld %t1.o -o %t --symbol-ordering-file %t-order-missing.txt --unresolved-symbols=ignore-all 2>&1 | \
+# RUN: FileCheck %s --check-prefixes=WARN,MISSING
+
+# Check that the warning can be disabled.
+# RUN: ld.lld %t1.o -o %t --symbol-ordering-file %t-order-missing.txt --unresolved-symbols=ignore-all --no-warn-symbol-ordering 2>&1 | \
+# RUN: FileCheck %s --check-prefixes=WARN --allow-empty
+
+# Check that the warning can be re-enabled
+# RUN: ld.lld %t1.o -o %t --symbol-ordering-file %t-order-missing.txt --unresolved-symbols=ignore-all --no-warn-symbol-ordering --warn-symbol-ordering 2>&1 | \
+# RUN: FileCheck %s --check-prefixes=WARN,MISSING
+
+# Check that a warning is emitted for undefined symbols.
+# RUN: echo "undefined" > %t-order-undef.txt
+# RUN: ld.lld %t1.o %t3.o -o %t --symbol-ordering-file %t-order-undef.txt --unresolved-symbols=ignore-all 2>&1 | \
+# RUN: FileCheck %s --check-prefixes=WARN,UNDEFINED
+
+# Check that a warning is emitted for imported shared symbols.
+# RUN: echo "shared" > %t-order-shared.txt
+# RUN: ld.lld %t1.o %t.so -o %t --symbol-ordering-file %t-order-shared.txt --unresolved-symbols=ignore-all 2>&1 | \
+# RUN: FileCheck %s --check-prefixes=WARN,SHARED
+
+# Check that a warning is emitted for absolute symbols.
+# RUN: echo "absolute" > %t-order-absolute.txt
+# RUN: ld.lld %t1.o -o %t --symbol-ordering-file %t-order-absolute.txt --unresolved-symbols=ignore-all 2>&1 | \
+# RUN: FileCheck %s --check-prefixes=WARN,ABSOLUTE
+
+# Check that a warning is emitted for symbols discarded due to --gc-sections.
+# RUN: echo "gc" > %t-order-gc.txt
+# RUN: ld.lld %t1.o -o %t --symbol-ordering-file %t-order-gc.txt --gc-sections --unresolved-symbols=ignore-all 2>&1 | \
+# RUN: FileCheck %s --check-prefixes=WARN,GC
+
+# Check that a warning is emitted for symbols discarded due to a linker script /DISCARD/ section.
+# RUN: echo "discard" > %t-order-discard.txt
+# RUN: echo "SECTIONS { /DISCARD/ : { *(.text.discard) } }" > %t.script
+# RUN: ld.lld %t1.o -o %t --symbol-ordering-file %t-order-discard.txt -T %t.script --unresolved-symbols=ignore-all 2>&1 | \
+# RUN: FileCheck %s --check-prefixes=WARN,DISCARD
+
+# Check that LLD does not warn for discarded COMDAT symbols, if they are present in the kept instance.
+# RUN: echo "comdat" > %t-order-comdat.txt
+# RUN: ld.lld %t1.o %t2.o -o %t --symbol-ordering-file %t-order-comdat.txt --unresolved-symbols=ignore-all 2>&1 | \
+# RUN: FileCheck %s --check-prefixes=WARN --allow-empty
+
+# Check that if a COMDAT was unused and discarded via --gc-sections, warn for each instance.
+# RUN: ld.lld %t1.o %t2.o -o %t --symbol-ordering-file %t-order-comdat.txt --gc-sections --unresolved-symbols=ignore-all 2>&1 | \
+# RUN: FileCheck %s --check-prefixes=WARN,COMDAT
+
+# Check that if a weak symbol is not kept, because of an equivalent global symbol, no warning is emitted.
+# RUN: echo "glob_or_wk" > %t-order-weak.txt
+# RUN: ld.lld %t1.o %t2.o -o %t --symbol-ordering-file %t-order-weak.txt --unresolved-symbols=ignore-all 2>&1 | \
+# RUN: FileCheck %s --check-prefixes=WARN --allow-empty
+
+# Check that symbols only in unused archive members result in a warning.
+# RUN: rm -f %t.a
+# RUN: llvm-ar rc %t.a %t3.o
+# RUN: ld.lld %t1.o %t.a -o %t --symbol-ordering-file %t-order-missing.txt --unresolved-symbols=ignore-all 2>&1 | \
+# RUN: FileCheck %s --check-prefixes=WARN,MISSING --allow-empty
+
+# Check that a warning for each same-named symbol with an issue.
+# RUN: echo "multi" > %t-order-same-name.txt
+# RUN: ld.lld %t1.o %t2.o %t3.o -o %t --symbol-ordering-file %t-order-same-name.txt --unresolved-symbols=ignore-all 2>&1 | \
+# RUN: FileCheck %s --check-prefixes=WARN,MULTI
+
+# Check that a warning is emitted if the same symbol is mentioned multiple times in the ordering file.
+# RUN: echo "_start" > %t-order-multiple-same.txt
+# RUN: echo "_start" >> %t-order-multiple-same.txt
+# RUN: ld.lld %t1.o -o %t --symbol-ordering-file %t-order-multiple-same.txt --unresolved-symbols=ignore-all 2>&1 | \
+# RUN: FileCheck %s --check-prefixes=WARN,SAMESYM
+
+# Check that all warnings can be emitted from the same input.
+# RUN: echo "missing_sym" > %t-order-multi.txt
+# RUN: echo "undefined" >> %t-order-multi.txt
+# RUN: echo "_start" >> %t-order-multi.txt
+# RUN: echo "shared" >> %t-order-multi.txt
+# RUN: echo "absolute" >> %t-order-multi.txt
+# RUN: echo "gc" >> %t-order-multi.txt
+# RUN: echo "discard" >> %t-order-multi.txt
+# RUN: echo "_start" >> %t-order-multi.txt
+# RUN: ld.lld %t1.o %t3.o %t.so -o %t --symbol-ordering-file %t-order-multi.txt --gc-sections -T %t.script --unresolved-symbols=ignore-all 2>&1 | \
+# RUN: FileCheck %s --check-prefixes=WARN,SAMESYM,ABSOLUTE,SHARED,UNDEFINED,GC,DISCARD,MISSING2
+
+# WARN-NOT: warning:
+# SAMESYM: warning: {{.*}}.txt: duplicate ordered symbol: _start
+# WARN-NOT: warning:
+# ABSOLUTE: warning: {{.*}}1.o: unable to order absolute symbol: absolute
+# WARN-NOT: warning:
+# DISCARD: warning: {{.*}}1.o: unable to order discarded symbol: discard
+# WARN-NOT: warning:
+# GC: warning: {{.*}}1.o: unable to order discarded symbol: gc
+# WARN-NOT: warning:
+# SHARED: warning: {{.*}}1.o: unable to order shared symbol: shared
+# WARN-NOT: warning:
+# UNDEFINED: warning: {{.*}}3.o: unable to order undefined symbol: undefined
+# WARN-NOT: warning:
+# MISSING: warning: symbol ordering file: no such symbol: missing
+# MISSING2: warning: symbol ordering file: no such symbol: missing_sym
+# COMDAT: warning: {{.*}}1.o: unable to order discarded symbol: comdat
+# COMDAT-NEXT: warning: {{.*}}2.o: unable to order discarded symbol: comdat
+# MULTI: warning: {{.*}}2.o: unable to order absolute symbol: multi
+# MULTI-NEXT: warning: {{.*}}3.o: unable to order undefined symbol: multi
+# WARN-NOT: warning:
+
+absolute = 0x1234
+
+.section .text.gc,"ax", at progbits
+.global gc
+gc:
+ nop
+
+.section .text.discard,"ax", at progbits
+.global discard
+discard:
+ nop
+
+.section .text.comdat,"axG", at progbits,comdat,comdat
+.weak comdat
+comdat:
+ nop
+
+.section .text.glob_or_wk,"ax", at progbits
+.weak glob_or_wk
+glob_or_wk:
+ nop
+
+.text
+.global _start
+_start:
+ movq %rax, absolute
+ callq shared
+
+# This is a "good" instance of the symbol
+multi:
+ nop
More information about the llvm-commits
mailing list