Rizin
unix-like reverse engineering framework and cli tools
xtensa-dis.c File Reference
#include "sysdep.h"
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <string.h>
#include "xtensa-isa.h"
#include "ansidecl.h"
#include <setjmp.h>
#include "disas-asm.h"
#include "libiberty.h"

Go to the source code of this file.

Classes

struct  dis_private
 

Macros

#define MAX(a, b)   (((a)) > ((b)) ? ((a)) : ((b)))
 
#define OPCODES_SIGJMP_BUF   void*
 
#define OPCODES_SIGSETJMP(buf)   nothing()
 
#define OPCODES_SIGLONGJMP(buf, val)   nothing()
 

Functions

static void nothing (void)
 
static int fetch_data (struct disassemble_info *info, bfd_vma memaddr)
 
static void print_xtensa_operand (bfd_vma memaddr, struct disassemble_info *info, xtensa_opcode opc, int opnd, unsigned operand_val)
 
int print_insn_xtensa (bfd_vma memaddr, struct disassemble_info *info)
 

Variables

xtensa_isa xtensa_default_isa
 
int show_raw_fields
 

Macro Definition Documentation

◆ MAX

#define MAX (   a,
  b 
)    (((a)) > ((b)) ? ((a)) : ((b)))

Definition at line 40 of file xtensa-dis.c.

◆ OPCODES_SIGJMP_BUF

#define OPCODES_SIGJMP_BUF   void*

Definition at line 48 of file xtensa-dis.c.

◆ OPCODES_SIGLONGJMP

#define OPCODES_SIGLONGJMP (   buf,
  val 
)    nothing()

Definition at line 50 of file xtensa-dis.c.

◆ OPCODES_SIGSETJMP

#define OPCODES_SIGSETJMP (   buf)    nothing()

Definition at line 49 of file xtensa-dis.c.

Function Documentation

◆ fetch_data()

static int fetch_data ( struct disassemble_info info,
bfd_vma  memaddr 
)
static

Definition at line 68 of file xtensa-dis.c.

69 {
70  int length, status = 0;
71  struct dis_private *priv = (struct dis_private *) info->private_data;
72  int insn_size = xtensa_isa_maxlength (xtensa_default_isa);
73 
74  /* Read the maximum instruction size, padding with zeros if we go past
75  the end of the text section. This code will automatically adjust
76  length when we hit the end of the buffer. */
77 
78  memset (priv->byte_buf, 0, insn_size);
79  for (length = insn_size; length > 0; length--)
80  {
81  status = (*info->read_memory_func) (memaddr, priv->byte_buf, length,
82  info);
83  if (status == 0) {
84  return length;
85  }
86  }
87  (*info->memory_error_func) (status, memaddr, info);
88  OPCODES_SIGLONGJMP (priv->bailout, 1);
89 return -1;
90  /*NOTREACHED*/
91 }
RzBinInfo * info(RzBinFile *bf)
Definition: bin_ne.c:86
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len static semflg const void static shmflg const struct timespec struct timespec static rem const char static group const void length
Definition: sflib.h:133
return memset(p, 0, total)
static const char struct stat static buf struct stat static buf static vhangup int status
Definition: sflib.h:145
bfd_byte * byte_buf
Definition: xtensa-dis.c:62
OPCODES_SIGJMP_BUF bailout
Definition: xtensa-dis.c:63
#define OPCODES_SIGLONGJMP(buf, val)
Definition: xtensa-dis.c:50
xtensa_isa xtensa_default_isa
Definition: elf32-xtensa.c:147
int xtensa_isa_maxlength(xtensa_isa isa)
Definition: xtensa-isa.c:405

References dis_private::bailout, dis_private::byte_buf, info(), length, memset(), OPCODES_SIGLONGJMP, status, xtensa_default_isa, and xtensa_isa_maxlength().

Referenced by print_insn_xtensa().

◆ nothing()

static void nothing ( void  )
static

Definition at line 44 of file xtensa-dis.c.

44  {
45  return;
46 }

Referenced by rz_test_main().

◆ print_insn_xtensa()

int print_insn_xtensa ( bfd_vma  memaddr,
struct disassemble_info info 
)

Definition at line 158 of file xtensa-dis.c.

