Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • opensrc/SMPStaticAnalyzer
1 result
Show changes
Commits on Source (2)
...@@ -1562,6 +1562,7 @@ STARS_ea_t SMPBasicBlock::GetUltimateDefAddr(const STARSOpndTypePtr &UseOp, STAR ...@@ -1562,6 +1562,7 @@ STARS_ea_t SMPBasicBlock::GetUltimateDefAddr(const STARSOpndTypePtr &UseOp, STAR
SMPInstr *CurrInst = this->GetFunc()->GetInstFromAddr(DefAddr); SMPInstr *CurrInst = this->GetFunc()->GetInstFromAddr(DefAddr);
assert(NULL != CurrInst); assert(NULL != CurrInst);
bool NewDefMoveOp = false; bool NewDefMoveOp = false;
#if 0
if (CurrInst->MDIsMoveInstr()) { if (CurrInst->MDIsMoveInstr()) {
DefMoveOp = CurrInst->GetMoveSource(); DefMoveOp = CurrInst->GetMoveSource();
DefMoveOp = CloneIfNecessary(DefMoveOp, this->GetFunc()->UsesFramePointer()); DefMoveOp = CloneIfNecessary(DefMoveOp, this->GetFunc()->UsesFramePointer());
...@@ -1577,6 +1578,9 @@ STARS_ea_t SMPBasicBlock::GetUltimateDefAddr(const STARSOpndTypePtr &UseOp, STAR ...@@ -1577,6 +1578,9 @@ STARS_ea_t SMPBasicBlock::GetUltimateDefAddr(const STARSOpndTypePtr &UseOp, STAR
DefMoveOp = CurrInst->MakeRegOpnd(LeaAddrReg); // convert to RegOp DefMoveOp = CurrInst->MakeRegOpnd(LeaAddrReg); // convert to RegOp
} }
} }
#else
NewDefMoveOp = CurrInst->IsSimpleCopy(DefMoveOp);
#endif
// We recurse if the DefMoveOp is a non-stack-ptr-reg, including the LeaMemUseOp being // We recurse if the DefMoveOp is a non-stack-ptr-reg, including the LeaMemUseOp being
// a single register (e.g. base but no index: lea ebx,[edx] is just a move in disguise) // a single register (e.g. base but no index: lea ebx,[edx] is just a move in disguise)
bool ValidOperand = NewDefMoveOp && ((DefMoveOp->IsRegOp() && (!MDIsStackPtrReg(DefMoveOp->GetReg(), UseFP))) bool ValidOperand = NewDefMoveOp && ((DefMoveOp->IsRegOp() && (!MDIsStackPtrReg(DefMoveOp->GetReg(), UseFP)))
......
...@@ -16223,6 +16223,8 @@ bool SMPFunction::ComputeReturnTargets(bool FirstIteration) { ...@@ -16223,6 +16223,8 @@ bool SMPFunction::ComputeReturnTargets(bool FirstIteration) {
if (NULL == FuncInfo) { if (NULL == FuncInfo) {
SMP_msg("SERIOUS WARNING: ComputeReturnTargets: Call location %llx not in a function.\n", SMP_msg("SERIOUS WARNING: ComputeReturnTargets: Call location %llx not in a function.\n",
(unsigned long long) CallAddr); (unsigned long long) CallAddr);
this->SetIsCalledFromOrphanedCode();
// IncompleteCaller = true;
continue; continue;
} }
// Get first addr in func and map to SMPFunction *. // Get first addr in func and map to SMPFunction *.
...@@ -16732,35 +16734,41 @@ void SMPFunction::EmitReturnTargetAnnotations(void) { ...@@ -16732,35 +16734,41 @@ void SMPFunction::EmitReturnTargetAnnotations(void) {
if (success) if (success)
ReturnProcessed = true; ReturnProcessed = true;
set<STARS_ea_t>::const_iterator RetTargIter; set<STARS_ea_t>::const_iterator RetTargIter;
for (RetTargIter = this->ReturnTargets.cbegin(); RetTargIter != this->ReturnTargets.cend(); ++RetTargIter) { for (const STARS_ea_t RetTargetAddr : this->ReturnTargets) {
STARS_ea_t RetTargetAddr = (*RetTargIter);
bool TailCallFlag = (this->TailReturnTargets.find(RetTargetAddr) != this->TailReturnTargets.end()); bool TailCallFlag = (this->TailReturnTargets.find(RetTargetAddr) != this->TailReturnTargets.end());
success &= global_STARS_program->PrintReturnInstXref(ReturnInstAddr, RetTargetAddr, RetInstSize, TailCallFlag); success &= global_STARS_program->PrintReturnInstXref(ReturnInstAddr, RetTargetAddr, RetInstSize, TailCallFlag);
} }
if (success && (!(this->IsPossibleIndirectCallTarget() || this->MultipleEntryPoints || OrphanCodeProblem))) { if (success && (!(this->IsPossibleIndirectCallTarget() || this->MultipleEntryPoints || OrphanCodeProblem))) {
global_STARS_program->PrintCodeToCodeXrefComplete(ReturnInstAddr, RetInstSize, this->ReturnTargets.size(), ZST_RETURN); global_STARS_program->PrintCodeToCodeXrefComplete(ReturnInstAddr, RetInstSize, this->ReturnTargets.size(), ZST_RETURN);
++STARS_ReturnSetComplete; ++STARS_ReturnSetComplete;
bool RetDeadRegsProblem = false;
if (!RetDeadRegsComputed) { if (!RetDeadRegsComputed) {
// Compute intersection of dead regs bitsets for each return target. // Compute intersection of dead regs bitsets for each return target.
for (set<STARS_ea_t>::const_iterator RetTargIter = this->ReturnTargets.cbegin(); RetTargIter != this->ReturnTargets.cend(); ++RetTargIter) { for (const STARS_ea_t RetTargetAddr : this->ReturnTargets) {
STARS_ea_t RetTargetAddr = (*RetTargIter);
STARS_Function_t *FuncInfo = SMP_get_func(RetTargetAddr); STARS_Function_t *FuncInfo = SMP_get_func(RetTargetAddr);
assert(NULL != FuncInfo); if (nullptr == FuncInfo) {
RetDeadRegsProblem = true;
SMP_msg("ERROR: Return target ID %llx not in any function.\n", (uint64_t) RetTargetAddr);
break; // cannot produce valid set
}
// Get first addr in func and map to SMPFunction *. // Get first addr in func and map to SMPFunction *.
STARS_ea_t FirstAddrOfCaller = FuncInfo->get_startEA(); STARS_ea_t FirstAddrOfCaller = FuncInfo->get_startEA();
SMPFunction *CallingFunc = this->GetProg()->FindFunction(FirstAddrOfCaller); SMPFunction *CallingFunc = this->GetProg()->FindFunction(FirstAddrOfCaller);
assert(nullptr != CallingFunc); assert(nullptr != CallingFunc);
SMPInstr *RetTargetInst = CallingFunc->GetInstFromAddr(RetTargetAddr); SMPInstr *RetTargetInst = CallingFunc->GetInstFromAddr(RetTargetAddr);
assert(nullptr != RetTargetInst); assert(nullptr != RetTargetInst);
if (!RetDeadRegsComputed) { if (!RetDeadRegsComputed) { // First target, initialize by OR-ing into empty bitset.
ReturnDeadRegs |= RetTargetInst->GetDeadRegsSet(); ReturnDeadRegs |= RetTargetInst->GetDeadRegsSet();
RetDeadRegsComputed = true; RetDeadRegsComputed = true;
} }
else { else { // Not first target, AND into bitset to get regs dead at all call sites.
ReturnDeadRegs &= RetTargetInst->GetDeadRegsSet(); ReturnDeadRegs &= RetTargetInst->GetDeadRegsSet();
} }
} }
} }
if (RetDeadRegsProblem) {
ReturnDeadRegs.reset();
}
ReturnInst->SetDeadRegsSet(ReturnDeadRegs); ReturnInst->SetDeadRegsSet(ReturnDeadRegs);
} }
else { else {
......
...@@ -43,6 +43,29 @@ uint16_t STARS_IRDB_Instruction_t::GetIDAOpcode(void) ...@@ -43,6 +43,29 @@ uint16_t STARS_IRDB_Instruction_t::GetIDAOpcode(void)
return this->IDAOpcode; // optimization return this->IDAOpcode; // optimization
} }
// Before we allow the CHECK_FOR_INSN and CHECK_FOR_INSN_RENAME macros
// to make the bulk of the decisions, we need to identify opcodes that
// have conflicting mnemonics.
//
// movsd could be a move-string opcode with each move being a dword, or
// it could be move-scalar-double-precision, an SSE2/AVX opcode.
// We will look at operands to catch the floating-point case before
// it gets turned into a move-string by CHECK_FOR_INSN_RENAME.
if (this->disasm.getMnemonic() == string("movsd")) {
const auto my_disasm = DecodedInstruction_t(this->irdb_insn);
bool Operand0SSEorAVX = (my_disasm.hasOperand(0)
&& (my_disasm.getOperand(0).isSseRegister()
|| my_disasm.getOperand(0).isAvxRegister()));
bool Operand1SSEorAVX = (my_disasm.hasOperand(1)
&& (my_disasm.getOperand(1).isSseRegister()
|| my_disasm.getOperand(1).isAvxRegister()));
if (Operand0SSEorAVX || Operand1SSEorAVX) {
this->IDAOpcode = STARS_NN_movsd;
this->IDAOpcodeCached = true;
return this->IDAOpcode;
}
}
#define CHECK_FOR_INSN(token) \ #define CHECK_FOR_INSN(token) \
if (disasm.getMnemonic() == string(#token) ) { /*string(disasm.Instruction.Mnemonic) == string(#token) + " ") */ \ if (disasm.getMnemonic() == string(#token) ) { /*string(disasm.Instruction.Mnemonic) == string(#token) + " ") */ \
this->IDAOpcode = STARS_NN_##token; \ this->IDAOpcode = STARS_NN_##token; \
...@@ -363,7 +386,6 @@ uint16_t STARS_IRDB_Instruction_t::GetIDAOpcode(void) ...@@ -363,7 +386,6 @@ uint16_t STARS_IRDB_Instruction_t::GetIDAOpcode(void)
CHECK_FOR_INSN(cmovl); CHECK_FOR_INSN(cmovl);
CHECK_FOR_INSN(cmovle); CHECK_FOR_INSN(cmovle);
CHECK_FOR_INSN(cmovnb); CHECK_FOR_INSN(cmovnb);
CHECK_FOR_INSN(cmovnb);
CHECK_FOR_INSN(cmovno); CHECK_FOR_INSN(cmovno);
CHECK_FOR_INSN(cmovnp); CHECK_FOR_INSN(cmovnp);
CHECK_FOR_INSN(cmovns); CHECK_FOR_INSN(cmovns);
...@@ -374,21 +396,10 @@ uint16_t STARS_IRDB_Instruction_t::GetIDAOpcode(void) ...@@ -374,21 +396,10 @@ uint16_t STARS_IRDB_Instruction_t::GetIDAOpcode(void)
CHECK_FOR_INSN(cmovz); CHECK_FOR_INSN(cmovz);
CHECK_FOR_INSN_RENAME(cmova, "cmovnbe"); CHECK_FOR_INSN_RENAME(cmova, "cmovnbe");
CHECK_FOR_INSN_RENAME(cmovb, "cmovb");
CHECK_FOR_INSN_RENAME(cmovbe, "cmovbe");
CHECK_FOR_INSN_RENAME(cmovg, "cmovnle"); CHECK_FOR_INSN_RENAME(cmovg, "cmovnle");
CHECK_FOR_INSN_RENAME(cmovge, "cmovnl"); CHECK_FOR_INSN_RENAME(cmovge, "cmovnl");
CHECK_FOR_INSN_RENAME(cmovl, "cmovl");
CHECK_FOR_INSN_RENAME(cmovle, "cmovle");
CHECK_FOR_INSN_RENAME(cmovnb, "cmovnb");
CHECK_FOR_INSN_RENAME(cmovnb, "cmovae"); CHECK_FOR_INSN_RENAME(cmovnb, "cmovae");
CHECK_FOR_INSN_RENAME(cmovno, "cmovno");
CHECK_FOR_INSN_RENAME(cmovnp, "cmovnp");
CHECK_FOR_INSN_RENAME(cmovns, "cmovns");
CHECK_FOR_INSN_RENAME(cmovnz, "cmovne"); CHECK_FOR_INSN_RENAME(cmovnz, "cmovne");
CHECK_FOR_INSN_RENAME(cmovo, "cmovo");
CHECK_FOR_INSN_RENAME(cmovp, "cmovp");
CHECK_FOR_INSN_RENAME(cmovs, "cmovs");
CHECK_FOR_INSN_RENAME(cmovz, "cmove"); CHECK_FOR_INSN_RENAME(cmovz, "cmove");
CHECK_FOR_INSN(fcmovb); CHECK_FOR_INSN(fcmovb);
CHECK_FOR_INSN(fcmove); CHECK_FOR_INSN(fcmove);
......