drutils.c

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

C
1,082
字号
extern dwr_formcl DWRFormClass( unsigned_16 form )
/************************************************/
// class a form
{
    dwr_formcl formcl;

    switch( form ) {
    case DW_FORM_addr:
        formcl = DWR_FORMCL_address;
        break;
    case DW_FORM_block1:
    case DW_FORM_block2:
    case DW_FORM_block4:
    case DW_FORM_block:
        formcl = DWR_FORMCL_block;
        break;
    case DW_FORM_flag:
        formcl = DWR_FORMCL_flag;
        break;
    case DW_FORM_data1:
    case DW_FORM_data2:
    case DW_FORM_data4:
    case DW_FORM_data8:
    case DW_FORM_sdata:
    case DW_FORM_udata:
        formcl = DWR_FORMCL_data;
        break;
    case DW_FORM_ref1:
    case DW_FORM_ref2:
    case DW_FORM_ref4:
    case DW_FORM_ref_udata:
        formcl = DWR_FORMCL_ref;
        break;
    case DW_FORM_ref_addr:
        formcl = DWR_FORMCL_ref_addr;
        break;
    case DW_FORM_string:
        formcl = DWR_FORMCL_string;
        break;
    case DW_FORM_indirect:
        formcl = DWR_FORMCL_indirect;
        break;
    default:
        DWREXCEPT( DREXCEP_BAD_DBG_INFO );
    }
    return( formcl );
}

extern unsigned_32 ReadConst( unsigned form, dr_handle info )
/***********************************************************/
{
    unsigned_32 retval;

    switch( form ) {
    case DW_FORM_data1:
    case DW_FORM_ref1:
    case DW_FORM_flag:
        retval = DWRVMReadByte( info );
        break;
    case DW_FORM_data2:
    case DW_FORM_ref2:
        retval = DWRVMReadWord( info );
        break;
    case DW_FORM_ref_addr:      // NYI: non-standard behaviour for DW_FORM_ref
    case DW_FORM_data4:
    case DW_FORM_ref4:
        retval = DWRVMReadDWord( info );
        break;
    case DW_FORM_sdata:
        retval = DWRVMReadSLEB128( &info );
        break;
    case DW_FORM_udata:
    case DW_FORM_ref_udata:
        retval = DWRVMReadULEB128( &info );
        break;
    case DW_FORM_indirect:
        retval = DWRVMReadULEB128( &info );
        retval = ReadConst( retval, info );
        break;
    default:
        DWREXCEPT( DREXCEP_BAD_DBG_INFO );
    }
    return( retval );
}

extern unsigned_32 DWRReadConstant( dr_handle abbrev, dr_handle info )
/********************************************************************/
{
    unsigned    form;

    form = DWRVMReadULEB128( &abbrev );
    return( ReadConst( form, info ) );
}

extern dr_handle DWRReadReference( dr_handle abbrev, dr_handle info )
/*******************************************************************/
// references are just a constant with the start of the compile unit added on.
{
    dr_handle       handle;
    dw_formnum      form;

    form = DWRVMReadULEB128( &abbrev );
    handle =  ReadConst( form, info );
    if( handle != 0 ) {     // if not NULL relocate
        if( form != DW_FORM_ref_addr ) {
            handle += DWRFindCompileUnit( info );
        } else {
            if( DWRCurrNode->wat_version == 1 ) { // handle Watcom 10.x DWARF
                handle += DWRFindCompileUnit( info );
            } else {
                handle += DWRCurrNode->sections[DR_DEBUG_INFO].base;
            }
        }
    }
    return( handle );
}

extern dr_handle DWRReadAddr( dr_handle abbrev, dr_handle info )
/**************************************************************/
// address size dependent on CCU info
{
    dr_handle    handle;
    unsigned     addr_size;
    unsigned_32  retval;
    unsigned     form;

    form = DWRVMReadULEB128( &abbrev );
    if( form != DW_FORM_addr ) {
        DWREXCEPT( DREXCEP_BAD_DBG_INFO );
    }
    if( DWRCurrNode->addr_size == 0 ) {
        handle =  DWRFindCompileUnit( info );
        addr_size = DWRGetAddrSize( handle );
    } else {
        addr_size = DWRCurrNode->addr_size;
    }
    switch( addr_size ) {
    case 1:
        retval = DWRVMReadByte( info );
        break;
    case 2:
        retval = DWRVMReadWord( info );
        break;
    case 4:
        retval = DWRVMReadDWord( info );
        break;
     }
    return( retval );
}

extern char * DWRReadString( dr_handle abbrev, dr_handle info )
/*************************************************************/
{
    unsigned    form;
    unsigned_32 offset;

    form = DWRVMReadULEB128( &abbrev );
    switch( form ) {
    case DW_FORM_string:
        return( DWRCopyString( &info ) );
    case DW_FORM_strp:
        offset = ReadConst( DW_FORM_data4, info );
        return( DWRCopyDbgSecString( &info, offset ) );
    default:
        DWREXCEPT( DREXCEP_BAD_DBG_INFO );
    }
    return( NULL );
}

extern int DWRReadFlag( dr_handle abbrev, dr_handle info )
/********************************************************/
{
    unsigned    form;

    form = DWRVMReadULEB128( &abbrev );
    if( form == DW_FORM_data1 || form == DW_FORM_flag ) {
        return( DWRVMReadByte( info ) );
    } else {
        DWREXCEPT( DREXCEP_BAD_DBG_INFO );
    }
    return( 0 );
}

