llvm-project/lld/test/ELF/driver.test
Fangrui Song 07dad4ecba
[ELF] Implement -z dynamic-undefined-weak
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
2fcaa00d1e2317a90c9071b735eb0e758b5dd58b).

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: https://github.com/llvm/llvm-project/pull/143831
2025-06-12 19:50:41 -07:00

68 lines
3.0 KiB
Plaintext

# REQUIRES: x86
# RUN: not ld.lld --unknown1 --unkn=own2 -m foo /no/such/file -lnosuchlib \
# RUN: 2>&1 | FileCheck -check-prefix=UNKNOWN %s
# UNKNOWN: error: unknown argument '--unknown1'
# UNKNOWN: error: unknown argument '--unkn=own2'
# UNKNOWN: error: unknown emulation: foo
# UNKNOWN: error: cannot open /no/such/file
# UNKNOWN: error: unable to find library -lnosuchlib
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
# RUN: not ld.lld %t -o /no/such/file 2>&1 | FileCheck -check-prefix=MISSING %s
# MISSING: error: cannot open output file /no/such/file
# RUN: ld.lld --help 2>&1 | FileCheck -check-prefix=HELP %s
# HELP: USAGE:
# HELP: : supported targets:{{.*}} elf
# RUN: not ld.lld --versin 2>&1 | FileCheck -check-prefix=SPELLVERSION %s
# SPELLVERSION: error: unknown argument '--versin', did you mean '--version'
## Attempt to link DSO with -r
# RUN: ld.lld -shared %t -o %t.so
# RUN: not ld.lld -r %t.so %t -o /dev/null 2>&1 | FileCheck -check-prefix=ERR %s
# ERR: error: attempted static link of dynamic object
# RUN: not ld.lld -r -shared -pie --export-dynamic %t -o /dev/null 2>&1 | FileCheck -check-prefix=ERR2 %s
# ERR2: error: -r and -shared may not be used together
# ERR2: error: -r and -pie may not be used together
# ERR2: error: -r and --export-dynamic may not be used together
# RUN: not ld.lld -r --icf=all --gdb-index --debug-names %t -o /dev/null 2>&1 | FileCheck -check-prefix=ERR4 %s
# ERR4: error: -r and --gdb-index may not be used together
# ERR4: error: -r and --icf may not be used together
# ERR4: error: -r and --debug-names may not be used together
# RUN: not ld.lld -shared -pie %t -o /dev/null 2>&1 | FileCheck -check-prefix=ERR7 %s
# ERR7: error: -shared and -pie may not be used together
## "--output=foo" is equivalent to "-o foo".
# RUN: not ld.lld %t --output=/no/such/file 2>&1 | FileCheck -check-prefix=ERR8 %s
# ERR8: error: cannot open output file /no/such/file
## "-output=foo" is equivalent to "-o utput=foo".
# RUN: not ld.lld %t -output=/no/such/file 2>&1 | FileCheck -check-prefix=ERR9 %s
# 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 -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
## Check we report "unknown -z value" error even with -v.
# RUN: ld.lld %t -z foo -z rel -o /dev/null -v 2>&1 | FileCheck -check-prefix=ERR10 %s --implicit-check-not=warning:
## Note: in GNU ld, --fatal-warning still leads to a warning.
# RUN: not ld.lld %t -z foo --fatal-warnings 2>&1 | FileCheck --check-prefix=ERR10-FATAL %s
# ERR10-FATAL: error: unknown -z value: foo
# RUN: not ld.lld %t -z max-page-size 2>&1 | FileCheck -check-prefix=ERR11 %s
# ERR11: error: invalid max-page-size:
.globl _start
_start:
nop