mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-09-27 00:34:57 +08:00
Merge remote-tracking branch 'origin/GP-6904_d-millar_unwinder_tests--SQUASHED'
This commit is contained in:
-6
@@ -85,9 +85,6 @@ public class DebuggerTrackLocationTrait {
|
||||
if (!value.getEntryKey().equals(TraceStackFrame.KEY_PC)) {
|
||||
return;
|
||||
}
|
||||
if (!value.getEntryKey().equals(TraceStackFrame.KEY_SP)) {
|
||||
return;
|
||||
}
|
||||
TraceStackFrame frame = value.getParent().queryInterface(TraceStackFrame.class);
|
||||
if (frame == null) {
|
||||
return;
|
||||
@@ -107,9 +104,6 @@ public class DebuggerTrackLocationTrait {
|
||||
if (!value.getEntryKey().equals(TraceStackFrame.KEY_PC)) {
|
||||
return;
|
||||
}
|
||||
if (!value.getEntryKey().equals(TraceStackFrame.KEY_SP)) {
|
||||
return;
|
||||
}
|
||||
TraceStackFrame frame = value.getParent().queryInterface(TraceStackFrame.class);
|
||||
if (frame == null) {
|
||||
return;
|
||||
|
||||
+11
@@ -819,12 +819,23 @@ public enum VariableValueUtils {
|
||||
public UnwoundFrame<WatchValue> getStackFrame(Function function,
|
||||
StackUnwindWarningSet warnings, TaskMonitor monitor, boolean required) {
|
||||
synchronized (lock) {
|
||||
// We unwind first from the current frame, because we want the closest function
|
||||
// match above the current frame.
|
||||
// NB: Unwinding from 0 may provide better info
|
||||
AnalysisUnwoundFrame<WatchValue> currentFrame =
|
||||
unwinder.findMatchForFunction(function, coordinates, warnings, monitor);
|
||||
if (currentFrame != null) {
|
||||
return currentFrame;
|
||||
}
|
||||
|
||||
// Unwind from 0 for functions below the current frame
|
||||
currentFrame = unwinder.findMatchForFunction(function, coordinates.frame(0),
|
||||
warnings, monitor);
|
||||
if (currentFrame != null) {
|
||||
warnings.add(new CustomStackUnwindWarning("Unwinding from frame 0"));
|
||||
return currentFrame;
|
||||
}
|
||||
|
||||
warnings.add(
|
||||
new CustomStackUnwindWarning("Failed to find match for %s among the %d frames."
|
||||
.formatted(function, unwinder.getRecoveredFrameCount())));
|
||||
|
||||
+26
-23
@@ -195,26 +195,19 @@ public class StackUnwinder {
|
||||
continue;
|
||||
}
|
||||
|
||||
Address pcVal = pcOrSp(frame, coord, state, true);
|
||||
Address pcVal = pcOrSp(frame, coord, warnings, state, true);
|
||||
if (pcVal == null) {
|
||||
// True if not frame 0 and no access to regs or stack
|
||||
break;
|
||||
}
|
||||
|
||||
ProgramLocation loc = getProgramLocation(coord.getSnap(), pcVal);
|
||||
if (loc != null && service != null) {
|
||||
UnwindInfo info =
|
||||
service.getUnwindInfo(loc.getProgram(), loc.getAddress(), monitor);
|
||||
if (info == null) {
|
||||
// Continue here to generate a frame and prevent recalculating info
|
||||
try {
|
||||
StaticAndUnwind sau = computeUnwindInfo(coord.getSnap(), pcVal, monitor);
|
||||
info = sau.info();
|
||||
}
|
||||
catch (CancelledException e) {
|
||||
warnings.add(
|
||||
new CustomStackUnwindWarning("Unwind cancelled for frame " + level));
|
||||
}
|
||||
}
|
||||
// Created UnwindInfo if it doesn't exist
|
||||
service.getUnwindInfo(loc.getProgram(), loc.getAddress(), monitor);
|
||||
}
|
||||
|
||||
Address spVal = pcOrSp(frame, coord, state, false);
|
||||
Address spVal = pcOrSp(frame, coord, warnings, state, false);
|
||||
|
||||
SavedRegisterMap nextRegisterMap = updateMap(frame, registerMap);
|
||||
frame = unwind(coord, pcVal, spVal, state, nextRegisterMap, monitor);
|
||||
@@ -243,7 +236,7 @@ public class StackUnwinder {
|
||||
}
|
||||
|
||||
private Address pcOrSp(AnalysisUnwoundFrame<WatchValue> frame,
|
||||
DebuggerCoordinates coordinates,
|
||||
DebuggerCoordinates coordinates, StackUnwindWarningSet warnings,
|
||||
PcodeExecutorState<?> state, boolean getPc) {
|
||||
TraceThread thread = coordinates.getThread();
|
||||
int level = coordinates.getFrame();
|
||||
@@ -284,20 +277,30 @@ public class StackUnwinder {
|
||||
UnwindInfo prevInfo = frame.getUnwindInfo();
|
||||
Address base = frame.getBasePointer();
|
||||
try {
|
||||
regVal = getPc ? prevInfo.computeNextPc(base, state, codeSpace, pc)
|
||||
: prevInfo.computeNextSp(base);
|
||||
if (regVal != null) {
|
||||
return regVal;
|
||||
if (prevInfo.ofReturn() == null) {
|
||||
warnings.add(new CustomStackUnwindWarning(
|
||||
"Indeterminate return from frame preceding " + level));
|
||||
}
|
||||
else {
|
||||
regVal = getPc ? prevInfo.computeNextPc(base, state, codeSpace, pc)
|
||||
: prevInfo.computeNextSp(base);
|
||||
if (regVal != null) {
|
||||
return regVal;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
// Use the fall-back case below
|
||||
warnings.add(new CustomStackUnwindWarning(e.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
// Fall-back to current frame
|
||||
RegisterValue rval = state.inspectRegisterValue(getPc ? pc : sp);
|
||||
return codeSpace.getAddress(rval.getUnsignedValue().longValue());
|
||||
if (coordinates.getFrame() == 0) {
|
||||
RegisterValue rval = state.inspectRegisterValue(getPc ? pc : sp);
|
||||
return codeSpace.getAddress(rval.getUnsignedValue().longValue());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
record StaticAndUnwind(Address staticPc, UnwindInfo info) {}
|
||||
|
||||
+648
File diff suppressed because it is too large
Load Diff
+661
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user