Merge remote-tracking branch 'origin/GP-3280_Dan_torchUnneededStateImpls'

This commit is contained in:
Ryan Kurtz 2023-04-24 06:49:13 -04:00
commit 66d494c603
5 changed files with 0 additions and 346 deletions

View File

@ -1,44 +0,0 @@
/* ###
* IP: GHIDRA
*
* 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.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.pcode.exec.trace;
import ghidra.pcode.exec.trace.data.PcodeTraceDataAccess;
/**
* A state composing a single {@link RequireHasKnownTraceCachedWriteBytesPcodeExecutorStatePiece}
*/
public class RequireHasKnownTraceCachedWriteBytesPcodeExecutorState
extends DefaultTracePcodeExecutorState<byte[]> {
/**
* Create the state
*
* @param data the trace-data access shim
*/
public RequireHasKnownTraceCachedWriteBytesPcodeExecutorState(PcodeTraceDataAccess data) {
super(new RequireHasKnownTraceCachedWriteBytesPcodeExecutorStatePiece(data));
}
protected RequireHasKnownTraceCachedWriteBytesPcodeExecutorState(
TracePcodeExecutorStatePiece<byte[], byte[]> piece) {
super(piece);
}
@Override
public RequireHasKnownTraceCachedWriteBytesPcodeExecutorState fork() {
return new RequireHasKnownTraceCachedWriteBytesPcodeExecutorState(piece.fork());
}
}

View File

@ -1,63 +0,0 @@
/* ###
* IP: GHIDRA
*
* 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.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.pcode.exec.trace;
import ghidra.pcode.exec.AccessPcodeExecutionException;
import ghidra.pcode.exec.trace.data.PcodeTraceDataAccess;
import ghidra.program.model.address.AddressSetView;
import ghidra.trace.model.memory.TraceMemoryState;
/**
* A relaxation of {@link RequireIsKnownTraceCachedWriteBytesPcodeExecutorStatePiece} that permits
* reads of stale addresses
*
* <p>
* An address can be read so long as it is {@link TraceMemoryState#KNOWN} for any non-scratch snap
* up to and including the given snap.
*/
public class RequireHasKnownTraceCachedWriteBytesPcodeExecutorStatePiece
extends RequireIsKnownTraceCachedWriteBytesPcodeExecutorStatePiece {
/**
* Construct a piece
*
* @param data the trace-data access shim
*/
public RequireHasKnownTraceCachedWriteBytesPcodeExecutorStatePiece(PcodeTraceDataAccess data) {
super(data);
}
protected RequireHasKnownTraceCachedWriteBytesPcodeExecutorStatePiece(PcodeTraceDataAccess data,
AbstractSpaceMap<CachedSpace> spaceMap) {
super(data, spaceMap);
}
@Override
public RequireHasKnownTraceCachedWriteBytesPcodeExecutorStatePiece fork() {
return new RequireHasKnownTraceCachedWriteBytesPcodeExecutorStatePiece(data,
spaceMap.fork());
}
@Override
protected AddressSetView getKnown(PcodeTraceDataAccess backing, AddressSetView set) {
return backing.intersectViewKnown(set, true);
}
@Override
protected AccessPcodeExecutionException excFor(AddressSetView unknown) {
throw new AccessPcodeExecutionException("Memory at " + unknown + " has never been known.");
}
}

View File

@ -1,44 +0,0 @@
/* ###
* IP: GHIDRA
*
* 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.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.pcode.exec.trace;
import ghidra.pcode.exec.trace.data.PcodeTraceDataAccess;
/**
* A state composing a single {@link RequireIsKnownTraceCachedWriteBytesPcodeExecutorState}
*/
public class RequireIsKnownTraceCachedWriteBytesPcodeExecutorState
extends DefaultTracePcodeExecutorState<byte[]> {
/**
* Create the state
*
* @param data the trace-data access shim
*/
public RequireIsKnownTraceCachedWriteBytesPcodeExecutorState(PcodeTraceDataAccess data) {
super(new RequireIsKnownTraceCachedWriteBytesPcodeExecutorStatePiece(data));
}
protected RequireIsKnownTraceCachedWriteBytesPcodeExecutorState(
TracePcodeExecutorStatePiece<byte[], byte[]> piece) {
super(piece);
}
@Override
public RequireIsKnownTraceCachedWriteBytesPcodeExecutorState fork() {
return new RequireIsKnownTraceCachedWriteBytesPcodeExecutorState(piece.fork());
}
}

