From 9825011cedeb3fdcfb54e312ab27d92a2a8488b0 Mon Sep 17 00:00:00 2001 From: bellard Date: Sun, 10 Apr 2005 22:15:08 +0000 Subject: [PATCH] __chkstk support --- i386-gen.c | 37 ++++++++++++++++++++++++++++++++----- tcctok.h | 1 + 2 files changed, 33 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 */ diff --git a/tcctok.h b/tcctok.h index 0414541..9d29379 100644 --- a/tcctok.h +++ b/tcctok.h @@ -155,6 +155,7 @@ DEF(TOK___fixunssfdi, "__fixunssfdi") DEF(TOK___fixunsdfdi, "__fixunsdfdi") DEF(TOK___fixunsxfdi, "__fixunsxfdi") + DEF(TOK___chkstk, "__chkstk") /* bound checking symbols */ #ifdef CONFIG_TCC_BCHECK