virtmem.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 674 行 · 第 1/2 页
C
674 行
return( ret );
}
#if 1 // ITB
#define ACCESSPAGE( __nd, __vm ) \
__nd = NODE( (__vm) ); \
__nd->refd = 1; \
if( !__nd->inmem ) { \
ReadPage( (__nd), (__vm) ); \
}
#else
static page_entry * AccessPage( virt_struct vm )
/**********************************************/
{
page_entry *node;
node = NODE( vm );
node->refd = TRUE;
if( !node->inmem ) {
ReadPage( node, vm );
}
return node;
}
#endif
extern void DWRVMRead( dr_handle hdl, void * info, unsigned len )
/***************************************************************/
/* go through the virtual memory nodes, reading data */
{
unsigned end_off;
unsigned off;
page_entry *node;
unsigned amt;
virt_struct vm;
vm.l = hdl;
off = NODE_OFF( vm );
for( ;; ) {
//node = AccessPage( vm );
ACCESSPAGE( node, vm ); // ITB
end_off = (unsigned long)off + len;
if( end_off <= MAX_NODE_SIZE ) break;
amt = MAX_NODE_SIZE - off;
memcpy( info, node->mem + off, amt );
len -= amt;
vm.l += amt;
info = (char *)info + amt;
off = 0;
}
memcpy( info, node->mem + off, len );
}
extern unsigned_8 DWRVMReadByte( dr_handle hdl )
/**********************************************/
{
page_entry *node;
virt_struct vm;
vm.l = hdl;
//node = AccessPage( vm );
ACCESSPAGE( node, vm ); // ITB
return( *(node->mem + NODE_OFF(vm)) );
}
static unsigned_32 ReadLEB128( dr_handle *vmptr, bool issigned )
/**************************************************************/
/* read and advance the vm pointer */
{
virt_struct vm;
page_entry *node;
unsigned_16 off;
unsigned_32 result;
unsigned_8 inbyte;
unsigned shift;
shift = 0;
vm.l = *vmptr;
//node = AccessPage( vm );
ACCESSPAGE( node, vm ); // ITB
off = NODE_OFF( vm );
vm.l++;
inbyte = *(node->mem + off);
result = inbyte & 0x7F;
while( inbyte & 0x80 ) {
off++;
if( off == MAX_NODE_SIZE ) {
off = 0;
//node = AccessPage( vm );
ACCESSPAGE( node, vm ); // ITB
}
shift += 7;
inbyte = *(node->mem + off);
result |= (unsigned_32)(inbyte & 0x7F) << shift;
vm.l++;
}
*vmptr = vm.l;
if( issigned ) {
if( inbyte & 0x40 ) { // we have to sign extend
result |= - ((signed_32)(1 << (shift + 7)));
}
}
return( result );
}
extern signed_32 DWRVMReadSLEB128( dr_handle *vmptr )
/***************************************************/
{
return( (signed_32) ReadLEB128( vmptr, TRUE ) );
}
extern unsigned_32 DWRVMReadULEB128( dr_handle *vmptr )
/*****************************************************/
{
page_entry *node;
char * walk;
unsigned off;
virt_struct vm;
unsigned_32 result = 0;
unsigned shift = 0;
char b;
vm.l = *vmptr;
//node = AccessPage( vm );
ACCESSPAGE( node, vm ); // ITB
off = NODE_OFF(vm);
if( off <= MAX_NODE_SIZE - 5 ) { // we can read whole uleb from buffer
walk = node->mem + off;
while( 1 ) {
b = *walk++;
result |= ( b & 0x7f ) << shift;
if( ( b & 0x80 ) == 0 ) break;
shift += 7;
}
*vmptr += walk - node->mem - off;
} else {
result = ReadLEB128( vmptr, FALSE );
}
return( result );
}
extern void DWRVMSkipLEB128( dr_handle *hdl )
/*******************************************/
// just advance the vm pointer past the leb128 (works on both signed & unsigned)
{
page_entry *node;
unsigned_16 off;
unsigned_8 inbyte;
virt_struct vm;
char *walk;
char b;
vm.l = *hdl;
//node = AccessPage( vm );
ACCESSPAGE( node, vm ); // ITB
off = NODE_OFF( vm );
if( off <= MAX_NODE_SIZE - 5 ) { // we can read whole leb from buffer
walk = node->mem + off;
while( 1 ) {
b = *walk++;
if( (b & 0x80) == 0 ) break;
}
vm.l += walk - node->mem - off;
} else {
vm.l++;
inbyte = *(node->mem + off);
while( inbyte & 0x80 ) {
off++;
if( off == MAX_NODE_SIZE ) {
off = 0;
//node = AccessPage( vm );
ACCESSPAGE( node, vm ); // ITB
}
inbyte = *(node->mem + off);
vm.l++;
}
}
*hdl = vm.l;
}
extern unsigned_16 DWRVMReadWord( dr_handle hdl )
/***********************************************/
{
page_entry *node;
char *target;
unsigned_16 off;
virt_struct vm;
vm.l = hdl;
//node = AccessPage( vm );
ACCESSPAGE( node, vm ); // ITB
off = NODE_OFF(vm);
target = node->mem + off;
if( off != MAX_NODE_SIZE - 1 ) { // we can read both bytes now.
// must not swap bytes in source buffer!
off = *((unsigned_16 *)target);
} else {
off = *target;
vm.l++;
//node = AccessPage( vm );
ACCESSPAGE( node, vm ); // ITB
off |= ((unsigned_16)*node->mem) << 8;
}
if( DWRCurrNode->byte_swap ) {
SWAP_16( off );
}
return( off );
}
extern unsigned_32 DWRVMReadDWord( dr_handle hdl )
/************************************************/
{
page_entry *node;
char *target;
unsigned off;
unsigned_32 result;
virt_struct vm;
vm.l = hdl;
//node = AccessPage( vm );
ACCESSPAGE( node, vm ); // ITB
off = NODE_OFF(vm);
target = node->mem + off;
if( off <= MAX_NODE_SIZE - 4 ) { // we can read both bytes now.
// must not swap bytes in source buffer!
result = *((unsigned_32 *)target);
} else {
off = MAX_NODE_SIZE - off;
memcpy( &result, target, off );
vm.l += 4;
//node = AccessPage( vm );
ACCESSPAGE( node, vm ); // ITB
memcpy( (char *)&result + off, node->mem, 4 - off );
}
if( DWRCurrNode->byte_swap ) {
SWAP_32( result );
}
return( result );
}
extern unsigned DWRStrLen( dr_handle hdl )
/****************************************/
{
unsigned off;
unsigned start_off;
page_entry *node;
virt_struct vm;
int length = 0;
vm.l = hdl;
start_off = NODE_OFF( vm );
off = start_off;
for( ;; ) {
//node = AccessPage( vm );
ACCESSPAGE( node, vm ); // ITB
while( off < MAX_NODE_SIZE ) {
if( node->mem[ off++ ] == '\0' ) {
goto end;
}
}
length += off - start_off;
vm.l += MAX_NODE_SIZE - start_off;
off = 0;
start_off = 0;
}
end:
length += off - start_off;
return( length - 1 ); // remove '\0' terminator's contrib
}
extern void DWRGetString( char * buf, dr_handle * hdlp )
/******************************************************/
{
unsigned off;
page_entry *node;
virt_struct vm;
char *wlkBuf = buf;
vm.l = *hdlp;
off = NODE_OFF( vm );
for( ;; ) {
//node = AccessPage( vm );
ACCESSPAGE( node, vm ); // ITB
while( off < MAX_NODE_SIZE ) {
*wlkBuf = node->mem[ off++ ];
vm.l++;
if( *wlkBuf++ == '\0' ) goto end;
}
off = 0;
}
end:
*hdlp = vm.l;
}
extern unsigned DWRGetStrBuff( dr_handle drstr, char *buf, unsigned max )
/***********************************************************************/
{
unsigned off;
page_entry *node;
virt_struct vm;
char curr;
unsigned len;
vm.l = drstr;
off = NODE_OFF( vm );
len = 0;
for( ;; ) {
//node = AccessPage( vm );
ACCESSPAGE( node, vm ); // ITB
while( off < MAX_NODE_SIZE ) {
curr = node->mem[ off++ ];
if( len < max ) {
*buf++ = curr;
}
++len;
if( curr == '\0' ) goto end;
vm.l++;
}
off = 0;
}
end:
return( len );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?