diff options
-rw-r--r-- | lld/ELF/Config.h | 1 | ||||
-rw-r--r-- | lld/ELF/Driver.cpp | 5 | ||||
-rw-r--r-- | lld/ELF/Options.td | 4 | ||||
-rw-r--r-- | lld/ELF/OutputSections.cpp | 5 | ||||
-rw-r--r-- | lld/test/elf2/now.s | 19 |
5 files changed, 33 insertions, 1 deletions
diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h index 503079f80a1..920b1165b85 100644 --- a/lld/ELF/Config.h +++ b/lld/ELF/Config.h @@ -44,6 +44,7 @@ struct Configuration { bool ExportDynamic; bool NoInhibitExec; bool NoUndefined; + bool ZNow = false; bool Shared; bool Static = false; bool WholeArchive = false; diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index a8170b10305..b27022c10a8 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -186,6 +186,11 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { Config->NoUndefined = Args.hasArg(OPT_no_undefined); Config->Shared = Args.hasArg(OPT_shared); + for (auto *Arg : Args.filtered(OPT_z)) { + if (Arg->getValue() == StringRef("now")) + Config->ZNow = true; + } + for (auto *Arg : Args) { switch (Arg->getOption().getID()) { case OPT_l: diff --git a/lld/ELF/Options.td b/lld/ELF/Options.td index 12205ff9154..dfa6dd69e74 100644 --- a/lld/ELF/Options.td +++ b/lld/ELF/Options.td @@ -82,6 +82,9 @@ def undefined : Joined<["--"], "undefined=">, def whole_archive : Flag<["--"], "whole-archive">, HelpText<"Force load of all members in a static library">; +def z : JoinedOrSeparate<["-"], "z">, MetaVarName<"<option>">, + HelpText<"Linker option extensions">; + // Aliases def alias_Bdynamic_call_shared: Flag<["-"], "call_shared">, Alias<Bdynamic>; def alias_Bdynamic_dy: Flag<["-"], "dy">, Alias<Bdynamic>; @@ -114,4 +117,3 @@ def no_fatal_warnings : Flag<["--"], "no-fatal-warnings">; def start_group : Flag<["--"], "start-group">; def strip_all : Flag<["--"], "strip-all">; def version_script : Separate<["--"], "version-script">; -def z : Separate<["-"], "z">; diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp index 1640c0c44c0..eb33444be72 100644 --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -269,6 +269,8 @@ template <class ELFT> void DynamicSection<ELFT>::finalize() { ++NumEntries; // DT_INIT if (FiniSym) ++NumEntries; // DT_FINI + if (Config->ZNow) + ++NumEntries; // DT_FLAGS_1 ++NumEntries; // DT_NULL @@ -341,6 +343,9 @@ template <class ELFT> void DynamicSection<ELFT>::writeTo(uint8_t *Buf) { if (FiniSym) WritePtr(DT_FINI, getSymVA(*FiniSym, BssSec)); + if (Config->ZNow) + WriteVal(DT_FLAGS_1, DF_1_NOW); + WriteVal(DT_NULL, 0); } diff --git a/lld/test/elf2/now.s b/lld/test/elf2/now.s new file mode 100644 index 00000000000..54d1274596c --- /dev/null +++ b/lld/test/elf2/now.s @@ -0,0 +1,19 @@ +# REQUIRES: x86 + +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +# RUN: lld -flavor gnu2 -shared %t -o %t.so +# RUN: lld -flavor gnu2 -z now %t %t.so -o %t1 +# RUN: lld -flavor gnu2 %t %t.so -o %t2 +# RUN: llvm-readobj -dynamic-table %t1 | FileCheck -check-prefix=NOW %s +# RUN: llvm-readobj -dynamic-table %t2 | FileCheck %s + +# NOW: DynamicSection [ +# NOW: 0x000000006FFFFFFB FLAGS_1 NOW +# NOW: ] + +# CHECK: DynamicSection [ +# CHECK-NOT: 0x000000006FFFFFFB FLAGS_1 NOW +# CHECK: ] + +.globl _start +_start: |