Release 940518
[wine/multimedia.git] / debugger / info.c
blobb4b2358b3477f7ed69e0c588291775ff7508421a
1 /*
2 * Wine debugger utility routines
3 * Eric Youngdale
4 * 9/93
5 */
7 #include <stdio.h>
8 #include "opcodes/dis-asm.h"
9 #include "regpos.h"
11 extern int * regval;
12 extern unsigned int dbg_mask;
13 extern unsigned int dbg_mode;
15 void application_not_running()
17 fprintf(stderr,"Application not running\n");
20 void print_address(unsigned int addr, FILE * outfile){
21 char * name;
22 extern char * find_nearest_symbol(unsigned int *);
24 name = find_nearest_symbol((unsigned int *) addr);
25 if(name)
26 fprintf(outfile,"0x%8.8x(%s)", addr, name);
27 else
28 fprintf(outfile,"0x%8.8x", addr);
32 void print_address_info(bfd_vma addr, disassemble_info * info){
33 print_address((unsigned int) addr, info->stream);
36 int print_insn(char *realmemaddr, char *memaddr, FILE *stream, int addrlen){
37 static disassemble_info info;
38 static int initialized = 0;
40 if (!initialized) {
41 INIT_DISASSEMBLE_INFO(info, stderr);
42 info.print_address_func = print_address_info;
43 initialized = 1;
45 info.stream = stream;
46 info.buffer = memaddr;
47 info.buffer_vma = (bfd_vma) realmemaddr;
48 info.buffer_length = 1024;
49 if (addrlen == 16)
50 return print_insn_i286((bfd_vma) realmemaddr, &info);
51 if (addrlen == 32)
52 return print_insn_i386((bfd_vma) realmemaddr, &info);
53 fprintf(stderr, "invalid address length %d.\n", addrlen);
54 return 0;
57 void info_reg(){
59 if(!regval) {
60 application_not_running();
61 return;
64 fprintf(stderr,"Register dump:\n");
65 /* First get the segment registers out of the way */
66 fprintf(stderr," CS:%4.4x SS:%4.4x DS:%4.4x ES:%4.4x GS:%4.4x FS:%4.4x\n",
67 SC_CS, SC_SS, SC_DS, SC_ES, SC_GS, SC_FS);
69 /* Now dump the main registers */
70 fprintf(stderr," EIP:%8.8x ESP:%8.8x EBP:%8.8x EFLAGS:%8.8x\n",
71 SC_EIP(dbg_mask), SC_ESP(dbg_mask), SC_EBP(dbg_mask), SC_EFLAGS);
73 /* And dump the regular registers */
75 fprintf(stderr," EAX:%8.8x EBX:%8.8x ECX:%8.8x EDX:%8.8x\n",
76 SC_EAX(dbg_mask), SC_EBX(dbg_mask), SC_ECX(dbg_mask), SC_EDX(dbg_mask));
78 /* Finally dump these main registers */
79 fprintf(stderr," EDI:%8.8x ESI:%8.8x\n",
80 SC_EDI(dbg_mask), SC_ESI(dbg_mask));
84 void info_stack(){
85 unsigned int * dump;
86 int i;
88 if(!regval) {
89 application_not_running();
90 return;
93 fprintf(stderr,"Stack dump:\n");
94 dump = (int*) SC_EIP(dbg_mask);
95 for(i=0; i<22; i++)
97 fprintf(stderr," %8.8x", *dump++);
98 if ((i % 8) == 7)
99 fprintf(stderr,"\n");
101 fprintf(stderr,"\n");
105 void examine_memory(int addr, int count, char format){
106 char * pnt;
107 unsigned int * dump;
108 unsigned short int * wdump;
109 int i;
111 if((addr & 0xffff0000) == 0 && dbg_mode == 16)
112 addr |= (format == 'i' ? SC_CS : SC_DS) << 16;
115 if(format != 'i' && count > 1) {
116 print_address(addr, stderr);
117 fprintf(stderr,": ");
121 switch(format){
122 case 's':
123 pnt = (char *) addr;
124 if (count == 1) count = 256;
125 while(*pnt && count) {
126 fputc( *pnt++, stderr);
127 count--;
129 fprintf(stderr,"\n");
130 return;
132 case 'i':
133 for(i=0; i<count; i++) {
134 print_address(addr, stderr);
135 fprintf(stderr,": ");
136 addr += print_insn((char *) addr, (char *) addr, stderr, dbg_mode);
137 fprintf(stderr,"\n");
139 return;
140 case 'x':
141 dump = (unsigned int *) addr;
142 for(i=0; i<count; i++)
144 fprintf(stderr," %8.8x", *dump++);
145 if ((i % 8) == 7) {
146 fprintf(stderr,"\n");
147 print_address((unsigned int) dump, stderr);
148 fprintf(stderr,": ");
151 fprintf(stderr,"\n");
152 return;
154 case 'd':
155 dump = (unsigned int *) addr;
156 for(i=0; i<count; i++)
158 fprintf(stderr," %d", *dump++);
159 if ((i % 8) == 7) {
160 fprintf(stderr,"\n");
161 print_address((unsigned int) dump, stderr);
162 fprintf(stderr,": ");
165 fprintf(stderr,"\n");
166 return;
168 case 'w':
169 wdump = (unsigned short int *) addr;
170 for(i=0; i<count; i++)
172 fprintf(stderr," %x", *wdump++);
173 if ((i % 10) == 7) {
174 fprintf(stderr,"\n");
175 print_address((unsigned int) wdump, stderr);
176 fprintf(stderr,": ");
179 fprintf(stderr,"\n");
180 return;
182 case 'c':
183 pnt = (char *) addr;
184 for(i=0; i<count; i++)
186 if(*pnt < 0x20) {
187 fprintf(stderr," ");
188 pnt++;
189 } else
190 fprintf(stderr," %c", *pnt++);
191 if ((i % 32) == 7) {
192 fprintf(stderr,"\n");
193 print_address((unsigned int) dump, stderr);
194 fprintf(stderr,": ");
197 fprintf(stderr,"\n");
198 return;
200 case 'b':
201 pnt = (char *) addr;
202 for(i=0; i<count; i++)
204 fprintf(stderr," %02.2x", (*pnt++) & 0xff);
205 if ((i % 32) == 7) {
206 fprintf(stderr,"\n");
207 print_address((unsigned int) pnt, stderr);
208 fprintf(stderr,": ");
211 fprintf(stderr,"\n");
212 return;
215 /* The rest are fairly straightforward */
217 fprintf(stderr,"examine mem: %x %d %c\n", addr, count, format);
220 char * helptext[] = {
221 "The commands accepted by the Wine debugger are a small subset",
222 "of the commands that gdb would accept. The commands currently",
223 "are:\n",
224 " info [reg,stack,break]",
225 " break <addr>",
226 " enable bpnum",
227 " disable bpnum",
228 " help",
229 " quit",
230 " print <expr>",
231 " bt",
232 " mode [16,32]",
233 " symbolfile <filename>",
234 " define <identifier> <expr>",
235 " x <expr>",
236 " cont",
237 " set <reg> = <expr>",
238 " set *<expr> = <expr>",
240 "The 'x' command accepts repeat counts and formats (including 'i') in the",
241 "same way that gdb does.",
243 " The following are examples of legal expressions:",
244 " $eax $eax+0x3 0x1000 ($eip + 256) *$eax *($esp + 3)",
245 " Also, a nm format symbol table can be read from a file using the",
246 " symbolfile command. Symbols can also be defined individually with",
247 " the define command.",
249 "The disassembly code seems to work most of the time, but it does get",
250 "a little confused at times. The 16 bit mode probably has not been used",
251 "much so there are probably bugs.",
253 NULL};
255 void dbg_help(){
256 int i;
257 i = 0;
258 while(helptext[i]) fprintf(stderr,"%s\n", helptext[i++]);
262 struct frame{
263 union{
264 struct {
265 unsigned short saved_bp;
266 unsigned short saved_ip;
267 unsigned short saved_cs;
268 } win16;
269 struct {
270 unsigned long saved_bp;
271 unsigned long saved_ip;
272 unsigned short saved_cs;
273 } win32;
274 } u;
278 void dbg_bt(){
279 struct frame * frame;
280 unsigned short cs;
281 int frameno = 0;
283 if(!regval) {
284 application_not_running();
285 return;
288 fprintf(stderr,"Backtrace:\n");
289 fprintf(stderr,"%d: %4.4x:%4.4x\n", frameno++, SC_CS, SC_EIP(dbg_mask));
290 cs = SC_CS;
292 frame = (struct frame *) ((SC_EBP(dbg_mask) & ~1) | (SC_SS << 16));
293 while((cs & 3) == 3) {
294 /* See if in 32 bit mode or not. Assume GDT means 32 bit. */
295 if ((cs & 7) != 7) {
296 cs = frame->u.win32.saved_cs;
297 fprintf(stderr,"%d %4.4x:%4.4x\n", frameno++, cs,
298 frame->u.win32.saved_ip);
299 frame = (struct frame *) frame->u.win32.saved_bp;
300 } else {
301 cs = frame->u.win16.saved_cs;
302 fprintf(stderr,"%d %4.4x:%4.4x\n", frameno++, cs,
303 frame->u.win16.saved_ip);
304 frame = (struct frame *) ((frame->u.win16.saved_bp & ~1) |
305 (SC_SS << 16));