GP-1062 revisions made to combined PR 1407 and 5442 (includes merge

changes by ghidra1)
This commit is contained in:
ghidorahrex 2021-06-22 10:02:24 -04:00 committed by ghidra1
parent d8c578d99d
commit f55d6b0f3b
27 changed files with 2482 additions and 1697 deletions

View file

@ -20,7 +20,7 @@
PCodeTest.defaults.toolchain_root = '/local/ToolChains' PCodeTest.defaults.toolchain_root = '/local/ToolChains'
PCodeTest.defaults.build_root = '/local/build-pcodetest' PCodeTest.defaults.build_root = '/local/build-pcodetest'
PCodeTest.defaults.gcc_version = '7.3.0' PCodeTest.defaults.gcc_version = '9.2.0'
PCodeTest.defaults.skip_files = [] PCodeTest.defaults.skip_files = []
PCodeTest.defaults.export_root = os.getcwd() + '/../../../../../ghidra.bin/Ghidra/Test/TestResources/data/pcodetests/' PCodeTest.defaults.export_root = os.getcwd() + '/../../../../../ghidra.bin/Ghidra/Test/TestResources/data/pcodetests/'
PCodeTest.defaults.pcodetest_src = os.getcwd() + '/c_src' PCodeTest.defaults.pcodetest_src = os.getcwd() + '/c_src'

View file

@ -665,10 +665,20 @@ PCodeTest({
}) })
PCodeTest({ PCodeTest({
'name': 'Xtensa', 'name': 'Xtensa_LE',
'build_all': 1, 'build_all': 1,
'build_exe': 1, 'build_exe': 1,
'toolchain': 'Xtensa/xtensa-lx106-elf', 'toolchain': 'Xtensa/xtensa-esp32-elf',
'language_id': 'Xtensa:LE:32:default', 'language_id': 'Xtensa:LE:32:default',
'ccflags': '-L %(toolchain_dir)s/lib/gcc/xtensa-lx106-elf/%(gcc_version)s -lgcc', 'gcc_version' : '8.4.0',
'ccflags': '-L %(toolchain_dir)s/lib/gcc/xtensa-esp32-elf/%(gcc_version)s',
})
PCodeTest({
'name': 'Xtensa_BE',
'build_all': 1,
'build_exe': 1,
'toolchain': 'Xtensa/xtensa-elf',
'language_id': 'Xtensa:BE:32:default',
'ccflags': '-L %(toolchain_dir)s/lib/gcc/xtensa-elf/%(gcc_version)s',
}) })

View file

@ -1,3 +1,18 @@
/* ###
* 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.
*/
apply from: "$rootProject.projectDir/gradle/distributableGhidraModule.gradle" apply from: "$rootProject.projectDir/gradle/distributableGhidraModule.gradle"
apply from: "$rootProject.projectDir/gradle/javaProject.gradle" apply from: "$rootProject.projectDir/gradle/javaProject.gradle"
apply from: "$rootProject.projectDir/gradle/javaTestProject.gradle" apply from: "$rootProject.projectDir/gradle/javaTestProject.gradle"
@ -8,3 +23,7 @@ eclipse.project.name = 'Processors Xtensa'
dependencies { dependencies {
api project(':Base') api project(':Base')
} }
sleighCompileOptions = [
"-l"
]

View file

@ -1,20 +1,18 @@
##VERSION: 2.0 ##VERSION: 2.0
Module.manifest||GHIDRA||||END| Module.manifest||GHIDRA||||END|
build.gradle||GHIDRA||||END| data/languages/cust.sinc||GHIDRA||||END|
data/languages/flix.sinc||GHIDRA||||END|
data/languages/xtensa.cspec||GHIDRA||||END| data/languages/xtensa.cspec||GHIDRA||||END|
data/languages/xtensa.dwarf||GHIDRA||||END| data/languages/xtensa.dwarf||GHIDRA||||END|
data/languages/xtensa.ldefs||GHIDRA||||END| data/languages/xtensa.ldefs||GHIDRA||||END|
data/languages/xtensa.opinion||GHIDRA||||END| data/languages/xtensa.opinion||GHIDRA||||END|
data/languages/xtensa.pspec||GHIDRA||||END| data/languages/xtensa.pspec||GHIDRA||||END|
data/languages/xtensa.sinc||GHIDRA||||END| data/languages/xtensaArch.sinc||GHIDRA||||END|
data/languages/xtensa.slaspec||GHIDRA||||END|
data/languages/xtensaInstructions.sinc||GHIDRA||||END| data/languages/xtensaInstructions.sinc||GHIDRA||||END|
data/languages/xtensaMain.sinc||GHIDRA||||END|
data/languages/xtensa_be.slaspec||GHIDRA||||END|
data/languages/xtensa_depbits.sinc||GHIDRA||||END|
data/languages/xtensa_le.slaspec||GHIDRA||||END|
data/manuals/xtensa.idx||GHIDRA||||END| data/manuals/xtensa.idx||GHIDRA||||END|
data/patterns/patternconstraints.xml||GHIDRA||||END| data/patterns/patternconstraints.xml||GHIDRA||||END|
data/patterns/xtensa_patterns.xml||GHIDRA||||END| data/patterns/xtensa_patterns.xml||GHIDRA||||END|
src/main/help/help/topics/xtensa/help.html||GHIDRA||||END|
src/main/help/help/TOC_Source.xml||GHIDRA||||END|
src/main/java/ghidra/app/util/bin/format/elf/relocation/Xtensa_ElfRelocationHandler.java||GHIDRA||||END|
src/main/java/ghidra/app/util/bin/format/elf/relocation/Xtensa_ElfRelocationConstants.java||GHIDRA||||END|
src/test.processors/java/ghidra/test/processors/Xtensa_O0_EmulatorTest.java||GHIDRA||||END|
src/test.processors/java/ghidra/test/processors/Xtensa_O3_EmulatorTest.java||GHIDRA||||END|

View file

@ -0,0 +1,17 @@
# Per the manual:
# CUST0 and CUST1 opcode encodings shown in Table 7193 are permanently reserved
# for designer-defined opcodes. In the future, customers who use these spaces
# exclusively for their own designer-defined opcodes will be able to add new
# Tensilica-defined options without changing their opcodes or binary executables.
define pcodeop cust0;
:cust0 "{op2="^op2^", r="^ar^", s="^as^", t="^at^"}" is op0=0x0 & op1=0x6 & op2 & ar & as & at {
cust0();
}
define pcodeop cust1;
:cust1 "{op2="^op2^", r="^ar^", s="^as^", t="^at^"}" is op0=0x0 & op1=0x7 & op2 & ar & as & at {
cust1();
}

View file

@ -0,0 +1,9 @@
# FLIX (Flexible Length Instruction eXtension) is a Xtensa processor extension
# that allows for variable-length, multi-op instructions with support from 4
# 16 bytes. Customizable, if if found they should be flagged.
define pcodeop flix;
:FLIX u_4_23 is op0=0xe & u_4_23 {
flix();
}

View file

@ -55,69 +55,15 @@
<pentry minsize="1" maxsize="4" extension="inttype"> <pentry minsize="1" maxsize="4" extension="inttype">
<register name="a2"/> <register name="a2"/>
</pentry> </pentry>
<pentry minsize="1" maxsize="4" extension="inttype"> <!-- TODO: Are joins impacted by endianess ? -->
<register name="a3"/>
</pentry>
<pentry minsize="1" maxsize="4" extension="inttype">
<register name="a4"/>
</pentry>
<pentry minsize="1" maxsize="4" extension="inttype">
<register name="a5"/>
</pentry>
</output>
<returnaddress>
<register name="a0"/>
</returnaddress>
<unaffected>
<register name="a1"/>
<register name="a12"/>
<register name="a13"/>
<register name="a14"/>
<register name="a15"/>
</unaffected>
</prototype>
</default_proto>
<!-- TODO: Evaluate calling convention introduced with PR 5442 -->
<prototype name="__stdcall_windowed" extrapop="0" stackshift="0">
<input>
<!-- TODO: These might be named a2, a3, a4, etc. -->
<pentry minsize="1" maxsize="4" extension="inttype">
<register name="i2"/>
</pentry>
<pentry minsize="1" maxsize="4" extension="inttype">
<register name="i3"/>
</pentry>
<pentry minsize="1" maxsize="4" extension="inttype">
<register name="i4"/>
</pentry>
<pentry minsize="1" maxsize="4" extension="inttype">
<register name="i5"/>
</pentry>
<pentry minsize="1" maxsize="4" extension="inttype">
<register name="i6"/>
</pentry>
<pentry minsize="1" maxsize="4" extension="inttype">
<register name="i7"/>
</pentry>
<pentry minsize="1" maxsize="500" align="4">
<addr offset="0" space="stack"/>
</pentry>
</input>
<output>
<!-- TODO: Verify minsize and maxsize values -->
<!-- TODO: Consider need to name registers -->
<pentry minsize="1" maxsize="4" extension="inttype">
<register name="o2"/>
</pentry>
<pentry minsize="5" maxsize="8" extension="inttype"> <pentry minsize="5" maxsize="8" extension="inttype">
<addr space="join" piece1="o3" piece2="o2"/> <addr space="join" piece1="a3" piece2="a2"/>
</pentry> </pentry>
<pentry minsize="9" maxsize="12" extension="inttype"> <pentry minsize="9" maxsize="12" extension="inttype">
<addr space="join" piece1="o4" piece2="o3" piece3="o2"/> <addr space="join" piece1="a4" piece2="a3" piece3="a2"/>
</pentry> </pentry>
<pentry minsize="13" maxsize="16" extension="inttype"> <pentry minsize="13" maxsize="16" extension="inttype">
<addr space="join" piece1="o5" piece2="o4" piece3="o3" piece4="o2"/> <addr space="join" piece1="a5" piece2="a4" piece3="a3" piece4="a2"/>
</pentry> </pentry>
</output> </output>
<returnaddress> <returnaddress>
@ -125,6 +71,7 @@
</returnaddress> </returnaddress>
<unaffected> <unaffected>
<register name="a1"/> <register name="a1"/>
<register name="a0"/>
<register name="a2"/> <register name="a2"/>
<register name="a3"/> <register name="a3"/>
<register name="a4"/> <register name="a4"/>
@ -135,11 +82,173 @@
<register name="a9"/> <register name="a9"/>
<register name="a10"/> <register name="a10"/>
<register name="a11"/> <register name="a11"/>
<register name="t2"/>
<register name="t3"/>
<register name="t4"/>
<register name="t5"/>
<register name="t6"/>
<register name="t7"/>
</unaffected>
</prototype>
</default_proto>
<prototype name="__call0" extrapop="0" stackshift="0">
<input>
<pentry minsize="1" maxsize="4" extension="inttype">
<register name="a2"/>
</pentry>
<pentry minsize="1" maxsize="4" extension="inttype">
<register name="a3"/>
</pentry>
<pentry minsize="1" maxsize="4" extension="inttype">
<register name="a4"/>
</pentry>
<pentry minsize="1" maxsize="4" extension="inttype">
<register name="a5"/>
</pentry>
<pentry minsize="1" maxsize="4" extension="inttype">
<register name="a6"/>
</pentry>
<pentry minsize="1" maxsize="4" extension="inttype">
<register name="a7"/>
</pentry>
<pentry minsize="1" maxsize="500" align="4">
<addr offset="0" space="stack"/>
</pentry>
</input>
<output>
<pentry minsize="1" maxsize="4" extension="inttype">
<register name="a2"/>
</pentry>
<!-- TODO: Are joins impacted by endianess ? -->
<pentry minsize="5" maxsize="8" extension="inttype">
<addr space="join" piece1="a3" piece2="a2"/>
</pentry>
<pentry minsize="9" maxsize="12" extension="inttype">
<addr space="join" piece1="a4" piece2="a3" piece3="a2"/>
</pentry>
<pentry minsize="13" maxsize="16" extension="inttype">
<addr space="join" piece1="a5" piece2="a4" piece3="a3" piece4="a2"/>
</pentry>
</output>
<returnaddress>
<register name="a0"/>
</returnaddress>
<unaffected>
<register name="a1"/>
<register name="a0"/>
<register name="a12"/> <register name="a12"/>
<register name="a13"/> <register name="a13"/>
<register name="a14"/> <register name="a14"/>
<register name="a15"/> <register name="a15"/>
</unaffected> </unaffected>
</prototype> </prototype>
<callotherfixup targetop="swap4">
<pcode incidentalcopy="true">
<body><![CDATA[
t2 = a2;
t3 = a3;
a2 = a6;
a3 = a7;
a4 = a8;
a5 = a9;
a6 = a10;
a7 = a11;
]]></body>
</pcode>
</callotherfixup>
<callotherfixup targetop="restore4">
<pcode incidentalcopy="true">
<body><![CDATA[
a6 = a2;
a7 = a3;
a2 = t2;
a3 = t3;
a4 = t0;
a5 = t0;
a8 = t0;
a9 = t0;
a10 = t0;
a11 = t0;
]]></body>
</pcode>
</callotherfixup>
<callotherfixup targetop="swap8">
<pcode incidentalcopy="true">
<body><![CDATA[
t2 = a2;
t3 = a3;
t4 = a4;
t5 = a5;
t6 = a6;
t7 = a7;
a2 = a10;
a3 = a11;
a4 = a12;
a5 = a13;
a6 = a14;
a7 = a15;
]]></body>
</pcode>
</callotherfixup>
<callotherfixup targetop="restore8">
<pcode incidentalcopy="true">
<body><![CDATA[
a10 = a2;
a11 = a3;
a2 = t2;
a3 = t3;
a4 = t4;
a5 = t5;
a6 = t6;
a7 = t7;
a8 = t0;
a9 = t0;
]]></body>
</pcode>
</callotherfixup>
<callotherfixup targetop="swap12">
<pcode incidentalcopy="true">
<body><![CDATA[
t2 = a2;
t3 = a3;
a2 = a14;
a3 = a15;
]]></body>
</pcode>
</callotherfixup>
<callotherfixup targetop="restore12">
<pcode incidentalcopy="true">
<body><![CDATA[
a14 = a2;
a15 = a3;
a2 = t2;
a3 = t3;
]]></body>
</pcode>
</callotherfixup>
<callotherfixup targetop="rotateRegWindow">
<pcode>
<input name="CALLINC"/>
<body><![CDATA[
t0 = t0;
]]></body>
</pcode>
</callotherfixup>
<callotherfixup targetop="restoreRegWindow">
<pcode>
<body><![CDATA[
t0 = t0;
]]></body>
</pcode>
</callotherfixup>
</compiler_spec> </compiler_spec>

