diff options
author | Davide Italiano <davide@freebsd.org> | 2015-10-06 16:20:00 +0000 |
---|---|---|
committer | Davide Italiano <davide@freebsd.org> | 2015-10-06 16:20:00 +0000 |
commit | c39c75dee407b27906d6a418461bb302bc047f08 (patch) | |
tree | 299762fffc0351e877a2d97af2ee4b0489eb37ba | |
parent | 3593739cb273bb304b27ac98916d7b833ed988c1 (diff) | |
download | bcm5719-llvm-c39c75dee407b27906d6a418461bb302bc047f08.tar.gz bcm5719-llvm-c39c75dee407b27906d6a418461bb302bc047f08.zip |
[ELF2] Implement --{enable, disable}-new-dtags options.
llvm-svn: 249428
-rw-r--r-- | lld/ELF/Config.h | 1 | ||||
-rw-r--r-- | lld/ELF/Driver.cpp | 1 | ||||
-rw-r--r-- | lld/ELF/Options.td | 7 | ||||
-rw-r--r-- | lld/ELF/OutputSections.cpp | 14 | ||||
-rw-r--r-- | lld/test/elf2/new-dtags.test | 18 |
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: |