char *DIGENTRY DIPImpModSrcLang( imp_image_handle *ii, imp_mod_handle im ) { char *ret = NULL; if( im == IMH_NOMOD ) { DCStatus( DS_FAIL ); return( NULL ); } switch( IMH2MODI( ii, im )->lang ) { case DR_LANG_UNKNOWN: // ret = "unknown"; ret = "c"; break; case DR_LANG_CPLUSPLUS: ret = "cpp"; break; case DR_LANG_FORTRAN: ret = "fortran"; break; case DR_LANG_C: ret = "c"; break; } return( ret ); }
static bool ArraySubRange( dr_handle tsub, int index, void *_df ) /****************************************************************/ { array_wlk_wlk *df = _df; dr_subinfo info; int_32 low; int_32 high; int_32 count; index = index; DRGetSubrangeInfo( tsub, &info ); /* DWARF 2.0 specifies lower bound defaults for C/C++ (0) and FORTRAN (1) */ if( info.low.val_class == DR_VAL_NOT ) { if( IMH2MODI( df->ii, df->it->im )->lang == DR_LANG_FORTRAN ) low = 1; else low = 0; } else { GetDrVal( df, &info.low, &low ); } if( info.count.val_class == DR_VAL_NOT ) { if( info.high.val_class == DR_VAL_NOT ) { return( FALSE ); } GetDrVal( df, &info.high, &high ); count = high - low +1; } else { GetDrVal( df, &info.count, &count ); } df->low = low; df->count *= count; df->dim++; return( df->cont ); }
void SetModPubNames( imp_image_handle *ii, drmem_hdl mod_handle ) /****************************************************************/ { imp_mod_handle im; im = Dwarf2Mod( ii, mod_handle ); if( im != IMH_NOMOD ) { IMH2MODI( ii, im )->has_pubnames = true; } }
size_t DIGENTRY DIPImpModName( imp_image_handle *ii, imp_mod_handle im, char *buff, size_t buff_size ) { char *name; size_t len; if( im == IMH_NOMOD || (name = IMH2MODI( ii, im )->name) == NULL ) { DCStatus( DS_FAIL ); return( 0 ); } len = NameCopy( buff, name, buff_size, 0 ); return( len ); }
static bool GetStrLen( imp_image_handle *ii, dr_handle dr_sym, location_context *lc, dr_typeinfo *ret ) { // Find value of scalar uint_32 seg; location_list src; location_list dst; imp_mod_handle im; union { long l; short s; char c; } val; unsigned idx_size; mod_info *modinfo; im = DwarfMod( ii, dr_sym ); if( im == IMH_NOMOD ) { return( FALSE ); } modinfo = IMH2MODI( ii, im ); if( modinfo->is_segment == FALSE ) { seg = SEG_DATA; // if flat hoke segment } else { EvalSeg( ii, dr_sym, &seg ); } if( EvalLocation( ii, lc, dr_sym, seg, &src ) != DS_OK ) { return( FALSE ); } idx_size = ret->size; if( idx_size == 0 ) { idx_size = modinfo->addr_size; } LocationCreate( &dst, LT_INTERNAL, &val ); if( DCAssignLocation( &dst, &src, idx_size ) != DS_OK ) { return( FALSE ); } switch( idx_size ) { case 1: ret->size = val.c; break; case 2: ret->size = val.s; break; case 4: ret->size = val.l; break; } return( TRUE ); }
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; drmem_hdl stmts; mod_info *modinfo; ret = DS_FAIL; if( im == IMH_NOMOD ) { DCStatus( ret ); return( ret ); } modinfo = IMH2MODI( ii, im ); switch( hk ) { case HK_IMAGE: break; case HK_TYPE: if( modinfo->stmts != DRMEM_HDL_NULL ) { ret = DS_OK; } break; case HK_CUE: stmts = modinfo->stmts; if( stmts != DRMEM_HDL_NULL ) { // 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 ); }
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 ); }
address DIGENTRY DIPImpModAddr( imp_image_handle *ii, imp_mod_handle im ) { l_walk_info walk; address a; drmem_hdl stmts; if( im != IMH_NOMOD && (stmts = IMH2MODI( ii, im )->stmts) != DRMEM_HDL_NULL ) { 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 GetSymVal( imp_image_handle *ii, dr_handle dr_sym, location_context *lc, int_32 *ret ) { // Find value of scalar dr_handle dr_type; dr_typeinfo typeinfo[1]; imp_mod_handle im; uint_32 seg; location_list src; location_list dst; dr_type = DRGetTypeAT( dr_sym ); if( dr_type == DR_HANDLE_NUL ) { return( FALSE ); } DRGetTypeInfo( dr_type, typeinfo ); if( typeinfo->size > sizeof( *ret ) ) { return( FALSE ); } im = DwarfMod( ii, dr_sym ); if( im == IMH_NOMOD ) { return( FALSE ); } if( IMH2MODI( ii, im )->is_segment == FALSE ) { seg = SEG_DATA; // if flat hoke segment } else { EvalSeg( ii, dr_sym, &seg ); } if( EvalLocation( ii, lc, dr_sym, seg, &src ) != DS_OK ) { return( FALSE ); } LocationCreate( &dst, LT_INTERNAL, ret ); if( DCAssignLocation( &dst, &src, typeinfo->size ) != DS_OK ) { return( FALSE ); } return( TRUE ); }
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 ); } } }
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 ); }
/* 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 DIPIMPENTRY( CueAdjust )( imp_image_handle *ii, imp_cue_handle *src, int adj, imp_cue_handle *dst ) /*****************************************************************/ { drmem_hdl stmts; dfline_search start_state; dfline_find find; dip_status ret; cue_item cue; cue_list *cue_map; address map_addr; DRSetDebug( ii->dwarf->handle ); /* must do at each call into DWARF */ stmts = IMH2MODI( ii, src->im )->stmts; if( stmts == DRMEM_HDL_NULL ) { DCStatus( DS_FAIL ); return( DS_ERR|DS_FAIL ); } cue_map = ii->cue_map; if( cue_map->im != src->im ) { ResetCueInfo( cue_map ); cue_map->im = src->im; 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; cue.mach = src->a.mach; find = LINE_NOT; while( 0 != adj ) { find = FindCue( cue_map, &cue, start_state ); if( find == LINE_NOT ) break; --adj; } dst->im = src->im; dst->fno = cue.fno; dst->line = cue.line; dst->col = cue.col; dst->a.mach = cue.mach; ret = DS_FAIL; 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 ); }
dip_status DIGENTRY DIPImpModDefault( imp_image_handle *ii, imp_mod_handle im, default_kind dk, dip_type_info *ti ) { /* Return the default type information for indicated type. The client uses this to figure out how big a default 'int', code pointer, and data pointer should be. The information depends on whether the 16 or 32-bit compiler was used, and what memory model the source file was compiled with. */ mod_info *modinfo; //TODO: finish modinfo = IMH2MODI( ii, im ); ti->size = modinfo->addr_size; switch( dk ) { case DK_INT: ti->kind = TK_INTEGER; ti->modifier = TM_SIGNED; break; case DK_DATA_PTR: case DK_CODE_PTR: ti->kind = TK_POINTER; switch( modinfo->model ) { case DR_MODEL_NONE: case DR_MODEL_FLAT: case DR_MODEL_SMALL: ti->modifier = TM_NEAR; break; case DR_MODEL_MEDIUM: if( dk == DK_CODE_PTR ) { ti->modifier = TM_FAR; ti->size += 2; } else { ti->modifier = TM_NEAR; } break; case DR_MODEL_COMPACT: if( dk == DK_CODE_PTR ) { ti->modifier = TM_NEAR; } else { ti->modifier = TM_FAR; ti->size += 2; } break; case DR_MODEL_LARGE: ti->modifier = TM_FAR; ti->size += 2; break; case DR_MODEL_HUGE: if( dk == DK_CODE_PTR ) { ti->modifier = TM_FAR; } else { ti->modifier = TM_HUGE; } ti->size += 2; break; } } return( DS_OK ); }