| |
| %{ |
| |
| /* Parser for command lines in the Wine debugger |
| * |
| * Version 1.0 |
| * Eric Youngdale |
| * 9/93 |
| */ |
| |
| #include <stdio.h> |
| #include <signal.h> |
| #include <unistd.h> |
| #include "windows.h" |
| #include "debugger.h" |
| |
| #define YYSTYPE int |
| |
| extern FILE * yyin; |
| unsigned int dbg_mode = 0; |
| |
| static enum exec_mode dbg_exec_mode = EXEC_CONT; |
| |
| void issue_prompt(void); |
| void mode_command(int); |
| %} |
| |
| |
| %token CONT |
| %token STEP |
| %token NEXT |
| %token QUIT |
| %token HELP |
| %token BACKTRACE |
| %token INFO |
| %token STACK |
| %token SEGMENTS |
| %token REG |
| %token REGS |
| %token NUM |
| %token ENABLE |
| %token DISABLE |
| %token BREAK |
| %token DELETE |
| %token SET |
| %token MODE |
| %token PRINT |
| %token EXAM |
| %token IDENTIFIER |
| %token FORMAT |
| %token NO_SYMBOL |
| %token SYMBOLFILE |
| %token DEFINE |
| %token ABORT |
| |
| %% |
| |
| input: /* empty */ |
| | input line { issue_prompt(); } |
| |
| line: '\n' |
| | infocmd '\n' |
| | error '\n' { yyerrok; } |
| | QUIT '\n' { exit(0); } |
| | HELP '\n' { dbg_help(); } |
| | CONT '\n' { dbg_exec_mode = EXEC_CONT; return 0; } |
| | STEP '\n' { dbg_exec_mode = EXEC_STEP_INSTR; return 0; } |
| | NEXT '\n' { dbg_exec_mode = EXEC_STEP_OVER; return 0; } |
| | ABORT '\n' { kill(getpid(), SIGABRT); } |
| | SYMBOLFILE IDENTIFIER '\n' { read_symboltable($2); } |
| | DEFINE IDENTIFIER expr '\n' { add_hash($2, 0, $3); } |
| | MODE NUM '\n' { mode_command($2); } |
| | ENABLE NUM '\n' { DEBUG_EnableBreakpoint( $2, TRUE ); } |
| | DISABLE NUM '\n' { DEBUG_EnableBreakpoint( $2, FALSE ); } |
| | BREAK '*' expr { DEBUG_AddBreakpoint( 0xffffffff, $3 ); } |
| | BREAK '\n' { DEBUG_AddBreakpoint( 0xffffffff, EIP ); } |
| | DELETE BREAK NUM '\n' { DEBUG_DelBreakpoint( $3 ); } |
| | BACKTRACE '\n' { DEBUG_BackTrace(); } |
| | x_command |
| | print_command |
| | deposit_command |
| |
| deposit_command: |
| SET REG '=' expr '\n' { DEBUG_SetRegister( $2, $4 ); } |
| | SET '*' expr '=' expr '\n' { *((unsigned int *) $3) = $5; } |
| | SET symbol '=' expr '\n' { *((unsigned int *) $2) = $4; } |
| |
| |
| x_command: |
| EXAM expr '\n' { examine_memory( 0xffffffff, $2, 1, 'x'); } |
| | EXAM FORMAT expr '\n' { examine_memory( 0xffffffff, $3, |
| $2 >> 8, $2 & 0xff ); } |
| |
| print_command: |
| PRINT expr '\n' { examine_memory( 0, ((unsigned int) &$2 ), 1,'x'); } |
| | PRINT FORMAT expr '\n' { examine_memory( 0, (unsigned int)&$3, |
| $2 >> 8, $2 & 0xff ); } |
| |
| symbol: IDENTIFIER { if (($$ = find_hash($1)) == 0xffffffff) |
| { |
| fprintf(stderr,"Symbol %s not found\n", (char *)$1); |
| YYERROR; |
| } |
| } |
| |
| expr: NUM { $$ = $1; } |
| | REG { $$ = DEBUG_GetRegister($1); } |
| | symbol { $$ = $1; } |
| | expr '+' NUM { $$ = $1 + $3; } |
| | expr '-' NUM { $$ = $1 - $3; } |
| | '(' expr ')' { $$ = $2; } |
| | '*' expr { $$ = *((unsigned int *) $2); } |
| |
| infocmd: INFO REGS { DEBUG_InfoRegisters(); } |
| | INFO STACK { DEBUG_InfoStack(); } |
| | INFO BREAK { DEBUG_InfoBreakpoints(); } |
| | INFO SEGMENTS { LDT_Print(); } |
| |
| |
| %% |
| |
| void |
| issue_prompt(){ |
| #ifndef USE_READLINE |
| fprintf(stderr,"Wine-dbg>"); |
| #endif |
| } |
| |
| void mode_command(int newmode) |
| { |
| if ((newmode == 16) || (newmode == 32)) dbg_mode = newmode; |
| else fprintf(stderr,"Invalid mode (use 16 or 32)\n"); |
| } |
| |
| |
| void wine_debug( int signal, struct sigcontext_struct *regs ) |
| { |
| static int loaded_symbols = 0; |
| char SymbolTableFile[256]; |
| int instr_len = 0, newmode; |
| #ifdef YYDEBUG |
| yydebug = 1; |
| #endif |
| |
| yyin = stdin; |
| context = (struct sigcontext_struct *)regs; |
| |
| if (CS == WINE_CODE_SELECTOR) newmode = 32; |
| else newmode = (GET_SEL_FLAGS(CS) & LDT_FLAGS_32BIT) ? 32 : 16; |
| |
| if (newmode != dbg_mode) |
| fprintf(stderr,"In %d bit mode.\n", dbg_mode = newmode); |
| |
| if(dbg_mode == 32 && !loaded_symbols) |
| { |
| loaded_symbols++; |
| GetPrivateProfileString("wine", "SymbolTableFile", "wine.sym", |
| SymbolTableFile, sizeof(SymbolTableFile), WINE_INI); |
| read_symboltable(SymbolTableFile); |
| } |
| |
| DEBUG_SetBreakpoints( FALSE ); |
| |
| if ((signal != SIGTRAP) || !DEBUG_ShouldContinue( regs, dbg_exec_mode )) |
| { |
| unsigned int segment = (CS == WINE_CODE_SELECTOR) ? 0 : CS; |
| |
| /* Show where we crashed */ |
| print_address( segment, EIP, dbg_mode ); |
| fprintf(stderr,": "); |
| instr_len = db_disasm( segment, EIP ) - EIP; |
| fprintf(stderr,"\n"); |
| |
| issue_prompt(); |
| yyparse(); |
| flush_symbols(); |
| } |
| |
| DEBUG_RestartExecution( regs, dbg_exec_mode, instr_len ); |
| } |
| |
| |
| int yyerror(char * s) |
| { |
| fprintf(stderr,"%s\n", s); |
| return 0; |
| } |
| |