1 | /*
|
---|
2 | * misc.c for mdb
|
---|
3 | */
|
---|
4 |
|
---|
5 | #include "mdb.h"
|
---|
6 | #include <ctype.h>
|
---|
7 | #include <stdio.h>
|
---|
8 | #include <stdlib.h>
|
---|
9 | #include <sys/stat.h>
|
---|
10 | #define ptrace mdbtrace
|
---|
11 | #include <sys/ptrace.h>
|
---|
12 | #include "proto.h"
|
---|
13 |
|
---|
14 | FORWARD _PROTOTYPE( void pr_ascii , (long val , int size ));
|
---|
15 |
|
---|
16 | /* Print ascii */
|
---|
17 | PRIVATE void pr_ascii(val, size)
|
---|
18 | long val;
|
---|
19 | int size;
|
---|
20 | {
|
---|
21 | int i;
|
---|
22 | int v;
|
---|
23 | int sh;
|
---|
24 |
|
---|
25 | #ifdef BYTES_SWAPPED
|
---|
26 | sh = 8 * size;
|
---|
27 | #else
|
---|
28 | sh = 0;
|
---|
29 | #endif
|
---|
30 |
|
---|
31 | for (i = 0; i < size; i++) {
|
---|
32 | v = (int) (val >> sh) & 0xFF;
|
---|
33 | #ifdef BYTES_SWAPPED
|
---|
34 | sh -= 8;
|
---|
35 | #else
|
---|
36 | sh += 8;
|
---|
37 | #endif
|
---|
38 | Printf(isprint(v) ? "%c" : "\\%03o", v);
|
---|
39 | }
|
---|
40 | Printf("\n");
|
---|
41 | }
|
---|
42 |
|
---|
43 | /* Dump stack */
|
---|
44 | PUBLIC void dump_stack(cnt)
|
---|
45 | long cnt;
|
---|
46 | {
|
---|
47 | vir_bytes v, vi;
|
---|
48 | long val, sp;
|
---|
49 | int num, size, nmode;
|
---|
50 |
|
---|
51 | size = INTSIZE; /* size of stack element */
|
---|
52 | num = (int) cnt;
|
---|
53 | if (num <= 0) num = 0;
|
---|
54 | if (num > sk_size) num = (int) sk_size / size;
|
---|
55 | nmode = num; /* Save mode */
|
---|
56 |
|
---|
57 | /* Get current SP */
|
---|
58 | sp = get_reg(curpid, reg_addr("sp"));
|
---|
59 |
|
---|
60 | /* Starting address is top of stack seg -1 */
|
---|
61 | vi = (vir_bytes) sk_addr + (vir_bytes) sk_size - size;
|
---|
62 |
|
---|
63 | /* Ending address */
|
---|
64 | v = (vir_bytes) end_addr;
|
---|
65 | if (nmode == 0) v = MAX(v, sp);
|
---|
66 |
|
---|
67 | Printf("Stack Dump SP=%*lx\nAddr\tHex\tAscii\n", 2 * size, sp);
|
---|
68 | do {
|
---|
69 | val = (ptrace(T_GETDATA, curpid, (long) vi, 0L) >> SHIFT(size))
|
---|
70 | & MASK(size);
|
---|
71 | Printf("%*lx\t", 2 * ADDRSIZE, (vi >> SHIFT(ADDRSIZE))
|
---|
72 | & MASK(ADDRSIZE));
|
---|
73 | Printf("%*lx\t", 2 * size, val);
|
---|
74 | pr_ascii(val, size);
|
---|
75 | num -= 1;
|
---|
76 | vi -= size;
|
---|
77 | } while (vi >= v && (nmode ? num > 0 : 1));
|
---|
78 |
|
---|
79 | }
|
---|
80 |
|
---|
81 |
|
---|
82 | /* Get file size */
|
---|
83 | PUBLIC off_t file_size(fd)
|
---|
84 | int fd;
|
---|
85 | {
|
---|
86 | struct stat st;
|
---|
87 |
|
---|
88 | if(fstat(fd,&st) <0 ) {
|
---|
89 | Printf("Cannot stat\n");
|
---|
90 | return 0L;
|
---|
91 | }
|
---|
92 | else
|
---|
93 | return st.st_size;
|
---|
94 | }
|
---|
95 |
|
---|
96 | /* Print help page */
|
---|
97 | PUBLIC void help_page()
|
---|
98 | {
|
---|
99 | outstr("\nHelp for mdb. For more details, type 'command ?'\n");
|
---|
100 | outstr("!#\t- Shell escape / Set Variable or register\n");
|
---|
101 | outstr("Tt\t- Current call / Backtrace all\n");
|
---|
102 | outstr("/nsf\t- Display for n size s with format f\n");
|
---|
103 | outstr("Xx [n]\t- Disasm / & display reg for n instructions\n");
|
---|
104 | outstr("Rr a\t- Run / with arguments a\n");
|
---|
105 | outstr("Cc [n]\t- Continue with current signal / no signal n times\n");
|
---|
106 | outstr("Ii [n]\t- Single step with / no signal for n instructions\n");
|
---|
107 | outstr("Mm t n\t- Trace until / Stop when modified t type for n instructions\n");
|
---|
108 | outstr("k \t- Kill traced process\n");
|
---|
109 | outstr("Bb\t- Display / Set Break-pt\n");
|
---|
110 | outstr("Dd\t- Delete all / one break-points\n");
|
---|
111 | outstr("P\t- Toggle Paging\n");
|
---|
112 | outstr("Ll name\t- Log to file name / and to standard output\n");
|
---|
113 | #ifdef DEBUG
|
---|
114 | outstr("Vv\t- Version info / Toggle debug flag\n");
|
---|
115 | #else
|
---|
116 | outstr("V\t- Version info\n");
|
---|
117 | #endif
|
---|
118 | outstr("e [t]\t- List symbols for type t\n");
|
---|
119 | outstr("y\t- Print segment mappings\n");
|
---|
120 | outstr("s [n]\t- Dump stack for n words\n");
|
---|
121 | #if SYSCALLS_SUPPORT
|
---|
122 | outstr("z [a]\t- Trace syscalls with address a\n");
|
---|
123 | #endif
|
---|
124 | outstr("? \t- Help - this screen\n");
|
---|
125 | outstr("@ file\t- Execute commands from file\n");
|
---|
126 | outstr("Qq\t- Quit / and kill traced process\n");
|
---|
127 | #ifdef DEBUG
|
---|
128 | outstr("Usage: mdb -x debug-level [-Ll]logfile exec-file core-file @command-file\n");
|
---|
129 | #else
|
---|
130 | outstr("Usage: mdb [-Ll]logfile exec-file core-file @command-file\n");
|
---|
131 | #endif
|
---|
132 | outstr(" mdb [-fc] file\n");
|
---|
133 | }
|
---|
134 |
|
---|
135 | PUBLIC void version_info()
|
---|
136 | {
|
---|
137 | Printf("\nmdb version %s.%d for Minix", MDBVERSION, MDBBUILD );
|
---|
138 | Printf(" %s.%s", OS_RELEASE, OS_VERSION);
|
---|
139 | #ifdef MINIX_PC
|
---|
140 | #ifdef __i386
|
---|
141 | Printf(" (32-bit)");
|
---|
142 | #else
|
---|
143 | Printf(" (16-bit)");
|
---|
144 | #endif
|
---|
145 | #endif
|
---|
146 | #ifdef MINIX_ST
|
---|
147 | Printf("-ST");
|
---|
148 | #endif
|
---|
149 | Printf("\n");
|
---|
150 | }
|
---|
151 |
|
---|
152 | /* Print help message on command */
|
---|
153 | PUBLIC void help_on(h)
|
---|
154 | int h;
|
---|
155 | {
|
---|
156 |
|
---|
157 | switch (h) {
|
---|
158 | case '/':
|
---|
159 | outstr("<address> /nsf\t- Display for n items of size s with format f from address\n");
|
---|
160 | outstr("\t n defaults to 1\n");
|
---|
161 | outstr("\t s defaults to size of int\n");
|
---|
162 | outstr("\t can be b for byte h for short l for long\n");
|
---|
163 | outstr("\t f defaults to d for decimal\n");
|
---|
164 | outstr("\t can be x X o d D c s or u as in printf\n");
|
---|
165 | outstr("\t y treat value as address\n");
|
---|
166 | outstr("\t i disasm\n");
|
---|
167 | break;
|
---|
168 | case '@':
|
---|
169 | outstr("@ file\t- Execute commands from file\n");
|
---|
170 | break;
|
---|
171 | case '#':
|
---|
172 | outstr("# <address> cs value\t- Set Variable(s) at address to value\n");
|
---|
173 | outstr("\t\t\t for c count and size s\n");
|
---|
174 | outstr("\t\t\t b for byte h for short or l for long\n");
|
---|
175 | outstr("\t\t\t Count or size must be specified\n");
|
---|
176 | outstr("# $xx value\t\t- Set register $xx to value\n");
|
---|
177 | break;
|
---|
178 | case 'C':
|
---|
179 | outstr("C [n]\t- Continue with curent signal n times\n");
|
---|
180 | outstr("\t n defaults to 1\n");
|
---|
181 | break;
|
---|
182 | case 'c':
|
---|
183 | outstr("c [n]\t- Continue with no signal n times\n");
|
---|
184 | outstr("\t n defaults to 1\n");
|
---|
185 | break;
|
---|
186 | case 'e':
|
---|
187 | outstr("e [t]\t- List symbols for type t\n");
|
---|
188 | break;
|
---|
189 | case 's':
|
---|
190 | outstr("s [n]\t- Dump stack for n words\n");
|
---|
191 | outstr("\t n defaults to whole stack\n");
|
---|
192 | break;
|
---|
193 | case 'I':
|
---|
194 | outstr("I n\t- Single step with signal for n instructions n defaults to 1\n");
|
---|
195 | break;
|
---|
196 | case 'i':
|
---|
197 | outstr("i n\t- Single step with no signal for n instructions n defaults to 1\n");
|
---|
198 | break;
|
---|
199 | case 'M':
|
---|
200 | case 'm':
|
---|
201 | if ( h == 'M')
|
---|
202 | outstr("<address> M t n\t- Trace until\n");
|
---|
203 | else
|
---|
204 | outstr("<address> m t n\t- Stop when\n");
|
---|
205 | outstr("\t\t<address> is modified t type for n instructions\n");
|
---|
206 | outstr("\t\tn defaults to 1\n");
|
---|
207 | outstr("\t\tb for byte h for short l for long defaults to size of int\n");
|
---|
208 | break;
|
---|
209 | case 'T':
|
---|
210 | outstr("T\t- Display current call\n");
|
---|
211 | break;
|
---|
212 | case 't':
|
---|
213 | outstr("t\t- Backtrace all calls\n");
|
---|
214 | break;
|
---|
215 | case '!':
|
---|
216 | outstr("![command]\t- Shell escape or spawn command\n");
|
---|
217 | break;
|
---|
218 | case 'R':
|
---|
219 | outstr("R\t- Run the exec-file\n");
|
---|
220 | break;
|
---|
221 | case 'r':
|
---|
222 | outstr("r [arguments]\t- Run the exec-file with arguments\n");
|
---|
223 | break;
|
---|
224 | case 'k':
|
---|
225 | outstr("k\t- Kill traced process\n");
|
---|
226 | break;
|
---|
227 | case 'B':
|
---|
228 | outstr("B\t- Display all the Break points\n");
|
---|
229 | break;
|
---|
230 | case 'b':
|
---|
231 | outstr("<address> b [commands]\t- Set Break-pt at address\n");
|
---|
232 | outstr("\t\t\t commands will be executed by mdb at break-pt\n");
|
---|
233 | break;
|
---|
234 | case 'D':
|
---|
235 | outstr("D\t- Delete all break-points\n");
|
---|
236 | break;
|
---|
237 | case 'd':
|
---|
238 | outstr("<address> d\t- Delete one break-point at address\n");
|
---|
239 | break;
|
---|
240 | case 'q':
|
---|
241 | outstr("q\t- Quit mdb (and kill traced program)\n");
|
---|
242 | break;
|
---|
243 | case 'Q':
|
---|
244 | outstr("Q\t- Quit mdb immediately\n");
|
---|
245 | break;
|
---|
246 | case 'P':
|
---|
247 | outstr("P\t- Toggle Paging\n");
|
---|
248 | outstr("\t Defaults is OFF\n");
|
---|
249 | break;
|
---|
250 | case 'L':
|
---|
251 | outstr("L name\t- Log to file name\n");
|
---|
252 | outstr("L\t- Reset output to standard output\n");
|
---|
253 | break;
|
---|
254 | case 'l':
|
---|
255 | outstr("l name\t- Log to file name and standard output\n");
|
---|
256 | outstr("l\t- Reset output to standard output\n");
|
---|
257 | outstr("\t Defaults to none\n");
|
---|
258 | break;
|
---|
259 | #ifdef DEBUG
|
---|
260 | case 'v':
|
---|
261 | outstr("v\t- Toggle debug flag\n");
|
---|
262 | break;
|
---|
263 | #endif
|
---|
264 | case 'V':
|
---|
265 | outstr("V\t- Print Version Information for mdb\n");
|
---|
266 | break;
|
---|
267 | case 'X':
|
---|
268 | outstr("<address> X [n] [offset]\t- Disasm for n instructions\n");
|
---|
269 | outstr("\t\t\t Starting at address+offset\n");
|
---|
270 | break;
|
---|
271 | case 'x':
|
---|
272 | outstr("<address> x [n] offset\t- Disasm & display registers for n instructions\n");
|
---|
273 | outstr("\t\t\t Starting at address+offset\n");
|
---|
274 | break;
|
---|
275 | case 'y':
|
---|
276 | outstr("y\t- Print segment mappings\n");
|
---|
277 | break;
|
---|
278 | #if SYSCALLS_SUPPORT
|
---|
279 | case 'z':
|
---|
280 | outstr("z [address]\t- Trace system calls using address\n");
|
---|
281 | outstr("\t\t If the exec-file has symbols, mdb looks for __sendrec\n");
|
---|
282 | break;
|
---|
283 | #endif
|
---|
284 | default:
|
---|
285 | Printf("No help on command '%c' is available\n",h);
|
---|
286 | break;
|
---|
287 | }
|
---|
288 | }
|
---|
289 |
|
---|