--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/launcher/inc/e32imageheaders.h Tue Feb 02 00:17:27 2010 +0200
@@ -0,0 +1,534 @@
+/*
+* Copyright (c) 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:
+*
+*/
+
+
+
+#ifndef __LAUNCHERE32IMAGEHEADERS_H__
+#define __LAUNCHERE32IMAGEHEADERS_H__
+
+#include <e32uid.h>
+
+/** Bit output stream.
+ Good for writing bit streams for packed, compressed or huffman data algorithms.
+
+ This class must be derived from and OverflowL() reimplemented if the bitstream data
+ cannot be generated into a single memory buffer.
+*/
+class TBitOutput
+ {
+public:
+ IMPORT_C TBitOutput();
+ IMPORT_C TBitOutput(TUint8* aBuf,TInt aSize);
+ inline void Set(TUint8* aBuf,TInt aSize);
+ inline const TUint8* Ptr() const;
+ inline TInt BufferedBits() const;
+//
+ IMPORT_C void WriteL(TUint aValue, TInt aLength);
+ IMPORT_C void HuffmanL(TUint aHuffCode);
+ IMPORT_C void PadL(TUint aPadding);
+private:
+ void DoWriteL(TUint aBits, TInt aSize);
+ virtual void OverflowL();
+private:
+ TUint iCode; // code in production
+ TInt iBits;
+ TUint8* iPtr;
+ TUint8* iEnd;
+ };
+
+/** Set the memory buffer to use for output
+
+ Data will be written to this buffer until it is full, at which point OverflowL() will
+ be called. This should handle the data and then can Set() again to reset the buffer
+ for further output.
+
+ @param aBuf The buffer for output
+ @param aSize The size of the buffer in bytes
+*/
+inline void TBitOutput::Set(TUint8* aBuf,TInt aSize)
+ {iPtr=aBuf;iEnd=aBuf+aSize;}
+
+/** Get the current write position in the output buffer
+
+ In conjunction with the address of the buffer, which should be known to the
+ caller, this describes the data in the bitstream.
+*/
+inline const TUint8* TBitOutput::Ptr() const
+ {return iPtr;}
+
+/** Get the number of bits that are buffered
+
+ This reports the number of bits that have not yet been written into the
+ output buffer. It will always lie in the range 0..7. Use PadL() to
+ pad the data out to the next byte and write it to the buffer.
+*/
+inline TInt TBitOutput::BufferedBits() const
+ {return iBits+8;}
+
+
+/** Bit input stream. Good for reading bit streams for packed, compressed or huffman
+ data algorithms.
+*/
+class TBitInput
+ {
+public:
+ IMPORT_C TBitInput();
+ IMPORT_C TBitInput(const TUint8* aPtr, TInt aLength, TInt aOffset=0);
+ IMPORT_C void Set(const TUint8* aPtr, TInt aLength, TInt aOffset=0);
+//
+ IMPORT_C TUint ReadL();
+ IMPORT_C TUint ReadL(TInt aSize);
+ IMPORT_C TUint HuffmanL(const TUint32* aTree);
+private:
+ virtual void UnderflowL();
+private:
+ TInt iCount;
+ TUint iBits;
+ TInt iRemain;
+ const TUint32* iPtr;
+ };
+
+/** Huffman code toolkit.
+
+ This class builds a huffman encoding from a frequency table and builds
+ a decoding tree from a code-lengths table
+
+ The encoding generated is based on the rule that given two symbols s1 and s2, with
+ code length l1 and l2, and huffman codes h1 and h2:
+
+ if l1<l2 then h1<h2 when compared lexicographically
+ if l1==l2 and s1<s2 then h1<h2 ditto
+
+ This allows the encoding to be stored compactly as a table of code lengths
+*/
+class Huffman
+ {
+public:
+ enum {KMaxCodeLength=27};
+ enum {KMetaCodes=KMaxCodeLength+1};
+ enum {KMaxCodes=0x8000};
+public:
+ IMPORT_C static void HuffmanL(const TUint32 aFrequency[],TInt aNumCodes,TUint32 aHuffman[]);
+ IMPORT_C static void Encoding(const TUint32 aHuffman[],TInt aNumCodes,TUint32 aEncodeTable[]);
+ IMPORT_C static void Decoding(const TUint32 aHuffman[],TInt aNumCodes,TUint32 aDecodeTree[],TInt aSymbolBase=0);
+ IMPORT_C static TBool IsValid(const TUint32 aHuffman[],TInt aNumCodes);
+//
+ IMPORT_C static void ExternalizeL(TBitOutput& aOutput,const TUint32 aHuffman[],TInt aNumCodes);
+ IMPORT_C static void InternalizeL(TBitInput& aInput,TUint32 aHuffman[],TInt aNumCodes);
+ };
+
+
+enum TCpu
+ {
+ ECpuUnknown=0, ECpuX86=0x1000, ECpuArmV4=0x2000, ECpuArmV5=0x2001, ECpuArmV6=0x2002, ECpuMCore=0x4000
+ };
+
+const TInt KOrdinalBase=1;
+const TUint KImageDll = 0x00000001u;
+const TUint KImageNoCallEntryPoint = 0x00000002u;
+const TUint KImageFixedAddressExe = 0x00000004u;
+const TUint KImageOldJFlag = 0x00000008u; // so we can run binaries built with pre 2.00 tools (hdrfmt=0)
+const TUint KImageOldElfFlag = 0x00000010u; // so we can run binaries built with pre 2.00 tools (hdrfmt=0)
+const TUint KImageABIMask = 0x00000018u; // only if hdr fmt not zero
+const TInt KImageABIShift = 3;
+const TUint KImageABI_GCC98r2 = 0x00000000u; // for ARM
+const TUint KImageABI_EABI = 0x00000008u; // for ARM
+const TUint KImageEptMask = 0x000000e0u; // entry point type
+const TInt KImageEptShift = 5;
+const TUint KImageEpt_Eka1 = 0x00000000u;
+const TUint KImageEpt_Eka2 = 0x00000020u;
+const TUint KImageHdrFmtMask = 0x0f000000u;
+const TInt KImageHdrFmtShift = 24;
+const TUint KImageHdrFmt_Original = 0x00000000u; // without compression support
+const TUint KImageHdrFmt_J = 0x01000000u; // with compression support
+const TUint KImageHdrFmt_V = 0x02000000u; // with versioning support
+const TUint KImageImpFmtMask = 0xf0000000u;
+const TInt KImageImpFmtShift = 28;
+const TUint KImageImpFmt_PE = 0x00000000u; // PE-derived imports
+const TUint KImageImpFmt_ELF = 0x10000000u; // ELF-derived imports
+const TUint KImageImpFmt_PE2 = 0x20000000u; // PE-derived imports without redundant copy of import ordinals
+const TUint KImageHWFloatMask = 0x00f00000u;
+const TInt KImageHWFloatShift = 20;
+const TUint KImageHWFloat_None = EFpTypeNone << KImageHWFloatShift; // No hardware floating point used
+const TUint KImageHWFloat_VFPv2 = EFpTypeVFPv2 << KImageHWFloatShift; // ARM VFPv2 floating point used
+
+const TUint KMyFormatNotCompressed=0;
+const TUint KMyUidCompressionDeflate=0x101F7AFC;
+
+const TUint32 KImageCrcInitialiser = 0xc90fdaa2u;
+/*
+const TUint16 KReservedRelocType = (TUint16)0x0000;
+const TUint16 KTextRelocType = (TUint16)0x1000;
+const TUint16 KDataRelocType = (TUint16)0x2000;
+const TUint16 KInferredRelocType = (TUint16)0x3000;
+*/
+class RFile;
+class E32ImageHeader
+ {
+public:
+ inline static TUint ABIFromFlags(TUint aFlags)
+ {
+ if (aFlags&KImageHdrFmtMask)
+ return aFlags & KImageABIMask;
+ if (aFlags&KImageOldElfFlag)
+ return KImageABI_EABI;
+ return KImageABI_GCC98r2;
+ }
+ inline static TUint EptFromFlags(TUint aFlags)
+ {
+ if (aFlags&KImageHdrFmtMask)
+ return aFlags & KImageEptMask;
+ if (aFlags&KImageOldJFlag)
+ return KImageEpt_Eka2;
+ return KImageEpt_Eka1;
+ }
+ inline static TUint HdrFmtFromFlags(TUint aFlags)
+ {
+ if (aFlags&KImageHdrFmtMask)
+ return aFlags & KImageHdrFmtMask;
+ if (aFlags&KImageOldJFlag)
+ return KImageHdrFmt_J;
+ return KImageHdrFmt_Original;
+ }
+ inline static TUint ImpFmtFromFlags(TUint aFlags)
+ {
+ if (aFlags&KImageHdrFmtMask)
+ return aFlags & KImageImpFmtMask;
+ if (aFlags&KImageOldElfFlag)
+ return KImageImpFmt_ELF;
+ return KImageImpFmt_PE;
+ }
+ inline TUint32 CompressionType() const
+ {
+ if (HdrFmtFromFlags(iFlags) >= KImageHdrFmt_J)
+ return iCompressionType;
+ return 0;
+ }
+ inline TUint32 ModuleVersion() const
+ {
+ if ((iFlags & KImageHdrFmtMask) >= KImageHdrFmt_V)
+ return iModuleVersion;
+ return 0x00000000u;
+ }
+ inline TInt TotalSize() const;
+ inline TInt UncompressedFileSize() const;
+ inline TUint HeaderFormat() const
+ { return HdrFmtFromFlags(iFlags); }
+ inline TUint EntryPointFormat() const
+ { return EptFromFlags(iFlags); }
+ inline TUint ImportFormat() const
+ { return ImpFmtFromFlags(iFlags); }
+ inline TUint ABI() const
+ { return ABIFromFlags(iFlags); }
+ inline void GetSecurityInfo(SSecurityInfo& aInfo) const;
+ inline TCpu CpuIdentifier() const;
+ inline TProcessPriority ProcessPriority() const;
+ inline TUint32 ExceptionDescriptor() const;
+ TInt IntegrityCheck(TInt aFileSize);
+ static TInt New(E32ImageHeader*& aHdr, RFile& aFile);
+public:
+ TUint32 iUid1;
+ TUint32 iUid2;
+ TUint32 iUid3;
+ TUint32 iUidChecksum;
+ TUint iSignature; // 'EPOC'
+ TUint32 iHeaderCrc; // CRC-32 of entire header
+ TUint32 iModuleVersion; // Version number for this executable (used in link resolution)
+ TUint32 iCompressionType; // Type of compression used (UID or 0 for none)
+ TVersion iToolsVersion; // Version of PETRAN/ELFTRAN which generated this file
+ TUint32 iTimeLo;
+ TUint32 iTimeHi;
+ TUint iFlags; // 0 = exe, 1 = dll, 2 = fixed address exe
+ TInt iCodeSize; // size of code, import address table, constant data and export dir
+ TInt iDataSize; // size of initialised data
+ TInt iHeapSizeMin;
+ TInt iHeapSizeMax;
+ TInt iStackSize;
+ TInt iBssSize;
+ TUint iEntryPoint; // offset into code of entry point
+ TUint iCodeBase; // where the code is linked for
+ TUint iDataBase; // where the data is linked for
+ TInt iDllRefTableCount; // filling this in enables E32ROM to leave space for it
+ TUint iExportDirOffset; // offset into the file of the export address table
+ TInt iExportDirCount;
+ TInt iTextSize; // size of just the text section, also doubles as the offset for the iat w.r.t. the code section
+ TUint iCodeOffset; // file offset to code section, also doubles as header size
+ TUint iDataOffset; // file offset to data section
+ TUint iImportOffset; // file offset to import section
+ TUint iCodeRelocOffset; // relocations for code and const
+ TUint iDataRelocOffset; // relocations for data
+ TUint16 iProcessPriority; // executables priority
+ TUint16 iCpuIdentifier; // 0x1000 = X86, 0x2000 = ARM
+ };
+
+class E32ImageHeaderComp : public E32ImageHeader
+ {
+public:
+ TUint32 iUncompressedSize; // Uncompressed size of file
+ // For J format this is file size - sizeof(E32ImageHeader)
+ // and this is included as part of the compressed data :-(
+ // For other formats this is file size - total header size
+ };
+
+class E32ImageHeaderV : public E32ImageHeaderComp
+ {
+public:
+ SSecurityInfo iS;
+
+ // Use iSpare1 as offset to Exception Descriptor
+ TUint32 iExceptionDescriptor; // Offset in bytes from start of code section to Exception Descriptor, bit 0 set if valid
+ TUint32 iSpare2;
+ TUint16 iExportDescSize; // size of bitmap section
+ TUint8 iExportDescType; // type of description of holes in export table
+ TUint8 iExportDesc[1]; // description of holes in export table - extend
+ };
+
+// export description type
+const TUint KImageHdr_ExpD_NoHoles =0x00; // no holes, all exports present
+const TUint KImageHdr_ExpD_FullBitmap =0x01; // full bitmap present
+const TUint KImageHdr_ExpD_SparseBitmap8 =0x02; // sparse bitmap present, granularity 8
+const TUint KImageHdr_ExpD_Xip =0xff; // XIP file
+
+
+inline TInt E32ImageHeader::TotalSize() const
+ {
+ if (HeaderFormat() == KImageHdrFmt_J && iCompressionType != 0)
+ return sizeof(E32ImageHeaderComp);
+ return iCodeOffset;
+ }
+
+inline TInt E32ImageHeader::UncompressedFileSize() const
+ {
+ TUint hdrfmt = HeaderFormat();
+ if (hdrfmt == KImageHdrFmt_Original || iCompressionType == 0)
+ return -1; // not compressed
+ else if (hdrfmt == KImageHdrFmt_J)
+ return ((E32ImageHeaderComp*)this)->iUncompressedSize + sizeof(E32ImageHeader);
+ else
+ return ((E32ImageHeaderComp*)this)->iUncompressedSize + iCodeOffset;
+ }
+
+extern const SSecurityInfo KDefaultSecurityInfo;
+inline void E32ImageHeader::GetSecurityInfo(SSecurityInfo& aInfo) const
+ {
+ if (HeaderFormat() >= KImageHdrFmt_V)
+ aInfo = ((E32ImageHeaderV*)this)->iS;
+ else
+ aInfo = KDefaultSecurityInfo;
+ }
+
+inline TCpu E32ImageHeader::CpuIdentifier() const
+ {
+ if (HeaderFormat() >= KImageHdrFmt_V)
+ return (TCpu)iCpuIdentifier;
+ return (TCpu)iHeaderCrc;
+ }
+
+inline TProcessPriority E32ImageHeader::ProcessPriority() const
+ {
+ if (HeaderFormat() >= KImageHdrFmt_V)
+ return (TProcessPriority)iProcessPriority;
+ return *(const TProcessPriority*)&iProcessPriority;
+ }
+
+inline TUint32 E32ImageHeader::ExceptionDescriptor() const
+ {
+ if (HeaderFormat() >= KImageHdrFmt_V)
+ {
+ TUint32 xd = ((E32ImageHeaderV*)this)->iExceptionDescriptor;
+ if ((xd & 1) && (xd != 0xffffffffu))
+ return (xd & ~1);
+ }
+ return 0;
+ }
+
+class E32ImportBlock
+ {
+public:
+ inline const E32ImportBlock* NextBlock(TUint aImpFmt) const;
+ inline TInt Size(TUint aImpFmt) const;
+ inline const TUint* Imports() const; // import list if present
+public:
+ TUint32 iOffsetOfDllName; // offset of name of dll importing from
+ TInt iNumberOfImports; // no of imports from this dll
+// TUint iImport[iNumberOfImports]; // list of imported ordinals, omitted in PE2 import format
+ };
+
+inline TInt E32ImportBlock::Size(TUint aImpFmt) const
+ {
+ TInt r = sizeof(E32ImportBlock);
+ if (aImpFmt!=KImageImpFmt_PE2)
+ r += iNumberOfImports * sizeof(TUint);
+ return r;
+ }
+
+inline const E32ImportBlock* E32ImportBlock::NextBlock(TUint aImpFmt) const
+ {
+ const E32ImportBlock* next = this + 1;
+ if (aImpFmt!=KImageImpFmt_PE2)
+ next = (const E32ImportBlock*)( (TUint8*)next + iNumberOfImports * sizeof(TUint) );
+ return next;
+ }
+
+inline const TUint* E32ImportBlock::Imports() const
+ {
+ return (const TUint*)(this + 1);
+ }
+
+class E32ImportSection
+ {
+public:
+ TInt iSize; // size of this section
+// E32ImportBlock[iDllRefTableCount];
+ };
+
+class E32RelocSection
+ {
+public:
+ TInt iSize; // size of this relocation section
+ TInt iNumberOfRelocs; // number of relocations in this section
+ };
+
+
+typedef TUint8* (*TMemoryMoveFunction)(TAny* aTrg,const TAny* aSrc,TInt aLength);
+
+const TInt KDeflateLengthMag=8;
+const TInt KDeflateDistanceMag=12;
+const TInt KDeflateMinLength=3;
+const TInt KDeflateMaxLength=KDeflateMinLength-1 + (1<<KDeflateLengthMag);
+const TInt KDeflateMaxDistance=(1<<KDeflateDistanceMag);
+const TInt KDeflateDistCodeBase=0x200;
+const TUint KDeflateHashMultiplier=0xAC4B9B19u;
+const TInt KDeflateHashShift=24;
+const TInt KInflateWindowSize=0x8000;
+
+
+class TEncoding
+ {
+public:
+ enum {ELiterals=256,ELengths=(KDeflateLengthMag-1)*4,ESpecials=1,EDistances=(KDeflateDistanceMag-1)*4};
+ enum {ELitLens=ELiterals+ELengths+ESpecials};
+ enum {EEos=ELiterals+ELengths};
+public:
+ TUint32 iLitLen[ELitLens];
+ TUint32 iDistance[EDistances];
+ };
+
+const TInt KDeflationCodes=TEncoding::ELitLens+TEncoding::EDistances;
+
+NONSHARABLE_CLASS(CInflater) : public CBase
+ {
+public:
+ enum {EBufSize = 0x800, ESafetyZone=8};
+public:
+ static CInflater* NewLC(TBitInput& aInput);
+ ~CInflater();
+ TInt ReadL(TUint8* aBuffer,TInt aLength, TMemoryMoveFunction aMemMovefn);
+ TInt SkipL(TInt aLength);
+private:
+ CInflater(TBitInput& aInput);
+ void ConstructL();
+ void InitL();
+ TInt InflateL();
+private:
+ TBitInput* iBits;
+ const TUint8* iRptr;
+ TInt iLen;
+ const TUint8* iAvail;
+ const TUint8* iLimit;
+ TEncoding* iEncoding;
+ TUint8* iOut;
+ };
+
+void DeflateL(const TUint8* aBuf, TInt aLength, TBitOutput& aOutput);
+
+
+NONSHARABLE_CLASS(TFileInput) : public TBitInput
+ {
+ enum {KBufSize=KInflateWindowSize};
+public:
+ TFileInput(RFile& aFile);
+ void Cancel();
+private:
+ void UnderflowL();
+private:
+ RFile& iFile;
+ TRequestStatus iStat;
+ TUint8* iReadBuf;
+ TPtr8 iPtr;
+ TUint8 iBuf1[KBufSize];
+ TUint8 iBuf2[KBufSize];
+ };
+
+class TFileNameInfo
+ {
+public:
+ enum
+ {
+ EIncludeDrive=1,
+ EIncludePath=2,
+ EIncludeBase=4,
+ EIncludeVer=8,
+ EForceVer=16,
+ EIncludeUid=32,
+ EForceUid=64,
+ EIncludeExt=128,
+ EIncludeDrivePath=EIncludeDrive|EIncludePath,
+ EIncludeBaseExt=EIncludeBase|EIncludeExt,
+ EIncludeDrivePathBaseExt=EIncludeDrive|EIncludePath|EIncludeBase|EIncludeExt,
+ };
+ enum
+ {
+ EAllowUid=1,
+ EAllowPlaceholder=2,
+ EAllowDecimalVersion=4,
+ };
+public:
+ TFileNameInfo();
+ TInt Set(const TDesC8& aFileName, TUint aFlags);
+ void Dump() const;
+public:
+ inline TInt DriveLen() const {return iPathPos;}
+ inline TInt PathLen() const {return iBasePos-iPathPos;}
+ inline TInt BaseLen() const {return iVerPos-iBasePos;}
+ inline TInt VerLen() const {return iUidPos-iVerPos;}
+ inline TInt UidLen() const {return iExtPos-iUidPos;}
+ inline TInt ExtLen() const {return iLen-iExtPos;}
+ inline TPtrC8 Drive() const {return TPtrC8(iName, iPathPos);}
+ inline TPtrC8 Path() const {return TPtrC8(iName+iPathPos, iBasePos-iPathPos);}
+ inline TPtrC8 DriveAndPath() const {return TPtrC8(iName, iBasePos);}
+ inline TPtrC8 Base() const {return TPtrC8(iName+iBasePos, iVerPos-iBasePos);}
+ inline TPtrC8 VerStr() const {return TPtrC8(iName+iVerPos, iUidPos-iVerPos);}
+ inline TPtrC8 UidStr() const {return TPtrC8(iName+iUidPos, iExtPos-iUidPos);}
+ inline TPtrC8 Ext() const {return TPtrC8(iName+iExtPos, iLen-iExtPos);}
+ inline TUint32 Version() const {return iVersion;}
+ inline TUint32 Uid() const {return iUid;}
+ void GetName(TDes8& aName, TUint aFlags) const;
+public:
+ const TText8* iName;
+ TInt iPathPos;
+ TInt iBasePos;
+ TInt iVerPos;
+ TInt iUidPos;
+ TInt iExtPos;
+ TInt iLen;
+ TUint32 iVersion;
+ TUint32 iUid;
+ };
+
+
+#endif // __LAUNCHERE32IMAGEHEADERS_H__