Skip to content

Commit

Permalink
add detection for inlined code in disassembly
Browse files Browse the repository at this point in the history
this allows the disassembler to detect inlined functions and hide them
to clean up the disassembler
  • Loading branch information
lievenhey committed Jul 7, 2023
1 parent 136afd8 commit 00c117d
Show file tree
Hide file tree
Showing 9 changed files with 401 additions and 51 deletions.
1 change: 1 addition & 0 deletions src/models/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ add_library(
codedelegate.cpp
costdelegate.cpp
data.cpp
disassemblyentry.cpp
disassemblymodel.cpp
disassemblyoutput.cpp
eventmodel.cpp
Expand Down
112 changes: 112 additions & 0 deletions src/models/disassemblyentry.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/*
SPDX-FileCopyrightText: Lieven Hey <[email protected]>
SPDX-FileCopyrightText: 2023 Klarälvdalens Datakonsult AB, a KDAB Group company, [email protected]
SPDX-License-Identifier: GPL-2.0-or-later
*/

#include "disassemblyentry.h"

DisassemblyEntry::DisassemblyEntry(DisassemblyEntry* parent, const DisassemblyOutput::DisassemblyLine& disassemblyLine,
QTextLine textLine)
: m_parent(parent)
, m_disassemblyLine(disassemblyLine)
, m_textLine(textLine)
{
if (parent) {
m_row = m_parent->childCount();
} else {
m_row = 0;
}
}

DisassemblyEntry* DisassemblyEntry::lastChild()
{
if (m_lines.isEmpty()) {
return nullptr;
}

return &m_lines[m_lines.size() - 1];
}

void DisassemblyEntry::addChild(const DisassemblyEntry& line)
{
m_lines.push_back(line);
}

void DisassemblyEntry::clear()
{
m_lines.clear();
}

bool DisassemblyEntry::operator==(const DisassemblyEntry& other) const
{
return std::tie(m_parent, m_lines, m_disassemblyLine, m_row)
== std::tie(other.m_parent, other.m_lines, other.m_disassemblyLine, other.m_row);
}

int DisassemblyEntry::findOffsetOf(const DisassemblyEntry* entry) const
{
auto found = std::find_if(m_lines.begin(), m_lines.end(),
[needle = entry](const DisassemblyEntry& entry) { return needle == &entry; });

if (found != m_lines.end()) {
return std::distance(m_lines.begin(), found);
}

return -1;
}

DisassemblyEntry::TreeIterator::TreeIterator(const DisassemblyEntry* entry, int child)
: m_entry(const_cast<DisassemblyEntry*>(entry))
, m_child(child)
{
}

DisassemblyEntry& DisassemblyEntry::TreeIterator::operator*() const
{
if (m_entry->childCount() == 0) {
return *m_entry;
}
return *m_entry->child(m_child);
}

DisassemblyEntry* DisassemblyEntry::TreeIterator::operator->() const
{
if (m_entry->childCount() == 0) {
return m_entry;
}
return m_entry->child(m_child);
}

DisassemblyEntry::TreeIterator& DisassemblyEntry::TreeIterator::operator++()
{
if (m_entry->childCount() == 0) {
m_entry++;
return *this;
}

m_child++;

if (m_child >= m_entry->childCount()) {
m_entry++;
m_child = 0;
}

return *this;
}

bool DisassemblyEntry::TreeIterator::operator==(const DisassemblyEntry::TreeIterator other) const
{
return this->m_entry == other.m_entry && this->m_child == other.m_child;
}

DisassemblyEntry::TreeIterator DisassemblyEntry::tree_begin() const
{
return TreeIterator(&m_lines[0], 0);
}

DisassemblyEntry::TreeIterator DisassemblyEntry::tree_end() const
{
return TreeIterator(m_lines.end(), 0);
}
103 changes: 103 additions & 0 deletions src/models/disassemblyentry.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/*
SPDX-FileCopyrightText: Lieven Hey <[email protected]>
SPDX-FileCopyrightText: 2023 Klarälvdalens Datakonsult AB, a KDAB Group company, [email protected]
SPDX-License-Identifier: GPL-2.0-or-later
*/

#pragma once

#include "disassemblyoutput.h"
#include <iterator>
#include <QTextLine>
#include <QVector>

class DisassemblyEntry
{
public:
DisassemblyEntry(DisassemblyEntry* parent, const DisassemblyOutput::DisassemblyLine& disassemblyLine = {},
QTextLine textLine = {});

~DisassemblyEntry() = default;

DisassemblyEntry* parent() const
{
return m_parent;
}

int row() const
{
return m_row;
}

DisassemblyEntry* child(int row)
{
return &m_lines[row];
}

DisassemblyEntry* child(int row) const
{
return const_cast<DisassemblyEntry*>(&m_lines[row]);
}

DisassemblyEntry* lastChild();

DisassemblyOutput::DisassemblyLine disassemblyLine() const
{
return m_disassemblyLine;
}

QTextLine textLine() const
{
return m_textLine;
}

int childCount() const
{
return m_lines.size();
}

void clear();
void addChild(const DisassemblyEntry& line);

bool operator==(const DisassemblyEntry& other) const;

int findOffsetOf(const DisassemblyEntry* entry) const;

// an iterator that will iterate over all children and grandchildren
class TreeIterator : public std::iterator<std::forward_iterator_tag, DisassemblyEntry>
{
public:
TreeIterator(const DisassemblyEntry* entry, int child);
DisassemblyEntry& operator*() const;
DisassemblyEntry* operator->() const;

TreeIterator& operator++();
TreeIterator operator++(int)
{
TreeIterator tmp = *this;
++(*this);
return tmp;
}

bool operator==(const TreeIterator other) const;
bool operator!=(const TreeIterator other) const
{
return !(*this == other);
}

private:
DisassemblyEntry* m_entry = nullptr;
int m_child = -1;
};

TreeIterator tree_begin() const;
TreeIterator tree_end() const;

private:
DisassemblyEntry* m_parent;
QVector<DisassemblyEntry> m_lines;
DisassemblyOutput::DisassemblyLine m_disassemblyLine;
QTextLine m_textLine;
int m_row;
};
Loading

0 comments on commit 00c117d

Please sign in to comment.