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