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 "types.h"
19 #include "elf.h"
20 #include "elf_loader.h"
21 #include "arch.h"
22 #include "loader_subset.h"
23 #include <string.h>
24 #include <stdlib.h>
25 
26 
27 //OSHeapHandle        EL_Heap;
28 ELAdrEntry*           ELAdrEntStart = NULL;
29 ELUnresolvedEntry*    ELUnrEntStart = NULL;
30 
31 extern u16 dbg_print_flag;
32 extern u32 unresolved_table_block_flag;
33 extern u32 ELi_ALIGN( u32 addr, u32 align_size);
34 
35 extern u16 ELi_LoadObject2( ELHandle* ElfHandle, void* obj_offset, void* buf);
36 
37 
38 #define MAKELST_DS_API        "    elAddAdrEntry"    //API function name to add to the address table on DS
39 
40 extern char    c_source_line_str[256];
41 extern FILE*   NewElfFilep;
42 
43 
44 /*------------------------------------------------------
45   Local Function Declarations
46  -----------------------------------------------------*/
47 // Relocate ELF object or that archive in a buffer
48 u16 ELi_LoadLibrary( ELHandle* ElfHandle, void* obj_image, u32 obj_len, void* buf, u16 type);
49 // Core function that relocates ELF object to buffer
50 u16 ELi_LoadObject( ELHandle* ElfHandle, void* obj_offset, void* buf);
51 // Stub functions that read data from the ELF object
52 void ELi_ReadFile( void* buf, void* file_struct, u32 file_base, u32 file_offset, u32 size);
53 void ELi_ReadMem( void* buf, void* file_struct, u32 file_base, u32 file_offset, u32 size);
54 
55 
56 
57 /*Express hex value with decimal string*/
ELi_SetDecSize(char * dec,u32 hex)58 void ELi_SetDecSize( char* dec, u32 hex)
59 {
60     u16 i;
61     u32 tmp = 1000000000;
62     u16 ptr = 0;
63 
64     memset( dec, 0x20, 10);
65     for( i=0; i<10; i++) {
66         if( ((hex / tmp) != 0) || (ptr != 0)) {
67             dec[ptr++] = 0x30 + (hex/tmp);
68             hex -= (hex/tmp) * tmp;
69         }
70         tmp /= 10;
71     }
72 }
73 
74 
75 
76 /*---------------------------------------------------------
77  Find size of the ELF object
78 
79     buf: Address of ELF image
80  --------------------------------------------------------*/
EL_GetElfSize(const void * buf)81 u32 EL_GetElfSize( const void* buf)
82 {
83     Elf32_Ehdr    Ehdr;
84     u32           size;
85 
86     if( ELF_LoadELFHeader( buf, &Ehdr) == NULL) {
87         return 0;
88     }
89     size = (u32)(Ehdr.e_shoff + (Ehdr.e_shentsize * Ehdr.e_shnum));
90     return size;
91 }
92 
93 
94 /*------------------------------------------------------
95   Initializes the dynamic link system.
96  -----------------------------------------------------*/
EL_Init(void)97 void EL_Init( void)
98 {
99 //    void* heap_start;
100     printf( "\n");
101     /*--- Memory allocation related settings ---*/
102 /*    OS_InitArena();
103     heap_start = OS_InitAlloc( OS_ARENA_MAIN, OS_GetMainArenaLo(), OS_GetMainArenaHi(), 1);
104     OS_SetMainArenaLo( heap_start );
105     EL_Heap = OS_CreateHeap( OS_ARENA_MAIN, heap_start, (void*)((u32)(OS_GetMainArenaHi())+1));
106     OS_SetCurrentHeap( OS_ARENA_MAIN, EL_Heap);*/
107     /*--------------------------------------*/
108 }
109 
110 /*------------------------------------------------------
111   Initialize the ELHandle structure
112  -----------------------------------------------------*/
EL_InitHandle(ELHandle * ElfHandle)113 BOOL EL_InitHandle( ELHandle* ElfHandle)
114 {
115     if( ElfHandle == NULL) {    /*NULL check*/
116         return FALSE;
117     }
118 
119     /*Set default values*/
120     ElfHandle->ShdrEx   = NULL;
121     ElfHandle->SymEx    = NULL;
122     ElfHandle->SymExTbl = NULL;
123     ElfHandle->SymExTarget = 0xFFFFFFFF;
124 
125     ElfHandle->process = EL_INITIALIZED;    /*Set the flag*/
126 
127     return TRUE;
128 }
129 
130 /*------------------------------------------------------
131   Relocate ELF object or that archive in a buffer
132 
133     ElfHandle: Header structure
134     ObjFile: Object file or archive file structure
135     buf: Buffer for loading
136     type: 0: Create elf with debug information removed, 1: Create elf for debugging
137  -----------------------------------------------------*/
EL_LoadLibraryfromFile(ELHandle * ElfHandle,FILE * ObjFile,void * buf,u16 type)138 u16 EL_LoadLibraryfromFile( ELHandle* ElfHandle, FILE* ObjFile, void* buf, u16 type)
139 {
140     u16 result;
141     u32 len;
142 
143     /*Set read function*/
144     ElfHandle->ELi_ReadStub = ELi_ReadFile;
145     ElfHandle->FileStruct = ObjFile;
146 
147     fseek( ObjFile, 0, SEEK_END);
148     len = ftell( ObjFile);
149     fseek( ObjFile, 0, SEEK_SET);
150     result = ELi_LoadLibrary( ElfHandle, NULL, len, buf, type);
151 
152     return result;
153 }
154 
155 /*------------------------------------------------------
156   Relocate ELF object or the archive in a buffer
157 
158     ElfHandle: Header structure
159     obj_image: RAM image address for OBJ file or archive file
160     buf: Buffer for loading
161  -----------------------------------------------------*/
EL_LoadLibraryfromMem(ELHandle * ElfHandle,void * obj_image,u32 obj_len,void * buf)162 u16 EL_LoadLibraryfromMem( ELHandle* ElfHandle, void* obj_image, u32 obj_len, void* buf)
163 {
164     u16 result;
165 
166     /*Set read function*/
167     ElfHandle->ELi_ReadStub = ELi_ReadMem;
168     ElfHandle->FileStruct = NULL;
169 
170     result = ELi_LoadLibrary( ElfHandle, obj_image, obj_len, buf, 0);
171 
172     return result;
173 }
174 
175 /*------------------------------------------------------
176   Relocate ELF object or the archive in a buffer
177 
178     ElfHandle: Header structure
179     obj_image: RAM image address for OBJ file or archive file
180     buf: Buffer for loading
181  -----------------------------------------------------*/
ELi_LoadLibrary(ELHandle * ElfHandle,void * obj_image,u32 obj_len,void * buf,u16 type)182 u16 ELi_LoadLibrary( ELHandle* ElfHandle, void* obj_image, u32 obj_len, void* buf, u16 type)
183 {
184     u16     result, all_result;
185     u32     image_pointer;
186     u32     new_image_pointer;
187     u32     arch_size;
188     u32     elf_num = 0;                /*Number of ELF objects*/
189     u32     obj_size;
190     u32     newarch_size = 0;
191     ArchHdr ArHdr;
192     char    OBJMAG[8];
193     char    ELFMAG[4] = { ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3};
194 
195 
196     all_result = EL_RELOCATED;
197     ElfHandle->ar_head = obj_image;
198     image_pointer = 0;
199 
200 
201     ElfHandle->ELi_ReadStub( OBJMAG, ElfHandle->FileStruct, (u32)obj_image, 0, 8);    /*Get the OBJ string*/
202     /*--------------- For archive files  ---------------*/
203     if( strncmp( OBJMAG, ARMAG, 8) == 0) {
204         arch_size = sizeof( ArchHdr);
205         image_pointer += 8;                /*To first entry*/
206 
207 
208         new_image_pointer = (u32)buf;
209         memcpy( buf, OBJMAG, 8); //Copy to stripped ELF
210         new_image_pointer += 8;
211         newarch_size += 8;
212 
213 
214         ElfHandle->buf_current = (void*)new_image_pointer;
215         while( image_pointer < obj_len) {
216             ElfHandle->ELi_ReadStub( &ArHdr, ElfHandle->FileStruct, (u32)(obj_image), image_pointer, arch_size);
217             ElfHandle->ELi_ReadStub( OBJMAG, ElfHandle->FileStruct, (u32)(obj_image), (image_pointer+arch_size), 4);    /*Get the OBJ string*/
218             if( strncmp( OBJMAG, ELFMAG, 4) == 0) {
219                 elf_num++;
220 
221                 memcpy( (void*)new_image_pointer, (const void*)&ArHdr, arch_size); //Copy ar header to stripped ELF
222 
223                 if( type == 0) {
224                 result = ELi_LoadObject( ElfHandle, (void*)(image_pointer+arch_size),
225                                          (void*)(new_image_pointer + arch_size));
226 //                                         (ElfHandle->buf_current + arch_size));
227                 }else{
228                 result = ELi_LoadObject2( ElfHandle, (void*)(image_pointer+arch_size),
229                                           (void*)(new_image_pointer + arch_size));
230                 }
231 
232                 ELi_SetDecSize( (char*)(((ArchHdr*)new_image_pointer)->ar_size), ElfHandle->newelf_size); //Update arch header size
233                 new_image_pointer += (ElfHandle->newelf_size + arch_size);
234                 newarch_size += (ElfHandle->newelf_size + arch_size);
235 
236                 if( result < all_result) {        /*Apply to all_result only when there are bad results*/
237                     all_result = result;
238                 }
239                 /*Set default values*/
240                 ElfHandle->ShdrEx = NULL;
241                 ElfHandle->SymEx = NULL;
242                 ElfHandle->process = EL_INITIALIZED;    /*Set the flag*/
243             }else{
244                 memcpy( (void*)new_image_pointer, (const void*)&ArHdr, arch_size); //Copy ar header to stripped ELF
245 
246                 /*Copy next (entry) of ar header to stripped ELF*/
247                 ElfHandle->ELi_ReadStub( (void*)(new_image_pointer+arch_size), ElfHandle->FileStruct,
248                                          (u32)(obj_image),
249                                          (image_pointer+arch_size), AR_GetEntrySize( &ArHdr));
250 
251                 new_image_pointer += (AR_GetEntrySize( &ArHdr) + arch_size);
252                 newarch_size += (AR_GetEntrySize( &ArHdr) + arch_size);
253             }
254             /*To next entry*/
255             obj_size = AR_GetEntrySize( &ArHdr);
256             if( obj_size %2)  //Padded by '\n' when the object size is an odd number.
257             {
258                 obj_size++;
259             }
260             image_pointer += arch_size + obj_size;
261         }
262         ElfHandle->newelf_size = newarch_size;
263     }else{/*--------------- For ELF files  ---------------*/
264         if( strncmp( OBJMAG, ELFMAG, 4) == 0) {
265             elf_num++;
266             if( type == 0) {
267                 all_result = ELi_LoadObject( ElfHandle, 0, buf);
268             }else{
269                 all_result = ELi_LoadObject2( ElfHandle, 0, buf);
270             }
271         }
272     }
273     /*-------------------------------------------------------*/
274 
275     if( elf_num) {
276         return all_result;
277     }else{
278         return EL_FAILED;
279     }
280 }
281 
282 /*------------------------------------------------------
283   Relocate ELF object to buffer
284 
285     ElfHandle: Header structure
286     obj_offset: Offset from RAM image address of object file
287     buf: Buffer for loading
288  -----------------------------------------------------*/
ELi_LoadObject(ELHandle * ElfHandle,void * obj_offset,void * buf)289 u16 ELi_LoadObject( ELHandle* ElfHandle, void* obj_offset, void* buf)
290 {
291     u16         i, j;
292 //    u32         num_of_entry;
293     ELShdrEx*   FwdShdrEx;
294     ELShdrEx*   CurrentShdrEx;
295     ELShdrEx    DmyShdrEx;
296 //    char        sym_str[128];     //For debugging print
297 //    u32         offset;           //For debugging print
298     u32         newelf_shoff = 0; //Write pointer to stripped ELF image
299     u32         buf_shdr;
300     u32         section_num = 0;
301 //    u32         newelf_size;
302     u32         tmp_buf;
303     u32         *shdr_table;      //Table for new/old number correspondence for section headers
304 //    u32         *sym_table;       //Table corresponding to the new/old numbers of symbol entries
305     u32         last_local_symbol_index = 0xFFFFFFFF;
306 
307 
308     /* Check initialization of ELHandle */
309     if( ElfHandle->process != EL_INITIALIZED) {
310         return EL_FAILED;
311     }
312     /* Buffer NULL check */
313     if( buf == NULL) {
314         return EL_FAILED;
315     }
316     /* Get ELF header */
317     ElfHandle->ELi_ReadStub( &(ElfHandle->CurrentEhdr), ElfHandle->FileStruct,
318                              (u32)(ElfHandle->ar_head), (u32)(obj_offset), sizeof( Elf32_Ehdr));
319 
320     /* Section handle build */
321     ElfHandle->elf_offset = obj_offset;
322     ElfHandle->buf_current = (void*)((u32)buf + sizeof( Elf32_Ehdr));
323     ElfHandle->shentsize = ElfHandle->CurrentEhdr.e_shentsize;
324 
325     /*Section header table build*/
326     shdr_table = (u32*)malloc( 4 * ElfHandle->CurrentEhdr.e_shnum);
327 
328     /*---------- Create ELShdrEx and shdr_table Lists  ----------*/
329     CurrentShdrEx = &DmyShdrEx;
330     for( i=0; i<(ElfHandle->CurrentEhdr.e_shnum); i++) {
331         CurrentShdrEx->next = (void*)(malloc( sizeof(ELShdrEx)));
332         CurrentShdrEx = (ELShdrEx*)(CurrentShdrEx->next);
333         memset( CurrentShdrEx, 0, sizeof(ELShdrEx));     //Clear zero
334 
335         /*Set flag to distinguish whether this is debugging information*/
336         if( ELi_ShdrIsDebug( ElfHandle, i) == TRUE) {    /*When it is debugging information*/
337             CurrentShdrEx->debug_flag = 1;
338             shdr_table[i] = 0xFFFFFFFF;
339         }else{                                           /*When not debugging information*/
340             /*Copy section header*/
341             ELi_GetShdr( ElfHandle, i, &(CurrentShdrEx->Shdr));
342             CurrentShdrEx->debug_flag = 0;
343             shdr_table[i] = section_num;                 /*Create section new/old table*/
344 //            printf( "shdr_table[0x%x] = 0x%x\n", i, section_num);
345             section_num++;
346             /*Get section string*/
347 #if 0 // Do not dynamically allocate section string buffer
348             CurrentShdrEx->str = (char*)malloc( 128);    //Get 128 character buffer
349             ELi_GetStrAdr( ElfHandle, ElfHandle->CurrentEhdr.e_shstrndx,
350                            CurrentShdrEx->Shdr.sh_name,
351                            CurrentShdrEx->str, 128);
352 #else
353             {
354                 u32 length;
355 
356                 length = ELi_GetStrLen( ElfHandle, ElfHandle->CurrentEhdr.e_shstrndx, CurrentShdrEx->Shdr.sh_name) + 1;
357 
358                 CurrentShdrEx->str = (char*)malloc(length);
359                 if(CurrentShdrEx->str == 0)
360                 {
361                     return EL_FAILED;
362                 }
363                 ELi_GetStrAdr( ElfHandle, ElfHandle->CurrentEhdr.e_shstrndx,
364                                CurrentShdrEx->Shdr.sh_name,
365                                CurrentShdrEx->str, length);
366             }
367 #endif
368         }
369     }
370 #if 0 /*Comment out because the addition of a special section was performed on the added-elf side*/
371     section_num++;                    //Add special section
372     ElfHandle->CurrentEhdr.e_shnum++; //Add special section
373     CurrentShdrEx->next = (void*)(malloc( sizeof(ELShdrEx)));
374     CurrentShdrEx = (ELShdrEx*)(CurrentShdrEx->next);
375     memset( CurrentShdrEx, 0, sizeof(ELShdrEx));    //Clear zero
376 //    CurrentShdrEx->Shdr.sh_name
377     CurrentShdrEx->Shdr.sh_type = SPECIAL_SECTION_TYPE;
378     CurrentShdrEx->Shdr.sh_flags = 0;
379     CurrentShdrEx->Shdr.sh_addr = 0;
380     CurrentShdrEx->Shdr.sh_offset = 0;
381     CurrentShdrEx->Shdr.sh_size = (section_num - 1)*4; //(ElfHandle->CurrentEhdr.e_shnum)*4; (When old section number is in the index)
382     CurrentShdrEx->Shdr.sh_link = 0;
383     CurrentShdrEx->Shdr.sh_info = 0;
384     CurrentShdrEx->Shdr.sh_addralign = 4;
385     CurrentShdrEx->Shdr.sh_entsize = 4;
386 #if 0 // Do not dynamically allocate section string buffer
387     CurrentShdrEx->str = (char*)malloc( 128);
388 #else
389     CurrentShdrEx->str = (char*)malloc( strlen(SPECIAL_SECTION_NAME) + 1 );
390     if(CurrentShdrEx->str == 0)
391     {
392         return EL_FAILED;
393     }
394 #endif
395     strcpy( CurrentShdrEx->str, SPECIAL_SECTION_NAME);
396 #endif
397     CurrentShdrEx->next = NULL;
398     ElfHandle->ShdrEx = DmyShdrEx.next;
399     /*--------------------------------------------------------*/
400 
401 
402     /*---------- Check and copy all sections  ----------*/
403 //    printf( "\nLoad to RAM:\n");
404     for( i=0; i<(ElfHandle->CurrentEhdr.e_shnum); i++) {
405         //
406         CurrentShdrEx = ELi_GetShdrExfromList( ElfHandle->ShdrEx, i);
407 
408         if( CurrentShdrEx->debug_flag == 1) {                 //When it is debugging information
409 //            printf( "skip debug-section %02x\n", i);
410         }else{                                                //When not debugging information
411             // .text section
412             if( /*(CurrentShdrEx->Shdr.sh_flags == (SHF_ALLOC | SHF_EXECINSTR))&&*/
413                 (CurrentShdrEx->Shdr.sh_type == SHT_PROGBITS)) {
414                 //Copy to memory
415                 CurrentShdrEx->loaded_adr = (u32)
416                                 ELi_CopySectionToBuffer( ElfHandle, &(CurrentShdrEx->Shdr));
417             }
418             // .data, .data1 section (Initialized data)
419 /*            else if( (CurrentShdrEx->Shdr.sh_flags == (SHF_ALLOC | SHF_WRITE))&&
420                 (CurrentShdrEx->Shdr.sh_type == SHT_PROGBITS)) {
421                 //Copy to memory
422                 CurrentShdrEx->loaded_adr = (u32)
423                                 ELi_CopySectionToBuffer( ElfHandle, &(CurrentShdrEx->Shdr));
424             }*/
425             // bss section
426             else if( (CurrentShdrEx->Shdr.sh_flags == (SHF_ALLOC | SHF_WRITE))&&
427                 (CurrentShdrEx->Shdr.sh_type == SHT_NOBITS)) {
428                 //Do not copy
429                 CurrentShdrEx->loaded_adr = ELi_ALIGN( (u32)(ElfHandle->buf_current), 4);
430 /*                CurrentShdrEx->loaded_adr = (u32)
431                                 ELi_AllocSectionToBuffer( ElfHandle, &(CurrentShdrEx->Shdr));*/
432             }
433             // .rodata, .rodata1 section
434 /*            else if( (CurrentShdrEx->Shdr.sh_flags == SHF_ALLOC)&&
435                 (CurrentShdrEx->Shdr.sh_type == SHT_PROGBITS)) {
436                 //Copy to memory
437                 CurrentShdrEx->loaded_adr = (u32)
438                                 ELi_CopySectionToBuffer( ElfHandle, &(CurrentShdrEx->Shdr));
439             }*/
440 #if 0 /*Comment out because the addition of a special section was performed on the added-elf side*/
441             else if( CurrentShdrEx->Shdr.sh_type == SPECIAL_SECTION_TYPE) {
442                 //Series of processes equivalent to ELi_CopySectionToBuffer
443                 u32 load_start = ELi_ALIGN( ((u32)(ElfHandle->buf_current)), 4);
444                 u32 sh_size    = CurrentShdrEx->Shdr.sh_size;
445                 u32* reverse_shdr_table = (u32*)malloc( 4 * (section_num-1)); //-1 is to exclude a special section
446                 /*Index converts to new section number table*/
447                 for( j=0; j<(ElfHandle->CurrentEhdr.e_shnum - 1); j++) {
448                     if( shdr_table[j] != 0xFFFFFFFF) {
449                         reverse_shdr_table[shdr_table[j]] = j;
450                     }
451                 }
452                 memcpy( (u32*)load_start, reverse_shdr_table, sh_size); //Copy new/old section correspondence table
453                 free( reverse_shdr_table);
454                 CurrentShdrEx->loaded_adr = load_start;
455                 ElfHandle->buf_current = (void*)(load_start + sh_size);
456             }
457 #endif
458             //Copy .arm_vfe_header, .ARM.exidx, .ARM.attributes and the like
459             else if( CurrentShdrEx->Shdr.sh_type >= SHT_LOPROC) {
460                 //Copy to memory
461                 CurrentShdrEx->loaded_adr = (u32)
462                                 ELi_CopySectionToBuffer( ElfHandle, &(CurrentShdrEx->Shdr));
463             }
464             //Symbol table section
465             else if( CurrentShdrEx->Shdr.sh_type == SHT_SYMTAB) {
466                 ELi_BuildSymList( ElfHandle, i, &(CurrentShdrEx->sym_table)); //Create symbol list
467                 {
468                     ELSymEx* CurrentSymEx;
469                     ELShdrEx* StrShEx;    //Character string section
470 #if 0 // Do not dynamically allocate section string buffer
471                     char     symstr[128];
472 #else
473                     char     *symstr;
474 #endif
475                     u32      symbol_num = 0;
476 
477                     /*--- Correct symbol entry data ---*/
478                     CurrentSymEx = ElfHandle->SymEx;
479                     while( CurrentSymEx != NULL) {  //If you track SymEx, debug symbols are not included
480                         /*Get character string section*/
481                         StrShEx = ELi_GetShdrExfromList( ElfHandle->ShdrEx,
482                                                          CurrentShdrEx->Shdr.sh_link);
483                         /*--- Build character string section content ---*/
484 #if 0 // Do not dynamically allocate section string buffer
485                         ELi_GetStrAdr( ElfHandle, CurrentShdrEx->Shdr.sh_link, //Get symbol string
486                                        CurrentSymEx->Sym.st_name,
487                                        symstr, 128);
488 #else
489                         {
490                             u32 length;
491 
492                             length = ELi_GetStrLen( ElfHandle, CurrentShdrEx->Shdr.sh_link, CurrentSymEx->Sym.st_name ) + 1;
493 
494                             symstr = (char*)malloc(length);
495                             if(symstr == 0)
496                             {
497                                 return EL_FAILED;
498                             }
499                             ELi_GetStrAdr( ElfHandle, CurrentShdrEx->Shdr.sh_link,
500                                            CurrentSymEx->Sym.st_name,
501                                            symstr, length);
502                         }
503 #endif
504                         StrShEx->str_table = realloc( StrShEx->str_table,     //Add symbol string
505                                                       (StrShEx->str_table_size) +
506                                                       strlen( symstr) + 1);
507                         strcpy( (u8*)((u32)StrShEx->str_table + StrShEx->str_table_size),
508                                 symstr);
509 
510                         CurrentSymEx->Sym.st_name = StrShEx->str_table_size; //Correct symbol entry data
511 
512                         StrShEx->str_table_size += ( strlen( symstr) + 1);
513 #if 0 // Do not dynamically allocate section string buffer
514 #else
515                         free(symstr);
516 #endif
517                         /*---------------------------------*/
518                         //Find final STB_LOCAL symbol (becomes the value of sh_info for the SYMTAB section header)
519                         if( ((ELF32_ST_BIND( (CurrentSymEx->Sym.st_info))) != STB_LOCAL)&&
520                             (last_local_symbol_index == 0xFFFFFFFF)) {
521                             last_local_symbol_index = symbol_num;
522                         }
523                         /*---------------------------------*/
524 
525                         symbol_num++;
526 
527                         /*---------------------------------*/
528                         if( (CurrentSymEx->Sym.st_shndx != SHN_UNDEF) &&
529                             (CurrentSymEx->Sym.st_shndx < SHN_LORESERVE)) {
530                             CurrentSymEx->Sym.st_shndx = shdr_table[CurrentSymEx->Sym.st_shndx]; //Update section number for the symbol entry
531                         }
532                         /*---------------------------------*/
533                         CurrentSymEx = CurrentSymEx->next;
534                     }/*-------------------------------------*/
535 
536                     /*--- Update the symbol table section header ---*/
537                     CurrentShdrEx->loaded_adr = (u32)(ELi_CopySymToBuffer( ElfHandle));
538                     if( (CurrentShdrEx->Shdr.sh_link != SHN_UNDEF) &&
539                         (CurrentShdrEx->Shdr.sh_link < SHN_LORESERVE)) {
540                             CurrentShdrEx->Shdr.sh_link = shdr_table[CurrentShdrEx->Shdr.sh_link]; //Update string section number
541                     }
542                     CurrentShdrEx->Shdr.sh_size = symbol_num * sizeof( Elf32_Sym);
543                     CurrentShdrEx->Shdr.sh_info = last_local_symbol_index; //Reference the ARM ELF materials
544                     /*----------------------------------------------*/
545                 }
546                 ELi_FreeSymList( ElfHandle, (u32**)(CurrentShdrEx->sym_table));    //Deallocate the symbol list
547             }
548 
549 /*            printf( "section %02x relocated at %08x\n",
550                         i, CurrentShdrEx->loaded_adr);*/
551         }
552     }
553 
554     /*---------- Processing for REL, RELA, STRTAB sections ----------*/
555     for( i=0; i<(ElfHandle->CurrentEhdr.e_shnum); i++) {
556         //
557         CurrentShdrEx = ELi_GetShdrExfromList( ElfHandle->ShdrEx, i);
558 
559         if( CurrentShdrEx->debug_flag == 1) {                //When it is debugging information
560         }else{                                               //When not debugging information
561             //REL section
562             if( CurrentShdrEx->Shdr.sh_type == SHT_REL) {
563                 CurrentShdrEx->loaded_adr = (u32)
564                                 ELi_CopySectionToBuffer( ElfHandle, &(CurrentShdrEx->Shdr));
565                 {
566                     Elf32_Rel*  CurrentRel;
567                     ELShdrEx*   SymShdrEx;
568                     u32         new_sym_num;
569                     /*Get the symbol section*/
570                     SymShdrEx = ELi_GetShdrExfromList( ElfHandle->ShdrEx,
571                                                        CurrentShdrEx->Shdr.sh_link);
572                     /*Correct the Rel section of the copy source*/
573                     for( j=0; j<(CurrentShdrEx->Shdr.sh_size/CurrentShdrEx->Shdr.sh_entsize); j++) {
574                         CurrentRel = (Elf32_Rel*)(CurrentShdrEx->loaded_adr + (j * sizeof( Elf32_Rel)));
575                         new_sym_num = SymShdrEx->sym_table[ELF32_R_SYM(CurrentRel->r_info)];
576                         CurrentRel->r_info = ELF32_R_INFO( new_sym_num,
577                                                             ELF32_R_TYPE(CurrentRel->r_info));
578                         }
579                 }
580             }
581             //RELA section
582             else if( CurrentShdrEx->Shdr.sh_type == SHT_RELA) {
583                 CurrentShdrEx->loaded_adr = (u32)
584                                 ELi_CopySectionToBuffer( ElfHandle, &(CurrentShdrEx->Shdr));
585                 {
586                     Elf32_Rela* CurrentRela;
587                     ELShdrEx*   SymShdrEx;
588                     u32         new_sym_num;
589                     /*Get the symbol section*/
590                     SymShdrEx = ELi_GetShdrExfromList( ElfHandle->ShdrEx,
591                                                        CurrentShdrEx->Shdr.sh_link);
592                     /*Correct the Rela section of the copy source*/
593                     for( j=0; j<(CurrentShdrEx->Shdr.sh_size/CurrentShdrEx->Shdr.sh_entsize); j++) {
594                         CurrentRela = (Elf32_Rela*)(CurrentShdrEx->loaded_adr + (j * sizeof( Elf32_Rela)));
595 //                        printf( "symnum: 0x%x\n", ELF32_R_SYM(CurrentRela->r_info));
596 //                        printf( "sym_table:0x%x", (u32)(SymShdrEx->sym_table));
597                         new_sym_num = SymShdrEx->sym_table[ELF32_R_SYM(CurrentRela->r_info)];
598                         CurrentRela->r_info = ELF32_R_INFO( new_sym_num,
599                                                             ELF32_R_TYPE(CurrentRela->r_info));
600                         }
601                 }
602             }
603             //String table section
604             else if( CurrentShdrEx->Shdr.sh_type == SHT_STRTAB) {
605                 if( i == ElfHandle->CurrentEhdr.e_shstrndx) { //Section name string table section
606                     CurrentShdrEx->loaded_adr = (u32)
607                         ELi_CopyShStrToBuffer( ElfHandle, &(CurrentShdrEx->Shdr));
608                 }else{
609                     CurrentShdrEx->loaded_adr = (u32)
610                         ELi_CopySymStrToBuffer( ElfHandle, CurrentShdrEx);
611 //                    printf( "sym str section:0x%x, size:0x%x\n", i, CurrentShdrEx->str_table_size);
612                 }
613             }
614         }
615     }
616     /*-------------------------------------------------------*/
617 
618 
619     /*Only the section content up to this point was copied to stripped ELF*/
620 
621 
622     /*---------- Copy section header to stripped elf ----------*/
623     buf_shdr = ELi_ALIGN( ((u32)(ElfHandle->buf_current)), 4);
624     ElfHandle->buf_current = (void*)buf_shdr;
625 //    printf( "buf_shdr = 0x%x\n", buf_shdr);
626 //    printf( "buf = 0x%x\n", (u32)buf);
627 
628     newelf_shoff = buf_shdr - ((u32)(buf));
629 //    printf( "newelf_shoff = 0x%x\n", newelf_shoff);
630 
631     section_num = 0;
632     for( i=0; i<(ElfHandle->CurrentEhdr.e_shnum); i++) {
633         //
634         tmp_buf = buf_shdr + ( section_num * sizeof( Elf32_Shdr));
635 
636         CurrentShdrEx = ELi_GetShdrExfromList( ElfHandle->ShdrEx, i);
637         if( CurrentShdrEx->debug_flag == 1) {                //Convert to the NULL section for debugging information
638 //            memset( (u8*)tmp_buf, '\0', sizeof( Elf32_Shdr));
639         }else{
640             /*Update offset*/
641             if( CurrentShdrEx->loaded_adr != 0) {
642                 CurrentShdrEx->Shdr.sh_offset = (CurrentShdrEx->loaded_adr - (u32)buf);
643             }
644             /*Copy section header to stripped ELF image*/
645             if( CurrentShdrEx->Shdr.sh_type == SHT_SYMTAB) {
646                 /*The symbol table sh_type indicates the index of the symbol entry*/
647               //For SYMTAB, because the sh_link is already converted at line 406, there is no need here.
648               //For SYMTAB, because the sh_info is already converted at line 428, there is no need here.
649             }else{
650                 CurrentShdrEx->Shdr.sh_link = shdr_table[CurrentShdrEx->Shdr.sh_link]; //Update section number
651                 CurrentShdrEx->Shdr.sh_info = shdr_table[CurrentShdrEx->Shdr.sh_info]; //Update section number
652             }
653             memcpy( (u8*)tmp_buf, &(CurrentShdrEx->Shdr),
654                     sizeof( Elf32_Shdr));
655             section_num++;                        /*Update section count*/
656         }
657     }
658 
659     // After copy ends
660     ElfHandle->process = EL_COPIED;
661     /*------------------------------------------------------------*/
662 
663     ElfHandle->newelf_size = (buf_shdr - (u32)buf) + (section_num*sizeof( Elf32_Shdr));
664 //    printf( "newelf_size = 0x%x\n", ElfHandle->newelf_size);
665 
666     /*---------- Update ELF Header ----------*/
667     ElfHandle->CurrentEhdr.e_shnum = section_num; /*Apply the reduced section count to the ELF header*/
668     ElfHandle->CurrentEhdr.e_shstrndx = shdr_table[ElfHandle->CurrentEhdr.e_shstrndx];
669     //Update the section header offset
670     ElfHandle->CurrentEhdr.e_shoff = newelf_shoff;
671     memcpy( (u8*)buf, &(ElfHandle->CurrentEhdr), sizeof( Elf32_Ehdr)); /*Copy ELF header to the stripped ELF image*/
672     /*-----------------------------------*/
673 
674 
675     /*---------- Relocate  ----------*/
676 /*    if( unresolved_table_block_flag == 0) {
677         if( dbg_print_flag == 1) {
678             printf( "\nRelocate Symbols:\n");
679         }
680     for( i=0; i<(ElfHandle->CurrentEhdr.e_shnum); i++) {
681         //
682         CurrentShdrEx = ELi_GetShdrExfromList( ElfHandle->ShdrEx, i);
683 
684         if( CurrentShdrEx->debug_flag == 1) {                //When it is debugging information
685         }else{                                                //When not debugging information
686 
687             if( CurrentShdrEx->Shdr.sh_type == SHT_REL) {
688                 num_of_entry = (CurrentShdrEx->Shdr.sh_size) /
689                                 (CurrentShdrEx->Shdr.sh_entsize);
690                 if( dbg_print_flag == 1) {
691                     printf( "num of REL = %x\n", num_of_entry);
692                     printf( "Section Header Info.\n");
693                     printf( "link   : %x\n", CurrentShdrEx->Shdr.sh_link);
694                     printf( "info   : %x\n", CurrentShdrEx->Shdr.sh_info);
695                     printf( " Offset     Info    Type            Sym.Value  Sym.Name\n");
696                 }
697                 offset = 0;
698                 for( j=0; j<num_of_entry; j++) {
699                     ELi_GetSent( ElfHandle, i, &(ElfHandle->Rel), offset, sizeof(Elf32_Rel));
700                     ELi_GetShdr( ElfHandle, CurrentShdrEx->Shdr.sh_link, &(ElfHandle->SymShdr));
701                     ELi_GetSent( ElfHandle, CurrentShdrEx->Shdr.sh_link, &(ElfHandle->Sym),
702                                  (u32)(ElfHandle->SymShdr.sh_entsize * ELF32_R_SYM( ElfHandle->Rel.r_info)), sizeof(Elf32_Sym));
703                     ELi_GetStrAdr( ElfHandle, ElfHandle->SymShdr.sh_link, ElfHandle->Sym.st_name, sym_str, 128);
704 
705                     if( dbg_print_flag == 1) {
706                         printf( "%08x  ", ElfHandle->Rel.r_offset);
707                         printf( "%08x ", ElfHandle->Rel.r_info);
708                         printf( "                  ");
709                         printf( "%08x ", ElfHandle->Sym.st_value);
710                         printf( sym_str);
711                         printf("\n");
712                     }
713                     // To next entry
714                     offset += (u32)(CurrentShdrEx->Shdr.sh_entsize);
715                 }
716                 if( dbg_print_flag == 1) {
717                     printf("\n");
718                 }
719                 //Relocate
720                 ELi_RelocateSym( ElfHandle, i);
721                 if( dbg_print_flag == 1) {
722                     printf("\n");
723                 }
724             }
725             else if( CurrentShdrEx->Shdr.sh_type == SHT_RELA) {
726 
727                 num_of_entry = (CurrentShdrEx->Shdr.sh_size) /
728                                 (CurrentShdrEx->Shdr.sh_entsize);
729                 if( dbg_print_flag == 1) {
730                     printf( "num of RELA = %x\n", num_of_entry);
731                     printf( "Section Header Info.\n");
732                     printf( "link   : %x\n", CurrentShdrEx->Shdr.sh_link);
733                     printf( "info   : %x\n", CurrentShdrEx->Shdr.sh_info);
734                     printf( " Offset     Info    Type            Sym.Value  Sym.Name\n");
735                 }
736                 offset = 0;
737                 for( j=0; j<num_of_entry; j++) {
738                     ELi_GetSent( ElfHandle, i, &(ElfHandle->Rela), offset, sizeof(Elf32_Rel));
739                     ELi_GetShdr( ElfHandle, CurrentShdrEx->Shdr.sh_link, &(ElfHandle->SymShdr));
740                     ELi_GetSent( ElfHandle, CurrentShdrEx->Shdr.sh_link, &(ElfHandle->Sym),
741                                  (u32)(ElfHandle->SymShdr.sh_entsize * ELF32_R_SYM( ElfHandle->Rela.r_info)), sizeof(Elf32_Sym));
742                     ELi_GetStrAdr( ElfHandle, ElfHandle->SymShdr.sh_link, ElfHandle->Sym.st_name, sym_str, 128);
743 
744                     if( dbg_print_flag == 1) {
745                         printf( "%08x  ", ElfHandle->Rela.r_offset);
746                         printf( "%08x ", ElfHandle->Rela.r_info);
747                         printf( "                  ");
748                         printf( "%08x ", ElfHandle->Sym.st_value);
749                         printf( sym_str);
750                         printf("\n");
751                     }
752                     // To next entry
753                     offset += (u32)(CurrentShdrEx->Shdr.sh_entsize);
754                 }
755                 if( dbg_print_flag == 1) {
756                     printf("\n");
757                 }
758                 //Relocate
759                 ELi_RelocateSym( ElfHandle, i);
760                 if( dbg_print_flag == 1) {
761                     printf("\n");
762                 }
763             }
764         }
765     }
766     }else{    //When not dll but a static module
767         for( i=0; i<(ElfHandle->CurrentEhdr.e_shnum); i++) {
768             CurrentShdrEx = ELi_GetShdrExfromList( ElfHandle->ShdrEx, i);
769             if( CurrentShdrEx->debug_flag == 1) {                //When it is debugging information
770             } else {
771                 if( CurrentShdrEx->Shdr.sh_type == SHT_SYMTAB) {
772                     ELi_DiscriminateGlobalSym( ElfHandle, i);
773                 }
774             }
775         }
776     }*/
777 
778     /*---------- Deallocate the ELShdrEx List  ----------*/
779     CurrentShdrEx = ElfHandle->ShdrEx;
780     if( CurrentShdrEx) {
781         do{
782             FwdShdrEx = CurrentShdrEx;
783             CurrentShdrEx = CurrentShdrEx->next;
784             if( FwdShdrEx->debug_flag == 0) {
785                 free( FwdShdrEx->str);    //When not debugging section
786             }
787             free( FwdShdrEx);
788         }while( CurrentShdrEx != NULL);
789         ElfHandle->ShdrEx = NULL;
790     }
791     /*-----------------------------------------*/
792 
793     /*Deallocate the section header table*/
794     free( shdr_table);
795 
796 
797 
798     /*Flush cache before the DLL in RAM is called*/
799 //    DC_FlushAll();
800 //    DC_WaitWriteBufferEmpty();
801 
802     return (ElfHandle->process);
803 }
804 
805 /*------------------------------------------------------
806   Resolve unresolved symbols using the address table
807  -----------------------------------------------------*/
EL_ResolveAllLibrary(void)808 u16 EL_ResolveAllLibrary( void)
809 {
810     ELAdrEntry*           AdrEnt;
811     ELUnresolvedEntry*    RemoveUnrEnt;
812     ELUnresolvedEntry*    UnrEnt;
813 //    ELUnresolvedEntry*    CurrentUnrEnt;
814 //    ELUnresolvedEntry*    FwdUnrEnt;
815 //    u32                    relocation_val;
816 //    ELAdrEntry            AddAdrEnt;
817 #if 0 // Do not dynamically allocate section string buffer
818     char                  sym_str[128];
819 #else
820     char                  *sym_str;
821 #endif
822     UnrEnt = ELUnrEntStart;
823     if( dbg_print_flag == 1) {
824         printf( "\nResolve all symbols:\n");
825     }
826     while( UnrEnt != NULL) {
827         if( UnrEnt->remove_flag == 0) {
828             AdrEnt = EL_GetAdrEntry( UnrEnt->sym_str);        /*Search from address table*/
829             if( AdrEnt) {                                    /*When found in address table*/
830                 UnrEnt->S_ = (u32)(AdrEnt->adr);
831                 UnrEnt->T_ = (u32)(AdrEnt->thumb_flag);
832                 if( unresolved_table_block_flag == 0) {
833                     if( dbg_print_flag == 1) {
834 //                        printf( "\n symbol found %s : %8x\n", UnrEnt->sym_str, UnrEnt->S_);
835                     }
836                     UnrEnt->remove_flag = 1;
837     //                ELi_RemoveUnresolvedEntry( UnrEnt);    //Delete from unresolved list because this was resolved
838                 }else{
839                     if( dbg_print_flag == 1) {
840                         printf( "\n static symbol found %s : %8x\n", UnrEnt->sym_str, (int)(UnrEnt->S_));
841                     }
842                     UnrEnt->AdrEnt = AdrEnt;            //Set the found address entry
843                     UnrEnt->remove_flag = 2;            //Marking (special value used only with makelst)
844 #if 0 // Do not dynamically allocate section string buffer
845 #else
846                     sym_str = (char*)malloc( strlen( UnrEnt->sym_str ) + 1 );
847                     if(sym_str == 0)
848                     {
849                         return EL_FAILED;
850                     }
851 #endif
852                     strcpy( sym_str, UnrEnt->sym_str);
853                     while( 1) {
854                         RemoveUnrEnt = ELi_GetUnresolvedEntry( sym_str);
855                         if( RemoveUnrEnt == NULL) {
856                             break;
857                         }else{
858                             RemoveUnrEnt->remove_flag = 1;
859                         }
860                     }
861 #if 0 // Do not dynamically allocate section string buffer
862 #else
863                     free(sym_str);
864 #endif
865                 }
866     /*            relocation_val = ELi_DoRelocate( UnrEnt);    //Resolve symbol
867                 if( !relocation_val) {
868                     return EL_FAILED;
869                 }*/
870 
871             }else{                                            /*When not found in address table*/
872                 if( unresolved_table_block_flag == 0) {
873                     if( dbg_print_flag == 1) {
874                         printf( "ERROR! cannot find symbol : %s\n", UnrEnt->sym_str);
875                     }
876                 }else{
877                     if( dbg_print_flag == 1) {
878                         printf( "ERROR! cannot find static symbol : %s\n", UnrEnt->sym_str);
879                     }
880                 }
881     /*            AddAdrEnt.next = NULL;
882                 AddAdrEnt.name = UnrEnt->sym_str;
883                 AddAdrEnt.
884                 EL_AddAdrEntry( */
885     //            return EL_FAILED;
886             }
887         }
888         UnrEnt = (ELUnresolvedEntry*)(UnrEnt->next);                            /*To next unresolved entry*/
889     }
890 
891     /*---------- Deallocate the ELUnresolvedEntry List  ----------*/
892 /*    CurrentUnrEnt = ELUnrEntStart;
893     if( CurrentUnrEnt) {
894         while( CurrentUnrEnt->next != NULL) {
895             FwdUnrEnt = CurrentUnrEnt;
896             CurrentUnrEnt = CurrentUnrEnt->next;
897             free( FwdUnrEnt->sym_str);    // symbol name string
898             free( FwdUnrEnt);            //Structure itself
899         }
900         ELUnrEntStart = NULL;
901     }*/
902     /*-------------------------------------------*/
903 
904     /*Flush cache before the DLL in RAM is called*/
905 //    DC_FlushAll();
906 //    DC_WaitWriteBufferEmpty();
907 
908     return EL_RELOCATED;
909 }
910 
911 
912 
913 
914 
915 /*------------------------------------------------------
916   Delete entry from address table
917  -----------------------------------------------------*/
EL_RemoveAdrEntry(ELAdrEntry * AdrEnt)918 BOOL EL_RemoveAdrEntry( ELAdrEntry* AdrEnt)
919 {
920     ELAdrEntry  DmyAdrEnt;
921     ELAdrEntry* CurrentAdrEnt;
922 
923     DmyAdrEnt.next = ELAdrEntStart;
924     CurrentAdrEnt  = &DmyAdrEnt;
925 
926     while( CurrentAdrEnt->next != AdrEnt) {
927         if( CurrentAdrEnt->next == NULL) {
928             return FALSE;
929         }else{
930             CurrentAdrEnt = (ELAdrEntry*)CurrentAdrEnt->next;
931         }
932     }
933 
934     CurrentAdrEnt->next = AdrEnt->next;
935     ELAdrEntStart = DmyAdrEnt.next;
936 
937     return TRUE;
938 }
939 
940 /*------------------------------------------------------
941   Add entry to address table
942  -----------------------------------------------------*/
EL_AddAdrEntry(ELAdrEntry * AdrEnt)943 void EL_AddAdrEntry( ELAdrEntry* AdrEnt)
944 {
945     ELAdrEntry  DmyAdrEnt;
946     ELAdrEntry* CurrentAdrEnt;
947 
948     if( !ELAdrEntStart) {
949         ELAdrEntStart = AdrEnt;
950     }else{
951         DmyAdrEnt.next = ELAdrEntStart;
952         CurrentAdrEnt = &DmyAdrEnt;
953 
954         while( CurrentAdrEnt->next != NULL) {
955             CurrentAdrEnt = (ELAdrEntry*)CurrentAdrEnt->next;
956         }
957         CurrentAdrEnt->next = (void*)AdrEnt;
958     }
959     AdrEnt->next = NULL;
960 }
961 
962 /*------------------------------------------------------
963   Search for entry corresponding to specified string in address table
964  -----------------------------------------------------*/
EL_GetAdrEntry(char * ent_name)965 ELAdrEntry* EL_GetAdrEntry( char* ent_name)
966 {
967     ELAdrEntry* CurrentAdrEnt;
968 
969     CurrentAdrEnt = ELAdrEntStart;
970     if( CurrentAdrEnt == NULL) {
971         return NULL;
972     }
973     while( strcmp( CurrentAdrEnt->name, ent_name) != 0) {
974         CurrentAdrEnt = (ELAdrEntry*)CurrentAdrEnt->next;
975         if( CurrentAdrEnt == NULL) {
976             break;
977         }
978     }
979     return CurrentAdrEnt;
980 }
981 
982 /*------------------------------------------------------
983   Return address corresponding to specified string in address table
984  -----------------------------------------------------*/
EL_GetGlobalAdr(char * ent_name)985 void* EL_GetGlobalAdr( char* ent_name)
986 {
987     u32         adr;
988     ELAdrEntry* CurrentAdrEnt;
989 
990     CurrentAdrEnt = EL_GetAdrEntry( ent_name);
991 
992     if( CurrentAdrEnt) {
993         if( CurrentAdrEnt->thumb_flag) {
994             adr = (u32)(CurrentAdrEnt->adr) + 1;
995         }else{
996             adr = (u32)(CurrentAdrEnt->adr);
997         }
998     }else{
999         adr = 0;
1000     }
1001 
1002     return (void*)(adr);
1003 }
1004 
1005 #if 0
1006 /*------------------------------------------------------
1007   Deallocate the address table (not allowed because it tried to delete up to the entry registered by the application)
1008  -----------------------------------------------------*/
1009 void* EL_FreeAdrTbl( void)
1010 {
1011     ELAdrEntry*    FwdAdrEnt;
1012     ELAdrEntry*    CurrentAdrEnt;
1013 
1014     /*---------- Deallocate the ELAdrEntry List  ----------*/
1015     CurrentAdrEnt = ELAdrEntStart;
1016     if( CurrentAdrEnt) {
1017         while( CurrentAdrEnt->next != NULL) {
1018             FwdAdrEnt = CurrentAdrEnt;
1019             CurrentAdrEnt = CurrentAdrEnt->next;
1020             free( FwdAdrEnt->name);        //Symbol name string
1021             free( FwdAdrEnt);            //Structure itself
1022         }
1023         ELAdrEntStart = NULL;
1024     }
1025     /*------------------------------------*/
1026 }
1027 #endif
1028 
1029 /*------------------------------------------------------
1030   Stub that reads data from the ELF object
1031  -----------------------------------------------------*/
ELi_ReadFile(void * buf,void * file_struct,u32 file_base,u32 file_offset,u32 size)1032 void ELi_ReadFile( void* buf, void* file_struct, u32 file_base, u32 file_offset, u32 size)
1033 {
1034 //  printf( "0x%x, 0x%x\n", file_offset, size);
1035     fseek( file_struct, file_offset, SEEK_SET);
1036     fread( buf, 1, size, file_struct);
1037 
1038 /*    FS_SeekFile( file_struct, (s32)(file_offset), FS_SEEK_SET);
1039     FS_ReadFile( file_struct, buf, (s32)(size));*/
1040 }
1041 
ELi_ReadMem(void * buf,void * file_struct,u32 file_base,u32 file_offset,u32 size)1042 void ELi_ReadMem( void* buf, void* file_struct, u32 file_base, u32 file_offset, u32 size)
1043 {
1044 /*    MI_CpuCopy8( (void*)(file_base + file_offset),
1045                 buf,
1046                 size);*/
1047     memcpy( buf,
1048             (void*)(file_base + file_offset),
1049             size);
1050 }
1051