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