NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

toolchain/45576: toolchain



>Number:         45576
>Category:       toolchain
>Synopsis:       ARM compiler bug extracting consecutive pointers from struct
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    toolchain-manager
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sun Nov 06 11:05:00 +0000 2011
>Originator:     Ignatios Souvatzis
>Release:        NetBSD 5.1
>Organization:
me
>Environment:
        
        
System: NetBSD marie 5.1 NetBSD 5.1 (MARIE) #0: Wed Jan 5 20:52:48 CET 2011 
ignatios@random87:/var/itch/obj/shark/sys/arch/shark/compile/MARIE shark
Architecture: arm
Machine: shark
Compiler:
Using built-in specs.
Target: arm--netbsdelf
Configured with: /usr/src/tools/gcc/../../gnu/dist/gcc4/configure 
--enable-long-long --disable-multilib --enable-threads --disable-symvers 
--build=x86_64-unknown-netbsd4.99.72 --host=arm--netbsdelf 
--target=arm--netbsdelf --enable-__cxa_atexit
Thread model: posix
gcc version 4.1.3 20080704 prerelease (NetBSD nb2 20081120)
>Description:

        When extracting two consecutive pointers in a struct to subtract
        them, for a certain range of offsets from the start of the struct,
        gcc 4.1.3 overwrites the register used for the struct base with
        the first pointer extracted, thus extracting garbage or getting 
        a SIGBUS when accessing the 2nd one.

        (Found when hunting down why wip/hplip3 SIGBUSsed on me on ARM,
         but not on i386).

        This happens with -O2 and -O1, but not with -O0

        The affected pointer offsets are 1024/1028 to 4088/4092 bytes 
        from struct start.

        Non-consecutive pointers are not affected.

>How-To-Repeat:
Here's a demo program:
% cat pointerdiff.c
#define testit(cs,ds) \
struct foo##cs##_##ds { \
        char c[cs]; \
        char *a; \
        char d[ds]; \
        char *b; \
}; \
int try##cs##_##ds (struct foo##cs##_##ds *g) {\
        return g->b - g->a; \
}

testit(0,0)
testit(16,0)
testit(64,0)
testit(256,0)
testit(1020,0)
testit(1024,0)
testit(4088,0)
testit(4092,0)
testit(4096,0)
testit(32768,0)
testit(0,12)
testit(1024,12)
testit(4096,12)
testit(0,1212)
testit(1024,1212)
testit(4096,1212)

% gcc -O1 -S pointerdiff.c

>Fix:
Workaround: Use gcc -O0 for affected programs. This is not very satisfactory,
as the code needs three to four times memory accesses and instructions.

I don't have a gcc 4.[456] for ARM around yet to test with that.

>Unformatted:
        
        


Home | Main Index | Thread Index | Old Index