Rizin
unix-like reverse engineering framework and cli tools
swift.c File Reference
#include "demangler_util.h"
#include <rz_libdemangle.h>

Go to the source code of this file.

Classes

struct  Type
 

Macros

#define STRCAT_BOUNDS(x)
 

Functions

static const char * getnum (const char *n, int *num)
 
static const char * numpos (const char *n)
 
static char * getstring (const char *s, int len)
 
static const char * resolve (struct Type *t, const char *foo, const char **bar)
 
char * libdemangle_handler_swift (const char *s)
 

Variables

static struct Type types []
 
static struct Type metas []
 
static struct Type flags []
 

Macro Definition Documentation

◆ STRCAT_BOUNDS

#define STRCAT_BOUNDS (   x)
Value:
if (((x) + 2 + strlen(out)) > sizeof(out)) \
break;
const lzma_allocator const uint8_t size_t uint8_t * out
Definition: block.h:528
int x
Definition: mipsasm.c:20

Function Documentation

◆ getnum()

static const char* getnum ( const char *  n,
int num 
)
static

Definition at line 64 of file swift.c.

64  {
65  if (num && *n) {
66  *num = atoi(n);
67  }
68  while (*n && *n >= '0' && *n <= '9') {
69  n++;
70  }
71  return n;
72 }
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
int n
Definition: mipsasm.c:19

References n, and num.

Referenced by libdemangle_handler_swift().

◆ getstring()

static char* getstring ( const char *  s,
int  len 
)
static

Definition at line 81 of file swift.c.

81  {
82  if (len < 1) {
83  return strdup("");
84  }
85  char *buf = malloc(len + 1);
86  memcpy(buf, s, len);
87  buf[len] = 0;
88  return buf;
89 }
size_t len
Definition: 6502dis.c:15
voidpf void * buf
Definition: ioapi.h:138
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
void * malloc(size_t size)
Definition: malloc.c:123
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 RzSocket * s
Definition: rtr.c:28

References len, malloc(), memcpy(), s, and strdup().

Referenced by libdemangle_handler_swift().

◆ libdemangle_handler_swift()

char* libdemangle_handler_swift ( const char *  s)

Definition at line 107 of file swift.c.

