⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dwarf2.c

📁 主要用于在线分析dsp目标代码的调试信息。DSP平台下用CCS调试源代码时
💻 C
📖 第 1 页 / 共 5 页
字号:
        if (! TYPE_TARGET_TYPE ( type ))
        {
            TYPE_TARGET_TYPE ( type ) = alloc_type ();  /* TYPE_CODE_UNDEF */
        }
        type = TYPE_TARGET_TYPE ( type );
    }

    is_const = TYPE_CONST ( type );
    is_volatile = TYPE_VOLATILE ( type );

    /* If this is a struct/class/union with no fields, then check whether a
     full definition exists somewhere else.  This is for systems where a
     type definition with no fields is issued for such types, instead of
     identifying them as stub types in the first place */

    if ( TYPE_IS_OPAQUE ( type ) )
    {
        char * name = type_name_no_tag ( type );
        struct type * newtype = NULL;
        if ( name == NULL )
        {
            //complain (&stub_noname_complaint);
            return type;
        }
        //newtype = lookup_transparent_type (name);
        if ( newtype )
            make_cv_type ( is_const, is_volatile, newtype, & type );
    }
    /* Otherwise, rely on the stub flag being set for opaque/stubbed types */
    else if ( TYPE_STUB ( type ) )
    {
    }

    if ( TYPE_TARGET_STUB ( type ))
    {
        struct type * range_type;
        struct type * target_type = check_typedef ( TYPE_TARGET_TYPE ( type ));

        if ( TYPE_STUB ( target_type ) || TYPE_TARGET_STUB ( target_type ))
        {
        }
        else if ( TYPE_CODE ( type ) == TYPE_CODE_ARRAY
            && TYPE_NFIELDS ( type ) == 1
            && ( TYPE_CODE ( range_type = TYPE_FIELD_TYPE ( type, 0 ))
            == TYPE_CODE_RANGE ))
        {
            /* Now recompute the length of the array type, based on its
         number of elements and the target type's length.  */
            TYPE_LENGTH ( type ) = (( TYPE_FIELD_BITPOS ( range_type, 1 )
                - TYPE_FIELD_BITPOS ( range_type, 0 ) + 1 )
                * TYPE_LENGTH ( target_type ));
            TYPE_FLAGS ( type ) &= ~ TYPE_FLAG_TARGET_STUB;
        }
        else if ( TYPE_CODE ( type ) == TYPE_CODE_RANGE )
        {
            TYPE_LENGTH ( type ) = TYPE_LENGTH ( target_type );
            TYPE_FLAGS ( type ) &= ~ TYPE_FLAG_TARGET_STUB;
        }
    }
    /* Cache TYPE_LENGTH for future use. */
    TYPE_LENGTH ( orig_type ) = TYPE_LENGTH ( type );
    return type;
}

