3 * Parser for command lines in the Wine debugger
5 * Copyright 1993 Eric Youngdale
6 * Copyright 1995 Morten Welinder
16 unsigned int dbg_mode
= 0;
18 static enum exec_mode dbg_exec_mode
= EXEC_CONT
;
20 void issue_prompt
(void);
21 void mode_command
(int);
22 void flush_symbols
(void);
36 %token CONT STEP LIST NEXT QUIT HELP BACKTRACE INFO STACK SEGMENTS REGS
37 %token ENABLE DISABLE BREAK DELETE SET MODE PRINT EXAM DEFINE ABORT
41 %token
<string> IDENTIFIER
42 %token
<integer
> NUM FORMAT
46 /* %left '=' OP_OR_EQUAL OP_XOR_EQUAL OP_AND_EQUAL OP_SHL_EQUAL \
47 OP_SHR_EQUAL OP_PLUS_EQUAL OP_MINUS_EQUAL \
48 OP_TIMES_EQUAL OP_DIVIDE_EQUAL OP_MODULO_EQUAL */
49 /* %left OP_COND */ /* ... ? ... : ... */
56 %left
'<' '>' OP_LE OP_GE
60 %left OP_SIGN
'!' '~' OP_DEREF
/* OP_INC OP_DEC OP_ADDR */
64 %type
<address
> addr segaddr symbol
68 input
: line
{ issue_prompt
(); }
69 | input line
{ issue_prompt
(); }
73 |
error EOL
{ yyerrok; }
75 command
: QUIT EOL
{ exit
(0); }
76 | HELP EOL
{ DEBUG_Help
(); }
77 | CONT EOL
{ dbg_exec_mode
= EXEC_CONT
; return
0; }
78 | STEP EOL
{ dbg_exec_mode
= EXEC_STEP_INSTR
; return
0; }
79 | NEXT EOL
{ dbg_exec_mode
= EXEC_STEP_OVER
; return
0; }
80 | LIST EOL
{ DEBUG_List
( NULL
, 15 ); }
81 | LIST addr EOL
{ DEBUG_List
( &$2, 15 ); }
82 | ABORT EOL
{ kill
(getpid
(), SIGABRT
); }
83 | SYMBOLFILE IDENTIFIER EOL
{ DEBUG_ReadSymbolTable
( $2 ); }
84 | DEFINE IDENTIFIER addr EOL
{ DEBUG_AddSymbol
( $2, &$3 ); }
85 | MODE NUM EOL
{ mode_command
($2); }
86 | ENABLE NUM EOL
{ DEBUG_EnableBreakpoint
( $2, TRUE
); }
87 | DISABLE NUM EOL
{ DEBUG_EnableBreakpoint
( $2, FALSE
); }
88 | BREAK
'*' addr EOL
{ DEBUG_AddBreakpoint
( &$3 ); }
89 | BREAK symbol EOL
{ DEBUG_AddBreakpoint
( &$2 ); }
90 | BREAK EOL
{ DBG_ADDR addr
= { CS_reg
(DEBUG_context
),
91 EIP_reg
(DEBUG_context
) };
92 DEBUG_AddBreakpoint
( &addr
);
94 | DELETE BREAK NUM EOL
{ DEBUG_DelBreakpoint
( $3 ); }
95 | BACKTRACE EOL
{ DEBUG_BackTrace
(); }
102 SET REG
'=' expr EOL
{ DEBUG_SetRegister
( $2, $4 ); }
103 | SET
'*' addr
'=' expr EOL
{ DEBUG_WriteMemory
( &$3, $5 ); }
104 | SET IDENTIFIER
'=' addr EOL
{ if
(!DEBUG_SetSymbolValue
( $2, &$4 ))
107 "Symbol %s not found\n", $2 );
114 EXAM addr EOL
{ DEBUG_ExamineMemory
( &$2, 1, 'x'); }
115 | EXAM FORMAT addr EOL
{ DEBUG_ExamineMemory
( &$3, $2>>8, $2&0xff ); }
118 PRINT addr EOL
{ DEBUG_Print
( &$2, 1, 'x' ); }
119 | PRINT FORMAT addr EOL
{ DEBUG_Print
( &$3, $2 >> 8, $2 & 0xff ); }
121 symbol
: IDENTIFIER
{ if
(!DEBUG_GetSymbolValue
( $1, &$$
))
123 fprintf
( stderr
, "Symbol %s not found\n", $1 );
128 addr
: expr
{ $$.seg
= 0xffffffff; $$.off
= $1; }
129 | segaddr
{ $$
= $1; }
131 segaddr
: expr
':' expr
{ $$.seg
= $1; $$.off
= $3; }
132 | symbol
{ $$
= $1; }
134 expr
: NUM
{ $$
= $1; }
135 | REG
{ $$
= DEBUG_GetRegister
($1); }
136 | expr OP_LOR expr
{ $$
= $1 ||
$3; }
137 | expr OP_LAND expr
{ $$
= $1 && $3; }
138 | expr
'|' expr
{ $$
= $1 |
$3; }
139 | expr
'&' expr
{ $$
= $1 & $3; }
140 | expr
'^' expr
{ $$
= $1 ^
$3; }
141 | expr OP_EQ expr
{ $$
= $1 == $3; }
142 | expr
'>' expr
{ $$
= $1 > $3; }
143 | expr
'<' expr
{ $$
= $1 < $3; }
144 | expr OP_GE expr
{ $$
= $1 >= $3; }
145 | expr OP_LE expr
{ $$
= $1 <= $3; }
146 | expr OP_NE expr
{ $$
= $1 != $3; }
147 | expr OP_SHL expr
{ $$
= (unsigned)$1 << $3; }
148 | expr OP_SHR expr
{ $$
= (unsigned)$1 >> $3; }
149 | expr
'+' expr
{ $$
= $1 + $3; }
150 | expr
'-' expr
{ $$
= $1 - $3; }
151 | expr
'*' expr
{ $$
= $1 * $3; }
154 if
($3 == -1 && $1 == 0x80000000l
)
155 yyerror ("Division overflow");
159 yyerror ("Division by zero"); }
162 if
($3 == -1 && $1 == 0x80000000l
)
163 $$
= 0; /* A sensible result in this case. */
167 yyerror ("Division by zero"); }
168 |
'-' expr %prec OP_SIGN
{ $$
= -$2; }
169 |
'+' expr %prec OP_SIGN
{ $$
= $2; }
170 |
'!' expr
{ $$
= !$2; }
171 |
'~' expr
{ $$
= ~
$2; }
172 |
'(' expr
')' { $$
= $2; }
173 /* For parser technical reasons we can't use "addr" here. */
174 |
'*' expr %prec OP_DEREF
{ DBG_ADDR addr
= { 0xffffffff, $2 };
175 $$
= DEBUG_ReadMemory
( &addr
); }
176 |
'*' segaddr %prec OP_DEREF
{ $$
= DEBUG_ReadMemory
( &$2 ); }
178 infocmd
: INFO REGS EOL
{ DEBUG_InfoRegisters
(); }
179 | INFO STACK EOL
{ DEBUG_InfoStack
(); }
180 | INFO BREAK EOL
{ DEBUG_InfoBreakpoints
(); }
181 | INFO SEGMENTS EOL
{ LDT_Print
( 0, -1 ); }
182 | INFO SEGMENTS expr EOL
{ LDT_Print
( SELECTOR_TO_ENTRY
($3), 1 ); }
190 fprintf
(stderr
,"Wine-dbg>");
194 void mode_command
(int newmode
)
196 if
((newmode
== 16) ||
(newmode
== 32)) dbg_mode
= newmode
;
197 else fprintf
(stderr
,"Invalid mode (use 16 or 32)\n");
201 void wine_debug
( int signal
, struct sigcontext_struct
*regs
)
203 static int loaded_symbols
= 0;
204 char SymbolTableFile
[256];
205 int instr_len
= 0, newmode
;
211 DEBUG_context
= (struct sigcontext_struct
*)regs
;
213 DEBUG_SetBreakpoints
( FALSE
);
218 PROFILE_GetWineIniString
( "wine", "SymbolTableFile", "wine.sym",
219 SymbolTableFile
, sizeof
(SymbolTableFile
) );
220 DEBUG_ReadSymbolTable
( SymbolTableFile
);
221 DEBUG_LoadEntryPoints
();
224 if
((signal
!= SIGTRAP
) ||
!DEBUG_ShouldContinue
( regs
, dbg_exec_mode
))
228 addr.seg
= CS_reg
(DEBUG_context
);
229 addr.off
= EIP_reg
(DEBUG_context
);
230 DBG_FIX_ADDR_SEG
( &addr
, 0 );
232 if
(!addr.seg
) newmode
= 32;
233 else newmode
= (GET_SEL_FLAGS
(addr.seg
) & LDT_FLAGS_32BIT
) ?
32 : 16;
235 if
(newmode
!= dbg_mode
)
236 fprintf
(stderr
,"In %d bit mode.\n", dbg_mode
= newmode
);
238 if
(signal
!= SIGTRAP
) /* This is a real crash, dump some info */
240 DEBUG_InfoRegisters
();
244 LDT_Print
( SELECTOR_TO_ENTRY
(DS_reg
(DEBUG_context
)), 1 );
245 if
(ES_reg
(DEBUG_context
) != DS_reg
(DEBUG_context
))
246 LDT_Print
( SELECTOR_TO_ENTRY
(ES_reg
(DEBUG_context
)), 1 );
251 /* Show where we crashed */
252 DEBUG_PrintAddress
( &addr
, dbg_mode
);
253 fprintf
(stderr
,": ");
254 if
(DBG_CHECK_READ_PTR
( &addr
, 1 ))
256 DEBUG_Disasm
( &addr
);
257 fprintf
(stderr
,"\n");
258 instr_len
= addr.off
- EIP_reg
(DEBUG_context
);
266 addr.seg
= CS_reg
(DEBUG_context
);
267 addr.off
= EIP_reg
(DEBUG_context
);
268 DBG_FIX_ADDR_SEG
( &addr
, 0 );
269 } while
(!DBG_CHECK_READ_PTR
( &addr
, 1 ));
272 DEBUG_RestartExecution
( regs
, dbg_exec_mode
, instr_len
);
276 int yyerror(char * s
)
278 fprintf
(stderr
,"%s\n", s
);