Ruby 2.7.0p0(2019-12-25revision647ee6f091eafcce70ffb75ddf7e121e192ab217)

fiddle.c
Go to the documentation of this file.
1 #include <fiddle.h>
2
3 VALUE mFiddle;
4 VALUE rb_eFiddleError;
5
6 #ifndef TYPE_SSIZE_T
7 # if SIZEOF_SIZE_T == SIZEOF_INT
8 # define TYPE_SSIZE_T TYPE_INT
9 # elif SIZEOF_SIZE_T == SIZEOF_LONG
10 # define TYPE_SSIZE_T TYPE_LONG
11 # elif defined HAVE_LONG_LONG && SIZEOF_SIZE_T == SIZEOF_LONG_LONG
12 # define TYPE_SSIZE_T TYPE_LONG_LONG
13 # endif
14 #endif
15 #define TYPE_SIZE_T (-1*SIGNEDNESS_OF_SIZE_T*TYPE_SSIZE_T)
16
17 #ifndef TYPE_PTRDIFF_T
18 # if SIZEOF_PTRDIFF_T == SIZEOF_INT
19 # define TYPE_PTRDIFF_T TYPE_INT
20 # elif SIZEOF_PTRDIFF_T == SIZEOF_LONG
21 # define TYPE_PTRDIFF_T TYPE_LONG
22 # elif defined HAVE_LONG_LONG && SIZEOF_PTRDIFF_T == SIZEOF_LONG_LONG
23 # define TYPE_PTRDIFF_T TYPE_LONG_LONG
24 # endif
25 #endif
26
27 #ifndef TYPE_INTPTR_T
28 # if SIZEOF_INTPTR_T == SIZEOF_INT
29 # define TYPE_INTPTR_T TYPE_INT
30 # elif SIZEOF_INTPTR_T == SIZEOF_LONG
31 # define TYPE_INTPTR_T TYPE_LONG
32 # elif defined HAVE_LONG_LONG && SIZEOF_INTPTR_T == SIZEOF_LONG_LONG
33 # define TYPE_INTPTR_T TYPE_LONG_LONG
34 # endif
35 #endif
36 #define TYPE_UINTPTR_T (-TYPE_INTPTR_T)
37
38 void Init_fiddle_pointer(void);
39
40 /*
41 * call-seq: Fiddle.malloc(size)
42 *
43 * Allocate +size+ bytes of memory and return the integer memory address
44 * for the allocated memory.
45 */
46 static VALUE
47 rb_fiddle_malloc(VALUE self, VALUE size)
48 {
49 void *ptr;
50
51 ptr = (void*)ruby_xmalloc(NUM2SIZET(size));
52 return PTR2NUM(ptr);
53 }
54
55 /*
56 * call-seq: Fiddle.realloc(addr, size)
57 *
58 * Change the size of the memory allocated at the memory location +addr+ to
59 * +size+ bytes. Returns the memory address of the reallocated memory, which
60 * may be different than the address passed in.
61 */
62 static VALUE
63 rb_fiddle_realloc(VALUE self, VALUE addr, VALUE size)
64 {
65 void *ptr = NUM2PTR(addr);
66
67 ptr = (void*)ruby_xrealloc(ptr, NUM2SIZET(size));
68 return PTR2NUM(ptr);
69 }
70
71 /*
72 * call-seq: Fiddle.free(addr)
73 *
74 * Free the memory at address +addr+
75 */
76 VALUE
77 rb_fiddle_free(VALUE self, VALUE addr)
78 {
79 void *ptr = NUM2PTR(addr);
80
81 ruby_xfree(ptr);
82 return Qnil;
83 }
84
85 /*
86 * call-seq: Fiddle.dlunwrap(addr)
87 *
88 * Returns the hexadecimal representation of a memory pointer address +addr+
89 *
90 * Example:
91 *
92 * lib = Fiddle.dlopen('/lib64/libc-2.15.so')
93 * => #<Fiddle::Handle:0x00000001342460>
94 *
95 * lib['strcpy'].to_s(16)
96 * => "7f59de6dd240"
97 *
98 * Fiddle.dlunwrap(Fiddle.dlwrap(lib['strcpy'].to_s(16)))
99 * => "7f59de6dd240"
100 */
101 VALUE
102 rb_fiddle_ptr2value(VALUE self, VALUE addr)
103 {
104 return (VALUE)NUM2PTR(addr);
105 }
106
107 /*
108 * call-seq: Fiddle.dlwrap(val)
109 *
110 * Returns a memory pointer of a function's hexadecimal address location +val+
111 *
112 * Example:
113 *
114 * lib = Fiddle.dlopen('/lib64/libc-2.15.so')
115 * => #<Fiddle::Handle:0x00000001342460>
116 *
117 * Fiddle.dlwrap(lib['strcpy'].to_s(16))
118 * => 25522520
119 */
120 static VALUE
121 rb_fiddle_value2ptr(VALUE self, VALUE val)
122 {
123 return PTR2NUM((void*)val);
124 }
125
126 void Init_fiddle_handle(void);
127
128 void
129 Init_fiddle(void)
130 {
131 /*
132 * Document-module: Fiddle
133 *
134 * A libffi wrapper for Ruby.
135 *
136 * == Description
137 *
138 * Fiddle is an extension to translate a foreign function interface (FFI)
139 * with ruby.
140 *
141 * It wraps {libffi}[http://sourceware.org/libffi/], a popular C library
142 * which provides a portable interface that allows code written in one
143 * language to call code written in another language.
144 *
145 * == Example
146 *
147 * Here we will use Fiddle::Function to wrap {floor(3) from
148 * libm}[http://linux.die.net/man/3/floor]
149 *
150 * require 'fiddle'
151 *
152 * libm = Fiddle.dlopen('/lib/libm.so.6')
153 *
154 * floor = Fiddle::Function.new(
155 * libm['floor'],
156 * [Fiddle::TYPE_DOUBLE],
157 * Fiddle::TYPE_DOUBLE
158 * )
159 *
160 * puts floor.call(3.14159) #=> 3.0
161 *
162 *
163 */
164 mFiddle = rb_define_module("Fiddle");
165
166 /*
167 * Document-class: Fiddle::DLError
168 *
169 * standard dynamic load exception
170 */
171 rb_eFiddleError = rb_define_class_under(mFiddle, "DLError", rb_eStandardError);
172
173 /* Document-const: TYPE_VOID
174 *
175 * C type - void
176 */
177 rb_define_const(mFiddle, "TYPE_VOID", INT2NUM(TYPE_VOID));
178
179 /* Document-const: TYPE_VOIDP
180 *
181 * C type - void*
182 */
183 rb_define_const(mFiddle, "TYPE_VOIDP", INT2NUM(TYPE_VOIDP));
184
185 /* Document-const: TYPE_CHAR
186 *
187 * C type - char
188 */
189 rb_define_const(mFiddle, "TYPE_CHAR", INT2NUM(TYPE_CHAR));
190
191 /* Document-const: TYPE_SHORT
192 *
193 * C type - short
194 */
195 rb_define_const(mFiddle, "TYPE_SHORT", INT2NUM(TYPE_SHORT));
196
197 /* Document-const: TYPE_INT
198 *
199 * C type - int
200 */
201 rb_define_const(mFiddle, "TYPE_INT", INT2NUM(TYPE_INT));
202
203 /* Document-const: TYPE_LONG
204 *
205 * C type - long
206 */
207 rb_define_const(mFiddle, "TYPE_LONG", INT2NUM(TYPE_LONG));
208
209 #if HAVE_LONG_LONG
210 /* Document-const: TYPE_LONG_LONG
211 *
212 * C type - long long
213 */
214 rb_define_const(mFiddle, "TYPE_LONG_LONG", INT2NUM(TYPE_LONG_LONG));
215 #endif
216
217 /* Document-const: TYPE_FLOAT
218 *
219 * C type - float
220 */
221 rb_define_const(mFiddle, "TYPE_FLOAT", INT2NUM(TYPE_FLOAT));
222
223 /* Document-const: TYPE_DOUBLE
224 *
225 * C type - double
226 */
227 rb_define_const(mFiddle, "TYPE_DOUBLE", INT2NUM(TYPE_DOUBLE));
228
229 /* Document-const: TYPE_SIZE_T
230 *
231 * C type - size_t
232 */
233 rb_define_const(mFiddle, "TYPE_SIZE_T", INT2NUM(TYPE_SIZE_T));
234
235 /* Document-const: TYPE_SSIZE_T
236 *
237 * C type - ssize_t
238 */
239 rb_define_const(mFiddle, "TYPE_SSIZE_T", INT2NUM(TYPE_SSIZE_T));
240
241 /* Document-const: TYPE_PTRDIFF_T
242 *
243 * C type - ptrdiff_t
244 */
245 rb_define_const(mFiddle, "TYPE_PTRDIFF_T", INT2NUM(TYPE_PTRDIFF_T));
246
247 /* Document-const: TYPE_INTPTR_T
248 *
249 * C type - intptr_t
250 */
251 rb_define_const(mFiddle, "TYPE_INTPTR_T", INT2NUM(TYPE_INTPTR_T));
252
253 /* Document-const: TYPE_UINTPTR_T
254 *
255 * C type - uintptr_t
256 */
257 rb_define_const(mFiddle, "TYPE_UINTPTR_T", INT2NUM(TYPE_UINTPTR_T));
258
259 /* Document-const: ALIGN_VOIDP
260 *
261 * The alignment size of a void*
262 */
263 rb_define_const(mFiddle, "ALIGN_VOIDP", INT2NUM(ALIGN_VOIDP));
264
265 /* Document-const: ALIGN_CHAR
266 *
267 * The alignment size of a char
268 */
269 rb_define_const(mFiddle, "ALIGN_CHAR", INT2NUM(ALIGN_CHAR));
270
271 /* Document-const: ALIGN_SHORT
272 *
273 * The alignment size of a short
274 */
275 rb_define_const(mFiddle, "ALIGN_SHORT", INT2NUM(ALIGN_SHORT));
276
277 /* Document-const: ALIGN_INT
278 *
279 * The alignment size of an int
280 */
281 rb_define_const(mFiddle, "ALIGN_INT", INT2NUM(ALIGN_INT));
282
283 /* Document-const: ALIGN_LONG
284 *
285 * The alignment size of a long
286 */
287 rb_define_const(mFiddle, "ALIGN_LONG", INT2NUM(ALIGN_LONG));
288
289 #if HAVE_LONG_LONG
290 /* Document-const: ALIGN_LONG_LONG
291 *
292 * The alignment size of a long long
293 */
294 rb_define_const(mFiddle, "ALIGN_LONG_LONG", INT2NUM(ALIGN_LONG_LONG));
295 #endif
296
297 /* Document-const: ALIGN_FLOAT
298 *
299 * The alignment size of a float
300 */
301 rb_define_const(mFiddle, "ALIGN_FLOAT", INT2NUM(ALIGN_FLOAT));
302
303 /* Document-const: ALIGN_DOUBLE
304 *
305 * The alignment size of a double
306 */
307 rb_define_const(mFiddle, "ALIGN_DOUBLE",INT2NUM(ALIGN_DOUBLE));
308
309 /* Document-const: ALIGN_SIZE_T
310 *
311 * The alignment size of a size_t
312 */
313 rb_define_const(mFiddle, "ALIGN_SIZE_T", INT2NUM(ALIGN_OF(size_t)));
314
315 /* Document-const: ALIGN_SSIZE_T
316 *
317 * The alignment size of a ssize_t
318 */
319 rb_define_const(mFiddle, "ALIGN_SSIZE_T", INT2NUM(ALIGN_OF(size_t))); /* same as size_t */
320
321 /* Document-const: ALIGN_PTRDIFF_T
322 *
323 * The alignment size of a ptrdiff_t
324 */
325 rb_define_const(mFiddle, "ALIGN_PTRDIFF_T", INT2NUM(ALIGN_OF(ptrdiff_t)));
326
327 /* Document-const: ALIGN_INTPTR_T
328 *
329 * The alignment size of a intptr_t
330 */
331 rb_define_const(mFiddle, "ALIGN_INTPTR_T", INT2NUM(ALIGN_OF(intptr_t)));
332
333 /* Document-const: ALIGN_UINTPTR_T
334 *
335 * The alignment size of a uintptr_t
336 */
337 rb_define_const(mFiddle, "ALIGN_UINTPTR_T", INT2NUM(ALIGN_OF(uintptr_t)));
338
339 /* Document-const: WINDOWS
340 *
341 * Returns a boolean regarding whether the host is WIN32
342 */
343 #if defined(_WIN32)
344 rb_define_const(mFiddle, "WINDOWS", Qtrue);
345 #else
346 rb_define_const(mFiddle, "WINDOWS", Qfalse);
347 #endif
348
349 /* Document-const: SIZEOF_VOIDP
350 *
351 * size of a void*
352 */
353 rb_define_const(mFiddle, "SIZEOF_VOIDP", INT2NUM(sizeof(void*)));
354
355 /* Document-const: SIZEOF_CHAR
356 *
357 * size of a char
358 */
359 rb_define_const(mFiddle, "SIZEOF_CHAR", INT2NUM(sizeof(char)));
360
361 /* Document-const: SIZEOF_SHORT
362 *
363 * size of a short
364 */
365 rb_define_const(mFiddle, "SIZEOF_SHORT", INT2NUM(sizeof(short)));
366
367 /* Document-const: SIZEOF_INT
368 *
369 * size of an int
370 */
371 rb_define_const(mFiddle, "SIZEOF_INT", INT2NUM(sizeof(int)));
372
373 /* Document-const: SIZEOF_LONG
374 *
375 * size of a long
376 */
377 rb_define_const(mFiddle, "SIZEOF_LONG", INT2NUM(sizeof(long)));
378
379 #if HAVE_LONG_LONG
380 /* Document-const: SIZEOF_LONG_LONG
381 *
382 * size of a long long
383 */
384 rb_define_const(mFiddle, "SIZEOF_LONG_LONG", INT2NUM(sizeof(LONG_LONG)));
385 #endif
386
387 /* Document-const: SIZEOF_FLOAT
388 *
389 * size of a float
390 */
391 rb_define_const(mFiddle, "SIZEOF_FLOAT", INT2NUM(sizeof(float)));
392
393 /* Document-const: SIZEOF_DOUBLE
394 *
395 * size of a double
396 */
397 rb_define_const(mFiddle, "SIZEOF_DOUBLE",INT2NUM(sizeof(double)));
398
399 /* Document-const: SIZEOF_SIZE_T
400 *
401 * size of a size_t
402 */
403 rb_define_const(mFiddle, "SIZEOF_SIZE_T", INT2NUM(sizeof(size_t)));
404
405 /* Document-const: SIZEOF_SSIZE_T
406 *
407 * size of a ssize_t
408 */
409 rb_define_const(mFiddle, "SIZEOF_SSIZE_T", INT2NUM(sizeof(size_t))); /* same as size_t */
410
411 /* Document-const: SIZEOF_PTRDIFF_T
412 *
413 * size of a ptrdiff_t
414 */
415 rb_define_const(mFiddle, "SIZEOF_PTRDIFF_T", INT2NUM(sizeof(ptrdiff_t)));
416
417 /* Document-const: SIZEOF_INTPTR_T
418 *
419 * size of a intptr_t
420 */
421 rb_define_const(mFiddle, "SIZEOF_INTPTR_T", INT2NUM(sizeof(intptr_t)));
422
423 /* Document-const: SIZEOF_UINTPTR_T
424 *
425 * size of a uintptr_t
426 */
427 rb_define_const(mFiddle, "SIZEOF_UINTPTR_T", INT2NUM(sizeof(uintptr_t)));
428
429 /* Document-const: RUBY_FREE
430 *
431 * Address of the ruby_xfree() function
432 */
433 rb_define_const(mFiddle, "RUBY_FREE", PTR2NUM(ruby_xfree));
434
435 /* Document-const: BUILD_RUBY_PLATFORM
436 *
437 * Platform built against (i.e. "x86_64-linux", etc.)
438 *
439 * See also RUBY_PLATFORM
440 */
441 rb_define_const(mFiddle, "BUILD_RUBY_PLATFORM", rb_str_new2(RUBY_PLATFORM));
442
443 rb_define_module_function(mFiddle, "dlwrap", rb_fiddle_value2ptr, 1);
444 rb_define_module_function(mFiddle, "dlunwrap", rb_fiddle_ptr2value, 1);
445 rb_define_module_function(mFiddle, "malloc", rb_fiddle_malloc, 1);
446 rb_define_module_function(mFiddle, "realloc", rb_fiddle_realloc, 2);
447 rb_define_module_function(mFiddle, "free", rb_fiddle_free, 1);
448
449 Init_fiddle_function();
450 Init_fiddle_closure();
451 Init_fiddle_handle();
452 Init_fiddle_pointer();
453 }
454 /* vim: set noet sws=4 sw=4: */
TYPE_VOIDP
#define TYPE_VOIDP
Definition: fiddle.h:108
TYPE_DOUBLE
#define TYPE_DOUBLE
Definition: fiddle.h:117
ruby_xfree
void ruby_xfree(void *x)
Definition: gc.c:10150
Init_fiddle_closure
void Init_fiddle_closure(void)
Definition: closure.c:292
TYPE_PTRDIFF_T
#define TYPE_PTRDIFF_T
Definition: fiddle.c:19
TYPE_LONG
#define TYPE_LONG
Definition: fiddle.h:112
rb_str_new2
#define rb_str_new2
Definition: intern.h:903
mFiddle
VALUE mFiddle
Definition: fiddle.c:3
Init_fiddle_handle
void Init_fiddle_handle(void)
Definition: handle.c:376
ruby_xmalloc
void * ruby_xmalloc(size_t size)
Definition: gc.c:11950
LONG_LONG
#define LONG_LONG
Definition: rb_mjit_min_header-2.7.0.h:3939
fiddle.h
VALUE
unsigned long VALUE
Definition: ruby.h:102
rb_define_module
VALUE rb_define_module(const char *name)
Definition: class.c:772
TYPE_UINTPTR_T
#define TYPE_UINTPTR_T
Definition: fiddle.c:36
TYPE_SHORT
#define TYPE_SHORT
Definition: fiddle.h:110
TYPE_INT
#define TYPE_INT
Definition: fiddle.h:111
INT2NUM
#define INT2NUM(x)
Definition: ruby.h:1609
ptr
struct RIMemo * ptr
Definition: debug.c:74
ALIGN_CHAR
#define ALIGN_CHAR
Definition: fiddle.h:123
Qfalse
#define Qfalse
Definition: ruby.h:467
rb_fiddle_ptr2value
VALUE rb_fiddle_ptr2value(VALUE self, VALUE addr)
Definition: fiddle.c:102
uintptr_t
unsigned int uintptr_t
Definition: win32.h:106
Init_fiddle_pointer
void Init_fiddle_pointer(void)
Definition: pointer.c:676
ALIGN_INT
#define ALIGN_INT
Definition: fiddle.h:124
ALIGN_OF
#define ALIGN_OF(type)
Definition: fiddle.h:119
ruby_xrealloc
void * ruby_xrealloc(void *ptr, size_t new_size)
Definition: gc.c:11980
rb_eFiddleError
VALUE rb_eFiddleError
Definition: fiddle.c:4
NUM2SIZET
#define NUM2SIZET(x)
Definition: ruby.h:769
TYPE_CHAR
#define TYPE_CHAR
Definition: fiddle.h:109
ALIGN_SHORT
#define ALIGN_SHORT
Definition: fiddle.h:122
TYPE_SIZE_T
#define TYPE_SIZE_T
Definition: fiddle.c:15
NUM2PTR
#define NUM2PTR(x)
Definition: conversions.h:37
ALIGN_LONG
#define ALIGN_LONG
Definition: fiddle.h:125
ALIGN_DOUBLE
#define ALIGN_DOUBLE
Definition: fiddle.h:130
ALIGN_FLOAT
#define ALIGN_FLOAT
Definition: fiddle.h:129
size
int size
Definition: encoding.c:58
TYPE_VOID
#define TYPE_VOID
Definition: fiddle.h:107
TYPE_INTPTR_T
#define TYPE_INTPTR_T
Definition: fiddle.c:29
ALIGN_VOIDP
#define ALIGN_VOIDP
Definition: fiddle.h:121
rb_define_module_function
void rb_define_module_function(VALUE module, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a module function for module.
Definition: class.c:1771
RUBY_PLATFORM
#define RUBY_PLATFORM
Definition: defines.h:460
TYPE_SSIZE_T
#define TYPE_SSIZE_T
Definition: fiddle.c:8
Init_fiddle_function
void Init_fiddle_function(void)
Definition: function.c:225
PTR2NUM
#define PTR2NUM(x)
Definition: conversions.h:36
rb_define_const
void rb_define_const(VALUE, const char *, VALUE)
Definition: variable.c:2880
TYPE_FLOAT
#define TYPE_FLOAT
Definition: fiddle.h:116
Init_fiddle
void Init_fiddle(void)
Definition: fiddle.c:129
Qtrue
#define Qtrue
Definition: ruby.h:468
intptr_t
int intptr_t
Definition: win32.h:90
rb_define_class_under
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
Definition: class.c:698
Qnil
#define Qnil
Definition: ruby.h:469
rb_eStandardError
VALUE rb_eStandardError
Definition: error.c:919
ptrdiff_t
long int ptrdiff_t
Definition: rb_mjit_min_header-2.7.0.h:802
rb_fiddle_free
VALUE rb_fiddle_free(VALUE self, VALUE addr)
Definition: fiddle.c:77