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);
|
write(sym.esym().st_size + A);
|
||||||
continue;
|
continue;
|
||||||
case R_X86_64_TLSDESC_CALL:
|
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
|
// call *(%rax) -> nop
|
||||||
loc[0] = 0x66;
|
loc[0] = 0x66;
|
||||||
loc[1] = 0x90;
|
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"
|
Fatal(ctx) << *this << ": GOTPC32_TLSDESC relocation is used"
|
||||||
<< " against an invalid code sequence";
|
<< " 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;
|
sym.flags |= NEEDS_TLSDESC;
|
||||||
break;
|
break;
|
||||||
case R_X86_64_TPOFF32:
|
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