forked from OSchip/llvm-project
[ELF] - Implemented --no-undefined-version flag
Option checks for cases where a version script explicitly lists a symbol, but the symbol is not defined and errors out such cases if any. Differential revision: http://reviews.llvm.org/D21745 llvm-svn: 273998
This commit is contained in:
parent
9c366cdf2a
commit
36b2c0a683
|
@ -86,6 +86,7 @@ struct Configuration {
|
|||
bool Mips64EL = false;
|
||||
bool NoGnuUnique;
|
||||
bool NoUndefined;
|
||||
bool NoUndefinedVersion;
|
||||
bool NoinhibitExec;
|
||||
bool Pic;
|
||||
bool Pie;
|
||||
|
|
|
@ -331,6 +331,7 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) {
|
|||
Config->ICF = Args.hasArg(OPT_icf);
|
||||
Config->NoGnuUnique = Args.hasArg(OPT_no_gnu_unique);
|
||||
Config->NoUndefined = Args.hasArg(OPT_no_undefined);
|
||||
Config->NoUndefinedVersion = Args.hasArg(OPT_no_undefined_version);
|
||||
Config->NoinhibitExec = Args.hasArg(OPT_noinhibit_exec);
|
||||
Config->Pie = Args.hasArg(OPT_pie);
|
||||
Config->PrintGcSections = Args.hasArg(OPT_print_gc_sections);
|
||||
|
|
|
@ -108,6 +108,9 @@ def noinhibit_exec: F<"noinhibit-exec">,
|
|||
def no_undefined: F<"no-undefined">,
|
||||
HelpText<"Report unresolved symbols even if the linker is creating a shared library">;
|
||||
|
||||
def no_undefined_version: F<"no-undefined-version">,
|
||||
HelpText<"Report version scripts that refer undefined symbols">;
|
||||
|
||||
def o: JoinedOrSeparate<["-"], "o">, MetaVarName<"<path>">,
|
||||
HelpText<"Path to file to write output">;
|
||||
|
||||
|
@ -234,7 +237,6 @@ def no_copy_dt_needed_entries: F<"no-copy-dt-needed-entries">,
|
|||
def no_dynamic_linker: F<"no-dynamic-linker">;
|
||||
def no_fatal_warnings: F<"no-fatal-warnings">;
|
||||
def no_mmap_output_file: F<"no-mmap-output-file">;
|
||||
def no_undefined_version: F<"no-undefined-version">;
|
||||
def no_warn_common: F<"no-warn-common">;
|
||||
def no_warn_mismatch: F<"no-warn-mismatch">;
|
||||
def rpath_link: S<"rpath-link">;
|
||||
|
|
|
@ -530,13 +530,20 @@ template <class ELFT> void SymbolTable<ELFT>::scanVersionScript() {
|
|||
// assign version references for each symbol.
|
||||
size_t I = 2;
|
||||
for (Version &V : Config->SymbolVersions) {
|
||||
for (StringRef Name : V.Globals)
|
||||
if (SymbolBody *B = find(Name)) {
|
||||
if (B->symbol()->VersionId != VER_NDX_GLOBAL &&
|
||||
B->symbol()->VersionId != VER_NDX_LOCAL)
|
||||
warning("duplicate symbol " + Name + " in version script");
|
||||
B->symbol()->VersionId = I;
|
||||
for (StringRef Name : V.Globals) {
|
||||
SymbolBody *B = find(Name);
|
||||
if (!B || B->isUndefined()) {
|
||||
if (Config->NoUndefinedVersion)
|
||||
error("version script assignment of " + V.Name + " to symbol " +
|
||||
Name + " failed: symbol not defined");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (B->symbol()->VersionId != VER_NDX_GLOBAL &&
|
||||
B->symbol()->VersionId != VER_NDX_LOCAL)
|
||||
warning("duplicate symbol " + Name + " in version script");
|
||||
B->symbol()->VersionId = I;
|
||||
}
|
||||
++I;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
# REQUIRES: x86
|
||||
|
||||
# RUN: echo "VERSION_1.0{ \
|
||||
# RUN: global: bar; \
|
||||
# RUN: };" > %t.script
|
||||
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
|
||||
# RUN: not ld.lld --version-script %t.script -shared --no-undefined-version \
|
||||
# RUN: %t.o -o %t.so 2>&1 | FileCheck -check-prefix=ERR1 %s
|
||||
# ERR1: version script assignment of VERSION_1.0 to symbol bar failed: symbol not defined
|
||||
|
||||
# RUN: echo "VERSION_1.0{ \
|
||||
# RUN: global: und; \
|
||||
# RUN: };" > %t2.script
|
||||
# RUN: not ld.lld --version-script %t2.script -shared --no-undefined-version \
|
||||
# RUN: %t.o -o %t.so 2>&1 | FileCheck -check-prefix=ERR2 %s
|
||||
# ERR2: version script assignment of VERSION_1.0 to symbol und failed: symbol not defined
|
||||
|
||||
.text
|
||||
.globl foo
|
||||
.type foo,@function
|
||||
foo:
|
||||
callq und@PLT
|
Loading…
Reference in New Issue