Melchior FRANZ wrote:

* Melchior FRANZ -- Friday 02 December 2005 01:43:
But ... we weren't really returning the address of an auto var.

Is it a gcc 4.0.2 (SuSE 10.0) compiler bug? tiny_xdr.cxx contains
this function;

 float
 XDR_decode_float ( const xdr_data_t & f_Val )
 {
     float* tmp;
     xdr_data_t dummy;

     dummy = XDR_decode_int32 (f_Val);
     tmp = (float*) &dummy;
     return (*tmp);
 }


And it turned out that when compiled with gcc 4.0.2 the return
value wasn't safe. When called three times in a row with different
values, we would get three times the same result. None of those
correct. This placed MP aircraft somewhere around the middle
of our Earth. For those understanding x86 assembler, here is
the resulting code (why does it not call _Z16XDR_decode_int32RKj?
"Optimized" away?):


decode_int32 is a nop on a x86 anyway

non-static "dummy"  (-O2)     --> doesn't work

(gdb) disass XDR_decode_float
Dump of assembler code for function _Z16XDR_decode_floatRKj:
0x08310816 <_Z16XDR_decode_floatRKj+0>:  push   %ebp
0x08310817 <_Z16XDR_decode_floatRKj+1>:  mov    %esp,%ebp
0x08310819 <_Z16XDR_decode_floatRKj+3>:  sub    $0x10,%esp
0x0831081c <_Z16XDR_decode_floatRKj+6>:  flds   0xfffffffc(%ebp)
0x0831081f <_Z16XDR_decode_floatRKj+9>:  leave
0x08310820 <_Z16XDR_decode_floatRKj+10>: ret
End of assembler dump.


This code does what it is supposed do to ie : return *((float *) arg);
except that.... & arg == 0xfffffffc(%esp)

non-static "dummy"  (-O0)     --> works

(gdb) disass XDR_decode_float
Dump of assembler code for function _Z16XDR_decode_floatRKj:
0x083be33a <_Z16XDR_decode_floatRKj+0>:  push   %ebp
0x083be33b <_Z16XDR_decode_floatRKj+1>:  mov    %esp,%ebp
0x083be33d <_Z16XDR_decode_floatRKj+3>:  sub    $0x18,%esp
0x083be340 <_Z16XDR_decode_floatRKj+6>:  mov    0x8(%ebp),%eax
0x083be343 <_Z16XDR_decode_floatRKj+9>:  mov    %eax,(%esp)
0x083be346 <_Z16XDR_decode_floatRKj+12>: call   0x83be1b4 
<_Z16XDR_decode_int32RKj>

& arg == 0x8(%esp)

static "dummy"                --> works

(gdb) disass XDR_decode_float
Dump of assembler code for function _Z16XDR_decode_floatRKj:
0x08310816 <_Z16XDR_decode_floatRKj+0>:  push   %ebp
0x08310817 <_Z16XDR_decode_floatRKj+1>:  mov    %esp,%ebp
0x08310819 <_Z16XDR_decode_floatRKj+3>:  sub    $0x4,%esp
0x0831081c <_Z16XDR_decode_floatRKj+6>:  mov    0x8(%ebp),%eax
0x0831081f <_Z16XDR_decode_floatRKj+9>:  mov    %eax,(%esp)
0x08310822 <_Z16XDR_decode_floatRKj+12>: call   0x83107e2 
<_Z16XDR_decode_int32RKj>
& arg == 0x8(%esp)
The code generated with -O2 and without static is wrong. Functions parameters are allways at a positive offset from sp. Perhaps adding a volatile modifier on the tmp pointer
could do the trick (of course doing that disables optimisations).

Harald.


_______________________________________________
Flightgear-devel mailing list
Flightgear-devel@flightgear.org
http://mail.flightgear.org/mailman/listinfo/flightgear-devel
2f585eeea02e2c79d7b1d8c4963bae2d

Reply via email to