View file

@ -5,13 +5,28 @@
endian="little" endian="little"
size="32" size="32"
variant="default" variant="default"
version="1.0" version="4.0"
slafile="xtensa.sla" slafile="xtensa_le.sla"
processorspec="xtensa.pspec" processorspec="xtensa.pspec"
manualindexfile="../manuals/xtensa.idx" manualindexfile="../manuals/xtensa.idx"
id="Xtensa:LE:32:default"> id="Xtensa:LE:32:default">
<description>Tensilica Xtensa 32-bit little-endian</description> <description>Tensilica Xtensa 32-bit little-endian</description>
<compiler name="default" spec="xtensa.cspec" id="default"/> <compiler name="default" spec="xtensa.cspec" id="default"/>
<external_name tool="gnu" name="xtensa"/>
<external_name tool="DWARF.register.mapping.file" name="xtensa.dwarf"/>
</language>
<language processor="Xtensa"
endian="big"
size="32"
variant="default"
version="4.0"
slafile="xtensa_be.sla"
processorspec="xtensa.pspec"
manualindexfile="../manuals/xtensa.idx"
id="Xtensa:BE:32:default">
<description>Tensilica Xtensa 32-bit big-endian</description>
<compiler name="default" spec="xtensa.cspec" id="default"/>
<external_name tool="gnu" name="xtensa"/>
<external_name tool="DWARF.register.mapping.file" name="xtensa.dwarf"/> <external_name tool="DWARF.register.mapping.file" name="xtensa.dwarf"/>
</language> </language>
</language_definitions> </language_definitions>

View file

@ -1,6 +1,6 @@
<opinions> <opinions>
<constraint loader="Executable and Linking Format (ELF)" compilerSpecID="default"> <constraint loader="Executable and Linking Format (ELF)" compilerSpecID="default">
<constraint primary="94" processor="Xtensa" size="32" variant="default"/> <constraint primary="94" processor="Xtensa" size="32"/>
<constraint primary="43975" processor="Xtensa" size="32" variant="default"/> <constraint primary="43975" processor="Xtensa" size="32"/>
</constraint> </constraint>
</opinions> </opinions>

View file

@ -2,4 +2,14 @@
<processor_spec> <processor_spec>
<programcounter register="pc"/> <programcounter register="pc"/>
<properties>
<property key="emulateInstructionStateModifierClass" value="ghidra.program.emulation.XtensaEmulateInstructionStateModifier" />
</properties>
<context_data>
<tracked_set space="ram">
<set name="PS" val="0"/>
</tracked_set>
</context_data>
</processor_spec> </processor_spec>

View file

