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.

Reply via email to