Add Tensilica Xtensa processor support

This commit is contained in:
Sebastian Schmidt 2020-01-03 16:14:17 +01:00 committed by ghidra1
parent ee64b89314
commit 245627846e
17 changed files with 2425 additions and 0 deletions

View file

@ -663,3 +663,12 @@ PCodeTest({
'has_double': 0,
'has_longlong': 0,
})
PCodeTest({
'name': 'Xtensa',
'build_all': 1,
'build_exe': 1,
'toolchain': 'Xtensa/xtensa-lx106-elf',
'language_id': 'Xtensa:LE:32:default',
'ccflags': '-L %(toolchain_dir)s/lib/gcc/xtensa-lx106-elf/%(gcc_version)s -lgcc',
})

View file

View file

@ -0,0 +1,11 @@
apply from: "$rootProject.projectDir/gradle/distributableGhidraModule.gradle"
apply from: "$rootProject.projectDir/gradle/javaProject.gradle"
apply from: "$rootProject.projectDir/gradle/javaTestProject.gradle"
apply from: "$rootProject.projectDir/gradle/processorProject.gradle"
apply plugin: 'eclipse'
eclipse.project.name = 'Processors Xtensa'
dependencies {
compile project(':Base')
}

View file

@ -0,0 +1,80 @@
<?xml version="1.0" encoding="UTF-8"?>
<compiler_spec>
<data_organization>
<absolute_max_alignment value="0" />
<machine_alignment value="2" />
<default_alignment value="1" />
<default_pointer_alignment value="4" />
<pointer_size value="4" />
<wchar_size value="4" />
<short_size value="2" />
<integer_size value="4" />
<long_size value="4" />
<long_long_size value="8" />
<float_size value="4" />
<double_size value="8" />
<long_double_size value="8" />
<size_alignment_map>
<entry size="1" alignment="1" />
<entry size="2" alignment="2" />
<entry size="4" alignment="4" />
<entry size="8" alignment="8" />
</size_alignment_map>
</data_organization>
<global>
<range space="ram"/>
</global>
<stackpointer register="a1" space="ram"/>
<default_proto>
<prototype name="__stdcall" 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>
<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>
</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>
</compiler_spec>

View file

@ -0,0 +1,7 @@
<dwarf>
<register_mappings>
<register_mapping dwarf="0" ghidra="a0"/>
<register_mapping dwarf="1" ghidra="a1" stackpointer="true"/>
<register_mapping dwarf="2" ghidra="a2" auto_count="14"/> <!-- a2..a15 -->
</register_mappings>
</dwarf>

View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<language_definitions>
<language processor="Xtensa"
endian="little"
size="32"
variant="default"
version="1.0"
slafile="xtensa.sla"
processorspec="xtensa.pspec"
manualindexfile="../manuals/xtensa.idx"
id="Xtensa:LE:32:default">
<description>Tensilica Xtensa 32-bit little-endian</description>
<compiler name="default" spec="xtensa.cspec" id="default"/>
<external_name tool="DWARF.register.mapping.file" name="xtensa.dwarf"/>
</language>
</language_definitions>

View file

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

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<processor_spec>
<programcounter register="pc"/>
</processor_spec>

View file

@ -0,0 +1,275 @@
define endian=little;
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
];
# Floating Point registers (FR + FCR (control) + FSR (status)).
# TODO: FCR and FSR seem unused?
define register offset=0x0100 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=0x0200 size=1 [
b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15
];
# Program counter.
define register offset=0x1000 size=4 [ pc ];
# Shift amount register. (TODO: other special registers)
define register offset=0x2000 size=1 [ sar ];
# 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)
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)
;
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.
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 | 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; }
# 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 nsa;
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

