Issue 71666
Summary lldb on AArch64 Linux cannot read thread local variables
Labels lldb
Assignees
Reporter DavidSpickett
    Since https://github.com/llvm/llvm-project/commit/e8ea47602bdb74a88c707d289fc241f7670e1483 we have support for TLS on x86 Linux, but this does not work on AArch64.

For AArch64 we do now have the `tpidr` register accessible, which is one piece of the puzzle.

The other part is that the compiler does not emit any TLS hint in the DWARF. Example code:
```
#include <pthread.h>

__thread int tls1=10;
void *start(void* ptr) {
  int a=10+tls1;
  return NULL;
}

int main() {
  pthread_t t1;
 pthread_create(&t1, NULL, start, NULL);
  void* r;
  pthread_join(t1, &r);
  return 0;
}
```
Compiled with clang for AArch64 we get this description:
```
0x00000023:   DW_TAG_variable
 DW_AT_name      ("tls1")
                DW_AT_type      (0x0000002b "int")
                DW_AT_external  (true)
 DW_AT_decl_file ("/tmp/test.c")
                DW_AT_decl_line (3)
```
For x86 you get:
```
0x000000e6:   DW_TAG_variable
 DW_AT_name      ("tls1")
                DW_AT_decl_file ("/tmp/test.c")
                DW_AT_decl_line (3)
 DW_AT_decl_column       (0x0e)
                DW_AT_type      (0x00000057 "int")
                DW_AT_external  (true)
 DW_AT_location  (DW_OP_const8u 0x0, DW_OP_GNU_push_tls_address)
```
Arm has not decided on a way to represent TLS variables in this same way (see `AArch64_ELFTargetObjectFile::Initialize`).

I briefly tried flipping that boolean so AArch64 did emit it, then using tpidr as the thread pointer. However the existing calculations do not work and I don't have time right now to see what the data structures are supposed to be.

My hacks aside, a vanilla LLDB doesn't see the variable at all:
```
(lldb) p tls1
error: <user _expression_ 0>:1:1: use of undeclared identifier 'tls1'
    1 | tls1
      | ^
```
GDB can read it:
```
(gdb) p tls1
$1 = 10
```
Apparently GDB is using `thread_db` from glibc to work this out, but I don't have the details.

We would I think have to:
* Mark tpidr as the thread pointer register.
* Pass this information to glibc somehow, using the symbol's address as the offset.
* Read the resulting location.
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to