Refactor ELF reader class
Some checks failed
Build check / build (push) Has been cancelled
Generate translation template / generate-pot (push) Has been cancelled

also properly interpet the mmap failure condition
This commit is contained in:
goeiecool9999
2026-09-22 20:01:24 +02:00
parent e24374a137
commit b1fe77e995
2 changed files with 40 additions and 46 deletions

View File

@@ -5,31 +5,19 @@
#include <sys/stat.h>
#include <unistd.h>
uint16 ELFSymbolTable::FindSection(int type, const std::string_view& name)
template <typename T>
std::span<T> ELFSymbolTable::SectionAsArray(const Elf64_Shdr* section)
{
if (!shTable || !shStrTable)
return 0;
if (section == nullptr)
return {};
if (section->sh_size < sizeof(T))
return {};
if (section->sh_entsize != 0 && section->sh_entsize != sizeof(T))
return {};
for (uint16 i = 0; i < header->e_shnum; ++i)
{
auto& entry = shTable[i];
if(entry.sh_type == type && std::string_view{&shStrTable[entry.sh_name]} == name)
{
return i;
}
}
return 0;
return {(T*)(mappedExecutable + section->sh_offset), section->sh_size / sizeof(T)};
}
void* ELFSymbolTable::SectionPointer(uint16 index)
{
return SectionPointer(shTable[index]);
}
void* ELFSymbolTable::SectionPointer(const Elf64_Shdr& section)
{
return (void*)(mappedExecutable + section.sh_offset);
}
ELFSymbolTable::ELFSymbolTable()
{
@@ -40,7 +28,7 @@ ELFSymbolTable::ELFSymbolTable()
// retrieve file size.
struct stat filestats;
if (fstat(fd, &filestats))
if (fstat(fd, &filestats) != 0)
{
close(fd);
return;
@@ -48,9 +36,9 @@ ELFSymbolTable::ELFSymbolTable()
mappedExecutableSize = filestats.st_size;
// attempt to map the file
mappedExecutable = (uint8*)(mmap(nullptr, mappedExecutableSize, PROT_READ, MAP_PRIVATE, fd, 0));
mappedExecutable = static_cast<uint8*>(mmap(nullptr, mappedExecutableSize, PROT_READ, MAP_PRIVATE, fd, 0));
close(fd);
if (!mappedExecutable)
if (mappedExecutable == MAP_FAILED)
return;
// verify signature
@@ -64,19 +52,11 @@ ELFSymbolTable::ELFSymbolTable()
}
}
shTable = (Elf64_Shdr*)(mappedExecutable + header->e_shoff);
shTable = {(Elf64_Shdr*)(mappedExecutable + header->e_shoff), header->e_shnum};
Elf64_Shdr& shStrn = shTable[header->e_shstrndx];
shStrTable = (char*)(mappedExecutable + shStrn.sh_offset);
strTable = (char*)SectionPointer(FindSection(SHT_STRTAB, ".strtab"));
Elf64_Shdr& symTabShdr = shTable[FindSection(SHT_SYMTAB, ".symtab")];
if (symTabShdr.sh_entsize == 0)
return;
symTableLen = symTabShdr.sh_size / symTabShdr.sh_entsize;
symTable = (Elf64_Sym*)(SectionPointer(symTabShdr));
shStrTable = SectionAsArray<char>(&shTable[header->e_shstrndx]);
strTable = SectionAsArray<char>(FindSection(SHT_STRTAB, ".strtab"));
symTable = SectionAsArray<Elf64_Sym>(FindSection(SHT_SYMTAB, ".symtab"));
}
ELFSymbolTable::~ELFSymbolTable()
@@ -85,15 +65,30 @@ ELFSymbolTable::~ELFSymbolTable()
munmap(mappedExecutable, mappedExecutableSize);
}
Elf64_Shdr* ELFSymbolTable::FindSection(Elf64_Word type, const std::string_view& name)
{
if (shTable.empty() || shStrTable.empty())
return nullptr;
for (auto& entry : shTable)
{
if(entry.sh_type == type && std::string_view{&shStrTable[entry.sh_name]} == name)
{
return &entry;
}
}
return nullptr;
}
std::string_view ELFSymbolTable::OffsetToSymbol(uint64 ptr, uint64& fromStart) const
{
if(!symTable || !strTable)
if(symTable.empty() || strTable.empty())
{
fromStart = -1;
return {};
}
for (auto entry = symTable+1; entry < symTable+symTableLen; ++entry)
for (auto entry = symTable.begin()+1; entry != symTable.end(); ++entry)
{
if (ELF64_ST_TYPE(entry->st_info) != STT_FUNC)
continue;

View File

@@ -15,17 +15,16 @@ private:
Elf64_Ehdr* header = nullptr;
Elf64_Shdr* shTable = nullptr;
char* shStrTable = nullptr;
std::span<Elf64_Shdr> shTable{};
std::span<char> shStrTable{};
Elf64_Sym* symTable = nullptr;
uint64 symTableLen = 0;
char* strTable = nullptr;
std::span<Elf64_Sym> symTable{};
std::span<char> strTable{};
uint16 FindSection(int type, const std::string_view& name);
Elf64_Shdr* FindSection(Elf64_Word type, const std::string_view& name);
void* SectionPointer (uint16 index);
void* SectionPointer(const Elf64_Shdr& section);
template <typename T>
std::span<T> SectionAsArray(const Elf64_Shdr* section);
// ownership of mapped memory, cannot copy.
ELFSymbolTable(const ELFSymbolTable&) = delete;