Implement pseudo for sh4

This commit is contained in:
Giovanni 2017-07-20 08:20:19 +02:00 committed by radare
parent 5996387f8e
commit ab221f8326
10 changed files with 296 additions and 2 deletions

View File

@ -233,6 +233,7 @@
&r_parse_plugin_mips_pseudo, \
&r_parse_plugin_mreplace, \
&r_parse_plugin_ppc_pseudo, \
&r_parse_plugin_sh_pseudo, \
&r_parse_plugin_x86_pseudo, \
0

View File

@ -21,7 +21,7 @@ STATIC_EGG_PLUGINS= p/exec.mk p/xor.mk
STATIC_FS_PLUGINS= p/ext2.mk p/fat.mk p/fb.mk p/hfs.mk p/hfsplus.mk p/iso9660.mk p/jfs.mk p/minix.mk p/ntfs.mk p/posix.mk p/reiserfs.mk p/sfs.mk p/tar.mk p/udf.mk p/ufs.mk p/xfs.mk
STATIC_IO_PLUGINS= p/bfdbg.mk p/debug.mk p/default.mk p/gzip.mk p/http.mk p/ihex.mk p/mach.mk p/malloc.mk p/mmap.mk p/null.mk p/procpid.mk p/ptrace.mk p/r2k.mk p/r2pipe.mk p/r2web.mk p/rap.mk p/self.mk p/shm.mk p/sparse.mk p/tcp.mk
STATIC_LANG_PLUGINS= p/vala.mk
STATIC_PARSE_PLUGINS= p/6502_pseudo.mk p/arm_pseudo.mk p/att2intel.mk p/dalvik_pseudo.mk p/m68k_pseudo.mk p/mips_pseudo.mk p/mreplace.mk p/ppc_pseudo.mk p/x86_pseudo.mk
STATIC_PARSE_PLUGINS= p/6502_pseudo.mk p/arm_pseudo.mk p/att2intel.mk p/dalvik_pseudo.mk p/m68k_pseudo.mk p/mips_pseudo.mk p/mreplace.mk p/ppc_pseudo.mk p/x86_pseudo.mk p/sh_pseudo.mk
# config.mk.tail
LIBR:=$(abspath $(dir $(lastword $(MAKEFILE_LIST))))

View File

@ -70,6 +70,7 @@ extern struct r_parse_plugin_t r_parse_plugin_mips_pseudo;
extern struct r_parse_plugin_t r_parse_plugin_dalvik_pseudo;
extern struct r_parse_plugin_t r_parse_plugin_mreplace;
extern struct r_parse_plugin_t r_parse_plugin_ppc_pseudo;
extern struct r_parse_plugin_t r_parse_plugin_sh_pseudo;
extern struct r_parse_plugin_t r_parse_plugin_6502_pseudo;
extern struct r_parse_plugin_t r_parse_plugin_m68k_pseudo;
#endif

View File

@ -227,5 +227,6 @@ parse = [
'mips_pseudo',
'mreplace',
'ppc_pseudo',
'sh_pseudo',
'x86_pseudo',
]

View File

@ -11,6 +11,7 @@ files=[
'p/parse_ppc_pseudo.c',
'p/parse_x86_pseudo.c',
'p/parse_z80_pseudo.c',
'p/parse_sh_pseudo.c',
'p/parse_mreplace/mreplace.c',
'p/parse_mreplace/mmemory.c'
]

View File

@ -12,7 +12,7 @@ foo: all
ALL_TARGETS=
ARCHS=att2intel.mk x86_pseudo.mk mreplace.mk
ARCHS+=arm_pseudo.mk z80_pseudo.mk ppc_pseudo.mk 6502_pseudo.mk
ARCHS+=m68k_pseudo.mk
ARCHS+=m68k_pseudo.mk sh_pseudo.mk
include $(ARCHS)

View File