@ -1,469 +0,0 @@
define endian=little;
define alignment=1;
define space ram type=ram_space size=4 default;
define space register type=register_space size=4;
# Special registers (SR). Not all are actually 32 bit, but for the sake of
# simplicity they are here.
define register offset=0x00 size=4 [ LBEG LEND LCOUNT SAR BR LITBASE ];
define register offset=0x30 size=4 [ SCOMPARE1 ];
define register offset=0x40 size=4 [ ACCLO ACCHI ];
define register offset=0x80 size=4 [ M0 M1 M2 M3 ];
define register offset=0x120 size=4 [ WindowBase WindowStart ];
define register offset=0x14c size=4 [ PTEVADDR ];
define register offset=0x164 size=4 [ MMID RASID ITLBCFG DTLBCFG ];
define register offset=0x180 size=4 [ IBREAKENABLE ];
define register offset=0x184 size=4 [ MEMCTL ];
define register offset=0x188 size=4 [ CACHEATTR ATOMCTL ];
define register offset=0x1a0 size=4 [ DDR ];
define register offset=0x1a8 size=4 [ MEPC MEPS MESAVE MESR MECR MEVADDR ];
define register offset=0x200 size=4 [ IBREAKA0 IBREAKA1 ];
define register offset=0x240 size=4 [ DBREAKA0 DBREAKA1 ];
define register offset=0x280 size=4 [ DBREAKC0 DBREAKC1 ];
define register offset=0x2c4 size=4 [ EPC1 EPC2 EPC3 EPC4 EPC5 EPC6 EPC7 ];
define register offset=0x300 size=4 [ DEPC ];
define register offset=0x308 size=4 [ EPS2 EPS3 EPS4 EPS5 EPS6 EPS7 ];
define register offset=0x344 size=4 [ EXCSAVE1 EXCSAVE2 EXCSAVE3 EXCSAVE4 EXCSAVE5 EXCSAVE6 EXCSAVE7 ];
define register offset=0x380 size=4 [ CPENABLE ];
define register offset=0x384 size=4 [ INTERRUPT INTSET INTCLEAR INTENABLE ];
define register offset=0x398 size=4 [ PS VECBASE EXCCAUSE DEBUGCAUSE CCOUNT PRID ICOUNT ICOUNTLEVEL EXCVADDR ];
define register offset=0x3c0 size=4 [ CCOMPARE0 CCOMPARE1 CCOMPARE2 ];
define register offset=0x3d0 size=4 [ MISC0 MISC1 MISC2 MISC3 ];
# TODO: Register offsets *might* be firmware specific?
# Address registers (AR).
define register offset=0x8000 size=4 [
a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15
i2 i3 i4 i5 i6 i7
o2 o3 o4 o5 o6 o7
];
# Floating Point registers (FR + FCR (control) + FSR (status)).
define register offset=0x8100 size=4 [
f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 f13 f14 f15
fcr fsr
];
# Boolean registers (BR).
define register offset=0x8200 size=1 [
b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15
];
# Program counter.
# TODO: offset could also be 0x1300 or 0x8300
define register offset=0x8300 size=4 [ pc ];
# Shift amount register. (TODO: other special registers)
# define register offset=0x2000 size=1 [ SAR ];
define register offset=0x8400 size=4 contextreg;
define context contextreg
phase=(0,0)
loopEnd=(1,1) noflow
;
# Regular 24-bit instruction.
define token insn(24)
# Named opcode/register fields.
op2 = (20,23)
ar = (12,15)
fr = (12,15)
br = (12,15)
as = (8,11)
fs = (8,11)
bs = (8,11)
sr = (8,15)
at = (4,7)
ft = (4,7)
bt = (4,7)
op1 = (16,19)
op0 = (0,3)
# Signed and unsigned immediates. Named [us]N_L_M, where u and s denote signedness, L and M the
# least and most significant bit of the immediate in the instruction word, and N the length
# (i.e. M-L+1).
u3_21_23 = (21,23)
u4_20_23 = (20,23)
s8_16_23 = (16,23) signed
u8_16_23 = (16,23)
u12_12_23 = (12,23)
s12_12_23 = (12,23) signed
u16_8_23 = (8,23)
s8_6_23 = (6,23) signed
u1_20 = (20,20)
u2_18_19 = (18,19)
u3_17_19 = (17,19)
u2_16_17 = (16,17)
u1_16 = (16,16)
u2_14_15 = (14,15)
u3_13_15 = (13,15)
u4_12_15 = (12,15)
u8_8_15 = (8,15)
u2_12_13 = (12,13)
u1_12 = (12,12)
u4_8_11 = (8,11)
u8_4_11 = (4,11)
s4_8_11 = (8,11) signed
u2_6_7 = (6,7)
u3_5_7 = (5,7)
u4_4_7 = (4,7)
s4_4_7 = (4,7)
u2_4_5 = (4,5)
u1_4 = (4,4)
;
# Narrow 16-bit instructions; fields are always prefixed with n_.
define token narrowinsn(16)
n_ar = (12,15)
n_as = (8,11)
n_at = (4,7)
n_op0 = (0, 3)
n_u4_12_15 = (12,15)
n_s4_12_15 = (12,15) signed
n_u4_8_11 = (8,11)
n_u1_7 = (7,7)
n_u2_6_7 = (6,7)
n_u4_4_7 = (4,7)
n_s3_4_6 = (4,6)
n_u2_4_5 = (4,5)
;
define token opbyte (8)
op0_8 = (0,7)
;
define token opword (16)
op0_16 = (0,15)
;
attach variables [ sr ] [
# 0x...0 0x...4 0x...8 0x...c
LBEG LEND LCOUNT SAR # 0x0_
BR LITBASE _ _ # 0x1_
_ _ _ _ # 0x2_
SCOMPARE1 _ _ _ # 0x3_
ACCLO ACCHI _ _ # 0x4_
_ _ _ _ # 0x5_
_ _ _ _ # 0x6_
_ _ _ _ # 0x7_
M0 M1 M2 M3 # 0x8_
_ _ _ _ # 0x9_
_ _ _ _ # 0xa_
_ _ _ _ # 0xb_
_ _ _ _ # 0xc_
_ _ _ _ # 0xd_
_ _ _ _ # 0xe_
_ _ _ _ # 0xf_
# 0x...0 0x...4 0x...8 0x...c
_ _ _ _ # 0x10_
_ _ _ _ # 0x11_
WindowBase WindowStart _ _ # 0x12_
_ _ _ _ # 0x13_
_ _ _ PTEVADDR # 0x14_
_ _ _ _ # 0x15_
_ MMID RASID ITLBCFG # 0x16_
DTLBCFG _ _ _ # 0x17_
IBREAKENABLE MEMCTL CACHEATTR ATOMCTL # 0x18_
_ _ _ _ # 0x19_
DDR _ MEPC MEPS # 0x1a_
MESAVE MESR MECR MEVADDR # 0x1b_
_ _ _ _ # 0x1c_
_ _ _ _ # 0x1d_
_ _ _ _ # 0x1e_
_ _ _ _ # 0x1f_
# 0x...0 0x...4 0x...8 0x...c
IBREAKA0 IBREAKA1 _ _ # 0x20_
_ _ _ _ # 0x21_
_ _ _ _ # 0x22_
_ _ _ _ # 0x23_
DBREAKA0 DBREAKA1 _ _ # 0x24_
_ _ _ _ # 0x25_
_ _ _ _ # 0x26_
_ _ _ _ # 0x27_
DBREAKC0 DBREAKC1 _ _ # 0x28_
_ _ _ _ # 0x29_
_ _ _ _ # 0x2a_
_ _ _ _ # 0x2b_
_ EPC1 EPC2 EPC3 # 0x2c_
EPC4 EPC5 EPC6 EPC7 # 0x2d_
_ _ _ _ # 0x2e_
_ _ _ _ # 0x2f_
# 0x...0 0x...4 0x...8 0x...c
DEPC _ EPS2 EPS3 # 0x30_
EPS4 EPS5 EPS6 EPS7 # 0x31_
_ _ _ _ # 0x32_
_ _ _ _ # 0x33_
_ EXCSAVE1 EXCSAVE2 EXCSAVE3 # 0x34_
EXCSAVE4 EXCSAVE5 EXCSAVE6 EXCSAVE7 # 0x35_
_ _ _ _ # 0x36_
_ _ _ _ # 0x37_
CPENABLE INTERRUPT INTSET INTCLEAR # 0x38_
INTENABLE _ PS VECBASE # 0x39_
EXCCAUSE DEBUGCAUSE CCOUNT PRID # 0x3a_
ICOUNT ICOUNTLEVEL EXCVADDR _ # 0x3b_
CCOMPARE0 CCOMPARE1 CCOMPARE2 _ # 0x3c_
MISC0 MISC1 MISC2 MISC3 # 0x3d_
_ _ _ _ # 0x3e_
_ _ _ _ # 0x3f_
# 0x...0 0x...4 0x...8 0x...c
];
attach variables [ ar as at n_ar n_as n_at ] [
a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15
];
attach variables [ fr fs ft ] [
f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 f13 f14 f15
];
attach variables [ br bs bt ] [
b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15
];
attach variables [ u8_8_15 ] [
# 0x...0 0x...4 0x...8 0x...c
LBEG LEND LCOUNT SAR # 0x0_
BR LITBASE _ _ # 0x1_
_ _ _ _ # 0x2_
SCOMPARE1 _ _ _ # 0x3_
ACCLO ACCHI _ _ # 0x4_
_ _ _ _ # 0x5_
_ _ _ _ # 0x6_
_ _ _ _ # 0x7_
M0 M1 M2 M3 # 0x8_
_ _ _ _ # 0x9_
_ _ _ _ # 0xa_
_ _ _ _ # 0xb_
_ _ _ _ # 0xc_
_ _ _ _ # 0xd_
_ _ _ _ # 0xe_
_ _ _ _ # 0xf_
# 0x...0 0x...4 0x...8 0x...c
_ _ _ _ # 0x10_
_ _ _ _ # 0x11_
WindowBase WindowStart _ _ # 0x12_
_ _ _ _ # 0x13_
_ _ _ PTEVADDR # 0x14_
_ _ _ _ # 0x15_
_ MMID RASID ITLBCFG # 0x16_
DTLBCFG _ _ _ # 0x17_
IBREAKENABLE MEMCTL CACHEATTR ATOMCTL # 0x18_
_ _ _ _ # 0x19_
DDR _ MEPC MEPS # 0x1a_
MESAVE MESR MECR MEVADDR # 0x1b_
_ _ _ _ # 0x1c_
_ _ _ _ # 0x1d_
_ _ _ _ # 0x1e_
_ _ _ _ # 0x1f_
# 0x...0 0x...4 0x...8 0x...c
IBREAKA0 IBREAKA1 _ _ # 0x20_
_ _ _ _ # 0x21_
_ _ _ _ # 0x22_
_ _ _ _ # 0x23_
DBREAKA0 DBREAKA1 _ _ # 0x24_
_ _ _ _ # 0x25_
_ _ _ _ # 0x26_
_ _ _ _ # 0x27_
DBREAKC0 DBREAKC1 _ _ # 0x28_
_ _ _ _ # 0x29_
_ _ _ _ # 0x2a_
_ _ _ _ # 0x2b_
_ EPC1 EPC2 EPC3 # 0x2c_
EPC4 EPC5 EPC6 EPC7 # 0x2d_
_ _ _ _ # 0x2e_
_ _ _ _ # 0x2f_
# 0x...0 0x...4 0x...8 0x...c
DEPC _ EPS2 EPS3 # 0x30_
EPS4 EPS5 EPS6 EPS7 # 0x31_
_ _ _ _ # 0x32_
_ _ _ _ # 0x33_
_ EXCSAVE1 EXCSAVE2 EXCSAVE3 # 0x34_
EXCSAVE4 EXCSAVE5 EXCSAVE6 EXCSAVE7 # 0x35_
_ _ _ _ # 0x36_
_ _ _ _ # 0x37_
CPENABLE INTERRUPT INTSET INTCLEAR # 0x38_
INTENABLE _ PS VECBASE # 0x39_
EXCCAUSE DEBUGCAUSE CCOUNT PRID # 0x3a_
ICOUNT ICOUNTLEVEL EXCVADDR _ # 0x3b_
CCOMPARE0 CCOMPARE1 CCOMPARE2 _ # 0x3c_
MISC0 MISC1 MISC2 MISC3 # 0x3d_
_ _ _ _ # 0x3e_
_ _ _ _ # 0x3f_
# 0x...0 0x...4 0x...8 0x...c
];
# Various 32-bit pointers relative to PC. Any operands that are split across non-consecutive
# bits are named foo_LL.LM_ML.MM, where LL is the least significant bits of the least
# singificant operand half, LM the most significant bits of the least significant operand half, etc.
urel_16_23: rel is u8_16_23 [ rel = inst_start + u8_16_23 + 4; ] { export *:4 rel; }
srel_16_23: rel is s8_16_23 [ rel = inst_start + s8_16_23 + 4; ] { export *:4 rel; }
srel_12_23: rel is s12_12_23 [ rel = inst_start + s12_12_23 + 4; ] { export *:4 rel; }
srel_6_23: rel is s8_6_23 [ rel = inst_start + s8_6_23 + 4; ] { export *:4 rel; }
urel_12_15_4_5: rel is n_u2_4_5 & n_u4_12_15 [
rel = inst_start + ((n_u2_4_5 << 4) | n_u4_12_15) + 4;
] { export *:4 rel; }
srel_6_23_sb2: rel is s8_6_23 [
rel = (inst_start & ~3) + ( s8_6_23 << 2 ) + 4;
] { export *:4 rel; }
srel_8_23_oex_sb2: rel is u16_8_23 [
rel = ((inst_start + 3) & ~3) + ((u16_8_23 | 0xfffc0000) << 2);
# Below might indicate firmware specific:
# rel = 0x9fa000 + 0x40000 + ((u16_8_23 | 0xffff0000) << 2);
] { export *:4 rel; }
# Immediates split across the instruction.
u5_8_11_20: tmp is u1_20 & u4_8_11 [ tmp = (u1_20 << 4) | u4_8_11; ] { export *[const]:1 tmp; }
u5_4_7_20: tmp is u1_20 & u4_4_7 [ tmp = (u1_20 << 4) | u4_4_7; ] { export *[const]:1 tmp; }
u5_8_11_16: tmp is u1_16 & u4_8_11 [ tmp = (u1_16 << 4) | u4_8_11; ] { export *[const]:1 tmp; }
u5_4_7_12: tmp is u1_12 & u4_4_7 [ tmp = (u1_12 << 4) | u4_4_7; ] { export *[const]:1 tmp; }
u5_8_11_4: tmp is u1_4 & u4_8_11 [ tmp = (u1_4 << 4) | u4_8_11; ] { export *[const]:1 tmp; }
# Signed 12-bit (extended to 16) immediate, used by MOVI.
s16_16_23_8_11: tmp is s4_8_11 & u8_16_23 [
tmp = (s4_8_11 << 8) | u8_16_23;
] { export *[const]:2 tmp; }
# An “asymmetric” immediate from -32..95, used by MOVI.N.
n_s8_12_15_4_6_asymm: tmp is n_s3_4_6 & n_s4_12_15 [
tmp = ((((n_s3_4_6 & 7) << 4) | (n_s4_12_15 & 15)) |
((((n_s3_4_6 >> 2) & 1) & ((n_s3_4_6 >> 1) & 1)) << 7));
] { export *[const]:1 tmp; }
# Immediates shifted or with offset.
s16_16_23_sb8: tmp is s8_16_23 [ tmp = s8_16_23 << 8; ] { export *[const]:2 tmp; }
u15_12_23_sb3: tmp is u12_12_23 [ tmp = u12_12_23 << 3; ] { export *[const]:2 tmp; }
u10_16_23_sb2: tmp is u8_16_23 [ tmp = u8_16_23 << 2; ] { export *[const]:2 tmp; }
u9_16_23_sb1: tmp is u8_16_23 [ tmp = u8_16_23 << 1; ] { export *[const]:2 tmp; }
u5_20_23_plus1: tmp is u4_20_23 [ tmp = u4_20_23 + 1; ] { export *[const]:1 tmp; }
u8_20.23_sb4: tmp is u4_20_23 [ tmp = u4_20_23 << 4; ] { export *[const]:1 tmp; }
u5_4_7_plus7: tmp is u4_4_7 [ tmp = u4_4_7 + 7; ] { export *[const]:1 tmp; }
n_u6_12_15_sb2: tmp is n_u4_12_15 [ tmp = n_u4_12_15 << 2; ] { export *[const]:1 tmp; }
# One-extended. FIXME: Verify this. Only used by [LS]32E (window extension), which arent yet
# implemented.
s5_12_15_oex: tmp is u4_12_15 [ tmp = (2 << u4_12_15) * -1; ] { export *[const]:2 tmp; }
# Some 4-bit immediates with mappings that cant be (easily) expressed in a single disassembly action.
# n_u4_4_7 with 0 being -1, used by ADDI.N.
n_s4_4_7_nozero: tmp is n_u4_4_7 = 0 [ tmp = -1; ] { export *[const]:4 tmp; }
n_s4_4_7_nozero: tmp is n_u4_4_7 [ tmp = n_u4_4_7+0; ] { export *[const]:4 tmp; }
# imm stored in sa for slli is 32-shift.
# TODO why can't we use subtable output for this instead of repeating u5_4_7_20 calc?
u5_4_7_20_slli: tmp is u1_20 & u4_4_7 [ tmp = 32 - ((u1_20 << 4) | u4_4_7); ] { export *[const]:1 tmp; }
# B4CONST(ar) (Branch Immediate) encodings, pg. 41 f.
r_b4const: tmp is ar = 0 [ tmp = 0xffffffff; ] { export *[const]:4 tmp; }
r_b4const: tmp is ar = 1 [ tmp = 0x1; ] { export *[const]:4 tmp; }
r_b4const: tmp is ar = 2 [ tmp = 0x2; ] { export *[const]:4 tmp; }
r_b4const: tmp is ar = 3 [ tmp = 0x3; ] { export *[const]:4 tmp; }
r_b4const: tmp is ar = 4 [ tmp = 0x4; ] { export *[const]:4 tmp; }
r_b4const: tmp is ar = 5 [ tmp = 0x5; ] { export *[const]:4 tmp; }
r_b4const: tmp is ar = 6 [ tmp = 0x6; ] { export *[const]:4 tmp; }
r_b4const: tmp is ar = 7 [ tmp = 0x7; ] { export *[const]:4 tmp; }
r_b4const: tmp is ar = 8 [ tmp = 0x8; ] { export *[const]:4 tmp; }
r_b4const: tmp is ar = 9 [ tmp = 0xa; ] { export *[const]:4 tmp; }
r_b4const: tmp is ar = 10 [ tmp = 0xc; ] { export *[const]:4 tmp; }
r_b4const: tmp is ar = 11 [ tmp = 0x10; ] { export *[const]:4 tmp; }
r_b4const: tmp is ar = 12 [ tmp = 0x20; ] { export *[const]:4 tmp; }
r_b4const: tmp is ar = 13 [ tmp = 0x40; ] { export *[const]:4 tmp; }
r_b4const: tmp is ar = 14 [ tmp = 0x80; ] { export *[const]:4 tmp; }
r_b4const: tmp is ar = 15 [ tmp = 0x100; ] { export *[const]:4 tmp; }
# B4CONSTU(ar) (Branch Unsigned Immediate) encodings, pg. 42.
r_b4constu: tmp is ar = 0 [ tmp = 0x8000; ] { export *[const]:4 tmp; }
r_b4constu: tmp is ar = 1 [ tmp = 0x1000; ] { export *[const]:4 tmp; }
r_b4constu: tmp is ar = 2 [ tmp = 0x2; ] { export *[const]:4 tmp; }
r_b4constu: tmp is ar = 3 [ tmp = 0x3; ] { export *[const]:4 tmp; }
r_b4constu: tmp is ar = 4 [ tmp = 0x4; ] { export *[const]:4 tmp; }
r_b4constu: tmp is ar = 5 [ tmp = 0x5; ] { export *[const]:4 tmp; }
r_b4constu: tmp is ar = 6 [ tmp = 0x6; ] { export *[const]:4 tmp; }
r_b4constu: tmp is ar = 7 [ tmp = 0x7; ] { export *[const]:4 tmp; }
r_b4constu: tmp is ar = 8 [ tmp = 0x8; ] { export *[const]:4 tmp; }
r_b4constu: tmp is ar = 9 [ tmp = 0xa; ] { export *[const]:4 tmp; }
r_b4constu: tmp is ar = 10 [ tmp = 0xc; ] { export *[const]:4 tmp; }
r_b4constu: tmp is ar = 11 [ tmp = 0x10; ] { export *[const]:4 tmp; }
r_b4constu: tmp is ar = 12 [ tmp = 0x20; ] { export *[const]:4 tmp; }
r_b4constu: tmp is ar = 13 [ tmp = 0x40; ] { export *[const]:4 tmp; }
r_b4constu: tmp is ar = 14 [ tmp = 0x80; ] { export *[const]:4 tmp; }
r_b4constu: tmp is ar = 15 [ tmp = 0x100; ] { export *[const]:4 tmp; }
define pcodeop breakpoint;
define pcodeop dhi;
define pcodeop dhu;
define pcodeop dhwb;
define pcodeop dhwbi;
define pcodeop dii;
define pcodeop diu;
define pcodeop diwb;
define pcodeop diwbi;
define pcodeop dpfl;
define pcodeop dpfr;
define pcodeop dpfro;
define pcodeop dpfw;
define pcodeop dpfwo;
define pcodeop dsync;
define pcodeop esync;
define pcodeop excw;
define pcodeop extw;
define pcodeop idtlb;
define pcodeop ihi;
define pcodeop ihu;
define pcodeop iii;
define pcodeop iitlb;
define pcodeop iiu;
define pcodeop ill;
define pcodeop ipf;
define pcodeop ipfl;
define pcodeop isync;
define pcodeop acquire;
define pcodeop ldct;
define pcodeop lict;
define pcodeop licw;
define pcodeop memw;
define pcodeop pdtlb;
define pcodeop pitlb;
define pcodeop rdtlb0;
define pcodeop rdtlb1;
define pcodeop rer;
define pcodeop rfdd;
define pcodeop rfde;
define pcodeop rfdo;
define pcodeop rfe;
define pcodeop rfi;
define pcodeop rfme;
define pcodeop rfue;
define pcodeop rfwo;
define pcodeop rfwu;
define pcodeop ritlb0;
define pcodeop ritlb1;
define pcodeop rsil;
define pcodeop rsr; # TODO: Map known special registers.
define pcodeop rsync;
define pcodeop rur;
define pcodeop s32c1i;
define pcodeop release;
define pcodeop sdct;
define pcodeop sict;
define pcodeop sicw;
define pcodeop simcall;
define pcodeop syscall;
define pcodeop waiti;
define pcodeop wdtlb;
define pcodeop wer;
define pcodeop witlb;
define pcodeop wsr; # TODO: Map known special registers.
define pcodeop wur;
define pcodeop xsr;

View file

@ -1,25 +0,0 @@
@include "xtensa.sinc"
# NOTE: This is quite a big hack; a real processor will compare nextPC to LEND on every ifetch.
# As we only inject the branch-back check on addresses marked by loop insns, we may miss
# strange things like loop registers being written directly or loop registers being overwritten
# by a "nested" loop instruction. We also don't check CLOOPENABLE (PS.EXCM).
# For code that hasn't been intentially crafted for anti-analysis this should be fine.
:^instruction is phase=0 & loopEnd=1 & instruction [phase=1;] {
if (LCOUNT == 0) goto <done>;
LCOUNT = LCOUNT - 1;
goto [LBEG];
<done>
build instruction;
}
:^instruction is phase=0 & loopEnd=0 & instruction [phase=1;] {
build instruction;
}
with : phase=1 {
@include "xtensaInstructions.sinc"
}
# TODO: Evaluate
# @include "xtensaTodo.sinc"