107  {
108 #define STRCAT_BOUNDS(x) \
109  if (((x) + 2 + strlen(out)) > sizeof(out)) \
110  break;
111  char out[1024];
112  int i, len, is_generic = 0;
113  int is_first = 1;
114  int is_last = 0;
115  int retmode = 0;
116  if (!strncmp(s, "imp.", 4)) {
117  s = s + 4;
118  }
119  if (!strncmp(s, "reloc.", 6)) {
120  s = s + 6;
121  }
122 
123  if (*s != 'T' && strncmp(s, "_T", 2) && strncmp(s, "__T", 3)) {
124  // modern swift symbols
125  if (strncmp(s, "$s", 2)) {
126  return NULL;
127  }
128  }
129 
130  if (!strncmp(s, "__", 2)) {
131  s = s + 2;
132  }
133 
134  const char *attr = NULL;
135  const char *attr2 = NULL;
136  const char *q, *p = s;
137  const char *q_end = p + strlen(p);
138  const char *q_start = p;
139 
140  if (strchr(s, '\'') || strchr(s, ' ')) {
141  return NULL;
142  }
143 
144  out[0] = 0;
145 
146  const char *tail = NULL;
147  if (p[0]) {
148  switch (p[1]) {
149  case 'W':
150  switch (p[2]) {
151  case 'a':
152  tail = "..protocol";
153  break;
154  }
155  break;
156  case 'F':
157  switch (p[2]) {
158  case 'e':
159  tail = "..extension";
160  p += 2;
161  break;
162  }
163  break;
164  case 'M':
165  switch (p[2]) {
166  case 'a':
167  tail = "..accessor.metadata";
168  break;
169  case 'e':
170  tail = "..override";
171  break;
172  case 'm':
173  tail = "..metaclass";
174  break;
175  case 'L':
176  tail = "..lazy.metadata";
177  break;
178  default:
179  tail = "..metadata";
180  break;
181  }
182  break;
183  case 'I': // interfaces
184  // TODO
185  return NULL;
186  }
187  }
188  if (tail) {
189  if (*p) {
190  p++;
191  }
192  } else {
193  if (*p && p[1]) {
194  p += 2;
195  }
196  }
197 
198  // XXX
199  q = getnum(p, NULL);
200 
201  // _TF or __TW
202  if (IS_DIGIT(*p) || *p == 'v' || *p == 'I' || *p == 'o' || *p == 'T' || *p == 'V' || *p == 'M' || *p == 'C' || *p == 'F' || *p == 'W') {
203  if (!strncmp(p + 1, "SS", 2)) {
204  strcat(out, "Swift.String.init (");
205  p += 3;
206  }
207  if (!strncmp(p, "vdv", 3)) {
208  tail = "..field";
209  p += 3;
210  }
211  if (!strncmp(p, "oFC", 3)) {
212  tail = "..init.witnesstable";
213  p += 4;
214  }
215  getnum(q, &len);
216  q = numpos(p);
217  for (i = 0, len = 1; len && q < q_end; q += len, i++) {
218  if (*q == 'P') {
219  q++;
220  }
221  q = getnum(q, &len);
222  if (!len) {
223  break;
224  }
225  char *str = getstring(q, len);
226  if (len == 2 && !strcmp(str, "ee")) {
227  strcat(out, "Swift");
228  } else {
229  RZ_FREE(str);
230  // push string
231  if (i && *out) {
232  strcat(out, ".");
233  }
235  len = RZ_MIN(len, strlen(q));
236  str = getstring(q, len);
237  strcat(out, str);
238  }
239  free(str);
240  }
241  if (q > q_end) {
242  return 0;
243  }
244  p = resolve(flags, q, &attr);
245  if (!p && ((*q == 'U') || (*q == 'R'))) {
246  p = resolve(metas, q, &attr);
247  if (attr && *q == 'R') {
248  attr = NULL;
249  q += 3;
250  }
251  }
252  /* parse accessors */
253  if (attr) {
254  int len = 0;
255  char *name = NULL;
256  /* get field name and then type */
257  resolve(types, q, &attr);
258 
259  q = getnum(q + 1, &len);
260  if (len < strlen(q)) {
261  resolve(types, q + len, &attr2);
262  } else {
263  resolve(types, q, &attr2);
264  }
265  name = getstring(q, len);
266  do {
267  if (name && *name) {
268  strcat(out, ".");
269  STRCAT_BOUNDS(strlen(name));
270  strcat(out, name);
271  }
272  if (attr && *attr) {
273  strcat(out, ".");
274  STRCAT_BOUNDS(strlen(attr));
275  strcat(out, attr);
276  }
277  if (attr2 && *attr2) {
278  strcat(out, "__");
279  STRCAT_BOUNDS(strlen(attr2));
280  strcat(out, attr2);
281  }
282  } while (0);
283  free(name);
284  if (*q == '_') {
285  strcat(out, " -> ()");
286  }
287  } else {
288  /* parse function parameters here */
289  // type len value/
290  for (i = 0; q && q < q_end && q >= q_start; i++) {
291  if (*q == 'f') {
292  q++;
293  }
294  switch (*q) {
295  case 's': {
296  int n = 0;
297  const char *Q = getnum(q + 1, &n);
298  char *res = getstring(Q, n);
299  strcat(out, res);
300  free(res);
301  q = Q + n + 1;
302  continue;
303  } break;
304  case 'u':
305  if (!strncmp(q, "uRxs", 4)) {
306  strcat(out, "..");
307  int n = 0;
308  const char *Q = getnum(q + 4, &n);
309  char *res = getstring(Q, n);
310  strcat(out, res);
311  free(res);
312  q = Q + n + 1;
313  continue;
314  }
315  break;
316  case 'S': // "S0"
317  if (q[1] == '1') {
318  q++;
319  }
320  switch (q[1]) {
321  case '0':
322  strcat(out, " (self) -> ()");
323  if (attr) {
324  strcat(out, attr);
325  }
326  q = p = q + 1;
327  attr = "";
328  break;
329  case 'S':
330  // swift string
331  strcat(out, "__String");
332  break;
333  case '_':
334  // swift string
335  if (q[0] && q[1] && q[2]) {
336  strcat(out, "..");
337  int n = 0;
338  const char *Q = getnum(q + 2, &n);
339  char *res = getstring(Q, n);
340  strcat(out, res);
341  free(res);
342  q = Q + n + 1;
343  continue;
344  }
345  break;
346  }
347  break;
348  case 'B':
349  case 'T':
350  case 'I':
351  p = resolve(types, q + 0, &attr); // type
352  if (p && *p && IS_DIGIT(p[1])) {
353  p--;
354  }
355  break;
356  case 'F':
357  strcat(out, " ()");
358  p = resolve(types, (strlen(q) > 2) ? q + 3 : "", &attr); // type
359  break;
360  case 'G':
361  q += 2;
362  if (!strncmp(q, "_V", 2)) {
363  q += 2;
364  }
365  p = resolve(types, q, &attr); // type
366  break;
367  case 'V':
368  p = resolve(types, q + 1, &attr); // type
369  break;
370  case '_':
371  // it's return value time!
372  p = resolve(types, q + 1, &attr); // type
373  break;
374  default:
375  p = resolve(types, q, &attr); // type
376  }
377 
378  if (p) {
379  q = getnum(p, &len);
380  if (attr && !strcmp(attr, "generic")) {
381  is_generic = 1;
382  }
383  if (!len) {
384  if (retmode) {
385  if (q + 1 > q_end) {
386  if (attr) {
387  strcat(out, " -> ");
388  STRCAT_BOUNDS(strlen(attr));
389  strcat(out, attr);
390  }
391  break;
392  }
393  resolve(types, *q ? q + 1 : q, &attr); // type
394  if (attr) {
395  strcat(out, " -> ");
396  STRCAT_BOUNDS(strlen(attr));
397  strcat(out, attr);
398  }
399  break;
400  }
401  retmode = 1;
402  len++;
403  }
404  if (len < 0 || len > 256) {
405  // invalid length
406  break;
407  }
408  if (len <= (q_end - q) && q[len]) {
409  char *s = getstring(q, len);
410  if (s && *s) {
411  if (is_first) {
412  strcat(out, is_generic ? "<" : "(");
413  is_first = 0;
414  }
415  is_last = q[len];
416  if (attr) {
417  STRCAT_BOUNDS(strlen(attr));
418  strcat(out, attr);
419  strcat(out, " ");
420  }
421  STRCAT_BOUNDS(strlen(s));
422  strcat(out, s);
423  if (is_last) {
424  strcat(out, is_generic ? ">" : ")");
425  is_first = (*s != '_');
426  if (is_generic && !is_first) {
427  break;
428  }
429  } else {
430  strcat(out, ", ");
431  }
432  } else {
433  if (attr) {
434  strcat(out, " -> ");
435  STRCAT_BOUNDS(strlen(attr));
436  strcat(out, attr);
437  }
438  }
439  free(s);
440  } else {
441  if (attr) {
442  strcat(out, " -> ");
443  STRCAT_BOUNDS(strlen(attr));
444  strcat(out, attr);
445  }
446  }
447  q += len;
448  p = q;
449  } else {
450  if (q && *q) {
451  q++;
452  } else {
453  break;
454  }
455  char *n = strstr(q, "__");
456  if (n) {
457  q = n + 1;
458  } else {
459  n = strchr(q, '_');
460  if (n) {
461  q = n + 1;
462  } else {
463  break;
464  }
465  }
466  }
467  }
468  }
469  }
470  if (*out) {
471  if (tail) {
472  strcat(out, tail);
473  }
474 #if 1
475  char *p, *outstr = strdup(out);
476  p = outstr;
477  for (;;) {
478  p = strstr(p, ")(");
479  if (p) {
480  p[0] = '_';
481  p[1] = '_';
482  p += 2;
483  } else {
484  break;
485  }
486  }
487  return outstr;
488 #endif
489  }
490  return NULL;
491 }
lzma_index ** i
Definition: index.h:629
#define Q(x)
#define NULL
Definition: cris-opc.c:27
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
void * p
Definition: libc.cpp:67
#define IS_DIGIT(x)
Definition: rz_str_util.h:11
#define RZ_FREE(x)
Definition: rz_types.h:369
#define RZ_MIN(x, y)
Definition: z80asm.h:102
static struct Type types[]
Definition: swift.c:12
static struct Type flags[]
Definition: swift.c:52
#define STRCAT_BOUNDS(x)
static const char * numpos(const char *n)
Definition: swift.c:74
static char * getstring(const char *s, int len)
Definition: swift.c:81
static const char * getnum(const char *n, int *num)
Definition: swift.c:64
static const char * resolve(struct Type *t, const char *foo, const char **bar)
Definition: swift.c:91
static struct Type metas[]
Definition: swift.c:39

