I am trying to reverse an ELF binary that makes use of thread-local variables. I can't figure out how to make Ghidra display them in a friendlier way (something like declaring a struct or similar).
For example, this is how a call to scanf with a FILE* stored in TLS looks like:
scanf(*(FILE **)(in_FS_OFFSET + 0xfffffff0),"%d",&num);
Ideally, I would like this to look something like:
scanf(tls->outfile, "%d", &num);
Is it possible to make it more user-friendly? I looked around but I haven't seen anyone complaining about this.
Here's an example code:
#include <threads.h>
#include <stdio.h>
#include <assert.h>
thread_local int foo = 0;
int main(void) {
assert(scanf("%d", &foo) == 1);
printf("foo is: %d\n", foo);
return 0;
}
tls.c
compile with CFLAGS="-std=c11 -Wall -Wextra -O0 -ggdb -Werror" make tls
And here's the decompiled code:
-O0
(and even at-O3
for that matter) tostatic
or a mere global variable. However, what's shown asin_FS_OFFSET
presumably isfs:0
and this answers how and why -4 is needed here. Given your answer, I think however, you're conflating things a bit.in_FS_OFFSET
as a pointer to the end of your struct, and then it would automatically recognize your thread_local fields.