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
        private void DbgTrace(string aType, SymAddress aOriginalAddress, TArmInstructionSet aOriginalISet)
        {
            StringBuilder lines = new StringBuilder();

            lines.AppendLine("   " + aType);
            //
            if (iStateData.LastBranch.IsKnown)
            {
                lines.AppendLine(string.Format("      using: {0} 0x{1} to go...",
                                               iBranchAddress.AddressBinary,
                                               iBranchAddress.AddressHex)
                                 );
                lines.AppendLine(string.Format("       from: {0} 0x{1} {2} 0x{3:x8} {4}",
                                               aOriginalAddress.AddressBinary,
                                               aOriginalAddress.AddressHex,
                                               ETMDecodeState.MakeInstructionSetPrefix(aOriginalISet),
                                               aOriginalAddress,
                                               iStateData.Engine.LookUpSymbol(aOriginalAddress))
                                 );
                lines.AppendLine(string.Format("         to: {0} 0x{1} {2} 0x{3:x8} {4}",
                                               iStateData.CurrentAddress.AddressBinary,
                                               iStateData.CurrentAddress.AddressHex,
                                               ETMDecodeState.MakeInstructionSetPrefix(iStateData.CurrentInstructionSet),
                                               iStateData.CurrentAddress,
                                               iStateData.Engine.LookUpSymbol(iStateData.CurrentAddress))
                                 );
            }
            //
            Trace(lines.ToString());
        }
Beispiel #3
0
        public void FlushChanges()
        {
            TArmInstructionSet originalInstructionSet = iStateData.CurrentInstructionSet;
            SymAddress         originalAddress        = new SymAddress(iStateData.CurrentAddress.Address);

            //if ( !IsLastInstructionCancelled )
            {
                // Set known address
                iStateData.SetKnownAddressBits(iBranchAddress.Address,
                                               iBranchAddress.KnownBits,
                                               TETMBranchType.EBranchExplicit);

                // Handle a change in security mode
                if (iSecurityMode != TArmSecurityMode.EUnknown)
                {
                    iStateData.CurrentSecurityMode = iSecurityMode;
                }

                if (iExceptionType != TArmExceptionType.EUnknown)
                {
                    iStateData.CurrentException = iExceptionType;
                }

                // Handle a change in instruction set
                if (iStateData.CurrentInstructionSet != iInstructionSet)
                {
                    iStateData.CurrentInstructionSet = iInstructionSet;
                }
            }

            DbgTrace(originalAddress, originalInstructionSet);
        }
        public static string ToString(TArmInstructionSet aInstructionSet)
        {
            string ret = string.Empty;

            //
            switch (aInstructionSet)
            {
            case TArmInstructionSet.EARM:
                ret = "[A]";
                break;

            case TArmInstructionSet.ETHUMB:
                ret = "[T]";
                break;

            case TArmInstructionSet.EJAZELLE:
                ret = "[J]";
                break;

            default:
                ret = "[?]";
                break;
            }
            //
            return(ret);
        }
Beispiel #5
0
        internal void OnBranch(uint aAddress, TArmInstructionSet aInstructionSet, TArmExceptionType aExceptionType, TETMBranchType aBranchType)
        {
            if (Branch != null)
            {
                ETMBranch branch = new ETMBranch(new SymAddress(aAddress), iBranchCounter, aBranchType, aInstructionSet, aExceptionType);

                // Try to find a symbol
                SymbolCollection col = null;
                Symbol           sym = LookUpSymbol(aAddress, out col);
                //
                if (sym != null)
                {
                    branch.Symbol = sym;
                }
                else if (col != null)
                {
                    branch.SymbolText = string.Format("Unknown Symbol from \'{0}\'", col.FileName.FileNameInHost);
                }

                // Cascade event
                Branch(branch);
            }

            ++iBranchCounter;
        }
Beispiel #6
0
        private void OnAddress(SymByte aByte)
        {
            int  byteNumber = 4 - iBytesRemaining;
            uint val        = aByte.LShift(byteNumber * 8);

            iAddress |= val;

            if (--iBytesRemaining == 0)
            {
                // Save for tracing purposes
                SymAddress         originalAddress        = new SymAddress(base.StateData.CurrentAddress.Address);
                TArmInstructionSet originalInstructionSet = base.StateData.CurrentInstructionSet;

                // Set new branch address
                TArmInstructionSet newInstructionSet = iInformationByte.InstructionSet;
                uint address = iAddress;
                if ((address & 0x1) == 0x1)
                {
                    // We branched to THUMB, hence change of instruction set...
                    address          &= 0xFFFFFFFE;
                    newInstructionSet = TArmInstructionSet.ETHUMB;
                }

                // Store address etc - always 32 bit full address during I-SYNC
                base.StateData.CurrentInstructionSet = newInstructionSet;
                base.StateData.SetKnownAddressBits(address, 32, TETMBranchType.EBranchExplicit);

                // And output debug trace...
                Trace(originalAddress, originalInstructionSet, base.StateData.CurrentAddress, newInstructionSet);

                // We're done
                iState = TState.EStateIdle;
            }
        }