@ -0,0 +1,274 @@
/* radare - LGPL - Copyright 2017 - wargio */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <r_lib.h>
#include <r_util.h>
#include <r_flag.h>
#include <r_anal.h>
#include <r_parse.h>
static int replace(int argc, const char *argv[], char *newstr) {
int i,j,k;
struct {
char *op;
char *str;
} ops[] = {
{ "add", "B += A"},
{ "addc", "B += A + t"},
{ "addv", "B += A; t = int_overflow (B)"},
{ "and", "B &= A"},
{ "and.b", "B &= A"},
{ "bf", "if(!t) goto A"},
{ "bf.s", "if(!t) goto A"},
{ "bra", "goto A"},
{ "brk", "_break_exception ()"},
{ "bsr", "call A"},
{ "bsrf", "call A"},
{ "bt", "if(t) goto A"},
{ "bt.s", "if(t) goto A"},
{ "clrmac", "_clrmac ()"},
{ "clrs", "_clrs ()"},
{ "clrt", "_clrt ()"},
{ "cmp/eq", "t = A == B ? 1 : 0"},
{ "cmp/ge", "t = A >= B ? 1 : 0"},
{ "cmp/gt", "t = A > B ? 1 : 0"},
{ "cmp/hi", "t = (unsigned) A > (unsigned) B ? 1 : 0"},
{ "cmp/hs", "t = (unsigned) A >= (unsigned) B ? 1 : 0"},
{ "cmp/pl", "t = A > 0 ? 1 : 0"},
{ "cmp/pz", "t = A >= 0 ? 1 : 0"},
{ "cmp/str", "t = A ^ B ? 1 : 0"},
{ "div1", "B /= A"},
{ "dmuls.l", "mac = B * A"},
{ "dmulu.l", "mac = (unsigned) B * (unsigned) A"},
{ "dt", "A--; t = !A ? 1 : 0"},
{ "exts.w", "B = (int) A"},
{ "extu.w", "B = (unsigned int) A"},
{ "fabs", "A = abs (A)"},
{ "fadd", "B += A"},
{ "fcmp/eq", "t = A == B ? 1 : 0"},
{ "fcmp/gt", "t = A > B ? 1 : 0"},
{ "fcnvds", "B = A"},
{ "fdiv", "B /= A"},
{ "flds", "B = A"},
{ "fldi0", "A = 0.0f"},
{ "fldi1", "A = 1.0f"},
{ "float", "B = A"},
{ "fmac", "C += A * B"},
{ "fmov", "B = A"},
{ "fmov.s", "B = A"},
{ "fmul", "B *= A"},
{ "fneg", "A = -A"},
{ "fsqrt", "A = sqrt (A)"},
{ "fsts", "B = A"},
{ "fsub", "B -= A"},
{ "ftrc", "B = A"},
{ "ftrv", "B *= A"},
{ "jmp", "goto A"},
{ "jsr", "goto A"},
{ "ldr", "B = A"},
{ "ldr.l", "B = A"},
{ "lds", "B = A"},
{ "lds.l", "B = A"},
{ "mov", "B = A"},
{ "mov.b", "B = A"},
{ "mov.l", "B = A"},
{ "mov.w", "B = A"},
{ "movca.l", "B = A"},
{ "movt", "A = t"},
{ "muls.w", "macl = A * B"},
{ "mulu.w", "macl = (unsigned) A * (unsigned) B"},
{ "neg", "A = -A"},
{ "negc", "A = (-A) - t"},
{ "nop", ""},
{ "not", "A = !A"},
{ "or", "B |= A"},
{ "rotcl", "t = A & 0x80000000 ? 0 : 1; A = (A << 1) | t"},
{ "rotl", "A = (A << 1) | (A >> 31)"},
{ "rotr", "A = (A << 31) | (A >> 1)"},
{ "rte", "_rte ()"},
{ "rts", "return"},
{ "sets", "s = 1"},
{ "sett", "t = 1"},
{ "shad", "B = A >= 0 ? B << A : B >> (31 - A)"},
{ "shal", "A <<= 1"},
{ "shar", "A >>= 1"},
{ "shld", "B = A >= 0 ? B << A : B >> (31 - A)"},
{ "shll", "A <<= 1"},
{ "shll2", "A <<= 2"},
{ "shll8", "A <<= 8"},
{ "shll16", "A <<= 16"},
{ "shlr", "A >>= 1"},
{ "shlr2", "A >>= 2"},
{ "shlr8", "A >>= 8"},
{ "shlr16", "A >>= 16"},
{ "sleep", "_halt ()"},
{ "stc", "B = A"},
{ "stc.l", "B = A"},
{ "sts", "B = A"},
{ "sts.l", "B = A"},
{ "sub", "B -= A"},
{ "subc", "B -= A - t"},
{ "subv", "B -= A; t = int_underflow (B)"},
{ "swap.b", "swap_byte (B, A)"},
{ "swap.w", "swap_word (B, A)"},
{ "tas.b", "test_and_set (A)"},
{ "trapa", "trap (A)"},
{ "tst", "t = B & A ? 1 : 0"},
{ "xor", "B ^= A"},
{ "xor.b", "B ^= A"},
{ NULL }
};
for (i = 0; ops[i].op != NULL; i++) {
if (!strcmp (ops[i].op, argv[0])) {
if (newstr != NULL) {
for (j = k = 0; ops[i].str[j] != '\0'; j++, k++) {
if (ops[i].str[j] >= 'A' && ops[i].str[j] <= 'J') {
const char *w = argv[ops[i].str[j] - '@'];
if (w != NULL) {
strcpy (newstr + k, w);
k += strlen(w) - 1;
}
} else newstr[k] = ops[i].str[j];
}
newstr[k] = '\0';
}
return true;
}
}
/* TODO: this is slow */
if (newstr != NULL) {
newstr[0] = '\0';
for (i = 0; i < argc; i++) {
strcat (newstr, argv[i]);
strcat (newstr, (i == 0 || i == argc - 1) ? " ":", ");
}
}
return false;
}
#define WSZ 128
static int parse(RParse *p, const char *data, char *str) {
int i, len = strlen (data);
char w0[WSZ];
char w1[WSZ];
char w2[WSZ];
char w3[WSZ];
char w4[WSZ];
char *buf, *ptr, *optr, *par;
// malloc can be slow here :?
if (!(buf = malloc (len + 1)))
return false;
memcpy (buf, data, len + 1);
r_str_chop (buf);
if (*buf) {
w0[0] = '\0';
w1[0] = '\0';
w2[0] = '\0';
w3[0] = '\0';
w4[0] = '\0';
ptr = strchr (buf, ' ');
if (!ptr) {
ptr = strchr (buf, '\t');
}
if (ptr) {
*ptr = '\0';
for (++ptr; *ptr == ' '; ptr++) {
//nothing to see here
}
strncpy (w0, buf, WSZ - 1);
strncpy (w1, ptr, WSZ - 1);
optr = ptr;
par = strchr (ptr, '(');
if (par && strchr (ptr, ',') > par) {
ptr = strchr (ptr, ')');
if (ptr) {
ptr = strchr (ptr, ',');
}
} else {
ptr = strchr (ptr, ',');
}
if (ptr) {
*ptr = '\0';
for (++ptr; *ptr == ' '; ptr++) {
//nothing to see here
}
strncpy (w1, optr, WSZ - 1);
strncpy (w2, ptr, WSZ - 1);
optr = ptr;
par = strchr (ptr, '(');
if (par && strchr (ptr, ',') > par) {
ptr = strchr (ptr, ')');
if (ptr) {
ptr = strchr (ptr, ',');
}
} else {
ptr = strchr (ptr, ',');
}
if (ptr) {
*ptr = '\0';
for (++ptr; *ptr == ' '; ptr++) {
//nothing to see here
}
strncpy (w2, optr, WSZ - 1);
strncpy (w3, ptr, WSZ - 1);
optr = ptr;
// bonus
par = strchr (ptr, '(');
if (par && strchr (ptr, ',') > par) {
ptr = strchr (ptr, ')');
if (ptr) {
ptr = strchr (ptr, ',');
}
} else {
ptr = strchr (ptr, ',');
}
if (ptr) {
*ptr = '\0';
for (++ptr; *ptr == ' '; ptr++) {
//nothing to see here
}
strncpy (w3, optr, WSZ - 1);
strncpy (w4, ptr, WSZ - 1);
}
}
}
} else {
strncpy (w0, buf, WSZ - 1);
}
{
const char *wa[] = { w0, w1, w2, w3, w4 };
int nw = 0;
for (i = 0; i < 5; i++) {
if (wa[i][0] != '\0') {
nw++;
}
}
replace (nw, wa, str);
}
}
free (buf);
return true;
}
RParsePlugin r_parse_plugin_sh_pseudo = {
.name = "sh.pseudo",
.desc = "SH-4 pseudo syntax",
.parse = parse
};
#ifndef CORELIB
RLibStruct radare_plugin = {
.type = R_LIB_TYPE_PARSE,
.data = &r_parse_plugin_sh_pseudo,
.version = R2_VERSION
};
#endif

