Release 970415
[wine] / debugger / dbg.y
1 %{
2 /*
3  * Parser for command lines in the Wine debugger
4  *
5  * Copyright 1993 Eric Youngdale
6  * Copyright 1995 Morten Welinder
7  */
8
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 "winnt.h"
18 #include "debugger.h"
19
20 #include "expr.h"
21
22 extern FILE * yyin;
23 unsigned int dbg_mode = 0;
24 int curr_frame = 0;
25
26 static enum exec_mode dbg_exec_mode = EXEC_CONT;
27 static int dbg_exec_count = 0;
28
29 void issue_prompt(void);
30 void mode_command(int);
31 void flush_symbols(void);
32 int yylex(void);
33 int yyerror(char *);
34
35 extern void VIRTUAL_Dump(void);  /* memory/virtual.c */
36
37 %}
38
39 %union
40 {
41     DBG_ADDR         address;
42     enum debug_regs  reg;
43     char *           string;
44     int              integer;
45     struct list_id   listing;
46     struct expr *    expression;
47     struct datatype * type;
48 }
49
50 %token tCONT tSTEP tLIST tNEXT tQUIT tHELP tBACKTRACE tINFO tWALK tUP tDOWN
51 %token tENABLE tDISABLE tBREAK tDELETE tSET tMODE tPRINT tEXAM tABORT
52 %token tCLASS tMAPS tMODULE tSTACK tSEGMENTS tREGS tWND tQUEUE tLOCAL
53 %token tEOL tSTRING
54 %token tFRAME tSHARE tCOND tDISPLAY tUNDISPLAY tDISASSEMBLE
55 %token tSTEPI tNEXTI tFINISH tSHOW tDIR
56 %token <string> tPATH
57 %token <string> tIDENTIFIER tSTRING
58 %token <integer> tNUM tFORMAT
59 %token <reg> tREG
60
61 %token tCHAR tSHORT tINT tLONG tFLOAT tDOUBLE tUNSIGNED tSIGNED 
62 %token tSTRUCT tUNION tENUM
63
64 /* %left ',' */
65 /* %left '=' OP_OR_EQUAL OP_XOR_EQUAL OP_AND_EQUAL OP_SHL_EQUAL \
66          OP_SHR_EQUAL OP_PLUS_EQUAL OP_MINUS_EQUAL \
67          OP_TIMES_EQUAL OP_DIVIDE_EQUAL OP_MODULO_EQUAL */
68 /* %left OP_COND */ /* ... ? ... : ... */
69 %left OP_LOR
70 %left OP_LAND
71 %left '|'
72 %left '^'
73 %left '&'
74 %left OP_EQ OP_NE
75 %left '<' '>' OP_LE OP_GE
76 %left OP_SHL OP_SHR
77 %left '+' '-'
78 %left '*' '/' '%'
79 %left OP_SIGN '!' '~' OP_DEREF /* OP_INC OP_DEC OP_ADDR */
80 %left '.' '[' OP_DRF
81 %nonassoc ':'
82
83 %type <expression> expr lval lvalue 
84 %type <type> type_cast type_expr
85 %type <address> expr_addr lval_addr
86 %type <integer> expr_value
87 %type <string> pathname
88
89 %type <listing> list_arg
90
91 %%
92
93 input: line                    { issue_prompt(); }
94     | input line               { issue_prompt(); }
95
96 line: command 
97     | tEOL
98     | error tEOL               { yyerrok; }
99
100 command:
101       tQUIT tEOL               { exit(0); }
102     | tHELP tEOL               { DEBUG_Help(); }
103     | tHELP tINFO tEOL         { DEBUG_HelpInfo(); }
104     | tCONT tEOL               { dbg_exec_count = 1; 
105                                  dbg_exec_mode = EXEC_CONT; return 0; }
106     | tCONT tNUM tEOL          { dbg_exec_count = $2; 
107                                  dbg_exec_mode = EXEC_CONT; return 0; }
108     | tSTEP tEOL               { dbg_exec_count = 1; 
109                                  dbg_exec_mode = EXEC_STEP_INSTR; return 0; }
110     | tNEXT tEOL               { dbg_exec_count = 1; 
111                                  dbg_exec_mode = EXEC_STEP_OVER; return 0; }
112     | tSTEP tNUM tEOL          { dbg_exec_count = $2; 
113                                  dbg_exec_mode = EXEC_STEP_INSTR; return 0; }
114     | tNEXT tNUM tEOL          { dbg_exec_count = $2; 
115                                  dbg_exec_mode = EXEC_STEP_OVER; return 0; }
116     | tSTEPI tEOL              { dbg_exec_count = 1; 
117                                  dbg_exec_mode = EXEC_STEPI_INSTR; return 0; }
118     | tNEXTI tEOL              { dbg_exec_count = 1; 
119                                  dbg_exec_mode = EXEC_STEPI_OVER; return 0; }
120     | tSTEPI tNUM tEOL         { dbg_exec_count = $2; 
121                                  dbg_exec_mode = EXEC_STEPI_INSTR; return 0; }
122     | tNEXTI tNUM tEOL         { dbg_exec_count = $2; 
123                                  dbg_exec_mode = EXEC_STEPI_OVER; return 0; }
124     | tABORT tEOL              { kill(getpid(), SIGABRT); }
125     | tMODE tNUM tEOL          { mode_command($2); }
126     | tENABLE tNUM tEOL        { DEBUG_EnableBreakpoint( $2, TRUE ); }
127     | tDISABLE tNUM tEOL       { DEBUG_EnableBreakpoint( $2, FALSE ); }
128     | tDELETE tBREAK tNUM tEOL { DEBUG_DelBreakpoint( $3 ); }
129     | tBACKTRACE tEOL          { DEBUG_BackTrace(); }
130     | tUP tEOL                 { DEBUG_SetFrame( curr_frame + 1 );  }
131     | tUP tNUM tEOL            { DEBUG_SetFrame( curr_frame + $2 ); }
132     | tDOWN tEOL               { DEBUG_SetFrame( curr_frame - 1 );  }
133     | tDOWN tNUM tEOL          { DEBUG_SetFrame( curr_frame - $2 ); }
134     | tFRAME tNUM tEOL         { DEBUG_SetFrame( $2 ); }
135     | tFINISH tEOL             { dbg_exec_count = 0;
136                                  dbg_exec_mode = EXEC_FINISH; return 0; }
137     | tSHOW tDIR tEOL          { DEBUG_ShowDir(); }
138     | tDIR pathname tEOL       { DEBUG_AddPath( $2 ); }
139     | tDIR tEOL                { DEBUG_NukePath(); }
140     | tDISPLAY tEOL            { DEBUG_InfoDisplay(); }
141     | tDISPLAY expr tEOL       { DEBUG_AddDisplay($2, 1, 0); }
142     | tDISPLAY tFORMAT expr tEOL { DEBUG_AddDisplay($3, $2 >> 8, $2 & 0xff); }
143     | tDELETE tDISPLAY tNUM tEOL { DEBUG_DelDisplay( $3 ); }
144     | tDELETE tDISPLAY tEOL    { DEBUG_DelDisplay( -1 ); }
145     | tUNDISPLAY tNUM tEOL     { DEBUG_DelDisplay( $2 ); }
146     | tUNDISPLAY tEOL          { DEBUG_DelDisplay( -1 ); }
147     | tCOND tNUM tEOL          { DEBUG_AddBPCondition($2, NULL); }
148     | tCOND tNUM expr tEOL     { DEBUG_AddBPCondition($2, $3); }
149     | list_command
150     | disassemble_command
151     | set_command
152     | x_command
153     | print_command
154     | break_command
155     | info_command
156     | walk_command
157
158 set_command:
159       tSET tREG '=' expr_value tEOL        { DEBUG_SetRegister( $2, $4 ); 
160                                              DEBUG_FreeExprMem(); }
161     | tSET lval_addr '=' expr_value tEOL   { DEBUG_WriteMemory( &$2, $4 ); 
162                                              DEBUG_FreeExprMem(); }
163
164 pathname:
165       tIDENTIFIER                    { $$ = $1; }
166     | tPATH                          { $$ = $1; }
167
168 disassemble_command:
169       tDISASSEMBLE tEOL              { DEBUG_Disassemble( NULL, NULL, 10 ); }
170     | tDISASSEMBLE expr_addr tEOL    { DEBUG_Disassemble( & $2, NULL, 10 ); }
171     | tDISASSEMBLE expr_addr ',' expr_addr tEOL { DEBUG_Disassemble( & $2, & $4, 0 ); }
172
173 list_command:
174       tLIST tEOL               { DEBUG_List( NULL, NULL, 10 ); }
175     | tLIST '-' tEOL           { DEBUG_List( NULL, NULL, -10 ); }
176     | tLIST list_arg tEOL      { DEBUG_List( & $2, NULL, 10 ); }
177     | tLIST ',' list_arg tEOL  { DEBUG_List( NULL, & $3, -10 ); }
178     | tLIST list_arg ',' list_arg tEOL { DEBUG_List( & $2, & $4, 0 ); }
179
180 list_arg:
181       tNUM                     { $$.sourcefile = NULL; $$.line = $1; }
182     | pathname ':' tNUM        { $$.sourcefile = $1; $$.line = $3; }
183     | tIDENTIFIER              { DEBUG_GetFuncInfo( & $$, NULL, $1); }
184     | pathname ':' tIDENTIFIER { DEBUG_GetFuncInfo( & $$, $1, $3); }
185     | '*' expr_addr            { DEBUG_FindNearestSymbol( & $2, FALSE, NULL, 
186                                                         0, & $$ ); 
187                                              DEBUG_FreeExprMem(); }
188
189 x_command:
190       tEXAM expr_addr tEOL     { DEBUG_ExamineMemory( &$2, 1, 'x'); 
191                                              DEBUG_FreeExprMem(); }
192     | tEXAM tFORMAT expr_addr tEOL  { DEBUG_ExamineMemory( &$3, $2>>8, $2&0xff ); 
193                                              DEBUG_FreeExprMem(); }
194
195 print_command:
196       tPRINT expr_addr tEOL    { DEBUG_Print( &$2, 1, 0, 0 ); 
197                                              DEBUG_FreeExprMem(); }
198     | tPRINT tFORMAT expr_addr tEOL { DEBUG_Print( &$3, $2 >> 8, $2 & 0xff, 0 ); 
199                                              DEBUG_FreeExprMem(); }
200
201 break_command:
202       tBREAK '*' expr_addr tEOL { DEBUG_AddBreakpoint( &$3 ); 
203                                              DEBUG_FreeExprMem(); }
204     | tBREAK tIDENTIFIER tEOL  { DBG_ADDR addr;
205                                  if( DEBUG_GetSymbolValue($2, -1, &addr, TRUE) )
206                                    {
207                                      DEBUG_AddBreakpoint( &addr );
208                                    }
209                                  else
210                                    {
211                                      fprintf(stderr,"Unable to add breakpoint\n");
212                                    }
213                                 }
214     | tBREAK tIDENTIFIER ':' tNUM tEOL  { DBG_ADDR addr;
215                                  if( DEBUG_GetSymbolValue($2, $4, &addr, TRUE) )
216                                    {
217                                      DEBUG_AddBreakpoint( &addr );
218                                    }
219                                  else
220                                    {
221                                      fprintf(stderr,"Unable to add breakpoint\n");
222                                    }
223                                 }
224     | tBREAK tNUM tEOL         { struct name_hash *nh;
225                                  DBG_ADDR addr = { NULL,
226                                                    CS_reg(&DEBUG_context),
227                                                    EIP_reg(&DEBUG_context) };
228
229                                  DBG_FIX_ADDR_SEG( &addr, CS_reg(&DEBUG_context) );
230                                  DEBUG_FindNearestSymbol(&addr, TRUE,
231                                                          &nh, 0, NULL);
232                                  if( nh != NULL )
233                                    {
234                                      DEBUG_GetLineNumberAddr(nh, 
235                                                       $2, &addr, TRUE);
236                                      DEBUG_AddBreakpoint( &addr );
237                                    }
238                                  else
239                                    {
240                                      fprintf(stderr,"Unable to add breakpoint\n");
241                                    }
242                                }
243
244     | tBREAK tEOL              { DBG_ADDR addr = { NULL,
245                                                    CS_reg(&DEBUG_context),
246                                                    EIP_reg(&DEBUG_context) };
247                                  DEBUG_AddBreakpoint( &addr );
248                                }
249
250 info_command:
251       tINFO tBREAK tEOL         { DEBUG_InfoBreakpoints(); }
252     | tINFO tCLASS expr_value tEOL    { CLASS_DumpClass( (CLASS *)$3 ); 
253                                              DEBUG_FreeExprMem(); }
254     | tINFO tSHARE tEOL         { DEBUG_InfoShare(); }
255     | tINFO tMODULE expr_value tEOL   { MODULE_DumpModule( $3 ); 
256                                              DEBUG_FreeExprMem(); }
257     | tINFO tQUEUE expr_value tEOL    { QUEUE_DumpQueue( $3 ); 
258                                              DEBUG_FreeExprMem(); }
259     | tINFO tREGS tEOL          { DEBUG_InfoRegisters(); }
260     | tINFO tSEGMENTS expr_value tEOL { LDT_Print( SELECTOR_TO_ENTRY($3), 1 ); 
261                                              DEBUG_FreeExprMem(); }
262     | tINFO tSEGMENTS tEOL      { LDT_Print( 0, -1 ); }
263     | tINFO tSTACK tEOL         { DEBUG_InfoStack(); }
264     | tINFO tMAPS tEOL          { VIRTUAL_Dump(); }
265     | tINFO tWND expr_value tEOL      { WIN_DumpWindow( $3 ); 
266                                              DEBUG_FreeExprMem(); }
267     | tINFO tLOCAL tEOL         { DEBUG_InfoLocals(); }
268     | tINFO tDISPLAY tEOL       { DEBUG_InfoDisplay(); }
269
270 walk_command:
271       tWALK tCLASS tEOL         { CLASS_WalkClasses(); }
272     | tWALK tMODULE tEOL        { MODULE_WalkModules(); }
273     | tWALK tQUEUE tEOL         { QUEUE_WalkQueues(); }
274     | tWALK tWND tEOL           { WIN_WalkWindows( 0, 0 ); }
275     | tWALK tWND tNUM tEOL      { WIN_WalkWindows( $3, 0 ); }
276
277
278 type_cast: 
279       '(' type_expr ')'         { $$ = $2; }
280
281 type_expr:
282       type_expr '*'             { $$ = DEBUG_FindOrMakePointerType($1); }
283     |  tINT                     { $$ = DEBUG_TypeCast(BASIC, "int"); }
284     | tCHAR                     { $$ = DEBUG_TypeCast(BASIC, "char"); }
285     | tLONG tINT                { $$ = DEBUG_TypeCast(BASIC, "long int"); }
286     | tUNSIGNED tINT            { $$ = DEBUG_TypeCast(BASIC, "unsigned int"); }
287     | tLONG tUNSIGNED tINT      { $$ = DEBUG_TypeCast(BASIC, "long unsigned int"); }
288     | tLONG tLONG tINT          { $$ = DEBUG_TypeCast(BASIC, "long long int"); }
289     | tLONG tLONG tUNSIGNED tINT { $$ = DEBUG_TypeCast(BASIC, "long long unsigned int"); }
290     | tSHORT tINT               { $$ = DEBUG_TypeCast(BASIC, "short int"); }
291     | tSHORT tUNSIGNED tINT     { $$ = DEBUG_TypeCast(BASIC, "short unsigned int"); }
292     | tSIGNED tCHAR             { $$ = DEBUG_TypeCast(BASIC, "signed char"); }
293     | tUNSIGNED tCHAR           { $$ = DEBUG_TypeCast(BASIC, "unsigned char"); }
294     | tFLOAT                    { $$ = DEBUG_TypeCast(BASIC, "float"); }
295     | tDOUBLE                   { $$ = DEBUG_TypeCast(BASIC, "double"); }
296     | tLONG tDOUBLE             { $$ = DEBUG_TypeCast(BASIC, "long double"); }
297     | tSTRUCT tIDENTIFIER       { $$ = DEBUG_TypeCast(STRUCT, $2); }
298     | tUNION tIDENTIFIER        { $$ = DEBUG_TypeCast(STRUCT, $2); }
299     | tENUM tIDENTIFIER         { $$ = DEBUG_TypeCast(ENUM, $2); }
300
301 expr_addr:
302     expr                         { $$ = DEBUG_EvalExpr($1); }
303
304 expr_value:
305       expr        { DBG_ADDR addr  = DEBUG_EvalExpr($1);
306                     $$ = addr.off ? *(unsigned int *) addr.off : 0; }
307 /*
308  * The expr rule builds an expression tree.  When we are done, we call
309  * EvalExpr to evaluate the value of the expression.  The advantage of
310  * the two-step approach is that it is possible to save expressions for
311  * use in 'display' commands, and in conditional watchpoints.
312  */
313 expr:
314       tNUM                       { $$ = DEBUG_ConstExpr($1); }
315     | tSTRING                    { $$ = DEBUG_StringExpr($1); }
316     | tREG                       { $$ = DEBUG_RegisterExpr($1); }
317     | tIDENTIFIER                { $$ = DEBUG_SymbolExpr($1); }
318     | expr OP_DRF tIDENTIFIER    { $$ = DEBUG_StructPExpr($1, $3); } 
319     | expr '.' tIDENTIFIER       { $$ = DEBUG_StructExpr($1, $3); } 
320     | tIDENTIFIER '(' ')'        { $$ = DEBUG_CallExpr($1, 0); } 
321     | tIDENTIFIER '(' expr ')'   { $$ = DEBUG_CallExpr($1, 1, $3); } 
322     | tIDENTIFIER '(' expr ',' expr ')'  { $$ = DEBUG_CallExpr($1, 2, $3, 
323                                                                $5); } 
324     | tIDENTIFIER '(' expr ',' expr ',' expr ')'         { $$ = DEBUG_CallExpr($1, 3, $3, $5, $7); } 
325     | tIDENTIFIER '(' expr ',' expr ',' expr ',' expr ')'        { $$ = DEBUG_CallExpr($1, 3, $3, $5, $7, $9); } 
326     | tIDENTIFIER '(' expr ',' expr ',' expr ',' expr ',' expr ')'       { $$ = DEBUG_CallExpr($1, 3, $3, $5, $7, $9, $11); } 
327     | expr '[' expr ']'          { $$ = DEBUG_BinopExpr(EXP_OP_ARR, $1, $3); } 
328     | expr ':' expr              { $$ = DEBUG_BinopExpr(EXP_OP_SEG, $1, $3); } 
329     | expr OP_LOR expr           { $$ = DEBUG_BinopExpr(EXP_OP_LOR, $1, $3); }
330     | expr OP_LAND expr          { $$ = DEBUG_BinopExpr(EXP_OP_LAND, $1, $3); }
331     | expr '|' expr              { $$ = DEBUG_BinopExpr(EXP_OP_OR, $1, $3); }
332     | expr '&' expr              { $$ = DEBUG_BinopExpr(EXP_OP_AND, $1, $3); }
333     | expr '^' expr              { $$ = DEBUG_BinopExpr(EXP_OP_XOR, $1, $3); }
334     | expr OP_EQ expr            { $$ = DEBUG_BinopExpr(EXP_OP_EQ, $1, $3); }
335     | expr '>' expr              { $$ = DEBUG_BinopExpr(EXP_OP_GT, $1, $3); }
336     | expr '<' expr              { $$ = DEBUG_BinopExpr(EXP_OP_LT, $1, $3); }
337     | expr OP_GE expr            { $$ = DEBUG_BinopExpr(EXP_OP_GE, $1, $3); }
338     | expr OP_LE expr            { $$ = DEBUG_BinopExpr(EXP_OP_LE, $1, $3); }
339     | expr OP_NE expr            { $$ = DEBUG_BinopExpr(EXP_OP_NE, $1, $3); }
340     | expr OP_SHL expr           { $$ = DEBUG_BinopExpr(EXP_OP_SHL, $1, $3); }
341     | expr OP_SHR expr           { $$ = DEBUG_BinopExpr(EXP_OP_SHR, $1, $3); }
342     | expr '+' expr              { $$ = DEBUG_BinopExpr(EXP_OP_ADD, $1, $3); }
343     | expr '-' expr              { $$ = DEBUG_BinopExpr(EXP_OP_SUB, $1, $3); }
344     | expr '*' expr              { $$ = DEBUG_BinopExpr(EXP_OP_MUL, $1, $3); }
345     | expr '/' expr              { $$ = DEBUG_BinopExpr(EXP_OP_DIV, $1, $3); }
346     | expr '%' expr              { $$ = DEBUG_BinopExpr(EXP_OP_REM, $1, $3); }
347     | '-' expr %prec OP_SIGN     { $$ = DEBUG_UnopExpr(EXP_OP_NEG, $2); }
348     | '+' expr %prec OP_SIGN     { $$ = $2; }
349     | '!' expr                   { $$ = DEBUG_UnopExpr(EXP_OP_NOT, $2); }
350     | '~' expr                   { $$ = DEBUG_UnopExpr(EXP_OP_LNOT, $2); }
351     | '(' expr ')'               { $$ = $2; }
352     | '*' expr %prec OP_DEREF    { $$ = DEBUG_UnopExpr(EXP_OP_DEREF, $2); }
353     | '&' expr %prec OP_DEREF    { $$ = DEBUG_UnopExpr(EXP_OP_ADDR, $2); }
354     | type_cast expr %prec OP_DEREF { $$ = DEBUG_TypeCastExpr($1, $2); } 
355         
356 /*
357  * The lvalue rule builds an expression tree.  This is a limited form
358  * of expression that is suitable to be used as an lvalue.
359  */
360 lval_addr:
361     lval                         { $$ = DEBUG_EvalExpr($1); }
362
363 lval:
364       lvalue                     { $$ = $1; }
365     | '*' expr                   { $$ = DEBUG_UnopExpr(EXP_OP_FORCE_DEREF, $2); }
366         
367 lvalue:
368       tNUM                       { $$ = DEBUG_ConstExpr($1); }
369     | tREG                       { $$ = DEBUG_RegisterExpr($1); }
370     | tIDENTIFIER                { $$ = DEBUG_SymbolExpr($1); }
371     | lvalue OP_DRF tIDENTIFIER  { $$ = DEBUG_StructPExpr($1, $3); } 
372     | lvalue '.' tIDENTIFIER     { $$ = DEBUG_StructExpr($1, $3); } 
373     | lvalue '[' expr ']'        { $$ = DEBUG_BinopExpr(EXP_OP_ARR, $1, $3); } 
374         
375 %%
376
377 void 
378 issue_prompt(){
379 #ifdef DONT_USE_READLINE
380         fprintf(stderr,"Wine-dbg>");
381 #endif
382 }
383
384 void mode_command(int newmode)
385 {
386     if ((newmode == 16) || (newmode == 32)) dbg_mode = newmode;
387     else fprintf(stderr,"Invalid mode (use 16 or 32)\n");
388 }
389
390
391 /***********************************************************************
392  *           DEBUG_Main
393  *
394  * Debugger main loop.
395  */
396 static void DEBUG_Main( int signal )
397 {
398     static int loaded_symbols = 0;
399     static BOOL32 in_debugger = FALSE;
400     char SymbolTableFile[256];
401     int newmode;
402     BOOL32 ret_ok;
403 #ifdef YYDEBUG
404     yydebug = 0;
405 #endif
406
407     if (in_debugger)
408     {
409         fprintf( stderr, "Segmentation fault inside debugger, exiting.\n" );
410         exit(1);
411     }
412     in_debugger = TRUE;
413     yyin = stdin;
414
415     DEBUG_SetBreakpoints( FALSE );
416
417     if (!loaded_symbols)
418     {
419         loaded_symbols++;
420
421         /*
422          * Initialize the type handling stuff.
423          */
424         DEBUG_InitTypes();
425
426         /*
427          * In some cases we can read the stabs information directly
428          * from the executable.  If this is the case, we don't need
429          * to bother with trying to read a symbol file, as the stabs
430          * also have line number and local variable information.
431          * As long as gcc is used for the compiler, stabs will
432          * be the default.  On SVr4, DWARF could be used, but we
433          * don't grok that yet, and in this case we fall back to using
434          * the wine.sym file.
435          */
436         if( DEBUG_ReadExecutableDbgInfo() == FALSE )
437         {
438             PROFILE_GetWineIniString( "wine", "SymbolTableFile", "wine.sym",
439                                      SymbolTableFile, sizeof(SymbolTableFile));
440             DEBUG_ReadSymbolTable( SymbolTableFile );
441         }
442
443         /*
444          * Read COFF, MSC, etc debug information that we noted when we
445          * started up the executable.
446          */
447         DEBUG_ProcessDeferredDebug();
448
449         DEBUG_LoadEntryPoints();
450     }
451
452 #if 0
453     fprintf(stderr, "Entering debugger  PC=%x, mode=%d, count=%d\n",
454             EIP_reg(&DEBUG_context),
455             dbg_exec_mode, dbg_exec_count);
456     
457     sleep(1);
458 #endif
459
460     if ((signal != SIGTRAP) || !DEBUG_ShouldContinue( dbg_exec_mode, 
461                                                       &dbg_exec_count ))
462     {
463         DBG_ADDR addr;
464
465         addr.seg = CS_reg(&DEBUG_context);
466         addr.off = EIP_reg(&DEBUG_context);
467         addr.type = NULL;
468         DBG_FIX_ADDR_SEG( &addr, 0 );
469
470         /* Put the display in a correct state */
471
472         XUngrabPointer( display, CurrentTime );
473         XUngrabServer( display );
474         XFlush( display );
475
476         if (!addr.seg) newmode = 32;
477         else newmode = (GET_SEL_FLAGS(addr.seg) & LDT_FLAGS_32BIT) ? 32 : 16;
478
479         if (newmode != dbg_mode)
480             fprintf(stderr,"In %d bit mode.\n", dbg_mode = newmode);
481
482         DEBUG_DoDisplay();
483
484         if (signal != SIGTRAP)  /* This is a real crash, dump some info */
485         {
486             DEBUG_InfoRegisters();
487             DEBUG_InfoStack();
488             if (dbg_mode == 16)
489             {
490                 LDT_Print( SELECTOR_TO_ENTRY(DS_reg(&DEBUG_context)), 1 );
491                 if (ES_reg(&DEBUG_context) != DS_reg(&DEBUG_context))
492                     LDT_Print( SELECTOR_TO_ENTRY(ES_reg(&DEBUG_context)), 1 );
493             }
494             DEBUG_BackTrace();
495         }
496         else
497         {
498           /*
499            * Do a quiet backtrace so that we have an idea of what the situation
500            * is WRT the source files.
501            */
502             DEBUG_SilentBackTrace();
503         }
504
505         if( signal != SIGTRAP )
506           {
507             /* Show where we crashed */
508             curr_frame = 0;
509             DEBUG_PrintAddress( &addr, dbg_mode, TRUE );
510             fprintf(stderr,":  ");
511             if (DBG_CHECK_READ_PTR( &addr, 1 ))
512               {
513                 DEBUG_Disasm( &addr, TRUE );
514                 fprintf(stderr,"\n");
515               }
516           }
517
518         ret_ok = 0;
519         do
520         {
521             issue_prompt();
522             yyparse();
523             flush_symbols();
524             addr.seg = CS_reg(&DEBUG_context);
525             addr.off = EIP_reg(&DEBUG_context);
526             DBG_FIX_ADDR_SEG( &addr, 0 );
527             ret_ok = DEBUG_ValidateRegisters();
528             if (ret_ok) ret_ok = DBG_CHECK_READ_PTR( &addr, 1 );
529         } while (!ret_ok);
530     }
531
532     dbg_exec_mode = DEBUG_RestartExecution( dbg_exec_mode, dbg_exec_count );
533     /*
534      * This will have gotten absorbed into the breakpoint info
535      * if it was used.  Otherwise it would have been ignored.
536      * In any case, we don't mess with it any more.
537      */
538     if( dbg_exec_mode == EXEC_CONT )
539       {
540         dbg_exec_count = 0;
541       }
542
543     in_debugger = FALSE;
544 }
545
546
547 /***********************************************************************
548  *           DebugBreak16   (KERNEL.203)
549  */
550 void DebugBreak16( CONTEXT *regs )
551 {
552     const char *module = MODULE_GetModuleName( GetExePtr(GetCurrentTask()) );
553     fprintf( stderr, "%s called DebugBreak\n", module ? module : "???" );
554     DEBUG_context = *regs;
555     DEBUG_Main( SIGTRAP );
556 }
557
558
559 void wine_debug( int signal, SIGCONTEXT *regs )
560 {
561     DEBUG_SetSigContext( regs );
562 #if 0
563     DWORD *stack = (DWORD *)ESP_reg(&DEBUG_context);
564     *(--stack) = 0;
565     *(--stack) = 0;
566     *(--stack) = EH_NONCONTINUABLE;
567     *(--stack) = EXCEPTION_ACCESS_VIOLATION;
568     *(--stack) = EIP_reg(&DEBUG_context);
569     ESP_reg(&DEBUG_context) = (DWORD)stack;
570     EIP_reg(&DEBUG_context) = GetProcAddress32( GetModuleHandle("KERNEL32"),
571                                                 "RaiseException" );
572 #endif
573     DEBUG_Main( signal );
574     DEBUG_GetSigContext( regs );
575 }
576
577 int yyerror(char * s)
578 {
579         fprintf(stderr,"%s\n", s);
580         return 0;
581 }
582