View File

@ -1,80 +0,0 @@
/* ###
* IP: GHIDRA
*
* 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.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.pcode.exec.trace;
import ghidra.pcode.exec.AccessPcodeExecutionException;
import ghidra.pcode.exec.trace.data.PcodeTraceDataAccess;
import ghidra.program.model.address.*;
import ghidra.trace.model.memory.TraceMemorySpace;
/**
* A space which requires reads to be completely {@link TraceMemorySpace#KNOWN} memory.
*
* <p>
* If a read can be partially completed, then it will proceed up to but not including the first
* non-known address. If the start address is non-known, the emulator will be interrupted.
*/
public class RequireIsKnownTraceCachedWriteBytesPcodeExecutorStatePiece
extends AbstractCheckedTraceCachedWriteBytesPcodeExecutorStatePiece {
/**
* Construct a piece
*
* @param data the trace-data access shim
*/
public RequireIsKnownTraceCachedWriteBytesPcodeExecutorStatePiece(PcodeTraceDataAccess data) {
super(data);
}
protected RequireIsKnownTraceCachedWriteBytesPcodeExecutorStatePiece(PcodeTraceDataAccess data,
AbstractSpaceMap<CachedSpace> spaceMap) {
super(data, spaceMap);
}
@Override
public RequireIsKnownTraceCachedWriteBytesPcodeExecutorStatePiece fork() {
return new RequireIsKnownTraceCachedWriteBytesPcodeExecutorStatePiece(data,
spaceMap.fork());
}
protected AddressSetView getKnown(PcodeTraceDataAccess backing, AddressSetView set) {
return backing.intersectViewKnown(set, false);
}
protected AccessPcodeExecutionException excFor(AddressSetView unknown) {
return new AccessPcodeExecutionException("Memory at " + unknown + " is unknown.");
}
@Override
protected int checkUninitialized(PcodeTraceDataAccess backing, Address start, int size,
AddressSet uninitialized) {
if (backing == null) {
if (!uninitialized.contains(start)) {
return (int) uninitialized.getMinAddress().subtract(start);
}
throw excFor(uninitialized);
}
// TODO: Could find first instead?
AddressSetView unknown = uninitialized.subtract(getKnown(backing, uninitialized));
if (unknown.isEmpty()) {
return size;
}
if (!unknown.contains(start)) {
return (int) unknown.getMinAddress().subtract(start);
}
throw excFor(unknown);
}
}

View File

