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

📄 dwarf2.c

📁 主要用于在线分析dsp目标代码的调试信息。DSP平台下用CCS调试源代码时
💻 C
📖 第 1 页 / 共 5 页
字号:
        info_ptr = read_attribute (& die->attrs[i], & abbrev->attrs[i], info_ptr, cu_header );
    }
    die_index[total_die_per_unit] = index;
    index += sizeof ( struct die_info ) + sizeof( struct attribute ) * abbrev->num_attrs ;
    total_die_per_unit ++;
    * diep = die;
    return info_ptr;
}

/* Read the die from the .debug_info section buffer.  And set diep to
   point to a newly allocated die with its information.  */

static char * read_full_die ( int * nest_level, struct die_info * die,  char * info_ptr,
    const struct comp_unit_head * cu_header )
{
    unsigned int abbrev_number, bytes_read, i, offset;
    struct abbrev_info * abbrev;

    offset = info_ptr - dwarf_info_buffer;
    abbrev_number = read_unsigned_leb128 ( info_ptr, & bytes_read );
    info_ptr += bytes_read;
    if (! abbrev_number )
    {
        * nest_level -= 1;
        if( info_ptr < end_ptr && !* nest_level )
        {
            * nest_level += 1;
            info_ptr = read_full_die( nest_level, die, info_ptr, cu_header ); /* 如果是对齐要求读下一个DIE */
            return info_ptr;
        }
        die->tag = ( enum dwarf_tag )0;
        die->abbrev = abbrev_number;
        die->offset = offset;
        die->ptype = NULL;
        return info_ptr;
    }

    abbrev = dwarf2_lookup_abbrev ( abbrev_number );
    die->offset = offset;
    die->tag = abbrev->tag;
    die->has_children = abbrev->has_children;
    if( die->has_children )
        * nest_level += 1;
    die->abbrev = abbrev_number;
    die->ptype = NULL;

    die->num_attrs = abbrev->num_attrs;
    die->attrs = ( struct attribute * )( die + 1 );

    for ( i = 0; i < abbrev->num_attrs; ++ i )
    {
        info_ptr = read_attribute (& die->attrs[i], & abbrev->attrs[i], info_ptr, cu_header );
    }

    return info_ptr;
}

static struct die_info * read_comp_unit ( char * info_ptr, const struct comp_unit_head * cu_header )
{
    struct die_info * first_die, * last_die, * die;
    char * cur_ptr;
    char * all_in_mem = NULL;
    int nesting_level;
    int i;

    /* Reset die reference table; we are
    building new ones now.  */

    cur_ptr = info_ptr;
    end_ptr = info_ptr + cu_header->length - 7 ; /* 计算当前unit的结束指针 */
    nesting_level = 0;
    first_die = last_die = NULL;
    init_scan();
    /* 开始时扫描该unit的DIE, 以获得需要分配的空间 */
    do
    {
        cur_ptr = scan_full_die(& nesting_level, & die, cur_ptr, cu_header );
        if( die )
            free( die ); /* 紧接着释放当前die */
    } while(( unsigned int )cur_ptr < ( unsigned int )end_ptr );

    /* 正式分配DIE */
    cur_ptr = info_ptr;
    nesting_level = 0;
    all_in_mem = ( char * )malloc( index ); /* index中保存了所需要分配空间的总数 */
    memset( all_in_mem, 0, index ); /* 缓冲区清0 */
    for( i = 0 ; i < total_die_per_unit; i ++ )
    {
        die = ( struct die_info *)( all_in_mem + die_index[i] );
        cur_ptr = read_full_die(& nesting_level, die, cur_ptr, cu_header );
        die->next = NULL;

        /* Enter die in reference hash table */
        store_in_ref_table ( die->offset, die );

        if (! first_die )
        {
            first_die = last_die = die;
        }
        else
        {
            last_die->next = die;
            last_die = die;
        }
    }
    uninit_scan();
    return first_die;
}

