public LoadConstant(ArmConditionCode condition, Variable dst, uint constant) : base(condition) { Constant = constant; VariableDefs.Add(dst); Operands.Add((true, dst)); }
public Branch(ArmConditionCode condition, BasicBlock destination, Variable cpsr = null) : base(condition) { if (destination == null) { throw new ArgumentNullException(nameof(destination)); } Destination = destination; if (condition != ArmConditionCode.ARM_CC_AL && cpsr != null) { VariableUses.Add(cpsr); FlagsUseOperand = cpsr; } }
public static ArmConditionCode GetOppositeCondition(ArmConditionCode cc) { switch (cc) { case ArmConditionCode.Invalid: return(ArmConditionCode.Invalid); case ArmConditionCode.ARM_CC_EQ: return(ArmConditionCode.ARM_CC_NE); case ArmConditionCode.ARM_CC_NE: return(ArmConditionCode.ARM_CC_EQ); case ArmConditionCode.ARM_CC_HS: return(ArmConditionCode.ARM_CC_LO); case ArmConditionCode.ARM_CC_LO: return(ArmConditionCode.ARM_CC_HS); case ArmConditionCode.ARM_CC_MI: return(ArmConditionCode.ARM_CC_PL); case ArmConditionCode.ARM_CC_PL: return(ArmConditionCode.ARM_CC_MI); case ArmConditionCode.ARM_CC_VS: return(ArmConditionCode.ARM_CC_VC); case ArmConditionCode.ARM_CC_VC: return(ArmConditionCode.ARM_CC_VS); case ArmConditionCode.ARM_CC_HI: return(ArmConditionCode.ARM_CC_LS); case ArmConditionCode.ARM_CC_LS: return(ArmConditionCode.ARM_CC_HI); case ArmConditionCode.ARM_CC_GE: return(ArmConditionCode.ARM_CC_LT); case ArmConditionCode.ARM_CC_LT: return(ArmConditionCode.ARM_CC_GE); case ArmConditionCode.ARM_CC_GT: return(ArmConditionCode.ARM_CC_LE); case ArmConditionCode.ARM_CC_LE: return(ArmConditionCode.ARM_CC_GT); case ArmConditionCode.ARM_CC_AL: return(ArmConditionCode.Invalid); default: throw new ArgumentOutOfRangeException(nameof(cc), cc, null); } }
public string BasicBlockGraphToDot() { int id = 0; var uniqueIds = new Dictionary <Instruction, int>(); var sb = new StringBuilder(); sb.AppendLine("digraph func {"); foreach (var block in BasicBlocks) { foreach (var successor in block.Successors) { ArmConditionCode cond = ArmConditionCode.ARM_CC_AL; BasicBlock otherSucc; if (successor.BlockConditionInstruction != null) { cond = successor.BlockCondition; } else if (block.Successors.Count == 2 && (otherSucc = block.Successors.First(s => s != successor)).BlockConditionInstruction != null) { cond = ArmUtil.GetOppositeCondition(otherSucc.BlockCondition); } else if (block.Instructions.Last() is Branch b) { if (successor == b.Destination) { cond = b.Condition == block.BlockCondition ? ArmConditionCode.ARM_CC_AL : b.Condition; } else if (block.Successors.Count == 2) { cond = ArmUtil.GetOppositeCondition(b.Condition); } } sb.AppendLine($"\"0x{block.Address:X08}\" -> \"0x{successor.Address:X08}\" [label=\"{cond}\"];"); } } sb.AppendLine("}"); return(sb.ToString()); }
public BasicBlock(uint address, ArmConditionCode blockCondition = ArmConditionCode.Invalid) { Address = address; BlockCondition = blockCondition; }
public override IRExpression GetIRPredicateCode(IRContext context, ArmConditionCode condition) { switch (Instruction.Id) { case ArmInstructionId.ARM_INS_AND: case ArmInstructionId.ARM_INS_LSR: switch (condition) { case ArmConditionCode.ARM_CC_EQ: return(GetIROperand(context, 0).Cast(IRPrimitive.U32) == 0u); case ArmConditionCode.ARM_CC_NE: return(GetIROperand(context, 0).Cast(IRPrimitive.U32) != 0u); case ArmConditionCode.ARM_CC_HS: case ArmConditionCode.ARM_CC_LO: case ArmConditionCode.ARM_CC_MI: case ArmConditionCode.ARM_CC_PL: case ArmConditionCode.ARM_CC_VS: case ArmConditionCode.ARM_CC_VC: case ArmConditionCode.ARM_CC_HI: case ArmConditionCode.ARM_CC_LS: case ArmConditionCode.ARM_CC_GE: case ArmConditionCode.ARM_CC_LT: case ArmConditionCode.ARM_CC_GT: case ArmConditionCode.ARM_CC_LE: throw new NotImplementedException("Unimplemented and condition"); case ArmConditionCode.ARM_CC_AL: return(true); default: throw new ArgumentException("Invalid condition!"); } case ArmInstructionId.ARM_INS_CMP: case ArmInstructionId.ARM_INS_SUB: switch (condition) { case ArmConditionCode.ARM_CC_EQ: return(GetIROperand(context, 0) == GetIRSecondOperand(context, 1)); case ArmConditionCode.ARM_CC_NE: return(GetIROperand(context, 0) != GetIRSecondOperand(context, 1)); case ArmConditionCode.ARM_CC_HS: return(GetIROperand(context, 0).UnsignedGreaterEqualAs(GetIRSecondOperand(context, 1))); case ArmConditionCode.ARM_CC_LO: return(GetIROperand(context, 0).UnsignedLessThan(GetIRSecondOperand(context, 1))); case ArmConditionCode.ARM_CC_MI: return((GetIROperand(context, 0) - GetIRSecondOperand(context, 1)).LessThan(0)); case ArmConditionCode.ARM_CC_PL: return((GetIROperand(context, 0) - GetIRSecondOperand(context, 1)).GreaterThan(0)); case ArmConditionCode.ARM_CC_VS: throw new NotImplementedException("Unimplemented cmp condition"); case ArmConditionCode.ARM_CC_VC: throw new NotImplementedException("Unimplemented cmp condition"); case ArmConditionCode.ARM_CC_HI: return(GetIROperand(context, 0).UnsignedGreaterThan(GetIRSecondOperand(context, 1))); case ArmConditionCode.ARM_CC_LS: return(GetIROperand(context, 0).UnsignedLessEqualAs(GetIRSecondOperand(context, 1))); case ArmConditionCode.ARM_CC_GE: return(GetIROperand(context, 0).GreaterEqualAs(GetIRSecondOperand(context, 1))); case ArmConditionCode.ARM_CC_LT: return(GetIROperand(context, 0).LessThan(GetIRSecondOperand(context, 1))); case ArmConditionCode.ARM_CC_GT: return(GetIROperand(context, 0).GreaterThan(GetIRSecondOperand(context, 1))); case ArmConditionCode.ARM_CC_LE: return(GetIROperand(context, 0).LessEqualAs(GetIRSecondOperand(context, 1))); case ArmConditionCode.ARM_CC_AL: return(true); default: throw new ArgumentException("Invalid condition!"); } default: throw new NotImplementedException("Unimplemented instruction!"); } }