@ -0,0 +1,3 @@
@include "xtensa.sinc"
@include "xtensaInstructions.sinc"
@include "xtensaTodo.sinc"

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,66 @@
## 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,242 @@
@xtensa.pdf[Xtensa® Instruction Set Architecture (ISA) Reference Manual, April 2010]
b4const(ar), 65
b4constu(ar), 66
call4, 322
call8, 324
call12, 326
callx4, 329
callx8, 331
callx12, 332
entry, 364
l32e, 400
movsp, 451
retw, 504
retw.n, 506
rotw, 520
s32e, 532
lddec, 410
ldinc, 411
mula.aa.*, 455
loop, 416
loopgtz, 418
loopnez, 420
abs, 270
abs.s, 271
add, 272
add.n, 273
add.s, 274
addi, 275
addi.n, 276
addmi, 277
addx2, 278
addx4, 279
addx8, 280
all4, 281
all8, 282
and, 283
andb, 284
andbc, 285
any4, 286
any8, 287
ball, 288
bany, 289
bbc, 290
bbci, 291
bbs, 293
bbsi, 294
beq, 296
beqi, 297
beqz, 298
beqz.n, 299
bf, 300
bge, 301
bgei, 302
bgeu, 303
bgeui, 304
bgez, 305
blt, 306
blti, 307
bltu, 308
bltui, 309
bltz, 310
bnall, 311
bne, 312
bnei, 313
bnez, 314
bnez.n, 315
bnone, 316
break, 317
break.n, 319
bt, 320
call0, 321
callx0, 328
ceil.s, 335
clamps, 336
dhi, 337
dhu, 339
dhwb, 341
dhwbi, 343
dii, 345
diu, 347
diwb, 349
diwbi, 351
dpfl, 353
dpfr, 355
dpfro, 357
dpfw, 359
dpfwo, 361
dsync, 363
esync, 366
excw, 367
extui, 368
extw, 369
float.s, 370
floor.s, 371
idtlb, 372
ihi, 373
ihu, 375
iii, 377
iitlb, 379
iiu, 380
ill, 382
ill.n, 383
ipf, 384
ipfl, 386
isync, 388
j, 390
ret, 502
jx, 392
l8ui, 393
l16si, 394
l16ui, 396
l32ai, 398
l32i, 402
l32i.n, 404
l32r, 406
ldct, 408
lict, 412
licw, 414
lsi, 422
lsiu, 424
lsx, 426
lsxu, 428
madd.s, 430
max, 431
maxu, 432
memw, 433
min, 434
minu, 435
mov.n, 437
mov.s, 438
moveqz, 439
moveqz.s, 440
movf, 441
movf.s, 442
movgez, 443
movgez.s, 444
movi, 445
movi.n, 446
movltz, 447
movltz.s, 448
movnez, 449
movnez.s, 450
movt, 452
movt.s, 453
msub.s, 454
mul.s, 459
mul16s, 460
mul16u, 461
mull, 474
mulsh, 479
muluh, 480
neg, 481
neg.s, 482
nop, 483
nop.n, 484
nsa, 485
nsau, 486
oeq.s, 487
ole.s, 488
olt.s, 489
mov, 436
or, 490
orb, 491
orbc, 492
pdtlb, 493
pitlb, 494
quos, 495
quou, 496
rdtlb0, 497
rdtlb1, 498
rems, 499
remu, 500
rer, 501
ret.n, 503
rfdd, 508
rfde, 509
rfdo, 510
rfe, 511
rfi, 512
rfme, 513
rfr, 514
rfue, 515
rfwo, 516
rfwu, 517
ritlb0, 518
ritlb1, 519
round.s, 521
rsil, 522
rsr, 524
rsync, 526
rur, 527
s8i, 528
s16i, 529
s32c1i, 530
s32i, 534
s32i.n, 536
s32ri, 538
sdct, 540
sext, 542
sict, 543
sicw, 545
simcall, 547
sll, 548
slli, 549
sra, 550
srai, 551
src, 552
srl, 553
srli, 554
ssa8b, 555
ssa8l, 556
ssai, 557
ssi, 558
ssiu, 560
ssl, 562
ssr, 563
ssx, 564
ssxu, 565
sub, 566
sub.s, 567
subx2, 568
subx4, 569
subx8, 570
syscall, 571
trunc.s, 572
ueq.s, 573
ufloat.s, 574
ule.s, 575
ult.s, 576
un.s, 578
utrunc.s, 579
waiti, 580
wdtlb, 581
wer, 582
wfr, 583
witlb, 584
wsr, 585
wur, 587
xor, 588
xorb, 589
xsr, 590

