Rizin
unix-like reverse engineering framework and cli tools
hexagon_arch.c File Reference
#include <rz_asm.h>
#include <rz_analysis.h>
#include <rz_util.h>
#include "hexagon.h"
#include "hexagon_insn.h"
#include "hexagon_arch.h"

Go to the source code of this file.

Functions

static bool is_last_instr (const ut8 parse_bits)
 
static bool is_endloop0_pkt (const ut8 pb_hi_0, const ut8 pb_hi_1)
 Checks if packet ends hardware loop 0. More...
 
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 instructions and the last one is a Duplex. More...
 
static bool is_endloop1_pkt (const ut8 pb_hi_0, const ut8 pb_hi_1)
 Checks if packet ends hardware loop 1. More...
 
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. More...
 
static HexInsnhex_get_instr_at_addr (HexState *state, const ut32 addr)
 Gives the instruction at a given address from the state. More...
 
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. More...
 
static void hex_clear_pkt (RZ_NONNULL HexPkt *p)
 Clears a packet and sets its attributes to invalid values. More...
 
static HexPkthex_get_stale_pkt (HexState *state)
 Gives the least used packet. More...
 
static HexPkthex_get_pkt (HexState *state, const ut32 addr)
 Returns the packet which covers the given address. More...
 
RZ_API void hex_insn_free (RZ_NULLABLE HexInsn *i)
 Frees an instruction. More...
 
RZ_API void hex_const_ext_free (RZ_NULLABLE HexConstExt *ce)
 Frees an constant extender. More...
 
static ut8 get_state_pkt_index (HexState *state, const HexPkt *p)
 Get the index of a packet in the state. More...
 
RZ_API HexStatehexagon_get_state ()
 Initializes each packet of the state once. More...
 
static bool is_pkt_full (const HexPkt *p)
 Checks if the packet has 4 instructions set. More...
 
static char * get_pkt_indicator (const bool utf8, const bool sdk, const bool prefix, HexPktSyntaxIndicator ind_type)
 Get the pkt indicator string. More...
 
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. More...
 
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 hardware loop. Otherwise it returns HEX_NO_LOOP. More...
 
static void make_next_packet_valid (HexState *state, const HexPkt *pkt)
 Sets the packet after pkt to valid and updates its mnemonic. More...
 
RZ_API HexInsnalloc_instr ()
 Allocates a new instruction on the heap. More...
 
static HexInsnhex_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. More...
 
static HexInsnhex_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. More...
 
static HexInsnhex_add_to_stale_pkt (HexState *state, const HexInsn *new_ins)
 Cleans the least accessed packet and copies the given instruction into it. More...
 
static HexInsnhex_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 packet, it will be written to a stale one. More...
 
static void setup_new_instr (HexInsn *hi, const HexReversedOpcode *rz_reverse, const ut32 addr, const ut8 parse_bits)
 Set the up new instr. More...
 
static bool imm_is_scaled (const HexOpAttr attr)
 
static HexConstExtget_const_ext_from_addr (const RzList *ce_list, const ut32 addr)
 Searched the constant extender in the ce_list, where addr is the key. More...
 
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. More...
 
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. More...
 

Function Documentation

◆ alloc_instr()

RZ_API HexInsn* alloc_instr ( )

Allocates a new instruction on the heap.

Returns
HexInsn* The new instruction.

Definition at line 507 of file hexagon_arch.c.

507  {
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 }
hi(addr) 0x03
void * calloc(size_t number, size_t size)
Definition: malloc.c:102
#define RZ_LOG_FATAL(fmtstr,...)
Definition: rz_log.h:60

References calloc(), hi(), and RZ_LOG_FATAL.

Referenced by hex_add_to_pkt(), hex_add_to_stale_pkt(), and hex_to_new_pkt().

◆ get_const_ext_from_addr()

static HexConstExt* get_const_ext_from_addr ( const RzList ce_list,
const ut32  addr 
)
static

Searched the constant extender in the ce_list, where addr is the key.

Parameters
ce_listThe list with constant extender values.
addrThe address of the instruction which gets the constant extender applied.
Returns
HexConstExt* A const. ext., if there is one which should be applied on the instruction at addr. Otherwise NULL.

Definition at line 719 of file hexagon_arch.c.

719  {
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 }
#define NULL
Definition: cris-opc.c:27
ut32 addr
Definition: hexagon.h:126
static int addr
Definition: z80asm.c:58

References HexConstExt::addr, addr, and NULL.