@ -34,7 +34,6 @@ import ghidra.dbg.target.schema.XmlSchemaContext;
import ghidra.pcode.emu.PcodeThread;
import ghidra.pcode.exec.*;
import ghidra.pcode.exec.PcodeExecutorStatePiece.Reason;
import ghidra.pcode.exec.trace.data.PcodeTraceDataAccess;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressRangeImpl;
import ghidra.program.model.lang.*;
@ -682,120 +681,6 @@ public class BytesTracePcodeEmulatorTest extends AbstractTracePcodeEmulatorTest
}
}
@Test(expected = AccessPcodeExecutionException.class)
public void testCheckedMOV_err() throws Throwable {
try (ToyDBTraceBuilder tb = new ToyDBTraceBuilder("Test", "x86:LE:64:default")) {
TraceThread thread = initTrace(tb, """
RIP = 0x00400000;
""",
List.of(
"MOV RCX,RAX"));
BytesTracePcodeEmulator emu = new BytesTracePcodeEmulator(tb.host, 0) {
@Override
protected TracePcodeExecutorState<byte[]> newState(PcodeTraceDataAccess data) {
return new RequireIsKnownTraceCachedWriteBytesPcodeExecutorState(data);
}
};
PcodeThread<byte[]> emuThread = emu.newThread(thread.getPath());
emuThread.stepInstruction();
}
}
@Test
public void testCheckedMOV_known() throws Throwable {
try (ToyDBTraceBuilder tb = new ToyDBTraceBuilder("Test", "x86:LE:64:default")) {
// Make RAX known in the trace
TraceThread thread = initTrace(tb, """
RIP = 0x00400000;
RAX = 0x1234;
""",
List.of(
"MOV RCX,RAX"));
BytesTracePcodeEmulator emu = new BytesTracePcodeEmulator(tb.host, 0) {
@Override
protected TracePcodeExecutorState<byte[]> newState(PcodeTraceDataAccess data) {
return new RequireIsKnownTraceCachedWriteBytesPcodeExecutorState(data);
}
};
PcodeThread<byte[]> emuThread = emu.newThread(thread.getPath());
emuThread.stepInstruction();
// No assertions. It should simply not throw an exception.
}
}
@Test(expected = AccessPcodeExecutionException.class)
public void testCheckedMOV_knownPast_err() throws Throwable {
try (ToyDBTraceBuilder tb = new ToyDBTraceBuilder("Test", "x86:LE:64:default")) {
// Make RAX known in the trace
TraceThread thread = initTrace(tb, """
RIP = 0x00400000;
RAX = 0x1234;
""",
List.of(
"MOV RCX,RAX"));
// Start emulator one snap later
BytesTracePcodeEmulator emu = new BytesTracePcodeEmulator(tb.host, 1) {
@Override
protected TracePcodeExecutorState<byte[]> newState(PcodeTraceDataAccess data) {
return new RequireIsKnownTraceCachedWriteBytesPcodeExecutorState(data);
}
};
PcodeThread<byte[]> emuThread = emu.newThread(thread.getPath());
emuThread.stepInstruction();
// No assertions. It should throw an exception.
}
}
@Test
public void testCheckedMOV_knownPast_has() throws Throwable {
try (ToyDBTraceBuilder tb = new ToyDBTraceBuilder("Test", "x86:LE:64:default")) {
// Make RAX known in the trace
TraceThread thread = initTrace(tb, """
RIP = 0x00400000;
RAX = 0x1234;
""",
List.of(
"MOV RCX,RAX"));
// Start emulator one snap later, but with "has-known" checks
BytesTracePcodeEmulator emu = new BytesTracePcodeEmulator(tb.host, 1) {
@Override
protected TracePcodeExecutorState<byte[]> newState(PcodeTraceDataAccess data) {
return new RequireHasKnownTraceCachedWriteBytesPcodeExecutorState(data);
}
};
PcodeThread<byte[]> emuThread = emu.newThread(thread.getPath());
emuThread.stepInstruction();
// No assertions. It should simply not throw an exception.
}
}
@Test
public void testCheckedMOV_initialized() throws Throwable {
try (ToyDBTraceBuilder tb = new ToyDBTraceBuilder("Test", "x86:LE:64:default")) {
TraceThread thread = initTrace(tb, """
RIP = 0x00400000;
""",
List.of(
"MOV RAX,0", // Have the program initialize it
"MOV RCX,RAX"));
BytesTracePcodeEmulator emu = new BytesTracePcodeEmulator(tb.host, 0) {
@Override
protected TracePcodeExecutorState<byte[]> newState(PcodeTraceDataAccess data) {
return new RequireIsKnownTraceCachedWriteBytesPcodeExecutorState(data);
}
};
PcodeThread<byte[]> emuThread = emu.newThread(thread.getPath());
emuThread.stepInstruction();
emuThread.stepInstruction();
// No assertions. It should simply not throw an exception.
}
}
@Test
public void testDEC_MOV_compat32() throws Throwable {
try (ToyDBTraceBuilder tb = new ToyDBTraceBuilder("Test", "x86:LE:64:default")) {