Beispiel #7
0
 public virtual bool ProvideInstructions(uint aAddress, TArmInstructionSet aInstructionSet, int aCount, out IArmInstruction[] aInstructions)
 {
     lock ( iAlwaysActivatedCollections )
     {
         bool ret = iAlwaysActivatedCollections.GetInstructions(aAddress, aInstructionSet, aCount, out aInstructions);
         return(ret);
     }
 }
Beispiel #8
0
 public ETMBranch(SymAddress aAddress, int aNumber, TETMBranchType aType, TArmInstructionSet aInstructionSet, TArmExceptionType aExceptionType)
 {
     iAddress        = aAddress;
     iNumber         = aNumber;
     iType           = aType;
     iInstructionSet = aInstructionSet;
     iExceptionType  = aExceptionType;
 }
Beispiel #9
0
        public override IArmInstruction ConvertToInstruction(uint aAddress, TArmInstructionSet aInstructionSet, uint aRawValue)
        {
            CodePlugin plugin = this.Plugin;

            IArmInstruction[] ret = plugin.ProvisioningManager.InstructionLibrary.ConvertToInstructions(aInstructionSet, new uint[1] {
                aRawValue
            }, aAddress);
            System.Diagnostics.Debug.Assert(ret != null && ret.Length == 1);
            return(ret[0]);
        }
        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);
        }
Beispiel #11
0
 private void DbgTrace(SymAddress aOriginalAddress, TArmInstructionSet aOriginalISet)
 {
     if (Count == 5)
     {
         DbgTrace("BRANCH-F", aOriginalAddress, aOriginalISet);
     }
     else
     {
         DbgTrace("BRANCH-P", aOriginalAddress, aOriginalISet);
     }
 }
Beispiel #12
0
        public static uint InstructionSize(TArmInstructionSet aSet)
        {
            uint ret = 2;

            //
            if (aSet == TArmInstructionSet.EARM)
            {
                ret = 4;
            }
            //
            return(ret);
        }
Beispiel #13
0
        private void Trace(SymAddress aOriginalAddress, TArmInstructionSet aOriginalISet, SymAddress aNewAddress, TArmInstructionSet aNewISet)
        {
            System.Diagnostics.Debug.Assert(base.StateData.LastBranch.IsKnown);
            //
            StringBuilder lines = new StringBuilder();

            lines.AppendLine("   I-SYNC");
            lines.AppendLine(string.Format("       from: {0} 0x{1:x8} {2}", ETMDecodeState.MakeInstructionSetPrefix(aOriginalISet), aOriginalAddress, StateData.Engine.LookUpSymbol(aOriginalAddress)));
            lines.AppendLine(string.Format("         to: {0} 0x{1:x8} {2}", ETMDecodeState.MakeInstructionSetPrefix(aNewISet), aNewAddress, StateData.Engine.LookUpSymbol(aNewAddress)));
            //
            base.Trace(lines.ToString());
        }
        internal void SetPC(uint aAddress, TArmInstructionSet aInstructionSet)
        {
            iPC.Address            = aAddress;
            iCurrentInstructionSet = aInstructionSet;

            // If BBC mode is enabled, i.e. branches are output even when a direct branch is taken
            // then we don't need to emit a branch event when seeing a 'Direct' branch type.
            bool isBBCModeEnabled = Config.BBCModeEnabled;

            if (isBBCModeEnabled == false && iPC.IsKnown)
            {
                iEngine.OnBranch(iPC, iCurrentInstructionSet, iCurrentException, TETMBranchType.EBranchDirect);
            }
        }
Beispiel #15
0
        public AccInstructionList LoadInstructions(uint aAddress, int aCount, TArmInstructionSet aType)
        {
            AccInstructionList ret = new AccInstructionList();

            // Get list of instructions from code engine
            IArmInstruction[] basicInstructions = null;
            bool available = iCodeView.GetInstructions(aAddress, aType, aCount, out basicInstructions);

            if (available)
            {
                // Convert the basic instructions into the different types
                // we can handle
                ret.AddRange(basicInstructions);
            }
            //
            return(ret);
        }
