From 55e92538f37be39d915fa395287ff67a4c7dfdfb Mon Sep 17 00:00:00 2001 From: Rusty Wagner Date: Wed, 31 Jan 2018 20:24:16 -0500 Subject: Adding CPU intrinsics support --- lowlevelilinstruction.cpp | 355 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 353 insertions(+), 2 deletions(-) (limited to 'lowlevelilinstruction.cpp') diff --git a/lowlevelilinstruction.cpp b/lowlevelilinstruction.cpp index ac691574..61eef39b 100644 --- a/lowlevelilinstruction.cpp +++ b/lowlevelilinstruction.cpp @@ -64,6 +64,7 @@ unordered_map {HighSSARegisterLowLevelOperandUsage, SSARegisterLowLevelOperand}, {LowRegisterLowLevelOperandUsage, RegisterLowLevelOperand}, {LowSSARegisterLowLevelOperandUsage, SSARegisterLowLevelOperand}, + {IntrinsicLowLevelOperandUsage, IntrinsicLowLevelOperand}, {ConstantLowLevelOperandUsage, IntegerLowLevelOperand}, {VectorLowLevelOperandUsage, IntegerLowLevelOperand}, {StackAdjustmentLowLevelOperandUsage, IntegerLowLevelOperand}, @@ -80,6 +81,8 @@ unordered_map {SourceSSARegistersLowLevelOperandUsage, SSARegisterListLowLevelOperand}, {SourceSSARegisterStacksLowLevelOperandUsage, SSARegisterStackListLowLevelOperand}, {SourceSSAFlagsLowLevelOperandUsage, SSAFlagListLowLevelOperand}, + {OutputRegisterOrFlagListLowLevelOperandUsage, RegisterOrFlagListLowLevelOperand}, + {OutputSSARegisterOrFlagListLowLevelOperandUsage, SSARegisterOrFlagListLowLevelOperand}, {SourceMemoryVersionsLowLevelOperandUsage, IndexListLowLevelOperand}, {TargetListLowLevelOperandUsage, IndexListLowLevelOperand}, {RegisterStackAdjustmentsLowLevelOperandUsage, RegisterStackAdjustmentsLowLevelOperand} @@ -202,6 +205,10 @@ unordered_map> {LLIL_ZX, {SourceExprLowLevelOperandUsage}}, {LLIL_LOW_PART, {SourceExprLowLevelOperandUsage}}, {LLIL_BOOL_TO_INT, {SourceExprLowLevelOperandUsage}}, + {LLIL_INTRINSIC, {OutputRegisterOrFlagListLowLevelOperandUsage, IntrinsicLowLevelOperandUsage, + ParameterExprsLowLevelOperandUsage}}, + {LLIL_INTRINSIC_SSA, {OutputSSARegisterOrFlagListLowLevelOperandUsage, IntrinsicLowLevelOperandUsage, + ParameterExprsLowLevelOperandUsage}}, {LLIL_UNIMPL_MEM, {SourceExprLowLevelOperandUsage}}, {LLIL_FADD, {LeftExprLowLevelOperandUsage, RightExprLowLevelOperandUsage}}, {LLIL_FSUB, {LeftExprLowLevelOperandUsage, RightExprLowLevelOperandUsage}}, @@ -269,6 +276,8 @@ static unordered_map() const } +const RegisterOrFlag LowLevelILRegisterOrFlagList::ListIterator::operator*() +{ + return RegisterOrFlag::FromIdentifier(*pos); +} + + +LowLevelILRegisterOrFlagList::LowLevelILRegisterOrFlagList(LowLevelILFunction* func, + const BNLowLevelILInstruction& instr, size_t count): m_list(func, instr, count) +{ +} + + +LowLevelILRegisterOrFlagList::const_iterator LowLevelILRegisterOrFlagList::begin() const +{ + const_iterator result; + result.pos = m_list.begin(); + return result; +} + + +LowLevelILRegisterOrFlagList::const_iterator LowLevelILRegisterOrFlagList::end() const +{ + const_iterator result; + result.pos = m_list.end(); + return result; +} + + +size_t LowLevelILRegisterOrFlagList::size() const +{ + return m_list.size(); +} + + +const RegisterOrFlag LowLevelILRegisterOrFlagList::operator[](size_t i) const +{ + if (i >= size()) + throw LowLevelILInstructionAccessException(); + auto iter = begin(); + for (size_t j = 0; j < i; j++) + ++iter; + return *iter; +} + + +LowLevelILRegisterOrFlagList::operator vector() const +{ + vector result; + for (auto& i : *this) + result.push_back(i); + return result; +} + + const SSARegister LowLevelILSSARegisterList::ListIterator::operator*() { LowLevelILIntegerList::const_iterator cur = pos; @@ -819,6 +1005,64 @@ LowLevelILSSAFlagList::operator vector() const } +const SSARegisterOrFlag LowLevelILSSARegisterOrFlagList::ListIterator::operator*() +{ + LowLevelILIntegerList::const_iterator cur = pos; + RegisterOrFlag rf = RegisterOrFlag::FromIdentifier(*cur); + ++cur; + size_t version = (size_t)*cur; + return SSARegisterOrFlag(rf, version); +} + + +LowLevelILSSARegisterOrFlagList::LowLevelILSSARegisterOrFlagList(LowLevelILFunction* func, + const BNLowLevelILInstruction& instr, size_t count): m_list(func, instr, count & (~1)) +{ +} + + +LowLevelILSSARegisterOrFlagList::const_iterator LowLevelILSSARegisterOrFlagList::begin() const +{ + const_iterator result; + result.pos = m_list.begin(); + return result; +} + + +LowLevelILSSARegisterOrFlagList::const_iterator LowLevelILSSARegisterOrFlagList::end() const +{ + const_iterator result; + result.pos = m_list.end(); + return result; +} + + +size_t LowLevelILSSARegisterOrFlagList::size() const +{ + return m_list.size() / 2; +} + + +const SSARegisterOrFlag LowLevelILSSARegisterOrFlagList::operator[](size_t i) const +{ + if (i >= size()) + throw LowLevelILInstructionAccessException(); + auto iter = begin(); + for (size_t j = 0; j < i; j++) + ++iter; + return *iter; +} + + +LowLevelILSSARegisterOrFlagList::operator vector() const +{ + vector result; + for (auto& i : *this) + result.push_back(i); + return result; +} + + LowLevelILOperand::LowLevelILOperand(const LowLevelILInstruction& instr, LowLevelILOperandUsage usage, size_t operandIndex): m_instr(instr), m_usage(usage), m_operandIndex(operandIndex) @@ -906,6 +1150,14 @@ uint32_t LowLevelILOperand::GetSemanticFlagGroup() const } +uint32_t LowLevelILOperand::GetIntrinsic() const +{ + if (m_type != IntrinsicLowLevelOperand) + throw LowLevelILInstructionAccessException(); + return m_instr.GetRawOperandAsRegister(m_operandIndex); +} + + SSARegister LowLevelILOperand::GetSSARegister() const { if (m_type != SSARegisterLowLevelOperand) @@ -953,6 +1205,14 @@ LowLevelILInstructionList LowLevelILOperand::GetExprList() const } +LowLevelILRegisterOrFlagList LowLevelILOperand::GetRegisterOrFlagList() const +{ + if (m_type != RegisterOrFlagListLowLevelOperand) + throw LowLevelILInstructionAccessException(); + return m_instr.GetRawOperandAsRegisterOrFlagList(m_operandIndex); +} + + LowLevelILSSARegisterList LowLevelILOperand::GetSSARegisterList() const { if (m_type != SSARegisterListLowLevelOperand) @@ -979,6 +1239,14 @@ LowLevelILSSAFlagList LowLevelILOperand::GetSSAFlagList() const } +LowLevelILSSARegisterOrFlagList LowLevelILOperand::GetSSARegisterOrFlagList() const +{ + if (m_type != SSARegisterOrFlagListLowLevelOperand) + throw LowLevelILInstructionAccessException(); + return m_instr.GetRawOperandAsSSARegisterOrFlagList(m_operandIndex); +} + + map LowLevelILOperand::GetRegisterStackAdjustments() const { if (m_type != RegisterStackAdjustmentsLowLevelOperand) @@ -1175,6 +1443,12 @@ LowLevelILInstructionList LowLevelILInstructionBase::GetRawOperandAsExprList(siz } +LowLevelILRegisterOrFlagList LowLevelILInstructionBase::GetRawOperandAsRegisterOrFlagList(size_t operand) const +{ + return LowLevelILRegisterOrFlagList(function, function->GetRawExpr(operands[operand + 1]), operands[operand]); +} + + LowLevelILSSARegisterList LowLevelILInstructionBase::GetRawOperandAsSSARegisterList(size_t operand) const { return LowLevelILSSARegisterList(function, function->GetRawExpr(operands[operand + 1]), operands[operand]); @@ -1193,6 +1467,12 @@ LowLevelILSSAFlagList LowLevelILInstructionBase::GetRawOperandAsSSAFlagList(size } +LowLevelILSSARegisterOrFlagList LowLevelILInstructionBase::GetRawOperandAsSSARegisterOrFlagList(size_t operand) const +{ + return LowLevelILSSARegisterOrFlagList(function, function->GetRawExpr(operands[operand + 1]), operands[operand]); +} + + map LowLevelILInstructionBase::GetRawOperandAsRegisterStackAdjustments(size_t operand) const { LowLevelILIntegerList list(function, function->GetRawExpr(operands[operand + 1]), operands[operand]); @@ -1225,6 +1505,14 @@ void LowLevelILInstructionBase::UpdateRawOperandAsSSARegisterList(size_t operand } +void LowLevelILInstructionBase::UpdateRawOperandAsSSARegisterOrFlagList(size_t operandIndex, + const vector& outputs) +{ + UpdateRawOperand(operandIndex, outputs.size() * 2); + UpdateRawOperand(operandIndex + 1, function->AddSSARegisterOrFlagList(outputs)); +} + + RegisterValue LowLevelILInstructionBase::GetValue() const { return function->GetExprValue(*(const LowLevelILInstruction*)this); @@ -1586,6 +1874,14 @@ void LowLevelILInstruction::VisitExprs(const std::function()) + i.VisitExprs(func); + break; + case LLIL_INTRINSIC_SSA: + for (auto& i : GetParameterExprs()) + i.VisitExprs(func); + break; default: break; } @@ -1840,6 +2136,16 @@ ExprId LowLevelILInstruction::CopyTo(LowLevelILFunction* dest, subExprHandler(AsTwoOperandWithCarry().GetLeftExpr()), subExprHandler(AsTwoOperandWithCarry().GetRightExpr()), subExprHandler(AsTwoOperandWithCarry().GetCarryExpr())); + case LLIL_INTRINSIC: + for (auto& i : GetParameterExprs()) + params.push_back(subExprHandler(i)); + return dest->Intrinsic(GetOutputRegisterOrFlagList(), GetIntrinsic(), + params, *this); + case LLIL_INTRINSIC_SSA: + for (auto& i : GetParameterExprs()) + params.push_back(subExprHandler(i)); + return dest->IntrinsicSSA(GetOutputSSARegisterOrFlagList(), GetIntrinsic(), + params, *this); default: throw LowLevelILInstructionAccessException(); } @@ -2104,6 +2410,15 @@ SSARegister LowLevelILInstruction::GetLowSSARegister() const } +uint32_t LowLevelILInstruction::GetIntrinsic() const +{ + size_t operandIndex; + if (GetOperandIndexForUsage(IntrinsicLowLevelOperandUsage, operandIndex)) + return GetRawOperandAsRegister(operandIndex); + throw LowLevelILInstructionAccessException(); +} + + int64_t LowLevelILInstruction::GetConstant() const { size_t operandIndex; @@ -2243,6 +2558,24 @@ LowLevelILSSAFlagList LowLevelILInstruction::GetSourceSSAFlags() const } +LowLevelILRegisterOrFlagList LowLevelILInstruction::GetOutputRegisterOrFlagList() const +{ + size_t operandIndex; + if (GetOperandIndexForUsage(OutputRegisterOrFlagListLowLevelOperandUsage, operandIndex)) + return GetRawOperandAsRegisterOrFlagList(operandIndex); + throw LowLevelILInstructionAccessException(); +} + + +LowLevelILSSARegisterOrFlagList LowLevelILInstruction::GetOutputSSARegisterOrFlagList() const +{ + size_t operandIndex; + if (GetOperandIndexForUsage(OutputSSARegisterOrFlagListLowLevelOperandUsage, operandIndex)) + return GetRawOperandAsSSARegisterOrFlagList(operandIndex); + throw LowLevelILInstructionAccessException(); +} + + LowLevelILIndexList LowLevelILInstruction::GetSourceMemoryVersions() const { size_t operandIndex; @@ -2760,7 +3093,7 @@ ExprId LowLevelILFunction::CallSSA(const vector& output, ExprId des AddExprWithLocation(LLIL_CALL_OUTPUT_SSA, loc, 0, 0, newMemoryVer, output.size() * 2, AddSSARegisterList(output)), dest, AddExprWithLocation(LLIL_CALL_STACK_SSA, loc, 0, 0, stack.reg, stack.version, prevMemoryVer), - AddExprWithLocation(LLIL_CALL_PARAM_SSA, loc, 0, 0, + AddExprWithLocation(LLIL_CALL_PARAM, loc, 0, 0, params.size(), AddOperandList(params))); } @@ -2772,7 +3105,7 @@ ExprId LowLevelILFunction::SystemCallSSA(const vector& output, cons AddExprWithLocation(LLIL_CALL_OUTPUT_SSA, loc, 0, 0, newMemoryVer, output.size() * 2, AddSSARegisterList(output)), AddExprWithLocation(LLIL_CALL_STACK_SSA, loc, 0, 0, stack.reg, stack.version, prevMemoryVer), - AddExprWithLocation(LLIL_CALL_PARAM_SSA, loc, 0, 0, + AddExprWithLocation(LLIL_CALL_PARAM, loc, 0, 0, params.size(), AddOperandList(params))); } @@ -2879,6 +3212,24 @@ ExprId LowLevelILFunction::SystemCall(const ILSourceLocation& loc) } +ExprId LowLevelILFunction::Intrinsic(const vector& outputs, uint32_t intrinsic, + const vector& params, const ILSourceLocation& loc) +{ + return AddExprWithLocation(LLIL_INTRINSIC, loc, 0, 0, + outputs.size(), AddRegisterOrFlagList(outputs), intrinsic, + AddExprWithLocation(LLIL_CALL_PARAM, loc, 0, 0, params.size(), AddOperandList(params))); +} + + +ExprId LowLevelILFunction::IntrinsicSSA(const vector& outputs, uint32_t intrinsic, + const vector& params, const ILSourceLocation& loc) +{ + return AddExprWithLocation(LLIL_INTRINSIC_SSA, loc, 0, 0, + outputs.size() * 2, AddSSARegisterOrFlagList(outputs), intrinsic, + AddExprWithLocation(LLIL_CALL_PARAM, loc, 0, 0, params.size(), AddOperandList(params))); +} + + ExprId LowLevelILFunction::Breakpoint(const ILSourceLocation& loc) { return AddExprWithLocation(LLIL_BP, loc, 0, 0); -- cgit v1.3.1