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();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|