1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - ELF Loader
3 File: elf_loader.c
4
5 Copyright 2006-2009 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:: 2009-06-04#$
14 $Rev: 10698 $
15 $Author: okubata_ryoma $
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 buf_size, 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 // Deallocate 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 /*--- Memory allocation relationship settings ---*/
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 default 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 default 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,u32 buf_size)299 ELDlld EL_LoadLibraryfromFile( ELDesc* elElfDesc, const char* FilePath, void* buf, u32 buf_size)
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, buf_size, 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 that reads OBJ or archive files
354 buf: Buffer for loading
355 -----------------------------------------------------*/
EL_LoadLibrary(ELDesc * elElfDesc,ELReadImage readfunc,u32 len,void * buf,u32 buf_size)356 ELDlld EL_LoadLibrary( ELDesc* elElfDesc, ELReadImage readfunc, u32 len, void* buf, u32 buf_size)
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, buf_size, 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 for OBJ file or archive file
384 buf: Buffer for loading
385 -----------------------------------------------------*/
EL_LoadLibraryfromMem(ELDesc * elElfDesc,void * obj_image,u32 obj_len,void * buf,u32 buf_size)386 ELDlld EL_LoadLibraryfromMem( ELDesc* elElfDesc, void* obj_image, u32 obj_len, void* buf, u32 buf_size)
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, buf_size, 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 for OBJ file or archive file
415 buf: Buffer for loading
416 -----------------------------------------------------*/
ELi_LoadLibrary(ELDesc * elElfDesc,void * obj_image,u32 obj_len,void * buf,u32 buf_size,u32 dll_fileid)417 static ELDlld ELi_LoadLibrary( ELDesc* elElfDesc, void* obj_image, u32 obj_len, void* buf, u32 buf_size, 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 /* Set the boundary address for checking buffers */
447 if( buf_size > (0xFFFFFFFF - (u32)buf)) {
448 MYObject->buf_limit_addr = 0xFFFFFFFF;
449 }else{
450 MYObject->buf_limit_addr = ((u32)buf + buf_size);
451 }
452
453 if( elElfDesc->i_elReadStub( OBJMAG, elElfDesc->FileStruct, (u32)obj_image, 0, 8) == FALSE) { /*Get the OBJ string*/
454 ELi_SetResultCode( elElfDesc, MYObject, EL_RESULT_CANNOT_ACCESS_ELF);
455 return( 0);
456 }
457 /*--------------- For archive files ---------------*/
458 if( OSAPI_STRNCMP( OBJMAG, ARMAG, 8) == 0) {
459 arch_size = sizeof( ArchHdr);
460 image_pointer += 8; /*To first entry*/
461
462 while( image_pointer < obj_len) {
463 if( elElfDesc->i_elReadStub( OBJMAG, elElfDesc->FileStruct, (u32)(obj_image), (image_pointer+arch_size), 4)
464 == FALSE) { /*Get the OBJ string*/
465 ELi_SetResultCode( elElfDesc, MYObject, EL_RESULT_CANNOT_ACCESS_ELF);
466 break;
467 }
468 if( OSAPI_STRNCMP( OBJMAG, ELFMAG, 4) == 0) {
469 /*Reset initial values*/
470 (void)ELi_ReInitDesc( elElfDesc);
471 result = ELi_LoadObject( elElfDesc, MYObject, (void*)(image_pointer+arch_size), MYObject->buf_current, dll_fileid, elf_num);
472 if( result != EL_RESULT_SUCCESS) {
473 break;
474 }
475 elf_num++;
476 }else{
477 }
478 /*To next entry*/
479 if( elElfDesc->i_elReadStub( &ArHdr, elElfDesc->FileStruct, (u32)(obj_image), image_pointer, arch_size)
480 == FALSE) {
481 ELi_SetResultCode( elElfDesc, MYObject, EL_RESULT_CANNOT_ACCESS_ELF);
482 return( 0);
483 }
484 image_pointer += arch_size + AR_GetEntrySize( &ArHdr);
485 }
486 }else{/*--------------- For ELF files ---------------*/
487 if( OSAPI_STRNCMP( OBJMAG, ELFMAG, 4) == 0) {
488 /*Reset initial values*/
489 (void)ELi_ReInitDesc( elElfDesc);
490 result = ELi_LoadObject( elElfDesc, MYObject, 0, MYObject->buf_current, dll_fileid, elf_num);
491 if( result != EL_RESULT_SUCCESS) {
492 }else{
493 elf_num++;
494 }
495 }else{
496 ELi_SetResultCode( elElfDesc, MYObject, EL_RESULT_INVALID_ELF);
497 }
498 }
499 /*-------------------------------------------------------*/
500
501 if( elf_num) {
502 if( OS_IsRunOnDebugger() == FALSE) {
503 (void)ELi_FreeVenTbl( elElfDesc, MYObject); /*Release the veneer link list when not debugging*/
504 }
505 MYObject->stat = elf_num;
506 //When (MEMO)Segment was loaded, buf_current was not advanced, so it was not applied to lib_size
507 MYObject->lib_size = ((u32)(MYObject->buf_current)) - ((u32)(MYObject->lib_start));
508 PRINTDEBUG( "library size : 0x%x\n", MYObject->lib_size);
509 return( (ELDlld)MYObject);
510 }else{
511 /* Object could not be processed so structure was destroyed */
512 (void)elRemoveObjEntry( &(elElfDesc->ELObjectStart), MYObject);
513 return 0; //NULL
514 }
515 }
516
517 /*------------------------------------------------------
518 Relocate ELF object to buffer
519
520 elElfDesc: Header structure
521 MYObject: Individual object management structure
522 obj_offset: Offset from image address on object file RAM
523 buf: Buffer to load (TODO: Buffer overflow countermeasure)
524 -----------------------------------------------------*/
ELi_LoadObject(ELDesc * elElfDesc,ELObject * MYObject,void * obj_offset,void * buf,u32 dll_fileid,u32 elf_num)525 static ELResult ELi_LoadObject( ELDesc* elElfDesc, ELObject* MYObject, void* obj_offset, void* buf, u32 dll_fileid, u32 elf_num)
526 {
527 ELResult ret_val;
528
529 /* Check initialization of ELDesc */
530 if( elElfDesc->process != (u32)EL_PROC_INITIALIZED) {
531 return( EL_RESULT_FAILURE);
532 }
533 /* Get ELF header */
534 if( elElfDesc->i_elReadStub( &(elElfDesc->CurrentEhdr), elElfDesc->FileStruct,
535 (u32)(elElfDesc->ar_head), (u32)(obj_offset), sizeof( Elf32_Ehdr))
536 == FALSE) {
537 ELi_SetResultCode( elElfDesc, MYObject, EL_RESULT_CANNOT_ACCESS_ELF);
538 return( EL_RESULT_CANNOT_ACCESS_ELF);
539 }
540
541 /* Build ELDesc structure */
542 elElfDesc->elf_offset = obj_offset;
543 elElfDesc->shentsize = elElfDesc->CurrentEhdr.e_shentsize;
544 elElfDesc->entry_adr = elElfDesc->CurrentEhdr.e_entry;
545
546 /* Process for each ELF file type */
547 switch( elElfDesc->CurrentEhdr.e_type) {
548
549 case ET_NONE:
550 PRINTDEBUG( "ERROR : Elf type \"ET_NONE\"\n");
551 ELi_SetResultCode( elElfDesc, MYObject, EL_RESULT_UNSUPPORTED_ELF);
552 ret_val = EL_RESULT_UNSUPPORTED_ELF;
553 break;
554
555 case ET_REL: /* X to execute; O to relocate */
556 PRINTDEBUG( "Elf type \"ET_REL\"\n");
557 if( buf == NULL) { /* Buffer NULL check */
558 ELi_SetResultCode( elElfDesc, MYObject, EL_RESULT_NO_MORE_RESOURCE);
559 return EL_RESULT_NO_MORE_RESOURCE;
560 }
561 ret_val = elLoadSections( elElfDesc, MYObject, dll_fileid, elf_num);
562 break;
563
564 case ET_EXEC: /* O to execute; X to relocate */
565 PRINTDEBUG( "Elf type \"ET_EXEC\"\n");
566 ret_val = elLoadSegments( elElfDesc, MYObject);
567 break;
568
569 case ET_DYN: /* O to execute; O to relocate (TODO: untested)*/
570 PRINTDEBUG( "Elf type \"ET_DYN\"\n");
571 if( buf == NULL) { //Handle as ET_EXEC when the load address is not specified
572 ret_val = elLoadSegments( elElfDesc, MYObject);
573 }else{ //Handle as ET_REL when the load address is not specified
574 ret_val = elLoadSections( elElfDesc, MYObject, dll_fileid, elf_num);
575 }
576 break;
577
578 case ET_CORE:
579 PRINTDEBUG( "ERROR : Elf type \"ET_CORE\"\n");
580 ELi_SetResultCode( elElfDesc, MYObject, EL_RESULT_UNSUPPORTED_ELF);
581 ret_val = EL_RESULT_UNSUPPORTED_ELF;
582 break;
583
584 default:
585 PRINTDEBUG( "ERROR : Invalid Elf type 0x%x\n",
586 elElfDesc->CurrentEhdr.e_type);
587 ELi_SetResultCode( elElfDesc, MYObject, EL_RESULT_INVALID_ELF);
588 ret_val = EL_RESULT_INVALID_ELF;
589 break;
590 }
591
592 return( ret_val);
593 }
594
595
596 /*------------------------------------------------------
597 Check and copy all segments
598
599 elElfDesc: Header structure
600 -----------------------------------------------------*/
elLoadSegments(ELDesc * elElfDesc,ELObject * MYObject)601 static ELResult elLoadSegments( ELDesc* elElfDesc, ELObject* MYObject)
602 {
603 u16 i;
604 //u32 load_start;
605 Elf32_Phdr CurrentPhdr;
606
607 for( i=0; i<(elElfDesc->CurrentEhdr.e_phnum); i++) {
608 /*Copy program header*/
609 ELi_GetPhdr( elElfDesc, i, &CurrentPhdr);
610
611 if( CurrentPhdr.p_type == PT_LOAD) {
612 /*If loadable segment, load to memory*/
613 if( ELi_CopySegmentToBuffer( elElfDesc, MYObject, &CurrentPhdr) == NULL) {
614 return( EL_RESULT_CANNOT_ACCESS_ELF);
615 }
616 }else{
617 PRINTDEBUG( "WARNING : skip segment (type = 0x%x)\n",
618 CurrentPhdr.p_type);
619 }
620 }
621 ELi_SetProcCode( elElfDesc, MYObject, EL_PROC_COPIED);
622 return( EL_RESULT_SUCCESS);
623 }
624
625
626 /*------------------------------------------------------
627 Check and copy all sections
628
629 elElfDesc: Header structure
630 -----------------------------------------------------*/
elLoadSections(ELDesc * elElfDesc,ELObject * MYObject,u32 dll_fileid,u32 elf_num)631 static ELResult elLoadSections( ELDesc* elElfDesc, ELObject* MYObject, u32 dll_fileid, u32 elf_num)
632 {
633 u16 i;
634 ELShdrEx* FwdShdrEx;
635 ELShdrEx* CurrentShdrEx;
636 ELShdrEx* InfoShdrEx; //For example, consider CurrentShdrEx as .text for rel.text
637 ELShdrEx DmyShdrEx;
638 #if (DEBUG_PRINT_ON == 1)
639 u16 j;
640 u32 num_of_entry;
641 char sym_str[128]; //For debug print
642 u32 offset; //For debug print
643 #endif
644
645 /*---------- Create ELShdrEx List ----------*/
646 CurrentShdrEx = &DmyShdrEx;
647 for( i=0; i<(elElfDesc->CurrentEhdr.e_shnum); i++) {
648 CurrentShdrEx->next = ELi_Malloc( elElfDesc, MYObject, sizeof(ELShdrEx));
649 if(CurrentShdrEx->next == NULL) {
650 return( EL_RESULT_NO_MORE_RESOURCE);
651 }
652 CurrentShdrEx = (ELShdrEx*)(CurrentShdrEx->next);
653 OSAPI_CPUFILL8( CurrentShdrEx, 0, sizeof(ELShdrEx)); //Clear zero
654
655 /*Set flag to distinguish whether this is debugging information*/
656 if( ELi_ShdrIsDebug( elElfDesc, i) == TRUE) { /*When it is debugging information*/
657 CurrentShdrEx->debug_flag = 1;
658 }else{ /*When not debugging information*/
659 /*Copy section header*/
660 ELi_GetShdr( elElfDesc, i, &(CurrentShdrEx->Shdr));
661 CurrentShdrEx->debug_flag = 0;
662 }
663 }
664 CurrentShdrEx->next = NULL;
665 elElfDesc->ShdrEx = DmyShdrEx.next;
666 /*--------------------------------------------*/
667
668 ELi_START_REGISTER_RELOCATION_INFO( ISTDRELOCATIONPROC_AUTO, (elElfDesc != i_eldesc_sim));
669
670 /*---------- Check and copy all sections ----------*/
671 PRINTDEBUG( "\nLoad to RAM:\n");
672 for( i=0; i<(elElfDesc->CurrentEhdr.e_shnum); i++) {
673 /**/
674 CurrentShdrEx = ELi_GetShdrExfromList( elElfDesc->ShdrEx, i);
675 // PRINTDEBUG( "section:%d sh_flag=0x%x\n", i, CurrentShdrEx->Shdr.sh_flags);
676 // PRINTDEBUG( "section:%d sh_type=0x%x\n", i, CurrentShdrEx->Shdr.sh_type);
677
678 if( CurrentShdrEx->debug_flag == 1) { /*When it is debugging information*/
679 PRINTDEBUG( "skip debug-section %02x\n", i);
680 }else{ /*When not debugging information*/
681 BOOL bLocate = FALSE;
682
683 /* .text section */
684 if( (CurrentShdrEx->Shdr.sh_flags == (SHF_ALLOC | SHF_EXECINSTR))&&
685 (CurrentShdrEx->Shdr.sh_type == SHT_PROGBITS)) {
686 //Copy to memory
687 CurrentShdrEx->loaded_adr = (u32)
688 ELi_CopySectionToBuffer( elElfDesc, MYObject, &(CurrentShdrEx->Shdr));
689 bLocate = TRUE;
690 }
691 /* .data, .data1 section (Initialized data) */
692 else if( (CurrentShdrEx->Shdr.sh_flags == (SHF_ALLOC | SHF_WRITE))&&
693 (CurrentShdrEx->Shdr.sh_type == SHT_PROGBITS)) {
694 //Copy to memory
695 CurrentShdrEx->loaded_adr = (u32)
696 ELi_CopySectionToBuffer( elElfDesc, MYObject, &(CurrentShdrEx->Shdr));
697 bLocate = TRUE;
698 }
699 /* bss section */
700 else if( (CurrentShdrEx->Shdr.sh_flags == (SHF_ALLOC | SHF_WRITE))&&
701 (CurrentShdrEx->Shdr.sh_type == SHT_NOBITS)) {
702 //Do not copy
703 CurrentShdrEx->loaded_adr = (u32)
704 ELi_AllocSectionToBuffer( elElfDesc, MYObject, &(CurrentShdrEx->Shdr));
705 bLocate = TRUE;
706 }
707 /* .rodata, .rodata1 section */
708 else if( (CurrentShdrEx->Shdr.sh_flags == SHF_ALLOC)&&
709 (CurrentShdrEx->Shdr.sh_type == SHT_PROGBITS)) {
710 //Copy to memory
711 CurrentShdrEx->loaded_adr = (u32)
712 ELi_CopySectionToBuffer( elElfDesc, MYObject, &(CurrentShdrEx->Shdr));
713 bLocate = TRUE;
714 }
715
716 if (bLocate) {
717 if( CurrentShdrEx->loaded_adr == NULL) { //When failed in ELi_CopySectionToBuffer
718 ELi_END_REGISTER_RELOCATION_INFO( ISTDRELOCATIONPROC_AUTO, (elElfDesc != i_eldesc_sim));
719 return( EL_RESULT_CANNOT_ACCESS_ELF);
720 }
721 (void)ELi_REGISTER_RELOCATION_INFO( ISTDRELOCATIONPROC_AUTO, dll_fileid, elf_num, i, CurrentShdrEx->loaded_adr, (elElfDesc != i_eldesc_sim));
722 }
723
724 PRINTDEBUG( "section %02x relocated at %08x\n",
725 i, CurrentShdrEx->loaded_adr);
726 }
727 }
728 /* After copy ends */
729 ELi_SetProcCode( elElfDesc, MYObject, EL_PROC_COPIED);
730 /*----------------------------------------------------*/
731
732 ELi_END_REGISTER_RELOCATION_INFO( ISTDRELOCATIONPROC_AUTO, (elElfDesc != i_eldesc_sim));
733
734 /*---------- Publication of global symbols and relocating of local symbols ----------*/
735 PRINTDEBUG( "\nRelocate Symbols:\n");
736 for( i=0; i<(elElfDesc->CurrentEhdr.e_shnum); i++) {
737 /**/
738 CurrentShdrEx = ELi_GetShdrExfromList( elElfDesc->ShdrEx, i);
739
740 if( CurrentShdrEx->debug_flag == 1) { /*When it is debugging information*/
741 }else{ /*When not debugging information*/
742
743 if( CurrentShdrEx->Shdr.sh_type == SHT_REL) {
744 /*Relocate*/
745 InfoShdrEx = ELi_GetShdrExfromList( elElfDesc->ShdrEx,
746 CurrentShdrEx->Shdr.sh_info);
747 if( InfoShdrEx->loaded_adr != 0) { //Relocate internally if targeted section is loaded
748 if(ELi_RelocateSym( elElfDesc, MYObject, i) == FALSE)
749 return( (ELResult)(elElfDesc->result)); //EL_RESULT_NO_MORE_RESOURCE or EL_RESULT_UNSUPPORTED_ELF
750 }
751 #if (DEBUG_PRINT_ON == 1)
752 num_of_entry = (CurrentShdrEx->Shdr.sh_size) /
753 (CurrentShdrEx->Shdr.sh_entsize);
754
755 PRINTDEBUG( "num of REL = %x\n", num_of_entry);
756 PRINTDEBUG( "Section Header Info.\n");
757 PRINTDEBUG( "link : %x\n", CurrentShdrEx->Shdr.sh_link);
758 PRINTDEBUG( "info : %x\n", CurrentShdrEx->Shdr.sh_info);
759 PRINTDEBUG( " Offset Info Type Sym.Value Sym.Name\n");
760 offset = 0;
761 for( j=0; j<num_of_entry; j++) {
762 ELi_GetSent( elElfDesc, i, &(elElfDesc->Rel), offset, sizeof(Elf32_Rel));
763 ELi_GetShdr( elElfDesc, CurrentShdrEx->Shdr.sh_link, &(elElfDesc->SymShdr));
764 ELi_GetSent( elElfDesc, CurrentShdrEx->Shdr.sh_link, &(elElfDesc->Sym),
765 (u32)(elElfDesc->SymShdr.sh_entsize * ELF32_R_SYM( elElfDesc->Rel.r_info)), sizeof(Elf32_Sym));
766 ELi_GetStrAdr( elElfDesc, elElfDesc->SymShdr.sh_link, elElfDesc->Sym.st_name, sym_str, 128);
767
768 PRINTDEBUG( "%08x ", elElfDesc->Rel.r_offset);
769 PRINTDEBUG( "%08x ", elElfDesc->Rel.r_info);
770 PRINTDEBUG( " ");
771 PRINTDEBUG( "%08x ", elElfDesc->Sym.st_value);
772 PRINTDEBUG( sym_str);
773 PRINTDEBUG( "\n");
774 /*To next entry*/
775 offset += (u32)(CurrentShdrEx->Shdr.sh_entsize);
776 }
777 #endif
778 }
779 else if( CurrentShdrEx->Shdr.sh_type == SHT_RELA) {
780 /*Relocate*/
781 InfoShdrEx = ELi_GetShdrExfromList( elElfDesc->ShdrEx,
782 CurrentShdrEx->Shdr.sh_info);
783 if( InfoShdrEx->loaded_adr != 0) { //Relocate internally if targeted section is loaded
784 if(ELi_RelocateSym( elElfDesc, MYObject, i) == FALSE)
785 return( EL_RESULT_NO_MORE_RESOURCE);
786 }
787
788 #if (DEBUG_PRINT_ON == 1)
789 num_of_entry = (CurrentShdrEx->Shdr.sh_size) /
790 (CurrentShdrEx->Shdr.sh_entsize);
791 PRINTDEBUG( "num of RELA = %x\n", num_of_entry);
792 PRINTDEBUG( "Section Header Info.\n");
793 PRINTDEBUG( "link : %x\n", CurrentShdrEx->Shdr.sh_link);
794 PRINTDEBUG( "info : %x\n", CurrentShdrEx->Shdr.sh_info);
795 PRINTDEBUG( " Offset Info Type Sym.Value Sym.Name\n");
796 offset = 0;
797 for( j=0; j<num_of_entry; j++) {
798 ELi_GetSent( elElfDesc, i, &(elElfDesc->Rela), offset, sizeof(Elf32_Rel));
799 ELi_GetShdr( elElfDesc, CurrentShdrEx->Shdr.sh_link, &(elElfDesc->SymShdr));
800 ELi_GetSent( elElfDesc, CurrentShdrEx->Shdr.sh_link, &(elElfDesc->Sym),
801 (u32)(elElfDesc->SymShdr.sh_entsize * ELF32_R_SYM( elElfDesc->Rela.r_info)), sizeof(Elf32_Sym));
802 ELi_GetStrAdr( elElfDesc, elElfDesc->SymShdr.sh_link, elElfDesc->Sym.st_name, sym_str, 128);
803
804 PRINTDEBUG( "%08x ", elElfDesc->Rela.r_offset);
805 PRINTDEBUG( "%08x ", elElfDesc->Rela.r_info);
806 PRINTDEBUG( " ");
807 PRINTDEBUG( "%08x ", elElfDesc->Sym.st_value);
808 PRINTDEBUG( sym_str);
809 PRINTDEBUG( "\n");
810 /*To next entry*/
811 offset += (u32)(CurrentShdrEx->Shdr.sh_entsize);
812 }
813 #endif
814 }
815 else if( CurrentShdrEx->Shdr.sh_type == SHT_SYMTAB) {
816 /*Register global symbol in address table*/
817 if(ELi_GoPublicGlobalSym( elElfDesc, MYObject, i) == FALSE)
818 return( EL_RESULT_NO_MORE_RESOURCE);
819 }
820 }
821 }
822 /*Create in ELi_RelocateSym and ELi_GoPublicGlobalSym and release the used symbol list*/
823 ELi_FreeSymList( elElfDesc);
824
825 /*---------- Deallocate the ELShdrEx List ----------*/
826 CurrentShdrEx = elElfDesc->ShdrEx;
827 if( CurrentShdrEx) {
828 do {
829 FwdShdrEx = CurrentShdrEx;
830 CurrentShdrEx = CurrentShdrEx->next;
831 OSAPI_FREE( FwdShdrEx);
832 }while( CurrentShdrEx != NULL);
833 elElfDesc->ShdrEx = NULL;
834 }
835 /*-----------------------------------------*/
836
837 /*Flush cache before DLL is called on RAM*/
838 #if (TARGET_ARM_V5 == 1)
839 OSAPI_FLUSHCACHEALL();
840 OSAPI_WAITCACHEBUF();
841 #endif
842
843 return( EL_RESULT_SUCCESS);
844 }
845
846 /*------------------------------------------------------
847 Resolve unresolved symbols using the address table
848 -----------------------------------------------------*/
ELi_ResolveAllLibrary(ELDesc * elElfDesc)849 ELProcess ELi_ResolveAllLibrary( ELDesc* elElfDesc)
850 {
851 ELAdrEntry* AdrEnt;
852 ELImportEntry* UnrEnt;
853 ELImportEntry* NextEnt;
854 // ELImportEntry* CurrentUnrEnt;
855 // ELImportEntry* FwdUnrEnt;
856 ELObject* ObjEnt;
857 ELObject* ExpObjEnt;
858 BOOL ret_val;
859
860 if( elElfDesc == NULL) {
861 return( EL_PROC_NOTHING);
862 }
863 ObjEnt = elElfDesc->ELObjectStart;
864 if( (ObjEnt == NULL)||((ObjEnt == elElfDesc->ELStaticObj)&&(ObjEnt->next == NULL))) {
865 return( EL_PROC_NOTHING); /* If there is no DLL */
866 }
867 while( ObjEnt != NULL) {
868 UnrEnt = (ELImportEntry*)ObjEnt->UnresolvedImportAdrEnt;
869 PRINTDEBUG( "\nResolve all symbols:\n");
870 while( UnrEnt != NULL) {
871 NextEnt = UnrEnt->next;
872 AdrEnt = elGetAdrEntry( elElfDesc, UnrEnt->sym_str, &ExpObjEnt); /*Search from address table*/
873 if( AdrEnt) { /*When found in address table*/
874 UnrEnt->S_ = (u32)(AdrEnt->adr);
875 UnrEnt->T_ = (u32)(AdrEnt->thumb_flag);
876 PRINTDEBUG( "\n symbol found %s : %8x\n", UnrEnt->sym_str, UnrEnt->S_);
877 ret_val = ELi_DoRelocate( elElfDesc, ObjEnt, UnrEnt); /*Resolve symbol*/
878 if( ret_val == FALSE) {
879 return( (ELProcess)(ObjEnt->process)); //Should be EL_PROC_COPIED. Is osPanic better? TODO: continuation
880 }else{
881 PRINTDEBUG( "%s ... ObjEnt:0x%x, ExpObjEnt:0x%x\n", UnrEnt->sym_str, ObjEnt, ExpObjEnt);
882 UnrEnt->Dlld = (struct ELObject*)ExpObjEnt; /*Register ObjEnt referenced in resolution*/
883 /* Change link from Unresolved to Resolved */
884 (void)ELi_ExtractImportEntry( &(ObjEnt->UnresolvedImportAdrEnt), UnrEnt);
885 ELi_AddImportEntry( &(ObjEnt->ResolvedImportAdrEnt), UnrEnt);
886 }
887 }else{ /*When not found in address table*/
888 if( elElfDesc != i_eldesc_sim) {
889 PRINTDEBUG( "\n ERROR! cannot find symbol : %s\n\n", UnrEnt->sym_str);
890 return( (ELProcess)(ObjEnt->process)); //Should be EL_PROC_COPIED. Is osPanic better? TODO: Continue
891 }
892 /*----- For simulation, assume it was forcefully resolved -----*/
893 UnrEnt->S_ = (u32)0;
894 UnrEnt->T_ = (u32)0;
895 ret_val = ELi_DoRelocate( elElfDesc, ObjEnt, UnrEnt);
896 UnrEnt->Dlld = (struct ELObject*)NULL; /*Register ObjEnt referenced in resolution*/
897 /* Change link from Unresolved to Resolved */
898 (void)ELi_ExtractImportEntry( &(ObjEnt->UnresolvedImportAdrEnt), UnrEnt);
899 ELi_AddImportEntry( &(ObjEnt->ResolvedImportAdrEnt), UnrEnt);
900 /*--------------------------------------------------------*/
901 }
902 UnrEnt = NextEnt; /*To next unresolved entry*/
903 }
904 ELi_SetProcCode( NULL, ObjEnt, EL_PROC_RELOCATED);
905 ObjEnt->lib_size = ((u32)(ObjEnt->buf_current)) - ((u32)(ObjEnt->lib_start)); //There is the possibility that veneer was added, so update the size
906 ObjEnt = ObjEnt->next;
907 }
908 ELi_SetProcCode( elElfDesc, NULL, EL_PROC_RELOCATED);
909
910 /*TODO: When fixed, only the UnrEnt entry that could not be resolved here should be deleted*/
911 #if 0
912 /*---------- Deallocate the ELImportEntry List ----------*/
913 ELi_FreeImportTbl( &ELUnrEntStart);
914 /*-------------------------------------------*/
915 #endif
916 /*Deallocate the veneer link request*/
917 // (void)ELi_FreeVenTbl();
918
919 /*Flush cache before DLL is called on RAM*/
920 #if (TARGET_ARM_V5 == 1)
921 OSAPI_FLUSHCACHEALL();
922 OSAPI_WAITCACHEBUF();
923 #endif
924
925 return EL_PROC_RELOCATED;
926 }
927
928
929 /*------------------------------------------------------
930 Unlink the object
931 -----------------------------------------------------*/
ELi_Unlink(ELDesc * elElfDesc,ELDlld my_dlld)932 BOOL ELi_Unlink( ELDesc* elElfDesc, ELDlld my_dlld)
933 {
934 ELObject* MYObject;
935 ELObject* ObjEnt;
936 ELImportEntry* ResEnt;
937 ELImportEntry* NextEnt;
938 u32 file_id;
939
940 if( elElfDesc == NULL) {
941 return( FALSE);
942 }
943
944 if( my_dlld == 0) {
945 ELi_SetResultCode( elElfDesc, NULL, EL_RESULT_INVALID_PARAMETER);
946 return( FALSE);
947 }
948
949 /* Object to unlink */
950 MYObject = (ELObject*)my_dlld;
951
952 /* Get the file ID of the object to unlink */
953 file_id = MYObject->file_id;
954
955 #if 0
956 /* Hide all export information */
957 if( MYObject->ExportAdrEnt) {
958 MYObject->HiddenAdrEnt = MYObject->ExportAdrEnt;
959 MYObject->ExportAdrEnt = NULL;
960 }
961 #else
962 /* Clear all export information */
963 elFreeAdrTbl( &(MYObject->ExportAdrEnt));
964 #endif
965
966 /* Reference other objects and make the resolved portions unresolved */
967 ObjEnt = elElfDesc->ELObjectStart;
968 while( ObjEnt != NULL) {
969 ResEnt = ObjEnt->ResolvedImportAdrEnt;
970 while( ResEnt != NULL) {
971 NextEnt = ResEnt->next;
972 PRINTDEBUG( "Compare ObjEnt:0x%x, ExpObjEnt:0x%x\n", ResEnt->Dlld, MYObject);
973 if( ResEnt->Dlld == (struct ELObject*)MYObject) {
974 PRINTDEBUG( "Unlink from ObjEnt:0x%x, ExpObjEnt:0x%x\n", ObjEnt, MYObject);
975 /* Link from Resolved to Unresolved */
976 (void)ELi_ExtractImportEntry( &(ObjEnt->ResolvedImportAdrEnt), ResEnt);
977 ELi_AddImportEntry( &(ObjEnt->UnresolvedImportAdrEnt), ResEnt);
978 ResEnt->Dlld = NULL;
979 }
980 ResEnt = NextEnt;
981 }
982 ObjEnt = ObjEnt->next;
983 }
984
985 /*Do not destroy import information or self*/
986
987
988 /*Destroy the veneer table*/
989 (void)ELi_FreeVenTbl( elElfDesc, MYObject); /*Deallocate the veneer link request*/
990
991 ELi_SetProcCode( elElfDesc, MYObject, EL_PROC_NOTHING);
992
993 ELi_START_REGISTER_RELOCATION_INFO( ISTDRELOCATIONPROC_AUTO, (elElfDesc != i_eldesc_sim));
994 (void)ELi_UNREGISTER_RELOCATION_INFO( ISTDRELOCATIONPROC_AUTO, file_id, (elElfDesc != i_eldesc_sim));
995 ELi_END_REGISTER_RELOCATION_INFO( ISTDRELOCATIONPROC_AUTO, (elElfDesc != i_eldesc_sim));
996
997 return( TRUE);
998 }
999
1000
1001 /*------------------------------------------------------
1002 Deallocate all object lists
1003 -----------------------------------------------------*/
ELi_FreeObject(ELObject ** ELObjEntStart)1004 static void ELi_FreeObject( ELObject** ELObjEntStart)
1005 {
1006 ELObject* FwdObjEnt;
1007 ELObject* CurrentObjEnt;
1008
1009 /*---------- Deallocate the ELObject List ----------*/
1010 CurrentObjEnt = (*ELObjEntStart);
1011 if( CurrentObjEnt) {
1012 do {
1013 FwdObjEnt = CurrentObjEnt;
1014 CurrentObjEnt = CurrentObjEnt->next;
1015 /**/
1016 elFreeAdrTbl( &(FwdObjEnt->ExportAdrEnt));
1017 elFreeAdrTbl( &(FwdObjEnt->HiddenAdrEnt));
1018 ELi_FreeImportTbl( &(FwdObjEnt->ResolvedImportAdrEnt));
1019 ELi_FreeImportTbl( &(FwdObjEnt->UnresolvedImportAdrEnt));
1020 OSAPI_FREE( FwdObjEnt);
1021 }while( CurrentObjEnt != NULL);
1022 (*ELObjEntStart) = NULL;
1023 }
1024 /*----------------------------------*/
1025 }
1026
1027
1028 /*------------------------------------------------------
1029 Check whether there are unresolved external references remaining in the object
1030 -----------------------------------------------------*/
EL_IsResolved(ELDlld my_dlld)1031 BOOL EL_IsResolved( ELDlld my_dlld)
1032 {
1033 ELObject* MYObject;
1034
1035 if( my_dlld == 0) {
1036 return( FALSE);
1037 }
1038
1039 MYObject = (ELObject*)my_dlld;
1040 /*TODO: Check whether MYObject is linked to the list*/
1041 if( (MYObject->stat != 0)&&(MYObject->UnresolvedImportAdrEnt == NULL)) {
1042 return( TRUE);
1043 }else{
1044 return( FALSE);
1045 }
1046 }
1047
1048
1049 /*------------------------------------------------------
1050 Initializes the object management structure.
1051 -----------------------------------------------------*/
ELi_InitObject(ELObject * MYObject)1052 static void ELi_InitObject( ELObject* MYObject)
1053 {
1054 MYObject->next = NULL;
1055 MYObject->lib_size = 0;
1056 MYObject->ExportAdrEnt = NULL;
1057 MYObject->HiddenAdrEnt = NULL;
1058 MYObject->ResolvedImportAdrEnt = NULL;
1059 MYObject->UnresolvedImportAdrEnt = NULL;
1060 MYObject->ELVenEntStart = NULL;
1061 MYObject->ELV4tVenEntStart = NULL;
1062 MYObject->stat = 0;
1063
1064 MYObject->process = (u32)EL_PROC_INITIALIZED;
1065 MYObject->result = (u32)EL_RESULT_SUCCESS;
1066 }
1067
1068
1069 /*------------------------------------------------------
1070 Delete entry from the object table
1071 -----------------------------------------------------*/
elRemoveObjEntry(ELObject ** StartEnt,ELObject * ObjEnt)1072 BOOL elRemoveObjEntry( ELObject** StartEnt, ELObject* ObjEnt)
1073 {
1074 ELObject DmyObjEnt;
1075 ELObject* CurObjEnt;
1076
1077 DmyObjEnt.next = (*StartEnt);
1078 CurObjEnt = &DmyObjEnt;
1079
1080 while( CurObjEnt->next != ObjEnt) {
1081 if( CurObjEnt->next == NULL) {
1082 return FALSE;
1083 }else{
1084 CurObjEnt = (ELObject*)CurObjEnt->next;
1085 }
1086 }
1087
1088 /*Relink link list*/
1089 CurObjEnt->next = ObjEnt->next;
1090 (*StartEnt) = DmyObjEnt.next;
1091
1092 /*Deallocate*/
1093 elFreeAdrTbl( &(ObjEnt->ExportAdrEnt));
1094 elFreeAdrTbl( &(ObjEnt->HiddenAdrEnt));
1095 ELi_FreeImportTbl( &(ObjEnt->ResolvedImportAdrEnt));
1096 ELi_FreeImportTbl( &(ObjEnt->UnresolvedImportAdrEnt));
1097 ELi_InitObject( ObjEnt); //stat = 0;
1098 OSAPI_FREE( ObjEnt);
1099
1100 return TRUE;
1101 }
1102
1103 /*------------------------------------------------------
1104 Add entry to object table
1105 -----------------------------------------------------*/
elAddObjEntry(ELObject ** StartEnt,ELObject * ObjEnt)1106 static void elAddObjEntry( ELObject** StartEnt, ELObject* ObjEnt)
1107 {
1108 ELObject DmyObjEnt;
1109 ELObject* CurObjEnt;
1110
1111 if( (*StartEnt) == NULL) {
1112 (*StartEnt) = ObjEnt;
1113 }else{
1114 DmyObjEnt.next = (*StartEnt);
1115 CurObjEnt = &DmyObjEnt;
1116
1117 while( CurObjEnt->next != NULL) {
1118 CurObjEnt = (ELObject*)CurObjEnt->next;
1119 }
1120 CurObjEnt->next = (void*)ObjEnt;
1121 }
1122 ObjEnt->next = NULL;
1123 }
1124
1125
1126 /*------------------------------------------------------
1127 Delete entry from address table
1128 -----------------------------------------------------*/
1129 #if 0
1130 BOOL elRemoveAdrEntry( ELAdrEntry* AdrEnt)
1131 {
1132 ELAdrEntry DmyAdrEnt;
1133 ELAdrEntry* CurrentAdrEnt;
1134
1135 DmyAdrEnt.next = ELAdrEntStart;
1136 CurrentAdrEnt = &DmyAdrEnt;
1137
1138 while( CurrentAdrEnt->next != AdrEnt) {
1139 if( CurrentAdrEnt->next == NULL) {
1140 return FALSE;
1141 }else{
1142 CurrentAdrEnt = (ELAdrEntry*)CurrentAdrEnt->next;
1143 }
1144 }
1145
1146 /*Relink link list*/
1147 CurrentAdrEnt->next = AdrEnt->next;
1148 ELAdrEntStart = DmyAdrEnt.next;
1149
1150 /*Deallocate*/
1151 OSAPI_FREE( AdrEnt);
1152
1153 return TRUE;
1154 }
1155 #endif
1156
1157 /*------------------------------------------------------
1158 Add entry to address table
1159 -----------------------------------------------------*/
elAddAdrEntry(ELAdrEntry ** ELAdrEntStart,ELAdrEntry * AdrEnt)1160 void elAddAdrEntry( ELAdrEntry** ELAdrEntStart, ELAdrEntry* AdrEnt)
1161 {
1162 ELAdrEntry DmyAdrEnt;
1163 ELAdrEntry* CurrentAdrEnt;
1164
1165 if( (*ELAdrEntStart) == NULL) {
1166 (*ELAdrEntStart) = AdrEnt;
1167 }else{
1168 DmyAdrEnt.next = (*ELAdrEntStart);
1169 CurrentAdrEnt = &DmyAdrEnt;
1170
1171 while( CurrentAdrEnt->next != NULL) {
1172 CurrentAdrEnt = (ELAdrEntry*)CurrentAdrEnt->next;
1173 }
1174 CurrentAdrEnt->next = (void*)AdrEnt;
1175 }
1176 AdrEnt->next = NULL;
1177 }
1178
1179 /*------------------------------------------------------
1180 Add entry from application to address table
1181 -----------------------------------------------------*/
ELi_Export(ELDesc * elElfDesc,ELAdrEntry * AdrEnt)1182 BOOL ELi_Export( ELDesc* elElfDesc, ELAdrEntry* AdrEnt)
1183 {
1184 ELAdrEntry DmyAdrEnt;
1185 ELAdrEntry* CurrentAdrEnt;
1186
1187 if( elElfDesc == NULL) {
1188 return( FALSE);
1189 }
1190 if( elElfDesc->ELStaticObj == NULL) {
1191 elElfDesc->ELStaticObj = (ELObject*)ELi_Malloc( elElfDesc, NULL, sizeof( ELObject));
1192 if(elElfDesc->ELStaticObj == NULL) {
1193 return( FALSE);
1194 }
1195 ELi_InitObject( elElfDesc->ELStaticObj);
1196 elAddObjEntry( &(elElfDesc->ELObjectStart), elElfDesc->ELStaticObj);
1197 }
1198
1199 if( !(elElfDesc->ELStaticObj->ExportAdrEnt)) {
1200 elElfDesc->ELStaticObj->ExportAdrEnt = (ELAdrEntry*)AdrEnt;
1201 }else{
1202 DmyAdrEnt.next = (ELAdrEntry*)elElfDesc->ELStaticObj->ExportAdrEnt;
1203 CurrentAdrEnt = &DmyAdrEnt;
1204
1205 while( CurrentAdrEnt->next != NULL) {
1206 CurrentAdrEnt = (ELAdrEntry*)CurrentAdrEnt->next;
1207 }
1208 CurrentAdrEnt->next = (void*)AdrEnt;
1209 }
1210 AdrEnt->next = NULL;
1211 return( TRUE);
1212 }
1213
1214 /*------------------------------------------------------
1215 Add entry of static side to address table
1216 -----------------------------------------------------*/
1217 #ifndef SDK_TWL
EL_AddStaticSym(void)1218 SDK_WEAK_SYMBOL void EL_AddStaticSym( void)
1219 //__declspec(weak) void EL_AddStaticSym( void)
1220 #else
1221 SDK_WEAK_SYMBOL void EL_AddStaticSym( void)
1222 #endif
1223 {
1224 PRINTDEBUG( "please link file which is generated by \"makelst\".\n");
1225 while( 1) {};
1226 }
1227
1228 /*------------------------------------------------------
1229 Return entry corresponding to specified string from entire address table and set the object that is exporting that entry to the ExpObEnt
1230
1231 -----------------------------------------------------*/
elGetAdrEntry(ELDesc * elElfDesc,const char * ent_name,ELObject ** ExpObjEnt)1232 ELAdrEntry* elGetAdrEntry( ELDesc* elElfDesc, const char* ent_name, ELObject** ExpObjEnt)
1233 {
1234 ELObject* ObjEnt;
1235 ELAdrEntry* CurrentAdrEnt;
1236
1237 ObjEnt = elElfDesc->ELObjectStart;
1238 while( ObjEnt != NULL) {
1239 CurrentAdrEnt = ObjEnt->ExportAdrEnt;
1240 while( CurrentAdrEnt != NULL) {
1241 if( OSAPI_STRCMP( CurrentAdrEnt->name, ent_name) == 0) {
1242 (*ExpObjEnt) = ObjEnt; //Specify OBJ that is exporting
1243 goto get_end;
1244 }
1245 CurrentAdrEnt = (ELAdrEntry*)CurrentAdrEnt->next;
1246 }
1247 ObjEnt = ObjEnt->next;
1248 }
1249 (*ExpObjEnt) = NULL; //Nobody is exporting
1250 get_end:
1251 return CurrentAdrEnt;
1252 }
1253
1254 /*------------------------------------------------------
1255 Return address corresponding to specified string in address table
1256 -----------------------------------------------------*/
ELi_GetGlobalAdr(ELDesc * elElfDesc,ELDlld my_dlld,const char * ent_name)1257 void* ELi_GetGlobalAdr( ELDesc* elElfDesc, ELDlld my_dlld, const char* ent_name)
1258 {
1259 u32 adr;
1260 ELAdrEntry* CurrentAdrEnt;
1261 ELObject* DmyObjEnt;
1262
1263 if( elElfDesc == NULL) {
1264 return( 0);
1265 }
1266
1267 if( my_dlld == 0) { /*Search from entirety*/
1268 CurrentAdrEnt = elGetAdrEntry( elElfDesc, ent_name, &DmyObjEnt);
1269 }else{ /*Search from specific objects*/
1270 CurrentAdrEnt = ((ELObject*)my_dlld)->ExportAdrEnt;
1271 while( CurrentAdrEnt != NULL) {
1272 if( OSAPI_STRCMP( CurrentAdrEnt->name, ent_name) == 0) {
1273 break;
1274 }
1275 CurrentAdrEnt = (ELAdrEntry*)CurrentAdrEnt->next;
1276 }
1277 }
1278
1279 if( CurrentAdrEnt) {
1280 if( CurrentAdrEnt->thumb_flag) { //TODO: only for func_flag
1281 adr = (u32)(CurrentAdrEnt->adr) + 1;
1282 }else{
1283 adr = (u32)(CurrentAdrEnt->adr);
1284 }
1285 }else{
1286 adr = 0;
1287 }
1288
1289 return (void*)(adr);
1290 }
1291
1292
1293 /*------------------------------------------------------
1294 Deallocate all address tables
1295 -----------------------------------------------------*/
elFreeAdrTbl(ELAdrEntry ** ELAdrEntStart)1296 static void elFreeAdrTbl( ELAdrEntry** ELAdrEntStart)
1297 {
1298 ELAdrEntry* FwdAdrEnt;
1299 ELAdrEntry* CurrentAdrEnt;
1300
1301 /*---------- Deallocate the ELAdrEntry List ----------*/
1302 CurrentAdrEnt = (*ELAdrEntStart);
1303 if( CurrentAdrEnt) {
1304 do {
1305 FwdAdrEnt = CurrentAdrEnt;
1306 CurrentAdrEnt = CurrentAdrEnt->next;
1307 OSAPI_FREE( FwdAdrEnt->name); //Symbol name character-string
1308 OSAPI_FREE( FwdAdrEnt); //Structure itself
1309 }while( CurrentAdrEnt != NULL);
1310 (*ELAdrEntStart) = NULL;
1311 }
1312 /*------------------------------------*/
1313 }
1314
1315
1316 /*------------------------------------------------------
1317 Stub that reads data from the ELF object
1318 -----------------------------------------------------*/
ELi_ReadFile(void * buf,void * file_struct,u32 file_base,u32 file_offset,u32 size)1319 static BOOL ELi_ReadFile( void* buf, void* file_struct, u32 file_base, u32 file_offset, u32 size)
1320 {
1321 #pragma unused( file_base)
1322 if( FS_SeekFile( file_struct, (s32)(file_offset), FS_SEEK_SET) == FALSE) {
1323 return( FALSE);
1324 }
1325 if( FS_ReadFile( file_struct, buf, (s32)(size)) == (s32)size) {
1326 return( TRUE);
1327 }else{
1328 return( FALSE);
1329 }
1330 }
1331
ELi_ReadMem(void * buf,void * file_struct,u32 file_base,u32 file_offset,u32 size)1332 static BOOL ELi_ReadMem( void* buf, void* file_struct, u32 file_base, u32 file_offset, u32 size)
1333 {
1334 #pragma unused(file_struct)
1335 OSAPI_CPUCOPY8( (void*)(file_base + file_offset),
1336 buf,
1337 size);
1338 return( TRUE);
1339 }
1340
ELi_ReadUsr(void * buf,void * file_struct,u32 file_base,u32 file_offset,u32 size)1341 static BOOL ELi_ReadUsr( void* buf, void* file_struct, u32 file_base, u32 file_offset, u32 size)
1342 {
1343 #pragma unused(file_struct)
1344 #pragma unused(file_base)
1345 if( i_elReadImage( file_offset, buf, size) == 0) {
1346 return( TRUE);
1347 }
1348 return( FALSE);
1349 }
1350
1351
1352 /*------------------------------------------------------
1353 Set of error codes/process codes
1354 Set ELResult when initial value is SUCCESS and an error occurs
1355 Set ELProcess when the initial value is INITIALIZED and in conjunction with progress
1356 -----------------------------------------------------*/
ELi_SetResultCode(ELDesc * elElfDesc,ELObject * MYObject,ELResult result)1357 void ELi_SetResultCode( ELDesc* elElfDesc, ELObject* MYObject, ELResult result)
1358 {
1359 if( elElfDesc != NULL) {
1360 elElfDesc->result = (u32)result;
1361 }
1362 if( MYObject != NULL) {
1363 MYObject->result = (u32)result;
1364 }
1365 }
1366
ELi_SetProcCode(ELDesc * elElfDesc,ELObject * MYObject,ELProcess process)1367 void ELi_SetProcCode( ELDesc* elElfDesc, ELObject* MYObject, ELProcess process)
1368 {
1369 if( elElfDesc != NULL) {
1370 elElfDesc->process = (u32)process;
1371 }
1372 if( MYObject != NULL) {
1373 MYObject->process = (u32)process;
1374 }
1375 }
1376