Make use of new RzType API in Rizin

This commit is contained in:
Riccardo Schirone 2021-09-07 11:12:07 +02:00 committed by Florian Märkl
parent 62ecf3fb2a
commit f42069369c
6 changed files with 67 additions and 124 deletions

2
rizin

@ -1 +1 @@
Subproject commit 254c5119e3563d05d02665cabbcba003c921cee8 Subproject commit c9f9aea2924d2f086b5a6b1ed0216b531faea125

View File

@ -3519,145 +3519,88 @@ QList<TypeDescription> CutterCore::getAllTypes()
return types; return types;
} }
QList<TypeDescription> CutterCore::getAllPrimitiveTypes() QList<TypeDescription> CutterCore::getBaseType(RzBaseTypeKind kind, const char *category)
{ {
CORE_LOCK(); CORE_LOCK();
QList<TypeDescription> primitiveTypes; QList<TypeDescription> types;
QJsonArray typesArray = cmdj("tj").array(); RzList *ts = rz_type_db_get_base_types_of_kind(core->analysis->typedb, kind);
for (const QJsonValue &value : typesArray) { RzBaseType *type;
QJsonObject typeObject = value.toObject(); RzListIter *iter;
CutterRListForeach (ts, iter, RzBaseType, type) {
TypeDescription exp; TypeDescription exp;
exp.type = typeObject[RJsonKey::type].toString(); exp.type = type->name;
exp.size = typeObject[RJsonKey::size].toVariant().toULongLong(); exp.size = rz_type_db_base_get_bitsize(core->analysis->typedb, type);
exp.format = typeObject[RJsonKey::format].toString(); exp.format = rz_type_format(core->analysis->typedb, type->name);
exp.category = tr("Primitive"); exp.category = tr(category);
primitiveTypes << exp; types << exp;
} }
rz_list_free(ts);
return primitiveTypes; return types;
}
QList<TypeDescription> CutterCore::getAllPrimitiveTypes()
{
return getBaseType(RZ_BASE_TYPE_KIND_ATOMIC, "Primitive");
} }
QList<TypeDescription> CutterCore::getAllUnions() QList<TypeDescription> CutterCore::getAllUnions()
{ {
CORE_LOCK(); return getBaseType(RZ_BASE_TYPE_KIND_UNION, "Union");
QList<TypeDescription> 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;
} }
QList<TypeDescription> CutterCore::getAllStructs() QList<TypeDescription> CutterCore::getAllStructs()
{ {
CORE_LOCK(); return getBaseType(RZ_BASE_TYPE_KIND_STRUCT, "Struct");
QList<TypeDescription> 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;
} }
QList<TypeDescription> CutterCore::getAllEnums() QList<TypeDescription> CutterCore::getAllEnums()
{ {
CORE_LOCK(); return getBaseType(RZ_BASE_TYPE_KIND_ENUM, "Enum");
QList<TypeDescription> 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;
} }
QList<TypeDescription> CutterCore::getAllTypedefs() QList<TypeDescription> CutterCore::getAllTypedefs()
{ {
CORE_LOCK(); return getBaseType(RZ_BASE_TYPE_KIND_TYPEDEF, "Typedef");
QList<TypeDescription> 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;
} }
QString CutterCore::addTypes(const char *str) QString CutterCore::addTypes(const char *str)
{ {
CORE_LOCK(); CORE_LOCK();
char *error_msg = nullptr; 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; QString error;
if (!parsed) { if (!parsed && error_msg) {
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) {
error = error_msg; error = error_msg;
rz_mem_free(error_msg); rz_mem_free(error_msg);
} else if (!parsed) {
error = QString("Failed to load new type %1").arg(str);
} }
return error; return error;
} }
QString CutterCore::getTypeAsC(QString name, QString category) QString CutterCore::getTypeAsC(QString name)
{ {
CORE_LOCK(); CORE_LOCK();
QString output = "Failed to fetch the output."; QString output = "Failed to fetch the output.";
if (name.isEmpty() || category.isEmpty()) { if (name.isEmpty()) {
return output; return output;
} }
QString typeName = sanitizeStringForCommand(name); char *earg = rz_cmd_escape_arg(name.toUtf8().constData(), RZ_CMD_ESCAPE_ONE_ARG);
if (category == "Struct") { // TODO: use API for `tc` command once available
output = cmdRaw(QString("tsc %1").arg(typeName)); QString result = cmd(QString("tc %1").arg(earg));
} else if (category == "Union") { free(earg);
output = cmdRaw(QString("tuc %1").arg(typeName)); return result;
} else if (category == "Enum") { }
output = cmdRaw(QString("tec %1").arg(typeName));
} else if (category == "Typedef") { bool CutterCore::deleteType(const char *typeName) {
output = cmdRaw(QString("ttc %1").arg(typeName)); CORE_LOCK();
} return rz_type_db_del(core->analysis->typedb, typeName);
return output;
} }
bool CutterCore::isAddressMapped(RVA addr) bool CutterCore::isAddressMapped(RVA addr)