View file

@ -0,0 +1,58 @@
package ghidra.app.util.bin.format.elf.relocation;
public class Xtensa_ElfRelocationConstants {
/* Xtensa processor ELF architecture-magic number */
// EM_XTENSA is already definded
public static final int EM_XTENSA_OLD = 0xABC7;
/* Xtensa relocations defined by the ABIs */
public static final int R_XTENSA_NONE = 0;
public static final int R_XTENSA_32 = 1;
public static final int R_XTENSA_RTLD = 2;
public static final int R_XTENSA_GLOB_DAT = 3;
public static final int R_XTENSA_JMP_SLOT = 4;
public static final int R_XTENSA_RELATIVE = 5;
public static final int R_XTENSA_PLT = 6;
public static final int R_XTENSA_OP0 = 8;
public static final int R_XTENSA_OP1 = 9;
public static final int R_XTENSA_OP2 = 10;
public static final int R_XTENSA_ASM_EXPAND = 11;
public static final int R_XTENSA_ASM_SIMPLIFY = 12;
public static final int R_XTENSA_GNU_VTINHERIT = 15;
public static final int R_XTENSA_GNU_VTENTRY = 16;
public static final int R_XTENSA_DIFF8 = 17;
public static final int R_XTENSA_DIFF16 = 18;
public static final int R_XTENSA_DIFF32 = 19;
public static final int R_XTENSA_SLOT0_OP = 20;
public static final int R_XTENSA_SLOT1_OP = 21;
public static final int R_XTENSA_SLOT2_OP = 22;
public static final int R_XTENSA_SLOT3_OP = 23;
public static final int R_XTENSA_SLOT4_OP = 24;
public static final int R_XTENSA_SLOT5_OP = 25;
public static final int R_XTENSA_SLOT6_OP = 26;
public static final int R_XTENSA_SLOT7_OP = 27;
public static final int R_XTENSA_SLOT8_OP = 28;
public static final int R_XTENSA_SLOT9_OP = 29;
public static final int R_XTENSA_SLOT10_OP = 30;
public static final int R_XTENSA_SLOT11_OP = 31;
public static final int R_XTENSA_SLOT12_OP = 32;
public static final int R_XTENSA_SLOT13_OP = 33;
public static final int R_XTENSA_SLOT14_OP = 34;
public static final int R_XTENSA_SLOT0_ALT = 35;
public static final int R_XTENSA_SLOT1_ALT = 36;
public static final int R_XTENSA_SLOT2_ALT = 37;
public static final int R_XTENSA_SLOT3_ALT = 38;
public static final int R_XTENSA_SLOT4_ALT = 39;
public static final int R_XTENSA_SLOT5_ALT = 40;
public static final int R_XTENSA_SLOT6_ALT = 41;
public static final int R_XTENSA_SLOT7_ALT = 42;
public static final int R_XTENSA_SLOT8_ALT = 43;
public static final int R_XTENSA_SLOT9_ALT = 44;
public static final int R_XTENSA_SLOT10_ALT = 45;
public static final int R_XTENSA_SLOT11_ALT = 46;
public static final int R_XTENSA_SLOT12_ALT = 47;
public static final int R_XTENSA_SLOT13_ALT = 48;
public static final int R_XTENSA_SLOT14_ALT = 49;
}

View file