/* Read in the comp unit header information from the debug_info at
   info_ptr. */

static char * read_comp_unit_head ( struct comp_unit_head * cu_header, char * info_ptr )
{
    int bytes_read;
    cu_header->length = read_initial_length ( info_ptr, cu_header,
        & bytes_read );
    info_ptr += bytes_read;
    cu_header->version = read_2_bytes ( info_ptr );
    info_ptr += 2; /* 更改指针 */
    cu_header->abbrev_offset = read_offset ( info_ptr, cu_header,
        & bytes_read );
    info_ptr += bytes_read;
    cu_header->addr_size = read_1_byte ( info_ptr );
    info_ptr += 1;
    cu_header->signed_addr_p = 1; /* 确定为有符号地址 */
    return info_ptr;
}

/* Read an attribute value described by an attribute form.  */

static char * read_attribute_value ( struct attribute * attr, unsigned form,
    char * info_ptr, const struct comp_unit_head * cu_header )
{
    unsigned int bytes_read;

    attr->form = ( enum dwarf_form )form;
    switch ( form )
    {
    case DW_FORM_addr:
    case DW_FORM_ref_addr:
        DW_ADDR ( attr ) = read_address ( info_ptr, cu_header, ( int *)& bytes_read );
        info_ptr += bytes_read;
        break;
    case DW_FORM_block2:
        DW_BLOCK ( attr ).size = read_2_bytes ( info_ptr );
        info_ptr += 2; /* 更改指针 */
        DW_BLOCK ( attr ).data = read_n_bytes ( info_ptr, DW_BLOCK ( attr ).size );
        info_ptr += DW_BLOCK ( attr ).size;
        break;
    case DW_FORM_block4:
        DW_BLOCK ( attr ).size = read_4_bytes ( info_ptr );
        info_ptr += 4; /* 更改指针 */
        DW_BLOCK ( attr ).data = read_n_bytes ( info_ptr, DW_BLOCK ( attr ).size );
        info_ptr += DW_BLOCK ( attr ).size;
        break;
    case DW_FORM_data2:
        DW_UNSND ( attr ) = read_2_bytes ( info_ptr );
        info_ptr += 2; /* 更改指针 */
        break;
    case DW_FORM_data4:
        DW_UNSND ( attr ) = read_4_bytes ( info_ptr );
        info_ptr += 4; /* 更改指针 */
        break;
    case DW_FORM_data8:
        /* 不支持该类型 */
        /*DW_UNSND (attr) = read_8_bytes (abfd, info_ptr);*/
        info_ptr += 8; /* 更改指针 */
        break;
    case DW_FORM_string:
        DW_STRING ( attr ) = read_string ( info_ptr, & bytes_read );
        info_ptr += bytes_read;
        break;
    case DW_FORM_strp:
        DW_STRING ( attr ) = read_indirect_string ( info_ptr, cu_header,
            & bytes_read );
        info_ptr += bytes_read;
        break;
    case DW_FORM_block:
        DW_BLOCK ( attr ).size = read_unsigned_leb128 ( info_ptr, & bytes_read );
        info_ptr += bytes_read;
        DW_BLOCK ( attr ).data = read_n_bytes ( info_ptr, DW_BLOCK ( attr ).size );
        info_ptr += DW_BLOCK ( attr ).size;
        break;
    case DW_FORM_block1:
        DW_BLOCK ( attr ).size = read_1_byte ( info_ptr );
        info_ptr += 1;
        DW_BLOCK ( attr ).data = read_n_bytes ( info_ptr, DW_BLOCK ( attr ).size );
        info_ptr += DW_BLOCK ( attr ).size;
        break;
    case DW_FORM_data1:
        DW_UNSND ( attr ) = read_1_byte ( info_ptr );
        info_ptr += 1;
        break;
    case DW_FORM_flag:
        DW_UNSND ( attr ) = read_1_byte ( info_ptr );
        info_ptr += 1;
        break;
    case DW_FORM_sdata:
        DW_SND ( attr ) = read_signed_leb128 ( info_ptr, & bytes_read );
        info_ptr += bytes_read;
        break;
    case DW_FORM_udata:
        DW_UNSND ( attr ) = read_unsigned_leb128 ( info_ptr, & bytes_read );
        info_ptr += bytes_read;
        break;
    case DW_FORM_ref1:
        DW_UNSND ( attr ) = read_1_byte ( info_ptr );
        info_ptr += 1;
        break;
    case DW_FORM_ref2:
        DW_UNSND ( attr ) = read_2_bytes ( info_ptr );
        info_ptr += 2; /* 更改指针 */
        break;
    case DW_FORM_ref4:
        DW_UNSND ( attr ) = read_4_bytes ( info_ptr );
        info_ptr += 4; /* 更改指针 */
        break;
    case DW_FORM_ref8:
        /*DW_UNSND (attr) = read_8_bytes (abfd, info_ptr);*/
        info_ptr += 8; /* 更改指针 */
        break;
    case DW_FORM_ref_udata:
        DW_UNSND ( attr ) = read_unsigned_leb128 ( info_ptr, & bytes_read );
        info_ptr += bytes_read;
        break;
    case DW_FORM_indirect:
        form = read_unsigned_leb128 ( info_ptr, & bytes_read );
        info_ptr += bytes_read;
        info_ptr = read_attribute_value ( attr, form, info_ptr, cu_header );
        break;
    default:
        printf ( "Dwarf Error: Cannot handle %s in DWARF reader.",
            dwarf_form_name ( form ));
    }
    return info_ptr;
}

