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.td4
-rw-r--r--lld/ELF/OutputSections.cpp5
-rw-r--r--lld/test/elf2/now.s19
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:
OpenPOWER on IntegriCloud