159 {
160  unsigned operand_val;
161  int bytes_fetched, size, maxsize, i, n, noperands, nslots;
162  xtensa_isa isa;
164  xtensa_format fmt;
165  struct dis_private priv;
166  static bfd_byte *byte_buf = NULL;
167  static xtensa_insnbuf insn_buffer = NULL;
168  static xtensa_insnbuf slot_buffer = NULL;
169  int first, first_slot, valid_insn;
170 
171  if (!xtensa_default_isa) {
173  }
174 
175  info->target = 0;
177 
178  /* Set bytes_per_line to control the amount of whitespace between the hex
179  values and the opcode. For Xtensa, we always print one "chunk" and we
180  vary bytes_per_chunk to determine how many bytes to print. (objdump
181  would apparently prefer that we set bytes_per_chunk to 1 and vary
182  bytes_per_line but that makes it hard to fit 64-bit instructions on
183  an 80-column screen.) The value of bytes_per_line here is not exactly
184  right, because objdump adds an extra space for each chunk so that the
185  amount of whitespace depends on the chunk size. Oh well, it's good
186  enough.... Note that we set the minimum size to 4 to accommodate
187  literal pools. */
188  info->bytes_per_line = MAX (maxsize, 4);
189 
190  /* Allocate buffers the first time through. */
191  if (!insn_buffer)
192  {
195  byte_buf = (bfd_byte *) xmalloc (MAX (maxsize, 4));
196  }
197 
198  priv.byte_buf = byte_buf;
199 
200  info->private_data = (void *) &priv;
201 #if 0
202  if (OPCODES_SIGSETJMP (priv.bailout) != 0)
203  /* Error return. */
204  return -1;
205 #endif
206 
207  /* Don't set "isa" before the setjmp to keep the compiler from griping. */
208  isa = xtensa_default_isa;
209  size = 0;
210  nslots = 0;
211 
212  /* Fetch the maximum size instruction. */
213  bytes_fetched = fetch_data (info, memaddr);
214 
215  /* Copy the bytes into the decode buffer. */
216  memset (insn_buffer, 0, (xtensa_insnbuf_size (isa) *
217  sizeof (xtensa_insnbuf_word)));
218  xtensa_insnbuf_from_chars (isa, insn_buffer, priv.byte_buf, bytes_fetched);
219 
220  fmt = xtensa_format_decode (isa, insn_buffer);
221  if (fmt == XTENSA_UNDEFINED || ((size = xtensa_format_length (isa, fmt)) > bytes_fetched)) {
222  valid_insn = 0;
223  } else {
224  /* Make sure all the opcodes are valid. */
225  valid_insn = 1;
226  nslots = xtensa_format_num_slots (isa, fmt);
227  for (n = 0; n < nslots; n++) {
228  xtensa_format_get_slot (isa, fmt, n, insn_buffer, slot_buffer);
229  if (xtensa_opcode_decode (isa, fmt, n, slot_buffer) == XTENSA_UNDEFINED) {
230  valid_insn = 0;
231  break;
232  }
233  }
234  }
235 
236  if (!valid_insn)
237  {
238  (*info->fprintf_func) (info->stream, ".byte %#02x", priv.byte_buf[0]);
239  return 1;
240  }
241 
242  if (nslots > 1) {
243  (*info->fprintf_func) (info->stream, "{ ");
244  }
245 
246  first_slot = 1;
247  for (n = 0; n < nslots; n++) {
248  if (first_slot) {
249  first_slot = 0;
250  } else {
251  (*info->fprintf_func) (info->stream, "; ");
252  }
253 
254  xtensa_format_get_slot (isa, fmt, n, insn_buffer, slot_buffer);
255  opc = xtensa_opcode_decode (isa, fmt, n, slot_buffer);
256  (*info->fprintf_func) (info->stream, "%s",
257  xtensa_opcode_name (isa, opc));
258 
259  /* Print the operands (if any). */
260  noperands = xtensa_opcode_num_operands (isa, opc);
261  first = 1;
262  for (i = 0; i < noperands; i++) {
263  if (xtensa_operand_is_visible (isa, opc, i) == 0) {
264  continue;
265  }
266  if (first) {
267  (*info->fprintf_func) (info->stream, " ");
268  first = 0;
269  } else {
270  (*info->fprintf_func) (info->stream, ", ");
271  }
272  (void)xtensa_operand_get_field (isa, opc, i, fmt, n,
273  slot_buffer, &operand_val);
274 
275  print_xtensa_operand (memaddr, info, opc, i, operand_val);
276  }
277  }
278 
279  if (nslots > 1) {
280  (*info->fprintf_func) (info->stream, " }");
281  }
282 
283  info->bytes_per_chunk = size;
284  info->display_endian = info->endian;
285 
286  return size;
287 }
lzma_index ** i
Definition: index.h:629
#define NULL
Definition: cris-opc.c:27
static ut64 opc
Definition: desil.c:33
#define xmalloc
Definition: disas-asm.h:43
voidpf void uLong size
Definition: ioapi.h:138
int n
Definition: mipsasm.c:19
unsigned char bfd_byte
Definition: mybfd.h:176
static void print_xtensa_operand(bfd_vma memaddr, struct disassemble_info *info, xtensa_opcode opc, int opnd, unsigned operand_val)
Definition: xtensa-dis.c:95
static int fetch_data(struct disassemble_info *info, bfd_vma memaddr)
Definition: xtensa-dis.c:68
#define OPCODES_SIGSETJMP(buf)
Definition: xtensa-dis.c:49
#define MAX(a, b)
Definition: xtensa-dis.c:40
int xtensa_format_get_slot(xtensa_isa isa, xtensa_format fmt, int slot, const xtensa_insnbuf insn, xtensa_insnbuf slotbuf)
Definition: xtensa-isa.c:629
int xtensa_opcode
Definition: xtensa-isa.h:83
int xtensa_format
Definition: xtensa-isa.h:84
int xtensa_format_num_slots(xtensa_isa isa, xtensa_format fmt)
Definition: xtensa-isa.c:606
uint32 xtensa_insnbuf_word
Definition: xtensa-isa.h:178
xtensa_opcode xtensa_opcode_decode(xtensa_isa isa, xtensa_format fmt, int slot, const xtensa_insnbuf slotbuf)
Definition: xtensa-isa.c:708
int xtensa_opcode_num_operands(xtensa_isa isa, xtensa_opcode opc)
Definition: xtensa-isa.c:816
xtensa_insnbuf_word * xtensa_insnbuf
Definition: xtensa-isa.h:179
int xtensa_insnbuf_size(xtensa_isa isa)
Definition: xtensa-isa.c:80
int xtensa_operand_get_field(xtensa_isa isa, xtensa_opcode opc, int opnd, xtensa_format fmt, int slot, const xtensa_insnbuf slotbuf, uint32 *valp)
Definition: xtensa-isa.c:975
int xtensa_format_length(xtensa_isa isa, xtensa_format fmt)
Definition: xtensa-isa.c:597
#define XTENSA_UNDEFINED
Definition: xtensa-isa.h:93
xtensa_format xtensa_format_decode(xtensa_isa isa, const xtensa_insnbuf insn)
Definition: xtensa-isa.c:570
void xtensa_insnbuf_from_chars(xtensa_isa isa, xtensa_insnbuf insn, const unsigned char *cp, int num_chars)
Definition: xtensa-isa.c:196
xtensa_isa xtensa_isa_init(xtensa_isa_status *errno_p, char **error_msg_p)
Definition: xtensa-isa.c:248
int xtensa_operand_is_visible(xtensa_isa isa, xtensa_opcode opc, int opnd)
Definition: xtensa-isa.c:924
const char * xtensa_opcode_name(xtensa_isa isa, xtensa_opcode opc)
Definition: xtensa-isa.c:759
xtensa_insnbuf xtensa_insnbuf_alloc(xtensa_isa isa)
Definition: xtensa-isa.c:88

