Skip to content

Commit

Permalink
k i think this is enough to trace through a testcase w/o tracing thro…
Browse files Browse the repository at this point in the history
…ugh interrupts
  • Loading branch information
0vercl0k committed May 12, 2024
1 parent 06101a5 commit 3c57d0c
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 36 deletions.
2 changes: 1 addition & 1 deletion src/wtf/ram.h
Expand Up @@ -13,7 +13,7 @@ struct Page {
// Page size.
//

static constexpr uint64_t Size = 0x1000;
static constexpr uint64_t Size = 0x1'000;
};

//
Expand Down
84 changes: 49 additions & 35 deletions src/wtf/whv_backend.cc
Expand Up @@ -7,7 +7,7 @@
#include <algorithm>
#include <fstream>

constexpr bool WhvLoggingOn = true;
constexpr bool WhvLoggingOn = false;

template <typename... Args_t>
void WhvDebugPrint(const char *Format, const Args_t &...args) {
Expand Down Expand Up @@ -1136,49 +1136,63 @@ WhvBackend_t::OnDebugTrap(const WHV_RUN_VP_EXIT_CONTEXT &Exception) {
// to continue execution.
//

if (LastBreakpointGpa_ == Gpa_t(0xffffffffffffffff)) {
if (TraceType_ == TraceType_t::Rip) {
bool StripTrapFlag = true;

//
// OK we got here because we are single stepping through the testcase.
//
WhvDebugPrint("Received debug trap @ {:#x}\n", Exception.VpContext.Rip);

if (TraceType_ == TraceType_t::Rip) {

//
// OK we got here because we are single stepping through the testcase.
//

WHV_X64_INTERRUPT_STATE_REGISTER InterruptState;
InterruptState.AsUINT64 = GetReg64(WHvRegisterInterruptState);
InterruptState.InterruptShadow = 0;
if (FAILED(
SetReg64(WHvRegisterInterruptState, InterruptState.AsUINT64))) {
fmt::print("Failed to set WHvRegisterInterruptState\n");
std::abort();
}

fmt::print(TraceFile_, "{:#x}\n", Exception.VpContext.Rip,
GetReg64(WHvX64RegisterRflags));
return SetReg64(WHvX64RegisterRflags,
Exception.VpContext.Rflags | RFLAGS_TRAP_FLAG_FLAG);
WHV_X64_INTERRUPT_STATE_REGISTER InterruptState;
InterruptState.AsUINT64 = GetReg64(WHvRegisterInterruptState);
InterruptState.InterruptShadow = 0;
const HRESULT Hr =
SetReg64(WHvRegisterInterruptState, InterruptState.AsUINT64);
if (FAILED(Hr)) {
fmt::print("Failed to set WHvRegisterInterruptState\n");
return Hr;
}

fmt::print(
"Got into OnDebugTrap with LastBreakpointGpa_ = 0xffffffffffffffff");
std::abort();
}
fmt::print(TraceFile_, "{:#x}\n", Exception.VpContext.Rip,
GetReg64(WHvX64RegisterRflags));

//
// Remember if we get there, it is because we hit a breakpoint, turned on
// TF in order to step over the instruction, and now we get the chance to
// turn it back on.
//
StripTrapFlag = false;
} else {
if (LastBreakpointGpa_ == Gpa_t(0xffffffffffffffff)) {
fmt::print(
"Got into OnDebugTrap with LastBreakpointGpa_ = 0xffffffffffffffff");
std::abort();
}

Ram_.AddBreakpoint(LastBreakpointGpa_);
WhvDebugPrint("Resetting breakpoint @ {:#x}", LastBreakpointGpa_);

//
// Strip TF off Rflags.
//
//
// Remember if we get there, it is because we hit a breakpoint, turned on
// TF in order to step over the instruction, and now we get the chance to
// turn it back on.
//

Ram_.AddBreakpoint(LastBreakpointGpa_);

WhvDebugPrint("Turning off RFLAGS.TF\n");
LastBreakpointGpa_ = Gpa_t(0xffffffffffffffff);
//
// Either strip or turn on TF.
//

LastBreakpointGpa_ = Gpa_t(0xffffffffffffffff);
}

if (StripTrapFlag) {
WhvDebugPrint("Turning off RFLAGS.TF\n");
return SetReg64(WHvX64RegisterRflags,
Exception.VpContext.Rflags & (~RFLAGS_TRAP_FLAG_FLAG));
}

WhvDebugPrint("Setting RFLAGS.TF\n");
return SetReg64(WHvX64RegisterRflags,
Exception.VpContext.Rflags & (~RFLAGS_TRAP_FLAG_FLAG));
Exception.VpContext.Rflags | RFLAGS_TRAP_FLAG_FLAG);
}

HRESULT
Expand Down

0 comments on commit 3c57d0c

Please sign in to comment.