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
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
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
30 * BSDI trace.c,v 2.2 1996/04/08 19:33:07 bostic Exp
33 #include <sys/cdefs.h>
34 __FBSDID("$FreeBSD$");
41 static u_short *saddr;
42 static u_char *iaddr, ibyte;
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 entering from VM86 mode:
54 * 1) Restore the trap flag from our saved flag state.
55 * 2) If we just finished a POPF or IRET instruction, patch the saved flag
62 resettrace(regcontext_t *REGS)
64 if ((R_EFLAGS & PSL_VM) == 0) /* invalid unless handling a vm86 process */
76 if ((u_char *)MAKEPTR(R_CS, R_IP - 1) == iaddr)
93 tracetrap(regcontext_t *REGS)
99 if ((R_EFLAGS & PSL_VM) == 0)
102 addr = (u_char *)MAKEPTR(R_CS, R_IP);
104 n = i386dis(R_CS, R_IP, addr, buf, 0);
105 printtrace(REGS, buf);
117 iaddr = (u_char *)MAKEPTR(R_CS, R_IP + n);
121 saddr = (u_short *)MAKEPTR(R_SS, R_SP - 2);
125 saddr = (u_short *)MAKEPTR(R_SS, R_SP + 0);
129 saddr = (u_short *)MAKEPTR(R_SS, R_SP + 4);
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]);
141 saddr = (u_short *)MAKEPTR(R_SS, R_SP - 4);
145 saddr = (u_short *)MAKEPTR(R_SS, R_SP + 0);
149 saddr = (u_short *)MAKEPTR(R_SS, R_SP + 8);
163 if (R_EFLAGS & PSL_T)
169 if (*iaddr == TRACETRAP)
187 showstate(long flags, long flag, char f)
189 putc((flags & flag) ? f : ' ', debugf);
193 printtrace(regcontext_t *REGS, char *buf)
196 static int first = 1;
198 u_char *addr = (u_char *)MAKEPTR(R_CS, R_IP);
202 fprintf(debugf, "%4s:%4s "
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",
215 fprintf(debugf, "%04x:%04x "
217 "%02x %02x %02x %02x %02x %02x "
220 "%04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x ",
223 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5],
226 R_AX, R_BX, R_CX, R_DX, R_DI, R_SI, R_SP, R_BP, R_SS, R_DS, R_ES);
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]);
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');