Release 950706
Wed Jul 5 19:06:35 1995 Alexandre Julliard <julliard@sunsite.unc.edu>
* [controls/scroll.c]
Fixed drawing bug that caused part of a non-client scroll bar
to be painted even when the scroll-bar was hidden.
* [debugger/break.c] [debugger/dbg.y]
Rewrote breakpoint handling to work in 16-bit mode.
Implemented single-stepping ('step' and 'next' instructions).
* [debugger/debug.l]
Format specifier is now a separate token.
Entering an empty line at the debugger prompt causes the previous
command to be repeated, like under gdb.
* [debugger/debug.l] [debugger/registers.c]
Differentiate 16-bit and 32-bit registers without taking current
mode into account ($eax is always 32-bit, $ax always 16-bit).
* [debugger/stack.c]
Fixed stack information routines to differentiate between 16-bit
and 32-bit stacks.
* [loader/task.c]
Option -debug now sets a breakpoint at the first instruction of
every loaded task.
* [miscemu/instr.c]
Added handling of lock, repe and repne prefixes.
* [objects/dib.c]
Changed StretchDIBits() to do the correct thing, even if it's still
not really optimal.
* [windows/graphics.c]
Fixes in RoundRect(), thanks to Babak Masalehdan.
* [windows/message.c]
Tried to fix mouse event handling with respect to disabled
windows.
* [windows/painting.c]
Clear WIN_NEEDS_NCPAINT flag before sending WM_NCPAINT to avoid
infinite loops.
* [windows/win.c]
Fixed IsWindowVisible() to return FALSE when one of the parent
windows is hidden.
Sat Jul 1 22:08:21 1995 Martin von Loewis <loewis@informatik.hu-berlin.de>
* [if1632/compobj.spec][misc/compobj.c]
CoGetMalloc: New function
Added relay entries for COMPOBJ ordinals above 100
CoInitialize: Changed parameter to DWORD
* [if1632/ole2.spec]
Exported implementation of OleBuildVersion
* [if1632/ole2disp.spec][misc/ole2disp.c][misc/Imakefile]
ole2disp.c: New file
SysAllocString, SysReallocString, SysAllocStringLen,
SysReAllocStringLen, SysFreeString, SysStringLen: new functions
* [if1632/ole2nls.spec][include/winnls.h][misc/ole2nls.c]
CompareStringA: New function
Thu Jun 29 19:42:02 1995 Marcus Meissner <msmeissn@faui01.informatik.uni-erlangen.de>
* [objects/font.c] [if1632/gdi.spec]
New stubs for CreateScalableFontResource, GetGlyphOutline.
Thu Jun 29 13:47:08 GMT 1995 Göran Thyni (goran@norrsken.bildbasen.se)
* [misc/commdlg.c]
Extensive changes and bug fixes to FileDialog handling,
behaves more like native Windows.
Wed Jun 28 13:04:44 1995 Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>
* [controls/listbox.c] [controls/combo.c]
Some minor optimizations.
* [memory/local.c]
LOCAL_FindFreeBlock(): Never use the last one.
* [memory/global.c]
GlobalReAlloc(): GMEM_MODIFY must not be ignored when size==0.
* [misc/file.c]
read() returns an error when length==0. This is not what Windows
programs expect, so pay attention to this in _lread(). Changed this
in _lwrite(), _hread(), _hwrite(), too.
* [loader/resource.c]
LoadIcon(): Ignore bih->biSizeImage, some icons have wrong values in
there.
* [if1632/shell.spec] [misc/shell.c]
Wrong spec file entries caused havoc: HKEY has 32 bit, not 16.
Accept some more combinations of parameters in the Reg..() functions.
* [if1632/toolhelp.spec]
Make InterruptRegister() and InterruptUnregister() return false.
* [windows/hook.c]
CallNextHookEx() used to crash when called with a null hhook. Fixed.
Wed Jun 28 10:14:34 1995 Martin von Loewis <martin@informatik.hu-berlin.de>
* [include/neexe.h][loader/ne_image.c]
NE_LoadSegment: Detect iterated segments
* [misc/ole2nls.c]
LOCALE_SLONGDATE: fixed typo
* [miscemu/int5c.c]
Reordered include files to avoid conflicts with Linux libc.5.1
* [rc/winerc.c]
Added -b option to process binary resource files into C arrays
* [include/callback.h]
CallWndProc: Added dummy ds parameter for libwine
* [include/gdi.h][include/user.h]
USER_HEAP_ALLOC, GDI_HEAP_ALLOC: dropped flags parameter
* [include/ldt.h][include/stackframe.h]
defined segment conversion macros for libwine
* [misc/atom.c]
Defined USER_HeapSel for libwine
* [misc/main.c]
Disable -dll option for libwine
* [misc/user.c]
removed GetFreeSystemResources, SystemHeapInfo from libwine for now
* [toolkit/heap.c]
fixed LocalLock prototype
* [toolkit/sup.c]
sync'ed load_mz_header, load_ne_header with structures
* [toolkit/winmain.c]
Disabled resource DLLs for libwine for now
Mon Jun 26 19:30:24 1995 Hans de Graaff (graaff@twi72.twi.tudelft.nl)
* [misc/main.c]
Fixed -enhanced option to report a 386 CPU instead of a 286.
Fri Jun 23 23:18:25 1995 Marcus Meissner <msmeissn@faui01.informatik.uni-erlangen.de>
* [misc/dos_fs.c]
Remove maximum open dosdirent limit (fixing the winfile.exe
problem) by using telldir()/seekdir().
Fri Jun 23 13:42:25 1995 Hans de Graaff (graaff@twi72.twi.tudelft.nl)
* [misc/profile.c]
Fixed problem parsing empty lines within sections in .ini files.
diff --git a/debugger/Imakefile b/debugger/Imakefile
index 7b7ea9d..39c46f4 100644
--- a/debugger/Imakefile
+++ b/debugger/Imakefile
@@ -16,7 +16,9 @@
dbg.tab.c \
hash.c \
info.c \
- lex.yy.c
+ lex.yy.c \
+ registers.c \
+ stack.c
SUBDIRS_OBJS = readline/readline.o
diff --git a/debugger/break.c b/debugger/break.c
index 711c495..e143669 100644
--- a/debugger/break.c
+++ b/debugger/break.c
@@ -1,3 +1,9 @@
+/*
+ * Debugger break-points handling
+ *
+ * Copyright 1994 Martin von Loewis
+ * Copyright 1995 Alexandre Julliard
+ */
#include <stdio.h>
#include <stdlib.h>
@@ -5,100 +11,42 @@
#ifdef linux
#include <sys/utsname.h>
#endif
-#include <windows.h>
-#include "db_disasm.h"
+#include "windows.h"
+#include "debugger.h"
-#define N_BP 25
+#define INT3 0xcc /* int 3 opcode */
+#define STEP_FLAG 0x100 /* single-step flag */
-extern int dbg_mode;
+#define MAX_BREAKPOINTS 25
-struct wine_bp{
- unsigned long addr;
- unsigned long next_addr;
- char in_use;
- char enabled;
- unsigned char databyte;
-};
-
-static struct wine_bp wbp[N_BP] = {{0,},};
-
-static int current_bp = -1;
-static int cont_mode=0; /* 0 - continuous execution
- 1 - advancing after breakpoint
- 2 - single step - not implemented
- */
-
-void info_break(void)
+typedef struct
{
- int j;
- fprintf(stderr,"Breakpoint status\n");
- for(j=0; j<N_BP; j++)
- if(wbp[j].in_use)
- fprintf(stderr,"%d: %c %8lx\n", j, (wbp[j].enabled ? 'y' : 'n'),
- wbp[j].addr);
-}
+ unsigned int segment;
+ unsigned int addr;
+ BYTE addrlen;
+ BYTE opcode;
+ BOOL enabled;
+ BOOL in_use;
+} BREAKPOINT;
-void disable_break(int bpnum)
+static BREAKPOINT breakpoints[MAX_BREAKPOINTS] = { { 0, }, };
+
+static int next_bp = 1; /* breakpoint 0 is reserved for step-over */
+
+
+/***********************************************************************
+ * DEBUG_ChangeOpcode
+ *
+ * Change the opcode at segment:addr.
+ */
+static void DEBUG_SetOpcode( unsigned int segment, unsigned int addr, BYTE op )
{
- if(bpnum >= N_BP || bpnum < 0)
- fprintf(stderr,"Breakpoint number out of range\n");
-
- wbp[bpnum].enabled = 0;
-}
-
-void enable_break(int bpnum)
-{
- if(bpnum >= N_BP || bpnum < 0)
- fprintf(stderr,"Breakpoint number out of range\n");
-
- wbp[bpnum].enabled = 1;
-}
-
-void add_break(unsigned long addr)
-{
- int j;
- for(j=0; j<N_BP; j++)
- if(!wbp[j].in_use)
- {
- wbp[j].in_use = 1;
- wbp[j].enabled = 1;
- wbp[j].addr = addr;
- wbp[j].next_addr = 0;
- return;
- }
- fprintf(stderr,"No more breakpoints\n");
-}
-
-static void bark()
-{
- static int barked=0;
- if(barked)return;
- barked=1;
- perror("Sorry, can't set break point");
-#ifdef linux
- {struct utsname buf;
- uname(&buf);
- if(strcmp(buf.sysname,"Linux")==0)
- { if(strcmp(buf.release,"1.1.62")<0)
- fprintf(stderr,"Your current Linux release is %s. "
- "You should upgrade to 1.1.62 or higher\n"
- "Alternatively, in /usr/src/linux/fs/exec.c,"
- " change MAP_SHARED to MAP_PRIVATE.\n", buf.release);
- } else
- fprintf(stderr,"Why did you compile for Linux, while your system is"
- " actually %s?\n",buf.sysname);
- }
-#endif
-}
-
-void insert_break(int flag)
-{
- unsigned char * pnt;
- int j;
-
- for(j=0; j<N_BP; j++)
- if(wbp[j].enabled)
- {
+ if (segment)
+ {
+ *(BYTE *)PTR_SEG_OFF_TO_LIN( segment, addr ) = op;
+ }
+ else /* 32-bit code, so we have to change the protection first */
+ {
/* There are a couple of problems with this. On Linux prior to
1.1.62, this call fails (ENOACCESS) due to a bug in fs/exec.c.
This code is currently not tested at all on BSD.
@@ -108,54 +56,221 @@
Not that portability matters, this code is i386 only anyways...
How do I get the old protection in order to restore it later on?
*/
- if(mprotect((caddr_t)(wbp[j].addr & (~4095)), 4096,
- PROT_READ|PROT_WRITE|PROT_EXEC) == -1){
- bark();
+ if (mprotect((caddr_t)(addr & (~4095)), 4096,
+ PROT_READ|PROT_WRITE|PROT_EXEC) == -1)
+ {
+ perror( "Can't set break point" );
return;
}
- pnt = (unsigned char *) wbp[j].addr;
- if(flag) {
- wbp[j].databyte = *pnt;
- *pnt = 0xcc; /* Change to an int 3 instruction */
- } else {
- *pnt = wbp[j].databyte;
- }
- mprotect((caddr_t)(wbp[j].addr & ~4095), 4096, PROT_READ|PROT_EXEC);
- }
-}
-
-/* Get the breakpoint number that we broke upon */
-int get_bpnum(unsigned int addr)
-{
- int j;
-
- for(j=0; j<N_BP; j++)
- if(wbp[j].enabled)
- if(wbp[j].addr == addr) return j;
-
- return -1;
-}
-
-void toggle_next(int num)
-{
- unsigned int addr;
- addr=wbp[num].addr;
- if(wbp[num].next_addr == 0)
- wbp[num].next_addr = db_disasm( 0, addr, (dbg_mode == 16) );
- wbp[num].addr=wbp[num].next_addr;
- wbp[num].next_addr=addr;
-}
-
-int should_continue(int bpnum)
-{
- if(bpnum<0)return 0;
- toggle_next(bpnum);
- if(bpnum==current_bp){
- current_bp=-1;
- cont_mode=0;
- return 1;
+ *(BYTE *)addr = op;
+ mprotect((caddr_t)(addr & ~4095), 4096, PROT_READ|PROT_EXEC);
}
- cont_mode=1;
- current_bp=bpnum;
- return 0;
+}
+
+
+/***********************************************************************
+ * DEBUG_SetBreakpoints
+ *
+ * Set or remove all the breakpoints.
+ */
+void DEBUG_SetBreakpoints( BOOL set )
+{
+ int i;
+
+ for (i = 0; i < MAX_BREAKPOINTS; i++)
+ {
+ if (breakpoints[i].in_use && breakpoints[i].enabled)
+ DEBUG_SetOpcode( breakpoints[i].segment, breakpoints[i].addr,
+ set ? INT3 : breakpoints[i].opcode );
+ }
+}
+
+
+/***********************************************************************
+ * DEBUG_FindBreakpoint
+ *
+ * Find the breakpoint for a given address. Return the breakpoint
+ * number or -1 if none.
+ */
+int DEBUG_FindBreakpoint( unsigned int segment, unsigned int addr )
+{
+ int i;
+
+ for (i = 0; i < MAX_BREAKPOINTS; i++)
+ {
+ if (breakpoints[i].in_use && breakpoints[i].enabled &&
+ breakpoints[i].segment == segment && breakpoints[i].addr == addr)
+ return i;
+ }
+ return -1;
+}
+
+
+/***********************************************************************
+ * DEBUG_AddBreakpoint
+ *
+ * Add a breakpoint.
+ */
+void DEBUG_AddBreakpoint( unsigned int segment, unsigned int addr )
+{
+ int num;
+ BYTE *p;
+
+ if (segment == 0xffffffff) segment = CS;
+ if (segment == WINE_CODE_SELECTOR) segment = 0;
+
+ if (next_bp < MAX_BREAKPOINTS)
+ num = next_bp++;
+ else /* try to find an empty slot */
+ {
+ for (num = 1; num < MAX_BREAKPOINTS; num++)
+ if (!breakpoints[num].in_use) break;
+ if (num >= MAX_BREAKPOINTS)
+ {
+ fprintf( stderr, "Too many breakpoints. Please delete some.\n" );
+ return;
+ }
+ }
+ p = segment ? (BYTE *)PTR_SEG_OFF_TO_LIN( segment, addr ) : (BYTE *)addr;
+ breakpoints[num].segment = segment;
+ breakpoints[num].addr = addr;
+ breakpoints[num].addrlen = !segment ? 32 :
+ (GET_SEL_FLAGS(segment) & LDT_FLAGS_32BIT) ? 32 : 16;
+ breakpoints[num].opcode = *p;
+ breakpoints[num].enabled = TRUE;
+ breakpoints[num].in_use = TRUE;
+ fprintf( stderr, "Breakpoint %d at ", num );
+ print_address( segment, addr, breakpoints[num].addrlen );
+ fprintf( stderr, "\n" );
+}
+
+
+/***********************************************************************
+ * DEBUG_DelBreakpoint
+ *
+ * Delete a breakpoint.
+ */
+void DEBUG_DelBreakpoint( int num )
+{
+ if ((num <= 0) || (num >= next_bp) || !breakpoints[num].in_use)
+ {
+ fprintf( stderr, "Invalid breakpoint number %d\n", num );
+ return;
+ }
+ breakpoints[num].enabled = FALSE;
+ breakpoints[num].in_use = FALSE;
+}
+
+
+/***********************************************************************
+ * DEBUG_EnableBreakpoint
+ *
+ * Enable or disable a break point.
+ */
+void DEBUG_EnableBreakpoint( int num, BOOL enable )
+{
+ if ((num <= 0) || (num >= next_bp) || !breakpoints[num].in_use)
+ {
+ fprintf( stderr, "Invalid breakpoint number %d\n", num );
+ return;
+ }
+ breakpoints[num].enabled = enable;
+}
+
+
+/***********************************************************************
+ * DEBUG_InfoBreakpoints
+ *
+ * Display break points information.
+ */
+void DEBUG_InfoBreakpoints(void)
+{
+ int i;
+
+ fprintf( stderr, "Breakpoints:\n" );
+ for (i = 1; i < next_bp; i++)
+ {
+ if (breakpoints[i].in_use)
+ {
+ fprintf( stderr, "%d: %c ", i, breakpoints[i].enabled ? 'y' : 'n');
+ print_address( breakpoints[i].segment, breakpoints[i].addr,
+ breakpoints[i].addrlen );
+ fprintf( stderr, "\n" );
+ }
+ }
+}
+
+
+/***********************************************************************
+ * DEBUG_ShouldContinue
+ *
+ * Determine if we should continue execution after a SIGTRAP signal when
+ * executing in the given mode.
+ */
+BOOL DEBUG_ShouldContinue( struct sigcontext_struct *context,
+ enum exec_mode mode )
+{
+ unsigned int segment, addr;
+ int bpnum;
+
+ /* If not single-stepping, back up over the int3 instruction */
+ if (!(EFL & STEP_FLAG)) EIP--;
+
+ segment = (CS == WINE_CODE_SELECTOR) ? 0 : CS;
+ addr = EIP;
+ bpnum = DEBUG_FindBreakpoint( segment, addr );
+ breakpoints[0].enabled = 0; /* disable the step-over breakpoint */
+
+ if ((bpnum != 0) && (bpnum != -1))
+ {
+ fprintf( stderr, "Stopped on breakpoint %d at ", bpnum );
+ print_address( breakpoints[bpnum].segment, breakpoints[bpnum].addr,
+ breakpoints[bpnum].addrlen );
+ fprintf( stderr, "\n" );
+ return FALSE;
+ }
+ /* no breakpoint, continue if in continuous mode */
+ return (mode == EXEC_CONT);
+}
+
+
+/***********************************************************************
+ * DEBUG_RestartExecution
+ *
+ * Set the breakpoints to the correct state to restart execution
+ * in the given mode.
+ */
+void DEBUG_RestartExecution( struct sigcontext_struct *context,
+ enum exec_mode mode, int instr_len )
+{
+ unsigned int segment, addr;
+
+ segment = (CS == WINE_CODE_SELECTOR) ? 0 : CS;
+ addr = EIP;
+
+ if (DEBUG_FindBreakpoint( segment, addr ) != -1)
+ mode = EXEC_STEP_INSTR; /* If there's a breakpoint, skip it */
+
+ switch(mode)
+ {
+ case EXEC_CONT: /* Continuous execution */
+ EFL &= ~STEP_FLAG;
+ DEBUG_SetBreakpoints( TRUE );
+ break;
+
+ case EXEC_STEP_OVER: /* Stepping over a call */
+ EFL &= ~STEP_FLAG;
+ breakpoints[0].segment = segment;
+ breakpoints[0].addr = addr + instr_len;
+ breakpoints[0].enabled = TRUE;
+ breakpoints[0].in_use = TRUE;
+ breakpoints[0].opcode = segment ?
+ *(BYTE *)PTR_SEG_OFF_TO_LIN(segment,addr+instr_len) : *(BYTE *)addr;
+ DEBUG_SetBreakpoints( TRUE );
+ break;
+
+ case EXEC_STEP_INSTR: /* Single-stepping an instruction */
+ EFL |= STEP_FLAG;
+ break;
+ }
}
diff --git a/debugger/db_disasm.c b/debugger/db_disasm.c
index 5d7d176..50474d6 100644
--- a/debugger/db_disasm.c
+++ b/debugger/db_disasm.c
@@ -61,25 +61,15 @@
/*
* Instruction disassembler.
*/
-#if 0
-#include <mach/boolean.h>
-#include "db_machdep.h"
-#include "db_access.h"
-#include "db_sym.h"
-
-#include <kern/task.h>
-#endif
#include <stdio.h>
-#include "db_disasm.h"
+#include "windows.h"
#include "ldt.h"
-extern void print_address( unsigned int seg, unsigned int addr, int addrlen );
-
/*
* Switch to disassemble 16-bit code.
*/
-static boolean_t db_disasm_16 = FALSE;
+static BOOL db_disasm_16 = FALSE;
/*
* Size attributes
@@ -932,13 +922,9 @@
/*
* Read address at location and return updated location.
*/
-db_addr_t
-db_read_address(segment, loc, short_addr, regmodrm, addrp)
- unsigned int segment;
- db_addr_t loc;
- int short_addr;
- int regmodrm;
- struct i_addr *addrp; /* out */
+unsigned int db_read_address( unsigned int segment, unsigned int loc,
+ int short_addr, int regmodrm,
+ struct i_addr *addrp )
{
int mod, rm, sib, index, disp;
@@ -1058,21 +1044,15 @@
fprintf(stderr,",%s,%d", addrp->index, 1<<addrp->ss);
fprintf(stderr,")");
} else
- db_task_printsym((db_addr_t)addrp->disp, size);
+ db_task_printsym(addrp->disp, size);
}
/*
* Disassemble floating-point ("escape") instruction
* and return updated location.
*/
-db_addr_t
-db_disasm_esc(segment, loc, inst, short_addr, size, seg)
- unsigned int segment;
- db_addr_t loc;
- int inst;
- int short_addr;
- int size;
- char * seg;
+unsigned int db_disasm_esc( unsigned int segment, unsigned int loc,
+ int inst, int short_addr, int size, char *seg )
{
int regmodrm;
struct finst *fp;
@@ -1151,11 +1131,7 @@
* Disassemble instruction at 'loc'. Return address of start of
* next instruction.
*/
-db_addr_t
-db_disasm(segment, loc, flag16)
- unsigned int segment;
- db_addr_t loc;
- boolean_t flag16;
+unsigned int db_disasm( unsigned int segment, unsigned int loc )
{
int inst;
int size;
@@ -1166,7 +1142,7 @@
int i_size;
int i_mode;
int regmodrm = 0;
- boolean_t first;
+ BOOL first;
int displ;
int prefix;
int imm;
@@ -1174,7 +1150,8 @@
int len;
struct i_addr address;
- db_disasm_16 = flag16;
+ if (!segment) db_disasm_16 = FALSE;
+ else db_disasm_16 = !(GET_SEL_FLAGS(segment) & LDT_FLAGS_32BIT);
get_value_inc(inst, segment, loc, 1, FALSE);
@@ -1240,7 +1217,7 @@
} while (prefix);
if (inst >= 0xd8 && inst <= 0xdf) {
- loc = db_disasm_esc(loc, inst, short_addr, size, seg);
+ loc = db_disasm_esc(segment, loc, inst, short_addr, size, seg);
fprintf(stderr,"\n");
return (loc);
}
@@ -1441,8 +1418,7 @@
if (seg)
fprintf(stderr,"%s:%d",seg, displ);
else
- db_task_printsym((db_addr_t)displ,
- short_addr ? WORD : LONG);
+ db_task_printsym(displ, short_addr ? WORD : LONG);
break;
case Db:
@@ -1454,8 +1430,7 @@
}
else
displ = displ + loc;
- db_task_printsym((db_addr_t)displ,
- short_addr ? WORD : LONG);
+ db_task_printsym(displ, short_addr ? WORD : LONG);
break;
case Dl:
@@ -1469,8 +1444,7 @@
get_value_inc(displ, segment, loc, 4, TRUE);
displ = displ + loc;
}
- db_task_printsym((db_addr_t)displ,
- short_addr ? WORD : LONG);
+ db_task_printsym( displ, short_addr ? WORD : LONG);
break;
case o1:
diff --git a/debugger/db_disasm.h b/debugger/db_disasm.h
deleted file mode 100644
index 73992d7..0000000
--- a/debugger/db_disasm.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#define FALSE 0
-#define TRUE 1
-
-typedef unsigned char boolean_t;
-typedef unsigned long db_addr_t;
-
-extern db_addr_t db_disasm(unsigned int segment, db_addr_t loc,
- boolean_t flag16);
diff --git a/debugger/dbg.y b/debugger/dbg.y
index fd8748d..c9a5585 100644
--- a/debugger/dbg.y
+++ b/debugger/dbg.y
@@ -10,24 +10,25 @@
#include <stdio.h>
#include <signal.h>
-#include "ldt.h"
+#include <unistd.h>
#include "windows.h"
-#include "wine.h"
+#include "debugger.h"
#define YYSTYPE int
-#include "regpos.h"
extern FILE * yyin;
-unsigned int * regval = NULL;
-unsigned int dbg_mask = 0;
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
@@ -40,10 +41,13 @@
%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
@@ -58,68 +62,59 @@
| infocmd '\n'
| error '\n' { yyerrok; }
| QUIT '\n' { exit(0); }
- | 'q' '\n' { exit(0); }
| HELP '\n' { dbg_help(); }
- | CONT '\n' { return 0; }
- | 'c' '\n' { return 0; }
+ | 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); }
+ | SYMBOLFILE IDENTIFIER '\n' { read_symboltable($2); }
| DEFINE IDENTIFIER expr '\n' { add_hash($2, 0, $3); }
- | MODE NUM { mode_command($2); }
- | ENABLE NUM { enable_break($2); }
- | DISABLE NUM { disable_break($2); }
- | BREAK '*' expr { add_break($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
- | BACKTRACE '\n' { dbg_bt(); }
| print_command
| deposit_command
deposit_command:
- SET REG '=' expr '\n' { if(regval) regval[$2] = $4; else application_not_running();}
+ SET REG '=' expr '\n' { DEBUG_SetRegister( $2, $4 ); }
| SET '*' expr '=' expr '\n' { *((unsigned int *) $3) = $5; }
- | SET symbol '=' expr '\n' { *((unsigned int *) $2) = $4; }
+ | SET symbol '=' expr '\n' { *((unsigned int *) $2) = $4; }
x_command:
- 'x' expr '\n' { examine_memory( 0xffffffff, $2, 1, 'x'); }
- | 'x' '/' fmt expr '\n' { examine_memory( 0xffffffff, $4, 1, $3); }
- | 'x' '/' NUM fmt expr '\n' { examine_memory( 0xffffffff, $5, $3, $4); }
+ EXAM expr '\n' { examine_memory( 0xffffffff, $2, 1, 'x'); }
+ | EXAM FORMAT expr '\n' { examine_memory( 0xffffffff, $3,
+ $2 >> 8, $2 & 0xff ); }
-print:
- 'p'
- | PRINT
-
print_command:
- print expr '\n' { examine_memory( 0, ((unsigned int) &$2 ), 1, 'x'); }
- | print '/' fmt expr '\n' { examine_memory( 0, (unsigned int) &$4, 1, $3); }
+ 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 ); }
- fmt: 'x' { $$ = 'x'; }
- | 'd' { $$ = 'd'; }
- | 'i' { $$ = 'i'; }
- | 'w' { $$ = 'w'; }
- | 's' { $$ = 's'; }
- | 'c' { $$ = 'c'; }
- | 'b' { $$ = 'b'; }
-
- symbol: IDENTIFIER { $$ = find_hash($1);
- if($$ == 0xffffffff) {
- fprintf(stderr,"Symbol %s not found\n", $1);
- YYERROR;
- }
- }
+ symbol: IDENTIFIER { if (($$ = find_hash($1)) == 0xffffffff)
+ {
+ fprintf(stderr,"Symbol %s not found\n", (char *)$1);
+ YYERROR;
+ }
+ }
expr: NUM { $$ = $1; }
- | REG { if(regval) $$ = regval[$1]; else application_not_running();}
+ | REG { $$ = DEBUG_GetRegister($1); }
| symbol { $$ = $1; }
| expr '+' NUM { $$ = $1 + $3; }
| expr '-' NUM { $$ = $1 - $3; }
| '(' expr ')' { $$ = $2; }
| '*' expr { $$ = *((unsigned int *) $2); }
- infocmd: INFO REGS { info_reg(); }
- | INFO STACK { info_stack(); }
+ infocmd: INFO REGS { DEBUG_InfoRegisters(); }
+ | INFO STACK { DEBUG_InfoStack(); }
+ | INFO BREAK { DEBUG_InfoBreakpoints(); }
| INFO SEGMENTS { LDT_Print(); }
- | INFO BREAK { info_break(); }
%%
@@ -133,78 +128,55 @@
void mode_command(int newmode)
{
- if(newmode == 16){
- dbg_mask = 0xffff;
- dbg_mode = 16;
- return;
- }
- if(newmode == 32){
- dbg_mask = 0xffffffff;
- dbg_mode = 32;
- return;
- }
- fprintf(stderr,"Invalid mode (use 16 or 32)\n");
+ if ((newmode == 16) || (newmode == 32)) dbg_mode = newmode;
+ else fprintf(stderr,"Invalid mode (use 16 or 32)\n");
}
-static int loaded_symbols = 0;
-void
-wine_debug(int signal, int * regs)
+void wine_debug( int signal, struct sigcontext_struct *regs )
{
- static int dummy_regs[32];
- char SymbolTableFile[256];
+ static int loaded_symbols = 0;
+ char SymbolTableFile[256];
+ int instr_len = 0, newmode;
#ifdef YYDEBUG
- yydebug = 0;
+ yydebug = 1;
#endif
- yyin = stdin;
- regval = regs ? regs : dummy_regs;
+ yyin = stdin;
+ context = (struct sigcontext_struct *)regs;
- if (SC_CS == WINE_CODE_SELECTOR) dbg_mode = 32;
- else dbg_mode = (GET_SEL_FLAGS(SC_CS) & LDT_FLAGS_32BIT) ? 32 : 16;
- dbg_mask = (dbg_mode == 32) ? 0xffffffff : 0xffff;
+ if (CS == WINE_CODE_SELECTOR) newmode = 32;
+ else newmode = (GET_SEL_FLAGS(CS) & LDT_FLAGS_32BIT) ? 32 : 16;
- fprintf(stderr,"In %d bit mode.\n", dbg_mode);
+ 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);
- }
+ if(dbg_mode == 32 && !loaded_symbols)
+ {
+ loaded_symbols++;
+ GetPrivateProfileString("wine", "SymbolTableFile", "wine.sym",
+ SymbolTableFile, sizeof(SymbolTableFile), WINE_INI);
+ read_symboltable(SymbolTableFile);
+ }
- /* Remove the breakpoints from memory... */
- insert_break(0);
+ DEBUG_SetBreakpoints( FALSE );
- /* If we stopped on a breakpoint, report this fact */
- if(signal == SIGTRAP)
- {
- unsigned int addr;
- int bpnum;
- addr = SC_EIP(dbg_mask);
- if (dbg_mode == 16) addr = PTR_SEG_OFF_TO_LIN( SC_CS, addr );
- if(should_continue(bpnum=get_bpnum(addr))){
- insert_break(1);
- return;
- }
- fprintf(stderr,"Stopped on breakpoint %d\n", bpnum);
- }
+ if ((signal != SIGTRAP) || !DEBUG_ShouldContinue( regs, dbg_exec_mode ))
+ {
+ unsigned int segment = (CS == WINE_CODE_SELECTOR) ? 0 : CS;
- /* Show where we crashed */
- if(regs)
- examine_memory(0xffffffff, SC_EIP(dbg_mask), 1, 'i');
+ /* 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();
+ }
- issue_prompt();
-
- yyparse();
- flush_symbols();
-
- /* Re-insert the breakpoints from memory... */
- insert_break(1);
-
- fprintf(stderr,"Returning to Wine...\n");
-
+ DEBUG_RestartExecution( regs, dbg_exec_mode, instr_len );
}
diff --git a/debugger/debug.l b/debugger/debug.l
index 68975b7..4b8ccf1 100644
--- a/debugger/debug.l
+++ b/debugger/debug.l
@@ -7,9 +7,10 @@
%{
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include "dbg.tab.h"
-#include "regpos.h"
+#include "debugger.h"
#ifdef USE_READLINE
#undef YY_INPUT
@@ -19,102 +20,89 @@
#endif
extern char * readline(char *);
+extern void add_history(char *);
+static int dbg_read(char * buf, int size);
static char * make_symbol(char *);
void flush_symbols();
static int syntax_error;
extern int yylval;
%}
-DIGIT [0-9]
-HEXDIGIT [0-9a-fA-F]
-
+DIGIT [0-9]
+HEXDIGIT [0-9a-fA-F]
+FORMAT [bcdiswx]
IDENTIFIER [_a-zA-Z\.~][_a-zA-Z0-9\.~]*
%%
-\n { syntax_error = 0; return '\n'; } /* Indicate end of command */
+\n { syntax_error = 0; return '\n'; } /*Indicate end of command*/
-"+" { return '+'; }
+[-+=()*] { return *yytext; }
-"-" { return '-'; }
+"0x"{HEXDIGIT}+ { sscanf(yytext, "%x", &yylval); return NUM; }
+{DIGIT}+ { sscanf(yytext, "%d", &yylval); return NUM; }
-"/" { return '/'; }
+"/"{DIGIT}+{FORMAT} { char *last; yylval = strtol( yytext+1, &last, NULL );
+ yylval = (yylval << 8) | *last; return FORMAT; }
+"/"{FORMAT} { yylval = (1 << 8) | yytext[1]; return FORMAT; }
-"=" { return '='; }
+$pc { yylval = REG_EIP; return REG; }
+$flags { yylval = REG_EFL; return REG; }
+$eip { yylval = REG_EIP; return REG; }
+$ip { yylval = REG_IP; return REG; }
+$esp { yylval = REG_ESP; return REG; }
+$sp { yylval = REG_SP; return REG; }
+$eax { yylval = REG_EAX; return REG; }
+$ebx { yylval = REG_EBX; return REG; }
+$ecx { yylval = REG_ECX; return REG; }
+$edx { yylval = REG_EDX; return REG; }
+$esi { yylval = REG_ESI; return REG; }
+$edi { yylval = REG_EDI; return REG; }
+$ebp { yylval = REG_EBP; return REG; }
+$ax { yylval = REG_AX; return REG; }
+$bx { yylval = REG_BX; return REG; }
+$cx { yylval = REG_CX; return REG; }
+$dx { yylval = REG_DX; return REG; }
+$si { yylval = REG_SI; return REG; }
+$di { yylval = REG_DI; return REG; }
+$bp { yylval = REG_BP; return REG; }
+$es { yylval = REG_ES; return REG; }
+$ds { yylval = REG_DS; return REG; }
+$cs { yylval = REG_CS; return REG; }
+$ss { yylval = REG_SS; return REG; }
-"(" { return '('; }
-
-")" { return ')'; }
-
-"*" { return '*'; }
-
-"?" { return HELP; }
-
-"0x"+{HEXDIGIT}+ {
- sscanf(yytext, "%x", &yylval);
- return NUM;
- }
-
-{DIGIT}+ {
- sscanf(yytext, "%d", &yylval);
- return NUM;
- }
-
-$pc { yylval = RN_EIP; return REG;}
-$sp { yylval = RN_ESP_AT_SIGNAL; return REG;}
-$eip { yylval = RN_EIP; return REG;}
-$esp { yylval = RN_ESP_AT_SIGNAL; return REG;}
-$ebp { yylval = RN_EBP; return REG;}
-$eax { yylval = RN_EAX; return REG;}
-$ebx { yylval = RN_EBX; return REG;}
-$ecx { yylval = RN_ECX; return REG;}
-$edx { yylval = RN_EDX; return REG;}
-$esi { yylval = RN_ESI; return REG;}
-$edi { yylval = RN_EDI; return REG;}
-
-$es { yylval = RN_ES; return REG;}
-$ds { yylval = RN_DS; return REG;}
-$cs { yylval = RN_CS; return REG;}
-$ss { yylval = RN_SS; return REG;}
-
-info|inf|in { return INFO; }
-segments|segm { return SEGMENTS; }
-break|brea|bre { return BREAK; }
-enable|enabl|enab|ena { return ENABLE;}
+info|inf|in { return INFO; }
+segments|segm { return SEGMENTS; }
+break|brea|bre|br|b { return BREAK; }
+enable|enabl|enab|ena { return ENABLE;}
disable|disabl|disab|disa|dis { return DISABLE; }
-
-quit|qui|qu { return QUIT; }
+delete|delet|dele|del { return DELETE; }
+quit|qui|qu|q { return QUIT; }
+x { return EXAM; }
help|hel|he { return HELP; }
+"?" { return HELP; }
set|se { return SET; }
bt { return BACKTRACE; }
-cont|con|co { return CONT; }
+cont|con|co|c { return CONT; }
+step|ste|st|s { return STEP; }
+next|nex|ne|n { return NEXT; }
symbolfile|symbolfil|symbolfi|symbolf|symbol|symbo|symb { return SYMBOLFILE; }
define|defin|defi|def|de { return DEFINE; }
abort|abor|abo { return ABORT; }
-print|prin|pri|pr { return PRINT; }
+print|prin|pri|pr|p { return PRINT; }
mode { return MODE; }
-regs|reg|re { return REGS; }
+registers|regs|reg|re { return REGS; }
stack|stac|sta|st { return STACK; }
-p { return 'p'; }
-x { return 'x'; }
-d { return 'd'; }
-i { return 'i'; }
-w { return 'w'; }
-b { return 'b'; }
-s { return 's'; }
-c { return 'c'; }
-q { return 'q'; }
-
{IDENTIFIER} {yylval = (int) make_symbol(yytext);
return IDENTIFIER;
}
@@ -161,35 +149,45 @@
string[++i] = '\0';
}
-dbg_read(char * buf, int size){
- char * line;
- int len;
+static int dbg_read(char * buf, int size)
+{
+ static char last_line[256] = "";
+ char * line;
+ int len;
+
+ for (;;)
+ {
+ flush_symbols();
+ line = readline ("Wine-dbg>");
+ if (!line) exit(0);
- do{
- flush_symbols();
- line = readline ("Wine-dbg>");
- if (!line) return 0;
- len = strlen(line);
+ /* Remove leading and trailing whitespace from the line.
+ Then, if there is anything left, add it to the history list
+ and execute it. */
+ stripwhite (line);
- /* Remove leading and trailing whitespace from the line.
- Then, if there is anything left, add it to the history list
- and execute it. */
- stripwhite (line);
-
- if (*line)
- {
- add_history (line);
- if(size < len + 1){
- fprintf(stderr,"Fatal readline goof.\n");
- exit(0);
- }
- strcpy(buf, line);
- buf[len] = '\n';
- buf[len+1] = 0;
- free(line);
- return len + 1;
- }
- } while (1==1);
+ if (*line)
+ {
+ add_history( line );
+ strncpy( last_line, line, 255 );
+ last_line[255] = '\0';
+ }
+ else line = last_line; /* Repeat previous command */
+
+ if ((len = strlen(line)) > 0)
+ {
+ if (size < len + 1)
+ {
+ fprintf(stderr,"Fatal readline goof.\n");
+ exit(0);
+ }
+ strcpy(buf, line);
+ buf[len] = '\n';
+ buf[len+1] = 0;
+ free(line);
+ return len + 1;
+ }
+ }
}
static char *local_symbols[10];
diff --git a/debugger/dtest.c b/debugger/dtest.c
deleted file mode 100644
index 3872cbf..0000000
--- a/debugger/dtest.c
+++ /dev/null
@@ -1,87 +0,0 @@
-#include <signal.h>
-#include <stdio.h>
-
-extern void wine_debug(unsigned int*);
-
-
-#ifdef linux
-#include <linux/sched.h>
-#include <asm/system.h>
-#endif
-
-struct sigaction segv_act;
-
-#ifdef linux
-
-struct sigcontext_struct {
- unsigned short sc_gs, __gsh;
- unsigned short sc_fs, __fsh;
- unsigned short sc_es, __esh;
- unsigned short sc_ds, __dsh;
- unsigned long sc_edi;
- unsigned long sc_esi;
- unsigned long sc_ebp;
- unsigned long sc_esp;
- unsigned long sc_ebx;
- unsigned long sc_edx;
- unsigned long sc_ecx;
- unsigned long sc_eax;
- unsigned long sc_trapno;
- unsigned long sc_err;
- unsigned long sc_eip;
- unsigned short sc_cs, __csh;
- unsigned long sc_eflags;
- unsigned long esp_at_signal;
- unsigned short sc_ss, __ssh;
- unsigned long i387;
- unsigned long oldmask;
- unsigned long cr2;
-};
-#endif
-
-#ifdef linux
-static void win_fault(int signal, struct sigcontext_struct context){
- struct sigcontext_struct *scp = &context;
-#else
-static void win_fault(int signal, int code, struct sigcontext *scp){
-#endif
-
- wine_debug((unsigned int *) scp); /* Enter our debugger */
-}
-
-char realtext[] = "This is what should really be printed\n";
-
-int
-main(){
- char * pnt;
-#ifdef linux
- segv_act.sa_handler = (__sighandler_t) win_fault;
- sigaction(SIGSEGV, &segv_act, NULL);
-#endif
-#if defined(__NetBSD__) || defined(__FreeBSD__)
- sigset_t sig_mask;
-
- sigemptyset(&sig_mask);
- segv_act.sa_handler = (__sighandler_t) win_fault;
- segv_act.sa_flags = 0;
- segv_act.sa_mask = sig_mask;
- if (sigaction(SIGSEGV, &segv_act, NULL) < 0) {
- perror("sigaction");
- exit(1);
- }
-#endif
-
- fprintf(stderr,"%x\n", realtext);
-
- /* Now force a segmentation fault */
- pnt = (char *) 0xc0000000;
-
- fprintf(stderr,"%s", pnt);
- return 0;
-
-}
-
-
-unsigned int * wine_files = NULL;
-
-GetEntryPointFromOrdinal(int wpnt, int ordinal) {}
diff --git a/debugger/hash.c b/debugger/hash.c
index 5136c1c..bca6553 100644
--- a/debugger/hash.c
+++ b/debugger/hash.c
@@ -155,10 +155,6 @@
}
-/* Load the entry points from the dynamic linking into the hash tables.
- * This does not work yet - something needs to be added before it scans the
- * tables correctly
- */
void load_entrypoints( HMODULE hModule )
{
diff --git a/debugger/info.c b/debugger/info.c
index 3f99349..65f8bbd 100644
--- a/debugger/info.c
+++ b/debugger/info.c
@@ -6,16 +6,10 @@
#include <stdio.h>
#include <stdlib.h>
-#include "ldt.h"
-#include "db_disasm.h"
-#include "regpos.h"
+#include "debugger.h"
extern char * find_nearest_symbol( unsigned int seg, unsigned int addr );
-extern int * regval;
-extern unsigned int dbg_mask;
-extern unsigned int dbg_mode;
-
void application_not_running()
{
fprintf(stderr,"Application not running\n");
@@ -32,54 +26,6 @@
}
-void info_reg(){
-
- if(!regval) {
- application_not_running();
- return;
- }
-
- fprintf(stderr,"Register dump:\n");
- /* First get the segment registers out of the way */
- fprintf(stderr," CS:%4.4x SS:%4.4x DS:%4.4x ES:%4.4x GS:%4.4x FS:%4.4x\n",
- SC_CS, SC_SS, SC_DS, SC_ES, SC_GS, SC_FS);
-
- /* Now dump the main registers */
- fprintf(stderr," EIP:%8.8x ESP:%8.8x EBP:%8.8x EFLAGS:%8.8x\n",
- SC_EIP(dbg_mask), SC_ESP(dbg_mask), SC_EBP(dbg_mask), SC_EFLAGS);
-
- /* And dump the regular registers */
-
- fprintf(stderr," EAX:%8.8x EBX:%8.8x ECX:%8.8x EDX:%8.8x\n",
- SC_EAX(dbg_mask), SC_EBX(dbg_mask), SC_ECX(dbg_mask), SC_EDX(dbg_mask));
-
- /* Finally dump these main registers */
- fprintf(stderr," EDI:%8.8x ESI:%8.8x\n",
- SC_EDI(dbg_mask), SC_ESI(dbg_mask));
-
-}
-
-void info_stack(){
- unsigned int * dump;
- int i;
-
- if(!regval) {
- application_not_running();
- return;
- }
-
- fprintf(stderr,"Stack dump:\n");
- dump = (int*) SC_ESP(dbg_mask);
- for(i=0; i<22; i++)
- {
- fprintf(stderr," %8.8x", *dump++);
- if ((i % 8) == 7)
- fprintf(stderr,"\n");
- }
- fprintf(stderr,"\n");
-}
-
-
void examine_memory( unsigned int segment, unsigned int addr,
int count, char format )
{
@@ -88,9 +34,10 @@
unsigned short int * wdump;
int i;
- if (segment == 0xffffffff)
- segment = (dbg_mode == 32) ? 0 : (format == 'i' ? SC_CS : SC_DS);
-
+ if (segment == 0xffffffff) segment = (format == 'i' ? CS : DS);
+ if ((segment == WINE_CODE_SELECTOR) || (segment == WINE_DATA_SELECTOR))
+ segment = 0;
+
if (format != 'i' && count > 1)
{
print_address( segment, addr, dbg_mode );
@@ -114,7 +61,7 @@
for(i=0; i<count; i++) {
print_address( segment, addr, dbg_mode );
fprintf(stderr,": ");
- addr = db_disasm( segment, addr, (dbg_mode == 16) );
+ addr = db_disasm( segment, addr );
fprintf(stderr,"\n");
};
return;
@@ -152,7 +99,7 @@
wdump = (unsigned short *)pnt;
for(i=0; i<count; i++)
{
- fprintf(stderr," %x", *wdump++);
+ fprintf(stderr," %04x", *wdump++);
addr += 2;
if ((i % 10) == 7) {
fprintf(stderr,"\n");
@@ -205,14 +152,15 @@
"The commands accepted by the Wine debugger are a small subset",
"of the commands that gdb would accept. The commands currently",
"are:\n",
-" break *<addr> bt",
+" break [*<addr>] delete break bpnum",
" disable bpnum enable bpnum",
" help quit",
" x <expr> cont",
+" step next",
" mode [16,32] print <expr>",
" set <reg> = <expr> set *<expr> = <expr>",
-" info [reg,stack,break,segments] symbolfile <filename>",
-" define <identifier> <expr>",
+" info [reg,stack,break,segments] bt",
+" symbolfile <filename> define <identifier> <expr>",
"",
"The 'x' command accepts repeat counts and formats (including 'i') in the",
"same way that gdb does.",
@@ -230,57 +178,3 @@
i = 0;
while(helptext[i]) fprintf(stderr,"%s\n", helptext[i++]);
}
-
-
-struct frame{
- union{
- struct {
- unsigned short saved_bp;
- unsigned short saved_ip;
- unsigned short saved_cs;
- } win16;
- struct {
- unsigned long saved_bp;
- unsigned long saved_ip;
- unsigned short saved_cs;
- } win32;
- } u;
-};
-
-
-void dbg_bt(){
- struct frame * frame;
- unsigned short cs;
- int frameno = 0;
-
- if(!regval) {
- application_not_running();
- return;
- }
-
- if (dbg_mode == 16)
- frame = (struct frame *)PTR_SEG_OFF_TO_LIN( SC_SS, SC_BP & ~1 );
- else
- frame = (struct frame *)SC_EBP(dbg_mask);
-
- fprintf(stderr,"Backtrace:\n");
- cs = SC_CS;
- while((cs & 3) == 3) {
- /* See if in 32 bit mode or not. Assume GDT means 32 bit. */
- if ((cs & 7) != 7) {
- fprintf(stderr,"%d ",frameno++);
- print_address( 0, frame->u.win32.saved_ip, 32 );
- fprintf( stderr, "\n" );
- if (!frame->u.win32.saved_ip) break;
- frame = (struct frame *) frame->u.win32.saved_bp;
- } else {
- if (frame->u.win16.saved_bp & 1) cs = frame->u.win16.saved_cs;
- fprintf(stderr,"%d %4.4x:%4.4x\n", frameno++, cs,
- frame->u.win16.saved_ip);
- if (!frame->u.win16.saved_bp) break;
- frame = (struct frame *) PTR_SEG_OFF_TO_LIN( SC_SS, frame->u.win16.saved_bp & ~1);
- }
- }
- putchar('\n');
-}
-
diff --git a/debugger/registers.c b/debugger/registers.c
new file mode 100644
index 0000000..4d948e9
--- /dev/null
+++ b/debugger/registers.c
@@ -0,0 +1,119 @@
+/*
+ * Debugger register handling
+ *
+ * Copyright 1995 Alexandre Julliard
+ */
+
+#include <stdio.h>
+#include "debugger.h"
+
+
+struct sigcontext_struct *context;
+
+
+
+/***********************************************************************
+ * DEBUG_SetRegister
+ *
+ * Set a register value.
+ */
+void DEBUG_SetRegister( enum debug_regs reg, int val )
+{
+ switch(reg)
+ {
+ case REG_EAX: EAX = val; break;
+ case REG_EBX: EBX = val; break;
+ case REG_ECX: ECX = val; break;
+ case REG_EDX: EDX = val; break;
+ case REG_ESI: ESI = val; break;
+ case REG_EDI: EDI = val; break;
+ case REG_EBP: EBP = val; break;
+ case REG_EFL: EFL = val; break;
+ case REG_EIP: EIP = val; break;
+ case REG_ESP: ESP = val; break;
+ case REG_AX: AX = val; break;
+ case REG_BX: BX = val; break;
+ case REG_CX: CX = val; break;
+ case REG_DX: DX = val; break;
+ case REG_SI: SI = val; break;
+ case REG_DI: DI = val; break;
+ case REG_BP: BP = val; break;
+ case REG_FL: FL = val; break;
+ case REG_IP: IP = val; break;
+ case REG_SP: SP = val; break;
+ case REG_CS: CS = val; break;
+ case REG_DS: DS = val; break;
+ case REG_ES: ES = val; break;
+ case REG_SS: SS = val; break;
+ }
+}
+
+
+/***********************************************************************
+ * DEBUG_GetRegister
+ *
+ * Get a register value.
+ */
+int DEBUG_GetRegister( enum debug_regs reg )
+{
+ switch(reg)
+ {
+ case REG_EAX: return EAX;
+ case REG_EBX: return EBX;
+ case REG_ECX: return ECX;
+ case REG_EDX: return EDX;
+ case REG_ESI: return ESI;
+ case REG_EDI: return EDI;
+ case REG_EBP: return EBP;
+ case REG_EFL: return EFL;
+ case REG_EIP: return EIP;
+ case REG_ESP: return ESP;
+ case REG_AX: return AX;
+ case REG_BX: return BX;
+ case REG_CX: return CX;
+ case REG_DX: return DX;
+ case REG_SI: return SI;
+ case REG_DI: return DI;
+ case REG_BP: return BP;
+ case REG_FL: return FL;
+ case REG_IP: return IP;
+ case REG_SP: return SP;
+ case REG_CS: return CS;
+ case REG_DS: return DS;
+ case REG_ES: return ES;
+ case REG_SS: return SS;
+ }
+ return 0; /* should not happen */
+}
+
+
+
+/***********************************************************************
+ * DEBUG_InfoRegisters
+ *
+ * Display registers information.
+ */
+void DEBUG_InfoRegisters(void)
+{
+ fprintf(stderr,"Register dump:\n");
+
+ /* First get the segment registers out of the way */
+ fprintf( stderr," CS:%04x SS:%04x DS:%04x ES:%04x\n", CS, SS, DS, ES );
+
+ if (dbg_mode == 16)
+ {
+ fprintf( stderr," IP:%04x SP:%04x BP:%04x FLAGS:%04x\n",
+ IP, SP, BP, FL );
+ fprintf( stderr," AX:%04x BX:%04x CX:%04x DX:%04x SI:%04x DI:%04x\n",
+ AX, BX, CX, DX, SI, DI );
+ }
+ else /* 32-bit mode */
+ {
+ fprintf( stderr, " EIP:%08lx ESP:%08lx EBP:%08lx EFLAGS:%08lx\n",
+ EIP, ESP, EBP, EFL );
+ fprintf( stderr, " EAX:%08lx EBX:%08lx ECX:%08lx EDX:%08lx\n",
+ EAX, EBX, ECX, EDX);
+ fprintf( stderr, " ESI:%08lx EDI:%08lx\n", ESI, EDI);
+ }
+}
+
diff --git a/debugger/regpos.h b/debugger/regpos.h
deleted file mode 100644
index e4068e1..0000000
--- a/debugger/regpos.h
+++ /dev/null
@@ -1,106 +0,0 @@
-
-#ifdef linux
-/* Register numbers */
-#define RN_GS 0
-#define RN_FS 1
-#define RN_ES 2
-#define RN_DS 3
-#define RN_EDI 4
-#define RN_ESI 5
-#define RN_EBP 6
-#define RN_ESP 7
-#define RN_EBX 8
-#define RN_EDX 9
-#define RN_ECX 10
-#define RN_EAX 11
-#define RN_TRAPNO 12
-#define RN_ERR 13
-#define RN_EIP 14
-#define RN_CS 15
-#define RN_EFLAGS 16
-#define RN_ESP_AT_SIGNAL 17
-#define RN_SS 18
-#define RN_I387 19
-#define RN_OLDMASK 20
-#define RN_CR2 21
-#endif
-
-#ifdef __NetBSD__
-/* Register numbers */
-#define RN_GS 0
-#define RN_FS 1
-#define RN_ES 2
-#define RN_DS 3
-#define RN_EDI 4
-#define RN_ESI 5
-#define RN_EBP 6
-#define RN_EBX 7
-#define RN_EDX 8
-#define RN_ECX 9
-#define RN_EAX 10
-#define RN_EIP 11
-#define RN_CS 12
-#define RN_EFLAGS 13
-#define RN_ESP_AT_SIGNAL 14
-#define RN_SS 15
-#define RN_OLDMASK 17
-#endif
-
-#ifdef __FreeBSD__
-#define RN_OLDMASK 1
-/* Register numbers */
-#define RN_ESP 2
-#define RN_EBP 3
-#define RN_ESP_AT_SIGNAL 4
-#define RN_EIP 5
-#define RN_EFLAGS 6
-#define RN_ES 7
-#define RN_DS 8
-#define RN_CS 9
-#define RN_SS 10
-#define RN_EDI 11
-#define RN_ESI 12
-#define RN_EBX 13
-#define RN_EDX 14
-#define RN_ECX 15
-#define RN_EAX 16
-/* FreeBSD doesn't save gs or fs */
-#define SC_GS 0x27
-#define SC_FS 0x27
-#endif
-
-#ifdef linux
-#define SC_GS regval[RN_GS]
-#define SC_FS regval[RN_FS]
-#define I387 regval[RN_I387]
-#define CR2 regval[RN_CR2]
-#endif
-#ifdef __NetBSD__
-#define SC_GS regval[RN_GS]
-#define SC_FS regval[RN_FS]
-#endif
-#define SC_ES regval[RN_ES]
-#define SC_DS regval[RN_DS]
-#define SC_EDI(dbg_mask) (regval[RN_EDI] & dbg_mask)
-#define SC_ESI(dbg_mask) (regval[RN_ESI] & dbg_mask)
-#define SC_EBP(dbg_mask) (regval[RN_EBP] & dbg_mask)
-#define SC_EBX(dbg_mask) (regval[RN_EBX] & dbg_mask)
-#define SC_EDX(dbg_mask) (regval[RN_EDX] & dbg_mask)
-#define SC_ECX(dbg_mask) (regval[RN_ECX] & dbg_mask)
-#define SC_EAX(dbg_mask) (regval[RN_EAX] & dbg_mask)
-#define SC_DI (regval[RN_EDI] & 0xffff)
-#define SC_SI (regval[RN_ESI] & 0xffff)
-#define SC_BP (regval[RN_EBP] & 0xffff)
-#define SC_SP (regval[RN_ESP] & 0xffff)
-#define SC_BX (regval[RN_EBX] & 0xffff)
-#define SC_DX (regval[RN_EDX] & 0xffff)
-#define SC_CX (regval[RN_ECX] & 0xffff)
-#define SC_AX (regval[RN_EAX] & 0xffff)
-#define SC_TRAPNO regval[RN_TRAPNO]
-#define SC_ERR regval[RN_ERR]
-#define SC_EIP(dbg_mask) (regval[RN_EIP] & dbg_mask)
-#define SC_CS regval[RN_CS]
-#define SC_EFLAGS regval[RN_EFLAGS]
-#define SC_ESP(dbg_mask) (regval[RN_ESP_AT_SIGNAL] & dbg_mask)
-#define SC_SS regval[RN_SS]
-#define OLDMASK regval[RN_OLDMASK]
diff --git a/debugger/stack.c b/debugger/stack.c
new file mode 100644
index 0000000..16a4b62
--- /dev/null
+++ b/debugger/stack.c
@@ -0,0 +1,89 @@
+/*
+ * Debugger stack handling
+ *
+ * Copyright 1995 Alexandre Julliard
+ */
+
+#include <stdio.h>
+#include "windows.h"
+#include "debugger.h"
+
+
+typedef struct
+{
+ WORD bp;
+ WORD ip;
+ WORD cs;
+} FRAME16;
+
+typedef struct
+{
+ DWORD bp;
+ DWORD ip;
+ WORD cs;
+} FRAME32;
+
+
+
+/***********************************************************************
+ * DEBUG_InfoStack
+ *
+ * Dump the top of the stack
+ */
+void DEBUG_InfoStack(void)
+{
+ fprintf(stderr,"Stack dump:\n");
+ if ((SS == WINE_DATA_SELECTOR) ||
+ (GET_SEL_FLAGS(SS) & LDT_FLAGS_32BIT)) /* 32-bit mode */
+ {
+ examine_memory( 0, ESP, 10, 'x' );
+ }
+ else /* 16-bit mode */
+ {
+ examine_memory( SS, SP, 10, 'w' );
+ }
+ fprintf(stderr,"\n");
+}
+
+
+/***********************************************************************
+ * DEBUG_BackTrace
+ *
+ * Display a stack back-trace.
+ */
+void DEBUG_BackTrace(void)
+{
+ int frameno = 0;
+
+ fprintf(stderr,"Backtrace:\n");
+ if (SS == WINE_DATA_SELECTOR) /* 32-bit mode */
+ {
+ FRAME32 *frame = (FRAME32 *)EBP;
+ while (frame->ip)
+ {
+ fprintf(stderr,"%d ",frameno++);
+ print_address( 0, frame->ip, 32 );
+ fprintf( stderr, "\n" );
+ frame = (FRAME32 *)frame->bp;
+ }
+ }
+ else /* 16-bit mode */
+ {
+ FRAME16 *frame = (FRAME16 *)PTR_SEG_OFF_TO_LIN( SS, BP & ~1 );
+ WORD cs = CS;
+ if (GET_SEL_FLAGS(SS) & LDT_FLAGS_32BIT)
+ {
+ fprintf( stderr, "Not implemented: 32-bit backtrace on a different stack segment.\n" );
+ return;
+ }
+ while (frame->bp)
+ {
+ if (frame->bp & 1) cs = frame->cs;
+ fprintf( stderr,"%d ", frameno++ );
+ print_address( cs, frame->ip, 16 );
+ fprintf( stderr, "\n" );
+ frame = (FRAME16 *)PTR_SEG_OFF_TO_LIN( SS, frame->bp & ~1 );
+ }
+ }
+ fprintf( stderr, "\n" );
+}