1 /* radare - LGPL - Copyright 2011-2019 - pancake, Roc Valles, condret, killabyte */
2
3 #if 0
4 http://www.atmel.com/images/atmel-0856-avr-instruction-set-manual.pdf
5 https://en.wikipedia.org/wiki/Atmel_AVR_instruction_set
6 #endif
7
8 #include <string.h>
9 #include <r_types.h>
10 #include <r_util.h>
11 #include <r_crypto.h>
12 #include <r_lib.h>
13 #include <r_asm.h>
14 #include <r_anal.h>
15
16 #include "../../asm/arch/avr/disasm.h"
17
18 static RDESContext desctx;
19
20 typedef struct _cpu_const_tag {
21 const char *const key;
22 ut8 type;
23 ut32 value;
24 ut8 size;
25 } CPU_CONST;
26
27 #define CPU_CONST_NONE 0
28 #define CPU_CONST_PARAM 1
29 #define CPU_CONST_REG 2
30
31 typedef struct _cpu_model_tag {
32 const char *const model;
33 int pc;
34 char *inherit;
35 struct _cpu_model_tag *inherit_cpu_p;
36 CPU_CONST *consts[10];
37 } CPU_MODEL;
38
39 typedef void (*inst_handler_t) (RAnal *anal, RAnalOp *op, const ut8 *buf, int len, int *fail, CPU_MODEL *cpu);
40
41 typedef struct _opcodes_tag_ {
42 const char *const name;
43 int mask;
44 int selector;
45 inst_handler_t handler;
46 int cycles;
47 int size;
48 ut64 type;
49 } OPCODE_DESC;
50
51 static OPCODE_DESC* avr_op_analyze(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *buf, int len, CPU_MODEL *cpu);
52
53 #define CPU_MODEL_DECL(model, pc, consts) \
54 { \
55 model, \
56 pc, \
57 consts \
58 }
59 #define MASK(bits) ((bits) == 32 ? 0xffffffff : (~((~((ut32) 0)) << (bits))))
60 #define CPU_PC_MASK(cpu) MASK((cpu)->pc)
61 #define CPU_PC_SIZE(cpu) ((((cpu)->pc) >> 3) + ((((cpu)->pc) & 0x07) ? 1 : 0))
62
63 #define INST_HANDLER(OPCODE_NAME) static void _inst__ ## OPCODE_NAME (RAnal *anal, RAnalOp *op, const ut8 *buf, int len, int *fail, CPU_MODEL *cpu)
64 #define INST_DECL(OP, M, SL, C, SZ, T) { #OP, (M), (SL), _inst__ ## OP, (C), (SZ), R_ANAL_OP_TYPE_ ## T }
65 #define INST_LAST { "unknown", 0, 0, (void *) 0, 2, 1, R_ANAL_OP_TYPE_UNK }
66
67 #define INST_CALL(OPCODE_NAME) _inst__ ## OPCODE_NAME (anal, op, buf, len, fail, cpu)
68 #define INST_INVALID { *fail = 1; return; }
69 #define INST_ASSERT(x) { if (!(x)) { INST_INVALID; } }
70
71 #define ESIL_A(e, ...) r_strbuf_appendf (&op->esil, e, ##__VA_ARGS__)
72
73 #define STR_BEGINS(in, s) r_str_ncasecmp (in, s, strlen (s))
74
75 // Following IO definitions are valid for:
76 // ATmega8
77 // ATmega88
78 CPU_CONST cpu_reg_common[] = {
79 { "spl", CPU_CONST_REG, 0x3d, sizeof (ut8) },
80 { "sph", CPU_CONST_REG, 0x3e, sizeof (ut8) },
81 { "sreg", CPU_CONST_REG, 0x3f, sizeof (ut8) },
82 { "spmcsr", CPU_CONST_REG, 0x37, sizeof (ut8) },
83 { NULL, 0, 0, 0 },
84 };
85
86 CPU_CONST cpu_memsize_common[] = {
87 { "eeprom_size", CPU_CONST_PARAM, 512, sizeof (ut32) },
88 { "io_size", CPU_CONST_PARAM, 0x40, sizeof (ut32) },
89 { "sram_start", CPU_CONST_PARAM, 0x60, sizeof (ut32) },
90 { "sram_size", CPU_CONST_PARAM, 1024, sizeof (ut32) },
91 { NULL, 0, 0, 0 },
92 };
93
94 CPU_CONST cpu_memsize_m640_m1280m_m1281_m2560_m2561[] = {
95 { "eeprom_size", CPU_CONST_PARAM, 512, sizeof (ut32) },
96 { "io_size", CPU_CONST_PARAM, 0x1ff, sizeof (ut32) },
97 { "sram_start", CPU_CONST_PARAM, 0x200, sizeof (ut32) },
98 { "sram_size", CPU_CONST_PARAM, 0x2000, sizeof (ut32) },
99 { NULL, 0, 0, 0 },
100 };
101
102 CPU_CONST cpu_memsize_xmega128a4u[] = {
103 { "eeprom_size", CPU_CONST_PARAM, 0x800, sizeof (ut32) },
104 { "io_size", CPU_CONST_PARAM, 0x1000, sizeof (ut32) },
105 { "sram_start", CPU_CONST_PARAM, 0x800, sizeof (ut32) },
106 { "sram_size", CPU_CONST_PARAM, 0x2000, sizeof (ut32) },
107 { NULL, 0, 0, 0 },
108 };
109
110 CPU_CONST cpu_pagesize_5_bits[] = {
111 { "page_size", CPU_CONST_PARAM, 5, sizeof (ut8) },
112 { NULL, 0, 0, 0 },
113 };
114
115 CPU_CONST cpu_pagesize_7_bits[] = {
116 { "page_size", CPU_CONST_PARAM, 7, sizeof (ut8) },
117 { NULL, 0, 0, 0 },
118 };
119
120 CPU_MODEL cpu_models[] = {
121 { .model = "ATmega640", .pc = 15,
122 .consts = {
123 cpu_reg_common,
124 cpu_memsize_m640_m1280m_m1281_m2560_m2561,
125 cpu_pagesize_7_bits,
126 NULL
127 },
128 },
129 {
130 .model = "ATxmega128a4u", .pc = 17,
131 .consts = {
132 cpu_reg_common,
133 cpu_memsize_xmega128a4u,
134 cpu_pagesize_7_bits,
135 NULL
136 }
137 },
138 { .model = "ATmega1280", .pc = 16, .inherit = "ATmega640" },
139 { .model = "ATmega1281", .pc = 16, .inherit = "ATmega640" },
140 { .model = "ATmega2560", .pc = 17, .inherit = "ATmega640" },
141 { .model = "ATmega2561", .pc = 17, .inherit = "ATmega640" },
142 { .model = "ATmega88", .pc = 8, .inherit = "ATmega8" },
143 // CPU_MODEL_DECL ("ATmega168", 13, 512, 512),
144 // last model is the default AVR - ATmega8 forever!
145 {
146 .model = "ATmega8", .pc = 13,
147 .consts = {
148 cpu_reg_common,
149 cpu_memsize_common,
150 cpu_pagesize_5_bits,
151 NULL
152 }
153 },
154 };
155
156 static CPU_MODEL *get_cpu_model(char *model);
157
__get_cpu_model_recursive(char * model)158 static CPU_MODEL *__get_cpu_model_recursive(char *model) {
159 CPU_MODEL *cpu = NULL;
160
161 for (cpu = cpu_models; cpu < cpu_models + ((sizeof (cpu_models) / sizeof (CPU_MODEL))) - 1; cpu++) {
162 if (!r_str_casecmp (model, cpu->model)) {
163 break;
164 }
165 }
166
167 // fix inheritance tree
168 if (cpu->inherit && !cpu->inherit_cpu_p) {
169 cpu->inherit_cpu_p = get_cpu_model (cpu->inherit);
170 if (!cpu->inherit_cpu_p) {
171 eprintf ("ERROR: Cannot inherit from unknown CPU model '%s'.\n", cpu->inherit);
172 }
173 }
174
175 return cpu;
176 }
177
get_cpu_model(char * model)178 static CPU_MODEL *get_cpu_model(char *model) {
179 static CPU_MODEL *cpu = NULL;
180 // cached value?
181 if (cpu && !r_str_casecmp (model, cpu->model)) {
182 return cpu;
183 }
184 // do the real search
185 cpu = __get_cpu_model_recursive (model);
186 return cpu;
187 }
188
const_get_value(CPU_CONST * c)189 static ut32 const_get_value(CPU_CONST *c) {
190 return c ? MASK (c->size * 8) & c->value : 0;
191 }
192
193
const_by_name(CPU_MODEL * cpu,int type,char * c)194 static CPU_CONST *const_by_name(CPU_MODEL *cpu, int type, char *c) {
195 CPU_CONST **clist, *citem;
196
197 for (clist = cpu->consts; *clist; clist++) {
198 for (citem = *clist; citem->key; citem++) {
199 if (!strcmp (c, citem->key)
200 && (type == CPU_CONST_NONE || type == citem->type)) {
201 return citem;
202 }
203 }
204 }
205 if (cpu->inherit_cpu_p) {
206 return const_by_name (cpu->inherit_cpu_p, type, c);
207 }
208 eprintf ("ERROR: CONSTANT key[%s] NOT FOUND.\n", c);
209 return NULL;
210 }
211
__esil_pop_argument(RAnalEsil * esil,ut64 * v)212 static int __esil_pop_argument(RAnalEsil *esil, ut64 *v) {
213 char *t = r_anal_esil_pop (esil);
214 if (!t || !r_anal_esil_get_parm (esil, t, v)) {
215 free (t);
216 return false;
217 }
218 free (t);
219 return true;
220 }
221
const_by_value(CPU_MODEL * cpu,int type,ut32 v)222 static CPU_CONST *const_by_value(CPU_MODEL *cpu, int type, ut32 v) {
223 CPU_CONST **clist, *citem;
224
225 for (clist = cpu->consts; *clist; clist++) {
226 for (citem = *clist; citem && citem->key; citem++) {
227 if (citem->value == (MASK (citem->size * 8) & v)
228 && (type == CPU_CONST_NONE || type == citem->type)) {
229 return citem;
230 }
231 }
232 }
233 if (cpu->inherit_cpu_p) {
234 return const_by_value (cpu->inherit_cpu_p, type, v);
235 }
236 return NULL;
237 }
238
__generic_io_dest(ut8 port,int write,CPU_MODEL * cpu)239 static RStrBuf *__generic_io_dest(ut8 port, int write, CPU_MODEL *cpu) {
240 RStrBuf *r = r_strbuf_new ("");
241 CPU_CONST *c = const_by_value (cpu, CPU_CONST_REG, port);
242 if (c != NULL) {
243 r_strbuf_set (r, c->key);
244 if (write) {
245 r_strbuf_append (r, ",=");
246 }
247 } else {
248 r_strbuf_setf (r, "_io,%d,+,%s[1]", port, write ? "=" : "");
249 }
250
251 return r;
252 }
253
__generic_ld_st(RAnalOp * op,char * mem,char ireg,int use_ramp,int prepostdec,int offset,int st)254 static void __generic_ld_st(RAnalOp *op, char *mem, char ireg, int use_ramp, int prepostdec, int offset, int st) {
255 if (ireg) {
256 // preincrement index register
257 if (prepostdec < 0) {
258 ESIL_A ("1,%c,-,%c,=,", ireg, ireg);
259 }
260 // set register index address
261 ESIL_A ("%c,", ireg);
262 // add offset
263 if (offset != 0) {
264 ESIL_A ("%d,+,", offset);
265 }
266 } else {
267 ESIL_A ("%d,", offset);
268 }
269 if (use_ramp) {
270 ESIL_A ("16,ramp%c,<<,+,", ireg ? ireg : 'd');
271 }
272 // set SRAM base address
273 ESIL_A ("_%s,+,", mem);
274 // read/write from SRAM
275 ESIL_A ("%s[1],", st ? "=" : "");
276 // postincrement index register
277 if (ireg && prepostdec > 0) {
278 ESIL_A ("1,%c,+,%c,=,", ireg, ireg);
279 }
280 }
281
__generic_pop(RAnalOp * op,int sz)282 static void __generic_pop(RAnalOp *op, int sz) {
283 if (sz > 1) {
284 ESIL_A ("1,sp,+,_ram,+,"); // calc SRAM(sp+1)
285 ESIL_A ("[%d],", sz); // read value
286 ESIL_A ("%d,sp,+=,", sz); // sp += item_size
287 } else {
288 ESIL_A ("1,sp,+=," // increment stack pointer
289 "sp,_ram,+,[1],"); // load SRAM[sp]
290 }
291 }
292
__generic_push(RAnalOp * op,int sz)293 static void __generic_push(RAnalOp *op, int sz) {
294 ESIL_A ("sp,_ram,+,"); // calc pointer SRAM(sp)
295 if (sz > 1) {
296 ESIL_A ("-%d,+,", sz - 1); // dec SP by 'sz'
297 }
298 ESIL_A ("=[%d],", sz); // store value in stack
299 ESIL_A ("-%d,sp,+=,", sz); // decrement stack pointer
300 }
301
INST_HANDLER(adc)302 INST_HANDLER (adc) { // ADC Rd, Rr
303 // ROL Rd
304 if (len < 2) {
305 return;
306 }
307 const ut32 d = ((buf[0] >> 4) & 0xf) | ((buf[1] & 1) << 4);
308 const ut32 r = (buf[0] & 0xf) | ((buf[1] & 2) << 3);
309 ESIL_A ("r%d,cf,+,r%d,+=,", r, d); // Rd + Rr + C
310 ESIL_A ("$z,zf,:=,");
311 ESIL_A ("3,$c,hf,:=,");
312 ESIL_A ("7,$c,cf,:=,");
313 ESIL_A ("7,$o,vf,:=,");
314 ESIL_A ("0x80,r%d,&,!,!,nf,:=", d);
315 }
316
INST_HANDLER(add)317 INST_HANDLER (add) { // ADD Rd, Rr
318 // LSL Rd
319 if (len < 2) {
320 return;
321 }
322 const ut32 d = ((buf[0] >> 4) & 0xf) | ((buf[1] & 1) << 4);
323 const ut32 r = (buf[0] & 0xf) | ((buf[1] & 2) << 3);
324 ESIL_A ("r%d,r%d,+=,", r, d); // Rd + Rr
325 ESIL_A ("$z,zf,:=,");
326 ESIL_A ("3,$c,hf,:=,");
327 ESIL_A ("7,$c,cf,:=,");
328 ESIL_A ("7,$o,vf,:=,");
329 ESIL_A ("0x80,r%d,&,!,!,nf,:=,", d);
330 }
331
INST_HANDLER(adiw)332 INST_HANDLER (adiw) { // ADIW Rd+1:Rd, K
333 if (len < 1) {
334 return;
335 }
336 const ut32 d = ((buf[0] & 0x30) >> 3) + 24;
337 const ut32 k = (buf[0] & 0x0f) | ((buf[0] >> 2) & 0x30);
338 op->val = k;
339 ESIL_A ("%d,r%d_r%d,+=,", k, d + 1, d); // Rd+1_Rd + k
340 // FLAGS:
341 ESIL_A ("7,$o,vf,:=,"); // V
342 ESIL_A ("r%d_r%d,0x8000,&,!,!,nf,:=,", d + 1, d); // N
343 ESIL_A ("$z,zf,:=,"); // Z
344 ESIL_A ("15,$c,cf,:=,"); // C
345 ESIL_A ("vf,nf,^,sf,:="); // S
346 }
347
INST_HANDLER(and)348 INST_HANDLER (and) { // AND Rd, Rr
349 // TST Rd
350 if (len < 2) {
351 return;
352 }
353 const ut32 d = ((buf[0] >> 4) & 0xf) | ((buf[1] & 1) << 4);
354 const ut32 r = (buf[0] & 0xf) | ((buf[1] & 2) << 3);
355 ESIL_A ("r%d,r%d,&=,$z,zf,:=,r%d,0x80,&,!,!,nf,:=,0,vf,:=,nf,sf,:=,", r, d, d);
356 }
357
INST_HANDLER(andi)358 INST_HANDLER (andi) { // ANDI Rd, K
359 // CBR Rd, K (= ANDI Rd, 1-K)
360 if (len < 2) {
361 return;
362 }
363 const ut32 d = ((buf[0] >> 4) & 0xf) + 16;
364 const ut32 k = ((buf[1] & 0x0f) << 4) | (buf[0] & 0x0f);
365 op->val = k;
366 ESIL_A ("%d,r%d,&=,$z,zf,:=,r%d,0x80,&,!,!,nf,:=,0,vf,:=,nf,sf,:=,", k, d, d);
367 }
368
INST_HANDLER(asr)369 INST_HANDLER (asr) { // ASR Rd
370 if (len < 2) {
371 return;
372 }
373 int d = ((buf[0] >> 4) & 0xf) | ((buf[1] & 1) << 4);
374 ESIL_A ("r%d,0x1,&,cf,:=,0x1,r%d,>>,r%d,0x80,&,|,", d, d, d);
375 // 0: R=(Rd >> 1) | Rd7
376 ESIL_A ("$z,zf,:=,"); // Z
377 ESIL_A ("r%d,0x80,&,!,!,nf,:=,", d); // N
378 ESIL_A ("nf,cf,^,vf,:=,"); // V
379 ESIL_A ("nf,vf,^,sf,:=,"); // S
380 }
381
INST_HANDLER(bclr)382 INST_HANDLER (bclr) { // BCLR s
383 // CLC
384 // CLH
385 // CLI
386 // CLN
387 // CLR
388 // CLS
389 // CLT
390 // CLV
391 // CLZ
392 if (len < 1) {
393 return;
394 }
395 int s = (buf[0] >> 4) & 0x7;
396 ESIL_A ("0xff,%d,1,<<,^,sreg,&=,", s);
397 }
398
INST_HANDLER(bld)399 INST_HANDLER (bld) { // BLD Rd, b
400 if (len < 2) {
401 return;
402 }
403 int d = ((buf[1] & 0x01) << 4) | ((buf[0] >> 4) & 0xf);
404 int b = buf[0] & 0x7;
405 ESIL_A ("r%d,%d,1,<<,0xff,^,&,", d, b); // Rd/b = 0
406 ESIL_A ("%d,tf,<<,|,r%d,=,", b, d); // Rd/b |= T<<b
407 }
408
INST_HANDLER(brbx)409 INST_HANDLER (brbx) { // BRBC s, k
410 // BRBS s, k
411 // BRBC/S 0: BRCC BRCS
412 // BRSH BRLO
413 // BRBC/S 1: BREQ BRNE
414 // BRBC/S 2: BRPL BRMI
415 // BRBC/S 3: BRVC BRVS
416 // BRBC/S 4: BRGE BRLT
417 // BRBC/S 5: BRHC BRHS
418 // BRBC/S 6: BRTC BRTS
419 // BRBC/S 7: BRID BRIE
420 if (len < 2) {
421 return;
422 }
423 int s = buf[0] & 0x7;
424 op->jump = op->addr
425 + ((((buf[1] & 0x03) << 6) | ((buf[0] & 0xf8) >> 2))
426 | (buf[1] & 0x2 ? ~((int) 0x7f) : 0))
427 + 2;
428 op->fail = op->addr + op->size;
429 op->cycles = 1; // XXX: This is a bug, because depends on eval state,
430 // so it cannot be really be known until this
431 // instruction is executed by the ESIL interpreter!!!
432 // In case of evaluating to true, this instruction
433 // needs 2 cycles, elsewhere it needs only 1 cycle.
434 ESIL_A ("%d,1,<<,sreg,&,", s); // SREG(s)
435 ESIL_A (buf[1] & 0x4
436 ? "!," // BRBC => branch if cleared
437 : "!,!,"); // BRBS => branch if set
438 ESIL_A ("?{,%"PFMT64d",pc,=,},", op->jump); // ?true => jmp
439 }
440
INST_HANDLER(break)441 INST_HANDLER (break) { // BREAK
442 ESIL_A ("BREAK");
443 }
444
INST_HANDLER(bset)445 INST_HANDLER (bset) { // BSET s
446 // SEC
447 // SEH
448 // SEI
449 // SEN
450 // SER
451 // SES
452 // SET
453 // SEV
454 // SEZ
455 if (len < 1) {
456 return;
457 }
458 int s = (buf[0] >> 4) & 0x7;
459 ESIL_A ("%d,1,<<,sreg,|=,", s);
460 }
461
INST_HANDLER(bst)462 INST_HANDLER (bst) { // BST Rd, b
463 if (len < 2) {
464 return;
465 }
466 ESIL_A ("r%d,%d,1,<<,&,!,!,tf,=,", // tf = Rd/b
467 ((buf[1] & 1) << 4) | ((buf[0] >> 4) & 0xf), // r
468 buf[0] & 0x7); // b
469 }
470
INST_HANDLER(call)471 INST_HANDLER (call) { // CALL k
472 if (len < 4) {
473 return;
474 }
475 op->jump = (buf[2] << 1)
476 | (buf[3] << 9)
477 | (buf[1] & 0x01) << 23
478 | (buf[0] & 0x01) << 17
479 | (buf[0] & 0xf0) << 14;
480 op->fail = op->addr + op->size;
481 op->cycles = cpu->pc <= 16 ? 3 : 4;
482 if (!STR_BEGINS (cpu->model, "ATxmega")) {
483 op->cycles--; // AT*mega optimizes one cycle
484 }
485 ESIL_A ("pc,"); // esil is already pointing to
486 // next instruction (@ret)
487 __generic_push (op, CPU_PC_SIZE (cpu)); // push @ret in stack
488 ESIL_A ("%"PFMT64d",pc,=,", op->jump); // jump!
489 }
490
INST_HANDLER(cbi)491 INST_HANDLER (cbi) { // CBI A, b
492 if (len < 1) {
493 return;
494 }
495 int a = (buf[0] >> 3) & 0x1f;
496 int b = buf[0] & 0x07;
497 RStrBuf *io_port;
498
499 op->family = R_ANAL_OP_FAMILY_IO;
500 op->type2 = 1;
501 op->val = a;
502
503 // read port a and clear bit b
504 io_port = __generic_io_dest (a, 0, cpu);
505 ESIL_A ("0xff,%d,1,<<,^,%s,&,", b, r_strbuf_get (io_port));
506 r_strbuf_free (io_port);
507
508 // write result to port a
509 io_port = __generic_io_dest (a, 1, cpu);
510 ESIL_A ("%s,", r_strbuf_get (io_port));
511 r_strbuf_free (io_port);
512 }
513
INST_HANDLER(com)514 INST_HANDLER (com) { // COM Rd
515 if (len < 2) {
516 return;
517 }
518 int r = ((buf[0] >> 4) & 0x0f) | ((buf[1] & 1) << 4);
519
520 ESIL_A ("r%d,0xff,-,r%d,=,$z,zf,:=,0,cf,:=,0,vf,:=,r%d,0x80,&,!,!,nf,:=,vf,nf,^,sf,:=", r, r, r);
521 // Rd = 0xFF-Rd
522 }
523
INST_HANDLER(cp)524 INST_HANDLER (cp) { // CP Rd, Rr
525 if (len < 2) {
526 return;
527 }
528 const ut32 r = (buf[0] & 0x0f) | ((buf[1] << 3) & 0x10);
529 const ut32 d = ((buf[0] >> 4) & 0x0f) | ((buf[1] << 4) & 0x10);
530 ESIL_A ("r%d,r%d,-,0x80,&,!,!,nf,:=,", r, d);
531 ESIL_A ("r%d,r%d,==,", r, d);
532 ESIL_A ("$z,zf,:=,");
533 ESIL_A ("3,$b,hf,:=,");
534 ESIL_A ("8,$b,cf,:=,");
535 ESIL_A ("7,$o,vf,:=,");
536 ESIL_A ("vf,nf,^,sf,:=");
537 }
538
INST_HANDLER(cpc)539 INST_HANDLER (cpc) { // CPC Rd, Rr
540 if (len < 2) {
541 return;
542 }
543 const ut32 r = (buf[0] & 0x0f) | ((buf[1] << 3) & 0x10);
544 const ut32 d = ((buf[0] >> 4) & 0x0f) | ((buf[1] << 4) & 0x10);
545
546 ESIL_A ("cf,r%d,+,DUP,r%d,-,0x80,&,!,!,nf,:=,", r, d); // Rd - Rr - C
547 ESIL_A ("r%d,==,", d);
548 ESIL_A ("$z,zf,:=,");
549 ESIL_A ("3,$b,hf,:=,");
550 ESIL_A ("8,$b,cf,:=,");
551 ESIL_A ("7,$o,vf,:=,");
552 ESIL_A ("vf,nf,^,sf,:=");
553 }
554
INST_HANDLER(cpi)555 INST_HANDLER (cpi) { // CPI Rd, K
556 if (len < 2) {
557 return;
558 }
559 const ut32 d = ((buf[0] >> 4) & 0xf) + 16;
560 const ut32 k = (buf[0] & 0xf) | ((buf[1] & 0xf) << 4);
561 ESIL_A ("%d,r%d,-,0x80,&,!,!,nf,:=,", k, d); // Rd - k
562 ESIL_A ("%d,r%d,==,", k, d);
563 ESIL_A ("$z,zf,:=,");
564 ESIL_A ("3,$b,hf,:=,");
565 ESIL_A ("8,$b,cf,:=,");
566 ESIL_A ("7,$o,vf,:=,");
567 ESIL_A ("vf,nf,^,sf,:=");
568 }
569
INST_HANDLER(cpse)570 INST_HANDLER (cpse) { // CPSE Rd, Rr
571 if (len < 2) {
572 return;
573 }
574 int r = (buf[0] & 0xf) | ((buf[1] & 0x2) << 3);
575 int d = ((buf[0] >> 4) & 0xf) | ((buf[1] & 0x1) << 4);
576 RAnalOp next_op = {0};
577
578 // calculate next instruction size (call recursively avr_op_analyze)
579 // and free next_op's esil string (we dont need it now)
580 avr_op_analyze (anal,
581 &next_op,
582 op->addr + op->size, buf + op->size, len - op->size,
583 cpu);
584 r_strbuf_fini (&next_op.esil);
585 op->jump = op->addr + next_op.size + 2;
586 op->fail = op->addr + 2;
587
588 // cycles
589 op->cycles = 1; // XXX: This is a bug, because depends on eval state,
590 // so it cannot be really be known until this
591 // instruction is executed by the ESIL interpreter!!!
592 // In case of evaluating to true, this instruction
593 // needs 2/3 cycles, elsewhere it needs only 1 cycle.
594 ESIL_A ("r%d,r%d,^,!,", r, d); // Rr == Rd
595 ESIL_A ("?{,%"PFMT64d",pc,=,},", op->jump); // ?true => jmp
596 }
597
INST_HANDLER(dec)598 INST_HANDLER (dec) { // DEC Rd
599 if (len < 2) {
600 return;
601 }
602 const ut32 d = ((buf[0] >> 4) & 0xf) | ((buf[1] & 0x1) << 4);
603 ESIL_A ("0x1,r%d,-=,", d); // Rd--
604 // FLAGS:
605 ESIL_A ("7,$o,vf,:=,"); // V
606 ESIL_A ("r%d,0x80,&,!,!,nf,:=,", d); // N
607 ESIL_A ("$z,zf,:=,"); // Z
608 ESIL_A ("vf,nf,^,sf,:=,"); // S
609 }
610
INST_HANDLER(des)611 INST_HANDLER (des) { // DES k
612 if (desctx.round < 16) { //DES
613 op->type = R_ANAL_OP_TYPE_CRYPTO;
614 op->cycles = 1; //redo this
615 r_strbuf_setf (&op->esil, "%d,des", desctx.round);
616 }
617 }
618
INST_HANDLER(eijmp)619 INST_HANDLER (eijmp) { // EIJMP
620 ut64 z, eind;
621 // read z and eind for calculating jump address on runtime
622 r_anal_esil_reg_read (anal->esil, "z", &z, NULL);
623 r_anal_esil_reg_read (anal->esil, "eind", &eind, NULL);
624 // real target address may change during execution, so this value will
625 // be changing all the time
626 op->jump = ((eind << 16) + z) << 1;
627 // jump
628 ESIL_A ("1,z,16,eind,<<,+,<<,pc,=,");
629 // cycles
630 op->cycles = 2;
631 }
632
INST_HANDLER(eicall)633 INST_HANDLER (eicall) { // EICALL
634 // push pc in stack
635 ESIL_A ("pc,"); // esil is already pointing to
636 // next instruction (@ret)
637 __generic_push (op, CPU_PC_SIZE (cpu)); // push @ret in stack
638 // do a standard EIJMP
639 INST_CALL (eijmp);
640 // fix cycles
641 op->cycles = !STR_BEGINS (cpu->model, "ATxmega") ? 3 : 4;
642 }
643
INST_HANDLER(elpm)644 INST_HANDLER (elpm) { // ELPM
645 // ELPM Rd
646 // ELPM Rd, Z+
647 if (len < 2) {
648 return;
649 }
650 int d = ((buf[1] & 0xfe) == 0x90)
651 ? ((buf[1] & 1) << 4) | ((buf[0] >> 4) & 0xf) // Rd
652 : 0; // R0
653 ESIL_A ("16,rampz,<<,z,+,_prog,+,[1],"); // read RAMPZ:Z
654 ESIL_A ("r%d,=,", d); // Rd = [1]
655 if ((buf[1] & 0xfe) == 0x90 && (buf[0] & 0xf) == 0x7) {
656 ESIL_A ("16,1,z,+,DUP,z,=,>>,1,&,rampz,+=,"); // ++(rampz:z)
657 }
658 }
659
INST_HANDLER(eor)660 INST_HANDLER (eor) { // EOR Rd, Rr
661 // CLR Rd
662 if (len < 2) {
663 return;
664 }
665 const ut32 d = ((buf[0] >> 4) & 0xf) | ((buf[1] & 1) << 4);
666 const ut32 r = (buf[0] & 0xf) | ((buf[1] & 2) << 3);
667 ESIL_A ("r%d,r%d,^=,$z,zf,:=,0,vf,:=,r%d,0x80,&,!,!,nf,:=,nf,sf,:=", r, d, d);
668 // 0: Rd ^= Rr
669 }
670
INST_HANDLER(fmul)671 INST_HANDLER (fmul) { // FMUL Rd, Rr
672 if (len < 1) {
673 return;
674 }
675 const ut32 d = ((buf[0] >> 4) & 0x7) + 16;
676 const ut32 r = (buf[0] & 0x7) + 16;
677
678 ESIL_A ("0xffff,1,r%d,r%d,*,<<,&,r1_r0,=,", r, d); // 0: r1_r0 = (rd * rr) << 1
679 ESIL_A ("r1_r0,0x8000,&,!,!,cf,:=,"); // C = R/15
680 ESIL_A ("$z,zf,:="); // Z = !R
681
682 }
683
INST_HANDLER(fmuls)684 INST_HANDLER (fmuls) { // FMULS Rd, Rr
685 if (len < 1) {
686 return;
687 }
688 const ut32 d = ((buf[0] >> 4) & 0x7) + 16;
689 const ut32 r = (buf[0] & 0x7) + 16;
690
691 ESIL_A ("1,");
692 ESIL_A ("r%d,DUP,0x80,&,?{,0xff00,|,},", d); // sign extension Rd
693 ESIL_A ("r%d,DUP,0x80,&,?{,0xff00,|,},", r); // sign extension Rr
694 ESIL_A ("*,<<,r1_r0,=,"); // 0: (Rd*Rr)<<1
695
696 ESIL_A ("r1_r0,0x8000,&,!,!,cf,:=,"); // C = R/16
697 ESIL_A ("$z,zf,:="); // Z = !R
698 }
699
INST_HANDLER(fmulsu)700 INST_HANDLER (fmulsu) { // FMULSU Rd, Rr
701 if (len < 1) {
702 return;
703 }
704 const ut32 d = ((buf[0] >> 4) & 0x7) + 16;
705 const ut32 r = (buf[0] & 0x7) + 16;
706
707 ESIL_A ("1,");
708 ESIL_A ("r%d,DUP,0x80,&,?{,0xff00,|,},", d); // sign extension Rd
709 ESIL_A ("r%d,*,<<,r1_r0,=,", r); // 0: (Rd*Rr)<<1
710
711 ESIL_A ("r1_r0,0x8000,&,!,!,cf,:=,"); // C = R/16
712 ESIL_A ("$z,zf,:="); // Z = !R
713 }
714
INST_HANDLER(ijmp)715 INST_HANDLER (ijmp) { // IJMP k
716 ut64 z;
717 // read z for calculating jump address on runtime
718 r_anal_esil_reg_read (anal->esil, "z", &z, NULL);
719 // real target address may change during execution, so this value will
720 // be changing all the time
721 op->jump = z << 1;
722 op->cycles = 2;
723 ESIL_A ("1,z,<<,pc,=,"); // jump!
724 }
725
INST_HANDLER(icall)726 INST_HANDLER (icall) { // ICALL k
727 // push pc in stack
728 ESIL_A ("pc,"); // esil is already pointing to
729 // next instruction (@ret)
730 __generic_push (op, CPU_PC_SIZE (cpu)); // push @ret in stack
731 // do a standard IJMP
732 INST_CALL (ijmp);
733 // fix cycles
734 if (!STR_BEGINS (cpu->model, "ATxmega")) {
735 // AT*mega optimizes 1 cycle!
736 op->cycles--;
737 }
738 }
739
INST_HANDLER(in)740 INST_HANDLER (in) { // IN Rd, A
741 if (len < 2) {
742 return;
743 }
744 int r = ((buf[0] >> 4) & 0x0f) | ((buf[1] & 0x01) << 4);
745 int a = (buf[0] & 0x0f) | ((buf[1] & 0x6) << 3);
746 RStrBuf *io_src = __generic_io_dest (a, 0, cpu);
747 op->type2 = 0;
748 op->val = a;
749 op->family = R_ANAL_OP_FAMILY_IO;
750 ESIL_A ("%s,r%d,=,", r_strbuf_get (io_src), r);
751 r_strbuf_free (io_src);
752 }
753
INST_HANDLER(inc)754 INST_HANDLER (inc) { // INC Rd
755 if (len < 2) {
756 return;
757 }
758 const ut32 d = ((buf[0] >> 4) & 0xf) | ((buf[1] & 0x1) << 4);
759 ESIL_A ("1,r%d,+=,", d); // Rd++
760 // FLAGS:
761 ESIL_A ("7,$o,vf,:=,"); // V
762 ESIL_A ("r%d,0x80,&,!,!,nf,:=,", d); // N
763 ESIL_A ("$z,zf,:=,"); // Z
764 ESIL_A ("vf,nf,^,sf,:=,"); // S
765 }
766
INST_HANDLER(jmp)767 INST_HANDLER (jmp) { // JMP k
768 if (len < 4) {
769 return;
770 }
771 op->jump = (buf[2] << 1)
772 | (buf[3] << 9)
773 | (buf[1] & 0x01) << 23
774 | (buf[0] & 0x01) << 17
775 | (buf[0] & 0xf0) << 14;
776 op->cycles = 3;
777 ESIL_A ("%"PFMT64d",pc,=,", op->jump); // jump!
778 }
779
INST_HANDLER(lac)780 INST_HANDLER (lac) { // LAC Z, Rd
781 if (len < 2) {
782 return;
783 }
784 int d = ((buf[0] >> 4) & 0xf) | ((buf[1] & 0x1) << 4);
785
786 // read memory from RAMPZ:Z
787 __generic_ld_st (op, "ram", 'z', 1, 0, 0, 0); // 0: Read (RAMPZ:Z)
788 ESIL_A ("r%d,0xff,^,&,", d); // 0: (Z) & ~Rd
789 ESIL_A ("DUP,r%d,=,", d); // Rd = [0]
790 __generic_ld_st (op, "ram", 'z', 1, 0, 0, 1); // Store in RAM
791 }
792
INST_HANDLER(las)793 INST_HANDLER (las) { // LAS Z, Rd
794 if (len < 2) {
795 return;
796 }
797 int d = ((buf[0] >> 4) & 0xf) | ((buf[1] & 0x1) << 4);
798
799 // read memory from RAMPZ:Z
800 __generic_ld_st (op, "ram", 'z', 1, 0, 0, 0); // 0: Read (RAMPZ:Z)
801 ESIL_A ("r%d,|,", d); // 0: (Z) | Rd
802 ESIL_A ("DUP,r%d,=,", d); // Rd = [0]
803 __generic_ld_st (op, "ram", 'z', 1, 0, 0, 1); // Store in RAM
804 }
805
INST_HANDLER(lat)806 INST_HANDLER (lat) { // LAT Z, Rd
807 if (len < 2) {
808 return;
809 }
810 int d = ((buf[0] >> 4) & 0xf) | ((buf[1] & 0x1) << 4);
811
812 // read memory from RAMPZ:Z
813 __generic_ld_st (op, "ram", 'z', 1, 0, 0, 0); // 0: Read (RAMPZ:Z)
814 ESIL_A ("r%d,^,", d); // 0: (Z) ^ Rd
815 ESIL_A ("DUP,r%d,=,", d); // Rd = [0]
816 __generic_ld_st (op, "ram", 'z', 1, 0, 0, 1); // Store in RAM
817 }
818
INST_HANDLER(ld)819 INST_HANDLER (ld) { // LD Rd, X
820 // LD Rd, X+
821 // LD Rd, -X
822 if (len < 2) {
823 return;
824 }
825 // read memory
826 __generic_ld_st (
827 op, "ram",
828 'x', // use index register X
829 0, // no use RAMP* registers
830 (buf[0] & 0xf) == 0xe
831 ? -1 // pre decremented
832 : (buf[0] & 0xf) == 0xd
833 ? 1 // post incremented
834 : 0, // no increment
835 0, // offset always 0
836 0); // load operation (!st)
837 // load register
838 ESIL_A ("r%d,=,", ((buf[1] & 1) << 4) | ((buf[0] >> 4) & 0xf));
839 // cycles
840 op->cycles = (buf[0] & 0x3) == 0
841 ? 2 // LD Rd, X
842 : (buf[0] & 0x3) == 1
843 ? 2 // LD Rd, X+
844 : 3; // LD Rd, -X
845 if (!STR_BEGINS (cpu->model, "ATxmega") && op->cycles > 1) {
846 // AT*mega optimizes 1 cycle!
847 op->cycles--;
848 }
849 }
850
INST_HANDLER(ldd)851 INST_HANDLER (ldd) { // LD Rd, Y LD Rd, Z
852 // LD Rd, Y+ LD Rd, Z+
853 // LD Rd, -Y LD Rd, -Z
854 // LD Rd, Y+q LD Rd, Z+q
855 if (len < 2) {
856 return;
857 }
858 // calculate offset (this value only has sense in some opcodes,
859 // but we are optimistic and we calculate it always)
860 int offset = (buf[1] & 0x20)
861 | ((buf[1] & 0xc) << 1)
862 | (buf[0] & 0x7);
863 // read memory
864 __generic_ld_st (
865 op, "ram",
866 buf[0] & 0x8 ? 'y' : 'z', // index register Y/Z
867 0, // no use RAMP* registers
868 !(buf[1] & 0x10)
869 ? 0 // no increment
870 : buf[0] & 0x1
871 ? 1 // post incremented
872 : -1, // pre decremented
873 !(buf[1] & 0x10) ? offset : 0, // offset or not offset
874 0); // load operation (!st)
875 // load register
876 ESIL_A ("r%d,=,", ((buf[1] & 1) << 4) | ((buf[0] >> 4) & 0xf));
877 // cycles
878 op->cycles =
879 (buf[1] & 0x10) == 0
880 ? (!offset ? 1 : 3) // LDD
881 : (buf[0] & 0x3) == 0
882 ? 1 // LD Rd, X
883 : (buf[0] & 0x3) == 1
884 ? 2 // LD Rd, X+
885 : 3; // LD Rd, -X
886 if (!STR_BEGINS (cpu->model, "ATxmega") && op->cycles > 1) {
887 // AT*mega optimizes 1 cycle!
888 op->cycles--;
889 }
890 }
891
INST_HANDLER(ldi)892 INST_HANDLER (ldi) { // LDI Rd, K
893 if (len < 2) {
894 return;
895 }
896 int k = (buf[0] & 0xf) + ((buf[1] & 0xf) << 4);
897 int d = ((buf[0] >> 4) & 0xf) + 16;
898 op->val = k;
899 ESIL_A ("0x%x,r%d,=,", k, d);
900 }
901
INST_HANDLER(lds)902 INST_HANDLER (lds) { // LDS Rd, k
903 if (len < 4) {
904 return;
905 }
906 int d = ((buf[0] >> 4) & 0xf) | ((buf[1] & 0x1) << 4);
907 int k = (buf[3] << 8) | buf[2];
908 op->ptr = k;
909
910 // load value from RAMPD:k
911 __generic_ld_st (op, "ram", 0, 1, 0, k, 0);
912 ESIL_A ("r%d,=,", d);
913 }
914
INST_HANDLER(sts)915 INST_HANDLER (sts) { // STS k, Rr
916 if (len < 4) {
917 return;
918 }
919 int r = ((buf[0] >> 4) & 0xf) | ((buf[1] & 0x1) << 4);
920 int k = (buf[3] << 8) | buf[2];
921 op->ptr = k;
922
923 ESIL_A ("r%d,", r);
924 __generic_ld_st (op, "ram", 0, 1, 0, k, 1);
925
926 op->cycles = 2;
927 }
928
929 #if 0
930 INST_HANDLER (lds16) { // LDS Rd, k
931 int d = ((buf[0] >> 4) & 0xf) + 16;
932 int k = (buf[0] & 0x0f)
933 | ((buf[1] << 3) & 0x30)
934 | ((buf[1] << 4) & 0x40)
935 | (~(buf[1] << 4) & 0x80);
936 op->ptr = k;
937
938 // load value from @k
939 __generic_ld_st (op, "ram", 0, 0, 0, k, 0);
940 ESIL_A ("r%d,=,", d);
941 }
942 #endif
943
INST_HANDLER(lpm)944 INST_HANDLER (lpm) { // LPM
945 // LPM Rd, Z
946 // LPM Rd, Z+
947 if (len < 2) {
948 return;
949 }
950 ut16 ins = (((ut16) buf[1]) << 8) | ((ut16) buf[0]);
951 // read program memory
952 __generic_ld_st (
953 op, "prog",
954 'z', // index register Y/Z
955 1, // use RAMP* registers
956 (ins & 0xfe0f) == 0x9005
957 ? 1 // post incremented
958 : 0, // no increment
959 0, // not offset
960 0); // load operation (!st)
961 // load register
962 ESIL_A ("r%d,=,",
963 (ins == 0x95c8)
964 ? 0 // LPM (r0)
965 : ((buf[0] >> 4) & 0xf) // LPM Rd
966 | ((buf[1] & 0x1) << 4));
967 }
968
INST_HANDLER(lsr)969 INST_HANDLER (lsr) { // LSR Rd
970 if (len < 2) {
971 return;
972 }
973 const ut32 d = ((buf[0] >> 4) & 0xf) | ((buf[1] & 1) << 4);
974 ESIL_A ("r%d,0x1,&,cf,:=,", d); // C = Rd0
975 ESIL_A ("1,r%d,>>=,", d); // 0: R=(Rd >> 1)
976 ESIL_A ("$z,zf,:=,"); // Z
977 ESIL_A ("0,nf,:=,"); // N
978 ESIL_A ("cf,vf,:=,"); // V
979 ESIL_A ("cf,sf,:=,"); // S
980 }
981
INST_HANDLER(mov)982 INST_HANDLER (mov) { // MOV Rd, Rr
983 if (len < 2) {
984 return;
985 }
986 const ut32 d = ((buf[1] << 4) & 0x10) | ((buf[0] >> 4) & 0x0f);
987 const ut32 r = ((buf[1] << 3) & 0x10) | (buf[0] & 0x0f);
988 ESIL_A ("r%d,r%d,=,", r, d);
989 }
990
INST_HANDLER(movw)991 INST_HANDLER (movw) { // MOVW Rd+1:Rd, Rr+1:Rr
992 if (len < 1) {
993 return;
994 }
995 const ut32 d = (buf[0] & 0xf0) >> 3;
996 const ut32 r = (buf[0] & 0x0f) << 1;
997 ESIL_A ("r%d,r%d,=,r%d,r%d,=,", r, d, r + 1, d + 1);
998 }
999
INST_HANDLER(mul)1000 INST_HANDLER (mul) { // MUL Rd, Rr
1001 if (len < 2) {
1002 return;
1003 }
1004 const ut32 d = ((buf[1] << 4) & 0x10) | ((buf[0] >> 4) & 0x0f);
1005 const ut32 r = ((buf[1] << 3) & 0x10) | (buf[0] & 0x0f);
1006
1007 ESIL_A ("r%d,r%d,*,r1_r0,=,", r, d); // 0: r1_r0 = rd * rr
1008 ESIL_A ("r1_r0,0x8000,&,!,!,cf,:=,"); // C = R/15
1009 ESIL_A ("$z,zf,:="); // Z = !R
1010 }
1011
INST_HANDLER(muls)1012 INST_HANDLER (muls) { // MULS Rd, Rr
1013 if (len < 1) {
1014 return;
1015 }
1016 const ut32 d = (buf[0] >> 4 & 0x0f) + 16;
1017 const ut32 r = (buf[0] & 0x0f) + 16;
1018
1019 ESIL_A ("r%d,DUP,0x80,&,?{,0xff00,|,},", d); // sign extension Rd
1020 ESIL_A ("r%d,DUP,0x80,&,?{,0xff00,|,},", r); // sign extension Rr
1021 ESIL_A ("*,r1_r0,=,"); // 0: (Rd*Rr)
1022
1023 ESIL_A ("r1_r0,0x8000,&,!,!,cf,:=,"); // C = R/16
1024 ESIL_A ("$z,zf,:="); // Z = !R
1025 }
1026
INST_HANDLER(mulsu)1027 INST_HANDLER (mulsu) { // MULSU Rd, Rr
1028 if (len < 1) {
1029 return;
1030 }
1031 const ut32 d = (buf[0] >> 4 & 0x07) + 16;
1032 const ut32 r = (buf[0] & 0x07) + 16;
1033
1034 ESIL_A ("r%d,DUP,0x80,&,?{,0xff00,|,},", d); // sign extension Rd
1035 ESIL_A ("r%d,*,r1_r0,=,", r); // 0: (Rd*Rr)
1036
1037 ESIL_A ("r1_r0,0x8000,&,!,!,cf,:=,"); // C = R/16
1038 ESIL_A ("$z,zf,:="); // Z = !R
1039 }
1040
INST_HANDLER(neg)1041 INST_HANDLER (neg) { // NEG Rd
1042 if (len < 2) {
1043 return;
1044 }
1045 int d = ((buf[0] >> 4) & 0xf) | ((buf[1] & 1) << 4);
1046 ESIL_A ("r%d,0x00,-,0xff,&,", d); // 0: (0-Rd)
1047 ESIL_A ("DUP,r%d,0xff,^,|,0x08,&,!,!,hf,=,", d); // H
1048 ESIL_A ("DUP,0x80,-,!,vf,=,"); // V
1049 ESIL_A ("DUP,0x80,&,!,!,nf,=,"); // N
1050 ESIL_A ("DUP,!,zf,=,"); // Z
1051 ESIL_A ("DUP,!,!,cf,=,"); // C
1052 ESIL_A ("vf,nf,^,sf,=,"); // S
1053 ESIL_A ("r%d,=,", d); // Rd = result
1054 }
1055
INST_HANDLER(nop)1056 INST_HANDLER (nop) { // NOP
1057 ESIL_A (",,");
1058 }
1059
INST_HANDLER(or)1060 INST_HANDLER (or) { // OR Rd, Rr
1061 if (len < 2) {
1062 return;
1063 }
1064 int d = ((buf[0] >> 4) & 0xf) | ((buf[1] & 1) << 4);
1065 int r = (buf[0] & 0xf) | ((buf[1] & 2) << 3);
1066 ESIL_A ("r%d,r%d,|=,", r, d); // 0: (Rd | Rr)
1067 ESIL_A ("$z,zf,:=,"); // Z
1068 ESIL_A ("r%d,&,!,!,nf,:=,", d); // N
1069 ESIL_A ("0,vf,:=,"); // V
1070 ESIL_A ("nf,sf,:="); // S
1071 }
1072
INST_HANDLER(ori)1073 INST_HANDLER (ori) { // ORI Rd, K
1074 // SBR Rd, K
1075 if (len < 2) {
1076 return;
1077 }
1078 const ut32 d = ((buf[0] >> 4) & 0xf) + 16;
1079 const ut32 k = (buf[0] & 0xf) | ((buf[1] & 0xf) << 4);
1080 op->val = k;
1081 ESIL_A ("%d,r%d,|=,", k, d); // 0: (Rd | k)
1082 ESIL_A ("$z,zf,:=,"); // Z
1083 ESIL_A ("r%d,0x80,&,!,!,nf,:=,", d); // N
1084 ESIL_A ("0,vf,:=,"); // V
1085 ESIL_A ("nf,sf,:="); // S
1086 }
1087
INST_HANDLER(out)1088 INST_HANDLER (out) { // OUT A, Rr
1089 if (len < 2) {
1090 return;
1091 }
1092 int r = ((buf[0] >> 4) & 0x0f) | ((buf[1] & 0x01) << 4);
1093 int a = (buf[0] & 0x0f) | ((buf[1] & 0x6) << 3);
1094 RStrBuf *io_dst = __generic_io_dest (a, 1, cpu);
1095 op->type2 = 1;
1096 op->val = a;
1097 op->family = R_ANAL_OP_FAMILY_IO;
1098 ESIL_A ("r%d,%s,", r, r_strbuf_get (io_dst));
1099 r_strbuf_free (io_dst);
1100 }
1101
INST_HANDLER(pop)1102 INST_HANDLER (pop) { // POP Rd
1103 if (len < 2) {
1104 return;
1105 }
1106 int d = ((buf[1] & 0x1) << 4) | ((buf[0] >> 4) & 0xf);
1107 __generic_pop (op, 1);
1108 ESIL_A ("r%d,=,", d); // store in Rd
1109
1110 }
1111
INST_HANDLER(push)1112 INST_HANDLER (push) { // PUSH Rr
1113 if (len < 2) {
1114 return;
1115 }
1116 int r = ((buf[1] & 0x1) << 4) | ((buf[0] >> 4) & 0xf);
1117 ESIL_A ("r%d,", r); // load Rr
1118 __generic_push (op, 1); // push it into stack
1119 // cycles
1120 op->cycles = !STR_BEGINS (cpu->model, "ATxmega")
1121 ? 1 // AT*mega optimizes one cycle
1122 : 2;
1123 }
1124
INST_HANDLER(rcall)1125 INST_HANDLER (rcall) { // RCALL k
1126 if (len < 2) {
1127 return;
1128 }
1129 // target address
1130 op->jump = op->addr + (
1131 (((((buf[1] & 0xf) << 8) | buf[0]) << 1)
1132 | (((buf[1] & 0x8) ? ~((int) 0x1fff) : 0)))
1133 + 2);
1134 op->fail = op->addr + op->size;
1135 // esil
1136 ESIL_A ("pc,"); // esil already points to next
1137 // instruction (@ret)
1138 __generic_push (op, CPU_PC_SIZE (cpu)); // push @ret addr
1139 ESIL_A ("%"PFMT64d",pc,=,", op->jump); // jump!
1140 // cycles
1141 if (!r_str_ncasecmp (cpu->model, "ATtiny", 6)) {
1142 op->cycles = 4; // ATtiny is always slow
1143 } else {
1144 // PC size decides required runtime!
1145 op->cycles = cpu->pc <= 16 ? 3 : 4;
1146 if (!STR_BEGINS (cpu->model, "ATxmega")) {
1147 op->cycles--; // ATxmega optimizes one cycle
1148 }
1149 }
1150 }
1151
INST_HANDLER(ret)1152 INST_HANDLER (ret) { // RET
1153 op->eob = true;
1154 // esil
1155 __generic_pop (op, CPU_PC_SIZE (cpu));
1156 ESIL_A ("pc,=,"); // jump!
1157 // cycles
1158 if (CPU_PC_SIZE (cpu) > 2) { // if we have a bus bigger than 16 bit
1159 op->cycles++; // (i.e. a 22-bit bus), add one extra cycle
1160 }
1161 }
1162
INST_HANDLER(reti)1163 INST_HANDLER (reti) { // RETI
1164 //XXX: There are not privileged instructions in ATMEL/AVR
1165 op->family = R_ANAL_OP_FAMILY_PRIV;
1166
1167 // first perform a standard 'ret'
1168 INST_CALL (ret);
1169
1170 // RETI: The I-bit is cleared by hardware after an interrupt
1171 // has occurred, and is set by the RETI instruction to enable
1172 // subsequent interrupts
1173 ESIL_A ("1,if,=,");
1174 }
1175
INST_HANDLER(rjmp)1176 INST_HANDLER (rjmp) { // RJMP k
1177 st32 jump = ((((( buf[1] & 0xf) << 9) | (buf[0] << 1)))
1178 | (buf[1] & 0x8 ? ~(0x1fff) : 0))
1179 + 2;
1180 op->jump = op->addr + jump;
1181 ESIL_A ("%"PFMT64d",pc,=,", op->jump);
1182 }
1183
INST_HANDLER(ror)1184 INST_HANDLER (ror) { // ROR Rd
1185 const ut32 d = ((buf[0] >> 4) & 0x0f) | ((buf[1] << 4) & 0x10);
1186 ESIL_A ("cf,nf,:=,"); // N
1187 ESIL_A ("r%d,0x1,&,", d); // C
1188 ESIL_A ("1,r%d,>>,7,cf,<<,|,r%d,=,cf,:=,", d, d); // 0: (Rd>>1) | (cf<<7)
1189 ESIL_A ("$z,zf,:=,"); // Z
1190 ESIL_A ("nf,cf,^,vf,:=,"); // V
1191 ESIL_A ("vf,nf,^,sf,:="); // S
1192 }
1193
INST_HANDLER(sbc)1194 INST_HANDLER (sbc) { // SBC Rd, Rr
1195 if (len < 2) {
1196 return;
1197 }
1198 const ut32 r = (buf[0] & 0x0f) | ((buf[1] & 0x2) << 3);
1199 const ut32 d = ((buf[0] >> 4) & 0xf) | ((buf[1] & 0x1) << 4);
1200
1201 ESIL_A ("cf,r%d,+,r%d,-=,", r, d); // 0: (Rd-Rr-C)
1202 ESIL_A ("$z,zf,:=,");
1203 ESIL_A ("3,$b,hf,:=,");
1204 ESIL_A ("8,$b,cf,:=,");
1205 ESIL_A ("7,$o,vf,:=,");
1206 ESIL_A ("0x80,r%d,&,!,!,nf,:=,", d);
1207 ESIL_A ("vf,nf,^,sf,:=");
1208 }
1209
INST_HANDLER(sbci)1210 INST_HANDLER (sbci) { // SBCI Rd, k
1211 if (len < 2) {
1212 return;
1213 }
1214 const ut32 d = ((buf[0] >> 4) & 0xf) + 16;
1215 const ut32 k = ((buf[1] & 0xf) << 4) | (buf[0] & 0xf);
1216 op->val = k;
1217
1218 ESIL_A ("cf,%d,+,r%d,-=,", k, d); // 0: (Rd-k-C)
1219 ESIL_A ("$z,zf,:=,");
1220 ESIL_A ("3,$b,hf,:=,");
1221 ESIL_A ("8,$b,cf,:=,");
1222 ESIL_A ("7,$o,vf,:=,");
1223 ESIL_A ("0x80,r%d,&,!,!,nf,:=,", d);
1224 ESIL_A ("vf,nf,^,sf,:=");
1225 }
1226
INST_HANDLER(sub)1227 INST_HANDLER (sub) { // SUB Rd, Rr
1228 if (len < 2) {
1229 return;
1230 }
1231 const ut32 d = ((buf[0] >> 4) & 0xf) | ((buf[1] & 1) << 4);
1232 const ut32 r = (buf[0] & 0xf) | ((buf[1] & 2) << 3);
1233
1234 ESIL_A ("r%d,r%d,-=,", r, d); // 0: (Rd-k)
1235 ESIL_A ("$z,zf,:=,");
1236 ESIL_A ("3,$b,hf,:=,");
1237 ESIL_A ("8,$b,cf,:=,");
1238 ESIL_A ("7,$o,vf,:=,");
1239 ESIL_A ("0x80,r%d,&,!,!,nf,:=,", d);
1240 ESIL_A ("vf,nf,^,sf,:=");
1241 }
1242
INST_HANDLER(subi)1243 INST_HANDLER (subi) { // SUBI Rd, k
1244 if (len < 2) {
1245 return;
1246 }
1247 const ut32 d = ((buf[0] >> 4) & 0xf) + 16;
1248 const ut32 k = ((buf[1] & 0xf) << 4) | (buf[0] & 0xf);
1249 op->val = k;
1250
1251 ESIL_A ("%d,r%d,-=,", k, d); // 0: (Rd-k)
1252 ESIL_A ("$z,zf,:=,");
1253 ESIL_A ("3,$b,hf,:=,");
1254 ESIL_A ("8,$b,cf,:=,");
1255 ESIL_A ("7,$o,vf,:=,");
1256 ESIL_A ("0x80,r%d,&,!,!,nf,:=,", d);
1257 ESIL_A ("vf,nf,^,sf,:=");
1258 }
1259
INST_HANDLER(sbi)1260 INST_HANDLER (sbi) { // SBI A, b
1261 if (len < 1) {
1262 return;
1263 }
1264 int a = (buf[0] >> 3) & 0x1f;
1265 int b = buf[0] & 0x07;
1266 RStrBuf *io_port;
1267
1268 op->type2 = 1;
1269 op->val = a;
1270 op->family = R_ANAL_OP_FAMILY_IO;
1271
1272 // read port a and clear bit b
1273 io_port = __generic_io_dest (a, 0, cpu);
1274 ESIL_A ("0xff,%d,1,<<,|,%s,&,", b, r_strbuf_get (io_port));
1275 r_strbuf_free (io_port);
1276
1277 // write result to port a
1278 io_port = __generic_io_dest (a, 1, cpu);
1279 ESIL_A ("%s,", r_strbuf_get (io_port));
1280 r_strbuf_free (io_port);
1281 }
1282
INST_HANDLER(sbix)1283 INST_HANDLER (sbix) { // SBIC A, b
1284 // SBIS A, b
1285 if (len < 2) {
1286 return;
1287 }
1288 int a = (buf[0] >> 3) & 0x1f;
1289 int b = buf[0] & 0x07;
1290 RAnalOp next_op = { 0 };
1291 RStrBuf *io_port;
1292
1293 op->type2 = 0;
1294 op->val = a;
1295 op->family = R_ANAL_OP_FAMILY_IO;
1296
1297 // calculate next instruction size (call recursively avr_op_analyze)
1298 // and free next_op's esil string (we dont need it now)
1299 avr_op_analyze (anal,
1300 &next_op,
1301 op->addr + op->size, buf + op->size,
1302 len - op->size,
1303 cpu);
1304 r_strbuf_fini (&next_op.esil);
1305 op->jump = op->addr + next_op.size + 2;
1306 op->fail = op->addr + op->size;
1307
1308 // cycles
1309 op->cycles = 1; // XXX: This is a bug, because depends on eval state,
1310 // so it cannot be really be known until this
1311 // instruction is executed by the ESIL interpreter!!!
1312 // In case of evaluating to false, this instruction
1313 // needs 2/3 cycles, elsewhere it needs only 1 cycle.
1314
1315 // read port a and clear bit b
1316 io_port = __generic_io_dest (a, 0, cpu);
1317 ESIL_A ("%d,1,<<,%s,&,", b, r_strbuf_get (io_port)); // IO(A,b)
1318 ESIL_A ((buf[1] & 0xe) == 0xc
1319 ? "!," // SBIC => branch if 0
1320 : "!,!,"); // SBIS => branch if 1
1321 ESIL_A ("?{,%"PFMT64d",pc,=,},", op->jump); // ?true => jmp
1322 r_strbuf_free (io_port);
1323 }
1324
INST_HANDLER(sbiw)1325 INST_HANDLER (sbiw) { // SBIW Rd+1:Rd, K
1326 if (len < 1) {
1327 return;
1328 }
1329 int d = ((buf[0] & 0x30) >> 3) + 24;
1330 int k = (buf[0] & 0xf) | ((buf[0] >> 2) & 0x30);
1331 op->val = k;
1332 ESIL_A ("%d,r%d_r%d,-=,", k, d + 1, d); // 0(Rd+1:Rd - Rr)
1333 ESIL_A ("$z,zf,:=,");
1334 ESIL_A ("15,$c,cf,:=,"); // C
1335 ESIL_A ("r%d_r%d,0x8000,&,!,!,nf,:=,", d + 1, d); // N
1336 ESIL_A ("r%d_r%d,0x8080,&,0x8080,!,vf,:=,", d + 1, d); // V
1337 ESIL_A ("vf,nf,^,sf,:="); // S
1338 }
1339
INST_HANDLER(sbrx)1340 INST_HANDLER (sbrx) { // SBRC Rr, b
1341 // SBRS Rr, b
1342 if (len < 2) {
1343 return;
1344 }
1345 int b = buf[0] & 0x7;
1346 int r = ((buf[0] >> 4) & 0xf) | ((buf[1] & 0x01) << 4);
1347 RAnalOp next_op = {0};
1348
1349 // calculate next instruction size (call recursively avr_op_analyze)
1350 // and free next_op's esil string (we dont need it now)
1351 avr_op_analyze (anal,
1352 &next_op,
1353 op->addr + op->size, buf + op->size, len - op->size,
1354 cpu);
1355 r_strbuf_fini (&next_op.esil);
1356 op->jump = op->addr + next_op.size + 2;
1357 op->fail = op->addr + 2;
1358
1359 // cycles
1360 op->cycles = 1; // XXX: This is a bug, because depends on eval state,
1361 // so it cannot be really be known until this
1362 // instruction is executed by the ESIL interpreter!!!
1363 // In case of evaluating to false, this instruction
1364 // needs 2/3 cycles, elsewhere it needs only 1 cycle.
1365 ESIL_A ("%d,1,<<,r%d,&,", b, r); // Rr(b)
1366 ESIL_A ((buf[1] & 0xe) == 0xc
1367 ? "!," // SBRC => branch if cleared
1368 : "!,!,"); // SBRS => branch if set
1369 ESIL_A ("?{,%"PFMT64d",pc,=,},", op->jump); // ?true => jmp
1370 }
1371
INST_HANDLER(sleep)1372 INST_HANDLER (sleep) { // SLEEP
1373 ESIL_A ("BREAK");
1374 }
1375
INST_HANDLER(spm)1376 INST_HANDLER (spm) { // SPM Z+
1377 ut64 spmcsr;
1378
1379 // read SPM Control Register (SPMCR)
1380 r_anal_esil_reg_read (anal->esil, "spmcsr", &spmcsr, NULL);
1381
1382 // clear SPMCSR
1383 ESIL_A ("0x7c,spmcsr,&=,");
1384
1385 // decide action depending on the old value of SPMCSR
1386 switch (spmcsr & 0x7f) {
1387 case 0x03: // PAGE ERASE
1388 // invoke SPM_CLEAR_PAGE (erases target page writing
1389 // the 0xff value
1390 ESIL_A ("16,rampz,<<,z,+,"); // push target address
1391 ESIL_A ("SPM_PAGE_ERASE,"); // do magic
1392 break;
1393
1394 case 0x01: // FILL TEMPORARY BUFFER
1395 ESIL_A ("r1,r0,"); // push data
1396 ESIL_A ("z,"); // push target address
1397 ESIL_A ("SPM_PAGE_FILL,"); // do magic
1398 break;
1399
1400 case 0x05: // WRITE PAGE
1401 ESIL_A ("16,rampz,<<,z,+,"); // push target address
1402 ESIL_A ("SPM_PAGE_WRITE,"); // do magic
1403 break;
1404
1405 default:
1406 eprintf ("SPM: I dont know what to do with SPMCSR %02x.\n",
1407 (unsigned int) spmcsr);
1408 }
1409
1410 op->cycles = 1; // This is truly false. Datasheets do not publish how
1411 // many cycles this instruction uses in all its
1412 // operation modes and I am pretty sure that this value
1413 // can vary substantially from one MCU type to another.
1414 // So... one cycle is fine.
1415 }
1416
INST_HANDLER(st)1417 INST_HANDLER (st) { // ST X, Rr
1418 // ST X+, Rr
1419 // ST -X, Rr
1420 if (len < 2) {
1421 return;
1422 }
1423 // load register
1424 ESIL_A ("r%d,", ((buf[1] & 1) << 4) | ((buf[0] >> 4) & 0xf));
1425 // write in memory
1426 __generic_ld_st (
1427 op, "ram",
1428 'x', // use index register X
1429 0, // no use RAMP* registers
1430 (buf[0] & 0xf) == 0xe
1431 ? -1 // pre decremented
1432 : (buf[0] & 0xf) == 0xd
1433 ? 1 // post increment
1434 : 0, // no increment
1435 0, // offset always 0
1436 1); // store operation (st)
1437 // // cycles
1438 // op->cycles = buf[0] & 0x3 == 0
1439 // ? 2 // LD Rd, X
1440 // : buf[0] & 0x3 == 1
1441 // ? 2 // LD Rd, X+
1442 // : 3; // LD Rd, -X
1443 // if (!STR_BEGINS (cpu->model, "ATxmega") && op->cycles > 1) {
1444 // // AT*mega optimizes 1 cycle!
1445 // op->cycles--;
1446 // }
1447 }
1448
INST_HANDLER(std)1449 INST_HANDLER (std) { // ST Y, Rr ST Z, Rr
1450 // ST Y+, Rr ST Z+, Rr
1451 // ST -Y, Rr ST -Z, Rr
1452 // ST Y+q, Rr ST Z+q, Rr
1453 if (len < 2) {
1454 return;
1455 }
1456 // load register
1457 ESIL_A ("r%d,", ((buf[1] & 1) << 4) | ((buf[0] >> 4) & 0xf));
1458 // write in memory
1459 __generic_ld_st (
1460 op, "ram",
1461 buf[0] & 0x8 ? 'y' : 'z', // index register Y/Z
1462 0, // no use RAMP* registers
1463 !(buf[1] & 0x10)
1464 ? 0 // no increment
1465 : buf[0] & 0x1
1466 ? 1 // post incremented
1467 : -1, // pre decremented
1468 !(buf[1] & 0x10)
1469 ? (buf[1] & 0x20) // offset
1470 | ((buf[1] & 0xc) << 1)
1471 | (buf[0] & 0x7)
1472 : 0, // no offset
1473 1); // load operation (!st)
1474 // // cycles
1475 // op->cycles =
1476 // buf[1] & 0x1 == 0
1477 // ? !(offset ? 1 : 3) // LDD
1478 // : buf[0] & 0x3 == 0
1479 // ? 1 // LD Rd, X
1480 // : buf[0] & 0x3 == 1
1481 // ? 2 // LD Rd, X+
1482 // : 3; // LD Rd, -X
1483 // if (!STR_BEGINS (cpu->model, "ATxmega") && op->cycles > 1) {
1484 // // AT*mega optimizes 1 cycle!
1485 // op->cycles--;
1486 // }
1487 }
1488
INST_HANDLER(swap)1489 INST_HANDLER (swap) { // SWAP Rd
1490 if (len < 2) {
1491 return;
1492 }
1493 int d = ((buf[1] & 0x1) << 4) | ((buf[0] >> 4) & 0xf);
1494 ESIL_A ("4,r%d,>>,0x0f,&,", d); // (Rd >> 4) & 0xf
1495 ESIL_A ("4,r%d,<<,0xf0,&,", d); // (Rd >> 4) & 0xf
1496 ESIL_A ("|,"); // S[0] | S[1]
1497 ESIL_A ("r%d,=,", d); // Rd = result
1498 }
1499
1500 OPCODE_DESC opcodes[] = {
1501 // op mask select cycles size type
1502 INST_DECL (break, 0xffff, 0x9698, 1, 2, TRAP ), // BREAK
1503 INST_DECL (eicall, 0xffff, 0x9519, 0, 2, UCALL ), // EICALL
1504 INST_DECL (eijmp, 0xffff, 0x9419, 0, 2, UJMP ), // EIJMP
1505 INST_DECL (icall, 0xffff, 0x9509, 0, 2, UCALL ), // ICALL
1506 INST_DECL (ijmp, 0xffff, 0x9409, 0, 2, UJMP ), // IJMP
1507 INST_DECL (lpm, 0xffff, 0x95c8, 3, 2, LOAD ), // LPM
1508 INST_DECL (nop, 0xffff, 0x0000, 1, 2, NOP ), // NOP
1509 INST_DECL (ret, 0xffff, 0x9508, 4, 2, RET ), // RET
1510 INST_DECL (reti, 0xffff, 0x9518, 4, 2, RET ), // RETI
1511 INST_DECL (sleep, 0xffff, 0x9588, 1, 2, NOP ), // SLEEP
1512 INST_DECL (spm, 0xffff, 0x95e8, 1, 2, TRAP ), // SPM ...
1513 INST_DECL (bclr, 0xff8f, 0x9488, 1, 2, MOV ), // BCLR s
1514 INST_DECL (bset, 0xff8f, 0x9408, 1, 2, MOV ), // BSET s
1515 INST_DECL (fmul, 0xff88, 0x0308, 2, 2, MUL ), // FMUL Rd, Rr
1516 INST_DECL (fmuls, 0xff88, 0x0380, 2, 2, MUL ), // FMULS Rd, Rr
1517 INST_DECL (fmulsu, 0xff88, 0x0388, 2, 2, MUL ), // FMULSU Rd, Rr
1518 INST_DECL (mulsu, 0xff88, 0x0300, 2, 2, AND ), // MUL Rd, Rr
1519 INST_DECL (des, 0xff0f, 0x940b, 0, 2, CRYPTO ), // DES k
1520 INST_DECL (adiw, 0xff00, 0x9600, 2, 2, ADD ), // ADIW Rd+1:Rd, K
1521 INST_DECL (sbiw, 0xff00, 0x9700, 2, 2, SUB ), // SBIW Rd+1:Rd, K
1522 INST_DECL (cbi, 0xff00, 0x9800, 1, 2, IO ), // CBI A, K
1523 INST_DECL (sbi, 0xff00, 0x9a00, 1, 2, IO ), // SBI A, K
1524 INST_DECL (movw, 0xff00, 0x0100, 1, 2, MOV ), // MOVW Rd+1:Rd, Rr+1:Rr
1525 INST_DECL (muls, 0xff00, 0x0200, 2, 2, AND ), // MUL Rd, Rr
1526 INST_DECL (asr, 0xfe0f, 0x9405, 1, 2, SAR ), // ASR Rd
1527 INST_DECL (com, 0xfe0f, 0x9400, 1, 2, NOT ), // BLD Rd, b
1528 INST_DECL (dec, 0xfe0f, 0x940a, 1, 2, SUB ), // DEC Rd
1529 INST_DECL (elpm, 0xfe0f, 0x9006, 0, 2, LOAD ), // ELPM Rd, Z
1530 INST_DECL (elpm, 0xfe0f, 0x9007, 0, 2, LOAD ), // ELPM Rd, Z+
1531 INST_DECL (inc, 0xfe0f, 0x9403, 1, 2, ADD ), // INC Rd
1532 INST_DECL (lac, 0xfe0f, 0x9206, 2, 2, LOAD ), // LAC Z, Rd
1533 INST_DECL (las, 0xfe0f, 0x9205, 2, 2, LOAD ), // LAS Z, Rd
1534 INST_DECL (lat, 0xfe0f, 0x9207, 2, 2, LOAD ), // LAT Z, Rd
1535 INST_DECL (ld, 0xfe0f, 0x900c, 0, 2, LOAD ), // LD Rd, X
1536 INST_DECL (ld, 0xfe0f, 0x900d, 0, 2, LOAD ), // LD Rd, X+
1537 INST_DECL (ld, 0xfe0f, 0x900e, 0, 2, LOAD ), // LD Rd, -X
1538 INST_DECL (lds, 0xfe0f, 0x9000, 0, 4, LOAD ), // LDS Rd, k
1539 INST_DECL (sts, 0xfe0f, 0x9200, 2, 4, STORE ), // STS k, Rr
1540 INST_DECL (lpm, 0xfe0f, 0x9004, 3, 2, LOAD ), // LPM Rd, Z
1541 INST_DECL (lpm, 0xfe0f, 0x9005, 3, 2, LOAD ), // LPM Rd, Z+
1542 INST_DECL (lsr, 0xfe0f, 0x9406, 1, 2, SHR ), // LSR Rd
1543 INST_DECL (neg, 0xfe0f, 0x9401, 2, 2, SUB ), // NEG Rd
1544 INST_DECL (pop, 0xfe0f, 0x900f, 2, 2, POP ), // POP Rd
1545 INST_DECL (push, 0xfe0f, 0x920f, 0, 2, PUSH ), // PUSH Rr
1546 INST_DECL (ror, 0xfe0f, 0x9407, 1, 2, SAR ), // ROR Rd
1547 INST_DECL (st, 0xfe0f, 0x920c, 2, 2, STORE ), // ST X, Rr
1548 INST_DECL (st, 0xfe0f, 0x920d, 0, 2, STORE ), // ST X+, Rr
1549 INST_DECL (st, 0xfe0f, 0x920e, 0, 2, STORE ), // ST -X, Rr
1550 INST_DECL (swap, 0xfe0f, 0x9402, 1, 2, SAR ), // SWAP Rd
1551 INST_DECL (call, 0xfe0e, 0x940e, 0, 4, CALL ), // CALL k
1552 INST_DECL (jmp, 0xfe0e, 0x940c, 2, 4, JMP ), // JMP k
1553 INST_DECL (bld, 0xfe08, 0xf800, 1, 2, MOV ), // BLD Rd, b
1554 INST_DECL (bst, 0xfe08, 0xfa00, 1, 2, MOV ), // BST Rd, b
1555 INST_DECL (sbix, 0xff00, 0x9900, 2, 2, CJMP ), // SBIC A, b
1556 INST_DECL (sbix, 0xff00, 0x9b00, 2, 2, CJMP ), // SBIS A, b
1557 INST_DECL (sbrx, 0xfe08, 0xfc00, 2, 2, CJMP ), // SBRC Rr, b
1558 INST_DECL (sbrx, 0xfe08, 0xfe00, 2, 2, CJMP ), // SBRS Rr, b
1559 INST_DECL (ldd, 0xfe07, 0x9001, 0, 2, LOAD ), // LD Rd, Y/Z+
1560 INST_DECL (ldd, 0xfe07, 0x9002, 0, 2, LOAD ), // LD Rd, -Y/Z
1561 INST_DECL (std, 0xfe07, 0x9201, 0, 2, STORE ), // ST Y/Z+, Rr
1562 INST_DECL (std, 0xfe07, 0x9202, 0, 2, STORE ), // ST -Y/Z, Rr
1563 INST_DECL (adc, 0xfc00, 0x1c00, 1, 2, ADD ), // ADC Rd, Rr
1564 INST_DECL (add, 0xfc00, 0x0c00, 1, 2, ADD ), // ADD Rd, Rr
1565 INST_DECL (and, 0xfc00, 0x2000, 1, 2, AND ), // AND Rd, Rr
1566 INST_DECL (brbx, 0xfc00, 0xf000, 0, 2, CJMP ), // BRBS s, k
1567 INST_DECL (brbx, 0xfc00, 0xf400, 0, 2, CJMP ), // BRBC s, k
1568 INST_DECL (cp, 0xfc00, 0x1400, 1, 2, CMP ), // CP Rd, Rr
1569 INST_DECL (cpc, 0xfc00, 0x0400, 1, 2, CMP ), // CPC Rd, Rr
1570 INST_DECL (cpse, 0xfc00, 0x1000, 0, 2, CJMP ), // CPSE Rd, Rr
1571 INST_DECL (eor, 0xfc00, 0x2400, 1, 2, XOR ), // EOR Rd, Rr
1572 INST_DECL (mov, 0xfc00, 0x2c00, 1, 2, MOV ), // MOV Rd, Rr
1573 INST_DECL (mul, 0xfc00, 0x9c00, 2, 2, AND ), // MUL Rd, Rr
1574 INST_DECL (or, 0xfc00, 0x2800, 1, 2, OR ), // OR Rd, Rr
1575 INST_DECL (sbc, 0xfc00, 0x0800, 1, 2, SUB ), // SBC Rd, Rr
1576 INST_DECL (sub, 0xfc00, 0x1800, 1, 2, SUB ), // SUB Rd, Rr
1577 INST_DECL (in, 0xf800, 0xb000, 1, 2, IO ), // IN Rd, A
1578 //INST_DECL (lds16, 0xf800, 0xa000, 1, 2, LOAD ), // LDS Rd, k
1579 INST_DECL (out, 0xf800, 0xb800, 1, 2, IO ), // OUT A, Rr
1580 INST_DECL (andi, 0xf000, 0x7000, 1, 2, AND ), // ANDI Rd, K
1581 INST_DECL (cpi, 0xf000, 0x3000, 1, 2, CMP ), // CPI Rd, K
1582 INST_DECL (ldi, 0xf000, 0xe000, 1, 2, LOAD ), // LDI Rd, K
1583 INST_DECL (ori, 0xf000, 0x6000, 1, 2, OR ), // ORI Rd, K
1584 INST_DECL (rcall, 0xf000, 0xd000, 0, 2, CALL ), // RCALL k
1585 INST_DECL (rjmp, 0xf000, 0xc000, 2, 2, JMP ), // RJMP k
1586 INST_DECL (sbci, 0xf000, 0x4000, 1, 2, SUB ), // SBC Rd, Rr
1587 INST_DECL (subi, 0xf000, 0x5000, 1, 2, SUB ), // SUBI Rd, Rr
1588 INST_DECL (ldd, 0xd200, 0x8000, 0, 2, LOAD ), // LD Rd, Y/Z+q
1589 INST_DECL (std, 0xd200, 0x8200, 0, 2, STORE ), // ST Y/Z+q, Rr
1590
1591 INST_LAST
1592 };
1593
set_invalid_op(RAnalOp * op,ut64 addr)1594 static void set_invalid_op(RAnalOp *op, ut64 addr) {
1595 // Unknown or invalid instruction.
1596 op->family = R_ANAL_OP_FAMILY_UNKNOWN;
1597 op->type = R_ANAL_OP_TYPE_UNK;
1598 op->addr = addr;
1599 op->nopcode = 1;
1600 op->cycles = 1;
1601 op->size = 2;
1602 // set an esil trap to prevent the execution of it
1603 r_strbuf_set (&op->esil, "1,$");
1604 }
1605
avr_op_analyze(RAnal * anal,RAnalOp * op,ut64 addr,const ut8 * buf,int len,CPU_MODEL * cpu)1606 static OPCODE_DESC* avr_op_analyze(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *buf, int len, CPU_MODEL *cpu) {
1607 OPCODE_DESC *opcode_desc;
1608 if (len < 2) {
1609 return NULL;
1610 }
1611 ut16 ins = (buf[1] << 8) | buf[0];
1612 int fail;
1613 char *t;
1614
1615 // process opcode
1616 for (opcode_desc = opcodes; opcode_desc->handler; opcode_desc++) {
1617 if ((ins & opcode_desc->mask) == opcode_desc->selector) {
1618 fail = 0;
1619
1620 // copy default cycles/size values
1621 op->cycles = opcode_desc->cycles;
1622 op->size = opcode_desc->size;
1623 op->type = opcode_desc->type;
1624 op->jump = UT64_MAX;
1625 op->fail = UT64_MAX;
1626 // op->fail = addr + op->size;
1627 op->addr = addr;
1628
1629 // start void esil expression
1630 r_strbuf_setf (&op->esil, "%s", "");
1631
1632 // handle opcode
1633 opcode_desc->handler (anal, op, buf, len, &fail, cpu);
1634 if (fail) {
1635 goto INVALID_OP;
1636 }
1637 if (op->cycles <= 0) {
1638 // eprintf ("opcode %s @%"PFMT64x" returned 0 cycles.\n", opcode_desc->name, op->addr);
1639 opcode_desc->cycles = 2;
1640 }
1641 op->nopcode = (op->type == R_ANAL_OP_TYPE_UNK);
1642
1643 // remove trailing coma (COMETE LA COMA)
1644 t = r_strbuf_get (&op->esil);
1645 if (t && strlen (t) > 1) {
1646 t += strlen (t) - 1;
1647 if (*t == ',') {
1648 *t = '\0';
1649 }
1650 }
1651
1652 return opcode_desc;
1653 }
1654 }
1655 #if 0
1656 // ignore reserved opcodes (if they have not been caught by the previous loop)
1657 if ((ins & 0xff00) == 0xff00 && (ins & 0xf) > 7) {
1658 goto INVALID_OP;
1659 }
1660
1661 INVALID_OP:
1662 // An unknown or invalid option has appeared.
1663 // -- Throw pokeball!
1664 op->family = R_ANAL_OP_FAMILY_UNKNOWN;
1665 op->type = R_ANAL_OP_TYPE_UNK;
1666 op->addr = addr;
1667 op->nopcode = 1;
1668 op->cycles = 1;
1669 op->size = 2;
1670 // launch esil trap (for communicating upper layers about this weird
1671 // and stinky situation
1672 r_strbuf_set (&op->esil, "1,$");
1673 #else
1674 INVALID_OP:
1675 set_invalid_op (op, addr);
1676 #endif
1677
1678 return NULL;
1679 }
1680
avr_op(RAnal * anal,RAnalOp * op,ut64 addr,const ut8 * buf,int len,RAnalOpMask mask)1681 static int avr_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *buf, int len, RAnalOpMask mask) {
1682 CPU_MODEL *cpu;
1683 ut64 offset;
1684 int size = -1;
1685 char mnemonic[32] = {0};
1686
1687 set_invalid_op (op, addr);
1688
1689 size = avr_decode (mnemonic, addr, buf, len);
1690 if (!strcmp (mnemonic, "invalid") ||
1691 !strcmp (mnemonic, "truncated")) {
1692 op->eob = true;
1693 op->mnemonic = strdup(mnemonic);
1694 return -1;
1695 }
1696
1697 if (!op) {
1698 return -1;
1699 }
1700
1701 // select cpu info
1702 cpu = get_cpu_model (anal->cpu);
1703
1704 // set memory layout registers
1705 if (anal->esil) {
1706 offset = 0;
1707 r_anal_esil_reg_write (anal->esil, "_prog", offset);
1708
1709 offset += (1 << cpu->pc);
1710 r_anal_esil_reg_write (anal->esil, "_io", offset);
1711
1712 offset += const_get_value (const_by_name (cpu, CPU_CONST_PARAM, "sram_start"));
1713 r_anal_esil_reg_write (anal->esil, "_sram", offset);
1714
1715 offset += const_get_value (const_by_name (cpu, CPU_CONST_PARAM, "sram_size"));
1716 r_anal_esil_reg_write (anal->esil, "_eeprom", offset);
1717
1718 offset += const_get_value (const_by_name (cpu, CPU_CONST_PARAM, "eeprom_size"));
1719 r_anal_esil_reg_write (anal->esil, "_page", offset);
1720 }
1721 // process opcode
1722 avr_op_analyze (anal, op, addr, buf, len, cpu);
1723
1724 op->mnemonic = strdup(mnemonic);
1725 op->size = size;
1726
1727 return size;
1728 }
1729
avr_custom_des(RAnalEsil * esil)1730 static bool avr_custom_des (RAnalEsil *esil) {
1731 ut64 key, encrypt, text,des_round;
1732 ut32 key_lo, key_hi, buf_lo, buf_hi;
1733 if (!esil || !esil->anal || !esil->anal->reg) {
1734 return false;
1735 }
1736 if (!__esil_pop_argument (esil, &des_round)) {
1737 return false;
1738 }
1739 r_anal_esil_reg_read (esil, "hf", &encrypt, NULL);
1740 r_anal_esil_reg_read (esil, "deskey", &key, NULL);
1741 r_anal_esil_reg_read (esil, "text", &text, NULL);
1742
1743 key_lo = key & UT32_MAX;
1744 key_hi = key >> 32;
1745 buf_lo = text & UT32_MAX;
1746 buf_hi = text >> 32;
1747
1748 if (des_round != desctx.round) {
1749 desctx.round = des_round;
1750 }
1751
1752 if (!desctx.round) {
1753 int i;
1754 //generating all round keys
1755 r_des_permute_key (&key_lo, &key_hi);
1756 for (i = 0; i < 16; i++) {
1757 r_des_round_key (i, &desctx.round_key_lo[i], &desctx.round_key_hi[i], &key_lo, &key_hi);
1758 }
1759 r_des_permute_block0 (&buf_lo, &buf_hi);
1760 }
1761
1762 if (encrypt) {
1763 r_des_round (&buf_lo, &buf_hi, &desctx.round_key_lo[desctx.round], &desctx.round_key_hi[desctx.round]);
1764 } else {
1765 r_des_round (&buf_lo, &buf_hi, &desctx.round_key_lo[15 - desctx.round], &desctx.round_key_hi[15 - desctx.round]);
1766 }
1767
1768 if (desctx.round == 15) {
1769 r_des_permute_block1 (&buf_hi, &buf_lo);
1770 desctx.round = 0;
1771 } else {
1772 desctx.round++;
1773 }
1774
1775 r_anal_esil_reg_write (esil, "text", text);
1776 return true;
1777 }
1778
1779 // ESIL operation SPM_PAGE_ERASE
avr_custom_spm_page_erase(RAnalEsil * esil)1780 static bool avr_custom_spm_page_erase(RAnalEsil *esil) {
1781 CPU_MODEL *cpu;
1782 ut8 c;
1783 ut64 addr, page_size_bits, i;
1784
1785 // sanity check
1786 if (!esil || !esil->anal || !esil->anal->reg) {
1787 return false;
1788 }
1789
1790 // get target address
1791 if (!__esil_pop_argument(esil, &addr)) {
1792 return false;
1793 }
1794
1795 // get details about current MCU and fix input address
1796 cpu = get_cpu_model (esil->anal->cpu);
1797 page_size_bits = const_get_value (const_by_name (cpu, CPU_CONST_PARAM, "page_size"));
1798
1799 // align base address to page_size_bits
1800 addr &= ~(MASK (page_size_bits));
1801
1802 // perform erase
1803 //eprintf ("SPM_PAGE_ERASE %ld bytes @ 0x%08" PFMT64x ".\n", page_size, addr);
1804 c = 0xff;
1805 for (i = 0; i < (1ULL << page_size_bits); i++) {
1806 r_anal_esil_mem_write (
1807 esil, (addr + i) & CPU_PC_MASK (cpu), &c, 1);
1808 }
1809
1810 return true;
1811 }
1812
1813 // ESIL operation SPM_PAGE_FILL
avr_custom_spm_page_fill(RAnalEsil * esil)1814 static bool avr_custom_spm_page_fill(RAnalEsil *esil) {
1815 CPU_MODEL *cpu;
1816 ut64 addr, page_size_bits, i;
1817 ut8 r0, r1;
1818
1819 // sanity check
1820 if (!esil || !esil->anal || !esil->anal->reg) {
1821 return false;
1822 }
1823
1824 // get target address, r0, r1
1825 if (!__esil_pop_argument(esil, &addr)) {
1826 return false;
1827 }
1828
1829 if (!__esil_pop_argument (esil, &i)) {
1830 return false;
1831 }
1832 r0 = i;
1833
1834 if (!__esil_pop_argument (esil, &i)) {
1835 return false;
1836 }
1837 r1 = i;
1838
1839 // get details about current MCU and fix input address
1840 cpu = get_cpu_model (esil->anal->cpu);
1841 page_size_bits = const_get_value (const_by_name (cpu, CPU_CONST_PARAM, "page_size"));
1842
1843 // align and crop base address
1844 addr &= (MASK (page_size_bits) ^ 1);
1845
1846 // perform write to temporary page
1847 //eprintf ("SPM_PAGE_FILL bytes (%02x, %02x) @ 0x%08" PFMT64x ".\n", r1, r0, addr);
1848 r_anal_esil_mem_write (esil, addr++, &r0, 1);
1849 r_anal_esil_mem_write (esil, addr++, &r1, 1);
1850
1851 return true;
1852 }
1853
1854 // ESIL operation SPM_PAGE_WRITE
avr_custom_spm_page_write(RAnalEsil * esil)1855 static bool avr_custom_spm_page_write(RAnalEsil *esil) {
1856 CPU_MODEL *cpu;
1857 char *t = NULL;
1858 ut64 addr, page_size_bits, tmp_page;
1859
1860 // sanity check
1861 if (!esil || !esil->anal || !esil->anal->reg) {
1862 return false;
1863 }
1864
1865 // get target address
1866 if (!__esil_pop_argument (esil, &addr)) {
1867 return false;
1868 }
1869
1870 // get details about current MCU and fix input address and base address
1871 // of the internal temporary page
1872 cpu = get_cpu_model (esil->anal->cpu);
1873 page_size_bits = const_get_value (const_by_name (cpu, CPU_CONST_PARAM, "page_size"));
1874 r_anal_esil_reg_read (esil, "_page", &tmp_page, NULL);
1875
1876 // align base address to page_size_bits
1877 addr &= (~(MASK (page_size_bits)) & CPU_PC_MASK (cpu));
1878
1879 // perform writing
1880 //eprintf ("SPM_PAGE_WRITE %ld bytes @ 0x%08" PFMT64x ".\n", page_size, addr);
1881 if (!(t = malloc (1 << page_size_bits))) {
1882 eprintf ("Cannot alloc a buffer for copying the temporary page.\n");
1883 return false;
1884 }
1885 r_anal_esil_mem_read (esil, tmp_page, (ut8 *) t, 1 << page_size_bits);
1886 r_anal_esil_mem_write (esil, addr, (ut8 *) t, 1 << page_size_bits);
1887
1888 return true;
1889 }
1890
esil_avr_hook_reg_write(RAnalEsil * esil,const char * name,ut64 * val)1891 static int esil_avr_hook_reg_write(RAnalEsil *esil, const char *name, ut64 *val) {
1892 CPU_MODEL *cpu;
1893
1894 if (!esil || !esil->anal) {
1895 return 0;
1896 }
1897
1898 // select cpu info
1899 cpu = get_cpu_model (esil->anal->cpu);
1900
1901 // crop registers and force certain values
1902 if (!strcmp (name, "pc")) {
1903 *val &= CPU_PC_MASK (cpu);
1904 } else if (!strcmp (name, "pcl")) {
1905 if (cpu->pc < 8) {
1906 *val &= MASK (8);
1907 }
1908 } else if (!strcmp (name, "pch")) {
1909 *val = cpu->pc > 8
1910 ? *val & MASK (cpu->pc - 8)
1911 : 0;
1912 }
1913
1914 return 0;
1915 }
1916
esil_avr_init(RAnalEsil * esil)1917 static int esil_avr_init(RAnalEsil *esil) {
1918 if (!esil) {
1919 return false;
1920 }
1921 desctx.round = 0;
1922 r_anal_esil_set_op (esil, "des", avr_custom_des, 0, 0, R_ANAL_ESIL_OP_TYPE_CUSTOM); //better meta info plz
1923 r_anal_esil_set_op (esil, "SPM_PAGE_ERASE", avr_custom_spm_page_erase, 0, 0, R_ANAL_ESIL_OP_TYPE_CUSTOM);
1924 r_anal_esil_set_op (esil, "SPM_PAGE_FILL", avr_custom_spm_page_fill, 0, 0, R_ANAL_ESIL_OP_TYPE_CUSTOM);
1925 r_anal_esil_set_op (esil, "SPM_PAGE_WRITE", avr_custom_spm_page_write, 0, 0, R_ANAL_ESIL_OP_TYPE_CUSTOM);
1926 esil->cb.hook_reg_write = esil_avr_hook_reg_write;
1927
1928 return true;
1929 }
1930
esil_avr_fini(RAnalEsil * esil)1931 static int esil_avr_fini(RAnalEsil *esil) {
1932 return true;
1933 }
1934
set_reg_profile(RAnal * anal)1935 static bool set_reg_profile(RAnal *anal) {
1936 const char *p =
1937 "=PC pcl\n"
1938 "=SN r24\n"
1939 "=SP sp\n"
1940 "=BP y\n"
1941 // explained in http://www.nongnu.org/avr-libc/user-manual/FAQ.html
1942 // and http://www.avrfreaks.net/forum/function-calling-convention-gcc-generated-assembly-file
1943 "=A0 r25\n"
1944 "=A1 r24\n"
1945 "=A2 r23\n"
1946 "=A3 r22\n"
1947 "=R0 r24\n"
1948 #if 0
1949 PC: 16- or 22-bit program counter
1950 SP: 8- or 16-bit stack pointer
1951 SREG: 8-bit status register
1952 RAMPX, RAMPY, RAMPZ, RAMPD and EIND:
1953 #endif
1954 // 8bit registers x 32
1955 "gpr r0 .8 0 0\n"
1956 "gpr r1 .8 1 0\n"
1957 "gpr r2 .8 2 0\n"
1958 "gpr r3 .8 3 0\n"
1959 "gpr r4 .8 4 0\n"
1960 "gpr r5 .8 5 0\n"
1961 "gpr r6 .8 6 0\n"
1962 "gpr r7 .8 7 0\n"
1963 "gpr text .64 0 0\n"
1964 "gpr r8 .8 8 0\n"
1965 "gpr r9 .8 9 0\n"
1966 "gpr r10 .8 10 0\n"
1967 "gpr r11 .8 11 0\n"
1968 "gpr r12 .8 12 0\n"
1969 "gpr r13 .8 13 0\n"
1970 "gpr r14 .8 14 0\n"
1971 "gpr r15 .8 15 0\n"
1972 "gpr deskey .64 8 0\n"
1973 "gpr r16 .8 16 0\n"
1974 "gpr r17 .8 17 0\n"
1975 "gpr r18 .8 18 0\n"
1976 "gpr r19 .8 19 0\n"
1977 "gpr r20 .8 20 0\n"
1978 "gpr r21 .8 21 0\n"
1979 "gpr r22 .8 22 0\n"
1980 "gpr r23 .8 23 0\n"
1981 "gpr r24 .8 24 0\n"
1982 "gpr r25 .8 25 0\n"
1983 "gpr r26 .8 26 0\n"
1984 "gpr r27 .8 27 0\n"
1985 "gpr r28 .8 28 0\n"
1986 "gpr r29 .8 29 0\n"
1987 "gpr r30 .8 30 0\n"
1988 "gpr r31 .8 31 0\n"
1989
1990 // 16 bit overlapped registers for 16 bit math
1991 "gpr r1_r0 .16 0 0\n" //this is a hack for mul
1992 "gpr r17_r16 .16 16 0\n"
1993 "gpr r19_r18 .16 18 0\n"
1994 "gpr r21_r20 .16 20 0\n"
1995 "gpr r23_r22 .16 22 0\n"
1996 "gpr r25_r24 .16 24 0\n"
1997 "gpr r27_r26 .16 26 0\n"
1998 "gpr r29_r28 .16 28 0\n"
1999 "gpr r31_r30 .16 30 0\n"
2000
2001 // 16 bit overlapped registers for memory addressing
2002 "gpr x .16 26 0\n"
2003 "gpr y .16 28 0\n"
2004 "gpr z .16 30 0\n"
2005 // program counter
2006 // NOTE: program counter size in AVR depends on the CPU model. It seems that
2007 // the PC may range from 16 bits to 22 bits.
2008 "gpr pc .32 32 0\n"
2009 "gpr pcl .16 32 0\n"
2010 "gpr pch .16 34 0\n"
2011 // special purpose registers
2012 "gpr sp .16 36 0\n"
2013 "gpr spl .8 36 0\n"
2014 "gpr sph .8 37 0\n"
2015 // status bit register (SREG)
2016 "gpr sreg .8 38 0\n"
2017 "gpr cf .1 38.0 0\n" // Carry. This is a borrow flag on subtracts.
2018 "gpr zf .1 38.1 0\n" // Zero. Set to 1 when an arithmetic result is zero.
2019 "gpr nf .1 38.2 0\n" // Negative. Set to a copy of the most significant bit of an arithmetic result.
2020 "gpr vf .1 38.3 0\n" // Overflow flag. Set in case of two's complement overflow.
2021 "gpr sf .1 38.4 0\n" // Sign flag. Unique to AVR, this is always (N ^ V) (xor), and shows the true sign of a comparison.
2022 "gpr hf .1 38.5 0\n" // Half carry. This is an internal carry from additions and is used to support BCD arithmetic.
2023 "gpr tf .1 38.6 0\n" // Bit copy. Special bit load and bit store instructions use this bit.
2024 "gpr if .1 38.7 0\n" // Interrupt flag. Set when interrupts are enabled.
2025 // 8bit segment registers to be added to X, Y, Z to get 24bit offsets
2026 "gpr rampx .8 39 0\n"
2027 "gpr rampy .8 40 0\n"
2028 "gpr rampz .8 41 0\n"
2029 "gpr rampd .8 42 0\n"
2030 "gpr eind .8 43 0\n"
2031 // memory mapping emulator registers
2032 // _prog
2033 // the program flash. It has its own address space.
2034 // _ram
2035 // _io
2036 // start of the data addres space. It is the same address of IO,
2037 // because IO is the first memory space addressable in the AVR.
2038 // _sram
2039 // start of the SRAM (this offset depends on IO size, and it is
2040 // inside the _ram address space)
2041 // _eeprom
2042 // this is another address space, outside ram and flash
2043 // _page
2044 // this is the temporary page used by the SPM instruction. This
2045 // memory is not directly addressable and it is used internally by
2046 // the CPU when autoflashing.
2047 "gpr _prog .32 44 0\n"
2048 "gpr _page .32 48 0\n"
2049 "gpr _eeprom .32 52 0\n"
2050 "gpr _ram .32 56 0\n"
2051 "gpr _io .32 56 0\n"
2052 "gpr _sram .32 60 0\n"
2053 // other important MCU registers
2054 // spmcsr/spmcr
2055 // Store Program Memory Control and Status Register (SPMCSR)
2056 "gpr spmcsr .8 64 0\n"
2057 ;
2058
2059 return r_reg_set_profile_string (anal->reg, p);
2060 }
2061
archinfo(RAnal * anal,int q)2062 static int archinfo(RAnal *anal, int q) {
2063 if (q == R_ANAL_ARCHINFO_ALIGN) {
2064 return 2;
2065 }
2066 if (q == R_ANAL_ARCHINFO_MAX_OP_SIZE) {
2067 return 4;
2068 }
2069 if (q == R_ANAL_ARCHINFO_MIN_OP_SIZE) {
2070 return 2;
2071 }
2072 return 2; // XXX
2073 }
2074
anal_mask_avr(RAnal * anal,int size,const ut8 * data,ut64 at)2075 static ut8 *anal_mask_avr(RAnal *anal, int size, const ut8 *data, ut64 at) {
2076 RAnalOp *op = NULL;
2077 ut8 *ret = NULL;
2078 int idx;
2079
2080 if (!(op = r_anal_op_new ())) {
2081 return NULL;
2082 }
2083
2084 if (!(ret = malloc (size))) {
2085 r_anal_op_free (op);
2086 return NULL;
2087 }
2088
2089 memset (ret, 0xff, size);
2090
2091 CPU_MODEL *cpu = get_cpu_model (anal->cpu);
2092
2093 for (idx = 0; idx + 1 < size; idx += op->size) {
2094 OPCODE_DESC* opcode_desc = avr_op_analyze (anal, op, at + idx, data + idx, size - idx, cpu);
2095
2096 if (op->size < 1) {
2097 break;
2098 }
2099
2100 if (!opcode_desc) { // invalid instruction
2101 continue;
2102 }
2103
2104 // the additional data for "long" opcodes (4 bytes) is usually something we want to ignore for matching
2105 // (things like memory offsets or jump addresses)
2106 if (op->size == 4) {
2107 ret[idx + 2] = 0;
2108 ret[idx + 3] = 0;
2109 }
2110
2111 if (op->ptr != UT64_MAX || op->jump != UT64_MAX) {
2112 ret[idx] = opcode_desc->mask;
2113 ret[idx + 1] = opcode_desc->mask >> 8;
2114 }
2115 }
2116
2117 r_anal_op_free (op);
2118
2119 return ret;
2120 }
2121
2122 RAnalPlugin r_anal_plugin_avr = {
2123 .name = "avr",
2124 .desc = "AVR code analysis plugin",
2125 .license = "LGPL3",
2126 .arch = "avr",
2127 .esil = true,
2128 .archinfo = archinfo,
2129 .bits = 8 | 16, // 24 big regs conflicts
2130 .op = &avr_op,
2131 .set_reg_profile = &set_reg_profile,
2132 .esil_init = esil_avr_init,
2133 .esil_fini = esil_avr_fini,
2134 .anal_mask = anal_mask_avr,
2135 };
2136
2137 #ifndef R2_PLUGIN_INCORE
2138 R_API RLibStruct radare_plugin = {
2139 .type = R_LIB_TYPE_ANAL,
2140 .data = &r_anal_plugin_avr,
2141 .version = R2_VERSION
2142 };
2143 #endif
2144