DW_AT_name
DW_AT_decl_file
DW_AT_decl_line
+
DW_AT_prototyped
DW_AT_inline
+ DW_AT_external
DW_AT_low_pc
DW_AT_high_pc
+ DW_AT_ranges
+ DW_AT_entry_pc
+ DW_AT_segment & DW_AT_address_class
+ DW_AT_return_addr
DW_AT_frame_base
- DW_AT_external
+ DW_AT_static_link
DW_AT_type
+ DW_AT_calling_convention
+ DW_AT_elemental // for FORTRAN only.
+ DW_AT_pure // for FORTRAN only.
+ DW_AT_recursive // for FORTRAN only.
+
----------------------------------------------------------------------*/
LIBGOBLIN_DWARF_TAG_FUNCTION_EXTERN
int
LibGoblin_DWARF_Info_CUHeader *p_cuheader )
{
+ int i_result;
+ int i_cnt;
+ int i_objid = NO_OBJ;
+ int i_objid_parent = NO_OBJ;
+ char *pstr_filepath = NULL;
+ char *pstr_path = NULL;
+ char *pstr_filename;
+ char str_filename[DRD64_MAX_PATH+1];
+ char str_path[DRD64_MAX_PATH+1];
+ DWord dw_lineoffset;
+ QWord qw_low_pc;
+ QWord qw_high_pc;
+ LibGoblin_SrcFile *p_srcfile;
+ LibGoblin_BinaryFile *p_bfile;
+ LibGoblin_ProgramInfo *p_pginfo;
+ LibGoblin_ObjectInfo *pobj_parent;
+ LibGoblin_ObjectInfo *p_obj;
+
+ LibGoblin_DWARF_Ranges t_ranges;
+ LibGoblin_DWARF_DIEValue *pval_name;
+ LibGoblin_DWARF_DIEValue *pval_declfile;
+ LibGoblin_DWARF_DIEValue *pval_declline;
+ LibGoblin_DWARF_DIEValue *pval_prototyped;
+ LibGoblin_DWARF_DIEValue *pval_inline;
+ LibGoblin_DWARF_DIEValue *pval_external;
+ LibGoblin_DWARF_DIEValue *pval_lowpc;
+ LibGoblin_DWARF_DIEValue *pval_highpc;
+ LibGoblin_DWARF_DIEValue *pval_ranges;
+ LibGoblin_DWARF_DIEValue *pval_entry_pc;
+ LibGoblin_DWARF_DIEValue *pval_segment;
+ LibGoblin_DWARF_DIEValue *pval_addr_class;
+ LibGoblin_DWARF_DIEValue *pval_return_addr;
+ LibGoblin_DWARF_DIEValue *pval_frame_base;
+ LibGoblin_DWARF_DIEValue *pval_static_link;
+ LibGoblin_DWARF_DIEValue *pval_type;
+ LibGoblin_DWARF_DIEValue *pval_calling_convention;
+
+
+ assert( NULL != p_binfo );
+
+ pval_name = DWARF_AttrForm_GetDIEValue( p_binfo, DW_AT_name );
+ pval_lowpc = DWARF_AttrForm_GetDIEValue( p_binfo, DW_AT_low_pc );
+ pval_highpc = DWARF_AttrForm_GetDIEValue( p_binfo, DW_AT_high_pc );
+ pval_ranges = DWARF_AttrForm_GetDIEValue( p_binfo, DW_AT_ranges );
+ pval_inline = DWARF_AttrForm_GetDIEValue( p_binfo, DW_AT_inline );
+ pval_declfile = DWARF_AttrForm_GetDIEValue( p_binfo, DW_AT_decl_file );
+ pval_declline = DWARF_AttrForm_GetDIEValue( p_binfo, DW_AT_decl_line );
+ pval_prototyped = DWARF_AttrForm_GetDIEValue( p_binfo, DW_AT_prototyped );
+ pval_external = DWARF_AttrForm_GetDIEValue( p_binfo, DW_AT_external );
+ pval_entry_pc = DWARF_AttrForm_GetDIEValue( p_binfo, DW_AT_entry_pc );
+ pval_segment = DWARF_AttrForm_GetDIEValue( p_binfo, DW_AT_segment );
+ pval_addr_class = DWARF_AttrForm_GetDIEValue( p_binfo, DW_AT_address_class );
+ pval_return_addr = DWARF_AttrForm_GetDIEValue( p_binfo, DW_AT_return_addr );
+ pval_frame_base = DWARF_AttrForm_GetDIEValue( p_binfo, DW_AT_frame_base );
+ pval_static_link = DWARF_AttrForm_GetDIEValue( p_binfo, DW_AT_static_link );
+ pval_type = DWARF_AttrForm_GetDIEValue( p_binfo, DW_AT_type );
+ pval_calling_convention = DWARF_AttrForm_GetDIEValue( p_binfo, DW_AT_calling_convention );
+
+ if( NULL == pval_name )
+ { goto goto_DWARF_Tag_Function_subprogram_post; }
+ //if( NULL != pval_name ) { pstr_filepath = pval_name->value.pstr_value; }
+
+ p_pginfo = ProgInfo_GetProgInfo( p_binfo->i_pginfo );
+ assert( NULL != p_pginfo );
+
+ i_objid_parent = p_ancestry[ i_childlv - 1 ].i_objid;
+ pobj_parent = ObjectInfo_GetObjectInfo( p_pginfo, i_objid_parent );
+
+ // Pattern A ---
+ if(( NULL != pval_lowpc ) && ( NULL != pval_highpc )) {
+ qw_low_pc = (( LIBGOBLIN_DWARF_INFO_TYPE_DWORD == pval_lowpc->b_type )
+ ? (QWord)pval_lowpc->value.dw_value : pval_lowpc->value.qw_value );
+ qw_high_pc = (( LIBGOBLIN_DWARF_INFO_TYPE_DWORD == pval_highpc->b_type )
+ ? (QWord)pval_highpc->value.dw_value : pval_highpc->value.qw_value );
+
+ t_ranges.i_ranges = 1;
+ t_ranges.ptr_low[0].value = (PtrValue)qw_low_pc;
+ t_ranges.ptr_high[0].value = (PtrValue)qw_high_pc;
+ }
+ // Pattern B ---
+ else if(( NULL != pval_ranges ) && ( NULL == pval_lowpc )) {
+ i_result = DWARF_Ranges_Read(
+ &t_ranges, p_binfo, pval_ranges->value.dw_value,
+ (PtrValue)0x00000000, p_cuheader->b_pointersize );
+ }
+ // Pattern C ---
+ else if(( NULL != pval_lowpc ) && ( NULL != pval_ranges )) {
+ qw_low_pc = (( LIBGOBLIN_DWARF_INFO_TYPE_DWORD == pval_lowpc->b_type )
+ ? (QWord)pval_lowpc->value.dw_value : pval_lowpc->value.qw_value );
+ i_result = DWARF_Ranges_Read(
+ &t_ranges, p_binfo, pval_ranges->value.dw_value,
+ (PtrValue)qw_low_pc, p_cuheader->b_pointersize );
+ }
+ // Pattern D ---
+ else {
+ if( NULL == pval_inline )
+ { goto goto_DWARF_Tag_Function_subprogram_post; }
+
+ t_ranges.i_ranges = 1;
+ t_ranges.ptr_low[0].value = (PtrValue)pobj_parent->addr.ptr_addr.value;
+ t_ranges.ptr_high[0].value = (PtrValue)pobj_parent->addr.ptr_addr.value;
+ }
+
+
+/*
+ p_bfile = BinaryFile_GetBinaryFile( p_binfo->i_binfile );
+ assert( NULL != p_bfile );
+
+ // (Phase1) Data Extract from .debug_info ===============================
+
+ // Data Extract (location)--- [MUST]
+ pval_lowpc = DWARF_AttrForm_GetDIEValue( p_binfo, DW_AT_low_pc );
+ pval_highpc = DWARF_AttrForm_GetDIEValue( p_binfo, DW_AT_high_pc );
+ pval_ranges = DWARF_AttrForm_GetDIEValue( p_binfo, DW_AT_ranges );
+
+
+ // Data Extract (stmt_list)---
+ pval_linestmt = DWARF_AttrForm_GetDIEValue( p_binfo, DW_AT_stmt_list );
+ if( NULL == pval_linestmt )
+ { goto goto_DWARF_Tag_CompileUnit_compile_unit_post; }
+
+
+ // (Phase2) Regist SrcFile from .dwarf_line ===================================
+ SrcFile_ClearSrcFileTable_inBinaryInfo( p_binfo );
+
+ p_srcfile = SrcFile_DispenseSrcFile( p_bfile, pstr_filename, pstr_path);
+ if( NULL == p_srcfile ) {
+ goto goto_DWARF_Tag_CompileUnit_compile_unit_post;
+ }
+
+ i_result = SrcFile_RegistSrcFileTable_inBinaryInfo( p_binfo, p_srcfile );
+ if( 0x00 != i_result ) {
+ goto goto_DWARF_Tag_CompileUnit_compile_unit_post;
+ }
+
+ dw_lineoffset = pval_linestmt->value.dw_value;
+ i_result = DWARF_Line_ReadSrcFile( p_binfo, dw_lineoffset );
+ if( 0x00 != i_result ) {
+ goto goto_DWARF_Tag_CompileUnit_compile_unit_post;
+ }
+
+
+ // (Phase3) Regist ObjInfo as ObjFile =========================================
+
+ for( i_cnt = 0; i_cnt < t_ranges.i_ranges; i_cnt++ ) {
+ p_obj = ObjectInfo_InsetObject(
+ p_pginfo, t_ranges.ptr_low[i_cnt].value,
+ (QWord)(t_ranges.ptr_high[i_cnt].value - t_ranges.ptr_low[i_cnt].value),
+ NULL, OBJINFO_INSETMODE_INSET | OBJINFO_INSETMODE_ADOPT,
+ OBJINFO_TYPE_OBJFILE );
+
+ p_obj->pstr_name = pval_name->value.pstr_value;
+ p_obj->dw_hash = Common_CalcDJBhash( pval_name->value.pstr_value );
+
+ if( 0 == i_cnt ) {
+ p_obj_parent = p_obj;
+ p_obj->info.objfile.i_objid_parent = NO_OBJ;
+ }
+ else {
+ p_obj->info.objfile.i_objid_parent = p_obj_parent->i_id;
+ }
+ p_obj->i_srcid = p_srcfile->i_id;
+ }
+ i_objid = p_obj_parent->i_id;
+goto_DWARF_Tag_CompileUnit_compile_unit_post:
+*/
+goto_DWARF_Tag_Function_subprogram_post:
printf( " UnImplement DW_TAG_subprogram: %s [%02xh]\n",
Debug_DWARF_GetTAGname( dw_tag ), dw_tag );
return NO_OBJ;