refactor registers to be read lazily

This commit is contained in:
Duncan Ogilvie 2017-12-31 14:12:26 +01:00
parent 7343c99cfa
commit 3fb8539c7a
No known key found for this signature in database
GPG Key ID: FC89E0AAA0C1AAD8
4 changed files with 30 additions and 37 deletions

View File

@ -109,24 +109,23 @@ namespace GleeBug
memset(&this->mContext, 0, sizeof(CONTEXT)); memset(&this->mContext, 0, sizeof(CONTEXT));
} }
const CONTEXT* Registers::GetContext() CONTEXT* Registers::GetContext()
{ {
handleLazyContext(); handleLazyContext();
return &mContext; return &mContext;
} }
void Registers::SetContext(const CONTEXT & context) /*void Registers::SetContext(const CONTEXT & context)
{ {
handleLazyContext(); handleLazyContext();
this->mContext = context; this->mContext = context;
} }*/
void Registers::setContextLazy(CONTEXT* oldContext, HANDLE hThread) void Registers::setContextLazy(CONTEXT* oldContext, HANDLE hThread)
{ {
this->mLazyOldContext = oldContext; this->mLazyOldContext = oldContext;
this->mLazyThread = hThread; this->mLazyThread = hThread;
this->mLazySet = true; this->mLazySet = true;
this->mContext = *this->mLazyOldContext;
} }
bool Registers::handleLazyContext() bool Registers::handleLazyContext()

View File

@ -162,13 +162,13 @@ namespace GleeBug
\brief Gets a pointer to the context object. \brief Gets a pointer to the context object.
\return This function will never return a nullptr. \return This function will never return a nullptr.
*/ */
const CONTEXT* GetContext(); CONTEXT* GetContext();
/** /**
\brief Sets the CONTEXT. \brief Sets the CONTEXT.
\param context The context to set. \param context The context to set.
*/ */
void SetContext(const CONTEXT & context); //void SetContext(const CONTEXT & context);
private: private:
CONTEXT mContext; CONTEXT mContext;

View File

