mirror of
https://github.com/hedge-dev/XenonRecomp.git
synced 2025-06-23 16:05:30 +00:00
Symbol table
This commit is contained in:
parent
36fb31de3a
commit
6d79935928
@ -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)
|
||||||
|
@ -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)
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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
18
PowerUtils/ppc_context.h
Normal 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
54
PowerUtils/section.h
Normal 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
39
PowerUtils/symbol.h
Normal 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
53
PowerUtils/symbol_table.h
Normal 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;
|
||||||
|
}
|
||||||
|
};
|
Loading…
x
Reference in New Issue
Block a user