Skip to content
Permalink
Browse files

Sanitized ListingItemModel

  • Loading branch information...
Dax89 committed May 16, 2019
1 parent cee653e commit 9da545603be60621fdcc828c1d024dd8e3531044
@@ -9,7 +9,9 @@ set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTORCC ON)

option(DEBUG_STL_ITERATORS "Enable iterator debugging in Debug mode (GCC only)" OFF)
option(DEBUG_STL_ITERATORS "Enable iterator debugging in Debug mode (GCC only)" OFF)
option(ENABLE_ADDRESS_SANITIZER "Enable Address Sanitizer" OFF)
option(ENABLE_THREAD_SANITIZER "Enable Thread Sanitizer" OFF)

string(TIMESTAMP REDASM_BUILD_TIMESTAMP "%Y%m%d")
set(REDASM_GIT_VERSION "unknown")
@@ -135,6 +137,16 @@ elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
target_compile_options(${PROJECT_NAME} PRIVATE -Wall -Wno-missing-braces)
endif()

if(CMAKE_BUILD_TYPE MATCHES "Debug")
if(ENABLE_ADDRESS_SANITIZER)
target_compile_options(${PROJECT_NAME} PRIVATE -fsanitize=address -fno-omit-frame-pointer)
target_link_options(${PROJECT_NAME} PRIVATE -fsanitize=address -fno-omit-frame-pointer)
elseif(ENABLE_THREAD_SANITIZER)
target_compile_options(${PROJECT_NAME} PRIVATE -fsanitize=thread -fno-omit-frame-pointer)
target_link_options(${PROJECT_NAME} PRIVATE -fsanitize=thread -fno-omit-frame-pointer)
endif()
endif()

# Post build commands
set(LIBREDASM_BIN ${CMAKE_BINARY_DIR}/LibREDasm/LibREDasm${CMAKE_SHARED_LIBRARY_SUFFIX})
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${LIBREDASM_BIN} ${CMAKE_BINARY_DIR})
@@ -19,7 +19,7 @@ ReferencesDialog::~ReferencesDialog() { delete ui; }

