toolsandutils/e32tools/elf2e32/source/pl_elfproducer.cpp
changeset 0 83f4b4db085c
child 1 d4b442d23379
equal deleted inserted replaced
-1:000000000000 0:83f4b4db085c
       
     1 // Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // Implementation of the Class ElfProducer for the elf2e32 tool
       
    15 // @internalComponent
       
    16 // @released
       
    17 // 
       
    18 //
       
    19 
       
    20 #include "pl_elfproducer.h"
       
    21 #include "pl_dllsymbol.h"
       
    22 #include <stdio.h>
       
    23 #include <string>
       
    24 #include "errorhandler.h"
       
    25 
       
    26 /**
       
    27  * Following array is indexed on the SECTION_INDEX enum 
       
    28  */
       
    29 char* SECTION_NAME[] = {
       
    30 	"",
       
    31 	"ER_RO",
       
    32 	".dynamic",
       
    33 	".hash",
       
    34 	".version_d",
       
    35 	".version",
       
    36 	".strtab",
       
    37 	".dynsym",
       
    38 	".shstrtab"
       
    39 };
       
    40 
       
    41 
       
    42 /**
       
    43 Constructor for class ElfProducer
       
    44 @param aParameterListInterface - instance of class ParameterListInterface
       
    45 @internalComponent
       
    46 @released
       
    47 */
       
    48 ElfProducer::ElfProducer(ParameterListInterface *aParameterListInterface): ElfExecutable(aParameterListInterface) , \
       
    49 	 iDSONameOffset(0),\
       
    50 	 iLinkAsOffset(0),\
       
    51 	 iSymbolsList(NULL),
       
    52 	 iDSODaux(NULL), \
       
    53 	 iDSOBuckets(NULL), \
       
    54      iDSOChains(NULL),\
       
    55 	 iCodeSectionData(NULL),\
       
    56 	 iElfFileOffset(0)
       
    57 {
       
    58 }
       
    59 
       
    60 
       
    61 
       
    62 /**
       
    63 Destructor for class ElfProducer to release allocated memory
       
    64 @internalComponent
       
    65 @released
       
    66 */
       
    67 ElfProducer::~ElfProducer(){
       
    68 	Cleanup();
       
    69 }
       
    70 
       
    71 
       
    72 /**
       
    73 This function sets the export Symbol list
       
    74 @internalComponent
       
    75 @released
       
    76 @param aSymbolList The export Symbol list.
       
    77 */
       
    78 void ElfProducer::SetSymbolList(SymbolList& aSymbolList){
       
    79 	iSymbolsList = &aSymbolList;
       
    80 	if (iSymbolsList)
       
    81 	{
       
    82 		SymbolList::iterator aPos, aEnd;
       
    83 		aPos = iSymbolsList->begin();
       
    84 		aEnd = iSymbolsList->end();
       
    85 		char *aAbsentSymbol = "_._.absent_export_";
       
    86 		int length = strlen(aAbsentSymbol);
       
    87 		while(aPos != aEnd)
       
    88 		{
       
    89 			/* If a symbol is marked as Absent in the DEF file, replace the 
       
    90 			 * symbol name with "_._.absent_export_<Ordinal Number>"
       
    91 			 */
       
    92 			if((*aPos)->Absent())
       
    93 			{
       
    94 				int aOrdinalNo = (*aPos)->OrdNum();
       
    95 				// Ordinal Number can be upto 0xffff which is 6 digits
       
    96 				char * aSymName = new char[length+7];
       
    97 				sprintf(aSymName, "_._.absent_export_%d", aOrdinalNo);
       
    98 				(*aPos)->SetSymbolName(aSymName);
       
    99 				delete[] aSymName;
       
   100 			}
       
   101 			aPos++;
       
   102 		}
       
   103 	}
       
   104 	iNSymbols = iSymbolsList->size() + 1;
       
   105 }
       
   106 
       
   107 /**
       
   108 This function takes the file names and generates the proxy dso library.
       
   109 @internalComponent
       
   110 @released
       
   111 @param aDsoFullName The full path and proxy-dso file name
       
   112 @param aDsoFileName The proxy-dso file name
       
   113 @param aLinkAs The DLL that defines the export Symbols
       
   114 */
       
   115 void ElfProducer::WriteElfFile(char* aDsoFullName, char* aDsoFileName , char* aLinkAs){
       
   116 
       
   117 	//This includes the full path followed by the file name
       
   118 	iDsoFullName = aDsoFullName;
       
   119 
       
   120 	iDSOName = aDsoFileName;
       
   121 	iLinkAs = aLinkAs;
       
   122 
       
   123 	InitElfContents();
       
   124 
       
   125 	WriteElfContents();
       
   126 }
       
   127 
       
   128 /**
       
   129 This function initializes the Elf members
       
   130 @internalComponent
       
   131 @released
       
   132 */
       
   133 void ElfProducer::InitElfContents() {
       
   134 
       
   135 	iElfHeader		= new Elf32_Ehdr;
       
   136 	iSections		= new Elf32_Shdr[MAX_SECTIONS+1];
       
   137 
       
   138 	iElfDynSym		= new Elf32_Sym[iNSymbols];
       
   139 	iVersionTbl		= new Elf32_Half[iNSymbols];
       
   140 	iVersionDef		= new Elf32_Verdef[2];
       
   141 	iDSODaux		= new Elf32_Verdaux[2];
       
   142 
       
   143 	iProgHeader		 = new Elf32_Phdr[2];
       
   144 	iCodeSectionData = new PLUINT32[iNSymbols];	
       
   145 
       
   146 	iHashTbl = new Elf32_HashTable;
       
   147 	
       
   148 	//premeditated
       
   149 	iHashTbl->nBuckets = (iNSymbols /3) + (iNSymbols % 0x3);
       
   150 	
       
   151 	iHashTbl->nChains = iNSymbols;
       
   152 
       
   153 	iDSOBuckets = new Elf32_Sword[iHashTbl->nBuckets];
       
   154 	iDSOChains = new Elf32_Sword[iHashTbl->nChains];
       
   155 
       
   156 	Elf32_Sword	aNullPtr = 0;
       
   157 
       
   158 	memset(iDSOBuckets, aNullPtr, sizeof(Elf32_Sword)*iHashTbl->nBuckets);
       
   159 	memset(iDSOChains,  aNullPtr, sizeof(Elf32_Sword)*iHashTbl->nChains);
       
   160 	memset(iCodeSectionData,  0, sizeof(PLUINT32)*iNSymbols);
       
   161 
       
   162 	CreateElfHeader();
       
   163 
       
   164 	SymbolList::iterator aItr = iSymbolsList->begin();
       
   165 	SymbolList::iterator aEnd = iSymbolsList->end();
       
   166 	Symbol		*aSym;
       
   167 	PLUINT32	aIdx = 1;
       
   168 
       
   169 	memset( &iElfDynSym[0], 0, sizeof(Elf32_Sym));
       
   170 	iDSOSymNameStrTbl.insert(iDSOSymNameStrTbl.end(), 0);
       
   171 
       
   172 	while(aItr != aEnd) {
       
   173 		String		aSymName("");
       
   174 		aSym = *aItr;
       
   175 		aSymName = aSym->SymbolName();
       
   176 		//set symbol info..
       
   177 		iElfDynSym[aIdx].st_name = iDSOSymNameStrTbl.size();
       
   178 
       
   179 		iDSOSymNameStrTbl.insert(iDSOSymNameStrTbl.end(), aSymName.begin(), aSymName.end() );
       
   180 		iDSOSymNameStrTbl.insert(iDSOSymNameStrTbl.end(), 0);
       
   181 
       
   182 		SetSymolFields( aSym, &iElfDynSym[aIdx], aIdx);
       
   183 
       
   184 		//set version table info...
       
   185 		iVersionTbl[aIdx] = DEFAULT_VERSION;
       
   186 		AddToHashTable(aSym->SymbolName(), aIdx);
       
   187 		aItr++;aIdx++;
       
   188 	}
       
   189 
       
   190 	CreateVersionTable();
       
   191 	
       
   192 	//Fill section headers...
       
   193 	CreateSections();
       
   194 
       
   195 	//Copy dyn entries..
       
   196 	CreateDynamicEntries();
       
   197 
       
   198 	//create code section data - this has the ordinal numbers...
       
   199 	CreateProgHeader();
       
   200 }
       
   201 
       
   202 /**
       
   203 This function creates the version definition table
       
   204 @internalComponent
       
   205 @released
       
   206 */
       
   207 void ElfProducer::CreateVersionTable()
       
   208 {
       
   209 	//Fill verdef table...
       
   210 	iVersionDef[0].vd_ndx = 1;
       
   211 	iVersionDef[0].vd_cnt = 1;
       
   212 	iVersionDef[0].vd_flags = 1;
       
   213 	iVersionDef[0].vd_hash = Util::elf_hash((const PLUCHAR*) iDSOName.c_str());
       
   214 	iVersionDef[0].vd_version = 1;
       
   215 
       
   216 	iVersionDef[0].vd_aux = sizeof(Elf32_Verdef);
       
   217 	iVersionDef[0].vd_next = sizeof(Elf32_Verdef) + sizeof(Elf32_Verdaux);
       
   218 
       
   219 	iDSONameOffset = iDSOSymNameStrTbl.size();
       
   220 
       
   221 	iDSOSymNameStrTbl.insert(iDSOSymNameStrTbl.end(),iDSOName.begin(), iDSOName.end());
       
   222 	iDSOSymNameStrTbl.insert(iDSOSymNameStrTbl.end(), 0);
       
   223 	
       
   224 	iDSODaux[0].vda_name = iDSONameOffset;
       
   225 	iDSODaux[0].vda_next = 0;
       
   226 
       
   227 	iVersionDef[1].vd_ndx = DEFAULT_VERSION;
       
   228 	iVersionDef[1].vd_cnt = 1;
       
   229 	iVersionDef[1].vd_flags = 0;
       
   230 	iVersionDef[1].vd_hash = Util::elf_hash((const PLUCHAR*)iLinkAs.c_str());
       
   231 	iVersionDef[1].vd_version = 1;
       
   232 
       
   233 	iVersionDef[1].vd_aux = sizeof(Elf32_Verdef);
       
   234 	iVersionDef[1].vd_next = 0;
       
   235 
       
   236 	iLinkAsOffset = iDSOSymNameStrTbl.size();
       
   237 	iDSOSymNameStrTbl.insert(iDSOSymNameStrTbl.end(),iLinkAs.begin(), iLinkAs.end());
       
   238 	iDSOSymNameStrTbl.insert(iDSOSymNameStrTbl.end(), 0);
       
   239 	
       
   240 	iDSODaux[1].vda_name = iLinkAsOffset;
       
   241 	iDSODaux[1].vda_next = 0;
       
   242 
       
   243 }
       
   244 
       
   245 /**
       
   246 This function sets the Elf Symbol fields
       
   247 @internalComponent
       
   248 @released
       
   249 @param aSym The Symbol representation
       
   250 @param aElfSym The Elf Symbol
       
   251 @param aCodeIndex The index at which this Symbol refers to in the code section where, we have the ordinal number
       
   252 */
       
   253 void ElfProducer::SetSymolFields(Symbol *aSym, Elf32_Sym* aElfSym, PLUINT32 aCodeIndex) {
       
   254 	
       
   255 	aElfSym->st_other = STV_DEFAULT;
       
   256 	
       
   257 	aElfSym->st_info = (PLUCHAR) (ELF32_ST_INFO(STB_GLOBAL, aSym->CodeDataType()));
       
   258 	aElfSym->st_value	= (aCodeIndex - 1)*sizeof(Elf32_Word);
       
   259 	
       
   260 	if(aSym->CodeDataType() == SymbolTypeCode){
       
   261 		aElfSym->st_size	= sizeof(Elf32_Word);
       
   262 	}else{
       
   263 		aElfSym->st_size	= aSym->SymbolSize();
       
   264 	}
       
   265 	aElfSym->st_shndx = CODE_SECTION;
       
   266 }
       
   267 
       
   268 /**
       
   269 This function adds an entry into the hash table based on the symbol name.
       
   270 @internalComponent
       
   271 @released
       
   272 @param aSymName The Symbol name
       
   273 @param aIndex The Symbol index in the Symbol table
       
   274 */
       
   275 void ElfProducer::AddToHashTable(const char* aSymName, PLUINT32 aIndex) 
       
   276 {
       
   277 	Elf32_Sword	aNullPtr = 0;
       
   278 
       
   279 	PLULONG	aHash = Util::elf_hash((PLUCHAR*)aSymName);
       
   280 	PLUINT32  aBIdx = aHash % iHashTbl->nBuckets;
       
   281 
       
   282 	if(iDSOBuckets[aBIdx] == aNullPtr)
       
   283 	{
       
   284 		iDSOBuckets[aBIdx] = aIndex;
       
   285 	}		
       
   286 	else
       
   287 	{
       
   288 		PLUINT32 aCIdx = iDSOBuckets[aBIdx];
       
   289 		
       
   290 		while(iDSOChains[aCIdx] != aNullPtr){
       
   291 
       
   292 			/* If the entry is already added into the hash table*/
       
   293 			if((PLUINT32)iDSOChains[aCIdx] == aIndex) {
       
   294 				return;
       
   295 			}
       
   296 			aCIdx = iDSOChains[aCIdx];
       
   297 		}
       
   298 		iDSOChains[aCIdx] = aIndex;
       
   299 	}
       
   300 }
       
   301 
       
   302 /**
       
   303 This function creates the different sections of the Elf file
       
   304 @internalComponent
       
   305 @released
       
   306 */
       
   307 void ElfProducer::CreateSections() {
       
   308 	PLUINT32	aIdx = 0;
       
   309 
       
   310 	//clear the first section...
       
   311 	memset(&iSections[0], 0, sizeof(Elf32_Shdr));
       
   312 	iDSOSectionNames.insert(iDSOSectionNames.begin(), 0);
       
   313 
       
   314 	// Set the ELF file offset.
       
   315 	// This indicates the start of sections.
       
   316 	iElfFileOffset = sizeof(Elf32_Ehdr);
       
   317 
       
   318 	iElfFileOffset += (sizeof(Elf32_Shdr) * iElfHeader->e_shnum);
       
   319 
       
   320 	//Check if the string table is 4-byte aligned..
       
   321 	AlignString(iDSOSymNameStrTbl);
       
   322 
       
   323 	for(aIdx = 1; aIdx <= MAX_SECTIONS; aIdx++) {
       
   324 		switch(aIdx)
       
   325 		{
       
   326 			case SYMBOL_SECTION:
       
   327 				SetSectionFields(aIdx, SECTION_NAME[aIdx], SHT_DYNSYM, \
       
   328 								   sizeof(Elf32_Sym), (iNSymbols * sizeof(Elf32_Sym)),\
       
   329 								   STRING_SECTION, CODE_SECTION, 4, 0, 0);
       
   330 				break;
       
   331 			case STRING_SECTION:
       
   332 				SetSectionFields(aIdx, SECTION_NAME[aIdx], SHT_STRTAB, \
       
   333 								   1, iDSOSymNameStrTbl.size(), 0, \
       
   334 								   0, 0, 0,0);
       
   335 				break;
       
   336 			case VERSION_SECTION:
       
   337 				SetSectionFields(aIdx, SECTION_NAME[aIdx], 0x6fffffff, \
       
   338 								   sizeof(Elf32_Half), (iNSymbols * sizeof(Elf32_Half)), SYMBOL_SECTION, \
       
   339 								   0, 2, 0, 0);
       
   340 				break;
       
   341 			case VER_DEF_SECTION:
       
   342 				SetSectionFields(aIdx, SECTION_NAME[aIdx],0x6ffffffd, \
       
   343 								   sizeof(Elf32_Verdaux), (2*(sizeof(Elf32_Verdef) + sizeof(Elf32_Verdaux))),\
       
   344 								   STRING_SECTION, DYNAMIC_SECTION, 4, 0, 0);
       
   345 				break;
       
   346 			case HASH_TBL_SECTION:
       
   347 				{
       
   348 					PLUINT32 aSize = sizeof(Elf32_HashTable) + \
       
   349 							(sizeof(Elf32_Sword) * (iHashTbl->nBuckets + iHashTbl->nChains));
       
   350 
       
   351 				SetSectionFields(aIdx, SECTION_NAME[aIdx], SHT_HASH, \
       
   352 								   0, aSize, SYMBOL_SECTION, 0, 4, 0, 0);
       
   353 				}
       
   354 				break;
       
   355 			case DYNAMIC_SECTION:
       
   356 				SetSectionFields(aIdx, SECTION_NAME[aIdx], SHT_DYNAMIC, \
       
   357 								   sizeof(Elf32_Dyn), ((MAX_DYN_ENTS + 1) *sizeof(Elf32_Dyn)),\
       
   358 								   STRING_SECTION, 0, 4, 0,0);
       
   359 				break;
       
   360 			case CODE_SECTION:
       
   361 				SetSectionFields(aIdx, SECTION_NAME[aIdx], SHT_PROGBITS, \
       
   362 								   0, (iNSymbols *sizeof(PLUINT32)),\
       
   363 								   0, 0, 4, (SHF_ALLOC | SHF_EXECINSTR),0);
       
   364 				break;
       
   365 			case SH_STR_SECTION:
       
   366 				{
       
   367 				PLUINT32 aSize = iDSOSectionNames.size() + strlen(SECTION_NAME[aIdx]);
       
   368 				SetSectionFields(aIdx, SECTION_NAME[aIdx], SHT_STRTAB, \
       
   369 								   1, aSize, 0, \
       
   370 								   0, 0, 0, 0);
       
   371 				//Check if the string table is 4-byte aligned..
       
   372 				AlignString(iDSOSectionNames);
       
   373 				iSections[aIdx].sh_size = iDSOSectionNames.size();
       
   374 
       
   375 				}
       
   376 				break;
       
   377 			default:
       
   378 				break;
       
   379 		}
       
   380 		iSections[aIdx].sh_offset = iElfFileOffset;
       
   381 		iElfFileOffset += iSections[aIdx].sh_size;
       
   382 
       
   383 		if(iElfFileOffset %4) {
       
   384 			iElfFileOffset += (4 - (iElfFileOffset %4));
       
   385 		}
       
   386 	}
       
   387 }
       
   388 
       
   389 /**
       
   390 This function sets the section header fields.
       
   391 @internalComponent
       
   392 @released
       
   393 @return Error status
       
   394 @param aSectionIndex The index of the section
       
   395 @param aSectionName The name of the section
       
   396 @param aType The type of the section
       
   397 @param aEntSz The size of each entry of the section
       
   398 @param aSectionSize The size of the section
       
   399 @param aLink The section this section is linked to
       
   400 @param aInfo Extra information. Depends on the section type of this section.
       
   401 @param aAddrAlign The address alignment of this section.
       
   402 @param aFlags Section flags
       
   403 @param aAddr The address of this section in memory(Here it remains 0)
       
   404 */
       
   405 void ElfProducer::SetSectionFields(PLUINT32 aSectionIndex, char* aSectionName, PLUINT32 aType, \
       
   406 								   PLUINT32 aEntSz, PLUINT32 aSectionSize, PLUINT32 aLink, \
       
   407 								   PLUINT32 aInfo, PLUINT32 aAddrAlign, PLUINT32 aFlags, \
       
   408 								   PLUINT32 aAddr)
       
   409 {
       
   410 	String aSecName = aSectionName;
       
   411 
       
   412 	iSections[aSectionIndex].sh_name			= iDSOSectionNames.size();
       
   413 	iDSOSectionNames.insert(iDSOSectionNames.end(), aSecName.begin(), aSecName.end());
       
   414 	iDSOSectionNames.insert(iDSOSectionNames.end(), 0);
       
   415 	
       
   416 	iSections[aSectionIndex].sh_type			= aType;
       
   417 	iSections[aSectionIndex].sh_entsize		= aEntSz;
       
   418 	iSections[aSectionIndex].sh_size			= aSectionSize;
       
   419 	iSections[aSectionIndex].sh_link			= aLink;
       
   420 	iSections[aSectionIndex].sh_flags		= aFlags;
       
   421 	iSections[aSectionIndex].sh_addralign	= aAddrAlign;
       
   422 	iSections[aSectionIndex].sh_info			= aInfo;
       
   423 	iSections[aSectionIndex].sh_addr			= aAddr;
       
   424 }
       
   425 
       
   426 /**
       
   427 This function cleans up the memory allocated to the Elf fields.
       
   428 @internalComponent
       
   429 @released
       
   430 */
       
   431 void ElfProducer::Cleanup()
       
   432 {
       
   433 	DELETE_PTR(iElfHeader);
       
   434 	DELETE_PTR_ARRAY(iSections);
       
   435 	DELETE_PTR_ARRAY(iElfDynSym);
       
   436 	DELETE_PTR_ARRAY(iVersionTbl);
       
   437 	DELETE_PTR_ARRAY(iVersionDef);
       
   438 	DELETE_PTR_ARRAY(iDSODaux);
       
   439 
       
   440 	DELETE_PTR_ARRAY(iProgHeader);
       
   441 	DELETE_PTR_ARRAY(iCodeSectionData);
       
   442 	DELETE_PTR_ARRAY(iHashTbl);
       
   443 	DELETE_PTR_ARRAY(iDSOBuckets);
       
   444 	DELETE_PTR_ARRAY(iDSOChains);
       
   445 }
       
   446 
       
   447 /**
       
   448 This function creates the dynamic sections.
       
   449 @internalComponent
       
   450 @released
       
   451 */
       
   452 void ElfProducer::CreateDynamicEntries()
       
   453 {
       
   454 	for(PLUINT32 aIdx = 0; aIdx <= MAX_DYN_ENTS; aIdx++ ) {
       
   455 		switch(aIdx) {
       
   456 			case DSO_DT_DSONAME:
       
   457 				iDSODynTbl[aIdx].d_tag = DT_SONAME;
       
   458 				iDSODynTbl[aIdx].d_val = iDSONameOffset;
       
   459 				break;
       
   460 			case DSO_DT_SYMTAB:
       
   461 				iDSODynTbl[aIdx].d_tag = DT_SYMTAB;
       
   462 				iDSODynTbl[aIdx].d_val = iSections[SYMBOL_SECTION].sh_offset;
       
   463 				break;
       
   464 			case DSO_DT_SYMENT:
       
   465 				iDSODynTbl[aIdx].d_tag = DT_SYMENT;
       
   466 				iDSODynTbl[aIdx].d_val = iSections[SYMBOL_SECTION].sh_entsize;
       
   467 				break;
       
   468 			case DSO_DT_STRTAB:
       
   469 				iDSODynTbl[aIdx].d_tag = DT_STRTAB;
       
   470 				iDSODynTbl[aIdx].d_val = iSections[STRING_SECTION].sh_offset;
       
   471 				break;
       
   472 			case DSO_DT_STRSZ:
       
   473 				iDSODynTbl[aIdx].d_tag = DT_STRSZ;
       
   474 				iDSODynTbl[aIdx].d_val = iDSOSymNameStrTbl.size();
       
   475 				break;
       
   476 			case DSO_DT_VERSYM:
       
   477 				iDSODynTbl[aIdx].d_tag = DT_VERSYM;
       
   478 				iDSODynTbl[aIdx].d_val = iSections[VERSION_SECTION].sh_offset;
       
   479 				break;
       
   480 			case DSO_DT_VERDEF:
       
   481 				iDSODynTbl[aIdx].d_tag = DT_VERDEF;
       
   482 				iDSODynTbl[aIdx].d_val = iSections[VER_DEF_SECTION].sh_offset;
       
   483 				break;
       
   484 			case DSO_DT_VERDEFNUM:
       
   485 				iDSODynTbl[aIdx].d_tag = DT_VERDEFNUM;
       
   486 				iDSODynTbl[aIdx].d_val = 2;
       
   487 				break;
       
   488 			case DSO_DT_HASH:
       
   489 				iDSODynTbl[aIdx].d_tag = DT_HASH;
       
   490 				iDSODynTbl[aIdx].d_val = iSections[HASH_TBL_SECTION].sh_offset;
       
   491 				break;
       
   492 			case DSO_DT_NULL:
       
   493 				iDSODynTbl[aIdx].d_tag = DT_NULL;
       
   494 				iDSODynTbl[aIdx].d_val = 0;
       
   495 				break;
       
   496 			default:
       
   497 				break;
       
   498 		}
       
   499 	}
       
   500 }
       
   501 
       
   502 /**
       
   503 This function creates the Elf header.
       
   504 @internalComponent
       
   505 @released
       
   506 */
       
   507 void ElfProducer::CreateElfHeader()
       
   508 {
       
   509 	//create ELF header
       
   510 	unsigned char c[EI_NIDENT] = {0x7f, 'E', 'L', 'F', \
       
   511 				ELFCLASS32, ELFDATA2LSB, 1, 0, \
       
   512 				0, 0, 0, 0, \
       
   513 				0, 0, 0, 0};       // e_ident
       
   514 
       
   515 	for (PLUINT32 i=0; i <EI_NIDENT;i++)
       
   516 		iElfHeader->e_ident[i] = c[i];
       
   517 
       
   518 	iElfHeader->e_type		= ET_DYN;
       
   519 	iElfHeader->e_machine	= EM_ARM;
       
   520 	iElfHeader->e_version	= EV_CURRENT;
       
   521 	iElfHeader->e_entry		= 0;
       
   522 	iElfHeader->e_shoff		= sizeof(Elf32_Ehdr);
       
   523 	iElfHeader->e_flags		= EF_ARM_BPABI_VERSION | EF_ARM_SYMSARESORTED;
       
   524 	iElfHeader->e_ehsize	= sizeof(Elf32_Ehdr);
       
   525 	iElfHeader->e_phentsize = sizeof(Elf32_Phdr);
       
   526 	iElfHeader->e_shentsize = sizeof(Elf32_Shdr);
       
   527 	iElfHeader->e_shnum		= MAX_SECTIONS + 1;
       
   528 	iElfHeader->e_shstrndx	= SH_STR_SECTION;
       
   529 	iElfHeader->e_phnum		= 2;
       
   530 }
       
   531 
       
   532 /**
       
   533 This function creates the program header
       
   534 @internalComponent
       
   535 @released
       
   536 */
       
   537 void ElfProducer::CreateProgHeader()
       
   538 {
       
   539 	//Update the program header offset..
       
   540 	iElfHeader->e_phoff		= iElfFileOffset;
       
   541 
       
   542 	// Update code section data..
       
   543 	SymbolList::iterator aItr = iSymbolsList->begin();
       
   544 	SymbolList::iterator end  = iSymbolsList->end();
       
   545 
       
   546 	Symbol *aSym;
       
   547 	PLUINT32	aPos = 0;
       
   548 	while(aItr != end) {
       
   549 		aSym = *aItr;
       
   550 
       
   551 		iCodeSectionData[aPos] = aSym->OrdNum();
       
   552 		aItr++;aPos++;
       
   553 	}
       
   554 
       
   555 	//Create program header
       
   556 	iProgHeader[0].p_align	= 4;
       
   557 	iProgHeader[0].p_offset = iSections[CODE_SECTION].sh_offset;
       
   558 	iProgHeader[0].p_type	= PT_LOAD;
       
   559 	iProgHeader[0].p_flags	= (PF_X | PF_ARM_ENTRY);
       
   560 	iProgHeader[0].p_filesz = iSections[CODE_SECTION].sh_size;
       
   561 	iProgHeader[0].p_paddr	= 0;
       
   562 	iProgHeader[0].p_vaddr	= 0;
       
   563 	iProgHeader[0].p_memsz  = iSections[CODE_SECTION].sh_size;
       
   564 
       
   565 	iProgHeader[1].p_align	= 4;
       
   566 	iProgHeader[1].p_offset = iSections[DYNAMIC_SECTION].sh_offset;
       
   567 	iProgHeader[1].p_type	= PT_DYNAMIC;
       
   568 	iProgHeader[1].p_flags	= (PF_R );
       
   569 	iProgHeader[1].p_filesz = iSections[DYNAMIC_SECTION].sh_size;
       
   570 	iProgHeader[1].p_paddr	= 0;
       
   571 	iProgHeader[1].p_vaddr	= 0;
       
   572 	iProgHeader[1].p_memsz  = 0;
       
   573 
       
   574 }
       
   575 
       
   576 /**
       
   577 This function aligns the string table to a 4-byte boundary
       
   578 @internalComponent
       
   579 @released
       
   580 @return Error status
       
   581 @param aStr - string to be aligned
       
   582 */
       
   583 void ElfProducer::AlignString(String& aStr) {
       
   584 
       
   585 	if( aStr.size() %4 ){
       
   586 		PLUCHAR	aPad = (PLUCHAR)(4 - (aStr.size() %4));
       
   587 
       
   588 		while(aPad--) {
       
   589 			aStr.insert(aStr.end(), 0);
       
   590 		}
       
   591 	}
       
   592 }
       
   593 
       
   594 /**
       
   595 This function writes the Elf file contents.
       
   596 @internalComponent
       
   597 @released
       
   598 */
       
   599 void ElfProducer::WriteElfContents()
       
   600 {
       
   601 	FILE		*aElfFd;
       
   602 	PLUINT32	aIndex;
       
   603 	
       
   604 	if((aElfFd = fopen(iDsoFullName.c_str(), "wb")) == NULL ) {
       
   605 		throw FileError(FILEOPENERROR, (char*)iDsoFullName.c_str());
       
   606 	}
       
   607 
       
   608 	// The ELF header..
       
   609 	fwrite(iElfHeader, 1, sizeof(Elf32_Ehdr), aElfFd);
       
   610 	
       
   611 	//Section headers
       
   612 	for(aIndex = 0; aIndex <= MAX_SECTIONS; aIndex++) {
       
   613 		fwrite(&iSections[aIndex], 1, sizeof(Elf32_Shdr), aElfFd);
       
   614 	}
       
   615 
       
   616 
       
   617 	//Each section..
       
   618 
       
   619 		//code
       
   620 		for(aIndex = 0; aIndex < iNSymbols; aIndex++) {
       
   621 			fwrite(&iCodeSectionData[aIndex], 1, sizeof(PLUINT32), aElfFd );
       
   622 		}
       
   623 		
       
   624 		//dyn table
       
   625 		for(aIndex = 0; aIndex <= MAX_DYN_ENTS; aIndex++) {
       
   626 			fwrite(&iDSODynTbl[aIndex], 1, sizeof(Elf32_Dyn), aElfFd);
       
   627 		}
       
   628 
       
   629 		//hash table
       
   630 		fwrite(&iHashTbl->nBuckets, 1, sizeof(Elf32_Word), aElfFd);
       
   631 		fwrite(&iHashTbl->nChains, 1, sizeof(Elf32_Word), aElfFd);
       
   632 
       
   633 		for(aIndex=0; aIndex < iHashTbl->nBuckets; aIndex++) {
       
   634 			fwrite(&iDSOBuckets[aIndex], 1, sizeof(Elf32_Sword), aElfFd);
       
   635 
       
   636 		}
       
   637 		for(aIndex=0; aIndex < iHashTbl->nChains; aIndex++) {
       
   638 			fwrite(&iDSOChains[aIndex], 1, sizeof(Elf32_Sword), aElfFd);
       
   639 			
       
   640 		}
       
   641 
       
   642 		//version def table
       
   643 		for(aIndex = 0; aIndex < 2; aIndex++) {
       
   644 			fwrite(&iVersionDef[aIndex], 1, sizeof(Elf32_Verdef), aElfFd);
       
   645 			fwrite(&iDSODaux[aIndex], 1, sizeof(Elf32_Verdaux), aElfFd);
       
   646 		}
       
   647 
       
   648 		//version table
       
   649 		for(aIndex = 0; aIndex < iNSymbols; aIndex++) {
       
   650 			fwrite(&iVersionTbl[aIndex], 1, sizeof(Elf32_Half), aElfFd );
       
   651 		}
       
   652 
       
   653 		if( iSections[VERSION_SECTION].sh_size %4 ) {
       
   654 			PLUINT32 aNPads = 4 - (iSections[VERSION_SECTION].sh_size %4);
       
   655 			PLUCHAR aPad = '\0';
       
   656 			while(aNPads--) {
       
   657 				fwrite(&aPad, 1, 1, aElfFd);
       
   658 			}
       
   659 		}
       
   660 
       
   661 		//string table
       
   662 		PLUINT32 aSz = iDSOSymNameStrTbl.size();
       
   663 		char *aData = new char[aSz];
       
   664 		memcpy(aData, iDSOSymNameStrTbl.data(), aSz);
       
   665 		fwrite(aData, 1, aSz, aElfFd);
       
   666 
       
   667 		DELETE_PTR_ARRAY(aData);
       
   668 
       
   669 		//Sym table
       
   670 		for(aIndex = 0; aIndex < iNSymbols; aIndex ++) {
       
   671 			fwrite(&iElfDynSym[aIndex], 1, sizeof(Elf32_Sym), aElfFd);
       
   672 		}
       
   673 
       
   674 		//section header name table
       
   675 		aSz = iDSOSectionNames.size();
       
   676 		char *aData1 = new char[ aSz];
       
   677 		memcpy(aData1, iDSOSectionNames.data(), aSz);
       
   678 		fwrite(aData1, 1, aSz, aElfFd);
       
   679 		DELETE_PTR_ARRAY(aData1);
       
   680 
       
   681 	//program header
       
   682 	for(aIndex = 0; aIndex < 2; aIndex++) {
       
   683 		fwrite(&iProgHeader[aIndex], 1, sizeof(Elf32_Phdr), aElfFd );
       
   684 	}
       
   685 
       
   686 	fclose(aElfFd);
       
   687 }
       
   688