Rizin
unix-like reverse engineering framework and cli tools
asm_mips_gnu.c File Reference
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <rz_types.h>
#include <rz_lib.h>
#include <rz_util.h>
#include <rz_asm.h>
#include "disas-asm.h"
#include "opcode/mips.h"

Go to the source code of this file.

Functions

int mips_assemble (const char *str, ut64 pc, ut8 *out)
 
static int mips_buffer_read_memory (bfd_vma memaddr, bfd_byte *myaddr, unsigned int length, struct disassemble_info *info)
 
static int symbol_at_address (bfd_vma addr, struct disassemble_info *info)
 
static void memory_error_func (int status, bfd_vma memaddr, struct disassemble_info *info)
 
static int disassemble (struct rz_asm_t *a, struct rz_asm_op_t *op, const ut8 *buf, int len)
 
static int assemble (RzAsm *a, RzAsmOp *op, const char *str)
 

Variables

static int mips_mode = 0
 
static unsigned long Offset = 0
 
static RzStrBufbuf_global = NULL
 
static unsigned char bytes [4]
 
static char * pre_cpu = NULL
 
static char * pre_features = NULL
 
RzAsmPlugin rz_asm_plugin_mips_gnu
 
RZ_API RzLibStruct rizin_plugin
 

Function Documentation

◆ assemble()

static int assemble ( RzAsm a,
RzAsmOp op,
const char *  str 
)
static

Definition at line 109 of file asm_mips_gnu.c.

109  {
110  ut8 *opbuf = (ut8 *)rz_strbuf_get(&op->buf);
111  int ret = mips_assemble(str, a->pc, opbuf);
112  if (a->big_endian) {
113  ut8 tmp = opbuf[0];
114  opbuf[0] = opbuf[3];
115  opbuf[3] = tmp;
116  tmp = opbuf[1];
117  opbuf[1] = opbuf[2];
118  opbuf[2] = tmp;
119  }
120  return ret;
121 }
int mips_assemble(const char *str, ut64 pc, ut8 *out)
Definition: mipsasm.c:148
uint8_t ut8
Definition: lh5801.h:11
RZ_API char * rz_strbuf_get(RzStrBuf *sb)
Definition: strbuf.c:321
#define a(i)
Definition: sha256.c:41
Definition: dis.c:32

References a, mips_assemble(), rz_strbuf_get(), cmd_descs_generate::str, and autogen_x86imm::tmp.

◆ disassemble()

static int disassemble ( struct rz_asm_t a,
struct rz_asm_op_t op,
const ut8 buf,
int  len 
)
static

Definition at line 48 of file asm_mips_gnu.c.

