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);
        }
Beispiel #2
0
        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;
                        }
                    }
                }
            }
        }
Beispiel #5
0
 public AccInstDataProcessing(IArmInstruction aInstruction)
     : base(aInstruction)
 {
     System.Diagnostics.Debug.Assert(base.Instruction.AIGroup == TArmInstructionGroup.EGroupDataProcessing);
 }
Beispiel #6
0
 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;
 }