📄 os2v1acc.c
字号:
}
unsigned ReqRead_mem()
{
read_mem_req *acc;
void *ret;
unsigned len;
acc = GetInPtr(0);
ret = GetOutPtr(0);
len = ReadBuffer(ret,acc->mem_addr.segment,acc->mem_addr.offset,acc->len);
return( len );
}
unsigned ReqWrite_mem()
{
write_mem_req *acc;
write_mem_ret *ret;
unsigned len;
acc = GetInPtr(0);
ret = GetOutPtr(0);
len = GetTotalSize() - sizeof(*acc);
ret->len = WriteBuffer( GetInPtr(sizeof(*ret)),
acc->mem_addr.segment, acc->mem_addr.offset, len );
return( sizeof( *ret ) );
}
static void ReadCPU( struct x86_cpu *r )
{
r->eax = Buff.u.r.AX;
r->ebx = Buff.u.r.BX;
r->ecx = Buff.u.r.CX;
r->edx = Buff.u.r.DX;
r->esi = Buff.u.r.SI;
r->edi = Buff.u.r.DI;
r->esp = Buff.u.r.SP;
r->ebp = Buff.u.r.BP;
r->eip = Buff.u.r.IP;
r->efl = Buff.u.r.FL;
r->ds = Buff.u.r.DS;
r->cs = Buff.u.r.CS;
r->es = Buff.u.r.ES;
r->ss = Buff.u.r.SS;
}
static void WriteCPU( struct x86_cpu *r )
{
Buff.u.r.AX = r->eax;
Buff.u.r.BX = r->ebx;
Buff.u.r.CX = r->ecx;
Buff.u.r.DX = r->edx;
Buff.u.r.SI = r->esi;
Buff.u.r.DI = r->edi;
Buff.u.r.SP = r->esp;
Buff.u.r.BP = r->ebp;
Buff.u.r.IP = r->eip;
Buff.u.r.FL = r->efl;
Buff.u.r.DS = r->ds;
Buff.u.r.CS = r->cs;
Buff.u.r.ES = r->es;
Buff.u.r.SS = r->ss;
}
unsigned ReqRead_cpu()
{
word *clr;
read_cpu_ret *ret;
ret = GetOutPtr(0);
for( clr = (word *)&ret->cpu;
(char *)clr < (char *)&ret->cpu + sizeof(trap_cpu_regs); ++clr ) {
*clr = 0;
}
if( Pid != 0 ) {
ReadRegs( &Buff );
ReadCPU( (struct x86_cpu *)&ret->cpu );
}
return( sizeof( read_cpu_ret ) );
}
unsigned ReqRead_fpu()
{
read_fpu_ret *ret;
TID save;
ret = GetOutPtr(0);
Buff.cmd = PT_CMD_READ_8087;
Buff.segv = FP_SEG( ret );
Buff.offv = FP_OFF( ret );
save = Buff.tid;
Buff.tid = 1; /*NYI: OS/2 V1.2 gets upset trying to read other tids */
DosPTrace( &Buff );
Buff.tid = save;
if( Buff.cmd == PT_RET_NO_NPX_YET ) return( 0 );
FPUExpand( ret );
return( sizeof( *ret ) );
}
unsigned ReqWrite_cpu()
{
trap_cpu_regs *regs;
regs = GetInPtr(sizeof(write_cpu_req));
if( Pid != 0 ) {
WriteCPU( (struct x86_cpu *)regs );
WriteRegs( &Buff );
}
return( 0 );
}
unsigned ReqWrite_fpu()
{
trap_fpu_regs *regs;
TID save;
regs = GetInPtr(sizeof(write_fpu_req));
Buff.cmd = PT_CMD_WRITE_8087;
Buff.segv = FP_SEG( regs );
Buff.offv = FP_OFF( regs );
FPUContract( regs );
save = Buff.tid;
Buff.tid = 1; /*NYI: OS/2 V1.2 gets upset trying to read other tids */
DosPTrace( &Buff );
Buff.tid = save;
return( 0 );
}
unsigned ReqRead_regs()
{
mad_registers *mr;
TID save;
mr = GetOutPtr(0);
memset( mr, 0, sizeof( mr->x86 ) );
if( Pid != 0 ) {
ReadRegs( &Buff );
ReadCPU( &mr->x86.cpu );
Buff.cmd = PT_CMD_READ_8087;
Buff.segv = FP_SEG( mr );
Buff.offv = FP_OFF( &mr->x86.fpu );
save = Buff.tid;
Buff.tid = 1; /*NYI: OS/2 V1.2 gets upset trying to read other tids */
DosPTrace( &Buff );
Buff.tid = save;
if( Buff.cmd != PT_RET_NO_NPX_YET ) {
FPUExpand( &mr->x86.fpu );
}
}
return( sizeof( mr->x86 ) );
}
unsigned ReqWrite_regs()
{
mad_registers *mr;
TID save;
mr = GetInPtr(sizeof(write_regs_req));
if( Pid != 0 ) {
WriteCPU( &mr->x86.cpu );
WriteRegs( &Buff );
Buff.cmd = PT_CMD_WRITE_8087;
Buff.segv = FP_SEG( mr );
Buff.offv = FP_OFF( &mr->x86.fpu );
FPUContract( &mr->x86.fpu );
save = Buff.tid;
Buff.tid = 1; /*NYI: OS/2 V1.2 gets upset trying to read other tids */
DosPTrace( &Buff );
Buff.tid = save;
}
return( 0 );
}
USHORT LibLoadPTrace( TRACEBUF *buff )
{
int cmd;
int value;
USHORT rv;
USHORT offv;
USHORT segv;
cmd = buff->cmd;
value = buff->value;
segv = buff->segv;
offv = buff->offv;
rv = DosPTrace( buff );
RecordModHandle( buff->mte );
for( ;; ) {
if( buff->cmd != PT_RET_LIB_LOADED ) return( rv );
RecordModHandle( buff->value );
buff->value = value;
buff->cmd = cmd;
buff->offv = offv;
buff->segv = segv;
rv = DosPTrace( buff );
}
}
#define EXE_IS_FULLSCREEN 0x0100
#define EXE_IS_PMC 0x0200
#define EXE_IS_PM 0x0300
static bool GetExeInfo( USHORT far *pCS, USHORT far *pIP, USHORT far *pExeType,
char far *name )
{
long open_rc;
HFILE handle;
USHORT shorty;
USHORT read;
ULONG new_head;
ULONG pos;
bool rc;
open_rc = OpenFile( name, 0, OPEN_PRIVATE );
if( open_rc < 0 ) return( FALSE );
handle = open_rc;
rc = FALSE;
for( ;; ) { /* guess */
if( DosChgFilePtr( handle, 0x00, 0, &pos ) != 0 ) break;
if( DosRead( handle, &shorty, sizeof( shorty ), &read ) != 0 ) break;
if( read != sizeof( shorty ) ) break;
if( shorty != 0x5a4d ) break; /* MZ */
if( DosChgFilePtr( handle, 0x18, 0, &pos ) != 0 ) break;
if( DosRead( handle, &shorty, sizeof( shorty ), &read ) != 0 ) break;
if( read != sizeof( shorty ) ) break;
if( shorty < 0x40 ) break; /* offset of relocation header */
if( DosChgFilePtr( handle, 0x3c, 0, &pos ) != 0 ) break;
if( DosRead( handle, &new_head, sizeof( new_head ), &read) != 0 ) break;
if( read != sizeof( new_head ) ) break;
if( DosChgFilePtr( handle, new_head, 0, &pos ) != 0 ) break;
if( DosRead( handle, &shorty, sizeof( shorty ), &read ) != 0 ) break;
if( read != sizeof( shorty ) ) break;
if( shorty != 0x454e ) break; /* NE */
if( DosChgFilePtr( handle, new_head+0x0c, 0, &pos ) != 0 ) break;
if( DosRead(handle,pExeType,sizeof( *pExeType ),&read) != 0 ) break;
if( read != sizeof( *pExeType ) ) break;
*pExeType &= 0x0700;
if( DosChgFilePtr( handle, new_head+0x14, 0, &pos ) != 0 ) break;
if( DosRead( handle, pIP, sizeof( *pIP ), &read ) != 0 ) break;
if( read != sizeof( *pIP ) ) break;
if( DosChgFilePtr( handle, new_head+0x16, 0, &pos ) != 0 ) break;
if( DosRead( handle, pCS, sizeof( *pCS ), &read ) != 0 ) break;
if( read != sizeof( *pCS ) ) break;
rc = TRUE;
break;
}
DosClose( handle );
return( rc );
}
typedef struct {
USHORT phmod[2]; /* offset-segment */
USHORT mod_name[2]; /* offset-segment */
USHORT fail_len;
PSZ fail_name; /* offset-segment */
USHORT hmod;
BYTE load_name[2];
} loadstack_t;
#define LOAD_THIS_DLL_SIZE 6
static bool CausePgmToLoadThisDLL( USHORT startCS, USHORT startIP )
{
char savecode[LOAD_THIS_DLL_SIZE];
USHORT codesize;
USHORT len;
loadstack_t far *loadstack;
USHORT dll_name_len;
char this_dll[BUFF_SIZE];
/* save a chunk of the program's code */
if( DosGetModName( ThisDLLModHandle, BUFF_SIZE, this_dll ) != 0 ) {
return( FALSE );
}
codesize = (char *)EndLoadThisDLL - (char *)LoadThisDLL;
if( codesize > LOAD_THIS_DLL_SIZE ) return( FALSE );
len = ReadBuffer( savecode, startCS, startIP, codesize );
if( Buff.cmd != PT_RET_SUCCESS ) return( FALSE );
if( len != codesize ) return( FALSE );
/* write the routine LoadThisDLL into program's code */
len = WriteBuffer( (char far *)LoadThisDLL, startCS, startIP, codesize );
if( len != codesize ) return( FALSE );
/* set up the stack for the routine LoadThisDLL */
dll_name_len = ( strlen( this_dll ) + 1 ) & ~1;
loadstack = Automagic( sizeof( loadstack_t ) + dll_name_len );
Buff.u.r.SP -= sizeof( loadstack_t ) + dll_name_len;
strcpy( loadstack->load_name, this_dll );
loadstack->fail_name = NULL;
loadstack->fail_len = 0;
loadstack->mod_name[0] = Buff.u.r.SP + offsetof( loadstack_t, load_name );
loadstack->mod_name[1] = Buff.u.r.SS;
loadstack->phmod[0] = Buff.u.r.SP + offsetof( loadstack_t, hmod );
loadstack->phmod[1] = Buff.u.r.SS;
len = WriteBuffer( (char far *)loadstack, Buff.u.r.SS,
Buff.u.r.SP, sizeof( loadstack_t ) + dll_name_len );
if( len != sizeof( loadstack_t ) + dll_name_len ) return( FALSE );
/* execute LoadThisDLL on behalf of the program */
WriteRegs( &Buff );
ExecuteCode( &Buff );
if( Buff.cmd != PT_RET_BREAK ) {
WriteBuffer( savecode, startCS, startIP, codesize );
return( FALSE );
} else {
WriteBuffer( savecode, startCS, startIP, codesize );
return( TRUE );
}
}
static void ExecuteUntil( USHORT CS, USHORT IP )
{
byte saved;
byte breakpt = 0xCC;
ReadBuffer( &saved, CS, IP, sizeof( byte ) );
WriteBuffer( &breakpt, CS, IP, sizeof( byte ) );
do {
Buff.cmd = PT_CMD_GO;
LibLoadPTrace( &Buff );
ReadRegs( &Buff );
} while( Buff.u.r.CS != CS || Buff.u.r.IP != IP );
WriteBuffer( &saved, CS, IP, sizeof( byte ) );
}
void AppSession()
{
DosSelectSession( SID, 0 );
}
void DebugSession()
{
DosSelectSession( 0, 0 );
}
unsigned ReqProg_load()
{
NEWSTARTDATA start;
char *parms;
char *end;
char *prog;
TRACEBUF save;
char exe_name[255];
USHORT startCS, startIP;
USHORT exe_type;
prog_load_ret *ret;
char appname[200];
ret = GetOutPtr( 0 );
ExceptNum = -1;
AtEnd = FALSE;
prog = GetInPtr( sizeof( prog_load_req ) );
if( FindFilePath( prog, exe_name, OS2ExtList ) != 0 ) {
exe_name[0] = '\0';
}
parms = AddDriveAndPath( exe_name, UtilBuff );
while( *prog != '\0' ) ++prog;
++prog;
end = (char *)GetInPtr( GetTotalSize()-1 ) + 1;
MergeArgvArray( prog, parms, end - prog );
CanExecTask = TRUE;
if( !GetExeInfo( &startCS, &startIP, &exe_type, UtilBuff ) ) {
CanExecTask = FALSE;
exe_type = EXE_IS_FULLSCREEN;
}
start.Length = 50;
start.Related = 1;
start.FgBg = !Remote;
start.TraceOpt = 1;
strcpy( appname, TRP_The_WATCOM_Debugger );
strcat( appname, ": " );
strcat( appname, exe_name );
start.PgmTitle = appname;
start.PgmName = UtilBuff;
start.PgmInputs = parms;
start.TermQ = 0;
start.Environment = NULL;
start.InheritOpt = 1;
start.IconFile = NULL;
start.PgmHandle = 0;
start.PgmControl = 0;
if( exe_type == EXE_IS_PM ) {
start.SessionType = SSF_TYPE_PM;
} else {
start.SessionType = SessionType; /* set by TaskInit */
}
ret->err = DosStartSession( (PSTARTDATA)&start, &SID, &Pid );
switch( ret->err ) {
case ERROR_SMG_START_IN_BACKGROUND:
/* this one's OK */
ret->err = 0;
break;
}
ret->flags = LD_FLAG_IS_PROT;
ret->task_id = Pid;
Buff.pid = Pid;
Buff.tid = 1;
if( ret->err != 0 ) {
Pid = 0;
} else {
Buff.cmd = PT_CMD_STOP;
LibLoadPTrace( &Buff );
if( Buff.cmd != PT_RET_SUCCESS ) {
ret->err = 14; /* can't load */
return( sizeof( *ret ) );
}
ReadRegs( &Buff );
if( CanExecTask ) {
Buff.cmd = PT_CMD_SEG_TO_SEL;
Buff.value = startCS;
Buff.mte = ModHandles[ 0 ];
DosPTrace( &Buff );
if( Buff.cmd == PT_RET_SUCCESS ) {
Buff.mte = ModHandles[ 0 ];
startCS = Buff.value;
if( startCS != Buff.u.r.CS || startIP != Buff.u.r.IP ) {
ExecuteUntil( startCS, startIP );
ReadRegs( &Buff );
}
save.pid = Pid;
save.tid = 1;
ReadRegs( &save );
if( !CausePgmToLoadThisDLL( startCS, startIP ) ) {
CanExecTask = FALSE;
}
WriteRegs( &save );
} else {
CanExecTask = FALSE;
}
}
Buff.pid = Pid;
Buff.tid = 1;
ReadRegs( &Buff );
}
ret->flags |= LD_FLAG_HAVE_RUNTIME_DLLS;
ret->mod_handle = 0;
CurrModHandle = 1;
return( sizeof( *ret ) );
}
unsigned ReqProg_kill()
{
prog_kill_ret *ret;
ret = GetOutPtr( 0 );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -