Play-/Source/ui_qt/DebugSupport/ELFView.cpp

182 lines
4.1 KiB
C++
Raw Normal View History

2019-12-21 18:36:40 +00:00
#include "ELFView.h"
#include "string_format.h"
#include "lexical_cast_ex.h"
#include <QLabel>
#include <QFontMetrics>
CELFView::CELFView(QMdiArea* parent)
2019-12-21 18:48:44 +00:00
: QMdiSubWindow(parent)
2019-12-21 18:36:40 +00:00
{
resize(568, 457);
parent->addSubWindow(this);
setWindowTitle("ELF File Viewer");
m_centralwidget = new QWidget(this);
m_treeWidget = new QTreeWidget(m_centralwidget);
m_layout = new QHBoxLayout(m_centralwidget);
m_groupBox = new QGroupBox(m_centralwidget);
m_layout->addWidget(m_treeWidget);
m_layout->addWidget(m_groupBox);
auto groupBoxLayout = new QHBoxLayout();
m_groupBox->setLayout(groupBoxLayout);
setWidget(m_centralwidget);
m_treeWidget->setMaximumSize(QSize(200, 2000));
QTreeWidgetItem* colHeader = m_treeWidget->headerItem();
colHeader->setText(0, "ELF");
m_pHeaderView = new CELFHeaderView(this, groupBoxLayout);
m_pSymbolView = new CELFSymbolView(this, groupBoxLayout);
m_pSectionView = new CELFSectionView(this, groupBoxLayout);
m_pProgramView = new CELFProgramView(this, groupBoxLayout);
connect(m_treeWidget, &QTreeWidget::itemSelectionChanged, this, &CELFView::itemSelectionChanged);
}
void CELFView::Reset()
{
m_pHeaderView->Reset();
m_pSymbolView->Reset();
m_pSectionView->Reset();
m_pProgramView->Reset();
}
void CELFView::SetELF(CELF* pELF)
{
Reset();
m_pELF = pELF;
if(m_pELF == NULL) return;
m_pHeaderView->SetELF(m_pELF);
m_pSymbolView->SetELF(m_pELF);
m_pSectionView->SetELF(m_pELF);
m_pProgramView->SetELF(m_pELF);
PopulateList();
}
void CELFView::resizeEvent(QResizeEvent* evt)
{
QMdiSubWindow::resizeEvent(evt);
m_pSectionView->ResizeEvent();
}
void CELFView::PopulateList()
{
m_treeWidget->clear();
QTreeWidgetItem* headRootItem = new QTreeWidgetItem(m_treeWidget, {"Header"});
m_treeWidget->addTopLevelItem(headRootItem);
QTreeWidgetItem* sectionsRootItem = new QTreeWidgetItem(m_treeWidget, {"Sections"});
m_treeWidget->addTopLevelItem(sectionsRootItem);
2022-03-15 08:13:44 -04:00
const auto& header = m_pELF->GetHeader();
2019-12-21 18:36:40 +00:00
const char* sStrTab = (const char*)m_pELF->GetSectionData(header.nSectHeaderStringTableIndex);
for(unsigned int i = 0; i < header.nSectHeaderCount; i++)
{
std::string sDisplay;
const char* sName(NULL);
2022-03-15 08:13:44 -04:00
auto pSect = m_pELF->GetSection(i);
2019-12-21 18:36:40 +00:00
if(sStrTab != NULL)
{
sName = sStrTab + pSect->nStringTableIndex;
}
else
{
sName = "";
}
if(strlen(sName))
{
sDisplay = sName;
}
else
{
sDisplay = ("Section ") + lexical_cast_uint<std::string>(i);
}
sectionsRootItem->addChild(new QTreeWidgetItem(sectionsRootItem, {sDisplay.c_str()}));
}
sectionsRootItem->setExpanded(true);
m_hasPrograms = header.nProgHeaderCount != 0;
if(m_hasPrograms)
{
QTreeWidgetItem* segmentsRootItem = new QTreeWidgetItem(m_treeWidget, {"Segments"});
m_treeWidget->addTopLevelItem(segmentsRootItem);
for(unsigned int i = 0; i < header.nProgHeaderCount; i++)
{
std::string sDisplay(("Segment ") + lexical_cast_uint<std::string>(i));
segmentsRootItem->addChild(new QTreeWidgetItem(segmentsRootItem, {sDisplay.c_str()}));
}
segmentsRootItem->setExpanded(true);
}
m_hasSymbols = m_pELF->FindSection(".strtab") && m_pELF->FindSection(".symtab");
if(m_hasSymbols)
{
QTreeWidgetItem* symbolsRootItem = new QTreeWidgetItem(m_treeWidget, {"Symbols"});
m_treeWidget->addTopLevelItem(symbolsRootItem);
}
}
void CELFView::itemSelectionChanged()
{
m_pHeaderView->hide();
m_pSectionView->hide();
m_pProgramView->hide();
m_pSymbolView->hide();
auto item = m_treeWidget->selectedItems().at(0);
if(!item)
return;
bool isRoot = item->parent() == nullptr;
int rootIndex = -1;
auto index = -1;
if(!isRoot)
{
index = item->parent()->indexOfChild(item);
rootIndex = m_treeWidget->indexOfTopLevelItem(item->parent());
}
else
{
rootIndex = m_treeWidget->indexOfTopLevelItem(item);
}
if(rootIndex == 0)
{
m_pHeaderView->show();
}
else if(rootIndex == 1)
{
if(index > -1)
{
m_pSectionView->SetSection(index);
m_pSectionView->show();
}
}
else if(rootIndex != -1)
{
if(rootIndex == 2 && m_hasPrograms)
{
if(index > -1)
{
m_pProgramView->SetProgram(index);
m_pProgramView->show();
}
}
else
{
m_pSymbolView->show();
}
}
}