$OpenBSD: patch-ext_dl_sym_c,v 1.1 2010/05/03 17:01:33 jcs Exp $ fix loading of compiled modules on amd64. http://rubyforge.org/tracker/index.php?func=detail&aid=5944&group_id=1103&atid=4331 http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/227097 --- ext/dl/sym.c.orig Sun Aug 10 17:36:08 2008 +++ ext/dl/sym.c Thu Feb 25 19:23:05 2010 @@ -361,9 +361,22 @@ rb_dl_win32_set_last_error(VALUE self, VALUE val) __declspec(noinline) # endif static int -rb_dlsym_guardcall(char type, ANY_TYPE *ret, long *stack, void *func) +rb_dlsym_guardcall(char type, ANY_TYPE *ret, long *stack, double *sse, + void *func) { char *volatile guard = ALLOCA_N(char, 1); /* guard stack pointer */ +#undef DLSTACK_PROTO +#define DLSTACK_PROTO long, long, long, long, long, \ + long, long, long, long, long, \ + long, long, long, long, long, \ + double, double, double, double, \ + double, double, double, double +#undef DLSTACK_ARGS +#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], \ + sse[0], sse[1], sse[2], sse[3], \ + sse[4], sse[5], sse[6], sse[7] switch(type){ case '0': { @@ -450,6 +463,9 @@ rb_dlsym_call(int argc, VALUE argv[], VALUE self) int i; long ftype; void *func; + + int sses=0; + double sse[8]; rb_secure_update(self); Data_Get_Struct(self, struct sym_data, sym); @@ -678,58 +694,58 @@ rb_dlsym_call(int argc, VALUE argv[], VALUE self) switch( sym->type[i+1] ){ case 'p': case 'P': - DLSTACK_PUSH_P(ANY2P(args[i])); - break; case 'a': case 'A': - DLSTACK_PUSH_P(ANY2P(args[i])); + case 'c': + case 'h': + case 'i': + case 'l': + case 'f': + case 'd': + //printf("arg %i: %x (stack)\n",i,ANY2P(args[i])); + memcpy(sp,&ANY2P(args[i]),sizeof(void*)); + sp++; break; + case 'C': - DLSTACK_PUSH_C(ANY2C(args[i])); + //printf("arg %i: '%c' (stack)\n",i,ANY2P(args[i])); + memcpy(sp,&ANY2C(args[i]),sizeof(void*)); + sp++; break; - case 'c': - DLSTACK_PUSH_P(ANY2P(args[i])); - break; case 'H': - DLSTACK_PUSH_H(ANY2H(args[i])); + //printf("arg %i: H (stack)\n",i); + memcpy(sp,&ANY2H(args[i]),sizeof(void*)); + sp++; break; - case 'h': - DLSTACK_PUSH_P(ANY2P(args[i])); - break; case 'I': - DLSTACK_PUSH_I(ANY2I(args[i])); + //printf("arg %i: %d (stack)\n",i,ANY2I(args[i])); + memcpy(sp,&ANY2I(args[i]),sizeof(void*)); + sp++; break; - case 'i': - DLSTACK_PUSH_P(ANY2P(args[i])); - break; case 'L': - DLSTACK_PUSH_L(ANY2L(args[i])); - break; - case 'l': - DLSTACK_PUSH_P(ANY2P(args[i])); - break; + //printf("arg %i: %liL (stack)\n",i,ANY2L(args[i])); + memcpy(sp,&ANY2L(args[i]),sizeof(void*)); + sp++; case 'F': - DLSTACK_PUSH_F(ANY2F(args[i])); + //printf("arg %i: %fF (sse)\n",i,ANY2F(args[i])); + sse[sses++]=*(double*)&ANY2F(args[i]); break; - case 'f': - DLSTACK_PUSH_P(ANY2P(args[i])); - break; case 'D': - DLSTACK_PUSH_D(ANY2D(args[i])); + //printf("arg %i: %fLF (sse)\n",i,ANY2D(args[i])); + sse[sses++]=ANY2D(args[i]); break; - case 'd': - DLSTACK_PUSH_P(ANY2P(args[i])); - break; case 'S': case 's': - DLSTACK_PUSH_P(ANY2S(args[i])); + //printf("arg %i: \"%s\" (stack)\n",i,ANY2S(args[i])); + memcpy(sp,&ANY2S(args[i]),sizeof(void*)); + sp++; break; } } DLSTACK_END(sym->type); #ifdef DLSTACK_GUARD - if(!rb_dlsym_guardcall(sym->type[0], &ret, stack, func)) { + if(!rb_dlsym_guardcall(sym->type[0], &ret, stack, sse, func)) { FREE_ARGS; rb_raise(rb_eDLTypeError, "unknown type `%c'", sym->type[0]); } @@ -876,7 +892,7 @@ rb_dlsym_call(int argc, VALUE argv[], VALUE self) if( ANY2S(ret) ){ val = rb_tainted_str_new2((char*)(ANY2S(ret))); DEBUG_CODE({ - printf("dlfree(%s)\n",(char*)(ANY2S(ret))); + //printf("dlfree(%s)\n",(char*)(ANY2S(ret))); }); dlfree((void*)(ANY2S(ret))); }