mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-24 13:21:22 +08:00
Merge remote-tracking branch 'origin/GP-5379_Dan_fixKeyReuse--SQUASHED'
(Closes #7497)
This commit is contained in:
+48
-29
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -241,6 +241,7 @@ public interface DebuggerStaticMappingService {
|
||||
* @param entries the entries to add
|
||||
* @param monitor a monitor to cancel the operation
|
||||
* @param truncateExisting true to delete or truncate the lifespan of overlapping entries
|
||||
* @throws CancelledException if the user cancels
|
||||
* @see #addMapping(TraceLocation, ProgramLocation, long, boolean)
|
||||
* @throws TraceConflictedMappingException if a conflicting mapping overlaps the source and
|
||||
* {@code truncateExisting} is false.
|
||||
@@ -259,6 +260,7 @@ public interface DebuggerStaticMappingService {
|
||||
* @param entries the entries to add
|
||||
* @param monitor a monitor to cancel the operation
|
||||
* @param truncateExisting true to delete or truncate the lifespan of overlapping entries
|
||||
* @throws CancelledException if the user cancels
|
||||
* @see #addMapping(TraceLocation, ProgramLocation, long, boolean)
|
||||
*/
|
||||
void addSectionMappings(Collection<SectionMapEntry> entries, TaskMonitor monitor,
|
||||
@@ -275,6 +277,7 @@ public interface DebuggerStaticMappingService {
|
||||
* @param entries the entries to add
|
||||
* @param monitor a monitor to cancel the operation
|
||||
* @param truncateExisting true to delete or truncate the lifespan of overlapping entries
|
||||
* @throws CancelledException if the user cancels
|
||||
* @see #addMapping(TraceLocation, ProgramLocation, long, boolean)
|
||||
*/
|
||||
void addRegionMappings(Collection<RegionMapEntry> entries, TaskMonitor monitor,
|
||||
@@ -421,17 +424,18 @@ public interface DebuggerStaticMappingService {
|
||||
* The service maintains an index of likely module names to domain files in the active project.
|
||||
* This will search that index for the module's full file path. Failing that, it will search
|
||||
* just for the module's file name. Among the programs found, it first prefers those whose
|
||||
* module name list (see {@link ProgramModuleIndexer#setModulePaths(Program, List)}) include the
|
||||
* sought module. Then, it prefers those whose executable path (see
|
||||
* {@link Program#setExecutablePath(String)}) matches the sought module. Finally, it prefers
|
||||
* matches on the program name and the domain file name. Ties in name matching are broken by
|
||||
* looking for domain files in the same folders as those programs already mapped into the trace
|
||||
* in the given address space.
|
||||
* module name list includes the sought module. Then, it prefers those whose executable path
|
||||
* (see {@link Program#setExecutablePath(String)}) matches the sought module. Finally, it
|
||||
* prefers matches on the program name and the domain file name. Ties in name matching are
|
||||
* broken by looking for domain files in the same folders as those programs already mapped into
|
||||
* the trace in the given address space.
|
||||
*
|
||||
* @param space the fallback address space if the module is missing its base
|
||||
* @param module the trace module
|
||||
* @param snap the snapshot to consider
|
||||
* @return the, possibly empty, set of probable matches
|
||||
*/
|
||||
DomainFile findBestModuleProgram(AddressSpace space, TraceModule module);
|
||||
DomainFile findBestModuleProgram(AddressSpace space, TraceModule module, long snap);
|
||||
|
||||
/**
|
||||
* Propose a module map for the given module to the given program
|
||||
@@ -440,14 +444,15 @@ public interface DebuggerStaticMappingService {
|
||||
* Note, no sanity check is performed on the given parameters. This will simply propose the
|
||||
* given module-program pair. It is strongly advised to use
|
||||
* {@link ModuleMapProposal#computeScore()} to assess the proposal. Alternatively, use
|
||||
* {@link #proposeModuleMap(TraceModule, Collection)} to have the service select the best-scored
|
||||
* mapping from a collection of proposed programs.
|
||||
* {@link #proposeModuleMap(TraceModule, long, Collection)} to have the service select the
|
||||
* best-scored mapping from a collection of proposed programs.
|
||||
*
|
||||
* @param module the module to consider
|
||||
* @param snap the source snapshot key
|
||||
* @param program the destination program to consider
|
||||
* @return the proposal
|
||||
*/
|
||||
ModuleMapProposal proposeModuleMap(TraceModule module, Program program);
|
||||
ModuleMapProposal proposeModuleMap(TraceModule module, long snap, Program program);
|
||||
|
||||
/**
|
||||
* Compute the best-scored module map for the given module and programs
|
||||
@@ -460,10 +465,12 @@ public interface DebuggerStaticMappingService {
|
||||
* @see ModuleMapProposal#computeScore()
|
||||
*
|
||||
* @param module the module to consider
|
||||
* @param snap the source snapshot key
|
||||
* @param programs a set of proposed destination programs
|
||||
* @return the best-scored proposal, or {@code null} if no program is proposed
|
||||
*/
|
||||
ModuleMapProposal proposeModuleMap(TraceModule module, Collection<? extends Program> programs);
|
||||
ModuleMapProposal proposeModuleMap(TraceModule module, long snap,
|
||||
Collection<? extends Program> programs);
|
||||
|
||||
/**
|
||||
* Compute the "best" map of trace module to program for each given module given a collection of
|
||||
@@ -476,11 +483,13 @@ public interface DebuggerStaticMappingService {
|
||||
* {@code null} values.
|
||||
*
|
||||
* @param modules the modules to map
|
||||
* @param snap the source snapshot key
|
||||
* @param programs the set of proposed destination programs
|
||||
* @return the proposal
|
||||
*/
|
||||
Map<TraceModule, ModuleMapProposal> proposeModuleMaps(
|
||||
Collection<? extends TraceModule> modules, Collection<? extends Program> programs);
|
||||
Collection<? extends TraceModule> modules, long snap,
|
||||
Collection<? extends Program> programs);
|
||||
|
||||
/**
|
||||
* Propose a singleton section map from the given section to the given program memory block
|
||||
@@ -489,15 +498,17 @@ public interface DebuggerStaticMappingService {
|
||||
* Note, no sanity check is performed on the given parameters. This will simply give a singleton
|
||||
* map of the given entry. It is strongly advised to use
|
||||
* {@link SectionMapProposal#computeScore()} to assess the proposal. Alternatively, use
|
||||
* {@link #proposeSectionMap(TraceModule, Collection)} to have the service select the
|
||||
* {@link #proposeSectionMap(TraceModule, long, Collection)} to have the service select the
|
||||
* best-scored mapping from a collection of proposed programs.
|
||||
*
|
||||
* @param section the section to map
|
||||
* @param snap the source snapshot key
|
||||
* @param program the destination program
|
||||
* @param block the memory block in the destination program
|
||||
* @return the proposed map
|
||||
*/
|
||||
SectionMapProposal proposeSectionMap(TraceSection section, Program program, MemoryBlock block);
|
||||
SectionMapProposal proposeSectionMap(TraceSection section, long snap, Program program,
|
||||
MemoryBlock block);
|
||||
|
||||
/**
|
||||
* Propose a section map for the given module to the given program
|
||||
@@ -506,14 +517,15 @@ public interface DebuggerStaticMappingService {
|
||||
* Note, no sanity check is performed on the given parameters. This will do its best to map
|
||||
* sections from the given module to memory blocks in the given program. It is strongly advised
|
||||
* to use {@link SectionMapProposal#computeScore()} to assess the proposal. Alternatively, use
|
||||
* {@link #proposeSectionMap(TraceModule, Collection)} to have the service select the
|
||||
* {@link #proposeSectionMap(TraceModule, long, Collection)} to have the service select the
|
||||
* best-scored mapping from a collection of proposed programs.
|
||||
*
|
||||
* @param module the module whose sections to map
|
||||
* @param snap the source snapshot key
|
||||
* @param program the destination program whose blocks to consider
|
||||
* @return the proposed map
|
||||
*/
|
||||
SectionMapProposal proposeSectionMap(TraceModule module, Program program);
|
||||
SectionMapProposal proposeSectionMap(TraceModule module, long snap, Program program);
|
||||
|
||||
/**
|
||||
* Proposed the best-scored section map for the given module and programs
|
||||
@@ -526,10 +538,11 @@ public interface DebuggerStaticMappingService {
|
||||
* @see SectionMapProposal#computeScore()
|
||||
*
|
||||
* @param module the module whose sections to map
|
||||
* @param snap the source snapshot key
|
||||
* @param programs a set of proposed destination programs
|
||||
* @return the best-scored map, or {@code null} if no program is proposed
|
||||
*/
|
||||
SectionMapProposal proposeSectionMap(TraceModule module,
|
||||
SectionMapProposal proposeSectionMap(TraceModule module, long snap,
|
||||
Collection<? extends Program> programs);
|
||||
|
||||
/**
|
||||
@@ -543,11 +556,13 @@ public interface DebuggerStaticMappingService {
|
||||
* {@code null} values.
|
||||
*
|
||||
* @param modules the modules to map
|
||||
* @param snap the source snapshot key
|
||||
* @param programs a set of proposed destination programs
|
||||
* @return the composite proposal
|
||||
*/
|
||||
Map<TraceModule, SectionMapProposal> proposeSectionMaps(
|
||||
Collection<? extends TraceModule> modules, Collection<? extends Program> programs);
|
||||
Collection<? extends TraceModule> modules, long snap,
|
||||
Collection<? extends Program> programs);
|
||||
|
||||
/**
|
||||
* Propose a singleton region map from the given region to the given program memory block
|
||||
@@ -556,15 +571,16 @@ public interface DebuggerStaticMappingService {
|
||||
* Note, no sanity check is performed on the given parameters. This will simply give a singleton
|
||||
* map of the given entry. It is strongly advised to use
|
||||
* {@link RegionMapProposal#computeScore()} to assess the proposal. Alternatively, use
|
||||
* {@link #proposeRegionMap(Collection, Collection)} to have the service select the best-scored
|
||||
* mapping from a collection of proposed programs.
|
||||
* {@link #proposeRegionMaps(Collection, long, Collection)} to have the service select the
|
||||
* best-scored mapping from a collection of proposed programs.
|
||||
*
|
||||
* @param region the region to map
|
||||
* @param snap the source snapshot key
|
||||
* @param program the destination program
|
||||
* @param block the memory block in the destination program
|
||||
* @return the proposed map
|
||||
*/
|
||||
RegionMapProposal proposeRegionMap(TraceMemoryRegion region, Program program,
|
||||
RegionMapProposal proposeRegionMap(TraceMemoryRegion region, long snap, Program program,
|
||||
MemoryBlock block);
|
||||
|
||||
/**
|
||||
@@ -575,14 +591,16 @@ public interface DebuggerStaticMappingService {
|
||||
* regions to memory blocks in the given program. For the best results, regions should all
|
||||
* comprise the same module, and the minimum address among the regions should be the module's
|
||||
* base address. It is strongly advised to use {@link RegionMapProposal#computeScore()} to
|
||||
* assess the proposal. Alternatively, use {@link #proposeRegionMap(Collection, Collection)} to
|
||||
* have the service select the best-scored mapping from a collection of proposed programs.
|
||||
* assess the proposal. Alternatively, use
|
||||
* {@link #proposeRegionMaps(Collection, long, Collection)} to have the service select the
|
||||
* best-scored mapping from a collection of proposed programs.
|
||||
*
|
||||
* @param region the region to map
|
||||
* @param regions the regions to map
|
||||
* @param snap the source snapshot key
|
||||
* @param program the destination program whose blocks to consider
|
||||
* @return the proposed map
|
||||
*/
|
||||
RegionMapProposal proposeRegionMap(Collection<? extends TraceMemoryRegion> regions,
|
||||
RegionMapProposal proposeRegionMap(Collection<? extends TraceMemoryRegion> regions, long snap,
|
||||
Program program);
|
||||
|
||||
/**
|
||||
@@ -597,11 +615,12 @@ public interface DebuggerStaticMappingService {
|
||||
* regions into likely modules. For the best results, the minimum address of each module should
|
||||
* be among the regions.
|
||||
*
|
||||
* @param modules the modules to map
|
||||
* @param regions the regions to map
|
||||
* @param snap the source snapshot key
|
||||
* @param programs a set of proposed destination programs
|
||||
* @return the composite proposal
|
||||
*/
|
||||
Map<Collection<TraceMemoryRegion>, RegionMapProposal> proposeRegionMaps(
|
||||
Collection<? extends TraceMemoryRegion> regions,
|
||||
Collection<? extends TraceMemoryRegion> regions, long snap,
|
||||
Collection<? extends Program> programs);
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ public interface AutoMapSpec extends ExtensionPoint {
|
||||
|
||||
boolean objectHasType(TraceObjectValue value);
|
||||
|
||||
String getInfoForObjects(Trace trace);
|
||||
String getInfoForObjects(Trace trace, long snap);
|
||||
|
||||
default boolean hasTask() {
|
||||
return true;
|
||||
@@ -103,7 +103,7 @@ public interface AutoMapSpec extends ExtensionPoint {
|
||||
return getMenuName();
|
||||
}
|
||||
|
||||
default void runTask(PluginTool tool, Trace trace) {
|
||||
default void runTask(PluginTool tool, Trace trace, long snap) {
|
||||
DebuggerStaticMappingService mappingService =
|
||||
tool.getService(DebuggerStaticMappingService.class);
|
||||
ProgramManager programManager = tool.getService(ProgramManager.class);
|
||||
@@ -114,7 +114,7 @@ public interface AutoMapSpec extends ExtensionPoint {
|
||||
@Override
|
||||
public boolean applyTo(Trace trace, TaskMonitor monitor) {
|
||||
try {
|
||||
performMapping(mappingService, trace, programManager, monitor);
|
||||
performMapping(mappingService, trace, snap, programManager, monitor);
|
||||
return true;
|
||||
}
|
||||
catch (CancelledException e) {
|
||||
@@ -132,12 +132,13 @@ public interface AutoMapSpec extends ExtensionPoint {
|
||||
*
|
||||
* @param mappingService the mapping service
|
||||
* @param trace the trace
|
||||
* @param snap the snap
|
||||
* @param programs the programs to consider
|
||||
* @param monitor a task monitor
|
||||
* @return true if any mappings were added
|
||||
* @throws CancelledException if the task monitor cancelled the task
|
||||
*/
|
||||
boolean performMapping(DebuggerStaticMappingService mappingService, Trace trace,
|
||||
boolean performMapping(DebuggerStaticMappingService mappingService, Trace trace, long snap,
|
||||
List<Program> programs, TaskMonitor monitor) throws CancelledException;
|
||||
|
||||
/**
|
||||
@@ -145,13 +146,15 @@ public interface AutoMapSpec extends ExtensionPoint {
|
||||
*
|
||||
* @param mappingService the mapping service
|
||||
* @param trace the trace
|
||||
* @param snap the snap
|
||||
* @param programManager the program manager
|
||||
* @param monitor a task monitor
|
||||
* @return true if any mappings were added
|
||||
* @throws CancelledException if the task monitor cancelled the task
|
||||
*/
|
||||
default boolean performMapping(DebuggerStaticMappingService mappingService, Trace trace,
|
||||
ProgramManager programManager, TaskMonitor monitor) throws CancelledException {
|
||||
return performMapping(mappingService, trace, programs(programManager), monitor);
|
||||
long snap, ProgramManager programManager, TaskMonitor monitor)
|
||||
throws CancelledException {
|
||||
return performMapping(mappingService, trace, snap, programs(programManager), monitor);
|
||||
}
|
||||
}
|
||||
|
||||
+9
-3
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -25,14 +25,20 @@ import ghidra.trace.model.target.TraceObjectValue;
|
||||
|
||||
public class DebuggerObjectActionContext extends DefaultActionContext {
|
||||
private final List<TraceObjectValue> objectValues;
|
||||
private final long snap;
|
||||
|
||||
public DebuggerObjectActionContext(Collection<TraceObjectValue> objectValues,
|
||||
ComponentProvider provider, Component sourceComponent) {
|
||||
ComponentProvider provider, Component sourceComponent, long snap) {
|
||||
super(provider, sourceComponent);
|
||||
this.objectValues = List.copyOf(objectValues);
|
||||
this.snap = snap;
|
||||
}
|
||||
|
||||
public List<TraceObjectValue> getObjectValues() {
|
||||
return objectValues;
|
||||
}
|
||||
|
||||
public long getSnap() {
|
||||
return snap;
|
||||
}
|
||||
}
|
||||
|
||||
+9
-2
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -33,6 +33,13 @@ public interface ModuleMapProposal extends MapProposal<TraceModule, Program, Mod
|
||||
*/
|
||||
TraceModule getModule();
|
||||
|
||||
/**
|
||||
* Get the module name for this entry (may depend on the snap)
|
||||
*
|
||||
* @return the name
|
||||
*/
|
||||
String getModuleName();
|
||||
|
||||
/**
|
||||
* Get the address range of the module in the trace, as computed from the matched program's
|
||||
* image size
|
||||
|
||||
+17
-2
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -16,6 +16,7 @@
|
||||
package ghidra.debug.api.modules;
|
||||
|
||||
import ghidra.debug.api.modules.RegionMapProposal.RegionMapEntry;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.model.mem.MemoryBlock;
|
||||
import ghidra.trace.model.memory.TraceMemoryRegion;
|
||||
@@ -34,6 +35,20 @@ public interface RegionMapProposal
|
||||
*/
|
||||
TraceMemoryRegion getRegion();
|
||||
|
||||
/**
|
||||
* Get the region's name (may depend on snap)
|
||||
*
|
||||
* @return the name
|
||||
*/
|
||||
String getRegionName();
|
||||
|
||||
/**
|
||||
* Get the region's minimum address (may depend on snap)
|
||||
*
|
||||
* @return the address
|
||||
*/
|
||||
Address getRegionMinAddress();
|
||||
|
||||
/**
|
||||
* Get the matched memory block
|
||||
*
|
||||
|
||||
+25
-2
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -16,6 +16,7 @@
|
||||
package ghidra.debug.api.modules;
|
||||
|
||||
import ghidra.debug.api.modules.SectionMapProposal.SectionMapEntry;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.model.mem.MemoryBlock;
|
||||
import ghidra.trace.model.modules.TraceModule;
|
||||
@@ -36,6 +37,20 @@ public interface SectionMapProposal
|
||||
*/
|
||||
TraceSection getSection();
|
||||
|
||||
/**
|
||||
* Get the section name (may depend on the snap)
|
||||
*
|
||||
* @return the name
|
||||
*/
|
||||
String getSectionName();
|
||||
|
||||
/**
|
||||
* Get the start address of the section (may depend on the snap)
|
||||
*
|
||||
* @return the start address
|
||||
*/
|
||||
Address getSectionStart();
|
||||
|
||||
/**
|
||||
* Get the module containing the section
|
||||
*
|
||||
@@ -43,6 +58,13 @@ public interface SectionMapProposal
|
||||
*/
|
||||
TraceModule getModule();
|
||||
|
||||
/**
|
||||
* Get the name of the module containing the section (may depend on snap)
|
||||
*
|
||||
* @return the name
|
||||
*/
|
||||
String getModuleName();
|
||||
|
||||
/**
|
||||
* Get the matched memory block
|
||||
*
|
||||
@@ -71,5 +93,6 @@ public interface SectionMapProposal
|
||||
*
|
||||
* @return the program
|
||||
*/
|
||||
@Override
|
||||
Program getProgram();
|
||||
}
|
||||
|
||||
+5
-5
@@ -320,8 +320,9 @@ public class DebuggerCoordinates {
|
||||
return objThread.getCanonicalPath();
|
||||
}
|
||||
TraceStack stack;
|
||||
long snap = time.getSnap();
|
||||
try {
|
||||
stack = thread.getTrace().getStackManager().getStack(thread, time.getSnap(), false);
|
||||
stack = thread.getTrace().getStackManager().getStack(thread, snap, false);
|
||||
}
|
||||
catch (IllegalStateException e) {
|
||||
// Schema does not specify a stack
|
||||
@@ -330,7 +331,7 @@ public class DebuggerCoordinates {
|
||||
if (stack == null) {
|
||||
return objThread.getCanonicalPath();
|
||||
}
|
||||
TraceStackFrame frame = stack.getFrame(frameLevel, false);
|
||||
TraceStackFrame frame = stack.getFrame(snap, frameLevel, false);
|
||||
if (frame == null) {
|
||||
return objThread.getCanonicalPath();
|
||||
}
|
||||
@@ -406,9 +407,8 @@ public class DebuggerCoordinates {
|
||||
return NOWHERE;
|
||||
}
|
||||
long snap = newTime.getSnap();
|
||||
Lifespan threadLifespan = thread == null ? null : thread.getLifespan();
|
||||
TraceThread newThread = threadLifespan != null && threadLifespan.contains(snap) ? thread
|
||||
: resolveThread(trace, target, newTime);
|
||||
boolean isThreadValid = thread == null ? false : thread.isValid(snap);
|
||||
TraceThread newThread = isThreadValid ? thread : resolveThread(trace, target, newTime);
|
||||
// This will cause the frame to reset to 0 on every snap change. That's fair....
|
||||
Integer newFrame = resolveFrame(newThread, newTime);
|
||||
KeyPath threadOrFramePath = resolvePath(newThread, newFrame, newTime);
|
||||
|
||||
@@ -1444,8 +1444,10 @@ public interface FlatDebuggerAPI {
|
||||
}
|
||||
|
||||
default ActionContext createContext(TraceObject object) {
|
||||
Trace trace = object.getTrace();
|
||||
DebuggerCoordinates coords = getTraceManager().getCurrentFor(trace);
|
||||
TraceObjectValue value = object.getCanonicalParents(Lifespan.ALL).findAny().orElseThrow();
|
||||
return new DebuggerObjectActionContext(List.of(value), null, null);
|
||||
return new DebuggerObjectActionContext(List.of(value), null, null, coords.getSnap());
|
||||
}
|
||||
|
||||
default ActionContext createContext(TraceThread thread) {
|
||||
@@ -1720,8 +1722,7 @@ public interface FlatDebuggerAPI {
|
||||
* This does not consider the current snap. It only considers a live target thread in the
|
||||
* present. In other words, if the user rewinds trace history to a point where the thread was
|
||||
* alive, this method still considers that thread terminated. To compute state with respect to
|
||||
* trace history, use {@link TraceThread#getLifespan()} and check if it contains the current
|
||||
* snap.
|
||||
* trace history, use {@link TraceThread#isValid(long)}.
|
||||
*
|
||||
* @param thread
|
||||
* @return the thread's execution state
|
||||
|
||||
+3
-2
@@ -190,7 +190,8 @@ public abstract class AbstractTraceRmiLaunchOffer implements TraceRmiLaunchOffer
|
||||
return false;
|
||||
}
|
||||
|
||||
if (spec.performMapping(mappingService, trace, List.of(program), monitor)) {
|
||||
long snap = connection.getLastSnapshot(trace);
|
||||
if (spec.performMapping(mappingService, trace, snap, List.of(program), monitor)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -206,7 +207,7 @@ public abstract class AbstractTraceRmiLaunchOffer implements TraceRmiLaunchOffer
|
||||
return true; // Probably shouldn't happen, but if it does, say "success"
|
||||
}
|
||||
ProgramLocation probe = new ProgramLocation(program, probeAddress);
|
||||
long snap = connection.getLastSnapshot(trace);
|
||||
|
||||
return mappingService.getOpenMappedLocation(trace, probe, snap) != null;
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -938,7 +938,8 @@ public class TraceRmiHandler extends AbstractTraceRmiConnection {
|
||||
|
||||
// Want addresses satisfying {@code known | (readOnly & everKnown)}
|
||||
TraceMemoryManager memoryManager = open.trace.getMemoryManager();
|
||||
AddressSetView readOnly = memoryManager.getRegionsAddressSetWith(snap, r -> !r.isWrite());
|
||||
AddressSetView readOnly =
|
||||
memoryManager.getRegionsAddressSetWith(snap, r -> !r.isWrite(snap));
|
||||
AddressSetView everKnown = memoryManager.getAddressesWithState(Lifespan.since(snap),
|
||||
s -> s == TraceMemoryState.KNOWN);
|
||||
AddressSetView roEverKnown = new IntersectionAddressSetView(readOnly, everKnown);
|
||||
|
||||
+4
-3
@@ -1334,7 +1334,7 @@ public class TraceRmiTarget extends AbstractTarget {
|
||||
RemoteParameter paramFrame = writeReg.params.get("frame");
|
||||
if (paramFrame != null) {
|
||||
TraceStack stack = trace.getStackManager().getLatestStack(thread, getSnap());
|
||||
TraceStackFrame frame = stack.getFrame(frameLevel, false);
|
||||
TraceStackFrame frame = stack.getFrame(getSnap(), frameLevel, false);
|
||||
if (!(frame instanceof TraceObjectStackFrame tof)) {
|
||||
Msg.error(this, "Non-object trace with TraceRmi!");
|
||||
return AsyncUtils.nil();
|
||||
@@ -1568,10 +1568,11 @@ public class TraceRmiTarget extends AbstractTarget {
|
||||
|
||||
@Override
|
||||
public boolean isBreakpointValid(TraceBreakpoint breakpoint) {
|
||||
if (breakpoint.getName().endsWith("emu-" + breakpoint.getMinAddress())) {
|
||||
long snap = getSnap();
|
||||
if (breakpoint.getName(snap).endsWith("emu-" + breakpoint.getMinAddress(snap))) {
|
||||
return false;
|
||||
}
|
||||
if (!breakpoint.isAlive(getSnap())) {
|
||||
if (!breakpoint.isValid(snap)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -288,9 +288,8 @@ public class PopulateDemoTrace extends GhidraScript {
|
||||
int pc2 = 0;
|
||||
|
||||
/**
|
||||
* For clarity, I will add each tick to the trace in its own transaction. The
|
||||
* Transaction class eases the syntax and reduces errors in starting and ending
|
||||
* transactions.
|
||||
* For clarity, I will add each tick to the trace in its own transaction. The Transaction
|
||||
* class eases the syntax and reduces errors in starting and ending transactions.
|
||||
*/
|
||||
try (Transaction tx = trace.openTransaction("Populate First Snapshot")) {
|
||||
/**
|
||||
@@ -699,7 +698,7 @@ public class PopulateDemoTrace extends GhidraScript {
|
||||
long snap =
|
||||
trace.getTimeManager().createSnapshot("Stepped Thread 2: CALL exit").getKey();
|
||||
|
||||
thread2.setDestructionSnap(snap);
|
||||
thread2.remove(snap);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -709,7 +708,7 @@ public class PopulateDemoTrace extends GhidraScript {
|
||||
long snap =
|
||||
trace.getTimeManager().createSnapshot("Stepped Thread 1: CALL exit").getKey();
|
||||
|
||||
thread1.setDestructionSnap(snap);
|
||||
thread1.remove(snap);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+7
-7
@@ -117,13 +117,13 @@ public class DebuggerDisassemblerPlugin extends Plugin implements PopupActionPro
|
||||
// It has never been known up to this snap
|
||||
return null;
|
||||
}
|
||||
TraceMemoryRegion region =
|
||||
memoryManager.getRegionContaining(mrent.getKey().getY1(), start);
|
||||
if (region == null || region.isWrite()) {
|
||||
long ks = mrent.getKey().getY1();
|
||||
TraceMemoryRegion region = memoryManager.getRegionContaining(ks, start);
|
||||
if (region == null || region.isWrite(ks)) {
|
||||
// It could have changed this snap, so unknown
|
||||
return null;
|
||||
}
|
||||
return mrent.getKey().getY1();
|
||||
return ks;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -133,8 +133,8 @@ public class DebuggerDisassemblerPlugin extends Plugin implements PopupActionPro
|
||||
* The view contains the addresses in {@code known | (readOnly & everKnown)}, where {@code
|
||||
* known} is the set of addresses in the {@link TraceMemoryState#KNOWN} state, {@code readOnly}
|
||||
* is the set of addresses in a {@link TraceMemoryRegion} having
|
||||
* {@link TraceMemoryRegion#isWrite()} false, and {@code everKnown} is the set of addresses in
|
||||
* the {@link TraceMemoryState#KNOWN} state in any previous snapshot.
|
||||
* {@link TraceMemoryRegion#isWrite(long)} false, and {@code everKnown} is the set of addresses
|
||||
* in the {@link TraceMemoryState#KNOWN} state in any previous snapshot.
|
||||
*
|
||||
* <p>
|
||||
* In plainer English, we want addresses that have freshly read bytes right now, or addresses in
|
||||
@@ -158,7 +158,7 @@ public class DebuggerDisassemblerPlugin extends Plugin implements PopupActionPro
|
||||
}
|
||||
TraceMemoryManager memoryManager = trace.getMemoryManager();
|
||||
AddressSetView readOnly =
|
||||
memoryManager.getRegionsAddressSetWith(ks, r -> !r.isWrite());
|
||||
memoryManager.getRegionsAddressSetWith(ks, r -> !r.isWrite(ks));
|
||||
AddressSetView everKnown = memoryManager.getAddressesWithState(Lifespan.since(ks),
|
||||
s -> s == TraceMemoryState.KNOWN);
|
||||
AddressSetView roEverKnown = new IntersectionAddressSetView(readOnly, everKnown);
|
||||
|
||||
+11
-10
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -81,18 +81,19 @@ public class DebuggerBlockChooserDialog extends ReusableDialogComponentProvider
|
||||
return score;
|
||||
}
|
||||
|
||||
public double score(TraceSection section, DebuggerStaticMappingService service) {
|
||||
public double score(TraceSection section, long snap, DebuggerStaticMappingService service) {
|
||||
if (section == null) {
|
||||
return score = 0;
|
||||
}
|
||||
return score = service.proposeSectionMap(section, program, block).computeScore();
|
||||
return score = service.proposeSectionMap(section, snap, program, block).computeScore();
|
||||
}
|
||||
|
||||
public double score(TraceMemoryRegion region, DebuggerStaticMappingService service) {
|
||||
public double score(TraceMemoryRegion region, long snap,
|
||||
DebuggerStaticMappingService service) {
|
||||
if (region == null) {
|
||||
return score = 0;
|
||||
}
|
||||
return score = service.proposeRegionMap(region, program, block).computeScore();
|
||||
return score = service.proposeRegionMap(region, snap, program, block).computeScore();
|
||||
}
|
||||
|
||||
public ProgramLocation getProgramLocation() {
|
||||
@@ -201,15 +202,15 @@ public class DebuggerBlockChooserDialog extends ReusableDialogComponentProvider
|
||||
}
|
||||
|
||||
public Map.Entry<Program, MemoryBlock> chooseBlock(PluginTool tool, TraceSection section,
|
||||
Collection<Program> programs) {
|
||||
long snap, Collection<Program> programs) {
|
||||
DebuggerStaticMappingService service = tool.getService(DebuggerStaticMappingService.class);
|
||||
return chooseBlock(tool, programs, rec -> rec.score(section, service));
|
||||
return chooseBlock(tool, programs, rec -> rec.score(section, snap, service));
|
||||
}
|
||||
|
||||
public Map.Entry<Program, MemoryBlock> chooseBlock(PluginTool tool, TraceMemoryRegion region,
|
||||
Collection<Program> programs) {
|
||||
long snap, Collection<Program> programs) {
|
||||
DebuggerStaticMappingService service = tool.getService(DebuggerStaticMappingService.class);
|
||||
return chooseBlock(tool, programs, rec -> rec.score(region, service));
|
||||
return chooseBlock(tool, programs, rec -> rec.score(region, snap, service));
|
||||
}
|
||||
|
||||
protected Map.Entry<Program, MemoryBlock> chooseBlock(PluginTool tool,
|
||||
|
||||
+12
-9
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -142,13 +142,14 @@ public class DebuggerLocationLabel extends JLabel {
|
||||
if (sections.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
long snap = current.getSnap();
|
||||
/**
|
||||
* TODO: DB's R-Tree could probably do this natively. Not sure it's an optimization, though,
|
||||
* since few, if any, overlapping sections are expected.
|
||||
*/
|
||||
sections.sort(ComparatorUtils.chainedComparator(List.of(
|
||||
Comparator.comparing(s -> s.getRange().getMinAddress()),
|
||||
Comparator.comparing(s -> -s.getRange().getLength()))));
|
||||
Comparator.comparing(s -> s.getRange(snap).getMinAddress()),
|
||||
Comparator.comparing(s -> -s.getRange(snap).getLength()))));
|
||||
return sections.get(sections.size() - 1);
|
||||
}
|
||||
|
||||
@@ -162,10 +163,11 @@ public class DebuggerLocationLabel extends JLabel {
|
||||
if (modules.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
long snap = current.getSnap();
|
||||
// TODO: DB's R-Tree could probably do this natively
|
||||
modules.sort(ComparatorUtils.chainedComparator(List.of(
|
||||
Comparator.comparing(m -> m.getRange().getMinAddress()),
|
||||
Comparator.comparing(m -> -m.getRange().getLength()))));
|
||||
Comparator.comparing(m -> m.getRange(snap).getMinAddress()),
|
||||
Comparator.comparing(m -> -m.getRange(snap).getLength()))));
|
||||
return modules.get(modules.size() - 1);
|
||||
}
|
||||
|
||||
@@ -185,18 +187,19 @@ public class DebuggerLocationLabel extends JLabel {
|
||||
if (address == null) {
|
||||
return "(nowhere)";
|
||||
}
|
||||
long snap = current.getSnap();
|
||||
try {
|
||||
TraceSection section = getNearestSectionContaining();
|
||||
if (section != null) {
|
||||
return section.getModule().getName() + ":" + section.getName();
|
||||
return section.getModule().getName(snap) + ":" + section.getName(snap);
|
||||
}
|
||||
TraceModule module = getNearestModuleContaining();
|
||||
if (module != null) {
|
||||
return module.getName();
|
||||
return module.getName(snap);
|
||||
}
|
||||
TraceMemoryRegion region = getRegionContaining();
|
||||
if (region != null) {
|
||||
return region.getName();
|
||||
return region.getName(snap);
|
||||
}
|
||||
return "(unknown)";
|
||||
}
|
||||
|
||||
+6
-6
@@ -81,14 +81,14 @@ public class ByModuleAutoMapSpec implements AutoMapSpec {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfoForObjects(Trace trace) {
|
||||
public String getInfoForObjects(Trace trace, long snap) {
|
||||
String modPart = trace.getModuleManager()
|
||||
.getAllModules()
|
||||
.getLoadedModules(snap)
|
||||
.stream()
|
||||
.map(m -> m.getName() + ":" + m.getBase())
|
||||
.map(m -> m.getName(snap) + ":" + m.getBase(snap))
|
||||
.sorted()
|
||||
.collect(Collectors.joining(","));
|
||||
String regPart = ByRegionAutoMapSpec.getInfoForRegions(trace);
|
||||
String regPart = ByRegionAutoMapSpec.getInfoForRegions(trace, snap);
|
||||
return modPart + ";" + regPart;
|
||||
}
|
||||
|
||||
@@ -99,9 +99,9 @@ public class ByModuleAutoMapSpec implements AutoMapSpec {
|
||||
|
||||
@Override
|
||||
public boolean performMapping(DebuggerStaticMappingService mappingService, Trace trace,
|
||||
List<Program> programs, TaskMonitor monitor) throws CancelledException {
|
||||
long snap, List<Program> programs, TaskMonitor monitor) throws CancelledException {
|
||||
Map<?, ModuleMapProposal> maps = mappingService
|
||||
.proposeModuleMaps(trace.getModuleManager().getAllModules(), programs);
|
||||
.proposeModuleMaps(trace.getModuleManager().getLoadedModules(snap), snap, programs);
|
||||
Collection<ModuleMapEntry> entries = MapProposal.flatten(maps.values());
|
||||
entries = MapProposal.removeOverlapping(entries);
|
||||
mappingService.addModuleMappings(entries, monitor, false);
|
||||
|
||||
+7
-7
@@ -64,18 +64,18 @@ public class ByRegionAutoMapSpec implements AutoMapSpec {
|
||||
return value.getParent().queryInterface(TraceObjectMemoryRegion.class) != null;
|
||||
}
|
||||
|
||||
static String getInfoForRegions(Trace trace) {
|
||||
static String getInfoForRegions(Trace trace, long snap) {
|
||||
return trace.getMemoryManager()
|
||||
.getAllRegions()
|
||||
.getRegionsAtSnap(snap)
|
||||
.stream()
|
||||
.map(r -> r.getName() + ":" + r.getMinAddress())
|
||||
.map(r -> r.getName(snap) + ":" + r.getMinAddress(snap))
|
||||
.sorted()
|
||||
.collect(Collectors.joining(","));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfoForObjects(Trace trace) {
|
||||
return getInfoForRegions(trace);
|
||||
public String getInfoForObjects(Trace trace, long snap) {
|
||||
return getInfoForRegions(trace, snap);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -85,9 +85,9 @@ public class ByRegionAutoMapSpec implements AutoMapSpec {
|
||||
|
||||
@Override
|
||||
public boolean performMapping(DebuggerStaticMappingService mappingService, Trace trace,
|
||||
List<Program> programs, TaskMonitor monitor) throws CancelledException {
|
||||
long snap, List<Program> programs, TaskMonitor monitor) throws CancelledException {
|
||||
Map<?, RegionMapProposal> maps = mappingService
|
||||
.proposeRegionMaps(trace.getMemoryManager().getAllRegions(), programs);
|
||||
.proposeRegionMaps(trace.getMemoryManager().getRegionsAtSnap(snap), snap, programs);
|
||||
Collection<RegionMapEntry> entries = MapProposal.flatten(maps.values());
|
||||
entries = MapProposal.removeOverlapping(entries);
|
||||
mappingService.addRegionMappings(entries, monitor, false);
|
||||
|
||||
+6
-5
@@ -65,11 +65,12 @@ public class BySectionAutoMapSpec implements AutoMapSpec {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfoForObjects(Trace trace) {
|
||||
public String getInfoForObjects(Trace trace, long snap) {
|
||||
return trace.getModuleManager()
|
||||
.getAllSections()
|
||||
.stream()
|
||||
.map(s -> s.getName() + ":" + s.getStart())
|
||||
.filter(s -> s.isValid(snap))
|
||||
.map(s -> s.getName(snap) + ":" + s.getStart(snap))
|
||||
.sorted()
|
||||
.collect(Collectors.joining(","));
|
||||
}
|
||||
@@ -81,9 +82,9 @@ public class BySectionAutoMapSpec implements AutoMapSpec {
|
||||
|
||||
@Override
|
||||
public boolean performMapping(DebuggerStaticMappingService mappingService, Trace trace,
|
||||
List<Program> programs, TaskMonitor monitor) throws CancelledException {
|
||||
Map<?, SectionMapProposal> maps = mappingService
|
||||
.proposeSectionMaps(trace.getModuleManager().getAllModules(), programs);
|
||||
long snap, List<Program> programs, TaskMonitor monitor) throws CancelledException {
|
||||
Map<?, SectionMapProposal> maps = mappingService.proposeSectionMaps(
|
||||
trace.getModuleManager().getLoadedModules(snap), snap, programs);
|
||||
Collection<SectionMapEntry> entries = MapProposal.flatten(maps.values());
|
||||
entries = MapProposal.removeOverlapping(entries);
|
||||
mappingService.addSectionMappings(entries, monitor, false);
|
||||
|
||||
+3
-3
@@ -61,7 +61,7 @@ public class NoneAutoMapSpec implements AutoMapSpec {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfoForObjects(Trace trace) {
|
||||
public String getInfoForObjects(Trace trace, long snap) {
|
||||
return "";
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ public class NoneAutoMapSpec implements AutoMapSpec {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runTask(PluginTool tool, Trace trace) {
|
||||
public void runTask(PluginTool tool, Trace trace, long snap) {
|
||||
// Don't bother launching a task that does nothing
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ public class NoneAutoMapSpec implements AutoMapSpec {
|
||||
|
||||
@Override
|
||||
public boolean performMapping(DebuggerStaticMappingService mappingService, Trace trace,
|
||||
List<Program> programs, TaskMonitor monitor) throws CancelledException {
|
||||
long snap, List<Program> programs, TaskMonitor monitor) throws CancelledException {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
+3
-4
@@ -62,7 +62,7 @@ public class OneToOneAutoMapSpec implements AutoMapSpec {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfoForObjects(Trace trace) {
|
||||
public String getInfoForObjects(Trace trace, long snap) {
|
||||
return "";
|
||||
}
|
||||
|
||||
@@ -77,12 +77,11 @@ public class OneToOneAutoMapSpec implements AutoMapSpec {
|
||||
|
||||
@Override
|
||||
public boolean performMapping(DebuggerStaticMappingService mappingService, Trace trace,
|
||||
List<Program> programs, TaskMonitor monitor) throws CancelledException {
|
||||
long snap, List<Program> programs, TaskMonitor monitor) throws CancelledException {
|
||||
boolean result = false;
|
||||
for (Program program : programs) {
|
||||
try {
|
||||
mappingService.addIdentityMapping(trace, program,
|
||||
Lifespan.nowOn(trace.getProgramView().getSnap()), false);
|
||||
mappingService.addIdentityMapping(trace, program, Lifespan.nowOn(snap), false);
|
||||
result = true;
|
||||
}
|
||||
catch (TraceConflictedMappingException e) {
|
||||
|
||||
+3
-3
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -85,7 +85,7 @@ public enum PCByStackLocationTrackingSpec implements LocationTrackingSpec, Locat
|
||||
return null;
|
||||
}
|
||||
int level = coordinates.getFrame();
|
||||
TraceStackFrame frame = stack.getFrame(level, false);
|
||||
TraceStackFrame frame = stack.getFrame(snap, level, false);
|
||||
if (frame == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
+5
-5
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -22,7 +22,8 @@ import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.lang.Register;
|
||||
import ghidra.program.model.lang.RegisterValue;
|
||||
import ghidra.program.util.ProgramLocation;
|
||||
import ghidra.trace.model.*;
|
||||
import ghidra.trace.model.Trace;
|
||||
import ghidra.trace.model.TraceAddressSnapRange;
|
||||
import ghidra.trace.model.guest.TracePlatform;
|
||||
import ghidra.trace.model.memory.TraceMemorySpace;
|
||||
import ghidra.trace.model.memory.TraceMemoryState;
|
||||
@@ -64,8 +65,7 @@ public interface RegisterLocationTrackingSpec extends LocationTrackingSpec, Loca
|
||||
if (reg == null) {
|
||||
return null;
|
||||
}
|
||||
Lifespan lifespan = thread.getLifespan();
|
||||
if (lifespan == null || !lifespan.contains(snap)) {
|
||||
if (!thread.isValid(snap)) {
|
||||
return null;
|
||||
}
|
||||
TraceMemorySpace regs = reg.getAddressSpace().isRegisterSpace()
|
||||
|
||||
+9
-9
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -60,7 +60,8 @@ public class VisibleROOnceAutoReadMemorySpec implements AutoReadMemorySpec {
|
||||
}
|
||||
Target target = coordinates.getTarget();
|
||||
TraceMemoryManager mm = coordinates.getTrace().getMemoryManager();
|
||||
AddressSetView alreadyKnown = mm.getAddressesWithState(coordinates.getSnap(), visible,
|
||||
long snap = coordinates.getSnap();
|
||||
AddressSetView alreadyKnown = mm.getAddressesWithState(snap, visible,
|
||||
s -> s == TraceMemoryState.KNOWN || s == TraceMemoryState.ERROR);
|
||||
AddressSet toRead = visible.subtract(alreadyKnown);
|
||||
|
||||
@@ -70,19 +71,18 @@ public class VisibleROOnceAutoReadMemorySpec implements AutoReadMemorySpec {
|
||||
|
||||
AddressSet everKnown = new AddressSet();
|
||||
for (AddressRange range : visible) {
|
||||
for (Entry<TraceAddressSnapRange, TraceMemoryState> ent : mm
|
||||
.getMostRecentStates(coordinates.getSnap(), range)) {
|
||||
for (Entry<TraceAddressSnapRange, TraceMemoryState> ent : mm.getMostRecentStates(snap,
|
||||
range)) {
|
||||
everKnown.add(ent.getKey().getRange());
|
||||
}
|
||||
}
|
||||
AddressSet readOnly = new AddressSet();
|
||||
for (AddressRange range : visible) {
|
||||
for (TraceMemoryRegion region : mm
|
||||
.getRegionsIntersecting(Lifespan.at(coordinates.getSnap()), range)) {
|
||||
if (region.isWrite()) {
|
||||
for (TraceMemoryRegion region : mm.getRegionsIntersecting(Lifespan.at(snap), range)) {
|
||||
if (region.isWrite(snap)) {
|
||||
continue;
|
||||
}
|
||||
readOnly.add(region.getRange());
|
||||
readOnly.add(region.getRange(snap));
|
||||
}
|
||||
}
|
||||
toRead.delete(everKnown.intersect(readOnly));
|
||||
|
||||
+16
-13
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -25,7 +25,6 @@ import ghidra.pcode.exec.SleighUtils;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.util.ProgramLocation;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpoint;
|
||||
import ghidra.trace.model.thread.TraceThread;
|
||||
|
||||
public class BreakpointLocationRow {
|
||||
private final DebuggerBreakpointsProvider provider;
|
||||
@@ -36,13 +35,16 @@ public class BreakpointLocationRow {
|
||||
this.loc = loc;
|
||||
}
|
||||
|
||||
private long getSnap() {
|
||||
return provider.traceManager.getCurrentFor(loc.getTrace()).getSnap();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return loc.getName();
|
||||
return loc.getName(getSnap());
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
long snap = provider.traceManager.getCurrentFor(loc.getTrace()).getSnap();
|
||||
return loc.isEnabled(snap);
|
||||
return loc.isEnabled(getSnap());
|
||||
}
|
||||
|
||||
public State getState() {
|
||||
@@ -75,12 +77,12 @@ public class BreakpointLocationRow {
|
||||
|
||||
public void setName(String name) {
|
||||
try (Transaction tid = loc.getTrace().openTransaction("Set breakpoint name")) {
|
||||
loc.setName(name);
|
||||
loc.setName(getSnap(), name);
|
||||
}
|
||||
}
|
||||
|
||||
public Address getAddress() {
|
||||
return loc.getMinAddress();
|
||||
return loc.getMinAddress(getSnap());
|
||||
}
|
||||
|
||||
public ProgramLocation getProgramLocation() {
|
||||
@@ -92,25 +94,26 @@ public class BreakpointLocationRow {
|
||||
}
|
||||
|
||||
public String getThreads() {
|
||||
return loc.getThreads()
|
||||
long snap = getSnap();
|
||||
return loc.getThreads(snap)
|
||||
.stream()
|
||||
.map(TraceThread::getName)
|
||||
.map(t -> t.getName(snap))
|
||||
.collect(Collectors.toSet())
|
||||
.toString();
|
||||
}
|
||||
|
||||
public String getComment() {
|
||||
return loc.getComment();
|
||||
return loc.getComment(getSnap());
|
||||
}
|
||||
|
||||
public void setComment(String comment) {
|
||||
try (Transaction tid = loc.getTrace().openTransaction("Set breakpoint comment")) {
|
||||
loc.setComment(comment);
|
||||
loc.setComment(getSnap(), comment);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasSleigh() {
|
||||
return !SleighUtils.UNCONDITIONAL_BREAK.equals(loc.getEmuSleigh());
|
||||
return !SleighUtils.UNCONDITIONAL_BREAK.equals(loc.getEmuSleigh(getSnap()));
|
||||
}
|
||||
|
||||
public TraceBreakpoint getTraceBreakpoint() {
|
||||
|
||||
+7
-4
@@ -699,7 +699,7 @@ public class DebuggerBreakpointsProvider extends ComponentProviderAdapter
|
||||
|
||||
private boolean isVisible(TraceBreakpoint location) {
|
||||
long snap = traceManager.getCurrentFor(trace).getSnap();
|
||||
return location.isAlive(snap);
|
||||
return location.isValid(snap);
|
||||
}
|
||||
|
||||
private void locationAdded(TraceBreakpoint location) {
|
||||
@@ -1336,7 +1336,8 @@ public class DebuggerBreakpointsProvider extends ComponentProviderAdapter
|
||||
}
|
||||
else if (ctx instanceof DebuggerBreakpointLocationsActionContext locCtx) {
|
||||
for (TraceBreakpoint tb : locCtx.getLocations()) {
|
||||
if (!EXECUTE_KINDS.containsAll(tb.getKinds())) {
|
||||
long snap = traceManager.getCurrentFor(tb.getTrace()).getSnap();
|
||||
if (!EXECUTE_KINDS.containsAll(tb.getKinds(snap))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1368,7 +1369,8 @@ public class DebuggerBreakpointsProvider extends ComponentProviderAdapter
|
||||
}
|
||||
else if (ctx instanceof DebuggerBreakpointLocationsActionContext locCtx) {
|
||||
for (TraceBreakpoint tb : locCtx.getLocations()) {
|
||||
String s = tb.getEmuSleigh();
|
||||
long snap = traceManager.getCurrentFor(tb.getTrace()).getSnap();
|
||||
String s = tb.getEmuSleigh(snap);
|
||||
if (sleigh != null && !sleigh.equals(s)) {
|
||||
return null;
|
||||
}
|
||||
@@ -1393,7 +1395,8 @@ public class DebuggerBreakpointsProvider extends ComponentProviderAdapter
|
||||
}
|
||||
else if (ctx instanceof DebuggerBreakpointLocationsActionContext locCtx) {
|
||||
for (TraceBreakpoint tb : locCtx.getLocations()) {
|
||||
tb.setEmuSleigh(sleigh);
|
||||
long snap = traceManager.getCurrentFor(tb.getTrace()).getSnap();
|
||||
tb.setEmuSleigh(snap, sleigh);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
+14
-10
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -620,23 +620,26 @@ public class DebuggerCopyIntoProgramDialog extends ReusableDialogComponentProvid
|
||||
|
||||
protected String computeRegionString(AddressRange rng) {
|
||||
TraceMemoryManager mm = source.getTrace().getMemoryManager();
|
||||
long snap = source.getSnap();
|
||||
Collection<? extends TraceMemoryRegion> regions =
|
||||
mm.getRegionsIntersecting(Lifespan.at(source.getSnap()), rng);
|
||||
return regions.isEmpty() ? "UNKNOWN" : regions.iterator().next().getName();
|
||||
mm.getRegionsIntersecting(Lifespan.at(snap), rng);
|
||||
return regions.isEmpty() ? "UNKNOWN" : regions.iterator().next().getName(snap);
|
||||
}
|
||||
|
||||
protected String computeModulesString(AddressRange rng) {
|
||||
TraceModuleManager mm = source.getTrace().getModuleManager();
|
||||
long snap = source.getSnap();
|
||||
Collection<? extends TraceModule> modules =
|
||||
mm.getModulesIntersecting(Lifespan.at(source.getSnap()), rng);
|
||||
return modules.stream().map(m -> m.getName()).collect(Collectors.joining(","));
|
||||
mm.getModulesIntersecting(Lifespan.at(snap), rng);
|
||||
return modules.stream().map(m -> m.getName(snap)).collect(Collectors.joining(","));
|
||||
}
|
||||
|
||||
protected String computeSectionsString(AddressRange rng) {
|
||||
TraceModuleManager mm = source.getTrace().getModuleManager();
|
||||
long snap = source.getSnap();
|
||||
Collection<? extends TraceSection> sections =
|
||||
mm.getSectionsIntersecting(Lifespan.at(source.getSnap()), rng);
|
||||
return sections.stream().map(s -> s.getName()).collect(Collectors.joining(","));
|
||||
mm.getSectionsIntersecting(Lifespan.at(snap), rng);
|
||||
return sections.stream().map(s -> s.getName(snap)).collect(Collectors.joining(","));
|
||||
}
|
||||
|
||||
protected void createEntry(Collection<RangeEntry> result, AddressRange srcRange,
|
||||
@@ -692,10 +695,11 @@ public class DebuggerCopyIntoProgramDialog extends ReusableDialogComponentProvid
|
||||
protected List<AddressRange> breakRangeByRegions(AddressRange srcRange) {
|
||||
AddressSet remains = new AddressSet(srcRange);
|
||||
List<AddressRange> result = new ArrayList<>();
|
||||
long snap = source.getSnap();
|
||||
for (TraceMemoryRegion region : source.getTrace()
|
||||
.getMemoryManager()
|
||||
.getRegionsIntersecting(Lifespan.at(source.getSnap()), srcRange)) {
|
||||
AddressRange range = region.getRange().intersect(srcRange);
|
||||
.getRegionsIntersecting(Lifespan.at(snap), srcRange)) {
|
||||
AddressRange range = region.getRange(snap).intersect(srcRange);
|
||||
result.add(range);
|
||||
remains.delete(range);
|
||||
}
|
||||
|
||||
+6
-5
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -219,21 +219,22 @@ public class DebuggerCopyPlan {
|
||||
@Override
|
||||
public void copy(TraceProgramView from, AddressRange fromRange, Program into,
|
||||
Address intoAddress, TaskMonitor monitor) throws Exception {
|
||||
long snap = from.getSnap();
|
||||
for (TraceBreakpoint bpt : from.getTrace()
|
||||
.getBreakpointManager()
|
||||
.getBreakpointsIntersecting(Lifespan.at(from.getSnap()), fromRange)) {
|
||||
monitor.checkCancelled();
|
||||
long off = bpt.getMinAddress().subtract(fromRange.getMinAddress());
|
||||
long off = bpt.getMinAddress(snap).subtract(fromRange.getMinAddress());
|
||||
Address dest = intoAddress.add(off);
|
||||
ProgramBreakpoint pb =
|
||||
new ProgramBreakpoint(into, dest, bpt.getLength(), bpt.getKinds());
|
||||
new ProgramBreakpoint(into, dest, bpt.getLength(snap), bpt.getKinds(snap));
|
||||
if (bpt.isEnabled(from.getSnap())) {
|
||||
pb.enable();
|
||||
}
|
||||
else {
|
||||
pb.disable();
|
||||
}
|
||||
pb.setEmuSleigh(bpt.getEmuSleigh());
|
||||
pb.setEmuSleigh(bpt.getEmuSleigh(snap));
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
+7
-6
@@ -1081,13 +1081,13 @@ public class DebuggerListingProvider extends CodeViewerProvider {
|
||||
Set<DomainFile> toOpen = new HashSet<>();
|
||||
TraceModuleManager modMan = trace.getModuleManager();
|
||||
Collection<TraceModule> modules = Stream.concat(
|
||||
modMan.getModulesAt(snap, address).stream().filter(m -> m.getSections().isEmpty()),
|
||||
modMan.getModulesAt(snap, address).stream().filter(m -> m.getSections(snap).isEmpty()),
|
||||
modMan.getSectionsAt(snap, address).stream().map(s -> s.getModule()))
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
// Attempt to open probable matches. All others, list to import
|
||||
for (TraceModule mod : modules) {
|
||||
DomainFile match = mappingService.findBestModuleProgram(space, mod);
|
||||
DomainFile match = mappingService.findBestModuleProgram(space, mod, snap);
|
||||
if (match == null) {
|
||||
missing.add(mod);
|
||||
}
|
||||
@@ -1108,7 +1108,7 @@ public class DebuggerListingProvider extends CodeViewerProvider {
|
||||
|
||||
for (TraceModule mod : missing) {
|
||||
consoleService.log(DebuggerResources.ICON_LOG_ERROR,
|
||||
"<html>The module <b><tt>" + HTMLUtilities.escapeHTML(mod.getName()) +
|
||||
"<html>The module <b><tt>" + HTMLUtilities.escapeHTML(mod.getName(snap)) +
|
||||
"</tt></b> was not found in the project</html>",
|
||||
new DebuggerMissingModuleActionContext(mod));
|
||||
}
|
||||
@@ -1139,12 +1139,13 @@ public class DebuggerListingProvider extends CodeViewerProvider {
|
||||
if (!affectedTraces.contains(module.getTrace())) {
|
||||
continue;
|
||||
}
|
||||
if (isMapped(module.getRange())) {
|
||||
long snap = traceManager.getCurrentFor(module.getTrace()).getSnap();
|
||||
if (isMapped(module.getRange(snap))) {
|
||||
consoleService.removeFromLog(mmCtx);
|
||||
continue;
|
||||
}
|
||||
for (TraceSection section : module.getSections()) {
|
||||
if (isMapped(section.getRange())) {
|
||||
for (TraceSection section : module.getSections(snap)) {
|
||||
if (isMapped(section.getRange(snap))) {
|
||||
consoleService.removeFromLog(mmCtx);
|
||||
continue nextCtx;
|
||||
}
|
||||
|
||||
+5
-4
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -71,13 +71,14 @@ public class MemoryStateListingBackgroundColorModel implements ListingBackground
|
||||
}
|
||||
|
||||
protected Color getUnknownColor(Address address) {
|
||||
long snap = view.getSnap();
|
||||
Entry<TraceAddressSnapRange, TraceMemoryState> ent =
|
||||
memory.getViewMostRecentStateEntry(view.getSnap(), address);
|
||||
memory.getViewMostRecentStateEntry(snap, address);
|
||||
if (ent == null || ent.getValue() != TraceMemoryState.KNOWN) {
|
||||
return COLOR_BACKGROUND_UNKNOWN;
|
||||
}
|
||||
TraceMemoryRegion region = memory.getRegionContaining(ent.getKey().getY1(), address);
|
||||
if (region != null && !region.isWrite()) {
|
||||
if (region != null && !region.isWrite(snap)) {
|
||||
return COLOR_BACKGROUND_UNKNOWN_BLENDED;
|
||||
}
|
||||
return COLOR_BACKGROUND_UNKNOWN;
|
||||
|
||||
+3
-3
@@ -40,7 +40,8 @@ import ghidra.framework.plugintool.annotation.AutoServiceConsumed;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressSet;
|
||||
import ghidra.program.util.ProgramSelection;
|
||||
import ghidra.trace.model.*;
|
||||
import ghidra.trace.model.Trace;
|
||||
import ghidra.trace.model.TraceDomainObjectListener;
|
||||
import ghidra.trace.model.memory.TraceMemoryManager;
|
||||
import ghidra.trace.model.memory.TraceMemoryRegion;
|
||||
import ghidra.trace.util.TraceEvents;
|
||||
@@ -53,7 +54,6 @@ public class DebuggerLegacyRegionsPanel extends JPanel {
|
||||
protected enum RegionTableColumns
|
||||
implements EnumeratedTableColumn<RegionTableColumns, RegionRow> {
|
||||
NAME("Name", String.class, RegionRow::getName, RegionRow::setName),
|
||||
LIFESPAN("Lifespan", Lifespan.class, RegionRow::getLifespan),
|
||||
START("Start", Address.class, RegionRow::getMinAddress),
|
||||
END("End", Address.class, RegionRow::getMaxAddress),
|
||||
LENGTH("Length", Long.class, RegionRow::getLength),
|
||||
@@ -159,7 +159,7 @@ public class DebuggerLegacyRegionsPanel extends JPanel {
|
||||
}
|
||||
AddressSet sel = new AddressSet();
|
||||
for (TraceMemoryRegion s : regions) {
|
||||
sel.add(s.getRange());
|
||||
sel.add(s.getRange(0));
|
||||
}
|
||||
ProgramSelection ps = new ProgramSelection(sel);
|
||||
listingService.setCurrentSelection(ps);
|
||||
|
||||
+4
-4
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -42,8 +42,8 @@ public class DebuggerRegionMapProposalDialog
|
||||
protected enum RegionMapTableColumns
|
||||
implements EnumeratedTableColumn<RegionMapTableColumns, RegionMapEntry> {
|
||||
REMOVE("Remove", String.class, e -> "Remove Proposed Entry", (e, v) -> nop()),
|
||||
REGION_NAME("Region", String.class, e -> e.getRegion().getName()),
|
||||
DYNAMIC_BASE("Dynamic Base", Address.class, e -> e.getRegion().getMinAddress()),
|
||||
REGION_NAME("Region", String.class, e -> e.getRegionName()),
|
||||
DYNAMIC_BASE("Dynamic Base", Address.class, e -> e.getRegionMinAddress()),
|
||||
CHOOSE("Choose", String.class, e -> "Choose Block", (e, s) -> nop()),
|
||||
PROGRAM_NAME("Program", String.class, e -> e.getToProgram().getName()),
|
||||
BLOCK_NAME("Block", String.class, e -> e.getBlock().getName()),
|
||||
|
||||
+7
-5
@@ -193,7 +193,7 @@ public class DebuggerRegionsProvider extends ComponentProviderAdapter {
|
||||
}
|
||||
AddressSet sel = new AddressSet();
|
||||
for (TraceMemoryRegion s : regions) {
|
||||
sel.add(s.getRange());
|
||||
sel.add(s.getRange(current.getSnap()));
|
||||
}
|
||||
ProgramSelection ps = new ProgramSelection(sel);
|
||||
listingService.setCurrentSelection(ps);
|
||||
@@ -403,7 +403,7 @@ public class DebuggerRegionsProvider extends ComponentProviderAdapter {
|
||||
return;
|
||||
}
|
||||
Map<?, RegionMapProposal> map = staticMappingService.proposeRegionMaps(regions,
|
||||
List.of(programManager.getAllOpenPrograms()));
|
||||
current.getSnap(), List.of(programManager.getAllOpenPrograms()));
|
||||
Collection<RegionMapEntry> proposal = MapProposal.flatten(map.values());
|
||||
promptRegionProposal(proposal);
|
||||
}
|
||||
@@ -416,7 +416,8 @@ public class DebuggerRegionsProvider extends ComponentProviderAdapter {
|
||||
if (program == null) {
|
||||
return;
|
||||
}
|
||||
RegionMapProposal map = staticMappingService.proposeRegionMap(regions, program);
|
||||
RegionMapProposal map =
|
||||
staticMappingService.proposeRegionMap(regions, current.getSnap(), program);
|
||||
Collection<RegionMapEntry> proposal = map.computeMap().values();
|
||||
promptRegionProposal(proposal);
|
||||
}
|
||||
@@ -431,7 +432,8 @@ public class DebuggerRegionsProvider extends ComponentProviderAdapter {
|
||||
return;
|
||||
}
|
||||
RegionMapProposal map =
|
||||
staticMappingService.proposeRegionMap(region, location.getProgram(), block);
|
||||
staticMappingService.proposeRegionMap(region, current.getSnap(), location.getProgram(),
|
||||
block);
|
||||
promptRegionProposal(map.computeMap().values());
|
||||
}
|
||||
|
||||
@@ -548,7 +550,7 @@ public class DebuggerRegionsProvider extends ComponentProviderAdapter {
|
||||
Msg.warn(this, "No program manager!");
|
||||
return null;
|
||||
}
|
||||
return blockChooserDialog.chooseBlock(getTool(), region,
|
||||
return blockChooserDialog.chooseBlock(getTool(), region, current.getSnap(),
|
||||
List.of(programManager.getAllOpenPrograms()));
|
||||
}
|
||||
|
||||
|
||||
+16
-30
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -18,7 +18,6 @@ package ghidra.app.plugin.core.debug.gui.memory;
|
||||
import db.Transaction;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressRange;
|
||||
import ghidra.trace.model.Lifespan;
|
||||
import ghidra.trace.model.memory.TraceMemoryRegion;
|
||||
|
||||
public class RegionRow {
|
||||
@@ -34,84 +33,71 @@ public class RegionRow {
|
||||
|
||||
public void setName(String name) {
|
||||
try (Transaction tx = region.getTrace().openTransaction("Rename region")) {
|
||||
region.setName(name);
|
||||
region.setName(0, name);
|
||||
}
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return region.getName();
|
||||
}
|
||||
|
||||
public Lifespan getLifespan() {
|
||||
return region.getLifespan();
|
||||
}
|
||||
|
||||
public long getCreatedSnap() {
|
||||
return region.getCreationSnap();
|
||||
}
|
||||
|
||||
public String getDestroyedSnap() {
|
||||
long snap = region.getDestructionSnap();
|
||||
return snap == Long.MAX_VALUE ? "" : Long.toString(snap);
|
||||
return region.getName(0);
|
||||
}
|
||||
|
||||
public AddressRange getRange() {
|
||||
return region.getRange();
|
||||
return region.getRange(0);
|
||||
}
|
||||
|
||||
public Address getMaxAddress() {
|
||||
return region.getMaxAddress();
|
||||
return region.getMaxAddress(0);
|
||||
}
|
||||
|
||||
public Address getMinAddress() {
|
||||
return region.getMinAddress();
|
||||
return region.getMinAddress(0);
|
||||
}
|
||||
|
||||
public long getLength() {
|
||||
return region.getLength();
|
||||
return region.getLength(0);
|
||||
}
|
||||
|
||||
public void setRead(boolean read) {
|
||||
try (Transaction tx =
|
||||
region.getTrace().openTransaction("Toggle region read flag")) {
|
||||
region.setRead(read);
|
||||
region.setRead(0, read);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isRead() {
|
||||
return region.isRead();
|
||||
return region.isRead(0);
|
||||
}
|
||||
|
||||
public void setWrite(boolean write) {
|
||||
try (Transaction tx =
|
||||
region.getTrace().openTransaction("Toggle region write flag")) {
|
||||
region.setWrite(write);
|
||||
region.setWrite(0, write);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isWrite() {
|
||||
return region.isWrite();
|
||||
return region.isWrite(0);
|
||||
}
|
||||
|
||||
public void setExecute(boolean execute) {
|
||||
try (Transaction tx =
|
||||
region.getTrace().openTransaction("Toggle region execute flag")) {
|
||||
region.setExecute(execute);
|
||||
region.setExecute(0, execute);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isExecute() {
|
||||
return region.isExecute();
|
||||
return region.isExecute(0);
|
||||
}
|
||||
|
||||
public void setVolatile(boolean vol) {
|
||||
try (Transaction tx =
|
||||
region.getTrace().openTransaction("Toggle region volatile flag")) {
|
||||
region.setVolatile(vol);
|
||||
region.setVolatile(0, vol);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isVolatile() {
|
||||
return region.isVolatile();
|
||||
return region.isVolatile(0);
|
||||
}
|
||||
}
|
||||
|
||||
+51
-33
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -21,14 +21,13 @@ import ghidra.async.AsyncDebouncer;
|
||||
import ghidra.async.AsyncTimer;
|
||||
import ghidra.debug.api.tracemgr.DebuggerCoordinates;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.trace.database.module.TraceObjectSection;
|
||||
import ghidra.trace.model.*;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpoint;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointManager;
|
||||
import ghidra.trace.model.memory.TraceMemoryManager;
|
||||
import ghidra.trace.model.memory.TraceMemoryRegion;
|
||||
import ghidra.trace.model.breakpoint.*;
|
||||
import ghidra.trace.model.memory.*;
|
||||
import ghidra.trace.model.modules.*;
|
||||
import ghidra.trace.model.thread.TraceThread;
|
||||
import ghidra.trace.model.thread.TraceThreadManager;
|
||||
import ghidra.trace.model.target.TraceObject;
|
||||
import ghidra.trace.model.thread.*;
|
||||
import ghidra.trace.util.TraceEvents;
|
||||
import ghidra.util.Swing;
|
||||
|
||||
@@ -91,60 +90,79 @@ public class DebuggerMemviewTraceListener extends TraceDomainObjectListener {
|
||||
}
|
||||
|
||||
private void threadChanged(TraceThread thread) {
|
||||
if (!trackThreads || !trackTrace) {
|
||||
if (!trackThreads || !trackTrace || !(thread instanceof TraceObjectThread objThread)) {
|
||||
return;
|
||||
}
|
||||
AddressFactory factory = thread.getTrace().getBaseAddressFactory();
|
||||
AddressSpace defaultSpace = factory.getDefaultAddressSpace();
|
||||
Long threadId = thread.getKey();
|
||||
|
||||
AddressRange rng = rng(defaultSpace, threadId, threadId);
|
||||
MemoryBox box = new MemoryBox("Thread " + thread.getName(), MemviewBoxType.THREAD, rng,
|
||||
thread.getLifespan());
|
||||
updateList.add(box);
|
||||
TraceObject obj = objThread.getObject();
|
||||
obj.getCanonicalParents(Lifespan.ALL).forEach(p -> {
|
||||
MemoryBox box = new MemoryBox("Thread " + thread.getName(p.getMinSnap()),
|
||||
MemviewBoxType.THREAD, rng, p.getLifespan());
|
||||
updateList.add(box);
|
||||
});
|
||||
updateLabelDebouncer.contact(null);
|
||||
}
|
||||
|
||||
private void regionChanged(TraceMemoryRegion region) {
|
||||
if (!trackRegions || !trackTrace) {
|
||||
if (!trackRegions || !trackTrace ||
|
||||
!(region instanceof TraceObjectMemoryRegion objRegion)) {
|
||||
return;
|
||||
}
|
||||
MemoryBox box = new MemoryBox("Region " + region.getName(), MemviewBoxType.VIRTUAL_ALLOC,
|
||||
region.getRange(), region.getLifespan());
|
||||
updateList.add(box);
|
||||
|
||||
TraceObject obj = objRegion.getObject();
|
||||
obj.getOrderedValues(Lifespan.ALL, TraceObjectMemoryRegion.KEY_RANGE, true).forEach(v -> {
|
||||
MemoryBox box = new MemoryBox("Region " + region.getName(v.getMinSnap()),
|
||||
MemviewBoxType.VIRTUAL_ALLOC, v.castValue(), v.getLifespan());
|
||||
updateList.add(box);
|
||||
});
|
||||
updateLabelDebouncer.contact(null);
|
||||
}
|
||||
|
||||
private void moduleChanged(TraceModule module) {
|
||||
if (!trackModules || !trackTrace) {
|
||||
if (!trackModules || !trackTrace || !(module instanceof TraceObjectModule objModule)) {
|
||||
return;
|
||||
}
|
||||
AddressRange range = module.getRange();
|
||||
if (range == null) {
|
||||
return;
|
||||
}
|
||||
MemoryBox box = new MemoryBox("Module " + module.getName(), MemviewBoxType.MODULE, range,
|
||||
module.getLifespan());
|
||||
updateList.add(box);
|
||||
|
||||
TraceObject obj = objModule.getObject();
|
||||
obj.getOrderedValues(Lifespan.ALL, TraceObjectModule.KEY_RANGE, true).forEach(v -> {
|
||||
MemoryBox box = new MemoryBox("Module " + module.getName(v.getMinSnap()),
|
||||
MemviewBoxType.MODULE, v.castValue(), v.getLifespan());
|
||||
updateList.add(box);
|
||||
});
|
||||
updateLabelDebouncer.contact(null);
|
||||
}
|
||||
|
||||
private void sectionChanged(TraceSection section) {
|
||||
if (!trackSections || !trackTrace) {
|
||||
if (!trackSections || !trackTrace || !(section instanceof TraceObjectSection objSection)) {
|
||||
return;
|
||||
}
|
||||
MemoryBox box = new MemoryBox("Section " + section.getName(), MemviewBoxType.IMAGE,
|
||||
section.getRange(), section.getModule().getLifespan());
|
||||
updateList.add(box);
|
||||
|
||||
TraceObject obj = objSection.getObject();
|
||||
obj.getOrderedValues(Lifespan.ALL, TraceObjectSection.KEY_RANGE, true).forEach(v -> {
|
||||
MemoryBox box = new MemoryBox("Module " + section.getName(v.getMinSnap()),
|
||||
MemviewBoxType.IMAGE, v.castValue(), v.getLifespan());
|
||||
updateList.add(box);
|
||||
});
|
||||
updateLabelDebouncer.contact(null);
|
||||
}
|
||||
|
||||
private void breakpointChanged(TraceBreakpoint bpt) {
|
||||
if (!trackBreakpoints || !trackTrace) {
|
||||
if (!trackBreakpoints || !trackTrace ||
|
||||
!(bpt instanceof TraceObjectBreakpointLocation objBpt)) {
|
||||
return;
|
||||
}
|
||||
MemoryBox box = new MemoryBox("Breakpoint " + bpt.getName(), MemviewBoxType.BREAKPOINT,
|
||||
bpt.getRange(), bpt.getLifespan());
|
||||
updateList.add(box);
|
||||
|
||||
TraceObject obj = objBpt.getObject();
|
||||
obj.getOrderedValues(Lifespan.ALL, TraceObjectBreakpointLocation.KEY_RANGE, true)
|
||||
.forEach(v -> {
|
||||
MemoryBox box = new MemoryBox("Module " + bpt.getName(v.getMinSnap()),
|
||||
MemviewBoxType.BREAKPOINT, v.castValue(), v.getLifespan());
|
||||
updateList.add(box);
|
||||
});
|
||||
updateLabelDebouncer.contact(null);
|
||||
}
|
||||
|
||||
@@ -238,7 +256,7 @@ public class DebuggerMemviewTraceListener extends TraceDomainObjectListener {
|
||||
TraceModuleManager moduleManager = trace.getModuleManager();
|
||||
for (TraceModule module : moduleManager.getAllModules()) {
|
||||
moduleChanged(module);
|
||||
Collection<? extends TraceSection> sections = module.getSections();
|
||||
Collection<? extends TraceSection> sections = module.getAllSections();
|
||||
for (TraceSection section : sections) {
|
||||
sectionChanged(section);
|
||||
}
|
||||
|
||||
+3
-2
@@ -34,7 +34,7 @@ import ghidra.debug.api.tracemgr.DebuggerCoordinates;
|
||||
import ghidra.framework.plugintool.*;
|
||||
import ghidra.framework.plugintool.annotation.AutoServiceConsumed;
|
||||
import ghidra.trace.model.Trace;
|
||||
import ghidra.trace.model.target.*;
|
||||
import ghidra.trace.model.target.TraceObject;
|
||||
import ghidra.trace.model.target.iface.TraceObjectInterface;
|
||||
import ghidra.trace.model.target.path.KeyPath;
|
||||
|
||||
@@ -115,7 +115,8 @@ public abstract class AbstractObjectsTableBasedPanel<U extends TraceObjectInterf
|
||||
List<ValueRow> sel = getSelectedItems();
|
||||
if (!sel.isEmpty()) {
|
||||
myActionContext = new DebuggerObjectActionContext(
|
||||
sel.stream().map(r -> r.getValue()).collect(Collectors.toList()), provider, table);
|
||||
sel.stream().map(r -> r.getValue()).collect(Collectors.toList()), provider, table,
|
||||
current.getSnap());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+5
-4
@@ -541,7 +541,7 @@ public class DebuggerModelProvider extends ComponentProvider implements Saveable
|
||||
.map(n -> n.getValue())
|
||||
.filter(o -> o != null) // Root for no trace would return null
|
||||
.collect(Collectors.toList()),
|
||||
DebuggerModelProvider.this, objectsTreePanel);
|
||||
DebuggerModelProvider.this, objectsTreePanel, current.getSnap());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -610,7 +610,7 @@ public class DebuggerModelProvider extends ComponentProvider implements Saveable
|
||||
return new DebuggerObjectActionContext(sel.stream()
|
||||
.map(r -> r.getValue())
|
||||
.collect(Collectors.toList()),
|
||||
DebuggerModelProvider.this, elementsTablePanel);
|
||||
DebuggerModelProvider.this, elementsTablePanel, current.getSnap());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -664,7 +664,7 @@ public class DebuggerModelProvider extends ComponentProvider implements Saveable
|
||||
return new DebuggerObjectActionContext(sel.stream()
|
||||
.map(r -> Objects.requireNonNull(r.getPath().getLastEntry()))
|
||||
.collect(Collectors.toList()),
|
||||
DebuggerModelProvider.this, attributesTablePanel);
|
||||
DebuggerModelProvider.this, attributesTablePanel, current.getSnap());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -768,7 +768,8 @@ public class DebuggerModelProvider extends ComponentProvider implements Saveable
|
||||
return;
|
||||
}
|
||||
Map<String, ActionEntry> actions = target.collectActions(ActionName.REFRESH,
|
||||
new DebuggerObjectActionContext(List.of(value), this, objectsTreePanel));
|
||||
new DebuggerObjectActionContext(List.of(value), this, objectsTreePanel,
|
||||
current.getSnap()));
|
||||
for (ActionEntry ent : actions.values()) {
|
||||
if (ent.requiresPrompt()) {
|
||||
continue;
|
||||
|
||||
+7
-6
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -53,7 +53,8 @@ public class DebuggerLegacyModulesPanel extends JPanel {
|
||||
DebuggerModuleActionContext context) {
|
||||
return context.getSelectedModules()
|
||||
.stream()
|
||||
.flatMap(m -> m.getSections().stream())
|
||||
// snap does not matter for legacy module
|
||||
.flatMap(m -> m.getSections(0).stream())
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@@ -61,7 +62,8 @@ public class DebuggerLegacyModulesPanel extends JPanel {
|
||||
DebuggerModuleActionContext context) {
|
||||
AddressSet sel = new AddressSet();
|
||||
for (TraceModule module : getSelectedModulesFromContext(context)) {
|
||||
sel.add(module.getRange());
|
||||
// snap does not matter for legacy module
|
||||
sel.add(module.getRange(0));
|
||||
}
|
||||
return sel;
|
||||
}
|
||||
@@ -73,7 +75,6 @@ public class DebuggerLegacyModulesPanel extends JPanel {
|
||||
SHORT_NAME("Name", String.class, ModuleRow::getShortName),
|
||||
NAME("Module Name", String.class, ModuleRow::getName, ModuleRow::setName),
|
||||
MAPPING("Mapping", String.class, ModuleRow::getMapping),
|
||||
LIFESPAN("Lifespan", Lifespan.class, ModuleRow::getLifespan),
|
||||
LENGTH("Length", Long.class, ModuleRow::getLength);
|
||||
|
||||
private final String header;
|
||||
@@ -251,7 +252,7 @@ public class DebuggerLegacyModulesPanel extends JPanel {
|
||||
moduleTableModel.addAllItems(moduleManager.getAllModules());
|
||||
}
|
||||
|
||||
public void setTrace(Trace trace) {
|
||||
private void setTrace(Trace trace) {
|
||||
if (currentTrace == trace) {
|
||||
return;
|
||||
}
|
||||
|
||||
+5
-5
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -48,7 +48,7 @@ public class DebuggerLegacySectionsPanel extends JPanel {
|
||||
|
||||
protected static Set<TraceModule> getSelectedModulesFromContext(
|
||||
DebuggerSectionActionContext context) {
|
||||
return context.getSelectedSections(false)
|
||||
return context.getSelectedSections(false, 0)
|
||||
.stream()
|
||||
.map(r -> r.getModule())
|
||||
.collect(Collectors.toSet());
|
||||
@@ -56,14 +56,14 @@ public class DebuggerLegacySectionsPanel extends JPanel {
|
||||
|
||||
protected static Set<TraceSection> getSelectedSectionsFromContext(
|
||||
DebuggerSectionActionContext context, boolean allowExpansion) {
|
||||
return context.getSelectedSections(allowExpansion);
|
||||
return context.getSelectedSections(allowExpansion, 0);
|
||||
}
|
||||
|
||||
protected static AddressSetView getSelectedAddressesFromContext(
|
||||
DebuggerSectionActionContext context) {
|
||||
AddressSet sel = new AddressSet();
|
||||
for (TraceSection section : getSelectedSectionsFromContext(context, false)) {
|
||||
sel.add(section.getRange());
|
||||
sel.add(section.getRange(0));
|
||||
}
|
||||
return sel;
|
||||
}
|
||||
|
||||
+3
-3
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -41,7 +41,7 @@ public class DebuggerModuleMapProposalDialog
|
||||
protected enum ModuleMapTableColumns
|
||||
implements EnumeratedTableColumn<ModuleMapTableColumns, ModuleMapEntry> {
|
||||
REMOVE("Remove", String.class, e -> "Remove Proposed Entry", (e, v) -> nop()),
|
||||
MODULE_NAME("Module", String.class, e -> e.getModule().getName()),
|
||||
MODULE_NAME("Module", String.class, e -> e.getModuleName()),
|
||||
DYNAMIC_BASE("Dynamic Base", Address.class, e -> e.getFromRange().getMinAddress()),
|
||||
CHOOSE("Choose", String.class, e -> "Choose Program", (e, v) -> nop()),
|
||||
PROGRAM_NAME("Program", String.class, e -> (e.getToProgram().getDomainFile() == null
|
||||
|
||||
+3
-3
@@ -190,7 +190,7 @@ public class DebuggerModulesPanel extends AbstractObjectsTableBasedPanel<TraceOb
|
||||
TraceObject child = value.getChild();
|
||||
TraceObjectModule module = child.queryInterface(TraceObjectModule.class);
|
||||
if (module != null) {
|
||||
result.addAll(module.getSections());
|
||||
result.addAll(module.getSections(ctx.getSnap()));
|
||||
continue;
|
||||
}
|
||||
TraceObjectSection section = child.queryInterface(TraceObjectSection.class);
|
||||
@@ -208,12 +208,12 @@ public class DebuggerModulesPanel extends AbstractObjectsTableBasedPanel<TraceOb
|
||||
TraceObject child = value.getChild();
|
||||
TraceObjectModule module = child.queryInterface(TraceObjectModule.class);
|
||||
if (module != null) {
|
||||
result.add(module.getRange());
|
||||
result.add(module.getRange(ctx.getSnap()));
|
||||
continue;
|
||||
}
|
||||
TraceObjectSection section = child.queryInterface(TraceObjectSection.class);
|
||||
if (section != null) {
|
||||
result.add(section.getRange());
|
||||
result.add(section.getRange(ctx.getSnap()));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
+35
-22
@@ -402,13 +402,20 @@ public class DebuggerModulesProvider extends ComponentProviderAdapter
|
||||
return;
|
||||
}
|
||||
couldHaveChanged = false;
|
||||
String infosThisTime = spec.getInfoForObjects(trace);
|
||||
DebuggerTraceManagerService traceManager =
|
||||
tool.getService(DebuggerTraceManagerService.class);
|
||||
if (traceManager == null) {
|
||||
return;
|
||||
}
|
||||
DebuggerCoordinates current = traceManager.getCurrentFor(trace);
|
||||
long snap = current.getSnap();
|
||||
String infosThisTime = spec.getInfoForObjects(trace, snap);
|
||||
if (Objects.equals(infosThisTime, infosLastTime)) {
|
||||
return;
|
||||
}
|
||||
infosLastTime = infosThisTime;
|
||||
|
||||
spec.runTask(tool, trace);
|
||||
spec.runTask(tool, trace, snap);
|
||||
}
|
||||
|
||||
public void forceMap() {
|
||||
@@ -593,7 +600,6 @@ public class DebuggerModulesProvider extends ComponentProviderAdapter
|
||||
boolean filterSectionsByModules = false;
|
||||
|
||||
private final Map<Trace, AutoMapState> autoMapStateByTrace = new WeakHashMap<>();
|
||||
private AutoMapState forMappingListener;
|
||||
|
||||
DockingAction actionImportMissingModule;
|
||||
DockingAction actionMapMissingModule;
|
||||
@@ -634,7 +640,7 @@ public class DebuggerModulesProvider extends ComponentProviderAdapter
|
||||
|
||||
private void importModuleFromFileSystem(TraceModule module) {
|
||||
GhidraFileChooser chooser = new GhidraFileChooser(getComponent());
|
||||
chooser.setSelectedFile(new File(module.getName()));
|
||||
chooser.setSelectedFile(new File(module.getName(current.getSnap())));
|
||||
File file = chooser.getSelectedFile();
|
||||
chooser.dispose();
|
||||
if (file == null) { // Perhaps cancelled
|
||||
@@ -837,7 +843,7 @@ public class DebuggerModulesProvider extends ComponentProviderAdapter
|
||||
return !ctx.getSelectedModules().isEmpty();
|
||||
}
|
||||
if (context instanceof DebuggerSectionActionContext ctx) {
|
||||
return !ctx.getSelectedSections(false).isEmpty();
|
||||
return !ctx.getSelectedSections(false, current.getSnap()).isEmpty();
|
||||
}
|
||||
if (context instanceof DebuggerObjectActionContext ctx) {
|
||||
return !ctx.getObjectValues().isEmpty();
|
||||
@@ -978,10 +984,13 @@ public class DebuggerModulesProvider extends ComponentProviderAdapter
|
||||
if (staticMappingService == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Program program = context.getProgram();
|
||||
Trace trace = context.getTrace();
|
||||
long snap = traceManager.getCurrentFor(trace).getSnap();
|
||||
|
||||
Map<TraceModule, ModuleMapProposal> map = staticMappingService.proposeModuleMaps(
|
||||
trace.getModuleManager().getAllModules(), List.of(program));
|
||||
trace.getModuleManager().getAllModules(), snap, List.of(program));
|
||||
Collection<ModuleMapEntry> proposal = MapProposal.flatten(map.values());
|
||||
promptModuleProposal(proposal, FMT_NO_MODULES_PROPOSAL_RETRY.formatted(
|
||||
trace.getDomainFile().getName(), program.getDomainFile().getName()));
|
||||
@@ -1022,10 +1031,10 @@ public class DebuggerModulesProvider extends ComponentProviderAdapter
|
||||
|
||||
Program program = context.getProgram();
|
||||
ModuleMapProposal proposal =
|
||||
staticMappingService.proposeModuleMap(module, program);
|
||||
staticMappingService.proposeModuleMap(module, snap, program);
|
||||
Map<TraceModule, ModuleMapEntry> map = proposal.computeMap();
|
||||
promptModuleProposal(map.values(), FMT_NO_MODULES_PROPOSAL_CURRENT.formatted(
|
||||
module.getName(), program.getDomainFile().getName()));
|
||||
module.getName(snap), program.getDomainFile().getName()));
|
||||
}
|
||||
|
||||
private void activatedMapMissingProgramIdentically(
|
||||
@@ -1089,16 +1098,16 @@ public class DebuggerModulesProvider extends ComponentProviderAdapter
|
||||
return;
|
||||
}
|
||||
|
||||
long snap = current.getSnap();
|
||||
ProgramSelection progSel = listingService.getCurrentSelection();
|
||||
TraceModuleManager moduleManager = current.getTrace().getModuleManager();
|
||||
if (progSel != null && !progSel.isEmpty()) {
|
||||
long snap = traceManager.getCurrentSnap();
|
||||
Set<TraceModule> modSel = new HashSet<>();
|
||||
Set<TraceSection> sectionSel = new HashSet<>();
|
||||
for (AddressRange range : progSel) {
|
||||
for (TraceModule module : moduleManager
|
||||
.getModulesIntersecting(Lifespan.at(snap), range)) {
|
||||
if (module.getSections().isEmpty()) {
|
||||
if (module.getSections(snap).isEmpty()) {
|
||||
modSel.add(module);
|
||||
}
|
||||
}
|
||||
@@ -1127,7 +1136,7 @@ public class DebuggerModulesProvider extends ComponentProviderAdapter
|
||||
TraceModule bestModule = null;
|
||||
for (TraceModule module : moduleManager
|
||||
.getLoadedModules(traceManager.getCurrentSnap())) {
|
||||
Address base = module.getBase();
|
||||
Address base = module.getBase(snap);
|
||||
if (base == null || base.getAddressSpace() != address.getAddressSpace()) {
|
||||
continue;
|
||||
}
|
||||
@@ -1138,12 +1147,12 @@ public class DebuggerModulesProvider extends ComponentProviderAdapter
|
||||
if (base.compareTo(address) > 0) {
|
||||
continue;
|
||||
}
|
||||
if (base.compareTo(bestModule.getBase()) <= 0) {
|
||||
if (base.compareTo(bestModule.getBase(snap)) <= 0) {
|
||||
continue;
|
||||
}
|
||||
bestModule = module;
|
||||
}
|
||||
if (bestModule.getSections().isEmpty()) {
|
||||
if (bestModule.getSections(snap).isEmpty()) {
|
||||
setSelectedModules(Set.of(bestModule));
|
||||
return;
|
||||
}
|
||||
@@ -1168,8 +1177,9 @@ public class DebuggerModulesProvider extends ComponentProviderAdapter
|
||||
if (staticMappingService == null) {
|
||||
return;
|
||||
}
|
||||
Map<TraceModule, ModuleMapProposal> map = staticMappingService.proposeModuleMaps(modules,
|
||||
List.of(programManager.getAllOpenPrograms()));
|
||||
Map<TraceModule, ModuleMapProposal> map =
|
||||
staticMappingService.proposeModuleMaps(modules, current.getSnap(),
|
||||
List.of(programManager.getAllOpenPrograms()));
|
||||
Collection<ModuleMapEntry> proposal = MapProposal.flatten(map.values());
|
||||
promptModuleProposal(proposal, NO_MODULES_PROPOSAL_SEL);
|
||||
}
|
||||
@@ -1182,7 +1192,8 @@ public class DebuggerModulesProvider extends ComponentProviderAdapter
|
||||
if (program == null) {
|
||||
return;
|
||||
}
|
||||
ModuleMapProposal proposal = staticMappingService.proposeModuleMap(module, program);
|
||||
ModuleMapProposal proposal =
|
||||
staticMappingService.proposeModuleMap(module, current.getSnap(), program);
|
||||
Map<TraceModule, ModuleMapEntry> map = proposal.computeMap();
|
||||
promptModuleProposal(map.values(), NO_MODULES_PROPOSAL_SEL);
|
||||
}
|
||||
@@ -1209,8 +1220,9 @@ public class DebuggerModulesProvider extends ComponentProviderAdapter
|
||||
}
|
||||
Set<TraceModule> modules =
|
||||
sections.stream().map(TraceSection::getModule).collect(Collectors.toSet());
|
||||
Map<?, SectionMapProposal> map = staticMappingService.proposeSectionMaps(modules,
|
||||
List.of(programManager.getAllOpenPrograms()));
|
||||
Map<?, SectionMapProposal> map =
|
||||
staticMappingService.proposeSectionMaps(modules, current.getSnap(),
|
||||
List.of(programManager.getAllOpenPrograms()));
|
||||
Collection<SectionMapEntry> proposal = MapProposal.flatten(map.values());
|
||||
Collection<SectionMapEntry> filtered = proposal.stream()
|
||||
.filter(e -> sections.contains(e.getSection()))
|
||||
@@ -1232,7 +1244,8 @@ public class DebuggerModulesProvider extends ComponentProviderAdapter
|
||||
return;
|
||||
}
|
||||
TraceModule module = modules.iterator().next();
|
||||
SectionMapProposal map = staticMappingService.proposeSectionMap(module, program);
|
||||
SectionMapProposal map =
|
||||
staticMappingService.proposeSectionMap(module, current.getSnap(), program);
|
||||
Collection<SectionMapEntry> proposal = map.computeMap().values();
|
||||
Collection<SectionMapEntry> filtered = proposal.stream()
|
||||
.filter(e -> sections.contains(e.getSection()))
|
||||
@@ -1249,8 +1262,8 @@ public class DebuggerModulesProvider extends ComponentProviderAdapter
|
||||
if (block == null) {
|
||||
return;
|
||||
}
|
||||
SectionMapProposal map =
|
||||
staticMappingService.proposeSectionMap(section, location.getProgram(), block);
|
||||
SectionMapProposal map = staticMappingService.proposeSectionMap(section, current.getSnap(),
|
||||
location.getProgram(), block);
|
||||
promptSectionProposal(map.computeMap().values());
|
||||
}
|
||||
|
||||
@@ -1444,7 +1457,7 @@ public class DebuggerModulesProvider extends ComponentProviderAdapter
|
||||
Msg.warn(this, "No program manager!");
|
||||
return null;
|
||||
}
|
||||
return blockChooserDialog.chooseBlock(getTool(), section,
|
||||
return blockChooserDialog.chooseBlock(getTool(), section, current.getSnap(),
|
||||
List.of(programManager.getAllOpenPrograms()));
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -45,10 +45,10 @@ public class DebuggerSectionActionContext extends DefaultActionContext {
|
||||
this.forcedSingle = forcedSingle;
|
||||
}
|
||||
|
||||
public Set<TraceSection> getSelectedSections(boolean allowExpansion) {
|
||||
public Set<TraceSection> getSelectedSections(boolean allowExpansion, long snap) {
|
||||
if (forcedSingle && allowExpansion) {
|
||||
return selectedSections.stream()
|
||||
.flatMap(s -> s.getModule().getSections().stream())
|
||||
.flatMap(s -> s.getModule().getSections(snap).stream())
|
||||
.collect(Collectors.toUnmodifiableSet());
|
||||
}
|
||||
return selectedSections;
|
||||
|
||||
+5
-5
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -42,9 +42,9 @@ public class DebuggerSectionMapProposalDialog
|
||||
protected enum SectionMapTableColumns
|
||||
implements EnumeratedTableColumn<SectionMapTableColumns, SectionMapEntry> {
|
||||
REMOVE("Remove", String.class, e -> "Remove Proposed Entry", (e, v) -> nop()),
|
||||
MODULE_NAME("Module", String.class, e -> e.getModule().getName()),
|
||||
SECTION_NAME("Section", String.class, e -> e.getSection().getName()),
|
||||
DYNAMIC_BASE("Dynamic Base", Address.class, e -> e.getSection().getStart()),
|
||||
MODULE_NAME("Module", String.class, e -> e.getModuleName()),
|
||||
SECTION_NAME("Section", String.class, e -> e.getSectionName()),
|
||||
DYNAMIC_BASE("Dynamic Base", Address.class, e -> e.getSectionStart()),
|
||||
CHOOSE("Choose", String.class, e -> "Choose Block", (e, s) -> nop()),
|
||||
PROGRAM_NAME("Program", String.class, e -> e.getToProgram().getName()),
|
||||
BLOCK_NAME("Block", String.class, e -> e.getBlock().getName()),
|
||||
|
||||
+9
-23
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -18,7 +18,6 @@ package ghidra.app.plugin.core.debug.gui.modules;
|
||||
import db.Transaction;
|
||||
import ghidra.app.plugin.core.debug.service.modules.DebuggerStaticMappingUtils;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.trace.model.Lifespan;
|
||||
import ghidra.trace.model.modules.TraceModule;
|
||||
|
||||
public class ModuleRow {
|
||||
@@ -36,16 +35,16 @@ public class ModuleRow {
|
||||
|
||||
public void setName(String name) {
|
||||
try (Transaction tx = module.getTrace().openTransaction("Renamed module")) {
|
||||
module.setName(name);
|
||||
module.setName(0, name);
|
||||
}
|
||||
}
|
||||
|
||||
public String getShortName() {
|
||||
return DebuggerStaticMappingUtils.computeModuleShortName(module.getName());
|
||||
return DebuggerStaticMappingUtils.computeModuleShortName(module.getName(0));
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return module.getName();
|
||||
return module.getName(0);
|
||||
}
|
||||
|
||||
public String getMapping() {
|
||||
@@ -54,31 +53,18 @@ public class ModuleRow {
|
||||
// 2. Range/Life changes to this module
|
||||
// 3. Snapshot navigation
|
||||
return DebuggerStaticMappingUtils.computeMappedFiles(module.getTrace(),
|
||||
provider.current.getSnap(), module.getRange());
|
||||
provider.current.getSnap(), module.getRange(0));
|
||||
}
|
||||
|
||||
public Address getBase() {
|
||||
return module.getBase();
|
||||
return module.getBase(0);
|
||||
}
|
||||
|
||||
public Address getMaxAddress() {
|
||||
return module.getMaxAddress();
|
||||
}
|
||||
|
||||
public long getLoadedSnap() {
|
||||
return module.getLoadedSnap();
|
||||
}
|
||||
|
||||
public Long getUnloadedSnap() {
|
||||
long snap = module.getUnloadedSnap();
|
||||
return snap == Long.MAX_VALUE ? null : snap;
|
||||
}
|
||||
|
||||
public Lifespan getLifespan() {
|
||||
return module.getLifespan();
|
||||
return module.getMaxAddress(0);
|
||||
}
|
||||
|
||||
public long getLength() {
|
||||
return module.getLength();
|
||||
return module.getLength(0);
|
||||
}
|
||||
}
|
||||
|
||||
+9
-16
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -18,8 +18,6 @@ package ghidra.app.plugin.core.debug.gui.modules;
|
||||
import db.Transaction;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressRange;
|
||||
import ghidra.trace.model.DefaultTraceLocation;
|
||||
import ghidra.trace.model.TraceLocation;
|
||||
import ghidra.trace.model.modules.TraceModule;
|
||||
import ghidra.trace.model.modules.TraceSection;
|
||||
import ghidra.util.Msg;
|
||||
@@ -42,7 +40,7 @@ public class SectionRow {
|
||||
|
||||
public void setName(String name) {
|
||||
try (Transaction tx = section.getTrace().openTransaction("Rename section")) {
|
||||
section.setName(name);
|
||||
section.setName(0, name);
|
||||
}
|
||||
catch (DuplicateNameException e) {
|
||||
Msg.showError(this, null, "Rename Section",
|
||||
@@ -51,31 +49,26 @@ public class SectionRow {
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return section.getName();
|
||||
return section.getName(0);
|
||||
}
|
||||
|
||||
public String getModuleName() {
|
||||
return section.getModule().getName();
|
||||
return section.getModule().getName(0);
|
||||
}
|
||||
|
||||
public AddressRange getRange() {
|
||||
return section.getRange();
|
||||
return section.getRange(0);
|
||||
}
|
||||
|
||||
public Address getStart() {
|
||||
return section.getStart();
|
||||
return section.getStart(0);
|
||||
}
|
||||
|
||||
public Address getEnd() {
|
||||
return section.getEnd();
|
||||
return section.getEnd(0);
|
||||
}
|
||||
|
||||
public long getLength() {
|
||||
return section.getRange().getLength();
|
||||
}
|
||||
|
||||
public TraceLocation getTraceLocation() {
|
||||
return new DefaultTraceLocation(section.getModule().getTrace(), null,
|
||||
section.getModule().getLifespan(), section.getStart());
|
||||
return section.getRange(0).getLength();
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -783,7 +783,7 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
|
||||
|
||||
protected String computeSubTitle() {
|
||||
TraceThread curThread = current.getThread();
|
||||
return curThread == null ? "" : curThread.getName();
|
||||
return curThread == null ? "" : curThread.getName(current.getSnap());
|
||||
}
|
||||
|
||||
protected void updateSubTitle() {
|
||||
|
||||
+2
-5
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -129,9 +129,6 @@ public class DebuggerLegacyStackPanel extends JPanel {
|
||||
}
|
||||
|
||||
private void stackAdded(TraceStack stack) {
|
||||
if (stack.getSnap() != current.getViewSnap()) {
|
||||
return;
|
||||
}
|
||||
TraceThread curThread = current.getThread();
|
||||
if (curThread != stack.getThread()) {
|
||||
return;
|
||||
|
||||
+3
-3
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -145,7 +145,7 @@ public class DebuggerStackProvider extends ComponentProviderAdapter {
|
||||
|
||||
protected String computeSubTitle() {
|
||||
TraceThread curThread = current.getThread();
|
||||
return curThread == null ? "" : curThread.getName();
|
||||
return curThread == null ? "" : curThread.getName(current.getSnap());
|
||||
}
|
||||
|
||||
protected void updateSubTitle() {
|
||||
|
||||
+4
-3
@@ -269,9 +269,10 @@ public enum VariableValueUtils {
|
||||
RegisterValue spRV = regs.getValue(platform, viewSnap, sp);
|
||||
Address spVal = cSpec.getStackBaseSpace().getAddress(spRV.getUnsignedValue().longValue());
|
||||
Address max;
|
||||
TraceMemoryRegion stackRegion = mem.getRegionContaining(coordinates.getSnap(), spVal);
|
||||
long snap = coordinates.getSnap();
|
||||
TraceMemoryRegion stackRegion = mem.getRegionContaining(snap, spVal);
|
||||
if (stackRegion != null) {
|
||||
max = stackRegion.getMaxAddress();
|
||||
max = stackRegion.getMaxAddress(snap);
|
||||
}
|
||||
else {
|
||||
long toMax = spVal.getAddressSpace().getMaxAddress().subtract(spVal);
|
||||
@@ -408,7 +409,7 @@ public enum VariableValueUtils {
|
||||
if (stack == null) {
|
||||
return null;
|
||||
}
|
||||
TraceStackFrame frame = stack.getFrame(0, false);
|
||||
TraceStackFrame frame = stack.getFrame(snap, 0, false);
|
||||
if (frame == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
+5
-63
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -38,10 +38,10 @@ import ghidra.framework.model.DomainObjectEvent;
|
||||
import ghidra.framework.plugintool.AutoService;
|
||||
import ghidra.framework.plugintool.annotation.AutoServiceConsumed;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.trace.model.*;
|
||||
import ghidra.trace.model.Trace;
|
||||
import ghidra.trace.model.TraceDomainObjectListener;
|
||||
import ghidra.trace.model.thread.TraceThread;
|
||||
import ghidra.trace.model.thread.TraceThreadManager;
|
||||
import ghidra.trace.model.time.TraceSnapshot;
|
||||
import ghidra.trace.util.TraceEvents;
|
||||
import ghidra.util.database.ObjectKey;
|
||||
import ghidra.util.table.GhidraTable;
|
||||
@@ -62,12 +62,9 @@ public class DebuggerLegacyThreadsPanel extends JPanel {
|
||||
true, true),
|
||||
MODULE("Module", String.class, ThreadRow::getModule, true, false),
|
||||
SP("SP", Address.class, ThreadRow::getStackPointer, true, false),
|
||||
CREATED("Created", Long.class, ThreadRow::getCreationSnap, true, false),
|
||||
DESTROYED("Destroyed", String.class, ThreadRow::getDestructionSnap, true, false),
|
||||
|
||||
STATE("State", ThreadState.class, ThreadRow::getState, true, true),
|
||||
COMMENT("Comment", String.class, ThreadRow::getComment, ThreadRow::setComment, true, false),
|
||||
PLOT("Plot", Lifespan.class, ThreadRow::getLifespan, false, true);
|
||||
COMMENT("Comment", String.class, ThreadRow::getComment, ThreadRow::setComment, true, false);
|
||||
|
||||
private final String header;
|
||||
private final Function<ThreadRow, ?> getter;
|
||||
@@ -145,9 +142,6 @@ public class DebuggerLegacyThreadsPanel extends JPanel {
|
||||
listenFor(TraceEvents.THREAD_CHANGED, this::threadChanged);
|
||||
listenFor(TraceEvents.THREAD_LIFESPAN_CHANGED, this::threadChanged);
|
||||
listenFor(TraceEvents.THREAD_DELETED, this::threadDeleted);
|
||||
|
||||
listenFor(TraceEvents.SNAPSHOT_ADDED, this::snapAdded);
|
||||
listenFor(TraceEvents.SNAPSHOT_DELETED, this::snapDeleted);
|
||||
}
|
||||
|
||||
private void objectRestored(DomainObjectChangeRecord rec) {
|
||||
@@ -165,14 +159,6 @@ public class DebuggerLegacyThreadsPanel extends JPanel {
|
||||
private void threadDeleted(TraceThread thread) {
|
||||
threadTableModel.deleteItem(thread);
|
||||
}
|
||||
|
||||
private void snapAdded(TraceSnapshot snapshot) {
|
||||
updateTimelineMax();
|
||||
}
|
||||
|
||||
private void snapDeleted() {
|
||||
updateTimelineMax();
|
||||
}
|
||||
}
|
||||
|
||||
private final DebuggerThreadsProvider provider;
|
||||
@@ -187,10 +173,6 @@ public class DebuggerLegacyThreadsPanel extends JPanel {
|
||||
|
||||
private final ForThreadsListener forThreadsListener = new ForThreadsListener();
|
||||
|
||||
/* package access for testing */
|
||||
final SpanTableCellRenderer<Long> spanRenderer = new SpanTableCellRenderer<>();
|
||||
final RangeCursorTableHeaderRenderer<Long> headerRenderer;
|
||||
|
||||
final TableCellRenderer boldCurrentRenderer = new AbstractGColumnRenderer<Object>() {
|
||||
@Override
|
||||
public String getFilterString(Object t, Settings settings) {
|
||||
@@ -225,8 +207,6 @@ public class DebuggerLegacyThreadsPanel extends JPanel {
|
||||
this.autoServiceWiring = AutoService.wireServicesConsumed(plugin, this);
|
||||
|
||||
threadTableModel = new ThreadTableModel(provider);
|
||||
headerRenderer = new RangeCursorTableHeaderRenderer<>(0L,
|
||||
threadTableModel.getColumn(ThreadTableColumns.PLOT.ordinal()));
|
||||
threadTable = new GhidraTable(threadTableModel);
|
||||
threadTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||
add(new JScrollPane(threadTable));
|
||||
@@ -269,32 +249,10 @@ public class DebuggerLegacyThreadsPanel extends JPanel {
|
||||
TableColumnModel columnModel = threadTable.getColumnModel();
|
||||
TableColumn colName = columnModel.getColumn(ThreadTableColumns.NAME.ordinal());
|
||||
colName.setCellRenderer(boldCurrentRenderer);
|
||||
TableColumn colCreated = columnModel.getColumn(ThreadTableColumns.CREATED.ordinal());
|
||||
colCreated.setCellRenderer(boldCurrentRenderer);
|
||||
TableColumn colDestroyed = columnModel.getColumn(ThreadTableColumns.DESTROYED.ordinal());
|
||||
colDestroyed.setCellRenderer(boldCurrentRenderer);
|
||||
TableColumn colState = columnModel.getColumn(ThreadTableColumns.STATE.ordinal());
|
||||
colState.setCellRenderer(boldCurrentRenderer);
|
||||
TableColumn colComment = columnModel.getColumn(ThreadTableColumns.COMMENT.ordinal());
|
||||
colComment.setCellRenderer(boldCurrentRenderer);
|
||||
TableColumn colPlot = columnModel.getColumn(ThreadTableColumns.PLOT.ordinal());
|
||||
colPlot.setCellRenderer(spanRenderer);
|
||||
colPlot.setHeaderRenderer(headerRenderer);
|
||||
|
||||
headerRenderer.addSeekListener(seekListener = pos -> {
|
||||
long snap = Math.round(pos);
|
||||
if (snap < 0) {
|
||||
snap = 0;
|
||||
}
|
||||
long max =
|
||||
current.getTrace() == null ? 0 : current.getTrace().getTimeManager().getMaxSnap();
|
||||
if (snap > max) {
|
||||
snap = max;
|
||||
}
|
||||
traceManager.activateSnap(snap);
|
||||
myActionContext = new DebuggerSnapActionContext(current.getTrace(), snap);
|
||||
provider.legacyThreadsPanelContextChanged();
|
||||
});
|
||||
}
|
||||
|
||||
private void removeOldListeners() {
|
||||
@@ -326,7 +284,6 @@ public class DebuggerLegacyThreadsPanel extends JPanel {
|
||||
current = coordinates;
|
||||
doSetTrace(coordinates.getTrace());
|
||||
doSetThread(coordinates.getThread());
|
||||
doSetSnap(coordinates.getSnap());
|
||||
}
|
||||
|
||||
private void doSetThread(TraceThread thread) {
|
||||
@@ -339,11 +296,6 @@ public class DebuggerLegacyThreadsPanel extends JPanel {
|
||||
threadTableModel.fireTableDataChanged();
|
||||
}
|
||||
|
||||
private void doSetSnap(long snap) {
|
||||
headerRenderer.setCursorPosition(snap);
|
||||
threadTable.getTableHeader().repaint();
|
||||
}
|
||||
|
||||
protected void loadThreads() {
|
||||
threadTableModel.clear();
|
||||
Trace curTrace = current.getTrace();
|
||||
@@ -352,16 +304,6 @@ public class DebuggerLegacyThreadsPanel extends JPanel {
|
||||
}
|
||||
TraceThreadManager manager = curTrace.getThreadManager();
|
||||
threadTableModel.addAllItems(manager.getAllThreads());
|
||||
updateTimelineMax();
|
||||
}
|
||||
|
||||
protected void updateTimelineMax() {
|
||||
Trace trace = current.getTrace();
|
||||
long max = orZero(trace == null ? null : trace.getTimeManager().getMaxSnap());
|
||||
Lifespan fullRange = Lifespan.span(0, max + 1);
|
||||
spanRenderer.setFullRange(fullRange);
|
||||
headerRenderer.setFullRange(fullRange);
|
||||
threadTable.getTableHeader().repaint();
|
||||
}
|
||||
|
||||
private void threadRowSelected(ListSelectionEvent e) {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user