On Monday 17 July 2023, Frederick Gotham wrote:
>
> If I change it to thread_local then try to re-compile, I get a linker error:
>
> R_AARCH64_ADR_PREL_LO21 used with TLS symbol f
>
> Do you know what syntax I use to access the thread_local variable from assembler? Will I need to write a separate function as follows?
In order to try understand how thread_local variables are accessed from aarch64 assembler, I wrote the following dynamic shared library in C:
__thread void (*f)(void);
void (*g)(void);
void Func(void)
{
g = f;
}
I compiled this to 'libtest.so" and then used 'objdump' on it to see:
<Func>:
Line 01: stp x29, x30, [sp, #-16]!
Line 02: mrs x1, tpidr_el0
Line 03: mov x29, sp
Line 04: adrp x0, 20000 <__cxa_finalize>
Line 05: ldr x2, [x0, #16]
Line 06: add x0, x0, #0x10
Line 07: blr x2
Line 08: adrp x2, 1f000 <__FRAME_END__+0x1e8c8>
Line 09: ldr x2, [x2, #4032]
Line 10: ldr x0, [x1, x0]
Line 11: str x0, [x2]
Line 12: ldp x29, x30, [sp], #16
Line 13: ret
Line #2 appears to put the address of "thread local storage" inside the x1 register.
Lines #4-7 at first glance seem to call the function "__cxz_finalize" (which is the one that gets called at the end of a program to invoke all the destructors of global objects)... but really I just think that the number 0x20000 is being used as a base address to apply offsets to.
Lines #7 definitely is calling some function though, I don't know which one.
Lines #8-12, I'm not sure here... but I think they're moving the value of the thread_local variable 'f' into the global variable 'g'.
Can anyone please help me understand this? And explore how I would go about writing aarch64 to access a thread_local variable called 'f'?