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