From 2211493242c8435b84ea25318bfbb63f4072bef2 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 5 Aug 2006 12:57:59 +0000 Subject: [PATCH] avoid mis-aligned pointer (relevant for 3m) in ffi-set svn: r3973 --- src/foreign/foreign.c | 151 ++++++++++++++++++++-------------------- src/foreign/foreign.ssc | 35 +++++----- 2 files changed, 94 insertions(+), 92 deletions(-) diff --git a/src/foreign/foreign.c b/src/foreign/foreign.c index d54bf94aca..285d2722c0 100644 --- a/src/foreign/foreign.c +++ b/src/foreign/foreign.c @@ -1078,7 +1078,7 @@ END_XFORM_SKIP; #define C2SCHEME(typ,src,delta,argsloc) c_to_scheme(typ,src,delta) #define REF_CTYPE(ctype) (((ctype *)W_OFFSET(src,delta))[0]) #endif -#define W_OFFSET(src, delta) ((char *)(src)+(delta)) +#define W_OFFSET(src, delta) ((char *)(src) XFORM_OK_PLUS (delta)) static Scheme_Object *C2SCHEME(Scheme_Object *type, void *src, int delta, int args_loc) { @@ -1135,16 +1135,16 @@ static Scheme_Object *C2SCHEME(Scheme_Object *type, void *src, int delta, int ar * the function is different: in the relevant cases zero an int and offset the * ptr */ #ifdef SCHEME_BIG_ENDIAN -#define SCHEME2C(typ,dst,val,basep,retloc) scheme_to_c(typ,dst,val,basep,retloc) +#define SCHEME2C(typ,dst,delta,val,basep,retloc) scheme_to_c(typ,dst,delta,val,basep,retloc) #else -#define SCHEME2C(typ,dst,val,basep,retloc) scheme_to_c(typ,dst,val,basep) +#define SCHEME2C(typ,dst,delta,val,basep,retloc) scheme_to_c(typ,dst,delta,val,basep) #endif /* Usually writes the C object to dst and returns NULL. When basetype_p is not * NULL, then any pointer value (any pointer or a struct) is returned, and the * basetype_p is set to the corrsponding number tag. If basetype_p is NULL, * then a struct value will be *copied* into dst. */ -static void* SCHEME2C(Scheme_Object *type, void *dst, +static void* SCHEME2C(Scheme_Object *type, void *dst, long delta, Scheme_Object *val, long *basetype_p, int ret_loc) { @@ -1158,12 +1158,12 @@ static void* SCHEME2C(Scheme_Object *type, void *dst, if (CTYPE_PRIMLABEL(type) == FOREIGN_fpointer) { /* No need for the SET_CTYPE trick for pointers */ if (SCHEME_FFICALLBACKP(val)) - ((void**)dst)[0] = ((ffi_callback_struct*)val)->callback; + ((void**)W_OFFSET(dst,delta))[0] = ((ffi_callback_struct*)val)->callback; else if (SCHEME_CPTRP(val)) - ((void**)dst)[0] = SCHEME_CPTR_VAL(val); + ((void**)W_OFFSET(dst,delta))[0] = SCHEME_CPTR_VAL(val); else if (SCHEME_FFIOBJP(val)) - ((void**)dst)[0] = ((ffi_obj_struct*)val)->obj; - else /* ((void**)dst)[0] = val; */ + ((void**)W_OFFSET(dst,delta))[0] = ((ffi_obj_struct*)val)->obj; + else /* ((void**)W_OFFSET(dst,delta))[0] = val; */ scheme_wrong_type("Scheme->C", "cpointer", 0, 1, &val); } else switch (CTYPE_PRIMLABEL(type)) { case FOREIGN_void: @@ -1171,14 +1171,14 @@ static void* SCHEME2C(Scheme_Object *type, void *dst, case FOREIGN_int8: #ifdef SCHEME_BIG_ENDIAN if (sizeof(Tsint8)C","int8",0,1,&(val)); return NULL; /* shush the compiler */ @@ -1186,14 +1186,14 @@ static void* SCHEME2C(Scheme_Object *type, void *dst, case FOREIGN_uint8: #ifdef SCHEME_BIG_ENDIAN if (sizeof(Tuint8)C","uint8",0,1,&(val)); return NULL; /* shush the compiler */ @@ -1201,14 +1201,14 @@ static void* SCHEME2C(Scheme_Object *type, void *dst, case FOREIGN_int16: #ifdef SCHEME_BIG_ENDIAN if (sizeof(Tsint16)C","int16",0,1,&(val)); return NULL; /* shush the compiler */ @@ -1216,41 +1216,41 @@ static void* SCHEME2C(Scheme_Object *type, void *dst, case FOREIGN_uint16: #ifdef SCHEME_BIG_ENDIAN if (sizeof(Tuint16)C","uint16",0,1,&(val)); return NULL; /* shush the compiler */ } case FOREIGN_int32: - if (!(scheme_get_realint_val(val,&(((Tsint32*)dst)[0])))) scheme_wrong_type("Scheme->C","int32",0,1,&(val)); + if (!(scheme_get_realint_val(val,&(((Tsint32*)W_OFFSET(dst,delta))[0])))) scheme_wrong_type("Scheme->C","int32",0,1,&(val)); return NULL; case FOREIGN_uint32: - if (!(scheme_get_unsigned_realint_val(val,&(((Tuint32*)dst)[0])))) scheme_wrong_type("Scheme->C","uint32",0,1,&(val)); + if (!(scheme_get_unsigned_realint_val(val,&(((Tuint32*)W_OFFSET(dst,delta))[0])))) scheme_wrong_type("Scheme->C","uint32",0,1,&(val)); return NULL; case FOREIGN_int64: - if (!(scheme_get_long_long_val(val,&(((Tsint64*)dst)[0])))) scheme_wrong_type("Scheme->C","int64",0,1,&(val)); + if (!(scheme_get_long_long_val(val,&(((Tsint64*)W_OFFSET(dst,delta))[0])))) scheme_wrong_type("Scheme->C","int64",0,1,&(val)); return NULL; case FOREIGN_uint64: - if (!(scheme_get_unsigned_long_long_val(val,&(((Tuint64*)dst)[0])))) scheme_wrong_type("Scheme->C","uint64",0,1,&(val)); + if (!(scheme_get_unsigned_long_long_val(val,&(((Tuint64*)W_OFFSET(dst,delta))[0])))) scheme_wrong_type("Scheme->C","uint64",0,1,&(val)); return NULL; case FOREIGN_fixint: #ifdef SCHEME_BIG_ENDIAN if (sizeof(Tsint32)C","fixint",0,1,&(val)); return NULL; /* shush the compiler */ @@ -1258,14 +1258,14 @@ static void* SCHEME2C(Scheme_Object *type, void *dst, case FOREIGN_ufixint: #ifdef SCHEME_BIG_ENDIAN if (sizeof(Tuint32)C","ufixint",0,1,&(val)); return NULL; /* shush the compiler */ @@ -1273,14 +1273,14 @@ static void* SCHEME2C(Scheme_Object *type, void *dst, case FOREIGN_fixnum: #ifdef SCHEME_BIG_ENDIAN if (sizeof(long)C","fixnum",0,1,&(val)); return NULL; /* shush the compiler */ @@ -1288,14 +1288,14 @@ static void* SCHEME2C(Scheme_Object *type, void *dst, case FOREIGN_ufixnum: #ifdef SCHEME_BIG_ENDIAN if (sizeof(unsigned long)C","ufixnum",0,1,&(val)); return NULL; /* shush the compiler */ @@ -1303,14 +1303,14 @@ static void* SCHEME2C(Scheme_Object *type, void *dst, case FOREIGN_float: #ifdef SCHEME_BIG_ENDIAN if (sizeof(float)C","float",0,1,&(val)); return NULL; /* shush the compiler */ @@ -1318,14 +1318,14 @@ static void* SCHEME2C(Scheme_Object *type, void *dst, case FOREIGN_double: #ifdef SCHEME_BIG_ENDIAN if (sizeof(double)C","double",0,1,&(val)); return NULL; /* shush the compiler */ @@ -1333,14 +1333,14 @@ static void* SCHEME2C(Scheme_Object *type, void *dst, case FOREIGN_doubleS: #ifdef SCHEME_BIG_ENDIAN if (sizeof(double)C","double*",0,1,&(val)); return NULL; /* shush the compiler */ @@ -1348,14 +1348,14 @@ static void* SCHEME2C(Scheme_Object *type, void *dst, case FOREIGN_bool: #ifdef SCHEME_BIG_ENDIAN if (sizeof(int)C","bool",0,1,&(val)); return NULL; /* shush the compiler */ @@ -1363,15 +1363,15 @@ static void* SCHEME2C(Scheme_Object *type, void *dst, case FOREIGN_string_ucs_4: #ifdef SCHEME_BIG_ENDIAN if (sizeof(mzchar*)size); + memcpy(W_OFFSET(dst, delta), p, CTYPE_PRIMTYPE(type)->size); return NULL; } else { *basetype_p = FOREIGN_struct; @@ -1808,6 +1808,7 @@ static Scheme_Object *foreign_ptr_ref(int argc, Scheme_Object *argv[]) static Scheme_Object *foreign_ptr_set(int argc, Scheme_Object *argv[]) { int size=0; void *ptr; + long delta = 0; Scheme_Object *val = argv[argc-1], *base; if (!SCHEME_FFIANYPTRP(argv[0])) scheme_wrong_type(MYNAME, "cpointer", 0, argc, argv); @@ -1839,13 +1840,13 @@ static Scheme_Object *foreign_ptr_set(int argc, Scheme_Object *argv[]) scheme_wrong_type(MYNAME, "abs-flag", 2, argc, argv); if (!SCHEME_INTP(argv[3])) scheme_wrong_type(MYNAME, "integer", 3, argc, argv); - ptr = (char*)ptr XFORM_OK_PLUS SCHEME_INT_VAL(argv[3]); + delta = SCHEME_INT_VAL(argv[3]); } else if (argc > 3) { if (!SCHEME_INTP(argv[2])) scheme_wrong_type(MYNAME, "integer", 2, argc, argv); - ptr = (char*)ptr XFORM_OK_PLUS (size * SCHEME_INT_VAL(argv[2])); + delta = (size * SCHEME_INT_VAL(argv[2])); } - SCHEME2C(argv[1], ptr, val, NULL, 0); + SCHEME2C(argv[1], ptr, delta, val, NULL, 0); return scheme_void; } @@ -1981,7 +1982,7 @@ Scheme_Object *ffi_do_call(void *data, int argc, Scheme_Object *argv[]) /* iterate on input values and types */ for (i=0; iproc, argc, argv); - SCHEME2C(data->otype, resultp, p, NULL, 1); + SCHEME2C(data->otype, resultp, 0, p, NULL, 1); } /* see ffi-callback below */ diff --git a/src/foreign/foreign.ssc b/src/foreign/foreign.ssc index 81b881895f..3452088202 100755 --- a/src/foreign/foreign.ssc +++ b/src/foreign/foreign.ssc @@ -906,7 +906,7 @@ void free_libffi_type(void *ignored, void *p) #define C2SCHEME(typ,src,delta,argsloc) c_to_scheme(typ,src,delta) #define REF_CTYPE(ctype) (((ctype *)W_OFFSET(src,delta))[0]) #endif -#define W_OFFSET(src, delta) ((char *)(src)+(delta)) +#define W_OFFSET(src, delta) ((char *)(src) XFORM_OK_PLUS (delta)) static Scheme_Object *C2SCHEME(Scheme_Object *type, void *src, int delta, int args_loc) { @@ -944,16 +944,16 @@ static Scheme_Object *C2SCHEME(Scheme_Object *type, void *src, int delta, int ar * the function is different: in the relevant cases zero an int and offset the * ptr */ #ifdef SCHEME_BIG_ENDIAN -#define SCHEME2C(typ,dst,val,basep,retloc) scheme_to_c(typ,dst,val,basep,retloc) +#define SCHEME2C(typ,dst,delta,val,basep,retloc) scheme_to_c(typ,dst,delta,val,basep,retloc) #else -#define SCHEME2C(typ,dst,val,basep,retloc) scheme_to_c(typ,dst,val,basep) +#define SCHEME2C(typ,dst,delta,val,basep,retloc) scheme_to_c(typ,dst,delta,val,basep) #endif /* Usually writes the C object to dst and returns NULL. When basetype_p is not * NULL, then any pointer value (any pointer or a struct) is returned, and the * basetype_p is set to the corrsponding number tag. If basetype_p is NULL, * then a struct value will be *copied* into dst. */ -static void* SCHEME2C(Scheme_Object *type, void *dst, +static void* SCHEME2C(Scheme_Object *type, void *dst, long delta, Scheme_Object *val, long *basetype_p, int ret_loc) { @@ -967,12 +967,12 @@ static void* SCHEME2C(Scheme_Object *type, void *dst, if (CTYPE_PRIMLABEL(type) == FOREIGN_fpointer) { /* No need for the SET_CTYPE trick for pointers */ if (SCHEME_FFICALLBACKP(val)) - ((void**)dst)[0] = ((ffi_callback_struct*)val)->callback; + ((void**)W_OFFSET(dst,delta))[0] = ((ffi_callback_struct*)val)->callback; else if (SCHEME_CPTRP(val)) - ((void**)dst)[0] = SCHEME_CPTR_VAL(val); + ((void**)W_OFFSET(dst,delta))[0] = SCHEME_CPTR_VAL(val); else if (SCHEME_FFIOBJP(val)) - ((void**)dst)[0] = ((ffi_obj_struct*)val)->obj; - else /* ((void**)dst)[0] = val; */ + ((void**)W_OFFSET(dst,delta))[0] = ((ffi_obj_struct*)val)->obj; + else /* ((void**)W_OFFSET(dst,delta))[0] = val; */ scheme_wrong_type("Scheme->C", "cpointer", 0, 1, &val); } else switch (CTYPE_PRIMLABEL(type)) { {:(for-each-type @@ -980,15 +980,15 @@ static void* SCHEME2C(Scheme_Object *type, void *dst, (list "scheme_wrong_type(\"Scheme->C\",\""type"\",0,1,&("obj"));")) (~ "case FOREIGN_"cname":") (if ctype - (let* ([x (list "((("ctype"*)dst)[0])")] + (let* ([x (list "((("ctype"*)W_OFFSET(dst,delta))[0])")] [f (lambda (p) (if (procedure? p) (p "val" x) (list p"(val)")))]) (if s->c (begin (display "#ifdef SCHEME_BIG_ENDIAN\n") (~ " if (sizeof("ctype")size); + memcpy(W_OFFSET(dst, delta), p, CTYPE_PRIMTYPE(type)->size); return NULL; } else { *basetype_p = FOREIGN_struct; @@ -1302,6 +1302,7 @@ static void* SCHEME2C(Scheme_Object *type, void *dst, {:(cdefine ptr-set! 3 5):} { int size=0; void *ptr; + long delta = 0; Scheme_Object *val = argv[argc-1], *base; if (!SCHEME_FFIANYPTRP(argv[0])) scheme_wrong_type(MYNAME, "cpointer", 0, argc, argv); @@ -1333,13 +1334,13 @@ static void* SCHEME2C(Scheme_Object *type, void *dst, scheme_wrong_type(MYNAME, "abs-flag", 2, argc, argv); if (!SCHEME_INTP(argv[3])) scheme_wrong_type(MYNAME, "integer", 3, argc, argv); - ptr = (char*)ptr XFORM_OK_PLUS SCHEME_INT_VAL(argv[3]); + delta = SCHEME_INT_VAL(argv[3]); } else if (argc > 3) { if (!SCHEME_INTP(argv[2])) scheme_wrong_type(MYNAME, "integer", 2, argc, argv); - ptr = (char*)ptr XFORM_OK_PLUS (size * SCHEME_INT_VAL(argv[2])); + delta = (size * SCHEME_INT_VAL(argv[2])); } - SCHEME2C(argv[1], ptr, val, NULL, 0); + SCHEME2C(argv[1], ptr, delta, val, NULL, 0); return scheme_void; } @@ -1473,7 +1474,7 @@ Scheme_Object *ffi_do_call(void *data, int argc, Scheme_Object *argv[]) /* iterate on input values and types */ for (i=0; iproc, argc, argv); - SCHEME2C(data->otype, resultp, p, NULL, 1); + SCHEME2C(data->otype, resultp, 0, p, NULL, 1); } /* see ffi-callback below */