Ruby
2.1.3p242(2014-09-19revision47630)
Main Page
Modules
Data Structures
Files
File List
Globals
ext
dl
dl.c
Go to the documentation of this file.
1
/*
2
* ext/dl/dl.c
3
*
4
* documentation:
5
* - Vincent Batts (vbatts@hashbangbash.com)
6
*
7
*/
8
#include <
ruby/ruby.h
>
9
#include <
ruby/io.h
>
10
#include <ctype.h>
11
#include "
dl.h
"
12
13
VALUE
rb_mDL
;
14
VALUE
rb_eDLError
;
15
VALUE
rb_eDLTypeError
;
16
17
ID
rbdl_id_cdecl
;
18
ID
rbdl_id_stdcall
;
19
20
#ifndef DLTYPE_SSIZE_T
21
# if SIZEOF_SIZE_T == SIZEOF_INT
22
# define DLTYPE_SSIZE_T DLTYPE_INT
23
# elif SIZEOF_SIZE_T == SIZEOF_LONG
24
# define DLTYPE_SSIZE_T DLTYPE_LONG
25
# elif defined HAVE_LONG_LONG && SIZEOF_SIZE_T == SIZEOF_LONG_LONG
26
# define DLTYPE_SSIZE_T DLTYPE_LONG_LONG
27
# endif
28
#endif
29
#define DLTYPE_SIZE_T (-1*SIGNEDNESS_OF_SIZE_T*DLTYPE_SSIZE_T)
30
31
#ifndef DLTYPE_PTRDIFF_T
32
# if SIZEOF_PTRDIFF_T == SIZEOF_INT
33
# define DLTYPE_PTRDIFF_T DLTYPE_INT
34
# elif SIZEOF_PTRDIFF_T == SIZEOF_LONG
35
# define DLTYPE_PTRDIFF_T DLTYPE_LONG
36
# elif defined HAVE_LONG_LONG && SIZEOF_PTRDIFF_T == SIZEOF_LONG_LONG
37
# define DLTYPE_PTRDIFF_T DLTYPE_LONG_LONG
38
# endif
39
#endif
40
41
#ifndef DLTYPE_INTPTR_T
42
# if SIZEOF_INTPTR_T == SIZEOF_INT
43
# define DLTYPE_INTPTR_T DLTYPE_INT
44
# elif SIZEOF_INTPTR_T == SIZEOF_LONG
45
# define DLTYPE_INTPTR_T DLTYPE_LONG
46
# elif defined HAVE_LONG_LONG && SIZEOF_INTPTR_T == SIZEOF_LONG_LONG
47
# define DLTYPE_INTPTR_T DLTYPE_LONG_LONG
48
# endif
49
#endif
50
#define DLTYPE_UINTPTR_T (-DLTYPE_INTPTR_T)
51
52
/*
53
* call-seq: DL.dlopen(so_lib)
54
*
55
* An interface to the dynamic linking loader
56
*
57
* This is a shortcut to DL::Handle.new and takes the same arguments.
58
*
59
* Example:
60
*
61
* libc_so = "/lib64/libc.so.6"
62
* => "/lib64/libc.so.6"
63
*
64
* libc = DL.dlopen(libc_so)
65
* => #<DL::Handle:0x00000000e05b00>
66
*/
67
VALUE
68
rb_dl_dlopen
(
int
argc
,
VALUE
argv
[],
VALUE
self
)
69
{
70
return
rb_class_new_instance
(argc, argv,
rb_cDLHandle
);
71
}
72
73
/*
74
* call-seq: DL.malloc(size)
75
*
76
* Allocate +size+ bytes of memory and return the integer memory address
77
* for the allocated memory.
78
*/
79
VALUE
80
rb_dl_malloc
(
VALUE
self
,
VALUE
size
)
81
{
82
void
*
ptr
;
83
84
ptr = (
void
*)
ruby_xmalloc
(
NUM2INT
(size));
85
return
PTR2NUM
(ptr);
86
}
87
88
/*
89
* call-seq: DL.realloc(addr, size)
90
*
91
* Change the size of the memory allocated at the memory location +addr+ to
92
* +size+ bytes. Returns the memory address of the reallocated memory, which
93
* may be different than the address passed in.
94
*/
95
VALUE
96
rb_dl_realloc
(
VALUE
self
,
VALUE
addr,
VALUE
size
)
97
{
98
void
*
ptr
=
NUM2PTR
(addr);
99
100
ptr = (
void
*)
ruby_xrealloc
(ptr,
NUM2INT
(size));
101
return
PTR2NUM
(ptr);
102
}
103
104
/*
105
* call-seq: DL.free(addr)
106
*
107
* Free the memory at address +addr+
108
*/
109
VALUE
110
rb_dl_free
(
VALUE
self
,
VALUE
addr)
111
{
112
void
*
ptr
=
NUM2PTR
(addr);
113
114
ruby_xfree
(ptr);
115
return
Qnil
;
116
}
117
118
/*
119
* call-seq: DL.dlunwrap(addr)
120
*
121
* Returns the hexadecimal representation of a memory pointer address +addr+
122
*
123
* Example:
124
*
125
* lib = DL.dlopen('/lib64/libc-2.15.so')
126
* => #<DL::Handle:0x00000001342460>
127
*
128
* lib['strcpy'].to_s(16)
129
* => "7f59de6dd240"
130
*
131
* DL.dlunwrap(DL.dlwrap(lib['strcpy'].to_s(16)))
132
* => "7f59de6dd240"
133
*/
134
VALUE
135
rb_dl_ptr2value
(
VALUE
self
,
VALUE
addr)
136
{
137
return
(
VALUE
)
NUM2PTR
(addr);
138
}
139
140
/*
141
* call-seq: DL.dlwrap(val)
142
*
143
* Returns a memory pointer of a function's hexadecimal address location +val+
144
*
145
* Example:
146
*
147
* lib = DL.dlopen('/lib64/libc-2.15.so')
148
* => #<DL::Handle:0x00000001342460>
149
*
150
* DL.dlwrap(lib['strcpy'].to_s(16))
151
* => 25522520
152
*/
153
VALUE
154
rb_dl_value2ptr
(
VALUE
self
,
VALUE
val)
155
{
156
return
PTR2NUM
((
void
*)val);
157
}
158
159
static
void
160
rb_dl_init_callbacks
(
VALUE
dl)
161
{
162
static
const
char
cb[] =
"dl/callback.so"
;
163
164
rb_autoload
(dl,
rb_intern_const
(
"CdeclCallbackAddrs"
), cb);
165
rb_autoload
(dl,
rb_intern_const
(
"CdeclCallbackProcs"
), cb);
166
#ifdef FUNC_STDCALL
167
rb_autoload
(dl,
rb_intern_const
(
"StdcallCallbackAddrs"
), cb);
168
rb_autoload
(dl,
rb_intern_const
(
"StdcallCallbackProcs"
), cb);
169
#endif
170
}
171
172
void
173
Init_dl
(
void
)
174
{
175
void
Init_dlhandle
(
void
);
176
void
Init_dlcfunc
(
void
);
177
void
Init_dlptr
(
void
);
178
179
rbdl_id_cdecl
=
rb_intern_const
(
"cdecl"
);
180
rbdl_id_stdcall
=
rb_intern_const
(
"stdcall"
);
181
182
/* Document-module: DL
183
*
184
* A bridge to the dlopen() or dynamic library linker function.
185
*
186
* == Example
187
*
188
* bash $> cat > sum.c <<EOF
189
* double sum(double *arry, int len)
190
* {
191
* double ret = 0;
192
* int i;
193
* for(i = 0; i < len; i++){
194
* ret = ret + arry[i];
195
* }
196
* return ret;
197
* }
198
*
199
* double split(double num)
200
* {
201
* double ret = 0;
202
* ret = num / 2;
203
* return ret;
204
* }
205
* EOF
206
* bash $> gcc -o libsum.so -shared sum.c
207
* bash $> cat > sum.rb <<EOF
208
* require 'dl'
209
* require 'dl/import'
210
*
211
* module LibSum
212
* extend DL::Importer
213
* dlload './libsum.so'
214
* extern 'double sum(double*, int)'
215
* extern 'double split(double)'
216
* end
217
*
218
* a = [2.0, 3.0, 4.0]
219
*
220
* sum = LibSum.sum(a.pack("d*"), a.count)
221
* p LibSum.split(sum)
222
* EOF
223
* bash $> ruby sum.rb
224
* 4.5
225
*
226
* WIN! :-)
227
*/
228
rb_mDL
=
rb_define_module
(
"DL"
);
229
230
/*
231
* Document-class: DL::DLError
232
*
233
* standard dynamic load exception
234
*/
235
rb_eDLError
=
rb_define_class_under
(
rb_mDL
,
"DLError"
,
rb_eStandardError
);
236
237
/*
238
* Document-class: DL::DLTypeError
239
*
240
* dynamic load incorrect type exception
241
*/
242
rb_eDLTypeError
=
rb_define_class_under
(
rb_mDL
,
"DLTypeError"
,
rb_eDLError
);
243
244
/* Document-const: MAX_CALLBACK
245
*
246
* Maximum number of callbacks
247
*/
248
rb_define_const
(
rb_mDL
,
"MAX_CALLBACK"
,
INT2NUM
(
MAX_CALLBACK
));
249
250
/* Document-const: DLSTACK_SIZE
251
*
252
* Dynamic linker stack size
253
*/
254
rb_define_const
(
rb_mDL
,
"DLSTACK_SIZE"
,
INT2NUM
(
DLSTACK_SIZE
));
255
256
rb_dl_init_callbacks
(
rb_mDL
);
257
258
/* Document-const: RTLD_GLOBAL
259
*
260
* rtld DL::Handle flag.
261
*
262
* The symbols defined by this library will be made available for symbol
263
* resolution of subsequently loaded libraries.
264
*/
265
rb_define_const
(
rb_mDL
,
"RTLD_GLOBAL"
,
INT2NUM
(RTLD_GLOBAL));
266
267
/* Document-const: RTLD_LAZY
268
*
269
* rtld DL::Handle flag.
270
*
271
* Perform lazy binding. Only resolve symbols as the code that references
272
* them is executed. If the symbol is never referenced, then it is never
273
* resolved. (Lazy binding is only performed for function references;
274
* references to variables are always immediately bound when the library
275
* is loaded.)
276
*/
277
rb_define_const
(
rb_mDL
,
"RTLD_LAZY"
,
INT2NUM
(RTLD_LAZY));
278
279
/* Document-const: RTLD_NOW
280
*
281
* rtld DL::Handle flag.
282
*
283
* If this value is specified or the environment variable LD_BIND_NOW is
284
* set to a nonempty string, all undefined symbols in the library are
285
* resolved before dlopen() returns. If this cannot be done an error is
286
* returned.
287
*/
288
rb_define_const
(
rb_mDL
,
"RTLD_NOW"
,
INT2NUM
(RTLD_NOW));
289
290
/* Document-const: TYPE_VOID
291
*
292
* DL::CFunc type - void
293
*/
294
rb_define_const
(
rb_mDL
,
"TYPE_VOID"
,
INT2NUM
(
DLTYPE_VOID
));
295
296
/* Document-const: TYPE_VOIDP
297
*
298
* DL::CFunc type - void*
299
*/
300
rb_define_const
(
rb_mDL
,
"TYPE_VOIDP"
,
INT2NUM
(
DLTYPE_VOIDP
));
301
302
/* Document-const: TYPE_CHAR
303
*
304
* DL::CFunc type - char
305
*/
306
rb_define_const
(
rb_mDL
,
"TYPE_CHAR"
,
INT2NUM
(
DLTYPE_CHAR
));
307
308
/* Document-const: TYPE_SHORT
309
*
310
* DL::CFunc type - short
311
*/
312
rb_define_const
(
rb_mDL
,
"TYPE_SHORT"
,
INT2NUM
(
DLTYPE_SHORT
));
313
314
/* Document-const: TYPE_INT
315
*
316
* DL::CFunc type - int
317
*/
318
rb_define_const
(
rb_mDL
,
"TYPE_INT"
,
INT2NUM
(
DLTYPE_INT
));
319
320
/* Document-const: TYPE_LONG
321
*
322
* DL::CFunc type - long
323
*/
324
rb_define_const
(
rb_mDL
,
"TYPE_LONG"
,
INT2NUM
(
DLTYPE_LONG
));
325
326
#if HAVE_LONG_LONG
327
/* Document-const: TYPE_LONG_LONG
328
*
329
* DL::CFunc type - long long
330
*/
331
rb_define_const
(
rb_mDL
,
"TYPE_LONG_LONG"
,
INT2NUM
(DLTYPE_LONG_LONG));
332
#endif
333
334
/* Document-const: TYPE_FLOAT
335
*
336
* DL::CFunc type - float
337
*/
338
rb_define_const
(
rb_mDL
,
"TYPE_FLOAT"
,
INT2NUM
(
DLTYPE_FLOAT
));
339
340
/* Document-const: TYPE_DOUBLE
341
*
342
* DL::CFunc type - double
343
*/
344
rb_define_const
(
rb_mDL
,
"TYPE_DOUBLE"
,
INT2NUM
(
DLTYPE_DOUBLE
));
345
346
/* Document-const: TYPE_SIZE_T
347
*
348
* DL::CFunc type - size_t
349
*/
350
rb_define_const
(
rb_mDL
,
"TYPE_SIZE_T"
,
INT2NUM
(
DLTYPE_SIZE_T
));
351
352
/* Document-const: TYPE_SSIZE_T
353
*
354
* DL::CFunc type - ssize_t
355
*/
356
rb_define_const
(
rb_mDL
,
"TYPE_SSIZE_T"
,
INT2NUM
(
DLTYPE_SSIZE_T
));
357
358
/* Document-const: TYPE_PTRDIFF_T
359
*
360
* DL::CFunc type - ptrdiff_t
361
*/
362
rb_define_const
(
rb_mDL
,
"TYPE_PTRDIFF_T"
,
INT2NUM
(
DLTYPE_PTRDIFF_T
));
363
364
/* Document-const: TYPE_INTPTR_T
365
*
366
* DL::CFunc type - intptr_t
367
*/
368
rb_define_const
(
rb_mDL
,
"TYPE_INTPTR_T"
,
INT2NUM
(
DLTYPE_INTPTR_T
));
369
370
/* Document-const: TYPE_UINTPTR_T
371
*
372
* DL::CFunc type - uintptr_t
373
*/
374
rb_define_const
(
rb_mDL
,
"TYPE_UINTPTR_T"
,
INT2NUM
(
DLTYPE_UINTPTR_T
));
375
376
/* Document-const: ALIGN_VOIDP
377
*
378
* The alignment size of a void*
379
*/
380
rb_define_const
(
rb_mDL
,
"ALIGN_VOIDP"
,
INT2NUM
(
ALIGN_VOIDP
));
381
382
/* Document-const: ALIGN_CHAR
383
*
384
* The alignment size of a char
385
*/
386
rb_define_const
(
rb_mDL
,
"ALIGN_CHAR"
,
INT2NUM
(
ALIGN_CHAR
));
387
388
/* Document-const: ALIGN_SHORT
389
*
390
* The alignment size of a short
391
*/
392
rb_define_const
(
rb_mDL
,
"ALIGN_SHORT"
,
INT2NUM
(
ALIGN_SHORT
));
393
394
/* Document-const: ALIGN_INT
395
*
396
* The alignment size of an int
397
*/
398
rb_define_const
(
rb_mDL
,
"ALIGN_INT"
,
INT2NUM
(
ALIGN_INT
));
399
400
/* Document-const: ALIGN_LONG
401
*
402
* The alignment size of a long
403
*/
404
rb_define_const
(
rb_mDL
,
"ALIGN_LONG"
,
INT2NUM
(
ALIGN_LONG
));
405
406
#if HAVE_LONG_LONG
407
/* Document-const: ALIGN_LONG_LONG
408
*
409
* The alignment size of a long long
410
*/
411
rb_define_const
(
rb_mDL
,
"ALIGN_LONG_LONG"
,
INT2NUM
(ALIGN_LONG_LONG));
412
#endif
413
414
/* Document-const: ALIGN_FLOAT
415
*
416
* The alignment size of a float
417
*/
418
rb_define_const
(
rb_mDL
,
"ALIGN_FLOAT"
,
INT2NUM
(
ALIGN_FLOAT
));
419
420
/* Document-const: ALIGN_DOUBLE
421
*
422
* The alignment size of a double
423
*/
424
rb_define_const
(
rb_mDL
,
"ALIGN_DOUBLE"
,
INT2NUM
(
ALIGN_DOUBLE
));
425
426
/* Document-const: ALIGN_SIZE_T
427
*
428
* The alignment size of a size_t
429
*/
430
rb_define_const
(
rb_mDL
,
"ALIGN_SIZE_T"
,
INT2NUM
(
ALIGN_OF
(
size_t
)));
431
432
/* Document-const: ALIGN_SSIZE_T
433
*
434
* The alignment size of a ssize_t
435
*/
436
rb_define_const
(
rb_mDL
,
"ALIGN_SSIZE_T"
,
INT2NUM
(
ALIGN_OF
(
size_t
)));
/* same as size_t */
437
438
/* Document-const: ALIGN_PTRDIFF_T
439
*
440
* The alignment size of a ptrdiff_t
441
*/
442
rb_define_const
(
rb_mDL
,
"ALIGN_PTRDIFF_T"
,
INT2NUM
(
ALIGN_OF
(ptrdiff_t)));
443
444
/* Document-const: ALIGN_INTPTR_T
445
*
446
* The alignment size of a intptr_t
447
*/
448
rb_define_const
(
rb_mDL
,
"ALIGN_INTPTR_T"
,
INT2NUM
(
ALIGN_OF
(
intptr_t
)));
449
450
/* Document-const: ALIGN_UINTPTR_T
451
*
452
* The alignment size of a uintptr_t
453
*/
454
rb_define_const
(
rb_mDL
,
"ALIGN_UINTPTR_T"
,
INT2NUM
(
ALIGN_OF
(
uintptr_t
)));
455
456
/* Document-const: SIZEOF_VOIDP
457
*
458
* size of a void*
459
*/
460
rb_define_const
(
rb_mDL
,
"SIZEOF_VOIDP"
,
INT2NUM
(
sizeof
(
void
*)));
461
462
/* Document-const: SIZEOF_CHAR
463
*
464
* size of a char
465
*/
466
rb_define_const
(
rb_mDL
,
"SIZEOF_CHAR"
,
INT2NUM
(
sizeof
(
char
)));
467
468
/* Document-const: SIZEOF_SHORT
469
*
470
* size of a short
471
*/
472
rb_define_const
(
rb_mDL
,
"SIZEOF_SHORT"
,
INT2NUM
(
sizeof
(
short
)));
473
474
/* Document-const: SIZEOF_INT
475
*
476
* size of an int
477
*/
478
rb_define_const
(
rb_mDL
,
"SIZEOF_INT"
,
INT2NUM
(
sizeof
(
int
)));
479
480
/* Document-const: SIZEOF_LONG
481
*
482
* size of a long
483
*/
484
rb_define_const
(
rb_mDL
,
"SIZEOF_LONG"
,
INT2NUM
(
sizeof
(
long
)));
485
486
#if HAVE_LONG_LONG
487
/* Document-const: SIZEOF_LONG_LONG
488
*
489
* size of a long long
490
*/
491
rb_define_const
(
rb_mDL
,
"SIZEOF_LONG_LONG"
,
INT2NUM
(
sizeof
(LONG_LONG)));
492
#endif
493
494
/* Document-const: SIZEOF_FLOAT
495
*
496
* size of a float
497
*/
498
rb_define_const
(
rb_mDL
,
"SIZEOF_FLOAT"
,
INT2NUM
(
sizeof
(
float
)));
499
500
/* Document-const: SIZEOF_DOUBLE
501
*
502
* size of a double
503
*/
504
rb_define_const
(
rb_mDL
,
"SIZEOF_DOUBLE"
,
INT2NUM
(
sizeof
(
double
)));
505
506
/* Document-const: SIZEOF_SIZE_T
507
*
508
* size of a size_t
509
*/
510
rb_define_const
(
rb_mDL
,
"SIZEOF_SIZE_T"
,
INT2NUM
(
sizeof
(
size_t
)));
511
512
/* Document-const: SIZEOF_SSIZE_T
513
*
514
* size of a ssize_t
515
*/
516
rb_define_const
(
rb_mDL
,
"SIZEOF_SSIZE_T"
,
INT2NUM
(
sizeof
(
size_t
)));
/* same as size_t */
517
518
/* Document-const: SIZEOF_PTRDIFF_T
519
*
520
* size of a ptrdiff_t
521
*/
522
rb_define_const
(
rb_mDL
,
"SIZEOF_PTRDIFF_T"
,
INT2NUM
(
sizeof
(ptrdiff_t)));
523
524
/* Document-const: SIZEOF_INTPTR_T
525
*
526
* size of a intptr_t
527
*/
528
rb_define_const
(
rb_mDL
,
"SIZEOF_INTPTR_T"
,
INT2NUM
(
sizeof
(
intptr_t
)));
529
530
/* Document-const: SIZEOF_UINTPTR_T
531
*
532
* size of a uintptr_t
533
*/
534
rb_define_const
(
rb_mDL
,
"SIZEOF_UINTPTR_T"
,
INT2NUM
(
sizeof
(
uintptr_t
)));
535
536
rb_define_module_function
(
rb_mDL
,
"dlwrap"
,
rb_dl_value2ptr
, 1);
537
rb_define_module_function
(
rb_mDL
,
"dlunwrap"
,
rb_dl_ptr2value
, 1);
538
539
rb_define_module_function
(
rb_mDL
,
"dlopen"
,
rb_dl_dlopen
, -1);
540
rb_define_module_function
(
rb_mDL
,
"malloc"
,
rb_dl_malloc
, 1);
541
rb_define_module_function
(
rb_mDL
,
"realloc"
,
rb_dl_realloc
, 2);
542
rb_define_module_function
(
rb_mDL
,
"free"
,
rb_dl_free
, 1);
543
544
/* Document-const: RUBY_FREE
545
*
546
* Address of the ruby_xfree() function
547
*/
548
rb_define_const
(
rb_mDL
,
"RUBY_FREE"
,
PTR2NUM
(
ruby_xfree
));
549
550
/* Document-const: BUILD_RUBY_PLATFORM
551
*
552
* Platform built against (i.e. "x86_64-linux", etc.)
553
*
554
* See also RUBY_PLATFORM
555
*/
556
rb_define_const
(
rb_mDL
,
"BUILD_RUBY_PLATFORM"
,
rb_str_new2
(
RUBY_PLATFORM
));
557
558
/* Document-const: BUILD_RUBY_VERSION
559
*
560
* Ruby Version built. (i.e. "1.9.3")
561
*
562
* See also RUBY_VERSION
563
*/
564
rb_define_const
(
rb_mDL
,
"BUILD_RUBY_VERSION"
,
rb_str_new2
(
RUBY_VERSION
));
565
566
Init_dlhandle
();
567
Init_dlcfunc
();
568
Init_dlptr
();
569
}
570
Generated on Mon Sep 22 2014 11:05:22 for Ruby by
1.8.2