View file

@ -0,0 +1,433 @@
define endian=$(ENDIAN);
define alignment=1;
define space ram type=ram_space size=4 default;
define space register type=register_space size=4;
# Address registers (AR).
define register offset=0x0000 size=4 [
a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15
];
# Temporary Address registers (facilitates simplified CALL register swapping used by decompiler)
define register offset=0x0080 size=4 [
t0 t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t11
];
# Floating Point registers
define register offset=0x0100 size=4 [
f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 f13 f14 f15
];
# Boolean registers (BR)
define register offset=0x0200 size=1 [
b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15
];
define register offset=0x0400 size=4 [
user0 user1 user2 user3 user4 user5 user6 user7 user8 user9 user10 user11 user12 user13 user14 user15
user16 user17 user18 user19 user20 user21 user22 user23 user24 user25 user26 user27 user28 user29 user30 user31
user32 user33 user34 user35 user36 user37 user38 user39 user40 user41 user42 user43 user44 user45 user46 user47
user48 user49 user50 user51 user52 user53 user54 user55 user56 user57 user58 user59 user60 user61 user62 user63
user64 user65 user66 user67 user68 user69 user70 user71 user72 user73 user74 user75 user76 user77 user78 user79
user80 user81 user82 user83 user84 user85 user86 user87 user88 user89 user90 user91 user92 user93 user94 user95
user96 user97 user98 user99 user100 user101 user102 user103 user104 user105 user106 user107 user108 user109 user110 user111
user112 user113 user114 user115 user116 user117 user118 user119 user120 user121 user122 user123 user124 user125 user126 user127
user128 user129 user130 user131 user132 user133 user134 user135 user136 user137 user138 user139 user140 user141 user142 user143
user144 user145 user146 user147 user148 user149 user150 user151 user152 user153 user154 user155 user156 user157 user158 user159
user160 user161 user162 user163 user164 user165 user166 user167 user168 user169 user170 user171 user172 user173 user174 user175
user176 user177 user178 user179 user180 user181 user182 user183 user184 user185 user186 user187 user188 user189 user190 user191
user192 user193 user194 user195 user196 user197 user198 user199 user200 user201 user202 user203 user204 user205 user206 user207
user208 user209 user210 user211 user212 user213 user214 user215 user216 user217 user218 user219 user220 user221 user222 user223
user224 user225 user226 user227 user228 user229 user230 THREADPTR FCR FSR user234 user235 user236 user237 user238 user239
user240 user241 user242 user243 user244 user245 user246 user247 user248 user249 user250 user251 user252 user253 user254 user255
];
# Program counter.
define register offset=0x1000 size=4 [ pc ];
define register offset=0x2000 size=4 [
LBEG LEND LCOUNT SAR BR LITBASE sr6 sr7 sr8 sr9 sr10 sr11 SCOMPARE1 sr13 sr14 sr15
@if ENDIAN == "big"
ACCHI ACCLO
@else
ACCLO ACCHI
@endif
sr18 sr19 sr20 sr21 sr22 sr23 sr24 sr25 sr26 sr27 sr28 sr29 sr30 sr31
M0 M1 M2 M3 sr36 sr37 sr38 sr39 sr40 sr41 sr42 sr43 sr44 sr45 sr46 sr47
sr48 sr49 sr50 sr51 sr52 sr53 sr54 sr55 sr56 sr57 sr58 sr59 sr60 sr61 sr62 sr63
sr64 sr65 sr66 sr67 sr68 sr69 sr70 sr71 WindowBase WindowStart sr74 sr75 sr76 sr77 sr78 sr79
sr80 sr81 sr82 PTEVADDR sr84 sr85 sr86 sr87 sr88 MMID RASID ITLBCFG DTLBCFG sr93 sr94 sr95
IBREAKENABLE MEMCTL CACHEATTR ATOMCTL sr100 sr101 sr102 sr103 DDR sr105 MEPC MEPS MESAVE MESR MECR MEVADDR
sr112 sr113 sr114 sr115 sr116 sr117 sr118 sr119 sr120 sr121 sr122 sr123 sr124 sr125 sr126 sr127
IBREAKA0 IBREAKA1 sr130 sr131 sr132 sr133 sr134 sr135 sr136 sr137 sr138 sr139 sr140 sr141 sr142 sr143
DBREAKA0 DBREAKA1 sr146 sr147 sr148 sr149 sr150 sr151 sr152 sr153 sr154 sr155 sr156 sr157 sr158 sr159
DBREAKC0 DBREAKC1 sr162 sr163 sr164 sr165 sr166 sr167 sr168 sr169 sr170 sr171 sr172 sr173 sr174 sr175
sr176 EPC1 EPC2 EPC3 EPC4 EPC5 EPC6 EPC7 sr184 sr185 sr186 sr187 sr188 sr189 sr190 sr191
DEPC sr193 EPS2 EPS3 EPS4 EPS5 EPS6 EPS7 sr200 sr201 sr202 sr203 sr204 sr205 sr206 sr207
sr208 EXCSAVE1 EXCSAVE2 EXCSAVE3 EXCSAVE4 EXCSAVE5 EXCSAVE6 EXCSAVE7 sr216 sr217 sr218 sr219 sr220 sr221 sr222 sr223
#TODO: REVIEW NEEDED! - INTSET / INTERRUPT placement/address (also review related attach)
CPENABLE INTERRUPT INTSET INTCLEAR INTENABLE sr229 PS VECBASE EXCCAUSE DEBUGCAUSE CCOUNT PRID ICOUNT ICOUNTLEVEL EXCVADDR sr239
CCOMPARE0 CCOMPARE1 CCOMPARE2 sr243 MISC0 MISC1 MISC2 MISC3 sr248 sr249 sr250 sr251 sr252 sr253 sr254 sr255
];
define register offset=0x2040 size=8 [ ACC ];
@define EPC_BASE "0x22c0" #address of EPCn = $(EPC_BASE) + (n * 4)
@define EPS_BASE "0x2300" #address of EPSn = $(EPS_BASE) + (n * 4)
@define PS_INTLEVEL "PS[0,4]"
@define PS_EXCM "PS[4,1]"
@define PS_UM "PS[5,1]"
@define PS_RING "PS[6,2]"
@define PS_OWB "PS[8,4]"
@define PS_CALLINC "PS[12,2]"
@define PS_WOE "PS[14,1]"
define register offset=0xf000 size=4 contextreg;
define context contextreg
loopMode=(0,0)
loopEnd=(1,1) noflow
#transient bits
phase=(31,31)
;
@if ENDIAN == "big"
# little-endian -> big-endian 24-bit conversion chart
#|00|01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|16|17|18|19|20|21|22|23|
#|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# Regular 24-bit instruction.
define token insn(24)
# Named opcode/register fields.
op2 = (0,3)
op1 = (4,7)
ar = (8,11)
fr = (8,11)
br = (8,11)
as = (12,15)
fs = (12,15)
bs = (12,15)
sr = (8,15)
at = (16,19)
ft = (16,19)
bt = (16,19)
op0 = (20,23)
# Signed and unsigned immediates. Named [us]N_L.M, where u and s denote signedness, L and M the
# least and most significant bit of the immediate in the instruction word, and N the length
# (i.e. M-L+1).
u3_21_23 = (0,2)
u4_20_23 = (0,3)
s8_16_23 = (0,7) signed
u8_16_23 = (0,7)
u12_12_23 = (0,11)
s12_12_23 = (0,11) signed
u16_8_23 = (0,15)
s8_6_23 = (0,17) signed
u1_20 = (3,3)
u2_18_19 = (4,5)
u3_17_19 = (4,6)
u2_16_17 = (6,7)
u1_16 = (7,7)
u1_15_15 = (8,8)
u2_14_15 = (8,9)
u3_13_15 = (8,10)
u4_12_15 = (8,11)
m0m1_14_14 = (9,9)
u2_12_13 = (10,11)
mw_12_13 = (10,11)
u1_12 = (11,11)
u4_8_11 = (12,15)
u8_4_11 = (12,19)
s4_8_11 = (12,15) signed
u1_7_7 = (16,16)
u2_6_7 = (16,17)
u3_5_7 = (16,18)
u4_4_7 = (16,19)
s4_4_7 = (16,19)
m2m3_6_6 = (17,17)
u_4_23 = (0,19)
u2_4_5 = (18,19)
u1_4 = (19,19)
;
# little-endian -> big-endian 16-bit conversion chart
#|00|01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|
#|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
# Narrow 16-bit instructions; fields are always prefixed with n_.
define token narrowinsn(16)
n_ar = (0,3)
n_as = (4,7)
n_at = (8,11)
n_op0 = (12,15)
n_u4_12_15 = (0,3)
n_s4_12_15 = (0,3) signed
n_u4_8_11 = (4,7)
n_u1_7 = (8,8)
n_u2_6_7 = (8,9)
n_u4_4_7 = (8,11)
n_s3_4_6 = (9,11)
n_u2_4_5 = (10,11)
;
@else
# Regular 24-bit instruction.
define token insn(24)
# Named opcode/register fields.
op2 = (20,23)
ar = (12,15)
fr = (12,15)
br = (12,15)
as = (8,11)
fs = (8,11)
bs = (8,11)
sr = (8,15)
at = (4,7)
ft = (4,7)
bt = (4,7)
op1 = (16,19)
op0 = (0,3)
# Signed and unsigned immediates. Named [us]N_L_M, where u and s denote signedness, L and M the
# least and most significant bit of the immediate in the instruction word, and N the length
# (i.e. M-L+1).
u3_21_23 = (21,23)
u4_20_23 = (20,23)
s8_16_23 = (16,23) signed
u8_16_23 = (16,23)
u12_12_23 = (12,23)
s12_12_23 = (12,23) signed
u16_8_23 = (8,23)
s8_6_23 = (6,23) signed
u1_20 = (20,20)
u2_18_19 = (18,19)
u3_17_19 = (17,19)
u2_16_17 = (16,17)
u1_16 = (16,16)
u1_15_15 = (15,15)
u2_14_15 = (14,15)
u3_13_15 = (13,15)
u4_12_15 = (12,15)
m0m1_14_14 = (14,14)
u2_12_13 = (12,13)
mw_12_13 = (12,13)
u1_12 = (12,12)
u4_8_11 = (8,11)
u8_4_11 = (4,11)
s4_8_11 = (8,11) signed
u1_7_7 = (7,7)
u2_6_7 = (6,7)
u3_5_7 = (5,7)
u4_4_7 = (4,7)
s4_4_7 = (4,7)
m2m3_6_6 = (6,6)
u_4_23 = (4,23)
u2_4_5 = (4,5)
u1_4 = (4,4)
;
# Narrow 16-bit instructions; fields are always prefixed with n_.
define token narrowinsn(16)
n_ar = (12,15)
n_as = (8,11)
n_at = (4,7)
n_op0 = (0, 3)
n_u4_12_15 = (12,15)
n_s4_12_15 = (12,15) signed
n_u4_8_11 = (8,11)
n_u1_7 = (7,7)
n_u2_6_7 = (6,7)
n_u4_4_7 = (4,7)
n_s3_4_6 = (4,6)
n_u2_4_5 = (4,5)
;
@endif
attach variables [ sr ] [
# 0x...0 0x...4 0x...8 0x...c
LBEG LEND LCOUNT SAR # 0x0_
BR LITBASE _ _ # 0x1_
_ _ _ _ # 0x2_
SCOMPARE1 _ _ _ # 0x3_
ACCLO ACCHI _ _ # 0x4_
_ _ _ _ # 0x5_
_ _ _ _ # 0x6_
_ _ _ _ # 0x7_
M0 M1 M2 M3 # 0x8_
_ _ _ _ # 0x9_
_ _ _ _ # 0xa_
_ _ _ _ # 0xb_
_ _ _ _ # 0xc_
_ _ _ _ # 0xd_
_ _ _ _ # 0xe_
_ _ _ _ # 0xf_
# 0x...0 0x...4 0x...8 0x...c
_ _ _ _ # 0x10_
_ _ _ _ # 0x11_
WindowBase WindowStart _ _ # 0x12_
_ _ _ _ # 0x13_
_ _ _ PTEVADDR # 0x14_
_ _ _ _ # 0x15_
_ MMID RASID ITLBCFG # 0x16_
DTLBCFG _ _ _ # 0x17_
IBREAKENABLE MEMCTL CACHEATTR ATOMCTL # 0x18_
_ _ _ _ # 0x19_
DDR _ MEPC MEPS # 0x1a_
MESAVE MESR MECR MEVADDR # 0x1b_
_ _ _ _ # 0x1c_
_ _ _ _ # 0x1d_
_ _ _ _ # 0x1e_
_ _ _ _ # 0x1f_
# 0x...0 0x...4 0x...8 0x...c
IBREAKA0 IBREAKA1 _ _ # 0x20_
_ _ _ _ # 0x21_
_ _ _ _ # 0x22_
_ _ _ _ # 0x23_
DBREAKA0 DBREAKA1 _ _ # 0x24_
_ _ _ _ # 0x25_
_ _ _ _ # 0x26_
_ _ _ _ # 0x27_
DBREAKC0 DBREAKC1 _ _ # 0x28_
_ _ _ _ # 0x29_
_ _ _ _ # 0x2a_
_ _ _ _ # 0x2b_
_ EPC1 EPC2 EPC3 # 0x2c_
EPC4 EPC5 EPC6 EPC7 # 0x2d_
_ _ _ _ # 0x2e_
_ _ _ _ # 0x2f_
# 0x...0 0x...4 0x...8 0x...c
DEPC _ EPS2 EPS3 # 0x30_
EPS4 EPS5 EPS6 EPS7 # 0x31_
_ _ _ _ # 0x32_
_ _ _ _ # 0x33_
_ EXCSAVE1 EXCSAVE2 EXCSAVE3 # 0x34_
EXCSAVE4 EXCSAVE5 EXCSAVE6 EXCSAVE7 # 0x35_
_ _ _ _ # 0x36_
_ _ _ _ # 0x37_
CPENABLE INTERRUPT INTSET INTCLEAR # 0x38_
INTENABLE _ PS VECBASE # 0x39_
EXCCAUSE DEBUGCAUSE CCOUNT PRID # 0x3a_
ICOUNT ICOUNTLEVEL EXCVADDR _ # 0x3b_
CCOMPARE0 CCOMPARE1 CCOMPARE2 _ # 0x3c_
MISC0 MISC1 MISC2 MISC3 # 0x3d_
_ _ _ _ # 0x3e_
_ _ _ _ # 0x3f_
# 0x...0 0x...4 0x...8 0x...c
];
attach variables [ ar as at n_ar n_as n_at ] [
a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15
];
attach variables [ fr fs ft ] [
f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 f13 f14 f15
];
attach variables [ br bs bt ] [
b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15
];
# Various 32-bit pointers relative to PC. Any operands that are split across non-consecutive
# bits are named foo_LL.LM_ML.MM, where LL is the least significant bits of the least
# singificant operand half, LM the most significant bits of the least significant operand half, etc.
attach variables [ mw_12_13 ] [
M0 M1 M2 M3
];
attach variables [ m2m3_6_6 ] [
M2 M3
];
attach variables [ m0m1_14_14 ] [
M0 M1
];
#implemented pcodeops
define pcodeop breakpoint;
define pcodeop dhi;
define pcodeop dhu;
define pcodeop dhwb;
define pcodeop dhwbi;
define pcodeop dii;
define pcodeop diu;
define pcodeop diwb;
define pcodeop diwbi;
define pcodeop dpfl;
define pcodeop dpfr;
define pcodeop dpfro;
define pcodeop dpfw;
define pcodeop dpfwo;
define pcodeop dsync;
define pcodeop esync;
define pcodeop excw;
define pcodeop extw;
define pcodeop idtlb;
define pcodeop ihi;
define pcodeop ihu;
define pcodeop iii;
define pcodeop iitlb;
define pcodeop iiu;
define pcodeop ill;
define pcodeop ipf;
define pcodeop ipfl;
define pcodeop isync;
define pcodeop acquire;
define pcodeop ldct;
define pcodeop lict;
define pcodeop licw;
define pcodeop memw;
define pcodeop nsa;
define pcodeop nsau;
define pcodeop pdtlb;
define pcodeop pitlb;
define pcodeop rdtlb0;
define pcodeop rdtlb1;
define pcodeop rer;
define pcodeop restore4;
define pcodeop restore8;
define pcodeop restore12;
define pcodeop rfdd;
define pcodeop rfde;
define pcodeop rfdo;
define pcodeop rfe;
define pcodeop rfi;
define pcodeop rfme;
define pcodeop rfue;
define pcodeop rfwo;
define pcodeop rfwu;
define pcodeop ritlb0;
define pcodeop ritlb1;
define pcodeop rsil;
define pcodeop rsr;
define pcodeop rsync;
define pcodeop rur;
define pcodeop s32c1i;
define pcodeop release;
define pcodeop restoreRegWindow;
define pcodeop rotateRegWindow;
define pcodeop sdct;
define pcodeop sict;
define pcodeop sicw;
define pcodeop simcall;
define pcodeop syscall;
define pcodeop swap4;
define pcodeop swap8;
define pcodeop swap12;
define pcodeop waiti;
define pcodeop wdtlb;
define pcodeop wer;
define pcodeop witlb;
define pcodeop wsr;
define pcodeop wur;
define pcodeop xsr;

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,116 @@
# Various 32-bit pointers relative to PC. Any operands that are split across non-consecutive
# bits are named foo_LL_LM_ML_MM, where LL is the least significant bits of the least
# singificant operand half, LM the most significant bits of the least significant operand half, etc.
srel_16_23: rel is s8_16_23 [ rel = inst_start + s8_16_23 + 4; ] { export *:4 rel; }
srel_12_23: rel is s12_12_23 [ rel = inst_start + s12_12_23 + 4; ] { export *:4 rel; }
srel_6_23: rel is s8_6_23 [ rel = inst_start + s8_6_23 + 4; ] { export *:4 rel; }
urel_12_15_4_5: rel is n_u2_4_5 & n_u4_12_15 [
rel = inst_start + ((n_u2_4_5 << 4) | n_u4_12_15) + 4;
] { export *:4 rel; }
srel_6_23_sb2: rel is s8_6_23 [
rel = (inst_start & ~3) + ( s8_6_23 << 2 ) + 4;
] { export *:4 rel; }
srel_8_23_oex_sb2: rel is u16_8_23 [
rel = ((inst_start + 3) & ~3) + ((u16_8_23 | 0xffff0000) << 2);
] { export *:4 rel; }
# Immediates split across the instruction.
u5_8_11_20: tmp is u1_20 & u4_8_11 [ tmp = (u1_20 << 4) | u4_8_11; ] { export *[const]:4 tmp; }
u5_4_7_20: tmp is u1_20 & u4_4_7 [ tmp = 32 - ((u1_20 << 4) | u4_4_7); ] { export *[const]:4 tmp; }
u5_8_11_16: tmp is u1_16 & u4_8_11 [ tmp = (u1_16 << 4) | u4_8_11; ] { export *[const]:4 tmp; }
u5_4_7_12: tmp is u1_12 & u4_4_7 [ tmp = (u1_12 << 4) | u4_4_7; ] { export *[const]:4 tmp; }
u5_8_11_4: tmp is u1_4 & u4_8_11 [ tmp = (u1_4 << 4) | u4_8_11; ] { export *[const]:4 tmp; }
# Signed 12-bit (extended to 16) immediate, used by MOVI.
s16_16_23_8_11: tmp is s4_8_11 & u8_16_23 [
tmp = (s4_8_11 << 8) | u8_16_23;
] { export *[const]:2 tmp; }
# An “asymmetric” immediate from -32..95, used by MOVI.N.
n_s8_12_15_4_6_asymm: tmp is n_s3_4_6 & n_s4_12_15 [
tmp = ((((n_s3_4_6 & 7) << 4) | (n_s4_12_15 & 15)) |
((((n_s3_4_6 >> 2) & 1) & ((n_s3_4_6 >> 1) & 1)) << 7));
] { export *[const]:1 tmp; }
# Immediates shifted or with offset.
s16_16_23_sb8: tmp is s8_16_23 [ tmp = s8_16_23 << 8; ] { export *[const]:4 tmp; }
u15_12_23_sb3: tmp is u12_12_23 [ tmp = u12_12_23 << 3; ] { export *[const]:4 tmp; }
u10_16_23_sb2: tmp is u8_16_23 [ tmp = u8_16_23 << 2; ] { export *[const]:4 tmp; }
u9_16_23_sb1: tmp is u8_16_23 [ tmp = u8_16_23 << 1; ] { export *[const]:4 tmp; }
u5_20_23_plus1: tmp is u4_20_23 [ tmp = u4_20_23 + 1; ] { export *[const]:4 tmp; }
u8_20_23_sb4: tmp is u4_20_23 [ tmp = u4_20_23 << 4; ] { export *[const]:4 tmp; }
u5_4_7_plus7: tmp is u4_4_7 [ tmp = u4_4_7 + 7; ] { export *[const]:4 tmp; }
n_u6_12_15_sb2: tmp is n_u4_12_15 [ tmp = n_u4_12_15 << 2; ] { export *[const]:4 tmp; }
# One-extended. FIXME: Verify this. Only used by [LS]32E (window extension), which arent yet
# implemented.
s5_12_15_oex: tmp is u4_12_15 [ tmp = (u4_12_15 << 2) - 64; ] { export *[const]:2 tmp; }
# Some 4-bit immediates with mappings that cant be (easily) expressed in a single disassembly action.
# n_u4_4_7 with 0 being -1, used by ADDI.N.
n_s4_4_7_nozero: tmp is n_u4_4_7 = 0 [ tmp = -1; ] { export *[const]:4 tmp; }
n_s4_4_7_nozero: tmp is n_u4_4_7 [ tmp = n_u4_4_7+0; ] { export *[const]:4 tmp; }
# B4CONST(ar) (Branch Immediate) encodings, pg. 41 f.
r_b4const: tmp is ar = 0 [ tmp = 0xffffffff; ] { export *[const]:4 tmp; }
r_b4const: tmp is ar = 1 [ tmp = 0x1; ] { export *[const]:4 tmp; }
r_b4const: tmp is ar = 2 [ tmp = 0x2; ] { export *[const]:4 tmp; }
r_b4const: tmp is ar = 3 [ tmp = 0x3; ] { export *[const]:4 tmp; }
r_b4const: tmp is ar = 4 [ tmp = 0x4; ] { export *[const]:4 tmp; }
r_b4const: tmp is ar = 5 [ tmp = 0x5; ] { export *[const]:4 tmp; }
r_b4const: tmp is ar = 6 [ tmp = 0x6; ] { export *[const]:4 tmp; }
r_b4const: tmp is ar = 7 [ tmp = 0x7; ] { export *[const]:4 tmp; }
r_b4const: tmp is ar = 8 [ tmp = 0x8; ] { export *[const]:4 tmp; }
r_b4const: tmp is ar = 9 [ tmp = 0xa; ] { export *[const]:4 tmp; }
r_b4const: tmp is ar = 10 [ tmp = 0xc; ] { export *[const]:4 tmp; }
r_b4const: tmp is ar = 11 [ tmp = 0x10; ] { export *[const]:4 tmp; }
r_b4const: tmp is ar = 12 [ tmp = 0x20; ] { export *[const]:4 tmp; }
r_b4const: tmp is ar = 13 [ tmp = 0x40; ] { export *[const]:4 tmp; }
r_b4const: tmp is ar = 14 [ tmp = 0x80; ] { export *[const]:4 tmp; }
r_b4const: tmp is ar = 15 [ tmp = 0x100; ] { export *[const]:4 tmp; }
# B4CONSTU(ar) (Branch Unsigned Immediate) encodings, pg. 42.
r_b4constu: tmp is ar = 0 [ tmp = 0x8000; ] { export *[const]:4 tmp; }
r_b4constu: tmp is ar = 1 [ tmp = 0x1000; ] { export *[const]:4 tmp; }
r_b4constu: tmp is ar = 2 [ tmp = 0x2; ] { export *[const]:4 tmp; }
r_b4constu: tmp is ar = 3 [ tmp = 0x3; ] { export *[const]:4 tmp; }
r_b4constu: tmp is ar = 4 [ tmp = 0x4; ] { export *[const]:4 tmp; }
r_b4constu: tmp is ar = 5 [ tmp = 0x5; ] { export *[const]:4 tmp; }
r_b4constu: tmp is ar = 6 [ tmp = 0x6; ] { export *[const]:4 tmp; }
r_b4constu: tmp is ar = 7 [ tmp = 0x7; ] { export *[const]:4 tmp; }
r_b4constu: tmp is ar = 8 [ tmp = 0x8; ] { export *[const]:4 tmp; }
r_b4constu: tmp is ar = 9 [ tmp = 0xa; ] { export *[const]:4 tmp; }
r_b4constu: tmp is ar = 10 [ tmp = 0xc; ] { export *[const]:4 tmp; }
r_b4constu: tmp is ar = 11 [ tmp = 0x10; ] { export *[const]:4 tmp; }
r_b4constu: tmp is ar = 12 [ tmp = 0x20; ] { export *[const]:4 tmp; }
r_b4constu: tmp is ar = 13 [ tmp = 0x40; ] { export *[const]:4 tmp; }
r_b4constu: tmp is ar = 14 [ tmp = 0x80; ] { export *[const]:4 tmp; }
r_b4constu: tmp is ar = 15 [ tmp = 0x100; ] { export *[const]:4 tmp; }
Ret4: loc is epsilon [loc = ((inst_start + 3) & 0x0fffffff) | 0x40000000; ] { ret:4 = loc; export ret; }
Ret8: loc is epsilon [loc = ((inst_start + 3) & 0x0fffffff) | 0x80000000; ] { ret:4 = loc; export ret; }
Ret12: loc is epsilon [loc = ((inst_start + 3) & 0x0fffffff) | 0xc0000000; ] { ret:4 = loc; export ret; }
:^instruction is phase=0 & loopMode=1 & instruction [ phase=1; ] {
build instruction;
if (LCOUNT == 0 || $(PS_EXCM)) goto inst_next;
LCOUNT = LCOUNT - 1;
goto [LBEG];
}
:^instruction is phase=0 & loopMode=1 & loopEnd=1 & instruction
[ loopMode=0; phase=1; ] {
build instruction;
}
:^instruction is phase=0 & loopMode=0 & instruction
[ phase=1; ] {
build instruction;
}

