dwabbrev.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 252 行

C
252
字号
/****************************************************************************
*
*                            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!
*
****************************************************************************/


/*
    manage the .debug_abbrev section
*/
#include "dwpriv.h"
#include "dwutils.h"
#include "dwabbrev.h"
#include "dwdecl.h"


#include "dwabinfo.gh"


static const struct {
    abbrev_code                 bit;
    char                        data[2];
}                               bitEncodings[] = {
    { AB_DECLARATION,           { DW_AT_declaration,    DW_FORM_flag } },
    { AB_ACCESSIBILITY,         { DW_AT_accessibility,  DW_FORM_data1 } },
    { AB_OPACCESS,              { DW_AT_accessibility,  DW_FORM_data1 } },
    { AB_TYPE,                  { DW_AT_type,           DW_FORM_ref4  } },
    { AB_NAME,                  { DW_AT_name,           DW_FORM_string } },
    { AB_START_SCOPE,           { DW_AT_start_scope,    DW_FORM_udata } },
    { AB_BYTE_SIZE,             { DW_AT_byte_size,      DW_FORM_udata } },
    { AB_DATA_LOCATION,         { DW_AT_data_member_location, DW_FORM_block1 } },
    { AB_RETURN_ADDR,           { DW_AT_return_addr,    DW_FORM_block1 } },
    { AB_ARTIFICIAL,            { DW_AT_artificial,     DW_FORM_flag } },
    { AB_MEMBER,                { DW_AT_containing_type,DW_FORM_ref4 } },
    { AB_SEGMENT,               { DW_AT_segment,        DW_FORM_block1 } },
    { AB_ADDRESS_CLASS,         { DW_AT_address_class,  DW_FORM_data1 } },
    { AB_VTABLE_LOC,            { DW_AT_vtable_elem_location, DW_FORM_block1 } }
};


static const uint_8 zeros[] = { 0, 0 };

/*
    Read the comments in dwmakeab.c for more information on the
    meaning of some of these variables.

    The actual map from W(u) to K(dim(W(u))) here is backwards from
    what was shown in the example in dwmakeab.c.  This is simply
    for performance reasons.
*/
static uint mapFromWToX(
    abbrev_code                 abbrev )
{
    uint                        result;
    abbrev_code                 mask;
    uint                        index;

    /* first we map W(u) onto K(dim(W(u))) */
    result = 0;
    index = ( abbrev & AB_ENUM_MASK ) - 1;
    mask = abbrevInfo[ index ].valid_mask & ~AB_ALWAYS;
    while( mask ) {
        if( mask & 1 ) {
            result = result * 2 + ( abbrev & 1 );
        }
        mask >>= 1;
        abbrev >>= 1;
    }
    /* finally we map onto X */
    return( result + abbrevInfo[ index ].bit_index );
}

