1 /* radare - LGPL - Copyright 2011-2019 - pancake */
2
3 #include <r_bin.h>
4 #include "i/private.h"
5 #include <cxx/demangle.h>
6
r_bin_demangle_list(RBin * bin)7 R_API void r_bin_demangle_list(RBin *bin) {
8 const char *langs[] = { "c++", "java", "objc", "swift", "dlang", "msvc", "rust", NULL };
9 RBinPlugin *plugin;
10 RListIter *it;
11 int i;
12 if (!bin) {
13 return;
14 }
15 for (i = 0; langs[i]; i++) {
16 bin->cb_printf ("%s\n", langs[i]);
17 }
18 r_list_foreach (bin->plugins, it, plugin) {
19 if (plugin->demangle) {
20 bin->cb_printf ("%s\n", plugin->name);
21 }
22 }
23 }
24
r_bin_demangle_plugin(RBin * bin,const char * name,const char * str)25 R_API char *r_bin_demangle_plugin(RBin *bin, const char *name, const char *str) {
26 RBinPlugin *plugin;
27 RListIter *it;
28 if (bin && name && str) {
29 r_list_foreach (bin->plugins, it, plugin) {
30 if (plugin->demangle && !strncmp (plugin->name, name, strlen (plugin->name))) {
31 return plugin->demangle (str);
32 }
33 }
34 }
35 return NULL;
36 }
37
r_bin_demangle_type(const char * str)38 R_API int r_bin_demangle_type(const char *str) {
39 if (str && *str) {
40 if (!strcmp (str, "swift")) {
41 return R_BIN_NM_SWIFT;
42 }
43 if (!strcmp (str, "java")) {
44 return R_BIN_NM_JAVA;
45 }
46 if (!strcmp (str, "objc")) {
47 return R_BIN_NM_OBJC;
48 }
49 if (!strcmp (str, "cxx") || !strcmp (str, "c++")) {
50 return R_BIN_NM_CXX;
51 }
52 if (!strcmp (str, "dlang")) {
53 return R_BIN_NM_DLANG;
54 }
55 if (!strcmp (str, "msvc")) {
56 return R_BIN_NM_MSVC;
57 }
58 if (!strcmp (str, "rust")) {
59 return R_BIN_NM_RUST;
60 }
61 }
62 return R_BIN_NM_NONE;
63 }
64
r_bin_demangle(RBinFile * bf,const char * def,const char * str,ut64 vaddr,bool libs)65 R_API char *r_bin_demangle(RBinFile *bf, const char *def, const char *str, ut64 vaddr, bool libs) {
66 int type = -1;
67 if (R_STR_ISEMPTY (str)) {
68 return NULL;
69 }
70 RBin *bin = bf? bf->rbin: NULL;
71 RBinObject *o = bf? bf->o: NULL;
72 RListIter *iter;
73 const char *lib = NULL;
74 if (!strncmp (str, "reloc.", 6)) {
75 str += 6;
76 }
77 if (!strncmp (str, "sym.", 4)) {
78 str += 4;
79 }
80 if (!strncmp (str, "imp.", 4)) {
81 str += 4;
82 }
83 if (o && libs) {
84 bool found = false;
85 r_list_foreach (o->libs, iter, lib) {
86 size_t len = strlen (lib);
87 if (!r_str_ncasecmp (str, lib, len)) {
88 str += len;
89 if (*str == '_') {
90 str++;
91 }
92 found = true;
93 break;
94 }
95 }
96 if (found) {
97 size_t len = strlen (bin->file);
98 if (!r_str_ncasecmp (str, bin->file, len)) {
99 lib = bin->file;
100 str += len;
101 if (*str == '_') {
102 str++;
103 }
104 }
105 }
106 }
107 if (!strncmp (str, "__", 2)) {
108 if (str[2] == 'T') {
109 type = R_BIN_NM_SWIFT;
110 } else {
111 type = R_BIN_NM_CXX;
112 // str++;
113 }
114 }
115 // if str is sym. or imp. when str+=4 str points to the end so just return
116 if (!*str) {
117 return NULL;
118 }
119 if (type == -1) {
120 type = r_bin_lang_type (bf, def, str);
121 }
122 char *demangled = NULL;
123 switch (type) {
124 case R_BIN_NM_JAVA: demangled = r_bin_demangle_java (str); break;
125 case R_BIN_NM_RUST: demangled = r_bin_demangle_rust (bf, str, vaddr); break;
126 case R_BIN_NM_OBJC: demangled = r_bin_demangle_objc (NULL, str); break;
127 case R_BIN_NM_SWIFT: demangled = r_bin_demangle_swift (str, bin? bin->demanglercmd: false); break;
128 case R_BIN_NM_CXX: demangled = r_bin_demangle_cxx (bf, str, vaddr); break;
129 case R_BIN_NM_MSVC: demangled = r_bin_demangle_msvc (str); break;
130 case R_BIN_NM_DLANG: demangled = r_bin_demangle_plugin (bin, "dlang", str); break;
131 }
132 if (libs && demangled && lib) {
133 char *d = r_str_newf ("%s_%s", lib, demangled);
134 free (demangled);
135 demangled = d;
136 }
137 return demangled;
138 }
139