mirror of
https://github.com/radareorg/radare2.git
synced 2024-11-23 13:19:54 +00:00
Hexagon QDSP6 v6 support - LGPLv3 (#9289)
This commit is contained in:
parent
897fb45241
commit
efcc2bef68
1809
libr/anal/arch/hexagon/hexagon_anal.c
Normal file
1809
libr/anal/arch/hexagon/hexagon_anal.c
Normal file
File diff suppressed because it is too large
Load Diff
2
libr/anal/arch/hexagon/hexagon_anal.h
Normal file
2
libr/anal/arch/hexagon/hexagon_anal.h
Normal file
@ -0,0 +1,2 @@
|
||||
int hexagon_anal_instruction(HexInsn *hi, RAnalOp *op);
|
||||
|
107
libr/anal/p/anal_hexagon.c
Normal file
107
libr/anal/p/anal_hexagon.c
Normal file
@ -0,0 +1,107 @@
|
||||
/* radare - LGPL - Copyright 2018 - xvilka */
|
||||
|
||||
#include <r_types.h>
|
||||
#include <r_util.h>
|
||||
#include <r_asm.h>
|
||||
#include <r_anal.h>
|
||||
#include <r_lib.h>
|
||||
#include "hexagon.h"
|
||||
#include "hexagon_insn.h"
|
||||
#include "hexagon_anal.h"
|
||||
|
||||
static int hexagon_v6_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *buf, int len) {
|
||||
HexInsn hi;
|
||||
ut32 data = 0;
|
||||
memset (op, 0, sizeof(RAnalOp));
|
||||
memset(&hi, 0, sizeof(hi));
|
||||
data = r_read_le32(buf);
|
||||
int size = hexagon_disasm_instruction(data, &hi);
|
||||
op->size = size;
|
||||
if (size <= 0) {
|
||||
return size;
|
||||
}
|
||||
|
||||
op->addr = addr;
|
||||
op->jump = op->fail = -1;
|
||||
op->ptr = op->val = -1;
|
||||
int ret = hexagon_anal_instruction(&hi, op);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int set_reg_profile(RAnal *anal) {
|
||||
// TODO: Add missing registers
|
||||
const char *p =
|
||||
"=PC pc\n"
|
||||
"=SP r29\n"
|
||||
"=FP r30\n"
|
||||
"=LR r31\n"
|
||||
"=ZF z\n"
|
||||
"=SF s\n"
|
||||
"=OF ov\n"
|
||||
"=CF cy\n"
|
||||
|
||||
"gpr r0 .32 0 0\n"
|
||||
"gpr r1 .32 4 0\n"
|
||||
"gpr r2 .32 8 0\n"
|
||||
"gpr r3 .32 12 0\n"
|
||||
"gpr r4 .32 16 0\n"
|
||||
"gpr r5 .32 20 0\n"
|
||||
"gpr r6 .32 24 0\n"
|
||||
"gpr r7 .32 28 0\n"
|
||||
"gpr r8 .32 32 0\n"
|
||||
"gpr r9 .32 36 0\n"
|
||||
"gpr r10 .32 40 0\n"
|
||||
"gpr r11 .32 44 0\n"
|
||||
"gpr r12 .32 48 0\n"
|
||||
"gpr r13 .32 52 0\n"
|
||||
"gpr r14 .32 56 0\n"
|
||||
"gpr r15 .32 60 0\n"
|
||||
"gpr r16 .32 64 0\n"
|
||||
"gpr r17 .32 68 0\n"
|
||||
"gpr r18 .32 72 0\n"
|
||||
"gpr r19 .32 76 0\n"
|
||||
"gpr r20 .32 80 0\n"
|
||||
"gpr r21 .32 84 0\n"
|
||||
"gpr r22 .32 88 0\n"
|
||||
"gpr r23 .32 92 0\n"
|
||||
"gpr r24 .32 96 0\n"
|
||||
"gpr r25 .32 100 0\n"
|
||||
"gpr r26 .32 104 0\n"
|
||||
"gpr r27 .32 108 0\n"
|
||||
"gpr r28 .32 112 0\n"
|
||||
"gpr r29 .32 116 0\n"
|
||||
"gpr r30 .32 120 0\n"
|
||||
"gpr r31 .32 124 0\n"
|
||||
"gpr pc .32 128 0\n"
|
||||
|
||||
"gpr psw .32 132 0\n"
|
||||
"gpr np .1 132.16 0\n"
|
||||
"gpr ep .1 132.17 0\n"
|
||||
"gpr ae .1 132.18 0\n"
|
||||
"gpr id .1 132.19 0\n"
|
||||
"flg cy .1 132.28 0\n"
|
||||
"flg ov .1 132.29 0\n"
|
||||
"flg s .1 132.30 0\n"
|
||||
"flg z .1 132.31 0\n";
|
||||
|
||||
return r_reg_set_profile_string (anal->reg, p);
|
||||
}
|
||||
|
||||
RAnalPlugin r_anal_plugin_hexagon = {
|
||||
.name = "hexagon",
|
||||
.desc = "Qualcomm Hexagon (QDSP6) V6",
|
||||
.license = "LGPL3",
|
||||
.arch = "hexagon",
|
||||
.bits = 32,
|
||||
.op = hexagon_v6_op,
|
||||
.esil = true,
|
||||
.set_reg_profile = set_reg_profile,
|
||||
};
|
||||
|
||||
#ifndef CORELIB
|
||||
RLibStruct radare_plugin = {
|
||||
.type = R_LIB_TYPE_ANAL,
|
||||
.data = &r_anal_plugin_hexagon_v6,
|
||||
.version = R2_VERSION
|
||||
};
|
||||
#endif
|
16
libr/anal/p/hexagon.mk
Normal file
16
libr/anal/p/hexagon.mk
Normal file
@ -0,0 +1,16 @@
|
||||
OBJ_HEXAGON=anal_hexagon.o
|
||||
OBJ_HEXAGON+=../../asm/arch/hexagon/hexagon.o
|
||||
OBJ_HEXAGON+=../../asm/arch/hexagon/hexagon_disas.o
|
||||
OBJ_HEXAGON+=../../anal/arch/hexagon/hexagon_anal.o
|
||||
|
||||
CFLAGS +=-I../asm/arch/hexagon
|
||||
CFLAGS +=-I../anal/arch/hexagon
|
||||
|
||||
STATIC_OBJ+=${OBJ_HEXAGON}
|
||||
TARGET_HEXAGON=anal_hexagon.${EXT_SO}
|
||||
|
||||
ALL_TARGETS+=${TARGET_HEXAGON}
|
||||
|
||||
${TARGET_HEXAGON}: ${OBJ_HEXAGON}
|
||||
${CC} $(call libname,anal_hexagon) ${LDFLAGS} ${CFLAGS} \
|
||||
-o $(TARGET_HEXAGON) $(OBJ_HEXAGON)
|
243
libr/asm/arch/hexagon/hexagon.c
Normal file
243
libr/asm/arch/hexagon/hexagon.c
Normal file
@ -0,0 +1,243 @@
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <r_types.h>
|
||||
#include <r_lib.h>
|
||||
#include <r_util.h>
|
||||
#include <r_asm.h>
|
||||
#include "hexagon.h"
|
||||
|
||||
// TODO: Handle also control reg pairs
|
||||
char* hex_get_cntl_reg(int opreg){
|
||||
switch (opreg) {
|
||||
case HEX_REG_SA0:
|
||||
return "SA0";
|
||||
case HEX_REG_LC0:
|
||||
return "LC0";
|
||||
case HEX_REG_SA1:
|
||||
return "SA1";
|
||||
case HEX_REG_LC1:
|
||||
return "LC1";
|
||||
case HEX_REG_P:
|
||||
return "P";
|
||||
case HEX_REG_M0:
|
||||
return "M0";
|
||||
case HEX_REG_M1:
|
||||
return "M1";
|
||||
case HEX_REG_USR:
|
||||
return "USR";
|
||||
case HEX_REG_PC:
|
||||
return "PC";
|
||||
case HEX_REG_UGP:
|
||||
return "UGP";
|
||||
case HEX_REG_GP:
|
||||
return "GP";
|
||||
case HEX_REG_CS0:
|
||||
return "CS0";
|
||||
case HEX_REG_CS1:
|
||||
return "CS1";
|
||||
case HEX_REG_UPCYCLELO:
|
||||
return "UPCYCLELO";
|
||||
case HEX_REG_UPCYCLEHI:
|
||||
return "UPCYCLEHI";
|
||||
case HEX_REG_FRAMELIMIT:
|
||||
return "FRAMELIMIT";
|
||||
case HEX_REG_FRAMEKEY:
|
||||
return "FRAMEKEY";
|
||||
case HEX_REG_PKTCOUNTLO:
|
||||
return "PKTCOUNTLO";
|
||||
case HEX_REG_PKTCOUNTHI:
|
||||
return "PKTCOUNTHI";
|
||||
case HEX_REG_UTIMERLO:
|
||||
return "UTIMERLO";
|
||||
case HEX_REG_UTIMERHI:
|
||||
return "UTIMERHI";
|
||||
default:
|
||||
return "<CRerr>";
|
||||
}
|
||||
}
|
||||
|
||||
char tmp[5] = { 0 };
|
||||
|
||||
char* hex_get_sys_reg(int opreg)
|
||||
{
|
||||
switch (opreg) {
|
||||
case HEX_REG_SGP0:
|
||||
return "SGP0";
|
||||
case HEX_REG_SGP1:
|
||||
return "SGP1";
|
||||
case HEX_REG_STID:
|
||||
return "STID";
|
||||
case HEX_REG_ELR:
|
||||
return "ELR";
|
||||
case HEX_REG_BADVA0:
|
||||
return "BADVA0";
|
||||
case HEX_REG_BADVA1:
|
||||
return "BADVA1";
|
||||
case HEX_REG_SSR:
|
||||
return "SSR";
|
||||
case HEX_REG_CCR:
|
||||
return "CCR";
|
||||
case HEX_REG_HTID:
|
||||
return "HTID";
|
||||
case HEX_REG_BADVA:
|
||||
return "BADVA";
|
||||
case HEX_REG_IMASK:
|
||||
return "IMASK";
|
||||
case HEX_REG_EVB:
|
||||
return "EVB";
|
||||
case HEX_REG_MODECTL:
|
||||
return "MODECTL";
|
||||
case HEX_REG_SYSCFG:
|
||||
return "SYSCFG";
|
||||
case HEX_REG_IPEND:
|
||||
return "IPEND";
|
||||
case HEX_REG_VID:
|
||||
return "VID";
|
||||
case HEX_REG_IAD:
|
||||
return "IAD";
|
||||
case HEX_REG_IEL:
|
||||
return "IEL";
|
||||
case HEX_REG_IAHL:
|
||||
return "IAHL";
|
||||
case HEX_REG_CFGBASE:
|
||||
return "CFGBASE";
|
||||
case HEX_REG_DIAG:
|
||||
return "DIAG";
|
||||
case HEX_REG_REV:
|
||||
return "REV";
|
||||
case HEX_REG_PCYCLELO:
|
||||
return "PCYCLELO";
|
||||
case HEX_REG_PCYCLEHI:
|
||||
return "PCYCLEHI";
|
||||
case HEX_REG_ISDBST:
|
||||
return "ISDBST";
|
||||
case HEX_REG_ISDBCFG0:
|
||||
return "ISDBCFG0";
|
||||
case HEX_REG_ISDBCFG1:
|
||||
return "ISDBCFG1";
|
||||
case HEX_REG_BRKPTPC0:
|
||||
return "BRKPTPC0";
|
||||
case HEX_REG_BRKPTCFG0:
|
||||
return "BRKPTCFG0";
|
||||
case HEX_REG_BRKPTPC1:
|
||||
return "BRKPTPC1";
|
||||
case HEX_REG_BRKPTCFG1:
|
||||
return "BRKPTCFG1";
|
||||
case HEX_REG_ISDBMBXIN:
|
||||
return "ISDBMBXIN";
|
||||
case HEX_REG_ISDBMBXOUT:
|
||||
return "ISDBMBXOUT";
|
||||
case HEX_REG_ISDBEN:
|
||||
return "ISDBEN";
|
||||
case HEX_REG_ISDBGPR:
|
||||
return "ISDBGPR";
|
||||
case HEX_REG_PMUCNT0:
|
||||
return "PMUCNT0";
|
||||
case HEX_REG_PMUCNT1:
|
||||
return "PMUCNT1";
|
||||
case HEX_REG_PMUCNT2:
|
||||
return "PMUCNT2";
|
||||
case HEX_REG_PMUCNT3:
|
||||
return "PMUCNT3";
|
||||
case HEX_REG_PMUEVTCFG:
|
||||
return "PMUEVTCFG";
|
||||
case HEX_REG_PMUCFG:
|
||||
return "PMUCFG";
|
||||
default:
|
||||
sprintf(tmp, "S%d", opreg);
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
|
||||
char* hex_get_sub_reg(int opreg)
|
||||
{
|
||||
switch (opreg) {
|
||||
case HEX_SUB_REG_R0:
|
||||
return "R0";
|
||||
case HEX_SUB_REG_R1:
|
||||
return "R1";
|
||||
case HEX_SUB_REG_R2:
|
||||
return "R2";
|
||||
case HEX_SUB_REG_R3:
|
||||
return "R3";
|
||||
case HEX_SUB_REG_R4:
|
||||
return "R4";
|
||||
case HEX_SUB_REG_R5:
|
||||
return "R5";
|
||||
case HEX_SUB_REG_R6:
|
||||
return "R6";
|
||||
case HEX_SUB_REG_R7:
|
||||
return "R7";
|
||||
case HEX_SUB_REG_R16:
|
||||
return "R16";
|
||||
case HEX_SUB_REG_R17:
|
||||
return "R17";
|
||||
case HEX_SUB_REG_R18:
|
||||
return "R18";
|
||||
case HEX_SUB_REG_R19:
|
||||
return "R19";
|
||||
case HEX_SUB_REG_R20:
|
||||
return "R20";
|
||||
case HEX_SUB_REG_R21:
|
||||
return "R21";
|
||||
case HEX_SUB_REG_R22:
|
||||
return "R22";
|
||||
case HEX_SUB_REG_R23:
|
||||
return "R23";
|
||||
default:
|
||||
return "<err>";
|
||||
}
|
||||
}
|
||||
|
||||
char* hex_get_sub_regpair(int opreg)
|
||||
{
|
||||
switch (opreg) {
|
||||
case HEX_SUB_REGPAIR_R1_R0:
|
||||
return "R1:R0";
|
||||
case HEX_SUB_REGPAIR_R3_R2:
|
||||
return "R3:R2";
|
||||
case HEX_SUB_REGPAIR_R5_R4:
|
||||
return "R5:R4";
|
||||
case HEX_SUB_REGPAIR_R7_R6:
|
||||
return "R7:R6";
|
||||
case HEX_SUB_REGPAIR_R17_R16:
|
||||
return "R17:R16";
|
||||
case HEX_SUB_REGPAIR_R19_R18:
|
||||
return "R19:R18";
|
||||
case HEX_SUB_REGPAIR_R21_R20:
|
||||
return "R21:R20";
|
||||
case HEX_SUB_REGPAIR_R23_R22:
|
||||
return "R23:R22";
|
||||
default:
|
||||
return "<err>";
|
||||
}
|
||||
}
|
||||
|
||||
inline bool hex_if_duplex(uint32_t insn_word)
|
||||
{
|
||||
if (insn_word & (3 << 14) == 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Constant extender value
|
||||
ut32 constant_extender = 1;
|
||||
|
||||
void hex_op_extend(HexOp *op)
|
||||
{
|
||||
if ((constant_extender != 1) && (op->type == HEX_OP_TYPE_IMM)) {
|
||||
op->op.imm = ((op->op.imm) & 0x3F) | (constant_extender);
|
||||
}
|
||||
constant_extender = 1;
|
||||
}
|
||||
|
||||
void hex_op_extend_off(HexOp *op, int offset)
|
||||
{
|
||||
if ((constant_extender != 1) && (op->type == HEX_OP_TYPE_IMM)) {
|
||||
op->op.imm = (op->op.imm) >> offset;
|
||||
hex_op_extend(op);
|
||||
}
|
||||
}
|
||||
|
||||
|
277
libr/asm/arch/hexagon/hexagon.h
Normal file
277
libr/asm/arch/hexagon/hexagon.h
Normal file
@ -0,0 +1,277 @@
|
||||
// Predicates - declare the predicate state
|
||||
typedef enum {
|
||||
HEX_NOPRED, // no conditional execution
|
||||
HEX_PRED_TRUE, // if (Pd) ...
|
||||
HEX_PRED_FALSE, // if (!Pd) ...
|
||||
HEX_PRED_TRUE_NEW, // if (Pd.new) ...
|
||||
HEX_PRED_FALSE_NEW, // if (!Pd.new) ...
|
||||
} HexPred;
|
||||
|
||||
// Pre/post-fixes, different types
|
||||
typedef enum {
|
||||
HEX_PF_RND = 1, // :rnd
|
||||
HEX_PF_CRND = 1<<1, // :crnd
|
||||
HEX_PF_RAW = 1<<2, // :raw
|
||||
HEX_PF_CHOP = 1<<3, // :chop
|
||||
HEX_PF_SAT = 1<<4, // :sat
|
||||
HEX_PF_HI = 1<<5, // :hi
|
||||
HEX_PF_LO = 1<<6, // :lo
|
||||
HEX_PF_LSH1 = 1<<7, // :<<1
|
||||
HEX_PF_LSH16 = 1<<8, // :<<16
|
||||
HEX_PF_RSH1 = 1<<9, // :>>1
|
||||
HEX_PF_NEG = 1<<10, // :neg
|
||||
HEX_PF_POS = 1<<11, // :pos
|
||||
HEX_PF_SCALE = 1<<12, // :scale, for FMA instructions
|
||||
HEX_PF_DEPRECATED = 1<<15, // :deprecated
|
||||
} HexPf;
|
||||
|
||||
typedef enum {
|
||||
HEX_OP_TYPE_IMM,
|
||||
HEX_OP_TYPE_REG,
|
||||
HEX_OP_TYPE_PREDICATE,
|
||||
HEX_OP_TYPE_CONTROL,
|
||||
HEX_OP_TYPE_SYSTEM,
|
||||
HEX_OP_TYPE_OPT, // Do not really use in the C code
|
||||
} HexOpType;
|
||||
|
||||
// Attributes - .H/.L, const extender
|
||||
typedef enum {
|
||||
HEX_OP_CONST_EXT = 1 << 0, // Constant extender marker for Immediate
|
||||
HEX_OP_REG_HI = 1 << 1, // Rn.H marker
|
||||
HEX_OP_REG_LO = 1 << 2, // Rn.L marker
|
||||
HEX_OP_REG_PAIR = 1 << 3, // Is this a register pair?
|
||||
} HexOpAttr;
|
||||
|
||||
typedef struct {
|
||||
ut8 type;
|
||||
union {
|
||||
ut8 reg; // + additional Hi or Lo selector // + additional shift // + additional :brev //
|
||||
ut32 imm;
|
||||
ut8 pred; // predicates - P0-P3 registers
|
||||
ut8 cr; // control register
|
||||
ut8 sys; // system control register
|
||||
} op;
|
||||
ut8 attr;
|
||||
} HexOp;
|
||||
|
||||
typedef struct {
|
||||
int instruction;
|
||||
ut32 mask;
|
||||
HexPred predicate; // predicate set if set
|
||||
ut16 pf; // additional prefixes (bitmap)
|
||||
bool duplex; // is part of duplex container?
|
||||
bool compound; // is part of compound instruction?
|
||||
bool last; // is last in instruction packet?
|
||||
int shift; // Optional shift left is it true?
|
||||
ut8 op_count;
|
||||
HexOp ops[4];
|
||||
char mnem[128]; // Instruction mnemonic
|
||||
} HexInsn;
|
||||
|
||||
// Instruction container (currently only 2 instructions)
|
||||
// Can handle duplexes
|
||||
typedef struct {
|
||||
bool duplex;
|
||||
HexInsn ins[2]; // Or make it pointer + size?
|
||||
} HexInsnCont;
|
||||
|
||||
// Instruction packet (Maximum - 4 instructions)
|
||||
// Can handle up to 4 instructions or 1 duplex + 2 instructions
|
||||
// Can have a loop marks
|
||||
typedef struct {
|
||||
bool loop0; // :endloop0 marker
|
||||
bool loop1; // :endloop1 marker
|
||||
int cont_cnt;
|
||||
HexInsnCont ins[4]; // Or make it pointer + size?
|
||||
} HexInsnPkt;
|
||||
|
||||
typedef enum {
|
||||
HEX_INSN_CLASS_CEXT = 0, // Constant extender
|
||||
HEX_INSN_CLASS_J1 = 1, // Jump
|
||||
HEX_INSN_CLASS_J2 = 2, // Jump
|
||||
HEX_INSN_CLASS_LD_ST = 3, // Load/Store
|
||||
HEX_INSN_CLASS_LD_ST_COND_GP = 4, // Load/Store conditional or GP relative
|
||||
HEX_INSN_CLASS_J3 = 5, // Jump
|
||||
HEX_INSN_CLASS_CR = 6, // Control register instructions
|
||||
HEX_INSN_CLASS_ALU32 = 7, // ALU32
|
||||
HEX_INSN_CLASS_XTYPE = 8, // XTYPE
|
||||
HEX_INSN_CLASS_LD = 9, // Just load instructions
|
||||
HEX_INSN_CLASS_ST = 10, // Just store instructions
|
||||
HEX_INSN_CLASS_ALU32_1 = 11, // ALU32
|
||||
HEX_INSN_CLASS_XTYPE_1 = 12, // XTYPE again
|
||||
HEX_INSN_CLASS_XTYPE_2 = 13, // XTYPE one more time
|
||||
HEX_INSN_CLASS_XTYPE_3 = 14, // And again, XTYPE
|
||||
HEX_INSN_CLASS_ALU32_2 = 12, // ALU32 again
|
||||
} HEX_INSN_CLASS;
|
||||
|
||||
typedef enum {
|
||||
HEX_REG_R0 = 0,
|
||||
HEX_REG_R1 = 1,
|
||||
HEX_REG_R2 = 2,
|
||||
HEX_REG_R3 = 3,
|
||||
HEX_REG_R4 = 4,
|
||||
HEX_REG_R5 = 5,
|
||||
HEX_REG_R6 = 6,
|
||||
HEX_REG_R7 = 7,
|
||||
HEX_REG_R8 = 8,
|
||||
HEX_REG_R9 = 9,
|
||||
HEX_REG_R10 = 10,
|
||||
HEX_REG_R11 = 11,
|
||||
HEX_REG_R12 = 12,
|
||||
HEX_REG_R13 = 13,
|
||||
HEX_REG_R14 = 14,
|
||||
HEX_REG_R15 = 15,
|
||||
HEX_REG_R16 = 16,
|
||||
HEX_REG_R17 = 17,
|
||||
HEX_REG_R18 = 18,
|
||||
HEX_REG_R19 = 19,
|
||||
HEX_REG_R20 = 20,
|
||||
HEX_REG_R21 = 21,
|
||||
HEX_REG_R22 = 22,
|
||||
HEX_REG_R23 = 23,
|
||||
HEX_REG_R24 = 24,
|
||||
HEX_REG_R25 = 25,
|
||||
HEX_REG_R26 = 26,
|
||||
HEX_REG_R27 = 27,
|
||||
HEX_REG_R28 = 28,
|
||||
HEX_REG_R29 = 29,
|
||||
HEX_REG_R30 = 30,
|
||||
HEX_REG_R31 = 31,
|
||||
} HEX_REG;
|
||||
|
||||
// TODO: Also add regpair values
|
||||
|
||||
// Control registers
|
||||
typedef enum {
|
||||
// Loop registers
|
||||
HEX_REG_SA0 = 0, // C0
|
||||
HEX_REG_LC0 = 1, // C1
|
||||
HEX_REG_SA1 = 2, // C2
|
||||
HEX_REG_LC1 = 3, // C3
|
||||
HEX_REG_P = 4, // C4 - 4 of 8bit registers
|
||||
// C5 is reserved
|
||||
// Modifier registers
|
||||
HEX_REG_M0 = 6, // C6
|
||||
HEX_REG_M1 = 7, // C7
|
||||
HEX_REG_USR = 8, // C8 // User Status Register
|
||||
HEX_REG_PC = 9, // C9 // Program counter
|
||||
HEX_REG_UGP = 10, // C10 // User General Pointer
|
||||
HEX_REG_GP = 11, // C11 // Global Pointer
|
||||
// Circular Start registers
|
||||
HEX_REG_CS0 = 12, // C12
|
||||
HEX_REG_CS1 = 13, // C13
|
||||
// Cycle Count registers
|
||||
HEX_REG_UPCYCLELO = 14, // C14
|
||||
HEX_REG_UPCYCLEHI = 15, // C15
|
||||
HEX_REG_FRAMELIMIT = 16, // C16 // Stack Bounds register
|
||||
HEX_REG_FRAMEKEY = 17, // C17 // Stack Smash register
|
||||
// Packet Count registers
|
||||
HEX_REG_PKTCOUNTLO = 18, // C18
|
||||
HEX_REG_PKTCOUNTHI = 19, // C19
|
||||
// C20 - C29 are reserved
|
||||
// Qtimer registers
|
||||
HEX_REG_UTIMERLO = 30, // C30
|
||||
HEX_REG_UTIMERHI = 31, // C31
|
||||
} HEX_CR_REG;
|
||||
|
||||
// Supervisor control registers
|
||||
typedef enum {
|
||||
HEX_REG_SGP0 = 0, // S0
|
||||
HEX_REG_SGP1 = 1, // S1
|
||||
HEX_REG_STID = 2, // S2
|
||||
HEX_REG_ELR = 3, // S3
|
||||
HEX_REG_BADVA0 = 4, // S4
|
||||
HEX_REG_BADVA1 = 5, // S5
|
||||
HEX_REG_SSR = 6, // S6
|
||||
HEX_REG_CCR = 7, // S7
|
||||
HEX_REG_HTID = 8, // S8
|
||||
HEX_REG_BADVA = 9, // S9
|
||||
HEX_REG_IMASK = 10, // S10
|
||||
// S11 - S15 are reserved
|
||||
HEX_REG_EVB = 16, // S16
|
||||
HEX_REG_MODECTL = 17, // S17
|
||||
HEX_REG_SYSCFG = 18, // S18
|
||||
// S19 is reserved
|
||||
HEX_REG_IPEND = 20, // S20
|
||||
HEX_REG_VID = 21, // S21
|
||||
HEX_REG_IAD = 22, // S22
|
||||
// S23 is reserved
|
||||
HEX_REG_IEL = 24, // S24
|
||||
// S25 is reserved
|
||||
HEX_REG_IAHL = 26, // S26
|
||||
HEX_REG_CFGBASE = 27, // S27
|
||||
HEX_REG_DIAG = 28, // S28
|
||||
HEX_REG_REV = 29, // S29
|
||||
HEX_REG_PCYCLELO = 30, // S30
|
||||
HEX_REG_PCYCLEHI = 31, // S31
|
||||
HEX_REG_ISDBST = 32, // S32
|
||||
HEX_REG_ISDBCFG0 = 33, // S33
|
||||
HEX_REG_ISDBCFG1 = 34, // S34
|
||||
// S35 is reserved
|
||||
HEX_REG_BRKPTPC0 = 36, // S36
|
||||
HEX_REG_BRKPTCFG0 = 37, // S37
|
||||
HEX_REG_BRKPTPC1 = 38, // S38
|
||||
HEX_REG_BRKPTCFG1 = 39, // S39
|
||||
HEX_REG_ISDBMBXIN = 40, // S40
|
||||
HEX_REG_ISDBMBXOUT = 41, // S41
|
||||
HEX_REG_ISDBEN = 42, // S42
|
||||
HEX_REG_ISDBGPR = 43, // S43
|
||||
// S44 - S47 are reserved
|
||||
HEX_REG_PMUCNT0 = 48, // S48
|
||||
HEX_REG_PMUCNT1 = 49, // S49
|
||||
HEX_REG_PMUCNT2 = 50, // S50
|
||||
HEX_REG_PMUCNT3 = 51, // S51
|
||||
HEX_REG_PMUEVTCFG = 52, // S52
|
||||
HEX_REG_PMUCFG = 53, // S53
|
||||
// S54 - S63 are reserved
|
||||
} HEX_SYSCR_REG;
|
||||
|
||||
// Here are the register field values for subinstructions
|
||||
|
||||
typedef enum {
|
||||
HEX_SUB_REG_R0 = 0, // 0b0000
|
||||
HEX_SUB_REG_R1 = 1, // 0b0001
|
||||
HEX_SUB_REG_R2 = 2, // 0b0010
|
||||
HEX_SUB_REG_R3 = 3, // 0b0011
|
||||
HEX_SUB_REG_R4 = 4, // 0b0100
|
||||
HEX_SUB_REG_R5 = 5, // 0b0101
|
||||
HEX_SUB_REG_R6 = 6, // 0b0110
|
||||
HEX_SUB_REG_R7 = 7, // 0b0111
|
||||
HEX_SUB_REG_R16 = 8, // 0b1000
|
||||
HEX_SUB_REG_R17 = 9, // 0b1001
|
||||
HEX_SUB_REG_R18 = 10, // 0b1010
|
||||
HEX_SUB_REG_R19 = 11, // 0b1011
|
||||
HEX_SUB_REG_R20 = 12, // 0b1100
|
||||
HEX_SUB_REG_R21 = 13, // 0b1101
|
||||
HEX_SUB_REG_R22 = 14, // 0b1110
|
||||
HEX_SUB_REG_R23 = 15, // 0b1111
|
||||
} HEX_SUB_REG;
|
||||
|
||||
|
||||
typedef enum {
|
||||
HEX_SUB_REGPAIR_R1_R0 = 0, // 0b000
|
||||
HEX_SUB_REGPAIR_R3_R2 = 1, // 0b001
|
||||
HEX_SUB_REGPAIR_R5_R4 = 2, // 0b010
|
||||
HEX_SUB_REGPAIR_R7_R6 = 3, // 0b011
|
||||
HEX_SUB_REGPAIR_R17_R16 = 4, // 0b100
|
||||
HEX_SUB_REGPAIR_R19_R18 = 5, // 0b101
|
||||
HEX_SUB_REGPAIR_R21_R20 = 6, // 0b110
|
||||
HEX_SUB_REGPAIR_R23_R22 = 7, // 0b111
|
||||
} HEX_SUB_REGPAIR;
|
||||
|
||||
|
||||
#define BIT_MASK(len) (BIT(len)-1)
|
||||
#define BF_MASK(start, len) (BIT_MASK(len)<<(start))
|
||||
#define BF_PREP(x, start, len) (((x)&BIT_MASK(len))<<(start))
|
||||
#define BF_GET(y, start, len) (((y)>>(start)) & BIT_MASK(len))
|
||||
#define BF_GETB(y, start, end) (BF_GET((y), (start), (end) - (start) + 1)
|
||||
|
||||
char* hex_get_cntl_reg(int opreg);
|
||||
char* hex_get_sys_reg(int opreg);
|
||||
char* hex_get_sub_reg(int opreg);
|
||||
char* hex_get_sub_regpair(int opreg);
|
||||
bool hex_if_duplex(ut32 insn_word);
|
||||
void hex_op_extend(HexOp *op);
|
||||
void hex_op_extend_off(HexOp *op, int offset);
|
||||
int hexagon_disasm_instruction(ut32 hi_u32, HexInsn *hi);
|
||||
|
45275
libr/asm/arch/hexagon/hexagon_disas.c
Normal file
45275
libr/asm/arch/hexagon/hexagon_disas.c
Normal file
File diff suppressed because it is too large
Load Diff
2802
libr/asm/arch/hexagon/hexagon_insn.h
Normal file
2802
libr/asm/arch/hexagon/hexagon_insn.h
Normal file
File diff suppressed because it is too large
Load Diff
36
libr/asm/p/asm_hexagon.c
Normal file
36
libr/asm/p/asm_hexagon.c
Normal file
@ -0,0 +1,36 @@
|
||||
/* radare - LGPL - Copyright 2018 - xvilka */
|
||||
|
||||
#include <r_types.h>
|
||||
#include <r_util.h>
|
||||
#include <r_asm.h>
|
||||
#include <r_lib.h>
|
||||
#include "hexagon.h"
|
||||
#include "hexagon_insn.h"
|
||||
|
||||
static int disassemble (RAsm *a, RAsmOp *op, const ut8 *buf, int l)
|
||||
{
|
||||
HexInsn hi;
|
||||
ut32 data = 0;
|
||||
memset(&hi, 0, sizeof(hi));
|
||||
data = r_read_le32(buf);
|
||||
int size = hexagon_disasm_instruction(data, &hi);
|
||||
op->size = size;
|
||||
strcpy(op->buf_asm, hi.mnem);
|
||||
return size;
|
||||
}
|
||||
|
||||
RAsmPlugin r_asm_plugin_hexagon = {
|
||||
.name = "hexagon",
|
||||
.arch = "hexagon",
|
||||
.license = "LGPL3",
|
||||
.bits = 32,
|
||||
.desc = "Qualcomm Hexagon (QDSP6) V6",
|
||||
.disassemble = &disassemble,
|
||||
};
|
||||
|
||||
#ifndef CORELIB
|
||||
struct r_lib_struct_t radare_plugin = {
|
||||
.type = R_LIB_TYPE_ASM,
|
||||
.data = &r_asm_plugin_hexagon
|
||||
};
|
||||
#endif
|
@ -90,8 +90,8 @@ print_insn_hexagon = hexagon_get_disassembler_from_mach(0,0);
|
||||
}
|
||||
|
||||
RAsmPlugin r_asm_plugin_hexagon_gnu = {
|
||||
.name = "hexagon",
|
||||
.arch = "hexagon",
|
||||
.name = "hexagon.gnu",
|
||||
.arch = "hexagon.gnu",
|
||||
.bits = 32,
|
||||
.endian = R_SYS_ENDIAN_BIG | R_SYS_ENDIAN_LITTLE,
|
||||
.license = "GPL3",
|
||||
|
15
libr/asm/p/hexagon.mk
Normal file
15
libr/asm/p/hexagon.mk
Normal file
@ -0,0 +1,15 @@
|
||||
OBJ_HEXAGON=asm_hexagon.o
|
||||
OBJ_HEXAGON+=../arch/hexagon/hexagon.o
|
||||
OBJ_HEXAGON+=../arch/hexagon/hexagon_disas.o
|
||||
|
||||
CFLAGS +=-I../asm/arch/hexagon
|
||||
|
||||
STATIC_OBJ+=${OBJ_HEXAGON}
|
||||
|
||||
TARGET_HEXAGON=asm_hexagon.${EXT_SO}
|
||||
ifeq ($(WITHPIC),1)
|
||||
ALL_TARGETS+=${TARGET_HEXAGON}
|
||||
|
||||
${TARGET_HEXAGON}: ${OBJ_HEXAGON}
|
||||
${CC} $(call libname,asm_hexagon) ${LDFLAGS} ${CFLAGS} -o ${TARGET_HEXAGON} ${OBJ_HEXAGON}
|
||||
endif
|
@ -1,14 +1,14 @@
|
||||
OBJ_HEXAGON=asm_hexagon_gnu.o
|
||||
OBJ_HEXAGON+=../arch/hexagon/gnu/hexagon-dis.o
|
||||
OBJ_HEXAGON+=../arch/hexagon/gnu/hexagon-opc.o
|
||||
OBJ_HEXAGON+=../arch/hexagon/gnu/safe-ctype.o
|
||||
OBJ_HEXAGON_GNU=asm_hexagon_gnu.o
|
||||
OBJ_HEXAGON_GNU+=../arch/hexagon/gnu/hexagon-dis.o
|
||||
OBJ_HEXAGON_GNU+=../arch/hexagon/gnu/hexagon-opc.o
|
||||
OBJ_HEXAGON_GNU+=../arch/hexagon/gnu/safe-ctype.o
|
||||
|
||||
STATIC_OBJ+=${OBJ_HEXAGON}
|
||||
STATIC_OBJ+=${OBJ_HEXAGON_GNU}
|
||||
|
||||
TARGET_HEXAGON=asm_hexagon_gnu.${EXT_SO}
|
||||
TARGET_HEXAGON_GNU=asm_hexagon_gnu.${EXT_SO}
|
||||
ifeq ($(WITHPIC),1)
|
||||
ALL_TARGETS+=${TARGET_HEXAGON}
|
||||
ALL_TARGETS+=${TARGET_HEXAGON_GNU}
|
||||
|
||||
${TARGET_HEXAGON}: ${OBJ_HEXAGON}
|
||||
${CC} $(call libname,asm_hexagon_gnu) ${LDFLAGS} ${CFLAGS} -o ${TARGET_HEXAGON} ${OBJ_HEXAGON}
|
||||
${TARGET_HEXAGON_GNU}: ${OBJ_HEXAGON_GNU}
|
||||
${CC} $(call libname,asm_hexagon_gnu) ${LDFLAGS} ${CFLAGS} -o ${TARGET_HEXAGON_GNU} ${OBJ_HEXAGON_GNU}
|
||||
endif
|
||||
|
@ -1672,6 +1672,7 @@ extern RAnalPlugin r_anal_plugin_ebc;
|
||||
extern RAnalPlugin r_anal_plugin_gb;
|
||||
extern RAnalPlugin r_anal_plugin_nios2;
|
||||
extern RAnalPlugin r_anal_plugin_malbolge;
|
||||
extern RAnalPlugin r_anal_plugin_hexagon;
|
||||
extern RAnalPlugin r_anal_plugin_wasm;
|
||||
extern RAnalPlugin r_anal_plugin_ws;
|
||||
extern RAnalPlugin r_anal_plugin_h8300;
|
||||
|
@ -253,6 +253,7 @@ extern RAsmPlugin r_asm_plugin_xtensa;
|
||||
extern RAsmPlugin r_asm_plugin_tricore;
|
||||
extern RAsmPlugin r_asm_plugin_pic;
|
||||
extern RAsmPlugin r_asm_plugin_rsp;
|
||||
extern RAsmPlugin r_asm_plugin_hexagon;
|
||||
extern RAsmPlugin r_asm_plugin_hexagon_gnu;
|
||||
extern RAsmPlugin r_asm_plugin_wasm;
|
||||
extern RAsmPlugin r_asm_plugin_tms320c64x;
|
||||
|
@ -12,6 +12,7 @@ anal.dalvik
|
||||
anal.ebc
|
||||
anal.gb
|
||||
anal.h8300
|
||||
anal.hexagon
|
||||
anal.i8080
|
||||
anal.java
|
||||
anal.m68k_cs
|
||||
@ -57,7 +58,7 @@ asm.cr16
|
||||
asm.cris_gnu
|
||||
asm.dalvik
|
||||
asm.dcpu16
|
||||
asm.hexagon_gnu
|
||||
asm.hexagon
|
||||
asm.ebc
|
||||
asm.gb
|
||||
asm.h8300
|
||||
|
@ -10,6 +10,7 @@ anal.gb
|
||||
anal.h8300
|
||||
anal.i8080
|
||||
anal.java
|
||||
anal.hexagon
|
||||
anal.m68k
|
||||
anal.malbolge
|
||||
anal.mips_cs
|
||||
@ -39,6 +40,7 @@ asm.h8300
|
||||
asm.i4004
|
||||
asm.i8080
|
||||
asm.java
|
||||
asm.hexagon
|
||||
asm.m68k
|
||||
asm.malbolge
|
||||
asm.mips_cs
|
||||
|
Loading…
Reference in New Issue
Block a user