1 /*- 2 * Copyright (c) 2003-2008 Joseph Koshy 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27 #include <sys/cdefs.h> 28 __FBSDID("$FreeBSD$"); 29 30 #include <sys/types.h> 31 #include <sys/cpuset.h> 32 #include <sys/param.h> 33 #include <sys/endian.h> 34 #include <sys/pmc.h> 35 #include <sys/sysctl.h> 36 #include <sys/imgact_aout.h> 37 #include <sys/imgact_elf.h> 38 39 #include <netinet/in.h> 40 41 #include <assert.h> 42 #include <err.h> 43 #include <fcntl.h> 44 #include <pmc.h> 45 #include <pmclog.h> 46 #include <stdbool.h> 47 #include <stdio.h> 48 #include <stdlib.h> 49 #include <string.h> 50 #include <sysexits.h> 51 #include <unistd.h> 52 53 #include "libpmcstat.h" 54 55 #define min(A,B) ((A) < (B) ? (A) : (B)) 56 #define max(A,B) ((A) > (B) ? (A) : (B)) 57 58 /* 59 * Add the list of symbols in the given section to the list associated 60 * with the object. 61 */ 62 void 63 pmcstat_image_add_symbols(struct pmcstat_image *image, Elf *e, 64 Elf_Scn *scn, GElf_Shdr *sh) 65 { 66 int firsttime; 67 size_t n, newsyms, nshsyms, nfuncsyms; 68 struct pmcstat_symbol *symptr; 69 char *fnname; 70 GElf_Sym sym; 71 Elf_Data *data; 72 73 if ((data = elf_getdata(scn, NULL)) == NULL) 74 return; 75 76 /* 77 * Determine the number of functions named in this 78 * section. 79 */ 80 81 nshsyms = sh->sh_size / sh->sh_entsize; 82 for (n = nfuncsyms = 0; n < nshsyms; n++) { 83 if (gelf_getsym(data, (int) n, &sym) != &sym) 84 return; 85 if (GELF_ST_TYPE(sym.st_info) == STT_FUNC) 86 nfuncsyms++; 87 } 88 89 if (nfuncsyms == 0) 90 return; 91 92 /* 93 * Allocate space for the new entries. 94 */ 95 firsttime = image->pi_symbols == NULL; 96 symptr = reallocarray(image->pi_symbols, 97 image->pi_symcount + nfuncsyms, sizeof(*symptr)); 98 if (symptr == image->pi_symbols) /* realloc() failed. */ 99 return; 100 image->pi_symbols = symptr; 101 102 /* 103 * Append new symbols to the end of the current table. 104 */ 105 symptr += image->pi_symcount; 106 107 for (n = newsyms = 0; n < nshsyms; n++) { 108 if (gelf_getsym(data, (int) n, &sym) != &sym) 109 return; 110 if (GELF_ST_TYPE(sym.st_info) != STT_FUNC) 111 continue; 112 113 if (sym.st_shndx == STN_UNDEF) 114 continue; 115 116 if (!firsttime && pmcstat_symbol_search(image, sym.st_value)) 117 continue; /* We've seen this symbol already. */ 118 119 if ((fnname = elf_strptr(e, sh->sh_link, sym.st_name)) 120 == NULL) 121 continue; 122 123 #if defined(__aarch64__) || defined(__arm__) 124 /* Ignore ARM mapping symbols. */ 125 if (fnname[0] == '$' && 126 (fnname[1] == 'a' || fnname[1] == 't' || 127 fnname[1] == 'd' || fnname[1] == 'x')) 128 continue; 129 130 /* 131 * Clear LSB from starting addresses for functions 132 * which execute in Thumb mode. We should perhaps 133 * only do this for functions in a $t mapping symbol 134 * range, but parsing mapping symbols would be a lot 135 * of work and function addresses shouldn't have the 136 * LSB set otherwise. 137 */ 138 sym.st_value &= ~1; 139 #endif 140 141 symptr->ps_name = pmcstat_string_intern(fnname); 142 symptr->ps_start = sym.st_value - image->pi_vaddr; 143 symptr->ps_end = symptr->ps_start + sym.st_size; 144 145 symptr++; 146 newsyms++; 147 } 148 149 image->pi_symcount += newsyms; 150 if (image->pi_symcount == 0) 151 return; 152 153 assert(newsyms <= nfuncsyms); 154 155 /* 156 * Return space to the system if there were duplicates. 157 */ 158 if (newsyms < nfuncsyms) 159 image->pi_symbols = reallocarray(image->pi_symbols, 160 image->pi_symcount, sizeof(*symptr)); 161 162 /* 163 * Keep the list of symbols sorted. 164 */ 165 qsort(image->pi_symbols, image->pi_symcount, sizeof(*symptr), 166 pmcstat_symbol_compare); 167 168 /* 169 * Deal with function symbols that have a size of 'zero' by 170 * making them extend to the next higher address. These 171 * symbols are usually defined in assembly code. 172 */ 173 for (symptr = image->pi_symbols; 174 symptr < image->pi_symbols + (image->pi_symcount - 1); 175 symptr++) 176 if (symptr->ps_start == symptr->ps_end) 177 symptr->ps_end = (symptr+1)->ps_start; 178 } 179 180 /* 181 * Record the fact that PC values from 'start' to 'end' come from 182 * image 'image'. 183 */ 184 185 void 186 pmcstat_image_link(struct pmcstat_process *pp, struct pmcstat_image *image, 187 uintfptr_t start) 188 { 189 struct pmcstat_pcmap *pcm, *pcmnew; 190 uintfptr_t offset; 191 #ifdef __powerpc__ 192 unsigned long kernbase; 193 size_t kernbase_len; 194 #endif 195 196 assert(image->pi_type != PMCSTAT_IMAGE_UNKNOWN && 197 image->pi_type != PMCSTAT_IMAGE_INDETERMINABLE); 198 199 if ((pcmnew = malloc(sizeof(*pcmnew))) == NULL) 200 err(EX_OSERR, "ERROR: Cannot create a map entry"); 201 202 /* 203 * PowerPC kernel is of DYN type and it has a base address 204 * where it is initially loaded, before being relocated. 205 * As the address in 'start' is where the kernel was relocated to, 206 * but the symbols always use the original base address, we need to 207 * subtract it to get the correct offset. 208 */ 209 #ifdef __powerpc__ 210 if (pp->pp_pid == -1) { 211 kernbase = 0; 212 kernbase_len = sizeof(kernbase); 213 if (sysctlbyname("kern.base_address", &kernbase, &kernbase_len, 214 NULL, 0) == -1) 215 warnx( 216 "WARNING: Could not retrieve kernel base address"); 217 else 218 start -= kernbase; 219 } 220 #endif 221 222 /* 223 * Adjust the map entry to only cover the text portion 224 * of the object. 225 */ 226 227 offset = start - image->pi_vaddr; 228 pcmnew->ppm_lowpc = image->pi_start + offset; 229 pcmnew->ppm_highpc = image->pi_end + offset; 230 pcmnew->ppm_image = image; 231 232 assert(pcmnew->ppm_lowpc < pcmnew->ppm_highpc); 233 234 /* Overlapped mmap()'s are assumed to never occur. */ 235 TAILQ_FOREACH(pcm, &pp->pp_map, ppm_next) 236 if (pcm->ppm_lowpc >= pcmnew->ppm_highpc) 237 break; 238 239 if (pcm == NULL) 240 TAILQ_INSERT_TAIL(&pp->pp_map, pcmnew, ppm_next); 241 else 242 TAILQ_INSERT_BEFORE(pcm, pcmnew, ppm_next); 243 } 244 245 /* 246 * Determine whether a given executable image is an A.OUT object, and 247 * if so, fill in its parameters from the text file. 248 * Sets image->pi_type. 249 */ 250 251 void 252 pmcstat_image_get_aout_params(struct pmcstat_image *image, 253 struct pmcstat_args *args) 254 { 255 int fd; 256 ssize_t nbytes; 257 struct exec ex; 258 const char *path; 259 char buffer[PATH_MAX]; 260 261 path = pmcstat_string_unintern(image->pi_execpath); 262 assert(path != NULL); 263 264 if (image->pi_iskernelmodule) 265 errx(EX_SOFTWARE, 266 "ERROR: a.out kernel modules are unsupported \"%s\"", path); 267 268 (void) snprintf(buffer, sizeof(buffer), "%s%s", 269 args->pa_fsroot, path); 270 271 if ((fd = open(buffer, O_RDONLY, 0)) < 0 || 272 (nbytes = read(fd, &ex, sizeof(ex))) < 0) { 273 if (args->pa_verbosity >= 2) 274 warn("WARNING: Cannot determine type of \"%s\"", 275 path); 276 image->pi_type = PMCSTAT_IMAGE_INDETERMINABLE; 277 if (fd != -1) 278 (void) close(fd); 279 return; 280 } 281 282 (void) close(fd); 283 284 if ((unsigned) nbytes != sizeof(ex) || 285 N_BADMAG(ex)) 286 return; 287 288 image->pi_type = PMCSTAT_IMAGE_AOUT; 289 290 /* TODO: the rest of a.out processing */ 291 292 return; 293 } 294 295 /* 296 * Examine an ELF file to determine the size of its text segment. 297 * Sets image->pi_type if anything conclusive can be determined about 298 * this image. 299 */ 300 301 void 302 pmcstat_image_get_elf_params(struct pmcstat_image *image, 303 struct pmcstat_args *args) 304 { 305 int fd; 306 size_t i, nph, nsh; 307 const char *path, *elfbase; 308 char *p, *endp; 309 bool first_exec_segment; 310 uintfptr_t minva, maxva; 311 Elf *e; 312 Elf_Scn *scn; 313 GElf_Ehdr eh; 314 GElf_Phdr ph; 315 GElf_Shdr sh; 316 enum pmcstat_image_type image_type; 317 char buffer[PATH_MAX]; 318 char buffer_modules[PATH_MAX]; 319 320 assert(image->pi_type == PMCSTAT_IMAGE_UNKNOWN); 321 322 image->pi_start = minva = ~(uintfptr_t) 0; 323 image->pi_end = maxva = (uintfptr_t) 0; 324 image->pi_type = image_type = PMCSTAT_IMAGE_INDETERMINABLE; 325 image->pi_isdynamic = 0; 326 image->pi_dynlinkerpath = NULL; 327 image->pi_vaddr = 0; 328 329 path = pmcstat_string_unintern(image->pi_execpath); 330 assert(path != NULL); 331 332 /* 333 * Look for kernel modules under FSROOT/KERNELPATH/NAME and 334 * FSROOT/boot/modules/NAME, and user mode executable objects 335 * under FSROOT/PATHNAME. 336 */ 337 if (image->pi_iskernelmodule) { 338 (void) snprintf(buffer, sizeof(buffer), "%s%s/%s", 339 args->pa_fsroot, args->pa_kernel, path); 340 (void) snprintf(buffer_modules, sizeof(buffer_modules), 341 "%s/boot/modules/%s", args->pa_fsroot, path); 342 } else { 343 (void) snprintf(buffer, sizeof(buffer), "%s%s", 344 args->pa_fsroot, path); 345 } 346 347 e = NULL; 348 fd = open(buffer, O_RDONLY, 0); 349 if (fd < 0 && !image->pi_iskernelmodule) { 350 warnx("WARNING: Cannot open \"%s\".", 351 buffer); 352 goto done; 353 } 354 if (fd < 0 && (fd = open(buffer_modules, O_RDONLY, 0)) < 0) { 355 warnx("WARNING: Cannot open \"%s\" or \"%s\".", 356 buffer, buffer_modules); 357 goto done; 358 } 359 if (elf_version(EV_CURRENT) == EV_NONE) { 360 warnx("WARNING: failed to init elf\n"); 361 goto done; 362 } 363 364 if ((e = elf_begin(fd, ELF_C_READ, NULL)) == NULL) { 365 warnx("WARNING: Cannot read \"%s\".", 366 buffer); 367 goto done; 368 } 369 370 if (elf_kind(e) != ELF_K_ELF) { 371 if (args->pa_verbosity >= 2) 372 warnx("WARNING: Cannot determine the type of \"%s\".", 373 buffer); 374 goto done; 375 } 376 377 if (gelf_getehdr(e, &eh) != &eh) { 378 warnx( 379 "WARNING: Cannot retrieve the ELF Header for \"%s\": %s.", 380 buffer, elf_errmsg(-1)); 381 goto done; 382 } 383 384 if (eh.e_type != ET_EXEC && eh.e_type != ET_DYN && 385 !(image->pi_iskernelmodule && eh.e_type == ET_REL)) { 386 warnx("WARNING: \"%s\" is of an unsupported ELF type.", 387 buffer); 388 goto done; 389 } 390 391 image_type = eh.e_ident[EI_CLASS] == ELFCLASS32 ? 392 PMCSTAT_IMAGE_ELF32 : PMCSTAT_IMAGE_ELF64; 393 394 /* 395 * Determine the virtual address where an executable would be 396 * loaded. Additionally, for dynamically linked executables, 397 * save the pathname to the runtime linker. 398 */ 399 if (eh.e_type != ET_REL) { 400 if (elf_getphnum(e, &nph) == 0) { 401 warnx( 402 "WARNING: Could not determine the number of program headers in \"%s\": %s.", 403 buffer, 404 elf_errmsg(-1)); 405 goto done; 406 } 407 first_exec_segment = true; 408 for (i = 0; i < eh.e_phnum; i++) { 409 if (gelf_getphdr(e, i, &ph) != &ph) { 410 warnx( 411 "WARNING: Retrieval of PHDR entry #%ju in \"%s\" failed: %s.", 412 (uintmax_t) i, buffer, elf_errmsg(-1)); 413 goto done; 414 } 415 switch (ph.p_type) { 416 case PT_DYNAMIC: 417 image->pi_isdynamic = 1; 418 break; 419 case PT_INTERP: 420 if ((elfbase = elf_rawfile(e, NULL)) == NULL) { 421 warnx( 422 "WARNING: Cannot retrieve the interpreter for \"%s\": %s.", 423 buffer, elf_errmsg(-1)); 424 goto done; 425 } 426 image->pi_dynlinkerpath = 427 pmcstat_string_intern(elfbase + 428 ph.p_offset); 429 break; 430 case PT_LOAD: 431 if ((ph.p_flags & PF_X) != 0 && 432 first_exec_segment) { 433 image->pi_vaddr = ph.p_vaddr & (-ph.p_align); 434 first_exec_segment = false; 435 } 436 break; 437 } 438 } 439 } 440 441 /* 442 * Get the min and max VA associated with this ELF object. 443 */ 444 if (elf_getshnum(e, &nsh) == 0) { 445 warnx( 446 "WARNING: Could not determine the number of sections for \"%s\": %s.", 447 buffer, elf_errmsg(-1)); 448 goto done; 449 } 450 451 for (i = 0; i < nsh; i++) { 452 if ((scn = elf_getscn(e, i)) == NULL || 453 gelf_getshdr(scn, &sh) != &sh) { 454 warnx( 455 "WARNING: Could not retrieve section header #%ju in \"%s\": %s.", 456 (uintmax_t) i, buffer, elf_errmsg(-1)); 457 goto done; 458 } 459 if (sh.sh_flags & SHF_EXECINSTR) { 460 minva = min(minva, sh.sh_addr); 461 maxva = max(maxva, sh.sh_addr + sh.sh_size); 462 } 463 if (sh.sh_type == SHT_SYMTAB || sh.sh_type == SHT_DYNSYM) 464 pmcstat_image_add_symbols(image, e, scn, &sh); 465 } 466 467 image->pi_start = minva; 468 image->pi_end = maxva; 469 image->pi_type = image_type; 470 image->pi_fullpath = pmcstat_string_intern(buffer); 471 472 /* Build display name 473 */ 474 endp = buffer; 475 for (p = buffer; *p; p++) 476 if (*p == '/') 477 endp = p+1; 478 image->pi_name = pmcstat_string_intern(endp); 479 480 done: 481 (void) elf_end(e); 482 if (fd >= 0) 483 (void) close(fd); 484 return; 485 } 486 487 /* 488 * Given an image descriptor, determine whether it is an ELF, or AOUT. 489 * If no handler claims the image, set its type to 'INDETERMINABLE'. 490 */ 491 492 void 493 pmcstat_image_determine_type(struct pmcstat_image *image, 494 struct pmcstat_args *args) 495 { 496 assert(image->pi_type == PMCSTAT_IMAGE_UNKNOWN); 497 498 /* Try each kind of handler in turn */ 499 if (image->pi_type == PMCSTAT_IMAGE_UNKNOWN) 500 pmcstat_image_get_elf_params(image, args); 501 if (image->pi_type == PMCSTAT_IMAGE_UNKNOWN) 502 pmcstat_image_get_aout_params(image, args); 503 504 /* 505 * Otherwise, remember that we tried to determine 506 * the object's type and had failed. 507 */ 508 if (image->pi_type == PMCSTAT_IMAGE_UNKNOWN) 509 image->pi_type = PMCSTAT_IMAGE_INDETERMINABLE; 510 } 511 512 /* 513 * Locate an image descriptor given an interned path, adding a fresh 514 * descriptor to the cache if necessary. This function also finds a 515 * suitable name for this image's sample file. 516 * 517 * We defer filling in the file format specific parts of the image 518 * structure till the time we actually see a sample that would fall 519 * into this image. 520 */ 521 522 struct pmcstat_image * 523 pmcstat_image_from_path(pmcstat_interned_string internedpath, 524 int iskernelmodule, struct pmcstat_args *args, 525 struct pmc_plugins *plugins) 526 { 527 int hash; 528 struct pmcstat_image *pi; 529 530 hash = pmcstat_string_lookup_hash(internedpath); 531 532 /* First, look for an existing entry. */ 533 LIST_FOREACH(pi, &pmcstat_image_hash[hash], pi_next) 534 if (pi->pi_execpath == internedpath && 535 pi->pi_iskernelmodule == iskernelmodule) 536 return (pi); 537 538 /* 539 * Allocate a new entry and place it at the head of the hash 540 * and LRU lists. 541 */ 542 pi = malloc(sizeof(*pi)); 543 if (pi == NULL) 544 return (NULL); 545 546 pi->pi_type = PMCSTAT_IMAGE_UNKNOWN; 547 pi->pi_execpath = internedpath; 548 pi->pi_start = ~0; 549 pi->pi_end = 0; 550 pi->pi_entry = 0; 551 pi->pi_vaddr = 0; 552 pi->pi_isdynamic = 0; 553 pi->pi_iskernelmodule = iskernelmodule; 554 pi->pi_dynlinkerpath = NULL; 555 pi->pi_symbols = NULL; 556 pi->pi_symcount = 0; 557 pi->pi_addr2line = NULL; 558 559 if (plugins[args->pa_pplugin].pl_initimage != NULL) 560 plugins[args->pa_pplugin].pl_initimage(pi); 561 if (plugins[args->pa_plugin].pl_initimage != NULL) 562 plugins[args->pa_plugin].pl_initimage(pi); 563 564 LIST_INSERT_HEAD(&pmcstat_image_hash[hash], pi, pi_next); 565 566 return (pi); 567 } 568