Rizin
unix-like reverse engineering framework and cli tools
parse_arm_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 RzListarm_tokenize (const char *assembly, size_t length)
 
static bool parse (RzParse *p, const char *assembly, RzStrBuf *sb)
 
static char * subs_var_string (RzParse *p, RzAnalysisVarField *var, char *tstr, const char *oldstr, const char *reg, int delta)
 
static char * mount_oldstr (RzParse *p, const char *reg, st64 delta, bool ucase)
 
static bool subvar (RzParse *p, RzAnalysisFunction *f, RzAnalysisOp *op, char *data, char *str, int len)
 

Variables

static const RzPseudoGrammar arm_lexicon []
 
static const RzPseudoDirect arm_direct []
 
static const RzPseudoReplace arm_replace []
 
static const RzPseudoConfig arm_config = RZ_PSEUDO_DEFINE_CONFIG(arm_direct, arm_lexicon, arm_replace, 5, arm_tokenize)
 
RzParsePlugin rz_parse_plugin_arm_pseudo
 
RZ_API RzLibStruct rizin_plugin
 

Function Documentation

◆ arm_tokenize()

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

Definition at line 136 of file parse_arm_pseudo.c.

136  {
137  size_t i, p;
138  char *buf = NULL;
139  const char *comma_replace = NULL;
140  bool keep = false;
141  RzList *tokens = NULL;
142 
143  buf = rz_str_ndup(assembly, length);
144  if (!buf) {
145  return NULL;
146  }
147 
148  for (i = 0, p = 0; p < length; ++i, ++p) {
149  if (buf[p] == ',') {
150  if (!keep) {
151  p++;
152  } else if (buf[p + 1] == ' ') {
153  buf[i] = buf[p];
154  p++;
155  continue;
156  }
157  } else if (buf[p] == '(') {
158  buf[p] = ' ';
159  } else if (buf[p] == ')') {
160  buf[p] = ' ';
161  } else if (buf[p] == '[') {
162  keep = true;
163  comma_replace = " + ";
164  } else if (buf[p] == ']') {
165  keep = false;
166  } else if (buf[p] == '{') {
167  if (strchr(buf + p + 1, ',') < strchr(buf + p + 1, '}')) {
168  keep = true;
169  comma_replace = ", ";
170  } else {
171  p++;
172  }
173  } else if (buf[p] == '}') {
174  if (!comma_replace) {
175  p++;
176  }
177  keep = false;
178  } else if ((buf[p] == 'w' || buf[p] == 'x') && buf[p + 1] == 'z' && buf[p + 2] == 'r') {
179  p += 2;
180  buf[p] = '0';
181  }
182  if (p > i) {
183  buf[i] = buf[p];
184  }
185  }
186  buf[i] = 0;
187 
188  tokens = rz_str_split_duplist(buf, " ", true);
189  free(buf);
190  if (!tokens) {
191  return NULL;
192  }
193 
194  if (comma_replace) {
195  RzListIter *it;
196  rz_list_foreach (tokens, it, buf) {
197  it->data = rz_str_replace(buf, ",", comma_replace, 1);
198  }
199  }
200 
201  return tokens;
202 }
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 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
RZ_API char * rz_str_replace(char *str, const char *key, const char *val, int g)
Definition: str.c:1110
void * data
Definition: rz_list.h:14

References rz_list_iter_t::data, free(), i, length, NULL, p, rz_str_ndup(), rz_str_replace(), and rz_str_split_duplist().

◆ mount_oldstr()

static char* mount_oldstr ( RzParse p,
const char *  reg,
st64  delta,
bool  ucase 
)
static

Definition at line 225 of file parse_arm_pseudo.c.

225  {
226  const char *tmplt;
227  char *oldstr;
228  if (delta > -10 && delta < 10) {
229  if (p->pseudo) {
230  char sign = '+';
231  if (delta < 0) {
232  sign = '-';
233  }
234  oldstr = rz_str_newf("%s %c %" PFMT64d, reg, sign, RZ_ABS(delta));
235  } else {
236  oldstr = rz_str_newf("%s, %" PFMT64d, reg, delta);
237  }
238  } else if (delta > 0) {
239  tmplt = p->pseudo ? "%s + 0x%x" : (ucase ? "%s, 0x%X" : "%s, 0x%x");
240  oldstr = rz_str_newf(tmplt, reg, delta);
241  } else {
242  tmplt = p->pseudo ? "%s - 0x%x" : (ucase ? "%s, -0x%X" : "%s, -0x%x");
243  oldstr = rz_str_newf(tmplt, reg, -delta);
244  }
245  if (ucase) {
246  char *comma = strchr(oldstr, ',');
247  if (comma) {
248  *comma = 0;
249  rz_str_case(oldstr, true);
250  *comma = ',';
251  }
252  }
253  return oldstr;
254 }
#define reg(n)
@ RZ_ABS
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
#define PFMT64d
Definition: rz_types.h:394
static st64 delta
Definition: vmenus.c:2425
static int comma
Definition: z80asm.c:76

References comma, delta, p, PFMT64d, reg, RZ_ABS, rz_str_case(), and rz_str_newf().

Referenced by subvar().

◆ parse()

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

Definition at line 204 of file parse_arm_pseudo.c.

204  {
205  return rz_pseudo_convert(&arm_config, assembly, sb);
206 }
static SblHeader sb
Definition: bin_mbn.c:26
static const RzPseudoConfig arm_config
static bool rz_pseudo_convert(const RzPseudoConfig *config, const char *assembly, RzStrBuf *sb)
Definition: parse_common.c:103

References arm_config, rz_pseudo_convert(), and sb.

◆ subs_var_string()

static char* subs_var_string ( RzParse p,
RzAnalysisVarField var,
char *  tstr,
const char *  oldstr,
const char *  reg,
int  delta 
)
static

Definition at line 208 of file parse_arm_pseudo.c.

208  {
209  char *newstr = p->localvar_only
210  ? rz_str_newf("%s", var->name)
211  : rz_str_newf("%s %c %s", reg, delta > 0 ? '+' : '-', var->name);
212  if (IS_UPPER(*tstr)) {
213  char *space = strrchr(newstr, ' ');
214  if (space) {
215  *space = 0;
216  rz_str_case(newstr, true);
217  *space = ' ';
218  }
219  }
220  char *ret = rz_str_replace(tstr, oldstr, newstr, 1);
221  free(newstr);
222  return ret;
223 }
static RASN1String * newstr(const char *string)
Definition: astr.c:23
#define IS_UPPER(c)
Definition: rz_str_util.h:14
Definition: z80asm.h:102

References delta, free(), IS_UPPER, newstr(), p, reg, rz_str_case(), rz_str_newf(), and rz_str_replace().

Referenced by subvar().

◆ subvar()

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

Definition at line 256 of file parse_arm_pseudo.c.

256  {
257  const ut64 addr = op->addr;
258  const int oplen = op->size;
259  RzList *spargs = NULL;
260  RzList *bpargs = NULL;
261  RzListIter *iter;
262  RzAnalysis *analysis = p->analb.analysis;
263  char *oldstr;
264  char *tstr = strdup(data);
265  if (!tstr) {
266  return false;
267  }
268 
269  if (!p->varlist) {
270  free(tstr);
271  return false;
272  }
273  if (p->subrel) {
274  char *rip;
275  if (p->pseudo) {
276  rip = (char *)rz_str_casestr(tstr, "[pc +");
277  if (!rip) {
278  rip = (char *)rz_str_casestr(tstr, "[pc -");
279  }
280  } else {
281  rip = (char *)rz_str_casestr(tstr, "[pc, ");
282  }
283 
284  if (rip) {
285  rip += 4;
286  char *tstr_new, *ripend = strchr(rip, ']');
287  const char *neg = strchr(rip, '-');
288  ut64 off = (oplen == 2 || strstr(tstr, ".w") || strstr(tstr, ".W")) ? 4 : 8;
289  ut64 repl_num = (addr + off) & ~3;
290  if (!ripend) {
291  ripend = "]";
292  }
293  const char *maybe_num = neg ? neg + 1 : rip;
294  maybe_num = rz_str_trim_head_ro(maybe_num);
295  if (rz_is_valid_input_num_value(NULL, maybe_num)) {
296  if (neg) {
297  repl_num -= rz_num_get(NULL, maybe_num);
298  } else {
299  repl_num += rz_num_get(NULL, maybe_num);
300  }
301  rip -= 3;
302  *rip = 0;
303  tstr_new = rz_str_newf("%s0x%08" PFMT64x "%s", tstr, repl_num, ripend);
304  free(tstr);
305  tstr = tstr_new;
306  }
307  }
308  }
309 
310  bpargs = p->varlist(f, 'b');
311  spargs = p->varlist(f, 's');
312  bool ucase = IS_UPPER(*tstr);
313  RzAnalysisVarField *var;
314  rz_list_foreach (bpargs, iter, var) {
315  st64 delta = p->get_ptr_at
316  ? p->get_ptr_at(f, var->delta, addr)
317  : ST64_MAX;
318  if (delta == ST64_MAX && var->field) {
319  delta = var->delta + f->bp_off;
320  } else if (delta == ST64_MAX) {
321  continue;
322  }
323  const char *reg = NULL;
324  if (p->get_reg_at) {
325  reg = p->get_reg_at(f, var->delta, addr);
326  }
327  if (!reg) {
328  reg = analysis->reg->name[RZ_REG_NAME_BP];
329  }
330  oldstr = mount_oldstr(p, reg, delta, ucase);
331  if (strstr(tstr, oldstr)) {
332  tstr = subs_var_string(p, var, tstr, oldstr, reg, delta);
333  free(oldstr);
334  break;
335  }
336  free(oldstr);
337  }
338  rz_list_foreach (spargs, iter, var) {
339  st64 delta = p->get_ptr_at
340  ? p->get_ptr_at(f, var->delta, addr)
341  : ST64_MAX;
342  if (delta == ST64_MAX && var->field) {
343  delta = var->delta;
344  } else if (delta == ST64_MAX) {
345  continue;
346  }
347  const char *reg = NULL;
348  if (p->get_reg_at) {
349  reg = p->get_reg_at(f, var->delta, addr);
350  }
351  if (!reg) {
352  reg = analysis->reg->name[RZ_REG_NAME_SP];
353  }
354  oldstr = mount_oldstr(p, reg, delta, ucase);
355  if (strstr(tstr, oldstr)) {
356  tstr = subs_var_string(p, var, tstr, oldstr, reg, delta);
357  free(oldstr);
358  break;
359  }
360  free(oldstr);
361  }
362  rz_list_free(bpargs);
363  rz_list_free(spargs);
364  if (len > strlen(tstr)) {
365  strcpy(str, tstr);
366  } else {
367  // TOO BIG STRING CANNOT REPLACE HERE
368  free(tstr);
369  return false;
370  }
371  free(tstr);
372  return true;
373 }
size_t len
Definition: 6502dis.c:15
static ut32 neg(ArmOp *op)
Definition: armass64.c:981
void rip(char *fname, off_t offset, unsigned int length)
Definition: cabrip.c:18
RZ_API void rz_list_free(RZ_NONNULL RzList *list)
Empties the list and frees the list pointer.
Definition: list.c:137
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")
int off
Definition: pal.c:13
static char * mount_oldstr(RzParse *p, const char *reg, st64 delta, bool ucase)
static char * subs_var_string(RzParse *p, RzAnalysisVarField *var, char *tstr, const char *oldstr, const char *reg, int delta)
RZ_DEPRECATE struct rz_analysis_var_field_t RzAnalysisVarField
RZ_API ut64 rz_num_get(RzNum *num, const char *str)
Definition: unum.c:172
RZ_API bool rz_is_valid_input_num_value(RzNum *num, const char *input_value)
Definition: unum.c:735
@ RZ_REG_NAME_SP
Definition: rz_reg.h:44
@ RZ_REG_NAME_BP
Definition: rz_reg.h:46
RZ_API const char * rz_str_trim_head_ro(const char *str)
Definition: str_trim.c:86
RZ_API const char * rz_str_casestr(const char *a, const char *b)
Definition: str.c:2757
#define PFMT64x
Definition: rz_types.h:393
#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
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
static int addr
Definition: z80asm.c:58

References addr, delta, f, free(), IS_UPPER, len, mount_oldstr(), rz_reg_t::name, neg(), NULL, off, p, PFMT64x, reg, rz_analysis_t::reg, rip(), rz_is_valid_input_num_value(), rz_list_free(), rz_num_get(), RZ_REG_NAME_BP, RZ_REG_NAME_SP, rz_str_casestr(), rz_str_newf(), rz_str_trim_head_ro(), st64, ST64_MAX, cmd_descs_generate::str, strdup(), subs_var_string(), and ut64().

Referenced by sh_il_negc().

Variable Documentation

◆ arm_config

Definition at line 134 of file parse_arm_pseudo.c.

Referenced by parse().

◆ arm_direct

const RzPseudoDirect arm_direct[]
static
Initial value:
= {
RZ_PSEUDO_DEFINE_DIRECT("beq lr", "if (? == ?) return"),
RZ_PSEUDO_DEFINE_DIRECT("bx lr", "return"),
}
#define RZ_PSEUDO_DEFINE_DIRECT(x, y)
Definition: parse_common.c:61

Definition at line 121 of file parse_arm_pseudo.c.

◆ arm_lexicon

const RzPseudoGrammar arm_lexicon[]
static

Definition at line 18 of file parse_arm_pseudo.c.

◆ arm_replace

const RzPseudoReplace arm_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 126 of file parse_arm_pseudo.c.

◆ rizin_plugin

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

Definition at line 383 of file parse_arm_pseudo.c.

◆ rz_parse_plugin_arm_pseudo

RzParsePlugin rz_parse_plugin_arm_pseudo
Initial value:
= {
.name = "arm.pseudo",
.desc = "ARM/ARM64 pseudo syntax",
.parse = parse,
.subvar = &subvar,
}
static bool subvar(RzParse *p, RzAnalysisFunction *f, RzAnalysisOp *op, char *data, char *str, int len)
static bool parse(RzParse *p, const char *assembly, RzStrBuf *sb)

Definition at line 375 of file parse_arm_pseudo.c.