Referenced by hex_extend_op().

◆ get_pkt_indicator()

static char* get_pkt_indicator ( const bool  utf8,
const bool  sdk,
const bool  prefix,
HexPktSyntaxIndicator  ind_type 
)
static

Get the pkt indicator string.

Parameters
utf8True: Return UTF8 string. False: Return ASCII.
sdkTrue: Return SDK conforming string ('{', '}', ':endloop0' etc.). False: Returns a non SDK conforming string
prefixTrue: Return the prefix indicator. False: Return the postfix. If there is no prefix/postfix for a given indicator type (e.g. for the utf8 version of 'endloop01') it returns an empty string.
ind_typeThe
prefix
Returns
char* The indicator string according to the given flags.

Definition at line 262 of file hexagon_arch.c.

262  {
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 }
unsigned short prefix[65536]
Definition: gun.c:163
#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
@ 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_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
#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

References ELOOP_01_PKT, ELOOP_0_PKT, ELOOP_1_PKT, FIRST_IN_PKT, HEX_PKT_ELOOP_0, HEX_PKT_ELOOP_01, HEX_PKT_ELOOP_01_SDK, HEX_PKT_ELOOP_01_UTF8, HEX_PKT_ELOOP_0_SDK, HEX_PKT_ELOOP_0_UTF8, HEX_PKT_ELOOP_1, HEX_PKT_ELOOP_1_SDK, HEX_PKT_ELOOP_1_UTF8, HEX_PKT_FIRST, HEX_PKT_FIRST_SDK, HEX_PKT_FIRST_UTF8, HEX_PKT_LAST, HEX_PKT_LAST_SDK, HEX_PKT_LAST_UTF8, HEX_PKT_MID, HEX_PKT_MID_UTF8, HEX_PKT_SDK_PADDING, HEX_PKT_SINGLE, HEX_PKT_SINGLE_UTF8, LAST_IN_PKT, MID_IN_PKT, prefix, and SINGLE_IN_PKT.

Referenced by hex_set_pkt_info().

◆ get_state_pkt_index()

static ut8 get_state_pkt_index ( HexState state,
const HexPkt p 
)
static

Get the index of a packet in the state.

Parameters
stateThe state to operade on.
pThe packet whichs index should be determined.
Returns
ut8 The index of the packet in the given state. UT8_MAX if it is not in the state.

Definition at line 201 of file hexagon_arch.c.

201  {
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 }
lzma_index ** i
Definition: index.h:629
#define HEXAGON_STATE_PKTS
Definition: hexagon.h:25
uint8_t ut8
Definition: lh5801.h:11
void * p
Definition: libc.cpp:67
#define UT8_MAX
Definition: dis.h:43
static int sp
Definition: z80asm.c:91

References HEXAGON_STATE_PKTS, i, p, sp, and UT8_MAX.

Referenced by hex_add_instr_to_state().

◆ hex_add_instr_to_state()

static HexInsn* hex_add_instr_to_state ( HexState state,
const HexInsn new_ins 
)
static

Copies the given instruction to a state packet it belongs to. If the instruction does not fit to any packet, it will be written to a stale one.

The instruction must have its address and parse bits set!

Parameters
stateThe state to operade on.
new_insThe instruction to be copied.
Returns
The pointer to the added instruction. Null if the instruction could not be copied.

Definition at line 615 of file hexagon_arch.c.

615  {
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 }
const char * k
Definition: dsignal.c:11
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 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 bool is_pkt_full(const HexPkt *p)
Checks if the packet has 4 instructions set.
Definition: hexagon_arch.c:245
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
static bool is_last_instr(const ut8 parse_bits)
Definition: hexagon_arch.c:19
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
ut32 addr
Definition: hexagon.h:109
ut8 parse_bits
Definition: hexagon.h:97

References HexInsn::addr, get_state_pkt_index(), hex_add_to_pkt(), hex_add_to_stale_pkt(), hex_to_new_pkt(), HEXAGON_STATE_PKTS, i, is_last_instr(), is_pkt_full(), k, NULL, p, and HexInsn::parse_bits.

Referenced by hexagon_reverse_opcode().

◆ hex_add_to_pkt()

static HexInsn* hex_add_to_pkt ( HexState state,
const HexInsn new_ins,
RZ_INOUT HexPkt p,
const ut8  k 
)
static

Copies an instruction to the packet p at position k.

Parameters
stateThe state to operade on.
new_insThe instruction to copy.
pThe packet in which the instruction will hold the instruction.
kThe index of the instruction in the packet.
Returns
HexInsn* Pointer to the copied instruction on the heap.

