ruby-dtrace 0.0.6 → 0.2.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. data/History.txt +21 -0
  2. data/Manifest.txt +86 -19
  3. data/README.txt +48 -6
  4. data/Rakefile +61 -20
  5. data/examples/scsi.rb +1 -1
  6. data/ext/dof/Makefile +154 -0
  7. data/ext/dof/constants.c +57 -0
  8. data/ext/dof/dof.h +56 -0
  9. data/ext/dof/dof_api.c +58 -0
  10. data/ext/dof/dof_helper.c +82 -0
  11. data/ext/dof/extconf.rb +4 -0
  12. data/ext/dof/file.c +90 -0
  13. data/ext/dof/generator.c +9 -0
  14. data/ext/dof/header.c +79 -0
  15. data/ext/dof/mkmf.log +10 -0
  16. data/ext/dof/parser.c +415 -0
  17. data/ext/dof/parser.h +10 -0
  18. data/ext/dof/section.c +312 -0
  19. data/ext/dtrace_aggdata.c +2 -2
  20. data/ext/dtrace_api.c +46 -34
  21. data/ext/dtrace_api.h +31 -7
  22. data/ext/dtrace_bufdata.c +3 -3
  23. data/ext/dtrace_hdl.c +66 -3
  24. data/ext/dtrace_probedata.c +4 -4
  25. data/ext/{dtrace_probe.c → dtrace_probedesc.c} +7 -7
  26. data/ext/extconf.rb +25 -0
  27. data/ext/i386-darwin/dtrace_probe.c +278 -0
  28. data/ext/i386-solaris/dtrace_probe.c +225 -0
  29. data/ext/stubs.txt +78 -0
  30. data/lib/dtrace.rb +34 -13
  31. data/lib/dtrace/aggregate.rb +40 -0
  32. data/lib/dtrace/aggregateset.rb +19 -0
  33. data/lib/dtrace/consumer.rb +174 -0
  34. data/lib/dtrace/data.rb +82 -0
  35. data/lib/dtrace/dof.rb +8 -0
  36. data/lib/dtrace/dof/file.rb +64 -0
  37. data/lib/dtrace/dof/section.rb +75 -0
  38. data/lib/dtrace/dof/section/strtab.rb +28 -0
  39. data/lib/{dtraceprintfrecord.rb → dtrace/printfrecord.rb} +4 -2
  40. data/lib/dtrace/probe.rb +3 -6
  41. data/lib/dtrace/probedata.rb +23 -0
  42. data/lib/dtrace/probedesc.rb +15 -0
  43. data/lib/dtrace/provider.rb +190 -169
  44. data/lib/dtrace/provider/klass.rb +33 -0
  45. data/lib/dtrace/provider/probedef.rb +24 -0
  46. data/lib/{dtracerecord.rb → dtrace/record.rb} +4 -2
  47. data/lib/{dtracestackrecord.rb → dtrace/stackrecord.rb} +10 -8
  48. data/lib/dtrace/version.rb +9 -0
  49. data/lib/dtraceconsumer.rb +3 -167
  50. data/plugin/dtrace/lib/dtracer.rb +4 -4
  51. data/test/apple-dof +0 -0
  52. data/test/disabled_probe_effect.txt +19 -0
  53. data/test/dof +0 -0
  54. data/test/dof2 +0 -0
  55. data/test/test_disabled_probe_effect.rb +56 -0
  56. data/test/test_dof_generator.rb +142 -0
  57. data/test/test_dof_helper.rb +106 -0
  58. data/test/test_dof_parser.rb +27 -0
  59. data/test/test_dof_providers.rb +278 -0
  60. data/test/test_dof_strtabs.rb +98 -0
  61. data/test/test_dtrace.rb +67 -1
  62. data/test/test_dtrace_aggregates.rb +5 -5
  63. data/test/test_dtrace_drops_errors.rb +5 -5
  64. data/test/test_dtrace_probe.rb +385 -0
  65. data/test/test_dtrace_probes.rb +414 -0
  66. data/test/test_dtrace_processes.rb +2 -2
  67. data/test/test_dtrace_profile.rb +12 -12
  68. data/test/test_dtrace_provider.rb +138 -0
  69. data/test/test_dtrace_repeat.rb +1 -1
  70. data/test/test_dtrace_rubyprobe.rb +3 -1
  71. data/test/test_dtrace_typefilter.rb +9 -9
  72. data/test/test_legacy_consumer.rb +56 -0
  73. metadata +112 -71
  74. data/lib/dtrace/provider/osx.rb +0 -25
  75. data/lib/dtrace/provider/solaris.rb +0 -29
  76. data/lib/dtraceaggregate.rb +0 -37
  77. data/lib/dtraceaggregateset.rb +0 -17
  78. data/lib/dtracedata.rb +0 -80
  79. data/lib/dtraceprobe.rb +0 -13
  80. data/lib/dtraceprobedata.rb +0 -21
  81. data/test/test_dynusdt.rb +0 -135