References flags, free(), getnum(), getstring(), i, IS_DIGIT, len, metas, n, NULL, numpos(), out, p, Q, resolve(), RZ_FREE, RZ_MIN, s, cmd_descs_generate::str, STRCAT_BOUNDS, strdup(), and types.

◆ numpos()

static const char* numpos ( const char *  n)
static

Definition at line 74 of file swift.c.

74  {
75  while (*n && (*n < '0' || *n > '9')) {
76  n++;
77  }
78  return n;
79 }

References n.

Referenced by libdemangle_handler_swift().

◆ resolve()

static const char* resolve ( struct Type t,
const char *  foo,
const char **  bar 
)
static

Definition at line 91 of file swift.c.

91  {
92  if (!t || !foo || !*foo) {
93  return NULL;
94  }
95  for (; t[0].code; t++) {
96  int len = strlen(t[0].code);
97  if (!strncmp(foo, t[0].code, len)) {
98  if (bar) {
99  *bar = t[0].name;
100  }
101  return foo + len;
102  }
103  }
104  return NULL;
105 }
static RzMain foo[]
Definition: main.c:11
const char * name
Definition: swift.c:9
const char * code
Definition: swift.c:8
Definition: inftree9.h:24

References Type::code, foo, len, Type::name, and NULL.