48  {
49  static struct disassemble_info disasm_obj;
50  if (len < 4) {
51  return -1;
52  }
53  buf_global = &op->buf_asm;
54  Offset = a->pc;
55  memcpy(bytes, buf, 4); // TODO handle thumb
56 
57  if ((a->cpu != pre_cpu) && (a->features != pre_features)) {
58  free(disasm_obj.disassembler_options);
59  memset(&disasm_obj, '\0', sizeof(struct disassemble_info));
60  }
61 
62  /* prepare disassembler */
63  if (a->cpu && (!pre_cpu || !strcmp(a->cpu, pre_cpu))) {
64  if (!rz_str_casecmp(a->cpu, "mips64r2")) {
65  disasm_obj.mach = bfd_mach_mipsisa64r2;
66  } else if (!rz_str_casecmp(a->cpu, "mips32r2")) {
67  disasm_obj.mach = bfd_mach_mipsisa32r2;
68  } else if (!rz_str_casecmp(a->cpu, "mips64")) {
69  disasm_obj.mach = bfd_mach_mipsisa64;
70  } else if (!rz_str_casecmp(a->cpu, "mips32")) {
71  disasm_obj.mach = bfd_mach_mipsisa32;
72  }
73  pre_cpu = rz_str_dup(pre_cpu, a->cpu);
74  }
75 
76  if (a->features && (!pre_features || !strcmp(a->features, pre_features))) {
77  free(disasm_obj.disassembler_options);
78  if (strstr(a->features, "n64")) {
79  disasm_obj.disassembler_options = rz_str_new("abi=n64");
80  } else if (strstr(a->features, "n32")) {
81  disasm_obj.disassembler_options = rz_str_new("abi=n32");
82  } else if (strstr(a->features, "o32")) {
83  disasm_obj.disassembler_options = rz_str_new("abi=o32");
84  }
85  pre_features = rz_str_dup(pre_features, a->features);
86  }
87 
88  mips_mode = a->bits;
89  disasm_obj.arch = CPU_LOONGSON_2F;
90  disasm_obj.buffer = bytes;
91  disasm_obj.read_memory_func = &mips_buffer_read_memory;
92  disasm_obj.symbol_at_address_func = &symbol_at_address;
93  disasm_obj.memory_error_func = &memory_error_func;
94  disasm_obj.print_address_func = &generic_print_address_func;
95  disasm_obj.buffer_vma = Offset;
96  disasm_obj.buffer_length = 4;
97  disasm_obj.endian = !a->big_endian;
98  disasm_obj.fprintf_func = &generic_fprintf_func;
99  disasm_obj.stream = stdout;
100  op->size = (disasm_obj.endian == BFD_ENDIAN_LITTLE)
101  ? print_insn_little_mips((bfd_vma)Offset, &disasm_obj)
102  : print_insn_big_mips((bfd_vma)Offset, &disasm_obj);
103  if (op->size == -1) {
104  rz_strbuf_set(&op->buf_asm, "(data)");
105  }
106  return op->size;
107 }
size_t len
Definition: 6502dis.c:15
static void memory_error_func(int status, bfd_vma memaddr, struct disassemble_info *info)
Definition: asm_mips_gnu.c:41
static int mips_mode
Definition: asm_mips_gnu.c:18
static char * pre_features
Definition: asm_mips_gnu.c:23
static unsigned long Offset
Definition: asm_mips_gnu.c:19
static int symbol_at_address(bfd_vma addr, struct disassemble_info *info)
Definition: asm_mips_gnu.c:37
static RzStrBuf * buf_global
Definition: asm_mips_gnu.c:20
static unsigned char bytes[4]
Definition: asm_mips_gnu.c:21
static int mips_buffer_read_memory(bfd_vma memaddr, bfd_byte *myaddr, unsigned int length, struct disassemble_info *info)
Definition: asm_mips_gnu.c:25
static char * pre_cpu
Definition: asm_mips_gnu.c:22
int print_insn_little_mips(bfd_vma, disassemble_info *)
Definition: mips-dis.c:2104
int print_insn_big_mips(bfd_vma, disassemble_info *)
Definition: mips-dis.c:2098
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
voidpf void * buf
Definition: ioapi.h:138
return memset(p, 0, total)
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
#define CPU_LOONGSON_2F
Definition: mips.h:610
#define bfd_mach_mipsisa32r2
Definition: mybfd.h:1657
BFD_HOST_U_64_BIT bfd_vma
Definition: mybfd.h:111
#define bfd_mach_mipsisa64
Definition: mybfd.h:1658
#define bfd_mach_mipsisa32
Definition: mybfd.h:1656
@ BFD_ENDIAN_LITTLE
Definition: mybfd.h:4618
#define bfd_mach_mipsisa64r2
Definition: mybfd.h:1659
RZ_API int rz_str_casecmp(const char *dst, const char *orig)
Definition: str.c:121
RZ_API char * rz_str_new(const char *str)
Definition: str.c:865
RZ_API char * rz_str_dup(char *ptr, const char *string)
Definition: str.c:1021
RZ_API const char * rz_strbuf_set(RzStrBuf *sb, const char *s)
Definition: strbuf.c:153

References a, disassemble_info::arch, BFD_ENDIAN_LITTLE, bfd_mach_mipsisa32, bfd_mach_mipsisa32r2, bfd_mach_mipsisa64, bfd_mach_mipsisa64r2, buf_global, disassemble_info::buffer, disassemble_info::buffer_length, disassemble_info::buffer_vma, bytes, CPU_LOONGSON_2F, disassemble_info::disassembler_options, disassemble_info::endian, disassemble_info::fprintf_func, free(), len, disassemble_info::mach, memcpy(), memory_error_func(), disassemble_info::memory_error_func, memset(), mips_buffer_read_memory(), mips_mode, Offset, pre_cpu, pre_features, disassemble_info::print_address_func, print_insn_big_mips(), print_insn_little_mips(), disassemble_info::read_memory_func, rz_str_casecmp(), rz_str_dup(), rz_str_new(), rz_strbuf_set(), disassemble_info::stream, symbol_at_address(), and disassemble_info::symbol_at_address_func.

