Merge remote-tracking branch

'origin/GP-6007_ghidorahrex_PR-1778_Tim---_tim_add_nds32_processor'
(Closes #1778)
This commit is contained in:
Ryan Kurtz
2025-12-04 04:26:04 -05:00
27 changed files with 2804 additions and 9 deletions

View File

@@ -16,6 +16,14 @@
#include "pcode_test.h"
#include "big_struct.h"
#ifdef HAS_LIBC
#include <string.h>
#else
void *memset(void *b, int c, size_t len);
void *memcpy(void *dst, const void *src, size_t n);
int memcmp(const void *s1, const void *s2, size_t n);
#endif
static i4 int_expectedValue;
static i4 int_actualValue;

View File

@@ -47,12 +47,14 @@ pcodeTestDefaults.has_vector = 0
pcodeTestDefaults.small_build = 0
pcodeTestDefaults.ld_library_path = ''
pcodeTestDefaults.toolchain_type = 'gcc'
pcodeTestDefaults.compile_exe = 'bin/gcc'
pcodeTestDefaults.objdump_exe = 'bin/objdump'
pcodeTestDefaults.compile_exe = 'gcc'
pcodeTestDefaults.objdump_exe = 'objdump'
pcodeTestDefaults.objdump_option = ''
pcodeTestDefaults.readelf_exe = 'bin/readelf'
pcodeTestDefaults.nm_exe = 'bin/nm'
pcodeTestDefaults.strip_exe = 'bin/strip'
pcodeTestDefaults.readelf_exe = 'readelf'
pcodeTestDefaults.exec_dir = 'bin/'
pcodeTestDefaults.exec_prefix = ''
pcodeTestDefaults.nm_exe = 'nm'
pcodeTestDefaults.strip_exe = 'strip'
pcodeTestDefaults.variants = {'O0': '-O0', 'O3': '-O3'}
pcodeTestDefaults.proc_test = ''
pcodeTestDefaults.force = False

View File

@@ -436,7 +436,7 @@ PCodeTest({
'name': 'NDS32BE',
'build_all': 1,
'toolchain': 'NDS32/nds32be-elf',
'ccflags': '',
'ccflags': '-mbig-endian',
'cclibs': '-lgcc',
'language_id': 'NDS32:BE:32:default',
})
@@ -444,9 +444,20 @@ PCodeTest({
PCodeTest({
'name': 'NDS32LE',
'build_all': 1,
'toolchain': 'NDS32/nds32le-elf',
'toolchain': 'NDS32/nds32le-elf',#'NDS32/nds32le-linux-glibc-v5d',
'ccflags': '-mlittle-endian -EL',
'cclibs': '-lgcc',
'language_id': 'NDS32:LE:32:default',
})
PCodeTest({
'name': 'NDS32AS',
'build_all': 1,
'toolchain': 'NDS32/nds32le-elf-mculib-v3s',
'exec_prefix': 'nds32le-elf-',
'ccflags': '',
'cclibs': '-lgcc',
'gcc_version': '12.2.0',
'language_id': 'NDS32:LE:32:default',
})

View File

@@ -88,7 +88,13 @@ class PCodeTestBuild(BuildUtil):
def main(self):
# make sure compiler exists and runnable
self.config.compile_exe = self.config.exec_dir + self.config.exec_prefix + self.config.compile_exe
self.config.build_exe = self.config.exec_dir + str(self.config.exec_prefix) + str(self.config.build_exe)
self.config.strip_exe = self.config.exec_dir + str(self.config.exec_prefix) + str(self.config.strip_exe)
self.config.objdump_exe = self.config.exec_dir + str(self.config.exec_prefix) + str(self.config.objdump_exe)
self.config.readelf_exe = self.config.exec_dir + str(self.config.exec_prefix) + str(self.config.readelf_exe)
self.config.nm_exe = self.config.exec_dir + str(self.config.exec_prefix) + str(self.config.nm_exe)
if not self.is_executable_file(self.which('compile_exe')):
self.log_err(self.config.format('build the Toolchain before compilation'))
return
@@ -427,6 +433,7 @@ class PCodeBuildGCC(PCodeTestBuild):
self.set_library_path(self.config.ld_library_path)
# Construct the compile/link command line and execute it
cmp = self.which('compile_exe')
cmd = [cmp] + input_files + self.cflags(output_file) + [opt_cflag, '-B', self.dirname(cmp), '-o', output_file]
out, err = self.run(cmd)

View File

View File

@@ -0,0 +1,30 @@
/* ###
* 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/javaProject.gradle"
apply from: "$rootProject.projectDir/gradle/jacocoProject.gradle"
apply from: "$rootProject.projectDir/gradle/javaTestProject.gradle"
apply from: "$rootProject.projectDir/gradle/processorProject.gradle"
apply plugin: 'eclipse'
eclipse.project.name = 'Processors NDS32'
dependencies {
api project(':Base')
// Temporary dependency so that pcodeTests can use the Decompiler switch recovery
api project(':Decompiler')
}

View File

@@ -0,0 +1,13 @@
##VERSION: 2.0
Module.manifest||GHIDRA||||END|
data/languages/lsmw.sinc||GHIDRA||||END|
data/languages/nds32.cspec||GHIDRA||||END|
data/languages/nds32.dwarf||GHIDRA||||END|
data/languages/nds32.ldefs||GHIDRA||||END|
data/languages/nds32.opinion||GHIDRA||||END|
data/languages/nds32.pspec||GHIDRA||||END|
data/languages/nds32.sinc||GHIDRA||||END|
data/languages/nds32be.slaspec||GHIDRA||||END|
data/languages/nds32le.slaspec||GHIDRA||||END|
data/patterns/nds32_patterns.xml||GHIDRA||||END|
data/patterns/patternconstraints.xml||GHIDRA||||END|

View File

@@ -0,0 +1,125 @@
Dreg: a0 is a0 & regNum=0 { export a0; }
Dreg: a1 is a1 & regNum=1 { export a1; }
Dreg: a2 is a2 & regNum=2 { export a2; }
Dreg: a3 is a3 & regNum=3 { export a3; }
Dreg: a4 is a4 & regNum=4 { export a4; }
Dreg: a5 is a5 & regNum=5 { export a5; }
Dreg: s0 is s0 & regNum=6 { export s0; }
Dreg: s1 is s1 & regNum=7 { export s1; }
Dreg: s2 is s2 & regNum=8 { export s2; }
Dreg: s3 is s3 & regNum=9 { export s3; }
Dreg: s4 is s4 & regNum=10 { export s4; }
Dreg: s5 is s5 & regNum=11 { export s5; }
Dreg: s6 is s6 & regNum=12 { export s6; }
Dreg: s7 is s7 & regNum=13 { export s7; }
Dreg: s8 is s8 & regNum=14 { export s8; }
Dreg: ta is ta & regNum=15 { export ta; }
Dreg: t0 is t0 & regNum=16 { export t0; }
Dreg: t1 is t1 & regNum=17 { export t1; }
Dreg: t2 is t2 & regNum=18 { export t2; }
Dreg: t3 is t3 & regNum=19 { export t3; }
Dreg: t4 is t4 & regNum=20 { export t4; }
Dreg: t5 is t5 & regNum=21 { export t5; }
Dreg: t6 is t6 & regNum=22 { export t6; }
Dreg: t7 is t7 & regNum=23 { export t7; }
Dreg: t8 is t8 & regNum=24 { export t8; }
Dreg: t9 is t9 & regNum=25 { export t9; }
Dreg: p0 is p0 & regNum=26 { export p0; }
Dreg: p1 is p1 & regNum=27 { export p1; }
Dreg: fp is fp & regNum=28 { export fp; }
Dreg: gp is gp & regNum=29 { export gp; }
Dreg: lp is lp & regNum=30 { export lp; }
Dreg: sp is sp & regNum=31 { export sp; }
macro Smwad(reg) {
mult_addr = mult_addr - 4;
*mult_addr = reg;
}
macro LmwOp(reg) {
reg = *mult_addr;
}
macro SmwOp(reg) {
*mult_addr = reg;
}
macro MwDec() { mult_addr = mult_addr - 4; }
macro MwInc() { mult_addr = mult_addr + 4; }
Lsmw_id: is LsmwId=0 { MwInc(); }
Lsmw_id: is LsmwId=1 { MwDec(); }
Lmw.fp: fp is Lsmw_id & LsmwBa=0 & Enable4_fp=1 & fp { LmwOp(fp); build Lsmw_id; }
Lmw.fp: fp is Lsmw_id & LsmwBa=1 & Enable4_fp=1 & fp { build Lsmw_id; LmwOp(fp); }
Lmw.fp: is Enable4_fp=0 { }
Lmw.gp: gp is Lsmw_id & LsmwBa=0 & Enable4_gp=1 & gp { LmwOp(gp); build Lsmw_id; }
Lmw.gp: gp is Lsmw_id & LsmwBa=1 & Enable4_gp=1 & gp { build Lsmw_id; LmwOp(gp); }
Lmw.gp: is Enable4_gp=0 { }
Lmw.lp: lp is Lsmw_id & LsmwBa=0 & Enable4_lp=1 & lp { LmwOp(lp); build Lsmw_id; }
Lmw.lp: lp is Lsmw_id & LsmwBa=1 & Enable4_lp=1 & lp { build Lsmw_id; LmwOp(lp); }
Lmw.lp: is Enable4_lp=0 { }
Lmw.sp: sp is Lsmw_id & LsmwBa=0 & Enable4_sp=1 & sp { LmwOp(sp); build Lsmw_id; }
Lmw.sp: sp is Lsmw_id & LsmwBa=1 & Enable4_sp=1 & sp { build Lsmw_id; LmwOp(sp); }
Lmw.sp: is Enable4_sp=0 { }
# Terminating condition
LmwReg: Dreg is LsmwId=0 & LsmwBa=0 & Dreg & counter=1 [regNum=regNum+1;] { build Dreg; LmwOp(Dreg); MwInc(); }
LmwReg: Dreg is LsmwId=1 & LsmwBa=0 & Dreg & counter=1 [regNum=regNum-1;] { build Dreg; LmwOp(Dreg); MwDec(); }
LmwReg: Dreg is LsmwId=0 & LsmwBa=1 & Dreg & counter=1 [regNum=regNum+1;] { build Dreg; MwInc(); LmwOp(Dreg); }
LmwReg: Dreg is LsmwId=1 & LsmwBa=1 & Dreg & counter=1 [regNum=regNum-1;] { build Dreg; MwDec(); LmwOp(Dreg); }
LmwReg: Dreg, LmwReg is LsmwId=0 & LsmwBa=0 & Dreg & LmwReg [ counter = counter-1; regNum=regNum+1;] { LmwOp(Dreg); MwInc(); build LmwReg; }
LmwReg: Dreg, LmwReg is LsmwId=1 & LsmwBa=0 & Dreg & LmwReg [ counter = counter-1; regNum=regNum-1;] { LmwOp(Dreg); MwDec(); build LmwReg; }
LmwReg: Dreg, LmwReg is LsmwId=0 & LsmwBa=1 & Dreg & LmwReg [ counter = counter-1; regNum=regNum+1;] { MwInc(); LmwOp(Dreg); build LmwReg; }
LmwReg: Dreg, LmwReg is LsmwId=1 & LsmwBa=1 & Dreg & LmwReg [ counter = counter-1; regNum=regNum-1;] { MwDec(); LmwOp(Dreg); build LmwReg; }
# Initial conditions
Lmw.regs: is (LsmwRe_ & LsmwRb_ & LsmwId=0 & Lmw.fp & Lmw.gp & Lmw.lp & Lmw.sp) ... & LmwReg [ regNum=LsmwRb_-1; counter=LsmwRe_-LsmwRb_+1; ] { build LmwReg; build Lmw.fp; build Lmw.gp; build Lmw.lp; build Lmw.sp; }
Lmw.regs: is (LsmwRe_ & LsmwRb_ & LsmwId=1 & Lmw.sp & Lmw.lp & Lmw.gp & Lmw.fp) ... & LmwReg [ regNum=LsmwRe_+1; counter=LsmwRe_-LsmwRb_+1; ] { build Lmw.sp; build Lmw.lp; build Lmw.gp; build Lmw.fp; build LmwReg; }
Lmw.regs: is LsmwRe_=0x1f & LsmwRb_=0x1f & LsmwId=0 & Lmw.fp & Lmw.gp & Lmw.lp & Lmw.sp { build Lmw.fp; build Lmw.gp; build Lmw.lp; build Lmw.sp; }
Lmw.regs: is LsmwRe_=0x1f & LsmwRb_=0x1f & LsmwId=1 & Lmw.sp & Lmw.lp & Lmw.gp & Lmw.fp { build Lmw.sp; build Lmw.lp; build Lmw.gp; build Lmw.fp; }
Lmwa.regs: is (LsmwRe_ & LsmwRb_ & LsmwId=0 & Lmw.fp & Lmw.gp & Lmw.lp & Lmw.sp) ... & LmwReg [ regNum=LsmwRb_-1; counter=LsmwRe_-LsmwRb_+1; ] { build LmwReg; build Lmw.sp; build Lmw.lp; build Lmw.gp; build Lmw.fp; }
Lmwa.regs: is (LsmwRe_ & LsmwRb_ & LsmwId=1 & Lmw.sp & Lmw.lp & Lmw.gp & Lmw.fp) ... & LmwReg [ regNum=LsmwRe_+1; counter=LsmwRe_-LsmwRb_+1; ] { build Lmw.fp; build Lmw.gp; build Lmw.lp; build Lmw.sp; build LmwReg; }
Lmwa.regs: is LsmwRe_=0x1f & LsmwRb_=0x1f & LsmwId=0 & Lmw.fp & Lmw.gp & Lmw.lp & Lmw.sp { build Lmw.sp; build Lmw.lp; build Lmw.gp; build Lmw.fp; }
Lmwa.regs: is LsmwRe_=0x1f & LsmwRb_=0x1f & LsmwId=1 & Lmw.sp & Lmw.lp & Lmw.gp & Lmw.fp { build Lmw.fp; build Lmw.gp; build Lmw.lp; build Lmw.sp; }
Smw.fp: fp is Lsmw_id & LsmwBa=0 & Enable4_fp=1 & fp { SmwOp(fp); build Lsmw_id; }
Smw.fp: fp is Lsmw_id & LsmwBa=1 & Enable4_fp=1 & fp { build Lsmw_id; SmwOp(fp); }
Smw.fp: is Enable4_fp=0 { }
Smw.gp: gp is Lsmw_id & LsmwBa=0 & Enable4_gp=1 & gp { SmwOp(gp); build Lsmw_id; }
Smw.gp: gp is Lsmw_id & LsmwBa=1 & Enable4_gp=1 & gp { build Lsmw_id; SmwOp(gp); }
Smw.gp: is Enable4_gp=0 { }
Smw.lp: lp is Lsmw_id & LsmwBa=0 & Enable4_lp=1 & lp { SmwOp(lp); build Lsmw_id; }
Smw.lp: lp is Lsmw_id & LsmwBa=1 & Enable4_lp=1 & lp { build Lsmw_id; SmwOp(lp); }
Smw.lp: is Enable4_lp=0 { }
Smw.sp: sp is Lsmw_id & LsmwBa=0 & Enable4_sp=1 & sp { SmwOp(sp); build Lsmw_id; }
Smw.sp: sp is Lsmw_id & LsmwBa=1 & Enable4_sp=1 & sp { build Lsmw_id; SmwOp(sp); }
Smw.sp: is Enable4_sp=0 { }
# Terminating condition
SmwReg: Dreg is LsmwId=0 & LsmwBa=0 & Dreg & counter=1 [regNum=regNum+1;] { build Dreg; SmwOp(Dreg); MwInc(); }
SmwReg: Dreg is LsmwId=1 & LsmwBa=0 & Dreg & counter=1 [regNum=regNum-1;] { build Dreg; SmwOp(Dreg); MwDec(); }
SmwReg: Dreg is LsmwId=0 & LsmwBa=1 & Dreg & counter=1 [regNum=regNum+1;] { build Dreg; MwInc(); SmwOp(Dreg); }
SmwReg: Dreg is LsmwId=1 & LsmwBa=1 & Dreg & counter=1 [regNum=regNum-1;] { build Dreg; MwDec(); SmwOp(Dreg); }
SmwReg: Dreg, SmwReg is LsmwId=0 & LsmwBa=0 & Dreg & SmwReg [ counter = counter-1; regNum=regNum+1;] { build Dreg; SmwOp(Dreg); MwInc(); build SmwReg; }
SmwReg: Dreg, SmwReg is LsmwId=1 & LsmwBa=0 & Dreg & SmwReg [ counter = counter-1; regNum=regNum-1;] { build Dreg; SmwOp(Dreg); MwDec(); build SmwReg; }
SmwReg: Dreg, SmwReg is LsmwId=0 & LsmwBa=1 & Dreg & SmwReg [ counter = counter-1; regNum=regNum+1;] { build Dreg; MwInc(); SmwOp(Dreg); build SmwReg; }
SmwReg: Dreg, SmwReg is LsmwId=1 & LsmwBa=1 & Dreg & SmwReg [ counter = counter-1; regNum=regNum-1;] { build Dreg; MwDec(); SmwOp(Dreg); build SmwReg; }
# Initial conditions
Smw.regs: is (LsmwRe_ & LsmwRb_ & LsmwId=0 & Smw.fp & Smw.gp & Smw.lp & Smw.sp) ... & SmwReg [ regNum=LsmwRb_-1; counter=LsmwRe_-LsmwRb_+1; ] { build SmwReg; build Smw.fp; build Smw.gp; build Smw.lp; build Smw.sp; }
Smw.regs: is (LsmwRe_ & LsmwRb_ & LsmwId=1 & Smw.sp & Smw.lp & Smw.gp & Smw.fp) ... & SmwReg [ regNum=LsmwRe_+1; counter=LsmwRe_-LsmwRb_+1; ] { build Smw.sp; build Smw.lp; build Smw.gp; build Smw.fp; build SmwReg; }
Smw.regs: is LsmwRe_=0x1f & LsmwRb_=0x1f & LsmwId=0 & Smw.fp & Smw.gp & Smw.lp & Smw.sp { build Smw.fp; build Smw.gp; build Smw.lp; build Smw.sp; }
Smw.regs: is LsmwRe_=0x1f & LsmwRb_=0x1f & LsmwId=1 & Smw.sp & Smw.lp & Smw.gp & Smw.fp { build Smw.sp; build Smw.lp; build Smw.gp; build Smw.fp; }
Smwa.regs: is (LsmwRe_ & LsmwRb_ & LsmwId=0 & Smw.fp & Smw.gp & Smw.lp & Smw.sp) ... & SmwReg [ regNum=LsmwRb_-1; counter=LsmwRe_-LsmwRb_+1; ] { build SmwReg; build Smw.sp; build Smw.lp; build Smw.gp; build Smw.fp; }
Smwa.regs: is (LsmwRe_ & LsmwRb_ & LsmwId=1 & Smw.sp & Smw.lp & Smw.gp & Smw.fp) ... & SmwReg [ regNum=LsmwRe_+1; counter=LsmwRe_-LsmwRb_+1; ] { build Smw.fp; build Smw.gp; build Smw.lp; build Smw.sp; build SmwReg; }
Smwa.regs: is LsmwRe_=0x1f & LsmwRb_=0x1f & LsmwId=0 & Smw.fp & Smw.gp & Smw.lp & Smw.sp { build Smw.sp; build Smw.lp; build Smw.gp; build Smw.fp; }
Smwa.regs: is LsmwRe_=0x1f & LsmwRb_=0x1f & LsmwId=1 & Smw.sp & Smw.lp & Smw.gp & Smw.fp { build Smw.fp; build Smw.gp; build Smw.lp; build Smw.sp; }

View File

@@ -0,0 +1,115 @@
<?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="2" />
<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="4" />
</size_alignment_map>
</data_organization>
<global>
<range space="ram"/>
<range space="csreg"/>
</global>
<stackpointer register="sp" space="ram"/>
<returnaddress>
<register name="lp"/>
</returnaddress>
<default_proto>
<prototype name="__stdcall" extrapop="0" stackshift="0">
<input>
<pentry minsize="1" maxsize="4" extension="inttype">
<register name="a0"/>
</pentry>
<pentry minsize="1" maxsize="4" extension="inttype">
<register name="a1"/>
</pentry>
<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="5" maxsize="8">
<addr space="join" piece1="a1" piece2="a0"/>
</pentry>
<pentry minsize="5" maxsize="8">
<addr space="join" piece1="a3" piece2="a2"/>
</pentry>
<pentry minsize="5" maxsize="8">
<addr space="join" piece1="a5" piece2="a4"/>
</pentry>
<pentry minsize="1" maxsize="500" align="4">
<addr offset="0" space="stack"/>
</pentry>
</input>
<output killedbycall="true">
<pentry minsize="1" maxsize="4" extension="inttype">
<register name="a0"/>
</pentry>
<pentry minsize="5" maxsize="8">
<addr space="join" piece1="a1" piece2="a0"/>
</pentry>
</output>
<unaffected>
<register name="s0"/>
<register name="s1"/>
<register name="s2"/>
<register name="s3"/>
<register name="s4"/>
<register name="s5"/>
<register name="s6"/>
<register name="s7"/>
<register name="s8"/>
<register name="p0"/>
<register name="p1"/>
<register name="fp"/>
<register name="gp"/>
<register name="lp"/>
<register name="sp"/>
</unaffected>
<killedbycall>
<register name="a0"/>
<register name="a1"/>
<register name="a2"/>
<register name="a3"/>
<register name="a4"/>
<register name="a5"/>
<register name="ta"/>
<register name="t0"/>
<register name="t1"/>
<register name="t2"/>
<register name="t3"/>
<register name="t4"/>
<register name="t5"/>
<register name="t6"/>
<register name="t7"/>
<register name="t8"/>
<register name="t9"/>
</killedbycall>
</prototype>
</default_proto>
</compiler_spec>

View File

@@ -0,0 +1,14 @@
<dwarf>
<register_mappings>
<register_mapping dwarf="0" ghidra="a0" auto_count="6"/> <!-- a0..a5 -->
<register_mapping dwarf="6" ghidra="s0" auto_count="9"/> <!-- s0..s8 -->
<register_mapping dwarf="15" ghidra="ta"/>
<register_mapping dwarf="16" ghidra="t0" auto_count="10"/> <!-- t0..t9 -->
<register_mapping dwarf="26" ghidra="p0" auto_count="2"/> <!-- p0..p1 -->
<register_mapping dwarf="28" ghidra="fp"/>
<register_mapping dwarf="29" ghidra="gp"/>
<register_mapping dwarf="30" ghidra="lp"/>
<register_mapping dwarf="31" ghidra="sp" stackpointer="true"/>
</register_mappings>
<call_frame_cfa value="0"/>
</dwarf>

View File

@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<language_definitions>
<language processor="NDS32"
endian="big"
instructionEndian="big"
size="32"
variant="default"
version="1.0"
slafile="nds32be.sla"
processorspec="nds32.pspec"
id="NDS32:BE:32:default">
<description>NDS32 default processor 32-bit big-endian</description>
<compiler name="default" spec="nds32.cspec" id="default"/>
<external_name tool="gnu" name="n1h_v3m"/>
<external_name tool="DWARF.register.mapping.file" name="nds32.dwarf"/>
</language>
<language processor="NDS32"
endian="little"
instructionEndian="big"
size="32"
variant="default"
version="1.0"
slafile="nds32le.sla"
processorspec="nds32.pspec"
id="NDS32:LE:32:default">
<description>NDS32 default processor 32-bit little-endian</description>
<compiler name="default" spec="nds32.cspec" id="default"/>
<external_name tool="gnu" name="n1h_v3m"/>
<external_name tool="DWARF.register.mapping.file" name="nds32.dwarf"/>
</language>
</language_definitions>

View File

@@ -0,0 +1,5 @@
<opinions>
<constraint loader="Executable and Linking Format (ELF)" compilerSpecID="default">
<constraint primary="167" processor="NDS32" size="32" />
</constraint>
</opinions>

View File

@@ -0,0 +1,155 @@
<?xml version="1.0" encoding="UTF-8"?>
<processor_spec>
<programcounter register="pc"/>
<default_memory_blocks>
<memory_block name="csr" start_address="csreg:0x0" length="0x8000" initialized="false"/>
</default_memory_blocks>
<default_symbols>
<symbol name="cpu_ver" address="csreg:0x000" size="4" description="" />
<symbol name="core_id" address="csreg:0x001" size="4" description="" />
<symbol name="icm_cfg" address="csreg:0x008" size="4" description="" />
<symbol name="dcm_cfg" address="csreg:0x010" size="4" description="" />
<symbol name="mmu_cfg" address="csreg:0x018" size="4" description="" />
<symbol name="msc_cfg" address="csreg:0x020" size="4" description="" />
<symbol name="msc_cfg2" address="csreg:0x021" size="4" description="" />
<symbol name="fucop_exist" address="csreg:0x028" size="4" description="" />
<symbol name="psw" address="csreg:0x080" size="4" description="" />
<symbol name="ipsw" address="csreg:0x081" size="4" description="" />
<symbol name="p_ipsw" address="csreg:0x082" size="4" description="" />
<symbol name="ivb" address="csreg:0x089" size="4" description="" />
<symbol name="int_ctrl" address="csreg:0x08a" size="4" description="" />
<symbol name="int_gpr_push_dis" address="csreg:0x08b" size="4" description="" />
<symbol name="eva" address="csreg:0x091" size="4" description="" />
<symbol name="p_eva" address="csreg:0x092" size="4" description="" />
<symbol name="itype" address="csreg:0x099" size="4" description="" />
<symbol name="p_itype" address="csreg:0x09a" size="4" description="" />
<symbol name="merr" address="csreg:0x0a1" size="4" description="" />
<symbol name="ipc" address="csreg:0x0a9" size="4" description="" />
<symbol name="p_ipc" address="csreg:0x0aa" size="4" description="" />
<symbol name="oipc" address="csreg:0x0ab" size="4" description="" />
<symbol name="p_p0" address="csreg:0x0b2" size="4" description="" />
<symbol name="p_p1" address="csreg:0x0ba" size="4" description="" />
<symbol name="int_mask" address="csreg:0x0c0" size="4" description="" />
<symbol name="int_mask2" address="csreg:0x0c1" size="4" description="" />
<symbol name="int_mask3" address="csreg:0x0c2" size="4" description="" />
<symbol name="int_pend" address="csreg:0x0c8" size="4" description="" />
<symbol name="int_pend2" address="csreg:0x0c9" size="4" description="" />
<symbol name="int_pend3" address="csreg:0x0ca" size="4" description="" />
<symbol name="int_trigger" address="csreg:0x0cc" size="4" description="" />
<symbol name="int_trigger2" address="csreg:0x0cd" size="4" description="" />
<symbol name="sp_usr" address="csreg:0x0d0" size="4" description="" />
<symbol name="sp_priv" address="next" size="4" description="" />
<symbol name="sp_usr1" address="next" size="4" description="" />
<symbol name="sp_priv1" address="next" size="4" description="" />
<symbol name="sp_usr2" address="next" size="4" description="" />
<symbol name="sp_priv2" address="next" size="4" description="" />
<symbol name="sp_usr3" address="next" size="4" description="" />
<symbol name="sp_priv3" address="next" size="4" description="" />
<symbol name="int_pri" address="next" size="4" description="" />
<symbol name="int_pri2" address="next" size="4" description="" />
<symbol name="int_pri3" address="next" size="4" description="" />
<symbol name="int_pri4" address="next" size="4" description="" />
<symbol name="mmu_ctl" address="csreg:0x100" size="4" description="" />
<symbol name="bg_region" address="csreg:0x101" size="4" description="" />
<symbol name="l1pptb" address="csreg:0x108" size="4" description="" />
<symbol name="tlb_vpn" address="csreg:0x110" size="4" description="" />
<symbol name="tlb_data" address="csreg:0x118" size="4" description="" />
<symbol name="tlb_misc" address="csreg:0x120" size="4" description="" />
<symbol name="vlpt_idx" address="csreg:0x128" size="4" description="" />
<symbol name="ilmb" address="csreg:0x130" size="4" description="" />
<symbol name="dlmb" address="csreg:0x138" size="4" description="" />
<symbol name="cache_ctl" address="csreg:0x140" size="4" description="" />
<symbol name="hsmp_saddr" address="csreg:0x148" size="4" description="" />
<symbol name="hsmp_eaddr" address="csreg:0x149" size="4" description="" />
<symbol name="sdz_ctl" address="csreg:0x178" size="4" description="" />
<symbol name="misc_ctl" address="csreg:0x179" size="4" description="" />
<symbol name="ecc_misc" address="csreg:0x17a" size="4" description="" />
<symbol name="bpc0" address="csreg:0x180" size="4" description="" />
<symbol name="bpc1" address="next" size="4" description="" />
<symbol name="bpc2" address="next" size="4" description="" />
<symbol name="bpc3" address="next" size="4" description="" />
<symbol name="bpc4" address="next" size="4" description="" />
<symbol name="bpc5" address="next" size="4" description="" />
<symbol name="bpc6" address="next" size="4" description="" />
<symbol name="bpc7" address="next" size="4" description="" />
<symbol name="bpa0" address="next" size="4" description="" />
<symbol name="bpa1" address="next" size="4" description="" />
<symbol name="bpa2" address="next" size="4" description="" />
<symbol name="bpa3" address="next" size="4" description="" />
<symbol name="bpa4" address="next" size="4" description="" />
<symbol name="bpa5" address="next" size="4" description="" />
<symbol name="bpa6" address="next" size="4" description="" />
<symbol name="bpa7" address="next" size="4" description="" />
<symbol name="bpam0" address="next" size="4" description="" />
<symbol name="bpam1" address="next" size="4" description="" />
<symbol name="bpam2" address="next" size="4" description="" />
<symbol name="bpam3" address="next" size="4" description="" />
<symbol name="bpam4" address="next" size="4" description="" />
<symbol name="bpam5" address="next" size="4" description="" />
<symbol name="bpam6" address="next" size="4" description="" />
<symbol name="bpam7" address="next" size="4" description="" />
<symbol name="bpv0" address="next" size="4" description="" />
<symbol name="bpv1" address="next" size="4" description="" />
<symbol name="bpv2" address="next" size="4" description="" />
<symbol name="bpv3" address="next" size="4" description="" />
<symbol name="bpv4" address="next" size="4" description="" />
<symbol name="bpv5" address="next" size="4" description="" />
<symbol name="bpv6" address="next" size="4" description="" />
<symbol name="bpv7" address="next" size="4" description="" />
<symbol name="bpcid0" address="next" size="4" description="" />
<symbol name="bpcid1" address="next" size="4" description="" />
<symbol name="bpcid2" address="next" size="4" description="" />
<symbol name="bpcid3" address="next" size="4" description="" />
<symbol name="bpcid4" address="next" size="4" description="" />
<symbol name="bpcid5" address="next" size="4" description="" />
<symbol name="bpcid6" address="next" size="4" description="" />
<symbol name="bpcid7" address="next" size="4" description="" />
<symbol name="edm_cfg" address="csreg:0x1a8" size="4" description="" />
<symbol name="edmsw" address="csreg:0x1b0" size="4" description="" />
<symbol name="edm_ctl" address="csreg:0x1b8" size="4" description="" />
<symbol name="edm_dtr" address="csreg:0x1c0" size="4" description="" />
<symbol name="bpmtc" address="csreg:0x1c8" size="4" description="" />
<symbol name="dimbr" address="csreg:0x1d0" size="4" description="" />
<symbol name="tecr0" address="csreg:0x1f0" size="4" description="" />
<symbol name="tecr1" address="csreg:0x1f1" size="4" description="" />
<symbol name="pfmc0" address="csreg:0x200" size="4" description="" />
<symbol name="pfmc1" address="csreg:0x201" size="4" description="" />
<symbol name="pfmc2" address="csreg:0x202" size="4" description="" />
<symbol name="pfm_ctl" address="csreg:0x208" size="4" description="" />
<symbol name="pft_ctl" address="csreg:0x210" size="4" description="" />
<symbol name="prusr_acc_ctl" address="csreg:0x220" size="4" description="" />
<symbol name="fucpr" address="csreg:0x228" size="4" description="" />
<symbol name="hsp_ctl" address="csreg:0x230" size="4" description="" />
<symbol name="sp_bound" address="csreg:0x231" size="4" description="" />
<symbol name="sp_bound_priv" address="csreg:0x230" size="4" description="" />
<symbol name="sp_base" address="csreg:0x230" size="4" description="" />
<symbol name="sp_base_priv" address="csreg:0x230" size="4" description="" />
<symbol name="dma_cfg" address="csreg:0x280" size="4" description="" />
<symbol name="dma_gcsw" address="csreg:0x288" size="4" description="" />
<symbol name="dma_chnsel" address="csreg:0x290" size="4" description="" />
<symbol name="dma_act" address="csreg:0x298" size="4" description="" />
<symbol name="dma_setup" address="csreg:0x2a0" size="4" description="" />
<symbol name="dma_isaddr" address="csreg:0x2a8" size="4" description="" />
<symbol name="dma_esaddr" address="csreg:0x2b0" size="4" description="" />
<symbol name="dma_tcnt" address="csreg:0x2b8" size="4" description="" />
<symbol name="dma_rcnt" address="csreg:0x2b9" size="4" description="" />
<symbol name="dma_status" address="csreg:0x2c0" size="4" description="" />
<symbol name="dma_hstatus" address="csreg:0x2c1" size="4" description="" />
<symbol name="dma_2dset" address="csreg:0x2c8" size="4" description="" />
<symbol name="dma_2dsctl" address="csreg:0x2c9" size="4" description="" />
<symbol name="secur0" address="csreg:0x300" size="4" description="" />
<symbol name="secur1" address="csreg:0x308" size="4" description="" />
<symbol name="secur2" address="csreg:0x309" size="4" description="" />
<symbol name="secur3" address="csreg:0x30a" size="4" description="" />
</default_symbols>
</processor_spec>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,3 @@
@define ENDIAN "big"
@include "nds32.sinc"

View File

@@ -0,0 +1,3 @@
@define ENDIAN "little"
@include "nds32.sinc"

View File

@@ -0,0 +1,12 @@
<patternlist>
<patternpairs totalbits="18" postbits="9">
<prepatterns>
<data>0xfc 1....... </data> <!-- pop25 sx,# -->
<data>0xdd 0x9e</data> <!-- ret5 lp -->
</prepatterns>
<postpatterns>
<data>0xfc 0....... </data> <!-- push25 sx,# -->
<funcstart/>
</postpatterns>
</patternpairs>
</patternlist>

View File

@@ -0,0 +1,5 @@
<patternconstraints>
<language id="NDS32:*:*:*">
<patternfile>nds32_patterns.xml</patternfile>
</language>
</patternconstraints>

View File

@@ -0,0 +1,172 @@
/* ###
* 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.plugin.core.analysis;
import java.math.BigInteger;
import ghidra.app.util.importer.MessageLog;
import ghidra.framework.options.Options;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSet;
import ghidra.program.model.address.AddressSetView;
import ghidra.program.model.lang.Processor;
import ghidra.program.model.lang.Register;
import ghidra.program.model.lang.RegisterValue;
import ghidra.program.model.listing.ContextChangeException;
import ghidra.program.model.listing.Function;
import ghidra.program.model.listing.Instruction;
import ghidra.program.model.listing.Program;
import ghidra.program.model.listing.ProgramContext;
import ghidra.program.model.symbol.FlowType;
import ghidra.program.model.symbol.Symbol;
import ghidra.program.model.symbol.SymbolUtilities;
import ghidra.program.util.ContextEvaluator;
import ghidra.program.util.SymbolicPropogator;
import ghidra.program.util.VarnodeContext;
import ghidra.util.Msg;
import ghidra.util.exception.AssertException;
import ghidra.util.exception.CancelledException;
import ghidra.util.task.TaskMonitor;
public class NDS32Analyzer extends ConstantPropagationAnalyzer {
private final static String PROCESSOR_NAME = "NDS32";
private static final String RECOVER_GP_OPTION_NAME = "Recover global GP register writes";
private static final String RECOVER_GP_OPTION_DESCRIPTION = "Reads the global GP value from the symbol _SDA_BASE_";
private static final boolean RECOVER_GP_OPTION_DEFAULT_VALUE = true;
//private boolean recoverSwitchTables = SWITCH_OPTION_DEFAULT_VALUE;
private boolean recoverGp = RECOVER_GP_OPTION_DEFAULT_VALUE;
private Address gpAssumptionValue = null;
private Register gp;
public NDS32Analyzer() {
super(PROCESSOR_NAME);
}
@Override
public boolean canAnalyze(Program program) {
boolean canAnalyze = program.getLanguage().getProcessor().equals(
Processor.findOrPossiblyCreateProcessor(PROCESSOR_NAME));
if (!canAnalyze) {
return false;
}
gp = program.getRegister("gp");
return true;
}
@Override
public void optionsChanged(Options options, Program program) {
super.optionsChanged(options, program);
options.registerOption(RECOVER_GP_OPTION_NAME, recoverGp, null,
RECOVER_GP_OPTION_DESCRIPTION);
recoverGp = options.getBoolean(RECOVER_GP_OPTION_NAME, recoverGp);
}
@Override
public boolean added(Program program, AddressSetView set, TaskMonitor monitor, MessageLog log)
throws CancelledException {
gpAssumptionValue = null;
checkForGlobalGP(program, set, monitor);
return super.added(program, set, monitor, log);
}
/**
* Check for a global GP register symbol or discovered symbol
* @param program
* @param set
* @param monitor
*/
private void checkForGlobalGP(Program program, AddressSetView set, TaskMonitor monitor) {
if (!recoverGp) {
return;
}
Symbol symbol = SymbolUtilities.getLabelOrFunctionSymbol(program, "_SDA_BASE_",
err -> Msg.error(this, err));
if (symbol != null) {
gpAssumptionValue = symbol.getAddress();
return;
}
// TODO : if the symbol doesn't exist, check manually... somewhere else
return;
}
@Override
public AddressSetView flowConstants(final Program program, Address flowStart,
AddressSetView flowSet, final SymbolicPropogator symEval, final TaskMonitor monitor)
throws CancelledException {
// get the function body
final Function func = program.getFunctionManager().getFunctionContaining(flowStart);
final AddressSet coveredSet = new AddressSet();
Address currentGPAssumptionValue = gpAssumptionValue;
// TODO : copypaste more code from MipsAddressAnalyzer to see if gp is written and act accordingly
if (func != null) {
flowStart = func.getEntryPoint();
if (currentGPAssumptionValue != null) {
ProgramContext programContext = program.getProgramContext();
RegisterValue gpVal = programContext.getRegisterValue(gp, flowStart);
if (gpVal == null || !gpVal.hasValue()) {
gpVal = new RegisterValue(gp,
BigInteger.valueOf(currentGPAssumptionValue.getOffset()));
try {
program.getProgramContext().setRegisterValue(func.getEntryPoint(),
func.getEntryPoint(), gpVal);
}
catch (ContextChangeException e) {
throw new AssertException("unexpected", e); // only happens for context register
}
}
}
}
ContextEvaluator eval = new ConstantPropagationContextEvaluator(monitor, trustWriteMemOption) {
@Override
public boolean evaluateDestination(VarnodeContext context, Instruction instruction) {
FlowType flowtype = instruction.getFlowType();
if (!flowtype.isJump()) {
return false;
}
return false;
}
};
AddressSet resultSet = symEval.flowConstants(flowStart, null, eval, true, monitor);
// Add in any addresses we should assume got covered
// These addresses are put on because we had to stop analysis due to an unknown register value
resultSet.add(coveredSet);
return resultSet;
}
}

View File

@@ -0,0 +1,96 @@
/* ###
* 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;
import java.util.Map;
import ghidra.app.util.bin.format.elf.*;
import ghidra.app.util.importer.MessageLog;
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.program.model.reloc.RelocationResult;
import ghidra.program.model.reloc.Relocation.Status;
public class NDS32_ElfRelocationHandler extends AbstractElfRelocationHandler<NDS32_ElfRelocationType, ElfRelocationContext<?>> {
public NDS32_ElfRelocationHandler() {
super(NDS32_ElfRelocationType.class);
}
@Override
public boolean canRelocate(ElfHeader elf) {
return elf.e_machine() == ElfConstants.EM_NDS32;
}
@Override
public int getRelrRelocationType() {
return NDS32_ElfRelocationType.R_NDS32_RELATIVE.typeId;
}
@Override
protected RelocationResult relocate(ElfRelocationContext<?> elfRelocationContext,
ElfRelocation relocation, NDS32_ElfRelocationType type, Address relocationAddress,
ElfSymbol sym, Address symbolAddr, long symbolValue, String symbolName)
throws MemoryAccessException {
ElfRelocationContext<?> nds32RelocationContext = elfRelocationContext;
int symbolIndex = relocation.getSymbolIndex();
return doRelocate(nds32RelocationContext, type, symbolIndex, relocation, relocationAddress);
}
private RelocationResult doRelocate(ElfRelocationContext<?> nds32RelocationContext, NDS32_ElfRelocationType type,
int symbolIndex, ElfRelocation relocation, Address relocationAddress)
throws MemoryAccessException {
Program program = nds32RelocationContext.getProgram();
Memory memory = program.getMemory();
MessageLog log = nds32RelocationContext.getLog();
ElfSymbol elfSymbol = nds32RelocationContext.getSymbol(symbolIndex);
long symbolValue = nds32RelocationContext.getSymbolValue(elfSymbol);
String symbolName = elfSymbol.getNameAsString();
// Read instruction as big endian
int oldValue = memory.getInt(relocationAddress, true);
long addend = 0;
if(relocation.hasAddend()) {
addend = relocation.getAddend();
}
int value = 0;
int newValue = 0;
int byteLength = 4;
switch(type) {
case R_NDS32_HI20_RELA:
value = (int)(symbolValue + addend);
newValue = (oldValue & 0xfff00000) | (value >> 12);
memory.setInt(relocationAddress, newValue, true);
return new RelocationResult(Status.APPLIED, byteLength);
case R_NDS32_LO12S0_RELA:
value = (int)(symbolValue + addend);
newValue = (oldValue & 0xfffff000) | (value & 0xfff);
memory.setInt(relocationAddress, newValue, true);
return new RelocationResult(Status.APPLIED, byteLength);
default:
return RelocationResult.UNSUPPORTED;
}
}
}

View File

@@ -0,0 +1,195 @@
/* ###
* 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;
public enum NDS32_ElfRelocationType implements ElfRelocationType {
/* REL relocations. */
R_NDS32_16(1),
R_NDS32_32(2),
R_NDS32_20(3),
R_NDS32_9_PCREL(4),
R_NDS32_15_PCREL(5),
R_NDS32_17_PCREL(6),
R_NDS32_25_PCREL(7),
R_NDS32_HI20(8),
R_NDS32_LO12S3(9),
R_NDS32_LO12S2(10),
R_NDS32_LO12S1(11),
R_NDS32_LO12S0(12),
R_NDS32_SDA15S3(13),
R_NDS32_SDA15S2(14),
R_NDS32_SDA15S1(15),
R_NDS32_SDA15S0(16),
R_NDS32_GNU_VTINHERIT(17),
R_NDS32_GNU_VTENTRY(18),
/* RELA relocations. */
R_NDS32_16_RELA(19),
R_NDS32_32_RELA(20),
R_NDS32_20_RELA(21),
R_NDS32_9_PCREL_RELA(22),
R_NDS32_15_PCREL_RELA(23),
R_NDS32_17_PCREL_RELA(24),
R_NDS32_25_PCREL_RELA(25),
R_NDS32_HI20_RELA(26),
R_NDS32_LO12S3_RELA(27),
R_NDS32_LO12S2_RELA(28),
R_NDS32_LO12S1_RELA(29),
R_NDS32_LO12S0_RELA(30),
R_NDS32_SDA15S3_RELA(31),
R_NDS32_SDA15S2_RELA(32),
R_NDS32_SDA15S1_RELA(33),
R_NDS32_SDA15S0_RELA(34),
R_NDS32_RELA_GNU_VTINHERIT(35),
R_NDS32_RELA_GNU_VTENTRY(36),
/* GOT and PLT. */
R_NDS32_GOT20(37),
R_NDS32_25_PLTREL(38),
R_NDS32_COPY(39),
R_NDS32_GLOB_DAT(40),
R_NDS32_JMP_SLOT(41),
R_NDS32_RELATIVE(42),
R_NDS32_GOTOFF(43),
R_NDS32_GOTPC20(44),
R_NDS32_GOT_HI20(45),
R_NDS32_GOT_LO12(46),
R_NDS32_GOTPC_HI20(47),
R_NDS32_GOTPC_LO12(48),
R_NDS32_GOTOFF_HI20(49),
R_NDS32_GOTOFF_LO12(50),
/* 32_to_16 relaxations. */
R_NDS32_INSN16(51),
/* Alignment tag. */
R_NDS32_LABEL(52),
R_NDS32_LONGCALL1(53), /* This is obsoleted. */
R_NDS32_LONGCALL2(54), /* This is obsoleted. */
R_NDS32_LONGCALL3(55), /* This is obsoleted. */
R_NDS32_LONGJUMP1(56), /* This is obsoleted. */
R_NDS32_LONGJUMP2(57), /* This is obsoleted. */
R_NDS32_LONGJUMP3(58), /* This is obsoleted. */
R_NDS32_LOADSTORE(59), /* This is obsoleted. */
R_NDS32_9_FIXED_RELA(60),
R_NDS32_15_FIXED_RELA(61),
R_NDS32_17_FIXED_RELA(62),
R_NDS32_25_FIXED_RELA(63),
R_NDS32_PLTREL_HI20(64), /* This is obsoleted. */
R_NDS32_PLTREL_LO12(65), /* This is obsoleted. */
R_NDS32_PLT_GOTREL_HI20(66),
R_NDS32_PLT_GOTREL_LO12(67),
R_NDS32_SDA12S2_DP_RELA(68),
R_NDS32_SDA12S2_SP_RELA(69),
R_NDS32_LO12S2_DP_RELA(70),
R_NDS32_LO12S2_SP_RELA(71),
R_NDS32_LO12S0_ORI_RELA(72),
R_NDS32_SDA16S3_RELA(73),
R_NDS32_SDA17S2_RELA(74),
R_NDS32_SDA18S1_RELA(75),
R_NDS32_SDA19S0_RELA(76),
R_NDS32_DWARF2_OP1_RELA(77), /* This is obsoleted. */
R_NDS32_DWARF2_OP2_RELA(78), /* This is obsoleted. */
R_NDS32_DWARF2_LEB_RELA(79), /* This is obsoleted. */
R_NDS32_UPDATE_TA_RELA(80), /* This is obsoleted. */
R_NDS32_9_PLTREL(81),
R_NDS32_PLT_GOTREL_LO20(82),
R_NDS32_PLT_GOTREL_LO15(83),
R_NDS32_PLT_GOTREL_LO19(84),
R_NDS32_GOT_LO15(85),
R_NDS32_GOT_LO19(86),
R_NDS32_GOTOFF_LO15(87),
R_NDS32_GOTOFF_LO19(88),
R_NDS32_GOT15S2_RELA(89),
R_NDS32_GOT17S2_RELA(90),
R_NDS32_5_RELA(91),
R_NDS32_10_UPCREL_RELA(92), /* This is obsoleted. */
R_NDS32_SDA_FP7U2_RELA(93),
R_NDS32_WORD_9_PCREL_RELA(94),
R_NDS32_25_ABS_RELA(95),
R_NDS32_17IFC_PCREL_RELA(96), /* This is obsoleted. */
R_NDS32_10IFCU_PCREL_RELA(97), /* This is obsoleted. */
/* TLS support. */
R_NDS32_TLS_LE_HI20(98),
R_NDS32_TLS_LE_LO12(99),
R_NDS32_TLS_IE_HI20(100),
R_NDS32_TLS_IE_LO12S2(101),
R_NDS32_TLS_TPOFF(102),
R_NDS32_TLS_LE_20(103),
R_NDS32_TLS_LE_15S0(104),
R_NDS32_TLS_LE_15S1(105),
R_NDS32_TLS_LE_15S2(106),
R_NDS32_LONGCALL4(107),
R_NDS32_LONGCALL5(108),
R_NDS32_LONGCALL6(109),
R_NDS32_LONGJUMP4(110),
R_NDS32_LONGJUMP5(111),
R_NDS32_LONGJUMP6(112),
R_NDS32_LONGJUMP7(113),
/* Reserved numbers: 114. */
/* TLS support */
R_NDS32_TLS_IE_LO12(115),
R_NDS32_TLS_IEGP_HI20(116),
R_NDS32_TLS_IEGP_LO12(117),
R_NDS32_TLS_IEGP_LO12S2(118),
R_NDS32_TLS_DESC(119),
R_NDS32_TLS_DESC_HI20(120),
R_NDS32_TLS_DESC_LO12(121),
R_NDS32_TLS_DESC_20(122),
R_NDS32_TLS_DESC_SDA17S2(123),
/* Reserved numbers: 124-191. */
/* These used only for relaxations */
R_NDS32_RELAX_ENTRY(192),
R_NDS32_GOT_SUFF(193),
R_NDS32_GOTOFF_SUFF(194),
R_NDS32_PLT_GOT_SUFF(195),
R_NDS32_MULCALL_SUFF(196), /* This is obsoleted. */
R_NDS32_PTR(197),
R_NDS32_PTR_COUNT(198),
R_NDS32_PTR_RESOLVED(199),
R_NDS32_PLTBLOCK(200), /* This is obsoleted. */
R_NDS32_RELAX_REGION_BEGIN(201),
R_NDS32_RELAX_REGION_END(202),
R_NDS32_MINUEND(203),
R_NDS32_SUBTRAHEND(204),
R_NDS32_DIFF8(205),
R_NDS32_DIFF16(206),
R_NDS32_DIFF32(207),
R_NDS32_DIFF_ULEB128(208),
R_NDS32_DATA(209),
R_NDS32_TRAN(210),
/* TLS support */
R_NDS32_TLS_LE_ADD(211),
R_NDS32_TLS_LE_LS(212),
R_NDS32_EMPTY(213),
R_NDS32_TLS_DESC_ADD(214),
R_NDS32_TLS_DESC_FUNC(215),
R_NDS32_TLS_DESC_CALL(216),
R_NDS32_TLS_DESC_MEM(217),
R_NDS32_RELAX_REMOVE(218),
R_NDS32_RELAX_GROUP(219),
R_NDS32_TLS_IEGP_LW(220),
R_NDS32_LSI(221),
R_NDS32_RELA_NOP_MAX(255);
public final int typeId;
private NDS32_ElfRelocationType(int typeId) {
this.typeId = typeId;
}
@Override
public int typeId() {
return typeId;
}
}

View File

@@ -0,0 +1,41 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.test.processors;
import ghidra.test.processors.support.ProcessorEmulatorTestAdapter;
import junit.framework.Test;
public class NDS32_BE_O0_EmulatorTest extends ProcessorEmulatorTestAdapter {
private static final String LANGUAGE_ID = "NDS32:BE:32:default";
private static final String COMPILER_SPEC_ID = "default";
private static final String[] REG_DUMP_SET = new String[] {};
public NDS32_BE_O0_EmulatorTest(String name) throws Exception {
super(name, LANGUAGE_ID, COMPILER_SPEC_ID, REG_DUMP_SET);
}
@Override
protected String getProcessorDesignator() {
return "NDS32BE_GCC_O0";
}
public static Test suite() {
return ProcessorEmulatorTestAdapter.buildEmulatorTestSuite(NDS32_BE_O0_EmulatorTest.class);
}
}

View File

@@ -0,0 +1,41 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.test.processors;
import ghidra.test.processors.support.ProcessorEmulatorTestAdapter;
import junit.framework.Test;
public class NDS32_BE_O3_EmulatorTest extends ProcessorEmulatorTestAdapter {
private static final String LANGUAGE_ID = "NDS32:BE:32:default";
private static final String COMPILER_SPEC_ID = "default";
private static final String[] REG_DUMP_SET = new String[] {};
public NDS32_BE_O3_EmulatorTest(String name) throws Exception {
super(name, LANGUAGE_ID, COMPILER_SPEC_ID, REG_DUMP_SET);
}
@Override
protected String getProcessorDesignator() {
return "NDS32BE_GCC_O3";
}
public static Test suite() {
return ProcessorEmulatorTestAdapter.buildEmulatorTestSuite(NDS32_BE_O3_EmulatorTest.class);
}
}

View File

@@ -0,0 +1,41 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.test.processors;
import ghidra.test.processors.support.ProcessorEmulatorTestAdapter;
import junit.framework.Test;
public class NDS32_LE_O0_EmulatorTest extends ProcessorEmulatorTestAdapter {
private static final String LANGUAGE_ID = "NDS32:LE:32:default";
private static final String COMPILER_SPEC_ID = "default";
private static final String[] REG_DUMP_SET = new String[] {};
public NDS32_LE_O0_EmulatorTest(String name) throws Exception {
super(name, LANGUAGE_ID, COMPILER_SPEC_ID, REG_DUMP_SET);
}
@Override
protected String getProcessorDesignator() {
return "NDS32LE_GCC_O0";
}
public static Test suite() {
return ProcessorEmulatorTestAdapter.buildEmulatorTestSuite(NDS32_LE_O0_EmulatorTest.class);
}
}

View File

@@ -0,0 +1,41 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.test.processors;
import ghidra.test.processors.support.ProcessorEmulatorTestAdapter;
import junit.framework.Test;
public class NDS32_LE_O3_EmulatorTest extends ProcessorEmulatorTestAdapter {
private static final String LANGUAGE_ID = "NDS32:LE:32:default";
private static final String COMPILER_SPEC_ID = "default";
private static final String[] REG_DUMP_SET = new String[] {};
public NDS32_LE_O3_EmulatorTest(String name) throws Exception {
super(name, LANGUAGE_ID, COMPILER_SPEC_ID, REG_DUMP_SET);
}
@Override
protected String getProcessorDesignator() {
return "NDS32LE_GCC_O3";
}
public static Test suite() {
return ProcessorEmulatorTestAdapter.buildEmulatorTestSuite(NDS32_LE_O3_EmulatorTest.class);
}
}

View File

@@ -20,7 +20,8 @@ simm18_lh: val is sop3131 & op1516 & op1719 & op2020 & op2130 [ val = (sop3131<<
export *[const]:$(XLEN) val;
}
simm18_lw: val is sop3131 & op1516 & op1719 & op2020 & op2130 [ val = (sop3131<<18) | (op1516<<16) | (op1719<<13) | (op2020<<12) | (op2130<<2); ] {
#simm18_lw: val is sop3131 & op1516 & op1719 & op2020 & op2130 [ val = (sop3131<<18) | (op1516<<16) | (op1719<<13) | (op2020<<12) | (op2130<<2); ] {
simm18_lw: val is sop3131 & op2121 & op1516 & op1719 & op2020 & op2230 [ val = (sop3131<<18) | (op2121 << 17) | (op1516<<15) | (op1719<<12) | (op2020<<11) | (op2230<<2); ] {
export *[const]:$(XLEN) val;
}

View File

@@ -1231,6 +1231,7 @@ define token instr (32)
op2122=(21,22)
op2130=(21,30)
op2222=(22,22)
op2230=(22,30)
op2323=(23,23)
op2324=(23,24)
op2330=(23,30)