//************************************************************************************* // //************************************************************************************* void CTraceRecorder::AbortTrace() { DAEDALUS_PROFILE( "CTraceRecorder::AbortTrace" ); if( mTracing ) { #ifdef LOG_ABORTED_TRACES FILE * fh( fopen( "aborted_traces.txt", "a" ) ); if(fh) { fprintf( fh, "\n\nTrace: (%d ops)\n", mTraceBuffer.size() ); u32 last_address( mTraceBuffer.size() > 0 ? mTraceBuffer[ 0 ].Address-4 : 0 ); for(std::vector< STraceEntry >::const_iterator it = mTraceBuffer.begin(); it != mTraceBuffer.end(); ++it) { u32 address( it->Address ); OpCode op_code( it->OpCode ); u32 branch_index( it->BranchIdx ); if( branch_index != INVALID_IDX ) { DAEDALUS_ASSERT( branch_index < mBranchDetails.size(), "The branch index is out of range" ); const SBranchDetails & details( mBranchDetails[ branch_index ] ); fprintf( fh, " BRANCH %d -> %08x\n", branch_index, details.TargetAddress ); } char buf[100]; SprintOpCodeInfo( buf, address, op_code ); bool is_jump( address != last_address + 4 ); fprintf( fh, "%08x: %c%s\n", address, is_jump ? '*' : ' ', buf ); last_address = address; } fclose(fh); } #endif //DBGConsole_Msg( 0, "Aborting tracing of [R%08x]", mStartTraceAddress ); mTracing = false; mStartTraceAddress = 0; mTraceBuffer.clear(); mBranchDetails.clear(); mExpectedExitTraceAddress = 0; mActiveBranchIdx = INVALID_IDX; mStopTraceAfterDelaySlot = false; mNeedIndirectExitMap = false; } }
int main( int argc, char** argv ) { assert( argc > 2 ); daw::history::pump_model_t pump_model( argv[1] ); auto data = read_file( argv[2] ); std::vector<uint8_t> v; for( size_t n = 0; n < data.size( ); n += 2 ) { while( std::isspace( data[n] ) ) { ++n; } char tmp[3] = { data[n], data[n + 1], 0 }; v.push_back( static_cast<uint8_t>(strtol( tmp, nullptr, 16 )) ); } if( v.back( ) == 0 ) { v.pop_back( ); // null terminator } v.pop_back( ); // crc v.pop_back( ); // crc auto range = daw::range::make_range( v.data( ), v.data( ) + v.size( ) ); std::vector<std::unique_ptr<daw::history::history_entry_obj>> entries; size_t pos = 0; auto good_item = []( auto const & i ) { if( !i ) { return false; } if( !i->timestamp( ) ) { return false; } return i->timestamp( )->date( ).year( ) == current_year( ); }; auto reasonible_year = []( auto const & i ) { if( i->timestamp( ) ) { auto item_year = i->timestamp( )->date( ).year( ); auto this_year = current_year( ); if( item_year < this_year - 2 ) { return false; } if( item_year > this_year + 2 ) { return false; } } return true; // Not all items have timestamps }; while( !range.at_end( ) ) { auto item = daw::history::create_history_entry( range, pump_model, pos ); if( item ) { if( item->op_code( ) == 0x0 ) { continue; } std::cout << std::dec << std::dec << pos+1 << "/" << v.size( ) << ": "; if( !reasonible_year( item ) ) { std::cerr << "WARNING: The year does not look correct, outside of plus or minute 2 years from current system year\n"; } std::cout << item->encode( ); entries.push_back( std::move( item ) ); } else { std::cout << std::dec << std::dec << pos+1 << "/" << v.size( ) << ": "; std::cout << "ERROR: data( "; auto err_start = pos; safe_advance( range, 1 ); while( !range.at_end( ) && (range[0] == 0 || !(item = daw::history::create_history_entry( range, pump_model, pos )) || !good_item( item ) )) { safe_advance( range, 1 ); ++pos; } auto offset = item ? item->size( ) - 1 : 0; std::cout << (pos-(err_start+offset)) << " ) { "; std::cout << daw::range::make_range( v.data( ) + err_start, v.data( ) + pos - offset ).to_hex_string( ) << " }\n"; if( !range.at_end( ) ) { std::cout << std::dec << std::dec << (pos-offset)+1 << "/" << v.size( ) << ": " << item->encode( ); entries.push_back( std::move( item ) ); } } std::cout << "\n\n"; } return EXIT_SUCCESS; }