[Bug c/44537] New: gcc produces bad MIPS jumps (in large C files)

2010-06-14 Thread wesley at terpstra dot ca
The assembler instructions gcc generates for a 'goto' statement only respect
the low 16 bits of the destination address by default (or in when using PIC in
general). This causes the program to jump to the wrong location and soon
thereafter segfault. The -mno-explicit-relocs seems to work around this
problem, but is no solution for a PIC compilation.

This problem appears in both:
Using built-in specs.
Target: mips-unknown-linux-gnu
Configured with: ../gcc/configure --prefix=/home/terpstra/gcc.bin
--enable-languages=c
Thread model: posix
gcc version 4.4.4 (GCC) 

and:
Using built-in specs.
Target: mips-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Debian 4.4.4-3'
--with-bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs
--enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --enable-shared
--enable-multiarch --enable-linker-build-id --with-system-zlib
--libexecdir=/usr/lib --without-included-gettext --enable-threads=posix
--with-gxx-include-dir=/usr/include/c++/4.4 --program-suffix=-4.4 --enable-nls
--enable-clocale=gnu --enable-libstdcxx-debug --disable-libssp
--enable-targets=all --enable-checking=release --build=mips-linux-gnu
--host=mips-linux-gnu --target=mips-linux-gnu
Thread model: posix
gcc version 4.4.4 (Debian 4.4.4-3) 

However, I've been having related problems since as far back as gcc-3.4 (at
least). The gcc-snapshot in debian also does not resolve this issue. Sometimes
different compiler versions and/or optimization flags cause compilation to
succeed. I presume this is because the jump offsets fit into 16 bits with
different optimization choices. I've seen a related problem where gcc -fPIC
creates invalid assembler that with 'branch out of range' .s files. However,
first I'll see if this bug being fixed resolves the other.

I've included an example C program which can produce the buggy assembler.
Compile with:
 -std=gnu99 -O0 -fno-common -fno-strict-aliasing -fomit-frame-pointer -w
-S mlyacc.6.preprocessed-nolines.c -g -o bug.s

The problem assembler comes from the goto on line 2928:
   goto leaveChunk; 
... when tracing with gdb execution should resume on line 33861, however it
instead jumps to line 2749:

Inspecting the generated assembler:
.loc 1 2928 0
.setnoat
lw  $1,%got($L894)($28)
nop
addiu   $1,$1,%lo($L894) 
jr  $1
... it is easy to see that the correct label (L894) is used as destination.
However, only the low 16 bits of the address are used.

When compiled with -mno-explicit-relocs, the assembler reads as:
.loc 1 2928 0
.setnoat
la  $1,$L894 #
jr  $1   
... which works. Modifying the -mexplicit-relocs version (gcc default) to use
'la' instead of the PIC %got results in correct program execution.


-- 
   Summary: gcc produces bad MIPS jumps (in large C files)
   Product: gcc
   Version: 4.4.4
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: wesley at terpstra dot ca
 GCC build triplet: mips-unknown-linux-gnu
  GCC host triplet: mips-unknown-linux-gnu
GCC target triplet: mips-unknown-linux-gnu


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44537



[Bug c/44537] gcc produces bad MIPS jumps (in large C files)

2010-06-14 Thread wesley at terpstra dot ca


--- Comment #1 from wesley at terpstra dot ca  2010-06-14 15:53 ---
Created an attachment (id=20908)
 --> (http://gcc.gnu.org/bugzilla/attachment.cgi?id=20908&action=view)
Pre-processed example file with bad branches.

Compile as described in the initial bug report.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44537



[Bug c/44537] gcc produces bad MIPS jumps (in large C files)

2010-06-14 Thread wesley at terpstra dot ca


--- Comment #3 from wesley at terpstra dot ca  2010-06-14 16:40 ---
(sid)terps...@gabrielli:~/mlton/mlton-20100608$ as -v
GNU assembler version 2.20.1 (mips-linux-gnu) using BFD version (GNU Binutils
for Debian) 2.20.1-system.20100303

... is the %got($L894) supposed to cover the case where the label is not in the
same high 16-bits as the start of the text section?


-- 

wesley at terpstra dot ca changed:

   What|Removed |Added

  Component|target  |c


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44537



[Bug target/44537] gcc produces bad MIPS jumps (in large C files)

2010-06-14 Thread wesley at terpstra dot ca


--- Comment #4 from wesley at terpstra dot ca  2010-06-14 17:22 ---
Created an attachment (id=20909)
 --> (http://gcc.gnu.org/bugzilla/attachment.cgi?id=20909&action=view)
Libraries needed to demonstrate the problem in a linked program

To be able to run the complete program:

gcc -std=gnu99 -mno-explicit-relocs -O0 -g -w -fno-strict-aliasing
mlyacc.6.preprocessed-nolines.c link.a -lgmp -lm -o mlyacc.good
gcc -std=gnu99 -O0 -g -w -fno-strict-aliasing mlyacc.6.preprocessed-nolines.c
link.a -lgmp -lm -o mlyacc.bad

... you need gmp 4.3.x to link it (which I imagine all gcc developers have).


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44537



[Bug target/44537] gcc produces bad MIPS jumps (in large C files)

2010-06-14 Thread wesley at terpstra dot ca


--- Comment #5 from wesley at terpstra dot ca  2010-06-14 17:25 ---
In case it is a binutils problem, I've attached a '.a' file sufficient to fully
link the program. To get to the problem jump is pretty easy:

gdb ./mlyacc.bad
break Chunk6
run
s


OUTPUT:
2926 nextFun = 2736; 
(gdb) 
2928   goto leaveChunk; 
(gdb) 

Program received signal SIGSEGV, Segmentation fault.
0x2aaad880 in ?? () from /lib/ld.so.1

./mlyacc.good says:
too many files
Usage: mlyacc.good file.grm

(of course it does a lot more if provided a .grm file)


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44537