Rizin
unix-like reverse engineering framework and cli tools
demangler.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2021 RizinOrg <info@rizin.re>
2 // SPDX-FileCopyrightText: 2021 deroad <wargio@libero.it>
3 // SPDX-License-Identifier: LGPL-3.0-only
4 
5 #include <rz_demangler.h>
6 #include <rz_util.h>
7 #include <rz_libdemangle.h>
8 #include <config.h>
9 
10 #define DEFINE_DEMANGLER_PLUGIN(name, lang, lic, auth, handler) \
11  RZ_API RzDemanglerPlugin rz_demangler_plugin_##name = { \
12  .language = lang, \
13  .license = lic, \
14  .author = auth, \
15  .demangle = &handler, \
16  }
17 
18 #if WITH_GPL
19 DEFINE_DEMANGLER_PLUGIN(cpp, "c++", "GPL-2", "Free Software Foundation", libdemangle_handler_cxx);
20 // rust demangler requires the cpp one.
21 DEFINE_DEMANGLER_PLUGIN(rust, "rust", "LGPL3", "pancake", libdemangle_handler_rust);
22 #endif
23 #if WITH_SWIFT_DEMANGLER
24 DEFINE_DEMANGLER_PLUGIN(swift, "swift", "MIT", "pancake", libdemangle_handler_swift);
25 #endif
26 
27 DEFINE_DEMANGLER_PLUGIN(java, "java", "LGPL3", "deroad", libdemangle_handler_java);
28 DEFINE_DEMANGLER_PLUGIN(msvc, "msvc", "LGPL3", "inisider", libdemangle_handler_msvc);
29 DEFINE_DEMANGLER_PLUGIN(objc, "objc", "LGPL3", "pancake", libdemangle_handler_objc);
30 
32 
33 RZ_LIB_VERSION(rz_demangler);
34 
38 RZ_API RZ_OWN char *rz_demangler_java(RZ_NULLABLE const char *symbol) {
39  return libdemangle_handler_java(symbol);
40 }
41 
45 RZ_API RZ_OWN char *rz_demangler_cxx(RZ_NONNULL const char *symbol) {
46 #if WITH_GPL
47  return libdemangle_handler_cxx(symbol);
48 #else
49  return NULL;
50 #endif
51 }
52 
56 RZ_API RZ_OWN char *rz_demangler_objc(RZ_NONNULL const char *symbol) {
57  return libdemangle_handler_objc(symbol);
58 }
59 
63 RZ_API RZ_OWN char *rz_demangler_rust(RZ_NONNULL const char *symbol) {
64 #if WITH_GPL
65  return libdemangle_handler_rust(symbol);
66 #else
67  return NULL;
68 #endif
69 }
70 
74 RZ_API RZ_OWN char *rz_demangler_msvc(RZ_NONNULL const char *symbol) {
75  return libdemangle_handler_msvc(symbol);
76 }
77 
83  if (!dem) {
84  return NULL;
85  }
86 
87  RzList *plugins = rz_list_new();
88  if (!plugins) {
89  free(dem);
90  return NULL;
91  }
92 
93  for (ut32 i = 0; i < RZ_ARRAY_SIZE(demangler_static_plugins); ++i) {
95  rz_warn_if_fail(p->language);
96  rz_warn_if_fail(p->license);
97  rz_warn_if_fail(p->author);
98  rz_warn_if_fail(p->demangle);
99  if (!p->demangle || !rz_list_append(plugins, p)) {
100  const char *lang = p->language ? p->language : "";
101  RZ_LOG_WARN("rz_demangler: failed to add '%s' plugin at index %u", lang, i);
102  }
103  }
104 
105  dem->plugins = plugins;
106  return dem;
107 }
108 
113  if (!dem) {
114  return;
115  }
116  rz_list_free(dem->plugins);
117  free(dem);
118 }
119 
128  rz_return_if_fail(dem && dem->plugins && iter);
129  const RzDemanglerPlugin *plugin;
130  RzListIter *it;
131 
132  rz_list_foreach (dem->plugins, it, plugin) {
133  if (!iter(plugin, data)) {
134  break;
135  }
136  }
137 }
138 
145  rz_return_val_if_fail(dem && dem->plugins && plugin && plugin->language, false);
146  rz_warn_if_fail(plugin->author);
147  rz_warn_if_fail(plugin->license);
148 
149  const RzDemanglerPlugin *cp;
150  RzListIter *it = NULL;
151 
152  rz_list_foreach (dem->plugins, it, cp) {
153  if (!strcmp(cp->language, plugin->language)) {
154  // avoids to have duplicates
155  rz_list_delete(dem->plugins, it);
156  break;
157  }
158  }
159 
160  return rz_list_append(dem->plugins, plugin);
161 }
162 
169  rz_return_val_if_fail(RZ_STR_ISNOTEMPTY(language) && dem && dem->plugins, NULL);
170 
171  RzListIter *it;
172  const RzDemanglerPlugin *plugin;
173  rz_list_foreach (dem->plugins, it, plugin) {
174  if (!strcmp(language, plugin->language)) {
175  return plugin;
176  }
177  }
178 
179  return NULL;
180 }
181 
187 RZ_API bool rz_demangler_resolve(RZ_NONNULL RzDemangler *dem, RZ_NULLABLE const char *symbol, RZ_NONNULL const char *language, RZ_NONNULL RZ_OWN char **output) {
188  rz_return_val_if_fail(language && dem->plugins && output, false);
189 
190  if (RZ_STR_ISEMPTY(symbol)) {
191  *output = NULL;
192  return true;
193  }
194 
195  const RzDemanglerPlugin *plugin;
196  RzListIter *it;
197 
198  rz_list_foreach (dem->plugins, it, plugin) {
199  if (!strcmp(plugin->language, language)) {
200  *output = plugin->demangle(symbol);
201  return true;
202  }
203  }
204 
205  return false;
206 }
lzma_index ** i
Definition: index.h:629
#define RZ_DEMANGLER_STATIC_PLUGINS
Definition: config.h:28
#define RZ_API
#define NULL
Definition: cris-opc.c:27
uint32_t ut32
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
void * p
Definition: libc.cpp:67
RZ_API RZ_OWN char * rz_demangler_cxx(RZ_NONNULL const char *symbol)
Demangles c++ symbols.
Definition: demangler.c:45
RZ_API RZ_OWN char * rz_demangler_objc(RZ_NONNULL const char *symbol)
Demangles objc symbols.
Definition: demangler.c:56
RZ_API RZ_OWN RzDemangler * rz_demangler_new(void)
Initializes the plugin list and returns a RzDemangler struct.
Definition: demangler.c:81
RZ_API RZ_OWN char * rz_demangler_msvc(RZ_NONNULL const char *symbol)
Demangles microsft vc symbols.
Definition: demangler.c:74
RZ_API RZ_OWN char * rz_demangler_java(RZ_NULLABLE const char *symbol)
Demangles java symbols.
Definition: demangler.c:38
RZ_LIB_VERSION(rz_demangler)
RZ_API RZ_OWN char * rz_demangler_rust(RZ_NONNULL const char *symbol)
Demangles rust symbols.
Definition: demangler.c:63
RZ_API void rz_demangler_free(RZ_NULLABLE RzDemangler *dem)
Frees the RzDemangler struct.
Definition: demangler.c:112
RZ_API bool rz_demangler_plugin_add(RZ_NONNULL RzDemangler *dem, RZ_NONNULL RzDemanglerPlugin *plugin)
Adds a new demangler plugin to the plugin list.
Definition: demangler.c:144
RZ_API bool rz_demangler_resolve(RZ_NONNULL RzDemangler *dem, RZ_NULLABLE const char *symbol, RZ_NONNULL const char *language, RZ_NONNULL RZ_OWN char **output)
Resolves a symbol based on its language and return an output that needs to be freed.
Definition: demangler.c:187
#define DEFINE_DEMANGLER_PLUGIN(name, lang, lic, auth, handler)
Definition: demangler.c:10
RZ_API void rz_demangler_plugin_iterate(RZ_NONNULL RzDemangler *dem, RZ_NONNULL RzDemanglerIter iter, RZ_NULLABLE void *data)
Iterates over the plugin list.
Definition: demangler.c:127
RZ_API RZ_BORROW const RzDemanglerPlugin * rz_demangler_plugin_get(RZ_NONNULL RzDemangler *dem, RZ_NONNULL const char *language)
Returns a demangler plugin pointer based on the language that is found.
Definition: demangler.c:168
static RzDemanglerPlugin * demangler_static_plugins[]
Definition: demangler.c:31
RZ_API void rz_list_delete(RZ_NONNULL RzList *list, RZ_NONNULL RzListIter *iter)
Removes an entry in the list by using the RzListIter pointer.
Definition: list.c:162
RZ_API RZ_OWN RzList * rz_list_new(void)
Returns a new initialized RzList pointer (free method is not initialized)
Definition: list.c:235
RZ_API RZ_BORROW RzListIter * rz_list_append(RZ_NONNULL RzList *list, void *data)
Appends at the end of the list a new element.
Definition: list.c:288
RZ_API void rz_list_free(RZ_NONNULL RzList *list)
Empties the list and frees the list pointer.
Definition: list.c:137
char * libdemangle_handler_rust(const char *sym)
Definition: rust.c:25
#define rz_warn_if_fail(expr)
Definition: rz_assert.h:35
#define rz_return_if_fail(expr)
Definition: rz_assert.h:100
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
bool(* RzDemanglerIter)(const RzDemanglerPlugin *plugin, void *data)
Definition: rz_demangler.h:27
RZ_API char * libdemangle_handler_msvc(const char *symbol)
Definition: msvc.c:6
RZ_API char * libdemangle_handler_objc(const char *symbol)
Definition: objc.c:6
RZ_API char * libdemangle_handler_java(const char *symbol)
Demangles java classes/methods/fields.
Definition: java.c:260
#define RZ_LOG_WARN(fmtstr,...)
Definition: rz_log.h:56
#define RZ_STR_ISNOTEMPTY(x)
Definition: rz_str.h:68
#define RZ_STR_ISEMPTY(x)
Definition: rz_str.h:67
#define RZ_NULLABLE
Definition: rz_types.h:65
#define RZ_OWN
Definition: rz_types.h:62
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define RZ_NONNULL
Definition: rz_types.h:64
#define RZ_ARRAY_SIZE(x)
Definition: rz_types.h:300
#define RZ_BORROW
Definition: rz_types.h:63
const char * language
demangler language
Definition: rz_demangler.h:17
RZ_OWN char *(* demangle)(RZ_NONNULL const char *symbol)
demangler method to resolve the mangled symbol
Definition: rz_demangler.h:20
RzList * plugins
Definition: rz_demangler.h:24
char * libdemangle_handler_swift(const char *s)
Definition: swift.c:107
diff_output_t output
Definition: zipcmp.c:237