summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRui Ueyama <ruiu@google.com>2016-04-07 20:41:41 +0000
committerRui Ueyama <ruiu@google.com>2016-04-07 20:41:41 +0000
commit8c76487ee5526ae81dc442b41abb2a785453c31d (patch)
tree19d8765cffce4bee1ced5bcda729813e7338bf89
parentd4131814b3117c00c3eb2b0dc30b6a03297421f4 (diff)
downloadbcm5719-llvm-8c76487ee5526ae81dc442b41abb2a785453c31d.tar.gz
bcm5719-llvm-8c76487ee5526ae81dc442b41abb2a785453c31d.zip
ELF: Add --no-gnu-unique option.
When the option is specified, then all STB_GNU_UNIQUE symbols are converted to STB_GLOBAL symbols. llvm-svn: 265717
-rw-r--r--lld/ELF/Config.h1
-rw-r--r--lld/ELF/Driver.cpp1
-rw-r--r--lld/ELF/Options.td3
-rw-r--r--lld/ELF/OutputSections.cpp2
-rw-r--r--lld/test/ELF/gnu-unique.s33
5 files changed, 30 insertions, 10 deletions
diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h
index ea94f88f2ba..8c48996aaa6 100644
--- a/lld/ELF/Config.h
+++ b/lld/ELF/Config.h
@@ -67,6 +67,7 @@ struct Configuration {
bool GnuHash = false;
bool ICF;
bool Mips64EL = false;
+ bool NoGnuUnique;
bool NoUndefined;
bool NoinhibitExec;
bool Pic;
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index ab3335bb900..72e4bae505d 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -282,6 +282,7 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) {
Config->ExportDynamic = Args.hasArg(OPT_export_dynamic);
Config->GcSections = Args.hasArg(OPT_gc_sections);
Config->ICF = Args.hasArg(OPT_icf);
+ Config->NoGnuUnique = Args.hasArg(OPT_no_gnu_unique);
Config->NoUndefined = Args.hasArg(OPT_no_undefined);
Config->NoinhibitExec = Args.hasArg(OPT_noinhibit_exec);
Config->Pie = Args.hasArg(OPT_pie);
diff --git a/lld/ELF/Options.td b/lld/ELF/Options.td
index 8b72fcacf68..b1881f21fab 100644
--- a/lld/ELF/Options.td
+++ b/lld/ELF/Options.td
@@ -91,6 +91,9 @@ def no_as_needed : Flag<["--"], "no-as-needed">;
def no_demangle: Flag<["--"], "no-demangle">,
HelpText<"Do not demangle symbol names">;
+def no_gnu_unique : Flag<["--"], "no-gnu-unique">,
+ HelpText<"Disable STB_GNU_UNIQUE symbol binding">;
+
def no_whole_archive : Flag<["--", "-"], "no-whole-archive">,
HelpText<"Restores the default behavior of loading archive members">;
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp
index f79a1d3a923..9d00caf41e7 100644
--- a/lld/ELF/OutputSections.cpp
+++ b/lld/ELF/OutputSections.cpp
@@ -1515,6 +1515,8 @@ uint8_t SymbolTableSection<ELFT>::getSymbolBinding(SymbolBody *Body) {
uint8_t Visibility = Body->getVisibility();
if (Visibility != STV_DEFAULT && Visibility != STV_PROTECTED)
return STB_LOCAL;
+ if (Config->NoGnuUnique && Body->Binding == STB_GNU_UNIQUE)
+ return STB_GLOBAL;
return Body->Binding;
}
diff --git a/lld/test/ELF/gnu-unique.s b/lld/test/ELF/gnu-unique.s
index f7206cf8c97..afc0da27063 100644
--- a/lld/test/ELF/gnu-unique.s
+++ b/lld/test/ELF/gnu-unique.s
@@ -1,7 +1,11 @@
+// REQUIRES: x86
// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
+//
// RUN: ld.lld %t -shared -o %tout.so
-// RUN: llvm-readobj -dyn-symbols %tout.so | FileCheck %s
-// REQUIRES: x86
+// RUN: llvm-readobj -dyn-symbols %tout.so | FileCheck -check-prefix=GNU %s
+//
+// RUN: ld.lld %t -shared -o %tout.so --no-gnu-unique
+// RUN: llvm-readobj -dyn-symbols %tout.so | FileCheck -check-prefix=NO %s
// Check that STB_GNU_UNIQUE is treated as a global and ends up in the dynamic
// symbol table as STB_GNU_UNIQUE.
@@ -14,11 +18,20 @@ _start:
.type symb, @gnu_unique_object
symb:
-# CHECK: Name: symb@
-# CHECK-NEXT: Value:
-# CHECK-NEXT: Size: 0
-# CHECK-NEXT: Binding: Unique
-# CHECK-NEXT: Type: Object
-# CHECK-NEXT: Other: 0
-# CHECK-NEXT: Section: .data
-# CHECK-NEXT: }
+# GNU: Name: symb@
+# GNU-NEXT: Value:
+# GNU-NEXT: Size: 0
+# GNU-NEXT: Binding: Unique
+# GNU-NEXT: Type: Object
+# GNU-NEXT: Other: 0
+# GNU-NEXT: Section: .data
+# GNU-NEXT: }
+
+# NO: Name: symb@
+# NO-NEXT: Value:
+# NO-NEXT: Size: 0
+# NO-NEXT: Binding: Global
+# NO-NEXT: Type: Object
+# NO-NEXT: Other: 0
+# NO-NEXT: Section: .data
+# NO-NEXT: }
OpenPOWER on IntegriCloud