From c534b1bce8d492d4bc3ccdd7583041fd3a1368a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=A4rkl?= Date: Wed, 1 May 2019 13:34:15 +0200 Subject: [PATCH] Use API for Functions (#1498) --- src/core/Cutter.cpp | 56 +++++++++++++++------------------ src/core/Cutter.h | 1 - src/core/CutterDescriptions.h | 3 -- src/widgets/FunctionsWidget.cpp | 49 ++++++----------------------- src/widgets/FunctionsWidget.h | 5 ++- 5 files changed, 37 insertions(+), 77 deletions(-) diff --git a/src/core/Cutter.cpp b/src/core/Cutter.cpp index 34df2190..d1e1c2af 100644 --- a/src/core/Cutter.cpp +++ b/src/core/Cutter.cpp @@ -1529,7 +1529,32 @@ QList CutterCore::getRAsmPluginDescriptions() QList CutterCore::getAllFunctions() { - return parseFunctionsJson(cmdjTask("aflj")); + CORE_LOCK(); + + QList ret; + ret.reserve(r_list_length(core_->anal->fcns)); + + RListIter *iter; + RAnalFunction *fcn; + CutterRListForeach (core_->anal->fcns, iter, RAnalFunction, fcn) { + FunctionDescription function; + function.offset = fcn->addr; + function.size = r_anal_fcn_size(fcn); + function.nargs = r_anal_var_count(core_->anal, fcn, 'b', 1) + + r_anal_var_count(core_->anal, fcn, 'r', 1) + + r_anal_var_count(core_->anal, fcn, 's', 1); + function.nlocals = r_anal_var_count(core_->anal, fcn, 'b', 0) + + r_anal_var_count(core_->anal, fcn, 'r', 0) + + r_anal_var_count(core_->anal, fcn, 's', 0); + function.nbbs = r_list_length (fcn->bbs); + function.calltype = fcn->cc ? QString::fromUtf8(fcn->cc) : QString(); + function.name = fcn->name ? QString::fromUtf8(fcn->name) : QString(); + function.edges = r_anal_fcn_count_edges(fcn, nullptr); + function.stackframe = fcn->maxstack; + ret.append(function); + } + + return ret; } QList CutterCore::getAllImports() @@ -1748,35 +1773,6 @@ QList CutterCore::parseStringsJson(const QJsonDocument &doc) return ret; } -QList CutterCore::parseFunctionsJson(const QJsonDocument &doc) -{ - QList ret; - QJsonArray jsonArray = doc.array(); - - for (const QJsonValue &value : jsonArray) { - QJsonObject jsonObject = value.toObject(); - - FunctionDescription function; - - function.offset = jsonObject[RJsonKey::offset].toVariant().toULongLong(); - function.size = jsonObject[RJsonKey::size].toVariant().toULongLong(); - function.nargs = jsonObject[RJsonKey::nargs].toVariant().toULongLong(); - function.nbbs = jsonObject[RJsonKey::nbbs].toVariant().toULongLong(); - function.nlocals = jsonObject[RJsonKey::nlocals].toVariant().toULongLong(); - function.cc = jsonObject[RJsonKey::cc].toVariant().toULongLong(); - function.calltype = jsonObject[RJsonKey::calltype].toString(); - function.name = jsonObject[RJsonKey::name].toString(); - function.edges = jsonObject[RJsonKey::edges].toVariant().toULongLong(); - function.cost = jsonObject[RJsonKey::cost].toVariant().toULongLong(); - function.calls = jsonObject[RJsonKey::outdegree].toVariant().toULongLong(); - function.stackframe = jsonObject[RJsonKey::stackframe].toVariant().toULongLong(); - - ret << function; - } - - return ret; -} - QList CutterCore::getAllFlagspaces() { CORE_LOCK(); diff --git a/src/core/Cutter.h b/src/core/Cutter.h index 96d84edb..3c2d023c 100644 --- a/src/core/Cutter.h +++ b/src/core/Cutter.h @@ -362,7 +362,6 @@ public: const QString &filterType = QString::null); QList parseStringsJson(const QJsonDocument &doc); - QList parseFunctionsJson(const QJsonDocument &doc); void handleREvent(int type, void *data); diff --git a/src/core/CutterDescriptions.h b/src/core/CutterDescriptions.h index 7abba2b9..225bf36f 100644 --- a/src/core/CutterDescriptions.h +++ b/src/core/CutterDescriptions.h @@ -17,12 +17,9 @@ struct FunctionDescription { RVA nargs; RVA nbbs; RVA nlocals; - RVA cc; QString calltype; QString name; RVA edges; - RVA cost; - RVA calls; RVA stackframe; bool contains(RVA addr) const diff --git a/src/widgets/FunctionsWidget.cpp b/src/widgets/FunctionsWidget.cpp index 8bc66b18..2ed96fd4 100644 --- a/src/widgets/FunctionsWidget.cpp +++ b/src/widgets/FunctionsWidget.cpp @@ -132,16 +132,10 @@ QVariant FunctionModel::data(const QModelIndex &index, int role) const case 5: return tr("Nlocals: %1").arg(RSizeString(function.nlocals)); case 6: - return tr("Cyclomatic complexity: %1").arg(RSizeString(function.cc)); - case 7: return tr("Call type: %1").arg(function.calltype); - case 8: + case 7: return tr("Edges: %1").arg(function.edges); - case 9: - return tr("Cost: %1").arg(function.cost); - case 10: - return tr("Calls/OutDegree: %1").arg(function.calls); - case 11: + case 8: return tr("StackFrame: %1").arg(function.stackframe); default: return QVariant(); @@ -158,20 +152,14 @@ QVariant FunctionModel::data(const QModelIndex &index, int role) const return RAddressString(function.offset); case NargsColumn: return function.nargs; - case NbbsColumn: - return function.nbbs; case NlocalsColumn: return function.nlocals; - case CcColumn: - return function.cc; + case NbbsColumn: + return function.nbbs; case CalltypeColumn: return function.calltype; case EdgesColumn: return function.edges; - case CostColumn: - return function.cost; - case CallsColumn: - return function.calls; case FrameColumn: return function.stackframe; default: @@ -267,20 +255,14 @@ QVariant FunctionModel::headerData(int section, Qt::Orientation orientation, int return tr("Offset"); case NargsColumn: return tr("Nargs"); - case NbbsColumn: - return tr("Nbbs"); case NlocalsColumn: return tr("Nlocals"); - case CcColumn: - return tr("Cyclo. Comp."); + case NbbsColumn: + return tr("Nbbs"); case CalltypeColumn: return tr("Call type"); case EdgesColumn: return tr("Edges"); - case CostColumn: - return tr("Cost"); - case CallsColumn: - return tr("Calls/OutDeg."); case FrameColumn: return tr("StackFrame"); default: @@ -402,33 +384,20 @@ bool FunctionSortFilterProxyModel::lessThan(const QModelIndex &left, const QMode if (left_function.nargs != right_function.nargs) return left_function.nargs < right_function.nargs; break; - case FunctionModel::NbbsColumn: - if (left_function.nbbs != right_function.nbbs) - return left_function.nbbs < right_function.nbbs; - break; case FunctionModel::NlocalsColumn: if (left_function.nlocals != right_function.nlocals) return left_function.nlocals < right_function.nlocals; break; - case FunctionModel::CcColumn: - if (left_function.cc != right_function.cc) - return left_function.cc < right_function.cc; + case FunctionModel::NbbsColumn: + if (left_function.nbbs != right_function.nbbs) + return left_function.nbbs < right_function.nbbs; break; case FunctionModel::CalltypeColumn: return left_function.calltype < right_function.calltype; - break; case FunctionModel::EdgesColumn: if (left_function.edges != right_function.edges) return left_function.edges < right_function.edges; break; - case FunctionModel::CostColumn: - if (left_function.cost != right_function.cost) - return left_function.cost < right_function.cost; - break; - case FunctionModel::CallsColumn: - if (left_function.calls != right_function.calls) - return left_function.calls < right_function.calls; - break; case FunctionModel::FrameColumn: if (left_function.stackframe != right_function.stackframe) return left_function.stackframe < right_function.stackframe; diff --git a/src/widgets/FunctionsWidget.h b/src/widgets/FunctionsWidget.h index e82797c4..ac46998e 100644 --- a/src/widgets/FunctionsWidget.h +++ b/src/widgets/FunctionsWidget.h @@ -46,9 +46,8 @@ public: static const int FunctionDescriptionRole = Qt::UserRole; static const int IsImportRole = Qt::UserRole + 1; - enum Column { NameColumn = 0, SizeColumn, ImportColumn, OffsetColumn, NargsColumn, NbbsColumn, - NlocalsColumn, CcColumn, CalltypeColumn, EdgesColumn, CostColumn, CallsColumn, - FrameColumn, ColumnCount + enum Column { NameColumn = 0, SizeColumn, ImportColumn, OffsetColumn, NargsColumn, NlocalsColumn, + NbbsColumn, CalltypeColumn, EdgesColumn, FrameColumn, ColumnCount }; FunctionModel(QList *functions, QSet *importAddresses, ut64 *mainAdress,