mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-11-25 21:51:47 +00:00
Merge remote-tracking branch 'origin/GP-3280_Dan_torchUnneededStateImpls'
This commit is contained in:
commit
66d494c603
@ -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());
|
||||
}
|
||||
}
|
@ -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.");
|
||||
}
|
||||
}
|
@ -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());
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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")) {
|
||||
|
Loading…
Reference in New Issue
Block a user