diff --git a/SMPDataFlowAnalysis.cpp b/SMPDataFlowAnalysis.cpp index 9f3417087b3315414e40f37ccf5b682e6667e5af..971b790c0c3e42b5edf9d2f2038f0777a8650e0e 100644 --- a/SMPDataFlowAnalysis.cpp +++ b/SMPDataFlowAnalysis.cpp @@ -66,7 +66,7 @@ #define STARS_DEBUG_DUMP_IDENTIFY_HIDDEN_OPERANDS 0 // print HIDDEN if operand.showed() is false #if IDA_SDK_VERSION > 560 -#define MAX_IDA_REG R_mxcsr +#define MAX_IDA_REG R_last #else #define MAX_IDA_REG 80 #endif @@ -82,7 +82,10 @@ const char *RegNames[MAX_IDA_REG + 1] = "MMX0", "MMX1", "MMX2", "MMX3", "MMX4", "MMX5", "MMX6", "MMX7", "XMM0", "XMM1", "XMM2", "XMM3", "XMM4", "XMM5", "XMM6", "XMM7", "XMM8", "XMM9", "XMM10", "XMM11", "XMM12", "XMM13", "XMM14", "XMM15", - "MXCSR" + "MXCSR", + "YMM0", "YMM1", "YMM2", "YMM3", "YMM4", "YMM5", "YMM6", "YMM7", + "YMM8", "YMM9", "YMM10", "YMM11", "YMM12", "YMM13", "YMM14", "YMM15", + "REG_ERROR" }; const unsigned char RegSizes[MAX_IDA_REG + 1] = @@ -96,7 +99,10 @@ const unsigned char RegSizes[MAX_IDA_REG + 1] = 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 4 + 4, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 4 }; const char *ErrorStrings[1] = { "ERROR_REG" }; diff --git a/SMPFunction.cpp b/SMPFunction.cpp index 164d4e0ccdc0c699d0d1401a05acd87927caa4b9..d6f3dd90dfb324d9720dbc2816251e9bc1bea6ba 100644 --- a/SMPFunction.cpp +++ b/SMPFunction.cpp @@ -1350,11 +1350,13 @@ bool SMPFunction::AnalyzeStackPointerDeltas(void) { } SMPitype FlowType = CurrInst->GetDataFlowType(); IncomingDelta += CurrentDelta; - if ((RETURN == FlowType) && (!CurrInst->IsCondTailCall())) { + if ((RETURN == FlowType) && (!CurrInst->IsCondTailCall()) && (!CurrInst->IsTailCall())) { // We hope to see a consistent outgoing delta from all RETURN points. // We special-case the conditional jump used as tail call, because it must be followed // by a real return instruction later. If the jump is taken, it acts as a return, but // it has not yet popped the stack. + // Also, a regular tail call always has the stack delta at zero and does not match + // the stack delta of actual return instructions elsewhere in the function. if (ReturnSeen) { // This is not the first RETURN seen. if (IncomingDelta != this->NetStackDelta) { // Inconsistent SMP_msg("ERROR: Inconsistent stack deltas at return instruction at %lx\n", diff --git a/SMPInstr.cpp b/SMPInstr.cpp index 7738f696a43a48afb77827aec1399890065689c5..65099d43fcedfa26164cb3536f70fae9e2433e94 100644 --- a/SMPInstr.cpp +++ b/SMPInstr.cpp @@ -2588,16 +2588,19 @@ sval_t SMPInstr::AnalyzeStackPointerDelta(sval_t IncomingDelta, sval_t PreAllocD // has no effect on the stack pointer. ; // leave InstDelta equal to negative or zero value from StackAlterationTable[] } - else if (this->IsRecursiveCall()) { + else if (this->IsRecursiveCall() || TailCall) { // We don't have the net stack delta for our own function yet, so we cannot // look it up. We must assume that each call has no net effect on the stack delta. // Alternatively, we could call this->GetBlock()->GetFunc()->GetStackDeltaForCallee() as below. + // Also, a tail call happens when the stack delta is down to zero, and the callee does not + // return to the caller, unlike the call cases below, so the callee's net stack delta is + // irrelevant to the caller. InstDelta = 0; } else if (this->IsAllocaCall()) { InstDelta = STARS_DEFAULT_ALLOCA_SIZE; } - else if ((CALL == FlowType) || (INDIR_CALL == FlowType) || TailCall) { + else if ((CALL == FlowType) || (INDIR_CALL == FlowType)) { // A real call instruction, which pushes a return address on the stack, // not a call used as a branch within the function. A return instruction // will usually cancel out the stack push that is implicit in the call, which @@ -2608,9 +2611,11 @@ sval_t SMPInstr::AnalyzeStackPointerDelta(sval_t IncomingDelta, sval_t PreAllocD // in which case we assume +4. !!!!****!!!! In the future, we could analyze // the code around an unresolved indirect call to see if it seems to be // removing items left on the stack by the callee. +#if 0 // SPECIAL CASE: A jump used as a tail call will have a stack ptr effect that is equal // to the net stack ptr effect of its target function, usually +4, whereas a jump // would otherwise have a net stack ptr effect of 0. +#endif ea_t CalledFuncAddr = this->GetCallTarget(); if ((BADADDR == CalledFuncAddr) || (0 == CalledFuncAddr)) { InstDelta = 0;