Add support for or1k (OpenRISC) disasm+analysis (#15515) ##arch

This commit is contained in:
Kamil Lorenc 2019-11-29 11:35:16 +01:00 committed by radare
parent 2fcff51dbc
commit e13281829c
12 changed files with 963 additions and 1 deletions

View File

@ -66,6 +66,7 @@ r_anal_sources = [
'p/anal_msp430.c',
'p/anal_nios2.c',
'p/anal_null.c',
'p/anal_or1k.c',
'p/anal_pic.c',
'p/anal_ppc_cs.c',
'p/anal_ppc_gnu.c',
@ -101,6 +102,7 @@ r_anal_sources = [
'../asm/arch/hexagon/hexagon_disas.c',
'../asm/arch/mcore/mcore.c',
'../asm/arch/msp430/msp430_disas.c',
'../asm/arch/or1k/or1k_disas.c',
'../asm/arch/pic/pic_midrange.c',
'../asm/arch/ppc/libvle/vle.c',
'../asm/arch/propeller/propeller_disas.c',

209
libr/anal/p/anal_or1k.c Normal file
View File

@ -0,0 +1,209 @@
/* radare2 - LGPL - Copyright 2019 - v3l0c1r4pt0r */
#include <r_asm.h>
#include <r_anal.h>
#include <r_lib.h>
#include <or1k_disas.h>
struct operands {
ut32 rd;
ut32 ra;
ut32 rb;
ut32 n;
ut32 k1;
ut32 k2;
ut32 k;
ut32 i;
ut32 l;
};
static ut32 cpu[32] = {0}; /* register contents */
static ut32 cpu_enable; /* allows to treat only registers with known value as
valid */
/**
* \brief Convert raw N operand to complete address
*
* \param n immediate, as appearing in instruction
* \param mask n operand mask
* \param addr address of current instruction
*
* \return 64-bit address
*/
static ut64 n_oper_to_addr(ut32 n, ut32 mask, ut64 addr) {
/* sign extension returns 32b unsigned N, then it is multiplied by 4, made
* signed to support negative offsets, added to address and made unsigned
* again */
return (ut64) ((st64) ((st32) (sign_extend(n, mask) << 2)) + addr);
}
static int insn_to_op(RAnal *a, RAnalOp *op, ut64 addr, insn_t *descr, insn_extra_t *extra, ut32 insn) {
struct operands o = {0};
insn_type_t type = type_of_opcode(descr, extra);
insn_type_descr_t *type_descr = &types[INSN_X];
/* only use type descriptor if it has some useful data */
if (has_type_descriptor(type) && is_type_descriptor_defined(type)) {
type_descr = &types[type];
}
if (extra == NULL) {
op->type = descr->insn_type;
} else {
op->type = extra->insn_type;
}
switch ((insn & INSN_OPCODE_MASK) >> INSN_OPCODE_SHIFT) {
case 0x00: /* l.j */
o.n = get_operand_value(insn, type_descr, INSN_OPER_N);
op->eob = true;
op->jump = n_oper_to_addr(o.n, get_operand_mask(type_descr, INSN_OPER_N),
addr);
op->delay = 1;
break;
case 0x01: /* l.jal */
o.n = get_operand_value(insn, type_descr, INSN_OPER_N);
op->eob = true;
op->jump = n_oper_to_addr(o.n, get_operand_mask(type_descr, INSN_OPER_N),
addr);
op->delay = 1;
break;
case 0x03: /* l.bnf */
o.n = get_operand_value(insn, type_descr, INSN_OPER_N);
op->cond = R_ANAL_COND_NE;
op->jump = n_oper_to_addr(o.n, get_operand_mask(type_descr, INSN_OPER_N),
addr);
op->fail = addr + 8;
op->delay = 1;
break;
case 0x04: /* l.bf */
o.n = get_operand_value(insn, type_descr, INSN_OPER_N);
op->cond = R_ANAL_COND_EQ;
op->jump = n_oper_to_addr(o.n, get_operand_mask(type_descr, INSN_OPER_N),
addr);
op->fail = addr + 8;
op->delay = 1;
break;
case 0x11: /* l.jr */
o.rb = get_operand_value(insn, type_descr, INSN_OPER_B);
op->eob = true;
if (cpu_enable & (1 << o.rb)) {
op->jump = cpu[o.rb];
}
op->delay = 1;
break;
case 0x12: /* l.jalr */
o.rb = get_operand_value(insn, type_descr, INSN_OPER_B);
op->eob = true;
if (cpu_enable & (1 << o.rb)) {
op->jump = cpu[o.rb];
}
op->delay = 1;
break;
case 0x06: /* extended */
switch (insn & (1 << 16)) {
case 0: /* l.movhi */
o.rd = get_operand_value(insn, type_descr, INSN_OPER_D);
o.k = get_operand_value(insn, type_descr, INSN_OPER_K);
cpu[o.rd] = o.k << 16;
cpu_enable |= (1 << o.rd);
break;
case 1: /* l.macrc */
break;
}
break;
case 0x27: /* l.addi */
o.rd = get_operand_value(insn, type_descr, INSN_OPER_D);
o.ra = get_operand_value(insn, type_descr, INSN_OPER_A);
o.i = get_operand_value(insn, type_descr, INSN_OPER_I);
if (cpu_enable & (1 << o.ra) & cpu_enable & (1 << o.rd)) {
cpu[o.rd] = cpu[o.ra] | o.i;
cpu_enable |= (1 << o.rd);
op->ptr = cpu[o.rd];
op->direction = 8; /* reference */
}
break;
case 0x2a: /* l.ori */
o.rd = get_operand_value(insn, type_descr, INSN_OPER_D);
o.ra = get_operand_value(insn, type_descr, INSN_OPER_A);
o.i = get_operand_value(insn, type_descr, INSN_OPER_I);
if (cpu_enable & (1 << o.ra)) {
cpu[o.rd] = cpu[o.ra] | o.i;
cpu_enable |= (1 << o.rd);
op->ptr = cpu[o.rd];
op->direction = 8; /* reference */
}
break;
default:
/* if unknown instruction encountered, better forget state */
cpu_enable = 0;
}
/* temporary solution to prevent using wrong register values */
if ((op->type & R_ANAL_OP_TYPE_JMP) == R_ANAL_OP_TYPE_JMP) {
/* FIXME: handle delay slot after branches */
cpu_enable = 0;
}
return 4;
}
static int or1k_op(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *data, int len, RAnalOpMask mask) {
ut32 insn, opcode;
ut8 opcode_idx;
char *line = NULL;
insn_t *insn_descr;
insn_extra_t *extra_descr;
op->size = -1;
r_strbuf_init (&op->esil);
/* read instruction and basic opcode value */
insn = r_read_be32(data);
op->size = 4;
opcode = (insn & INSN_OPCODE_MASK);
opcode_idx = opcode >> INSN_OPCODE_SHIFT;
/* make sure instruction descriptor table is not overflowed */
if (opcode_idx >= insns_count) {
return op->size;
}
/* if instruction is marked as invalid finish processing now */
insn_descr = &insns[opcode_idx];
if (insn_descr->type == INSN_INVAL) {
return op->size;
}
/* if name is null, but extra is present, it means 6 most significant bits
* are not enough to decode instruction */
if ((insn_descr->name == NULL) && (insn_descr->extra != NULL)) {
extra_descr = find_extra_descriptor(insn_descr->extra, insn);
if (extra_descr != NULL) {
insn_to_op(a, op, addr, insn_descr, extra_descr, insn);
}
}
else {
/* otherwise basic descriptor is enough */
insn_to_op(a, op, addr, insn_descr, NULL, insn);
}
return op->size;
}
RAnalPlugin r_anal_plugin_or1k = {
.name = "or1k",
.desc = "OpenRISC 1000",
.license = "LGPL3",
.bits = 32,
.arch = "or1k",
.esil = false,
.op = &or1k_op,
};
#ifndef R2_PLUGIN_INCORE
R_API RLibStruct radare_plugin = {
.type = R_LIB_TYPE_ANAL,
.data = &r_anal_plugin_or1k,
.version = R2_VERSION
};
#endif

12
libr/anal/p/or1k.mk Normal file
View File

@ -0,0 +1,12 @@
OBJ_OR1K=anal_or1k.o
OBJ_OR1K+=../../asm/arch/or1k/or1k_disas.o
CFLAGS+=-I../asm/arch/or1k
STATIC_OBJ+=${OBJ_OR1K}
TARGET_OR1K=anal_or1k.${EXT_SO}
ALL_TARGETS+=${TARGET_OR1K}
${TARGET_OR1K}: ${OBJ_OR1K}
${CC} $(call libname,anal_nios2) ${LDFLAGS} ${CFLAGS} \
-o anal_or1k.${EXT_SO} ${OBJ_OR1K}

View File

@ -0,0 +1,361 @@
/* radare2 - LGPL - Copyright 2019 - v3l0c1r4pt0r */
#include <r_anal.h>
#include "or1k_disas.h"
insn_type_descr_t types[] = {
[INSN_X] = {INSN_X, "%s",
{
0
}
},
/* ------KKKKKAAAAABBBBBKKKKKKKKKKK */
[INSN_KABK] = {INSN_KABK, "%s r%d, r%d, 0x%x",
{
[INSN_OPER_K1] = {INSN_OPER_K1, INSN_K1_MASK, INSN_K1_SHIFT},
[INSN_OPER_A] = {INSN_OPER_A, INSN_A_MASK, INSN_A_SHIFT},
[INSN_OPER_B] = {INSN_OPER_B, INSN_B_MASK, INSN_B_SHIFT},
[INSN_OPER_K2] = {INSN_OPER_K2, INSN_K2_MASK, INSN_EMPTY_SHIFT}
}
},
/* ------IIIIIAAAAABBBBBIIIIIIIIIII */
[INSN_IABI] = {INSN_IABI, "%s r%d, r%d, 0x%x",
{
[INSN_OPER_K1] = {INSN_OPER_K1, INSN_K1_MASK, INSN_K1_SHIFT},
[INSN_OPER_A] = {INSN_OPER_A, INSN_A_MASK, INSN_A_SHIFT},
[INSN_OPER_B] = {INSN_OPER_B, INSN_B_MASK, INSN_B_SHIFT},
[INSN_OPER_K2] = {INSN_OPER_K2, INSN_K2_MASK, INSN_EMPTY_SHIFT}
}
},
/* ------NNNNNNNNNNNNNNNNNNNNNNNNNN */
[INSN_N] = {INSN_N, "%s 0x%x",
{
[INSN_OPER_N] = {INSN_OPER_N, INSN_N_MASK, INSN_EMPTY_SHIFT}
}
},
/* ----------------KKKKKKKKKKKKKKKK */
[INSN_K] = {INSN_K, "%s 0x%x",
{
[INSN_OPER_K] = {INSN_OPER_K, INSN_K_MASK, INSN_EMPTY_SHIFT}
}
},
/* ------DDDDD-----KKKKKKKKKKKKKKKK */
[INSN_DK] = {INSN_DK, "%s r%d, 0x%x",
{
[INSN_OPER_K] = {INSN_OPER_K, INSN_K_MASK, INSN_EMPTY_SHIFT},
[INSN_OPER_D] = {INSN_OPER_D, INSN_D_MASK, INSN_D_SHIFT}
}
},
/* ------DDDDDNNNNNNNNNNNNNNNNNNNNN */
[INSN_DN] = {INSN_DN, "%s r%d, 0x%x",
{
[INSN_OPER_N] = {INSN_OPER_N, INSN_N_MASK, INSN_EMPTY_SHIFT},
[INSN_OPER_D] = {INSN_OPER_D, INSN_D_MASK, INSN_D_SHIFT}
}
},
/* ----------------BBBBB----------- */
[INSN_B] = {INSN_B, "%s r%d",
{
[INSN_OPER_B] = {INSN_OPER_B, INSN_B_MASK, INSN_B_SHIFT}
}
},
/* ------DDDDD--------------------- */
[INSN_D] = {INSN_D, "%s r%d",
{
[INSN_OPER_D] = {INSN_OPER_D, INSN_D_MASK, INSN_D_SHIFT}
}
},
/* -----------AAAAAIIIIIIIIIIIIIIII */
[INSN_AI] = {INSN_AI, "%s r%d, 0x%x",
{
[INSN_OPER_I] = {INSN_OPER_I, INSN_I_MASK, INSN_EMPTY_SHIFT},
[INSN_OPER_A] = {INSN_OPER_A, INSN_A_MASK, INSN_A_SHIFT}
}
},
/* ------DDDDDAAAAAIIIIIIIIIIIIIIII */
[INSN_DAI] = {INSN_DAI, "%s r%d, r%d, 0x%x",
{
[INSN_OPER_D] = {INSN_OPER_D, INSN_D_MASK, INSN_D_SHIFT},
[INSN_OPER_A] = {INSN_OPER_A, INSN_A_MASK, INSN_A_SHIFT},
[INSN_OPER_I] = {INSN_OPER_I, INSN_I_MASK, INSN_EMPTY_SHIFT}
}
},
/* ------DDDDDAAAAAKKKKKKKKKKKKKKKK */
[INSN_DAK] = {INSN_DAK, "%s r%d, r%d, 0x%x",
{
[INSN_OPER_D] = {INSN_OPER_D, INSN_D_MASK, INSN_D_SHIFT},
[INSN_OPER_A] = {INSN_OPER_A, INSN_A_MASK, INSN_A_SHIFT},
[INSN_OPER_I] = {INSN_OPER_I, INSN_I_MASK, INSN_EMPTY_SHIFT}
}
},
/* ------DDDDDAAAAA----------LLLLLL */
[INSN_DAL] = {INSN_DAL, "%s r%d, r%d, 0x%x",
{
[INSN_OPER_D] = {INSN_OPER_D, INSN_D_MASK, INSN_D_SHIFT},
[INSN_OPER_A] = {INSN_OPER_A, INSN_A_MASK, INSN_A_SHIFT},
[INSN_OPER_L] = {INSN_OPER_L, INSN_L_MASK, INSN_EMPTY_SHIFT}
}
},
/* ------DDDDDAAAAA---------------- */
[INSN_DA] = {INSN_DA, "%s r%d, r%d",
{
[INSN_OPER_D] = {INSN_OPER_D, INSN_D_MASK, INSN_D_SHIFT},
[INSN_OPER_A] = {INSN_OPER_A, INSN_A_MASK, INSN_A_SHIFT}
}
},
/* ------DDDDDAAAAABBBBB----------- */
[INSN_DAB] = {INSN_DAB, "%s r%d, r%d, r%d",
{
[INSN_OPER_D] = {INSN_OPER_D, INSN_D_MASK, INSN_D_SHIFT},
[INSN_OPER_A] = {INSN_OPER_A, INSN_A_MASK, INSN_A_SHIFT},
[INSN_OPER_B] = {INSN_OPER_B, INSN_B_MASK, INSN_B_SHIFT}
}
},
/* -----------AAAAABBBBB----------- */
[INSN_AB] = {INSN_AB, "%s r%d, r%d",
{
[INSN_OPER_A] = {INSN_OPER_A, INSN_A_MASK, INSN_A_SHIFT},
[INSN_OPER_B] = {INSN_OPER_B, INSN_B_MASK, INSN_B_SHIFT}
}
},
};
size_t types_count = sizeof(types) / sizeof(insn_type_descr_t);
insn_extra_t extra_0x5[] = {
{(0x05<<26)|(0b01<<24), "l.nop", INSN_K, INSN_OPCODE_MASK | (0b11 << 24), R_ANAL_OP_TYPE_NOP},
{0}
};
insn_extra_t extra_0x6[] = {
{(0x06<<26)|(0<<16), "l.movhi", INSN_DK, INSN_OPCODE_MASK | (1 << 16)},
{(0x06<<26)|(1<<16), "l.macrc", INSN_D, INSN_OPCODE_MASK | (1 << 16)},
{0}
};
insn_extra_t extra_0x8[] = {
{(0x08<<26)|(0b0000000000), "l.sys", INSN_K, INSN_OPCODE_MASK | 0b1111111111 << 16},
{(0x08<<26)|(0b0100000000), "l.trap", INSN_K, INSN_OPCODE_MASK | 0b1111111111 << 16},
{(0x08<<26)|(0b10000000000000000000000000), "l.msync", INSN_X, INSN_OPCODE_MASK | 0x3ffffff},
{(0x08<<26)|(0b10100000000000000000000000), "l.psync", INSN_X, INSN_OPCODE_MASK | 0x3ffffff},
{(0x08<<26)|(0b11000000000000000000000000), "l.csync", INSN_X, INSN_OPCODE_MASK | 0x3ffffff},
{0}
};
insn_extra_t extra_0x2e[] = {
{(0x2e<<26)|(0b00<<6), "l.slli", INSN_DAL, INSN_OPCODE_MASK | (0b11 << 6)},
{(0x2e<<26)|(0b01<<6), "l.srli", INSN_DAL, INSN_OPCODE_MASK | (0b11 << 6)},
{(0x2e<<26)|(0b10<<6), "l.srai", INSN_DAL, INSN_OPCODE_MASK | (0b11 << 6)},
{(0x2e<<26)|(0b11<<6), "l.rori", INSN_DAL, INSN_OPCODE_MASK | (0b11 << 6)},
{0}
};
insn_extra_t extra_0x2f[] = {
{(0x2f<<26)|(0b00000<<21), "l.sfeqi", INSN_AI, INSN_OPCODE_MASK | (0b11111 << 21)},
{(0x2f<<26)|(0b00001<<21), "l.sfnei", INSN_AI, INSN_OPCODE_MASK | (0b11111 << 21)},
{(0x2f<<26)|(0b00010<<21), "l.sfgtui", INSN_AI, INSN_OPCODE_MASK | (0b11111 << 21)},
{(0x2f<<26)|(0b00011<<21), "l.sfgeui", INSN_AI, INSN_OPCODE_MASK | (0b11111 << 21)},
{(0x2f<<26)|(0b00100<<21), "l.sfltui", INSN_AI, INSN_OPCODE_MASK | (0b11111 << 21)},
{(0x2f<<26)|(0b00101<<21), "l.sfleui", INSN_AI, INSN_OPCODE_MASK | (0b11111 << 21)},
{(0x2f<<26)|(0b01010<<21), "l.sfgtsi", INSN_AI, INSN_OPCODE_MASK | (0b11111 << 21)}, /* FIXME: signed */
{(0x2f<<26)|(0b01011<<21), "l.sfgesi", INSN_AI, INSN_OPCODE_MASK | (0b11111 << 21)}, /* FIXME: signed */
{(0x2f<<26)|(0b01100<<21), "l.sfltsi", INSN_AI, INSN_OPCODE_MASK | (0b11111 << 21)}, /* FIXME: signed */
{(0x2f<<26)|(0b01101<<21), "l.sflesi", INSN_AI, INSN_OPCODE_MASK | (0b11111 << 21)}, /* FIXME: signed */
{0}
};
insn_extra_t extra_0x31[] = {
{(0x31<<26)|(0b0001), "l.mac", INSN_AB, INSN_OPCODE_MASK | (0b1111)},
{(0x31<<26)|(0b0011), "l.macu", INSN_AB, INSN_OPCODE_MASK | (0b1111)},
{(0x31<<26)|(0b0010), "l.msb", INSN_AB, INSN_OPCODE_MASK | (0b1111)},
{(0x31<<26)|(0b0100), "l.msbu", INSN_AB, INSN_OPCODE_MASK | (0b1111)},
{0}
};
insn_extra_t extra_0x32[] = {
{(0x32<<26)|(0b00001000), "lf.sfeq.s", INSN_AB, INSN_OPCODE_MASK | (0b11111111)},
{(0x32<<26)|(0b00001001), "lf.sfne.s", INSN_AB, INSN_OPCODE_MASK | (0b11111111)},
{(0x32<<26)|(0b00001010), "lf.sfgt.s", INSN_AB, INSN_OPCODE_MASK | (0b11111111)},
{(0x32<<26)|(0b00001011), "lf.sfge.s", INSN_AB, INSN_OPCODE_MASK | (0b11111111)},
{(0x32<<26)|(0b00001100), "lf.sflt.s", INSN_AB, INSN_OPCODE_MASK | (0b11111111)},
{(0x32<<26)|(0b00001101), "lf.sfle.s", INSN_AB, INSN_OPCODE_MASK | (0b11111111)},
{(0x32<<26)|(0b00011000), "lf.sfeq.d", INSN_AB, INSN_OPCODE_MASK | (0b11111111)},
{(0x32<<26)|(0b00011001), "lf.sfne.d", INSN_AB, INSN_OPCODE_MASK | (0b11111111)},
{(0x32<<26)|(0b00011010), "lf.sfgt.d", INSN_AB, INSN_OPCODE_MASK | (0b11111111)},
{(0x32<<26)|(0b00011011), "lf.sfge.d", INSN_AB, INSN_OPCODE_MASK | (0b11111111)},
{(0x32<<26)|(0b00011100), "lf.sflt.d", INSN_AB, INSN_OPCODE_MASK | (0b11111111)},
{(0x32<<26)|(0b00011101), "lf.sfle.d", INSN_AB, INSN_OPCODE_MASK | (0b11111111)},
{(0x32<<26)|(0b00101000), "lf.sfueq.s", INSN_AB, INSN_OPCODE_MASK | (0b11111111)},
{(0x32<<26)|(0b00101001), "lf.sfune.s", INSN_AB, INSN_OPCODE_MASK | (0b11111111)},
{(0x32<<26)|(0b00101010), "lf.sfugt.s", INSN_AB, INSN_OPCODE_MASK | (0b11111111)},
{(0x32<<26)|(0b00101011), "lf.sfuge.s", INSN_AB, INSN_OPCODE_MASK | (0b11111111)},
{(0x32<<26)|(0b00101100), "lf.sfult.s", INSN_AB, INSN_OPCODE_MASK | (0b11111111)},
{(0x32<<26)|(0b00101101), "lf.sfule.s", INSN_AB, INSN_OPCODE_MASK | (0b11111111)},
{(0x32<<26)|(0b00101110), "lf.sfun.s", INSN_AB, INSN_OPCODE_MASK | (0b11111111)},
{(0x32<<26)|(0b00110100), "lf.stod.d", INSN_AB, INSN_OPCODE_MASK | (0b11111111)},
{(0x32<<26)|(0b00110101), "lf.dtos.d", INSN_AB, INSN_OPCODE_MASK | (0b11111111)},
{(0x32<<26)|(0b00111000), "lf.sfueq.d", INSN_AB, INSN_OPCODE_MASK | (0b11111111)},
{(0x32<<26)|(0b00111001), "lf.sfune.d", INSN_AB, INSN_OPCODE_MASK | (0b11111111)},
{(0x32<<26)|(0b00111010), "lf.sfugt.d", INSN_AB, INSN_OPCODE_MASK | (0b11111111)},
{(0x32<<26)|(0b00111011), "lf.sfuge.d", INSN_AB, INSN_OPCODE_MASK | (0b11111111)},
{(0x32<<26)|(0b00111100), "lf.sfult.d", INSN_AB, INSN_OPCODE_MASK | (0b11111111)},
{(0x32<<26)|(0b00111101), "lf.sfule.d", INSN_AB, INSN_OPCODE_MASK | (0b11111111)},
{(0x32<<26)|(0b00111110), "lf.sfun.d", INSN_AB, INSN_OPCODE_MASK | (0b11111111)},
{(0x32<<26)|(0b1101<<4), "lf.cust1.s", INSN_AB, INSN_OPCODE_MASK | (0b1111 << 4)},
{(0x32<<26)|(0b1110<<4), "lf.cust1.d", INSN_AB, INSN_OPCODE_MASK | (0b1111 << 4)},
{(0x32<<26)|(0b00000100), "lf.itof.s", INSN_DA, INSN_OPCODE_MASK | (0b11111111)},
{(0x32<<26)|(0b00000101), "lf.ftoi.s", INSN_DA, INSN_OPCODE_MASK | (0b11111111)},
{(0x32<<26)|(0b00010100), "lf.itof.d", INSN_DA, INSN_OPCODE_MASK | (0b11111111)},
{(0x32<<26)|(0b00010101), "lf.ftoi.d", INSN_DA, INSN_OPCODE_MASK | (0b11111111)},
{(0x32<<26)|(0b00000000), "lf.add.s", INSN_DAB, INSN_OPCODE_MASK | (0b11111111)},
{(0x32<<26)|(0b00000001), "lf.sub.s", INSN_DAB, INSN_OPCODE_MASK | (0b11111111)},
{(0x32<<26)|(0b00000010), "lf.mul.s", INSN_DAB, INSN_OPCODE_MASK | (0b11111111)},
{(0x32<<26)|(0b00000011), "lf.div.s", INSN_DAB, INSN_OPCODE_MASK | (0b11111111)},
{(0x32<<26)|(0b00000111), "lf.madd.s", INSN_DAB, INSN_OPCODE_MASK | (0b11111111)},
{(0x32<<26)|(0b00010000), "lf.add.d", INSN_DAB, INSN_OPCODE_MASK | (0b11111111)},
{(0x32<<26)|(0b00010001), "lf.sub.d", INSN_DAB, INSN_OPCODE_MASK | (0b11111111)},
{(0x32<<26)|(0b00010010), "lf.mul.d", INSN_DAB, INSN_OPCODE_MASK | (0b11111111)},
{(0x32<<26)|(0b00010011), "lf.div.d", INSN_DAB, INSN_OPCODE_MASK | (0b11111111)},
{(0x32<<26)|(0b00010111), "lf.madd.d", INSN_DAB, INSN_OPCODE_MASK | (0b11111111)},
{0}
};
insn_extra_t extra_0x38[] = {
{(0x38<<26)|(0b0000<<6)|(0b1100), "l.exths", INSN_DA, INSN_OPCODE_MASK | (0xf << 6) | 0xf},
{(0x38<<26)|(0b0000<<6)|(0b1101), "l.extws", INSN_DA, INSN_OPCODE_MASK | (0xf << 6) | 0xf},
{(0x38<<26)|(0b0001<<6)|(0b1100), "l.extbs", INSN_DA, INSN_OPCODE_MASK | (0xf << 6) | 0xf},
{(0x38<<26)|(0b0001<<6)|(0b1101), "l.extwz", INSN_DA, INSN_OPCODE_MASK | (0xf << 6) | 0xf},
{(0x38<<26)|(0b0010<<6)|(0b1100), "l.exthz", INSN_DA, INSN_OPCODE_MASK | (0xf << 6) | 0xf},
{(0x38<<26)|(0b0011<<6)|(0b1100), "l.extbz", INSN_DA, INSN_OPCODE_MASK | (0xf << 6) | 0xf},
{(0x38<<26)|(0b0000<<6)|(0b0000), "l.add", INSN_DAB, INSN_OPCODE_MASK | (0xc << 6) | 0xf},
{(0x38<<26)|(0b0000<<6)|(0b0001), "l.addc", INSN_DAB, INSN_OPCODE_MASK | (0xc << 6) | 0xf},
{(0x38<<26)|(0b0000<<6)|(0b0010), "l.sub", INSN_DAB, INSN_OPCODE_MASK | (0xc << 6) | 0xf},
{(0x38<<26)|(0b0000<<6)|(0b0011), "l.and", INSN_DAB, INSN_OPCODE_MASK | (0xc << 6) | 0xf},
{(0x38<<26)|(0b0000<<6)|(0b0100), "l.or", INSN_DAB, INSN_OPCODE_MASK | (0xc << 6) | 0xf},
{(0x38<<26)|(0b0000<<6)|(0b0101), "l.xor", INSN_DAB, INSN_OPCODE_MASK | (0xc << 6) | 0xf},
{(0x38<<26)|(0b0000<<6)|(0b1110), "l.cmov", INSN_DAB, INSN_OPCODE_MASK | (0xc << 6) | 0xf},
{(0x38<<26)|(0b0000<<6)|(0b1111), "l.ff1", INSN_DA, INSN_OPCODE_MASK | (0xc << 6) | 0xf},
{(0x38<<26)|(0b0000<<6)|(0b1000), "l.sll", INSN_DAB, INSN_OPCODE_MASK | (0xf << 6) | 0xf},
{(0x38<<26)|(0b0001<<6)|(0b1000), "l.srl", INSN_DAB, INSN_OPCODE_MASK | (0xf << 6) | 0xf},
{(0x38<<26)|(0b0010<<6)|(0b1000), "l.sra", INSN_DAB, INSN_OPCODE_MASK | (0xf << 6) | 0xf},
{(0x38<<26)|(0b0011<<6)|(0b1000), "l.ror", INSN_DAB, INSN_OPCODE_MASK | (0xf << 6) | 0xf},
{(0x38<<26)|(0b01<<8)|(0b1111), "l.fl1", INSN_DA, INSN_OPCODE_MASK | (0x3 << 8) | 0xf},
{(0x38<<26)|(0b11<<8)|(0b0110), "l.mul", INSN_DAB, INSN_OPCODE_MASK | (0x3 << 8) | 0xf},
{(0x38<<26)|(0b11<<8)|(0b0111), "l.muld", INSN_AB, INSN_OPCODE_MASK | (0x3 << 8) | 0xf},
{(0x38<<26)|(0b11<<8)|(0b1001), "l.div", INSN_DAB, INSN_OPCODE_MASK | (0x3 << 8) | 0xf},
{(0x38<<26)|(0b11<<8)|(0b1010), "l.divu", INSN_DAB, INSN_OPCODE_MASK | (0x3 << 8) | 0xf},
{(0x38<<26)|(0b11<<8)|(0b1011), "l.mulu", INSN_DAB, INSN_OPCODE_MASK | (0x3 << 8) | 0xf},
{(0x38<<26)|(0b11<<8)|(0b1100), "l.muldu", INSN_AB, INSN_OPCODE_MASK | (0x3 << 8) | 0xf},
{0}
};
insn_extra_t extra_0x39[] = {
{(0x39<<26)|(0b00000<<21), "l.sfeq", INSN_AB, INSN_OPCODE_MASK | (0b11111 << 21)},
{(0x39<<26)|(0b00001<<21), "l.sfne", INSN_AB, INSN_OPCODE_MASK | (0b11111 << 21)},
{(0x39<<26)|(0b00010<<21), "l.sfgtu", INSN_AB, INSN_OPCODE_MASK | (0b11111 << 21)},
{(0x39<<26)|(0b00011<<21), "l.sfgeu", INSN_AB, INSN_OPCODE_MASK | (0b11111 << 21)},
{(0x39<<26)|(0b00100<<21), "l.sfltu", INSN_AB, INSN_OPCODE_MASK | (0b11111 << 21)},
{(0x39<<26)|(0b00101<<21), "l.sfleu", INSN_AB, INSN_OPCODE_MASK | (0b11111 << 21)},
{(0x39<<26)|(0b01010<<21), "l.sfgts", INSN_AB, INSN_OPCODE_MASK | (0b11111 << 21)},
{(0x39<<26)|(0b01011<<21), "l.sfges", INSN_AB, INSN_OPCODE_MASK | (0b11111 << 21)},
{(0x39<<26)|(0b01100<<21), "l.sflts", INSN_AB, INSN_OPCODE_MASK | (0b11111 << 21)},
{(0x39<<26)|(0b01101<<21), "l.sfles", INSN_AB, INSN_OPCODE_MASK | (0b11111 << 21)},
{0}
};
insn_t insns[] = {
[0x00] = {(0x00<<26), "l.j", INSN_N, R_ANAL_OP_TYPE_JMP},
[0x01] = {(0x01<<26), "l.jal", INSN_N, R_ANAL_OP_TYPE_CALL},
[0x02] = {(0x02<<26), "l.adrp", INSN_DN},
[0x03] = {(0x03<<26), "l.bnf", INSN_N, R_ANAL_OP_TYPE_CJMP},
[0x04] = {(0x04<<26), "l.bf", INSN_N, R_ANAL_OP_TYPE_CJMP},
[0x05] = {(0x05<<26), NULL, INSN_X, R_ANAL_OP_TYPE_NULL, extra_0x5},
[0x06] = {(0x06<<26), NULL, INSN_X, R_ANAL_OP_TYPE_NULL, extra_0x6},
[0x07] = {(0x07<<26)},
[0x08] = {(0x08<<26), NULL, INSN_X, R_ANAL_OP_TYPE_NULL, extra_0x8},
[0x09] = {(0x09<<26), "l.rfe", INSN_X},
[0x0a] = {(0x0a<<26), "lv.ext0a", INSN_X}, /* TODO: implement */
[0x0b] = {(0x0b<<26)},
[0x0c] = {(0x0c<<26)},
[0x0d] = {(0x0d<<26)},
[0x0e] = {(0x0e<<26)},
[0x0f] = {(0x0f<<26)},
[0x10] = {(0x10<<26)},
[0x11] = {(0x11<<26), "l.jr", INSN_B, R_ANAL_OP_TYPE_JMP},
[0x12] = {(0x12<<26), "l.jalr", INSN_B, R_ANAL_OP_TYPE_CALL},
[0x13] = {(0x13<<26), "l.maci", INSN_AI},
[0x14] = {(0x14<<26)},
[0x15] = {(0x15<<26)},
[0x16] = {(0x16<<26)},
[0x17] = {(0x17<<26)},
[0x18] = {(0x18<<26)},
[0x19] = {(0x19<<26)},
[0x1a] = {(0x1a<<26), "l.lf", INSN_DAI},
[0x1b] = {(0x1b<<26), "l.lwa", INSN_DAI},
[0x1c] = {(0x1c<<26), "l.cust1", INSN_X},
[0x1d] = {(0x1d<<26), "l.cust2", INSN_X},
[0x1e] = {(0x1e<<26), "l.cust3", INSN_X},
[0x1f] = {(0x1f<<26), "l.cust4", INSN_X},
[0x20] = {(0x20<<26), "l.ld", INSN_DAI},
[0x21] = {(0x21<<26), "l.lwz", INSN_DAI},
[0x22] = {(0x22<<26), "l.lws", INSN_DAI},
[0x23] = {(0x23<<26), "l.lbz", INSN_DAI},
[0x24] = {(0x24<<26), "l.lbs", INSN_DAI},
[0x25] = {(0x25<<26), "l.lhz", INSN_DAI},
[0x26] = {(0x26<<26), "l.lhs", INSN_DAI},
[0x27] = {(0x27<<26), "l.addi", INSN_DAI, R_ANAL_OP_TYPE_LOAD},
[0x28] = {(0x28<<26), "l.addic", INSN_DAI},
[0x29] = {(0x29<<26), "l.andi", INSN_DAK},
[0x2a] = {(0x2a<<26), "l.ori", INSN_DAK, R_ANAL_OP_TYPE_LOAD},
[0x2b] = {(0x2b<<26), "l.xori", INSN_DAI},
[0x2c] = {(0x2c<<26), "l.muli", INSN_DAI},
[0x2d] = {(0x2d<<26), "l.mfspr", INSN_DAK},
[0x2e] = {(0x2e<<26), NULL, INSN_X, R_ANAL_OP_TYPE_NULL, extra_0x2e},
[0x2f] = {(0x2f<<26), NULL, INSN_X, R_ANAL_OP_TYPE_NULL, extra_0x2f},
[0x30] = {(0x30<<26), "l.mtspr", INSN_KABK},
[0x31] = {(0x31<<26), NULL, INSN_X, R_ANAL_OP_TYPE_NULL, extra_0x31},
[0x32] = {(0x32<<26), NULL, INSN_X, R_ANAL_OP_TYPE_NULL, extra_0x32},
[0x33] = {(0x33<<26), "l.swa", INSN_IABI},
[0x34] = {(0x34<<26)},
[0x35] = {(0x35<<26), "l.sw", INSN_IABI},
[0x36] = {(0x36<<26), "l.sb", INSN_IABI},
[0x37] = {(0x37<<26), "l.sh", INSN_IABI},
[0x38] = {(0x38<<26), NULL, INSN_X, R_ANAL_OP_TYPE_NULL, extra_0x38},
[0x39] = {(0x39<<26), NULL, INSN_X, R_ANAL_OP_TYPE_NULL, extra_0x39},
[0x3a] = {(0x3a<<26)},
[0x3b] = {(0x3b<<26)},
[0x3c] = {(0x3c<<26), "l.cust5", INSN_X},
[0x3d] = {(0x3d<<26), "l.cust6", INSN_X},
[0x3e] = {(0x3e<<26), "l.cust7", INSN_X},
[0x3f] = {(0x3f<<26), "l.cust8", INSN_X},
};
size_t insns_count = sizeof(insns) / sizeof(insn_t);
insn_extra_t *find_extra_descriptor(insn_extra_t *extra_descr, ut32 insn) {
ut32 opcode;
while (extra_descr->type != INSN_END) {
opcode = (insn & extra_descr->opcode_mask);
if (extra_descr->opcode == opcode) {
break;
}
extra_descr++;
}
if (extra_descr->type != INSN_END) {
return extra_descr;
} else {
return NULL;
}
}
ut32 sign_extend(ut32 number, ut32 mask) {
/* xor of mask with itself shifted left detects msb of mask and msb of space
* on the right. And discards the latter */
ut32 first_bit = (mask ^ (mask >> 1)) & mask;
/* if first bit is set */
if (number & first_bit) {
/* set every bit outside mask */
number |= ~mask;
}
return number;
}

View File

@ -0,0 +1,181 @@
/* radare2 - LGPL - Copyright 2019 - v3l0c1r4pt0r */
#include <r_lib.h>
#ifndef OR1K_DISAS_H
#define OR1K_DISAS_H
/** Default mask for opcode */
#define INSN_OPCODE_MASK (0b111111 * 0x4000000)
#define INSN_OPCODE_SHIFT 26
/** Empty mask for unused operands */
#define INSN_EMPTY_SHIFT 0
#define INSN_EMPTY_MASK 0
/** Mask for N operand */
#define INSN_N_MASK 0b11111111111111111111111111
/** Shift for D operand */
#define INSN_D_SHIFT 21
/** Mask for D operand */
#define INSN_D_MASK (0b11111 * 0x200000)
/** Mask for K operand */
#define INSN_K_MASK 0b1111111111111111
/** Shift for B operand */
#define INSN_B_SHIFT 11
/** Mask for B operand */
#define INSN_B_MASK (0b11111 * 0x800)
/** Shift for A operand */
#define INSN_A_SHIFT 16
/** Mask for A operand */
#define INSN_A_MASK (0b11111 * 0x10000)
/** Mask for I operand */
#define INSN_I_MASK 0b1111111111111111
/** Mask for L operand */
#define INSN_L_MASK 0b111111
/** Shift for first K operand */
#define INSN_K1_SHIFT 21
/** Mask for first K operand */
#define INSN_K1_MASK (0b11111 * 0x200000)
/** Mask for second K operand */
#define INSN_K2_MASK 0b11111111111
typedef enum insn_type {
INSN_END = 0, /**< end of array indicator */
INSN_INVAL = 0, /**< invalid opcode */
INSN_X, /**< no operands */
INSN_N, /**< 26-bit immediate */
INSN_DN, /**< 5-bit destination register, then 26-bit immediate */
INSN_K, /**< 16-bit immediate */
INSN_DK, /**< 5-bit destination register, then 16-bit immediate */
INSN_D, /**< 5-bit destination register */
INSN_B, /**< 5-bit source register */
INSN_AI, /**< 5-bit source register, then 16-bit immediate */
INSN_DAI, /**< 5-bit destination register, 5-bit source register, then 16-bit
immediate */
INSN_DAK, /**< 5-bit destination register, 5-bit source register, then 16-bit
immediate */
INSN_DAL, /**< 5-bit destination register, 5-bit source register, then 6-bit
immediate */
INSN_KABK, /**< 5-bit MSB of immediate, 5-bit source register, 5-bit source
register, then 11-bit rest of immediate */
INSN_AB, /**< 5-bit source register, then 5-bit source register */
INSN_DA, /**< 5-bit destination register, then 5-bit source register */
INSN_DAB, /**< 5-bit destination register, 5-bit source register, then 5-bit
source register */
INSN_IABI, /**< 5-bit MSB of immediate, 5-bit source register, 5-bit source
register, then 11-bit rest of immediate */
INSN_SIZE, /**< number of types */
} insn_type_t;
typedef enum {
INSN_OPER_K1, /**< 5-bit MSBs of immediate */
INSN_OPER_K2, /**< 11-bit LSBs of immediate */
INSN_OPER_A, /**< 5-bit source register */
INSN_OPER_B, /**< 5-bit source register */
INSN_OPER_N, /**< 26-bit immediate */
INSN_OPER_K, /**< 16-bit immediate */
INSN_OPER_D, /**< 5-bit destination register */
INSN_OPER_I, /**< 16-bit immediate */
INSN_OPER_L, /**< 6-bit immediate */
INSN_OPER_SIZE /**< number of operand types */
} insn_oper_t;
typedef struct {
int oper;
ut32 mask;
ut32 shift;
} insn_oper_descr_t;
typedef struct {
int type;
char *format;
insn_oper_descr_t operands[INSN_OPER_SIZE];
} insn_type_descr_t;
typedef struct {
ut32 opcode;
char *name;
int type;
int opcode_mask;
int insn_type; /**< One of \link _RAnalOpType \endlink */
} insn_extra_t;
typedef struct {
ut32 opcode;
char *name;
int type;
int insn_type; /**< One of \link _RAnalOpType \endlink */
insn_extra_t *extra;
} insn_t;
extern insn_type_descr_t types[];
extern size_t types_count;
extern insn_extra_t extra_0x5[];
extern insn_extra_t extra_0x6[];
extern insn_extra_t extra_0x8[];
extern insn_extra_t extra_0x2e[];
extern insn_extra_t extra_0x2f[];
extern insn_extra_t extra_0x31[];
extern insn_extra_t extra_0x32[];
extern insn_extra_t extra_0x38[];
extern insn_extra_t extra_0x39[];
extern insn_t insns[];
extern size_t insns_count;
insn_extra_t *find_extra_descriptor(insn_extra_t *extra_descr, ut32 insn);
/**
* \brief Performs sign extension of number
*
* \param number number to extend
* \param mask mask under which number is placed
*
* \return sign-extended number
*
* If mask does not begin on the lsb, space on the right will also be filled with ones
*
*/
ut32 sign_extend(ut32 number, ut32 mask);
static inline ut32 get_operand_mask(insn_type_descr_t *type_descr, insn_oper_t operand) {
return type_descr->operands[operand].mask;
}
static inline ut32 get_operand_shift(insn_type_descr_t *type_descr, insn_oper_t operand) {
return type_descr->operands[operand].shift;
}
static inline ut32 get_operand_value(ut32 insn, insn_type_descr_t *type_descr, insn_oper_t operand) {
return (insn & get_operand_mask(type_descr, operand)) >> get_operand_shift(type_descr, operand);
}
static inline int has_type_descriptor(insn_type_t type) {
return types + types_count > &types[type];
}
static inline int is_type_descriptor_defined(insn_type_t type) {
return types[type].type == type;
}
static inline insn_type_t type_of_opcode(insn_t *descr, insn_extra_t *extra_descr) {
r_return_val_if_fail (descr, INSN_END);
if (extra_descr == NULL) {
return descr->type;
} else {
return extra_descr->type;
}
}
#endif /* OR1K_DISAS_H */

View File

@ -39,6 +39,7 @@ r_asm_sources = [
'p/asm_mips_gnu.c',
'p/asm_msp430.c',
'p/asm_nios2.c',
'p/asm_or1k.c',
'p/asm_pic.c',
'p/asm_mcore.c',
'p/asm_ppc_cs.c',
@ -115,6 +116,7 @@ r_asm_sources = [
'arch/msp430/msp430_disas.c',
'arch/nios/gnu/nios2-dis.c',
'arch/nios/gnu/nios2-opc.c',
'arch/or1k/or1k_disas.c',
'arch/pic/pic_baseline.c',
'arch/pic/pic_midrange.c',
'arch/pic/pic_pic18.c',
@ -174,7 +176,8 @@ r_asm_inc = [
'arch/ebc',
'arch/cr16',
'arch/8051',
'arch/v810'
'arch/v810',
'arch/or1k'
)
]

177
libr/asm/p/asm_or1k.c Normal file
View File

@ -0,0 +1,177 @@
/* radare2 - LGPL - Copyright 2019 - v3l0c1r4pt0r */
#include <r_asm.h>
#include <r_lib.h>
#include "../arch/or1k/or1k_disas.h"
struct operands {
ut32 rd;
ut32 ra;
ut32 rb;
ut32 n;
ut32 k1;
ut32 k2;
ut32 k;
ut32 i;
ut32 l;
};
static int insn_to_str(RAsm *a, char **line, insn_t *descr, insn_extra_t *extra, ut32 insn) {
struct operands o = {0};
char *name;
insn_type_t type = type_of_opcode(descr, extra);
insn_type_descr_t *type_descr = &types[INSN_X];
/* only use type descriptor if it has some useful data */
if (has_type_descriptor(type) && is_type_descriptor_defined(type)) {
type_descr = &types[type];
}
o.rd = get_operand_value(insn, type_descr, INSN_OPER_D);
o.ra = get_operand_value(insn, type_descr, INSN_OPER_A);
o.rb = get_operand_value(insn, type_descr, INSN_OPER_B);
o.k1 = get_operand_value(insn, type_descr, INSN_OPER_K1);
o.k2 = get_operand_value(insn, type_descr, INSN_OPER_K2);
o.n = get_operand_value(insn, type_descr, INSN_OPER_N);
o.k = get_operand_value(insn, type_descr, INSN_OPER_K);
o.i = get_operand_value(insn, type_descr, INSN_OPER_I);
o.l = get_operand_value(insn, type_descr, INSN_OPER_L);
name = (extra == NULL) ? descr->name : extra->name;
if (name == NULL || type_descr->format == NULL) {
/* this should not happen, give up */
*line = sdb_fmt("invalid");
return 4;
}
switch (type) {
case INSN_X:
*line = sdb_fmt(type_descr->format, name);
break;
case INSN_N:
*line = sdb_fmt(type_descr->format, name,
(sign_extend(o.n, get_operand_mask(type_descr, INSN_OPER_N)) << 2) +
a->pc);
break;
case INSN_K:
*line = sdb_fmt(type_descr->format, name, o.k);
break;
case INSN_DK:
*line = sdb_fmt(type_descr->format, name, o.rd, o.k);
break;
case INSN_DN:
*line = sdb_fmt(type_descr->format, name, o.rd, o.n << 13);
break;
case INSN_B:
*line = sdb_fmt(type_descr->format, name, o.rb);
break;
case INSN_D:
*line = sdb_fmt(type_descr->format, name, o.rd);
break;
case INSN_AI:
*line = sdb_fmt(type_descr->format, name, o.ra, o.i);
break;
case INSN_DAI:
*line = sdb_fmt(type_descr->format, name, o.rd, o.ra, o.i);
break;
case INSN_DAK:
*line = sdb_fmt(type_descr->format, name, o.rd, o.ra, o.i);
break;
case INSN_DAL:
*line = sdb_fmt(type_descr->format, name, o.rd, o.ra, o.l);
break;
case INSN_DA:
*line = sdb_fmt(type_descr->format, name, o.rd, o.ra);
break;
case INSN_DAB:
*line = sdb_fmt(type_descr->format, name, o.rd, o.ra, o.rb);
break;
case INSN_AB:
*line = sdb_fmt(type_descr->format, name, o.ra, o.rb);
break;
case INSN_IABI:
*line = sdb_fmt(type_descr->format, name,
o.ra, o.rb, (o.k1 << 11) | o.k2);
break;
case INSN_KABK:
*line = sdb_fmt(type_descr->format, name,
o.ra, o.rb, (o.k1 << 11) | o.k2);
break;
default:
*line = sdb_fmt("invalid");
}
return 4;
}
static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
ut32 insn, opcode;
ut8 opcode_idx;
char *line = NULL;
insn_t *insn_descr;
insn_extra_t *extra_descr;
op->size = -1;
if (len < 4) {
line = sdb_fmt("invalid");
r_strbuf_set (&op->buf_asm, line);
return op->size;
}
/* read instruction and basic opcode value */
insn = r_read_be32(buf);
op->size = 4;
opcode = (insn & INSN_OPCODE_MASK);
opcode_idx = opcode >> INSN_OPCODE_SHIFT;
/* make sure instruction descriptor table is not overflowed */
if (opcode_idx >= insns_count) {
line = sdb_fmt("invalid");
r_strbuf_set (&op->buf_asm, line);
return op->size;
}
/* if instruction is marked as invalid finish processing now */
insn_descr = &insns[opcode_idx];
if (insn_descr->type == INSN_INVAL) {
line = sdb_fmt("invalid");
r_strbuf_set (&op->buf_asm, line);
return op->size;
}
/* if name is null, but extra is present, it means 6 most significant bits
* are not enough to decode instruction */
if ((insn_descr->name == NULL) && (insn_descr->extra != NULL)) {
if ((extra_descr = find_extra_descriptor(insn_descr->extra, insn)) != NULL) {
insn_to_str(a, &line, insn_descr, extra_descr, insn);
}
else {
line = sdb_fmt("invalid");
}
r_strbuf_set (&op->buf_asm, line);
}
else {
/* otherwise basic descriptor is enough */
insn_to_str(a, &line, insn_descr, NULL, insn);
r_strbuf_set (&op->buf_asm, line);
}
return op->size;
}
RAsmPlugin r_asm_plugin_or1k = {
.name = "or1k",
.desc = "OpenRISC 1000",
.license = "LGPL3",
.arch = "or1k",
.bits = 32,
.endian = R_SYS_ENDIAN_BIG,
.fini = NULL,
.disassemble = &disassemble,
};
#ifndef R2_PLUGIN_INCORE
R_API RLibStruct radare_plugin = {
.type = R_LIB_TYPE_ASM, .data = &r_asm_plugin_or1k, .version = R2_VERSION};
#endif

11
libr/asm/p/or1k.mk Normal file
View File

@ -0,0 +1,11 @@
OBJ_OR1K=asm_or1k.o
OBJ_OR1K+=../arch/or1k/or1k_disas.o
CFLAGS+=-I./arch/or1k/
STATIC_OBJ+=${OBJ_OR1K}
TARGET_OR1K=asm_or1k.${EXT_SO}
ALL_TARGETS+=${TARGET_OR1K}
${TARGET_OR1K}: ${OBJ_OR1K}
${CC} $(call libname,asm_or1k) ${LDFLAGS} ${CFLAGS} -o asm_or1k.${EXT_SO} ${OBJ_OR1K}

View File

@ -2037,6 +2037,7 @@ extern RAnalPlugin r_anal_plugin_mips_cs;
extern RAnalPlugin r_anal_plugin_mips_gnu;
extern RAnalPlugin r_anal_plugin_msp430;
extern RAnalPlugin r_anal_plugin_nios2;
extern RAnalPlugin r_anal_plugin_or1k;
extern RAnalPlugin r_anal_plugin_pic;
extern RAnalPlugin r_anal_plugin_ppc_cs;
extern RAnalPlugin r_anal_plugin_ppc_gnu;

View File

@ -237,6 +237,7 @@ extern RAsmPlugin r_asm_plugin_mips_cs;
extern RAsmPlugin r_asm_plugin_mips_gnu;
extern RAsmPlugin r_asm_plugin_msp430;
extern RAsmPlugin r_asm_plugin_nios2;
extern RAsmPlugin r_asm_plugin_or1k;
extern RAsmPlugin r_asm_plugin_pic;
extern RAsmPlugin r_asm_plugin_ppc_cs;
extern RAsmPlugin r_asm_plugin_ppc_gnu;

View File

@ -27,6 +27,7 @@ anal_plugins = [
'msp430',
'nios2',
'null',
'or1k',
'pic',
'ppc_cs',
'ppc_gnu',
@ -89,6 +90,7 @@ asm_plugins = [
'mips_gnu',
'msp430',
'nios2',
'or1k',
'pic',
'ppc_cs',
'ppc_gnu',

View File

@ -26,6 +26,7 @@ anal.mips_gnu
anal.msp430
anal.nios2
anal.null
anal.or1k
anal.ppc_cs
anal.ppc_gnu
anal.sh
@ -84,6 +85,7 @@ asm.mips_cs
asm.mips_gnu
asm.msp430
asm.nios2
asm.or1k
asm.ppc_cs
asm.ppc_gnu
asm.propeller