diff options
| author | bellard <bellard> | 2002-01-03 22:43:10 +0000 |
|---|---|---|
| committer | bellard <bellard> | 2002-01-03 22:43:10 +0000 |
| commit | 14799da83834b7057a2c7d534eb27f06993b25b9 (patch) | |
| tree | 8777df5c50a7bbd17fb4da648057ec637eb7ec21 /i386-gen.c | |
| parent | 8b41bc57e1d19c15a688f5d5c20296c460ec8254 (diff) | |
| download | tinycc-14799da83834b7057a2c7d534eb27f06993b25b9.tar.gz tinycc-14799da83834b7057a2c7d534eb27f06993b25b9.tar.bz2 | |
suppressed some buffer overflows - moved function generation to cpu specific code (XXX: should have less cpu specific code for that)
Diffstat (limited to 'i386-gen.c')
| -rw-r--r-- | i386-gen.c | 44 |
1 files changed, 44 insertions, 0 deletions
@@ -72,6 +72,8 @@ typedef struct GFuncContext { /******************************************************/ +static int *func_sub_sp_ptr; + void g(int c) { *(char *)ind++ = c; @@ -355,6 +357,48 @@ void gfunc_call(GFuncContext *c) vtop--; } +/* generate function prolog of type 't' */ +void gfunc_prolog(int t) +{ + int addr, align, size, u; + Sym *sym; + + sym = sym_find((unsigned)t >> VT_STRUCT_SHIFT); + addr = 8; + /* if the function returns a structure, then add an + implicit pointer parameter */ + func_vt = sym->t; + if ((func_vt & VT_BTYPE) == VT_STRUCT) { + func_vc = addr; + addr += 4; + } + /* define parameters */ + while ((sym = sym->next) != NULL) { + u = sym->t; + sym_push(sym->v & ~SYM_FIELD, u, + VT_LOCAL | VT_LVAL, addr); + size = type_size(u, &align); + size = (size + 3) & ~3; +#ifdef FUNC_STRUCT_PARAM_AS_PTR + /* structs are passed as pointer */ + if ((u & VT_BTYPE) == VT_STRUCT) { + size = 4; + } +#endif + addr += size; + } + o(0xe58955); /* push %ebp, mov %esp, %ebp */ + func_sub_sp_ptr = (int *)oad(0xec81, 0); /* sub $xxx, %esp */ +} + +/* generate function epilog */ +void gfunc_epilog(void) +{ + o(0xc3c9); /* leave, ret */ + *func_sub_sp_ptr = (-loc + 3) & -4; /* align local size to word & + save local variables */ +} + int gjmp(int t) { return psym(0xe9, t); |
