Rizin
unix-like reverse engineering framework and cli tools
hexagon_arch.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2021 Rot127 <unisono@quyllur.org>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 // LLVM commit: 96e220e6886868d6663d966ecc396befffc355e7
5 // LLVM commit date: 2022-01-05 11:01:52 +0000 (ISO 8601 format)
6 // Date of code generation: 2022-04-02 06:41:46-04:00
7 //========================================
8 // The following code is generated.
9 // Do not edit. Repository of code generator:
10 // https://github.com/rizinorg/rz-hexagon
11 
12 #include <rz_asm.h>
13 #include <rz_analysis.h>
14 #include <rz_util.h>
15 #include "hexagon.h"
16 #include "hexagon_insn.h"
17 #include "hexagon_arch.h"
18 
19 static inline bool is_last_instr(const ut8 parse_bits) {
20  // Duplex instr. (parse bits = 0) are always the last.
21  return ((parse_bits == 0x3) || (parse_bits == 0x0));
22 }
23 
32 static inline bool is_endloop0_pkt(const ut8 pb_hi_0, const ut8 pb_hi_1) {
33  return ((pb_hi_0 == 0x2) && ((pb_hi_1 == 0x1) || (pb_hi_1 == 0x3)));
34 }
35 
45 static inline bool is_undoc_endloop0_pkt(const ut8 pb_hi_0, const ut8 pb_hi_1) {
46  return ((pb_hi_0 == 0x2) && (pb_hi_1 == 0x0));
47 }
48 
57 static inline bool is_endloop1_pkt(const ut8 pb_hi_0, const ut8 pb_hi_1) {
58  return ((pb_hi_0 == 0x1) && (pb_hi_1 == 0x2));
59 }
60 
69 static inline bool is_endloop01_pkt(const ut8 pb_hi_0, const ut8 pb_hi_1) {
70  return ((pb_hi_0 == 0x2) && (pb_hi_1 == 0x2));
71 }
72 
81  HexPkt *p;
82  for (ut8 i = 0; i < HEXAGON_STATE_PKTS; ++i) {
83  p = &state->pkts[i];
84  HexInsn *pi = NULL;
85  RzListIter *iter = NULL;
86  rz_list_foreach (p->insn, iter, pi) {
87  if (addr == pi->addr) {
88  p->last_access = rz_time_now();
89  return pi;
90  }
91  }
92  }
93  return NULL;
94 }
95 
105 
106  HexInsn *hi = NULL;
107  RzListIter *it = NULL;
108  ut8 i = 0;
109  rz_list_foreach (p->insn, it, hi) {
110  if (hi->addr == addr) {
111  return i;
112  }
113  ++i;
114  }
115  return UT8_MAX;
116 }
117 
124  p->last_instr_present = false;
125  p->is_valid = false;
126  p->last_access = 0;
127  rz_list_purge(p->insn);
128 }
129 
137  HexPkt *stale_state_pkt = &state->pkts[0];
138  ut64 oldest = UT64_MAX;
139 
140  for (ut8 i = 0; i < HEXAGON_STATE_PKTS; ++i) {
141  if (state->pkts[i].last_access < oldest) {
142  stale_state_pkt = &state->pkts[i];
143  }
144  }
145  return stale_state_pkt;
146 }
147 
156  HexPkt *p = NULL;
157  HexInsn *pi = NULL;
158  RzListIter *iter = NULL;
159  for (ut8 i = 0; i < HEXAGON_STATE_PKTS; ++i) {
160  p = &state->pkts[i];
161  rz_list_foreach (p->insn, iter, pi) {
162  if (addr == pi->addr) {
163  return p;
164  }
165  }
166  }
167  return NULL;
168 }
169 
176  if (!i) {
177  return;
178  }
179  free(i);
180 }
181 
188  if (!ce) {
189  return;
190  }
191  free(ce);
192 }
193 
202  HexPkt *sp;
203  for (ut8 i = 0; i < HEXAGON_STATE_PKTS; ++i) {
204  sp = &state->pkts[i];
205  if (sp->pkt_addr == p->pkt_addr) {
206  return i;
207  }
208  }
209  return UT8_MAX;
210 }
211 
218  static HexState *state = NULL;
219  if (state) {
220  return state;
221  }
222 
223  state = calloc(1, sizeof(HexState));
224  if (!state) {
225  RZ_LOG_FATAL("Could not allocate memory for HexState!");
226  }
227  for (int i = 0; i < HEXAGON_STATE_PKTS; ++i) {
228  state->pkts[i].insn = rz_list_newf((RzListFree)hex_insn_free);
229  if (!state->pkts[i].insn) {
230  RZ_LOG_FATAL("Could not initialize instruction list!");
231  }
232  hex_clear_pkt(&(state->pkts[i]));
233  }
235  return state;
236 }
237 
245 static inline bool is_pkt_full(const HexPkt *p) {
246  return rz_list_length(p->insn) >= 4;
247 }
248 
262 static char *get_pkt_indicator(const bool utf8, const bool sdk, const bool prefix, HexPktSyntaxIndicator ind_type) {
263  switch (ind_type) {
264  default:
265  return "";
266  case SINGLE_IN_PKT:
267  if (prefix) {
268  if (sdk) {
269  return HEX_PKT_FIRST_SDK;
270  } else {
271  return utf8 ? HEX_PKT_SINGLE_UTF8 : HEX_PKT_SINGLE;
272  }
273  } else {
274  if (sdk) {
275  return HEX_PKT_LAST_SDK;
276  }
277  }
278  break;
279  case FIRST_IN_PKT:
280  if (!prefix) {
281  break;
282  }
283  if (sdk) {
284  return HEX_PKT_FIRST_SDK;
285  }
286  if (utf8) {
287  return HEX_PKT_FIRST_UTF8;
288  } else {
289  return HEX_PKT_FIRST;
290  }
291  break;
292  case MID_IN_PKT:
293  if (!prefix) {
294  break;
295  }
296  if (sdk) {
297  return HEX_PKT_SDK_PADDING;
298  }
299  if (utf8) {
300  return HEX_PKT_MID_UTF8;
301  } else {
302  return HEX_PKT_MID;
303  }
304  break;
305  case LAST_IN_PKT:
306  if (prefix) {
307  if (sdk) {
308  return HEX_PKT_SDK_PADDING;
309  }
310  if (utf8) {
311  return HEX_PKT_LAST_UTF8;
312  } else {
313  return HEX_PKT_LAST;
314  }
315  } else {
316  if (sdk) {
317  return HEX_PKT_LAST_SDK;
318  }
319  }
320  break;
321  case ELOOP_0_PKT:
322  if (prefix) {
323  break;
324  }
325  if (sdk) {
326  return HEX_PKT_ELOOP_0_SDK;
327  }
328  if (utf8) {
329  return HEX_PKT_ELOOP_0_UTF8;
330  } else {
331  return HEX_PKT_ELOOP_0;
332  }
333  break;
334  case ELOOP_1_PKT:
335  if (prefix) {
336  break;
337  }
338  if (sdk) {
339  return HEX_PKT_ELOOP_1_SDK;
340  }
341  if (utf8) {
342  return HEX_PKT_ELOOP_1_UTF8;
343  } else {
344  return HEX_PKT_ELOOP_1;
345  }
346  break;
347  case ELOOP_01_PKT:
348  if (prefix) {
349  break;
350  }
351  if (sdk) {
352  return HEX_PKT_ELOOP_01_SDK;
353  }
354  if (utf8) {
355  return HEX_PKT_ELOOP_01_UTF8;
356  } else {
357  return HEX_PKT_ELOOP_01;
358  }
359  break;
360  }
361  return "";
362 }
363 
371 static void hex_set_pkt_info(const RzAsm *rz_asm, RZ_INOUT HexInsn *hi, const HexPkt *p, const ut8 k, const bool update_mnemonic) {
372  rz_return_if_fail(hi && p);
373  bool is_first = (k == 0);
374  HexPktInfo *hi_pi = &hi->pkt_info;
376  bool sdk_form = rz_config_get_b(state->cfg, "plugins.hexagon.sdk");
377 
378  strncpy(hi_pi->mnem_postfix, "", 16);
379  // Parse instr. position in pkt
380  if (is_first && is_last_instr(hi->parse_bits)) { // Single instruction packet.
381  hi_pi->first_insn = true;
382  hi_pi->last_insn = true;
383  if (p->is_valid) {
384  strncpy(hi_pi->mnem_prefix, get_pkt_indicator(rz_asm->utf8, sdk_form, true, SINGLE_IN_PKT), 8);
385  if (sdk_form) {
386  strncpy(hi_pi->mnem_postfix, get_pkt_indicator(rz_asm->utf8, sdk_form, false, SINGLE_IN_PKT), 8);
387  }
388  } else {
389  strncpy(hi_pi->mnem_prefix, HEX_PKT_UNK, 8);
390  }
391  } else if (is_first) {
392  hi_pi->first_insn = true;
393  hi_pi->last_insn = false;
394  if (p->is_valid) {
395  strncpy(hi_pi->mnem_prefix, get_pkt_indicator(rz_asm->utf8, sdk_form, true, FIRST_IN_PKT), 8);
396  } else {
397  strncpy(hi_pi->mnem_prefix, HEX_PKT_UNK, 8);
398  }
399  } else if (is_last_instr(hi->parse_bits)) {
400  hi_pi->first_insn = false;
401  hi_pi->last_insn = true;
402  if (p->is_valid) {
403  strncpy(hi_pi->mnem_prefix, get_pkt_indicator(rz_asm->utf8, sdk_form, true, LAST_IN_PKT), 8);
404  if (sdk_form) {
405  strncpy(hi_pi->mnem_postfix, get_pkt_indicator(rz_asm->utf8, sdk_form, false, LAST_IN_PKT), 8);
406  }
407 
408  switch (hex_get_loop_flag(p)) {
409  default:
410  break;
411  case HEX_LOOP_01:
412  strncat(hi_pi->mnem_postfix, get_pkt_indicator(rz_asm->utf8, sdk_form, false, ELOOP_01_PKT), 23 - strlen(hi_pi->mnem_postfix));
413  break;
414  case HEX_LOOP_0:
415  strncat(hi_pi->mnem_postfix, get_pkt_indicator(rz_asm->utf8, sdk_form, false, ELOOP_0_PKT), 23 - strlen(hi_pi->mnem_postfix));
416  break;
417  case HEX_LOOP_1:
418  strncat(hi_pi->mnem_postfix, get_pkt_indicator(rz_asm->utf8, sdk_form, false, ELOOP_1_PKT), 23 - strlen(hi_pi->mnem_postfix));
419  break;
420  }
421  } else {
422  strncpy(hi_pi->mnem_prefix, HEX_PKT_UNK, 8);
423  }
424  } else {
425  hi_pi->first_insn = false;
426  hi_pi->last_insn = false;
427  if (p->is_valid) {
428  strncpy(hi_pi->mnem_prefix, get_pkt_indicator(rz_asm->utf8, sdk_form, true, MID_IN_PKT), 8);
429  } else {
430  strncpy(hi_pi->mnem_prefix, HEX_PKT_UNK, 8);
431  }
432  }
433  if (update_mnemonic) {
434  sprintf(hi->mnem, "%s%s%s", hi_pi->mnem_prefix, hi->mnem_infix, hi_pi->mnem_postfix);
435  }
436 }
437 
447  if (!p || rz_list_length(p->insn) < 2) {
448  return HEX_NO_LOOP;
449  }
450 
451  ut8 pb_0 = ((HexInsn *)rz_list_get_n(p->insn, 0))->parse_bits;
452  ut8 pb_1 = ((HexInsn *)rz_list_get_n(p->insn, 1))->parse_bits;
453 
454  if (is_endloop0_pkt(pb_0, pb_1)) {
455  return HEX_LOOP_0;
456  } else if (is_endloop1_pkt(pb_0, pb_1)) {
457  return HEX_LOOP_1;
458  } else if (is_endloop01_pkt(pb_0, pb_1)) {
459  return HEX_LOOP_01;
460  } else if (is_undoc_endloop0_pkt(pb_0, pb_1)) {
461  RZ_LOG_VERBOSE("Undocumented hardware loop 0 endloop packet.");
462  return HEX_LOOP_0;
463  } else {
464  return HEX_NO_LOOP;
465  }
466 }
467 
474 static void make_next_packet_valid(HexState *state, const HexPkt *pkt) {
475  HexInsn *tmp = rz_list_get_top(pkt->insn);
476  if (!tmp) {
477  return;
478  }
479  ut32 pkt_addr = tmp->addr + 4;
480 
481  HexPkt *p;
482  for (int i = 0; i < HEXAGON_STATE_PKTS; ++i) {
483  p = &state->pkts[i];
484  if (p->pkt_addr == pkt_addr) {
485  if (p->is_valid) {
486  break;
487  }
488  p->is_valid = true;
489  HexInsn *hi = NULL;
490  RzListIter *it = NULL;
491  ut8 k = 0;
492  rz_list_foreach (p->insn, it, hi) {
493  hex_set_pkt_info(&state->rz_asm, hi, p, k, true);
494  ++k;
495  }
496  p->last_access = rz_time_now();
497  break;
498  }
499  }
500 }
501 
508  HexInsn *hi = calloc(1, sizeof(HexInsn));
509  if (!hi) {
510  RZ_LOG_FATAL("Could not allocate memory for new instruction.\n");
511  }
512 
513  return hi;
514 }
515 
525 static HexInsn *hex_add_to_pkt(HexState *state, const HexInsn *new_ins, RZ_INOUT HexPkt *p, const ut8 k) {
526  if (k > 3) {
527  RZ_LOG_FATAL("Instruction could not be set! A packet can only hold four instructions but k=%d.", k);
528  }
529  HexInsn *hi = alloc_instr();
530  memcpy(hi, new_ins, sizeof(HexInsn));
531  rz_list_insert(p->insn, k, hi);
532 
533  if (k == 0) {
534  p->pkt_addr = hi->addr;
535  }
536  p->last_instr_present |= is_last_instr(hi->parse_bits);
537  ut32 p_l = rz_list_length(p->insn);
538  hex_set_pkt_info(&state->rz_asm, hi, p, k, false);
539  if (k == 0 && p_l > 1) {
540  // Update the instruction which was previously the first one.
541  hex_set_pkt_info(&state->rz_asm, rz_list_get_n(p->insn, 1), p, 1, true);
542  }
543  p->last_access = rz_time_now();
544  if (p->last_instr_present) {
546  }
547  return hi;
548 }
549 
559 static HexInsn *hex_to_new_pkt(HexState *state, const HexInsn *new_ins, const HexPkt *p, RZ_INOUT HexPkt *new_p) {
560  hex_clear_pkt(new_p);
561 
562  HexInsn *hi = alloc_instr();
563  memcpy(hi, new_ins, sizeof(HexInsn));
564  rz_list_insert(new_p->insn, 0, hi);
565 
566  new_p->last_instr_present |= is_last_instr(hi->parse_bits);
567  new_p->hw_loop0_addr = p->hw_loop0_addr;
568  new_p->hw_loop1_addr = p->hw_loop1_addr;
569  new_p->is_valid = (p->is_valid || p->last_instr_present);
570  new_p->pkt_addr = hi->addr;
571  new_p->last_access = rz_time_now();
572  hex_set_pkt_info(&state->rz_asm, hi, new_p, 0, false);
573  if (new_p->last_instr_present) {
575  }
576  return hi;
577 }
578 
586 static HexInsn *hex_add_to_stale_pkt(HexState *state, const HexInsn *new_ins) {
588  hex_clear_pkt(p);
589 
590  HexInsn *hi = alloc_instr();
591  memcpy(hi, new_ins, sizeof(HexInsn));
592  rz_list_insert(p->insn, 0, hi);
593 
594  p->last_instr_present |= is_last_instr(hi->parse_bits);
595  p->pkt_addr = new_ins->addr;
596  // p->is_valid = true; // Setting it true also detects a lot of data as valid assembly.
597  p->last_access = rz_time_now();
598  hex_set_pkt_info(&state->rz_asm, hi, p, 0, false);
599  if (p->last_instr_present) {
601  }
602  return hi;
603 }
604 
616  if (!new_ins) {
617  return NULL;
618  }
619  bool add_to_pkt = false;
620  bool new_pkt = false;
621  bool write_to_stale_pkt = false;
622  bool insert_before_pkt_hi = false;
623  ut8 k = 0; // New instruction position in packet.
624 
625  HexPkt *p;
626  if (new_ins->addr == 0x0) {
627  return hex_add_to_stale_pkt(state, new_ins);
628  }
629 
630  for (ut8 i = 0; i < HEXAGON_STATE_PKTS; ++i, k = 0) {
631  p = &(state->pkts[i]);
632 
633  HexInsn *pkt_instr = NULL; // Instructions already in the packet.
634  RzListIter *iter = NULL;
635  rz_list_foreach (p->insn, iter, pkt_instr) {
636  if (new_ins->addr == (pkt_instr->addr - 4)) {
637  // Instruction preceeds one in the packet.
638  if (is_last_instr(new_ins->parse_bits) || is_pkt_full(p)) {
639  write_to_stale_pkt = true;
640  break;
641  } else {
642  insert_before_pkt_hi = true;
643  add_to_pkt = true;
644  break;
645  }
646  } else if (new_ins->addr == (pkt_instr->addr + 4)) {
647  if (is_last_instr(pkt_instr->parse_bits) || is_pkt_full(p)) {
648  new_pkt = true;
649  break;
650  } else {
651  add_to_pkt = true;
652  break;
653  }
654  }
655  ++k;
656  }
657  if (add_to_pkt || new_pkt || write_to_stale_pkt) {
658  break;
659  }
660  }
661 
662  // Add the instruction to packet p
663  if (add_to_pkt) {
664  if (insert_before_pkt_hi) {
665  return hex_add_to_pkt(state, new_ins, p, k);
666  }
667  return hex_add_to_pkt(state, new_ins, p, k + 1);
668 
669  } else if (new_pkt) {
671  return hex_to_new_pkt(state, new_ins, p, &state->pkts[ni]);
672  } else {
673  return hex_add_to_stale_pkt(state, new_ins);
674  }
675 }
676 
685 static void setup_new_instr(HexInsn *hi, const HexReversedOpcode *rz_reverse, const ut32 addr, const ut8 parse_bits) {
686  hi->instruction = HEX_INS_INVALID_DECODE;
687  hi->addr = addr;
688  hi->parse_bits = parse_bits;
689  if (rz_reverse->asm_op) {
690  memcpy(&(hi->asm_op), rz_reverse->asm_op, sizeof(RzAsmOp));
691  }
692  if (rz_reverse->ana_op) {
693  memcpy(&(hi->ana_op), rz_reverse->ana_op, sizeof(RzAnalysisOp));
694  }
695 
696  hi->ana_op.val = UT64_MAX;
697  for (ut8 i = 0; i < 6; ++i) {
698  hi->ana_op.analysis_vals[i].imm = ST64_MAX;
699  }
700  hi->ana_op.jump = UT64_MAX;
701  hi->ana_op.fail = UT64_MAX;
702  hi->ana_op.ptr = UT64_MAX;
703 
704  hi->asm_op.size = 4;
705  hi->ana_op.size = 4;
706 }
707 
708 static inline bool imm_is_scaled(const HexOpAttr attr) {
709  return (attr & HEX_OP_IMM_SCALED);
710 }
711 
719 static HexConstExt *get_const_ext_from_addr(const RzList *ce_list, const ut32 addr) {
720  HexConstExt *ce = NULL;
721  RzListIter *iter = NULL;
722  rz_list_foreach (ce_list, iter, ce) {
723  if (addr == ce->addr) {
724  return ce;
725  }
726  }
727  return NULL;
728 }
729 
738 RZ_API void hex_extend_op(HexState *state, RZ_INOUT HexOp *op, const bool set_new_extender, const ut32 addr) {
739  if (rz_list_length(state->const_ext_l) > MAX_CONST_EXT) {
740  rz_list_purge(state->const_ext_l);
741  }
742 
743  if (op->type != HEX_OP_TYPE_IMM) {
744  return;
745  }
746 
747  HexConstExt *ce;
748  if (set_new_extender) {
749  ce = calloc(1, sizeof(HexConstExt));
750  ce->addr = addr + 4;
751  ce->const_ext = op->op.imm;
752  rz_list_append(state->const_ext_l, ce);
753  return;
754  }
755 
756  ce = get_const_ext_from_addr(state->const_ext_l, addr);
757  if (ce) {
758  op->op.imm = imm_is_scaled(op->attr) ? (op->op.imm >> op->shift) : op->op.imm;
759  op->op.imm = ((op->op.imm & 0x3F) | ce->const_ext);
760  rz_list_delete_data(state->const_ext_l, ce);
761  return;
762  }
763 }
764 
772 RZ_API void hexagon_reverse_opcode(const RzAsm *rz_asm, HexReversedOpcode *rz_reverse, const ut8 *buf, const ut64 addr) {
774  if (!state) {
775  RZ_LOG_FATAL("HexState was NULL.");
776  }
777  if (rz_asm) {
778  memcpy(&state->rz_asm, rz_asm, sizeof(RzAsm));
779  }
781  if (hi) {
782  // Opcode was already reversed and is still in the state. Copy the result and return.
783  switch (rz_reverse->action) {
784  default:
785  memcpy(rz_reverse->asm_op, &(hi->asm_op), sizeof(RzAsmOp));
786  memcpy(rz_reverse->ana_op, &(hi->ana_op), sizeof(RzAnalysisOp));
787  rz_strbuf_set(&rz_reverse->asm_op->buf_asm, hi->mnem);
788  rz_reverse->asm_op->asm_toks = rz_asm_tokenize_asm_regex(&rz_reverse->asm_op->buf_asm, state->token_patterns);
789  rz_reverse->asm_op->asm_toks->op_type = hi->ana_op.type;
790  return;
791  case HEXAGON_DISAS:
792  memcpy(rz_reverse->asm_op, &(hi->asm_op), sizeof(RzAsmOp));
793  rz_strbuf_set(&rz_reverse->asm_op->buf_asm, hi->mnem);
794  rz_reverse->asm_op->asm_toks = rz_asm_tokenize_asm_regex(&rz_reverse->asm_op->buf_asm, state->token_patterns);
795  rz_reverse->asm_op->asm_toks->op_type = hi->ana_op.type;
796  return;
797  case HEXAGON_ANALYSIS:
798  memcpy(rz_reverse->ana_op, &(hi->ana_op), sizeof(RzAnalysisOp));
799  return;
800  }
801  }
802 
803  ut32 data = rz_read_le32(buf);
804  ut8 parse_bits = (data & 0x0000c000) >> 14;
805  HexInsn instr = { 0 };
806  setup_new_instr(&instr, rz_reverse, addr, parse_bits);
807  // Add to state
808  hi = hex_add_instr_to_state(state, &instr);
809  if (!hi) {
810  return;
811  }
812  HexPkt *p = hex_get_pkt(state, hi->addr);
813 
814  // Do disasassembly and analysis
816 
817  switch (rz_reverse->action) {
818  default:
819  memcpy(rz_reverse->asm_op, &hi->asm_op, sizeof(RzAsmOp));
820  memcpy(rz_reverse->ana_op, &hi->ana_op, sizeof(RzAnalysisOp));
821  rz_strbuf_set(&rz_reverse->asm_op->buf_asm, hi->mnem);
822  rz_reverse->asm_op->asm_toks = rz_asm_tokenize_asm_regex(&rz_reverse->asm_op->buf_asm, state->token_patterns);
823  rz_reverse->asm_op->asm_toks->op_type = hi->ana_op.type;
824  break;
825  case HEXAGON_DISAS:
826  memcpy(rz_reverse->asm_op, &hi->asm_op, sizeof(RzAsmOp));
827  rz_strbuf_set(&rz_reverse->asm_op->buf_asm, hi->mnem);
828  rz_reverse->asm_op->asm_toks = rz_asm_tokenize_asm_regex(&rz_reverse->asm_op->buf_asm, state->token_patterns);
829  rz_reverse->asm_op->asm_toks->op_type = hi->ana_op.type;
830  break;
831  case HEXAGON_ANALYSIS:
832  memcpy(rz_reverse->ana_op, &hi->ana_op, sizeof(RzAnalysisOp));
833  break;
834  }
835 }
lzma_index ** i
Definition: index.h:629
RZ_API RZ_OWN RzAsmTokenString * rz_asm_tokenize_asm_regex(RZ_BORROW RzStrBuf *asm_str, RzPVector *patterns)
Splits an asm string into tokens by using the given regex patterns.
Definition: asm.c:1472
RZ_API bool rz_config_get_b(RzConfig *cfg, RZ_NONNULL const char *name)
Definition: config.c:142
#define RZ_API
#define NULL
Definition: cris-opc.c:27
uint32_t ut32
const char * k
Definition: dsignal.c:11
unsigned short prefix[65536]
Definition: gun.c:163
int hexagon_disasm_instruction(HexState *state, const ut32 hi_u32, RZ_INOUT HexInsn *hi, HexPkt *pkt)
@ HEX_OP_TYPE_IMM
Definition: hexagon.h:55
#define HEXAGON_STATE_PKTS
Definition: hexagon.h:25
HexOpAttr
Definition: hexagon.h:61
@ HEX_OP_IMM_SCALED
Definition: hexagon.h:68
HexLoopAttr
Definition: hexagon.h:71
@ HEX_NO_LOOP
Definition: hexagon.h:72
@ HEX_LOOP_0
Definition: hexagon.h:73
@ HEX_LOOP_1
Definition: hexagon.h:74
@ HEX_LOOP_01
Definition: hexagon.h:75
#define MAX_CONST_EXT
Definition: hexagon.h:24
RZ_API void hex_insn_free(RZ_NULLABLE HexInsn *i)
Frees an instruction.
Definition: hexagon_arch.c:175
RZ_API void hex_const_ext_free(RZ_NULLABLE HexConstExt *ce)
Frees an constant extender.
Definition: hexagon_arch.c:187
static HexPkt * hex_get_pkt(HexState *state, const ut32 addr)
Returns the packet which covers the given address.
Definition: hexagon_arch.c:155
static HexInsn * hex_get_instr_at_addr(HexState *state, const ut32 addr)
Gives the instruction at a given address from the state.
Definition: hexagon_arch.c:80
RZ_API HexLoopAttr hex_get_loop_flag(const HexPkt *p)
Returns the loop type of a packet. Though only if this packet is the last packet in last packet in a ...
Definition: hexagon_arch.c:446
static bool is_endloop0_pkt(const ut8 pb_hi_0, const ut8 pb_hi_1)
Checks if packet ends hardware loop 0.
Definition: hexagon_arch.c:32
RZ_API void hexagon_reverse_opcode(const RzAsm *rz_asm, HexReversedOpcode *rz_reverse, const ut8 *buf, const ut64 addr)
Reverses a given opcode and copies the result into one of the rizin structs in rz_reverse.
Definition: hexagon_arch.c:772
static HexPkt * hex_get_stale_pkt(HexState *state)
Gives the least used packet.
Definition: hexagon_arch.c:136
static char * get_pkt_indicator(const bool utf8, const bool sdk, const bool prefix, HexPktSyntaxIndicator ind_type)
Get the pkt indicator string.
Definition: hexagon_arch.c:262
RZ_API ut8 hexagon_get_pkt_index_of_addr(const ut32 addr, const HexPkt *p)
Returns the index of an addr in a given packet.
Definition: hexagon_arch.c:103
static ut8 get_state_pkt_index(HexState *state, const HexPkt *p)
Get the index of a packet in the state.
Definition: hexagon_arch.c:201
static bool is_endloop1_pkt(const ut8 pb_hi_0, const ut8 pb_hi_1)
Checks if packet ends hardware loop 1.
Definition: hexagon_arch.c:57
static void hex_clear_pkt(RZ_NONNULL HexPkt *p)
Clears a packet and sets its attributes to invalid values.
Definition: hexagon_arch.c:123
RZ_API HexInsn * alloc_instr()
Allocates a new instruction on the heap.
Definition: hexagon_arch.c:507
static void hex_set_pkt_info(const RzAsm *rz_asm, RZ_INOUT HexInsn *hi, const HexPkt *p, const ut8 k, const bool update_mnemonic)
Sets the packet related information in an instruction.
Definition: hexagon_arch.c:371
static HexInsn * hex_add_to_pkt(HexState *state, const HexInsn *new_ins, RZ_INOUT HexPkt *p, const ut8 k)
Copies an instruction to the packet p at position k.
Definition: hexagon_arch.c:525
static void make_next_packet_valid(HexState *state, const HexPkt *pkt)
Sets the packet after pkt to valid and updates its mnemonic.
Definition: hexagon_arch.c:474
RZ_API HexState * hexagon_get_state()
Initializes each packet of the state once.
Definition: hexagon_arch.c:217
static bool is_pkt_full(const HexPkt *p)
Checks if the packet has 4 instructions set.
Definition: hexagon_arch.c:245
static bool is_endloop01_pkt(const ut8 pb_hi_0, const ut8 pb_hi_1)
Checks if packet ends hardware loop 0 and hw-loop 1.
Definition: hexagon_arch.c:69
static HexInsn * hex_to_new_pkt(HexState *state, const HexInsn *new_ins, const HexPkt *p, RZ_INOUT HexPkt *new_p)
Cleans the packet new_p, copies the instruction new_ins and the attributes of p to it.
Definition: hexagon_arch.c:559
RZ_API void hex_extend_op(HexState *state, RZ_INOUT HexOp *op, const bool set_new_extender, const ut32 addr)
Applies the constant extender to the immediate value in op.
Definition: hexagon_arch.c:738
static HexInsn * hex_add_instr_to_state(HexState *state, const HexInsn *new_ins)
Copies the given instruction to a state packet it belongs to. If the instruction does not fit to any ...
Definition: hexagon_arch.c:615
static HexConstExt * get_const_ext_from_addr(const RzList *ce_list, const ut32 addr)
Searched the constant extender in the ce_list, where addr is the key.
Definition: hexagon_arch.c:719
static bool is_last_instr(const ut8 parse_bits)
Definition: hexagon_arch.c:19
static void setup_new_instr(HexInsn *hi, const HexReversedOpcode *rz_reverse, const ut32 addr, const ut8 parse_bits)
Set the up new instr.
Definition: hexagon_arch.c:685
static bool is_undoc_endloop0_pkt(const ut8 pb_hi_0, const ut8 pb_hi_1)
Checks if packet ends hardware loop 0. But for an undocumented variant where the packet has only two ...
Definition: hexagon_arch.c:45
static bool imm_is_scaled(const HexOpAttr attr)
Definition: hexagon_arch.c:708
static HexInsn * hex_add_to_stale_pkt(HexState *state, const HexInsn *new_ins)
Cleans the least accessed packet and copies the given instruction into it.
Definition: hexagon_arch.c:586
#define HEX_PKT_ELOOP_01_UTF8
Definition: hexagon_arch.h:55
#define HEX_PKT_LAST_SDK
Definition: hexagon_arch.h:51
#define HEX_PKT_ELOOP_01
Definition: hexagon_arch.h:58
#define HEX_PKT_LAST
Definition: hexagon_arch.h:54
#define HEX_PKT_SINGLE_UTF8
Definition: hexagon_arch.h:45
#define HEX_PKT_ELOOP_0_UTF8
Definition: hexagon_arch.h:57
#define HEX_PKT_FIRST
Definition: hexagon_arch.h:52
#define HEX_PKT_ELOOP_0
Definition: hexagon_arch.h:60
#define HEX_PKT_ELOOP_1_SDK
Definition: hexagon_arch.h:62
#define HEX_PKT_MID
Definition: hexagon_arch.h:53
#define HEX_PKT_LAST_UTF8
Definition: hexagon_arch.h:48
#define HEX_PKT_ELOOP_1
Definition: hexagon_arch.h:59
HexPktSyntaxIndicator
Definition: hexagon_arch.h:17
@ FIRST_IN_PKT
Definition: hexagon_arch.h:19
@ ELOOP_01_PKT
Definition: hexagon_arch.h:24
@ LAST_IN_PKT
Definition: hexagon_arch.h:21
@ SINGLE_IN_PKT
Definition: hexagon_arch.h:18
@ MID_IN_PKT
Definition: hexagon_arch.h:20
@ ELOOP_0_PKT
Definition: hexagon_arch.h:22
@ ELOOP_1_PKT
Definition: hexagon_arch.h:23
#define HEX_PKT_UNK
Definition: hexagon_arch.h:43
#define HEX_PKT_SINGLE
Definition: hexagon_arch.h:44
#define HEX_PKT_MID_UTF8
Definition: hexagon_arch.h:47
#define HEX_PKT_FIRST_UTF8
Definition: hexagon_arch.h:46
#define HEX_PKT_SDK_PADDING
Definition: hexagon_arch.h:50
@ HEXAGON_ANALYSIS
Definition: hexagon_arch.h:29
@ HEXAGON_DISAS
Definition: hexagon_arch.h:30
#define HEX_PKT_ELOOP_0_SDK
Definition: hexagon_arch.h:63
#define HEX_PKT_ELOOP_1_UTF8
Definition: hexagon_arch.h:56
#define HEX_PKT_FIRST_SDK
Definition: hexagon_arch.h:49
#define HEX_PKT_ELOOP_01_SDK
Definition: hexagon_arch.h:61
@ HEX_INS_INVALID_DECODE
Definition: hexagon_insn.h:13
hi(addr) 0x03
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
voidpf void * buf
Definition: ioapi.h:138
sprintf
Definition: kernel.h:365
uint8_t ut8
Definition: lh5801.h:11
void * p
Definition: libc.cpp:67
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
RZ_API RZ_BORROW RzListIter * rz_list_insert(RZ_NONNULL RzList *list, ut32 n, void *data)
Inserts a new element at the N-th position.
Definition: list.c:342
RZ_API RZ_OWN RzList * rz_list_newf(RzListFree f)
Returns a new initialized RzList pointer and sets the free method.
Definition: list.c:248
RZ_API bool rz_list_delete_data(RZ_NONNULL RzList *list, void *ptr)
Deletes an entry in the list by searching for a pointer.
Definition: list.c:148
RZ_API RZ_BORROW void * rz_list_get_top(RZ_NONNULL const RzList *list)
Returns the last element of the list.
Definition: list.c:457
RZ_API RZ_BORROW void * rz_list_get_n(RZ_NONNULL const RzList *list, ut32 n)
Returns the N-th element of the list.
Definition: list.c:574
RZ_API ut32 rz_list_length(RZ_NONNULL const RzList *list)
Returns the length of the list.
Definition: list.c:109
RZ_API RZ_BORROW RzListIter * rz_list_append(RZ_NONNULL RzList *list, void *data)
Appends at the end of the list a new element.
Definition: list.c:288
RZ_API void rz_list_purge(RZ_NONNULL RzList *list)
Empties the list without freeing the list pointer.
Definition: list.c:120
void * calloc(size_t number, size_t size)
Definition: malloc.c:102
#define rz_return_if_fail(expr)
Definition: rz_assert.h:100
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
static ut32 rz_read_le32(const void *src)
Definition: rz_endian.h:239
void(* RzListFree)(void *ptr)
Definition: rz_list.h:11
#define RZ_LOG_VERBOSE(fmtstr,...)
Definition: rz_log.h:52
#define RZ_LOG_FATAL(fmtstr,...)
Definition: rz_log.h:60
RZ_API const char * rz_strbuf_set(RzStrBuf *sb, const char *s)
Definition: strbuf.c:153
RZ_API ut64 rz_time_now(void)
Returns the current time in microseconds.
Definition: time.c:88
#define RZ_NULLABLE
Definition: rz_types.h:65
#define RZ_NONNULL
Definition: rz_types.h:64
#define RZ_INOUT
Definition: rz_types.h:52
#define UT64_MAX
Definition: rz_types_base.h:86
#define UT8_MAX
#define ST64_MAX
Definition: rz_types_base.h:84
ut32 const_ext
Definition: hexagon.h:127
ut32 addr
Definition: hexagon.h:126
ut32 addr
Definition: hexagon.h:109
ut8 parse_bits
Definition: hexagon.h:97
Definition: hexagon.h:85
char mnem_postfix[24]
Definition: hexagon.h:82
bool first_insn
Definition: hexagon.h:79
char mnem_prefix[16]
Definition: hexagon.h:81
bool last_insn
Definition: hexagon.h:80
RzList * insn
Definition: hexagon.h:115
Pointer to the rizin structs for disassembled and analysed instructions.
Definition: hexagon_arch.h:37
RzAnalysisOp * ana_op
Definition: hexagon_arch.h:39
RzAsmOp * asm_op
Definition: hexagon_arch.h:40
HexReverseAction action
Definition: hexagon_arch.h:38
Buffer packets for reversed instructions.
Definition: hexagon.h:134
ut32 op_type
RzAnalysisOpType. Mnemonic color depends on this.
Definition: rz_print.h:73
RzStrBuf buf_asm
Definition: rz_asm.h:72
RzAsmTokenString * asm_toks
Tokenized asm string.
Definition: rz_asm.h:74
bool utf8
Definition: rz_asm.h:123
Definition: dis.h:43
Definition: dis.c:32
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
static int sp
Definition: z80asm.c:91
static int addr
Definition: z80asm.c:58