dip_status DIGENTRY DIPImpTypeBase( imp_image_handle *ii, imp_type_handle *it, imp_type_handle *base, location_context *lc, location_list *ll ) { dr_handle btype; lc = lc; ll = ll; /* Given an implementation type handle, fill in 'base' with the base type of the handle. */ if( base != it ) { *base = *it; } DRSetDebug( ii->dwarf->handle ); /* must do at each call into dwarf */ if( base->state == DF_SET && base->sub_array ) { base->array.index = GetArrayDim( base->array.index, 1 ); if( base->array.is_based ) { base->array.is_set = FALSE; } base->array.is_based = TRUE; if( base->array.index != DR_HANDLE_NUL ) { return( DS_OK ); } } btype = DRSkipTypeChain( base->type ); /* skip modifiers and typedefs */ base->type = DRGetTypeAT( btype ); /* get base type */ if( base->type == DR_HANDLE_NUL ) { base->type = DR_HANDLE_VOID; /* no type means 'void' */ } base->state = DF_NOT; return( DS_OK ); }
dip_status DIGENTRY DIPImpTypeProcInfo( imp_image_handle *ii, imp_type_handle *proc, imp_type_handle *parm, unsigned n ) { dr_handle btype; dr_handle parm_type = DR_HANDLE_NUL; dip_status ret; DRSetDebug( ii->dwarf->handle ); /* must do at each call into dwarf */ btype = DRSkipTypeChain( proc->type ); /* skip modifiers and typedefs */ if( n > 0 ) { btype = GetParmN( ii, btype, n ); }// if n == 0 just fall through and get type of function if( btype != DR_HANDLE_NUL ) { parm_type = DRGetTypeAT( btype ); /* get type */ } if( parm_type != DR_HANDLE_NUL ) { parm->state = DF_NOT; parm->type = parm_type; parm->im = proc->im; ret = DS_OK; } else { ret = DS_FAIL; } return( ret ); }
static bool ACueFileNum( void *_fc, dr_line_file *curr ) /******************************************************/ { file_walk_cue *fc = _fc; bool cont; imp_cue_handle *ic; dr_dbg_handle saved; ic = fc->ic; ic->a = NilAddr; ic->im = fc->im; if( FirstCue( fc->stmts, curr->index, ic ) ) { ic->fno = curr->index; ic->line = 1; ic->col = 0; } saved = DRGetDebug(); fc->wr = fc->wk( fc->ii, ic, fc->d ); DRSetDebug( saved ); if( fc->wr == WR_CONTINUE ) { cont = true; } else { cont = false; } return( cont ); }
void Module::setModule() //---------------------- // tell the dwarf library that we are reading out of this module { REQUIRE( _dataFile->isInitialized(), "Module::setModule - not initialized" ); DRSetDebug( _dbgInfo ); }
dip_status InitModMap( imp_image_handle *ii ) /***********************************************/ // Make the imp_mod_handle to dr_handle map { mod_list list; dip_status ret; ret = DS_OK; ii->mod_count = 0; InitModList( &list ); InitAddrSym( ii->addr_sym ); DRSetDebug( ii->dwarf->handle ); /* set dwarf to image */ DRIterateCompileUnits( &list, ModFill ); DRDbgClear( ii->dwarf->handle ); /* clear some mem */ ii->mod_count = list.count; ii->mod_map = FiniModInfo( &list ); if( list.version == VER_V1 ) { DRDbgOldVersion( ii->dwarf->handle, 1 ); } else if( list.version == VER_V2 ) { DRDbgOldVersion( ii->dwarf->handle, 2 ); } else if( list.version == VER_ERROR ) { DCStatus( DS_INFO_BAD_VERSION ); ret = DS_FAIL | DS_INFO_BAD_VERSION; } return( ret ); }
/* Adjust the 'src' cue by 'adj' amount and return the result in 'dst'. That is, If you get called with "DIPImpCueAdjust( ii, src, 1, dst )", the 'dst' handle should be filled in with implementation cue handle representing the source cue immediately following the 'src' cue. Passing in an 'adj' of -1 will get the immediately preceeding source cue. The list of source cues for each file are considered a ring, so if 'src' is the first cue in a file, an 'adj' of -1 will return the last source cue FOR THAT FILE. The cue adjust never crosses a file boundry. Also, if 'src' is the last cue in a file, and 'adj' of 1 will get the first source cue FOR THAT FILE. If an adjustment causes a wrap from begining to end or vice versa, you should return DS_WRAPPED status (NOTE: DS_ERR should *not* be or'd in, nor should DCStatus be called in this case). Otherwise DS_OK should be returned unless an error occurred. */ dip_status DIPENTRY DIPImpCueAdjust( imp_image_handle *ii, imp_cue_handle *src, int adj, imp_cue_handle *dst ) /*****************************************************************/ { dr_handle stmts; dfline_search start_state; dfline_find find; dip_status ret; imp_mod_handle imx; cue_item cue; cue_list *cue_map; address map_addr; imx = src->imx; DRSetDebug( ii->dwarf->handle ); /* must do at each call into DWARF */ stmts = ii->mod_map[imx].stmts; if( stmts == 0 ) { DCStatus( DS_FAIL ); return( DS_ERR|DS_FAIL ); } cue_map= ii->cue_map; if( cue_map->imx != imx ) { ResetCueInfo( cue_map ); cue_map->imx = imx; map_addr = NilAddr; LoadCueMap( stmts, &map_addr, cue_map ); } if( adj < 0 ) { start_state = LOOK_LOW; adj = -adj; } else { start_state = LOOK_HIGH; } cue.fno = src->fno; cue.line = src->line; cue.col = src->col; while( 0 != adj ) { find = FindCue( cue_map, &cue, start_state ); if( find == LINE_NOT ) break; --adj; } dst->imx = imx; dst->fno = cue.fno; dst->line = cue.line; dst->col = cue.col; dst->a.mach = cue.mach; switch( find ) { case LINE_NOT: DCStatus( DS_FAIL ); ret = DS_ERR | DS_FAIL; break; case LINE_WRAPPED: ret = DS_WRAPPED; break; case LINE_FOUND: ret = DS_OK; break; } return( ret ); }
walk_result DIPENTRY DIPImpWalkFileList( imp_image_handle *ii, imp_mod_handle im, IMP_CUE_WKR *wk, imp_cue_handle *ic, void *d ) /*************************************************************************/ { file_walk_cue wlk; im_idx imx; dr_handle stmts; imx = IM2IMX( im ); DRSetDebug( ii->dwarf->handle ); /* must do at each call into DWARF */ stmts = ii->mod_map[imx].stmts; if( stmts == 0 ) { DCStatus( DS_FAIL ); return( WR_CONTINUE ); } wlk.stmts = stmts; wlk.ii = ii; wlk.imx = imx; wlk.wk = wk; wlk.ic = ic; wlk.d = d; wlk.wr = WR_CONTINUE; DRWalkLFiles( stmts, ACueFileNum, &wlk, ACueDir, NULL ); return( wlk.wr ); }
static int ACueFileNum( void *_fc, dr_line_file *curr ) /*****************************************************/ { file_walk_cue *fc = _fc; int cont; imp_cue_handle *ic; dr_dbg_handle saved; ic = fc->ic; DCFree( curr->name ); ic->a = NilAddr; ic->imx = fc->imx; if( FirstCue( fc->stmts, curr->index, ic ) ) { ic->fno = curr->index; ic->line = 1; ic->col = 0; } saved = DRGetDebug(); fc->wr = fc->wk( fc->ii, ic, fc->d ); DRSetDebug( saved ); if( fc->wr == WR_CONTINUE ) { cont = TRUE; } else { cont = FALSE; } return( cont ); }
static bool AInherit( dr_handle inh, int index, void *_d ) /********************************************************/ { //TODO: Need to track virtual base as not to visit same place twice type_wlk_wlk *d = _d; bool cont; dr_handle btype; dr_handle old_inh; imp_sym_handle *is; dr_dbg_handle saved; walk_result wr; index = index; cont = TRUE; btype = DRGetTypeAT( inh ); btype = DRSkipTypeChain( btype ); /* skip modifiers and typedefs */ if( DRGetVirtuality( inh ) == DR_VIRTUALITY_VIRTUAL ) { if( !AddBase( btype, &d->com.vbase ) ) { return( cont ); } } is = d->is; SetSymHandle( (type_wlk *)d, is ); is->sym = inh; is->sclass = SYM_MEM; // treat inherit like a var saved = DRGetDebug(); wr = d->wk( d->com.ii, SWI_INHERIT_START, is, d->com.d ); DRSetDebug( saved ); if( wr == WR_CONTINUE ) { old_inh = d->com.inh; d->com.inh = inh; DRWalkStruct( btype, StrucWlk, d ); d->com.inh = old_inh; saved = DRGetDebug(); d->wk( d->com.ii, SWI_INHERIT_END, NULL, d->com.d ); DRSetDebug( saved ); if( d->wr != WR_CONTINUE ) { cont = FALSE; } } return( cont ); }
search_result SearchMbr( imp_image_handle *ii, imp_type_handle *it, lookup_item *li, void *d ) //Search for matching lookup item { dr_handle btype; type_wlk_lookup df; df_cleaner cleanup; DRSetDebug( ii->dwarf->handle ); /* must do at each call into dwarf */ if( it->state == DF_NOT ) { if( DRGetTypeInfo( it->type, &it->typeinfo ) ) { it->state = DF_SET; } } if( it->state == DF_NOT ) { return( SR_NONE ); } df.com.im = it->im; df.com.ii = ii; df.com.d = d; df.com.root = it->type; df.com.inh = DR_HANDLE_NUL; df.com.vbase = NULL; cleanup.rtn = FreeBases; //push cleanup cleanup.d = &df.com.vbase; cleanup.prev = Cleaners; Cleaners = &cleanup; btype = DRSkipTypeChain( it->type ); if( li->case_sensitive ) { df.comp = memcmp; } else { df.comp = memicmp; } df.li = li; df.sr = SR_NONE; switch( it->typeinfo.kind ) { case DR_TYPEK_ENUM: df.com.sclass = SYM_ENUM; df.com.einfo.size = it->typeinfo.size; df.com.einfo.sign = it->typeinfo.modifier.sign; DRWalkEnum( btype, AEnumMemLookup, &df ); break; case DR_TYPEK_STRUCT: case DR_TYPEK_UNION: case DR_TYPEK_CLASS: df.com.sclass = SYM_MEM; DRWalkStruct( btype, StrucWlkLookup, &df ); break; default: DCStatus( DS_ERR | DS_BAD_PARM ); df.sr = SR_FAIL; } FreeBases( &df.com.vbase ); // free virtual base list Cleaners = cleanup.prev; // pop cleanup return( df.sr ); }
extern int GetParmCount( imp_image_handle *ii, dr_handle proc ) { /******************************************************/ // return handle of the n parm parm_wlk df; df.count = 0; df.last = 0; DRSetDebug( ii->dwarf->handle ); /* must do at each call into dwarf */ DRWalkBlock( proc, DR_SRCH_parm, AParm, (void *)&df ); return( df.count ); }
extern walk_result WalkTypeSymList( imp_image_handle *ii, imp_type_handle *it, IMP_SYM_WKR *wk, imp_sym_handle *is, void *d ) { dr_handle btype; type_wlk_wlk df; df_cleaner cleanup; DRSetDebug( ii->dwarf->handle ); /* must do at each call into dwarf */ if( it->state == DF_NOT ) { if( DRGetTypeInfo( it->type, &it->typeinfo ) ) { it->state = DF_SET; } } if( it->state == DF_NOT ) { return( WR_STOP ); } df.com.im = it->im; df.com.ii = ii; df.com.d = d; df.com.root = it->type; df.com.inh = DR_HANDLE_NUL; df.com.vbase = NULL; cleanup.rtn = FreeBases; //push cleanup cleanup.d = &df.com.vbase; cleanup.prev = Cleaners; Cleaners = &cleanup; btype = DRSkipTypeChain( it->type ); df.is = is; df.wk = wk; df.wr = WR_CONTINUE; switch( it->typeinfo.kind ) { case DR_TYPEK_ENUM: df.com.sclass = SYM_ENUM; df.com.einfo.size = it->typeinfo.size; df.com.einfo.sign = it->typeinfo.modifier.sign; DRWalkEnum( btype, AEnumMem, &df ); break; case DR_TYPEK_STRUCT: case DR_TYPEK_UNION: case DR_TYPEK_CLASS: df.com.sclass = SYM_MEM; DRWalkStruct( btype, StrucWlk, &df ); break; default: DCStatus( DS_ERR | DS_BAD_PARM ); df.wr = WR_STOP; } FreeBases( &df.com.vbase ); // free virtual base list Cleaners = cleanup.prev; // pop cleanup return( df.wr ); }
dip_status DIGENTRY DIPImpModInfo( imp_image_handle *ii, imp_mod_handle im, handle_kind hk ) { /* Return DS_OK if the module has the kind of information indicated by 'hk', DS_FAIL if it does not. */ dip_status ret; dr_handle stmts; mod_info *modinfo; ret = DS_FAIL; if( im == IMH_NOMOD ) { DCStatus( ret ); return( ret ); } modinfo = IM2MODI( ii, im ); switch( hk ) { case HK_IMAGE: break; case HK_TYPE: if( modinfo->stmts != 0 ) { ret = DS_OK; } break; case HK_CUE: stmts = modinfo->stmts; if( stmts != 0 ) { // need to get rid of stmts for file with no cues l_walk_info walk; address a; walk.ii = ii; walk.im = im; walk.ret = &a; DRSetDebug( ii->dwarf->handle ); /* set dwarf to image */ if( !DRWalkLines( stmts, SEG_CODE, ALineCue, &walk ) ) { ret = DS_OK; } } break; case HK_SYM: /* if no lang assumed linker generated */ if( modinfo->lang != DR_LANG_UNKNOWN ) { ret = DS_OK; } break; default: break; } return( ret ); }
size_t DIPIMPENTRY( CueFile )( imp_image_handle *ii, imp_cue_handle *ic, char *buff, size_t buff_size ) /************************************************************************/ { char *name; file_walk_name wlk; size_t len; drmem_hdl stmts; drmem_hdl cu_tag; int i; mod_info *modinfo; DRSetDebug( ii->dwarf->handle ); /* must do at each call into dwarf */ modinfo = IMH2MODI( ii, ic->im ); stmts = modinfo->stmts; cu_tag = modinfo->cu_tag; if( stmts == DRMEM_HDL_NULL || cu_tag == DRMEM_HDL_NULL ) { DCStatus( DS_FAIL ); return( 0 ); } wlk.index = ic->fno; wlk.ret = NULL; wlk.num_dirs = 0; wlk.dirs = NULL; DRWalkLFiles( stmts, ACueFile, &wlk, ACueDir, &wlk ); name = wlk.ret; // Free directory and file table information for( i = 0; i < wlk.num_dirs; i++ ) { DCFree( wlk.dirs[i].name ); } DCFree( wlk.dirs ); if( name == NULL ) { DCStatus( DS_FAIL ); return( 0 ); } // If compilation unit has a DW_AT_comp_dir attribute, we need to // stuff that in front of the file pathname, unless that is absolute len = DRGetCompDirBuff( cu_tag, buff, buff_size ); if( ( len > 1 ) && IsRelPathname( name ) ) { // Ignore empty comp dirs len = NameCopy( buff, "/", buff_size, len ); } else { len = 0; } len = NameCopy( buff, name, buff_size, len ); DCFree( name ); return( len ); }
Module::Module( const char *name, WCValSList<String> & enabled, WCValSList<String> & disabled ) //------------------------------------------------------------ { WCPtrOrderedVector<ComponentFile> components; FileInfo finf( name ); int i; MsgRetType ret; _dataFile = new ElfFile( name, false ); DwarfFileMerger merger( name, enabled, disabled ); if( !merger.upToDate() ) { if( !finf.exists() ) { merger.doMerge(); } else { if( enabled.entries() != 0 ) { ret = WMessageDialog::messagef( topWindow, MsgQuestion, MsgYesNo, "Source Browser", "Database %s is not consistent with module files.\n" "Merge the database now?", name ); if( ret == MsgRetYes ) { merger.doMerge(); } } } } _dataFile->initSections(); _dataFile->getEnabledComponents( &components ); for( i = 0; i < components.entries(); i += 1 ) { _enabledFiles.add( new WFileName( components[i]->name ) ); } components.clear(); _dataFile->getDisabledComponents( &components ); for( i = 0; i < components.entries(); i += 1 ) { _disabledFiles.add( new WFileName( components[i]->name ) ); } checkSourceTime(); _dbgInfo = DRDbgInit( this, _dataFile->getDRSizes(), false ); DRSetDebug( _dbgInfo ); }
extern dr_handle GetParmN( imp_image_handle *ii,dr_handle proc, int count ) { /******************************************************/ // return handle of the n parm parm_wlk df; dr_handle ret; df.count = 0; df.last = count; DRSetDebug( ii->dwarf->handle ); /* must do at each call into dwarf */ if( DRWalkBlock( proc, DR_SRCH_parm, AParm, (void *)&df ) ) { ret = DR_HANDLE_NUL; } else { ret = df.var; } return( ret ); }
drmem_hdl GetParmN( imp_image_handle *ii, drmem_hdl proc, int count ) /******************************************************/ // return handle of the n parm { parm_wlk df; drmem_hdl ret; df.count = 0; df.last = count; DRSetDebug( ii->dwarf->handle ); /* must do at each call into dwarf */ if( DRWalkBlock( proc, DR_SRCH_parm, AParm, (void *)&df ) ) { ret = DRMEM_HDL_NULL; }else{ ret = df.var; } return( ret ); }
walk_result DIGENTRY DIPImpWalkModList( imp_image_handle *ii, IMP_MOD_WKR *wk, void *d ) { im_idx i; walk_result ret; dr_dbg_handle saved; ret = WR_CONTINUE; for( i = 0; i < ii->mod_count; ++i ) { saved = DRGetDebug(); ret = wk( ii, IMX2IM( i ), d ); DRSetDebug( saved ); if( ret != WR_CONTINUE ) { break; } } return( ret ); }
walk_result DIGENTRY DIPImpWalkTypeList( imp_image_handle *ii, imp_mod_handle im, IMP_TYPE_WKR *wk, imp_type_handle *it, void *d ) { dr_handle cu_tag; struct mod_type typ_wlk; DRSetDebug( ii->dwarf->handle ); /* must do at each interface */ cu_tag = IMH2MODI( ii, im )->cu_tag; typ_wlk.ii = ii; typ_wlk.im = im; typ_wlk.wk = wk; typ_wlk.it = it; typ_wlk.d = d; DRWalkModTypes( cu_tag, AType, &typ_wlk ); return( typ_wlk.wr ); }
dip_status DIGENTRY DIPImpTypeArrayInfo( imp_image_handle *ii, imp_type_handle *array, location_context *lc, array_info *ai, imp_type_handle *index ) { /* Given an implemenation type handle that represents an array type, get information about the array shape and index type. The location context is for variable dimensioned arrays again. The 'index' parameter is filled in with the type of variable used to subscript the array. It may be NULL, in which case no information is returned. */ DRSetDebug( ii->dwarf->handle ); /* must do at each call into dwarf */ if( array->state == DF_NOT ) { InitTypeHandle( ii, array, lc ); } if( array->state == DF_NOT ) { DCStatus( DS_ERR | DS_BAD_PARM ); return( DS_ERR | DS_BAD_PARM ); } if( array->typeinfo.kind != DR_TYPEK_ARRAY ) { DCStatus( DS_ERR | DS_BAD_PARM ); return( DS_ERR | DS_BAD_PARM ); } ai->low_bound = array->array.low; ai->num_elts = array->array.num_elts; ai->num_dims = array->array.dims; ai->column_major = array->array.column_major; ai->stride = array->array.base_stride; if( index != NULL ) { index->im = array->im; if( array->array.index == DR_HANDLE_NUL ) { //Fake a type up index->state = DF_SET; index->type = DR_HANDLE_NUL; index->typeinfo.size = 0; index->typeinfo.kind = DR_TYPEK_NONE; index->typeinfo.mclass = DR_MOD_NONE; } else { index->state = DF_NOT; index->type = array->array.index; } } return( DS_OK ); }
address DIGENTRY DIPImpModAddr( imp_image_handle *ii, imp_mod_handle im ) { l_walk_info walk; address a; dr_handle stmts; if( im != IMH_NOMOD && (stmts = IM2MODI( ii, im )->stmts) != 0 ) { DRSetDebug( ii->dwarf->handle ); /* must do at each call into dwarf */ walk.ii = ii; walk.im = im; walk.ret = &a; if( !DRWalkLines( stmts, SEG_CODE, AModAddr, &walk ) ) { // found return( a ); } } DCStatus( DS_FAIL ); return( NilAddr ); }
static bool AEnumMem( dr_handle var, int index, void *_d ) /********************************************************/ { type_wlk_wlk *d = _d; bool cont; imp_sym_handle *is; dr_dbg_handle saved; index = index; cont = TRUE; is = d->is; SetSymHandle( (type_wlk *)d, is ); is->sym = var; saved = DRGetDebug(); d->wr = d->wk( d->com.ii, SWI_SYMBOL, is, d->com.d ); DRSetDebug( saved ); if( d->wr != WR_CONTINUE ) { cont = FALSE; } return( cont ); }
static bool AType( dr_handle type, void *_typ_wlk, dr_search_context *cont ) /**************************************************************************/ { struct mod_type *typ_wlk = _typ_wlk; bool ret; imp_type_handle *it; dr_dbg_handle saved; cont = cont; ret = TRUE; it = typ_wlk->it; it->im = typ_wlk->im; it->state = DF_NOT; it->type = type; saved = DRGetDebug(); typ_wlk->wr = typ_wlk->wk( typ_wlk->ii, it, typ_wlk->d ); DRSetDebug( saved ); if( typ_wlk->wr != WR_CONTINUE ) { ret = FALSE; } return( ret ); }
walk_result DFWalkModListSrc( imp_image_handle *ii, bool src, IMP_MOD_WKR wk, void *d ) { im_idx i; walk_result ret; dr_dbg_handle saved; mod_info *modinfo; ret = WR_CONTINUE; modinfo = ii->mod_map; for( i = 0; i < ii->mod_count; ++i ) { if( src == modinfo->has_pubnames ) { saved = DRGetDebug(); ret = wk( ii, IMX2IM( i ), d ); DRSetDebug( saved ); if( ret != WR_CONTINUE ) { break; } } ++modinfo; } return( ret ); }
static bool AMem( dr_handle var, int index, void *_d ) /****************************************************/ { type_wlk_wlk *d = _d; bool cont; imp_sym_handle *is; dr_dbg_handle saved; cont = TRUE; is = d->is; SetSymHandle( (type_wlk *)d, is ); is->sym = var; switch( index ) { case 0: is->sclass = SYM_MEM; break; case 2: is->sclass = SYM_MEMVAR; // static member break; case 3: if( DRGetVirtuality( var ) == DR_VIRTUALITY_VIRTUAL ) { is->sclass = SYM_VIRTF; // virtual func } else if( !DRIsSymDefined( var ) ) { is->sclass = SYM_MEMF; // memfunc decl } else { is->sclass = SYM_MEMVAR; // inlined defn treat like a var } break; } saved = DRGetDebug(); d->wr = d->wk( d->com.ii, SWI_SYMBOL, is, d->com.d ); DRSetDebug( saved ); if( d->wr != WR_CONTINUE ) { cont = FALSE; } return( cont ); }
walk_result DIPIMPENTRY( WalkFileList )( imp_image_handle *ii, imp_mod_handle im, DIP_IMP_CUE_WALKER *wk, imp_cue_handle *ic, void *d ) /*************************************************************************/ { file_walk_cue wlk; drmem_hdl stmts; DRSetDebug( ii->dwarf->handle ); /* must do at each call into DWARF */ stmts = IMH2MODI( ii, im )->stmts; if( stmts == DRMEM_HDL_NULL ) { DCStatus( DS_FAIL ); return( WR_CONTINUE ); } wlk.stmts = stmts; wlk.ii = ii; wlk.im = im; wlk.wk = wk; wlk.ic = ic; wlk.d = d; wlk.wr = WR_CONTINUE; DRWalkLFiles( stmts, ACueFileNum, &wlk, ACueDir, NULL ); return( wlk.wr ); }
static void InitTypeHandle( imp_image_handle *ii, imp_type_handle *it, location_context *lc ) { /***********************************************************************/ //Set type handle to the base state //If array poise at first index imp_type_handle sub; dr_array_info info; dr_handle btype; dr_array_stat stat; uint_32 base_stride; uint_32 n_el; if( it->state == DF_NOT ) { DRSetDebug( ii->dwarf->handle ); /* must do at each call into dwarf */ DRGetTypeInfo( it->type, &it->typeinfo ); it->state = DF_SET; it->sub_array = FALSE; if( it->typeinfo.kind == DR_TYPEK_ARRAY ) { if( it->typeinfo.size == 0 ) { btype = DRSkipTypeChain( it->type ); /* skip modifiers and typedefs */ stat = DRGetArrayInfo( btype, &info ); if( stat & DR_ARRAY_STRIDE_SIZE ) { base_stride = info.stride_size/8; } else { btype = DRGetTypeAT( btype ); /* get base type */ sub.type = btype; sub.im = it->im; sub.state = DF_NOT; InitTypeHandle( ii, &sub, lc ); base_stride = sub.typeinfo.size; } it->array.base_stride = base_stride; it->array.column_major = 0; /* 1 for fortran */ if( stat & DR_ARRAY_ORDERING ) { if( info.ordering == DW_ORD_col_major ) { it->array.column_major = 1; } } else if( IMH2MODI( ii, it->im )->lang == DR_LANG_FORTRAN ) { it->array.column_major = 1; } if( info.child == DR_HANDLE_NUL ) { // set info now it->array.dims = 1; it->array.low = 0; it->array.index = DR_HANDLE_NUL; if( stat & DR_ARRAY_COUNT ) { if( info.count == 0 ) { // ie char (*x)[] info.count = 1; } it->typeinfo.size = info.count * it->array.base_stride; it->array.num_elts= info.count; } else { it->typeinfo.size = it->array.base_stride; } if( !it->array.column_major ) { base_stride = it->typeinfo.size; n_el = it->array.num_elts; base_stride = n_el ? base_stride / n_el : 0; it->array.base_stride = base_stride; } it->array.is_set = TRUE; it->array.is_based = FALSE; it->sub_array = FALSE; } else { it->sub_array = TRUE; it->array.is_set = FALSE; it->array.index = GetArrayDim( info.child, 0 ); } } } else if( it->typeinfo.kind == DR_TYPEK_STRING ) { if( DRStringLengthAT( it->type ) ) { if( !GetStrLen( ii, it->type, lc, &it->typeinfo ) ) { it->typeinfo.size = 1; } } } } if( it->typeinfo.kind == DR_TYPEK_ARRAY ) { if( !it->array.is_set ) { GetArraySize( ii, it, lc ); } else if( it->array.is_based ) { GetArraySubSize( ii, it, lc ); } } }
unsigned DIGENTRY DIPImpTypeName( imp_image_handle *ii, imp_type_handle *it, unsigned num, symbol_type *tag, char *buff, unsigned buff_size ) { /* Given the imp_type_handle, copy the name of the type into 'buff'. Do not copy more than 'buff_size' - 1 characters into the buffer and append a trailing '\0' character. Return the real length of the type name (not including the trailing '\0' character) even if you had to truncate it to fit it into the buffer. If something went wrong and you can't get the type name, call DCStatus and return zero. NOTE: the client might pass in zero for 'buff_size'. In that case, just return the length of the module name and do not attempt to put anything into the buffer. Since there can be a "string" of typedef names associated with a type_handle, the 'num' parm indicates which one of the names the client wants returned. Zero is the first type name, one is the second, etc. Fill in '*tag' with ST_ENUM_TAG, ST_UNION_TAG, ST_STRUCT_TAG, ST_CLASS_TAG if the name is a enum, union, struct, or class tag name respectively. If not, set '*tag' to ST_NONE. If the type does not have a name, return zero. */ char *name = NULL; dr_handle dr_type; dr_typeinfo typeinfo; unsigned len; DRSetDebug( ii->dwarf->handle ); /* must do at each call into dwarf */ ++num; len = 0; dr_type = it->type; while( dr_type != DR_HANDLE_NUL ) { name = DRGetName( dr_type ); if( name != NULL ) { if( --num == 0 ) break; DCFree( name ); } dr_type = DRGetTypeAT( dr_type ); } if( num == 0 ) { DRGetTypeInfo( dr_type, &typeinfo ); switch( typeinfo.kind ) { case DR_TYPEK_ENUM: *tag = ST_ENUM_TAG; break; case DR_TYPEK_STRUCT: *tag = ST_STRUCT_TAG; break; case DR_TYPEK_UNION: *tag = ST_UNION_TAG; break; case DR_TYPEK_CLASS: *tag = ST_CLASS_TAG; break; default: *tag = ST_NONE; break; } len = NameCopy( buff, name, buff_size, 0 ); DCFree( name ); } return( len ); }
search_result DIPIMPENTRY( LineCue )( imp_image_handle *ii, imp_mod_handle im, cue_fileid file, unsigned long line, unsigned column, imp_cue_handle *ic ) /**********************************************************************/ { search_result ret; dfline_find find; dfline_search what; drmem_hdl stmts; cue_list *cue_map; address map_addr; cue_item cue; if( im == IMH_NOMOD ) { DCStatus( DS_FAIL ); return( SR_NONE ); } DRSetDebug( ii->dwarf->handle ); /* must do at each call into DWARF */ stmts = IMH2MODI( ii, im )->stmts; if( stmts == DRMEM_HDL_NULL ) { return( SR_NONE ); } cue_map= ii->cue_map; if( cue_map->im != im ) { ResetCueInfo( cue_map ); cue_map->im = im; map_addr = NilAddr; LoadCueMap( stmts, &map_addr, cue_map ); } if( file == 0 ) { // primary file cue.fno = 1; } else { cue.fno = (uint_16)file; } cue.line = line; cue.col = (uint_16)column; cue.mach.offset = 0; cue.mach.segment = 0; ic->a = NilAddr; if( line == 0 ) { what = LOOK_FILE; } else { what = LOOK_CLOSEST; } find = FindCue( cue_map, &cue, what ); ic->im = im; ic->fno = cue.fno; ic->line = cue.line; ic->col = cue.col; ic->a.mach = cue.mach; ret = SR_NONE; switch( find ) { case LINE_CLOSEST: ret = SR_CLOSEST; break; case LINE_FOUND: ret = SR_EXACT; break; case LINE_NOT: ret = SR_NONE; break; } return( ret ); }
search_result DIPIMPENTRY( AddrCue )( imp_image_handle *ii, imp_mod_handle im, address addr, imp_cue_handle *ic ) /*******************************************************************/ { /* Search for the closest cue in the given module that has an address * less then or equal to the given address. If there is no such cue * return SR_NONE. If there is one exactly at the address return * SR_EXACT. Otherwise, return SR_CLOSEST. */ address map_addr; search_result ret; cue_list *cue_map; cue_item cue; drmem_hdl stmts; if( im == IMH_NOMOD ) { DCStatus( DS_FAIL ); return( SR_NONE ); } DRSetDebug( ii->dwarf->handle ); /* must do at each call into dwarf */ stmts = IMH2MODI( ii, im )->stmts; if( stmts == DRMEM_HDL_NULL ) { return( SR_NONE ); } map_addr = addr; cue_map = ii->cue_map; Real2Map( ii->addr_map, &map_addr ); if( cue_map->im != im ) { ResetCueInfo( cue_map ); cue_map->im = im; LoadCueMap( stmts, &map_addr, cue_map ); } ic->im = im; ic->fno = 0; ic->line = 0; ic->col = 0; ic->a = NilAddr; ret = SR_NONE; if( map_addr.mach.segment == cue_map->last.mach.segment && map_addr.mach.offset >= cue_map->last.mach.offset && map_addr.mach.offset < cue_map->last.next_offset ) { ic->fno = cue_map->last.fno; ic->line = cue_map->last.line; ic->col = cue_map->last.col; ic->a.mach = cue_map->last.mach; if( cue_map->last.mach.offset == map_addr.mach.offset ) { ret = SR_EXACT; } else { ret = SR_CLOSEST; } return( ret ); } if( FindCueOffset( cue_map, &map_addr.mach, &cue ) ) { ic->fno = cue.fno; ic->line = cue.line; ic->col = cue.col; ic->a.mach = cue.mach; if( cue.mach.offset == map_addr.mach.offset ) { ret = SR_EXACT; } else { ret = SR_CLOSEST; } cue_map->last = cue; } return( ret ); }