diff --git a/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/listing/InternalTraceBaseDefinedUnitsView.java b/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/listing/InternalTraceBaseDefinedUnitsView.java index 1651b29cc9..5b990c15d3 100644 --- a/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/listing/InternalTraceBaseDefinedUnitsView.java +++ b/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/listing/InternalTraceBaseDefinedUnitsView.java @@ -4,9 +4,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -33,4 +33,10 @@ public interface InternalTraceBaseDefinedUnitsView AddressRange range = platform.getConventionalRegisterRange(getSpace(), register); clear(span, range, true, monitor); } + + @Override + default void clear(Lifespan span, Register register, TaskMonitor monitor) + throws CancelledException { + clear(getTrace().getPlatformManager().getHostPlatform(), span, register, monitor); + } } diff --git a/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/model/listing/TraceBaseDefinedUnitsView.java b/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/model/listing/TraceBaseDefinedUnitsView.java index 1785094f6c..5d142e16a2 100644 --- a/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/model/listing/TraceBaseDefinedUnitsView.java +++ b/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/model/listing/TraceBaseDefinedUnitsView.java @@ -4,9 +4,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -60,10 +60,7 @@ public interface TraceBaseDefinedUnitsView * @param monitor a monitor for progress and cancellation * @throws CancelledException if the clear is cancelled */ - default void clear(Lifespan span, Register register, TaskMonitor monitor) - throws CancelledException { - clear(span, TraceRegisterUtils.rangeForRegister(register), true, monitor); - } + void clear(Lifespan span, Register register, TaskMonitor monitor) throws CancelledException; /** * Clear the units contained within the given span and platform register diff --git a/Ghidra/Debug/Framework-TraceModeling/src/test/java/ghidra/trace/database/listing/DBTraceCodeManagerTest.java b/Ghidra/Debug/Framework-TraceModeling/src/test/java/ghidra/trace/database/listing/DBTraceCodeManagerTest.java index 7d86bf4dbf..53a05e1751 100644 --- a/Ghidra/Debug/Framework-TraceModeling/src/test/java/ghidra/trace/database/listing/DBTraceCodeManagerTest.java +++ b/Ghidra/Debug/Framework-TraceModeling/src/test/java/ghidra/trace/database/listing/DBTraceCodeManagerTest.java @@ -20,8 +20,7 @@ import static org.junit.Assert.*; import java.io.File; import java.io.IOException; import java.math.BigInteger; -import java.util.ArrayList; -import java.util.List; +import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.function.Function; @@ -45,7 +44,11 @@ import ghidra.trace.database.guest.*; import ghidra.trace.model.ImmutableTraceAddressSnapRange; import ghidra.trace.model.Lifespan; import ghidra.trace.model.listing.*; +import ghidra.trace.model.memory.TraceMemorySpace; import ghidra.trace.model.stack.TraceStack; +import ghidra.trace.model.target.TraceObject; +import ghidra.trace.model.target.TraceObject.ConflictResolution; +import ghidra.trace.model.target.path.KeyPath; import ghidra.trace.model.target.schema.SchemaContext; import ghidra.trace.model.thread.TraceThread; import ghidra.trace.util.TraceRegisterUtils; @@ -1839,6 +1842,65 @@ public class DBTraceCodeManagerTest extends AbstractGhidraHeadlessIntegrationTes assertEquals(rvOne, ctxManager.getValue(b.language, r4, 6, b.addr(0x4008))); } + @Test + public void testClearInRegisterSpace() throws CodeUnitInsertionException, CancelledException { + TraceCodeSpace regCode; + try (Transaction tx = b.startTransaction()) { + b.createRootObject(); + KeyPath pathThread = KeyPath.parse("Targets[0].Threads[1]"); + TraceObject objThread = b.trace.getObjectManager().createObject(pathThread); + objThread.insert(Lifespan.nowOn(0), ConflictResolution.DENY); + TraceThread thread = + Objects.requireNonNull(objThread.queryInterface(TraceThread.class)); + TraceObject objRegs = b.trace.getObjectManager() + .createObject(KeyPath.parse("Targets[0].Threads[1].Registers")); + objRegs.insert(Lifespan.nowOn(0), ConflictResolution.DENY); + + Register r0 = b.reg("r0"); + TraceMemorySpace regBytes = + b.trace.getMemoryManager().getMemoryRegisterSpace(thread, true); + regBytes.setValue(0, new RegisterValue(r0, BigInteger.ONE)); + + regCode = regBytes.getCodeSpace(true); + regCode.definedData().create(Lifespan.nowOn(0), r0, LongDataType.dataType); + regCode.definedData().clear(Lifespan.nowOn(1), r0, TaskMonitor.DUMMY); + } + + List result = new ArrayList<>(); + regCode.definedUnits().get(1, true).forEach(result::add); + assertEquals(0, result.size()); + } + + @Test + public void testClearInRegisterSpaceUsingHostPlatform() + throws CodeUnitInsertionException, CancelledException { + TraceCodeSpace regCode; + try (Transaction tx = b.startTransaction()) { + b.createRootObject(); + KeyPath pathThread = KeyPath.parse("Targets[0].Threads[1]"); + TraceObject objThread = b.trace.getObjectManager().createObject(pathThread); + objThread.insert(Lifespan.nowOn(0), ConflictResolution.DENY); + TraceThread thread = + Objects.requireNonNull(objThread.queryInterface(TraceThread.class)); + TraceObject objRegs = b.trace.getObjectManager() + .createObject(KeyPath.parse("Targets[0].Threads[1].Registers")); + objRegs.insert(Lifespan.nowOn(0), ConflictResolution.DENY); + + Register r0 = b.reg("r0"); + TraceMemorySpace regBytes = + b.trace.getMemoryManager().getMemoryRegisterSpace(thread, true); + regBytes.setValue(0, new RegisterValue(r0, BigInteger.ONE)); + + regCode = regBytes.getCodeSpace(true); + regCode.definedData().create(Lifespan.nowOn(0), r0, LongDataType.dataType); + regCode.definedData().clear(b.host, Lifespan.nowOn(1), r0, TaskMonitor.DUMMY); + } + + List result = new ArrayList<>(); + regCode.definedUnits().get(1, true).forEach(result::add); + assertEquals(0, result.size()); + } + @Test public void testAddGuestInstructionThenRemoveAndDelete() throws AddressOverflowException, CodeUnitInsertionException, IOException, CancelledException {