/[pcsx2_0.9.7]/branch/r3113_0.9.7_beta/fps2bios/kernel/iopload/iopelf.c
ViewVC logotype

Contents of /branch/r3113_0.9.7_beta/fps2bios/kernel/iopload/iopelf.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 32 - (show annotations) (download)
Tue Sep 7 03:29:01 2010 UTC (10 years, 10 months ago) by william
File MIME type: text/plain
File size: 9457 byte(s)
branching from upstream revision (http://pcsx2.googlecode.com/svn/trunk
): r3113 to
https://svn.netsolutions.dnsalias.com/websvn/ps2/pcsx2/pcsx2_0.9.7/branch/r3113_0.9.7_beta
1 #include "romdir.h"
2 #include "iopelf.h"
3
4 typedef struct {
5 u32 st_name;
6 u32 st_value;
7 u32 st_size;
8 u8 st_info;
9 u8 st_other;
10 u16 st_shndx;
11 } Elf32_Sym;
12
13 char *sections_names;
14
15 ELF_HEADER *elfHeader;
16 ELF_PHR *elfProgH;
17 ELF_SHR *elfSectH;
18 u8 *elfdata;
19 int elfsize;
20 u32 elfbase;
21 static int debug=1;
22
23 #define _dprintf(fmt, args...) \
24 if (debug > 0) __printf("iopelf: " fmt, ## args)
25
26 static void __memcpy(void *dest, const void *src, int n) {
27 const u8 *s = (u8*)src;
28 u8 *d = (u8*)dest;
29
30 while (n) {
31 *d++ = *s++; n--;
32 }
33 }
34
35
36 int loadHeaders() {
37 elfHeader = (ELF_HEADER*)elfdata;
38
39 if ((elfHeader->e_shentsize != sizeof(ELF_SHR)) && (elfHeader->e_shnum > 0)) {
40 return -1;
41 }
42
43 #ifdef ELF_LOG
44 ELF_LOG( "type: " );
45 #endif
46 switch( elfHeader->e_type )
47 {
48 default:
49 #ifdef ELF_LOG
50 ELF_LOG( "unknown %x", elfHeader->e_type );
51 #endif
52 break;
53
54 case 0x0:
55 #ifdef ELF_LOG
56 ELF_LOG( "no file type" );
57 #endif
58 break;
59
60 case 0x1:
61 #ifdef ELF_LOG
62 ELF_LOG( "relocatable" );
63 #endif
64 break;
65
66 case 0x2:
67 #ifdef ELF_LOG
68 ELF_LOG( "executable" );
69 #endif
70 break;
71 }
72 #ifdef ELF_LOG
73 ELF_LOG( "\n" );
74 ELF_LOG( "machine: " );
75 #endif
76 switch ( elfHeader->e_machine )
77 {
78 default:
79 #ifdef ELF_LOG
80 ELF_LOG( "unknown" );
81 #endif
82 break;
83
84 case 0x8:
85 #ifdef ELF_LOG
86 ELF_LOG( "mips_rs3000" );
87 #endif
88 break;
89 }
90 #ifdef ELF_LOG
91 ELF_LOG("\n");
92 ELF_LOG("version: %d\n",elfHeader->e_version);
93 ELF_LOG("entry: %08x\n",elfHeader->e_entry);
94 ELF_LOG("flags: %08x\n",elfHeader->e_flags);
95 ELF_LOG("eh size: %08x\n",elfHeader->e_ehsize);
96 ELF_LOG("ph off: %08x\n",elfHeader->e_phoff);
97 ELF_LOG("ph entsiz: %08x\n",elfHeader->e_phentsize);
98 ELF_LOG("ph num: %08x\n",elfHeader->e_phnum);
99 ELF_LOG("sh off: %08x\n",elfHeader->e_shoff);
100 ELF_LOG("sh entsiz: %08x\n",elfHeader->e_shentsize);
101 ELF_LOG("sh num: %08x\n",elfHeader->e_shnum);
102 ELF_LOG("sh strndx: %08x\n",elfHeader->e_shstrndx);
103
104 ELF_LOG("\n");
105 #endif
106
107 return 0;
108 }
109
110
111 int loadProgramHeaders() {
112 int i;
113
114 if (elfHeader->e_phnum == 0) {
115 return 0;
116 }
117
118 if (elfHeader->e_phentsize != sizeof(ELF_PHR)) {
119 return -1;
120 }
121
122 elfProgH = (ELF_PHR*)&elfdata[elfHeader->e_phoff];
123
124 for ( i = 0 ; i < elfHeader->e_phnum ; i++ )
125 {
126 #ifdef ELF_LOG
127 ELF_LOG( "Elf32 Program Header\n" );
128 ELF_LOG( "type: " );
129 #endif
130 switch ( elfProgH[ i ].p_type )
131 {
132 default:
133 #ifdef ELF_LOG
134 ELF_LOG( "unknown %x", (int)elfProgH[ i ].p_type );
135 #endif
136 break;
137
138 case 0x1:
139 #ifdef ELF_LOG
140 ELF_LOG("load");
141 #endif
142 /* if ( elfHeader->e_shnum == 0 ) {*/
143 if (elfProgH[ i ].p_offset < elfsize) {
144 int size;
145
146 if ((elfProgH[ i ].p_filesz + elfProgH[ i ].p_offset) > elfsize) {
147 size = elfsize - elfProgH[ i ].p_offset;
148 } else {
149 size = elfProgH[ i ].p_filesz;
150 }
151 _dprintf("loading program at %x, size=%x\n", elfProgH[ i ].p_paddr + elfbase, size);
152 __memcpy((void*)(elfProgH[ i ].p_paddr + elfbase),
153 &elfdata[elfProgH[ i ].p_offset],
154 size);
155 }
156 #ifdef ELF_LOG
157 ELF_LOG("\t*LOADED*");
158 #endif
159 // }
160 break;
161 }
162 #ifdef ELF_LOG
163 ELF_LOG("\n");
164 ELF_LOG("offset: %08x\n",(int)elfProgH[i].p_offset);
165 ELF_LOG("vaddr: %08x\n",(int)elfProgH[i].p_vaddr);
166 ELF_LOG("paddr: %08x\n",elfProgH[i].p_paddr);
167 ELF_LOG("file size: %08x\n",elfProgH[i].p_filesz);
168 ELF_LOG("mem size: %08x\n",elfProgH[i].p_memsz);
169 ELF_LOG("flags: %08x\n",elfProgH[i].p_flags);
170 ELF_LOG("palign: %08x\n",elfProgH[i].p_align);
171 ELF_LOG("\n");
172 #endif
173 }
174
175 return 0;
176 }
177
178 void _relocateElfSection(int i) {
179 ELF_REL *rel;
180 int size = elfSectH[i].sh_size / 4;
181 int r = 0;
182 u32 *ptr, *tmp;
183 ELF_SHR *rsec = &elfSectH[elfSectH[i].sh_info];
184 u8 *mem = (u8*)(elfSectH[i].sh_addr + elfbase);
185 u32 imm;
186 int j;
187
188 ptr = (u32*)(elfdata+elfSectH[i].sh_offset);
189
190 // _dprintf("relocating section %s\n", &sections_names[rsec->sh_name]);
191 // __printf("sh_addr %x\n", elfSectH[i].sh_addr);
192
193 while (size > 0) {
194 rel = (ELF_REL*)&ptr[r];
195 // __printf("rel size=%x: offset=%x, info=%x\n", size, rel->r_offset, rel->r_info);
196
197 tmp = (u32*)&mem[rel->r_offset];
198 switch ((u8)rel->r_info) {
199 case 2: // R_MIPS_32
200 *tmp+= elfbase; break;
201
202 case 4: // R_MIPS_26
203 *tmp = (*tmp & 0xfc000000) |
204 (((*tmp & 0x03ffffff) + (elfbase >> 2)) & 0x03ffffff);
205 break;
206
207 case 5: // R_MIPS_HI16
208 imm = (((*tmp & 0xffff) + (elfbase >> 16)) & 0xffff);
209 for (j=(r+2)/2; j<elfSectH[i].sh_size / 4; j++) {
210 if (j*2 == r) continue;
211 if ((u8)((ELF_REL*)&ptr[j*2])->r_info == 6)
212 break;
213 // if ((rel->r_info >> 8) == (((ELF_REL*)&ptr[j*2])->r_info >> 8))
214 // break;
215 }
216
217 /* if (j != elfSectH[i].sh_size / 4)*/ {
218 u32 *p;
219
220 rel = (ELF_REL*)&ptr[j*2];
221 // __printf("HI16: found match: %x\n", rel->r_offset);
222 p = (u32*)&mem[rel->r_offset];
223 // __printf("%x + %x = %x\n", *p, elfbase, (*p & 0xffff) + (elfbase & 0xffff));
224 if (((*p & 0xffff) + (elfbase & 0xffff)) & 0x8000) {
225 // __printf("found\n");
226 imm++;
227 }
228 }
229 *tmp = (*tmp & 0xffff0000) | imm;
230 break;
231
232 case 6: // R_MIPS_LO16
233 *tmp = (*tmp & 0xffff0000) |
234 (((*tmp & 0xffff) + (elfbase & 0xffff)) & 0xffff);
235 break;
236
237 default:
238 __printf("UNKNOWN R_MIPS REL!!\n");
239 break;
240 }
241
242 size-= 2; r+= 2;
243 }
244 }
245
246 int loadSectionHeaders() {
247 int i;
248 int i_st = -1;
249 int i_dt = -1;
250
251 if (elfHeader->e_shnum == 0) {
252 return -1;
253 }
254
255 elfSectH = (ELF_SHR*)&elfdata[elfHeader->e_shoff];
256
257 if ( elfHeader->e_shstrndx < elfHeader->e_shnum ) {
258 sections_names = (char *)&elfdata[elfSectH[ elfHeader->e_shstrndx ].sh_offset];
259 }
260
261 for ( i = 0 ; i < elfHeader->e_shnum ; i++ )
262 {
263 #ifdef ELF_LOG
264 ELF_LOG( "Elf32 Section Header [%x] %s", i, &sections_names[ elfSectH[ i ].sh_name ] );
265 #endif
266 /* if ( elfSectH[i].sh_flags & 0x2 ) {
267 if (elfSectH[i].sh_offset < elfsize) {
268 int size;
269
270 if ((elfSectH[i].sh_size + elfSectH[i].sh_offset) > elfsize) {
271 size = elfsize - elfSectH[i].sh_offset;
272 } else {
273 size = elfSectH[i].sh_size;
274 }
275 memcpy(&psM[ elfSectH[ i ].sh_addr &0x1ffffff ],
276 &elfdata[elfSectH[i].sh_offset],
277 size);
278 }
279 #ifdef ELF_LOG
280 ELF_LOG( "\t*LOADED*" );
281 #endif
282 }*/
283 #ifdef ELF_LOG
284 ELF_LOG("\n");
285 ELF_LOG("type: ");
286 #endif
287 switch ( elfSectH[ i ].sh_type )
288 {
289 default:
290 #ifdef ELF_LOG
291 ELF_LOG("unknown %08x",elfSectH[i].sh_type);
292 #endif
293 break;
294
295 case 0x0:
296 #ifdef ELF_LOG
297 ELF_LOG("null");
298 #endif
299 break;
300
301 case 0x1:
302 #ifdef ELF_LOG
303 ELF_LOG("progbits");
304 #endif
305 break;
306
307 case 0x2:
308 #ifdef ELF_LOG
309 ELF_LOG("symtab");
310 #endif
311 break;
312
313 case 0x3:
314 #ifdef ELF_LOG
315 ELF_LOG("strtab");
316 #endif
317 break;
318
319 case 0x4:
320 #ifdef ELF_LOG
321 ELF_LOG("rela");
322 #endif
323 break;
324
325 case 0x8:
326 #ifdef ELF_LOG
327 ELF_LOG("no bits");
328 #endif
329 break;
330
331 case 0x9:
332 #ifdef ELF_LOG
333 ELF_LOG("rel");
334 #endif
335 break;
336 }
337 #ifdef ELF_LOG
338 ELF_LOG("\n");
339 ELF_LOG("flags: %08x\n", elfSectH[i].sh_flags);
340 ELF_LOG("addr: %08x\n", elfSectH[i].sh_addr);
341 ELF_LOG("offset: %08x\n", elfSectH[i].sh_offset);
342 ELF_LOG("size: %08x\n", elfSectH[i].sh_size);
343 ELF_LOG("link: %08x\n", elfSectH[i].sh_link);
344 ELF_LOG("info: %08x\n", elfSectH[i].sh_info);
345 ELF_LOG("addralign: %08x\n", elfSectH[i].sh_addralign);
346 ELF_LOG("entsize: %08x\n", elfSectH[i].sh_entsize);
347 #endif
348 // dump symbol table
349
350 if (elfSectH[i].sh_type == 0x02) {
351 i_st = i; i_dt = elfSectH[i].sh_link;
352 }
353 }
354
355
356 // now that we have all the stuff loaded, relocate it
357 for (i = 0 ; i < elfHeader->e_shnum ; i++) {
358 if (elfSectH[i].sh_type == 0x09) { // relocations
359 _relocateElfSection(i);
360 }
361 }
362
363 return 0;
364 }
365
366 void* loadElfFile(ROMFILE_INFO* ri, u32 offset)
367 {
368 imageInfo* ii;
369 ELF_PHR* ph;
370 ELF_IOPMOD* im;
371
372 __printf("loadElfFile: base=%x, size=%x\n", ri->fileData, ri->entry->fileSize);
373 elfdata = (u8*)(ri->fileData);
374 elfsize = ri->entry->fileSize;
375 elfbase = offset+0x30;
376
377 loadHeaders();
378
379 // fill the image info header
380 ph= (ELF_PHR*)((char*)elfHeader +elfHeader->e_phoff);
381 im= (ELF_IOPMOD*)((char*)elfHeader + ph[0].p_offset);
382 ii = (imageInfo*)offset;
383
384 if( *(u16*)(elfHeader->e_ident+4) != 0x101 )
385 return NULL;
386 if (elfHeader->e_machine != EM_MIPS)
387 return NULL;
388 if (elfHeader->e_phentsize != sizeof(ELF_PHR))
389 return NULL;
390 if (elfHeader->e_phnum != 2)
391 return NULL;
392 if (ph[0].p_type != PT_SCE_IOPMOD)
393 return NULL;
394 if (elfHeader->e_type != ET_SCE_IOPRELEXEC){
395 if (elfHeader->e_type != elfHeader->e_phnum )//ET_EXEC)
396 return NULL;
397 //result->type=3;
398 }
399 //else result->type=4;
400
401 ii->next =0;
402 ii->name =NULL;
403 ii->version =0;
404 ii->flags =0;
405 ii->modid =0;
406 if ((int)im->moduleinfo != -1) {
407 moduleInfo* minfo = (moduleInfo*)(im->moduleinfo+ph[1].p_vaddr); // probably wrong
408 ii->name = minfo->name;
409 ii->version = minfo->version;
410 }
411 else {
412 ii->name = NULL;
413 ii->version = 0;
414 }
415 ii->entry = im->entry;
416 ii->gp_value = im->gp_value;
417 ii->p1_vaddr = ph[1].p_vaddr;
418 ii->text_size = im->text_size;
419 ii->data_size = im->data_size;
420 ii->bss_size = im->bss_size;
421
422 loadProgramHeaders();
423 loadSectionHeaders();
424
425 _dprintf("loadElfFile: e_entry=%x, hdr=%x\n", elfHeader->e_entry, elfHeader);
426 return (void*)(elfbase+elfHeader->e_entry);
427 }
428

  ViewVC Help
Powered by ViewVC 1.1.22