[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Bug ld/20868] ld relaxes TLS access erroneously for aarch64 in ilp32 mo
From: |
ynorov at caviumnetworks dot com |
Subject: |
[Bug ld/20868] ld relaxes TLS access erroneously for aarch64 in ilp32 mode |
Date: |
Sat, 26 Nov 2016 05:20:56 +0000 |
https://sourceware.org/bugzilla/show_bug.cgi?id=20868
--- Comment #4 from Yury Norov <ynorov at caviumnetworks dot com> ---
(In reply to Jiong Wang from comment #3)
> Hi Yury,
>
> Some quick thoughts:
>
> >
> > But in executalbe binary ld relaxes tls access with direct address
> > calculation:
> > 279 register unsigned long __result asm ("w0");
> > 280 asm volatile ("adrp %0, :tlsgd:foo; \n"
> > 281 400618: 90000080 adrp x0, 410000
> > <__FRAME_END__+0xf828>
> > 282 40061c: f948ec00 ldr x0, [x0,#4568]
> > 283 400620: d53bd041 mrs x1, tpidr_el0
> > 284 400624: 8b000020 add x0, x1, x0
>
> The sequences is still loading tls offset from GOT table, then add it to the
> tp. It seems to me be a GD->IE bug on ILP32.
>
> Can you try to modify 0xf9400000 to 0xb9400000 in elfNN_aarch64_tls_relax
> when relaxing BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC, does it work for you?
>
> The "ldr x0, [x0,#4568]" looks suspicous to me. the x0 implies 8bytes
> scale, while ILP32 relocations are doing 4bytes shift.
To me too.
This code replaces TLS access with GOT using "ldr w0, [x0, ...]" manually, and
it works:
register unsigned long __result asm ("w0");
// asm volatile ("adrp %0, :tlsgd:foo; \n"
// "add %w0, %w0, #:tlsgd_lo12:foo; \n"
// "bl my_tls_get_addr;\n"
// "nop\n"
// : "=r" (__result)
// :
// : "x1", "x2", "x3", "x4", "x5", "x6", "x7",
// "x8", "x9", "x10", "x11", "x12", "x13",
// "x14", "x15", "x16", "x17", "x18", "x30",
// "memory", "cc");
asm volatile ("adrp %0, :gottprel:foo; \n"
"ldr %w0, [%0, #:gottprel_lo12:foo];\n"
"mrs x1, tpidr_el0;\n"
"add %w0, w1, %w0\n"
: "=r" (__result)
:
: "x1", "x2", "x3", "x4", "x5", "x6", "x7",
"x8", "x9", "x10", "x11", "x12", "x13",
"x14", "x15", "x16", "x17", "x18", "x30",
"memory", "cc");
bp = (unsigned int *) __result;
printf ("TLS_LD == %p\n", bp);
printf ("*TLS_LD == %d\n", *bp);
I can prepare the patch for binutils, but I need some time to setup environment
and get into the code. If you find it urgent, you'd better do it by yourself
--
You are receiving this mail because:
You are on the CC list for the bug.