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:
Ilya V. Matveychikov 2014-02-04 02:52:13 +04:00 committed by pancake
parent c24543f112
commit 1db5c446a9
11 changed files with 5393 additions and 1 deletions

View File

@ -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

View File

@ -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__ */

View File

@ -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__ */

View File

@ -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}

67
libr/asm/p/asm_tms320.c Normal file
View File

@ -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

10
libr/asm/p/tms320.mk Normal file
View File

@ -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}

View File

@ -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;

View File

@ -30,6 +30,7 @@ asm.i8080
asm.8051
asm.msil
asm.c55plus
asm.tms320
asm.gb
asm.snes
asm.ebc