Move the 'sh' plugin to the new home ##arch

* Honor regprofiles from arch via anal
* Add some more plugins for the wasi builds
This commit is contained in:
pancake 2022-11-09 18:51:50 +01:00 committed by GitHub
parent ec25b8ab8b
commit 4c834515da
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 336 additions and 276 deletions

View File

@ -18,96 +18,96 @@ bin_xtr.xtr_fatmach0
bin_xtr.xtr_sep64
"
SHARED="
core.java
core.a2f
bp.arm
bp.x86
bp.mips
cmd.dummy
esil.dummy
egg.exec
egg.xor
io.debug
io.malloc
io.sparse
parse.att2intel
parse.mips_pseudo
parse.tms320_pseudo
parse.dalvik_pseudo
parse.x86_pseudo
parse.6502_pseudo
parse.wasm_pseudo
asm.vasm
anal.ppc_cs
io.mach
io.debug
io.mmap
io.w32
io.w32dbg
io.ihex
crypto.aes
io.rap
io.ewf
io.http
io.bfdbg
io.gdb
io.bochs
io.haret
bin_xtr.dyldcache
fs.fat
fs.ntfs
fs.ext2
fs.hfs
fs.hfsplus
fs.reiserfs
fs.tar
fs.cpio
fs.xfs
fs.iso9660
fs.udf
fs.ufs
fs.posix
fs.jfs
fs.minix
fs.fb
fs.sfs
io.ptrace
io.procpid
io.shm
io.zip
asm.sparc
asm.arm
asm.x86_nz
asm.mips_cs
anal.avr
anal.mips_cs
anal.x86_cs
anal.arm_cs
anal.java
anal.dalvik
anal.ppc
anal.sparc
anal.8051
anal.i8080
anal.arc
anal.arm_cs
anal.avr
anal.bf
anal.z80
anal.xap
anal.tms320
anal.dalvik
anal.i8080
anal.java
anal.m68k
anal.sh
anal.mips_cs
anal.ppc
anal.ppc_cs
anal.sparc
anal.tms320
anal.x86_cs
anal.x86_im
anal.x86_simple
anal.xap
anal.z80
arch.sh
asm.arm
asm.mips_cs
asm.rar
asm.sparc
asm.vasm
asm.x86_nz
bin.fs
bin.p9
bin.rar
bin.te
bin_xtr.dyldcache
bp.arm
bp.bf
bp.mips
bp.ppc
debug.native
bp.x86
cmd.dummy
core.a2f
core.java
crypto.aes
debug.bf
debug.esil
debug.gdb
debug.native
debug.rap
debug.bf
asm.rar
io.shm"
egg.exec
egg.xor
esil.dummy
fs.cpio
fs.ext2
fs.fat
fs.fb
fs.hfs
fs.hfsplus
fs.iso9660
fs.jfs
fs.minix
fs.ntfs
fs.posix
fs.reiserfs
fs.sfs
fs.tar
fs.udf
fs.ufs
fs.xfs
io.bfdbg
io.bochs
io.debug
io.debug
io.ewf
io.gdb
io.haret
io.http
io.ihex
io.mach
io.malloc
io.mmap
io.procpid
io.ptrace
io.rap
io.shm
io.shm
io.sparse
io.w32
io.w32dbg
io.zip
parse.6502_pseudo
parse.att2intel
parse.dalvik_pseudo
parse.mips_pseudo
parse.tms320_pseudo
parse.wasm_pseudo
parse.x86_pseudo"

View File

@ -38,7 +38,6 @@ anal.null
anal.pdp11_gnu
anal.ppc_cs
anal.ppc_gnu
anal.sh
anal.sparc_cs
anal.sparc_gnu
anal.s390_cs
@ -66,6 +65,7 @@ anal.pickle
anal.propeller
arch.null
arch.jdh8
arch.sh
arch.i4004
arch.amd29k
esil.dummy

View File

@ -73,7 +73,7 @@ anal.z80
anal.xap
anal.tms320
anal.m68k
anal.sh
arch.sh
anal.x86_im
anal.x86_simple
bin.fs

View File

@ -33,7 +33,7 @@ anal.lm32
anal.pdp11_gnu
anal.ppc_cs
anal.ppc_gnu
anal.sh
arch.sh
anal.sparc_cs
anal.sparc_gnu
anal.s390_cs

View File

@ -29,7 +29,7 @@ anal.mcs96
anal.s390_gnu
anal.hppa_gnu
anal.lm32
anal.sh
arch.sh
anal.sparc_gnu
anal.tricore
anal.v850

View File

@ -25,7 +25,7 @@ anal.nios2
anal.null
anal.ppc_cs
anal.ppc_gnu
anal.sh
arch.sh
anal.sparc_cs
anal.sparc_gnu
anal.s390_cs

View File

@ -15,7 +15,7 @@ anal.mips_cs
anal.mcs96
anal.nios2
anal.null
anal.sh
arch.sh
anal.sparc_cs
anal.s390_cs
anal.ws

View File

@ -4,6 +4,12 @@ asm.arm
asm.null
anal.dalvik
anal.wasm
anal.pyc
anal.bf
anal.bpf
anal.riscv
anal.ppc_gnu
anal.mips_cs
anal.x86_cs
anal.arm_cs
anal.null
@ -18,6 +24,9 @@ crypto.aes
fs.posix
fs.io
fs.r2
fs.fat
fs.zip
fs.cpio
bin.any
bin.elf
bin.elf64
@ -36,8 +45,9 @@ core.a2f
core.sixref
bp.arm
cmd.dummy
egg.exec
egg.xor
lang.spp
lang.pipe
debug.esil
debug.null
io.debug

View File

