diff --git a/IDEHelper/COFF.cpp b/IDEHelper/COFF.cpp index 682199df..fca3e25d 100644 --- a/IDEHelper/COFF.cpp +++ b/IDEHelper/COFF.cpp @@ -2635,6 +2635,7 @@ void COFF::ParseCompileUnit_Symbols(DbgCompileUnit* compileUnit, uint8* sectionD // } curSubprogram->mFrameBaseLen = frameProc->cbFrame + frameProc->cbSaveRegs; + curSubprogram->mParamBaseReg = (DbgSubprogram::LocalBaseRegKind)(uint8)frameProc->flags.encodedParamBasePointer; curSubprogram->mLocalBaseReg = (DbgSubprogram::LocalBaseRegKind)(uint8)frameProc->flags.encodedLocalBasePointer; } } @@ -6003,10 +6004,10 @@ void COFF::FinishHotSwap() mTypeMap.Clear(); } -addr_target COFF::EvaluateLocation(DbgSubprogram* dwSubprogram, const uint8* locData, int locDataLen, WdStackFrame* stackFrame, DbgAddrType* outAddrType, bool allowReg) +addr_target COFF::EvaluateLocation(DbgSubprogram* dwSubprogram, const uint8* locData, int locDataLen, WdStackFrame* stackFrame, DbgAddrType* outAddrType, DbgEvalLocFlags flags) { if (mDbgFlavor == DbgFlavor_GNU) - return DbgModule::EvaluateLocation(dwSubprogram, locData, locDataLen, stackFrame, outAddrType, allowReg); + return DbgModule::EvaluateLocation(dwSubprogram, locData, locDataLen, stackFrame, outAddrType, flags); addr_target pc = 0; if (stackFrame != NULL) @@ -6104,30 +6105,20 @@ addr_target COFF::EvaluateLocation(DbgSubprogram* dwSubprogram, const uint8* loc { DEFRANGESYMFRAMEPOINTERREL& defRangeFPRel = *(DEFRANGESYMFRAMEPOINTERREL*)dataStart; + DbgSubprogram::LocalBaseRegKind baseReg = ((flags & DbgEvalLocFlag_IsParam) != 0) ? dwSubprogram->mParamBaseReg : dwSubprogram->mLocalBaseReg; + *outAddrType = DbgAddrType_Target; #ifdef BF_DBG_64 - if (dwSubprogram->mLocalBaseReg == DbgSubprogram::LocalBaseRegKind_RSP) + if (baseReg == DbgSubprogram::LocalBaseRegKind_RSP) result = stackFrame->mRegisters.mIntRegsArray[X64Reg_RSP] + defRangeFPRel.offFramePointer; - else if (dwSubprogram->mLocalBaseReg == DbgSubprogram::LocalBaseRegKind_R13) + else if (baseReg == DbgSubprogram::LocalBaseRegKind_R13) result = stackFrame->mRegisters.mIntRegsArray[X64Reg_R13] + defRangeFPRel.offFramePointer; else result = stackFrame->mRegisters.mIntRegsArray[X64Reg_RBP] + defRangeFPRel.offFramePointer; #else - if (dwSubprogram->mLocalBaseReg == DbgSubprogram::LocalBaseRegKind_VFRAME) - { - if (defRangeFPRel.offFramePointer > 0) - { - // Note that a positive offFramePointer always refers to params, and param fp reg is always EBP-relative. - // If this is not true in some cases then we need to actually pass in knowledge of whether is loc data is - // from a param or not, and we have to store the param fp reg just like the local fp reg (mLocalBaseReg) - result = stackFrame->mRegisters.mIntRegsArray[X86Reg_EBP] + defRangeFPRel.offFramePointer; - } - else - result = stackFrame->mRegisters.mIntRegsArray[X86Reg_ESP] + dwSubprogram->mFrameBaseLen + defRangeFPRel.offFramePointer; - //result = stackFrame->mRegisters.mIntRegsArray[X86Reg_EBP] + defRangeFPRel.offFramePointer; - //result = ((stackFrame->mRegisters.mIntRegsArray[X86Reg_ESP] + dwSubprogram->mFrameBaseLen) & ~7) + defRangeFPRel.offFramePointer; - } - else if (dwSubprogram->mLocalBaseReg == DbgSubprogram::LocalBaseRegKind_EBX) + if (baseReg == DbgSubprogram::LocalBaseRegKind_VFRAME) + result = stackFrame->mRegisters.mIntRegsArray[X86Reg_ESP] + dwSubprogram->mFrameBaseLen + defRangeFPRel.offFramePointer; + else if (baseReg == DbgSubprogram::LocalBaseRegKind_EBX) result = stackFrame->mRegisters.mIntRegsArray[X86Reg_EBX] + defRangeFPRel.offFramePointer; else result = stackFrame->mRegisters.mIntRegsArray[X86Reg_EBP] + defRangeFPRel.offFramePointer; diff --git a/IDEHelper/COFF.h b/IDEHelper/COFF.h index 095af709..15921a23 100644 --- a/IDEHelper/COFF.h +++ b/IDEHelper/COFF.h @@ -312,7 +312,7 @@ public: virtual void PopulateStaticVariableMap() override; virtual void ProcessDebugInfo() override; virtual void FinishHotSwap() override; - virtual addr_target EvaluateLocation(DbgSubprogram* dwSubprogram, const uint8* locData, int locDataLen, WdStackFrame* stackFrame, DbgAddrType* outAddrType, bool allowReg) override; + virtual addr_target EvaluateLocation(DbgSubprogram* dwSubprogram, const uint8* locData, int locDataLen, WdStackFrame* stackFrame, DbgAddrType* outAddrType, DbgEvalLocFlags flags = DbgEvalLocFlag_None) override; virtual bool CanGetOldSource() override; virtual String GetOldSourceCommand(const StringImpl& path) override; virtual bool HasPendingDebugInfo() override; diff --git a/IDEHelper/Compiler/BfStmtEvaluator.cpp b/IDEHelper/Compiler/BfStmtEvaluator.cpp index 718b95ab..aa204950 100644 --- a/IDEHelper/Compiler/BfStmtEvaluator.cpp +++ b/IDEHelper/Compiler/BfStmtEvaluator.cpp @@ -6145,19 +6145,26 @@ void BfModule::Visit(BfForEachStatement* forEachStmt) BfMethodMatcher methodMatcher(forEachStmt->mVariableName, this, "get__", argValues.mResolvedArgs, NULL); methodMatcher.mMethodType = BfMethodType_PropertyGetter; methodMatcher.CheckType(target.mType->ToTypeInstance(), target, false); - methodMatcher.mCheckedKind = boundsCheck ? BfCheckedKind_Checked : BfCheckedKind_Unchecked; - BfTypedValue arrayItem = exprEvaluator.CreateCall(&methodMatcher, target); - - if ((varInst) && (arrayItem)) + if (methodMatcher.mBestMethodDef == NULL) { - if (isRefExpression) - arrayItem = BfTypedValue(arrayItem.mValue, CreateRefType(arrayItem.mType)); - else if (!arrayItem.mType->IsComposite()) + Fail("Failed to find indexer method in array", forEachStmt); + } + else + { + methodMatcher.mCheckedKind = boundsCheck ? BfCheckedKind_Checked : BfCheckedKind_Unchecked; + BfTypedValue arrayItem = exprEvaluator.CreateCall(&methodMatcher, target); + + if ((varInst) && (arrayItem)) + { + if (isRefExpression) + arrayItem = BfTypedValue(arrayItem.mValue, CreateRefType(arrayItem.mType)); + else if (!arrayItem.mType->IsComposite()) + arrayItem = LoadValue(arrayItem); + arrayItem = Cast(forEachStmt->mCollectionExpression, arrayItem, varType, BfCastFlags_Explicit); arrayItem = LoadValue(arrayItem); - arrayItem = Cast(forEachStmt->mCollectionExpression, arrayItem, varType, BfCastFlags_Explicit); - arrayItem = LoadValue(arrayItem); - if (arrayItem) - mBfIRBuilder->CreateStore(arrayItem.mValue, varInst); + if (arrayItem) + mBfIRBuilder->CreateStore(arrayItem.mValue, varInst); + } } } else diff --git a/IDEHelper/DbgModule.cpp b/IDEHelper/DbgModule.cpp index 5b3cba53..7d252b95 100644 --- a/IDEHelper/DbgModule.cpp +++ b/IDEHelper/DbgModule.cpp @@ -6425,8 +6425,10 @@ void DbgModule::FinishHotSwap() mSymbolNameMap.Clear(); } -addr_target DbgModule::ExecuteOps(DbgSubprogram* dwSubprogram, const uint8* locData, int locDataLen, WdStackFrame* stackFrame, CPURegisters* registers, DbgAddrType* outAddrType, bool allowReg, addr_target* pushValue) +addr_target DbgModule::ExecuteOps(DbgSubprogram* dwSubprogram, const uint8* locData, int locDataLen, WdStackFrame* stackFrame, CPURegisters* registers, DbgAddrType* outAddrType, DbgEvalLocFlags flags, addr_target* pushValue) { + bool allowReg = (flags & DbgEvalLocFlag_IsParam) == 0; + const uint8* locDataEnd = locData + locDataLen; int regNum = -1; @@ -6507,7 +6509,7 @@ addr_target DbgModule::ExecuteOps(DbgSubprogram* dwSubprogram, const uint8* locD } BF_ASSERT(nonInlinedSubProgram->mFrameBaseData != NULL); - uint64 loc = EvaluateLocation(nonInlinedSubProgram, nonInlinedSubProgram->mFrameBaseData, nonInlinedSubProgram->mFrameBaseLen, stackFrame, outAddrType, false); + uint64 loc = EvaluateLocation(nonInlinedSubProgram, nonInlinedSubProgram->mFrameBaseData, nonInlinedSubProgram->mFrameBaseLen, stackFrame, outAddrType, DbgEvalLocFlag_DisallowReg); int64 offset = DecodeSLEB128(locData); loc += offset; //loc = BfDebuggerReadMemory(loc); @@ -6631,7 +6633,7 @@ addr_target DbgModule::ExecuteOps(DbgSubprogram* dwSubprogram, const uint8* locD return stackFrameData[--stackIdx]; } -addr_target DbgModule::EvaluateLocation(DbgSubprogram* dwSubprogram, const uint8* locData, int locDataLen, WdStackFrame* stackFrame, DbgAddrType* outAddrType, bool allowReg) +addr_target DbgModule::EvaluateLocation(DbgSubprogram* dwSubprogram, const uint8* locData, int locDataLen, WdStackFrame* stackFrame, DbgAddrType* outAddrType, DbgEvalLocFlags flags) { BP_ZONE("DebugTarget::EvaluateLocation"); @@ -6725,7 +6727,7 @@ addr_target DbgModule::EvaluateLocation(DbgSubprogram* dwSubprogram, const uint8 } } - return ExecuteOps(dwSubprogram, locData, locDataLen, stackFrame, registers, outAddrType, allowReg); + return ExecuteOps(dwSubprogram, locData, locDataLen, stackFrame, registers, outAddrType, flags); } void DbgModule::ProcessHotSwapVariables() diff --git a/IDEHelper/DbgModule.h b/IDEHelper/DbgModule.h index 930a1e02..642e1194 100644 --- a/IDEHelper/DbgModule.h +++ b/IDEHelper/DbgModule.h @@ -384,6 +384,7 @@ public: int mDeferredInternalsSize; int mVTableLoc; int mStepFilterVersion; + LocalBaseRegKind mParamBaseReg; LocalBaseRegKind mLocalBaseReg; bool mHasQualifiedName; bool mIsStepFiltered; @@ -1086,6 +1087,13 @@ enum DbgModuleLoadState DbgModuleLoadState_Loaded }; +enum DbgEvalLocFlags +{ + DbgEvalLocFlag_None = 0, + DbgEvalLocFlag_DisallowReg = 1, + DbgEvalLocFlag_IsParam = 2 +}; + struct DbgSizedArrayEntry { DbgType* mElementType; @@ -1286,8 +1294,8 @@ public: int64 GetImageSize(); virtual void FinishHotSwap(); - addr_target ExecuteOps(DbgSubprogram* dwSubprogram, const uint8* locData, int locDataLen, WdStackFrame* stackFrame, CPURegisters* registers, DbgAddrType* outAddrType, bool allowReg, addr_target* pushValue = NULL); - virtual addr_target EvaluateLocation(DbgSubprogram* dwSubprogram, const uint8* locData, int locDataLen, WdStackFrame* stackFrame, DbgAddrType* outAddrType, bool allowReg = true); + addr_target ExecuteOps(DbgSubprogram* dwSubprogram, const uint8* locData, int locDataLen, WdStackFrame* stackFrame, CPURegisters* registers, DbgAddrType* outAddrType, DbgEvalLocFlags flags, addr_target* pushValue = NULL); + virtual addr_target EvaluateLocation(DbgSubprogram* dwSubprogram, const uint8* locData, int locDataLen, WdStackFrame* stackFrame, DbgAddrType* outAddrType, DbgEvalLocFlags flags = DbgEvalLocFlag_None); //const uint8* CopyOrigImageData(addr_target address, int length); diff --git a/IDEHelper/DebugTarget.cpp b/IDEHelper/DebugTarget.cpp index 15f0d31d..2e4e21b4 100644 --- a/IDEHelper/DebugTarget.cpp +++ b/IDEHelper/DebugTarget.cpp @@ -1699,7 +1699,7 @@ bool DebugTarget::RollBackStackFrame_DwFrameDescriptor(CPURegisters* registers, { int blockLen = (int)DecodeULEB128(data); DbgAddrType addrType; - state->mCFA = dwFrameDescriptor->mCommonFrameDescriptor->mDbgModule->ExecuteOps(NULL, data, blockLen , NULL, registers, &addrType, true, &state->mCFA); + state->mCFA = dwFrameDescriptor->mCommonFrameDescriptor->mDbgModule->ExecuteOps(NULL, data, blockLen , NULL, registers, &addrType, DbgEvalLocFlag_None, &state->mCFA); } break; case DW_CFA_expression: @@ -1766,7 +1766,7 @@ bool DebugTarget::RollBackStackFrame_DwFrameDescriptor(CPURegisters* registers, case DW_CFA_expression: { DbgAddrType addrType; - registers->mIntRegsArray[registerNum] = dwFrameDescriptor->mCommonFrameDescriptor->mDbgModule->ExecuteOps(NULL, registerRuleData->mParamData, registerRuleData->mParamOffset, NULL, registers, &addrType, true, &state->mCFA); + registers->mIntRegsArray[registerNum] = dwFrameDescriptor->mCommonFrameDescriptor->mDbgModule->ExecuteOps(NULL, registerRuleData->mParamData, registerRuleData->mParamOffset, NULL, registers, &addrType, DbgEvalLocFlag_None, &state->mCFA); } break; default: @@ -2372,7 +2372,7 @@ bool DebugTarget::GetValueByNameInBlock_Helper(DbgSubprogram* dwSubprogram, DbgB return false; } - *outAddr = variable->mCompileUnit->mDbgModule->EvaluateLocation(dwSubprogram, variable->mLocationData, variable->mLocationLen, stackFrame, outAddrType); + *outAddr = variable->mCompileUnit->mDbgModule->EvaluateLocation(dwSubprogram, variable->mLocationData, variable->mLocationLen, stackFrame, outAddrType, variable->mIsParam ? DbgEvalLocFlag_IsParam : DbgEvalLocFlag_None); _FixParam(variable);