diff -r 000000000000 -r 044383f39525 imgtools/romtools/readimage/src/rom_image_reader.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/imgtools/romtools/readimage/src/rom_image_reader.cpp Tue Oct 27 16:36:35 2009 +0000 @@ -0,0 +1,953 @@ +/* +* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* @internalComponent +* @released +* +*/ + +#include +#include "rom_image_reader.h" +#include "r_rom.h" + +void InflateUnCompress(unsigned char* source, int sourcesize, unsigned char* dest, int destsize); +RomImageFSEntry::RomImageFSEntry (const char* aName) : iName(aName), iSibling(0), iChildren(0) { +} +RomImageFSEntry::~RomImageFSEntry() { + if(iChildren){ + delete iChildren; + iChildren = NULL ; + } + if(iSibling){ + delete iSibling ; + iSibling = NULL ; + } +} + +//Rom Image header +RomImageHeader::RomImageHeader(char* aHdr, EImageType aImgType) +{ + switch( aImgType) + { + case EROM_IMAGE: + iLoaderHdr = (TRomLoaderHeader*)aHdr; + iRomHdr = (TRomHeader*)(aHdr + sizeof(TRomLoaderHeader)); + iExtRomHdr = 0; + break; + + case EROMX_IMAGE: + iExtRomHdr = (TExtensionRomHeader*)(aHdr); + iRomHdr = 0; + iLoaderHdr = 0; + break; + + case EBAREROM_IMAGE: + iLoaderHdr = 0; + iRomHdr = (TRomHeader*)aHdr; + iExtRomHdr = 0; + break; + default: + iExtRomHdr = 0; + iRomHdr = 0; + iLoaderHdr = 0; + break ; + } +} + + +void RomImageHeader::DumpRomHdr() +{ + if(iLoaderHdr) + *out << "ROM Image " << endl << endl; + else + *out << "Bare ROM Image" << endl << endl; + TUint aPos = 0; + bool aContinue = true; + + *out << "Image Signature ................."; + + if(iLoaderHdr){ + TText *aRomName = reinterpret_cast(iLoaderHdr) ; + while (aPos < KRomNameSize) { + *out << (char)aRomName[aPos++]; + } + } + + *out << endl << endl; + + DumpInHex("Timestamp", (iRomHdr->iTime >> 32)) ; + DumpInHex(" ", (iRomHdr->iTime &0xffffffff), aContinue) << endl; + + DumpInHex("RomBase", iRomHdr->iRomBase) << endl; + + DumpInHex("RomSize", iRomHdr->iRomSize) << endl; + DumpInHex("KernelDataAddress", iRomHdr->iKernDataAddress) << endl; + DumpInHex("KernelLimit", iRomHdr->iKernelLimit) << endl; + DumpInHex("PrimaryFile", iRomHdr->iPrimaryFile) << endl; + DumpInHex("SecondaryFile", iRomHdr->iSecondaryFile) << endl; + DumpInHex("CheckSum", iRomHdr->iCheckSum) << endl; + DumpInHex("Hardware", iRomHdr->iHardware) << endl; + + DumpInHex("Language", (TUint)(iRomHdr->iLanguage >> 32)); + DumpInHex(" ", ((TUint)(iRomHdr->iLanguage & 0xffffffff)), aContinue) <iKernelConfigFlags) << endl; + DumpInHex("RomExceptionSearchTable", iRomHdr->iRomExceptionSearchTable) << endl; + DumpInHex("RomHeaderSize", iRomHdr->iRomHeaderSize) << endl; + DumpInHex("RomSectionHeader", iRomHdr->iRomSectionHeader) << endl; + DumpInHex("TotalSvDataSize", iRomHdr->iTotalSvDataSize) << endl; + DumpInHex("VariantFile", iRomHdr->iVariantFile) << endl; + DumpInHex("ExtensionFile", iRomHdr->iExtensionFile) << endl; + DumpInHex("RelocInfo", iRomHdr->iRelocInfo) << endl; + DumpInHex("OldTraceMask", iRomHdr->iOldTraceMask) << endl; + DumpInHex("UserDataAddress", iRomHdr->iUserDataAddress) << endl; + DumpInHex("TotalUserDataSize", iRomHdr->iTotalUserDataSize) << endl; + DumpInHex("DebugPort", iRomHdr->iDebugPort) << endl; + + DumpInHex("Version", iRomHdr->iVersion.iMajor, false, 2); + DumpInHex(".", iRomHdr->iVersion.iMinor, aContinue, 2); + DumpInHex("(" ,iRomHdr->iVersion.iBuild, aContinue, 2); + *out << ")" << endl; + + DumpInHex("CompressionType", iRomHdr->iCompressionType) << endl; + DumpInHex("CompressedSize", iRomHdr->iCompressedSize) << endl; + DumpInHex("UncompressedSize", iRomHdr->iUncompressedSize) << endl; + DumpInHex("HcrFileAddress", iRomHdr->iHcrFileAddress) << endl; + + DumpInHex("DisabledCapabilities", iRomHdr->iDisabledCapabilities[0]); + DumpInHex(" ", iRomHdr->iDisabledCapabilities[1], aContinue) << endl; + + DumpInHex("TraceMask", iRomHdr->iTraceMask[0]); + aPos = 1; + while( aPos < (TUint)KNumTraceMaskWords) + { + if(iRomHdr->iTraceMask[aPos]) + { + DumpInHex(" ", iRomHdr->iTraceMask[aPos++], aContinue); + } + else + { + DumpInHex(" ", iRomHdr->iTraceMask[aPos++], aContinue, 1); + } + + } + + *out << endl << endl; + +} +void RomImageHeader::DumpRomXHdr() +{ + *out << "Extension ROM Image" << endl << endl; + bool aContinue = true; + + DumpInHex("Timestamp", (iExtRomHdr->iTime >> 32)) ; + DumpInHex(" ", (iExtRomHdr->iTime &0xffffffff), aContinue) << endl; + + DumpInHex("RomBase", iExtRomHdr->iRomBase) << endl; + + DumpInHex("RomSize", iExtRomHdr->iRomSize) << endl; + DumpInHex("CheckSum", iExtRomHdr->iCheckSum) << endl; + + DumpInHex("Version", iExtRomHdr->iVersion.iMajor, false, 2); + DumpInHex(".", iExtRomHdr->iVersion.iMinor, aContinue, 2); + DumpInHex("(" ,iExtRomHdr->iVersion.iBuild, aContinue, 2); + *out << ")" << endl; + + DumpInHex("CompressionType", iExtRomHdr->iCompressionType) << endl; + DumpInHex("CompressedSize", iExtRomHdr->iCompressedSize) << endl; + DumpInHex("UncompressedSize", iExtRomHdr->iUncompressedSize) << endl; + + *out << endl << endl; + +} +//Rom Image reader +RomImageReader::RomImageReader(const char* aFile, EImageType aImgType) : +ImageReader(aFile), iImageHeader(0), +iRomSize(0),iHeaderBuffer(0), +iRomLayoutData(0),iImgType(aImgType) +{ + iRomImageRootDirEntry = new RomImageDirEntry(""); +} + +RomImageReader::~RomImageReader() +{ + if(iFile.is_open()) + iFile.close(); + if(iHeaderBuffer) + delete []iHeaderBuffer; + if(iRomLayoutData) + delete []iRomLayoutData; + delete iRomImageRootDirEntry; + + +} + +void RomImageReader::ReadImage() +{ + if(iFile.is_open()) return ; + iFile.open(iImgFileName.c_str(), ios::binary | ios::in); + if( !iFile.is_open() ) { + throw ImageReaderException(iImgFileName.c_str(), "Cannot open file "); + } + + TUint headerSize = GetHdrSize() ; + if(headerSize > 0){ + iHeaderBuffer = new char[headerSize]; + iFile.read(iHeaderBuffer,headerSize); + } +} + +void RomImageReader::Validate() +{ +} + +TUint32 RomImageReader::GetImageCompressionType() +{ + if(iImageHeader->iRomHdr )// iImageType == EROM_IMAGE + return iImageHeader->iRomHdr->iCompressionType; + else + return iImageHeader->iExtRomHdr->iCompressionType; +} + + +TLinAddr RomImageReader::GetRomBase() +{ + if(iImageHeader->iRomHdr )// iImageType == EROM_IMAGE + return iImageHeader->iRomHdr->iRomBase ; + else + return iImageHeader->iExtRomHdr->iRomBase; +} + +TLinAddr RomImageReader::GetRootDirList() +{ + if(iImageHeader->iRomHdr )// iImageType == EROM_IMAGE + return iImageHeader->iRomHdr->iRomRootDirectoryList; + else + return iImageHeader->iExtRomHdr->iRomRootDirectoryList; +} + +TUint RomImageReader::GetHdrSize() +{ + TUint headerSize = 0; + if(EROM_IMAGE == iImgType){ + headerSize = sizeof(TRomLoaderHeader) + sizeof(TRomHeader); + }else if(EROMX_IMAGE == iImgType){ + headerSize = sizeof(TExtensionRomHeader); + }else if(EBAREROM_IMAGE == iImgType){ + headerSize = sizeof(TRomHeader); + } + return headerSize; +} + + +static const TInt KIOBytes = 0x100000; +// reading a huge buffer at a time is very slow, reading 1MB bytes at a time is much faster +void RomImageReader::ReadData(char* aBuffer, TUint aLength) +{ + TUint readBytes = 0 ; + while(readBytes < aLength){ + TUint toRead = KIOBytes; + if(readBytes + toRead > aLength) + toRead = aLength - readBytes ; + iFile.read(&aBuffer[readBytes],toRead); + readBytes += toRead ; + } +} +void RomImageReader::ProcessImage() +{ + if(iRomLayoutData) return ; + iImageHeader = new RomImageHeader(iHeaderBuffer, iImgType); + + iFile.seekg(0, ios::end); + // fileSize + TUint fileSize = iFile.tellg(); + + //let's skip the RomLoaderHeader + TUint romDataBegin = (EROM_IMAGE == iImgType) ? sizeof(TRomLoaderHeader) : 0 ; + iFile.seekg(romDataBegin,ios::beg); + + if(EROMX_IMAGE == iImgType){// EROMX_IMAGE, just set the iUnpagedRomBuffer + if(GetImageCompressionType() == KUidCompressionDeflate){ + TUint32 readLen = fileSize - sizeof(TExtensionRomHeader) ; + iRomSize = iImageHeader->iExtRomHdr->iUncompressedSize ; + iRomLayoutData = new char[iRomSize]; + char* temp = new char[readLen]; + // header is not compressed. + iFile.read(iRomLayoutData,sizeof(TExtensionRomHeader)); + ReadData(temp ,readLen); + TUint8* uncompressDest = reinterpret_cast(iRomLayoutData + sizeof(TExtensionRomHeader)); + InflateUnCompress(reinterpret_cast(temp),readLen,uncompressDest,iRomSize - sizeof(TExtensionRomHeader)); + delete []temp ; + + }else{ + iRomSize = fileSize ; + iRomLayoutData = new char[iRomSize]; + ReadData(iRomLayoutData,iRomSize); + } + } // end EROMX_IMAGE + else { + //EROM_IMAGE or EBAREROM_IMAGE + const TInt KPageSize = 0x1000; + TRomHeader *hdr = iImageHeader->iRomHdr; + iRomSize = hdr->iUncompressedSize ; + iRomLayoutData = new char[iRomSize]; + char* curDataPointer = iRomLayoutData ; + TUint totalReadBytes = 0; + bool hasPageableSec = (hdr->iPageableRomStart > 0 && hdr->iPageableRomSize > 0) ; + + // read data before unpaged + ReadData(curDataPointer,hdr->iCompressedUnpagedStart); + curDataPointer += hdr->iCompressedUnpagedStart ; + totalReadBytes += hdr->iCompressedUnpagedStart; + + // read the unpaged part, if compressed , then decompress + if(GetImageCompressionType() == KUidCompressionDeflate){ + char* temp = new char[hdr->iUnpagedCompressedSize]; + ReadData(temp,hdr->iUnpagedCompressedSize); + totalReadBytes += hdr->iUnpagedCompressedSize; + InflateUnCompress(reinterpret_cast(temp),hdr->iUnpagedCompressedSize,reinterpret_cast(curDataPointer) ,hdr->iUnpagedUncompressedSize); + delete []temp ; + }else{ + TUint unpagedSeclen ; + if(hasPageableSec) { // there is paged section + unpagedSeclen = hdr->iPageableRomStart - hdr->iCompressedUnpagedStart; + }else{ + unpagedSeclen = iRomSize - hdr->iCompressedUnpagedStart; + } + ReadData(curDataPointer,unpagedSeclen); + totalReadBytes += unpagedSeclen ; + } + curDataPointer = iRomLayoutData + totalReadBytes; + //if there is a paged section , read and extract it + + // read the paged section, + if(hasPageableSec){ + if((TUint)(hdr->iPageableRomStart + hdr->iPageableRomSize) > iRomSize){ + throw ImageReaderException("Incorrect values of ROM header fields.", ""); + } + if(0 == hdr->iRomPageIndex){ // + // no compression for paged section ,just read it + iFile.read(curDataPointer,iRomSize - totalReadBytes); + } + else{ + //aligment calculation + TUint pagedSecOffset = (totalReadBytes + KPageSize - 1) & (~(KPageSize - 1)); + if(pagedSecOffset > totalReadBytes){ + // there are gap bytes between unpaged and paged sections + iFile.read(curDataPointer,pagedSecOffset - totalReadBytes); + curDataPointer = iRomLayoutData + pagedSecOffset; + } + TUint pagedIndexCount = ( hdr->iUncompressedSize + KPageSize - 1) / KPageSize; + // how many bytes ? + // the page index table include the unpaged part ; + TUint firstPagedIndexTblItem = hdr->iPageableRomStart / KPageSize; + + TUint tempBufLen = KPageSize << 8; + char* readBuffer = new char[tempBufLen]; + + TUint8* src,*srcNext = NULL; + SRomPageInfo* pageInfo = reinterpret_cast(&iRomLayoutData[hdr->iRomPageIndex]); + CBytePair bp(EFalse); + for(TUint i = firstPagedIndexTblItem ; i < pagedIndexCount ; i+= 256){ + TUint endIndex = i + 255 ; + if(endIndex >= pagedIndexCount) + endIndex = pagedIndexCount - 1; + TUint readLen = pageInfo[endIndex].iDataStart + pageInfo[endIndex].iDataSize - pageInfo[i].iDataStart ; + iFile.read(readBuffer,readLen); + src = reinterpret_cast(readBuffer); + for(TUint j = i ; j <= endIndex ; j++){ + switch(pageInfo[j].iCompressionType) + { + case SRomPageInfo::EBytePair: + { + TInt unpacked = bp.Decompress(reinterpret_cast(curDataPointer), KPageSize, src, pageInfo[j].iDataSize, srcNext); + if (unpacked < 0) { + delete []readBuffer; + throw ImageReaderException("Corrupted BytePair compressed ROM image", ""); + } + curDataPointer += unpacked; + break ; + } + case SRomPageInfo::ENoCompression: + memcpy(curDataPointer,src,pageInfo[j].iDataSize); + curDataPointer += pageInfo[j].iDataSize ; + break ; + default: + delete []readBuffer; + throw ImageReaderException("Undefined compression type", ""); + break ; + + } + src += pageInfo[j].iDataSize; + } // end for(TUint j = i ; j <= endIndex ; j++) + } // end for(TUint i = firstPagedIndexTblItem ; i < pagedIndexCount ; i+= 256) + delete []readBuffer ; + }// else + + } // if(hasPageableSec) + + } + TUint32 offset = GetRootDirList() - GetRomBase(); + TRomRootDirectoryList* rootDirList = reinterpret_cast(iRomLayoutData + offset ); + TInt dirCount = rootDirList->iNumRootDirs ; + string tempName ; + for(TInt i = 0 ; i < dirCount ; i++) { + offset = rootDirList->iRootDir[i].iAddressLin - GetRomBase(); + TRomDir* romDir = reinterpret_cast(iRomLayoutData + offset); + Name(tempName,reinterpret_cast(romDir->iEntry.iName),romDir->iEntry.iNameLength); + BuildDir(romDir, iRomImageRootDirEntry); + } + +} + + +void RomImageReader::BuildDir(TRomDir* aDir, RomImageFSEntry* aPaFSEntry) +{ + + TInt processBytes = 0 ; + TInt totalDirBytes = aDir->iSize - sizeof(aDir->iSize); + TRomEntry* entry = &aDir->iEntry; + RomImageFSEntry *fsEntry ; + string name ; + const char* pritableName = ""; + + while(processBytes < totalDirBytes){ + Name(name,reinterpret_cast(entry->iName),entry->iNameLength); + pritableName = name.c_str(); + if(entry->iAtt & 0x10) { // is a directory + fsEntry = new RomImageDirEntry(pritableName); + AddChild(aPaFSEntry,fsEntry,NULL); + TUint offset = entry->iAddressLin - GetRomBase(); + TRomDir* subFolder = reinterpret_cast(iRomLayoutData + offset); + BuildDir(subFolder,fsEntry); + } + else{ + fsEntry = new RomImageFileEntry(pritableName); + AddChild(aPaFSEntry,fsEntry,entry); + } + // increase the processedBytes + processBytes += (entry->iNameLength << 1) + reinterpret_cast(entry->iName) - reinterpret_cast(entry); + + //align to next 4 bytes + processBytes = (processBytes + 3) & ( ~3 ); + // get next entry + entry = reinterpret_cast( reinterpret_cast(&aDir->iEntry) + processBytes); + } + +} + +void RomImageReader::AddChild(RomImageFSEntry *aParent, RomImageFSEntry *aChild, TRomEntry* aRomEntry) +{ + if(!aParent->iChildren) + aParent->iChildren = aChild; + else { + RomImageFSEntry *aLast = aParent->iChildren; + + while(aLast->iSibling) + aLast = aLast->iSibling; + aLast->iSibling = aChild; + } + + if(!aChild->IsDirectory()) { + RomImageFileEntry* file = static_cast(aChild); + file->iTRomEntryPtr = aRomEntry; + + if(aRomEntry->iAddressLin > GetRomBase()) { + TUint32 offset = aRomEntry->iAddressLin - GetRomBase(); + + TRomImageHeader* imgHdr = reinterpret_cast(iRomLayoutData + offset); + + file->ImagePtr.iRomFileEntry = imgHdr; + + TUint8 aUid1[4]; + memcpy(aUid1, &file->ImagePtr.iRomFileEntry->iUid1, 4); + + if( ReaderUtil::IsExecutable(aUid1) ) { + file->iExecutable = true; + } + else { + file->iExecutable = false; + file->ImagePtr.iDataFileAddr = aRomEntry->iAddressLin; + } + } + else { + file->ImagePtr.iRomFileEntry = NULL; + } + } + + if(aParent != iRomImageRootDirEntry) { + aChild->iPath = aParent->iPath; + aChild->iPath += DIR_SEPARATOR; + aChild->iPath += aParent->iName.c_str(); + } +} + +void RomImageReader::Name(string& aName, const wchar_t* aUnicodeName, TUint aLen) +{ + char* temp = (char*)_alloca((aLen << 1) + 1) ; + size_t n = wcsrtombs(temp,&aUnicodeName,aLen,NULL); + if(n == (size_t)-1){ // the unicode string can not be coverted. + aName = "???"; + } + temp[n] = 0; + if(n > 0) + aName.assign(temp,n) ; + else + aName = ""; + +} + +void RomImageReader::DumpTree() +{ + RomImageFSEntry* aFsEntry = iRomImageRootDirEntry; + if( aFsEntry->iChildren ) + DumpSubTree(aFsEntry->iChildren); +} + +void RomImageReader::DumpDirStructure() +{ + *out << "Directory Listing" << endl; + *out << "=================" << endl; + int aPadding = 0; + if( iRomImageRootDirEntry ){ + DumpDirStructure(iRomImageRootDirEntry, aPadding); + } + *out << endl << endl; +} + +void RomImageReader::DumpDirStructure(RomImageFSEntry* aEntry, int &aPadding) +{ + if(!aEntry) + return; + + int aPadLen = 2 * aPadding;//scaling for legibility + for (int i = 0; i < aPadLen; i++) + *out << " "; + + *out << aEntry->Name() << endl; + + if( aEntry->iChildren){ + aPadding++; + DumpDirStructure(aEntry->iChildren, aPadding); + aPadding--; + } + DumpDirStructure(aEntry->iSibling, aPadding); +} + +void RomImageReader::DumpSubTree(RomImageFSEntry* aFsEntry) +{ + if(!aFsEntry) + return; + + if( aFsEntry->iChildren ){ + DumpSubTree(aFsEntry->iChildren); + } + + if( aFsEntry->iSibling ) + DumpSubTree(aFsEntry->iSibling); + + RomImageFSEntry *aEntry = aFsEntry; + + if(!aEntry->IsDirectory()) { + *out << "********************************************************************" << endl; + *out << "File........................" << aEntry->iPath.c_str() << DIR_SEPARATOR << aEntry->Name() << endl; + + if( ((RomImageFileEntry*)aEntry)->iExecutable ) { + DumpImage((RomImageFileEntry*)aEntry); + } + else{ + *out << "Linear Addr................." << ((RomImageFileEntry*)aEntry)->ImagePtr.iDataFileAddr << endl; + } + } +} + +void RomImageReader::DumpImage(RomImageFileEntry * aEntry) +{ + bool aContinue = true; + + DumpInHex("Load Address", aEntry->iTRomEntryPtr->iAddressLin) << endl; + DumpInHex("Size", aEntry->iTRomEntryPtr->iSize) << endl; + + TRomImageHeader *aRomImgEntry = aEntry->ImagePtr.iRomFileEntry; + + if( !aRomImgEntry ) + return; + //UIDs + DumpInHex("Uids", aRomImgEntry->iUid1); + DumpInHex(" ", aRomImgEntry->iUid2, aContinue); + DumpInHex(" ", aRomImgEntry->iUid3, aContinue); + DumpInHex(" ", aRomImgEntry->iUidChecksum, aContinue) << endl; + + DumpInHex("Entry point", aRomImgEntry->iEntryPoint) << endl; + DumpInHex("Code start addr", aRomImgEntry->iCodeAddress) << endl; + DumpInHex("Data start addr", aRomImgEntry->iDataAddress) << endl; + DumpInHex("DataBssLinearBase", aRomImgEntry->iDataBssLinearBase) << endl; + DumpInHex("Text size", aRomImgEntry->iTextSize) << endl; + DumpInHex("Code size", aRomImgEntry->iCodeSize) << endl; + DumpInHex("Data size", aRomImgEntry->iDataSize) << endl; + DumpInHex("Bss size", (aRomImgEntry->iBssSize)) << endl; + DumpInHex("Total data size", aRomImgEntry->iTotalDataSize) << endl; + DumpInHex("Heap min", aRomImgEntry->iHeapSizeMin) << endl; + DumpInHex("Heap max", aRomImgEntry->iHeapSizeMax) << endl; + DumpInHex("Stack size", aRomImgEntry->iStackSize) << endl; + + TDllRefTable *aRefTbl = NULL; + + if( aRomImgEntry->iDllRefTable ) { + TUint32 aOff = (TUint32)aRomImgEntry->iDllRefTable - iImageHeader->iRomHdr->iRomBase; + aRefTbl = (TDllRefTable*) ((char*)iImageHeader->iRomHdr + aOff); + TUint32 aVirtualAddr = (TUint32)aRefTbl->iEntry[0]; + DumpInHex("Dll ref table", aVirtualAddr) << endl; + } + + DumpInHex("Export directory", aRomImgEntry->iExportDir) << endl; + DumpInHex("Export dir count", aRomImgEntry->iExportDirCount) << endl; + DumpInHex("Hardware variant", aRomImgEntry->iHardwareVariant) << endl; + DumpInHex("Flags", aRomImgEntry->iFlags) << endl; + DumpInHex("Secure ID", aRomImgEntry->iS.iSecureId) << endl; + DumpInHex("Vendor ID", aRomImgEntry->iS.iVendorId) << endl; + + DumpInHex("Capability", aRomImgEntry->iS.iCaps[1]); + DumpInHex(" ", aRomImgEntry->iS.iCaps[0], aContinue) << endl; + + *out << "Tools Version..............." << dec << (TUint)aRomImgEntry->iToolsVersion.iMajor; + *out << "." ; + out->width(2) ; + out->fill('0'); + *out << dec << (TUint)aRomImgEntry->iToolsVersion.iMinor ; + *out << "(" << dec << aRomImgEntry->iToolsVersion.iBuild << ")"; + *out << endl; + + *out << "Module Version.............." << dec << (aRomImgEntry->iModuleVersion >> 16) << endl; + DumpInHex("Exception Descriptor", aRomImgEntry->iExceptionDescriptor) << endl; + *out << "Priority...................." << dec << aRomImgEntry->iPriority << endl; + + if( aRefTbl ) + DumpInHex("Dll ref table size", aRefTbl->iNumberOfEntries*8) << endl; + else + DumpInHex("Dll ref table size", 0) << endl; + + if( iDisplayOptions & DUMP_E32_IMG_FLAG){ + if(stricmp(iE32ImgFileName.c_str(), aEntry->Name()) == 0){ + TUint aSectionOffset = aRomImgEntry->iCodeAddress - iImageHeader->iRomHdr->iRomBase; + TUint* aCodeSection = (TUint*)((char*)iImageHeader->iRomHdr + aSectionOffset); + *out << "\nCode (Size=0x" << hex << aRomImgEntry->iCodeSize << ")" << endl; + DumpData(aCodeSection, aRomImgEntry->iCodeSize); + + aSectionOffset = aRomImgEntry->iDataAddress - iImageHeader->iRomHdr->iRomBase; + TUint* aDataSection = (TUint*)((char*)iImageHeader->iRomHdr + aSectionOffset); + if( aRomImgEntry->iDataSize){ + *out << "\nData (Size=0x" << hex << aRomImgEntry->iDataSize << ")" << endl; + DumpData(aDataSection, aRomImgEntry->iDataSize); + } + } + } + + *out << endl << endl; +} + +void RomImageReader::DumpAttribs(RomImageFSEntry* aFsEntry) +{ + +// a larger rom image cause stack overflow under visual studio if we use recursion algorithm here. +// can gcc compiler guarantee this overflow will never be happen ? + if( aFsEntry->iChildren ) + DumpAttribs(aFsEntry->iChildren); + + if(aFsEntry->iSibling) + DumpAttribs(aFsEntry->iSibling); + if(aFsEntry->IsDirectory()) return ; + RomImageFileEntry* file = static_cast(aFsEntry); + if(!file->iExecutable) return ; + TRomImageHeader* aRomImgEntry = file->ImagePtr.iRomFileEntry; + + if( !aRomImgEntry) return; + + const char* prefix ; + if(aRomImgEntry->iFlags & KRomImageFlagPrimary){ + prefix = "Primary"; + } + else if(aRomImgEntry->iFlags & KRomImageFlagVariant){ + prefix = "Variant"; + } + else if(aRomImgEntry->iFlags & KRomImageFlagExtension){ + prefix = "Extension"; + } + else if(aRomImgEntry->iFlags & KRomImageFlagDevice){ + prefix = "Device"; + } + else + return; + + out->width(10); + out->fill(' '); + *out << left << prefix; + out->width(40); + *out << right << file->Name() << "[" ; + DumpInHex( "", aRomImgEntry->iHardwareVariant, true) << "] "; + DumpInHex( " DataSize=", (aRomImgEntry->iBssSize + aRomImgEntry->iDataSize), true) << endl; + +} + +void RomImageReader::Dump() +{ + if( !((iDisplayOptions & EXTRACT_FILES_FLAG) || + (iDisplayOptions & LOG_IMAGE_CONTENTS_FLAG) || + (iDisplayOptions & EXTRACT_FILE_SET_FLAG)) ) { + *out << "Image Name................." << iImgFileName.c_str() << endl; + + if( iImageHeader->iRomHdr ) + iImageHeader->DumpRomHdr(); + else + iImageHeader->DumpRomXHdr(); + + DumpAttribs(iRomImageRootDirEntry); + *out << endl ; + + if(iDisplayOptions & DUMP_VERBOSE_FLAG) { + DumpDirStructure(); + DumpTree(); + } + + if(iDisplayOptions & DUMP_DIR_ENTRIES_FLAG) { + DumpDirStructure(); + } + } +} + + +/** +Function iterates through all the entries in the image +by making a call to TraverseImage function. + +@internalComponent +@released +*/ +void RomImageReader::ExtractImageContents() +{ + if( (iDisplayOptions & EXTRACT_FILE_SET_FLAG) ) + { + //TODO: + ImageReader::ExtractFileSet(iRomLayoutData); + } + + if( iDisplayOptions & EXTRACT_FILES_FLAG || iDisplayOptions & LOG_IMAGE_CONTENTS_FLAG ) + { + if(iRomImageRootDirEntry) + { + // name of the log file. + string logFile; + // output stream for the log file. + ofstream oFile; + + if( iDisplayOptions & LOG_IMAGE_CONTENTS_FLAG){ + if( ImageReader::iZdrivePath.compare("")){ + // create a string to hold path information. + string filePath(ImageReader::iZdrivePath); + string delimiter("\\"); + // replace backslash with double backslash. + FindAndInsertString(filePath,delimiter,delimiter); + logFile = filePath; + // create specified directory. + CreateSpecifiedDir(&filePath[0],"\\\\"); + logFile.append("\\\\"); + logFile.append(ImageReader::iLogFileName); + } + else + { + logFile = ImageReader::iLogFileName; + } + // open the specified file in append mode. + oFile.open(logFile.c_str() ,ios::out|ios::app); + + if(!oFile.is_open()){ + throw ImageReaderException((char*)ImageReader::iLogFileName.c_str(), "Failed to open the log file"); + } + } + TraverseImage(iRomImageRootDirEntry,oFile); + if(oFile.is_open()) oFile.close(); + } + } +} + + +/** +Function to traverse entire image and check for an entity.If the entity found in the image is a file +then it makes a call to CheckFileExtension to check for extension. + +@internalComponent +@released + +@param aEntity - pointer to the entry in rom image. +@param aFile - output stream. +*/ +void RomImageReader::TraverseImage(RomImageFSEntry* aEntity,ofstream& aFile) +{ + if(!aEntity->IsDirectory()) { + CheckFileExtension(aEntity,aFile); + } + + if (aEntity->iChildren) { + TraverseImage(aEntity->iChildren,aFile); + } + + if (aEntity->iSibling) { + TraverseImage(aEntity->iSibling,aFile); + } +} + + +/** +Function to get check extension of the given file.If the extension of the file is "sis" +then call ExtractFile function to extract the file from the image. + +@internalComponent +@released + +@param aEntity - pointer to the entry in rom image. +@param aFile - output stream. +*/ +void RomImageReader::CheckFileExtension(RomImageFSEntry* aEntity,ofstream& aFile) +{ + RomImageFileEntry* romEntry = (RomImageFileEntry*)aEntity; + // get the size of the entity. + TUint32 size = romEntry->iTRomEntryPtr->iSize; + // get the offset of the entity. + TUint32 offset = romEntry->iTRomEntryPtr->iAddressLin - GetRomBase() ; + + const char* fileName = aEntity->iName.c_str(); + + // create a string to hold the path information. + string romfilePath(romEntry->iPath); + string forwardSlash("/"); + string slash("\\"); + //replace slash with double backward slash. + FindAndReplaceString( romfilePath, forwardSlash, slash ); + + if( iDisplayOptions & LOG_IMAGE_CONTENTS_FLAG && iDisplayOptions & EXTRACT_FILES_FLAG ) { + // get the position. + size_t pos = aEntity->iName.find_last_of("."); + + const char* extName = fileName + ( pos + 1 ); + if ( !stricmp(extName ,"SIS") || !stricmp(extName ,"DAT") ) { + // if the two strings are same then extract the corresponding file. + ImageReader::ExtractFile(offset,size,fileName,&romfilePath[0],&ImageReader::iZdrivePath[0],iRomLayoutData); + } + else { + LogRomEnrtyToFile(romfilePath.c_str(),fileName,aFile); + } + } + else if( iDisplayOptions & LOG_IMAGE_CONTENTS_FLAG ) { + LogRomEnrtyToFile(romfilePath.c_str(),fileName,aFile); + } + else { + if(romEntry->iExecutable) { + size += sizeof(TRomImageHeader); + } + // extract the corresponding file. + ImageReader::ExtractFile(offset,size,fileName,&romfilePath[0],&ImageReader::iZdrivePath[0],iRomLayoutData); + } +} + + +/** +Function to log the rom entry to a specified file. + +@internalComponent +@released + +@param aPath - Complete path of an entity. +@param aEntityName - Entity name. +@param aFile - output stream. +*/ +void RomImageReader::LogRomEnrtyToFile(const char* aPath,const char* aEntityName,ofstream& aFile) +{ + if(aFile.is_open()) + { + aFile.seekp(0,ios::end); + aFile<IsDirectory()) { + + RomImageFileEntry* romEntry = (RomImageFileEntry*)aEntity; + + PFILEINFO fileInfo = new FILEINFO; + + // get the size of the entity. + fileInfo->iSize = romEntry->iTRomEntryPtr->iSize; + // get the offset of the entity. + fileInfo->iOffset = (romEntry->iTRomEntryPtr->iAddressLin - GetRomBase()); + + if(romEntry->iExecutable) { + fileInfo->iSize += sizeof(TRomImageHeader); + } + + if((fileInfo->iOffset + fileInfo->iSize) > iRomSize) { + fileInfo->iOffset = 0; + fileInfo->iSize = 0; + } + + string fileName(romEntry->iPath); + fileName.append(DIR_SEPARATOR); + fileName.append(aEntity->iName); + + aFileMap[fileName] = fileInfo; + } + + if (aEntity->iChildren) { + ProcessDirectory(aEntity->iChildren, aFileMap); + } + + if (aEntity->iSibling) { + ProcessDirectory(aEntity->iSibling, aFileMap); + } +} + +/** +Function to read the directory structure details of te ROM image. + +@internalComponent +@released + +@param aFileMap - map of filename with its size and offset values. +*/ +void RomImageReader::GetFileInfo(FILEINFOMAP &aFileMap) { + ProcessDirectory(iRomImageRootDirEntry, aFileMap); +} + +/** +Function to get the ROM image size. + +@internalComponent +@released +*/ +TUint32 RomImageReader::GetImageSize() { + return iRomSize; +} +