static void read_array_type ( struct die_info * die, const struct comp_unit_head * cu_header )
{
    struct die_info * child_die;
    struct type * type = NULL;
    struct type * element_type, * range_type, * index_type;
    struct type ** range_types = NULL;
    struct attribute * attr;
    int ndim = 0;
    /* Return if we've already decoded this type. */
    if ( die->ptype )
    {
        return;
    }

    element_type = die_type ( die,  cu_header );
    if( ! element_type )
    {
        printf( "find no element type\r\n" );
        return;
    }

    /* Irix 6.2 native cc creates array types without children for
     arrays with unspecified length.  */
    if ( die->has_children == 0 )
    {
        index_type = dwarf2_fundamental_type ( FT_INTEGER );
        range_type = create_range_type ( NULL, index_type, 0, - 1 );
        die->ptype = create_array_type ( NULL, element_type, range_type );
        return;
    }

    child_die = die->next;
    while ( child_die && child_die->tag )
    {
        if ( child_die->tag == DW_TAG_subrange_type )
        {
            int low, high;

            /* Default bounds to an array with unspecified length.  */
            low = 0;
            high = - 1;

            index_type = die_type ( child_die, cu_header );
            attr = dwarf_attr ( child_die, DW_AT_lower_bound );
            if ( attr )
            {
                if ( attr->form == DW_FORM_sdata )
                {
                    low = DW_SND ( attr );
                }
                else if ( attr->form == DW_FORM_udata
                    || attr->form == DW_FORM_data1
                    || attr->form == DW_FORM_data2
                    || attr->form == DW_FORM_data4
                    || attr->form == DW_FORM_data8 )
                {
                    low = DW_UNSND ( attr );
                }
                else
                {
                    low = 0;
                }
            }
            attr = dwarf_attr ( child_die, DW_AT_upper_bound );
            if ( attr )
            {
                if ( attr->form == DW_FORM_sdata )
                {
                    high = DW_SND ( attr );
                }
                else if ( attr->form == DW_FORM_udata
                    || attr->form == DW_FORM_data1
                    || attr->form == DW_FORM_data2
                    || attr->form == DW_FORM_data4
                    || attr->form == DW_FORM_data8 )
                {
                    high = DW_UNSND ( attr );
                }
                else if ( attr->form == DW_FORM_block1 )
                {
                    /* GCC encodes arrays with unspecified or dynamic length
                     with a DW_FORM_block1 attribute.
                     FIXME: GDB does not yet know how to handle dynamic
                     arrays properly, treat them as arrays with unspecified
                     length for now.  */
                    high = - 1;
                }
                else
                {
                    high = 1;
                }
            }

            /* Create a range type and save it for array type creation.  */
            if (( ndim % DW_FIELD_ALLOC_CHUNK ) == 0 )
            {
                range_types = ( struct type **)
                    realloc ( range_types, ( ndim + DW_FIELD_ALLOC_CHUNK )
                    * sizeof ( struct type *));
                if ( ndim == 0 )
                {
                }
            }
            range_types[ndim ++ ] = create_range_type ( NULL, index_type, low, high );
        }
        child_die = sibling_die ( child_die );
    }

    /* Dwarf2 dimensions are output from left to right, create the
     necessary array types in backwards order.  */
    type = element_type;
    while ( ndim -- > 0 )
        type = create_array_type ( NULL, type, range_types[ndim] );

    /* Understand Dwarf2 support for vector types (like they occur on
     the PowerPC w/ AltiVec).  Gcc just adds another attribute to the
     array type.  This is not part of the Dwarf2/3 standard yet, but a
     custom vendor extension.  The main difference between a regular
     array and the vector variant is that vectors are passed by value
     to functions.  */
    attr = dwarf_attr ( die, DW_AT_GNU_vector );
    if ( attr )
        TYPE_FLAGS ( type ) |= TYPE_FLAG_VECTOR;

    /* Install the type in the die. */
    die->ptype = type;
}

static void read_typedef ( struct die_info * die, const struct comp_unit_head * cu_header )
{
    struct attribute * attr;
    char * name = NULL;

    if (! die->ptype )
    {
        attr = dwarf_attr ( die, DW_AT_name );
        if ( attr && DW_STRING ( attr ))
        {
            name = DW_STRING ( attr );
        }
        die->ptype = init_type ( TYPE_CODE_TYPEDEF, 0, TYPE_FLAG_TARGET_STUB, name );
        TYPE_TARGET_TYPE ( die->ptype ) = die_type ( die, cu_header );
    }
}

void smash_to_member_type ( struct type * type, struct type * domain, struct type * to_type )
{
    smash_type ( type );
    TYPE_TARGET_TYPE ( type ) = to_type;
    TYPE_DOMAIN_TYPE ( type ) = domain;
    TYPE_LENGTH ( type ) = 1;   /* In practice, this is never needed.  */
    TYPE_CODE ( type ) = TYPE_CODE_MEMBER;
}

static void read_tag_ptr_to_member_type ( struct die_info * die, const struct comp_unit_head * cu_header )
{
    struct type * type;
    struct type * to_type;
    struct type * domain;

    if ( die->ptype )
    {
        return;
    }

    type = alloc_type ();
    to_type = die_type ( die,  cu_header );
    domain = die_containing_type ( die, cu_header );
    smash_to_member_type ( type, domain, to_type );

    die->ptype = type;
}

static void read_tag_volatile_type ( struct die_info * die, const struct comp_unit_head * cu_header )
{
    struct type * base_type;

    if ( die->ptype )
    {
        return;
    }

    base_type = die_type ( die,  cu_header );
    die->ptype = make_cv_type ( TYPE_CONST ( base_type ), 1, base_type, 0 );
}

static void read_type_die ( struct die_info * die,  const struct comp_unit_head * cu_header )
{
    switch ( die->tag )
    {
    case DW_TAG_class_type:
    case DW_TAG_structure_type:
    case DW_TAG_union_type:
        read_structure_scope ( die, cu_header );
        break;
    case DW_TAG_enumeration_type:

        read_enumeration ( die,  cu_header );

        break;
    case DW_TAG_subprogram:
    case DW_TAG_subroutine_type:
        read_subroutine_type ( die,  cu_header );
        break;
    case DW_TAG_array_type:
        read_array_type ( die,  cu_header );
        break;
    case DW_TAG_pointer_type:

        read_tag_pointer_type ( die,  cu_header );

        break;
    case DW_TAG_ptr_to_member_type:

        read_tag_ptr_to_member_type ( die,  cu_header );

        break;
    case DW_TAG_reference_type:
        /*
        read_tag_reference_type (die, objfile, cu_header);
        */
        break;
    case DW_TAG_const_type:
        read_tag_const_type ( die, cu_header );
        break;
    case DW_TAG_volatile_type:

        read_tag_volatile_type ( die, cu_header );

        break;
    case DW_TAG_string_type:
        /*
        read_tag_string_type (die, objfile);
        */
        break;
    case DW_TAG_typedef:
        read_typedef ( die, cu_header );
        break;
    case DW_TAG_base_type:
        read_base_type ( die );
        break;
    default:
        /*
        complain (&dwarf2_unexpected_tag, dwarf_tag_name (die->tag));
        */
        break;
    }
}

static struct type * tag_type_to_type ( struct die_info * die, const struct comp_unit_head * cu_header )
{
    if ( die->ptype )
    {
        return die->ptype;
    }
    else
    {
        read_type_die ( die, cu_header );
        if (! die->ptype )
        {
            printf ( "Dwarf Error: Cannot find type of die." );
        }
        return die->ptype;
    }
}

/* Return the type of the die in question using its DW_AT_type attribute.  */

static struct type * die_type ( struct die_info * die, const struct comp_unit_head * cu_header )
{
    struct type * type;
    struct attribute * type_attr;
    struct die_info * type_die;
    unsigned int ref;

    type_attr = dwarf_attr ( die, DW_AT_type );
    if (! type_attr )
    {
        /* A missing DW_AT_type represents a void type.  */
        return dwarf2_fundamental_type ( FT_VOID );
    }
    else
    {
        ref = dwarf2_get_ref_die_offset ( type_attr );
        type_die = follow_die_ref ( ref );
        if (! type_die )
        {
            printf ( "Dwarf Error: Cannot find referent at offset %d.", ref );
            return NULL;
        }
    }
    type = tag_type_to_type ( type_die, cu_header );
    if (! type )
    {
        printf ( "Dwarf Error: Problem turning type die at offset into gdb type." );
    }
    return type;
}

static int frame_base_reg;
static CORE_ADDR frame_base_offset;

static CORE_ADDR decode_locdesc ( struct dwarf_block * blk, const struct comp_unit_head * cu_header )
{
    int i;
    int size = blk->size;
    char * data = blk->data;
    CORE_ADDR stack[64]; /* stack */
    int stacki;
    unsigned int bytes_read, unsnd;
    unsigned char op;

    i = 0;
    stacki = 0;
    stack[stacki] = 0;
    while ( i < size )
    {
        op = data[i ++ ];
        switch ( op )
        {
        case DW_OP_lit0:
        case DW_OP_lit1:
        case DW_OP_lit2:
        case DW_OP_lit3:
        case DW_OP_lit4:
        case DW_OP_lit5:
        case DW_OP_lit6:
        case DW_OP_lit7:
        case DW_OP_lit8:
        case DW_OP_lit9:
        case DW_OP_lit10:
        case DW_OP_lit11:
        case DW_OP_lit12:
        case DW_OP_lit13:
        case DW_OP_lit14:
        case DW_OP_lit15:
        case DW_OP_lit16:
        case DW_OP_lit17:
        case DW_OP_lit18:
        case DW_OP_lit19:
        case DW_OP_lit20:
        case DW_OP_lit21:
        case DW_OP_lit22:
        case DW_OP_lit23:
        case DW_OP_lit24:
        case DW_OP_lit25:
        case DW_OP_lit26:
        case DW_OP_lit27:
        case DW_OP_lit28:
       

⌨️ 快捷键说明

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