gcc-darwin-arm64 icon indicating copy to clipboard operation
gcc-darwin-arm64 copied to clipboard

TLS on arm64 Darwin

Open saagarjha opened this issue 4 years ago • 4 comments

I saw that you left this section empty–if you haven't gotten around to looking at this, here's a bit about how it's implemented:

$ clang -x c -Os -
__thread int foo;

int main() {
	return foo;
}
$ otool -tV a.out
a.out:
(__TEXT,__text) section
_main:
0000000100003f94	stp	x29, x30, [sp, #-0x10]!
0000000100003f98	mov	x29, sp
0000000100003f9c	adrp	x0, 1 ; 0x100004000
0000000100003fa0	add	x0, x0, #0x0
0000000100003fa4	ldr	x8, [x0]
0000000100003fa8	blr	x8
0000000100003fac	ldr	w0, [x0]
0000000100003fb0	ldp	x29, x30, [sp], #0x10
0000000100003fb4	ret
$ nm -m a.out
0000000100000000 (__TEXT,__text) [referenced dynamically] external __mh_execute_header
                 (undefined) external __tlv_bootstrap (from libSystem)
0000000100004000 (__DATA,__thread_vars) external _foo
0000000100004018 (__DATA,__thread_bss) non-external _foo$tlv$init
0000000100003f94 (__TEXT,__text) external _main
                 (undefined) external dyld_stub_binder (from libSystem)

At program startup dyld's _dyld_initializer (called by libSystem's initializer, called by dyld's startup) will call tlv_initializer which registers tlv_load_notification for each image that is laoded. tlv_load_notification calls tlv_initialize_descriptors. tlv_initialize_descriptors looks in the section with all the thread local variables (see __DATA,__thread_vars above) to initialize the thunk used to access the TLS variables. You can see the thunk (which is tls_get_var and the first member of the TLVDescriptor at 0x100004000) being called, which is written in assembly and reads TPIDRRO_EL0.

saagarjha avatar Aug 19 '20 02:08 saagarjha

thanks for this.

For the compiler's output - it's helpful to dump the object file : so do "clang foo.c -c" and then use objdump -d -r foo.o to look at the relocations created. [Also otool -rv foo.o is useful for listing relocs in data sections].

One can look at the .s file (clang foo.c -c -save-temps) to see the assembler syntax that the clang assembler is expecting (which is different from GAS too).

iains avatar Aug 25 '20 20:08 iains

cross-referencing against GCC bug 52268: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52268

cooljeanius avatar Jul 09 '21 23:07 cooljeanius

macports/macports-legacy-support@345091d might be helpful

cooljeanius avatar Apr 21 '22 11:04 cooljeanius

unfortunately, adding the compiler TLS support is quite a large job [because Darwin has never had native TLS support, but uses the generic emulated TLS - the change will be quite invasive]. Of course, Mach-O TLS is different from the ELF models .. so not sure how much read-across there will be.

(but it's useful to know about the runtime support, when we get to that stage).

iains avatar Apr 21 '22 11:04 iains