public void StackBuildingElementConstructed(StackAlgorithm aAlg, StackOutputEntry aEntry) { lock (this) { iEngine.DataOutput.InsertAsFirstEntry(aEntry); } }
private void EmitElement(StackOutputEntry aEntry) { // Debug support if (base.Engine.Verbose) { StringBuilder line = new StringBuilder("[AccurateAlgorithm] "); // if (aEntry.IsCurrentStackPointerEntry) { line.Append("[C] "); } else if (aEntry.IsRegisterBasedEntry) { const int KNormalAddressWidth = 10; string prefix = "[ " + aEntry.AssociatedRegisterName; prefix = prefix.PadRight(KNormalAddressWidth - 2); prefix += " ]"; line.Append(prefix); } else if (aEntry.IsGhost) { line.Append("[G] "); } else if (aEntry.IsOutsideCurrentStackRange) { line.Append(" "); } else { line.AppendFormat("[{0:x8}]", aEntry.Address); } line.AppendFormat(" {0:x8} {1}", aEntry.Data, aEntry.DataAsString); if (aEntry.Symbol != null) { string baseAddressOffset = aEntry.Symbol.ToStringOffset(aEntry.Data); line.AppendFormat("{0} {1}", baseAddressOffset, aEntry.Symbol.Name); } else if (aEntry.AssociatedBinary != string.Empty) { line.AppendFormat("{0} {1}", SymbolConstants.KUnknownOffset, aEntry.AssociatedBinary); } base.Trace(line.ToString()); } // Count the number of accurate entries if (aEntry.IsAccurate) { ++iAccurateEntryCount; } // Flush entry base.StackObserver.StackBuildingElementConstructed(this, aEntry); }
private void CreateEntries() { if (iStackOutput != null) { int count = iStackOutput.Count; // for (int i = 0; i < count; i++) { StackOutputEntry dataOutputEntry = iStackOutput[i]; // CIStackEntry entry = new CIStackEntry(this, dataOutputEntry); base.AddChild(entry); } } }
internal CIStackEntry(CIStack aParent, StackOutputEntry aEntry) : base(aParent.Container, aParent) { iEntry = aEntry; // If the stack entry references a symbol then associate it with // the parent dictionary immediately. if (aEntry.Symbol != null) { ICISymbolManager symbolManager = this.SymbolManager; CISymbol symbol = symbolManager.SymbolDictionary.Register(aEntry.Symbol); this.AddChild(symbol); base.Trace(string.Format("[CIStackEntry] address: 0x{0:x8}, symbol: {1}, symId: {2}", iEntry.Data, symbol.Symbol, symbol.Id)); } }
private bool AddLRAndPC() { bool addedLRandPC = false; // ArmRegisterCollection regs = base.Engine.Registers; // If we're inside the stack address range, then poke in the PC and LR values if (regs.Count > 0) { // Working bottom up, so LR should go on the stack first if (regs.Contains(TArmRegisterType.EArmReg_LR)) { ArmRegister regLR = regs[TArmRegisterType.EArmReg_LR]; StackOutputEntry entryLR = new StackOutputEntry(0, regLR.Value, base.DebugEngineView); entryLR.IsRegisterBasedEntry = true; entryLR.IsOutsideCurrentStackRange = true; entryLR.AssociatedRegister = regLR.RegType; EmitElement(entryLR); } // Then the PC... if (regs.Contains(TArmRegisterType.EArmReg_PC)) { ArmRegister regPC = regs[TArmRegisterType.EArmReg_PC]; StackOutputEntry entryPC = new StackOutputEntry(0, regPC.Value, base.DebugEngineView); entryPC.IsRegisterBasedEntry = true; entryPC.IsOutsideCurrentStackRange = true; entryPC.AssociatedRegister = regPC.RegType; EmitElement(entryPC); } // Even if they weren't added, we at least attempted to addd them addedLRandPC = true; } return(addedLRandPC); }
protected override void PerformOperation() { // Get the source data we need to reconstruct and signal we're about to start StackSourceData sourceData = base.SourceData; // Get the output data sink StackOutputData outputData = base.OutputData; outputData.Clear(); outputData.AlgorithmName = Name; // Get the address range of the stack pointer data AddressRange pointerRange = base.Engine.AddressInfo.StackPointerRange; AddressRange pointerRangeExtended = base.Engine.AddressInfo.StackPointerRangeWithExtensionArea; // Indicates if we added LR and PC to the call stack bool addedLRandPC = false; // Get registers ArmRegisterCollection regs = base.Engine.Registers; foreach (DataBufferUint sourceEntry in sourceData.GetUintEnumerator()) { // Check if it is within the stack domain, taking into account // our extended range if (pointerRangeExtended.Contains(sourceEntry.Address)) { StackOutputEntry outputEntry = new StackOutputEntry(sourceEntry.Address, sourceEntry.Uint, base.DebugEngineView); // Is it the element tht corresponds to the current value of SP? bool isCurrentSPEntry = (outputEntry.AddressRange.Contains(base.Engine.AddressInfo.Pointer)); outputEntry.IsCurrentStackPointerEntry = isCurrentSPEntry; // Is it within the pure 'stack pointer' address range? bool outsidePureStackPointerRange = !pointerRange.Contains(sourceEntry.Address); outputEntry.IsOutsideCurrentStackRange = outsidePureStackPointerRange; // These are never accurate, but neither are they ghosts outputEntry.IsAccurate = false; outputEntry.IsGhost = false; // Save entry EmitElement(outputEntry); // If we're inside the stack address range, then poke in the PC and LR values if (isCurrentSPEntry) { System.Diagnostics.Debug.Assert(!addedLRandPC); addedLRandPC = AddLRAndPC(); } } else { // Nope, ignore it... } NotifyEvent(TEvent.EReadingProgress); ++iDWordIndex; } // If the stack overflowed, then SP might be outside of the stack range. Therefore // LR and PC will not be added yet. if (!addedLRandPC) { AddLRAndPC(); } }
private void EmitElement(StackOutputEntry aEntry) { // Flush entry base.StackObserver.StackBuildingElementConstructed(this, aEntry); }
private void CreateStackOutput() { // Get the source data we need to reconstruct and signal we're about to start StackSourceData sourceData = base.SourceData; // Get the output data sink StackOutputData outputData = base.OutputData; outputData.Clear(); outputData.AlgorithmName = Name; // Get the address range of the stack pointer data AddressRange pointerRange = base.Engine.AddressInfo.StackPointerRange; AddressRange pointerRangeExtended = base.Engine.AddressInfo.StackPointerRangeWithExtensionArea; foreach (DataBufferUint sourceEntry in sourceData.GetUintEnumerator()) { // Check if it is within the stack domain, taking into account // our extended range if (pointerRangeExtended.Contains(sourceEntry.Address)) { StackOutputEntry outputEntry = new StackOutputEntry(sourceEntry.Address, sourceEntry.Uint, base.DebugEngineView); // Is it the element that corresponds to the current value of SP? bool isCurrentSPEntry = (outputEntry.AddressRange.Contains(base.Engine.AddressInfo.Pointer)); // Is it within the pure 'stack pointer' address range? bool outsidePureStackPointerRange = !pointerRange.Contains(sourceEntry.Address); outputEntry.IsOutsideCurrentStackRange = outsidePureStackPointerRange; // Is it a ghost? if (outputEntry.Symbol != null) { ArmStackFrame realStackFrame = FrameByStackAddress(sourceEntry.Address); outputEntry.IsAccurate = (realStackFrame != null); outputEntry.IsGhost = (realStackFrame == null); } // Save entry EmitElement(outputEntry); // If we're inside the stack address range, then poke in the PC and LR values if (isCurrentSPEntry) { outputEntry.IsCurrentStackPointerEntry = true; // Working bottom up, so LR should go on the stack first ArmStackFrame stackFrameLR = FrameByRegisterType(TArmRegisterType.EArmReg_LR); if (stackFrameLR != null) { StackOutputEntry entryLR = new StackOutputEntry(0, stackFrameLR.Data, base.DebugEngineView); entryLR.IsRegisterBasedEntry = true; entryLR.IsOutsideCurrentStackRange = true; entryLR.AssociatedRegister = stackFrameLR.AssociatedRegister; EmitElement(entryLR); } // Then the PC... ArmStackFrame stackFramePC = FrameByRegisterType(TArmRegisterType.EArmReg_PC); if (stackFramePC != null) { StackOutputEntry entryPC = new StackOutputEntry(0, stackFramePC.Data, base.DebugEngineView); entryPC.IsRegisterBasedEntry = true; entryPC.IsOutsideCurrentStackRange = true; entryPC.AssociatedRegister = stackFramePC.AssociatedRegister; EmitElement(entryPC); } } } else { // Nope, ignore it... } NotifyEvent(TEvent.EReadingProgress); ++iDWordIndex; } }