1 #pragma once
2 #include <cstdint>
3 #include "be_val.h"
4 
5 #pragma pack(push, 1)
6 
7 namespace elf
8 {
9 
10 enum Machine : uint32_t /* e_machine */
11 {
12    EM_PPC = 20 /* PowerPC */
13 };
14 
15 enum Encoding : uint32_t /* e_encoding */
16 {
17    ELFDATANONE = 0,
18    ELFDATA2LSB = 1,
19    ELFDATA2MSB = 2
20 };
21 
22 enum Class : uint32_t /* e_class */
23 {
24    ELFCLASSNONE = 0,
25    ELFCLASS32 = 1,
26    ELFCLASS64 = 2
27 };
28 
29 enum Version : uint32_t /* e_elf_version */
30 {
31    EV_NONE = 0,
32    EV_CURRENT = 1,
33 };
34 
35 enum FileType : uint32_t /* e_type */
36 {
37    ET_NONE = 0,         /* No file type */
38    ET_REL = 1,          /* Relocatable file */
39    ET_EXEC = 2,         /* Executable file */
40    ET_DYN = 3,          /* Shared object file */
41    ET_CORE = 4,         /* Core file */
42    ET_LOPROC = 0xff00,  /* Beginning of processor-specific codes */
43    ET_CAFE_RPL = 0xff01, /* Cafe RPL file */
44    ET_HIPROC = 0xffff   /* Processor-specific */
45 };
46 
47 enum EABI : uint32_t /* e_abi */
48 {
49    EABI_CAFE = 0xcafe   /* WiiU CafeOS */
50 };
51 
52 enum SectionFlags : uint32_t /* sh_flags */
53 {
54    SHF_WRITE = 0x1,
55    SHF_ALLOC = 0x2,
56    SHF_EXECINSTR = 0x4,
57    SHF_DEFLATED = 0x08000000,
58    SHF_MASKPROC = 0xF0000000,
59 };
60 
61 enum SectionType : uint32_t /* sh_type */
62 {
63    SHT_NULL = 0,                 /* No associated section (inactive entry). */
64    SHT_PROGBITS = 1,             /* Program-defined contents. */
65    SHT_SYMTAB = 2,               /* Symbol table. */
66    SHT_STRTAB = 3,               /* String table. */
67    SHT_RELA = 4,                 /* Relocation entries; explicit addends. */
68    SHT_HASH = 5,                 /* Symbol hash table. */
69    SHT_DYNAMIC = 6,              /* Information for dynamic linking. */
70    SHT_NOTE = 7,                 /* Information about the file. */
71    SHT_NOBITS = 8,               /* Data occupies no space in the file. */
72    SHT_REL = 9,                  /* Relocation entries; no explicit addends. */
73    SHT_SHLIB = 10,               /* Reserved. */
74    SHT_DYNSYM = 11,              /* Symbol table. */
75    SHT_INIT_ARRAY = 14,          /* Pointers to initialization functions. */
76    SHT_FINI_ARRAY = 15,          /* Pointers to termination functions. */
77    SHT_PREINIT_ARRAY = 16,       /* Pointers to pre-init functions. */
78    SHT_GROUP = 17,               /* Section group. */
79    SHT_SYMTAB_SHNDX = 18,        /* Indices for SHN_XINDEX entries. */
80    SHT_LOPROC = 0x70000000,      /* Lowest processor arch-specific type. */
81    SHT_HIPROC = 0x7fffffff,      /* Highest processor arch-specific type. */
82    SHT_LOUSER = 0x80000000,      /* Lowest type reserved for applications. */
83    SHT_RPL_EXPORTS = 0x80000001, /* RPL Exports */
84    SHT_RPL_IMPORTS = 0x80000002, /* RPL Imports */
85    SHT_RPL_CRCS = 0x80000003,    /* RPL CRCs */
86    SHT_RPL_FILEINFO = 0x80000004,/* RPL FileInfo */
87    SHT_HIUSER = 0xffffffff       /* Highest type reserved for applications. */
88 };
89 
90 enum SymbolBinding : uint32_t /* st_info >> 4 */
91 {
92    STB_LOCAL = 0,       /* Local symbol, not visible outside obj file containing def */
93    STB_GLOBAL = 1,      /* Global symbol, visible to all object files being combined */
94    STB_WEAK = 2,        /* Weak symbol, like global but lower-precedence */
95    STB_GNU_UNIQUE = 10,
96    STB_LOOS = 10,       /* Lowest operating system-specific binding type */
97    STB_HIOS = 12,       /* Highest operating system-specific binding type */
98    STB_LOPROC = 13,     /* Lowest processor-specific binding type */
99    STB_HIPROC = 15      /* Highest processor-specific binding type */
100 };
101 
102 enum SymbolType : uint32_t /* st_info & f */
103 {
104    STT_NOTYPE = 0,      /* Symbol's type is not specified */
105    STT_OBJECT = 1,      /* Symbol is a data object (variable, array, etc.) */
106    STT_FUNC = 2,        /* Symbol is executable code (function, etc.) */
107    STT_SECTION = 3,     /* Symbol refers to a section */
108    STT_FILE = 4,        /* Local, absolute symbol that refers to a file */
109    STT_COMMON = 5,      /* An uninitialized common block */
110    STT_TLS = 6,         /* Thread local data object */
111    STT_LOOS = 7,        /* Lowest operating system-specific symbol type */
112    STT_HIOS = 8,        /* Highest operating system-specific symbol type */
113    STT_GNU_IFUNC = 10,  /* GNU indirect function */
114    STT_LOPROC = 13,     /* Lowest processor-specific symbol type */
115    STT_HIPROC = 15      /* Highest processor-specific symbol type */
116 };
117 
118 enum SectionIndex : uint16_t /* st_shndx */
119 {
120    SHN_UNDEF = 0,        /* Undefined */
121    SHN_LORESERVE = 0xff00,   /* Reserved range */
122    SHN_ABS = 0xfff1,   /* Absolute symbols */
123    SHN_COMMON = 0xfff2,   /* Common symbols */
124    SHN_XINDEX = 0xffff,   /* Escape -- index stored elsewhere */
125    SHN_HIRESERVE = 0xffff
126 };
127 
128 enum RelocationType : uint32_t /* r_info & 0xff */
129 {
130    R_PPC_NONE = 0,
131    R_PPC_ADDR32 = 1,
132    R_PPC_ADDR24 = 2,
133    R_PPC_ADDR16 = 3,
134    R_PPC_ADDR16_LO = 4,
135    R_PPC_ADDR16_HI = 5,
136    R_PPC_ADDR16_HA = 6,
137    R_PPC_ADDR14 = 7,
138    R_PPC_ADDR14_BRTAKEN = 8,
139    R_PPC_ADDR14_BRNTAKEN = 9,
140    R_PPC_REL24 = 10,
141    R_PPC_REL14 = 11,
142    R_PPC_REL14_BRTAKEN = 12,
143    R_PPC_REL14_BRNTAKEN = 13,
144    R_PPC_GOT16 = 14,
145    R_PPC_GOT16_LO = 15,
146    R_PPC_GOT16_HI = 16,
147    R_PPC_GOT16_HA = 17,
148    R_PPC_PLTREL24 = 18,
149    R_PPC_JMP_SLOT = 21,
150    R_PPC_RELATIVE = 22,
151    R_PPC_LOCAL24PC = 23,
152    R_PPC_REL32 = 26,
153    R_PPC_TLS = 67,
154    R_PPC_DTPMOD32 = 68,
155    R_PPC_TPREL16 = 69,
156    R_PPC_TPREL16_LO = 70,
157    R_PPC_TPREL16_HI = 71,
158    R_PPC_TPREL16_HA = 72,
159    R_PPC_TPREL32 = 73,
160    R_PPC_DTPREL16 = 74,
161    R_PPC_DTPREL16_LO = 75,
162    R_PPC_DTPREL16_HI = 76,
163    R_PPC_DTPREL16_HA = 77,
164    R_PPC_DTPREL32 = 78,
165    R_PPC_GOT_TLSGD16 = 79,
166    R_PPC_GOT_TLSGD16_LO = 80,
167    R_PPC_GOT_TLSGD16_HI = 81,
168    R_PPC_GOT_TLSGD16_HA = 82,
169    R_PPC_GOT_TLSLD16 = 83,
170    R_PPC_GOT_TLSLD16_LO = 84,
171    R_PPC_GOT_TLSLD16_HI = 85,
172    R_PPC_GOT_TLSLD16_HA = 86,
173    R_PPC_GOT_TPREL16 = 87,
174    R_PPC_GOT_TPREL16_LO = 88,
175    R_PPC_GOT_TPREL16_HI = 89,
176    R_PPC_GOT_TPREL16_HA = 90,
177    R_PPC_GOT_DTPREL16 = 91,
178    R_PPC_GOT_DTPREL16_LO = 92,
179    R_PPC_GOT_DTPREL16_HI = 93,
180    R_PPC_GOT_DTPREL16_HA = 94,
181    R_PPC_TLSGD = 95,
182    R_PPC_TLSLD = 96,
183    R_PPC_EMB_SDA21 = 109,
184    R_PPC_REL16 = 249,
185    R_PPC_REL16_LO = 250,
186    R_PPC_REL16_HI = 251,
187    R_PPC_REL16_HA = 252,
188 };
189 
190 enum RplFileInfoFlag : uint32_t
191 {
192    RPL_IS_RPX = 0x2,
193 };
194 
195 static const unsigned HeaderMagic = 0x7f454c46;
196 
197 struct Header
198 {
199    be_val<uint32_t> magic;       /* File identification. */
200    be_val<uint8_t> fileClass;    /* File class. */
201    be_val<uint8_t> encoding;     /* Data encoding. */
202    be_val<uint8_t> elfVersion;   /* File version. */
203    be_val<uint16_t> abi;         /* OS/ABI identification. (EABI_*) */
204    be_val<uint8_t> pad[7];
205 
206    be_val<uint16_t> type;        /* Type of file (ET_*) */
207    be_val<uint16_t> machine;     /* Required architecture for this file (EM_*) */
208    be_val<uint32_t> version;     /* Must be equal to 1 */
209    be_val<uint32_t> entry;       /* Address to jump to in order to start program */
210    be_val<uint32_t> phoff;       /* Program header table's file offset, in bytes */
211    be_val<uint32_t> shoff;       /* Section header table's file offset, in bytes */
212    be_val<uint32_t> flags;       /* Processor-specific flags */
213    be_val<uint16_t> ehsize;      /* Size of ELF header, in bytes */
214    be_val<uint16_t> phentsize;   /* Size of an entry in the program header table */
215    be_val<uint16_t> phnum;       /* Number of entries in the program header table */
216    be_val<uint16_t> shentsize;   /* Size of an entry in the section header table */
217    be_val<uint16_t> shnum;       /* Number of entries in the section header table */
218    be_val<uint16_t> shstrndx;    /* Sect hdr table index of sect name string table */
219 };
220 CHECK_SIZE(Header, 0x34);
221 
222 struct SectionHeader
223 {
224    be_val<uint32_t> name;      /* Section name (index into string table) */
225    be_val<uint32_t> type;      /* Section type (SHT_*) */
226    be_val<uint32_t> flags;     /* Section flags (SHF_*) */
227    be_val<uint32_t> addr;      /* Address where section is to be loaded */
228    be_val<uint32_t> offset;    /* File offset of section data, in bytes */
229    be_val<uint32_t> size;      /* Size of section, in bytes */
230    be_val<uint32_t> link;      /* Section type-specific header table index link */
231    be_val<uint32_t> info;      /* Section type-specific extra information */
232    be_val<uint32_t> addralign; /* Section address alignment */
233    be_val<uint32_t> entsize;   /* Size of records contained within the section */
234 };
235 CHECK_SIZE(SectionHeader, 0x28);
236 
237 struct Symbol
238 {
239    be_val<uint32_t> name;  /* Symbol name (index into string table) */
240    be_val<uint32_t> value; /* Value or address associated with the symbol */
241    be_val<uint32_t> size;  /* Size of the symbol */
242    be_val<uint8_t>  info;  /* Symbol's type and binding attributes */
243    be_val<uint8_t>  other; /* Must be zero; reserved */
244    be_val<uint16_t> shndx; /* Which section (header table index) it's defined in (SHN_*) */
245 };
246 CHECK_SIZE(Symbol, 0x10);
247 
248 struct Rela
249 {
250    be_val<uint32_t> offset;
251    be_val<uint32_t> info;
252    be_val<int32_t> addend;
253 };
254 CHECK_SIZE(Rela, 0x0C);
255 
256 struct RplImport
257 {
258    be_val<uint32_t> count;
259    be_val<uint32_t> signature;
260    char name[1];
261 };
262 
263 struct RplExport
264 {
265    struct Export
266    {
267       be_val<uint32_t> value;
268       be_val<uint32_t> name;
269    };
270 
271    be_val<uint32_t> count;
272    be_val<uint32_t> signature;
273    Export exports[1];
274 };
275 
276 struct RplCrc
277 {
278    be_val<uint32_t> crc;
279 };
280 CHECK_SIZE(RplCrc, 0x04);
281 
282 struct RplFileInfo
283 {
284    be_val<uint32_t> version;
285    be_val<uint32_t> textSize;
286    be_val<uint32_t> textAlign;
287    be_val<uint32_t> dataSize;
288    be_val<uint32_t> dataAlign;
289    be_val<uint32_t> loadSize;
290    be_val<uint32_t> loadAlign;
291    be_val<uint32_t> tempSize;
292    be_val<uint32_t> trampAdjust;
293    be_val<uint32_t> sdaBase;
294    be_val<uint32_t> sda2Base;
295    be_val<uint32_t> stackSize;
296    be_val<uint32_t> filename;
297    be_val<uint32_t> flags;
298    be_val<uint32_t> heapSize;
299    be_val<uint32_t> tagOffset;
300    be_val<uint32_t> minVersion;
301    be_val<int32_t> compressionLevel;
302    be_val<uint32_t> trampAddition;
303    be_val<uint32_t> fileInfoPad;
304    be_val<uint32_t> cafeSdkVersion;
305    be_val<uint32_t> cafeSdkRevision;
306    be_val<uint16_t> tlsModuleIndex;
307    be_val<uint16_t> tlsAlignShift;
308    be_val<uint32_t> runtimeFileInfoSize;
309 };
310 CHECK_SIZE(RplFileInfo, 0x60);
311 
312 } /* namespace elf */
313 
314 #pragma pack(pop)
315