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