fix: support new trace compiler features for preventing clashes. Automatically turn on OST_TRACE_COMPILER_IN_USE macro. Look for trace header in systemincludes. Make directories in makefile parse to prevent clashes during build. Correct path for autogen headers. Correct case issue with autogen headers on Linux.
/*
* 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 <e32rom.h>
#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<TText *>(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) <<endl;
DumpInHex("KernelConfigFlags", iRomHdr->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<TUint8*>(iRomLayoutData + sizeof(TExtensionRomHeader));
InflateUnCompress(reinterpret_cast<TUint8*>(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<TUint8*>(temp),hdr->iUnpagedCompressedSize,reinterpret_cast<TUint8*>(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<SRomPageInfo*>(&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<TUint8*>(readBuffer);
for(TUint j = i ; j <= endIndex ; j++){
switch(pageInfo[j].iCompressionType)
{
case SRomPageInfo::EBytePair:
{
TInt unpacked = bp.Decompress(reinterpret_cast<TUint8*>(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<TRomRootDirectoryList*>(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<TRomDir*>(iRomLayoutData + offset);
Name(tempName,reinterpret_cast<const wchar_t *>(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<const wchar_t *>(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<TRomDir*>(iRomLayoutData + offset);
BuildDir(subFolder,fsEntry);
}
else{
fsEntry = new RomImageFileEntry(pritableName);
AddChild(aPaFSEntry,fsEntry,entry);
}
// increase the processedBytes
processBytes += (entry->iNameLength << 1) + reinterpret_cast<TInt>(entry->iName) - reinterpret_cast<TInt>(entry);
//align to next 4 bytes
processBytes = (processBytes + 3) & ( ~3 );
// get next entry
entry = reinterpret_cast<TRomEntry*>( reinterpret_cast<char*>(&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<RomImageFileEntry*>(aChild);
file->iTRomEntryPtr = aRomEntry;
if(aRomEntry->iAddressLin > GetRomBase()) {
TUint32 offset = aRomEntry->iAddressLin - GetRomBase();
TRomImageHeader* imgHdr = reinterpret_cast<TRomImageHeader*>(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<RomImageFileEntry*>(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<<aPath<<"\\"<<aEntityName<<"\n";
}
}
/**
Function to read the directory structure details of te ROM image.
@internalComponent
@released
@param aEntity - pointer to the entry in rom image.
@param aFileMap - map of filename with its size and offset values.
@param aImgSize - Image size
*/
void RomImageReader::ProcessDirectory(RomImageFSEntry *aEntity, FILEINFOMAP &aFileMap)
{
if(!aEntity->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;
}