Răsfoiți Sursa

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

Nicolas Cannasse 5 ani în urmă
părinte
comite
f8cd20f52f
4 a modificat fișierele cu 23 adăugiri și 18 ștergeri
  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_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_sys_init(void **args, int nargs, void *hlfile);
 HL_API void hl_setup_callbacks(void *sc, void *gw);
 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 );
 HL_API void hl_setup_reload_check( void *freload, void *param );
 
 
 #include <setjmp.h>
 #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_c2hl = NULL;
 static void *call_jit_hl2c = 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
 		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.
 		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 HUI16:
 	case HI32:
 	case HI32:
 	case HBOOL:
 	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;
 		return &ret->v.i;
 	case HF32:
 	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;
 		return &ret->v.f;
 	case HF64:
 	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;
 		return &ret->v.d;
 	default:
 	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 ) {
 	if( !call_jit_c2hl ) {
 		call_jit_c2hl = code + ctx->c2hl;
 		call_jit_c2hl = code + ctx->c2hl;
 		call_jit_hl2c = code + ctx->hl2c;
 		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
 #		ifdef JIT_CUSTOM_LONGJUMP
 		hl_setup_longjump(code + ctx->longjump);
 		hl_setup_longjump(code + ctx->longjump);
 #		endif
 #		endif

+ 5 - 5
src/main.c

@@ -44,7 +44,6 @@ typedef struct {
 	hl_code *code;
 	hl_code *code;
 	hl_module *m;
 	hl_module *m;
 	vdynamic *ret;
 	vdynamic *ret;
-	vclosure c;
 	pchar *file;
 	pchar *file;
 	int file_time;
 	int file_time;
 } main_context;
 } main_context;
@@ -139,6 +138,7 @@ int wmain(int argc, pchar *argv[]) {
 #else
 #else
 int main(int argc, pchar *argv[]) {
 int main(int argc, pchar *argv[]) {
 #endif
 #endif
+	static vclosure cl;
 	pchar *file = NULL;
 	pchar *file = NULL;
 	char *error_msg = NULL;
 	char *error_msg = NULL;
 	int debug_port = -1;
 	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);
 		fprintf(stderr,"Could not start debugger on port %d",debug_port);
 		return 4;
 		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();
 	setup_handler();
 	hl_profile_setup(profile_count);
 	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();
 	hl_profile_end();
 	if( isExc ) {
 	if( isExc ) {
 		varray *a = hl_exception_stack();
 		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;
 	c->hasValue = 1;
 #	ifdef HL_64
 #	ifdef HL_64
 	int stack = 0;
 	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;
 	c->stackCount = stack;
 #	endif
 #	endif
 	c->value = v;
 	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_static_call hlc_static_call = NULL;
 static fptr_get_wrapper hlc_get_wrapper = 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_static_call = (fptr_static_call)c;
 	hlc_get_wrapper = (fptr_get_wrapper)w;
 	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
 #define HL_MAX_ARGS 9
 
 
 HL_PRIM vdynamic* hl_call_method( vdynamic *c, varray *args ) {
 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;
 		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;
 	tret = cl->t->fun->ret;
 	if( !hl_is_ptr(tret) ) {
 	if( !hl_is_ptr(tret) ) {
 		vdynamic *r;
 		vdynamic *r;
@@ -290,7 +294,7 @@ HL_PRIM void *hl_wrapper_call( void *_c, void **args, vdynamic *ret ) {
 			vargs[p++] = v;
 			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;
 	aret = hl_is_ptr(w->t->fun->ret) ? &pret : pret;
 	if( aret == NULL ) aret = &pret;
 	if( aret == NULL ) aret = &pret;
 	switch( tfun->ret->kind ) {
 	switch( tfun->ret->kind ) {