ruby-usdt 0.0.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.
- data/LICENSE.md +18 -0
- data/README.md +75 -0
- data/ext/libusdt/Makefile +117 -0
- data/ext/libusdt/README +59 -0
- data/ext/libusdt/test.pl +83 -0
- data/ext/libusdt/test_usdt.c +60 -0
- data/ext/libusdt/usdt.c +198 -0
- data/ext/libusdt/usdt.h +50 -0
- data/ext/libusdt/usdt_dof.c +118 -0
- data/ext/libusdt/usdt_dof_file.c +240 -0
- data/ext/libusdt/usdt_dof_sections.c +172 -0
- data/ext/libusdt/usdt_internal.h +100 -0
- data/ext/libusdt/usdt_probe.c +66 -0
- data/ext/libusdt/usdt_tracepoints_i386.s +65 -0
- data/ext/libusdt/usdt_tracepoints_x86_64.s +83 -0
- data/ext/usdt/Makefile +157 -0
- data/ext/usdt/conftest.dSYM/Contents/Info.plist +20 -0
- data/ext/usdt/conftest.dSYM/Contents/Resources/DWARF/conftest +0 -0
- data/ext/usdt/extconf.rb +9 -0
- data/ext/usdt/test.rb +23 -0
- data/ext/usdt/usdt.c +141 -0
- data/ext/usdt/usdt.h +50 -0
- data/lib/usdt/version.rb +3 -0
- data/lib/usdt.rb +2 -0
- metadata +71 -0
@@ -0,0 +1,118 @@
|
|
1
|
+
#include "usdt_internal.h"
|
2
|
+
|
3
|
+
#include <stdlib.h>
|
4
|
+
|
5
|
+
int
|
6
|
+
usdt_dof_section_add_data(usdt_dof_section_t *section, void *data, size_t length)
|
7
|
+
{
|
8
|
+
int newlen = section->size + length;
|
9
|
+
|
10
|
+
if ((section->data = realloc((char *)section->data, newlen)) == NULL)
|
11
|
+
return (-1);
|
12
|
+
|
13
|
+
memcpy(section->data + section->size, data, length);
|
14
|
+
section->size = newlen;
|
15
|
+
return (0);
|
16
|
+
}
|
17
|
+
|
18
|
+
size_t
|
19
|
+
usdt_provider_dof_size(usdt_provider_t *provider, usdt_strtab_t *strtab)
|
20
|
+
{
|
21
|
+
uint8_t i, j;
|
22
|
+
int args = 0;
|
23
|
+
int probes = 0;
|
24
|
+
size_t size = 0;
|
25
|
+
usdt_probedef_t *pd;
|
26
|
+
size_t sections[8];
|
27
|
+
|
28
|
+
for (pd = provider->probedefs; pd != NULL; pd = pd->next) {
|
29
|
+
args += usdt_probedef_argc(pd);
|
30
|
+
probes++;
|
31
|
+
}
|
32
|
+
|
33
|
+
sections[0] = sizeof(dof_hdr_t);
|
34
|
+
sections[1] = sizeof(dof_sec_t) * 6;
|
35
|
+
sections[2] = strtab->size;
|
36
|
+
sections[3] = sizeof(dof_probe_t) * probes;
|
37
|
+
sections[4] = sizeof(uint8_t) * args;
|
38
|
+
sections[5] = sizeof(uint32_t) * probes;
|
39
|
+
sections[6] = sizeof(uint32_t) * probes;
|
40
|
+
sections[7] = sizeof(dof_provider_t);
|
41
|
+
|
42
|
+
for (i = 0; i < 8; i++) {
|
43
|
+
size += sections[i];
|
44
|
+
j = size % 8;
|
45
|
+
if (j > 0)
|
46
|
+
size += (8 - j);
|
47
|
+
}
|
48
|
+
|
49
|
+
return size;
|
50
|
+
}
|
51
|
+
|
52
|
+
int
|
53
|
+
usdt_dof_section_init(usdt_dof_section_t *section, uint32_t type, dof_secidx_t index)
|
54
|
+
{
|
55
|
+
section->type = type;
|
56
|
+
section->index = index;
|
57
|
+
section->flags = DOF_SECF_LOAD;
|
58
|
+
section->offset = 0;
|
59
|
+
section->size = 0;
|
60
|
+
section->entsize = 0;
|
61
|
+
section->pad = 0;
|
62
|
+
section->next = NULL;
|
63
|
+
|
64
|
+
if ((section->data = malloc(1)) == NULL)
|
65
|
+
return (-1);
|
66
|
+
|
67
|
+
switch(type) {
|
68
|
+
case DOF_SECT_PROBES: section->align = 8; break;
|
69
|
+
case DOF_SECT_PRARGS: section->align = 1; break;
|
70
|
+
case DOF_SECT_PROFFS: section->align = 4; break;
|
71
|
+
case DOF_SECT_PRENOFFS: section->align = 4; break;
|
72
|
+
case DOF_SECT_PROVIDER: section->align = 4; break;
|
73
|
+
}
|
74
|
+
|
75
|
+
return (0);
|
76
|
+
}
|
77
|
+
|
78
|
+
int
|
79
|
+
usdt_strtab_init(usdt_strtab_t *strtab, dof_secidx_t index)
|
80
|
+
{
|
81
|
+
strtab->type = DOF_SECT_STRTAB;;
|
82
|
+
strtab->index = index;
|
83
|
+
strtab->flags = DOF_SECF_LOAD;
|
84
|
+
strtab->offset = 0;
|
85
|
+
strtab->size = 0;
|
86
|
+
strtab->entsize = 0;
|
87
|
+
strtab->pad = 0;
|
88
|
+
strtab->data = NULL;
|
89
|
+
strtab->align = 1;
|
90
|
+
strtab->strindex = 1;
|
91
|
+
|
92
|
+
if ((strtab->data = (char *) malloc(1)) == NULL)
|
93
|
+
return (-1);
|
94
|
+
|
95
|
+
*strtab->data = '\0';
|
96
|
+
|
97
|
+
return (0);
|
98
|
+
}
|
99
|
+
|
100
|
+
dof_stridx_t
|
101
|
+
usdt_strtab_add(usdt_strtab_t *strtab, const char *string)
|
102
|
+
{
|
103
|
+
size_t length;
|
104
|
+
int index;
|
105
|
+
|
106
|
+
length = strlen(string);
|
107
|
+
index = strtab->strindex;
|
108
|
+
strtab->strindex += (length + 1);
|
109
|
+
|
110
|
+
if ((strtab->data = realloc(strtab->data, strtab->strindex)) == NULL)
|
111
|
+
return (-1);
|
112
|
+
|
113
|
+
memcpy((char *) (strtab->data + index), (char *)string, length + 1);
|
114
|
+
strtab->size = index + length + 1;
|
115
|
+
|
116
|
+
return index;
|
117
|
+
}
|
118
|
+
|
@@ -0,0 +1,240 @@
|
|
1
|
+
#include "usdt_internal.h"
|
2
|
+
|
3
|
+
#include <stdio.h>
|
4
|
+
#include <stdlib.h>
|
5
|
+
|
6
|
+
static uint8_t
|
7
|
+
dof_version(uint8_t header_version)
|
8
|
+
{
|
9
|
+
uint8_t dof_version;
|
10
|
+
/* DOF versioning: Apple always needs version 3, but Solaris can use
|
11
|
+
1 or 2 depending on whether is-enabled probes are needed. */
|
12
|
+
#ifdef __APPLE__
|
13
|
+
dof_version = DOF_VERSION_3;
|
14
|
+
#else
|
15
|
+
switch(header_version) {
|
16
|
+
case 1:
|
17
|
+
dof_version = DOF_VERSION_1;
|
18
|
+
break;
|
19
|
+
case 2:
|
20
|
+
dof_version = DOF_VERSION_2;
|
21
|
+
break;
|
22
|
+
default:
|
23
|
+
dof_version = DOF_VERSION;
|
24
|
+
}
|
25
|
+
#endif
|
26
|
+
return dof_version;
|
27
|
+
}
|
28
|
+
|
29
|
+
#ifdef __APPLE__
|
30
|
+
static const char *helper = "/dev/dtracehelper";
|
31
|
+
|
32
|
+
static int
|
33
|
+
load_dof(int fd, dof_helper_t *dh)
|
34
|
+
{
|
35
|
+
int ret;
|
36
|
+
uint8_t buffer[sizeof(dof_ioctl_data_t) + sizeof(dof_helper_t)];
|
37
|
+
dof_ioctl_data_t* ioctlData = (dof_ioctl_data_t*)buffer;
|
38
|
+
user_addr_t val;
|
39
|
+
|
40
|
+
ioctlData->dofiod_count = 1;
|
41
|
+
memcpy(&ioctlData->dofiod_helpers[0], dh, sizeof(dof_helper_t));
|
42
|
+
|
43
|
+
val = (user_addr_t)(unsigned long)ioctlData;
|
44
|
+
ret = ioctl(fd, DTRACEHIOC_ADDDOF, &val);
|
45
|
+
|
46
|
+
return ret;
|
47
|
+
}
|
48
|
+
|
49
|
+
#else /* Solaris */
|
50
|
+
|
51
|
+
/* ignore Sol10 GA ... */
|
52
|
+
static const char *helper = "/dev/dtrace/helper";
|
53
|
+
|
54
|
+
static int
|
55
|
+
load_dof(int fd, dof_helper_t *dh)
|
56
|
+
{
|
57
|
+
return ioctl(fd, DTRACEHIOC_ADDDOF, dh);
|
58
|
+
}
|
59
|
+
|
60
|
+
#endif
|
61
|
+
|
62
|
+
static void
|
63
|
+
pad_section(usdt_dof_section_t *sec)
|
64
|
+
{
|
65
|
+
size_t i, pad;
|
66
|
+
|
67
|
+
if (sec->align > 1) {
|
68
|
+
i = sec->offset % sec->align;
|
69
|
+
if (i > 0) {
|
70
|
+
pad = sec->align - i;
|
71
|
+
sec->offset = (pad + sec->offset);
|
72
|
+
sec->pad = pad;
|
73
|
+
}
|
74
|
+
}
|
75
|
+
}
|
76
|
+
|
77
|
+
static void
|
78
|
+
dof_header(dof_hdr_t *header)
|
79
|
+
{
|
80
|
+
int i;
|
81
|
+
|
82
|
+
header->dofh_ident[DOF_ID_MAG0] = DOF_MAG_MAG0;
|
83
|
+
header->dofh_ident[DOF_ID_MAG1] = DOF_MAG_MAG1;
|
84
|
+
header->dofh_ident[DOF_ID_MAG2] = DOF_MAG_MAG2;
|
85
|
+
header->dofh_ident[DOF_ID_MAG3] = DOF_MAG_MAG3;
|
86
|
+
|
87
|
+
header->dofh_ident[DOF_ID_MODEL] = DOF_MODEL_NATIVE;
|
88
|
+
header->dofh_ident[DOF_ID_ENCODING] = DOF_ENCODE_NATIVE;
|
89
|
+
header->dofh_ident[DOF_ID_VERSION] = dof_version(2);
|
90
|
+
header->dofh_ident[DOF_ID_DIFVERS] = DIF_VERSION;
|
91
|
+
header->dofh_ident[DOF_ID_DIFIREG] = DIF_DIR_NREGS;
|
92
|
+
header->dofh_ident[DOF_ID_DIFTREG] = DIF_DTR_NREGS;
|
93
|
+
|
94
|
+
for (i = DOF_ID_PAD; i < DOF_ID_SIZE; i++)
|
95
|
+
header->dofh_ident[i] = 0;
|
96
|
+
|
97
|
+
header->dofh_flags = 0;
|
98
|
+
|
99
|
+
header->dofh_hdrsize = sizeof(dof_hdr_t);
|
100
|
+
header->dofh_secsize = sizeof(dof_sec_t);
|
101
|
+
header->dofh_secoff = sizeof(dof_hdr_t);
|
102
|
+
|
103
|
+
header->dofh_loadsz = 0;
|
104
|
+
header->dofh_filesz = 0;
|
105
|
+
header->dofh_pad = 0;
|
106
|
+
}
|
107
|
+
|
108
|
+
static size_t
|
109
|
+
add_header(usdt_dof_file_t *file, size_t offset, usdt_dof_section_t *section)
|
110
|
+
{
|
111
|
+
dof_sec_t header;
|
112
|
+
|
113
|
+
header.dofs_flags = section->flags;
|
114
|
+
header.dofs_type = section->type;
|
115
|
+
header.dofs_offset = section->offset;
|
116
|
+
header.dofs_size = section->size;
|
117
|
+
header.dofs_entsize = section->entsize;
|
118
|
+
header.dofs_align = section->align;
|
119
|
+
|
120
|
+
memcpy((file->dof + offset), &header, sizeof(dof_sec_t));
|
121
|
+
return (offset + sizeof(dof_sec_t));
|
122
|
+
}
|
123
|
+
|
124
|
+
static size_t
|
125
|
+
add_section(usdt_dof_file_t *file, size_t offset, usdt_dof_section_t *section)
|
126
|
+
{
|
127
|
+
if (section->pad > 0) {
|
128
|
+
memcpy((file->dof + offset), "\0", section->pad);
|
129
|
+
offset += section->pad;
|
130
|
+
}
|
131
|
+
|
132
|
+
memcpy((file->dof + offset), section->data, section->size);
|
133
|
+
return (offset + section->size);
|
134
|
+
}
|
135
|
+
|
136
|
+
int
|
137
|
+
usdt_dof_file_load(usdt_dof_file_t *file, const char *module)
|
138
|
+
{
|
139
|
+
dof_helper_t dh;
|
140
|
+
dof_hdr_t *dof;
|
141
|
+
int fd;
|
142
|
+
|
143
|
+
dof = (dof_hdr_t *) file->dof;
|
144
|
+
|
145
|
+
dh.dofhp_dof = (uintptr_t)dof;
|
146
|
+
dh.dofhp_addr = (uintptr_t)dof;
|
147
|
+
(void) strncpy(dh.dofhp_mod, module, sizeof (dh.dofhp_mod));
|
148
|
+
|
149
|
+
if ((fd = open(helper, O_RDWR)) < 0)
|
150
|
+
return (-1);
|
151
|
+
|
152
|
+
file->gen = load_dof(fd, &dh);
|
153
|
+
|
154
|
+
if ((close(fd)) < 0)
|
155
|
+
return (-1);
|
156
|
+
|
157
|
+
return (0);
|
158
|
+
}
|
159
|
+
|
160
|
+
void
|
161
|
+
usdt_dof_file_append_section(usdt_dof_file_t *file, usdt_dof_section_t *section)
|
162
|
+
{
|
163
|
+
usdt_dof_section_t *s;
|
164
|
+
|
165
|
+
if (file->sections == NULL) {
|
166
|
+
file->sections = section;
|
167
|
+
}
|
168
|
+
else {
|
169
|
+
for (s = file->sections; (s->next != NULL); s = s->next) ;
|
170
|
+
s->next = section;
|
171
|
+
}
|
172
|
+
}
|
173
|
+
|
174
|
+
void
|
175
|
+
usdt_dof_file_generate(usdt_dof_file_t *file, usdt_strtab_t *strtab)
|
176
|
+
{
|
177
|
+
dof_hdr_t header;
|
178
|
+
uint64_t filesz;
|
179
|
+
uint64_t loadsz;
|
180
|
+
usdt_dof_section_t *sec;
|
181
|
+
size_t offset;
|
182
|
+
|
183
|
+
dof_header(&header);
|
184
|
+
header.dofh_secnum = 6;
|
185
|
+
|
186
|
+
filesz = sizeof(dof_hdr_t) + (sizeof(dof_sec_t) * header.dofh_secnum);
|
187
|
+
loadsz = filesz;
|
188
|
+
|
189
|
+
strtab->offset = filesz;
|
190
|
+
pad_section((usdt_dof_section_t *)strtab);
|
191
|
+
filesz += strtab->size + strtab->pad;
|
192
|
+
|
193
|
+
if (strtab->flags & 1)
|
194
|
+
loadsz += strtab->size + strtab->pad;
|
195
|
+
|
196
|
+
for (sec = file->sections; sec != NULL; sec = sec->next) {
|
197
|
+
sec->offset = filesz;
|
198
|
+
pad_section(sec);
|
199
|
+
filesz += sec->size + sec->pad;
|
200
|
+
if (sec->flags & 1)
|
201
|
+
loadsz += sec->size + sec->pad;
|
202
|
+
}
|
203
|
+
|
204
|
+
header.dofh_loadsz = loadsz;
|
205
|
+
header.dofh_filesz = filesz;
|
206
|
+
memcpy(file->dof, &header, sizeof(dof_hdr_t));
|
207
|
+
|
208
|
+
offset = sizeof(dof_hdr_t);
|
209
|
+
|
210
|
+
offset = add_header(file, offset, (usdt_dof_section_t *)strtab);
|
211
|
+
|
212
|
+
for (sec = file->sections; sec != NULL; sec = sec->next)
|
213
|
+
offset = add_header(file, offset, sec);
|
214
|
+
|
215
|
+
offset = add_section(file, offset, (usdt_dof_section_t *)strtab);
|
216
|
+
|
217
|
+
for (sec = file->sections; sec != NULL; sec = sec->next)
|
218
|
+
offset = add_section(file, offset, sec);
|
219
|
+
}
|
220
|
+
|
221
|
+
usdt_dof_file_t *
|
222
|
+
usdt_dof_file_init(usdt_provider_t *provider, size_t size)
|
223
|
+
{
|
224
|
+
usdt_dof_file_t *file;
|
225
|
+
|
226
|
+
if ((file = malloc(sizeof(*file))) == NULL) {
|
227
|
+
usdt_error(provider, USDT_ERROR_MALLOC);
|
228
|
+
return (NULL);
|
229
|
+
}
|
230
|
+
|
231
|
+
if ((file->dof = valloc(size)) == NULL) {
|
232
|
+
usdt_error(provider, USDT_ERROR_VALLOC);
|
233
|
+
return (NULL);
|
234
|
+
}
|
235
|
+
|
236
|
+
file->sections = NULL;
|
237
|
+
file->size = size;
|
238
|
+
|
239
|
+
return (file);
|
240
|
+
}
|
@@ -0,0 +1,172 @@
|
|
1
|
+
#include "usdt_internal.h"
|
2
|
+
|
3
|
+
int
|
4
|
+
usdt_dof_probes_sect(usdt_dof_section_t *probes,
|
5
|
+
usdt_provider_t *provider, usdt_strtab_t *strtab)
|
6
|
+
{
|
7
|
+
usdt_probedef_t *pd;
|
8
|
+
dof_probe_t p;
|
9
|
+
dof_stridx_t type, argv;
|
10
|
+
uint8_t argc, i;
|
11
|
+
uint32_t argidx = 0;
|
12
|
+
uint32_t offidx = 0;
|
13
|
+
|
14
|
+
usdt_dof_section_init(probes, DOF_SECT_PROBES, 1);
|
15
|
+
|
16
|
+
for (pd = provider->probedefs; pd != NULL; pd = pd->next) {
|
17
|
+
argc = 0;
|
18
|
+
argv = 0;
|
19
|
+
|
20
|
+
for (i = 0; pd->types[i] != USDT_ARGTYPE_NONE && i < 6; i++) {
|
21
|
+
switch(pd->types[i]) {
|
22
|
+
case USDT_ARGTYPE_INTEGER:
|
23
|
+
type = usdt_strtab_add(strtab, "int");
|
24
|
+
break;
|
25
|
+
case USDT_ARGTYPE_STRING:
|
26
|
+
type = usdt_strtab_add(strtab, "char *");
|
27
|
+
break;
|
28
|
+
default:
|
29
|
+
break;
|
30
|
+
}
|
31
|
+
|
32
|
+
argc++;
|
33
|
+
if (argv == 0)
|
34
|
+
argv = type;
|
35
|
+
}
|
36
|
+
|
37
|
+
if (usdt_create_tracepoints(pd->probe) < 0) {
|
38
|
+
usdt_error(provider, USDT_ERROR_VALLOC);
|
39
|
+
return (-1);
|
40
|
+
}
|
41
|
+
|
42
|
+
#ifdef __x86_64__
|
43
|
+
p.dofpr_addr = (uint64_t) pd->probe->isenabled_addr;
|
44
|
+
#elif __i386__
|
45
|
+
p.dofpr_addr = (uint32_t) pd->probe->isenabled_addr;
|
46
|
+
#else
|
47
|
+
#error "only x86_64 and i386 supported"
|
48
|
+
#endif
|
49
|
+
p.dofpr_func = usdt_strtab_add(strtab, pd->function);
|
50
|
+
p.dofpr_name = usdt_strtab_add(strtab, pd->name);
|
51
|
+
p.dofpr_nargv = argv;
|
52
|
+
p.dofpr_xargv = argv;
|
53
|
+
p.dofpr_argidx = argidx;
|
54
|
+
p.dofpr_offidx = offidx;
|
55
|
+
p.dofpr_nargc = argc;
|
56
|
+
p.dofpr_xargc = argc;
|
57
|
+
p.dofpr_noffs = 1;
|
58
|
+
p.dofpr_enoffidx = offidx;
|
59
|
+
p.dofpr_nenoffs = 1;
|
60
|
+
|
61
|
+
usdt_dof_section_add_data(probes, &p, sizeof(dof_probe_t));
|
62
|
+
probes->entsize = sizeof(dof_probe_t);
|
63
|
+
|
64
|
+
argidx += argc;
|
65
|
+
offidx++;
|
66
|
+
}
|
67
|
+
|
68
|
+
return (0);
|
69
|
+
}
|
70
|
+
|
71
|
+
int
|
72
|
+
usdt_dof_prargs_sect(usdt_dof_section_t *prargs, usdt_provider_t *provider)
|
73
|
+
{
|
74
|
+
usdt_probedef_t *pd;
|
75
|
+
uint8_t i;
|
76
|
+
|
77
|
+
usdt_dof_section_init(prargs, DOF_SECT_PRARGS, 2);
|
78
|
+
prargs->entsize = 1;
|
79
|
+
|
80
|
+
for (pd = provider->probedefs; pd != NULL; pd = pd->next) {
|
81
|
+
for (i = 0; pd->types[i] != USDT_ARGTYPE_NONE && i < 6; i++)
|
82
|
+
usdt_dof_section_add_data(prargs, &i, 1);
|
83
|
+
}
|
84
|
+
if (prargs->size == 0) {
|
85
|
+
i = 0;
|
86
|
+
if (usdt_dof_section_add_data(prargs, &i, 1) < 0) {
|
87
|
+
usdt_error(provider, USDT_ERROR_MALLOC);
|
88
|
+
return (-1);
|
89
|
+
}
|
90
|
+
}
|
91
|
+
|
92
|
+
return (0);
|
93
|
+
}
|
94
|
+
|
95
|
+
int
|
96
|
+
usdt_dof_proffs_sect(usdt_dof_section_t *proffs,
|
97
|
+
usdt_provider_t *provider, char *dof)
|
98
|
+
{
|
99
|
+
usdt_probedef_t *pd;
|
100
|
+
uint32_t off;
|
101
|
+
|
102
|
+
usdt_dof_section_init(proffs, DOF_SECT_PROFFS, 3);
|
103
|
+
proffs->entsize = 4;
|
104
|
+
|
105
|
+
for (pd = provider->probedefs; pd != NULL; pd = pd->next) {
|
106
|
+
off = usdt_probe_offset(pd->probe, dof, usdt_probedef_argc(pd));
|
107
|
+
if (usdt_dof_section_add_data(proffs, &off, 4) < 0) {
|
108
|
+
usdt_error(provider, USDT_ERROR_MALLOC);
|
109
|
+
return (-1);
|
110
|
+
}
|
111
|
+
}
|
112
|
+
|
113
|
+
return (0);
|
114
|
+
}
|
115
|
+
|
116
|
+
int
|
117
|
+
usdt_dof_prenoffs_sect(usdt_dof_section_t *prenoffs,
|
118
|
+
usdt_provider_t *provider, char *dof)
|
119
|
+
{
|
120
|
+
usdt_probedef_t *pd;
|
121
|
+
uint32_t off;
|
122
|
+
|
123
|
+
usdt_dof_section_init(prenoffs, DOF_SECT_PRENOFFS, 4);
|
124
|
+
prenoffs->entsize = 4;
|
125
|
+
|
126
|
+
for (pd = provider->probedefs; pd != NULL; pd = pd->next) {
|
127
|
+
off = usdt_is_enabled_offset(pd->probe, dof);
|
128
|
+
if (usdt_dof_section_add_data(prenoffs, &off, 4) < 0) {
|
129
|
+
usdt_error(provider, USDT_ERROR_MALLOC);
|
130
|
+
return (-1);
|
131
|
+
}
|
132
|
+
}
|
133
|
+
|
134
|
+
return (0);
|
135
|
+
}
|
136
|
+
|
137
|
+
int
|
138
|
+
usdt_dof_provider_sect(usdt_dof_section_t *provider_s, usdt_provider_t *provider)
|
139
|
+
{
|
140
|
+
dof_provider_t p;
|
141
|
+
|
142
|
+
usdt_dof_section_init(provider_s, DOF_SECT_PROVIDER, 5);
|
143
|
+
|
144
|
+
p.dofpv_strtab = 0;
|
145
|
+
p.dofpv_probes = 1;
|
146
|
+
p.dofpv_prargs = 2;
|
147
|
+
p.dofpv_proffs = 3;
|
148
|
+
p.dofpv_prenoffs = 4;
|
149
|
+
p.dofpv_name = 1; // provider name always first strtab entry.
|
150
|
+
p.dofpv_provattr = DOF_ATTR(DTRACE_STABILITY_EVOLVING,
|
151
|
+
DTRACE_STABILITY_EVOLVING,
|
152
|
+
DTRACE_STABILITY_EVOLVING);
|
153
|
+
p.dofpv_modattr = DOF_ATTR(DTRACE_STABILITY_PRIVATE,
|
154
|
+
DTRACE_STABILITY_PRIVATE,
|
155
|
+
DTRACE_STABILITY_EVOLVING);
|
156
|
+
p.dofpv_funcattr = DOF_ATTR(DTRACE_STABILITY_PRIVATE,
|
157
|
+
DTRACE_STABILITY_PRIVATE,
|
158
|
+
DTRACE_STABILITY_EVOLVING);
|
159
|
+
p.dofpv_nameattr = DOF_ATTR(DTRACE_STABILITY_EVOLVING,
|
160
|
+
DTRACE_STABILITY_EVOLVING,
|
161
|
+
DTRACE_STABILITY_EVOLVING);
|
162
|
+
p.dofpv_argsattr = DOF_ATTR(DTRACE_STABILITY_EVOLVING,
|
163
|
+
DTRACE_STABILITY_EVOLVING,
|
164
|
+
DTRACE_STABILITY_EVOLVING);
|
165
|
+
|
166
|
+
if ((usdt_dof_section_add_data(provider_s, &p, sizeof(p))) < 0) {
|
167
|
+
usdt_error(provider, USDT_ERROR_MALLOC);
|
168
|
+
return (-1);
|
169
|
+
}
|
170
|
+
|
171
|
+
return (0);
|
172
|
+
}
|
@@ -0,0 +1,100 @@
|
|
1
|
+
#include <sys/dtrace.h>
|
2
|
+
#include <sys/types.h>
|
3
|
+
#include <sys/mman.h>
|
4
|
+
|
5
|
+
#include <errno.h>
|
6
|
+
#include <string.h>
|
7
|
+
#include <fcntl.h>
|
8
|
+
#include <unistd.h>
|
9
|
+
#include <stdint.h>
|
10
|
+
#include <assert.h>
|
11
|
+
|
12
|
+
#ifndef __APPLE__
|
13
|
+
/* solaris and freebsd */
|
14
|
+
#include <stdlib.h>
|
15
|
+
#endif
|
16
|
+
|
17
|
+
#define FUNC_SIZE 32
|
18
|
+
|
19
|
+
#include "usdt.h"
|
20
|
+
|
21
|
+
extern void usdt_tracepoint_isenabled(void);
|
22
|
+
extern void usdt_tracepoint_probe(void);
|
23
|
+
extern void usdt_tracepoint_end(void);
|
24
|
+
extern void usdt_probe_args(void *, int, void**);
|
25
|
+
|
26
|
+
/*
|
27
|
+
typedef enum usdt_argtype {
|
28
|
+
USDT_ARGTYPE_NONE = 0,
|
29
|
+
USDT_ARGTYPE_STRING,
|
30
|
+
USDT_ARGTYPE_INTEGER
|
31
|
+
} usdt_argtype_t;
|
32
|
+
*/
|
33
|
+
|
34
|
+
uint32_t usdt_probe_offset(usdt_probe_t *probe, char *dof, uint8_t argc);
|
35
|
+
uint32_t usdt_is_enabled_offset(usdt_probe_t *probe, char *dof);
|
36
|
+
int usdt_create_tracepoints(usdt_probe_t *probe);
|
37
|
+
|
38
|
+
uint8_t usdt_probedef_argc(usdt_probedef_t *probedef);
|
39
|
+
|
40
|
+
typedef struct usdt_dof_section {
|
41
|
+
dof_secidx_t index;
|
42
|
+
uint32_t type;
|
43
|
+
uint32_t flags;
|
44
|
+
uint32_t align;
|
45
|
+
uint64_t offset;
|
46
|
+
uint64_t size;
|
47
|
+
uint32_t entsize;
|
48
|
+
size_t pad;
|
49
|
+
struct usdt_dof_section *next;
|
50
|
+
char *data;
|
51
|
+
} usdt_dof_section_t;
|
52
|
+
|
53
|
+
int usdt_dof_section_init(usdt_dof_section_t *section,
|
54
|
+
uint32_t type, dof_secidx_t index);
|
55
|
+
int usdt_dof_section_add_data(usdt_dof_section_t *section,
|
56
|
+
void *data, size_t length);
|
57
|
+
|
58
|
+
typedef struct usdt_strtab {
|
59
|
+
dof_secidx_t index;
|
60
|
+
uint32_t type;
|
61
|
+
uint32_t flags;
|
62
|
+
uint32_t align;
|
63
|
+
uint64_t offset;
|
64
|
+
uint64_t size;
|
65
|
+
uint32_t entsize;
|
66
|
+
size_t pad;
|
67
|
+
int strindex;
|
68
|
+
char *data;
|
69
|
+
} usdt_strtab_t;
|
70
|
+
|
71
|
+
int usdt_strtab_init(usdt_strtab_t *strtab, dof_secidx_t index);
|
72
|
+
dof_stridx_t usdt_strtab_add(usdt_strtab_t *strtab, const char *string);
|
73
|
+
char *usdt_strtab_header(usdt_strtab_t *strtab);
|
74
|
+
size_t usdt_strtab_size(usdt_strtab_t *strtab);
|
75
|
+
|
76
|
+
size_t usdt_provider_dof_size(usdt_provider_t *provider, usdt_strtab_t *strtab);
|
77
|
+
|
78
|
+
typedef struct usdt_dof_file {
|
79
|
+
char *dof;
|
80
|
+
int gen;
|
81
|
+
size_t size;
|
82
|
+
usdt_dof_section_t *sections;
|
83
|
+
} usdt_dof_file_t;
|
84
|
+
|
85
|
+
usdt_dof_file_t *usdt_dof_file_init(usdt_provider_t *provider, size_t size);
|
86
|
+
void usdt_dof_file_append_section(usdt_dof_file_t *file, usdt_dof_section_t *section);
|
87
|
+
void usdt_dof_file_generate(usdt_dof_file_t *file, usdt_strtab_t *strtab);
|
88
|
+
int usdt_dof_file_load(usdt_dof_file_t *file, const char *module);
|
89
|
+
|
90
|
+
int usdt_dof_probes_sect(usdt_dof_section_t *probes,
|
91
|
+
usdt_provider_t *provider, usdt_strtab_t *strtab);
|
92
|
+
int usdt_dof_prargs_sect(usdt_dof_section_t *prargs,
|
93
|
+
usdt_provider_t *provider);
|
94
|
+
int usdt_dof_proffs_sect(usdt_dof_section_t *proffs,
|
95
|
+
usdt_provider_t *provider, char *dof);
|
96
|
+
int usdt_dof_prenoffs_sect(usdt_dof_section_t *prenoffs,
|
97
|
+
usdt_provider_t *provider, char *dof);
|
98
|
+
int usdt_dof_provider_sect(usdt_dof_section_t *provider_s,
|
99
|
+
usdt_provider_t *provider);
|
100
|
+
|
@@ -0,0 +1,66 @@
|
|
1
|
+
#include "usdt_internal.h"
|
2
|
+
|
3
|
+
#ifdef __APPLE__
|
4
|
+
|
5
|
+
uint32_t
|
6
|
+
usdt_probe_offset(usdt_probe_t *probe, char *dof, uint8_t argc)
|
7
|
+
{
|
8
|
+
uint32_t offset;
|
9
|
+
#ifdef __x86_64__
|
10
|
+
offset = ((uint64_t) probe->probe_addr - (uint64_t) dof + 2);
|
11
|
+
#elif __i386__
|
12
|
+
offset = ((uint32_t) probe->probe_addr - (uint32_t) dof + 2);
|
13
|
+
#else
|
14
|
+
#error "only x86_64 and i386 supported"
|
15
|
+
#endif
|
16
|
+
return (offset);
|
17
|
+
}
|
18
|
+
|
19
|
+
uint32_t
|
20
|
+
usdt_is_enabled_offset(usdt_probe_t *probe, char *dof)
|
21
|
+
{
|
22
|
+
uint32_t offset;
|
23
|
+
#ifdef __x86_64__
|
24
|
+
offset = ((uint64_t) probe->isenabled_addr - (uint64_t) dof + 2);
|
25
|
+
#elif __i386__
|
26
|
+
offset = ((uint32_t) probe->isenabled_addr - (uint32_t) dof + 6);
|
27
|
+
#else
|
28
|
+
#error "only x86_64 and i386 supported"
|
29
|
+
#endif
|
30
|
+
return (offset);
|
31
|
+
}
|
32
|
+
|
33
|
+
#else /* solaris and freebsd */
|
34
|
+
|
35
|
+
uint32_t
|
36
|
+
usdt_probe_offset(usdt_probe_t *probe, char *dof, uint8_t argc)
|
37
|
+
{
|
38
|
+
return (12);
|
39
|
+
}
|
40
|
+
|
41
|
+
uint32_t
|
42
|
+
usdt_is_enabled_offset(usdt_probe_t *probe, char *dof)
|
43
|
+
{
|
44
|
+
return (6);
|
45
|
+
}
|
46
|
+
|
47
|
+
#endif
|
48
|
+
|
49
|
+
int
|
50
|
+
usdt_create_tracepoints(usdt_probe_t *probe)
|
51
|
+
{
|
52
|
+
/* ensure that the tracepoints will fit the heap we're allocating */
|
53
|
+
assert((usdt_tracepoint_end - usdt_tracepoint_isenabled) < FUNC_SIZE);
|
54
|
+
|
55
|
+
if ((probe->isenabled_addr = valloc(FUNC_SIZE)) == NULL) {
|
56
|
+
return (-1);
|
57
|
+
}
|
58
|
+
probe->probe_addr = probe->isenabled_addr +
|
59
|
+
(usdt_tracepoint_probe - usdt_tracepoint_isenabled);
|
60
|
+
|
61
|
+
memcpy(probe->isenabled_addr, usdt_tracepoint_isenabled, FUNC_SIZE);
|
62
|
+
mprotect((void *)probe->isenabled_addr, FUNC_SIZE,
|
63
|
+
PROT_READ | PROT_WRITE | PROT_EXEC);
|
64
|
+
|
65
|
+
return (0);
|
66
|
+
}
|