changeset 198:706fb60a1760

- safety fix for sparc32, protecting from callback handler problems when handler itself needs to spill
author Tassilo Philipp
date Sun, 19 Mar 2017 18:44:47 +0100
parents 53c42b1d9f8b
children e2233f6d887f
files dyncallback/dyncall_callback_sparc32.s
diffstat 1 files changed, 23 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/dyncallback/dyncall_callback_sparc32.s	Sun Mar 19 18:43:39 2017 +0100
+++ b/dyncallback/dyncall_callback_sparc32.s	Sun Mar 19 18:44:47 2017 +0100
@@ -6,7 +6,7 @@
  Description: Callback - Implementation for Sparc 32-bit
  License:
 
-   Copyright (c) 2007-2016 Daniel Adler <dadler@uni-goettingen.de>,
+   Copyright (c) 2007-2017 Daniel Adler <dadler@uni-goettingen.de>,
                            Tassilo Philipp <tphilipp@potion-studios.com>
 
    Permission to use, copy, modify, and distribute this software for any
@@ -37,28 +37,31 @@
 dcCallbackThunkEntry:
 
 	/* Prolog. */
-	/* Frame size of 80b comes from needing storage space for the following: */
-	/*   DCargs(sparc_req_reg_save_area:64 + argptr:4) + pad:4 + retval:8 */
-	save %sp, -80, %sp
+	/* Frame size of 104b comes from needing storage space for the following: */
+	/*   req_reg_save_area:64 + spill:24 + dcargs:4 + retval:8 + pad:4 */
+	/* Spill area could theoretically be only 16b, b/c cbHandler function has */
+ 	/* 4 arguments, but let's be conservative. */ /* cbHandler function might decide to spill (6x4b) @@@ testcode, or rely on 8byte return space in parent stack */
+	save %sp, -104, %sp 
 
-	/* Spill register args. */
-	st   %i0, [ %fp + 68 ]  /* reg arg 0 */
-	st   %i1, [ %fp + 72 ]  /* reg arg 1 */
-	st   %i2, [ %fp + 76 ]  /* reg arg 2 */
-	st   %i3, [ %fp + 80 ]  /* reg arg 3 */
-	st   %i4, [ %fp + 84 ]  /* reg arg 4 */
-	st   %i5, [ %fp + 88 ]  /* reg arg 5 */
+	/* Spill register args as dcargs is based on that (in prev frame, after */
+	/* req_reg_save_area and struct_ret_ptr). */
 	add  %fp, 68, %l0
-	st   %l0, [ %sp + 64 ]  /* init arg_ptr */
+	st   %i0, [ %l0 +  0 ]  /* reg arg 0 */
+	st   %i1, [ %l0 +  4 ]  /* reg arg 1 */
+	st   %i2, [ %l0 +  8 ]  /* reg arg 2 */
+	st   %i3, [ %l0 + 12 ]  /* reg arg 3 */
+	st   %i4, [ %l0 + 16 ]  /* reg arg 4 */
+	st   %i5, [ %l0 + 20 ]  /* reg arg 5 */
+	st   %l0, [ %sp + 88 ]  /* init arg_ptr */
 
 	/* Zero retval store. */
-	st   %g0, [ %sp + 72 ]
-	st   %g0, [ %sp + 76 ]
+	st   %g0, [ %sp +  96 ]
+	st   %g0, [ %sp + 100 ]
 
 	/* Prepare callback handler call. */
 	mov  %g1, %o0           /* Param 0 = DCCallback*, %g1 holds ptr to thunk */
-	add  %sp, 64, %o1       /* Param 1 = DCArgs* (ptr to struct with args ptr) */
-	add  %sp, 72, %o2       /* Param 2 = results ptr to 8b of local stack data */
+	add  %sp, 88, %o1       /* Param 1 = DCArgs* (ptr to struct with args ptr) */
+	add  %sp, 96, %o2       /* Param 2 = results ptr to 8b of local stack data */
 	ld   [ %g1 + 28 ], %o3  /* Param 3 = userdata ptr */
 
 	ld   [ %g1 + 24 ], %l0
@@ -66,10 +69,10 @@
 	nop
 
 	/* Put retval in %i0/%i1 (to be in caller's %o0/%o1), and %f0/%f1. */
-	ld   [ %sp + 72 ], %i0
-	ld   [ %sp + 76 ], %i1
-	ld   [ %sp + 72 ], %f0
-	ld   [ %sp + 76 ], %f1
+	ld   [ %sp +  96 ], %i0
+	ld   [ %sp + 100 ], %i1
+	ld   [ %sp +  96 ], %f0
+	ld   [ %sp + 100 ], %f1
 
 	/* Epilog. */
 	restore                 /* unshift reg window */