From 6ed32d5d1d2fb7f4b9c23c1cad968b14a6f66dc7 Mon Sep 17 00:00:00 2001 From: NIRMAL MANOJ C Date: Wed, 5 Aug 2020 00:33:39 +0530 Subject: [PATCH] Xrefs action for references (#2352) * X-Refs for references (functions, global variables, constant variables with addresses) in the decompiler. --- src/menus/DecompilerContextMenu.cpp | 36 ++++++++++++++++++++++------- src/menus/DecompilerContextMenu.h | 6 +++++ 2 files changed, 34 insertions(+), 8 deletions(-) diff --git a/src/menus/DecompilerContextMenu.cpp b/src/menus/DecompilerContextMenu.cpp index ff1da195..277835d5 100644 --- a/src/menus/DecompilerContextMenu.cpp +++ b/src/menus/DecompilerContextMenu.cpp @@ -3,6 +3,7 @@ #include "MainWindow.h" #include "dialogs/BreakpointsDialog.h" #include "dialogs/CommentsDialog.h" +#include "dialogs/XrefsDialog.h" #include "common/Configuration.h" #include @@ -28,6 +29,7 @@ DecompilerContextMenu::DecompilerContextMenu(QWidget *parent, MainWindow *mainWi actionDeleteComment(tr("Delete comment"), this), actionRenameThingHere(tr("Rename function at cursor"), this), actionDeleteName(tr("Delete "), this), + actionXRefs(tr("Show X-Refs"), this), actionToggleBreakpoint(tr("Add/remove breakpoint"), this), actionAdvancedBreakpoint(tr("Advanced breakpoint"), this), breakpointsInLineMenu(new QMenu(this)), @@ -43,6 +45,8 @@ DecompilerContextMenu::DecompilerContextMenu(QWidget *parent, MainWindow *mainWi setActionAddComment(); setActionDeleteComment(); + setActionXRefs(); + setActionRenameThingHere(); setActionDeleteName(); @@ -129,6 +133,7 @@ void DecompilerContextMenu::aboutToHideSlot() actionAddComment.setVisible(true); actionRenameThingHere.setVisible(true); actionDeleteName.setVisible(false); + actionXRefs.setVisible(true); } void DecompilerContextMenu::aboutToShowSlot() @@ -202,13 +207,7 @@ void DecompilerContextMenu::aboutToShowSlot() } actionCopyInstructionAddress.setText(tr("Copy instruction address (%1)").arg(RAddressString( offset))); - bool isReference = false; - if (annotationHere) { - isReference = (annotationHere->type == R_CODE_ANNOTATION_TYPE_GLOBAL_VARIABLE - || annotationHere->type == R_CODE_ANNOTATION_TYPE_CONSTANT_VARIABLE - || annotationHere->type == R_CODE_ANNOTATION_TYPE_FUNCTION_NAME); - } - if (isReference) { + if (annotationHere && r_annotation_is_reference(annotationHere)) { actionCopyReferenceAddress.setVisible(true); RVA referenceAddr = annotationHere->reference.offset; RFlagItem *flagDetails = r_flag_get_i(Core()->core()->flags, referenceAddr); @@ -222,6 +221,7 @@ void DecompilerContextMenu::aboutToShowSlot() actionCopyReferenceAddress.setText(tr("Copy address (%1)").arg(RAddressString(referenceAddr))); } } else { + actionXRefs.setVisible(false); actionCopyReferenceAddress.setVisible(false); } if (actionShowInSubmenu.menu() != nullptr) { @@ -270,6 +270,13 @@ void DecompilerContextMenu::setActionDeleteComment() addAction(&actionDeleteComment); } +void DecompilerContextMenu::setActionXRefs() +{ + connect(&actionXRefs, &QAction::triggered, this, &DecompilerContextMenu::actionXRefsTriggered); + addAction(&actionXRefs); + actionXRefs.setShortcut(Qt::Key_X); +} + void DecompilerContextMenu::setActionRenameThingHere() { actionRenameThingHere.setShortcut({Qt::Key_N}); @@ -392,6 +399,18 @@ void DecompilerContextMenu::actionDeleteNameTriggered() Core()->delFlag(annotationHere->reference.offset); } +void DecompilerContextMenu::actionXRefsTriggered() +{ + if (!annotationHere || !r_annotation_is_reference(annotationHere)) { + return; + } + XrefsDialog dialog(mainWindow, nullptr); + QString displayString = (annotationHere->type == R_CODE_ANNOTATION_TYPE_FUNCTION_NAME) ? QString( + annotationHere->reference.name) : RAddressString(annotationHere->reference.offset); + dialog.fillRefsForAddress(annotationHere->reference.offset, displayString, false); + dialog.exec(); +} + void DecompilerContextMenu::actionToggleBreakpointTriggered() { if (!this->availableBreakpoints.isEmpty()) { @@ -473,7 +492,8 @@ void DecompilerContextMenu::updateTargetMenuActions() QMenu *menu; if (annotationHere->type == R_CODE_ANNOTATION_TYPE_GLOBAL_VARIABLE || annotationHere->type == R_CODE_ANNOTATION_TYPE_CONSTANT_VARIABLE) { - menu = mainWindow->createShowInMenu(this, annotationHere->reference.offset, MainWindow::AddressTypeHint::Data); + menu = mainWindow->createShowInMenu(this, annotationHere->reference.offset, + MainWindow::AddressTypeHint::Data); RVA var_addr = annotationHere->reference.offset; RFlagItem *flagDetails = r_flag_get_i(core->flags, var_addr); if (flagDetails) { diff --git a/src/menus/DecompilerContextMenu.h b/src/menus/DecompilerContextMenu.h index 5d3c7c37..9f896129 100644 --- a/src/menus/DecompilerContextMenu.h +++ b/src/menus/DecompilerContextMenu.h @@ -42,6 +42,8 @@ private slots: void actionRenameThingHereTriggered(); void actionDeleteNameTriggered(); + void actionXRefsTriggered(); + void actionToggleBreakpointTriggered(); void actionAdvancedBreakpointTriggered(); @@ -73,6 +75,8 @@ private: QAction actionRenameThingHere; QAction actionDeleteName; + QAction actionXRefs; + QMenu *breakpointMenu; QAction actionToggleBreakpoint; QAction actionAdvancedBreakpoint; @@ -96,6 +100,8 @@ private: void setActionAddComment(); void setActionDeleteComment(); + void setActionXRefs(); + void setActionRenameThingHere(); void setActionDeleteName();