Beispiel #16
0
        private void TraceDirectBranch(SymAddress aOriginalAddress, TArmInstructionSet aOriginalISet, SymAddress aNewAddress, TArmInstructionSet aNewISet)
        {
            StringBuilder lines = new StringBuilder();

            lines.AppendLine("   BRANCH-D");
            //
            if (base.StateData.LastBranch.IsKnown)
            {
                lines.AppendLine(string.Format("       from: {0} 0x{1:x8} {2}", ETMDecodeState.MakeInstructionSetPrefix(aOriginalISet), aOriginalAddress, StateData.Engine.LookUpSymbol(aOriginalAddress)));
                lines.AppendLine(string.Format("         to: {0} 0x{1:x8} {2}", ETMDecodeState.MakeInstructionSetPrefix(aNewISet), aNewAddress, StateData.Engine.LookUpSymbol(aNewAddress)));
            }
            else
            {
            }
            //
            base.Trace(lines.ToString());
        }
Beispiel #17
0
        private void GetPrologueInstructions()
        {
            TArmInstructionSet instSet = CPU.CurrentProcessorMode;
            uint address = FunctionStartingAddressWithoutType;

            // Let's get unadulterated instruction counts
            int instCount = iPrologueInstructionCount;

            if (address > 0 && instCount > 0)
            {
                iInstructions = CodeHelper.LoadInstructions(address, instCount, instSet);
            }
            else
            {
                iInstructions = new AccInstructionList();
            }

            // Verify that we have the expected number of instructions.
            // If, for some reason, the code provider does not supply
            // any Prologue instructions, then we should bail out.
            int actual = iInstructions.Count;

            if (actual != instCount)
            {
                throw new Exception(string.Format("Prologue instructions unavailable or insufficient @ address: 0x{0:x8} - expected: {1}, received: {2}", FunctionStartingAddressWithoutType, instCount, actual));
            }

            // Since we fetch all the instructions from a function (leading up to the current address)
            // we may have lots more instructions that we'd ideally normally expect to see form part
            // of the function prologue. Normally, we cap the prologue instruction count at ~19 instructions,
            // so therefore we should disable any instructions beyond this maximum.
            for (int i = KMaxPrologueInstructionCount - 1; i < iInstructions.Count; i++)
            {
                iInstructions[i].Ignored = true;
            }

            // Run the instructions through the pre-filter. We tell the
            // instruction list how many instructions through the current function
            // we are because this helps to identify whether a branch has been
            // executed as the last instruction, or whether we artificially limited
            // the preamble, in which case the branch was "probably" not taken.
            iInstructions.Prefilter(iPrologueInstructionCount);
            iInstructions.DebugPrint(iEngine as ITracer);
        }
        public bool GetInstructions(uint aAddress, TArmInstructionSet aInstructionSet, int aCount, out IArmInstruction[] aInstructions)
        {
            // First check with the relocated/activated code collections,
            // i.e. RAM-loaded code that has been fixed up.
            bool ret = iRelocator.CollectionList.GetInstructions(aAddress, aInstructionSet, aCount, out aInstructions);

            if (ret == false)
            {
                foreach (CodeSource source in SourceManager)
                {
                    if (source.Contains(aAddress))
                    {
                        ret = source.ProvideInstructions(aAddress, aInstructionSet, aCount, out aInstructions);
                        break;
                    }
                }
            }
            //
            return(ret);
        }
Beispiel #19
0
        public IArmInstruction[] ConvertToInstructions(TArmInstructionSet aInstructionSet, uint[] aRawInstructions, uint aStartingAddress)
        {
            IArmInstruction[] ret = null;
            //
            switch (aInstructionSet)
            {
            case TArmInstructionSet.EARM:
                ret = ConvertToArm(aRawInstructions, aStartingAddress);
                break;

            case TArmInstructionSet.ETHUMB:
                ret = ConvertToThumb(aRawInstructions, aStartingAddress);
                break;

            default:
                throw new NotSupportedException();
            }
            //
            return(ret);
        }
Beispiel #20
0
        public static string MakeInstructionSetPrefix(TArmInstructionSet aInstructionSet)
        {
            string instSet;

            switch (aInstructionSet)
            {
            default:
            case TArmInstructionSet.EARM:
                instSet = "[A]";
                break;

            case TArmInstructionSet.ETHUMB:
                instSet = "[T]";
                break;

            case TArmInstructionSet.EJAZELLE:
                instSet = "[J]";
                break;
            }
            return(instSet);
        }
