drutils.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,082 行 · 第 1/3 页

C
1,082
字号
        for( i = 0; i < ctxt.stack.free; i += 1 ) {
            ctxt.stack.stack[ i ] = startingCtxt->stack.stack[ i ];
        }
    }

    do {
        cont = DWRScanCompileUnit( &ctxt, fn, tagarray, depth, data );

        ctxt.compunit = ((compunit_info *) ctxt.compunit)->next;
        if( ctxt.compunit ) {
            ctxt.start = ((compunit_info *) ctxt.compunit)->start;
            ctxt.end = ctxt.start + DWRVMReadDWord( ctxt.start );
            ctxt.start += COMPILE_UNIT_HDR_SIZE;
        }
    } while( cont && ctxt.compunit != NULL );

    DWRFreeContextStack( &ctxt.stack );

    return( cont );     /* false if more symbols, true if at end of info */
}

extern bool DWRWalkCompileUnit( dr_handle mod, DWRCUWLK fn,
                        unsigned_16 const *tagarray, dr_depth depth, void *data )
/*******************************************************************************/
{
    bool                cont;
    dr_search_context   ctxt;
    compunit_info       *compunit;

    compunit = DWRFindCompileInfo( mod );
    ctxt.compunit = compunit;
    ctxt.start = mod;
    ctxt.end = compunit->start + DWRVMReadDWord( compunit->start );
    ctxt.classhdl = 0;
    ctxt.functionhdl = 0;
    ctxt.stack.size = 0;
    ctxt.stack.free = 0;
    ctxt.stack.stack = NULL;

    cont = DWRScanCompileUnit( &ctxt, fn, tagarray, depth, data );


    DWRFreeContextStack( &ctxt.stack );

    return( cont );     /* false if more symbols, true if at end of info */
}

extern int DWRWalkChildren( dr_handle mod, unsigned_16 const *tags,
                            DRWLKBLK *wlks, void *d )
/*****************************************************************/
// takes an array of tags and wlks and calls wlk on tag match
// default func called if the 0 tag at end of array has a non NULL func
{
    dr_handle       abbrev;
    dr_handle       curr;
    dw_tagnum       tag;
    unsigned_8      haschild;
    int             index;
    DRWLKBLK        wlk;
    compunit_info   *cu;

    cu = DWRFindCompileInfo( mod );
    abbrev = DWRVMReadULEB128( &mod );
    if( abbrev == 0 ) {
        DWREXCEPT( DREXCEP_DWARF_LIB_FAIL );
    }

    abbrev = cu->abbrevs[abbrev];
    tag = DWRVMReadULEB128( &abbrev );
    haschild = DWRVMReadByte( abbrev );

    abbrev += sizeof( unsigned_8 );         /* skip child byte */
    DWRSkipAttribs( abbrev, &mod );
    if( haschild == DW_CHILDREN_yes ) {
        curr = mod;
        for( ;; ) {
            mod = curr;
            abbrev = DWRVMReadULEB128( &curr );
            if( abbrev == 0 ) break;
            abbrev = cu->abbrevs[ abbrev ];
            tag = DWRVMReadULEB128( &abbrev );
            haschild = DWRVMReadByte( abbrev );
            abbrev += sizeof( unsigned_8 );
            index = 0;
            while( tags[index] != 0 ) {
                if( tags[index] == tag ) break;
                ++index;
            }
            wlk = wlks[index];
            if( wlk != NULL ) {
                if( !wlk( mod, index, d ) )
                    return( FALSE );    // FALSE == quit
            }
            if( haschild ) {
                DWRSkipChildren( &abbrev, &curr );
            } else {
                DWRSkipAttribs( abbrev, &curr );
            }
        }
    }
    return( TRUE );
}

extern int DWRWalkContaining( dr_handle mod, dr_handle target,
                              DRWLKBLK wlk, void *d )