References dis_private::bailout, dis_private::byte_buf, fetch_data(), i, info(), MAX, memset(), n, NULL, opc, OPCODES_SIGSETJMP, print_xtensa_operand(), xmalloc, xtensa_default_isa, xtensa_format_decode(), xtensa_format_get_slot(), xtensa_format_length(), xtensa_format_num_slots(), xtensa_insnbuf_alloc(), xtensa_insnbuf_from_chars(), xtensa_insnbuf_size(), xtensa_isa_init(), xtensa_isa_maxlength(), xtensa_opcode_decode(), xtensa_opcode_name(), xtensa_opcode_num_operands(), xtensa_operand_get_field(), xtensa_operand_is_visible(), and XTENSA_UNDEFINED.

Referenced by disassemble().

◆ print_xtensa_operand()

static void print_xtensa_operand ( bfd_vma  memaddr,
struct disassemble_info info,
xtensa_opcode  opc,
int  opnd,
unsigned  operand_val 
)
static

Definition at line 95 of file xtensa-dis.c.

100 {
102  int signed_operand_val;
103 
104  if (show_raw_fields)
105  {
106  if (operand_val < 0xa) {
107  (*info->fprintf_func) (info->stream, "%u", operand_val);
108  } else {
109  (*info->fprintf_func) (info->stream, "0x%x", operand_val);
110  }
111  return;
112  }
113 
114  (void) xtensa_operand_decode (isa, opc, opnd, &operand_val);
115  signed_operand_val = (int) operand_val;
116 
117  if (xtensa_operand_is_register (isa, opc, opnd) == 0)
118  {
119  if (xtensa_operand_is_PCrelative (isa, opc, opnd) == 1)
120  {
121  (void) xtensa_operand_undo_reloc (isa, opc, opnd,
122  &operand_val, memaddr);
123  info->target = operand_val;
124  (*info->print_address_func) (info->target, info);
125  }
126  else
127  {
128  if ((signed_operand_val > -256) && (signed_operand_val < 256)) {
129  (*info->fprintf_func) (info->stream, "%d", signed_operand_val);
130  } else {
131  (*info->fprintf_func) (info->stream, "0x%x", signed_operand_val);
132  }
133  }
134  }
135  else
136  {
137  int i = 1;
138  xtensa_regfile opnd_rf = xtensa_operand_regfile (isa, opc, opnd);
139  (*info->fprintf_func) (info->stream, "%s%u",
140  xtensa_regfile_shortname (isa, opnd_rf),
141  operand_val);
142  while (i < xtensa_operand_num_regs (isa, opc, opnd))
143  {
144  operand_val++;
145  (*info->fprintf_func) (info->stream, ":%s%u",
146  xtensa_regfile_shortname (isa, opnd_rf),
147  operand_val);
148  i++;
149  }
150  }
151 }
static int
Definition: sfsocketcall.h:114
int show_raw_fields
Definition: xtensa-dis.c:58
const char * xtensa_regfile_shortname(xtensa_isa isa, xtensa_regfile rf)
Definition: xtensa-isa.c:1474
int xtensa_operand_is_PCrelative(xtensa_isa isa, xtensa_opcode opc, int opnd)
Definition: xtensa-isa.c:1221
int xtensa_operand_undo_reloc(xtensa_isa isa, xtensa_opcode opc, int opnd, uint32 *valp, uint32 pc)
Definition: xtensa-isa.c:1274
int xtensa_operand_num_regs(xtensa_isa isa, xtensa_opcode opc, int opnd)
Definition: xtensa-isa.c:1188
int xtensa_operand_is_register(xtensa_isa isa, xtensa_opcode opc, int opnd)
Definition: xtensa-isa.c:1155
int xtensa_regfile
Definition: xtensa-isa.h:85
xtensa_regfile xtensa_operand_regfile(xtensa_isa isa, xtensa_opcode opc, int opnd)
Definition: xtensa-isa.c:1173
int xtensa_operand_decode(xtensa_isa isa, xtensa_opcode opc, int opnd, uint32 *valp)
Definition: xtensa-isa.c:1128

References i, info(), int, opc, show_raw_fields, xtensa_default_isa, xtensa_operand_decode(), xtensa_operand_is_PCrelative(), xtensa_operand_is_register(), xtensa_operand_num_regs(), xtensa_operand_regfile(), xtensa_operand_undo_reloc(), and xtensa_regfile_shortname().

Referenced by print_insn_xtensa().

Variable Documentation

◆ show_raw_fields

int show_raw_fields

Definition at line 58 of file xtensa-dis.c.

Referenced by print_xtensa_operand().

◆ xtensa_default_isa

xtensa_isa xtensa_default_isa
extern

Definition at line 147 of file elf32-xtensa.c.

Referenced by fetch_data(), print_insn_xtensa(), and print_xtensa_operand().