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