use data_offset in sections instead of pointer to ease section reallocation

This commit is contained in:
bellard 2002-07-27 14:06:11 +00:00
parent 9b48237795
commit a42941b1f0

View File

@ -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);