diff --git a/Ghidra/Debug/Framework-TraceModeling/src/test/java/ghidra/pcode/exec/trace/TracePcodeEmulatorTest.java b/Ghidra/Debug/Framework-TraceModeling/src/test/java/ghidra/pcode/exec/trace/TracePcodeEmulatorTest.java index 3d7da631ad..c3fc1d459f 100644 --- a/Ghidra/Debug/Framework-TraceModeling/src/test/java/ghidra/pcode/exec/trace/TracePcodeEmulatorTest.java +++ b/Ghidra/Debug/Framework-TraceModeling/src/test/java/ghidra/pcode/exec/trace/TracePcodeEmulatorTest.java @@ -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 public void testIMM() throws Throwable { 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, List.of( diff --git a/Ghidra/Debug/Framework-TraceModeling/src/test/java/ghidra/trace/database/listing/DBTraceCodeUnitTest.java b/Ghidra/Debug/Framework-TraceModeling/src/test/java/ghidra/trace/database/listing/DBTraceCodeUnitTest.java index 0c96adea6f..440c137371 100644 --- a/Ghidra/Debug/Framework-TraceModeling/src/test/java/ghidra/trace/database/listing/DBTraceCodeUnitTest.java +++ b/Ghidra/Debug/Framework-TraceModeling/src/test/java/ghidra/trace/database/listing/DBTraceCodeUnitTest.java @@ -1195,8 +1195,8 @@ public class DBTraceCodeUnitTest extends AbstractGhidraHeadlessIntegrationTest i4004 = b.addInstruction(0, b.addr(0x4004), b.language, b.buf(0xf4, 0)); } - // TODO: Test with context - assertNull(i4004.getBaseContextRegister()); + // TODO: Test with non-default context + assertEquals(Register.DEFAULT_CONTEXT, i4004.getBaseContextRegister()); assertEquals(b.language.getRegisters(), i4004.getRegisters()); assertEquals(r4, i4004.getRegister("r4")); diff --git a/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/emu/DefaultPcodeThread.java b/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/emu/DefaultPcodeThread.java index e95a38d6d7..7d0111678e 100644 --- a/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/emu/DefaultPcodeThread.java +++ b/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/emu/DefaultPcodeThread.java @@ -126,7 +126,7 @@ public class DefaultPcodeThread implements PcodeThread { this.pc = language.getProgramCounter(); this.contextreg = language.getContextBaseRegister(); - if (contextreg != null) { + if (contextreg != Register.DEFAULT_CONTEXT) { defaultContext = new ProgramContextImpl(language); language.applyContextSettings(defaultContext); this.context = defaultContext.getDefaultDisassemblyContext(); @@ -190,7 +190,7 @@ public class DefaultPcodeThread implements PcodeThread { @Override public void overrideContextWithDefault() { - if (contextreg != null) { + if (contextreg != Register.DEFAULT_CONTEXT) { overrideContext(defaultContext.getDefaultValue(contextreg, counter)); } } @@ -206,7 +206,7 @@ public class DefaultPcodeThread implements PcodeThread { long offset = arithmetic.toConcrete(state.getVar(pc)).longValue(); setCounter(language.getDefaultSpace().getAddress(offset)); - if (contextreg != null) { + if (contextreg != Register.DEFAULT_CONTEXT) { try { BigInteger ctx = arithmetic.toConcrete(state.getVar(contextreg)); assignContext(new RegisterValue(contextreg, ctx)); @@ -271,7 +271,7 @@ public class DefaultPcodeThread implements PcodeThread { if (frame.isFallThrough()) { overrideCounter(counter.addWrap(decoder.getLastLengthWithDelays())); } - if (contextreg != null) { + if (contextreg != Register.DEFAULT_CONTEXT) { overrideContext(instruction.getRegisterValue(contextreg)); } postExecuteInstruction(); diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/Register.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/Register.java index a35c5ee185..1af3d35e09 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/Register.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/Register.java @@ -43,6 +43,9 @@ public class Register implements java.io.Serializable, Comparable { /** Register can be used in SIMD operations **/ 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 description; // description of the register private Address address; // smallest address containing bits for this register diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/RegisterManager.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/RegisterManager.java index 92f16dc430..65072c8ca4 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/RegisterManager.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/RegisterManager.java @@ -32,7 +32,7 @@ public class RegisterManager { private Map> registerAddressMap = new HashMap>(); - /**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 sortedVectorRegisters; class RegisterSizeKey { @@ -80,10 +80,11 @@ public class RegisterManager { /** * Construct RegisterManager - * @param registers all defined registers with appropriate parent-child relationships - * properly established. - * @param registerNameMap a complete name-to-register map including all register aliases - * and alternate spellings (e.g., case-variations) + * + * @param registers all defined registers with appropriate parent-child relationships properly + * established. + * @param registerNameMap a complete name-to-register map including all register aliases and + * alternate spellings (e.g., case-variations) */ RegisterManager(List registers, Map registerNameMap) { this.registers = Collections.unmodifiableList(registers); @@ -126,8 +127,7 @@ public class RegisterManager { } // if there is no context register, force a default one if (contextBaseRegister == null) { - contextBaseRegister = - new Register("DEFAULT_CONTEXT", "DEFAULT_CONTEXT", Address.NO_ADDRESS, 4, true, 0); + contextBaseRegister = Register.DEFAULT_CONTEXT; } // handle the register size 0 case; Collections.reverse(registerListSortedBySize); @@ -156,6 +156,7 @@ public class RegisterManager { /** * Get context base-register + * * @return context base register or null if one has not been defined by the language. */ 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 */ public List getContextRegisters() { @@ -171,9 +174,8 @@ public class RegisterManager { } /** - * Get an alphabetical sorted unmodifiable list of original register names - * (including context registers). Names correspond to orignal register - * name and not aliases which may be defined. + * Get an alphabetical sorted unmodifiable list of original register names (including context + * registers). Names correspond to orignal register name and not aliases which may be defined. * * @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 + * * @param addr register address * @return register or null if not found */ @@ -222,6 +225,7 @@ public class RegisterManager { /** * Get register by address and size + * * @param addr register address * @param size register size * @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. - * The specified name must match either the case-sensitive name or - * be entirely lowercase or uppercase. + * Get register by name. A semi-case-insensitive lookup is performed. The specified name must + * match either the case-sensitive name or be entirely lowercase or uppercase. + * * @param name register name * @return register or null if not found */ @@ -247,6 +251,7 @@ public class RegisterManager { /** * Get all registers as an unsorted unmodifiable list. + * * @return unmodifiable list of all registers defined */ public List getRegisters() { @@ -255,7 +260,8 @@ public class RegisterManager { /** * 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 */ public List getSortedVectorRegisters() { @@ -274,6 +280,7 @@ public class RegisterManager { /** * Compares two vector registers, first by size (descending) and then by offset (ascending). + * * @param reg1 vector register * @param reg2 vector register * @return result of comparison