14
libr/parse/p/sh_pseudo.mk Normal file
View File

@ -0,0 +1,14 @@
OBJ_SHPSEUDO+=parse_sh_pseudo.o
TARGET_SHPSEUDO=parse_sh_pseudo.${EXT_SO}
ALL_TARGETS+=${TARGET_SHPSEUDO}
STATIC_OBJ+=${OBJ_SHPSEUDO}
${TARGET_SHPSEUDO}: ${OBJ_SHPSEUDO}
ifeq ($(CC),cccl)
${CC} $(call libname,parse_sh_pseudo) -L../../util -llibr_util \
$(LDFLAGS_SHARED) ${CFLAGS} -o ${TARGET_SHPSEUDO} ${OBJ_SHPSEUDO}
else
${CC} $(call libname,parse_sh_pseudo) -L../../util -lr_util \
$(LDFLAGS_SHARED) ${CFLAGS} -o ${TARGET_SHPSEUDO} ${OBJ_SHPSEUDO}
endif

View File

@ -231,5 +231,6 @@ parse.dalvik_pseudo
parse.mips_pseudo
parse.mreplace
parse.ppc_pseudo
parse.sh_pseudo
parse.x86_pseudo"
SHARED="io.shm"

View File

@ -187,5 +187,6 @@ parse.dalvik_pseudo
parse.mips_pseudo
parse.mreplace
parse.ppc_pseudo
parse.sh_pseudo
parse.x86_pseudo"
SHARED="io.shm"