1 /* radare - LGPL - Copyright 2013-2019 - pancake */
2
3 #include <r_bin.h>
4 #include "../i/private.h"
5 #include "./cxx/demangle.h"
6
r_bin_demangle_cxx(RBinFile * bf,const char * str,ut64 vaddr)7 R_API char *r_bin_demangle_cxx(RBinFile *bf, const char *str, ut64 vaddr) {
8 // DMGL_TYPES | DMGL_PARAMS | DMGL_ANSI | DMGL_VERBOSE
9 // | DMGL_RET_POSTFIX | DMGL_TYPES;
10 int i;
11 #if WITH_GPL
12 int flags = DMGL_NO_OPTS | DMGL_PARAMS;
13 #endif
14 const char *prefixes[] = {
15 "__symbol_stub1_",
16 "reloc.",
17 "sym.imp.",
18 "imp.",
19 NULL
20 };
21 char *tmpstr = strdup (str);
22 char *p = tmpstr;
23
24 if (p[0] == p[1] && *p == '_') {
25 p++;
26 }
27 for (i = 0; prefixes[i]; i++) {
28 int plen = strlen (prefixes[i]);
29 if (!strncmp (p, prefixes[i], plen)) {
30 p += plen;
31 break;
32 }
33 }
34 // remove CXXABI suffix
35 char *cxxabi = strstr (p, "@@CXXABI");
36 char *glibcxx = strstr (p, "@GLIBCXX");
37 if (cxxabi) {
38 *cxxabi = '\0';
39 } else if (glibcxx) {
40 if (p < glibcxx && glibcxx[-1] == '@') {
41 glibcxx[-1] = '\0';
42 } else {
43 *glibcxx = '\0';
44 }
45 }
46 #if WITH_GPL
47 char *out = cplus_demangle_v3 (p, flags);
48 #else
49 /* TODO: implement a non-gpl alternative to c++v3 demangler */
50 char *out = NULL;
51 #endif
52 free (tmpstr);
53 if (out) {
54 char *sign = (char *)strchr (out, '(');
55 if (sign) {
56 char *str = out;
57 char *ptr = NULL;
58 char *nerd = NULL;
59 for (;;) {
60 ptr = strstr (str, "::");
61 if (!ptr || ptr > sign) {
62 break;
63 }
64 nerd = ptr;
65 str = ptr + 1;
66 }
67 if (nerd && *nerd) {
68 *nerd = 0;
69 if (bf) {
70 RBinSymbol *sym = r_bin_file_add_method (bf, out, nerd + 2, 0);
71 if (sym) {
72 if (sym->vaddr != 0 && sym->vaddr != vaddr) {
73 if (bf && bf->rbin && bf->rbin->verbose) {
74 eprintf ("Dupped method found: %s\n", sym->name);
75 }
76 }
77 if (sym->vaddr == 0) {
78 sym->vaddr = vaddr;
79 }
80 }
81 }
82 *nerd = ':';
83 }
84 }
85 }
86 return out;
87 }
88