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