mirror of
https://github.com/radareorg/radare2.git
synced 2025-03-03 19:59:09 +00:00
Initial support for C++ classes extracted from the demangler
This commit is contained in:
parent
414310836a
commit
7b94a79dcd
@ -2163,18 +2163,20 @@ R_API RBinObject *r_bin_get_object(RBin *bin) {
|
||||
|
||||
R_API RList * /*<RBinClass>*/ r_bin_get_classes(RBin *bin) {
|
||||
RBinObject *o = r_bin_cur_object (bin);
|
||||
if (o) return o->classes;
|
||||
return NULL;
|
||||
return o? o->classes: NULL;
|
||||
}
|
||||
|
||||
R_API RBinClass *r_bin_class_new(RBinFile *binfile, const char *name, const char *super, int view) {
|
||||
RBinObject *o = binfile? binfile->o: NULL;
|
||||
RList *list = NULL;
|
||||
RBinClass *c;
|
||||
if (!o)
|
||||
if (!o) {
|
||||
return NULL;
|
||||
}
|
||||
list = o->classes;
|
||||
if (!name) return NULL;
|
||||
if (!name) {
|
||||
return NULL;
|
||||
}
|
||||
c = r_bin_class_get (binfile, name);
|
||||
if (c) {
|
||||
if (super) {
|
||||
@ -2184,15 +2186,18 @@ R_API RBinClass *r_bin_class_new(RBinFile *binfile, const char *name, const char
|
||||
return c;
|
||||
}
|
||||
c = R_NEW0 (RBinClass);
|
||||
if (!c) return NULL;
|
||||
if (!c) {
|
||||
return NULL;
|
||||
}
|
||||
c->name = strdup (name);
|
||||
c->super = super? strdup (super): NULL;
|
||||
c->index = r_list_length (list);
|
||||
c->methods = r_list_new ();
|
||||
c->fields = r_list_new ();
|
||||
c->visibility = view;
|
||||
if (!list)
|
||||
if (!list) {
|
||||
list = o->classes = r_list_new ();
|
||||
}
|
||||
r_list_append (list, c);
|
||||
return c;
|
||||
}
|
||||
@ -2214,14 +2219,25 @@ R_API RBinClass *r_bin_class_get(RBinFile *binfile, const char *name) {
|
||||
|
||||
R_API int r_bin_class_add_method(RBinFile *binfile, const char *classname, const char *name, int nargs) {
|
||||
RBinClass *c = r_bin_class_get (binfile, classname);
|
||||
RBinSymbol *sym = R_NEW0 (RBinSymbol);
|
||||
if (!sym) return false;
|
||||
sym->name = strdup (name);
|
||||
if (c) {
|
||||
r_list_append (c->methods, sym);
|
||||
return true;
|
||||
if (!c) {
|
||||
c = r_bin_class_new (binfile, classname, NULL, 0);
|
||||
if (!c) {
|
||||
eprintf ("Cannot allocate class %s\n", classname);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
c = r_bin_class_new (binfile, classname, NULL, 0);
|
||||
RBinSymbol *m;
|
||||
RListIter *iter;
|
||||
r_list_foreach (c->methods, iter, m) {
|
||||
if (!strcmp (m->name, name)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
RBinSymbol *sym = R_NEW0 (RBinSymbol);
|
||||
if (!sym) {
|
||||
return false;
|
||||
}
|
||||
sym->name = strdup (name);
|
||||
r_list_append (c->methods, sym);
|
||||
return true;
|
||||
}
|
||||
|
@ -117,7 +117,7 @@ R_API char *r_bin_demangle_msvc(const char *str) {
|
||||
return out;
|
||||
}
|
||||
|
||||
R_API char *r_bin_demangle_cxx(const char *str) {
|
||||
R_API char *r_bin_demangle_cxx(RBinFile *binfile, const char *str) {
|
||||
char *out;
|
||||
// DMGL_TYPES | DMGL_PARAMS | DMGL_ANSI | DMGL_VERBOSE
|
||||
// | DMGL_RET_POSTFIX | DMGL_TYPES;
|
||||
@ -132,10 +132,10 @@ R_API char *r_bin_demangle_cxx(const char *str) {
|
||||
"imp.",
|
||||
NULL
|
||||
};
|
||||
if (str[0]==str[1] && *str=='_') {
|
||||
if (str[0] == str[1] && *str == '_') {
|
||||
str++;
|
||||
} {
|
||||
for (i=0; prefixes[i]; i++) {
|
||||
for (i = 0; prefixes[i]; i++) {
|
||||
int plen = strlen (prefixes[i]);
|
||||
if (!strncmp (str, prefixes[i], plen)) {
|
||||
str += plen;
|
||||
@ -149,11 +149,18 @@ R_API char *r_bin_demangle_cxx(const char *str) {
|
||||
/* TODO: implement a non-gpl alternative to c++v3 demangler */
|
||||
out = NULL;
|
||||
#endif
|
||||
|
||||
if (out) {
|
||||
r_str_replace_char (out, ' ', 0);
|
||||
}
|
||||
|
||||
{
|
||||
/* extract class/method information */
|
||||
char *nerd = (char*)r_str_last (out, "::");
|
||||
if (nerd && *nerd) {
|
||||
*nerd = 0;
|
||||
r_bin_class_add_method (binfile, out, nerd + 2, 0);
|
||||
*nerd = ':';
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
@ -165,23 +172,27 @@ R_API char *r_bin_demangle_objc(RBinFile *binfile, const char *sym) {
|
||||
int i, nargs = 0;
|
||||
const char *type = NULL;
|
||||
|
||||
if (!binfile || !sym)
|
||||
if (!binfile || !sym) {
|
||||
return NULL;
|
||||
}
|
||||
if (binfile && binfile->o && binfile->o->classes) {
|
||||
binfile = NULL;
|
||||
}
|
||||
|
||||
/* classes */
|
||||
if (!strncmp (sym, "_OBJC_Class_", 12)) {
|
||||
ret = r_str_newf ("class %s", sym + 12);
|
||||
if (binfile) r_bin_class_new (binfile, sym + 12,
|
||||
NULL, R_BIN_CLASS_PUBLIC);
|
||||
if (binfile) {
|
||||
r_bin_class_new (binfile, sym + 12,
|
||||
NULL, R_BIN_CLASS_PUBLIC);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
if (!strncmp (sym, "_OBJC_CLASS_$_", 14)) {
|
||||
ret = r_str_newf ("class %s", sym + 14);
|
||||
if (binfile) r_bin_class_new (binfile, sym + 14,
|
||||
NULL, R_BIN_CLASS_PUBLIC);
|
||||
if (binfile) {
|
||||
r_bin_class_new (binfile, sym + 14,
|
||||
NULL, R_BIN_CLASS_PUBLIC);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
/* fields */
|
||||
@ -268,7 +279,9 @@ R_API char *r_bin_demangle_objc(RBinFile *binfile, const char *sym) {
|
||||
}
|
||||
if (type && name && *name) {
|
||||
ret = r_str_newf ("%s int %s::%s(%s)", type, clas, name, args);
|
||||
if (binfile) r_bin_class_add_method (binfile, clas, name, nargs);
|
||||
if (binfile) {
|
||||
r_bin_class_add_method (binfile, clas, name, nargs);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -364,18 +377,19 @@ R_API char *r_bin_demangle(RBinFile *binfile, const char *def, const char *str)
|
||||
}
|
||||
}
|
||||
// if str is sym. or imp. when str+=4 str points to the end so just return
|
||||
if (!*str)
|
||||
if (!*str) {
|
||||
return NULL;
|
||||
}
|
||||
if (type == -1) {
|
||||
type = r_bin_lang_type (binfile, def, str);
|
||||
}
|
||||
switch (type) {
|
||||
case R_BIN_NM_JAVA: return r_bin_demangle_java (str);
|
||||
/* rust uses the same mangling as c++ and appends a uniqueid */
|
||||
case R_BIN_NM_RUST: return r_bin_demangle_cxx (str);
|
||||
case R_BIN_NM_RUST: return r_bin_demangle_cxx (binfile, str);
|
||||
case R_BIN_NM_OBJC: return r_bin_demangle_objc (NULL, str);
|
||||
case R_BIN_NM_SWIFT: return r_bin_demangle_swift (str, bin->demanglercmd);
|
||||
case R_BIN_NM_CXX: return r_bin_demangle_cxx (str);
|
||||
case R_BIN_NM_CXX: return r_bin_demangle_cxx (binfile, str);
|
||||
case R_BIN_NM_DLANG: return r_bin_demangle_plugin (bin, "dlang", str);
|
||||
}
|
||||
return NULL;
|
||||
|
@ -508,7 +508,7 @@ R_API const char *r_bin_entry_type_string(int etype);
|
||||
R_API char* r_bin_demangle(RBinFile *binfile, const char *lang, const char *str);
|
||||
R_API int r_bin_demangle_type (const char *str);
|
||||
R_API char *r_bin_demangle_java(const char *str);
|
||||
R_API char *r_bin_demangle_cxx(const char *str);
|
||||
R_API char *r_bin_demangle_cxx(RBinFile *binfile, const char *str);
|
||||
R_API char *r_bin_demangle_msvc(const char *str);
|
||||
R_API char *r_bin_demangle_swift(const char *s, bool syscmd);
|
||||
R_API char *r_bin_demangle_objc(RBinFile *binfile, const char *sym);
|
||||
|
@ -132,5 +132,6 @@ R_API char *r_str_between(const char *str, const char *prefix, const char *suffi
|
||||
R_API bool r_str_startswith(const char *str, const char *needle);
|
||||
R_API bool r_str_endswith(const char *str, const char *needle);
|
||||
R_API bool r_str_isnumber (const char *str);
|
||||
R_API const char *r_str_last (const char *in, const char *ch);
|
||||
|
||||
#endif // R_STR_H
|
||||
|
@ -2513,3 +2513,20 @@ R_API bool r_str_isnumber (const char *str) {
|
||||
}
|
||||
return isnum;
|
||||
}
|
||||
|
||||
/* TODO: optimize to start searching by the end of the string */
|
||||
R_API const char *r_str_last(const char *str, const char *ch) {
|
||||
char *ptr, *end = NULL;
|
||||
if (!str || !ch) {
|
||||
return NULL;
|
||||
}
|
||||
do {
|
||||
ptr = strstr (str, ch);
|
||||
if (!ptr) {
|
||||
break;
|
||||
}
|
||||
end = ptr;
|
||||
str = ptr + 1;
|
||||
} while (true);
|
||||
return end;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user