CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
hrydgard

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: hrydgard/ppsspp
Path: blob/master/Core/ELF/ElfReader.h
Views: 1401
1
// Copyright (c) 2012- PPSSPP Project.
2
3
// This program is free software: you can redistribute it and/or modify
4
// it under the terms of the GNU General Public License as published by
5
// the Free Software Foundation, version 2.0 or later versions.
6
7
// This program is distributed in the hope that it will be useful,
8
// but WITHOUT ANY WARRANTY; without even the implied warranty of
9
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
// GNU General Public License 2.0 for more details.
11
12
// A copy of the GPL 2.0 should have been included with the program.
13
// If not, see http://www.gnu.org/licenses/
14
15
// Official git repository and contact information can be found at
16
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
17
18
#pragma once
19
20
#include <vector>
21
#include "Common/CommonTypes.h"
22
#include "Core/ELF/ElfTypes.h"
23
24
enum {
25
R_MIPS_NONE,
26
R_MIPS_16,
27
R_MIPS_32,
28
R_MIPS_REL32,
29
R_MIPS_26,
30
R_MIPS_HI16,
31
R_MIPS_LO16,
32
R_MIPS_GPREL16,
33
R_MIPS_LITERAL,
34
R_MIPS_GOT16,
35
R_MIPS_PC16,
36
R_MIPS_CALL16,
37
R_MIPS_GPREL32
38
};
39
40
enum KnownElfTypes {
41
KNOWNELF_PSP = 0,
42
KNOWNELF_DS = 1,
43
KNOWNELF_GBA = 2,
44
};
45
46
typedef int SectionID;
47
48
class ElfReader {
49
public:
50
ElfReader(const void *ptr, size_t size) {
51
base = (const char*)ptr;
52
base32 = (const u32 *)ptr;
53
header = (const Elf32_Ehdr*)ptr;
54
segments = (const Elf32_Phdr *)(base + header->e_phoff);
55
sections = (const Elf32_Shdr *)(base + header->e_shoff);
56
size_ = size;
57
}
58
59
~ElfReader() {
60
delete[] sectionOffsets;
61
delete[] sectionAddrs;
62
}
63
64
u32 Read32(int off) const {
65
return base32[off >> 2];
66
}
67
68
// Quick accessors
69
ElfType GetType() const { return (ElfType)(u16)(header->e_type); }
70
ElfMachine GetMachine() const { return (ElfMachine)(u16)(header->e_machine); }
71
u32 GetEntryPoint() const { return entryPoint; }
72
u32 GetFlags() const { return (u32)(header->e_flags); }
73
74
int GetNumSegments() const { return (int)(header->e_phnum); }
75
int GetNumSections() const { return (int)(header->e_shnum); }
76
const char *GetSectionName(int section) const;
77
const u8 *GetPtr(u32 offset) const {
78
return (const u8*)base + offset;
79
}
80
// Note: zero is not a valid output, means unavailable.
81
u32 GetSectionDataOffset(int section) const {
82
if (section < 0 || section >= header->e_shnum)
83
return 0;
84
if (sections[section].sh_type == SHT_NOBITS)
85
return 0;
86
return sections[section].sh_offset;
87
}
88
const u8 *GetSectionDataPtr(int section) const {
89
u32 offset = GetSectionDataOffset(section);
90
if (offset == 0 || offset > size_)
91
return nullptr;
92
return GetPtr(offset);
93
}
94
const u8 *GetSegmentPtr(int segment) const {
95
if (segments[segment].p_offset > size_)
96
return nullptr;
97
return GetPtr(segments[segment].p_offset);
98
}
99
u32 GetSectionAddr(SectionID section) const {
100
return sectionAddrs[section];
101
}
102
int GetSectionSize(SectionID section) const {
103
return sections[section].sh_size;
104
}
105
106
//-1 for not found
107
SectionID GetSectionByName(const char *name, int firstSection = 0) const;
108
109
u32 GetSegmentPaddr(int segment) const {
110
return segments[segment].p_paddr;
111
}
112
u32 GetSegmentOffset(int segment) const {
113
return segments[segment].p_offset;
114
}
115
u32 GetSegmentVaddr(int segment) const {
116
return segmentVAddr[segment];
117
}
118
u32 GetSegmentDataSize(int segment) const {
119
return segments[segment].p_filesz;
120
}
121
u32 GetSegmentMemSize(int segment) const {
122
return segments[segment].p_memsz;
123
}
124
125
u32 GetFirstSegmentAlign() const {
126
return firstSegAlign;
127
}
128
129
bool DidRelocate() const {
130
return bRelocate;
131
}
132
133
u32 GetVaddr() const {
134
return vaddr;
135
}
136
137
u32 GetTotalSize() const {
138
return totalSize;
139
}
140
141
u32 GetTotalTextSize() const;
142
u32 GetTotalTextSizeFromSeg() const;
143
u32 GetTotalDataSize() const;
144
u32 GetTotalSectionSizeByPrefix(const std::string &prefix) const;
145
146
std::vector<SectionID> GetCodeSections() const;
147
148
int LoadInto(u32 vaddr, bool fromTop);
149
bool LoadSymbols();
150
bool LoadRelocations(const Elf32_Rel *rels, int numRelocs);
151
void LoadRelocations2(int rel_seg);
152
153
private:
154
const char *base = nullptr;
155
const u32 *base32 = nullptr;
156
const Elf32_Ehdr *header = nullptr;
157
const Elf32_Phdr *segments = nullptr;
158
const Elf32_Shdr *sections = nullptr;
159
u32 *sectionOffsets = nullptr;
160
u32 *sectionAddrs = nullptr;
161
bool bRelocate = false;
162
u32 entryPoint = 0;
163
u32 totalSize = 0;
164
u32 vaddr = 0;
165
u32 segmentVAddr[32]{};
166
size_t size_ = 0;
167
u32 firstSegAlign = 0;
168
};
169
170