📄 accbrwat.c
字号:
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
* DESCRIBE IT HERE!
*
****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <direct.h>
#include "stdnt.h"
#if defined( MD_x86 )
#include "dbg386.h"
#endif
#define MAX_WP 32
typedef struct {
addr48_ptr loc;
DWORD value;
DWORD linear;
unsigned short len;
unsigned short dregs;
} watch_point;
static watch_point wpList[MAX_WP];
typedef struct break_point {
struct break_point *next;
addr48_ptr addr;
BYTE byte;
} break_point;
static break_point *Breaks = NULL;
unsigned ReqSet_break( void )
{
brkpnt_type ch;
set_break_req *acc;
set_break_ret *ret;
break_point *new;
acc = GetInPtr( 0 );
ret = GetOutPtr( 0 );
ReadMem( acc->break_addr.segment, acc->break_addr.offset, &ch,
sizeof( ch ) );
ret->old = ch;
new = LocalAlloc( LMEM_FIXED, sizeof( *new ) );
new->byte = ch;
new->addr = acc->break_addr;
new->next = Breaks;
Breaks = new;
ch = BRK_POINT;
WriteMem( acc->break_addr.segment, acc->break_addr.offset, &ch,
sizeof( ch ) );
return( sizeof( *ret ) );
}
unsigned ReqClear_break( void )
{
brkpnt_type ch;
clear_break_req *acc;
break_point *brk;
break_point *next;
// we can assume all breaks are cleared at once
for( brk = Breaks; brk != NULL; brk = next ) {
next = brk->next;
LocalFree( brk );
}
Breaks = NULL;
acc = GetInPtr( 0 );
ch = acc->old;
WriteMem( acc->break_addr.segment, acc->break_addr.offset, &ch,
sizeof( ch ) );
return( 0 );
}
BOOL FindBreak( WORD segment, DWORD offset, BYTE *ch )
{
break_point *brk;
for( brk = Breaks; brk != NULL; brk = brk->next ) {
if( brk->addr.segment != segment ) {
continue;
}
if( brk->addr.offset != offset ) {
continue;
}
*ch = brk->byte;
return( TRUE );
}
return( FALSE );
}
#if defined( MD_x86 )
/*
* setDR6 - set value of debug register 6
*/
static void setDR6( DWORD tmp )
{
CONTEXT con;
thread_info *ti;
ti = FindThread( DebugeeTid );
MyGetThreadContext( ti, &con );
con.Dr6 = tmp;
MySetThreadContext( ti, &con );
}
/*
* SetDR7 - set value of debug register 7
*/
void SetDR7( DWORD tmp )
{
CONTEXT con;
thread_info *ti;
//char buff[256];
ti = FindThread( DebugeeTid );
if( ti == NULL ) {
return;
}
MyGetThreadContext( ti, &con );
con.Dr7 = tmp;
//sprintf( buff, "tid=%8.8x, dr7=%8.8x", DebugeeTid, tmp );
//MessageBox( NULL, buff, "Dr7", MB_APPLMODAL+MB_OK );
MySetThreadContext( ti, &con );
}
/*
* GetDR6 - get value of debug register 6
*/
DWORD GetDR6( void )
{
CONTEXT con;
thread_info *ti;
ti = FindThread( DebugeeTid );
MyGetThreadContext( ti, &con );
return( con.Dr6 );
}
static DWORD setDRn( int i, DWORD linear, long type )
{
CONTEXT con;
thread_info *ti;
ti = FindThread( DebugeeTid );
MyGetThreadContext( ti, &con );
( ( DWORD * ) & con.Dr0 )[i] = linear;
MySetThreadContext( ti, &con );
return( ( type << DR7_RWLSHIFT( i ) )
// | ( DR7_GEMASK << DR7_GLSHIFT(i) ) | DR7_GE
| ( DR7_LEMASK << DR7_GLSHIFT( i ) ) | DR7_LE );
}
#endif
/*
* ClearDebugRegs - set for no watch points
*/
void ClearDebugRegs( void )
{
#if defined( MD_x86 )
int i;
for( i = 0; i < 4; i++ ) {
setDRn( i, 0L, 0L );
}
setDR6( 0 );
SetDR7( 0 );
#elif defined( MD_axp ) || defined( MD_ppc )
/* nothing to do */
#else
#error ClearDebugRegs not configured
#endif
}
/*
* SetDebugRegs - set debug registers for watch points
*/
BOOL SetDebugRegs( void )
{
#if defined( MD_x86 )
int needed;
int i;
int dr;
DWORD dr7;
watch_point *wp;
needed = 0;
for( i = 0; i < WPCount; i++ ) {
needed += wpList[i].dregs;
}
if( needed > 4 ) {
return( FALSE );
}
dr = 0;
dr7 = 0;
for( i = 0, wp = wpList; i < WPCount; i++, wp++ ) {
dr7 |= setDRn( dr, wp->linear, DRLen( wp->len ) | DR7_BWR );
dr++;
if( wp->dregs == 2 ) {
dr7 |= setDRn( dr, wp->linear + wp->len,
DRLen( wp->len ) | DR7_BWR );
dr++;
}
}
SetDR7( dr7 );
return( TRUE );
#elif defined( MD_axp ) || defined( MD_ppc )
return( FALSE );
#else
#error SetDebugRegs not configured
#endif
}
/*
* CheckWatchPoints - check if a watchpoint was hit
*/
BOOL CheckWatchPoints( void )
{
DWORD value;
int i;
for( i = 0; i < WPCount; i++ ) {
ReadMem( wpList[i].loc.segment, wpList[i].loc.offset, &value,
sizeof( value ) );
if( value != wpList[i].value ) {
return( TRUE );
}
}
return( FALSE );
}
#if defined( MD_x86 )
static DWORD CalcLinear( WORD segment, DWORD offset )
{
LDT_ENTRY sel;
thread_info *ti;
ti = FindThread( DebugeeTid );
if( ti == NULL ) {
return( offset );
}
if( !GetThreadSelectorEntry( ti->thread_handle, segment, &sel ) ) {
return( offset );
}
return( offset +
( ( sel.HighWord.Bits.BaseHi << 24 ) |
( sel.HighWord.Bits.BaseMid << 16 ) |
sel.BaseLow ) );
}
#endif
unsigned ReqSet_watch( void )
{
set_watch_req *acc;
set_watch_ret *ret;
DWORD value;
watch_point *curr;
#if defined( MD_x86 )
DWORD linear;
#endif
acc = GetInPtr( 0 );
ret = GetOutPtr( 0 );
ret->multiplier = 100000;
ret->err = 1;
if( WPCount < MAX_WP ) {
ret->err = 0;
curr = wpList + WPCount;
curr->loc.segment = acc->watch_addr.segment;
curr->loc.offset = acc->watch_addr.offset;
ReadMem( acc->watch_addr.segment, acc->watch_addr.offset, &value,
sizeof( dword ) );
curr->value = value;
curr->len = acc->size;
WPCount++;
#if defined( MD_x86 )
linear = CalcLinear( acc->watch_addr.segment, acc->watch_addr.offset );
curr->linear = linear;
curr->linear &= ~( curr->len - 1 );
curr->dregs = ( linear & ( curr->len - 1 ) ) ? 2 : 1;
{
unsigned i;
unsigned needed;
needed = 0;
for( i = 0; i < WPCount; ++i ) {
needed += wpList[i].dregs;
}
if( needed <= 4 ) {
ret->multiplier |= USING_DEBUG_REG;
}
}
#endif
}
return( sizeof( *ret ) );
}
unsigned ReqClear_watch( void )
{
clear_watch_req *acc;
watch_point *dst;
watch_point *src;
int i;
acc = GetInPtr( 0 );
dst = src = wpList;
for( i = 0; i < WPCount; i++ ) {
if( src->loc.segment != acc->watch_addr.segment
|| src->loc.offset != acc->watch_addr.offset ) {
dst->loc.offset = src->loc.offset;
dst->loc.segment = src->loc.segment;
dst->value = src->value;
dst++;
}
src++;
}
WPCount--;
return( 0 );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -