@@ -3198,7 +3198,27 @@ bool DebuggerController::IsInstructionExecuted(uint64_t address)
31983198 return false ;
31993199 }
32003200
3201- return m_executedInstructions.find (address) != m_executedInstructions.end ();
3201+ return m_executedInstructionCounts.find (address) != m_executedInstructionCounts.end ();
3202+ }
3203+
3204+ size_t DebuggerController::GetInstructionExecutionCount (uint64_t address)
3205+ {
3206+ if (!m_state->IsConnected () || !IsTTD ())
3207+ {
3208+ return 0 ;
3209+ }
3210+
3211+ if (!m_codeCoverageAnalysisRun)
3212+ {
3213+ return 0 ;
3214+ }
3215+
3216+ auto iter = m_executedInstructionCounts.find (address);
3217+ if (iter != m_executedInstructionCounts.end ())
3218+ {
3219+ return iter->second ;
3220+ }
3221+ return 0 ;
32023222}
32033223
32043224
@@ -3217,7 +3237,7 @@ bool DebuggerController::RunCodeCoverageAnalysis(uint64_t startAddress, uint64_t
32173237 }
32183238
32193239 // Clear previous analysis results
3220- m_executedInstructions .clear ();
3240+ m_executedInstructionCounts .clear ();
32213241 m_codeCoverageAnalysisRun = false ;
32223242
32233243 LogInfo (" Starting TTD code coverage analysis." );
@@ -3243,23 +3263,22 @@ bool DebuggerController::RunCodeCoverageAnalysis(uint64_t startAddress, uint64_t
32433263 // Add all executed instruction addresses within the range
32443264 if (event.instructionAddress >= startAddress && event.instructionAddress <= endAddress)
32453265 {
3246- // Check if the event is within the specified time range
3247- m_executedInstructions.insert (event.address );
3266+ m_executedInstructionCounts[event.instructionAddress ]++;
32483267 }
32493268 }
32503269 }
32513270
32523271 m_codeCoverageAnalysisRun = true ;
32533272 LogInfo (" TTD code coverage analysis completed for ranges. Found %" PRIu64 " executed instructions." ,
3254- (uint64_t )m_executedInstructions .size ());
3273+ (uint64_t )m_executedInstructionCounts .size ());
32553274
32563275 return true ;
32573276}
32583277
32593278
32603279size_t DebuggerController::GetExecutedInstructionCount () const
32613280{
3262- return m_executedInstructions .size ();
3281+ return m_executedInstructionCounts .size ();
32633282}
32643283
32653284
@@ -3282,17 +3301,18 @@ bool DebuggerController::SaveCodeCoverageToFile(const std::string& filePath) con
32823301
32833302 // Write header
32843303 uint32_t magic = 0x54544443 ; // "TTDC" - TTD Coverage
3285- uint32_t version = 1 ;
3286- size_t count = m_executedInstructions .size ();
3304+ uint32_t version = 2 ;
3305+ size_t count = m_executedInstructionCounts .size ();
32873306
32883307 file.write (reinterpret_cast <const char *>(&magic), sizeof (magic));
32893308 file.write (reinterpret_cast <const char *>(&version), sizeof (version));
32903309 file.write (reinterpret_cast <const char *>(&count), sizeof (count));
32913310
3292- // Write addresses
3293- for (uint64_t addr : m_executedInstructions )
3311+ // Write addresses and execution counts in pairs
3312+ for (const auto & [ addr, execCount] : m_executedInstructionCounts )
32943313 {
32953314 file.write (reinterpret_cast <const char *>(&addr), sizeof (addr));
3315+ file.write (reinterpret_cast <const char *>(&execCount), sizeof (execCount));
32963316 }
32973317
32983318 file.close ();
@@ -3331,22 +3351,38 @@ bool DebuggerController::LoadCodeCoverageFromFile(const std::string& filePath)
33313351 }
33323352
33333353 file.read (reinterpret_cast <char *>(&version), sizeof (version));
3334- if (version != 1 )
3354+ if (version != 1 && version != 2 )
33353355 {
33363356 LogError (" %s" , fmt::format (" Unsupported file version: {}" , version).c_str ());
33373357 return false ;
33383358 }
33393359
33403360 file.read (reinterpret_cast <char *>(&count), sizeof (count));
33413361
3342- // Clear existing data and read addresses
3343- m_executedInstructions .clear ();
3362+ // Clear existing data
3363+ m_executedInstructionCounts .clear ();
33443364
3345- for (size_t i = 0 ; i < count; i++)
3365+ // Read executed instruction addresses according to version
3366+ if (version == 1 )
3367+ {
3368+ // Version 1 files don't have execution counts, so assume count = 1 for backward compatibility
3369+ for (size_t i = 0 ; i < count; i++)
3370+ {
3371+ uint64_t addr;
3372+ file.read (reinterpret_cast <char *>(&addr), sizeof (addr));
3373+ m_executedInstructionCounts[addr] = 1 ;
3374+ }
3375+ }
3376+ else if (version > 1 )
33463377 {
3347- uint64_t addr;
3348- file.read (reinterpret_cast <char *>(&addr), sizeof (addr));
3349- m_executedInstructions.insert (addr);
3378+ for (size_t i = 0 ; i < count; i++)
3379+ {
3380+ uint64_t addr;
3381+ uint32_t execCount;
3382+ file.read (reinterpret_cast <char *>(&addr), sizeof (addr));
3383+ file.read (reinterpret_cast <char *>(&execCount), sizeof (execCount));
3384+ m_executedInstructionCounts[addr] = execCount;
3385+ }
33503386 }
33513387
33523388 file.close ();
0 commit comments