ruby-dtrace 0.2.8 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+ }