Newer
Older
set<DefOrUse, LessDefUse>::iterator setIterator;
for (setIterator = Instructions->GetFirstDef(); setIterator != Instructions->GetLastDef(); setIterator++) {
op_t Operand = setIterator->GetOp();
clc5q
committed
int BaseReg;
int IndexReg;
ushort ScaleFactor;
ea_t offset;
// now o_mem can have sib byte as well, as
clc5q
committed
// reported by IDA. Check if the base reg is R_none
// and index reg is R_none. If they are, then this is
clc5q
committed
// a direct global write and can be marked safe.
clc5q
committed
MDExtractAddressFields(Operand, BaseReg, IndexReg, ScaleFactor, offset);
clc5q
committed
// go onto next def
continue;
HasIndirectGlobalWrite = true;
}
clc5q
committed
MDExtractAddressFields(Operand, BaseReg, IndexReg, ScaleFactor, offset);
bool FramePointerRelative = (this->UseFP && (BaseReg == R_bp));
bool StackPointerRelative = (BaseReg == R_sp);
if (StackPointerRelative || FramePointerRelative) {
clc5q
committed
if (IndexReg == R_none) {
bool tempWritesAboveLocalFrame = this->WritesAboveLocalFrame(Operand);
msg(" Function %s marked as unsafe due to direct write above loc "
"variables offset=%x loc=%x\n ", this->GetFuncName(),
offset, this->LocalVarsSize);
msg("Write above local frame in %s : offset: %d ",
this->GetFuncName(), offset);
msg("LocalVarsSize: %d OutgoingArgsSize: %d frsize: %d frregs: %d",
this->LocalVarsSize, this->OutgoingArgsSize,
this->FuncInfo.frsize, this->FuncInfo.frregs);
Instructions->Dump();
}
#endif
bool tempWritesAboveLocalFrameIndirect = this->IndexedWritesAboveLocalFrame(Operand);
/* seperate indirect writes to this frame from indirect writes to another frame */
WritesAboveLocalFrameIndirect = true;
msg(" Function %s marked as unsafe due to indexed stack write above "
"loc variable offset\n", this->GetFuncName());
msg("%s %x\n", (Instructions)->GetDisasm(), (Instructions)->GetAddr());
msg(" Function %s marked as unsafe due to indexed stack write\n",
this->GetFuncName());
msg("%s %x\n", (Instructions)->GetDisasm(), (Instructions)->GetAddr());
/* check whether there is profiler information for this indirect reference */
clc5q
committed
HasIndirectWrite = true;
}
else if (Operand.type == o_phrase) {
// so phrase is of the form [BASE_REG + IND ]
// if the index register is missing just make sure that
// the displacement is below stack frame top
clc5q
committed
MDExtractAddressFields(Operand, BaseReg, IndexReg, ScaleFactor, offset);
// check the base reg
// if index reg is used mark as unsafe
if ((BaseReg == R_sp || (this->UseFP && BaseReg == R_bp))) {
if (IndexReg == R_none) {
/* addressing mode is *esp or *ebp */
clc5q
committed
continue;
}
else {
HasIndexedStackWrite = true;
#if SMP_DEBUG_FUNC
msg(" Function %s marked as unsafe due to indexed stack write\n", this->GetFuncName());
clc5q
committed
msg("%s %x\n", (Instructions)->GetDisasm(), (Instructions)->GetAddr());
#endif
}
/* check whether there is profiler information for this indirect reference */
clc5q
committed
HasIndirectWrite = true;
// else not memory, and we don't care.
} // end for all DEFs in current instruction
} // end for all instructions
clc5q
committed
// For mmStrata bounds checking of the stack frame, we don't care
// about indirect writes unless they are to the stack.
bool Unsafe = (HasStackPointerCopy || HasStackPointerPush
|| HasIndexedStackWrite || this->SharedChunks
|| this->UnresolvedIndirectJumps || this->UnresolvedIndirectCalls);
this->SafeFunc = (!Unsafe);
bool SpecUnsafe = (HasStackPointerCopy || HasStackPointerPush
|| HasIndexedStackWrite || this->SharedChunks
|| this->UnresolvedIndirectJumps);
this->SpecSafeFunc = (!SpecUnsafe);
this->WritesAboveRA = WritesAboveLocalFrameIndirect;
this->SafeCallee = (!Unsafe) && (!WritesAboveLocalFrameIndirect) && this->AnalyzedSP;
this->SpecSafeCallee = (!SpecUnsafe) && (!WritesAboveLocalFrameIndirect) && this->AnalyzedSP;
this->SpecNeedsStackReferent = SpecUnsafe;
this->HasIndirectWrites = (HasIndexedStackWrite || HasIndirectWrite
|| WritesAboveLocalFrameIndirect || HasIndirectGlobalWrite);
if (Unsafe || WritesAboveLocalFrame || WritesAboveLocalFrameIndirect || HasIndirectGlobalWrite
|| HasIndirectWrite || (!this->AnalyzedSP)) {
clc5q
committed
this->ReturnAddrStatus = FUNC_UNSAFE;
clc5q
committed
msg("UNSAFE function %s ", this->GetFuncName());
msg("StackPtrCopy: %d StackPtrPush: %d IndirectGlobal: %d ",
HasStackPointerCopy, HasStackPointerPush, HasIndirectGlobalWrite);
msg("WritesAboveFrame: %d IndirectStack: %d IndirectWrite: %d ",
WritesAboveLocalFrame, HasIndexedStackWrite, HasIndirectWrite);
msg("AnalyzedSP: %d UnresolvedCalls: %d UnresolvedJumps: %d SharedChunks: %d IsLeaf: %d\n",
this->AnalyzedSP, this->UnresolvedIndirectCalls, this->UnresolvedIndirectJumps,
clc5q
committed
this->SharedChunks, this->IsLeaf());
clc5q
committed
}
else if (HasCallTargets) {
clc5q
committed
this->ReturnAddrStatus = FUNC_UNKNOWN;
}
msg("Function %s is SAFE\n", GetFuncName());
msg("Function %s is UNSAFE\n", GetFuncName());
msg("Function %s is UNKNOWN\n", GetFuncName());
msg("Function %s is mmSAFE\n", GetFuncName());
else
msg("Function %s is mmUNSAFE\n", GetFuncName());
msg("Function %s is Speculatively mmSAFE\n", GetFuncName());
else
msg("Function %s is Speculatively mmUNSAFE\n", GetFuncName());
#endif
clc5q
committed
return;
} // end of SMPFunction::MarkFunctionSafe()