summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/ELF/Config.h1
-rw-r--r--lld/ELF/Driver.cpp5
-rw-r--r--lld/ELF/Options.td3
-rw-r--r--lld/ELF/OutputSections.cpp2
-rw-r--r--lld/test/ELF/auxiliary.s12
5 files changed, 23 insertions, 0 deletions
diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h
index 6eec7e1430f..7bf650c3a33 100644
--- a/lld/ELF/Config.h
+++ b/lld/ELF/Config.h
@@ -76,6 +76,7 @@ struct Configuration {
llvm::StringRef Sysroot;
std::string RPath;
std::vector<VersionDefinition> VersionDefinitions;
+ std::vector<llvm::StringRef> AuxiliaryList;
std::vector<llvm::StringRef> DynamicList;
std::vector<llvm::StringRef> SearchPaths;
std::vector<llvm::StringRef> Undefined;
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index c1a6d3f274b..9b44b1ba6c3 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -490,6 +490,11 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) {
Config->OFormatBinary = isOutputFormatBinary(Args);
+ for (auto *Arg : Args.filtered(OPT_auxiliary))
+ Config->AuxiliaryList.push_back(Arg->getValue());
+ if (!Config->Shared && !Config->AuxiliaryList.empty())
+ error("-f may not be used without -shared");
+
for (auto *Arg : Args.filtered(OPT_undefined))
Config->Undefined.push_back(Arg->getValue());
diff --git a/lld/ELF/Options.td b/lld/ELF/Options.td
index b7be00aefa1..acfba9e4612 100644
--- a/lld/ELF/Options.td
+++ b/lld/ELF/Options.td
@@ -7,6 +7,8 @@ class J<string name>: Joined<["--", "-"], name>;
class S<string name>: Separate<["--", "-"], name>;
class JS<string name>: JoinedOrSeparate<["--", "-"], name>;
+def auxiliary: S<"auxiliary">, HelpText<"Set DT_AUXILIARY field to the specified name">;
+
def Bsymbolic: F<"Bsymbolic">, HelpText<"Bind defined symbols locally">;
def Bsymbolic_functions: F<"Bsymbolic-functions">,
@@ -188,6 +190,7 @@ def z: JoinedOrSeparate<["-"], "z">, MetaVarName<"<option>">,
HelpText<"Linker option extensions">;
// Aliases
+def alias_auxiliary: Separate<["-"], "f">, Alias<auxiliary>;
def alias_Bdynamic_call_shared: F<"call_shared">, Alias<Bdynamic>;
def alias_Bdynamic_dy: F<"dy">, Alias<Bdynamic>;
def alias_Bstatic_dn: F<"dn">, Alias<Bstatic>;
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp
index 244b5a1d808..36de1e446ca 100644
--- a/lld/ELF/OutputSections.cpp
+++ b/lld/ELF/OutputSections.cpp
@@ -650,6 +650,8 @@ template <class ELFT> void DynamicSection<ELFT>::finalize() {
// Add strings. We know that these are the last strings to be added to
// DynStrTab and doing this here allows this function to set DT_STRSZ.
+ for (StringRef S : Config->AuxiliaryList)
+ Add({DT_AUXILIARY, Out<ELFT>::DynStrTab->addString(S)});
if (!Config->RPath.empty())
Add({Config->EnableNewDtags ? DT_RUNPATH : DT_RPATH,
Out<ELFT>::DynStrTab->addString(Config->RPath)});
diff --git a/lld/test/ELF/auxiliary.s b/lld/test/ELF/auxiliary.s
new file mode 100644
index 00000000000..236d0a421d4
--- /dev/null
+++ b/lld/test/ELF/auxiliary.s
@@ -0,0 +1,12 @@
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+# RUN: ld.lld %t.o -shared -f aaa --auxiliary bbb -o %t
+# RUN: llvm-readobj --dynamic-table %t | FileCheck %s
+
+# CHECK: DynamicSection [
+# CHECK-NEXT: Tag Type Name/Value
+# CHECK-NEXT: 0x000000007FFFFFFD AUXILIARY Auxiliary library: [aaa]
+# CHECK-NEXT: 0x000000007FFFFFFD AUXILIARY Auxiliary library: [bbb]
+
+# RUN: not ld.lld %t.o -f aaa --auxiliary bbb -o %t 2>&1 \
+# RUN: | FileCheck -check-prefix=ERR %s
+# ERR: -f may not be used without -shared
OpenPOWER on IntegriCloud