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 * Copyright 2018, Joyent, Inc.
25 */
26
27 #include <sys/stack.h>
28 #include <sys/regset.h>
29 #include <sys/frame.h>
30 #include <sys/sysmacros.h>
31 #include <sys/trap.h>
32 #include <sys/machelf.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 <saveargs.h>
41 #include "Pcontrol.h"
42 #include "Pstack.h"
43
44 static uchar_t int_syscall_instr[] = { 0xCD, T_SYSCALLINT };
45 static uchar_t syscall_instr[] = { 0x0f, 0x05 };
46
47 const char *
Ppltdest(struct ps_prochandle * P,uintptr_t pltaddr)48 Ppltdest(struct ps_prochandle *P, uintptr_t pltaddr)
49 {
50 map_info_t *mp = Paddr2mptr(P, pltaddr);
51 file_info_t *fp;
52 size_t i;
53 uintptr_t r_addr;
54
55 if (mp == NULL || (fp = mp->map_file) == NULL ||
56 fp->file_plt_base == 0 ||
57 pltaddr - fp->file_plt_base >= fp->file_plt_size) {
58 errno = EINVAL;
59 return (NULL);
60 }
61
62 i = (pltaddr - fp->file_plt_base) / M_PLT_ENTSIZE - M_PLT_XNumber;
63
64 if (P->status.pr_dmodel == PR_MODEL_LP64) {
65 Elf64_Rela r;
66
67 r_addr = fp->file_jmp_rel + i * sizeof (r);
68
69 if (Pread(P, &r, sizeof (r), r_addr) == sizeof (r) &&
70 (i = ELF64_R_SYM(r.r_info)) < fp->file_dynsym.sym_symn) {
71 Elf_Data *data = fp->file_dynsym.sym_data_pri;
72 Elf64_Sym *symp = &(((Elf64_Sym *)data->d_buf)[i]);
73
74 return (fp->file_dynsym.sym_strs + symp->st_name);
75 }
76 } else {
77 Elf32_Rel r;
78
79 r_addr = fp->file_jmp_rel + i * sizeof (r);
80
81 if (Pread(P, &r, sizeof (r), r_addr) == sizeof (r) &&
82 (i = ELF32_R_SYM(r.r_info)) < fp->file_dynsym.sym_symn) {
83 Elf_Data *data = fp->file_dynsym.sym_data_pri;
84 Elf32_Sym *symp = &(((Elf32_Sym *)data->d_buf)[i]);
85
86 return (fp->file_dynsym.sym_strs + symp->st_name);
87 }
88 }
89
90 return (NULL);
91 }
92
93 int
Pissyscall(struct ps_prochandle * P,uintptr_t addr)94 Pissyscall(struct ps_prochandle *P, uintptr_t addr)
95 {
96 uchar_t instr[16];
97
98 if (P->status.pr_dmodel == PR_MODEL_LP64) {
99 if (Pread(P, instr, sizeof (syscall_instr), addr) !=
100 sizeof (syscall_instr) ||
101 memcmp(instr, syscall_instr, sizeof (syscall_instr)) != 0)
102 return (0);
103 else
104 return (1);
105 }
106
107 if (Pread(P, instr, sizeof (int_syscall_instr), addr) !=
108 sizeof (int_syscall_instr))
109 return (0);
110
111 if (memcmp(instr, int_syscall_instr, sizeof (int_syscall_instr)) == 0)
112 return (1);
113
114 return (0);
115 }
116
117 int
Pissyscall_prev(struct ps_prochandle * P,uintptr_t addr,uintptr_t * dst)118 Pissyscall_prev(struct ps_prochandle *P, uintptr_t addr, uintptr_t *dst)
119 {
120 int ret;
121
122 if (P->status.pr_dmodel == PR_MODEL_LP64) {
123 if (Pissyscall(P, addr - sizeof (syscall_instr))) {
124 if (dst)
125 *dst = addr - sizeof (syscall_instr);
126 return (1);
127 }
128 return (0);
129 }
130
131 if ((ret = Pissyscall(P, addr - sizeof (int_syscall_instr))) != 0) {
132 if (dst)
133 *dst = addr - sizeof (int_syscall_instr);
134 return (ret);
135 }
136
137 return (0);
138 }
139
140 int
Pissyscall_text(struct ps_prochandle * P,const void * buf,size_t buflen)141 Pissyscall_text(struct ps_prochandle *P, const void *buf, size_t buflen)
142 {
143 if (P->status.pr_dmodel == PR_MODEL_LP64) {
144 if (buflen >= sizeof (syscall_instr) &&
145 memcmp(buf, syscall_instr, sizeof (syscall_instr)) == 0)
146 return (1);
147 else
148 return (0);
149 }
150
151 if (buflen < sizeof (int_syscall_instr))
152 return (0);
153
154 if (memcmp(buf, int_syscall_instr, sizeof (int_syscall_instr)) == 0)
155 return (1);
156
157 return (0);
158 }
159
160 #define TR_ARG_MAX 6 /* Max args to print, same as SPARC */
161
162 static boolean_t
argcount_ctf(struct ps_prochandle * P,uint32_t pc,uint_t * countp)163 argcount_ctf(struct ps_prochandle *P, uint32_t pc, uint_t *countp)
164 {
165 GElf_Sym sym;
166 ctf_file_t *ctfp;
167 ctf_funcinfo_t finfo;
168 prsyminfo_t si = { 0 };
169
170 if (Pxlookup_by_addr(P, pc, NULL, 0, &sym, &si) != 0)
171 return (B_FALSE);
172
173 if ((ctfp = Paddr_to_ctf(P, pc)) == NULL)
174 return (B_FALSE);
175
176 if (ctf_func_info(ctfp, si.prs_id, &finfo) == CTF_ERR)
177 return (B_FALSE);
178
179 *countp = finfo.ctc_argc;
180
181 return (B_TRUE);
182 }
183
184 /*
185 * Given a return address, determine the likely number of arguments
186 * that were pushed on the stack prior to its execution. We do this by
187 * expecting that a typical call sequence consists of pushing arguments on
188 * the stack, executing a call instruction, and then performing an add
189 * on %esp to restore it to the value prior to pushing the arguments for
190 * the call. We attempt to detect such an add, and divide the addend
191 * by the size of a word to determine the number of pushed arguments.
192 *
193 * If we do not find such an add, this does not necessarily imply that the
194 * function took no arguments. It is not possible to reliably detect such a
195 * void function because hand-coded assembler does not always perform an add
196 * to %esp immediately after the "call" instruction (eg. _sys_call()).
197 * Because of this, we default to returning MIN(sz, TR_ARG_MAX) instead of 0
198 * in the absence of an add to %esp.
199 */
200 static ulong_t
argcount(struct ps_prochandle * P,uint32_t pc,ssize_t sz)201 argcount(struct ps_prochandle *P, uint32_t pc, ssize_t sz)
202 {
203 uchar_t instr[6];
204 ulong_t count, max;
205
206 max = MIN(sz / sizeof (uint32_t), TR_ARG_MAX);
207
208 /*
209 * Read the instruction at the return location.
210 */
211 if (Pread(P, instr, sizeof (instr), (uintptr_t)pc) != sizeof (instr))
212 return (max);
213
214 if (instr[1] != 0xc4)
215 return (max);
216
217 switch (instr[0]) {
218 case 0x81: /* count is a longword */
219 count = instr[2]+(instr[3]<<8)+(instr[4]<<16)+(instr[5]<<24);
220 break;
221 case 0x83: /* count is a byte */
222 count = instr[2];
223 break;
224 default:
225 return (max);
226 }
227
228 count /= sizeof (uint32_t);
229 return (MIN(count, max));
230 }
231
232 static void
ucontext_32_to_prgregs(const ucontext32_t * uc,prgregset_t dst)233 ucontext_32_to_prgregs(const ucontext32_t *uc, prgregset_t dst)
234 {
235 const greg32_t *src = &uc->uc_mcontext.gregs[0];
236
237 dst[REG_DS] = (uint16_t)src[DS];
238 dst[REG_ES] = (uint16_t)src[ES];
239
240 dst[REG_GS] = (uint16_t)src[GS];
241 dst[REG_FS] = (uint16_t)src[FS];
242 dst[REG_SS] = (uint16_t)src[SS];
243 dst[REG_RSP] = (uint32_t)src[UESP];
244 dst[REG_RFL] = src[EFL];
245 dst[REG_CS] = (uint16_t)src[CS];
246 dst[REG_RIP] = (uint32_t)src[EIP];
247 dst[REG_ERR] = (uint32_t)src[ERR];
248 dst[REG_TRAPNO] = (uint32_t)src[TRAPNO];
249 dst[REG_RAX] = (uint32_t)src[EAX];
250 dst[REG_RCX] = (uint32_t)src[ECX];
251 dst[REG_RDX] = (uint32_t)src[EDX];
252 dst[REG_RBX] = (uint32_t)src[EBX];
253 dst[REG_RBP] = (uint32_t)src[EBP];
254 dst[REG_RSI] = (uint32_t)src[ESI];
255 dst[REG_RDI] = (uint32_t)src[EDI];
256 }
257
258 static int
Pstack_iter32(struct ps_prochandle * P,const prgregset_t regs,proc_stack_f * func,void * arg)259 Pstack_iter32(struct ps_prochandle *P, const prgregset_t regs,
260 proc_stack_f *func, void *arg)
261 {
262 prgreg_t *prevfp = NULL;
263 uint_t pfpsize = 0;
264 int nfp = 0;
265 struct {
266 prgreg32_t fp;
267 prgreg32_t pc;
268 prgreg32_t args[32];
269 } frame;
270 uint_t argc;
271 ssize_t sz;
272 prgregset_t gregs;
273 uint32_t fp, pfp, pc, ctf_pc;
274 long args[32];
275 int rv;
276 int i;
277
278 /*
279 * Type definition for a structure corresponding to an IA32
280 * signal frame. Refer to the comments in Pstack.c for more info
281 */
282 typedef struct {
283 prgreg32_t fp;
284 prgreg32_t pc;
285 int signo;
286 caddr32_t ucp;
287 caddr32_t sip;
288 } sf_t;
289
290 uclist_t ucl;
291 ucontext32_t uc;
292 uintptr_t uc_addr;
293
294 init_uclist(&ucl, P);
295 (void) memcpy(gregs, regs, sizeof (gregs));
296
297 fp = regs[R_FP];
298 ctf_pc = pc = regs[R_PC];
299
300 while (fp != 0 || pc != 0) {
301 if (stack_loop(fp, &prevfp, &nfp, &pfpsize))
302 break;
303
304 if (fp != 0 &&
305 (sz = Pread(P, &frame, sizeof (frame), (uintptr_t)fp)
306 >= (ssize_t)(2* sizeof (uint32_t)))) {
307 /*
308 * One more trick for signal frames: the kernel sets
309 * the return pc of the signal frame to 0xffffffff on
310 * Intel IA32, so argcount won't work.
311 */
312 if (frame.pc != -1L) {
313 sz -= 2* sizeof (uint32_t);
314 if (argcount_ctf(P, ctf_pc, &argc)) {
315 argc = MIN(argc, 32);
316 } else {
317 argc = argcount(P, (uint32_t)frame.pc,
318 sz);
319 }
320 } else
321 argc = 3; /* sighandler(signo, sip, ucp) */
322 } else {
323 (void) memset(&frame, 0, sizeof (frame));
324 argc = 0;
325 }
326
327 ctf_pc = frame.pc;
328 gregs[R_FP] = fp;
329 gregs[R_PC] = pc;
330
331 for (i = 0; i < argc; i++)
332 args[i] = (uint32_t)frame.args[i];
333
334 if ((rv = func(arg, gregs, argc, args)) != 0)
335 break;
336
337 /*
338 * In order to allow iteration over java frames (which can have
339 * their own frame pointers), we allow the iterator to change
340 * the contents of gregs. If we detect a change, then we assume
341 * that the new values point to the next frame.
342 */
343 if (gregs[R_FP] != fp || gregs[R_PC] != pc) {
344 fp = gregs[R_FP];
345 pc = gregs[R_PC];
346 continue;
347 }
348
349 pfp = fp;
350 fp = frame.fp;
351 pc = frame.pc;
352
353 if (find_uclink(&ucl, pfp + sizeof (sf_t)))
354 uc_addr = pfp + sizeof (sf_t);
355 else
356 uc_addr = (uintptr_t)NULL;
357
358 if (uc_addr != (uintptr_t)NULL &&
359 Pread(P, &uc, sizeof (uc), uc_addr) == sizeof (uc)) {
360 ucontext_32_to_prgregs(&uc, gregs);
361 fp = gregs[R_FP];
362 pc = gregs[R_PC];
363 }
364 }
365
366 if (prevfp)
367 free(prevfp);
368
369 free_uclist(&ucl);
370 return (rv);
371 }
372
373 static void
ucontext_n_to_prgregs(const ucontext_t * src,prgregset_t dst)374 ucontext_n_to_prgregs(const ucontext_t *src, prgregset_t dst)
375 {
376 (void) memcpy(dst, src->uc_mcontext.gregs, sizeof (gregset_t));
377 }
378
379 /*
380 * Read arguments from the frame indicated by regs into args, return the
381 * number of arguments successfully read
382 */
383 static int
read_args(struct ps_prochandle * P,uintptr_t fp,uintptr_t pc,prgreg_t * args,size_t argsize)384 read_args(struct ps_prochandle *P, uintptr_t fp, uintptr_t pc, prgreg_t *args,
385 size_t argsize)
386 {
387 GElf_Sym sym;
388 ctf_file_t *ctfp = NULL;
389 ctf_funcinfo_t finfo;
390 prsyminfo_t si = {0};
391 uint8_t ins[SAVEARGS_INSN_SEQ_LEN];
392 size_t insnsize;
393 int argc = 0;
394 int rettype = 0;
395 int start_index = 0;
396 int args_style = 0;
397 int i;
398 ctf_id_t args_types[5];
399
400 if (Pxlookup_by_addr(P, pc, NULL, 0, &sym, &si) != 0)
401 return (0);
402
403 if ((ctfp = Paddr_to_ctf(P, pc)) == NULL)
404 return (0);
405
406 if (ctf_func_info(ctfp, si.prs_id, &finfo) == CTF_ERR)
407 return (0);
408
409 argc = finfo.ctc_argc;
410
411 if (argc == 0)
412 return (0);
413
414 rettype = ctf_type_kind(ctfp, finfo.ctc_return);
415
416 /*
417 * If the function returns a structure or union greater than 16 bytes
418 * in size %rdi contains the address in which to store the return
419 * value rather than for an argument.
420 */
421 if (((rettype == CTF_K_STRUCT) || (rettype == CTF_K_UNION)) &&
422 ctf_type_size(ctfp, finfo.ctc_return) > 16)
423 start_index = 1;
424 else
425 start_index = 0;
426
427 /*
428 * If any of the first 5 arguments are a structure less than 16 bytes
429 * in size, it will be passed spread across two argument registers,
430 * and we will not cope.
431 */
432 if (ctf_func_args(ctfp, si.prs_id, 5, args_types) == CTF_ERR)
433 return (0);
434
435 for (i = 0; i < MIN(5, finfo.ctc_argc); i++) {
436 int t = ctf_type_kind(ctfp, args_types[i]);
437
438 if (((t == CTF_K_STRUCT) || (t == CTF_K_UNION)) &&
439 ctf_type_size(ctfp, args_types[i]) <= 16)
440 return (0);
441 }
442
443 /*
444 * The number of instructions to search for argument saving is limited
445 * such that only instructions prior to %pc are considered and we
446 * never read arguments from a function where the saving code has not
447 * in fact yet executed.
448 */
449 insnsize = MIN(MIN(sym.st_size, SAVEARGS_INSN_SEQ_LEN),
450 pc - sym.st_value);
451
452 if (Pread(P, ins, insnsize, sym.st_value) != insnsize)
453 return (0);
454
455 if ((argc != 0) &&
456 ((args_style = saveargs_has_args(ins, insnsize, argc,
457 start_index)) != SAVEARGS_NO_ARGS)) {
458 int regargs = MIN((6 - start_index), argc);
459 size_t size = regargs * sizeof (long);
460 int i;
461
462 /*
463 * If Studio pushed a structure return address as an argument,
464 * we need to read one more argument than actually exists (the
465 * addr) to make everything line up.
466 */
467 if (args_style == SAVEARGS_STRUCT_ARGS)
468 size += sizeof (long);
469
470 if (Pread(P, args, size, (fp - size)) != size)
471 return (0);
472
473 for (i = 0; i < (regargs / 2); i++) {
474 prgreg_t t = args[i];
475
476 args[i] = args[regargs - i - 1];
477 args[regargs - i - 1] = t;
478 }
479
480 if (argc > regargs) {
481 size = MIN((argc - regargs) * sizeof (long),
482 argsize - (regargs * sizeof (long)));
483
484 if (Pread(P, &args[regargs], size, fp +
485 (sizeof (uintptr_t) * 2)) != size)
486 return (6);
487 }
488
489 return (argc);
490 } else {
491 return (0);
492 }
493 }
494
495 int
Pstack_iter(struct ps_prochandle * P,const prgregset_t regs,proc_stack_f * func,void * arg)496 Pstack_iter(struct ps_prochandle *P, const prgregset_t regs,
497 proc_stack_f *func, void *arg)
498 {
499 struct {
500 uintptr_t fp;
501 uintptr_t pc;
502 } frame;
503
504 uint_t pfpsize = 0;
505 prgreg_t *prevfp = NULL;
506 prgreg_t fp, pfp;
507 prgreg_t pc;
508
509 prgregset_t gregs;
510 int nfp = 0;
511
512 uclist_t ucl;
513 int rv = 0;
514 int argc;
515
516 uintptr_t uc_addr;
517 ucontext_t uc;
518
519 /*
520 * Type definition for a structure corresponding to an IA32
521 * signal frame. Refer to the comments in Pstack.c for more info
522 */
523 typedef struct {
524 prgreg_t fp;
525 prgreg_t pc;
526 prgreg_t signo;
527 siginfo_t *sip;
528 } sigframe_t;
529 prgreg_t args[32] = {0};
530
531 if (P->status.pr_dmodel != PR_MODEL_LP64)
532 return (Pstack_iter32(P, regs, func, arg));
533
534 init_uclist(&ucl, P);
535 (void) memcpy(gregs, regs, sizeof (gregs));
536
537 fp = gregs[R_FP];
538 pc = gregs[R_PC];
539
540 while (fp != 0 || pc != 0) {
541
542 if (stack_loop(fp, &prevfp, &nfp, &pfpsize))
543 break;
544
545 if (fp != 0 &&
546 Pread(P, &frame, sizeof (frame), (uintptr_t)fp) ==
547 sizeof (frame)) {
548 if (frame.pc == -1) {
549 argc = 3;
550 args[2] = fp + sizeof (sigframe_t);
551 if (Pread(P, &args, 2 * sizeof (prgreg_t),
552 fp + 2 * sizeof (prgreg_t)) !=
553 2 * sizeof (prgreg_t))
554 argc = 0;
555 } else {
556 argc = read_args(P, fp, pc, args,
557 sizeof (args));
558 }
559 } else {
560 (void) memset(&frame, 0, sizeof (frame));
561 argc = 0;
562 }
563
564 gregs[R_FP] = fp;
565 gregs[R_PC] = pc;
566
567 if ((rv = func(arg, gregs, argc, args)) != 0)
568 break;
569
570 pfp = fp;
571 fp = frame.fp;
572 pc = frame.pc;
573
574 if (pc == -1 && find_uclink(&ucl, pfp + sizeof (sigframe_t))) {
575 uc_addr = pfp + sizeof (sigframe_t);
576
577 if (Pread(P, &uc, sizeof (uc), uc_addr)
578 == sizeof (uc)) {
579 ucontext_n_to_prgregs(&uc, gregs);
580 fp = gregs[R_FP];
581 pc = gregs[R_PC];
582 }
583 }
584 }
585
586 if (prevfp)
587 free(prevfp);
588
589 free_uclist(&ucl);
590
591 return (rv);
592 }
593
594 uintptr_t
Psyscall_setup(struct ps_prochandle * P,int nargs,int sysindex,uintptr_t sp)595 Psyscall_setup(struct ps_prochandle *P, int nargs, int sysindex, uintptr_t sp)
596 {
597 if (P->status.pr_dmodel == PR_MODEL_ILP32) {
598 sp -= sizeof (int) * (nargs+2);
599
600 P->status.pr_lwp.pr_reg[REG_RAX] = sysindex;
601 P->status.pr_lwp.pr_reg[REG_RSP] = sp;
602 P->status.pr_lwp.pr_reg[REG_RIP] = P->sysaddr;
603 } else {
604 int pusharg = (nargs > 6) ? nargs - 6: 0;
605
606 sp -= sizeof (int64_t) * (pusharg+2);
607
608 P->status.pr_lwp.pr_reg[REG_RAX] = sysindex;
609 P->status.pr_lwp.pr_reg[REG_RSP] = sp;
610 P->status.pr_lwp.pr_reg[REG_RIP] = P->sysaddr;
611 }
612
613 return (sp);
614 }
615
616 int
Psyscall_copyinargs(struct ps_prochandle * P,int nargs,argdes_t * argp,uintptr_t ap)617 Psyscall_copyinargs(struct ps_prochandle *P, int nargs, argdes_t *argp,
618 uintptr_t ap)
619 {
620 if (P->status.pr_dmodel == PR_MODEL_ILP32) {
621 int32_t arglist[MAXARGS+2];
622 int i;
623 argdes_t *adp;
624
625 for (i = 0, adp = argp; i < nargs; i++, adp++)
626 arglist[1 + i] = (int32_t)adp->arg_value;
627
628 arglist[0] = P->status.pr_lwp.pr_reg[REG_RIP];
629 if (Pwrite(P, &arglist[0], sizeof (int) * (nargs+1),
630 (uintptr_t)ap) != sizeof (int) * (nargs+1))
631 return (-1);
632 } else {
633 int64_t arglist[MAXARGS+2];
634 int i;
635 argdes_t *adp;
636 int pusharg = (nargs > 6) ? nargs - 6: 0;
637
638 for (i = 0, adp = argp; i < nargs; i++, adp++) {
639 switch (i) {
640 case 0:
641 (void) Pputareg(P, REG_RDI, adp->arg_value);
642 break;
643 case 1:
644 (void) Pputareg(P, REG_RSI, adp->arg_value);
645 break;
646 case 2:
647 (void) Pputareg(P, REG_RDX, adp->arg_value);
648 break;
649 case 3:
650 (void) Pputareg(P, REG_RCX, adp->arg_value);
651 break;
652 case 4:
653 (void) Pputareg(P, REG_R8, adp->arg_value);
654 break;
655 case 5:
656 (void) Pputareg(P, REG_R9, adp->arg_value);
657 break;
658 default:
659 arglist[i - 5] = (uint64_t)adp->arg_value;
660 break;
661 }
662 }
663
664 arglist[0] = P->status.pr_lwp.pr_reg[REG_RIP];
665
666 if (Pwrite(P, &arglist[0],
667 sizeof (int64_t) * (pusharg + 1), ap) !=
668 sizeof (int64_t) * (pusharg + 1))
669 return (-1);
670 }
671
672 return (0);
673 }
674
675 int
Psyscall_copyoutargs(struct ps_prochandle * P,int nargs,argdes_t * argp,uintptr_t ap)676 Psyscall_copyoutargs(struct ps_prochandle *P, int nargs, argdes_t *argp,
677 uintptr_t ap)
678 {
679 if (P->status.pr_dmodel == PR_MODEL_ILP32) {
680 uint32_t arglist[MAXARGS + 2];
681 int i;
682 argdes_t *adp;
683
684 if (Pread(P, &arglist[0], sizeof (int) * (nargs+1),
685 (uintptr_t)ap) != sizeof (int) * (nargs+1))
686 return (-1);
687
688 for (i = 0, adp = argp; i < nargs; i++, adp++)
689 adp->arg_value = arglist[i];
690 } else {
691 int pusharg = (nargs > 6) ? nargs - 6: 0;
692 int64_t arglist[MAXARGS+2];
693 int i;
694 argdes_t *adp;
695
696 if (pusharg > 0 &&
697 Pread(P, &arglist[0], sizeof (int64_t) * (pusharg + 1),
698 ap) != sizeof (int64_t) * (pusharg + 1))
699 return (-1);
700
701 for (i = 0, adp = argp; i < nargs; i++, adp++) {
702 switch (i) {
703 case 0:
704 adp->arg_value =
705 P->status.pr_lwp.pr_reg[REG_RDI];
706 break;
707 case 1:
708 adp->arg_value =
709 P->status.pr_lwp.pr_reg[REG_RSI];
710 break;
711 case 2:
712 adp->arg_value =
713 P->status.pr_lwp.pr_reg[REG_RDX];
714 break;
715 case 3:
716 adp->arg_value =
717 P->status.pr_lwp.pr_reg[REG_RCX];
718 break;
719 case 4:
720 adp->arg_value =
721 P->status.pr_lwp.pr_reg[REG_R8];
722 break;
723 case 5:
724 adp->arg_value =
725 P->status.pr_lwp.pr_reg[REG_R9];
726 break;
727 default:
728 adp->arg_value = arglist[i - 6];
729 break;
730 }
731 }
732
733 return (0);
734 }
735
736 return (0);
737 }
738