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