mirror of
https://github.com/radareorg/radare2.git
synced 2024-12-02 18:27:18 +00:00
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 ;
|
||||
|
2701
libr/asm/arch/tms320/c55x/table.h
Normal file
2701
libr/asm/arch/tms320/c55x/table.h
Normal file
File diff suppressed because it is too large
Load Diff
1275
libr/asm/arch/tms320/c55x/table_e.h
Normal file
1275
libr/asm/arch/tms320/c55x/table_e.h
Normal file
File diff suppressed because it is too large
Load Diff
1035
libr/asm/arch/tms320/tms320_dasm.c
Normal file
1035
libr/asm/arch/tms320/tms320_dasm.c
Normal file
File diff suppressed because it is too large
Load Diff
223
libr/asm/arch/tms320/tms320_dasm.h
Normal file
223
libr/asm/arch/tms320/tms320_dasm.h
Normal 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__ */
|
76
libr/asm/arch/tms320/tms320_p.h
Normal file
76
libr/asm/arch/tms320/tms320_p.h
Normal 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__ */
|
@ -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
67
libr/asm/p/asm_tms320.c
Normal 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
10
libr/asm/p/tms320.mk
Normal 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}
|
@ -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
Block a user