@ -0,0 +1,292 @@
package ghidra.app.util.bin.format.elf.relocation;
import ghidra.app.util.bin.format.elf.ElfConstants;
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.listing.Program;
import ghidra.program.model.mem.Memory;
import ghidra.program.model.mem.MemoryAccessException;
import ghidra.util.exception.NotFoundException;
public class Xtensa_ElfRelocationHandler extends ElfRelocationHandler {
@Override
public boolean canRelocate(ElfHeader elf) {
return elf.e_machine() == ElfConstants.EM_XTENSA ||
elf.e_machine() == Xtensa_ElfRelocationConstants.EM_XTENSA_OLD;
}
@Override
public void relocate(ElfRelocationContext elfRelocationContext, ElfRelocation relocation, Address relocationAddress)
throws MemoryAccessException, NotFoundException {
ElfHeader elf = elfRelocationContext.getElfHeader();
if (!canRelocate(elf)) {
return;
}
int type=relocation.getType();
if (Xtensa_ElfRelocationConstants.R_XTENSA_NONE == type) {
return;
}
Program program = elfRelocationContext.getProgram();
Memory memory = program.getMemory();
long addend = relocation.hasAddend() ? relocation.getAddend() : memory.getInt(relocationAddress);
long offset = relocationAddress.getOffset();
long base = elfRelocationContext.getImageBaseWordAdjustmentOffset();
ElfSymbol sym = null;
long symbolValue = 0;
String symbolName = null;
int symbolIndex = relocation.getSymbolIndex();
if (symbolIndex != 0) {
sym = elfRelocationContext.getSymbol(symbolIndex);
}
if (null != sym) {
symbolValue = elfRelocationContext.getSymbolValue(sym);
symbolName = sym.getNameAsString();
}
switch(type) {
case Xtensa_ElfRelocationConstants.R_XTENSA_32:
markAsWarning(program, relocationAddress, "R_XTENSA_32",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
break;
case Xtensa_ElfRelocationConstants.R_XTENSA_RTLD:
markAsWarning(program, relocationAddress, "R_XTENSA_RTLD",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
break;
case Xtensa_ElfRelocationConstants.R_XTENSA_GLOB_DAT:
markAsWarning(program, relocationAddress, "R_XTENSA_GLOB_DAT",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
break;
case Xtensa_ElfRelocationConstants.R_XTENSA_JMP_SLOT:
markAsWarning(program, relocationAddress, "R_XTENSA_JMP_SLOT",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
break;
case Xtensa_ElfRelocationConstants.R_XTENSA_RELATIVE:
markAsWarning(program, relocationAddress, "R_XTENSA_RELATIVE",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
break;
case Xtensa_ElfRelocationConstants.R_XTENSA_PLT:
markAsWarning(program, relocationAddress, "R_XTENSA_PLT",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
break;
case Xtensa_ElfRelocationConstants.R_XTENSA_OP0:
markAsWarning(program, relocationAddress, "R_XTENSA_OP0",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
break;
case Xtensa_ElfRelocationConstants.R_XTENSA_OP1:
markAsWarning(program, relocationAddress, "R_XTENSA_OP1",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
break;
case Xtensa_ElfRelocationConstants.R_XTENSA_OP2:
markAsWarning(program, relocationAddress, "R_XTENSA_OP2",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
break;
case Xtensa_ElfRelocationConstants.R_XTENSA_ASM_EXPAND:
markAsWarning(program, relocationAddress, "R_XTENSA_ASM_EXPAND",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
break;
case Xtensa_ElfRelocationConstants.R_XTENSA_ASM_SIMPLIFY:
markAsWarning(program, relocationAddress, "R_XTENSA_ASM_SIMPLIFY",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
break;
case Xtensa_ElfRelocationConstants.R_XTENSA_GNU_VTINHERIT:
markAsWarning(program, relocationAddress, "R_XTENSA_GNU_VTINHERIT",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
break;
case Xtensa_ElfRelocationConstants.R_XTENSA_GNU_VTENTRY:
markAsWarning(program, relocationAddress, "R_XTENSA_GNU_VTENTRY",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
break;
case Xtensa_ElfRelocationConstants.R_XTENSA_DIFF8:
markAsWarning(program, relocationAddress, "R_XTENSA_DIFF8",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
break;
case Xtensa_ElfRelocationConstants.R_XTENSA_DIFF16:
markAsWarning(program, relocationAddress, "R_XTENSA_DIFF16",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
break;
case Xtensa_ElfRelocationConstants.R_XTENSA_DIFF32:
markAsWarning(program, relocationAddress, "R_XTENSA_DIFF32",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
break;
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT0_OP:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT0_OP",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
break;
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT1_OP:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT1_OP",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
break;
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT2_OP:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT2_OP",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
break;
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT3_OP:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT3_OP",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
break;
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT4_OP:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT4_OP",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
break;
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT5_OP:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT5_OP",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
break;
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT6_OP:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT6_OP",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
break;
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT7_OP:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT7_OP",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
break;
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT8_OP:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT8_OP",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
break;
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT9_OP:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT9_OP",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
break;
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT10_OP:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT10_OP",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
break;
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT11_OP:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT11_OP",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
break;
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT12_OP:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT12_OP",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
break;
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT13_OP:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT13_OP",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
break;
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT14_OP:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT14_OP",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
break;
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT0_ALT:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT0_ALT",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
break;
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT1_ALT:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT1_ALT",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
break;
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT2_ALT:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT2_ALT",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
break;
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT3_ALT:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT3_ALT",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
break;
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT4_ALT:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT4_ALT",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
break;
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT5_ALT:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT5_ALT",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
break;
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT6_ALT:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT6_ALT",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
break;
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT7_ALT:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT7_ALT",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
break;
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT8_ALT:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT8_ALT",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
break;
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT9_ALT:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT9_ALT",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
break;
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT10_ALT:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT10_ALT",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
break;
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT11_ALT:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT11_ALT",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
break;
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT12_ALT:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT12_ALT",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
break;
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT13_ALT:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT13_ALT",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
break;
case Xtensa_ElfRelocationConstants.R_XTENSA_SLOT14_ALT:
markAsWarning(program, relocationAddress, "R_XTENSA_SLOT14_ALT",
symbolName, symbolIndex, "TODO, needs support ",
elfRelocationContext.getLog());
break;
default:
markAsUnhandled(program, relocationAddress, type, symbolIndex,
symbolName, elfRelocationContext.getLog());
break;
}
}
}

View file

@ -0,0 +1,25 @@
package ghidra.test.processors;
import ghidra.test.processors.support.ProcessorEmulatorTestAdapter;
import junit.framework.Test;
public class Xtensa_O0_EmulatorTest extends ProcessorEmulatorTestAdapter {
private static final String LANGUAGE_ID = "Xtensa:LE:32:default";
private static final String COMPILER_SPEC_ID = "default";
private static final String[] REG_DUMP_SET = new String[] {};
public Xtensa_O0_EmulatorTest(String name) throws Exception {
super(name, LANGUAGE_ID, COMPILER_SPEC_ID, REG_DUMP_SET);
}
@Override
protected String getProcessorDesignator() {
return "Xtensa_GCC_O0";
}
public static Test suite() {
return ProcessorEmulatorTestAdapter.buildEmulatorTestSuite(Xtensa_O0_EmulatorTest.class);
}
}

View file

@ -0,0 +1,25 @@
package ghidra.test.processors;
import ghidra.test.processors.support.ProcessorEmulatorTestAdapter;
import junit.framework.Test;
public class Xtensa_O3_EmulatorTest extends ProcessorEmulatorTestAdapter {
private static final String LANGUAGE_ID = "Xtensa:LE:32:default";
private static final String COMPILER_SPEC_ID = "default";
private static final String[] REG_DUMP_SET = new String[] {};
public Xtensa_O3_EmulatorTest(String name) throws Exception {
super(name, LANGUAGE_ID, COMPILER_SPEC_ID, REG_DUMP_SET);
}
@Override
protected String getProcessorDesignator() {
return "Xtensa_GCC_O3";
}
public static Test suite() {
return ProcessorEmulatorTestAdapter.buildEmulatorTestSuite(Xtensa_O3_EmulatorTest.class);
}
}