Beispiel #21
0
        protected static int CompressionLeftShiftCount(TArmInstructionSet aIS)
        {
            int ret = 2;

            // Interpret the bytes to form an address based upon current
            // instruction set.
            switch (aIS)
            {
            default:
            case TArmInstructionSet.EARM:
                break;

            case TArmInstructionSet.ETHUMB:
                ret = 1;
                break;

            case TArmInstructionSet.EJAZELLE:
                ret = 0;
                break;
            }
            //
            return(ret);
        }
Beispiel #22
0
 public bool GetInstructions(uint aAddress, TArmInstructionSet aInstructionSet, int aCount, out IArmInstruction[] aInstructions)
 {
     return(DoGetInstructions(aAddress, aInstructionSet, aCount, out aInstructions));
 }
Beispiel #23
0
        private bool HandleTHUMBMultiInstructionBranch(uint aInstruction1, uint aInstruction2)
        {
            bool branched = false;

            // THUMB multi branch with link exchange instruction - consumes 32 bits
            // of the instruction pipeline, i.e. instructions @ aIndex and aIndex+1 both
            // consumed.
            //
            // Check the signature is correct:
            //
            // NB:
            //   The first Thumb instruction has H == 10 and supplies the high part of the
            //   branch offset. This instruction sets up for the subroutine call and is
            //   shared between the BL and BLX forms.
            //
            //   The second Thumb instruction has H == 11 (for BL) or H == 01 (for BLX). It
            //   supplies the low part of the branch offset and causes the subroutine call
            //   to take place.
            //
            //  15   14   13   12 11   10                        0
            // ----------------------------------------------------
            //  1    1    1      H     <---     offset_11      -->
            //
            // mask1  =      11 00000000000
            // value1 =      10 00000000000
            //           111 11 10111010101
            // mask2  =       1 00000000000
            // value2 =       1 00000000000
            //           111 10 11111111111
            bool inst1Valid = ((aInstruction1 & 0x1800) == 0x1000);
            bool inst2Valid = ((aInstruction2 & 0x0800) == 0x0800);

            if (inst1Valid && inst2Valid)
            {
                TArmInstructionSet    newInstructionSet = TArmInstructionSet.ETHUMB;
                TMultiPartThumbBranch branchType        = TMultiPartThumbBranch.ETHUMBBL;
                if ((aInstruction2 & 0x1800) == 0x0800)
                {
                    branchType        = TMultiPartThumbBranch.ETHUMBBLX;
                    newInstructionSet = TArmInstructionSet.EARM;
                }

                // We subtract two, because we're already handling the second instruction
                // and the address is relative to the first.
                uint address = base.StateData.CurrentAddress - 2;

                // 111 10 00000000100
                //    100000000000000
                //
                int instImmediate1 = SignExtend11BitTo32BitTHUMB(aInstruction1 & 0x7FF, 12);
                address  = (uint)(address + instImmediate1);
                address += 4;

                // 111 01 11101011010
                //        11111111111 (0x7FF)
                //        11101011010 = 0x75A * 2 = EB4
                //
                // 111 01 11011100010
                //        11011100010 = 0X6E2 * 2 = DC4
                //
                //

                // Second instruction
                uint instImmediate2 = (aInstruction2 & 0x7FF) * 2;
                address += instImmediate2;

                // For BLX, the resulting address is forced to be word-aligned by
                // clearing bit[1].
                if (branchType == TMultiPartThumbBranch.ETHUMBBLX)
                {
                    address = address & 0xFFFFFFFD;
                }

                base.StateData.SetPC(address, newInstructionSet);
                branched = true;
            }
            else
            {
                // Oops. We ran out of instructions. This shouldn't ever happen
                // assuming that the P-HEADER's are synched properly.
                throw new ETMException("ERROR - synchronisation lost with P-HEADERS - 2nd THUMB BLX instruction missing");
            }

            return(branched);
        }
Beispiel #24
0
        protected override bool DoGetInstructions(uint aAddress, TArmInstructionSet aInstructionSet, int aCount, out IArmInstruction[] aInstructions)
        {
            bool ret = iQueryAPI.GetInstructions(aAddress, aInstructionSet, aCount, out aInstructions);

            return(ret);
        }
