mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 10:49:34 +02:00
Merge remote-tracking branch 'origin/patch'
This commit is contained in:
commit
cfaa8b9032
5 changed files with 102 additions and 71 deletions
|
@ -93,6 +93,9 @@ public interface LogicalBreakpointInternal extends LogicalBreakpoint {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
// volatile reads
|
||||||
|
Bookmark eBookmark = this.eBookmark;
|
||||||
|
Bookmark dBookmark = this.dBookmark;
|
||||||
if (eBookmark != null) {
|
if (eBookmark != null) {
|
||||||
return String.format("<enabled %s(%s) at %s in %s>", eBookmark.getTypeString(),
|
return String.format("<enabled %s(%s) at %s in %s>", eBookmark.getTypeString(),
|
||||||
eBookmark.getCategory(), eBookmark.getAddress(), program.getName());
|
eBookmark.getCategory(), eBookmark.getAddress(), program.getName());
|
||||||
|
@ -127,6 +130,9 @@ public interface LogicalBreakpointInternal extends LogicalBreakpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void deleteFromProgram() {
|
public void deleteFromProgram() {
|
||||||
|
// volatile reads
|
||||||
|
Bookmark eBookmark = this.eBookmark;
|
||||||
|
Bookmark dBookmark = this.dBookmark;
|
||||||
try (UndoableTransaction tid =
|
try (UndoableTransaction tid =
|
||||||
UndoableTransaction.start(program, "Clear breakpoint", false)) {
|
UndoableTransaction.start(program, "Clear breakpoint", false)) {
|
||||||
BookmarkManager bookmarkManager = program.getBookmarkManager();
|
BookmarkManager bookmarkManager = program.getBookmarkManager();
|
||||||
|
@ -193,6 +199,7 @@ public interface LogicalBreakpointInternal extends LogicalBreakpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Bookmark getBookmark() {
|
public Bookmark getBookmark() {
|
||||||
|
Bookmark eBookmark = this.eBookmark;
|
||||||
if (eBookmark != null) {
|
if (eBookmark != null) {
|
||||||
return eBookmark;
|
return eBookmark;
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,6 +81,7 @@ public class DefaultTraceRecorder implements TraceRecorder {
|
||||||
|
|
||||||
public DefaultTraceRecorder(DebuggerModelServicePlugin plugin, Trace trace, TargetObject target,
|
public DefaultTraceRecorder(DebuggerModelServicePlugin plugin, Trace trace, TargetObject target,
|
||||||
DefaultDebuggerTargetTraceMapper mapper) {
|
DefaultDebuggerTargetTraceMapper mapper) {
|
||||||
|
trace.addConsumer(this);
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
this.tool = plugin.getTool();
|
this.tool = plugin.getTool();
|
||||||
this.trace = trace;
|
this.trace = trace;
|
||||||
|
@ -99,9 +100,6 @@ public class DefaultTraceRecorder implements TraceRecorder {
|
||||||
this.symbolRecorder = new DefaultSymbolRecorder(this);
|
this.symbolRecorder = new DefaultSymbolRecorder(this);
|
||||||
this.timeRecorder = new DefaultTimeRecorder(this);
|
this.timeRecorder = new DefaultTimeRecorder(this);
|
||||||
this.objectManager = new TraceObjectManager(target, mapper, this);
|
this.objectManager = new TraceObjectManager(target, mapper, this);
|
||||||
|
|
||||||
trace.addConsumer(this);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*---------------- OBJECT MANAGER METHODS -------------------*/
|
/*---------------- OBJECT MANAGER METHODS -------------------*/
|
||||||
|
@ -358,10 +356,15 @@ public class DefaultTraceRecorder implements TraceRecorder {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void invalidate() {
|
protected void invalidate() {
|
||||||
valid = false;
|
|
||||||
objectManager.disposeModelListeners();
|
objectManager.disposeModelListeners();
|
||||||
|
synchronized (this) {
|
||||||
|
if (!valid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
valid = false;
|
||||||
trace.release(this);
|
trace.release(this);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*---------------- FOCUS-SUPPORT METHODS -------------------*/
|
/*---------------- FOCUS-SUPPORT METHODS -------------------*/
|
||||||
|
|
||||||
|
|
|
@ -213,11 +213,6 @@ public class DebuggerStaticMappingServicePlugin extends Plugin
|
||||||
return new AddressRangeImpl(min, max);
|
return new AddressRangeImpl(min, max);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Program openStaticProgram() {
|
|
||||||
return ProgramURLUtils.openHackedUpGhidraURL(programManager, tool.getProject(),
|
|
||||||
mapping.getStaticProgramURL(), ProgramManager.OPEN_VISIBLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isStaticProgramOpen() {
|
public boolean isStaticProgramOpen() {
|
||||||
return program != null;
|
return program != null;
|
||||||
}
|
}
|
||||||
|
@ -389,31 +384,22 @@ public class DebuggerStaticMappingServicePlugin extends Plugin
|
||||||
return Collections.unmodifiableMap(result);
|
return Collections.unmodifiableMap(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void openAndCollectPrograms(AddressRange rng, Range<Long> span,
|
protected void collectMappedProgramURLsInView(AddressRange rng, Range<Long> span,
|
||||||
Set<Program> result, Set<Exception> failures) {
|
Set<URL> result) {
|
||||||
TraceAddressSnapRange tatr = new ImmutableTraceAddressSnapRange(rng, span);
|
TraceAddressSnapRange tatr = new ImmutableTraceAddressSnapRange(rng, span);
|
||||||
for (Entry<TraceAddressSnapRange, MappingEntry> out : outbound.entrySet()) {
|
for (Entry<TraceAddressSnapRange, MappingEntry> out : outbound.entrySet()) {
|
||||||
if (!out.getKey().intersects(tatr)) {
|
if (!out.getKey().intersects(tatr)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
MappingEntry me = out.getValue();
|
MappingEntry me = out.getValue();
|
||||||
try {
|
result.add(me.getStaticProgramURL());
|
||||||
result.add(me.openStaticProgram());
|
|
||||||
}
|
|
||||||
catch (Exception e) {
|
|
||||||
if (failures == null) {
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
failures.add(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<Program> openMappedProgramsInView(AddressSetView set, Range<Long> span,
|
public Set<URL> getMappedProgramURLsInView(AddressSetView set, Range<Long> span) {
|
||||||
Set<Exception> failures) {
|
Set<URL> result = new HashSet<>();
|
||||||
Set<Program> result = new HashSet<>();
|
|
||||||
for (AddressRange rng : set) {
|
for (AddressRange rng : set) {
|
||||||
openAndCollectPrograms(rng, span, result, failures);
|
collectMappedProgramURLsInView(rng, span, result);
|
||||||
}
|
}
|
||||||
return Collections.unmodifiableSet(result);
|
return Collections.unmodifiableSet(result);
|
||||||
}
|
}
|
||||||
|
@ -847,21 +833,25 @@ public class DebuggerStaticMappingServicePlugin extends Plugin
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<Program> getOpenMappedProgramsAtSnap(Trace trace, long snap) {
|
public Set<Program> getOpenMappedProgramsAtSnap(Trace trace, long snap) {
|
||||||
|
synchronized (lock) {
|
||||||
InfoPerTrace info = requireTrackedInfo(trace);
|
InfoPerTrace info = requireTrackedInfo(trace);
|
||||||
if (info == null) {
|
if (info == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return info.getOpenMappedProgramsAtSnap(snap);
|
return info.getOpenMappedProgramsAtSnap(snap);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ProgramLocation getOpenMappedLocation(TraceLocation loc) {
|
public ProgramLocation getOpenMappedLocation(TraceLocation loc) {
|
||||||
|
synchronized (lock) {
|
||||||
InfoPerTrace info = requireTrackedInfo(loc.getTrace());
|
InfoPerTrace info = requireTrackedInfo(loc.getTrace());
|
||||||
if (info == null) {
|
if (info == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return info.getOpenMappedLocations(loc.getAddress(), loc.getLifespan());
|
return info.getOpenMappedLocations(loc.getAddress(), loc.getLifespan());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected long getNonScratchSnap(TraceProgramView view) {
|
protected long getNonScratchSnap(TraceProgramView view) {
|
||||||
return view.getViewport().getTop(s -> s >= 0 ? s : null);
|
return view.getViewport().getTop(s -> s >= 0 ? s : null);
|
||||||
|
@ -869,6 +859,7 @@ public class DebuggerStaticMappingServicePlugin extends Plugin
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ProgramLocation getStaticLocationFromDynamic(ProgramLocation loc) {
|
public ProgramLocation getStaticLocationFromDynamic(ProgramLocation loc) {
|
||||||
|
synchronized (lock) {
|
||||||
loc = ProgramLocationUtils.fixLocation(loc, true);
|
loc = ProgramLocationUtils.fixLocation(loc, true);
|
||||||
TraceProgramView view = (TraceProgramView) loc.getProgram();
|
TraceProgramView view = (TraceProgramView) loc.getProgram();
|
||||||
Trace trace = view.getTrace();
|
Trace trace = view.getTrace();
|
||||||
|
@ -881,63 +872,93 @@ public class DebuggerStaticMappingServicePlugin extends Plugin
|
||||||
return ProgramLocationUtils.replaceAddress(loc, mapped.getProgram(),
|
return ProgramLocationUtils.replaceAddress(loc, mapped.getProgram(),
|
||||||
mapped.getByteAddress());
|
mapped.getByteAddress());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<TraceLocation> getOpenMappedLocations(ProgramLocation loc) {
|
public Set<TraceLocation> getOpenMappedLocations(ProgramLocation loc) {
|
||||||
|
synchronized (lock) {
|
||||||
InfoPerProgram info = requireTrackedInfo(loc.getProgram());
|
InfoPerProgram info = requireTrackedInfo(loc.getProgram());
|
||||||
if (info == null) {
|
if (info == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return info.getOpenMappedTraceLocations(loc.getByteAddress());
|
return info.getOpenMappedTraceLocations(loc.getByteAddress());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TraceLocation getOpenMappedLocation(Trace trace, ProgramLocation loc, long snap) {
|
public TraceLocation getOpenMappedLocation(Trace trace, ProgramLocation loc, long snap) {
|
||||||
|
synchronized (lock) {
|
||||||
InfoPerProgram info = requireTrackedInfo(loc.getProgram());
|
InfoPerProgram info = requireTrackedInfo(loc.getProgram());
|
||||||
if (info == null) {
|
if (info == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return info.getOpenMappedTraceLocation(trace, loc.getByteAddress(), snap);
|
return info.getOpenMappedTraceLocation(trace, loc.getByteAddress(), snap);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ProgramLocation getDynamicLocationFromStatic(TraceProgramView view,
|
public ProgramLocation getDynamicLocationFromStatic(TraceProgramView view,
|
||||||
ProgramLocation loc) {
|
ProgramLocation loc) {
|
||||||
TraceLocation tloc = getOpenMappedLocation(view.getTrace(), loc, getNonScratchSnap(view));
|
synchronized (lock) {
|
||||||
|
TraceLocation tloc =
|
||||||
|
getOpenMappedLocation(view.getTrace(), loc, getNonScratchSnap(view));
|
||||||
if (tloc == null) {
|
if (tloc == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return ProgramLocationUtils.replaceAddress(loc, view, tloc.getAddress());
|
return ProgramLocationUtils.replaceAddress(loc, view, tloc.getAddress());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<Program, Collection<MappedAddressRange>> getOpenMappedViews(Trace trace,
|
public Map<Program, Collection<MappedAddressRange>> getOpenMappedViews(Trace trace,
|
||||||
AddressSetView set, long snap) {
|
AddressSetView set, long snap) {
|
||||||
|
synchronized (lock) {
|
||||||
InfoPerTrace info = requireTrackedInfo(trace);
|
InfoPerTrace info = requireTrackedInfo(trace);
|
||||||
if (info == null) {
|
if (info == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return info.getOpenMappedViews(set, Range.singleton(snap));
|
return info.getOpenMappedViews(set, Range.singleton(snap));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<TraceSnap, Collection<MappedAddressRange>> getOpenMappedViews(Program program,
|
public Map<TraceSnap, Collection<MappedAddressRange>> getOpenMappedViews(Program program,
|
||||||
AddressSetView set) {
|
AddressSetView set) {
|
||||||
|
synchronized (lock) {
|
||||||
InfoPerProgram info = requireTrackedInfo(program);
|
InfoPerProgram info = requireTrackedInfo(program);
|
||||||
if (info == null) {
|
if (info == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return info.getOpenMappedViews(set);
|
return info.getOpenMappedViews(set);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<Program> openMappedProgramsInView(Trace trace, AddressSetView set, long snap,
|
public Set<Program> openMappedProgramsInView(Trace trace, AddressSetView set, long snap,
|
||||||
Set<Exception> failures) {
|
Set<Exception> failures) {
|
||||||
|
Set<URL> urls;
|
||||||
|
synchronized (lock) {
|
||||||
InfoPerTrace info = requireTrackedInfo(trace);
|
InfoPerTrace info = requireTrackedInfo(trace);
|
||||||
if (info == null) {
|
if (info == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return info.openMappedProgramsInView(set, Range.singleton(snap), failures);
|
urls = info.getMappedProgramURLsInView(set, Range.singleton(snap));
|
||||||
|
}
|
||||||
|
Set<Program> result = new HashSet<>();
|
||||||
|
for (URL url : urls) {
|
||||||
|
try {
|
||||||
|
Program program = ProgramURLUtils.openHackedUpGhidraURL(programManager,
|
||||||
|
tool.getProject(), url, ProgramManager.OPEN_VISIBLE);
|
||||||
|
result.add(program);
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
if (failures == null) {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
failures.add(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Collection<? extends Program> orderCurrentFirst(
|
protected Collection<? extends Program> orderCurrentFirst(
|
||||||
|
|
|
@ -79,6 +79,7 @@ public interface UndoableTransaction extends AutoCloseable {
|
||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
if (open) {
|
if (open) {
|
||||||
|
open = false;
|
||||||
endTransaction(commit);
|
endTransaction(commit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
/* ###
|
/* ###
|
||||||
* IP: GHIDRA
|
* IP: GHIDRA
|
||||||
* REVIEWED: YES
|
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -16,6 +15,8 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.framework.data;
|
package ghidra.framework.data;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
import ghidra.framework.model.*;
|
import ghidra.framework.model.*;
|
||||||
import ghidra.framework.plugintool.PluginTool;
|
import ghidra.framework.plugintool.PluginTool;
|
||||||
import ghidra.util.Msg;
|
import ghidra.util.Msg;
|
||||||
|
@ -23,8 +24,6 @@ import ghidra.util.SystemUtilities;
|
||||||
import ghidra.util.datastruct.WeakDataStructureFactory;
|
import ghidra.util.datastruct.WeakDataStructureFactory;
|
||||||
import ghidra.util.datastruct.WeakSet;
|
import ghidra.util.datastruct.WeakSet;
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <code>DomainObjectDBTransaction</code> represents an atomic undoable operation performed
|
* <code>DomainObjectDBTransaction</code> represents an atomic undoable operation performed
|
||||||
* on a single domain object.
|
* on a single domain object.
|
||||||
|
@ -145,7 +144,7 @@ class DomainObjectDBTransaction implements Transaction {
|
||||||
try {
|
try {
|
||||||
entry = list.get(transactionID - baseId);
|
entry = list.get(transactionID - baseId);
|
||||||
}
|
}
|
||||||
catch (ArrayIndexOutOfBoundsException e) {
|
catch (IndexOutOfBoundsException e) {
|
||||||
throw new IllegalStateException("Transaction not found");
|
throw new IllegalStateException("Transaction not found");
|
||||||
}
|
}
|
||||||
if (entry.status != NOT_DONE) {
|
if (entry.status != NOT_DONE) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue