mirror of
https://github.com/hedge-dev/XenonRecomp.git
synced 2025-04-19 19:01:17 +00:00
Symbol table
This commit is contained in:
parent
36fb31de3a
commit
6d79935928
@ -4,9 +4,15 @@
|
||||
|
||||
int main()
|
||||
{
|
||||
// TODO: ELFs, symbols, sections, a lot
|
||||
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)
|
||||
{
|
||||
@ -17,8 +23,6 @@ int main()
|
||||
auto base = section.base;
|
||||
const auto end = section.base + section.size;
|
||||
|
||||
ppc::SetDetail(true);
|
||||
|
||||
if (section.flags & SectionFlags_Code)
|
||||
{
|
||||
while(base < end)
|
||||
|
@ -1,5 +1,5 @@
|
||||
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_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)
|
||||
{
|
||||
sections.emplace_back(std::string(name), this->base + base,
|
||||
sections.emplace(std::string(name), this->base + base,
|
||||
size, static_cast<SectionFlags>(flags), data);
|
||||
}
|
||||
|
||||
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 section.data + (address - section.base);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
return section->data + (address - section->base);
|
||||
}
|
||||
|
||||
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.size = size;
|
||||
image.data = std::make_unique<uint8_t[]>(size);
|
||||
image.entry_point = std::byteswap(header->e_entry);
|
||||
memcpy(image.data.get(), data, size);
|
||||
|
||||
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))
|
||||
{
|
||||
image.base = psections[i].p_vaddr;
|
||||
image.base = std::byteswap(psections[i].p_vaddr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -68,7 +67,7 @@ Image ElfLoadImage(const uint8_t* data, size_t size)
|
||||
for (size_t i = 0; i < numSections; i++)
|
||||
{
|
||||
const auto& section = sections[i];
|
||||
if (section.sh_type == 0)
|
||||
if (section.sh_type == 0 || section.sh_addr == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -1,16 +1,10 @@
|
||||
#pragma once
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <expected>
|
||||
|
||||
struct Section;
|
||||
enum SectionFlags : uint8_t
|
||||
{
|
||||
SectionFlags_None = 0,
|
||||
SectionFlags_Data = 1,
|
||||
SectionFlags_Code = 2
|
||||
};
|
||||
#include <section.h>
|
||||
#include "symbol_table.h"
|
||||
|
||||
struct Image
|
||||
{
|
||||
@ -19,7 +13,8 @@ struct Image
|
||||
uint32_t size{};
|
||||
|
||||
size_t entry_point{};
|
||||
std::vector<Section> sections{};
|
||||
std::set<Section, SectionComparer> sections{};
|
||||
SymbolTable symbols{};
|
||||
|
||||
/**
|
||||
* \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);
|
||||
};
|
||||
|
||||
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);
|
||||
|
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