◆ memory_error_func()

static void memory_error_func ( int  status,
bfd_vma  memaddr,
struct disassemble_info info 
)
static

Definition at line 41 of file asm_mips_gnu.c.

41  {
42  //--
43 }

Referenced by disassemble().

◆ mips_assemble()

int mips_assemble ( const char *  str,
ut64  pc,
ut8 out 
)

Definition at line 148 of file mipsasm.c.

148  {
149  int i, hasp;
150  char w0[32], w1[32], w2[32], w3[32];
151  char *s = strdup(str);
152  if (!s) {
153  return -1;
154  }
155 
156  rz_str_replace_char(s, ',', ' ');
157  hasp = rz_str_replace_char(s, '(', ' ');
158  rz_str_replace_char(s, ')', ' ');
159 
160  *out = 0;
161  *w0 = 0;
162  *w1 = 0;
163  *w2 = 0;
164  *w3 = 0;
165 
166  if (!strncmp(s, "jalr", 4) && !strchr(s, ',')) {
167  char opstr[32];
168  const char *arg = strchr(s, ' ');
169  if (arg) {
170  snprintf(opstr, sizeof(opstr), "jalr ra ra %s", arg + 1);
171  free(s);
172  s = strdup(opstr);
173  if (!s) {
174  return -1;
175  }
176  }
177  }
178 
179  sscanf(s, "%31s", w0);
180  if (*w0) {
181  for (i = 0; ops[i].name; i++) {
182  if (!strcmp(ops[i].name, w0)) {
183  switch (ops[i].args) {
184  case 3: sscanf(s, "%31s %31s %31s %31s", w0, w1, w2, w3); break;
185  case -3: sscanf(s, "%31s %31s %31s %31s", w0, w1, w2, w3); break;
186  case 2: sscanf(s, "%31s %31s %31s", w0, w1, w2); break;
187  case -2: sscanf(s, "%31s %31s %31s", w0, w1, w2); break;
188  case 1: sscanf(s, "%31s %31s", w0, w1); break;
189  case -1: sscanf(s, "%31s %31s", w0, w1); break;
190  case 0: sscanf(s, "%31s", w0); break;
191  }
192  if (hasp) {
193  char tmp[32];
194  strcpy(tmp, w2);
195  strcpy(w2, w3);
196  strcpy(w3, tmp);
197  }
198  switch (ops[i].type) {
199  case 'R': {
200  // reg order diff per instruction 'group' - ordered to number of likelyhood to call (add > mfhi)
201  int op = 0, rs = 0, rt = 0, rd = 0, sa = 0, fn = 0;
202  bool invalid = false;
203  switch (ops[i].args) {
204  case 3:
205  rs = getreg(w2);
206  rt = getreg(w3);
207  rd = getreg(w1);
208  fn = ops[i].n;
209  break;
210  case -3:
211  if (ops[i].n > -1) {
212  rt = getreg(w2);
213  rd = getreg(w1);
214  sa = getreg(w3);
215  fn = ops[i].n;
216  } else {
217  rs = getreg(w3);
218  rt = getreg(w2);
219  rd = getreg(w1);
220  fn = (-1 * ops[i].n);
221  }
222  break;
223  case 2:
224  rs = getreg(w1);
225  rt = getreg(w2);
226  fn = ops[i].n;
227  break;
228  case 1:
229  rs = getreg(w1);
230  fn = ops[i].n;
231  break;
232  case -2:
233  rs = getreg(w2);
234  rd = getreg(w1);
235  fn = ops[i].n;
236  break;
237  case -1:
238  rd = getreg(w1);
239  fn = ops[i].n;
240  break;
241  case 0:
242  fn = ops[i].n;
243  break;
244  default:
245  invalid = true;
246  break;
247  }
248  if (!invalid) {
249  free(s);
250  return mips_r(out, op, rs, rt, rd, sa, fn);
251  }
252  break;
253  }
254  case 'I':
255  case 'B': {
256  bool invalid = false;
257  int op = 0, rs = 0, rt = 0, imm = 0, is_branch = ops[i].type == 'B';
258  switch (ops[i].args) {
259  case 2:
260  op = ops[i].n;
261  rt = getreg(w1);
262  imm = getreg(w2);
263  break;
264  case 3:
265  op = ops[i].n;
266  rs = getreg(w2);
267  rt = getreg(w1);
268  imm = getreg(w3);
269  break;
270  case -2:
271  if (ops[i].n > 0) {
272  op = ops[i].n;
273  rs = getreg(w1);
274  imm = getreg(w2);
275  } else {
276  op = (-1 * ops[i].n);
277  rs = getreg(w1);
278  rt = ops[i].x;
279  imm = getreg(w2);
280  }
281  break;
282  case -1:
283  if (ops[i].n > 0) {
284  op = ops[i].n;
285  imm = getreg(w1);
286  } else {
287  op = (-1 * ops[i].n);
288  rt = ops[i].x;
289  imm = getreg(w1);
290  }
291  break;
292  default:
293  invalid = true;
294  break;
295  }
296  if (!invalid) {
297  free(s);
298  return mips_i(out, op, rs, rt, imm, is_branch);
299  }
300  break;
301  }
302  case 'J':
303  if (ops[i].args == 1) {
304  free(s);
305  return mips_j(out, ops[i].n, getreg(w1));
306  }
307  break;
308  case 'N': // nop
309  memset(out, 0, 4);
310  free(s);
311  return 4;
312  }
313  free(s);
314  return -1;
315  }
316  }
317  }
318  free(s);
319  return -1;
320 }
#define rs()
#define rd()
#define imm
lzma_index ** i
Definition: index.h:629
static int opstr(RzAsm *a, ut8 *data, const Opcode *op)
Definition: asm_x86_nz.c:4054
const lzma_allocator const uint8_t size_t uint8_t * out
Definition: block.h:528
snprintf
Definition: kernel.h:364
static const char struct stat static buf struct stat static buf static idle const char static path static fd const char static len const void static prot const char struct module static image struct kernel_sym static table unsigned char static buf static fsuid unsigned struct dirent unsigned static count const struct iovec static count static pid const void static len static flags const struct sched_param static p static pid static policy struct timespec static tp static suid unsigned fn
Definition: sflib.h:186
return strdup("=SP r13\n" "=LR r14\n" "=PC r15\n" "=A0 r0\n" "=A1 r1\n" "=A2 r2\n" "=A3 r3\n" "=ZF zf\n" "=SF nf\n" "=OF vf\n" "=CF cf\n" "=SN or0\n" "gpr lr .32 56 0\n" "gpr pc .32 60 0\n" "gpr cpsr .32 64 0 ____tfiae_________________qvczn\n" "gpr or0 .32 68 0\n" "gpr tf .1 64.5 0 thumb\n" "gpr ef .1 64.9 0 endian\n" "gpr jf .1 64.24 0 java\n" "gpr qf .1 64.27 0 sticky_overflow\n" "gpr vf .1 64.28 0 overflow\n" "gpr cf .1 64.29 0 carry\n" "gpr zf .1 64.30 0 zero\n" "gpr nf .1 64.31 0 negative\n" "gpr itc .4 64.10 0 if_then_count\n" "gpr gef .4 64.16 0 great_or_equal\n" "gpr r0 .32 0 0\n" "gpr r1 .32 4 0\n" "gpr r2 .32 8 0\n" "gpr r3 .32 12 0\n" "gpr r4 .32 16 0\n" "gpr r5 .32 20 0\n" "gpr r6 .32 24 0\n" "gpr r7 .32 28 0\n" "gpr r8 .32 32 0\n" "gpr r9 .32 36 0\n" "gpr r10 .32 40 0\n" "gpr r11 .32 44 0\n" "gpr r12 .32 48 0\n" "gpr r13 .32 52 0\n" "gpr r14 .32 56 0\n" "gpr r15 .32 60 0\n" "gpr r16 .32 64 0\n" "gpr r17 .32 68 0\n")
static int mips_r(ut8 *b, int op, int rs, int rt, int rd, int sa, int fun)
Definition: mipsasm.c:80
int args
Definition: mipsasm.c:18
static struct @104 ops[]
int n
Definition: mipsasm.c:19
static int getreg(const char *p)
Definition: mipsasm.c:122
static int mips_j(ut8 *b, int op, int addr)
Definition: mipsasm.c:113
int type
Definition: mipsasm.c:17
static int mips_i(ut8 *b, int op, int rs, int rt, int imm, int is_branch)
Definition: mipsasm.c:94
def is_branch(insn)
static RzSocket * s
Definition: rtr.c:28
RZ_API int rz_str_replace_char(char *s, int a, int b)
Definition: str.c:169
Definition: z80asm.h:102

References args, fn, free(), getreg(), i, imm, objdump-m68k::is_branch(), memset(), mips_i(), mips_j(), mips_r(), n, ops, opstr(), out, rd, rs, rz_str_replace_char(), s, snprintf, cmd_descs_generate::str, strdup(), autogen_x86imm::tmp, type, w0, w1, w2, and w3.

Referenced by assemble().

◆ mips_buffer_read_memory()

static int mips_buffer_read_memory ( bfd_vma  memaddr,
bfd_byte myaddr,
unsigned int  length,
struct disassemble_info info 
)
static

Definition at line 25 of file asm_mips_gnu.c.

25  {
26  int delta = (memaddr - Offset);
27  if (delta < 0) {
28  return -1; // disable backward reads
29  }
30  if ((delta + length) > 4) {
31  return -1;
32  }
33  memcpy(myaddr, bytes + delta, length);
34  return 0;
35 }
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
static st64 delta
Definition: vmenus.c:2425

References bytes, delta, length, memcpy(), and Offset.

Referenced by disassemble().

◆ symbol_at_address()

static int symbol_at_address ( bfd_vma  addr,
struct disassemble_info info 
)
static

Definition at line 37 of file asm_mips_gnu.c.

37  {
38  return 0;
39 }

Referenced by disassemble().

Variable Documentation

◆ buf_global

RzStrBuf* buf_global = NULL
static

Definition at line 20 of file asm_mips_gnu.c.

Referenced by disassemble().

◆ bytes

unsigned char bytes[4]
static

Definition at line 21 of file asm_mips_gnu.c.

Referenced by disassemble(), and mips_buffer_read_memory().

◆ mips_mode

int mips_mode = 0
static

Definition at line 18 of file asm_mips_gnu.c.

Referenced by disassemble().

◆ Offset

unsigned long Offset = 0
static

Definition at line 19 of file asm_mips_gnu.c.

Referenced by disassemble(), and mips_buffer_read_memory().

◆ pre_cpu

char* pre_cpu = NULL
static

Definition at line 22 of file asm_mips_gnu.c.

Referenced by disassemble().

◆ pre_features

char* pre_features = NULL
static

Definition at line 23 of file asm_mips_gnu.c.

Referenced by disassemble().

◆ rizin_plugin

RZ_API RzLibStruct rizin_plugin
Initial value:
= {
.type = RZ_LIB_TYPE_ASM,
}
RzAsmPlugin rz_asm_plugin_mips_gnu
Definition: asm_mips_gnu.c:123
@ RZ_LIB_TYPE_ASM
Definition: rz_lib.h:72
#define RZ_VERSION
Definition: rz_version.h:8
const char * version
Definition: rz_asm.h:133

Definition at line 135 of file asm_mips_gnu.c.

◆ rz_asm_plugin_mips_gnu

RzAsmPlugin rz_asm_plugin_mips_gnu
Initial value:
= {
.name = "mips.gnu",
.arch = "mips",
.license = "GPL3",
.bits = 32 | 64,
.desc = "MIPS CPU",
.disassemble = &disassemble,
.assemble = &assemble
}
static int disassemble(struct rz_asm_t *a, struct rz_asm_op_t *op, const ut8 *buf, int len)
Definition: asm_mips_gnu.c:48
static int assemble(RzAsm *a, RzAsmOp *op, const char *str)
Definition: asm_mips_gnu.c:109
#define RZ_SYS_ENDIAN_BIG
Definition: rz_types.h:527
#define RZ_SYS_ENDIAN_LITTLE
Definition: rz_types.h:526

Definition at line 123 of file asm_mips_gnu.c.