* Copyright (c) 1982, 1986, 1989 The Regents of the University of California.
* %sccs.include.proprietary.c%
* @(#)sys_process.c 7.22 (Berkeley) %G%
* Used to pass trace command from
* parent to child being traced.
* This data base cannot be
* Process debugging system call.
ptrace(curp
, uap
, retval
)
if (p
== 0 || p
->p_stat
!= SSTOP
|| p
->p_pptr
!= curp
||
sleep((caddr_t
)&ipc
, IPCPRI
);
sleep((caddr_t
)&ipc
, IPCPRI
);
#define PHYSOFF(p, o) ((caddr_t)(p) + (o))
* Transmit a tracing request from the parent to the child process
* being debugged. This code runs in the context of the child process
* to fulfill the command requested by the parent.
if (ipc
.ip_lock
!= p
->p_pid
)
p
->p_addr
->u_kproc
.kp_proc
.p_regs
= p
->p_regs
; /* u.u_ar0 */
case PT_READ_I
: /* read the child's text space */
if (!useracc((caddr_t
)ipc
.ip_addr
, 4, B_READ
))
ipc
.ip_data
= fuiword((caddr_t
)ipc
.ip_addr
);
case PT_READ_D
: /* read the child's data space */
if (!useracc((caddr_t
)ipc
.ip_addr
, 4, B_READ
))
ipc
.ip_data
= fuword((caddr_t
)ipc
.ip_addr
);
case PT_READ_U
: /* read the child's u. */
if (p
->p_addr
->u_pcb
.pcb_flags
& PCB_HPUXTRACE
)
i
= hpuxtobsduoff(ipc
.ip_addr
);
if ((u_int
) i
> ctob(UPAGES
)-sizeof(int) || (i
& 1) != 0)
ipc
.ip_data
= *(int *)PHYSOFF(p
->p_addr
, i
);
case PT_WRITE_I
: /* write the child's text space */
if ((i
= suiword((caddr_t
)ipc
.ip_addr
, ipc
.ip_data
)) < 0) {
sa
= trunc_page((vm_offset_t
)ipc
.ip_addr
);
ea
= round_page((vm_offset_t
)ipc
.ip_addr
+sizeof(int)-1);
rv
= vm_map_protect(&p
->p_vmspace
->vm_map
, sa
, ea
,
if (rv
== KERN_SUCCESS
) {
i
= suiword((caddr_t
)ipc
.ip_addr
, ipc
.ip_data
);
(void) vm_map_protect(&p
->p_vmspace
->vm_map
,
sa
, ea
, VM_PROT_READ
|VM_PROT_EXECUTE
,
case PT_WRITE_D
: /* write the child's data space */
if (suword((caddr_t
)ipc
.ip_addr
, 0) < 0)
(void) suword((caddr_t
)ipc
.ip_addr
, ipc
.ip_data
);
case PT_WRITE_U
: /* write the child's u. */
if (p
->p_addr
->u_pcb
.pcb_flags
& PCB_HPUXTRACE
)
i
= hpuxtobsduoff(ipc
.ip_addr
);
poff
= (int *)PHYSOFF(kstack
, i
);
for (i
=0; i
<NIPCREG
; i
++)
if (poff
== &p
->p_regs
[ipcreg
[i
]])
if (poff
== &p
->p_regs
[PS
]) {
ipc
.ip_data
|= PSL_USERSET
;
ipc
.ip_data
&= ~PSL_USERCLR
;
if (ipc
.ip_data
& PSL_CM
)
ipc
.ip_data
&= ~PSL_CM_CLR
;
if (poff
>= (int *)&((struct user
*)kstack
)->u_pcb
.pcb_fpregs
.fpf_regs
&&
poff
<= (int *)&((struct user
*)kstack
)->u_pcb
.pcb_fpregs
.fpf_fpiar
)
case PT_STEP
: /* single step the child */
case PT_CONTINUE
: /* continue the child */
if ((int)ipc
.ip_addr
!= 1)
p
->p_regs
[PC
] = (int)ipc
.ip_addr
;
if ((unsigned)ipc
.ip_data
> NSIG
)
p
->p_xstat
= ipc
.ip_data
; /* see issig */
case PT_KILL
: /* kill the child process */
exit(p
, (int)p
->p_xstat
);
* Process debugging system call.
register struct uprof
*upp
= &p
->p_stats
->p_prof
;
upp
->pr_base
= uap
->bufbase
;
upp
->pr_size
= uap
->bufsize
;
upp
->pr_off
= uap
->pcoffset
;
upp
->pr_scale
= uap
->pcscale
;