STATIC void procAddrBlock( uint_16 total_len, samp_data * data ) /**************************************************************/ { image_info * curr_image; int map_count; int new_count; int i; int j; map_to_actual *map; total_len -= offsetof( samp_block, d.map ); new_count = total_len / sizeof( mapping ); curr_image = CurrSIOData->curr_image; map_count = curr_image->map_count + new_count; map = curr_image->map_data; if( map == NULL ) { map = ProfAlloc( map_count * sizeof(*map) ); } else { map = ProfRealloc( map, map_count * sizeof(*map) ); } for( i = 0, j = curr_image->map_count; i < new_count; ++i, ++j ) { map[j].map.mach.segment = data->map.data[i].map.segment; map[j].map.mach.offset = data->map.data[i].map.offset; map[j].actual.mach.segment = data->map.data[i].actual.segment; map[j].actual.mach.offset = data->map.data[i].actual.offset; map[j].length = 0xffff; //NYI: get from executable.... } curr_image->map_count = map_count; curr_image->map_data = map; }
extern char * WPSourceGetLine( a_window * wnd, int line ) /*******************************************************/ { sio_data * curr_sio; wp_srcfile * wp_src; int buff_len; curr_sio = WndExtra( wnd ); wp_src = curr_sio->src_file; if( wp_src->src_buff_len == 0 ) { wp_src->src_buff = ProfAlloc( 100 ); wp_src->src_buff_len = 100; } for( ;; ) { buff_len = FReadLine( wp_src->src_file, line, 0, wp_src->src_buff, wp_src->src_buff_len ); if( buff_len != wp_src->src_buff_len ) break; wp_src->src_buff_len += 120; wp_src->src_buff = ProfRealloc( wp_src->src_buff, wp_src->src_buff_len ); } if( buff_len < 0 ) { wp_src->src_eof = P_TRUE; return( NULL ); } wp_src->src_eof = P_FALSE; wp_src->src_buff[buff_len] = NULLCHAR; return( wp_src->src_buff ); }
char * WPAsmGetLine( a_window * wnd, int line ) /*********************************************/ { sio_data * curr_sio; wp_asmfile * wpasm_file; src_info * src; wp_asmline * asm_line; int asm_group; int asm_row; int buff_len; curr_sio = WndExtra( wnd ); wpasm_file = curr_sio->asm_file; if( line >= wpasm_file->asm_rows ) { return( NULL ); } asm_line = WPGetAsmLoc( wpasm_file, line, &asm_group, &asm_row ); if( asm_line->source_line ) { src = &asm_line->u.src; if( src->src_file == NULL ) { strcpy( wpasm_file->asm_buff, LIT( Unable_To_Open_Src ) ); } else { for( ;; ) { buff_len = FReadLine( src->src_file, src->line, 0, wpasm_file->asm_buff, wpasm_file->asm_buff_len ); if( buff_len != wpasm_file->asm_buff_len ) break; wpasm_file->asm_buff_len += 120; wpasm_file->asm_buff = ProfRealloc( wpasm_file->asm_buff, wpasm_file->asm_buff_len ); } if( buff_len < 0 ) { buff_len = 0; } wpasm_file->asm_buff[buff_len] = NULLCHAR; } } else { SetNumBytes( 0 ); SetExeFile( wpasm_file->fh, false ); SetExeImage( curr_sio->curr_image ); GetFullInstruct( asm_line->u.asm_line.addr, wpasm_file->asm_buff, wpasm_file->asm_buff_len-1 ); } return( wpasm_file->asm_buff ); }
STATIC walk_result loadModuleInfo( mod_handle mh, void *_curr_image ) /*******************************************************************/ { image_info *curr_image = _curr_image; mod_info *new_mod; int mod_count; int name_len; name_len = DIPModName( mh, NULL, 0 ); new_mod = ProfCAlloc( sizeof( mod_info ) + name_len ); DIPModName( mh, new_mod->name, name_len + 1 ); new_mod->mh = mh; mod_count = curr_image->mod_count; curr_image->mod_count++; curr_image->module = ProfRealloc( curr_image->module, curr_image->mod_count * sizeof( pointer ) ); curr_image->module[mod_count] = new_mod; initFileInfo( new_mod ); DIPWalkSymList( SS_MODULE, &mh, &loadRoutineInfo, new_mod ); return( WR_CONTINUE ); }
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 ); }
STATIC walk_result loadRoutineInfo( sym_walk_info swi, sym_handle *sym, void *_new_mod ) /*********************************************************************/ { mod_info *new_mod = _new_mod; sym_info sinfo; file_info *sym_file; rtn_info *new_rtn; int rtn_count; int name_len; int sym_size; int demangle_type; if( swi != SWI_SYMBOL ) { return( WR_CONTINUE ); } SymInfo( sym, NULL, &sinfo ); if( sinfo.kind != SK_CODE && sinfo.kind != SK_PROCEDURE ) { return( WR_CONTINUE ); } sym_file = loadFileInfo( new_mod, sym ); name_len = SymName( sym, NULL, SN_DEMANGLED, NULL, 0 ); if( name_len == 0 ) { name_len = SymName( sym, NULL, SN_SOURCE, NULL, 0 ); demangle_type = SN_SOURCE; } else { demangle_type = SN_DEMANGLED; } new_rtn = ProfCAlloc( sizeof( rtn_info ) + name_len ); SymName( sym, NULL, demangle_type, new_rtn->name, name_len + 1 ); sym_size = DIPHandleSize( HK_SYM ); new_rtn->sh = ProfAlloc( sym_size ); memcpy( new_rtn->sh, sym, sym_size ); rtn_count = sym_file->rtn_count; sym_file->rtn_count++; sym_file->routine = ProfRealloc( sym_file->routine, sym_file->rtn_count * sizeof( pointer ) ); sym_file->routine[rtn_count] = new_rtn; return( WR_CONTINUE ); }
STATIC void procImageBlock( samp_data *data, bool main_exe ) /**********************************************************/ { image_info *new_image; int name_len; int image_index; name_len = strlen( data->code.name ) + 1; new_image = ProfCAlloc( sizeof(image_info) ); image_index = CurrSIOData->image_count; CurrSIOData->image_count++; CurrSIOData->images = ProfRealloc( CurrSIOData->images, CurrSIOData->image_count*sizeof(pointer)); CurrSIOData->images[image_index] = new_image; CurrSIOData->curr_image = new_image; new_image->name = ProfAlloc( name_len ); memcpy( new_image->name, data->code.name, name_len ); new_image->overlay_table.mach.segment = data->code.ovl_tab.segment; new_image->overlay_table.mach.offset = data->code.ovl_tab.offset; new_image->time_stamp = data->code.time_stamp; new_image->main_load = main_exe; }
wp_asmline * WPGetAsmLoc( wp_asmfile * wpasm_file, int row, int * group_loc, int * row_loc ) /******************************************************************/ { wp_asmline * asm_line; int asm_row; int asm_group; asm_group = row / MAX_ASM_LINE_INDEX; asm_row = row - (asm_group * MAX_ASM_LINE_INDEX); if( asm_group != 0 && asm_row == 0 && asm_group > wpasm_file->asm_groups ) { wpasm_file->asm_data = ProfRealloc( wpasm_file->asm_data, sizeof(wp_asm_groups)*(asm_group+1) ); wpasm_file->asm_data[asm_group].asm_lines = ProfAlloc( MAX_ASM_LINE_SIZE ); wpasm_file->asm_groups++; } *group_loc = asm_group; *row_loc = asm_row; asm_line = &wpasm_file->asm_data[asm_group].asm_lines[asm_row]; return( asm_line ); }
STATIC bint procCmd( char * cmd ) /*******************************/ { char *rover; int name_len; int old_len; int cmd_type; int index; bint do_report; bint do_option; do_report = P_FALSE; for( ;; ) { cmd = eatBlanks( cmd ); if( *cmd == NULLCHAR ) break; #ifdef __UNIX__ if( *cmd == '-' ) { #else if( *cmd == '-' || *cmd == '/' ) { #endif do_option = P_TRUE; ++cmd; cmd_type = minLook( &cmd ); } else if( *cmd == '?' ) { do_option = P_TRUE; cmd_type = HELP_OPT; } else { do_option = P_FALSE; rover = cmd; cmd = eatAllChars( cmd ); name_len = cmd - rover; if( name_len > _MAX_PATH ) { name_len = _MAX_PATH; } memcpy( SamplePath, rover, name_len ); SamplePath[name_len] = NULLCHAR; } if( do_option ) { switch( cmd_type ) { case FAIL_OPT: ErrorMsg( LIT( Cmd_Option_Not_Valid ), cmd-1 ); #if defined( __WINDOWS__ ) || defined( __NT__ ) || defined( __OS2_PM__ ) fatal( LIT( Usage ) ); #else /* fall through */ #endif case HELP_OPT: index = 0; while( cmdUsage[index] ) { ErrorMsg( cmdUsage[index++] ); } exit( 0 ); case DIP_OPT: cmd = eatBlanks( cmd ); if( *cmd == '=' ) { cmd = eatBlanks( cmd+1 ); } rover = cmd; cmd = eatAlphaNum( cmd ); if( *cmd == NULLCHAR || cmd-rover == 0 ) { if( WProfDips != NULL ) { ProfFree( WProfDips ); WProfDips = NULL; WProfDipSize = 0; } } else { name_len = cmd - rover; old_len = WProfDipSize; WProfDipSize = old_len + name_len + 1; if( old_len == 0 ) { WProfDipSize++; } else { old_len--; } WProfDips = ProfRealloc( WProfDips, WProfDipSize ); memcpy( WProfDips+old_len, rover, name_len ); old_len += name_len; WProfDips[old_len++] = NULLCHAR; WProfDips[old_len] = NULLCHAR; } break; #if defined( __DOS__ ) case NOGRAPHICSMOUSE_OPT: case NOCHARREMAP_OPT: WndStyle &= ~(GUI_CHARMAP_DLG|GUI_CHARMAP_MOUSE); break; #endif #ifndef NDEBUG case R_OPT: do_report = P_TRUE; break; #endif } } } return( do_report ); } STATIC char * eatBlanks( char * cmd ) { /*************************************/ while( isspace( *cmd ) && *cmd != NULLCHAR ) { ++cmd; } return( cmd ); } STATIC char * eatAlphaNum( char * cmd ) { /***************************************/ while( isalnum( *cmd ) && *cmd != NULLCHAR ) { ++cmd; } return( cmd ); } STATIC char * eatAllChars( char * cmd ) { /***************************************/ while( !isspace( *cmd ) && *cmd != NULLCHAR ) { ++cmd; } return( cmd ); } STATIC int minLook( char * * value ) { /************************************/ int index; int curr_len; char * * strtab; byte * lentab; char * strlook; char * strchck; char * base_val; char check_char; base_val = *value; lentab = cmdLen; strtab = cmdNames; index = 0; for(;;) { strlook = *strtab++; if( strlook == NULL ) { return( FAIL_OPT ); } strchck = base_val; curr_len = 0; for(;;) { check_char = tolower( *strchck ); if( check_char == NULLCHAR || !(isalpha( check_char ) || check_char == '?') ) { if( curr_len >= *lentab ) { *value += curr_len; return( cmdType[index] ); } break; } if( *strlook != check_char ) break; strlook++; strchck++; curr_len++; } lentab++; index++; } }
STATIC bool sampleProcOverview( a_window * wnd, int row, int piece, wnd_line_piece * line ) /******************************************************************/ { sio_data * curr_sio; clicks_t tick_count; clicks_t total_ticks; char * text; if( piece >= PIECE_LAST ) { return( false ); } curr_sio = WndExtra( wnd ); row += STATUS_ROW + 1; text = LIT( Empty_Str ); tick_count = 0; if( row <= curr_sio->level_open ) { if( row == 0 ) { text = curr_sio->samp_file_name; tick_count = curr_sio->total_samples; } else if( row == 1 ) { text = curr_sio->curr_image->name; tick_count = curr_sio->curr_image->agg_count; } else if( row == 2 ) { text = curr_sio->curr_mod->name; tick_count = curr_sio->curr_mod->agg_count; } else if( row == 3 ) { text = curr_sio->curr_file->name; tick_count = curr_sio->curr_file->agg_count; } else if( row == 4 ) { text = curr_sio->curr_rtn->name; tick_count = curr_sio->curr_rtn->tick_count; } } if( piece == PIECE_MOUSE_CATCHER ) { line->indent = 0; line->tabstop = false; line->master_tabstop = true; line->attr = WPA_PLAIN; line->text = LIT( Empty_Str ); if( row <= curr_sio->level_open ) { line->extent = BAR_TAIL_POINT; } } else if( piece == PIECE_BAR ) { line->indent = BAR_TAIL_POINT; if( curr_sio->total_samples == 0 ) { curr_sio->total_samples = 1; } total_ticks = curr_sio->total_samples; line->attr = WPA_PLAIN; line->tabstop = false; line->master_tabstop = true; if( row > curr_sio->level_open ) { line->text = LIT( Empty_Str ); } else { line->draw_bar = true; barData.bar_style = GUI_BAR_SHADOW; barData.bar_colour = WPA_ABS_BAR; barData.bar_group = false; barData.bar_selected = false; tick_count *= BAR_TAIL_POINT - (WndMaxCharX( wnd ) / 2); line->extent = tick_count / total_ticks; if( line->extent == 0 && tick_count != 0 ) { line->extent = 1; } line->indent -= line->extent; line->text = (char *)&barData; } } else if( piece == PIECE_SEPARATOR ) { indentPiece = SEPARATOR_POINT; line->indent = indentPiece; line->vertical_line = true; line->text = LIT( Empty_Str ); line->attr = WPA_PLAIN; line->tabstop = false; line->master_tabstop = true; } else if( piece == PIECE_HOOK ) { if( row > curr_sio->level_open ) { return( false ); } line->tabstop = false; line->master_tabstop = true; line->text = LIT( Empty_Str ); if( row == 0 ) { indentPiece += WndMaxCharX( wnd ); } else { indentPiece += (row*2 - 1) * WndMaxCharX( wnd ); line->indent = indentPiece; indentPiece += 2 * WndMaxCharX( wnd ); line->draw_hook = true; line->attr = WPA_PLAIN; } } else if( piece == PIECE_NAME_TITLE ) { line->indent = indentPiece; nameBuff = ProfRealloc( nameBuff, strlen( overviewHeaders[row] ) + 1 ); strcpy( nameBuff, overviewHeaders[row] ); line->text = nameBuff; line->tabstop = false; line->master_tabstop = true; if( curr_sio->level_open == row ) { line->attr = WPA_OVERVIEW_NAME; } else { line->attr = WPA_PLAIN; } indentPiece += WndExtentX( wnd, nameBuff ); } else { line->indent = indentPiece; nameBuff = ProfRealloc( nameBuff, strlen( text ) + 1 ); strcpy( nameBuff, text ); line->text = nameBuff; line->tabstop = false; line->master_tabstop = true; if( curr_sio->level_open == row ) { line->attr = WPA_OVERVIEW_NAME; } else { line->attr = WPA_PLAIN; } } return( true ); }
STATIC void calcAggregates( void ) /********************************/ { unsigned index; unsigned index2; int cmp_result; unsigned *sorted_idx; address ***sorted_vect; massgd_sample_addr **massgd_data; // unsigned mbuckets; unsigned curr_mbucket; unsigned curr_midx; thread_data *thd; unsigned buckets; unsigned base; unsigned best; unsigned end; massgd_sample_addr *curr; ClearMassaged( CurrSIOData ); buckets = 0; for( thd = CurrSIOData->samples; thd != NULL; thd = thd->next ) { buckets += RAW_BUCKET_IDX( thd->end_time - thd->start_time ) + 1; } sorted_idx = ProfCAlloc( buckets * sizeof( *sorted_idx ) ); sorted_vect = ProfAlloc( buckets * sizeof(*thd->raw_bucket) ); base = 0; for( thd = CurrSIOData->samples; thd != NULL; thd = thd->next ) { end = RAW_BUCKET_IDX( thd->end_time - thd->start_time ) + 1; for( index = 0; index < end; ++index, ++base ) { sorted_vect[base] = ProfAlloc( MAX_RAW_BUCKET_INDEX * sizeof( **sorted_vect ) ); for( index2 = 0; index2 < MAX_RAW_BUCKET_INDEX; ++index2 ) { sorted_vect[base][index2] = &thd->raw_bucket[index][index2]; } qsort( sorted_vect[base], MAX_RAW_BUCKET_INDEX, sizeof(**sorted_vect), rawSampCmp ); } } /* skip over all the 0:0 samples */ for( index = 0; index < buckets; ++index ) { index2 = 0; for( ;; ) { if( index2 >= MAX_RAW_BUCKET_INDEX ) break; if( !(sorted_vect[index][index2]->mach.segment == 0 && sorted_vect[index][index2]->mach.offset == 0) ) break; ++index2; } sorted_idx[index] = index2; } curr = NULL; curr_mbucket = 0; curr_midx = -1; // mbuckets = 1; massgd_data = ProfAlloc( sizeof( *massgd_data ) ); massgd_data[0] = ProfCAlloc( MAX_MASSGD_BUCKET_SIZE ); for( ;; ) { best = -1U; for( index = 0; index < buckets; ++index ) { index2 = sorted_idx[index]; if( index2 >= MAX_RAW_BUCKET_INDEX ) continue; if( best == -1U ) best = index; cmp_result = AddrCmp( sorted_vect[index][index2], sorted_vect[best][sorted_idx[best]] ); if( cmp_result < 0 ) best = index; } if( best == -1U ) break; if( curr == NULL || AddrCmp( sorted_vect[best][sorted_idx[best]], curr->raw ) != 0 ) { if( ++curr_midx >= MAX_MASSGD_BUCKET_INDEX ) { ++curr_mbucket; massgd_data = ProfRealloc( massgd_data, (curr_mbucket+1) * sizeof(*massgd_data) ); massgd_data[curr_mbucket] = ProfCAlloc( MAX_MASSGD_BUCKET_SIZE ); curr_midx = 0; } curr = &massgd_data[curr_mbucket][curr_midx]; curr->raw = sorted_vect[best][sorted_idx[best]]; } curr->hits++; sorted_idx[best]++; } CurrSIOData->massaged_sample = massgd_data; CurrSIOData->number_massaged = 1 + curr_midx + (curr_mbucket * (unsigned long)MAX_MASSGD_BUCKET_INDEX); CurrSIOData->massaged_mapped = true; for( index = 0; index < buckets; ++index ) { ProfFree( sorted_vect[index] ); } ProfFree( sorted_vect ); ProfFree( sorted_idx ); }
STATIC bool readSampleFile( void ) /********************************/ { file_handle fh; uint_16 size; void *buff; int buff_len; off_t start_position; bool main_exe; samp_block_prefix prefix; samp_block_prefix *next_prefix; /* we can add error checking for things like */ /**/ /* - number of samples match the info # of samples */ /* - main exe load if there is an overlay table */ /**/ fh = CurrSIOData->fh; start_position = lseek( fh, CurrSIOData->header.sample_start, SEEK_SET ); if( start_position == (off_t) -1 ) { ErrorMsg( LIT( Smp_File_IO_Err ), CurrSIOData->samp_file_name ); return( false ); } if( read( fh, &prefix, SIZE_PREFIX ) != SIZE_PREFIX ) { ErrorMsg( LIT( Smp_File_IO_Err ), CurrSIOData->samp_file_name ); return( false ); } buff = ProfAlloc( SIZE_DATA ); buff_len = SIZE_DATA; main_exe = false; while( prefix.kind != SAMP_LAST ) { size = prefix.length; if( buff_len < size ) { buff = ProfRealloc( buff, size ); buff_len = size; } /* reads data & next prefix */ if( BigRead( fh, buff, size ) != size ) { ErrorMsg( LIT( Smp_File_IO_Err ), CurrSIOData->samp_file_name ); ProfFree( buff ); return( false ); } next_prefix = (void *)( ((char *) buff) + ( size - SIZE_PREFIX )); /* if we're reading a sample record from a callgraph sample */ /* file, the next record should contain callgraph information */ /* which we will also want stored in memory for processing */ /* 16-jul-92 CMS */ // if( CallGraph && prefix.kind == SAMP_SAMPLES && // next_prefix->kind == SAMP_CALLGRAPH ) { // size = next_prefix->length; // /* reads callgraph data & next prefix */ // if( BigRead( fh, next_prefix, size ) != size ) { // errorIO(); // ProfFree( buff ); // ErrorMsg( LIT( Smp_File_IO_Err ), CurrSIOData->samp_file_name ); // return( false ); // } // next_prefix = (void *)( ((char *) next_prefix) + ( size - SIZE_PREFIX )); // } switch( prefix.kind ) { case SAMP_INFO: procInfoBlock( prefix.tick, buff ); break; case SAMP_SAMPLES: if( !procSampleBlock( prefix.tick, prefix.length, buff ) ) { return( false ); } break; case SAMP_MARK: procMarkBlock( prefix.tick, buff ); break; case SAMP_OVL_LOAD: procOverlayBlock( prefix.tick, buff ); break; case SAMP_ADDR_MAP: procAddrBlock( prefix.length, buff ); break; case SAMP_MAIN_LOAD: main_exe = true; /* fall through */ case SAMP_CODE_LOAD: procImageBlock( buff, main_exe ); main_exe = false; break; case SAMP_REMAP_SECTION: procRemapBlock( prefix.tick, prefix.length, buff ); break; case SAMP_CALLGRAPH: // printf( "sample callgraph\n" ); break; } prefix = *next_prefix; } ProfFree( buff ); return( true ); }
STATIC bool procSampleBlock( clicks_t tick, uint_16 total_len, samp_data *data ) /*************************************************************/ { thread_id thread; unsigned data_index; unsigned index; unsigned index2; unsigned count; unsigned buckets; clicks_t end_tick; ldiv_t div_result; thread_data *thd; thread_data **owner; address *samp; thread = data->sample.thread_id; total_len -= offsetof( samp_block, d.sample ); count = total_len / sizeof( samp_address ); CurrSIOData->total_samples += count; end_tick = tick + count; owner = &CurrSIOData->samples; for( ;; ) { thd = *owner; if( thd == NULL ) { thd = ProfAlloc( sizeof( *thd ) ); *owner = thd; thd->next = NULL; thd->thread = thread; thd->start_time = tick; thd->end_time = end_tick; buckets = RAW_BUCKET_IDX( count ) + 1; thd->raw_bucket = ProfAlloc( buckets * sizeof( *thd->raw_bucket ) ); for( index = 0; index < buckets; ++index ) { thd->raw_bucket[index] = ProfCAlloc( MAX_RAW_BUCKET_SIZE ); } break; } if( thd->thread == thread ) break; owner = &thd->next; } if( end_tick > thd->end_time ) { index = RAW_BUCKET_IDX( thd->end_time - thd->start_time ) + 1; buckets = RAW_BUCKET_IDX( end_tick - thd->start_time ) + 1; if( buckets > index ) { thd->raw_bucket = ProfRealloc( thd->raw_bucket, buckets * sizeof( *thd->raw_bucket ) ); for( ; index < buckets; ++index ) { thd->raw_bucket[index] = ProfCAlloc( MAX_RAW_BUCKET_SIZE ); } } thd->end_time = end_tick; } div_result = ldiv( tick - thd->start_time, MAX_RAW_BUCKET_INDEX ); index = div_result.quot; index2 = div_result.rem; data_index = 0; while( count > 0 ) { samp = &thd->raw_bucket[index][index2]; samp->mach.segment = data->sample.sample[data_index].segment; samp->mach.offset = data->sample.sample[data_index].offset; if( ++index2 >= MAX_RAW_BUCKET_INDEX ) { index2 = 0; ++index; } ++data_index; --count; } return( true ); }
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 ); } }