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 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; } }