mirror of
https://github.com/rui314/mold.git
synced 2024-11-15 14:36:25 +03:00
Fix TLSDESC relocations for statically-linked executables
We shouldn't create TLSDESC dynamic relocations for statically- linked executables because such executables don't contain the tranpoline function needed for TLSDESC. Instead, we should always relax these relocations.
This commit is contained in:
parent
3c79d672dc
commit
4c710df347
@ -410,7 +410,7 @@ void InputSection<X86_64>::apply_reloc_alloc(Context<X86_64> &ctx, u8 *base) {
|
||||
write(sym.esym().st_size + A);
|
||||
continue;
|
||||
case R_X86_64_TLSDESC_CALL:
|
||||
if (ctx.arg.relax && !ctx.arg.shared) {
|
||||
if (ctx.arg.is_static || (ctx.arg.relax && !ctx.arg.shared)) {
|
||||
// call *(%rax) -> nop
|
||||
loc[0] = 0x66;
|
||||
loc[1] = 0x90;
|
||||
@ -644,7 +644,10 @@ void InputSection<X86_64>::scan_relocations(Context<X86_64> &ctx) {
|
||||
Fatal(ctx) << *this << ": GOTPC32_TLSDESC relocation is used"
|
||||
<< " against an invalid code sequence";
|
||||
|
||||
if (!ctx.arg.relax || ctx.arg.shared)
|
||||
// TLSDESC relocs must be relaxed for a statically-linked executable
|
||||
// even if -no-relax is given. It is because a statically-linked
|
||||
// executable doesn't contain a tranpoline function needed for TLSDESC.
|
||||
if (!ctx.arg.is_static && (!ctx.arg.relax || ctx.arg.shared))
|
||||
sym.flags |= NEEDS_TLSDESC;
|
||||
break;
|
||||
case R_X86_64_TPOFF32:
|
||||
|
39
test/tlsdesc-static.sh
Executable file
39
test/tlsdesc-static.sh
Executable file
@ -0,0 +1,39 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
cd $(dirname $0)
|
||||
mold=`pwd`/../mold
|
||||
echo -n "Testing $(basename -s .sh $0) ... "
|
||||
t=$(pwd)/tmp/$(basename -s .sh $0)
|
||||
mkdir -p $t
|
||||
|
||||
if [ $(uname -m) = x86_64 ]; then
|
||||
dialect=gnu2
|
||||
elif [ $(uname -m) = aarch64 ]; then
|
||||
dialect=desc
|
||||
else
|
||||
echo skipped
|
||||
exit 0
|
||||
fi
|
||||
|
||||
cat <<EOF | gcc -fPIC -mtls-dialect=$dialect -c -o $t/a.o -xc -
|
||||
#include <stdio.h>
|
||||
|
||||
extern _Thread_local int foo;
|
||||
|
||||
int main() {
|
||||
foo = 42;
|
||||
printf("%d\n", foo);
|
||||
}
|
||||
EOF
|
||||
|
||||
cat <<EOF | gcc -fPIC -mtls-dialect=$dialect -c -o $t/b.o -xc -
|
||||
_Thread_local int foo;
|
||||
EOF
|
||||
|
||||
clang -fuse-ld=$mold -o $t/exe $t/a.o $t/b.o -static
|
||||
$t/exe | grep -q 42
|
||||
|
||||
clang -fuse-ld=$mold -o $t/exe $t/a.o $t/b.o -static -Wl,-no-relax
|
||||
$t/exe | grep -q 42
|
||||
|
||||
echo OK
|
Loading…
Reference in New Issue
Block a user