Rizin
unix-like reverse engineering framework and cli tools
hexagon_disas.c File Reference
#include <stdio.h>
#include <stdbool.h>
#include <rz_types.h>
#include <rz_util.h>
#include <rz_util/rz_hex.h>
#include <rz_util/rz_strbuf.h>
#include <rz_analysis.h>
#include "hexagon.h"
#include "hexagon_insn.h"
#include "hexagon_arch.h"

Go to the source code of this file.

Classes

struct  HexOpMask
 
struct  HexOpTemplate
 
struct  HexInsnTemplate
 

Macros

#define NO_OPT_IF_ASAN
 
#define HEX_OP_MASKS_MAX   4
 

Enumerations

enum  HexOpTemplateType {
  HEX_OP_TEMPLATE_TYPE_NONE = 0 , HEX_OP_TEMPLATE_TYPE_IMM = 1 , HEX_OP_TEMPLATE_TYPE_IMM_CONST = 2 , HEX_OP_TEMPLATE_TYPE_REG = 3 ,
  HEX_OP_TEMPLATE_TYPE_MASK = 3
}
 
enum  HexOpTemplateFlag {
  HEX_OP_TEMPLATE_FLAG_REG_OUT = 1 << 2 , HEX_OP_TEMPLATE_FLAG_REG_PAIR = 1 << 3 , HEX_OP_TEMPLATE_FLAG_REG_QUADRUPLE = 1 << 4 , HEX_OP_TEMPLATE_FLAG_REG_N_REG = 1 << 5 ,
  HEX_OP_TEMPLATE_FLAG_IMM_SIGNED = 1 << 2 , HEX_OP_TEMPLATE_FLAG_IMM_EXTENDABLE = 1 << 3 , HEX_OP_TEMPLATE_FLAG_IMM_PC_RELATIVE = 1 << 4 , HEX_OP_TEMPLATE_FLAG_IMM_DOUBLE_HASH = 1 << 5
}
 
enum  HexInsnTemplateFlag {
  HEX_INSN_TEMPLATE_FLAG_CALL = 1 << 0 , HEX_INSN_TEMPLATE_FLAG_PREDICATED = 1 << 1 , HEX_INSN_TEMPLATE_FLAG_HAS_JMP_TGT = 1 << 2 , HEX_INSN_TEMPLATE_FLAG_LOOP_BEGIN = 1 << 3 ,
  HEX_INSN_TEMPLATE_FLAG_LOOP_0 = 1 << 4 , HEX_INSN_TEMPLATE_FLAG_LOOP_1 = 1 << 5
}
 

Functions

static bool is_last_instr (const ut8 parse_bits)
 
static ut32 hex_op_masks_extract (const HexOpMask *masks, ut32 val, RZ_OUT ut32 *bits_total)
 
static int get_jmp_target_imm_op_index (const HexInsnTemplate *tpl)
 
static void hex_disasm_with_templates (const HexInsnTemplate *tpl, HexState *state, ut32 hi_u32, RZ_INOUT HexInsn *hi, ut64 addr, HexPkt *pkt)
 
int hexagon_disasm_instruction (HexState *state, const ut32 hi_u32, RZ_INOUT HexInsn *hi, HexPkt *pkt)
 

Variables

static const HexInsnTemplate templates_duplex_0x0 []
 
static const HexInsnTemplate templates_duplex_0x1 []
 
static const HexInsnTemplate templates_duplex_0x2 []
 
static const HexInsnTemplate templates_duplex_0x3 []
 
static const HexInsnTemplate templates_duplex_0x4 []
 
static const HexInsnTemplate templates_duplex_0x5 []
 
static const HexInsnTemplate templates_duplex_0x6 []
 
static const HexInsnTemplate templates_duplex_0x7 []
 
static const HexInsnTemplate templates_duplex_0x8 []
 
static const HexInsnTemplate templates_duplex_0x9 []
 
static const HexInsnTemplate templates_duplex_0xa []
 
static const HexInsnTemplate templates_duplex_0xb []
 
static const HexInsnTemplate templates_duplex_0xc []
 
static const HexInsnTemplate templates_duplex_0xd []
 
static const HexInsnTemplate templates_duplex_0xe []
 
static const HexInsnTemplatetemplates_duplex []
 
static const HexInsnTemplate templates_normal_0x0 []
 
static const HexInsnTemplate templates_normal_0x1 []
 
static const HexInsnTemplate templates_normal_0x2 []
 
static const HexInsnTemplate templates_normal_0x3 []
 
static const HexInsnTemplate templates_normal_0x4 []
 
static const HexInsnTemplate templates_normal_0x5 []
 
static const HexInsnTemplate templates_normal_0x6 []
 
static const HexInsnTemplate templates_normal_0x7 []
 
static const HexInsnTemplate templates_normal_0x8 []
 
static const HexInsnTemplate templates_normal_0x9 []
 
static const HexInsnTemplate templates_normal_0xa []
 
static const HexInsnTemplate templates_normal_0xb []
 
static const HexInsnTemplate templates_normal_0xc []
 
static const HexInsnTemplate templates_normal_0xd []
 
static const HexInsnTemplate templates_normal_0xe []
 
static const HexInsnTemplate templates_normal_0xf []
 
static const HexInsnTemplatetemplates_normal []
 

Macro Definition Documentation

