1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-08 03:28:20 +02:00

Fixed some Win32 and chkstk rollback issues

This commit is contained in:
Brian Fiete 2019-09-05 11:09:13 -07:00
parent 0ce6e44523
commit 8c21f24867
6 changed files with 86 additions and 46 deletions

View file

@ -16550,6 +16550,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
}
else if (methodDef->mMethodType == BfMethodType_CtorClear)
{
SetIllegalSrcPos();
mBfIRBuilder->ClearDebugLocation();
PopulateType(mCurTypeInstance, BfPopulateType_Data);
auto thisVal = GetThis();

View file

@ -2024,6 +2024,19 @@ bool DebugTarget::RollBackStackFrame_COFFFrameDescriptor(CPURegisters* registers
return false;
}
bool DebugTarget::RollBackStackFrame_SimpleRet(CPURegisters* registers)
{
int regSize = sizeof(addr_target);
addr_target* regPC = registers->GetPCRegisterRef();
addr_target* regSP = registers->GetSPRegisterRef();
addr_target newPC = 0;
gDebugger->ReadMemory(*regSP, sizeof(addr_target), &newPC);
*regSP += regSize;
*regPC = newPC;
return true;
}
bool DebugTarget::RollBackStackFrame(CPURegisters* registers, addr_target* outReturnAddressLoc, bool isStackStart)
{
if (outReturnAddressLoc != NULL)
@ -2036,16 +2049,7 @@ bool DebugTarget::RollBackStackFrame(CPURegisters* registers, addr_target* outRe
{
// If we are literally just a return then often the frame descriptor is wrong,
// but we know this is ACTUALLY just a simple rollback
int regSize = sizeof(addr_target);
addr_target* regPC = registers->GetPCRegisterRef();
addr_target* regSP = registers->GetSPRegisterRef();
addr_target newPC = 0;
gDebugger->ReadMemory(*regSP, sizeof(addr_target), &newPC);
*regSP += regSize;
*regPC = newPC;
return true;
return RollBackStackFrame_SimpleRet(registers);
}
}
@ -2058,6 +2062,9 @@ bool DebugTarget::RollBackStackFrame(CPURegisters* registers, addr_target* outRe
DbgSubprogram* dbgSubprogram = FindSubProgram(pc);
if (dbgSubprogram != NULL)
{
if (pc == dbgSubprogram->mBlock.mLowPC)
return RollBackStackFrame_SimpleRet(registers);
auto dbgModule = dbgSubprogram->mCompileUnit->mDbgModule;
if ((dbgModule != NULL) && (!dbgModule->mParsedFrameDescriptors))
{
@ -2066,6 +2073,10 @@ bool DebugTarget::RollBackStackFrame(CPURegisters* registers, addr_target* outRe
return true;
}
}
else
{
return RollBackStackFrame_SimpleRet(registers);
}
#endif
// Fall through after this, we need to process a 'return'

View file

@ -65,6 +65,7 @@ protected:
bool RollBackStackFrame_ExceptionDirectory(CPURegisters* registers, addr_target* outReturnAddressLoc, bool& alreadyRolledBackPC);
bool RollBackStackFrame_DwFrameDescriptor(CPURegisters* registers, addr_target* outReturnAddressLoc);
bool RollBackStackFrame_COFFFrameDescriptor(CPURegisters* registers, addr_target* outReturnAddressLoc, bool isStackStart);
bool RollBackStackFrame_SimpleRet(CPURegisters* registers);
bool PropogateRegisterUpCallStack_ExceptionDirectory(addr_target findPC, CPURegisters* callerRegisters, CPURegisters* calleeRegisters, void* regPtr, bool& wasSaved);
void RemoveTargetData();
bool GetValueByNameInBlock_Helper(DbgSubprogram* dwSubprogram, DbgBlock* dwBlock, String& name, WdStackFrame* stackFrame, intptr* outAddr, DbgType** outType, DbgAddrType* outAddrType);

View file

@ -4276,8 +4276,24 @@ bool WinDebugger::SetupStep(StepType stepType)
if ((mStepType != StepType_StepOut_NoFrame) && (RollBackStackFrame(&registers, true)))
{
pcAddress = registers.GetPC();
bool isStackAdjust = false;
DbgSubprogram* dwSubprogram = mDebugTarget->FindSubProgram(pcAddress);
if (dwSubprogram != NULL)
{
if ((strcmp(dwSubprogram->mName, "_chkstk") == 0) ||
(strcmp(dwSubprogram->mName, "__chkstk") == 0) ||
(strcmp(dwSubprogram->mName, "_alloca_probe") == 0))
isStackAdjust = true;
}
pcAddress = registers.GetPC();
if (isStackAdjust)
{
// We set it to zero so we never detect an "isDeeper" condition which would skip over the return-location breakpoint
mStepSP = 0;
}
else
{
addr_target oldAddress = pcAddress;
CPUInst inst;
@ -4287,6 +4303,10 @@ bool WinDebugger::SetupStep(StepType stepType)
break;
if ((inst.IsBranch()) || (inst.IsCall()) || (inst.IsReturn()))
break;
#ifdef BF_DBG_32
if (!inst.StackAdjust(mStepSP))
break;
#endif
DbgSubprogram* checkSubprogram = NULL;
auto checkLineData = FindLineDataAtAddress(pcAddress, &checkSubprogram, NULL, NULL, DbgOnDemandKind_LocalOnly);
if (checkLineData == NULL)
@ -4300,18 +4320,7 @@ bool WinDebugger::SetupStep(StepType stepType)
{
BfLogDbg("Adjusting stepout address from %p to %p\n", oldAddress, pcAddress);
}
#ifdef BF_DBG_32
// if (mDebugTarget->DecodeInstruction(pcAddress, &inst))
// {
// if (inst.IsStackAdjust())
// {
// auto oldAddress = pcAddress;
// pcAddress += inst.GetLength();
// BfLogDbg("Adjusting stepout address from %p to %p\n", oldAddress, pcAddress);
// }
// }
#endif
}
BfLogDbg("SetupStep Stepout SetTempBreakpoint %p\n", pcAddress);
SetTempBreakpoint(pcAddress);
@ -4416,6 +4425,9 @@ bool WinDebugger::SetupStep(StepType stepType)
if ((inst.IsReturn()) && (instIdx == 0) && (!mStepInAssembly))
{
// Do actual STEP OUT so we set up proper "stepping over unimportant post-return instructions"
if (stepType == StepType_StepInto)
return SetupStep(StepType_StepOut_ThenInto);
else
return SetupStep(StepType_StepOut);
}

View file

@ -151,9 +151,24 @@ int X86Instr::GetLength()
return mSize;
}
bool X86Instr::IsStackAdjust()
bool X86Instr::StackAdjust(uint32& adjust)
{
return mMCInst.getOpcode() == X86::SUB32ri8;
if (adjust == 0)
return true;
if (mMCInst.getOpcode() != X86::SUB32ri8)
return true;
auto operand0 = mMCInst.getOperand(0);
if (operand0.getReg() != llvm::X86::ESP)
return true;
auto operand2 = mMCInst.getOperand(2);
if (!operand2.isImm())
return false;
adjust -= (uint32)operand2.getImm();
return true;
}
bool X86Instr::IsBranch()

View file

@ -292,7 +292,7 @@ public:
}
int GetLength();
bool IsStackAdjust();
bool StackAdjust(uint32& adjust);
bool IsBranch();
bool IsCall();
bool IsRep(bool& isPrefixOnly);