1 /* The kernel call implemented in this file:
4 * The parameters for this kernel call are:
5 * m2_i1: CTL_ENDPT process that is traced
6 * m2_i2: CTL_REQUEST trace request
7 * m2_l1: CTL_ADDRESS address at traced process' space
8 * m2_l2: CTL_DATA data to be written or returned here
11 #include "../system.h"
12 #include <sys/ptrace.h>
16 /*==========================================================================*
18 *==========================================================================*/
19 #define TR_VLSIZE ((vir_bytes) sizeof(long))
21 PUBLIC
int do_trace(m_ptr
)
22 register message
*m_ptr
;
24 /* Handle the debugging commands supported by the ptrace system call
26 * T_STOP stop the process
27 * T_OK enable tracing by parent for this process
28 * T_GETINS return value from instruction space
29 * T_GETDATA return value from data space
30 * T_GETUSER return value from user process table
31 * T_SETINS set value from instruction space
32 * T_SETDATA set value from data space
33 * T_SETUSER set value in user process table
34 * T_RESUME resume execution
36 * T_STEP set trace bit
38 * The T_OK and T_EXIT commands are handled completely by the process manager,
39 * all others come here.
42 register struct proc
*rp
;
44 vir_bytes tr_addr
= (vir_bytes
) m_ptr
->CTL_ADDRESS
;
45 long tr_data
= m_ptr
->CTL_DATA
;
46 int tr_request
= m_ptr
->CTL_REQUEST
;
47 int tr_proc_nr_e
= m_ptr
->CTL_ENDPT
, tr_proc_nr
;
51 if(!isokendpt(tr_proc_nr_e
, &tr_proc_nr
)) return(EINVAL
);
52 if (iskerneln(tr_proc_nr
)) return(EPERM
);
54 rp
= proc_addr(tr_proc_nr
);
55 if (isemptyp(rp
)) return(EIO
);
57 case T_STOP
: /* stop process */
58 RTS_LOCK_SET(rp
, P_STOP
);
59 rp
->p_reg
.psw
&= ~TRACEBIT
; /* clear trace bit */
62 case T_GETINS
: /* return value from instruction space */
63 if (rp
->p_memmap
[T
].mem_len
!= 0) {
64 if ((src
= umap_local(rp
, T
, tr_addr
, TR_VLSIZE
)) == 0) return(EIO
);
65 phys_copy(src
, vir2phys(&tr_data
), (phys_bytes
) sizeof(long));
66 m_ptr
->CTL_DATA
= tr_data
;
69 /* Text space is actually data space - fall through. */
71 case T_GETDATA
: /* return value from data space */
72 if ((src
= umap_local(rp
, D
, tr_addr
, TR_VLSIZE
)) == 0) return(EIO
);
73 phys_copy(src
, vir2phys(&tr_data
), (phys_bytes
) sizeof(long));
74 m_ptr
->CTL_DATA
= tr_data
;
77 case T_GETUSER
: /* return value from process table */
78 if ((tr_addr
& (sizeof(long) - 1)) != 0 ||
79 tr_addr
> sizeof(struct proc
) - sizeof(long))
81 m_ptr
->CTL_DATA
= *(long *) ((char *) rp
+ (int) tr_addr
);
84 case T_SETINS
: /* set value in instruction space */
85 if (rp
->p_memmap
[T
].mem_len
!= 0) {
86 if ((dst
= umap_local(rp
, T
, tr_addr
, TR_VLSIZE
)) == 0) return(EIO
);
87 phys_copy(vir2phys(&tr_data
), dst
, (phys_bytes
) sizeof(long));
91 /* Text space is actually data space - fall through. */
93 case T_SETDATA
: /* set value in data space */
94 if ((dst
= umap_local(rp
, D
, tr_addr
, TR_VLSIZE
)) == 0) return(EIO
);
95 phys_copy(vir2phys(&tr_data
), dst
, (phys_bytes
) sizeof(long));
99 case T_SETUSER
: /* set value in process table */
100 if ((tr_addr
& (sizeof(reg_t
) - 1)) != 0 ||
101 tr_addr
> sizeof(struct stackframe_s
) - sizeof(reg_t
))
104 #if (_MINIX_CHIP == _CHIP_INTEL)
105 /* Altering segment registers might crash the kernel when it
106 * tries to load them prior to restarting a process, so do
109 if (i
== (int) &((struct proc
*) 0)->p_reg
.cs
||
110 i
== (int) &((struct proc
*) 0)->p_reg
.ds
||
111 i
== (int) &((struct proc
*) 0)->p_reg
.es
||
113 i
== (int) &((struct proc
*) 0)->p_reg
.gs
||
114 i
== (int) &((struct proc
*) 0)->p_reg
.fs
||
116 i
== (int) &((struct proc
*) 0)->p_reg
.ss
)
119 if (i
== (int) &((struct proc
*) 0)->p_reg
.psw
)
120 /* only selected bits are changeable */
123 *(reg_t
*) ((char *) &rp
->p_reg
+ i
) = (reg_t
) tr_data
;
127 case T_RESUME
: /* resume execution */
128 RTS_LOCK_UNSET(rp
, P_STOP
);
132 case T_STEP
: /* set trace bit */
133 rp
->p_reg
.psw
|= TRACEBIT
;
134 RTS_LOCK_UNSET(rp
, P_STOP
);
138 case T_READB_INS
: /* get value from instruction space */
139 if (rp
->p_memmap
[T
].mem_len
!= 0) {
140 if ((dst
= umap_local(rp
, T
, tr_addr
, 1)) == 0) return(EFAULT
);
141 phys_copy(dst
, vir2phys(&ub
), (phys_bytes
) 1);
142 m_ptr
->CTL_DATA
= ub
;
146 if ((dst
= umap_local(rp
, D
, tr_addr
, 1)) == 0) return(EFAULT
);
147 phys_copy(dst
, vir2phys(&ub
), (phys_bytes
) 1);
148 m_ptr
->CTL_DATA
= ub
;
151 case T_WRITEB_INS
: /* set value in instruction space */
152 if (rp
->p_memmap
[T
].mem_len
!= 0) {
153 if ((dst
= umap_local(rp
, T
, tr_addr
, 1)) == 0) return(EFAULT
);
154 phys_copy(vir2phys(&tr_data
), dst
, (phys_bytes
) 1);
159 if ((dst
= umap_local(rp
, D
, tr_addr
, 1)) == 0) return(EFAULT
);
160 phys_copy(vir2phys(&tr_data
), dst
, (phys_bytes
) 1);
170 #endif /* USE_TRACE */