◆ HEX_OP_MASKS_MAX

#define HEX_OP_MASKS_MAX   4

Definition at line 29 of file hexagon_disas.c.

◆ NO_OPT_IF_ASAN

#define NO_OPT_IF_ASAN

Definition at line 26 of file hexagon_disas.c.

Enumeration Type Documentation

◆ HexInsnTemplateFlag

Enumerator
HEX_INSN_TEMPLATE_FLAG_CALL 
HEX_INSN_TEMPLATE_FLAG_PREDICATED 
HEX_INSN_TEMPLATE_FLAG_HAS_JMP_TGT 
HEX_INSN_TEMPLATE_FLAG_LOOP_BEGIN 
HEX_INSN_TEMPLATE_FLAG_LOOP_0 
HEX_INSN_TEMPLATE_FLAG_LOOP_1 

Definition at line 74 of file hexagon_disas.c.

74  {
HexInsnTemplateFlag
Definition: hexagon_disas.c:74
@ HEX_INSN_TEMPLATE_FLAG_LOOP_0
Definition: hexagon_disas.c:79
@ HEX_INSN_TEMPLATE_FLAG_PREDICATED
Definition: hexagon_disas.c:76
@ HEX_INSN_TEMPLATE_FLAG_CALL
Definition: hexagon_disas.c:75
@ HEX_INSN_TEMPLATE_FLAG_LOOP_BEGIN
Definition: hexagon_disas.c:78
@ HEX_INSN_TEMPLATE_FLAG_HAS_JMP_TGT
Definition: hexagon_disas.c:77
@ HEX_INSN_TEMPLATE_FLAG_LOOP_1
Definition: hexagon_disas.c:80

◆ HexOpTemplateFlag

Enumerator
HEX_OP_TEMPLATE_FLAG_REG_OUT 
HEX_OP_TEMPLATE_FLAG_REG_PAIR 
HEX_OP_TEMPLATE_FLAG_REG_QUADRUPLE 
HEX_OP_TEMPLATE_FLAG_REG_N_REG 
HEX_OP_TEMPLATE_FLAG_IMM_SIGNED 
HEX_OP_TEMPLATE_FLAG_IMM_EXTENDABLE 
HEX_OP_TEMPLATE_FLAG_IMM_PC_RELATIVE 
HEX_OP_TEMPLATE_FLAG_IMM_DOUBLE_HASH 

Definition at line 39 of file hexagon_disas.c.

39  {
40  // 1 << 0 and 1 << 1 reserved by HexOpTemplateType
41  // for HEX_OP_TEMPLATE_TYPE_REG:
46  // for HEX_OP_TEMPLATE_TYPE_IMM:
HexOpTemplateFlag
Definition: hexagon_disas.c:39
@ HEX_OP_TEMPLATE_FLAG_IMM_DOUBLE_HASH
Definition: hexagon_disas.c:50
@ HEX_OP_TEMPLATE_FLAG_REG_OUT
Definition: hexagon_disas.c:42
@ HEX_OP_TEMPLATE_FLAG_IMM_SIGNED
Definition: hexagon_disas.c:47
@ HEX_OP_TEMPLATE_FLAG_REG_N_REG
Definition: hexagon_disas.c:45
@ HEX_OP_TEMPLATE_FLAG_IMM_PC_RELATIVE
Definition: hexagon_disas.c:49
@ HEX_OP_TEMPLATE_FLAG_REG_PAIR
Definition: hexagon_disas.c:43
@ HEX_OP_TEMPLATE_FLAG_IMM_EXTENDABLE
Definition: hexagon_disas.c:48
@ HEX_OP_TEMPLATE_FLAG_REG_QUADRUPLE
Definition: hexagon_disas.c:44

◆ HexOpTemplateType

Enumerator
HEX_OP_TEMPLATE_TYPE_NONE 
HEX_OP_TEMPLATE_TYPE_IMM 
HEX_OP_TEMPLATE_TYPE_IMM_CONST 
HEX_OP_TEMPLATE_TYPE_REG 
HEX_OP_TEMPLATE_TYPE_MASK 

Definition at line 31 of file hexagon_disas.c.

31  {
HexOpTemplateType
Definition: hexagon_disas.c:31
@ HEX_OP_TEMPLATE_TYPE_IMM_CONST
Definition: hexagon_disas.c:34
@ HEX_OP_TEMPLATE_TYPE_NONE
Definition: hexagon_disas.c:32
@ HEX_OP_TEMPLATE_TYPE_REG
Definition: hexagon_disas.c:35
@ HEX_OP_TEMPLATE_TYPE_IMM
Definition: hexagon_disas.c:33
@ HEX_OP_TEMPLATE_TYPE_MASK
Definition: hexagon_disas.c:36

Function Documentation

◆ get_jmp_target_imm_op_index()

static int get_jmp_target_imm_op_index ( const HexInsnTemplate tpl)
static
Returns
the index of the immediate operand used as the jump target or -1 if there is none.

Definition at line 53439 of file hexagon_disas.c.

53439  {
53440  if (!(tpl->flags & HEX_INSN_TEMPLATE_FLAG_HAS_JMP_TGT)) {
53441  return -1;
53442  }
53443  bool has_imm = false;
53444  size_t i;
53445  for (i = 0; i < HEX_MAX_OPERANDS; i++) {
53446  const HexOpTemplate *op = &tpl->ops[i];
53449  break;
53450  }
53451  if (type == HEX_OP_TEMPLATE_TYPE_IMM) {
53452  has_imm = true;
53454  return i;
53455  }
53456  }
53457  }
53458  return has_imm && i == 1 ? 0 : -1;
53459 }
lzma_index ** i
Definition: index.h:629
#define HEX_MAX_OPERANDS
Definition: hexagon.h:21
int type
Definition: mipsasm.c:17
HexOpTemplate ops[HEX_MAX_OPERANDS]
Definition: hexagon_disas.c:89
Definition: dis.c:32

References HexInsnTemplate::flags, HEX_INSN_TEMPLATE_FLAG_HAS_JMP_TGT, HEX_MAX_OPERANDS, HEX_OP_TEMPLATE_FLAG_IMM_PC_RELATIVE, HEX_OP_TEMPLATE_TYPE_IMM, HEX_OP_TEMPLATE_TYPE_MASK, HEX_OP_TEMPLATE_TYPE_NONE, i, HexInsnTemplate::ops, and type.

Referenced by hex_disasm_with_templates().

◆ hex_disasm_with_templates()

static void hex_disasm_with_templates ( const HexInsnTemplate tpl,
HexState state,
ut32  hi_u32,
RZ_INOUT HexInsn hi,
ut64  addr,
HexPkt pkt 
)
static

Definition at line 53461 of file hexagon_disas.c.

53461  {
53462  bool print_reg_alias = rz_config_get_b(state->cfg, "plugins.hexagon.reg.alias");
53463  bool show_hash = rz_config_get_b(state->cfg, "plugins.hexagon.imm.hash");
53464  bool sign_nums = rz_config_get_b(state->cfg, "plugins.hexagon.imm.sign");
53465  char signed_imm[HEX_MAX_OPERANDS][32];
53466  // Find the right template
53467  for (; tpl->id; tpl++) {
53468  if ((hi_u32 & tpl->encoding.mask) == tpl->encoding.op) {
53469  break;
53470  }
53471  }
53472  if (!tpl->id) {
53473  // unknown/invalid
53474  return;
53475  }
53476  hi->instruction = tpl->id;
53477  hi->opcode = hi_u32;
53478  hi->parse_bits = (hi_u32 & HEX_PARSE_BITS_MASK) >> 14;
53479  hi->pred = tpl->pred;
53480 
53481  // textual disasm is built by copying tpl->syntax while inserting the ops at the right positions
53482  RzStrBuf sb;
53483  rz_strbuf_init(&sb);
53484  size_t syntax_cur = 0;
53485  size_t syntax_len = strlen(tpl->syntax);
53486 
53487  hi->op_count = 0;
53488  for (size_t i = 0; i < HEX_MAX_OPERANDS; i++) {
53489  const HexOpTemplate *op = &tpl->ops[i];
53492  break;
53493  }
53494 
53495  if (op->syntax > syntax_cur && op->syntax <= syntax_len) {
53496  rz_strbuf_append_n(&sb, tpl->syntax + syntax_cur, op->syntax - syntax_cur);
53497  syntax_cur = op->syntax;
53498  }
53499 
53500  hi->op_count++;
53501  hi->ops[i].attr = 0;
53502  switch (type) {
53503  case HEX_OP_TEMPLATE_TYPE_IMM: {
53504  hi->ops[i].type = HEX_OP_TYPE_IMM;
53505  ut32 bits_total;
53506  hi->ops[i].op.imm = hex_op_masks_extract(op->masks, hi_u32, &bits_total) << op->imm_scale;
53507  hi->ops[i].shift = op->imm_scale;
53508  if (op->imm_scale) {
53509  hi->ops[i].attr |= HEX_OP_IMM_SCALED;
53510  }
53511  if (op->info & HEX_OP_TEMPLATE_FLAG_IMM_SIGNED) {
53512  ut32 shift = bits_total + op->imm_scale - 1;
53513  rz_warn_if_fail(shift < 64);
53514  if (hi->ops[i].op.imm & (1ull << shift)) {
53515  hi->ops[i].op.imm |= UT64_MAX << shift;
53516  }
53517  }
53519  hex_extend_op(state, &hi->ops[i], false, addr);
53520  }
53521  // textual disasm
53522  const char *h = show_hash ? ((op->info & HEX_OP_TEMPLATE_FLAG_IMM_DOUBLE_HASH) ? "##" : "#") : "";
53524  rz_strbuf_appendf(&sb, "0x%" PFMT32x, pkt->pkt_addr + (st32)hi->ops[i].op.imm);
53525  } else if (op->info & HEX_OP_TEMPLATE_FLAG_IMM_SIGNED) {
53526  if (sign_nums && ((st32)hi->ops[i].op.imm) < 0) {
53527  char tmp[28] = { 0 };
53528  rz_hex_ut2st_str(hi->ops[i].op.imm, tmp, 28);
53529  snprintf(signed_imm[i], sizeof(signed_imm[i]), "%s%s", h, tmp);
53530  } else {
53531  snprintf(signed_imm[i], sizeof(signed_imm[i]), "%s0x%" PFMT32x, h, (st32)hi->ops[i].op.imm);
53532  }
53533  rz_strbuf_append(&sb, signed_imm[i]);
53534  } else {
53535  rz_strbuf_appendf(&sb, "%s0x%" PFMT32x, h, (ut32)hi->ops[i].op.imm);
53536  }
53537  break;
53538  }
53540  hi->ops[i].type = HEX_OP_TYPE_IMM;
53541  hi->ops[i].op.imm = -1;
53542  // textual disasm
53543  rz_strbuf_append(&sb, "-1");
53544  break;
53546  hi->ops[i].type = HEX_OP_TYPE_REG;
53547  hi->ops[i].op.reg = hex_op_masks_extract(op->masks, hi_u32, NULL);
53548  if (op->info & HEX_OP_TEMPLATE_FLAG_REG_OUT) {
53549  hi->ops[i].attr |= HEX_OP_REG_OUT;
53550  }
53551  if (op->info & HEX_OP_TEMPLATE_FLAG_REG_PAIR) {
53552  hi->ops[i].attr |= HEX_OP_REG_PAIR;
53553  }
53554  if (op->info & HEX_OP_TEMPLATE_FLAG_REG_QUADRUPLE) {
53555  hi->ops[i].attr |= HEX_OP_REG_QUADRUPLE;
53556  }
53557  // textual disasm
53558  int regidx = hi->ops[i].op.reg;
53559  if (op->info & HEX_OP_TEMPLATE_FLAG_REG_N_REG) {
53560  regidx = resolve_n_register(hi->ops[i].op.reg, hi->addr, pkt);
53561  }
53562  rz_strbuf_append(&sb, hex_get_reg_in_class(op->reg_cls, regidx, print_reg_alias));
53563  break;
53564  default:
53566  break;
53567  }
53568  }
53569 
53570  // Textual disassembly
53571  if (syntax_len > syntax_cur) {
53572  rz_strbuf_append_n(&sb, tpl->syntax + syntax_cur, syntax_len - syntax_cur);
53573  }
53574  strncpy(hi->mnem_infix, rz_strbuf_get(&sb), sizeof(hi->mnem_infix) - 1);
53575  snprintf(hi->mnem, sizeof(hi->mnem), "%s%s%s", hi->pkt_info.mnem_prefix, hi->mnem_infix, hi->pkt_info.mnem_postfix);
53576 
53577  // RzAnalysisOp contents
53578  hi->ana_op.addr = hi->addr;
53579  hi->ana_op.id = hi->instruction;
53580  hi->ana_op.size = 4;
53581  hi->ana_op.cond = tpl->cond;
53582  hi->ana_op.type = hi->ana_op.prefix == RZ_ANALYSIS_OP_PREFIX_HWLOOP_END ? RZ_ANALYSIS_OP_TYPE_CJMP : tpl->type;
53583  int jmp_target_imm_op_index = get_jmp_target_imm_op_index(tpl);
53584  if (jmp_target_imm_op_index >= 0) {
53586  pkt->is_eob = true;
53587  }
53588  hi->ana_op.jump = pkt->pkt_addr + (st32)hi->ops[jmp_target_imm_op_index].op.imm;
53590  hi->ana_op.fail = hi->ana_op.addr + 4;
53591  }
53593  if (tpl->flags & HEX_INSN_TEMPLATE_FLAG_LOOP_0) {
53594  pkt->hw_loop0_addr = hi->ana_op.jump;
53595  } else if (tpl->flags & HEX_INSN_TEMPLATE_FLAG_LOOP_1) {
53596  pkt->hw_loop1_addr = hi->ana_op.jump;
53597  }
53598  }
53599  }
53600  for (size_t i = 0; i < RZ_MIN(hi->op_count, RZ_ARRAY_SIZE(hi->ana_op.analysis_vals)); i++) {
53601  const HexOpTemplate *op = &tpl->ops[i];
53603  if (jmp_target_imm_op_index >= 0 && type == HEX_OP_TEMPLATE_TYPE_IMM) {
53604  hi->ana_op.val = hi->ana_op.jump;
53605  hi->ana_op.analysis_vals[i].imm = hi->ana_op.jump;
53606  } else if (tpl->id == HEX_INS_J2_JUMPR) {
53607  // jumpr Rs is sometimes used as jumpr R31.
53608  // Block analysis needs to check it to recognize if this jump is a return.
53609  hi->ana_op.analysis_vals[0].plugin_specific = hi->ops[0].op.reg;
53610  } else if (type == HEX_OP_TEMPLATE_TYPE_IMM) {
53611  hi->ana_op.analysis_vals[i].imm = hi->ops[i].op.imm;
53612  }
53613  }
53614 
53615  if (tpl->id == HEX_INS_A4_EXT) {
53616  hex_extend_op(state, &(hi->ops[0]), true, addr);
53617  }
53618 }
#define PFMT32x
static RZ_NULLABLE RzILOpBitVector * shift(RzILOpBitVector *val, RZ_NULLABLE RzILOpBool **carry_out, arm_shifter type, RZ_OWN RzILOpBitVector *dist)
Definition: arm_il32.c:190
static SblHeader sb
Definition: bin_mbn.c:26
RZ_API bool rz_config_get_b(RzConfig *cfg, RZ_NONNULL const char *name)
Definition: config.c:142
#define NULL
Definition: cris-opc.c:27
uint32_t ut32
char * hex_get_reg_in_class(HexRegClass cls, int opcode_reg, bool get_alias)
Definition: hexagon.c:829
int resolve_n_register(const int reg_num, const ut32 addr, const HexPkt *p)
Resolves the 3 bit value of an Nt.new reg to the general register of the producer.
Definition: hexagon.c:878
@ HEX_OP_TYPE_REG
Definition: hexagon.h:56
@ HEX_OP_TYPE_IMM
Definition: hexagon.h:55
#define HEX_PARSE_BITS_MASK
Definition: hexagon.h:22
@ HEX_OP_REG_QUADRUPLE
Definition: hexagon.h:66
@ HEX_OP_IMM_SCALED
Definition: hexagon.h:68
@ HEX_OP_REG_OUT
Definition: hexagon.h:67
@ HEX_OP_REG_PAIR
Definition: hexagon.h:65
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 int get_jmp_target_imm_op_index(const HexInsnTemplate *tpl)
static ut32 hex_op_masks_extract(const HexOpMask *masks, ut32 val, RZ_OUT ut32 *bits_total)
@ HEX_INS_J2_JUMPR
Definition: hexagon_insn.h:417
@ HEX_INS_A4_EXT
Definition: hexagon_insn.h:215
hi(addr) 0x03
snprintf
Definition: kernel.h:364
@ RZ_ANALYSIS_OP_PREFIX_HWLOOP_END
Definition: rz_analysis.h:353
@ RZ_ANALYSIS_OP_TYPE_CJMP
Definition: rz_analysis.h:373
#define rz_warn_if_reached()
Definition: rz_assert.h:29
#define rz_warn_if_fail(expr)
Definition: rz_assert.h:35
RZ_API void rz_hex_ut2st_str(const ut32 in, RZ_INOUT char *out, const int len)
Takes an unsigned 32bit integer with MSB set to 1 and returns the signed integer in hex format as str...
Definition: hex.c:405
RZ_API char * rz_strbuf_get(RzStrBuf *sb)
Definition: strbuf.c:321
RZ_API bool rz_strbuf_append(RzStrBuf *sb, const char *s)
Definition: strbuf.c:222
RZ_API bool rz_strbuf_appendf(RzStrBuf *sb, const char *fmt,...) RZ_PRINTF_CHECK(2
RZ_API void rz_strbuf_init(RzStrBuf *sb)
Definition: strbuf.c:33
RZ_API bool rz_strbuf_append_n(RzStrBuf *sb, const char *s, size_t l)
Definition: strbuf.c:229
#define RZ_ARRAY_SIZE(x)
Definition: rz_types.h:300
#define RZ_MIN(x, y)
#define UT64_MAX
Definition: rz_types_base.h:86
#define st32
Definition: rz_types_base.h:12
#define h(i)
Definition: sha256.c:48
const char * syntax
Definition: hexagon_disas.c:93
struct HexInsnTemplate::@69 encoding
_RzAnalysisOpType type
Definition: hexagon_disas.c:94
enum HEX_INS id
Definition: hexagon_disas.c:88
ut32 hw_loop0_addr
Definition: hexagon.h:118
ut32 pkt_addr
Definition: hexagon.h:121
bool is_eob
Definition: hexagon.h:122
ut32 hw_loop1_addr
Definition: hexagon.h:119
Definition: dis.h:43
if(dbg->bits==RZ_SYS_BITS_64)
Definition: windows-arm64.h:4
static int addr
Definition: z80asm.c:58

References addr, HexInsnTemplate::cond, HexInsnTemplate::encoding, HexInsnTemplate::flags, get_jmp_target_imm_op_index(), h, hex_extend_op(), hex_get_reg_in_class(), HEX_INS_A4_EXT, HEX_INS_J2_JUMPR, HEX_INSN_TEMPLATE_FLAG_CALL, HEX_INSN_TEMPLATE_FLAG_LOOP_0, HEX_INSN_TEMPLATE_FLAG_LOOP_1, HEX_INSN_TEMPLATE_FLAG_LOOP_BEGIN, HEX_INSN_TEMPLATE_FLAG_PREDICATED, HEX_MAX_OPERANDS, HEX_OP_IMM_SCALED, hex_op_masks_extract(), HEX_OP_REG_OUT, HEX_OP_REG_PAIR, HEX_OP_REG_QUADRUPLE, HEX_OP_TEMPLATE_FLAG_IMM_DOUBLE_HASH, HEX_OP_TEMPLATE_FLAG_IMM_EXTENDABLE, HEX_OP_TEMPLATE_FLAG_IMM_PC_RELATIVE, HEX_OP_TEMPLATE_FLAG_IMM_SIGNED, HEX_OP_TEMPLATE_FLAG_REG_N_REG, HEX_OP_TEMPLATE_FLAG_REG_OUT, HEX_OP_TEMPLATE_FLAG_REG_PAIR, HEX_OP_TEMPLATE_FLAG_REG_QUADRUPLE, HEX_OP_TEMPLATE_TYPE_IMM, HEX_OP_TEMPLATE_TYPE_IMM_CONST, HEX_OP_TEMPLATE_TYPE_MASK, HEX_OP_TEMPLATE_TYPE_NONE, HEX_OP_TEMPLATE_TYPE_REG, HEX_OP_TYPE_IMM, HEX_OP_TYPE_REG, HEX_PARSE_BITS_MASK, hi(), HexPkt::hw_loop0_addr, HexPkt::hw_loop1_addr, i, HexInsnTemplate::id, if(), HexPkt::is_eob, HexInsnTemplate::mask, NULL, HexInsnTemplate::op, HexInsnTemplate::ops, PFMT32x, HexPkt::pkt_addr, HexInsnTemplate::pred, resolve_n_register(), RZ_ANALYSIS_OP_PREFIX_HWLOOP_END, RZ_ANALYSIS_OP_TYPE_CJMP, RZ_ARRAY_SIZE, rz_config_get_b(), rz_hex_ut2st_str(), RZ_MIN, rz_strbuf_append(), rz_strbuf_append_n(), rz_strbuf_appendf(), rz_strbuf_get(), rz_strbuf_init(), rz_warn_if_fail, rz_warn_if_reached, sb, shift(), snprintf, st32, HexInsnTemplate::syntax, autogen_x86imm::tmp, HexInsnTemplate::type, type, and UT64_MAX.

Referenced by hexagon_disasm_instruction().

◆ hex_op_masks_extract()

static ut32 hex_op_masks_extract ( const HexOpMask masks,
ut32  val,
RZ_OUT ut32 bits_total 
)
static
Parameters
masksarray of exactly HEX_OP_MASKS_MAX items, ordered ascending by shift, optionally terminated earlier by an entry with bits = 0

Definition at line 53419 of file hexagon_disas.c.

53419  {
53420  ut8 off = 0;
53421  ut32 r = 0;
53422  for (size_t i = 0; i < HEX_OP_MASKS_MAX; i++) {
53423  const HexOpMask *m = &masks[i];
53424  if (!m->bits) {
53425  break;
53426  }
53427  r |= ((val >> m->shift) & rz_num_bitmask(m->bits)) << off;
53428  off += m->bits;
53429  }
53430  if (bits_total) {
53431  *bits_total = off;
53432  }
53433  return r;
53434 }
ut16 val
Definition: armass64_const.h:6
#define r
Definition: crypto_rc6.c:12
#define HEX_OP_MASKS_MAX
Definition: hexagon_disas.c:29
uint8_t ut8
Definition: lh5801.h:11
int off
Definition: pal.c:13
static ut64 rz_num_bitmask(ut8 width)
Get the 64-bit value that has exactly its width lowest bits set to 1. e.g. rz_num_bitmask(2) == 0b11 ...
Definition: rz_num.h:134

References HEX_OP_MASKS_MAX, i, regress::m, off, r, rz_num_bitmask(), and val.

Referenced by hex_disasm_with_templates().

◆ hexagon_disasm_instruction()

int hexagon_disasm_instruction ( HexState state,
const ut32  hi_u32,
RZ_INOUT HexInsn hi,
HexPkt pkt 
)

Definition at line 53620 of file hexagon_disas.c.

53620  {
53621  ut32 addr = hi->addr;
53622  if (hi->pkt_info.last_insn) {
53623  switch (hex_get_loop_flag(pkt)) {
53624  default: break;
53625  case HEX_LOOP_01:
53626  hi->ana_op.prefix = RZ_ANALYSIS_OP_PREFIX_HWLOOP_END;
53627  hi->ana_op.fail = pkt->hw_loop0_addr;
53628  hi->ana_op.jump = pkt->hw_loop1_addr;
53629  hi->ana_op.val = hi->ana_op.jump;
53630  break;
53631  case HEX_LOOP_0:
53632  hi->ana_op.prefix = RZ_ANALYSIS_OP_PREFIX_HWLOOP_END;
53633  hi->ana_op.jump = pkt->hw_loop0_addr;
53634  hi->ana_op.val = hi->ana_op.jump;
53635  break;
53636  case HEX_LOOP_1:
53637  hi->ana_op.prefix = RZ_ANALYSIS_OP_PREFIX_HWLOOP_END;
53638  hi->ana_op.jump = pkt->hw_loop1_addr;
53639  hi->ana_op.val = hi->ana_op.jump;
53640  break;
53641  }
53642  }
53643  if (hi_u32 != 0x00000000) {
53644  if (((hi_u32 >> 14) & 0x3) == 0) {
53645  // DUPLEXES
53646  ut32 cat = (((hi_u32 >> 29) & 0xF) << 1) | ((hi_u32 >> 13) & 1);
53647  if (cat < 0xf) {
53649  hi->duplex = true;
53650  }
53651  } else {
53652  ut32 cat = (hi_u32 >> 28) & 0xF;
53654  }
53655  }
53656  if (pkt->is_eob && is_last_instr(hi->parse_bits)) {
53657  hi->ana_op.eob = true;
53658  }
53659  if (hi->instruction == HEX_INS_INVALID_DECODE) {
53660  hi->parse_bits = ((hi_u32)&0xc000) >> 14;
53661  hi->ana_op.type = RZ_ANALYSIS_OP_TYPE_ILL;
53662  sprintf(hi->mnem_infix, "invalid");
53663  sprintf(hi->mnem, "%s%s%s", hi->pkt_info.mnem_prefix, hi->mnem_infix, hi->pkt_info.mnem_postfix);
53664  }
53665 
53666  return 4;
53667 }
@ HEX_LOOP_0
Definition: hexagon.h:73
@ HEX_LOOP_1
Definition: hexagon.h:74
@ HEX_LOOP_01
Definition: hexagon.h:75
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 const HexInsnTemplate * templates_duplex[]
static void hex_disasm_with_templates(const HexInsnTemplate *tpl, HexState *state, ut32 hi_u32, RZ_INOUT HexInsn *hi, ut64 addr, HexPkt *pkt)
static const HexInsnTemplate * templates_normal[]
static bool is_last_instr(const ut8 parse_bits)
@ HEX_INS_INVALID_DECODE
Definition: hexagon_insn.h:13
sprintf
Definition: kernel.h:365
@ RZ_ANALYSIS_OP_TYPE_ILL
Definition: rz_analysis.h:387
static int cat(char *argv[])
Definition: ziptool.c:170

References addr, cat(), hex_disasm_with_templates(), hex_get_loop_flag(), HEX_INS_INVALID_DECODE, HEX_LOOP_0, HEX_LOOP_01, HEX_LOOP_1, hi(), HexPkt::hw_loop0_addr, HexPkt::hw_loop1_addr, HexPkt::is_eob, is_last_instr(), RZ_ANALYSIS_OP_PREFIX_HWLOOP_END, RZ_ANALYSIS_OP_TYPE_ILL, sprintf, templates_duplex, and templates_normal.

Referenced by hexagon_reverse_opcode().

◆ is_last_instr()

static bool is_last_instr ( const ut8  parse_bits)
inlinestatic

Definition at line 53410 of file hexagon_disas.c.

53410  {
53411  // Duplex instr. (parse bits = 0) are always the last.
53412  return ((parse_bits == 0x3) || (parse_bits == 0x0));
53413 }

Referenced by hexagon_disasm_instruction().

Variable Documentation

◆ templates_duplex

const HexInsnTemplate* templates_duplex[]
static
Initial value:
= {
}
static const HexInsnTemplate templates_duplex_0x6[]
static const HexInsnTemplate templates_duplex_0xa[]
static const HexInsnTemplate templates_duplex_0x5[]
static const HexInsnTemplate templates_duplex_0x3[]
static const HexInsnTemplate templates_duplex_0xe[]
static const HexInsnTemplate templates_duplex_0x7[]
static const HexInsnTemplate templates_duplex_0x8[]
static const HexInsnTemplate templates_duplex_0x4[]
static const HexInsnTemplate templates_duplex_0xd[]
static const HexInsnTemplate templates_duplex_0x0[]
Definition: hexagon_disas.c:97
static const HexInsnTemplate templates_duplex_0x2[]
static const HexInsnTemplate templates_duplex_0xb[]
static const HexInsnTemplate templates_duplex_0x9[]
static const HexInsnTemplate templates_duplex_0xc[]
static const HexInsnTemplate templates_duplex_0x1[]

Definition at line 20286 of file hexagon_disas.c.

Referenced by hexagon_disasm_instruction().

◆ templates_duplex_0x0

const HexInsnTemplate templates_duplex_0x0[]
static

Definition at line 97 of file hexagon_disas.c.

◆ templates_duplex_0x1

const HexInsnTemplate templates_duplex_0x1[]
static

Definition at line 152 of file hexagon_disas.c.

◆ templates_duplex_0x2

const HexInsnTemplate templates_duplex_0x2[]
static

Definition at line 646 of file hexagon_disas.c.

◆ templates_duplex_0x3

const HexInsnTemplate templates_duplex_0x3[]
static

Definition at line 2186 of file hexagon_disas.c.

◆ templates_duplex_0x4

const HexInsnTemplate templates_duplex_0x4[]
static

Definition at line 7085 of file hexagon_disas.c.

◆ templates_duplex_0x5

const HexInsnTemplate templates_duplex_0x5[]
static

Definition at line 7895 of file hexagon_disas.c.

◆ templates_duplex_0x6

const HexInsnTemplate templates_duplex_0x6[]
static

Definition at line 13640 of file hexagon_disas.c.

◆ templates_duplex_0x7

const HexInsnTemplate templates_duplex_0x7[]
static

Definition at line 14450 of file hexagon_disas.c.

◆ templates_duplex_0x8

const HexInsnTemplate templates_duplex_0x8[]
static

Definition at line 17478 of file hexagon_disas.c.

◆ templates_duplex_0x9

const HexInsnTemplate templates_duplex_0x9[]
static

Definition at line 17550 of file hexagon_disas.c.

◆ templates_duplex_0xa

const HexInsnTemplate templates_duplex_0xa[]
static

Definition at line 17896 of file hexagon_disas.c.

◆ templates_duplex_0xb

const HexInsnTemplate templates_duplex_0xb[]
static

Definition at line 17951 of file hexagon_disas.c.

◆ templates_duplex_0xc

const HexInsnTemplate templates_duplex_0xc[]
static

Definition at line 18211 of file hexagon_disas.c.

◆ templates_duplex_0xd

const HexInsnTemplate templates_duplex_0xd[]
static

Definition at line 18471 of file hexagon_disas.c.

◆ templates_duplex_0xe

const HexInsnTemplate templates_duplex_0xe[]
static

Definition at line 19755 of file hexagon_disas.c.

◆ templates_normal

const HexInsnTemplate* templates_normal[]
static
Initial value:
= {
}
static const HexInsnTemplate templates_normal_0xa[]
static const HexInsnTemplate templates_normal_0x6[]
static const HexInsnTemplate templates_normal_0x1[]
static const HexInsnTemplate templates_normal_0x4[]
static const HexInsnTemplate templates_normal_0x8[]
static const HexInsnTemplate templates_normal_0xf[]
static const HexInsnTemplate templates_normal_0x7[]
static const HexInsnTemplate templates_normal_0x2[]
static const HexInsnTemplate templates_normal_0xb[]
static const HexInsnTemplate templates_normal_0x3[]
static const HexInsnTemplate templates_normal_0x0[]
static const HexInsnTemplate templates_normal_0xd[]
static const HexInsnTemplate templates_normal_0x9[]
static const HexInsnTemplate templates_normal_0x5[]
static const HexInsnTemplate templates_normal_0xe[]
static const HexInsnTemplate templates_normal_0xc[]

Definition at line 53391 of file hexagon_disas.c.

Referenced by hexagon_disasm_instruction().

◆ templates_normal_0x0

const HexInsnTemplate templates_normal_0x0[]
static
Initial value:
= {
{
.encoding = { .mask = 0xf0000000, .op = 0x0 },
.ops = {
{ .info = HEX_OP_TEMPLATE_TYPE_IMM | HEX_OP_TEMPLATE_FLAG_IMM_EXTENDABLE | HEX_OP_TEMPLATE_FLAG_IMM_DOUBLE_HASH, .masks = { { 0xe, 0 }, { 0xc, 16 } }, .imm_scale = 6, .syntax = 7 },
},
.pred = HEX_NOPRED,
.cond = RZ_TYPE_COND_AL,
.syntax = "immext()",
},
{
.encoding = { .mask = 0xffff3fff, .op = 0x0 },
.pred = HEX_NOPRED,
.cond = RZ_TYPE_COND_AL,
.syntax = "<invalid>",
},
{ { 0 } },
}
@ HEX_NOPRED
Definition: hexagon.h:29
@ RZ_ANALYSIS_OP_TYPE_NULL
Definition: rz_analysis.h:367
@ RZ_TYPE_COND_AL
Always executed (no condition)
Definition: rz_type.h:183

Definition at line 20304 of file hexagon_disas.c.

◆ templates_normal_0x1

const HexInsnTemplate templates_normal_0x1[]
static

Definition at line 20329 of file hexagon_disas.c.

◆ templates_normal_0x2

const HexInsnTemplate templates_normal_0x2[]
static

Definition at line 28251 of file hexagon_disas.c.

◆ templates_normal_0x3

const HexInsnTemplate templates_normal_0x3[]
static

Definition at line 30999 of file hexagon_disas.c.

◆ templates_normal_0x4

const HexInsnTemplate templates_normal_0x4[]
static

Definition at line 32735 of file hexagon_disas.c.

◆ templates_normal_0x5

const HexInsnTemplate templates_normal_0x5[]
static

Definition at line 33999 of file hexagon_disas.c.

◆ templates_normal_0x6

const HexInsnTemplate templates_normal_0x6[]
static

Definition at line 34500 of file hexagon_disas.c.

◆ templates_normal_0x7

const HexInsnTemplate templates_normal_0x7[]
static

Definition at line 35615 of file hexagon_disas.c.

◆ templates_normal_0x8

const HexInsnTemplate templates_normal_0x8[]
static

Definition at line 36484 of file hexagon_disas.c.

◆ templates_normal_0x9

const HexInsnTemplate templates_normal_0x9[]
static

Definition at line 38875 of file hexagon_disas.c.

◆ templates_normal_0xa

const HexInsnTemplate templates_normal_0xa[]
static

Definition at line 41214 of file hexagon_disas.c.

◆ templates_normal_0xb

const HexInsnTemplate templates_normal_0xb[]
static
Initial value:
= {
{
.encoding = { .mask = 0xf0000000, .op = 0xb0000000 },
.ops = {
{ .info = HEX_OP_TEMPLATE_TYPE_REG | HEX_OP_TEMPLATE_FLAG_REG_OUT, .masks = { { 0x5, 0 } }, .reg_cls = HEX_REG_CLASS_INT_REGS, .syntax = 0 },
{ .info = HEX_OP_TEMPLATE_TYPE_REG, .masks = { { 0x5, 16 } }, .reg_cls = HEX_REG_CLASS_INT_REGS, .syntax = 7 },
},
.pred = HEX_NOPRED,
.cond = RZ_TYPE_COND_AL,
.syntax = " = add(,)",
},
{ { 0 } },
}
@ HEX_REG_CLASS_INT_REGS
Definition: hexagon.h:154
@ HEX_INS_A2_ADDI
Definition: hexagon_insn.h:30

Definition at line 43622 of file hexagon_disas.c.

◆ templates_normal_0xc

const HexInsnTemplate templates_normal_0xc[]
static

Definition at line 43640 of file hexagon_disas.c.

◆ templates_normal_0xd

const HexInsnTemplate templates_normal_0xd[]
static

Definition at line 45431 of file hexagon_disas.c.

◆ templates_normal_0xe

const HexInsnTemplate templates_normal_0xe[]
static

Definition at line 47575 of file hexagon_disas.c.

◆ templates_normal_0xf

const HexInsnTemplate templates_normal_0xf[]
static

Definition at line 52540 of file hexagon_disas.c.