View file

@ -1,66 +0,0 @@
## Windowed Register Option ##
# CALL4 - Call PC-relative, Rotate Window by 4, pg. 298.
:call4 srel_6.23_sb2 is srel_6.23_sb2 & u2_4.5 = 0b01 & op0 = 0b0101 unimpl
# CALL8 - Call PC-relative, Rotate Window by 8, pg. 300.
:call8 srel_6.23_sb2 is srel_6.23_sb2 & u2_4.5 = 0b10 & op0 = 0b0101 unimpl
# CALL12 - Call PC-relative, Rotate Window by 12, pg. 302.
:call12 srel_6.23_sb2 is srel_6.23_sb2 & u2_4.5 = 0b11 & op0 = 0b0101 unimpl
# CALLX4 - Call Register, Rotate Window by 4, pg. 305.
:callx4 as is op2 = 0 & op1 = 0 & ar = 0 & as & u2_6.7 = 0b11 & u2_4.5 = 0b01 & op0 = 0 unimpl
# CALLX8 - Call Register, Rotate Window by 8, pg. 307.
:callx8 as is op2 = 0 & op1 = 0 & ar = 0 & as & u2_6.7 = 0b11 & u2_4.5 = 0b10 & op0 = 0 unimpl
# CALLX12 - Call Register, Rotate Window by 12, pg. 308.
:callx12 as is op2 = 0 & op1 = 0 & ar = 0 & as & u2_6.7 = 0b11 & u2_4.5 = 0b11 & op0 = 0 unimpl
# ENTRY - Subroutine Entry, pg. 340.
:entry as, u15_12.23_sb3 is u15_12.23_sb3 & as & u2_6.7 = 0b00 & u2_4.5 = 0b11 & op0 = 0b0110 unimpl
# L32E - Load 32-bit for Window Exceptions, pg. 376.
:l32e at, as, s5_12.15_oex is op2 = 0 & op1 = 0b1001 & s5_12.15_oex & as & at & op0 = 0 unimpl
# MOVSP - Move to Stack Pointer, pg. 427.
:movsp at, as is op2 = 0 & op1 = 0 & ar = 0b0001 & as & at & op0 = 0 unimpl
# RETW - Windowed Return, pg. 480.
:retw is op2 = 0 & ar = 0 & as = 0 & at = 0 & u2_18.19 = 0b10 & u2_16.17 = 0b01 & op0 = 0 unimpl
# RETW.N - Narrow Windowed Return, pg. 482.
:retw.n is n_ar = 0b1111 & n_as = 0 & n_at = 0b0001 & n_op0 = 0b1101 unimpl
# ROTW - Rotate Window, pg. 496.
:rotw s4_4.7 is op2 = 0b0100 & op1 = 0 & ar = 0b1000 & as = 0 & s4_4.7 & op0 = 0 unimpl
# S32E - Store 32-bit for Window Exceptions, pg. 508.
:s32e at, as, s5_12.15_oex is op2 = 0b0100 & op1 = 0b1001 & s5_12.15_oex & as & at & op0 = 0 unimpl
## MAC16 option ##
# LDDEC - Load with Autodecrement, pg. 386.
:lddec "MAC16_REGS[" u2_12.13 "]", as is op2 = 0b1001 & op1 = 0 & u2_14.15 = 0 & u2_12.13 & as & at = 0 & op0 = 0b0100 unimpl
# LDINC - Load with Autoincrement, pg. 387.
:ldinc "MAC16_REGS[" u2_12.13 "]", as is op2 = 0b1000 & op1 = 0 & u2_14.15 = 0 & u2_12.13 & as & at = 0 & op0 = 0b0100 unimpl
# MULA.AA.* - Signed Multiply, pg. 431.
:mula.aa.* as, at is op2 = 0b0001 & u2_18.19 = 0b01 & ar = 0 & as & at & op0 = 0b0100 unimpl
# FIXME: Add remaining MUL.* opcodes.
## Loop Option ##
# LOOP - Loop, pg. 392.
:loop as, urel_16.23 is urel_16.23 & ar = 0b1000 & as & at = 0b0111 & op0 = 0b0110 unimpl
# LOOPGTZ - Loop if Greater Than Zero, pg. 394.
:loopgtz as, urel_16.23 is urel_16.23 & ar = 0b1010 & as & at = 0b0111 & op0 = 0b0110 unimpl
# LOOPNEZ - Loop if Not Equal Zero, pg. 396.
:loopnez as, urel_16.23 is urel_16.23 & ar = 0b1001 & as & at = 0b0111 & op0 = 0b0110 unimpl

