extern void AsmMoveDot( a_window *wnd, address addr ) { int row; asm_window *asw; DIPHDL( cue, ch1 ); DIPHDL( cue, ch2 ); if( wnd == NULL ) return; asw = WndAsm( wnd ); if( DeAliasAddrCue( asw->mod, addr, ch1 ) != SR_NONE && DeAliasAddrCue( asw->mod, asw->dotaddr, ch2 ) != SR_NONE ) { if( CueMod( ch1 ) == CueMod( ch2 ) && CueFileId( ch1 ) == CueFileId( ch2 ) && CueLine( ch1 ) == CueLine( ch2 ) ) { return; } } WndNoSelect( wnd ); row = AsmAddrRow( wnd, addr ); if( row == WndRows( wnd ) ) { AsmSetFirst( wnd, addr, TRUE ); row = AsmAddrRow( wnd, addr ); WndDirtyCurr( wnd ); WndNewCurrent( wnd, row, PIECE_CURRENT ); WndRepaint( wnd ); row = 0; } else { WndDirtyCurr( wnd ); WndNewCurrent( wnd, row, PIECE_CURRENT ); } AsmSetDotAddr( wnd, addr ); }
void BreakAllModEntries( mod_handle handle ) { name_list list; address addr; int i; bool have_mod_cue; sym_info sinfo; DIPHDL( cue, ch ); DIPHDL( cue, ch_mod ); NameListInit( &list, WF_CODE ); NameListAddModules( &list, handle, false, true ); have_mod_cue = FindFirstCue( handle, ch_mod ); for( i = 0; i < NameListNumRows( &list ); ++i ) { addr = NameListAddr( &list, i ); SymInfo( NameListHandle( &list, i ), NULL, &sinfo ); if( !sinfo.is_global && !sinfo.is_public ) continue; if( have_mod_cue && DeAliasAddrCue( handle, addr, ch ) != SR_NONE ) { if( CueFileId( ch ) != CueFileId( ch_mod ) ) { continue; } } if( FindBreak( addr ) != NULL ) { continue; } AddBreak( addr ); } NameListFree( &list ); }
static walk_result FindCue( cue_handle *ch, void *d ) { cue_find *cd = d; char file[FILENAME_MAX]; unsigned len; unsigned match; len = CueFile( ch, file, sizeof( file ) ); if( len < cd->len ) return( WR_CONTINUE ); if( memcmp( &file[len - cd->len], cd->name, cd->len ) == 0 ) { match = CMP_SENSITIVE; } else if( memicmp( &file[len - cd->len], cd->name, cd->len ) == 0 ) { match = CMP_INSENSITIVE; } else { return( WR_CONTINUE ); } if( match > cd->match ) { cd->match = match; cd->id = CueFileId( ch ); cd->ambig = FALSE; } else if( match == cd->match ) { cd->ambig = TRUE; } return( WR_CONTINUE ); }
extern bool SrcMoveDot( a_window *wnd, address addr ) { unsigned line; mod_handle mod; file_window *file; DIPHDL( cue, ch ); if( wnd == NULL ) return( FALSE ); file = WndFile( wnd ); if( file->mod == NO_MOD && !file->track ) return( FALSE ); if( IS_NIL_ADDR( addr ) ) { WndScrollAbs( wnd, 0 ); return( FALSE ); } DeAliasAddrMod( addr, &mod ); if( DeAliasAddrCue( mod, addr, ch ) == SR_NONE ) { if( LineCue( mod, 0, 0, 0, ch ) == SR_NONE ) return( FALSE ); } line = CueLine( ch ); if( mod != file->mod || CueFileId( ch ) != file->file_id ) { if( !file->track ) return( FALSE ); FileTrack( wnd, ch ); } --line; WndScrollAbs( wnd, line ); // WndMoveCurrent( wnd, line, PIECE_SOURCE ); FileSetDotAddr( wnd, addr ); FileSetTitle( wnd, CueMod( ch ) ); return( TRUE ); }
static remap_return ReMapOnePoint( brkp *bp, image_entry *image ) { mod_handle himage, mod; bool ok; address addr; DIPHDL( cue, ch ); DIPHDL( cue, ch2 ); remap_return rc = REMAP_REMAPPED; if( !bp->status.b.unmapped ) return( REMAP_WRONG_IMAGE ); if( bp->image_name == NULL || bp->mod_name == NULL ) { if( image == NULL ) { if( ReMapAddress( &bp->loc ) ) { rc = REMAP_REMAPPED; } else { rc = REMAP_ERROR; } } else { rc = ReMapImageAddress( &bp->loc, image ); } } else { himage = LookupImageName( bp->image_name, strlen( bp->image_name ) ); if( himage == NO_MOD ) return( REMAP_ERROR ); mod = LookupModName( himage, bp->mod_name, strlen( bp->mod_name ) ); if( mod == NO_MOD ) return( REMAP_ERROR ); ok = GetBPSymAddr( bp, &addr ); if( !ok ) return( REMAP_ERROR ); if( bp->cue_diff != 0 ) { if( DeAliasAddrCue( mod, addr, ch ) != SR_EXACT ) return( REMAP_ERROR ); if( LineCue( mod, CueFileId( ch ), CueLine( ch ) + bp->cue_diff, 0, ch2 ) != SR_EXACT ) return( REMAP_ERROR ); addr = CueAddr( ch2 ); } if( bp->addr_diff != 0 ) { addr.mach.offset += bp->addr_diff; } bp->loc.addr = addr; rc = REMAP_REMAPPED; } if( rc == REMAP_REMAPPED ) { bp->status.b.unmapped = false; } SetPointAddr( bp, bp->loc.addr ); if( bp->status.b.activate_on_remap ) { ActPoint( bp, true ); } return( rc ); }
/** * Compares two cues, the first one being the one which information we use * searching for the 2nd. * * @param cue The first cue. * @param cue2 The result cue (depends on search_rc). * @param expected_rc The expected search result. * @param actual_rc The actual search result. * @param exp_exact_line Set if we're to expect a matching line number. * @param exp_le_line Set if we're to expect a less or equal line number. * @param exp_exact_addr Set if we're to expect a matching address. * @param exp_le_line Set if we're to expect a less or equal address. * @param operation The name of the search operation. */ static void CompareCues( cue_handle *cue, cue_handle *cue2, search_result expected_rc, search_result actual_rc, bool exp_exact_line, bool exp_le_line, bool exp_exact_addr, bool exp_le_addr, const char *operation ) { if( actual_rc != expected_rc ) { printf( "FAILED: %s returned %d instead of %d\n", operation, actual_rc, expected_rc ); } if( actual_rc == SR_CLOSEST || actual_rc == SR_EXACT ) { address addr = CueAddr( cue ); unsigned long line = CueLine( cue ); address addr2 = CueAddr( cue2 ); unsigned long line2 = CueLine( cue2 ); int failed; failed = CueFileId( cue2 ) != CueFileId( cue ); failed |= exp_exact_line && line2 != line; failed |= exp_le_line && line2 <= line; failed |= exp_exact_addr && ( addr2.mach.segment != addr.mach.segment || addr2.mach.offset != addr.mach.offset ); failed |= exp_le_addr && ( addr2.mach.segment != addr.mach.segment || addr2.mach.offset <= addr.mach.offset ); if( failed ) { printf( "FAILED: %s: cue2:{file=%#x line=%lu addr=%04x:%08lx}\n" " %*s != cue:{file=%#x line=%lu addr=%04x:%08lx}\n", operation, CueFileId( cue2 ), line2, addr2.mach.segment, (long)addr2.mach.offset, strlen( operation ), "", CueFileId( cue ), line, addr.mach.segment, (long)addr.mach.offset ); } } }
brkp *FindBreakByLine( mod_handle mod, cue_fileid id, unsigned line ) { brkp *bp; mod_handle brk_mod; DIPHDL( cue, ch ); for( bp = BrkList; bp != NULL; bp = bp->next ) { if( DeAliasAddrMod( bp->loc.addr, &brk_mod ) == SR_NONE )continue; if( brk_mod != mod )continue; if( DeAliasAddrCue( brk_mod, bp->loc.addr, ch ) == SR_NONE ) continue; if( CueFileId( ch ) != id ) continue; if( CueLine( ch ) != line ) continue; return( bp ); } return( NULL ); }
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 ); }
void *OpenSrcFile( cue_handle *ch ) { void *hndl; char_ring *path; char *p; char *d; char *rem_name; bool used_star; unsigned len; char *buff; len = CueFile( ch, NULL, 0 ) + 1; _AllocA( buff, len ); CueFile( ch, buff, len ); hndl = FOpenSource( buff, CueMod( ch ), CueFileId( ch ) ); if( hndl != NULL ) return( hndl ); for( path = SrcSpec; path != NULL; path = path->next ) { used_star = FALSE; d = TxtBuff; for( p = path->name; *p != '\0'; ++p ) { if( *p == '*' ) { used_star = TRUE; d += ModName( CueMod( ch ), d, TXT_LEN ); } else { *d++ = *p; } } *d = NULLCHAR; if( !used_star ) { #if 0 /* John can't remember why he put this code in, and it screws up when the user sets a source path of ".". If we find some case where it's required, we'll have to think harder about things. */ if( *ExtPointer( TxtBuff, 0 ) != '\0' ) { *SkipPathInfo( TxtBuff, 0 ) = '\0'; } #endif d = AppendPathDelim( TxtBuff, 0 ); if( !IsAbsolutePath( buff ) ) { StrCopy( buff, d ); hndl = FOpenSource( TxtBuff, CueMod( ch ), CueFileId( ch ) ); if( hndl != NULL ) return( hndl ); } /* We have a small problem here. We want to strip off the path information for the source file name, but we don't know if the file was compiled on the local system or the remote one. We'll kludge things by doing a local skip and then a remote one and seeing who takes off the most stuff. Don't even think about the case where the file has been compiled on a third, different type of file system. */ p = SkipPathInfo( buff, OP_LOCAL ); rem_name = SkipPathInfo( buff, OP_REMOTE ); if( rem_name > p ) p = rem_name; d = StrCopy( p, d ); *d = NULLCHAR; } hndl = FOpenSource( TxtBuff, CueMod( ch ), CueFileId( ch ) ); if( hndl != NULL ) return( hndl ); } return( NULL ); }
/** * 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 ); }
static void FileTrack( a_window *wnd, cue_handle *ch ) { unsigned active, old_active; unsigned end_line; int slack; file_window *file = WndFile( wnd ); mod_handle mod; cue_fileid id; wnd_row curr_row; int curr_piece; if( ch == NULL ) { mod = NO_MOD; id = 0; } else { mod = CueMod( ch ); id = CueFileId( ch ); } if( file->viewhndl == NULL || file->mod != mod || file->file_id != id ) { if( file->viewhndl != NULL ) { FDoneSource( file->viewhndl ); } file->mod = mod; file->file_id = id; FileSetDotAddr( wnd, GetCodeDot() ); if( file->mod == NO_MOD ) { file->viewhndl = NULL; } else { file->viewhndl = OpenSrcFile( ch ); } FileSetTitle( wnd, mod ); SeekToTheEnd( file ); file->eof = UINT_MAX; WndZapped( wnd ); FilePosInit( wnd ); file->active = NOT_ACTIVE; FilePos( wnd, 0 ); DbgUpdate( UP_OPEN_CHANGE ); } active = ActiveLine(); if( active != file->active ) { FileSetDotAddr( wnd, GetCodeDot() ); WndGetCurrent( wnd, &curr_row, &curr_piece ); WndNoCurrent( wnd ); if( curr_row != WND_NO_ROW ) { WndRowDirty( wnd, curr_row ); } } old_active = file->active; file->active = NOT_ACTIVE; slack = WndRows( wnd ) / 4; if( slack > 2 ) slack = 2; end_line = WndTop( wnd ) + WndRows( wnd ) - 1; if( old_active == NOT_ACTIVE || active > end_line ) { WndZapped( wnd ); WndScroll( wnd, active - slack - WndTop( wnd ) ); } else if( active > end_line - slack ) { WndRowDirtyImmed( wnd, old_active ); WndScroll( wnd, WndRows( wnd ) - 2 * slack ); } else if( active < WndTop( wnd ) ) { WndRowDirtyImmed( wnd, old_active ); WndScroll( wnd, active - WndTop( wnd ) - slack ); } else { WndRowDirty( wnd, old_active ); } WndNewCurrent( wnd, active, PIECE_SOURCE ); WndRowDirty( wnd, active ); file->active = active; }
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 ); } }