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 free(dp); 1417 return (NULL); 1418 } 1419 1420 /* 1421 * Allow librtld_db the opportunity to "fix" the program 1422 * headers, if it needs to, before we process them. 1423 */ 1424 if (P->rap != NULL && ehdr.e_type == ET_DYN) { 1425 rd_fix_phdrs(P->rap, dp, phdr.p_filesz, addr); 1426 } 1427 1428 for (i = 0; i < phdr.p_filesz / sizeof (Elf32_Dyn); i++) { 1429 switch (dp[i].d_tag) { 1430 /* 1431 * For the .plt section. 1432 */ 1433 case DT_PLTGOT: 1434 d[DI_PLTGOT] = &dp[i]; 1435 continue; 1436 case DT_JMPREL: 1437 d[DI_JMPREL] = &dp[i]; 1438 continue; 1439 case DT_PLTRELSZ: 1440 d[DI_PLTRELSZ] = &dp[i]; 1441 continue; 1442 case DT_PLTREL: 1443 d[DI_PLTREL] = &dp[i]; 1444 continue; 1445 default: 1446 continue; 1447 1448 /* 1449 * For the .dynsym section. 1450 */ 1451 case DT_SYMTAB: 1452 d[DI_SYMTAB] = &dp[i]; 1453 break; 1454 case DT_HASH: 1455 d[DI_HASH] = &dp[i]; 1456 break; 1457 case DT_SYMENT: 1458 d[DI_SYMENT] = &dp[i]; 1459 break; 1460 1461 /* 1462 * For the .dynstr section. 1463 */ 1464 case DT_STRTAB: 1465 d[DI_STRTAB] = &dp[i]; 1466 break; 1467 case DT_STRSZ: 1468 d[DI_STRSZ] = &dp[i]; 1469 break; 1470 } 1471 1472 dcount++; 1473 } 1474 1475 /* 1476 * We need all of those dynamic entries in order to put 1477 * together a complete set of elf sections, but we'll 1478 * let the PLT section slide if need be. The dynsym- and 1479 * dynstr-related dynamic entries are mandatory in both 1480 * executables and shared objects so if one of those is 1481 * missing, we're in some trouble and should abort. 1482 */ 1483 if (dcount + 4 != DI_NENT) { 1484 dprintf("text section missing required dynamic " 1485 "entries\n"); 1486 return (NULL); 1487 } 1488 1489 if (ehdr.e_type == ET_DYN) { 1490 if (d[DI_PLTGOT] != NULL) 1491 d[DI_PLTGOT]->d_un.d_ptr += addr; 1492 if (d[DI_JMPREL] != NULL) 1493 d[DI_JMPREL]->d_un.d_ptr += addr; 1494 d[DI_SYMTAB]->d_un.d_ptr += addr; 1495 d[DI_HASH]->d_un.d_ptr += addr; 1496 d[DI_STRTAB]->d_un.d_ptr += addr; 1497 } 1498 1499 /* elf header */ 1500 size = sizeof (Elf32_Ehdr); 1501 1502 /* program headers from in-core elf fragment */ 1503 size += phnum * ehdr.e_phentsize; 1504 1505 /* unused shdr, and .shstrtab section */ 1506 size += sizeof (Elf32_Shdr); 1507 size += sizeof (Elf32_Shdr); 1508 size += roundup(sizeof (shstr), 4); 1509 1510 /* .dynsym section */ 1511 size += sizeof (Elf32_Shdr); 1512 if (Pread(P, &nchain, sizeof (nchain), 1513 d[DI_HASH]->d_un.d_ptr + 4) != sizeof (nchain)) { 1514 dprintf("Pread of .dynsym at %lx failed\n", 1515 (long)(d[DI_HASH]->d_un.d_val + 4)); 1516 goto bad32; 1517 } 1518 size += sizeof (Elf32_Sym) * nchain; 1519 1520 /* .dynstr section */ 1521 size += sizeof (Elf32_Shdr); 1522 size += roundup(d[DI_STRSZ]->d_un.d_val, 4); 1523 1524 /* .dynamic section */ 1525 size += sizeof (Elf32_Shdr); 1526 size += roundup(phdr.p_filesz, 4); 1527 1528 /* .plt section */ 1529 if (d[DI_PLTGOT] != NULL && d[DI_JMPREL] != NULL && 1530 d[DI_PLTRELSZ] != NULL && d[DI_PLTREL] != NULL) { 1531 uintptr_t penult, ult; 1532 uintptr_t jmprel = d[DI_JMPREL]->d_un.d_ptr; 1533 size_t pltrelsz = d[DI_PLTRELSZ]->d_un.d_val; 1534 1535 if (d[DI_PLTREL]->d_un.d_val == DT_RELA) { 1536 uint_t ndx = pltrelsz / sizeof (Elf32_Rela) - 2; 1537 Elf32_Rela r[2]; 1538 1539 if (Pread(P, r, sizeof (r), jmprel + 1540 sizeof (r[0]) * ndx) != sizeof (r)) { 1541 dprintf("Pread of DT_RELA failed\n"); 1542 goto bad32; 1543 } 1544 1545 penult = r[0].r_offset; 1546 ult = r[1].r_offset; 1547 1548 } else if (d[DI_PLTREL]->d_un.d_val == DT_REL) { 1549 uint_t ndx = pltrelsz / sizeof (Elf32_Rel) - 2; 1550 Elf32_Rel r[2]; 1551 1552 if (Pread(P, r, sizeof (r), jmprel + 1553 sizeof (r[0]) * ndx) != sizeof (r)) { 1554 dprintf("Pread of DT_REL failed\n"); 1555 goto bad32; 1556 } 1557 1558 penult = r[0].r_offset; 1559 ult = r[1].r_offset; 1560 } else { 1561 dprintf(".plt: unknown jmprel value\n"); 1562 goto bad32; 1563 } 1564 1565 pltentsz = ult - penult; 1566 1567 if (ehdr.e_type == ET_DYN) 1568 ult += addr; 1569 1570 pltsz = ult - d[DI_PLTGOT]->d_un.d_ptr + pltentsz; 1571 1572 size += sizeof (Elf32_Shdr); 1573 size += roundup(pltsz, 4); 1574 } 1575 1576 if ((elfdata = calloc(1, size)) == NULL) 1577 goto bad32; 1578 1579 /* LINTED - alignment */ 1580 ep = (Elf32_Ehdr *)elfdata; 1581 (void) memcpy(ep, &ehdr, offsetof(Elf32_Ehdr, e_phoff)); 1582 1583 ep->e_ehsize = sizeof (Elf32_Ehdr); 1584 ep->e_phoff = sizeof (Elf32_Ehdr); 1585 ep->e_phentsize = ehdr.e_phentsize; 1586 ep->e_phnum = phnum; 1587 ep->e_shoff = ep->e_phoff + phnum * ep->e_phentsize; 1588 ep->e_shentsize = sizeof (Elf32_Shdr); 1589 ep->e_shnum = (pltsz == 0) ? 5 : 6; 1590 ep->e_shstrndx = 1; 1591 1592 /* LINTED - alignment */ 1593 sp = (Elf32_Shdr *)(elfdata + ep->e_shoff); 1594 off = ep->e_shoff + ep->e_shentsize * ep->e_shnum; 1595 1596 /* 1597 * Copying the program headers directly from the process's 1598 * address space is a little suspect, but since we only 1599 * use them for their address and size values, this is fine. 1600 */ 1601 if (Pread(P, &elfdata[ep->e_phoff], phnum * ep->e_phentsize, 1602 addr + ehdr.e_phoff) != phnum * ep->e_phentsize) { 1603 free(elfdata); 1604 dprintf("failed to read program headers\n"); 1605 goto bad32; 1606 } 1607 1608 /* 1609 * The first elf section is always skipped. 1610 */ 1611 sp++; 1612 1613 /* 1614 * Section Header[1] sh_name: .shstrtab 1615 */ 1616 sp->sh_name = 0; 1617 sp->sh_type = SHT_STRTAB; 1618 sp->sh_flags = SHF_STRINGS; 1619 sp->sh_addr = 0; 1620 sp->sh_offset = off; 1621 sp->sh_size = sizeof (shstr); 1622 sp->sh_link = 0; 1623 sp->sh_info = 0; 1624 sp->sh_addralign = 1; 1625 sp->sh_entsize = 0; 1626 1627 (void) memcpy(&elfdata[off], shstr, sizeof (shstr)); 1628 off += roundup(sp->sh_size, 4); 1629 sp++; 1630 1631 /* 1632 * Section Header[2] sh_name: .dynsym 1633 */ 1634 sp->sh_name = 10; 1635 sp->sh_type = SHT_DYNSYM; 1636 sp->sh_flags = SHF_ALLOC; 1637 sp->sh_addr = d[DI_SYMTAB]->d_un.d_ptr; 1638 if (ehdr.e_type == ET_DYN) 1639 sp->sh_addr -= addr; 1640 sp->sh_offset = off; 1641 sp->sh_size = nchain * sizeof (Elf32_Sym); 1642 sp->sh_link = 3; 1643 sp->sh_info = 1; 1644 sp->sh_addralign = 4; 1645 sp->sh_entsize = sizeof (Elf32_Sym); 1646 1647 if (Pread(P, &elfdata[off], sp->sh_size, 1648 d[DI_SYMTAB]->d_un.d_ptr) != sp->sh_size) { 1649 free(elfdata); 1650 dprintf("failed to read .dynsym at %lx\n", 1651 (long)d[DI_SYMTAB]->d_un.d_ptr); 1652 goto bad32; 1653 } 1654 1655 off += roundup(sp->sh_size, 4); 1656 sp++; 1657 1658 /* 1659 * Section Header[3] sh_name: .dynstr 1660 */ 1661 sp->sh_name = 18; 1662 sp->sh_type = SHT_STRTAB; 1663 sp->sh_flags = SHF_ALLOC | SHF_STRINGS; 1664 sp->sh_addr = d[DI_STRTAB]->d_un.d_ptr; 1665 if (ehdr.e_type == ET_DYN) 1666 sp->sh_addr -= addr; 1667 sp->sh_offset = off; 1668 sp->sh_size = d[DI_STRSZ]->d_un.d_val; 1669 sp->sh_link = 0; 1670 sp->sh_info = 0; 1671 sp->sh_addralign = 1; 1672 sp->sh_entsize = 0; 1673 1674 if (Pread(P, &elfdata[off], sp->sh_size, 1675 d[DI_STRTAB]->d_un.d_ptr) != sp->sh_size) { 1676 free(elfdata); 1677 dprintf("failed to read .dynstr\n"); 1678 goto bad32; 1679 } 1680 off += roundup(sp->sh_size, 4); 1681 sp++; 1682 1683 /* 1684 * Section Header[4] sh_name: .dynamic 1685 */ 1686 sp->sh_name = 26; 1687 sp->sh_type = SHT_DYNAMIC; 1688 sp->sh_flags = SHF_WRITE | SHF_ALLOC; 1689 sp->sh_addr = phdr.p_vaddr; 1690 if (ehdr.e_type == ET_DYN) 1691 sp->sh_addr -= addr; 1692 sp->sh_offset = off; 1693 sp->sh_size = phdr.p_filesz; 1694 sp->sh_link = 3; 1695 sp->sh_info = 0; 1696 sp->sh_addralign = 4; 1697 sp->sh_entsize = sizeof (Elf32_Dyn); 1698 1699 (void) memcpy(&elfdata[off], dp, sp->sh_size); 1700 off += roundup(sp->sh_size, 4); 1701 sp++; 1702 1703 /* 1704 * Section Header[5] sh_name: .plt 1705 */ 1706 if (pltsz != 0) { 1707 sp->sh_name = 35; 1708 sp->sh_type = SHT_PROGBITS; 1709 sp->sh_flags = SHF_WRITE | SHF_ALLOC | SHF_EXECINSTR; 1710 sp->sh_addr = d[DI_PLTGOT]->d_un.d_ptr; 1711 if (ehdr.e_type == ET_DYN) 1712 sp->sh_addr -= addr; 1713 sp->sh_offset = off; 1714 sp->sh_size = pltsz; 1715 sp->sh_link = 0; 1716 sp->sh_info = 0; 1717 sp->sh_addralign = 4; 1718 sp->sh_entsize = pltentsz; 1719 1720 if (Pread(P, &elfdata[off], sp->sh_size, 1721 d[DI_PLTGOT]->d_un.d_ptr) != sp->sh_size) { 1722 free(elfdata); 1723 dprintf("failed to read .plt\n"); 1724 goto bad32; 1725 } 1726 off += roundup(sp->sh_size, 4); 1727 sp++; 1728 } 1729 1730 free(dp); 1731 goto good; 1732 1733 bad32: 1734 free(dp); 1735 return (NULL); 1736 #ifdef _LP64 1737 } else if (P->status.pr_dmodel == PR_MODEL_LP64) { 1738 Elf64_Ehdr ehdr, *ep; 1739 Elf64_Phdr phdr; 1740 Elf64_Shdr *sp; 1741 Elf64_Dyn *dp; 1742 Elf64_Dyn *d[DI_NENT] = { 0 }; 1743 uint_t phnum, i, dcount = 0; 1744 uint64_t off; 1745 size_t pltsz = 0, pltentsz; 1746 1747 if (read_ehdr64(P, &ehdr, &phnum, addr) != 0 || 1748 read_dynamic_phdr64(P, &ehdr, phnum, &phdr, addr) != 0) 1749 return (NULL); 1750 1751 if (ehdr.e_type == ET_DYN) 1752 phdr.p_vaddr += addr; 1753 1754 if ((dp = malloc(phdr.p_filesz)) == NULL) 1755 return (NULL); 1756 1757 if (Pread(P, dp, phdr.p_filesz, phdr.p_vaddr) != 1758 phdr.p_filesz) { 1759 free(dp); 1760 return (NULL); 1761 } 1762 1763 for (i = 0; i < phdr.p_filesz / sizeof (Elf64_Dyn); i++) { 1764 switch (dp[i].d_tag) { 1765 /* 1766 * For the .plt section. 1767 */ 1768 case DT_PLTGOT: 1769 d[DI_PLTGOT] = &dp[i]; 1770 continue; 1771 case DT_JMPREL: 1772 d[DI_JMPREL] = &dp[i]; 1773 continue; 1774 case DT_PLTRELSZ: 1775 d[DI_PLTRELSZ] = &dp[i]; 1776 continue; 1777 case DT_PLTREL: 1778 d[DI_PLTREL] = &dp[i]; 1779 continue; 1780 default: 1781 continue; 1782 1783 /* 1784 * For the .dynsym section. 1785 */ 1786 case DT_SYMTAB: 1787 d[DI_SYMTAB] = &dp[i]; 1788 break; 1789 case DT_HASH: 1790 d[DI_HASH] = &dp[i]; 1791 break; 1792 case DT_SYMENT: 1793 d[DI_SYMENT] = &dp[i]; 1794 break; 1795 1796 /* 1797 * For the .dynstr section. 1798 */ 1799 case DT_STRTAB: 1800 d[DI_STRTAB] = &dp[i]; 1801 break; 1802 case DT_STRSZ: 1803 d[DI_STRSZ] = &dp[i]; 1804 break; 1805 } 1806 1807 dcount++; 1808 } 1809 1810 /* 1811 * We need all of those dynamic entries in order to put 1812 * together a complete set of elf sections, but we'll 1813 * let the PLT section slide if need be. The dynsym- and 1814 * dynstr-related dynamic entries are mandatory in both 1815 * executables and shared objects so if one of those is 1816 * missing, we're in some trouble and should abort. 1817 */ 1818 if (dcount + 4 != DI_NENT) { 1819 dprintf("text section missing required dynamic " 1820 "entries\n"); 1821 return (NULL); 1822 } 1823 1824 if (ehdr.e_type == ET_DYN) { 1825 if (d[DI_PLTGOT] != NULL) 1826 d[DI_PLTGOT]->d_un.d_ptr += addr; 1827 if (d[DI_JMPREL] != NULL) 1828 d[DI_JMPREL]->d_un.d_ptr += addr; 1829 d[DI_SYMTAB]->d_un.d_ptr += addr; 1830 d[DI_HASH]->d_un.d_ptr += addr; 1831 d[DI_STRTAB]->d_un.d_ptr += addr; 1832 } 1833 1834 /* elf header */ 1835 size = sizeof (Elf64_Ehdr); 1836 1837 /* program headers from in-core elf fragment */ 1838 size += phnum * ehdr.e_phentsize; 1839 1840 /* unused shdr, and .shstrtab section */ 1841 size += sizeof (Elf64_Shdr); 1842 size += sizeof (Elf64_Shdr); 1843 size += roundup(sizeof (shstr), 8); 1844 1845 /* .dynsym section */ 1846 size += sizeof (Elf64_Shdr); 1847 if (Pread(P, &nchain, sizeof (nchain), 1848 d[DI_HASH]->d_un.d_ptr + 4) != sizeof (nchain)) 1849 goto bad64; 1850 size += sizeof (Elf64_Sym) * nchain; 1851 1852 /* .dynstr section */ 1853 size += sizeof (Elf64_Shdr); 1854 size += roundup(d[DI_STRSZ]->d_un.d_val, 8); 1855 1856 /* .dynamic section */ 1857 size += sizeof (Elf64_Shdr); 1858 size += roundup(phdr.p_filesz, 8); 1859 1860 /* .plt section */ 1861 if (d[DI_PLTGOT] != NULL && d[DI_JMPREL] != NULL && 1862 d[DI_PLTRELSZ] != NULL && d[DI_PLTREL] != NULL) { 1863 uintptr_t penult, ult; 1864 uintptr_t jmprel = d[DI_JMPREL]->d_un.d_ptr; 1865 size_t pltrelsz = d[DI_PLTRELSZ]->d_un.d_val; 1866 1867 if (d[DI_PLTREL]->d_un.d_val == DT_RELA) { 1868 uint_t ndx = pltrelsz / sizeof (Elf64_Rela) - 2; 1869 Elf64_Rela r[2]; 1870 1871 if (Pread(P, r, sizeof (r), jmprel + 1872 sizeof (r[0]) * ndx) != sizeof (r)) { 1873 dprintf("Pread jmprel DT_RELA at %p " 1874 "failed\n", 1875 (void *)(jmprel + 1876 sizeof (r[0]) * ndx)); 1877 goto bad64; 1878 } 1879 1880 penult = r[0].r_offset; 1881 ult = r[1].r_offset; 1882 1883 } else if (d[DI_PLTREL]->d_un.d_val == DT_REL) { 1884 uint_t ndx = pltrelsz / sizeof (Elf64_Rel) - 2; 1885 Elf64_Rel r[2]; 1886 1887 if (Pread(P, r, sizeof (r), jmprel + 1888 sizeof (r[0]) * ndx) != sizeof (r)) { 1889 dprintf("Pread jmprel DT_REL at %p " 1890 "failed\n", 1891 (void *)(jmprel + 1892 sizeof (r[0]) * ndx)); 1893 goto bad64; 1894 } 1895 1896 penult = r[0].r_offset; 1897 ult = r[1].r_offset; 1898 } else { 1899 dprintf("DT_PLTREL value %p unknown\n", 1900 (void *)d[DI_PLTREL]->d_un.d_ptr); 1901 goto bad64; 1902 } 1903 1904 pltentsz = ult - penult; 1905 1906 if (ehdr.e_type == ET_DYN) 1907 ult += addr; 1908 1909 pltsz = ult - d[DI_PLTGOT]->d_un.d_ptr + pltentsz; 1910 1911 size += sizeof (Elf64_Shdr); 1912 size += roundup(pltsz, 8); 1913 } 1914 1915 if ((elfdata = calloc(1, size)) == NULL) 1916 goto bad64; 1917 1918 /* LINTED - alignment */ 1919 ep = (Elf64_Ehdr *)elfdata; 1920 (void) memcpy(ep, &ehdr, offsetof(Elf64_Ehdr, e_phoff)); 1921 1922 ep->e_ehsize = sizeof (Elf64_Ehdr); 1923 ep->e_phoff = sizeof (Elf64_Ehdr); 1924 ep->e_phentsize = ehdr.e_phentsize; 1925 ep->e_phnum = phnum; 1926 ep->e_shoff = ep->e_phoff + phnum * ep->e_phentsize; 1927 ep->e_shentsize = sizeof (Elf64_Shdr); 1928 ep->e_shnum = (pltsz == 0) ? 5 : 6; 1929 ep->e_shstrndx = 1; 1930 1931 /* LINTED - alignment */ 1932 sp = (Elf64_Shdr *)(elfdata + ep->e_shoff); 1933 off = ep->e_shoff + ep->e_shentsize * ep->e_shnum; 1934 1935 /* 1936 * Copying the program headers directly from the process's 1937 * address space is a little suspect, but since we only 1938 * use them for their address and size values, this is fine. 1939 */ 1940 if (Pread(P, &elfdata[ep->e_phoff], phnum * ep->e_phentsize, 1941 addr + ehdr.e_phoff) != phnum * ep->e_phentsize) { 1942 free(elfdata); 1943 goto bad64; 1944 } 1945 1946 /* 1947 * The first elf section is always skipped. 1948 */ 1949 sp++; 1950 1951 /* 1952 * Section Header[1] sh_name: .shstrtab 1953 */ 1954 sp->sh_name = 0; 1955 sp->sh_type = SHT_STRTAB; 1956 sp->sh_flags = SHF_STRINGS; 1957 sp->sh_addr = 0; 1958 sp->sh_offset = off; 1959 sp->sh_size = sizeof (shstr); 1960 sp->sh_link = 0; 1961 sp->sh_info = 0; 1962 sp->sh_addralign = 1; 1963 sp->sh_entsize = 0; 1964 1965 (void) memcpy(&elfdata[off], shstr, sizeof (shstr)); 1966 off += roundup(sp->sh_size, 8); 1967 sp++; 1968 1969 /* 1970 * Section Header[2] sh_name: .dynsym 1971 */ 1972 sp->sh_name = 10; 1973 sp->sh_type = SHT_DYNSYM; 1974 sp->sh_flags = SHF_ALLOC; 1975 sp->sh_addr = d[DI_SYMTAB]->d_un.d_ptr; 1976 if (ehdr.e_type == ET_DYN) 1977 sp->sh_addr -= addr; 1978 sp->sh_offset = off; 1979 sp->sh_size = nchain * sizeof (Elf64_Sym); 1980 sp->sh_link = 3; 1981 sp->sh_info = 1; 1982 sp->sh_addralign = 8; 1983 sp->sh_entsize = sizeof (Elf64_Sym); 1984 1985 if (Pread(P, &elfdata[off], sp->sh_size, 1986 d[DI_SYMTAB]->d_un.d_ptr) != sp->sh_size) { 1987 free(elfdata); 1988 goto bad64; 1989 } 1990 1991 off += roundup(sp->sh_size, 8); 1992 sp++; 1993 1994 /* 1995 * Section Header[3] sh_name: .dynstr 1996 */ 1997 sp->sh_name = 18; 1998 sp->sh_type = SHT_STRTAB; 1999 sp->sh_flags = SHF_ALLOC | SHF_STRINGS; 2000 sp->sh_addr = d[DI_STRTAB]->d_un.d_ptr; 2001 if (ehdr.e_type == ET_DYN) 2002 sp->sh_addr -= addr; 2003 sp->sh_offset = off; 2004 sp->sh_size = d[DI_STRSZ]->d_un.d_val; 2005 sp->sh_link = 0; 2006 sp->sh_info = 0; 2007 sp->sh_addralign = 1; 2008 sp->sh_entsize = 0; 2009 2010 if (Pread(P, &elfdata[off], sp->sh_size, 2011 d[DI_STRTAB]->d_un.d_ptr) != sp->sh_size) { 2012 free(elfdata); 2013 goto bad64; 2014 } 2015 off += roundup(sp->sh_size, 8); 2016 sp++; 2017 2018 /* 2019 * Section Header[4] sh_name: .dynamic 2020 */ 2021 sp->sh_name = 26; 2022 sp->sh_type = SHT_DYNAMIC; 2023 sp->sh_flags = SHF_WRITE | SHF_ALLOC; 2024 sp->sh_addr = phdr.p_vaddr; 2025 if (ehdr.e_type == ET_DYN) 2026 sp->sh_addr -= addr; 2027 sp->sh_offset = off; 2028 sp->sh_size = phdr.p_filesz; 2029 sp->sh_link = 3; 2030 sp->sh_info = 0; 2031 sp->sh_addralign = 8; 2032 sp->sh_entsize = sizeof (Elf64_Dyn); 2033 2034 (void) memcpy(&elfdata[off], dp, sp->sh_size); 2035 off += roundup(sp->sh_size, 8); 2036 sp++; 2037 2038 /* 2039 * Section Header[5] sh_name: .plt 2040 */ 2041 if (pltsz != 0) { 2042 sp->sh_name = 35; 2043 sp->sh_type = SHT_PROGBITS; 2044 sp->sh_flags = SHF_WRITE | SHF_ALLOC | SHF_EXECINSTR; 2045 sp->sh_addr = d[DI_PLTGOT]->d_un.d_ptr; 2046 if (ehdr.e_type == ET_DYN) 2047 sp->sh_addr -= addr; 2048 sp->sh_offset = off; 2049 sp->sh_size = pltsz; 2050 sp->sh_link = 0; 2051 sp->sh_info = 0; 2052 sp->sh_addralign = 8; 2053 sp->sh_entsize = pltentsz; 2054 2055 if (Pread(P, &elfdata[off], sp->sh_size, 2056 d[DI_PLTGOT]->d_un.d_ptr) != sp->sh_size) { 2057 free(elfdata); 2058 goto bad64; 2059 } 2060 off += roundup(sp->sh_size, 8); 2061 sp++; 2062 } 2063 2064 free(dp); 2065 goto good; 2066 2067 bad64: 2068 free(dp); 2069 return (NULL); 2070 #endif /* _LP64 */ 2071 } 2072 good: 2073 if ((elf = elf_memory(elfdata, size)) == NULL) { 2074 free(elfdata); 2075 return (NULL); 2076 } 2077 2078 fptr->file_elfmem = elfdata; 2079 2080 return (elf); 2081 } 2082 2083 /* 2084 * We wouldn't need these if qsort(3C) took an argument for the callback... 2085 */ 2086 static mutex_t sort_mtx = DEFAULTMUTEX; 2087 static char *sort_strs; 2088 static GElf_Sym *sort_syms; 2089 2090 int 2091 byaddr_cmp_common(GElf_Sym *a, char *aname, GElf_Sym *b, char *bname) 2092 { 2093 if (a->st_value < b->st_value) 2094 return (-1); 2095 if (a->st_value > b->st_value) 2096 return (1); 2097 2098 /* 2099 * Prefer the function to the non-function. 2100 */ 2101 if (GELF_ST_TYPE(a->st_info) != GELF_ST_TYPE(b->st_info)) { 2102 if (GELF_ST_TYPE(a->st_info) == STT_FUNC) 2103 return (-1); 2104 if (GELF_ST_TYPE(b->st_info) == STT_FUNC) 2105 return (1); 2106 } 2107 2108 /* 2109 * Prefer the weak or strong global symbol to the local symbol. 2110 */ 2111 if (GELF_ST_BIND(a->st_info) != GELF_ST_BIND(b->st_info)) { 2112 if (GELF_ST_BIND(b->st_info) == STB_LOCAL) 2113 return (-1); 2114 if (GELF_ST_BIND(a->st_info) == STB_LOCAL) 2115 return (1); 2116 } 2117 2118 /* 2119 * Prefer the symbol that doesn't begin with a '$' since compilers and 2120 * other symbol generators often use it as a prefix. 2121 */ 2122 if (*bname == '$') 2123 return (-1); 2124 if (*aname == '$') 2125 return (1); 2126 2127 /* 2128 * Prefer the name with fewer leading underscores in the name. 2129 */ 2130 while (*aname == '_' && *bname == '_') { 2131 aname++; 2132 bname++; 2133 } 2134 2135 if (*bname == '_') 2136 return (-1); 2137 if (*aname == '_') 2138 return (1); 2139 2140 /* 2141 * Prefer the symbol with the smaller size. 2142 */ 2143 if (a->st_size < b->st_size) 2144 return (-1); 2145 if (a->st_size > b->st_size) 2146 return (1); 2147 2148 /* 2149 * All other factors being equal, fall back to lexicographic order. 2150 */ 2151 return (strcmp(aname, bname)); 2152 } 2153 2154 static int 2155 byaddr_cmp(const void *aa, const void *bb) 2156 { 2157 GElf_Sym *a = &sort_syms[*(uint_t *)aa]; 2158 GElf_Sym *b = &sort_syms[*(uint_t *)bb]; 2159 char *aname = sort_strs + a->st_name; 2160 char *bname = sort_strs + b->st_name; 2161 2162 return (byaddr_cmp_common(a, aname, b, bname)); 2163 } 2164 2165 static int 2166 byname_cmp(const void *aa, const void *bb) 2167 { 2168 GElf_Sym *a = &sort_syms[*(uint_t *)aa]; 2169 GElf_Sym *b = &sort_syms[*(uint_t *)bb]; 2170 char *aname = sort_strs + a->st_name; 2171 char *bname = sort_strs + b->st_name; 2172 2173 return (strcmp(aname, bname)); 2174 } 2175 2176 void 2177 optimize_symtab(sym_tbl_t *symtab) 2178 { 2179 GElf_Sym *symp, *syms; 2180 uint_t i, *indexa, *indexb; 2181 Elf_Data *data; 2182 size_t symn, strsz, count; 2183 2184 if (symtab == NULL || symtab->sym_data == NULL || 2185 symtab->sym_byaddr != NULL) 2186 return; 2187 2188 data = symtab->sym_data; 2189 symn = symtab->sym_symn; 2190 strsz = symtab->sym_strsz; 2191 2192 symp = syms = malloc(sizeof (GElf_Sym) * symn); 2193 2194 /* 2195 * First record all the symbols into a table and count up the ones 2196 * that we're interested in. We mark symbols as invalid by setting 2197 * the st_name to an illegal value. 2198 */ 2199 for (i = 0, count = 0; i < symn; i++, symp++) { 2200 if (gelf_getsym(data, i, symp) != NULL && 2201 symp->st_name < strsz && 2202 IS_DATA_TYPE(GELF_ST_TYPE(symp->st_info))) 2203 count++; 2204 else 2205 symp->st_name = strsz; 2206 } 2207 2208 /* 2209 * Allocate sufficient space for both tables and populate them 2210 * with the same symbols we just counted. 2211 */ 2212 symtab->sym_count = count; 2213 indexa = symtab->sym_byaddr = calloc(sizeof (uint_t), count); 2214 indexb = symtab->sym_byname = calloc(sizeof (uint_t), count); 2215 2216 for (i = 0, symp = syms; i < symn; i++, symp++) { 2217 if (symp->st_name < strsz) 2218 *indexa++ = *indexb++ = i; 2219 } 2220 2221 /* 2222 * Sort the two tables according to the appropriate criteria. 2223 */ 2224 (void) mutex_lock(&sort_mtx); 2225 sort_strs = symtab->sym_strs; 2226 sort_syms = syms; 2227 2228 qsort(symtab->sym_byaddr, count, sizeof (uint_t), byaddr_cmp); 2229 qsort(symtab->sym_byname, count, sizeof (uint_t), byname_cmp); 2230 2231 sort_strs = NULL; 2232 sort_syms = NULL; 2233 (void) mutex_unlock(&sort_mtx); 2234 2235 free(syms); 2236 } 2237 2238 /* 2239 * Build the symbol table for the given mapped file. 2240 */ 2241 void 2242 Pbuild_file_symtab(struct ps_prochandle *P, file_info_t *fptr) 2243 { 2244 char objectfile[PATH_MAX]; 2245 uint_t i; 2246 2247 GElf_Ehdr ehdr; 2248 GElf_Sym s; 2249 2250 Elf_Data *shdata; 2251 Elf_Scn *scn; 2252 Elf *elf; 2253 size_t nshdrs, shstrndx; 2254 2255 struct { 2256 GElf_Shdr c_shdr; 2257 Elf_Data *c_data; 2258 const char *c_name; 2259 } *cp, *cache = NULL, *dyn = NULL, *plt = NULL, *ctf = NULL; 2260 2261 if (fptr->file_init) 2262 return; /* We've already processed this file */ 2263 2264 /* 2265 * Mark the file_info struct as having the symbol table initialized 2266 * even if we fail below. We tried once; we don't try again. 2267 */ 2268 fptr->file_init = 1; 2269 2270 if (elf_version(EV_CURRENT) == EV_NONE) { 2271 dprintf("libproc ELF version is more recent than libelf\n"); 2272 return; 2273 } 2274 2275 if (P->state == PS_DEAD || P->state == PS_IDLE) { 2276 /* 2277 * If we're a not live, we can't open files from the /proc 2278 * object directory; we have only the mapping and file names 2279 * to guide us. We prefer the file_lname, but need to handle 2280 * the case of it being NULL in order to bootstrap: we first 2281 * come here during rd_new() when the only information we have 2282 * is interpreter name associated with the AT_BASE mapping. 2283 */ 2284 (void) snprintf(objectfile, sizeof (objectfile), "%s", 2285 fptr->file_lname ? fptr->file_lname : fptr->file_pname); 2286 } else { 2287 (void) snprintf(objectfile, sizeof (objectfile), 2288 "%s/%d/object/%s", 2289 procfs_path, (int)P->pid, fptr->file_pname); 2290 } 2291 2292 /* 2293 * Open the object file, create the elf file, and then get the elf 2294 * header and .shstrtab data buffer so we can process sections by 2295 * name. If anything goes wrong try to fake up an elf file from 2296 * the in-core elf image. 2297 */ 2298 if ((fptr->file_fd = open(objectfile, O_RDONLY)) < 0) { 2299 dprintf("Pbuild_file_symtab: failed to open %s: %s\n", 2300 objectfile, strerror(errno)); 2301 2302 if ((elf = fake_elf(P, fptr)) == NULL || 2303 elf_kind(elf) != ELF_K_ELF || 2304 gelf_getehdr(elf, &ehdr) == NULL || 2305 elf_getshnum(elf, &nshdrs) == 0 || 2306 elf_getshstrndx(elf, &shstrndx) == 0 || 2307 (scn = elf_getscn(elf, shstrndx)) == NULL || 2308 (shdata = elf_getdata(scn, NULL)) == NULL) { 2309 dprintf("failed to fake up ELF file\n"); 2310 return; 2311 } 2312 2313 } else if ((elf = elf_begin(fptr->file_fd, ELF_C_READ, NULL)) == NULL || 2314 elf_kind(elf) != ELF_K_ELF || 2315 gelf_getehdr(elf, &ehdr) == NULL || 2316 elf_getshnum(elf, &nshdrs) == 0 || 2317 elf_getshstrndx(elf, &shstrndx) == 0 || 2318 (scn = elf_getscn(elf, shstrndx)) == NULL || 2319 (shdata = elf_getdata(scn, NULL)) == NULL) { 2320 int err = elf_errno(); 2321 2322 dprintf("failed to process ELF file %s: %s\n", 2323 objectfile, (err == 0) ? "<null>" : elf_errmsg(err)); 2324 2325 if ((elf = fake_elf(P, fptr)) == NULL || 2326 elf_kind(elf) != ELF_K_ELF || 2327 gelf_getehdr(elf, &ehdr) == NULL || 2328 elf_getshnum(elf, &nshdrs) == 0 || 2329 elf_getshstrndx(elf, &shstrndx) == 0 || 2330 (scn = elf_getscn(elf, shstrndx)) == NULL || 2331 (shdata = elf_getdata(scn, NULL)) == NULL) { 2332 dprintf("failed to fake up ELF file\n"); 2333 goto bad; 2334 } 2335 2336 } else if (file_differs(P, elf, fptr)) { 2337 Elf *newelf; 2338 2339 /* 2340 * Before we get too excited about this elf file, we'll check 2341 * its checksum value against the value we have in memory. If 2342 * they don't agree, we try to fake up a new elf file and 2343 * proceed with that instead. 2344 */ 2345 2346 dprintf("ELF file %s (%lx) doesn't match in-core image\n", 2347 fptr->file_pname, 2348 (ulong_t)fptr->file_map->map_pmap.pr_vaddr); 2349 2350 if ((newelf = fake_elf(P, fptr)) == NULL || 2351 elf_kind(newelf) != ELF_K_ELF || 2352 gelf_getehdr(newelf, &ehdr) == NULL || 2353 elf_getshnum(newelf, &nshdrs) == 0 || 2354 elf_getshstrndx(newelf, &shstrndx) == 0 || 2355 (scn = elf_getscn(newelf, shstrndx)) == NULL || 2356 (shdata = elf_getdata(scn, NULL)) == NULL) { 2357 dprintf("failed to fake up ELF file\n"); 2358 } else { 2359 (void) elf_end(elf); 2360 elf = newelf; 2361 2362 dprintf("switched to faked up ELF file\n"); 2363 } 2364 } 2365 2366 if ((cache = malloc(nshdrs * sizeof (*cache))) == NULL) { 2367 dprintf("failed to malloc section cache for %s\n", objectfile); 2368 goto bad; 2369 } 2370 2371 dprintf("processing ELF file %s\n", objectfile); 2372 fptr->file_class = ehdr.e_ident[EI_CLASS]; 2373 fptr->file_etype = ehdr.e_type; 2374 fptr->file_elf = elf; 2375 fptr->file_shstrs = shdata->d_buf; 2376 fptr->file_shstrsz = shdata->d_size; 2377 2378 /* 2379 * Iterate through each section, caching its section header, data 2380 * pointer, and name. We use this for handling sh_link values below. 2381 */ 2382 for (cp = cache + 1, scn = NULL; scn = elf_nextscn(elf, scn); cp++) { 2383 if (gelf_getshdr(scn, &cp->c_shdr) == NULL) { 2384 dprintf("Pbuild_file_symtab: Failed to get section " 2385 "header\n"); 2386 goto bad; /* Failed to get section header */ 2387 } 2388 2389 if ((cp->c_data = elf_getdata(scn, NULL)) == NULL) { 2390 dprintf("Pbuild_file_symtab: Failed to get section " 2391 "data\n"); 2392 goto bad; /* Failed to get section data */ 2393 } 2394 2395 if (cp->c_shdr.sh_name >= shdata->d_size) { 2396 dprintf("Pbuild_file_symtab: corrupt section name"); 2397 goto bad; /* Corrupt section name */ 2398 } 2399 2400 cp->c_name = (const char *)shdata->d_buf + cp->c_shdr.sh_name; 2401 } 2402 2403 /* 2404 * Now iterate through the section cache in order to locate info 2405 * for the .symtab, .dynsym, .dynamic, .plt, and .SUNW_ctf sections: 2406 */ 2407 for (i = 1, cp = cache + 1; i < nshdrs; i++, cp++) { 2408 GElf_Shdr *shp = &cp->c_shdr; 2409 2410 if (shp->sh_type == SHT_SYMTAB || shp->sh_type == SHT_DYNSYM) { 2411 sym_tbl_t *symp = shp->sh_type == SHT_SYMTAB ? 2412 &fptr->file_symtab : &fptr->file_dynsym; 2413 /* 2414 * It's possible that the we already got the symbol 2415 * table from the core file itself. Either the file 2416 * differs in which case our faked up elf file will 2417 * only contain the dynsym (not the symtab) or the 2418 * file matches in which case we'll just be replacing 2419 * the symbol table we pulled out of the core file 2420 * with an equivalent one. In either case, this 2421 * check isn't essential, but it's a good idea. 2422 */ 2423 if (symp->sym_data == NULL) { 2424 dprintf("Symbol table found for %s\n", 2425 objectfile); 2426 symp->sym_data = cp->c_data; 2427 symp->sym_symn = shp->sh_size / shp->sh_entsize; 2428 symp->sym_strs = 2429 cache[shp->sh_link].c_data->d_buf; 2430 symp->sym_strsz = 2431 cache[shp->sh_link].c_data->d_size; 2432 symp->sym_hdr = cp->c_shdr; 2433 symp->sym_strhdr = cache[shp->sh_link].c_shdr; 2434 } else { 2435 dprintf("Symbol table already there for %s\n", 2436 objectfile); 2437 } 2438 2439 } else if (shp->sh_type == SHT_DYNAMIC) { 2440 dyn = cp; 2441 } else if (strcmp(cp->c_name, ".plt") == 0) { 2442 plt = cp; 2443 } else if (strcmp(cp->c_name, ".SUNW_ctf") == 0) { 2444 /* 2445 * Skip over bogus CTF sections so they don't come back 2446 * to haunt us later. 2447 */ 2448 if (shp->sh_link == 0 || 2449 shp->sh_link >= nshdrs || 2450 (cache[shp->sh_link].c_shdr.sh_type != SHT_DYNSYM && 2451 cache[shp->sh_link].c_shdr.sh_type != SHT_SYMTAB)) { 2452 dprintf("Bad sh_link %d for " 2453 "CTF\n", shp->sh_link); 2454 continue; 2455 } 2456 ctf = cp; 2457 } 2458 } 2459 2460 /* 2461 * At this point, we've found all the symbol tables we're ever going 2462 * to find: the ones in the loop above and possibly the symtab that 2463 * was included in the core file. Before we perform any lookups, we 2464 * create sorted versions to optimize for lookups. 2465 */ 2466 optimize_symtab(&fptr->file_symtab); 2467 optimize_symtab(&fptr->file_dynsym); 2468 2469 /* 2470 * Fill in the base address of the text mapping for shared libraries. 2471 * This allows us to translate symbols before librtld_db is ready. 2472 */ 2473 if (fptr->file_etype == ET_DYN) { 2474 fptr->file_dyn_base = fptr->file_map->map_pmap.pr_vaddr - 2475 fptr->file_map->map_pmap.pr_offset; 2476 dprintf("setting file_dyn_base for %s to %lx\n", 2477 objectfile, (long)fptr->file_dyn_base); 2478 } 2479 2480 /* 2481 * Record the CTF section information in the file info structure. 2482 */ 2483 if (ctf != NULL) { 2484 fptr->file_ctf_off = ctf->c_shdr.sh_offset; 2485 fptr->file_ctf_size = ctf->c_shdr.sh_size; 2486 if (ctf->c_shdr.sh_link != 0 && 2487 cache[ctf->c_shdr.sh_link].c_shdr.sh_type == SHT_DYNSYM) 2488 fptr->file_ctf_dyn = 1; 2489 } 2490 2491 if (fptr->file_lo == NULL) 2492 goto done; /* Nothing else to do if no load object info */ 2493 2494 /* 2495 * If the object is a shared library and we have a different rl_base 2496 * value, reset file_dyn_base according to librtld_db's information. 2497 */ 2498 if (fptr->file_etype == ET_DYN && 2499 fptr->file_lo->rl_base != fptr->file_dyn_base) { 2500 dprintf("resetting file_dyn_base for %s to %lx\n", 2501 objectfile, (long)fptr->file_lo->rl_base); 2502 fptr->file_dyn_base = fptr->file_lo->rl_base; 2503 } 2504 2505 /* 2506 * Fill in the PLT information for this file if a PLT symbol is found. 2507 */ 2508 if (sym_by_name(&fptr->file_dynsym, "_PROCEDURE_LINKAGE_TABLE_", &s, 2509 NULL) != NULL) { 2510 fptr->file_plt_base = s.st_value + fptr->file_dyn_base; 2511 fptr->file_plt_size = (plt != NULL) ? plt->c_shdr.sh_size : 0; 2512 2513 /* 2514 * Bring the load object up to date; it is the only way the 2515 * user has to access the PLT data. The PLT information in the 2516 * rd_loadobj_t is not set in the call to map_iter() (the 2517 * callback for rd_loadobj_iter) where we set file_lo. 2518 */ 2519 fptr->file_lo->rl_plt_base = fptr->file_plt_base; 2520 fptr->file_lo->rl_plt_size = fptr->file_plt_size; 2521 2522 dprintf("PLT found at %p, size = %lu\n", 2523 (void *)fptr->file_plt_base, (ulong_t)fptr->file_plt_size); 2524 } 2525 2526 /* 2527 * Fill in the PLT information. 2528 */ 2529 if (dyn != NULL) { 2530 uintptr_t dynaddr = dyn->c_shdr.sh_addr + fptr->file_dyn_base; 2531 size_t ndyn = dyn->c_shdr.sh_size / dyn->c_shdr.sh_entsize; 2532 GElf_Dyn d; 2533 2534 for (i = 0; i < ndyn; i++) { 2535 if (gelf_getdyn(dyn->c_data, i, &d) != NULL && 2536 d.d_tag == DT_JMPREL) { 2537 dprintf("DT_JMPREL is %p\n", 2538 (void *)(uintptr_t)d.d_un.d_ptr); 2539 fptr->file_jmp_rel = 2540 d.d_un.d_ptr + fptr->file_dyn_base; 2541 break; 2542 } 2543 } 2544 2545 dprintf("_DYNAMIC found at %p, %lu entries, DT_JMPREL = %p\n", 2546 (void *)dynaddr, (ulong_t)ndyn, (void *)fptr->file_jmp_rel); 2547 } 2548 2549 done: 2550 free(cache); 2551 return; 2552 2553 bad: 2554 if (cache != NULL) 2555 free(cache); 2556 2557 (void) elf_end(elf); 2558 fptr->file_elf = NULL; 2559 if (fptr->file_elfmem != NULL) { 2560 free(fptr->file_elfmem); 2561 fptr->file_elfmem = NULL; 2562 } 2563 (void) close(fptr->file_fd); 2564 fptr->file_fd = -1; 2565 } 2566 2567 /* 2568 * Given a process virtual address, return the map_info_t containing it. 2569 * If none found, return NULL. 2570 */ 2571 map_info_t * 2572 Paddr2mptr(struct ps_prochandle *P, uintptr_t addr) 2573 { 2574 int lo = 0; 2575 int hi = P->map_count - 1; 2576 int mid; 2577 map_info_t *mp; 2578 2579 while (lo <= hi) { 2580 2581 mid = (lo + hi) / 2; 2582 mp = &P->mappings[mid]; 2583 2584 /* check that addr is in [vaddr, vaddr + size) */ 2585 if ((addr - mp->map_pmap.pr_vaddr) < mp->map_pmap.pr_size) 2586 return (mp); 2587 2588 if (addr < mp->map_pmap.pr_vaddr) 2589 hi = mid - 1; 2590 else 2591 lo = mid + 1; 2592 } 2593 2594 return (NULL); 2595 } 2596 2597 /* 2598 * Return the map_info_t for the executable file. 2599 * If not found, return NULL. 2600 */ 2601 static map_info_t * 2602 exec_map(struct ps_prochandle *P) 2603 { 2604 uint_t i; 2605 map_info_t *mptr; 2606 map_info_t *mold = NULL; 2607 file_info_t *fptr; 2608 uintptr_t base; 2609 2610 for (i = 0, mptr = P->mappings; i < P->map_count; i++, mptr++) { 2611 if (mptr->map_pmap.pr_mapname[0] == '\0') 2612 continue; 2613 if (strcmp(mptr->map_pmap.pr_mapname, "a.out") == 0) { 2614 if ((fptr = mptr->map_file) != NULL && 2615 fptr->file_lo != NULL) { 2616 base = fptr->file_lo->rl_base; 2617 if (base >= mptr->map_pmap.pr_vaddr && 2618 base < mptr->map_pmap.pr_vaddr + 2619 mptr->map_pmap.pr_size) /* text space */ 2620 return (mptr); 2621 mold = mptr; /* must be the data */ 2622 continue; 2623 } 2624 /* This is a poor way to test for text space */ 2625 if (!(mptr->map_pmap.pr_mflags & MA_EXEC) || 2626 (mptr->map_pmap.pr_mflags & MA_WRITE)) { 2627 mold = mptr; 2628 continue; 2629 } 2630 return (mptr); 2631 } 2632 } 2633 2634 return (mold); 2635 } 2636 2637 /* 2638 * Given a shared object name, return the map_info_t for it. If no matching 2639 * object is found, return NULL. Normally, the link maps contain the full 2640 * object pathname, e.g. /usr/lib/libc.so.1. We allow the object name to 2641 * take one of the following forms: 2642 * 2643 * 1. An exact match (i.e. a full pathname): "/usr/lib/libc.so.1" 2644 * 2. An exact basename match: "libc.so.1" 2645 * 3. An initial basename match up to a '.' suffix: "libc.so" or "libc" 2646 * 4. The literal string "a.out" is an alias for the executable mapping 2647 * 2648 * The third case is a convenience for callers and may not be necessary. 2649 * 2650 * As the exact same object name may be loaded on different link maps (see 2651 * dlmopen(3DL)), we also allow the caller to resolve the object name by 2652 * specifying a particular link map id. If lmid is PR_LMID_EVERY, the 2653 * first matching name will be returned, regardless of the link map id. 2654 */ 2655 static map_info_t * 2656 object_to_map(struct ps_prochandle *P, Lmid_t lmid, const char *objname) 2657 { 2658 map_info_t *mp; 2659 file_info_t *fp; 2660 size_t objlen; 2661 uint_t i; 2662 2663 /* 2664 * If we have no rtld_db, then always treat a request as one for all 2665 * link maps. 2666 */ 2667 if (P->rap == NULL) 2668 lmid = PR_LMID_EVERY; 2669 2670 /* 2671 * First pass: look for exact matches of the entire pathname or 2672 * basename (cases 1 and 2 above): 2673 */ 2674 for (i = 0, mp = P->mappings; i < P->map_count; i++, mp++) { 2675 2676 if (mp->map_pmap.pr_mapname[0] == '\0' || 2677 (fp = mp->map_file) == NULL || fp->file_lname == NULL) 2678 continue; 2679 2680 if (lmid != PR_LMID_EVERY && 2681 (fp->file_lo == NULL || lmid != fp->file_lo->rl_lmident)) 2682 continue; 2683 2684 /* 2685 * If we match, return the primary text mapping; otherwise 2686 * just return the mapping we matched. 2687 */ 2688 if (strcmp(fp->file_lname, objname) == 0 || 2689 strcmp(fp->file_lbase, objname) == 0) 2690 return (fp->file_map ? fp->file_map : mp); 2691 } 2692 2693 objlen = strlen(objname); 2694 2695 /* 2696 * Second pass: look for partial matches (case 3 above): 2697 */ 2698 for (i = 0, mp = P->mappings; i < P->map_count; i++, mp++) { 2699 2700 if (mp->map_pmap.pr_mapname[0] == '\0' || 2701 (fp = mp->map_file) == NULL || fp->file_lname == NULL) 2702 continue; 2703 2704 if (lmid != PR_LMID_EVERY && 2705 (fp->file_lo == NULL || lmid != fp->file_lo->rl_lmident)) 2706 continue; 2707 2708 /* 2709 * If we match, return the primary text mapping; otherwise 2710 * just return the mapping we matched. 2711 */ 2712 if (strncmp(fp->file_lbase, objname, objlen) == 0 && 2713 fp->file_lbase[objlen] == '.') 2714 return (fp->file_map ? fp->file_map : mp); 2715 } 2716 2717 /* 2718 * One last check: we allow "a.out" to always alias the executable, 2719 * assuming this name was not in use for something else. 2720 */ 2721 if ((lmid == PR_LMID_EVERY || lmid == LM_ID_BASE) && 2722 (strcmp(objname, "a.out") == 0)) 2723 return (P->map_exec); 2724 2725 return (NULL); 2726 } 2727 2728 static map_info_t * 2729 object_name_to_map(struct ps_prochandle *P, Lmid_t lmid, const char *name) 2730 { 2731 map_info_t *mptr; 2732 2733 if (!P->info_valid) 2734 Pupdate_maps(P); 2735 2736 if (P->map_exec == NULL && ((mptr = Paddr2mptr(P, 2737 Pgetauxval(P, AT_ENTRY))) != NULL || (mptr = exec_map(P)) != NULL)) 2738 P->map_exec = mptr; 2739 2740 if (P->map_ldso == NULL && (mptr = Paddr2mptr(P, 2741 Pgetauxval(P, AT_BASE))) != NULL) 2742 P->map_ldso = mptr; 2743 2744 if (name == PR_OBJ_EXEC) 2745 mptr = P->map_exec; 2746 else if (name == PR_OBJ_LDSO) 2747 mptr = P->map_ldso; 2748 else 2749 mptr = object_to_map(P, lmid, name); 2750 2751 return (mptr); 2752 } 2753 2754 /* 2755 * When two symbols are found by address, decide which one is to be preferred. 2756 */ 2757 static GElf_Sym * 2758 sym_prefer(GElf_Sym *sym1, char *name1, GElf_Sym *sym2, char *name2) 2759 { 2760 /* 2761 * Prefer the non-NULL symbol. 2762 */ 2763 if (sym1 == NULL) 2764 return (sym2); 2765 if (sym2 == NULL) 2766 return (sym1); 2767 2768 /* 2769 * Defer to the sort ordering... 2770 */ 2771 return (byaddr_cmp_common(sym1, name1, sym2, name2) <= 0 ? sym1 : sym2); 2772 } 2773 2774 /* 2775 * Look up a symbol by address in the specified symbol table. 2776 * Adjustment to 'addr' must already have been made for the 2777 * offset of the symbol if this is a dynamic library symbol table. 2778 */ 2779 static GElf_Sym * 2780 sym_by_addr(sym_tbl_t *symtab, GElf_Addr addr, GElf_Sym *symp, uint_t *idp) 2781 { 2782 Elf_Data *data = symtab->sym_data; 2783 GElf_Sym sym, osym; 2784 uint_t i, oid, *byaddr = symtab->sym_byaddr; 2785 int min, max, mid, omid, found = 0; 2786 2787 if (data == NULL) 2788 return (NULL); 2789 2790 min = 0; 2791 max = symtab->sym_count - 1; 2792 osym.st_value = 0; 2793 2794 /* 2795 * We can't return when we've found a match, we have to continue 2796 * searching for the closest matching symbol. 2797 */ 2798 while (min <= max) { 2799 mid = (max + min) / 2; 2800 2801 i = byaddr[mid]; 2802 (void) gelf_getsym(data, i, &sym); 2803 2804 if (addr >= sym.st_value && 2805 addr < sym.st_value + sym.st_size && 2806 (!found || sym.st_value > osym.st_value)) { 2807 osym = sym; 2808 omid = mid; 2809 oid = i; 2810 found = 1; 2811 } 2812 2813 if (addr < sym.st_value) 2814 max = mid - 1; 2815 else 2816 min = mid + 1; 2817 } 2818 2819 if (!found) 2820 return (NULL); 2821 2822 /* 2823 * There may be many symbols with identical values so we walk 2824 * backward in the byaddr table to find the best match. 2825 */ 2826 do { 2827 sym = osym; 2828 i = oid; 2829 2830 if (omid == 0) 2831 break; 2832 2833 oid = byaddr[--omid]; 2834 (void) gelf_getsym(data, oid, &osym); 2835 } while (addr >= osym.st_value && 2836 addr < sym.st_value + osym.st_size && 2837 osym.st_value == sym.st_value); 2838 2839 *symp = sym; 2840 if (idp != NULL) 2841 *idp = i; 2842 return (symp); 2843 } 2844 2845 /* 2846 * Look up a symbol by name in the specified symbol table. 2847 */ 2848 static GElf_Sym * 2849 sym_by_name(sym_tbl_t *symtab, const char *name, GElf_Sym *symp, uint_t *idp) 2850 { 2851 Elf_Data *data = symtab->sym_data; 2852 char *strs = symtab->sym_strs; 2853 uint_t i, *byname = symtab->sym_byname; 2854 int min, mid, max, cmp; 2855 2856 if (data == NULL || strs == NULL) 2857 return (NULL); 2858 2859 min = 0; 2860 max = symtab->sym_count - 1; 2861 2862 while (min <= max) { 2863 mid = (max + min) / 2; 2864 2865 i = byname[mid]; 2866 (void) gelf_getsym(data, i, symp); 2867 2868 if ((cmp = strcmp(name, strs + symp->st_name)) == 0) { 2869 if (idp != NULL) 2870 *idp = i; 2871 return (symp); 2872 } 2873 2874 if (cmp < 0) 2875 max = mid - 1; 2876 else 2877 min = mid + 1; 2878 } 2879 2880 return (NULL); 2881 } 2882 2883 /* 2884 * Search the process symbol tables looking for a symbol whose 2885 * value to value+size contain the address specified by addr. 2886 * Return values are: 2887 * sym_name_buffer containing the symbol name 2888 * GElf_Sym symbol table entry 2889 * prsyminfo_t ancillary symbol information 2890 * Returns 0 on success, -1 on failure. 2891 */ 2892 int 2893 Pxlookup_by_addr( 2894 struct ps_prochandle *P, 2895 uintptr_t addr, /* process address being sought */ 2896 char *sym_name_buffer, /* buffer for the symbol name */ 2897 size_t bufsize, /* size of sym_name_buffer */ 2898 GElf_Sym *symbolp, /* returned symbol table entry */ 2899 prsyminfo_t *sip) /* returned symbol info */ 2900 { 2901 GElf_Sym *symp; 2902 char *name; 2903 GElf_Sym sym1, *sym1p = NULL; 2904 GElf_Sym sym2, *sym2p = NULL; 2905 char *name1 = NULL; 2906 char *name2 = NULL; 2907 uint_t i1; 2908 uint_t i2; 2909 map_info_t *mptr; 2910 file_info_t *fptr; 2911 2912 (void) Prd_agent(P); 2913 2914 if ((mptr = Paddr2mptr(P, addr)) == NULL || /* no such address */ 2915 (fptr = build_map_symtab(P, mptr)) == NULL || /* no mapped file */ 2916 fptr->file_elf == NULL) /* not an ELF file */ 2917 return (-1); 2918 2919 /* 2920 * Adjust the address by the load object base address in 2921 * case the address turns out to be in a shared library. 2922 */ 2923 addr -= fptr->file_dyn_base; 2924 2925 /* 2926 * Search both symbol tables, symtab first, then dynsym. 2927 */ 2928 if ((sym1p = sym_by_addr(&fptr->file_symtab, addr, &sym1, &i1)) != NULL) 2929 name1 = fptr->file_symtab.sym_strs + sym1.st_name; 2930 if ((sym2p = sym_by_addr(&fptr->file_dynsym, addr, &sym2, &i2)) != NULL) 2931 name2 = fptr->file_dynsym.sym_strs + sym2.st_name; 2932 2933 if ((symp = sym_prefer(sym1p, name1, sym2p, name2)) == NULL) 2934 return (-1); 2935 2936 name = (symp == sym1p) ? name1 : name2; 2937 if (bufsize > 0) { 2938 (void) strncpy(sym_name_buffer, name, bufsize); 2939 sym_name_buffer[bufsize - 1] = '\0'; 2940 } 2941 2942 *symbolp = *symp; 2943 if (sip != NULL) { 2944 sip->prs_name = bufsize == 0 ? NULL : sym_name_buffer; 2945 sip->prs_object = fptr->file_lbase; 2946 sip->prs_id = (symp == sym1p) ? i1 : i2; 2947 sip->prs_table = (symp == sym1p) ? PR_SYMTAB : PR_DYNSYM; 2948 sip->prs_lmid = (fptr->file_lo == NULL) ? LM_ID_BASE : 2949 fptr->file_lo->rl_lmident; 2950 } 2951 2952 if (GELF_ST_TYPE(symbolp->st_info) != STT_TLS) 2953 symbolp->st_value += fptr->file_dyn_base; 2954 2955 return (0); 2956 } 2957 2958 int 2959 Plookup_by_addr(struct ps_prochandle *P, uintptr_t addr, char *buf, size_t size, 2960 GElf_Sym *symp) 2961 { 2962 return (Pxlookup_by_addr(P, addr, buf, size, symp, NULL)); 2963 } 2964 2965 /* 2966 * Search the process symbol tables looking for a symbol whose name matches the 2967 * specified name and whose object and link map optionally match the specified 2968 * parameters. On success, the function returns 0 and fills in the GElf_Sym 2969 * symbol table entry. On failure, -1 is returned. 2970 */ 2971 int 2972 Pxlookup_by_name( 2973 struct ps_prochandle *P, 2974 Lmid_t lmid, /* link map to match, or -1 for any */ 2975 const char *oname, /* load object name */ 2976 const char *sname, /* symbol name */ 2977 GElf_Sym *symp, /* returned symbol table entry */ 2978 prsyminfo_t *sip) /* returned symbol info */ 2979 { 2980 map_info_t *mptr; 2981 file_info_t *fptr; 2982 int cnt; 2983 2984 GElf_Sym sym; 2985 prsyminfo_t si; 2986 int rv = -1; 2987 uint_t id; 2988 2989 if (oname == PR_OBJ_EVERY) { 2990 /* create all the file_info_t's for all the mappings */ 2991 (void) Prd_agent(P); 2992 cnt = P->num_files; 2993 fptr = list_next(&P->file_head); 2994 } else { 2995 cnt = 1; 2996 if ((mptr = object_name_to_map(P, lmid, oname)) == NULL || 2997 (fptr = build_map_symtab(P, mptr)) == NULL) 2998 return (-1); 2999 } 3000 3001 /* 3002 * Iterate through the loaded object files and look for the symbol 3003 * name in the .symtab and .dynsym of each. If we encounter a match 3004 * with SHN_UNDEF, keep looking in hopes of finding a better match. 3005 * This means that a name such as "puts" will match the puts function 3006 * in libc instead of matching the puts PLT entry in the a.out file. 3007 */ 3008 for (; cnt > 0; cnt--, fptr = list_next(fptr)) { 3009 Pbuild_file_symtab(P, fptr); 3010 3011 if (fptr->file_elf == NULL) 3012 continue; 3013 3014 if (lmid != PR_LMID_EVERY && fptr->file_lo != NULL && 3015 lmid != fptr->file_lo->rl_lmident) 3016 continue; 3017 3018 if (fptr->file_symtab.sym_data != NULL && 3019 sym_by_name(&fptr->file_symtab, sname, symp, &id)) { 3020 if (sip != NULL) { 3021 sip->prs_id = id; 3022 sip->prs_table = PR_SYMTAB; 3023 sip->prs_object = oname; 3024 sip->prs_name = sname; 3025 sip->prs_lmid = fptr->file_lo == NULL ? 3026 LM_ID_BASE : fptr->file_lo->rl_lmident; 3027 } 3028 } else if (fptr->file_dynsym.sym_data != NULL && 3029 sym_by_name(&fptr->file_dynsym, sname, symp, &id)) { 3030 if (sip != NULL) { 3031 sip->prs_id = id; 3032 sip->prs_table = PR_DYNSYM; 3033 sip->prs_object = oname; 3034 sip->prs_name = sname; 3035 sip->prs_lmid = fptr->file_lo == NULL ? 3036 LM_ID_BASE : fptr->file_lo->rl_lmident; 3037 } 3038 } else { 3039 continue; 3040 } 3041 3042 if (GELF_ST_TYPE(symp->st_info) != STT_TLS) 3043 symp->st_value += fptr->file_dyn_base; 3044 3045 if (symp->st_shndx != SHN_UNDEF) 3046 return (0); 3047 3048 if (rv != 0) { 3049 if (sip != NULL) 3050 si = *sip; 3051 sym = *symp; 3052 rv = 0; 3053 } 3054 } 3055 3056 if (rv == 0) { 3057 if (sip != NULL) 3058 *sip = si; 3059 *symp = sym; 3060 } 3061 3062 return (rv); 3063 } 3064 3065 /* 3066 * Search the process symbol tables looking for a symbol whose name matches the 3067 * specified name, but without any restriction on the link map id. 3068 */ 3069 int 3070 Plookup_by_name(struct ps_prochandle *P, const char *object, 3071 const char *symbol, GElf_Sym *symp) 3072 { 3073 return (Pxlookup_by_name(P, PR_LMID_EVERY, object, symbol, symp, NULL)); 3074 } 3075 3076 /* 3077 * Iterate over the process's address space mappings. 3078 */ 3079 int 3080 Pmapping_iter(struct ps_prochandle *P, proc_map_f *func, void *cd) 3081 { 3082 map_info_t *mptr; 3083 file_info_t *fptr; 3084 char *object_name; 3085 int rc = 0; 3086 int i; 3087 3088 /* create all the file_info_t's for all the mappings */ 3089 (void) Prd_agent(P); 3090 3091 for (i = 0, mptr = P->mappings; i < P->map_count; i++, mptr++) { 3092 if ((fptr = mptr->map_file) == NULL) 3093 object_name = NULL; 3094 else 3095 object_name = fptr->file_lname; 3096 if ((rc = func(cd, &mptr->map_pmap, object_name)) != 0) 3097 return (rc); 3098 } 3099 return (0); 3100 } 3101 3102 /* 3103 * Iterate over the process's mapped objects. 3104 */ 3105 int 3106 Pobject_iter(struct ps_prochandle *P, proc_map_f *func, void *cd) 3107 { 3108 map_info_t *mptr; 3109 file_info_t *fptr; 3110 uint_t cnt; 3111 int rc = 0; 3112 3113 (void) Prd_agent(P); /* create file_info_t's for all the mappings */ 3114 Pupdate_maps(P); 3115 3116 for (cnt = P->num_files, fptr = list_next(&P->file_head); 3117 cnt; cnt--, fptr = list_next(fptr)) { 3118 3119 const char *lname = fptr->file_lname ? fptr->file_lname : ""; 3120 3121 if ((mptr = fptr->file_map) == NULL) 3122 continue; 3123 3124 if ((rc = func(cd, &mptr->map_pmap, lname)) != 0) 3125 return (rc); 3126 } 3127 return (0); 3128 } 3129 3130 /* 3131 * Given a virtual address, return the name of the underlying 3132 * mapped object (file), as provided by the dynamic linker. 3133 * Return NULL on failure (no underlying shared library). 3134 */ 3135 char * 3136 Pobjname(struct ps_prochandle *P, uintptr_t addr, 3137 char *buffer, size_t bufsize) 3138 { 3139 map_info_t *mptr; 3140 file_info_t *fptr; 3141 3142 /* create all the file_info_t's for all the mappings */ 3143 (void) Prd_agent(P); 3144 3145 if ((mptr = Paddr2mptr(P, addr)) != NULL && 3146 (fptr = mptr->map_file) != NULL && 3147 fptr->file_lname != NULL) { 3148 (void) strncpy(buffer, fptr->file_lname, bufsize); 3149 if (strlen(fptr->file_lname) >= bufsize) 3150 buffer[bufsize-1] = '\0'; 3151 return (buffer); 3152 } 3153 return (NULL); 3154 } 3155 3156 /* 3157 * Given a virtual address, return the link map id of the underlying mapped 3158 * object (file), as provided by the dynamic linker. Return -1 on failure. 3159 */ 3160 int 3161 Plmid(struct ps_prochandle *P, uintptr_t addr, Lmid_t *lmidp) 3162 { 3163 map_info_t *mptr; 3164 file_info_t *fptr; 3165 3166 /* create all the file_info_t's for all the mappings */ 3167 (void) Prd_agent(P); 3168 3169 if ((mptr = Paddr2mptr(P, addr)) != NULL && 3170 (fptr = mptr->map_file) != NULL && fptr->file_lo != NULL) { 3171 *lmidp = fptr->file_lo->rl_lmident; 3172 return (0); 3173 } 3174 3175 return (-1); 3176 } 3177 3178 /* 3179 * Given an object name and optional lmid, iterate over the object's symbols. 3180 * If which == PR_SYMTAB, search the normal symbol table. 3181 * If which == PR_DYNSYM, search the dynamic symbol table. 3182 */ 3183 static int 3184 Psymbol_iter_com(struct ps_prochandle *P, Lmid_t lmid, const char *object_name, 3185 int which, int mask, pr_order_t order, proc_xsym_f *func, void *cd) 3186 { 3187 GElf_Sym sym; 3188 GElf_Shdr shdr; 3189 map_info_t *mptr; 3190 file_info_t *fptr; 3191 sym_tbl_t *symtab; 3192 Elf_Data *data; 3193 size_t symn; 3194 const char *strs; 3195 size_t strsz; 3196 prsyminfo_t si; 3197 int rv; 3198 uint_t *map, i, count, ndx; 3199 3200 if ((mptr = object_name_to_map(P, lmid, object_name)) == NULL) 3201 return (-1); 3202 3203 if ((fptr = build_map_symtab(P, mptr)) == NULL || /* no mapped file */ 3204 fptr->file_elf == NULL) /* not an ELF file */ 3205 return (-1); 3206 3207 /* 3208 * Search the specified symbol table. 3209 */ 3210 switch (which) { 3211 case PR_SYMTAB: 3212 symtab = &fptr->file_symtab; 3213 si.prs_table = PR_SYMTAB; 3214 break; 3215 case PR_DYNSYM: 3216 symtab = &fptr->file_dynsym; 3217 si.prs_table = PR_DYNSYM; 3218 break; 3219 default: 3220 return (-1); 3221 } 3222 3223 si.prs_object = object_name; 3224 si.prs_lmid = fptr->file_lo == NULL ? 3225 LM_ID_BASE : fptr->file_lo->rl_lmident; 3226 3227 data = symtab->sym_data; 3228 symn = symtab->sym_symn; 3229 strs = symtab->sym_strs; 3230 strsz = symtab->sym_strsz; 3231 3232 if (data == NULL || strs == NULL) 3233 return (-1); 3234 3235 switch (order) { 3236 case PRO_NATURAL: 3237 map = NULL; 3238 count = symn; 3239 break; 3240 case PRO_BYNAME: 3241 map = symtab->sym_byname; 3242 count = symtab->sym_count; 3243 break; 3244 case PRO_BYADDR: 3245 map = symtab->sym_byaddr; 3246 count = symtab->sym_count; 3247 break; 3248 default: 3249 return (-1); 3250 } 3251 3252 rv = 0; 3253 3254 for (i = 0; i < count; i++) { 3255 ndx = map == NULL ? i : map[i]; 3256 if (gelf_getsym(data, ndx, &sym) != NULL) { 3257 uint_t s_bind, s_type, type; 3258 3259 if (sym.st_name >= strsz) /* invalid st_name */ 3260 continue; 3261 3262 s_bind = GELF_ST_BIND(sym.st_info); 3263 s_type = GELF_ST_TYPE(sym.st_info); 3264 3265 /* 3266 * In case you haven't already guessed, this relies on 3267 * the bitmask used in <libproc.h> for encoding symbol 3268 * type and binding matching the order of STB and STT 3269 * constants in <sys/elf.h>. ELF can't change without 3270 * breaking binary compatibility, so I think this is 3271 * reasonably fair game. 3272 */ 3273 if (s_bind < STB_NUM && s_type < STT_NUM) { 3274 type = (1 << (s_type + 8)) | (1 << s_bind); 3275 if ((type & ~mask) != 0) 3276 continue; 3277 } else 3278 continue; /* Invalid type or binding */ 3279 3280 if (GELF_ST_TYPE(sym.st_info) != STT_TLS) 3281 sym.st_value += fptr->file_dyn_base; 3282 3283 si.prs_name = strs + sym.st_name; 3284 3285 /* 3286 * If symbol's type is STT_SECTION, then try to lookup 3287 * the name of the corresponding section. 3288 */ 3289 if (GELF_ST_TYPE(sym.st_info) == STT_SECTION && 3290 fptr->file_shstrs != NULL && 3291 gelf_getshdr(elf_getscn(fptr->file_elf, 3292 sym.st_shndx), &shdr) != NULL && 3293 shdr.sh_name != 0 && 3294 shdr.sh_name < fptr->file_shstrsz) 3295 si.prs_name = fptr->file_shstrs + shdr.sh_name; 3296 3297 si.prs_id = ndx; 3298 if ((rv = func(cd, &sym, si.prs_name, &si)) != 0) 3299 break; 3300 } 3301 } 3302 3303 return (rv); 3304 } 3305 3306 int 3307 Pxsymbol_iter(struct ps_prochandle *P, Lmid_t lmid, const char *object_name, 3308 int which, int mask, proc_xsym_f *func, void *cd) 3309 { 3310 return (Psymbol_iter_com(P, lmid, object_name, which, mask, 3311 PRO_NATURAL, func, cd)); 3312 } 3313 3314 int 3315 Psymbol_iter_by_lmid(struct ps_prochandle *P, Lmid_t lmid, 3316 const char *object_name, int which, int mask, proc_sym_f *func, void *cd) 3317 { 3318 return (Psymbol_iter_com(P, lmid, object_name, which, mask, 3319 PRO_NATURAL, (proc_xsym_f *)func, cd)); 3320 } 3321 3322 int 3323 Psymbol_iter(struct ps_prochandle *P, 3324 const char *object_name, int which, int mask, proc_sym_f *func, void *cd) 3325 { 3326 return (Psymbol_iter_com(P, PR_LMID_EVERY, object_name, which, mask, 3327 PRO_NATURAL, (proc_xsym_f *)func, cd)); 3328 } 3329 3330 int 3331 Psymbol_iter_by_addr(struct ps_prochandle *P, 3332 const char *object_name, int which, int mask, proc_sym_f *func, void *cd) 3333 { 3334 return (Psymbol_iter_com(P, PR_LMID_EVERY, object_name, which, mask, 3335 PRO_BYADDR, (proc_xsym_f *)func, cd)); 3336 } 3337 3338 int 3339 Psymbol_iter_by_name(struct ps_prochandle *P, 3340 const char *object_name, int which, int mask, proc_sym_f *func, void *cd) 3341 { 3342 return (Psymbol_iter_com(P, PR_LMID_EVERY, object_name, which, mask, 3343 PRO_BYNAME, (proc_xsym_f *)func, cd)); 3344 } 3345 3346 /* 3347 * Get the platform string from the core file if we have it; 3348 * just perform the system call for the caller if this is a live process. 3349 */ 3350 char * 3351 Pplatform(struct ps_prochandle *P, char *s, size_t n) 3352 { 3353 if (P->state == PS_IDLE) { 3354 errno = ENODATA; 3355 return (NULL); 3356 } 3357 3358 if (P->state == PS_DEAD) { 3359 if (P->core->core_platform == NULL) { 3360 errno = ENODATA; 3361 return (NULL); 3362 } 3363 (void) strncpy(s, P->core->core_platform, n - 1); 3364 s[n - 1] = '\0'; 3365 3366 } else if (sysinfo(SI_PLATFORM, s, n) == -1) 3367 return (NULL); 3368 3369 return (s); 3370 } 3371 3372 /* 3373 * Get the uname(2) information from the core file if we have it; 3374 * just perform the system call for the caller if this is a live process. 3375 */ 3376 int 3377 Puname(struct ps_prochandle *P, struct utsname *u) 3378 { 3379 if (P->state == PS_IDLE) { 3380 errno = ENODATA; 3381 return (-1); 3382 } 3383 3384 if (P->state == PS_DEAD) { 3385 if (P->core->core_uts == NULL) { 3386 errno = ENODATA; 3387 return (-1); 3388 } 3389 (void) memcpy(u, P->core->core_uts, sizeof (struct utsname)); 3390 return (0); 3391 } 3392 return (uname(u)); 3393 } 3394 3395 /* 3396 * Get the zone name from the core file if we have it; look up the 3397 * name based on the zone id if this is a live process. 3398 */ 3399 char * 3400 Pzonename(struct ps_prochandle *P, char *s, size_t n) 3401 { 3402 if (P->state == PS_IDLE) { 3403 errno = ENODATA; 3404 return (NULL); 3405 } 3406 3407 if (P->state == PS_DEAD) { 3408 if (P->core->core_zonename == NULL) { 3409 errno = ENODATA; 3410 return (NULL); 3411 } 3412 (void) strlcpy(s, P->core->core_zonename, n); 3413 } else { 3414 if (getzonenamebyid(P->status.pr_zoneid, s, n) < 0) 3415 return (NULL); 3416 s[n - 1] = '\0'; 3417 } 3418 return (s); 3419 } 3420 3421 /* 3422 * Called from Pcreate(), Pgrab(), and Pfgrab_core() to initialize 3423 * the symbol table heads in the new ps_prochandle. 3424 */ 3425 void 3426 Pinitsym(struct ps_prochandle *P) 3427 { 3428 P->num_files = 0; 3429 list_link(&P->file_head, NULL); 3430 } 3431 3432 /* 3433 * Called from Prelease() to destroy the symbol tables. 3434 * Must be called by the client after an exec() in the victim process. 3435 */ 3436 void 3437 Preset_maps(struct ps_prochandle *P) 3438 { 3439 int i; 3440 3441 if (P->rap != NULL) { 3442 rd_delete(P->rap); 3443 P->rap = NULL; 3444 } 3445 3446 if (P->execname != NULL) { 3447 free(P->execname); 3448 P->execname = NULL; 3449 } 3450 3451 if (P->auxv != NULL) { 3452 free(P->auxv); 3453 P->auxv = NULL; 3454 P->nauxv = 0; 3455 } 3456 3457 for (i = 0; i < P->map_count; i++) 3458 map_info_free(P, &P->mappings[i]); 3459 3460 if (P->mappings != NULL) { 3461 free(P->mappings); 3462 P->mappings = NULL; 3463 } 3464 P->map_count = P->map_alloc = 0; 3465 3466 P->info_valid = 0; 3467 } 3468 3469 typedef struct getenv_data { 3470 char *buf; 3471 size_t bufsize; 3472 const char *search; 3473 size_t searchlen; 3474 } getenv_data_t; 3475 3476 /*ARGSUSED*/ 3477 static int 3478 getenv_func(void *data, struct ps_prochandle *P, uintptr_t addr, 3479 const char *nameval) 3480 { 3481 getenv_data_t *d = data; 3482 size_t len; 3483 3484 if (nameval == NULL) 3485 return (0); 3486 3487 if (d->searchlen < strlen(nameval) && 3488 strncmp(nameval, d->search, d->searchlen) == 0 && 3489 nameval[d->searchlen] == '=') { 3490 len = MIN(strlen(nameval), d->bufsize - 1); 3491 (void) strncpy(d->buf, nameval, len); 3492 d->buf[len] = '\0'; 3493 return (1); 3494 } 3495 3496 return (0); 3497 } 3498 3499 char * 3500 Pgetenv(struct ps_prochandle *P, const char *name, char *buf, size_t buflen) 3501 { 3502 getenv_data_t d; 3503 3504 d.buf = buf; 3505 d.bufsize = buflen; 3506 d.search = name; 3507 d.searchlen = strlen(name); 3508 3509 if (Penv_iter(P, getenv_func, &d) == 1) { 3510 char *equals = strchr(d.buf, '='); 3511 3512 if (equals != NULL) { 3513 (void) memmove(d.buf, equals + 1, 3514 d.buf + buflen - equals - 1); 3515 d.buf[d.buf + buflen - equals] = '\0'; 3516 3517 return (buf); 3518 } 3519 } 3520 3521 return (NULL); 3522 } 3523 3524 /* number of argument or environment pointers to read all at once */ 3525 #define NARG 100 3526 3527 int 3528 Penv_iter(struct ps_prochandle *P, proc_env_f *func, void *data) 3529 { 3530 const psinfo_t *psp; 3531 uintptr_t envpoff; 3532 GElf_Sym sym; 3533 int ret; 3534 char *buf, *nameval; 3535 size_t buflen; 3536 3537 int nenv = NARG; 3538 long envp[NARG]; 3539 3540 /* 3541 * Attempt to find the "_environ" variable in the process. 3542 * Failing that, use the original value provided by Ppsinfo(). 3543 */ 3544 if ((psp = Ppsinfo(P)) == NULL) 3545 return (-1); 3546 3547 envpoff = psp->pr_envp; /* Default if no _environ found */ 3548 3549 if (Plookup_by_name(P, PR_OBJ_EXEC, "_environ", &sym) == 0) { 3550 if (P->status.pr_dmodel == PR_MODEL_NATIVE) { 3551 if (Pread(P, &envpoff, sizeof (envpoff), 3552 sym.st_value) != sizeof (envpoff)) 3553 envpoff = psp->pr_envp; 3554 } else if (P->status.pr_dmodel == PR_MODEL_ILP32) { 3555 uint32_t envpoff32; 3556 3557 if (Pread(P, &envpoff32, sizeof (envpoff32), 3558 sym.st_value) != sizeof (envpoff32)) 3559 envpoff = psp->pr_envp; 3560 else 3561 envpoff = envpoff32; 3562 } 3563 } 3564 3565 buflen = 128; 3566 buf = malloc(buflen); 3567 3568 ret = 0; 3569 for (;;) { 3570 uintptr_t envoff; 3571 3572 if (nenv == NARG) { 3573 (void) memset(envp, 0, sizeof (envp)); 3574 if (P->status.pr_dmodel == PR_MODEL_NATIVE) { 3575 if (Pread(P, envp, 3576 sizeof (envp), envpoff) <= 0) { 3577 ret = -1; 3578 break; 3579 } 3580 } else if (P->status.pr_dmodel == PR_MODEL_ILP32) { 3581 uint32_t e32[NARG]; 3582 int i; 3583 3584 (void) memset(e32, 0, sizeof (e32)); 3585 if (Pread(P, e32, sizeof (e32), envpoff) <= 0) { 3586 ret = -1; 3587 break; 3588 } 3589 for (i = 0; i < NARG; i++) 3590 envp[i] = e32[i]; 3591 } 3592 nenv = 0; 3593 } 3594 3595 if ((envoff = envp[nenv++]) == NULL) 3596 break; 3597 3598 /* 3599 * Attempt to read the string from the process. 3600 */ 3601 again: 3602 ret = Pread_string(P, buf, buflen, envoff); 3603 3604 if (ret <= 0) { 3605 nameval = NULL; 3606 } else if (ret == buflen - 1) { 3607 free(buf); 3608 /* 3609 * Bail if we have a corrupted environment 3610 */ 3611 if (buflen >= ARG_MAX) 3612 return (-1); 3613 buflen *= 2; 3614 buf = malloc(buflen); 3615 goto again; 3616 } else { 3617 nameval = buf; 3618 } 3619 3620 if ((ret = func(data, P, envoff, nameval)) != 0) 3621 break; 3622 3623 envpoff += (P->status.pr_dmodel == PR_MODEL_LP64)? 8 : 4; 3624 } 3625 3626 free(buf); 3627 3628 return (ret); 3629 } 3630