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); }
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()); }
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); }
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; }
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; } }
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); } }
public ETMBranch(SymAddress aAddress, int aNumber, TETMBranchType aType, TArmInstructionSet aInstructionSet, TArmExceptionType aExceptionType) { iAddress = aAddress; iNumber = aNumber; iType = aType; iInstructionSet = aInstructionSet; iExceptionType = aExceptionType; }
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); }
private void DbgTrace(SymAddress aOriginalAddress, TArmInstructionSet aOriginalISet) { if (Count == 5) { DbgTrace("BRANCH-F", aOriginalAddress, aOriginalISet); } else { DbgTrace("BRANCH-P", aOriginalAddress, aOriginalISet); } }
public static uint InstructionSize(TArmInstructionSet aSet) { uint ret = 2; // if (aSet == TArmInstructionSet.EARM) { ret = 4; } // return(ret); }
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); } }
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); }
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()); }
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); }
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); }
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); }
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); }
public bool GetInstructions(uint aAddress, TArmInstructionSet aInstructionSet, int aCount, out IArmInstruction[] aInstructions) { return(DoGetInstructions(aAddress, aInstructionSet, aCount, out aInstructions)); }
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); }
protected override bool DoGetInstructions(uint aAddress, TArmInstructionSet aInstructionSet, int aCount, out IArmInstruction[] aInstructions) { bool ret = iQueryAPI.GetInstructions(aAddress, aInstructionSet, aCount, out aInstructions); return(ret); }
public IArmInstruction[] ConvertToInstructions(TArmInstructionSet aInstructionSet, uint[] aRawInstructions, uint aStartingAddress) { IArmInstruction[] ret = iManager.InstructionLibrary.ConvertToInstructions(aInstructionSet, aRawInstructions, aStartingAddress); return(ret); }
protected ArmBaseInstruction(TArmInstructionSet aInstructionSet) { iInstructionSet = aInstructionSet; }
public IArmInstruction[] ConvertRawValuesToInstructions(TArmInstructionSet aInstructionSet, uint[] aRawValues, uint aStartingAddress) { IArmInstruction[] ret = iProvider.ConvertToInstructions(aInstructionSet, aRawValues, aStartingAddress); return(ret); }
public abstract IArmInstruction ConvertToInstruction(uint aAddress, TArmInstructionSet aInstructionSet, uint aRawValue);
protected abstract bool DoGetInstructions(uint aAddress, TArmInstructionSet aInstructionSet, int aCount, out IArmInstruction[] aInstructions);
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); }