@@ -0,0 +1,415 @@
1
+ /*
2
+ * Ruby-Dtrace
3
+ * (c) 2008 Chris Andrews <chris@nodnol.org>
4
+ */
5
+
6
+ #include "dof.h"
7
+
8
+ RUBY_EXTERN eDtraceDofException;
9
+
10
+ static void
11
+ rubydump(void *data, int len)
12
+ {
13
+ VALUE str;
14
+ VALUE dumped;
15
+ char *out;
16
+
17
+ str = rb_str_new(data, len);
18
+ dumped = rb_funcall(str, rb_intern("inspect"), 0);
19
+ out = STR2CSTR(dumped);
20
+
21
+ fprintf(stderr, "%s\n", out);
22
+ }
23
+
24
+ static void
25
+ rubyinspect(VALUE data)
26
+ {
27
+ VALUE dumped;
28
+ char *out;
29
+
30
+ dumped = rb_funcall(data, rb_intern("inspect"), 0);
31
+ out = STR2CSTR(dumped);
32
+
33
+ fprintf(stderr, "%s\n", out);
34
+ }
35
+
36
+ static const char *
37
+ _dof_sec_type(uint32_t type)
38
+ {
39
+ switch(type) {
40
+ case DOF_SECT_NONE:
41
+ return "null section";
42
+ case DOF_SECT_COMMENTS:
43
+ return "compiler comments";
44
+ case DOF_SECT_SOURCE:
45
+ return "D program source code";
46
+ case DOF_SECT_ECBDESC:
47
+ return "dof_ecbdesc_t";
48
+ case DOF_SECT_PROBEDESC:
49
+ return "dof_probedesc_t";
50
+ case DOF_SECT_ACTDESC:
51
+ return "dof_actdesc_t array";
52
+ case DOF_SECT_DIFOHDR:
53
+ return "dof_difohdr_t (variable length)";
54
+ case DOF_SECT_DIF:
55
+ return "uint32_t array of byte code";
56
+ case DOF_SECT_STRTAB:
57
+ return "string table";
58
+ case DOF_SECT_VARTAB:
59
+ return "dtrace_difv_t array";
60
+ case DOF_SECT_RELTAB:
61
+ return "dof_relodesc_t array";
62
+ case DOF_SECT_TYPTAB:
63
+ return "dtrace_diftype_t array";
64
+ case DOF_SECT_URELHDR:
65
+ return "dof_relohdr_t (user relocations)";
66
+ case DOF_SECT_KRELHDR:
67
+ return "dof_relohdr_t (kernel relocations)";
68
+ case DOF_SECT_OPTDESC:
69
+ return "dof_optdesc_t array";
70
+ case DOF_SECT_PROVIDER:
71
+ return "dof_provider_t";
72
+ case DOF_SECT_PROBES:
73
+ return "dof_probe_t array";
74
+ case DOF_SECT_PRARGS:
75
+ return "uint8_t array (probe arg mappings)";
76
+ case DOF_SECT_PROFFS:
77
+ return "uint32_t array (probe arg offsets)";
78
+ case DOF_SECT_INTTAB:
79
+ return "uint64_t array";
80
+ case DOF_SECT_UTSNAME:
81
+ return "struct utsname";
82
+ case DOF_SECT_XLTAB:
83
+ return "dof_xlref_t array";
84
+ case DOF_SECT_XLMEMBERS:
85
+ return "dof_xlmember_t array";
86
+ case DOF_SECT_XLIMPORT:
87
+ return "dof_xlator_t";
88
+ case DOF_SECT_XLEXPORT:
89
+ return "dof_xlator_t";
90
+ case DOF_SECT_PREXPORT:
91
+ return "dof_secidx_t array (exported objs)";
92
+ case DOF_SECT_PRENOFFS:
93
+ return "uint32_t array (enabled offsets)";
94
+ default:
95
+ return "unknown section type";
96
+ }
97
+ }
98
+
99
+ static VALUE
100
+ _dof_parse_string_table(VALUE self, char *dof, dof_sec_t *sec)
101
+ {
102
+ char *data = (char *)(dof + sec->dofs_offset);
103
+
104
+ VALUE strtab = rb_hash_new();
105
+ VALUE ctx = rb_cv_get(self, "@@ctx");
106
+ int i, bool = 0;
107
+
108
+ for (i = 0; i < sec->dofs_size - 1; ++i) {
109
+ if (*data) {
110
+ if (bool)
111
+ rb_hash_aset(strtab, INT2FIX(i), rb_str_new2(data));
112
+ bool = 0;
113
+ }
114
+ else if (!bool) {
115
+ bool = 1;
116
+ }
117
+ ++data;
118
+ }
119
+
120
+ rb_hash_aset(ctx, ID2SYM(rb_intern("strtab")), strtab);
121
+ return strtab;
122
+ }
123
+
124
+ static VALUE
125
+ _dof_parse_dof_probe_t_array(VALUE self, char *dof, dof_sec_t *sec)
126
+ {
127
+ dof_probe_t probe;
128
+ char *data = (char *)(dof + sec->dofs_offset);
129
+ VALUE probes = rb_ary_new();
130
+ VALUE ctx = rb_cv_get(self, "@@ctx");
131
+ VALUE strtab;
132
+ VALUE probe_data;
133
+ char addr_str[18]; // XXX length of pointer as string?
134
+ int count = 0;
135
+ int offset = 0;
136
+
137
+ strtab = rb_hash_aref(ctx, ID2SYM(rb_intern("strtab")));
138
+ if (NIL_P(strtab)) {
139
+ rb_raise(eDtraceDofException, "no string table available while parsing probe_t array");
140
+ return Qnil;
141
+ }
142
+
143
+ while (offset < sec->dofs_size) {
144
+ memcpy(&probe, dof + sec->dofs_offset + offset, sizeof(probe));
145
+ count++;
146
+
147
+ probe_data = rb_hash_new();
148
+ sprintf(addr_str, "%p", probe.dofpr_addr);
149
+ rb_hash_aset(probe_data, ID2SYM(rb_intern("addr")), rb_str_new2(addr_str));
150
+ rb_hash_aset(probe_data, ID2SYM(rb_intern("func")), rb_hash_aref(strtab, INT2FIX(probe.dofpr_func)));
151
+ rb_hash_aset(probe_data, ID2SYM(rb_intern("name")), rb_hash_aref(strtab, INT2FIX(probe.dofpr_name)));
152
+ rb_hash_aset(probe_data, ID2SYM(rb_intern("nargv")), rb_hash_aref(strtab, INT2FIX(probe.dofpr_nargv)));
153
+ rb_hash_aset(probe_data, ID2SYM(rb_intern("xargv")), rb_hash_aref(strtab, INT2FIX(probe.dofpr_xargv)));
154
+
155
+ rb_hash_aset(probe_data, ID2SYM(rb_intern("argidx")), INT2FIX(probe.dofpr_argidx));
156
+ rb_hash_aset(probe_data, ID2SYM(rb_intern("offidx")), INT2FIX(probe.dofpr_offidx));
157
+ rb_hash_aset(probe_data, ID2SYM(rb_intern("nargc")), INT2FIX(probe.dofpr_nargc));
158
+ rb_hash_aset(probe_data, ID2SYM(rb_intern("xargc")), INT2FIX(probe.dofpr_xargc));
159
+ rb_hash_aset(probe_data, ID2SYM(rb_intern("noffs")), INT2FIX(probe.dofpr_noffs));
160
+ rb_hash_aset(probe_data, ID2SYM(rb_intern("enoffidx")), INT2FIX(probe.dofpr_enoffidx));
161
+ rb_hash_aset(probe_data, ID2SYM(rb_intern("nenoffs")), INT2FIX(probe.dofpr_nenoffs));
162
+
163
+ rb_ary_push(probes, probe_data);
164
+ offset += sizeof(probe);
165
+ }
166
+
167
+ return probes;
168
+ }
169
+
170
+ static VALUE
171
+ _dof_parse_dof_relodesc_t_array(VALUE self, char *dof, dof_sec_t *sec)
172
+ {
173
+ dof_relodesc_t relodesc;
174
+ char *data = (char *)(dof + sec->dofs_offset);
175
+ VALUE relodescs = rb_ary_new();
176
+ VALUE ctx = rb_cv_get(self, "@@ctx");
177
+ VALUE strtab = rb_hash_aref(ctx, ID2SYM(rb_intern("strtab")));
178
+ VALUE relodesc_data;
179
+ int count = 0;
180
+ int offset = 0;
181
+
182
+ while (offset < sec->dofs_size) {
183
+ memcpy(&relodesc, dof + sec->dofs_offset + offset, sizeof(relodesc));
184
+ count++;
185
+
186
+ relodesc_data = rb_hash_new();
187
+ rb_hash_aset(relodesc_data, ID2SYM(rb_intern("name")), rb_hash_aref(strtab, INT2FIX(relodesc.dofr_name)));
188
+
189
+ switch(relodesc.dofr_type) {
190
+ case DOF_RELO_NONE:
191
+ rb_hash_aset(relodesc_data, ID2SYM(rb_intern("type")), rb_str_new2("none"));
192
+ break;
193
+ case DOF_RELO_SETX:
194
+ rb_hash_aset(relodesc_data, ID2SYM(rb_intern("type")), rb_str_new2("setx"));
195
+ break;
196
+ default:
197
+ rb_hash_aset(relodesc_data, ID2SYM(rb_intern("type")), rb_str_new2("unknown"));
198
+ break;
199
+ }
200
+
201
+ rb_hash_aset(relodesc_data, ID2SYM(rb_intern("offset")), INT2FIX(relodesc.dofr_offset));
202
+ rb_hash_aset(relodesc_data, ID2SYM(rb_intern("data")), INT2FIX(relodesc.dofr_data));
203
+
204
+ rb_ary_push(relodescs, relodesc_data);
205
+ offset += sizeof(relodesc);
206
+ }
207
+
208
+ return relodescs;
209
+ }
210
+
211
+ static VALUE
212
+ _dof_parse_dof_relohdr_t(VALUE self, char *dof, dof_sec_t *sec)
213
+ {
214
+ dof_relohdr_t relohdr;
215
+ char *data = (char *)(dof + sec->dofs_offset);
216
+ VALUE relohdr_data = rb_hash_new();
217
+
218
+ memcpy(&relohdr, dof + sec->dofs_offset, sizeof(relohdr));
219
+ rb_hash_aset(relohdr_data, ID2SYM(rb_intern("strtab")), INT2FIX(relohdr.dofr_strtab));
220
+ rb_hash_aset(relohdr_data, ID2SYM(rb_intern("relsec")), INT2FIX(relohdr.dofr_relsec));
221
+ rb_hash_aset(relohdr_data, ID2SYM(rb_intern("tgtsec")), INT2FIX(relohdr.dofr_tgtsec));
222
+
223
+ return relohdr_data;
224
+ }
225
+
226
+ static VALUE
227
+ _dof_parse_dof_attr_t(dof_attr_t attr)
228
+ {
229
+ VALUE attr_data = rb_hash_new();
230
+
231
+ rb_hash_aset(attr_data, ID2SYM(rb_intern("name")), INT2FIX(DOF_ATTR_NAME(attr)));
232
+ rb_hash_aset(attr_data, ID2SYM(rb_intern("data")), INT2FIX(DOF_ATTR_DATA(attr)));
233
+ rb_hash_aset(attr_data, ID2SYM(rb_intern("class")), INT2FIX(DOF_ATTR_CLASS(attr)));
234
+
235
+ return attr_data;
236
+ }
237
+
238
+ static VALUE
239
+ _dof_parse_dof_provider_t(VALUE self, char *dof, dof_sec_t *sec)
240
+ {
241
+ dof_provider_t provider;
242
+ char *data = (char *)(dof + sec->dofs_offset);
243
+ VALUE provider_data = rb_hash_new();
244
+ VALUE ctx = rb_cv_get(self, "@@ctx");
245
+ VALUE strtab = rb_hash_aref(ctx, ID2SYM(rb_intern("strtab")));
246
+
247
+ memcpy(&provider, dof + sec->dofs_offset, sizeof(provider));
248
+ rb_hash_aset(provider_data, ID2SYM(rb_intern("name")), rb_hash_aref(strtab, INT2FIX(provider.dofpv_name)));
249
+ rb_hash_aset(provider_data, ID2SYM(rb_intern("strtab")), INT2FIX(provider.dofpv_strtab));
250
+ rb_hash_aset(provider_data, ID2SYM(rb_intern("probes")), INT2FIX(provider.dofpv_probes));
251
+ rb_hash_aset(provider_data, ID2SYM(rb_intern("prargs")), INT2FIX(provider.dofpv_prargs));
252
+ rb_hash_aset(provider_data, ID2SYM(rb_intern("proffs")), INT2FIX(provider.dofpv_proffs));
253
+
254
+ rb_hash_aset(provider_data, ID2SYM(rb_intern("provattr")), _dof_parse_dof_attr_t(provider.dofpv_provattr));
255
+ rb_hash_aset(provider_data, ID2SYM(rb_intern("modattr")), _dof_parse_dof_attr_t(provider.dofpv_modattr));
256
+ rb_hash_aset(provider_data, ID2SYM(rb_intern("funcattr")), _dof_parse_dof_attr_t(provider.dofpv_funcattr));
257
+ rb_hash_aset(provider_data, ID2SYM(rb_intern("nameattr")), _dof_parse_dof_attr_t(provider.dofpv_nameattr));
258
+ rb_hash_aset(provider_data, ID2SYM(rb_intern("argsattr")), _dof_parse_dof_attr_t(provider.dofpv_argsattr));
259
+
260
+ return provider_data;
261
+ }
262
+
263
+ static VALUE
264
+ _dof_parse_uint8_t_array(VALUE self, char *dof, dof_sec_t *sec)
265
+ {
266
+ VALUE ary_data = rb_ary_new();
267
+ char *data = (char *)(dof + sec->dofs_offset);
268
+ int len = sec->dofs_size / sizeof(uint8_t);
269
+ uint8_t array[len];
270
+ int i;
271
+
272
+ memcpy(&array, data, len * sizeof(uint8_t));
273
+ for (i = 0; i < len; i++) {
274
+ rb_ary_push(ary_data, INT2FIX(array[i]));
275
+ }
276
+
277
+ return ary_data;
278
+ }
279
+
280
+ static VALUE
281
+ _dof_parse_uint32_t_array(VALUE self, char *dof, dof_sec_t *sec)
282
+ {
283
+ VALUE ary_data = rb_ary_new();
284
+ char *data = (char *)(dof + sec->dofs_offset);
285
+ int len = sec->dofs_size / sizeof(uint32_t);
286
+ uint32_t array[len];
287
+ int i;
288
+
289
+ memcpy(&array, data, len * sizeof(uint32_t));
290
+ for (i = 0; i < len; i++) {
291
+ rb_ary_push(ary_data, INT2FIX((unsigned int)array[i]));
292
+ }
293
+
294
+ return ary_data;
295
+ }
296
+
297
+ static VALUE
298
+ _dof_parse_comments(VALUE self, char *dof, dof_sec_t *sec)
299
+ {
300
+ char comment[sec->dofs_size + 1];
301
+ char *data = (char *)(dof + sec->dofs_offset);
302
+
303
+ strncpy(comment, data, sec->dofs_size);
304
+ return rb_str_new2(comment);
305
+ }
306
+
307
+ static VALUE
308
+ _dof_parse_utsname(VALUE self, char *dof, dof_sec_t *sec)
309
+ {
310
+ struct utsname uts;
311
+ VALUE uts_data = rb_hash_new();
312
+ char *data = (char *)(dof + sec->dofs_offset);
313
+
314
+ memcpy(&uts, data, sizeof(uts));
315
+
316
+ rb_hash_aset(uts_data, ID2SYM(rb_intern("sysname")), rb_str_new2(uts.sysname));
317
+ rb_hash_aset(uts_data, ID2SYM(rb_intern("nodename")), rb_str_new2(uts.nodename));
318
+ rb_hash_aset(uts_data, ID2SYM(rb_intern("release")), rb_str_new2(uts.release));
319
+ rb_hash_aset(uts_data, ID2SYM(rb_intern("version")), rb_str_new2(uts.version));
320
+ rb_hash_aset(uts_data, ID2SYM(rb_intern("machine")), rb_str_new2(uts.machine));
321
+
322
+ return uts_data;
323
+ }
324
+
325
+ static VALUE
326
+ _dof_parse_unknown(VALUE self, char *dof, dof_sec_t *sec)
327
+ {
328
+ VALUE section_data = rb_hash_new();
329
+ return section_data;
330
+ }
331
+
332
+ /* Parse the given DOF */
333
+ VALUE dof_parse(VALUE self, VALUE rdof)
334
+ {
335
+ VALUE dof_data;
336
+ VALUE sec_data;
337
+ VALUE ctx;
338
+ VALUE sec;
339
+ char *dof;
340
+ char *pos;
341
+ dof_hdr_t dof_hdr;
342
+ dof_sec_t dof_sec;
343
+ int i;
344
+
345
+ ctx = rb_hash_new();
346
+ rb_cv_set(self, "@@ctx", ctx);
347
+
348
+ dof = STR2CSTR(rdof);
349
+ pos = dof;
350
+ memcpy(&dof_hdr, pos, sizeof(dof_hdr));
351
+
352
+ /* Check magic */
353
+ if (!(dof_hdr.dofh_ident[0] == DOF_MAG_MAG0 &&
354
+ dof_hdr.dofh_ident[1] == DOF_MAG_MAG1 &&
355
+ dof_hdr.dofh_ident[2] == DOF_MAG_MAG2 &&
356
+ dof_hdr.dofh_ident[3] == DOF_MAG_MAG3)) {
357
+ rb_raise(eDtraceDofException, "bad DOF header magic");
358
+ return Qnil;
359
+ }
360
+ pos += dof_hdr.dofh_hdrsize;
361
+
362
+ dof_data = rb_ary_new();
363
+
364
+ /* Walk section headers, parsing sections */
365
+ for (i = 0; i < dof_hdr.dofh_secnum; i++) {
366
+ memcpy(&dof_sec, pos, sizeof(struct dof_sec));
367
+
368
+ sec_data = rb_hash_new();
369
+ rb_hash_aset(sec_data, ID2SYM(rb_intern("index")), INT2FIX(i));
370
+ rb_hash_aset(sec_data, ID2SYM(rb_intern("type")), rb_str_new2(_dof_sec_type(dof_sec.dofs_type)));
371
+ rb_hash_aset(sec_data, ID2SYM(rb_intern("flags")), INT2FIX(dof_sec.dofs_flags));
372
+
373
+ sec = Qnil;
374
+ switch(dof_sec.dofs_type) {
375
+ case DOF_SECT_STRTAB:
376
+ sec = _dof_parse_string_table(self, dof, &dof_sec);
377
+ break;
378
+ case DOF_SECT_PROBES:
379
+ sec = _dof_parse_dof_probe_t_array(self, dof, &dof_sec);
380
+ break;
381
+ case DOF_SECT_PROVIDER:
382
+ sec = _dof_parse_dof_provider_t(self, dof, &dof_sec);
383
+ break;
384
+ case DOF_SECT_PRARGS:
385
+ sec = _dof_parse_uint8_t_array(self, dof, &dof_sec);
386
+ break;
387
+ case DOF_SECT_PRENOFFS:
388
+ case DOF_SECT_PROFFS:
389
+ sec = _dof_parse_uint32_t_array(self, dof, &dof_sec);
390
+ break;
391
+ case DOF_SECT_RELTAB:
392
+ sec = _dof_parse_dof_relodesc_t_array(self, dof, &dof_sec);
393
+ break;
394
+ case DOF_SECT_URELHDR:
395
+ sec = _dof_parse_dof_relohdr_t(self, dof, &dof_sec);
396
+ break;
397
+ case DOF_SECT_UTSNAME:
398
+ sec = _dof_parse_utsname(self, dof, &dof_sec);
399
+ break;
400
+ case DOF_SECT_COMMENTS:
401
+ sec = _dof_parse_comments(self, dof, &dof_sec);
402
+ break;
403
+ default:
404
+ sec = _dof_parse_unknown(self, dof, &dof_sec);
405
+ break;
406
+ }
407
+ rb_hash_aset(sec_data, ID2SYM(rb_intern("data")), sec);
408
+
409
+ rb_ary_push(dof_data, sec_data);
410
+ pos += dof_hdr.dofh_secsize;
411
+ }
412
+
413
+ return dof_data;
414
+ }
415
+
@@ -0,0 +1,10 @@
1
+ /*
2
+ * Ruby-Dtrace
3
+ * (c) 2008 Chris Andrews <chris@nodnol.org>
4
+ */
5
+
6
+ #include <ruby.h>
7
+ #include <sys/dtrace.h>
8
+ #include <sys/utsname.h>
9
+
10
+ static VALUE dof_parse(VALUE self, VALUE dof);
@@ -0,0 +1,312 @@
1
+ /*
2
+ * Ruby-Dtrace
3
+ * (c) 2008 Chris Andrews <chris@nodnol.org>
4
+ */
5
+
6
+ #include "dof.h"
7
+ #include <errno.h>
8
+ #include <string.h>
9
+
10
+ RUBY_EXTERN eDtraceDofException;
11
+
12
+ /* :nodoc: */
13
+ VALUE dof_generate_section_header(VALUE self) {
14
+ VALUE hdr_data;
15
+ dof_sec_t hdr;
16
+ uint32_t type;
17
+ uint64_t offset;
18
+ uint64_t size;
19
+ uint32_t entsize;
20
+
21
+ memset(&hdr, 0, sizeof(hdr));
22
+ hdr.dofs_flags = FIX2INT(rb_iv_get(self, "@flags"));
23
+ hdr.dofs_type = FIX2INT(rb_iv_get(self, "@section_type"));
24
+ hdr.dofs_offset = FIX2INT(rb_iv_get(self, "@offset"));
25
+ hdr.dofs_size = FIX2INT(rb_iv_get(self, "@size"));
26
+ hdr.dofs_entsize = FIX2INT(rb_iv_get(self, "@entsize"));
27
+ hdr.dofs_align = FIX2INT(rb_iv_get(self, "@align"));
28
+
29
+ hdr_data = rb_str_new((const char *)&hdr, sizeof(hdr));
30
+ return hdr_data;
31
+ }
32
+
33
+ /* :nodoc: */
34
+ VALUE dof_generate_comments(VALUE self) {
35
+ VALUE dof;
36
+ VALUE comments = rb_iv_get(self, "@data");
37
+
38
+ if (NIL_P(comments) ) {
39
+ rb_raise(eDtraceDofException, "no comments in dof_generate_comments");
40
+ return Qnil;
41
+ }
42
+
43
+ Check_Type(comments, T_STRING);
44
+
45
+ dof = rb_str_new(RSTRING(comments)->ptr, RSTRING(comments)->len + 1);
46
+ return dof;
47
+ }
48
+
49
+ /* :nodoc: */
50
+ VALUE dof_generate_probes(VALUE self) {
51
+ VALUE dof;
52
+ VALUE probes = rb_iv_get(self, "@data");
53
+ VALUE probe;
54
+ int i;
55
+
56
+ if (NIL_P(probes) ) {
57
+ rb_raise(eDtraceDofException, "no probes in dof_generate_probes");
58
+ return Qnil;
59
+ }
60
+ Check_Type(probes, T_ARRAY);
61
+
62
+ dof = rb_str_new2("");
63
+
64
+ for (i = 0; i < rb_ary_len(probes); i++) {
65
+ probe = rb_ary_entry(probes, i);
66
+
67
+ Check_Type(probe, T_HASH);
68
+
69
+ dof_probe_t p;
70
+ memset(&p, 0, sizeof(p));
71
+
72
+ p.dofpr_addr = (uint64_t)FIX2INT(rb_hash_aref(probe, ID2SYM(rb_intern("addr"))));
73
+ p.dofpr_func = (dof_stridx_t)FIX2INT(rb_hash_aref(probe, ID2SYM(rb_intern("func"))));
74
+ p.dofpr_name = (dof_stridx_t)FIX2INT(rb_hash_aref(probe, ID2SYM(rb_intern("name"))));
75
+ p.dofpr_nargv = (dof_stridx_t)FIX2INT(rb_hash_aref(probe, ID2SYM(rb_intern("nargv"))));
76
+ p.dofpr_xargv = (dof_stridx_t)FIX2INT(rb_hash_aref(probe, ID2SYM(rb_intern("xargv"))));
77
+
78
+ p.dofpr_argidx = (uint32_t)FIX2INT(rb_hash_aref(probe, ID2SYM(rb_intern("argidx"))));
79
+ p.dofpr_offidx = (uint32_t)FIX2INT(rb_hash_aref(probe, ID2SYM(rb_intern("offidx"))));
80
+ p.dofpr_nargc = (uint8_t)FIX2INT(rb_hash_aref(probe, ID2SYM(rb_intern("nargc"))));
81
+ p.dofpr_xargc = (uint8_t)FIX2INT(rb_hash_aref(probe, ID2SYM(rb_intern("xargc"))));
82
+ p.dofpr_noffs = (uint16_t)FIX2INT(rb_hash_aref(probe, ID2SYM(rb_intern("noffs"))));
83
+ p.dofpr_enoffidx = (uint32_t)FIX2INT(rb_hash_aref(probe, ID2SYM(rb_intern("enoffidx"))));
84
+ p.dofpr_nenoffs = (uint16_t)FIX2INT(rb_hash_aref(probe, ID2SYM(rb_intern("nenoffs"))));
85
+
86
+ VALUE p_dof = rb_str_new((const char *)&p, sizeof(p));
87
+ rb_str_concat(dof, p_dof);
88
+ }
89
+
90
+ return dof;
91
+ }
92
+
93
+ /* :nodoc: */
94
+ VALUE dof_generate_strtab(VALUE self) {
95
+ VALUE dof;
96
+ VALUE strings = rb_iv_get(self, "@data");
97
+ VALUE string;
98
+ int i;
99
+
100
+ if (NIL_P(strings) ) {
101
+ rb_raise(eDtraceDofException, "no strings in dof_generate_strtab");
102
+ return Qnil;
103
+ }
104
+ Check_Type(strings, T_ARRAY);
105
+
106
+ dof = rb_str_new("", 0);
107
+ rb_str_concat(dof, rb_str_new("\0", 1));
108
+
109
+ for (i = 0; i < rb_ary_len(strings); i++) {
110
+ string = rb_ary_entry(strings, i);
111
+
112
+ Check_Type(string, T_STRING);
113
+
114
+ rb_str_concat(dof, rb_str_new(RSTRING(string)->ptr, RSTRING(string)->len + 1));
115
+ }
116
+
117
+ return dof;
118
+ }
119
+
120
+ /* :nodoc: */
121
+ VALUE dof_generate_utsname(VALUE self) {
122
+ VALUE dof;
123
+ struct utsname u;
124
+
125
+ if (uname(&u) < 0) {
126
+ rb_raise(eDtraceDofException, "uname failed: %s", strerror(errno));
127
+ return Qnil;
128
+ }
129
+
130
+ dof = rb_str_new((const char *)&u, sizeof(struct utsname));
131
+ return dof;
132
+ }
133
+
134
+ /* :nodoc: */
135
+ VALUE dof_generate_prargs(VALUE self) {
136
+ VALUE dof;
137
+ VALUE args = rb_iv_get(self, "@data");
138
+ VALUE rarg;
139
+ uint8_t arg;
140
+ int i;
141
+
142
+ if (NIL_P(args) ) {
143
+ rb_raise(eDtraceDofException, "no args in dof_generate_prargs");
144
+ return Qnil;
145
+ }
146
+ Check_Type(args, T_ARRAY);
147
+
148
+ dof = rb_str_new("", 0);
149
+
150
+ for (i = 0; i < rb_ary_len(args); i++) {
151
+ rarg = rb_ary_entry(args, i);
152
+ Check_Type(rarg, T_FIXNUM);
153
+ if (FIX2INT(rarg) >= 0 && FIX2INT(rarg) < 256) {
154
+ arg = FIX2INT(rarg);
155
+ rb_str_concat(dof, rb_str_new((char *)&arg, 1));
156
+ }
157
+ }
158
+
159
+ return dof;
160
+ }
161
+
162
+ /* :nodoc: */
163
+ VALUE dof_generate_proffs(VALUE self) {
164
+ VALUE dof;
165
+ VALUE args = rb_iv_get(self, "@data");
166
+ VALUE rarg;
167
+ uint32_t arg;
168
+ int i;
169
+
170
+ if (NIL_P(args) ) {
171
+ rb_raise(eDtraceDofException, "no args in dof_generate_proffs");
172
+ return Qnil;
173
+ }
174
+ Check_Type(args, T_ARRAY);
175
+
176
+ dof = rb_str_new("", 0);
177
+
178
+ for (i = 0; i < rb_ary_len(args); i++) {
179
+ rarg = rb_ary_entry(args, i);
180
+ Check_Type(rarg, T_FIXNUM);
181
+ arg = FIX2INT(rarg);
182
+ rb_str_concat(dof, rb_str_new((char *)&arg, 4));
183
+ }
184
+
185
+ return dof;
186
+ }
187
+
188
+ /* :nodoc: */
189
+ VALUE dof_generate_prenoffs(VALUE self) {
190
+ VALUE dof;
191
+ VALUE args = rb_iv_get(self, "@data");
192
+ VALUE rarg;
193
+ uint32_t arg;
194
+ int i;
195
+
196
+ if (NIL_P(args) ) {
197
+ rb_raise(eDtraceDofException, "no args in dof_generate_prenoffs");
198
+ return Qnil;
199
+ }
200
+ Check_Type(args, T_ARRAY);
201
+
202
+ dof = rb_str_new("", 0);
203
+
204
+ for (i = 0; i < rb_ary_len(args); i++) {
205
+ rarg = rb_ary_entry(args, i);
206
+ Check_Type(rarg, T_FIXNUM);
207
+ arg = FIX2INT(rarg);
208
+ rb_str_concat(dof, rb_str_new((char *)&arg, 4));
209
+ }
210
+
211
+ return dof;
212
+ }
213
+
214
+ dof_attr_t _dof_generate_dof_attr_t(VALUE data) {
215
+ dof_attr_t attr = 0;
216
+ uint8_t n = 0;
217
+ uint8_t d = 0;
218
+ uint8_t c = 0;
219
+
220
+ Check_Type(data, T_HASH);
221
+
222
+ n = FIX2INT(rb_hash_aref(data, ID2SYM(rb_intern("name"))));
223
+ d = FIX2INT(rb_hash_aref(data, ID2SYM(rb_intern("data"))));
224
+ c = FIX2INT(rb_hash_aref(data, ID2SYM(rb_intern("class"))));
225
+
226
+ attr = DOF_ATTR(n, d, c);
227
+ return attr;
228
+ }
229
+
230
+ /* :nodoc: */
231
+ VALUE dof_generate_provider(VALUE self) {
232
+ VALUE dof;
233
+ VALUE provider = rb_iv_get(self, "@data");
234
+ dof_provider_t p;
235
+
236
+ if (NIL_P(provider) ) {
237
+ rb_raise(eDtraceDofException, "no data in dof_generate_provider");
238
+ return Qnil;
239
+ }
240
+ Check_Type(provider, T_HASH);
241
+
242
+ p.dofpv_strtab = (dof_secidx_t)FIX2INT(rb_hash_aref(provider, ID2SYM(rb_intern("strtab"))));
243
+ p.dofpv_probes = (dof_secidx_t)FIX2INT(rb_hash_aref(provider, ID2SYM(rb_intern("probes"))));
244
+ p.dofpv_prargs = (dof_secidx_t)FIX2INT(rb_hash_aref(provider, ID2SYM(rb_intern("prargs"))));
245
+ p.dofpv_proffs = (dof_secidx_t)FIX2INT(rb_hash_aref(provider, ID2SYM(rb_intern("proffs"))));
246
+ p.dofpv_name = (dof_stridx_t)FIX2INT(rb_hash_aref(provider, ID2SYM(rb_intern("name"))));
247
+ p.dofpv_provattr = _dof_generate_dof_attr_t(rb_hash_aref(provider, ID2SYM(rb_intern("provattr"))));
248
+ p.dofpv_modattr = _dof_generate_dof_attr_t(rb_hash_aref(provider, ID2SYM(rb_intern("modattr"))));
249
+ p.dofpv_funcattr = _dof_generate_dof_attr_t(rb_hash_aref(provider, ID2SYM(rb_intern("funcattr"))));
250
+ p.dofpv_nameattr = _dof_generate_dof_attr_t(rb_hash_aref(provider, ID2SYM(rb_intern("nameattr"))));
251
+ p.dofpv_argsattr = _dof_generate_dof_attr_t(rb_hash_aref(provider, ID2SYM(rb_intern("argsattr"))));
252
+ p.dofpv_prenoffs = (dof_secidx_t)FIX2INT(rb_hash_aref(provider, ID2SYM(rb_intern("prenoffs"))));
253
+
254
+ dof = rb_str_new((const char *)&p, sizeof(p));
255
+ return dof;
256
+ }
257
+
258
+ /* :nodoc: */
259
+ VALUE dof_generate_reltab(VALUE self) {
260
+ VALUE dof;
261
+ VALUE relos = rb_iv_get(self, "@data");
262
+ VALUE relo;
263
+ int i;
264
+
265
+ if (NIL_P(relos) ) {
266
+ rb_raise(eDtraceDofException, "no relos in dof_generate_reltab");
267
+ return Qnil;
268
+ }
269
+ Check_Type(relos, T_ARRAY);
270
+
271
+ dof = rb_str_new2("");
272
+
273
+ for (i = 0; i < rb_ary_len(relos); i++) {
274
+ relo = rb_ary_entry(relos, i);
275
+
276
+ Check_Type(relo, T_HASH);
277
+
278
+ dof_relodesc_t r;
279
+ memset(&r, 0, sizeof(r));
280
+
281
+ r.dofr_name = (dof_stridx_t)FIX2INT(rb_hash_aref(relo, ID2SYM(rb_intern("name"))));
282
+ r.dofr_type = (uint32_t)FIX2INT(rb_hash_aref(relo, ID2SYM(rb_intern("type"))));
283
+ r.dofr_offset = (uint64_t)FIX2INT(rb_hash_aref(relo, ID2SYM(rb_intern("offset"))));
284
+ r.dofr_data = (uint64_t)FIX2INT(rb_hash_aref(relo, ID2SYM(rb_intern("data"))));
285
+
286
+ VALUE r_dof = rb_str_new((const char *)&r, sizeof(r));
287
+ rb_str_concat(dof, r_dof);
288
+ }
289
+
290
+ return dof;
291
+ }
292
+
293
+ /* :nodoc: */
294
+ VALUE dof_generate_relhdr(VALUE self) {
295
+ VALUE dof;
296
+ VALUE relhdr = rb_iv_get(self, "@data");
297
+ dof_relohdr_t r;
298
+
299
+ if (NIL_P(relhdr) ) {
300
+ rb_raise(eDtraceDofException, "no data in dof_generate_relhdr");
301
+ return Qnil;
302
+ }
303
+ Check_Type(relhdr, T_HASH);
304
+
305
+ r.dofr_strtab = (dof_secidx_t)FIX2INT(rb_hash_aref(relhdr, ID2SYM(rb_intern("strtab"))));
306
+ r.dofr_relsec = (dof_secidx_t)FIX2INT(rb_hash_aref(relhdr, ID2SYM(rb_intern("relsec"))));
307
+ r.dofr_tgtsec = (dof_secidx_t)FIX2INT(rb_hash_aref(relhdr, ID2SYM(rb_intern("tgtsec"))));
308
+
309
+ dof = rb_str_new((const char *)&r, sizeof(r));
310
+ return dof;
311
+ }
312
+