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