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.

Reply via email to