Make RBin demanglers pluggable and selectable ##bin

This commit is contained in:
pancake 2026-07-15 20:21:57 +02:00
parent c1e112507d
commit e769bfedce
60 changed files with 1041 additions and 129 deletions

View file

@ -171,7 +171,11 @@ generate_configmk () {
fi
done
fi
printf " p/${plg}.mk"
if [ "$lib" = "bin_demangle" ]; then
printf " p/${plg}_demangle.mk"
else
printf " p/${plg}.mk"
fi
done
echo
@ -184,7 +188,11 @@ generate_configmk () {
splugins="${splugins} __${uclib}"
printf "SHARED_${uclib}_TARGETS="
fi
printf " p/io_${plg}.${EXT}"
if [ "$lib" = "bin_demangle" ]; then
printf " p/bin_demangle_${plg}.${EXT}"
else
printf " p/io_${plg}.${EXT}"
fi
done
echo
}

View file

@ -1,4 +1,13 @@
STATIC="
bin_demangle.cxx
bin_demangle.dlang
bin_demangle.ibmxl
bin_demangle.java
bin_demangle.msvc
bin_demangle.objc
bin_demangle.pascal
bin_demangle.rust
bin_demangle.swift
anal.null
anal.autoname
arch.arm

View file

@ -1,4 +1,13 @@
STATIC="
bin_demangle.cxx
bin_demangle.dlang
bin_demangle.ibmxl
bin_demangle.java
bin_demangle.msvc
bin_demangle.objc
bin_demangle.pascal
bin_demangle.rust
bin_demangle.swift
arch.null
arch.i4004
bp.null

View file

@ -1,4 +1,13 @@
STATIC="
bin_demangle.cxx
bin_demangle.dlang
bin_demangle.ibmxl
bin_demangle.java
bin_demangle.msvc
bin_demangle.objc
bin_demangle.pascal
bin_demangle.rust
bin_demangle.swift
anal.null
anal.autoname
arch.6502

View file

@ -1,4 +1,13 @@
STATIC="
bin_demangle.cxx
bin_demangle.dlang
bin_demangle.ibmxl
bin_demangle.java
bin_demangle.msvc
bin_demangle.objc
bin_demangle.pascal
bin_demangle.rust
bin_demangle.swift
anal.null
anal.autoname
arch.6502

View file

@ -1,4 +1,13 @@
STATIC="
bin_demangle.cxx
bin_demangle.dlang
bin_demangle.ibmxl
bin_demangle.java
bin_demangle.msvc
bin_demangle.objc
bin_demangle.pascal
bin_demangle.rust
bin_demangle.swift
anal.null
anal.autoname
anal.callargs

View file

@ -1,4 +1,13 @@
STATIC="
bin_demangle.cxx
bin_demangle.dlang
bin_demangle.ibmxl
bin_demangle.java
bin_demangle.msvc
bin_demangle.objc
bin_demangle.pascal
bin_demangle.rust
bin_demangle.swift
anal.null
anal.autoname
arch.x86_cs

View file

@ -1,4 +1,13 @@
STATIC="
bin_demangle.cxx
bin_demangle.dlang
bin_demangle.ibmxl
bin_demangle.java
bin_demangle.msvc
bin_demangle.objc
bin_demangle.pascal
bin_demangle.rust
bin_demangle.swift
anal.null
anal.autoname
arch.x86_cs

View file

@ -1,4 +1,13 @@
STATIC="
bin_demangle.cxx
bin_demangle.dlang
bin_demangle.ibmxl
bin_demangle.java
bin_demangle.msvc
bin_demangle.objc
bin_demangle.pascal
bin_demangle.rust
bin_demangle.swift
anal.null
anal.autoname
arch.arm

View file

@ -1,4 +1,13 @@
STATIC="
bin_demangle.cxx
bin_demangle.dlang
bin_demangle.ibmxl
bin_demangle.java
bin_demangle.msvc
bin_demangle.objc
bin_demangle.pascal
bin_demangle.rust
bin_demangle.swift
anal.null
anal.autoname
arch.6502

View file

@ -1,4 +1,13 @@
STATIC="
bin_demangle.cxx
bin_demangle.dlang
bin_demangle.ibmxl
bin_demangle.java
bin_demangle.msvc
bin_demangle.objc
bin_demangle.pascal
bin_demangle.rust
bin_demangle.swift
arch.8051
anal.null
anal.autoname

View file

@ -1,4 +1,13 @@
STATIC="arch.8051
STATIC="bin_demangle.cxx
bin_demangle.dlang
bin_demangle.ibmxl
bin_demangle.java
bin_demangle.msvc
bin_demangle.objc
bin_demangle.pascal
bin_demangle.rust
bin_demangle.swift
arch.8051
anal.null
anal.autoname
arch.x86_cs

View file

@ -1,4 +1,13 @@
STATIC="
bin_demangle.cxx
bin_demangle.dlang
bin_demangle.ibmxl
bin_demangle.java
bin_demangle.msvc
bin_demangle.objc
bin_demangle.pascal
bin_demangle.rust
bin_demangle.swift
anal.null
anal.autoname
anal.callargs

View file

@ -1,6 +1,15 @@
# same as default, but removing some plugins to avoid dupped symbols (use diff)
# this file should be removed as soon as those 2 plugins get built properly
STATIC="arch.8051
STATIC="bin_demangle.cxx
bin_demangle.dlang
bin_demangle.ibmxl
bin_demangle.java
bin_demangle.msvc
bin_demangle.objc
bin_demangle.pascal
bin_demangle.rust
bin_demangle.swift
arch.8051
anal.null
anal.autoname
anal.drcov

View file

@ -1,4 +1,13 @@
STATIC="arch.8051
STATIC="bin_demangle.cxx
bin_demangle.dlang
bin_demangle.ibmxl
bin_demangle.java
bin_demangle.msvc
bin_demangle.objc
bin_demangle.pascal
bin_demangle.rust
bin_demangle.swift
arch.8051
anal.null
anal.autoname
arch.6502

View file

@ -1,4 +1,13 @@
STATIC="arch.8051
STATIC="bin_demangle.cxx
bin_demangle.dlang
bin_demangle.ibmxl
bin_demangle.java
bin_demangle.msvc
bin_demangle.objc
bin_demangle.pascal
bin_demangle.rust
bin_demangle.swift
arch.8051
anal.null
anal.autoname
arch.6502

View file

@ -1,4 +1,13 @@
STATIC="
bin_demangle.cxx
bin_demangle.dlang
bin_demangle.ibmxl
bin_demangle.java
bin_demangle.msvc
bin_demangle.objc
bin_demangle.pascal
bin_demangle.rust
bin_demangle.swift
anal.null
anal.autoname
arch.arm

View file

@ -1,4 +1,13 @@
STATIC="
bin_demangle.cxx
bin_demangle.dlang
bin_demangle.ibmxl
bin_demangle.java
bin_demangle.msvc
bin_demangle.objc
bin_demangle.pascal
bin_demangle.rust
bin_demangle.swift
anal.null
anal.autoname
anal.callargs

View file

@ -1,4 +1,13 @@
STATIC="
bin_demangle.cxx
bin_demangle.dlang
bin_demangle.ibmxl
bin_demangle.java
bin_demangle.msvc
bin_demangle.objc
bin_demangle.pascal
bin_demangle.rust
bin_demangle.swift
anal.null
anal.autoname
arch.null

View file

@ -1,4 +1,13 @@
STATIC="
bin_demangle.cxx
bin_demangle.dlang
bin_demangle.ibmxl
bin_demangle.java
bin_demangle.msvc
bin_demangle.objc
bin_demangle.pascal
bin_demangle.rust
bin_demangle.swift
anal.null
anal.autoname
arch.6502

View file

@ -16,28 +16,15 @@ CFLAGS+=-DR2_PLUGIN_INCORE -Iformat -Imangling
include ${STATIC_BIN_PLUGINS}
include ${STATIC_BIN_XTR_PLUGINS}
include ${STATIC_BIN_LDR_PLUGINS}
include ${STATIC_BIN_DEMANGLE_PLUGINS}
include $(SHLR)/java/deps.mk
include $(LIBR)/magic/deps.mk
STATIC_OBJS=$(addprefix $(LTOP)/bin/p/, $(STATIC_OBJ))
OBJS=bin.o addrline.o bin_ldr.o bin_write.o demangle.o
STATIC_OBJS=$(sort $(addprefix $(LTOP)/bin/p/, $(STATIC_OBJ)))
OBJS=bin.o addrline.o bin_ldr.o bin_write.o demangle.o demangle_stubs.o
OBJS+=dwarf.o bfilter.o bfile.o bobj.o blang.o
OBJS+=${STATIC_OBJS}
ifeq (1,$(WITH_GPL))
OBJS+=mangling/cxx/cp-demangle.o
endif
OBJS+=mangling/cxx2/cxx2.o mangling/cxx2/itanium.o
OBJS+=mangling/cxx2/rust.o mangling/cxx2/dlang.o
OBJS+=mangling/cxx2/xlc.o
OBJS+=mangling/cxx2/gnu-v2.o
OBJS+=mangling/cxx2/armabi.o
OBJS+=mangling/demangler.o
OBJS+=mangling/microsoft.o
OBJS+=mangling/objc.o mangling/cxx.o mangling/msvc.o
OBJS+=mangling/swift.o mangling/swift-sd.o
OBJS+=mangling/java.o
OBJS+=mangling/pascal.o
OBJS+=mangling/rust.o
OBJS+=mangling/swift.o
OBJS+=$(EXTERNAL_STATIC_OBJS)
include $(TOP)/libr/bin/format/pdb/deps.mk

View file

@ -22,10 +22,14 @@ R_LIB_VERSION(r_bin);
#if !defined(R_BIN_LDR_STATIC_PLUGINS)
#define R_BIN_LDR_STATIC_PLUGINS 0
#endif
#if !defined(R_BIN_DEMANGLE_STATIC_PLUGINS)
#define R_BIN_DEMANGLE_STATIC_PLUGINS 0
#endif
static RBinPlugin *bin_static_plugins[] = { R_BIN_STATIC_PLUGINS, NULL };
static RBinXtrPlugin *bin_xtr_static_plugins[] = { R_BIN_XTR_STATIC_PLUGINS, NULL };
static RBinLdrPlugin *bin_ldr_static_plugins[] = { R_BIN_LDR_STATIC_PLUGINS, NULL };
static RBinDemanglePlugin *bin_demangle_static_plugins[] = { R_BIN_DEMANGLE_STATIC_PLUGINS, NULL };
static void bin_plugin_fini(void *user, void *plugin) {
RBinPlugin *plug = plugin;
@ -42,6 +46,7 @@ static bool bin_load_plugins(RLibStore *store) {
r_lib_add_static (bin, bin_static_plugins, (RLibPluginAddCb)r_bin_plugin_add);
r_lib_add_static (bin, bin_xtr_static_plugins, (RLibPluginAddCb)r_bin_xtr_add);
r_lib_add_static (bin, bin_ldr_static_plugins, (RLibPluginAddCb)r_bin_ldr_add);
r_lib_add_static (bin, bin_demangle_static_plugins, (RLibPluginAddCb)r_bin_demangle_plugin_add);
return true;
}
@ -593,6 +598,114 @@ R_API bool r_bin_plugin_remove(RBin *bin, RBinPlugin *plugin) {
return false;
}
static int demangle_type_index(RBinLanguage type) {
ut32 value = (ut32)type & 0xffff;
if (!value || (value & (value - 1))) {
return -1;
}
int index = r_bits_ctz32 (value);
return index < R_BIN_DEMANGLE_TYPE_SLOTS? index: -1;
}
static void demangle_names_remove(RBin *bin, RBinDemanglePlugin *plugin) {
ht_pp_delete (bin->demangle_by_name, plugin->meta.name);
if (R_STR_ISEMPTY (plugin->aliases)) {
return;
}
char *aliases = strdup (plugin->aliases);
RList *list = r_str_split_list (aliases, ",", 0);
RListIter *iter;
const char *alias;
r_list_foreach (list, iter, alias) {
if (R_STR_ISNOTEMPTY (alias)) {
ht_pp_delete (bin->demangle_by_name, alias);
}
}
r_list_free (list);
free (aliases);
}
R_API RBinDemanglePlugin *r_bin_demangle_plugin_find(RBin *bin, const char *name) {
R_RETURN_VAL_IF_FAIL (bin && name, NULL);
return ht_pp_find (bin->demangle_by_name, name, NULL);
}
R_API bool r_bin_demangle_plugin_add(RBin *bin, RBinDemanglePlugin *plugin) {
R_RETURN_VAL_IF_FAIL (bin && plugin && plugin->meta.name && plugin->demangle, false);
int type_index = demangle_type_index (plugin->type);
if (plugin->type != R_BIN_LANG_NONE && type_index < 0) {
R_LOG_WARN ("Invalid demangler language type for '%s'", plugin->meta.name);
return false;
}
if (r_bin_demangle_plugin_find (bin, plugin->meta.name)
|| (type_index >= 0 && bin->demangle_by_type[type_index])) {
R_LOG_WARN ("Demangler plugin '%s' is already registered", plugin->meta.name);
return false;
}
HtPP *seen = ht_pp_new0 ();
ht_pp_insert (seen, plugin->meta.name, plugin);
char *aliases = R_STR_ISNOTEMPTY (plugin->aliases)? strdup (plugin->aliases): NULL;
RList *list = aliases? r_str_split_list (aliases, ",", 0): NULL;
RListIter *iter;
const char *alias;
r_list_foreach (list, iter, alias) {
if (R_STR_ISEMPTY (alias) || ht_pp_find (seen, alias, NULL)
|| r_bin_demangle_plugin_find (bin, alias)) {
R_LOG_WARN ("Duplicate demangler alias '%s'", r_str_get (alias));
ht_pp_free (seen);
r_list_free (list);
free (aliases);
return false;
}
ht_pp_insert (seen, alias, plugin);
}
ht_pp_free (seen);
RBinDemanglePlugin *copy = R_NEW0 (RBinDemanglePlugin);
*copy = *plugin;
if (!ht_pp_insert (bin->demangle_by_name, copy->meta.name, copy)) {
r_list_free (list);
free (aliases);
free (copy);
return false;
}
r_list_foreach (list, iter, alias) {
if (!ht_pp_insert (bin->demangle_by_name, alias, copy)) {
demangle_names_remove (bin, copy);
r_list_free (list);
free (aliases);
free (copy);
return false;
}
}
if (!r_list_append (bin->demangle_plugins, copy)) {
demangle_names_remove (bin, copy);
r_list_free (list);
free (aliases);
free (copy);
return false;
}
if (type_index >= 0) {
bin->demangle_by_type[type_index] = copy;
}
r_list_free (list);
free (aliases);
return true;
}
R_API bool r_bin_demangle_plugin_remove(RBin *bin, RBinDemanglePlugin *plugin) {
R_RETURN_VAL_IF_FAIL (bin && plugin && plugin->meta.name, false);
RBinDemanglePlugin *registered = r_bin_demangle_plugin_find (bin, plugin->meta.name);
if (!registered || strcmp (registered->meta.name, plugin->meta.name)) {
return false;
}
int type_index = demangle_type_index (registered->type);
if (type_index >= 0 && bin->demangle_by_type[type_index] == registered) {
bin->demangle_by_type[type_index] = NULL;
}
demangle_names_remove (bin, registered);
return r_list_delete_data (bin->demangle_plugins, registered);
}
R_API bool r_bin_ldr_add(RBin *bin, RBinLdrPlugin *foo) {
R_RETURN_VAL_IF_FAIL (bin && foo, false);
RList *ldrs = bin->libstore->ldrs;
@ -636,6 +749,8 @@ R_API void r_bin_free(RBin *bin) {
}
RVecBinSymclassGlob_fini (&bin->symclass_globs);
r_libstore_free (bin->libstore);
r_list_free (bin->demangle_plugins);
ht_pp_free (bin->demangle_by_name);
sdb_free (bin->sdb);
r_id_storage_free (bin->ids);
r_str_constpool_fini (&bin->constpool);
@ -1216,6 +1331,8 @@ R_API RBin *r_bin_new(void) {
bin->ids = r_id_storage_new (0, ST32_MAX);
bin->binfiles = r_list_newf ((RListFree)r_bin_file_free);
bin->demangle_plugins = r_list_newf ((RListFree)free);
bin->demangle_by_name = ht_pp_new0 ();
r_libstore_new (&bin->libstore, bin, NULL, (RListFree)free, bin_load_plugins, (RLibPluginAddCb)r_bin_plugin_add, (RLibPluginAddCb)r_bin_plugin_remove);
return bin;
}

View file

@ -2,8 +2,6 @@
#include <r_bin.h>
#include "i/private.h"
#include <cxx/demangle.h>
#include "mangling/cxx2/cxx2.h"
static char *demangle_trunc(RBinFile *bf, char *s) {
RBin *bin = bf? bf->rbin: NULL;
@ -27,46 +25,17 @@ static char *demangle_trunc(RBinFile *bf, char *s) {
}
R_API void r_bin_demangle_list(RBin *bin) {
const char *langs[] = {
"c++",
"dart",
"dlang",
"groovy",
"ibmxl",
"java",
"msvc",
"objc",
"pascal",
"rust",
"swift",
NULL
};
RBinPlugin *plugin;
RListIter *it;
int i;
if (!bin) {
return;
}
for (i = 0; langs[i]; i++) {
bin->cb_printf ("%s\n", langs[i]);
}
RList *plugins = bin->libstore->plugins;
r_list_foreach (plugins, it, plugin) {
if (plugin->demangle) {
bin->cb_printf ("%s\n", plugin->meta.name);
}
RBinDemanglePlugin *plugin;
RListIter *iter;
r_list_foreach (bin->demangle_plugins, iter, plugin) {
bin->cb_printf ("%s\n", plugin->meta.name);
}
}
R_API char *r_bin_demangle_dlang(const char *str) {
return r_demangle_dlang (str);
}
R_API char *r_bin_demangle_ibmxl(const char *str) {
return r_demangle_ibmxl (str);
}
R_API char *r_bin_demangle_plugin(RBin *bin, const char *name, const char *str) {
static char *demangle_legacy_plugin(RBin *bin, const char *name, const char *str) {
RBinPlugin *plugin;
RListIter *it;
if (bin && name && str) {
@ -80,6 +49,24 @@ R_API char *r_bin_demangle_plugin(RBin *bin, const char *name, const char *str)
return NULL;
}
R_API char *r_bin_demangle_plugin(RBin *bin, const char *name, const char *str) {
R_RETURN_VAL_IF_FAIL (bin && name && str, NULL);
RBinDemanglePlugin *plugin = r_bin_demangle_plugin_find (bin, name);
if (plugin) {
RBinFile *bf = bin->cur;
RBinFile tmp = { 0 };
if (!bf && plugin->type == R_BIN_LANG_SWIFT) {
tmp.rbin = bin;
bf = &tmp;
}
char *res = plugin->demangle (bf, str, 0);
if (res) {
return res;
}
}
return demangle_legacy_plugin (bin, name, str);
}
R_API int r_bin_demangle_type(const char *str) {
if (R_STR_ISNOTEMPTY (str)) {
if (!strcmp (str, "swift")) {
@ -125,13 +112,36 @@ R_API int r_bin_demangle_type(const char *str) {
return R_BIN_LANG_NONE;
}
static RBinDemanglePlugin *demangle_plugin_by_type(RBin *bin, int type) {
ut32 value = (ut32)type & 0xffff;
if (!bin || !value || (value & (value - 1))) {
return NULL;
}
int index = r_bits_ctz32 (value);
return index < R_BIN_DEMANGLE_TYPE_SLOTS? bin->demangle_by_type[index]: NULL;
}
static char *demangle_without_bin(RBinFile *bf, int type, const char *str, ut64 vaddr) {
switch (type & 0xffff) {
case R_BIN_LANG_JAVA: return r_bin_demangle_java (str);
case R_BIN_LANG_RUST: return r_bin_demangle_rust (bf, str, vaddr);
case R_BIN_LANG_OBJC: return r_bin_demangle_objc (NULL, str);
case R_BIN_LANG_SWIFT: return r_bin_demangle_swift (str, false, true);
case R_BIN_LANG_CXX: return r_bin_demangle_cxx (bf, str, vaddr);
case R_BIN_LANG_IBMXL: return r_bin_demangle_ibmxl (str);
case R_BIN_LANG_PASCAL: return r_bin_demangle_freepascal (str);
case R_BIN_LANG_MSVC: return r_bin_demangle_msvc (str);
case R_BIN_LANG_DLANG: return r_bin_demangle_dlang (str);
}
return NULL;
}
R_API char *r_bin_demangle(RBinFile *bf, const char *def, const char *str, ut64 vaddr, bool libs) {
int type = -1;
if (R_STR_ISEMPTY (str)) {
return NULL;
}
RBin *bin = bf? bf->rbin: NULL;
bool trylib = bin? bin->options.demangle_trylib: true;
RBinObject *o = bf? bf->bo: NULL;
RListIter *iter;
const char *lib = NULL;
@ -195,23 +205,20 @@ R_API char *r_bin_demangle(RBinFile *bf, const char *def, const char *str, ut64
if (type == -1) {
type = r_bin_lang_type (bf, def, str);
}
// type = R_BIN_LANG_SWIFT;
char *demangled = NULL;
switch (type) {
case R_BIN_LANG_JAVA: demangled = r_bin_demangle_java (str); break;
case R_BIN_LANG_RUST: demangled = r_bin_demangle_rust (bf, str, vaddr); break;
case R_BIN_LANG_OBJC: demangled = r_bin_demangle_objc (NULL, str); break;
case R_BIN_LANG_SWIFT: demangled = r_bin_demangle_swift (str, bin? bin->options.demangle_usecmd: false, trylib); break;
case R_BIN_LANG_CXX: demangled = r_bin_demangle_cxx (bf, str, vaddr); break;
case R_BIN_LANG_IBMXL: demangled = r_bin_demangle_ibmxl (str); break;
case R_BIN_LANG_PASCAL: demangled = r_bin_demangle_freepascal (str); break;
case R_BIN_LANG_MSVC: demangled = r_bin_demangle_msvc (str); break;
case R_BIN_LANG_DLANG:
demangled = r_demangle_dlang (str);
if (!demangled) {
demangled = r_bin_demangle_plugin (bin, "dlang", str);
if (bin) {
RBinDemanglePlugin *plugin = demangle_plugin_by_type (bin, type);
if (!plugin && R_STR_ISNOTEMPTY (def)) {
plugin = r_bin_demangle_plugin_find (bin, def);
}
break;
if (plugin) {
demangled = plugin->demangle (bf, str, vaddr);
}
if (!demangled && type == R_BIN_LANG_DLANG) {
demangled = demangle_legacy_plugin (bin, "dlang", str);
}
} else {
demangled = demangle_without_bin (bf, type, str, vaddr);
}
if (libs && demangled && lib) {
char *d = r_str_newf ("%s_%s", lib, demangled);

73
libr/bin/demangle_stubs.c Normal file
View file

@ -0,0 +1,73 @@
/* radare - LGPL - Copyright 2026 - pancake */
#include <r_bin.h>
#ifndef R_BIN_DEMANGLE_JAVA
R_API char *r_bin_demangle_java(const char *str) {
(void)str;
return NULL;
}
#endif
#ifndef R_BIN_DEMANGLE_PASCAL
R_API char *r_bin_demangle_freepascal(const char *str) {
(void)str;
return NULL;
}
#endif
#ifndef R_BIN_DEMANGLE_CXX
R_API char *r_bin_demangle_cxx(RBinFile *bf, const char *str, ut64 vaddr) {
(void)bf;
(void)str;
(void)vaddr;
return NULL;
}
#endif
#ifndef R_BIN_DEMANGLE_MSVC
R_API char *r_bin_demangle_msvc(const char *str) {
(void)str;
return NULL;
}
#endif
#ifndef R_BIN_DEMANGLE_SWIFT
R_API char *r_bin_demangle_swift(const char *str, bool syscmd, bool trylib) {
(void)str;
(void)syscmd;
(void)trylib;
return NULL;
}
#endif
#ifndef R_BIN_DEMANGLE_OBJC
R_API char *r_bin_demangle_objc(RBinFile *bf, const char *str) {
(void)bf;
(void)str;
return NULL;
}
#endif
#ifndef R_BIN_DEMANGLE_RUST
R_API char *r_bin_demangle_rust(RBinFile *bf, const char *str, ut64 vaddr) {
(void)bf;
(void)str;
(void)vaddr;
return NULL;
}
#endif
#ifndef R_BIN_DEMANGLE_DLANG
R_API char *r_bin_demangle_dlang(const char *str) {
(void)str;
return NULL;
}
#endif
#ifndef R_BIN_DEMANGLE_IBMXL
R_API char *r_bin_demangle_ibmxl(const char *str) {
(void)str;
return NULL;
}
#endif

View file

@ -1073,10 +1073,14 @@ static void get_protocol_list_of_lists(RBinFile *bf, RBinClass *klass, objc_cach
iterate_list_of_lists (bf, on_protocol_list, &ctx, p);
}
static char *demangle_classname(RBin *rbin, const char *s) {
static char *demangle_swift(RBinFile *bf, const char *s) {
return r_bin_demangle (bf, "swift", s, 0, false);
}
static char *demangle_classname(RBinFile *bf, const char *s) {
char *ret;
if (r_str_startswith (s, "_TtC")) {
ret = r_bin_demangle_swift (s, rbin->options.demangle_usecmd, rbin->options.demangle_trylib);
ret = demangle_swift (bf, s);
} else {
ret = strdup (s);
}
@ -1262,7 +1266,7 @@ static void get_class_ro_t(RBinFile *bf, bool *is_meta_class, RBinClass *klass,
}
r_bin_name_free (klass->name);
klass->name = r_bin_name_new (name);
char *dn = demangle_classname (bf->rbin, name);
char *dn = demangle_classname (bf, name);
if (dn) {
r_bin_name_demangled (klass->name, dn);
free (dn);
@ -1325,9 +1329,6 @@ static mach0_ut get_isa_value(void) {
void MACH0_(get_class_t)(RBinFile *bf, RBinClass *klass, mach0_ut p, bool dupe, const RSkipList *relocs, objc_cache_opt_info *oi) {
R_RETURN_IF_FAIL (bf && bf->bo && bf->bo->info);
RBin *bin = bf->rbin;
bool trylib = bin? bin->options.demangle_trylib: false;
bool usecmd = bin? bin->options.demangle_usecmd: false;
struct MACH0_(SClass) c = {0};
const int size = sizeof (struct MACH0_(SClass));
ut32 offset = 0, left = 0;
@ -1380,7 +1381,7 @@ void MACH0_(get_class_t)(RBinFile *bf, RBinClass *klass, mach0_ut p, bool dupe,
klass->super = r_list_newf ((void *)r_bin_name_free);
}
RBinName *bn = r_bin_name_new (klass_name);
char *dn = demangle_classname (bf->rbin, klass_name);
char *dn = demangle_classname (bf, klass_name);
#if 0
// avoid registering when demangled baseklass == demangled superklass
const char *base_klass_name = r_bin_name_tostring2 (klass->name, 'd');
@ -1410,7 +1411,7 @@ void MACH0_(get_class_t)(RBinFile *bf, RBinClass *klass, mach0_ut p, bool dupe,
target_class_name += _objc_class_len;
r_bin_name_demangled (sup, target_class_name);
if (r_str_startswith (target_class_name, "_T")) {
char *dsuper = r_bin_demangle_swift (target_class_name, usecmd, trylib);
char *dsuper = demangle_swift (bf, target_class_name);
if (dsuper && strcmp (dsuper, target_class_name)) {
r_bin_name_demangled (sup, dsuper);
}
@ -1543,9 +1544,6 @@ static void parse_type(RBinFile *bf, RList *list, SwiftType st, HtUP *symbols_ht
free (otypename);
return;
}
RBin *bin = bf->rbin;
bool trylib = bin? bin->options.demangle_trylib: false;
bool usecmd = bin? bin->options.demangle_usecmd: false;
char *typename = r_name_filter_dup (otypename);
RBinClass *klass = r_bin_class_new (typename, NULL, false);
klass->origin = R_BIN_CLASS_ORIGIN_BIN;
@ -1554,7 +1552,7 @@ static void parse_type(RBinFile *bf, RList *list, SwiftType st, HtUP *symbols_ht
if ((st8)*super_name > 5) {
klass->super = r_list_newf ((void *)r_bin_name_free);
RBinName *bn = r_bin_name_new (super_name);
char *sname = r_bin_demangle_swift (super_name, usecmd, trylib);
char *sname = demangle_swift (bf, super_name);
if (R_STR_ISNOTEMPTY (sname)) {
r_bin_name_demangled (bn, sname);
}
@ -1605,7 +1603,7 @@ static void parse_type(RBinFile *bf, RList *list, SwiftType st, HtUP *symbols_ht
rawname = strdup (r_bin_name_tostring (sym->name));
method_name = r_name_filter_dup (rawname); // r_bin_name_tostring (sym->name));
r_bin_name_filtered (sym->name, method_name);
char *dname = r_bin_demangle_swift (method_name, usecmd, trylib);
char *dname = demangle_swift (bf, method_name);
if (dname) {
r_bin_name_demangled (sym->name, dname);
free (sym->name->oname);
@ -1690,7 +1688,7 @@ static void parse_type(RBinFile *bf, RList *list, SwiftType st, HtUP *symbols_ht
ftype += r_str_nlen (ftype, 6);
}
field->type = r_bin_name_new (ftype);
char *demangled_type = r_bin_demangle_swift (ftype, usecmd, trylib);
char *demangled_type = demangle_swift (bf, ftype);
if (demangled_type) {
r_bin_name_demangled (field->type, demangled_type);
free (demangled_type);
@ -2052,7 +2050,7 @@ void MACH0_(get_category_t)(RBinFile *bf, RBinClass *klass, mach0_ut p, const RS
if (target_class_name) {
char *kname = r_str_newf ("%s(%s)", target_class_name, category_name);
klass->name = r_bin_name_new (kname);
char *demangled = demangle_classname (bf->rbin, target_class_name);
char *demangled = demangle_classname (bf, target_class_name);
if (demangled) {
char *dname = r_str_newf ("%s(%s)", demangled, category_name);
r_bin_name_demangled (klass->name, dname);

View file

@ -0,0 +1,8 @@
/* radare - LGPL - Copyright 2026 - pancake */
#include <r_bin.h>
#include "cxx2/cxx2.h"
R_API char *r_bin_demangle_dlang(const char *str) {
return r_demangle_dlang (str);
}

View file

@ -0,0 +1,8 @@
/* radare - LGPL - Copyright 2026 - pancake */
#include <r_bin.h>
#include "cxx2/cxx2.h"
R_API char *r_bin_demangle_ibmxl(const char *str) {
return r_demangle_ibmxl (str);
}

View file

@ -5,6 +5,7 @@ r_bin_sources = [
'bin_write.c',
'addrline.c',
'demangle.c',
'demangle_stubs.c',
'dwarf.c',
'blang.c',
'bfilter.c',
@ -132,30 +133,64 @@ r_bin_sources = [
'format/pdb/stream_file.c',
'format/pdb/stream_pe.c',
'format/pdb/tpi.c',
# symbol name manglers
'mangling/cxx.c',
'mangling/cxx2/cxx2.c',
'mangling/cxx2/itanium.c',
'mangling/cxx2/rust.c',
'mangling/cxx2/dlang.c',
'mangling/cxx2/xlc.c',
'mangling/cxx2/gnu-v2.c',
'mangling/cxx2/armabi.c',
'mangling/pascal.c',
'mangling/demangler.c',
'mangling/rust.c',
'mangling/java.c',
'mangling/microsoft.c',
'mangling/msvc.c',
'mangling/objc.c',
'mangling/swift-sd.c',
# language detection
'mangling/swift.c'
]
if not get_option('nogpl')
demangle_c_args = []
need_cxx_demangler = bin_demangle_plugins.contains('cxx') or bin_demangle_plugins.contains('rust')
if need_cxx_demangler
demangle_c_args += ['-DR_BIN_DEMANGLE_CXX=1']
r_bin_sources += [
'mangling/cxx/cp-demangle.c',
'mangling/cxx.c',
'mangling/cxx2/itanium.c',
'mangling/cxx2/xlc.c',
'mangling/cxx2/gnu-v2.c',
'mangling/cxx2/armabi.c',
]
if not get_option('nogpl')
r_bin_sources += ['mangling/cxx/cp-demangle.c']
endif
endif
if bin_demangle_plugins.contains('cxx')
r_bin_sources += ['p/bin_demangle_cxx.c']
endif
if bin_demangle_plugins.contains('dlang')
demangle_c_args += ['-DR_BIN_DEMANGLE_DLANG=1']
r_bin_sources += ['p/bin_demangle_dlang.c', 'mangling/dlang.c', 'mangling/cxx2/dlang.c']
endif
if bin_demangle_plugins.contains('ibmxl')
demangle_c_args += ['-DR_BIN_DEMANGLE_IBMXL=1']
r_bin_sources += ['p/bin_demangle_ibmxl.c', 'mangling/ibmxl.c']
if not need_cxx_demangler
r_bin_sources += ['mangling/cxx2/xlc.c']
endif
endif
if bin_demangle_plugins.contains('java')
demangle_c_args += ['-DR_BIN_DEMANGLE_JAVA=1']
r_bin_sources += ['p/bin_demangle_java.c', 'mangling/java.c']
endif
if bin_demangle_plugins.contains('msvc')
demangle_c_args += ['-DR_BIN_DEMANGLE_MSVC=1']
r_bin_sources += ['p/bin_demangle_msvc.c', 'mangling/msvc.c', 'mangling/microsoft.c', 'mangling/demangler.c']
endif
if bin_demangle_plugins.contains('objc')
demangle_c_args += ['-DR_BIN_DEMANGLE_OBJC=1']
r_bin_sources += ['p/bin_demangle_objc.c', 'mangling/objc.c']
endif
if bin_demangle_plugins.contains('pascal')
demangle_c_args += ['-DR_BIN_DEMANGLE_PASCAL=1']
r_bin_sources += ['p/bin_demangle_pascal.c', 'mangling/pascal.c']
endif
if bin_demangle_plugins.contains('rust')
demangle_c_args += ['-DR_BIN_DEMANGLE_RUST=1']
r_bin_sources += ['p/bin_demangle_rust.c', 'mangling/rust.c', 'mangling/cxx2/rust.c']
endif
if bin_demangle_plugins.contains('swift')
demangle_c_args += ['-DR_BIN_DEMANGLE_SWIFT=1']
r_bin_sources += ['p/bin_demangle_swift.c', 'mangling/swift-sd.c']
endif
if bin_plugins.contains('pyc') or bin_plugins.contains('pickle')
@ -177,7 +212,7 @@ endif
r_bin = library('r_bin', r_bin_sources,
include_directories: r_bin_inc,
c_args: ['-DR_API_BIN_ONLY=1'] + library_cflags,
c_args: ['-DR_API_BIN_ONLY=1'] + demangle_c_args + library_cflags,
dependencies: [
r_util_dep,
r_cons_dep,
@ -202,7 +237,7 @@ r_bin_dep = declare_dependency(link_with: r_bin,
if get_option('blob')
r_bin_static = static_library('r_bin_static', r_bin_sources,
include_directories: r_bin_inc,
c_args: ['-DR_API_BIN_ONLY=1'] + library_cflags,
c_args: ['-DR_API_BIN_ONLY=1'] + demangle_c_args + library_cflags,
dependencies: [
r_util_static_dep,
r_cons_static_dep,

View file

@ -26,7 +26,11 @@ FORMATS+=mdmp.mk z64.mk qnx.mk prg.mk dmp64.mk xtac.mk pef.mk mdt.mk som.mk
FORMATS+=xtr_dyldcache.mk xtr_ftab.mk
include $(FORMATS)
DEMANGLERS=cxx_demangle.mk dlang_demangle.mk ibmxl_demangle.mk
DEMANGLERS+=java_demangle.mk msvc_demangle.mk objc_demangle.mk
DEMANGLERS+=pascal_demangle.mk rust_demangle.mk swift_demangle.mk
include $(FORMATS) $(DEMANGLERS)
clean:
-rm -f *.so *.o ${STATIC_OBJ}

View file

@ -0,0 +1,22 @@
/* radare - LGPL - Copyright 2026 - pancake */
#include <r_bin.h>
RBinDemanglePlugin r_bin_demangle_plugin_cxx = {
.meta = {
.name = "c++",
.desc = "C++ demangler",
.license = "LGPL-3.0-only",
},
.type = R_BIN_LANG_CXX,
.aliases = "cxx",
.demangle = r_bin_demangle_cxx,
};
#ifndef R2_PLUGIN_INCORE
R_API RLibStruct radare_plugin = {
.type = R_LIB_TYPE_BIN_DEMANGLE,
.data = &r_bin_demangle_plugin_cxx,
.version = R2_VERSION,
};
#endif

View file

@ -0,0 +1,28 @@
/* radare - LGPL - Copyright 2026 - pancake */
#include <r_bin.h>
static char *demangle(RBinFile *bf, const char *symbol, ut64 vaddr) {
(void)bf;
(void)vaddr;
return r_bin_demangle_dlang (symbol);
}
RBinDemanglePlugin r_bin_demangle_plugin_dlang = {
.meta = {
.name = "dlang",
.desc = "D language demangler",
.license = "LGPL-3.0-only",
},
.type = R_BIN_LANG_DLANG,
.aliases = "d",
.demangle = demangle,
};
#ifndef R2_PLUGIN_INCORE
R_API RLibStruct radare_plugin = {
.type = R_LIB_TYPE_BIN_DEMANGLE,
.data = &r_bin_demangle_plugin_dlang,
.version = R2_VERSION,
};
#endif

View file

@ -0,0 +1,28 @@
/* radare - LGPL - Copyright 2026 - pancake */
#include <r_bin.h>
static char *demangle(RBinFile *bf, const char *symbol, ut64 vaddr) {
(void)bf;
(void)vaddr;
return r_bin_demangle_ibmxl (symbol);
}
RBinDemanglePlugin r_bin_demangle_plugin_ibmxl = {
.meta = {
.name = "ibmxl",
.desc = "IBM XL C++ demangler",
.license = "LGPL-3.0-only",
},
.type = R_BIN_LANG_IBMXL,
.aliases = "xlc,xlc++",
.demangle = demangle,
};
#ifndef R2_PLUGIN_INCORE
R_API RLibStruct radare_plugin = {
.type = R_LIB_TYPE_BIN_DEMANGLE,
.data = &r_bin_demangle_plugin_ibmxl,
.version = R2_VERSION,
};
#endif

View file

@ -0,0 +1,27 @@
/* radare - LGPL - Copyright 2026 - pancake */
#include <r_bin.h>
static char *demangle(RBinFile *bf, const char *symbol, ut64 vaddr) {
(void)bf;
(void)vaddr;
return r_bin_demangle_java (symbol);
}
RBinDemanglePlugin r_bin_demangle_plugin_java = {
.meta = {
.name = "java",
.desc = "Java demangler",
.license = "LGPL-3.0-only",
},
.type = R_BIN_LANG_JAVA,
.demangle = demangle,
};
#ifndef R2_PLUGIN_INCORE
R_API RLibStruct radare_plugin = {
.type = R_LIB_TYPE_BIN_DEMANGLE,
.data = &r_bin_demangle_plugin_java,
.version = R2_VERSION,
};
#endif

View file

@ -0,0 +1,27 @@
/* radare - LGPL - Copyright 2026 - pancake */
#include <r_bin.h>
static char *demangle(RBinFile *bf, const char *symbol, ut64 vaddr) {
(void)bf;
(void)vaddr;
return r_bin_demangle_msvc (symbol);
}
RBinDemanglePlugin r_bin_demangle_plugin_msvc = {
.meta = {
.name = "msvc",
.desc = "Microsoft Visual C++ demangler",
.license = "LGPL-3.0-only",
},
.type = R_BIN_LANG_MSVC,
.demangle = demangle,
};
#ifndef R2_PLUGIN_INCORE
R_API RLibStruct radare_plugin = {
.type = R_LIB_TYPE_BIN_DEMANGLE,
.data = &r_bin_demangle_plugin_msvc,
.version = R2_VERSION,
};
#endif

View file

@ -0,0 +1,27 @@
/* radare - LGPL - Copyright 2026 - pancake */
#include <r_bin.h>
static char *demangle(RBinFile *bf, const char *symbol, ut64 vaddr) {
(void)bf;
(void)vaddr;
return r_bin_demangle_objc (NULL, symbol);
}
RBinDemanglePlugin r_bin_demangle_plugin_objc = {
.meta = {
.name = "objc",
.desc = "Objective-C demangler",
.license = "LGPL-3.0-only",
},
.type = R_BIN_LANG_OBJC,
.demangle = demangle,
};
#ifndef R2_PLUGIN_INCORE
R_API RLibStruct radare_plugin = {
.type = R_LIB_TYPE_BIN_DEMANGLE,
.data = &r_bin_demangle_plugin_objc,
.version = R2_VERSION,
};
#endif

View file

@ -0,0 +1,28 @@
/* radare - LGPL - Copyright 2026 - pancake */
#include <r_bin.h>
static char *demangle(RBinFile *bf, const char *symbol, ut64 vaddr) {
(void)bf;
(void)vaddr;
return r_bin_demangle_freepascal (symbol);
}
RBinDemanglePlugin r_bin_demangle_plugin_pascal = {
.meta = {
.name = "pascal",
.desc = "Free Pascal demangler",
.license = "LGPL-3.0-only",
},
.type = R_BIN_LANG_PASCAL,
.aliases = "freepascal",
.demangle = demangle,
};
#ifndef R2_PLUGIN_INCORE
R_API RLibStruct radare_plugin = {
.type = R_LIB_TYPE_BIN_DEMANGLE,
.data = &r_bin_demangle_plugin_pascal,
.version = R2_VERSION,
};
#endif

View file

@ -0,0 +1,21 @@
/* radare - LGPL - Copyright 2026 - pancake */
#include <r_bin.h>
RBinDemanglePlugin r_bin_demangle_plugin_rust = {
.meta = {
.name = "rust",
.desc = "Rust demangler",
.license = "LGPL-3.0-only",
},
.type = R_BIN_LANG_RUST,
.demangle = r_bin_demangle_rust,
};
#ifndef R2_PLUGIN_INCORE
R_API RLibStruct radare_plugin = {
.type = R_LIB_TYPE_BIN_DEMANGLE,
.data = &r_bin_demangle_plugin_rust,
.version = R2_VERSION,
};
#endif

View file

@ -0,0 +1,29 @@
/* radare - LGPL - Copyright 2026 - pancake */
#include <r_bin.h>
static char *demangle(RBinFile *bf, const char *symbol, ut64 vaddr) {
(void)vaddr;
RBin *bin = bf? bf->rbin: NULL;
bool usecmd = bin? bin->options.demangle_usecmd: false;
bool trylib = bin? bin->options.demangle_trylib: true;
return r_bin_demangle_swift (symbol, usecmd, trylib);
}
RBinDemanglePlugin r_bin_demangle_plugin_swift = {
.meta = {
.name = "swift",
.desc = "Swift demangler",
.license = "LGPL-3.0-only",
},
.type = R_BIN_LANG_SWIFT,
.demangle = demangle,
};
#ifndef R2_PLUGIN_INCORE
R_API RLibStruct radare_plugin = {
.type = R_LIB_TYPE_BIN_DEMANGLE,
.data = &r_bin_demangle_plugin_swift,
.version = R2_VERSION,
};
#endif

View file

@ -138,7 +138,7 @@ static bool symbols_vec(RBinFile *bf) {
sctn_header = r_list_get_n (pe_stream->sections_hdrs, (gdata->segment - 1));
if (sctn_header) {
RBinSymbol *sym = RVecRBinSymbol_emplace_back (ret);
char *demangled_name = r_bin_demangle_msvc (gdata->name.name);
char *demangled_name = r_bin_demangle (bf, "msvc", gdata->name.name, 0, false);
const char *name = demangled_name? demangled_name: gdata->name.name;
sym->name = r_bin_name_new (name);

View file

@ -0,0 +1,19 @@
OBJ_DEMANGLE_CXX=bin_demangle_cxx.o \
../mangling/cxx.o \
../mangling/cxx2/itanium.o \
../mangling/cxx2/xlc.o \
../mangling/cxx2/gnu-v2.o \
../mangling/cxx2/armabi.o
ifeq (1,$(WITH_GPL))
OBJ_DEMANGLE_CXX+=../mangling/cxx/cp-demangle.o
endif
CFLAGS+=-DR_BIN_DEMANGLE_CXX=1
STATIC_OBJ+=${OBJ_DEMANGLE_CXX}
TARGET_DEMANGLE_CXX=bin_demangle_cxx.${EXT_SO}
ALL_TARGETS+=${TARGET_DEMANGLE_CXX}
${TARGET_DEMANGLE_CXX}: ${OBJ_DEMANGLE_CXX}
${CC} $(call libname,bin_demangle_cxx) ${CFLAGS} -o $@ \
${OBJ_DEMANGLE_CXX} $(LINK) $(LDFLAGS)

View file

@ -0,0 +1,12 @@
OBJ_DEMANGLE_DLANG=bin_demangle_dlang.o \
../mangling/dlang.o \
../mangling/cxx2/dlang.o
CFLAGS+=-DR_BIN_DEMANGLE_DLANG=1
STATIC_OBJ+=${OBJ_DEMANGLE_DLANG}
TARGET_DEMANGLE_DLANG=bin_demangle_dlang.${EXT_SO}
ALL_TARGETS+=${TARGET_DEMANGLE_DLANG}
${TARGET_DEMANGLE_DLANG}: ${OBJ_DEMANGLE_DLANG}
${CC} $(call libname,bin_demangle_dlang) ${CFLAGS} -o $@ \
${OBJ_DEMANGLE_DLANG} $(LINK) $(LDFLAGS)

View file

@ -0,0 +1,12 @@
OBJ_DEMANGLE_IBMXL=bin_demangle_ibmxl.o \
../mangling/ibmxl.o \
../mangling/cxx2/xlc.o
CFLAGS+=-DR_BIN_DEMANGLE_IBMXL=1
STATIC_OBJ+=${OBJ_DEMANGLE_IBMXL}
TARGET_DEMANGLE_IBMXL=bin_demangle_ibmxl.${EXT_SO}
ALL_TARGETS+=${TARGET_DEMANGLE_IBMXL}
${TARGET_DEMANGLE_IBMXL}: ${OBJ_DEMANGLE_IBMXL}
${CC} $(call libname,bin_demangle_ibmxl) ${CFLAGS} -o $@ \
${OBJ_DEMANGLE_IBMXL} $(LINK) $(LDFLAGS)

View file

@ -0,0 +1,10 @@
OBJ_DEMANGLE_JAVA=bin_demangle_java.o ../mangling/java.o
CFLAGS+=-DR_BIN_DEMANGLE_JAVA=1
STATIC_OBJ+=${OBJ_DEMANGLE_JAVA}
TARGET_DEMANGLE_JAVA=bin_demangle_java.${EXT_SO}
ALL_TARGETS+=${TARGET_DEMANGLE_JAVA}
${TARGET_DEMANGLE_JAVA}: ${OBJ_DEMANGLE_JAVA}
${CC} $(call libname,bin_demangle_java) ${CFLAGS} -o $@ \
${OBJ_DEMANGLE_JAVA} $(LINK) $(LDFLAGS)

View file

@ -0,0 +1,13 @@
OBJ_DEMANGLE_MSVC=bin_demangle_msvc.o \
../mangling/msvc.o \
../mangling/microsoft.o \
../mangling/demangler.o
CFLAGS+=-DR_BIN_DEMANGLE_MSVC=1
STATIC_OBJ+=${OBJ_DEMANGLE_MSVC}
TARGET_DEMANGLE_MSVC=bin_demangle_msvc.${EXT_SO}
ALL_TARGETS+=${TARGET_DEMANGLE_MSVC}
${TARGET_DEMANGLE_MSVC}: ${OBJ_DEMANGLE_MSVC}
${CC} $(call libname,bin_demangle_msvc) ${CFLAGS} -o $@ \
${OBJ_DEMANGLE_MSVC} $(LINK) $(LDFLAGS)

View file

@ -0,0 +1,10 @@
OBJ_DEMANGLE_OBJC=bin_demangle_objc.o ../mangling/objc.o
CFLAGS+=-DR_BIN_DEMANGLE_OBJC=1
STATIC_OBJ+=${OBJ_DEMANGLE_OBJC}
TARGET_DEMANGLE_OBJC=bin_demangle_objc.${EXT_SO}
ALL_TARGETS+=${TARGET_DEMANGLE_OBJC}
${TARGET_DEMANGLE_OBJC}: ${OBJ_DEMANGLE_OBJC}
${CC} $(call libname,bin_demangle_objc) ${CFLAGS} -o $@ \
${OBJ_DEMANGLE_OBJC} $(LINK) $(LDFLAGS)

View file

@ -0,0 +1,10 @@
OBJ_DEMANGLE_PASCAL=bin_demangle_pascal.o ../mangling/pascal.o
CFLAGS+=-DR_BIN_DEMANGLE_PASCAL=1
STATIC_OBJ+=${OBJ_DEMANGLE_PASCAL}
TARGET_DEMANGLE_PASCAL=bin_demangle_pascal.${EXT_SO}
ALL_TARGETS+=${TARGET_DEMANGLE_PASCAL}
${TARGET_DEMANGLE_PASCAL}: ${OBJ_DEMANGLE_PASCAL}
${CC} $(call libname,bin_demangle_pascal) ${CFLAGS} -o $@ \
${OBJ_DEMANGLE_PASCAL} $(LINK) $(LDFLAGS)

View file

@ -0,0 +1,21 @@
OBJ_DEMANGLE_RUST=bin_demangle_rust.o \
../mangling/rust.o \
../mangling/cxx2/rust.o \
../mangling/cxx.o \
../mangling/cxx2/itanium.o \
../mangling/cxx2/xlc.o \
../mangling/cxx2/gnu-v2.o \
../mangling/cxx2/armabi.o
ifeq (1,$(WITH_GPL))
OBJ_DEMANGLE_RUST+=../mangling/cxx/cp-demangle.o
endif
CFLAGS+=-DR_BIN_DEMANGLE_RUST=1 -DR_BIN_DEMANGLE_CXX=1
STATIC_OBJ+=${OBJ_DEMANGLE_RUST}
TARGET_DEMANGLE_RUST=bin_demangle_rust.${EXT_SO}
ALL_TARGETS+=${TARGET_DEMANGLE_RUST}
${TARGET_DEMANGLE_RUST}: ${OBJ_DEMANGLE_RUST}
${CC} $(call libname,bin_demangle_rust) ${CFLAGS} -o $@ \
${OBJ_DEMANGLE_RUST} $(LINK) $(LDFLAGS)

View file

@ -0,0 +1,10 @@
OBJ_DEMANGLE_SWIFT=bin_demangle_swift.o ../mangling/swift-sd.o
CFLAGS+=-DR_BIN_DEMANGLE_SWIFT=1
STATIC_OBJ+=${OBJ_DEMANGLE_SWIFT}
TARGET_DEMANGLE_SWIFT=bin_demangle_swift.${EXT_SO}
ALL_TARGETS+=${TARGET_DEMANGLE_SWIFT}
${TARGET_DEMANGLE_SWIFT}: ${OBJ_DEMANGLE_SWIFT}
${CC} $(call libname,bin_demangle_swift) ${CFLAGS} -o $@ \
${OBJ_DEMANGLE_SWIFT} $(LINK) $(LDFLAGS)

View file

@ -12,6 +12,7 @@
#define R_EGG_STATIC_PLUGINS @plugins_egg@
#define R_BIN_STATIC_PLUGINS @plugins_bin@
#define R_BIN_DEMANGLE_STATIC_PLUGINS @plugins_bin_demangle@
#define R_BIN_LDR_STATIC_PLUGINS @plugins_bin_ldr@
#define R_BIN_XTR_STATIC_PLUGINS @plugins_bin_xtr@
#define R_FS_STATIC_PLUGINS @plugins_fs@

View file

@ -30,6 +30,20 @@ CB(egg, egg)
CB(fs, fs)
CB(arch, anal->arch);
static bool __lib_bin_demangle_cb(RLibPlugin *pl, void *user, void *data) {
RCore *core = user;
RPluginMeta *meta = data;
pl->free = NULL;
pl->name = strdup (meta->name);
return r_bin_demangle_plugin_add (core->bin, data);
}
static bool __lib_bin_demangle_dt(RLibPlugin *pl, void *user, void *data) {
RCore *core = user;
free (pl->name);
return r_bin_demangle_plugin_remove (core->bin, data);
}
static void core_load_internal_plugins(void *user) {
RCore *core = (RCore *)user;
r_libstore_load (core->libstore);
@ -92,6 +106,7 @@ R_API void r_core_loadlibs_init(RCore *core) {
DF (ASM, "assembly plugins", asm);
// DF (PARSE, "parsing plugins", parse);
DF (BIN, "bin plugins", bin);
DF (BIN_DEMANGLE, "bin demangler plugins", bin_demangle);
DF (EGG, "egg plugins", egg);
DF (FS, "fs plugins", fs);
DF (ARCH, "arch plugins", arch);

View file

@ -543,6 +543,15 @@ typedef struct r_bin_file_t {
RArena *arena;
} RBinFile;
#define R_BIN_DEMANGLE_TYPE_SLOTS 16
typedef struct r_bin_demangle_plugin_t {
RPluginMeta meta;
RBinLanguage type;
const char *aliases;
char *(*demangle)(RBinFile *bf, const char *symbol, ut64 vaddr);
} RBinDemanglePlugin;
typedef struct r_bin_create_options_t {
const char *pluginname;
ut64 baseaddr; // where the linker maps the binary in memory
@ -608,6 +617,9 @@ struct r_bin_t {
RStrConstPool constpool;
RBinOptions options;
RLibStore *libstore;
RList /*<RBinDemanglePlugin *>*/ *demangle_plugins;
HtPP /*<char *, RBinDemanglePlugin *>*/ *demangle_by_name;
RBinDemanglePlugin *demangle_by_type[R_BIN_DEMANGLE_TYPE_SLOTS];
struct r_fs_t *fs; // optional: r_bin_open_buf probes containers via r_fs
};
@ -916,6 +928,9 @@ R_API bool r_bin_plugin_add(RBin *bin, RBinPlugin *plugin);
R_API bool r_bin_plugin_remove(RBin *bin, RBinPlugin *plugin);
R_API bool r_bin_xtr_add(RBin *bin, RBinXtrPlugin *foo);
R_API bool r_bin_ldr_add(RBin *bin, RBinLdrPlugin *foo);
R_API bool r_bin_demangle_plugin_add(RBin *bin, RBinDemanglePlugin *plugin);
R_API bool r_bin_demangle_plugin_remove(RBin *bin, RBinDemanglePlugin *plugin);
R_API RBinDemanglePlugin *r_bin_demangle_plugin_find(RBin *bin, const char *name);
R_API void r_bin_list(RBin *bin, PJ *pj, int format);
R_API bool r_bin_list_plugin(RBin *bin, const char *name, PJ *pj, int json);
R_API RBinPlugin *r_bin_get_binplugin_by_buffer(RBin *bin, RBinFile *bf, RBuffer *buf);
@ -1092,6 +1107,15 @@ R_API void r_bin_section_free(RBinSection *bs);
/* plugin pointers */
extern RBinLdrPlugin r_bin_ldr_plugin_ldr_linux;
extern RBinDemanglePlugin r_bin_demangle_plugin_cxx;
extern RBinDemanglePlugin r_bin_demangle_plugin_dlang;
extern RBinDemanglePlugin r_bin_demangle_plugin_ibmxl;
extern RBinDemanglePlugin r_bin_demangle_plugin_java;
extern RBinDemanglePlugin r_bin_demangle_plugin_msvc;
extern RBinDemanglePlugin r_bin_demangle_plugin_objc;
extern RBinDemanglePlugin r_bin_demangle_plugin_pascal;
extern RBinDemanglePlugin r_bin_demangle_plugin_rust;
extern RBinDemanglePlugin r_bin_demangle_plugin_swift;
extern RBinPlugin r_bin_plugin_null;
extern RBinPlugin r_bin_plugin_art;
extern RBinPlugin r_bin_plugin_avr;

View file

@ -116,6 +116,7 @@ enum {
R_LIB_TYPE_ESIL, /* r_anal.esil plugin */
R_LIB_TYPE_ARCH, /* arch plugins */
R_LIB_TYPE_MUTA, /* mutator */
R_LIB_TYPE_BIN_DEMANGLE, /* bin demanglers */
R_LIB_TYPE_LAST
};

View file

@ -557,23 +557,31 @@ static bool __lib_bin_ldr_dt(RLibPlugin *pl, void *p, void *u) {
return true;
}
static bool __lib_bin_demangle_cb(RLibPlugin *pl, void *user, void *data) {
RBinDemanglePlugin *plugin = data;
return r_bin_demangle_plugin_add (user, plugin);
}
static bool __lib_bin_demangle_dt(RLibPlugin *pl, void *user, void *data) {
return true;
}
static char *__demangleAs(RBin *bin, int type, const char *file) {
bool syscmd = bin->options.demangle_usecmd;
char *res = NULL;
const char *name = NULL;
switch (type) {
case R_BIN_LANG_CXX: res = r_bin_demangle_cxx (NULL, file, 0); break;
case R_BIN_LANG_IBMXL: res = r_bin_demangle_ibmxl (file); break;
case R_BIN_LANG_JAVA: res = r_bin_demangle_java (file); break;
case R_BIN_LANG_OBJC: res = r_bin_demangle_objc (NULL, file); break;
case R_BIN_LANG_SWIFT: res = r_bin_demangle_swift (file, syscmd, bin->options.demangle_trylib); break;
case R_BIN_LANG_MSVC: res = r_bin_demangle_msvc (file); break;
case R_BIN_LANG_RUST: res = r_bin_demangle_rust (NULL, file, 0); break;
case R_BIN_LANG_DLANG: res = r_bin_demangle_dlang (file); break;
case R_BIN_LANG_CXX: name = "cxx"; break;
case R_BIN_LANG_IBMXL: name = "ibmxl"; break;
case R_BIN_LANG_JAVA: name = "java"; break;
case R_BIN_LANG_OBJC: name = "objc"; break;
case R_BIN_LANG_SWIFT: name = "swift"; break;
case R_BIN_LANG_MSVC: name = "msvc"; break;
case R_BIN_LANG_RUST: name = "rust"; break;
case R_BIN_LANG_DLANG: name = "dlang"; break;
default:
R_LOG_ERROR ("Unsupported demangler");
break;
return NULL;
}
return res;
return r_bin_demangle_plugin (bin, name, file);
}
static void list_plugins(RBin *bin, const char *plugin_name, PJ *pj, int rad) {
@ -658,6 +666,8 @@ R_API int r_main_rabin2(int argc, const char **argv) {
&__lib_bin_xtr_cb, &__lib_bin_xtr_dt, bin);
r_lib_add_handler (l, R_LIB_TYPE_BIN_LDR, "bin ldr plugins",
&__lib_bin_ldr_cb, &__lib_bin_ldr_dt, bin);
r_lib_add_handler (l, R_LIB_TYPE_BIN_DEMANGLE, "bin demangler plugins",
&__lib_bin_demangle_cb, &__lib_bin_demangle_dt, bin);
r_lib_load_default_paths (l, R_LIB_LOAD_DEFAULT);
r_lib_free (l);
} else {

View file

@ -11,6 +11,7 @@ asm_plugins = [ 'null', 'att2intel' ]
anal_plugins = [ 'null', 'autoname', 'a2f', 'tcc', 'blaze', 'tp', 'sbpf', 'path', 'drcov', 'callargs' ]
arch_plugins = [ 'null' ]
bin_plugins = [ 'null' ]
bin_demangle_plugins = get_option('demanglers')
bin_ldr_plugins = [ 'ldr_linux' ]
bin_xtr_plugins = []
io_plugins = [ 'malloc', 'cyclic', 'xattr', 'fd', 'tap', 'default', 'null', 'rbuf', 'r2pipe' ]

View file

@ -7,8 +7,9 @@ R_LIB_VERSION (r_lib);
/* XXX : this must be registered at runtime instead of hardcoded */
static const char *const r_lib_types[] = {
"io", "dbg", "lang", "asm", "anal", "parse", "bin", "bin_xtr", "bin_ldr",
"bp", "syscall", "fastcall", "muta", "core", "egg", "fs", "arch", NULL
"io", "dbg", "lang", "asm", "anal", "bin", "bin_xtr", "bin_ldr",
"bp", "syscall", "fastcall", "crypto", "core", "egg", "fs", "esil",
"arch", "muta", "bin_demangle", NULL
};
R_API void *r_lib_dl_open(const char *libname, bool safe_mode) {

View file

@ -262,6 +262,7 @@ conf_data.set('plugins_arch', '&r_arch_plugin_' + ', &r_arch_plugin_'.join(arch_
conf_data.set('plugins_asm', '&r_asm_plugin_' + ', &r_asm_plugin_'.join(asm_plugins) + ', 0')
conf_data.set('plugins_bp', '&r_bp_plugin_' + ', &r_bp_plugin_'.join(bp_plugins) + ', 0')
conf_data.set('plugins_bin', '&r_bin_plugin_' + ', &r_bin_plugin_'.join(bin_plugins) + ', 0')
conf_data.set('plugins_bin_demangle', bin_demangle_plugins.length() > 0 ? '&r_bin_demangle_plugin_' + ', &r_bin_demangle_plugin_'.join(bin_demangle_plugins) + ', 0' : '0')
conf_data.set('plugins_bin_ldr', '&r_bin_ldr_plugin_' + ', &r_bin_ldr_plugin_'.join(bin_ldr_plugins) + ', 0')
conf_data.set('plugins_bin_xtr', '&r_bin_xtr_plugin_' + ', &r_bin_xtr_plugin_'.join(bin_xtr_plugins) + ', 0')
conf_data.set('plugins_muta', '&r_muta_plugin_' + ', &r_muta_plugin_'.join(muta_plugins) + ', 0')

View file

@ -8,6 +8,7 @@ option('debugstuff', type: 'boolean', value: true, description: 'Permit and hand
# Plugins
option('plugins', type: 'string', value: '', description: 'Comma separated list of plugin names')
option('demanglers', type: 'array', choices: ['cxx', 'dlang', 'ibmxl', 'java', 'msvc', 'objc', 'pascal', 'rust', 'swift'], value: ['cxx', 'dlang', 'ibmxl', 'java', 'msvc', 'objc', 'pascal', 'rust', 'swift'], description: 'Demangler plugins to include')
# For Windows
option('r2_libdir', type: 'string', value: '')

View file

@ -13,9 +13,7 @@ iD list
EOF
EXPECT=<<EOF
c++
dart
dlang
groovy
ibmxl
java
msvc

View file

@ -17,6 +17,7 @@ if get_option('enable_tests')
'base64',
'big',
'bin',
'bin_demangle',
'bitmap',
'bitset',
'buf',
@ -105,6 +106,7 @@ if get_option('enable_tests')
r_search_dep,
r_muta_dep,
r_magic_dep,
gdb_dep,
lrt,
],
install: false,

View file

@ -0,0 +1,87 @@
#include <r_bin.h>
#include "minunit.h"
static char *unit_demangle(RBinFile *bf, const char *symbol, ut64 vaddr) {
(void)bf;
(void)vaddr;
return strdup (symbol);
}
static bool test_demangle_registry(void) {
RBin *bin = r_bin_new ();
mu_assert_notnull (bin, "RBin allocation");
mu_assert_true (r_libstore_load (bin->libstore), "load static RBin plugins");
RBinDemanglePlugin *cxx = r_bin_demangle_plugin_find (bin, "cxx");
if (cxx) {
mu_assert_ptreq (cxx, r_bin_demangle_plugin_find (bin, "c++"), "C++ alias lookup");
mu_assert_ptreq (cxx, bin->demangle_by_type[r_bits_ctz32 (R_BIN_LANG_CXX)], "C++ direct table lookup");
}
RBinDemanglePlugin plugin = {
.meta = {
.name = "unit",
.desc = "unit test demangler",
},
.type = R_BIN_LANG_NONE,
.aliases = "test,testalias",
.demangle = unit_demangle,
};
mu_assert_true (r_bin_demangle_plugin_add (bin, &plugin), "add named demangler");
mu_assert_ptreq (r_bin_demangle_plugin_find (bin, "unit"), r_bin_demangle_plugin_find (bin, "testalias"), "custom alias lookup");
RBinFile bf = { 0 };
bf.rbin = bin;
char *res = r_bin_demangle (&bf, "test", "symbol", 0, false);
mu_assert_streq (res, "symbol", "dispatch an explicitly named demangler");
free (res);
RBinDemanglePlugin duplicate_alias = {
.meta.name = "duplicate",
.type = R_BIN_LANG_NONE,
.aliases = "testalias",
.demangle = unit_demangle,
};
mu_assert_false (r_bin_demangle_plugin_add (bin, &duplicate_alias), "reject duplicate aliases");
RBinDemanglePlugin typed = {
.meta.name = "typed",
.type = R_BIN_LANG_CIL,
.demangle = unit_demangle,
};
mu_assert_true (r_bin_demangle_plugin_add (bin, &typed), "add typed demangler");
RBinDemanglePlugin duplicate_type = {
.meta.name = "duplicate_type",
.type = R_BIN_LANG_CIL,
.demangle = unit_demangle,
};
mu_assert_false (r_bin_demangle_plugin_add (bin, &duplicate_type), "reject duplicate language providers");
res = r_bin_demangle (&bf, "cil", "typed-symbol", 0, false);
mu_assert_streq (res, "typed-symbol", "direct language table dispatch");
free (res);
RBinDemanglePlugin invalid_type = {
.meta.name = "invalid_type",
.type = R_BIN_LANG_CXX | R_BIN_LANG_RUST,
.demangle = unit_demangle,
};
mu_assert_false (r_bin_demangle_plugin_add (bin, &invalid_type), "reject non-unique language types");
mu_assert_true (r_bin_demangle_plugin_remove (bin, &typed), "remove typed demangler");
mu_assert_true (r_bin_demangle_plugin_remove (bin, &plugin), "remove named demangler");
mu_assert_null (r_bin_demangle_plugin_find (bin, "testalias"), "remove alias index");
mu_assert_null (r_bin_demangle_plugin (bin, "missing", "symbol"), "missing demangler");
r_bin_free (bin);
mu_end;
}
static bool all_tests(void) {
mu_run_test (test_demangle_registry);
return tests_passed != tests_run;
}
int main(int argc, char **argv) {
(void)argc;
(void)argv;
return all_tests ();
}