Closed GoogleCodeExporter closed 8 years ago
Oops, looks like I've described the error for the wrong test case. The one that
I
actually had in mind was "gcc.c-torture/execute/20020412-1.c".
Original comment by nou...@gmail.com
on 2 Dec 2008 at 10:24
Below is the simplified version of the "20020412-1.c" test case:
{{{
extern void abort (void);
void foo (int size, char *t)
{
int i;
if (t[0] != '0')
abort();
}
int main (void)
{
int z = 5;
char a[z];
a[0] = '0';
a[1] = '1';
a[2] = '2';
a[3] = '3';
a[4] = '4';
foo (z, a);
}
}}}
The test fails because we overwrite the "30313233 34001d40" values when putting
the
arguments for the "foo" function to the callee stack:
stl $s35,-284(,$s2)
sts $s36,-280(,$s2)
lds $s35,.LC2 #movdi case3
lea $s36,2
sts $s36,-296(,$s2)
lea $s34,-296(,$s2)
or $s33,0,$s35
bsic $s32,($s33)
The values are overwritten after the "sts $s36,-296(,$s2)" instruction is
executed.
Original comment by nou...@gmail.com
on 3 Dec 2008 at 2:57
Well, the error has to be in the code for dynamic allocation of arrays, since
the
example below, which uses statically allocated array, works ok:
{{{
extern void abort (void);
void foo (int size, char *t)
{
int i;
if (t[0] != '0')
abort();
}
int main (void)
{
int z = 5;
char a[5];
a[0] = '0';
a[1] = '1';
a[2] = '2';
a[3] = '3';
a[4] = '4';
foo (z, a);
}
}}}
Original comment by nou...@gmail.com
on 3 Dec 2008 at 5:24
After a very careful examination of the assembly code for the simplified
example (the
one that fails), it all seems to me that the problem lies in the "lea
$s36,-272(,$s2)" instruction (see the file attached). This one loads the
starting
address for the variable length array. But strangely, the address the "lea"
instruction loads, belongs to the stack of the callee function. Wouldn't be more
sensible that the array would be loaded to the memory space that belongs to the
caller function?
Moreover, after the stack increase, the "-272(,$s2)" address is exactly the
address
where the arguments for the callee function are stored. As a result, the array
gets
overwritten right before the "foo" function is being called.
Original comment by nou...@gmail.com
on 4 Dec 2008 at 5:19
Attachments:
It turns out that the problem was in the "STACK_DYNAMIC_OFFSET" macro which is
used
for calculating the offset to the start of dynamically allocated memory on the
stack
(which resulted in a "lea $s36,-272(,$s2)" instruction with the incorrect
offset).
Before, we used the default implementation of the macro, which calculates the
offset
to the dynamically allocated memory on the stack by using the following formula:
"STACK_DYNAMIC_OFFSET = STACK_POINTER_OFFSET + length_of_arguments". This
formula is
valid only if the STACK_POINTER_OFFSET offset is positive. Since SX uses
negative
STACK_POINTER_OFFSET the correct formula is, as follows:
"STACK_DYNAMIC_OFFSET = STACK_POINTER_OFFSET - length_of_arguments"
After defining the SX-specific STACK_DYNAMIC_OFFSET macro in "sx.h", the test
case
works ok.
Original comment by nou...@gmail.com
on 8 Dec 2008 at 9:35
no, the definition suggested above is flawed. it makes the above test case
work, but
only due to sheer luck.
gcc.dg/struct-by-value-22 fails due to wrong calculation of
STACK_DYNAMIC_OFFSET.
for the time being, we assume that dynamically allocated stack space (due to
variable
sized arrays or alloca() calls) is put between statically allocated locals and
outgoing vars. in this case the definition is
#define STACK_DYNAMIC_OFFSET(FUNDECL) \
(-SX_RSA_SIZE - current_function_outgoing_args_size - 8)
which works with all relevant test cases ...
Original comment by jmoc...@gmail.com
on 6 Feb 2009 at 11:21
fixed with r221.
Original comment by jmoc...@gmail.com
on 6 Feb 2009 at 11:21
attaching a test case that thoroughly checks for stack trashing due to dynamic
stack
sizing.
Original comment by jmoc...@gmail.com
on 6 Feb 2009 at 12:59
Attachments:
Original issue reported on code.google.com by
nou...@gmail.com
on 1 Dec 2008 at 10:56