Ruby 2.7.7p221 (2022-11-24 revision 168ec2b1e5ad0e4688e963d9de019557c78feed9)
fiddle.c
Go to the documentation of this file.
1#include <fiddle.h>
2
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
38void 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 */
46static VALUE
47rb_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 */
62static VALUE
63rb_fiddle_realloc(VALUE self, VALUE addr, VALUE size)
64{
65 void *ptr = NUM2PTR(addr);
66
68 return PTR2NUM(ptr);
69}
70
71/*
72 * call-seq: Fiddle.free(addr)
73 *
74 * Free the memory at address +addr+
75 */
78{
79 void *ptr = NUM2PTR(addr);
80
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 */
101VALUE
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 */
120static VALUE
121rb_fiddle_value2ptr(VALUE self, VALUE val)
122{
123 return PTR2NUM((void*)val);
124}
125
126void Init_fiddle_handle(void);
127
128void
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 */
172
173 /* Document-const: TYPE_VOID
174 *
175 * C type - void
176 */
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 */
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 */
202
203 /* Document-const: TYPE_LONG
204 *
205 * C type - long
206 */
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 */
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 */
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 */
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);
445 rb_define_module_function(mFiddle, "malloc", rb_fiddle_malloc, 1);
446 rb_define_module_function(mFiddle, "realloc", rb_fiddle_realloc, 2);
448
453}
454/* vim: set noet sws=4 sw=4: */
void Init_fiddle_closure(void)
Definition: closure.c:289
#define NUM2PTR(x)
Definition: conversions.h:37
#define PTR2NUM(x)
Definition: conversions.h:36
struct RIMemo * ptr
Definition: debug.c:65
void Init_fiddle(void)
Definition: fiddle.c:129
#define TYPE_PTRDIFF_T
Definition: fiddle.c:19
void Init_fiddle_pointer(void)
Definition: pointer.c:676
VALUE mFiddle
Definition: fiddle.c:3
VALUE rb_fiddle_ptr2value(VALUE self, VALUE addr)
Definition: fiddle.c:102
VALUE rb_fiddle_free(VALUE self, VALUE addr)
Definition: fiddle.c:77
#define TYPE_SIZE_T
Definition: fiddle.c:15
VALUE rb_eFiddleError
Definition: fiddle.c:4
#define TYPE_INTPTR_T
Definition: fiddle.c:29
void Init_fiddle_handle(void)
Definition: handle.c:376
#define TYPE_SSIZE_T
Definition: fiddle.c:8
#define TYPE_UINTPTR_T
Definition: fiddle.c:36
#define TYPE_FLOAT
Definition: fiddle.h:116
#define TYPE_CHAR
Definition: fiddle.h:109
#define TYPE_VOID
Definition: fiddle.h:107
#define ALIGN_DOUBLE
Definition: fiddle.h:130
#define TYPE_INT
Definition: fiddle.h:111
#define TYPE_LONG
Definition: fiddle.h:112
#define ALIGN_OF(type)
Definition: fiddle.h:119
#define ALIGN_CHAR
Definition: fiddle.h:123
#define ALIGN_LONG
Definition: fiddle.h:125
#define TYPE_VOIDP
Definition: fiddle.h:108
#define ALIGN_SHORT
Definition: fiddle.h:122
#define ALIGN_FLOAT
Definition: fiddle.h:129
#define TYPE_DOUBLE
Definition: fiddle.h:117
#define TYPE_SHORT
Definition: fiddle.h:110
#define ALIGN_VOIDP
Definition: fiddle.h:121
#define ALIGN_INT
Definition: fiddle.h:124
void Init_fiddle_function(void)
Definition: function.c:225
VALUE rb_define_class_under(VALUE, const char *, VALUE)
Defines a class under the namespace of outer.
Definition: class.c:711
VALUE rb_define_module(const char *)
Definition: class.c:785
VALUE rb_eStandardError
Definition: error.c:921
#define rb_str_new2
long int ptrdiff_t
__intptr_t intptr_t
unsigned long VALUE
#define INT2NUM(x)
void rb_define_module_function(VALUE, const char *, VALUE(*)(), int)
void rb_define_const(VALUE, const char *, VALUE)
Definition: variable.c:2891
#define RUBY_PLATFORM
#define NUM2SIZET(x)
unsigned int size
#define Qtrue
__uintptr_t uintptr_t
#define Qnil
#define Qfalse
void void ruby_xfree(void *)
Definition: gc.c:10183
void void void * ruby_xrealloc(void *, size_t) __attribute__((__returns_nonnull__)) __attribute__((alloc_size(2)))
Definition: gc.c:12038
#define LONG_LONG
void * ruby_xmalloc(size_t) __attribute__((__malloc__)) __attribute__((__returns_nonnull__)) __attribute__((alloc_size(1)))
Definition: gc.c:12008