summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavide Italiano <davide@freebsd.org>2015-10-06 16:20:00 +0000
committerDavide Italiano <davide@freebsd.org>2015-10-06 16:20:00 +0000
commitc39c75dee407b27906d6a418461bb302bc047f08 (patch)
tree299762fffc0351e877a2d97af2ee4b0489eb37ba
parent3593739cb273bb304b27ac98916d7b833ed988c1 (diff)
downloadbcm5719-llvm-c39c75dee407b27906d6a418461bb302bc047f08.tar.gz
bcm5719-llvm-c39c75dee407b27906d6a418461bb302bc047f08.zip
[ELF2] Implement --{enable, disable}-new-dtags options.
llvm-svn: 249428
-rw-r--r--lld/ELF/Config.h1
-rw-r--r--lld/ELF/Driver.cpp1
-rw-r--r--lld/ELF/Options.td7
-rw-r--r--lld/ELF/OutputSections.cpp14
-rw-r--r--lld/test/elf2/new-dtags.test18
5 files changed, 38 insertions, 3 deletions
diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h
index d9c3a4b43f8..bc5c09e8dfd 100644
--- a/lld/ELF/Config.h
+++ b/lld/ELF/Config.h
@@ -31,6 +31,7 @@ struct Configuration {
bool DiscardAll;
bool DiscardLocals;
bool DiscardNone;
+ bool EnableNewDtags = true;
bool ExportDynamic;
bool NoInhibitExec;
bool NoUndefined;
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 79217648e90..e2c44807b44 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -130,6 +130,7 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
Config->DiscardAll = Args.hasArg(OPT_discard_all);
Config->DiscardLocals = Args.hasArg(OPT_discard_locals);
Config->DiscardNone = Args.hasArg(OPT_discard_none);
+ Config->EnableNewDtags = !Args.hasArg(OPT_disable_new_dtags);
Config->ExportDynamic = Args.hasArg(OPT_export_dynamic);
Config->NoInhibitExec = Args.hasArg(OPT_noinhibit_exec);
Config->NoUndefined = Args.hasArg(OPT_no_undefined);
diff --git a/lld/ELF/Options.td b/lld/ELF/Options.td
index be5107ed1ee..96e7cbc5f4c 100644
--- a/lld/ELF/Options.td
+++ b/lld/ELF/Options.td
@@ -14,6 +14,9 @@ def allow_multiple_definition: Flag<["--"], "allow-multiple-definition">,
def allow_shlib_undefined : Flag<["--", "-"], "allow-shlib-undefined">;
+def disable_new_dtags : Flag<["--"], "disable-new-dtags">,
+ HelpText<"Disable new dynamic tags">;
+
def discard_all : Flag<["-"], "discard-all">,
HelpText<"Delete all local symbols">;
@@ -26,6 +29,9 @@ def discard_none : Flag<["-"], "discard-none">,
def dynamic_linker : Separate<["--", "-"], "dynamic-linker">,
HelpText<"Which dynamic linker to use">;
+def enable_new_dtags : Flag<["--"], "enable-new-dtags">,
+ HelpText<"Enable new dynamic tags">;
+
def entry : Separate<["--", "-"], "entry">, MetaVarName<"<entry>">,
HelpText<"Name of entry point symbol">;
@@ -96,7 +102,6 @@ def O3 : Flag<["-"], "O3">;
def as_needed : Flag<["--"], "as-needed">;
def build_id : Flag<["--"], "build-id">;
def eh_frame_hdr : Flag<["--"], "eh-frame-hdr">;
-def enable_new_dtags : Flag<["--"], "enable-new-dtags">;
def end_group : Flag<["--"], "end-group">;
def gc_sections : Flag<["--"], "gc-sections">;
def hash_style : Joined<["--"], "hash-style=">;
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp
index 9bcfaa6d02d..72776e0d6dc 100644
--- a/lld/ELF/OutputSections.cpp
+++ b/lld/ELF/OutputSections.cpp
@@ -228,7 +228,7 @@ template <class ELFT> void DynamicSection<ELFT>::finalize() {
++NumEntries; // DT_HASH
if (!Config->RPath.empty()) {
- ++NumEntries; // DT_RUNPATH
+ ++NumEntries; // DT_RUNPATH / DT_RPATH
DynStrSec.add(Config->RPath);
}
@@ -294,7 +294,17 @@ template <class ELFT> void DynamicSection<ELFT>::writeTo(uint8_t *Buf) {
WritePtr(DT_HASH, HashSec.getVA());
if (!Config->RPath.empty())
- WriteVal(DT_RUNPATH, DynStrSec.getFileOff(Config->RPath));
+
+ // If --enable-new-dtags is set lld emits DT_RUNPATH
+ // instead of DT_RPATH. The two tags are functionally
+ // equivalent except for the following:
+ // - DT_RUNPATH is searched after LD_LIBRARY_PATH, while
+ // DT_RPATH is searched before.
+ // - DT_RUNPATH is used only to search for direct
+ // dependencies of the object it's contained in, while
+ // DT_RPATH is used for indirect dependencies as well.
+ WriteVal(Config->EnableNewDtags ? DT_RUNPATH : DT_RPATH,
+ DynStrSec.getFileOff(Config->RPath));
if (!Config->SoName.empty())
WriteVal(DT_SONAME, DynStrSec.getFileOff(Config->SoName));
diff --git a/lld/test/elf2/new-dtags.test b/lld/test/elf2/new-dtags.test
new file mode 100644
index 00000000000..ef28bd02607
--- /dev/null
+++ b/lld/test/elf2/new-dtags.test
@@ -0,0 +1,18 @@
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+// RUN: lld -flavor gnu2 %t.o -rpath=/somepath -shared --disable-new-dtags -o %t
+// RUN: lld -flavor gnu2 %t.o -rpath=/somepath -shared --enable-new-dtags -o %t2
+// RUN: llvm-readobj --dynamic-table %t | FileCheck --check-prefix=DISABLE %s
+// RUN: llvm-readobj --dynamic-table %t2 | FileCheck --check-prefix=ENABLE %s
+
+// DISABLE: DynamicSection [
+// DISABLE: 0x000000000000000F RPATH /somepath
+// DISABLE-NOT: RUNPATH
+// DISABLE: ]
+
+// ENABLE: DynamicSection [
+// ENABLE: 0x000000000000001D RUNPATH /somepath
+// ENABLE-NOT: RPATH
+// ENABLE: ]
+
+.global _start
+_start:
OpenPOWER on IntegriCloud