unsigned MarkAbbrevAsUsed(
    dw_client                   cli,
    abbrev_code *               abbrev )
{
    static const uint_8         sibling_attr[] = {
        DW_AT_sibling,          DW_FORM_ref4
    };
    uint                        index;
    uint                        code;
    uint_8                      bit;
    char                        buf[ 2*MAX_LEB128 ];
    char                        *end;
    const struct abbrev_info *  data;
    int                         i;

    data = &abbrevInfo[ ( *abbrev & AB_ENUM_MASK ) - 1 ];

    /* check for AT_decl_* */
    *abbrev |= CheckDecl( cli, data->valid_mask );

    /* check the emitted bit set to see if we've emitted this already */
    code = mapFromWToX( *abbrev );
    bit = 1 << ( code & 0x7 );
    index = code / 8;
    code++;             // make sure we don't get a zero code.
    if( cli->debug_abbrev.emitted[ index ] & bit ) return( code );
    /* has not been emitted */
    cli->debug_abbrev.emitted[ index ] |= bit;
    /* if pre compiled abbrevs don't gen */
    if( cli->compiler_options & DW_CM_ABBREV_PRE ) return( code );
    /* emit the abbrev number, and tag */
    end = ULEB128( buf, code );
    end = ULEB128( end, data->tag );
    CLIWrite( DW_DEBUG_ABBREV, buf, end - buf );

    /* add in the attributes that are always emitted */
    *abbrev |= data->valid_mask & AB_ALWAYS;

    /* emit the child byte */
    if( *abbrev & AB_SIBLING ) {
        buf[0] = DW_CHILDREN_yes;
        CLIWrite( DW_DEBUG_ABBREV, buf, 1 );
        CLIWrite( DW_DEBUG_ABBREV, sibling_attr, sizeof(sibling_attr) );
    } else {
        buf[0] = DW_CHILDREN_no;
        CLIWrite( DW_DEBUG_ABBREV, buf, 1 );
    }

    /* AT_decl_file and AT_decl_line must occur here */
    if( *abbrev & AB_DECL ) {
        static const uint_8     attr[] = {
            DW_AT_decl_file,    DW_FORM_udata,
            DW_AT_decl_line,    DW_FORM_udata,
            DW_AT_decl_column,  DW_FORM_udata
        };
        CLIWrite( DW_DEBUG_ABBREV, attr, sizeof( attr ) );
    }

    /* now emit the extra attributes */
    for( i = 0; i < sizeof(bitEncodings) / sizeof(bitEncodings[0]); ++i ) {
        if( *abbrev & bitEncodings[ i ].bit ) {
            CLIWrite( DW_DEBUG_ABBREV, bitEncodings[ i ].data, 2 );
        }
    }

    if( *abbrev & AB_LOWHIGH_PC ) {
        static const uint_8     lowhi_attrs[] = {
            DW_AT_low_pc,       DW_FORM_addr,
            DW_AT_high_pc,      DW_FORM_addr,
        };
        CLIWrite( DW_DEBUG_ABBREV, lowhi_attrs, sizeof( lowhi_attrs ) );
    }

    /* now do the AB_SUBR_DECLARATION kludge */
    if( data->valid_mask & AB_SUBR_DECLARATION ) {
        if( *abbrev & AB_SUBR_DECLARATION ) {
            buf[0] = DW_AT_declaration;
            buf[1] = DW_FORM_flag;
            CLIWrite( DW_DEBUG_ABBREV, buf, 2 );
        } else {
            static const uint_8 subr_attrs[] = {
                DW_AT_return_addr,      DW_FORM_block1,
                DW_AT_low_pc,           DW_FORM_addr,
                DW_AT_high_pc,          DW_FORM_addr,
            };
            CLIWrite( DW_DEBUG_ABBREV, subr_attrs, sizeof( subr_attrs ) );
        }
    }

    /* and finally the base information */
    if( data->data_len ) {
        CLIWrite( DW_DEBUG_ABBREV, &encodings[ data->data_offset ],
            data->data_len );
    }

    /* and the zero terminators */
    CLIWrite( DW_DEBUG_ABBREV, zeros, 2 );
    return( code );
}


void InitDebugAbbrev(
    dw_client                   cli )
{
    memset( cli->debug_abbrev.emitted, 0, sizeof( cli->debug_abbrev.emitted ) );
}


void FiniDebugAbbrev(
    dw_client                   cli )
{
    CLIWrite( DW_DEBUG_ABBREV, zeros, 1 );
}

extern void  GenAllAbbrev( dw_client  cli ){

    abbrev_code                 abbrev;
    uint_32                     mask;
    uint                        index;
    uint                        count;
    uint                        mask_count;
    uint_32                     mask_bit;

    /* generate all abbrev codes */
    index = 0;
    while( index < (AB_MAX-1) ){
        if( (index+1) == (AB_MAX-1) ){
            count = AB_LAST_CODE - abbrevInfo[index].bit_index;
        }else{
            count = abbrevInfo[index+1].bit_index-abbrevInfo[index].bit_index;
        }
        mask = abbrevInfo[ index ].valid_mask & ~AB_ALWAYS;
        for( mask_count = 0;  mask_count < count; ++mask_count ){
            uint which_mask_bits;

            abbrev = 0;
            mask_bit = 0x80000000;
            which_mask_bits = mask_count;
            while( which_mask_bits ) {
                while( (mask & mask_bit ) == 0 ){ /* tab to next bit flag */
                    mask_bit >>= 1;
                }
                if( which_mask_bits & 1 ) {
                    abbrev |= mask_bit;
                }
                mask_bit >>= 1;
                which_mask_bits >>=1;
            }
            abbrev |= (index+1);
            MarkAbbrevAsUsed( cli, &abbrev );
        }
        ++index;
    }
}

⌨️ 快捷键说明

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