Referenced by dex_resolve_symbol_in_class_methods(), libdemangle_handler_swift(), rz_bin_dex_resolve_symbol(), and rz_bin_java_class_resolve_symbol().

Variable Documentation

◆ flags

struct Type flags[]
static
Initial value:
= {
{ "s", "setter" },
{ "g", "getter" },
{ "m", "method" },
{ "d", "destructor" },
{ "D", "deallocator" },
{ "c", "constructor" },
{ "C", "allocator" },
{ NULL, NULL }
}

Definition at line 1 of file swift.c.

Referenced by libdemangle_handler_swift().

◆ metas

struct Type metas[]
static
Initial value:
= {
{ "FC", "ClassFunc" },
{ "S0_FT", "?" },
{ "RxC", ".." },
{ "S0", "self" },
{ "U__FQ_T_", "<A>(A)" },
{ "ToFC", "@objc class func" },
{ "ToF", "@objc func" },
{ NULL, NULL }
}

Definition at line 1 of file swift.c.

Referenced by can_emulate_metadata(), ds_disassemble(), ds_print_meta_infos(), libdemangle_handler_swift(), requires_op_size(), rz_analysis_fcn(), rz_analysis_reflines_get(), and rz_core_analysis_get_stats().

◆ types

struct Type types[]
static
Initial value:
= {
{ "Sb", "Bool" },
{ "SS", "String" },
{ "FS", "String" },
{ "GV", "mutableAddressor" },
{ "Ss", "generic" },
{ "S_", "Generic" },
{ "TF", "GenericSpec" },
{ "Ts", "String" },
{ "Sa", "Array" },
{ "Si", "Swift.Int" },
{ "Sf", "Float" },
{ "Sb", "Bool" },
{ "Su", "UInt" },
{ "SQ", "ImplicitlyUnwrappedOptional" },
{ "Sc", "UnicodeScalar" },
{ "Sd", "Double" },
{ "SS", "String" },
{ "Bi1", "Builtin.Int1" },
{ "Bp", "Builtin.RawPointer" },
{ "Bw", "Builtin.Word" },
{ NULL, NULL }
}

Definition at line 1 of file swift.c.

Referenced by libdemangle_handler_swift().