qnxacc.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,824 行 · 第 1/4 页
C
1,824 行
if( ProcInfo.loaded_proc ) {
net_kill( ProcInfo.proc, ProcInfo.pid, SIGKILL );
}
goto fail;
}
if( !ProcInfo.loaded_proc ) {
__qnx_debug_hold( ProcInfo.proc, ProcInfo.pid );
ret->flags |= LD_FLAG_IS_STARTED;
}
ret->task_id = ProcInfo.pid;
qnx_osinfo( ProcInfo.nid, &info );
ProcInfo.cpu = info.cpu;
ProcInfo.fpu = info.fpu;
ProcInfo.version = info.version;
ProcInfo.sflags = info.sflags;
if( info.sflags & _PSF_PROTECTED ) {
ret->flags |= LD_FLAG_IS_PROT;
}
if( info.sflags & _PSF_32BIT ) {
ProcInfo.proc32 = TRUE;
}
has_flat = FALSE;
if( __qnx_debug_xfer( ProcInfo.proc, ProcInfo.pid, _DEBUG_PSINFO,
&off_info, sizeof( off_info ), 0, 0 ) != -1 ) {
if( proc.flags & _PPF_FLAT ) {
ProcInfo.flat = TRUE;
ProcInfo.code_offset = off_info.codeoff;
ProcInfo.data_offset = off_info.codeoff + off_info.codesize;
}
has_flat = TRUE;
}
if( ForceFpu32 < 0 ) {
ProcInfo.fpu32 = FALSE;
} else if( ForceFpu32 > 0 ) {
ProcInfo.fpu32 = TRUE;
} else if( ProcInfo.dbg32 ) {
ProcInfo.fpu32 = TRUE;
} else if( info.sflags & _PSF_EMU16_INSTALLED ) {
/* 16-bit emulator always writes out 16-bit state */
ProcInfo.fpu32 = FALSE;
} else if( !ProcInfo.proc32 ) {
ProcInfo.fpu32 = FALSE;
} else if( has_flat ) {
/* Proc32's that support flat model save 16-bit floating point
state as the full 32-bit form */
ProcInfo.fpu32 = TRUE;
} else {
ProcInfo.fpu32 = FALSE;
}
ProcInfo.thread[0].tid = ProcInfo.pid;
errno = 0;
}
fail:
ret->err = errno;
if( ret->err != 0 ) {
qnx_vc_detach( ProcInfo.proc );
ProcInfo.pid = 0;
}
ret->mod_handle = MH_DEBUGGEE;
return( sizeof( *ret ) );
}
unsigned ReqProg_kill()
{
prog_kill_ret *ret;
pid_t pid;
ret = GetOutPtr( 0 );
for( pid = 0; pid = next_thread( pid, THREAD_ALL ); ) {
if( ProcInfo.loaded_proc && !ProcInfo.at_end ) {
net_kill( ProcInfo.proc, pid, SIGKILL );
if( ProcInfo.nid == 0 ) { //NYI: temp kludge
/* receive the MID signalling task death */
Receive( 0, 0, 0 );
}
}
__qnx_debug_detach( ProcInfo.proc, pid );
if( ProcInfo.loaded_proc ) waitpid( -1, NULL, 0 );
}
if( ProcInfo.pid ) {
qnx_proxy_rem_detach( ProcInfo.nid, ProcInfo.mid );
qnx_vc_detach( ProcInfo.proc );
ProcInfo.proc = PROC_PID;
}
ProcInfo.sig = -1;
ProcInfo.sflags = 0;
ProcInfo.at_end = FALSE;
ProcInfo.save_in = -1;
ProcInfo.save_out = -1;
ret->err = 0;
return( sizeof( *ret ) );
}
unsigned ReqSet_break()
{
long opcode;
set_break_req *acc;
set_break_ret *ret;
acc = GetInPtr( 0 );
ret = GetOutPtr( 0 );
__qnx_debug_brk( ProcInfo.proc, ProcInfo.pid, _DEBUG_BRK_SET, &opcode,
acc->break_addr.offset, acc->break_addr.segment );
ret->old = opcode;
return( sizeof( *ret ) );
}
unsigned ReqClear_break()
{
long opcode;
clear_break_req *acc;
acc = GetInPtr( 0 );
opcode = acc->old;
__qnx_debug_brk( ProcInfo.proc, ProcInfo.pid, _DEBUG_BRK_CLR, &opcode,
acc->break_addr.offset, acc->break_addr.segment );
return( 0 );
}
unsigned ReqSet_watch()
{
unsigned size;
set_watch_req *acc;
set_watch_ret *ret;
acc = GetInPtr( 0 );
ret = GetOutPtr( 0 );
for( size = acc->size; size != 0; --size ) {
WatchPoints[ WatchCount ].seg = acc->watch_addr.segment;
WatchPoints[ WatchCount ].off = acc->watch_addr.offset;
#if 0
ReadBuffer( &WatchPoints[ WatchCount ].byte,
WatchPoints[ WatchCount ].seg, WatchPoints[ WatchCount ].off, 1 );
#endif
++acc->watch_addr.offset;
++WatchCount;
}
ret->err = 0;
ret->multiplier = 1000;
return( sizeof( *ret ) );
}
unsigned ReqClear_watch()
{
WatchCount = 0; /* assume all are cleared at the same time */
return( 0 );
}
static void RunHandler( int sig )
{
sig = sig;
ProcInfo.stopped = TRUE;
/* Running this signal handler will cause the Receive to terminate */
}
static int RunIt( unsigned step )
{
struct _debug_info info;
void (*old)();
pid_t pid;
int ret;
thread_info *thread;
thread_info *new;
unsigned i;
ProcInfo.stopped = TRUE;
for( thread = ProcInfo.thread; thread < &ProcInfo.thread[ProcInfo.max_threads]; thread++ ) {
if( thread->tid && thread->fork && !thread->frozen ) {
__qnx_debug_cont( ProcInfo.proc, thread->tid, 0 );
thread->tid = 0;
ProcInfo.stopped = FALSE;
}
}
if( !ProcInfo.stopped ) {
return( COND_THREAD );
}
for( thread = ProcInfo.thread; thread < &ProcInfo.thread[ProcInfo.max_threads]; thread++ ) {
if( thread->tid == 0 ) continue;
if( step == 0 || thread->tid == ProcInfo.pid ) {
if( !thread->frozen ) {
if( __qnx_debug_cont( ProcInfo.proc, thread->tid, step ) == 0 ) {
ProcInfo.stopped = FALSE;
}
}
}
}
if( !ProcInfo.stopped ) {
old = signal( SIGINT, &RunHandler );
Receive( MID, 0, 0 );
signal( SIGINT, old );
if( ProcInfo.stopped ) {
if( step ) {
__qnx_debug_hold( ProcInfo.proc, ProcInfo.pid );
} else {
for( thread = ProcInfo.thread; thread < &ProcInfo.thread[ProcInfo.max_threads]; thread++ ) {
if( thread->tid != 0 ) {
__qnx_debug_hold( ProcInfo.proc, thread->tid );
}
}
}
return( COND_USER );
}
ret = 0;
for( i = 0; i < ProcInfo.max_threads; i++ ) {
/*
Don't walk the thread array directly because it might move
due to a realloc.
*/
thread = &ProcInfo.thread[i];
if( thread->frozen ) continue;
pid = thread->tid;
if( pid == 0 ) continue;
if( step == 0 || pid == ProcInfo.pid ) {
__qnx_debug_xfer( ProcInfo.proc, pid, _DEBUG_INFO, &info, sizeof( info ), 0, 0 );
switch( info.debug_state ) {
case _DEBUG_STATE_CONT:
__qnx_debug_hold( ProcInfo.proc, pid );
break;
case _DEBUG_STATE_HELD:
ret |= COND_USER;
if(pid != ProcInfo.pid) {
ProcInfo.pid = pid;
ret |= COND_THREAD;
}
break;
case _DEBUG_STATE_TRACE:
ret |= COND_TRACE;
if(pid != ProcInfo.pid) {
ProcInfo.pid = pid;
ret |= COND_THREAD;
}
break;
case _DEBUG_STATE_BRK:
ret |= COND_BREAK;
if(pid != ProcInfo.pid) {
ProcInfo.pid = pid;
ret |= COND_THREAD;
}
break;
case _DEBUG_STATE_WATCH:
ret |= COND_WATCH;
if(pid != ProcInfo.pid) {
ProcInfo.pid = pid;
ret |= COND_THREAD;
}
break;
case _DEBUG_STATE_DEAD:
thread->dying = TRUE;
if( ( pid = next_thread( 0, THREAD_THAWED ) ) || ( pid = next_thread( 0, THREAD_FROZEN ) ) ) {
__qnx_debug_detach( ProcInfo.proc, thread->tid );
thread->tid = 0;
find_thread(pid)->frozen = FALSE;
ProcInfo.pid = pid;
ret |= COND_THREAD;
} else {
thread->dying = FALSE;
if( pid != ProcInfo.pid ) {
ProcInfo.pid = pid;
ret |= COND_THREAD;
}
ProcInfo.at_end = TRUE;
ret |= COND_TERMINATE;
}
break;
case _DEBUG_STATE_SIGNAL:
__qnx_debug_sigclr( ProcInfo.proc, pid, info.signo );
if( info.signo == SIGINT ) {
ret |= COND_USER;
} else {
ProcInfo.sig = info.signo;
ret = COND_EXCEPTION;
}
break;
case _DEBUG_STATE_FORK:
ProcInfo.fork = 1;
ProcInfo.son = info.messenger;
if( new = find_thread( 0 ) ) {
new->tid = ProcInfo.son;
new->frozen = TRUE;
new->fork = TRUE;
ret |= COND_THREAD;
}
ret |= COND_MESSAGE;
break;
case _DEBUG_STATE_THREAD:
ProcInfo.son = info.messenger;
if( new = find_thread( 0 ) ) {
if( __qnx_debug_attach( ProcInfo.proc, ProcInfo.son, ProcInfo.mid ) == 0 ) {
new->tid = ProcInfo.son;
new->frozen = FALSE;
}
}
ret |= COND_THREAD;
break;
}
}
}
return( ret );
}
ProcInfo.at_end = TRUE;
return( COND_TERMINATE );
}
static unsigned ProgRun( bool step )
{
struct _reg_struct regs;
prog_go_ret *ret;
pid_t pid;
ret = GetOutPtr( 0 );
if( ProcInfo.at_end ) {
ret->conditions = COND_TERMINATE;
} else if( step ) {
ret->conditions = RunIt( 1 );
} else {
#if 0
{ int i;
for( i = 0; i < WatchCount; ++i ) {
Out( "watch at " );
OutNum( WatchPoints[i].seg );
Out( ":" );
OutNum( WatchPoints[i].off );
Out( "\n" );
}
}
#endif
for( pid = 0; pid = next_thread( pid, THREAD_THAWED ) ; ) {
__qnx_debug_xfer( ProcInfo.proc, pid, _DEBUG_WATCH_WR, WatchPoints,
WatchCount * sizeof( struct _watch_struct ), 0, 0 );
}
ret->conditions = RunIt( 0 );
}
if( !(ret->conditions & COND_TERMINATE) ) {
__qnx_debug_xfer( ProcInfo.proc, ProcInfo.pid, _DEBUG_REG_RD, ®s, sizeof( regs ), 0, 0 );
#if 0
Out( "stopped at " );
OutNum( regs.ip );
Out( " because of " );
OutNum( ret->conditions );
Out( "\n" );
#endif
ret->program_counter.offset = regs.ip;
ret->program_counter.segment = regs.cs;
ret->stack_pointer.offset = regs.sp;
ret->stack_pointer.segment = regs.ss;
}
ret->conditions |= COND_CONFIG;
return( sizeof( *ret ) );
}
unsigned ReqProg_step()
{
return( ProgRun( TRUE ) );
}
unsigned ReqProg_go()
{
return( ProgRun( FALSE ) );
}
#define STK_ALIGN( v, type ) ((v)+(sizeof(type)-1) & ~(sizeof(type)-1))
static unsigned_16 Redir32( bool input )
{
struct _reg_struct save, new;
int *save_hdl;
unsigned len;
redirect_stdin_ret *ret;
char *file_name;
dword code;
addr48_ptr slib;
ret = GetOutPtr( 0 );
file_name = GetInPtr( sizeof( redirect_stdin_req ) );
ret->err = 1;
if( ProcInfo.pid == 0 ) {
return( sizeof( *ret ) );
}
slib = GetSLibTable( TRUE );
if( slib.segment == 0 ) {
return( sizeof( *ret ) );
}
if( __qnx_debug_xfer( ProcInfo.proc, ProcInfo.pid, _DEBUG_REG_RD,
&save, sizeof( save ), 0, 0 ) != 0 ) {
return( sizeof( *ret ) );
}
new = save;
if( input ) {
new.ax = 0;
save_hdl = &ProcInfo.save_in;
} else {
new.ax = 1;
save_hdl = &ProcInfo.save_out;
}
ret->err = 0;
if( *save_hdl != -1 ) {
new.cs = slib.segment & ~PRIV_MASK;
new.cs |= save.cs & PRIV_MASK;
new.ip = slib.offset;
new.dx = *save_hdl;
new.sp -= 3*sizeof( dword );
code = 256;
__qnx_debug_xfer( ProcInfo.proc, ProcInfo.pid, _DEBUG_MEM_WR, &code,
sizeof( code ), new.sp, new.ss );
__qnx_debug_xfer( ProcInfo.proc, ProcInfo.pid, _DEBUG_REG_WR, &new,
sizeof( new ), 0, 0 );
__qnx_debug_cont( ProcInfo.proc, ProcInfo.pid, 0 );
Receive( 0, 0, 0 );
*save_hdl = -1;
}
if( file_name[0] != '\0' ) {
new.cs = slib.segment & ~PRIV_MASK;
new.cs |= save.cs & PRIV_MASK;
new.ip = slib.offset;
len = strlen( file_name ) + 1;
new.sp -= STK_ALIGN( len, dword );
new.dx = new.sp;
__qnx_debug_xfer( ProcInfo.proc, ProcInfo.pid, _DEBUG_MEM_WR, file_name,
len, new.sp, new.ss );
new.sp -= 3*sizeof( dword );
code = 257;
__qnx_debug_xfer( ProcInfo.proc, ProcInfo.pid, _DEBUG_MEM_WR, &code,
sizeof( code ), new.sp, new.ss );
__qnx_debug_xfer( ProcInfo.proc, ProcInfo.pid, _DEBUG_REG_WR, &new,
sizeof( new ), 0, 0 );
__qnx_debug_cont( ProcInfo.proc, ProcInfo.pid, 0 );
Receive( 0, 0, 0 );
__qnx_debug_xfer( ProcInfo.proc, ProcInfo.pid, _DEBUG_REG_RD, &new,
sizeof( new ), 0, 0 );
if( (unsigned)new.ax == -1 ) ret->err = 1;
*save_hdl = new.ax;
}
__qnx_debug_xfer( ProcInfo.proc, ProcInfo.pid, _DEBUG_REG_WR, &save,
sizeof( save ), 0, 0 );
return( sizeof( *ret ) );
}
unsigned Redir16( bool input )
{
struct _reg_struct save, new;
addr48_ptr slib;
addr32_ptr func;
int *save_hdl;
unsigned len;
redirect_stdin_ret *ret;
char *file_name;
ret = GetOutPtr( 0 );
file_name = GetInPtr( sizeof( redirect_stdin_req ) );
ret->err = 1;
if( ProcInfo.pid == 0 ) {
return( sizeof( *ret ) );
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?