From 71401b0731594c6a54b73bfa17a6cb38ae15919e Mon Sep 17 00:00:00 2001 From: TuxSH <1922548+TuxSH@users.noreply.github.com> Date: Tue, 28 Jan 2020 01:13:21 +0000 Subject: [PATCH] thermosphere: add structural changes needed for range step --- thermosphere/src/core_ctx.h | 2 ++ thermosphere/src/debug_manager.c | 16 ++++++++++++++-- thermosphere/src/debug_manager.h | 2 ++ thermosphere/src/single_step.c | 13 +++++++++++-- 4 files changed, 29 insertions(+), 4 deletions(-) diff --git a/thermosphere/src/core_ctx.h b/thermosphere/src/core_ctx.h index 974688d1c..fbd4392b1 100644 --- a/thermosphere/src/core_ctx.h +++ b/thermosphere/src/core_ctx.h @@ -35,6 +35,8 @@ typedef struct ALIGN(64) CoreCtx { // Debug features bool wasPaused; // @0x1F + uintptr_t steppingRangeStartAddr; // @0x20 + uintptr_t steppingRangeEndAddr; // @0x28 // Most likely written to: diff --git a/thermosphere/src/debug_manager.c b/thermosphere/src/debug_manager.c index 66074762c..dc4a091fb 100644 --- a/thermosphere/src/debug_manager.c +++ b/thermosphere/src/debug_manager.c @@ -29,6 +29,8 @@ GDBContext g_gdbContext = { 0 }; typedef struct DebugManager { DebugEventInfo debugEventInfos[MAX_CORE]; + uintptr_t steppingRangeStartAddrs[MAX_CORE]; + uintptr_t steppingRangeEndAddrs[MAX_CORE]; ALIGN(64) atomic_uint pausedCoreList; atomic_uint singleStepCoreList; @@ -94,8 +96,12 @@ bool debugManagerHandlePause(void) // Single-step: if inactive and requested, start single step; cancel if active and not requested u32 ssReqd = (atomic_load(&g_debugManager.singleStepCoreList) & BIT(currentCoreCtx->coreId)) != 0; SingleStepState singleStepState = singleStepGetNextState(currentCoreCtx->guestFrame); - if (ssReqd && singleStepState == SingleStepState_Inactive) { - singleStepSetNextState(currentCoreCtx->guestFrame, SingleStepState_ActiveNotPending); + if (ssReqd) { + currentCoreCtx->steppingRangeStartAddr = g_debugManager.steppingRangeStartAddrs[coreId]; + currentCoreCtx->steppingRangeEndAddr = g_debugManager.steppingRangeEndAddrs[coreId]; + if(singleStepState == SingleStepState_Inactive) { + singleStepSetNextState(currentCoreCtx->guestFrame, SingleStepState_ActiveNotPending); + } } else if (!ssReqd && singleStepState != SingleStepState_Inactive) { singleStepSetNextState(currentCoreCtx->guestFrame, SingleStepState_Inactive); } @@ -128,6 +134,12 @@ void debugManagerUnpauseCores(u32 coreList, u32 singleStepList) __sev(); } +void debugManagerSetSteppingRange(u32 coreId, uintptr_t startAddr, uintptr_t endAddr) +{ + g_debugManager.steppingRangeStartAddrs[coreId] = startAddr; + g_debugManager.steppingRangeEndAddrs[coreId] = endAddr; +} + u32 debugManagerGetPausedCoreList(void) { return atomic_load(&g_debugManager.pausedCoreList); diff --git a/thermosphere/src/debug_manager.h b/thermosphere/src/debug_manager.h index 07df9640e..dab24e9de 100644 --- a/thermosphere/src/debug_manager.h +++ b/thermosphere/src/debug_manager.h @@ -57,6 +57,8 @@ bool debugManagerHandlePause(void); void debugManagerPauseCores(u32 coreList); void debugManagerUnpauseCores(u32 coreList, u32 singleStepList); +void debugManagerSetSteppingRange(u32 coreId, uintptr_t startAddr, uintptr_t endAddr); + u32 debugManagerGetPausedCoreList(void); const DebugEventInfo *debugManagerMarkAndGetCoreDebugEvent(u32 coreId); diff --git a/thermosphere/src/single_step.c b/thermosphere/src/single_step.c index cbeb84202..582cf24fe 100644 --- a/thermosphere/src/single_step.c +++ b/thermosphere/src/single_step.c @@ -62,8 +62,17 @@ void singleStepSetNextState(ExceptionStackFrame *frame, SingleStepState state) void handleSingleStep(ExceptionStackFrame *frame, ExceptionSyndromeRegister esr) { - // Disable single-step ASAP - singleStepSetNextState(NULL, SingleStepState_Inactive); + uintptr_t addr = frame->elr_el2; + + // Stepping range support; + if (addr >= currentCoreCtx->steppingRangeStartAddr && addr < currentCoreCtx->steppingRangeEndAddr) { + // Reactivate single-step + singleStepSetNextState(frame, SingleStepState_ActiveNotPending); + } else { + // Disable single-step + singleStepSetNextState(frame, SingleStepState_Inactive); + // TODO report exception to gdb + } DEBUG("Single-step exeception ELR = 0x%016llx, ISV = %u, EX = %u\n", frame->elr_el2, (esr.iss >> 24) & 1, (esr.iss >> 6) & 1); }