Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
stenzek
GitHub Repository: stenzek/duckstation
Path: blob/master/src/util/elf_file.h
4802 views
1
// SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin <[email protected]>
2
// SPDX-License-Identifier: CC-BY-NC-ND-4.0
3
4
#pragma once
5
6
#include "common/heap_array.h"
7
#include "common/types.h"
8
9
#include <functional>
10
#include <string_view>
11
12
class Error;
13
14
class ELFFile
15
{
16
public:
17
using DataArray = DynamicHeapArray<u8>;
18
19
// ELF header constants
20
static constexpr u8 EI_NIDENT = 16;
21
static constexpr u16 ET_EXEC = 2;
22
static constexpr u16 ET_DYN = 3;
23
static constexpr u16 EM_MIPS = 8;
24
static constexpr u16 SHN_UNDEF = 0;
25
static constexpr u32 SHT_NULL = 0;
26
static constexpr u32 SHT_PROGBITS = 1;
27
static constexpr u32 SHT_SYMTAB = 2;
28
static constexpr u32 SHT_STRTAB = 3;
29
static constexpr u32 SHT_RELA = 4;
30
static constexpr u32 SHT_HASH = 5;
31
static constexpr u32 SHT_DYNAMIC = 6;
32
static constexpr u32 SHT_NOTE = 7;
33
static constexpr u32 SHT_NOBITS = 8;
34
static constexpr u32 SHT_REL = 9;
35
static constexpr u32 SHT_SHLIB = 10;
36
static constexpr u32 SHT_DYNSYM = 11;
37
static constexpr u32 SHT_NUM = 12;
38
static constexpr u32 PT_NULL = 0;
39
static constexpr u32 PT_LOAD = 1;
40
static constexpr u32 PT_DYNAMIC = 2;
41
static constexpr u32 PT_INTERP = 3;
42
static constexpr u32 PT_NOTE = 4;
43
static constexpr u32 PT_SHLIB = 5;
44
static constexpr u32 PT_PHDR = 6;
45
static constexpr u32 PT_TLS = 7;
46
47
// ELF Header structure
48
struct Elf32_Ehdr
49
{
50
u8 e_ident[EI_NIDENT]; // Magic number and other information
51
u16 e_type; // Object file type
52
u16 e_machine; // Architecture
53
u32 e_version; // Object file version
54
u32 e_entry; // Entry point virtual address
55
u32 e_phoff; // Program header table file offset
56
u32 e_shoff; // Section header table file offset
57
u32 e_flags; // Processor-specific flags
58
u16 e_ehsize; // ELF header size in bytes
59
u16 e_phentsize; // Program header table entry size
60
u16 e_phnum; // Program header table entry count
61
u16 e_shentsize; // Section header table entry size
62
u16 e_shnum; // Section header table entry count
63
u16 e_shstrndx; // Section header string table index
64
};
65
66
// Section header structure
67
struct Elf32_Shdr
68
{
69
u32 sh_name; // Section name (string tbl index)
70
u32 sh_type; // Section type
71
u32 sh_flags; // Section flags
72
u32 sh_addr; // Section virtual addr at execution
73
u32 sh_offset; // Section file offset
74
u32 sh_size; // Section size in bytes
75
u32 sh_link; // Link to another section
76
u32 sh_info; // Additional section information
77
u32 sh_addralign; // Section alignment
78
u32 sh_entsize; // Entry size if section holds table
79
};
80
81
// Program header structure
82
struct Elf32_Phdr
83
{
84
u32 p_type;
85
u32 p_offset;
86
u32 p_vaddr;
87
u32 p_paddr;
88
u32 p_filesz;
89
u32 p_memsz;
90
u32 p_flags;
91
u32 p_align;
92
};
93
94
public:
95
ELFFile();
96
~ELFFile();
97
98
static bool IsValidElfHeader(const std::span<const u8> data, Error* error = nullptr);
99
static bool IsValidElfHeader(const Elf32_Ehdr& header, Error* error = nullptr);
100
101
const Elf32_Ehdr& GetELFHeader() const;
102
u32 GetEntryPoint() const;
103
104
const Elf32_Shdr* GetSectionHeader(u32 index) const;
105
std::string_view GetSectionName(const Elf32_Shdr& section) const;
106
u32 GetSectionCount() const;
107
108
const Elf32_Phdr* GetProgramHeader(u32 index) const;
109
u32 GetProgramHeaderCount() const;
110
111
bool Open(const char* path, Error* error);
112
bool Open(DataArray data, Error* error);
113
114
using LoadExecutableSectionCallback =
115
std::function<bool(std::span<const u8> data, u32 dest_vaddr, u32 dest_size, Error* error)>;
116
bool LoadExecutableSections(const LoadExecutableSectionCallback& callback, Error* error) const;
117
118
private:
119
DataArray m_data;
120
};
121
122