Definition at line 525 of file hexagon_arch.c.

525  {
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 }
uint32_t ut32
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 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
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_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 ut64 rz_time_now(void)
Returns the current time in microseconds.
Definition: time.c:88

References alloc_instr(), hex_set_pkt_info(), hi(), is_last_instr(), k, make_next_packet_valid(), memcpy(), p, rz_list_get_n(), rz_list_insert(), rz_list_length(), RZ_LOG_FATAL, and rz_time_now().

Referenced by hex_add_instr_to_state().

◆ hex_add_to_stale_pkt()

static HexInsn* hex_add_to_stale_pkt ( HexState state,
const HexInsn new_ins 
)
static

Cleans the least accessed packet and copies the given instruction into it.

Parameters
stateThe state to operade on.
new_insThe instruction to copy.
Returns
HexInsn* Pointer to the copied instruction on the heap.

Definition at line 586 of file hexagon_arch.c.

586  {
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 }
static HexPkt * hex_get_stale_pkt(HexState *state)
Gives the least used packet.
Definition: hexagon_arch.c:136
static void hex_clear_pkt(RZ_NONNULL HexPkt *p)
Clears a packet and sets its attributes to invalid values.
Definition: hexagon_arch.c:123

References HexInsn::addr, alloc_instr(), hex_clear_pkt(), hex_get_stale_pkt(), hex_set_pkt_info(), hi(), is_last_instr(), make_next_packet_valid(), memcpy(), p, rz_list_insert(), and rz_time_now().

Referenced by hex_add_instr_to_state().

◆ hex_clear_pkt()

static void hex_clear_pkt ( RZ_NONNULL HexPkt p)
static

Clears a packet and sets its attributes to invalid values.

Parameters
pThe packet to clear.

Definition at line 123 of file hexagon_arch.c.

123  {
124  p->last_instr_present = false;
125  p->is_valid = false;
126  p->last_access = 0;
127  rz_list_purge(p->insn);
128 }
RZ_API void rz_list_purge(RZ_NONNULL RzList *list)
Empties the list without freeing the list pointer.
Definition: list.c:120

References p, and rz_list_purge().

Referenced by hex_add_to_stale_pkt(), hex_to_new_pkt(), and hexagon_get_state().

◆ hex_const_ext_free()

RZ_API void hex_const_ext_free ( RZ_NULLABLE HexConstExt ce)

Frees an constant extender.

Parameters
ceThe constant extender to be freed.

Definition at line 187 of file hexagon_arch.c.

187  {
188  if (!ce) {
189  return;
190  }
191  free(ce);
192 }
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130

References free().

Referenced by hexagon_get_state().

◆ hex_extend_op()

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.

Parameters
stateThe state to operade on.
opThe operand the extender is applied to or taken from.
set_new_extenderTrue if the immediate value of the op comes from immext() and sets the a new constant extender. False otherwise.
addrThe address of the currently disassembled instruction.

Definition at line 738 of file hexagon_arch.c.

738  {
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 }
@ HEX_OP_TYPE_IMM
Definition: hexagon.h:55
#define MAX_CONST_EXT
Definition: hexagon.h:24
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 imm_is_scaled(const HexOpAttr attr)
Definition: hexagon_arch.c:708
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 RzListIter * rz_list_append(RZ_NONNULL RzList *list, void *data)
Appends at the end of the list a new element.
Definition: list.c:288
ut32 const_ext
Definition: hexagon.h:127
Definition: dis.c:32

References HexConstExt::addr, addr, calloc(), HexConstExt::const_ext, get_const_ext_from_addr(), HEX_OP_TYPE_IMM, imm_is_scaled(), MAX_CONST_EXT, rz_list_append(), rz_list_delete_data(), rz_list_length(), and rz_list_purge().

Referenced by hex_disasm_with_templates().

◆ hex_get_instr_at_addr()

static HexInsn* hex_get_instr_at_addr ( HexState state,
const ut32  addr 
)
static

Gives the instruction at a given address from the state.

Parameters
stateThe state to operade on.
addrThe address of the instruction.
Returns
Pointer to instruction or NULL if none was found.

Definition at line 80 of file hexagon_arch.c.

80  {
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 }

References HexInsn::addr, addr, HEXAGON_STATE_PKTS, i, NULL, p, and rz_time_now().

Referenced by hexagon_reverse_opcode().

