diff -r 000000000000 -r 83f4b4db085c toolsandutils/e32tools/elf2e32/source/pl_elfproducer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/toolsandutils/e32tools/elf2e32/source/pl_elfproducer.cpp Tue Feb 02 01:39:43 2010 +0200 @@ -0,0 +1,688 @@ +// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// Implementation of the Class ElfProducer for the elf2e32 tool +// @internalComponent +// @released +// +// + +#include "pl_elfproducer.h" +#include "pl_dllsymbol.h" +#include +#include +#include "errorhandler.h" + +/** + * Following array is indexed on the SECTION_INDEX enum + */ +char* SECTION_NAME[] = { + "", + "ER_RO", + ".dynamic", + ".hash", + ".version_d", + ".version", + ".strtab", + ".dynsym", + ".shstrtab" +}; + + +/** +Constructor for class ElfProducer +@param aParameterListInterface - instance of class ParameterListInterface +@internalComponent +@released +*/ +ElfProducer::ElfProducer(ParameterListInterface *aParameterListInterface): ElfExecutable(aParameterListInterface) , \ + iDSONameOffset(0),\ + iLinkAsOffset(0),\ + iSymbolsList(NULL), + iDSODaux(NULL), \ + iDSOBuckets(NULL), \ + iDSOChains(NULL),\ + iCodeSectionData(NULL),\ + iElfFileOffset(0) +{ +} + + + +/** +Destructor for class ElfProducer to release allocated memory +@internalComponent +@released +*/ +ElfProducer::~ElfProducer(){ + Cleanup(); +} + + +/** +This function sets the export Symbol list +@internalComponent +@released +@param aSymbolList The export Symbol list. +*/ +void ElfProducer::SetSymbolList(SymbolList& aSymbolList){ + iSymbolsList = &aSymbolList; + if (iSymbolsList) + { + SymbolList::iterator aPos, aEnd; + aPos = iSymbolsList->begin(); + aEnd = iSymbolsList->end(); + char *aAbsentSymbol = "_._.absent_export_"; + int length = strlen(aAbsentSymbol); + while(aPos != aEnd) + { + /* If a symbol is marked as Absent in the DEF file, replace the + * symbol name with "_._.absent_export_" + */ + if((*aPos)->Absent()) + { + int aOrdinalNo = (*aPos)->OrdNum(); + // Ordinal Number can be upto 0xffff which is 6 digits + char * aSymName = new char[length+7]; + sprintf(aSymName, "_._.absent_export_%d", aOrdinalNo); + (*aPos)->SetSymbolName(aSymName); + delete[] aSymName; + } + aPos++; + } + } + iNSymbols = iSymbolsList->size() + 1; +} + +/** +This function takes the file names and generates the proxy dso library. +@internalComponent +@released +@param aDsoFullName The full path and proxy-dso file name +@param aDsoFileName The proxy-dso file name +@param aLinkAs The DLL that defines the export Symbols +*/ +void ElfProducer::WriteElfFile(char* aDsoFullName, char* aDsoFileName , char* aLinkAs){ + + //This includes the full path followed by the file name + iDsoFullName = aDsoFullName; + + iDSOName = aDsoFileName; + iLinkAs = aLinkAs; + + InitElfContents(); + + WriteElfContents(); +} + +/** +This function initializes the Elf members +@internalComponent +@released +*/ +void ElfProducer::InitElfContents() { + + iElfHeader = new Elf32_Ehdr; + iSections = new Elf32_Shdr[MAX_SECTIONS+1]; + + iElfDynSym = new Elf32_Sym[iNSymbols]; + iVersionTbl = new Elf32_Half[iNSymbols]; + iVersionDef = new Elf32_Verdef[2]; + iDSODaux = new Elf32_Verdaux[2]; + + iProgHeader = new Elf32_Phdr[2]; + iCodeSectionData = new PLUINT32[iNSymbols]; + + iHashTbl = new Elf32_HashTable; + + //premeditated + iHashTbl->nBuckets = (iNSymbols /3) + (iNSymbols % 0x3); + + iHashTbl->nChains = iNSymbols; + + iDSOBuckets = new Elf32_Sword[iHashTbl->nBuckets]; + iDSOChains = new Elf32_Sword[iHashTbl->nChains]; + + Elf32_Sword aNullPtr = 0; + + memset(iDSOBuckets, aNullPtr, sizeof(Elf32_Sword)*iHashTbl->nBuckets); + memset(iDSOChains, aNullPtr, sizeof(Elf32_Sword)*iHashTbl->nChains); + memset(iCodeSectionData, 0, sizeof(PLUINT32)*iNSymbols); + + CreateElfHeader(); + + SymbolList::iterator aItr = iSymbolsList->begin(); + SymbolList::iterator aEnd = iSymbolsList->end(); + Symbol *aSym; + PLUINT32 aIdx = 1; + + memset( &iElfDynSym[0], 0, sizeof(Elf32_Sym)); + iDSOSymNameStrTbl.insert(iDSOSymNameStrTbl.end(), 0); + + while(aItr != aEnd) { + String aSymName(""); + aSym = *aItr; + aSymName = aSym->SymbolName(); + //set symbol info.. + iElfDynSym[aIdx].st_name = iDSOSymNameStrTbl.size(); + + iDSOSymNameStrTbl.insert(iDSOSymNameStrTbl.end(), aSymName.begin(), aSymName.end() ); + iDSOSymNameStrTbl.insert(iDSOSymNameStrTbl.end(), 0); + + SetSymolFields( aSym, &iElfDynSym[aIdx], aIdx); + + //set version table info... + iVersionTbl[aIdx] = DEFAULT_VERSION; + AddToHashTable(aSym->SymbolName(), aIdx); + aItr++;aIdx++; + } + + CreateVersionTable(); + + //Fill section headers... + CreateSections(); + + //Copy dyn entries.. + CreateDynamicEntries(); + + //create code section data - this has the ordinal numbers... + CreateProgHeader(); +} + +/** +This function creates the version definition table +@internalComponent +@released +*/ +void ElfProducer::CreateVersionTable() +{ + //Fill verdef table... + iVersionDef[0].vd_ndx = 1; + iVersionDef[0].vd_cnt = 1; + iVersionDef[0].vd_flags = 1; + iVersionDef[0].vd_hash = Util::elf_hash((const PLUCHAR*) iDSOName.c_str()); + iVersionDef[0].vd_version = 1; + + iVersionDef[0].vd_aux = sizeof(Elf32_Verdef); + iVersionDef[0].vd_next = sizeof(Elf32_Verdef) + sizeof(Elf32_Verdaux); + + iDSONameOffset = iDSOSymNameStrTbl.size(); + + iDSOSymNameStrTbl.insert(iDSOSymNameStrTbl.end(),iDSOName.begin(), iDSOName.end()); + iDSOSymNameStrTbl.insert(iDSOSymNameStrTbl.end(), 0); + + iDSODaux[0].vda_name = iDSONameOffset; + iDSODaux[0].vda_next = 0; + + iVersionDef[1].vd_ndx = DEFAULT_VERSION; + iVersionDef[1].vd_cnt = 1; + iVersionDef[1].vd_flags = 0; + iVersionDef[1].vd_hash = Util::elf_hash((const PLUCHAR*)iLinkAs.c_str()); + iVersionDef[1].vd_version = 1; + + iVersionDef[1].vd_aux = sizeof(Elf32_Verdef); + iVersionDef[1].vd_next = 0; + + iLinkAsOffset = iDSOSymNameStrTbl.size(); + iDSOSymNameStrTbl.insert(iDSOSymNameStrTbl.end(),iLinkAs.begin(), iLinkAs.end()); + iDSOSymNameStrTbl.insert(iDSOSymNameStrTbl.end(), 0); + + iDSODaux[1].vda_name = iLinkAsOffset; + iDSODaux[1].vda_next = 0; + +} + +/** +This function sets the Elf Symbol fields +@internalComponent +@released +@param aSym The Symbol representation +@param aElfSym The Elf Symbol +@param aCodeIndex The index at which this Symbol refers to in the code section where, we have the ordinal number +*/ +void ElfProducer::SetSymolFields(Symbol *aSym, Elf32_Sym* aElfSym, PLUINT32 aCodeIndex) { + + aElfSym->st_other = STV_DEFAULT; + + aElfSym->st_info = (PLUCHAR) (ELF32_ST_INFO(STB_GLOBAL, aSym->CodeDataType())); + aElfSym->st_value = (aCodeIndex - 1)*sizeof(Elf32_Word); + + if(aSym->CodeDataType() == SymbolTypeCode){ + aElfSym->st_size = sizeof(Elf32_Word); + }else{ + aElfSym->st_size = aSym->SymbolSize(); + } + aElfSym->st_shndx = CODE_SECTION; +} + +/** +This function adds an entry into the hash table based on the symbol name. +@internalComponent +@released +@param aSymName The Symbol name +@param aIndex The Symbol index in the Symbol table +*/ +void ElfProducer::AddToHashTable(const char* aSymName, PLUINT32 aIndex) +{ + Elf32_Sword aNullPtr = 0; + + PLULONG aHash = Util::elf_hash((PLUCHAR*)aSymName); + PLUINT32 aBIdx = aHash % iHashTbl->nBuckets; + + if(iDSOBuckets[aBIdx] == aNullPtr) + { + iDSOBuckets[aBIdx] = aIndex; + } + else + { + PLUINT32 aCIdx = iDSOBuckets[aBIdx]; + + while(iDSOChains[aCIdx] != aNullPtr){ + + /* If the entry is already added into the hash table*/ + if((PLUINT32)iDSOChains[aCIdx] == aIndex) { + return; + } + aCIdx = iDSOChains[aCIdx]; + } + iDSOChains[aCIdx] = aIndex; + } +} + +/** +This function creates the different sections of the Elf file +@internalComponent +@released +*/ +void ElfProducer::CreateSections() { + PLUINT32 aIdx = 0; + + //clear the first section... + memset(&iSections[0], 0, sizeof(Elf32_Shdr)); + iDSOSectionNames.insert(iDSOSectionNames.begin(), 0); + + // Set the ELF file offset. + // This indicates the start of sections. + iElfFileOffset = sizeof(Elf32_Ehdr); + + iElfFileOffset += (sizeof(Elf32_Shdr) * iElfHeader->e_shnum); + + //Check if the string table is 4-byte aligned.. + AlignString(iDSOSymNameStrTbl); + + for(aIdx = 1; aIdx <= MAX_SECTIONS; aIdx++) { + switch(aIdx) + { + case SYMBOL_SECTION: + SetSectionFields(aIdx, SECTION_NAME[aIdx], SHT_DYNSYM, \ + sizeof(Elf32_Sym), (iNSymbols * sizeof(Elf32_Sym)),\ + STRING_SECTION, CODE_SECTION, 4, 0, 0); + break; + case STRING_SECTION: + SetSectionFields(aIdx, SECTION_NAME[aIdx], SHT_STRTAB, \ + 1, iDSOSymNameStrTbl.size(), 0, \ + 0, 0, 0,0); + break; + case VERSION_SECTION: + SetSectionFields(aIdx, SECTION_NAME[aIdx], 0x6fffffff, \ + sizeof(Elf32_Half), (iNSymbols * sizeof(Elf32_Half)), SYMBOL_SECTION, \ + 0, 2, 0, 0); + break; + case VER_DEF_SECTION: + SetSectionFields(aIdx, SECTION_NAME[aIdx],0x6ffffffd, \ + sizeof(Elf32_Verdaux), (2*(sizeof(Elf32_Verdef) + sizeof(Elf32_Verdaux))),\ + STRING_SECTION, DYNAMIC_SECTION, 4, 0, 0); + break; + case HASH_TBL_SECTION: + { + PLUINT32 aSize = sizeof(Elf32_HashTable) + \ + (sizeof(Elf32_Sword) * (iHashTbl->nBuckets + iHashTbl->nChains)); + + SetSectionFields(aIdx, SECTION_NAME[aIdx], SHT_HASH, \ + 0, aSize, SYMBOL_SECTION, 0, 4, 0, 0); + } + break; + case DYNAMIC_SECTION: + SetSectionFields(aIdx, SECTION_NAME[aIdx], SHT_DYNAMIC, \ + sizeof(Elf32_Dyn), ((MAX_DYN_ENTS + 1) *sizeof(Elf32_Dyn)),\ + STRING_SECTION, 0, 4, 0,0); + break; + case CODE_SECTION: + SetSectionFields(aIdx, SECTION_NAME[aIdx], SHT_PROGBITS, \ + 0, (iNSymbols *sizeof(PLUINT32)),\ + 0, 0, 4, (SHF_ALLOC | SHF_EXECINSTR),0); + break; + case SH_STR_SECTION: + { + PLUINT32 aSize = iDSOSectionNames.size() + strlen(SECTION_NAME[aIdx]); + SetSectionFields(aIdx, SECTION_NAME[aIdx], SHT_STRTAB, \ + 1, aSize, 0, \ + 0, 0, 0, 0); + //Check if the string table is 4-byte aligned.. + AlignString(iDSOSectionNames); + iSections[aIdx].sh_size = iDSOSectionNames.size(); + + } + break; + default: + break; + } + iSections[aIdx].sh_offset = iElfFileOffset; + iElfFileOffset += iSections[aIdx].sh_size; + + if(iElfFileOffset %4) { + iElfFileOffset += (4 - (iElfFileOffset %4)); + } + } +} + +/** +This function sets the section header fields. +@internalComponent +@released +@return Error status +@param aSectionIndex The index of the section +@param aSectionName The name of the section +@param aType The type of the section +@param aEntSz The size of each entry of the section +@param aSectionSize The size of the section +@param aLink The section this section is linked to +@param aInfo Extra information. Depends on the section type of this section. +@param aAddrAlign The address alignment of this section. +@param aFlags Section flags +@param aAddr The address of this section in memory(Here it remains 0) +*/ +void ElfProducer::SetSectionFields(PLUINT32 aSectionIndex, char* aSectionName, PLUINT32 aType, \ + PLUINT32 aEntSz, PLUINT32 aSectionSize, PLUINT32 aLink, \ + PLUINT32 aInfo, PLUINT32 aAddrAlign, PLUINT32 aFlags, \ + PLUINT32 aAddr) +{ + String aSecName = aSectionName; + + iSections[aSectionIndex].sh_name = iDSOSectionNames.size(); + iDSOSectionNames.insert(iDSOSectionNames.end(), aSecName.begin(), aSecName.end()); + iDSOSectionNames.insert(iDSOSectionNames.end(), 0); + + iSections[aSectionIndex].sh_type = aType; + iSections[aSectionIndex].sh_entsize = aEntSz; + iSections[aSectionIndex].sh_size = aSectionSize; + iSections[aSectionIndex].sh_link = aLink; + iSections[aSectionIndex].sh_flags = aFlags; + iSections[aSectionIndex].sh_addralign = aAddrAlign; + iSections[aSectionIndex].sh_info = aInfo; + iSections[aSectionIndex].sh_addr = aAddr; +} + +/** +This function cleans up the memory allocated to the Elf fields. +@internalComponent +@released +*/ +void ElfProducer::Cleanup() +{ + DELETE_PTR(iElfHeader); + DELETE_PTR_ARRAY(iSections); + DELETE_PTR_ARRAY(iElfDynSym); + DELETE_PTR_ARRAY(iVersionTbl); + DELETE_PTR_ARRAY(iVersionDef); + DELETE_PTR_ARRAY(iDSODaux); + + DELETE_PTR_ARRAY(iProgHeader); + DELETE_PTR_ARRAY(iCodeSectionData); + DELETE_PTR_ARRAY(iHashTbl); + DELETE_PTR_ARRAY(iDSOBuckets); + DELETE_PTR_ARRAY(iDSOChains); +} + +/** +This function creates the dynamic sections. +@internalComponent +@released +*/ +void ElfProducer::CreateDynamicEntries() +{ + for(PLUINT32 aIdx = 0; aIdx <= MAX_DYN_ENTS; aIdx++ ) { + switch(aIdx) { + case DSO_DT_DSONAME: + iDSODynTbl[aIdx].d_tag = DT_SONAME; + iDSODynTbl[aIdx].d_val = iDSONameOffset; + break; + case DSO_DT_SYMTAB: + iDSODynTbl[aIdx].d_tag = DT_SYMTAB; + iDSODynTbl[aIdx].d_val = iSections[SYMBOL_SECTION].sh_offset; + break; + case DSO_DT_SYMENT: + iDSODynTbl[aIdx].d_tag = DT_SYMENT; + iDSODynTbl[aIdx].d_val = iSections[SYMBOL_SECTION].sh_entsize; + break; + case DSO_DT_STRTAB: + iDSODynTbl[aIdx].d_tag = DT_STRTAB; + iDSODynTbl[aIdx].d_val = iSections[STRING_SECTION].sh_offset; + break; + case DSO_DT_STRSZ: + iDSODynTbl[aIdx].d_tag = DT_STRSZ; + iDSODynTbl[aIdx].d_val = iDSOSymNameStrTbl.size(); + break; + case DSO_DT_VERSYM: + iDSODynTbl[aIdx].d_tag = DT_VERSYM; + iDSODynTbl[aIdx].d_val = iSections[VERSION_SECTION].sh_offset; + break; + case DSO_DT_VERDEF: + iDSODynTbl[aIdx].d_tag = DT_VERDEF; + iDSODynTbl[aIdx].d_val = iSections[VER_DEF_SECTION].sh_offset; + break; + case DSO_DT_VERDEFNUM: + iDSODynTbl[aIdx].d_tag = DT_VERDEFNUM; + iDSODynTbl[aIdx].d_val = 2; + break; + case DSO_DT_HASH: + iDSODynTbl[aIdx].d_tag = DT_HASH; + iDSODynTbl[aIdx].d_val = iSections[HASH_TBL_SECTION].sh_offset; + break; + case DSO_DT_NULL: + iDSODynTbl[aIdx].d_tag = DT_NULL; + iDSODynTbl[aIdx].d_val = 0; + break; + default: + break; + } + } +} + +/** +This function creates the Elf header. +@internalComponent +@released +*/ +void ElfProducer::CreateElfHeader() +{ + //create ELF header + unsigned char c[EI_NIDENT] = {0x7f, 'E', 'L', 'F', \ + ELFCLASS32, ELFDATA2LSB, 1, 0, \ + 0, 0, 0, 0, \ + 0, 0, 0, 0}; // e_ident + + for (PLUINT32 i=0; i e_ident[i] = c[i]; + + iElfHeader->e_type = ET_DYN; + iElfHeader->e_machine = EM_ARM; + iElfHeader->e_version = EV_CURRENT; + iElfHeader->e_entry = 0; + iElfHeader->e_shoff = sizeof(Elf32_Ehdr); + iElfHeader->e_flags = EF_ARM_BPABI_VERSION | EF_ARM_SYMSARESORTED; + iElfHeader->e_ehsize = sizeof(Elf32_Ehdr); + iElfHeader->e_phentsize = sizeof(Elf32_Phdr); + iElfHeader->e_shentsize = sizeof(Elf32_Shdr); + iElfHeader->e_shnum = MAX_SECTIONS + 1; + iElfHeader->e_shstrndx = SH_STR_SECTION; + iElfHeader->e_phnum = 2; +} + +/** +This function creates the program header +@internalComponent +@released +*/ +void ElfProducer::CreateProgHeader() +{ + //Update the program header offset.. + iElfHeader->e_phoff = iElfFileOffset; + + // Update code section data.. + SymbolList::iterator aItr = iSymbolsList->begin(); + SymbolList::iterator end = iSymbolsList->end(); + + Symbol *aSym; + PLUINT32 aPos = 0; + while(aItr != end) { + aSym = *aItr; + + iCodeSectionData[aPos] = aSym->OrdNum(); + aItr++;aPos++; + } + + //Create program header + iProgHeader[0].p_align = 4; + iProgHeader[0].p_offset = iSections[CODE_SECTION].sh_offset; + iProgHeader[0].p_type = PT_LOAD; + iProgHeader[0].p_flags = (PF_X | PF_ARM_ENTRY); + iProgHeader[0].p_filesz = iSections[CODE_SECTION].sh_size; + iProgHeader[0].p_paddr = 0; + iProgHeader[0].p_vaddr = 0; + iProgHeader[0].p_memsz = iSections[CODE_SECTION].sh_size; + + iProgHeader[1].p_align = 4; + iProgHeader[1].p_offset = iSections[DYNAMIC_SECTION].sh_offset; + iProgHeader[1].p_type = PT_DYNAMIC; + iProgHeader[1].p_flags = (PF_R ); + iProgHeader[1].p_filesz = iSections[DYNAMIC_SECTION].sh_size; + iProgHeader[1].p_paddr = 0; + iProgHeader[1].p_vaddr = 0; + iProgHeader[1].p_memsz = 0; + +} + +/** +This function aligns the string table to a 4-byte boundary +@internalComponent +@released +@return Error status +@param aStr - string to be aligned +*/ +void ElfProducer::AlignString(String& aStr) { + + if( aStr.size() %4 ){ + PLUCHAR aPad = (PLUCHAR)(4 - (aStr.size() %4)); + + while(aPad--) { + aStr.insert(aStr.end(), 0); + } + } +} + +/** +This function writes the Elf file contents. +@internalComponent +@released +*/ +void ElfProducer::WriteElfContents() +{ + FILE *aElfFd; + PLUINT32 aIndex; + + if((aElfFd = fopen(iDsoFullName.c_str(), "wb")) == NULL ) { + throw FileError(FILEOPENERROR, (char*)iDsoFullName.c_str()); + } + + // The ELF header.. + fwrite(iElfHeader, 1, sizeof(Elf32_Ehdr), aElfFd); + + //Section headers + for(aIndex = 0; aIndex <= MAX_SECTIONS; aIndex++) { + fwrite(&iSections[aIndex], 1, sizeof(Elf32_Shdr), aElfFd); + } + + + //Each section.. + + //code + for(aIndex = 0; aIndex < iNSymbols; aIndex++) { + fwrite(&iCodeSectionData[aIndex], 1, sizeof(PLUINT32), aElfFd ); + } + + //dyn table + for(aIndex = 0; aIndex <= MAX_DYN_ENTS; aIndex++) { + fwrite(&iDSODynTbl[aIndex], 1, sizeof(Elf32_Dyn), aElfFd); + } + + //hash table + fwrite(&iHashTbl->nBuckets, 1, sizeof(Elf32_Word), aElfFd); + fwrite(&iHashTbl->nChains, 1, sizeof(Elf32_Word), aElfFd); + + for(aIndex=0; aIndex < iHashTbl->nBuckets; aIndex++) { + fwrite(&iDSOBuckets[aIndex], 1, sizeof(Elf32_Sword), aElfFd); + + } + for(aIndex=0; aIndex < iHashTbl->nChains; aIndex++) { + fwrite(&iDSOChains[aIndex], 1, sizeof(Elf32_Sword), aElfFd); + + } + + //version def table + for(aIndex = 0; aIndex < 2; aIndex++) { + fwrite(&iVersionDef[aIndex], 1, sizeof(Elf32_Verdef), aElfFd); + fwrite(&iDSODaux[aIndex], 1, sizeof(Elf32_Verdaux), aElfFd); + } + + //version table + for(aIndex = 0; aIndex < iNSymbols; aIndex++) { + fwrite(&iVersionTbl[aIndex], 1, sizeof(Elf32_Half), aElfFd ); + } + + if( iSections[VERSION_SECTION].sh_size %4 ) { + PLUINT32 aNPads = 4 - (iSections[VERSION_SECTION].sh_size %4); + PLUCHAR aPad = '\0'; + while(aNPads--) { + fwrite(&aPad, 1, 1, aElfFd); + } + } + + //string table + PLUINT32 aSz = iDSOSymNameStrTbl.size(); + char *aData = new char[aSz]; + memcpy(aData, iDSOSymNameStrTbl.data(), aSz); + fwrite(aData, 1, aSz, aElfFd); + + DELETE_PTR_ARRAY(aData); + + //Sym table + for(aIndex = 0; aIndex < iNSymbols; aIndex ++) { + fwrite(&iElfDynSym[aIndex], 1, sizeof(Elf32_Sym), aElfFd); + } + + //section header name table + aSz = iDSOSectionNames.size(); + char *aData1 = new char[ aSz]; + memcpy(aData1, iDSOSectionNames.data(), aSz); + fwrite(aData1, 1, aSz, aElfFd); + DELETE_PTR_ARRAY(aData1); + + //program header + for(aIndex = 0; aIndex < 2; aIndex++) { + fwrite(&iProgHeader[aIndex], 1, sizeof(Elf32_Phdr), aElfFd ); + } + + fclose(aElfFd); +} +