Merge remote-tracking branch

'origin/GP-751_ghizard_VarnodeContext_Needs_OverlayAddressSpace' (Closes
#2785, Closes #2787)
This commit is contained in:
ghidra1 2021-03-10 13:28:20 -05:00
commit 79fce9b032
2 changed files with 63 additions and 36 deletions

View file

@ -47,20 +47,20 @@ public class VarnodeContext implements ProcessorContext {
protected DisassemblerContextImpl spaceContext;
// holds temp memory values for computation
protected HashMap<Varnode, Varnode> memoryVals = new HashMap<Varnode, Varnode>();
protected HashMap<Varnode, Varnode> memoryVals = new HashMap<>();
// holds temp values for computation
private HashMap<Varnode, Varnode> tempVals = new HashMap<Varnode, Varnode>();
protected HashMap<Varnode, Varnode> tempUniqueVals = new HashMap<Varnode, Varnode>();
private HashMap<Varnode, Varnode> tempVals = new HashMap<>();
protected HashMap<Varnode, Varnode> tempUniqueVals = new HashMap<>();
protected boolean keepTempUniqueValues = false;
protected HashSet<Varnode> clearVals = new HashSet<Varnode>();
protected HashSet<Varnode> clearVals = new HashSet<>();
// locations where registers were last set to a constant value
protected HashMap<Varnode, Address> lastSet = new HashMap<Varnode, Address>();
protected HashMap<Varnode, Address> lastSet = new HashMap<>();
// all locations where a register was last explicitly set to a value, not just has the value
protected HashMap<Varnode, AddressSet> allLastSet = new HashMap<Varnode, AddressSet>();
protected HashMap<Varnode, AddressSet> allLastSet = new HashMap<>();
protected Program program;
protected VarnodeTranslator trans; // translator for varnodes<-->registers
@ -68,7 +68,7 @@ public class VarnodeContext implements ProcessorContext {
protected Varnode[] retVarnodes = null; // varnodes used to return values
protected Varnode stackVarnode = null; // varnode that represents the stack
protected Register stackReg = null;
private HashSet<String> validSymbolicStackNames = new HashSet<String>(); // list of stack related register names
private HashSet<String> validSymbolicStackNames = new HashSet<>(); // list of stack related register names
protected static final NotFoundException notFoundExc = new NotFoundException();
@ -88,9 +88,7 @@ public class VarnodeContext implements ProcessorContext {
this.program = program;
// make a copy, because we could be making new spaces.
// TODO: This could be a problem if some of the Pcode comes up with Overlay Address Spaces.
// TODO: This doesn't get Stack space, or other overlay spaces...
this.addrFactory = new OffsetAddressFactory(program.getLanguage().getAddressFactory());
this.addrFactory = new OffsetAddressFactory(program.getAddressFactory());
BAD_ADDRESS = addrFactory.getAddress(getAddressSpace("BAD_ADDRESS_SPACE"), 0);
@ -168,7 +166,7 @@ public class VarnodeContext implements ProcessorContext {
currentAddress = toAddr;
this.lastSet = new HashMap<Varnode, Address>(); // clear out any interim last sets... rely on allLastSet now
this.lastSet = new HashMap<>(); // clear out any interim last sets... rely on allLastSet now
offsetContext.flowStart(fromAddr, toAddr);
spaceContext.flowStart(fromAddr, toAddr);
@ -755,10 +753,10 @@ public class VarnodeContext implements ProcessorContext {
}
if (clearContext) {
if (!keepTempUniqueValues) {
tempUniqueVals = new HashMap<Varnode, Varnode>();
tempUniqueVals = new HashMap<>();
}
tempVals = new HashMap<Varnode, Varnode>();
clearVals = new HashSet<Varnode>();
tempVals = new HashMap<>();
clearVals = new HashSet<>();
}
}
@ -867,9 +865,6 @@ public class VarnodeContext implements ProcessorContext {
public Varnode getVarnode(int spaceID, long offset, int size) {
AddressSpace space = addrFactory.getAddressSpace(spaceID);
if (space == null) {
return new Varnode(null, size);
}
Address target = space.getTruncatedAddress(offset, true);
Varnode vt = new Varnode(target, size);
return vt;
@ -1242,8 +1237,7 @@ public class VarnodeContext implements ProcessorContext {
throws NotFoundException {
// degenerate case, don't need to know the value
if (val1.equals(val2)) {
return createVarnode(0, addrFactory.getConstantSpace().getSpaceID(),
val1.getSize());
return createVarnode(0, addrFactory.getConstantSpace().getSpaceID(), val1.getSize());
}
int spaceID = val1.getSpace();
long valbase = 0;
@ -1442,7 +1436,7 @@ public class VarnodeContext implements ProcessorContext {
class OffsetAddressFactory extends DefaultAddressFactory {
OffsetAddressFactory(AddressFactory baseFactory) {
super(baseFactory.getAllAddressSpaces());
super(filterSpaces(baseFactory.getAllAddressSpaces()));
}
private int getNextUniqueID() {
@ -1471,4 +1465,18 @@ class OffsetAddressFactory extends DefaultAddressFactory {
int type = AddressSpace.ID_TYPE_MASK & spaceID;
return (type == AddressSpace.TYPE_SYMBOL);
}
private static AddressSpace[] filterSpaces(AddressSpace[] allSpaces) {
List<AddressSpace> spaces = new ArrayList<>();
for (AddressSpace space : allSpaces) {
int type = space.getType();
if (type == AddressSpace.TYPE_VARIABLE || type == AddressSpace.TYPE_STACK ||
type == AddressSpace.TYPE_EXTERNAL || type == AddressSpace.TYPE_JOIN) {
continue;
}
spaces.add(space);
}
return spaces.toArray(new AddressSpace[0]);
}
}

View file

@ -18,6 +18,7 @@ package ghidra.program.model.address;
import java.util.ArrayList;
import java.util.HashMap;
import ghidra.program.model.lang.BasicCompilerSpec;
import ghidra.util.datastruct.IntObjectHashtable;
import ghidra.util.exception.DuplicateNameException;
@ -59,9 +60,9 @@ public class DefaultAddressFactory implements AddressFactory {
*/
public DefaultAddressFactory(AddressSpace[] addrSpaces, AddressSpace defaultSpace) {
memoryAddressSet = new AddressSet();
spaces = new ArrayList<AddressSpace>(addrSpaces.length);
spaceLookup = new IntObjectHashtable<AddressSpace>();
spaceNameTable = new HashMap<String, AddressSpace>();
spaces = new ArrayList<>(addrSpaces.length);
spaceLookup = new IntObjectHashtable<>();
spaceNameTable = new HashMap<>();
for (AddressSpace space : addrSpaces) {
checkReservedSpace(space);
@ -78,9 +79,6 @@ public class DefaultAddressFactory implements AddressFactory {
else if (space.getType() == AddressSpace.TYPE_UNIQUE) {
uniqueSpace = space;
}
else if (space.getType() == AddressSpace.TYPE_STACK) {
throw new IllegalArgumentException("Stack space should not be specified");
}
else if (space.getType() == AddressSpace.TYPE_REGISTER) {
if (registerSpace != null || !space.getName().equalsIgnoreCase("register")) {
// Ghidra address encoding only handles a single register space
@ -89,9 +87,6 @@ public class DefaultAddressFactory implements AddressFactory {
}
registerSpace = space;
}
else if (space.getType() == AddressSpace.TYPE_VARIABLE) {
throw new IllegalArgumentException("Variable space must be defined by language");
}
// build up an address set for all possible "real" addresses
if (space.isMemorySpace()) {
memoryAddressSet.addRange(space.getMinAddress(), space.getMaxAddress());
@ -118,17 +113,40 @@ public class DefaultAddressFactory implements AddressFactory {
}
private void checkReservedSpace(AddressSpace space) {
checkReservedVariable(space);
checkReservedJoin(space);
checkReservedExternal(space);
checkReservedStack(space);
}
private void checkReservedVariable(AddressSpace space) {
if (space.getType() == AddressSpace.TYPE_VARIABLE ||
space.getName().equalsIgnoreCase(AddressSpace.VARIABLE_SPACE.getName()) ||
space.getName().equals("join")) {
space.getName().equalsIgnoreCase(AddressSpace.VARIABLE_SPACE.getName())) {
throw new IllegalArgumentException("Variable space should not be specified");
}
}
private void checkReservedJoin(AddressSpace space) {
if (space.getType() == AddressSpace.TYPE_JOIN ||
space.getName().equals(BasicCompilerSpec.JOIN_SPACE_NAME)) {
throw new IllegalArgumentException("Join space should not be specified");
}
}
private void checkReservedExternal(AddressSpace space) {
if (space.getType() == AddressSpace.TYPE_EXTERNAL ||
space.getName().equalsIgnoreCase(AddressSpace.EXTERNAL_SPACE.getName())) {
throw new IllegalArgumentException("External space should not be specified");
}
}
private void checkReservedStack(AddressSpace space) {
if (space.getType() == AddressSpace.TYPE_STACK ||
space.getName().equalsIgnoreCase(BasicCompilerSpec.STACK_SPACE_NAME)) {
throw new IllegalArgumentException("Stack space should not be specified");
}
}
/**
* @see ghidra.program.model.address.AddressFactory#getAddress(java.lang.String)
*/
@ -141,6 +159,7 @@ public class DefaultAddressFactory implements AddressFactory {
}
}
catch (AddressFormatException e) {
// ignore
}
for (AddressSpace space : spaces) {
@ -155,6 +174,7 @@ public class DefaultAddressFactory implements AddressFactory {
}
}
catch (AddressFormatException e) {
// ignore
}
}
return null;
@ -167,8 +187,8 @@ public class DefaultAddressFactory implements AddressFactory {
@Override
public Address[] getAllAddresses(String addrString, boolean caseSensitive) {
ArrayList<Address> loadedMemoryList = new ArrayList<Address>();
ArrayList<Address> otherList = new ArrayList<Address>();
ArrayList<Address> loadedMemoryList = new ArrayList<>();
ArrayList<Address> otherList = new ArrayList<>();
for (AddressSpace space : spaces) {
// Only parse against true physical spaces first
@ -210,7 +230,6 @@ public class DefaultAddressFactory implements AddressFactory {
return defaultSpace;
}
@Override
public AddressSpace[] getAddressSpaces() {
return getPhysicalSpaces();// we avoid returning analysis spaces here