mirror of
https://github.com/frida/tinycc
synced 2024-12-26 06:56:49 +03:00
x86_64: Fix segfault for global data
When offsetted addresses of global non-static data are computed multiple times in the same statement the x86_64 backend uses gen_gotpcrel with offset, which implements an add insn on the register given. load() uses the R member of the to-be-loaded value, which doesn't yet have a reg assigned in all cases. So use the register we're supposed to load the value into as that register.
This commit is contained in:
parent
86ac6b9bee
commit
1d0a5c2515
@ -85,6 +85,7 @@ void statement_expr_test(void);
|
|||||||
void asm_test(void);
|
void asm_test(void);
|
||||||
void builtin_test(void);
|
void builtin_test(void);
|
||||||
void weak_test(void);
|
void weak_test(void);
|
||||||
|
void global_data_test(void);
|
||||||
|
|
||||||
int fib(int n);
|
int fib(int n);
|
||||||
void num(int n);
|
void num(int n);
|
||||||
@ -583,6 +584,7 @@ int main(int argc, char **argv)
|
|||||||
asm_test();
|
asm_test();
|
||||||
builtin_test();
|
builtin_test();
|
||||||
weak_test();
|
weak_test();
|
||||||
|
global_data_test();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2509,3 +2511,31 @@ int getme (struct condstruct *s, int i)
|
|||||||
int i4 = (i == 0 ? s : (void*)0)->i;
|
int i4 = (i == 0 ? s : (void*)0)->i;
|
||||||
return i1 + i2 + i3 + i4;
|
return i1 + i2 + i3 + i4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct global_data
|
||||||
|
{
|
||||||
|
int a[40];
|
||||||
|
int *b[40];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct global_data global_data;
|
||||||
|
|
||||||
|
int global_data_getstuff (int *, int);
|
||||||
|
|
||||||
|
void global_data_callit (int i)
|
||||||
|
{
|
||||||
|
*global_data.b[i] = global_data_getstuff (global_data.b[i], 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int global_data_getstuff (int *p, int i)
|
||||||
|
{
|
||||||
|
return *p + i;
|
||||||
|
}
|
||||||
|
|
||||||
|
void global_data_test (void)
|
||||||
|
{
|
||||||
|
global_data.a[0] = 42;
|
||||||
|
global_data.b[0] = &global_data.a[0];
|
||||||
|
global_data_callit (0);
|
||||||
|
printf ("%d\n", global_data.a[0]);
|
||||||
|
}
|
||||||
|
@ -414,7 +414,7 @@ void load(int r, SValue *sv)
|
|||||||
} else {
|
} else {
|
||||||
orex(1,0,r,0x8b);
|
orex(1,0,r,0x8b);
|
||||||
o(0x05 + REG_VALUE(r) * 8); /* mov xx(%rip), r */
|
o(0x05 + REG_VALUE(r) * 8); /* mov xx(%rip), r */
|
||||||
gen_gotpcrel(fr, sv->sym, fc);
|
gen_gotpcrel(r, sv->sym, fc);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
} else if (is64_type(ft)) {
|
} else if (is64_type(ft)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user