rizin/librz/analysis/rtti.c
2021-01-21 22:05:44 +08:00

99 lines
2.4 KiB
C

// SPDX-License-Identifier: LGPL-3.0-only
#include "rz_analysis.h"
RZ_API char *rz_analysis_rtti_demangle_class_name(RzAnalysis *analysis, const char *name) {
RVTableContext context;
rz_analysis_vtable_begin(analysis, &context);
if (context.abi == RZ_ANALYSIS_CPP_ABI_MSVC) {
return rz_analysis_rtti_msvc_demangle_class_name(&context, name);
}
return rz_analysis_rtti_itanium_demangle_class_name(&context, name);
}
RZ_API void rz_analysis_rtti_print_at_vtable(RzAnalysis *analysis, ut64 addr, int mode) {
bool use_json = mode == 'j';
if (use_json) {
rz_cons_print("[");
}
RVTableContext context;
rz_analysis_vtable_begin(analysis, &context);
if (context.abi == RZ_ANALYSIS_CPP_ABI_MSVC) {
rz_analysis_rtti_msvc_print_at_vtable(&context, addr, mode, false);
} else {
rz_analysis_rtti_itanium_print_at_vtable(&context, addr, mode);
}
if (use_json) {
rz_cons_print("]\n");
}
}
RZ_API void rz_analysis_rtti_print_all(RzAnalysis *analysis, int mode) {
RVTableContext context;
rz_analysis_vtable_begin(analysis, &context);
bool use_json = mode == 'j';
if (use_json) {
rz_cons_print("[");
}
rz_cons_break_push(NULL, NULL);
RzList *vtables = rz_analysis_vtable_search(&context);
RzListIter *vtableIter;
RVTableInfo *table;
if (vtables) {
bool comma = false;
bool success = false;
rz_list_foreach (vtables, vtableIter, table) {
if (rz_cons_is_breaked()) {
break;
}
if (use_json && success) {
rz_cons_print(",");
comma = true;
}
if (context.abi == RZ_ANALYSIS_CPP_ABI_MSVC) {
success = rz_analysis_rtti_msvc_print_at_vtable(&context, table->saddr, mode, true);
} else {
success = rz_analysis_rtti_itanium_print_at_vtable(&context, table->saddr, mode);
}
if (success) {
comma = false;
if (!use_json) {
rz_cons_print("\n");
}
}
}
if (use_json && !success && comma) {
// drop last comma if necessary
rz_cons_drop(1);
}
}
rz_list_free(vtables);
if (use_json) {
rz_cons_print("]\n");
}
rz_cons_break_pop();
}
RZ_API void rz_analysis_rtti_recover_all(RzAnalysis *analysis) {
RVTableContext context;
rz_analysis_vtable_begin(analysis, &context);
rz_cons_break_push(NULL, NULL);
RzList *vtables = rz_analysis_vtable_search(&context);
if (vtables) {
if (context.abi == RZ_ANALYSIS_CPP_ABI_MSVC) {
rz_analysis_rtti_msvc_recover_all(&context, vtables);
} else {
rz_analysis_rtti_itanium_recover_all(&context, vtables);
}
}
rz_list_free(vtables);
rz_cons_break_pop();
}