forked from yath/ghidra-xtensa
Compare commits
24 Commits
various-im
...
master
Author | SHA1 | Date | |
---|---|---|---|
e307f72005 | |||
fa550ba9d2 | |||
08cb358913 | |||
109a4649fe | |||
cf8aa3fed9 | |||
e4823d14bb | |||
94c353ae9d | |||
e8182f4460 | |||
0b73145bcc | |||
4bbf6bc542 | |||
b13b4d64ee | |||
6fe915e8d0 | |||
2169d80370 | |||
83112e48da | |||
33ca0710c9 | |||
1eb0067abe | |||
fb39ee087a | |||
c21f1866e7 | |||
f0faee57e4 | |||
9a837fe2dd | |||
66fc608881 | |||
868699f570 | |||
210fe20433 | |||
c60fbd02e4 |
11
build.gradle
Normal file
11
build.gradle
Normal file
@ -0,0 +1,11 @@
|
||||
def ghidraDir
|
||||
|
||||
if (System.env.GHIDRA_DIR) {
|
||||
ghidraDir = System.env.GHIDRA_DIR
|
||||
} else if (project.hasProperty("GHIDRA_DIR")) {
|
||||
ghidraDir = project.getProperty("GHIDRA_DIR")
|
||||
} else {
|
||||
throw new GradleException("GHIDRA_DIR is not defined!")
|
||||
}
|
||||
|
||||
apply from: new File(ghidraDir).getCanonicalPath() + "/support/buildExtension.gradle"
|
@ -55,14 +55,14 @@
|
||||
<pentry minsize="1" maxsize="4" extension="inttype">
|
||||
<register name="a2"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4" extension="inttype">
|
||||
<register name="a3"/>
|
||||
<pentry minsize="5" maxsize="8" extension="inttype">
|
||||
<addr space="join" piece1="a3" piece2="a2"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4" extension="inttype">
|
||||
<register name="a4"/>
|
||||
<pentry minsize="9" maxsize="12" extension="inttype">
|
||||
<addr space="join" piece1="a4" piece2="a3" piece3="a2"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4" extension="inttype">
|
||||
<register name="a5"/>
|
||||
<pentry minsize="13" maxsize="16" extension="inttype">
|
||||
<addr space="join" piece1="a5" piece2="a4" piece3="a3" piece4="a2"/>
|
||||
</pentry>
|
||||
</output>
|
||||
<returnaddress>
|
||||
|
@ -2,6 +2,6 @@
|
||||
<register_mappings>
|
||||
<register_mapping dwarf="0" ghidra="a0"/>
|
||||
<register_mapping dwarf="1" ghidra="a1" stackpointer="true"/>
|
||||
<register_mapping dwarf="2" ghidra="a2" auto_count="13"/> <!-- a2..a15 -->
|
||||
<register_mapping dwarf="2" ghidra="a2" auto_count="14"/> <!-- a2..a15 -->
|
||||
</register_mappings>
|
||||
</dwarf>
|
||||
|
@ -4,28 +4,59 @@ 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 ];
|
||||
|
||||
# Address registers (AR).
|
||||
define register offset=0x0000 size=4 [
|
||||
define register offset=0x8000 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 [
|
||||
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=0x0200 size=1 [
|
||||
define register offset=0x8200 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 ];
|
||||
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)
|
||||
@ -37,6 +68,7 @@ define token insn(24)
|
||||
as = (8,11)
|
||||
fs = (8,11)
|
||||
bs = (8,11)
|
||||
sr = (8,15)
|
||||
at = (4,7)
|
||||
ft = (4,7)
|
||||
bt = (4,7)
|
||||
@ -67,7 +99,7 @@ define token insn(24)
|
||||
u1_12 = (12,12)
|
||||
u4_8.11 = (8,11)
|
||||
u8_4.11 = (4,11)
|
||||
# s4_8.11 = (8,11) signed
|
||||
s4_8.11 = (8,11) signed
|
||||
u2_6.7 = (6,7)
|
||||
u3_5.7 = (5,7)
|
||||
u4_4.7 = (4,7)
|
||||
@ -94,6 +126,78 @@ define token narrowinsn(16)
|
||||
|
||||
;
|
||||
|
||||
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
|
||||
];
|
||||
@ -138,11 +242,8 @@ u5_4.7_12: tmp is u1_12 & u4_4.7 [ tmp = (u1_12 << 4) | u4_4.7; ] { export *
|
||||
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 u4_8.11 & u8_16.23 [
|
||||
# FIXME: This table, and the fields used, should be signed, but using s4_8.11 and s8_16.23
|
||||
# somehow confuses Ghidra.
|
||||
tmp = (0xf000 * (u4_8.11 >> 3)) | # Sign-extend.
|
||||
(u4_8.11 << 8) | u8_16.23;
|
||||
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.
|
||||
@ -167,25 +268,14 @@ n_u6_12.15_sb2: tmp is n_u4_12.15 [ tmp = n_u4_12.15 << 2; ] { export *[const]:
|
||||
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 can’t be (easily) expressed in a single disassembly action.
|
||||
# FIXME: “foo: tmp is u4_foo [ tmp = u4_foo; ]” doesn’t work when a more special constructor exists.
|
||||
|
||||
# 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 = 1 [ tmp = 1; ] { export *[const]:4 tmp; }
|
||||
n_s4_4.7_nozero: tmp is n_u4_4.7 = 2 [ tmp = 2; ] { export *[const]:4 tmp; }
|
||||
n_s4_4.7_nozero: tmp is n_u4_4.7 = 3 [ tmp = 3; ] { export *[const]:4 tmp; }
|
||||
n_s4_4.7_nozero: tmp is n_u4_4.7 = 4 [ tmp = 4; ] { export *[const]:4 tmp; }
|
||||
n_s4_4.7_nozero: tmp is n_u4_4.7 = 5 [ tmp = 5; ] { export *[const]:4 tmp; }
|
||||
n_s4_4.7_nozero: tmp is n_u4_4.7 = 6 [ tmp = 6; ] { export *[const]:4 tmp; }
|
||||
n_s4_4.7_nozero: tmp is n_u4_4.7 = 7 [ tmp = 7; ] { export *[const]:4 tmp; }
|
||||
n_s4_4.7_nozero: tmp is n_u4_4.7 = 8 [ tmp = 8; ] { export *[const]:4 tmp; }
|
||||
n_s4_4.7_nozero: tmp is n_u4_4.7 = 9 [ tmp = 9; ] { export *[const]:4 tmp; }
|
||||
n_s4_4.7_nozero: tmp is n_u4_4.7 = 10 [ tmp = 10; ] { export *[const]:4 tmp; }
|
||||
n_s4_4.7_nozero: tmp is n_u4_4.7 = 11 [ tmp = 11; ] { export *[const]:4 tmp; }
|
||||
n_s4_4.7_nozero: tmp is n_u4_4.7 = 12 [ tmp = 12; ] { export *[const]:4 tmp; }
|
||||
n_s4_4.7_nozero: tmp is n_u4_4.7 = 13 [ tmp = 13; ] { export *[const]:4 tmp; }
|
||||
n_s4_4.7_nozero: tmp is n_u4_4.7 = 14 [ tmp = 14; ] { export *[const]:4 tmp; }
|
||||
n_s4_4.7_nozero: tmp is n_u4_4.7 = 15 [ tmp = 15; ] { export *[const]:4 tmp; }
|
||||
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; }
|
||||
@ -257,7 +347,6 @@ define pcodeop lict;
|
||||
define pcodeop licw;
|
||||
define pcodeop memw;
|
||||
define pcodeop nsa;
|
||||
define pcodeop nsau;
|
||||
define pcodeop pdtlb;
|
||||
define pcodeop pitlb;
|
||||
define pcodeop rdtlb0;
|
||||
@ -275,7 +364,6 @@ 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;
|
||||
@ -289,6 +377,5 @@ 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;
|
||||
|
@ -1,3 +1,23 @@
|
||||
@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"
|
||||
@include "xtensaTodo.sinc"
|
||||
}
|
||||
|
@ -155,7 +155,7 @@ macro extract_bit(val, bit, result) {
|
||||
:bbsi as, u5_4.7_12, srel_16.23 is srel_16.23 & u3_13.15 = 0b111 & as & u5_4.7_12 & op0 = 0b0111 {
|
||||
local bval;
|
||||
extract_bit(as, u5_4.7_12, bval);
|
||||
if (bval == 0)
|
||||
if (bval != 0)
|
||||
goto srel_16.23;
|
||||
}
|
||||
|
||||
@ -480,11 +480,13 @@ macro extract_bit(val, bit, result) {
|
||||
# ILL - Illegal Instruction, pg. 358.
|
||||
:ill is op2 = 0 & op1 = 0 & ar = 0 & as = 0 & at = 0 & op0 = 0 {
|
||||
ill();
|
||||
goto inst_start;
|
||||
}
|
||||
|
||||
# ILL.N - Narrow Illegal Instruction, pg. 359.
|
||||
:ill.n is n_ar = 0b1111 & n_as = 0 & n_at = 0b0110 & n_op0 = 0b1101 {
|
||||
ill();
|
||||
goto inst_start;
|
||||
}
|
||||
|
||||
# IPF - Instruction Cache Prefetch, pg. 360.
|
||||
@ -581,6 +583,33 @@ macro extract_bit(val, bit, result) {
|
||||
at = licw(as);
|
||||
}
|
||||
|
||||
macro loopSetup(as, end, doit) {
|
||||
LCOUNT = as - 1;
|
||||
LBEG = inst_next;
|
||||
#LEND = end;
|
||||
if (doit) goto <body>;
|
||||
goto end;
|
||||
<body>
|
||||
}
|
||||
|
||||
# LOOP - Loop, pg. 392.
|
||||
:loop as, urel_16.23 is urel_16.23 & ar=0b1000 & as & at=0b0111 & op0=0b0110
|
||||
[loopEnd=1; globalset(urel_16.23, loopEnd);] {
|
||||
loopSetup(as, urel_16.23, 1:1);
|
||||
}
|
||||
|
||||
# LOOPGTZ - Loop if Greater Than Zero, pg. 394.
|
||||
:loopgtz as, urel_16.23 is urel_16.23 & ar=0b1010 & as & at=0b0111 & op0=0b0110
|
||||
[loopEnd=1; globalset(urel_16.23, loopEnd);] {
|
||||
loopSetup(as, urel_16.23, as s> 0);
|
||||
}
|
||||
|
||||
# LOOPNEZ - Loop if Not Equal Zero, pg. 396.
|
||||
:loopnez as, urel_16.23 is urel_16.23 & ar=0b1001 & as & at=0b0111 & op0=0b0110
|
||||
[loopEnd=1; globalset(urel_16.23, loopEnd);] {
|
||||
loopSetup(as, urel_16.23, as != 0);
|
||||
}
|
||||
|
||||
# LSI - Load Single Immediate, pg. 398.
|
||||
:lsi ft, as, u10_16.23_sb2 is u10_16.23_sb2 & ar = 0 & as & ft & op0 = 0b0011 {
|
||||
local addr:4 = as + zext(u10_16.23_sb2);
|
||||
@ -829,7 +858,21 @@ macro extract_bit(val, bit, result) {
|
||||
|
||||
# NSAU - Normalization Shift Amount Unsigned, pg. 462. (Count leading zeros)
|
||||
:nsau at, as is op2 = 0b0100 & op1 = 0 & ar = 0b1111 & as & at & op0 = 0 {
|
||||
at = nsau(as);
|
||||
local z4 = as[16,16] == 0;
|
||||
|
||||
local t3 = zext(z4)*as[0,16] + zext(!z4)*as[16,16];
|
||||
local z3 = t3[8,8] == 0;
|
||||
|
||||
local t2 = (z3)*t3[0,8] + (!z3)*t3[8,8];
|
||||
local z2 = t2[4,4] == 0;
|
||||
|
||||
local t1 = (z2)*t2[0,4] + (!z2)*t2[4,4];
|
||||
local z1 = t1[2,2] == 0;
|
||||
|
||||
local z0 = (z1)*(t1[1,1] == 0) + (!z1)*(t1[3,1] == 0);
|
||||
local all0 = as == 0;
|
||||
|
||||
at = zext((all0)*32 + (!all0)*(z4<<4 | z3<<3 | z2<<2 | z1<<1 | z0));
|
||||
}
|
||||
|
||||
# OEQ.S - Compare Single Equal, pg. 463.
|
||||
@ -989,8 +1032,9 @@ macro extract_bit(val, bit, result) {
|
||||
}
|
||||
|
||||
# RSR - Read Special Register, pg. 500.
|
||||
:rsr at, u8_8.15 is op0 = 0 & op1 = 0b0011 & u8_8.15 & at & op0 = 0 {
|
||||
at = rsr(u8_8.15:1);
|
||||
:rsr at, sr is op0 = 0 & op1 = 0b0011 & sr & at & op0 = 0 {
|
||||
local src:4 = zext(sr);
|
||||
at = *[register]:4 src;
|
||||
}
|
||||
|
||||
# RSYNC - Register Read Synchronize, pg. 502.
|
||||
@ -1069,19 +1113,18 @@ macro extract_bit(val, bit, result) {
|
||||
|
||||
# SLL - Shift Left Logical, pg. 524.
|
||||
:sll ar, as is op2 = 0b1010 & op1 = 0b0001 & ar & as & at = 0 & op0 = 0 {
|
||||
local sa:1 = 32 - (sar & 0xf); # XXX check this
|
||||
local sa = 32 - SAR;
|
||||
ar = as << sa;
|
||||
}
|
||||
|
||||
# SLLI - Shift Left Logical Immediate, pg. 525.
|
||||
:slli ar, as, u5_4.7_20 is u3_21.23 = 0 & u5_4.7_20 & op1 = 0b0001 & ar & as & op0 = 0 {
|
||||
local sa:1 = 32 - u5_4.7_20; # XXX check this
|
||||
ar = as << sa;
|
||||
:slli ar, as, u5_4.7_20_slli is u3_21.23 = 0 & u5_4.7_20_slli & op1 = 0b0001 & ar & as & op0 = 0 {
|
||||
ar = as << u5_4.7_20_slli;
|
||||
}
|
||||
|
||||
# SRA - Shift Right Arithmetic, pg. 526.
|
||||
:sra ar, at is op2 = 0b1011 & op1 = 0b0001 & ar & as = 0 & at & op0 = 0 {
|
||||
ar = at s>> sar;
|
||||
ar = at s>> SAR;
|
||||
}
|
||||
|
||||
# SRAI - Shift Right Arithmetic Immediate, pg. 527.
|
||||
@ -1094,13 +1137,13 @@ macro extract_bit(val, bit, result) {
|
||||
local s64:8 = zext(as);
|
||||
local t64:8 = zext(at);
|
||||
local combined:8 = (s64 << 32) | t64;
|
||||
local shifted:8 = combined >> sar;
|
||||
local shifted:8 = combined >> SAR;
|
||||
ar = shifted:4;
|
||||
}
|
||||
|
||||
# SRL - Shift Right Logical, pg. 529.
|
||||
:srl ar, at is op2 = 0b1001 & op1 = 0b0001 & ar & as = 0 & at & op0 = 0 {
|
||||
ar = at >> sar;
|
||||
ar = at >> SAR;
|
||||
}
|
||||
|
||||
# SRLI - Shift Right Logical Immediate, pg. 530.
|
||||
@ -1111,18 +1154,17 @@ macro extract_bit(val, bit, result) {
|
||||
# SSA8B - Set Shift Amount for BE Byte Shift, pg. 531.
|
||||
:ssa8b as is op2 = 0b0100 & op1 = 0 & ar = 0b0011 & as & at = 0 & op0 = 0 {
|
||||
local lsa:4 = (as&3)*8;
|
||||
sar = 32 - lsa:1;
|
||||
SAR = 32 - lsa;
|
||||
}
|
||||
|
||||
# SSA8L - Set Shift Amount for LE Byte Shift, pg. 532.
|
||||
:ssa8l as is op2 = 0b0100 & op1 = 0 & ar = 0b0010 & as & at = 0 & op0 = 0 {
|
||||
local rsa:4 = (as&3)*8;
|
||||
sar = rsa:1;
|
||||
SAR = (as&3)*8;
|
||||
}
|
||||
|
||||
# SSAI - Set Shift Amount Immediate, pg. 533.
|
||||
:ssai u5_8.11_4 is op2 = 0b0100 & op1 = 0 & ar = 0b0100 & u5_8.11_4 & u3_5.7 = 0 & op0 = 0 {
|
||||
sar = u5_8.11_4:1;
|
||||
SAR = zext(u5_8.11_4);
|
||||
}
|
||||
|
||||
# SSI - Store Single Immediate, pg. 534.
|
||||
@ -1140,12 +1182,12 @@ macro extract_bit(val, bit, result) {
|
||||
|
||||
# SSL - Set Shift Amount for Left Shift, pg. 538.
|
||||
:ssl as is op2 = 0b0100 & op1 = 0 & ar = 0b0001 & as & at = 0 & op0 = 0 {
|
||||
sar = 32 - (as:1 & 0xf);
|
||||
SAR = 32 - (as & 0x1f);
|
||||
}
|
||||
|
||||
# SSR - Set Shift Amount for Right Shift, pg. 539.
|
||||
:ssr as is op2 = 0b0100 & op1 = 0 & ar = 0 & as & at = 0 & op0 = 0 {
|
||||
sar = (as:1 & 0xf);
|
||||
SAR = (as & 0x1f);
|
||||
}
|
||||
|
||||
# SSX - Store Singe Indexed, pg. 540.
|
||||
@ -1202,9 +1244,10 @@ macro extract_bit(val, bit, result) {
|
||||
br = nan(fs) || nan(ft) || fs f== ft;
|
||||
}
|
||||
|
||||
# UFLOAT.S - Convert Unsigned Fixed to Single, pg. 550. XXX: How is this different from float.as?
|
||||
# UFLOAT.S - Convert Unsigned Fixed to Single, pg. 550.
|
||||
:ufloat.s fr, as, u4_4.7 is op2 = 0b1101 & op1 = 0b1010 & fr & as & u4_4.7 & op0 = 0 {
|
||||
local f = int2float(as);
|
||||
local tmp:8 = zext(as);
|
||||
local f = int2float(tmp);
|
||||
local d = int2float(1:2 << u4_4.7:2);
|
||||
fr = d f/ f;
|
||||
}
|
||||
@ -1226,10 +1269,14 @@ macro extract_bit(val, bit, result) {
|
||||
br = nan(fs) || nan(ft);
|
||||
}
|
||||
|
||||
# UTRUNC.S - Truncate Single to Fixed Unsigned, pg. 555. FIXME: difference to trunc.s?
|
||||
# UTRUNC.S - Truncate Single to Fixed Unsigned, pg. 555.
|
||||
:utrunc.s ar, fs, u4_4.7 is op2 = 0b1110 & op1 = 0b1010 & ar & fs & u4_4.7 & op0 = 0 {
|
||||
local scale:4 = int2float(1:2 << u4_4.7:2);
|
||||
ar = trunc(fs f* scale);
|
||||
local tmp:8 = trunc(fs f* scale);
|
||||
local posof = nan(fs) || (tmp >> 16) != 0;
|
||||
local negof = tmp s< 0;
|
||||
local noof = !posof && !negof;
|
||||
ar = zext(posof)*0xffffffff + zext(negof)*0x80000000 + zext(noof)*tmp:4;
|
||||
}
|
||||
|
||||
# WAITI - Wait Interrupt, pg. 556.
|
||||
@ -1258,8 +1305,9 @@ macro extract_bit(val, bit, result) {
|
||||
}
|
||||
|
||||
# WSR - Write Special Register, pg. 561.
|
||||
:wsr at, u8_8.15 is op2 = 0b0001 & op1 = 0b0011 & u8_8.15 & at & op0 = 0 {
|
||||
wsr(u8_8.15:1, at);
|
||||
:wsr at, sr is op2 = 0b0001 & op1 = 0b0011 & sr & at & op0 = 0 {
|
||||
local dst:4 = zext(sr);
|
||||
*[register]:4 dst = at;
|
||||
}
|
||||
|
||||
# WUR - Write User Register, pg. 563.
|
||||
@ -1278,6 +1326,6 @@ macro extract_bit(val, bit, result) {
|
||||
}
|
||||
|
||||
# XSR - Exchange Special Register, pg. 566.
|
||||
:xsr at, u8_8.15 is op2 = 0b1110 & op1 = 0b0001 & u8_8.15 & at & op0 = 0 {
|
||||
:xsr at, u8_8.15 is op2 = 0b0110 & op1 = 0b0001 & u8_8.15 & at & op0 = 0 {
|
||||
at = xsr(u8_8.15:1, at);
|
||||
}
|
||||
|
@ -54,13 +54,25 @@
|
||||
# FIXME: Add remaining MUL.* opcodes.
|
||||
|
||||
|
||||
## Loop Option ##
|
||||
# TODO this produces correct pcode, tho it would be nicer to display the float in disasm as well
|
||||
# +0.0 +1.0 +2.0 +0.5
|
||||
const.s_imm: tmp is as=0 [ tmp = 0x00000000; ] { export *[const]:4 tmp; }
|
||||
const.s_imm: tmp is as=1 [ tmp = 0x3F800000; ] { export *[const]:4 tmp; }
|
||||
const.s_imm: tmp is as=2 [ tmp = 0x40000000; ] { export *[const]:4 tmp; }
|
||||
const.s_imm: tmp is as=3 [ tmp = 0x3F000000; ] { export *[const]:4 tmp; }
|
||||
|
||||
# LOOP - Loop, pg. 392.
|
||||
:loop as, urel_16.23 is urel_16.23 & ar = 0b1000 & as & at = 0b0111 & op0 = 0b0110 unimpl
|
||||
:const.s fr, const.s_imm is op2=0b1111 & op1=0b1010 & fr & const.s_imm & at=0b0011 & op0=0 {
|
||||
fr = float2float(const.s_imm);
|
||||
}
|
||||
|
||||
# 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
|
||||
# Stub out some insns which mainly appear in boilerplate library functions...
|
||||
:div0.s fr, fs is op2=0b1111 & op1=0b1010 & fr & fs & at=0b0111 & op0=0 unimpl
|
||||
:sqrt0.s fr, fs is op2=0b1111 & op1=0b1010 & fr & fs & at=0b1001 & op0=0 unimpl
|
||||
:nexp01.s fr, fs is op2=0b1111 & op1=0b1010 & fr & fs & at=0b1011 & op0=0 unimpl
|
||||
:mksadj.s fr, fs is op2=0b1111 & op1=0b1010 & fr & fs & at=0b1100 & op0=0 unimpl
|
||||
:mkdadj.s fr, fs is op2=0b1111 & op1=0b1010 & fr & fs & at=0b1101 & op0=0 unimpl
|
||||
:addexp.s fr, fs is op2=0b1111 & op1=0b1010 & fr & fs & at=0b1110 & op0=0 unimpl
|
||||
:addexpm.s fr, fs is op2=0b1111 & op1=0b1010 & fr & fs & at=0b1111 & op0=0 unimpl
|
||||
:maddn.s fr, fs, ft is op2=0b0110 & op1=0b1010 & fr & fs & ft & op0=0 unimpl
|
||||
:divn.s fr, fs, ft is op2=0b0111 & op1=0b1010 & fr & fs & ft & op0=0 unimpl
|
||||
|
5
extension.properties
Normal file
5
extension.properties
Normal file
@ -0,0 +1,5 @@
|
||||
name=Xtensa
|
||||
description=Xtensa CPU plugin
|
||||
author=Sebastian Schmidt
|
||||
createdOn=
|
||||
version=@extversion@
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
5
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
5
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
234
gradlew
vendored
Executable file
234
gradlew
vendored
Executable file
@ -0,0 +1,234 @@
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Copyright © 2015-2021 the original authors.
|
||||
#
|
||||
# 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
|
||||
#
|
||||
# https://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.
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# Gradle start up script for POSIX generated by Gradle.
|
||||
#
|
||||
# Important for running:
|
||||
#
|
||||
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
|
||||
# noncompliant, but you have some other compliant shell such as ksh or
|
||||
# bash, then to run this script, type that shell name before the whole
|
||||
# command line, like:
|
||||
#
|
||||
# ksh Gradle
|
||||
#
|
||||
# Busybox and similar reduced shells will NOT work, because this script
|
||||
# requires all of these POSIX shell features:
|
||||
# * functions;
|
||||
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
||||
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
||||
# * compound commands having a testable exit status, especially «case»;
|
||||
# * various built-in commands including «command», «set», and «ulimit».
|
||||
#
|
||||
# Important for patching:
|
||||
#
|
||||
# (2) This script targets any POSIX shell, so it avoids extensions provided
|
||||
# by Bash, Ksh, etc; in particular arrays are avoided.
|
||||
#
|
||||
# The "traditional" practice of packing multiple parameters into a
|
||||
# space-separated string is a well documented source of bugs and security
|
||||
# problems, so this is (mostly) avoided, by progressively accumulating
|
||||
# options in "$@", and eventually passing that to Java.
|
||||
#
|
||||
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
|
||||
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
|
||||
# see the in-line comments for details.
|
||||
#
|
||||
# There are tweaks for specific operating systems such as AIX, CygWin,
|
||||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# within the Gradle project.
|
||||
#
|
||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
|
||||
# Resolve links: $0 may be a link
|
||||
app_path=$0
|
||||
|
||||
# Need this for daisy-chained symlinks.
|
||||
while
|
||||
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
|
||||
[ -h "$app_path" ]
|
||||
do
|
||||
ls=$( ls -ld "$app_path" )
|
||||
link=${ls#*' -> '}
|
||||
case $link in #(
|
||||
/*) app_path=$link ;; #(
|
||||
*) app_path=$APP_HOME$link ;;
|
||||
esac
|
||||
done
|
||||
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=${0##*/}
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD=maximum
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
} >&2
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
} >&2
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "$( uname )" in #(
|
||||
CYGWIN* ) cygwin=true ;; #(
|
||||
Darwin* ) darwin=true ;; #(
|
||||
MSYS* | MINGW* ) msys=true ;; #(
|
||||
NONSTOP* ) nonstop=true ;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD=$JAVA_HOME/jre/sh/java
|
||||
else
|
||||
JAVACMD=$JAVA_HOME/bin/java
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD=java
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
case $MAX_FD in #(
|
||||
max*)
|
||||
MAX_FD=$( ulimit -H -n ) ||
|
||||
warn "Could not query maximum file descriptor limit"
|
||||
esac
|
||||
case $MAX_FD in #(
|
||||
'' | soft) :;; #(
|
||||
*)
|
||||
ulimit -n "$MAX_FD" ||
|
||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||
esac
|
||||
fi
|
||||
|
||||
# Collect all arguments for the java command, stacking in reverse order:
|
||||
# * args from the command line
|
||||
# * the main class name
|
||||
# * -classpath
|
||||
# * -D...appname settings
|
||||
# * --module-path (only if needed)
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
|
||||
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if "$cygwin" || "$msys" ; then
|
||||
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
||||
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
||||
|
||||
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
for arg do
|
||||
if
|
||||
case $arg in #(
|
||||
-*) false ;; # don't mess with options #(
|
||||
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
|
||||
[ -e "$t" ] ;; #(
|
||||
*) false ;;
|
||||
esac
|
||||
then
|
||||
arg=$( cygpath --path --ignore --mixed "$arg" )
|
||||
fi
|
||||
# Roll the args list around exactly as many times as the number of
|
||||
# args, so each arg winds up back in the position where it started, but
|
||||
# possibly modified.
|
||||
#
|
||||
# NB: a `for` loop captures its iteration list before it begins, so
|
||||
# changing the positional parameters here affects neither the number of
|
||||
# iterations, nor the values presented in `arg`.
|
||||
shift # remove old arg
|
||||
set -- "$@" "$arg" # push replacement arg
|
||||
done
|
||||
fi
|
||||
|
||||
# Collect all arguments for the java command;
|
||||
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
||||
# shell script including quotes and variable substitutions, so put them in
|
||||
# double quotes to make sure that they get re-expanded; and
|
||||
# * put everything else in single quotes, so that it's not re-expanded.
|
||||
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
-classpath "$CLASSPATH" \
|
||||
org.gradle.wrapper.GradleWrapperMain \
|
||||
"$@"
|
||||
|
||||
# Use "xargs" to parse quoted args.
|
||||
#
|
||||
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||
#
|
||||
# In Bash we could simply go:
|
||||
#
|
||||
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
|
||||
# set -- "${ARGS[@]}" "$@"
|
||||
#
|
||||
# but POSIX shell has neither arrays nor command substitution, so instead we
|
||||
# post-process each arg (as a line of input to sed) to backslash-escape any
|
||||
# character that might be a shell metacharacter, then use eval to reverse
|
||||
# that process (while maintaining the separation between arguments), and wrap
|
||||
# the whole thing up as a single "set" statement.
|
||||
#
|
||||
# This will of course break if any of these variables contains a newline or
|
||||
# an unmatched quote.
|
||||
#
|
||||
|
||||
eval "set -- $(
|
||||
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
|
||||
xargs -n1 |
|
||||
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
|
||||
tr '\n' ' '
|
||||
)" '"$@"'
|
||||
|
||||
exec "$JAVACMD" "$@"
|
89
gradlew.bat
vendored
Normal file
89
gradlew.bat
vendored
Normal file
@ -0,0 +1,89 @@
|
||||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user