1#ifndef RUBY_DL_H 2#define RUBY_DL_H 3 4#include <ruby.h> 5 6#if !defined(FUNC_CDECL) 7# define FUNC_CDECL(x) x 8#endif 9 10#if defined(HAVE_DLFCN_H) 11# include <dlfcn.h> 12# /* some stranger systems may not define all of these */ 13#ifndef RTLD_LAZY 14#define RTLD_LAZY 0 15#endif 16#ifndef RTLD_GLOBAL 17#define RTLD_GLOBAL 0 18#endif 19#ifndef RTLD_NOW 20#define RTLD_NOW 0 21#endif 22#else 23# if defined(_WIN32) 24# include <windows.h> 25# define dlopen(name,flag) ((void*)LoadLibrary(name)) 26# define dlerror() strerror(rb_w32_map_errno(GetLastError())) 27# define dlsym(handle,name) ((void*)GetProcAddress((handle),(name))) 28# define RTLD_LAZY -1 29# define RTLD_NOW -1 30# define RTLD_GLOBAL -1 31# endif 32#endif 33 34#define MAX_CALLBACK 5 35#define DLSTACK_TYPE SIGNED_VALUE 36#define DLSTACK_SIZE (20) 37#define DLSTACK_PROTO \ 38 DLSTACK_TYPE,DLSTACK_TYPE,DLSTACK_TYPE,DLSTACK_TYPE,DLSTACK_TYPE,\ 39 DLSTACK_TYPE,DLSTACK_TYPE,DLSTACK_TYPE,DLSTACK_TYPE,DLSTACK_TYPE,\ 40 DLSTACK_TYPE,DLSTACK_TYPE,DLSTACK_TYPE,DLSTACK_TYPE,DLSTACK_TYPE,\ 41 DLSTACK_TYPE,DLSTACK_TYPE,DLSTACK_TYPE,DLSTACK_TYPE,DLSTACK_TYPE 42#define DLSTACK_ARGS(stack) \ 43 (stack)[0],(stack)[1],(stack)[2],(stack)[3],(stack)[4],\ 44 (stack)[5],(stack)[6],(stack)[7],(stack)[8],(stack)[9],\ 45 (stack)[10],(stack)[11],(stack)[12],(stack)[13],(stack)[14],\ 46 (stack)[15],(stack)[16],(stack)[17],(stack)[18],(stack)[19] 47 48#define DLSTACK_PROTO0_ void 49#define DLSTACK_PROTO1_ DLSTACK_TYPE 50#define DLSTACK_PROTO2_ DLSTACK_PROTO1_, DLSTACK_TYPE 51#define DLSTACK_PROTO3_ DLSTACK_PROTO2_, DLSTACK_TYPE 52#define DLSTACK_PROTO4_ DLSTACK_PROTO3_, DLSTACK_TYPE 53#define DLSTACK_PROTO4_ DLSTACK_PROTO3_, DLSTACK_TYPE 54#define DLSTACK_PROTO5_ DLSTACK_PROTO4_, DLSTACK_TYPE 55#define DLSTACK_PROTO6_ DLSTACK_PROTO5_, DLSTACK_TYPE 56#define DLSTACK_PROTO7_ DLSTACK_PROTO6_, DLSTACK_TYPE 57#define DLSTACK_PROTO8_ DLSTACK_PROTO7_, DLSTACK_TYPE 58#define DLSTACK_PROTO9_ DLSTACK_PROTO8_, DLSTACK_TYPE 59#define DLSTACK_PROTO10_ DLSTACK_PROTO9_, DLSTACK_TYPE 60#define DLSTACK_PROTO11_ DLSTACK_PROTO10_, DLSTACK_TYPE 61#define DLSTACK_PROTO12_ DLSTACK_PROTO11_, DLSTACK_TYPE 62#define DLSTACK_PROTO13_ DLSTACK_PROTO12_, DLSTACK_TYPE 63#define DLSTACK_PROTO14_ DLSTACK_PROTO13_, DLSTACK_TYPE 64#define DLSTACK_PROTO14_ DLSTACK_PROTO13_, DLSTACK_TYPE 65#define DLSTACK_PROTO15_ DLSTACK_PROTO14_, DLSTACK_TYPE 66#define DLSTACK_PROTO16_ DLSTACK_PROTO15_, DLSTACK_TYPE 67#define DLSTACK_PROTO17_ DLSTACK_PROTO16_, DLSTACK_TYPE 68#define DLSTACK_PROTO18_ DLSTACK_PROTO17_, DLSTACK_TYPE 69#define DLSTACK_PROTO19_ DLSTACK_PROTO18_, DLSTACK_TYPE 70#define DLSTACK_PROTO20_ DLSTACK_PROTO19_, DLSTACK_TYPE 71 72/* 73 * Add ",..." as the last argument. 74 * This is required for variable argument functions such 75 * as fprintf() on x86_64-linux. 76 * 77 * http://refspecs.linuxfoundation.org/elf/x86_64-abi-0.95.pdf 78 * page 19: 79 * 80 * For calls that may call functions that use varargs or stdargs 81 * (prototype-less calls or calls to functions containing ellipsis 82 * (...) in the declaration) %al is used as hidden argument to 83 * specify the number of SSE registers used. 84 */ 85#define DLSTACK_PROTO0 void 86#define DLSTACK_PROTO1 DLSTACK_PROTO1_, ... 87#define DLSTACK_PROTO2 DLSTACK_PROTO2_, ... 88#define DLSTACK_PROTO3 DLSTACK_PROTO3_, ... 89#define DLSTACK_PROTO4 DLSTACK_PROTO4_, ... 90#define DLSTACK_PROTO4 DLSTACK_PROTO4_, ... 91#define DLSTACK_PROTO5 DLSTACK_PROTO5_, ... 92#define DLSTACK_PROTO6 DLSTACK_PROTO6_, ... 93#define DLSTACK_PROTO7 DLSTACK_PROTO7_, ... 94#define DLSTACK_PROTO8 DLSTACK_PROTO8_, ... 95#define DLSTACK_PROTO9 DLSTACK_PROTO9_, ... 96#define DLSTACK_PROTO10 DLSTACK_PROTO10_, ... 97#define DLSTACK_PROTO11 DLSTACK_PROTO11_, ... 98#define DLSTACK_PROTO12 DLSTACK_PROTO12_, ... 99#define DLSTACK_PROTO13 DLSTACK_PROTO13_, ... 100#define DLSTACK_PROTO14 DLSTACK_PROTO14_, ... 101#define DLSTACK_PROTO14 DLSTACK_PROTO14_, ... 102#define DLSTACK_PROTO15 DLSTACK_PROTO15_, ... 103#define DLSTACK_PROTO16 DLSTACK_PROTO16_, ... 104#define DLSTACK_PROTO17 DLSTACK_PROTO17_, ... 105#define DLSTACK_PROTO18 DLSTACK_PROTO18_, ... 106#define DLSTACK_PROTO19 DLSTACK_PROTO19_, ... 107#define DLSTACK_PROTO20 DLSTACK_PROTO20_, ... 108 109#define DLSTACK_ARGS0(stack) 110#define DLSTACK_ARGS1(stack) (stack)[0] 111#define DLSTACK_ARGS2(stack) DLSTACK_ARGS1(stack), (stack)[1] 112#define DLSTACK_ARGS3(stack) DLSTACK_ARGS2(stack), (stack)[2] 113#define DLSTACK_ARGS4(stack) DLSTACK_ARGS3(stack), (stack)[3] 114#define DLSTACK_ARGS5(stack) DLSTACK_ARGS4(stack), (stack)[4] 115#define DLSTACK_ARGS6(stack) DLSTACK_ARGS5(stack), (stack)[5] 116#define DLSTACK_ARGS7(stack) DLSTACK_ARGS6(stack), (stack)[6] 117#define DLSTACK_ARGS8(stack) DLSTACK_ARGS7(stack), (stack)[7] 118#define DLSTACK_ARGS9(stack) DLSTACK_ARGS8(stack), (stack)[8] 119#define DLSTACK_ARGS10(stack) DLSTACK_ARGS9(stack), (stack)[9] 120#define DLSTACK_ARGS11(stack) DLSTACK_ARGS10(stack), (stack)[10] 121#define DLSTACK_ARGS12(stack) DLSTACK_ARGS11(stack), (stack)[11] 122#define DLSTACK_ARGS13(stack) DLSTACK_ARGS12(stack), (stack)[12] 123#define DLSTACK_ARGS14(stack) DLSTACK_ARGS13(stack), (stack)[13] 124#define DLSTACK_ARGS15(stack) DLSTACK_ARGS14(stack), (stack)[14] 125#define DLSTACK_ARGS16(stack) DLSTACK_ARGS15(stack), (stack)[15] 126#define DLSTACK_ARGS17(stack) DLSTACK_ARGS16(stack), (stack)[16] 127#define DLSTACK_ARGS18(stack) DLSTACK_ARGS17(stack), (stack)[17] 128#define DLSTACK_ARGS19(stack) DLSTACK_ARGS18(stack), (stack)[18] 129#define DLSTACK_ARGS20(stack) DLSTACK_ARGS19(stack), (stack)[19] 130 131extern VALUE rb_mDL; 132extern VALUE rb_cDLHandle; 133extern VALUE rb_cDLSymbol; 134extern VALUE rb_eDLError; 135extern VALUE rb_eDLTypeError; 136 137#define ALIGN_OF(type) offsetof(struct {char align_c; type align_x;}, align_x) 138 139#define ALIGN_VOIDP ALIGN_OF(void*) 140#define ALIGN_SHORT ALIGN_OF(short) 141#define ALIGN_CHAR ALIGN_OF(char) 142#define ALIGN_INT ALIGN_OF(int) 143#define ALIGN_LONG ALIGN_OF(long) 144#if HAVE_LONG_LONG 145#define ALIGN_LONG_LONG ALIGN_OF(LONG_LONG) 146#endif 147#define ALIGN_FLOAT ALIGN_OF(float) 148#define ALIGN_DOUBLE ALIGN_OF(double) 149 150#define DLALIGN(ptr,offset,align) \ 151 ((offset) += ((align) - ((uintptr_t)((char *)(ptr) + (offset))) % (align)) % (align)) 152 153 154#define DLTYPE_VOID 0 155#define DLTYPE_VOIDP 1 156#define DLTYPE_CHAR 2 157#define DLTYPE_SHORT 3 158#define DLTYPE_INT 4 159#define DLTYPE_LONG 5 160#if HAVE_LONG_LONG 161#define DLTYPE_LONG_LONG 6 162#endif 163#define DLTYPE_FLOAT 7 164#define DLTYPE_DOUBLE 8 165#define MAX_DLTYPE 9 166 167#if SIZEOF_VOIDP == SIZEOF_LONG 168# define PTR2NUM(x) (ULONG2NUM((unsigned long)(x))) 169# define NUM2PTR(x) ((void*)(NUM2ULONG(x))) 170#else 171/* # error --->> Ruby/DL2 requires sizeof(void*) == sizeof(long) to be compiled. <<--- */ 172# define PTR2NUM(x) (ULL2NUM((unsigned long long)(x))) 173# define NUM2PTR(x) ((void*)(NUM2ULL(x))) 174#endif 175 176#define BOOL2INT(x) (((x) == Qtrue)?1:0) 177#define INT2BOOL(x) ((x)?Qtrue:Qfalse) 178 179typedef void (*freefunc_t)(void*); 180 181struct dl_handle { 182 void *ptr; 183 int open; 184 int enable_close; 185}; 186 187 188struct cfunc_data { 189 void *ptr; 190 char *name; 191 int type; 192 ID calltype; 193 VALUE wrap; 194}; 195extern ID rbdl_id_cdecl; 196extern ID rbdl_id_stdcall; 197#define CFUNC_CDECL (rbdl_id_cdecl) 198#define CFUNC_STDCALL (rbdl_id_stdcall) 199 200struct ptr_data { 201 void *ptr; 202 long size; 203 freefunc_t free; 204 VALUE wrap[2]; 205}; 206 207#define RDL_HANDLE(obj) ((struct dl_handle *)(DATA_PTR(obj))) 208#define RCFUNC_DATA(obj) ((struct cfunc_data *)(DATA_PTR(obj))) 209#define RPTR_DATA(obj) ((struct ptr_data *)(DATA_PTR(obj))) 210 211VALUE rb_dlcfunc_new(void (*func)(), int dltype, const char * name, ID calltype); 212int rb_dlcfunc_kind_p(VALUE func); 213VALUE rb_dlptr_new(void *ptr, long size, freefunc_t func); 214VALUE rb_dlptr_new2(VALUE klass, void *ptr, long size, freefunc_t func); 215VALUE rb_dlptr_malloc(long size, freefunc_t func); 216 217#endif 218