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