Rizin
unix-like reverse engineering framework and cli tools
emit_arm.c File Reference
#include <rz_egg.h>

Go to the source code of this file.

Macros

#define attsyntax   0
 
#define EMIT_NAME   emit_arm
 
#define RZ_ARCH   "arm"
 
#define RZ_SZ   8
 
#define RZ_SP   "sp"
 
#define RZ_BP   "fp"
 
#define RZ_AX   "r7"
 
#define RZ_GP    { "r0", "r1", "r2", "r3", "r4" }
 
#define RZ_TMP   "r9"
 
#define RZ_NGP   5
 

Functions

static void emit_init (RzEgg *egg)
 
static char * emit_syscall (RzEgg *egg, int num)
 
static void emit_frame (RzEgg *egg, int sz)
 
static void emit_frame_end (RzEgg *egg, int sz, int ctx)
 
static void emit_comment (RzEgg *egg, const char *fmt,...)
 
static void emit_equ (RzEgg *egg, const char *key, const char *value)
 
static void emit_syscall_args (RzEgg *egg, int nargs)
 
static void emit_set_string (RzEgg *egg, const char *dstvar, const char *str, int j)
 
static void emit_jmp (RzEgg *egg, const char *str, int atr)
 
static void emit_call (RzEgg *egg, const char *str, int atr)
 
static void emit_arg (RzEgg *egg, int xs, int num, const char *str)
 
static void emit_get_result (RzEgg *egg, const char *ocn)
 
static void emit_restore_stack (RzEgg *egg, int size)
 
static void emit_get_while_end (RzEgg *egg, char *str, const char *ctxpush, const char *label)
 
static void emit_while_end (RzEgg *egg, const char *labelback)
 
static void emit_get_var (RzEgg *egg, int type, char *out, int idx)
 
static void emit_trap (RzEgg *egg)
 
static void emit_load_ptr (RzEgg *egg, const char *dst)
 
static void emit_branch (RzEgg *egg, char *b, char *g, char *e, char *n, int sz, const char *dst)
 
static void emit_load (RzEgg *egg, const char *dst, int sz)
 
static void emit_mathop (RzEgg *egg, int ch, int vs, int type, const char *eq, const char *p)
 
static const char * emit_regs (RzEgg *egg, int idx)
 

Variables

static char * regs [] = RZ_GP
 
static int lastarg = 0
 
static char lastargs [16][32]
 
RzEggEmit EMIT_NAME
 

Macro Definition Documentation

◆ attsyntax

#define attsyntax   0

Definition at line 5 of file emit_arm.c.

◆ EMIT_NAME

#define EMIT_NAME   emit_arm

Definition at line 7 of file emit_arm.c.

◆ RZ_ARCH

#define RZ_ARCH   "arm"

Definition at line 8 of file emit_arm.c.

◆ RZ_AX

#define RZ_AX   "r7"

Definition at line 12 of file emit_arm.c.

◆ RZ_BP

#define RZ_BP   "fp"

Definition at line 11 of file emit_arm.c.

◆ RZ_GP

#define RZ_GP    { "r0", "r1", "r2", "r3", "r4" }

Definition at line 13 of file emit_arm.c.

◆ RZ_NGP

#define RZ_NGP   5

Definition at line 16 of file emit_arm.c.

◆ RZ_SP

#define RZ_SP   "sp"

Definition at line 10 of file emit_arm.c.

◆ RZ_SZ

#define RZ_SZ   8

Definition at line 9 of file emit_arm.c.

◆ RZ_TMP

#define RZ_TMP   "r9"

Definition at line 15 of file emit_arm.c.

Function Documentation

◆ emit_arg()

static void emit_arg ( RzEgg egg,
int  xs,
int  num,
const char *  str 
)
static

Definition at line 139 of file emit_arm.c.

139  {
140  int d = atoi(str);
141  if (!attsyntax && (*str == '$')) {
142  str++;
143  }
144  lastarg = num;
145  switch (xs) {
146  case 0:
147  if (strchr(str, ',')) {
148  // rz_egg_printf (egg, ". str r0, [%s]\n", str);
149  strncpy(lastargs[num - 1], str, sizeof(lastargs[0]) - 1);
150  } else {
151  if (!atoi(str)) {
152  eprintf("WARNING: probably a bug?\n");
153  }
154  rz_egg_printf(egg, " mov r0, %s\n", str);
155  snprintf(lastargs[num - 1], sizeof(lastargs[0]), "sp, %d", 8 + (num * 4));
156  rz_egg_printf(egg, " str r0, [%s]\n", lastargs[num - 1]);
157  }
158  break;
159  case '*':
160  rz_egg_printf(egg, " push {%s}\n", str);
161  break;
162  case '&':
163  if (d) {
164  rz_egg_printf(egg, " add " RZ_BP ", %d\n", d);
165  }
166  rz_egg_printf(egg, " push {" RZ_BP "}\n");
167  if (d) {
168  rz_egg_printf(egg, " sub " RZ_BP ", %d\n", d);
169  }
170  break;
171  }
172 }
RZ_API void rz_egg_printf(RzEgg *egg, const char *fmt,...)
Definition: egg.c:336
#define attsyntax
Definition: emit_arm.c:5
static char lastargs[16][32]
Definition: emit_arm.c:21
#define RZ_BP
Definition: emit_arm.c:11
static int lastarg
Definition: emit_arm.c:20
snprintf
Definition: kernel.h:364
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
#define eprintf(x, y...)
Definition: rlcc.c:7
#define d(i)
Definition: sha256.c:44

References attsyntax, d, eprintf, lastarg, lastargs, num, RZ_BP, rz_egg_printf(), snprintf, and cmd_descs_generate::str.

◆ emit_branch()

static void emit_branch ( RzEgg egg,
char *  b,
char *  g,
char *  e,
char *  n,
int  sz,
const char *  dst 
)
static

Definition at line 213 of file emit_arm.c.

213  {
214  char *p, str[64];
215  char *arg = NULL;
216  char *op = "beq";
217  /* NOTE that jb/ja are inverted to fit cmp opcode */
218  if (b) {
219  *b = '\0';
220  op = e ? "bge" : "bgt";
221  arg = b + 1;
222  } else if (g) {
223  *g = '\0';
224  op = e ? "ble" : "blt";
225  arg = g + 1;
226  }
227  if (!arg) {
228  if (e) {
229  arg = e + 1;
230  op = "bne";
231  } else {
232  arg = "0";
233  op = n ? "bne" : "beq";
234  }
235  }
236 
237  if (*arg == '=') {
238  arg++; /* for <=, >=, ... */
239  }
240  p = rz_egg_mkvar(egg, str, arg, 0);
241  rz_egg_printf(egg, " pop " RZ_AX "\n"); /* TODO: add support for more than one arg get arg0 */
242  rz_egg_printf(egg, " cmp %s, " RZ_AX "\n", p);
243  // if (context>0)
244  rz_egg_printf(egg, " %s %s\n", op, dst);
245  free(p);
246 }
#define e(frag)
#define NULL
Definition: cris-opc.c:27
RZ_API char * rz_egg_mkvar(RzEgg *egg, char *out, const char *_str, int delta)
Definition: egg_lang.c:538
#define RZ_AX
Definition: emit_arm.c:12
struct @667 g
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
void * p
Definition: libc.cpp:67
char * dst
Definition: lz4.h:724
int n
Definition: mipsasm.c:19
#define b(i)
Definition: sha256.c:42
Definition: dis.c:32

References b, dst, e, free(), g, n, NULL, p, RZ_AX, rz_egg_mkvar(), rz_egg_printf(), and cmd_descs_generate::str.

◆ emit_call()

static void emit_call ( RzEgg egg,
const char *  str,
int  atr 
)
static

Definition at line 123 of file emit_arm.c.

