diff --git a/src/base/SMPInstr.cpp b/src/base/SMPInstr.cpp index 02c056b62a165e3651ccf6939fc623915ec2dff0..63f3886075f24a0fc9bbb8eb8f75bb9d4fd00e66 100644 --- a/src/base/SMPInstr.cpp +++ b/src/base/SMPInstr.cpp @@ -1871,7 +1871,8 @@ STARSOpndTypePtr SMPInstr::GetPushedOpnd(void) const { // return STARS_BADADDR if not jump, target addr otherwise. STARS_ea_t SMPInstr::GetJumpTarget(void) const { STARS_ea_t TargetAddr = STARS_BADADDR; - if (this->HasGoodRTL() && (this->type & (JUMP | COND_BRANCH))) { + if (this->HasGoodRTL() + && ((this->type & (JUMP | COND_BRANCH)) || this->IsFixedCallJump())) { // We want to find an RTL of the form: inst_ptr_reg := code_addr SMPRegTransfer *CurrRT = this->RTL.GetRT(0); STARSOpndTypePtr DefOp = CurrRT->GetLeftOperand(); @@ -4618,7 +4619,12 @@ STARS_sval_t SMPInstr::AnalyzeStackPointerDelta(STARS_sval_t IncomingDelta, STAR #endif STARS_ea_t CalledFuncAddr = this->GetCallTarget(); if ((STARS_BADADDR == CalledFuncAddr) || (0 == CalledFuncAddr)) { - InstDelta = 0; + if (this->IsFixedCallJump()) { // push happens previously; callee should swallow return address + InstDelta = CALLING_CONVENTION_DEFAULT_FUNCTION_STACK_DELTA; + } + else { + InstDelta = 0; + } } else { // We have a call target SMPFunction *CalleeFunc = this->GetBlock()->GetFunc()->GetProg()->FindFunction(CalledFuncAddr); @@ -5346,8 +5352,8 @@ void SMPInstr::SetLeaMemUseOp(STARSOpndTypePtr NewLeaOperand) { // a call to a "push retaddr/jump calltarget" pair. void SMPInstr::SetFixedCallJump(void) { this->booleans5 |= INSTR_SET_FIXED_CALL_JUMP; - this->type = CALL; this->CallTarget = this->GetJumpTarget(); + this->type = CALL; // Important: Change type to CALL only after calling GetJumpTarget() this->RTL.GetRT(0)->SetOperator(SMP_CALL); this->RTL.GetRT(0)->SetLeftOperand(this->STARSInstPtr->MakeVoidOpnd()); return;