| 712 | |
| 713 | |
| 714 | bool GetLowLevelILForArmInstruction(Architecture* arch, uint64_t addr, LowLevelILFunction& il, Instruction& instr, size_t addrSize) |
| 715 | { |
| 716 | (void)arch; |
| 717 | (void)addr; |
| 718 | (void)addrSize; |
| 719 | InstructionOperand& op1 = instr.operands[0]; |
| 720 | InstructionOperand& op2 = instr.operands[1]; |
| 721 | InstructionOperand& op3 = instr.operands[2]; |
| 722 | InstructionOperand& op4 = instr.operands[3]; |
| 723 | InstructionOperand& op5 = instr.operands[4]; |
| 724 | InstructionOperand& op6 = instr.operands[5]; |
| 725 | LowLevelILLabel trueLabel, falseLabel, endLabel, loopBody, loopStart, loopExit; |
| 726 | uint32_t flagOperation[2] = {IL_FLAGWRITE_NONE, IL_FLAGWRITE_ALL}; |
| 727 | LowLevelILLabel trueCode, falseCode, endCode; |
| 728 | switch (instr.operation) |
| 729 | { |
| 730 | case ARMV7_ADD: |
| 731 | ConditionExecute(il, instr.cond, SetRegisterOrBranch(il, op1.reg, |
| 732 | il.Add(get_register_size(op1.reg), |
| 733 | ReadRegisterOrPointer(il, op2, addr), |
| 734 | ReadILOperand(il, op3, addr), flagOperation[instr.setsFlags]))); |
| 735 | break; |
| 736 | case ARMV7_ADDW: |
| 737 | ConditionExecute(il, instr.cond, SetRegisterOrBranch(il, op1.reg, |
| 738 | il.Add(get_register_size(op1.reg), |
| 739 | ReadRegisterOrPointer(il, op2, addr), |
| 740 | ReadILOperand(il, op3, addr), IL_FLAGWRITE_NONE))); |
| 741 | break; |
| 742 | case ARMV7_ADC: |
| 743 | ConditionExecute(il, instr.cond, SetRegisterOrBranch(il, op1.reg, |
| 744 | il.AddCarry(get_register_size(op1.reg), |
| 745 | ReadRegisterOrPointer(il, op2, addr), |
| 746 | ReadILOperand(il, op3, addr), il.Flag(IL_FLAG_C), flagOperation[instr.setsFlags]))); |
| 747 | break; |
| 748 | case ARMV7_ADR: |
| 749 | ConditionExecute(il, instr.cond, |
| 750 | SetRegisterOrBranch(il, op1.reg, |
| 751 | il.ConstPointer(get_register_size(op1.reg), op2.imm))); |
| 752 | break; |
| 753 | case ARMV7_AND: |
| 754 | ConditionExecute(il, instr.cond, SetRegisterOrBranch(il, op1.reg, |
| 755 | il.And(get_register_size(op1.reg), |
| 756 | ReadRegisterOrPointer(il, op2, addr), |
| 757 | ReadILOperand(il, op3, addr), flagOperation[instr.setsFlags]))); |
| 758 | break; |
| 759 | case ARMV7_ASR: |
| 760 | ConditionExecute(il, instr.cond, |
| 761 | SetRegisterOrBranch(il, op1.reg, |
| 762 | il.ArithShiftRight(get_register_size(op2.reg), |
| 763 | ReadRegisterOrPointer(il, op2, addr), |
| 764 | ReadILOperand(il, op3, addr), flagOperation[instr.setsFlags]))); |
| 765 | break; |
| 766 | case ARMV7_B: |
| 767 | ConditionalJump(arch, il, instr.cond, addrSize, op1.imm, addr + 4); |
| 768 | return false; |
| 769 | case ARMV7_BFC: |
| 770 | ConditionExecute(il, instr.cond, SetRegisterOrBranch(il, op1.reg, |
| 771 | il.And(get_register_size(op1.reg), ReadRegisterOrPointer(il, op1, addr), |
no test coverage detected