https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122515
Bug ID: 122515
Summary: Integer overflow on i686 when getting offsets in large
archives
Product: gcc
Version: 15.1.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: lto
Assignee: unassigned at gcc dot gnu.org
Reporter: siddhesh at gcc dot gnu.org
Target Milestone: ---
Created attachment 62685
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=62685&action=edit
Use off_t for offsets into archives
Reproducer:
$ cat > Makefile
CC = gcc
CXX = g++
numfiles = 8
srcfiles = src1.c
all: clean finalbin
final.c:
{ \
echo 'extern int bar_7 (int);';\
echo '';\
echo 'int main (void)';\
echo '{';\
echo ' return bar_7 (42);';\
echo '}';\
} > $@
main.c:
{ \
echo 'typedef struct {';\
echo ' int num;';\
echo ' int foo[40000000];';\
echo '} A_0;';\
echo '';\
echo 'A_0 a1 = {1};';\
echo 'A_0 a2 = {2};';\
echo '';\
echo 'int bar_0 (int i)';\
echo '{';\
echo ' return i++;';\
echo '}';\
} > $@
srcs = $(shell seq 1 $(numfiles))
srcfiles += $(patsubst %,src%.c,$(srcs))
objfiles = $(srcfiles:.c=.o)
num = $(patsubst src%.c,%,$@)
src%.c: main.c
i=$$(echo $@ | sed 's/src\([0-9]\+\)\.c/\1/') \
sed -e "s/bar_0/bar_$(num)/" -e "s/A_0/A_$(num)/g" $^ > $@
%.o : %.c
$(CC) -flto=auto -ffat-lto-objects -c -o $@ $^
libbig.a: $(objfiles)
ar rcs $@ $^
finalbin: final.c libbig.a
$(CC) -flto=auto -ffat-lto-objects -O2 -o $@ $^
clean:
rm -f *.c
rm -f *.o
rm -f libbig.a
$ make
gcc -flto=auto -ffat-lto-objects -O2 -o finalbin final.c libbig.a
lto1: fatal error: Cannot map libbig.a
compilation terminated.
lto-wrapper: fatal error: gcc returned 1 exit status
compilation terminated.
/usr/bin/ld: error: lto-wrapper failed
collect2: error: ld returned 1 exit status
make: *** [Makefile:55: finalbin] Error 1
rm src6.c src7.c src4.c src1.c src8.c src2.c src5.c src3.c
In some cases this can cause ICEs like in this issue when building cmake on
i686:
https://issues.redhat.com/browse/RHEL-113687
The problem is that offsets are being read into a `long` in some places and not
`off_t`, which is wrong because they're 32-bit and 64-bit respectively on i686.
There's no reason to use `long` for this. The attached patch fixes this. I'm
testing this right now.
