ELF2: Add -soname option.
llvm-svn: 249058
diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h
index 2e2c031..03d5c95 100644
--- a/lld/ELF/Config.h
+++ b/lld/ELF/Config.h
@@ -21,6 +21,7 @@
llvm::StringRef DynamicLinker;
llvm::StringRef Entry;
llvm::StringRef OutputFile = "a.out";
+ llvm::StringRef SoName;
llvm::StringRef Sysroot;
std::string RPath;
std::vector<llvm::StringRef> InputSearchPaths;
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index af8144f..f6a0629 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -117,6 +117,9 @@
if (auto *Arg = Args.getLastArg(OPT_entry))
Config->Entry = Arg->getValue();
+ if (auto *Arg = Args.getLastArg(OPT_soname))
+ Config->SoName = Arg->getValue();
+
Config->AllowMultipleDefinition = Args.hasArg(OPT_allow_multiple_definition);
Config->DiscardAll = Args.hasArg(OPT_discard_all);
Config->DiscardLocals = Args.hasArg(OPT_discard_locals);
diff --git a/lld/ELF/Options.td b/lld/ELF/Options.td
index 4d4a84e..3d7be62 100644
--- a/lld/ELF/Options.td
+++ b/lld/ELF/Options.td
@@ -52,6 +52,9 @@
def shared : Flag<["-"], "shared">,
HelpText<"Build a shared object">;
+def soname : Joined<["-"], "soname=">,
+ HelpText<"Set DT_SONAME">;
+
def sysroot : Joined<["--"], "sysroot=">,
HelpText<"Set the system root">;
@@ -69,6 +72,7 @@
def alias_discard_locals: Flag<["-"], "X">, Alias<discard_locals>;
def alias_entry : Separate<["-"], "e">, Alias<entry>;
def alias_l : Joined<["--"], "library=">, Alias<l>;
+def alias_soname : Separate<["-"], "h">, Alias<soname>;
// Options listed below are silently ignored now.
def as_needed : Flag<["--"], "as-needed">;
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp
index 1382cd7..ad58e75 100644
--- a/lld/ELF/OutputSections.cpp
+++ b/lld/ELF/OutputSections.cpp
@@ -198,10 +198,14 @@
++NumEntries; // DT_STRSZ
++NumEntries; // DT_HASH
- StringRef RPath = Config->RPath;
- if (!RPath.empty()) {
+ if (!Config->RPath.empty()) {
++NumEntries; // DT_RUNPATH
- DynStrSec.add(RPath);
+ DynStrSec.add(Config->RPath);
+ }
+
+ if (!Config->SoName.empty()) {
+ ++NumEntries; // DT_SONAME
+ DynStrSec.add(Config->SoName);
}
const std::vector<std::unique_ptr<SharedFileBase>> &SharedFiles =
@@ -255,10 +259,15 @@
P->d_un.d_ptr = HashSec.getVA();
++P;
- StringRef RPath = Config->RPath;
- if (!RPath.empty()) {
+ if (!Config->RPath.empty()) {
P->d_tag = DT_RUNPATH;
- P->d_un.d_val = DynStrSec.getFileOff(RPath);
+ P->d_un.d_val = DynStrSec.getFileOff(Config->RPath);
+ ++P;
+ }
+
+ if (!Config->SoName.empty()) {
+ P->d_tag = DT_SONAME;
+ P->d_un.d_val = DynStrSec.getFileOff(Config->SoName);
++P;
}
diff --git a/lld/test/elf2/soname2.s b/lld/test/elf2/soname2.s
new file mode 100644
index 0000000..3c75745
--- /dev/null
+++ b/lld/test/elf2/soname2.s
@@ -0,0 +1,8 @@
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+// RUN: lld -flavor gnu2 %t.o -shared -soname=foo.so -o %t
+// RUN: llvm-readobj --dynamic-table %t | FileCheck %s
+
+// CHECK: 0x000000000000000E SONAME LibrarySoname (foo.so)
+
+.global _start
+_start: