mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-12-01 08:30:59 +00:00
GT-3041_emteere Added emulation tests and minor changes to calling
convention. Assigning correct return storage will require a separate change to core Ghidra. Pulled-from: mumbel <22204578+mumbel@users.noreply.github.com>
This commit is contained in:
parent
56d427ce50
commit
0a517e6864
@ -4,16 +4,16 @@
|
||||
Module.manifest||GHIDRA||||END|
|
||||
build.gradle||GHIDRA||||END|
|
||||
data/build.xml||GHIDRA||||END|
|
||||
data/languages/tricore.cspec||GHIDRA||||END|
|
||||
data/languages/tricore.ldefs||GHIDRA||||END|
|
||||
data/languages/tricore.pspec||GHIDRA||||END|
|
||||
data/languages/tc29x.pspec||GHIDRA||||END|
|
||||
data/languages/tc172x.pspec||GHIDRA||||END|
|
||||
data/languages/tc176x.pspec||GHIDRA||||END|
|
||||
data/languages/tricore.slaspec||GHIDRA||||END|
|
||||
data/languages/tricore.sinc||GHIDRA||||END|
|
||||
data/languages/tricore.pcp.sinc||GHIDRA||||END|
|
||||
data/languages/tc29x.pspec||GHIDRA||||END|
|
||||
data/languages/tricore.cspec||GHIDRA||||END|
|
||||
data/languages/tricore.dwarf||GHIDRA||||END|
|
||||
data/languages/tricore.ldefs||GHIDRA||||END|
|
||||
data/languages/tricore.opinion||GHIDRA||||END|
|
||||
data/languages/tricore.pcp.sinc||GHIDRA||||END|
|
||||
data/languages/tricore.pspec||GHIDRA||||END|
|
||||
data/languages/tricore.sinc||GHIDRA||||END|
|
||||
data/languages/tricore.slaspec||GHIDRA||||END|
|
||||
data/manuals/tricore.idx||GHIDRA||||END|
|
||||
data/manuals/tricore2.idx||GHIDRA||||END|
|
||||
|
||||
|
@ -1,6 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<processor_spec>
|
||||
<properties>
|
||||
<property key="emulateInstructionStateModifierClass"
|
||||
value="ghidra.program.emulation.TRICOREEmulateInstructionStateModifier"/>
|
||||
</properties>
|
||||
|
||||
<programcounter register="PC"/>
|
||||
<data_space space="ram"/>
|
||||
|
@ -1,10 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<processor_spec>
|
||||
<properties>
|
||||
<property key="emulateInstructionStateModifierClass"
|
||||
value="ghidra.program.emulation.TRICOREEmulateInstructionStateModifier"/>
|
||||
</properties>
|
||||
|
||||
<programcounter register="PC"/>
|
||||
<data_space space="ram"/>
|
||||
|
||||
|
||||
<default_memory_blocks>
|
||||
<memory_block name="LDRAM.13" start_address="0xd0000000" length="0x1e000" mode="rwv" initialized="false"/>
|
||||
<memory_block name="SPRAM.13" start_address="0xd4000000" length="0x6000" mode="rwv" initialized="false"/>
|
||||
|
@ -1,10 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<processor_spec>
|
||||
|
||||
<properties>
|
||||
<property key="emulateInstructionStateModifierClass"
|
||||
value="ghidra.program.emulation.TRICOREEmulateInstructionStateModifier"/>
|
||||
</properties>
|
||||
|
||||
<programcounter register="PC"/>
|
||||
<data_space space="ram"/>
|
||||
|
||||
|
||||
<default_memory_blocks>
|
||||
<memory_block name="CPU2_DSPR" start_address="0x50000000" length="0x1E000" mode="rwv" initialized="false"/>
|
||||
<memory_block name="CPU2_PSPR" start_address="0x50100000" length="0x8000" mode="rwv" initialized="false"/>
|
||||
|
@ -20,78 +20,146 @@
|
||||
<entry size="8" alignment="4" />
|
||||
</size_alignment_map>
|
||||
</data_organization>
|
||||
<spacebase name="a0_" register="a0" space="ram"/>
|
||||
<spacebase name="a1_" register="a1" space="ram"/>
|
||||
<spacebase name="a8_" register="a8" space="ram"/>
|
||||
<spacebase name="a9_" register="a9" space="ram"/>
|
||||
<global>
|
||||
<register name="a8"/>
|
||||
<register name="a9"/>
|
||||
<register name="p8"/>
|
||||
<register name="a0"/>
|
||||
<register name="a1"/>
|
||||
<register name="p0"/>
|
||||
<range space="ram"/>
|
||||
</global>
|
||||
|
||||
<returnaddress>
|
||||
<register name="a11"/>
|
||||
</returnaddress>
|
||||
|
||||
<stackpointer register="a10" space="ram"/>
|
||||
<default_proto>
|
||||
<prototype name="__stdcall" extrapop="0" stackshift="0" strategy="register">
|
||||
<input>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<!-- This is the first non pointer -->
|
||||
<register name="a4"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<!-- This is the first non pointer -->
|
||||
<register name="d4"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="a5"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="d5"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="a6"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="d6"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="a7"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="d7"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="500" align="4">
|
||||
<addr offset="16" space="ram"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4"> <!-- This is the first non pointer -->
|
||||
<register name="a4"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4"> <!-- This is the first non pointer -->
|
||||
<register name="d4"/>
|
||||
</pentry>
|
||||
<pentry minsize="5" maxsize="8"> <!-- This is the first >4 byte non pointer -->
|
||||
<register name="e4"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="a5"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="d5"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="a6"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="d6"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="a7"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="d7"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="500" align="4">
|
||||
<addr offset="16" space="ram"/>
|
||||
</pentry>
|
||||
</input>
|
||||
|
||||
<!-- There are issues with locking in function signatures with multiple possible
|
||||
return locations. When the signature is committed/locked, Ghidra will apply the
|
||||
first available location, which is incorrect. The decompiler can figure
|
||||
out between two variable locations but doesn't currently pass back the
|
||||
return storage location. A fix is needed, or use custom storage. -->
|
||||
|
||||
<output>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<pentry minsize="1" maxsize="4" metatype="ptr">
|
||||
<register name="a2"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="d2"/>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="e2"/>
|
||||
</pentry>
|
||||
</output>
|
||||
<unaffected>
|
||||
<register name="d8"/>
|
||||
<register name="d9"/>
|
||||
<register name="d10"/>
|
||||
<register name="d11"/>
|
||||
<register name="d12"/>
|
||||
<register name="d13"/>
|
||||
<register name="d14"/>
|
||||
<register name="d15"/>
|
||||
<register name="a10"/>
|
||||
<register name="a11"/>
|
||||
<register name="a12"/>
|
||||
<register name="a13"/>
|
||||
<register name="a14"/>
|
||||
<register name="a15"/>
|
||||
<register name="d8"/>
|
||||
<register name="d9"/>
|
||||
<register name="d10"/>
|
||||
<register name="d11"/>
|
||||
<register name="d12"/>
|
||||
<register name="d13"/>
|
||||
<register name="d14"/>
|
||||
<register name="d15"/>
|
||||
<register name="a10"/>
|
||||
<register name="a11"/>
|
||||
<register name="a12"/>
|
||||
<register name="a13"/>
|
||||
<register name="a14"/>
|
||||
<register name="a15"/>
|
||||
</unaffected>
|
||||
</prototype>
|
||||
</default_proto>
|
||||
|
||||
<!-- This will no longer be necessary once fixes are made to support the
|
||||
correct choice of storage location when there are multiple return types -->
|
||||
|
||||
<prototype name="__stdcall_data" extrapop="0" stackshift="0" strategy="register">
|
||||
<input>
|
||||
<pentry minsize="1" maxsize="4"> <!-- This is the first non pointer -->
|
||||
<register name="a4"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4"> <!-- This is the first non pointer -->
|
||||
<register name="d4"/>
|
||||
</pentry>
|
||||
<pentry minsize="5" maxsize="8"> <!-- This is the first >4 byte non pointer -->
|
||||
<register name="e4"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="a5"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="d5"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="a6"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="d6"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="a7"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="d7"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="500" align="4">
|
||||
<addr offset="16" space="ram"/>
|
||||
</pentry>
|
||||
</input>
|
||||
<output>
|
||||
<pentry minsize="1" maxsize="8">
|
||||
<register name="e2"/>
|
||||
</pentry>
|
||||
</output>
|
||||
<unaffected>
|
||||
<register name="d8"/>
|
||||
<register name="d9"/>
|
||||
<register name="d10"/>
|
||||
<register name="d11"/>
|
||||
<register name="d12"/>
|
||||
<register name="d13"/>
|
||||
<register name="d14"/>
|
||||
<register name="d15"/>
|
||||
<register name="a10"/>
|
||||
<register name="a11"/>
|
||||
<register name="a12"/>
|
||||
<register name="a13"/>
|
||||
<register name="a14"/>
|
||||
<register name="a15"/>
|
||||
</unaffected>
|
||||
</prototype>
|
||||
|
||||
<callotherfixup targetop="saveCallerState">
|
||||
<pcode>
|
||||
<input name="fcx"/>
|
||||
|
5
Ghidra/Processors/tricore/data/languages/tricore.opinion
Normal file
5
Ghidra/Processors/tricore/data/languages/tricore.opinion
Normal file
@ -0,0 +1,5 @@
|
||||
<opinions>
|
||||
<constraint loader="Executable and Linking Format (ELF)" compilerSpecID="gcc">
|
||||
<constraint primary="44" processor="tricore" endian="little" size="32" />
|
||||
</constraint>
|
||||
</opinions>
|
@ -1,6 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<processor_spec>
|
||||
<properties>
|
||||
<property key="emulateInstructionStateModifierClass"
|
||||
value="ghidra.program.emulation.TRICOREEmulateInstructionStateModifier"/>
|
||||
</properties>
|
||||
|
||||
<programcounter register="PC"/>
|
||||
<volatile outputop="write" inputop="read">
|
||||
<range space="ram" first="0x0" last="0x20"/>
|
||||
|
@ -0,0 +1,168 @@
|
||||
/* ###
|
||||
* 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.program.emulation;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
import ghidra.pcode.emulate.Emulate;
|
||||
import ghidra.pcode.emulate.EmulateInstructionStateModifier;
|
||||
import ghidra.pcode.emulate.callother.OpBehaviorOther;
|
||||
import ghidra.pcode.error.LowlevelError;
|
||||
import ghidra.pcode.memstate.MemoryState;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressSpace;
|
||||
import ghidra.program.model.lang.Register;
|
||||
import ghidra.program.model.pcode.Varnode;
|
||||
|
||||
public class TRICOREEmulateInstructionStateModifier extends EmulateInstructionStateModifier {
|
||||
Register FCX,PCXI,LCX,PSW,a10,a11,d8,a12,d12;
|
||||
|
||||
public TRICOREEmulateInstructionStateModifier(Emulate emu) {
|
||||
super(emu);
|
||||
|
||||
registerPcodeOpBehavior("saveCallerState", new tricore_SaveCallerState());
|
||||
registerPcodeOpBehavior("restoreCallerState", new tricore_RestoreCallerState());
|
||||
cacheRegisters(emu);
|
||||
}
|
||||
|
||||
// Save Caller State, could be done in Pcode
|
||||
//
|
||||
private class tricore_SaveCallerState implements OpBehaviorOther {
|
||||
@Override
|
||||
public void evaluate(Emulate emu, Varnode outputVarnode, Varnode[] inputs) {
|
||||
int numArgs = inputs.length - 1;
|
||||
if (numArgs != 3) throw new LowlevelError(this.getClass().getName() + ": requires 3 inputs (FCX, LCX, PCXI), got " + numArgs);
|
||||
|
||||
MemoryState memoryState = emu.getMemoryState();
|
||||
|
||||
// compute new EA
|
||||
BigInteger FCXvalue = memoryState.getBigInteger(FCX);
|
||||
// read the value at FCX, if get nothing, then assume just increment the FCX to get to new node.
|
||||
|
||||
// EA = {FCX.FCXS, 6'b0, FCX.FCXO, 6'b0};
|
||||
long ea = FCXvalue.longValue();
|
||||
ea = ((ea & 0xffff0000) << 12) | ((ea & 0xffff) << 6);
|
||||
|
||||
Address EA_addr = emu.getExecuteAddress().getNewAddress(ea);
|
||||
AddressSpace addressSpace = emu.getExecuteAddress().getAddressSpace();
|
||||
|
||||
// new_FCX = M(EA, word);
|
||||
BigInteger new_FCXvalue = memoryState.getBigInteger(addressSpace, ea, 4, false);
|
||||
// if new_FCX == 0, or not-initialized, then just increment FCX again
|
||||
if (new_FCXvalue.equals(BigInteger.ZERO)) {
|
||||
new_FCXvalue = FCXvalue.add(BigInteger.ONE);
|
||||
}
|
||||
|
||||
// M(EA,16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12], A[13], A[14], A[15], D[12], D[13], D[14], D[15]};
|
||||
byte[] outBytes = new byte[4*16];
|
||||
int index = 0;
|
||||
index += copyRegisterToArray(PCXI, PCXI.getBitLength()/8, memoryState, outBytes, index);
|
||||
index += copyRegisterToArray(PSW, PSW.getBitLength()/8, memoryState, outBytes, index);
|
||||
index += copyRegisterToArray(a10, 2 * a10.getBitLength()/8, memoryState, outBytes, index);
|
||||
index += copyRegisterToArray(d8, 4 * d8.getBitLength()/8, memoryState, outBytes, index);
|
||||
index += copyRegisterToArray(a12, 4 * a12.getBitLength()/8, memoryState, outBytes, index);
|
||||
index += copyRegisterToArray(d12, 4 * d12.getBitLength()/8, memoryState, outBytes, index);
|
||||
// write the bytes
|
||||
memoryState.setChunk(outBytes, EA_addr.getAddressSpace(), EA_addr.getOffset(), 4*16);
|
||||
|
||||
BigInteger PCXIvalue = memoryState.getBigInteger(PCXI);
|
||||
// PCXI[19:0] = FCX[19:0];
|
||||
// PCXI.PCPN = ICR.CCPN;
|
||||
// PCXI.PIE = ICR.IE;
|
||||
// PCXI.UL = 1;
|
||||
PCXIvalue = PCXIvalue.andNot(BigInteger.valueOf(0x000fffff)).or(FCXvalue.and(BigInteger.valueOf(0x000fffff)));
|
||||
memoryState.setValue(PCXI, PCXIvalue);
|
||||
|
||||
// FCX[19:0] = new_FCX[19:0];
|
||||
FCXvalue = FCXvalue.andNot(BigInteger.valueOf(0x000fffff)).or(new_FCXvalue.and(BigInteger.valueOf(0x000fffff)));
|
||||
memoryState.setValue(FCX, FCXvalue);
|
||||
|
||||
// write to memory
|
||||
|
||||
BigInteger LCXvalue = memoryState.getBigInteger(LCX);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private class tricore_RestoreCallerState implements OpBehaviorOther {
|
||||
@Override
|
||||
public void evaluate(Emulate emu, Varnode outputVarnode, Varnode[] inputs) {
|
||||
int numArgs = inputs.length - 1;
|
||||
if (numArgs != 3) throw new LowlevelError(this.getClass().getName() + ": requires 3 inputs (FCX, LCX, PCXI), got " + numArgs);
|
||||
|
||||
MemoryState memoryState = emu.getMemoryState();
|
||||
|
||||
// compute new EA
|
||||
BigInteger FCXvalue = memoryState.getBigInteger(FCX);
|
||||
BigInteger PCXIvalue = memoryState.getBigInteger(PCXI);
|
||||
|
||||
// read the value at FCX, if get nothing, then assume just increment the FCX to get to new node.
|
||||
|
||||
// EA = {FCX.FCXS, 6'b0, FCX.FCXO, 6'b0};
|
||||
long ea = PCXIvalue.longValue();
|
||||
ea = ((ea & 0xffff0000) << 12) | ((ea & 0xffff) << 6);
|
||||
|
||||
Address EA_addr = emu.getExecuteAddress().getNewAddress(ea);
|
||||
AddressSpace addressSpace = emu.getExecuteAddress().getAddressSpace();
|
||||
|
||||
// read the bytes
|
||||
byte[] inBytes = new byte[4*16];
|
||||
memoryState.getChunk(inBytes, addressSpace, EA_addr.getOffset(), 4*16, true);
|
||||
// {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12], A[13], A[14], A[15], D[12], D[13], D[14], D[15] = M(EA,16 * word)};
|
||||
int index = 0;
|
||||
index += copyArrayToRegister(PCXI, PCXI.getBitLength()/8, memoryState, inBytes, index);
|
||||
index += copyArrayToRegister(PSW, PSW.getBitLength()/8, memoryState, inBytes, index);
|
||||
index += copyArrayToRegister(a10, 2 * a10.getBitLength()/8, memoryState, inBytes, index);
|
||||
index += copyArrayToRegister(d8, 4 * d8.getBitLength()/8, memoryState, inBytes, index);
|
||||
index += copyArrayToRegister(a12, 4 * a12.getBitLength()/8, memoryState, inBytes, index);
|
||||
index += copyArrayToRegister(d12, 4 * d12.getBitLength()/8, memoryState, inBytes, index);
|
||||
|
||||
// M(EA, word) = FCX;
|
||||
memoryState.setValue(EA_addr.getAddressSpace(), EA_addr.getOffset(), 4, FCXvalue);
|
||||
|
||||
// FCX[19:0] = new_FCX[19:0];
|
||||
FCXvalue = FCXvalue.andNot(BigInteger.valueOf(0x000fffff)).or(PCXIvalue.and(BigInteger.valueOf(0x000fffff)));
|
||||
memoryState.setValue(FCX, FCXvalue);
|
||||
}
|
||||
}
|
||||
|
||||
// Helper functions
|
||||
private int copyRegisterToArray(Register reg, int len, MemoryState memoryState, byte[] outBytes, int i) {
|
||||
byte vBytes[] = new byte[len];
|
||||
int nread = memoryState.getChunk(vBytes, reg.getAddressSpace(), reg.getOffset(), len, false);
|
||||
System.arraycopy(vBytes, 0, outBytes, i, len);
|
||||
return nread;
|
||||
}
|
||||
|
||||
private int copyArrayToRegister(Register reg, int len, MemoryState memoryState, byte[] inBytes, int i) {
|
||||
byte[] vBytes = new byte[len];
|
||||
AddressSpace spc = reg.getAddressSpace();
|
||||
System.arraycopy(inBytes, i, vBytes, 0, vBytes.length);
|
||||
memoryState.setChunk(vBytes, spc, reg.getOffset(), vBytes.length);
|
||||
return len;
|
||||
}
|
||||
|
||||
private void cacheRegisters(Emulate emu) {
|
||||
FCX = emu.getLanguage().getRegister("FCX");
|
||||
LCX = emu.getLanguage().getRegister("LCX");
|
||||
PCXI = emu.getLanguage().getRegister("PCXI");
|
||||
PSW = emu.getLanguage().getRegister("PSW");
|
||||
a10 = emu.getLanguage().getRegister("a10");
|
||||
d8 = emu.getLanguage().getRegister("d8");
|
||||
a12 = emu.getLanguage().getRegister("a12");
|
||||
d12 = emu.getLanguage().getRegister("d12");
|
||||
}
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
/* ###
|
||||
* 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.test.processors;
|
||||
|
||||
import ghidra.framework.options.Options;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.test.processors.support.EmulatorTestRunner;
|
||||
import ghidra.test.processors.support.ProcessorEmulatorTestAdapter;
|
||||
import junit.framework.Test;
|
||||
|
||||
public class TRICORE_BE_O0_EmulatorTest extends ProcessorEmulatorTestAdapter {
|
||||
private static final String LANGUAGE_ID = "tricore:LE:32:default";
|
||||
private static final String COMPILER_SPEC_ID = "default";
|
||||
private static final String[] REG_DUMP_SET = new String[] {};
|
||||
|
||||
public TRICORE_BE_O0_EmulatorTest(String name) throws Exception {
|
||||
super(name, LANGUAGE_ID, COMPILER_SPEC_ID, REG_DUMP_SET);
|
||||
}
|
||||
|
||||
protected String getProcessorDesignator() { return "tricore_GCC_O0"; }
|
||||
|
||||
protected void initializeState(EmulatorTestRunner testRunner, Program program) throws Exception {
|
||||
testRunner.setRegister("a10", 0x40000000L); // stack, unused location
|
||||
testRunner.setRegister("FCX", 0x00020000L); // free context list start, unused location
|
||||
testRunner.setRegister("LCX", 0x00030000L); // free context list max
|
||||
testRunner.setRegister("PCXI", 0x0L); // current thread context list
|
||||
}
|
||||
|
||||
public static Test suite() {
|
||||
return ProcessorEmulatorTestAdapter.buildEmulatorTestSuite(TRICORE_BE_O0_EmulatorTest.class);
|
||||
}
|
||||
|
||||
protected void setAnalysisOptions(Options analysisOptions) {
|
||||
super.setAnalysisOptions(analysisOptions);
|
||||
analysisOptions.setBoolean("Reference", false); // too many bad disassemblies
|
||||
}
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
/* ###
|
||||
* 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.test.processors;
|
||||
|
||||
import ghidra.framework.options.Options;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.test.processors.support.EmulatorTestRunner;
|
||||
import ghidra.test.processors.support.ProcessorEmulatorTestAdapter;
|
||||
import junit.framework.Test;
|
||||
|
||||
public class TRICORE_BE_O3_EmulatorTest extends ProcessorEmulatorTestAdapter {
|
||||
|
||||
private static final String LANGUAGE_ID = "tricore:LE:32:default";
|
||||
private static final String COMPILER_SPEC_ID = "default";
|
||||
|
||||
private static final String[] REG_DUMP_SET = new String[] {};
|
||||
|
||||
public TRICORE_BE_O3_EmulatorTest(String name) throws Exception {
|
||||
super(name, LANGUAGE_ID, COMPILER_SPEC_ID, REG_DUMP_SET);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getProcessorDesignator() {
|
||||
return "tricore_GCC_O3";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initializeState(EmulatorTestRunner testRunner, Program program) throws Exception {
|
||||
testRunner.setRegister("a10", 0x40000000L); // stack, unused location
|
||||
|
||||
testRunner.setRegister("FCX", 0x00020000L); // free context list start, unused location
|
||||
testRunner.setRegister("LCX", 0x00030000L); // free context list max
|
||||
|
||||
testRunner.setRegister("PCXI", 0x0L); // current thread context list
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
protected void setAnalysisOptions(Options analysisOptions) {
|
||||
super.setAnalysisOptions(analysisOptions);
|
||||
analysisOptions.setBoolean("Reference", false); // too many bad disassemblies
|
||||
}
|
||||
|
||||
public static Test suite() {
|
||||
return ProcessorEmulatorTestAdapter.buildEmulatorTestSuite(TRICORE_BE_O3_EmulatorTest.class);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user