Release 961222
[wine/multimedia.git] / debugger / dbg.y
bloba7ab4f74f26cc0790656302f5bb32103c48a395e
1 %{
2 /*
3 * Parser for command lines in the Wine debugger
5 * Copyright 1993 Eric Youngdale
6 * Copyright 1995 Morten Welinder
7 */
9 #include <stdio.h>
10 #include <signal.h>
11 #include <unistd.h>
12 #include "class.h"
13 #include "module.h"
14 #include "options.h"
15 #include "queue.h"
16 #include "win.h"
17 #include "debugger.h"
19 extern FILE * yyin;
20 unsigned int dbg_mode = 0;
21 int curr_frame = 0;
23 static enum exec_mode dbg_exec_mode = EXEC_CONT;
25 void issue_prompt(void);
26 void mode_command(int);
27 void flush_symbols(void);
28 int yylex(void);
29 int yyerror(char *);
33 %union
35 DBG_ADDR address;
36 enum debug_regs reg;
37 char * string;
38 int integer;
41 %token tCONT tSTEP tLIST tNEXT tQUIT tHELP tBACKTRACE tINFO tWALK tUP tDOWN
42 %token tENABLE tDISABLE tBREAK tDELETE tSET tMODE tPRINT tEXAM tDEFINE tABORT
43 %token tCLASS tMODULE tSTACK tSEGMENTS tREGS tWND tQUEUE tLOCAL
44 %token tNO_SYMBOL tEOL
45 %token tSYMBOLFILE
46 %token tFRAME
49 %token <string> tIDENTIFIER
50 %token <integer> tNUM tFORMAT
51 %token <reg> tREG
53 /* %left ',' */
54 /* %left '=' OP_OR_EQUAL OP_XOR_EQUAL OP_AND_EQUAL OP_SHL_EQUAL \
55 OP_SHR_EQUAL OP_PLUS_EQUAL OP_MINUS_EQUAL \
56 OP_TIMES_EQUAL OP_DIVIDE_EQUAL OP_MODULO_EQUAL */
57 /* %left OP_COND */ /* ... ? ... : ... */
58 %left OP_LOR
59 %left OP_LAND
60 %left '|'
61 %left '^'
62 %left '&'
63 %left OP_EQ OP_NE
64 %left '<' '>' OP_LE OP_GE
65 %left OP_SHL OP_SHR
66 %left '+' '-'
67 %left '*' '/' '%'
68 %left OP_SIGN '!' '~' OP_DEREF /* OP_INC OP_DEC OP_ADDR */
69 %nonassoc ':'
71 %type <integer> expr
72 %type <address> addr segaddr symbol
76 input: line { issue_prompt(); }
77 | input line { issue_prompt(); }
79 line: command
80 | tEOL
81 | error tEOL { yyerrok; }
83 command:
84 tQUIT tEOL { exit(0); }
85 | tHELP tEOL { DEBUG_Help(); }
86 | tCONT tEOL { dbg_exec_mode = EXEC_CONT; return 0; }
87 | tSTEP tEOL { dbg_exec_mode = EXEC_STEP_INSTR; return 0; }
88 | tNEXT tEOL { dbg_exec_mode = EXEC_STEP_OVER; return 0; }
89 | tLIST tEOL { DEBUG_List( NULL, 15 ); }
90 | tLIST addr tEOL { DEBUG_List( &$2, 15 ); }
91 | tABORT tEOL { kill(getpid(), SIGABRT); }
92 | tSYMBOLFILE tIDENTIFIER tEOL { DEBUG_ReadSymbolTable( $2 ); }
93 | tDEFINE tIDENTIFIER addr tEOL { DEBUG_AddSymbol( $2, &$3, NULL ); }
94 | tMODE tNUM tEOL { mode_command($2); }
95 | tENABLE tNUM tEOL { DEBUG_EnableBreakpoint( $2, TRUE ); }
96 | tDISABLE tNUM tEOL { DEBUG_EnableBreakpoint( $2, FALSE ); }
97 | tDELETE tBREAK tNUM tEOL { DEBUG_DelBreakpoint( $3 ); }
98 | tBACKTRACE tEOL { DEBUG_BackTrace(); }
99 | tUP tEOL { DEBUG_SetFrame( curr_frame + 1 ); }
100 | tUP tNUM tEOL { DEBUG_SetFrame( curr_frame + $2 ); }
101 | tDOWN tEOL { DEBUG_SetFrame( curr_frame - 1 ); }
102 | tDOWN tNUM tEOL { DEBUG_SetFrame( curr_frame - $2 ); }
103 | tFRAME expr tEOL { DEBUG_SetFrame( $2 ); }
104 | set_command
105 | x_command
106 | print_command
107 | break_command
108 | info_command
109 | walk_command
111 set_command:
112 tSET tREG '=' expr tEOL { DEBUG_SetRegister( $2, $4 ); }
113 | tSET '*' addr '=' expr tEOL { DEBUG_WriteMemory( &$3, $5 ); }
114 | tSET tIDENTIFIER '=' addr tEOL { if (!DEBUG_SetSymbolValue( $2, &$4 ))
116 fprintf( stderr,
117 "Symbol %s not found\n", $2 );
118 YYERROR;
122 x_command:
123 tEXAM addr tEOL { DEBUG_ExamineMemory( &$2, 1, 'x'); }
124 | tEXAM tFORMAT addr tEOL { DEBUG_ExamineMemory( &$3, $2>>8, $2&0xff ); }
126 print_command:
127 tPRINT addr tEOL { DEBUG_Print( &$2, 1, 'x' ); }
128 | tPRINT tFORMAT addr tEOL { DEBUG_Print( &$3, $2 >> 8, $2 & 0xff ); }
130 break_command:
131 tBREAK '*' addr tEOL { DEBUG_AddBreakpoint( &$3 ); }
132 | tBREAK symbol tEOL { DEBUG_AddBreakpoint( &$2 ); }
133 | tBREAK symbol '+' expr tEOL { DBG_ADDR addr = $2;
134 addr.off += $4;
135 DEBUG_AddBreakpoint( &addr );
137 | tBREAK tEOL { DBG_ADDR addr = { CS_reg(DEBUG_context),
138 EIP_reg(DEBUG_context) };
139 DEBUG_AddBreakpoint( &addr );
142 info_command:
143 tINFO tBREAK tEOL { DEBUG_InfoBreakpoints(); }
144 | tINFO tCLASS expr tEOL { CLASS_DumpClass( (CLASS *)$3 ); }
145 | tINFO tMODULE expr tEOL { MODULE_DumpModule( $3 ); }
146 | tINFO tQUEUE expr tEOL { QUEUE_DumpQueue( $3 ); }
147 | tINFO tREGS tEOL { DEBUG_InfoRegisters(); }
148 | tINFO tSEGMENTS expr tEOL { LDT_Print( SELECTOR_TO_ENTRY($3), 1 ); }
149 | tINFO tSEGMENTS tEOL { LDT_Print( 0, -1 ); }
150 | tINFO tSTACK tEOL { DEBUG_InfoStack(); }
151 | tINFO tWND expr tEOL { WIN_DumpWindow( $3 ); }
152 | tINFO tLOCAL tEOL { DEBUG_InfoLocals(); }
154 walk_command:
155 tWALK tCLASS tEOL { CLASS_WalkClasses(); }
156 | tWALK tMODULE tEOL { MODULE_WalkModules(); }
157 | tWALK tQUEUE tEOL { QUEUE_WalkQueues(); }
158 | tWALK tWND tEOL { WIN_WalkWindows( 0, 0 ); }
159 | tWALK tWND tNUM tEOL { WIN_WalkWindows( $3, 0 ); }
161 symbol:
162 tIDENTIFIER { if (!DEBUG_GetSymbolValue( $1, -1, &$$ ))
164 fprintf( stderr, "Symbol %s not found\n", $1 );
165 YYERROR;
168 | tIDENTIFIER ':' tNUM { if (!DEBUG_GetSymbolValue( $1, $3, &$$ ))
170 fprintf( stderr, "No code at %s:%d\n", $1, $3 );
171 YYERROR;
175 addr:
176 expr { $$.seg = 0xffffffff; $$.off = $1; }
177 | segaddr { $$ = $1; }
179 segaddr:
180 expr ':' expr { $$.seg = $1; $$.off = $3; }
181 | symbol { $$ = $1; }
182 | symbol '+' expr { $$ = $1; $$.off += $3; }
183 | symbol '-' expr { $$ = $1; $$.off -= $3; }
185 expr:
186 tNUM { $$ = $1; }
187 | tREG { $$ = DEBUG_GetRegister($1); }
188 | expr OP_LOR expr { $$ = $1 || $3; }
189 | expr OP_LAND expr { $$ = $1 && $3; }
190 | expr '|' expr { $$ = $1 | $3; }
191 | expr '&' expr { $$ = $1 & $3; }
192 | expr '^' expr { $$ = $1 ^ $3; }
193 | expr OP_EQ expr { $$ = $1 == $3; }
194 | expr '>' expr { $$ = $1 > $3; }
195 | expr '<' expr { $$ = $1 < $3; }
196 | expr OP_GE expr { $$ = $1 >= $3; }
197 | expr OP_LE expr { $$ = $1 <= $3; }
198 | expr OP_NE expr { $$ = $1 != $3; }
199 | expr OP_SHL expr { $$ = (unsigned)$1 << $3; }
200 | expr OP_SHR expr { $$ = (unsigned)$1 >> $3; }
201 | expr '+' expr { $$ = $1 + $3; }
202 | expr '-' expr { $$ = $1 - $3; }
203 | expr '*' expr { $$ = $1 * $3; }
204 | expr '/' expr { if ($3)
205 if ($3 == -1 && $1 == 0x80000000l)
206 yyerror ("Division overflow");
207 else $$ = $1 / $3;
208 else yyerror ("Division by zero");
210 | expr '%' expr { if ($3)
211 if ($3 == -1 && $1 == 0x80000000l)
212 $$ = 0; /* A sensible result in this case. */
213 else $$ = $1 % $3;
214 else yyerror ("Division by zero");
216 | '-' expr %prec OP_SIGN { $$ = -$2; }
217 | '+' expr %prec OP_SIGN { $$ = $2; }
218 | '!' expr { $$ = !$2; }
219 | '~' expr { $$ = ~$2; }
220 | '(' expr ')' { $$ = $2; }
221 /* For parser technical reasons we can't use "addr" here. */
222 | '*' expr %prec OP_DEREF { DBG_ADDR addr = { 0xffffffff, $2 };
223 $$ = DEBUG_ReadMemory( &addr ); }
224 | '*' segaddr %prec OP_DEREF { $$ = DEBUG_ReadMemory( &$2 ); }
228 void
229 issue_prompt(){
230 #ifdef DONT_USE_READLINE
231 fprintf(stderr,"Wine-dbg>");
232 #endif
235 void mode_command(int newmode)
237 if ((newmode == 16) || (newmode == 32)) dbg_mode = newmode;
238 else fprintf(stderr,"Invalid mode (use 16 or 32)\n");
243 /***********************************************************************
244 * DEBUG_EnterDebugger
246 * Force an entry into the debugger.
248 void DEBUG_EnterDebugger(void)
250 kill( getpid(), SIGHUP );
254 /***********************************************************************
255 * DebugBreak16 (KERNEL.203)
257 void DebugBreak16( SIGCONTEXT *regs )
259 const char *module = MODULE_GetModuleName( GetExePtr(GetCurrentTask()) );
260 fprintf( stderr, "%s called DebugBreak\n", module ? module : "???" );
261 wine_debug( SIGTRAP, regs );
265 void wine_debug( int signal, SIGCONTEXT *regs )
267 static int loaded_symbols = 0;
268 char SymbolTableFile[256];
269 int instr_len = 0, newmode;
270 BOOL32 ret_ok;
271 #ifdef YYDEBUG
272 yydebug = 0;
273 #endif
275 yyin = stdin;
276 DEBUG_context = regs;
278 DEBUG_SetBreakpoints( FALSE );
280 if (!loaded_symbols)
282 loaded_symbols++;
284 * In some cases we can read the stabs information directly
285 * from the executable. If this is the case, we don't need
286 * to bother with trying to read a symbol file, as the stabs
287 * also have line number and local variable information.
288 * As long as gcc is used for the compiler, stabs will
289 * be the default. On SVr4, DWARF could be used, but we
290 * don't grok that yet, and in this case we fall back to using
291 * the wine.sym file.
293 if( DEBUG_ReadExecutableDbgInfo() == FALSE )
295 PROFILE_GetWineIniString( "wine", "SymbolTableFile", "wine.sym",
296 SymbolTableFile, sizeof(SymbolTableFile));
297 DEBUG_ReadSymbolTable( SymbolTableFile );
301 * Read COFF, MSC, etc debug information that we noted when we
302 * started up the executable.
304 DEBUG_ProcessDeferredDebug();
306 DEBUG_LoadEntryPoints();
309 if ((signal != SIGTRAP) || !DEBUG_ShouldContinue( regs, dbg_exec_mode ))
311 DBG_ADDR addr;
313 addr.seg = CS_reg(DEBUG_context);
314 addr.off = EIP_reg(DEBUG_context);
315 DBG_FIX_ADDR_SEG( &addr, 0 );
317 /* Put the display in a correct state */
319 XUngrabPointer( display, CurrentTime );
320 XUngrabServer( display );
321 XFlush( display );
323 if (!addr.seg) newmode = 32;
324 else newmode = (GET_SEL_FLAGS(addr.seg) & LDT_FLAGS_32BIT) ? 32 : 16;
326 if (newmode != dbg_mode)
327 fprintf(stderr,"In %d bit mode.\n", dbg_mode = newmode);
329 if (signal != SIGTRAP) /* This is a real crash, dump some info */
331 DEBUG_InfoRegisters();
332 DEBUG_InfoStack();
333 if (dbg_mode == 16)
335 LDT_Print( SELECTOR_TO_ENTRY(DS_reg(DEBUG_context)), 1 );
336 if (ES_reg(DEBUG_context) != DS_reg(DEBUG_context))
337 LDT_Print( SELECTOR_TO_ENTRY(ES_reg(DEBUG_context)), 1 );
339 DEBUG_BackTrace();
342 /* Show where we crashed */
343 curr_frame = 0;
344 DEBUG_PrintAddress( &addr, dbg_mode, TRUE );
345 fprintf(stderr,": ");
346 if (DBG_CHECK_READ_PTR( &addr, 1 ))
348 DEBUG_Disasm( &addr );
349 fprintf(stderr,"\n");
350 instr_len = addr.off - EIP_reg(DEBUG_context);
353 ret_ok = 0;
356 issue_prompt();
357 yyparse();
358 flush_symbols();
359 addr.seg = CS_reg(DEBUG_context);
360 addr.off = EIP_reg(DEBUG_context);
361 DBG_FIX_ADDR_SEG( &addr, 0 );
362 ret_ok = DEBUG_ValidateRegisters();
363 if (ret_ok) ret_ok = DBG_CHECK_READ_PTR( &addr, 1 );
364 } while (!ret_ok);
367 DEBUG_RestartExecution( regs, dbg_exec_mode, instr_len );
371 int yyerror(char * s)
373 fprintf(stderr,"%s\n", s);
374 return 0;