changeset 351:e2578fa968b7

[project @ 2005-04-10 22:15:08 by bellard] __chkstk support
author bellard
date Sun, 10 Apr 2005 22:15:08 +0000
parents 4ebba89e2599
children 364ab2ace9b3
files i386-gen.c tcctok.h
diffstat 2 files changed, 33 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/i386-gen.c	Sun Apr 10 21:46:58 2005 +0000
+++ b/i386-gen.c	Sun Apr 10 22:15:08 2005 +0000
@@ -398,6 +398,12 @@
     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 @@
     }
     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 @@
 /* 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 @@
         *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 @@
         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 */
--- a/tcctok.h	Sun Apr 10 21:46:58 2005 +0000
+++ b/tcctok.h	Sun Apr 10 22:15:08 2005 +0000
@@ -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