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