◆ hex_get_loop_flag()

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 hardware loop. Otherwise it returns HEX_NO_LOOP.

Parameters
pThe instruction packet.
Returns
HexLoopAttr The loop type this packet belongs to.

Definition at line 446 of file hexagon_arch.c.

446  {
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 }
@ 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
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
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 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 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
#define RZ_LOG_VERBOSE(fmtstr,...)
Definition: rz_log.h:52

References HEX_LOOP_0, HEX_LOOP_01, HEX_LOOP_1, HEX_NO_LOOP, is_endloop01_pkt(), is_endloop0_pkt(), is_endloop1_pkt(), is_undoc_endloop0_pkt(), p, rz_list_get_n(), rz_list_length(), and RZ_LOG_VERBOSE.

Referenced by hex_set_pkt_info(), and hexagon_disasm_instruction().

◆ hex_get_pkt()

static HexPkt* hex_get_pkt ( HexState state,
const ut32  addr 
)
static

Returns the packet which covers the given address.

Parameters
stateThe state to operade on.
addrThe address of an instruction.
Returns
HexPkt* The packet to which this address belongs to or NULL if no packet was found.

Definition at line 155 of file hexagon_arch.c.

155  {
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 }

References HexInsn::addr, addr, HEXAGON_STATE_PKTS, i, NULL, and p.

Referenced by hexagon_reverse_opcode().

◆ hex_get_stale_pkt()

static HexPkt* hex_get_stale_pkt ( HexState state)
static

Gives the least used packet.

Parameters
stateThe state to operade on.
Returns
HexPkt* Pointer to the least used packet.

Definition at line 136 of file hexagon_arch.c.

136  {
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 }
#define UT64_MAX
Definition: rz_types_base.h:86
ut64(WINAPI *w32_GetEnabledXStateFeatures)()

References HEXAGON_STATE_PKTS, i, ut64(), and UT64_MAX.

Referenced by hex_add_to_stale_pkt().

◆ hex_insn_free()

RZ_API void hex_insn_free ( RZ_NULLABLE HexInsn i)

Frees an instruction.

Parameters
iThe instruction to be freed.

Definition at line 175 of file hexagon_arch.c.

175  {
176  if (!i) {
177  return;
178  }
179  free(i);
180 }

References free(), and i.

Referenced by hexagon_get_state().

◆ hex_set_pkt_info()

static void hex_set_pkt_info ( const RzAsm rz_asm,
RZ_INOUT HexInsn hi,
const HexPkt p,
const ut8  k,
const bool  update_mnemonic 
)
static

Sets the packet related information in an instruction.

Parameters
hiThe instruction.
pThe packet the instruction belongs to.
kThe index of the instruction within the packet.

Definition at line 371 of file hexagon_arch.c.

371  {
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 }
RZ_API bool rz_config_get_b(RzConfig *cfg, RZ_NONNULL const char *name)
Definition: config.c:142
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 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 HexState * hexagon_get_state()
Initializes each packet of the state once.
Definition: hexagon_arch.c:217
#define HEX_PKT_UNK
Definition: hexagon_arch.h:43
sprintf
Definition: kernel.h:365
#define rz_return_if_fail(expr)
Definition: rz_assert.h:100
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
Buffer packets for reversed instructions.
Definition: hexagon.h:134
bool utf8
Definition: rz_asm.h:123

References ELOOP_01_PKT, ELOOP_0_PKT, ELOOP_1_PKT, FIRST_IN_PKT, HexPktInfo::first_insn, get_pkt_indicator(), hex_get_loop_flag(), HEX_LOOP_0, HEX_LOOP_01, HEX_LOOP_1, HEX_PKT_UNK, hexagon_get_state(), hi(), is_last_instr(), k, LAST_IN_PKT, HexPktInfo::last_insn, MID_IN_PKT, HexPktInfo::mnem_postfix, HexPktInfo::mnem_prefix, p, rz_config_get_b(), rz_return_if_fail, SINGLE_IN_PKT, sprintf, and rz_asm_t::utf8.

Referenced by hex_add_to_pkt(), hex_add_to_stale_pkt(), hex_to_new_pkt(), and make_next_packet_valid().

◆ hex_to_new_pkt()

static HexInsn* hex_to_new_pkt ( HexState state,
const HexInsn new_ins,
const HexPkt p,
RZ_INOUT HexPkt new_p 
)
static

Cleans the packet new_p, copies the instruction new_ins and the attributes of p to it.

