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