Skip to content

Commit

Permalink
Put all ELF symbol listing code in common.
Browse files Browse the repository at this point in the history
  • Loading branch information
jpd002 committed Jul 31, 2023
1 parent 16a6151 commit a4d5045
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 61 deletions.
50 changes: 45 additions & 5 deletions Source/ELF.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <vector>
#include <stdexcept>
#include <cassert>
#include <functional>
#include "Types.h"
#include "ElfDefs.h"
#include "PtrStream.h"
Expand Down Expand Up @@ -100,7 +101,7 @@ class CELF
return m_sections.size();
}

SECTIONHEADER* GetSection(unsigned int index)
const SECTIONHEADER* GetSection(unsigned int index) const
{
if(index >= m_sections.size())
{
Expand All @@ -109,7 +110,7 @@ class CELF
return &m_sections[index];
}

const void* GetSectionData(unsigned int index)
const void* GetSectionData(unsigned int index) const
{
auto section = GetSection(index);
if(section == nullptr) return nullptr;
Expand All @@ -125,14 +126,14 @@ class CELF
return stringTableData + sectionHeader->nStringTableIndex;
}

SECTIONHEADER* FindSection(const char* requestedSectionName)
const SECTIONHEADER* FindSection(const char* requestedSectionName) const
{
auto sectionIndex = FindSectionIndex(requestedSectionName);
if(sectionIndex == 0) return nullptr;
return GetSection(sectionIndex);
}

unsigned int FindSectionIndex(const char* requestedSectionName)
unsigned int FindSectionIndex(const char* requestedSectionName) const
{
auto stringTableData = reinterpret_cast<const char*>(GetSectionData(m_header.nSectHeaderStringTableIndex));
if(stringTableData == nullptr) return 0;
Expand All @@ -148,7 +149,7 @@ class CELF
return 0;
}

const void* FindSectionData(const char* requestedSectionName)
const void* FindSectionData(const char* requestedSectionName) const
{
auto section = FindSection(requestedSectionName);
if(section == nullptr) return nullptr;
Expand All @@ -164,6 +165,45 @@ class CELF
return &m_programs[index];
}

uint64 GetSymbolCount() const
{
auto symbolTable = FindSection(".symtab");
if(!symbolTable) return 0;
return symbolTable->nSize / sizeof(SYMBOL);
}

typedef std::function<void(const SYMBOL&, uint8, uint8, const char*)> SymbolEnumarationCallback;

void EnumerateSymbols(const SymbolEnumarationCallback& callback) const
{
auto symbolTable = FindSection(".symtab");
if(!symbolTable) return;

auto stringTable = reinterpret_cast<const char*>(GetSectionData(symbolTable->nIndex));
if(!stringTable) return;

auto symbols = reinterpret_cast<const SYMBOL*>(FindSectionData(".symtab"));
unsigned int symbolCount = symbolTable->nSize / sizeof(SYMBOL);

for(unsigned int i = 0; i < symbolCount; i++)
{
auto symbol = symbols[i];

if(m_header.nId[ELF::EI_DATA] == ELF::ELFDATA2MSB)
{
Framework::CEndian::FromMSBF(symbol.nName);
Framework::CEndian::FromMSBF(symbol.nValue);
Framework::CEndian::FromMSBF(symbol.nSize);
Framework::CEndian::FromMSBF(symbol.nSectionIndex);
}

uint8 symbolType = symbol.nInfo & 0x0F;
uint8 symbolBinding = (symbol.nInfo >> 4) & 0x0F;
auto symbolName = stringTable + symbol.nName;
callback(symbol, symbolType, symbolBinding, symbolName);
}
}

private:
void ReadSectionHeaders(Framework::CStream& stream)
{
Expand Down
24 changes: 5 additions & 19 deletions Source/iop/IopBios.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3932,27 +3932,13 @@ void CIopBios::PrepareModuleDebugInfo(CELF32& elf, const ExecutableRange& module
}

//Look also for symbol tables
{
auto pSymTab = elf.FindSection(".symtab");
if(pSymTab != NULL)
elf.EnumerateSymbols([&](const ELF::ELFSYMBOL32& symbol, uint8 type, uint8 binding, const char* name) {
if(type == ELF::STT_FUNC)
{
const char* pStrTab = reinterpret_cast<const char*>(elf.GetSectionData(pSymTab->nIndex));
if(pStrTab != NULL)
{
auto pSym = reinterpret_cast<const ELF::ELFSYMBOL32*>(elf.FindSectionData(".symtab"));
unsigned int nCount = pSymTab->nSize / sizeof(ELF::ELFSYMBOL32);

for(unsigned int i = 0; i < nCount; i++)
{
if((pSym[i].nInfo & 0x0F) != 0x02) continue;
auto symbolSection = elf.GetSection(pSym[i].nSectionIndex);
if(symbolSection == NULL) continue;
m_cpu.m_Functions.InsertTag(moduleRange.first + symbolSection->nStart + pSym[i].nValue, (char*)pStrTab + pSym[i].nName);
functionAdded = true;
}
}
m_cpu.m_Functions.InsertTag(symbol.nValue + moduleRange.first, name);
functionAdded = true;
}
}
});

if(functionAdded)
{
Expand Down
26 changes: 8 additions & 18 deletions Source/ui_qt/DebugSupport/ELFSymbolView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,36 +49,25 @@ void CELFSymbolView<ElfType>::SetELF(ElfType* pELF)
template <typename ElfType>
void CELFSymbolView<ElfType>::PopulateList()
{
const char* sectionName = ".symtab";

auto pSymTab = m_pELF->FindSection(sectionName);
if(pSymTab == NULL) return;

const char* pStrTab = (const char*)m_pELF->GetSectionData(pSymTab->nIndex);
if(pStrTab == NULL) return;

auto symbols = reinterpret_cast<const typename ElfType::SYMBOL*>(m_pELF->FindSectionData(sectionName));
unsigned int count = pSymTab->nSize / sizeof(typename ElfType::SYMBOL);

auto count = m_pELF->GetSymbolCount();
m_tableWidget->setRowCount(count);

#define CASE_ELF_ENUM(enumValue) \
case ELF::enumValue: \
sTemp = #enumValue; \
break;

for(unsigned int i = 0; i < count; i++)
{
auto symbol = symbols[i];
int i = 0;

m_pELF->EnumerateSymbols([&](const typename ElfType::SYMBOL& symbol, uint8 type, uint8 binding, const char* name) {
int j = 0;
std::string sTemp;

m_tableWidget->setItem(i, j++, new QTableWidgetItem(pStrTab + symbol.nName));
m_tableWidget->setItem(i, j++, new QTableWidgetItem(name));
m_tableWidget->setItem(i, j++, new QTableWidgetItem(lexical_cast_hex<std::string>(symbol.nValue, 8).c_str()));
m_tableWidget->setItem(i, j++, new QTableWidgetItem(lexical_cast_hex<std::string>(symbol.nSize, 8).c_str()));

switch(symbol.nInfo & 0x0F)
switch(type)
{
CASE_ELF_ENUM(STT_NOTYPE)
CASE_ELF_ENUM(STT_OBJECT)
Expand All @@ -91,7 +80,7 @@ void CELFSymbolView<ElfType>::PopulateList()
}
m_tableWidget->setItem(i, j++, new QTableWidgetItem(sTemp.c_str()));

switch((symbol.nInfo >> 4) & 0xF)
switch(binding)
{
CASE_ELF_ENUM(STB_LOCAL)
CASE_ELF_ENUM(STB_GLOBAL)
Expand All @@ -113,8 +102,9 @@ void CELFSymbolView<ElfType>::PopulateList()
}
m_tableWidget->setItem(i, j++, new QTableWidgetItem(sTemp.c_str()));

i++;
});
#undef CASE_ELF_ENUM
}
}

template class CELFSymbolView<CELF32>;
Expand Down
31 changes: 12 additions & 19 deletions Source/ui_qt/DebugSupport/FunctionsView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -292,26 +292,19 @@ void CFunctionsView::OnImportClick()
std::end(m_modules) != moduleIterator; moduleIterator++)
{
const auto& module(*moduleIterator);
CELF32* moduleImage = reinterpret_cast<CELF32*>(module.param);
auto moduleImage = reinterpret_cast<CELF32*>(module.param);
if(!moduleImage) continue;

if(moduleImage == NULL) continue;

auto pSymTab = moduleImage->FindSection(".symtab");
if(pSymTab == NULL) continue;

const char* pStrTab = (const char*)moduleImage->GetSectionData(pSymTab->nIndex);
if(pStrTab == NULL) continue;

auto pSym = reinterpret_cast<const CELF32::SYMBOL*>(moduleImage->FindSectionData(".symtab"));
unsigned int nCount = pSymTab->nSize / sizeof(CELF32::SYMBOL);

for(unsigned int i = 0; i < nCount; i++)
{
if((pSym[i].nInfo & 0x0F) != 0x02) continue;
auto symbolSection = moduleImage->GetSection(pSym[i].nSectionIndex);
if(symbolSection == NULL) continue;
m_context->m_Functions.InsertTag(module.begin + (pSym[i].nValue - symbolSection->nStart), pStrTab + pSym[i].nName);
}
moduleImage->EnumerateSymbols([&](const ELF::ELFSYMBOL32& symbol, uint8 type, uint8 binding, const char* name) {
if(type == ELF::STT_FUNC)
{
//NOTE: This check for the section owning the symbol might not be necessary.
//Since we load the executable at the address specified by the program header
auto symbolSection = moduleImage->GetSection(symbol.nSectionIndex);
if(!symbolSection) return;
m_context->m_Functions.InsertTag(module.begin + (symbol.nValue - symbolSection->nStart), name);
}
});
}

RefreshList();
Expand Down

0 comments on commit a4d5045

Please sign in to comment.