diff --git a/SMPDataFlowAnalysis.cpp b/SMPDataFlowAnalysis.cpp index d4f3ebcc41b448bd222c9b1935fca16e392dfa37..43895bc13e4afff8f212385abf5660fc44301d25 100644 --- a/SMPDataFlowAnalysis.cpp +++ b/SMPDataFlowAnalysis.cpp @@ -1082,7 +1082,8 @@ set<DefOrUse, LessDefUse>::iterator DefOrUseSet::SetType(op_t CurrOp, SMPOperand SMP_msg("ERROR: Changing type of immediate from %d to %d at %x: ", CurrRef->GetType(), Type, Instr->GetAddr()); CurrRef->Dump(); SMP_msg("\n"); - Instr->Dump(); + SMPInstr InstCopy = (*Instr); + InstCopy.Dump(); } } #endif diff --git a/SMPInstr.cpp b/SMPInstr.cpp index d9f1a664622841713564e28d15fb1d764c8ae71e..cf880e25b0db01536cd971561e2cfb61ec6cb535 100644 --- a/SMPInstr.cpp +++ b/SMPInstr.cpp @@ -67,6 +67,7 @@ using namespace std; #define SMP_VERBOSE_DEBUG_INFER_TYPES 0 #define SMP_VERBOSE_DUMP 0 #define SMP_VERBOSE_FIND_POINTERS 0 +#define STARS_DUMP_FG_INFO 1 // show signedness of DEFs and USEs in dump #define SMP_CALL_TRASHES_REGS 1 // Add DEFs of caller-saved regs to CALL instructions #define SMP_BASEREG_POINTER_TYPE 1 // Initialize Base Register USEs to type POINTER? @@ -867,13 +868,82 @@ void SMPInstr::PrintOperands(void) const { } // end of SMPInstr::PrintOperands() // Complete DEBUG printing. -void SMPInstr::Dump(void) const { +void SMPInstr::Dump(void) { SMP_msg("%x %d SMPitype: %d %s\n", this->address, this->SMPcmd.size, (int) this->type, DisAsmText.GetDisAsm(this->GetAddr())); +#if STARS_DUMP_FG_INFO + SMP_msg("USEs: "); + if (NULL == this->GetBlock()) { // during early improvement of disasm + this->Uses.Dump(); + SMP_msg("DEFs: "); + this->Defs.Dump(); + } + else { + set<DefOrUse, LessDefUse>::iterator UseIter, DefIter; + op_t UseOp, DefOp; + int UseHashValue, DefHashValue, UseSSANum, DefSSANum; + unsigned short SignMiscInfo, SignMask; + bool LocalName; + for (UseIter = this->GetFirstUse(); UseIter != this->GetLastUse(); ++UseIter) { + UseIter->Dump(); + UseOp = UseIter->GetOp(); + if (o_reg == UseOp.type) { + LocalName = this->GetBlock()->IsLocalName(UseOp); + UseSSANum = UseIter->GetSSANum(); + UseHashValue = HashGlobalNameAndSSA(UseOp, UseSSANum); + if (LocalName) { + SignMiscInfo = this->GetBlock()->GetUseSignMiscInfo(UseHashValue); + } + else { + SignMiscInfo = this->GetBlock()->GetFunc()->GetUseSignMiscInfo(UseHashValue); + } + SignMask = SignMiscInfo & FG_MASK_SIGNEDNESS_BITS; + if (SignMask == FG_MASK_SIGNED) { + SMP_msg(" Si "); + } + else if (SignMask == FG_MASK_UNSIGNED) { + SMP_msg(" Un "); + } + else if (SignMask == FG_MASK_INCONSISTENT_SIGN) { + SMP_msg(" Xs "); + } + } + SMP_msg("\n"); + } + SMP_msg("DEFs: "); + for (DefIter = this->GetFirstDef(); DefIter != this->GetLastDef(); ++DefIter) { + DefIter->Dump(); + DefOp = DefIter->GetOp(); + if (o_reg == DefOp.type) { + LocalName = this->GetBlock()->IsLocalName(DefOp); + DefSSANum = DefIter->GetSSANum(); + DefHashValue = HashGlobalNameAndSSA(DefOp, DefSSANum); + if (LocalName) { + SignMiscInfo = this->GetBlock()->GetDefSignMiscInfo(DefHashValue); + } + else { + SignMiscInfo = this->GetBlock()->GetFunc()->GetDefSignMiscInfo(DefHashValue); + } + SignMask = SignMiscInfo & FG_MASK_SIGNEDNESS_BITS; + if (SignMask == FG_MASK_SIGNED) { + SMP_msg(" Si "); + } + else if (SignMask == FG_MASK_UNSIGNED) { + SMP_msg(" Un "); + } + else if (SignMask == FG_MASK_INCONSISTENT_SIGN) { + SMP_msg(" Xs "); + } + } + SMP_msg("\n"); + } + } +#else SMP_msg("USEs: "); this->Uses.Dump(); SMP_msg("DEFs: "); this->Defs.Dump(); +#endif this->RTL.Dump(); #if SMP_VERBOSE_DUMP this->PrintOperands(); @@ -4451,8 +4521,8 @@ bool SMPInstr::IsBenignTruncation(int &IdiomCode) { // Do we not consider overflow or underflow on this type of instruction to be an error? bool SMPInstr::IsBenignOverflow(int &IdiomCode) { bool benign = false; - set<DefOrUse, LessDefUse>::iterator DefIter; - SMPOperandType DefType; + set<DefOrUse, LessDefUse>::iterator DefIter, UseIter; + SMPOperandType DefType, UseType; int DefSSANum; ea_t DefAddr; op_t DefOp; @@ -4526,6 +4596,27 @@ bool SMPInstr::IsBenignOverflow(int &IdiomCode) { } } + if (!benign) { + // Any overflow or underflow producing a PTROFFSET type should be suppressed. + for (DefIter = this->GetFirstDef(); DefIter != this->GetLastDef(); ++DefIter) { + DefType = DefIter->GetType(); + if (IsEqType(DefType, PTROFFSET)) { + benign = true; + IdiomCode = 19; + } + } + } + if (!benign) { + // Any overflow or underflow using a PTROFFSET type should be suppressed. + for (UseIter = this->GetFirstUse(); UseIter != this->GetLastUse(); ++UseIter) { + UseType = UseIter->GetType(); + if (IsEqType(UseType, PTROFFSET)) { + benign = true; + IdiomCode = 19; + } + } + } + return benign; } // end of SMPInstr::IsBenignOverflow() @@ -8318,7 +8409,7 @@ void SMPInstr::MDEmitLeaOpcodeOverflowAnnotations(FILE *InfoAnnotFile, list<size bool SourceFound = false; bool DataPointer = false; int SSANum; - SMPOperandType DefType; + SMPOperandType DefType, UseType; int UseHashValue; int IdiomCode = 0; struct FineGrainedInfo UseFGInfo, SourceDefFGInfo; @@ -8368,6 +8459,25 @@ void SMPInstr::MDEmitLeaOpcodeOverflowAnnotations(FILE *InfoAnnotFile, list<size } } + if (0 == IdiomCode) { + // Any overflow or underflow producing a PTROFFSET type should be suppressed. + for (DefIter = this->GetFirstDef(); DefIter != this->GetLastDef(); ++DefIter) { + DefType = DefIter->GetType(); + if (IsEqType(DefType, PTROFFSET)) { + IdiomCode = 19; + } + } + } + if (0 == IdiomCode) { + // Any overflow or underflow using a PTROFFSET type should be suppressed. + for (UseIter = this->GetFirstUse(); UseIter != this->GetLastUse(); ++UseIter) { + UseType = UseIter->GetType(); + if (IsEqType(UseType, PTROFFSET)) { + IdiomCode = 19; + } + } + } + char *disasm = DisAsmText.GetDisAsm(this->GetAddr()); ScaledIndexReg = (0 < ScaleFactor); diff --git a/SMPInstr.h b/SMPInstr.h index 231d4e5e49edd8055a6ce01e63515fb457c2b1da..7646796891c7985cf50305b66a4a893f327541e7 100644 --- a/SMPInstr.h +++ b/SMPInstr.h @@ -503,7 +503,7 @@ public: // Printing methods void PrintOperands(void) const; char *DestString(int OptType); - void Dump(void) const; // Complete debug print, with DEF/USE list, SSA #s, RTL + void Dump(void); // Complete debug print, with DEF/USE list, SSA #s, RTL // Analysis methods op_t GetSourceOnlyOperand(void); // return non-flags-reg non-dest source operand