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