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

276 lines
6.2 KiB
C++
Raw Normal View History

2019-12-21 18:36:40 +00:00
#include "ELFSectionView.h"
#include "string_format.h"
#include "lexical_cast_ex.h"
#include <QLabel>
#include <QAction>
#include <QInputDialog>
#include <QMenu>
#include <QMessageBox>
#include <QHeaderView>
#include <QFontDatabase>
#include <QFontMetrics>
CELFSectionView::CELFSectionView(QMdiSubWindow* parent, QLayout* groupBoxLayout)
2019-12-21 18:48:44 +00:00
: QWidget(parent)
2019-12-21 18:36:40 +00:00
{
std::vector<std::string> labelsStr = {"Type:", "Flags:", "Address:", "File Offset:", "Size:", "Section Link:", "Info:", "Alignment:", "Entry Size:"};
m_layout = new QVBoxLayout(this);
auto label = new QLabel(this);
QFontMetrics metric(label->font());
delete label;
auto labelWidth = metric.horizontalAdvance(labelsStr.back().c_str()) + 10;
for(auto labelStr : labelsStr)
{
auto horizontalLayout = new QHBoxLayout();
2019-12-21 18:36:40 +00:00
auto label = new QLabel(this);
label->setText(labelStr.c_str());
label->setFixedWidth(labelWidth);
horizontalLayout->addWidget(label);
auto lineEdit = new QLineEdit(this);
lineEdit->setReadOnly(true);
m_editFields.push_back(lineEdit);
horizontalLayout->addWidget(lineEdit);
m_layout->addLayout(horizontalLayout);
}
2020-01-05 22:46:47 +00:00
m_memView = new CMemoryViewTable(this);
auto verticalLayout = new QHBoxLayout();
2019-12-21 18:36:40 +00:00
verticalLayout->addWidget(m_memView);
m_dynSecTableWidget = new QTableWidget(this);
m_dynSecTableWidget->setRowCount(0);
m_dynSecTableWidget->setColumnCount(2);
m_dynSecTableWidget->setHorizontalHeaderLabels({"Type", "Value"});
m_dynSecTableWidget->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch);
verticalLayout->addWidget(m_dynSecTableWidget);
m_layout->addLayout(verticalLayout);
groupBoxLayout->addWidget(this);
hide();
}
void CELFSectionView::SetSection(int section)
{
FillInformation(section);
}
void CELFSectionView::Reset()
{
for(auto editField : m_editFields)
{
editField->clear();
}
}
void CELFSectionView::showEvent(QShowEvent* evt)
{
QWidget::showEvent(evt);
2020-01-05 22:46:47 +00:00
m_memView->ShowEvent();
2019-12-21 18:36:40 +00:00
}
void CELFSectionView::ResizeEvent()
{
2020-01-05 22:46:47 +00:00
m_memView->ResizeEvent();
2019-12-21 18:36:40 +00:00
}
void CELFSectionView::SetBytesPerLine(int bytesForLine)
{
2020-01-05 22:46:47 +00:00
m_memView->SetBytesPerLine(bytesForLine);
2019-12-21 18:36:40 +00:00
}
void CELFSectionView::SetELF(CELF* pELF)
{
m_pELF = pELF;
}
void CELFSectionView::FillInformation(int section)
{
int i = 0;
std::string sTemp;
2022-03-15 08:13:44 -04:00
auto pH = m_pELF->GetSection(section);
2019-12-21 18:36:40 +00:00
switch(pH->nType)
{
case CELF::SHT_NULL:
sTemp = "SHT_NULL";
break;
case CELF::SHT_PROGBITS:
sTemp = "SHT_PROGBITS";
break;
case CELF::SHT_SYMTAB:
sTemp = "SHT_SYMTAB";
break;
case CELF::SHT_STRTAB:
sTemp = "SHT_STRTAB";
break;
case CELF::SHT_HASH:
sTemp = "SHT_HASH";
break;
case CELF::SHT_DYNAMIC:
sTemp = "SHT_DYNAMIC";
break;
case CELF::SHT_NOTE:
sTemp = "SHT_NOTE";
break;
case CELF::SHT_NOBITS:
sTemp = "SHT_NOBITS";
break;
case CELF::SHT_REL:
sTemp = "SHT_REL";
break;
case CELF::SHT_DYNSYM:
sTemp = "SHT_DYNSYM";
break;
default:
sTemp = string_format("Unknown (0x%08X)", pH->nType);
break;
}
m_editFields[i++]->setText(sTemp.c_str());
sTemp = string_format("0x%08X", pH->nFlags);
if(pH->nFlags & 0x7)
{
sTemp += " (";
2022-02-28 16:40:29 -05:00
if(pH->nFlags & CELF::SHF_WRITE)
2019-12-21 18:36:40 +00:00
{
sTemp += "SHF_WRITE";
2022-02-28 16:40:29 -05:00
if(pH->nFlags & 0x06)
2019-12-21 18:36:40 +00:00
{
sTemp += " | ";
}
}
2022-02-28 16:40:29 -05:00
if(pH->nFlags & CELF::SHF_ALLOC)
2019-12-21 18:36:40 +00:00
{
sTemp += "SHF_ALLOC";
if(pH->nFlags & 0x04)
{
sTemp += " | ";
}
}
2022-02-28 16:40:29 -05:00
if(pH->nFlags & CELF::SHF_EXECINSTR)
2019-12-21 18:36:40 +00:00
{
sTemp += "SHF_EXECINSTR";
}
sTemp += ")";
}
m_editFields[i++]->setText(sTemp.c_str());
sTemp = string_format("0x%08X", pH->nStart);
m_editFields[i++]->setText(sTemp.c_str());
sTemp = string_format("0x%08X", pH->nOffset);
m_editFields[i++]->setText(sTemp.c_str());
sTemp = string_format("0x%08X", pH->nSize);
m_editFields[i++]->setText(sTemp.c_str());
sTemp = string_format("%i", pH->nIndex);
m_editFields[i++]->setText(sTemp.c_str());
sTemp = string_format("%i", pH->nInfo);
m_editFields[i++]->setText(sTemp.c_str());
sTemp = string_format("0x%08X", pH->nAlignment);
m_editFields[i++]->setText(sTemp.c_str());
sTemp = string_format("0x%08X", pH->nOther);
m_editFields[i++]->setText(sTemp.c_str());
if(pH->nType == CELF::SHT_DYNAMIC)
{
FillDynamicSectionListView(section);
m_dynSecTableWidget->show();
2020-01-05 22:46:47 +00:00
m_memView->SetData(nullptr, 0);
2019-12-21 18:36:40 +00:00
m_memView->hide();
}
else if(pH->nType != CELF::SHT_NOBITS)
{
2019-12-21 18:48:44 +00:00
uint8* data = (uint8*)m_pELF->GetSectionData(section);
auto getByte = [data](uint32 offset) {
2019-12-21 18:36:40 +00:00
return data[offset];
};
2020-01-05 22:46:47 +00:00
m_memView->SetData(getByte, pH->nSize);
2019-12-21 18:36:40 +00:00
m_memView->show();
m_dynSecTableWidget->hide();
}
else
{
2020-01-05 22:46:47 +00:00
m_memView->SetData(nullptr, 0);
2019-12-21 18:36:40 +00:00
m_memView->show();
m_dynSecTableWidget->hide();
}
}
void CELFSectionView::FillDynamicSectionListView(int section)
{
m_dynSecTableWidget->setRowCount(0);
2022-03-15 08:13:44 -04:00
auto pH = m_pELF->GetSection(section);
2019-12-21 18:36:40 +00:00
const uint32* dynamicData = reinterpret_cast<const uint32*>(m_pELF->GetSectionData(section));
const char* stringTable = (pH->nOther != -1) ? reinterpret_cast<const char*>(m_pELF->GetSectionData(pH->nIndex)) : NULL;
for(unsigned int i = 0; i < pH->nSize; i += 8, dynamicData += 2)
{
uint32 tag = *(dynamicData + 0);
uint32 value = *(dynamicData + 1);
if(tag == 0) break;
std::string tempTag;
std::string tempVal;
switch(tag)
{
case CELF::DT_NEEDED:
tempTag = "DT_NEEDED";
tempVal = stringTable + value;
break;
case CELF::DT_PLTRELSZ:
tempTag = "DT_PLTRELSZ";
tempVal = string_format("0x%08X", value);
break;
case CELF::DT_PLTGOT:
tempTag = "DT_PLTGOT";
tempVal = string_format("0x%08X", value);
break;
case CELF::DT_HASH:
tempTag = "DT_HASH";
tempVal = string_format("0x%08X", value);
break;
case CELF::DT_STRTAB:
tempTag = "DT_STRTAB";
tempVal = string_format("0x%08X", value);
break;
case CELF::DT_SYMTAB:
tempTag = "DT_SYMTAB";
tempVal = string_format("0x%08X", value);
break;
case CELF::DT_SONAME:
tempTag = "DT_SONAME";
tempVal = stringTable + value;
break;
case CELF::DT_SYMBOLIC:
tempTag = "DT_SYMBOLIC";
tempVal = "";
break;
default:
tempTag = string_format("Unknown (0x%08X)", tag);
tempVal = string_format("0x%08X", value);
break;
}
m_dynSecTableWidget->setRowCount((i / 8) + 1);
m_dynSecTableWidget->setItem((i / 8), 0, new QTableWidgetItem(tempTag.c_str()));
m_dynSecTableWidget->setItem((i / 8), 1, new QTableWidgetItem(tempVal.c_str()));
}
}