void ReferencesDialog::on_tvReferences_doubleClicked(const QModelIndex &index)
{
if(!index.isValid() || !index.internalPointer())
if(!index.isValid() || !index.internalId())
return;

emit jumpTo(index.internalId());
@@ -10,7 +10,10 @@ QVariant GotoModel::data(const QModelIndex &index, int role) const
if(!m_disassembler)
return QVariant();

const REDasm::ListingItem* item = reinterpret_cast<const REDasm::ListingItem*>(index.internalPointer());
const REDasm::ListingItem* item = this->item(index);

if(!item)
return QVariant();

if(role == Qt::DisplayRole)
{
@@ -4,7 +4,8 @@

ListingFilterModel::ListingFilterModel(QObject *parent) : QIdentityProxyModel(parent) { }
const QString &ListingFilterModel::filter() const { return m_filterstring; }
void ListingFilterModel::setDisassembler(const REDasm::DisassemblerPtr& disassembler) { reinterpret_cast<ListingItemModel*>(this->sourceModel())->setDisassembler(disassembler); }
const REDasm::ListingItem *ListingFilterModel::item(const QModelIndex &index) const { return static_cast<ListingItemModel*>(this->sourceModel())->item(this->mapToSource(index)); }
void ListingFilterModel::setDisassembler(const REDasm::DisassemblerPtr& disassembler) { static_cast<ListingItemModel*>(this->sourceModel())->setDisassembler(disassembler); }

void ListingFilterModel::setFilter(const QString &filter)
{
@@ -40,16 +41,21 @@ QModelIndex ListingFilterModel::index(int row, int column, const QModelIndex&) c
if(m_filtereditems.empty())
return QModelIndex();

return this->createIndex(row, column, m_filtereditems[row]);
return this->createIndex(row, column);
}

QModelIndex ListingFilterModel::mapFromSource(const QModelIndex &sourceindex) const
{
if(!this->canFilter() || !sourceindex.isValid())
return QIdentityProxyModel::mapFromSource(sourceindex);

REDasm::ListingItem* item = reinterpret_cast<REDasm::ListingItem*>(sourceindex.internalPointer());
size_t idx = m_filtereditems.indexOf(item);
ListingItemModel* listingitemmodel = reinterpret_cast<ListingItemModel*>(this->sourceModel());
auto location = listingitemmodel->address(sourceindex);

if(!location.valid)
return QModelIndex();

size_t idx = m_filtereditems.indexOf(location);

if(idx == REDasm::npos)
return QModelIndex();
@@ -63,8 +69,7 @@ QModelIndex ListingFilterModel::mapToSource(const QModelIndex &proxyindex) const
return QIdentityProxyModel::mapToSource(proxyindex);

ListingItemModel* listingitemmodel = reinterpret_cast<ListingItemModel*>(this->sourceModel());
REDasm::ListingItem* item = reinterpret_cast<REDasm::ListingItem*>(proxyindex.internalPointer());
size_t idx = listingitemmodel->m_items.indexOf(item);
size_t idx = listingitemmodel->m_items.indexOf(m_filtereditems[proxyindex.row()]);

if(idx == REDasm::npos)
return QModelIndex();
@@ -79,19 +84,19 @@ void ListingFilterModel::updateFiltering()

if(this->canFilter())
{
QAbstractItemModel* sourcemodel = this->sourceModel();
ListingItemModel* listingitemmodel = reinterpret_cast<ListingItemModel*>(this->sourceModel());

for(int i = 0; i < sourcemodel->rowCount(); i++)
for(int i = 0; i < listingitemmodel->rowCount(); i++)
{
for(int j = 0; j < sourcemodel->columnCount(); j++)
for(int j = 0; j < listingitemmodel->columnCount(); j++)
{
QModelIndex index = sourcemodel->index(i, j);
QVariant data = sourcemodel->data(index);
QModelIndex index = listingitemmodel->index(i, j);
QVariant data = listingitemmodel->data(index);

if((data.type() != QVariant::String) || (data.toString().indexOf(m_filterstring, 0, Qt::CaseInsensitive) == -1))
continue;

m_filtereditems.append(reinterpret_cast<REDasm::ListingItem*>(index.internalPointer()));
m_filtereditems.push_back(listingitemmodel->address(index));
break;
}
}
@@ -11,6 +11,7 @@ class ListingFilterModel : public QIdentityProxyModel
public:
explicit ListingFilterModel(QObject *parent = nullptr);
const QString& filter() const;
const REDasm::ListingItem* item(const QModelIndex& index) const;
void setDisassembler(const REDasm::DisassemblerPtr &disassembler);
void setFilter(const QString& filter);
void clearFilter();
@@ -30,7 +31,7 @@ class ListingFilterModel : public QIdentityProxyModel
template<typename T> static ListingFilterModel* createFilter(size_t filter, QObject* parent);

private:
QVector<REDasm::ListingItem*> m_filtereditems;
QList<address_t> m_filtereditems;
QString m_filterstring;
};

@@ -19,22 +19,53 @@ void ListingItemModel::setDisassembler(const REDasm::DisassemblerPtr& disassembl
if(!this->isItemAllowed(it->get()))
continue;

m_items.insert(it->get());
m_items.insert((*it)->address);
}

this->endResetModel();

EVENT_CONNECT(document, changed, this, std::bind(&ListingItemModel::onListingChanged, this, std::placeholders::_1));
}

const REDasm::ListingItem *ListingItemModel::item(const QModelIndex &index) const
{
if(!index.isValid() || (index.row() >= m_items.size()))
return nullptr;

auto lock = REDasm::s_lock_safe_ptr(m_disassembler->document());
REDasm::ListingDocumentType::const_iterator it = lock->end();

if(m_itemtype == REDasm::ListingItem::SegmentItem)
it = lock->segmentItem(m_items[index.row()]);
else if(m_itemtype == REDasm::ListingItem::FunctionItem)
it = lock->functionItem(m_items[index.row()]);
else
{
it = lock->instructionItem(m_items[index.row()]); // Try to get an instruction

if(it == lock->end())
it = lock->symbolItem(m_items[index.row()]); // Try to get an symbol
}

return (it != lock->end()) ? it->get() : nullptr;
}

address_location ListingItemModel::address(const QModelIndex &index) const
{
if(!index.isValid() || (index.row() < 0) || (index.row() >= m_items.size()))
return REDasm::invalid_location<address_t>();

return REDasm::make_location(m_items[index.row()]);
}

QModelIndex ListingItemModel::index(int row, int column, const QModelIndex &parent) const
{
Q_UNUSED(parent)

if((row < 0) || (row >= m_items.size()))
return QModelIndex();

return this->createIndex(row, column, const_cast<REDasm::ListingItem*>(m_items[row]));
return this->createIndex(row, column);
}

int ListingItemModel::rowCount(const QModelIndex &) const { return m_items.size(); }
@@ -65,9 +96,8 @@ QVariant ListingItemModel::data(const QModelIndex &index, int role) const
if(!index.isValid())
return QVariant();

REDasm::ListingItem* item = reinterpret_cast<REDasm::ListingItem*>(index.internalPointer());
auto lock = REDasm::x_lock_safe_ptr(m_disassembler->document());
const REDasm::Symbol* symbol = lock->symbol(item->address);
auto lock = REDasm::s_lock_safe_ptr(m_disassembler->document());
const REDasm::Symbol* symbol = lock->symbol(m_items[index.row()]);

if(!symbol)
return QVariant();
@@ -132,16 +162,16 @@ void ListingItemModel::onListingChanged(const REDasm::ListingDocumentChanged *ld

if(ldc->isRemoved())
{
int idx = static_cast<int>(m_items.indexOf(ldc->item));
int idx = static_cast<int>(m_items.indexOf(ldc->item->address));
this->beginRemoveRows(QModelIndex(), idx, idx);
m_items.erase(static_cast<size_t>(idx));
m_items.eraseAt(static_cast<size_t>(idx));
this->endRemoveRows();
}
else if(ldc->isInserted())
{
int idx = static_cast<int>(m_items.insertionIndex(ldc->item));
int idx = static_cast<int>(m_items.insertionIndex(ldc->item->address));
this->beginInsertRows(QModelIndex(), idx, idx);
m_items.insert(ldc->item);
m_items.insert(ldc->item->address);
this->endInsertRows();
}
}
@@ -12,22 +12,24 @@ class ListingItemModel : public DisassemblerModel
public:
explicit ListingItemModel(size_t itemtype, QObject *parent = nullptr);
void setDisassembler(const REDasm::DisassemblerPtr &disassembler) override;
const REDasm::ListingItem* item(const QModelIndex& index) const;
address_location address(const QModelIndex& index) const;

public:
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
int rowCount(const QModelIndex& = QModelIndex()) const override;
int columnCount(const QModelIndex& = QModelIndex()) const override;
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
QVariant data(const QModelIndex &index, int role) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;

protected:
virtual bool isItemAllowed(const REDasm::ListingItem *item) const;

private:
private slots:
void onListingChanged(const REDasm::ListingDocumentChanged *ldc);

private:
REDasm::ListingItemConstContainer m_items;
REDasm::sorted_container<address_t> m_items;
size_t m_itemtype;

friend class ListingFilterModel;
@@ -219,7 +219,7 @@ void DisassemblerView::updateCurrentFilter(int index)

void DisassemblerView::gotoXRef(const QModelIndex &index)
{
if(!index.isValid() || !index.internalPointer())
if(!index.isValid() || !index.internalId())
return;

ui->tabView->setCurrentWidget(ui->tabListing);
@@ -228,10 +228,15 @@ void DisassemblerView::gotoXRef(const QModelIndex &index)

void DisassemblerView::goTo(const QModelIndex &index)
{
if(!index.isValid() || !index.internalPointer())
if(!index.isValid())
return;

m_disassembler->document()->goTo(reinterpret_cast<REDasm::ListingItem*>(index.internalPointer()));
const REDasm::ListingItem* item = this->itemFromIndex(index);

if(!item)
return;

m_disassembler->document()->goTo(item);

if(!m_graphview->isCursorInGraph())
ui->stackedWidget->setCurrentWidget(m_listingview);
@@ -241,16 +246,13 @@ void DisassemblerView::goTo(const QModelIndex &index)

void DisassemblerView::showModelReferences()
{
if(!m_currentindex.isValid() || !m_currentindex.internalPointer())
if(!m_currentindex.isValid())
return;

REDasm::ListingItem* item = nullptr;
const QAbstractProxyModel* proxymodel = dynamic_cast<const QAbstractProxyModel*>(m_currentindex.model());
const REDasm::ListingItem* item = this->itemFromIndex(m_currentindex);

if(proxymodel)
item = reinterpret_cast<REDasm::ListingItem*>(proxymodel->mapToSource(m_currentindex).internalPointer());
else
item = reinterpret_cast<REDasm::ListingItem*>(m_currentindex.internalPointer());
if(!item)
return;

const REDasm::Symbol* symbol = nullptr;

@@ -475,6 +477,16 @@ void DisassemblerView::showGoto()
void DisassemblerView::goForward() { m_disassembler->document()->cursor()->goForward(); }
void DisassemblerView::goBack() { m_disassembler->document()->cursor()->goBack(); }

const REDasm::ListingItem *DisassemblerView::itemFromIndex(const QModelIndex &index) const
{
const ListingFilterModel* filtermodel = dynamic_cast<const ListingFilterModel*>(index.model());

if(filtermodel)
return filtermodel->item(index);

return nullptr;
}

void DisassemblerView::syncHexEdit()
{
REDasm::ListingDocument& document = m_disassembler->document();
@@ -54,6 +54,7 @@ class DisassemblerView : public QWidget
void goBack();

private:
const REDasm::ListingItem* itemFromIndex(const QModelIndex& index) const;
ListingFilterModel* getSelectedFilterModel();
std::string currentWord() const;
void showListingOrGraph();

0 comments on commit 9da5456

Please sign in to comment.
You can’t perform that action at this time.