From f42069369cc718b20c205f9b7653a1e04aad689f Mon Sep 17 00:00:00 2001 From: Riccardo Schirone Date: Tue, 7 Sep 2021 11:12:07 +0200 Subject: [PATCH] Make use of new RzType API in Rizin --- rizin | 2 +- src/core/Cutter.cpp | 133 ++++++++-------------------- src/core/Cutter.h | 13 ++- src/dialogs/EditVariablesDialog.cpp | 30 +++---- src/widgets/TypesWidget.cpp | 9 +- src/widgets/TypesWidget.h | 4 +- 6 files changed, 67 insertions(+), 124 deletions(-) diff --git a/rizin b/rizin index 254c5119..c9f9aea2 160000 --- a/rizin +++ b/rizin @@ -1 +1 @@ -Subproject commit 254c5119e3563d05d02665cabbcba003c921cee8 +Subproject commit c9f9aea2924d2f086b5a6b1ed0216b531faea125 diff --git a/src/core/Cutter.cpp b/src/core/Cutter.cpp index f6dbcda6..79192f8a 100644 --- a/src/core/Cutter.cpp +++ b/src/core/Cutter.cpp @@ -3519,145 +3519,88 @@ QList CutterCore::getAllTypes() return types; } -QList CutterCore::getAllPrimitiveTypes() +QList CutterCore::getBaseType(RzBaseTypeKind kind, const char *category) { CORE_LOCK(); - QList primitiveTypes; + QList types; - QJsonArray typesArray = cmdj("tj").array(); - for (const QJsonValue &value : typesArray) { - QJsonObject typeObject = value.toObject(); + RzList *ts = rz_type_db_get_base_types_of_kind(core->analysis->typedb, kind); + RzBaseType *type; + RzListIter *iter; + CutterRListForeach (ts, iter, RzBaseType, type) { TypeDescription exp; - exp.type = typeObject[RJsonKey::type].toString(); - exp.size = typeObject[RJsonKey::size].toVariant().toULongLong(); - exp.format = typeObject[RJsonKey::format].toString(); - exp.category = tr("Primitive"); - primitiveTypes << exp; + exp.type = type->name; + exp.size = rz_type_db_base_get_bitsize(core->analysis->typedb, type); + exp.format = rz_type_format(core->analysis->typedb, type->name); + exp.category = tr(category); + types << exp; } + rz_list_free(ts); - return primitiveTypes; + return types; +} + +QList CutterCore::getAllPrimitiveTypes() +{ + return getBaseType(RZ_BASE_TYPE_KIND_ATOMIC, "Primitive"); } QList CutterCore::getAllUnions() { - CORE_LOCK(); - QList unions; - - QJsonArray typesArray = cmdj("tuj").array(); - for (const QJsonValue value : typesArray) { - QJsonObject typeObject = value.toObject(); - - TypeDescription exp; - - exp.type = typeObject[RJsonKey::type].toString(); - exp.size = typeObject[RJsonKey::size].toVariant().toULongLong(); - exp.category = "Union"; - unions << exp; - } - - return unions; + return getBaseType(RZ_BASE_TYPE_KIND_UNION, "Union"); } QList CutterCore::getAllStructs() { - CORE_LOCK(); - QList structs; - - QJsonArray typesArray = cmdj("tsj").array(); - for (const QJsonValue value : typesArray) { - QJsonObject typeObject = value.toObject(); - - TypeDescription exp; - - exp.type = typeObject[RJsonKey::type].toString(); - exp.size = typeObject[RJsonKey::size].toVariant().toULongLong(); - exp.category = "Struct"; - structs << exp; - } - - return structs; + return getBaseType(RZ_BASE_TYPE_KIND_STRUCT, "Struct"); } QList CutterCore::getAllEnums() { - CORE_LOCK(); - QList enums; - - QJsonObject typesObject = cmdj("tej").object(); - for (QString key : typesObject.keys()) { - TypeDescription exp; - exp.type = key; - exp.size = 0; - exp.category = "Enum"; - enums << exp; - } - - return enums; + return getBaseType(RZ_BASE_TYPE_KIND_ENUM, "Enum"); } QList CutterCore::getAllTypedefs() { - CORE_LOCK(); - QList typeDefs; - - QJsonObject typesObject = cmdj("ttj").object(); - for (QString key : typesObject.keys()) { - TypeDescription exp; - exp.type = key; - exp.size = 0; - exp.category = "Typedef"; - typeDefs << exp; - } - - return typeDefs; + return getBaseType(RZ_BASE_TYPE_KIND_TYPEDEF, "Typedef"); } QString CutterCore::addTypes(const char *str) { CORE_LOCK(); char *error_msg = nullptr; - char *parsed = rz_type_parse_c_string(core->analysis->typedb, str, &error_msg); + int parsed = rz_type_parse_string(core->analysis->typedb, str, &error_msg); QString error; - if (!parsed) { - if (error_msg) { - error = error_msg; - rz_mem_free(error_msg); - } - return error; - } - - rz_type_db_save_parsed_type(core->analysis->typedb, parsed); - rz_mem_free(parsed); - - if (error_msg) { + if (!parsed && error_msg) { error = error_msg; rz_mem_free(error_msg); + } else if (!parsed) { + error = QString("Failed to load new type %1").arg(str); } return error; } -QString CutterCore::getTypeAsC(QString name, QString category) +QString CutterCore::getTypeAsC(QString name) { CORE_LOCK(); QString output = "Failed to fetch the output."; - if (name.isEmpty() || category.isEmpty()) { + if (name.isEmpty()) { return output; } - QString typeName = sanitizeStringForCommand(name); - if (category == "Struct") { - output = cmdRaw(QString("tsc %1").arg(typeName)); - } else if (category == "Union") { - output = cmdRaw(QString("tuc %1").arg(typeName)); - } else if (category == "Enum") { - output = cmdRaw(QString("tec %1").arg(typeName)); - } else if (category == "Typedef") { - output = cmdRaw(QString("ttc %1").arg(typeName)); - } - return output; + char *earg = rz_cmd_escape_arg(name.toUtf8().constData(), RZ_CMD_ESCAPE_ONE_ARG); + // TODO: use API for `tc` command once available + QString result = cmd(QString("tc %1").arg(earg)); + free(earg); + return result; +} + +bool CutterCore::deleteType(const char *typeName) { + CORE_LOCK(); + return rz_type_db_del(core->analysis->typedb, typeName); } bool CutterCore::isAddressMapped(RVA addr) diff --git a/src/core/Cutter.h b/src/core/Cutter.h index c9245b74..375943d1 100644 --- a/src/core/Cutter.h +++ b/src/core/Cutter.h @@ -590,11 +590,10 @@ public: /** * @brief Fetching the C representation of a given Type - * @param name - the name or the type of the given Type / Struct - * @param category - the category of the given Type (Struct, Union, Enum, ...) + * @param name - the name or the type of the given Type * @return The type decleration as C output */ - QString getTypeAsC(QString name, QString category); + QString getTypeAsC(QString name); /** * @brief Adds new types @@ -608,6 +607,13 @@ public: QString addTypes(const char *str); QString addTypes(const QString &str) { return addTypes(str.toUtf8().constData()); } + /** + * @brief Remove a type + * @param typeName Name of the type to remove + */ + bool deleteType(const char *typeName); + bool deleteType(QString typeName) { return deleteType(typeName.toUtf8().constData()); } + /** * @brief Checks if the given address is mapped to a region * @param addr The address to be checked @@ -788,6 +794,7 @@ private: RizinTaskDialog *debugTaskDialog; QVector getCutterRCFilePaths() const; + QList getBaseType(RzBaseTypeKind kind, const char *category); }; class CUTTER_EXPORT RzCoreLocked diff --git a/src/dialogs/EditVariablesDialog.cpp b/src/dialogs/EditVariablesDialog.cpp index fe50bc38..08966071 100644 --- a/src/dialogs/EditVariablesDialog.cpp +++ b/src/dialogs/EditVariablesDialog.cpp @@ -84,26 +84,18 @@ void EditVariablesDialog::updateFields() ui->typeComboBox->setCurrentText(desc.type); } +static void addTypeDescriptionsToComboBox(QComboBox *comboBox, QList list) { + for (const TypeDescription &thisType : list) { + comboBox->addItem(thisType.type); + } + comboBox->insertSeparator(comboBox->count()); +} + void EditVariablesDialog::populateTypesComboBox() { - // gets all loaded types, structures and enums and puts them in a list + addTypeDescriptionsToComboBox(ui->typeComboBox, Core()->getAllStructs()); + addTypeDescriptionsToComboBox(ui->typeComboBox, Core()->getAllPrimitiveTypes()); + addTypeDescriptionsToComboBox(ui->typeComboBox, Core()->getAllEnums()); + addTypeDescriptionsToComboBox(ui->typeComboBox, Core()->getAllTypedefs()); - QStringList userStructures; - QStringList userEnumerations; - QList primitiveTypesTypeList; - - userStructures = Core()->cmdList("ts"); - ui->typeComboBox->addItems(userStructures); - ui->typeComboBox->insertSeparator(ui->typeComboBox->count()); - - primitiveTypesTypeList = Core()->getAllPrimitiveTypes(); - - for (const TypeDescription &thisType : primitiveTypesTypeList) { - ui->typeComboBox->addItem(thisType.type); - } - - ui->typeComboBox->insertSeparator(ui->typeComboBox->count()); - - userEnumerations = Core()->cmdList("te"); - ui->typeComboBox->addItems(userEnumerations); } diff --git a/src/widgets/TypesWidget.cpp b/src/widgets/TypesWidget.cpp index 91cf9551..c9963c79 100644 --- a/src/widgets/TypesWidget.cpp +++ b/src/widgets/TypesWidget.cpp @@ -76,7 +76,7 @@ QVariant TypesModel::headerData(int section, Qt::Orientation, int role) const bool TypesModel::removeRows(int row, int count, const QModelIndex &parent) { - Core()->cmdRaw("t-" + types->at(row).type); + Core()->deleteType(types->at(row).type); beginRemoveRows(parent, row, row + count - 1); while (count--) { types->removeAt(row); @@ -275,7 +275,8 @@ void TypesWidget::on_actionExport_Types_triggered() return; } QTextStream fileOut(&file); - fileOut << Core()->cmdRaw("tc"); + // TODO: use API for `tc` command once available + fileOut << Core()->cmd("tc"); file.close(); } @@ -304,7 +305,7 @@ void TypesWidget::viewType(bool readOnly) } else { dialog.setWindowTitle(tr("View Type: ") + t.type + tr(" (Read Only)")); } - dialog.fillTextArea(Core()->getTypeAsC(t.type, t.category)); + dialog.fillTextArea(Core()->getTypeAsC(t.type)); dialog.exec(); } @@ -351,7 +352,7 @@ void TypesWidget::typeItemDoubleClicked(const QModelIndex &index) if (t.category == "Primitive") { return; } - dialog.fillTextArea(Core()->getTypeAsC(t.type, t.category)); + dialog.fillTextArea(Core()->getTypeAsC(t.type)); dialog.setWindowTitle(tr("View Type: ") + t.type + tr(" (Read Only)")); dialog.exec(); } diff --git a/src/widgets/TypesWidget.h b/src/widgets/TypesWidget.h index ddddeb09..e567a146 100644 --- a/src/widgets/TypesWidget.h +++ b/src/widgets/TypesWidget.h @@ -31,7 +31,7 @@ private: QList *types; public: - enum Columns { TYPE = 0, SIZE, FORMAT, CATEGORY, COUNT }; + enum Columns { TYPE = 0, SIZE, CATEGORY, FORMAT, COUNT }; static const int TypeDescriptionRole = Qt::UserRole; TypesModel(QList *types, QObject *parent = nullptr); @@ -81,7 +81,7 @@ private slots: /** * @brief Executed on clicking the Export Types option in the context menu * It shows the user a file dialog box to select a file where the types - * will be exported. It uses the "tc" command of Rizin to export the types. + * will be exported. */ void on_actionExport_Types_triggered();