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