aboutsummaryrefslogtreecommitdiff
path: root/i386-gen.c
diff options
context:
space:
mode:
authorbellard <bellard>2002-01-03 22:43:10 +0000
committerbellard <bellard>2002-01-03 22:43:10 +0000
commit14799da83834b7057a2c7d534eb27f06993b25b9 (patch)
tree8777df5c50a7bbd17fb4da648057ec637eb7ec21 /i386-gen.c
parent8b41bc57e1d19c15a688f5d5c20296c460ec8254 (diff)
downloadtinycc-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.c44
1 files changed, 44 insertions, 0 deletions
diff --git a/i386-gen.c b/i386-gen.c
index 7741bcc..dd9d4c4 100644
--- a/i386-gen.c
+++ b/i386-gen.c
@@ -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);