@ -17,19 +17,14 @@ namespace GleeBug
{ {
memset(&this->mOldContext, 0, sizeof(CONTEXT)); memset(&this->mOldContext, 0, sizeof(CONTEXT));
this->mOldContext.ContextFlags = CONTEXT_ALL; //TODO: granular control over what's required this->mOldContext.ContextFlags = CONTEXT_ALL; //TODO: granular control over what's required
if(GetThreadContext(this->hThread, &this->mOldContext)) this->registers.setContextLazy(&this->mOldContext, this->hThread);
{ return true;
this->registers.SetContext(this->mOldContext);
return true;
}
__debugbreak();
return false;
} }
bool Thread::RegWriteContext() bool Thread::RegWriteContext()
{ {
//check if something actually changed //check if something actually changed
if (memcmp(&this->mOldContext, &this->registers.mContext, sizeof(CONTEXT)) == 0) if (this->registers.mLazySet || memcmp(&this->mOldContext, &this->registers.mContext, sizeof(CONTEXT)) == 0)
return true; return true;
//update the context //update the context
if(SetThreadContext(this->hThread, &this->registers.mContext)) if(SetThreadContext(this->hThread, &this->registers.mContext))

View File

@ -655,44 +655,43 @@ public:
thread->registers.Cs = titcontext->cs; thread->registers.Cs = titcontext->cs;
thread->registers.Ss = titcontext->ss; thread->registers.Ss = titcontext->ss;
// x87 // x87
auto context = *(thread->registers.GetContext()); auto context = thread->registers.GetContext();
#ifdef _WIN64 #ifdef _WIN64
context.FltSave.ControlWord = titcontext->x87fpu.ControlWord; context->FltSave.ControlWord = titcontext->x87fpu.ControlWord;
context.FltSave.StatusWord = titcontext->x87fpu.StatusWord; context->FltSave.StatusWord = titcontext->x87fpu.StatusWord;
context.FltSave.TagWord = FsaveToFxsaveTagWord(titcontext->x87fpu.TagWord); context->FltSave.TagWord = FsaveToFxsaveTagWord(titcontext->x87fpu.TagWord);
context.FltSave.ErrorSelector = (WORD)titcontext->x87fpu.ErrorSelector; context->FltSave.ErrorSelector = (WORD)titcontext->x87fpu.ErrorSelector;
context.FltSave.ErrorOffset = titcontext->x87fpu.ErrorOffset; context->FltSave.ErrorOffset = titcontext->x87fpu.ErrorOffset;
context.FltSave.DataSelector = (WORD)titcontext->x87fpu.DataSelector; context->FltSave.DataSelector = (WORD)titcontext->x87fpu.DataSelector;
context.FltSave.DataOffset = titcontext->x87fpu.DataOffset; context->FltSave.DataOffset = titcontext->x87fpu.DataOffset;
// Skip titcontext->x87fpu.Cr0NpxState // Skip titcontext->x87fpu.Cr0NpxState
context.MxCsr = titcontext->MxCsr; context->MxCsr = titcontext->MxCsr;
for(int i = 0; i < 8; i++) for(int i = 0; i < 8; i++)
memcpy(&context.FltSave.FloatRegisters[i], &(titcontext->RegisterArea[i * 10]), 10); memcpy(&context->FltSave.FloatRegisters[i], &(titcontext->RegisterArea[i * 10]), 10);
for(int i = 0; i < 16; i++) for(int i = 0; i < 16; i++)
memcpy(&(context.FltSave.XmmRegisters[i]), &(titcontext->XmmRegisters[i]), 16); memcpy(&(context->FltSave.XmmRegisters[i]), &(titcontext->XmmRegisters[i]), 16);
#else //x86 #else //x86
context.FloatSave.ControlWord = titcontext->x87fpu.ControlWord; context->FloatSave.ControlWord = titcontext->x87fpu.ControlWord;
context.FloatSave.StatusWord = titcontext->x87fpu.StatusWord; context->FloatSave.StatusWord = titcontext->x87fpu.StatusWord;
context.FloatSave.TagWord = titcontext->x87fpu.TagWord; context->FloatSave.TagWord = titcontext->x87fpu.TagWord;
context.FloatSave.ErrorSelector = titcontext->x87fpu.ErrorSelector; context->FloatSave.ErrorSelector = titcontext->x87fpu.ErrorSelector;
context.FloatSave.ErrorOffset = titcontext->x87fpu.ErrorOffset; context->FloatSave.ErrorOffset = titcontext->x87fpu.ErrorOffset;
context.FloatSave.DataSelector = titcontext->x87fpu.DataSelector; context->FloatSave.DataSelector = titcontext->x87fpu.DataSelector;
context.FloatSave.DataOffset = titcontext->x87fpu.DataOffset; context->FloatSave.DataOffset = titcontext->x87fpu.DataOffset;
context.FloatSave.Cr0NpxState = titcontext->x87fpu.Cr0NpxState; context->FloatSave.Cr0NpxState = titcontext->x87fpu.Cr0NpxState;
memcpy(context.FloatSave.RegisterArea, titcontext->RegisterArea, 80); memcpy(context->FloatSave.RegisterArea, titcontext->RegisterArea, 80);
// MXCSR ExtendedRegisters[24] // MXCSR ExtendedRegisters[24]
memcpy(&(context.ExtendedRegisters[24]), &titcontext->MxCsr, sizeof(titcontext->MxCsr)); memcpy(&(context->ExtendedRegisters[24]), &titcontext->MxCsr, sizeof(titcontext->MxCsr));
// for x86 copy the 8 Xmm Registers from ExtendedRegisters[(10+n)*16]; (n is the index of the xmm register) to the XMM register // for x86 copy the 8 Xmm Registers from ExtendedRegisters[(10+n)*16]; (n is the index of the xmm register) to the XMM register
for(int i = 0; i < 8; i++) for(int i = 0; i < 8; i++)
memcpy(&context.ExtendedRegisters[(10 + i) * 16], &(titcontext->XmmRegisters[i]), 16); memcpy(&context->ExtendedRegisters[(10 + i) * 16], &(titcontext->XmmRegisters[i]), 16);
#endif //_WIN64 #endif //_WIN64
//TODO: AVX //TODO: AVX
thread->registers.SetContext(context);
return true; return true;
} }