Release 940510
[wine.git] / debugger / info.c
blob0a98d8977a45eedb7ec757269fd170381748298a
1 /*
2 * Wine debugger utility routines
3 * Eric Youngdale
4 * 9/93
5 */
7 #include <stdio.h>
8 #include "regpos.h"
10 extern int * regval;
11 extern unsigned int dbg_mask;
12 extern unsigned int dbg_mode;
14 extern int print_insn(char * memaddr, char * realaddr, FILE * stream, int addrlen);
16 /* THese three helper functions eliminate the need for patching the
17 module from gdb for disassembly of code */
19 void application_not_running()
21 fprintf(stderr,"Application not running\n");
24 void read_memory(char * memaddr, char * buffer, int len){
25 memcpy(buffer, memaddr, len);
28 void fputs_filtered(char * buffer, FILE * outfile){
29 fputs(buffer, outfile);
32 void print_address(unsigned int addr, FILE * outfile){
33 char * name;
34 name = find_nearest_symbol(addr);
35 if(name)
36 fprintf(outfile,"0x%8.8x(%s)", addr, name);
37 else
38 fprintf(outfile,"0x%8.8x", addr);
43 void info_reg(){
45 if(!regval) {
46 application_not_running();
47 return 0;
50 fprintf(stderr,"Register dump:\n");
51 /* First get the segment registers out of the way */
52 fprintf(stderr," CS:%4.4x SS:%4.4x DS:%4.4x ES:%4.4x GS:%4.4x FS:%4.4x\n",
53 SC_CS, SC_SS, SC_DS, SC_ES, SC_GS, SC_FS);
55 /* Now dump the main registers */
56 fprintf(stderr," EIP:%8.8x ESP:%8.8x EBP:%8.8x EFLAGS:%8.8x\n",
57 SC_EIP(dbg_mask), SC_ESP(dbg_mask), SC_EBP(dbg_mask), SC_EFLAGS);
59 /* And dump the regular registers */
61 fprintf(stderr," EAX:%8.8x EBX:%8.8x ECX:%8.8x EDX:%8.8x\n",
62 SC_EAX(dbg_mask), SC_EBX(dbg_mask), SC_ECX(dbg_mask), SC_EDX(dbg_mask));
64 /* Finally dump these main registers */
65 fprintf(stderr," EDI:%8.8x ESI:%8.8x\n",
66 SC_EDI(dbg_mask), SC_ESI(dbg_mask));
70 void info_stack(){
71 unsigned int * dump;
72 int i;
74 if(!regval) {
75 application_not_running();
76 return 0;
79 fprintf(stderr,"Stack dump:\n");
80 dump = (int*) SC_EIP(dbg_mask);
81 for(i=0; i<22; i++)
83 fprintf(stderr," %8.8x", *dump++);
84 if ((i % 8) == 7)
85 fprintf(stderr,"\n");
87 fprintf(stderr,"\n");
91 void examine_memory(int addr, int count, char format){
92 char * pnt;
93 unsigned int * dump;
94 unsigned short int * wdump;
95 int i;
97 if((addr & 0xffff0000) == 0 && dbg_mode == 16)
98 addr |= (format == 'i' ? SC_CS : SC_DS) << 16;
101 if(format != 'i' && count > 1) {
102 print_address(addr, stderr);
103 fprintf(stderr,": ");
107 switch(format){
108 case 's':
109 pnt = (char *) addr;
110 if (count == 1) count = 256;
111 while(*pnt && count) {
112 fputc( *pnt++, stderr);
113 count--;
115 fprintf(stderr,"\n");
116 return;
118 case 'i':
119 for(i=0; i<count; i++) {
120 print_address(addr, stderr);
121 fprintf(stderr,": ");
122 addr += print_insn((char *) addr, (char *) addr, stderr, dbg_mode);
123 fprintf(stderr,"\n");
125 return;
126 case 'x':
127 dump = (unsigned int *) addr;
128 for(i=0; i<count; i++)
130 fprintf(stderr," %8.8x", *dump++);
131 if ((i % 8) == 7) {
132 fprintf(stderr,"\n");
133 print_address((unsigned int) dump, stderr);
134 fprintf(stderr,": ");
137 fprintf(stderr,"\n");
138 return;
140 case 'd':
141 dump = (unsigned int *) addr;
142 for(i=0; i<count; i++)
144 fprintf(stderr," %d", *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 'w':
155 wdump = (unsigned short int *) addr;
156 for(i=0; i<count; i++)
158 fprintf(stderr," %x", *wdump++);
159 if ((i % 10) == 7) {
160 fprintf(stderr,"\n");
161 print_address((unsigned int) wdump, stderr);
162 fprintf(stderr,": ");
165 fprintf(stderr,"\n");
166 return;
168 case 'c':
169 pnt = (char *) addr;
170 for(i=0; i<count; i++)
172 if(*pnt < 0x20) {
173 fprintf(stderr," ");
174 pnt++;
175 } else
176 fprintf(stderr," %c", *pnt++);
177 if ((i % 32) == 7) {
178 fprintf(stderr,"\n");
179 print_address((unsigned int) dump, stderr);
180 fprintf(stderr,": ");
183 fprintf(stderr,"\n");
184 return;
186 case 'b':
187 pnt = (char *) addr;
188 for(i=0; i<count; i++)
190 fprintf(stderr," %02.2x", (*pnt++) & 0xff);
191 if ((i % 32) == 7) {
192 fprintf(stderr,"\n");
193 print_address((unsigned int) pnt, stderr);
194 fprintf(stderr,": ");
197 fprintf(stderr,"\n");
198 return;
201 /* The rest are fairly straightforward */
203 fprintf(stderr,"examine mem: %x %d %c\n", addr, count, format);
206 char * helptext[] = {
207 "The commands accepted by the Wine debugger are a small subset",
208 "of the commands that gdb would accept. The commands currently",
209 "are:\n",
210 " info [reg,stack,break]",
211 " break <addr>",
212 " enable bpnum",
213 " disable bpnum",
214 " help",
215 " quit",
216 " print <expr>",
217 " bt",
218 " mode [16,32]",
219 " symbolfile <filename>",
220 " define <identifier> <expr>",
221 " x <expr>",
222 " cont",
223 " set <reg> = <expr>",
224 " set *<expr> = <expr>",
226 "The 'x' command accepts repeat counts and formats (including 'i') in the",
227 "same way that gdb does.",
229 " The following are examples of legal expressions:",
230 " $eax $eax+0x3 0x1000 ($eip + 256) *$eax *($esp + 3)",
231 " Also, a nm format symbol table can be read from a file using the",
232 " symbolfile command. Symbols can also be defined individually with",
233 " the define command.",
235 "The disassembly code seems to work most of the time, but it does get",
236 "a little confused at times. The 16 bit mode probably has not been used",
237 "much so there are probably bugs. I snagged the file from the gdb-4.7",
238 "source tree, which is what was on my latest cdrom. I should check to see",
239 "if newer versions of gdb have anything substanitally different for the",
240 "disassembler.",
242 NULL};
244 void dbg_help(){
245 int i;
246 i = 0;
247 while(helptext[i]) fprintf(stderr,"%s\n", helptext[i++]);
251 struct frame{
252 union{
253 struct {
254 unsigned short saved_bp;
255 unsigned short saved_ip;
256 unsigned short saved_cs;
257 } win16;
258 struct {
259 unsigned long saved_bp;
260 unsigned long saved_ip;
261 unsigned short saved_cs;
262 } win32;
263 } u;
267 void dbg_bt(){
268 struct frame * frame;
269 unsigned short cs;
270 int frameno = 0;
272 if(!regval) {
273 application_not_running();
274 return 0;
277 fprintf(stderr,"Backtrace:\n");
278 fprintf(stderr,"%d: %4.4x:%4.4x\n", frameno++, SC_CS, SC_EIP(dbg_mask));
279 cs = SC_CS;
281 frame = (struct frame *) ((SC_EBP(dbg_mask) & ~1) | (SC_SS << 16));
282 while((cs & 3) == 3) {
283 /* See if in 32 bit mode or not. Assume GDT means 32 bit. */
284 if ((cs & 7) != 7) {
285 cs = frame->u.win32.saved_cs;
286 fprintf(stderr,"%d %4.4x:%4.4x\n", frameno++, cs,
287 frame->u.win32.saved_ip);
288 frame = (struct frame *) frame->u.win32.saved_bp;
289 } else {
290 cs = frame->u.win16.saved_cs;
291 fprintf(stderr,"%d %4.4x:%4.4x\n", frameno++, cs,
292 frame->u.win16.saved_ip);
293 frame = (struct frame *) ((frame->u.win16.saved_bp & ~1) |
294 (SC_SS << 16));