Rizin
unix-like reverse engineering framework and cli tools
analysis_tms320.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2014 Ilya V. Matveychikov <i.matveychikov@milabs.ru>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 #include <rz_analysis.h>
5 #include "analysis_tms320c64x.c"
6 #include "../../asm/arch/tms320/tms320_dasm.h"
7 
8 typedef int (*TMS_ANALYSIS_OP_FN)(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *buf, int len);
9 
10 int tms320_c54x_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *buf, int len);
11 int tms320_c55x_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *buf, int len);
12 int tms320_c55x_plus_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *buf, int len);
13 
14 static bool match(const char *str, const char *token) {
15  return !strncasecmp(str, token, strlen(token));
16 }
17 
18 int tms320_c54x_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *buf, int len) {
19  // TODO: add the implementation
20  return 0;
21 }
22 
23 int tms320_c55x_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *buf, int len) {
24  tms320_dasm_t *engine = (tms320_dasm_t *)analysis->plugin_data;
25  const char *str = engine->syntax;
26 
27  op->delay = 0;
28  op->size = tms320_dasm(engine, buf, len);
30 
31  str = strstr(str, "||") ? str + 3 : str;
32 
33  if (match(str, "B ")) {
35  if (match(str, "B AC")) {
37  }
38  } else if (match(str, "BCC ") || match(str, "BCCU ")) {
40  } else if (match(str, "CALL ")) {
42  if (match(str, "CALL AC")) {
44  }
45  } else if (match(str, "CALLCC ")) {
47  } else if (match(str, "RET")) {
49  if (match(str, "RETCC")) {
51  }
52  } else if (match(str, "MOV ")) {
54  } else if (match(str, "PSHBOTH ")) {
56  } else if (match(str, "PSH ")) {
58  } else if (match(str, "POPBOTH ") || match(str, "POP ")) {
60  } else if (match(str, "CMP ")) {
62  } else if (match(str, "CMPAND ")) {
64  } else if (match(str, "NOP")) {
66  } else if (match(str, "INTR ")) {
68  } else if (match(str, "TRAP ")) {
70  } else if (match(str, "INVALID")) {
72  }
73 
74  return op->size;
75 }
76 
79 
80  if (analysis->cpu && rz_str_casecmp(analysis->cpu, "c64x") == 0) {
81 #ifdef CAPSTONE_TMS320C64X_H
82  return tms320c64x_analop(analysis, op, addr, buf, len, mask);
83 #else
84  return -1;
85 #endif
86  }
87  if (analysis->cpu && rz_str_casecmp(analysis->cpu, "c54x") == 0) {
88  aop = tms320_c54x_op;
89  } else if (analysis->cpu && rz_str_casecmp(analysis->cpu, "c55x") == 0) {
90  aop = tms320_c55x_op;
91  } else if (analysis->cpu && rz_str_casecmp(analysis->cpu, "c55x+") == 0) {
92  aop = tms320_c55x_plus_op;
93  }
94  return aop(analysis, op, addr, buf, len);
95 }
96 
97 static bool tms320_init(void **user) {
99  if (!engine) {
100  return false;
101  }
102  tms320_dasm_init(engine);
103  *user = engine;
104  return true;
105 }
106 
107 static bool tms320_fini(void *user) {
108  rz_return_val_if_fail(user, false);
109  tms320_dasm_t *engine = (tms320_dasm_t *)user;
110  tms320_dasm_fini(engine);
111  free(engine);
112  return true;
113 }
114 
115 static bool is_c5000(const char *cpu) {
116  if (!cpu) {
117  return false;
118  }
119  return (rz_str_casecmp(cpu, "c55x+") == 0) || (rz_str_casecmp(cpu, "c55x") == 0);
120 }
121 
123  const char *p;
124  if (is_c5000(a->cpu)) {
125  p =
126  "=PC pc\n"
127  "=A0 ar0\n"
128  "=A1 ar1\n"
129  "=A2 ar2\n"
130  "=A3 ar3\n"
131  "=A4 ar4\n"
132  "=R0 ar0\n"
133  "ctr ac0 .40 496 0 # Accumulator 0\n"
134  "ctr ac1 .40 498 0 # Accumulator 1\n"
135  "ctr ac2 .40 500 0 # Accumulator 2\n"
136  "ctr ac3 .40 502 0 # Accumulator 3\n"
137  "gpr ar0 .16 504 0 # Auxiliary registers 0\n"
138  "gpr ar1 .16 505 0 # Auxiliary registers 1\n"
139  "gpr ar2 .16 506 0 # Auxiliary registers 2\n"
140  "gpr ar3 .16 507 0 # Auxiliary registers 3\n"
141  "gpr ar4 .16 508 0 # Auxiliary registers 4\n"
142  "gpr ar5 .16 509 0 # Auxiliary registers 5\n"
143  "gpr ar6 .16 510 0 # Auxiliary registers 6\n"
144  "gpr ar7 .16 511 0 # Auxiliary registers 7\n"
145  "gpr xar0 .23 512 0 # Extended auxiliary registers 0\n"
146  "gpr xar1 .23 513 0 # Extended auxiliary registers 1\n"
147  "gpr xar2 .23 514 0 # Extended auxiliary registers 2\n"
148  "gpr xar3 .23 515 0 # Extended auxiliary registers 3\n"
149  "gpr xar4 .23 516 0 # Extended auxiliary registers 4\n"
150  "gpr xar5 .23 517 0 # Extended auxiliary registers 5\n"
151  "gpr xar6 .23 518 0 # Extended auxiliary registers 6\n"
152  "gpr xar7 .23 519 0 # Extended auxiliary registers 7\n"
153  "ctr bk03 .16 520 0 # Circular buffer size registers\n"
154  "ctr bk47 .16 521 0 # Circular buffer size registers\n"
155  "ctr bkc .16 522 0 # Circular buffer size registers\n"
156  "ctr brc0 .16 523 0 # Block-repeat counters 0\n"
157  "ctr brc1 .16 524 0 # Block-repeat counters 1\n"
158  "ctr brs1 .16 525 0 # BRC1 save register\n"
159  "ctr bsa01 .16 526 0 # Circular buffer start address registers\n"
160  "ctr bsa23 .16 527 0 # Circular buffer start address registers\n"
161  "ctr bsa45 .16 528 0 # Circular buffer start address registers\n"
162  "ctr bsa67 .16 529 0 # Circular buffer start address registers\n"
163  "ctr bsac .16 530 0 # Circular buffer start address registers\n"
164  "ctr cdp .16 531 0 # Coefficient data pointer (low part of XCDP)\n"
165  "ctr cdph .7 532 0 # High part of XCDP\n"
166  "ctr cfct .8 533 0 # Control-flow context register\n"
167  "ctr csr .16 534 0 # Computed single-repeat register\n"
168  "ctr dbier0 .16 535 0 # Debug interrupt enable registers 0\n"
169  "ctr dbier1 .16 536 0 # Debug interrupt enable registers 1\n"
170  "ctr dp .16 537 0 # Data page register (low part of XDP)\n"
171  "ctr dph .7 538 0 # High part of XDP\n"
172  "ctr ier0 .16 539 0 # Interrupt enable registers 0\n"
173  "ctr ier1 .16 540 0 # Interrupt enable registers 1\n"
174  "ctr ifr0 .16 541 0 # Interrupt flag registers 0\n"
175  "ctr ifr1 .16 542 0 # Interrupt flag registers 1\n"
176  "ctr ivpd .16 543 0 # Interrupt vector pointers\n"
177  "ctr ivph .16 544 0 # Interrupt vector pointers\n"
178  "ctr pc .24 545 0 # Program counter\n"
179  "ctr pdp .9 546 0 # Peripheral data page register\n"
180  "ctr rea0 .24 547 0 # Block-repeat end address registers 0\n"
181  "ctr rea1 .24 548 0 # Block-repeat end address registers 1\n"
182  "ctr reta .24 549 0 # Return address register\n"
183  "ctr rptc .16 550 0 # Single-repeat counter\n"
184  "ctr rsa0 .24 551 0 # Block-repeat start address registers 0\n"
185  "ctr rsa1 .24 552 0 # Block-repeat start address registers 1\n"
186  "ctr sp .16 553 0 # Data stack pointer (low part of XSP)\n"
187  "ctr sph .7 554 0 # High part of XSP and XSSP\n"
188  "ctr ssp .16 555 0 # System stack pointer (low part of XSSP)\n"
189  "ctr st0_55 .16 556 0 # Status registers 0\n"
190  "ctr st1_55 .16 557 0 # Status registers 1\n"
191  "ctr st2_55 .16 558 0 # Status registers 2\n"
192  "ctr st3_55 .16 559 0 # Status registers 3\n"
193  "ctr t0 .16 560 0 # Temporary register 0\n"
194  "ctr t1 .16 561 0 # Temporary register 1\n"
195  "ctr t2 .16 562 0 # Temporary register 2\n"
196  "ctr t3 .16 563 0 # Temporary register 3\n"
197  "ctr trn0 .16 564 0 # Transition registers 1\n"
198  "ctr trn1 .16 565 0 # Transition registers 1\n"
199  "ctr xcdp .23 566 0 # Extended coefficient data pointer\n"
200  "ctr xdp .23 567 0 # Extended data page register\n"
201  "ctr xsp .23 568 0 # Extended data stack pointer\n"
202  "ctr xssp .23 569 0 # Extended system stack pointer\n";
203  } else {
204  p =
205  "=PC pc\n"
206  "=A0 a4\n"
207  "=A1 b4\n"
208  "=A2 a6\n"
209  "=A3 a6\n"
210  "=A4 a8\n"
211  "=A5 b8\n"
212  "=A6 a10\n"
213  "=A7 b10\n"
214  "=A8 a12\n"
215  "=A9 b12\n"
216  "=R0 a4\n"
217  "gpr a0 .32 0 0\n"
218  "gpr a1 .32 4 0\n"
219  "gpr a2 .32 8 0\n"
220  "gpr a3 .32 12 0\n"
221  "gpr a4 .32 16 0\n"
222  "gpr a5 .32 20 0\n"
223  "gpr a6 .32 24 0\n"
224  "gpr a7 .32 28 0\n"
225  "gpr a8 .32 32 0\n"
226  "gpr a9 .32 36 0\n"
227  "gpr a10 .32 40 0\n"
228  "gpr a11 .32 44 0\n"
229  "gpr a12 .32 48 0\n"
230  "gpr a13 .32 52 0\n"
231  "gpr a14 .32 56 0\n"
232  "gpr a15 .32 60 0\n"
233 #ifdef CAPSTONE_TMS320C64X_H
234  "gpr a16 .32 64 0\n"
235  "gpr a17 .32 68 0\n"
236  "gpr a18 .32 72 0\n"
237  "gpr a19 .32 76 0\n"
238  "gpr a20 .32 80 0\n"
239  "gpr a21 .32 84 0\n"
240  "gpr a22 .32 88 0\n"
241  "gpr a23 .32 92 0\n"
242  "gpr a24 .32 96 0\n"
243  "gpr a25 .32 100 0\n"
244  "gpr a26 .32 104 0\n"
245  "gpr a27 .32 108 0\n"
246  "gpr a28 .32 112 0\n"
247  "gpr a29 .32 116 0\n"
248  "gpr a30 .32 120 0\n"
249  "gpr a31 .32 124 0\n"
250 #endif
251  "gpr b0 .32 128 0\n"
252  "gpr b1 .32 132 0\n"
253  "gpr b2 .32 136 0\n"
254  "gpr b3 .32 140 0\n"
255  "gpr b4 .32 144 0\n"
256  "gpr b5 .32 148 0\n"
257  "gpr b6 .32 152 0\n"
258  "gpr b7 .32 156 0\n"
259  "gpr b8 .32 160 0\n"
260  "gpr b9 .32 164 0\n"
261  "gpr b10 .32 168 0\n"
262  "gpr b11 .32 172 0\n"
263  "gpr b12 .32 176 0\n"
264  "gpr b13 .32 180 0\n"
265  "gpr b14 .32 184 0\n"
266  "gpr b15 .32 188 0\n"
267 #ifdef CAPSTONE_TMS320C64X_H
268  "gpr b16 .32 192 0\n"
269  "gpr b17 .32 196 0\n"
270  "gpr b18 .32 200 0\n"
271  "gpr b19 .32 204 0\n"
272  "gpr b20 .32 208 0\n"
273  "gpr b21 .32 212 0\n"
274  "gpr b22 .32 216 0\n"
275  "gpr b23 .32 220 0\n"
276  "gpr b24 .32 224 0\n"
277  "gpr b25 .32 228 0\n"
278  "gpr b26 .32 232 0\n"
279  "gpr b27 .32 236 0\n"
280  "gpr b28 .32 240 0\n"
281  "gpr b29 .32 244 0\n"
282  "gpr b30 .32 248 0\n"
283  "gpr b31 .32 252 0\n"
284 #endif
285  "ctr amr .32 256 0 # Addressing mode register\n"
286  "ctr csr .32 260 0 # Control status register\n"
287  "ctr gfpgfr .32 264 0 # Galois field multiply control register\n"
288  "ctr icr .32 268 0 # Interrupt clear register\n"
289  "ctr ier .32 272 0 # Interrupt enable register\n"
290  "ctr ifr .32 276 0 # Interrupt flag register\n"
291  "ctr irp .32 280 0 # Interrupt return pointer register\n"
292  "ctr isr .32 284 0 # Interrupt set register\n"
293  "ctr istp .32 288 0 # Interrupt service table pointer register\n"
294  "ctr nrp .32 292 0 # Nonmaskable interrupt return pointer register\n"
295  "ctr pce1 .32 296 0 # Program counter, E1 phase\n"
296 #ifdef CAPSTONE_TMS320C64X_H
297  // Control Register File Extensions (C64x+ DSP)
298  "ctr dier .32 300 0 # (C64x+ only) Debug interrupt enable register\n"
299  "ctr dnum .32 304 0 # (C64x+ only) DSP core number register\n"
300  "ctr ecr .32 308 0 # (C64x+ only) Exception clear register\n"
301  "ctr efr .32 312 0 # (C64x+ only) Exception flag register\n"
302  "ctr gplya .32 316 0 # (C64x+ only) GMPY A-side polynomial register\n"
303  "ctr gplyb .32 320 0 # (C64x+ only) GMPY B-side polynomial register\n"
304  "ctr ierr .32 324 0 # (C64x+ only) Internal exception report register\n"
305  "ctr ilc .32 328 0 # (C64x+ only) Inner loop count register\n"
306  "ctr itsr .32 332 0 # (C64x+ only) Interrupt task state register\n"
307  "ctr ntsr .32 336 0 # (C64x+ only) NMI/Exception task state register\n"
308  "ctr rep .32 340 0 # (C64x+ only) Restricted entry point address register\n"
309  "ctr rilc .32 344 0 # (C64x+ only) Reload inner loop count register\n"
310  "ctr ssr .32 348 0 # (C64x+ only) Saturation status register\n"
311  "ctr tsch .32 352 0 # (C64x+ only) Time-stamp counter (high 32) register\n"
312  "ctr tscl .32 356 0 # (C64x+ only) Time-stamp counter (low 32) register\n"
313  "ctr tsr .32 360 0 # (C64x+ only) Task state register\n"
314 #endif
315  "gpr a0:a1 .64 364 0\n"
316  "gpr a2:a3 .64 368 0\n"
317  "gpr a4:a5 .64 372 0\n"
318  "gpr a6:a7 .64 376 0\n"
319  "gpr a8:a9 .64 380 0\n"
320  "gpr a10:a11 .64 384 0\n"
321  "gpr a12:a13 .64 388 0\n"
322  "gpr a14:a15 .64 392 0\n"
323 #ifdef CAPSTONE_TMS320C64X_H
324  "gpr a16:a17 .64 396 0\n"
325  "gpr a18:a19 .64 400 0\n"
326  "gpr a20:a21 .64 404 0\n"
327  "gpr a22:a23 .64 408 0\n"
328  "gpr a24:a25 .64 412 0\n"
329  "gpr a26:a27 .64 416 0\n"
330  "gpr a28:a29 .64 420 0\n"
331  "gpr a30:a31 .64 424 0\n"
332 #endif
333  "gpr b0:b1 .64 428 0\n"
334  "gpr b2:b3 .64 432 0\n"
335  "gpr b4:b5 .64 436 0\n"
336  "gpr b6:b7 .64 440 0\n"
337  "gpr b8:b9 .64 444 0\n"
338  "gpr b10:b11 .64 448 0\n"
339  "gpr b12:b13 .64 452 0\n"
340  "gpr b14:b15 .64 456 0\n"
341 #ifdef CAPSTONE_TMS320C64X_H
342  "gpr b16:b17 .64 460 0\n"
343  "gpr b18:b19 .64 464 0\n"
344  "gpr b20:b21 .64 468 0\n"
345  "gpr b22:b23 .64 472 0\n"
346  "gpr b24:b25 .64 476 0\n"
347  "gpr b26:b27 .64 480 0\n"
348  "gpr b28:b29 .64 484 0\n"
349  "gpr b30:b31 .64 488 0\n"
350 #endif
351  ;
352  }
353 
354  return strdup(p);
355 }
356 
358  .name = "tms320",
359  .arch = "tms320",
360  .bits = 32,
361  .desc = "TMS320 DSP family code analysis plugin",
362  .init = tms320_init,
363  .fini = tms320_fini,
364  .license = "LGPLv3",
365  .op = &tms320_op,
366  .get_reg_profile = get_reg_profile,
367 };
368 
369 #ifndef RZ_PLUGIN_INCORE
372  .data = &rz_analysis_plugin_tms320,
374 };
375 #endif
size_t len
Definition: 6502dis.c:15
ut8 op
Definition: 6502dis.c:13
#define mask()
static ut32 cpu[32]
Definition: analysis_or1k.c:21
static bool tms320_fini(void *user)
static char * get_reg_profile(RZ_BORROW RzAnalysis *a)
int tms320_c55x_plus_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *buf, int len)
int tms320_c54x_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *buf, int len)
int tms320_c55x_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *buf, int len)
static bool match(const char *str, const char *token)
static bool tms320_init(void **user)
RZ_API RzLibStruct rizin_plugin
static bool is_c5000(const char *cpu)
int(* TMS_ANALYSIS_OP_FN)(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *buf, int len)
int tms320_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *buf, int len, RzAnalysisOpMask mask)
RzAnalysisPlugin rz_analysis_plugin_tms320
#define RZ_API
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
voidpf void * buf
Definition: ioapi.h:138
uint8_t ut8
Definition: lh5801.h:11
void * p
Definition: libc.cpp:67
return strdup("=SP r13\n" "=LR r14\n" "=PC r15\n" "=A0 r0\n" "=A1 r1\n" "=A2 r2\n" "=A3 r3\n" "=ZF zf\n" "=SF nf\n" "=OF vf\n" "=CF cf\n" "=SN or0\n" "gpr lr .32 56 0\n" "gpr pc .32 60 0\n" "gpr cpsr .32 64 0 ____tfiae_________________qvczn\n" "gpr or0 .32 68 0\n" "gpr tf .1 64.5 0 thumb\n" "gpr ef .1 64.9 0 endian\n" "gpr jf .1 64.24 0 java\n" "gpr qf .1 64.27 0 sticky_overflow\n" "gpr vf .1 64.28 0 overflow\n" "gpr cf .1 64.29 0 carry\n" "gpr zf .1 64.30 0 zero\n" "gpr nf .1 64.31 0 negative\n" "gpr itc .4 64.10 0 if_then_count\n" "gpr gef .4 64.16 0 great_or_equal\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")
RzAnalysisOpMask
Definition: rz_analysis.h:439
@ RZ_ANALYSIS_OP_TYPE_CMP
Definition: rz_analysis.h:399
@ RZ_ANALYSIS_OP_TYPE_UNK
Definition: rz_analysis.h:388
@ RZ_ANALYSIS_OP_TYPE_JMP
Definition: rz_analysis.h:368
@ RZ_ANALYSIS_OP_TYPE_UPUSH
Definition: rz_analysis.h:395
@ RZ_ANALYSIS_OP_TYPE_UJMP
Definition: rz_analysis.h:369
@ RZ_ANALYSIS_OP_TYPE_SWI
Definition: rz_analysis.h:393
@ RZ_ANALYSIS_OP_TYPE_NULL
Definition: rz_analysis.h:367
@ RZ_ANALYSIS_OP_TYPE_TRAP
Definition: rz_analysis.h:392
@ RZ_ANALYSIS_OP_TYPE_CCALL
Definition: rz_analysis.h:383
@ RZ_ANALYSIS_OP_TYPE_CALL
Definition: rz_analysis.h:378
@ RZ_ANALYSIS_OP_TYPE_CRET
Definition: rz_analysis.h:386
@ RZ_ANALYSIS_OP_TYPE_PUSH
Definition: rz_analysis.h:397
@ RZ_ANALYSIS_OP_TYPE_POP
Definition: rz_analysis.h:398
@ RZ_ANALYSIS_OP_TYPE_CJMP
Definition: rz_analysis.h:373
@ RZ_ANALYSIS_OP_TYPE_MOV
Definition: rz_analysis.h:390
@ RZ_ANALYSIS_OP_TYPE_UCALL
Definition: rz_analysis.h:379
@ RZ_ANALYSIS_OP_TYPE_RET
Definition: rz_analysis.h:385
@ RZ_ANALYSIS_OP_TYPE_NOP
Definition: rz_analysis.h:389
@ RZ_ANALYSIS_OP_TYPE_ACMP
Definition: rz_analysis.h:400
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
@ RZ_LIB_TYPE_ANALYSIS
Definition: rz_lib.h:73
RZ_API int rz_str_casecmp(const char *dst, const char *orig)
Definition: str.c:121
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define RZ_BORROW
Definition: rz_types.h:63
#define RZ_VERSION
Definition: rz_version.h:8
static int
Definition: sfsocketcall.h:114
#define a(i)
Definition: sha256.c:41
const char * version
Definition: rz_analysis.h:1239
void * plugin_data
Definition: rz_analysis.h:561
char syntax[1024]
Definition: tms320_dasm.h:127
int tms320_dasm_fini(tms320_dasm_t *dasm)
Definition: tms320_dasm.c:1202
int tms320_dasm_init(tms320_dasm_t *dasm)
Definition: tms320_dasm.c:1181
int tms320_dasm(tms320_dasm_t *dasm, const ut8 *stream, int len)
Definition: tms320_dasm.c:1154
Definition: dis.c:32
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
static int addr
Definition: z80asm.c:58