mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 02:39:44 +02:00
Merge remote-tracking branch 'origin/GP-2642_Dan_compatEmulatorHelper--SQUASHED'
This commit is contained in:
commit
254e749f95
25 changed files with 1815 additions and 741 deletions
|
@ -1,6 +1,5 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -31,7 +30,7 @@ import ghidra.program.model.address.Address;
|
|||
///
|
||||
/// depending on the type of breakpoint they currently want to invoke
|
||||
|
||||
public abstract class BreakTable {
|
||||
public interface BreakTable {
|
||||
|
||||
/// \brief Associate a particular emulator with breakpoints in this table
|
||||
///
|
||||
|
|
|
@ -29,7 +29,7 @@ import ghidra.program.model.address.Address;
|
|||
///
|
||||
/// Breakpoints are stored in map containers, and the core BreakTable methods
|
||||
/// are implemented to search in these containers
|
||||
public class BreakTableCallBack extends BreakTable {
|
||||
public class BreakTableCallBack implements BreakTable {
|
||||
|
||||
public static final String DEFAULT_NAME = "*";
|
||||
|
||||
|
|
|
@ -0,0 +1,269 @@
|
|||
/* ###
|
||||
* 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.memstate;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
import ghidra.pcode.utils.Utils;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressSpace;
|
||||
import ghidra.program.model.lang.Language;
|
||||
import ghidra.program.model.lang.Register;
|
||||
import ghidra.program.model.pcode.Varnode;
|
||||
|
||||
public abstract class AbstractMemoryState implements MemoryState {
|
||||
final Language language;
|
||||
|
||||
public AbstractMemoryState(Language language) {
|
||||
this.language = language;
|
||||
}
|
||||
|
||||
/**
|
||||
* A convenience method for setting a value directly on a varnode rather than breaking out the
|
||||
* components
|
||||
*
|
||||
* @param vn the varnode location to be written
|
||||
* @param cval the value to write into the varnode location
|
||||
*/
|
||||
@Override
|
||||
public final void setValue(Varnode vn, long cval) {
|
||||
Address addr = vn.getAddress();
|
||||
setValue(addr.getAddressSpace(), addr.getOffset(), vn.getSize(), cval);
|
||||
}
|
||||
|
||||
/**
|
||||
* A convenience method for setting a value directly on a register rather than breaking out the
|
||||
* components
|
||||
*
|
||||
* @param reg the register location to be written
|
||||
* @param cval the value to write into the register location
|
||||
*/
|
||||
@Override
|
||||
public final void setValue(Register reg, long cval) {
|
||||
Address addr = reg.getAddress();
|
||||
setValue(addr.getAddressSpace(), addr.getOffset(), reg.getMinimumByteSize(), cval);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a convenience method for setting registers by name. Any register name known to the
|
||||
* language can be used as a write location. The associated address space, offset, and size is
|
||||
* looked up and automatically passed to the main setValue routine.
|
||||
*
|
||||
* @param nm is the name of the register
|
||||
* @param cval is the value to write to the register
|
||||
*/
|
||||
@Override
|
||||
public final void setValue(String nm, long cval) {
|
||||
// Set a "register" value
|
||||
setValue(language.getRegister(nm), cval);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the main interface for writing values to the MemoryState. If there is no registered
|
||||
* MemoryBank for the desired address space, or if there is some other error, an exception is
|
||||
* thrown.
|
||||
*
|
||||
* @param spc is the address space to write to
|
||||
* @param off is the offset where the value should be written
|
||||
* @param size is the number of bytes to be written
|
||||
* @param cval is the value to be written
|
||||
*/
|
||||
@Override
|
||||
public final void setValue(AddressSpace spc, long off, int size, long cval) {
|
||||
setChunk(Utils.longToBytes(cval, size, language.isBigEndian()), spc, off, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* A convenience method for reading a value directly from a varnode rather than querying for the
|
||||
* offset and space
|
||||
*
|
||||
* @param vn the varnode location to be read
|
||||
* @return the value read from the varnode location
|
||||
*/
|
||||
@Override
|
||||
public final long getValue(Varnode vn) {
|
||||
Address addr = vn.getAddress();
|
||||
return getValue(addr.getAddressSpace(), addr.getOffset(), vn.getSize());
|
||||
}
|
||||
|
||||
/**
|
||||
* A convenience method for reading a value directly from a register rather than querying for
|
||||
* the offset and space
|
||||
*
|
||||
* @param reg the register location to be read
|
||||
* @return the value read from the register location
|
||||
*/
|
||||
@Override
|
||||
public final long getValue(Register reg) {
|
||||
Address addr = reg.getAddress();
|
||||
return getValue(addr.getAddressSpace(), addr.getOffset(), reg.getMinimumByteSize());
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a convenience method for reading registers by name. any register name known to the
|
||||
* language can be used as a read location. The associated address space, offset, and size is
|
||||
* looked up and automatically passed to the main getValue routine.
|
||||
*
|
||||
* @param nm is the name of the register
|
||||
* @return the value associated with that register
|
||||
*/
|
||||
@Override
|
||||
public final long getValue(String nm) {
|
||||
// Get a "register" value
|
||||
return getValue(language.getRegister(nm));
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the main interface for reading values from the MemoryState. If there is no registered
|
||||
* MemoryBank for the desired address space, or if there is some other error, an exception is
|
||||
* thrown.
|
||||
*
|
||||
* @param spc is the address space being queried
|
||||
* @param off is the offset of the value being queried
|
||||
* @param size is the number of bytes to query
|
||||
* @return the queried value
|
||||
*/
|
||||
@Override
|
||||
public final long getValue(AddressSpace spc, long off, int size) {
|
||||
if (spc.isConstantSpace()) {
|
||||
return off;
|
||||
}
|
||||
byte[] bytes = new byte[size];
|
||||
getChunk(bytes, spc, off, size, false);
|
||||
return Utils.bytesToLong(bytes, size, language.isBigEndian());
|
||||
}
|
||||
|
||||
/**
|
||||
* A convenience method for setting a value directly on a varnode rather than breaking out the
|
||||
* components
|
||||
*
|
||||
* @param vn the varnode location to be written
|
||||
* @param cval the value to write into the varnode location
|
||||
*/
|
||||
@Override
|
||||
public final void setValue(Varnode vn, BigInteger cval) {
|
||||
Address addr = vn.getAddress();
|
||||
setValue(addr.getAddressSpace(), addr.getOffset(), vn.getSize(), cval);
|
||||
}
|
||||
|
||||
/**
|
||||
* A convenience method for setting a value directly on a register rather than breaking out the
|
||||
* components
|
||||
*
|
||||
* @param reg the register location to be written
|
||||
* @param cval the value to write into the register location
|
||||
*/
|
||||
@Override
|
||||
public final void setValue(Register reg, BigInteger cval) {
|
||||
Address addr = reg.getAddress();
|
||||
setValue(addr.getAddressSpace(), addr.getOffset(), reg.getMinimumByteSize(), cval);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a convenience method for setting registers by name. Any register name known to the
|
||||
* language can be used as a write location. The associated address space, offset, and size is
|
||||
* looked up and automatically passed to the main setValue routine.
|
||||
*
|
||||
* @param nm is the name of the register
|
||||
* @param cval is the value to write to the register
|
||||
*/
|
||||
@Override
|
||||
public final void setValue(String nm, BigInteger cval) {
|
||||
// Set a "register" value
|
||||
setValue(language.getRegister(nm), cval);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the main interface for writing values to the MemoryState. If there is no registered
|
||||
* MemoryBank for the desired address space, or if there is some other error, an exception is
|
||||
* thrown.
|
||||
*
|
||||
* @param spc is the address space to write to
|
||||
* @param off is the offset where the value should be written
|
||||
* @param size is the number of bytes to be written
|
||||
* @param cval is the value to be written
|
||||
*/
|
||||
@Override
|
||||
public final void setValue(AddressSpace spc, long off, int size, BigInteger cval) {
|
||||
setChunk(Utils.bigIntegerToBytes(cval, size, language.isBigEndian()), spc, off, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* A convenience method for reading a value directly from a varnode rather than querying for the
|
||||
* offset and space
|
||||
*
|
||||
* @param vn the varnode location to be read
|
||||
* @param signed true if signed value should be returned, false for unsigned value
|
||||
* @return the unsigned value read from the varnode location
|
||||
*/
|
||||
@Override
|
||||
public final BigInteger getBigInteger(Varnode vn, boolean signed) {
|
||||
Address addr = vn.getAddress();
|
||||
return getBigInteger(addr.getAddressSpace(), addr.getOffset(), vn.getSize(), signed);
|
||||
}
|
||||
|
||||
/**
|
||||
* A convenience method for reading a value directly from a register rather than querying for
|
||||
* the offset and space
|
||||
*
|
||||
* @param reg the register location to be read
|
||||
* @return the unsigned value read from the register location
|
||||
*/
|
||||
@Override
|
||||
public final BigInteger getBigInteger(Register reg) {
|
||||
Address addr = reg.getAddress();
|
||||
return getBigInteger(addr.getAddressSpace(), addr.getOffset(), reg.getMinimumByteSize(),
|
||||
false);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a convenience method for reading registers by name. any register name known to the
|
||||
* language can be used as a read location. The associated address space, offset, and size is
|
||||
* looked up and automatically passed to the main getValue routine.
|
||||
*
|
||||
* @param nm is the name of the register
|
||||
* @return the unsigned value associated with that register
|
||||
*/
|
||||
@Override
|
||||
public final BigInteger getBigInteger(String nm) {
|
||||
// Get a "register" value
|
||||
return getBigInteger(language.getRegister(nm));
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the main interface for reading values from the MemoryState. If there is no registered
|
||||
* MemoryBank for the desired address space, or if there is some other error, an exception is
|
||||
* thrown.
|
||||
*
|
||||
* @param spc is the address space being queried
|
||||
* @param off is the offset of the value being queried
|
||||
* @param size is the number of bytes to query
|
||||
* @param signed true if signed value should be returned, false for unsigned value
|
||||
* @return the queried unsigned value
|
||||
*/
|
||||
@Override
|
||||
public final BigInteger getBigInteger(AddressSpace spc, long off, int size, boolean signed) {
|
||||
if (spc.isConstantSpace()) {
|
||||
if (!signed && off < 0) {
|
||||
return new BigInteger(1, Utils.longToBytes(off, 8, true));
|
||||
}
|
||||
return BigInteger.valueOf(off);
|
||||
}
|
||||
byte[] bytes = new byte[size];
|
||||
getChunk(bytes, spc, off, size, false);
|
||||
return Utils.bytesToBigInteger(bytes, size, language.isBigEndian(), signed);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,148 @@
|
|||
/* ###
|
||||
* 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.memstate;
|
||||
|
||||
import generic.stl.VectorSTL;
|
||||
import ghidra.pcode.error.LowlevelError;
|
||||
import ghidra.pcode.utils.Utils;
|
||||
import ghidra.program.model.address.AddressSpace;
|
||||
import ghidra.program.model.lang.Language;
|
||||
|
||||
/**
|
||||
* All storage/state for a pcode emulator machine
|
||||
*
|
||||
* Every piece of information in a pcode emulator machine is representable as a triple
|
||||
* (AddressSpace,offset,size). This class allows getting and setting of all state information of
|
||||
* this form.
|
||||
*/
|
||||
public class DefaultMemoryState extends AbstractMemoryState {
|
||||
|
||||
VectorSTL<MemoryBank> memspace = new VectorSTL<MemoryBank>();
|
||||
|
||||
/**
|
||||
* MemoryState constructor for a specified processor language
|
||||
*
|
||||
* @param language
|
||||
*/
|
||||
public DefaultMemoryState(Language language) {
|
||||
super(language);
|
||||
}
|
||||
|
||||
/**
|
||||
* MemoryBanks associated with specific address spaces must be registers with this MemoryState
|
||||
* via this method. Each address space that will be used during emulation must be registered
|
||||
* separately. The MemoryState object does not assume responsibility for freeing the MemoryBank.
|
||||
*
|
||||
* @param bank is a pointer to the MemoryBank to be registered
|
||||
*/
|
||||
@Override
|
||||
public final void setMemoryBank(MemoryBank bank) {
|
||||
AddressSpace spc = bank.getSpace();
|
||||
int index = spc.getUnique();
|
||||
|
||||
while (index >= memspace.size())
|
||||
memspace.push_back(null);
|
||||
|
||||
memspace.set(index, bank);
|
||||
}
|
||||
|
||||
/**
|
||||
* Any MemoryBank that has been registered with this MemoryState can be retrieved via this
|
||||
* method if the MemoryBank's associated address space is known.
|
||||
*
|
||||
* @param spc is the address space of the desired MemoryBank
|
||||
* @return the MemoryBank or null if no bank is associated with spc.
|
||||
*/
|
||||
@Override
|
||||
public final MemoryBank getMemoryBank(AddressSpace spc) {
|
||||
int index = spc.getUnique();
|
||||
if (index >= memspace.size())
|
||||
return null;
|
||||
return memspace.get(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the main interface for reading a range of bytes from the MemorySate. The MemoryBank
|
||||
* associated with the address space of the query is looked up and the request is forwarded to
|
||||
* the getChunk method on the MemoryBank. If there is no registered MemoryBank or some other
|
||||
* error, an exception is thrown. All getLongValue methods utilize this method to read the bytes
|
||||
* from the appropriate memory bank.
|
||||
*
|
||||
* @param res the result buffer for storing retrieved bytes
|
||||
* @param spc the desired address space
|
||||
* @param off the starting offset of the byte range being read
|
||||
* @param size the number of bytes being read
|
||||
* @param stopOnUnintialized if true a partial read is permitted and returned size may be
|
||||
* smaller than size requested
|
||||
* @return number of bytes actually read
|
||||
* @throws LowlevelError if spc has not been mapped within this MemoryState or memory fault
|
||||
* handler generated error
|
||||
*/
|
||||
@Override
|
||||
public int getChunk(byte[] res, AddressSpace spc, long off, int size,
|
||||
boolean stopOnUnintialized) {
|
||||
if (spc.isConstantSpace()) {
|
||||
System.arraycopy(Utils.longToBytes(off, size, language.isBigEndian()), 0, res, 0, size);
|
||||
return size;
|
||||
}
|
||||
MemoryBank mspace = getMemoryBank(spc);
|
||||
if (mspace == null)
|
||||
throw new LowlevelError("Getting chunk from unmapped memory space: " + spc.getName());
|
||||
return mspace.getChunk(off, size, res, stopOnUnintialized);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the main interface for setting values for a range of bytes in the MemoryState. The
|
||||
* MemoryBank associated with the desired address space is looked up and the write is forwarded
|
||||
* to the setChunk method on the MemoryBank. If there is no registered MemoryBank or some other
|
||||
* error, an exception is throw. All setValue methods utilize this method to read the bytes from
|
||||
* the appropriate memory bank.
|
||||
*
|
||||
* @param val the byte values to be written into the MemoryState
|
||||
* @param spc the address space being written
|
||||
* @param off the starting offset of the range being written
|
||||
* @param size the number of bytes to write
|
||||
* @throws LowlevelError if spc has not been mapped within this MemoryState
|
||||
*/
|
||||
@Override
|
||||
public void setChunk(byte[] val, AddressSpace spc, long off, int size) {
|
||||
MemoryBank mspace = getMemoryBank(spc);
|
||||
if (mspace == null)
|
||||
throw new LowlevelError("Setting chunk of unmapped memory space: " + spc.getName());
|
||||
mspace.setChunk(off, size, val);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the main interface for setting the initialization status for a range of bytes in the
|
||||
* MemoryState. The MemoryBank associated with the desired address space is looked up and the
|
||||
* write is forwarded to the setInitialized method on the MemoryBank. If there is no registered
|
||||
* MemoryBank or some other error, an exception is throw. All setValue methods utilize this
|
||||
* method to read the bytes from the appropriate memory bank.
|
||||
*
|
||||
* @param initialized indicates if range should be marked as initialized or not
|
||||
* @param spc the address space being written
|
||||
* @param off the starting offset of the range being written
|
||||
* @param size the number of bytes to write
|
||||
*/
|
||||
@Override
|
||||
public void setInitialized(boolean initialized, AddressSpace spc, long off, int size) {
|
||||
MemoryBank mspace = getMemoryBank(spc);
|
||||
if (mspace == null)
|
||||
throw new LowlevelError("Setting intialization status of unmapped memory space: " +
|
||||
spc.getName());
|
||||
mspace.setInitialized(off, size, initialized);
|
||||
}
|
||||
}
|
|
@ -16,47 +16,13 @@
|
|||
package ghidra.pcode.memstate;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import generic.stl.VectorSTL;
|
||||
import ghidra.pcode.error.LowlevelError;
|
||||
import ghidra.pcode.utils.Utils;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressSpace;
|
||||
import ghidra.program.model.lang.Language;
|
||||
import ghidra.program.model.lang.Register;
|
||||
import ghidra.program.model.pcode.Varnode;
|
||||
|
||||
/**
|
||||
* All storage/state for a pcode emulator machine
|
||||
*
|
||||
* Every piece of information in a pcode emulator machine is representable as a triple
|
||||
* (AddressSpace,offset,size). This class allows getting and setting
|
||||
* of all state information of this form.
|
||||
*/
|
||||
public class MemoryState {
|
||||
|
||||
Language language;
|
||||
VectorSTL<MemoryBank> memspace = new VectorSTL<MemoryBank>();
|
||||
Map<Register, Varnode> regVarnodeCache = new HashMap<Register, Varnode>();
|
||||
|
||||
/**
|
||||
* MemoryState constructor for a specified processor language
|
||||
* @param language
|
||||
*/
|
||||
public MemoryState(Language language) {
|
||||
this.language = language;
|
||||
}
|
||||
|
||||
private Varnode getVarnode(Register reg) {
|
||||
Varnode varnode = regVarnodeCache.get(reg);
|
||||
if (varnode == null) {
|
||||
varnode = new Varnode(reg.getAddress(), reg.getMinimumByteSize());
|
||||
regVarnodeCache.put(reg, varnode);
|
||||
}
|
||||
return varnode;
|
||||
}
|
||||
public interface MemoryState {
|
||||
|
||||
/**
|
||||
* MemoryBanks associated with specific address spaces must be registers with this MemoryState
|
||||
|
@ -64,15 +30,7 @@ public class MemoryState {
|
|||
* separately. The MemoryState object does not assume responsibility for freeing the MemoryBank.
|
||||
* @param bank is a pointer to the MemoryBank to be registered
|
||||
*/
|
||||
public final void setMemoryBank(MemoryBank bank) {
|
||||
AddressSpace spc = bank.getSpace();
|
||||
int index = spc.getUnique();
|
||||
|
||||
while (index >= memspace.size())
|
||||
memspace.push_back(null);
|
||||
|
||||
memspace.set(index, bank);
|
||||
}
|
||||
void setMemoryBank(MemoryBank bank);
|
||||
|
||||
/**
|
||||
* Any MemoryBank that has been registered with this MemoryState can be retrieved via this
|
||||
|
@ -80,12 +38,7 @@ public class MemoryState {
|
|||
* @param spc is the address space of the desired MemoryBank
|
||||
* @return the MemoryBank or null if no bank is associated with spc.
|
||||
*/
|
||||
public final MemoryBank getMemoryBank(AddressSpace spc) {
|
||||
int index = spc.getUnique();
|
||||
if (index >= memspace.size())
|
||||
return null;
|
||||
return memspace.get(index);
|
||||
}
|
||||
MemoryBank getMemoryBank(AddressSpace spc);
|
||||
|
||||
/**
|
||||
* A convenience method for setting a value directly on a varnode rather than
|
||||
|
@ -93,10 +46,7 @@ public class MemoryState {
|
|||
* @param vn the varnode location to be written
|
||||
* @param cval the value to write into the varnode location
|
||||
*/
|
||||
public final void setValue(Varnode vn, long cval) {
|
||||
Address addr = vn.getAddress();
|
||||
setValue(addr.getAddressSpace(), addr.getOffset(), vn.getSize(), cval);
|
||||
}
|
||||
void setValue(Varnode vn, long cval);
|
||||
|
||||
/**
|
||||
* A convenience method for setting a value directly on a register rather than
|
||||
|
@ -104,10 +54,7 @@ public class MemoryState {
|
|||
* @param reg the register location to be written
|
||||
* @param cval the value to write into the register location
|
||||
*/
|
||||
public final void setValue(Register reg, long cval) {
|
||||
Address addr = reg.getAddress();
|
||||
setValue(addr.getAddressSpace(), addr.getOffset(), reg.getMinimumByteSize(), cval);
|
||||
}
|
||||
void setValue(Register reg, long cval);
|
||||
|
||||
/**
|
||||
* This is a convenience method for setting registers by name.
|
||||
|
@ -117,12 +64,7 @@ public class MemoryState {
|
|||
* @param nm is the name of the register
|
||||
* @param cval is the value to write to the register
|
||||
*/
|
||||
public final void setValue(String nm, long cval) {
|
||||
// Set a "register" value
|
||||
Varnode vdata = getVarnode(language.getRegister(nm));
|
||||
Address addr = vdata.getAddress();
|
||||
setValue(addr.getAddressSpace(), addr.getOffset(), vdata.getSize(), cval);
|
||||
}
|
||||
void setValue(String nm, long cval);
|
||||
|
||||
/**
|
||||
* This is the main interface for writing values to the MemoryState.
|
||||
|
@ -133,9 +75,7 @@ public class MemoryState {
|
|||
* @param size is the number of bytes to be written
|
||||
* @param cval is the value to be written
|
||||
*/
|
||||
public final void setValue(AddressSpace spc, long off, int size, long cval) {
|
||||
setChunk(Utils.longToBytes(cval, size, language.isBigEndian()), spc, off, size);
|
||||
}
|
||||
void setValue(AddressSpace spc, long off, int size, long cval);
|
||||
|
||||
/**
|
||||
* A convenience method for reading a value directly from a varnode rather
|
||||
|
@ -143,10 +83,7 @@ public class MemoryState {
|
|||
* @param vn the varnode location to be read
|
||||
* @return the value read from the varnode location
|
||||
*/
|
||||
public final long getValue(Varnode vn) {
|
||||
Address addr = vn.getAddress();
|
||||
return getValue(addr.getAddressSpace(), addr.getOffset(), vn.getSize());
|
||||
}
|
||||
long getValue(Varnode vn);
|
||||
|
||||
/**
|
||||
* A convenience method for reading a value directly from a register rather
|
||||
|
@ -154,10 +91,7 @@ public class MemoryState {
|
|||
* @param reg the register location to be read
|
||||
* @return the value read from the register location
|
||||
*/
|
||||
public final long getValue(Register reg) {
|
||||
Address addr = reg.getAddress();
|
||||
return getValue(addr.getAddressSpace(), addr.getOffset(), reg.getMinimumByteSize());
|
||||
}
|
||||
long getValue(Register reg);
|
||||
|
||||
/**
|
||||
* This is a convenience method for reading registers by name.
|
||||
|
@ -167,12 +101,7 @@ public class MemoryState {
|
|||
* @param nm is the name of the register
|
||||
* @return the value associated with that register
|
||||
*/
|
||||
public final long getValue(String nm) {
|
||||
// Get a "register" value
|
||||
Varnode vdata = getVarnode(language.getRegister(nm));
|
||||
Address addr = vdata.getAddress();
|
||||
return getValue(addr.getAddressSpace(), addr.getOffset(), vdata.getSize());
|
||||
}
|
||||
long getValue(String nm);
|
||||
|
||||
/**
|
||||
* This is the main interface for reading values from the MemoryState.
|
||||
|
@ -183,14 +112,7 @@ public class MemoryState {
|
|||
* @param size is the number of bytes to query
|
||||
* @return the queried value
|
||||
*/
|
||||
public final long getValue(AddressSpace spc, long off, int size) {
|
||||
if (spc.isConstantSpace()) {
|
||||
return off;
|
||||
}
|
||||
byte[] bytes = new byte[size];
|
||||
getChunk(bytes, spc, off, size, false);
|
||||
return Utils.bytesToLong(bytes, size, language.isBigEndian());
|
||||
}
|
||||
long getValue(AddressSpace spc, long off, int size);
|
||||
|
||||
/**
|
||||
* A convenience method for setting a value directly on a varnode rather than
|
||||
|
@ -198,10 +120,7 @@ public class MemoryState {
|
|||
* @param vn the varnode location to be written
|
||||
* @param cval the value to write into the varnode location
|
||||
*/
|
||||
public final void setValue(Varnode vn, BigInteger cval) {
|
||||
Address addr = vn.getAddress();
|
||||
setValue(addr.getAddressSpace(), addr.getOffset(), vn.getSize(), cval);
|
||||
}
|
||||
void setValue(Varnode vn, BigInteger cval);
|
||||
|
||||
/**
|
||||
* A convenience method for setting a value directly on a register rather than
|
||||
|
@ -209,10 +128,7 @@ public class MemoryState {
|
|||
* @param reg the register location to be written
|
||||
* @param cval the value to write into the register location
|
||||
*/
|
||||
public final void setValue(Register reg, BigInteger cval) {
|
||||
Address addr = reg.getAddress();
|
||||
setValue(addr.getAddressSpace(), addr.getOffset(), reg.getMinimumByteSize(), cval);
|
||||
}
|
||||
void setValue(Register reg, BigInteger cval);
|
||||
|
||||
/**
|
||||
* This is a convenience method for setting registers by name.
|
||||
|
@ -222,12 +138,7 @@ public class MemoryState {
|
|||
* @param nm is the name of the register
|
||||
* @param cval is the value to write to the register
|
||||
*/
|
||||
public final void setValue(String nm, BigInteger cval) {
|
||||
// Set a "register" value
|
||||
Varnode vdata = getVarnode(language.getRegister(nm));
|
||||
Address addr = vdata.getAddress();
|
||||
setValue(addr.getAddressSpace(), addr.getOffset(), vdata.getSize(), cval);
|
||||
}
|
||||
void setValue(String nm, BigInteger cval);
|
||||
|
||||
/**
|
||||
* This is the main interface for writing values to the MemoryState.
|
||||
|
@ -238,9 +149,7 @@ public class MemoryState {
|
|||
* @param size is the number of bytes to be written
|
||||
* @param cval is the value to be written
|
||||
*/
|
||||
public final void setValue(AddressSpace spc, long off, int size, BigInteger cval) {
|
||||
setChunk(Utils.bigIntegerToBytes(cval, size, language.isBigEndian()), spc, off, size);
|
||||
}
|
||||
void setValue(AddressSpace spc, long off, int size, BigInteger cval);
|
||||
|
||||
/**
|
||||
* A convenience method for reading a value directly from a varnode rather
|
||||
|
@ -249,10 +158,7 @@ public class MemoryState {
|
|||
* @param signed true if signed value should be returned, false for unsigned value
|
||||
* @return the unsigned value read from the varnode location
|
||||
*/
|
||||
public final BigInteger getBigInteger(Varnode vn, boolean signed) {
|
||||
Address addr = vn.getAddress();
|
||||
return getBigInteger(addr.getAddressSpace(), addr.getOffset(), vn.getSize(), signed);
|
||||
}
|
||||
BigInteger getBigInteger(Varnode vn, boolean signed);
|
||||
|
||||
/**
|
||||
* A convenience method for reading a value directly from a register rather
|
||||
|
@ -260,11 +166,7 @@ public class MemoryState {
|
|||
* @param reg the register location to be read
|
||||
* @return the unsigned value read from the register location
|
||||
*/
|
||||
public final BigInteger getBigInteger(Register reg) {
|
||||
Address addr = reg.getAddress();
|
||||
return getBigInteger(addr.getAddressSpace(), addr.getOffset(), reg.getMinimumByteSize(),
|
||||
false);
|
||||
}
|
||||
BigInteger getBigInteger(Register reg);
|
||||
|
||||
/**
|
||||
* This is a convenience method for reading registers by name.
|
||||
|
@ -274,12 +176,7 @@ public class MemoryState {
|
|||
* @param nm is the name of the register
|
||||
* @return the unsigned value associated with that register
|
||||
*/
|
||||
public final BigInteger getBigInteger(String nm) {
|
||||
// Get a "register" value
|
||||
Varnode vdata = getVarnode(language.getRegister(nm));
|
||||
Address addr = vdata.getAddress();
|
||||
return getBigInteger(addr.getAddressSpace(), addr.getOffset(), vdata.getSize(), false);
|
||||
}
|
||||
BigInteger getBigInteger(String nm);
|
||||
|
||||
/**
|
||||
* This is the main interface for reading values from the MemoryState.
|
||||
|
@ -291,17 +188,7 @@ public class MemoryState {
|
|||
* @param signed true if signed value should be returned, false for unsigned value
|
||||
* @return the queried unsigned value
|
||||
*/
|
||||
public final BigInteger getBigInteger(AddressSpace spc, long off, int size, boolean signed) {
|
||||
if (spc.isConstantSpace()) {
|
||||
if (!signed && off < 0) {
|
||||
return new BigInteger(1, Utils.longToBytes(off, 8, true));
|
||||
}
|
||||
return BigInteger.valueOf(off);
|
||||
}
|
||||
byte[] bytes = new byte[size];
|
||||
getChunk(bytes, spc, off, size, false);
|
||||
return Utils.bytesToBigInteger(bytes, size, language.isBigEndian(), signed);
|
||||
}
|
||||
BigInteger getBigInteger(AddressSpace spc, long off, int size, boolean signed);
|
||||
|
||||
/**
|
||||
* This is the main interface for reading a range of bytes from the MemorySate.
|
||||
|
@ -320,17 +207,8 @@ public class MemoryState {
|
|||
* @throws LowlevelError if spc has not been mapped within this MemoryState or memory fault
|
||||
* handler generated error
|
||||
*/
|
||||
public int getChunk(byte[] res, AddressSpace spc, long off, int size,
|
||||
boolean stopOnUnintialized) {
|
||||
if (spc.isConstantSpace()) {
|
||||
System.arraycopy(Utils.longToBytes(off, size, language.isBigEndian()), 0, res, 0, size);
|
||||
return size;
|
||||
}
|
||||
MemoryBank mspace = getMemoryBank(spc);
|
||||
if (mspace == null)
|
||||
throw new LowlevelError("Getting chunk from unmapped memory space: " + spc.getName());
|
||||
return mspace.getChunk(off, size, res, stopOnUnintialized);
|
||||
}
|
||||
int getChunk(byte[] res, AddressSpace spc, long off, int size,
|
||||
boolean stopOnUnintialized);
|
||||
|
||||
/**
|
||||
* This is the main interface for setting values for a range of bytes in the MemoryState.
|
||||
|
@ -345,12 +223,7 @@ public class MemoryState {
|
|||
* @param size the number of bytes to write
|
||||
* @throws LowlevelError if spc has not been mapped within this MemoryState
|
||||
*/
|
||||
public void setChunk(byte[] val, AddressSpace spc, long off, int size) {
|
||||
MemoryBank mspace = getMemoryBank(spc);
|
||||
if (mspace == null)
|
||||
throw new LowlevelError("Setting chunk of unmapped memory space: " + spc.getName());
|
||||
mspace.setChunk(off, size, val);
|
||||
}
|
||||
void setChunk(byte[] val, AddressSpace spc, long off, int size);
|
||||
|
||||
/**
|
||||
* This is the main interface for setting the initialization status for a range of bytes
|
||||
|
@ -365,12 +238,6 @@ public class MemoryState {
|
|||
* @param off the starting offset of the range being written
|
||||
* @param size the number of bytes to write
|
||||
*/
|
||||
public void setInitialized(boolean initialized, AddressSpace spc, long off, int size) {
|
||||
MemoryBank mspace = getMemoryBank(spc);
|
||||
if (mspace == null)
|
||||
throw new LowlevelError("Setting intialization status of unmapped memory space: " +
|
||||
spc.getName());
|
||||
mspace.setInitialized(off, size, initialized);
|
||||
}
|
||||
void setInitialized(boolean initialized, AddressSpace spc, long off, int size);
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue