/* * doFindSymbol */ BOOL doFindSymbol( ADDRESS *addr, syminfo *si, int getsrcinfo ) { sym_handle *symhdl; cue_handle *cue; search_result sr; location_list ll; address dipaddr; BOOL ret; si->segnum = -1; si->name[0] = 0; if( !StatShowSymbols || curProcess == NULL ) { return( FALSE ); } symhdl = MemAlloc( DIPHandleSize( HK_SYM ) ); dipaddr.sect_id = 0; dipaddr.indirect = FALSE; dipaddr.mach.offset = addr->offset; dipaddr.mach.segment = addr->seg; sr = AddrSym( NO_MOD, dipaddr, symhdl ); switch( sr ) { case SR_CLOSEST: SymLocation( symhdl, NULL, &ll ); si->symoff = addr->offset - ll.e[0].u.addr.mach.offset; break; case SR_EXACT: si->symoff = 0; break; case SR_NONE: ret = FALSE; break; } if( sr != SR_NONE ) { SymName( symhdl, NULL, SN_OBJECT, si->name, MAX_SYM_NAME ); // SymName( symhdl, NULL, SN_SOURCE, si->name, MAX_SYM_NAME ); if( getsrcinfo ) { cue = MemAlloc( DIPHandleSize( HK_CUE ) ); if( AddrCue( NO_MOD, dipaddr, cue ) == SR_NONE ) { MemFree( cue ); ret = FALSE; } else { CueFile( cue, si->filename, MAX_FILE_NAME ); si->linenum = CueLine( cue ); MemFree( cue ); ret = TRUE; } } } MemFree( symhdl ); return( ret ); }
extern wp_srcfile * WPSourceOpen( sio_data * curr_sio, bint quiet ) /*****************************************************************/ { file_info * curr_file; rtn_info * curr_rtn; wp_srcfile * wpsrc_file; void * src_file; mod_info * curr_mod; cue_handle * ch; location_list ll; int line; curr_mod = curr_sio->curr_mod; curr_file = curr_sio->curr_file; curr_rtn = curr_sio->curr_rtn; if( curr_file->unknown_file ) { src_file = NULL; } else { src_file = FOpenSource( curr_file->name, curr_mod->mh, curr_file->fid ); } if( src_file == NULL ) { curr_sio->src_file = NULL; if( !quiet ) { if( curr_file->unknown_file ) { ErrorMsg( LIT( Src_File_Not_Known ) ); } else { ErrorMsg( LIT( Src_File_Not_Found ), curr_file->name ); } } return( NULL ); } wpsrc_file = ProfCAlloc( sizeof( wp_srcfile ) ); wpsrc_file->src_file = src_file; curr_sio->src_file = wpsrc_file; if( SymLocation( curr_rtn->sh, NULL, &ll ) == DS_OK ) { ch = alloca( DIPHandleSize( HK_CUE ) ); AddrCue( curr_mod->mh, ll.e[0].u.addr, ch ); wpsrc_file->rtn_line = CueLine( ch ); } setSrcLineData( wpsrc_file, curr_sio, curr_mod, curr_file, curr_rtn ); line = 1; for( ;; ) { WPSourceGetLine( curr_sio->sample_window, line ); if( wpsrc_file->src_eof ) break; line++; } wpsrc_file->src_rows = line - 1; return( wpsrc_file ); }
STATIC file_info *loadFileInfo( mod_info *curr_mod, sym_handle *sym ) /********************************************************************/ { file_info *sym_file; cue_handle *ch; cue_fileid fid; int file_count; int count; location_list ll; if( SymLocation( sym, NULL, &ll ) != DS_OK ) { return( curr_mod->mod_file[0] ); } ch = alloca( DIPHandleSize( HK_CUE ) ); switch( AddrCue( curr_mod->mh, ll.e[0].u.addr, ch ) ) { case SR_NONE: case SR_FAIL: return( curr_mod->mod_file[0] ); } fid = CueFileId( ch ); file_count = curr_mod->file_count; count = 0; while( count < file_count ) { sym_file = curr_mod->mod_file[count]; if( sym_file->fid == fid ) { return( sym_file ); } count++; } curr_mod->file_count++; curr_mod->mod_file = ProfRealloc( curr_mod->mod_file, curr_mod->file_count * sizeof( pointer ) ); count = CueFile( ch, NULL, 0 ) + 1; sym_file = ProfCAlloc( sizeof( file_info ) + count ); sym_file->fid = fid; CueFile( ch, sym_file->name, count ); initRoutineInfo( sym_file ); curr_mod->mod_file[file_count] = sym_file; return( sym_file ); }
/** * WalkFileList callback, the module pass. * * @returns WR_CONTINUE * @param cue The file. * @param ignored Unused user argument. */ static walk_result File2Callback( cue_handle *cue, void *ignored ) { address prev_addr = {0}; long prev_line = -1; cue_handle *next_cue = alloca( DIPHandleSize( HK_CUE, false ) ); cue_handle *prev_cue = NULL; cue_handle *cue2 = alloca( DIPHandleSize( HK_CUE, false ) ); mod_handle mod = CueMod( cue ); cue_fileid file_id = CueFileId( cue ); search_result search_rc; char buff[1024]; size_t len; dip_status rc; /* filename */ buff[0] = '\0'; len = CueFile( cue, buff, sizeof( buff ) ); if( len > 0 ) { printf( " %lx %s\n", file_id, buff ); } else { printf( " %lx (len=%u)\n", file_id, len ); } /* check the LineCue function */ if( Opts.do_cue_tests ) { search_rc = LineCue( mod, file_id, 0, 0, cue2 ); CompareCues( cue, cue2, SR_EXACT, search_rc, true, false, true, false, "LineCue(,,0,)" ); } /* lines */ do { long line = CueLine( cue ); unsigned column = CueColumn( cue ); address addr = CueAddr( cue ); printf( " Line %5ld ", line ); if( column ) { printf( "Col %2d ", column ); } printf( "at %04x:%08lx%s\n", addr.mach.segment, (long)addr.mach.offset, prev_line >= 0 && addr.mach.offset < prev_addr.mach.offset ? "^" : prev_line >= 0 && line < prev_line ? "!" : "" ); /* do tests */ if( Opts.do_cue_tests ) { if( CueFileId( cue ) != file_id ) { printf( "ERROR: file id changed! new:%#lx old:%#lx\n", (long)CueFileId( cue ), (long)file_id ); } if( CueMod( cue ) != mod ) { printf( "ERROR: module changed! new:%#lx old:%#lx\n", (long)CueMod( cue ), (long)file_id ); } /* line searches */ search_rc = LineCue( mod, file_id, line, 0, cue2 ); CompareCues( cue, cue2, SR_EXACT, search_rc, true, false, false, false, "LineCue(,,n,)" ); if( line > prev_line + 1 && prev_line >= 0 ) { search_rc = LineCue( mod, file_id, line - 1, 0, cue2 ); CompareCues( prev_cue, cue2, prev_line == line - 1 ? SR_EXACT : SR_CLOSEST, search_rc, true, false, false, false, "LineCue(,,n-1,)" ); } /* address searches */ search_rc = AddrCue( mod, addr, cue2 ); CompareCues( cue, cue2, SR_EXACT, search_rc, false, false, true, false, "AddrCue(,,n,)" ); } /* next */ rc = CueAdjust( cue, 1, next_cue ); prev_cue = cue; cue = next_cue; next_cue = prev_cue; prev_addr = addr; prev_line = line; } while( rc == DS_OK ); return( WR_CONTINUE ); }
wp_asmfile *WPAsmOpen( sio_data * curr_sio, int src_row, bool quiet ) /*******************************************************************/ { wp_asmfile * wpasm_file; cue_handle * ch; cue_handle * ch2; mod_info * curr_mod; file_info * curr_file; massgd_sample_addr * samp_data; wp_asmline * asm_line; mod_handle mh; file_handle fh; address addr; cue_fileid fid; search_result cue_find; int rows; int asm_group; int asm_row; int file_index; int addr_cmp; clicks_t addr_tick_index; quiet=quiet; ch = alloca( DIPHandleSize( HK_CUE ) ); ch2 = alloca( DIPHandleSize( HK_CUE ) ); curr_file = curr_sio->curr_file; curr_mod = curr_sio->curr_mod; if( curr_file->fid == 0 || LineCue( curr_mod->mh, curr_sio->curr_file->fid, src_row, 0, ch2 ) == SR_NONE ) { ch2 = NULL; } fh = ExeOpen( curr_sio->curr_image->name ); if( fh == -1 ) { ErrorMsg( LIT( Exe_Not_Found ), curr_sio->curr_image->name ); return( NULL ); } wpasm_file = ProfCAlloc( sizeof(wp_asmfile) ); curr_sio->asm_file = wpasm_file; wpasm_file->asm_buff = ProfAlloc( MAX_ASM_BUFF_LEN ); wpasm_file->asm_buff_len = MAX_ASM_BUFF_LEN; SetNumBytes( 0 ); SetExeFile( fh, false ); wpasm_file->fh = fh; addr = ModAddr( curr_mod->mh ); SetExeOffset( addr ); wpasm_file->max_time = 0; addr_tick_index = curr_mod->first_tick_index - 1; samp_data = WPGetMassgdSampData( curr_sio, addr_tick_index++ ); wpasm_file->asm_data = ProfAlloc( sizeof(wp_asm_groups) ); wpasm_file->asm_data[0].asm_lines = ProfAlloc( MAX_ASM_LINE_SIZE ); wpasm_file->asm_groups = 0; rows = 0; for( ;; ) { mh = curr_mod->mh; if( EndOfSegment() || AddrMod( addr, &mh ) == SR_NONE || mh != curr_mod->mh ) break; cue_find = (AddrCue( curr_mod->mh, addr, ch ) == SR_EXACT); if( ch2 != NULL && CueCmp( ch, ch2 ) == 0 ) { wpasm_file->entry_line = rows; ch2 = NULL; } asm_line = WPGetAsmLoc( wpasm_file, rows, &asm_group, &asm_row ); if( cue_find ) { asm_line->source_line = true; asm_line->u.src.line = CueLine( ch ); asm_line->u.src.src_file = NULL; if( !curr_file->unknown_file ) { fid = CueFileId( ch ); file_index = 0; while( file_index < curr_mod->file_count ) { curr_file = curr_mod->mod_file[file_index]; if( curr_file->fid == fid ) { asm_line->u.src.src_file = FOpenSource( curr_file->name, mh, fid ); break; } file_index++; } } rows++; asm_line = WPGetAsmLoc( wpasm_file, rows, &asm_group, &asm_row ); } asm_line = &wpasm_file->asm_data[asm_group].asm_lines[asm_row]; asm_line->source_line = false; asm_line->u.asm_line.addr = addr; asm_line->u.asm_line.tick_count = 0; for( ;; ) { if( samp_data == NULL ) break; addr_cmp = AddrCmp( &addr, samp_data->raw ); if( addr_cmp < 0 ) break; if( addr_cmp == 0 ) { asm_line->u.asm_line.tick_count = samp_data->hits; if( asm_line->u.asm_line.tick_count > wpasm_file->max_time ) { wpasm_file->max_time = asm_line->u.asm_line.tick_count; } } samp_data = WPGetMassgdSampData( curr_sio, addr_tick_index++ ); } rows++; CodeAdvance( &addr ); } WPGetAsmLoc( wpasm_file, rows, &asm_group, &asm_row ); wpasm_file->asm_data[asm_group].asm_lines = ProfRealloc( wpasm_file->asm_data[asm_group].asm_lines, sizeof(wp_asmline)*(asm_row+1) ); wpasm_file->asm_rows = rows; return( wpasm_file ); }
STATIC void setSrcLineData( wp_srcfile * wpsrc_file, sio_data * curr_sio, mod_info * curr_mod, file_info * curr_file, rtn_info * curr_rtn ) /***************************************************************************/ { massgd_sample_addr * samp_data; wp_srcline * lines; rtn_info * rtn_rover; cue_handle * ch; clicks_t click_index; unsigned long last_srcline; unsigned long new_line; int line_count; int line_index; int count; int count2; ch = alloca( DIPHandleSize( HK_CUE ) ); lines = NULL; line_index = -1; last_srcline = 0; new_line = 0; line_count = 0; wpsrc_file->max_time = 0; count = 0; while( count < curr_file->rtn_count ) { rtn_rover = curr_file->routine[count]; if( rtn_rover->tick_count == 0 ) { count2 = 0; } else { click_index = rtn_rover->first_tick_index - 1; count2 = rtn_rover->last_tick_index - click_index; line_count += count2; lines = ProfRealloc( lines, sizeof(wp_srcline)*line_count ); } while( count2-- > 0 ) { samp_data = WPGetMassgdSampData( curr_sio, click_index ); if( AddrCue( curr_mod->mh, *samp_data->raw, ch ) != SR_NONE ) { if( CueFileId( ch ) == curr_file->fid ) { new_line = CueLine( ch ); } } if( last_srcline != new_line || line_index == -1 ) { line_index++; lines[line_index].line = new_line; lines[line_index].tick_count = 0; last_srcline = new_line; if( line_index == 0 && curr_rtn == rtn_rover ) { wpsrc_file->samp_line = new_line; } } lines[line_index].tick_count += samp_data->hits; if( lines[line_index].tick_count > wpsrc_file->max_time ) { wpsrc_file->max_time = lines[line_index].tick_count; } click_index++; } line_count = line_index + 1; count++; } wpsrc_file->wp_line_count = line_count; if( line_count != 0 ) { wpsrc_file->src_lines = ProfRealloc( lines, sizeof(wp_srcline)*line_count ); } }