Made Wine's debugger work satisfactorily with DOS apps.
Perhaps dereferencing work better for Win16 apps too now, but
it appears the debugger core wasn't designed for segmentation.
diff --git a/debugger/break.c b/debugger/break.c
index 04c269c..d625006 100644
--- a/debugger/break.c
+++ b/debugger/break.c
@@ -16,6 +16,7 @@
#include "toolhelp.h"
#include "windows.h"
#include "debugger.h"
+#include "dosexe.h"
#define INT3 0xcc /* int 3 opcode */
@@ -97,6 +98,7 @@
/* Handle call instructions */
+ case 0xcd: /* int <intno> */
case 0xe8: /* call <offset> */
case 0x9a: /* lcall <seg>:<off> */
return TRUE;
@@ -347,9 +349,9 @@
if (!(pModule = NE_GetPtr( entry.hModule ))) continue;
if (pModule->flags & NE_FFLAGS_LIBMODULE) continue; /* Library */
- if (pModule->dos_image) { /* DOS module */
- addr.seg = pModule->cs | ((DWORD)pModule->self << 16);
- addr.off = pModule->ip;
+ if (pModule->lpDosTask) { /* DOS module */
+ addr.seg = pModule->lpDosTask->init_cs | ((DWORD)pModule->self << 16);
+ addr.off = pModule->lpDosTask->init_ip;
fprintf( stderr, "DOS task '%s': ", entry.szModule );
DEBUG_AddBreakpoint( &addr );
} else
diff --git a/debugger/db_disasm.c b/debugger/db_disasm.c
index 65fb9e5..cde7c29 100644
--- a/debugger/db_disasm.c
+++ b/debugger/db_disasm.c
@@ -1160,7 +1160,7 @@
* Set this so we get can supress the printout if we need to.
*/
db_display = display;
- db_disasm_16 = !IS_SELECTOR_32BIT(addr->seg);
+ db_disasm_16 = IS_SELECTOR_V86(addr->seg) || !IS_SELECTOR_32BIT(addr->seg);
get_value_inc( inst, addr, 1, FALSE );
diff --git a/debugger/dbg.y b/debugger/dbg.y
index c56ce96..f6a89bd 100644
--- a/debugger/dbg.y
+++ b/debugger/dbg.y
@@ -230,8 +230,11 @@
DBG_ADDR addr = { NULL,
CS_reg(&DEBUG_context),
EIP_reg(&DEBUG_context) };
-
+ TDB *pTask = (TDB*)GlobalLock16( GetCurrentTask() );
+ if (ISV86(&DEBUG_context))
+ addr.seg |= (DWORD)(pTask?(pTask->hModule):0)<<16;
DBG_FIX_ADDR_SEG( &addr, CS_reg(&DEBUG_context) );
+ GlobalUnlock16( GetCurrentTask() );
DEBUG_FindNearestSymbol(&addr, TRUE,
&nh, 0, NULL);
if( nh != NULL )
@@ -249,6 +252,10 @@
| tBREAK tEOL { DBG_ADDR addr = { NULL,
CS_reg(&DEBUG_context),
EIP_reg(&DEBUG_context) };
+ TDB *pTask = (TDB*)GlobalLock16( GetCurrentTask() );
+ if (ISV86(&DEBUG_context))
+ addr.seg |= (DWORD)(pTask?(pTask->hModule):0)<<16;
+ GlobalUnlock16( GetCurrentTask() );
DEBUG_AddBreakpoint( &addr );
}
diff --git a/debugger/expr.c b/debugger/expr.c
index f097f7d..9637f8a 100644
--- a/debugger/expr.c
+++ b/debugger/expr.c
@@ -12,6 +12,7 @@
#include <sys/types.h>
#include <neexe.h>
#include "module.h"
+#include "task.h"
#include "selectors.h"
#include "debugger.h"
#include "xmalloc.h"
@@ -494,6 +495,11 @@
case EXP_OP_SEG:
rtn.seg = VAL(exp1);
exp->un.binop.result = VAL(exp2);
+ if (ISV86(&DEBUG_context)) {
+ TDB *pTask = (TDB*)GlobalLock16( GetCurrentTask() );
+ rtn.seg |= (DWORD)(pTask?(pTask->hModule):0)<<16;
+ GlobalUnlock16( GetCurrentTask() );
+ }
break;
case EXP_OP_LOR:
rtn.seg = 0;
diff --git a/debugger/source.c b/debugger/source.c
index 4d3715b..29e2c03 100644
--- a/debugger/source.c
+++ b/debugger/source.c
@@ -24,6 +24,7 @@
#include "peexe.h"
#include "debugger.h"
#include "peexe.h"
+#include "task.h"
#include "xmalloc.h"
struct searchlist
@@ -492,9 +493,12 @@
last = DEBUG_LastDisassemble;
if (!last.seg && !last.off)
{
+ TDB *pTask = (TDB*)GlobalLock16( GetCurrentTask() );
last.seg = CS_reg(&DEBUG_context);
last.off = EIP_reg(&DEBUG_context);
+ if (ISV86(&DEBUG_context)) last.seg |= (DWORD)(pTask?(pTask->hModule):0)<<16; else
if (IS_SELECTOR_SYSTEM(last.seg)) last.seg = 0;
+ GlobalUnlock16( GetCurrentTask() );
}
for (i=0;i<offset;i++)
if (!_disassemble(&last)) break;
diff --git a/debugger/types.c b/debugger/types.c
index 567799c..ca98a6e 100644
--- a/debugger/types.c
+++ b/debugger/types.c
@@ -349,18 +349,20 @@
long long int
DEBUG_GetExprValue(DBG_ADDR * addr, char ** format)
{
+ DBG_ADDR address = *addr;
unsigned int rtn;
struct datatype * type2 = NULL;
struct en_values * e;
char * def_format = "0x%x";
rtn = 0;
+ address.seg = 0; /* FIXME? I don't quite get this... */
assert(addr->type != NULL);
switch(addr->type->type)
{
case BASIC:
- if (!DBG_CHECK_READ_PTR( addr, addr->type->un.basic.basic_size))
+ if (!DBG_CHECK_READ_PTR( &address, addr->type->un.basic.basic_size))
{
return 0;
}
@@ -388,7 +390,7 @@
}
break;
case POINTER:
- if (!DBG_CHECK_READ_PTR( addr, 1 )) return 0;
+ if (!DBG_CHECK_READ_PTR( &address, 1 )) return 0;
rtn = (unsigned int) *((unsigned char **)addr->off);
type2 = addr->type->un.pointer.pointsto;
if( type2->type == BASIC && type2->un.basic.basic_size == 1 )
@@ -403,11 +405,12 @@
break;
case ARRAY:
case STRUCT:
- if (!DBG_CHECK_READ_PTR( addr, 1 )) return 0;
+ if (!DBG_CHECK_READ_PTR( &address, 1 )) return 0;
rtn = (unsigned int) *((unsigned char **)addr->off);
def_format = "0x%8.8x";
break;
case ENUM:
+ if (!DBG_CHECK_READ_PTR( &address, 1 )) return 0;
rtn = (unsigned int) *((unsigned char **)addr->off);
for(e = addr->type->un.enumeration.members; e; e = e->next )
{
@@ -442,6 +445,8 @@
unsigned int
DEBUG_TypeDerefPointer(DBG_ADDR * addr, struct datatype ** newtype)
{
+ DBG_ADDR address = *addr;
+
/*
* Make sure that this really makes sense.
*/
@@ -452,7 +457,8 @@
}
*newtype = addr->type->un.pointer.pointsto;
- return *(unsigned int*) (addr->off);
+ address.off = *(unsigned int*) (addr->off);
+ return (unsigned int)DBG_ADDR_TO_LIN(&address); /* FIXME: is this right (or "better") ? */
}
unsigned int