radare2/libr/anal/p/anal_sysz.c

129 lines
2.9 KiB
C

/* radare2 - LGPL - Copyright 2014 - pancake */
#include <r_anal.h>
#include <r_lib.h>
#include <capstone.h>
#include <systemz.h>
// instruction set: http://www.tachyonsoft.com/inst390m.htm
#if CS_API_MAJOR < 2
#error Old Capstone not supported
#endif
#if CS_API_MINOR < 1
#error Old Capstone not supported
#endif
#define esilprintf(op, fmt, arg...) r_strbuf_setf (&op->esil, fmt, ##arg)
#define INSOP(n) insn->detail->sysz.operands[n]
static int analop(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len) {
csh handle;
cs_insn *insn;
int mode, n, ret;
mode = CS_MODE_BIG_ENDIAN;
ret = cs_open (CS_ARCH_SYSZ, mode, &handle);
op->type = R_ANAL_OP_TYPE_NULL;
op->size = 0;
op->delay = 0;
r_strbuf_init (&op->esil);
if (ret == CS_ERR_OK) {
cs_option (handle, CS_OPT_DETAIL, CS_OPT_ON);
// capstone-next
n = cs_disasm_ex (handle, (const ut8*)buf, len, addr, 1, &insn);
if (n<1) {
op->type = R_ANAL_OP_TYPE_ILL;
} else {
op->size = insn->size;
switch (insn->id) {
case SYSZ_INS_BRCL:
case SYSZ_INS_BRASL:
op->type = R_ANAL_OP_TYPE_CALL;
break;
case SYSZ_INS_BR:
op->type = R_ANAL_OP_TYPE_JMP;
break;
case SYSZ_INS_BRC:
case SYSZ_INS_BER:
case SYSZ_INS_BHR:
case SYSZ_INS_BHER:
case SYSZ_INS_BLR:
case SYSZ_INS_BLER:
case SYSZ_INS_BLHR:
case SYSZ_INS_BNER:
case SYSZ_INS_BNHR:
case SYSZ_INS_BNHER:
case SYSZ_INS_BNLR:
case SYSZ_INS_BNLER:
case SYSZ_INS_BNLHR:
case SYSZ_INS_BNOR:
case SYSZ_INS_BOR:
case SYSZ_INS_BASR:
case SYSZ_INS_BRAS:
case SYSZ_INS_BRCT:
case SYSZ_INS_BRCTG:
op->type = R_ANAL_OP_TYPE_CJMP;
break;
case SYSZ_INS_JE:
case SYSZ_INS_JGE:
case SYSZ_INS_JHE:
case SYSZ_INS_JGHE:
case SYSZ_INS_JH:
case SYSZ_INS_JGH:
case SYSZ_INS_JLE:
case SYSZ_INS_JGLE:
case SYSZ_INS_JLH:
case SYSZ_INS_JGLH:
case SYSZ_INS_JL:
case SYSZ_INS_JGL:
case SYSZ_INS_JNE:
case SYSZ_INS_JGNE:
case SYSZ_INS_JNHE:
case SYSZ_INS_JGNHE:
case SYSZ_INS_JNH:
case SYSZ_INS_JGNH:
case SYSZ_INS_JNLE:
case SYSZ_INS_JGNLE:
case SYSZ_INS_JNLH:
case SYSZ_INS_JGNLH:
case SYSZ_INS_JNL:
case SYSZ_INS_JGNL:
case SYSZ_INS_JNO:
case SYSZ_INS_JGNO:
case SYSZ_INS_JO:
case SYSZ_INS_JGO:
case SYSZ_INS_JG:
op->type = R_ANAL_OP_TYPE_CJMP;
op->jump = INSOP(0).imm;
op->fail = addr+op->size;
break;
case SYSZ_INS_J:
op->type = R_ANAL_OP_TYPE_JMP;
op->jump = INSOP(0).imm;
op->fail = UT64_MAX;
break;
}
}
cs_free (insn, n);
cs_close (&handle);
}
return op->size;
}
RAnalPlugin r_anal_plugin_sysz = {
.name = "systemz.cs",
.desc = "Capstone SystemZ microanalysis",
.license = "BSD",
.arch = R_SYS_ARCH_SYSZ,
.bits = 32|64,
.op = &analop,
//.set_reg_profile = &set_reg_profile,
};
#ifndef CORELIB
struct r_lib_struct_t radare_plugin = {
.type = R_LIB_TYPE_ANAL,
.data = &r_anal_plugin_sysz
};
#endif