Parameters
stateThe state to operade on.
new_insThe instruction to copy.
pThe old packet which attributes are copied to the new one.
new_pThe new packet will hold the instruction.
Returns
HexInsn* Pointer to the copied instruction on the heap.

Definition at line 559 of file hexagon_arch.c.

559  {
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 }

References alloc_instr(), hex_clear_pkt(), hex_set_pkt_info(), hi(), is_last_instr(), make_next_packet_valid(), memcpy(), p, rz_list_insert(), and rz_time_now().

Referenced by hex_add_instr_to_state().

◆ hexagon_get_pkt_index_of_addr()

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.

Parameters
addrAddress of an instruction.
pThe packet. to search in.
Returns
ut8 The index of the addr if it is in the packet. UT8_MAX otherwise.

Definition at line 103 of file hexagon_arch.c.

103  {
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 }
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108

References addr, hi(), i, NULL, p, rz_return_val_if_fail, and UT8_MAX.

Referenced by resolve_n_register().

◆ hexagon_get_state()

RZ_API HexState* hexagon_get_state ( )

Initializes each packet of the state once.

Returns
The initialized state of the plugins.

Definition at line 217 of file hexagon_arch.c.

217  {
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 }
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
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
void(* RzListFree)(void *ptr)
Definition: rz_list.h:11

References calloc(), hex_clear_pkt(), hex_const_ext_free(), hex_insn_free(), HEXAGON_STATE_PKTS, i, NULL, rz_list_newf(), and RZ_LOG_FATAL.

Referenced by hex_set_pkt_info(), and hexagon_reverse_opcode().

◆ hexagon_reverse_opcode()

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.

Parameters
rz_reverseRizin core structs which store asm and analysis information.
bufThe buffer which stores the current opcode.
addrThe address of the current opcode.

Definition at line 772 of file hexagon_arch.c.

772  {
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 }
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
int hexagon_disasm_instruction(HexState *state, const ut32 hi_u32, RZ_INOUT HexInsn *hi, HexPkt *pkt)
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
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 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
@ HEXAGON_ANALYSIS
Definition: hexagon_arch.h:29
@ HEXAGON_DISAS
Definition: hexagon_arch.h:30
voidpf void * buf
Definition: ioapi.h:138
static ut32 rz_read_le32(const void *src)
Definition: rz_endian.h:239
RZ_API const char * rz_strbuf_set(RzStrBuf *sb, const char *s)
Definition: strbuf.c:153
RzAnalysisOp * ana_op
Definition: hexagon_arch.h:39
RzAsmOp * asm_op
Definition: hexagon_arch.h:40
HexReverseAction action
Definition: hexagon_arch.h:38
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

References HexReversedOpcode::action, addr, HexReversedOpcode::ana_op, HexReversedOpcode::asm_op, rz_asm_op_t::asm_toks, rz_asm_op_t::buf_asm, hex_add_instr_to_state(), hex_get_instr_at_addr(), hex_get_pkt(), HEXAGON_ANALYSIS, HEXAGON_DISAS, hexagon_disasm_instruction(), hexagon_get_state(), hi(), memcpy(), RzAsmTokenString::op_type, p, rz_asm_tokenize_asm_regex(), RZ_LOG_FATAL, rz_read_le32(), rz_strbuf_set(), and setup_new_instr().

Referenced by hexagon_v6_op().

◆ imm_is_scaled()

static bool imm_is_scaled ( const HexOpAttr  attr)
inlinestatic

Definition at line 708 of file hexagon_arch.c.

708  {
709  return (attr & HEX_OP_IMM_SCALED);
710 }
@ HEX_OP_IMM_SCALED
Definition: hexagon.h:68

References HEX_OP_IMM_SCALED.

Referenced by hex_extend_op().

◆ is_endloop01_pkt()

static bool is_endloop01_pkt ( const ut8  pb_hi_0,
const ut8  pb_hi_1 
)
inlinestatic

Checks if packet ends hardware loop 0 and hw-loop 1.

Parameters
pb_hi_0Parse bits instruction 0.
pb_hi_1Parse bits instruction 1.
Returns
true Packet ends hardware loop 0 and hw-loop 1.
false Packet does not end hardware loop 0 and hw-loop 1.

Definition at line 69 of file hexagon_arch.c.

69  {
70  return ((pb_hi_0 == 0x2) && (pb_hi_1 == 0x2));
71 }

Referenced by hex_get_loop_flag().

◆ is_endloop0_pkt()