123  {
124  int i;
125  // rz_egg_printf (egg, " ARGS=%d CALL(%s,%d)\n", lastarg, str, atr);
126  for (i = 0; i < lastarg; i++) {
127  rz_egg_printf(egg, " ldr r%d, [%s]\n", lastarg - 1 - i, lastargs[i]);
128  lastargs[i][0] = 0;
129  }
130 
131  if (atr) {
132  rz_egg_printf(egg, " ldr r0, %s", str);
133  rz_egg_printf(egg, " blx r0\n");
134  } else {
135  rz_egg_printf(egg, " bl %s\n", str);
136  }
137 }
lzma_index ** i
Definition: index.h:629

References i, lastarg, lastargs, rz_egg_printf(), and cmd_descs_generate::str.

◆ emit_comment()

static void emit_comment ( RzEgg egg,
const char *  fmt,
  ... 
)
static

Definition at line 66 of file emit_arm.c.

66  {
67  va_list ap;
68  char buf[1024];
69  va_start(ap, fmt);
70  vsnprintf(buf, sizeof(buf), fmt, ap);
71  rz_egg_printf(egg, "# %s\n", buf);
72  va_end(ap);
73 }
voidpf void * buf
Definition: ioapi.h:138
vsnprintf
Definition: kernel.h:366

References rz_egg_printf(), and vsnprintf.

◆ emit_equ()

static void emit_equ ( RzEgg egg,
const char *  key,
const char *  value 
)
static

Definition at line 75 of file emit_arm.c.

75  {
76  rz_egg_printf(egg, ".equ %s, %s\n", key, value);
77 }
static int value
Definition: cmd_api.c:93
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 key
Definition: sflib.h:118

References key, rz_egg_printf(), and value.

◆ emit_frame()

static void emit_frame ( RzEgg egg,
int  sz 
)
static

Definition at line 46 of file emit_arm.c.

46  {
47  rz_egg_printf(egg, " push {fp,lr}\n");
48  if (sz > 0) {
49  rz_egg_printf(egg,
50  // " mov "RZ_BP", "RZ_SP"\n"
51  " add fp, sp, $4\n" // size of arguments
52  " sub sp, %d\n",
53  sz); // size of stackframe 8, 16, ..
54  }
55 }

References rz_egg_printf().

◆ emit_frame_end()

static void emit_frame_end ( RzEgg egg,
int  sz,
int  ctx 
)
static

Definition at line 57 of file emit_arm.c.

57  {
58  if (sz > 0) {
59  rz_egg_printf(egg, " add sp, fp, %d\n", sz);
60  }
61  if (ctx > 0) {
62  rz_egg_printf(egg, " pop {fp,pc}\n");
63  }
64 }

References rz_egg_printf().

◆ emit_get_result()

static void emit_get_result ( RzEgg egg,
const char *  ocn 
)
static

Definition at line 174 of file emit_arm.c.

174  {
175  rz_egg_printf(egg, " mov %s, r0\n", ocn);
176 }

References rz_egg_printf().

◆ emit_get_var()

static void emit_get_var ( RzEgg egg,
int  type,
char *  out,
int  idx 
)
static

Definition at line 195 of file emit_arm.c.

195  {
196  switch (type) {
197  case 0: sprintf(out, "sp, %d", idx - 1); break; /* variable */
198  case 1:
199  sprintf(out, "r%d", idx);
200  break; /* registers */
201  // sp,$%d", idx); break; /* argument */ // XXX: MUST BE r0, r1, r2, ..
202  }
203 }
const lzma_allocator const uint8_t size_t uint8_t * out
Definition: block.h:528
sprintf
Definition: kernel.h:365
int type
Definition: mipsasm.c:17
int idx
Definition: setup.py:197

References setup::idx, out, sprintf, and type.

◆ emit_get_while_end()

static void emit_get_while_end ( RzEgg egg,
char *  str,
const char *  ctxpush,
const char *  label 
)
static

Definition at line 183 of file emit_arm.c.

183  {
184  sprintf(str, " push {%s}\n b %s\n", ctxpush, label);
185 }
Definition: dis.h:35

References sprintf, and cmd_descs_generate::str.

◆ emit_init()

static void emit_init ( RzEgg egg)
static

Definition at line 23 of file emit_arm.c.

23  {
24  /* TODO */
25 }

