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-12-15#$
14 $Rev: 9650 $
15 $Author: kitase_hirotake $
16 *---------------------------------------------------------------------------*/
17
18 #include "el_config.h"
19
20 #ifdef SDK_TWL
21 #include <twl.h>
22 #else
23 #include <nitro.h>
24 #endif
25
26 #include "elf.h"
27 #include "arch.h"
28 #include "elf_loader.h"
29 #include "loader_subset.h"
30 #include <istdbglibpriv.h>
31
32
33 #ifndef SDK_TWL
34 OSHeapHandle EL_Heap;
35 #endif
36
37
38 #if 1
39
40 /*------------------------------------------------------
41 Function to notify the IS-TWL_DEBUGGER
42 -----------------------------------------------------*/
43 void _ISTDbgLib_StartRegistRelocationInfo( ISTDOVERLAYPROC nProc );
44 BOOL _ISTDbgLib_RegistRelocationInfo( ISTDOVERLAYPROC nProc, u32 nDll, u32 nELF, u32 nSection, u32 nLMA );
45 void _ISTDbgLib_EndRegistRelocationInfo( ISTDOVERLAYPROC nProc );
46 BOOL _ISTDbgLib_UnregistRelocationInfo( ISTDOVERLAYPROC nProc, u32 nDll );
47
_ISTDbgLib_StartRegistRelocationInfo(ISTDOVERLAYPROC nProc)48 SDK_WEAK_SYMBOL void _ISTDbgLib_StartRegistRelocationInfo( ISTDOVERLAYPROC nProc )
49 {
50 (void)nProc;
51 return;
52 }
53
_ISTDbgLib_RegistRelocationInfo(ISTDOVERLAYPROC nProc,u32 nDll,u32 nELF,u32 nSection,u32 nLMA)54 SDK_WEAK_SYMBOL BOOL _ISTDbgLib_RegistRelocationInfo( ISTDOVERLAYPROC nProc, u32 nDll, u32 nELF, u32 nSection, u32 nLMA )
55 {
56 (void)nProc;
57 (void)nDll;
58 (void)nELF;
59 (void)nSection;
60 (void)nLMA;
61 return TRUE;
62 }
63
_ISTDbgLib_EndRegistRelocationInfo(ISTDOVERLAYPROC nProc)64 SDK_WEAK_SYMBOL void _ISTDbgLib_EndRegistRelocationInfo( ISTDOVERLAYPROC nProc )
65 {
66 (void)nProc;
67 return;
68 }
69
_ISTDbgLib_UnregistRelocationInfo(ISTDOVERLAYPROC nProc,u32 nDll)70 SDK_WEAK_SYMBOL BOOL _ISTDbgLib_UnregistRelocationInfo( ISTDOVERLAYPROC nProc, u32 nDll )
71 {
72 (void)nProc;
73 (void)nDll;
74 return TRUE;
75 }
76
77 /* stub */
78 static void ELi_START_REGISTER_RELOCATION_INFO( ISTDOVERLAYPROC nProc, BOOL enable );
79 static BOOL ELi_REGISTER_RELOCATION_INFO( ISTDOVERLAYPROC nProc, u32 nDll, u32 nELF, u32 nSection, u32 nLMA, BOOL enable );
80 static void ELi_END_REGISTER_RELOCATION_INFO( ISTDOVERLAYPROC nProc, BOOL enable );
81 static BOOL ELi_UNREGISTER_RELOCATION_INFO( ISTDOVERLAYPROC nProc, u32 nDll, BOOL enable );
82
ELi_START_REGISTER_RELOCATION_INFO(ISTDOVERLAYPROC nProc,BOOL enable)83 static void ELi_START_REGISTER_RELOCATION_INFO( ISTDOVERLAYPROC nProc, BOOL enable )
84 {
85 if( enable) {
86 _ISTDbgLib_StartRegistRelocationInfo( nProc);
87 }
88 }
ELi_REGISTER_RELOCATION_INFO(ISTDOVERLAYPROC nProc,u32 nDll,u32 nELF,u32 nSection,u32 nLMA,BOOL enable)89 static BOOL ELi_REGISTER_RELOCATION_INFO( ISTDOVERLAYPROC nProc, u32 nDll, u32 nELF, u32 nSection, u32 nLMA, BOOL enable )
90 {
91 if( enable) {
92 return( _ISTDbgLib_RegistRelocationInfo( nProc, nDll, nELF, nSection, nLMA));
93 }
94 return( FALSE);
95 }
ELi_END_REGISTER_RELOCATION_INFO(ISTDOVERLAYPROC nProc,BOOL enable)96 static void ELi_END_REGISTER_RELOCATION_INFO( ISTDOVERLAYPROC nProc, BOOL enable )
97 {
98 if( enable) {
99 _ISTDbgLib_EndRegistRelocationInfo( nProc);
100 }
101 }
ELi_UNREGISTER_RELOCATION_INFO(ISTDOVERLAYPROC nProc,u32 nDll,BOOL enable)102 static BOOL ELi_UNREGISTER_RELOCATION_INFO( ISTDOVERLAYPROC nProc, u32 nDll, BOOL enable )
103 {
104 if( enable) {
105 return( _ISTDbgLib_UnregistRelocationInfo( nProc, nDll));
106 }
107 return( FALSE);
108 }
109 #endif
110
111
112 /*------------------------------------------------------
113 External Functions
114 -----------------------------------------------------*/
115 extern ELDesc* i_eldesc_sim;
116
117
118 /*------------------------------------------------------
119 Global Variables
120 -----------------------------------------------------*/
121 static ELReadImage i_elReadImage;
122 ELAlloc i_elAlloc;
123 ELFree i_elFree;
124
125 static BOOL i_el_initialized = FALSE;
126 static OSMutex i_el_mutex;
127
128
129 /*------------------------------------------------------
130 Local Function Declarations
131 -----------------------------------------------------*/
132 static void ELi_FreeObject( ELObject** ELObjEntStart);
133 static void ELi_InitObject( ELObject* MYObject);
134 BOOL elRemoveObjEntry( ELObject** StartEnt, ELObject* ObjEnt);
135 static void elAddObjEntry( ELObject** StartEnt, ELObject* ObjEnt);
136
137 static BOOL ELi_ReInitDesc( ELDesc* elElfDesc);
138 static ELResult elLoadSegments( ELDesc* elElfDesc, ELObject* MYObject);
139 static ELResult elLoadSections( ELDesc* elElfDesc, ELObject* MYObject, u32 dll_fileid, u32 elf_num);
140
141 // Relocate ELF object or that archive in a buffer
142 static ELDlld ELi_LoadLibrary( ELDesc* elElfDesc, void* obj_image, u32 obj_len, void* buf, u32 dll_fileid);
143 // Core function that relocates ELF object to buffer
144 static ELResult ELi_LoadObject( ELDesc* elElfDesc, ELObject* MYObject, void* obj_offset, void* buf, u32 dll_fileid, u32 elf_num);
145 // Stub function that reads data from the ELF object
146 static BOOL ELi_ReadFile( void* buf, void* file_struct, u32 file_base, u32 file_offset, u32 size);
147 static BOOL ELi_ReadMem( void* buf, void* file_struct, u32 file_base, u32 file_offset, u32 size);
148 static BOOL ELi_ReadUsr( void* buf, void* file_struct, u32 file_base, u32 file_offset, u32 size);
149
150 // Delete entry from address table
151 //BOOL elRemoveAdrEntry( ELAdrEntry* AdrEnt);
152
153 // Add entry to address table
154 void elAddAdrEntry( ELAdrEntry** ELAdrEntStart, ELAdrEntry* AdrEnt);
155
156 // Search for entry corresponding to specified string in address table
157 ELAdrEntry* elGetAdrEntry( ELDesc* elElfDesc, const char* ent_name, ELObject** ExpObjEnt);
158
159 // Release all address tables
160 static void elFreeAdrTbl( ELAdrEntry** ELAdrEntStart);
161
162
163 /*---------------------------------------------------------
164 Find size of the ELF object
165
166 buf: Address of ELF image
167 --------------------------------------------------------*/
EL_GetElfSize(const void * buf)168 u32 EL_GetElfSize( const void* buf)
169 {
170 Elf32_Ehdr Ehdr;
171 u32 size;
172
173 if( ELF_LoadELFHeader( buf, &Ehdr) == NULL) {
174 return 0;
175 }
176 size = (u32)(Ehdr.e_shoff + (Ehdr.e_shentsize * Ehdr.e_shnum));
177 return size;
178 }
179
180
181 /*---------------------------------------------------------
182 Find the size of the linked library
183 --------------------------------------------------------*/
EL_GetLibSize(ELDlld my_dlld)184 u32 EL_GetLibSize( ELDlld my_dlld)
185 {
186 if( my_dlld == 0) {
187 return( 0);
188 }
189 return( ((ELObject*)my_dlld)->lib_size);
190 }
191
192
193 /*------------------------------------------------------
194 Initialize the dynamic link system
195 -----------------------------------------------------*/
196 #if 0
197 //#ifndef SDK_TWL
198 void ELi_Init( void)
199 {
200 void* heap_start;
201
202 if( i_el_initialized) {
203 return;
204 }
205
206 i_el_initialized = TRUE;
207
208 /*--- Set memory allocation relationship ---*/
209 OS_InitArena();
210 heap_start = OS_InitAlloc( OS_ARENA_MAIN, OS_GetMainArenaLo(), OS_GetMainArenaHi(), 1);
211 OS_SetMainArenaLo( heap_start );
212 EL_Heap = OS_CreateHeap( OS_ARENA_MAIN, heap_start, (void*)((u32)(OS_GetMainArenaHi())+1));
213 OS_SetCurrentHeap( OS_ARENA_MAIN, EL_Heap);
214 /*--------------------------------------*/
215
216 OS_InitMutex( &i_el_mutex);
217 }
218 #else
ELi_Init(ELAlloc alloc,ELFree free)219 void ELi_Init( ELAlloc alloc, ELFree free)
220 {
221 i_elAlloc = alloc;
222 i_elFree = free;
223
224 if( i_el_initialized) {
225 return;
226 }
227
228 i_el_initialized = TRUE;
229
230 OS_InitMutex( &i_el_mutex);
231 }
232
ELi_Malloc(ELDesc * elElfDesc,ELObject * MYObject,size_t size)233 void* ELi_Malloc( ELDesc* elElfDesc, ELObject* MYObject, size_t size)
234 {
235 void* ptr;
236
237 ptr = OSAPI_MALLOC( size);
238 if( ptr == NULL) {
239 ELi_SetResultCode( elElfDesc, MYObject, EL_RESULT_NO_MORE_RESOURCE);
240 return( NULL);
241 }
242 return( ptr);
243 }
244 #endif
245
246 /*------------------------------------------------------
247 Initialize the ELDesc structure
248 -----------------------------------------------------*/
ELi_InitDesc(ELDesc * elElfDesc)249 BOOL ELi_InitDesc( ELDesc* elElfDesc)
250 {
251 if( elElfDesc == NULL) { /*NULL check*/
252 return FALSE;
253 }
254
255 /*Set defaut values*/
256 elElfDesc->ShdrEx = NULL;
257 elElfDesc->SymEx = NULL;
258 elElfDesc->SymExTbl = NULL;
259 elElfDesc->SymExTarget = 0xFFFFFFFF;
260
261 elElfDesc->process = (u32)EL_PROC_INITIALIZED; /*Set the flag*/
262 elElfDesc->result = (u32)EL_RESULT_SUCCESS;
263
264 /**/
265 elElfDesc->ELObjectStart = NULL;
266 elElfDesc->ELStaticObj = NULL;
267
268 return TRUE;
269 }
270
271 /*------------------------------------------------------
272 Reinitialize the ELDesc structure if the object has finished reading
273 -----------------------------------------------------*/
ELi_ReInitDesc(ELDesc * elElfDesc)274 static BOOL ELi_ReInitDesc( ELDesc* elElfDesc)
275 {
276 if( elElfDesc == NULL) { /*NULL check*/
277 return FALSE;
278 }
279
280 /*Set defaut values*/
281 elElfDesc->ShdrEx = NULL;
282 elElfDesc->SymEx = NULL;
283 elElfDesc->SymExTbl = NULL;
284 elElfDesc->SymExTarget = 0xFFFFFFFF;
285
286 elElfDesc->process = (u32)EL_PROC_INITIALIZED; /*Set the flag*/
287 elElfDesc->result = (u32)EL_RESULT_SUCCESS;
288
289 return TRUE;
290 }
291
292 /*------------------------------------------------------
293 Relocate ELF object or that archive in a buffer
294
295 elElfDesc: Header structure
296 ObjFile: Object file or archive file structure
297 buf: Buffer for loading
298 -----------------------------------------------------*/
EL_LoadLibraryfromFile(ELDesc * elElfDesc,const char * FilePath,void * buf)299 ELDlld EL_LoadLibraryfromFile( ELDesc* elElfDesc, const char* FilePath, void* buf)
300 {
301 ELDlld dlld;
302 u32 len;
303 FSFile file[1];
304 FSFileID file_id[1];
305
306 if( elElfDesc == NULL) {
307 return( 0);
308 }
309
310 OS_LockMutex( &i_el_mutex);
311
312 FS_InitFile(file);
313
314 if( !FS_OpenFileEx(file, FilePath, FS_FILEMODE_R) )
315 {
316 ELi_SetResultCode( elElfDesc, NULL, EL_RESULT_CANNOT_ACCESS_ELF);
317 OS_UnlockMutex( &i_el_mutex);
318 return 0;
319 }
320
321 if( !FS_ConvertPathToFileID( file_id, FilePath ) )
322 {
323 (void)FS_CloseFile(file);
324 OS_UnlockMutex( &i_el_mutex);
325 return 0;
326 }
327
328 /*Set read function*/
329 elElfDesc->i_elReadStub = ELi_ReadFile;
330 elElfDesc->FileStruct = (int*)file;
331
332 len = FS_GetFileLength( file );
333
334 dlld = ELi_LoadLibrary( elElfDesc, NULL, len, buf, file_id[0].file_id);
335
336 if( dlld != 0) {
337 ((ELObject*)dlld)->file_id = file_id[0].file_id;
338 }
339
340 if( !FS_CloseFile(file)) {
341 ELi_SetResultCode( elElfDesc, NULL, EL_RESULT_CANNOT_ACCESS_ELF);
342 dlld = 0;
343 }
344
345 OS_UnlockMutex( &i_el_mutex);
346 return( dlld);
347 }
348
349 /*------------------------------------------------------
350 Relocate ELF object or that archive in a buffer
351
352 elElfDesc: Header structure
353 readfunc: User function the reads object or archive files
354 buf: Buffer for loading
355 -----------------------------------------------------*/
EL_LoadLibrary(ELDesc * elElfDesc,ELReadImage readfunc,u32 len,void * buf)356 ELDlld EL_LoadLibrary( ELDesc* elElfDesc, ELReadImage readfunc, u32 len, void* buf)
357 {
358 ELDlld dlld;
359
360 if( elElfDesc == NULL) {
361 return( 0);
362 }
363
364 OS_LockMutex( &i_el_mutex);
365
366 i_elReadImage = readfunc;
367 elElfDesc->i_elReadStub = ELi_ReadUsr;
368
369 dlld = ELi_LoadLibrary( elElfDesc, NULL, len, buf, 0xFFFFFFFF);
370
371 if( dlld != 0) {
372 ((ELObject*)dlld)->file_id = 0xFFFFFFFF;
373 }
374
375 OS_UnlockMutex( &i_el_mutex);
376 return( dlld);
377 }
378
379 /*------------------------------------------------------
380 Relocate ELF object or that archive in a buffer
381
382 elElfDesc: Header structure
383 obj_image: Image address on RAM of object file or archive file
384 buf: Buffer for loading
385 -----------------------------------------------------*/
EL_LoadLibraryfromMem(ELDesc * elElfDesc,void * obj_image,u32 obj_len,void * buf)386 ELDlld EL_LoadLibraryfromMem( ELDesc* elElfDesc, void* obj_image, u32 obj_len, void* buf)
387 {
388 ELDlld dlld;
389
390 if( elElfDesc == NULL) {
391 return( 0);
392 }
393
394 OS_LockMutex( &i_el_mutex);
395
396 /*Set read function*/
397 elElfDesc->i_elReadStub = ELi_ReadMem;
398 elElfDesc->FileStruct = NULL;
399
400 dlld = ELi_LoadLibrary( elElfDesc, obj_image, obj_len, buf, 0xFFFFFFFF);
401
402 if( dlld != 0) {
403 ((ELObject*)dlld)->file_id = 0xFFFFFFFF;
404 }
405
406 OS_UnlockMutex( &i_el_mutex);
407 return( dlld);
408 }
409
410 /*------------------------------------------------------
411 Relocate ELF object or that archive in a buffer
412
413 elElfDesc: Header structure
414 obj_image: Image address on RAM of object file or archive file
415 buf: Buffer for loading
416 -----------------------------------------------------*/
ELi_LoadLibrary(ELDesc * elElfDesc,void * obj_image,u32 obj_len,void * buf,u32 dll_fileid)417 static ELDlld ELi_LoadLibrary( ELDesc* elElfDesc, void* obj_image, u32 obj_len, void* buf, u32 dll_fileid)
418 {
419 ELResult result;
420 u32 image_pointer;
421 u32 arch_size;
422 u32 elf_num = 0; /*Number of ELF objects*/
423 ArchHdr ArHdr;
424 char OBJMAG[8];
425 char ELFMAG[4] = { ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3};
426 ELObject* MYObject;
427
428 /*-------*/
429 if( elElfDesc->i_elReadStub == NULL) {
430 ELi_SetResultCode( elElfDesc, NULL, EL_RESULT_CANNOT_ACCESS_ELF);
431 return( 0);
432 }
433 /*-------*/
434
435 /* Allocate individual object management structure */
436 MYObject = (ELObject*)ELi_Malloc( elElfDesc, NULL, sizeof( ELObject));
437 if(MYObject == NULL)
438 return 0;
439 ELi_InitObject( MYObject);
440 elAddObjEntry( &(elElfDesc->ELObjectStart), MYObject);
441
442 elElfDesc->ar_head = obj_image;
443 image_pointer = 0;
444 MYObject->lib_start = buf;
445 MYObject->buf_current = buf;
446
447 if( elElfDesc->i_elReadStub( OBJMAG, elElfDesc->FileStruct, (u32)obj_image, 0, 8) == FALSE) { /*Get the OBJ character string*/
448 ELi_SetResultCode( elElfDesc, MYObject, EL_RESULT_CANNOT_ACCESS_ELF);
449 return( 0);
450 }
451 /*--------------- For archive files ---------------*/
452 if( OSAPI_STRNCMP( OBJMAG, ARMAG, 8) == 0) {
453 arch_size = sizeof( ArchHdr);
454 image_pointer += 8; /*To first entry*/
455
456 while( image_pointer < obj_len) {
457 if( elElfDesc->i_elReadStub( OBJMAG, elElfDesc->FileStruct, (u32)(obj_image), (image_pointer+arch_size), 4)
458 == FALSE) { /*Get the OBJ character string*/
459 ELi_SetResultCode( elElfDesc, MYObject, EL_RESULT_CANNOT_ACCESS_ELF);
460 break;
461 }
462 if( OSAPI_STRNCMP( OBJMAG, ELFMAG, 4) == 0) {
463 /*Reset initial values*/
464 (void)ELi_ReInitDesc( elElfDesc);
465 result = ELi_LoadObject( elElfDesc, MYObject, (void*)(image_pointer+arch_size), MYObject->buf_current, dll_fileid, elf_num);
466 if( result != EL_RESULT_SUCCESS) {
467 break;
468 }
469 elf_num++;
470 }else{
471 }
472 /*To next entry*/
473 if( elElfDesc->i_elReadStub( &ArHdr, elElfDesc->FileStruct, (u32)(obj_image), image_pointer, arch_size)
474 == FALSE) {
475 ELi_SetResultCode( elElfDesc, MYObject, EL_RESULT_CANNOT_ACCESS_ELF);
476 return( 0);
477 }
478 image_pointer += arch_size + AR_GetEntrySize( &ArHdr);
479 }
480 }else{/*--------------- For ELF files ---------------*/
481 if( OSAPI_STRNCMP( OBJMAG, ELFMAG, 4) == 0) {
482 /*Reset initial values*/
483 (void)ELi_ReInitDesc( elElfDesc);
484 result = ELi_LoadObject( elElfDesc, MYObject, 0, MYObject->buf_current, dll_fileid, elf_num);
485 if( result != EL_RESULT_SUCCESS) {
486 }else{
487 elf_num++;
488 }
489 }else{
490 ELi_SetResultCode( elElfDesc, MYObject, EL_RESULT_INVALID_ELF);
491 }
492 }
493 /*-------------------------------------------------------*/
494
495 if( elf_num) {
496 if( OS_IsRunOnDebugger() == FALSE) {
497 (void)ELi_FreeVenTbl( elElfDesc, MYObject); /*Release the veneer link list when not debugging*/
498 }
499 MYObject->stat = elf_num;
500 //When (MEMO)Segment was loaded, buf_current was not advanced, so it was not applied to lib_size
501 MYObject->lib_size = ((u32)(MYObject->buf_current)) - ((u32)(MYObject->lib_start));
502 PRINTDEBUG( "library size : 0x%x\n", MYObject->lib_size);
503 return( (ELDlld)MYObject);
504 }else{
505 /* Object could not be processed so structure was destroyed */
506 (void)elRemoveObjEntry( &(elElfDesc->ELObjectStart), MYObject);
507 return 0; //NULL
508 }
509 }
510
511 /*------------------------------------------------------
512 Relocate ELF object to buffer
513
514 elElfDesc: Header structure
515 MYObject: Individual object management structure
516 obj_offset: Offset from image address on object file RAM
517 buf: Buffer to load (TODO: Buffer overflow countermeasure)
518 -----------------------------------------------------*/
ELi_LoadObject(ELDesc * elElfDesc,ELObject * MYObject,void * obj_offset,void * buf,u32 dll_fileid,u32 elf_num)519 static ELResult ELi_LoadObject( ELDesc* elElfDesc, ELObject* MYObject, void* obj_offset, void* buf, u32 dll_fileid, u32 elf_num)
520 {
521 ELResult ret_val;
522
523 /* Check initialization of ELDesc */
524 if( elElfDesc->process != (u32)EL_PROC_INITIALIZED) {
525 return( EL_RESULT_FAILURE);
526 }
527 /* Get ELF header */
528 if( elElfDesc->i_elReadStub( &(elElfDesc->CurrentEhdr), elElfDesc->FileStruct,
529 (u32)(elElfDesc->ar_head), (u32)(obj_offset), sizeof( Elf32_Ehdr))
530 == FALSE) {
531 ELi_SetResultCode( elElfDesc, MYObject, EL_RESULT_CANNOT_ACCESS_ELF);
532 return( EL_RESULT_CANNOT_ACCESS_ELF);
533 }
534
535 /* Build ELDesc structure */
536 elElfDesc->elf_offset = obj_offset;
537 elElfDesc->shentsize = elElfDesc->CurrentEhdr.e_shentsize;
538 elElfDesc->entry_adr = elElfDesc->CurrentEhdr.e_entry;
539
540 /* Process for each ELF file type */
541 switch( elElfDesc->CurrentEhdr.e_type) {
542
543 case ET_NONE:
544 PRINTDEBUG( "ERROR : Elf type \"ET_NONE\"\n");
545 ELi_SetResultCode( elElfDesc, MYObject, EL_RESULT_UNSUPPORTED_ELF);
546 ret_val = EL_RESULT_UNSUPPORTED_ELF;
547 break;
548
549 case ET_REL: /* X to execute; O to relocate */
550 PRINTDEBUG( "Elf type \"ET_REL\"\n");
551 if( buf == NULL) { /* Buffer NULL check */
552 ELi_SetResultCode( elElfDesc, MYObject, EL_RESULT_NO_MORE_RESOURCE);
553 return EL_RESULT_NO_MORE_RESOURCE;
554 }
555 ret_val = elLoadSections( elElfDesc, MYObject, dll_fileid, elf_num);
556 break;
557
558 case ET_EXEC: /* O to execute; X to relocate */
559 PRINTDEBUG( "Elf type \"ET_EXEC\"\n");
560 ret_val = elLoadSegments( elElfDesc, MYObject);
561 break;
562
563 case ET_DYN: /* O to execute; O to relocate (TODO: untested)*/
564 PRINTDEBUG( "Elf type \"ET_DYN\"\n");
565 if( buf == NULL) { //Handle as ET_EXEC when the load address is not specified
566 ret_val = elLoadSegments( elElfDesc, MYObject);
567 }else{ //Handle as ET_REL when the load address is not specified
568 ret_val = elLoadSections( elElfDesc, MYObject, dll_fileid, elf_num);
569 }
570 break;
571
572 case ET_CORE:
573 PRINTDEBUG( "ERROR : Elf type \"ET_CORE\"\n");
574 ELi_SetResultCode( elElfDesc, MYObject, EL_RESULT_UNSUPPORTED_ELF);
575 ret_val = EL_RESULT_UNSUPPORTED_ELF;
576 break;
577
578 default:
579 PRINTDEBUG( "ERROR : Invalid Elf type 0x%x\n",
580 elElfDesc->CurrentEhdr.e_type);
581 ELi_SetResultCode( elElfDesc, MYObject, EL_RESULT_INVALID_ELF);
582 ret_val = EL_RESULT_INVALID_ELF;
583 break;
584 }
585
586 return( ret_val);
587 }
588
589
590 /*------------------------------------------------------
591 Check and copy all segments
592
593 elElfDesc: Header structure
594 -----------------------------------------------------*/
elLoadSegments(ELDesc * elElfDesc,ELObject * MYObject)595 static ELResult elLoadSegments( ELDesc* elElfDesc, ELObject* MYObject)
596 {
597 u16 i;
598 //u32 load_start;
599 Elf32_Phdr CurrentPhdr;
600
601 for( i=0; i<(elElfDesc->CurrentEhdr.e_phnum); i++) {
602 /*Copy program header*/
603 ELi_GetPhdr( elElfDesc, i, &CurrentPhdr);
604
605 if( CurrentPhdr.p_type == PT_LOAD) {
606 /*If loadable segment, load to memory*/
607 if( ELi_CopySegmentToBuffer( elElfDesc, MYObject, &CurrentPhdr) == NULL) {
608 return( EL_RESULT_CANNOT_ACCESS_ELF);
609 }
610 }else{
611 PRINTDEBUG( "WARNING : skip segment (type = 0x%x)\n",
612 CurrentPhdr.p_type);
613 }
614 }
615 ELi_SetProcCode( elElfDesc, MYObject, EL_PROC_COPIED);
616 return( EL_RESULT_SUCCESS);
617 }
618
619
620 /*------------------------------------------------------
621 Check and copy all sections
622
623 elElfDesc: Header structure
624 -----------------------------------------------------*/
elLoadSections(ELDesc * elElfDesc,ELObject * MYObject,u32 dll_fileid,u32 elf_num)625 static ELResult elLoadSections( ELDesc* elElfDesc, ELObject* MYObject, u32 dll_fileid, u32 elf_num)
626 {
627 u16 i;
628 ELShdrEx* FwdShdrEx;
629 ELShdrEx* CurrentShdrEx;
630 ELShdrEx* InfoShdrEx; //For example, consider CurrentShdrEx as .text for rel.text
631 ELShdrEx DmyShdrEx;
632 #if (DEBUG_PRINT_ON == 1)
633 u16 j;
634 u32 num_of_entry;
635 char sym_str[128]; //For debug print
636 u32 offset; //For debug print
637 #endif
638
639 /*---------- Create ELShdrEx List ----------*/
640 CurrentShdrEx = &DmyShdrEx;
641 for( i=0; i<(elElfDesc->CurrentEhdr.e_shnum); i++) {
642 CurrentShdrEx->next = ELi_Malloc( elElfDesc, MYObject, sizeof(ELShdrEx));
643 if(CurrentShdrEx->next == NULL) {
644 return( EL_RESULT_NO_MORE_RESOURCE);
645 }
646 CurrentShdrEx = (ELShdrEx*)(CurrentShdrEx->next);
647 OSAPI_CPUFILL8( CurrentShdrEx, 0, sizeof(ELShdrEx)); //Zero-clear
648
649 /*Set flag to distinguish whether this is debugging information*/
650 if( ELi_ShdrIsDebug( elElfDesc, i) == TRUE) { /*When it is debugging information*/
651 CurrentShdrEx->debug_flag = 1;
652 }else{ /*When not debugging information*/
653 /*Copy section header*/
654 ELi_GetShdr( elElfDesc, i, &(CurrentShdrEx->Shdr));
655 CurrentShdrEx->debug_flag = 0;
656 }
657 }
658 CurrentShdrEx->next = NULL;
659 elElfDesc->ShdrEx = DmyShdrEx.next;
660 /*--------------------------------------------*/
661
662 ELi_START_REGISTER_RELOCATION_INFO( ISTDRELOCATIONPROC_AUTO, (elElfDesc != i_eldesc_sim));
663
664 /*---------- Check and copy all sections ----------*/
665 PRINTDEBUG( "\nLoad to RAM:\n");
666 for( i=0; i<(elElfDesc->CurrentEhdr.e_shnum); i++) {
667 /**/
668 CurrentShdrEx = ELi_GetShdrExfromList( elElfDesc->ShdrEx, i);
669 // PRINTDEBUG( "section:%d sh_flag=0x%x\n", i, CurrentShdrEx->Shdr.sh_flags);
670 // PRINTDEBUG( "section:%d sh_type=0x%x\n", i, CurrentShdrEx->Shdr.sh_type);
671
672 if( CurrentShdrEx->debug_flag == 1) { /*When it is debugging information*/
673 PRINTDEBUG( "skip debug-section %02x\n", i);
674 }else{ /*When not debugging information*/
675 BOOL bLocate = FALSE;
676
677 /* .text section */
678 if( (CurrentShdrEx->Shdr.sh_flags == (SHF_ALLOC | SHF_EXECINSTR))&&
679 (CurrentShdrEx->Shdr.sh_type == SHT_PROGBITS)) {
680 //Copy to memory
681 CurrentShdrEx->loaded_adr = (u32)
682 ELi_CopySectionToBuffer( elElfDesc, MYObject, &(CurrentShdrEx->Shdr));
683 bLocate = TRUE;
684 }
685 /* .data, .data1 section (Initialized data) */
686 else if( (CurrentShdrEx->Shdr.sh_flags == (SHF_ALLOC | SHF_WRITE))&&
687 (CurrentShdrEx->Shdr.sh_type == SHT_PROGBITS)) {
688 //Copy to memory
689 CurrentShdrEx->loaded_adr = (u32)
690 ELi_CopySectionToBuffer( elElfDesc, MYObject, &(CurrentShdrEx->Shdr));
691 bLocate = TRUE;
692 }
693 /* bss section */
694 else if( (CurrentShdrEx->Shdr.sh_flags == (SHF_ALLOC | SHF_WRITE))&&
695 (CurrentShdrEx->Shdr.sh_type == SHT_NOBITS)) {
696 //Do not copy
697 CurrentShdrEx->loaded_adr = (u32)
698 ELi_AllocSectionToBuffer( elElfDesc, MYObject, &(CurrentShdrEx->Shdr));
699 bLocate = TRUE;
700 }
701 /* .rodata, .rodata1 section*/
702 else if( (CurrentShdrEx->Shdr.sh_flags == SHF_ALLOC)&&
703 (CurrentShdrEx->Shdr.sh_type == SHT_PROGBITS)) {
704 //Copy to memory
705 CurrentShdrEx->loaded_adr = (u32)
706 ELi_CopySectionToBuffer( elElfDesc, MYObject, &(CurrentShdrEx->Shdr));
707 bLocate = TRUE;
708 }
709
710 if (bLocate) {
711 if( CurrentShdrEx->loaded_adr == NULL) { //When failed in ELi_CopySectionToBuffer
712 ELi_END_REGISTER_RELOCATION_INFO( ISTDRELOCATIONPROC_AUTO, (elElfDesc != i_eldesc_sim));
713 return( EL_RESULT_CANNOT_ACCESS_ELF);
714 }
715 (void)ELi_REGISTER_RELOCATION_INFO( ISTDRELOCATIONPROC_AUTO, dll_fileid, elf_num, i, CurrentShdrEx->loaded_adr, (elElfDesc != i_eldesc_sim));
716 }
717
718 PRINTDEBUG( "section %02x relocated at %08x\n",
719 i, CurrentShdrEx->loaded_adr);
720 }
721 }
722 /* After copy ends */
723 ELi_SetProcCode( elElfDesc, MYObject, EL_PROC_COPIED);
724 /*----------------------------------------------------*/
725
726 ELi_END_REGISTER_RELOCATION_INFO( ISTDRELOCATIONPROC_AUTO, (elElfDesc != i_eldesc_sim));
727
728 /*---------- Publication of global symbols and relocating of local symbols ----------*/
729 PRINTDEBUG( "\nRelocate Symbols:\n");
730 for( i=0; i<(elElfDesc->CurrentEhdr.e_shnum); i++) {
731 /**/
732 CurrentShdrEx = ELi_GetShdrExfromList( elElfDesc->ShdrEx, i);
733
734 if( CurrentShdrEx->debug_flag == 1) { /*When it is debugging information*/
735 }else{ /*When not debugging information*/
736
737 if( CurrentShdrEx->Shdr.sh_type == SHT_REL) {
738 /*Relocate*/
739 InfoShdrEx = ELi_GetShdrExfromList( elElfDesc->ShdrEx,
740 CurrentShdrEx->Shdr.sh_info);
741 if( InfoShdrEx->loaded_adr != 0) { //Relocate internally if targeted section is loaded
742 if(ELi_RelocateSym( elElfDesc, MYObject, i) == FALSE)
743 return( (ELResult)(elElfDesc->result)); //EL_RESULT_NO_MORE_RESOURCE or EL_RESULT_UNSUPPORTED_ELF
744 }
745 #if (DEBUG_PRINT_ON == 1)
746 num_of_entry = (CurrentShdrEx->Shdr.sh_size) /
747 (CurrentShdrEx->Shdr.sh_entsize);
748
749 PRINTDEBUG( "num of REL = %x\n", num_of_entry);
750 PRINTDEBUG( "Section Header Info.\n");
751 PRINTDEBUG( "link : %x\n", CurrentShdrEx->Shdr.sh_link);
752 PRINTDEBUG( "info : %x\n", CurrentShdrEx->Shdr.sh_info);
753 PRINTDEBUG( " Offset Info Type Sym.Value Sym.Name\n");
754 offset = 0;
755 for( j=0; j<num_of_entry; j++) {
756 ELi_GetSent( elElfDesc, i, &(elElfDesc->Rel), offset, sizeof(Elf32_Rel));
757 ELi_GetShdr( elElfDesc, CurrentShdrEx->Shdr.sh_link, &(elElfDesc->SymShdr));
758 ELi_GetSent( elElfDesc, CurrentShdrEx->Shdr.sh_link, &(elElfDesc->Sym),
759 (u32)(elElfDesc->SymShdr.sh_entsize * ELF32_R_SYM( elElfDesc->Rel.r_info)), sizeof(Elf32_Sym));
760 ELi_GetStrAdr( elElfDesc, elElfDesc->SymShdr.sh_link, elElfDesc->Sym.st_name, sym_str, 128);
761
762 PRINTDEBUG( "%08x ", elElfDesc->Rel.r_offset);
763 PRINTDEBUG( "%08x ", elElfDesc->Rel.r_info);
764 PRINTDEBUG( " ");
765 PRINTDEBUG( "%08x ", elElfDesc->Sym.st_value);
766 PRINTDEBUG( sym_str);
767 PRINTDEBUG( "\n");
768 /*To next entry*/
769 offset += (u32)(CurrentShdrEx->Shdr.sh_entsize);
770 }
771 #endif
772 }
773 else if( CurrentShdrEx->Shdr.sh_type == SHT_RELA) {
774 /*Relocate*/
775 InfoShdrEx = ELi_GetShdrExfromList( elElfDesc->ShdrEx,
776 CurrentShdrEx->Shdr.sh_info);
777 if( InfoShdrEx->loaded_adr != 0) { //Relocate internally if targeted section is loaded
778 if(ELi_RelocateSym( elElfDesc, MYObject, i) == FALSE)
779 return( EL_RESULT_NO_MORE_RESOURCE);
780 }
781
782 #if (DEBUG_PRINT_ON == 1)
783 num_of_entry = (CurrentShdrEx->Shdr.sh_size) /
784 (CurrentShdrEx->Shdr.sh_entsize);
785 PRINTDEBUG( "num of RELA = %x\n", num_of_entry);
786 PRINTDEBUG( "Section Header Info.\n");
787 PRINTDEBUG( "link : %x\n", CurrentShdrEx->Shdr.sh_link);
788 PRINTDEBUG( "info : %x\n", CurrentShdrEx->Shdr.sh_info);
789 PRINTDEBUG( " Offset Info Type Sym.Value Sym.Name\n");
790 offset = 0;
791 for( j=0; j<num_of_entry; j++) {
792 ELi_GetSent( elElfDesc, i, &(elElfDesc->Rela), offset, sizeof(Elf32_Rel));
793 ELi_GetShdr( elElfDesc, CurrentShdrEx->Shdr.sh_link, &(elElfDesc->SymShdr));
794 ELi_GetSent( elElfDesc, CurrentShdrEx->Shdr.sh_link, &(elElfDesc->Sym),
795 (u32)(elElfDesc->SymShdr.sh_entsize * ELF32_R_SYM( elElfDesc->Rela.r_info)), sizeof(Elf32_Sym));
796 ELi_GetStrAdr( elElfDesc, elElfDesc->SymShdr.sh_link, elElfDesc->Sym.st_name, sym_str, 128);
797
798 PRINTDEBUG( "%08x ", elElfDesc->Rela.r_offset);
799 PRINTDEBUG( "%08x ", elElfDesc->Rela.r_info);
800 PRINTDEBUG( " ");
801 PRINTDEBUG( "%08x ", elElfDesc->Sym.st_value);
802 PRINTDEBUG( sym_str);
803 PRINTDEBUG( "\n");
804 /*To next entry*/
805 offset += (u32)(CurrentShdrEx->Shdr.sh_entsize);
806 }
807 #endif
808 }
809 else if( CurrentShdrEx->Shdr.sh_type == SHT_SYMTAB) {
810 /*Register global symbol in address table*/
811 if(ELi_GoPublicGlobalSym( elElfDesc, MYObject, i) == FALSE)
812 return( EL_RESULT_NO_MORE_RESOURCE);
813 }
814 }
815 }
816 /*Create in ELi_RelocateSym and ELi_GoPublicGlobalSym & and release the used symbol list*/
817 ELi_FreeSymList( elElfDesc);
818
819 /*---------- Free the ELShdrEx List ----------*/
820 CurrentShdrEx = elElfDesc->ShdrEx;
821 if( CurrentShdrEx) {
822 do {
823 FwdShdrEx = CurrentShdrEx;
824 CurrentShdrEx = CurrentShdrEx->next;
825 OSAPI_FREE( FwdShdrEx);
826 }while( CurrentShdrEx != NULL);
827 elElfDesc->ShdrEx = NULL;
828 }
829 /*-----------------------------------------*/
830
831 /*Flush cache before DLL is called on RAM*/
832 #if (TARGET_ARM_V5 == 1)
833 OSAPI_FLUSHCACHEALL();
834 OSAPI_WAITCACHEBUF();
835 #endif
836
837 return( EL_RESULT_SUCCESS);
838 }
839
840 /*------------------------------------------------------
841 Resolve unresolved symbols using the address table
842 -----------------------------------------------------*/
ELi_ResolveAllLibrary(ELDesc * elElfDesc)843 ELProcess ELi_ResolveAllLibrary( ELDesc* elElfDesc)
844 {
845 ELAdrEntry* AdrEnt;
846 ELImportEntry* UnrEnt;
847 ELImportEntry* NextEnt;
848 // ELImportEntry* CurrentUnrEnt;
849 // ELImportEntry* FwdUnrEnt;
850 ELObject* ObjEnt;
851 ELObject* ExpObjEnt;
852 BOOL ret_val;
853
854 if( elElfDesc == NULL) {
855 return( EL_PROC_NOTHING);
856 }
857 ObjEnt = elElfDesc->ELObjectStart;
858 if( (ObjEnt == NULL)||((ObjEnt == elElfDesc->ELStaticObj)&&(ObjEnt->next == NULL))) {
859 return( EL_PROC_NOTHING); /* If there is no dll */
860 }
861 while( ObjEnt != NULL) {
862 UnrEnt = (ELImportEntry*)ObjEnt->UnresolvedImportAdrEnt;
863 PRINTDEBUG( "\nResolve all symbols:\n");
864 while( UnrEnt != NULL) {
865 NextEnt = UnrEnt->next;
866 AdrEnt = elGetAdrEntry( elElfDesc, UnrEnt->sym_str, &ExpObjEnt); /*Search from address table*/
867 if( AdrEnt) { /*When found in address table*/
868 UnrEnt->S_ = (u32)(AdrEnt->adr);
869 UnrEnt->T_ = (u32)(AdrEnt->thumb_flag);
870 PRINTDEBUG( "\n symbol found %s : %8x\n", UnrEnt->sym_str, UnrEnt->S_);
871 ret_val = ELi_DoRelocate( elElfDesc, ObjEnt, UnrEnt); /*Resolve symbol*/
872 if( ret_val == FALSE) {
873 return( (ELProcess)(ObjEnt->process)); //Should be EL_PROC_COPIED Is osPanic better? TODO: continuation
874 }else{
875 PRINTDEBUG( "%s ... ObjEnt:0x%x, ExpObjEnt:0x%x\n", UnrEnt->sym_str, ObjEnt, ExpObjEnt);
876 UnrEnt->Dlld = (struct ELObject*)ExpObjEnt; /*Register ObjEnt referenced in resolution*/
877 /* Change link from Unresolved to Resolved */
878 (void)ELi_ExtractImportEntry( &(ObjEnt->UnresolvedImportAdrEnt), UnrEnt);
879 ELi_AddImportEntry( &(ObjEnt->ResolvedImportAdrEnt), UnrEnt);
880 }
881 }else{ /*When not found in address table*/
882 if( elElfDesc != i_eldesc_sim) {
883 PRINTDEBUG( "\n ERROR! cannot find symbol : %s\n\n", UnrEnt->sym_str);
884 return( (ELProcess)(ObjEnt->process)); //Should be EL_PROC_COPIED Is osPanic better? TODO: Continue
885 }
886 /*----- For simulation, assume it was forcefully resolved -----*/
887 UnrEnt->S_ = (u32)0;
888 UnrEnt->T_ = (u32)0;
889 ret_val = ELi_DoRelocate( elElfDesc, ObjEnt, UnrEnt);
890 UnrEnt->Dlld = (struct ELObject*)NULL; /*Register ObjEnt referenced in resolution*/
891 /* Change link from Unresolved to Resolved */
892 (void)ELi_ExtractImportEntry( &(ObjEnt->UnresolvedImportAdrEnt), UnrEnt);
893 ELi_AddImportEntry( &(ObjEnt->ResolvedImportAdrEnt), UnrEnt);
894 /*--------------------------------------------------------*/
895 }
896 UnrEnt = NextEnt; /*To next unresolved entry*/
897 }
898 ELi_SetProcCode( NULL, ObjEnt, EL_PROC_RELOCATED);
899 ObjEnt->lib_size = ((u32)(ObjEnt->buf_current)) - ((u32)(ObjEnt->lib_start)); //There is the possibility that veneer was added, so update the size.
900 ObjEnt = ObjEnt->next;
901 }
902 ELi_SetProcCode( elElfDesc, NULL, EL_PROC_RELOCATED);
903
904 /*TODO: When fixed, only the UnrEnt entry that could not be resolved here should be deleted*/
905 #if 0
906 /*---------- Free the ELImportEntry List ----------*/
907 ELi_FreeImportTbl( &ELUnrEntStart);
908 /*-------------------------------------------*/
909 #endif
910 /*Release the veneer link request*/
911 // (void)ELi_FreeVenTbl();
912
913 /*Flush cache before DLL is called on RAM*/
914 #if (TARGET_ARM_V5 == 1)
915 OSAPI_FLUSHCACHEALL();
916 OSAPI_WAITCACHEBUF();
917 #endif
918
919 return EL_PROC_RELOCATED;
920 }
921
922
923 /*------------------------------------------------------
924 Unlink the object
925 -----------------------------------------------------*/
ELi_Unlink(ELDesc * elElfDesc,ELDlld my_dlld)926 BOOL ELi_Unlink( ELDesc* elElfDesc, ELDlld my_dlld)
927 {
928 ELObject* MYObject;
929 ELObject* ObjEnt;
930 ELImportEntry* ResEnt;
931 ELImportEntry* NextEnt;
932 u32 file_id;
933
934 if( elElfDesc == NULL) {
935 return( FALSE);
936 }
937
938 if( my_dlld == 0) {
939 ELi_SetResultCode( elElfDesc, NULL, EL_RESULT_INVALID_PARAMETER);
940 return( FALSE);
941 }
942
943 /* Object to unlink */
944 MYObject = (ELObject*)my_dlld;
945
946 /* Get the file ID of the object to unlink */
947 file_id = MYObject->file_id;
948
949 #if 0
950 /* Hide all export information */
951 if( MYObject->ExportAdrEnt) {
952 MYObject->HiddenAdrEnt = MYObject->ExportAdrEnt;
953 MYObject->ExportAdrEnt = NULL;
954 }
955 #else
956 /* Clear all export information */
957 elFreeAdrTbl( &(MYObject->ExportAdrEnt));
958 #endif
959
960 /* Reference other objects and make the resolved portions unresolved */
961 ObjEnt = elElfDesc->ELObjectStart;
962 while( ObjEnt != NULL) {
963 ResEnt = ObjEnt->ResolvedImportAdrEnt;
964 while( ResEnt != NULL) {
965 NextEnt = ResEnt->next;
966 PRINTDEBUG( "Compare ObjEnt:0x%x, ExpObjEnt:0x%x\n", ResEnt->Dlld, MYObject);
967 if( ResEnt->Dlld == (struct ELObject*)MYObject) {
968 PRINTDEBUG( "Unlink from ObjEnt:0x%x, ExpObjEnt:0x%x\n", ObjEnt, MYObject);
969 /* Link from Resolved to Unresolved */
970 (void)ELi_ExtractImportEntry( &(ObjEnt->ResolvedImportAdrEnt), ResEnt);
971 ELi_AddImportEntry( &(ObjEnt->UnresolvedImportAdrEnt), ResEnt);
972 ResEnt->Dlld = NULL;
973 }
974 ResEnt = NextEnt;
975 }
976 ObjEnt = ObjEnt->next;
977 }
978
979 /*Do not destroy import information or self*/
980
981
982 /*Destroy the veneer table*/
983 (void)ELi_FreeVenTbl( elElfDesc, MYObject); /*Release the veneer link request*/
984
985 ELi_SetProcCode( elElfDesc, MYObject, EL_PROC_NOTHING);
986
987 ELi_START_REGISTER_RELOCATION_INFO( ISTDRELOCATIONPROC_AUTO, (elElfDesc != i_eldesc_sim));
988 (void)ELi_UNREGISTER_RELOCATION_INFO( ISTDRELOCATIONPROC_AUTO, file_id, (elElfDesc != i_eldesc_sim));
989 ELi_END_REGISTER_RELOCATION_INFO( ISTDRELOCATIONPROC_AUTO, (elElfDesc != i_eldesc_sim));
990
991 return( TRUE);
992 }
993
994
995 /*------------------------------------------------------
996 Deallocate all object lists
997 -----------------------------------------------------*/
ELi_FreeObject(ELObject ** ELObjEntStart)998 static void ELi_FreeObject( ELObject** ELObjEntStart)
999 {
1000 ELObject* FwdObjEnt;
1001 ELObject* CurrentObjEnt;
1002
1003 /*---------- Free the ELObject List ----------*/
1004 CurrentObjEnt = (*ELObjEntStart);
1005 if( CurrentObjEnt) {
1006 do {
1007 FwdObjEnt = CurrentObjEnt;
1008 CurrentObjEnt = CurrentObjEnt->next;
1009 /**/
1010 elFreeAdrTbl( &(FwdObjEnt->ExportAdrEnt));
1011 elFreeAdrTbl( &(FwdObjEnt->HiddenAdrEnt));
1012 ELi_FreeImportTbl( &(FwdObjEnt->ResolvedImportAdrEnt));
1013 ELi_FreeImportTbl( &(FwdObjEnt->UnresolvedImportAdrEnt));
1014 OSAPI_FREE( FwdObjEnt);
1015 }while( CurrentObjEnt != NULL);
1016 (*ELObjEntStart) = NULL;
1017 }
1018 /*----------------------------------*/
1019 }
1020
1021
1022 /*------------------------------------------------------
1023 Check whether there are unresolved external references remaining in the object
1024 -----------------------------------------------------*/
EL_IsResolved(ELDlld my_dlld)1025 BOOL EL_IsResolved( ELDlld my_dlld)
1026 {
1027 ELObject* MYObject;
1028
1029 if( my_dlld == 0) {
1030 return( FALSE);
1031 }
1032
1033 MYObject = (ELObject*)my_dlld;
1034 /*TODO: Check whether MYObject is linked to the list*/
1035 if( (MYObject->stat != 0)&&(MYObject->UnresolvedImportAdrEnt == NULL)) {
1036 return( TRUE);
1037 }else{
1038 return( FALSE);
1039 }
1040 }
1041
1042
1043 /*------------------------------------------------------
1044 Initializes the object management structure.
1045 -----------------------------------------------------*/
ELi_InitObject(ELObject * MYObject)1046 static void ELi_InitObject( ELObject* MYObject)
1047 {
1048 MYObject->next = NULL;
1049 MYObject->lib_size = 0;
1050 MYObject->ExportAdrEnt = NULL;
1051 MYObject->HiddenAdrEnt = NULL;
1052 MYObject->ResolvedImportAdrEnt = NULL;
1053 MYObject->UnresolvedImportAdrEnt = NULL;
1054 MYObject->ELVenEntStart = NULL;
1055 MYObject->ELV4tVenEntStart = NULL;
1056 MYObject->stat = 0;
1057
1058 MYObject->process = (u32)EL_PROC_INITIALIZED;
1059 MYObject->result = (u32)EL_RESULT_SUCCESS;
1060 }
1061
1062
1063 /*------------------------------------------------------
1064 Delete entry from the object table
1065 -----------------------------------------------------*/
elRemoveObjEntry(ELObject ** StartEnt,ELObject * ObjEnt)1066 BOOL elRemoveObjEntry( ELObject** StartEnt, ELObject* ObjEnt)
1067 {
1068 ELObject DmyObjEnt;
1069 ELObject* CurObjEnt;
1070
1071 DmyObjEnt.next = (*StartEnt);
1072 CurObjEnt = &DmyObjEnt;
1073
1074 while( CurObjEnt->next != ObjEnt) {
1075 if( CurObjEnt->next == NULL) {
1076 return FALSE;
1077 }else{
1078 CurObjEnt = (ELObject*)CurObjEnt->next;
1079 }
1080 }
1081
1082 /*Relink link list*/
1083 CurObjEnt->next = ObjEnt->next;
1084 (*StartEnt) = DmyObjEnt.next;
1085
1086 /*Free*/
1087 elFreeAdrTbl( &(ObjEnt->ExportAdrEnt));
1088 elFreeAdrTbl( &(ObjEnt->HiddenAdrEnt));
1089 ELi_FreeImportTbl( &(ObjEnt->ResolvedImportAdrEnt));
1090 ELi_FreeImportTbl( &(ObjEnt->UnresolvedImportAdrEnt));
1091 ELi_InitObject( ObjEnt); //stat = 0;
1092 OSAPI_FREE( ObjEnt);
1093
1094 return TRUE;
1095 }
1096
1097 /*------------------------------------------------------
1098 Add entry to object table
1099 -----------------------------------------------------*/
elAddObjEntry(ELObject ** StartEnt,ELObject * ObjEnt)1100 static void elAddObjEntry( ELObject** StartEnt, ELObject* ObjEnt)
1101 {
1102 ELObject DmyObjEnt;
1103 ELObject* CurObjEnt;
1104
1105 if( (*StartEnt) == NULL) {
1106 (*StartEnt) = ObjEnt;
1107 }else{
1108 DmyObjEnt.next = (*StartEnt);
1109 CurObjEnt = &DmyObjEnt;
1110
1111 while( CurObjEnt->next != NULL) {
1112 CurObjEnt = (ELObject*)CurObjEnt->next;
1113 }
1114 CurObjEnt->next = (void*)ObjEnt;
1115 }
1116 ObjEnt->next = NULL;
1117 }
1118
1119
1120 /*------------------------------------------------------
1121 Delete entry from address table
1122 -----------------------------------------------------*/
1123 #if 0
1124 BOOL elRemoveAdrEntry( ELAdrEntry* AdrEnt)
1125 {
1126 ELAdrEntry DmyAdrEnt;
1127 ELAdrEntry* CurrentAdrEnt;
1128
1129 DmyAdrEnt.next = ELAdrEntStart;
1130 CurrentAdrEnt = &DmyAdrEnt;
1131
1132 while( CurrentAdrEnt->next != AdrEnt) {
1133 if( CurrentAdrEnt->next == NULL) {
1134 return FALSE;
1135 }else{
1136 CurrentAdrEnt = (ELAdrEntry*)CurrentAdrEnt->next;
1137 }
1138 }
1139
1140 /*Relink link list*/
1141 CurrentAdrEnt->next = AdrEnt->next;
1142 ELAdrEntStart = DmyAdrEnt.next;
1143
1144 /*Free*/
1145 OSAPI_FREE( AdrEnt);
1146
1147 return TRUE;
1148 }
1149 #endif
1150
1151 /*------------------------------------------------------
1152 Add entry to address table
1153 -----------------------------------------------------*/
elAddAdrEntry(ELAdrEntry ** ELAdrEntStart,ELAdrEntry * AdrEnt)1154 void elAddAdrEntry( ELAdrEntry** ELAdrEntStart, ELAdrEntry* AdrEnt)
1155 {
1156 ELAdrEntry DmyAdrEnt;
1157 ELAdrEntry* CurrentAdrEnt;
1158
1159 if( (*ELAdrEntStart) == NULL) {
1160 (*ELAdrEntStart) = AdrEnt;
1161 }else{
1162 DmyAdrEnt.next = (*ELAdrEntStart);
1163 CurrentAdrEnt = &DmyAdrEnt;
1164
1165 while( CurrentAdrEnt->next != NULL) {
1166 CurrentAdrEnt = (ELAdrEntry*)CurrentAdrEnt->next;
1167 }
1168 CurrentAdrEnt->next = (void*)AdrEnt;
1169 }
1170 AdrEnt->next = NULL;
1171 }
1172
1173 /*------------------------------------------------------
1174 Add entry from application to address table
1175 -----------------------------------------------------*/
ELi_Export(ELDesc * elElfDesc,ELAdrEntry * AdrEnt)1176 BOOL ELi_Export( ELDesc* elElfDesc, ELAdrEntry* AdrEnt)
1177 {
1178 ELAdrEntry DmyAdrEnt;
1179 ELAdrEntry* CurrentAdrEnt;
1180
1181 if( elElfDesc == NULL) {
1182 return( FALSE);
1183 }
1184 if( elElfDesc->ELStaticObj == NULL) {
1185 elElfDesc->ELStaticObj = (ELObject*)ELi_Malloc( elElfDesc, NULL, sizeof( ELObject));
1186 if(elElfDesc->ELStaticObj == NULL) {
1187 return( FALSE);
1188 }
1189 ELi_InitObject( elElfDesc->ELStaticObj);
1190 elAddObjEntry( &(elElfDesc->ELObjectStart), elElfDesc->ELStaticObj);
1191 }
1192
1193 if( !(elElfDesc->ELStaticObj->ExportAdrEnt)) {
1194 elElfDesc->ELStaticObj->ExportAdrEnt = (ELAdrEntry*)AdrEnt;
1195 }else{
1196 DmyAdrEnt.next = (ELAdrEntry*)elElfDesc->ELStaticObj->ExportAdrEnt;
1197 CurrentAdrEnt = &DmyAdrEnt;
1198
1199 while( CurrentAdrEnt->next != NULL) {
1200 CurrentAdrEnt = (ELAdrEntry*)CurrentAdrEnt->next;
1201 }
1202 CurrentAdrEnt->next = (void*)AdrEnt;
1203 }
1204 AdrEnt->next = NULL;
1205 return( TRUE);
1206 }
1207
1208 /*------------------------------------------------------
1209 Add entry of static side to address table
1210 -----------------------------------------------------*/
1211 #ifndef SDK_TWL
EL_AddStaticSym(void)1212 SDK_WEAK_SYMBOL void EL_AddStaticSym( void)
1213 //__declspec(weak) void EL_AddStaticSym( void)
1214 #else
1215 SDK_WEAK_SYMBOL void EL_AddStaticSym( void)
1216 #endif
1217 {
1218 PRINTDEBUG( "please link file which is generated by \"makelst\".\n");
1219 while( 1) {};
1220 }
1221
1222 /*------------------------------------------------------
1223 Return entry corresponding to specified character string from entire address table and set the object that is exporting that entry to the ExpObEnt
1224
1225 -----------------------------------------------------*/
elGetAdrEntry(ELDesc * elElfDesc,const char * ent_name,ELObject ** ExpObjEnt)1226 ELAdrEntry* elGetAdrEntry( ELDesc* elElfDesc, const char* ent_name, ELObject** ExpObjEnt)
1227 {
1228 ELObject* ObjEnt;
1229 ELAdrEntry* CurrentAdrEnt;
1230
1231 ObjEnt = elElfDesc->ELObjectStart;
1232 while( ObjEnt != NULL) {
1233 CurrentAdrEnt = ObjEnt->ExportAdrEnt;
1234 while( CurrentAdrEnt != NULL) {
1235 if( OSAPI_STRCMP( CurrentAdrEnt->name, ent_name) == 0) {
1236 (*ExpObjEnt) = ObjEnt; //Specify object that is exporting
1237 goto get_end;
1238 }
1239 CurrentAdrEnt = (ELAdrEntry*)CurrentAdrEnt->next;
1240 }
1241 ObjEnt = ObjEnt->next;
1242 }
1243 (*ExpObjEnt) = NULL; //Nobody is exporting
1244 get_end:
1245 return CurrentAdrEnt;
1246 }
1247
1248 /*------------------------------------------------------
1249 Return address corresponding to specified string in address table
1250 -----------------------------------------------------*/
ELi_GetGlobalAdr(ELDesc * elElfDesc,ELDlld my_dlld,const char * ent_name)1251 void* ELi_GetGlobalAdr( ELDesc* elElfDesc, ELDlld my_dlld, const char* ent_name)
1252 {
1253 u32 adr;
1254 ELAdrEntry* CurrentAdrEnt;
1255 ELObject* DmyObjEnt;
1256
1257 if( elElfDesc == NULL) {
1258 return( 0);
1259 }
1260
1261 if( my_dlld == 0) { /*Search from entirety*/
1262 CurrentAdrEnt = elGetAdrEntry( elElfDesc, ent_name, &DmyObjEnt);
1263 }else{ /*Search from specific objects*/
1264 CurrentAdrEnt = ((ELObject*)my_dlld)->ExportAdrEnt;
1265 while( CurrentAdrEnt != NULL) {
1266 if( OSAPI_STRCMP( CurrentAdrEnt->name, ent_name) == 0) {
1267 break;
1268 }
1269 CurrentAdrEnt = (ELAdrEntry*)CurrentAdrEnt->next;
1270 }
1271 }
1272
1273 if( CurrentAdrEnt) {
1274 if( CurrentAdrEnt->thumb_flag) { //TODO: only for func_flag
1275 adr = (u32)(CurrentAdrEnt->adr) + 1;
1276 }else{
1277 adr = (u32)(CurrentAdrEnt->adr);
1278 }
1279 }else{
1280 adr = 0;
1281 }
1282
1283 return (void*)(adr);
1284 }
1285
1286
1287 /*------------------------------------------------------
1288 Release all address tables
1289 -----------------------------------------------------*/
elFreeAdrTbl(ELAdrEntry ** ELAdrEntStart)1290 static void elFreeAdrTbl( ELAdrEntry** ELAdrEntStart)
1291 {
1292 ELAdrEntry* FwdAdrEnt;
1293 ELAdrEntry* CurrentAdrEnt;
1294
1295 /*---------- Free the ELAdrEntry List ----------*/
1296 CurrentAdrEnt = (*ELAdrEntStart);
1297 if( CurrentAdrEnt) {
1298 do {
1299 FwdAdrEnt = CurrentAdrEnt;
1300 CurrentAdrEnt = CurrentAdrEnt->next;
1301 OSAPI_FREE( FwdAdrEnt->name); //Symbol name character-string
1302 OSAPI_FREE( FwdAdrEnt); //Structure itself
1303 }while( CurrentAdrEnt != NULL);
1304 (*ELAdrEntStart) = NULL;
1305 }
1306 /*------------------------------------*/
1307 }
1308
1309
1310 /*------------------------------------------------------
1311 Stub that reads data from the ELF object
1312 -----------------------------------------------------*/
ELi_ReadFile(void * buf,void * file_struct,u32 file_base,u32 file_offset,u32 size)1313 static BOOL ELi_ReadFile( void* buf, void* file_struct, u32 file_base, u32 file_offset, u32 size)
1314 {
1315 #pragma unused( file_base)
1316 if( FS_SeekFile( file_struct, (s32)(file_offset), FS_SEEK_SET) == FALSE) {
1317 return( FALSE);
1318 }
1319 if( FS_ReadFile( file_struct, buf, (s32)(size)) == (s32)size) {
1320 return( TRUE);
1321 }else{
1322 return( FALSE);
1323 }
1324 }
1325
ELi_ReadMem(void * buf,void * file_struct,u32 file_base,u32 file_offset,u32 size)1326 static BOOL ELi_ReadMem( void* buf, void* file_struct, u32 file_base, u32 file_offset, u32 size)
1327 {
1328 #pragma unused(file_struct)
1329 OSAPI_CPUCOPY8( (void*)(file_base + file_offset),
1330 buf,
1331 size);
1332 return( TRUE);
1333 }
1334
ELi_ReadUsr(void * buf,void * file_struct,u32 file_base,u32 file_offset,u32 size)1335 static BOOL ELi_ReadUsr( void* buf, void* file_struct, u32 file_base, u32 file_offset, u32 size)
1336 {
1337 #pragma unused(file_struct)
1338 #pragma unused(file_base)
1339 if( i_elReadImage( file_offset, buf, size) == 0) {
1340 return( TRUE);
1341 }
1342 return( FALSE);
1343 }
1344
1345
1346 /*------------------------------------------------------
1347 Set of error codes/process codes
1348 Set ELResult when initial value is SUCCESS and an error occurs
1349 Set ELProcess when the initial value is INITIALIZED, and in conjunction with progress.
1350 -----------------------------------------------------*/
ELi_SetResultCode(ELDesc * elElfDesc,ELObject * MYObject,ELResult result)1351 void ELi_SetResultCode( ELDesc* elElfDesc, ELObject* MYObject, ELResult result)
1352 {
1353 if( elElfDesc != NULL) {
1354 elElfDesc->result = (u32)result;
1355 }
1356 if( MYObject != NULL) {
1357 MYObject->result = (u32)result;
1358 }
1359 }
1360
ELi_SetProcCode(ELDesc * elElfDesc,ELObject * MYObject,ELProcess process)1361 void ELi_SetProcCode( ELDesc* elElfDesc, ELObject* MYObject, ELProcess process)
1362 {
1363 if( elElfDesc != NULL) {
1364 elElfDesc->process = (u32)process;
1365 }
1366 if( MYObject != NULL) {
1367 MYObject->process = (u32)process;
1368 }
1369 }
1370