View file

@ -0,0 +1,12 @@
@define ENDIAN "big"
@include "xtensaArch.sinc"
@include "xtensaMain.sinc"
with : phase=1 {
@include "xtensaInstructions.sinc"
#@include "xtensa_depbits.sinc" #comment floating-point and uncomment this to use depbits
@include "cust.sinc"
@include "flix.sinc"
}

View file

@ -0,0 +1,11 @@
# Xtensa Deposit Bits instruction
# This is broken out because it collides with the floating point instructions. It is not included by default
# DEPBITS - Add (RRR), pg. 394.
shiftimm: simm is u4_20_23 & u1_16 [ simm = u1_16 << 4 + u4_20_23; ] { export *[const]:4 simm; }
:depbits as, at, shiftimm, u4_12_15 is u3_17_19=0x5 & u4_12_15 & as & at & op0 = 0 & shiftimm {
mask:4 = (1 << u4_12_15) - 1;
bits:4 = (as & mask) << shiftimm;
mask = mask << shiftimm;
at = (~mask & at) | bits;
}

View file

@ -0,0 +1,12 @@
@define ENDIAN "little"
@include "xtensaArch.sinc"
@include "xtensaMain.sinc"
with : phase=1 {
@include "xtensaInstructions.sinc"
#@include "xtensa_depbits.sinc" #comment floating-point and uncomment this to use depbits
@include "cust.sinc"
@include "flix.sinc"
}

View file

@ -1,242 +1,354 @@
@xtensa.pdf[Xtensa® Instruction Set Architecture (ISA) Reference Manual, April 2010] @isa_summary.pdf[Xtensa® Instruction Set Architecture Summary, For all Xtensa LX Processors April 2022]
b4const(ar), 65 ABS, 324
b4constu(ar), 66 ABS.D, 324
call4, 322 ABS.S, 325
call8, 324 ADD, 326
call12, 326 ADD.N, 326
callx4, 329 ADD.D, 327
callx8, 331 ADD.S, 328
callx12, 332 ADDEXP.D, 329
entry, 364 ADDEXP.S, 329
l32e, 400 ADDEXPM.D, 330
movsp, 451 ADDEXPM.S, 331
retw, 504 ADDI, 332
retw.n, 506 ADDI.N, 333
rotw, 520 ADDMI, 334
s32e, 532 ADDX2, 335
lddec, 410 ADDX4, 336
ldinc, 411 ADDX8, 336
mula.aa.*, 455 ALL4, 337
loop, 416 ALL8, 338
loopgtz, 418 AND, 339
loopnez, 420 ANDB, 339
abs, 270 ANDBC, 340
abs.s, 271 ANY4, 341
add, 272 ANY8, 341
add.n, 273 BALL, 342
add.s, 274 BANY, 343
addi, 275 BBC, 344
addi.n, 276 BBCI, 345
addmi, 277 BBCI.L, 346
addx2, 278 BBS, 347
addx4, 279 BBSI, 348
addx8, 280 BBSI.L, 349
all4, 281 BEQ, 349
all8, 282 BEQI, 350
and, 283 BEQZ, 351
andb, 284 BEQZ.N, 352
andbc, 285 BF, 353
any4, 286 BGE, 354
any8, 287 BGEI, 355
ball, 288 ixBGEU, 356
bany, 289 BGEUI, 357
bbc, 290 BGEZ, 358
bbci, 291 BLT, 359
bbs, 293 BLTI, 360
bbsi, 294 BLTU, 361
beq, 296 BLTUI, 361
beqi, 297 BLTZ, 362
beqz, 298 BNALL, 363
beqz.n, 299 BNE, 364
bf, 300 BNEI, 365
bge, 301 BNEZ, 366
bgei, 302 BNEZ.N, 367
bgeu, 303 BNONE, 368
bgeui, 304 BREAK, 369
bgez, 305 BREAK.N, 370
blt, 306 BT, 371
blti, 307 CALL0, 372
bltu, 308 CALL4 373
bltui, 309 CALL8, 375
bltz, 310 CALL12, 376
bnall, 311 CALLX0, 377
bne, 312 CALLX4, 378
bnei, 313 CALLX8, 379
bnez, 314 CALLX12, 380
bnez.n, 315 CEIL.D, 382
bnone, 316 CEIL.S, 383
break, 317 CLAMPS, 383
break.n, 319 CLREX, 384
bt, 320 CONST.D, 385
call0, 321 CONST.S, 386
callx0, 328 CONST16, 387
ceil.s, 335 CVTD.S, 388
clamps, 336 CVTS.D, 389
dhi, 337 DCI, 389
dhu, 339 DCWB, 391
dhwb, 341 DCWBI, 392
dhwbi, 343 DEPBITS, 394
dii, 345 DHI, 395
diu, 347 DHI.B, 396
diwb, 349 DHU, 397
diwbi, 351 DHWB, 398
dpfl, 353 DHWB.B, 400
dpfr, 355 DHWBI, 400
dpfro, 357 DHWBI.B, 402
dpfw, 359 xDII, 403
dpfwo, 361 DIU, 404
dsync, 363 DIV0.D, 406
esync, 366 DIV0.S, 406
excw, 367 DIVN.D, 407
extui, 368 DIVN.S, 408
extw, 369 DIWB, 409
float.s, 370 DIWBI, 410
floor.s, 371 DIWBUI.P, 412
idtlb, 372 DPFL, 413
ihi, 373 DPFM.B, 415
ihu, 375 DPFM.BF, 416
iii, 377 DPFR, 416
iitlb, 379 DPFR.B, 418
iiu, 380 DPFR.BF, 419
ill, 382 DPFRO, 419
ill.n, 383 DPFW, 421
ipf, 384 DPFW.B, 422
ipfl, 386 DPFW.BF, 423
isync, 388 DPFWO, 424
j, 390 DSYNC, 425
ret, 502 ENTRY, 426
jx, 392 ESYNC, 427
l8ui, 393 EXCW, 428
l16si, 394 EXTUI, 429
l16ui, 396 EXTW, 430
l32ai, 398 FLOAT.D, 431
l32i, 402 FLOAT.S, 431
l32i.n, 404 FLOOR.D, 432
l32r, 406 FLOOR.S, 433
ldct, 408 FSYNC, 434
lict, 412 GETEX, 434
licw, 414 IDTLB, 435
lsi, 422 IHI, 436
lsiu, 424 IHU, 438
lsx, 426 III, 439
lsxu, 428 IITLB, 441
madd.s, 430 IIU, 442
max, 431 ILL, 443
maxu, 432 ILL.N, 444
memw, 433 IPF, 444
min, 434 IPFL, 446
minu, 435 ISYNC, 447
mov.n, 437 J, 449
mov.s, 438 J.L, 449
moveqz, 439 JX, 450
moveqz.s, 440 L8UI, 450
movf, 441 L16SI, 451
movf.s, 442 L16UI, 453
movgez, 443 L32AI, 454
movgez.s, 444 L32E, 455
movi, 445 L32EX, 457
movi.n, 446 L32I, 458
movltz, 447 L32I.N, 459
movltz.s, 448 L32R, 461
movnez, 449 LDCT, 463
movnez.s, 450 LDCW, 464
movt, 452 LDDEC, 465
movt.s, 453 LDDR32.P, 467
msub.s, 454 LDI, 467
mul.s, 459 LDINC, 468
mul16s, 460 LDIP, 469
mul16u, 461 LDX, 471
mull, 474 LDXP, 472
mulsh, 479 LOOP, 473
muluh, 480 LOOPGTZ, 475
neg, 481 LOOPNEZ, 476
neg.s, 482 LSI, 478
nop, 483 LSIP, 480
nop.n, 484 LSIU, 481
nsa, 485 LSX, 482
nsau, 486 LSXP, 483
oeq.s, 487 LSXU, 484
ole.s, 488 MADD.D, 486
olt.s, 489 MADD.S, 486
mov, 436 MADDN.D, 487
or, 490 MADDN.S, 488
orb, 491 MAX, 489
orbc, 492 MAXU, 489
pdtlb, 493 MEMW, 490
pitlb, 494 MIN, 491
quos, 495 MINU, 491
quou, 496 MKDADJ.D, 492
rdtlb0, 497 MKDADJ.S, 493
rdtlb1, 498 MKSADJ.D, 494
rems, 499 MKSADJ.S, 494
remu, 500 MOV, 495
rer, 501 MOV.D, 496
ret.n, 503 MOV.N, 497
rfdd, 508 MOV.S, 498
rfde, 509 MOVEQZ, 499
rfdo, 510 MOVEQZ.D, 499
rfe, 511 MOVEQZ.S, 500
rfi, 512 MOVF, 501
rfme, 513 MOVF.D, 502
rfr, 514 MOVF.S, 503
rfue, 515 MOVGEZ, 504
rfwo, 516 MOVGEZ.D, 504
rfwu, 517 MOVGEZ.S, 505
ritlb0, 518 MOVI, 506
ritlb1, 519 MOVI.N, 507
round.s, 521 MOVLTZ, 508
rsil, 522 MOVLTZ.D, 509
rsr, 524 MOVLTZ.S, 510
rsync, 526 MOVNEZ, 510
rur, 527 MOVNEZ.D, 511
s8i, 528 MOVNEZ.S, 512
s16i, 529 MOVSP, 513
s32c1i, 530 MOVT, 514
s32i, 534 MOVT.D, 515
s32i.n, 536 MOVT.S, 516
s32ri, 538 MSUB.D, 517
sdct, 540 MSUB.S, 517
sext, 542 MUL.AA.*, 518
sict, 543 MUL.AD.*, 519
sicw, 545 MUL.DA.*, 520
simcall, 547 MUL.DD.*, 521
sll, 548 MUL.D, 522
slli, 549 MUL.S, 522
sra, 550 MUL16S, 523
srai, 551 MUL16U, 524
src, 552 MULA.AA.*, 524
srl, 553 MULA.AD.*, 525
srli, 554 MULA.DA.*, 526
ssa8b, 555 MULA.DA.*.LDDEC, 527
ssa8l, 556 MULA.DA.*.LDINC, 528
ssai, 557 MULA.DD.*, 530
ssi, 558 MULA.DD.*.LDDEC 531
ssiu, 560 MULA.DD.*.LDINC 532
ssl, 562 MULL, 534
ssr, 563 MULS.AA.*, 535
ssx, 564 MULS.AD.*, 535
ssxu, 565 MULS.DA.*, 536
sub, 566 MULS.DD.*, 537
sub.s, 567 MULSH, 538
subx2, 568 MULUH, 539
subx4, 569 NEG, 540
subx8, 570 NEG.D, 540
syscall, 571 NEG.S, 541
trunc.s, 572 NEXP01.D, 541
ueq.s, 573 NEXP01.S, 542
ufloat.s, 574 NOP, 543
ule.s, 575 NOP.N, 544
ult.s, 576 NSA, 545
un.s, 578 NSAU, 546
utrunc.s, 579 OEQ.D, 547
waiti, 580 OEQ.S, 547
wdtlb, 581 OLE.D, 548
wer, 582 OLE.S, 549
wfr, 583 OLT.D, 550
witlb, 584 OLT.S, 551
wsr, 585 OR, 551
wur, 587 ORB, 552
xor, 588 ORBC, 553
xorb, 589 TLB, 553
xsr, 590 PITLB, 554
PPTLB, 555
QUOS, 556
QUOU, 557
RDTLB0, 558
RDTLB1, 559
RECIP0.D, 560
RECIP0.S, 560
REMS, 561
REMU, 562
RER, 563
RET, 564
RET.N, 564
RETW, 565
RETW.N, 567
RFDD, 568
RFDE, 569
RFDO, 570
RFE, 570
RFI, 571
RFME, 572
RFR, 573
RFRD, 573
RFUE, 574
RFWO, 575
RFWU, 576
RITLB0, 576
RITLB1, 577
ROTW, 578
ROUND.D, 579
ROUND.S, 580
RPTLB0, 580
RPTLB1, 581
RSIL, 582
RSQRT0.D, 583
RSQRT0.S, 584
RSR.*, 585
RSYNC, 586
RUR.*, 586
S8I, 587
S16I, 588
S32C1I, 589
S32E, 591
S32EX, 592
S32I, 594
S32I.N, 595
S32NB, 596
S32RI, 597
SALT, 599
SALTU, 600
SDDR32.P, 600
SDI, 601
SDIP, 602
SDX, 603
SDXP, 604
SEXT, 605
SICT, 606
SICW, 607
SIMCALL, 609
SLL, 609
SLLI, 610
SQRT0.D, 611
SQRT0.S, 612
SRA, 613
SRAI, 613
SRC, 614
SRL, 615
SRLI, 616
SSA8B, 616
SSA8L, 617
SSAI, 618
SSI, 619
SSIP, 620
SSIU, 621
SSL, 622
SSR, 623
SSX, 624
SSXP, 625
SSXU, 626
SUB, 627
SUB.D, 627
SUB.S, 628
SUBX2, 629
SUBX4, 629
SUBX8, 630
SYSCALL, 631
TRUNC.D, 632
TRUNC.S, 632
UEQ.D, 633
UEQ.S, 634
UFLOAT.D, 635
UFLOAT.S, 636
ULE.D, 636
ULE.S, 637
ULT.D, 638
ULT.S, 639
UMUL.AA.*, 639
UN.D, 640
UN.S, 641
UTRUNC.D, 642
UTRUNC.S, 642
WAITI, 643
WDTLB, 644
WER, 645
WFR, 646
WFRD, 647
WITLB, 648
WPTLB, 649
WSR.*, 650
WUR.*, 651
XOR, 652
XORB, 652
XSR.*, 653