/************************************************************/
// Walk into tags that enclose target
// The final call shoud be target else a goose chase
{
    dr_handle   abbrev;
    dr_handle   curr;
    dw_tagnum   tag;
    unsigned_8  haschild;

    abbrev = DWRVMReadULEB128( &mod );
    if( abbrev == 0 ) {
        DWREXCEPT( DREXCEP_DWARF_LIB_FAIL );
    }

    abbrev = DWRLookupAbbrev( mod, abbrev );
    tag = DWRVMReadULEB128( &abbrev );
    haschild = DWRVMReadByte( abbrev );

    abbrev += sizeof( unsigned_8 );         /* skip child byte */
    DWRSkipAttribs( abbrev, &mod );
    if( haschild == DW_CHILDREN_yes ) {
        curr = mod;
        for( ;; ) {
            dr_handle   old_abbrev;
            dr_handle   old_curr;

            if( curr > target ) break;
            mod = curr;
            abbrev = DWRVMReadULEB128( &curr );
            if( abbrev == 0 ) break;
            abbrev = DWRLookupAbbrev( mod, abbrev );
            tag = DWRVMReadULEB128( &abbrev );
            haschild = DWRVMReadByte( abbrev );
            abbrev += sizeof( unsigned_8 );
            old_abbrev = abbrev;
            old_curr = curr;
            if( haschild ) {
                DWRSkipChildren( &abbrev, &curr );
            } else {
                DWRSkipAttribs( abbrev, &curr );
            }
            if( curr > target ) {       // mod < target < curr - encloses
                if( !wlk( mod, 0, d ) ){
                    return( FALSE );    // FALSE == quit
                }
                abbrev = old_abbrev;    // rest cause we are going in
                curr = old_curr;
                DWRSkipAttribs( abbrev, &curr );    // skip current tags stuff
            }
        }
    }
    return( TRUE );
}

extern bool DWRWalkSiblings( dr_handle           curr,
                             unsigned_16  const *tags,
                             DRWLKBLK *wlks,  void *d )
/*************************************************************/
// takes an array of tags and wlks and calls wlk on tag match
// default func called if the 0 tag at end of array has a non NULL func
// positions curr at next tag return TRUE if end of list
{
    dr_handle   abbrev;
    dr_handle   start;
    dw_tagnum   tag;
    unsigned_8  haschild;
    int         index;
    int         cont;
    DRWLKBLK    wlk;

    cont = TRUE;
    for( ;; ) {
        start = curr;
        abbrev = DWRVMReadULEB128( &curr );
        if( abbrev == 0 ) break;
        abbrev = DWRLookupAbbrev( curr, abbrev );
        tag = DWRVMReadULEB128( &abbrev );
        haschild = DWRVMReadByte( abbrev );
        abbrev += sizeof( unsigned_8 );
        index = 0;
        while( tags[index] != 0 ) {
            if( tags[index] == tag ) break;
            ++index;
        }
        wlk = wlks[index];
        if( wlk != NULL ) {
            cont = wlk( start, index, d );
        }
        if( !cont ) break;
        if( haschild ) {
            DWRSkipChildren( &abbrev, &curr );
        } else {
            DWRSkipAttribs( abbrev, &curr );
        }
    }
    return( cont );
}

extern int DWRWalkScope( dr_handle mod,
                         unsigned_16 const *tags,
                         DRWLKBLK wlk,   void *d )
