Andrew Haley wrote:
David Daney writes:
> Richard,
>
> Sometime between 1/7 and 1/16 on the trunk I started getting wrong code
> on a bunch of java testcases under mipsel-linux.
>
> It looks related to (but not necessarily caused by) this patch:
>
> http://gcc.gnu.org/ml/gcc-patches/2006-03/msg01346.html
>
> For example if we examine the assembler output of the PR9577.java
> testcase, we see:
>
> .
> .
> .
> $LBB2:
> lw $2,40($fp)
> sw $2,24($fp)
> lw $2,24($fp)
> move $4,$2
> .option pic0
> jal _ZN4java4lang6ObjectC1Ev
> nop
>
> .option pic2
> lw $28,16($fp)
> $LBE2:
> move $sp,$fp
> lw $31,36($sp)
> lw $fp,32($sp)
> addiu $sp,$sp,40
> j $31
> nop
>
> The call to _ZN4java4lang6ObjectC1Ev is being generated as non-pic, even
> though that symbol is defined in libgcj.so. The assembler and linker
> conspire to jump to address 0x00000000 for this call.
>
> It looks like the logic that decides if a symbol is external to the
> compilation unit is faulty.
>
> Any ideas about where it might have gone wrong?
Does http://gcc.gnu.org/ml/gcc/2007-01/msg01184.html fix this?
Unfortunately no. The following output is generated with r121186 +
Andrew.s patched class.c
There are several problems with the generated code for the failing class:
public class PR9577
{
private native void sayHello (String[] s, Object o);
public static void main (String[] args)
{
PR9577 x = new PR9577( );
x.sayHello( null, null);
}
}
Note that this class has an implicit public constructor that does
nothing other than call the super class (java.lang.Object) constructor.
/home/build/gcc-build/gcc/gcj -v
-B/home/build/gcc-build/mipsel-unknown-linux-gnu/libjava/
-B/home/build/gcc-build/gcc/ --encoding=UTF-8
-B/home/build/gcc-build/mipsel-unknown-linux-gnu/libjava/testsuite/../
/home/build/gcc/libjava/testsuite/libjava.cni/PR9577.jar -o j.s -S
Here is the entire generated code for the constructor:
.globl _ZN6PR9577C1Ev
.ent _ZN6PR9577C1Ev
.type _ZN6PR9577C1Ev, @function
_ZN6PR9577C1Ev:
$LFB2:
.frame $fp,40,$31 # vars= 8, regs= 2/0, args= 16,
gp= 8
.mask 0xc0000000,-4
.fmask 0x00000000,0
.set noreorder
.set nomacro
addiu $sp,$sp,-40
$LCFI0:
sw $31,36($sp)
$LCFI1:
sw $fp,32($sp)
$LCFI2:
move $fp,$sp
$LCFI3:
.cprestore 16
sw $4,40($fp)
$LBB2:
lw $2,40($fp)
sw $2,24($fp)
lw $2,24($fp)
move $4,$2
.option pic0
jal _ZN4java4lang6ObjectC1Ev
nop
.option pic2
lw $28,16($fp)
$LBE2:
move $sp,$fp
lw $31,36($sp)
lw $fp,32($sp)
addiu $sp,$sp,40
j $31
nop
.set macro
.set reorder
$LFE2:
.end _ZN6PR9577C1Ev
Here are the problems I see:
1) The call to _ZN4java4lang6ObjectC1Ev is absolute instead of via the
plt. That function is in a shared library not this compilation unit.
2) It is a public global method. $gp should be initialized, but it is not.
If I compile it with -O3 -mshared I get:
.globl _ZN6PR9577C1Ev
.ent _ZN6PR9577C1Ev
.type _ZN6PR9577C1Ev, @function
_ZN6PR9577C1Ev:
$LFB2:
.frame $sp,32,$31 # vars= 0, regs= 1/0, args= 16,
gp= 8
.mask 0x80000000,-8
.fmask 0x00000000,0
.set noreorder
.cpload $25
.set nomacro
addiu $sp,$sp,-32
$LCFI0:
sw $31,24($sp)
$LCFI1:
.cprestore 16
lw $25,%call16(_ZN4java4lang6ObjectC1Ev)($28)
jalr $25
nop
lw $28,16($sp)
lw $31,24($sp)
j $31
addiu $sp,$sp,32
.set macro
.set reorder
$LFE2:
.end _ZN6PR9577C1Ev
This time the call to _ZN4java4lang6ObjectC1Ev *is* done via the plt,
but we are using .cpload instead of having gcc generate the individual
instructions and interleaving them with the $sp adjustment as it
normally does.
David Daney