https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88962
Bug ID: 88962 Summary: Invalid/inconsistent PowerPC TLS variable access Product: gcc Version: 8.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: jirik.svoboda at seznam dot cz Target Milestone: --- If I build a GCC cross-compiler for PowerPC (ppc-linux-gnu): binutils-2.31.1 ./configure --target=ppc-linux-gnu --prefix=... --dsiable-nls --disable-werror --enable-gold --enable-deterministic-archives make all make install gcc-8.2.0 ./configure --target=ppc-linux-gnu --prefix=... --with-gnu-as --with-gnu-ld --disable-nls --disable-threads --enable-languages=c --disable-multilib --disable-libgcj --without-headers --disable-shared --enable-lto --disable-werror make all-gcc make install-gcc and then build a shared library that accesses a static thread-local variable and a non-static thread-local variable: [jirka@omelette tmp]$ cat test.c static __thread int a; __thread int b; int geta(void) { return a; } int getb(void) { return b; } int seta(int n) { a = n; } [jirka@omelette tmp]$ /usr/local/xcross/ppc-linux-gnu/bin/ppc-linux-gnu-gcc -nostdlib -fPIC -O3 -c -o test.o test.c [jirka@omelette tmp]$ /usr/local/xcross/ppc-linux-gnu/bin/ppc-linux-gnu-gcc -nostdlib -shared -fPIC -O3 -o test.so test.o [jirka@omelette tmp]$ /usr/local/xcross/ppc-linux-gnu/bin/ppc-linux-gnu-objdump -D test.so 00000248 <geta>: 248: 7c 08 02 a6 mflr r0 24c: 42 9f 00 09 bcl 20,4*cr7+so,254 <geta+0xc> 250: 00 01 fd c4 .long 0x1fdc4 254: 7d 28 02 a6 mflr r9 258: 94 21 ff f0 stwu r1,-16(r1) 25c: 80 69 00 00 lwz r3,0(r9) 260: 90 01 00 14 stw r0,20(r1) 264: 7c 69 1a 14 add r3,r9,r3 268: 93 c1 00 08 stw r30,8(r1) 26c: 38 63 ff f4 addi r3,r3,-12 270: 48 01 fd f9 bl 20068 <__tls_get_addr@plt> 274: 80 01 00 14 lwz r0,20(r1) 278: 3c 63 00 00 addis r3,r3,0 27c: 83 c1 00 08 lwz r30,8(r1) 280: 38 63 80 04 addi r3,r3,-32764 <--- **** subtract bias 32K 284: 7c 08 03 a6 mtlr r0 288: 80 63 00 00 lwz r3,0(r3) 28c: 38 21 00 10 addi r1,r1,16 290: 4e 80 00 20 blr 00000294 <getb>: 294: 7c 08 02 a6 mflr r0 298: 42 9f 00 09 bcl 20,4*cr7+so,2a0 <getb+0xc> 29c: 00 01 fd 78 .long 0x1fd78 2a0: 7d 28 02 a6 mflr r9 2a4: 94 21 ff f0 stwu r1,-16(r1) 2a8: 80 69 00 00 lwz r3,0(r9) 2ac: 90 01 00 14 stw r0,20(r1) 2b0: 7c 69 1a 14 add r3,r9,r3 2b4: 93 c1 00 08 stw r30,8(r1) 2b8: 38 63 ff ec addi r3,r3,-20 2bc: 48 01 fd ad bl 20068 <__tls_get_addr@plt> 2c0: 80 01 00 14 lwz r0,20(r1) 2c4: 80 63 00 00 lwz r3,0(r3) < ---- **** no bias subtracted 2c8: 83 c1 00 08 lwz r30,8(r1) 2cc: 7c 08 03 a6 mtlr r0 2d0: 38 21 00 10 addi r1,r1,16 2d4: 4e 80 00 20 blr As you can see, for static thread-local variable, we subtract 32K bias from result of __tls_get_addr@plt. For non-static thread-local variable, we do not subtract anything. This looks like a bug. For -O0 optimization we never subtract anything. Not sure which behavior is correct -- subtract 32 K or not) -- I ran into this when implementing PowerPC architecture support for HelenOS dynamic linker. I am inclined to think it should always subtract 32K bias according to the ABI. In any case I think it needs to behave consistently, otherwise cannot make the TLS work in all cases.