/************************************************/
// walk a scope starting at mod
// if a block go into it, if a tag we are interested in call user
{
    dr_handle   abbrev;
    dr_handle   curr;
    dw_tagnum   tag;
    unsigned_8  haschild;
    int         index;

    if( !wlk( mod, 0, d ) ) // call with parent
        return( FALSE );    // FALSE == quit
    abbrev = DWRVMReadULEB128( &mod );
    if( abbrev == 0 ) {
        DWREXCEPT( DREXCEP_DWARF_LIB_FAIL );
    }

    abbrev = DWRLookupAbbrev( mod, abbrev );
    tag = DWRVMReadULEB128( &abbrev );
    haschild = DWRVMReadByte( abbrev );

    abbrev += sizeof( unsigned_8 );         /* skip child byte */
    DWRSkipAttribs( abbrev, &mod );
    if( haschild == DW_CHILDREN_yes ) {
        int         depth;
        int         skip;

        depth = 1;
        skip  = TRUE;
        curr = mod;
        for( ;; ) {
            mod = curr;
            abbrev = DWRVMReadULEB128( &curr );
            if( abbrev == 0 ) {
                if( --depth == 0 ) break;
                continue;
            }
            abbrev = DWRLookupAbbrev( curr, abbrev );
            tag = DWRVMReadULEB128( &abbrev );
            haschild = DWRVMReadByte( abbrev );
            abbrev += sizeof( unsigned_8 );
            index = 0;
            while( tags[index] != 0 ) {
                if( tags[index] == tag ) {
                    if( !wlk( mod, depth, d ) )
                        return( FALSE );    // FALSE == quit
                    break;
                }
                ++index;
            }
            if( tag == DW_TAG_lexical_block ) {
                ++depth; // go into block
                 DWRSkipAttribs( abbrev, &curr );
            } else {
                if( haschild ) {    // skip fuzz
                    DWRSkipChildren( &abbrev, &curr );
                } else {
                    DWRSkipAttribs( abbrev, &curr );
                }
            }
        }
    }
    return( TRUE );
}

static compunit_info * FindCompileInfo( compunit_info *compunit, dr_handle addr )
/*******************************************************************************/
{
    for( ;; ) {
        if( (addr >= compunit->start) && (addr <= compunit->end) ) break;
        compunit = compunit->next;
        if( compunit == NULL ) break;
    }
    if( compunit == NULL ) {
        DWREXCEPT( DREXCEP_DWARF_LIB_FAIL );
    }
    return( compunit );
}

compunit_info * DWRFindCompileInfo( dr_handle addr )
/**************************************************/
/* gets the dr_handle of the module that addr is in */
{
    compunit_info   *compunit;

    compunit = DWRCurrNode->last_ccu;
    if( addr < compunit->start ) {  // start at begining
        compunit = &DWRCurrNode->compunit;
    }
    compunit = FindCompileInfo( compunit, addr );
    DWRCurrNode->last_ccu = compunit;
    return( compunit );
}

dr_handle DWRFindCompileUnit( dr_handle addr )
/********************************************/
{
    compunit_info   *compunit;

    compunit = DWRFindCompileInfo( addr );
    return( compunit->start );
}

#define CONTEXT_GUESS 0x10

extern void DWRContextPush( dr_context_stack *stack, uint_32 val )
/****************************************************************/
{
    if( stack->stack == NULL ) {
        stack->stack = DWRALLOC( CONTEXT_GUESS * sizeof( uint_32 ) );
        stack->free = 0;
        stack->size = CONTEXT_GUESS;
    }
    if( stack->free >= stack->size ) {
        stack->size += CONTEXT_GUESS;
        stack->stack = DWRREALLOC( stack->stack, stack->size * sizeof( dr_handle ) );
    }

    stack->stack[ stack->free ] = val;
    stack->free += 1;
}

extern uint_32 DWRContextPop( dr_context_stack *stack )
/*****************************************************/
{
    if( stack->free <= 0 ) {
        DWREXCEPT( DREXCEP_DWARF_LIB_FAIL );
    }

    stack->free -= 1;
    return( stack->stack[ stack->free ] );
}

extern dr_handle DWRContext( dr_context_stack *stack, int up )
/************************************************************/
{
    int free;

    free = stack->free;
    free -= up+1;
    if( free <= 0 ) {
        return( 0 );
    }
    return( stack->stack[free] );
}

extern void DWRFreeContextStack( dr_context_stack *stack )
/********************************************************/
{
    DWRFREE( stack->stack );
    stack->free = 0;
    stack->size = 0;
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?