GP-0: Trace/emu test fixes re/ DEFAULT_CONTEXT

This commit is contained in:
Dan 2021-09-07 12:04:44 -04:00
parent e61571669f
commit ad135a4e80
5 changed files with 33 additions and 23 deletions

View file

@ -291,12 +291,12 @@ public class TracePcodeEmulatorTest extends AbstractGhidraHeadlessIntegrationTes
} }
/** /**
* This tests an language without a contextreg * This tests a language without a real contextreg
*/ */
@Test @Test
public void testIMM() throws Throwable { public void testIMM() throws Throwable {
try (ToyDBTraceBuilder tb = new ToyDBTraceBuilder("Test", "Toy:BE:64:default")) { try (ToyDBTraceBuilder tb = new ToyDBTraceBuilder("Test", "Toy:BE:64:default")) {
assertNull(tb.language.getContextBaseRegister()); assertEquals(Register.DEFAULT_CONTEXT, tb.language.getContextBaseRegister());
TraceThread thread = initTrace(tb, TraceThread thread = initTrace(tb,
List.of( List.of(

View file

@ -1195,8 +1195,8 @@ public class DBTraceCodeUnitTest extends AbstractGhidraHeadlessIntegrationTest
i4004 = b.addInstruction(0, b.addr(0x4004), b.language, b.buf(0xf4, 0)); i4004 = b.addInstruction(0, b.addr(0x4004), b.language, b.buf(0xf4, 0));
} }
// TODO: Test with context // TODO: Test with non-default context
assertNull(i4004.getBaseContextRegister()); assertEquals(Register.DEFAULT_CONTEXT, i4004.getBaseContextRegister());
assertEquals(b.language.getRegisters(), i4004.getRegisters()); assertEquals(b.language.getRegisters(), i4004.getRegisters());
assertEquals(r4, i4004.getRegister("r4")); assertEquals(r4, i4004.getRegister("r4"));

View file

@ -126,7 +126,7 @@ public class DefaultPcodeThread<T> implements PcodeThread<T> {
this.pc = language.getProgramCounter(); this.pc = language.getProgramCounter();
this.contextreg = language.getContextBaseRegister(); this.contextreg = language.getContextBaseRegister();
if (contextreg != null) { if (contextreg != Register.DEFAULT_CONTEXT) {
defaultContext = new ProgramContextImpl(language); defaultContext = new ProgramContextImpl(language);
language.applyContextSettings(defaultContext); language.applyContextSettings(defaultContext);
this.context = defaultContext.getDefaultDisassemblyContext(); this.context = defaultContext.getDefaultDisassemblyContext();
@ -190,7 +190,7 @@ public class DefaultPcodeThread<T> implements PcodeThread<T> {
@Override @Override
public void overrideContextWithDefault() { public void overrideContextWithDefault() {
if (contextreg != null) { if (contextreg != Register.DEFAULT_CONTEXT) {
overrideContext(defaultContext.getDefaultValue(contextreg, counter)); overrideContext(defaultContext.getDefaultValue(contextreg, counter));
} }
} }
@ -206,7 +206,7 @@ public class DefaultPcodeThread<T> implements PcodeThread<T> {
long offset = arithmetic.toConcrete(state.getVar(pc)).longValue(); long offset = arithmetic.toConcrete(state.getVar(pc)).longValue();
setCounter(language.getDefaultSpace().getAddress(offset)); setCounter(language.getDefaultSpace().getAddress(offset));
if (contextreg != null) { if (contextreg != Register.DEFAULT_CONTEXT) {
try { try {
BigInteger ctx = arithmetic.toConcrete(state.getVar(contextreg)); BigInteger ctx = arithmetic.toConcrete(state.getVar(contextreg));
assignContext(new RegisterValue(contextreg, ctx)); assignContext(new RegisterValue(contextreg, ctx));
@ -271,7 +271,7 @@ public class DefaultPcodeThread<T> implements PcodeThread<T> {
if (frame.isFallThrough()) { if (frame.isFallThrough()) {
overrideCounter(counter.addWrap(decoder.getLastLengthWithDelays())); overrideCounter(counter.addWrap(decoder.getLastLengthWithDelays()));
} }
if (contextreg != null) { if (contextreg != Register.DEFAULT_CONTEXT) {
overrideContext(instruction.getRegisterValue(contextreg)); overrideContext(instruction.getRegisterValue(contextreg));
} }
postExecuteInstruction(); postExecuteInstruction();

View file

@ -43,6 +43,9 @@ public class Register implements java.io.Serializable, Comparable<Register> {
/** Register can be used in SIMD operations **/ /** Register can be used in SIMD operations **/
public final static int TYPE_VECTOR = 128; public final static int TYPE_VECTOR = 128;
public final static Register DEFAULT_CONTEXT =
new Register("DEFAULT_CONTEXT", "DEFAULT_CONTEXT", Address.NO_ADDRESS, 4, true, 0);
private String name; private String name;
private String description; // description of the register private String description; // description of the register
private Address address; // smallest address containing bits for this register private Address address; // smallest address containing bits for this register

View file

@ -32,7 +32,7 @@ public class RegisterManager {
private Map<Address, List<Register>> registerAddressMap = private Map<Address, List<Register>> registerAddressMap =
new HashMap<Address, List<Register>>(); new HashMap<Address, List<Register>>();
/**List of vector registers, sorted first by size and then by offset**/ /** List of vector registers, sorted first by size and then by offset **/
private List<Register> sortedVectorRegisters; private List<Register> sortedVectorRegisters;
class RegisterSizeKey { class RegisterSizeKey {
@ -80,10 +80,11 @@ public class RegisterManager {
/** /**
* Construct RegisterManager * Construct RegisterManager
* @param registers all defined registers with appropriate parent-child relationships *
* properly established. * @param registers all defined registers with appropriate parent-child relationships properly
* @param registerNameMap a complete name-to-register map including all register aliases * established.
* and alternate spellings (e.g., case-variations) * @param registerNameMap a complete name-to-register map including all register aliases and
* alternate spellings (e.g., case-variations)
*/ */
RegisterManager(List<Register> registers, Map<String, Register> registerNameMap) { RegisterManager(List<Register> registers, Map<String, Register> registerNameMap) {
this.registers = Collections.unmodifiableList(registers); this.registers = Collections.unmodifiableList(registers);
@ -126,8 +127,7 @@ public class RegisterManager {
} }
// if there is no context register, force a default one // if there is no context register, force a default one
if (contextBaseRegister == null) { if (contextBaseRegister == null) {
contextBaseRegister = contextBaseRegister = Register.DEFAULT_CONTEXT;
new Register("DEFAULT_CONTEXT", "DEFAULT_CONTEXT", Address.NO_ADDRESS, 4, true, 0);
} }
// handle the register size 0 case; // handle the register size 0 case;
Collections.reverse(registerListSortedBySize); Collections.reverse(registerListSortedBySize);
@ -156,6 +156,7 @@ public class RegisterManager {
/** /**
* Get context base-register * Get context base-register
*
* @return context base register or null if one has not been defined by the language. * @return context base register or null if one has not been defined by the language.
*/ */
public Register getContextBaseRegister() { public Register getContextBaseRegister() {
@ -163,7 +164,9 @@ public class RegisterManager {
} }
/** /**
* Get unsorted unmodifiable list of all processor context registers (include base context register and children) * Get unsorted unmodifiable list of all processor context registers (include base context
* register and children)
*
* @return all processor context registers * @return all processor context registers
*/ */
public List<Register> getContextRegisters() { public List<Register> getContextRegisters() {
@ -171,9 +174,8 @@ public class RegisterManager {
} }
/** /**
* Get an alphabetical sorted unmodifiable list of original register names * Get an alphabetical sorted unmodifiable list of original register names (including context
* (including context registers). Names correspond to orignal register * registers). Names correspond to orignal register name and not aliases which may be defined.
* name and not aliases which may be defined.
* *
* @return alphabetical sorted unmodifiable list of original register names. * @return alphabetical sorted unmodifiable list of original register names.
*/ */
@ -183,6 +185,7 @@ public class RegisterManager {
/** /**
* Returns the largest register located at the specified address * Returns the largest register located at the specified address
*
* @param addr register address * @param addr register address
* @return register or null if not found * @return register or null if not found
*/ */
@ -222,6 +225,7 @@ public class RegisterManager {
/** /**
* Get register by address and size * Get register by address and size
*
* @param addr register address * @param addr register address
* @param size register size * @param size register size
* @return register or null if not found * @return register or null if not found
@ -235,9 +239,9 @@ public class RegisterManager {
} }
/** /**
* Get register by name. A semi-case-insensitive lookup is performed. * Get register by name. A semi-case-insensitive lookup is performed. The specified name must
* The specified name must match either the case-sensitive name or * match either the case-sensitive name or be entirely lowercase or uppercase.
* be entirely lowercase or uppercase. *
* @param name register name * @param name register name
* @return register or null if not found * @return register or null if not found
*/ */
@ -247,6 +251,7 @@ public class RegisterManager {
/** /**
* Get all registers as an unsorted unmodifiable list. * Get all registers as an unsorted unmodifiable list.
*
* @return unmodifiable list of all registers defined * @return unmodifiable list of all registers defined
*/ */
public List<Register> getRegisters() { public List<Register> getRegisters() {
@ -255,7 +260,8 @@ public class RegisterManager {
/** /**
* Get an unmodifiable list of all vector registers indentified by the processor specification * Get an unmodifiable list of all vector registers indentified by the processor specification
* in sorted order based upon address and size. * in sorted order based upon address and size.
*
* @return all vector registers as unmodifiable list * @return all vector registers as unmodifiable list
*/ */
public List<Register> getSortedVectorRegisters() { public List<Register> getSortedVectorRegisters() {
@ -274,6 +280,7 @@ public class RegisterManager {
/** /**
* Compares two vector registers, first by size (descending) and then by offset (ascending). * Compares two vector registers, first by size (descending) and then by offset (ascending).
*
* @param reg1 vector register * @param reg1 vector register
* @param reg2 vector register * @param reg2 vector register
* @return result of comparison * @return result of comparison