private IArmInstruction[] ConvertToThumb(uint[] aRawInstructions, uint aStartingAddress) { // TODO: optimise this List <IArmInstruction> ret = new List <IArmInstruction>(); // uint address = aStartingAddress; for (int i = 0; i < aRawInstructions.Length; i++, address += 2) { uint raw = aRawInstructions[i]; foreach (ThumbInstruction inst in iThumbInstructions) { if (inst.Matches(raw)) { Type type = inst.GetType(); ConstructorInfo ctor = type.GetConstructor(new Type[] { }); ThumbInstruction copy = (ThumbInstruction)ctor.Invoke(new object[] { }); copy.AIAddress = address; copy.AIRawValue = raw; ret.Add(copy); Disassemble(copy); break; } } } // return(ret.ToArray()); }
internal override void Process(ArmPrologueHelper aProlog) { IArmInstruction instruction = base.Instruction; // Only unconditional instructions are handled if (instruction.AIConditionCode == TArmInstructionCondition.AL) { if (instruction is ArmInstruction) { ArmInstruction armInst = (ArmInstruction)instruction; // if (armInst is Arm_LoadOrStoreMultiple) { Arm_LoadOrStoreMultiple lsmInstruction = (Arm_LoadOrStoreMultiple)instruction; // We're looking for store operations if (lsmInstruction.DataTransferType == TArmDataTransferType.EStore) { // We're looking for LSM's that involve SP. if (lsmInstruction.BaseRegister == TArmRegisterType.EArmReg_SP) { if (lsmInstruction is Arm_LoadOrStoreMultiple_GP) { Arm_LoadOrStoreMultiple_GP gpLsmInstruction = (Arm_LoadOrStoreMultiple_GP)lsmInstruction; HandleDTOperation(aProlog, gpLsmInstruction.Registers); } else if (lsmInstruction is Arm_LoadOrStoreMultiple_VFP) { Arm_LoadOrStoreMultiple_VFP vfpLsmInstruction = (Arm_LoadOrStoreMultiple_VFP)lsmInstruction; HandleDTOperation(aProlog, vfpLsmInstruction.Registers); } } } } } else if (instruction is ThumbInstruction) { ThumbInstruction thumbInst = (ThumbInstruction)instruction; // if (thumbInst is Thumb_LoadOrStoreMultiple) { // Special case that loads or stores multiple registers Thumb_LoadOrStoreMultiple lsmThumb = (Thumb_LoadOrStoreMultiple)thumbInst; if (lsmThumb.DataTransferType == TArmDataTransferType.EStore && lsmThumb.Rd == TArmRegisterType.EArmReg_SP) { HandleDTOperation(aProlog, lsmThumb.Registers); } else { } } else if (thumbInst is Thumb_LDR_RelativeToPC) { // When the Prologue needs to establish a working stack slurry, then often // the scratch registers are used to build up a large subtraction from SP. HandleDTLoad(aProlog, thumbInst as Thumb_LDR_RelativeToPC); } } else { throw new NotSupportedException("Instruction type not supported"); } } }