Fix and simplify the reporting of undefined symbols.
Now reportUndefined only has to look at Config->UnresolvedSymbols and the symbol. getUnresolvedSymbolOption does all the hard work of mapping options like -shared and -z defs to one of the UnresolvedPolicy enum entries. The critical fix is that now "-z defs --warn-unresolved-symbols" only warns. llvm-svn: 293290
This commit is contained in:
parent
095d6b8f99
commit
403b093eff
|
@ -41,7 +41,7 @@ enum class DiscardPolicy { Default, All, Locals, None };
|
|||
enum class StripPolicy { None, All, Debug };
|
||||
|
||||
// For --unresolved-symbols.
|
||||
enum class UnresolvedPolicy { NoUndef, ReportError, Warn, Ignore };
|
||||
enum class UnresolvedPolicy { ReportError, Warn, WarnAll, Ignore, IgnoreAll };
|
||||
|
||||
// For --sort-section and linkerscript sorting rules.
|
||||
enum class SortSectionPolicy { Default, None, Alignment, Name, Priority };
|
||||
|
|
|
@ -350,29 +350,39 @@ void LinkerDriver::main(ArrayRef<const char *> ArgsArr, bool CanExitEarly) {
|
|||
}
|
||||
|
||||
static UnresolvedPolicy getUnresolvedSymbolOption(opt::InputArgList &Args) {
|
||||
// Find the last of --unresolved-symbols, --no-undefined and -z defs.
|
||||
bool UnresolvedSymbolIsIgnoreAll = false;
|
||||
bool ZDefs = false;
|
||||
for (auto *Arg : Args) {
|
||||
unsigned ID = Arg->getOption().getID();
|
||||
if (ID == OPT_unresolved_symbols) {
|
||||
StringRef S = Arg->getValue();
|
||||
if (S == "ignore-all" || S == "ignore-in-object-files") {
|
||||
ZDefs = false;
|
||||
UnresolvedSymbolIsIgnoreAll = true;
|
||||
} else if (S != "ignore-in-shared-libs" && S != "report-all") {
|
||||
error("unknown --unresolved-symbols value: " + S);
|
||||
}
|
||||
} else if (ID == OPT_no_undefined ||
|
||||
(ID == OPT_z && Arg->getValue() == StringRef("defs"))) {
|
||||
ZDefs = true;
|
||||
UnresolvedSymbolIsIgnoreAll = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (Args.hasArg(OPT_noinhibit_exec))
|
||||
return UnresolvedPolicy::Warn;
|
||||
if (Args.hasArg(OPT_no_undefined) || hasZOption(Args, "defs"))
|
||||
return UnresolvedPolicy::NoUndef;
|
||||
return UnresolvedPolicy::WarnAll;
|
||||
if (Config->Relocatable)
|
||||
return UnresolvedPolicy::Ignore;
|
||||
|
||||
if (auto *Arg = Args.getLastArg(OPT_warn_undef, OPT_error_undef)) {
|
||||
if (Arg->getOption().getID() == OPT_warn_undef)
|
||||
return UnresolvedPolicy::Warn;
|
||||
return UnresolvedPolicy::IgnoreAll;
|
||||
|
||||
if (ZDefs || (!Config->Shared && !UnresolvedSymbolIsIgnoreAll)) {
|
||||
if (auto *Arg = Args.getLastArg(OPT_warn_undef, OPT_error_undef))
|
||||
if (Arg->getOption().getID() == OPT_warn_undef)
|
||||
return UnresolvedPolicy::Warn;
|
||||
return UnresolvedPolicy::ReportError;
|
||||
}
|
||||
|
||||
if (auto *Arg = Args.getLastArg(OPT_unresolved_symbols)) {
|
||||
StringRef S = Arg->getValue();
|
||||
if (S == "ignore-all" || S == "ignore-in-object-files")
|
||||
return UnresolvedPolicy::Ignore;
|
||||
if (S == "ignore-in-shared-libs" || S == "report-all")
|
||||
return UnresolvedPolicy::ReportError;
|
||||
error("unknown --unresolved-symbols value: " + S);
|
||||
}
|
||||
return UnresolvedPolicy::ReportError;
|
||||
return UnresolvedPolicy::Ignore;
|
||||
}
|
||||
|
||||
static Target2Policy getTarget2Option(opt::InputArgList &Args) {
|
||||
|
|
|
@ -555,17 +555,17 @@ static typename ELFT::uint computeAddend(const elf::ObjectFile<ELFT> &File,
|
|||
template <class ELFT>
|
||||
static void reportUndefined(SymbolBody &Sym, InputSectionBase<ELFT> &S,
|
||||
typename ELFT::uint Offset) {
|
||||
if (Config->UnresolvedSymbols == UnresolvedPolicy::Ignore)
|
||||
return;
|
||||
|
||||
if (Config->Shared && Sym.symbol()->Visibility == STV_DEFAULT &&
|
||||
Config->UnresolvedSymbols != UnresolvedPolicy::NoUndef)
|
||||
bool CanBeExternal = Sym.symbol()->computeBinding() != STB_LOCAL &&
|
||||
Sym.getVisibility() == STV_DEFAULT;
|
||||
if (Config->UnresolvedSymbols == UnresolvedPolicy::IgnoreAll ||
|
||||
(Config->UnresolvedSymbols == UnresolvedPolicy::Ignore && CanBeExternal))
|
||||
return;
|
||||
|
||||
std::string Msg =
|
||||
S.getLocation(Offset) + ": undefined symbol '" + toString(Sym) + "'";
|
||||
|
||||
if (Config->UnresolvedSymbols == UnresolvedPolicy::Warn)
|
||||
if (Config->UnresolvedSymbols == UnresolvedPolicy::WarnAll ||
|
||||
(Config->UnresolvedSymbols == UnresolvedPolicy::Warn && CanBeExternal))
|
||||
warn(Msg);
|
||||
else
|
||||
error(Msg);
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
# REQUIRES: x86
|
||||
# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
|
||||
# RUN: not ld.lld -shared %t.o -o %t.so -z defs --warn-unresolved-symbols 2>&1| FileCheck %s
|
||||
|
||||
# CHECK: warning: {{.*}}: undefined symbol 'foo'
|
||||
# CHECK: error: {{.*}}: undefined symbol 'bar'
|
||||
# CHECK: error: {{.*}}: undefined symbol 'zed'
|
||||
|
||||
.data
|
||||
.quad foo
|
||||
.hidden bar
|
||||
.quad bar
|
||||
.protected zed
|
||||
.quad zed
|
Loading…
Reference in New Issue