From ab221f832691729a2f9bf0490b8a873379754b86 Mon Sep 17 00:00:00 2001 From: Giovanni Date: Thu, 20 Jul 2017 08:20:19 +0200 Subject: [PATCH] Implement pseudo for sh4 --- libr/config.h.meson | 1 + libr/config.mk.meson | 2 +- libr/include/r_parse.h | 1 + libr/meson.build | 1 + libr/parse/meson.build | 1 + libr/parse/p/Makefile | 2 +- libr/parse/p/parse_sh_pseudo.c | 274 +++++++++++++++++++++++++++++++++ libr/parse/p/sh_pseudo.mk | 14 ++ plugins.def.cfg | 1 + plugins.meson.cfg | 1 + 10 files changed, 296 insertions(+), 2 deletions(-) create mode 100644 libr/parse/p/parse_sh_pseudo.c create mode 100644 libr/parse/p/sh_pseudo.mk diff --git a/libr/config.h.meson b/libr/config.h.meson index 1a5c8f18e2..065f95e7f4 100644 --- a/libr/config.h.meson +++ b/libr/config.h.meson @@ -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 diff --git a/libr/config.mk.meson b/libr/config.mk.meson index 4bc1a42ce5..3606023675 100644 --- a/libr/config.mk.meson +++ b/libr/config.mk.meson @@ -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)))) diff --git a/libr/include/r_parse.h b/libr/include/r_parse.h index 10a7d01f89..6e6c616353 100644 --- a/libr/include/r_parse.h +++ b/libr/include/r_parse.h @@ -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 diff --git a/libr/meson.build b/libr/meson.build index 1915deb7d8..46bdd96a65 100644 --- a/libr/meson.build +++ b/libr/meson.build @@ -227,5 +227,6 @@ parse = [ 'mips_pseudo', 'mreplace', 'ppc_pseudo', + 'sh_pseudo', 'x86_pseudo', ] diff --git a/libr/parse/meson.build b/libr/parse/meson.build index 0360f2747f..80779fb13c 100644 --- a/libr/parse/meson.build +++ b/libr/parse/meson.build @@ -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' ] diff --git a/libr/parse/p/Makefile b/libr/parse/p/Makefile index ba5f32eaba..5ab0cf6a79 100644 --- a/libr/parse/p/Makefile +++ b/libr/parse/p/Makefile @@ -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) diff --git a/libr/parse/p/parse_sh_pseudo.c b/libr/parse/p/parse_sh_pseudo.c new file mode 100644 index 0000000000..8aa465b748 --- /dev/null +++ b/libr/parse/p/parse_sh_pseudo.c @@ -0,0 +1,274 @@ +/* radare - LGPL - Copyright 2017 - wargio */ + +#include +#include +#include + +#include +#include +#include +#include +#include + +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 diff --git a/libr/parse/p/sh_pseudo.mk b/libr/parse/p/sh_pseudo.mk new file mode 100644 index 0000000000..b664b606f8 --- /dev/null +++ b/libr/parse/p/sh_pseudo.mk @@ -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 diff --git a/plugins.def.cfg b/plugins.def.cfg index bf8771588f..a0d590c87f 100644 --- a/plugins.def.cfg +++ b/plugins.def.cfg @@ -231,5 +231,6 @@ parse.dalvik_pseudo parse.mips_pseudo parse.mreplace parse.ppc_pseudo +parse.sh_pseudo parse.x86_pseudo" SHARED="io.shm" diff --git a/plugins.meson.cfg b/plugins.meson.cfg index a31f376923..9833f462e1 100644 --- a/plugins.meson.cfg +++ b/plugins.meson.cfg @@ -187,5 +187,6 @@ parse.dalvik_pseudo parse.mips_pseudo parse.mreplace parse.ppc_pseudo +parse.sh_pseudo parse.x86_pseudo" SHARED="io.shm"