-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[ELF] Implement -z dynamic-undefined-weak #143831
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[ELF] Implement -z dynamic-undefined-weak #143831
Conversation
Created using spr 1.3.5-bogner
@llvm/pr-subscribers-lld-elf Author: Fangrui Song (MaskRay) ChangesThe behavior of an undefined weak reference is implementation defined. Dynamic -no-pie linking and -pie allow flexibility. Changes adjust the This patch implements -z [no]dynamic-undefined-weak option to fine-tune
The -pie behavior likely stays stable while -no-pie ( Documentation in ld.lld.1 has not been updated yet, as the behavior is Full diff: https://github.com/llvm/llvm-project/pull/143831.diff 7 Files Affected:
diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h
index 0a52dfe6901bd..3a9001d2cc8b8 100644
--- a/lld/ELF/Config.h
+++ b/lld/ELF/Config.h
@@ -368,6 +368,7 @@ struct Config {
bool writeAddends;
bool zCombreloc;
bool zCopyreloc;
+ bool zDynamicUndefined;
bool zForceBti;
bool zForceIbt;
bool zGlobal;
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 12dac82c614a7..87b19cf543d9f 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -591,6 +591,7 @@ static void checkZOptions(Ctx &ctx, opt::InputArgList &args) {
args::getZOptionValue(args, OPT_z, "max-page-size", 0);
args::getZOptionValue(args, OPT_z, "common-page-size", 0);
getZFlag(args, "rel", "rela", false);
+ getZFlag(args, "dynamic-undefined-weak", "nodynamic-undefined-weak", false);
for (auto *arg : args.filtered(OPT_z))
if (!arg->isClaimed())
Warn(ctx) << "unknown -z value: " << StringRef(arg->getValue());
@@ -3058,6 +3059,13 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
ctx.hasDynsym = !ctx.sharedFiles.empty() || ctx.arg.isPic;
ctx.arg.exportDynamic &= ctx.hasDynsym;
+ // Preemptibility of undefined symbols when ctx.hasDynsym is true. Default is
+ // true for dynamic linking.
+ ctx.arg.zDynamicUndefined =
+ getZFlag(args, "dynamic-undefined-weak", "nodynamic-undefined-weak",
+ ctx.sharedFiles.size() || ctx.arg.shared) &&
+ ctx.hasDynsym;
+
// If an entry symbol is in a static archive, pull out that file now.
if (Symbol *sym = ctx.symtab->find(ctx.arg.entry))
handleUndefined(ctx, sym, "--entry");
diff --git a/lld/ELF/Symbols.cpp b/lld/ELF/Symbols.cpp
index c461dfed0d741..de839795c50d7 100644
--- a/lld/ELF/Symbols.cpp
+++ b/lld/ELF/Symbols.cpp
@@ -333,10 +333,13 @@ bool elf::computeIsPreemptible(Ctx &ctx, const Symbol &sym) {
if (sym.visibility() != STV_DEFAULT)
return false;
- // At this point copy relocations have not been created yet, so any
- // symbol that is not defined locally is preemptible.
+ // At this point copy relocations have not been created yet.
+ // Shared symbols are preemptible. Undefined symbols are preemptible
+ // when zDynamicUndefined (default in dynamic linking). Weakness is not
+ // checked, though undefined non-weak would typically trigger relocation
+ // errors unless options like -z undefs are used.
if (!sym.isDefined())
- return true;
+ return !sym.isUndefined() || ctx.arg.zDynamicUndefined;
if (!ctx.arg.shared)
return false;
@@ -360,7 +363,6 @@ void elf::parseVersionAndComputeIsPreemptible(Ctx &ctx) {
// can contain versions in the form of <name>@<version>.
// Let them parse and update their names to exclude version suffix.
// In addition, compute isExported and isPreemptible.
- bool maybePreemptible = ctx.sharedFiles.size() || ctx.arg.shared;
for (Symbol *sym : ctx.symtab->getSymbols()) {
if (sym->hasVersionSuffix)
sym->parseSymbolVersion(ctx);
@@ -369,11 +371,11 @@ void elf::parseVersionAndComputeIsPreemptible(Ctx &ctx) {
continue;
}
if (!sym->isDefined() && !sym->isCommon()) {
- sym->isPreemptible = maybePreemptible && computeIsPreemptible(ctx, *sym);
+ sym->isPreemptible = computeIsPreemptible(ctx, *sym);
} else if (ctx.arg.exportDynamic &&
(sym->isUsedInRegularObj || !sym->ltoCanOmit)) {
sym->isExported = true;
- sym->isPreemptible = maybePreemptible && computeIsPreemptible(ctx, *sym);
+ sym->isPreemptible = computeIsPreemptible(ctx, *sym);
}
}
}
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index 10dc688160d1e..f430f4e59a3fc 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -285,7 +285,6 @@ static void demoteDefined(Defined &sym, DenseMap<SectionBase *, size_t> &map) {
static void demoteSymbolsAndComputeIsPreemptible(Ctx &ctx) {
llvm::TimeTraceScope timeScope("Demote symbols");
DenseMap<InputFile *, DenseMap<SectionBase *, size_t>> sectionIndexMap;
- bool maybePreemptible = ctx.sharedFiles.size() || ctx.arg.shared;
for (Symbol *sym : ctx.symtab->getSymbols()) {
if (auto *d = dyn_cast<Defined>(sym)) {
if (d->section && !d->section->isLive())
@@ -301,9 +300,8 @@ static void demoteSymbolsAndComputeIsPreemptible(Ctx &ctx) {
}
}
- if (maybePreemptible)
- sym->isPreemptible = (sym->isUndefined() || sym->isExported) &&
- computeIsPreemptible(ctx, *sym);
+ sym->isPreemptible = (sym->isUndefined() || sym->isExported) &&
+ computeIsPreemptible(ctx, *sym);
}
}
diff --git a/lld/test/ELF/driver.test b/lld/test/ELF/driver.test
index 45d73607c8ac6..6d5761212cc38 100644
--- a/lld/test/ELF/driver.test
+++ b/lld/test/ELF/driver.test
@@ -47,7 +47,8 @@
# ERR9: error: cannot open output file utput=/no/such/file
# RUN: ld.lld %t -z foo -o /dev/null 2>&1 | FileCheck -check-prefix=ERR10 %s --implicit-check-not=warning:
-# RUN: ld.lld %t -z foo -z rel -z rela -z max-page-size=1 -z common-page-size=1 -o /dev/null --version 2>&1 | \
+# RUN: ld.lld %t -z foo -z rel -z rela -z max-page-size=1 -z common-page-size=1 -z dynamic-undefined-weak \
+# RUN: -z nodynamic-undefined-weak -o /dev/null --version 2>&1 | \
# RUN: FileCheck -check-prefix=ERR10 %s --implicit-check-not=warning:
# ERR10: warning: unknown -z value: foo
diff --git a/lld/test/ELF/weak-undef-got-plt.s b/lld/test/ELF/weak-undef-got-plt.s
index 0ee3da2cd3b40..48a7914e5b987 100644
--- a/lld/test/ELF/weak-undef-got-plt.s
+++ b/lld/test/ELF/weak-undef-got-plt.s
@@ -6,11 +6,17 @@
# RUN: ld.lld a.o -o a
# RUN: llvm-readelf -r a | FileCheck %s --check-prefix=NORELOC
+# RUN: ld.lld a.o -o a -z dynamic-undefined-weak
+# RUN: llvm-readelf -r a | FileCheck %s --check-prefix=NORELOC
# RUN: ld.lld a.o s.so -o as
# RUN: llvm-objdump -dR as | FileCheck %s
+# RUN: ld.lld a.o s.so -o as -z nodynamic-undefined-weak
+# RUN: llvm-readelf -r a | FileCheck %s --check-prefix=NORELOC
# RUN: ld.lld -pie a.o s.so -o as.pie
# RUN: llvm-objdump -dR as.pie | FileCheck %s
+# RUN: ld.lld -pie a.o s.so -o as.pie -z nodynamic-undefined-weak
+# RUN: llvm-readelf -r as.pie | FileCheck --check-prefix=NORELOC %s
# RUN: ld.lld -shared a.o -o a.so
# RUN: llvm-objdump -dR a.so | FileCheck %s
diff --git a/lld/test/ELF/weak-undef-rw.s b/lld/test/ELF/weak-undef-rw.s
index 497228a3cf905..8d777669b7e16 100644
--- a/lld/test/ELF/weak-undef-rw.s
+++ b/lld/test/ELF/weak-undef-rw.s
@@ -18,9 +18,22 @@
## gABI leaves the behavior of weak undefined references implementation defined.
## We choose to resolve them statically for static linking and produce dynamic relocations
## for dynamic linking (-shared or at least one input DSO).
-##
-## Note: Some ports of GNU ld support -z nodynamic-undefined-weak that we don't
-## implement.
+
+## -z dynamic-undefined-weak is ignored if .dynsym is absent (-no-pie without DSO)
+# RUN: ld.lld a.o -o a.d -z dynamic-undefined-weak 2>&1 | count 0
+# RUN: llvm-readelf -r --hex-dump=.data a.d | FileCheck %s --check-prefix=STATIC
+
+## Currently no effect for S+A relocations.
+# RUN: ld.lld a.o s.so -o as.d -z dynamic-undefined-weak
+# RUN: llvm-readelf -r --hex-dump=.data as.d | FileCheck %s --check-prefix=STATIC
+
+## -z dynamic-undefined-weak forces dynamic relocations if .dynsym is present.
+# RUN: ld.lld a.o -o a.pie.d -pie -z dynamic-undefined-weak
+# RUN: llvm-readelf -r a.pie.d | FileCheck %s --check-prefix=DYN
+
+## -z nodynamic-undefined-weak suppresses dynamic relocations.
+# RUN: ld.lld a.o -o a.so.n -shared -z dynamic-undefined-weak -z nodynamic-undefined-weak
+# RUN: llvm-readelf -r --hex-dump=.data a.so.n | FileCheck %s --check-prefix=STATIC
# STATIC: no relocations
# STATIC: Hex dump of section '.data':
|
@llvm/pr-subscribers-lld Author: Fangrui Song (MaskRay) ChangesThe behavior of an undefined weak reference is implementation defined. Dynamic -no-pie linking and -pie allow flexibility. Changes adjust the This patch implements -z [no]dynamic-undefined-weak option to fine-tune
The -pie behavior likely stays stable while -no-pie ( Documentation in ld.lld.1 has not been updated yet, as the behavior is Full diff: https://github.com/llvm/llvm-project/pull/143831.diff 7 Files Affected:
diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h
index 0a52dfe6901bd..3a9001d2cc8b8 100644
--- a/lld/ELF/Config.h
+++ b/lld/ELF/Config.h
@@ -368,6 +368,7 @@ struct Config {
bool writeAddends;
bool zCombreloc;
bool zCopyreloc;
+ bool zDynamicUndefined;
bool zForceBti;
bool zForceIbt;
bool zGlobal;
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 12dac82c614a7..87b19cf543d9f 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -591,6 +591,7 @@ static void checkZOptions(Ctx &ctx, opt::InputArgList &args) {
args::getZOptionValue(args, OPT_z, "max-page-size", 0);
args::getZOptionValue(args, OPT_z, "common-page-size", 0);
getZFlag(args, "rel", "rela", false);
+ getZFlag(args, "dynamic-undefined-weak", "nodynamic-undefined-weak", false);
for (auto *arg : args.filtered(OPT_z))
if (!arg->isClaimed())
Warn(ctx) << "unknown -z value: " << StringRef(arg->getValue());
@@ -3058,6 +3059,13 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
ctx.hasDynsym = !ctx.sharedFiles.empty() || ctx.arg.isPic;
ctx.arg.exportDynamic &= ctx.hasDynsym;
+ // Preemptibility of undefined symbols when ctx.hasDynsym is true. Default is
+ // true for dynamic linking.
+ ctx.arg.zDynamicUndefined =
+ getZFlag(args, "dynamic-undefined-weak", "nodynamic-undefined-weak",
+ ctx.sharedFiles.size() || ctx.arg.shared) &&
+ ctx.hasDynsym;
+
// If an entry symbol is in a static archive, pull out that file now.
if (Symbol *sym = ctx.symtab->find(ctx.arg.entry))
handleUndefined(ctx, sym, "--entry");
diff --git a/lld/ELF/Symbols.cpp b/lld/ELF/Symbols.cpp
index c461dfed0d741..de839795c50d7 100644
--- a/lld/ELF/Symbols.cpp
+++ b/lld/ELF/Symbols.cpp
@@ -333,10 +333,13 @@ bool elf::computeIsPreemptible(Ctx &ctx, const Symbol &sym) {
if (sym.visibility() != STV_DEFAULT)
return false;
- // At this point copy relocations have not been created yet, so any
- // symbol that is not defined locally is preemptible.
+ // At this point copy relocations have not been created yet.
+ // Shared symbols are preemptible. Undefined symbols are preemptible
+ // when zDynamicUndefined (default in dynamic linking). Weakness is not
+ // checked, though undefined non-weak would typically trigger relocation
+ // errors unless options like -z undefs are used.
if (!sym.isDefined())
- return true;
+ return !sym.isUndefined() || ctx.arg.zDynamicUndefined;
if (!ctx.arg.shared)
return false;
@@ -360,7 +363,6 @@ void elf::parseVersionAndComputeIsPreemptible(Ctx &ctx) {
// can contain versions in the form of <name>@<version>.
// Let them parse and update their names to exclude version suffix.
// In addition, compute isExported and isPreemptible.
- bool maybePreemptible = ctx.sharedFiles.size() || ctx.arg.shared;
for (Symbol *sym : ctx.symtab->getSymbols()) {
if (sym->hasVersionSuffix)
sym->parseSymbolVersion(ctx);
@@ -369,11 +371,11 @@ void elf::parseVersionAndComputeIsPreemptible(Ctx &ctx) {
continue;
}
if (!sym->isDefined() && !sym->isCommon()) {
- sym->isPreemptible = maybePreemptible && computeIsPreemptible(ctx, *sym);
+ sym->isPreemptible = computeIsPreemptible(ctx, *sym);
} else if (ctx.arg.exportDynamic &&
(sym->isUsedInRegularObj || !sym->ltoCanOmit)) {
sym->isExported = true;
- sym->isPreemptible = maybePreemptible && computeIsPreemptible(ctx, *sym);
+ sym->isPreemptible = computeIsPreemptible(ctx, *sym);
}
}
}
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index 10dc688160d1e..f430f4e59a3fc 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -285,7 +285,6 @@ static void demoteDefined(Defined &sym, DenseMap<SectionBase *, size_t> &map) {
static void demoteSymbolsAndComputeIsPreemptible(Ctx &ctx) {
llvm::TimeTraceScope timeScope("Demote symbols");
DenseMap<InputFile *, DenseMap<SectionBase *, size_t>> sectionIndexMap;
- bool maybePreemptible = ctx.sharedFiles.size() || ctx.arg.shared;
for (Symbol *sym : ctx.symtab->getSymbols()) {
if (auto *d = dyn_cast<Defined>(sym)) {
if (d->section && !d->section->isLive())
@@ -301,9 +300,8 @@ static void demoteSymbolsAndComputeIsPreemptible(Ctx &ctx) {
}
}
- if (maybePreemptible)
- sym->isPreemptible = (sym->isUndefined() || sym->isExported) &&
- computeIsPreemptible(ctx, *sym);
+ sym->isPreemptible = (sym->isUndefined() || sym->isExported) &&
+ computeIsPreemptible(ctx, *sym);
}
}
diff --git a/lld/test/ELF/driver.test b/lld/test/ELF/driver.test
index 45d73607c8ac6..6d5761212cc38 100644
--- a/lld/test/ELF/driver.test
+++ b/lld/test/ELF/driver.test
@@ -47,7 +47,8 @@
# ERR9: error: cannot open output file utput=/no/such/file
# RUN: ld.lld %t -z foo -o /dev/null 2>&1 | FileCheck -check-prefix=ERR10 %s --implicit-check-not=warning:
-# RUN: ld.lld %t -z foo -z rel -z rela -z max-page-size=1 -z common-page-size=1 -o /dev/null --version 2>&1 | \
+# RUN: ld.lld %t -z foo -z rel -z rela -z max-page-size=1 -z common-page-size=1 -z dynamic-undefined-weak \
+# RUN: -z nodynamic-undefined-weak -o /dev/null --version 2>&1 | \
# RUN: FileCheck -check-prefix=ERR10 %s --implicit-check-not=warning:
# ERR10: warning: unknown -z value: foo
diff --git a/lld/test/ELF/weak-undef-got-plt.s b/lld/test/ELF/weak-undef-got-plt.s
index 0ee3da2cd3b40..48a7914e5b987 100644
--- a/lld/test/ELF/weak-undef-got-plt.s
+++ b/lld/test/ELF/weak-undef-got-plt.s
@@ -6,11 +6,17 @@
# RUN: ld.lld a.o -o a
# RUN: llvm-readelf -r a | FileCheck %s --check-prefix=NORELOC
+# RUN: ld.lld a.o -o a -z dynamic-undefined-weak
+# RUN: llvm-readelf -r a | FileCheck %s --check-prefix=NORELOC
# RUN: ld.lld a.o s.so -o as
# RUN: llvm-objdump -dR as | FileCheck %s
+# RUN: ld.lld a.o s.so -o as -z nodynamic-undefined-weak
+# RUN: llvm-readelf -r a | FileCheck %s --check-prefix=NORELOC
# RUN: ld.lld -pie a.o s.so -o as.pie
# RUN: llvm-objdump -dR as.pie | FileCheck %s
+# RUN: ld.lld -pie a.o s.so -o as.pie -z nodynamic-undefined-weak
+# RUN: llvm-readelf -r as.pie | FileCheck --check-prefix=NORELOC %s
# RUN: ld.lld -shared a.o -o a.so
# RUN: llvm-objdump -dR a.so | FileCheck %s
diff --git a/lld/test/ELF/weak-undef-rw.s b/lld/test/ELF/weak-undef-rw.s
index 497228a3cf905..8d777669b7e16 100644
--- a/lld/test/ELF/weak-undef-rw.s
+++ b/lld/test/ELF/weak-undef-rw.s
@@ -18,9 +18,22 @@
## gABI leaves the behavior of weak undefined references implementation defined.
## We choose to resolve them statically for static linking and produce dynamic relocations
## for dynamic linking (-shared or at least one input DSO).
-##
-## Note: Some ports of GNU ld support -z nodynamic-undefined-weak that we don't
-## implement.
+
+## -z dynamic-undefined-weak is ignored if .dynsym is absent (-no-pie without DSO)
+# RUN: ld.lld a.o -o a.d -z dynamic-undefined-weak 2>&1 | count 0
+# RUN: llvm-readelf -r --hex-dump=.data a.d | FileCheck %s --check-prefix=STATIC
+
+## Currently no effect for S+A relocations.
+# RUN: ld.lld a.o s.so -o as.d -z dynamic-undefined-weak
+# RUN: llvm-readelf -r --hex-dump=.data as.d | FileCheck %s --check-prefix=STATIC
+
+## -z dynamic-undefined-weak forces dynamic relocations if .dynsym is present.
+# RUN: ld.lld a.o -o a.pie.d -pie -z dynamic-undefined-weak
+# RUN: llvm-readelf -r a.pie.d | FileCheck %s --check-prefix=DYN
+
+## -z nodynamic-undefined-weak suppresses dynamic relocations.
+# RUN: ld.lld a.o -o a.so.n -shared -z dynamic-undefined-weak -z nodynamic-undefined-weak
+# RUN: llvm-readelf -r --hex-dump=.data a.so.n | FileCheck %s --check-prefix=STATIC
# STATIC: no relocations
# STATIC: Hex dump of section '.data':
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me. Could be worth mentioning in the description that this option is available in GNU ld.
I only realised when getting to the comment in the tests.
The description in the GNU manual https://sourceware.org/binutils/docs/ld/Options.html might be a good start for the ld.lld man page.
@@ -47,7 +47,8 @@ | |||
# ERR9: error: cannot open output file utput=/no/such/file | |||
|
|||
# RUN: ld.lld %t -z foo -o /dev/null 2>&1 | FileCheck -check-prefix=ERR10 %s --implicit-check-not=warning: | |||
# RUN: ld.lld %t -z foo -z rel -z rela -z max-page-size=1 -z common-page-size=1 -o /dev/null --version 2>&1 | \ | |||
# RUN: ld.lld %t -z foo -z rel -z rela -z max-page-size=1 -z common-page-size=1 -z dynamic-undefined-weak \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just to check this is testing that the later -z nodynamic-undefined-weak
overrides -z nodynamic-undefined-weak
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes!
Created using spr 1.3.5-bogner
Created using spr 1.3.5-bogner
Update description and docs/ld.lld.1. Added a hidden undefined weak symbol test. Note: The option is not very effective with -no-pie, e.g. on |
The behavior of an undefined weak reference is implementation defined. For static -no-pie linking, dynamic relocations are generally avoided (except IRELATIVE). -shared linking generally emits dynamic relocations. Dynamic -no-pie linking and -pie allow flexibility. Changes adjust the behavior for better consistency and simpler internal representation, e.g. https://reviews.llvm.org/D63003 https://reviews.llvm.org/D105164 (generalized to undefined non-weak in 2fcaa00). GNU ld introduced -z [no]dynamic-undefined-weak option to fine-tune the behavior. (The option is not very effective with -no-pie, e.g. on x86-64, `ld.bfd a.o s.so -z dynamic-undefined-weak` generates R_X86_64_NONE relocations instead of GLOB_DAT/JUMP_SLOT) This patch implements -z [no]dynamic-undefined-weak option. The effects are summarized as follows: * Static -no-pie: no-op * Dynamic -no-pie: nodynamic-undefined-weak suppresses GLOB_DAT/JUMP_SLOT * Static -pie: dynamic-undefined-weak generates ABS/GLOB_DAT/JUMP_SLOT. https://discourse.llvm.org/t/lld-weak-undefined-symbols-in-vdso-only/86749 * Dynamic -pie: nodynamic-undefined-weak suppresses ABS/GLOB_DAT/JUMP_SLOT The -pie behavior likely stays stable while -no-pie (`!ctx.arg.isPic` in `isStaticLinkTimeConstant`) behavior will likely change in the future. The current default value of ctx.arg.zDynamicUndefined is selected to prevent behavior changes. Pull Request: llvm/llvm-project#143831
The behavior of an undefined weak reference is implementation defined. For static -no-pie linking, dynamic relocations are generally avoided (except IRELATIVE). -shared linking generally emits dynamic relocations. Dynamic -no-pie linking and -pie allow flexibility. Changes adjust the behavior for better consistency and simpler internal representation, e.g. https://reviews.llvm.org/D63003 https://reviews.llvm.org/D105164 (generalized to undefined non-weak in 2fcaa00). GNU ld introduced -z [no]dynamic-undefined-weak option to fine-tune the behavior. (The option is not very effective with -no-pie, e.g. on x86-64, `ld.bfd a.o s.so -z dynamic-undefined-weak` generates R_X86_64_NONE relocations instead of GLOB_DAT/JUMP_SLOT) This patch implements -z [no]dynamic-undefined-weak option. The effects are summarized as follows: * Static -no-pie: no-op * Dynamic -no-pie: nodynamic-undefined-weak suppresses GLOB_DAT/JUMP_SLOT * Static -pie: dynamic-undefined-weak generates ABS/GLOB_DAT/JUMP_SLOT. https://discourse.llvm.org/t/lld-weak-undefined-symbols-in-vdso-only/86749 * Dynamic -pie: nodynamic-undefined-weak suppresses ABS/GLOB_DAT/JUMP_SLOT The -pie behavior likely stays stable while -no-pie (`!ctx.arg.isPic` in `isStaticLinkTimeConstant`) behavior will likely change in the future. The current default value of ctx.arg.zDynamicUndefined is selected to prevent behavior changes. Pull Request: llvm#143831
The behavior of an undefined weak reference is implementation defined. For static -no-pie linking, dynamic relocations are generally avoided (except IRELATIVE). -shared linking generally emits dynamic relocations. Dynamic -no-pie linking and -pie allow flexibility. Changes adjust the behavior for better consistency and simpler internal representation, e.g. https://reviews.llvm.org/D63003 https://reviews.llvm.org/D105164 (generalized to undefined non-weak in 2fcaa00). GNU ld introduced -z [no]dynamic-undefined-weak option to fine-tune the behavior. (The option is not very effective with -no-pie, e.g. on x86-64, `ld.bfd a.o s.so -z dynamic-undefined-weak` generates R_X86_64_NONE relocations instead of GLOB_DAT/JUMP_SLOT) This patch implements -z [no]dynamic-undefined-weak option. The effects are summarized as follows: * Static -no-pie: no-op * Dynamic -no-pie: nodynamic-undefined-weak suppresses GLOB_DAT/JUMP_SLOT * Static -pie: dynamic-undefined-weak generates ABS/GLOB_DAT/JUMP_SLOT. https://discourse.llvm.org/t/lld-weak-undefined-symbols-in-vdso-only/86749 * Dynamic -pie: nodynamic-undefined-weak suppresses ABS/GLOB_DAT/JUMP_SLOT The -pie behavior likely stays stable while -no-pie (`!ctx.arg.isPic` in `isStaticLinkTimeConstant`) behavior will likely change in the future. The current default value of ctx.arg.zDynamicUndefined is selected to prevent behavior changes. Pull Request: llvm#143831
The behavior of an undefined weak reference is implementation defined.
For static -no-pie linking, dynamic relocations are generally avoided (except
IRELATIVE). -shared linking generally emits dynamic relocations.
Dynamic -no-pie linking and -pie allow flexibility. Changes adjust the
behavior for better consistency and simpler internal representation,
e.g. https://reviews.llvm.org/D63003 https://reviews.llvm.org/D105164
(generalized to undefined non-weak in
2fcaa00).
GNU ld introduced -z [no]dynamic-undefined-weak option to fine-tune the
behavior. (The option is not very effective with -no-pie, e.g. on
x86-64,
ld.bfd a.o s.so -z dynamic-undefined-weak
generatesR_X86_64_NONE relocations instead of GLOB_DAT/JUMP_SLOT)
This patch implements -z [no]dynamic-undefined-weak option.
The effects are summarized as follows:
https://discourse.llvm.org/t/lld-weak-undefined-symbols-in-vdso-only/86749
The -pie behavior likely stays stable while -no-pie (
!ctx.arg.isPic
inisStaticLinkTimeConstant
) behavior will likely change in the future.The current default value of ctx.arg.zDynamicUndefined is selected to
prevent behavior changes.