/* Read an attribute described by an abbreviated attribute.  */

static char * read_attribute ( struct attribute * attr, struct attr_abbrev * abbrev, char * info_ptr,
    const struct comp_unit_head * cu_header )
{
    attr->name = abbrev->name;
    return read_attribute_value ( attr, abbrev->form, info_ptr, cu_header );
}

static struct type * ftypes[FT_NUM_MEMBERS];    /* Fundamental types */

static struct type * dwarf2_fundamental_type ( int typeid )
{
    if ( typeid < 0 || typeid >= FT_NUM_MEMBERS )
    {
        printf ( "Dwarf Error: internal error - invalid fundamental type id %d.", typeid );
    }

    /* Look for this particular type in the fundamental type vector.  If
    one is not found, create and install one appropriate for the
    current language and the current target machine. */

    if ( ftypes[typeid] == NULL )
    {
        ftypes[typeid] = c_create_fundamental_type( typeid );
    }

    return ( ftypes[typeid] );
}

/* Helper function to initialize the standard scalar types.

   If NAME is non-NULL and OBJFILE is non-NULL, then we make a copy
   of the string pointed to by name in the type_obstack for that objfile,
   and initialize the type name to that copy.  There are places (mipsread.c
   in particular, where init_type is called with a NULL value for NAME). */

struct type * init_type ( enum type_code code, int length, int flags, char * name )
{
    struct type * ptype;
    int size;
    int oldpri;

    if( name )
    size = sizeof( struct type ) + sizeof( struct main_type ) + strlen( name ) + 1;
    else
    size = sizeof( struct type ) + sizeof( struct main_type );

    /* 一起分配MAIN TYPE与 TYPE数据 与类型名称 */

    ptype = ( struct type * )malloc( size );
    if( ! ptype )
    {
    printf( "not enough memory malloc in %s : %d !\r\n", __FILE__, __LINE__ );
    suspend_task( get_current_task(), & oldpri ); /* 阻塞该任务 */
    }
    memset ( ptype, 0, size );
    ptype->pmain_type = ( struct main_type * )( ptype + 1 );
    ptype->chain = ptype;
    ptype->pmain_type->vptr_fieldno = - 1;

