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 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 #include <sys/stack.h> 29 #include <sys/regset.h> 30 #include <sys/frame.h> 31 #include <sys/sysmacros.h> 32 #include <sys/trap.h> 33 34 #include <stdlib.h> 35 #include <unistd.h> 36 #include <sys/types.h> 37 #include <errno.h> 38 #include <string.h> 39 40 #include "Pcontrol.h" 41 #include "Pstack.h" 42 43 #define M_PLT_NRSV 1 /* reserved PLT entries */ 44 #define M_PLT_ENTSIZE 16 /* size of each PLT entry */ 45 46 static uchar_t int_syscall_instr[] = { 0xCD, T_SYSCALLINT }; 47 static uchar_t syscall_instr[] = { 0x0f, 0x05 }; 48 49 const char * 50 Ppltdest(struct ps_prochandle *P, uintptr_t pltaddr) 51 { 52 map_info_t *mp = Paddr2mptr(P, pltaddr); 53 file_info_t *fp; 54 size_t i; 55 uintptr_t r_addr; 56 57 if (mp == NULL || (fp = mp->map_file) == NULL || 58 fp->file_plt_base == 0 || 59 pltaddr - fp->file_plt_base >= fp->file_plt_size) { 60 errno = EINVAL; 61 return (NULL); 62 } 63 64 i = (pltaddr - fp->file_plt_base) / M_PLT_ENTSIZE - M_PLT_NRSV; 65 66 if (P->status.pr_dmodel == PR_MODEL_LP64) { 67 Elf64_Rela r; 68 69 r_addr = fp->file_jmp_rel + i * sizeof (r); 70 71 if (Pread(P, &r, sizeof (r), r_addr) == sizeof (r) && 72 (i = ELF64_R_SYM(r.r_info)) < fp->file_dynsym.sym_symn) { 73 Elf_Data *data = fp->file_dynsym.sym_data_pri; 74 Elf64_Sym *symp = &(((Elf64_Sym *)data->d_buf)[i]); 75 76 return (fp->file_dynsym.sym_strs + symp->st_name); 77 } 78 } else { 79 Elf32_Rel r; 80 81 r_addr = fp->file_jmp_rel + i * sizeof (r); 82 83 if (Pread(P, &r, sizeof (r), r_addr) == sizeof (r) && 84 (i = ELF32_R_SYM(r.r_info)) < fp->file_dynsym.sym_symn) { 85 Elf_Data *data = fp->file_dynsym.sym_data_pri; 86 Elf32_Sym *symp = &(((Elf32_Sym *)data->d_buf)[i]); 87 88 return (fp->file_dynsym.sym_strs + symp->st_name); 89 } 90 } 91 92 return (NULL); 93 } 94 95 int 96 Pissyscall(struct ps_prochandle *P, uintptr_t addr) 97 { 98 uchar_t instr[16]; 99 100 if (P->status.pr_dmodel == PR_MODEL_LP64) { 101 if (Pread(P, instr, sizeof (syscall_instr), addr) != 102 sizeof (syscall_instr) || 103 memcmp(instr, syscall_instr, sizeof (syscall_instr)) != 0) 104 return (0); 105 else 106 return (1); 107 } 108 109 if (Pread(P, instr, sizeof (int_syscall_instr), addr) != 110 sizeof (int_syscall_instr)) 111 return (0); 112 113 if (memcmp(instr, int_syscall_instr, sizeof (int_syscall_instr)) == 0) 114 return (1); 115 116 return (0); 117 } 118 119 int 120 Pissyscall_prev(struct ps_prochandle *P, uintptr_t addr, uintptr_t *dst) 121 { 122 int ret; 123 124 if (P->status.pr_dmodel == PR_MODEL_LP64) { 125 if (Pissyscall(P, addr - sizeof (syscall_instr))) { 126 if (dst) 127 *dst = addr - sizeof (syscall_instr); 128 return (1); 129 } 130 return (0); 131 } 132 133 if ((ret = Pissyscall(P, addr - sizeof (int_syscall_instr))) != 0) { 134 if (dst) 135 *dst = addr - sizeof (int_syscall_instr); 136 return (ret); 137 } 138 139 return (0); 140 } 141 142 int 143 Pissyscall_text(struct ps_prochandle *P, const void *buf, size_t buflen) 144 { 145 if (P->status.pr_dmodel == PR_MODEL_LP64) { 146 if (buflen >= sizeof (syscall_instr) && 147 memcmp(buf, syscall_instr, sizeof (syscall_instr)) == 0) 148 return (1); 149 else 150 return (0); 151 } 152 153 if (buflen < sizeof (int_syscall_instr)) 154 return (0); 155 156 if (memcmp(buf, int_syscall_instr, sizeof (int_syscall_instr)) == 0) 157 return (1); 158 159 return (0); 160 } 161 162 #define TR_ARG_MAX 6 /* Max args to print, same as SPARC */ 163 164 /* 165 * Given a return address, determine the likely number of arguments 166 * that were pushed on the stack prior to its execution. We do this by 167 * expecting that a typical call sequence consists of pushing arguments on 168 * the stack, executing a call instruction, and then performing an add 169 * on %esp to restore it to the value prior to pushing the arguments for 170 * the call. We attempt to detect such an add, and divide the addend 171 * by the size of a word to determine the number of pushed arguments. 172 * 173 * If we do not find such an add, this does not necessarily imply that the 174 * function took no arguments. It is not possible to reliably detect such a 175 * void function because hand-coded assembler does not always perform an add 176 * to %esp immediately after the "call" instruction (eg. _sys_call()). 177 * Because of this, we default to returning MIN(sz, TR_ARG_MAX) instead of 0 178 * in the absence of an add to %esp. 179 */ 180 static ulong_t 181 argcount(struct ps_prochandle *P, uint32_t pc, ssize_t sz) 182 { 183 uchar_t instr[6]; 184 ulong_t count, max; 185 186 max = MIN(sz / sizeof (uint32_t), TR_ARG_MAX); 187 188 /* 189 * Read the instruction at the return location. 190 */ 191 if (Pread(P, instr, sizeof (instr), (uintptr_t)pc) != sizeof (instr)) 192 return (max); 193 194 if (instr[1] != 0xc4) 195 return (max); 196 197 switch (instr[0]) { 198 case 0x81: /* count is a longword */ 199 count = instr[2]+(instr[3]<<8)+(instr[4]<<16)+(instr[5]<<24); 200 break; 201 case 0x83: /* count is a byte */ 202 count = instr[2]; 203 break; 204 default: 205 return (max); 206 } 207 208 count /= sizeof (uint32_t); 209 return (MIN(count, max)); 210 } 211 212 static void 213 ucontext_32_to_prgregs(const ucontext32_t *uc, prgregset_t dst) 214 { 215 const greg32_t *src = &uc->uc_mcontext.gregs[0]; 216 217 dst[REG_DS] = (uint16_t)src[DS]; 218 dst[REG_ES] = (uint16_t)src[ES]; 219 220 dst[REG_GS] = (uint16_t)src[GS]; 221 dst[REG_FS] = (uint16_t)src[FS]; 222 dst[REG_SS] = (uint16_t)src[SS]; 223 dst[REG_RSP] = (uint32_t)src[UESP]; 224 dst[REG_RFL] = src[EFL]; 225 dst[REG_CS] = (uint16_t)src[CS]; 226 dst[REG_RIP] = (uint32_t)src[EIP]; 227 dst[REG_ERR] = (uint32_t)src[ERR]; 228 dst[REG_TRAPNO] = (uint32_t)src[TRAPNO]; 229 dst[REG_RAX] = (uint32_t)src[EAX]; 230 dst[REG_RCX] = (uint32_t)src[ECX]; 231 dst[REG_RDX] = (uint32_t)src[EDX]; 232 dst[REG_RBX] = (uint32_t)src[EBX]; 233 dst[REG_RBP] = (uint32_t)src[EBP]; 234 dst[REG_RSI] = (uint32_t)src[ESI]; 235 dst[REG_RDI] = (uint32_t)src[EDI]; 236 } 237 238 static int 239 Pstack_iter32(struct ps_prochandle *P, const prgregset_t regs, 240 proc_stack_f *func, void *arg) 241 { 242 prgreg_t *prevfp = NULL; 243 uint_t pfpsize = 0; 244 int nfp = 0; 245 struct { 246 prgreg32_t fp; 247 prgreg32_t pc; 248 prgreg32_t args[32]; 249 } frame; 250 uint_t argc; 251 ssize_t sz; 252 prgregset_t gregs; 253 uint32_t fp, pfp, pc; 254 long args[32]; 255 int rv; 256 int i; 257 258 /* 259 * Type definition for a structure corresponding to an IA32 260 * signal frame. Refer to the comments in Pstack.c for more info 261 */ 262 typedef struct { 263 prgreg32_t fp; 264 prgreg32_t pc; 265 int signo; 266 caddr32_t ucp; 267 caddr32_t sip; 268 } sf_t; 269 270 uclist_t ucl; 271 ucontext32_t uc; 272 uintptr_t uc_addr; 273 274 init_uclist(&ucl, P); 275 (void) memcpy(gregs, regs, sizeof (gregs)); 276 277 fp = regs[R_FP]; 278 pc = regs[R_PC]; 279 280 while (fp != 0 || pc != 0) { 281 if (stack_loop(fp, &prevfp, &nfp, &pfpsize)) 282 break; 283 284 if (fp != 0 && 285 (sz = Pread(P, &frame, sizeof (frame), (uintptr_t)fp) 286 >= (ssize_t)(2* sizeof (uint32_t)))) { 287 /* 288 * One more trick for signal frames: the kernel sets 289 * the return pc of the signal frame to 0xffffffff on 290 * Intel IA32, so argcount won't work. 291 */ 292 if (frame.pc != -1L) { 293 sz -= 2* sizeof (uint32_t); 294 argc = argcount(P, (uint32_t)frame.pc, sz); 295 } else 296 argc = 3; /* sighandler(signo, sip, ucp) */ 297 } else { 298 (void) memset(&frame, 0, sizeof (frame)); 299 argc = 0; 300 } 301 302 gregs[R_FP] = fp; 303 gregs[R_PC] = pc; 304 305 for (i = 0; i < argc; i++) 306 args[i] = (uint32_t)frame.args[i]; 307 308 if ((rv = func(arg, gregs, argc, args)) != 0) 309 break; 310 311 /* 312 * In order to allow iteration over java frames (which can have 313 * their own frame pointers), we allow the iterator to change 314 * the contents of gregs. If we detect a change, then we assume 315 * that the new values point to the next frame. 316 */ 317 if (gregs[R_FP] != fp || gregs[R_PC] != pc) { 318 fp = gregs[R_FP]; 319 pc = gregs[R_PC]; 320 continue; 321 } 322 323 pfp = fp; 324 fp = frame.fp; 325 pc = frame.pc; 326 327 if (find_uclink(&ucl, pfp + sizeof (sf_t))) 328 uc_addr = pfp + sizeof (sf_t); 329 else 330 uc_addr = NULL; 331 332 if (uc_addr != NULL && 333 Pread(P, &uc, sizeof (uc), uc_addr) == sizeof (uc)) { 334 ucontext_32_to_prgregs(&uc, gregs); 335 fp = gregs[R_FP]; 336 pc = gregs[R_PC]; 337 } 338 } 339 340 if (prevfp) 341 free(prevfp); 342 343 free_uclist(&ucl); 344 return (rv); 345 } 346 347 static void 348 ucontext_n_to_prgregs(const ucontext_t *src, prgregset_t dst) 349 { 350 (void) memcpy(dst, src->uc_mcontext.gregs, sizeof (gregset_t)); 351 } 352 353 354 int 355 Pstack_iter(struct ps_prochandle *P, const prgregset_t regs, 356 proc_stack_f *func, void *arg) 357 { 358 struct { 359 uintptr_t fp; 360 uintptr_t pc; 361 } frame; 362 363 uint_t pfpsize = 0; 364 prgreg_t *prevfp = NULL; 365 prgreg_t fp, pfp; 366 prgreg_t pc; 367 368 prgregset_t gregs; 369 int nfp = 0; 370 371 uclist_t ucl; 372 int rv = 0; 373 int argc; 374 375 uintptr_t uc_addr; 376 ucontext_t uc; 377 378 /* 379 * Type definition for a structure corresponding to an IA32 380 * signal frame. Refer to the comments in Pstack.c for more info 381 */ 382 typedef struct { 383 prgreg_t fp; 384 prgreg_t pc; 385 prgreg_t signo; 386 siginfo_t *sip; 387 } sigframe_t; 388 prgreg_t args[32]; 389 390 if (P->status.pr_dmodel != PR_MODEL_LP64) 391 return (Pstack_iter32(P, regs, func, arg)); 392 393 init_uclist(&ucl, P); 394 (void) memcpy(gregs, regs, sizeof (gregs)); 395 396 fp = gregs[R_FP]; 397 pc = gregs[R_PC]; 398 399 while (fp != 0 || pc != 0) { 400 401 if (stack_loop(fp, &prevfp, &nfp, &pfpsize)) 402 break; 403 404 if (fp != 0 && 405 Pread(P, &frame, sizeof (frame), (uintptr_t)fp) == 406 sizeof (frame)) { 407 408 if (frame.pc != -1) { 409 /* 410 * Function arguments are not available on 411 * amd64 without extensive DWARF processing. 412 */ 413 argc = 0; 414 } else { 415 argc = 3; 416 args[2] = fp + sizeof (sigframe_t); 417 if (Pread(P, &args, 2 * sizeof (prgreg_t), 418 fp + 2 * sizeof (prgreg_t)) != 419 2 * sizeof (prgreg_t)) 420 argc = 0; 421 } 422 } else { 423 (void) memset(&frame, 0, sizeof (frame)); 424 argc = 0; 425 } 426 427 gregs[R_FP] = fp; 428 gregs[R_PC] = pc; 429 430 if ((rv = func(arg, gregs, argc, args)) != 0) 431 break; 432 433 pfp = fp; 434 fp = frame.fp; 435 pc = frame.pc; 436 437 if (pc == -1 && find_uclink(&ucl, pfp + sizeof (sigframe_t))) { 438 uc_addr = pfp + sizeof (sigframe_t); 439 440 if (Pread(P, &uc, sizeof (uc), uc_addr) 441 == sizeof (uc)) { 442 ucontext_n_to_prgregs(&uc, gregs); 443 fp = gregs[R_FP]; 444 pc = gregs[R_PC]; 445 } 446 } 447 } 448 449 if (prevfp) 450 free(prevfp); 451 452 free_uclist(&ucl); 453 454 return (rv); 455 } 456 457 uintptr_t 458 Psyscall_setup(struct ps_prochandle *P, int nargs, int sysindex, uintptr_t sp) 459 { 460 if (P->status.pr_dmodel == PR_MODEL_ILP32) { 461 sp -= sizeof (int) * (nargs+2); 462 463 P->status.pr_lwp.pr_reg[REG_RAX] = sysindex; 464 P->status.pr_lwp.pr_reg[REG_RSP] = sp; 465 P->status.pr_lwp.pr_reg[REG_RIP] = P->sysaddr; 466 } else { 467 int pusharg = (nargs > 6) ? nargs - 6: 0; 468 469 sp -= sizeof (int64_t) * (pusharg+2); 470 471 P->status.pr_lwp.pr_reg[REG_RAX] = sysindex; 472 P->status.pr_lwp.pr_reg[REG_RSP] = sp; 473 P->status.pr_lwp.pr_reg[REG_RIP] = P->sysaddr; 474 } 475 476 return (sp); 477 } 478 479 int 480 Psyscall_copyinargs(struct ps_prochandle *P, int nargs, argdes_t *argp, 481 uintptr_t ap) 482 { 483 if (P->status.pr_dmodel == PR_MODEL_ILP32) { 484 int32_t arglist[MAXARGS+2]; 485 int i; 486 argdes_t *adp; 487 488 for (i = 0, adp = argp; i < nargs; i++, adp++) 489 arglist[1 + i] = (int32_t)adp->arg_value; 490 491 arglist[0] = P->status.pr_lwp.pr_reg[REG_RIP]; 492 if (Pwrite(P, &arglist[0], sizeof (int) * (nargs+1), 493 (uintptr_t)ap) != sizeof (int) * (nargs+1)) 494 return (-1); 495 } else { 496 int64_t arglist[MAXARGS+2]; 497 int i; 498 argdes_t *adp; 499 int pusharg = (nargs > 6) ? nargs - 6: 0; 500 501 for (i = 0, adp = argp; i < nargs; i++, adp++) { 502 switch (i) { 503 case 0: 504 (void) Pputareg(P, REG_RDI, adp->arg_value); 505 break; 506 case 1: 507 (void) Pputareg(P, REG_RSI, adp->arg_value); 508 break; 509 case 2: 510 (void) Pputareg(P, REG_RDX, adp->arg_value); 511 break; 512 case 3: 513 (void) Pputareg(P, REG_RCX, adp->arg_value); 514 break; 515 case 4: 516 (void) Pputareg(P, REG_R8, adp->arg_value); 517 break; 518 case 5: 519 (void) Pputareg(P, REG_R9, adp->arg_value); 520 break; 521 default: 522 arglist[i - 5] = (uint64_t)adp->arg_value; 523 break; 524 } 525 } 526 527 arglist[0] = P->status.pr_lwp.pr_reg[REG_RIP]; 528 529 if (Pwrite(P, &arglist[0], 530 sizeof (int64_t) * (pusharg + 1), ap) != 531 sizeof (int64_t) * (pusharg + 1)) 532 return (-1); 533 } 534 535 return (0); 536 } 537 538 int 539 Psyscall_copyoutargs(struct ps_prochandle *P, int nargs, argdes_t *argp, 540 uintptr_t ap) 541 { 542 if (P->status.pr_dmodel == PR_MODEL_ILP32) { 543 uint32_t arglist[MAXARGS + 2]; 544 int i; 545 argdes_t *adp; 546 547 if (Pread(P, &arglist[0], sizeof (int) * (nargs+1), 548 (uintptr_t)ap) != sizeof (int) * (nargs+1)) 549 return (-1); 550 551 for (i = 0, adp = argp; i < nargs; i++, adp++) 552 adp->arg_value = arglist[i]; 553 } else { 554 int pusharg = (nargs > 6) ? nargs - 6: 0; 555 int64_t arglist[MAXARGS+2]; 556 int i; 557 argdes_t *adp; 558 559 if (pusharg > 0 && 560 Pread(P, &arglist[0], sizeof (int64_t) * (pusharg + 1), 561 ap) != sizeof (int64_t) * (pusharg + 1)) 562 return (-1); 563 564 for (i = 0, adp = argp; i < nargs; i++, adp++) { 565 switch (i) { 566 case 0: 567 adp->arg_value = 568 P->status.pr_lwp.pr_reg[REG_RDI]; 569 break; 570 case 1: 571 adp->arg_value = 572 P->status.pr_lwp.pr_reg[REG_RSI]; 573 break; 574 case 2: 575 adp->arg_value = 576 P->status.pr_lwp.pr_reg[REG_RDX]; 577 break; 578 case 3: 579 adp->arg_value = 580 P->status.pr_lwp.pr_reg[REG_RCX]; 581 break; 582 case 4: 583 adp->arg_value = 584 P->status.pr_lwp.pr_reg[REG_R8]; 585 break; 586 case 5: 587 adp->arg_value = 588 P->status.pr_lwp.pr_reg[REG_R9]; 589 break; 590 default: 591 adp->arg_value = arglist[i - 6]; 592 break; 593 } 594 } 595 596 return (0); 597 } 598 599 return (0); 600 } 601