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 + -
显示快捷键?