Skip to content

Instantly share code, notes, and snippets.

@shqking
Last active June 29, 2023 01:47
Show Gist options
  • Save shqking/4aab67e0105f7c1f2c549d57d5799f94 to your computer and use it in GitHub Desktop.
Save shqking/4aab67e0105f7c1f2c549d57d5799f94 to your computer and use it in GitHub Desktop.
Macos ZTS

####Test case:

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

__thread int x = 0;

int main()
{
    int tmp = x;
    tmp ++;
    printf("val: %d\n", tmp);

    return 0;
}

Question: how to get the address of thread local variable "x"?

####Linux AArch64

Assembly(gcc -S)

mrs     x0, tpidr_el0                     // Line 1: TCB address
add     x0, x0, #:tprel_hi12:x, lsl #12
add     x0, x0, #:tprel_lo12_nc:x         // Line 3: add the offset of "x"
ldr     w0, [x0]

Disassembly(after link)

00000000000007a4 <main>:
 7a4:   a9be7bfd        stp     x29, x30, [sp, #-32]!
 7a8:   910003fd        mov     x29, sp
 7ac:   d53bd040        mrs     x0, tpidr_el0
 7b0:   91400000        add     x0, x0, #0x0, lsl #12
 7b4:   91004000        add     x0, x0, #0x10
 7b8:   b9400000        ldr     w0, [x0]

For JIT: base addr + offset.

  • TCB address can be obtained via system register at runtime, i.e. "mrs"

  • the offset of "x" to TCB is determined during the compiler time.

Reference: https://blog.iret.xyz/article.aspx/thread_pointer_aarch64

####Macos Apple Silicon

Reference: http://www.jakubkonka.com/2021/01/21/llvm-tls-apple-silicon.html

Assembly(gcc -S)

_main:                                  ; @main
  ...
  adrp  x8, _x@TLVPPAGE         // Line 1:
  ldr x8, [x8, _x@TLVPPAGEOFF]  // Line 2
  ldr x9, [x8]                  // Line 3:
  mov x0, x8 
  blr x9                        // Line 5: 
  mov w10, #0 
  stur wzr, [x29, #-4] 
  ldr w11, [x0]                 // Line 8: 
  stur w11, [x29, #-8] 
  ldur w11, [x29, #-8] 
  add w11, w11, #1 ; =1 

Lines 1-2: get the address of of the __thread_vars section

Line 3: get the address of function tlv_get_address

Line 5: call function tlv_get_address

Line 8: address of "x" is returned in "x0" register.

before link:

 c: 08 00 00 90            adrp    x8, #0
10: 08 01 40 f9            ldr     x8, [x8]
14: 09 01 40 f9            ldr     x9, [x8]
18: e0 03 08 aa            mov     x0, x8
1c: 20 01 3f d6            blr     x9

after link:

100003f0c: 28 00 00 b0     adrp    x8, #20480
100003f10: 08 21 00 91     add     x8, x8, #8   // ldr -> add.
100003f14: 09 01 40 f9     ldr     x9, [x8]
100003f18: e0 03 08 aa     mov     x0, x8
100003f1c: 20 01 3f d6     blr     x9

Question: how can JIT generate this code sequence?

@kunalspathak
Copy link

I have a WIP PR to generate these offset/address in JIT: dotnet/runtime#87082

@shqking
Copy link
Author

shqking commented Jun 29, 2023

I have a WIP PR to generate these offset/address in JIT: dotnet/runtime#87082

Thanks for your link.

IIRC, we addressed this issue in PHP JIT by php/php-src#7042

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment