1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - ELF Loader
3 File: elf.c
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 #include "types.h"
18
19 #include "elf.h"
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23
24 static int endian;
25 //static BOOL load_strndx_done = FALSE;
26
27
28 #if 0
29 /*---------------------------------------------------------
30 Read byte data
31 --------------------------------------------------------*/
32 static u8 *load_elf32_byte(u8 *dest, u8 *org, int lsb)
33 {
34 u8 *temp_ptr;
35
36 temp_ptr = (u8 *)org;
37 *dest = *temp_ptr;
38 temp_ptr++;
39
40 return temp_ptr;
41 }
42 #endif
43
44 /*---------------------------------------------------------
45 Read half-word data
46 --------------------------------------------------------*/
load_elf32_half(Elf32_Half * dest,u8 * org,int lsb)47 static u8 *load_elf32_half(Elf32_Half *dest, u8 *org, int lsb)
48 {
49 u8 *temp_ptr;
50
51 temp_ptr = (u8 *)org;
52 if( lsb == ELFDATA2LSB ) {
53 *dest = (u16)((u16)(*temp_ptr) & 0x00ff);
54 temp_ptr++;
55 *dest |= ((u16)(*temp_ptr) << 8 ) & 0xff00;
56 temp_ptr++;
57 }
58 else /* ELFDATA2MSB*/ {
59 *dest = (u16)(((u16)(*temp_ptr) << 8 ) & 0xff00);
60 temp_ptr++;
61 *dest |= ((u16)(*temp_ptr) & 0x00ff);
62 temp_ptr++;
63 }
64 return (void *)temp_ptr;
65 }
66
67 #if 0
68 /*---------------------------------------------------------
69 Read word data
70 --------------------------------------------------------*/
71 static u8 *load_elf32_sword(Elf32_Sword *dest, u8 *org, int lsb)
72 {
73 u8 *temp_ptr;
74 u32 temp;
75
76 temp_ptr = (u8 *)org;
77 if( lsb == ELFDATA2LSB ) {
78 temp = ((u32)(*temp_ptr) & 0x000000ff);
79 temp_ptr++;
80 temp |= (((u32)(*temp_ptr) << 8 ) & 0x0000ff00);
81 temp_ptr++;
82 temp |= (((u32)(*temp_ptr) << 16 ) & 0x00ff0000);
83 temp_ptr++;
84 temp |= (((u32)(*temp_ptr) << 24 ) & 0xff000000);
85 temp_ptr++;
86 }
87 else /* ELFDATA2MSB*/ {
88 temp = (((u32)(*temp_ptr) << 24 ) & 0xff000000);
89 temp_ptr++;
90 temp |= (((u32)(*temp_ptr) << 16 ) & 0x00ff0000);
91 temp_ptr++;
92 temp |= (((u32)(*temp_ptr) << 8 ) & 0x0000ff00);
93 temp_ptr++;
94 temp |= ((u32)(*temp_ptr) & 0x000000ff);
95 temp_ptr++;
96 }
97 *dest = *( (Elf32_Sword *)&temp );
98 return (void *)temp_ptr;
99 }
100
101
102 static u8 *load_elf32_word(Elf32_Word *dest, u8 *org, int lsb)
103 {
104 u8 *temp_ptr;
105 temp_ptr = (u8 *)org;
106 if( lsb == ELFDATA2LSB ) {
107 *dest = ((u32)(*temp_ptr) & 0x000000ff);
108 temp_ptr++;
109 *dest |= (((u32)(*temp_ptr) << 8 ) & 0x0000ff00);
110 temp_ptr++;
111 *dest |= (((u32)(*temp_ptr) << 16 ) & 0x00ff0000);
112 temp_ptr++;
113 *dest |= (((u32)(*temp_ptr) << 24 ) & 0xff000000);
114 temp_ptr++;
115 }
116 else /* ELFDATA2MSB*/ {
117 *dest = (((u32)(*temp_ptr) << 24 ) & 0xff000000);
118 temp_ptr++;
119 *dest |= (((u32)(*temp_ptr) << 16 ) & 0x00ff0000);
120 temp_ptr++;
121 *dest |= (((u32)(*temp_ptr) << 8 ) & 0x0000ff00);
122 temp_ptr++;
123 *dest |= ((u32)(*temp_ptr) & 0x000000ff);
124 temp_ptr++;
125 }
126 return (void *)temp_ptr;
127 }
128 #endif
129
130 /*---------------------------------------------------------
131 Read ELF header
132
133 buf: Address of ELF header
134 ehdr: Buffer for writing read data
135 --------------------------------------------------------*/
ELF_LoadELFHeader(const void * buf,Elf32_Ehdr * ehdr)136 void *ELF_LoadELFHeader(const void *buf, Elf32_Ehdr *ehdr)
137 {
138 u8 *file_ptr;
139
140 if( !buf ) {
141 return NULL;
142 }
143
144 file_ptr = (u8 *)buf;
145
146 /* Copy to buffer */
147 //MI_CpuCopy8( (void*)file_ptr, ehdr->e_ident, EI_NIDENT);
148 memcpy( (void*)(ehdr->e_ident), (void*)file_ptr, EI_NIDENT);
149 file_ptr += EI_NIDENT;
150
151 /* Magic Number*/
152 if( ehdr->e_ident[EI_MAG0] != ELFMAG0 ) {
153 return NULL;
154 }
155 if( ehdr->e_ident[EI_MAG1] != ELFMAG1 ) {
156 return NULL;
157 }
158 if( ehdr->e_ident[EI_MAG2] != ELFMAG2 ) {
159 return NULL;
160 }
161 if( ehdr->e_ident[EI_MAG3] != ELFMAG3 ) {
162 return NULL;
163 }
164
165 /* CLASS*/
166 switch( ehdr->e_ident[EI_CLASS] ) {
167 case ELFCLASSNONE:
168 break;
169 case ELFCLASS32:
170 break;
171 case ELFCLASS64:
172 break;
173 default:
174 break;
175 }
176
177 /* DATA*/
178 switch( ehdr->e_ident[EI_DATA] ) {
179 case ELFDATANONE:
180 break;
181 case ELFDATA2LSB:
182 endian = ELFDATA2LSB;
183 break;
184 case ELFDATA2MSB:
185 endian = ELFDATA2MSB;
186 break;
187 default:
188 break;
189 }
190
191 /* TYPE*/
192 file_ptr = load_elf32_half(&(ehdr->e_type), file_ptr, endian);
193 switch( ehdr->e_type ) {
194 case ET_NONE:
195 break;
196 case ET_REL:
197 break;
198 case ET_EXEC:
199 break;
200 case ET_DYN:
201 break;
202 case ET_CORE:
203 break;
204 case ET_LOPROC:
205 break;
206 case ET_HIPROC:
207 break;
208 default:
209 break;
210 }
211
212 /*---------- ELF Header Display ----------*/
213 /* printf( "\nELF Header:\n");
214 file_ptr = load_elf32_half(&(ehdr->e_machine), file_ptr, endian);
215 printf("e_machine = %d\n",ehdr->e_machine);
216
217 file_ptr = load_elf32_word(&(ehdr->e_version), file_ptr, endian);
218 printf("e_version = %d\n",ehdr->e_version);
219
220 file_ptr = load_elf32_word(&(ehdr->e_entry), file_ptr, endian);
221 printf("e_entry(entry point) = 0x%08x\n",ehdr->e_entry);
222
223 file_ptr = load_elf32_word(&(ehdr->e_phoff), file_ptr, endian);
224 printf("e_phoff(program header offset) = 0x%08x\n",ehdr->e_phoff);
225
226 file_ptr = load_elf32_word(&(ehdr->e_shoff), file_ptr, endian);
227 printf("e_shoff(section header offset) = 0x%08x\n",ehdr->e_shoff);
228
229 file_ptr = load_elf32_word(&(ehdr->e_flags), file_ptr, endian);
230 printf("e_flags = 0x%08x\n",ehdr->e_flags);
231 if( ehdr->e_flags & EF_ARM_HASENTRY ) {
232 printf("has entry\n");
233 }
234 if( ehdr->e_flags & EF_ARM_SYMSARESORTED ) {
235 printf("symbols are sorted\n");
236 }
237 if( ehdr->e_flags & EF_ARM_DYNSYMSUSESEGIDX ) {
238 printf("dynamic symbols use segmnet index\n");
239 }
240 if( ehdr->e_flags & EF_ARM_MAPSYMSFIRST ) {
241 printf("map symbols first\n");
242 }
243 printf("EABI version %x \n", (ehdr->e_flags & EF_ARM_EABIMASK) >> 24 );
244
245
246 file_ptr = load_elf32_half(&(ehdr->e_ehsize), file_ptr, endian);
247 printf("e_ehsize = %d\n",ehdr->e_ehsize);
248
249 file_ptr = load_elf32_half(&(ehdr->e_phentsize), file_ptr, endian);
250 printf("e_phentsize = %d\n",ehdr->e_phentsize);
251
252 file_ptr = load_elf32_half(&(ehdr->e_phnum), file_ptr, endian);
253 printf("e_phnum = %d\n",ehdr->e_phnum);
254
255 file_ptr = load_elf32_half(&(ehdr->e_shentsize), file_ptr, endian);
256 printf("e_shentsize = %d\n",ehdr->e_shentsize);
257
258 file_ptr = load_elf32_half(&(ehdr->e_shnum), file_ptr, endian);
259 printf("e_shnum = %d\n",ehdr->e_shnum);
260
261 file_ptr = load_elf32_half(&(ehdr->e_shstrndx), file_ptr, endian);
262 printf("e_shstrndx(section index no. of the section header string table section = %d\n",ehdr->e_shstrndx);
263 printf("\n");*/
264 /*-----------------------------------*/
265
266 return file_ptr;
267 }
268
269 #if 0
270 /*---------------------------------------------------------
271 Relocation Entry Load
272 --------------------------------------------------------*/
273 static void *ELF_LoadRel(const void *buf, Elf32_Rel *rel)
274 {
275 u8 *file_ptr;
276
277 if( !buf ) {
278 return NULL;
279 }
280
281 file_ptr = (u8 *)buf;
282 file_ptr = load_elf32_word(&(rel->r_offset), file_ptr, endian);
283 file_ptr = load_elf32_word(&(rel->r_info), file_ptr, endian);
284
285 return file_ptr;
286 }
287
288 static void *ELF_LoadRela(const void *buf, Elf32_Rela *rela)
289 {
290 u8 *file_ptr;
291
292 if( !buf ) {
293 return NULL;
294 }
295
296 file_ptr = (u8 *)buf;
297 file_ptr = load_elf32_word(&(rela->r_offset), file_ptr, endian);
298 file_ptr = load_elf32_word(&(rela->r_info), file_ptr, endian);
299 file_ptr = load_elf32_sword(&(rela->r_addend), file_ptr, endian);
300
301 return file_ptr;
302 }
303
304
305 /*---------------------------------------------------------
306 Symbol Table Entry Load
307 buf: Pointer to buffer to load the symbol entry
308 sym: Header address of load source symbol entry
309 --------------------------------------------------------*/
310 static void *ELF_LoadSymbol(const void *buf, Elf32_Sym *sym)
311 {
312 u8 *file_ptr;
313
314 if( !buf ) {
315 return NULL;
316 }
317
318 file_ptr = (u8 *)buf;
319 file_ptr = load_elf32_word(&(sym->st_name), file_ptr, endian);
320 file_ptr = load_elf32_word(&(sym->st_value), file_ptr, endian);
321 file_ptr = load_elf32_word(&(sym->st_size), file_ptr, endian);
322 file_ptr = load_elf32_byte(&(sym->st_info), file_ptr, endian);
323 file_ptr = load_elf32_byte(&(sym->st_other), file_ptr, endian);
324 file_ptr = load_elf32_half(&(sym->st_shndx), file_ptr, endian);
325
326 return file_ptr;
327 }
328
329
330 /*---------------------------------------------------------
331 Section Header Load
332 buf: Pointer to buffer to load the section header
333 shdr: Header address of load source section header
334 --------------------------------------------------------*/
335 static void *ELF_LoadSectionHeader(const void *buf,Elf32_Shdr *shdr)
336 {
337 u8 *file_ptr;
338
339 if( !buf ) {
340 return NULL;
341 }
342
343 file_ptr = (u8 *)buf;
344 file_ptr = load_elf32_word(&(shdr->sh_name), file_ptr, endian);
345 file_ptr = load_elf32_word(&(shdr->sh_type), file_ptr, endian);
346 file_ptr = load_elf32_word(&(shdr->sh_flags), file_ptr, endian);
347 file_ptr = load_elf32_word(&(shdr->sh_addr), file_ptr, endian);
348 file_ptr = load_elf32_word(&(shdr->sh_offset), file_ptr, endian);
349 file_ptr = load_elf32_word(&(shdr->sh_size), file_ptr, endian);
350 file_ptr = load_elf32_word(&(shdr->sh_link), file_ptr, endian);
351 file_ptr = load_elf32_word(&(shdr->sh_info), file_ptr, endian);
352 file_ptr = load_elf32_word(&(shdr->sh_addralign), file_ptr, endian);
353 file_ptr = load_elf32_word(&(shdr->sh_entsize ), file_ptr, endian);
354
355 return file_ptr;
356 }
357 #endif
358