extern dr_handle DWRGetAbbrev( dr_handle *entry )
/***********************************************/
{
    dr_handle       abbrev;
    compunit_info   *cu;

    cu = DWRFindCompileInfo( *entry );
    abbrev = DWRVMReadULEB128( entry );
    abbrev = cu->abbrevs[abbrev];
    DWRVMSkipLEB128( &abbrev ); // skip the tag.
    abbrev++;                   // skip the child pointer.
    return( abbrev );
}

extern dr_handle DWRLookupAbbrev( dr_handle entry, dr_handle abbr )
/*****************************************************************/
{
    dr_handle       abbrev;
    compunit_info   *cu;

    cu = DWRFindCompileInfo( entry );
    if( abbr >= cu->numabbrevs ) {
        DWREXCEPT( DREXCEP_BAD_DBG_INFO );
        abbrev = 0;
    } else
        abbrev = cu->abbrevs[abbr];
    return( abbrev );
}

extern dr_handle DWRReadAbbrev( dr_handle entry )
/***********************************************/
{
    dr_handle       abbrev;

    abbrev = DWRVMReadULEB128( &entry );
    return( DWRLookupAbbrev( entry, abbrev ) );
}

extern char * DWRCopyString( dr_handle *info )
/********************************************/
{
    unsigned    count;
    char        *str;

    count = DWRStrLen( *info );
    str = DWRALLOC( count + 1 );
    DWRGetString( str, info );
    return( str );
}

extern char * DWRCopyDbgSecString( dr_handle *info, unsigned_32 offset )
/**********************************************************************/
{
    unsigned    count;
    char        *str;
    dr_handle   dbgsec_str;

    dbgsec_str = DWRCurrNode->sections[DR_DEBUG_STR].base + offset;
    count = DWRStrLen( dbgsec_str );
    str = DWRALLOC( count + 1 );
    DWRGetString( str, &dbgsec_str );
    return( str );
}

extern dw_atnum DWRScanForAttrib( dr_handle *abbrev, dr_handle *info,
                                                        dw_atnum at )
/*******************************************************************/
/* look for a specific attribute in the list of attributes */
{
    dw_atnum    attrib;
    dw_formnum  form;

    for( ;; ) {
        attrib = DWRVMReadULEB128( abbrev );
        if( attrib == at ) break;
        form = DWRVMReadULEB128( abbrev );
        if( attrib == 0 ) break;
        DWRSkipForm( info, form );
    }
    return( attrib );
}

static unsigned_16 CompUnitTag[] = { DW_TAG_compile_unit, 0 };

extern void DWRGetCompileUnitHdr( dr_handle mod,
                                  DWRCUWLK fn,
                                  void *data )
/**********************************************/
{
    dr_search_context   ctxt;
    compunit_info       *compunit;

    compunit = DWRFindCompileInfo( mod );
    ctxt.compunit = compunit;

    ctxt.start = compunit->start;
    ctxt.end = compunit->start + DWRVMReadDWord( compunit->start );
    ctxt.start += COMPILE_UNIT_HDR_SIZE;
    ctxt.stack.size = 0;
    ctxt.stack.free = 0;
    ctxt.stack.stack = NULL;

    DWRScanCompileUnit( &ctxt, fn, CompUnitTag, 0, data );
    DWRFreeContextStack( &ctxt.stack );
}

extern dr_handle DRGetCompileUnitTag( dr_handle comp_unit )
/*********************************************************/
{ // given the start of the compilation unit header
  // return the start of the DW_TAG_compile_unit
  // assume it starts after header

    comp_unit += COMPILE_UNIT_HDR_SIZE;
    return( comp_unit );
}

#define DEMANGLE_BUF_SIZE 256

extern char * DWRGetName( dr_handle abbrev, dr_handle entry )
/***********************************************************/
{
    char    *name;
    char    buffer[ DEMANGLE_BUF_SIZE ];
    int     len;
    int     base_len;

    name = NULL;
    if( DWRScanForAttrib( &abbrev, &entry, DW_AT_name ) != 0 ) {
        name = DWRReadString( abbrev, entry );

        len = strlen( name );
        if( __is_mangled( name, len ) ) {
            base_len = __demangled_basename( name, len,
                                             buffer, DEMANGLE_BUF_SIZE );

            DWRREALLOC( name, base_len + 1 );
            strncpy( name, buffer, base_len + 1 );
        }
    }
    return( name );
}

void DRIterateCompileUnits( void *data, bool (*callback)( void *, dr_handle ) )
/*****************************************************************************/
{
    compunit_info   *compunit;

    compunit = &DWRCurrNode->compunit;
    do {
        if( !callback( data, compunit->start ) ) break;    // FALSE == quit
        compunit = compunit->next;
    } while( compunit != NULL );
}

bool DWRScanAllCompileUnits( dr_search_context * startingCtxt,
                        DWRCUWLK fn,
                        unsigned_16 const *tagarray, dr_depth depth, void * data )
/********************************************************************************/
{
    bool                cont;
    dr_search_context   ctxt;
    int                 i;

    if( startingCtxt == NULL ) {
        ctxt.compunit = &DWRCurrNode->compunit;
        ctxt.start = ((compunit_info *)ctxt.compunit)->start;
        ctxt.end = ctxt.start + DWRVMReadDWord( ctxt.start );
        ctxt.start += COMPILE_UNIT_HDR_SIZE;
        ctxt.classhdl = 0;
        ctxt.functionhdl = 0;
        ctxt.stack.size = 0;
        ctxt.stack.free = 0;
        ctxt.stack.stack = NULL;
    } else {
        ctxt = *startingCtxt;   /* structure copy */

        /* but allocate and copy own stack */
        ctxt.stack.stack = DWRALLOC( ctxt.stack.size * sizeof( uint_32 ) );

⌨️ 快捷键说明

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