8 #define IS_INDIRECT_ADDRESS_REGISTER(x) ((x)=='x'||(x)=='y'||(x)=='z')
10 #define throw_error(msg, ...) \
12 RZ_LOG_ERROR("[!] avr_assembler: " msg, ##__VA_ARGS__); \
13 return AVR_INVALID_SIZE; \
16 #define return_error_if_empty_input(a, b) \
18 if (RZ_STR_ISEMPTY(a) || b < 1) { \
19 RZ_LOG_ERROR("[!] avr_assembler: the input is empty.\n"); \
20 return AVR_INVALID_SIZE; \
24 #define expected_const_or_error(a,exp) \
26 if (RZ_STR_ISEMPTY((a)) || strcmp((a),(exp))) { \
27 RZ_LOG_ERROR("[!] avr_assembler: expected '%s' but got '%s'.\n", (exp), (a)); \
28 return AVR_INVALID_SIZE; \
32 #define parse_register_or_error_limit(rn,rs,min,max) \
38 if (RZ_STR_ISEMPTY(tmp)) { \
39 RZ_LOG_ERROR("[!] avr_assembler: invalid register '%s'.\n", (rs)); \
40 return AVR_INVALID_SIZE; \
42 (rn) = strtoll(tmp, NULL, 0); \
43 if ((rn) < (min) || (rn) > (max)) { \
44 RZ_LOG_ERROR("[!] avr_assembler: expected register %u <= reg <= 31 (parsed %u).\n", (min), (rn)); \
45 return AVR_INVALID_SIZE; \
49 #define parse_register_or_error(rn,rs) \
55 if (RZ_STR_ISEMPTY(tmp)) { \
56 RZ_LOG_ERROR("[!] avr_assembler: invalid register '%s'.\n", (rs)); \
57 return AVR_INVALID_SIZE; \
59 (rn) = strtoll(tmp, NULL, 0); \
61 RZ_LOG_ERROR("[!] avr_assembler: expected register 0 <= reg <= 31 (parsed %u).\n", (rn)); \
62 return AVR_INVALID_SIZE; \
67 #define parse_register_pair_or_error(rn,rs) \
73 if (RZ_STR_ISEMPTY(tmp)) { \
74 RZ_LOG_ERROR("[!] avr_assembler: invalid register '%s'.\n", (rs)); \
75 return AVR_INVALID_SIZE; \
77 (rn) = strtoll(tmp, (char **)&tmp, 0); \
79 RZ_LOG_ERROR("[!] avr_assembler: expected register 0 <= reg <= 31 (parsed %u).\n", (rn)); \
80 return AVR_INVALID_SIZE; \
88 (rn) = strtoll(tmp, NULL, 0); \
90 RZ_LOG_ERROR("[!] avr_assembler: expected register 0 <= reg <= 31 (parsed %u).\n", (rn)); \
91 return AVR_INVALID_SIZE; \
93 if (high != (rn) + 1) { \
94 RZ_LOG_ERROR("[!] avr_assembler: register pair r%u:r%u invalid: %u != %u + 1.\n", \
95 (unsigned int)high, (unsigned int)(rn), (unsigned int)high, (unsigned int)(rn)); \
96 return AVR_INVALID_SIZE; \
101 #define parse_unsigned_or_error(rn,rs,limit) \
105 if (tmp[0] == '$') { \
109 if (RZ_STR_ISEMPTY(tmp)) { \
110 RZ_LOG_ERROR("[!] avr_assembler: invalid unsigned number '%s'.\n", (rs)); \
111 return AVR_INVALID_SIZE; \
113 (rn) = strtoull(tmp, NULL, base); \
114 if ((rn) > (limit)) { \
115 RZ_LOG_ERROR("[!] avr_assembler: unsigned number '%s' >= %u.\n", (rs), limit); \
116 return AVR_INVALID_SIZE; \
120 #define parse_address_or_error(rn,rs,pc,llow,lhigh) \
123 if (RZ_STR_ISEMPTY(tmp)) { \
124 RZ_LOG_ERROR("[!] avr_assembler: invalid address '%s'.\n", (rs)); \
125 return AVR_INVALID_SIZE; \
127 if (tmp[0] == '.') { \
128 (rn) = (st64)strtoull(tmp + 1, NULL, 0); \
130 st64 abs = strtoull(tmp, NULL, 0); \
134 (rn) = ~(-((rn) - 1)); \
139 if (((rn) < (llow) || (rn) > (lhigh))) { \
140 RZ_LOG_ERROR("[!] avr_assembler: invalid address -64 <= addr <= 63 (parsed %d).\n", (rn)); \
141 return AVR_INVALID_SIZE; \
145 #define parse_signed_or_error(rn,rs,min,max) \
148 if (RZ_STR_ISEMPTY(tmp)) { \
149 RZ_LOG_ERROR("[!] avr_assembler: invalid unsigned number '%s'.\n", (rs)); \
150 return AVR_INVALID_SIZE; \
153 if ((rn) < (min)) { \
154 RZ_LOG_ERROR("[!] avr_assembler: signed number '%s' < %u.\n", (rs), min); \
155 return AVR_INVALID_SIZE; \
157 if ((rn) > (max)) { \
158 RZ_LOG_ERROR("[!] avr_assembler: signed number '%s' > %u.\n", (rs), max); \
159 return AVR_INVALID_SIZE; \
163 #define auto_write16(buf,val,be) \
166 rz_write_be16(buf, val); \
168 rz_write_le16(buf, val); \
196 cbins |= (Rr & 0x000F);
197 cbins |= ((Rr << 5) & 0x0200);
198 cbins |= ((Rd << 4) & 0x01F0);
211 if (Rd < 24 || Rd & 1) {
212 throw_error(
"register must be Rd = {24,26,28,30} (parsed r%u)\n", Rd);
218 cbins |= (K & 0x000F);
219 cbins |= ((K << 2) & 0x00C0);
220 cbins |= ((Rd << 4) & 0x0030);
235 cbins |= (K & 0x000F);
236 cbins |= ((K << 4) & 0x0F00);
237 cbins |= ((Rd << 4) & 0x00F0);
253 cbins |= (K & 0x000F);
254 cbins |= ((K << 4) & 0x0F00);
255 cbins |= ((Rd << 4) & 0x00F0);
266 cbins |= ((Rd << 4) & 0x01F0);
280 cbins |= (
b & 0x0007);
281 cbins |= ((Rd << 4) & 0x01F0);
292 cbins |= ((
k << 3) & 0x03F8);
306 ut16 kl =
k & 0xFFFF;
308 cbins |= (kh & 0x0001);
309 cbins |= ((kh << 3) & 0x01F0);
324 cbins |= (
b & 0x0007);
325 cbins |= ((
A << 3) & 0x00F8);
337 cbins |= (Rd & 0x000F);
338 cbins |= ((Rd << 5) & 0x0200);
339 cbins |= ((Rd << 4) & 0x01F0);
351 cbins |= ((K << 4) & 0x00F0);
363 }
else if (ntokens == 3) {
371 cbins |= ((Rd << 4) & 0x01F0);
372 }
else if (ntokens == 4) {
381 cbins |= ((Rd << 4) & 0x01F0);
383 throw_error(
"expected 'elpm' or 'elpm Rd, M' | 0 <= d <= 31 | M = {Z,Z+}\n");
399 cbins |= (Rr & 0x0007);
400 cbins |= ((Rd << 4) & 0x0070);
413 cbins |= (
A & 0x000F);
414 cbins |= ((
A << 5) & 0x0600);
415 cbins |= ((Rd << 4) & 0x01F0);
426 cbins |= ((Rd << 4) & 0x01F0);
440 if (!strcmp(tokens[2],
"x")) {
444 }
else if (!strcmp(tokens[2],
"y")) {
448 }
else if (!strcmp(tokens[2],
"z")) {
452 }
else if (!strcmp(tokens[2],
"-x")) {
456 }
else if (!strcmp(tokens[2],
"-y")) {
460 }
else if (!strcmp(tokens[2],
"-z")) {
465 throw_error(
"expected 'X' or 'Y' or 'Z' or '-X' or '-Y' or '-Z', but got '%s'\n", tokens[2]);
467 }
else if (ntokens == 4 && !strcmp(tokens[3],
"+")) {
468 if (!strcmp(tokens[2],
"x")) {
472 }
else if (!strcmp(tokens[2],
"y")) {
476 }
else if (!strcmp(tokens[2],
"z")) {
481 throw_error(
"expected 'X+' or 'Y+' or 'Z+', but got '%s+'\n", tokens[2]);
484 throw_error(
"expected ld Rd, M | 0 <= d <= 31 | M = {X,Y,Z,X+,Y+,Z+,-X,-Y,-Z}\n");
487 cbins |= ((Rd << 4) & 0x01F0);
499 if (!strcmp(tokens[3],
"+")) {
500 if (!strcmp(tokens[2],
"y")) {
504 }
else if (!strcmp(tokens[2],
"z")) {
509 throw_error(
"expected 'Y+' or 'Z+', but got '%s+'\n", tokens[2]);
512 throw_error(
"expected ldd Rd, M + q | 0 <= d <= 31 | M = {Y,Z} | 0 <= q <= 63\n");
516 cbins |= ((q << 7) & 0x0C00);
517 cbins |= ((q << 8) & 0x2000);
518 cbins |= ((Rd << 4) & 0x01F0);
535 if (k <= 127 && Rd >= 16) {
541 cbins |= ((
k << 4) & 0x0700);
542 cbins |= ((Rd << 4) & 0x00F0);
551 cbins |= ((Rd << 4) & 0x01F0);
563 }
else if (ntokens == 3) {
571 cbins |= ((Rd << 4) & 0x01F0);
572 }
else if (ntokens == 4) {
581 cbins |= ((Rd << 4) & 0x01F0);
583 throw_error(
"expected 'lpm' or 'lpm Rd, M' | 0 <= d <= 31 | M = {Z,Z+}\n");
595 cbins |= (
k & 0x0FFF);
609 throw_error(
"register must be even, Rd = {0,2,...,30} (parsed r%u)\n", Rd);
611 throw_error(
"register must be even, Rr = {0,2,...,30} (parsed r%u)\n", Rr);
616 cbins |= Rr & 0x000F;
617 cbins |= ((Rd << 4) & 0x00F0);
632 cbins |= Rr & 0x000F;
633 cbins |= ((Rd << 4) & 0x00F0);
646 cbins |= (
A & 0x000F);
647 cbins |= ((
A << 5) & 0x0600);
648 cbins |= ((Rd << 4) & 0x01F0);
661 cbins |= (
b & 0x0007);
662 cbins |= ((Rr << 4) & 0x01F0);
674 cbins |= ((Rd << 4) & 0x00F0);
686 }
else if (ntokens == 3) {
708 if (!strcmp(tokens[1],
"x")) {
712 }
else if (!strcmp(tokens[1],
"y")) {
716 }
else if (!strcmp(tokens[1],
"z")) {
720 }
else if (!strcmp(tokens[1],
"-x")) {
724 }
else if (!strcmp(tokens[1],
"-y")) {
728 }
else if (!strcmp(tokens[1],
"-z")) {
733 throw_error(
"expected 'X' or 'Y' or 'Z' or '-X' or '-Y' or '-Z', but got '%s'\n", tokens[1]);
735 }
else if (ntokens == 5 && !strcmp(tokens[2],
"+") && !strcmp(tokens[3],
"1")) {
736 if (!strcmp(tokens[1],
"x")) {
740 }
else if (!strcmp(tokens[1],
"y")) {
744 }
else if (!strcmp(tokens[1],
"z")) {
749 throw_error(
"expected 'X+' or 'Y+' or 'Z+', but got '%s+'\n", tokens[2]);
752 throw_error(
"expected st M, Rr | 0 <= r <= 31 | M = {X,Y,Z,-X,-Y,-Z}\n");
755 cbins |= ((Rr << 4) & 0x01F0);
768 if (!strcmp(tokens[1],
"x")) {
772 }
else if (!strcmp(tokens[1],
"y")) {
776 }
else if (!strcmp(tokens[1],
"z")) {
781 throw_error(
"expected 'X+' or 'Y+' or 'Z+', but got '%s+'\n", tokens[1]);
783 cbins |= ((Rr << 4) & 0x01F0);
787 }
else if (ntokens == 5) {
794 if (!strcmp(tokens[1],
"y")) {
798 }
else if (!strcmp(tokens[1],
"z")) {
803 throw_error(
"expected 'Y' or 'Z', but got '%s'\n", tokens[1]);
807 cbins |= ((q << 7) & 0x0C00);
808 cbins |= ((q << 8) & 0x2000);
809 cbins |= ((Rr << 4) & 0x01F0);
815 throw_error(
"expected std Rr, M + q | 0 <= d <= 31 | M = {Y,Z} | 0 <= q <= 63\n");
832 if (k <= 127 && Rr >= 16) {
838 cbins |= ((
k << 4) & 0x0700);
839 cbins |= ((Rr << 4) & 0x00F0);
848 cbins |= ((Rr << 4) & 0x01F0);
860 cbins |= ((
b << 4) & 0x0070);
873 cbins |= (
b & 0x0007);
874 cbins |= ((
k << 3) & 0x03F8);
914 {
"cbr" , 0x7000, 3, 3,
avr_cbr },
933 {
"elpm" , 0x0000, 1, 5,
avr_elpm },
946 {
"ld" , 0x0000, 3, 5,
avr_ld },
947 {
"ldd" , 0x0000, 5, 5,
avr_ldd },
949 {
"lds" , 0x0000, 3, 3,
avr_lds },
950 {
"lpm" , 0x0000, 1, 5,
avr_lpm },
990 {
"spm" , 0x0000, 1, 5,
avr_spm },
991 {
"st" , 0x0000, 3, 5,
avr_st },
992 {
"std" , 0x0000, 4, 5,
avr_std },
993 {
"sts" , 0x0000, 3, 3,
avr_sts },
1017 for (
st32 i = 0;
i < input_size; ++
i) {
1018 if (cinput[
i] ==
',') {
1062 tokens[
count] = copy;
1090 if (!tokens || ntokens < 1) {
1091 RZ_LOG_ERROR(
"[!] avr_assembler: invalid assembly.\n");
1092 goto avr_assembler_end;
1100 if (ntokens < mintoks || ntokens > maxtoks) {
1101 RZ_LOG_ERROR(
"[!] avr_assembler: '%s' requires %u <= ntokens <= %u, but %u tokens was provided.\n", tokens[0], mintoks, maxtoks, ntokens);
1102 goto avr_assembler_end;
static ut32 avr_ld(ut16 cbins, cchar **tokens, ut32 ntokens, ut8 *data, ut64 pc, bool be)
static ut32 avr_cbr(ut16 cbins, cchar **tokens, ut32 ntokens, ut8 *data, ut64 pc, bool be)
static ut32 avr_dddcrrr(ut16 cbins, cchar **tokens, ut32 ntokens, ut8 *data, ut64 pc, bool be)
#define parse_address_or_error(rn, rs, pc, llow, lhigh)
static ut32 avr_KKKKcccc(ut16 cbins, cchar **tokens, ut32 ntokens, ut8 *data, ut64 pc, bool be)
static ut32 avr_lpm(ut16 cbins, cchar **tokens, ut32 ntokens, ut8 *data, ut64 pc, bool be)
static ut32 avr_AAdddddAAAA(ut16 cbins, cchar **tokens, ut32 ntokens, ut8 *data, ut64 pc, bool be)
static const AvrInstruction instructions[]
static ut32 avr_rdddddrrrr(ut16 cbins, cchar **tokens, ut32 ntokens, ut8 *data, ut64 pc, bool be)
#define parse_unsigned_or_error(rn, rs, limit)
static ut32 avr_st(ut16 cbins, cchar **tokens, ut32 ntokens, ut8 *data, ut64 pc, bool be)
static void sanitize_input(char *cinput, st32 input_size)
static ut32 avr_kkkkkkkccc(ut16 cbins, cchar **tokens, ut32 ntokens, ut8 *data, ut64 pc, bool be)
static ut32 avr_lds(ut16 cbins, cchar **tokens, ut32 ntokens, ut8 *data, ut64 pc, bool be)
ut32(* Encode)(ut16 cbins, cchar **tokens, ut32 ntokens, ut8 *data, ut64 pc, bool be)
static ut32 avr_rrrrrcbbb(ut16 cbins, cchar **tokens, ut32 ntokens, ut8 *data, ut64 pc, bool be)
static void tokens_free(char **tokens)
static ut32 avr_AAAAAbbb(ut16 cbins, cchar **tokens, ut32 ntokens, ut8 *data, ut64 pc, bool be)
#define return_error_if_empty_input(a, b)
static ut32 avr_ldd(ut16 cbins, cchar **tokens, ut32 ntokens, ut8 *data, ut64 pc, bool be)
static char * strdup_limit(cchar *begin, cchar *end)
ut32 avr_assembler(const char *input, st32 input_size, ut8 *output, st32 output_size, ut64 pc, bool be)
static ut32 avr_ssscccc(ut16 cbins, cchar **tokens, ut32 ntokens, ut8 *data, ut64 pc, bool be)
#define auto_write16(buf, val, be)
#define expected_const_or_error(a, exp)
#define parse_register_or_error_limit(rn, rs, min, max)
static ut32 avr_std(ut16 cbins, cchar **tokens, ut32 ntokens, ut8 *data, ut64 pc, bool be)
static ut32 avr_elpm(ut16 cbins, cchar **tokens, ut32 ntokens, ut8 *data, ut64 pc, bool be)
static ut32 avr_kkkkkkksss(ut16 cbins, cchar **tokens, ut32 ntokens, ut8 *data, ut64 pc, bool be)
static ut32 avr_unique(ut16 cbins, cchar **tokens, ut32 ntokens, ut8 *data, ut64 pc, bool be)
static ut32 avr_dddddcbbb(ut16 cbins, cchar **tokens, ut32 ntokens, ut8 *data, ut64 pc, bool be)
static ut32 avr_ddddcccc(ut16 cbins, cchar **tokens, ut32 ntokens, ut8 *data, ut64 pc, bool be)
static char ** tokens_new(cchar *input, st32 input_size, ut32 *ntokens)
static ut32 avr_ddddrrrr(ut16 cbins, cchar **tokens, ut32 ntokens, ut8 *data, ut64 pc, bool be)
static ut32 avr_rrrrrcccc(ut16 cbins, cchar **tokens, ut32 ntokens, ut8 *data, ut64 pc, bool be)
#define throw_error(msg,...)
static ut32 avr_KKKKddddKKKK(ut16 cbins, cchar **tokens, ut32 ntokens, ut8 *data, ut64 pc, bool be)
#define parse_register_or_error(rn, rs)
static ut32 avr_ddddrrrr_2x(ut16 cbins, cchar **tokens, ut32 ntokens, ut8 *data, ut64 pc, bool be)
static ut32 avr_kkkkkccck(ut16 cbins, cchar **tokens, ut32 ntokens, ut8 *data, ut64 pc, bool be)
struct avr_decoder_t AvrInstruction
static ut32 avr_AArrrrrAAAA(ut16 cbins, cchar **tokens, ut32 ntokens, ut8 *data, ut64 pc, bool be)
static ut32 avr_kkkkkkkkkkkk(ut16 cbins, cchar **tokens, ut32 ntokens, ut8 *data, ut64 pc, bool be)
static ut32 avr_dddddddddd(ut16 cbins, cchar **tokens, ut32 ntokens, ut8 *data, ut64 pc, bool be)
#define parse_register_pair_or_error(rn, rs)
Parse things like "r25:r24" or just "r24". Result would be 24 in both cases.
static ut32 avr_KKddKKKK(ut16 cbins, cchar **tokens, ut32 ntokens, ut8 *data, ut64 pc, bool be)
static ut32 avr_sts(ut16 cbins, cchar **tokens, ut32 ntokens, ut8 *data, ut64 pc, bool be)
static ut32 avr_dddddcccc(ut16 cbins, cchar **tokens, ut32 ntokens, ut8 *data, ut64 pc, bool be)
static ut32 avr_spm(ut16 cbins, cchar **tokens, ut32 ntokens, ut8 *data, ut64 pc, bool be)
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void count
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len static semflg const void static shmflg const struct timespec struct timespec static rem const char static group const void start
RZ_API void Ht_() free(HtName_(Ht) *ht)
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
void * malloc(size_t size)
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")
#define rz_warn_if_reached()
#define rz_warn_if_fail(expr)
#define RZ_LOG_ERROR(fmtstr,...)
RZ_API int rz_str_casecmp(const char *dst, const char *orig)
RZ_API const char * rz_str_trim_head_wp(const char *str)
RZ_API const char * rz_str_trim_head_ro(const char *str)
Definitions common to the whole liblzma library.
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
static bool input(void *ud, zip_uint8_t *data, zip_uint64_t length)