internal ETMInstruction FetchInstruction(uint aAddress) { ETMInstruction ret = new ETMInstruction(aAddress); // bool gotCode = false; if (this.LastBranch.IsKnown && Engine.DebugEngineView != null) { DbgViewCode codeView = Engine.DebugEngineView.Code; // In the case where we've been asked to fetch the code from the exception // vector, then bypass the rom/rofs code entirely. bool isExceptionVector = Config.IsExceptionVector(aAddress); if (isExceptionVector) { System.Diagnostics.Debug.Assert(this.CurrentInstructionSet == TArmInstructionSet.EARM); TArmExceptionVector vector = Config.MapToExceptionVector(aAddress); uint rawInstruction = Config.GetExceptionVector(vector); ret.Instruction = codeView.ConvertToInstruction(aAddress, TArmInstructionSet.EARM, rawInstruction); } else { IArmInstruction[] instructions = null; gotCode = codeView.GetInstructions(aAddress, CurrentInstructionSet, 1, out instructions); // if (gotCode) { System.Diagnostics.Debug.Assert(instructions != null && instructions.Length == 1); ret.Instruction = instructions[0]; } } } // return(ret); }
private void ProcessFormat2Conditions(ETMPcktPHeaderFormat2 aHeader) { string atom1TypeName = TraceAtomTypeName(aHeader.Atom1Type); string atom2TypeName = TraceAtomTypeName(aHeader.Atom2Type); base.Trace("{0} - 1 x {1}, 1 x {2}", base.MakeTracePacketPrefix("P-HEADER(2)"), atom1TypeName, atom2TypeName); // First instruction { uint address1 = base.StateData.CurrentAddress; ETMInstruction inst1 = base.StateData.FetchInstruction(address1); TraceAtom(aHeader.Atom1Type, inst1); if (aHeader.Atom1Type == ETMPcktPHeaderBase.TAtomType.EAtomE_Passed) { bool branched = CheckForBranch(inst1); if (!branched) { base.StateData.IncrementPC(); } } else { base.StateData.IncrementPC(); } } // Second instruction { uint address2 = base.StateData.CurrentAddress; ETMInstruction inst2 = base.StateData.FetchInstruction(address2); TraceAtom(aHeader.Atom2Type, inst2); if (aHeader.Atom2Type == ETMPcktPHeaderBase.TAtomType.EAtomE_Passed) { bool branched = CheckForBranch(inst2); if (!branched) { base.StateData.IncrementPC(); } } else { base.StateData.IncrementPC(); } } // Spacer - to make the verbose output easier to read... base.Trace(string.Empty); }
private void ProcessFormat1Conditions(ETMPcktPHeaderFormat1 aHeader) { string pass = aHeader.ConditionCountPassed > 0 ? string.Format("{0} x PASS", aHeader.ConditionCountPassed) : string.Empty; string fail = aHeader.ConditionCountFailed > 0 ? string.Format(", {0} x FAIL", aHeader.ConditionCountFailed) : string.Empty; base.Trace("{0} - {1} {2}", base.MakeTracePacketPrefix("P-HEADER(1)"), pass, fail); // Get the total number of instructions processed int totalExecutedInstructionCount = aHeader.ConditionCountPassed + aHeader.ConditionCountFailed; // Trace passed instructions for (int i = 0; i < aHeader.ConditionCountPassed; i++) { uint address = base.StateData.CurrentAddress; ETMInstruction instruction = base.StateData.FetchInstruction(address); // TraceAtom(ETMPcktPHeaderBase.TAtomType.EAtomE_Passed, instruction); // We will now check the current instruction to see if it's a branch. // If it is, then we don't need to increment the instruction address, because // the explicit branch will set a new PC location. // // Note that in the case of a thumb BLX, i.e. two 16-bit instructions which // interpreted together form a +/-4mb branch address, we also need // to ensure that the bool branched = CheckForBranch(instruction); if (!branched) { base.StateData.IncrementPC(); } } // Trace and failed instructions if (aHeader.ConditionCountFailed > 0) { uint address = base.StateData.CurrentAddress; ETMInstruction instruction = base.StateData.FetchInstruction(address); // TraceAtom(ETMPcktPHeaderBase.TAtomType.EAtomN_Failed, instruction); base.StateData.IncrementPC(); } // Spacer - to make the verbose output easier to read... base.Trace(string.Empty); }
private void TraceAtom(ETMPcktPHeaderBase.TAtomType aType, ETMInstruction aInstruction) { string atomTypeName = TraceAtomTypeName(aType); // StringBuilder text = new StringBuilder(); text.AppendFormat("{0} 0x{1}: {2} {3}", base.StateData.NumberOfProcessedInstructions.ToString().PadLeft(6, ' '), base.StateData.CurrentAddress.AddressHex, base.StateData.CurrentAddress.AddressBinary, atomTypeName ); // if (base.StateData.LastBranch.IsKnown) { string disasm = aInstruction.ToString(); text.Append(" " + disasm); } // base.Trace(text.ToString()); }
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); }