public bool GetInstructions(uint aAddress, TArmInstructionSet aInstructionSet, int aCount, out IArmInstruction[] aInstructions) { Predicate <CodeCollection> predicate = delegate(CodeCollection collection) { return(collection.Contains(aAddress)); }; // bool ret = false; // lock ( iCollections ) { CodeCollection found = iCollections.Find(predicate); if (found != null) { // Implement last-access optimisation ret = found.GetInstructions(aAddress, aInstructionSet, aCount, out aInstructions); } else { aInstructions = new IArmInstruction[0]; } } // return(ret); }
internal override void Process(ArmPrologueHelper aProlog) { IArmInstruction instruction = base.Instruction; // Only unconditional instructions are handled if (instruction.AIConditionCode == TArmInstructionCondition.AL) { // Two heuristically observed requirements: // // 1) It must be an immediate instruction // 2) It must apply with source & destination registers both being SP if (instruction is ArmInstruction) { // Aim is to detect modifications to SP (i.e. reservation of stack space) Arm_DataProcessing armDpInst = instruction as Arm_DataProcessing; // 1) Must supply an immediate value if (armDpInst != null && armDpInst.SuppliesImmediate) { // 2) Must apply to SP if (armDpInst.Rd == TArmRegisterType.EArmReg_SP && armDpInst.Rn == TArmRegisterType.EArmReg_SP) { uint immediate = armDpInst.Immediate; HandleDPOperation(armDpInst.OperationType, immediate, aProlog); } } } else if (instruction is ThumbInstruction) { Thumb_AddOrSubtract thumbDpInst = instruction as Thumb_AddOrSubtract; // 2) Must apply to SP if (thumbDpInst.Rd == TArmRegisterType.EArmReg_SP) { // 1) Must supply an immediate value if (thumbDpInst != null && thumbDpInst.SuppliesImmediate) { uint immediate = thumbDpInst.Immediate; HandleDPOperation(thumbDpInst.OperationType, immediate, aProlog); } else if (thumbDpInst is Thumb_Add_2Regs_High) { // Handle the case where one register supplies the number of // words by which the stack pointer is incremented. Used when // a large stack allocation is made. } } } else { throw new NotSupportedException("Instruction type not supported"); } } }
public bool GetInstructions(uint aAddress, TArmInstructionSet aInstructionSet, int aCount, out IArmInstruction[] aInstructions) { bool valid = false; aInstructions = new IArmInstruction[0]; // We need the code and the instruction converter if (IsCodeAvailable && IfaceInstructionConverter != null) { // Check range is valid AddressRange range = new AddressRange(iBaseAddress, 0); range.UpdateMax(range.Min + iCode.Length); uint extent = aAddress + ((uint)aCount * (uint)aInstructionSet); // valid = range.Contains(aAddress) && range.Contains(extent); if (valid) { List <uint> rawInstructions = new List <uint>(); // using (SymbianStreamReaderLE reader = SymbianStreamReaderLE.New(new MemoryStream(iCode))) { uint address = aAddress - iBaseAddress; reader.Seek(address); // for (int i = 0; i < aCount; i++) { uint value = 0; // switch (aInstructionSet) { case TArmInstructionSet.ETHUMB: value = reader.ReadUInt16(); break; case TArmInstructionSet.EARM: value = reader.ReadUInt32(); break; default: case TArmInstructionSet.EJAZELLE: throw new NotSupportedException("Jazelle is not supported"); } // rawInstructions.Add(value); address += (uint)aInstructionSet; } } // aInstructions = iInstructionConverter.ConvertRawValuesToInstructions(aInstructionSet, rawInstructions.ToArray(), aAddress); } } // Return empty array if not valid return(valid); }
internal override void Prefilter(AccInstructionList aInstructions, int aMyIndex, int aInstructionCountOffsetToPC) { if (this.Ignored == false) { int count = aInstructions.Count; // if (base.Instruction.AIConditionCode == TArmInstructionCondition.AL) { // As soon as we see any unconditional branch statement we can be sure that we are past the Prologue. for (int i = aMyIndex + 1; i < count; i++) { aInstructions[i].Ignored = true; } } else { // Count the number of interesting instructions before the conditional branch int interestingInstructionCount = 0; for (int i = 0; i < aMyIndex; i++) { AccInstruction accInstruction = aInstructions[i]; IArmInstruction inst = accInstruction.Instruction; // bool involvesSP = inst.QueryInvolvement(TArmRegisterType.EArmReg_SP); if (involvesSP) { ++interestingInstructionCount; } } // If we have seen at least one interesting instruction then assume prologue is complete. if (interestingInstructionCount >= 1) { for (int i = aMyIndex; i < count; i++) { aInstructions[i].Ignored = true; } } } } }
public AccInstDataProcessing(IArmInstruction aInstruction) : base(aInstruction) { System.Diagnostics.Debug.Assert(base.Instruction.AIGroup == TArmInstructionGroup.EGroupDataProcessing); }
public ETMInstruction(uint aAddress, IArmInstruction aInstruction) { iAddress = new SymAddress(aAddress); iInstruction = aInstruction; }
public AccInstUnknown(IArmInstruction aInstruction) : base(aInstruction) { }
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"); } } }
public AccInstDataTransfer(IArmInstruction aInstruction) : base(aInstruction) { System.Diagnostics.Debug.Assert(base.Instruction.AIGroup == TArmInstructionGroup.EGroupDataTransfer); }
public AccInstBranch(IArmInstruction aInstruction) : base(aInstruction) { System.Diagnostics.Debug.Assert(base.Instruction.AIGroup == TArmInstructionGroup.EGroupBranch); }
protected AccInstruction(IArmInstruction aInstruction) { iInstruction = aInstruction; }