diff -r 59148e28d9f6 -r 626366955efb toolsandutils/e32tools/elf2e32/source/e32imagefile.cpp --- a/toolsandutils/e32tools/elf2e32/source/e32imagefile.cpp Fri Jun 25 18:24:47 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1994 +0,0 @@ -// 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 e32 image creation and dump for elf2e32 tool -// @internalComponent -// @released -// -// - -#include "pl_elfexecutable.h" - -// get E32ImageHeader class... -#define INCLUDE_E32IMAGEHEADER_IMPLEMENTATION -#define RETURN_FAILURE(_r) return (fprintf(stderr, "line %d\n", __LINE__),_r) -//#define E32IMAGEHEADER_TRACE(_t) printf _t -#include "e32imagefile.h" - -#include "pl_elfimportrelocation.h" -#include "pl_elflocalrelocation.h" -#include "pl_elfimports.h" -#include "elffilesupplied.h" -#include "pl_dllsymbol.h" -#include "h_ver.h" -#include "checksum.h" -#include "errorhandler.h" - -#include -#include -#include -#include -#ifndef __LINUX__ - #include -#else - #include -#endif -#include -#include - -using namespace std; - -template inline T Align(T v, size_t s) -{ - unsigned int inc = s-1; - unsigned int mask = ~inc; - unsigned int val = (unsigned int)v; - unsigned int res = (val+inc) & mask; - return (T)res; -} - -// Need a default constructor for TVersion, but don't want all the other stuff in h_utl.cpp -/** -Default constructor for TVersion class. -@internalComponent -@released -*/ -TVersion::TVersion(){} - -/** -Constructor for TVersion class. -@internalComponent -@released -*/ -TVersion::TVersion(TInt aMajor, TInt aMinor, TInt aBuild): - iMajor((TInt8)aMajor), iMinor((TInt8)aMinor), iBuild((TInt16)aBuild) -{ -} - - -/** -Constructor for E32ImageChunkDesc class. -@internalComponent -@released -*/ -E32ImageChunkDesc::E32ImageChunkDesc(char * aData, size_t aSize, size_t aOffset, char * aDoc): - iData(aData), iSize(aSize), iOffset(aOffset), iDoc(aDoc) -{ -} - -/** -Destructor for E32ImageChunkDesc class. -@internalComponent -@released -*/ -E32ImageChunkDesc::~E32ImageChunkDesc() -{ -} - -/** -This function writes its data in the buffer. -@param aPlace - a location in the buffer -@internalComponent -@released -*/ -void E32ImageChunkDesc::Write(char * aPlace) -{ - memcpy(aPlace+iOffset, iData, iSize); -} - -/** -Constructor for E32ImageChunks class. -@internalComponent -@released -*/ -E32ImageChunks::E32ImageChunks(): - iOffset(0) -{ -} - -/** -Destructor for E32ImageChunks class. -@internalComponent -@released -*/ -E32ImageChunks::~E32ImageChunks() -{ - if(iChunks.size()) - { - ChunkList::iterator aItr = iChunks.begin(); - ChunkList::iterator last = iChunks.end(); - E32ImageChunkDesc *temp; - - while( aItr != last) - { - temp = *aItr; - aItr++; - delete temp; - } - } -} - -/** -This function creates and adds a chunk into a list. -@param aData - input buffer -@param asize - size of the input buffer -@param aOffset - byte offset of this chunk from the 1 byte in e32 image file. -@param aDoc - name of the chunk -@internalComponent -@released -*/ -void E32ImageChunks::AddChunk(char * aData, size_t aSize, size_t aOffset, char * aDoc) -{ - E32ImageChunkDesc * aChunk = new E32ImageChunkDesc(aData, aSize, aOffset, aDoc); - iChunks.push_back(aChunk); - iOffset += Align(aSize, sizeof(TUint32)); -} - -/** -This function returns the list of chunks. -@internalComponent -@released -*/ -E32ImageChunks::ChunkList & E32ImageChunks::GetChunks() -{ - return iChunks; -} - -/** -This function returns the current offset pointing to the last chunk that -was added into the list of chunks. -@internalComponent -@released -*/ -size_t E32ImageChunks::GetOffset() -{ - return iOffset; -} - -/** -This function sets the current offset pointing to the last chunk that -was added into the list of chunks. -@internalComponent -@released -*/ -void E32ImageChunks::SetOffset(size_t aOffset) -{ - iOffset = aOffset; -} - -/** -Constructor for E32ImageFile class. -@internalComponent -@released -*/ -E32ImageFile::E32ImageFile(const char * aFileName, ElfExecutable * aExecutable, ElfFileSupplied *aUseCase) : - iFileName(aFileName), - iE32Image(0), - iExportBitMap(0), - iElfExecutable(aExecutable), - iData(0), - iUseCase(aUseCase), - iHdr(0), - iHdrSize(sizeof(E32ImageHeaderV)), - iImportSection(0), - iImportSectionSize(0), - iCodeRelocs(0), - iCodeRelocsSize(0), - iDataRelocs(0), - iDataRelocsSize(0), - iExportOffset(0), - iLayoutDone(false), - iMissingExports(0), - iSymNameOffset(0) -{ -} - -/** -This function generates the E32 image. -@internalComponent -@released -*/ -void E32ImageFile::GenerateE32Image() -{ - if( iUseCase->GetNamedSymLookup() ){ - ProcessSymbolInfo(); - } - ProcessImports(); - ProcessRelocations(); - ConstructImage(); -} - -/** -This function processes the import map by looking into the dso files -from which the symbols are imported. It also fetches the ordinal numbers -for the corresponding symbols. -@internalComponent -@released -*/ -void E32ImageFile::ProcessImports() -{ - string aStrTab; - vector aStrTabOffsets; - int aNumDlls = 0; - int aNumImports = 0; - bool aNamedLookup = iUseCase->GetNamedSymLookup(); - TUint aImportTabEntryPos = 0; - - ElfImports::ImportMap aImportMap = iElfExecutable->GetImports(); - ElfImports::ImportMap::iterator p; - - // First set up the string table and record offsets into string table of each - // LinkAs name. - for (p = aImportMap.begin(); p != aImportMap.end(); p++) - { - ElfImports::RelocationList & aImports = (*p).second; - char* aLinkAs = aImports[0]->iVerRecord->iLinkAs; - - aStrTabOffsets.push_back(aStrTab.size()); // - string s = aLinkAs; - aStrTab.insert(aStrTab.end(),s.begin(),s.end()); - aStrTab.insert(aStrTab.end(),0); - aNumDlls++; - aNumImports += aImports.size(); - } - - iNumDlls = aNumDlls; - iNumImports = aNumImports; - - // Now we can figure out the size of everything - size_t aImportSectionSize = sizeof(E32ImportSection) + - (sizeof(E32ImportBlock) * aNumDlls) + - (sizeof(unsigned int) * aNumImports); - - vector aImportSection; - - // This is the 'E32ImportSection' header - fill with 0 for the moment - aImportSection.push_back(0); - - if( aNamedLookup ) { - // These are the 0th ordinals imported into the import table, one - // entry for each DLL. - aImportSectionSize += (sizeof(unsigned int) * aNumDlls); - } - // Now fill in the E32ImportBlocks - int idx = 0; - char * aDsoName; - for (p = aImportMap.begin(); p != aImportMap.end(); p++, idx++) - { - ElfImports::RelocationList & aImports = (*p).second; - aDsoName = aImports[0]->iVerRecord->iSOName; - - //const char * aDSO = FindDSO((*p).first); - const char * aDSO = FindDSO(aDsoName); - - aImportSection.push_back(aStrTabOffsets[idx] + aImportSectionSize); - int nImports = aImports.size(); - - // Take the additional 0th ordinal import into account - if( aNamedLookup ) - nImports++; - aImportSection.push_back(nImports); - - size_t aSize; - Elf32_Ehdr * aElfFile = 0; - ReadInputELFFile(aDSO, aSize, aElfFile); - - ElfExecutable aElfExecutable(NULL);//(aElfFile, aSize); - aElfExecutable.ProcessElfFile(aElfFile); - - ElfImports::RelocationList::iterator q; - for (q = aImports.begin(); q != aImports.end(); q++) - { - ElfImportRelocation * aReloc = *q; - char * aSymName = iElfExecutable->GetSymbolName(aReloc->iSymNdx); - unsigned int aOrdinal = aElfExecutable.GetSymbolOrdinal(aSymName); - - //check the reloc refers to Code Segment - try - { - if (iElfExecutable->SegmentType(aReloc->iAddr) != ESegmentRO) - { - throw ImportRelocationError(ILLEGALEXPORTFROMDATASEGMENT, aSymName, iElfExecutable->iParameterListInterface->ElfInput()); - } - } - /**This catch block introduced here is to avoid deleting partially constructed object(s). - Otherwise global catch block will delete the partially constructed object(s) and the tool will crash. - */ - catch(ErrorHandler& aError) - { - aError.Report(); - exit(EXIT_FAILURE); - } - - Elf32_Word aRelocOffset = iElfExecutable->GetRelocationOffset(aReloc); - aImportSection.push_back(aRelocOffset); - - Elf32_Word * aRelocPlace = iElfExecutable->GetRelocationPlace(aReloc); - if (aOrdinal > 0xFFFF) - { - } - if (aReloc->iAddend > 0xFFFF) - { - } - * aRelocPlace = (aReloc->iAddend<<16) | aOrdinal; - } - - if( aNamedLookup ) { - aImportTabEntryPos = aImportSection.size(); - // Keep track of the location of the entry - iImportTabLocations.push_back(aImportTabEntryPos); - // Put the entry as 0 now, which shall be updated - aImportSection.push_back(0); - } - - delete [] ((char*)aElfFile); - } - - assert(aImportSectionSize == aImportSection.size() * sizeof(Elf32_Word)); - - size_t aTotalSize = Align(aImportSectionSize + aStrTab.size(), sizeof(Elf32_Word)); - - // Fill in the section header now we have the correct value. - aImportSection[0] = aTotalSize; - - // Now construct the unified section - iImportSectionSize = aTotalSize; - iImportSection = (uint32 *)new char[aTotalSize]; - memset(iImportSection, 0, aTotalSize); - memcpy(iImportSection, aImportSection.begin(), aImportSectionSize); - char * strTab = ((char *)iImportSection) + aImportSectionSize; - memcpy(strTab, aStrTab.data(), aStrTab.size()); - -} - - -/** -This function checks if a DSO file exists. -@param aPath - DSO file name. -@internalComponent -@released -*/ -static bool ProbePath(string & aPath) -{ - ifstream aInput; - const char * p = aPath.c_str(); - aInput.open(p); - if (aInput.is_open()) - { - aInput.close(); - return true; - } - else - { - return false; - } -} - -/** -This function allocates space for a DSO file name. -@param aPath - DSO file name -@internalComponent -@released -*/ -const char * AllocatePath(string & aPath) -{ - const char * p = aPath.c_str(); - size_t len = aPath.size(); - char * result = new char[len+1]; - strcpy(result, p); - return (const char *)result; -} - -/** -This function searches for a DSO in the libpath specified. -@param aName - DSO file name -@internalComponent -@released -*/ -const char * E32ImageFile::FindDSO(const char * aName) -{ - string aDSOName(aName); - string aDSOPath(aName); - - const char *aNewDsoName; - - if (ProbePath(aDSOName)) - { - aNewDsoName = AllocatePath(aDSOName); - cleanupStack.push_back((char*)aNewDsoName); - return aNewDsoName; - } - - ParameterListInterface::LibSearchPaths & paths = iUseCase->GetLibSearchPaths(); - ParameterListInterface::LibSearchPaths::iterator p = paths.begin(); - for (; p != paths.end(); p++) - { - string path(*p); - char dir = iUseCase->GetDirectorySeparator(); - aDSOPath.erase(); - aDSOPath.insert(aDSOPath.end(), path.begin(), path.end()); - aDSOPath.insert(aDSOPath.end(), dir); - aDSOPath.insert(aDSOPath.end(), aDSOName.begin(), aDSOName.end()); - if (ProbePath(aDSOPath)) - { - aNewDsoName = AllocatePath(aDSOPath); - cleanupStack.push_back((char*)aNewDsoName); - return aNewDsoName; - } - } - throw ELFFileError(DSONOTFOUNDERROR,(char*)aName); -} - -void E32ImageFile::ReadInputELFFile(const char * aName, size_t & aFileSize, Elf32_Ehdr * & aELFFile ) -{ - ifstream aInput; - aInput.open(aName, ifstream::binary|ifstream::in); - if (aInput.is_open()) - { - aInput.seekg(0,ios::end); - aFileSize = (unsigned int) aInput.tellg(); - aInput.seekg(0,ios::beg); - aELFFile = (Elf32_Ehdr *)new char [aFileSize]; - aInput.read((char *)aELFFile, aFileSize); - aInput.close(); - } - else - { - throw FileError(FILEOPENERROR,(char*)aName); - } -} - -/** -This function processes relocations. -@internalComponent -@released -*/ -void E32ImageFile::ProcessRelocations() -{ - ProcessCodeRelocations(); - ProcessDataRelocations(); -} - -/** -This function processes Code relocations. -@internalComponent -@released -*/ -void E32ImageFile::ProcessCodeRelocations() -{ - CreateRelocations(iElfExecutable->GetCodeRelocations(), iCodeRelocs, iCodeRelocsSize); -} - -/** -This function processes Data relocations. -@internalComponent -@released -*/ -void E32ImageFile::ProcessDataRelocations() -{ - CreateRelocations(iElfExecutable->GetDataRelocations(), iDataRelocs, iDataRelocsSize); -} - -/** -This function creates Code and Data relocations from the corresponding -ELF form to E32 form. -@internalComponent -@released -*/ -void E32ImageFile::CreateRelocations(ElfRelocations::RelocationList & aRelocList, char * & aRelocs, size_t & aRelocsSize) -{ - size_t rsize = RelocationsSize(aRelocList); - if (rsize) - { - aRelocsSize = Align(rsize + sizeof(E32RelocSection), sizeof(uint32)); - - uint32 aBase = (*aRelocList.begin())->iSegment->p_vaddr; - //add for cleanup to be done later.. - cleanupStack.push_back(aRelocs); - aRelocs = new char [aRelocsSize]; - memset(aRelocs, 0, aRelocsSize); - E32RelocSection * aRelocSection = (E32RelocSection * )aRelocs; - - uint16 * data = (uint16 *)(aRelocSection + 1); - E32RelocPageDesc * startofblock = (E32RelocPageDesc *)data; - - int page = -1; - int pagesize = sizeof(E32RelocPageDesc); - ElfRelocations::RelocationList::iterator r; - for (r = aRelocList.begin(); r != aRelocList.end(); r++) - { - ElfLocalRelocation * aReloc = *r; - int p = aReloc->iAddr & 0xfffff000; - if (page != p) - { - if (pagesize%4 != 0) - { - *data++ = 0; - pagesize += sizeof(uint16); - } - if (page == -1) page = p; - startofblock->aOffset = page - aBase; - startofblock->aSize = pagesize; - pagesize = sizeof(E32RelocPageDesc); - page = p; - startofblock = (E32RelocPageDesc *)data; - data = (uint16 *)(startofblock + 1); - } - uint16 relocType = aReloc->Fixup(); - *data++ = (uint16)((aReloc->iAddr & 0xfff) | relocType); - pagesize += sizeof(uint16); - } - if (pagesize%4 != 0) - { - *data++ = 0; - pagesize += sizeof(uint16); - } - startofblock->aOffset = page - aBase; - startofblock->aSize = pagesize; - ((E32RelocSection *)aRelocs)->iNumberOfRelocs = aRelocList.size(); - ((E32RelocSection *)aRelocs)->iSize = rsize; - - } -} - -/** -This function calculates the relocation taking into consideration -the page boundaries if they are crossed. The relocations are -sorted. -@param aRelocList - relocations found in the Elf file. -@internalComponent -@released -*/ -size_t E32ImageFile::RelocationsSize(ElfRelocations::RelocationList & aRelocList) -{ - size_t bytecount = 0; - int page = -1; - ElfRelocations::RelocationList::iterator r; - for (r = aRelocList.begin(); r != aRelocList.end(); r++) - { - ElfLocalRelocation * aReloc = *r; - int p = aReloc->iAddr & 0xfffff000; - if (page != p) - { - if (bytecount%4 != 0) - bytecount += sizeof(uint16); - bytecount += sizeof(E32RelocPageDesc); // page, block size - page = p; - } - bytecount += sizeof(uint16); - } - if (bytecount%4 != 0) - bytecount += sizeof(uint16); - return bytecount; -} - -/** -This function returns the E32 interpretation for an Elf relocation type. -@param aReloc - relocation entry. -@internalComponent -@released -*/ -E32ImageFile::uint16 E32ImageFile::GetE32RelocType(ElfRelocation * aReloc) -{ - ESegmentType aSegType = aReloc->iSegmentType; // iElfExecutable->SegmentType(aReloc->iSymbol->st_value); - switch (aSegType) - { - case ESegmentRO: - return KTextRelocType; - case ESegmentRW: - return KDataRelocType; - default: - break; - }; - - // maybe this should be an error - return KInferredRelocType; -} - -/** -This function constructs the E32 image. -@internalComponent -@released -*/ -void E32ImageFile::ConstructImage() -{ - InitE32ImageHeader(); - ComputeE32ImageLayout(); - FinalizeE32Image(); - AllocateE32Image(); -} - -/** -This function calculates the timestamp. -@param aTime -@internalComponent -@released -*/ -Int64 timeToInt64(TInt aTime) -{ - aTime-=(30*365*24*60*60+7*24*60*60); // seconds since midnight Jan 1st, 2000 - Int64 daysTo2000AD=730497; - Int64 t=daysTo2000AD*24*3600+aTime; // seconds since 0000 - t=t+3600; // BST (?) - return t*1000000; // milliseconds -} - -/** -This function returns the E32 image header size. -@internalComponent -@released -*/ -size_t E32ImageFile::GetE32ImageHeaderSize() -{ - return sizeof(E32ImageHeaderV); -} - -/** -This function returns the extended E32 image header size. -@internalComponent -@released -*/ -size_t E32ImageFile::GetExtendedE32ImageHeaderSize() -{ - return iHdrSize; -} - -/** -This function sets the extended E32 image header size. -@internalComponent -@released -*/ -void E32ImageFile::SetExtendedE32ImageHeaderSize(size_t aSize) -{ - iHdrSize = aSize; -} - -/** -This function initialises the E32 image header fields. -@internalComponent -@released -*/ -void E32ImageFile::InitE32ImageHeader() -{ - iHdr = iUseCase->AllocateE32ImageHeader(); - - iHdr->iUid1 = 0; - iHdr->iUid2 = 0; - iHdr->iUid3 = 0; - iHdr->iHeaderCrc = 0; - iHdr->iSignature = 0x434f5045u; - iHdr->iModuleVersion = 0x00010000u; - iHdr->iCompressionType = 0; - iHdr->iToolsVersion = TVersion(MajorVersion, MinorVersion, Build); - Int64 ltime(timeToInt64(time(0))); - iHdr->iTimeLo=(uint32)ltime; - iHdr->iTimeHi=(uint32)(ltime>>32); - iHdr->iFlags = KImageHdrFmt_V; - // Confusingly, CodeSize means everything except writable data - iHdr->iCodeSize = 0; - iHdr->iDataSize = iElfExecutable->GetRWSize(); - iHdr->iHeapSizeMin = 0; - iHdr->iHeapSizeMax = 0; - iHdr->iStackSize = 0; - iHdr->iBssSize = iElfExecutable->GetBssSize(); - iHdr->iEntryPoint = 0; - iHdr->iCodeBase = iElfExecutable->GetROBase(); - iHdr->iDataBase = iElfExecutable->GetRWBase(); - iHdr->iDllRefTableCount = iNumDlls; - iHdr->iExportDirOffset = 0; - iHdr->iExportDirCount = iUseCase->GetNumExports(); - iHdr->iTextSize = iElfExecutable->GetROSize(); - iHdr->iCodeOffset = 0; - iHdr->iDataOffset = 0; - iHdr->iImportOffset = 0; - iHdr->iCodeRelocOffset = 0; - iHdr->iDataRelocOffset = 0; - iHdr->iProcessPriority = (uint16)EPriorityForeground; - iHdr->iUncompressedSize = 0; - iHdr->iS.iSecureId = 0; - iHdr->iS.iVendorId = 0; - iHdr->iExceptionDescriptor = 0; - iHdr->iSpare2 = 0; - - iHdr->iExportDescSize = iUseCase->GetExportDescSize(); - iHdr->iExportDescType = iUseCase->GetExportDescType(); - if (iHdr->iExportDescSize == 0) iHdr->iExportDesc[0] = 0; - -} - -/** -This function creates the E32 image layout. -@internalComponent -@released -*/ -void E32ImageFile::ComputeE32ImageLayout() -{ - // E32Image header - iChunks.AddChunk((char *)iHdr, Align(GetExtendedE32ImageHeaderSize(), sizeof(uint32)), 0, "Image Header"); - - uint32 endOfHeader = iChunks.GetOffset(); - - // Code section - iHdr->iCodeOffset = iChunks.GetOffset(); - iChunks.AddChunk(iElfExecutable->GetRawROSegment(), iElfExecutable->GetROSize(), iHdr->iCodeOffset, "Code Section"); - - // Exports Next - then we can set up CodeSize - // Call out to the use case so it can decide how we do this - // record exporttable offset for default case - - bool aSymLkupEnabled = iUseCase->GetNamedSymLookup(); - // The export table is required either when: - // a. there are exported symbols - // b. symbol lookup is enabled - because this table also indicates the dependencies - bool aExportTableNeeded = (iHdr->iExportDirCount || aSymLkupEnabled) ? 1 : 0; - - iExportOffset = iChunks.GetOffset() + 4; - iHdr->iExportDirOffset = aExportTableNeeded ? iUseCase->GetExportOffset() : 0; - if ( aExportTableNeeded && iUseCase->AllocateExportTableP()) - iChunks.AddChunk(iUseCase->GetExportTable(), iUseCase->GetExportTableSize(), iChunks.GetOffset(), "Export Table"); - - // Symbol info next - if( aSymLkupEnabled ){ - E32EpocExpSymInfoHdr* aSymHdrInfo = (E32EpocExpSymInfoHdr*)CreateSymbolInfo(iChunks.GetOffset()); - if( aSymHdrInfo ) - iChunks.AddChunk( (char*)aSymHdrInfo, aSymHdrInfo->iSize, iChunks.GetOffset(), "Symbol Info" ); - } - - // CodeSize is current offset - endof header offset - iHdr->iTextSize = iHdr->iCodeSize = iChunks.GetOffset() - endOfHeader; - - // Data section - if (iElfExecutable->GetRWSize()) - { - iHdr->iDataOffset = iChunks.GetOffset(); - iChunks.AddChunk(iElfExecutable->GetRawRWSegment(), iElfExecutable->GetRWSize(), iHdr->iDataOffset, "Data Section"); - } - - // Import Section - if (iImportSectionSize) - { - iHdr->iImportOffset = iChunks.GetOffset(); - iChunks.AddChunk((char *)iImportSection, iImportSectionSize, iHdr->iImportOffset, "Import Section"); - } - - // Code relocs - if (iCodeRelocsSize) - { - iHdr->iCodeRelocOffset = iChunks.GetOffset(); - iChunks.AddChunk((char *)iCodeRelocs, iCodeRelocsSize, iHdr->iCodeRelocOffset, "Code Relocs"); - } - - // Data relocs - if (iDataRelocsSize) - { - iHdr->iDataRelocOffset = iChunks.GetOffset(); - iChunks.AddChunk((char *)iDataRelocs, iDataRelocsSize, iHdr->iDataRelocOffset, "Data Relocs"); - } - - iLayoutDone = true; -} - -/** -This function returns the byte offset in the E32 image from where the -export table starts. -@internalComponent -@released -*/ -size_t E32ImageFile::GetExportOffset() -{ - return iExportOffset; -} - -/** -This function returns E32 image size. -@internalComponent -@released -*/ -size_t E32ImageFile::GetE32ImageSize() -{ - assert(iLayoutDone); - return iChunks.GetOffset(); - -} - -/** -This function creates the export bitmap also replacing the absent symbols -with the entry point functions. -@internalComponent -@released -*/ -void E32ImageFile::CreateExportBitMap() -{ - int nexp = iUseCase->GetNumExports(); - size_t memsz = (nexp + 7) >> 3; - iExportBitMap = new uint8[memsz]; - memset(iExportBitMap, 0xff, memsz); - // skip header - uint32 * exports = ((uint32 *)iUseCase->GetExportTable()) + 1; - uint32 absentVal = EntryPointOffset() + iElfExecutable->GetROBase(); - iMissingExports = 0; - for (int i=0; i>3] &= ~(1u << (i & 7)); - ++iMissingExports; - } - } -} - -/** -This function creates export desription for the absent symbols. -@internalComponent -@released -*/ -void E32ImageFile::AddExportDescription() -{ - CreateExportBitMap(); - if (iMissingExports == 0) - return; // nothing to do - - int nexp = iUseCase->GetNumExports(); - size_t memsz = (nexp + 7) >> 3; // size of complete bitmap - size_t mbs = (memsz + 7) >> 3; // size of meta-bitmap - size_t nbytes = 0; - unsigned int i; - for (i=0; iiExportDescType = edt; - if (edt == KImageHdr_ExpD_FullBitmap) - { - iHdr->iExportDescSize = (uint16)memsz; - iHdr->iExportDesc[0] = iExportBitMap[0]; - uint8 * aDesc = new uint8[extra_space]; - memset(aDesc, 0, extra_space); - memcpy(aDesc, &iExportBitMap[1], memsz-1); - iChunks.AddChunk((char *)aDesc,extra_space, iChunks.GetOffset(), "Export Description"); - } - else - { - iHdr->iExportDescSize = (uint16)(mbs + nbytes); - uint8 * aBuf = new uint8[extra_space + 1]; - memset(aBuf , 0, extra_space + 1); - TUint8* mptr = aBuf; - TUint8* gptr = mptr + mbs; - for (i=0; i>3] |= (1u << (i&7)); - *gptr++ = iExportBitMap[i]; - } - } - iHdr->iExportDesc[0] = aBuf[0]; - uint8 * aDesc = new uint8[extra_space]; - memcpy(aDesc, aBuf+1, extra_space); - delete[] aBuf; - iChunks.AddChunk((char *)aDesc,extra_space, iChunks.GetOffset(), "Export Description"); - } -} - -/** -This function sets the fields of the E32 image. -@internalComponent -@released -*/ -void E32ImageFile::FinalizeE32Image() -{ - // Arrange a header for this E32 Image - iHdr->iCpuIdentifier = GetCpuIdentifier(); - // Import format is ELF-derived - iHdr->iFlags |= KImageImpFmt_ELF; - // ABI is ARM EABI - iHdr->iFlags |= KImageABI_EABI; - iHdr->iFlags |= KImageEpt_Eka2; - - bool isDllp = iUseCase->ImageIsDll(); - if (isDllp) - { - iHdr->iFlags |= KImageDll; - if (iHdr->iDataSize && !iUseCase->AllowDllData()) - throw ELFFileError(DLLHASINITIALISEDDATAERROR, (char*)iUseCase->InputElfFileName()); - - if (iHdr->iBssSize && !iUseCase->AllowDllData()) - throw ELFFileError(DLLHASUNINITIALISEDDATAERROR, (char*)iUseCase->InputElfFileName()); - - } - - iHdr->iHeapSizeMin = iUseCase->HeapCommittedSize(); - iHdr->iHeapSizeMax = iUseCase->HeapReservedSize(); - iHdr->iStackSize = iUseCase->StackCommittedSize(); - - - iHdr->iEntryPoint = EntryPointOffset(); - - EEntryPointStatus r = ValidateEntryPoint(); - if (r == EEntryPointCorrupt) - throw ELFFileError(ENTRYPOINTCORRUPTERROR, (char*)iUseCase->InputElfFileName()); - else if (r == EEntryPointNotSupported) - throw ELFFileError(ENTRYPOINTNOTSUPPORTEDERROR, (char*)iUseCase->InputElfFileName()); - - SetUpExceptions(); - SetUids(); - SetSecureId(); - SetVendorId(); - SetCallEntryPoints(); - SetCapability(); - SetPriority(isDllp); - SetFixedAddress(isDllp); - SetVersion(); - SetCompressionType(); - SetFPU(); - - SetPaged(); - - SetSymbolLookup(); - SetDebuggable(); - SetSmpSafe(); - UpdateHeaderCrc(); -} - -/** -This function returns the CPU identifier for the E32 image header. -@internalComponent -@released -*/ -E32ImageFile::uint16 E32ImageFile::GetCpuIdentifier() -{ - return (uint16)ECpuArmV5; -} - -/** -This function returns the entry point of the E32 image . -@internalComponent -@released -*/ -E32ImageFile::uint32 E32ImageFile::EntryPointOffset() -{ - return iElfExecutable->EntryPointOffset(); -} - -/** -This function validates the entry point of the E32 image . -@internalComponent -@released -*/ -E32ImageFile::EEntryPointStatus E32ImageFile::ValidateEntryPoint() -{ - uint32 epOffset = iHdr->iEntryPoint; - if (epOffset & 3) - return EEntryPointOK; // if entry point not 4 byte aligned, must be old style - uint32 fileOffset = epOffset + iElfExecutable->iCodeSegmentHdr->p_offset; - if (fileOffset+4 > iChunks.GetOffset()) - return EEntryPointCorrupt; // entry point is past the end of the file?? - int ept = 0; // old style if first instruction not recognised - uint8 * p = ELF_ENTRY_PTR(uint8, iElfExecutable->iElfHeader, fileOffset + 4); - uint32 x = *--p; - x<<=8; - x|=*--p; - x<<=8; - x|=*--p; - x<<=8; - x|=*--p; - if ((x & 0xffffff00) == 0xe31f0000) - { - // starts with tst pc, #n - new entry point - ept = (x & 0xff) + 1; - } - if (ept>7) - return EEntryPointNotSupported; - iHdr->iFlags |= (ept<LookupStaticSymbol(aExDescName); - if (aSym) - { - uint32 aSymVaddr = aSym->st_value; - uint32 aROBase = iElfExecutable->GetROBase(); - uint32 aROSize = iElfExecutable->GetROSize(); - //check its in RO segment - if (aSymVaddr < aROBase || aSymVaddr >= (aROBase + aROSize)) - { - throw ELFFileError(EXCEPTIONDESCRIPTOROUTSIDEROERROR,(char*)iUseCase->InputElfFileName()); - } - // Set bottom bit so 0 in header slot means an old binary. - // The decriptor is always aligned on a 4 byte boundary. - iHdr->iExceptionDescriptor = (aSymVaddr - aROBase) | 0x00000001; - } -} - -/** -This function sets the UIDs of the E32 image . -@internalComponent -@released -*/ -void E32ImageFile::SetUids() -{ - iHdr->iUid1=iUseCase->GetUid1(); - iHdr->iUid2=iUseCase->GetUid2(); - iHdr->iUid3=iUseCase->GetUid3(); -} - -/** -This function sets the secure ID of the E32 image as passed in the command line. -@internalComponent -@released -*/ -void E32ImageFile::SetSecureId() -{ - if (iUseCase->GetSecureIdOption()) - iHdr->iS.iSecureId = iUseCase->GetSecureId(); - else - iHdr->iS.iSecureId = iUseCase->GetUid3(); -} - -/** -This function sets the vendor Id of the E32 image as passed in command line. -@internalComponent -@released -*/ -void E32ImageFile::SetVendorId() -{ - iHdr->iS.iVendorId = iUseCase->GetVendorId(); -} - -/** -This function sets the call entry point of the E32 image . -@internalComponent -@released -*/ -void E32ImageFile::SetCallEntryPoints() -{ - if (iUseCase->GetCallEntryPoints()) - iHdr->iFlags|=KImageNoCallEntryPoint; - else - iHdr->iFlags&=~KImageNoCallEntryPoint; -} - -/** -This function sets the capcbility of the E32 image as specified in the command line. -@internalComponent -@released -*/ -void E32ImageFile::SetCapability() -{ - iHdr->iS.iCaps = iUseCase->GetCapability(); -} - -/** -This function sets the priority of the E32 exe. -@internalComponent -@released -*/ -void E32ImageFile::SetPriority(bool isDllp) -{ - if (iUseCase->GetPriority()) - { - if (isDllp) - { - cerr << "Warning: Cannot set priority of a DLL." << endl; - } - else - iHdr->iProcessPriority = (unsigned short)iUseCase->GetPriority(); - } -} - -/** -This function sets the fixed address flag of the E32 image . -@internalComponent -@released -*/ -void E32ImageFile::SetFixedAddress(bool isDllp) -{ - if (iUseCase->GetFixedAddress()) - { - if (isDllp) - { - cerr << "Warning: Cannot set fixed address for DLL." << endl; - } - else - iHdr->iFlags|=KImageFixedAddressExe; - } - else - iHdr->iFlags&=~KImageFixedAddressExe; -} - -/** -This function sets the version of the E32 image . -@internalComponent -@released -*/ -void E32ImageFile::SetVersion() -{ - iHdr->iModuleVersion = iUseCase->GetVersion(); -} - -/** -This function sets the compression type of the E32 image . -@internalComponent -@released -*/ -void E32ImageFile::SetCompressionType() -{ - if(iUseCase->GetCompress()) - iHdr->iCompressionType = iUseCase->GetCompressionMethod(); - else - iHdr->iCompressionType = KFormatNotCompressed; - -} - -/** -This function sets the FPU type that the E32 image targets . -@internalComponent -@released -*/ -void E32ImageFile::SetFPU() -{ - iHdr->iFlags &=~ KImageHWFloatMask; - - if (iUseCase->GetFPU() == 1) - iHdr->iFlags |= KImageHWFloat_VFPv2; -} - -/** -This function sets the paging attribute in the E32 image. -@internalComponent -@released -*/ -void E32ImageFile::SetPaged() -{ - // Code paging. - - if ( iUseCase->IsCodePaged() ) - { - iHdr->iFlags |= KImageCodePaged; - iHdr->iFlags &= ~KImageCodeUnpaged; - } - else if ( iUseCase->IsCodeUnpaged() ) - { - iHdr->iFlags |= KImageCodeUnpaged; - iHdr->iFlags &= ~KImageCodePaged; - } - else if ( iUseCase->IsCodeDefaultPaged() ) - { - iHdr->iFlags &= ~KImageCodePaged; - iHdr->iFlags &= ~KImageCodeUnpaged; - } - - // Data paging. - - if ( iUseCase->IsDataPaged() ) - { - iHdr->iFlags |= KImageDataPaged; - iHdr->iFlags &= ~KImageDataUnpaged; - } - else if ( iUseCase->IsDataUnpaged() ) - { - iHdr->iFlags |= KImageDataUnpaged; - iHdr->iFlags &= ~KImageDataPaged; - } - else if ( iUseCase->IsDataDefaultPaged() ) - { - iHdr->iFlags &= ~KImageDataPaged; - iHdr->iFlags &= ~KImageDataUnpaged; - } -} - -/** -This function sets the Debuggable attribute in the E32 image. -@internalComponent -@released -*/ -void E32ImageFile::SetDebuggable() -{ - if (iUseCase->IsDebuggable() == true) - { - iHdr->iFlags |= KImageDebuggable; - } - else - { - iHdr->iFlags &= ~KImageDebuggable; - } -} - - -void E32ImageFile::SetSmpSafe() -{ - if ( iUseCase->IsSmpSafe() ) - { - iHdr->iFlags |= KImageSMPSafe; - } - else - { - iHdr->iFlags &= ~KImageSMPSafe; - } -} - -/** -This function sets the named symol-lookup attribute in the E32 image. -@internalComponent -@released -*/ -void E32ImageFile::SetSymbolLookup() -{ - if(iUseCase->GetNamedSymLookup()) - { - iHdr->iFlags |= KImageNmdExpData; - } - else - { - iHdr->iFlags &= ~KImageNmdExpData; - } -} - -/** -Class for Uids. -@internalComponent -@released -*/ -class TE32ImageUids -{ -public: - TE32ImageUids(TUint32 aUid1, TUint32 aUid2, TUint32 aUid3); - void Set(const TUidType& aUidType); - TUint Check() { return ((checkSum(((TUint8*)this)+1)<<16)|checkSum(this));} -private: - TUidType iType; - TUint iCheck; - -}; - -/** -Constructor for TE32ImageUids. -@internalComponent -@released -*/ -TE32ImageUids::TE32ImageUids(TUint32 aUid1, TUint32 aUid2, TUint32 aUid3) -{ - Set(TUidType(TUid::Uid(aUid1), TUid::Uid(aUid2), TUid::Uid(aUid3))); -} - -/** -This function sets the Uid. -@internalComponent -@released -*/ -void TE32ImageUids::Set(const TUidType& aUidType) -{ - iType=aUidType; - iCheck=Check(); -} - -/** -Default constructor for TUidType class. -@internalComponent -@released -*/ -TUidType::TUidType() -{ - memset(this, 0, sizeof(TUidType)); -} - -/** -Constructor for TUidType class. -@internalComponent -@released -*/ -TUidType::TUidType(TUid aUid1,TUid aUid2,TUid aUid3) -{ - iUid[0]=aUid1; - iUid[1]=aUid2; - iUid[2]=aUid3; -} - -// needed by E32ImageHeaderV::ValidateHeader... -TCheckedUid::TCheckedUid(const TUidType& aUidType) - { - iType = aUidType; - iCheck = ((TE32ImageUids*)this)->Check(); - } - -// needed by E32ImageHeaderV::ValidateHeader... -void Mem::Crc32(TUint32& aCrc, const TAny* aPtr, TInt aLength) - { - ::Crc32(aCrc, aPtr, aLength); - } - -/** -This function updates the CRC of the E32 Image. -@internalComponent -@released -*/ -void E32ImageFile::UpdateHeaderCrc() -{ - TE32ImageUids u(iHdr->iUid1, iHdr->iUid2, iHdr->iUid3); - iHdr->iUidChecksum = u.Check(); - TInt hdrsz = GetExtendedE32ImageHeaderSize(); - iHdr->iUncompressedSize = iChunks.GetOffset() - Align(GetExtendedE32ImageHeaderSize(), sizeof(uint32)); - iHdr->iHeaderCrc = KImageCrcInitialiser; - uint32 crc = 0; - Crc32(crc, iHdr, hdrsz); - iHdr->iHeaderCrc = crc; -} - -/** -This function creates a buffer and writes all the data into the buffer. -@internalComponent -@released -*/ -void E32ImageFile::AllocateE32Image() -{ - size_t aImageSize = iChunks.GetOffset(); - iE32Image = new char[aImageSize]; - memset(iE32Image, 0, aImageSize); - - E32ImageChunks::ChunkList aChunkList = iChunks.GetChunks(); - E32ImageChunks::ChunkList::iterator p; - for(p = aChunkList.begin(); p != aChunkList.end(); p++) - { - (*p)->Write(iE32Image); - } - - E32ImageHeaderV* header = (E32ImageHeaderV*)iE32Image; - TInt headerSize = header->TotalSize(); - if(KErrNone!=header->ValidateWholeImage(iE32Image+headerSize,GetE32ImageSize()-headerSize)) - throw InvalidE32ImageError(VALIDATIONERROR, (char*)iUseCase->OutputE32FileName()); -} - -/** -This function deflates the compressed data. -@param bytes -@param size -@param os -@internalComponent -@released -*/ -void DeflateCompress(char* bytes, size_t size, ofstream & os); - -/** -This function Paged Pack the compressed data. -@param bytes -@param size -@param os -@internalComponent -@released -*/ -void CompressPages(TUint8 * bytes, TInt size, ofstream& os); - - -/** -This function writes into the final E32 image file. -@param aName - E32 image file name -@internalComponent -@released -*/ -bool E32ImageFile::WriteImage(const char * aName) -{ - ofstream *os = new ofstream(); - os->open(aName, ofstream::binary|ofstream::out); - - if (os->is_open()) - { - uint32 compression = iHdr->CompressionType(); - if (compression == KUidCompressionDeflate) - { - size_t aHeaderSize = GetExtendedE32ImageHeaderSize(); - size_t aBodySize = GetE32ImageSize() - aHeaderSize; - os->write(iE32Image, aHeaderSize); - DeflateCompress(iE32Image + aHeaderSize, aBodySize, *os); - } - else if (compression == KUidCompressionBytePair) - { - size_t aHeaderSize = GetExtendedE32ImageHeaderSize(); - os->write(iE32Image, aHeaderSize); - - // Compress and write out code part - int srcStart = GetExtendedE32ImageHeaderSize(); - CompressPages( (TUint8*)iE32Image + srcStart, iHdr->iCodeSize, *os); - - - // Compress and write out data part - srcStart += iHdr->iCodeSize; - int srcLen = GetE32ImageSize() - srcStart; - - CompressPages((TUint8*)iE32Image + srcStart, srcLen, *os); - - } - else if (compression == 0) - { - os->write(iE32Image, GetE32ImageSize()); // image not compressed - } - - } - else - { - throw FileError(FILEOPENERROR,(char*)aName); - } - os->close(); - if(os!=NULL) - { - delete os; - os = NULL; - } - return true; -} - - -/** -Constructor for E32ImageFile class. -@internalComponent -@released -*/ -E32ImageFile::E32ImageFile(): iFileName(NULL), iE32Image(NULL),iExportBitMap(0),cleanupStack(0), iData(NULL),iHdr(NULL),iImportSection(0), iSize(0), iOrigHdr(NULL), iError(0), iSource(EE32Image), iOrigHdrOffsetAdj(0) -{ - -}; - -/** -Destructor for E32ImageFile class. -@internalComponent -@released -*/ -E32ImageFile::~E32ImageFile() -{ - delete[] iData; - if (iHdr && iHdr != iOrigHdr) - delete iHdr; - - delete [] iExportBitMap; - delete [] iE32Image; - delete [] iImportSection; - - std::vector::iterator aPos; - char *aPtr; - aPos = cleanupStack.begin(); - while( aPos != cleanupStack.end() ) - { - aPtr = *aPos; - delete [] aPtr; - aPos++; - } - -} - -/** -Adjust the size of allocated data and fix the member data -@internalComponent -@released -*/ -void E32ImageFile::Adjust(TInt aSize, TBool aAllowShrink) -{ - TInt asize = ((aSize+0x3)&0xfffffffc); - - if (asize == iSize) - return; - - if (iSize == 0) - { - iSize = asize; - iData = new char[iSize]; - memset(iData, 0, iSize); - } - else if (aAllowShrink || asize > iSize) - { - TInt oldsize = iSize; - iSize = asize; - iData = (char*)realloc(iData, iSize); - - if (iSize > oldsize) - memset(iData+oldsize, 0, iSize-oldsize); - } - - if (!iData) - iSize = 0; - - if (iHdr && iHdr == iOrigHdr) - iHdr = (E32ImageHeaderV*)iData; - - iOrigHdr = (E32ImageHeader*)iData; -} - -/** -Read the E32 image. -@param is - input stream -@internalComponent -@released -*/ -TInt E32ImageFile::ReadHeader(ifstream& is) -{ - Adjust(sizeof(E32ImageHeader), EFalse); - is.read(iData, sizeof(E32ImageHeader)); - TInt hdrsz = iOrigHdr->TotalSize(); - - if (hdrsz > 0x10000) - return KErrCorrupt; // sanity check - - if (hdrsz > (TInt)sizeof(E32ImageHeader)) - { - Adjust(hdrsz, EFalse); - is.read(iData+sizeof(E32ImageHeader), hdrsz-sizeof(E32ImageHeader)); - } - - TUint32 uncompressedSize; - TInt r = iOrigHdr->ValidateHeader(iFileSize,uncompressedSize); - - if (r != KErrNone) - { - fprintf(stderr, "Integrity check failed %d\n", r); - return r; - } - - iHdr = (E32ImageHeaderV*)iOrigHdr; - return KErrNone; -} - -/** -Return the offset of the text section -@internalComponent -@released -*/ -TUint E32ImageFile::TextOffset() -{ - return 0; -} - -/** -Return the offset of the data section -@internalComponent -@released -*/ -TUint E32ImageFile::DataOffset() -{ - return iHdr->iCodeSize; -} - -/** -Return the offset of the bss section -@internalComponent -@released -*/ -TUint E32ImageFile::BssOffset() -{ - return DataOffset()+iHdr->iDataSize; -} - - -/** -This function creates the bitmap after reading the E32 image file -@internalComponent -@released -*/ -void E32ImageFile::E32ImageExportBitMap() -{ - TInt nexp = iOrigHdr->iExportDirCount; - TInt memsz = (nexp + 7) >> 3; - iExportBitMap = new TUint8[memsz]; - memset(iExportBitMap, 0xff, memsz); - TUint* exports = (TUint*)(iData + iOrigHdr->iExportDirOffset); - TUint absoluteEntryPoint = iOrigHdr->iEntryPoint + iOrigHdr->iCodeBase; - TUint impfmt = iOrigHdr->ImportFormat(); - TUint hdrfmt = iOrigHdr->HeaderFormat(); - TUint absentVal = (impfmt == KImageImpFmt_ELF) ? absoluteEntryPoint : iOrigHdr->iEntryPoint; - TInt i; - iMissingExports = 0; - - for (i=0; i>3] &= ~(1u << (i & 7)); - ++iMissingExports; - } - } - - if (hdrfmt < KImageHdrFmt_V && iMissingExports) - { - fprintf(stderr, "Bad exports\n"); - exit(999); - } -} - -/** -This function creates the export description after reading the E32 image file -@internalComponent -@released -*/ -TInt E32ImageFile::CheckExportDescription() -{ - TUint hdrfmt = iOrigHdr->HeaderFormat(); - if (hdrfmt < KImageHdrFmt_V && iMissingExports) - return KErrCorrupt; - - if (iHdr->iExportDescType == KImageHdr_ExpD_NoHoles) - { - return iMissingExports ? KErrCorrupt : KErrNone; - } - - TInt nexp = iOrigHdr->iExportDirCount; - TInt memsz = (nexp + 7) >> 3; // size of complete bitmap - TInt mbs = (memsz + 7) >> 3; // size of meta-bitmap - TInt eds = iHdr->iExportDescSize; - - if (iHdr->iExportDescType == KImageHdr_ExpD_FullBitmap) - { - if (eds != memsz) - return KErrCorrupt; - if (memcmp(iHdr->iExportDesc, iExportBitMap, eds) == 0) - return KErrNone; - return KErrCorrupt; - } - - if (iHdr->iExportDescType != KImageHdr_ExpD_SparseBitmap8) - return KErrNotSupported; - - TInt nbytes = 0; - TInt i; - for (i=0; iiExportDesc; - const TUint8* gptr = mptr + mbs; - for (i=0; i>3] & (1u << (i&7)); - if (iExportBitMap[i] != 0xff) - { - if (!mbit || *gptr++ != iExportBitMap[i]) - return KErrCorrupt; - } - else if (mbit) - return KErrCorrupt; - } - - return KErrNone; -} - - -int DecompressPages(TUint8 * bytes, ifstream& is); - - -/** -This function creates the E32 image reading from the file -@param is -@param aImage -@internalComponent -@released -*/ -ifstream& operator>>(ifstream& is, E32ImageFile& aImage) -{ - aImage.iError = aImage.ReadHeader(is); - if (aImage.iError != KErrNone) - return is; - - E32ImageHeader* oh = aImage.iOrigHdr; - TInt orighdrsz = oh->TotalSize(); - int remainder = aImage.iSize - orighdrsz; - TUint compression = oh->CompressionType(); - if (compression == 0) - { - is.read(aImage.iData + orighdrsz, remainder); - } - else if (compression == KUidCompressionDeflate) - { //Uncompress - aImage.iError = KErrNoMemory; - unsigned int uncompsize = ((E32ImageHeaderComp*)aImage.iOrigHdr)->iUncompressedSize; - aImage.Adjust(uncompsize + orighdrsz); - - if (aImage.iData==NULL) - return is; - - oh = aImage.iOrigHdr; - - unsigned char* compressedData = new unsigned char[remainder]; - if (compressedData==NULL) - return is; - - is.read(reinterpret_cast(compressedData), remainder); - unsigned int destsize = uncompsize; - InflateUnCompress( compressedData, remainder, (unsigned char*)(aImage.iData + orighdrsz), destsize); - - if (destsize != uncompsize) - MessageHandler::GetInstance()->ReportMessage(WARNING, HUFFMANINCONSISTENTSIZEERROR); - - delete [] compressedData; - - if ((TUint)orighdrsz > oh->iCodeOffset) - { - // need to adjust code offsets in original - aImage.iOrigHdrOffsetAdj = (TUint)orighdrsz - oh->iCodeOffset; - aImage.OffsetAdjust(oh->iCodeOffset); - aImage.OffsetAdjust(oh->iDataOffset); - aImage.OffsetAdjust(oh->iCodeRelocOffset); - aImage.OffsetAdjust(oh->iDataRelocOffset); - aImage.OffsetAdjust(oh->iImportOffset); - aImage.OffsetAdjust(oh->iExportDirOffset); - } - aImage.iError = KErrNone; - } - else if(compression == KUidCompressionBytePair) - { // Uncompress - aImage.iError = KErrNoMemory; - unsigned int uncompsize = ((E32ImageHeaderComp*)aImage.iOrigHdr)->iUncompressedSize; - aImage.Adjust(uncompsize + orighdrsz); - if (aImage.iData==NULL) - return is; - oh = aImage.iOrigHdr; - - // Read and decompress code part of the image - - unsigned int uncompressedCodeSize = DecompressPages((TUint8 *) (aImage.iData + orighdrsz), is); - - - // Read and decompress data part of the image - - unsigned int uncompressedDataSize = DecompressPages((TUint8 *) (aImage.iData + orighdrsz + uncompressedCodeSize), is); - - if (uncompressedCodeSize + uncompressedDataSize != uncompsize) - MessageHandler::GetInstance()->ReportMessage(WARNING, BYTEPAIRINCONSISTENTSIZEERROR); - - if ((TUint)orighdrsz > oh->iCodeOffset) - { - // need to adjust code offsets in original - aImage.iOrigHdrOffsetAdj = (TUint)orighdrsz - oh->iCodeOffset; - aImage.OffsetAdjust(oh->iCodeOffset); - aImage.OffsetAdjust(oh->iDataOffset); - aImage.OffsetAdjust(oh->iCodeRelocOffset); - aImage.OffsetAdjust(oh->iDataRelocOffset); - aImage.OffsetAdjust(oh->iImportOffset); - aImage.OffsetAdjust(oh->iExportDirOffset); - } - aImage.iError = KErrNone; - } - aImage.E32ImageExportBitMap(); - - return is; -} -#ifdef __LINUX__ -#include -/** -Simple function uses stdlib fstat to obtain the size of the file. -@param aFileName - e32 image file name -@internalComponent -@released -*/ -int GetFileSize(const char* aFileName) { - // Open the file the old-fashioned way :-) - struct stat fileInfo; - if(stat(aFileName,&fileInfo)!=0) { - throw FileError(FILEOPENERROR,(char *)aFileName); - } - off_t fileSize = fileInfo.st_size; - return fileSize; -} -#else -int GetFileSize(const char* aFileName) { - _finddata_t fileinfo; - int ret=_findfirst((char *)aFileName,&fileinfo); - if (ret==-1) - { - throw FileError(FILEOPENERROR,(char *)aFileName); - } - return fileinfo.size; -} -#endif - - -/** -This function opens the e32 image file. -@param aFileName - e32 image file name -@internalComponent -@released -*/ -TInt E32ImageFile::Open(const char* aFileName) -{ - iFileSize = GetFileSize(aFileName); - - Adjust(iFileSize); - ifstream ifile((char *)aFileName, ios::in | ios::binary); - if(!ifile.is_open()) - { - throw FileError(FILEOPENERROR,(char *)aFileName); - } - ifile >> *this; - ifile.close(); - - if (iError != KErrNone) - return iError; - - return KErrNone; -} - -void E32ImageFile::ProcessSymbolInfo() { - - Elf32_Addr aPlace = iUseCase->GetExportTableAddress() - 4;// This location points to 0th ord. - // Create a relocation entry for the 0th ordinal. - ElfLocalRelocation *aRel = new ElfLocalRelocation(iElfExecutable, aPlace, 0, 0, R_ARM_ABS32, \ - NULL, ESegmentRO, NULL, false); - aRel->Add(); - - aPlace += iUseCase->GetExportTableSize();// aPlace now points to the symInfo - uint32 *aZerothOrd = (uint32*)iUseCase->GetExportTable(); - *aZerothOrd = aPlace; - aPlace += sizeof(E32EpocExpSymInfoHdr);// aPlace now points to the symbol address - // which is just after the syminfo header. - if(!iElfExecutable->iExports) - return; - - // Donot disturb the internal list sorting. - ElfExports::ExportList aList = iElfExecutable->iExports->GetExports(false); - - ElfExports::ExportList::iterator aIter = aList.begin(); - DllSymbol *aSym; - TUint aAlign, aNameLen; - - - char aPad[] = {'\0', '\0', '\0', '\0'}; - - - while ( aIter != aList.end() ) { - aSym = *aIter; - iSymAddrTab.push_back(aSym->iElfSym->st_value); - // The symbol names always start at a 4-byte aligned offset. - iSymNameOffset = iSymbolNames.size() >> 2; - iSymNameOffTab.push_back(iSymNameOffset); - - iSymbolNames += aSym->SymbolName(); - iSymbolNames += '\0'; - aNameLen = iSymbolNames.size(); - aAlign = Align(aNameLen, sizeof(int)); - aAlign = aAlign - aNameLen; - if(aAlign % 4){ - iSymbolNames.append(aPad, aAlign); - } - //Create a relocation entry... - aRel = new ElfLocalRelocation(iElfExecutable, aPlace, 0, 0, R_ARM_ABS32, NULL,\ - ESegmentRO, aSym->iElfSym, false); - aPlace += sizeof(uint32); - aRel->Add(); - aIter++; - } -} - -char* E32ImageFile::CreateSymbolInfo(size_t aBaseOffset) { - E32EpocExpSymInfoHdr aSymInf; - uint32 aSizeofNames, aSize; - - SetSymInfo(aSymInf); - if( aSymInf.iFlags & 1) { - aSizeofNames = sizeof(uint32); - } - else { - aSizeofNames = sizeof(uint16); - } - - aSize = aSymInf.iSize; - - char* aInfo = new char[aSize]; - memset(aInfo, 0, aSize); - memcpy(aInfo, (void*)&aSymInf, sizeof(aSymInf)); - - TUint aPos = aSymInf.iSymbolTblOffset; - memcpy(aInfo+aPos, iSymAddrTab.begin(), iSymAddrTab.size()*sizeof(uint32)); - - aPos += iSymAddrTab.size()*aSizeofNames; - aPos += iSymNameOffTab.size()*aSizeofNames; - aPos = Align(aPos, sizeof(uint32)); - - std::vector::iterator Iter = iSymNameOffTab.begin(); - TInt aOffLen = 2; - if(aSymInf.iFlags & 1) - aOffLen=4; - while(Iter != iSymNameOffTab.end()){ - memcpy( ((void*)(aInfo+aPos)), ((void*)Iter), aOffLen); - aPos += aOffLen; - Iter++; - } - - aPos = aSymInf.iStringTableOffset; - memcpy(aInfo+aPos, iSymbolNames.begin(), iSymbolNames.size()); - - // At the end, the dependencies are listed. They remain zeroes and shall be fixed up - // while relocating. - - // Update the import table to have offsets to ordinal zero entries - uint32 *aLocation, aOffset; - uint32 *aImportTab = iImportSection; - - std::vector::iterator aIter = iImportTabLocations.begin(); - aOffset = aBaseOffset - iHdr->iCodeOffset;// This gives the offset of syminfo table base - // wrt the code section start - aOffset += aSymInf.iDepDllZeroOrdTableOffset; // This points to the ordinal zero offset table now - while( aIter != iImportTabLocations.end()) { - aLocation = (aImportTab + *aIter); - *aLocation = aOffset; - aOffset += sizeof(uint32); - aIter++; - } - - return aInfo; -} - -void E32ImageFile::SetSymInfo(E32EpocExpSymInfoHdr& aSymInfo) -{ - uint32 aSize = sizeof(E32EpocExpSymInfoHdr); - memset(&aSymInfo, 0, aSize); - - uint16 aNSymbols = (uint16) iSymAddrTab.size(); - aSymInfo.iSymCount = aNSymbols; - aSymInfo.iSymbolTblOffset = aSize; - aSize += aNSymbols * sizeof(uint32); // Symbol addresses - TUint aNameTabSz = iSymbolNames.size(); - TInt aSizeofNames; - - if( iSymNameOffset < 0xffff) { - aSizeofNames = sizeof(uint16); - aSymInfo.iFlags &= ~1;//reset the 0th bit - } - else { - aSizeofNames = sizeof(uint32); - aSymInfo.iFlags |= 1;//set the 0th bit - } - aSize += Align((aNSymbols * aSizeofNames), sizeof(uint32)); // Symbol name offsets - aSymInfo.iStringTableOffset = aSize; - aSize += aNameTabSz; // Symbol names in string tab - aSymInfo.iStringTableSz = aNameTabSz; - aSymInfo.iDepDllZeroOrdTableOffset = aSize; - aSymInfo.iDllCount = iNumDlls ; - aSize += iNumDlls * sizeof(uint32); // Dependency list - ordinal zero placeholder - aSymInfo.iSize = aSize; -} -