- little mdoc cleanup
[dragonfly/vkernel-mp.git] / usr.bin / doscmd / trace.c
blob3349d19908057fd4d22a89955fd839bcf35d3d67
1 /*
2 * Copyright (c) 1992, 1993, 1996
3 * Berkeley Software Design, Inc. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by Berkeley Software
16 * Design, Inc.
18 * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
30 * BSDI trace.c,v 2.2 1996/04/08 19:33:07 bostic Exp
32 * $FreeBSD: src/usr.bin/doscmd/trace.c,v 1.3.2.1 2002/04/25 11:04:51 tg Exp $
33 * $DragonFly: src/usr.bin/doscmd/trace.c,v 1.2 2003/06/17 06:29:26 dillon Exp $
36 #include "doscmd.h"
37 #include "trap.h"
39 int tmode = 0;
41 static u_short *saddr;
42 static u_char *iaddr, ibyte;
44 /* locals */
45 static void printtrace(regcontext_t *REGS, char *buf);
46 static inline void showstate(long, long, char);
49 * Before exiting to VM86 mode:
50 * 1) Always set the trap flag.
51 * 2) If this is a POPF or IRET instruction, set the trap flag in the saved
52 * flag state on the stack.
53 * On enterint from VM86 mode:
54 * 1) Restore the trap flag from our saved flag state.
55 * 2) If we just finished a POPF or IRET unstruction, patch the saved flag
56 * state on the stack.
59 int tracetype;
61 int
62 resettrace(regcontext_t *REGS)
64 if ((R_EFLAGS & PSL_VM) == 0) /* invalid unless handling a vm86 process */
65 return (0);
67 /* XXX */ return 1;
69 switch (tracetype) {
70 case 1:
71 R_EFLAGS &= ~PSL_T;
72 tracetype = 0;
73 return (1);
75 case 2:
76 if ((u_char *)MAKEPTR(R_CS, R_IP - 1) == iaddr)
77 R_IP --;
78 *iaddr = ibyte;
79 tracetype = 0;
80 return (1);
82 case 3:
83 case 4:
84 R_EFLAGS &= ~PSL_T;
85 *saddr &= ~PSL_T;
86 tracetype = 0;
87 return (1);
89 return (0);
92 void
93 tracetrap(regcontext_t *REGS)
95 u_char *addr;
96 int n;
97 char buf[100];
99 if ((R_EFLAGS & PSL_VM) == 0)
100 return;
102 addr = (u_char *)MAKEPTR(R_CS, R_IP);
104 n = i386dis(R_CS, R_IP, addr, buf, 0);
105 printtrace(REGS, buf);
107 /* XXX */
108 R_EFLAGS |= PSL_T;
109 return;
110 /* XXX */
113 switch (addr[0]) {
114 case REPNZ:
115 case REPZ:
116 tracetype = 2;
117 iaddr = (u_char *)MAKEPTR(R_CS, R_IP + n);
118 break;
119 case PUSHF:
120 tracetype = 4;
121 saddr = (u_short *)MAKEPTR(R_SS, R_SP - 2);
122 break;
123 case POPF:
124 tracetype = 3;
125 saddr = (u_short *)MAKEPTR(R_SS, R_SP + 0);
126 break;
127 case IRET:
128 tracetype = 3;
129 saddr = (u_short *)MAKEPTR(R_SS, R_SP + 4);
130 #if 0
131 printf("IRET: %04x %04x %04x\n",
132 ((u_short *)MAKEPTR(R_SS, R_SP))[0],
133 ((u_short *)MAKEPTR(R_SS, R_SP))[1],
134 ((u_short *)MAKEPTR(R_SS, R_SP))[2]);
135 #endif
136 break;
137 case OPSIZ:
138 switch (addr[1]) {
139 case PUSHF:
140 tracetype = 4;
141 saddr = (u_short *)MAKEPTR(R_SS, R_SP - 4);
142 break;
143 case POPF:
144 tracetype = 3;
145 saddr = (u_short *)MAKEPTR(R_SS, R_SP + 0);
146 break;
147 case IRET:
148 tracetype = 3;
149 saddr = (u_short *)MAKEPTR(R_SS, R_SP + 8);
150 break;
151 default:
152 tracetype = 1;
153 break;
155 default:
156 tracetype = 1;
157 break;
160 switch (tracetype) {
161 case 1:
162 case 4:
163 if (R_EFLAGS & PSL_T)
164 tracetype = 0;
165 else
166 R_EFLAGS |= PSL_T;
167 break;
168 case 2:
169 if (*iaddr == TRACETRAP)
170 tracetype = 0;
171 else {
172 ibyte = *iaddr;
173 *iaddr = TRACETRAP;
175 break;
176 case 3:
177 R_EFLAGS |= PSL_T;
178 if (*saddr & PSL_T)
179 tracetype = 0;
180 else
181 *saddr |= PSL_T;
182 break;
186 static inline void
187 showstate(long flags, long flag, char f)
189 putc((flags & flag) ? f : ' ', debugf);
192 static void
193 printtrace(regcontext_t *REGS, char *buf)
196 static int first = 1;
197 #if BIG_DEBUG
198 u_char *addr = (u_char *)MAKEPTR(R_CS, R_IP);
199 #endif
201 if (first) {
202 fprintf(debugf, "%4s:%4s "
203 #if BIG_DEBUG
204 ".. .. .. .. .. .. "
205 #endif
206 "%-30s "
207 "%4s %4s %4s %4s %4s %4s %4s %4s %4s %4s %4s\n",
208 "CS", "IP", "instruction",
209 "AX", "BX", "CX", "DX",
210 "DI", "SI", "SP", "BP",
211 "SS", "DS", "ES");
212 first = 0;
215 fprintf(debugf, "%04x:%04x "
216 #if BIG_DEBUG
217 "%02x %02x %02x %02x %02x %02x "
218 #endif
219 "%-30s "
220 "%04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x ",
221 R_CS, R_IP,
222 #if BIG_DEBUG
223 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5],
224 #endif
225 buf,
226 R_AX, R_BX, R_CX, R_DX, R_DI, R_SI, R_SP, R_BP, R_SS, R_DS, R_ES);
227 #if 0
228 fprintf(debugf, "%04x %04x %04x %04x ",
229 ((u_short *)VECPTR(0x0D760FCA-14))[0],
230 ((u_short *)VECPTR(0x0D760FCA-14))[1],
231 ((u_short *)VECPTR(0x0D760F7A+8))[0],
232 ((u_short *)VECPTR(0x0D760F7A+8))[1]);
233 #endif
234 showstate(R_EFLAGS, PSL_C, 'C');
235 showstate(R_EFLAGS, PSL_PF, 'P');
236 showstate(R_EFLAGS, PSL_AF, 'c');
237 showstate(R_EFLAGS, PSL_Z, 'Z');
238 showstate(R_EFLAGS, PSL_N, 'N');
239 showstate(R_EFLAGS, PSL_T, 'T');
240 showstate(R_EFLAGS, PSL_I, 'I');
241 showstate(R_EFLAGS, PSL_D, 'D');
242 showstate(R_EFLAGS, PSL_V, 'V');
243 showstate(R_EFLAGS, PSL_NT, 'n');
244 showstate(R_EFLAGS, PSL_RF, 'r');
245 showstate(R_EFLAGS, PSL_VM, 'v');
246 showstate(R_EFLAGS, PSL_AC, 'a');
247 showstate(R_EFLAGS, PSL_VIF, 'i');
248 showstate(R_EFLAGS, PSL_VIP, 'p');
249 putc('\n', debugf);