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