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