View file

@ -1,57 +0,0 @@
<?xml version='1.0' encoding='ISO-8859-1' ?>
<!--
This is an XML file intended to be parsed by the Ghidra help system. It is loosely based
upon the JavaHelp table of contents document format. The Ghidra help system uses a
TOC_Source.xml file to allow a module with help to define how its contents appear in the
Ghidra help viewer's table of contents. The main document (in the Base module)
defines a basic structure for the
Ghidra table of contents system. Other TOC_Source.xml files may use this structure to insert
their files directly into this structure (and optionally define a substructure).
In this document, a tag can be either a <tocdef> or a <tocref>. The former is a definition
of an XML item that may have a link and may contain other <tocdef> and <tocref> children.
<tocdef> items may be referred to in other documents by using a <tocref> tag with the
appropriate id attribute value. Using these two tags allows any module to define a place
in the table of contents system (<tocdef>), which also provides a place for
other TOC_Source.xml files to insert content (<tocref>).
During the help build time, all TOC_Source.xml files will be parsed and validated to ensure
that all <tocref> tags point to valid <tocdef> tags. From these files will be generated
<module name>_TOC.xml files, which are table of contents files written in the format
desired by the JavaHelp system. Additionally, the genated files will be merged together
as they are loaded by the JavaHelp system. In the end, when displaying help in the Ghidra
help GUI, there will be on table of contents that has been created from the definitions in
all of the modules' TOC_Source.xml files.
Tags and Attributes
<tocdef>
-id - the name of the definition (this must be unique across all TOC_Source.xml files)
-text - the display text of the node, as seen in the help GUI
-target** - the file to display when the node is clicked in the GUI
-sortgroup - this is a string that defines where a given node should appear under a given
parent. The string values will be sorted by the JavaHelp system using
a javax.text.RulesBasedCollator. If this attribute is not specified, then
the text of attribute will be used.
<tocref>
-id - The id of the <tocdef> that this reference points to
**The URL for the target is relative and should start with 'help/topics'. This text is
used by the Ghidra help system to provide a universal starting point for all links so that
they can be resolved at runtime, across modules.
-->
<tocroot>
<!-- Uncomment and adjust fields to add help topic to help system's Table of Contents
<tocref id="Ghidra Functionality">
<tocdef id="HelpAnchor" text="My Feature" target="help/topics/my_topic/help.html" />
</tocref>
-->
</tocroot>

View file

@ -1,23 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML>
<HEAD>
<META name="generator" content=
"HTML Tidy for Java (vers. 2009-12-01), see jtidy.sourceforge.net">
<META http-equiv="Content-Language" content="en-us">
<META http-equiv="Content-Type" content="text/html; charset=windows-1252">
<META name="GENERATOR" content="Microsoft FrontPage 4.0">
<META name="ProgId" content="FrontPage.Editor.Document">
<TITLE>Skeleton Help File for a Module</TITLE>
<LINK rel="stylesheet" type="text/css" href="help/shared/DefaultStyle.css">
</HEAD>
<BODY>
<H1><a name="HelpAnchor"></a>Skeleton Help File for a Module</H1>
<P>This is a simple skeleton help topic. For a better description of what should and should not
go in here, see the "sample" Ghidra extension in the Extensions/Ghidra directory, or see your
favorite help topic. In general, language modules do not have their own help topics.</P>
</BODY>
</HTML>

View file

