aboutsummaryrefslogtreecommitdiff
path: root/i386-gen.c
diff options
context:
space:
mode:
authorbellard <bellard>2005-04-10 22:15:08 +0000
committerbellard <bellard>2005-04-10 22:15:08 +0000
commit9825011cedeb3fdcfb54e312ab27d92a2a8488b0 (patch)
tree3980762db7e9c639693d451d1af0a886b093430e /i386-gen.c
parent2c538d7a2b0fb9e72c0fbb9af5d351302584aca0 (diff)
downloadtinycc-9825011cedeb3fdcfb54e312ab27d92a2a8488b0.tar.gz
tinycc-9825011cedeb3fdcfb54e312ab27d92a2a8488b0.tar.bz2
__chkstk support
Diffstat (limited to 'i386-gen.c')
-rw-r--r--i386-gen.c37
1 files changed, 32 insertions, 5 deletions
diff --git a/i386-gen.c b/i386-gen.c
index b6d5ac3..e988924 100644
--- a/i386-gen.c
+++ b/i386-gen.c
@@ -398,6 +398,12 @@ void gfunc_call(int nb_args)
vtop--;
}
+#ifdef TCC_TARGET_PE
+#define FUNC_PROLOG_SIZE 10
+#else
+#define FUNC_PROLOG_SIZE 9
+#endif
+
/* generate function prolog of type 't' */
void gfunc_prolog(CType *func_type)
{
@@ -417,9 +423,8 @@ void gfunc_prolog(CType *func_type)
}
param_index = 0;
- o(0xe58955); /* push %ebp, mov %esp, %ebp */
- func_sub_sp_offset = oad(0xec81, 0); /* sub $xxx, %esp */
-
+ ind += FUNC_PROLOG_SIZE;
+ func_sub_sp_offset = ind;
/* if the function returns a structure, then add an
implicit pointer parameter */
func_vt = sym->type;
@@ -470,6 +475,8 @@ void gfunc_prolog(CType *func_type)
/* generate function epilog */
void gfunc_epilog(void)
{
+ int v, saved_ind;
+
#ifdef CONFIG_TCC_BCHECK
if (do_bounds_check && func_bound_offset != lbounds_section->data_offset) {
int saved_ind;
@@ -480,7 +487,7 @@ void gfunc_epilog(void)
*bounds_ptr = 0;
/* generate bound local allocation */
saved_ind = ind;
- ind = func_sub_sp_offset + 4;
+ ind = func_sub_sp_offset;
sym_data = get_sym_ref(&char_pointer_type, lbounds_section,
func_bound_offset, lbounds_section->data_offset);
greloc(cur_text_section, sym_data,
@@ -512,7 +519,27 @@ void gfunc_epilog(void)
g(func_ret_sub >> 8);
}
/* align local size to word & save local variables */
- *(int *)(cur_text_section->data + func_sub_sp_offset) = (-loc + 3) & -4;
+
+ v = (-loc + 3) & -4;
+ saved_ind = ind;
+ ind = func_sub_sp_offset - FUNC_PROLOG_SIZE;
+#ifdef TCC_TARGET_PE
+ if (v >= 4096) {
+ Sym *sym = external_global_sym(TOK___chkstk, &func_old_type, 0);
+ oad(0xb8, v); /* mov stacksize, %eax */
+ oad(0xe8, -4); /* call __chkstk, (does the stackframe too) */
+ greloc(cur_text_section, sym, ind-4, R_386_PC32);
+ } else
+#endif
+ {
+ o(0xe58955); /* push %ebp, mov %esp, %ebp */
+ o(0xec81); /* sub esp, stacksize */
+ gen_le32(v);
+#if FUNC_PROLOG_SIZE == 10
+ o(0x90); /* adjust to FUNC_PROLOG_SIZE */
+#endif
+ }
+ ind = saved_ind;
}
/* generate a jump to a label */