◆ emit_jmp()

static void emit_jmp ( RzEgg egg,
const char *  str,
int  atr 
)
static

Definition at line 114 of file emit_arm.c.

114  {
115  if (atr) {
116  rz_egg_printf(egg, " ldr r0, %s", str);
117  rz_egg_printf(egg, " bx r0\n");
118  } else {
119  rz_egg_printf(egg, " b %s\n", str);
120  }
121 }

References rz_egg_printf(), and cmd_descs_generate::str.

◆ emit_load()

static void emit_load ( RzEgg egg,
const char *  dst,
int  sz 
)
static

Definition at line 248 of file emit_arm.c.

248  {
249  switch (sz) {
250  case 'l':
251  rz_egg_printf(egg, " mov " RZ_AX ", %s\n", dst);
252  rz_egg_printf(egg, " mov " RZ_AX ", [" RZ_AX "]\n");
253  break;
254  case 'b':
255  rz_egg_printf(egg, " mov " RZ_AX ", %s\n", dst);
256  rz_egg_printf(egg, " movz " RZ_AX ", [" RZ_AX "]\n");
257  break;
258  default:
259  // TODO: unhandled?!?
260  rz_egg_printf(egg, " mov " RZ_AX ", %s\n", dst);
261  rz_egg_printf(egg, " mov " RZ_AX ", [" RZ_AX "]\n");
262  }
263 }

References dst, RZ_AX, and rz_egg_printf().

◆ emit_load_ptr()

static void emit_load_ptr ( RzEgg egg,
const char *  dst 
)
static

Definition at line 209 of file emit_arm.c.

209  {
210  rz_egg_printf(egg, " ldr r0, [fp, %d]\n", atoi(dst));
211 }

References dst, and rz_egg_printf().

◆ emit_mathop()

static void emit_mathop ( RzEgg egg,
int  ch,
int  vs,
int  type,
const char *  eq,
const char *  p 
)
static

Definition at line 265 of file emit_arm.c.

265  {
266  char *op;
267  switch (ch) {
268  case '^': op = "eor"; break;
269  case '&': op = "and"; break;
270  case '|': op = "orr"; break;
271  case '-': op = "sub"; break;
272  case '+': op = "add"; break;
273  case '*': op = "mul"; break;
274  case '/': op = "div"; break;
275  default: op = "mov"; break;
276  }
277  if (!eq) {
278  eq = RZ_AX;
279  }
280  if (!p) {
281  p = RZ_AX;
282  }
283 #if 0
284  // TODO:
285  eprintf ("TYPE = %c\n", type);
286  eprintf (" %s%c %c%s, %s\n", op, vs, type, eq, p);
287  eprintf (" %s %s, [%s]\n", op, p, eq);
288 #endif
289  if (type == '*') {
290  rz_egg_printf(egg, " %s %s, [%s]\n", op, p, eq);
291  } else {
292  rz_egg_printf(egg, " %s %s, %s\n", op, p, eq);
293  }
294 }
ut8 op
Definition: 6502dis.c:13

References eprintf, eq, op, p, RZ_AX, rz_egg_printf(), and type.

◆ emit_regs()

static const char* emit_regs ( RzEgg egg,
int  idx 
)
static

Definition at line 296 of file emit_arm.c.

296  {
297  return regs[idx % RZ_NGP];
298 }
static char * regs[]
Definition: emit_arm.c:19
#define RZ_NGP
Definition: emit_arm.c:16

References setup::idx, regs, and RZ_NGP.

◆ emit_restore_stack()

static void emit_restore_stack ( RzEgg egg,
int  size 
)
static

Definition at line 178 of file emit_arm.c.

178  {
179  // XXX: must die.. or add emit_store_stack. not needed by ARM
180  // rz_egg_printf (egg, " add sp, %d\n", size);
181 }

◆ emit_set_string()

static void emit_set_string ( RzEgg egg,
const char *  dstvar,
const char *  str,
int  j 
)
static

Definition at line 88 of file emit_arm.c.

88  {
89  int rest, off = 0;
90  off = strlen(str) + 1;
91  rest = (off % 4);
92  if (rest) {
93  rest = 4 - rest;
94  }
95  off += rest - 4;
96  rz_egg_printf(egg, " add pc, %d\n", (off));
97  // XXX: does not handle \n and so on.. must use rz_util
98  // use rz_str_escape to handle \n
99  // do not forget mem leak
100  rz_egg_printf(egg, ".string \"%s\"\n", str = rz_str_escape(str));
101  free((char *)str);
102  if (rest) {
103  rz_egg_printf(egg, ".fill %d, 1, 0\n", (rest));
104  }
105  rz_egg_printf(egg, " sub r0, pc, %d\n", off + 12);
106  {
107  char str[32], *p = rz_egg_mkvar(egg, str, dstvar, 0);
108  // rz_egg_printf (egg, "DSTVAR=%s --> %s\n", dstvar, p);
109  rz_egg_printf(egg, " str r0, [%s]\n", p);
110  free(p);
111  }
112 }
int off
Definition: pal.c:13
RZ_API RZ_OWN char * rz_str_escape(RZ_NONNULL const char *buf)
Definition: str.c:1550

References free(), off, p, rz_egg_mkvar(), rz_egg_printf(), rz_str_escape(), and cmd_descs_generate::str.

◆ emit_syscall()

static char* emit_syscall ( RzEgg egg,
int  num 
)
static

Definition at line 27 of file emit_arm.c.

27  {
28  int svc = 0;
29  switch (egg->os) {
30  case RZ_EGG_OS_DARWIN:
31  case RZ_EGG_OS_OSX:
32  case RZ_EGG_OS_IOS:
33  case RZ_EGG_OS_MACOS:
34  svc = 0x80;
35  break;
36  case RZ_EGG_OS_WATCHOS:
37  svc = 0x8000;
38  break;
39  case RZ_EGG_OS_LINUX:
40  svc = 0;
41  break;
42  }
43  return rz_str_newf(": mov " RZ_AX ", `.arg`\n: svc 0x%x\n", svc);
44 }
static RzILOpEffect * svc(cs_insn *insn, bool is_thumb)
Definition: arm_il32.c:1134
#define RZ_EGG_OS_IOS
Definition: rz_egg.h:131
#define RZ_EGG_OS_WATCHOS
Definition: rz_egg.h:130
#define RZ_EGG_OS_DARWIN
Definition: rz_egg.h:129
#define RZ_EGG_OS_MACOS
Definition: rz_egg.h:132
#define RZ_EGG_OS_OSX
Definition: rz_egg.h:128
#define RZ_EGG_OS_LINUX
Definition: rz_egg.h:127
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
ut32 os
Definition: rz_egg.h:109

References rz_egg_t::os, RZ_AX, RZ_EGG_OS_DARWIN, RZ_EGG_OS_IOS, RZ_EGG_OS_LINUX, RZ_EGG_OS_MACOS, RZ_EGG_OS_OSX, RZ_EGG_OS_WATCHOS, rz_str_newf(), and svc().

◆ emit_syscall_args()

static void emit_syscall_args ( RzEgg egg,
int  nargs 
)
static

Definition at line 79 of file emit_arm.c.

79  {
80  int j, k;
81  for (j = 0; j < nargs; j++) {
82  k = j * RZ_SZ;
83  rz_egg_printf(egg, " ldr %s, [sp, %d]\n",
84  regs[j + 1], k ? k + 4 : k + 8);
85  }
86 }
const char * k
Definition: dsignal.c:11
#define RZ_SZ
Definition: emit_arm.c:9

References k, cmd_descs_generate::nargs, regs, rz_egg_printf(), and RZ_SZ.

◆ emit_trap()

static void emit_trap ( RzEgg egg)
static

Definition at line 205 of file emit_arm.c.

205  {
206  rz_egg_printf(egg, " udf 16\n");
207 }

References rz_egg_printf().

◆ emit_while_end()

static void emit_while_end ( RzEgg egg,
const char *  labelback 
)
static

Definition at line 187 of file emit_arm.c.

187  {
188  rz_egg_printf(egg,
189  " pop " RZ_AX "\n"
190  " cmp " RZ_AX ", " RZ_AX "\n" // XXX MUST SUPPORT != 0 COMPARE HERE
191  " beq %s\n",
192  labelback);
193 }

References RZ_AX, and rz_egg_printf().

Variable Documentation

◆ EMIT_NAME

RzEggEmit EMIT_NAME
Initial value:
= {
.arch = RZ_ARCH,
.size = RZ_SZ,
.jmp = emit_jmp,
.call = emit_call,
.init = emit_init,
.equ = emit_equ,
.regs = emit_regs,
.trap = emit_trap,
.frame = emit_frame,
.frame_end = emit_frame_end,
.comment = emit_comment,
.push_arg = emit_arg,
.restore_stack = emit_restore_stack,
.get_result = emit_get_result,
.syscall_args = emit_syscall_args,
.set_string = emit_set_string,
.get_var = emit_get_var,
.while_end = emit_while_end,
.get_while_end = emit_get_while_end,
.branch = emit_branch,
.load = emit_load,
.load_ptr = emit_load_ptr,
.mathop = emit_mathop,
.syscall = emit_syscall,
}
static void emit_comment(RzEgg *egg, const char *fmt,...)
Definition: emit_arm.c:66
static void emit_branch(RzEgg *egg, char *b, char *g, char *e, char *n, int sz, const char *dst)
Definition: emit_arm.c:213
static void emit_jmp(RzEgg *egg, const char *str, int atr)
Definition: emit_arm.c:114
static void emit_call(RzEgg *egg, const char *str, int atr)
Definition: emit_arm.c:123
#define RZ_ARCH
Definition: emit_arm.c:8
static void emit_init(RzEgg *egg)
Definition: emit_arm.c:23
static char * emit_syscall(RzEgg *egg, int num)
Definition: emit_arm.c:27
static void emit_frame_end(RzEgg *egg, int sz, int ctx)
Definition: emit_arm.c:57
static void emit_get_while_end(RzEgg *egg, char *str, const char *ctxpush, const char *label)
Definition: emit_arm.c:183
static void emit_trap(RzEgg *egg)
Definition: emit_arm.c:205
static void emit_restore_stack(RzEgg *egg, int size)
Definition: emit_arm.c:178
static void emit_while_end(RzEgg *egg, const char *labelback)
Definition: emit_arm.c:187
static void emit_get_var(RzEgg *egg, int type, char *out, int idx)
Definition: emit_arm.c:195
static void emit_load(RzEgg *egg, const char *dst, int sz)
Definition: emit_arm.c:248
static const char * emit_regs(RzEgg *egg, int idx)
Definition: emit_arm.c:296
static void emit_arg(RzEgg *egg, int xs, int num, const char *str)
Definition: emit_arm.c:139
static void emit_mathop(RzEgg *egg, int ch, int vs, int type, const char *eq, const char *p)
Definition: emit_arm.c:265
static void emit_syscall_args(RzEgg *egg, int nargs)
Definition: emit_arm.c:79
static void emit_get_result(RzEgg *egg, const char *ocn)
Definition: emit_arm.c:174
static void emit_set_string(RzEgg *egg, const char *dstvar, const char *str, int j)
Definition: emit_arm.c:88
static void emit_frame(RzEgg *egg, int sz)
Definition: emit_arm.c:46
static void emit_load_ptr(RzEgg *egg, const char *dst)
Definition: emit_arm.c:209
static void emit_equ(RzEgg *egg, const char *key, const char *value)
Definition: emit_arm.c:75

Definition at line 300 of file emit_arm.c.

◆ lastarg

int lastarg = 0
static

Definition at line 20 of file emit_arm.c.

Referenced by emit_arg(), and emit_call().

◆ lastargs

char lastargs[16][32]
static

Definition at line 21 of file emit_arm.c.

Referenced by emit_arg(), and emit_call().

◆ regs

char* regs[] = RZ_GP
static

Definition at line 19 of file emit_arm.c.

Referenced by emit_regs(), and emit_syscall_args().