mirror of
https://github.com/frida/tinycc
synced 2024-11-28 02:29:38 +03:00
use data_offset in sections instead of pointer to ease section reallocation
This commit is contained in:
parent
9b48237795
commit
a42941b1f0
58
i386-gen.c
58
i386-gen.c
@ -79,13 +79,14 @@ typedef struct GFuncContext {
|
|||||||
|
|
||||||
/******************************************************/
|
/******************************************************/
|
||||||
|
|
||||||
static int *func_sub_sp_ptr;
|
static unsigned long func_sub_sp_offset;
|
||||||
static unsigned char *func_bound_ptr;
|
static unsigned long func_bound_offset;
|
||||||
static int func_ret_sub;
|
static int func_ret_sub;
|
||||||
|
|
||||||
void g(int c)
|
void g(int c)
|
||||||
{
|
{
|
||||||
*(char *)ind++ = c;
|
cur_text_section->data[ind] = c;
|
||||||
|
ind++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void o(int c)
|
void o(int c)
|
||||||
@ -107,10 +108,11 @@ void gen_le32(int c)
|
|||||||
/* output a symbol and patch all calls to it */
|
/* output a symbol and patch all calls to it */
|
||||||
void gsym_addr(int t, int a)
|
void gsym_addr(int t, int a)
|
||||||
{
|
{
|
||||||
int n;
|
int n, *ptr;
|
||||||
while (t) {
|
while (t) {
|
||||||
n = *(int *)t; /* next value */
|
ptr = (int *)(cur_text_section->data + t);
|
||||||
*(int *)t = a - t - 4;
|
n = *ptr; /* next value */
|
||||||
|
*ptr = a - t - 4;
|
||||||
t = n;
|
t = n;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -128,7 +130,7 @@ void gsym(int t)
|
|||||||
int oad(int c, int s)
|
int oad(int c, int s)
|
||||||
{
|
{
|
||||||
o(c);
|
o(c);
|
||||||
*(int *)ind = s;
|
*(int *)(cur_text_section->data + ind) = s;
|
||||||
s = ind;
|
s = ind;
|
||||||
ind = ind + 4;
|
ind = ind + 4;
|
||||||
return s;
|
return s;
|
||||||
@ -141,7 +143,7 @@ void gen_addr32(int r, int c)
|
|||||||
gen_le32(c);
|
gen_le32(c);
|
||||||
} else {
|
} else {
|
||||||
greloc(cur_text_section,
|
greloc(cur_text_section,
|
||||||
(Sym *)c, ind - (int)cur_text_section->data, R_386_32);
|
(Sym *)c, ind, R_386_32);
|
||||||
gen_le32(0);
|
gen_le32(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -351,7 +353,7 @@ void gfunc_call(GFuncContext *c)
|
|||||||
if (vtop->r & VT_SYM) {
|
if (vtop->r & VT_SYM) {
|
||||||
/* relocation case */
|
/* relocation case */
|
||||||
greloc(cur_text_section, vtop->c.sym,
|
greloc(cur_text_section, vtop->c.sym,
|
||||||
ind + 1 - (int)cur_text_section->data, R_386_PC32);
|
ind + 1, R_386_PC32);
|
||||||
oad(0xe8, -4);
|
oad(0xe8, -4);
|
||||||
} else {
|
} else {
|
||||||
oad(0xe8, vtop->c.ul - ind - 5);
|
oad(0xe8, vtop->c.ul - ind - 5);
|
||||||
@ -403,12 +405,12 @@ void gfunc_prolog(int t)
|
|||||||
if (func_call == FUNC_STDCALL)
|
if (func_call == FUNC_STDCALL)
|
||||||
func_ret_sub = addr - 8;
|
func_ret_sub = addr - 8;
|
||||||
o(0xe58955); /* push %ebp, mov %esp, %ebp */
|
o(0xe58955); /* push %ebp, mov %esp, %ebp */
|
||||||
func_sub_sp_ptr = (int *)oad(0xec81, 0); /* sub $xxx, %esp */
|
func_sub_sp_offset = oad(0xec81, 0); /* sub $xxx, %esp */
|
||||||
/* leave some room for bound checking code */
|
/* leave some room for bound checking code */
|
||||||
if (do_bounds_check) {
|
if (do_bounds_check) {
|
||||||
oad(0xb8, 0); /* lbound section pointer */
|
oad(0xb8, 0); /* lbound section pointer */
|
||||||
oad(0xb8, 0); /* call to function */
|
oad(0xb8, 0); /* call to function */
|
||||||
func_bound_ptr = lbounds_section->data_ptr;
|
func_bound_offset = lbounds_section->data_offset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -416,36 +418,34 @@ void gfunc_prolog(int t)
|
|||||||
void gfunc_epilog(void)
|
void gfunc_epilog(void)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_TCC_BCHECK
|
#ifdef CONFIG_TCC_BCHECK
|
||||||
if (do_bounds_check && func_bound_ptr != lbounds_section->data_ptr) {
|
if (do_bounds_check && func_bound_offset != lbounds_section->data_offset) {
|
||||||
int saved_ind;
|
int saved_ind;
|
||||||
int *bounds_ptr;
|
int *bounds_ptr;
|
||||||
Sym *sym, *sym_data;
|
Sym *sym, *sym_data;
|
||||||
/* add end of table info */
|
/* add end of table info */
|
||||||
bounds_ptr = (int *)lbounds_section->data_ptr;
|
bounds_ptr = section_ptr_add(lbounds_section, sizeof(int));
|
||||||
*bounds_ptr++ = 0;
|
*bounds_ptr = 0;
|
||||||
lbounds_section->data_ptr = (unsigned char *)bounds_ptr;
|
|
||||||
/* generate bound local allocation */
|
/* generate bound local allocation */
|
||||||
saved_ind = ind;
|
saved_ind = ind;
|
||||||
ind = (int)func_sub_sp_ptr + 4;
|
ind = func_sub_sp_offset + 4;
|
||||||
sym_data = get_sym_ref(char_pointer_type, lbounds_section,
|
sym_data = get_sym_ref(char_pointer_type, lbounds_section,
|
||||||
func_bound_ptr - lbounds_section->data,
|
func_bound_offset, lbounds_section->data_offset);
|
||||||
lbounds_section->data_ptr - func_bound_ptr);
|
|
||||||
greloc(cur_text_section, sym_data,
|
greloc(cur_text_section, sym_data,
|
||||||
ind + 1 - (int)cur_text_section->data, R_386_32);
|
ind + 1, R_386_32);
|
||||||
oad(0xb8, 0); /* mov %eax, xxx */
|
oad(0xb8, 0); /* mov %eax, xxx */
|
||||||
sym = external_sym(TOK___bound_local_new, func_old_type, 0);
|
sym = external_sym(TOK___bound_local_new, func_old_type, 0);
|
||||||
greloc(cur_text_section, sym,
|
greloc(cur_text_section, sym,
|
||||||
ind + 1 - (int)cur_text_section->data, R_386_PC32);
|
ind + 1, R_386_PC32);
|
||||||
oad(0xe8, -4);
|
oad(0xe8, -4);
|
||||||
ind = saved_ind;
|
ind = saved_ind;
|
||||||
/* generate bound check local freeing */
|
/* generate bound check local freeing */
|
||||||
o(0x5250); /* save returned value, if any */
|
o(0x5250); /* save returned value, if any */
|
||||||
greloc(cur_text_section, sym_data,
|
greloc(cur_text_section, sym_data,
|
||||||
ind + 1 - (int)cur_text_section->data, R_386_32);
|
ind + 1, R_386_32);
|
||||||
oad(0xb8, 0); /* mov %eax, xxx */
|
oad(0xb8, 0); /* mov %eax, xxx */
|
||||||
sym = external_sym(TOK___bound_local_delete, func_old_type, 0);
|
sym = external_sym(TOK___bound_local_delete, func_old_type, 0);
|
||||||
greloc(cur_text_section, sym,
|
greloc(cur_text_section, sym,
|
||||||
ind + 1 - (int)cur_text_section->data, R_386_PC32);
|
ind + 1, R_386_PC32);
|
||||||
oad(0xe8, -4);
|
oad(0xe8, -4);
|
||||||
o(0x585a); /* restore returned value, if any */
|
o(0x585a); /* restore returned value, if any */
|
||||||
}
|
}
|
||||||
@ -459,7 +459,7 @@ void gfunc_epilog(void)
|
|||||||
g(func_ret_sub >> 8);
|
g(func_ret_sub >> 8);
|
||||||
}
|
}
|
||||||
/* align local size to word & save local variables */
|
/* align local size to word & save local variables */
|
||||||
*func_sub_sp_ptr = (-loc + 3) & -4;
|
*(int *)(cur_text_section->data + func_sub_sp_offset) = (-loc + 3) & -4;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* generate a jump to a label */
|
/* generate a jump to a label */
|
||||||
@ -489,7 +489,7 @@ int gtst(int inv, int t)
|
|||||||
/* insert vtop->c jump list in t */
|
/* insert vtop->c jump list in t */
|
||||||
p = &vtop->c.i;
|
p = &vtop->c.i;
|
||||||
while (*p != 0)
|
while (*p != 0)
|
||||||
p = (int *)*p;
|
p = (int *)(cur_text_section->data + *p);
|
||||||
*p = t;
|
*p = t;
|
||||||
t = vtop->c.i;
|
t = vtop->c.i;
|
||||||
} else {
|
} else {
|
||||||
@ -809,7 +809,7 @@ void gen_cvt_ftoi(int t)
|
|||||||
sym = external_sym(TOK___tcc_int_fpu_control,
|
sym = external_sym(TOK___tcc_int_fpu_control,
|
||||||
VT_SHORT | VT_UNSIGNED, VT_LVAL);
|
VT_SHORT | VT_UNSIGNED, VT_LVAL);
|
||||||
greloc(cur_text_section, sym,
|
greloc(cur_text_section, sym,
|
||||||
ind - (int)cur_text_section->data, R_386_32);
|
ind, R_386_32);
|
||||||
gen_le32(0);
|
gen_le32(0);
|
||||||
|
|
||||||
oad(0xec81, size); /* sub $xxx, %esp */
|
oad(0xec81, size); /* sub $xxx, %esp */
|
||||||
@ -822,7 +822,7 @@ void gen_cvt_ftoi(int t)
|
|||||||
sym = external_sym(TOK___tcc_fpu_control,
|
sym = external_sym(TOK___tcc_fpu_control,
|
||||||
VT_SHORT | VT_UNSIGNED, VT_LVAL);
|
VT_SHORT | VT_UNSIGNED, VT_LVAL);
|
||||||
greloc(cur_text_section, sym,
|
greloc(cur_text_section, sym,
|
||||||
ind - (int)cur_text_section->data, R_386_32);
|
ind, R_386_32);
|
||||||
gen_le32(0);
|
gen_le32(0);
|
||||||
|
|
||||||
r = get_reg(RC_INT);
|
r = get_reg(RC_INT);
|
||||||
@ -863,13 +863,13 @@ void gen_bounded_ptr_add(void)
|
|||||||
/* do a fast function call */
|
/* do a fast function call */
|
||||||
sym = external_sym(TOK___bound_ptr_add, func_old_type, 0);
|
sym = external_sym(TOK___bound_ptr_add, func_old_type, 0);
|
||||||
greloc(cur_text_section, sym,
|
greloc(cur_text_section, sym,
|
||||||
ind + 1 - (int)cur_text_section->data, R_386_PC32);
|
ind + 1, R_386_PC32);
|
||||||
oad(0xe8, -4);
|
oad(0xe8, -4);
|
||||||
/* returned pointer is in eax */
|
/* returned pointer is in eax */
|
||||||
vtop++;
|
vtop++;
|
||||||
vtop->r = REG_EAX | VT_BOUNDED;
|
vtop->r = REG_EAX | VT_BOUNDED;
|
||||||
/* address of bounding function call point */
|
/* address of bounding function call point */
|
||||||
vtop->c.ptr = (cur_text_section->reloc->data_ptr - sizeof(Elf32_Rel));
|
vtop->c.ul = (cur_text_section->reloc->data_offset - sizeof(Elf32_Rel));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* patch pointer addition in vtop so that pointer dereferencing is
|
/* patch pointer addition in vtop so that pointer dereferencing is
|
||||||
@ -906,7 +906,7 @@ void gen_bounded_ptr_deref(void)
|
|||||||
|
|
||||||
/* patch relocation */
|
/* patch relocation */
|
||||||
/* XXX: find a better solution ? */
|
/* XXX: find a better solution ? */
|
||||||
rel = vtop->c.ptr;
|
rel = (Elf32_Rel *)(cur_text_section->reloc->data + vtop->c.ul);
|
||||||
sym = external_sym(func, func_old_type, 0);
|
sym = external_sym(func, func_old_type, 0);
|
||||||
if (!sym->c)
|
if (!sym->c)
|
||||||
put_extern_sym(sym, NULL, 0);
|
put_extern_sym(sym, NULL, 0);
|
||||||
|
Loading…
Reference in New Issue
Block a user