Print this page
4474 DTrace Userland CTF Support
4475 DTrace userland Keyword
4476 DTrace tests should be better citizens
4479 pid provider types
4480 dof emulation missing checks
Reviewed by: Bryan Cantrill <bryan@joyent.com>
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/lib/libdtrace/common/dt_module.c
+++ new/usr/src/lib/libdtrace/common/dt_module.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
↓ open down ↓ |
14 lines elided |
↑ open up ↑ |
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
24 24 */
25 +/*
26 + * Copyright (c) 2013, Joyent, Inc. All rights reserved.
27 + */
25 28
26 29 #include <sys/types.h>
27 30 #include <sys/modctl.h>
28 31 #include <sys/kobj.h>
29 32 #include <sys/kobj_impl.h>
30 33 #include <sys/sysmacros.h>
31 34 #include <sys/elf.h>
32 35 #include <sys/task.h>
33 36
34 37 #include <unistd.h>
35 38 #include <project.h>
36 39 #include <strings.h>
37 40 #include <stdlib.h>
38 41 #include <libelf.h>
39 42 #include <limits.h>
40 43 #include <assert.h>
41 44 #include <errno.h>
42 45 #include <dirent.h>
43 46
44 47 #include <dt_strtab.h>
45 48 #include <dt_module.h>
46 49 #include <dt_impl.h>
47 50
48 51 static const char *dt_module_strtab; /* active strtab for qsort callbacks */
49 52
50 53 static void
51 54 dt_module_symhash_insert(dt_module_t *dmp, const char *name, uint_t id)
52 55 {
53 56 dt_sym_t *dsp = &dmp->dm_symchains[dmp->dm_symfree];
54 57 uint_t h;
55 58
56 59 assert(dmp->dm_symfree < dmp->dm_nsymelems + 1);
57 60
58 61 dsp->ds_symid = id;
59 62 h = dt_strtab_hash(name, NULL) % dmp->dm_nsymbuckets;
60 63 dsp->ds_next = dmp->dm_symbuckets[h];
61 64 dmp->dm_symbuckets[h] = dmp->dm_symfree++;
62 65 }
63 66
64 67 static uint_t
65 68 dt_module_syminit32(dt_module_t *dmp)
66 69 {
67 70 #if STT_NUM != (STT_TLS + 1)
68 71 #error "STT_NUM has grown. update dt_module_syminit32()"
69 72 #endif
70 73
71 74 const Elf32_Sym *sym = dmp->dm_symtab.cts_data;
72 75 const char *base = dmp->dm_strtab.cts_data;
73 76 size_t ss_size = dmp->dm_strtab.cts_size;
74 77 uint_t i, n = dmp->dm_nsymelems;
75 78 uint_t asrsv = 0;
76 79
77 80 for (i = 0; i < n; i++, sym++) {
78 81 const char *name = base + sym->st_name;
79 82 uchar_t type = ELF32_ST_TYPE(sym->st_info);
80 83
81 84 if (type >= STT_NUM || type == STT_SECTION)
82 85 continue; /* skip sections and unknown types */
83 86
84 87 if (sym->st_name == 0 || sym->st_name >= ss_size)
85 88 continue; /* skip null or invalid names */
86 89
87 90 if (sym->st_value != 0 &&
88 91 (ELF32_ST_BIND(sym->st_info) != STB_LOCAL || sym->st_size))
89 92 asrsv++; /* reserve space in the address map */
90 93
91 94 dt_module_symhash_insert(dmp, name, i);
92 95 }
93 96
94 97 return (asrsv);
95 98 }
96 99
97 100 static uint_t
98 101 dt_module_syminit64(dt_module_t *dmp)
99 102 {
100 103 #if STT_NUM != (STT_TLS + 1)
101 104 #error "STT_NUM has grown. update dt_module_syminit64()"
102 105 #endif
103 106
104 107 const Elf64_Sym *sym = dmp->dm_symtab.cts_data;
105 108 const char *base = dmp->dm_strtab.cts_data;
106 109 size_t ss_size = dmp->dm_strtab.cts_size;
107 110 uint_t i, n = dmp->dm_nsymelems;
108 111 uint_t asrsv = 0;
109 112
110 113 for (i = 0; i < n; i++, sym++) {
111 114 const char *name = base + sym->st_name;
112 115 uchar_t type = ELF64_ST_TYPE(sym->st_info);
113 116
114 117 if (type >= STT_NUM || type == STT_SECTION)
115 118 continue; /* skip sections and unknown types */
116 119
117 120 if (sym->st_name == 0 || sym->st_name >= ss_size)
118 121 continue; /* skip null or invalid names */
119 122
120 123 if (sym->st_value != 0 &&
121 124 (ELF64_ST_BIND(sym->st_info) != STB_LOCAL || sym->st_size))
122 125 asrsv++; /* reserve space in the address map */
123 126
124 127 dt_module_symhash_insert(dmp, name, i);
125 128 }
126 129
127 130 return (asrsv);
128 131 }
129 132
130 133 /*
131 134 * Sort comparison function for 32-bit symbol address-to-name lookups. We sort
132 135 * symbols by value. If values are equal, we prefer the symbol that is
133 136 * non-zero sized, typed, not weak, or lexically first, in that order.
134 137 */
135 138 static int
136 139 dt_module_symcomp32(const void *lp, const void *rp)
137 140 {
138 141 Elf32_Sym *lhs = *((Elf32_Sym **)lp);
139 142 Elf32_Sym *rhs = *((Elf32_Sym **)rp);
140 143
141 144 if (lhs->st_value != rhs->st_value)
142 145 return (lhs->st_value > rhs->st_value ? 1 : -1);
143 146
144 147 if ((lhs->st_size == 0) != (rhs->st_size == 0))
145 148 return (lhs->st_size == 0 ? 1 : -1);
146 149
147 150 if ((ELF32_ST_TYPE(lhs->st_info) == STT_NOTYPE) !=
148 151 (ELF32_ST_TYPE(rhs->st_info) == STT_NOTYPE))
149 152 return (ELF32_ST_TYPE(lhs->st_info) == STT_NOTYPE ? 1 : -1);
150 153
151 154 if ((ELF32_ST_BIND(lhs->st_info) == STB_WEAK) !=
152 155 (ELF32_ST_BIND(rhs->st_info) == STB_WEAK))
153 156 return (ELF32_ST_BIND(lhs->st_info) == STB_WEAK ? 1 : -1);
154 157
155 158 return (strcmp(dt_module_strtab + lhs->st_name,
156 159 dt_module_strtab + rhs->st_name));
157 160 }
158 161
159 162 /*
160 163 * Sort comparison function for 64-bit symbol address-to-name lookups. We sort
161 164 * symbols by value. If values are equal, we prefer the symbol that is
162 165 * non-zero sized, typed, not weak, or lexically first, in that order.
163 166 */
164 167 static int
165 168 dt_module_symcomp64(const void *lp, const void *rp)
166 169 {
167 170 Elf64_Sym *lhs = *((Elf64_Sym **)lp);
168 171 Elf64_Sym *rhs = *((Elf64_Sym **)rp);
169 172
170 173 if (lhs->st_value != rhs->st_value)
171 174 return (lhs->st_value > rhs->st_value ? 1 : -1);
172 175
173 176 if ((lhs->st_size == 0) != (rhs->st_size == 0))
174 177 return (lhs->st_size == 0 ? 1 : -1);
175 178
176 179 if ((ELF64_ST_TYPE(lhs->st_info) == STT_NOTYPE) !=
177 180 (ELF64_ST_TYPE(rhs->st_info) == STT_NOTYPE))
178 181 return (ELF64_ST_TYPE(lhs->st_info) == STT_NOTYPE ? 1 : -1);
179 182
180 183 if ((ELF64_ST_BIND(lhs->st_info) == STB_WEAK) !=
181 184 (ELF64_ST_BIND(rhs->st_info) == STB_WEAK))
182 185 return (ELF64_ST_BIND(lhs->st_info) == STB_WEAK ? 1 : -1);
183 186
184 187 return (strcmp(dt_module_strtab + lhs->st_name,
185 188 dt_module_strtab + rhs->st_name));
186 189 }
187 190
188 191 static void
189 192 dt_module_symsort32(dt_module_t *dmp)
190 193 {
191 194 Elf32_Sym *symtab = (Elf32_Sym *)dmp->dm_symtab.cts_data;
192 195 Elf32_Sym **sympp = (Elf32_Sym **)dmp->dm_asmap;
193 196 const dt_sym_t *dsp = dmp->dm_symchains + 1;
194 197 uint_t i, n = dmp->dm_symfree;
195 198
196 199 for (i = 1; i < n; i++, dsp++) {
197 200 Elf32_Sym *sym = symtab + dsp->ds_symid;
198 201 if (sym->st_value != 0 &&
199 202 (ELF32_ST_BIND(sym->st_info) != STB_LOCAL || sym->st_size))
200 203 *sympp++ = sym;
201 204 }
202 205
203 206 dmp->dm_aslen = (uint_t)(sympp - (Elf32_Sym **)dmp->dm_asmap);
204 207 assert(dmp->dm_aslen <= dmp->dm_asrsv);
205 208
206 209 dt_module_strtab = dmp->dm_strtab.cts_data;
207 210 qsort(dmp->dm_asmap, dmp->dm_aslen,
208 211 sizeof (Elf32_Sym *), dt_module_symcomp32);
209 212 dt_module_strtab = NULL;
210 213 }
211 214
212 215 static void
213 216 dt_module_symsort64(dt_module_t *dmp)
214 217 {
215 218 Elf64_Sym *symtab = (Elf64_Sym *)dmp->dm_symtab.cts_data;
216 219 Elf64_Sym **sympp = (Elf64_Sym **)dmp->dm_asmap;
217 220 const dt_sym_t *dsp = dmp->dm_symchains + 1;
218 221 uint_t i, n = dmp->dm_symfree;
219 222
220 223 for (i = 1; i < n; i++, dsp++) {
221 224 Elf64_Sym *sym = symtab + dsp->ds_symid;
222 225 if (sym->st_value != 0 &&
223 226 (ELF64_ST_BIND(sym->st_info) != STB_LOCAL || sym->st_size))
224 227 *sympp++ = sym;
225 228 }
226 229
227 230 dmp->dm_aslen = (uint_t)(sympp - (Elf64_Sym **)dmp->dm_asmap);
228 231 assert(dmp->dm_aslen <= dmp->dm_asrsv);
229 232
230 233 dt_module_strtab = dmp->dm_strtab.cts_data;
231 234 qsort(dmp->dm_asmap, dmp->dm_aslen,
232 235 sizeof (Elf64_Sym *), dt_module_symcomp64);
233 236 dt_module_strtab = NULL;
234 237 }
235 238
236 239 static GElf_Sym *
237 240 dt_module_symgelf32(const Elf32_Sym *src, GElf_Sym *dst)
238 241 {
239 242 if (dst != NULL) {
240 243 dst->st_name = src->st_name;
241 244 dst->st_info = src->st_info;
242 245 dst->st_other = src->st_other;
243 246 dst->st_shndx = src->st_shndx;
244 247 dst->st_value = src->st_value;
245 248 dst->st_size = src->st_size;
246 249 }
247 250
248 251 return (dst);
249 252 }
250 253
251 254 static GElf_Sym *
252 255 dt_module_symgelf64(const Elf64_Sym *src, GElf_Sym *dst)
253 256 {
254 257 if (dst != NULL)
255 258 bcopy(src, dst, sizeof (GElf_Sym));
256 259
257 260 return (dst);
258 261 }
259 262
260 263 static GElf_Sym *
261 264 dt_module_symname32(dt_module_t *dmp, const char *name,
262 265 GElf_Sym *symp, uint_t *idp)
263 266 {
264 267 const Elf32_Sym *symtab = dmp->dm_symtab.cts_data;
265 268 const char *strtab = dmp->dm_strtab.cts_data;
266 269
267 270 const Elf32_Sym *sym;
268 271 const dt_sym_t *dsp;
269 272 uint_t i, h;
270 273
271 274 if (dmp->dm_nsymelems == 0)
272 275 return (NULL);
273 276
274 277 h = dt_strtab_hash(name, NULL) % dmp->dm_nsymbuckets;
275 278
276 279 for (i = dmp->dm_symbuckets[h]; i != 0; i = dsp->ds_next) {
277 280 dsp = &dmp->dm_symchains[i];
278 281 sym = symtab + dsp->ds_symid;
279 282
280 283 if (strcmp(name, strtab + sym->st_name) == 0) {
281 284 if (idp != NULL)
282 285 *idp = dsp->ds_symid;
283 286 return (dt_module_symgelf32(sym, symp));
284 287 }
285 288 }
286 289
287 290 return (NULL);
288 291 }
289 292
290 293 static GElf_Sym *
291 294 dt_module_symname64(dt_module_t *dmp, const char *name,
292 295 GElf_Sym *symp, uint_t *idp)
293 296 {
294 297 const Elf64_Sym *symtab = dmp->dm_symtab.cts_data;
295 298 const char *strtab = dmp->dm_strtab.cts_data;
296 299
297 300 const Elf64_Sym *sym;
298 301 const dt_sym_t *dsp;
299 302 uint_t i, h;
300 303
301 304 if (dmp->dm_nsymelems == 0)
302 305 return (NULL);
303 306
304 307 h = dt_strtab_hash(name, NULL) % dmp->dm_nsymbuckets;
305 308
306 309 for (i = dmp->dm_symbuckets[h]; i != 0; i = dsp->ds_next) {
307 310 dsp = &dmp->dm_symchains[i];
308 311 sym = symtab + dsp->ds_symid;
309 312
310 313 if (strcmp(name, strtab + sym->st_name) == 0) {
311 314 if (idp != NULL)
312 315 *idp = dsp->ds_symid;
313 316 return (dt_module_symgelf64(sym, symp));
314 317 }
315 318 }
316 319
317 320 return (NULL);
318 321 }
319 322
320 323 static GElf_Sym *
321 324 dt_module_symaddr32(dt_module_t *dmp, GElf_Addr addr,
322 325 GElf_Sym *symp, uint_t *idp)
323 326 {
324 327 const Elf32_Sym **asmap = (const Elf32_Sym **)dmp->dm_asmap;
325 328 const Elf32_Sym *symtab = dmp->dm_symtab.cts_data;
326 329 const Elf32_Sym *sym;
327 330
328 331 uint_t i, mid, lo = 0, hi = dmp->dm_aslen - 1;
329 332 Elf32_Addr v;
330 333
331 334 if (dmp->dm_aslen == 0)
332 335 return (NULL);
333 336
334 337 while (hi - lo > 1) {
335 338 mid = (lo + hi) / 2;
336 339 if (addr >= asmap[mid]->st_value)
337 340 lo = mid;
338 341 else
339 342 hi = mid;
340 343 }
341 344
342 345 i = addr < asmap[hi]->st_value ? lo : hi;
343 346 sym = asmap[i];
344 347 v = sym->st_value;
345 348
346 349 /*
347 350 * If the previous entry has the same value, improve our choice. The
348 351 * order of equal-valued symbols is determined by the comparison func.
349 352 */
350 353 while (i-- != 0 && asmap[i]->st_value == v)
351 354 sym = asmap[i];
352 355
353 356 if (addr - sym->st_value < MAX(sym->st_size, 1)) {
354 357 if (idp != NULL)
355 358 *idp = (uint_t)(sym - symtab);
356 359 return (dt_module_symgelf32(sym, symp));
357 360 }
358 361
359 362 return (NULL);
360 363 }
361 364
362 365 static GElf_Sym *
363 366 dt_module_symaddr64(dt_module_t *dmp, GElf_Addr addr,
364 367 GElf_Sym *symp, uint_t *idp)
365 368 {
366 369 const Elf64_Sym **asmap = (const Elf64_Sym **)dmp->dm_asmap;
367 370 const Elf64_Sym *symtab = dmp->dm_symtab.cts_data;
368 371 const Elf64_Sym *sym;
369 372
370 373 uint_t i, mid, lo = 0, hi = dmp->dm_aslen - 1;
371 374 Elf64_Addr v;
372 375
373 376 if (dmp->dm_aslen == 0)
374 377 return (NULL);
375 378
376 379 while (hi - lo > 1) {
377 380 mid = (lo + hi) / 2;
378 381 if (addr >= asmap[mid]->st_value)
379 382 lo = mid;
380 383 else
381 384 hi = mid;
382 385 }
383 386
384 387 i = addr < asmap[hi]->st_value ? lo : hi;
385 388 sym = asmap[i];
386 389 v = sym->st_value;
387 390
388 391 /*
389 392 * If the previous entry has the same value, improve our choice. The
390 393 * order of equal-valued symbols is determined by the comparison func.
391 394 */
392 395 while (i-- != 0 && asmap[i]->st_value == v)
393 396 sym = asmap[i];
394 397
395 398 if (addr - sym->st_value < MAX(sym->st_size, 1)) {
396 399 if (idp != NULL)
397 400 *idp = (uint_t)(sym - symtab);
398 401 return (dt_module_symgelf64(sym, symp));
399 402 }
400 403
401 404 return (NULL);
402 405 }
403 406
404 407 static const dt_modops_t dt_modops_32 = {
405 408 dt_module_syminit32,
406 409 dt_module_symsort32,
407 410 dt_module_symname32,
408 411 dt_module_symaddr32
409 412 };
410 413
↓ open down ↓ |
376 lines elided |
↑ open up ↑ |
411 414 static const dt_modops_t dt_modops_64 = {
412 415 dt_module_syminit64,
413 416 dt_module_symsort64,
414 417 dt_module_symname64,
415 418 dt_module_symaddr64
416 419 };
417 420
418 421 dt_module_t *
419 422 dt_module_create(dtrace_hdl_t *dtp, const char *name)
420 423 {
424 + long pid;
425 + char *eptr;
426 + dt_ident_t *idp;
421 427 uint_t h = dt_strtab_hash(name, NULL) % dtp->dt_modbuckets;
422 428 dt_module_t *dmp;
423 429
424 430 for (dmp = dtp->dt_mods[h]; dmp != NULL; dmp = dmp->dm_next) {
425 431 if (strcmp(dmp->dm_name, name) == 0)
426 432 return (dmp);
427 433 }
428 434
429 435 if ((dmp = malloc(sizeof (dt_module_t))) == NULL)
430 436 return (NULL); /* caller must handle allocation failure */
431 437
432 438 bzero(dmp, sizeof (dt_module_t));
433 439 (void) strlcpy(dmp->dm_name, name, sizeof (dmp->dm_name));
↓ open down ↓ |
3 lines elided |
↑ open up ↑ |
434 440 dt_list_append(&dtp->dt_modlist, dmp);
435 441 dmp->dm_next = dtp->dt_mods[h];
436 442 dtp->dt_mods[h] = dmp;
437 443 dtp->dt_nmods++;
438 444
439 445 if (dtp->dt_conf.dtc_ctfmodel == CTF_MODEL_LP64)
440 446 dmp->dm_ops = &dt_modops_64;
441 447 else
442 448 dmp->dm_ops = &dt_modops_32;
443 449
450 + /*
451 + * Modules for userland processes are special. They always refer to a
452 + * specific process and have a copy of their CTF data from a specific
453 + * instant in time. Any dt_module_t that begins with 'pid' is a module
454 + * for a specific process, much like how any probe description that
455 + * begins with 'pid' is special. pid123 refers to process 123. A module
456 + * that is just 'pid' refers specifically to pid$target. This is
457 + * generally done as D does not currently allow for macros to be
458 + * evaluated when working with types.
459 + */
460 + if (strncmp(dmp->dm_name, "pid", 3) == 0) {
461 + errno = 0;
462 + if (dmp->dm_name[3] == '\0') {
463 + idp = dt_idhash_lookup(dtp->dt_macros, "target");
464 + if (idp != NULL && idp->di_id != 0)
465 + dmp->dm_pid = idp->di_id;
466 + } else {
467 + pid = strtol(dmp->dm_name + 3, &eptr, 10);
468 + if (errno == 0 && *eptr == '\0')
469 + dmp->dm_pid = (pid_t)pid;
470 + else
471 + dt_dprintf("encountered malformed pid "
472 + "module: %s\n", dmp->dm_name);
473 + }
474 + }
475 +
444 476 return (dmp);
445 477 }
446 478
447 479 dt_module_t *
448 480 dt_module_lookup_by_name(dtrace_hdl_t *dtp, const char *name)
449 481 {
450 482 uint_t h = dt_strtab_hash(name, NULL) % dtp->dt_modbuckets;
451 483 dt_module_t *dmp;
452 484
453 485 for (dmp = dtp->dt_mods[h]; dmp != NULL; dmp = dmp->dm_next) {
454 486 if (strcmp(dmp->dm_name, name) == 0)
455 487 return (dmp);
456 488 }
457 489
458 490 return (NULL);
459 491 }
460 492
461 493 /*ARGSUSED*/
462 494 dt_module_t *
463 495 dt_module_lookup_by_ctf(dtrace_hdl_t *dtp, ctf_file_t *ctfp)
464 496 {
465 497 return (ctfp ? ctf_getspecific(ctfp) : NULL);
466 498 }
467 499
468 500 static int
469 501 dt_module_load_sect(dtrace_hdl_t *dtp, dt_module_t *dmp, ctf_sect_t *ctsp)
470 502 {
471 503 const char *s;
472 504 size_t shstrs;
473 505 GElf_Shdr sh;
474 506 Elf_Data *dp;
475 507 Elf_Scn *sp;
476 508
477 509 if (elf_getshdrstrndx(dmp->dm_elf, &shstrs) == -1)
478 510 return (dt_set_errno(dtp, EDT_NOTLOADED));
479 511
480 512 for (sp = NULL; (sp = elf_nextscn(dmp->dm_elf, sp)) != NULL; ) {
481 513 if (gelf_getshdr(sp, &sh) == NULL || sh.sh_type == SHT_NULL ||
482 514 (s = elf_strptr(dmp->dm_elf, shstrs, sh.sh_name)) == NULL)
483 515 continue; /* skip any malformed sections */
484 516
485 517 if (sh.sh_type == ctsp->cts_type &&
486 518 sh.sh_entsize == ctsp->cts_entsize &&
487 519 strcmp(s, ctsp->cts_name) == 0)
488 520 break; /* section matches specification */
489 521 }
490 522
491 523 /*
492 524 * If the section isn't found, return success but leave cts_data set
493 525 * to NULL and cts_size set to zero for our caller.
494 526 */
495 527 if (sp == NULL || (dp = elf_getdata(sp, NULL)) == NULL)
496 528 return (0);
↓ open down ↓ |
43 lines elided |
↑ open up ↑ |
497 529
498 530 ctsp->cts_data = dp->d_buf;
499 531 ctsp->cts_size = dp->d_size;
500 532
501 533 dt_dprintf("loaded %s [%s] (%lu bytes)\n",
502 534 dmp->dm_name, ctsp->cts_name, (ulong_t)ctsp->cts_size);
503 535
504 536 return (0);
505 537 }
506 538
539 +typedef struct dt_module_cb_arg {
540 + struct ps_prochandle *dpa_proc;
541 + dtrace_hdl_t *dpa_dtp;
542 + dt_module_t *dpa_dmp;
543 + uint_t dpa_count;
544 +} dt_module_cb_arg_t;
545 +
546 +/* ARGSUSED */
547 +static int
548 +dt_module_load_proc_count(void *arg, const prmap_t *prmap, const char *obj)
549 +{
550 + ctf_file_t *fp;
551 + dt_module_cb_arg_t *dcp = arg;
552 +
553 + /* Try to grab a ctf container if it exists */
554 + fp = Pname_to_ctf(dcp->dpa_proc, obj);
555 + if (fp != NULL)
556 + dcp->dpa_count++;
557 + return (0);
558 +}
559 +
560 +/* ARGSUSED */
561 +static int
562 +dt_module_load_proc_build(void *arg, const prmap_t *prmap, const char *obj)
563 +{
564 + ctf_file_t *fp;
565 + char buf[MAXPATHLEN], *p;
566 + dt_module_cb_arg_t *dcp = arg;
567 + int count = dcp->dpa_count;
568 + Lmid_t lmid;
569 +
570 + fp = Pname_to_ctf(dcp->dpa_proc, obj);
571 + if (fp == NULL)
572 + return (0);
573 + fp = ctf_dup(fp);
574 + if (fp == NULL)
575 + return (0);
576 + dcp->dpa_dmp->dm_libctfp[count] = fp;
577 + /*
578 + * While it'd be nice to simply use objname here, because of our prior
579 + * actions we'll always get a resolved object name to its on disk file.
580 + * Like the pid provider, we need to tell a bit of a lie here. The type
581 + * that the user thinks of is in terms of the libraries they requested,
582 + * eg. libc.so.1, they don't care about the fact that it's
583 + * libc_hwcap.so.1.
584 + */
585 + (void) Pobjname(dcp->dpa_proc, prmap->pr_vaddr, buf, sizeof (buf));
586 + if ((p = strrchr(buf, '/')) == NULL)
587 + p = buf;
588 + else
589 + p++;
590 +
591 + /*
592 + * If for some reason we can't find a link map id for this module, which
593 + * would be really quite weird. We instead just say the link map id is
594 + * zero.
595 + */
596 + if (Plmid(dcp->dpa_proc, prmap->pr_vaddr, &lmid) != 0)
597 + lmid = 0;
598 +
599 + if (lmid == 0)
600 + dcp->dpa_dmp->dm_libctfn[count] = strdup(p);
601 + else
602 + (void) asprintf(&dcp->dpa_dmp->dm_libctfn[count],
603 + "LM%lx`%s", lmid, p);
604 + if (dcp->dpa_dmp->dm_libctfn[count] == NULL)
605 + return (1);
606 + ctf_setspecific(fp, dcp->dpa_dmp);
607 + dcp->dpa_count++;
608 + return (0);
609 +}
610 +
611 +/*
612 + * We've been asked to load data that belongs to another process. As such we're
613 + * going to pgrab it at this instant, load everything that we might ever care
614 + * about, and then drive on. The reason for this is that the process that we're
615 + * interested in might be changing. As long as we have grabbed it, then this
616 + * can't be a problem for us.
617 + *
618 + * For now, we're actually going to punt on most things and just try to get CTF
619 + * data, nothing else. Basically this is only useful as a source of type
620 + * information, we can't go and do the stacktrace lookups, etc.
621 + */
622 +static int
623 +dt_module_load_proc(dtrace_hdl_t *dtp, dt_module_t *dmp)
624 +{
625 + struct ps_prochandle *p;
626 + dt_module_cb_arg_t arg;
627 +
628 + /*
629 + * Note that on success we do not release this hold. We must hold this
630 + * for our life time.
631 + */
632 + p = dt_proc_grab(dtp, dmp->dm_pid, 0, PGRAB_RDONLY | PGRAB_FORCE);
633 + if (p == NULL) {
634 + dt_dprintf("failed to grab pid: %d\n", (int)dmp->dm_pid);
635 + return (dt_set_errno(dtp, EDT_CANTLOAD));
636 + }
637 + dt_proc_lock(dtp, p);
638 +
639 + arg.dpa_proc = p;
640 + arg.dpa_dtp = dtp;
641 + arg.dpa_dmp = dmp;
642 + arg.dpa_count = 0;
643 + if (Pobject_iter_resolved(p, dt_module_load_proc_count, &arg) != 0) {
644 + dt_dprintf("failed to iterate objects\n");
645 + dt_proc_release(dtp, p);
646 + return (dt_set_errno(dtp, EDT_CANTLOAD));
647 + }
648 +
649 + if (arg.dpa_count == 0) {
650 + dt_dprintf("no ctf data present\n");
651 + dt_proc_unlock(dtp, p);
652 + dt_proc_release(dtp, p);
653 + return (dt_set_errno(dtp, EDT_CANTLOAD));
654 + }
655 +
656 + dmp->dm_libctfp = malloc(sizeof (ctf_file_t *) * arg.dpa_count);
657 + if (dmp->dm_libctfp == NULL) {
658 + dt_proc_unlock(dtp, p);
659 + dt_proc_release(dtp, p);
660 + return (dt_set_errno(dtp, EDT_NOMEM));
661 + }
662 + bzero(dmp->dm_libctfp, sizeof (ctf_file_t *) * arg.dpa_count);
663 +
664 + dmp->dm_libctfn = malloc(sizeof (char *) * arg.dpa_count);
665 + if (dmp->dm_libctfn == NULL) {
666 + free(dmp->dm_libctfp);
667 + dt_proc_unlock(dtp, p);
668 + dt_proc_release(dtp, p);
669 + return (dt_set_errno(dtp, EDT_NOMEM));
670 + }
671 + bzero(dmp->dm_libctfn, sizeof (char *) * arg.dpa_count);
672 +
673 + dmp->dm_nctflibs = arg.dpa_count;
674 +
675 + arg.dpa_count = 0;
676 + if (Pobject_iter_resolved(p, dt_module_load_proc_build, &arg) != 0) {
677 + dt_proc_unlock(dtp, p);
678 + dt_module_unload(dtp, dmp);
679 + dt_proc_release(dtp, p);
680 + return (dt_set_errno(dtp, EDT_CANTLOAD));
681 + }
682 + assert(arg.dpa_count == dmp->dm_nctflibs);
683 + dt_dprintf("loaded %d ctf modules for pid %d\n", arg.dpa_count,
684 + (int)dmp->dm_pid);
685 +
686 + dt_proc_unlock(dtp, p);
687 + dt_proc_release(dtp, p);
688 + dmp->dm_flags |= DT_DM_LOADED;
689 +
690 + return (0);
691 +}
692 +
507 693 int
508 694 dt_module_load(dtrace_hdl_t *dtp, dt_module_t *dmp)
509 695 {
510 696 if (dmp->dm_flags & DT_DM_LOADED)
511 697 return (0); /* module is already loaded */
512 698
699 + if (dmp->dm_pid != 0)
700 + return (dt_module_load_proc(dtp, dmp));
701 +
513 702 dmp->dm_ctdata.cts_name = ".SUNW_ctf";
514 703 dmp->dm_ctdata.cts_type = SHT_PROGBITS;
515 704 dmp->dm_ctdata.cts_flags = 0;
516 705 dmp->dm_ctdata.cts_data = NULL;
517 706 dmp->dm_ctdata.cts_size = 0;
518 707 dmp->dm_ctdata.cts_entsize = 0;
519 708 dmp->dm_ctdata.cts_offset = 0;
520 709
521 710 dmp->dm_symtab.cts_name = ".symtab";
522 711 dmp->dm_symtab.cts_type = SHT_SYMTAB;
523 712 dmp->dm_symtab.cts_flags = 0;
524 713 dmp->dm_symtab.cts_data = NULL;
525 714 dmp->dm_symtab.cts_size = 0;
526 715 dmp->dm_symtab.cts_entsize = dmp->dm_ops == &dt_modops_64 ?
527 716 sizeof (Elf64_Sym) : sizeof (Elf32_Sym);
528 717 dmp->dm_symtab.cts_offset = 0;
529 718
530 719 dmp->dm_strtab.cts_name = ".strtab";
531 720 dmp->dm_strtab.cts_type = SHT_STRTAB;
532 721 dmp->dm_strtab.cts_flags = 0;
533 722 dmp->dm_strtab.cts_data = NULL;
534 723 dmp->dm_strtab.cts_size = 0;
535 724 dmp->dm_strtab.cts_entsize = 0;
536 725 dmp->dm_strtab.cts_offset = 0;
537 726
538 727 /*
539 728 * Attempt to load the module's CTF section, symbol table section, and
540 729 * string table section. Note that modules may not contain CTF data:
541 730 * this will result in a successful load_sect but data of size zero.
542 731 * We will then fail if dt_module_getctf() is called, as shown below.
543 732 */
544 733 if (dt_module_load_sect(dtp, dmp, &dmp->dm_ctdata) == -1 ||
545 734 dt_module_load_sect(dtp, dmp, &dmp->dm_symtab) == -1 ||
546 735 dt_module_load_sect(dtp, dmp, &dmp->dm_strtab) == -1) {
547 736 dt_module_unload(dtp, dmp);
548 737 return (-1); /* dt_errno is set for us */
549 738 }
550 739
551 740 /*
552 741 * Allocate the hash chains and hash buckets for symbol name lookup.
553 742 * This is relatively simple since the symbol table is of fixed size
554 743 * and is known in advance. We allocate one extra element since we
555 744 * use element indices instead of pointers and zero is our sentinel.
556 745 */
557 746 dmp->dm_nsymelems =
558 747 dmp->dm_symtab.cts_size / dmp->dm_symtab.cts_entsize;
559 748
560 749 dmp->dm_nsymbuckets = _dtrace_strbuckets;
561 750 dmp->dm_symfree = 1; /* first free element is index 1 */
562 751
563 752 dmp->dm_symbuckets = malloc(sizeof (uint_t) * dmp->dm_nsymbuckets);
564 753 dmp->dm_symchains = malloc(sizeof (dt_sym_t) * dmp->dm_nsymelems + 1);
565 754
566 755 if (dmp->dm_symbuckets == NULL || dmp->dm_symchains == NULL) {
567 756 dt_module_unload(dtp, dmp);
568 757 return (dt_set_errno(dtp, EDT_NOMEM));
569 758 }
570 759
571 760 bzero(dmp->dm_symbuckets, sizeof (uint_t) * dmp->dm_nsymbuckets);
572 761 bzero(dmp->dm_symchains, sizeof (dt_sym_t) * dmp->dm_nsymelems + 1);
573 762
574 763 /*
575 764 * Iterate over the symbol table data buffer and insert each symbol
576 765 * name into the name hash if the name and type are valid. Then
577 766 * allocate the address map, fill it in, and sort it.
578 767 */
579 768 dmp->dm_asrsv = dmp->dm_ops->do_syminit(dmp);
580 769
581 770 dt_dprintf("hashed %s [%s] (%u symbols)\n",
582 771 dmp->dm_name, dmp->dm_symtab.cts_name, dmp->dm_symfree - 1);
583 772
584 773 if ((dmp->dm_asmap = malloc(sizeof (void *) * dmp->dm_asrsv)) == NULL) {
585 774 dt_module_unload(dtp, dmp);
586 775 return (dt_set_errno(dtp, EDT_NOMEM));
587 776 }
↓ open down ↓ |
65 lines elided |
↑ open up ↑ |
588 777
589 778 dmp->dm_ops->do_symsort(dmp);
590 779
591 780 dt_dprintf("sorted %s [%s] (%u symbols)\n",
592 781 dmp->dm_name, dmp->dm_symtab.cts_name, dmp->dm_aslen);
593 782
594 783 dmp->dm_flags |= DT_DM_LOADED;
595 784 return (0);
596 785 }
597 786
787 +int
788 +dt_module_hasctf(dtrace_hdl_t *dtp, dt_module_t *dmp)
789 +{
790 + if (dmp->dm_pid != 0 && dmp->dm_nctflibs > 0)
791 + return (1);
792 + return (dt_module_getctf(dtp, dmp) != NULL);
793 +}
794 +
598 795 ctf_file_t *
599 796 dt_module_getctf(dtrace_hdl_t *dtp, dt_module_t *dmp)
600 797 {
601 798 const char *parent;
602 799 dt_module_t *pmp;
603 800 ctf_file_t *pfp;
604 801 int model;
605 802
606 803 if (dmp->dm_ctfp != NULL || dt_module_load(dtp, dmp) != 0)
607 804 return (dmp->dm_ctfp);
608 805
609 806 if (dmp->dm_ops == &dt_modops_64)
610 807 model = CTF_MODEL_LP64;
611 808 else
612 809 model = CTF_MODEL_ILP32;
613 810
614 811 /*
615 812 * If the data model of the module does not match our program data
616 813 * model, then do not permit CTF from this module to be opened and
617 814 * returned to the compiler. If we support mixed data models in the
618 815 * future for combined kernel/user tracing, this can be removed.
619 816 */
620 817 if (dtp->dt_conf.dtc_ctfmodel != model) {
621 818 (void) dt_set_errno(dtp, EDT_DATAMODEL);
622 819 return (NULL);
623 820 }
624 821
625 822 if (dmp->dm_ctdata.cts_size == 0) {
626 823 (void) dt_set_errno(dtp, EDT_NOCTF);
627 824 return (NULL);
628 825 }
629 826
630 827 dmp->dm_ctfp = ctf_bufopen(&dmp->dm_ctdata,
631 828 &dmp->dm_symtab, &dmp->dm_strtab, &dtp->dt_ctferr);
632 829
633 830 if (dmp->dm_ctfp == NULL) {
634 831 (void) dt_set_errno(dtp, EDT_CTF);
635 832 return (NULL);
636 833 }
637 834
638 835 (void) ctf_setmodel(dmp->dm_ctfp, model);
639 836 ctf_setspecific(dmp->dm_ctfp, dmp);
640 837
641 838 if ((parent = ctf_parent_name(dmp->dm_ctfp)) != NULL) {
642 839 if ((pmp = dt_module_create(dtp, parent)) == NULL ||
643 840 (pfp = dt_module_getctf(dtp, pmp)) == NULL) {
644 841 if (pmp == NULL)
645 842 (void) dt_set_errno(dtp, EDT_NOMEM);
646 843 goto err;
647 844 }
648 845
649 846 if (ctf_import(dmp->dm_ctfp, pfp) == CTF_ERR) {
650 847 dtp->dt_ctferr = ctf_errno(dmp->dm_ctfp);
651 848 (void) dt_set_errno(dtp, EDT_CTF);
652 849 goto err;
653 850 }
654 851 }
655 852
656 853 dt_dprintf("loaded CTF container for %s (%p)\n",
657 854 dmp->dm_name, (void *)dmp->dm_ctfp);
658 855
659 856 return (dmp->dm_ctfp);
660 857
↓ open down ↓ |
53 lines elided |
↑ open up ↑ |
661 858 err:
662 859 ctf_close(dmp->dm_ctfp);
663 860 dmp->dm_ctfp = NULL;
664 861 return (NULL);
665 862 }
666 863
667 864 /*ARGSUSED*/
668 865 void
669 866 dt_module_unload(dtrace_hdl_t *dtp, dt_module_t *dmp)
670 867 {
868 + int i;
869 +
671 870 ctf_close(dmp->dm_ctfp);
672 871 dmp->dm_ctfp = NULL;
673 872
873 + if (dmp->dm_libctfp != NULL) {
874 + for (i = 0; i < dmp->dm_nctflibs; i++) {
875 + ctf_close(dmp->dm_libctfp[i]);
876 + free(dmp->dm_libctfn[i]);
877 + }
878 + free(dmp->dm_libctfp);
879 + free(dmp->dm_libctfn);
880 + dmp->dm_libctfp = NULL;
881 + dmp->dm_nctflibs = 0;
882 + }
883 +
674 884 bzero(&dmp->dm_ctdata, sizeof (ctf_sect_t));
675 885 bzero(&dmp->dm_symtab, sizeof (ctf_sect_t));
676 886 bzero(&dmp->dm_strtab, sizeof (ctf_sect_t));
677 887
678 888 if (dmp->dm_symbuckets != NULL) {
679 889 free(dmp->dm_symbuckets);
680 890 dmp->dm_symbuckets = NULL;
681 891 }
682 892
683 893 if (dmp->dm_symchains != NULL) {
684 894 free(dmp->dm_symchains);
685 895 dmp->dm_symchains = NULL;
686 896 }
687 897
688 898 if (dmp->dm_asmap != NULL) {
689 899 free(dmp->dm_asmap);
690 900 dmp->dm_asmap = NULL;
691 901 }
692 902
693 903 dmp->dm_symfree = 0;
694 904 dmp->dm_nsymbuckets = 0;
695 905 dmp->dm_nsymelems = 0;
696 906 dmp->dm_asrsv = 0;
697 907 dmp->dm_aslen = 0;
698 908
699 909 dmp->dm_text_va = NULL;
700 910 dmp->dm_text_size = 0;
701 911 dmp->dm_data_va = NULL;
702 912 dmp->dm_data_size = 0;
703 913 dmp->dm_bss_va = NULL;
↓ open down ↓ |
20 lines elided |
↑ open up ↑ |
704 914 dmp->dm_bss_size = 0;
705 915
706 916 if (dmp->dm_extern != NULL) {
707 917 dt_idhash_destroy(dmp->dm_extern);
708 918 dmp->dm_extern = NULL;
709 919 }
710 920
711 921 (void) elf_end(dmp->dm_elf);
712 922 dmp->dm_elf = NULL;
713 923
924 + dmp->dm_pid = 0;
925 +
714 926 dmp->dm_flags &= ~DT_DM_LOADED;
715 927 }
716 928
717 929 void
718 930 dt_module_destroy(dtrace_hdl_t *dtp, dt_module_t *dmp)
719 931 {
720 932 uint_t h = dt_strtab_hash(dmp->dm_name, NULL) % dtp->dt_modbuckets;
721 933 dt_module_t **dmpp = &dtp->dt_mods[h];
722 934
723 935 dt_list_delete(&dtp->dt_modlist, dmp);
724 936 assert(dtp->dt_nmods != 0);
725 937 dtp->dt_nmods--;
726 938
727 939 /*
728 940 * Now remove this module from its hash chain. We expect to always
729 941 * find the module on its hash chain, so in this loop we assert that
730 942 * we don't run off the end of the list.
731 943 */
732 944 while (*dmpp != dmp) {
733 945 dmpp = &((*dmpp)->dm_next);
734 946 assert(*dmpp != NULL);
735 947 }
736 948
737 949 *dmpp = dmp->dm_next;
738 950
739 951 dt_module_unload(dtp, dmp);
740 952 free(dmp);
741 953 }
742 954
743 955 /*
744 956 * Insert a new external symbol reference into the specified module. The new
745 957 * symbol will be marked as undefined and is assigned a symbol index beyond
746 958 * any existing cached symbols from this module. We use the ident's di_data
747 959 * field to store a pointer to a copy of the dtrace_syminfo_t for this symbol.
748 960 */
749 961 dt_ident_t *
750 962 dt_module_extern(dtrace_hdl_t *dtp, dt_module_t *dmp,
751 963 const char *name, const dtrace_typeinfo_t *tip)
752 964 {
753 965 dtrace_syminfo_t *sip;
754 966 dt_ident_t *idp;
755 967 uint_t id;
756 968
757 969 if (dmp->dm_extern == NULL && (dmp->dm_extern = dt_idhash_create(
758 970 "extern", NULL, dmp->dm_nsymelems, UINT_MAX)) == NULL) {
759 971 (void) dt_set_errno(dtp, EDT_NOMEM);
760 972 return (NULL);
761 973 }
762 974
763 975 if (dt_idhash_nextid(dmp->dm_extern, &id) == -1) {
764 976 (void) dt_set_errno(dtp, EDT_SYMOFLOW);
765 977 return (NULL);
766 978 }
767 979
768 980 if ((sip = malloc(sizeof (dtrace_syminfo_t))) == NULL) {
769 981 (void) dt_set_errno(dtp, EDT_NOMEM);
770 982 return (NULL);
771 983 }
772 984
773 985 idp = dt_idhash_insert(dmp->dm_extern, name, DT_IDENT_SYMBOL, 0, id,
774 986 _dtrace_symattr, 0, &dt_idops_thaw, NULL, dtp->dt_gen);
775 987
776 988 if (idp == NULL) {
777 989 (void) dt_set_errno(dtp, EDT_NOMEM);
778 990 free(sip);
779 991 return (NULL);
780 992 }
781 993
782 994 sip->dts_object = dmp->dm_name;
783 995 sip->dts_name = idp->di_name;
784 996 sip->dts_id = idp->di_id;
785 997
786 998 idp->di_data = sip;
787 999 idp->di_ctfp = tip->dtt_ctfp;
788 1000 idp->di_type = tip->dtt_type;
789 1001
790 1002 return (idp);
791 1003 }
↓ open down ↓ |
68 lines elided |
↑ open up ↑ |
792 1004
793 1005 const char *
794 1006 dt_module_modelname(dt_module_t *dmp)
795 1007 {
796 1008 if (dmp->dm_ops == &dt_modops_64)
797 1009 return ("64-bit");
798 1010 else
799 1011 return ("32-bit");
800 1012 }
801 1013
1014 +/* ARGSUSED */
1015 +int
1016 +dt_module_getlibid(dtrace_hdl_t *dtp, dt_module_t *dmp, const ctf_file_t *fp)
1017 +{
1018 + int i;
1019 +
1020 + for (i = 0; i < dmp->dm_nctflibs; i++) {
1021 + if (dmp->dm_libctfp[i] == fp)
1022 + return (i);
1023 + }
1024 +
1025 + return (-1);
1026 +}
1027 +
1028 +/* ARGSUSED */
1029 +ctf_file_t *
1030 +dt_module_getctflib(dtrace_hdl_t *dtp, dt_module_t *dmp, const char *name)
1031 +{
1032 + int i;
1033 +
1034 + for (i = 0; i < dmp->dm_nctflibs; i++) {
1035 + if (strcmp(dmp->dm_libctfn[i], name) == 0)
1036 + return (dmp->dm_libctfp[i]);
1037 + }
1038 +
1039 + return (NULL);
1040 +}
1041 +
802 1042 /*
803 1043 * Update our module cache by adding an entry for the specified module 'name'.
804 1044 * We create the dt_module_t and populate it using /system/object/<name>/.
805 1045 */
806 1046 static void
807 1047 dt_module_update(dtrace_hdl_t *dtp, const char *name)
808 1048 {
809 1049 char fname[MAXPATHLEN];
810 1050 struct stat64 st;
811 1051 int fd, err, bits;
812 1052
813 1053 dt_module_t *dmp;
814 1054 const char *s;
815 1055 size_t shstrs;
816 1056 GElf_Shdr sh;
817 1057 Elf_Data *dp;
818 1058 Elf_Scn *sp;
819 1059
820 1060 (void) snprintf(fname, sizeof (fname),
821 1061 "%s/%s/object", OBJFS_ROOT, name);
822 1062
823 1063 if ((fd = open(fname, O_RDONLY)) == -1 || fstat64(fd, &st) == -1 ||
824 1064 (dmp = dt_module_create(dtp, name)) == NULL) {
825 1065 dt_dprintf("failed to open %s: %s\n", fname, strerror(errno));
826 1066 (void) close(fd);
827 1067 return;
828 1068 }
829 1069
830 1070 /*
831 1071 * Since the module can unload out from under us (and /system/object
832 1072 * will return ENOENT), tell libelf to cook the entire file now and
833 1073 * then close the underlying file descriptor immediately. If this
834 1074 * succeeds, we know that we can continue safely using dmp->dm_elf.
835 1075 */
836 1076 dmp->dm_elf = elf_begin(fd, ELF_C_READ, NULL);
837 1077 err = elf_cntl(dmp->dm_elf, ELF_C_FDREAD);
838 1078 (void) close(fd);
839 1079
840 1080 if (dmp->dm_elf == NULL || err == -1 ||
841 1081 elf_getshdrstrndx(dmp->dm_elf, &shstrs) == -1) {
842 1082 dt_dprintf("failed to load %s: %s\n",
843 1083 fname, elf_errmsg(elf_errno()));
844 1084 dt_module_destroy(dtp, dmp);
845 1085 return;
846 1086 }
847 1087
848 1088 switch (gelf_getclass(dmp->dm_elf)) {
849 1089 case ELFCLASS32:
850 1090 dmp->dm_ops = &dt_modops_32;
851 1091 bits = 32;
852 1092 break;
853 1093 case ELFCLASS64:
854 1094 dmp->dm_ops = &dt_modops_64;
855 1095 bits = 64;
856 1096 break;
857 1097 default:
858 1098 dt_dprintf("failed to load %s: unknown ELF class\n", fname);
859 1099 dt_module_destroy(dtp, dmp);
860 1100 return;
861 1101 }
862 1102
863 1103 /*
864 1104 * Iterate over the section headers locating various sections of
865 1105 * interest and use their attributes to flesh out the dt_module_t.
866 1106 */
867 1107 for (sp = NULL; (sp = elf_nextscn(dmp->dm_elf, sp)) != NULL; ) {
868 1108 if (gelf_getshdr(sp, &sh) == NULL || sh.sh_type == SHT_NULL ||
869 1109 (s = elf_strptr(dmp->dm_elf, shstrs, sh.sh_name)) == NULL)
870 1110 continue; /* skip any malformed sections */
871 1111
872 1112 if (strcmp(s, ".text") == 0) {
873 1113 dmp->dm_text_size = sh.sh_size;
874 1114 dmp->dm_text_va = sh.sh_addr;
875 1115 } else if (strcmp(s, ".data") == 0) {
876 1116 dmp->dm_data_size = sh.sh_size;
877 1117 dmp->dm_data_va = sh.sh_addr;
878 1118 } else if (strcmp(s, ".bss") == 0) {
879 1119 dmp->dm_bss_size = sh.sh_size;
880 1120 dmp->dm_bss_va = sh.sh_addr;
881 1121 } else if (strcmp(s, ".info") == 0 &&
882 1122 (dp = elf_getdata(sp, NULL)) != NULL) {
883 1123 bcopy(dp->d_buf, &dmp->dm_info,
884 1124 MIN(sh.sh_size, sizeof (dmp->dm_info)));
885 1125 } else if (strcmp(s, ".filename") == 0 &&
886 1126 (dp = elf_getdata(sp, NULL)) != NULL) {
887 1127 (void) strlcpy(dmp->dm_file,
888 1128 dp->d_buf, sizeof (dmp->dm_file));
889 1129 }
890 1130 }
891 1131
892 1132 dmp->dm_flags |= DT_DM_KERNEL;
893 1133 dmp->dm_modid = (int)OBJFS_MODID(st.st_ino);
894 1134
895 1135 if (dmp->dm_info.objfs_info_primary)
896 1136 dmp->dm_flags |= DT_DM_PRIMARY;
897 1137
898 1138 dt_dprintf("opened %d-bit module %s (%s) [%d]\n",
899 1139 bits, dmp->dm_name, dmp->dm_file, dmp->dm_modid);
900 1140 }
901 1141
902 1142 /*
903 1143 * Unload all the loaded modules and then refresh the module cache with the
904 1144 * latest list of loaded modules and their address ranges.
905 1145 */
906 1146 void
907 1147 dtrace_update(dtrace_hdl_t *dtp)
908 1148 {
909 1149 dt_module_t *dmp;
910 1150 DIR *dirp;
911 1151
912 1152 for (dmp = dt_list_next(&dtp->dt_modlist);
913 1153 dmp != NULL; dmp = dt_list_next(dmp))
914 1154 dt_module_unload(dtp, dmp);
915 1155
916 1156 /*
917 1157 * Open /system/object and attempt to create a libdtrace module for
918 1158 * each kernel module that is loaded on the current system.
919 1159 */
920 1160 if (!(dtp->dt_oflags & DTRACE_O_NOSYS) &&
921 1161 (dirp = opendir(OBJFS_ROOT)) != NULL) {
922 1162 struct dirent *dp;
923 1163
924 1164 while ((dp = readdir(dirp)) != NULL) {
925 1165 if (dp->d_name[0] != '.')
926 1166 dt_module_update(dtp, dp->d_name);
927 1167 }
928 1168
929 1169 (void) closedir(dirp);
930 1170 }
931 1171
932 1172 /*
933 1173 * Look up all the macro identifiers and set di_id to the latest value.
934 1174 * This code collaborates with dt_lex.l on the use of di_id. We will
935 1175 * need to implement something fancier if we need to support non-ints.
936 1176 */
937 1177 dt_idhash_lookup(dtp->dt_macros, "egid")->di_id = getegid();
938 1178 dt_idhash_lookup(dtp->dt_macros, "euid")->di_id = geteuid();
939 1179 dt_idhash_lookup(dtp->dt_macros, "gid")->di_id = getgid();
940 1180 dt_idhash_lookup(dtp->dt_macros, "pid")->di_id = getpid();
941 1181 dt_idhash_lookup(dtp->dt_macros, "pgid")->di_id = getpgid(0);
942 1182 dt_idhash_lookup(dtp->dt_macros, "ppid")->di_id = getppid();
943 1183 dt_idhash_lookup(dtp->dt_macros, "projid")->di_id = getprojid();
944 1184 dt_idhash_lookup(dtp->dt_macros, "sid")->di_id = getsid(0);
945 1185 dt_idhash_lookup(dtp->dt_macros, "taskid")->di_id = gettaskid();
946 1186 dt_idhash_lookup(dtp->dt_macros, "uid")->di_id = getuid();
947 1187
948 1188 /*
949 1189 * Cache the pointers to the modules representing the base executable
950 1190 * and the run-time linker in the dtrace client handle. Note that on
951 1191 * x86 krtld is folded into unix, so if we don't find it, use unix
952 1192 * instead.
953 1193 */
954 1194 dtp->dt_exec = dt_module_lookup_by_name(dtp, "genunix");
955 1195 dtp->dt_rtld = dt_module_lookup_by_name(dtp, "krtld");
956 1196 if (dtp->dt_rtld == NULL)
957 1197 dtp->dt_rtld = dt_module_lookup_by_name(dtp, "unix");
958 1198
959 1199 /*
960 1200 * If this is the first time we are initializing the module list,
961 1201 * remove the module for genunix from the module list and then move it
962 1202 * to the front of the module list. We do this so that type and symbol
963 1203 * queries encounter genunix and thereby optimize for the common case
964 1204 * in dtrace_lookup_by_name() and dtrace_lookup_by_type(), below.
965 1205 */
966 1206 if (dtp->dt_exec != NULL &&
967 1207 dtp->dt_cdefs == NULL && dtp->dt_ddefs == NULL) {
968 1208 dt_list_delete(&dtp->dt_modlist, dtp->dt_exec);
969 1209 dt_list_prepend(&dtp->dt_modlist, dtp->dt_exec);
970 1210 }
971 1211 }
972 1212
973 1213 static dt_module_t *
974 1214 dt_module_from_object(dtrace_hdl_t *dtp, const char *object)
975 1215 {
976 1216 int err = EDT_NOMOD;
977 1217 dt_module_t *dmp;
978 1218
979 1219 switch ((uintptr_t)object) {
980 1220 case (uintptr_t)DTRACE_OBJ_EXEC:
981 1221 dmp = dtp->dt_exec;
982 1222 break;
983 1223 case (uintptr_t)DTRACE_OBJ_RTLD:
984 1224 dmp = dtp->dt_rtld;
985 1225 break;
986 1226 case (uintptr_t)DTRACE_OBJ_CDEFS:
987 1227 dmp = dtp->dt_cdefs;
988 1228 break;
989 1229 case (uintptr_t)DTRACE_OBJ_DDEFS:
990 1230 dmp = dtp->dt_ddefs;
991 1231 break;
992 1232 default:
993 1233 dmp = dt_module_create(dtp, object);
994 1234 err = EDT_NOMEM;
995 1235 }
996 1236
997 1237 if (dmp == NULL)
998 1238 (void) dt_set_errno(dtp, err);
999 1239
1000 1240 return (dmp);
1001 1241 }
1002 1242
1003 1243 /*
1004 1244 * Exported interface to look up a symbol by name. We return the GElf_Sym and
1005 1245 * complete symbol information for the matching symbol.
1006 1246 */
1007 1247 int
1008 1248 dtrace_lookup_by_name(dtrace_hdl_t *dtp, const char *object, const char *name,
1009 1249 GElf_Sym *symp, dtrace_syminfo_t *sip)
1010 1250 {
1011 1251 dt_module_t *dmp;
1012 1252 dt_ident_t *idp;
1013 1253 uint_t n, id;
1014 1254 GElf_Sym sym;
1015 1255
1016 1256 uint_t mask = 0; /* mask of dt_module flags to match */
1017 1257 uint_t bits = 0; /* flag bits that must be present */
1018 1258
1019 1259 if (object != DTRACE_OBJ_EVERY &&
1020 1260 object != DTRACE_OBJ_KMODS &&
1021 1261 object != DTRACE_OBJ_UMODS) {
1022 1262 if ((dmp = dt_module_from_object(dtp, object)) == NULL)
1023 1263 return (-1); /* dt_errno is set for us */
1024 1264
1025 1265 if (dt_module_load(dtp, dmp) == -1)
1026 1266 return (-1); /* dt_errno is set for us */
1027 1267 n = 1;
1028 1268
1029 1269 } else {
1030 1270 if (object == DTRACE_OBJ_KMODS)
1031 1271 mask = bits = DT_DM_KERNEL;
1032 1272 else if (object == DTRACE_OBJ_UMODS)
1033 1273 mask = DT_DM_KERNEL;
1034 1274
1035 1275 dmp = dt_list_next(&dtp->dt_modlist);
1036 1276 n = dtp->dt_nmods;
1037 1277 }
1038 1278
1039 1279 if (symp == NULL)
1040 1280 symp = &sym;
1041 1281
1042 1282 for (; n > 0; n--, dmp = dt_list_next(dmp)) {
1043 1283 if ((dmp->dm_flags & mask) != bits)
1044 1284 continue; /* failed to match required attributes */
1045 1285
1046 1286 if (dt_module_load(dtp, dmp) == -1)
1047 1287 continue; /* failed to load symbol table */
1048 1288
1049 1289 if (dmp->dm_ops->do_symname(dmp, name, symp, &id) != NULL) {
1050 1290 if (sip != NULL) {
1051 1291 sip->dts_object = dmp->dm_name;
1052 1292 sip->dts_name = (const char *)
1053 1293 dmp->dm_strtab.cts_data + symp->st_name;
1054 1294 sip->dts_id = id;
1055 1295 }
1056 1296 return (0);
1057 1297 }
1058 1298
1059 1299 if (dmp->dm_extern != NULL &&
1060 1300 (idp = dt_idhash_lookup(dmp->dm_extern, name)) != NULL) {
1061 1301 if (symp != &sym) {
1062 1302 symp->st_name = (uintptr_t)idp->di_name;
1063 1303 symp->st_info =
1064 1304 GELF_ST_INFO(STB_GLOBAL, STT_NOTYPE);
1065 1305 symp->st_other = 0;
1066 1306 symp->st_shndx = SHN_UNDEF;
1067 1307 symp->st_value = 0;
1068 1308 symp->st_size =
1069 1309 ctf_type_size(idp->di_ctfp, idp->di_type);
1070 1310 }
1071 1311
1072 1312 if (sip != NULL) {
1073 1313 sip->dts_object = dmp->dm_name;
1074 1314 sip->dts_name = idp->di_name;
1075 1315 sip->dts_id = idp->di_id;
1076 1316 }
1077 1317
1078 1318 return (0);
1079 1319 }
1080 1320 }
1081 1321
1082 1322 return (dt_set_errno(dtp, EDT_NOSYM));
1083 1323 }
1084 1324
1085 1325 /*
1086 1326 * Exported interface to look up a symbol by address. We return the GElf_Sym
1087 1327 * and complete symbol information for the matching symbol.
1088 1328 */
1089 1329 int
1090 1330 dtrace_lookup_by_addr(dtrace_hdl_t *dtp, GElf_Addr addr,
1091 1331 GElf_Sym *symp, dtrace_syminfo_t *sip)
1092 1332 {
1093 1333 dt_module_t *dmp;
1094 1334 uint_t id;
1095 1335 const dtrace_vector_t *v = dtp->dt_vector;
1096 1336
1097 1337 if (v != NULL)
1098 1338 return (v->dtv_lookup_by_addr(dtp->dt_varg, addr, symp, sip));
1099 1339
1100 1340 for (dmp = dt_list_next(&dtp->dt_modlist); dmp != NULL;
1101 1341 dmp = dt_list_next(dmp)) {
1102 1342 if (addr - dmp->dm_text_va < dmp->dm_text_size ||
1103 1343 addr - dmp->dm_data_va < dmp->dm_data_size ||
1104 1344 addr - dmp->dm_bss_va < dmp->dm_bss_size)
1105 1345 break;
1106 1346 }
1107 1347
1108 1348 if (dmp == NULL)
1109 1349 return (dt_set_errno(dtp, EDT_NOSYMADDR));
1110 1350
1111 1351 if (dt_module_load(dtp, dmp) == -1)
1112 1352 return (-1); /* dt_errno is set for us */
1113 1353
1114 1354 if (symp != NULL) {
1115 1355 if (dmp->dm_ops->do_symaddr(dmp, addr, symp, &id) == NULL)
1116 1356 return (dt_set_errno(dtp, EDT_NOSYMADDR));
1117 1357 }
1118 1358
1119 1359 if (sip != NULL) {
1120 1360 sip->dts_object = dmp->dm_name;
1121 1361
1122 1362 if (symp != NULL) {
1123 1363 sip->dts_name = (const char *)
1124 1364 dmp->dm_strtab.cts_data + symp->st_name;
1125 1365 sip->dts_id = id;
1126 1366 } else {
1127 1367 sip->dts_name = NULL;
1128 1368 sip->dts_id = 0;
1129 1369 }
1130 1370 }
1131 1371
1132 1372 return (0);
↓ open down ↓ |
321 lines elided |
↑ open up ↑ |
1133 1373 }
1134 1374
1135 1375 int
1136 1376 dtrace_lookup_by_type(dtrace_hdl_t *dtp, const char *object, const char *name,
1137 1377 dtrace_typeinfo_t *tip)
1138 1378 {
1139 1379 dtrace_typeinfo_t ti;
1140 1380 dt_module_t *dmp;
1141 1381 int found = 0;
1142 1382 ctf_id_t id;
1143 - uint_t n;
1383 + uint_t n, i;
1144 1384 int justone;
1385 + ctf_file_t *fp;
1386 + char *buf, *p, *q;
1145 1387
1146 1388 uint_t mask = 0; /* mask of dt_module flags to match */
1147 1389 uint_t bits = 0; /* flag bits that must be present */
1148 1390
1149 1391 if (object != DTRACE_OBJ_EVERY &&
1150 1392 object != DTRACE_OBJ_KMODS &&
1151 1393 object != DTRACE_OBJ_UMODS) {
1152 1394 if ((dmp = dt_module_from_object(dtp, object)) == NULL)
1153 1395 return (-1); /* dt_errno is set for us */
1154 1396
1155 1397 if (dt_module_load(dtp, dmp) == -1)
1156 1398 return (-1); /* dt_errno is set for us */
1157 1399 n = 1;
1158 1400 justone = 1;
1159 -
1160 1401 } else {
1161 1402 if (object == DTRACE_OBJ_KMODS)
1162 1403 mask = bits = DT_DM_KERNEL;
1163 1404 else if (object == DTRACE_OBJ_UMODS)
1164 1405 mask = DT_DM_KERNEL;
1165 1406
1166 1407 dmp = dt_list_next(&dtp->dt_modlist);
1167 1408 n = dtp->dt_nmods;
1168 1409 justone = 0;
1169 1410 }
1170 1411
1171 1412 if (tip == NULL)
1172 1413 tip = &ti;
↓ open down ↓ |
3 lines elided |
↑ open up ↑ |
1173 1414
1174 1415 for (; n > 0; n--, dmp = dt_list_next(dmp)) {
1175 1416 if ((dmp->dm_flags & mask) != bits)
1176 1417 continue; /* failed to match required attributes */
1177 1418
1178 1419 /*
1179 1420 * If we can't load the CTF container, continue on to the next
1180 1421 * module. If our search was scoped to only one module then
1181 1422 * return immediately leaving dt_errno unmodified.
1182 1423 */
1183 - if (dt_module_getctf(dtp, dmp) == NULL) {
1424 + if (dt_module_hasctf(dtp, dmp) == 0) {
1184 1425 if (justone)
1185 1426 return (-1);
1186 1427 continue;
1187 1428 }
1188 1429
1189 1430 /*
1190 1431 * Look up the type in the module's CTF container. If our
1191 1432 * match is a forward declaration tag, save this choice in
1192 1433 * 'tip' and keep going in the hope that we will locate the
1193 1434 * underlying structure definition. Otherwise just return.
1194 1435 */
1195 - if ((id = ctf_lookup_by_name(dmp->dm_ctfp, name)) != CTF_ERR) {
1436 + if (dmp->dm_pid == 0) {
1437 + id = ctf_lookup_by_name(dmp->dm_ctfp, name);
1438 + fp = dmp->dm_ctfp;
1439 + } else {
1440 + if ((p = strchr(name, '`')) != NULL) {
1441 + buf = strdup(name);
1442 + if (buf == NULL)
1443 + return (dt_set_errno(dtp, EDT_NOMEM));
1444 + p = strchr(buf, '`');
1445 + if ((q = strchr(p + 1, '`')) != NULL)
1446 + p = q;
1447 + *p = '\0';
1448 + fp = dt_module_getctflib(dtp, dmp, buf);
1449 + if (fp == NULL || (id = ctf_lookup_by_name(fp,
1450 + p + 1)) == CTF_ERR)
1451 + id = CTF_ERR;
1452 + free(buf);
1453 + } else {
1454 + for (i = 0; i < dmp->dm_nctflibs; i++) {
1455 + fp = dmp->dm_libctfp[i];
1456 + id = ctf_lookup_by_name(fp, name);
1457 + if (id != CTF_ERR)
1458 + break;
1459 + }
1460 + }
1461 + }
1462 + if (id != CTF_ERR) {
1196 1463 tip->dtt_object = dmp->dm_name;
1197 - tip->dtt_ctfp = dmp->dm_ctfp;
1464 + tip->dtt_ctfp = fp;
1198 1465 tip->dtt_type = id;
1199 -
1200 - if (ctf_type_kind(dmp->dm_ctfp, ctf_type_resolve(
1201 - dmp->dm_ctfp, id)) != CTF_K_FORWARD)
1466 + if (ctf_type_kind(fp, ctf_type_resolve(fp, id)) !=
1467 + CTF_K_FORWARD)
1202 1468 return (0);
1203 1469
1204 1470 found++;
1205 1471 }
1206 1472 }
1207 1473
1208 1474 if (found == 0)
1209 1475 return (dt_set_errno(dtp, EDT_NOTYPE));
1210 1476
1211 1477 return (0);
1212 1478 }
↓ open down ↓ |
1 lines elided |
↑ open up ↑ |
1213 1479
1214 1480 int
1215 1481 dtrace_symbol_type(dtrace_hdl_t *dtp, const GElf_Sym *symp,
1216 1482 const dtrace_syminfo_t *sip, dtrace_typeinfo_t *tip)
1217 1483 {
1218 1484 dt_module_t *dmp;
1219 1485
1220 1486 tip->dtt_object = NULL;
1221 1487 tip->dtt_ctfp = NULL;
1222 1488 tip->dtt_type = CTF_ERR;
1489 + tip->dtt_flags = 0;
1223 1490
1224 1491 if ((dmp = dt_module_lookup_by_name(dtp, sip->dts_object)) == NULL)
1225 1492 return (dt_set_errno(dtp, EDT_NOMOD));
1226 1493
1227 1494 if (symp->st_shndx == SHN_UNDEF && dmp->dm_extern != NULL) {
1228 1495 dt_ident_t *idp =
1229 1496 dt_idhash_lookup(dmp->dm_extern, sip->dts_name);
1230 1497
1231 1498 if (idp == NULL)
1232 1499 return (dt_set_errno(dtp, EDT_NOSYM));
1233 1500
1234 1501 tip->dtt_ctfp = idp->di_ctfp;
1235 1502 tip->dtt_type = idp->di_type;
1236 1503
1237 1504 } else if (GELF_ST_TYPE(symp->st_info) != STT_FUNC) {
1238 1505 if (dt_module_getctf(dtp, dmp) == NULL)
1239 1506 return (-1); /* errno is set for us */
1240 1507
1241 1508 tip->dtt_ctfp = dmp->dm_ctfp;
1242 1509 tip->dtt_type = ctf_lookup_by_symbol(dmp->dm_ctfp, sip->dts_id);
1243 1510
1244 1511 if (tip->dtt_type == CTF_ERR) {
1245 1512 dtp->dt_ctferr = ctf_errno(tip->dtt_ctfp);
1246 1513 return (dt_set_errno(dtp, EDT_CTF));
1247 1514 }
1248 1515
1249 1516 } else {
1250 1517 tip->dtt_ctfp = DT_FPTR_CTFP(dtp);
1251 1518 tip->dtt_type = DT_FPTR_TYPE(dtp);
1252 1519 }
1253 1520
1254 1521 tip->dtt_object = dmp->dm_name;
1255 1522 return (0);
1256 1523 }
1257 1524
1258 1525 static dtrace_objinfo_t *
1259 1526 dt_module_info(const dt_module_t *dmp, dtrace_objinfo_t *dto)
1260 1527 {
1261 1528 dto->dto_name = dmp->dm_name;
1262 1529 dto->dto_file = dmp->dm_file;
1263 1530 dto->dto_id = dmp->dm_modid;
1264 1531 dto->dto_flags = 0;
1265 1532
1266 1533 if (dmp->dm_flags & DT_DM_KERNEL)
1267 1534 dto->dto_flags |= DTRACE_OBJ_F_KERNEL;
1268 1535 if (dmp->dm_flags & DT_DM_PRIMARY)
1269 1536 dto->dto_flags |= DTRACE_OBJ_F_PRIMARY;
1270 1537
1271 1538 dto->dto_text_va = dmp->dm_text_va;
1272 1539 dto->dto_text_size = dmp->dm_text_size;
1273 1540 dto->dto_data_va = dmp->dm_data_va;
1274 1541 dto->dto_data_size = dmp->dm_data_size;
1275 1542 dto->dto_bss_va = dmp->dm_bss_va;
1276 1543 dto->dto_bss_size = dmp->dm_bss_size;
1277 1544
1278 1545 return (dto);
1279 1546 }
1280 1547
1281 1548 int
1282 1549 dtrace_object_iter(dtrace_hdl_t *dtp, dtrace_obj_f *func, void *data)
1283 1550 {
1284 1551 const dt_module_t *dmp = dt_list_next(&dtp->dt_modlist);
1285 1552 dtrace_objinfo_t dto;
1286 1553 int rv;
1287 1554
1288 1555 for (; dmp != NULL; dmp = dt_list_next(dmp)) {
1289 1556 if ((rv = (*func)(dtp, dt_module_info(dmp, &dto), data)) != 0)
1290 1557 return (rv);
1291 1558 }
1292 1559
1293 1560 return (0);
1294 1561 }
1295 1562
1296 1563 int
1297 1564 dtrace_object_info(dtrace_hdl_t *dtp, const char *object, dtrace_objinfo_t *dto)
1298 1565 {
1299 1566 dt_module_t *dmp;
1300 1567
1301 1568 if (object == DTRACE_OBJ_EVERY || object == DTRACE_OBJ_KMODS ||
1302 1569 object == DTRACE_OBJ_UMODS || dto == NULL)
1303 1570 return (dt_set_errno(dtp, EINVAL));
1304 1571
1305 1572 if ((dmp = dt_module_from_object(dtp, object)) == NULL)
1306 1573 return (-1); /* dt_errno is set for us */
1307 1574
1308 1575 if (dt_module_load(dtp, dmp) == -1)
1309 1576 return (-1); /* dt_errno is set for us */
1310 1577
1311 1578 (void) dt_module_info(dmp, dto);
1312 1579 return (0);
1313 1580 }
↓ open down ↓ |
81 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX