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.
This commit is contained in:
parent
a7cf4eecf2
commit
69df37199b
|
@ -16,6 +16,7 @@
|
||||||
#include "toolhelp.h"
|
#include "toolhelp.h"
|
||||||
#include "windows.h"
|
#include "windows.h"
|
||||||
#include "debugger.h"
|
#include "debugger.h"
|
||||||
|
#include "dosexe.h"
|
||||||
|
|
||||||
#define INT3 0xcc /* int 3 opcode */
|
#define INT3 0xcc /* int 3 opcode */
|
||||||
|
|
||||||
|
@ -97,6 +98,7 @@ static BOOL32 DEBUG_IsStepOverInstr()
|
||||||
|
|
||||||
/* Handle call instructions */
|
/* Handle call instructions */
|
||||||
|
|
||||||
|
case 0xcd: /* int <intno> */
|
||||||
case 0xe8: /* call <offset> */
|
case 0xe8: /* call <offset> */
|
||||||
case 0x9a: /* lcall <seg>:<off> */
|
case 0x9a: /* lcall <seg>:<off> */
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -347,9 +349,9 @@ void DEBUG_AddModuleBreakpoints(void)
|
||||||
if (!(pModule = NE_GetPtr( entry.hModule ))) continue;
|
if (!(pModule = NE_GetPtr( entry.hModule ))) continue;
|
||||||
if (pModule->flags & NE_FFLAGS_LIBMODULE) continue; /* Library */
|
if (pModule->flags & NE_FFLAGS_LIBMODULE) continue; /* Library */
|
||||||
|
|
||||||
if (pModule->dos_image) { /* DOS module */
|
if (pModule->lpDosTask) { /* DOS module */
|
||||||
addr.seg = pModule->cs | ((DWORD)pModule->self << 16);
|
addr.seg = pModule->lpDosTask->init_cs | ((DWORD)pModule->self << 16);
|
||||||
addr.off = pModule->ip;
|
addr.off = pModule->lpDosTask->init_ip;
|
||||||
fprintf( stderr, "DOS task '%s': ", entry.szModule );
|
fprintf( stderr, "DOS task '%s': ", entry.szModule );
|
||||||
DEBUG_AddBreakpoint( &addr );
|
DEBUG_AddBreakpoint( &addr );
|
||||||
} else
|
} else
|
||||||
|
|
|
@ -1160,7 +1160,7 @@ void DEBUG_Disasm( DBG_ADDR *addr, int display )
|
||||||
* Set this so we get can supress the printout if we need to.
|
* Set this so we get can supress the printout if we need to.
|
||||||
*/
|
*/
|
||||||
db_display = display;
|
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 );
|
get_value_inc( inst, addr, 1, FALSE );
|
||||||
|
|
||||||
|
|
|
@ -230,8 +230,11 @@ break_command:
|
||||||
DBG_ADDR addr = { NULL,
|
DBG_ADDR addr = { NULL,
|
||||||
CS_reg(&DEBUG_context),
|
CS_reg(&DEBUG_context),
|
||||||
EIP_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) );
|
DBG_FIX_ADDR_SEG( &addr, CS_reg(&DEBUG_context) );
|
||||||
|
GlobalUnlock16( GetCurrentTask() );
|
||||||
DEBUG_FindNearestSymbol(&addr, TRUE,
|
DEBUG_FindNearestSymbol(&addr, TRUE,
|
||||||
&nh, 0, NULL);
|
&nh, 0, NULL);
|
||||||
if( nh != NULL )
|
if( nh != NULL )
|
||||||
|
@ -249,6 +252,10 @@ break_command:
|
||||||
| tBREAK tEOL { DBG_ADDR addr = { NULL,
|
| tBREAK tEOL { DBG_ADDR addr = { NULL,
|
||||||
CS_reg(&DEBUG_context),
|
CS_reg(&DEBUG_context),
|
||||||
EIP_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 );
|
DEBUG_AddBreakpoint( &addr );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <neexe.h>
|
#include <neexe.h>
|
||||||
#include "module.h"
|
#include "module.h"
|
||||||
|
#include "task.h"
|
||||||
#include "selectors.h"
|
#include "selectors.h"
|
||||||
#include "debugger.h"
|
#include "debugger.h"
|
||||||
#include "xmalloc.h"
|
#include "xmalloc.h"
|
||||||
|
@ -494,6 +495,11 @@ DEBUG_EvalExpr(struct expr * exp)
|
||||||
case EXP_OP_SEG:
|
case EXP_OP_SEG:
|
||||||
rtn.seg = VAL(exp1);
|
rtn.seg = VAL(exp1);
|
||||||
exp->un.binop.result = VAL(exp2);
|
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;
|
break;
|
||||||
case EXP_OP_LOR:
|
case EXP_OP_LOR:
|
||||||
rtn.seg = 0;
|
rtn.seg = 0;
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include "peexe.h"
|
#include "peexe.h"
|
||||||
#include "debugger.h"
|
#include "debugger.h"
|
||||||
#include "peexe.h"
|
#include "peexe.h"
|
||||||
|
#include "task.h"
|
||||||
#include "xmalloc.h"
|
#include "xmalloc.h"
|
||||||
|
|
||||||
struct searchlist
|
struct searchlist
|
||||||
|
@ -492,9 +493,12 @@ DEBUG_Disassemble(const DBG_ADDR *xstart,const DBG_ADDR *xend,int offset)
|
||||||
last = DEBUG_LastDisassemble;
|
last = DEBUG_LastDisassemble;
|
||||||
if (!last.seg && !last.off)
|
if (!last.seg && !last.off)
|
||||||
{
|
{
|
||||||
|
TDB *pTask = (TDB*)GlobalLock16( GetCurrentTask() );
|
||||||
last.seg = CS_reg(&DEBUG_context);
|
last.seg = CS_reg(&DEBUG_context);
|
||||||
last.off = EIP_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;
|
if (IS_SELECTOR_SYSTEM(last.seg)) last.seg = 0;
|
||||||
|
GlobalUnlock16( GetCurrentTask() );
|
||||||
}
|
}
|
||||||
for (i=0;i<offset;i++)
|
for (i=0;i<offset;i++)
|
||||||
if (!_disassemble(&last)) break;
|
if (!_disassemble(&last)) break;
|
||||||
|
|
|
@ -349,18 +349,20 @@ DEBUG_InitTypes()
|
||||||
long long int
|
long long int
|
||||||
DEBUG_GetExprValue(DBG_ADDR * addr, char ** format)
|
DEBUG_GetExprValue(DBG_ADDR * addr, char ** format)
|
||||||
{
|
{
|
||||||
|
DBG_ADDR address = *addr;
|
||||||
unsigned int rtn;
|
unsigned int rtn;
|
||||||
struct datatype * type2 = NULL;
|
struct datatype * type2 = NULL;
|
||||||
struct en_values * e;
|
struct en_values * e;
|
||||||
char * def_format = "0x%x";
|
char * def_format = "0x%x";
|
||||||
|
|
||||||
rtn = 0;
|
rtn = 0;
|
||||||
|
address.seg = 0; /* FIXME? I don't quite get this... */
|
||||||
assert(addr->type != NULL);
|
assert(addr->type != NULL);
|
||||||
|
|
||||||
switch(addr->type->type)
|
switch(addr->type->type)
|
||||||
{
|
{
|
||||||
case BASIC:
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -388,7 +390,7 @@ DEBUG_GetExprValue(DBG_ADDR * addr, char ** format)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case POINTER:
|
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);
|
rtn = (unsigned int) *((unsigned char **)addr->off);
|
||||||
type2 = addr->type->un.pointer.pointsto;
|
type2 = addr->type->un.pointer.pointsto;
|
||||||
if( type2->type == BASIC && type2->un.basic.basic_size == 1 )
|
if( type2->type == BASIC && type2->un.basic.basic_size == 1 )
|
||||||
|
@ -403,11 +405,12 @@ DEBUG_GetExprValue(DBG_ADDR * addr, char ** format)
|
||||||
break;
|
break;
|
||||||
case ARRAY:
|
case ARRAY:
|
||||||
case STRUCT:
|
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);
|
rtn = (unsigned int) *((unsigned char **)addr->off);
|
||||||
def_format = "0x%8.8x";
|
def_format = "0x%8.8x";
|
||||||
break;
|
break;
|
||||||
case ENUM:
|
case ENUM:
|
||||||
|
if (!DBG_CHECK_READ_PTR( &address, 1 )) return 0;
|
||||||
rtn = (unsigned int) *((unsigned char **)addr->off);
|
rtn = (unsigned int) *((unsigned char **)addr->off);
|
||||||
for(e = addr->type->un.enumeration.members; e; e = e->next )
|
for(e = addr->type->un.enumeration.members; e; e = e->next )
|
||||||
{
|
{
|
||||||
|
@ -442,6 +445,8 @@ DEBUG_GetExprValue(DBG_ADDR * addr, char ** format)
|
||||||
unsigned int
|
unsigned int
|
||||||
DEBUG_TypeDerefPointer(DBG_ADDR * addr, struct datatype ** newtype)
|
DEBUG_TypeDerefPointer(DBG_ADDR * addr, struct datatype ** newtype)
|
||||||
{
|
{
|
||||||
|
DBG_ADDR address = *addr;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Make sure that this really makes sense.
|
* Make sure that this really makes sense.
|
||||||
*/
|
*/
|
||||||
|
@ -452,7 +457,8 @@ DEBUG_TypeDerefPointer(DBG_ADDR * addr, struct datatype ** newtype)
|
||||||
}
|
}
|
||||||
|
|
||||||
*newtype = addr->type->un.pointer.pointsto;
|
*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
|
unsigned int
|
||||||
|
|
Loading…
Reference in New Issue