kernel: Use hashdestroy() to free hash tables allocated with hashinit().
[dragonfly.git] / usr.bin / doscmd / debug.c
1 /*
2  * Copyright (c) 1996
3  *      Michael Smith, All rights reserved.
4  * Copyright (c) 1992, 1993, 1996
5  *      Berkeley Software Design, Inc.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *      This product includes software developed by Berkeley Software
18  *      Design, Inc.
19  *
20  * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  *
32  * from: BSDI doscmd.c,v 2.3 1996/04/08 19:32:30 bostic Exp
33  *
34  * $FreeBSD: src/usr.bin/doscmd/debug.c,v 1.3.2.2 2002/04/25 11:04:50 tg Exp $
35  * $DragonFly: src/usr.bin/doscmd/debug.c,v 1.2 2003/06/17 04:29:25 dillon Exp $
36  */
37
38 #include <stdarg.h>
39
40 #include "doscmd.h"
41 #include "tty.h"
42
43 /* debug output goes here */
44 FILE *debugf;
45
46 /* see doscmd.h for flag names */
47 int debug_flags = D_ALWAYS;
48
49 /* include register dumps when reporting unknown interrupts */
50 int vflag = 0;
51
52 /* interrupts to trace */
53 #define BPW     (sizeof(u_long) << 3)
54 u_long debug_ints[256/BPW];
55
56 /* Debug flag manipulation */
57 void
58 debug_set(int x)
59 {
60     x &= 0xff;
61     debug_ints[x/BPW] |= 1 << (x & (BPW - 1));
62 }
63
64 void
65 debug_unset(int x)
66 {
67     x &= 0xff;
68     debug_ints[x/BPW] &= ~(1 << (x & (BPW - 1)));
69 }
70
71 u_long
72 debug_isset(int x)
73 {
74     x &= 0xff;
75     return(debug_ints[x/BPW] & (1 << (x & (BPW - 1))));
76 }
77
78
79 /*
80 ** Emit a debugging message if (flags) matches the current
81 ** debugging mode.
82 */
83 void
84 debug(int flags, const char *fmt, ...)
85 {
86     va_list args;
87
88     if (flags & (debug_flags & ~0xff)) {
89         if ((debug_flags & 0xff) == 0
90             && (flags & (D_ITRAPS | D_TRAPS))
91             && !debug_isset(flags & 0xff))
92             return;
93         va_start (args, fmt);
94         vfprintf (debugf, fmt, args);
95         va_end (args);
96     }
97 }
98
99 /*
100 ** Emit a terminal error message and exit
101 */
102 void
103 fatal(const char *fmt, ...)
104 {
105     va_list args;
106
107     dead = 1;
108
109     if (xmode) {
110         char buf[1024];
111         const char *m;
112
113         va_start (args, fmt);
114         vfprintf (debugf, fmt, args);
115         vsprintf (buf, fmt, args);
116         va_end (args);
117         
118         tty_move(23, 0);
119         for (m = buf; *m; ++m)
120             tty_write(*m, 0x0400);
121
122         tty_move(24, 0);
123         for (m = "(PRESS <CTRL-ALT> ANY MOUSE BUTTON TO exit)"; *m; ++m)
124             tty_write(*m, 0x0900);
125         tty_move(-1, -1);
126         for (;;)
127             tty_pause();
128     }
129
130     va_start (args, fmt);
131     fprintf (debugf, "doscmd: fatal error ");
132     vfprintf (debugf, fmt, args);
133     va_end (args);
134     quit (1);
135 }
136
137 /*
138 ** Emit a register dump (usually when dying)
139 */
140 void
141 dump_regs(regcontext_t *REGS)
142 {
143     u_char      *addr;
144     int         i;
145     char        buf[100];
146
147     debug (D_ALWAYS, "\n");
148     debug (D_ALWAYS, "ax=%04x bx=%04x cx=%04x dx=%04x\n", R_AX, R_BX, R_CX, R_DX);
149     debug (D_ALWAYS, "si=%04x di=%04x sp=%04x bp=%04x\n", R_SI, R_DI, R_SP, R_BP);
150     debug (D_ALWAYS, "cs=%04x ss=%04x ds=%04x es=%04x\n", R_CS, R_SS, R_DS, R_ES);
151     debug (D_ALWAYS, "ip=%x eflags=%lx\n", R_IP, R_EFLAGS);
152
153     addr = (u_char *)MAKEPTR(R_CS, R_IP);
154
155     for (i = 0; i < 16; i++)
156         debug (D_ALWAYS, "%02x ", addr[i]);
157     debug (D_ALWAYS, "\n");
158
159     addr = (char *)MAKEPTR(R_CS, R_IP);
160     i386dis(R_CS, R_IP, addr, buf, 0);
161
162     debug (D_ALWAYS, "%s\n", buf);
163 }
164
165 /*
166 ** Unknown interrupt error messages
167 */
168 void
169 unknown_int2(int maj, int min, regcontext_t *REGS)
170 {
171     if (vflag) dump_regs(REGS);
172     printf("Unknown interrupt %02x function %02x\n", maj, min);
173     R_FLAGS |= PSL_C;
174 }
175
176 void
177 unknown_int3(int maj, int min, int sub, regcontext_t *REGS)
178 {
179     if (vflag) dump_regs(REGS);
180     printf("Unknown interrupt %02x function %02x subfunction %02x\n",
181            maj, min, sub);
182     R_FLAGS |= PSL_C;
183 }
184
185 void
186 unknown_int4(int maj, int min, int sub, int ss, regcontext_t *REGS)
187 {
188     if (vflag) dump_regs(REGS);
189     printf("Unknown interrupt %02x function %02x subfunction %02x %02x\n",
190            maj, min, sub, ss);
191     R_FLAGS |= PSL_C;
192 }
193