diff --git a/ext/dl/dl.c b/ext/dl/dl.c index 0eda4926d7..cb370ae252 100644 --- a/ext/dl/dl.c +++ b/ext/dl/dl.c @@ -635,6 +635,7 @@ Init_dl() rb_define_const(rb_mDL, "MAX_ARG", INT2NUM(MAX_ARG)); rb_define_const(rb_mDL, "MAX_CBARG", INT2NUM(MAX_CBARG)); rb_define_const(rb_mDL, "MAX_CBENT", INT2NUM(MAX_CBENT)); + rb_define_const(rb_mDL, "DLSTACK", rb_tainted_str_new2(DLSTACK_METHOD)); rb_define_module_function(rb_mDL, "dlopen", rb_dl_dlopen, -1); rb_define_module_function(rb_mDL, "set_callback", rb_dl_set_callback, -1); diff --git a/ext/dl/dl.h b/ext/dl/dl.h index 5068fc6bbc..bfe83087cd 100644 --- a/ext/dl/dl.h +++ b/ext/dl/dl.h @@ -8,9 +8,9 @@ #include #include -#define DL_VERSION "1.1.0" +#define DL_VERSION "1.2.0" #define DL_MAJOR_VERSION 1 -#define DL_MINOR_VERSION 1 +#define DL_MINOR_VERSION 2 #define DL_PATCH_VERSION 0 #if defined(HAVE_DLFCN_H) @@ -142,32 +142,48 @@ #if defined(USE_INLINE_ASM) # if defined(__i386__) && defined(__GNUC__) -# define ASM_START(sym) -# define ASM_END(sym) -# define ASM_PUSH_C(x) asm volatile ("pushl %0" :: "g" (x)); -# define ASM_PUSH_H(x) asm volatile ("pushl %0" :: "g" (x)); -# define ASM_PUSH_I(x) asm volatile ("pushl %0" :: "g" (x)); -# define ASM_PUSH_L(x) asm volatile ("pushl %0" :: "g" (x)); -# define ASM_PUSH_P(x) asm volatile ("pushl %0" :: "g" (x)); -# define ASM_PUSH_F(x) asm volatile ("flds %0"::"g"(x));\ - asm volatile ("subl $4,%esp");\ - asm volatile ("fstps (%esp)"); -# define ASM_PUSH_D(x) asm volatile ("fldl %0"::"g"(x));\ - asm volatile ("subl $8,%esp");\ - asm volatile ("fstpl (%esp)") +# define DLSTACK +# define DLSTACK_METHOD "asm" +# define DLSTACK_REVERSE +# define DLSTACK_PROTO +# define DLSTACK_ARGS +# define DLSTACK_START(sym) +# define DLSTACK_END(sym) +# define DLSTACK_PUSH_C(x) asm volatile ("pushl %0" :: "g" (x)); +# define DLSTACK_PUSH_H(x) asm volatile ("pushl %0" :: "g" (x)); +# define DLSTACK_PUSH_I(x) asm volatile ("pushl %0" :: "g" (x)); +# define DLSTACK_PUSH_L(x) asm volatile ("pushl %0" :: "g" (x)); +# define DLSTACK_PUSH_P(x) asm volatile ("pushl %0" :: "g" (x)); +# define DLSTACK_PUSH_F(x) asm volatile ("flds %0"::"g"(x));\ + asm volatile ("subl $4,%esp");\ + asm volatile ("fstps (%esp)"); +# define DLSTACK_PUSH_D(x) asm volatile ("fldl %0"::"g"(x));\ + asm volatile ("subl $8,%esp");\ + asm volatile ("fstpl (%esp)") # else # error --with-asm is not supported on this machine # endif #elif defined(USE_DLSTACK) -# define ASM_START(sym) -# define ASM_END(sym) -# define ASM_PUSH_C(x) {long v=(long)x; memcpy(sp,&v,sizeof(long)); sp++;} -# define ASM_PUSH_H(x) {long v=(long)x; memcpy(sp,&v,sizeof(long)); sp++;} -# define ASM_PUSH_I(x) {long v=(long)x; memcpy(sp,&v,sizeof(long)); sp++;} -# define ASM_PUSH_L(x) memcpy(sp,&x,sizeof(long)); sp++; -# define ASM_PUSH_P(x) memcpy(sp,&x,sizeof(void*)); sp++; -# define ASM_PUSH_F(x) memcpy(sp,&x,sizeof(float)); sp+=sizeof(float)/sizeof(long); -# define ASM_PUSH_D(x) memcpy(sp,&x,sizeof(double)); sp+=sizeof(double)/sizeof(long); +# define DLSTACK +# define DLSTACK_METHOD "dl" +# define DLSTACK_PROTO long,long,long,long,long,\ + long,long,long,long,long,\ + long,long,long,long,long +# define DLSTACK_ARGS stack[0],stack[1],stack[2],stack[3],stack[4],\ + stack[5],stack[6],stack[7],stack[8],stack[9],\ + stack[10],stack[11],stack[12],stack[13],stack[14] +# define DLSTACK_SIZE (sizeof(long)*15) +# define DLSTACK_START(sym) +# define DLSTACK_END(sym) +# define DLSTACK_PUSH_C(x) {long v=(long)x; memcpy(sp,&v,sizeof(long)); sp++;} +# define DLSTACK_PUSH_H(x) {long v=(long)x; memcpy(sp,&v,sizeof(long)); sp++;} +# define DLSTACK_PUSH_I(x) {long v=(long)x; memcpy(sp,&v,sizeof(long)); sp++;} +# define DLSTACK_PUSH_L(x) memcpy(sp,&x,sizeof(long)); sp++; +# define DLSTACK_PUSH_P(x) memcpy(sp,&x,sizeof(void*)); sp++; +# define DLSTACK_PUSH_F(x) memcpy(sp,&x,sizeof(float)); sp+=sizeof(float)/sizeof(long); +# define DLSTACK_PUSH_D(x) memcpy(sp,&x,sizeof(double)); sp+=sizeof(double)/sizeof(long); +#else +# define DLSTACK_METHOD "none" #endif extern VALUE rb_mDL; diff --git a/ext/dl/sym.c b/ext/dl/sym.c index 5340dcb489..502e0f4bf4 100644 --- a/ext/dl/sym.c +++ b/ext/dl/sym.c @@ -101,7 +101,7 @@ rb_dlsym_new(void (*func)(), const char *name, const char *type) data->name = name ? strdup(name) : NULL; data->type = type ? strdup(type) : NULL; data->len = type ? strlen(type) : 0; -#if !(defined(USE_INLINE_ASM) || defined(USE_DLSTACK)) +#if !(defined(DLSTACK)) if( data->len - 1 > MAX_ARG ){ rb_raise(rb_eDLError, "maximum number of arguments is %d.", MAX_ARG); }; @@ -519,17 +519,11 @@ rb_dlsym_call(int argc, VALUE argv[], VALUE self) func = sym->func; -#if defined(USE_INLINE_ASM) || defined(USE_DLSTACK) +#if defined(DLSTACK) { -#if defined(USE_DLSTACK) -#define DLSTACK_PROTO long,long,long,long,long,\ - long,long,long,long,long,\ - long,long,long,long,long -#define DLSTACK_ARGS stack[0],stack[1],stack[2],stack[3],stack[4],\ - stack[5],stack[6],stack[7],stack[8],stack[9],\ - stack[10],stack[11],stack[12],stack[13],stack[14] +#if defined(DLSTACK_SIZE) int stk_size; - long stack[15]; + long stack[DLSTACK_SIZE]; long *sp; sp = stack; @@ -538,75 +532,72 @@ rb_dlsym_call(int argc, VALUE argv[], VALUE self) FREE_ARGS; rb_raise(rb_eDLTypeError, "unknown type '%c'.", -stk_size); } - else if( stk_size > (int)(sizeof(long) * 15) ){ + else if( stk_size > (int)(DLSTACK_SIZE) ){ FREE_ARGS; rb_raise(rb_eArgError, "too many arguments."); } -#elif defined(USE_INLINE_ASM) -#define DLSTACK_PROTO -#define DLSTACK_ARGS #endif - ASM_START(sym); + DLSTACK_START(sym); -#if defined(USE_DLSTACK) - for( i = 0; i <= sym->len -2; i++ ) -#else +#if defined(DLSTACK_REVERSE) for( i = sym->len - 2; i >= 0; i-- ) +#else + for( i = 0; i <= sym->len -2; i++ ) #endif { switch( sym->type[i+1] ){ case 'p': case 'P': - ASM_PUSH_P(ANY2P(args[i])); + DLSTACK_PUSH_P(ANY2P(args[i])); break; case 'a': case 'A': - ASM_PUSH_P(ANY2P(args[i])); + DLSTACK_PUSH_P(ANY2P(args[i])); break; case 'C': - ASM_PUSH_C(ANY2C(args[i])); + DLSTACK_PUSH_C(ANY2C(args[i])); break; case 'c': - ASM_PUSH_P(ANY2P(args[i])); + DLSTACK_PUSH_P(ANY2P(args[i])); break; case 'H': - ASM_PUSH_H(ANY2H(args[i])); + DLSTACK_PUSH_H(ANY2H(args[i])); break; case 'h': - ASM_PUSH_P(ANY2P(args[i])); + DLSTACK_PUSH_P(ANY2P(args[i])); break; case 'I': - ASM_PUSH_I(ANY2I(args[i])); + DLSTACK_PUSH_I(ANY2I(args[i])); break; case 'i': - ASM_PUSH_P(ANY2P(args[i])); + DLSTACK_PUSH_P(ANY2P(args[i])); break; case 'L': - ASM_PUSH_L(ANY2L(args[i])); + DLSTACK_PUSH_L(ANY2L(args[i])); break; case 'l': - ASM_PUSH_P(ANY2P(args[i])); + DLSTACK_PUSH_P(ANY2P(args[i])); break; case 'F': - ASM_PUSH_F(ANY2F(args[i])); + DLSTACK_PUSH_F(ANY2F(args[i])); break; case 'f': - ASM_PUSH_P(ANY2P(args[i])); + DLSTACK_PUSH_P(ANY2P(args[i])); break; case 'D': - ASM_PUSH_D(ANY2D(args[i])); + DLSTACK_PUSH_D(ANY2D(args[i])); break; case 'd': - ASM_PUSH_P(ANY2P(args[i])); + DLSTACK_PUSH_P(ANY2P(args[i])); break; case 'S': case 's': - ASM_PUSH_P(ANY2S(args[i])); + DLSTACK_PUSH_P(ANY2S(args[i])); break; }; } - ASM_END(sym->type); + DLSTACK_END(sym->type); { switch( sym->type[0] ){ @@ -678,14 +669,14 @@ rb_dlsym_call(int argc, VALUE argv[], VALUE self) } } } -#else +#else /* defined(DLSTACK) */ switch(ftype){ #include "call.func" default: FREE_ARGS; rb_raise(rb_eDLTypeError, "unsupported function type `%s'", sym->type); }; -#endif +#endif /* defined(DLSTACK) */ switch( sym->type[0] ){ case '0': diff --git a/ext/dl/test/test.rb b/ext/dl/test/test.rb index e6a7f33623..c4f1915387 100644 --- a/ext/dl/test/test.rb +++ b/ext/dl/test/test.rb @@ -31,6 +31,7 @@ print("VERSION = #{DL::VERSION}\n") print("MAJOR_VERSION = #{DL::MAJOR_VERSION}\n") print("MINOR_VERSION = #{DL::MINOR_VERSION}\n") print("\n") +print("DLSTACK = #{DL::DLSTACK}\n") print("MAX_ARG = #{DL::MAX_ARG}\n") print("MAX_CBARG = #{DL::MAX_CBARG}\n") print("MAX_CBENT = #{DL::MAX_CBENT}\n")