@ -1,3 +1,18 @@
/* ###
* 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.app.util.bin.format.elf.relocation; package ghidra.app.util.bin.format.elf.relocation;
public class Xtensa_ElfRelocationConstants { public class Xtensa_ElfRelocationConstants {

View file

@ -1,9 +1,21 @@
/* ###
* 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.app.util.bin.format.elf.relocation; package ghidra.app.util.bin.format.elf.relocation;
import ghidra.app.util.bin.format.elf.ElfConstants; import ghidra.app.util.bin.format.elf.*;
import ghidra.app.util.bin.format.elf.ElfHeader;
import ghidra.app.util.bin.format.elf.ElfRelocation;
import ghidra.app.util.bin.format.elf.ElfSymbol;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.listing.Program; import ghidra.program.model.listing.Program;
import ghidra.program.model.mem.MemoryAccessException; import ghidra.program.model.mem.MemoryAccessException;
@ -15,24 +27,25 @@ public class Xtensa_ElfRelocationHandler extends ElfRelocationHandler {
@Override @Override
public boolean canRelocate(ElfHeader elf) { public boolean canRelocate(ElfHeader elf) {
return elf.e_machine() == ElfConstants.EM_XTENSA || return elf.e_machine() == ElfConstants.EM_XTENSA ||
elf.e_machine() == Xtensa_ElfRelocationConstants.EM_XTENSA_OLD; elf.e_machine() == Xtensa_ElfRelocationConstants.EM_XTENSA_OLD;
} }
@Override @Override
public RelocationResult relocate(ElfRelocationContext elfRelocationContext, ElfRelocation relocation, Address relocationAddress) public RelocationResult relocate(ElfRelocationContext elfRelocationContext,
ElfRelocation relocation, Address relocationAddress)
throws MemoryAccessException, NotFoundException { throws MemoryAccessException, NotFoundException {
ElfHeader elf = elfRelocationContext.getElfHeader(); ElfHeader elf = elfRelocationContext.getElfHeader();
if (!canRelocate(elf)) { if (!canRelocate(elf)) {
return RelocationResult.FAILURE; return RelocationResult.FAILURE;
} }
int type=relocation.getType(); int type = relocation.getType();
if (Xtensa_ElfRelocationConstants.R_XTENSA_NONE == type) { if (Xtensa_ElfRelocationConstants.R_XTENSA_NONE == type) {
return RelocationResult.FAILURE; return RelocationResult.SKIPPED;
} }
Program program = elfRelocationContext.getProgram(); Program program = elfRelocationContext.getProgram();
ElfSymbol sym = null; ElfSymbol sym = null;
String symbolName = null; String symbolName = null;
@ -47,243 +60,150 @@ public class Xtensa_ElfRelocationHandler extends ElfRelocationHandler {
//int byteLength = 4; // most relocations affect 4-bytes (change if different) //int byteLength = 4; // most relocations affect 4-bytes (change if different)
switch(type) { switch (type) {
case Xtensa_ElfRelocationConstants.R_XTENSA_32: case Xtensa_ElfRelocationConstants.R_XTENSA_32:
markAsWarning(program, relocationAddress, "R_XTENSA_32", markAsWarning(program, relocationAddress, "R_XTENSA_32", symbolName, symbolIndex,
symbolName, symbolIndex, "TODO, needs support ", "TODO, needs support ", elfRelocationContext.getLog());
case Xtensa_ElfRelocationConstants.R_XTENSA_RTLD:
markAsWarning(program, relocationAddress, "R_XTENSA_RTLD", symbolName, symbolIndex,
"TODO, needs support ", elfRelocationContext.getLog());
case Xtensa_ElfRelocationConstants.R_XTENSA_GLOB_DAT:
markAsWarning(program, relocationAddress, "R_XTENSA_GLOB_DAT", symbolName,
symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
case Xtensa_ElfRelocationConstants.R_XTENSA_JMP_SLOT:
markAsWarning(program, relocationAddress, "R_XTENSA_JMP_SLOT", symbolName,
symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
case Xtensa_ElfRelocationConstants.R_XTENSA_RELATIVE:
markAsWarning(program, relocationAddress, "R_XTENSA_RELATIVE", symbolName,
symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
case Xtensa_ElfRelocationConstants.R_XTENSA_PLT:
markAsWarning(program, relocationAddress, "R_XTENSA_PLT", symbolName, symbolIndex,
"TODO, needs support ", elfRelocationContext.getLog());
case Xtensa_ElfRelocationConstants.R_XTENSA_OP0:
markAsWarning(program, relocationAddress, "R_XTENSA_OP0", symbolName, symbolIndex,
"TODO, needs support ", elfRelocationContext.getLog());
case Xtensa_ElfRelocationConstants.R_XTENSA_OP1:
markAsWarning(program, relocationAddress, "R_XTENSA_OP1", symbolName, symbolIndex,
"TODO, needs support ", elfRelocationContext.getLog());
case Xtensa_ElfRelocationConstants.R_XTENSA_OP2:
markAsWarning(program, relocationAddress, "R_XTENSA_OP2", symbolName, symbolIndex,
"TODO, needs support ", elfRelocationContext.getLog());
case Xtensa_ElfRelocationConstants.R_XTENSA_ASM_EXPAND:
markAsWarning(program, relocationAddress, "R_XTENSA_ASM_EXPAND", symbolName,
symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
case Xtensa_ElfRelocationConstants.R_XTENSA_ASM_SIMPLIFY:
markAsWarning(program, relocationAddress, "R_XTENSA_ASM_SIMPLIFY", symbolName,
symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
case Xtensa_ElfRelocationConstants.R_XTENSA_GNU_VTINHERIT:
markAsWarning(program, relocationAddress, "R_XTENSA_GNU_VTINHERIT", symbolName,
symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
case Xtensa_ElfRelocationConstants.R_XTENSA_GNU_VTENTRY:
markAsWarning(program, relocationAddress, "R_XTENSA_GNU_VTENTRY", symbolName,
symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
case Xtensa_ElfRelocationConstants.R_XTENSA_DIFF8:
markAsWarning(program, relocationAddress, "R_XTENSA_DIFF8", symbolName, symbolIndex,
"TODO, needs support ", elfRelocationContext.getLog());
case Xtensa_ElfRelocationConstants.R_XTENSA_DIFF16:
markAsWarning(program, relocationAddress, "R_XTENSA_DIFF16", symbolName,
symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
case Xtensa_ElfRelocationConstants.R_XTENSA_DIFF32:
markAsWarning(program, relocationAddress, "R_XTENSA_DIFF32", symbolName,
symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT0_OP:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT0_OP", symbolName,
symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT1_OP:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT1_OP", symbolName,
symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT2_OP:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT2_OP", symbolName,
symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT3_OP:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT3_OP", symbolName,
symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT4_OP:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT4_OP", symbolName,
symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT5_OP:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT5_OP", symbolName,
symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT6_OP:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT6_OP", symbolName,
symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT7_OP:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT7_OP", symbolName,
symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT8_OP:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT8_OP", symbolName,
symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT9_OP:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT9_OP", symbolName,
symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT10_OP:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT10_OP", symbolName,
symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT11_OP:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT11_OP", symbolName,
symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT12_OP:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT12_OP", symbolName,
symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT13_OP:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT13_OP", symbolName,
symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT14_OP:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT14_OP", symbolName,
symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT0_ALT:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT0_ALT", symbolName,
symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT1_ALT:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT1_ALT", symbolName,
symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT2_ALT:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT2_ALT", symbolName,
symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT3_ALT:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT3_ALT", symbolName,
symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT4_ALT:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT4_ALT", symbolName,
symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT5_ALT:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT5_ALT", symbolName,
symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT6_ALT:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT6_ALT", symbolName,
symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT7_ALT:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT7_ALT", symbolName,
symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT8_ALT:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT8_ALT", symbolName,
symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT9_ALT:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT9_ALT", symbolName,
symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT10_ALT:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT10_ALT", symbolName,
symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT11_ALT:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT11_ALT", symbolName,
symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT12_ALT:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT12_ALT", symbolName,
symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT13_ALT:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT13_ALT", symbolName,
symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT14_ALT:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT14_ALT", symbolName,
symbolIndex, "TODO, needs support ", elfRelocationContext.getLog());
default:
markAsUnhandled(program, relocationAddress, type, symbolIndex, symbolName,
elfRelocationContext.getLog()); elfRelocationContext.getLog());
return RelocationResult.UNSUPPORTED;
case Xtensa_ElfRelocationConstants.R_XTENSA_RTLD:
markAsWarning(program, relocationAddress, "R_XTENSA_RTLD",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
return RelocationResult.UNSUPPORTED;
case Xtensa_ElfRelocationConstants.R_XTENSA_GLOB_DAT:
markAsWarning(program, relocationAddress, "R_XTENSA_GLOB_DAT",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
return RelocationResult.UNSUPPORTED;
case Xtensa_ElfRelocationConstants.R_XTENSA_JMP_SLOT:
markAsWarning(program, relocationAddress, "R_XTENSA_JMP_SLOT",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
return RelocationResult.UNSUPPORTED;
case Xtensa_ElfRelocationConstants.R_XTENSA_RELATIVE:
markAsWarning(program, relocationAddress, "R_XTENSA_RELATIVE",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
return RelocationResult.UNSUPPORTED;
case Xtensa_ElfRelocationConstants.R_XTENSA_PLT:
markAsWarning(program, relocationAddress, "R_XTENSA_PLT",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
return RelocationResult.UNSUPPORTED;
case Xtensa_ElfRelocationConstants.R_XTENSA_OP0:
markAsWarning(program, relocationAddress, "R_XTENSA_OP0",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
return RelocationResult.UNSUPPORTED;
case Xtensa_ElfRelocationConstants.R_XTENSA_OP1:
markAsWarning(program, relocationAddress, "R_XTENSA_OP1",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
return RelocationResult.UNSUPPORTED;
case Xtensa_ElfRelocationConstants.R_XTENSA_OP2:
markAsWarning(program, relocationAddress, "R_XTENSA_OP2",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
return RelocationResult.UNSUPPORTED;
case Xtensa_ElfRelocationConstants.R_XTENSA_ASM_EXPAND:
markAsWarning(program, relocationAddress, "R_XTENSA_ASM_EXPAND",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
return RelocationResult.UNSUPPORTED;
case Xtensa_ElfRelocationConstants.R_XTENSA_ASM_SIMPLIFY:
markAsWarning(program, relocationAddress, "R_XTENSA_ASM_SIMPLIFY",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
return RelocationResult.UNSUPPORTED;
case Xtensa_ElfRelocationConstants.R_XTENSA_GNU_VTINHERIT:
markAsWarning(program, relocationAddress, "R_XTENSA_GNU_VTINHERIT",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
return RelocationResult.UNSUPPORTED;
case Xtensa_ElfRelocationConstants.R_XTENSA_GNU_VTENTRY:
markAsWarning(program, relocationAddress, "R_XTENSA_GNU_VTENTRY",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
return RelocationResult.UNSUPPORTED;
case Xtensa_ElfRelocationConstants.R_XTENSA_DIFF8:
markAsWarning(program, relocationAddress, "R_XTENSA_DIFF8",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
return RelocationResult.UNSUPPORTED;
case Xtensa_ElfRelocationConstants.R_XTENSA_DIFF16:
markAsWarning(program, relocationAddress, "R_XTENSA_DIFF16",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
return RelocationResult.UNSUPPORTED;
case Xtensa_ElfRelocationConstants.R_XTENSA_DIFF32:
markAsWarning(program, relocationAddress, "R_XTENSA_DIFF32",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
return RelocationResult.UNSUPPORTED;
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT0_OP:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT0_OP",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
return RelocationResult.UNSUPPORTED;
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT1_OP:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT1_OP",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
return RelocationResult.UNSUPPORTED;
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT2_OP:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT2_OP",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
return RelocationResult.UNSUPPORTED;
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT3_OP:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT3_OP",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
return RelocationResult.UNSUPPORTED;
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT4_OP:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT4_OP",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
return RelocationResult.UNSUPPORTED;
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT5_OP:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT5_OP",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
return RelocationResult.UNSUPPORTED;
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT6_OP:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT6_OP",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
return RelocationResult.UNSUPPORTED;
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT7_OP:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT7_OP",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
return RelocationResult.UNSUPPORTED;
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT8_OP:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT8_OP",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
return RelocationResult.UNSUPPORTED;
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT9_OP:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT9_OP",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
return RelocationResult.UNSUPPORTED;
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT10_OP:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT10_OP",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
return RelocationResult.UNSUPPORTED;
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT11_OP:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT11_OP",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
return RelocationResult.UNSUPPORTED;
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT12_OP:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT12_OP",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
return RelocationResult.UNSUPPORTED;
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT13_OP:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT13_OP",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
return RelocationResult.UNSUPPORTED;
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT14_OP:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT14_OP",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
return RelocationResult.UNSUPPORTED;
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT0_ALT:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT0_ALT",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
return RelocationResult.UNSUPPORTED;
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT1_ALT:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT1_ALT",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
return RelocationResult.UNSUPPORTED;
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT2_ALT:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT2_ALT",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
return RelocationResult.UNSUPPORTED;
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT3_ALT:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT3_ALT",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
return RelocationResult.UNSUPPORTED;
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT4_ALT:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT4_ALT",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
return RelocationResult.UNSUPPORTED;
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT5_ALT:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT5_ALT",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
return RelocationResult.UNSUPPORTED;
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT6_ALT:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT6_ALT",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
return RelocationResult.UNSUPPORTED;
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT7_ALT:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT7_ALT",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
return RelocationResult.UNSUPPORTED;
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT8_ALT:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT8_ALT",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
return RelocationResult.UNSUPPORTED;
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT9_ALT:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT9_ALT",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
return RelocationResult.UNSUPPORTED;
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT10_ALT:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT10_ALT",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
return RelocationResult.UNSUPPORTED;
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT11_ALT:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT11_ALT",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
return RelocationResult.UNSUPPORTED;
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT12_ALT:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT12_ALT",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
return RelocationResult.UNSUPPORTED;
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT13_ALT:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT13_ALT",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
return RelocationResult.UNSUPPORTED;
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT14_ALT:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT14_ALT",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
return RelocationResult.UNSUPPORTED;
default:
markAsUnhandled(program, relocationAddress, type, symbolIndex,
symbolName, elfRelocationContext.getLog());
return RelocationResult.SKIPPED;
} }
return RelocationResult.UNSUPPORTED;
} }
} }

View file

@ -0,0 +1,159 @@
/* ###
* 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.util.Stack;
import ghidra.pcode.emulate.Emulate;
import ghidra.pcode.emulate.EmulateInstructionStateModifier;
import ghidra.pcode.emulate.callother.OpBehaviorOther;
import ghidra.pcode.emulate.callother.OpBehaviorOtherNOP;
import ghidra.pcode.error.LowlevelError;
import ghidra.pcode.memstate.MemoryState;
import ghidra.program.model.address.Address;
import ghidra.program.model.lang.Register;
import ghidra.program.model.pcode.Varnode;
public class XtensaEmulateInstructionStateModifier extends EmulateInstructionStateModifier {
private Stack<RegisterStash> stashStack = new Stack<RegisterStash>();
public XtensaEmulateInstructionStateModifier(Emulate emu) {
super(emu);
registerPcodeOpBehavior("rotateRegWindow", new RotateRegWindow());
registerPcodeOpBehavior("restoreRegWindow", new RestoreRegWindow());
registerPcodeOpBehavior("swap4", new OpBehaviorOtherNOP());
registerPcodeOpBehavior("swap8", new OpBehaviorOtherNOP());
registerPcodeOpBehavior("swap12", new OpBehaviorOtherNOP());
registerPcodeOpBehavior("restore4", new OpBehaviorOtherNOP());
registerPcodeOpBehavior("restore8", new OpBehaviorOtherNOP());
registerPcodeOpBehavior("restore12", new OpBehaviorOtherNOP());
}
private class RotateRegWindow implements OpBehaviorOther {
@Override
public void evaluate(Emulate emu, Varnode out, Varnode[] inputs) {
if (inputs.length != 2) {
throw new LowlevelError("rotateRegWindow: missing required CALLINC input");
}
MemoryState memoryState = emu.getMemoryState();
Varnode in = inputs[1];
long callinc = memoryState.getValue(in);
if (callinc == 0) {
return;
}
if (callinc < 0 || callinc > 3) {
throw new LowlevelError("rotateRegWindow: invalid value for CALLINC (0x" +
Long.toHexString(callinc) + ")");
}
// push window onto stack
stashStack.push(new RegisterStash((int) callinc));
//rotate registers
Address baseARegAddr = language.getRegister("a0").getAddress();
int count = (int) callinc << 2; // windowSize
long windowRegOffset = count * 4;
count = 16 - count;
for (int i = 0; i < count; i++) {
Varnode fromRegVarnode =
new Varnode(baseARegAddr.add(windowRegOffset + (i * 4)), 4);
Varnode toRegVarnode = new Varnode(baseARegAddr.add(i * 4), 4);
long value = memoryState.getValue(fromRegVarnode);
memoryState.setValue(toRegVarnode, value);
}
}
}
private class RestoreRegWindow implements OpBehaviorOther {
@Override
public void evaluate(Emulate emu, Varnode out, Varnode[] inputs) {
if (inputs.length != 1) {
throw new LowlevelError("restoreRegWindow: unexpected input varnodes");
}
MemoryState memoryState = emu.getMemoryState();
Register a0Reg = language.getRegister("a0");
long callinc = (memoryState.getValue(a0Reg) >> 30) & 0x3;
if (callinc == 0) {
return;
}
if (stashStack.isEmpty()) {
throw new LowlevelError("restoreRegWindow: window register stash is empty");
}
RegisterStash stash = stashStack.peek();
if (callinc != stash.callinc) {
throw new LowlevelError("restoreRegWindow: return address CALLINC (" + callinc +
") does not match last entry CALLINC value (" + stash.callinc + ")");
}
//rotate registers
Address baseARegAddr = language.getRegister("a0").getAddress();
int count = (int) callinc << 2; // windowSize
long windowRegOffset = count * 4;
count = 16 - count;
for (int i = 0; i < count; i++) {
Varnode fromRegVarnode = new Varnode(baseARegAddr.add(i * 4), 4);
Varnode toRegVarnode = new Varnode(baseARegAddr.add(windowRegOffset + (i * 4)), 4);
long value = memoryState.getValue(fromRegVarnode);
memoryState.setValue(toRegVarnode, value);
}
// remove from stack and restore
stashStack.pop();
stash.restore();
}
}
private class RegisterStash {
private int callinc;
private int[] values;
RegisterStash(int callinc) {
this.callinc = callinc;
MemoryState memoryState = emu.getMemoryState();
Address baseARegAddr = language.getRegister("a0").getAddress();
int count = callinc << 2;
values = new int[count];
for (int i = 0; i < count; i++) {
Varnode regVarnode = new Varnode(baseARegAddr.add(4 * i), 4);
values[i] = (int) memoryState.getValue(regVarnode);
}
}
public void restore() {
MemoryState memoryState = emu.getMemoryState();
Address baseARegAddr = language.getRegister("a0").getAddress();
for (int i = 0; i < values.length; i++) {
Varnode regVarnode = new Varnode(baseARegAddr.add(4 * i), 4);
memoryState.setValue(regVarnode, values[i]);
}
}
}
}

View file

@ -1,3 +1,18 @@
/* ###
* 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; package ghidra.test.processors;
import ghidra.test.processors.support.ProcessorEmulatorTestAdapter; import ghidra.test.processors.support.ProcessorEmulatorTestAdapter;

View file

@ -1,3 +1,18 @@
/* ###
* 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; package ghidra.test.processors;
import ghidra.test.processors.support.ProcessorEmulatorTestAdapter; import ghidra.test.processors.support.ProcessorEmulatorTestAdapter;