1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - ELF Loader
3 File: elf_loader.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:: 2010-01-08#$
14 $Rev: 11276 $
15 $Author: shirait $
16 *---------------------------------------------------------------------------*/
17
18 #include <stdlib.h>
19 #include <string.h>
20
21 #include "types.h"
22 #include "elf.h"
23 #include "elf_loader.h"
24 #include "arch.h"
25 #include "loader_subset.h"
26
27 //OSHeapHandle EL_Heap;
28 ELAdrEntry* ELAdrEntStart = NULL;
29 ELUnresolvedEntry* ELUnrEntStart = NULL;
30
31 extern u16 dbg_print_flag;
32 extern u16 unresolved_table_block_flag;
33
34 #define MAKELST_DS_API " (void)EL_Export" //API function name to add to the address table on DS
35
36 extern char c_source_line_str[256];
37 extern FILE* CSourceFilep;
38
39 extern void file_write( char* c_str, FILE* Fp);
40
41
42 /*------------------------------------------------------
43 Local Function Declarations
44 -----------------------------------------------------*/
45 // Relocate ELF object or that archive in a buffer
46 u16 ELi_LoadLibrary( ELHandle* ElfHandle, void* obj_image, u32 obj_len, void* buf);
47 // Core function that relocates ELF object to buffer
48 u16 ELi_LoadObject( ELHandle* ElfHandle, void* obj_offset, void* buf);
49 // Stub functions that read data from the ELF object
50 void ELi_ReadFile( void* buf, void* file_struct, u32 file_base, u32 file_offset, u32 size);
51 void ELi_ReadMem( void* buf, void* file_struct, u32 file_base, u32 file_offset, u32 size);
52
53
54
55
56 /*---------------------------------------------------------
57 Find size of the ELF object
58
59 buf: Address of ELF image
60 --------------------------------------------------------*/
EL_GetElfSize(const void * buf)61 u32 EL_GetElfSize( const void* buf)
62 {
63 Elf32_Ehdr Ehdr;
64 u32 size;
65
66 if( ELF_LoadELFHeader( buf, &Ehdr) == NULL) {
67 return 0;
68 }
69 size = (u32)(Ehdr.e_shoff + (Ehdr.e_shentsize * Ehdr.e_shnum));
70 return size;
71 }
72
73
74 /*------------------------------------------------------
75 Initializes the dynamic link system.
76 -----------------------------------------------------*/
EL_Init(void)77 void EL_Init( void)
78 {
79 // void* heap_start;
80 printf( "\n");
81 /*--- Memory allocation related settings ---*/
82 /* OS_InitArena();
83 heap_start = OS_InitAlloc( OS_ARENA_MAIN, OS_GetMainArenaLo(), OS_GetMainArenaHi(), 1);
84 OS_SetMainArenaLo( heap_start );
85 EL_Heap = OS_CreateHeap( OS_ARENA_MAIN, heap_start, (void*)((u32)(OS_GetMainArenaHi())+1));
86 OS_SetCurrentHeap( OS_ARENA_MAIN, EL_Heap);*/
87 /*--------------------------------------*/
88 }
89
90 /*------------------------------------------------------
91 Initialize the ELHandle structure
92 -----------------------------------------------------*/
EL_InitHandle(ELHandle * ElfHandle)93 BOOL EL_InitHandle( ELHandle* ElfHandle)
94 {
95 if( ElfHandle == NULL) { /*NULL check*/
96 return FALSE;
97 }
98
99 /*Set default values*/
100 ElfHandle->ShdrEx = NULL;
101 ElfHandle->SymEx = NULL;
102
103 ElfHandle->process = EL_INITIALIZED; /*Set the flag*/
104
105 return TRUE;
106 }
107
108 /*------------------------------------------------------
109 Relocate ELF object or that archive in a buffer
110
111 ElfHandle: Header structure
112 ObjFile: Object file or archive file structure
113 buf: Buffer for loading
114 -----------------------------------------------------*/
EL_LoadLibraryfromFile(ELHandle * ElfHandle,FILE * ObjFile,void * buf)115 u16 EL_LoadLibraryfromFile( ELHandle* ElfHandle, FILE* ObjFile, void* buf)
116 {
117 u16 result;
118 u32 len;
119
120 /*Set read function*/
121 ElfHandle->ELi_ReadStub = ELi_ReadFile;
122 ElfHandle->FileStruct = ObjFile;
123
124 fseek( ObjFile, 0, SEEK_END);
125 len = ftell( ObjFile);
126 fseek( ObjFile, 0, SEEK_SET);
127 result = ELi_LoadLibrary( ElfHandle, NULL, len, buf);
128
129 return result;
130 }
131
132 /*------------------------------------------------------
133 Relocate ELF object or that archive in a buffer
134
135 ElfHandle: Header structure
136 obj_image: RAM image address for OBJ file or archive file
137 buf: Buffer for loading
138 -----------------------------------------------------*/
EL_LoadLibraryfromMem(ELHandle * ElfHandle,void * obj_image,u32 obj_len,void * buf)139 u16 EL_LoadLibraryfromMem( ELHandle* ElfHandle, void* obj_image, u32 obj_len, void* buf)
140 {
141 u16 result;
142
143 /*Set read function*/
144 ElfHandle->ELi_ReadStub = ELi_ReadMem;
145 ElfHandle->FileStruct = NULL;
146
147 result = ELi_LoadLibrary( ElfHandle, obj_image, obj_len, buf);
148
149 return result;
150 }
151
152 /*------------------------------------------------------
153 Relocate ELF object or that archive in a buffer
154
155 ElfHandle: Header structure
156 obj_image: RAM image address for OBJ file or archive file
157 buf: Buffer for loading
158 -----------------------------------------------------*/
ELi_LoadLibrary(ELHandle * ElfHandle,void * obj_image,u32 obj_len,void * buf)159 u16 ELi_LoadLibrary( ELHandle* ElfHandle, void* obj_image, u32 obj_len, void* buf)
160 {
161 u16 result, all_result;
162 u32 image_pointer;
163 u32 arch_size;
164 u32 elf_num = 0; /*Number of ELF objects*/
165 u32 obj_size;
166 ArchHdr ArHdr;
167 char OBJMAG[8];
168 char ELFMAG[4] = { ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3};
169
170 all_result = EL_RELOCATED;
171 ElfHandle->ar_head = obj_image;
172 image_pointer = 0;
173
174 ElfHandle->ELi_ReadStub( OBJMAG, ElfHandle->FileStruct, (u32)obj_image, 0, 8); /*Get the OBJ string*/
175 /*--------------- For archive files ---------------*/
176 if( strncmp( OBJMAG, ARMAG, 8) == 0) {
177 arch_size = sizeof( ArchHdr);
178 image_pointer += 8; /*To first entry*/
179
180 ElfHandle->buf_current = buf;
181 while( image_pointer < obj_len) {
182 ElfHandle->ELi_ReadStub( OBJMAG, ElfHandle->FileStruct, (u32)(obj_image), (image_pointer+arch_size), 4); /*Get the OBJ string*/
183 if( strncmp( OBJMAG, ELFMAG, 4) == 0) {
184 elf_num++;
185 result = ELi_LoadObject( ElfHandle, (void*)(image_pointer+arch_size), ElfHandle->buf_current);
186 if( result < all_result) { /*Apply to all_result only when there are bad results*/
187 all_result = result;
188 }
189 /*Set default values*/
190 ElfHandle->ShdrEx = NULL;
191 ElfHandle->SymEx = NULL;
192 ElfHandle->process = EL_INITIALIZED; /*Set the flag*/
193 }else{
194 }
195 /*To next entry*/
196 ElfHandle->ELi_ReadStub( &ArHdr, ElfHandle->FileStruct, (u32)(obj_image), image_pointer, arch_size);
197 obj_size = AR_GetEntrySize( &ArHdr);
198 if( obj_size % 2) //Padded by '\n' when the object size is an odd number.
199 {
200 obj_size++;
201 }
202 image_pointer += arch_size + obj_size;
203 }
204 }else{/*--------------- For ELF files ---------------*/
205 if( strncmp( OBJMAG, ELFMAG, 4) == 0) {
206 elf_num++;
207 all_result = ELi_LoadObject( ElfHandle, 0, buf);
208 }
209 }
210 /*-------------------------------------------------------*/
211
212 if( elf_num) {
213 return all_result;
214 }else{
215 return EL_FAILED;
216 }
217 }
218
219 /*------------------------------------------------------
220 Relocate ELF object to buffer
221
222 ElfHandle: Header structure
223 obj_offset: Offset from RAM image address of object file
224 buf: Buffer for loading
225 -----------------------------------------------------*/
ELi_LoadObject(ELHandle * ElfHandle,void * obj_offset,void * buf)226 u16 ELi_LoadObject( ELHandle* ElfHandle, void* obj_offset, void* buf)
227 {
228 u16 i, j;
229 u32 num_of_entry;
230 ELShdrEx* FwdShdrEx;
231 ELShdrEx* CurrentShdrEx;
232 ELShdrEx DmyShdrEx;
233 char sym_str[128]; //For debug print
234 u32 offset; //For debug print
235
236 /* Check initialization of ELHandle */
237 if( ElfHandle->process != EL_INITIALIZED) {
238 return EL_FAILED;
239 }
240 /* Buffer NULL check */
241 if( buf == NULL) {
242 return EL_FAILED;
243 }
244 /* Get ELF header */
245 ElfHandle->ELi_ReadStub( &(ElfHandle->CurrentEhdr), ElfHandle->FileStruct,
246 (u32)(ElfHandle->ar_head), (u32)(obj_offset), sizeof( Elf32_Ehdr));
247
248 /* Section handle build */
249 ElfHandle->elf_offset = obj_offset;
250 ElfHandle->buf_current = buf;
251 ElfHandle->shentsize = ElfHandle->CurrentEhdr.e_shentsize;
252
253 /*---------- Create ELShdrEx List ----------*/
254 CurrentShdrEx = &DmyShdrEx;
255 for( i=0; i<(ElfHandle->CurrentEhdr.e_shnum); i++) {
256 CurrentShdrEx->next = (void*)(malloc( sizeof(ELShdrEx)));
257 CurrentShdrEx = (ELShdrEx*)(CurrentShdrEx->next);
258 memset( CurrentShdrEx, 0, sizeof(ELShdrEx)); //Clear zero
259
260 /*Set flag to distinguish whether this is debugging information*/
261 if( ELi_ShdrIsDebug( ElfHandle, i) == TRUE) { /*When it is debugging information*/
262 CurrentShdrEx->debug_flag = 1;
263 }else{ /*When not debugging information*/
264 /*Copy section header*/
265 ELi_GetShdr( ElfHandle, i, &(CurrentShdrEx->Shdr));
266 CurrentShdrEx->debug_flag = 0;
267 }
268 }
269 CurrentShdrEx->next = NULL;
270 ElfHandle->ShdrEx = DmyShdrEx.next;
271 /*--------------------------------------------*/
272
273 /*---------- Check and copy all sections ----------*/
274 /* printf( "\nLoad to RAM:\n");
275 for( i=0; i<(ElfHandle->CurrentEhdr.e_shnum); i++) {
276 //
277 CurrentShdrEx = ELi_GetShdrExfromList( ElfHandle->ShdrEx, i);
278
279 if( CurrentShdrEx->debug_flag == 1) { //When it is debugging information
280 printf( "skip debug-section %02x\n", i);
281 }else{ //When not debugging information
282 // .text section
283 if( (CurrentShdrEx->Shdr.sh_flags == (SHF_ALLOC | SHF_EXECINSTR))&&
284 (CurrentShdrEx->Shdr.sh_type == SHT_PROGBITS)) {
285 //Copy to memory
286 CurrentShdrEx->loaded_adr = (u32)
287 ELi_CopySectionToBuffer( ElfHandle, &(CurrentShdrEx->Shdr));
288 }
289 // .data, .data1 section (Initialized data)
290 else if( (CurrentShdrEx->Shdr.sh_flags == (SHF_ALLOC | SHF_WRITE))&&
291 (CurrentShdrEx->Shdr.sh_type == SHT_PROGBITS)) {
292 //Copy to memory
293 CurrentShdrEx->loaded_adr = (u32)
294 ELi_CopySectionToBuffer( ElfHandle, &(CurrentShdrEx->Shdr));
295 }
296 // .bss section
297 else if( (CurrentShdrEx->Shdr.sh_flags == (SHF_ALLOC | SHF_WRITE))&&
298 (CurrentShdrEx->Shdr.sh_type == SHT_NOBITS)) {
299 //Do not copy
300 CurrentShdrEx->loaded_adr = (u32)
301 ELi_AllocSectionToBuffer( ElfHandle, &(CurrentShdrEx->Shdr));
302 }
303 // .rodata, .rodata1 section
304 else if( (CurrentShdrEx->Shdr.sh_flags == SHF_ALLOC)&&
305 (CurrentShdrEx->Shdr.sh_type == SHT_PROGBITS)) {
306 //Copy to memory
307 CurrentShdrEx->loaded_adr = (u32)
308 ELi_CopySectionToBuffer( ElfHandle, &(CurrentShdrEx->Shdr));
309 }
310
311 printf( "section %02x relocated at %08x\n",
312 i, CurrentShdrEx->loaded_adr);
313 }
314 }
315 // After copy ends
316 ElfHandle->process = EL_COPIED;*/
317 /*----------------------------------------------------*/
318
319 /*---------- Relocate ----------*/
320 if( unresolved_table_block_flag == 0) {
321 if( dbg_print_flag == 1) {
322 printf( "\nRelocate Symbols:\n");
323 }
324 for( i=0; i<(ElfHandle->CurrentEhdr.e_shnum); i++) {
325 /**/
326 CurrentShdrEx = ELi_GetShdrExfromList( ElfHandle->ShdrEx, i);
327
328 if( CurrentShdrEx->debug_flag == 1) { /*When it is debugging information*/
329 }else{ /*When not debugging information*/
330
331 if( CurrentShdrEx->Shdr.sh_type == SHT_REL) {
332 num_of_entry = (CurrentShdrEx->Shdr.sh_size) /
333 (CurrentShdrEx->Shdr.sh_entsize);
334 if( dbg_print_flag == 1) {
335 printf( "num of REL = %x\n", (int)(num_of_entry));
336 printf( "Section Header Info.\n");
337 printf( "link : %x\n", (int)(CurrentShdrEx->Shdr.sh_link));
338 printf( "info : %x\n", (int)(CurrentShdrEx->Shdr.sh_info));
339 printf( " Offset Info Type Sym.Value Sym.Name\n");
340 }
341 offset = 0;
342 for( j=0; j<num_of_entry; j++) {
343 ELi_GetSent( ElfHandle, i, &(ElfHandle->Rel), offset, sizeof(Elf32_Rel));
344 ELi_GetShdr( ElfHandle, CurrentShdrEx->Shdr.sh_link, &(ElfHandle->SymShdr));
345 ELi_GetSent( ElfHandle, CurrentShdrEx->Shdr.sh_link, &(ElfHandle->Sym),
346 (u32)(ElfHandle->SymShdr.sh_entsize * ELF32_R_SYM( ElfHandle->Rel.r_info)), sizeof(Elf32_Sym));
347 ELi_GetStrAdr( ElfHandle, ElfHandle->SymShdr.sh_link, ElfHandle->Sym.st_name, sym_str, 128);
348
349 if( dbg_print_flag == 1) {
350 printf( "%08x ", (int)(ElfHandle->Rel.r_offset));
351 printf( "%08x ", (int)(ElfHandle->Rel.r_info));
352 printf( " ");
353 printf( "%08x ", (int)(ElfHandle->Sym.st_value));
354 printf( sym_str);
355 printf( "\n");
356 }
357 /*To next entry*/
358 offset += (u32)(CurrentShdrEx->Shdr.sh_entsize);
359 }
360 if( dbg_print_flag == 1) {
361 printf( "\n");
362 }
363 /*Relocate*/
364 ELi_RelocateSym( ElfHandle, i);
365 if( dbg_print_flag == 1) {
366 printf( "\n");
367 }
368 }
369 else if( CurrentShdrEx->Shdr.sh_type == SHT_RELA) {
370
371 num_of_entry = (CurrentShdrEx->Shdr.sh_size) /
372 (CurrentShdrEx->Shdr.sh_entsize);
373 if( dbg_print_flag == 1) {
374 printf( "num of RELA = %x\n", (int)(num_of_entry));
375 printf( "Section Header Info.\n");
376 printf( "link : %x\n", (int)(CurrentShdrEx->Shdr.sh_link));
377 printf( "info : %x\n", (int)(CurrentShdrEx->Shdr.sh_info));
378 printf( " Offset Info Type Sym.Value Sym.Name\n");
379 }
380 offset = 0;
381 for( j=0; j<num_of_entry; j++) {
382 ELi_GetSent( ElfHandle, i, &(ElfHandle->Rela), offset, sizeof(Elf32_Rel));
383 ELi_GetShdr( ElfHandle, CurrentShdrEx->Shdr.sh_link, &(ElfHandle->SymShdr));
384 ELi_GetSent( ElfHandle, CurrentShdrEx->Shdr.sh_link, &(ElfHandle->Sym),
385 (u32)(ElfHandle->SymShdr.sh_entsize * ELF32_R_SYM( ElfHandle->Rela.r_info)), sizeof(Elf32_Sym));
386 ELi_GetStrAdr( ElfHandle, ElfHandle->SymShdr.sh_link, ElfHandle->Sym.st_name, sym_str, 128);
387
388 if( dbg_print_flag == 1) {
389 printf( "%08x ", (int)(ElfHandle->Rela.r_offset));
390 printf( "%08x ", (int)(ElfHandle->Rela.r_info));
391 printf( " ");
392 printf( "%08x ", (int)(ElfHandle->Sym.st_value));
393 printf( sym_str);
394 printf( "\n");
395 }
396 /*To next entry*/
397 offset += (u32)(CurrentShdrEx->Shdr.sh_entsize);
398 }
399 if( dbg_print_flag == 1) {
400 printf( "\n");
401 }
402 /*Relocate*/
403 ELi_RelocateSym( ElfHandle, i);
404 if( dbg_print_flag == 1) {
405 printf( "\n");
406 }
407 }
408 }
409 }
410 }else{ /*When not a DLL but a static module*/
411 for( i=0; i<(ElfHandle->CurrentEhdr.e_shnum); i++) {
412 CurrentShdrEx = ELi_GetShdrExfromList( ElfHandle->ShdrEx, i);
413 if( CurrentShdrEx->debug_flag == 1) { /*When it is debugging information*/
414 }else{
415 if( CurrentShdrEx->Shdr.sh_type == SHT_SYMTAB) {
416 ELi_DiscriminateGlobalSym( ElfHandle, i);
417 }
418 }
419 }
420 }
421
422 /*---------- Deallocate the ELShdrEx List ----------*/
423 CurrentShdrEx = ElfHandle->ShdrEx;
424 if( CurrentShdrEx) {
425 while( CurrentShdrEx->next != NULL) {
426 FwdShdrEx = CurrentShdrEx;
427 CurrentShdrEx = CurrentShdrEx->next;
428 free( FwdShdrEx);
429 }
430 ElfHandle->ShdrEx = NULL;
431 }
432 /*-----------------------------------------*/
433
434 /*Flush cache before the DLL in RAM is called*/
435 // DC_FlushAll();
436 // DC_WaitWriteBufferEmpty();
437
438 return (ElfHandle->process);
439 }
440
441 /*------------------------------------------------------
442 Resolve unresolved symbols using the address table
443 -----------------------------------------------------*/
EL_ResolveAllLibrary(void)444 u16 EL_ResolveAllLibrary( void)
445 {
446 ELAdrEntry* AdrEnt;
447 ELUnresolvedEntry* RemoveUnrEnt;
448 ELUnresolvedEntry* UnrEnt;
449 // ELUnresolvedEntry* CurrentUnrEnt;
450 // ELUnresolvedEntry* FwdUnrEnt;
451 // u32 relocation_val;
452 // ELAdrEntry AddAdrEnt;
453 char sym_str[128];
454
455 UnrEnt = ELUnrEntStart;
456 if( dbg_print_flag == 1) {
457 printf( "\nResolve all symbols:\n");
458 }
459 while( UnrEnt != NULL) {
460 if( UnrEnt->remove_flag == 0) {
461 AdrEnt = EL_GetAdrEntry( UnrEnt->sym_str); /*Search from address table*/
462 if( AdrEnt) { /*When found in address table*/
463 UnrEnt->S_ = (u32)(AdrEnt->adr);
464 UnrEnt->T_ = (u32)(AdrEnt->thumb_flag);
465 if( unresolved_table_block_flag == 0) {
466 if( dbg_print_flag == 1) {
467 printf( "\n symbol found %s : %8x\n", UnrEnt->sym_str, (int)(UnrEnt->S_));
468 }
469 UnrEnt->remove_flag = 1;
470 // ELi_RemoveUnresolvedEntry( UnrEnt); //Delete from unresolved list because this was resolved
471 }else{
472 if( dbg_print_flag == 1) {
473 printf( "\n static symbol found %s : %8x\n", UnrEnt->sym_str, (int)(UnrEnt->S_));
474 }
475 UnrEnt->AdrEnt = AdrEnt; //Set the found address entry
476 UnrEnt->remove_flag = 2; //Marking (special value used only with makelst)
477 strcpy( sym_str, UnrEnt->sym_str);
478 while( 1) {
479 RemoveUnrEnt = ELi_GetUnresolvedEntry( sym_str);
480 if( RemoveUnrEnt == NULL) {
481 break;
482 }else{
483 RemoveUnrEnt->remove_flag = 1;
484 }
485 }
486 }
487 /* relocation_val = ELi_DoRelocate( UnrEnt); //Resolve symbol
488 if( !relocation_val) {
489 return EL_FAILED;
490 }*/
491
492 }else{ /*When not found in address table*/
493 if( unresolved_table_block_flag == 0) {
494 if( dbg_print_flag == 1) {
495 printf( "ERROR! cannot find symbol : %s\n", UnrEnt->sym_str);
496 }
497 }else{
498 if( dbg_print_flag == 1) {
499 printf( "ERROR! cannot find static symbol : %s\n", UnrEnt->sym_str);
500 }
501 }
502 /* AddAdrEnt.next = NULL;
503 AddAdrEnt.name = UnrEnt->sym_str;
504 AddAdrEnt.
505 EL_AddAdrEntry( */
506 // return EL_FAILED;
507 }
508 }
509 UnrEnt = (ELUnresolvedEntry*)(UnrEnt->next); /*To next unresolved entry*/
510 }
511
512 /*---------- Deallocate the ELUnresolvedEntry List ----------*/
513 /* CurrentUnrEnt = ELUnrEntStart;
514 if( CurrentUnrEnt) {
515 while( CurrentUnrEnt->next != NULL) {
516 FwdUnrEnt = CurrentUnrEnt;
517 CurrentUnrEnt = CurrentUnrEnt->next;
518 free( FwdUnrEnt->sym_str); // symbol name string
519 free( FwdUnrEnt); //Structure itself
520 }
521 ELUnrEntStart = NULL;
522 }*/
523 /*-------------------------------------------*/
524
525 /*Flush cache before the DLL in RAM is called*/
526 // DC_FlushAll();
527 // DC_WaitWriteBufferEmpty();
528
529 return EL_RELOCATED;
530 }
531
532
533
534 /*------------------------------------------------------
535 Write marked symbol to a public file as a structure
536 -----------------------------------------------------*/
EL_ExtractStaticSym1(void)537 void EL_ExtractStaticSym1( void)
538 {
539 // ELAdrEntry* AdrEnt;
540 // ELUnresolvedEntry* RemoveUnrEnt;
541 ELUnresolvedEntry* UnrEnt;
542 // ELUnresolvedEntry* CurrentUnrEnt;
543 // ELUnresolvedEntry* FwdUnrEnt;
544 // u32 relocation_val;
545 // ELAdrEntry AddAdrEnt;
546 char sym_str[256];
547
548
549 UnrEnt = ELUnrEntStart;
550
551
552 file_write( "/*--------------------------------\n", CSourceFilep);
553 file_write( " extern symbol\n", CSourceFilep);
554 file_write( " --------------------------------*/
555 \n", CSourceFilep);
556
557 while( UnrEnt != NULL) {
558 if( UnrEnt->remove_flag == 2) {//Marking (special value used only with makelst)
559 if( (UnrEnt->AdrEnt->func_flag) != STT_FUNC
560 && (UnrEnt->AdrEnt->name[0] == '_' && UnrEnt->AdrEnt->name[1] != '_')) {
561 memset( sym_str, 0, 128);
562 strcpy( sym_str, "extern u8 ");
563 strcat( sym_str, UnrEnt->sym_str);
564 strcat( sym_str, ";\n");
565 file_write( sym_str, CSourceFilep);
566 }
567 }
568 UnrEnt = (ELUnresolvedEntry*)(UnrEnt->next); /*To next unresolved entry*/
569 }
570
571 file_write( "\n\n", CSourceFilep);
572
573
574 file_write( "/*--------------------------------\n", CSourceFilep);
575 file_write( " symbol structure\n", CSourceFilep);
576 file_write( " --------------------------------*/
577 \n", CSourceFilep);
578
579 UnrEnt = ELUnrEntStart;
580
581 while( UnrEnt != NULL) {
582 if( UnrEnt->remove_flag == 2) {//Marking (special value used only with makelst)
583 memset( sym_str, 0, 128);
584 strcpy( sym_str, "ELAdrEntry AdrEnt_");
585 strcat( sym_str, UnrEnt->sym_str);
586 strcat( sym_str, " = {\n");
587 file_write( sym_str, CSourceFilep);
588
589 file_write( " (void*)NULL,\n", CSourceFilep);
590
591 strcpy( sym_str, " (char*)\"");
592 strcat( sym_str, UnrEnt->sym_str);
593 strcat( sym_str, "\\0\", \n");
594 file_write( sym_str, CSourceFilep);
595
596 if( (UnrEnt->AdrEnt->func_flag) == STT_FUNC) {
597 strcpy( sym_str, " (void*)");
598 }else{
599 strcpy( sym_str, " (void*)&");
600 }
601 strcat( sym_str, UnrEnt->sym_str);
602 strcat( sym_str, ",\n");
603 file_write( sym_str, CSourceFilep);
604
605 if( (UnrEnt->AdrEnt->func_flag) == 1) {
606 file_write( " 0,\n", CSourceFilep);
607 }else{
608 file_write( " 1,\n", CSourceFilep);
609 }
610 if( (UnrEnt->AdrEnt->thumb_flag) == 0) {
611 file_write( " 0,\n", CSourceFilep);
612 }else{
613 file_write( " 1,\n", CSourceFilep);
614 }
615 file_write( "};\n", CSourceFilep);
616
617 // printf( "\n static symbol found %s : %8x\n", UnrEnt->sym_str, UnrEnt->S_);
618 }
619 UnrEnt = (ELUnresolvedEntry*)(UnrEnt->next); /*To next unresolved entry*/
620 }
621 }
622
623 /*------------------------------------------------------
624 Write marked symbol to a public file as an API
625 -----------------------------------------------------*/
EL_ExtractStaticSym2(void)626 void EL_ExtractStaticSym2( void)
627 {
628 // ELAdrEntry* AdrEnt;
629 // ELUnresolvedEntry* RemoveUnrEnt;
630 ELUnresolvedEntry* UnrEnt;
631 // ELUnresolvedEntry* CurrentUnrEnt;
632 // ELUnresolvedEntry* FwdUnrEnt;
633 // u32 relocation_val;
634 // ELAdrEntry AddAdrEnt;
635 char sym_str[256];
636
637 UnrEnt = ELUnrEntStart;
638
639 while( UnrEnt != NULL) {
640 if( UnrEnt->remove_flag == 2) {//Marking (special value used only with makelst)
641 memset( sym_str, 0, 128);
642 strcpy( sym_str, MAKELST_DS_API);
643 strcat( sym_str, "( &AdrEnt_");
644 strcat( sym_str, UnrEnt->sym_str);
645 strcat( sym_str, ");\n");
646 file_write( sym_str, CSourceFilep);
647
648 // printf( "\n static symbol found %s : %8x\n", UnrEnt->sym_str, UnrEnt->S_);
649 }
650 UnrEnt = (ELUnresolvedEntry*)(UnrEnt->next); /*To next unresolved entry*/
651 }
652 }
653
654
655 /*------------------------------------------------------
656 Delete entry from address table
657 -----------------------------------------------------*/
EL_RemoveAdrEntry(ELAdrEntry * AdrEnt)658 BOOL EL_RemoveAdrEntry( ELAdrEntry* AdrEnt)
659 {
660 ELAdrEntry DmyAdrEnt;
661 ELAdrEntry* CurrentAdrEnt;
662
663 DmyAdrEnt.next = ELAdrEntStart;
664 CurrentAdrEnt = &DmyAdrEnt;
665
666 while( CurrentAdrEnt->next != AdrEnt) {
667 if( CurrentAdrEnt->next == NULL) {
668 return FALSE;
669 }else{
670 CurrentAdrEnt = (ELAdrEntry*)CurrentAdrEnt->next;
671 }
672 }
673
674 CurrentAdrEnt->next = AdrEnt->next;
675 ELAdrEntStart = DmyAdrEnt.next;
676
677 return TRUE;
678 }
679
680 /*------------------------------------------------------
681 Add entry to address table
682 -----------------------------------------------------*/
EL_AddAdrEntry(ELAdrEntry * AdrEnt)683 void EL_AddAdrEntry( ELAdrEntry* AdrEnt)
684 {
685 ELAdrEntry DmyAdrEnt;
686 ELAdrEntry* CurrentAdrEnt;
687
688 if( !ELAdrEntStart) {
689 ELAdrEntStart = AdrEnt;
690 }else{
691 DmyAdrEnt.next = ELAdrEntStart;
692 CurrentAdrEnt = &DmyAdrEnt;
693
694 while( CurrentAdrEnt->next != NULL) {
695 CurrentAdrEnt = (ELAdrEntry*)CurrentAdrEnt->next;
696 }
697 CurrentAdrEnt->next = (void*)AdrEnt;
698 }
699 AdrEnt->next = NULL;
700 }
701
702 /*------------------------------------------------------
703 Search for entry corresponding to specified string in address table
704 -----------------------------------------------------*/
EL_GetAdrEntry(char * ent_name)705 ELAdrEntry* EL_GetAdrEntry( char* ent_name)
706 {
707 ELAdrEntry* CurrentAdrEnt;
708
709 CurrentAdrEnt = ELAdrEntStart;
710 if( CurrentAdrEnt == NULL) {
711 return NULL;
712 }
713 while( strcmp( CurrentAdrEnt->name, ent_name) != 0) {
714 CurrentAdrEnt = (ELAdrEntry*)CurrentAdrEnt->next;
715 if( CurrentAdrEnt == NULL) {
716 break;
717 }
718 }
719 return CurrentAdrEnt;
720 }
721
722 /*------------------------------------------------------
723 Return address corresponding to specified string in address table
724 -----------------------------------------------------*/
EL_GetGlobalAdr(char * ent_name)725 void* EL_GetGlobalAdr( char* ent_name)
726 {
727 u32 adr;
728 ELAdrEntry* CurrentAdrEnt;
729
730 CurrentAdrEnt = EL_GetAdrEntry( ent_name);
731
732 if( CurrentAdrEnt) {
733 if( CurrentAdrEnt->thumb_flag) {
734 adr = (u32)(CurrentAdrEnt->adr) + 1;
735 }else{
736 adr = (u32)(CurrentAdrEnt->adr);
737 }
738 }else{
739 adr = 0;
740 }
741
742 return (void*)(adr);
743 }
744
745
746 /*------------------------------------------------------
747 Deallocate the address table (failed because it tried to delete up to the entry registered by the application)
748 -----------------------------------------------------*/
749 #if 0
750 void* EL_FreeAdrTbl( void)
751 {
752 ELAdrEntry* FwdAdrEnt;
753 ELAdrEntry* CurrentAdrEnt;
754
755 /*---------- Deallocate the ELAdrEntry List ----------*/
756 CurrentAdrEnt = ELAdrEntStart;
757 if( CurrentAdrEnt) {
758 while( CurrentAdrEnt->next != NULL) {
759 FwdAdrEnt = CurrentAdrEnt;
760 CurrentAdrEnt = CurrentAdrEnt->next;
761 free( FwdAdrEnt->name); //Symbol name string
762 free( FwdAdrEnt); //Structure itself
763 }
764 ELAdrEntStart = NULL;
765 }
766 /*------------------------------------*/
767 }
768 #endif
769
770 /*------------------------------------------------------
771 Stub that reads data from the ELF object
772 -----------------------------------------------------*/
ELi_ReadFile(void * buf,void * file_struct,u32 file_base,u32 file_offset,u32 size)773 void ELi_ReadFile( void* buf, void* file_struct, u32 file_base, u32 file_offset, u32 size)
774 {
775 fseek( file_struct, file_offset, SEEK_SET);
776 fread( buf, 1, size, file_struct);
777
778 /* FS_SeekFile( file_struct, (s32)(file_offset), FS_SEEK_SET);
779 FS_ReadFile( file_struct, buf, (s32)(size));*/
780 }
781
ELi_ReadMem(void * buf,void * file_struct,u32 file_base,u32 file_offset,u32 size)782 void ELi_ReadMem( void* buf, void* file_struct, u32 file_base, u32 file_offset, u32 size)
783 {
784 /* MI_CpuCopy8( (void*)(file_base + file_offset),
785 buf,
786 size);*/
787 memcpy( buf,
788 (void*)(file_base + file_offset),
789 size);
790 }
791