static bool is_endloop0_pkt ( const ut8  pb_hi_0,
const ut8  pb_hi_1 
)
inlinestatic

Checks if packet ends hardware loop 0.

Parameters
pb_hi_0Parse bits instruction 0.
pb_hi_1Parse bits instruction 1.
Returns
true Packet ends hardware loop 0.
false Packet does not end hardware loop 0.

Definition at line 32 of file hexagon_arch.c.

32  {
33  return ((pb_hi_0 == 0x2) && ((pb_hi_1 == 0x1) || (pb_hi_1 == 0x3)));
34 }

Referenced by hex_get_loop_flag().

◆ is_endloop1_pkt()

static bool is_endloop1_pkt ( const ut8  pb_hi_0,
const ut8  pb_hi_1 
)
inlinestatic

Checks if packet ends hardware loop 1.

Parameters
pb_hi_0Parse bits instruction 0.
pb_hi_1Parse bits instruction 1.
Returns
true Packet ends hardware loop 1.
false Packet does not end hardware loop 1.

Definition at line 57 of file hexagon_arch.c.

57  {
58  return ((pb_hi_0 == 0x1) && (pb_hi_1 == 0x2));
59 }

Referenced by hex_get_loop_flag().

◆ is_last_instr()

static bool is_last_instr ( const ut8  parse_bits)
inlinestatic

Definition at line 19 of file hexagon_arch.c.

19  {
20  // Duplex instr. (parse bits = 0) are always the last.
21  return ((parse_bits == 0x3) || (parse_bits == 0x0));
22 }

Referenced by hex_add_instr_to_state(), hex_add_to_pkt(), hex_add_to_stale_pkt(), hex_set_pkt_info(), and hex_to_new_pkt().

◆ is_pkt_full()

static bool is_pkt_full ( const HexPkt p)
inlinestatic

Checks if the packet has 4 instructions set.

Parameters
pThe packet to check.
Returns
true The packet stores already 4 instructions.
false The packet stores less than 4 instructions.

Definition at line 245 of file hexagon_arch.c.

245  {
246  return rz_list_length(p->insn) >= 4;
247 }

References p, and rz_list_length().

Referenced by hex_add_instr_to_state().

◆ is_undoc_endloop0_pkt()

static bool is_undoc_endloop0_pkt ( const ut8  pb_hi_0,
const ut8  pb_hi_1 
)
inlinestatic

Checks if packet ends hardware loop 0. But for an undocumented variant where the packet has only two instructions and the last one is a Duplex.

Parameters
pb_hi_0Parse bits instruction 0.
pb_hi_1Parse bits instruction 1 (duplex and end of packet).
Returns
true Packet ends hardware loop 0.
false Packet does not end hardware loop 0.

Definition at line 45 of file hexagon_arch.c.

45  {
46  return ((pb_hi_0 == 0x2) && (pb_hi_1 == 0x0));
47 }

Referenced by hex_get_loop_flag().

◆ make_next_packet_valid()

static void make_next_packet_valid ( HexState state,
const HexPkt pkt 
)
static

Sets the packet after pkt to valid and updates its mnemonic.

Parameters
stateThe state to operade on.
pktThe packet which predecessor will be updated.

Definition at line 474 of file hexagon_arch.c.

474  {
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 }
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
RzList * insn
Definition: hexagon.h:115

References hex_set_pkt_info(), HEXAGON_STATE_PKTS, hi(), i, HexPkt::insn, k, NULL, p, rz_list_get_top(), rz_time_now(), and autogen_x86imm::tmp.

Referenced by hex_add_to_pkt(), hex_add_to_stale_pkt(), and hex_to_new_pkt().

◆ setup_new_instr()

static void setup_new_instr ( HexInsn hi,
const HexReversedOpcode rz_reverse,
const ut32  addr,
const ut8  parse_bits 
)
static

Set the up new instr.

Parameters
hiThe instruction to set up.
rz_reverseRzAsmOp and RzAnalysisOp which could have some data, which needs to be copied.
addrThe address of the instruction.
parse_bitsThe parse bits of the instruction

Definition at line 685 of file hexagon_arch.c.

685  {
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 }
@ HEX_INS_INVALID_DECODE
Definition: hexagon_insn.h:13
#define ST64_MAX
Definition: rz_types_base.h:84

References addr, HexReversedOpcode::ana_op, HexReversedOpcode::asm_op, HEX_INS_INVALID_DECODE, hi(), i, memcpy(), ST64_MAX, and UT64_MAX.

Referenced by hexagon_reverse_opcode().