ruby-usdt 0.2.0 → 0.2.1

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,128 @@
1
+ /*
2
+ * Copyright (c) 2012, Chris Andrews. All rights reserved.
3
+ */
4
+
5
+ #include "usdt_internal.h"
6
+
7
+ #include <stdlib.h>
8
+
9
+ int
10
+ usdt_dof_section_add_data(usdt_dof_section_t *section, void *data, size_t length)
11
+ {
12
+ int newlen = section->size + length;
13
+
14
+ if ((section->data = realloc((char *)section->data, newlen)) == NULL)
15
+ return (-1);
16
+
17
+ memcpy(section->data + section->size, data, length);
18
+ section->size = newlen;
19
+ return (0);
20
+ }
21
+
22
+ size_t
23
+ usdt_provider_dof_size(usdt_provider_t *provider, usdt_strtab_t *strtab)
24
+ {
25
+ uint8_t i, j;
26
+ int args = 0;
27
+ int probes = 0;
28
+ size_t size = 0;
29
+ usdt_probedef_t *pd;
30
+ size_t sections[8];
31
+
32
+ for (pd = provider->probedefs; pd != NULL; pd = pd->next) {
33
+ args += pd->argc;
34
+ probes++;
35
+ }
36
+
37
+ sections[0] = sizeof(dof_hdr_t);
38
+ sections[1] = sizeof(dof_sec_t) * 6;
39
+ sections[2] = strtab->size;
40
+ sections[3] = sizeof(dof_probe_t) * probes;
41
+ sections[4] = sizeof(uint8_t) * args;
42
+ sections[5] = sizeof(uint32_t) * probes;
43
+ sections[6] = sizeof(uint32_t) * probes;
44
+ sections[7] = sizeof(dof_provider_t);
45
+
46
+ for (i = 0; i < 8; i++) {
47
+ size += sections[i];
48
+ j = size % 8;
49
+ if (j > 0)
50
+ size += (8 - j);
51
+ }
52
+
53
+ return size;
54
+ }
55
+
56
+ int
57
+ usdt_dof_section_init(usdt_dof_section_t *section, uint32_t type, dof_secidx_t index)
58
+ {
59
+ section->type = type;
60
+ section->index = index;
61
+ section->flags = DOF_SECF_LOAD;
62
+ section->offset = 0;
63
+ section->size = 0;
64
+ section->entsize = 0;
65
+ section->pad = 0;
66
+ section->next = NULL;
67
+
68
+ if ((section->data = malloc(1)) == NULL)
69
+ return (-1);
70
+
71
+ switch(type) {
72
+ case DOF_SECT_PROBES: section->align = 8; break;
73
+ case DOF_SECT_PRARGS: section->align = 1; break;
74
+ case DOF_SECT_PROFFS: section->align = 4; break;
75
+ case DOF_SECT_PRENOFFS: section->align = 4; break;
76
+ case DOF_SECT_PROVIDER: section->align = 4; break;
77
+ }
78
+
79
+ return (0);
80
+ }
81
+
82
+ void
83
+ usdt_dof_section_free(usdt_dof_section_t *section)
84
+ {
85
+ free(section->data);
86
+ }
87
+
88
+ int
89
+ usdt_strtab_init(usdt_strtab_t *strtab, dof_secidx_t index)
90
+ {
91
+ strtab->type = DOF_SECT_STRTAB;;
92
+ strtab->index = index;
93
+ strtab->flags = DOF_SECF_LOAD;
94
+ strtab->offset = 0;
95
+ strtab->size = 0;
96
+ strtab->entsize = 0;
97
+ strtab->pad = 0;
98
+ strtab->data = NULL;
99
+ strtab->align = 1;
100
+ strtab->strindex = 1;
101
+
102
+ if ((strtab->data = (char *) malloc(1)) == NULL)
103
+ return (-1);
104
+
105
+ *strtab->data = '\0';
106
+
107
+ return (0);
108
+ }
109
+
110
+ dof_stridx_t
111
+ usdt_strtab_add(usdt_strtab_t *strtab, const char *string)
112
+ {
113
+ size_t length;
114
+ int index;
115
+
116
+ length = strlen(string);
117
+ index = strtab->strindex;
118
+ strtab->strindex += (length + 1);
119
+
120
+ if ((strtab->data = realloc(strtab->data, strtab->strindex)) == NULL)
121
+ return (0);
122
+
123
+ memcpy((char *) (strtab->data + index), (char *)string, length + 1);
124
+ strtab->size = index + length + 1;
125
+
126
+ return (index);
127
+ }
128
+
@@ -0,0 +1,277 @@
1
+ /*
2
+ * Copyright (c) 2012, Chris Andrews. All rights reserved.
3
+ */
4
+
5
+ #include "usdt_internal.h"
6
+
7
+ #include <stdio.h>
8
+ #include <stdlib.h>
9
+
10
+ static uint8_t
11
+ dof_version(uint8_t header_version)
12
+ {
13
+ uint8_t dof_version;
14
+ /* DOF versioning: Apple always needs version 3, but Solaris can use
15
+ 1 or 2 depending on whether is-enabled probes are needed. */
16
+ #ifdef __APPLE__
17
+ dof_version = DOF_VERSION_3;
18
+ #else
19
+ switch(header_version) {
20
+ case 1:
21
+ dof_version = DOF_VERSION_1;
22
+ break;
23
+ case 2:
24
+ dof_version = DOF_VERSION_2;
25
+ break;
26
+ default:
27
+ dof_version = DOF_VERSION;
28
+ }
29
+ #endif
30
+ return dof_version;
31
+ }
32
+
33
+ #ifdef __APPLE__
34
+ static const char *helper = "/dev/dtracehelper";
35
+
36
+ static int
37
+ load_dof(int fd, dof_helper_t *dh)
38
+ {
39
+ int ret;
40
+ uint8_t buffer[sizeof(dof_ioctl_data_t) + sizeof(dof_helper_t)];
41
+ dof_ioctl_data_t* ioctlData = (dof_ioctl_data_t*)buffer;
42
+ user_addr_t val;
43
+
44
+ ioctlData->dofiod_count = 1;
45
+ memcpy(&ioctlData->dofiod_helpers[0], dh, sizeof(dof_helper_t));
46
+
47
+ val = (user_addr_t)(unsigned long)ioctlData;
48
+ ret = ioctl(fd, DTRACEHIOC_ADDDOF, &val);
49
+
50
+ if (ret < 0)
51
+ return ret;
52
+
53
+ return (int)(ioctlData->dofiod_helpers[0].dofhp_dof);
54
+ }
55
+
56
+ #else /* Solaris */
57
+
58
+ /* ignore Sol10 GA ... */
59
+ static const char *helper = "/dev/dtrace/helper";
60
+
61
+ static int
62
+ load_dof(int fd, dof_helper_t *dh)
63
+ {
64
+ return ioctl(fd, DTRACEHIOC_ADDDOF, dh);
65
+ }
66
+
67
+ #endif
68
+
69
+ static void
70
+ pad_section(usdt_dof_section_t *sec)
71
+ {
72
+ size_t i, pad;
73
+
74
+ if (sec->align > 1) {
75
+ i = sec->offset % sec->align;
76
+ if (i > 0) {
77
+ pad = sec->align - i;
78
+ sec->offset = (pad + sec->offset);
79
+ sec->pad = pad;
80
+ }
81
+ }
82
+ }
83
+
84
+ static void
85
+ dof_header(dof_hdr_t *header)
86
+ {
87
+ int i;
88
+
89
+ header->dofh_ident[DOF_ID_MAG0] = DOF_MAG_MAG0;
90
+ header->dofh_ident[DOF_ID_MAG1] = DOF_MAG_MAG1;
91
+ header->dofh_ident[DOF_ID_MAG2] = DOF_MAG_MAG2;
92
+ header->dofh_ident[DOF_ID_MAG3] = DOF_MAG_MAG3;
93
+
94
+ header->dofh_ident[DOF_ID_MODEL] = DOF_MODEL_NATIVE;
95
+ header->dofh_ident[DOF_ID_ENCODING] = DOF_ENCODE_NATIVE;
96
+ header->dofh_ident[DOF_ID_VERSION] = dof_version(2);
97
+ header->dofh_ident[DOF_ID_DIFVERS] = DIF_VERSION;
98
+ header->dofh_ident[DOF_ID_DIFIREG] = DIF_DIR_NREGS;
99
+ header->dofh_ident[DOF_ID_DIFTREG] = DIF_DTR_NREGS;
100
+
101
+ for (i = DOF_ID_PAD; i < DOF_ID_SIZE; i++)
102
+ header->dofh_ident[i] = 0;
103
+
104
+ header->dofh_flags = 0;
105
+
106
+ header->dofh_hdrsize = sizeof(dof_hdr_t);
107
+ header->dofh_secsize = sizeof(dof_sec_t);
108
+ header->dofh_secoff = sizeof(dof_hdr_t);
109
+
110
+ header->dofh_loadsz = 0;
111
+ header->dofh_filesz = 0;
112
+ header->dofh_pad = 0;
113
+ }
114
+
115
+ static size_t
116
+ add_header(usdt_dof_file_t *file, size_t offset, usdt_dof_section_t *section)
117
+ {
118
+ dof_sec_t header;
119
+
120
+ header.dofs_flags = section->flags;
121
+ header.dofs_type = section->type;
122
+ header.dofs_offset = section->offset;
123
+ header.dofs_size = section->size;
124
+ header.dofs_entsize = section->entsize;
125
+ header.dofs_align = section->align;
126
+
127
+ memcpy((file->dof + offset), &header, sizeof(dof_sec_t));
128
+ return (offset + sizeof(dof_sec_t));
129
+ }
130
+
131
+ static size_t
132
+ add_section(usdt_dof_file_t *file, size_t offset, usdt_dof_section_t *section)
133
+ {
134
+ if (section->pad > 0) {
135
+ /* maximum padding required is 7 */
136
+ memcpy((file->dof + offset), "\0\0\0\0\0\0\0", section->pad);
137
+ offset += section->pad;
138
+ }
139
+
140
+ memcpy((file->dof + offset), section->data, section->size);
141
+ return (offset + section->size);
142
+ }
143
+
144
+ int
145
+ usdt_dof_file_unload(usdt_dof_file_t *file)
146
+ {
147
+ int fd, ret;
148
+
149
+ if ((fd = open(helper, O_RDWR)) < 0)
150
+ return (-1);
151
+
152
+ ret = ioctl(fd, DTRACEHIOC_REMOVE, file->gen);
153
+
154
+ if (ret < 0)
155
+ return (-1);
156
+
157
+ if ((close(fd)) < 0)
158
+ return (-1);
159
+
160
+ return (0);
161
+ }
162
+
163
+ int
164
+ usdt_dof_file_load(usdt_dof_file_t *file, const char *module)
165
+ {
166
+ dof_helper_t dh;
167
+ dof_hdr_t *dof;
168
+ int fd;
169
+
170
+ dof = (dof_hdr_t *) file->dof;
171
+
172
+ dh.dofhp_dof = (uintptr_t)dof;
173
+ dh.dofhp_addr = (uintptr_t)dof;
174
+ (void) strncpy(dh.dofhp_mod, module, sizeof (dh.dofhp_mod));
175
+
176
+ if ((fd = open(helper, O_RDWR)) < 0)
177
+ return (-1);
178
+
179
+ file->gen = load_dof(fd, &dh);
180
+
181
+ if ((close(fd)) < 0)
182
+ return (-1);
183
+
184
+ if (file->gen < 0)
185
+ return (-1);
186
+
187
+ return (0);
188
+ }
189
+
190
+ void
191
+ usdt_dof_file_append_section(usdt_dof_file_t *file, usdt_dof_section_t *section)
192
+ {
193
+ usdt_dof_section_t *s;
194
+
195
+ if (file->sections == NULL) {
196
+ file->sections = section;
197
+ }
198
+ else {
199
+ for (s = file->sections; (s->next != NULL); s = s->next) ;
200
+ s->next = section;
201
+ }
202
+ }
203
+
204
+ void
205
+ usdt_dof_file_generate(usdt_dof_file_t *file, usdt_strtab_t *strtab)
206
+ {
207
+ dof_hdr_t header;
208
+ uint64_t filesz;
209
+ uint64_t loadsz;
210
+ usdt_dof_section_t *sec;
211
+ size_t offset;
212
+
213
+ dof_header(&header);
214
+ header.dofh_secnum = 6;
215
+
216
+ filesz = sizeof(dof_hdr_t) + (sizeof(dof_sec_t) * header.dofh_secnum);
217
+ loadsz = filesz;
218
+
219
+ strtab->offset = filesz;
220
+ pad_section((usdt_dof_section_t *)strtab);
221
+ filesz += strtab->size + strtab->pad;
222
+
223
+ if (strtab->flags & 1)
224
+ loadsz += strtab->size + strtab->pad;
225
+
226
+ for (sec = file->sections; sec != NULL; sec = sec->next) {
227
+ sec->offset = filesz;
228
+ pad_section(sec);
229
+ filesz += sec->size + sec->pad;
230
+ if (sec->flags & 1)
231
+ loadsz += sec->size + sec->pad;
232
+ }
233
+
234
+ header.dofh_loadsz = loadsz;
235
+ header.dofh_filesz = filesz;
236
+ memcpy(file->dof, &header, sizeof(dof_hdr_t));
237
+
238
+ offset = sizeof(dof_hdr_t);
239
+
240
+ offset = add_header(file, offset, (usdt_dof_section_t *)strtab);
241
+
242
+ for (sec = file->sections; sec != NULL; sec = sec->next)
243
+ offset = add_header(file, offset, sec);
244
+
245
+ offset = add_section(file, offset, (usdt_dof_section_t *)strtab);
246
+
247
+ for (sec = file->sections; sec != NULL; sec = sec->next)
248
+ offset = add_section(file, offset, sec);
249
+ }
250
+
251
+ usdt_dof_file_t *
252
+ usdt_dof_file_init(usdt_provider_t *provider, size_t size)
253
+ {
254
+ usdt_dof_file_t *file;
255
+
256
+ if ((file = malloc(sizeof(*file))) == NULL) {
257
+ usdt_error(provider, USDT_ERROR_MALLOC);
258
+ return (NULL);
259
+ }
260
+
261
+ if ((file->dof = valloc(size)) == NULL) {
262
+ usdt_error(provider, USDT_ERROR_VALLOC);
263
+ return (NULL);
264
+ }
265
+
266
+ file->sections = NULL;
267
+ file->size = size;
268
+
269
+ return (file);
270
+ }
271
+
272
+ void
273
+ usdt_dof_file_free(usdt_dof_file_t *file)
274
+ {
275
+ free(file->dof);
276
+ free(file);
277
+ }
@@ -0,0 +1,190 @@
1
+ /*
2
+ * Copyright (c) 2012, Chris Andrews. All rights reserved.
3
+ */
4
+
5
+ #include "usdt_internal.h"
6
+
7
+ int
8
+ usdt_dof_probes_sect(usdt_dof_section_t *probes,
9
+ usdt_provider_t *provider, usdt_strtab_t *strtab)
10
+ {
11
+ usdt_probedef_t *pd;
12
+ dof_probe_t p;
13
+ dof_stridx_t type, argv;
14
+ uint8_t argc, i;
15
+ uint32_t argidx = 0;
16
+ uint32_t offidx = 0;
17
+
18
+ usdt_dof_section_init(probes, DOF_SECT_PROBES, 1);
19
+
20
+ for (pd = provider->probedefs; pd != NULL; pd = pd->next) {
21
+ argc = 0;
22
+ argv = 0;
23
+ type = 0;
24
+
25
+ for (i = 0; i < pd->argc; i++) {
26
+ switch(pd->types[i]) {
27
+ case USDT_ARGTYPE_INTEGER:
28
+ type = usdt_strtab_add(strtab, "int");
29
+ break;
30
+ case USDT_ARGTYPE_STRING:
31
+ type = usdt_strtab_add(strtab, "char *");
32
+ break;
33
+ default:
34
+ break;
35
+ }
36
+
37
+ argc++;
38
+ if (argv == 0)
39
+ argv = type;
40
+ }
41
+
42
+ if (usdt_create_tracepoints(pd->probe) < 0) {
43
+ usdt_error(provider, USDT_ERROR_VALLOC);
44
+ return (-1);
45
+ }
46
+
47
+ #ifdef __x86_64__
48
+ p.dofpr_addr = (uint64_t) pd->probe->isenabled_addr;
49
+ #elif __i386__ || __i386
50
+ p.dofpr_addr = (uint32_t) pd->probe->isenabled_addr;
51
+ #else
52
+ #error "only x86_64 and i386 supported"
53
+ #endif
54
+ p.dofpr_func = usdt_strtab_add(strtab, pd->function);
55
+ p.dofpr_name = usdt_strtab_add(strtab, pd->name);
56
+ p.dofpr_nargv = argv;
57
+ p.dofpr_xargv = argv;
58
+ p.dofpr_argidx = argidx;
59
+ p.dofpr_offidx = offidx;
60
+ p.dofpr_nargc = argc;
61
+ p.dofpr_xargc = argc;
62
+ p.dofpr_noffs = 1;
63
+ p.dofpr_enoffidx = offidx;
64
+ p.dofpr_nenoffs = 1;
65
+ p.dofpr_pad1 = 0;
66
+ p.dofpr_pad2 = 0;
67
+
68
+ usdt_dof_section_add_data(probes, &p, sizeof(dof_probe_t));
69
+ probes->entsize = sizeof(dof_probe_t);
70
+
71
+ argidx += argc;
72
+ offidx++;
73
+ }
74
+
75
+ return (0);
76
+ }
77
+
78
+ int
79
+ usdt_dof_prargs_sect(usdt_dof_section_t *prargs, usdt_provider_t *provider)
80
+ {
81
+ usdt_probedef_t *pd;
82
+ uint8_t i;
83
+
84
+ usdt_dof_section_init(prargs, DOF_SECT_PRARGS, 2);
85
+ prargs->entsize = 1;
86
+
87
+ for (pd = provider->probedefs; pd != NULL; pd = pd->next) {
88
+ for (i = 0; i < pd->argc; i++)
89
+ usdt_dof_section_add_data(prargs, &i, 1);
90
+ }
91
+ if (prargs->size == 0) {
92
+ i = 0;
93
+ if (usdt_dof_section_add_data(prargs, &i, 1) < 0) {
94
+ usdt_error(provider, USDT_ERROR_MALLOC);
95
+ return (-1);
96
+ }
97
+ }
98
+
99
+ return (0);
100
+ }
101
+
102
+ int
103
+ usdt_dof_proffs_sect(usdt_dof_section_t *proffs,
104
+ usdt_provider_t *provider, char *dof)
105
+ {
106
+ usdt_probedef_t *pd;
107
+ uint32_t off;
108
+
109
+ usdt_dof_section_init(proffs, DOF_SECT_PROFFS, 3);
110
+ proffs->entsize = 4;
111
+
112
+ for (pd = provider->probedefs; pd != NULL; pd = pd->next) {
113
+ off = usdt_probe_offset(pd->probe, dof, pd->argc);
114
+ if (usdt_dof_section_add_data(proffs, &off, 4) < 0) {
115
+ usdt_error(provider, USDT_ERROR_MALLOC);
116
+ return (-1);
117
+ }
118
+ }
119
+
120
+ return (0);
121
+ }
122
+
123
+ int
124
+ usdt_dof_prenoffs_sect(usdt_dof_section_t *prenoffs,
125
+ usdt_provider_t *provider, char *dof)
126
+ {
127
+ usdt_probedef_t *pd;
128
+ uint32_t off;
129
+
130
+ usdt_dof_section_init(prenoffs, DOF_SECT_PRENOFFS, 4);
131
+ prenoffs->entsize = 4;
132
+
133
+ for (pd = provider->probedefs; pd != NULL; pd = pd->next) {
134
+ off = usdt_is_enabled_offset(pd->probe, dof);
135
+ if (usdt_dof_section_add_data(prenoffs, &off, 4) < 0) {
136
+ usdt_error(provider, USDT_ERROR_MALLOC);
137
+ return (-1);
138
+ }
139
+ }
140
+
141
+ return (0);
142
+ }
143
+
144
+ int
145
+ usdt_dof_provider_sect(usdt_dof_section_t *provider_s, usdt_provider_t *provider)
146
+ {
147
+ dof_provider_t p;
148
+
149
+ usdt_dof_section_init(provider_s, DOF_SECT_PROVIDER, 5);
150
+
151
+ p.dofpv_strtab = 0;
152
+ p.dofpv_probes = 1;
153
+ p.dofpv_prargs = 2;
154
+ p.dofpv_proffs = 3;
155
+ p.dofpv_prenoffs = 4;
156
+ p.dofpv_name = 1; /* provider name always first strtab entry. */
157
+
158
+ /*
159
+ * Stability is something of a hack. Everything is marked *
160
+ * "stable" here to permit use of the "args" array, which is *
161
+ * needed to access arguments past "arg9".
162
+ *
163
+ * It should be up to the creator of the provider to decide
164
+ * this, though, and it should be possible to set the
165
+ * appropriate stability at creation time.
166
+ */
167
+
168
+ p.dofpv_provattr = DOF_ATTR(DTRACE_STABILITY_STABLE,
169
+ DTRACE_STABILITY_STABLE,
170
+ DTRACE_STABILITY_STABLE);
171
+ p.dofpv_modattr = DOF_ATTR(DTRACE_STABILITY_STABLE,
172
+ DTRACE_STABILITY_STABLE,
173
+ DTRACE_STABILITY_STABLE);
174
+ p.dofpv_funcattr = DOF_ATTR(DTRACE_STABILITY_STABLE,
175
+ DTRACE_STABILITY_STABLE,
176
+ DTRACE_STABILITY_STABLE);
177
+ p.dofpv_nameattr = DOF_ATTR(DTRACE_STABILITY_STABLE,
178
+ DTRACE_STABILITY_STABLE,
179
+ DTRACE_STABILITY_STABLE);
180
+ p.dofpv_argsattr = DOF_ATTR(DTRACE_STABILITY_STABLE,
181
+ DTRACE_STABILITY_STABLE,
182
+ DTRACE_STABILITY_STABLE);
183
+
184
+ if ((usdt_dof_section_add_data(provider_s, &p, sizeof(p))) < 0) {
185
+ usdt_error(provider, USDT_ERROR_MALLOC);
186
+ return (-1);
187
+ }
188
+
189
+ return (0);
190
+ }