Refactor VisualNavbar to use API instead of p-j (#2953)

With the updated rizin, this also fixes any error prints saying
"Cannot alloc for this range" and json errors when no valid range is
available.
This commit is contained in:
Florian Märkl 2022-05-30 13:01:55 +02:00 committed by GitHub
parent 150769cd6b
commit 1914b34fd8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 57 additions and 75 deletions

2
rizin

@ -1 +1 @@
Subproject commit 24524f26b5e4db58a736f702a77e79245148c559 Subproject commit 0950e823a4502677cbf77cfd0266e8de64875fc0

View File

@ -3857,60 +3857,6 @@ QList<SearchDescription> CutterCore::getAllSearch(QString searchFor, QString spa
return searchRef; return searchRef;
} }
BlockStatistics CutterCore::getBlockStatistics(unsigned int blocksCount)
{
BlockStatistics blockStats;
if (blocksCount == 0) {
blockStats.from = blockStats.to = blockStats.blocksize = 0;
return blockStats;
}
CutterJson statsObj;
// User TempConfig here to set the search boundaries to all sections. This makes sure
// that the Visual Navbar will show all the relevant addresses.
{
TempConfig tempConfig;
tempConfig.set("search.in", "bin.sections");
statsObj = cmdj("p-j " + QString::number(blocksCount));
}
blockStats.from = statsObj[RJsonKey::from].toRVA();
blockStats.to = statsObj[RJsonKey::to].toRVA();
blockStats.blocksize = statsObj[RJsonKey::blocksize].toRVA();
for (CutterJson blockObj : statsObj[RJsonKey::blocks]) {
BlockDescription block;
block.addr = blockObj[RJsonKey::offset].toRVA();
block.size = blockObj[RJsonKey::size].toRVA();
block.flags = blockObj[RJsonKey::flags].toSt64();
block.functions = blockObj[RJsonKey::functions].toSt64();
block.inFunctions = blockObj[RJsonKey::in_functions].toSt64();
block.comments = blockObj[RJsonKey::comments].toSt64();
block.symbols = blockObj[RJsonKey::symbols].toSt64();
block.strings = blockObj[RJsonKey::strings].toSt64();
block.rwx = 0;
QString rwxStr = blockObj[RJsonKey::rwx].toString();
if (rwxStr.length() == 3) {
if (rwxStr[0] == 'r') {
block.rwx |= (1 << 0);
}
if (rwxStr[1] == 'w') {
block.rwx |= (1 << 1);
}
if (rwxStr[2] == 'x') {
block.rwx |= (1 << 2);
}
}
blockStats.blocks << block;
}
return blockStats;
}
QList<XrefDescription> CutterCore::getXRefsForVariable(QString variableName, bool findWrites, QList<XrefDescription> CutterCore::getXRefsForVariable(QString variableName, bool findWrites,
RVA offset) RVA offset)
{ {

View File

@ -658,7 +658,6 @@ public:
QList<MemoryMapDescription> getMemoryMap(); QList<MemoryMapDescription> getMemoryMap();
QList<SearchDescription> getAllSearch(QString searchFor, QString space, QString in); QList<SearchDescription> getAllSearch(QString searchFor, QString space, QString in);
BlockStatistics getBlockStatistics(unsigned int blocksCount);
QList<BreakpointDescription> getBreakpoints(); QList<BreakpointDescription> getBreakpoints();
QList<ProcessDescription> getAllProcesses(); QList<ProcessDescription> getAllProcesses();
/** /**

View File

@ -21,7 +21,8 @@ VisualNavbar::VisualNavbar(MainWindow *main, QWidget *parent)
graphicsView(new QGraphicsView), graphicsView(new QGraphicsView),
seekGraphicsItem(nullptr), seekGraphicsItem(nullptr),
PCGraphicsItem(nullptr), PCGraphicsItem(nullptr),
main(main) main(main),
stats(nullptr, rz_core_analysis_stats_free)
{ {
Q_UNUSED(parent); Q_UNUSED(parent);
@ -114,7 +115,34 @@ void VisualNavbar::fetchAndPaintData()
void VisualNavbar::fetchStats() void VisualNavbar::fetchStats()
{ {
stats = Core()->getBlockStatistics(statsWidth); static const ut64 blocksCount = 2048;
RzCoreLocked core(Core());
stats.reset(nullptr);
RzList *list = rz_core_get_boundaries_prot(core, -1, NULL, "search");
if (!list) {
return;
}
RzListIter *iter;
RzIOMap *map;
ut64 from = UT64_MAX;
ut64 to = 0;
CutterRzListForeach (list, iter, RzIOMap, map) {
ut64 f = rz_itv_begin(map->itv);
ut64 t = rz_itv_end(map->itv);
if (f < from) {
from = f;
}
if (t > to) {
to = t;
}
}
rz_list_free(list);
to--; // rz_core_analysis_get_stats takes inclusive ranges
if (to < from) {
return;
}
stats.reset(rz_core_analysis_get_stats(core, from, to, RZ_MAX(1, (to + 1 - from) / blocksCount)));
} }
enum class DataType : int { Empty, Code, String, Symbol, Count }; enum class DataType : int { Empty, Code, String, Symbol, Count };
@ -127,17 +155,18 @@ void VisualNavbar::updateGraphicsScene()
PCGraphicsItem = nullptr; PCGraphicsItem = nullptr;
graphicsScene->setBackgroundBrush(QBrush(Config()->getColor("gui.navbar.empty"))); graphicsScene->setBackgroundBrush(QBrush(Config()->getColor("gui.navbar.empty")));
if (stats.to <= stats.from) { if (!stats) {
return; return;
} }
int w = graphicsView->width(); int w = graphicsView->width();
int h = graphicsView->height(); int h = graphicsView->height();
RVA totalSize = stats.to - stats.from; RVA totalSize = stats->to - stats->from + 1;
RVA beginAddr = stats.from; RVA beginAddr = stats->from;
double widthPerByte = (double)w / (double)totalSize; double widthPerByte = (double)w
/ (double)(totalSize ? totalSize : pow(2.0, 64.0)); // account for overflow on 2^64
auto xFromAddr = [widthPerByte, beginAddr](RVA addr) -> double { auto xFromAddr = [widthPerByte, beginAddr](RVA addr) -> double {
return (addr - beginAddr) * widthPerByte; return (addr - beginAddr) * widthPerByte;
}; };
@ -153,24 +182,28 @@ void VisualNavbar::updateGraphicsScene()
DataType lastDataType = DataType::Empty; DataType lastDataType = DataType::Empty;
QGraphicsRectItem *dataItem = nullptr; QGraphicsRectItem *dataItem = nullptr;
QRectF dataItemRect(0.0, 0.0, 0.0, h); QRectF dataItemRect(0.0, 0.0, 0.0, h);
for (const BlockDescription &block : stats.blocks) { for (size_t i = 0; i < rz_vector_len(&stats->blocks); i++) {
RzCoreAnalysisStatsItem *block =
reinterpret_cast<RzCoreAnalysisStatsItem *>(rz_vector_index_ptr(&stats->blocks, i));
ut64 from = rz_core_analysis_stats_get_block_from(stats.get(), i);
ut64 to = rz_core_analysis_stats_get_block_to(stats.get(), i) + 1;
// Keep track of where which memory segment is mapped so we are able to convert from // Keep track of where which memory segment is mapped so we are able to convert from
// address to X coordinate and vice versa. // address to X coordinate and vice versa.
XToAddress x2a; XToAddress x2a;
x2a.x_start = xFromAddr(block.addr); x2a.x_start = xFromAddr(from);
x2a.x_end = xFromAddr(block.addr + block.size); x2a.x_end = xFromAddr(to);
x2a.address_from = block.addr; x2a.address_from = from;
x2a.address_to = block.addr + block.size; x2a.address_to = to;
xToAddress.append(x2a); xToAddress.append(x2a);
DataType dataType; DataType dataType;
if (block.functions > 0) { if (block->functions) {
dataType = DataType::Code; dataType = DataType::Code;
} else if (block.strings > 0) { } else if (block->strings) {
dataType = DataType::String; dataType = DataType::String;
} else if (block.symbols > 0) { } else if (block->symbols) {
dataType = DataType::Symbol; dataType = DataType::Symbol;
} else if (block.inFunctions > 0) { } else if (block->in_functions) {
dataType = DataType::Code; dataType = DataType::Code;
} else { } else {
lastDataType = DataType::Empty; lastDataType = DataType::Empty;
@ -178,7 +211,7 @@ void VisualNavbar::updateGraphicsScene()
} }
if (dataType == lastDataType) { if (dataType == lastDataType) {
double r = xFromAddr(block.addr + block.size); double r = xFromAddr(to);
if (r > dataItemRect.right()) { if (r > dataItemRect.right()) {
dataItemRect.setRight(r); dataItemRect.setRight(r);
dataItem->setRect(dataItemRect); dataItem->setRect(dataItemRect);
@ -187,8 +220,8 @@ void VisualNavbar::updateGraphicsScene()
continue; continue;
} }
dataItemRect.setX(xFromAddr(block.addr)); dataItemRect.setX(xFromAddr(from));
dataItemRect.setRight(xFromAddr(block.addr + block.size)); dataItemRect.setRight(xFromAddr(to));
dataItem = new QGraphicsRectItem(); dataItem = new QGraphicsRectItem();
dataItem->setPen(Qt::NoPen); dataItem->setPen(Qt::NoPen);

View File

@ -6,6 +6,10 @@
#include "core/Cutter.h" #include "core/Cutter.h"
#include <rz_core.h>
#include <memory>
class MainWindow; class MainWindow;
class QGraphicsView; class QGraphicsView;
@ -43,7 +47,7 @@ private:
QGraphicsRectItem *PCGraphicsItem; QGraphicsRectItem *PCGraphicsItem;
MainWindow *main; MainWindow *main;
BlockStatistics stats; std::unique_ptr<RzCoreAnalysisStats, decltype(&rz_core_analysis_stats_free)> stats;
unsigned int statsWidth = 0; unsigned int statsWidth = 0;
unsigned int previousWidth = 0; unsigned int previousWidth = 0;