summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeorge Rimar <grimar@accesssoftek.com>2016-07-08 06:47:28 +0000
committerGeorge Rimar <grimar@accesssoftek.com>2016-07-08 06:47:28 +0000
commitc61bcd80af7d8c0f527aa94f5e4eb4ca63d36f0c (patch)
treefbf3b5a3c81bc2d7c925dc7e5e62518774eaa2f7
parentf7bf6de0afc88a919742f8131210526fef3fb19a (diff)
downloadbcm5719-llvm-c61bcd80af7d8c0f527aa94f5e4eb4ca63d36f0c.tar.gz
bcm5719-llvm-c61bcd80af7d8c0f527aa94f5e4eb4ca63d36f0c.zip
[ELF] - Do not error out when version declaration not found when building executable.
When building executable usually version script is absent. Before this patch error was shown in the case when symbol name contained version and there was no script to match it. Instead of error out patch allows to create new version declaration in this case and use it. gnu linkers do the same. That is PR28359. Differential revision: http://reviews.llvm.org/D21890 llvm-svn: 274828
-rw-r--r--lld/ELF/Config.h1
-rw-r--r--lld/ELF/Driver.cpp1
-rw-r--r--lld/ELF/SymbolTable.cpp10
-rw-r--r--lld/test/ELF/verdef-executable.s269
4 files changed, 281 insertions, 0 deletions
diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h
index 3c9c7a1ea62..4e746a5a1ea 100644
--- a/lld/ELF/Config.h
+++ b/lld/ELF/Config.h
@@ -84,6 +84,7 @@ struct Configuration {
bool FatalWarnings;
bool GcSections;
bool GnuHash = false;
+ bool HasVersionScript = false;
bool ICF;
bool Mips64EL = false;
bool NoGnuUnique;
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 5ce2a8c4d14..21357fb8654 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -439,6 +439,7 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) {
Config->DynamicList.push_back(Arg->getValue());
if (auto *Arg = Args.getLastArg(OPT_version_script)) {
+ Config->HasVersionScript = true;
if (Optional<MemoryBufferRef> Buffer = readFile(Arg->getValue()))
parseVersionScript(*Buffer);
}
diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp
index a0ebb0257c5..f01bc94c703 100644
--- a/lld/ELF/SymbolTable.cpp
+++ b/lld/ELF/SymbolTable.cpp
@@ -186,6 +186,16 @@ static uint16_t getVersionId(Symbol *Sym, StringRef Name) {
return Default ? I : (I | VERSYM_HIDDEN);
++I;
}
+
+ // If we are not building shared and version script
+ // is not specified, then it is not a error, it is
+ // in common not to use script for linking executables.
+ // In this case we just create new version.
+ if (!Config->Shared && !Config->HasVersionScript) {
+ Config->SymbolVersions.push_back(elf::Version(Version));
+ return Default ? I : (I | VERSYM_HIDDEN);
+ }
+
error("symbol " + Name + " has undefined version " + Version);
return 0;
}
diff --git a/lld/test/ELF/verdef-executable.s b/lld/test/ELF/verdef-executable.s
new file mode 100644
index 00000000000..9af98da5297
--- /dev/null
+++ b/lld/test/ELF/verdef-executable.s
@@ -0,0 +1,269 @@
+# REQUIRES: x86
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1
+# RUN: ld.lld %t1 -o %t
+# RUN: llvm-readobj -t -V -dyn-symbols %t | FileCheck --check-prefix=EXE %s
+
+# EXE: Symbols [
+# EXE-NEXT: Symbol {
+# EXE-NEXT: Name:
+# EXE-NEXT: Value: 0x0
+# EXE-NEXT: Size: 0
+# EXE-NEXT: Binding: Local
+# EXE-NEXT: Type: None (0x0)
+# EXE-NEXT: Other: 0
+# EXE-NEXT: Section: Undefined (0x0)
+# EXE-NEXT: }
+# EXE-NEXT: Symbol {
+# EXE-NEXT: Name: _start
+# EXE-NEXT: Value: 0x11004
+# EXE-NEXT: Size: 0
+# EXE-NEXT: Binding: Global
+# EXE-NEXT: Type: None
+# EXE-NEXT: Other: 0
+# EXE-NEXT: Section: .text
+# EXE-NEXT: }
+# EXE-NEXT: Symbol {
+# EXE-NEXT: Name: a
+# EXE-NEXT: Value: 0x11000
+# EXE-NEXT: Size: 0
+# EXE-NEXT: Binding: Global
+# EXE-NEXT: Type: Function
+# EXE-NEXT: Other: 0
+# EXE-NEXT: Section: .text
+# EXE-NEXT: }
+# EXE-NEXT: Symbol {
+# EXE-NEXT: Name: b
+# EXE-NEXT: Value: 0x11002
+# EXE-NEXT: Size: 0
+# EXE-NEXT: Binding: Global
+# EXE-NEXT: Type: Function
+# EXE-NEXT: Other: 0
+# EXE-NEXT: Section: .text
+# EXE-NEXT: }
+# EXE-NEXT: Symbol {
+# EXE-NEXT: Name: b
+# EXE-NEXT: Value: 0x11001
+# EXE-NEXT: Size: 0
+# EXE-NEXT: Binding: Global
+# EXE-NEXT: Type: Function
+# EXE-NEXT: Other: 0
+# EXE-NEXT: Section: .text
+# EXE-NEXT: }
+# EXE-NEXT: Symbol {
+# EXE-NEXT: Name: b_1
+# EXE-NEXT: Value: 0x11001
+# EXE-NEXT: Size: 0
+# EXE-NEXT: Binding: Global
+# EXE-NEXT: Type: Function
+# EXE-NEXT: Other: 0
+# EXE-NEXT: Section: .text
+# EXE-NEXT: }
+# EXE-NEXT: Symbol {
+# EXE-NEXT: Name: b_2
+# EXE-NEXT: Value: 0x11002
+# EXE-NEXT: Size: 0
+# EXE-NEXT: Binding: Global
+# EXE-NEXT: Type: Function
+# EXE-NEXT: Other: 0
+# EXE-NEXT: Section: .text
+# EXE-NEXT: }
+# EXE-NEXT: Symbol {
+# EXE-NEXT: Name: c
+# EXE-NEXT: Value: 0x11003
+# EXE-NEXT: Size: 0
+# EXE-NEXT: Binding: Global
+# EXE-NEXT: Type: Function
+# EXE-NEXT: Other: 0
+# EXE-NEXT: Section: .text
+# EXE-NEXT: }
+# EXE-NEXT: ]
+# EXE-NEXT: DynamicSymbols [
+# EXE-NEXT: ]
+# EXE-NEXT: Version symbols {
+# EXE-NEXT: }
+# EXE-NEXT: SHT_GNU_verdef {
+# EXE-NEXT: }
+# EXE-NEXT: SHT_GNU_verneed {
+# EXE-NEXT: }
+
+# RUN: ld.lld -pie --export-dynamic %t1 -o %t2
+# RUN: llvm-readobj -t -V -dyn-symbols %t2 | \
+# RUN: FileCheck --check-prefix=EXEDYN %s
+
+# EXEDYN: DynamicSymbols [
+# EXEDYN-NEXT: Symbol {
+# EXEDYN-NEXT: Name: @
+# EXEDYN-NEXT: Value: 0x0
+# EXEDYN-NEXT: Size: 0
+# EXEDYN-NEXT: Binding: Local
+# EXEDYN-NEXT: Type: None
+# EXEDYN-NEXT: Other: 0
+# EXEDYN-NEXT: Section: Undefined
+# EXEDYN-NEXT: }
+# EXEDYN-NEXT: Symbol {
+# EXEDYN-NEXT: Name: _start@
+# EXEDYN-NEXT: Value: 0x1004
+# EXEDYN-NEXT: Size: 0
+# EXEDYN-NEXT: Binding: Global
+# EXEDYN-NEXT: Type: None
+# EXEDYN-NEXT: Other: 0
+# EXEDYN-NEXT: Section: .text
+# EXEDYN-NEXT: }
+# EXEDYN-NEXT: Symbol {
+# EXEDYN-NEXT: Name: a@
+# EXEDYN-NEXT: Value: 0x1000
+# EXEDYN-NEXT: Size: 0
+# EXEDYN-NEXT: Binding: Global
+# EXEDYN-NEXT: Type: Function
+# EXEDYN-NEXT: Other: 0
+# EXEDYN-NEXT: Section: .text
+# EXEDYN-NEXT: }
+# EXEDYN-NEXT: Symbol {
+# EXEDYN-NEXT: Name: b@@LIBSAMPLE_2.0
+# EXEDYN-NEXT: Value: 0x1002
+# EXEDYN-NEXT: Size: 0
+# EXEDYN-NEXT: Binding: Global
+# EXEDYN-NEXT: Type: Function
+# EXEDYN-NEXT: Other: 0
+# EXEDYN-NEXT: Section: .text
+# EXEDYN-NEXT: }
+# EXEDYN-NEXT: Symbol {
+# EXEDYN-NEXT: Name: b@LIBSAMPLE_1.0
+# EXEDYN-NEXT: Value: 0x1001
+# EXEDYN-NEXT: Size: 0
+# EXEDYN-NEXT: Binding: Global
+# EXEDYN-NEXT: Type: Function
+# EXEDYN-NEXT: Other: 0
+# EXEDYN-NEXT: Section: .text
+# EXEDYN-NEXT: }
+# EXEDYN-NEXT: Symbol {
+# EXEDYN-NEXT: Name: b_1@
+# EXEDYN-NEXT: Value: 0x1001
+# EXEDYN-NEXT: Size: 0
+# EXEDYN-NEXT: Binding: Global
+# EXEDYN-NEXT: Type: Function
+# EXEDYN-NEXT: Other: 0
+# EXEDYN-NEXT: Section: .text
+# EXEDYN-NEXT: }
+# EXEDYN-NEXT: Symbol {
+# EXEDYN-NEXT: Name: b_2@
+# EXEDYN-NEXT: Value: 0x1002
+# EXEDYN-NEXT: Size: 0
+# EXEDYN-NEXT: Binding: Global
+# EXEDYN-NEXT: Type: Function
+# EXEDYN-NEXT: Other: 0
+# EXEDYN-NEXT: Section: .text
+# EXEDYN-NEXT: }
+# EXEDYN-NEXT: Symbol {
+# EXEDYN-NEXT: Name: c@
+# EXEDYN-NEXT: Value: 0x1003
+# EXEDYN-NEXT: Size: 0
+# EXEDYN-NEXT: Binding: Global
+# EXEDYN-NEXT: Type: Function
+# EXEDYN-NEXT: Other: 0
+# EXEDYN-NEXT: Section: .text
+# EXEDYN-NEXT: }
+# EXEDYN-NEXT: ]
+# EXEDYN-NEXT: Version symbols {
+# EXEDYN-NEXT: Section Name: .gnu.version
+# EXEDYN-NEXT: Address: 0x288
+# EXEDYN-NEXT: Offset: 0x288
+# EXEDYN-NEXT: Link: 1
+# EXEDYN-NEXT: Symbols [
+# EXEDYN-NEXT: Symbol {
+# EXEDYN-NEXT: Version: 0
+# EXEDYN-NEXT: Name: @
+# EXEDYN-NEXT: }
+# EXEDYN-NEXT: Symbol {
+# EXEDYN-NEXT: Version: 1
+# EXEDYN-NEXT: Name: _start@
+# EXEDYN-NEXT: }
+# EXEDYN-NEXT: Symbol {
+# EXEDYN-NEXT: Version: 1
+# EXEDYN-NEXT: Name: a@
+# EXEDYN-NEXT: }
+# EXEDYN-NEXT: Symbol {
+# EXEDYN-NEXT: Version: 2
+# EXEDYN-NEXT: Name: b@@LIBSAMPLE_2.0
+# EXEDYN-NEXT: }
+# EXEDYN-NEXT: Symbol {
+# EXEDYN-NEXT: Version: 3
+# EXEDYN-NEXT: Name: b@LIBSAMPLE_1.0
+# EXEDYN-NEXT: }
+# EXEDYN-NEXT: Symbol {
+# EXEDYN-NEXT: Version: 1
+# EXEDYN-NEXT: Name: b_1@
+# EXEDYN-NEXT: }
+# EXEDYN-NEXT: Symbol {
+# EXEDYN-NEXT: Version: 1
+# EXEDYN-NEXT: Name: b_2@
+# EXEDYN-NEXT: }
+# EXEDYN-NEXT: Symbol {
+# EXEDYN-NEXT: Version: 1
+# EXEDYN-NEXT: Name: c@
+# EXEDYN-NEXT: }
+# EXEDYN-NEXT: ]
+# EXEDYN-NEXT: }
+# EXEDYN-NEXT: SHT_GNU_verdef {
+# EXEDYN-NEXT: Definition {
+# EXEDYN-NEXT: Version: 1
+# EXEDYN-NEXT: Flags: Base
+# EXEDYN-NEXT: Index: 1
+# EXEDYN-NEXT: Hash:
+# EXEDYN-NEXT: Name:
+# EXEDYN-NEXT: }
+# EXEDYN-NEXT: Definition {
+# EXEDYN-NEXT: Version: 1
+# EXEDYN-NEXT: Flags: 0x0
+# EXEDYN-NEXT: Index: 2
+# EXEDYN-NEXT: Hash: 98456416
+# EXEDYN-NEXT: Name: LIBSAMPLE_2.0
+# EXEDYN-NEXT: }
+# EXEDYN-NEXT: Definition {
+# EXEDYN-NEXT: Version: 1
+# EXEDYN-NEXT: Flags: 0x0
+# EXEDYN-NEXT: Index: 3
+# EXEDYN-NEXT: Hash: 98457184
+# EXEDYN-NEXT: Name: LIBSAMPLE_1.0
+# EXEDYN-NEXT: }
+# EXEDYN-NEXT: }
+# EXEDYN-NEXT: SHT_GNU_verneed {
+# EXEDYN-NEXT: }
+
+## Check when linking executable that error produced if version script
+## was specified and there are symbols with version in name that
+## is absent in script.
+# RUN: echo "VERSION { \
+# RUN: global: foo; \
+# RUN: local: *; }; " > %t.script
+# RUN: not ld.lld --version-script %t.script %t1 -o %t3 2>&1 | \
+# RUN: FileCheck -check-prefix=ERR %s
+# ERR: symbol b@LIBSAMPLE_1.0 has undefined version LIBSAMPLE_1.0
+
+b@LIBSAMPLE_1.0 = b_1
+b@@LIBSAMPLE_2.0 = b_2
+
+.globl a
+.type a,@function
+a:
+retq
+
+.globl b_1
+.type b_1,@function
+b_1:
+retq
+
+.globl b_2
+.type b_2,@function
+b_2:
+retq
+
+.globl c
+.type c,@function
+c:
+retq
+
+.globl _start
+_start:
+ nop
OpenPOWER on IntegriCloud