bintools/elftools/elftran/elf_dlld.cpp
changeset 590 360bd6b35136
parent 0 044383f39525
equal deleted inserted replaced
588:c7c26511138f 590:360bd6b35136
    18 
    18 
    19 
    19 
    20 #include <string.h>
    20 #include <string.h>
    21 #include <stdlib.h>
    21 #include <stdlib.h>
    22 #include <e32std.h>
    22 #include <e32std.h>
    23 #include <elfdefs.h>
    23 #include "elfdefs.h"
    24 #include "elfdll.h"
    24 #include "elfdll.h"
    25 #include "elffile.h"
    25 #include "elffile.h"
    26 #include <h_utl.h>
    26 #include "h_utl.h"
    27 #include <e32ldr.h>
    27 #include <e32ldr.h>
    28 
    28 
    29 ELFFile::ELFDllData::ELFDllData(ELFFile * f)
    29 ELFFile::ELFDllData::ELFDllData(ELFFile * f) :
    30     :
    30          iElfFile(f), iDynStrTab(0), iDynStrTabSize(0), iDynSymTab(0),
    31         iElfFile(f),
    31  		iSymSize(0), iRela(0), iRelaSz(0), iRelaEnt(0), 
    32 
    32  		iRel(0), iRelSz(0), iRelEnt(0),
    33         iDynStrTab(0),
    33  		iHashTable(0), iNamedExportSymbolHead(0),  iNamedExportCount(0),
    34         iDynStrTabSize(0),
    34 		iSymStringTableSize(0),iStringNameOffset(0), 
    35         iDynSymTab(0),
    35 		iDepRecords(0), iDepRecordsTail(0),iNeededDllNames(0),iNeededDllNamesTail(0),
    36 
    36 		iOrdZeroRec(0), iNamedLookupEnabled(0), 
    37         iSymSize(0),
    37 		iDllHead(0), iDllTail(0), 
    38         iRela(0),
    38  		iNumberOfImports(0),  iNumberOfExports(0), iNumberOfImportDlls(0),
    39         iRelaSz(0),
    39  		iStringTableSize(0), iNumberOfRelocs(0), iNumberOfCodeRelocs(0),
    40         iRelaEnt(0),
    40  		iNumberOfDataRelocs(0)
    41 
    41  		  		
    42         iRel(0),
       
    43         iRelSz(0),
       
    44         iRelEnt(0),
       
    45 
       
    46         iHashTable(0),
       
    47 
       
    48         iNamedExportSymbolHead(0),
       
    49         iNamedExportCount(0),
       
    50 
       
    51         iSymStringTableSize(0),
       
    52         iStringNameOffset(0),
       
    53 
       
    54         iDepRecords(0),
       
    55         iDepRecordsTail(0),
       
    56 
       
    57         iNeededDllNames(0),
       
    58         iNeededDllNamesTail(0),
       
    59 
       
    60         iOrdZeroRec(0),
       
    61 
       
    62         iNamedLookupEnabled(0),
       
    63 
       
    64         iDllHead(0),
       
    65         iDllTail(0),
       
    66 
       
    67         iNumberOfImports(0),
       
    68         iNumberOfExports(0),
       
    69         iNumberOfImportDlls(0),
       
    70 
       
    71         iStringTableSize(0),
       
    72 
       
    73         iNumberOfRelocs(0),
       
    74         iNumberOfCodeRelocs(0),
       
    75         iNumberOfDataRelocs(0)
       
    76 		{
    42 		{
    77 		}
    43 		}
    78 
    44 
    79 ELFFile::ELFDllData::~ELFDllData()
    45 ELFFile::ELFDllData::~ELFDllData()
    80 	{
    46 	{
   132 					errors++;
    98 					errors++;
   133 					}
    99 					}
   134 			}
   100 			}
   135 	// Set up export info
   101 	// Set up export info
   136 	if (InitExportInfo())
   102 	if (InitExportInfo())
   137 	       {
   103 	       { 
   138 	       TText * sym = (TText *)"_E32Startup";
       
   139 	       // If _E32Startup is defined then this is not a DLL
   104 	       // If _E32Startup is defined then this is not a DLL
   140 	       iImageIsDll = !iElfFile->SymbolPresent(sym);
   105 	       iImageIsDll = !iElfFile->SymbolPresent("_E32Startup");
   141 	       }
   106 	       }
   142 	if (errors > 0) return EFalse;
   107 	if (errors > 0) return EFalse;
   143 	return ETrue;
   108 	return ETrue;
   144 	}
   109 	}
   145 
   110 
   245 	nImports++;
   210 	nImports++;
   246     iTail->iNext = s;
   211     iTail->iNext = s;
   247     iTail = s;
   212     iTail = s;
   248     }
   213     }
   249 
   214 
   250 static unsigned long elf_hash(const unsigned char *name)
   215 static unsigned long elf_hash(const unsigned char* name)
   251     {
   216     {
   252     unsigned long h, g;
   217     unsigned long h, g;
   253     for (h = 0; *name != 0; ++name)
   218     for (h = 0; *name != 0; ++name)
   254 	        {
   219 	        {
   255 			h = (h << 4) + *name;
   220 			h = (h << 4) + *name;
   258 			h &= ~g;
   223 			h &= ~g;
   259 			}
   224 			}
   260 	return h;
   225 	return h;
   261     }
   226     }
   262 
   227 
   263 Elf32_Word ELFFile::ELFDllData::FindSymbolIndex(TText * s)
   228 Elf32_Word ELFFile::ELFDllData::FindSymbolIndex(const char* s)
   264     {
   229     {
   265 	TUint h = elf_hash(s);
   230 	TUint h = elf_hash((const unsigned char*)s);
   266 	TUint nb = iHashTable[0].nBuckets;
   231 	TUint nb = iHashTable[0].nBuckets;
   267 	TUint probe = h%nb;
   232 	TUint probe = h%nb;
   268 	Elf32_Sword * bucket = ELFADDR(Elf32_Sword, iHashTable, sizeof(Elf32_HashTable));
   233 	Elf32_Sword * bucket = ELFADDR(Elf32_Sword, iHashTable, sizeof(Elf32_HashTable));
   269 	Elf32_Sword * chain = ELFADDR(Elf32_Sword, bucket, nb * sizeof(Elf32_Sword));
   234 	Elf32_Sword * chain = ELFADDR(Elf32_Sword, bucket, nb * sizeof(Elf32_Sword));
   270 	Elf32_Sword idx = bucket[probe];
   235 	Elf32_Sword idx = bucket[probe];
   271 
   236 
   272 	do 	
   237 	do 	
   273 			{
   238 			{
   274 			if (!strcmp(ELFADDR(char, iDynStrTab, iDynSymTab[idx].st_name), (char *)s)) return idx;
   239 			if (!strcmp(ELFADDR(char, iDynStrTab, iDynSymTab[idx].st_name), s)) return idx;
   275 			idx = chain[idx];
   240 			idx = chain[idx];
   276 			} while (idx > 0);
   241 			} while (idx > 0);
   277 	if (idx == 0) idx = -1;
   242 	if (idx == 0) idx = -1;
   278 	return idx;
   243 	return idx;
   279 	}
   244 	}
   280 
   245 
   281 TBool ELFFile::ELFDllData::InitExportInfo()
   246 TBool ELFFile::ELFDllData::InitExportInfo()
   282 	{
   247 	{
   283 	memset(&iSymInfoHdr, 0, sizeof(iSymInfoHdr));
   248 	memset(&iSymInfoHdr, 0, sizeof(iSymInfoHdr)); 
   284 	TText * exp = (TText *)EXPORTTABLENAME;
   249 	if ((iExportTableSymIdx = FindSymbolIndex(EXPORTTABLENAME)) != (Elf32_Word)-1)
   285 	if ( int(iExportTableSymIdx = FindSymbolIndex(exp)) != -1 )
   250 			{ 
   286 			{
   251 			iExportTableSizeSymIdx = FindSymbolIndex(EXPORTTABLESIZENAME);
   287 			TText * exps = (TText *)EXPORTTABLESIZENAME;
       
   288 			iExportTableSizeSymIdx = FindSymbolIndex(exps);
       
   289 			//TUint offset = iDynSymTab[iExportTableSizeSymIdx].st_value - (TUint)code;
   252 			//TUint offset = iDynSymTab[iExportTableSizeSymIdx].st_value - (TUint)code;
   290 			Elf32_Word * pNumberOfExports = iElfFile->CodePtrFromAddr(iDynSymTab[iExportTableSizeSymIdx].st_value);
   253 			Elf32_Word * pNumberOfExports = iElfFile->CodePtrFromAddr(iDynSymTab[iExportTableSizeSymIdx].st_value);
   291 			iNumberOfExports = * pNumberOfExports;
   254 			iNumberOfExports = * pNumberOfExports;
   292 			iImageIsDll = ETrue;
   255 			iImageIsDll = ETrue;
   293 			return ETrue;
   256 			return ETrue;
   378 
   341 
   379 					// sanity check: segment should be the code segment
   342 					// sanity check: segment should be the code segment
   380 					if (!iElfFile->CodeSegmentP(segment))
   343 					if (!iElfFile->CodeSegmentP(segment))
   381 							{
   344 							{
   382 							Print(EPeError, "Import relocation does not refer to code segment.\n");
   345 							Print(EPeError, "Import relocation does not refer to code segment.\n");
       
   346 							Print(EPeError, "Dll: %s\n", sym->iDll);
       
   347 							Print(EPeError, "Ordinal: %d\n", sym->iOrd);
       
   348 							Print(EPeError, "DLL name: %s\n", dll->iName);
   383 							aSize = 0;
   349 							aSize = 0;
   384 							return 0;
   350 							return 0;
   385 							}
   351 							}
   386 
   352 
   387 					// This field is misnamed because it is actually given as a virtual address in 
   353 					// This field is misnamed because it is actually given as a virtual address in 
   394 					// We store there reloc offset in the top 16 bits of the 'reloc info'.
   360 					// We store there reloc offset in the top 16 bits of the 'reloc info'.
   395 					// NB the ELF reloc values should only ever be multiples of 4. So we could optimize here,
   361 					// NB the ELF reloc values should only ever be multiples of 4. So we could optimize here,
   396 					// but we won't.
   362 					// but we won't.
   397 					TUint relocVal = *relocAddr;
   363 					TUint relocVal = *relocAddr;
   398 					TUint importOrdinal = sym->iOrd;
   364 					TUint importOrdinal = sym->iOrd;
   399 					if (relocVal > 0xFFFF)
   365 					if (relocVal > 0xFFFF) {
   400 							Print(EPeError, "ELF relocation exceeds E32Image limit of 64K.\n");
   366 							Print(EPeError, "ELF relocation exceeds E32Image limit of 64K.\n");
   401 					if (importOrdinal > 0xFFFF)
   367 							Print(EPeError, "Dll: %s\n", sym->iDll);
       
   368 							Print(EPeError, "Ordinal: %d\n", sym->iOrd);
       
   369 							Print(EPeError, "DLL name: %s\n", dll->iName);
       
   370 					}
       
   371 					if (importOrdinal > 0xFFFF) {
   402 							Print(EPeError, "Import ordinal exceeds E32Image limit of 64K.\n");
   372 							Print(EPeError, "Import ordinal exceeds E32Image limit of 64K.\n");
   403    
   373 							Print(EPeError, "Dll: %s\n", sym->iDll);
       
   374 							Print(EPeError, "Ordinal: %d\n", sym->iOrd);
       
   375 							Print(EPeError, "DLL name: %s\n", dll->iName);
       
   376 					}   
   404    					*rp = segOffset;
   377    					*rp = segOffset;
   405    			
   378    			
   406    					// eek !! surgery on the code segment....
   379    					// eek !! surgery on the code segment....
   407 					*relocAddr = (relocVal<<16) | importOrdinal;
   380 					*relocAddr = (relocVal<<16) | importOrdinal;
   408 					}
   381 					}
   436 	//
   409 	//
   437 	{
   410 	{
   438 	TInt nrelocs = iRelSz/iRelEnt;
   411 	TInt nrelocs = iRelSz/iRelEnt;
   439 
   412 
   440 	TInt SrcSegIdx = -1;
   413 	TInt SrcSegIdx = -1;
   441 
   414 	
       
   415 	TInt idx = 0;
   442 	TInt cidx = 0;
   416 	TInt cidx = 0;
   443 	TInt didx = 0;
   417 	TInt didx = 0;
   444 
   418 
   445 	for (TInt idx = 0; idx < nrelocs; idx++)
   419 	for (idx = 0, cidx = 0, didx = 0; idx < nrelocs; idx++)
   446 	        {
   420 	        {
   447 			Elf32_Rel * rel = &iRel[idx];
   421 			Elf32_Rel * rel = &iRel[idx];
   448 
   422 
   449 			if (ELF32_R_TYPE(rel->r_info) == R_ARM_RABS32)
   423 			if (ELF32_R_TYPE(rel->r_info) == R_ARM_RABS32)
   450 					{
   424 					{
   529 
   503 
   530 TBool ELFFile::ELFDllData::SetupSymbolValues()
   504 TBool ELFFile::ELFDllData::SetupSymbolValues()
   531 {
   505 {
   532 	NamedExportSymbol *aSym, *aPrevSym;
   506 	NamedExportSymbol *aSym, *aPrevSym;
   533 
   507 
   534 	if( int(iExportTableSymIdx) == -1 || int(iExportTableSizeSymIdx) == -1)
   508 	if( iExportTableSymIdx == (Elf32_Word)-1 || iExportTableSizeSymIdx == (Elf32_Word)-1)
   535 		return FALSE;
   509 		return FALSE;
   536 
   510 
   537 	// Fetch the 'export table' symbol from the dynamic symbol table.
   511 	// Fetch the 'export table' symbol from the dynamic symbol table.
   538 	Elf32_Sym *aElfExpTbl = &iDynSymTab[iExportTableSymIdx];
   512 	Elf32_Sym *aElfExpTbl = &iDynSymTab[iExportTableSymIdx];
   539 
   513