mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 10:49:34 +02:00
GP-0: Trace/emu test fixes re/ DEFAULT_CONTEXT
This commit is contained in:
parent
e61571669f
commit
ad135a4e80
5 changed files with 33 additions and 23 deletions
|
@ -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(
|
||||||
|
|
|
@ -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"));
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue