Rizin
unix-like reverse engineering framework and cli tools
parse_mips_pseudo.c File Reference
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <rz_lib.h>
#include <rz_util.h>
#include <rz_flag.h>
#include <rz_analysis.h>
#include <rz_parse.h>
#include "parse_common.c"

Go to the source code of this file.

Functions

static RzListmips_tokenize (const char *assembly, size_t length)
 
static bool parse (RzParse *parse, const char *assembly, RzStrBuf *sb)
 
static bool subvar (RzParse *p, RzAnalysisFunction *f, RzAnalysisOp *op, char *data, char *str, int len)
 

Variables

static const RzPseudoGrammar mips_lexicon []
 
static const RzPseudoDirect mips_direct []
 
static const RzPseudoReplace mips_replace []
 
static const RzPseudoConfig mips_config = RZ_PSEUDO_DEFINE_CONFIG(mips_direct, mips_lexicon, mips_replace, 4, mips_tokenize)
 
RzParsePlugin rz_parse_plugin_mips_pseudo
 
RZ_API RzLibStruct rizin_plugin
 

Function Documentation

◆ mips_tokenize()

RzList * mips_tokenize ( const char *  assembly,
size_t  length 
)
static

Definition at line 95 of file parse_mips_pseudo.c.

95  {
96  size_t i, p;
97  char *buf = NULL;
98  bool insert_zero = false;
99  RzList *tokens = NULL;
100 
101  buf = rz_str_ndup(assembly, length);
102  if (!buf) {
103  return NULL;
104  }
105 
106  for (i = 0, p = 0; p < length; ++i, ++p) {
107  if (buf[p] == ',') {
108  p++;
109  } else if (buf[p] == '(') {
110  buf[p] = ' ';
111  if (!IS_HEXCHAR(buf[p - 1])) {
112  p++;
113  insert_zero = true;
114  }
115  } else if (buf[p] == ')') {
116  buf[p] = 0;
117  } else if (buf[p] == 'z' && buf[p + 1] == 'e' && buf[p + 2] == 'r' && buf[p + 3] == 'o') {
118  p += 3;
119  buf[p] = '0';
120  }
121  if (p > i) {
122  buf[i] = buf[p];
123  }
124  }
125  buf[i] = 0;
126 
127  tokens = rz_str_split_duplist(buf, " ", true);
128  free(buf);
129  if (!tokens) {
130  return NULL;
131  }
132 
133  if (insert_zero) {
134  rz_list_insert(tokens, rz_list_length(tokens) - 1, strdup("0"));
135  }
136 
137  return tokens;
138 }
lzma_index ** i
Definition: index.h:629
#define NULL
Definition: cris-opc.c:27
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
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
voidpf void * buf
Definition: ioapi.h:138
void * p
Definition: libc.cpp:67
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 ut32 rz_list_length(RZ_NONNULL const RzList *list)
Returns the length of the list.
Definition: list.c:109
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")
RZ_API char * rz_str_ndup(RZ_NULLABLE const char *ptr, int len)
Create new copy of string ptr limited to size len.
Definition: str.c:1006
RZ_API RzList * rz_str_split_duplist(const char *str, const char *c, bool trim)
Split the string str according to the substring c and returns a RzList with the result.
Definition: str.c:3464
#define IS_HEXCHAR(x)
Definition: rz_str_util.h:9

References free(), i, IS_HEXCHAR, length, NULL, p, rz_list_insert(), rz_list_length(), rz_str_ndup(), rz_str_split_duplist(), and strdup().

◆ parse()

static bool parse ( RzParse parse,
const char *  assembly,
RzStrBuf sb 
)
static

Definition at line 140 of file parse_mips_pseudo.c.

140  {
141  return rz_pseudo_convert(&mips_config, assembly, sb);
142 }
static SblHeader sb
Definition: bin_mbn.c:26
static bool rz_pseudo_convert(const RzPseudoConfig *config, const char *assembly, RzStrBuf *sb)
Definition: parse_common.c:103
static const RzPseudoConfig mips_config

References mips_config, rz_pseudo_convert(), and sb.

◆ subvar()

static bool subvar ( RzParse p,
RzAnalysisFunction f,
RzAnalysisOp op,
char *  data,
char *  str,
int  len 
)
static

Definition at line 144 of file parse_mips_pseudo.c.

144  {
145  const ut64 addr = op->addr;
146  RzListIter *iter;
147  char *oldstr;
148  char *tstr = strdup(data);
149  RzAnalysis *analysis = p->analb.analysis;
150 
151  if (!p->varlist) {
152  free(tstr);
153  return false;
154  }
155  RzList *bpargs = p->varlist(f, 'b');
156  RzList *spargs = p->varlist(f, 's');
157  const bool ucase = IS_UPPER(*tstr);
158  RzAnalysisVarField *var;
159  rz_list_foreach (spargs, iter, var) {
160  st64 delta = p->get_ptr_at
161  ? p->get_ptr_at(f, var->delta, addr)
162  : ST64_MAX;
163  if (delta == ST64_MAX && var->field) {
164  delta = var->delta;
165  } else if (delta == ST64_MAX) {
166  continue;
167  }
168  const char *reg = NULL;
169  if (p->get_reg_at) {
170  reg = p->get_reg_at(f, var->delta, addr);
171  }
172  if (!reg) {
173  reg = analysis->reg->name[RZ_REG_NAME_SP];
174  }
175  char *tmpf;
176  // TODO: honor asm pseudo
177  if (RZ_ABS(delta) < 10) {
178  tmpf = "%d(%s)";
179  } else if (delta > 0) {
180  tmpf = "0x%x(%s)";
181  } else {
182  tmpf = "-0x%x(%s)";
183  }
184  oldstr = rz_str_newf(tmpf, RZ_ABS(delta), reg);
185  if (ucase) {
186  char *comma = strchr(oldstr, ',');
187  if (comma) {
188  *comma = 0;
189  rz_str_case(oldstr, true);
190  *comma = ',';
191  }
192  }
193  if (strstr(tstr, oldstr)) {
194  char *newstr = (p->localvar_only)
195  ? rz_str_newf("(%s)", var->name)
196  : rz_str_newf("%s%s(%s)", delta > 0 ? "" : "-", var->name, reg);
197  tstr = rz_str_replace(tstr, oldstr, newstr, 1);
198  free(newstr);
199  free(oldstr);
200  break;
201  }
202  free(oldstr);
203  }
204  rz_list_foreach (bpargs, iter, var) {
205  char *tmpf = NULL;
206  st64 delta = p->get_ptr_at
207  ? p->get_ptr_at(f, var->delta, addr)
208  : ST64_MAX;
209  if (delta == ST64_MAX && var->field) {
210  delta = var->delta + f->bp_off;
211  } else if (delta == ST64_MAX) {
212  continue;
213  }
214  const char *reg = NULL;
215  if (p->get_reg_at) {
216  reg = p->get_reg_at(f, var->delta, addr);
217  }
218  if (!reg) {
219  reg = analysis->reg->name[RZ_REG_NAME_BP];
220  }
221  if (RZ_ABS(delta) < 10) {
222  tmpf = "%d(%s)";
223  } else if (delta > 0) {
224  tmpf = "0x%x(%s)";
225  } else {
226  tmpf = "-0x%x(%s)";
227  }
228  oldstr = rz_str_newf(tmpf, RZ_ABS(delta), reg);
229  if (ucase) {
230  char *comma = strchr(oldstr, ',');
231  if (comma) {
232  *comma = 0;
233  rz_str_case(oldstr, true);
234  *comma = ',';
235  }
236  }
237  if (strstr(tstr, oldstr)) {
238  char *newstr = (p->localvar_only)
239  ? rz_str_newf("(%s)", var->name)
240  : rz_str_newf("%s%s(%s)", delta > 0 ? "" : "-", var->name, reg);
241  tstr = rz_str_replace(tstr, oldstr, newstr, 1);
242  free(newstr);
243  free(oldstr);
244  break;
245  }
246  free(oldstr);
247  }
248  bool ret = true;
249  if (len > strlen(tstr)) {
250  strcpy(str, tstr);
251  } else {
252  // TOO BIG STRING CANNOT REPLACE HERE
253  ret = false;
254  }
255  free(tstr);
256  rz_list_free(bpargs);
257  rz_list_free(spargs);
258  return ret;
259 }
size_t len
Definition: 6502dis.c:15
static RASN1String * newstr(const char *string)
Definition: astr.c:23
#define reg(n)
RZ_API void rz_list_free(RZ_NONNULL RzList *list)
Empties the list and frees the list pointer.
Definition: list.c:137
@ RZ_ABS
RZ_DEPRECATE struct rz_analysis_var_field_t RzAnalysisVarField
@ RZ_REG_NAME_SP
Definition: rz_reg.h:44
@ RZ_REG_NAME_BP
Definition: rz_reg.h:46
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
RZ_API void rz_str_case(char *str, bool up)
Definition: str.c:341
RZ_API char * rz_str_replace(char *str, const char *key, const char *val, int g)
Definition: str.c:1110
#define IS_UPPER(c)
Definition: rz_str_util.h:14
#define st64
Definition: rz_types_base.h:10
#define ST64_MAX
Definition: rz_types_base.h:84
#define f(i)
Definition: sha256.c:46
char * name[RZ_REG_NAME_LAST]
Definition: rz_reg.h:149
Definition: dis.c:32
static st64 delta
Definition: vmenus.c:2425
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
static int comma
Definition: z80asm.c:76
static int addr
Definition: z80asm.c:58

References addr, comma, delta, f, free(), IS_UPPER, len, rz_reg_t::name, newstr(), NULL, p, reg, rz_analysis_t::reg, RZ_ABS, rz_list_free(), RZ_REG_NAME_BP, RZ_REG_NAME_SP, rz_str_case(), rz_str_newf(), rz_str_replace(), st64, ST64_MAX, cmd_descs_generate::str, strdup(), and ut64().

Variable Documentation

◆ mips_config

Definition at line 93 of file parse_mips_pseudo.c.

Referenced by parse().

◆ mips_direct

const RzPseudoDirect mips_direct[]
static
Initial value:
= {
RZ_PSEUDO_DEFINE_DIRECT("jr ra", "return"),
}
#define RZ_PSEUDO_DEFINE_DIRECT(x, y)
Definition: parse_common.c:61

Definition at line 83 of file parse_mips_pseudo.c.

◆ mips_lexicon

const RzPseudoGrammar mips_lexicon[]
static

Definition at line 19 of file parse_mips_pseudo.c.

◆ mips_replace

const RzPseudoReplace mips_replace[]
static
Initial value:
= {
RZ_PSEUDO_DEFINE_REPLACE(" + 0]", "]", 0),
RZ_PSEUDO_DEFINE_REPLACE("+ -", "- ", 1),
RZ_PSEUDO_DEFINE_REPLACE("0 << 16", "0", 1),
}
#define RZ_PSEUDO_DEFINE_REPLACE(x, y, f)
Definition: parse_common.c:64

Definition at line 87 of file parse_mips_pseudo.c.

◆ rizin_plugin

RZ_API RzLibStruct rizin_plugin
Initial value:
= {
.version = RZ_VERSION
}
RzParsePlugin rz_parse_plugin_mips_pseudo
@ RZ_LIB_TYPE_PARSE
Definition: rz_lib.h:74
#define RZ_VERSION
Definition: rz_version.h:8

Definition at line 271 of file parse_mips_pseudo.c.

◆ rz_parse_plugin_mips_pseudo

RzParsePlugin rz_parse_plugin_mips_pseudo
Initial value:
= {
.name = "mips.pseudo",
.desc = "MIPS pseudo syntax",
.init = NULL,
.fini = NULL,
.parse = parse,
.subvar = subvar,
}
static bool subvar(RzParse *p, RzAnalysisFunction *f, RzAnalysisOp *op, char *data, char *str, int len)
static bool parse(RzParse *parse, const char *assembly, RzStrBuf *sb)

Definition at line 261 of file parse_mips_pseudo.c.