📄 nlmacc.c
字号:
acc = GetInPtr(0);
addr.offset = acc->mem_addr.offset;
addr.segment = acc->mem_addr.segment;
len = ReadWrite( ReadMemory, &addr, GetOutPtr(0), acc->len );
return( len );
}
unsigned ReqWrite_mem( void )
{
addr48_ptr addr;
write_mem_req *acc;
write_mem_ret *ret;
unsigned len;
acc = GetInPtr(0);
ret = GetOutPtr(0);
len = GetTotalSize() - sizeof(*acc);
addr.offset = acc->mem_addr.offset;
addr.segment = acc->mem_addr.segment;
ret->len = ReadWrite( WriteMemory, &addr, GetInPtr(sizeof(*acc)), len );
return( sizeof( *ret ) );
}
unsigned ReqRead_io( void )
{
read_io_req *acc;
void *data;
acc = GetInPtr(0);
data = GetOutPtr( 0 );
if( acc->len == 1 ) {
*( (byte *)data ) = in_b( acc->IO_offset );
} else if( acc->len == 2 ) {
*( (word *)data ) = in_w( acc->IO_offset );
} else {
*( (dword *)data ) = in_d( acc->IO_offset );
}
return( acc->len );
}
unsigned ReqWrite_io( void )
{
write_io_req *acc;
write_io_ret *ret;
void *data;
unsigned len;
acc = GetInPtr( 0 );
ret = GetOutPtr( 0 );
data = GetInPtr( sizeof( *acc ) );
len = GetTotalSize() - sizeof( *acc );
if( len == 1 ) {
out_b( acc->IO_offset, *( (byte *)data ) );
} else if( len == 2 ) {
out_w( acc->IO_offset, *( (word *)data ) );
} else {
out_d( acc->IO_offset, *( (dword *)data ) );
}
ret->len = len;
return( sizeof( *ret ) );
}
//obsolete
unsigned ReqRead_cpu( void )
{
trap_cpu_regs *regs;
regs = GetOutPtr(0);
if( MSB == NULL ) {
memset( regs, 0, sizeof( *regs ) );
} else {
*regs = MSB->cpu;
}
return( sizeof( *regs ) );
}
//obsolete
unsigned ReqRead_fpu( void )
{
trap_fpu_regs *regs;
regs = GetOutPtr(0);
if( MSB == NULL ) {
memset( regs, 0, sizeof( *regs ) );
} else {
*regs = MSB->fpu;
}
return( sizeof( *regs ) );
}
//obsolete
unsigned ReqWrite_cpu( void )
{
if( MSB != NULL ) {
MSB->cpu = *(trap_cpu_regs *)GetInPtr(sizeof(write_cpu_req));
}
return( 0 );
}
//obsolete
unsigned ReqWrite_fpu( void )
{
if( MSB != NULL ) {
MSB->fpu = *(trap_fpu_regs *)GetInPtr(sizeof(write_fpu_req));
}
return( 0 );
}
unsigned ReqRead_regs( void )
{
mad_registers *mr;
mr = GetOutPtr(0);
memset( mr, 0, sizeof( mr->x86 ) );
if( MSB != NULL ) {
mr->x86.cpu = *(struct x86_cpu *)&MSB->cpu;
mr->x86.fpu = *(struct x86_fpu *)&MSB->fpu;
}
return( sizeof( mr->x86 ) );
}
unsigned ReqWrite_regs( void )
{
mad_registers *mr;
mr = GetInPtr(sizeof(write_regs_req));
if( MSB != NULL ) {
*(struct x86_cpu *)&MSB->cpu = mr->x86.cpu;
*(struct x86_fpu *)&MSB->fpu = mr->x86.fpu;
}
return( 0 );
}
static char *LoadName;
static unsigned LoadLen;
static prog_load_ret *LoadRet;
static void LoadHelper( void )
{
int err;
int handle;
char *src, *dst;
char nlm_name[256];
char ch;
unsigned len;
Enable();
MSBHead = NULL;
ThreadId = 0;
MSB = NULL;
src = LoadName;
StringToNLMPath( src, nlm_name );
dst = CmdLine;
len = LoadLen;
for( ;; ) {
if( len == 0 )
break;
ch = *src;
if( ch == '\0' )
ch = ' ';
*dst = ch;
++dst;
++src;
--len;
}
if( dst > CmdLine && src[-1] == '\0' )
--dst;
*dst = '\0';
LoadRet->err = 0;
NLMState = NLM_PRELOADING;
_DBG_EVENT(( "*LoadHelper: NLMState = NLM_PRELOADING\r\n" ));
ExpectingEvent = TRUE;
if( nlm_name[0] == '\0'
|| ( handle = IOOpen( nlm_name, O_RDONLY ) ) == -1
|| IOSeek( handle, SEEK_SET, offsetof( nlm_header, moduleName ) )
!= offsetof( nlm_header, moduleName )
|| IORead( handle, NLMName, 14 ) != 14
|| IOClose( handle ) != 0 ) {
NLMState = NLM_NONE;
_DBG_EVENT(( " NLMState = NLM_NONE\r\n" ));
DebuggerLoadedNLM = NULL;
if( LoadRet != NULL )
LoadRet->err = 2;
_DBG_EVENT(( " Waking up the debugger for noopen event\r\n" ));
WakeDebugger();
} else {
_DBG_EVENT(( " Name is '%S'\r\n", NLMName ));
err = LoadModule( systemConsoleScreen, CmdLine, LO_DEBUG );
_DBG_EVENT(( " Load ret code %d\r\n", err ));
if( err != 0 ) {
NLMState = NLM_NONE;
_DBG_EVENT(( " NLMState = NLM_NONE\r\n" ));
DebuggerLoadedNLM = NULL;
if( LoadRet != NULL )
LoadRet->err = err;
_DBG_EVENT(( " Waking up the debugger for noload event\r\n" ));
WakeDebugger();
}
}
FreeThread( LocateThread( RunningProcess ) );
if( NLMState != NLM_NONE) {
NLMState = NLM_LOADED;
_DBG_EVENT(( "LoadHelper: NLMState = NLM_LOADED\r\n" ));
#if defined ( _USE_NEW_KERNEL )
kSemaphoreWait( kHelperSem );
#else
CPSemaphore( HelperSem );
#endif
_DBG_EVENT(( "LoadHelper: Helper awake -- calling KillMe NLM=%8x!\r\n", DebuggerLoadedNLM ));
NLMState = NLM_NONE;
_DBG_EVENT(( "LoadHelper: NLMState = NLM_NONE\r\n" ));
if( DebuggerLoadedNLM )
KillMe( DebuggerLoadedNLM );
}
DebuggerLoadedNLM = NULL;
_DBG_EVENT(( "LoadHelper: Helper killing itself\r\n" ));
Suicide();
}
#if 0
static void LoadHelper( void )
{
int err;
int handle;
char *src, *dst;
char nlm_name[256];
char ch;
unsigned len;
Enable();
MSBHead = NULL;
ThreadId = 0;
MSB = NULL;
src = LoadName;
StringToNLMPath( src, nlm_name );
dst = CmdLine;
len = LoadLen;
for( ;; ) {
if( len == 0 )
break;
ch = *src;
if( ch == '\0' )
ch = ' ';
*dst = ch;
++dst;
++src;
--len;
}
if( dst > CmdLine && src[-1] == '\0' )
--dst;
*dst = '\0';
LoadRet->err = 0;
NLMState = NLM_PRELOADING;
_DBG_EVENT(( "*LoadHelper: NLMState = NLM_PRELOADING\r\n" ));
ExpectingEvent = TRUE;
if( nlm_name[0] == '\0'
|| ( handle = IOOpen( nlm_name, O_RDONLY ) ) == -1
|| IOSeek( handle, SEEK_SET, offsetof( nlm_header, moduleName ) )
!= offsetof( nlm_header, moduleName )
|| IORead( handle, NLMName, 14 ) != 14
|| IOClose( handle ) != 0 ) {
NLMState = NLM_NONE;
_DBG_EVENT(( " NLMState = NLM_NONE\r\n" ));
DebuggerLoadedNLM = NULL;
if( LoadRet != NULL ) LoadRet->err = 2;
_DBG_EVENT(( " Waking up the debugger for noopen event\r\n" ));
WakeDebugger();
} else {
_DBG_EVENT(( " Name is '%S'\r\n", NLMName ));
err = LoadModule( systemConsoleScreen, CmdLine, LO_DEBUG );
_DBG_EVENT(( " Load ret code %d\r\n", err ));
if( err != 0 ) {
NLMState = NLM_NONE;
_DBG_EVENT(( " NLMState = NLM_NONE\r\n" ));
DebuggerLoadedNLM = NULL;
if( LoadRet != NULL )
LoadRet->err = err;
_DBG_EVENT(( " Waking up the debugger for noload event\r\n" ));
WakeDebugger();
}
}
FreeThread( LocateThread( RunningProcess ) );
NLMState = NLM_LOADED;
_DBG_EVENT(( "LoadHelper: NLMState = NLM_LOADED\r\n" ));
CPSemaphore( HelperSem );
_DBG_EVENT(( "LoadHelper: Helper awake -- calling KillMe NLM=%8x!\r\n", DebuggerLoadedNLM ));
NLMState = NLM_NONE;
_DBG_EVENT(( "LoadHelper: NLMState = NLM_NONE\r\n" ));
if( DebuggerLoadedNLM )
KillMe( DebuggerLoadedNLM );
DebuggerLoadedNLM = NULL;
_DBG_EVENT(( "LoadHelper: Helper killing itself\r\n" ));
Suicide();
}
#endif
static char helper_stack[8192]; /* We may return before thread dies! */
unsigned ReqProg_load( void )
{
prog_load_ret *ret;
struct LoadDefinitionStructure *ld;
LoadedListHandle nlm;
LoadName = (char *)GetInPtr( sizeof( prog_load_req ) );
LoadLen = GetTotalSize() - sizeof( prog_load_req );
ret = GetOutPtr( 0 );
LoadRet = ret;
// scheduling priority, code address, stack top, stack len, process name, resource tag
CMakeProcess( 50, &LoadHelper, &helper_stack[ sizeof( helper_stack ) ],
sizeof( helper_stack ), TRP_The_WATCOM_Debugger, ProcessTag );
_DBG_EVENT(( "*ReqProg_load: Putting debugger to sleep for load of %s\r\n", LoadName ));
SleepDebugger();
_DBG_EVENT(( "ReqProg_load: Debugger awake after load\r\n" ));
ret->task_id = 1;
ret->flags = LD_FLAG_IS_32 | LD_FLAG_IS_PROT;
ret->mod_handle = 0;
LoadRet = NULL;
// The list that is traversed are all the loaded NLMs.
// nlm is an index/handle of some sort.
// ld is a pointer to a block of information about the NLM
// including its name.
nlm = 0;
for( ;; ) {
nlm = GetNextLoadedListEntry( nlm );
if( nlm == 0 )
break;
ld = ValidateModuleHandle( nlm );
if( ld != DebuggerLoadedNLM ) {
// skip the main NLM
NewNLMListEntry( ld );
}
}
_DBG_THREAD(("ReqProg_load: MSB after load=%8x\r\n", MSB));
return( sizeof( *ret ) );
}
unsigned ReqProg_kill( void )
{
msb *m;
prog_kill_ret *ret;
FreeInvalidThreads();
if( DebuggerLoadedNLM != NULL ) {
m = MSBHead;
while( m != NULL ) {
m->to_be_killed = TRUE;
if( m->asleep && m->clib_created ) {
DebuggerLoadedNLM = NULL;
SetupPIDForACleanExit( m->os_id );
}
#if defined ( _USE_NEW_KERNEL )
_DBG_THREAD(( "----- Releasing semaphore for MSB=%8x, sem=%8x\r\n", m, m->ksem ));
msb_KernelSemaphoreReleaseAll( m );
m->ksem = NULL;
#else
_DBG_THREAD(( "----- Releasing semaphore for MSB=%8x, sem=%8x\r\n", m, m->sem ));
CSemaphoreReleaseAll( m->sem ); /* will be freed when thread awakes */
m->sem = 0;
#endif
m = m->next;
}
}
while( NLMList != NULL ) {
FreeAnNLMListEntry();
}
LastNLMListEntry = NULL;
#if defined ( _USE_NEW_KERNEL )
kSemaphoreSignal( kHelperSem );
#else
CVSemaphore( HelperSem );
#endif
ret = GetOutPtr( 0 );
ret->err = 0;
return( sizeof( *ret ) );
}
unsigned Execute( msb *which )
{
msb *m;
for( m = MSBHead; m != NULL; m = m->next ) {
_DBG_THREAD(( "check thread msb=%8x: frozen=%d, asleep=%d\r\n", m, m->frozen, m->asleep ));
if( !m->frozen && m->asleep ) {
if( which == NULL || which == m ) {
#if defined ( _USE_NEW_KERNEL )
_DBG_THREAD(( "Letting a thread execute, MSB=%8x, sem=%8x\r\n", m, m->ksem ));
kSemaphoreSignal( m->ksem );
#else
_DBG_THREAD(( "Letting a thread execute, MSB=%8x, sem=%8x\r\n", m, m->sem ));
CVSemaphore( m->sem );
#endif
}
}
}
/* freeze all threads!!! */
_DBG_EVENT(( "*Execute: Putting debugger to sleep for execution\r\n" ));
SleepDebugger();
_DBG_EVENT(( "Execute: Debugger awake after execution\r\n" ));
if( MSB == NULL )
return( COND_TERMINATE );
switch( MSB->xnum )
{
case 1:
if( FakeBreak ) {
FakeBreak = FALSE;
return( COND_USER );
}
if( MSB->errnum & DR6_BS ) {
return( COND_TRACE );
} else if( MSB->errnum & ( DR6_B0+DR6_B1+DR6_B2+DR6_B3 ) ) {
return( COND_WATCH );
} else {
return( COND_EXCEPTION );
}
case 3:
return( COND_BREAK );
case ENTER_DEBUGGER_EVENT:
case KEYBOARD_BREAK_EVENT:
return( COND_USER );
case TERMINATE_NLM_EVENT:
if( DebuggerLoadedNLM == NULL ) {
return( COND_LIBRARIES | COND_TERMINATE );
} else {
return( COND_LIBRARIES );
}
case START_NLM_EVENT:
return( COND_LIBRARIES );
case START_THREAD_EVENT:
case TERMINATE_THREAD_EVENT:
return( 0 );
case INVALID_INTERRUPT_ABEND:
case ASSEMBLY_ABEND:
case BREAKPOINT_FUNCTION_EVENT:
default:
return( COND_EXCEPTION );
}
}
unsigned ReqSet_watch( void )
{
dword l;
set_watch_req *acc;
set_watch_ret *ret;
watch *curr;
int i,needed;
int dreg_avail[4];
acc = GetInPtr( 0 );
ret = GetOutPtr( 0 );
ret->err = 1;
ret->multiplier = 2000;
if( WatchCount < MAX_WP && ReadMemory( &acc->watch_addr, 4UL, &l ) == 0 ) {
ret->err = 0;
curr = WatchPoints + WatchCount;
curr->addr.segment = acc->watch_addr.segment;
curr->addr.offset = acc->watch_addr.offset;
curr->linear = acc->watch_addr.offset;
curr->len = acc->size;
curr->linear &= ~(curr->len-1);
curr->dregs = ( curr->addr.offset & (curr->len-1) ) ? 2 : 1;
curr->value = l;
++WatchCount;
needed = 0;
for( i = 0; i < WatchCount; ++i ) {
needed += WatchPoints[ i ].dregs;
}
for( i = 0; i < NUM_DREG; ++i ) {
dreg_avail[ i ] = DoReserveBreakpoint();
if( dreg_avail[ i ] < 0 )
break;
}
for( i = 0; i < NUM_DREG; ++i ) {
if( dreg_avail[ i ] < 0 )
break;
UnReserveABreakpoint( dreg_avail[ i ] );
}
if( needed <= i )
ret->multiplier |= USING_DEBUG_REG;
}
return( sizeof( *ret ) );
}
unsigned ReqClear_watch( void )
{
WatchCount = 0;
return( 0 );
}
unsigned ReqSet_break( void )
{
byte l;
set_break_req *acc;
set_break_ret *ret;
char ch;
acc = GetInPtr( 0 );
ret = GetOutPtr( 0 );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -