ruby-dtrace 0.2.8 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,586 @@
1
+ /* Ruby-Dtrace
2
+ * (c) 2008 Chris Andrews <chris@nodnol.org>
3
+ */
4
+
5
+ #include "dtrace_api.h"
6
+
7
+ #include <errno.h>
8
+ #include <stdlib.h>
9
+ #include <sys/mman.h>
10
+
11
+ RUBY_EXTERN VALUE eDtraceException;
12
+
13
+ #define FUNC_SIZE 256
14
+ #define IS_ENABLED_FUNC_LEN 48
15
+
16
+ void install_insns(uint8_t *probe_insns, uint8_t *insns, int count)
17
+ {
18
+ int i,j;
19
+ uint8_t *ip;
20
+ ip = insns;
21
+ for (j = 1; j <= count; j++) {
22
+ for (i = 0; i < 4; i++) {
23
+ *ip++ = *probe_insns++;
24
+ }
25
+ }
26
+ }
27
+
28
+ /* :nodoc: */
29
+ VALUE dtraceprobe_init(VALUE self, VALUE rargc)
30
+ {
31
+ dtrace_probe_t *probe;
32
+ uint8_t *ip;
33
+ int i;
34
+ int argc = FIX2INT(rargc);
35
+ uint8_t probe_insns[FUNC_SIZE];
36
+
37
+ Data_Get_Struct(self, dtrace_probe_t, probe);
38
+
39
+ /* First initialise the is_enabled tracepoint */
40
+ uint8_t insns[FUNC_SIZE] = {
41
+ /* save %sp, -104, %sp */
42
+ 0x9d, 0xe3, 0xbf, 0x98,
43
+ /* nop */
44
+ 0x01, 0x00, 0x00, 0x00,
45
+ /* clr %o0 */
46
+ 0x90, 0x10, 0x00, 0x00,
47
+ /* ba 0x11c */
48
+ 0x10, 0x80, 0x00, 0x02,
49
+ /* st %o0, [%fp - 4] */
50
+ 0xd0, 0x27, 0xbf, 0xfc,
51
+ /* ld [%fp - 4], %l0 */
52
+ 0xe0, 0x07, 0xbf, 0xfc,
53
+ /* or %l0, %g0, %i0 */
54
+ 0xb0, 0x14, 0x00, 0x00,
55
+ /* ret */
56
+ 0x81, 0xc7, 0xe0, 0x08,
57
+ /* restore */
58
+ 0x81, 0xe8, 0x00, 0x00,
59
+
60
+ 0x00, 0x01, 0x00, 0x00,
61
+ 0x00, 0x01, 0x00, 0x00,
62
+ 0x00, 0x01, 0x00, 0x00,
63
+ };
64
+
65
+ /* Now build probe tracepoint */
66
+ switch (argc) {
67
+
68
+ case 0:
69
+ {
70
+ uint8_t probe_insns[FUNC_SIZE] = {
71
+ /* save %sp, -96, %sp */
72
+ 0x9d, 0xe3, 0xbf, 0x90,
73
+ /* nop */
74
+ 0x01, 0x00, 0x00, 0x00,
75
+ /* nop */
76
+ 0x01, 0x00, 0x00, 0x00,
77
+ /* ret */
78
+ 0x81, 0xc7, 0xe0, 0x08,
79
+ /* restore */
80
+ 0x81, 0xe8, 0x00, 0x00,
81
+ };
82
+ install_insns(probe_insns, &insns[IS_ENABLED_FUNC_LEN], 8);
83
+ }
84
+ break;
85
+
86
+ case 1:
87
+ {
88
+ uint8_t probe_insns[FUNC_SIZE] = {
89
+ /* save %sp, -96, %sp */
90
+ 0x9d, 0xe3, 0xbf, 0xa0,
91
+ /* st %i0, [%fp + 68] */
92
+ 0xf0, 0x27, 0xa0, 0x44,
93
+ /* ld [%fp + 68], %l0 */
94
+ 0xe0, 0x07, 0xa0, 0x44,
95
+ /* nop */
96
+ 0x01, 0x00, 0x00, 0x00,
97
+ /* or %l0, %g0, %o0 */
98
+ 0x90, 0x14, 0x00, 0x00,
99
+ /* ret */
100
+ 0x81, 0xc7, 0xe0, 0x08,
101
+ /* restore */
102
+ 0x81, 0xe8, 0x00, 0x00,
103
+ };
104
+ install_insns(probe_insns, &insns[IS_ENABLED_FUNC_LEN], 12);
105
+ }
106
+ break;
107
+
108
+ case 2:
109
+ {
110
+ uint8_t probe_insns[FUNC_SIZE] = {
111
+ /* save %sp, -96, %sp */
112
+ 0x9d, 0xe3, 0xbf, 0xa0,
113
+ /* st %i0, [%fp + 68] */
114
+ 0xf0, 0x27, 0xa0, 0x44,
115
+ /* st %i1, [%fp + 72] */
116
+ 0xf2, 0x27, 0xa0, 0x48 ,
117
+ /* ld [%fp + 68], %l0 */
118
+ 0xe0, 0x07, 0xa0, 0x44,
119
+ /* ld [%fp + 72], %l1 */
120
+ 0xe2, 0x07, 0xa0, 0x48,
121
+ /* or %l0, %g0, %o0 */
122
+ 0x90, 0x14, 0x00, 0x00,
123
+ /* nop */
124
+ 0x01, 0x00, 0x00, 0x00,
125
+ /* or %l1, %g0, %o1 */
126
+ 0x92, 0x14, 0x40, 0x00,
127
+ /* ret */
128
+ 0x81, 0xc7, 0xe0, 0x08,
129
+ /* restore */
130
+ 0x81, 0xe8, 0x00, 0x00,
131
+ };
132
+ install_insns(probe_insns, &insns[IS_ENABLED_FUNC_LEN], 12);
133
+ }
134
+ break;
135
+
136
+ case 3:
137
+ {
138
+ uint8_t probe_insns[FUNC_SIZE] = {
139
+ /* save %sp, -96, %sp */
140
+ 0x9d, 0xe3, 0xbf, 0xa0,
141
+ /* st %i0, [%fp + 68] */
142
+ 0xf0, 0x27, 0xa0, 0x44,
143
+ /* st %i1, [%fp + 72] */
144
+ 0xf2, 0x27, 0xa0, 0x48 ,
145
+ /* st %i2, [%fp + 76] */
146
+ 0xf4, 0x27, 0xa0, 0x4c,
147
+ /* ld [%fp + 68], %l0 */
148
+ 0xe0, 0x07, 0xa0, 0x44,
149
+ /* ld [%fp + 72], %l1 */
150
+ 0xe2, 0x07, 0xa0, 0x48,
151
+ /* ld [%fp + 76], %l2 */
152
+ 0xe4, 0x07, 0xa0, 0x4c,
153
+ /* or %l0, %g0, %o0 */
154
+ 0x90, 0x14, 0x00, 0x00,
155
+ /* or %l1, %g0, %o1 */
156
+ 0x92, 0x14, 0x40, 0x00,
157
+ /* nop */
158
+ 0x01, 0x00, 0x00, 0x00,
159
+ /* or %l2, %g0, %o2 */
160
+ 0x94, 0x14, 0x80, 0x00,
161
+ /* ret */
162
+ 0x81, 0xc7, 0xe0, 0x08,
163
+ /* restore */
164
+ 0x81, 0xe8, 0x00, 0x00,
165
+ };
166
+ install_insns(probe_insns, &insns[IS_ENABLED_FUNC_LEN], 16);
167
+ }
168
+ break;
169
+
170
+ case 4:
171
+ {
172
+ uint8_t probe_insns[FUNC_SIZE] = {
173
+ /* save %sp, -96, %sp */
174
+ 0x9d, 0xe3, 0xbf, 0xa0,
175
+ /* st %i0, [%fp + 68] */
176
+ 0xf0, 0x27, 0xa0, 0x44,
177
+ /* st %i1, [%fp + 72] */
178
+ 0xf2, 0x27, 0xa0, 0x48 ,
179
+ /* st %i2, [%fp + 76] */
180
+ 0xf4, 0x27, 0xa0, 0x4c,
181
+ /* st %i3, [%fp + 80] */
182
+ 0xf6, 0x27, 0xa0, 0x50,
183
+ /* ld [%fp + 68], %l0 */
184
+ 0xe0, 0x07, 0xa0, 0x44,
185
+ /* ld [%fp + 72], %l1 */
186
+ 0xe2, 0x07, 0xa0, 0x48,
187
+ /* ld [%fp + 76], %l2 */
188
+ 0xe4, 0x07, 0xa0, 0x4c,
189
+ /* ld [%fp + 80], %l3 */
190
+ 0xe6, 0x07, 0xa0, 0x50,
191
+ /* or %l0, %g0, %o0 */
192
+ 0x90, 0x14, 0x00, 0x00,
193
+ /* or %l1, %g0, %o1 */
194
+ 0x92, 0x14, 0x40, 0x00,
195
+ /* or %l2, %g0, %o2 */
196
+ 0x94, 0x14, 0x80, 0x00,
197
+ /* nop */
198
+ 0x01, 0x00, 0x00, 0x00,
199
+ /* or %l3, %g0, %o3 */
200
+ 0x96, 0x14, 0x00, 0x00,
201
+ /* ret */
202
+ 0x81, 0xc7, 0xe0, 0x08,
203
+ /* restore */
204
+ 0x81, 0xe8, 0x00, 0x00,
205
+ };
206
+ install_insns(probe_insns, &insns[IS_ENABLED_FUNC_LEN], 16);
207
+ }
208
+ break;
209
+
210
+ case 5:
211
+ {
212
+ uint8_t probe_insns[FUNC_SIZE] = {
213
+ /* save %sp, -96, %sp */
214
+ 0x9d, 0xe3, 0xbf, 0xa0,
215
+ /* st %i0, [%fp + 68] */
216
+ 0xf0, 0x27, 0xa0, 0x44,
217
+ /* st %i1, [%fp + 72] */
218
+ 0xf2, 0x27, 0xa0, 0x48 ,
219
+ /* st %i2, [%fp + 76] */
220
+ 0xf4, 0x27, 0xa0, 0x4c,
221
+ /* st %i3, [%fp + 80] */
222
+ 0xf6, 0x27, 0xa0, 0x50,
223
+ /* st %i4, [%fp + 84] */
224
+ 0xf8, 0x27, 0xa0, 0x54,
225
+ /* ld [%fp + 68], %l0 */
226
+ 0xe0, 0x07, 0xa0, 0x44,
227
+ /* ld [%fp + 72], %l1 */
228
+ 0xe2, 0x07, 0xa0, 0x48,
229
+ /* ld [%fp + 76], %l2 */
230
+ 0xe4, 0x07, 0xa0, 0x4c,
231
+ /* ld [%fp + 80], %l3 */
232
+ 0xe6, 0x07, 0xa0, 0x50,
233
+ /* ld [%fp + 84], %l4 */
234
+ 0xe8, 0x07, 0xa0, 0x54,
235
+ /* or %l0, %g0, %o0 */
236
+ 0x90, 0x14, 0x00, 0x00,
237
+ /* or %l1, %g0, %o1 */
238
+ 0x92, 0x14, 0x40, 0x00,
239
+ /* or %l2, %g0, %o2 */
240
+ 0x94, 0x14, 0x80, 0x00,
241
+ /* or %l3, %g0, %o3 */
242
+ 0x96, 0x14, 0xc0, 0x00,
243
+ /* nop */
244
+ 0x01, 0x00, 0x00, 0x00,
245
+ /* or %l4, %g0, %o4 */
246
+ 0x98, 0x15, 0x00, 0x00,
247
+ /* ret */
248
+ 0x81, 0xc7, 0xe0, 0x08,
249
+ /* restore */
250
+ 0x81, 0xe8, 0x00, 0x00,
251
+ };
252
+ install_insns(probe_insns, &insns[IS_ENABLED_FUNC_LEN], 20);
253
+ }
254
+ break;
255
+
256
+ case 6:
257
+ {
258
+ uint8_t probe_insns[FUNC_SIZE] = {
259
+ /* save %sp, -96, %sp */
260
+ 0x9d, 0xe3, 0xbf, 0xa0,
261
+ /* st %i0, [%fp + 68] */
262
+ 0xf0, 0x27, 0xa0, 0x44,
263
+ /* st %i1, [%fp + 72] */
264
+ 0xf2, 0x27, 0xa0, 0x48 ,
265
+ /* st %i2, [%fp + 76] */
266
+ 0xf4, 0x27, 0xa0, 0x4c,
267
+ /* st %i3, [%fp + 80] */
268
+ 0xf6, 0x27, 0xa0, 0x50,
269
+ /* st %i4, [%fp + 84] */
270
+ 0xf8, 0x27, 0xa0, 0x54,
271
+ /* st %i5, [%fp + 88] */
272
+ 0xfa, 0x27, 0xa0, 0x58,
273
+ /* ld [%fp + 68], %l0 */
274
+ 0xe0, 0x07, 0xa0, 0x44,
275
+ /* ld [%fp + 72], %l1 */
276
+ 0xe2, 0x07, 0xa0, 0x48,
277
+ /* ld [%fp + 76], %l2 */
278
+ 0xe4, 0x07, 0xa0, 0x4c,
279
+ /* ld [%fp + 80], %l3 */
280
+ 0xe6, 0x07, 0xa0, 0x50,
281
+ /* ld [%fp + 84], %l5 */
282
+ 0xea, 0x07, 0xa0, 0x54,
283
+ /* ld [%fp + 88], %l4 */
284
+ 0xe8, 0x07, 0xa0, 0x58,
285
+ /* or %l0, %g0, %o0 */
286
+ 0x90, 0x14, 0x00, 0x00,
287
+ /* or %l1, %g0, %o1 */
288
+ 0x92, 0x14, 0x40, 0x00,
289
+ /* or %l2, %g0, %o2 */
290
+ 0x94, 0x14, 0x80, 0x00,
291
+ /* or %l3, %g0, %o3 */
292
+ 0x96, 0x14, 0xc0, 0x00,
293
+ /* or %l5, %g0, %o4 */
294
+ 0x98, 0x15, 0x40, 0x00,
295
+ /* nop */
296
+ 0x01, 0x00, 0x00, 0x00,
297
+ /* or %l4, %g0, %o5 */
298
+ 0x9a, 0x15, 0x00, 0x00,
299
+ /* ret */
300
+ 0x81, 0xc7, 0xe0, 0x08,
301
+ /* restore */
302
+ 0x81, 0xe8, 0x00, 0x00,
303
+ };
304
+ install_insns(probe_insns, &insns[IS_ENABLED_FUNC_LEN], 24);
305
+ }
306
+ break;
307
+
308
+ case 7:
309
+ {
310
+ uint8_t probe_insns[FUNC_SIZE] = {
311
+ /* save %sp, -96, %sp */
312
+ 0x9d, 0xe3, 0xbf, 0xa0,
313
+ /* st %i0, [%fp + 68] */
314
+ 0xf0, 0x27, 0xa0, 0x44,
315
+ /* st %i1, [%fp + 72] */
316
+ 0xf2, 0x27, 0xa0, 0x48 ,
317
+ /* st %i2, [%fp + 76] */
318
+ 0xf4, 0x27, 0xa0, 0x4c,
319
+ /* st %i3, [%fp + 80] */
320
+ 0xf6, 0x27, 0xa0, 0x50,
321
+ /* st %i4, [%fp + 84] */
322
+ 0xf8, 0x27, 0xa0, 0x54,
323
+ /* st %i5, [%fp + 88] */
324
+ 0xfa, 0x27, 0xa0, 0x58,
325
+ /* ld [%fp + 92], %l0 */
326
+ 0xe0, 0x07, 0xa0, 0x5c,
327
+ /* st %l0, [%fp + 92] */
328
+ 0xe0, 0x27, 0xa0, 0x5c,
329
+ /* ld [%fp + 68], %l0 */
330
+ 0xe0, 0x07, 0xa0, 0x44,
331
+ /* ld [%fp + 72], %l1 */
332
+ 0xe2, 0x07, 0xa0, 0x48,
333
+ /* ld [%fp + 76], %l2 */
334
+ 0xe4, 0x07, 0xa0, 0x4c,
335
+ /* ld [%fp + 80], %l3 */
336
+ 0xe6, 0x07, 0xa0, 0x50,
337
+ /* ld [%fp + 84], %l5 */
338
+ 0xea, 0x07, 0xa0, 0x54,
339
+ /* ld [%fp + 88], %l4 */
340
+ 0xec, 0x07, 0xa0, 0x58,
341
+ /* ld [%fp + 92], %l5 */
342
+ 0xe8, 0x07, 0xa0, 0x5c,
343
+ /* or %l0, %g0, %o0 */
344
+ 0x90, 0x14, 0x00, 0x00,
345
+ /* or %l1, %g0, %o1 */
346
+ 0x92, 0x14, 0x40, 0x00,
347
+ /* or %l2, %g0, %o2 */
348
+ 0x94, 0x14, 0x80, 0x00,
349
+ /* or %l3, %g0, %o3 */
350
+ 0x96, 0x14, 0xc0, 0x00,
351
+ /* or %l5, %g0, %o4 */
352
+ 0x98, 0x15, 0x40, 0x00,
353
+ /* or %l6, %g0, %o5 */
354
+ 0x9a, 0x15, 0x80, 0x00,
355
+ /* nop */
356
+ 0x01, 0x00, 0x00, 0x00,
357
+ /* st %l4, [%sp + 92] */
358
+ 0xe8, 0x23, 0xa0, 0x5c,
359
+ /* ret */
360
+ 0x81, 0xc7, 0xe0, 0x08,
361
+ /* restore */
362
+ 0x81, 0xe8, 0x00, 0x00,
363
+ };
364
+ install_insns(probe_insns, &insns[IS_ENABLED_FUNC_LEN], 28);
365
+ }
366
+ break;
367
+
368
+ case 8:
369
+ {
370
+ uint8_t probe_insns[FUNC_SIZE] = {
371
+ /* save %sp, -96, %sp */
372
+ 0x9d, 0xe3, 0xbf, 0x98,
373
+ /* st %i0, [%fp + 68] */
374
+ 0xf0, 0x27, 0xa0, 0x44,
375
+ /* st %i1, [%fp + 72] */
376
+ 0xf2, 0x27, 0xa0, 0x48 ,
377
+ /* st %i2, [%fp + 76] */
378
+ 0xf4, 0x27, 0xa0, 0x4c,
379
+ /* st %i3, [%fp + 80] */
380
+ 0xf6, 0x27, 0xa0, 0x50,
381
+ /* st %i4, [%fp + 84] */
382
+ 0xf8, 0x27, 0xa0, 0x54,
383
+ /* st %i5, [%fp + 88] */
384
+ 0xfa, 0x27, 0xa0, 0x58,
385
+ /* ld [%fp + 92], %l0 */
386
+ 0xe0, 0x07, 0xa0, 0x5c,
387
+ /* st %l0, [%fp + 92] */
388
+ 0xe0, 0x27, 0xa0, 0x5c,
389
+ /* ld [%fp + 96], %l0 */
390
+ 0xe0, 0x07, 0xa0, 0x60,
391
+ /* st %l0, [%fp + 96] */
392
+ 0xe0, 0x27, 0xa0, 0x60,
393
+ /* ld [%fp + 68], %l0 */
394
+ 0xe0, 0x07, 0xa0, 0x44,
395
+ /* ld [%fp + 72], %l1 */
396
+ 0xe2, 0x07, 0xa0, 0x48,
397
+ /* ld [%fp + 76], %l2 */
398
+ 0xe4, 0x07, 0xa0, 0x4c,
399
+ /* ld [%fp + 80], %l3 */
400
+ 0xe6, 0x07, 0xa0, 0x50,
401
+ /* ld [%fp + 84], %l5 */
402
+ 0xea, 0x07, 0xa0, 0x54,
403
+ /* ld [%fp + 88], %l6 */
404
+ 0xec, 0x07, 0xa0, 0x58,
405
+ /* ld [%fp + 92], %l7 */
406
+ 0xee, 0x07, 0xa0, 0x5c,
407
+ /* ld [%fp + 96], %l4 */
408
+ 0xe8, 0x07, 0xa0, 0x60,
409
+ /* or %l0, %g0, %o0 */
410
+ 0x90, 0x14, 0x00, 0x00,
411
+ /* or %l1, %g0, %o1 */
412
+ 0x92, 0x14, 0x40, 0x00,
413
+ /* or %l2, %g0, %o2 */
414
+ 0x94, 0x14, 0x80, 0x00,
415
+ /* or %l3, %g0, %o3 */
416
+ 0x96, 0x14, 0xc0, 0x00,
417
+ /* or %l5, %g0, %o4 */
418
+ 0x98, 0x15, 0x40, 0x00,
419
+ /* or %l6, %g0, %o5 */
420
+ 0x9a, 0x15, 0x80, 0x00,
421
+ /* st %l7, [%sp + 92] */
422
+ 0xee, 0x23, 0xa0, 0x5c,
423
+ /* nop */
424
+ 0x01, 0x00, 0x00, 0x00,
425
+ /* st %l4, [%sp + 96] */
426
+ 0xe8, 0x23, 0xa0, 0x60,
427
+ /* ret */
428
+ 0x81, 0xc7, 0xe0, 0x08,
429
+ /* restore */
430
+ 0x81, 0xe8, 0x00, 0x00,
431
+ };
432
+ install_insns(probe_insns, &insns[IS_ENABLED_FUNC_LEN], 32);
433
+ }
434
+ break;
435
+
436
+ default:
437
+ rb_raise(eDtraceException, "probe argc max is 8");
438
+ return Qnil;
439
+ break;
440
+ }
441
+
442
+ /* allocate memory on a page boundary, for mprotect */
443
+ probe->func = (void *)memalign(PAGESIZE, FUNC_SIZE);
444
+ if (probe->func < 0) {
445
+ rb_raise(eDtraceException, "malloc failed: %s\n", strerror(errno));
446
+ return Qnil;
447
+ }
448
+
449
+ if ((mprotect((void *)probe->func, FUNC_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC)) < 0) {
450
+ rb_raise(eDtraceException, "mprotect failed: %s\n", strerror(errno));
451
+ return Qnil;
452
+ }
453
+
454
+ if ((memcpy(probe->func, insns, FUNC_SIZE)) < 0) {
455
+ rb_raise(eDtraceException, "memcpy failed: %s\n", strerror(errno));
456
+ return Qnil;
457
+ }
458
+
459
+ return self;
460
+ }
461
+
462
+ VALUE dtraceprobe_free(void *arg)
463
+ {
464
+ dtrace_probe_t *probe = (dtrace_probe_t *)arg;
465
+
466
+ if (probe) {
467
+ free(probe);
468
+ }
469
+ }
470
+
471
+ VALUE dtraceprobe_alloc(VALUE klass)
472
+ {
473
+ VALUE obj;
474
+ dtrace_probe_t *probe;
475
+
476
+ probe = ALLOC(dtrace_probe_t);
477
+ if (!probe) {
478
+ rb_raise(eDtraceException, "alloc failed");
479
+ return Qnil;
480
+ }
481
+
482
+ /* no mark function: no ruby objects hung off this struct */
483
+ obj = Data_Wrap_Struct(klass, NULL, dtraceprobe_free, probe);
484
+ return obj;
485
+ }
486
+
487
+ VALUE dtraceprobe_addr(VALUE self)
488
+ {
489
+ dtrace_probe_t *probe;
490
+
491
+ Data_Get_Struct(self, dtrace_probe_t, probe);
492
+ return INT2FIX(probe->func);
493
+ }
494
+
495
+ VALUE dtraceprobe_is_enabled(VALUE self)
496
+ {
497
+ dtrace_probe_t *probe;
498
+
499
+ Data_Get_Struct(self, dtrace_probe_t, probe);
500
+ return ((int)(*probe->func)()) ? Qtrue : Qfalse;
501
+ }
502
+
503
+ VALUE dtraceprobe_fire(int argc, VALUE *ruby_argv, VALUE self) {
504
+ dtrace_probe_t *probe;
505
+ int i;
506
+ void *argv[8]; // probe argc max for now.
507
+ void (*func)();
508
+
509
+ Data_Get_Struct(self, dtrace_probe_t, probe);
510
+
511
+ /* munge Ruby values to either char *s or ints. */
512
+ for (i = 0; i < argc; i++) {
513
+ switch (TYPE(ruby_argv[i])) {
514
+ case T_STRING:
515
+ argv[i] = (void *)RSTRING(ruby_argv[i])->ptr;
516
+ break;
517
+ case T_FIXNUM:
518
+ argv[i] = (void *)FIX2INT(ruby_argv[i]);
519
+ break;
520
+ default:
521
+ rb_raise(eDtraceException, "type of arg[%d] is not string or fixnum", i);
522
+ break;
523
+ }
524
+ }
525
+
526
+ func = (void (*)())(probe->func + IS_ENABLED_FUNC_LEN);
527
+
528
+ switch (argc) {
529
+ case 0:
530
+ (void)(*func)();
531
+ break;
532
+ case 1:
533
+ (void)(*func)(argv[0]);
534
+ break;
535
+ case 2:
536
+ (void)(*func)(argv[0], argv[1]);
537
+ break;
538
+ case 3:
539
+ (void)(*func)(argv[0], argv[1], argv[2]);
540
+ break;
541
+ case 4:
542
+ (void)(*func)(argv[0], argv[1], argv[2], argv[3]);
543
+ break;
544
+ case 5:
545
+ (void)(*func)(argv[0], argv[1], argv[2], argv[3],
546
+ argv[4]);
547
+ break;
548
+ case 6:
549
+ (void)(*func)(argv[0], argv[1], argv[2], argv[3],
550
+ argv[4], argv[5]);
551
+ break;
552
+ case 7:
553
+ (void)(*func)(argv[0], argv[1], argv[2], argv[3],
554
+ argv[4], argv[5], argv[6]);
555
+ break;
556
+ case 8:
557
+ (void)(*func)(argv[0], argv[1], argv[2], argv[3],
558
+ argv[4], argv[5], argv[6], argv[7]);
559
+ break;
560
+ default:
561
+ rb_raise(eDtraceException, "probe argc max is 8");
562
+ break;
563
+ }
564
+
565
+ return Qnil;
566
+ }
567
+
568
+ VALUE dtraceprobe_probe_offset(VALUE self, VALUE rfile, VALUE argc)
569
+ {
570
+ /*
571
+ * compute offset into stub: see dtrace_probe.c
572
+ *
573
+ * 48 bytes - length of is_enabled function
574
+ * +
575
+ * 3 instrs function entry - 12 bytes
576
+ * +
577
+ * 3 instrs per argument - 12 bytes
578
+ *
579
+ */
580
+ return INT2FIX(IS_ENABLED_FUNC_LEN + 12 + (FIX2INT(argc) * 12));
581
+ }
582
+
583
+ VALUE dtraceprobe_is_enabled_offset(VALUE self, VALUE rfile)
584
+ {
585
+ return INT2FIX(8);
586
+ }