Skip to content
Snippets Groups Projects
Commit 28382379 authored by an7s's avatar an7s
Browse files

only instrument unknown overflows for non-lea instructions for now

Former-commit-id: c65fdd5e3852ff7a1e46c474b2e9106733083f10
parent 56142402
No related branches found
No related tags found
No related merge requests found
...@@ -54,6 +54,10 @@ class IntegerTransform : public Transform ...@@ -54,6 +54,10 @@ class IntegerTransform : public Transform
std::map<VirtualOffset, MEDS_InstructionCheckAnnotation>* getAnnotations() { return m_annotations; } std::map<VirtualOffset, MEDS_InstructionCheckAnnotation>* getAnnotations() { return m_annotations; }
protected:
void logMessage(const std::string &p_method, const std::string &p_msg);
void logMessage(const std::string &p_method, const MEDS_InstructionCheckAnnotation&, const std::string &p_msg);
private: private:
std::set<VirtualOffset>* m_benignFalsePositives; std::set<VirtualOffset>* m_benignFalsePositives;
bool m_policySaturatingArithmetic; bool m_policySaturatingArithmetic;
...@@ -65,12 +69,19 @@ class IntegerTransform : public Transform ...@@ -65,12 +69,19 @@ class IntegerTransform : public Transform
// make sure these match the function names in $STRATA/src/posix/x86_linux/detector_number_handling/overflow_detector.c // make sure these match the function names in $STRATA/src/posix/x86_linux/detector_number_handling/overflow_detector.c
#define INTEGER_OVERFLOW_DETECTOR "integer_overflow_detector" #define INTEGER_OVERFLOW_DETECTOR "integer_overflow_detector"
#define ADDSUB_OVERFLOW_DETECTOR_SIGNED_32 "addsub_overflow_detector_signed_32" #define ADDSUB_OVERFLOW_DETECTOR_SIGNED_32 "addsub_overflow_detector_signed_32"
#define ADDSUB_OVERFLOW_DETECTOR_UNSIGNED_32 "addsub_overflow_detector_unsigned_32" #define ADDSUB_OVERFLOW_DETECTOR_UNSIGNED_32 "addsub_overflow_detector_unsigned_32"
#define ADDSUB_OVERFLOW_DETECTOR_UNKNOWN_32 "addsub_overflow_detector_unknown_32"
#define ADDSUB_OVERFLOW_DETECTOR_SIGNED_16 "addsub_overflow_detector_signed_16" #define ADDSUB_OVERFLOW_DETECTOR_SIGNED_16 "addsub_overflow_detector_signed_16"
#define ADDSUB_OVERFLOW_DETECTOR_UNSIGNED_16 "addsub_overflow_detector_unsigned_16" #define ADDSUB_OVERFLOW_DETECTOR_UNSIGNED_16 "addsub_overflow_detector_unsigned_16"
#define ADDSUB_OVERFLOW_DETECTOR_UNKNOWN_16 "addsub_overflow_detector_unknown_16"
#define ADDSUB_OVERFLOW_DETECTOR_SIGNED_8 "addsub_overflow_detector_signed_8" #define ADDSUB_OVERFLOW_DETECTOR_SIGNED_8 "addsub_overflow_detector_signed_8"
#define ADDSUB_OVERFLOW_DETECTOR_UNSIGNED_8 "addsub_overflow_detector_unsigned_8" #define ADDSUB_OVERFLOW_DETECTOR_UNSIGNED_8 "addsub_overflow_detector_unsigned_8"
#define ADDSUB_OVERFLOW_DETECTOR_UNKNOWN_8 "addsub_overflow_detector_unknown_8"
#define MUL_OVERFLOW_DETECTOR_32 "mul_overflow_detector_32" #define MUL_OVERFLOW_DETECTOR_32 "mul_overflow_detector_32"
#define MUL_OVERFLOW_DETECTOR_16 "mul_overflow_detector_16" #define MUL_OVERFLOW_DETECTOR_16 "mul_overflow_detector_16"
#define MUL_OVERFLOW_DETECTOR_8 "mul_overflow_detector_8" #define MUL_OVERFLOW_DETECTOR_8 "mul_overflow_detector_8"
......
...@@ -256,16 +256,19 @@ void IntegerTransform::addSignednessCheck(Instruction_t *p_instruction, const ME ...@@ -256,16 +256,19 @@ void IntegerTransform::addSignednessCheck(Instruction_t *p_instruction, const ME
void IntegerTransform::handleOverflowCheck(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, int p_policy) void IntegerTransform::handleOverflowCheck(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, int p_policy)
{ {
if (p_annotation.isUnknownSign()) if (p_annotation.isUnknownSign() && !p_annotation.isNoFlag())
{ {
// right now, doesn't yet handle lea
addOverflowCheckUnknownSign(p_instruction, p_annotation, p_policy); addOverflowCheckUnknownSign(p_instruction, p_annotation, p_policy);
} }
else if (p_annotation.isOverflow() && p_annotation.isNoFlag()) else if (p_annotation.isNoFlag())
{ {
// handle lea
addOverflowCheckNoFlag(p_instruction, p_annotation, p_policy); addOverflowCheckNoFlag(p_instruction, p_annotation, p_policy);
} }
else if (isMultiplyInstruction(p_instruction) || p_annotation.isUnderflow() || p_annotation.isOverflow()) else if (isMultiplyInstruction(p_instruction) || p_annotation.isUnderflow() || p_annotation.isOverflow())
{ {
// handle signed/unsigned add/sub overflows (non lea)
addOverflowCheck(p_instruction, p_annotation, p_policy); addOverflowCheck(p_instruction, p_annotation, p_policy);
} }
else else
...@@ -455,7 +458,7 @@ void IntegerTransform::addOverflowCheckNoFlag_RegPlusReg(Instruction_t *p_instru ...@@ -455,7 +458,7 @@ void IntegerTransform::addOverflowCheckNoFlag_RegPlusReg(Instruction_t *p_instru
void IntegerTransform::addOverflowCheckNoFlag_RegPlusConstant(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, const Register::RegisterName& p_reg1, const int p_constantValue, const Register::RegisterName& p_reg3, int p_policy) void IntegerTransform::addOverflowCheckNoFlag_RegPlusConstant(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, const Register::RegisterName& p_reg1, const int p_constantValue, const Register::RegisterName& p_reg3, int p_policy)
{ {
// cerr << "integertransform: doit: reg+constant: register: " << Register::toString(p_reg1) << " constant: " << dec << p_constantValue << " target register: " << Register::toString(p_reg3) << " annotation: " << p_annotation.toString() << endl; cerr << "integertransform: doit: reg+constant: register: " << Register::toString(p_reg1) << " constant: " << dec << p_constantValue << " target register: " << Register::toString(p_reg3) << " annotation: " << p_annotation.toString() << endl;
// //
// Original instruction is of the form: // Original instruction is of the form:
...@@ -526,7 +529,8 @@ void IntegerTransform::addOverflowCheckNoFlag_RegPlusConstant(Instruction_t *p_i ...@@ -526,7 +529,8 @@ void IntegerTransform::addOverflowCheckNoFlag_RegPlusConstant(Instruction_t *p_i
void IntegerTransform::addOverflowCheckNoFlag_RegTimesConstant(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, const Register::RegisterName& p_reg1, const int p_constantValue, const Register::RegisterName& p_reg3, int p_policy) void IntegerTransform::addOverflowCheckNoFlag_RegTimesConstant(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, const Register::RegisterName& p_reg1, const int p_constantValue, const Register::RegisterName& p_reg3, int p_policy)
{ {
// cerr << "integertransform: reg*constant: register: " << Register::toString(p_reg1) << " constant: " << p_constantValue << " target register: " << Register::toString(p_reg3) << " annotation: " << p_annotation.toString() << endl; cerr << "integertransform: reg*constant: register: " << Register::toString(p_reg1) << " constant: " << p_constantValue << " target register: " << Register::toString(p_reg3) << " annotation: " << p_annotation.toString() << endl;
// //
// Original instruction is of the form: // Original instruction is of the form:
// lea r3, [r1*constant] // lea r3, [r1*constant]
...@@ -636,19 +640,23 @@ void IntegerTransform::handleInfiniteLoop(Instruction_t *p_instruction, const ME ...@@ -636,19 +640,23 @@ void IntegerTransform::handleInfiniteLoop(Instruction_t *p_instruction, const ME
// imul, mul -- always check using jno // imul, mul -- always check using jno
// add, sub -- use signedness information annotation to emit either jno, jnc // add, sub -- use signedness information annotation to emit either jno, jnc
// //
// p_addressOriginalInstruction is set when we call method from lea instrumentation
void IntegerTransform::addOverflowCheck(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, int p_policy, AddressID_t *p_addressOriginalInstruction) void IntegerTransform::addOverflowCheck(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, int p_policy, AddressID_t *p_addressOriginalInstruction)
{ {
assert(getFileIR() && p_instruction && p_instruction->GetFallthrough()); assert(getFileIR() && p_instruction && p_instruction->GetFallthrough());
Register::RegisterName targetReg = getTargetRegister(p_instruction); Register::RegisterName targetReg = getTargetRegister(p_instruction);
if (targetReg == Register::UNKNOWN) if (targetReg == Register::UNKNOWN)
{ {
cerr << "integertransform: OVERFLOW UNKNOWN SIGN: unknown register -- skip instrumentation" << endl; if (p_addressOriginalInstruction)
cerr << "integertransform: OVERFLOW UNKNOWN SIGN: LEA case unknown register -- skip instrumentation -- address: " << std::hex << p_instruction->GetAddress() << endl;
else
cerr << "integertransform: OVERFLOW UNKNOWN SIGN: unknown register -- skip instrumentation -- address: " << std::hex << p_instruction->GetAddress() <<endl;
return; return;
} }
cerr << "IntegerTransform::addOverflowCheck(): instr: " << p_instruction->getDisassembly() << " address: " << std::hex << p_instruction->GetAddress() << " annotation: " << p_annotation.toString() << " policy: " << p_policy << endl; cerr << "IntegerTransform::addOverflowCheck(): instr: " << p_instruction->getDisassembly() << " address: " << std::hex << p_instruction->GetAddress() << " annotation: " << p_annotation.toString() << " policy: " << p_policy << endl;
string detector(INTEGER_OVERFLOW_DETECTOR); string detector(INTEGER_OVERFLOW_DETECTOR);
string dataBits; string dataBits;
...@@ -714,6 +722,9 @@ cerr << "IntegerTransform::addOverflowCheck(): instr: " << p_instruction->getDis ...@@ -714,6 +722,9 @@ cerr << "IntegerTransform::addOverflowCheck(): instr: " << p_instruction->getDis
if (p_addressOriginalInstruction) if (p_addressOriginalInstruction)
{ {
// this is the lea case -- by default, lea doesn't implement saturating
// arithmetic
p_policy = POLICY_CONTINUE; // reset to get correct diagnostic msgs
addCallbackHandler(detector, p_instruction, jncond_i, nextOrig_i, p_policy, p_addressOriginalInstruction); addCallbackHandler(detector, p_instruction, jncond_i, nextOrig_i, p_policy, p_addressOriginalInstruction);
} }
else if (p_policy == POLICY_CONTINUE_SATURATING_ARITHMETIC) else if (p_policy == POLICY_CONTINUE_SATURATING_ARITHMETIC)
...@@ -1184,6 +1195,7 @@ bool IntegerTransform::isBlacklisted(Function_t *func) ...@@ -1184,6 +1195,7 @@ bool IntegerTransform::isBlacklisted(Function_t *func)
void IntegerTransform::addOverflowCheckUnknownSign(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, int p_policy) void IntegerTransform::addOverflowCheckUnknownSign(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, int p_policy)
{ {
assert(getFileIR() && p_instruction && p_instruction->GetFallthrough()); assert(getFileIR() && p_instruction && p_instruction->GetFallthrough());
Register::RegisterName targetReg = getTargetRegister(p_instruction); Register::RegisterName targetReg = getTargetRegister(p_instruction);
if (targetReg == Register::UNKNOWN) if (targetReg == Register::UNKNOWN)
{ {
...@@ -1193,8 +1205,17 @@ void IntegerTransform::addOverflowCheckUnknownSign(Instruction_t *p_instruction, ...@@ -1193,8 +1205,17 @@ void IntegerTransform::addOverflowCheckUnknownSign(Instruction_t *p_instruction,
cerr << "IntegerTransform::addOverflowCheckUnknownSign(): instr: " << p_instruction->getDisassembly() << " address: " << std::hex << p_instruction->GetAddress() << " annotation: " << p_annotation.toString() << " policy: " << p_policy << endl; cerr << "IntegerTransform::addOverflowCheckUnknownSign(): instr: " << p_instruction->getDisassembly() << " address: " << std::hex << p_instruction->GetAddress() << " annotation: " << p_annotation.toString() << " policy: " << p_policy << endl;
// set detector/handler
string detector(OVERFLOW_UNKNOWN_SIGN_DETECTOR); string detector(OVERFLOW_UNKNOWN_SIGN_DETECTOR);
string dataBits; if (!isMultiplyInstruction(p_instruction))
{
if (p_annotation.getBitWidth() == 32)
detector = string(ADDSUB_OVERFLOW_DETECTOR_UNKNOWN_32);
else if (p_annotation.getBitWidth() == 16)
detector = string(ADDSUB_OVERFLOW_DETECTOR_UNKNOWN_16);
else if (p_annotation.getBitWidth() == 8)
detector = string(ADDSUB_OVERFLOW_DETECTOR_UNKNOWN_8);
}
// for now assume we're dealing with add/sub 32 bit // for now assume we're dealing with add/sub 32 bit
db_id_t fileID = p_instruction->GetAddress()->GetFileID(); db_id_t fileID = p_instruction->GetAddress()->GetFileID();
...@@ -1208,6 +1229,7 @@ cerr << "IntegerTransform::addOverflowCheckUnknownSign(): instr: " << p_instruct ...@@ -1208,6 +1229,7 @@ cerr << "IntegerTransform::addOverflowCheckUnknownSign(): instr: " << p_instruct
Instruction_t* nextOrig_i = p_instruction->GetFallthrough(); Instruction_t* nextOrig_i = p_instruction->GetFallthrough();
// instrument for both jno and jnc // instrument for both jno and jnc
// redundant for imul, but that's ok, optimize later
p_instruction->SetFallthrough(jno_i); p_instruction->SetFallthrough(jno_i);
addJno(jno_i, jnc_i, nextOrig_i); addJno(jno_i, jnc_i, nextOrig_i);
addJnc(jnc_i, nop_i, nextOrig_i); addJnc(jnc_i, nop_i, nextOrig_i);
...@@ -1224,3 +1246,13 @@ cerr << "IntegerTransform::addOverflowCheckUnknownSign(): instr: " << p_instruct ...@@ -1224,3 +1246,13 @@ cerr << "IntegerTransform::addOverflowCheckUnknownSign(): instr: " << p_instruct
addCallbackHandler(detector, p_instruction, nop_i, nextOrig_i, p_policy); addCallbackHandler(detector, p_instruction, nop_i, nextOrig_i, p_policy);
} }
} }
void IntegerTransform::logMessage(const std::string &p_method, const std::string &p_msg)
{
std::cerr << p_method << ": " << p_msg << std::endl;
}
void IntegerTransform::logMessage(const std::string &p_method, const MEDS_InstructionCheckAnnotation& p_annotation, const std::string &p_msg)
{
logMessage(p_method, p_msg + " annotation: " + p_annotation.toString());
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment