Rizin
unix-like reverse engineering framework and cli tools
parse_riscv_pseudo.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2020 Aswin C (officialcjunior) <realc@protonmail.com>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 #include <rz_lib.h>
5 #include <rz_flag.h>
6 #include <rz_analysis.h>
7 #include <rz_parse.h>
8 
9 static int replace(int argc, const char *argv[], char *newstr) {
10 #define MAXPSEUDOOPS 10
11  int i, j, k, d;
12  char ch;
13  struct {
14  int narg;
15  char *op;
16  char *str;
17  int args[MAXPSEUDOOPS];
18  } ops[] = {
19  { 0, "add", "# = # + #", { 1, 2, 3 } },
20  { 0, "addi", "# = # + #", { 1, 2, 3 } },
21  { 0, "and", "# = # & #", { 1, 2, 3 } },
22  { 0, "andi", "# = # & #", { 1, 2, 3 } },
23  { 0, "beq", "if (# == #) goto #", { 1, 2, 3 } },
24  { 0, "bleu", "if (unsigned)# <= # goto #", { 1, 2, 3 } },
25  { 0, "bltu", "if (unsigned)# < # goto #", { 1, 2, 3 } },
26  { 0, "blt", "if (# < #) goto #", { 1, 2, 3 } },
27  { 0, "beqz", "if (# == 0) goto #", { 1, 2 } },
28  { 0, "bne", "if (# != #) goto #", { 1, 2, 3 } },
29  { 0, "bnez", "if (# != 0) goto #", { 1, 2 } },
30  { 0, "bgez", "if (# >= 0) goto #", { 1, 2 } },
31  { 0, "bgtz", "if (# > 0) goto #", { 1, 2 } },
32  { 0, "fld", "# = #", { 1, 2 } },
33  { 0, "j", "jmp #", { 1 } },
34  { 0, "jr", "jmp #", { 1 } },
35  { 0, "jalr", "jmp #", { 1 } },
36  { 0, "jal", "jmp #", { 1 } },
37  { 0, "ld", "# = (double)[#]", { 1, 2 } },
38  { 0, "li", "# = #", { 1, 2 } },
39  { 0, "lh", "# = [#]", { 1, 2 } },
40  { 0, "lui", "# = #", { 1, 2 } },
41  { 0, "lbu", "# = (unsigned)[#]", { 1, 2 } },
42  { 0, "lhu", "# = (unsigned)[#]", { 1, 2 } },
43  { 0, "lw", "# = [#]", { 1, 2 } },
44  { 0, "mv", "# = #", { 1, 2 } },
45  { 0, "or", "# = # | #", { 1, 2, 3 } },
46  { 0, "sd", "[#] = (double)#", { 2, 1 } },
47  { 0, "sw", "[#] = #", { 2, 1 } },
48  { 0, "sb", "[#] = #", { 2, 1 } },
49  { 0, "sh", "[#] = #", { 2, 1 } },
50  { 0, "sub", "# = # - #", { 1, 2, 3 } },
51  { 0, NULL }
52  };
53  if (!newstr) {
54  return false;
55  }
56 
57  for (i = 0; ops[i].op; i++) {
58  if (ops[i].narg) {
59  if (argc - 1 != ops[i].narg) {
60  continue;
61  }
62  }
63  if (!strcmp(ops[i].op, argv[0])) {
64  if (newstr) {
65  d = 0;
66  j = 0;
67  ch = ops[i].str[j];
68  for (j = 0, k = 0; ch != '\0'; j++, k++) {
69  ch = ops[i].str[j];
70  if (ch == '#') {
71  if (d >= MAXPSEUDOOPS) {
72  // XXX Shouldn't ever happen...
73  continue;
74  }
75  int idx = ops[i].args[d];
76  d++;
77  if (idx <= 0) {
78  // XXX Shouldn't ever happen...
79  continue;
80  }
81  const char *w = argv[idx];
82  if (w) {
83  strcpy(newstr + k, w);
84  k += strlen(w) - 1;
85  }
86  } else {
87  newstr[k] = ch;
88  }
89  }
90  newstr[k] = '\0';
91  }
92  rz_str_replace_char(newstr, '{', '(');
93  rz_str_replace_char(newstr, '}', ')');
94  return true;
95  }
96  }
97 
98  /* TODO: this is slow */
99  newstr[0] = '\0';
100  for (i = 0; i < argc; i++) {
101  strcat(newstr, argv[i]);
102  strcat(newstr, (!i || i == argc - 1) ? " " : ",");
103  }
104 
105  rz_str_replace_char(newstr, '{', '(');
106  rz_str_replace_char(newstr, '}', ')');
107  return false;
108 }
109 
110 static bool parse(RzParse *p, const char *data, RzStrBuf *sb) {
111  char w0[256], w1[256], w2[256], w3[256];
112  char str[1024] = { 0 };
113  int i, len = strlen(data), n;
114  char *buf, *ptr, *optr, *num;
115 
116  if (len >= sizeof(w0)) {
117  return false;
118  }
119  // malloc can be slow here :?
120  if (!(buf = malloc(len + 1))) {
121  return false;
122  }
123  memcpy(buf, data, len + 1);
124  if (*buf) {
125  *w0 = *w1 = *w2 = *w3 = '\0';
126  ptr = strchr(buf, ' ');
127  if (!ptr) {
128  ptr = strchr(buf, '\t');
129  }
130  if (ptr) {
131  *ptr = '\0';
132  for (++ptr; *ptr == ' '; ptr++) {
133  ;
134  }
135  strncpy(w0, buf, sizeof(w0) - 1);
136  strncpy(w1, ptr, sizeof(w1) - 1);
137 
138  optr = ptr;
139  if (*ptr == '(') {
140  ptr = strchr(ptr + 1, ')');
141  }
142  if (ptr && *ptr == '[') {
143  ptr = strchr(ptr + 1, ']');
144  }
145  if (ptr && *ptr == '{') {
146  ptr = strchr(ptr + 1, '}');
147  }
148  if (!ptr) {
149  eprintf("Unbalanced bracket\n");
150  free(buf);
151  return false;
152  }
153  ptr = strchr(ptr, ',');
154  if (ptr) {
155  *ptr = '\0';
156  for (++ptr; *ptr == ' '; ptr++) {
157  ;
158  }
159  strncpy(w1, optr, sizeof(w1) - 1);
160  strncpy(w2, ptr, sizeof(w2) - 1);
161  optr = ptr;
162  ptr = strchr(ptr, ',');
163  if (ptr) {
164  *ptr = '\0';
165  for (++ptr; *ptr == ' '; ptr++) {
166  ;
167  }
168  strncpy(w2, optr, sizeof(w2) - 1);
169  strncpy(w3, ptr, sizeof(w3) - 1);
170  }
171  }
172  ptr = strchr(buf, '(');
173  if (ptr) {
174  *ptr = 0;
175  num = (char *)rz_str_lchr(buf, ' ');
176  if (!num) {
177  num = (char *)rz_str_lchr(buf, ',');
178  }
179  if (num) {
180  n = atoi(num + 1);
181  *ptr = '[';
182  rz_str_cpy(num + 1, ptr);
183  ptr = (char *)rz_str_lchr(buf, ']');
184  if (n && ptr) {
185  char *rest = strdup(ptr + 1);
186  size_t dist = len + 1 - (ptr - buf);
187  if (n > 0) {
188  snprintf(ptr, dist, "+%d]%s", n, rest);
189  } else {
190  snprintf(ptr, dist, "%d]%s", n, rest);
191  }
192  free(rest);
193  }
194  } else {
195  *ptr = '[';
196  }
197  }
198  }
199  {
200  const char *wa[] = { w0, w1, w2, w3 };
201  int nw = 0;
202  for (i = 0; i < 4; i++) {
203  if (wa[i][0]) {
204  nw++;
205  }
206  }
207  replace(nw, wa, str);
208  }
209  }
210  {
211  char *s = strdup(str);
212  s = rz_str_replace(s, "+ -", "- ", 1);
213  s = rz_str_replace(s, "- -", "+ ", 1);
214  rz_strf(str, "%s", s);
215  free(s);
216  }
217  free(buf);
218  rz_strbuf_set(sb, str);
219  return true;
220 }
221 
223  .name = "riscv.pseudo",
224  .desc = "riscv pseudo syntax",
225  .parse = parse,
226 };
227 
228 #ifndef RZ_PLUGIN_INCORE
232  .version = RZ_VERSION
233 };
234 #endif
size_t len
Definition: 6502dis.c:15
static struct @29 ops[]
ut8 op
Definition: 6502dis.c:13
lzma_index ** i
Definition: index.h:629
static RASN1String * newstr(const char *string)
Definition: astr.c:23
static SblHeader sb
Definition: bin_mbn.c:26
#define RZ_API
#define NULL
Definition: cris-opc.c:27
#define w
Definition: crypto_rc6.c:13
const char * k
Definition: dsignal.c:11
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
voidpf void * buf
Definition: ioapi.h:138
snprintf
Definition: kernel.h:364
void * p
Definition: libc.cpp:67
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
void * malloc(size_t size)
Definition: malloc.c:123
static static fork const void static count static fd const char const char static newpath char char char static envp time_t static t const char static mode static whence const char static dir time_t static t unsigned static seconds const char struct utimbuf static buf static inc static sig const char static mode static oldfd struct tms static buf static getgid static geteuid const char static filename static arg static mask struct ustat static ubuf static getppid static setsid static egid sigset_t static set struct timeval struct timezone static tz fd_set fd_set fd_set struct timeval static timeout const char char static bufsiz const char static swapflags void static offset const char static length static mode static who const char struct statfs static buf unsigned unsigned num
Definition: sflib.h:126
static static fork const void static count static fd const char const char static newpath char char argv
Definition: sflib.h:40
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 args
Definition: mipsasm.c:18
int n
Definition: mipsasm.c:19
int idx
Definition: setup.py:197
static bool parse(RzParse *p, const char *data, RzStrBuf *sb)
RZ_API RzLibStruct rizin_plugin
#define MAXPSEUDOOPS
RzParsePlugin rz_parse_plugin_riscv_pseudo
static int replace(int argc, const char *argv[], char *newstr)
#define eprintf(x, y...)
Definition: rlcc.c:7
static RzSocket * s
Definition: rtr.c:28
@ RZ_LIB_TYPE_PARSE
Definition: rz_lib.h:74
RZ_API const char * rz_str_lchr(const char *str, char chr)
Definition: str.c:669
#define rz_str_cpy(x, y)
Definition: rz_str.h:109
RZ_API char * rz_str_replace(char *str, const char *key, const char *val, int g)
Definition: str.c:1110
RZ_API int rz_str_replace_char(char *s, int a, int b)
Definition: str.c:169
#define rz_strf(buf,...)
Convenience macro for local temporary strings.
Definition: rz_str.h:59
RZ_API const char * rz_strbuf_set(RzStrBuf *sb, const char *s)
Definition: strbuf.c:153
#define RZ_VERSION
Definition: rz_version.h:8
#define d(i)
Definition: sha256.c:44
Definition: dis.c:32