mirror of
https://github.com/frida/tinycc
synced 2025-01-24 12:12:05 +03:00
x86-64: Fix call saved register restore
Loads of VT_LLOCAL values (which effectively represent saved addresses of lvalues) were done in VT_INT type, loosing the upper 32 bits. Needs to be done in VT_PTR type.
This commit is contained in:
parent
9a81dcab0a
commit
a42b029101
@ -88,6 +88,7 @@ void weak_test(void);
|
|||||||
void global_data_test(void);
|
void global_data_test(void);
|
||||||
void cmp_comparison_test(void);
|
void cmp_comparison_test(void);
|
||||||
void math_cmp_test(void);
|
void math_cmp_test(void);
|
||||||
|
void callsave_test(void);
|
||||||
|
|
||||||
int fib(int n);
|
int fib(int n);
|
||||||
void num(int n);
|
void num(int n);
|
||||||
@ -596,6 +597,7 @@ int main(int argc, char **argv)
|
|||||||
global_data_test();
|
global_data_test();
|
||||||
cmp_comparison_test();
|
cmp_comparison_test();
|
||||||
math_cmp_test();
|
math_cmp_test();
|
||||||
|
callsave_test();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2658,3 +2660,21 @@ void math_cmp_test(void)
|
|||||||
FCMP(nan, nan, >, !=, 4);
|
FCMP(nan, nan, >, !=, 4);
|
||||||
FCMP(nan, nan, <=, !=, 5);
|
FCMP(nan, nan, <=, !=, 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double get100 () { return 100.0; }
|
||||||
|
|
||||||
|
void callsave_test(void)
|
||||||
|
{
|
||||||
|
int i, s; double *d; double t;
|
||||||
|
s = sizeof (double);
|
||||||
|
printf ("callsavetest: %d\n", s);
|
||||||
|
d = alloca (sizeof(double));
|
||||||
|
d[0] = 10.0;
|
||||||
|
/* x86-64 had a bug were the next call to get100 would evict
|
||||||
|
the lvalue &d[0] as VT_LLOCAL, and the reload would be done
|
||||||
|
in int type, not pointer type. When alloca returns a pointer
|
||||||
|
with the high 32 bit set (which is likely on x86-64) the access
|
||||||
|
generates a segfault. */
|
||||||
|
i = d[0] > get100 ();
|
||||||
|
printf ("%d\n", i);
|
||||||
|
}
|
||||||
|
@ -1460,7 +1460,7 @@ void gen_opf(int op)
|
|||||||
if ((r & VT_VALMASK) == VT_LLOCAL) {
|
if ((r & VT_VALMASK) == VT_LLOCAL) {
|
||||||
SValue v1;
|
SValue v1;
|
||||||
r = get_reg(RC_INT);
|
r = get_reg(RC_INT);
|
||||||
v1.type.t = VT_INT;
|
v1.type.t = VT_PTR;
|
||||||
v1.r = VT_LOCAL | VT_LVAL;
|
v1.r = VT_LOCAL | VT_LVAL;
|
||||||
v1.c.ul = fc;
|
v1.c.ul = fc;
|
||||||
load(r, &v1);
|
load(r, &v1);
|
||||||
@ -1531,7 +1531,7 @@ void gen_opf(int op)
|
|||||||
if ((r & VT_VALMASK) == VT_LLOCAL) {
|
if ((r & VT_VALMASK) == VT_LLOCAL) {
|
||||||
SValue v1;
|
SValue v1;
|
||||||
r = get_reg(RC_INT);
|
r = get_reg(RC_INT);
|
||||||
v1.type.t = VT_INT;
|
v1.type.t = VT_PTR;
|
||||||
v1.r = VT_LOCAL | VT_LVAL;
|
v1.r = VT_LOCAL | VT_LVAL;
|
||||||
v1.c.ul = fc;
|
v1.c.ul = fc;
|
||||||
load(r, &v1);
|
load(r, &v1);
|
||||||
|
Loading…
Reference in New Issue
Block a user