Bug 88962 - Invalid/inconsistent PowerPC TLS variable access
Summary: Invalid/inconsistent PowerPC TLS variable access
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 8.2.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2019-01-21 21:44 UTC by Jiri Svoboda
Modified: 2019-08-01 16:47 UTC (History)
2 users (show)

See Also:
Host:
Target: powerpc
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jiri Svoboda 2019-01-21 21:44:10 UTC
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.
Comment 1 Andrew Pinski 2019-01-21 21:56:39 UTC
What happens if you use -fno-section-anchors option?  My bet is the section anchor is setting the bias for the static variables to be 32k off of the center.
Comment 2 Jiri Svoboda 2019-01-21 22:04:43 UTC
I added the -fno-section-anchors option to both the compile and link invocations but I am still getting the same result.
Comment 3 Segher Boessenkool 2019-08-01 16:47:15 UTC
Looking at GCC's output:

[ cutting away irrelevant (irrelevant here) dot ops: ]

geta:
        stwu 1,-16(1)
        mflr 0
        bcl 20,31,$+8
        mflr 3
        lwz 9,0(3)
        add 3,3,9
        stw 0,20(1)
        addi 3,3,a@got@tlsld
        stw 30,8(1)
        bl __tls_get_addr(a@tlsld)@plt
        lwz 0,20(1)
        lwz 30,8(1)
        addis 3,3,a@dtprel@ha
        mtlr 0
        addi 3,3,a@dtprel@l
        lwz 3,0(3)
        addi 1,1,16
        blr


getb:
        stwu 1,-16(1)
        mflr 0
        bcl 20,31,$+8
        mflr 3
        lwz 9,0(3)
        add 3,3,9
        stw 0,20(1)
        addi 3,3,b@got@tlsgd
        stw 30,8(1)
        bl __tls_get_addr(b@tlsgd)@plt
        lwz 0,20(1)
        lwz 30,8(1)
        lwz 3,0(3)
        mtlr 0
        addi 1,1,16
        blr


tlsld and tlsgd have quite different semantics, so this isn't a real surprise?

What do you think the compiler should do differently?

(Closing as invalid, please reopen if you want further action).