Release 950216
[wine.git] / debugger / info.c
blob3f640dab5b6d6f7155df6caf5c3d1416cd5e66c6
1 /*
2 * Wine debugger utility routines
3 * Eric Youngdale
4 * 9/93
5 */
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include "db_disasm.h"
10 #include "regpos.h"
12 extern int * regval;
13 extern unsigned int dbg_mask;
14 extern unsigned int dbg_mode;
16 void application_not_running()
18 fprintf(stderr,"Application not running\n");
21 void print_address(unsigned int addr, FILE * outfile){
22 char * name;
23 extern char * find_nearest_symbol(unsigned int *);
25 name = find_nearest_symbol((unsigned int *) addr);
26 if(name)
27 fprintf(outfile,"0x%8.8x(%s)", addr, name);
28 else
29 fprintf(outfile,"0x%8.8x", addr);
33 #ifdef GNU_DISASM
34 void print_address_info(bfd_vma addr, disassemble_info * info){
35 print_address((unsigned int) addr, info->stream);
38 int print_insn(char *realmemaddr, char *memaddr, FILE *stream, int addrlen){
39 static disassemble_info info;
40 static int initialized = 0;
42 if (!initialized) {
43 INIT_DISASSEMBLE_INFO(info, stderr);
44 info.print_address_func = print_address_info;
45 initialized = 1;
47 info.stream = stream;
48 info.buffer = memaddr;
49 info.buffer_vma = (bfd_vma) realmemaddr;
50 info.buffer_length = 1024;
51 if (addrlen == 16)
52 return print_insn_i286((bfd_vma) realmemaddr, &info);
53 if (addrlen == 32)
54 return print_insn_i386((bfd_vma) realmemaddr, &info);
55 fprintf(stderr, "invalid address length %d.\n", addrlen);
56 return 0;
58 #else
59 void db_task_printsym(unsigned int addr){
60 print_address(addr, stderr);
63 int print_insn(char *realmemaddr, char *memaddr, FILE *stream, int addrlen)
65 if (addrlen == 16)
66 return db_disasm((unsigned int) realmemaddr, 0, 1) -
67 ((unsigned int) realmemaddr);
68 if (addrlen == 32)
69 return db_disasm((unsigned int) realmemaddr, 0, 0) -
70 ((unsigned int) realmemaddr);
71 fprintf(stderr, "invalid address length %d.\n", addrlen);
72 return 0;
74 #endif
76 void info_reg(){
78 if(!regval) {
79 application_not_running();
80 return;
83 fprintf(stderr,"Register dump:\n");
84 /* First get the segment registers out of the way */
85 fprintf(stderr," CS:%4.4x SS:%4.4x DS:%4.4x ES:%4.4x GS:%4.4x FS:%4.4x\n",
86 SC_CS, SC_SS, SC_DS, SC_ES, SC_GS, SC_FS);
88 /* Now dump the main registers */
89 fprintf(stderr," EIP:%8.8x ESP:%8.8x EBP:%8.8x EFLAGS:%8.8x\n",
90 SC_EIP(dbg_mask), SC_ESP(dbg_mask), SC_EBP(dbg_mask), SC_EFLAGS);
92 /* And dump the regular registers */
94 fprintf(stderr," EAX:%8.8x EBX:%8.8x ECX:%8.8x EDX:%8.8x\n",
95 SC_EAX(dbg_mask), SC_EBX(dbg_mask), SC_ECX(dbg_mask), SC_EDX(dbg_mask));
97 /* Finally dump these main registers */
98 fprintf(stderr," EDI:%8.8x ESI:%8.8x\n",
99 SC_EDI(dbg_mask), SC_ESI(dbg_mask));
103 void info_stack(){
104 unsigned int * dump;
105 int i;
107 if(!regval) {
108 application_not_running();
109 return;
112 fprintf(stderr,"Stack dump:\n");
113 dump = (int*) SC_EIP(dbg_mask);
114 for(i=0; i<22; i++)
116 fprintf(stderr," %8.8x", *dump++);
117 if ((i % 8) == 7)
118 fprintf(stderr,"\n");
120 fprintf(stderr,"\n");
124 void examine_memory(int addr, int count, char format){
125 char * pnt;
126 unsigned int * dump;
127 unsigned short int * wdump;
128 int i;
130 if((addr & 0xffff0000) == 0 && dbg_mode == 16)
131 addr |= (format == 'i' ? SC_CS : SC_DS) << 16;
134 if(format != 'i' && count > 1) {
135 print_address(addr, stderr);
136 fprintf(stderr,": ");
140 switch(format){
141 case 's':
142 pnt = (char *) addr;
143 if (count == 1) count = 256;
144 while(*pnt && count) {
145 fputc( *pnt++, stderr);
146 count--;
148 fprintf(stderr,"\n");
149 return;
151 case 'i':
152 for(i=0; i<count; i++) {
153 print_address(addr, stderr);
154 fprintf(stderr,": ");
155 addr += print_insn((char *) addr, (char *) addr, stderr, dbg_mode);
156 fprintf(stderr,"\n");
158 return;
159 case 'x':
160 dump = (unsigned int *) addr;
161 for(i=0; i<count; i++)
163 fprintf(stderr," %8.8x", *dump++);
164 if ((i % 8) == 7) {
165 fprintf(stderr,"\n");
166 print_address((unsigned int) dump, stderr);
167 fprintf(stderr,": ");
170 fprintf(stderr,"\n");
171 return;
173 case 'd':
174 dump = (unsigned int *) addr;
175 for(i=0; i<count; i++)
177 fprintf(stderr," %d", *dump++);
178 if ((i % 8) == 7) {
179 fprintf(stderr,"\n");
180 print_address((unsigned int) dump, stderr);
181 fprintf(stderr,": ");
184 fprintf(stderr,"\n");
185 return;
187 case 'w':
188 wdump = (unsigned short int *) addr;
189 for(i=0; i<count; i++)
191 fprintf(stderr," %x", *wdump++);
192 if ((i % 10) == 7) {
193 fprintf(stderr,"\n");
194 print_address((unsigned int) wdump, stderr);
195 fprintf(stderr,": ");
198 fprintf(stderr,"\n");
199 return;
201 case 'c':
202 pnt = (char *) addr;
203 for(i=0; i<count; i++)
205 if(*pnt < 0x20) {
206 fprintf(stderr," ");
207 pnt++;
208 } else
209 fprintf(stderr," %c", *pnt++);
210 if ((i % 32) == 7) {
211 fprintf(stderr,"\n");
212 print_address((unsigned int) pnt, stderr);
213 fprintf(stderr,": ");
216 fprintf(stderr,"\n");
217 return;
219 case 'b':
220 pnt = (char *) addr;
221 for(i=0; i<count; i++)
223 fprintf(stderr," %02x", (*pnt++) & 0xff);
224 if ((i % 32) == 7) {
225 fprintf(stderr,"\n");
226 print_address((unsigned int) pnt, stderr);
227 fprintf(stderr,": ");
230 fprintf(stderr,"\n");
231 return;
234 /* The rest are fairly straightforward */
236 fprintf(stderr,"examine mem: %x %d %c\n", addr, count, format);
239 char * helptext[] = {
240 "The commands accepted by the Wine debugger are a small subset",
241 "of the commands that gdb would accept. The commands currently",
242 "are:\n",
243 " break *<addr> bt",
244 " disable bpnum enable bpnum",
245 " help quit",
246 " x <expr> cont",
247 " mode [16,32] print <expr>",
248 " set <reg> = <expr> set *<expr> = <expr>",
249 " info [reg,stack,break,segments] symbolfile <filename>",
250 " define <identifier> <expr>",
252 "The 'x' command accepts repeat counts and formats (including 'i') in the",
253 "same way that gdb does.",
255 " The following are examples of legal expressions:",
256 " $eax $eax+0x3 0x1000 ($eip + 256) *$eax *($esp + 3)",
257 " Also, a nm format symbol table can be read from a file using the",
258 " symbolfile command. Symbols can also be defined individually with",
259 " the define command.",
261 NULL};
263 void dbg_help(){
264 int i;
265 i = 0;
266 while(helptext[i]) fprintf(stderr,"%s\n", helptext[i++]);
270 struct frame{
271 union{
272 struct {
273 unsigned short saved_bp;
274 unsigned short saved_ip;
275 unsigned short saved_cs;
276 } win16;
277 struct {
278 unsigned long saved_bp;
279 unsigned long saved_ip;
280 unsigned short saved_cs;
281 } win32;
282 } u;
286 void dbg_bt(){
287 struct frame * frame;
288 unsigned short cs;
289 int frameno = 0;
291 if(!regval) {
292 application_not_running();
293 return;
296 frame = (struct frame *) ((SC_EBP(dbg_mask) & ~1) | (SC_SS << 16));
298 fprintf(stderr,"Backtrace:\n");
299 fprintf(stderr,"%d ",frameno);
300 print_address(frame->u.win32.saved_ip,stderr);
301 cs = SC_CS;
302 while((cs & 3) == 3) {
303 /* See if in 32 bit mode or not. Assume GDT means 32 bit. */
304 if ((cs & 7) != 7) {
305 void CallTo32();
306 fprintf(stderr,"\n%d ",frameno++);
307 print_address(frame->u.win32.saved_ip,stderr);
308 if(frame->u.win32.saved_ip<((unsigned long)CallTo32+1000))break;
309 frame = (struct frame *) frame->u.win32.saved_bp;
310 } else {
311 cs = frame->u.win16.saved_cs;
312 fprintf(stderr,"%d %4.4x:%4.4x\n", frameno++, cs,
313 frame->u.win16.saved_ip);
314 frame = (struct frame *) ((frame->u.win16.saved_bp & ~1) |
315 (SC_SS << 16));
318 putchar('\n');