Add TMS320 disassembly engine
This patch adds TMS320 DSP family processors disassembly engine. It's purpose to add support for the all the families processors but as for now the only one of them is supported (C55X).
This commit is contained in:
parent
c24543f112
commit
1db5c446a9
|
@ -7,6 +7,9 @@ ASM_OBJS += arch/x86/ollyasm/asmserv.c arch/x86/ollyasm/assembl.c arch/x86/ollya
|
|||
ASM_OBJS += arch/c55plus/c55plus.c arch/c55plus/decode.c arch/c55plus/decode_funcs.c ;
|
||||
ASM_OBJS += arch/c55plus/hashtable.c arch/c55plus/hashvector.c arch/c55plus/ins.c arch/c55plus/utils.c ;
|
||||
|
||||
# TMS320
|
||||
ASM_OBJS += arch/tms320/tms320_dasm.c ;
|
||||
|
||||
# ARC
|
||||
ASM_OBJS += arch/arc/gnu/arc-dis.c ;
|
||||
ASM_OBJS += arch/arc/gnu/arc-ext.c ;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,223 @@
|
|||
#ifndef __TMS320_DASM_H__
|
||||
#define __TMS320_DASM_H__
|
||||
|
||||
#define IDA_COMPATIBLE_MODE 1
|
||||
|
||||
/* forward declarations */
|
||||
|
||||
struct tms320_instruction;
|
||||
typedef struct tms320_instruction insn_item_t;
|
||||
|
||||
struct tms320_instruction_mask;
|
||||
typedef struct tms320_instruction_mask insn_mask_t;
|
||||
|
||||
struct tms320_instruction_flag;
|
||||
typedef struct tms320_instruction_flag insn_flag_t;
|
||||
|
||||
struct tms320_instruction_head;
|
||||
typedef struct tms320_instruction_head insn_head_t;
|
||||
|
||||
typedef enum {
|
||||
TMS320_FLAG_E = 0x10,
|
||||
TMS320_FLAG_R,
|
||||
TMS320_FLAG_U,
|
||||
TMS320_FLAG_u,
|
||||
TMS320_FLAG_g,
|
||||
TMS320_FLAG_r,
|
||||
TMS320_FLAG_t,
|
||||
|
||||
TMS320_FLAG_uu,
|
||||
TMS320_FLAG_mm,
|
||||
TMS320_FLAG_cc,
|
||||
TMS320_FLAG_tt,
|
||||
TMS320_FLAG_vv,
|
||||
TMS320_FLAG_ss,
|
||||
TMS320_FLAG_dd,
|
||||
TMS320_FLAG_SS,
|
||||
TMS320_FLAG_DD,
|
||||
|
||||
TMS320_FLAG_k3,
|
||||
TMS320_FLAG_k4,
|
||||
TMS320_FLAG_k5,
|
||||
TMS320_FLAG_k6,
|
||||
TMS320_FLAG_k8,
|
||||
TMS320_FLAG_k12,
|
||||
TMS320_FLAG_k16,
|
||||
|
||||
TMS320_FLAG_K8,
|
||||
TMS320_FLAG_K16,
|
||||
|
||||
TMS320_FLAG_l1,
|
||||
TMS320_FLAG_l3,
|
||||
TMS320_FLAG_l7,
|
||||
TMS320_FLAG_l16,
|
||||
|
||||
TMS320_FLAG_L7,
|
||||
TMS320_FLAG_L8,
|
||||
TMS320_FLAG_L16,
|
||||
|
||||
TMS320_FLAG_P8,
|
||||
TMS320_FLAG_P24,
|
||||
TMS320_FLAG_D16,
|
||||
|
||||
TMS320_FLAG_SHFT,
|
||||
TMS320_FLAG_SHIFTW,
|
||||
TMS320_FLAG_CCCCCCC,
|
||||
TMS320_FLAG_AAAAAAAI,
|
||||
|
||||
TMS320_FLAG_FSSS,
|
||||
TMS320_FLAG_FDDD,
|
||||
TMS320_FLAG_XSSS,
|
||||
TMS320_FLAG_XDDD,
|
||||
TMS320_FLAG_XACS,
|
||||
TMS320_FLAG_XACD,
|
||||
|
||||
TMS320_FLAG_XXX,
|
||||
TMS320_FLAG_MMM,
|
||||
TMS320_FLAG_Y,
|
||||
TMS320_FLAG_YY,
|
||||
} insn_flag_e;
|
||||
|
||||
struct tms320_instruction {
|
||||
#define i_list_last(x) !(((x)->i_list || (x)->m_list || (x)->f_list || (x)->syntax))
|
||||
insn_item_t * i_list;
|
||||
|
||||
insn_mask_t * m_list;
|
||||
insn_flag_t * f_list;
|
||||
|
||||
char * syntax;
|
||||
};
|
||||
|
||||
struct tms320_instruction_mask {
|
||||
#define m_list_last(x) !(((x)->f || (x)->n || (x)->v))
|
||||
ut8 f, n, v; /* from, number, value */
|
||||
};
|
||||
|
||||
struct tms320_instruction_flag {
|
||||
#define f_list_last(x) !(((x)->f || (x)->v))
|
||||
ut8 f, v; /* from, value */
|
||||
};
|
||||
|
||||
struct tms320_instruction_head {
|
||||
ut8 byte;
|
||||
ut8 size;
|
||||
insn_item_t insn;
|
||||
};
|
||||
|
||||
/*
|
||||
* TMS320 dasm instance
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
insn_head_t * head;
|
||||
insn_item_t * insn;
|
||||
|
||||
union {
|
||||
ut8 opcode;
|
||||
ut8 stream[8];
|
||||
ut64 opcode64;
|
||||
};
|
||||
|
||||
ut8 length;
|
||||
char syntax[1024];
|
||||
|
||||
#define def_field(name, size) \
|
||||
unsigned int bf_##name##_valid:1; \
|
||||
unsigned int bf_##name##_value:size;
|
||||
|
||||
struct {
|
||||
def_field (E, 1);
|
||||
def_field (R, 1);
|
||||
def_field (U, 1);
|
||||
def_field (u, 1);
|
||||
def_field (g, 1);
|
||||
def_field (r, 1);
|
||||
def_field (t, 1);
|
||||
|
||||
def_field (k3, 3);
|
||||
def_field (k4, 4);
|
||||
def_field (k5, 5);
|
||||
def_field (k6, 6);
|
||||
def_field (k8, 8);
|
||||
def_field (k12, 12);
|
||||
def_field (k16, 16);
|
||||
|
||||
def_field (l1, 1);
|
||||
def_field (l3, 3);
|
||||
def_field (l7, 7);
|
||||
def_field (l16, 16);
|
||||
|
||||
def_field (K8, 8);
|
||||
def_field (K16, 16);
|
||||
|
||||
def_field (L7, 7);
|
||||
def_field (L8, 8);
|
||||
def_field (L16, 16);
|
||||
|
||||
def_field (P8, 8);
|
||||
def_field (P24, 24);
|
||||
|
||||
def_field (D16, 16);
|
||||
|
||||
def_field (SHFT, 4);
|
||||
def_field (SHIFTW, 6);
|
||||
|
||||
def_field (ss, 2);
|
||||
def_field (dd, 2);
|
||||
|
||||
def_field (uu, 2);
|
||||
def_field (cc, 2);
|
||||
def_field (mm, 2);
|
||||
def_field (vv, 2);
|
||||
def_field (tt, 2);
|
||||
|
||||
def_field (FSSS, 4);
|
||||
def_field (FDDD, 4);
|
||||
def_field (XSSS, 4);
|
||||
def_field (XDDD, 4);
|
||||
|
||||
def_field (CCCCCCC, 7);
|
||||
def_field (AAAAAAAI, 8);
|
||||
|
||||
def_field (SS, 2);
|
||||
def_field (SS2, 2);
|
||||
def_field (DD, 2);
|
||||
def_field (DD2, 2);
|
||||
|
||||
// aggregates
|
||||
|
||||
def_field (Xmem_mmm, 3);
|
||||
def_field (Xmem_reg, 3);
|
||||
|
||||
def_field (Ymem_mmm, 3);
|
||||
def_field (Ymem_reg, 3);
|
||||
|
||||
} f;
|
||||
|
||||
RHashTable * map;
|
||||
RHashTable * map_e;
|
||||
} tms320_dasm_t;;
|
||||
|
||||
#define field_valid(d, name) \
|
||||
(d)->f.bf_##name##_valid
|
||||
#define field_value(d, name) \
|
||||
(d)->f.bf_##name##_value
|
||||
|
||||
#define set_field_value(d, name, value) \
|
||||
({ \
|
||||
field_valid(d, name) = 1; \
|
||||
field_value(d, name) = value; \
|
||||
})
|
||||
|
||||
#define LIST_END { 0 }
|
||||
|
||||
#define INSN_MASK(af, an, av) { .f = af, .n = an, .v = av }
|
||||
#define INSN_FLAG(af, av) { .f = af, .v = TMS320_FLAG_##av }
|
||||
#define INSN_SYNTAX(arg...) (char *)#arg
|
||||
|
||||
extern int tms320_dasm(tms320_dasm_t *, const ut8 *, int);
|
||||
|
||||
extern int tms320_dasm_init(tms320_dasm_t *);
|
||||
extern int tms320_dasm_fini(tms320_dasm_t *);
|
||||
|
||||
#endif /* __TMS320_DASM_H__ */
|
|
@ -0,0 +1,76 @@
|
|||
#ifndef __TMS320_P_H__
|
||||
#define __TMS320_P_H__
|
||||
|
||||
#ifndef min
|
||||
# define min(a,b) ((a) < (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#ifndef ARRAY_SIZE
|
||||
# define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
||||
#endif
|
||||
|
||||
#ifndef get_bits
|
||||
# define get_bits(av, af, an) (((av) >> (af)) & ((2 << (an - 1)) - 1))
|
||||
#endif
|
||||
|
||||
static inline ut16 le16(ut16 v)
|
||||
{
|
||||
ut16 value = v;
|
||||
#if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__
|
||||
ut8 * pv = (void *)&v;
|
||||
value = (pv[0] << 8) | pv[1];
|
||||
#endif
|
||||
return value;
|
||||
}
|
||||
|
||||
static inline ut32 le24(ut32 v)
|
||||
{
|
||||
ut32 value = v;
|
||||
#if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__
|
||||
ut8 * pv = (void *)&v;
|
||||
value = (pv[0] << 16) | (pv[1] << 8) | pv[2];
|
||||
#endif
|
||||
return value;
|
||||
}
|
||||
|
||||
static inline ut32 le32(ut32 v)
|
||||
{
|
||||
ut32 value = v;
|
||||
#if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__
|
||||
ut8 * pv = (void *)&v;
|
||||
value = (pv[0] << 24) | (pv[1] << 16) | (pv[2] << 8) | pv[3];
|
||||
#endif
|
||||
return value;
|
||||
}
|
||||
|
||||
static inline ut16 be16(ut16 v)
|
||||
{
|
||||
ut16 value = v;
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
ut8 * pv = (void *)&v;
|
||||
value = (pv[0] << 8) | pv[1];
|
||||
#endif
|
||||
return value;
|
||||
}
|
||||
|
||||
static inline ut32 be24(ut32 v)
|
||||
{
|
||||
ut32 value = v;
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
ut8 * pv = (void *)&v;
|
||||
value = (pv[0] << 16) | (pv[1] << 8) | pv[2];
|
||||
#endif
|
||||
return value;
|
||||
}
|
||||
|
||||
static inline ut32 be32(ut32 v)
|
||||
{
|
||||
ut32 value = v;
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
ut8 * pv = (void *)&v;
|
||||
value = (pv[0] << 24) | (pv[1] << 16) | (pv[2] << 8) | pv[3];
|
||||
#endif
|
||||
return value;
|
||||
}
|
||||
|
||||
#endif /* __TMS320_P_H__ */
|
|
@ -13,7 +13,7 @@ ALL_TARGETS=
|
|||
# TODO: rename to enabled plugins
|
||||
ARCHS=mips.mk sparc.mk java.mk bf.mk arm.mk dalvik.mk x86_as.mk x86_nz.mk
|
||||
ARCHS+=ppc.mk x86_olly.mk x86.mk csr.mk x86_nasm.mk psosvm.mk avr.mk
|
||||
ARCHS+=msil.mk sh.mk arm_winedbg.mk c55plus.mk gb.mk snes.mk ebc.mk malbolge.mk ws.mk
|
||||
ARCHS+=msil.mk sh.mk arm_winedbg.mk c55plus.mk tms320.mk gb.mk snes.mk ebc.mk malbolge.mk ws.mk
|
||||
include $(ARCHS)
|
||||
|
||||
all: ${ALL_TARGETS}
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* TMS320 disassembly engine
|
||||
*
|
||||
* Written by Ilya V. Matveychikov <i.matveychikov@milabs.ru>
|
||||
*
|
||||
* Distributed under LGPLv3
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <r_types.h>
|
||||
#include <r_lib.h>
|
||||
#include <r_asm.h>
|
||||
|
||||
#include "../arch/tms320/tms320_dasm.h"
|
||||
|
||||
static tms320_dasm_t engine = { };
|
||||
|
||||
static int tms320_disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
|
||||
int ret = 1;
|
||||
|
||||
ret = tms320_dasm(&engine, buf, len);
|
||||
|
||||
snprintf(op->buf_asm, R_ASM_BUFSIZE, \
|
||||
"%s", ret < 0 ? "invalid" : engine.syntax);
|
||||
|
||||
return (op->size = ret);
|
||||
}
|
||||
|
||||
static int tms320_set_subarch(RAsm *a, const char * name)
|
||||
{
|
||||
if (strcmp(name, "C55X") == 0) {
|
||||
fprintf(stderr, "C55X requested\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tms320_init(void * user)
|
||||
{
|
||||
return tms320_dasm_init(&engine);
|
||||
}
|
||||
|
||||
static int tms320_fini(void * user)
|
||||
{
|
||||
return tms320_dasm_fini(&engine);
|
||||
}
|
||||
|
||||
RAsmPlugin r_asm_plugin_tms320 = {
|
||||
.name = "tms320",
|
||||
.arch = "tms320",
|
||||
.desc = "TMS320 DSP family disassembly plugin",
|
||||
.license = "LGPLv3",
|
||||
.bits = 32|64,
|
||||
.init = tms320_init,
|
||||
.fini = tms320_fini,
|
||||
.disassemble = tms320_disassemble,
|
||||
.set_subarch = tms320_set_subarch,
|
||||
};
|
||||
|
||||
#ifndef CORELIB
|
||||
struct r_lib_struct_t radare_plugin = {
|
||||
.type = R_LIB_TYPE_ASM,
|
||||
.data = &r_asm_plugin_tms320
|
||||
};
|
||||
#endif
|
|
@ -0,0 +1,10 @@
|
|||
OBJ_TMS320=asm_tms320.o
|
||||
OBJ_TMS320+=../arch/tms320/tms320_dasm.o
|
||||
|
||||
STATIC_OBJ+=${OBJ_TMS320}
|
||||
TARGET_TMS320=asm_tms320.${EXT_SO}
|
||||
|
||||
ALL_TARGETS+=${TARGET_TMS320}
|
||||
|
||||
${TARGET_TMS320}: ${OBJ_TMS320}
|
||||
${CC} $(call libname,asm_tms320) ${LDFLAGS} ${CFLAGS} ${OBJ_TMS320}
|
|
@ -182,6 +182,7 @@ extern RAsmPlugin r_asm_plugin_rar;
|
|||
extern RAsmPlugin r_asm_plugin_dcpu16;
|
||||
extern RAsmPlugin r_asm_plugin_8051;
|
||||
extern RAsmPlugin r_asm_plugin_c55plus;
|
||||
extern RAsmPlugin r_asm_plugin_tms320;
|
||||
extern RAsmPlugin r_asm_plugin_gb;
|
||||
extern RAsmPlugin r_asm_plugin_snes;
|
||||
extern RAsmPlugin r_asm_plugin_ebc;
|
||||
|
|
|
@ -30,6 +30,7 @@ asm.i8080
|
|||
asm.8051
|
||||
asm.msil
|
||||
asm.c55plus
|
||||
asm.tms320
|
||||
asm.gb
|
||||
asm.snes
|
||||
asm.ebc
|
||||
|
|
Loading…
Reference in New Issue