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