View File

@ -590,11 +590,10 @@ public:
/** /**
* @brief Fetching the C representation of a given Type * @brief Fetching the C representation of a given Type
* @param name - the name or the type of the given Type / Struct * @param name - the name or the type of the given Type
* @param category - the category of the given Type (Struct, Union, Enum, ...)
* @return The type decleration as C output * @return The type decleration as C output
*/ */
QString getTypeAsC(QString name, QString category); QString getTypeAsC(QString name);
/** /**
* @brief Adds new types * @brief Adds new types
@ -608,6 +607,13 @@ public:
QString addTypes(const char *str); QString addTypes(const char *str);
QString addTypes(const QString &str) { return addTypes(str.toUtf8().constData()); } 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 * @brief Checks if the given address is mapped to a region
* @param addr The address to be checked * @param addr The address to be checked
@ -788,6 +794,7 @@ private:
RizinTaskDialog *debugTaskDialog; RizinTaskDialog *debugTaskDialog;
QVector<QString> getCutterRCFilePaths() const; QVector<QString> getCutterRCFilePaths() const;
QList<TypeDescription> getBaseType(RzBaseTypeKind kind, const char *category);
}; };
class CUTTER_EXPORT RzCoreLocked class CUTTER_EXPORT RzCoreLocked

View File

@ -84,26 +84,18 @@ void EditVariablesDialog::updateFields()
ui->typeComboBox->setCurrentText(desc.type); ui->typeComboBox->setCurrentText(desc.type);
} }
static void addTypeDescriptionsToComboBox(QComboBox *comboBox, QList<TypeDescription> list) {
for (const TypeDescription &thisType : list) {
comboBox->addItem(thisType.type);
}
comboBox->insertSeparator(comboBox->count());
}
void EditVariablesDialog::populateTypesComboBox() 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<TypeDescription> 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);
} }

View File

@ -76,7 +76,7 @@ QVariant TypesModel::headerData(int section, Qt::Orientation, int role) const
bool TypesModel::removeRows(int row, int count, const QModelIndex &parent) 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); beginRemoveRows(parent, row, row + count - 1);
while (count--) { while (count--) {
types->removeAt(row); types->removeAt(row);
@ -275,7 +275,8 @@ void TypesWidget::on_actionExport_Types_triggered()
return; return;
} }
QTextStream fileOut(&file); QTextStream fileOut(&file);
fileOut << Core()->cmdRaw("tc"); // TODO: use API for `tc` command once available
fileOut << Core()->cmd("tc");
file.close(); file.close();
} }
@ -304,7 +305,7 @@ void TypesWidget::viewType(bool readOnly)
} else { } else {
dialog.setWindowTitle(tr("View Type: ") + t.type + tr(" (Read Only)")); 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(); dialog.exec();
} }
@ -351,7 +352,7 @@ void TypesWidget::typeItemDoubleClicked(const QModelIndex &index)
if (t.category == "Primitive") { if (t.category == "Primitive") {
return; 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.setWindowTitle(tr("View Type: ") + t.type + tr(" (Read Only)"));
dialog.exec(); dialog.exec();
} }

View File

@ -31,7 +31,7 @@ private:
QList<TypeDescription> *types; QList<TypeDescription> *types;
public: public:
enum Columns { TYPE = 0, SIZE, FORMAT, CATEGORY, COUNT }; enum Columns { TYPE = 0, SIZE, CATEGORY, FORMAT, COUNT };
static const int TypeDescriptionRole = Qt::UserRole; static const int TypeDescriptionRole = Qt::UserRole;
TypesModel(QList<TypeDescription> *types, QObject *parent = nullptr); TypesModel(QList<TypeDescription> *types, QObject *parent = nullptr);
@ -81,7 +81,7 @@ private slots:
/** /**
* @brief Executed on clicking the Export Types option in the context menu * @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 * 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(); void on_actionExport_Types_triggered();