@ -66,14 +66,10 @@ static void zign_rename_for(REvent *ev, int type, void *user, void *data) {
void r_anal_hint_storage_init(RAnal *a);
void r_anal_hint_storage_fini(RAnal *a);
static void r_meta_item_fini(RAnalMetaItem *item) {
free (item->str);
}
static void r_meta_item_free(void *_item) {
if (_item) {
RAnalMetaItem *item = _item;
r_meta_item_fini (item);
free (item->str);
free (item);
}
}
@ -234,7 +230,7 @@ R_API bool r_anal_use(RAnal *anal, const char *name) {
if (anal->arch) {
bool res = r_arch_use (anal->arch, anal->config, name);
if (res) {
R_LOG_DEBUG ("sing experimental '%s' r_arch plugin", name);
r_anal_set_reg_profile (anal, NULL);
return true;
} else {
anal->arch->current = NULL;
@ -261,18 +257,27 @@ R_API bool r_anal_use(RAnal *anal, const char *name) {
}
R_API char *r_anal_get_reg_profile(RAnal *anal) {
if (anal->arch && anal->arch->current && anal->arch->current->p && anal->arch->current->p->set_reg_profile) {
eprintf ("WINRAR must get wat awat at\n");
}
return (anal && anal->cur && anal->cur->get_reg_profile)
? anal->cur->get_reg_profile (anal) : NULL;
}
// deprecate.. or at least reuse get_reg_profile...
R_API bool r_anal_set_reg_profile(RAnal *anal, const char *p) {
R_DEPRECATE R_API bool r_anal_set_reg_profile(RAnal *anal, const char *p) {
if (p) {
return r_reg_set_profile_string (anal->reg, p);
}
/// if the code goes this way, it means that we are expecting the anal plugin to give us the regprofile which should be deprecated
bool ret = false;
if (anal && anal->cur && anal->cur->set_reg_profile) {
ret = anal->cur->set_reg_profile (anal);
} else if (anal->arch && anal->arch->current && anal->arch->current->p && anal->arch->current->p->set_reg_profile) {
// RArchPluginRegistersCallback set_reg_profile = R_UNWRAP5 (anal, arch, current, p, regs);
ret = anal->arch->current->p->set_reg_profile (anal->arch->cfg, anal->reg);
} else if (anal->arch && anal->arch->current && anal->arch->current->p && anal->arch->current->p->set_reg_profile) {
ret = anal->arch->current->p->set_reg_profile (anal->arch->cfg, anal->reg);
} else {
char *p = r_anal_get_reg_profile (anal);
if (p && *p) {
@ -722,7 +727,7 @@ R_API void r_anal_bind(RAnal *anal, RAnalBind *b) {
b->anal = anal;
b->get_fcn_in = r_anal_get_fcn_in;
b->get_hint = r_anal_hint_get;
b->encode = (RAnalEncode)r_anal_opasm; // TODO rename to encode
b->encode = (RAnalEncode)r_anal_opasm; // TODO rename to encode.. and use r_arch_encode when all plugs are moved
b->decode = (RAnalDecode)r_anal_op; // TODO rename to decode
b->opinit = r_anal_op_init;
b->mnemonics = r_anal_mnemonics;
@ -784,6 +789,6 @@ R_API void r_anal_remove_import(RAnal *anal, const char *imp) {
}
R_API void r_anal_purge_imports(RAnal *anal) {
R_DIRTY(anal);
r_list_purge (anal->imports);
R_DIRTY (anal);
}

View File

@ -119,8 +119,6 @@ r_anal_sources = [
'../asm/arch/s390/gnu/s390-opc.c',
'../asm/arch/sparc/gnu/sparc-dis.c',
'../asm/arch/sparc/gnu/sparc-opc.c',
'p/anal_sh.c',
'../asm/arch/sh/gnu/sh-dis.c',
'p/anal_snes.c',
'p/anal_lm32.c',
'p/anal_sparc_cs.c',

View File

@ -1,10 +0,0 @@
OBJ_SH=anal_sh.o
OBJ_SH+=../../asm/arch/sh/gnu/sh-dis.o
STATIC_OBJ+=$(OBJ_SH)
TARGET_SH=anal_sh.$(EXT_SO)
ALL_TARGETS+=$(TARGET_SH)
$(TARGET_SH): $(OBJ_SH)
$(CC) $(call libname,anal_sh) $(LDFLAGS) $(CFLAGS) -o anal_sh.$(EXT_SO) $(OBJ_SH)

View File

@ -4,6 +4,7 @@ NAME=r_arch
R2DEPS+=r_util r_reg
CFLAGS+=-DR2_PLUGIN_INCORE
CFLAGS:=-I.. -I$(LTOP)/asm/arch/include -DR2_PLUGIN_INCORE -Iarch -I$(TOP)/shlr $(CFLAGS)
.PHONY: pre
pre: libr_arch.$(EXT_SO) libr_arch.$(EXT_AR)

View File

@ -6,6 +6,7 @@
static const RArchPlugin * const arch_static_plugins[] = { R_ARCH_STATIC_PLUGINS };
static void plugin_free(void *p) {
// XXX
}
static void _decoder_free_cb(HtPPKv *kv) {
@ -289,11 +290,12 @@ R_API bool r_arch_del(RArch *arch, const char *name) {
}
R_API void r_arch_free(RArch *arch) {
r_return_if_fail (arch);
ht_pp_free (arch->decoders);
r_list_free (arch->plugins);
r_unref (arch->cfg);
free (arch);
if (arch) {
ht_pp_free (arch->decoders);
r_list_free (arch->plugins);
r_unref (arch->cfg);
free (arch);
}
}
#if 0

View File

@ -1,6 +1,5 @@
/* radare - LGPL - Copyright 2010-2022 - pancake, condret */
#if 0
#include <r_arch.h>
#include <r_io.h>
#include <r_reg.h>
@ -8,6 +7,7 @@
R_API RArchValue *r_arch_value_new(void) { //macro for this ?
return R_NEW0 (RArchValue);
}
#if 0
R_API RArchValue *r_arch_value_copy(RArchValue *ov) {
r_return_val_if_fail (ov, NULL);

View File

@ -135,5 +135,5 @@ R_API int r_arch_decode(RArch *arch, const char *dname, RAnalOp *op, ut64 addr,
if (!decoder || !decoder->p->decode) {
return -1;
}
return decoder->p->decode (arch->cfg, op, addr, data, len, mask, decoder->user);
return decoder->p->decode (arch, op, addr, data, len, mask, decoder->user);
}

View File

@ -9,10 +9,9 @@
R_API int r_arch_encode(RArch *a, ut64 addr, const char *s, ut8 *outbuf, int outlen) {
int res = 0;
RArchOpAsmCallback opasm = R_UNWRAP4 (a, current, p, opasm);
if (opasm) { // a->current && a->current->p && a->current->p->opasm) {
res = opasm (a, addr, s, outbuf, outlen);
RArchOpAsmCallback encode = R_UNWRAP4 (a, current, p, encode);
if (encode) {
res = encode (a, addr, s, outbuf, outlen);
}
return res;
}

View File

@ -11,10 +11,14 @@ r_arch_sources = [
'p/arch_i4004.c',
'p/arch_amd29k.c',
'p/arch_jdh8.c',
'p/arch_sh.c',
'p/sh/gnu/sh-dis.c',
]
arch_inc = include_directories('../asm/arch/include')
r_arch = library('r_arch', r_arch_sources,
include_directories: [platform_inc],
include_directories: [platform_inc, arch_inc],
c_args: library_cflags,
dependencies: [
r_util_dep,
@ -31,7 +35,7 @@ r_arch_dep = declare_dependency(link_with: r_arch,
if get_option('blob')
r_arch_static = static_library('r_arch_static', r_arch_sources,
include_directories: [platform_inc],
include_directories: [platform_inc, arch_inc],
c_args: library_cflags,
dependencies: [r_util_static_dep],
install: true,

View File

@ -903,7 +903,8 @@ static int archinfo(RArchConfig *cfg, ut32 q) {
return 4;
}
static int decode(RArchConfig *cfg, RAnalOp *op, ut64 addr, const ut8 *buf, int len, ut32 mask, void *user) {
static int decode(RArch *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len, ut32 mask, void *user) {
RArchConfig *cfg = a->cfg;
op->size = 4;
op->eob = false;

View File

@ -1,9 +1,9 @@
/* radare - LGPL - Copyright 2016-2022 - pancake, condret */
#include <r_arch.h>
#include "../i/i4004/gperfdb.c"
#include "./i4004/gperfdb.c"
static bool set_reg_profile(RArchConfig *cfg, RReg *reg) {
static char *i4004_regs(RArchInstance *a) {
const char *p =
"=PC PC\n"
/* syntax not yet supported */
@ -43,7 +43,7 @@ static bool set_reg_profile(RArchConfig *cfg, RReg *reg) {
"gpr PC2 .12 .104 0\n"
"gpr PC3 .12 .120 0\n"
;
return r_reg_set_profile_string (reg, p);
return strdup (p);
}
/* That 3 is a hack */
@ -98,7 +98,7 @@ static int i4004_get_ins_len(ut8 hex) {
return ret;
}
static int i4004_decode(RArchConfig *cfg, RAnalOp *op, ut64 addr, const ut8 *buf, int len, ut32 mask, void *user) {
static int i4004_decode(RArch *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len, ut32 mask, void *user) {
char basm[64];
const size_t basz = sizeof (basm);
int rlen = i4004_get_ins_len (*buf);
@ -251,7 +251,7 @@ static int i4004_decode(RArchConfig *cfg, RAnalOp *op, ut64 addr, const ut8 *buf
return op->size = rlen;
}
static int i4004_anal_opasm(RArch *a, ut64 addr, const char *str, ut8 *outbuf, int outsize) {
static int i4004_encode(RArch *a, ut64 addr, const char *str, ut8 *outbuf, int outsize) {
char *s = strdup (str);
r_str_case (s, false);
s = r_str_replace (s, "_", "?", false); // mitigate a bug in sdb -C
@ -391,8 +391,8 @@ RArchPlugin r_arch_plugin_i4004 = {
.esil = false,
.author = "pancake, condret",
.decode = &i4004_decode,
.opasm = &i4004_anal_opasm,
.set_reg_profile = &set_reg_profile
.encode = &i4004_encode,
.regs = &i4004_regs,
};
#ifndef R2_PLUGIN_INCORE

View File

@ -2,9 +2,9 @@
#include <r_anal.h>
#include <r_lib.h>
#include "../i/jdh8/jdh8dis.c"
#include "./jdh8/jdh8dis.c"
static int decode(RArchConfig *cfg, RAnalOp *op, ut64 addr, const ut8 *buf, int len, ut32 mask, void *user) {
static int decode(RArch *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len, ut32 mask, void *user) {
int dlen = 0;
char *o = jdh8Disass (buf, len, &dlen);
op->mnemonic = strdup (o);

View File

@ -199,46 +199,58 @@ static ut64 disarm_8bit_offset(ut64 pc, ut32 offs) {
return (off << 1) + pc + 4;
}
static char *regs[]={ "r0","r1","r2","r3","r4","r5","r6","r7","r8","r9","r10","r11","r12","r13","r14","r15","pc" };
#if USE_REG_NAMES
static const char *regs[] = { "r0", "r1","r2", "r3", "r4","r5","r6","r7","r8","r9","r10","r11","r12","r13","r14","r15","pc" };
#endif
static RAnalValue *anal_fill_ai_rg(RAnal *anal, int idx) {
RAnalValue *ret = r_anal_value_new ();
ret->reg = r_reg_get (anal->reg, regs[idx], R_REG_TYPE_GPR);
static RArchValue *anal_fill_ai_rg(RArch *anal, int idx) {
RArchValue *ret = r_arch_value_new ();
#if USE_REG_NAMES
ret->reg = regs[idx];
#else
// ret->reg = r_reg_get (anal->reg, regs[idx], R_REG_TYPE_GPR);
#endif
return ret;
}
static RAnalValue *anal_fill_im(RAnal *anal, st32 v) {
RAnalValue *ret = r_anal_value_new ();
static RArchValue *anal_fill_im(RArch *anal, st32 v) {
RArchValue *ret = r_arch_value_new ();
ret->imm = v;
return ret;
}
/* Implements @(disp,Rn), size = 1 for .b, 2 for .w, 4 for .l */
static RAnalValue *anal_fill_reg_disp_mem(RAnal *anal, int reg, st64 delta, st64 size) {
RAnalValue *ret = anal_fill_ai_rg (anal, reg);
ret->memref = size;
ret->delta = delta*size;
static RArchValue *anal_fill_reg_disp_mem(RArch *anal, int reg, st64 delta, st64 size) {
RArchValue *ret = anal_fill_ai_rg (anal, reg);
if (ret) {
ret->memref = size;
ret->delta = delta*size;
}
return ret;
}
/* Rn */
static RAnalValue *anal_fill_reg_ref(RAnal *anal, int reg, st64 size) {
RAnalValue *ret = anal_fill_ai_rg (anal, reg);
static RArchValue *anal_fill_reg_ref(RArch *anal, int reg, st64 size) {
RArchValue *ret = anal_fill_ai_rg (anal, reg);
ret->memref = size;
return ret;
}
/* @(R0,Rx) references for all sizes */
static RAnalValue *anal_fill_r0_reg_ref(RAnal *anal, int reg, st64 size) {
RAnalValue *ret = anal_fill_ai_rg (anal, 0);
ret->regdelta = r_reg_get (anal->reg, regs[reg], R_REG_TYPE_GPR);
static RArchValue *anal_fill_r0_reg_ref(RArch *anal, int reg, st64 size) {
RArchValue *ret = anal_fill_ai_rg (anal, 0);
#if USE_REG_NAMES
ret->regdelta = regs[reg];
#else
// ret->regdelta = r_reg_get (anal->reg, regs[reg], R_REG_TYPE_GPR);
#endif
ret->memref = size;
return ret;
}
// @(disp,PC) for size=2(.w), size=4(.l). disp is 0-extended
static RAnalValue *anal_pcrel_disp_mov(RAnal* anal, RAnalOp* op, ut8 disp, int size) {
RAnalValue *ret = r_anal_value_new ();
static RArchValue *anal_pcrel_disp_mov(RArch* anal, RAnalOp* op, ut8 disp, int size) {
RArchValue *ret = r_arch_value_new ();
if (size==2) {
ret->base = op->addr + 4;
ret->delta = disp << 1;
@ -251,16 +263,20 @@ static RAnalValue *anal_pcrel_disp_mov(RAnal* anal, RAnalOp* op, ut8 disp, int s
}
//= PC+4+R<reg>
static RAnalValue *anal_regrel_jump(RAnal* anal, RAnalOp* op, ut8 reg) {
RAnalValue *ret = r_anal_value_new ();
ret->reg = r_reg_get (anal->reg, regs[reg], R_REG_TYPE_GPR);
static RArchValue *anal_regrel_jump(RArch* anal, RAnalOp* op, ut8 reg) {
RArchValue *ret = r_arch_value_new ();
#if USE_REG_NAMES
ret->reg = regs[reg];
#else
// ret->reg = r_reg_get (anal->reg, regs[reg], R_REG_TYPE_GPR);
#endif
ret->base = op->addr + 4;
return ret;
}
/* 16 decoder routines, based on 1st nibble value */
static int first_nibble_is_0(RAnal* anal, RAnalOp* op, ut16 code) { //STOP
RAnalValue *dst = NULL, *src0 = NULL, *src1 = NULL;
static int first_nibble_is_0(RArch* anal, RAnalOp* op, ut16 code) { //STOP
RArchValue *dst = NULL, *src0 = NULL, *src1 = NULL;
if (IS_BSRF (code)) {
/* Call 'far' subroutine Rn+PC+4 */
op->type = R_ANAL_OP_TYPE_UCALL;
@ -406,35 +422,29 @@ static int first_nibble_is_0(RAnal* anal, RAnalOp* op, ut16 code) { //STOP
}
if (dst) {
r_vector_push (&op->dsts, dst);
r_anal_value_free (dst);
}
if (src0) {
r_vector_push (&op->srcs, src0);
r_anal_value_free (src0);
}
if (src1) {
r_vector_push (&op->srcs, src1);
r_anal_value_free (src1);
}
return op->size;
}
//nibble = 1; 0001nnnnmmmmi4*4 mov.l <REG_M>,@(<disp>,<REG_N>)
static int movl_reg_rdisp(RAnal* anal, RAnalOp* op, ut16 code) {
RAnalValue *dst, *src;
static int movl_reg_rdisp(RArch* anal, RAnalOp* op, ut16 code) {
op->type = R_ANAL_OP_TYPE_STORE;
src = anal_fill_ai_rg (anal, GET_SOURCE_REG (code));
dst = anal_fill_reg_disp_mem (anal, GET_TARGET_REG (code), code & 0x0F, LONG_SIZE);
RArchValue *src = anal_fill_ai_rg (anal, GET_SOURCE_REG (code));
RArchValue *dst = anal_fill_reg_disp_mem (anal, GET_TARGET_REG (code), code & 0x0F, LONG_SIZE);
r_strbuf_setf (&op->esil, "r%d,r%d,0x%x,+,=[4]", GET_SOURCE_REG (code), GET_TARGET_REG (code), (code & 0xF) << 2);
r_vector_push (&op->dsts, dst);
r_vector_push (&op->srcs, src);
r_anal_value_free (dst);
r_anal_value_free (src);
return op->size;
}
static int first_nibble_is_2(RAnal* anal, RAnalOp* op, ut16 code) {
RAnalValue *dst = NULL, *src0 = NULL, *src1 = NULL;
static int first_nibble_is_2(RArch* anal, RAnalOp* op, ut16 code) {
RArchValue *dst = NULL, *src0 = NULL, *src1 = NULL;
if (IS_MOVB_REG_TO_REGREF (code)) { // 0010nnnnmmmm0000 mov.b <REG_M>,@<REG_N>
op->type = R_ANAL_OP_TYPE_STORE;
src0 = anal_fill_ai_rg (anal, GET_SOURCE_REG (code));
@ -505,22 +515,19 @@ static int first_nibble_is_2(RAnal* anal, RAnalOp* op, ut16 code) {
if (dst) {
r_vector_push (&op->dsts, dst);
r_anal_value_free (dst);
}
if (src0) {
r_vector_push (&op->srcs, src0);
r_anal_value_free (src0);
}
if (src1) {
r_vector_push (&op->srcs, src1);
r_anal_value_free (src1);
}
return op->size;
}
static int first_nibble_is_3(RAnal* anal, RAnalOp* op, ut16 code) {
RAnalValue *dst = NULL, *src0 = NULL, *src1 = NULL;
static int first_nibble_is_3(RArch* anal, RAnalOp* op, ut16 code) {
RArchValue *dst = NULL, *src0 = NULL, *src1 = NULL;
//TODO Handle carry/overflow , CMP/xx?
if (IS_ADD (code)) {
op->type = R_ANAL_OP_TYPE_ADD;
@ -618,23 +625,20 @@ static int first_nibble_is_3(RAnal* anal, RAnalOp* op, ut16 code) {
}
if (dst) {
r_vector_push (&op->dsts, dst);
r_anal_value_free (dst);
}
if (src0) {
r_vector_push (&op->srcs, src0);
r_anal_value_free (src0);
}
if (src1) {
r_vector_push (&op->srcs, src1);
r_anal_value_free (src1);
}
return op->size;
}
static int first_nibble_is_4(RAnal* anal, RAnalOp* op, ut16 code) {
RAnalValue *dst = NULL;
static int first_nibble_is_4(RArch* anal, RAnalOp* op, ut16 code) {
RArchValue *dst = NULL;
switch(code & 0xF0FF) { //TODO: change to common } else if construction
case 0x4020: //shal
op->type = R_ANAL_OP_TYPE_SAL;
@ -808,27 +812,24 @@ static int first_nibble_is_4(RAnal* anal, RAnalOp* op, ut16 code) {
}
if (dst) {
r_vector_push (&op->dsts, dst);
r_anal_value_free (dst);
}
return op->size;
}
//nibble=5; 0101nnnnmmmmi4*4 mov.l @(<disp>,<REG_M>),<REG_N>
static int movl_rdisp_reg(RAnal* anal, RAnalOp* op, ut16 code) {
RAnalValue *dst, *src;
static int movl_rdisp_reg(RArch* anal, RAnalOp* op, ut16 code) {
RArchValue *dst, *src;
op->type = R_ANAL_OP_TYPE_LOAD;
dst = anal_fill_ai_rg (anal, GET_TARGET_REG (code));
src = anal_fill_reg_disp_mem (anal, GET_SOURCE_REG (code), code & 0x0F, LONG_SIZE);
r_strbuf_setf (&op->esil, "r%d,0x%x,+,[4],r%d,=", GET_SOURCE_REG (code), (code&0xF) * 4, GET_TARGET_REG (code));
r_vector_push (&op->dsts, dst);
r_vector_push (&op->srcs, src);
r_anal_value_free (dst);
r_anal_value_free (src);
return op->size;
}
static int first_nibble_is_6(RAnal* anal, RAnalOp* op, ut16 code) {
RAnalValue *dst = NULL, *src = NULL;
static int first_nibble_is_6(RArch* anal, RAnalOp* op, ut16 code) {
RArchValue *dst = NULL, *src = NULL;
if (IS_MOV_REGS (code)) {
op->type = R_ANAL_OP_TYPE_MOV;
src = anal_fill_ai_rg (anal, GET_SOURCE_REG (code));
@ -910,32 +911,29 @@ static int first_nibble_is_6(RAnal* anal, RAnalOp* op, ut16 code) {
}
if (dst) {
r_vector_push (&op->dsts, dst);
r_anal_value_free (dst);
}
if (src) {
r_vector_push (&op->srcs, src);
r_anal_value_free (src);
}
return op->size;
}
//nibble=7; 0111nnnni8*1.... add #<imm>,<REG_N>
static int add_imm(RAnal* anal, RAnalOp* op, ut16 code) {
RAnalValue *dst, *src;
static int add_imm(RArch* anal, RAnalOp* op, ut16 code) {
op->type = R_ANAL_OP_TYPE_ADD;
src = anal_fill_im (anal, (st8)(code & 0xFF)); //Casting to (st8) forces sign-extension.
dst = anal_fill_ai_rg (anal, GET_TARGET_REG (code));
// mask ESIL
r_strbuf_setf (&op->esil, "0x%x,DUP,0x80,&,?{,0xFFFFFF00,|,},r%d,+=", code & 0xFF, GET_TARGET_REG (code));
// mask VALUE
RArchValue *src = anal_fill_im (anal, (st8)(code & 0xFF)); //Casting to (st8) forces sign-extension.
RArchValue *dst = anal_fill_ai_rg (anal, GET_TARGET_REG (code));
r_vector_push (&op->dsts, dst);
r_vector_push (&op->srcs, src);
r_anal_value_free (dst);
r_anal_value_free (src);
return op->size;
}
static int first_nibble_is_8(RAnal* anal, RAnalOp* op, ut16 code) {
RAnalValue *dst = NULL, *src = NULL;
static int first_nibble_is_8(RArch* anal, RAnalOp* op, ut16 code) {
RArchValue *dst = NULL, *src = NULL;
if (IS_BT_OR_BF (code)) {
op->type = R_ANAL_OP_TYPE_CJMP; //Jump if true or jump if false insns
op->jump = disarm_8bit_offset (op->addr, GET_BTF_OFFSET (code));
@ -982,33 +980,28 @@ static int first_nibble_is_8(RAnal* anal, RAnalOp* op, ut16 code) {
}
if (dst) {
r_vector_push (&op->dsts, dst);
r_anal_value_free (dst);
}
if (src) {
r_vector_push (&op->srcs, src);
r_anal_value_free (src);
}
return op->size;
}
//nibble=9; 1001nnnni8p2.... mov.w @(<disp>,PC),<REG_N>
static int movw_pcdisp_reg(RAnal* anal, RAnalOp* op, ut16 code) {
RAnalValue *dst, *src;
static int movw_pcdisp_reg(RArch* anal, RAnalOp* op, ut16 code) {
op->type = R_ANAL_OP_TYPE_LOAD;
dst = anal_fill_ai_rg (anal, GET_TARGET_REG (code));
src = r_anal_value_new ();
RArchValue *dst = anal_fill_ai_rg (anal, GET_TARGET_REG (code));
RArchValue *src = r_arch_value_new ();
src->base = (code & 0xFF) * 2+op->addr + 4;
src->memref = 1;
r_strbuf_setf (&op->esil, "0x%" PFMT64x ",[2],r%d,=,r%d,0x8000,&,?{,0xFFFF0000,r%d,|=,}", src->base, GET_TARGET_REG (code), GET_TARGET_REG (code), GET_TARGET_REG (code));
r_vector_push (&op->dsts, dst);
r_vector_push (&op->srcs, src);
r_anal_value_free (dst);
r_anal_value_free (src);
return op->size;
}
//nibble=A; 1010i12......... bra <bdisp12>
static int bra(RAnal* anal, RAnalOp* op, ut16 code) {
static int bra(RArch* anal, RAnalOp* op, ut16 code) {
/* Unconditional branch, relative to PC */
op->type = R_ANAL_OP_TYPE_JMP;
op->delay = 1;
@ -1019,7 +1012,7 @@ static int bra(RAnal* anal, RAnalOp* op, ut16 code) {
}
//nibble=B; 1011i12......... bsr <bdisp12>
static int bsr(RAnal* anal, RAnalOp* op, ut16 code) {
static int bsr(RArch* anal, RAnalOp* op, ut16 code) {
/* Subroutine call, relative to PC */
op->type = R_ANAL_OP_TYPE_CALL;
op->jump = disarm_12bit_offset (op, GET_BRA_OFFSET (code));
@ -1028,8 +1021,8 @@ static int bsr(RAnal* anal, RAnalOp* op, ut16 code) {
return op->size;
}
static int first_nibble_is_c(RAnal* anal, RAnalOp* op, ut16 code) {
RAnalValue *dst = NULL, *src0 = NULL, *src1 = NULL;
static int first_nibble_is_c(RArch* anal, RAnalOp* op, ut16 code) {
RArchValue *dst = NULL, *src0 = NULL, *src1 = NULL;
if (IS_TRAP (code)) {
op->type = R_ANAL_OP_TYPE_SWI;
op->val = (ut8)(code & 0xFF);
@ -1113,58 +1106,48 @@ static int first_nibble_is_c(RAnal* anal, RAnalOp* op, ut16 code) {
if (dst) {
r_vector_push (&op->dsts, dst);
r_anal_value_free (dst);
}
if (src0) {
r_vector_push (&op->srcs, src0);
r_anal_value_free (src0);
}
if (src1) {
r_vector_push (&op->srcs, src1);
r_anal_value_free (src1);
}
return op->size;
}
//nibble=d; 1101nnnni8 : mov.l @(<disp>,PC), Rn
static int movl_pcdisp_reg(RAnal* anal, RAnalOp* op, ut16 code) {
RAnalValue *dst, *src;
// nibble=d; 1101nnnni8 : mov.l @(<disp>,PC), Rn
static int movl_pcdisp_reg(RArch* anal, RAnalOp* op, ut16 code) {
op->type = R_ANAL_OP_TYPE_LOAD;
src = anal_pcrel_disp_mov (anal, op, code & 0xFF, LONG_SIZE);
//TODO: check it
dst = anal_fill_ai_rg (anal, GET_TARGET_REG (code));
//r_strbuf_setf (&op->esil, "0x%x,[4],r%d,=", (code & 0xFF) * 4 + (op->addr & 0xfffffff3) + 4, GET_TARGET_REG (code));
RArchValue *src = anal_pcrel_disp_mov (anal, op, code & 0xFF, LONG_SIZE);
RArchValue *dst = anal_fill_ai_rg (anal, GET_TARGET_REG (code));
// r_strbuf_setf (&op->esil, "0x%x,[4],r%d,=", (code & 0xFF) * 4 + (op->addr & 0xfffffff3) + 4, GET_TARGET_REG (code));
r_strbuf_setf (&op->esil, "0x%" PFMT64x ",[4],r%d,=", (code & 0xFF) * 4 + ((op->addr >> 2)<<2) + 4, GET_TARGET_REG (code));
r_vector_push (&op->dsts, dst);
r_vector_push (&op->srcs, src);
r_anal_value_free (dst);
r_anal_value_free (src);
return op->size;
}
//nibble=e; 1110nnnni8*1.... mov #<imm>,<REG_N>
static int mov_imm_reg(RAnal* anal, RAnalOp* op, ut16 code) {
RAnalValue *dst, *src;
// nibble=e; 1110nnnni8*1.... mov #<imm>,<REG_N>
static int mov_imm_reg(RArch* arch, RAnalOp* op, ut16 code) {
op->type = R_ANAL_OP_TYPE_MOV;
dst = anal_fill_ai_rg (anal, GET_TARGET_REG (code));
src = anal_fill_im (anal, (st8)(code & 0xFF));
RArchValue *dst = anal_fill_ai_rg (arch, GET_TARGET_REG (code));
RArchValue *src = anal_fill_im (arch, (st8)(code & 0xFF));
r_strbuf_setf (&op->esil, "0x%x,r%d,=,r%d,0x80,&,?{,0xFFFFFF00,r%d,|=,}", code & 0xFF, GET_TARGET_REG (code), GET_TARGET_REG (code), GET_TARGET_REG (code));
r_vector_push (&op->dsts, dst);
r_vector_push (&op->srcs, src);
r_anal_value_free (dst);
r_anal_value_free (src);
return op->size;
}
//nibble=f;
static int fpu_insn(RAnal* anal, RAnalOp* op, ut16 code) {
//Not interested on FPU stuff for now
// nibble=f;
static int fpu_insn(RArch* a, RAnalOp* op, ut16 code) {
// Not interested on FPU stuff for now
op->family = R_ANAL_OP_FAMILY_FPU;
return op->size;
}
/* Table of routines for further analysis based on 1st nibble */
static int (*first_nibble_decode[])(RAnal*,RAnalOp*,ut16) = {
static int (*first_nibble_decode[])(RArch*,RAnalOp*,ut16) = {
first_nibble_is_0,
movl_reg_rdisp,
first_nibble_is_2,
@ -1184,7 +1167,8 @@ static int (*first_nibble_decode[])(RAnal*,RAnalOp*,ut16) = {
};
/* Set the profile register */
static bool sh_set_reg_profile(RAnal* anal) {
static bool sh_set_reg_profile(RArchConfig* arch, struct r_reg_t *reg) {
eprintf ("reg profile lol\n");
//TODO Add system ( ssr, spc ) + fpu regs
const char * const p =
"=PC pc\n"
@ -1219,10 +1203,10 @@ static bool sh_set_reg_profile(RAnal* anal) {
"gpr vbr .32 80 0\n"
"gpr mach .32 84 0\n"
"gpr macl .32 88 0\n";
return r_reg_set_profile_string (anal->reg, p);
return r_reg_set_profile_string (reg, p);
}
static int archinfo(RAnal *anal, int q) {
static int archinfo(RArchConfig *a, ut32 q) {
return 2;
}
@ -1256,7 +1240,7 @@ static void memory_error_func(int status, bfd_vma memaddr, struct disassemble_in
DECLARE_GENERIC_PRINT_ADDRESS_FUNC_NOGLOBALS ()
DECLARE_GENERIC_FPRINTF_FUNC_NOGLOBALS ()
static int disassemble(RAnal *a, RAnalOp *op, const ut8 *buf, int len) {
static int disassemble(RArch *a, RAnalOp *op, const ut8 *buf, int len) {
ut8 bytes[BUFSZ] = {0};
struct disassemble_info disasm_obj = {0};
if (len < 2) {
@ -1273,7 +1257,7 @@ static int disassemble(RAnal *a, RAnalOp *op, const ut8 *buf, int len) {
disasm_obj.symbol_at_address_func = &symbol_at_address;
disasm_obj.memory_error_func = &memory_error_func;
disasm_obj.print_address_func = &generic_print_address_func;
disasm_obj.endian = !R_ARCH_CONFIG_IS_BIG_ENDIAN (a->config);
disasm_obj.endian = !R_ARCH_CONFIG_IS_BIG_ENDIAN (a->cfg);
disasm_obj.fprintf_func = &generic_fprintf_func;
disasm_obj.stream = sb;
@ -1292,34 +1276,34 @@ static int disassemble(RAnal *a, RAnalOp *op, const ut8 *buf, int len) {
}
/* This is the basic operation analysis. Just initialize and jump to
* routines defined in first_nibble_decode table
*/
static int sh_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int len, RAnalOpMask mask) {
if (!op || !data || len < 2) {
* routines defined in first_nibble_decode table */
static int sh_op(RArch *a, RAnalOp *op, ut64 addr, const ut8 *data, int len, ut32 mask, void *user) {
// static int sh_op(RArch *a, RAnalOp *op, ut64 addr, const ut8 *data, int len, RAnalOpMask mask) {
if (!op || !a || !data || len < 2) {
return 0;
}
op->addr = addr;
op->type = R_ANAL_OP_TYPE_UNK;
op->size = 2;
if (mask & R_ARCH_OP_MASK_DISASM) {
op->size = disassemble (anal, op, data, len);
op->size = disassemble (a, op, data, len);
// should be always 2?
}
bool be = R_ARCH_CONFIG_IS_BIG_ENDIAN (anal->config);
bool be = R_ARCH_CONFIG_IS_BIG_ENDIAN (a->cfg);
ut8 msb = be? data[0]: data[1];
ut8 lsb = be? data[1]: data[0];
return first_nibble_decode[(msb >> 4) & 0x0F](anal, op, (ut16)(((ut16)msb << 8) | lsb));
return first_nibble_decode[(msb >> 4) & 0x0F](a, op, (ut16)(((ut16)msb << 8) | lsb));
}
RAnalPlugin r_anal_plugin_sh = {
RArchPlugin r_arch_plugin_sh = {
.name = "sh",
.desc = "SH-4 code analysis plugin",
.license = "LGPL3",
.endian = R_SYS_ENDIAN_LITTLE | R_SYS_ENDIAN_BIG,
.arch = "sh",
.archinfo = archinfo,
.info = archinfo,
.bits = 32,
.op = &sh_op,
.decode = &sh_op,
.set_reg_profile = &sh_set_reg_profile,
.esil = true
};
@ -1327,7 +1311,7 @@ RAnalPlugin r_anal_plugin_sh = {
#ifndef R2_PLUGIN_INCORE
R_API RLibStruct radare_plugin = {
.type = R_LIB_TYPE_ANAL,
.data = &r_anal_plugin_sh,
.data = &r_arch_plugin_sh,
.version = R2_VERSION
};
#endif

10
libr/arch/p/sh.mk Normal file
View File

@ -0,0 +1,10 @@
OBJ_SH=arch_sh.o
OBJ_SH+=p/sh/gnu/sh-dis.o
STATIC_OBJ+=$(OBJ_SH)
TARGET_SH=arch_sh.$(EXT_SO)
ALL_TARGETS+=$(TARGET_SH)
$(TARGET_SH): $(OBJ_SH)
$(CC) $(call libname,arch_sh) $(LDFLAGS) $(CFLAGS) -o arch_sh.$(EXT_SO) $(OBJ_SH)

View File

@ -28,35 +28,6 @@ typedef enum {
R_ANAL_STACK_ALIGN,
} RAnalStackOp;
// XXX deprecate those names are uglyies and we can reuse R_PERM
typedef enum {
R_ANAL_ACC_UNKNOWN = 0,
R_ANAL_ACC_R = (1 << 0),
R_ANAL_ACC_W = (1 << 1),
} RAnalValueAccess;
typedef enum {
R_ANAL_VAL_REG,
R_ANAL_VAL_MEM,
R_ANAL_VAL_IMM,
} RAnalValueType;
// base + reg + regdelta * mul + delta
typedef struct r_anal_value_t {
RAnalValueType type;
RAnalValueAccess access;
int absolute; // if true, unsigned cast is used
int memref; // is memory reference? which size? 1, 2 ,4, 8
ut64 base ; // numeric address
st64 delta; // numeric delta
st64 imm; // immediate value
int mul; // multiplier (reg*4+base)
// XXX can be invalidated if regprofile changes causing an UAF
RRegItem *seg; // segment selector register
RRegItem *reg; // register item reference
RRegItem *regdelta; // register index used
} RAnalValue;
typedef enum {
R_ANAL_OP_DIR_READ = 1,
R_ANAL_OP_DIR_WRITE = 2,

View File

@ -87,13 +87,49 @@ typedef struct r_arch_decoder_t {
typedef struct r_arch_t {
RList *plugins; // all plugins
struct r_arch_instance_t *cur; // this var must deprecate current!
RArchDecoder *current; // currently used decoder
HtPP *decoders; // as decoders instantiated plugins
RArchConfig *cfg; // config
bool autoselect;
} RArch;
typedef struct r_arch_instance_t {
struct r_arch_t *arch;
struct r_arch_plugin_t *plugin;
RArchConfig *config; // TODO remove arch->config!
void *data;
void *user;
} RArchInstance;
typedef int (*RArchOpAsmCallback)(RArch *a, ut64 addr, const char *str, ut8 *outbuf, int outlen);
// typedef int (*RArchPluginInfoCallback)(RArchInstance *i, ut32 query);
typedef int (*RArchPluginInfoCallback)(RArchConfig *cfg, ut32 query);
// typedef int (*RArchPluginDecodeCallback)(RArchConfig *cfg, struct r_anal_op_t *op, ut64 addr, const ut8 *data, int len, ut32 mask, void *user);
typedef int (*RArchPluginDecodeCallback)(RArch *cfg, struct r_anal_op_t *op, ut64 addr, const ut8 *data, int len, ut32 mask, void *user);
typedef char *(*RArchPluginRegistersCallback)(RArchInstance *ai);
#if 0
// addr, data/len and *user can be taken from RAnalOp, so the user must fill those fields before calling this functions
R_API int r_arch_op_setbytes(op, ut64 addr, const ut8* data, int len);
typedef bool (*RArchPluginDecodeCallback)(RArchInstance *cfg, struct r_anal_op_t *op, RArchDecodeMask mask);
typedef bool (*RArchPluginEncodeCallback)(RArchInstance *cfg, struct r_anal_op_t *op);
/*
RArchOp op;
RArch *a = r_arch_new ();
RArchConfig *cfg = r_arch_config_new ();
RArchInstance *ai = r_arch_use (a, cfg, "x86");
RArchOp *op = r_arch_new ();
r_arch_op_setbytes (op, 0x10080840, "\x90", 1);
if (r_arch_instance_decode (ai, op)) {
r_cons_printf ("Disasm of 0x90 is %s\n", r_arch_op_tostring (op));
} else {
R_LOG_ERROR ("Cannot disassemble");
}
r_arch_op_free (op);
r_arch_instance_free (ai);
r_arch_free (a);
*/
#endif
typedef struct r_arch_plugin_t {
char *name;
@ -107,12 +143,13 @@ typedef struct r_arch_plugin_t {
ut32 bits;
ut32 addr_bits;
bool esil;
bool (*init)(void **user);
bool (*init)(void **user); // Should return an RArchSession, this struct contains all the info we need
void (*fini)(void *user);
int (*info)(RArchConfig *cfg, ut32 query);
int (*decode)(RArchConfig *cfg, struct r_anal_op_t *op, ut64 addr, const ut8 *data, int len, ut32 mask, void *user);
RArchPluginInfoCallback info;
RArchPluginDecodeCallback decode;
RArchPluginRegistersCallback regs;
bool (*set_reg_profile)(RArchConfig *cfg, struct r_reg_t *reg);
RArchOpAsmCallback opasm;
RArchOpAsmCallback encode;
//TODO: reenable this later
// bool (*esil_init)(RAnalEsil *esil);
// void (*esil_fini)(RAnalEsil *esil);
@ -123,6 +160,7 @@ typedef struct r_arch_plugin_t {
R_API bool r_arch_load_decoder(RArch *arch, const char *dname);
R_API bool r_arch_use_decoder(RArch *arch, const char *dname);
R_API bool r_arch_unload_decoder(RArch *arch, const char *dname);
R_API int r_arch_info(RArch *arch, const char *dname, ut32 query);
R_API int r_arch_decode(RArch *arch, const char *dname, struct r_anal_op_t *op, ut64 addr, const ut8 *data, int len, ut32 mask);
R_API int r_arch_encode(RArch *a, ut64 addr, const char *s, ut8 *outbuf, int outlen);
@ -130,6 +168,9 @@ R_API bool r_arch_set_reg_profile(RArch *arch, const char *dname, struct r_reg_t
//R_API bool r_arch_esil_init(RArch *arch, const char *dname, RAnalEsil *esil);
//R_API void r_arch_esil_fini(RArch *arch, const char *dname, RAnalEsil *esil);
// instance.c
// R_API RArchInstance r_arch_use(RArch *arch, RArchConfig *config, const char *name);
// arch.c
R_API RArch *r_arch_new(void);
R_API bool r_arch_use(RArch *arch, RArchConfig *config, const char *name);
@ -146,6 +187,46 @@ R_API void r_arch_config_set_cpu(RArchConfig *config, R_NULLABLE const char *cpu
R_API void r_arch_config_set_bits(RArchConfig *config, int bits);
R_API RArchConfig *r_arch_config_new(void);
// XXX deprecate those names are uglyies and we can reuse R_PERM
typedef enum {
R_ANAL_ACC_UNKNOWN = 0,
R_ANAL_ACC_R = (1 << 0),
R_ANAL_ACC_W = (1 << 1),
} RArchValueAccess;
typedef enum {
R_ANAL_VAL_REG,
R_ANAL_VAL_MEM,
R_ANAL_VAL_IMM,
} RArchValueType;
#define RAnalValueType RArchValueType
#define USE_REG_NAMES 0
// base + reg + regdelta * mul + delta
typedef struct r_arch_value_t {
RArchValueType type;
RArchValueAccess access;
int absolute; // if true, unsigned cast is used
int memref; // is memory reference? which size? 1, 2 ,4, 8
ut64 base ; // numeric address
st64 delta; // numeric delta
st64 imm; // immediate value
int mul; // multiplier (reg*4+base)
#if USE_REG_NAMES
const char *seg;
const char *reg;
const char *regdelta;
#else
// XXX can be invalidated if regprofile changes causing an UAF
RRegItem *seg; // segment selector register
RRegItem *reg; // register item reference
RRegItem *regdelta; // register index used
#endif
} RArchValue;
// backward compat
#define RAnalValue RArchValue
R_API RArchValue *r_arch_value_new(void);
#if 0
// switchop
R_API RArchSwitchOp *r_arch_switch_op_new(ut64 addr, ut64 min_val, ut64 max_val, ut64 def_val);
@ -153,7 +234,6 @@ R_API RArchCaseOp *r_arch_case_op_new(ut64 addr, ut64 val, ut64 jump);
R_API void r_arch_switch_op_free(RArchSwitchOp *swop);
R_API RArchCaseOp* r_arch_switch_op_add_case(RArchSwitchOp *swop, ut64 addr, ut64 value, ut64 jump);
// archvalue.c
R_API RAnalValue *r_arch_value_new(void);
R_API RArchValue *r_arch_value_copy(RArchValue *ov);
R_API void r_arch_value_free(RArchValue *value);
R_API ut64 r_arch_value_to_ut64(RArchValue *val, struct r_reg_t *reg);
@ -177,6 +257,7 @@ extern RArchPlugin r_arch_plugin_null;
extern RArchPlugin r_arch_plugin_i4004;
extern RArchPlugin r_arch_plugin_amd29k;
extern RArchPlugin r_arch_plugin_jdh8;
extern RArchPlugin r_arch_plugin_sh;
#ifdef __cplusplus
}

View File

@ -234,7 +234,8 @@ typedef struct _utX {
#define R_UNWRAP2(a,b) ((a)? a->b: NULL)
#define R_UNWRAP3(a,b,c) ((a)? a->b? a->b->c: NULL: NULL)
#define R_UNWRAP4(a,b,c,d) ((a)? a->b? a->b->c? a->b->c->d: NULL: NULL: NULL)
#define R_UNWRAP5(a,b,c,d,e) ((a)? a->b? a->b->c? a->b->c->d: a->b->c->d->e: NULL: NULL: NULL: NULL)
#define R_UNWRAP5(a,b,c,d,e) ((a)? a->b? a->b->c? a->b->c->d? a->b->c->d->e: NULL: NULL: NULL: NULL)
#define R_UNWRAP6(a,b,c,d,e,f) ((a)? a->b? a->b->c? a->b->c->d? a->b->c->d->e? a->b->c->d->e: NULL, NULL: NULL: NULL: NULL)
#ifdef __GNUC__
#define R_UNUSED __attribute__((__unused__))

View File

@ -6,6 +6,8 @@ esil_plugins = [ 'dummy' ]
asm_plugins = [ 'null' ]
anal_plugins = [ 'null' ]
arch_plugins = [ 'null',
'sh',
'jdh8',
'i4004',
'amd29k',
]
@ -171,7 +173,6 @@ anal_plugins += [
'riscv',
'riscv_cs',
'rsp',
'sh',
'snes',
'sparc_cs',
's390_cs',

View File

@ -37,6 +37,8 @@ echo "WASI_SDK=$WASI_SDK"
# export CC="${WASI_SDK}/bin/clang -D
ERR=0
# XXX gperf-builds are broken
# ./configure --with-static-themes --with-compiler=wasi --disable-debugger --without-fork --with-ostype=wasi --with-checks-level=0 --disable-threads --without-dylink --with-libr --without-gpl
./configure --with-static-themes --without-gperf --with-compiler=wasi --disable-debugger --without-fork --with-ostype=wasi --with-checks-level=0 --disable-threads --without-dylink --with-libr --without-gpl
make -j
R2V=`./configure -qV`