Beispiel #25
0
 public IArmInstruction[] ConvertToInstructions(TArmInstructionSet aInstructionSet, uint[] aRawInstructions, uint aStartingAddress)
 {
     IArmInstruction[] ret = iManager.InstructionLibrary.ConvertToInstructions(aInstructionSet, aRawInstructions, aStartingAddress);
     return(ret);
 }
Beispiel #26
0
 protected ArmBaseInstruction(TArmInstructionSet aInstructionSet)
 {
     iInstructionSet = aInstructionSet;
 }
Beispiel #27
0
 public IArmInstruction[] ConvertRawValuesToInstructions(TArmInstructionSet aInstructionSet, uint[] aRawValues, uint aStartingAddress)
 {
     IArmInstruction[] ret = iProvider.ConvertToInstructions(aInstructionSet, aRawValues, aStartingAddress);
     return(ret);
 }
Beispiel #28
0
 public abstract IArmInstruction ConvertToInstruction(uint aAddress, TArmInstructionSet aInstructionSet, uint aRawValue);
Beispiel #29
0
 protected abstract bool DoGetInstructions(uint aAddress, TArmInstructionSet aInstructionSet, int aCount, out IArmInstruction[] aInstructions);
Beispiel #30
0
        private bool CheckForBranch(ETMInstruction aInstruction)
        {
            bool branched = false;
            TArmInstructionSet originalInstructionSet = base.StateData.CurrentInstructionSet;
            SymAddress         originalAddress        = new SymAddress(base.StateData.CurrentAddress.Address);

            //
            if (base.StateData.LastBranch.IsKnown)
            {
                uint address = base.StateData.CurrentAddress;
                TArmInstructionSet instructionSet = base.StateData.CurrentInstructionSet;
                //
                if (instructionSet == TArmInstructionSet.EARM)
                {
                    if (iBranchMask_ARM_BOrBL.IsMatch(aInstruction))
                    {
                        // 1110 101 0 111111111111111111111101
                        int offset = SignExtend24BitTo32BitARM(aInstruction & 0x00FFFFFF);
                        base.StateData.SetPC((uint)(address + offset));
                        branched = true;
                    }
                    else if (iBranchMask_ARM_BLX_BranchToThumb.IsMatch(aInstruction))
                    {
                        // TODO: verify this - no data to test at the moment
                        int offset = SignExtend24BitTo32BitARM(aInstruction & 0x00FFFFFF);
                        base.StateData.SetPC((uint)(address + offset), TArmInstructionSet.ETHUMB);
                        branched = true;
                    }
                }
                else if (instructionSet == TArmInstructionSet.ETHUMB)
                {
                    if (iBranchMask_THUMB_B1.IsMatch(aInstruction))
                    {
                        //  15 14 13 12   11 -> 8    7    ->      0
                        // -----------------------------------------
                        //   1  1  0  1     cond     signed_immed_8
                        int offset = SignExtend8BitTo32BitTHUMB(aInstruction & 0xFF);
                        base.StateData.SetPC((uint)(address + offset));
                        branched = true;
                    }
                    else if (iBranchMask_THUMB_B2.IsMatch(aInstruction))
                    {
                        //  15 14 13 12 11   10        ->         0
                        // -----------------------------------------
                        //   1  1  0  1  1       signed_immed_11
                        int offset = SignExtend11BitTo32BitTHUMB(aInstruction & 0x7FF);
                        base.StateData.SetPC((uint)(address + offset));
                        branched = true;
                    }
                    else
                    {
                        ETMInstruction inst1      = base.StateData.LastInstruction;
                        bool           inst1Match = iBranchMask_THUMB_BLX_Part1.IsMatch(inst1.AIRawValue);
                        ETMInstruction inst2      = aInstruction;
                        bool           inst2Match = iBranchMask_THUMB_BLX_Part2.IsMatch(inst2.AIRawValue);
                        //
                        if (inst1Match && inst2Match)
                        {
                            branched = HandleTHUMBMultiInstructionBranch(inst1.AIRawValue, inst2.AIRawValue);
                            System.Diagnostics.Debug.Assert(branched == true);
                        }
                    }
                }
                else
                {
                    throw new NotSupportedException();
                }
            }
            if (branched)
            {
                base.StateData.IncrementProcessedInstructionCounter();
                TraceDirectBranch(originalAddress, originalInstructionSet, base.StateData.CurrentAddress, base.StateData.CurrentInstructionSet);
            }

            // Always cache the last processed instruction
            base.StateData.LastInstruction = aInstruction;
            return(branched);
        }