    ptype->pmain_type->code = code;
    ptype->pmain_type->length = length;
    ptype->pmain_type->flags |= flags;

    if ( name != NULL )
    {
    ptype->pmain_type->name = ( char *)( ptype->pmain_type + 1 );
    memcpy( ptype->pmain_type->name, name, strlen( name ));
    }
    else
    {
    ptype->pmain_type->name = name;
    }

    /* C++ fancies.  */

    if ( code == TYPE_CODE_STRUCT || code == TYPE_CODE_UNION )
    {
    //INIT_CPLUS_SPECIFIC (type);
    }
    return ( ptype );
}

/* Helper function.  Create an empty composite type.  */

struct type *
    init_composite_type ( char * name, enum type_code code )
{
    struct type * t;
    t = init_type ( code, 0,  NULL, NULL );
    t->pmain_type->tag_name = name;
    return t;
}

/* Create a fundamental C type using default reasonable for the current
   target machine.

   Some object/debugging file formats (DWARF version 1, COFF, etc) do not
   define fundamental types such as "int" or "double".  Others (stabs or
   DWARF version 2, etc) do define fundamental types.  For the formats which
   don't provide fundamental types, gdb can create such types using this
   function.

   FIXME:  Some compilers distinguish explicitly signed integral types
   (signed short, signed int, signed long) from "regular" integral types
   (short, int, long) in the debugging information.  There is some dis-
   agreement as to how useful this feature is.  In particular, gcc does
   not support this.  Also, only some debugging formats allow the
   distinction to be passed on to a debugger.  For now, we always just
   use "short", "int", or "long" as the type name, for both the implicit
   and explicitly signed types.  This also makes life easier for the
   gdb test suite since we don't have to account for the differences
   in output depending upon what the compiler and debugging format
   support.  We will probably have to re-examine the issue when gdb
   starts taking it's fundamental type information directly from the
   debugging information supplied by the compiler.  fnf@cygnus.com */

struct type * c_create_fundamental_type ( int typeid )
{
    register struct type * type = NULL;

    switch ( typeid )
    {
    default:
        /* FIXME:  For now, if we are asked to produce a type not in this
         language, create the equivalent of a C integer type with the
         name "<?type?>".  When all the dust settles from the type
         reconstruction work, this should probably become an error. */
        type = init_type ( TYPE_CODE_INT, 4, 0, "<?type?>" );
        printf ( "internal error: no C/C++ fundamental type %d", typeid );
        break;
    case FT_VOID:
        type = init_type ( TYPE_CODE_VOID,
            4,/* 字节数 */
            0, "void" );
        break;
    case FT_BOOLEAN:
        type = init_type ( TYPE_CODE_BOOL,
            1,
            0, "bool" );
        break;
    case FT_CHAR:
        type = init_type ( TYPE_CODE_INT,
            1,
            TYPE_FLAG_NOSIGN, "char" );
        break;
    case FT_SIGNED_CHAR:
        type = init_type ( TYPE_CODE_INT,
            1,
            0, "signed char" );
        break;
    case FT_UNSIGNED_CHAR:
        type = init_type ( TYPE_CODE_INT,
            1,
            TYPE_FLAG_UNSIGNED, "unsigned char" );
        break;
    case FT_SHORT:
        type = init_type ( TYPE_CODE_INT,
            2,/* 字节数 */
            0, "short" );
        break;
    case FT_SIGNED_SHORT:
        type = init_type ( TYPE_CODE_INT,
            2,/* 字节数 */
            0, "short" );   /* FIXME-fnf */
        break;
    case FT_UNSIGNED_SHORT:
        type = init_type ( TYPE_CODE_INT,
            2,/* 字节数 */
            TYPE_FLAG_UNSIGNED, "unsigned short" );
        break;
    case FT_INTEGER:
        type = init_type ( TYPE_CODE_INT,
            4,/* 字节数 */
            0, "int" );

⌨️ 快捷键说明

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