1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <assert.h> 30 #include <stdio.h> 31 #include <stdlib.h> 32 #include <stddef.h> 33 #include <unistd.h> 34 #include <ctype.h> 35 #include <fcntl.h> 36 #include <string.h> 37 #include <strings.h> 38 #include <memory.h> 39 #include <errno.h> 40 #include <dirent.h> 41 #include <signal.h> 42 #include <limits.h> 43 #include <libgen.h> 44 #include <zone.h> 45 #include <sys/types.h> 46 #include <sys/stat.h> 47 #include <sys/systeminfo.h> 48 #include <sys/sysmacros.h> 49 50 #include "libproc.h" 51 #include "Pcontrol.h" 52 #include "Putil.h" 53 54 static file_info_t *build_map_symtab(struct ps_prochandle *, map_info_t *); 55 static map_info_t *exec_map(struct ps_prochandle *); 56 static map_info_t *object_to_map(struct ps_prochandle *, Lmid_t, const char *); 57 static map_info_t *object_name_to_map(struct ps_prochandle *, 58 Lmid_t, const char *); 59 static GElf_Sym *sym_by_name(sym_tbl_t *, const char *, GElf_Sym *, uint_t *); 60 static int read_ehdr32(struct ps_prochandle *, Elf32_Ehdr *, uint_t *, 61 uintptr_t); 62 #ifdef _LP64 63 static int read_ehdr64(struct ps_prochandle *, Elf64_Ehdr *, uint_t *, 64 uintptr_t); 65 #endif 66 67 #define DATA_TYPES \ 68 ((1 << STT_OBJECT) | (1 << STT_FUNC) | \ 69 (1 << STT_COMMON) | (1 << STT_TLS)) 70 #define IS_DATA_TYPE(tp) (((1 << (tp)) & DATA_TYPES) != 0) 71 72 #define MA_RWX (MA_READ | MA_WRITE | MA_EXEC) 73 74 typedef enum { 75 PRO_NATURAL, 76 PRO_BYADDR, 77 PRO_BYNAME 78 } pr_order_t; 79 80 static int 81 addr_cmp(const void *aa, const void *bb) 82 { 83 uintptr_t a = *((uintptr_t *)aa); 84 uintptr_t b = *((uintptr_t *)bb); 85 86 if (a > b) 87 return (1); 88 if (a < b) 89 return (-1); 90 return (0); 91 } 92 93 /* 94 * This function creates a list of addresses for a load object's sections. 95 * The list is in ascending address order and alternates start address 96 * then end address for each section we're interested in. The function 97 * returns a pointer to the list, which must be freed by the caller. 98 */ 99 static uintptr_t * 100 get_saddrs(struct ps_prochandle *P, uintptr_t ehdr_start, uint_t *n) 101 { 102 uintptr_t a, addr, *addrs, last = 0; 103 uint_t i, naddrs = 0, unordered = 0; 104 105 if (P->status.pr_dmodel == PR_MODEL_ILP32) { 106 Elf32_Ehdr ehdr; 107 Elf32_Phdr phdr; 108 uint_t phnum; 109 110 if (read_ehdr32(P, &ehdr, &phnum, ehdr_start) != 0) 111 return (NULL); 112 113 addrs = malloc(sizeof (uintptr_t) * phnum * 2); 114 a = ehdr_start + ehdr.e_phoff; 115 for (i = 0; i < phnum; i++, a += ehdr.e_phentsize) { 116 if (Pread(P, &phdr, sizeof (phdr), a) != 117 sizeof (phdr)) { 118 free(addrs); 119 return (NULL); 120 } 121 if (phdr.p_type != PT_LOAD || phdr.p_memsz == 0) 122 continue; 123 124 addr = phdr.p_vaddr; 125 if (ehdr.e_type == ET_DYN) 126 addr += ehdr_start; 127 if (last > addr) 128 unordered = 1; 129 addrs[naddrs++] = addr; 130 addrs[naddrs++] = last = addr + phdr.p_memsz - 1; 131 } 132 #ifdef _LP64 133 } else { 134 Elf64_Ehdr ehdr; 135 Elf64_Phdr phdr; 136 uint_t phnum; 137 138 if (read_ehdr64(P, &ehdr, &phnum, ehdr_start) != 0) 139 return (NULL); 140 141 addrs = malloc(sizeof (uintptr_t) * phnum * 2); 142 a = ehdr_start + ehdr.e_phoff; 143 for (i = 0; i < phnum; i++, a += ehdr.e_phentsize) { 144 if (Pread(P, &phdr, sizeof (phdr), a) != 145 sizeof (phdr)) { 146 free(addrs); 147 return (NULL); 148 } 149 if (phdr.p_type != PT_LOAD || phdr.p_memsz == 0) 150 continue; 151 152 addr = phdr.p_vaddr; 153 if (ehdr.e_type == ET_DYN) 154 addr += ehdr_start; 155 if (last > addr) 156 unordered = 1; 157 addrs[naddrs++] = addr; 158 addrs[naddrs++] = last = addr + phdr.p_memsz - 1; 159 } 160 #endif 161 } 162 163 if (unordered) 164 qsort(addrs, naddrs, sizeof (uintptr_t), addr_cmp); 165 166 *n = naddrs; 167 return (addrs); 168 } 169 170 /* 171 * Allocation function for a new file_info_t 172 */ 173 static file_info_t * 174 file_info_new(struct ps_prochandle *P, map_info_t *mptr) 175 { 176 file_info_t *fptr; 177 map_info_t *mp; 178 uintptr_t addr; 179 uint_t i, j; 180 181 if ((fptr = calloc(1, sizeof (file_info_t))) == NULL) 182 return (NULL); 183 184 list_link(fptr, &P->file_head); 185 (void) strcpy(fptr->file_pname, mptr->map_pmap.pr_mapname); 186 mptr->map_file = fptr; 187 fptr->file_ref = 1; 188 fptr->file_fd = -1; 189 P->num_files++; 190 191 /* 192 * To figure out which map_info_t instances correspond to the mappings 193 * for this load object we try to obtain the start and end address 194 * for each section of our in-memory ELF image. If successful, we 195 * walk down the list of addresses and the list of map_info_t 196 * instances in lock step to correctly find the mappings that 197 * correspond to this load object. 198 */ 199 if ((fptr->file_saddrs = get_saddrs(P, mptr->map_pmap.pr_vaddr, 200 &fptr->file_nsaddrs)) == NULL) 201 return (fptr); 202 203 i = j = 0; 204 mp = P->mappings; 205 while (j < P->map_count && i < fptr->file_nsaddrs) { 206 addr = fptr->file_saddrs[i]; 207 if (addr >= mp->map_pmap.pr_vaddr && 208 addr < mp->map_pmap.pr_vaddr + mp->map_pmap.pr_size && 209 mp->map_file == NULL) { 210 mp->map_file = fptr; 211 fptr->file_ref++; 212 } 213 214 if (addr < mp->map_pmap.pr_vaddr + mp->map_pmap.pr_size) { 215 i++; 216 } else { 217 mp++; 218 j++; 219 } 220 } 221 222 return (fptr); 223 } 224 225 /* 226 * Deallocation function for a file_info_t 227 */ 228 static void 229 file_info_free(struct ps_prochandle *P, file_info_t *fptr) 230 { 231 if (--fptr->file_ref == 0) { 232 list_unlink(fptr); 233 if (fptr->file_symtab.sym_elf) { 234 (void) elf_end(fptr->file_symtab.sym_elf); 235 free(fptr->file_symtab.sym_elfmem); 236 } 237 if (fptr->file_symtab.sym_byname) 238 free(fptr->file_symtab.sym_byname); 239 if (fptr->file_symtab.sym_byaddr) 240 free(fptr->file_symtab.sym_byaddr); 241 242 if (fptr->file_dynsym.sym_elf) { 243 (void) elf_end(fptr->file_dynsym.sym_elf); 244 free(fptr->file_dynsym.sym_elfmem); 245 } 246 if (fptr->file_dynsym.sym_byname) 247 free(fptr->file_dynsym.sym_byname); 248 if (fptr->file_dynsym.sym_byaddr) 249 free(fptr->file_dynsym.sym_byaddr); 250 251 if (fptr->file_lo) 252 free(fptr->file_lo); 253 if (fptr->file_lname) 254 free(fptr->file_lname); 255 if (fptr->file_elf) 256 (void) elf_end(fptr->file_elf); 257 if (fptr->file_elfmem != NULL) 258 free(fptr->file_elfmem); 259 if (fptr->file_fd >= 0) 260 (void) close(fptr->file_fd); 261 if (fptr->file_ctfp) { 262 ctf_close(fptr->file_ctfp); 263 free(fptr->file_ctf_buf); 264 } 265 if (fptr->file_saddrs) 266 free(fptr->file_saddrs); 267 free(fptr); 268 P->num_files--; 269 } 270 } 271 272 /* 273 * Deallocation function for a map_info_t 274 */ 275 static void 276 map_info_free(struct ps_prochandle *P, map_info_t *mptr) 277 { 278 file_info_t *fptr; 279 280 if ((fptr = mptr->map_file) != NULL) { 281 if (fptr->file_map == mptr) 282 fptr->file_map = NULL; 283 file_info_free(P, fptr); 284 } 285 if (P->execname && mptr == P->map_exec) { 286 free(P->execname); 287 P->execname = NULL; 288 } 289 if (P->auxv && (mptr == P->map_exec || mptr == P->map_ldso)) { 290 free(P->auxv); 291 P->auxv = NULL; 292 P->nauxv = 0; 293 } 294 if (mptr == P->map_exec) 295 P->map_exec = NULL; 296 if (mptr == P->map_ldso) 297 P->map_ldso = NULL; 298 } 299 300 /* 301 * Call-back function for librtld_db to iterate through all of its shared 302 * libraries. We use this to get the load object names for the mappings. 303 */ 304 static int 305 map_iter(const rd_loadobj_t *lop, void *cd) 306 { 307 char buf[PATH_MAX]; 308 struct ps_prochandle *P = cd; 309 map_info_t *mptr; 310 file_info_t *fptr; 311 312 dprintf("encountered rd object at %p\n", (void *)lop->rl_base); 313 314 if ((mptr = Paddr2mptr(P, lop->rl_base)) == NULL) { 315 dprintf("map_iter: base address doesn't match any mapping\n"); 316 return (1); /* Base address does not match any mapping */ 317 } 318 319 if ((fptr = mptr->map_file) == NULL && 320 (fptr = file_info_new(P, mptr)) == NULL) { 321 dprintf("map_iter: failed to allocate a new file_info_t\n"); 322 return (1); /* Failed to allocate a new file_info_t */ 323 } 324 325 if ((fptr->file_lo == NULL) && 326 (fptr->file_lo = malloc(sizeof (rd_loadobj_t))) == NULL) { 327 dprintf("map_iter: failed to allocate rd_loadobj_t\n"); 328 file_info_free(P, fptr); 329 return (1); /* Failed to allocate rd_loadobj_t */ 330 } 331 332 fptr->file_map = mptr; 333 *fptr->file_lo = *lop; 334 335 fptr->file_lo->rl_plt_base = fptr->file_plt_base; 336 fptr->file_lo->rl_plt_size = fptr->file_plt_size; 337 338 if (fptr->file_lname) { 339 free(fptr->file_lname); 340 fptr->file_lname = NULL; 341 } 342 343 if (Pread_string(P, buf, sizeof (buf), lop->rl_nameaddr) > 0) { 344 if ((fptr->file_lname = strdup(buf)) != NULL) 345 fptr->file_lbase = basename(fptr->file_lname); 346 } else { 347 dprintf("map_iter: failed to read string at %p\n", 348 (void *)lop->rl_nameaddr); 349 } 350 351 dprintf("loaded rd object %s lmid %lx\n", 352 fptr->file_lname ? fptr->file_lname : "<NULL>", lop->rl_lmident); 353 return (1); 354 } 355 356 static void 357 map_set(struct ps_prochandle *P, map_info_t *mptr, const char *lname) 358 { 359 file_info_t *fptr; 360 361 if ((fptr = mptr->map_file) == NULL && 362 (fptr = file_info_new(P, mptr)) == NULL) 363 return; /* Failed to allocate a new file_info_t */ 364 365 fptr->file_map = mptr; 366 367 if ((fptr->file_lo == NULL) && 368 (fptr->file_lo = malloc(sizeof (rd_loadobj_t))) == NULL) { 369 file_info_free(P, fptr); 370 return; /* Failed to allocate rd_loadobj_t */ 371 } 372 373 (void) memset(fptr->file_lo, 0, sizeof (rd_loadobj_t)); 374 fptr->file_lo->rl_base = mptr->map_pmap.pr_vaddr; 375 fptr->file_lo->rl_bend = 376 mptr->map_pmap.pr_vaddr + mptr->map_pmap.pr_size; 377 378 fptr->file_lo->rl_plt_base = fptr->file_plt_base; 379 fptr->file_lo->rl_plt_size = fptr->file_plt_size; 380 381 if (fptr->file_lname == NULL && 382 (fptr->file_lname = strdup(lname)) != NULL) 383 fptr->file_lbase = basename(fptr->file_lname); 384 } 385 386 static void 387 load_static_maps(struct ps_prochandle *P) 388 { 389 map_info_t *mptr; 390 391 /* 392 * Construct the map for the a.out. 393 */ 394 if ((mptr = object_name_to_map(P, PR_LMID_EVERY, PR_OBJ_EXEC)) != NULL) 395 map_set(P, mptr, "a.out"); 396 397 /* 398 * If the dynamic linker exists for this process, 399 * construct the map for it. 400 */ 401 if (Pgetauxval(P, AT_BASE) != -1L && 402 (mptr = object_name_to_map(P, PR_LMID_EVERY, PR_OBJ_LDSO)) != NULL) 403 map_set(P, mptr, "ld.so.1"); 404 } 405 406 /* 407 * Go through all the address space mappings, validating or updating 408 * the information already gathered, or gathering new information. 409 * 410 * This function is only called when we suspect that the mappings have changed 411 * because this is the first time we're calling it or because of rtld activity. 412 */ 413 void 414 Pupdate_maps(struct ps_prochandle *P) 415 { 416 char mapfile[PATH_MAX]; 417 int mapfd; 418 struct stat statb; 419 prmap_t *Pmap = NULL; 420 prmap_t *pmap; 421 ssize_t nmap; 422 int i; 423 uint_t oldmapcount; 424 map_info_t *newmap, *newp; 425 map_info_t *mptr; 426 427 if (P->info_valid || P->state == PS_UNDEAD) 428 return; 429 430 Preadauxvec(P); 431 432 (void) snprintf(mapfile, sizeof (mapfile), "%s/%d/map", 433 procfs_path, (int)P->pid); 434 if ((mapfd = open(mapfile, O_RDONLY)) < 0 || 435 fstat(mapfd, &statb) != 0 || 436 statb.st_size < sizeof (prmap_t) || 437 (Pmap = malloc(statb.st_size)) == NULL || 438 (nmap = pread(mapfd, Pmap, statb.st_size, 0L)) <= 0 || 439 (nmap /= sizeof (prmap_t)) == 0) { 440 if (Pmap != NULL) 441 free(Pmap); 442 if (mapfd >= 0) 443 (void) close(mapfd); 444 Preset_maps(P); /* utter failure; destroy tables */ 445 return; 446 } 447 (void) close(mapfd); 448 449 if ((newmap = calloc(1, nmap * sizeof (map_info_t))) == NULL) 450 return; 451 452 /* 453 * We try to merge any file information we may have for existing 454 * mappings, to avoid having to rebuild the file info. 455 */ 456 mptr = P->mappings; 457 pmap = Pmap; 458 newp = newmap; 459 oldmapcount = P->map_count; 460 for (i = 0; i < nmap; i++, pmap++, newp++) { 461 462 if (oldmapcount == 0) { 463 /* 464 * We've exhausted all the old mappings. Every new 465 * mapping should be added. 466 */ 467 newp->map_pmap = *pmap; 468 469 } else if (pmap->pr_vaddr == mptr->map_pmap.pr_vaddr && 470 pmap->pr_size == mptr->map_pmap.pr_size && 471 pmap->pr_offset == mptr->map_pmap.pr_offset && 472 (pmap->pr_mflags & ~(MA_BREAK | MA_STACK)) == 473 (mptr->map_pmap.pr_mflags & ~(MA_BREAK | MA_STACK)) && 474 pmap->pr_pagesize == mptr->map_pmap.pr_pagesize && 475 pmap->pr_shmid == mptr->map_pmap.pr_shmid && 476 strcmp(pmap->pr_mapname, mptr->map_pmap.pr_mapname) == 0) { 477 478 /* 479 * This mapping matches exactly. Copy over the old 480 * mapping, taking care to get the latest flags. 481 * Make sure the associated file_info_t is updated 482 * appropriately. 483 */ 484 *newp = *mptr; 485 if (P->map_exec == mptr) 486 P->map_exec = newp; 487 if (P->map_ldso == mptr) 488 P->map_ldso = newp; 489 newp->map_pmap.pr_mflags = pmap->pr_mflags; 490 if (mptr->map_file != NULL && 491 mptr->map_file->file_map == mptr) 492 mptr->map_file->file_map = newp; 493 oldmapcount--; 494 mptr++; 495 496 } else if (pmap->pr_vaddr + pmap->pr_size > 497 mptr->map_pmap.pr_vaddr) { 498 499 /* 500 * The old mapping doesn't exist any more, remove it 501 * from the list. 502 */ 503 map_info_free(P, mptr); 504 oldmapcount--; 505 i--; 506 newp--; 507 pmap--; 508 mptr++; 509 510 } else { 511 512 /* 513 * This is a new mapping, add it directly. 514 */ 515 newp->map_pmap = *pmap; 516 } 517 } 518 519 /* 520 * Free any old maps 521 */ 522 while (oldmapcount) { 523 map_info_free(P, mptr); 524 oldmapcount--; 525 mptr++; 526 } 527 528 free(Pmap); 529 if (P->mappings != NULL) 530 free(P->mappings); 531 P->mappings = newmap; 532 P->map_count = P->map_alloc = nmap; 533 P->info_valid = 1; 534 535 /* 536 * Consult librtld_db to get the load object 537 * names for all of the shared libraries. 538 */ 539 if (P->rap != NULL) 540 (void) rd_loadobj_iter(P->rap, map_iter, P); 541 } 542 543 /* 544 * Update all of the mappings and rtld_db as if by Pupdate_maps(), and then 545 * forcibly cache all of the symbol tables associated with all object files. 546 */ 547 void 548 Pupdate_syms(struct ps_prochandle *P) 549 { 550 file_info_t *fptr = list_next(&P->file_head); 551 int i; 552 553 Pupdate_maps(P); 554 555 for (i = 0; i < P->num_files; i++, fptr = list_next(fptr)) { 556 Pbuild_file_symtab(P, fptr); 557 (void) Pbuild_file_ctf(P, fptr); 558 } 559 } 560 561 /* 562 * Return the librtld_db agent handle for the victim process. 563 * The handle will become invalid at the next successful exec() and the 564 * client (caller of proc_rd_agent()) must not use it beyond that point. 565 * If the process is already dead, we've already tried our best to 566 * create the agent during core file initialization. 567 */ 568 rd_agent_t * 569 Prd_agent(struct ps_prochandle *P) 570 { 571 if (P->rap == NULL && P->state != PS_DEAD && P->state != PS_IDLE) { 572 Pupdate_maps(P); 573 if (P->num_files == 0) 574 load_static_maps(P); 575 rd_log(_libproc_debug); 576 if ((P->rap = rd_new(P)) != NULL) 577 (void) rd_loadobj_iter(P->rap, map_iter, P); 578 } 579 return (P->rap); 580 } 581 582 /* 583 * Return the prmap_t structure containing 'addr', but only if it 584 * is in the dynamic linker's link map and is the text section. 585 */ 586 const prmap_t * 587 Paddr_to_text_map(struct ps_prochandle *P, uintptr_t addr) 588 { 589 map_info_t *mptr; 590 591 if (!P->info_valid) 592 Pupdate_maps(P); 593 594 if ((mptr = Paddr2mptr(P, addr)) != NULL) { 595 file_info_t *fptr = build_map_symtab(P, mptr); 596 const prmap_t *pmp = &mptr->map_pmap; 597 598 if (fptr != NULL && fptr->file_lo != NULL && 599 fptr->file_lo->rl_base >= pmp->pr_vaddr && 600 fptr->file_lo->rl_base < pmp->pr_vaddr + pmp->pr_size) 601 return (pmp); 602 } 603 604 return (NULL); 605 } 606 607 /* 608 * Return the prmap_t structure containing 'addr' (no restrictions on 609 * the type of mapping). 610 */ 611 const prmap_t * 612 Paddr_to_map(struct ps_prochandle *P, uintptr_t addr) 613 { 614 map_info_t *mptr; 615 616 if (!P->info_valid) 617 Pupdate_maps(P); 618 619 if ((mptr = Paddr2mptr(P, addr)) != NULL) 620 return (&mptr->map_pmap); 621 622 return (NULL); 623 } 624 625 /* 626 * Convert a full or partial load object name to the prmap_t for its 627 * corresponding primary text mapping. 628 */ 629 const prmap_t * 630 Plmid_to_map(struct ps_prochandle *P, Lmid_t lmid, const char *name) 631 { 632 map_info_t *mptr; 633 634 if (name == PR_OBJ_EVERY) 635 return (NULL); /* A reasonable mistake */ 636 637 if ((mptr = object_name_to_map(P, lmid, name)) != NULL) 638 return (&mptr->map_pmap); 639 640 return (NULL); 641 } 642 643 const prmap_t * 644 Pname_to_map(struct ps_prochandle *P, const char *name) 645 { 646 return (Plmid_to_map(P, PR_LMID_EVERY, name)); 647 } 648 649 const rd_loadobj_t * 650 Paddr_to_loadobj(struct ps_prochandle *P, uintptr_t addr) 651 { 652 map_info_t *mptr; 653 654 if (!P->info_valid) 655 Pupdate_maps(P); 656 657 if ((mptr = Paddr2mptr(P, addr)) == NULL) 658 return (NULL); 659 660 /* 661 * By building the symbol table, we implicitly bring the PLT 662 * information up to date in the load object. 663 */ 664 (void) build_map_symtab(P, mptr); 665 666 return (mptr->map_file->file_lo); 667 } 668 669 const rd_loadobj_t * 670 Plmid_to_loadobj(struct ps_prochandle *P, Lmid_t lmid, const char *name) 671 { 672 map_info_t *mptr; 673 674 if (name == PR_OBJ_EVERY) 675 return (NULL); 676 677 if ((mptr = object_name_to_map(P, lmid, name)) == NULL) 678 return (NULL); 679 680 /* 681 * By building the symbol table, we implicitly bring the PLT 682 * information up to date in the load object. 683 */ 684 (void) build_map_symtab(P, mptr); 685 686 return (mptr->map_file->file_lo); 687 } 688 689 const rd_loadobj_t * 690 Pname_to_loadobj(struct ps_prochandle *P, const char *name) 691 { 692 return (Plmid_to_loadobj(P, PR_LMID_EVERY, name)); 693 } 694 695 ctf_file_t * 696 Pbuild_file_ctf(struct ps_prochandle *P, file_info_t *fptr) 697 { 698 ctf_sect_t ctdata, symtab, strtab; 699 sym_tbl_t *symp; 700 int err; 701 702 if (fptr->file_ctfp != NULL) 703 return (fptr->file_ctfp); 704 705 Pbuild_file_symtab(P, fptr); 706 707 if (fptr->file_ctf_size == 0) 708 return (NULL); 709 710 symp = fptr->file_ctf_dyn ? &fptr->file_dynsym : &fptr->file_symtab; 711 if (symp->sym_data == NULL) 712 return (NULL); 713 714 /* 715 * The buffer may alread be allocated if this is a core file that 716 * contained CTF data for this file. 717 */ 718 if (fptr->file_ctf_buf == NULL) { 719 fptr->file_ctf_buf = malloc(fptr->file_ctf_size); 720 if (fptr->file_ctf_buf == NULL) { 721 dprintf("failed to allocate ctf buffer\n"); 722 return (NULL); 723 } 724 725 if (pread(fptr->file_fd, fptr->file_ctf_buf, 726 fptr->file_ctf_size, fptr->file_ctf_off) != 727 fptr->file_ctf_size) { 728 free(fptr->file_ctf_buf); 729 fptr->file_ctf_buf = NULL; 730 dprintf("failed to read ctf data\n"); 731 return (NULL); 732 } 733 } 734 735 ctdata.cts_name = ".SUNW_ctf"; 736 ctdata.cts_type = SHT_PROGBITS; 737 ctdata.cts_flags = 0; 738 ctdata.cts_data = fptr->file_ctf_buf; 739 ctdata.cts_size = fptr->file_ctf_size; 740 ctdata.cts_entsize = 1; 741 ctdata.cts_offset = 0; 742 743 symtab.cts_name = fptr->file_ctf_dyn ? ".dynsym" : ".symtab"; 744 symtab.cts_type = symp->sym_hdr.sh_type; 745 symtab.cts_flags = symp->sym_hdr.sh_flags; 746 symtab.cts_data = symp->sym_data->d_buf; 747 symtab.cts_size = symp->sym_hdr.sh_size; 748 symtab.cts_entsize = symp->sym_hdr.sh_entsize; 749 symtab.cts_offset = symp->sym_hdr.sh_offset; 750 751 strtab.cts_name = fptr->file_ctf_dyn ? ".dynstr" : ".strtab"; 752 strtab.cts_type = symp->sym_strhdr.sh_type; 753 strtab.cts_flags = symp->sym_strhdr.sh_flags; 754 strtab.cts_data = symp->sym_strs; 755 strtab.cts_size = symp->sym_strhdr.sh_size; 756 strtab.cts_entsize = symp->sym_strhdr.sh_entsize; 757 strtab.cts_offset = symp->sym_strhdr.sh_offset; 758 759 fptr->file_ctfp = ctf_bufopen(&ctdata, &symtab, &strtab, &err); 760 if (fptr->file_ctfp == NULL) { 761 free(fptr->file_ctf_buf); 762 fptr->file_ctf_buf = NULL; 763 return (NULL); 764 } 765 766 dprintf("loaded %lu bytes of CTF data for %s\n", 767 (ulong_t)fptr->file_ctf_size, fptr->file_pname); 768 769 return (fptr->file_ctfp); 770 } 771 772 ctf_file_t * 773 Paddr_to_ctf(struct ps_prochandle *P, uintptr_t addr) 774 { 775 map_info_t *mptr; 776 file_info_t *fptr; 777 778 if (!P->info_valid) 779 Pupdate_maps(P); 780 781 if ((mptr = Paddr2mptr(P, addr)) == NULL || 782 (fptr = mptr->map_file) == NULL) 783 return (NULL); 784 785 return (Pbuild_file_ctf(P, fptr)); 786 } 787 788 ctf_file_t * 789 Plmid_to_ctf(struct ps_prochandle *P, Lmid_t lmid, const char *name) 790 { 791 map_info_t *mptr; 792 file_info_t *fptr; 793 794 if (name == PR_OBJ_EVERY) 795 return (NULL); 796 797 if ((mptr = object_name_to_map(P, lmid, name)) == NULL || 798 (fptr = mptr->map_file) == NULL) 799 return (NULL); 800 801 return (Pbuild_file_ctf(P, fptr)); 802 } 803 804 ctf_file_t * 805 Pname_to_ctf(struct ps_prochandle *P, const char *name) 806 { 807 return (Plmid_to_ctf(P, PR_LMID_EVERY, name)); 808 } 809 810 /* 811 * If we're not a core file, re-read the /proc/<pid>/auxv file and store 812 * its contents in P->auxv. In the case of a core file, we either 813 * initialized P->auxv in Pcore() from the NT_AUXV, or we don't have an 814 * auxv because the note was missing. 815 */ 816 void 817 Preadauxvec(struct ps_prochandle *P) 818 { 819 char auxfile[64]; 820 struct stat statb; 821 ssize_t naux; 822 int fd; 823 824 if (P->state == PS_DEAD) 825 return; /* Already read during Pgrab_core() */ 826 if (P->state == PS_IDLE) 827 return; /* No aux vec for Pgrab_file() */ 828 829 if (P->auxv != NULL) { 830 free(P->auxv); 831 P->auxv = NULL; 832 P->nauxv = 0; 833 } 834 835 (void) snprintf(auxfile, sizeof (auxfile), "%s/%d/auxv", 836 procfs_path, (int)P->pid); 837 if ((fd = open(auxfile, O_RDONLY)) < 0) 838 return; 839 840 if (fstat(fd, &statb) == 0 && 841 statb.st_size >= sizeof (auxv_t) && 842 (P->auxv = malloc(statb.st_size + sizeof (auxv_t))) != NULL) { 843 if ((naux = read(fd, P->auxv, statb.st_size)) < 0 || 844 (naux /= sizeof (auxv_t)) < 1) { 845 free(P->auxv); 846 P->auxv = NULL; 847 } else { 848 P->auxv[naux].a_type = AT_NULL; 849 P->auxv[naux].a_un.a_val = 0L; 850 P->nauxv = (int)naux; 851 } 852 } 853 854 (void) close(fd); 855 } 856 857 /* 858 * Return a requested element from the process's aux vector. 859 * Return -1 on failure (this is adequate for our purposes). 860 */ 861 long 862 Pgetauxval(struct ps_prochandle *P, int type) 863 { 864 auxv_t *auxv; 865 866 if (P->auxv == NULL) 867 Preadauxvec(P); 868 869 if (P->auxv == NULL) 870 return (-1); 871 872 for (auxv = P->auxv; auxv->a_type != AT_NULL; auxv++) { 873 if (auxv->a_type == type) 874 return (auxv->a_un.a_val); 875 } 876 877 return (-1); 878 } 879 880 /* 881 * Return a pointer to our internal copy of the process's aux vector. 882 * The caller should not hold on to this pointer across any libproc calls. 883 */ 884 const auxv_t * 885 Pgetauxvec(struct ps_prochandle *P) 886 { 887 static const auxv_t empty = { AT_NULL, 0L }; 888 889 if (P->auxv == NULL) 890 Preadauxvec(P); 891 892 if (P->auxv == NULL) 893 return (&empty); 894 895 return (P->auxv); 896 } 897 898 /* 899 * Return 1 if the given mapping corresponds to the given file_info_t's 900 * load object; return 0 otherwise. 901 */ 902 static int 903 is_mapping_in_file(struct ps_prochandle *P, map_info_t *mptr, file_info_t *fptr) 904 { 905 prmap_t *pmap = &mptr->map_pmap; 906 rd_loadobj_t *lop = fptr->file_lo; 907 uint_t i; 908 909 /* 910 * We can get for free the start address of the text and data 911 * sections of the load object. Start by seeing if the mapping 912 * encloses either of these. 913 */ 914 if ((pmap->pr_vaddr <= lop->rl_base && 915 lop->rl_base < pmap->pr_vaddr + pmap->pr_size) || 916 (pmap->pr_vaddr <= lop->rl_data_base && 917 lop->rl_data_base < pmap->pr_vaddr + pmap->pr_size)) 918 return (1); 919 920 /* 921 * It's still possible that this mapping correponds to the load 922 * object. Consider the example of a mapping whose start and end 923 * addresses correspond to those of the load object's text section. 924 * If the mapping splits, e.g. as a result of a segment demotion, 925 * then although both mappings are still backed by the same section, 926 * only one will be seen to enclose that section's start address. 927 * Thus, to be rigorous, we ask not whether this mapping encloses 928 * the start of a section, but whether there exists a section that 929 * encloses the start of this mapping. 930 * 931 * If we don't already have the section addresses, and we successfully 932 * get them, then we cache them in case we come here again. 933 */ 934 if (fptr->file_saddrs == NULL && 935 (fptr->file_saddrs = get_saddrs(P, 936 fptr->file_map->map_pmap.pr_vaddr, &fptr->file_nsaddrs)) == NULL) 937 return (0); 938 for (i = 0; i < fptr->file_nsaddrs; i += 2) { 939 /* Does this section enclose the start of the mapping? */ 940 if (fptr->file_saddrs[i] <= pmap->pr_vaddr && 941 fptr->file_saddrs[i + 1] > pmap->pr_vaddr) 942 return (1); 943 } 944 945 return (0); 946 } 947 948 /* 949 * Find or build the symbol table for the given mapping. 950 */ 951 static file_info_t * 952 build_map_symtab(struct ps_prochandle *P, map_info_t *mptr) 953 { 954 prmap_t *pmap = &mptr->map_pmap; 955 file_info_t *fptr; 956 uint_t i; 957 958 if ((fptr = mptr->map_file) != NULL) { 959 Pbuild_file_symtab(P, fptr); 960 return (fptr); 961 } 962 963 if (pmap->pr_mapname[0] == '\0') 964 return (NULL); 965 966 /* 967 * Attempt to find a matching file. 968 * (A file can be mapped at several different addresses.) 969 */ 970 for (i = 0, fptr = list_next(&P->file_head); i < P->num_files; 971 i++, fptr = list_next(fptr)) { 972 if (strcmp(fptr->file_pname, pmap->pr_mapname) == 0 && 973 fptr->file_lo && is_mapping_in_file(P, mptr, fptr)) { 974 mptr->map_file = fptr; 975 fptr->file_ref++; 976 Pbuild_file_symtab(P, fptr); 977 return (fptr); 978 } 979 } 980 981 /* 982 * If we need to create a new file_info structure, iterate 983 * through the load objects in order to attempt to connect 984 * this new file with its primary text mapping. We again 985 * need to handle ld.so as a special case because we need 986 * to be able to bootstrap librtld_db. 987 */ 988 if ((fptr = file_info_new(P, mptr)) == NULL) 989 return (NULL); 990 991 if (P->map_ldso != mptr) { 992 if (P->rap != NULL) 993 (void) rd_loadobj_iter(P->rap, map_iter, P); 994 else 995 (void) Prd_agent(P); 996 } else { 997 fptr->file_map = mptr; 998 } 999 1000 /* 1001 * If librtld_db wasn't able to help us connect the file to a primary 1002 * text mapping, set file_map to the current mapping because we require 1003 * fptr->file_map to be set in Pbuild_file_symtab. librtld_db may be 1004 * unaware of what's going on in the rare case that a legitimate ELF 1005 * file has been mmap(2)ed into the process address space *without* 1006 * the use of dlopen(3x). 1007 */ 1008 if (fptr->file_map == NULL) 1009 fptr->file_map = mptr; 1010 1011 Pbuild_file_symtab(P, fptr); 1012 1013 return (fptr); 1014 } 1015 1016 static int 1017 read_ehdr32(struct ps_prochandle *P, Elf32_Ehdr *ehdr, uint_t *phnum, 1018 uintptr_t addr) 1019 { 1020 if (Pread(P, ehdr, sizeof (*ehdr), addr) != sizeof (*ehdr)) 1021 return (-1); 1022 1023 if (ehdr->e_ident[EI_MAG0] != ELFMAG0 || 1024 ehdr->e_ident[EI_MAG1] != ELFMAG1 || 1025 ehdr->e_ident[EI_MAG2] != ELFMAG2 || 1026 ehdr->e_ident[EI_MAG3] != ELFMAG3 || 1027 ehdr->e_ident[EI_CLASS] != ELFCLASS32 || 1028 #ifdef _BIG_ENDIAN 1029 ehdr->e_ident[EI_DATA] != ELFDATA2MSB || 1030 #else 1031 ehdr->e_ident[EI_DATA] != ELFDATA2LSB || 1032 #endif 1033 ehdr->e_ident[EI_VERSION] != EV_CURRENT) 1034 return (-1); 1035 1036 if ((*phnum = ehdr->e_phnum) == PN_XNUM) { 1037 Elf32_Shdr shdr0; 1038 1039 if (ehdr->e_shoff == 0 || ehdr->e_shentsize < sizeof (shdr0) || 1040 Pread(P, &shdr0, sizeof (shdr0), addr + ehdr->e_shoff) != 1041 sizeof (shdr0)) 1042 return (-1); 1043 1044 if (shdr0.sh_info != 0) 1045 *phnum = shdr0.sh_info; 1046 } 1047 1048 return (0); 1049 } 1050 1051 static int 1052 read_dynamic_phdr32(struct ps_prochandle *P, const Elf32_Ehdr *ehdr, 1053 uint_t phnum, Elf32_Phdr *phdr, uintptr_t addr) 1054 { 1055 uint_t i; 1056 1057 for (i = 0; i < phnum; i++) { 1058 uintptr_t a = addr + ehdr->e_phoff + i * ehdr->e_phentsize; 1059 if (Pread(P, phdr, sizeof (*phdr), a) != sizeof (*phdr)) 1060 return (-1); 1061 1062 if (phdr->p_type == PT_DYNAMIC) 1063 return (0); 1064 } 1065 1066 return (-1); 1067 } 1068 1069 #ifdef _LP64 1070 static int 1071 read_ehdr64(struct ps_prochandle *P, Elf64_Ehdr *ehdr, uint_t *phnum, 1072 uintptr_t addr) 1073 { 1074 if (Pread(P, ehdr, sizeof (Elf64_Ehdr), addr) != sizeof (Elf64_Ehdr)) 1075 return (-1); 1076 1077 if (ehdr->e_ident[EI_MAG0] != ELFMAG0 || 1078 ehdr->e_ident[EI_MAG1] != ELFMAG1 || 1079 ehdr->e_ident[EI_MAG2] != ELFMAG2 || 1080 ehdr->e_ident[EI_MAG3] != ELFMAG3 || 1081 ehdr->e_ident[EI_CLASS] != ELFCLASS64 || 1082 #ifdef _BIG_ENDIAN 1083 ehdr->e_ident[EI_DATA] != ELFDATA2MSB || 1084 #else 1085 ehdr->e_ident[EI_DATA] != ELFDATA2LSB || 1086 #endif 1087 ehdr->e_ident[EI_VERSION] != EV_CURRENT) 1088 return (-1); 1089 1090 if ((*phnum = ehdr->e_phnum) == PN_XNUM) { 1091 Elf64_Shdr shdr0; 1092 1093 if (ehdr->e_shoff == 0 || ehdr->e_shentsize < sizeof (shdr0) || 1094 Pread(P, &shdr0, sizeof (shdr0), addr + ehdr->e_shoff) != 1095 sizeof (shdr0)) 1096 return (-1); 1097 1098 if (shdr0.sh_info != 0) 1099 *phnum = shdr0.sh_info; 1100 } 1101 1102 return (0); 1103 } 1104 1105 static int 1106 read_dynamic_phdr64(struct ps_prochandle *P, const Elf64_Ehdr *ehdr, 1107 uint_t phnum, Elf64_Phdr *phdr, uintptr_t addr) 1108 { 1109 uint_t i; 1110 1111 for (i = 0; i < phnum; i++) { 1112 uintptr_t a = addr + ehdr->e_phoff + i * ehdr->e_phentsize; 1113 if (Pread(P, phdr, sizeof (*phdr), a) != sizeof (*phdr)) 1114 return (-1); 1115 1116 if (phdr->p_type == PT_DYNAMIC) 1117 return (0); 1118 } 1119 1120 return (-1); 1121 } 1122 #endif /* _LP64 */ 1123 1124 /* 1125 * The text segment for each load object contains the elf header and 1126 * program headers. We can use this information to determine if the 1127 * file that corresponds to the load object is the same file that 1128 * was loaded into the process's address space. There can be a discrepency 1129 * if a file is recompiled after the process is started or if the target 1130 * represents a core file from a differently configured system -- two 1131 * common examples. The DT_CHECKSUM entry in the dynamic section 1132 * provides an easy method of comparison. It is important to note that 1133 * the dynamic section usually lives in the data segment, but the meta 1134 * data we use to find the dynamic section lives in the text segment so 1135 * if either of those segments is absent we can't proceed. 1136 * 1137 * We're looking through the elf file for several items: the symbol tables 1138 * (both dynsym and symtab), the procedure linkage table (PLT) base, 1139 * size, and relocation base, and the CTF information. Most of this can 1140 * be recovered from the loaded image of the file itself, the exceptions 1141 * being the symtab and CTF data. 1142 * 1143 * First we try to open the file that we think corresponds to the load 1144 * object, if the DT_CHECKSUM values match, we're all set, and can simply 1145 * recover all the information we need from the file. If the values of 1146 * DT_CHECKSUM don't match, or if we can't access the file for whatever 1147 * reasaon, we fake up a elf file to use in its stead. If we can't read 1148 * the elf data in the process's address space, we fall back to using 1149 * the file even though it may give inaccurate information. 1150 * 1151 * The elf file that we fake up has to consist of sections for the 1152 * dynsym, the PLT and the dynamic section. Note that in the case of a 1153 * core file, we'll get the CTF data in the file_info_t later on from 1154 * a section embedded the core file (if it's present). 1155 * 1156 * file_differs() conservatively looks for mismatched files, identifying 1157 * a match when there is any ambiguity (since that's the legacy behavior). 1158 */ 1159 static int 1160 file_differs(struct ps_prochandle *P, Elf *elf, file_info_t *fptr) 1161 { 1162 Elf_Scn *scn; 1163 GElf_Shdr shdr; 1164 GElf_Dyn dyn; 1165 Elf_Data *data; 1166 uint_t i, ndyn; 1167 GElf_Xword cksum; 1168 uintptr_t addr; 1169 1170 if (fptr->file_map == NULL) 1171 return (0); 1172 1173 if ((Pcontent(P) & (CC_CONTENT_TEXT | CC_CONTENT_DATA)) != 1174 (CC_CONTENT_TEXT | CC_CONTENT_DATA)) 1175 return (0); 1176 1177 /* 1178 * First, we find the checksum value in the elf file. 1179 */ 1180 scn = NULL; 1181 while ((scn = elf_nextscn(elf, scn)) != NULL) { 1182 if (gelf_getshdr(scn, &shdr) != NULL && 1183 shdr.sh_type == SHT_DYNAMIC) 1184 goto found_shdr; 1185 } 1186 return (0); 1187 1188 found_shdr: 1189 if ((data = elf_getdata(scn, NULL)) == NULL) 1190 return (0); 1191 1192 if (P->status.pr_dmodel == PR_MODEL_ILP32) 1193 ndyn = shdr.sh_size / sizeof (Elf32_Dyn); 1194 #ifdef _LP64 1195 else if (P->status.pr_dmodel == PR_MODEL_LP64) 1196 ndyn = shdr.sh_size / sizeof (Elf64_Dyn); 1197 #endif 1198 else 1199 return (0); 1200 1201 for (i = 0; i < ndyn; i++) { 1202 if (gelf_getdyn(data, i, &dyn) != NULL && 1203 dyn.d_tag == DT_CHECKSUM) 1204 goto found_cksum; 1205 } 1206 1207 /* 1208 * The in-memory ELF has no DT_CHECKSUM section, but we will report it 1209 * as matching the file anyhow. 1210 */ 1211 return (0); 1212 1213 found_cksum: 1214 cksum = dyn.d_un.d_val; 1215 dprintf("elf cksum value is %llx\n", (u_longlong_t)cksum); 1216 1217 /* 1218 * Get the base of the text mapping that corresponds to this file. 1219 */ 1220 addr = fptr->file_map->map_pmap.pr_vaddr; 1221 1222 if (P->status.pr_dmodel == PR_MODEL_ILP32) { 1223 Elf32_Ehdr ehdr; 1224 Elf32_Phdr phdr; 1225 Elf32_Dyn dync, *dynp; 1226 uint_t phnum, i; 1227 1228 if (read_ehdr32(P, &ehdr, &phnum, addr) != 0 || 1229 read_dynamic_phdr32(P, &ehdr, phnum, &phdr, addr) != 0) 1230 return (0); 1231 1232 if (ehdr.e_type == ET_DYN) 1233 phdr.p_vaddr += addr; 1234 if ((dynp = malloc(phdr.p_filesz)) == NULL) 1235 return (0); 1236 dync.d_tag = DT_NULL; 1237 if (Pread(P, dynp, phdr.p_filesz, phdr.p_vaddr) != 1238 phdr.p_filesz) { 1239 free(dynp); 1240 return (0); 1241 } 1242 1243 for (i = 0; i < phdr.p_filesz / sizeof (Elf32_Dyn); i++) { 1244 if (dynp[i].d_tag == DT_CHECKSUM) 1245 dync = dynp[i]; 1246 } 1247 1248 free(dynp); 1249 1250 if (dync.d_tag != DT_CHECKSUM) 1251 return (0); 1252 1253 dprintf("image cksum value is %llx\n", 1254 (u_longlong_t)dync.d_un.d_val); 1255 return (dync.d_un.d_val != cksum); 1256 #ifdef _LP64 1257 } else if (P->status.pr_dmodel == PR_MODEL_LP64) { 1258 Elf64_Ehdr ehdr; 1259 Elf64_Phdr phdr; 1260 Elf64_Dyn dync, *dynp; 1261 uint_t phnum, i; 1262 1263 if (read_ehdr64(P, &ehdr, &phnum, addr) != 0 || 1264 read_dynamic_phdr64(P, &ehdr, phnum, &phdr, addr) != 0) 1265 return (0); 1266 1267 if (ehdr.e_type == ET_DYN) 1268 phdr.p_vaddr += addr; 1269 if ((dynp = malloc(phdr.p_filesz)) == NULL) 1270 return (0); 1271 dync.d_tag = DT_NULL; 1272 if (Pread(P, dynp, phdr.p_filesz, phdr.p_vaddr) != 1273 phdr.p_filesz) { 1274 free(dynp); 1275 return (0); 1276 } 1277 1278 for (i = 0; i < phdr.p_filesz / sizeof (Elf64_Dyn); i++) { 1279 if (dynp[i].d_tag == DT_CHECKSUM) 1280 dync = dynp[i]; 1281 } 1282 1283 free(dynp); 1284 1285 if (dync.d_tag != DT_CHECKSUM) 1286 return (0); 1287 1288 dprintf("image cksum value is %llx\n", 1289 (u_longlong_t)dync.d_un.d_val); 1290 return (dync.d_un.d_val != cksum); 1291 #endif /* _LP64 */ 1292 } 1293 1294 return (0); 1295 } 1296 1297 static Elf * 1298 fake_elf(struct ps_prochandle *P, file_info_t *fptr) 1299 { 1300 enum { 1301 DI_PLTGOT = 0, 1302 DI_JMPREL, 1303 DI_PLTRELSZ, 1304 DI_PLTREL, 1305 DI_SYMTAB, 1306 DI_HASH, 1307 DI_SYMENT, 1308 DI_STRTAB, 1309 DI_STRSZ, 1310 DI_NENT 1311 }; 1312 uintptr_t addr; 1313 size_t size = 0; 1314 caddr_t elfdata = NULL; 1315 Elf *elf; 1316 Elf32_Word nchain; 1317 static char shstr[] = ".shstrtab\0.dynsym\0.dynstr\0.dynamic\0.plt"; 1318 1319 if (fptr->file_map == NULL) 1320 return (NULL); 1321 1322 if ((Pcontent(P) & (CC_CONTENT_TEXT | CC_CONTENT_DATA)) != 1323 (CC_CONTENT_TEXT | CC_CONTENT_DATA)) 1324 return (NULL); 1325 1326 addr = fptr->file_map->map_pmap.pr_vaddr; 1327 1328 /* 1329 * We're building a in memory elf file that will let us use libelf 1330 * for most of the work we need to later (e.g. symbol table lookups). 1331 * We need sections for the dynsym, dynstr, and plt, and we need 1332 * the program headers from the text section. The former is used in 1333 * Pbuild_file_symtab(); the latter is used in several functions in 1334 * Pcore.c to reconstruct the origin of each mapping from the load 1335 * object that spawned it. 1336 * 1337 * Here are some useful pieces of elf trivia that will help 1338 * to elucidate this code. 1339 * 1340 * All the information we need about the dynstr can be found in these 1341 * two entries in the dynamic section: 1342 * 1343 * DT_STRTAB base of dynstr 1344 * DT_STRSZ size of dynstr 1345 * 1346 * So deciphering the dynstr is pretty straightforward. 1347 * 1348 * The dynsym is a little trickier. 1349 * 1350 * DT_SYMTAB base of dynsym 1351 * DT_SYMENT size of a dynstr entry (Elf{32,64}_Sym) 1352 * DT_HASH base of hash table for dynamic lookups 1353 * 1354 * The DT_SYMTAB entry gives us any easy way of getting to the base 1355 * of the dynsym, but getting the size involves rooting around in the 1356 * dynamic lookup hash table. Here's the layout of the hash table: 1357 * 1358 * +-------------------+ 1359 * | nbucket | All values are of type 1360 * +-------------------+ Elf32_Word 1361 * | nchain | 1362 * +-------------------+ 1363 * | bucket[0] | 1364 * | . . . | 1365 * | bucket[nbucket-1] | 1366 * +-------------------+ 1367 * | chain[0] | 1368 * | . . . | 1369 * | chain[nchain-1] | 1370 * +-------------------+ 1371 * (figure 5-12 from the SYS V Generic ABI) 1372 * 1373 * Symbols names are hashed into a particular bucket which contains 1374 * an index into the symbol table. Each entry in the symbol table 1375 * has a corresponding entry in the chain table which tells the 1376 * consumer where the next entry in the hash chain is. We can use 1377 * the nchain field to find out the size of the dynsym. 1378 * 1379 * We can figure out the size of the .plt section, but it takes some 1380 * doing. We need to use the following information: 1381 * 1382 * DT_PLTGOT base of the PLT 1383 * DT_JMPREL base of the PLT's relocation section 1384 * DT_PLTRELSZ size of the PLT's relocation section 1385 * DT_PLTREL type of the PLT's relocation section 1386 * 1387 * We can use the relocation section to figure out the address of the 1388 * last entry and subtract off the value of DT_PLTGOT to calculate 1389 * the size of the PLT. 1390 * 1391 * For more information, check out the System V Generic ABI. 1392 */ 1393 1394 if (P->status.pr_dmodel == PR_MODEL_ILP32) { 1395 Elf32_Ehdr ehdr, *ep; 1396 Elf32_Phdr phdr; 1397 Elf32_Shdr *sp; 1398 Elf32_Dyn *dp; 1399 Elf32_Dyn *d[DI_NENT] = { 0 }; 1400 uint_t phnum, i, dcount = 0; 1401 uint32_t off; 1402 size_t pltsz = 0, pltentsz; 1403 1404 if ((read_ehdr32(P, &ehdr, &phnum, addr) != 0) || 1405 read_dynamic_phdr32(P, &ehdr, phnum, &phdr, addr) != 0) 1406 return (NULL); 1407 1408 if (ehdr.e_type == ET_DYN) 1409 phdr.p_vaddr += addr; 1410 1411 if ((dp = malloc(phdr.p_filesz)) == NULL) 1412 return (NULL); 1413 1414 if (Pread(P, dp, phdr.p_filesz, phdr.p_vaddr) != 1415 phdr.p_filesz) 1416 goto bad32; 1417 1418 /* 1419 * Allow librtld_db the opportunity to "fix" the program 1420 * headers, if it needs to, before we process them. 1421 */ 1422 if (P->rap != NULL && ehdr.e_type == ET_DYN) { 1423 rd_fix_phdrs(P->rap, dp, phdr.p_filesz, addr); 1424 } 1425 1426 for (i = 0; i < phdr.p_filesz / sizeof (Elf32_Dyn); i++) { 1427 switch (dp[i].d_tag) { 1428 /* 1429 * For the .plt section. 1430 */ 1431 case DT_PLTGOT: 1432 d[DI_PLTGOT] = &dp[i]; 1433 continue; 1434 case DT_JMPREL: 1435 d[DI_JMPREL] = &dp[i]; 1436 continue; 1437 case DT_PLTRELSZ: 1438 d[DI_PLTRELSZ] = &dp[i]; 1439 continue; 1440 case DT_PLTREL: 1441 d[DI_PLTREL] = &dp[i]; 1442 continue; 1443 default: 1444 continue; 1445 1446 /* 1447 * For the .dynsym section. 1448 */ 1449 case DT_SYMTAB: 1450 d[DI_SYMTAB] = &dp[i]; 1451 break; 1452 case DT_HASH: 1453 d[DI_HASH] = &dp[i]; 1454 break; 1455 case DT_SYMENT: 1456 d[DI_SYMENT] = &dp[i]; 1457 break; 1458 1459 /* 1460 * For the .dynstr section. 1461 */ 1462 case DT_STRTAB: 1463 d[DI_STRTAB] = &dp[i]; 1464 break; 1465 case DT_STRSZ: 1466 d[DI_STRSZ] = &dp[i]; 1467 break; 1468 } 1469 1470 dcount++; 1471 } 1472 1473 /* 1474 * We need all of those dynamic entries in order to put 1475 * together a complete set of elf sections, but we'll 1476 * let the PLT section slide if need be. The dynsym- and 1477 * dynstr-related dynamic entries are mandatory in both 1478 * executables and shared objects so if one of those is 1479 * missing, we're in some trouble and should abort. 1480 */ 1481 if (dcount + 4 != DI_NENT) { 1482 dprintf("text section missing required dynamic " 1483 "entries\n"); 1484 goto bad32; 1485 } 1486 1487 if (ehdr.e_type == ET_DYN) { 1488 if (d[DI_PLTGOT] != NULL) 1489 d[DI_PLTGOT]->d_un.d_ptr += addr; 1490 if (d[DI_JMPREL] != NULL) 1491 d[DI_JMPREL]->d_un.d_ptr += addr; 1492 d[DI_SYMTAB]->d_un.d_ptr += addr; 1493 d[DI_HASH]->d_un.d_ptr += addr; 1494 d[DI_STRTAB]->d_un.d_ptr += addr; 1495 } 1496 1497 /* elf header */ 1498 size = sizeof (Elf32_Ehdr); 1499 1500 /* program headers from in-core elf fragment */ 1501 size += phnum * ehdr.e_phentsize; 1502 1503 /* unused shdr, and .shstrtab section */ 1504 size += sizeof (Elf32_Shdr); 1505 size += sizeof (Elf32_Shdr); 1506 size += roundup(sizeof (shstr), 4); 1507 1508 /* .dynsym section */ 1509 size += sizeof (Elf32_Shdr); 1510 if (Pread(P, &nchain, sizeof (nchain), 1511 d[DI_HASH]->d_un.d_ptr + 4) != sizeof (nchain)) { 1512 dprintf("Pread of .dynsym at %lx failed\n", 1513 (long)(d[DI_HASH]->d_un.d_val + 4)); 1514 goto bad32; 1515 } 1516 size += sizeof (Elf32_Sym) * nchain; 1517 1518 /* .dynstr section */ 1519 size += sizeof (Elf32_Shdr); 1520 size += roundup(d[DI_STRSZ]->d_un.d_val, 4); 1521 1522 /* .dynamic section */ 1523 size += sizeof (Elf32_Shdr); 1524 size += roundup(phdr.p_filesz, 4); 1525 1526 /* .plt section */ 1527 if (d[DI_PLTGOT] != NULL && d[DI_JMPREL] != NULL && 1528 d[DI_PLTRELSZ] != NULL && d[DI_PLTREL] != NULL) { 1529 uintptr_t penult, ult; 1530 uintptr_t jmprel = d[DI_JMPREL]->d_un.d_ptr; 1531 size_t pltrelsz = d[DI_PLTRELSZ]->d_un.d_val; 1532 1533 if (d[DI_PLTREL]->d_un.d_val == DT_RELA) { 1534 uint_t ndx = pltrelsz / sizeof (Elf32_Rela) - 2; 1535 Elf32_Rela r[2]; 1536 1537 if (Pread(P, r, sizeof (r), jmprel + 1538 sizeof (r[0]) * ndx) != sizeof (r)) { 1539 dprintf("Pread of DT_RELA failed\n"); 1540 goto bad32; 1541 } 1542 1543 penult = r[0].r_offset; 1544 ult = r[1].r_offset; 1545 1546 } else if (d[DI_PLTREL]->d_un.d_val == DT_REL) { 1547 uint_t ndx = pltrelsz / sizeof (Elf32_Rel) - 2; 1548 Elf32_Rel r[2]; 1549 1550 if (Pread(P, r, sizeof (r), jmprel + 1551 sizeof (r[0]) * ndx) != sizeof (r)) { 1552 dprintf("Pread of DT_REL failed\n"); 1553 goto bad32; 1554 } 1555 1556 penult = r[0].r_offset; 1557 ult = r[1].r_offset; 1558 } else { 1559 dprintf(".plt: unknown jmprel value\n"); 1560 goto bad32; 1561 } 1562 1563 pltentsz = ult - penult; 1564 1565 if (ehdr.e_type == ET_DYN) 1566 ult += addr; 1567 1568 pltsz = ult - d[DI_PLTGOT]->d_un.d_ptr + pltentsz; 1569 1570 size += sizeof (Elf32_Shdr); 1571 size += roundup(pltsz, 4); 1572 } 1573 1574 if ((elfdata = calloc(1, size)) == NULL) 1575 goto bad32; 1576 1577 /* LINTED - alignment */ 1578 ep = (Elf32_Ehdr *)elfdata; 1579 (void) memcpy(ep, &ehdr, offsetof(Elf32_Ehdr, e_phoff)); 1580 1581 ep->e_ehsize = sizeof (Elf32_Ehdr); 1582 ep->e_phoff = sizeof (Elf32_Ehdr); 1583 ep->e_phentsize = ehdr.e_phentsize; 1584 ep->e_phnum = phnum; 1585 ep->e_shoff = ep->e_phoff + phnum * ep->e_phentsize; 1586 ep->e_shentsize = sizeof (Elf32_Shdr); 1587 ep->e_shnum = (pltsz == 0) ? 5 : 6; 1588 ep->e_shstrndx = 1; 1589 1590 /* LINTED - alignment */ 1591 sp = (Elf32_Shdr *)(elfdata + ep->e_shoff); 1592 off = ep->e_shoff + ep->e_shentsize * ep->e_shnum; 1593 1594 /* 1595 * Copying the program headers directly from the process's 1596 * address space is a little suspect, but since we only 1597 * use them for their address and size values, this is fine. 1598 */ 1599 if (Pread(P, &elfdata[ep->e_phoff], phnum * ep->e_phentsize, 1600 addr + ehdr.e_phoff) != phnum * ep->e_phentsize) { 1601 free(elfdata); 1602 dprintf("failed to read program headers\n"); 1603 goto bad32; 1604 } 1605 1606 /* 1607 * The first elf section is always skipped. 1608 */ 1609 sp++; 1610 1611 /* 1612 * Section Header[1] sh_name: .shstrtab 1613 */ 1614 sp->sh_name = 0; 1615 sp->sh_type = SHT_STRTAB; 1616 sp->sh_flags = SHF_STRINGS; 1617 sp->sh_addr = 0; 1618 sp->sh_offset = off; 1619 sp->sh_size = sizeof (shstr); 1620 sp->sh_link = 0; 1621 sp->sh_info = 0; 1622 sp->sh_addralign = 1; 1623 sp->sh_entsize = 0; 1624 1625 (void) memcpy(&elfdata[off], shstr, sizeof (shstr)); 1626 off += roundup(sp->sh_size, 4); 1627 sp++; 1628 1629 /* 1630 * Section Header[2] sh_name: .dynsym 1631 */ 1632 sp->sh_name = 10; 1633 sp->sh_type = SHT_DYNSYM; 1634 sp->sh_flags = SHF_ALLOC; 1635 sp->sh_addr = d[DI_SYMTAB]->d_un.d_ptr; 1636 if (ehdr.e_type == ET_DYN) 1637 sp->sh_addr -= addr; 1638 sp->sh_offset = off; 1639 sp->sh_size = nchain * sizeof (Elf32_Sym); 1640 sp->sh_link = 3; 1641 sp->sh_info = 1; 1642 sp->sh_addralign = 4; 1643 sp->sh_entsize = sizeof (Elf32_Sym); 1644 1645 if (Pread(P, &elfdata[off], sp->sh_size, 1646 d[DI_SYMTAB]->d_un.d_ptr) != sp->sh_size) { 1647 free(elfdata); 1648 dprintf("failed to read .dynsym at %lx\n", 1649 (long)d[DI_SYMTAB]->d_un.d_ptr); 1650 goto bad32; 1651 } 1652 1653 off += roundup(sp->sh_size, 4); 1654 sp++; 1655 1656 /* 1657 * Section Header[3] sh_name: .dynstr 1658 */ 1659 sp->sh_name = 18; 1660 sp->sh_type = SHT_STRTAB; 1661 sp->sh_flags = SHF_ALLOC | SHF_STRINGS; 1662 sp->sh_addr = d[DI_STRTAB]->d_un.d_ptr; 1663 if (ehdr.e_type == ET_DYN) 1664 sp->sh_addr -= addr; 1665 sp->sh_offset = off; 1666 sp->sh_size = d[DI_STRSZ]->d_un.d_val; 1667 sp->sh_link = 0; 1668 sp->sh_info = 0; 1669 sp->sh_addralign = 1; 1670 sp->sh_entsize = 0; 1671 1672 if (Pread(P, &elfdata[off], sp->sh_size, 1673 d[DI_STRTAB]->d_un.d_ptr) != sp->sh_size) { 1674 free(elfdata); 1675 dprintf("failed to read .dynstr\n"); 1676 goto bad32; 1677 } 1678 off += roundup(sp->sh_size, 4); 1679 sp++; 1680 1681 /* 1682 * Section Header[4] sh_name: .dynamic 1683 */ 1684 sp->sh_name = 26; 1685 sp->sh_type = SHT_DYNAMIC; 1686 sp->sh_flags = SHF_WRITE | SHF_ALLOC; 1687 sp->sh_addr = phdr.p_vaddr; 1688 if (ehdr.e_type == ET_DYN) 1689 sp->sh_addr -= addr; 1690 sp->sh_offset = off; 1691 sp->sh_size = phdr.p_filesz; 1692 sp->sh_link = 3; 1693 sp->sh_info = 0; 1694 sp->sh_addralign = 4; 1695 sp->sh_entsize = sizeof (Elf32_Dyn); 1696 1697 (void) memcpy(&elfdata[off], dp, sp->sh_size); 1698 off += roundup(sp->sh_size, 4); 1699 sp++; 1700 1701 /* 1702 * Section Header[5] sh_name: .plt 1703 */ 1704 if (pltsz != 0) { 1705 sp->sh_name = 35; 1706 sp->sh_type = SHT_PROGBITS; 1707 sp->sh_flags = SHF_WRITE | SHF_ALLOC | SHF_EXECINSTR; 1708 sp->sh_addr = d[DI_PLTGOT]->d_un.d_ptr; 1709 if (ehdr.e_type == ET_DYN) 1710 sp->sh_addr -= addr; 1711 sp->sh_offset = off; 1712 sp->sh_size = pltsz; 1713 sp->sh_link = 0; 1714 sp->sh_info = 0; 1715 sp->sh_addralign = 4; 1716 sp->sh_entsize = pltentsz; 1717 1718 if (Pread(P, &elfdata[off], sp->sh_size, 1719 d[DI_PLTGOT]->d_un.d_ptr) != sp->sh_size) { 1720 free(elfdata); 1721 dprintf("failed to read .plt\n"); 1722 goto bad32; 1723 } 1724 off += roundup(sp->sh_size, 4); 1725 sp++; 1726 } 1727 1728 free(dp); 1729 goto good; 1730 1731 bad32: 1732 free(dp); 1733 return (NULL); 1734 #ifdef _LP64 1735 } else if (P->status.pr_dmodel == PR_MODEL_LP64) { 1736 Elf64_Ehdr ehdr, *ep; 1737 Elf64_Phdr phdr; 1738 Elf64_Shdr *sp; 1739 Elf64_Dyn *dp; 1740 Elf64_Dyn *d[DI_NENT] = { 0 }; 1741 uint_t phnum, i, dcount = 0; 1742 uint64_t off; 1743 size_t pltsz = 0, pltentsz; 1744 1745 if (read_ehdr64(P, &ehdr, &phnum, addr) != 0 || 1746 read_dynamic_phdr64(P, &ehdr, phnum, &phdr, addr) != 0) 1747 return (NULL); 1748 1749 if (ehdr.e_type == ET_DYN) 1750 phdr.p_vaddr += addr; 1751 1752 if ((dp = malloc(phdr.p_filesz)) == NULL) 1753 return (NULL); 1754 1755 if (Pread(P, dp, phdr.p_filesz, phdr.p_vaddr) != 1756 phdr.p_filesz) 1757 goto bad64; 1758 1759 for (i = 0; i < phdr.p_filesz / sizeof (Elf64_Dyn); i++) { 1760 switch (dp[i].d_tag) { 1761 /* 1762 * For the .plt section. 1763 */ 1764 case DT_PLTGOT: 1765 d[DI_PLTGOT] = &dp[i]; 1766 continue; 1767 case DT_JMPREL: 1768 d[DI_JMPREL] = &dp[i]; 1769 continue; 1770 case DT_PLTRELSZ: 1771 d[DI_PLTRELSZ] = &dp[i]; 1772 continue; 1773 case DT_PLTREL: 1774 d[DI_PLTREL] = &dp[i]; 1775 continue; 1776 default: 1777 continue; 1778 1779 /* 1780 * For the .dynsym section. 1781 */ 1782 case DT_SYMTAB: 1783 d[DI_SYMTAB] = &dp[i]; 1784 break; 1785 case DT_HASH: 1786 d[DI_HASH] = &dp[i]; 1787 break; 1788 case DT_SYMENT: 1789 d[DI_SYMENT] = &dp[i]; 1790 break; 1791 1792 /* 1793 * For the .dynstr section. 1794 */ 1795 case DT_STRTAB: 1796 d[DI_STRTAB] = &dp[i]; 1797 break; 1798 case DT_STRSZ: 1799 d[DI_STRSZ] = &dp[i]; 1800 break; 1801 } 1802 1803 dcount++; 1804 } 1805 1806 /* 1807 * We need all of those dynamic entries in order to put 1808 * together a complete set of elf sections, but we'll 1809 * let the PLT section slide if need be. The dynsym- and 1810 * dynstr-related dynamic entries are mandatory in both 1811 * executables and shared objects so if one of those is 1812 * missing, we're in some trouble and should abort. 1813 */ 1814 if (dcount + 4 != DI_NENT) { 1815 dprintf("text section missing required dynamic " 1816 "entries\n"); 1817 goto bad64; 1818 } 1819 1820 if (ehdr.e_type == ET_DYN) { 1821 if (d[DI_PLTGOT] != NULL) 1822 d[DI_PLTGOT]->d_un.d_ptr += addr; 1823 if (d[DI_JMPREL] != NULL) 1824 d[DI_JMPREL]->d_un.d_ptr += addr; 1825 d[DI_SYMTAB]->d_un.d_ptr += addr; 1826 d[DI_HASH]->d_un.d_ptr += addr; 1827 d[DI_STRTAB]->d_un.d_ptr += addr; 1828 } 1829 1830 /* elf header */ 1831 size = sizeof (Elf64_Ehdr); 1832 1833 /* program headers from in-core elf fragment */ 1834 size += phnum * ehdr.e_phentsize; 1835 1836 /* unused shdr, and .shstrtab section */ 1837 size += sizeof (Elf64_Shdr); 1838 size += sizeof (Elf64_Shdr); 1839 size += roundup(sizeof (shstr), 8); 1840 1841 /* .dynsym section */ 1842 size += sizeof (Elf64_Shdr); 1843 if (Pread(P, &nchain, sizeof (nchain), 1844 d[DI_HASH]->d_un.d_ptr + 4) != sizeof (nchain)) 1845 goto bad64; 1846 size += sizeof (Elf64_Sym) * nchain; 1847 1848 /* .dynstr section */ 1849 size += sizeof (Elf64_Shdr); 1850 size += roundup(d[DI_STRSZ]->d_un.d_val, 8); 1851 1852 /* .dynamic section */ 1853 size += sizeof (Elf64_Shdr); 1854 size += roundup(phdr.p_filesz, 8); 1855 1856 /* .plt section */ 1857 if (d[DI_PLTGOT] != NULL && d[DI_JMPREL] != NULL && 1858 d[DI_PLTRELSZ] != NULL && d[DI_PLTREL] != NULL) { 1859 uintptr_t penult, ult; 1860 uintptr_t jmprel = d[DI_JMPREL]->d_un.d_ptr; 1861 size_t pltrelsz = d[DI_PLTRELSZ]->d_un.d_val; 1862 1863 if (d[DI_PLTREL]->d_un.d_val == DT_RELA) { 1864 uint_t ndx = pltrelsz / sizeof (Elf64_Rela) - 2; 1865 Elf64_Rela r[2]; 1866 1867 if (Pread(P, r, sizeof (r), jmprel + 1868 sizeof (r[0]) * ndx) != sizeof (r)) { 1869 dprintf("Pread jmprel DT_RELA at %p " 1870 "failed\n", 1871 (void *)(jmprel + 1872 sizeof (r[0]) * ndx)); 1873 goto bad64; 1874 } 1875 1876 penult = r[0].r_offset; 1877 ult = r[1].r_offset; 1878 1879 } else if (d[DI_PLTREL]->d_un.d_val == DT_REL) { 1880 uint_t ndx = pltrelsz / sizeof (Elf64_Rel) - 2; 1881 Elf64_Rel r[2]; 1882 1883 if (Pread(P, r, sizeof (r), jmprel + 1884 sizeof (r[0]) * ndx) != sizeof (r)) { 1885 dprintf("Pread jmprel DT_REL at %p " 1886 "failed\n", 1887 (void *)(jmprel + 1888 sizeof (r[0]) * ndx)); 1889 goto bad64; 1890 } 1891 1892 penult = r[0].r_offset; 1893 ult = r[1].r_offset; 1894 } else { 1895 dprintf("DT_PLTREL value %p unknown\n", 1896 (void *)d[DI_PLTREL]->d_un.d_ptr); 1897 goto bad64; 1898 } 1899 1900 pltentsz = ult - penult; 1901 1902 if (ehdr.e_type == ET_DYN) 1903 ult += addr; 1904 1905 pltsz = ult - d[DI_PLTGOT]->d_un.d_ptr + pltentsz; 1906 1907 size += sizeof (Elf64_Shdr); 1908 size += roundup(pltsz, 8); 1909 } 1910 1911 if ((elfdata = calloc(1, size)) == NULL) 1912 goto bad64; 1913 1914 /* LINTED - alignment */ 1915 ep = (Elf64_Ehdr *)elfdata; 1916 (void) memcpy(ep, &ehdr, offsetof(Elf64_Ehdr, e_phoff)); 1917 1918 ep->e_ehsize = sizeof (Elf64_Ehdr); 1919 ep->e_phoff = sizeof (Elf64_Ehdr); 1920 ep->e_phentsize = ehdr.e_phentsize; 1921 ep->e_phnum = phnum; 1922 ep->e_shoff = ep->e_phoff + phnum * ep->e_phentsize; 1923 ep->e_shentsize = sizeof (Elf64_Shdr); 1924 ep->e_shnum = (pltsz == 0) ? 5 : 6; 1925 ep->e_shstrndx = 1; 1926 1927 /* LINTED - alignment */ 1928 sp = (Elf64_Shdr *)(elfdata + ep->e_shoff); 1929 off = ep->e_shoff + ep->e_shentsize * ep->e_shnum; 1930 1931 /* 1932 * Copying the program headers directly from the process's 1933 * address space is a little suspect, but since we only 1934 * use them for their address and size values, this is fine. 1935 */ 1936 if (Pread(P, &elfdata[ep->e_phoff], phnum * ep->e_phentsize, 1937 addr + ehdr.e_phoff) != phnum * ep->e_phentsize) { 1938 free(elfdata); 1939 goto bad64; 1940 } 1941 1942 /* 1943 * The first elf section is always skipped. 1944 */ 1945 sp++; 1946 1947 /* 1948 * Section Header[1] sh_name: .shstrtab 1949 */ 1950 sp->sh_name = 0; 1951 sp->sh_type = SHT_STRTAB; 1952 sp->sh_flags = SHF_STRINGS; 1953 sp->sh_addr = 0; 1954 sp->sh_offset = off; 1955 sp->sh_size = sizeof (shstr); 1956 sp->sh_link = 0; 1957 sp->sh_info = 0; 1958 sp->sh_addralign = 1; 1959 sp->sh_entsize = 0; 1960 1961 (void) memcpy(&elfdata[off], shstr, sizeof (shstr)); 1962 off += roundup(sp->sh_size, 8); 1963 sp++; 1964 1965 /* 1966 * Section Header[2] sh_name: .dynsym 1967 */ 1968 sp->sh_name = 10; 1969 sp->sh_type = SHT_DYNSYM; 1970 sp->sh_flags = SHF_ALLOC; 1971 sp->sh_addr = d[DI_SYMTAB]->d_un.d_ptr; 1972 if (ehdr.e_type == ET_DYN) 1973 sp->sh_addr -= addr; 1974 sp->sh_offset = off; 1975 sp->sh_size = nchain * sizeof (Elf64_Sym); 1976 sp->sh_link = 3; 1977 sp->sh_info = 1; 1978 sp->sh_addralign = 8; 1979 sp->sh_entsize = sizeof (Elf64_Sym); 1980 1981 if (Pread(P, &elfdata[off], sp->sh_size, 1982 d[DI_SYMTAB]->d_un.d_ptr) != sp->sh_size) { 1983 free(elfdata); 1984 goto bad64; 1985 } 1986 1987 off += roundup(sp->sh_size, 8); 1988 sp++; 1989 1990 /* 1991 * Section Header[3] sh_name: .dynstr 1992 */ 1993 sp->sh_name = 18; 1994 sp->sh_type = SHT_STRTAB; 1995 sp->sh_flags = SHF_ALLOC | SHF_STRINGS; 1996 sp->sh_addr = d[DI_STRTAB]->d_un.d_ptr; 1997 if (ehdr.e_type == ET_DYN) 1998 sp->sh_addr -= addr; 1999 sp->sh_offset = off; 2000 sp->sh_size = d[DI_STRSZ]->d_un.d_val; 2001 sp->sh_link = 0; 2002 sp->sh_info = 0; 2003 sp->sh_addralign = 1; 2004 sp->sh_entsize = 0; 2005 2006 if (Pread(P, &elfdata[off], sp->sh_size, 2007 d[DI_STRTAB]->d_un.d_ptr) != sp->sh_size) { 2008 free(elfdata); 2009 goto bad64; 2010 } 2011 off += roundup(sp->sh_size, 8); 2012 sp++; 2013 2014 /* 2015 * Section Header[4] sh_name: .dynamic 2016 */ 2017 sp->sh_name = 26; 2018 sp->sh_type = SHT_DYNAMIC; 2019 sp->sh_flags = SHF_WRITE | SHF_ALLOC; 2020 sp->sh_addr = phdr.p_vaddr; 2021 if (ehdr.e_type == ET_DYN) 2022 sp->sh_addr -= addr; 2023 sp->sh_offset = off; 2024 sp->sh_size = phdr.p_filesz; 2025 sp->sh_link = 3; 2026 sp->sh_info = 0; 2027 sp->sh_addralign = 8; 2028 sp->sh_entsize = sizeof (Elf64_Dyn); 2029 2030 (void) memcpy(&elfdata[off], dp, sp->sh_size); 2031 off += roundup(sp->sh_size, 8); 2032 sp++; 2033 2034 /* 2035 * Section Header[5] sh_name: .plt 2036 */ 2037 if (pltsz != 0) { 2038 sp->sh_name = 35; 2039 sp->sh_type = SHT_PROGBITS; 2040 sp->sh_flags = SHF_WRITE | SHF_ALLOC | SHF_EXECINSTR; 2041 sp->sh_addr = d[DI_PLTGOT]->d_un.d_ptr; 2042 if (ehdr.e_type == ET_DYN) 2043 sp->sh_addr -= addr; 2044 sp->sh_offset = off; 2045 sp->sh_size = pltsz; 2046 sp->sh_link = 0; 2047 sp->sh_info = 0; 2048 sp->sh_addralign = 8; 2049 sp->sh_entsize = pltentsz; 2050 2051 if (Pread(P, &elfdata[off], sp->sh_size, 2052 d[DI_PLTGOT]->d_un.d_ptr) != sp->sh_size) { 2053 free(elfdata); 2054 goto bad64; 2055 } 2056 off += roundup(sp->sh_size, 8); 2057 sp++; 2058 } 2059 2060 free(dp); 2061 goto good; 2062 2063 bad64: 2064 free(dp); 2065 return (NULL); 2066 #endif /* _LP64 */ 2067 } 2068 good: 2069 if ((elf = elf_memory(elfdata, size)) == NULL) { 2070 free(elfdata); 2071 return (NULL); 2072 } 2073 2074 fptr->file_elfmem = elfdata; 2075 2076 return (elf); 2077 } 2078 2079 /* 2080 * We wouldn't need these if qsort(3C) took an argument for the callback... 2081 */ 2082 static mutex_t sort_mtx = DEFAULTMUTEX; 2083 static char *sort_strs; 2084 static GElf_Sym *sort_syms; 2085 2086 int 2087 byaddr_cmp_common(GElf_Sym *a, char *aname, GElf_Sym *b, char *bname) 2088 { 2089 if (a->st_value < b->st_value) 2090 return (-1); 2091 if (a->st_value > b->st_value) 2092 return (1); 2093 2094 /* 2095 * Prefer the function to the non-function. 2096 */ 2097 if (GELF_ST_TYPE(a->st_info) != GELF_ST_TYPE(b->st_info)) { 2098 if (GELF_ST_TYPE(a->st_info) == STT_FUNC) 2099 return (-1); 2100 if (GELF_ST_TYPE(b->st_info) == STT_FUNC) 2101 return (1); 2102 } 2103 2104 /* 2105 * Prefer the weak or strong global symbol to the local symbol. 2106 */ 2107 if (GELF_ST_BIND(a->st_info) != GELF_ST_BIND(b->st_info)) { 2108 if (GELF_ST_BIND(b->st_info) == STB_LOCAL) 2109 return (-1); 2110 if (GELF_ST_BIND(a->st_info) == STB_LOCAL) 2111 return (1); 2112 } 2113 2114 /* 2115 * Prefer the symbol that doesn't begin with a '$' since compilers and 2116 * other symbol generators often use it as a prefix. 2117 */ 2118 if (*bname == '$') 2119 return (-1); 2120 if (*aname == '$') 2121 return (1); 2122 2123 /* 2124 * Prefer the name with fewer leading underscores in the name. 2125 */ 2126 while (*aname == '_' && *bname == '_') { 2127 aname++; 2128 bname++; 2129 } 2130 2131 if (*bname == '_') 2132 return (-1); 2133 if (*aname == '_') 2134 return (1); 2135 2136 /* 2137 * Prefer the symbol with the smaller size. 2138 */ 2139 if (a->st_size < b->st_size) 2140 return (-1); 2141 if (a->st_size > b->st_size) 2142 return (1); 2143 2144 /* 2145 * All other factors being equal, fall back to lexicographic order. 2146 */ 2147 return (strcmp(aname, bname)); 2148 } 2149 2150 static int 2151 byaddr_cmp(const void *aa, const void *bb) 2152 { 2153 GElf_Sym *a = &sort_syms[*(uint_t *)aa]; 2154 GElf_Sym *b = &sort_syms[*(uint_t *)bb]; 2155 char *aname = sort_strs + a->st_name; 2156 char *bname = sort_strs + b->st_name; 2157 2158 return (byaddr_cmp_common(a, aname, b, bname)); 2159 } 2160 2161 static int 2162 byname_cmp(const void *aa, const void *bb) 2163 { 2164 GElf_Sym *a = &sort_syms[*(uint_t *)aa]; 2165 GElf_Sym *b = &sort_syms[*(uint_t *)bb]; 2166 char *aname = sort_strs + a->st_name; 2167 char *bname = sort_strs + b->st_name; 2168 2169 return (strcmp(aname, bname)); 2170 } 2171 2172 void 2173 optimize_symtab(sym_tbl_t *symtab) 2174 { 2175 GElf_Sym *symp, *syms; 2176 uint_t i, *indexa, *indexb; 2177 Elf_Data *data; 2178 size_t symn, strsz, count; 2179 2180 if (symtab == NULL || symtab->sym_data == NULL || 2181 symtab->sym_byaddr != NULL) 2182 return; 2183 2184 data = symtab->sym_data; 2185 symn = symtab->sym_symn; 2186 strsz = symtab->sym_strsz; 2187 2188 symp = syms = malloc(sizeof (GElf_Sym) * symn); 2189 2190 /* 2191 * First record all the symbols into a table and count up the ones 2192 * that we're interested in. We mark symbols as invalid by setting 2193 * the st_name to an illegal value. 2194 */ 2195 for (i = 0, count = 0; i < symn; i++, symp++) { 2196 if (gelf_getsym(data, i, symp) != NULL && 2197 symp->st_name < strsz && 2198 IS_DATA_TYPE(GELF_ST_TYPE(symp->st_info))) 2199 count++; 2200 else 2201 symp->st_name = strsz; 2202 } 2203 2204 /* 2205 * Allocate sufficient space for both tables and populate them 2206 * with the same symbols we just counted. 2207 */ 2208 symtab->sym_count = count; 2209 indexa = symtab->sym_byaddr = calloc(sizeof (uint_t), count); 2210 indexb = symtab->sym_byname = calloc(sizeof (uint_t), count); 2211 2212 for (i = 0, symp = syms; i < symn; i++, symp++) { 2213 if (symp->st_name < strsz) 2214 *indexa++ = *indexb++ = i; 2215 } 2216 2217 /* 2218 * Sort the two tables according to the appropriate criteria. 2219 */ 2220 (void) mutex_lock(&sort_mtx); 2221 sort_strs = symtab->sym_strs; 2222 sort_syms = syms; 2223 2224 qsort(symtab->sym_byaddr, count, sizeof (uint_t), byaddr_cmp); 2225 qsort(symtab->sym_byname, count, sizeof (uint_t), byname_cmp); 2226 2227 sort_strs = NULL; 2228 sort_syms = NULL; 2229 (void) mutex_unlock(&sort_mtx); 2230 2231 free(syms); 2232 } 2233 2234 /* 2235 * Build the symbol table for the given mapped file. 2236 */ 2237 void 2238 Pbuild_file_symtab(struct ps_prochandle *P, file_info_t *fptr) 2239 { 2240 char objectfile[PATH_MAX]; 2241 uint_t i; 2242 2243 GElf_Ehdr ehdr; 2244 GElf_Sym s; 2245 2246 Elf_Data *shdata; 2247 Elf_Scn *scn; 2248 Elf *elf; 2249 size_t nshdrs, shstrndx; 2250 2251 struct { 2252 GElf_Shdr c_shdr; 2253 Elf_Data *c_data; 2254 const char *c_name; 2255 } *cp, *cache = NULL, *dyn = NULL, *plt = NULL, *ctf = NULL; 2256 2257 if (fptr->file_init) 2258 return; /* We've already processed this file */ 2259 2260 /* 2261 * Mark the file_info struct as having the symbol table initialized 2262 * even if we fail below. We tried once; we don't try again. 2263 */ 2264 fptr->file_init = 1; 2265 2266 if (elf_version(EV_CURRENT) == EV_NONE) { 2267 dprintf("libproc ELF version is more recent than libelf\n"); 2268 return; 2269 } 2270 2271 if (P->state == PS_DEAD || P->state == PS_IDLE) { 2272 /* 2273 * If we're a not live, we can't open files from the /proc 2274 * object directory; we have only the mapping and file names 2275 * to guide us. We prefer the file_lname, but need to handle 2276 * the case of it being NULL in order to bootstrap: we first 2277 * come here during rd_new() when the only information we have 2278 * is interpreter name associated with the AT_BASE mapping. 2279 */ 2280 (void) snprintf(objectfile, sizeof (objectfile), "%s", 2281 fptr->file_lname ? fptr->file_lname : fptr->file_pname); 2282 } else { 2283 (void) snprintf(objectfile, sizeof (objectfile), 2284 "%s/%d/object/%s", 2285 procfs_path, (int)P->pid, fptr->file_pname); 2286 } 2287 2288 /* 2289 * Open the object file, create the elf file, and then get the elf 2290 * header and .shstrtab data buffer so we can process sections by 2291 * name. If anything goes wrong try to fake up an elf file from 2292 * the in-core elf image. 2293 */ 2294 if ((fptr->file_fd = open(objectfile, O_RDONLY)) < 0) { 2295 dprintf("Pbuild_file_symtab: failed to open %s: %s\n", 2296 objectfile, strerror(errno)); 2297 2298 if ((elf = fake_elf(P, fptr)) == NULL || 2299 elf_kind(elf) != ELF_K_ELF || 2300 gelf_getehdr(elf, &ehdr) == NULL || 2301 elf_getshnum(elf, &nshdrs) == 0 || 2302 elf_getshstrndx(elf, &shstrndx) == 0 || 2303 (scn = elf_getscn(elf, shstrndx)) == NULL || 2304 (shdata = elf_getdata(scn, NULL)) == NULL) { 2305 dprintf("failed to fake up ELF file\n"); 2306 return; 2307 } 2308 2309 } else if ((elf = elf_begin(fptr->file_fd, ELF_C_READ, NULL)) == NULL || 2310 elf_kind(elf) != ELF_K_ELF || 2311 gelf_getehdr(elf, &ehdr) == NULL || 2312 elf_getshnum(elf, &nshdrs) == 0 || 2313 elf_getshstrndx(elf, &shstrndx) == 0 || 2314 (scn = elf_getscn(elf, shstrndx)) == NULL || 2315 (shdata = elf_getdata(scn, NULL)) == NULL) { 2316 int err = elf_errno(); 2317 2318 dprintf("failed to process ELF file %s: %s\n", 2319 objectfile, (err == 0) ? "<null>" : elf_errmsg(err)); 2320 2321 if ((elf = fake_elf(P, fptr)) == NULL || 2322 elf_kind(elf) != ELF_K_ELF || 2323 gelf_getehdr(elf, &ehdr) == NULL || 2324 elf_getshnum(elf, &nshdrs) == 0 || 2325 elf_getshstrndx(elf, &shstrndx) == 0 || 2326 (scn = elf_getscn(elf, shstrndx)) == NULL || 2327 (shdata = elf_getdata(scn, NULL)) == NULL) { 2328 dprintf("failed to fake up ELF file\n"); 2329 goto bad; 2330 } 2331 2332 } else if (file_differs(P, elf, fptr)) { 2333 Elf *newelf; 2334 2335 /* 2336 * Before we get too excited about this elf file, we'll check 2337 * its checksum value against the value we have in memory. If 2338 * they don't agree, we try to fake up a new elf file and 2339 * proceed with that instead. 2340 */ 2341 2342 dprintf("ELF file %s (%lx) doesn't match in-core image\n", 2343 fptr->file_pname, 2344 (ulong_t)fptr->file_map->map_pmap.pr_vaddr); 2345 2346 if ((newelf = fake_elf(P, fptr)) == NULL || 2347 elf_kind(newelf) != ELF_K_ELF || 2348 gelf_getehdr(newelf, &ehdr) == NULL || 2349 elf_getshnum(newelf, &nshdrs) == 0 || 2350 elf_getshstrndx(newelf, &shstrndx) == 0 || 2351 (scn = elf_getscn(newelf, shstrndx)) == NULL || 2352 (shdata = elf_getdata(scn, NULL)) == NULL) { 2353 dprintf("failed to fake up ELF file\n"); 2354 } else { 2355 (void) elf_end(elf); 2356 elf = newelf; 2357 2358 dprintf("switched to faked up ELF file\n"); 2359 } 2360 } 2361 2362 if ((cache = malloc(nshdrs * sizeof (*cache))) == NULL) { 2363 dprintf("failed to malloc section cache for %s\n", objectfile); 2364 goto bad; 2365 } 2366 2367 dprintf("processing ELF file %s\n", objectfile); 2368 fptr->file_class = ehdr.e_ident[EI_CLASS]; 2369 fptr->file_etype = ehdr.e_type; 2370 fptr->file_elf = elf; 2371 fptr->file_shstrs = shdata->d_buf; 2372 fptr->file_shstrsz = shdata->d_size; 2373 2374 /* 2375 * Iterate through each section, caching its section header, data 2376 * pointer, and name. We use this for handling sh_link values below. 2377 */ 2378 for (cp = cache + 1, scn = NULL; scn = elf_nextscn(elf, scn); cp++) { 2379 if (gelf_getshdr(scn, &cp->c_shdr) == NULL) { 2380 dprintf("Pbuild_file_symtab: Failed to get section " 2381 "header\n"); 2382 goto bad; /* Failed to get section header */ 2383 } 2384 2385 if ((cp->c_data = elf_getdata(scn, NULL)) == NULL) { 2386 dprintf("Pbuild_file_symtab: Failed to get section " 2387 "data\n"); 2388 goto bad; /* Failed to get section data */ 2389 } 2390 2391 if (cp->c_shdr.sh_name >= shdata->d_size) { 2392 dprintf("Pbuild_file_symtab: corrupt section name"); 2393 goto bad; /* Corrupt section name */ 2394 } 2395 2396 cp->c_name = (const char *)shdata->d_buf + cp->c_shdr.sh_name; 2397 } 2398 2399 /* 2400 * Now iterate through the section cache in order to locate info 2401 * for the .symtab, .dynsym, .dynamic, .plt, and .SUNW_ctf sections: 2402 */ 2403 for (i = 1, cp = cache + 1; i < nshdrs; i++, cp++) { 2404 GElf_Shdr *shp = &cp->c_shdr; 2405 2406 if (shp->sh_type == SHT_SYMTAB || shp->sh_type == SHT_DYNSYM) { 2407 sym_tbl_t *symp = shp->sh_type == SHT_SYMTAB ? 2408 &fptr->file_symtab : &fptr->file_dynsym; 2409 /* 2410 * It's possible that the we already got the symbol 2411 * table from the core file itself. Either the file 2412 * differs in which case our faked up elf file will 2413 * only contain the dynsym (not the symtab) or the 2414 * file matches in which case we'll just be replacing 2415 * the symbol table we pulled out of the core file 2416 * with an equivalent one. In either case, this 2417 * check isn't essential, but it's a good idea. 2418 */ 2419 if (symp->sym_data == NULL) { 2420 dprintf("Symbol table found for %s\n", 2421 objectfile); 2422 symp->sym_data = cp->c_data; 2423 symp->sym_symn = shp->sh_size / shp->sh_entsize; 2424 symp->sym_strs = 2425 cache[shp->sh_link].c_data->d_buf; 2426 symp->sym_strsz = 2427 cache[shp->sh_link].c_data->d_size; 2428 symp->sym_hdr = cp->c_shdr; 2429 symp->sym_strhdr = cache[shp->sh_link].c_shdr; 2430 } else { 2431 dprintf("Symbol table already there for %s\n", 2432 objectfile); 2433 } 2434 2435 } else if (shp->sh_type == SHT_DYNAMIC) { 2436 dyn = cp; 2437 } else if (strcmp(cp->c_name, ".plt") == 0) { 2438 plt = cp; 2439 } else if (strcmp(cp->c_name, ".SUNW_ctf") == 0) { 2440 /* 2441 * Skip over bogus CTF sections so they don't come back 2442 * to haunt us later. 2443 */ 2444 if (shp->sh_link == 0 || 2445 shp->sh_link >= nshdrs || 2446 (cache[shp->sh_link].c_shdr.sh_type != SHT_DYNSYM && 2447 cache[shp->sh_link].c_shdr.sh_type != SHT_SYMTAB)) { 2448 dprintf("Bad sh_link %d for " 2449 "CTF\n", shp->sh_link); 2450 continue; 2451 } 2452 ctf = cp; 2453 } 2454 } 2455 2456 /* 2457 * At this point, we've found all the symbol tables we're ever going 2458 * to find: the ones in the loop above and possibly the symtab that 2459 * was included in the core file. Before we perform any lookups, we 2460 * create sorted versions to optimize for lookups. 2461 */ 2462 optimize_symtab(&fptr->file_symtab); 2463 optimize_symtab(&fptr->file_dynsym); 2464 2465 /* 2466 * Fill in the base address of the text mapping for shared libraries. 2467 * This allows us to translate symbols before librtld_db is ready. 2468 */ 2469 if (fptr->file_etype == ET_DYN) { 2470 fptr->file_dyn_base = fptr->file_map->map_pmap.pr_vaddr - 2471 fptr->file_map->map_pmap.pr_offset; 2472 dprintf("setting file_dyn_base for %s to %lx\n", 2473 objectfile, (long)fptr->file_dyn_base); 2474 } 2475 2476 /* 2477 * Record the CTF section information in the file info structure. 2478 */ 2479 if (ctf != NULL) { 2480 fptr->file_ctf_off = ctf->c_shdr.sh_offset; 2481 fptr->file_ctf_size = ctf->c_shdr.sh_size; 2482 if (ctf->c_shdr.sh_link != 0 && 2483 cache[ctf->c_shdr.sh_link].c_shdr.sh_type == SHT_DYNSYM) 2484 fptr->file_ctf_dyn = 1; 2485 } 2486 2487 if (fptr->file_lo == NULL) 2488 goto done; /* Nothing else to do if no load object info */ 2489 2490 /* 2491 * If the object is a shared library and we have a different rl_base 2492 * value, reset file_dyn_base according to librtld_db's information. 2493 */ 2494 if (fptr->file_etype == ET_DYN && 2495 fptr->file_lo->rl_base != fptr->file_dyn_base) { 2496 dprintf("resetting file_dyn_base for %s to %lx\n", 2497 objectfile, (long)fptr->file_lo->rl_base); 2498 fptr->file_dyn_base = fptr->file_lo->rl_base; 2499 } 2500 2501 /* 2502 * Fill in the PLT information for this file if a PLT symbol is found. 2503 */ 2504 if (sym_by_name(&fptr->file_dynsym, "_PROCEDURE_LINKAGE_TABLE_", &s, 2505 NULL) != NULL) { 2506 fptr->file_plt_base = s.st_value + fptr->file_dyn_base; 2507 fptr->file_plt_size = (plt != NULL) ? plt->c_shdr.sh_size : 0; 2508 2509 /* 2510 * Bring the load object up to date; it is the only way the 2511 * user has to access the PLT data. The PLT information in the 2512 * rd_loadobj_t is not set in the call to map_iter() (the 2513 * callback for rd_loadobj_iter) where we set file_lo. 2514 */ 2515 fptr->file_lo->rl_plt_base = fptr->file_plt_base; 2516 fptr->file_lo->rl_plt_size = fptr->file_plt_size; 2517 2518 dprintf("PLT found at %p, size = %lu\n", 2519 (void *)fptr->file_plt_base, (ulong_t)fptr->file_plt_size); 2520 } 2521 2522 /* 2523 * Fill in the PLT information. 2524 */ 2525 if (dyn != NULL) { 2526 uintptr_t dynaddr = dyn->c_shdr.sh_addr + fptr->file_dyn_base; 2527 size_t ndyn = dyn->c_shdr.sh_size / dyn->c_shdr.sh_entsize; 2528 GElf_Dyn d; 2529 2530 for (i = 0; i < ndyn; i++) { 2531 if (gelf_getdyn(dyn->c_data, i, &d) != NULL && 2532 d.d_tag == DT_JMPREL) { 2533 dprintf("DT_JMPREL is %p\n", 2534 (void *)(uintptr_t)d.d_un.d_ptr); 2535 fptr->file_jmp_rel = 2536 d.d_un.d_ptr + fptr->file_dyn_base; 2537 break; 2538 } 2539 } 2540 2541 dprintf("_DYNAMIC found at %p, %lu entries, DT_JMPREL = %p\n", 2542 (void *)dynaddr, (ulong_t)ndyn, (void *)fptr->file_jmp_rel); 2543 } 2544 2545 done: 2546 free(cache); 2547 return; 2548 2549 bad: 2550 if (cache != NULL) 2551 free(cache); 2552 2553 (void) elf_end(elf); 2554 fptr->file_elf = NULL; 2555 if (fptr->file_elfmem != NULL) { 2556 free(fptr->file_elfmem); 2557 fptr->file_elfmem = NULL; 2558 } 2559 (void) close(fptr->file_fd); 2560 fptr->file_fd = -1; 2561 } 2562 2563 /* 2564 * Given a process virtual address, return the map_info_t containing it. 2565 * If none found, return NULL. 2566 */ 2567 map_info_t * 2568 Paddr2mptr(struct ps_prochandle *P, uintptr_t addr) 2569 { 2570 int lo = 0; 2571 int hi = P->map_count - 1; 2572 int mid; 2573 map_info_t *mp; 2574 2575 while (lo <= hi) { 2576 2577 mid = (lo + hi) / 2; 2578 mp = &P->mappings[mid]; 2579 2580 /* check that addr is in [vaddr, vaddr + size) */ 2581 if ((addr - mp->map_pmap.pr_vaddr) < mp->map_pmap.pr_size) 2582 return (mp); 2583 2584 if (addr < mp->map_pmap.pr_vaddr) 2585 hi = mid - 1; 2586 else 2587 lo = mid + 1; 2588 } 2589 2590 return (NULL); 2591 } 2592 2593 /* 2594 * Return the map_info_t for the executable file. 2595 * If not found, return NULL. 2596 */ 2597 static map_info_t * 2598 exec_map(struct ps_prochandle *P) 2599 { 2600 uint_t i; 2601 map_info_t *mptr; 2602 map_info_t *mold = NULL; 2603 file_info_t *fptr; 2604 uintptr_t base; 2605 2606 for (i = 0, mptr = P->mappings; i < P->map_count; i++, mptr++) { 2607 if (mptr->map_pmap.pr_mapname[0] == '\0') 2608 continue; 2609 if (strcmp(mptr->map_pmap.pr_mapname, "a.out") == 0) { 2610 if ((fptr = mptr->map_file) != NULL && 2611 fptr->file_lo != NULL) { 2612 base = fptr->file_lo->rl_base; 2613 if (base >= mptr->map_pmap.pr_vaddr && 2614 base < mptr->map_pmap.pr_vaddr + 2615 mptr->map_pmap.pr_size) /* text space */ 2616 return (mptr); 2617 mold = mptr; /* must be the data */ 2618 continue; 2619 } 2620 /* This is a poor way to test for text space */ 2621 if (!(mptr->map_pmap.pr_mflags & MA_EXEC) || 2622 (mptr->map_pmap.pr_mflags & MA_WRITE)) { 2623 mold = mptr; 2624 continue; 2625 } 2626 return (mptr); 2627 } 2628 } 2629 2630 return (mold); 2631 } 2632 2633 /* 2634 * Given a shared object name, return the map_info_t for it. If no matching 2635 * object is found, return NULL. Normally, the link maps contain the full 2636 * object pathname, e.g. /usr/lib/libc.so.1. We allow the object name to 2637 * take one of the following forms: 2638 * 2639 * 1. An exact match (i.e. a full pathname): "/usr/lib/libc.so.1" 2640 * 2. An exact basename match: "libc.so.1" 2641 * 3. An initial basename match up to a '.' suffix: "libc.so" or "libc" 2642 * 4. The literal string "a.out" is an alias for the executable mapping 2643 * 2644 * The third case is a convenience for callers and may not be necessary. 2645 * 2646 * As the exact same object name may be loaded on different link maps (see 2647 * dlmopen(3DL)), we also allow the caller to resolve the object name by 2648 * specifying a particular link map id. If lmid is PR_LMID_EVERY, the 2649 * first matching name will be returned, regardless of the link map id. 2650 */ 2651 static map_info_t * 2652 object_to_map(struct ps_prochandle *P, Lmid_t lmid, const char *objname) 2653 { 2654 map_info_t *mp; 2655 file_info_t *fp; 2656 size_t objlen; 2657 uint_t i; 2658 2659 /* 2660 * If we have no rtld_db, then always treat a request as one for all 2661 * link maps. 2662 */ 2663 if (P->rap == NULL) 2664 lmid = PR_LMID_EVERY; 2665 2666 /* 2667 * First pass: look for exact matches of the entire pathname or 2668 * basename (cases 1 and 2 above): 2669 */ 2670 for (i = 0, mp = P->mappings; i < P->map_count; i++, mp++) { 2671 2672 if (mp->map_pmap.pr_mapname[0] == '\0' || 2673 (fp = mp->map_file) == NULL || fp->file_lname == NULL) 2674 continue; 2675 2676 if (lmid != PR_LMID_EVERY && 2677 (fp->file_lo == NULL || lmid != fp->file_lo->rl_lmident)) 2678 continue; 2679 2680 /* 2681 * If we match, return the primary text mapping; otherwise 2682 * just return the mapping we matched. 2683 */ 2684 if (strcmp(fp->file_lname, objname) == 0 || 2685 strcmp(fp->file_lbase, objname) == 0) 2686 return (fp->file_map ? fp->file_map : mp); 2687 } 2688 2689 objlen = strlen(objname); 2690 2691 /* 2692 * Second pass: look for partial matches (case 3 above): 2693 */ 2694 for (i = 0, mp = P->mappings; i < P->map_count; i++, mp++) { 2695 2696 if (mp->map_pmap.pr_mapname[0] == '\0' || 2697 (fp = mp->map_file) == NULL || fp->file_lname == NULL) 2698 continue; 2699 2700 if (lmid != PR_LMID_EVERY && 2701 (fp->file_lo == NULL || lmid != fp->file_lo->rl_lmident)) 2702 continue; 2703 2704 /* 2705 * If we match, return the primary text mapping; otherwise 2706 * just return the mapping we matched. 2707 */ 2708 if (strncmp(fp->file_lbase, objname, objlen) == 0 && 2709 fp->file_lbase[objlen] == '.') 2710 return (fp->file_map ? fp->file_map : mp); 2711 } 2712 2713 /* 2714 * One last check: we allow "a.out" to always alias the executable, 2715 * assuming this name was not in use for something else. 2716 */ 2717 if ((lmid == PR_LMID_EVERY || lmid == LM_ID_BASE) && 2718 (strcmp(objname, "a.out") == 0)) 2719 return (P->map_exec); 2720 2721 return (NULL); 2722 } 2723 2724 static map_info_t * 2725 object_name_to_map(struct ps_prochandle *P, Lmid_t lmid, const char *name) 2726 { 2727 map_info_t *mptr; 2728 2729 if (!P->info_valid) 2730 Pupdate_maps(P); 2731 2732 if (P->map_exec == NULL && ((mptr = Paddr2mptr(P, 2733 Pgetauxval(P, AT_ENTRY))) != NULL || (mptr = exec_map(P)) != NULL)) 2734 P->map_exec = mptr; 2735 2736 if (P->map_ldso == NULL && (mptr = Paddr2mptr(P, 2737 Pgetauxval(P, AT_BASE))) != NULL) 2738 P->map_ldso = mptr; 2739 2740 if (name == PR_OBJ_EXEC) 2741 mptr = P->map_exec; 2742 else if (name == PR_OBJ_LDSO) 2743 mptr = P->map_ldso; 2744 else if (Prd_agent(P) != NULL || P->state == PS_IDLE) 2745 mptr = object_to_map(P, lmid, name); 2746 else 2747 mptr = NULL; 2748 2749 return (mptr); 2750 } 2751 2752 /* 2753 * When two symbols are found by address, decide which one is to be preferred. 2754 */ 2755 static GElf_Sym * 2756 sym_prefer(GElf_Sym *sym1, char *name1, GElf_Sym *sym2, char *name2) 2757 { 2758 /* 2759 * Prefer the non-NULL symbol. 2760 */ 2761 if (sym1 == NULL) 2762 return (sym2); 2763 if (sym2 == NULL) 2764 return (sym1); 2765 2766 /* 2767 * Defer to the sort ordering... 2768 */ 2769 return (byaddr_cmp_common(sym1, name1, sym2, name2) <= 0 ? sym1 : sym2); 2770 } 2771 2772 /* 2773 * Look up a symbol by address in the specified symbol table. 2774 * Adjustment to 'addr' must already have been made for the 2775 * offset of the symbol if this is a dynamic library symbol table. 2776 */ 2777 static GElf_Sym * 2778 sym_by_addr(sym_tbl_t *symtab, GElf_Addr addr, GElf_Sym *symp, uint_t *idp) 2779 { 2780 Elf_Data *data = symtab->sym_data; 2781 GElf_Sym sym, osym; 2782 uint_t i, oid, *byaddr = symtab->sym_byaddr; 2783 int min, max, mid, omid, found = 0; 2784 2785 if (data == NULL) 2786 return (NULL); 2787 2788 min = 0; 2789 max = symtab->sym_count - 1; 2790 osym.st_value = 0; 2791 2792 /* 2793 * We can't return when we've found a match, we have to continue 2794 * searching for the closest matching symbol. 2795 */ 2796 while (min <= max) { 2797 mid = (max + min) / 2; 2798 2799 i = byaddr[mid]; 2800 (void) gelf_getsym(data, i, &sym); 2801 2802 if (addr >= sym.st_value && 2803 addr < sym.st_value + sym.st_size && 2804 (!found || sym.st_value > osym.st_value)) { 2805 osym = sym; 2806 omid = mid; 2807 oid = i; 2808 found = 1; 2809 } 2810 2811 if (addr < sym.st_value) 2812 max = mid - 1; 2813 else 2814 min = mid + 1; 2815 } 2816 2817 if (!found) 2818 return (NULL); 2819 2820 /* 2821 * There may be many symbols with identical values so we walk 2822 * backward in the byaddr table to find the best match. 2823 */ 2824 do { 2825 sym = osym; 2826 i = oid; 2827 2828 if (omid == 0) 2829 break; 2830 2831 oid = byaddr[--omid]; 2832 (void) gelf_getsym(data, oid, &osym); 2833 } while (addr >= osym.st_value && 2834 addr < sym.st_value + osym.st_size && 2835 osym.st_value == sym.st_value); 2836 2837 *symp = sym; 2838 if (idp != NULL) 2839 *idp = i; 2840 return (symp); 2841 } 2842 2843 /* 2844 * Look up a symbol by name in the specified symbol table. 2845 */ 2846 static GElf_Sym * 2847 sym_by_name(sym_tbl_t *symtab, const char *name, GElf_Sym *symp, uint_t *idp) 2848 { 2849 Elf_Data *data = symtab->sym_data; 2850 char *strs = symtab->sym_strs; 2851 uint_t i, *byname = symtab->sym_byname; 2852 int min, mid, max, cmp; 2853 2854 if (data == NULL || strs == NULL) 2855 return (NULL); 2856 2857 min = 0; 2858 max = symtab->sym_count - 1; 2859 2860 while (min <= max) { 2861 mid = (max + min) / 2; 2862 2863 i = byname[mid]; 2864 (void) gelf_getsym(data, i, symp); 2865 2866 if ((cmp = strcmp(name, strs + symp->st_name)) == 0) { 2867 if (idp != NULL) 2868 *idp = i; 2869 return (symp); 2870 } 2871 2872 if (cmp < 0) 2873 max = mid - 1; 2874 else 2875 min = mid + 1; 2876 } 2877 2878 return (NULL); 2879 } 2880 2881 /* 2882 * Search the process symbol tables looking for a symbol whose 2883 * value to value+size contain the address specified by addr. 2884 * Return values are: 2885 * sym_name_buffer containing the symbol name 2886 * GElf_Sym symbol table entry 2887 * prsyminfo_t ancillary symbol information 2888 * Returns 0 on success, -1 on failure. 2889 */ 2890 int 2891 Pxlookup_by_addr( 2892 struct ps_prochandle *P, 2893 uintptr_t addr, /* process address being sought */ 2894 char *sym_name_buffer, /* buffer for the symbol name */ 2895 size_t bufsize, /* size of sym_name_buffer */ 2896 GElf_Sym *symbolp, /* returned symbol table entry */ 2897 prsyminfo_t *sip) /* returned symbol info */ 2898 { 2899 GElf_Sym *symp; 2900 char *name; 2901 GElf_Sym sym1, *sym1p = NULL; 2902 GElf_Sym sym2, *sym2p = NULL; 2903 char *name1 = NULL; 2904 char *name2 = NULL; 2905 uint_t i1; 2906 uint_t i2; 2907 map_info_t *mptr; 2908 file_info_t *fptr; 2909 2910 (void) Prd_agent(P); 2911 2912 if ((mptr = Paddr2mptr(P, addr)) == NULL || /* no such address */ 2913 (fptr = build_map_symtab(P, mptr)) == NULL || /* no mapped file */ 2914 fptr->file_elf == NULL) /* not an ELF file */ 2915 return (-1); 2916 2917 /* 2918 * Adjust the address by the load object base address in 2919 * case the address turns out to be in a shared library. 2920 */ 2921 addr -= fptr->file_dyn_base; 2922 2923 /* 2924 * Search both symbol tables, symtab first, then dynsym. 2925 */ 2926 if ((sym1p = sym_by_addr(&fptr->file_symtab, addr, &sym1, &i1)) != NULL) 2927 name1 = fptr->file_symtab.sym_strs + sym1.st_name; 2928 if ((sym2p = sym_by_addr(&fptr->file_dynsym, addr, &sym2, &i2)) != NULL) 2929 name2 = fptr->file_dynsym.sym_strs + sym2.st_name; 2930 2931 if ((symp = sym_prefer(sym1p, name1, sym2p, name2)) == NULL) 2932 return (-1); 2933 2934 name = (symp == sym1p) ? name1 : name2; 2935 if (bufsize > 0) { 2936 (void) strncpy(sym_name_buffer, name, bufsize); 2937 sym_name_buffer[bufsize - 1] = '\0'; 2938 } 2939 2940 *symbolp = *symp; 2941 if (sip != NULL) { 2942 sip->prs_name = bufsize == 0 ? NULL : sym_name_buffer; 2943 sip->prs_object = fptr->file_lbase; 2944 sip->prs_id = (symp == sym1p) ? i1 : i2; 2945 sip->prs_table = (symp == sym1p) ? PR_SYMTAB : PR_DYNSYM; 2946 sip->prs_lmid = (fptr->file_lo == NULL) ? LM_ID_BASE : 2947 fptr->file_lo->rl_lmident; 2948 } 2949 2950 if (GELF_ST_TYPE(symbolp->st_info) != STT_TLS) 2951 symbolp->st_value += fptr->file_dyn_base; 2952 2953 return (0); 2954 } 2955 2956 int 2957 Plookup_by_addr(struct ps_prochandle *P, uintptr_t addr, char *buf, size_t size, 2958 GElf_Sym *symp) 2959 { 2960 return (Pxlookup_by_addr(P, addr, buf, size, symp, NULL)); 2961 } 2962 2963 /* 2964 * Search the process symbol tables looking for a symbol whose name matches the 2965 * specified name and whose object and link map optionally match the specified 2966 * parameters. On success, the function returns 0 and fills in the GElf_Sym 2967 * symbol table entry. On failure, -1 is returned. 2968 */ 2969 int 2970 Pxlookup_by_name( 2971 struct ps_prochandle *P, 2972 Lmid_t lmid, /* link map to match, or -1 for any */ 2973 const char *oname, /* load object name */ 2974 const char *sname, /* symbol name */ 2975 GElf_Sym *symp, /* returned symbol table entry */ 2976 prsyminfo_t *sip) /* returned symbol info */ 2977 { 2978 map_info_t *mptr; 2979 file_info_t *fptr; 2980 int cnt; 2981 2982 GElf_Sym sym; 2983 prsyminfo_t si; 2984 int rv = -1; 2985 uint_t id; 2986 2987 if (oname == PR_OBJ_EVERY) { 2988 /* create all the file_info_t's for all the mappings */ 2989 (void) Prd_agent(P); 2990 cnt = P->num_files; 2991 fptr = list_next(&P->file_head); 2992 } else { 2993 cnt = 1; 2994 if ((mptr = object_name_to_map(P, lmid, oname)) == NULL || 2995 (fptr = build_map_symtab(P, mptr)) == NULL) 2996 return (-1); 2997 } 2998 2999 /* 3000 * Iterate through the loaded object files and look for the symbol 3001 * name in the .symtab and .dynsym of each. If we encounter a match 3002 * with SHN_UNDEF, keep looking in hopes of finding a better match. 3003 * This means that a name such as "puts" will match the puts function 3004 * in libc instead of matching the puts PLT entry in the a.out file. 3005 */ 3006 for (; cnt > 0; cnt--, fptr = list_next(fptr)) { 3007 Pbuild_file_symtab(P, fptr); 3008 3009 if (fptr->file_elf == NULL) 3010 continue; 3011 3012 if (lmid != PR_LMID_EVERY && fptr->file_lo != NULL && 3013 lmid != fptr->file_lo->rl_lmident) 3014 continue; 3015 3016 if (fptr->file_symtab.sym_data != NULL && 3017 sym_by_name(&fptr->file_symtab, sname, symp, &id)) { 3018 if (sip != NULL) { 3019 sip->prs_id = id; 3020 sip->prs_table = PR_SYMTAB; 3021 sip->prs_object = oname; 3022 sip->prs_name = sname; 3023 sip->prs_lmid = fptr->file_lo == NULL ? 3024 LM_ID_BASE : fptr->file_lo->rl_lmident; 3025 } 3026 } else if (fptr->file_dynsym.sym_data != NULL && 3027 sym_by_name(&fptr->file_dynsym, sname, symp, &id)) { 3028 if (sip != NULL) { 3029 sip->prs_id = id; 3030 sip->prs_table = PR_DYNSYM; 3031 sip->prs_object = oname; 3032 sip->prs_name = sname; 3033 sip->prs_lmid = fptr->file_lo == NULL ? 3034 LM_ID_BASE : fptr->file_lo->rl_lmident; 3035 } 3036 } else { 3037 continue; 3038 } 3039 3040 if (GELF_ST_TYPE(symp->st_info) != STT_TLS) 3041 symp->st_value += fptr->file_dyn_base; 3042 3043 if (symp->st_shndx != SHN_UNDEF) 3044 return (0); 3045 3046 if (rv != 0) { 3047 if (sip != NULL) 3048 si = *sip; 3049 sym = *symp; 3050 rv = 0; 3051 } 3052 } 3053 3054 if (rv == 0) { 3055 if (sip != NULL) 3056 *sip = si; 3057 *symp = sym; 3058 } 3059 3060 return (rv); 3061 } 3062 3063 /* 3064 * Search the process symbol tables looking for a symbol whose name matches the 3065 * specified name, but without any restriction on the link map id. 3066 */ 3067 int 3068 Plookup_by_name(struct ps_prochandle *P, const char *object, 3069 const char *symbol, GElf_Sym *symp) 3070 { 3071 return (Pxlookup_by_name(P, PR_LMID_EVERY, object, symbol, symp, NULL)); 3072 } 3073 3074 /* 3075 * Iterate over the process's address space mappings. 3076 */ 3077 int 3078 Pmapping_iter(struct ps_prochandle *P, proc_map_f *func, void *cd) 3079 { 3080 map_info_t *mptr; 3081 file_info_t *fptr; 3082 char *object_name; 3083 int rc = 0; 3084 int i; 3085 3086 /* create all the file_info_t's for all the mappings */ 3087 (void) Prd_agent(P); 3088 3089 for (i = 0, mptr = P->mappings; i < P->map_count; i++, mptr++) { 3090 if ((fptr = mptr->map_file) == NULL) 3091 object_name = NULL; 3092 else 3093 object_name = fptr->file_lname; 3094 if ((rc = func(cd, &mptr->map_pmap, object_name)) != 0) 3095 return (rc); 3096 } 3097 return (0); 3098 } 3099 3100 /* 3101 * Iterate over the process's mapped objects. 3102 */ 3103 int 3104 Pobject_iter(struct ps_prochandle *P, proc_map_f *func, void *cd) 3105 { 3106 map_info_t *mptr; 3107 file_info_t *fptr; 3108 uint_t cnt; 3109 int rc = 0; 3110 3111 (void) Prd_agent(P); /* create file_info_t's for all the mappings */ 3112 Pupdate_maps(P); 3113 3114 for (cnt = P->num_files, fptr = list_next(&P->file_head); 3115 cnt; cnt--, fptr = list_next(fptr)) { 3116 3117 const char *lname = fptr->file_lname ? fptr->file_lname : ""; 3118 3119 if ((mptr = fptr->file_map) == NULL) 3120 continue; 3121 3122 if ((rc = func(cd, &mptr->map_pmap, lname)) != 0) 3123 return (rc); 3124 } 3125 return (0); 3126 } 3127 3128 /* 3129 * Given a virtual address, return the name of the underlying 3130 * mapped object (file), as provided by the dynamic linker. 3131 * Return NULL on failure (no underlying shared library). 3132 */ 3133 char * 3134 Pobjname(struct ps_prochandle *P, uintptr_t addr, 3135 char *buffer, size_t bufsize) 3136 { 3137 map_info_t *mptr; 3138 file_info_t *fptr; 3139 3140 /* create all the file_info_t's for all the mappings */ 3141 (void) Prd_agent(P); 3142 3143 if ((mptr = Paddr2mptr(P, addr)) != NULL && 3144 (fptr = mptr->map_file) != NULL && 3145 fptr->file_lname != NULL) { 3146 (void) strncpy(buffer, fptr->file_lname, bufsize); 3147 if (strlen(fptr->file_lname) >= bufsize) 3148 buffer[bufsize-1] = '\0'; 3149 return (buffer); 3150 } 3151 return (NULL); 3152 } 3153 3154 /* 3155 * Given a virtual address, return the link map id of the underlying mapped 3156 * object (file), as provided by the dynamic linker. Return -1 on failure. 3157 */ 3158 int 3159 Plmid(struct ps_prochandle *P, uintptr_t addr, Lmid_t *lmidp) 3160 { 3161 map_info_t *mptr; 3162 file_info_t *fptr; 3163 3164 /* create all the file_info_t's for all the mappings */ 3165 (void) Prd_agent(P); 3166 3167 if ((mptr = Paddr2mptr(P, addr)) != NULL && 3168 (fptr = mptr->map_file) != NULL && fptr->file_lo != NULL) { 3169 *lmidp = fptr->file_lo->rl_lmident; 3170 return (0); 3171 } 3172 3173 return (-1); 3174 } 3175 3176 /* 3177 * Given an object name and optional lmid, iterate over the object's symbols. 3178 * If which == PR_SYMTAB, search the normal symbol table. 3179 * If which == PR_DYNSYM, search the dynamic symbol table. 3180 */ 3181 static int 3182 Psymbol_iter_com(struct ps_prochandle *P, Lmid_t lmid, const char *object_name, 3183 int which, int mask, pr_order_t order, proc_xsym_f *func, void *cd) 3184 { 3185 GElf_Sym sym; 3186 GElf_Shdr shdr; 3187 map_info_t *mptr; 3188 file_info_t *fptr; 3189 sym_tbl_t *symtab; 3190 Elf_Data *data; 3191 size_t symn; 3192 const char *strs; 3193 size_t strsz; 3194 prsyminfo_t si; 3195 int rv; 3196 uint_t *map, i, count, ndx; 3197 3198 if ((mptr = object_name_to_map(P, lmid, object_name)) == NULL) 3199 return (-1); 3200 3201 if ((fptr = build_map_symtab(P, mptr)) == NULL || /* no mapped file */ 3202 fptr->file_elf == NULL) /* not an ELF file */ 3203 return (-1); 3204 3205 /* 3206 * Search the specified symbol table. 3207 */ 3208 switch (which) { 3209 case PR_SYMTAB: 3210 symtab = &fptr->file_symtab; 3211 si.prs_table = PR_SYMTAB; 3212 break; 3213 case PR_DYNSYM: 3214 symtab = &fptr->file_dynsym; 3215 si.prs_table = PR_DYNSYM; 3216 break; 3217 default: 3218 return (-1); 3219 } 3220 3221 si.prs_object = object_name; 3222 si.prs_lmid = fptr->file_lo == NULL ? 3223 LM_ID_BASE : fptr->file_lo->rl_lmident; 3224 3225 data = symtab->sym_data; 3226 symn = symtab->sym_symn; 3227 strs = symtab->sym_strs; 3228 strsz = symtab->sym_strsz; 3229 3230 if (data == NULL || strs == NULL) 3231 return (-1); 3232 3233 switch (order) { 3234 case PRO_NATURAL: 3235 map = NULL; 3236 count = symn; 3237 break; 3238 case PRO_BYNAME: 3239 map = symtab->sym_byname; 3240 count = symtab->sym_count; 3241 break; 3242 case PRO_BYADDR: 3243 map = symtab->sym_byaddr; 3244 count = symtab->sym_count; 3245 break; 3246 default: 3247 return (-1); 3248 } 3249 3250 rv = 0; 3251 3252 for (i = 0; i < count; i++) { 3253 ndx = map == NULL ? i : map[i]; 3254 if (gelf_getsym(data, ndx, &sym) != NULL) { 3255 uint_t s_bind, s_type, type; 3256 3257 if (sym.st_name >= strsz) /* invalid st_name */ 3258 continue; 3259 3260 s_bind = GELF_ST_BIND(sym.st_info); 3261 s_type = GELF_ST_TYPE(sym.st_info); 3262 3263 /* 3264 * In case you haven't already guessed, this relies on 3265 * the bitmask used in <libproc.h> for encoding symbol 3266 * type and binding matching the order of STB and STT 3267 * constants in <sys/elf.h>. ELF can't change without 3268 * breaking binary compatibility, so I think this is 3269 * reasonably fair game. 3270 */ 3271 if (s_bind < STB_NUM && s_type < STT_NUM) { 3272 type = (1 << (s_type + 8)) | (1 << s_bind); 3273 if ((type & ~mask) != 0) 3274 continue; 3275 } else 3276 continue; /* Invalid type or binding */ 3277 3278 if (GELF_ST_TYPE(sym.st_info) != STT_TLS) 3279 sym.st_value += fptr->file_dyn_base; 3280 3281 si.prs_name = strs + sym.st_name; 3282 3283 /* 3284 * If symbol's type is STT_SECTION, then try to lookup 3285 * the name of the corresponding section. 3286 */ 3287 if (GELF_ST_TYPE(sym.st_info) == STT_SECTION && 3288 fptr->file_shstrs != NULL && 3289 gelf_getshdr(elf_getscn(fptr->file_elf, 3290 sym.st_shndx), &shdr) != NULL && 3291 shdr.sh_name != 0 && 3292 shdr.sh_name < fptr->file_shstrsz) 3293 si.prs_name = fptr->file_shstrs + shdr.sh_name; 3294 3295 si.prs_id = ndx; 3296 if ((rv = func(cd, &sym, si.prs_name, &si)) != 0) 3297 break; 3298 } 3299 } 3300 3301 return (rv); 3302 } 3303 3304 int 3305 Pxsymbol_iter(struct ps_prochandle *P, Lmid_t lmid, const char *object_name, 3306 int which, int mask, proc_xsym_f *func, void *cd) 3307 { 3308 return (Psymbol_iter_com(P, lmid, object_name, which, mask, 3309 PRO_NATURAL, func, cd)); 3310 } 3311 3312 int 3313 Psymbol_iter_by_lmid(struct ps_prochandle *P, Lmid_t lmid, 3314 const char *object_name, int which, int mask, proc_sym_f *func, void *cd) 3315 { 3316 return (Psymbol_iter_com(P, lmid, object_name, which, mask, 3317 PRO_NATURAL, (proc_xsym_f *)func, cd)); 3318 } 3319 3320 int 3321 Psymbol_iter(struct ps_prochandle *P, 3322 const char *object_name, int which, int mask, proc_sym_f *func, void *cd) 3323 { 3324 return (Psymbol_iter_com(P, PR_LMID_EVERY, object_name, which, mask, 3325 PRO_NATURAL, (proc_xsym_f *)func, cd)); 3326 } 3327 3328 int 3329 Psymbol_iter_by_addr(struct ps_prochandle *P, 3330 const char *object_name, int which, int mask, proc_sym_f *func, void *cd) 3331 { 3332 return (Psymbol_iter_com(P, PR_LMID_EVERY, object_name, which, mask, 3333 PRO_BYADDR, (proc_xsym_f *)func, cd)); 3334 } 3335 3336 int 3337 Psymbol_iter_by_name(struct ps_prochandle *P, 3338 const char *object_name, int which, int mask, proc_sym_f *func, void *cd) 3339 { 3340 return (Psymbol_iter_com(P, PR_LMID_EVERY, object_name, which, mask, 3341 PRO_BYNAME, (proc_xsym_f *)func, cd)); 3342 } 3343 3344 /* 3345 * Get the platform string from the core file if we have it; 3346 * just perform the system call for the caller if this is a live process. 3347 */ 3348 char * 3349 Pplatform(struct ps_prochandle *P, char *s, size_t n) 3350 { 3351 if (P->state == PS_IDLE) { 3352 errno = ENODATA; 3353 return (NULL); 3354 } 3355 3356 if (P->state == PS_DEAD) { 3357 if (P->core->core_platform == NULL) { 3358 errno = ENODATA; 3359 return (NULL); 3360 } 3361 (void) strncpy(s, P->core->core_platform, n - 1); 3362 s[n - 1] = '\0'; 3363 3364 } else if (sysinfo(SI_PLATFORM, s, n) == -1) 3365 return (NULL); 3366 3367 return (s); 3368 } 3369 3370 /* 3371 * Get the uname(2) information from the core file if we have it; 3372 * just perform the system call for the caller if this is a live process. 3373 */ 3374 int 3375 Puname(struct ps_prochandle *P, struct utsname *u) 3376 { 3377 if (P->state == PS_IDLE) { 3378 errno = ENODATA; 3379 return (-1); 3380 } 3381 3382 if (P->state == PS_DEAD) { 3383 if (P->core->core_uts == NULL) { 3384 errno = ENODATA; 3385 return (-1); 3386 } 3387 (void) memcpy(u, P->core->core_uts, sizeof (struct utsname)); 3388 return (0); 3389 } 3390 return (uname(u)); 3391 } 3392 3393 /* 3394 * Get the zone name from the core file if we have it; look up the 3395 * name based on the zone id if this is a live process. 3396 */ 3397 char * 3398 Pzonename(struct ps_prochandle *P, char *s, size_t n) 3399 { 3400 if (P->state == PS_IDLE) { 3401 errno = ENODATA; 3402 return (NULL); 3403 } 3404 3405 if (P->state == PS_DEAD) { 3406 if (P->core->core_zonename == NULL) { 3407 errno = ENODATA; 3408 return (NULL); 3409 } 3410 (void) strlcpy(s, P->core->core_zonename, n); 3411 } else { 3412 if (getzonenamebyid(P->status.pr_zoneid, s, n) < 0) 3413 return (NULL); 3414 s[n - 1] = '\0'; 3415 } 3416 return (s); 3417 } 3418 3419 /* 3420 * Called from Pcreate(), Pgrab(), and Pfgrab_core() to initialize 3421 * the symbol table heads in the new ps_prochandle. 3422 */ 3423 void 3424 Pinitsym(struct ps_prochandle *P) 3425 { 3426 P->num_files = 0; 3427 list_link(&P->file_head, NULL); 3428 } 3429 3430 /* 3431 * Called from Prelease() to destroy the symbol tables. 3432 * Must be called by the client after an exec() in the victim process. 3433 */ 3434 void 3435 Preset_maps(struct ps_prochandle *P) 3436 { 3437 int i; 3438 3439 if (P->rap != NULL) { 3440 rd_delete(P->rap); 3441 P->rap = NULL; 3442 } 3443 3444 if (P->execname != NULL) { 3445 free(P->execname); 3446 P->execname = NULL; 3447 } 3448 3449 if (P->auxv != NULL) { 3450 free(P->auxv); 3451 P->auxv = NULL; 3452 P->nauxv = 0; 3453 } 3454 3455 for (i = 0; i < P->map_count; i++) 3456 map_info_free(P, &P->mappings[i]); 3457 3458 if (P->mappings != NULL) { 3459 free(P->mappings); 3460 P->mappings = NULL; 3461 } 3462 P->map_count = P->map_alloc = 0; 3463 3464 P->info_valid = 0; 3465 } 3466 3467 typedef struct getenv_data { 3468 char *buf; 3469 size_t bufsize; 3470 const char *search; 3471 size_t searchlen; 3472 } getenv_data_t; 3473 3474 /*ARGSUSED*/ 3475 static int 3476 getenv_func(void *data, struct ps_prochandle *P, uintptr_t addr, 3477 const char *nameval) 3478 { 3479 getenv_data_t *d = data; 3480 size_t len; 3481 3482 if (nameval == NULL) 3483 return (0); 3484 3485 if (d->searchlen < strlen(nameval) && 3486 strncmp(nameval, d->search, d->searchlen) == 0 && 3487 nameval[d->searchlen] == '=') { 3488 len = MIN(strlen(nameval), d->bufsize - 1); 3489 (void) strncpy(d->buf, nameval, len); 3490 d->buf[len] = '\0'; 3491 return (1); 3492 } 3493 3494 return (0); 3495 } 3496 3497 char * 3498 Pgetenv(struct ps_prochandle *P, const char *name, char *buf, size_t buflen) 3499 { 3500 getenv_data_t d; 3501 3502 d.buf = buf; 3503 d.bufsize = buflen; 3504 d.search = name; 3505 d.searchlen = strlen(name); 3506 3507 if (Penv_iter(P, getenv_func, &d) == 1) { 3508 char *equals = strchr(d.buf, '='); 3509 3510 if (equals != NULL) { 3511 (void) memmove(d.buf, equals + 1, 3512 d.buf + buflen - equals - 1); 3513 d.buf[d.buf + buflen - equals] = '\0'; 3514 3515 return (buf); 3516 } 3517 } 3518 3519 return (NULL); 3520 } 3521 3522 /* number of argument or environment pointers to read all at once */ 3523 #define NARG 100 3524 3525 int 3526 Penv_iter(struct ps_prochandle *P, proc_env_f *func, void *data) 3527 { 3528 const psinfo_t *psp; 3529 uintptr_t envpoff; 3530 GElf_Sym sym; 3531 int ret; 3532 char *buf, *nameval; 3533 size_t buflen; 3534 3535 int nenv = NARG; 3536 long envp[NARG]; 3537 3538 /* 3539 * Attempt to find the "_environ" variable in the process. 3540 * Failing that, use the original value provided by Ppsinfo(). 3541 */ 3542 if ((psp = Ppsinfo(P)) == NULL) 3543 return (-1); 3544 3545 envpoff = psp->pr_envp; /* Default if no _environ found */ 3546 3547 if (Plookup_by_name(P, PR_OBJ_EXEC, "_environ", &sym) == 0) { 3548 if (P->status.pr_dmodel == PR_MODEL_NATIVE) { 3549 if (Pread(P, &envpoff, sizeof (envpoff), 3550 sym.st_value) != sizeof (envpoff)) 3551 envpoff = psp->pr_envp; 3552 } else if (P->status.pr_dmodel == PR_MODEL_ILP32) { 3553 uint32_t envpoff32; 3554 3555 if (Pread(P, &envpoff32, sizeof (envpoff32), 3556 sym.st_value) != sizeof (envpoff32)) 3557 envpoff = psp->pr_envp; 3558 else 3559 envpoff = envpoff32; 3560 } 3561 } 3562 3563 buflen = 128; 3564 buf = malloc(buflen); 3565 3566 ret = 0; 3567 for (;;) { 3568 uintptr_t envoff; 3569 3570 if (nenv == NARG) { 3571 (void) memset(envp, 0, sizeof (envp)); 3572 if (P->status.pr_dmodel == PR_MODEL_NATIVE) { 3573 if (Pread(P, envp, 3574 sizeof (envp), envpoff) <= 0) { 3575 ret = -1; 3576 break; 3577 } 3578 } else if (P->status.pr_dmodel == PR_MODEL_ILP32) { 3579 uint32_t e32[NARG]; 3580 int i; 3581 3582 (void) memset(e32, 0, sizeof (e32)); 3583 if (Pread(P, e32, sizeof (e32), envpoff) <= 0) { 3584 ret = -1; 3585 break; 3586 } 3587 for (i = 0; i < NARG; i++) 3588 envp[i] = e32[i]; 3589 } 3590 nenv = 0; 3591 } 3592 3593 if ((envoff = envp[nenv++]) == NULL) 3594 break; 3595 3596 /* 3597 * Attempt to read the string from the process. 3598 */ 3599 again: 3600 ret = Pread_string(P, buf, buflen, envoff); 3601 3602 if (ret <= 0) { 3603 nameval = NULL; 3604 } else if (ret == buflen - 1) { 3605 free(buf); 3606 /* 3607 * Bail if we have a corrupted environment 3608 */ 3609 if (buflen >= ARG_MAX) 3610 return (-1); 3611 buflen *= 2; 3612 buf = malloc(buflen); 3613 goto again; 3614 } else { 3615 nameval = buf; 3616 } 3617 3618 if ((ret = func(data, P, envoff, nameval)) != 0) 3619 break; 3620 3621 envpoff += (P->status.pr_dmodel == PR_MODEL_LP64)? 8 : 4; 3622 } 3623 3624 free(buf); 3625 3626 return (ret); 3627 } 3628