Symbol table

This commit is contained in:
Sajid 2024-09-08 08:32:31 +06:00
parent 36fb31de3a
commit 6d79935928
8 changed files with 186 additions and 48 deletions

View File

@ -4,9 +4,15 @@
int main() int main()
{ {
// TODO: ELFs, symbols, sections, a lot
const auto file = LoadFile("add.elf"); const auto file = LoadFile("add.elf");
const auto image = Image::ParseImage(file.data(), file.size()).value(); auto image = Image::ParseImage(file.data(), file.size()).value();
for (const auto& section : image.sections)
{
image.symbols.emplace(section.name, section.base, section.size, Symbol_Section);
}
image.symbols.emplace("_start", image.entry_point, 0x30, Symbol_Function);
for (const auto& section : image.sections) for (const auto& section : image.sections)
{ {
@ -17,8 +23,6 @@ int main()
auto base = section.base; auto base = section.base;
const auto end = section.base + section.size; const auto end = section.base + section.size;
ppc::SetDetail(true);
if (section.flags & SectionFlags_Code) if (section.flags & SectionFlags_Code)
{ {
while(base < end) while(base < end)

View File

@ -1,5 +1,5 @@
project("PowerUtils") project("PowerUtils")
add_library(PowerUtils "disasm.h" "disasm.cpp" "file.h" "xex.cpp" "image.h" "image.cpp" "elf.h") add_library(PowerUtils "disasm.h" "disasm.cpp" "file.h" "xex.cpp" "image.h" "image.cpp" "elf.h" "ppc_context.h" "symbol.h" "symbol_table.h" "section.h")
target_include_directories(PowerUtils PUBLIC .) target_include_directories(PowerUtils PUBLIC .)
target_link_libraries(PowerUtils PUBLIC capstone) target_link_libraries(PowerUtils PUBLIC capstone)

View File

@ -5,21 +5,19 @@
void Image::Map(const std::string_view& name, size_t base, uint32_t size, uint8_t flags, uint8_t* data) void Image::Map(const std::string_view& name, size_t base, uint32_t size, uint8_t flags, uint8_t* data)
{ {
sections.emplace_back(std::string(name), this->base + base, sections.emplace(std::string(name), this->base + base,
size, static_cast<SectionFlags>(flags), data); size, static_cast<SectionFlags>(flags), data);
} }
const void* Image::Find(size_t address) const const void* Image::Find(size_t address) const
{ {
for (const auto& section : sections) const auto section = sections.find(address);
if (section == sections.end())
{ {
if (section == address) return nullptr;
{
return section.data + (address - section.base);
}
} }
return nullptr; return section->data + (address - section->base);
} }
std::expected<Image, int> Image::ParseImage(const uint8_t* data, size_t size) std::expected<Image, int> Image::ParseImage(const uint8_t* data, size_t size)
@ -44,6 +42,7 @@ Image ElfLoadImage(const uint8_t* data, size_t size)
Image image{}; Image image{};
image.size = size; image.size = size;
image.data = std::make_unique<uint8_t[]>(size); image.data = std::make_unique<uint8_t[]>(size);
image.entry_point = std::byteswap(header->e_entry);
memcpy(image.data.get(), data, size); memcpy(image.data.get(), data, size);
auto stringTableIndex = std::byteswap(header->e_shstrndx); auto stringTableIndex = std::byteswap(header->e_shstrndx);
@ -58,7 +57,7 @@ Image ElfLoadImage(const uint8_t* data, size_t size)
{ {
if (psections[i].p_type == std::byteswap((Elf32_Word)PT_LOAD)) if (psections[i].p_type == std::byteswap((Elf32_Word)PT_LOAD))
{ {
image.base = psections[i].p_vaddr; image.base = std::byteswap(psections[i].p_vaddr);
break; break;
} }
} }
@ -68,7 +67,7 @@ Image ElfLoadImage(const uint8_t* data, size_t size)
for (size_t i = 0; i < numSections; i++) for (size_t i = 0; i < numSections; i++)
{ {
const auto& section = sections[i]; const auto& section = sections[i];
if (section.sh_type == 0) if (section.sh_type == 0 || section.sh_addr == 0)
{ {
continue; continue;
} }

View File

@ -1,16 +1,10 @@
#pragma once #pragma once
#include <memory> #include <memory>
#include <string> #include <string>
#include <vector> #include <set>
#include <expected> #include <expected>
#include <section.h>
struct Section; #include "symbol_table.h"
enum SectionFlags : uint8_t
{
SectionFlags_None = 0,
SectionFlags_Data = 1,
SectionFlags_Code = 2
};
struct Image struct Image
{ {
@ -19,7 +13,8 @@ struct Image
uint32_t size{}; uint32_t size{};
size_t entry_point{}; size_t entry_point{};
std::vector<Section> sections{}; std::set<Section, SectionComparer> sections{};
SymbolTable symbols{};
/** /**
* \brief Map data to image by RVA * \brief Map data to image by RVA
@ -46,28 +41,4 @@ struct Image
static std::expected<Image, int> ParseImage(const uint8_t* data, size_t size); static std::expected<Image, int> ParseImage(const uint8_t* data, size_t size);
}; };
struct Section
{
std::string name{};
size_t base{};
uint32_t size{};
SectionFlags flags{};
uint8_t* data{};
bool operator<(size_t address) const
{
return address < base;
}
bool operator>(size_t address) const
{
return address >= (base + size);
}
bool operator==(size_t address) const
{
return address >= base && address < base + size;
}
};
Image ElfLoadImage(const uint8_t* data, size_t size); Image ElfLoadImage(const uint8_t* data, size_t size);

18
PowerUtils/ppc_context.h Normal file
View File

@ -0,0 +1,18 @@
#pragma once
#include <cstdint>
typedef float float128[4];
struct PPCContext
{
uint64_t iar;
uint64_t lr;
uint64_t ctr;
uint32_t xer;
uint32_t cr[8];
uint32_t fpcsr;
uint64_t gpr[32];
double fpr[32];
float128 vpr[128];
};

54
PowerUtils/section.h Normal file
View File

@ -0,0 +1,54 @@
#pragma once
#include <string>
#include <cstdint>
enum SectionFlags : uint8_t
{
SectionFlags_None = 0,
SectionFlags_Data = 1,
SectionFlags_Code = 2
};
struct Section
{
std::string name{};
size_t base{};
uint32_t size{};
SectionFlags flags{};
uint8_t* data{};
bool operator<(size_t address) const
{
return address < base;
}
bool operator>(size_t address) const
{
return address >= (base + size);
}
bool operator==(size_t address) const
{
return address >= base && address < base + size;
}
};
struct SectionComparer
{
using is_transparent = void;
bool operator()(const Section& lhs, size_t rhs) const
{
return rhs > lhs.base + lhs.size;
}
bool operator()(size_t lhs, const Section& rhs) const
{
return lhs < rhs.base;
}
bool operator()(const Section& lhs, const Section& rhs) const
{
return (lhs.base + lhs.size) < rhs.base;
}
};

39
PowerUtils/symbol.h Normal file
View File

@ -0,0 +1,39 @@
#pragma once
#include <string>
#include <cstdint>
enum SymbolType
{
Symbol_None,
Symbol_Section,
Symbol_Function,
Symbol_Comment,
};
struct Symbol
{
std::string name{};
uint32_t address{};
uint32_t size{};
SymbolType type{};
};
struct SymbolComparer
{
using is_transparent = void;
bool operator()(const Symbol& lhs, size_t rhs) const
{
return rhs > lhs.address + lhs.size;
}
bool operator()(size_t lhs, const Symbol& rhs) const
{
return lhs < rhs.address;
}
bool operator()(const Symbol& lhs, const Symbol& rhs) const
{
return (lhs.address + lhs.size) < rhs.address;
}
};

53
PowerUtils/symbol_table.h Normal file
View File

@ -0,0 +1,53 @@
#pragma once
#include "symbol.h"
#include <set>
class SymbolTable : public std::multiset<Symbol, SymbolComparer>
{
public:
const_iterator find(size_t address) const
{
auto iter = std::multiset<Symbol, SymbolComparer>::find(address);
if (iter == end())
{
return iter;
}
size_t closest{ address - iter->address };
auto match = iter;
for (; iter != end(); ++iter)
{
const size_t distance = address - iter->address;
if (distance <= closest)
{
match = iter;
closest = distance;
}
}
return match;
}
iterator find(size_t address)
{
auto iter = std::multiset<Symbol, SymbolComparer>::find(address);
if (iter == end())
{
return iter;
}
size_t closest{ address - iter->address };
auto match = iter;
for (; iter != end(); ++iter)
{
const size_t distance = address - iter->address;
if (distance <= closest)
{
match = iter;
closest = distance;
}
}
return match;
}
};