1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - ELF Loader
3   File:     elf.h
4 
5   Copyright 2006-2008 Nintendo. All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law. They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Date:: 2008-09-18#$
14   $Rev: 8573 $
15   $Author: okubata_ryoma $
16  *---------------------------------------------------------------------------*/
17 
18 #ifndef ELF_H_
19 #define ELF_H_
20 
21 
22 
23 #ifdef SDK_TWL
24 #include <twl.h>
25 #else
26 #include <nitro.h>
27 #endif
28 
29 
30 
31 /*---------------------------------------------------------
32  Type Definitions
33  --------------------------------------------------------*/
34 typedef u32 Elf32_Addr;       /* size:4, align:4    Unsigned program address  */
35 typedef u16 Elf32_Half;       /* size:2, align:2    Unsigned medium int */
36 typedef u32 Elf32_Off;        /* size:4, align:4    Unsigned file offset */
37 typedef s32 Elf32_Sword;      /* size:4, align:4    Signed large int */
38 typedef u32 Elf32_Word;       /* size:4, align:4    Unsigned large int */
39 
40 /*---------------------------------------------------------
41  ELF Header
42  --------------------------------------------------------*/
43 /* e_ident index */
44 #define EI_MAG0       0        /* File identification */
45 #define EI_MAG1       1        /* File identification */
46 #define EI_MAG2       2        /* File identification */
47 #define EI_MAG3       3        /* File identification */
48 #define EI_CLASS      4        /* File class 0=invalid, 1=32bit, 2=64bit */
49 #define EI_DATA       5        /* Data encoding 0=invalid, 1=LSB, 2=MSB */
50 #define EI_VERSION    6        /* File version (currently 1) */
51 #define EI_PAD        7        /* Start of padding bytes */
52 #define EI_NIDENT    16        /* Size of e_ident[] */
53 
54 typedef struct {
55   unsigned char e_ident[EI_NIDENT];
56   Elf32_Half    e_type;      /* ELF format (relocatable, executable, etc.) */
57   Elf32_Half    e_machine;   /* Architecture requested by the file */
58   Elf32_Word    e_version;   /* Version of the ELF format (currently 1) */
59   Elf32_Addr    e_entry;     /* Program entry point. 0 if unspecified */
60   Elf32_Off     e_phoff;     /* Offset from the start of the file to the program header table */
61   Elf32_Off     e_shoff;     /* Offset from the start of the file to the section header table */
62   Elf32_Word    e_flags;     /* Processor-specific flags */
63   Elf32_Half    e_ehsize;    /* ELF header size */
64   Elf32_Half    e_phentsize; /* Size of a program header */
65   Elf32_Half    e_phnum;     /* Number of program headers */
66   Elf32_Half    e_shentsize; /* Size of a section header */
67   Elf32_Half    e_shnum;     /* Number of section headers */
68   Elf32_Half    e_shstrndx;  /* Index into the table section with strings for the section names */
69 } Elf32_Ehdr;
70 
71 /* Content defined for e_ident[EI_*] */
72 #define ELFMAG0         0x7f
73 #define ELFMAG1         'E'
74 #define ELFMAG2         'L'
75 #define ELFMAG3         'F'
76 #define ELFCLASSNONE    0        /* invalid */
77 #define ELFCLASS32      1        /* ARM and Thumb processors use 32-bit ELF. */
78 #define ELFCLASS64      2
79 #define ELFDATANONE     0        /* invalid */
80 #define ELFDATA2LSB     1        /* little-endian */
81 #define ELFDATA2MSB     2        /* big-endian */
82 
83 
84 /* [e_type] */
85 #define ET_NONE      0           /* No file type */
86 #define ET_REL       1           /* Re-locatable file */
87 #define ET_EXEC      2           /* Executable file */
88 #define ET_DYN       3           /* Shared object file */
89 #define ET_CORE      4           /* Core file */
90 #define ET_LOPROC    0xff00      /* Processor-specific */
91 #define ET_HIPROC    0xffff      /* Processor-specific */
92 
93 /* [e_machine] */
94 #define EM_NONE         0        /* No machine */
95 #define EM_M32          1
96 #define EM_SPARC        2
97 #define EM_386          3
98 #define EM_68K          4
99 #define EM_88K          5
100 #define EM_860          7
101 #define EM_MIPS         8
102 #define EM_MIPS_RS4_BE 10
103 #define EM_ARM         40        /* ARM/Thumb Architecture */
104 
105 
106 /* [e_version] This member identifies the object file version.*/
107 #define EV_NONE       0          /* Invalid version */
108 #define EV_CURRENT    1          /* Current version */
109 
110 
111 /*
112   ARM-specific e_flags
113   e_flags Field           Value   Meaning
114   EF_ARM_HASENTRY         (0x02)  e_entry contains a program-loader entry point
115                                   (See section 4.1.1, Entry points, below.)
116   EF_ARM_SYMSARESORTED    (0x04)  Each subsection of the symbol table is sorted by symbol value
117                                   (See section 4.4.8, Symbol table order, below.)
118   EF_ARM_DYNSYMSUSESEGIDX (0x8)   Symbols in dynamic symbol tables that are defined in sections
119                                   included in program segment n have st_shndx = n + 1.
120                                   (See section 4.4.9, Dynamic symbol table entries, below.)
121   EF_ARM_MAPSYMSFIRST     (0x10)  Mapping symbols precede other local symbols in the symbol table
122                                   (see section 4.4.8, Symbol table order, below).
123 
124   EF_ARM_EABIMASK         (0xFF000000)(current version is 0x02000000)
125                                   This masks an 8-bit version number, the version of the ARM
126                                   EABI to which this ELF file conforms. This EABI is version 2. A
127                                   value of 0 denotes unknown conformance.
128 */
129 #define EF_ARM_HASENTRY         0x02
130 #define EF_ARM_SYMSARESORTED    0x04
131 #define EF_ARM_DYNSYMSUSESEGIDX 0x8
132 #define EF_ARM_MAPSYMSFIRST     0x10
133 #define EF_ARM_EABIMASK         0xFF000000
134 
135 
136 /*---------------------------------------------------------
137  Program headers
138  --------------------------------------------------------*/
139 typedef struct {
140   Elf32_Word p_type;
141   Elf32_Off  p_offset;
142   Elf32_Addr p_vaddr;
143   Elf32_Addr p_paddr;
144   Elf32_Word p_filesz;
145   Elf32_Word p_memsz;
146   Elf32_Word p_flags;
147   Elf32_Word p_align;
148 } Elf32_Phdr;
149 
150 /* [p_type] */
151 #define PT_NULL    0 /* An unused entry; the meaning of other member values is undefined */
152 #define PT_LOAD    1 /* Segment that will be loaded at run time */
153 #define PT_DYNAMIC 2 /* Segment that stores a dynamic structure array */
154 #define PT_INTERP  3 /* Segment that stores the path of the interpreter used to parse the file */
155 #define PT_NOTE    4 /* Segment that stores information not used to parse the file */
156 #define PT_SHLIB   5 /* Reserved */
157 #define PT_PHDR    6 /* Program header table (exists only when part of the program's memory image is used) */
158 //#define PT_TLS   ? /* Template for the thread-local storage segment */
159 
160 #define PT_LOOS    0x60000000  /* OS-specific reserved region */
161 #define PT_HIOS    0x6fffffff
162 
163 #define PT_LOPROC  0x70000000  /* Processor-specific reserved region */
164 #define PT_HIPROC  0x7fffffff
165 
166 /* [p_flags]*/
167 #define PF_X         1          /*Executable*/
168 #define PF_W         2          /*Writeable*/
169 #define PF_R         4          /*Readable*/
170 #define PF_ARM_SB    0x10000000 /*The segment contains the location addressed by the static base*/
171 #define PF_ARM_PI    0x20000000 /*The segment is position-independent*/
172 #define PF_ARM_ENTRY 0x80000000 /*The segment contains the entry point*/
173 #define PF_MASKPROC  0xf0000000
174 
175 
176 /*---------------------------------------------------------
177  Section headers
178  --------------------------------------------------------*/
179 typedef struct {
180   Elf32_Word    sh_name;        /*Index into the table section with strings for the section headers*/
181   Elf32_Word    sh_type;        /* Type (refer to the definitions below) */
182   Elf32_Word    sh_flags;
183   Elf32_Addr    sh_addr;        /*  */
184   Elf32_Off     sh_offset;      /* Offset from the start of the file */
185   Elf32_Word    sh_size;        /* Size in bytes */
186   Elf32_Word    sh_link;        /* The meaning of this value changes with sh_type */
187   Elf32_Word    sh_info;        /* The meaning of this value changes with sh_type */
188   Elf32_Word    sh_addralign;   /* Alignment restrictions (no restrictions when this is 0 or 1, and 4-byte alignment when this is 4) */
189   Elf32_Word    sh_entsize;     /* Size of a single element when there is a fixed-size entry table */
190 } Elf32_Shdr;
191 
192 /* sh_addr mod sh_addralign must equal 0 */
193 
194 /* Section Types, [sh_type] */
195 #define SHT_NULL     0
196 #define SHT_PROGBITS 1
197 #define SHT_SYMTAB   2
198 #define SHT_STRTAB   3
199 #define SHT_RELA     4
200 #define SHT_HASH     5
201 #define SHT_DYNAMIC  6
202 #define SHT_NOTE     7
203 #define SHT_NOBITS   8
204 #define SHT_REL      9
205 #define SHT_SHLIB   10
206 #define SHT_DYNSYM  11
207 #define SHT_LOPROC  0x70000000
208 #define SHT_HIPROC  0x7fffffff
209 #define SHT_LOUSER  0x80000000
210 #define SHT_HIUSER  0xffffffff
211 
212 
213 /* [sh_flags] */
214 #define SHF_WRITE     0x1
215 #define SHF_ALLOC     0x2
216 #define SHF_EXECINSTR 0x4
217 #define SHF_MASKPROC  0xf0000000
218 /* ARM-EABI-specific */
219 #define SHF_ENTRYSECT      0x10000000   /* The section contains an entry point.  */
220 #define SHF_COMDEF         0x80000000   /* The section may be multiply defined in the input to a link step.  */
221 /* Others */
222 #define SHF_LINK_ORDER     0x80
223 
224 /*Section index*/
225 //Sym->st_shndx, etc.
226 #define SHN_UNDEF          0
227 #define SHN_LORESERVE      0xff00
228 #define SHN_LOPROC         0xff00
229 #define SHN_HIPROC         0xff1f
230 #define SHN_ABS            0xfff1
231 #define SHN_COMMON         0xfff2
232 #define SHN_HIRESERVE      0xffff
233 
234 
235 //Structures after this point contain the actual data, not headers
236 
237 /*---------------------------------------------------------
238  Symbol Table Entry
239  --------------------------------------------------------*/
240 typedef struct {
241   Elf32_Word    st_name;    /* Index into the symbol string table */
242   Elf32_Addr    st_value;    /* Probably the offset value into the associated section */
243   Elf32_Word    st_size;    /* 0 if the size does not exist or is unknown */
244   unsigned char st_info;    /* Type and binding attributes */
245   unsigned char st_other;    /* Currently contains 0 */
246   Elf32_Half    st_shndx;    /* Related section header table index */
247 } Elf32_Sym;
248 
249 
250 /* st_info */
251 #define ELF32_ST_BIND(i) ((i)>>4)
252 #define ELF32_ST_TYPE(i) ((i)&0xf)
253 #define ELF32_ST_INFO(b,t) (((b)<<4)+((t)&0xf))
254 
255 /* Binding attributes for st_info */
256 #define STB_LOCAL   0
257 #define STB_GLOBAL  1
258 #define STB_WEAK    2
259 #define STB_LOPROC 13
260 #define STB_HIPROC 15
261 
262 /* Symbol types for st_info */
263 #define STT_NOTYPE  0        /*Undefined*/
264 #define STT_OBJECT  1        /*Data object*/
265 #define STT_FUNC    2
266 #define STT_SECTION 3
267 #define STT_FILE    4
268 #define STT_LOPROC 13
269 #define STT_HIPROC 15
270 
271 
272 /*---------------------------------------------------------
273  Relocation Entry
274  --------------------------------------------------------*/
275 typedef struct {
276   Elf32_Addr r_offset;
277   Elf32_Word r_info;
278 } Elf32_Rel;
279 
280 typedef struct {
281   Elf32_Addr r_offset;
282   Elf32_Word r_info;
283   Elf32_Sword r_addend;
284 } Elf32_Rela;
285 
286 #define ELF32_R_SYM(i) ((i)>>8)
287 #define ELF32_R_TYPE(i) ((unsigned char)(i))
288 #define ELF32_R_INFO(s,t) (((s)<<8)+(unsigned char)(t))
289 
290 
291 /* r_info type */
292 #define R_ARM_NONE        0 /* Any No relocation. Encodes dependencies between sections. */
293 #define R_ARM_PC24        1 /* ARM B/BL S . P + A */
294 #define R_ARM_ABS32       2 /* 32-bit word S + A */
295 #define R_ARM_REL32       3 /* 32-bit word S . P + A */
296 #define R_ARM_PC13        4 /* ARM LDR r, [pc,...] S . P + A */
297 #define R_ARM_ABS16       5 /* 16-bit half-word S + A */
298 #define R_ARM_ABS12       6 /* ARM LDR/STR S + A */
299 #define R_ARM_THM_ABS5    7 /* Thumb LDR/STR S + A */
300 #define R_ARM_ABS8        8 /* 8-bit byte S + A */
301 #define R_ARM_SBREL32     9 /* 32-bit word S . B + A */
302 #define R_ARM_THM_PC22   10 /* Thumb BL pair S . P+ A */
303 #define R_ARM_THM_PC8    11 /* Thumb LDR r, [pc,...] S . P + A */
304 #define R_ARM_AMP_VCALL9 12 /* AMP VCALL Obsolete.SA-1500 only. */
305 #define R_ARM_SWI24      13 /* ARM SWI S + A */
306 #define R_ARM_THM_SWI8   14 /* Thumb SWI S + A */
307 #define R_ARM_XPC25      15 /* ARM BLX S . P+ A */
308 #define R_ARM_THM_XPC22  16 /* Thumb BLX pair S . P+ A */
309 
310 /* 17-31, reserved to ARM Linux */
311 //17-19 Reserved to ARM LINUX
312 #define R_ARM_COPY      20 /* 32 bit word Copy symbol at dynamic link time. */
313 #define R_ARM_GLOB_DAT  21 /* 32 bit word Create GOT entry. */
314 #define R_ARM_JUMP_SLOT 22 /* 32 bit word Create PLT entry. */
315 #define R_ARM_RELATIVE  23 /* 32 bit word Adjust by program base. */
316 #define R_ARM_GOTOFF    24 /* 32 bit word Offset relative to start of GOT. */
317 #define R_ARM_GOTPC     25 /* 32 bit word Insert address of GOT. */
318 #define R_ARM_GOT32     26 /* 32 bit word Entry in GOT. */
319 #define R_ARM_PLT32     27 /* ARM BL Entry in PLT. */
320 
321 /* 28-31 Reserved to ARM LINUX */
322 #define R_ARM_ALU_PCREL_7_0   32 /* ARM ADD/SUB (S . P + A) & 0x000000FF */
323 #define R_ARM_ALU_PCREL_15_8  33 /* ARM ADD/SUB (S . P + A) & 0x0000FF00 */
324 #define R_ARM_ALU_PCREL_23_15 34 /* ARM ADD/SUB (S . P + A) & 0x00FF0000 */
325 #define R_ARM_LDR_SBREL_11_0  35 /* ARM LDR/STR (S . B + A) & 0x00000FFF */
326 #define R_ARM_ALU_SBREL_19_12 36 /* ARM ADD/SUB (S . B + A) & 0x000FF000 */
327 #define R_ARM_ALU_SBREL_27_20 37 /* ARM ADD/SUB (S . B + A) & 0x0FF00000 */
328 
329 #define R_ARM_TARGET1     38
330 #define R_ARM_ROSEGREL32  39
331 #define R_ARM_V4BX        40
332 #define R_ARM_TARGET2     41
333 #define R_ARM_PREL31      42
334 
335 /* 96-111, reserved to ARM g++ */
336 #define R_ARM_GNU_VTENTRY   100 /* 32 bit word Record C++ vtable entry. */
337 #define R_ARM_GNU_VTINHERIT 101 /* 32 bit word Record C++ member usage. */
338 #define R_ARM_THM_PC11      102 /* Thumb B S . P + A */
339 #define R_ARM_THM_PC9       103 /* Thumb B<cond> S . P + A */
340 
341 /* 112-127, reserved for private experiments */
342 
343 /* 128-248, reserved to ARM */
344 #define R_ARM_RXPC25    249 /* ARM BLX (delta S . delta P) + A #define For calls between program segments */
345 #define R_ARM_RSBREL32  250 /* Word (delta S . delta SB) + A For an offset from SB, the static base */
346 #define R_ARM_THM_RPC22 251 /* Thumb BL/BLX pair (delta S . delta P) + A For calls between program segments */
347 #define R_ARM_RREL32    252 /* Word (delta S . delta P) + A For on offset between two segments */
348 #define R_ARM_RABS32    253 /* Word delta S + A For the address of a location in the target segment */
349 #define R_ARM_RPC24     254 /* ARM B/BL (delta S . delta P) + A For calls between program segments */
350 #define R_ARM_RBASE     255 /* None None.Identifies the segment being relocated by the following
351                    relocation directives. The ARM EABI poses two problems for relocating
352                    executables and shared objects encoded in */
353 
354 
355 // shirait
356 #define R_ARM_LDR_PC_G0        4    //LDR
357 
358 #define R_ARM_ABS12            6    //LDR, STR
359 
360 #define R_ARM_THM_CALL        10    //Identical to R_ARM_THM_PC22
361 
362 #define R_ARM_CALL            28    //BL/BLX
363 #define R_ARM_JUMP24          29    //B/BL<cond>
364 #define R_ARM_THM_JUMP24      30
365 
366 #define R_ARM_MOVW_ABS_NC     43    //MOVW
367 #define R_ARM_MOVT_ABS        44    //MOVT
368 #define R_ARM_MOVW_PREL_NC    45    //MOVW
369 #define R_ARM_MOVT_PREL       46    //MOVT
370 
371 #define R_ARM_ALU_PC_G0_NC    57    //ADD, SUB
372 #define R_ARM_ALU_PC_G0       58    //ADD, SUB
373 #define R_ARM_ALU_PC_G1_NC    59    //ADD, SUB
374 #define R_ARM_ALU_PC_G1       60    //ADD, SUB
375 #define R_ARM_ALU_PC_G2       61    //ADD, SUB
376 #define R_ARM_LDR_PC_G1       62    //LDR, STR, LDRB, STRB
377 #define R_ARM_LDR_PC_G2       63    //LDR, STR, LDRB, STRB
378 #define R_ARM_LDRS_PC_G0      64    //LDRD, STRD, LDRH, STRH, LDRSH, LDRSB
379 #define R_ARM_LDRS_PC_G1      65    //LDRD, STRD, LDRH, STRH, LDRSH, LDRSB
380 #define R_ARM_LDRS_PC_G2      66    //LDRD, STRD, LDRH, STRH, LDRSH, LDRSB
381 #define R_ARM_LDC_PC_G0       67    //LDC, STC
382 #define R_ARM_LDC_PC_G1       68    //LDC, STC
383 #define R_ARM_LDC_PC_G2       69    //LDC, STC
384 #define R_ARM_ALU_SB_G0_NC    70    //ADD, SUB
385 #define R_ARM_ALU_SB_G0       71    //ADD, SUB
386 #define R_ARM_ALU_SB_G1_NC    72    //ADD, SUB
387 #define R_ARM_ALU_SB_G1       73    //ADD, SUB
388 #define R_ARM_ALU_SB_G2       74    //ADD, SUB
389 #define R_ARM_LDR_SB_G0       75    //LDR, STR, LDRB, STRB
390 #define R_ARM_LDR_SB_G1       76    //LDR, STR, LDRB, STRB
391 #define R_ARM_LDR_SB_G2       77    //LDR, STR, LDRB, STRB
392 #define R_ARM_LDRS_SB_G0      78    //LDRD, STRD, LDRH, STRH, LDRSH, LDRSB
393 #define R_ARM_LDRS_SB_G1      79    //LDRD, STRD, LDRH, STRH, LDRSH, LDRSB
394 #define R_ARM_LDRS_SB_G2      80    //LDRD, STRD, LDRH, STRH, LDRSH, LDRSB
395 #define R_ARM_LDC_SB_G0       81    //LDC, STC
396 #define R_ARM_LDC_SB_G1       82    //LDC, STC
397 #define R_ARM_LDC_SB_G2       83    //LDC, STC
398 #define R_ARM_MOVW_BREL_NC    84    //MOVW
399 #define R_ARM_MOVT_BREL       85    //MOVT
400 #define R_ARM_MOVW_BREL       86    //MOVW
401 
402 #define R_ARM_GOT_BREL12      97    //LDR
403 #define R_ARM_GOTOFF12        98    //LDR, STR
404 
405 #define R_ARM_TLS_LDO12      109    //LDR, STR
406 #define R_ARM_TLS_LE12       110    //LDR, STR
407 #define R_ARM_TLS_TE12GP     111    //LDR
408 
409 
410 
411 /*---------------------------------------------------------
412  Dynamic Section elf_v1.2
413  --------------------------------------------------------*/
414 typedef struct {
415   Elf32_Sword d_tag;
416   union {
417     Elf32_Word d_val;
418     Elf32_Addr d_ptr;
419   } d_un;
420 } Elf32_Dyn;
421 
422 
423 /* Additional symbol types for Thumb.  */
424 #define STT_ARM_TFUNC      STT_LOPROC   /* A Thumb function.  */
425 #define STT_ARM_16BIT      STT_HIPROC   /* A Thumb label.  */
426 
427 
428 /*---------------------------------------------------------
429  Read out the ELF header
430  --------------------------------------------------------*/
431 void *ELF_LoadELFHeader(const void *buf, Elf32_Ehdr *ehdr);
432 
433 #endif /* ELF_H_ */
434