Selaa lähdekoodia

fix for windows jit: prevent not-scratch regs to keep function address in callback (false positive in call stacks)

Nicolas Cannasse 5 vuotta sitten
vanhempi
commit
f8cd20f52f
4 muutettua tiedostoa jossa 23 lisäystä ja 18 poistoa
  1. 1 0
      src/hl.h
  2. 6 6
      src/jit.c
  3. 5 5
      src/main.c
  4. 11 7
      src/std/fun.c

+ 1 - 0
src/hl.h

@@ -831,6 +831,7 @@ HL_API void *hl_fatal_error( const char *msg, const char *file, int line );
 HL_API void hl_fatal_fmt( const char *file, int line, const char *fmt, ...);
 HL_API void hl_sys_init(void **args, int nargs, void *hlfile);
 HL_API void hl_setup_callbacks(void *sc, void *gw);
+HL_API void hl_setup_callbacks2(void *sc, void *gw, int flags);
 HL_API void hl_setup_reload_check( void *freload, void *param );
 
 #include <setjmp.h>

+ 6 - 6
src/jit.c

@@ -2239,7 +2239,7 @@ static void jit_nops( jit_ctx *ctx ) {
 static void *call_jit_c2hl = NULL;
 static void *call_jit_hl2c = NULL;
 
-static void *callback_c2hl( void *f, hl_type *t, void **args, vdynamic *ret ) {
+static void *callback_c2hl( void **f, hl_type *t, void **args, vdynamic *ret ) {
 	/*
 		prepare stack and regs according to prepare_call_args, but by reading runtime type information
 		from the function type. The stack and regs will be setup by the trampoline function.
@@ -2333,16 +2333,16 @@ static void *callback_c2hl( void *f, hl_type *t, void **args, vdynamic *ret ) {
 	case HUI16:
 	case HI32:
 	case HBOOL:
-		ret->v.i = ((int (*)(void *, void *, void *))call_jit_c2hl)(f, (void**)&stack + pos, &stack);
+		ret->v.i = ((int (*)(void *, void *, void *))call_jit_c2hl)(*f, (void**)&stack + pos, &stack);
 		return &ret->v.i;
 	case HF32:
-		ret->v.f = ((float (*)(void *, void *, void *))call_jit_c2hl)(f, (void**)&stack + pos, &stack);
+		ret->v.f = ((float (*)(void *, void *, void *))call_jit_c2hl)(*f, (void**)&stack + pos, &stack);
 		return &ret->v.f;
 	case HF64:
-		ret->v.d = ((double (*)(void *, void *, void *))call_jit_c2hl)(f, (void**)&stack + pos, &stack);
+		ret->v.d = ((double (*)(void *, void *, void *))call_jit_c2hl)(*f, (void**)&stack + pos, &stack);
 		return &ret->v.d;
 	default:
-		return ((void *(*)(void *, void *, void *))call_jit_c2hl)(f, (void**)&stack + pos, &stack);
+		return ((void *(*)(void *, void *, void *))call_jit_c2hl)(*f, (void**)&stack + pos, &stack);
 	}
 }
 
@@ -4144,7 +4144,7 @@ void *hl_jit_code( jit_ctx *ctx, hl_module *m, int *codesize, hl_debug_infos **d
 	if( !call_jit_c2hl ) {
 		call_jit_c2hl = code + ctx->c2hl;
 		call_jit_hl2c = code + ctx->hl2c;
-		hl_setup_callbacks(callback_c2hl, get_wrapper);
+		hl_setup_callbacks2(callback_c2hl, get_wrapper, 1);
 #		ifdef JIT_CUSTOM_LONGJUMP
 		hl_setup_longjump(code + ctx->longjump);
 #		endif

+ 5 - 5
src/main.c

@@ -44,7 +44,6 @@ typedef struct {
 	hl_code *code;
 	hl_module *m;
 	vdynamic *ret;
-	vclosure c;
 	pchar *file;
 	int file_time;
 } main_context;
@@ -139,6 +138,7 @@ int wmain(int argc, pchar *argv[]) {
 #else
 int main(int argc, pchar *argv[]) {
 #endif
+	static vclosure cl;
 	pchar *file = NULL;
 	char *error_msg = NULL;
 	int debug_port = -1;
@@ -225,12 +225,12 @@ int main(int argc, pchar *argv[]) {
 		fprintf(stderr,"Could not start debugger on port %d",debug_port);
 		return 4;
 	}
-	ctx.c.t = ctx.code->functions[ctx.m->functions_indexes[ctx.m->code->entrypoint]].type;
-	ctx.c.fun = ctx.m->functions_ptrs[ctx.m->code->entrypoint];
-	ctx.c.hasValue = 0;
+	cl.t = ctx.code->functions[ctx.m->functions_indexes[ctx.m->code->entrypoint]].type;
+	cl.fun = ctx.m->functions_ptrs[ctx.m->code->entrypoint];
+	cl.hasValue = 0;
 	setup_handler();
 	hl_profile_setup(profile_count);
-	ctx.ret = hl_dyn_call_safe(&ctx.c,NULL,0,&isExc);
+	ctx.ret = hl_dyn_call_safe(&cl,NULL,0,&isExc);
 	hl_profile_end();
 	if( isExc ) {
 		varray *a = hl_exception_stack();

+ 11 - 7
src/std/fun.c

@@ -60,10 +60,7 @@ HL_PRIM vclosure *hl_alloc_closure_ptr( hl_type *fullt, void *fvalue, void *v )
 	c->hasValue = 1;
 #	ifdef HL_64
 	int stack = 0;
-	if( hl_closure_stack_capture ) {
-		stack = hl_internal_capture_stack((void**)(c + 1), hl_closure_stack_capture);
-		memset((void**)(c + 1)+stack,0,sizeof(void*)*(hl_closure_stack_capture - stack));
-	}
+	if( hl_closure_stack_capture ) stack = hl_internal_capture_stack((void**)(c + 1), hl_closure_stack_capture);
 	c->stackCount = stack;
 #	endif
 	c->value = v;
@@ -124,12 +121,19 @@ typedef void *(*fptr_get_wrapper)(hl_type *t);
 
 static fptr_static_call hlc_static_call = NULL;
 static fptr_get_wrapper hlc_get_wrapper = NULL;
+static int hlc_call_flags = 0;
 
-HL_PRIM void hl_setup_callbacks( void *c, void *w ) {
+HL_PRIM void hl_setup_callbacks2( void *c, void *w, int flags ) {
 	hlc_static_call = (fptr_static_call)c;
 	hlc_get_wrapper = (fptr_get_wrapper)w;
+	hlc_call_flags = flags;
+}
+
+HL_PRIM void hl_setup_callbacks( void *c, void *w ) {
+	hl_setup_callbacks2(c,w,0);
 }
 
+
 #define HL_MAX_ARGS 9
 
 HL_PRIM vdynamic* hl_call_method( vdynamic *c, varray *args ) {
@@ -186,7 +190,7 @@ HL_PRIM vdynamic* hl_call_method( vdynamic *c, varray *args ) {
 		}
 		pargs[i] = p;
 	}
-	ret = hlc_static_call(cl->fun,cl->t,pargs,&out);
+	ret = hlc_static_call(hlc_call_flags & 1 ? &cl->fun : cl->fun,cl->t,pargs,&out);
 	tret = cl->t->fun->ret;
 	if( !hl_is_ptr(tret) ) {
 		vdynamic *r;
@@ -290,7 +294,7 @@ HL_PRIM void *hl_wrapper_call( void *_c, void **args, vdynamic *ret ) {
 			vargs[p++] = v;
 		}
 	}
-	pret = hlc_static_call(w->fun,w->hasValue ? w->t->fun->parent : w->t,vargs,ret);
+	pret = hlc_static_call(hlc_call_flags & 1 ? &w->fun : w->fun,w->hasValue ? w->t->fun->parent : w->t,vargs,ret);
 	aret = hl_is_ptr(w->t->fun->ret) ? &pret : pret;
 	if( aret == NULL ) aret = &pret;
 	switch( tfun->ret->kind ) {