summaryrefslogtreecommitdiffstats
path: root/usr.bin/doscmd/trace.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin/doscmd/trace.c')
-rw-r--r--usr.bin/doscmd/trace.c249
1 files changed, 249 insertions, 0 deletions
diff --git a/usr.bin/doscmd/trace.c b/usr.bin/doscmd/trace.c
new file mode 100644
index 0000000..65a6ae3
--- /dev/null
+++ b/usr.bin/doscmd/trace.c
@@ -0,0 +1,249 @@
+/*
+ * Copyright (c) 1992, 1993, 1996
+ * Berkeley Software Design, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Berkeley Software
+ * Design, Inc.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * BSDI trace.c,v 2.2 1996/04/08 19:33:07 bostic Exp
+ *
+ * $Id: trace.c,v 1.3 1996/09/25 00:03:44 miff Exp $
+ */
+
+#include "doscmd.h"
+#include "trap.h"
+
+extern FILE *debugf;
+int tmode = 0;
+
+static u_short *saddr;
+static u_char *iaddr, ibyte;
+
+/* locals */
+static void printtrace(regcontext_t *REGS, char *buf);
+
+
+/*
+ * Before exiting to VM86 mode:
+ * 1) Always set the trap flag.
+ * 2) If this is a POPF or IRET instruction, set the trap flag in the saved
+ * flag state on the stack.
+ * On enterint from VM86 mode:
+ * 1) Restore the trap flag from our saved flag state.
+ * 2) If we just finished a POPF or IRET unstruction, patch the saved flag
+ * state on the stack.
+ */
+
+int tracetype;
+
+int
+resettrace(regcontext_t *REGS)
+{
+ if ((R_EFLAGS & PSL_VM) == 0) /* invalid unless handling a vm86 process */
+ return (0);
+
+/* XXX */ return 1;
+
+ switch (tracetype) {
+ case 1:
+ R_EFLAGS &= ~PSL_T;
+ tracetype = 0;
+ return (1);
+
+ case 2:
+ if ((u_char *)MAKEPTR(R_CS, R_IP - 1) == iaddr)
+ R_IP --;
+ *iaddr = ibyte;
+ tracetype = 0;
+ return (1);
+
+ case 3:
+ case 4:
+ R_EFLAGS &= ~PSL_T;
+ *saddr &= ~PSL_T;
+ tracetype = 0;
+ return (1);
+ }
+ return (0);
+}
+
+void
+tracetrap(regcontext_t *REGS)
+{
+ u_char *addr;
+ int n;
+ char buf[100];
+
+ if ((R_EFLAGS & PSL_VM) == 0)
+ return;
+
+ addr = (u_char *)N_GETPTR(R_CS, R_IP);
+
+ n = i386dis(R_CS, R_IP, addr, buf, 0);
+ printtrace(REGS, buf);
+
+/* XXX */
+ R_EFLAGS |= PSL_T;
+ return;
+/* XXX */
+
+
+ switch (addr[0]) {
+ case REPNZ:
+ case REPZ:
+ tracetype = 2;
+ iaddr = (u_char *)MAKEPTR(R_CS, R_IP + n);
+ break;
+ case PUSHF:
+ tracetype = 4;
+ saddr = (u_short *)MAKEPTR(R_SS, R_SP - 2);
+ break;
+ case POPF:
+ tracetype = 3;
+ saddr = (u_short *)MAKEPTR(R_SS, R_SP + 0);
+ break;
+ case IRET:
+ tracetype = 3;
+ saddr = (u_short *)MAKEPTR(R_SS, R_SP + 4);
+#if 0
+ printf("IRET: %04x %04x %04x\n",
+ ((u_short *)N_GETPTR(R_SS, R_SP))[0],
+ ((u_short *)N_GETPTR(R_SS, R_SP))[1],
+ ((u_short *)N_GETPTR(R_SS, R_SP))[2]);
+#endif
+ break;
+ case OPSIZ:
+ switch (addr[1]) {
+ case PUSHF:
+ tracetype = 4;
+ saddr = (u_short *)MAKEPTR(R_SS, R_SP - 4);
+ break;
+ case POPF:
+ tracetype = 3;
+ saddr = (u_short *)MAKEPTR(R_SS, R_SP + 0);
+ break;
+ case IRET:
+ tracetype = 3;
+ saddr = (u_short *)MAKEPTR(R_SS, R_SP + 8);
+ break;
+ default:
+ tracetype = 1;
+ break;
+ }
+ default:
+ tracetype = 1;
+ break;
+ }
+
+ switch (tracetype) {
+ case 1:
+ case 4:
+ if (R_EFLAGS & PSL_T)
+ tracetype = 0;
+ else
+ R_EFLAGS |= PSL_T;
+ break;
+ case 2:
+ if (*iaddr == TRACETRAP)
+ tracetype = 0;
+ else {
+ ibyte = *iaddr;
+ *iaddr = TRACETRAP;
+ }
+ break;
+ case 3:
+ R_EFLAGS |= PSL_T;
+ if (*saddr & PSL_T)
+ tracetype = 0;
+ else
+ *saddr |= PSL_T;
+ break;
+ }
+}
+
+inline
+showstate(long flags, long flag, char f)
+{
+ putc((flags & flag) ? f : ' ', debugf);
+}
+
+static void
+printtrace(regcontext_t *REGS, char *buf)
+{
+
+ static int first = 1;
+ u_char *addr = (u_char *)N_GETPTR(R_CS, R_IP);
+ char *bigfmt = "%04x:%04x "
+#if BIG_DEBUG
+ "%02x %02x %02x %02x %02x %02x "
+#endif
+ "%-30s "
+ "%04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x ";
+
+ if (first) {
+ fprintf(debugf, "%4s:%4s "
+#if BIG_DEBUG
+ ".. .. .. .. .. .. "
+#endif
+ "%-30s "
+ "%4s %4s %4s %4s %4s %4s %4s %4s %4s %4s %4s\n",
+ "CS", "IP", "instruction",
+ "AX", "BX", "CX", "DX",
+ "DI", "SI", "SP", "BP",
+ "SS", "DS", "ES");
+ first = 0;
+ }
+
+ fprintf(debugf, bigfmt,
+ R_CS, R_IP,
+#if BIG_DEBUG
+ addr[0], addr[1], addr[2], addr[3], addr[4], addr[5],
+#endif
+ buf,
+ R_AX, R_BX, R_CX, R_DX, R_DI, R_SI, R_SP, R_BP, R_SS, R_DS, R_ES);
+#if 0
+ fprintf(debugf, "%04x %04x %04x %04x ",
+ ((u_short *)VECPTR(0x0D760FCA-14))[0],
+ ((u_short *)VECPTR(0x0D760FCA-14))[1],
+ ((u_short *)VECPTR(0x0D760F7A+8))[0],
+ ((u_short *)VECPTR(0x0D760F7A+8))[1]);
+#endif
+ showstate(R_EFLAGS, PSL_C, 'C');
+ showstate(R_EFLAGS, PSL_PF, 'P');
+ showstate(R_EFLAGS, PSL_AF, 'c');
+ showstate(R_EFLAGS, PSL_Z, 'Z');
+ showstate(R_EFLAGS, PSL_N, 'N');
+ showstate(R_EFLAGS, PSL_T, 'T');
+ showstate(R_EFLAGS, PSL_I, 'I');
+ showstate(R_EFLAGS, PSL_D, 'D');
+ showstate(R_EFLAGS, PSL_V, 'V');
+ showstate(R_EFLAGS, PSL_NT, 'n');
+ showstate(R_EFLAGS, PSL_RF, 'r');
+ showstate(R_EFLAGS, PSL_VM, 'v');
+ showstate(R_EFLAGS, PSL_AC, 'a');
+ showstate(R_EFLAGS, PSL_VIF, 'i');
+ showstate(R_EFLAGS, PSL_VIP, 'p');
+ putc('\n', debugf);
+}
OpenPOWER on IntegriCloud