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.
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.
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]
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #include <sys/stack.h>
27 #include <sys/regset.h>
28 #include <sys/frame.h>
29 #include <sys/sysmacros.h>
31 #include <sys/machelf.h>
35 #include <sys/types.h>
42 static uchar_t int_syscall_instr
[] = { 0xCD, T_SYSCALLINT
};
45 Ppltdest(struct ps_prochandle
*P
, uintptr_t pltaddr
)
47 map_info_t
*mp
= Paddr2mptr(P
, pltaddr
);
54 if (mp
== NULL
|| (fp
= mp
->map_file
) == NULL
||
55 fp
->file_plt_base
== 0 ||
56 pltaddr
- fp
->file_plt_base
>= fp
->file_plt_size
) {
61 i
= (pltaddr
- fp
->file_plt_base
) / M_PLT_ENTSIZE
- M_PLT_XNumber
;
63 r_addr
= fp
->file_jmp_rel
+ i
* sizeof (r
);
65 if (Pread(P
, &r
, sizeof (r
), r_addr
) == sizeof (r
) &&
66 (i
= ELF32_R_SYM(r
.r_info
)) < fp
->file_dynsym
.sym_symn
) {
68 Elf_Data
*data
= fp
->file_dynsym
.sym_data_pri
;
69 Elf32_Sym
*symp
= &(((Elf32_Sym
*)data
->d_buf
)[i
]);
71 return (fp
->file_dynsym
.sym_strs
+ symp
->st_name
);
78 Pissyscall(struct ps_prochandle
*P
, uintptr_t addr
)
82 if (Pread(P
, instr
, sizeof (int_syscall_instr
), addr
) !=
83 sizeof (int_syscall_instr
))
86 if (memcmp(instr
, int_syscall_instr
, sizeof (int_syscall_instr
)) == 0)
93 Pissyscall_prev(struct ps_prochandle
*P
, uintptr_t addr
, uintptr_t *dst
)
97 if (ret
= Pissyscall(P
, addr
- sizeof (int_syscall_instr
))) {
99 *dst
= addr
- sizeof (int_syscall_instr
);
108 Pissyscall_text(struct ps_prochandle
*P
, const void *buf
, size_t buflen
)
110 if (buflen
< sizeof (int_syscall_instr
))
113 if (memcmp(buf
, int_syscall_instr
, sizeof (int_syscall_instr
)) == 0)
119 #define TR_ARG_MAX 6 /* Max args to print, same as SPARC */
122 * Given a return address, determine the likely number of arguments
123 * that were pushed on the stack prior to its execution. We do this by
124 * expecting that a typical call sequence consists of pushing arguments on
125 * the stack, executing a call instruction, and then performing an add
126 * on %esp to restore it to the value prior to pushing the arguments for
127 * the call. We attempt to detect such an add, and divide the addend
128 * by the size of a word to determine the number of pushed arguments.
130 * If we do not find such an add, this does not necessarily imply that the
131 * function took no arguments. It is not possible to reliably detect such a
132 * void function because hand-coded assembler does not always perform an add
133 * to %esp immediately after the "call" instruction (eg. _sys_call()).
134 * Because of this, we default to returning MIN(sz, TR_ARG_MAX) instead of 0
135 * in the absence of an add to %esp.
138 argcount(struct ps_prochandle
*P
, long pc
, ssize_t sz
)
143 max
= MIN(sz
/ sizeof (long), TR_ARG_MAX
);
146 * Read the instruction at the return location.
148 if (Pread(P
, instr
, sizeof (instr
), pc
) != sizeof (instr
) ||
153 case 0x81: /* count is a longword */
154 count
= instr
[2]+(instr
[3]<<8)+(instr
[4]<<16)+(instr
[5]<<24);
156 case 0x83: /* count is a byte */
163 count
/= sizeof (long);
164 return (MIN(count
, max
));
168 ucontext_n_to_prgregs(const ucontext_t
*src
, prgregset_t dst
)
170 (void) memcpy(dst
, src
->uc_mcontext
.gregs
, sizeof (gregset_t
));
174 Pstack_iter(struct ps_prochandle
*P
, const prgregset_t regs
,
175 proc_stack_f
*func
, void *arg
)
177 prgreg_t
*prevfp
= NULL
;
193 * Type definition for a structure corresponding to an IA32
194 * signal frame. Refer to the comments in Pstack.c for more info
208 init_uclist(&ucl
, P
);
209 (void) memcpy(gregs
, regs
, sizeof (gregs
));
214 while (fp
!= 0 || pc
!= 0) {
215 if (stack_loop(fp
, &prevfp
, &nfp
, &pfpsize
))
219 (sz
= Pread(P
, &frame
, sizeof (frame
), (uintptr_t)fp
)
220 >= (ssize_t
)(2* sizeof (long)))) {
222 * One more trick for signal frames: the kernel sets
223 * the return pc of the signal frame to 0xffffffff on
224 * Intel IA32, so argcount won't work.
226 if (frame
.pc
!= -1L) {
227 sz
-= 2* sizeof (long);
228 argc
= argcount(P
, (long)frame
.pc
, sz
);
230 argc
= 3; /* sighandler(signo, sip, ucp) */
232 (void) memset(&frame
, 0, sizeof (frame
));
239 if ((rv
= func(arg
, gregs
, argc
, frame
.args
)) != 0)
243 * In order to allow iteration over java frames (which can have
244 * their own frame pointers), we allow the iterator to change
245 * the contents of gregs. If we detect a change, then we assume
246 * that the new values point to the next frame.
248 if (gregs
[R_FP
] != fp
|| gregs
[R_PC
] != pc
) {
258 if (find_uclink(&ucl
, pfp
+ sizeof (sf_t
)))
259 uc_addr
= pfp
+ sizeof (sf_t
);
261 uc_addr
= (uintptr_t)NULL
;
263 if (uc_addr
!= (uintptr_t)NULL
&&
264 Pread(P
, &uc
, sizeof (uc
), uc_addr
) == sizeof (uc
)) {
266 ucontext_n_to_prgregs(&uc
, gregs
);
279 Psyscall_setup(struct ps_prochandle
*P
, int nargs
, int sysindex
, uintptr_t sp
)
281 sp
-= sizeof (int) * (nargs
+2); /* space for arg list + CALL parms */
283 P
->status
.pr_lwp
.pr_reg
[EAX
] = sysindex
;
284 P
->status
.pr_lwp
.pr_reg
[R_SP
] = sp
;
285 P
->status
.pr_lwp
.pr_reg
[R_PC
] = P
->sysaddr
;
291 Psyscall_copyinargs(struct ps_prochandle
*P
, int nargs
, argdes_t
*argp
,
294 int32_t arglist
[MAXARGS
+2];
298 for (i
= 0, adp
= argp
; i
< nargs
; i
++, adp
++)
299 arglist
[1 + i
] = (int32_t)adp
->arg_value
;
301 arglist
[0] = P
->status
.pr_lwp
.pr_reg
[R_PC
];
302 if (Pwrite(P
, &arglist
[0], sizeof (int) * (nargs
+1),
303 (uintptr_t)ap
) != sizeof (int) * (nargs
+1))
310 Psyscall_copyoutargs(struct ps_prochandle
*P
, int nargs
, argdes_t
*argp
,
313 uint32_t arglist
[MAXARGS
+ 2];
317 if (Pread(P
, &arglist
[0], sizeof (int) * (nargs
+1), (uintptr_t)ap
)
318 != sizeof (int) * (nargs
+1))
321 for (i
= 0, adp
= argp
; i
< nargs
; i
++, adp
++)
322 adp
->arg_value
= arglist
[i
];