imgtools/romtools/rombuild/r_obey.cpp
changeset 590 360bd6b35136
parent 0 044383f39525
child 626 ac03b93ca9c4
equal deleted inserted replaced
588:c7c26511138f 590:360bd6b35136
    16 */
    16 */
    17 
    17 
    18 
    18 
    19 #include <string.h>
    19 #include <string.h>
    20 
    20 
    21 #ifdef __VC32__
    21 #include <strstream>
    22  #ifdef __MSVCDOTNET__
    22 #include <iomanip>
    23   #include <strstream>
    23 
    24   #include <iomanip>
       
    25  #else //!__MSVCDOTNET__
       
    26   #include <strstrea.h>
       
    27   #include <iomanip.h>
       
    28  #endif //__MSVCDOTNET__
       
    29 #else //!__VC32__
       
    30 #ifdef __TOOLS2__
       
    31  #include <sstream>
       
    32   #include <iomanip>
       
    33 #else
       
    34  #include <strstream.h>
       
    35  #include <iomanip.h>
       
    36 #endif 
       
    37 #endif //__VC32__
       
    38 
    24 
    39 #include <stdlib.h>
    25 #include <stdlib.h>
    40 #include <stdio.h>
    26 #include <stdio.h>
    41 #include <time.h>
    27 #include <time.h>
    42 #include <assert.h>
    28 #include <assert.h>
    43 
    29 #include <errno.h>
    44 #include "e32std.h"
    30 
    45 #include "e32std_private.h"
    31 #include <e32std.h>
    46 #include "e32rom.h"
    32 #include <e32std_private.h>
    47 #include "u32std.h"
    33 #include <e32rom.h>
       
    34 #include <u32std.h>
       
    35 #include <f32file.h>
    48 
    36 
    49 #include "r_rom.h"
    37 #include "r_rom.h"
    50 #include "r_obey.h"
    38 #include "r_obey.h"
    51 #include "r_global.h"
    39 #include "r_global.h"
    52 #include "h_utl.h"
    40 #include "h_utl.h"
    53 #include "patchdataprocessor.h"
    41 #include "patchdataprocessor.h"
    54 #include "r_coreimage.h"
    42 #include "r_coreimage.h" 
    55 
    43 
    56 #define _P(word)	word, sizeof(word)-1	// match prefix, optionally followed by [HWVD]
    44 #define _P(word)	word, sizeof(word)-1	// match prefix, optionally followed by [HWVD]
    57 #define _K(word)	word, 0					// match whole word
    45 #define _K(word)	word, 0					// match whole word
    58 
    46 static char* const NullString = "" ;
    59 const ObeyFileKeyword ObeyFileReader::iKeywords[] =
    47 const ObeyFileKeyword ObeyFileReader::iKeywords[] = {
    60 {
       
    61 	{_P("file"),		2,-2, EKeywordFile, "Executable file to be loaded into the ROM"},
    48 	{_P("file"),		2,-2, EKeywordFile, "Executable file to be loaded into the ROM"},
    62 	{_P("data"),		2,-2, EKeywordData, "Data file to be copied into the ROM"},
    49 	{_P("data"),		2,-2, EKeywordData, "Data file to be copied into the ROM"},
    63 	{_P("primary"),		1+2,-2, EKeywordPrimary, "An EPOC Kernel"},
    50 	{_P("primary"),		1+2,-2, EKeywordPrimary, "An EPOC Kernel"},
    64 	{_P("secondary"),	2,-2, EKeywordSecondary, "?"},
    51 	{_P("secondary"),	2,-2, EKeywordSecondary, "?"},
    65 	{_P("variant"),		1+2,-2, EKeywordVariant, "?"},
    52 	{_P("variant"),		1+2,-2, EKeywordVariant, "?"},
   137 	{_K("filecompressbytepair"),  	2, -2, EKeywordExecutableCompressionMethodBytePair, "Byte pair compresion method for the individual executable image."},
   124 	{_K("filecompressbytepair"),  	2, -2, EKeywordExecutableCompressionMethodBytePair, "Byte pair compresion method for the individual executable image."},
   138 	{_K("kernelconfig"), 1, 2, EKeywordKernelConfig, "Set an arbitrary bit of the kernel config flags to on/off)"},
   125 	{_K("kernelconfig"), 1, 2, EKeywordKernelConfig, "Set an arbitrary bit of the kernel config flags to on/off)"},
   139 	{_K("maxunpagedsize"),	1, 1, EKeywordMaxUnpagedMemSize, "Maxinum unpaged size in ROM image. Default is no limited."},
   126 	{_K("maxunpagedsize"),	1, 1, EKeywordMaxUnpagedMemSize, "Maxinum unpaged size in ROM image. Default is no limited."},
   140 	{_K("hcrdata") , 2, 2,EKeywordHardwareConfigRepositoryData,"HCR image data"},
   127 	{_K("hcrdata") , 2, 2,EKeywordHardwareConfigRepositoryData,"HCR image data"},
   141 	{0,0,0,0,EKeywordNone,""} 
   128 	{0,0,0,0,EKeywordNone,""} 
   142 	
   129 
   143 };
   130 };
   144 
   131 
   145 void ObeyFileReader::KeywordHelp() // static
   132 void ObeyFileReader::KeywordHelp() { // static
   146 	{
   133 
   147 	cout << "Obey file keywords:\n";
   134 	cout << "Obey file keywords:\n";
   148 
   135 
   149 	const ObeyFileKeyword* k=0;
   136 	const ObeyFileKeyword* k=0;
   150 	for (k=iKeywords; k->iKeyword!=0; k++)
   137 	for (k=iKeywords; k->iKeyword!=0; k++) {
   151 		{
       
   152 		if (k->iHelpText==0)
   138 		if (k->iHelpText==0)
   153 			continue;
   139 			continue;
   154 		if (k->iHelpText[0]=='(' && !H.iVerbose)
   140 		if (k->iHelpText[0]=='(' && !H.iVerbose)
   155 			continue;	// don't normally report things in (parentheses)
   141 			continue;	// don't normally report things in (parentheses)
   156 
   142 
   159 		if (k->iKeywordLength)
   145 		if (k->iKeywordLength)
   160 			memcpy(buf+k->iKeywordLength,"[HWVD]",6);
   146 			memcpy(buf+k->iKeywordLength,"[HWVD]",6);
   161 		if (H.iVerbose)
   147 		if (H.iVerbose)
   162 			sprintf(buf+20,"%2d",k->iNumArgs);
   148 			sprintf(buf+20,"%2d",k->iNumArgs);
   163 		cout << "    " << buf << " " << k->iHelpText << endl;
   149 		cout << "    " << buf << " " << k->iHelpText << endl;
   164 		}
   150 	}
   165 	cout << endl;
   151 	cout << endl;
   166 
   152 
   167 	cout << "File attributes:\n";
   153 	cout << "File attributes:\n";
   168 
   154 
   169 	const FileAttributeKeyword* f=0;
   155 	const FileAttributeKeyword* f=0;
   170 	for (f=iAttributeKeywords; f->iKeyword!=0; f++)
   156 	for (f=iAttributeKeywords; f->iKeyword!=0; f++) {
   171 		{
       
   172 		if (f->iHelpText==0)
   157 		if (f->iHelpText==0)
   173 			continue;
   158 			continue;
   174 		if (f->iHelpText[0]=='(' && !H.iVerbose)
   159 		if (f->iHelpText[0]=='(' && !H.iVerbose)
   175 			continue;	// don't normally report things in (parentheses)
   160 			continue;	// don't normally report things in (parentheses)
   176 
   161 
   177 		char buf[32];
   162 		char buf[32];
   178 		sprintf(buf, "%-20s", f->iKeyword);
   163 		sprintf(buf, "%-20s", f->iKeyword);
   179 		if (H.iVerbose)
   164 		if (H.iVerbose)
   180 			sprintf(buf+20,"%2d",k->iNumArgs);
   165 			sprintf(buf+20,"%2d",k->iNumArgs);
   181 		cout << "    " << buf << " " << f->iHelpText << endl;
   166 		cout << "    " << buf << " " << f->iHelpText << endl;
   182 		}
   167 	}
   183 	cout << endl;
   168 	cout << endl;
   184 	}
   169 }
   185 
   170 
   186 TInt NumberOfVariants=0;
   171 TInt NumberOfVariants=0;
   187 
       
   188 ObeyFileReader::ObeyFileReader(TText* aFileName):
       
   189 //
   172 //
   190 // Constructor
   173 // Constructor
   191 //
   174 //
   192 	iMark(0), iMarkLine(0), iCurrentMark(0), iCurrentLine(0), imaxLength(0),iSuffix(0),iLine(0)
   175 ObeyFileReader::ObeyFileReader(const char* aFileName):iFileName(aFileName),iCurrentLine(0), iNumWords(0),iLine(0),iMarkLine(0)  {
   193 	{
   176 	for(TUint i = 0 ; i < KNumWords ; i++)
   194 
   177 		iWord[i] = NullString ;	 
   195 	iFileName = new TText[strlen((const char *)aFileName)+1];
   178 	*iSuffix = 0 ; 
   196 	strcpy((char *)iFileName,(const char *)aFileName);
   179 
   197 	}
   180 }
   198 
   181 
   199 ObeyFileReader::~ObeyFileReader()
   182 ObeyFileReader::~ObeyFileReader() {
   200 	{
   183 	if(iLine)
   201 	if (iObeyFile)
   184 		delete [] iLine;
   202 		fclose(iObeyFile);
   185 }
   203 	iObeyFile=0;
       
   204 	delete [] iFileName;
       
   205 	delete [] iLine;
       
   206 	}
       
   207 
       
   208 TBool ObeyFileReader::Open()
       
   209 //
   186 //
   210 // Open the file & return a status
   187 // Open the file & return a status
   211 //
   188 //
   212 	{
   189 TBool ObeyFileReader::Open() {
   213 
   190 	ifstream ifs(iFileName.c_str(),ios_base::in + ios_base::binary);
   214  	iObeyFile = fopen((const char *)iFileName,"r");
   191 	if (!ifs.is_open()) {
   215 	if (!iObeyFile)
   192 		Print(EError,"Cannot open obey file %s\n",iFileName.c_str());
   216 		{
       
   217 		Print(EError,"Cannot open obey file %s\n",iFileName);
       
   218 		return EFalse;
   193 		return EFalse;
   219 		}
   194 	}
   220 	if (SetLineLengthBuffer() != KErrNone)
   195 	iLines.clear();
   221 	 	{
   196 	if(iLine){
   222 		Print(EError,"Insufficent Memory to Continue.");	
   197 		delete []iLine;
   223 	 	return EFalse;
   198 		iLine = 0 ;
   224 		}
   199 	}		
       
   200 	ifs.seekg(0,ios_base::end);
       
   201 	size_t length = ifs.tellg();
       
   202 	char* buffer = new char[length + 2];
       
   203 	if (0 == buffer) {
       
   204 		Print(EError,"Insufficient Memory to Continue.");
       
   205 		return EFalse;
       
   206 	}
       
   207 	ifs.seekg(0,ios_base::beg);
       
   208 	ifs.read(buffer,length); 
       
   209 	size_t readcout = ifs.gcount() ;
       
   210 	if(readcout != length){ 	
       
   211 		Print(EError,"Cannot Read All of File.");	
       
   212 		delete []buffer ;
       
   213 		ifs.close();
       
   214 		return EFalse;
       
   215 	}
       
   216 	buffer[length] = '\n';
       
   217 	buffer[length + 1] = 0 ; 
       
   218 	ifs.close();
       
   219 	char* lineStart = buffer ;
       
   220 	char* end = buffer + length ;
       
   221 	string line ;
       
   222 	size_t maxLengthOfLine = 0 ; 
       
   223 	while(lineStart <= end){
       
   224 		while(*lineStart == ' ' || *lineStart == '\t') //trimleft 
       
   225 			lineStart ++ ;		
       
   226 		char* lineEnd = lineStart ;	 
       
   227 		while(*lineEnd != '\r' && *lineEnd != '\n')
       
   228 			lineEnd ++ ;
       
   229 		if(strnicmp(lineStart,"REM",3) == 0){
       
   230 			line = "" ; // REMOVE "REM ... "
       
   231 		}
       
   232 		else {
       
   233 			TInt lastIndex = lineEnd - lineStart - 1;
       
   234 			while(lastIndex >= 0 &&  // trimright
       
   235 				(lineStart[lastIndex] == ' ' || lineStart[lastIndex] == '\t'))
       
   236 				lastIndex -- ;
       
   237 			if(lastIndex >= 0)
       
   238 				line.assign(lineStart,lastIndex + 1);
       
   239 			else
       
   240 				line = "";
       
   241 		}
       
   242 	 
       
   243 
       
   244 		if(line.length() > maxLengthOfLine)
       
   245 			maxLengthOfLine = line.length();
       
   246 		iLines.push_back(line);
       
   247 		if(*lineEnd == '\r') {
       
   248 			if(lineEnd[1] == '\n')
       
   249 				lineStart = lineEnd + 2 ;
       
   250 			else
       
   251 				lineStart = lineEnd + 1 ;
       
   252 		}
       
   253 		else // '\n'
       
   254 			lineStart = lineEnd + 1 ; 
       
   255 	}	
       
   256 	delete []buffer ;
       
   257 	iLine = new char[maxLengthOfLine + 1]; 
       
   258 	iCurrentLine = 0 ;
       
   259 	iMarkLine = 0 ;
   225 	return ETrue;
   260 	return ETrue;
   226 	}
   261 }
   227 
   262  
   228 TInt ObeyFileReader::SetLineLengthBuffer()
   263 
   229 // Get the Max Line length for the given obey file and allocate the buffer.
   264 void ObeyFileReader::Mark()	{ 
   230 	{
   265 	iMarkLine = iCurrentLine - 1;
   231 	char ch = '\0';
   266 }
   232 	TInt length = 0;
   267 
   233 		
   268 void ObeyFileReader::MarkNext() { 
   234 	Rewind();
       
   235 	while ((ch = (char)fgetc(iObeyFile)) != EOF)
       
   236 		{
       
   237 		length++;
       
   238 		if (ch == '\n')
       
   239 			{
       
   240 			if (length > imaxLength)
       
   241 				imaxLength = length;
       
   242 			length = 0;				
       
   243 			}
       
   244 		}
       
   245 	
       
   246 	if (length > imaxLength)
       
   247 		imaxLength = length;
       
   248 		
       
   249 	if (0 == imaxLength)
       
   250 		{
       
   251 		Print(EError,"Empty obey file passed as input.");
       
   252 		exit(-1);
       
   253 		}			
       
   254 	else if (imaxLength < 2)
       
   255 		{
       
   256 		Print(EError,"Invalid obey file passed as input.");
       
   257 		exit(-1);
       
   258 		}
       
   259 		
       
   260 	Rewind();
       
   261 	iLine = new TText[imaxLength+1];
       
   262 	
       
   263 	if(!iLine)
       
   264 		return KErrNoMemory;
       
   265 
       
   266 	return KErrNone;
       
   267 	}
       
   268 
       
   269 void ObeyFileReader::Mark()
       
   270 	{
       
   271 
       
   272 	iMark = iCurrentMark;
       
   273 	iMarkLine = iCurrentLine-1;
       
   274 	}
       
   275 
       
   276 void ObeyFileReader::MarkNext()
       
   277 	{
       
   278 
       
   279 	iMark = ftell(iObeyFile);
       
   280 	iMarkLine = iCurrentLine;
   269 	iMarkLine = iCurrentLine;
   281 	}
   270 }
   282 
   271 
   283 void ObeyFileReader::Rewind()
   272 void ObeyFileReader::Rewind() {
   284 	{
       
   285 	
       
   286 	fseek(iObeyFile,iMark,SEEK_SET);
       
   287 	iCurrentMark = iMark;
       
   288 	iCurrentLine = iMarkLine;
   273 	iCurrentLine = iMarkLine;
   289 	}
   274 }
   290 
   275 
   291 void ObeyFileReader::CopyWord(TInt aIndex, TText*& aString)
   276 char* ObeyFileReader::DupWord(TInt aIndex) const {
   292 	{
   277 	char* retVal = 0 ;
   293 	aString = new TText[strlen((const char *)iWord[aIndex])+1];
   278 	if(aIndex >= 0 && aIndex < (TInt)KNumWords){
   294 	strcpy((char *)aString, (const char *)iWord[aIndex]);
   279 		size_t len = strlen(iWord[aIndex]) + 1;
   295 	}
   280 		retVal = new char[len];
   296 
   281 		if(retVal)
   297 TInt ObeyFileReader::ReadAndParseLine()
   282 			memcpy(retVal,iWord[aIndex],len);
   298 	{
   283 	} 
   299 	if (feof(iObeyFile))
   284 	return retVal ;
       
   285 }
       
   286 
       
   287 
       
   288 TInt ObeyFileReader::ReadAndParseLine() {
       
   289 	if (iCurrentLine >= (TInt)iLines.size())
   300 		return KErrEof;
   290 		return KErrEof;
   301 	iCurrentLine++;
   291 	iCurrentLine++; 
   302 	iCurrentMark = ftell(iObeyFile);
       
   303 	iLine[0]='\0';
       
   304 	fgets((char*)iLine,imaxLength+1,iObeyFile);
       
   305 	iNumWords = Parse();
   292 	iNumWords = Parse();
   306 	return KErrNone;
   293 	return KErrNone;
   307 	}
   294 }
   308 
       
   309 TInt ObeyFileReader::NextLine(TInt aPass, enum EKeyword& aKeyword)
   295 TInt ObeyFileReader::NextLine(TInt aPass, enum EKeyword& aKeyword)
   310 	{
   296 	{
   311 
   297 
   312 NextLine:
   298 NextLine:
   313 	TInt err = ReadAndParseLine();
   299 	TInt err = ReadAndParseLine();
   314 	if (err == KErrEof)
   300 	if (err == KErrEof)
   315 		return KErrEof;
   301 		return KErrEof;
   316 	if (iNumWords == 0 || stricmp((const char*)iWord[0], "rem")==0)
   302 	if (iNumWords == 0 )
   317 		goto NextLine;
   303 		goto NextLine;
   318 	if (stricmp((const char*)iWord[0], "stop")==0)
   304 	if (stricmp((const char*)iWord[0], "stop")==0)
   319 		return KErrEof;
   305 		return KErrEof;
   320 
   306 
   321 	const ObeyFileKeyword* k=0;
   307 	const ObeyFileKeyword* k=0;
   322 	for (k=iKeywords; k->iKeyword!=0; k++)
   308 	for (k=iKeywords; k->iKeyword!=0; k++) {
   323 		{
   309 		if (k->iKeywordLength == 0) {
   324 		if (k->iKeywordLength == 0)
       
   325 			{
       
   326 			// Exact case-insensitive match on keyword
   310 			// Exact case-insensitive match on keyword
   327 			if (stricmp((const char*)iWord[0], k->iKeyword) != 0)
   311 			if (stricmp((const char*)iWord[0], k->iKeyword) != 0)
   328 				continue;
   312 				continue;
   329 			iSuffix = 0;
   313 			*iSuffix = 0;
   330 			}
   314 		}
   331 		else
   315 		else {
   332 			{
       
   333 			// Prefix match
   316 			// Prefix match
   334 			if (strnicmp((const char*)iWord[0], k->iKeyword, k->iKeywordLength) != 0)
   317 			if (strnicmp((const char*)iWord[0], k->iKeyword, k->iKeywordLength) != 0)
   335 				continue;
   318 				continue;
   336 			// Suffix must be empty, or a variant number in []
   319 			// Suffix must be empty, or a variant number in []
   337 			iSuffix = iWord[0]+k->iKeywordLength;
   320 			strncpy(iSuffix,iWord[0]+k->iKeywordLength,80);
   338 			if (*iSuffix != '\0' && *iSuffix != '[')
   321 			if (*iSuffix != '\0' && *iSuffix != '[')
   339 				continue;
   322 				continue;
   340 			}
   323 		}
   341 		// found a match
   324 		// found a match
   342 		if ((k->iPass & aPass) == 0)
   325 		if ((k->iPass & aPass) == 0) 
   343 			goto NextLine;
   326 			goto NextLine;
   344 		if (k->iNumArgs>=0 && (1+k->iNumArgs != iNumWords))
   327 		if (k->iNumArgs>=0 && (1+k->iNumArgs != iNumWords))	{			 
   345 			{
       
   346 			 
       
   347 			if(EKeywordHardwareConfigRepositoryData == k->iKeywordEnum){ // preq2131 specific 
   328 			if(EKeywordHardwareConfigRepositoryData == k->iKeywordEnum){ // preq2131 specific 
   348 				Print(EWarning, "Incorrect number of arguments for keyword '%s' on line %d. Extra argument(s) are ignored.\n",
   329 				Print(EWarning, "Incorrect number of arguments for keyword '%s' on line %d. Extra argument(s) are ignored.\n",	iWord[0],iCurrentLine);
   349 				iWord[0],iCurrentLine);
       
   350 				aKeyword = k->iKeywordEnum;
   330 				aKeyword = k->iKeywordEnum;
   351 				return KErrNone;
   331 				return KErrNone;
   352 			}else{
   332 			}else{
   353 				Print(EError, "Incorrect number of arguments for keyword %s on line %d.\n",
   333 				Print(EError, "Incorrect number of arguments for keyword %s on line %d.\n",
   354 					iWord[0], iCurrentLine);
   334 					iWord[0], iCurrentLine);
   355 			}
   335 			}
   356 			goto NextLine;
   336 			goto NextLine;
   357 			}
   337 		}
   358 		if (k->iNumArgs<0 && (1-k->iNumArgs > iNumWords))
   338 		if (k->iNumArgs<0 && (1-k->iNumArgs > iNumWords)){
   359 			{
       
   360 			Print(EError, "Too few arguments for keyword %s on line %d.\n",
   339 			Print(EError, "Too few arguments for keyword %s on line %d.\n",
   361 				iWord[0], iCurrentLine);
   340 				iWord[0], iCurrentLine);
   362 			goto NextLine;
   341 			goto NextLine;
   363 			}
   342 		}
   364 		
   343 		
   365 		aKeyword = k->iKeywordEnum;
   344 		aKeyword = k->iKeywordEnum;
   366 		return KErrNone;
   345 		return KErrNone;
   367 		}
   346 	}
   368 	if (aPass == 1)
   347 	if (aPass == 1)
   369 		Print(EWarning, "Unknown keyword '%s'.  Line %d ignored\n", iWord[0], iCurrentLine);
   348 		Print(EWarning, "Unknown keyword '%s'.  Line %d ignored\n", iWord[0], iCurrentLine);
   370 	goto NextLine;
   349 	goto NextLine;
   371 	}
   350 }
   372 
   351 
   373 inline TBool ObeyFileReader::IsGap(char ch)
   352  
   374 	{
       
   375 	return (ch==' ' || ch=='=' || ch=='\t');
       
   376 	}
       
   377 
       
   378 TInt ObeyFileReader::Parse()
       
   379 //
   353 //
   380 // splits a line into words, and returns the number of words found
   354 // splits a line into words, and returns the number of words found
   381 //
   355 // 
   382 
   356 TInt ObeyFileReader::Parse() {
   383 	{
   357 
   384 
   358 	for (TUint i = 0; i < KNumWords; i++)
   385 	TUint i; 
   359 		iWord[i] = NullString;
   386 	TText *letter=iLine;
       
   387 	TText *end=iLine+strlen((char *)iLine);
       
   388 	for (i=0; i<KNumWords; i++)
       
   389 		iWord[i]=end;
       
   390 
   360 
   391 	enum TState {EInWord, EInQuotedWord, EInGap};
   361 	enum TState {EInWord, EInQuotedWord, EInGap};
   392 	TState state=EInGap;
   362 	TState state = EInGap;	 
   393 
   363 	TUint i = 0;
   394 	i=0;
   364 	const string& line = iLines[iCurrentLine -1];  
   395 	while (i<KNumWords && letter<end)
   365 
   396 		{
   366 	memcpy(iLine,line.c_str(),line.length());
   397 		char ch=*letter;
   367 	iLine[line.length()] = 0 ; 
   398 		if (ch==0)
   368 	char* linestr = iLine;
   399 			break;
   369 	while (i < KNumWords && *linestr != 0) {
   400 		if (ch=='\n')
   370 		switch (state) {
   401 			{
       
   402 			*letter='\0';	// remove trailing newline left by fgets
       
   403 			break;
       
   404 			}
       
   405 		switch (state)
       
   406 			{
       
   407 		case EInGap:
   371 		case EInGap:
   408 			if (ch=='\"')
   372 			if (*linestr =='\"') {
   409 				{
   373 				if (linestr[1] != 0 && linestr[1]!='\"')
   410 				if (letter[1]!=0 && letter[1]!='\"')
   374 					iWord[i++] = linestr + 1;
   411 					iWord[i++]=letter+1;
   375 				state = EInQuotedWord;
       
   376 			}
       
   377 			else if (!IsGap(*linestr)) {
       
   378 				iWord[i++] = linestr;
       
   379 				state=EInWord;
       
   380 			}
       
   381 			else
       
   382 				*linestr=0;
       
   383 			break;
       
   384 		case EInWord:
       
   385 			if (*linestr == '\"') {
       
   386 				*linestr = 0;
       
   387 				if (linestr[1] != 0 && linestr[1] != '\"')
       
   388 					iWord[i++] = linestr+1;
   412 				state=EInQuotedWord;
   389 				state=EInQuotedWord;
   413 				}
   390 			}
   414 			else if (!IsGap(ch))
   391 			else if (IsGap(*linestr)) {
   415 				{
   392 				*linestr=0;
   416 				iWord[i++]=letter;
       
   417 				state=EInWord;
       
   418 				}
       
   419 			else
       
   420 				*letter=0;
       
   421 			break;
       
   422 		case EInWord:
       
   423 			if (ch=='\"')
       
   424 				{
       
   425 				*letter=0;
       
   426 				if (letter[1]!=0 && letter[1]!='\"')
       
   427 					iWord[i++]=letter+1;
       
   428 				state=EInQuotedWord;
       
   429 				}
       
   430 			else if (IsGap(ch))
       
   431 				{
       
   432 				*letter=0;
       
   433 				state=EInGap;
   393 				state=EInGap;
   434 				}
   394 			}
   435 			break;
   395 			break;
   436 		case EInQuotedWord:
   396 		case EInQuotedWord:
   437 			if (ch=='\"')
   397 			if (*linestr == '\"'){
   438 				{
   398 				*linestr = 0;
   439 				*letter=0;
   399 				state = EInGap;
   440 				state=EInGap;
   400 			}
   441 				}
   401 			break;
   442 			break;
   402 		}
   443 			}
   403 		linestr++;
   444 		letter++;
   404 	}
   445 		}
       
   446 	return i;
   405 	return i;
   447 	}
   406 }
   448 
   407 
   449 void ObeyFileReader::ProcessLanguages(TInt64& aLanguageMask)
   408 
   450 	{
   409 void ObeyFileReader::ProcessLanguages(TInt64& aLanguageMask) {
   451 	TInt i=1;
   410 	TInt i=1;
   452 	while (i<iNumWords)
   411 	while (i<iNumWords) {
   453 		{
       
   454 		char *aStr=(char *)iWord[i];
   412 		char *aStr=(char *)iWord[i];
   455 		TLanguage l=ELangTest;
   413 		TLanguage l=ELangTest;
   456 		if (stricmp(aStr, "test")==0)
   414 		if (stricmp(aStr, "test")==0)
   457 			l=ELangTest;
   415 			l=ELangTest;
   458 		else if (stricmp(aStr, "english")==0)
   416 		else if (stricmp(aStr, "english")==0)
   495 			l=ELangBelgianFlemish;
   453 			l=ELangBelgianFlemish;
   496 		else if (stricmp(aStr, "Australian")==0)
   454 		else if (stricmp(aStr, "Australian")==0)
   497 			l=ELangAustralian;
   455 			l=ELangAustralian;
   498 		else if (stricmp(aStr, "BelgianFrench")==0)
   456 		else if (stricmp(aStr, "BelgianFrench")==0)
   499 			l=ELangBelgianFrench;
   457 			l=ELangBelgianFrench;
   500 		else
   458 		else {
   501 			{
       
   502 			Print(EError, "Unknown language '%s' on line %d", iWord[i], iCurrentLine);
   459 			Print(EError, "Unknown language '%s' on line %d", iWord[i], iCurrentLine);
   503 			exit(666);
   460 			exit(666);
   504 			}
   461 		}
   505 		aLanguageMask = aLanguageMask+(1<<(TInt)l);
   462 		aLanguageMask = aLanguageMask+(1<<(TInt)l);
   506 		i++;
   463 		i++;
   507 		}
   464 	}
   508 	}
   465 }
   509 
   466 
   510 void ObeyFileReader::ProcessTime(TInt64& aTime)
       
   511 //
   467 //
   512 // Process the timestamp
   468 // Process the timestamp
   513 //
   469 //
   514 	{
   470 void ObeyFileReader::ProcessTime(TInt64& aTime) {
   515 	char timebuf[256];
   471 	char timebuf[256];
   516 	if (iNumWords>2)
   472 	if (iNumWords>2)
   517 		sprintf(timebuf, "%s_%s", iWord[1], iWord[2]);
   473 		sprintf(timebuf, "%s_%s", iWord[1], iWord[2]);
   518 	else
   474 	else
   519 		strcpy(timebuf, (char*)iWord[1]);
   475 		strncpy(timebuf, iWord[1],256);
   520 
   476 
   521 	TInt r=StringToTime(aTime, timebuf);
   477 	TInt r = StringToTime(aTime, timebuf);
   522 	if (r==KErrGeneral)
   478 	if (r==KErrGeneral) {
   523 		{
       
   524 		Print(EError, "incorrect format for time keyword on line %d\n", iCurrentLine);
   479 		Print(EError, "incorrect format for time keyword on line %d\n", iCurrentLine);
   525 		exit(0x670);
   480 		exit(0x670);
   526 		}
   481 	}
   527 	if (r==KErrArgument)
   482 	if (r==KErrArgument) {
   528 		{
       
   529 		Print(EError, "Time out of range on line %d\n", iCurrentLine);
   483 		Print(EError, "Time out of range on line %d\n", iCurrentLine);
   530 		exit(0x670);
   484 		exit(0x670);
   531 		}
   485 	}
   532 	}
   486 }
   533 
   487 
   534 TInt64 ObeyFileReader::iTimeNow=0;
   488 TInt64 ObeyFileReader::iTimeNow=0;
   535 void ObeyFileReader::TimeNow(TInt64& aTime)
   489 void ObeyFileReader::TimeNow(TInt64& aTime) {
   536 	{
   490 	if (iTimeNow==0) {
   537 	if (iTimeNow==0)
       
   538 		{
       
   539 		TInt sysTime=time(0);					// seconds since midnight Jan 1st, 1970
   491 		TInt sysTime=time(0);					// seconds since midnight Jan 1st, 1970
   540 		sysTime-=(30*365*24*60*60+7*24*60*60);	// seconds since midnight Jan 1st, 2000
   492 		sysTime-=(30*365*24*60*60+7*24*60*60);	// seconds since midnight Jan 1st, 2000
   541 		TInt64 daysTo2000AD=730497;
   493 		TInt64 daysTo2000AD=730497;
   542 		TInt64 t=daysTo2000AD*24*3600+sysTime;	// seconds since 0000
   494 		TInt64 t=daysTo2000AD*24*3600+sysTime;	// seconds since 0000
   543 		t=t+3600;								// BST (?)
   495 		t=t+3600;								// BST (?)
   544 		iTimeNow=t*1000000;						// milliseconds
   496 		iTimeNow=t*1000000;						// milliseconds
   545 		}
   497 	}
   546 	aTime=iTimeNow;
   498 	aTime=iTimeNow;
   547 	}
   499 }
   548 
       
   549 TInt ObeyFileReader::ProcessAlign(TInt &aAlign)
       
   550 //
   500 //
   551 // Process the align keyword
   501 // Process the align keyword
   552 //
   502 //
   553 	{
   503 TInt ObeyFileReader::ProcessAlign(TInt &aAlign) {
   554 
   504 		
   555 	TInt align;
   505 	TInt err = Val(aAlign,Word(1));
   556 	if (Val(align, Word(1)))
   506 	if(err != KErrNone) 
   557 		return Print(EError, "Number required for 'align' keyword on line %d\n", iCurrentLine);
   507 		return Print(EError, "Number required for 'align' keyword on line %d\n", iCurrentLine); 
   558 	aAlign=align;
       
   559 	TInt i;
   508 	TInt i;
   560 	for (i=4; i!=0x40000000; i<<=1)
   509 	for (i=4; i!=0x40000000; i<<=1)
   561 		if (i==aAlign)
   510 		if (i==aAlign)
   562 			return KErrNone;
   511 			return KErrNone;
   563 	return Print(EError, "Alignment must be a power of 2 and bigger than 4.  Line %d\n", iCurrentLine);
   512 	return Print(EError, "Alignment must be a power of 2 and bigger than 4.  Line %d\n", iCurrentLine);
   564 	}
   513 }
   565 
   514 
   566 
   515 
   567 const FileAttributeKeyword ObeyFileReader::iAttributeKeywords[] =
   516 const FileAttributeKeyword ObeyFileReader::iAttributeKeywords[] = {
   568 {
       
   569 	{"stackreserve",6	,1,1,EAttributeStackReserve, "?"},
   517 	{"stackreserve",6	,1,1,EAttributeStackReserve, "?"},
   570 	{"stack",3			,1,1,EAttributeStack, "?"},
   518 	{"stack",3			,1,1,EAttributeStack, "?"},
   571 	{"reloc",3			,1,1,EAttributeReloc, "?"},
   519 	{"reloc",3			,1,1,EAttributeReloc, "?"},
   572 	{"code-align",10	,1,1,EAttributeCodeAlign, "Additional code alignment constraint"},
   520 	{"code-align",10	,1,1,EAttributeCodeAlign, "Additional code alignment constraint"},
   573 	{"data-align",10	,1,1,EAttributeDataAlign, "Additional data alignment constraint"},
   521 	{"data-align",10	,1,1,EAttributeDataAlign, "Additional data alignment constraint"},
   593 	{_K("unpageddata")	,1,0,EAttributeUnpagedData, "Don't use data paging for this file"},
   541 	{_K("unpageddata")	,1,0,EAttributeUnpagedData, "Don't use data paging for this file"},
   594 	{_K("pageddata")	,1,0,EAttributePagedData, "Use data paging for this file"},
   542 	{_K("pageddata")	,1,0,EAttributePagedData, "Use data paging for this file"},
   595 	{0,0,0,0,EAttributeStackReserve,0}
   543 	{0,0,0,0,EAttributeStackReserve,0}
   596 };
   544 };
   597 
   545 
   598 TInt ObeyFileReader::NextAttribute(TInt& aIndex, TInt aHasFile, enum EFileAttribute& aKeyword, TText*& aArg)
   546 TInt ObeyFileReader::NextAttribute(TInt& aIndex, TInt aHasFile, enum EFileAttribute& aKeyword, char*& aArg) {
   599 	{
       
   600 NextAttribute:
   547 NextAttribute:
   601 	if (aIndex >= iNumWords)
   548 	if (aIndex >= iNumWords)
   602 		return KErrEof;
   549 		return KErrEof;
   603 	TText* word=iWord[aIndex++];
   550 	char* word=iWord[aIndex++];
   604 	const FileAttributeKeyword* k;
   551 	const FileAttributeKeyword* k;
   605 	for (k=iAttributeKeywords; k->iKeyword!=0; k++)
   552 	for (k=iAttributeKeywords; k->iKeyword!=0; k++) {
   606 		{
   553 		if (k->iKeywordLength == 0) {
   607 		if (k->iKeywordLength == 0)
       
   608 			{
       
   609 			// Exact match on keyword
   554 			// Exact match on keyword
   610 			if (stricmp((const char*)word, k->iKeyword) != 0)
   555 			if (stricmp(word, k->iKeyword) != 0)
   611 				continue;
   556 				continue;
   612 			}
   557 		}
   613 		else
   558 		else {
   614 			{
       
   615 			// Prefix match
   559 			// Prefix match
   616 			if (strnicmp((const char*)word, k->iKeyword, k->iKeywordLength) != 0)
   560 			if (strnicmp(word, k->iKeyword, k->iKeywordLength) != 0)
   617 				continue;
   561 				continue;
   618 			}
   562 		}
   619 		// found a match
   563 		// found a match
   620 		if (k->iNumArgs>0)
   564 		if (k->iNumArgs>0) {
   621 			{
       
   622 			TInt argIndex = aIndex;
   565 			TInt argIndex = aIndex;
   623 			aIndex += k->iNumArgs;		// interface only really supports 1 argument
   566 			aIndex += k->iNumArgs;		// interface only really supports 1 argument
   624 			if (aIndex>iNumWords)
   567 			if (aIndex>iNumWords) {
   625 				{
       
   626 				Print(EError, "Missing argument for attribute %s on line %d\n", word, iCurrentLine);
   568 				Print(EError, "Missing argument for attribute %s on line %d\n", word, iCurrentLine);
   627 				return KErrArgument;
   569 				return KErrArgument;
   628 				}
   570 			}
   629 			aArg=iWord[argIndex];
   571 			aArg=iWord[argIndex];
   630 			}
   572 		}
   631 		if (k->iIsFileAttribute && !aHasFile)
   573 		if (k->iIsFileAttribute && !aHasFile) {
   632 			{
       
   633 			Print(EError, "File attribute %s applied to non-file on line %d\n", word, iCurrentLine);
   574 			Print(EError, "File attribute %s applied to non-file on line %d\n", word, iCurrentLine);
   634 			return KErrNotSupported;
   575 			return KErrNotSupported;
   635 			}
   576 		}
   636 		aKeyword=k->iAttributeEnum;
   577 		aKeyword=k->iAttributeEnum;
   637 		return KErrNone;
   578 		return KErrNone;
   638 		}
   579 	}
   639 	Print(EWarning, "Unknown attribute '%s' skipped on line %d\n", word, iCurrentLine);
   580 	Print(EWarning, "Unknown attribute '%s' skipped on line %d\n", word, iCurrentLine);
   640 	goto NextAttribute;
   581 	goto NextAttribute;
   641 	}
   582 }
   642 
   583 
   643 
   584 
   644 
   585 
   645 
   586 
   646 CObeyFile::CObeyFile(ObeyFileReader& aReader):
   587 CObeyFile::CObeyFile(ObeyFileReader& aReader):
   647 	iRomFileName(0),iRomOddFileName(0),iRomEvenFileName(0),
   588 iRomFileName(0),iRomOddFileName(0),iRomEvenFileName(0),
   648 	iSRecordFileName(0),iBootFileName(0),iKernelRomName(0),
   589 iSRecordFileName(0),iBootFileName(0),iKernelRomName(0),
   649 	iRomSize(0),iRomLinearBase(0xffffffff),iRomAlign(0),
   590 iRomSize(0),iRomLinearBase(0xffffffff),iRomAlign(0),
   650 	iKernDataRunAddress(0),iDataRunAddress(0),iKernelLimit(0xffffffff),
   591 iKernDataRunAddress(0),iDataRunAddress(0),iKernelLimit(0xffffffff),
   651 	iKernHeapMin(0),iKernHeapMax(0),iSectionStart(0),iSectionPosition(-1),
   592 iKernHeapMin(0),iKernHeapMax(0),iSectionStart(0),iSectionPosition(-1),
   652 	iVersion(0,0,0),iCheckSum(0),iNumberOfPeFiles(0),iNumberOfDataFiles(0),
   593 iVersion(0,0,0),iCheckSum(0),iNumberOfPeFiles(0),iNumberOfDataFiles(0),
   653 	iNumberOfPrimaries(0),iNumberOfExtensions(0),iNumberOfVariants(0),
   594 iNumberOfPrimaries(0),iNumberOfExtensions(0),iNumberOfVariants(0),
   654 	iNumberOfDevices(0),iNumberOfHCRDataFiles (0),
   595 iNumberOfDevices(0),iNumberOfHCRDataFiles (0),
   655 	//iAllVariantsMask[256],
   596 //iAllVariantsMask[256],
   656 	iPrimaries(0),iVariants(0),iExtensions(0),iDevices(0),
   597 iPrimaries(0),iVariants(0),iExtensions(0),iDevices(0),
   657 	iLanguage(0),iHardware(0),iTime(0),iMemModel(E_MM_Moving),iPageSize(0x1000),
   598 iLanguage(0),iHardware(0),iTime(0),iMemModel(E_MM_Moving),iPageSize(0x1000),
   658 	iChunkSize(0x100000),iVirtualAllocSize(0x1000),iKernelModel(ESingleKernel),
   599 iChunkSize(0x100000),iVirtualAllocSize(0x1000),iKernelModel(ESingleKernel),
   659 	iCollapseMode(ECollapseNone),iSRecordBase(0),iCurrentSectionNumber(0),
   600 iCollapseMode(ECollapseNone),iSRecordBase(0),iCurrentSectionNumber(0),
   660 	iDefaultStackReserve(0),//iTraceMask[KNumTraceMaskWords];iInitialBTraceFilter[8];
   601 iDefaultStackReserve(0),//iTraceMask[KNumTraceMaskWords];iInitialBTraceFilter[8];
   661 	iInitialBTraceBuffer(0),iInitialBTraceMode(0),iDebugPort(0),
   602 iInitialBTraceBuffer(0),iInitialBTraceMode(0),iDebugPort(0),
   662 	iDebugPortParsed(EFalse),iRootDirectory(0),iDllDataTop(0x40000000),
   603 iDebugPortParsed(EFalse),iRootDirectory(0),iDllDataTop(0x40000000),
   663 	iKernelConfigFlags(0),iPagingPolicyParsed(EFalse),iCodePagingPolicyParsed(EFalse),
   604 iKernelConfigFlags(0),iPagingPolicyParsed(EFalse),iCodePagingPolicyParsed(EFalse),
   664 	iDataPagingPolicyParsed(EFalse),iPagingOverrideParsed(EFalse),
   605 iDataPagingPolicyParsed(EFalse),iPagingOverrideParsed(EFalse),
   665 	iCodePagingOverrideParsed(EFalse),iDataPagingOverrideParsed(EFalse),
   606 iCodePagingOverrideParsed(EFalse),iDataPagingOverrideParsed(EFalse),
   666 	/*iPlatSecDisabledCaps(), */iPlatSecDisabledCapsParsed(EFalse),iMaxUnpagedMemSize(0),
   607 /*iPlatSecDisabledCaps(), */iPlatSecDisabledCapsParsed(EFalse),iMaxUnpagedMemSize(0),
   667 	iReader(aReader),iMissingFiles(0),iLastExecutable(0),iAreaSet(),iFirstFile(0),
   608 iReader(aReader),iMissingFiles(0),iLastExecutable(0),iAreaSet(),iFirstFile(0),
   668 	iCurrentFile(0),iLastVariantFile(0),iFirstDllDataEntry(0),
   609 iCurrentFile(0),iLastVariantFile(0),iFirstDllDataEntry(0),
   669 	iUpdatedMaxUnpagedMemSize(EFalse),iPatchData(new CPatchDataProcessor)
   610 iUpdatedMaxUnpagedMemSize(EFalse),iPatchData(new CPatchDataProcessor) {
   670 	{
       
   671 
   611 
   672 	TUint i; 
   612 	TUint i; 
   673 	for (i=0; i<256; i++)
   613 	for (i=0; i<256; i++)
   674 		iAllVariantsMask[i]=0;
   614 		iAllVariantsMask[i]=0;
   675 	for (i=0; i<(TUint)KNumTraceMaskWords; i++) 
   615 	for (i=0; i<(TUint)KNumTraceMaskWords; i++) 
   676 		iTraceMask[i]=0;
   616 		iTraceMask[i]=0;
   677 	for (i=0; i<sizeof(iInitialBTraceFilter)/sizeof(TUint32); i++)
   617 	for (i=0; i<sizeof(iInitialBTraceFilter)/sizeof(TUint32); i++)
   678 		iInitialBTraceFilter[i]=0;	
   618 		iInitialBTraceFilter[i]=0;	
   679 	memset(&iPlatSecDisabledCaps,0,sizeof(SCapabilitySet));
   619 	memset(&iPlatSecDisabledCaps,0,sizeof(SCapabilitySet));
   680 	iNextFilePtrPtr = &iFirstFile;
   620 	iNextFilePtrPtr = &iFirstFile;
   681 	}
   621 }
   682 
   622 
   683 CObeyFile::~CObeyFile()
       
   684 //
   623 //
   685 // Destructor
   624 // Destructor
   686 //
   625 // 
   687 	{
   626 CObeyFile::~CObeyFile(){
   688 
   627 
   689 	Release();
   628 	Release();
   690 	delete [] iRomFileName;
   629 	if(iRomFileName){
       
   630 		delete [] iRomFileName;
       
   631 		iRomFileName = 0 ;
       
   632 	}
   691 	if (iRootDirectory)
   633 	if (iRootDirectory)
   692 		iRootDirectory->Destroy();
   634 		iRootDirectory->Destroy();
   693 	delete iPatchData;
   635 	if(iPatchData) {
   694 	}
   636 		delete iPatchData;
   695 
   637 		iPatchData = 0 ;
   696 void CObeyFile::Release()
   638 	}
       
   639 }
   697 //
   640 //
   698 // Free resources not needed after building a ROM
   641 // Free resources not needed after building a ROM
   699 //
   642 // 
   700 	{
   643 void CObeyFile::Release() {
   701 	iAreaSet.ReleaseAllAreas();
   644 	iAreaSet.ReleaseAllAreas();
   702 
   645 	
   703 	delete [] iBootFileName;
   646 	if(iBootFileName) delete [] iBootFileName;
   704 	delete [] iPrimaries;
   647 	if(iPrimaries) delete [] iPrimaries;
   705 	delete [] iVariants;
   648 	if(iVariants) delete [] iVariants;
   706 	delete [] iExtensions;
   649 	if(iExtensions) delete [] iExtensions;
   707 	delete [] iDevices;
   650 	if(iDevices) delete [] iDevices;
   708 
   651 
   709 	iBootFileName = 0;
   652 	iBootFileName = 0;
   710 	iPrimaries = 0;
   653 	iPrimaries = 0;
   711 	iVariants = 0;
   654 	iVariants = 0;
   712 	iExtensions = 0;
   655 	iExtensions = 0;
   713 	iDevices = 0;
   656 	iDevices = 0;
   714 	iFirstFile = 0;
   657 	iFirstFile = 0;
   715 	iNextFilePtrPtr = &iFirstFile;
   658 	iNextFilePtrPtr = &iFirstFile;
   716 	}
   659 }
   717 
   660 
   718 TRomBuilderEntry *CObeyFile::FirstFile()
   661 TRomBuilderEntry *CObeyFile::FirstFile() {
   719 	{
       
   720 	iCurrentFile = iFirstFile;
   662 	iCurrentFile = iFirstFile;
   721 	return iCurrentFile;
   663 	return iCurrentFile;
   722 	}
   664 }
   723 
   665 
   724 TRomBuilderEntry *CObeyFile::NextFile()
   666 TRomBuilderEntry *CObeyFile::NextFile() {
   725 	{
       
   726 	iCurrentFile = iCurrentFile ? iCurrentFile->iNext : 0;
   667 	iCurrentFile = iCurrentFile ? iCurrentFile->iNext : 0;
   727 	return iCurrentFile;
   668 	return iCurrentFile;
   728 	}
   669 }
   729 
   670 
   730 /*
   671 /*
   731 *Set first link in patchdata linked list
   672 *Set first link in patchdata linked list
   732 **/
   673 **/
   733 void CObeyFile::SetFirstDllDataEntry(DllDataEntry* aDllDataEntry)
   674 void CObeyFile::SetFirstDllDataEntry(DllDataEntry* aDllDataEntry) {
   734 {
   675 	iFirstDllDataEntry = aDllDataEntry;
   735   	iFirstDllDataEntry = aDllDataEntry;
       
   736 }
   676 }
   737 
   677 
   738 /*
   678 /*
   739 *Get first link in patchdata linked list
   679 *Get first link in patchdata linked list
   740 **/
   680 **/
   741 DllDataEntry* CObeyFile::GetFirstDllDataEntry() const
   681 DllDataEntry* CObeyFile::GetFirstDllDataEntry() const {
   742 {
       
   743 	return iFirstDllDataEntry;
   682 	return iFirstDllDataEntry;
   744 }
   683 }
   745 
   684 
   746 TInt CObeyFile::ProcessKernelRom()
   685 TInt CObeyFile::ProcessKernelRom() {
   747 	{
       
   748 	//
   686 	//
   749 	// First pass through the obey file to set up key variables
   687 	// First pass through the obey file to set up key variables
   750 	//
   688 	//
   751 
       
   752 	iReader.Rewind();
   689 	iReader.Rewind();
   753 
   690 
   754 	TInt count=0;
   691 	TInt count=0;
   755 	enum EKeyword keyword;
   692 	enum EKeyword keyword;
   756 	while (iReader.NextLine(1,keyword) != KErrEof)
   693 	while (iReader.NextLine(1,keyword) != KErrEof) {
   757 		{
   694 		if (keyword == EKeywordExtensionRom) {
   758 		if (keyword == EKeywordExtensionRom)
       
   759 			{
       
   760 			if (count==0)
   695 			if (count==0)
   761 				return KErrNotFound;		// no kernel ROM, just extension ROMs.
   696 				return KErrNotFound;		// no kernel ROM, just extension ROMs.
   762 			break;
   697 			break;
   763 			}
   698 		}
   764 
   699 
   765 		count++;
   700 		count++;
   766 		if (! ProcessKeyword(keyword))
   701 		if (! ProcessKeyword(keyword))
   767 			return KErrGeneral;
   702 			return KErrGeneral;
   768 		}
   703 	}
   769 
   704 
   770 	if (!GotKeyVariables())
   705 	if (!GotKeyVariables())
   771 		return KErrGeneral;
   706 		return KErrGeneral;
   772 
   707 
   773 	if (! CreateDefaultArea())
   708 	if (! CreateDefaultArea())
   777 	// second pass to process the file specifications in the obey file building
   712 	// second pass to process the file specifications in the obey file building
   778 	// up the TRomNode directory structure and the TRomBuilderEntry list
   713 	// up the TRomNode directory structure and the TRomBuilderEntry list
   779 	//
   714 	//
   780 	iReader.Rewind();
   715 	iReader.Rewind();
   781 
   716 
   782 	iRootDirectory = new TRomNode((TText*)"");
   717 	iRootDirectory = new TRomNode("");
   783 	iLastExecutable = iRootDirectory;
   718 	iLastExecutable = iRootDirectory;
   784 
   719 
   785 	TInt align=0;
   720 	TInt align=0;
   786 	while (iReader.NextLine(2,keyword)!=KErrEof)
   721 	while (iReader.NextLine(2,keyword)!=KErrEof) {
   787 		{
       
   788 		if (keyword == EKeywordExtensionRom)
   722 		if (keyword == EKeywordExtensionRom)
   789 			break;
   723 			break;
   790 
   724 
   791 		switch (keyword)
   725 		switch (keyword) {
   792 			{
       
   793 		case EKeywordSection:
   726 		case EKeywordSection:
   794 			if (ParseSection()!=KErrNone)
   727 			if (ParseSection()!=KErrNone)
   795 				return KErrGeneral;
   728 				return KErrGeneral;
   796 			break;
   729 			break;
   797 		case EKeywordAlign:
   730 		case EKeywordAlign:
   802 		case EKeywordAlias:
   735 		case EKeywordAlias:
   803 		case EKeywordRename:
   736 		case EKeywordRename:
   804 			if (!ProcessRenaming(keyword))
   737 			if (!ProcessRenaming(keyword))
   805 				return KErrGeneral;
   738 				return KErrGeneral;
   806 			break;
   739 			break;
   807 		case EKeywordPatchDllData:
   740 		case EKeywordPatchDllData: {
   808 		{
   741 				// Collect patchdata statements to process at the end
   809 			// Collect patchdata statements to process at the end
   742 				StringVector patchDataTokens;
   810 			StringVector patchDataTokens;
   743 				SplitPatchDataStatement(patchDataTokens); 
   811 			SplitPatchDataStatement(patchDataTokens); 
   744 				iPatchData->AddPatchDataStatement(patchDataTokens);									
   812 			iPatchData->AddPatchDataStatement(patchDataTokens);									
   745 				break;
   813 			break;
   746 			}
   814 		}
       
   815 
   747 
   816 		default:
   748 		default:
   817 			if (!ProcessFile(align, keyword))
   749 			if (!ProcessFile(align, keyword))
   818 				return KErrGeneral;
   750 				return KErrGeneral;				
   819 			align=0;
   751 			align=0;
   820 			break;
   752 			break;
   821 			}
   753 		}
   822 		}
   754 	}
   823 
   755 	
   824 	if( !ParsePatchDllData())
   756 	if( !ParsePatchDllData())
   825 		return KErrGeneral;
   757 		return KErrGeneral;
   826 
   758 
   827 	iReader.Mark();			// ready for processing the extension rom(s)
   759 	iReader.Mark();			// ready for processing the extension rom(s)
   828 
   760 
   829 	if (iMissingFiles!=0)
   761 	if (iMissingFiles!=0)
   830 		return KErrGeneral;
   762 		return KErrGeneral;
   831 	if (iNumberOfDataFiles+iNumberOfPeFiles==0)
   763 	if (iNumberOfDataFiles+iNumberOfPeFiles==0) {
   832 		{
       
   833 		Print(EError, "No files specified.\n");
   764 		Print(EError, "No files specified.\n");
   834 		return KErrGeneral;
   765 		return KErrGeneral;
   835 		}
   766 	}
   836 	if (!CheckHardwareVariants())
   767 	if (!CheckHardwareVariants())
   837 		return KErrGeneral;
   768 		return KErrGeneral;
   838 
   769 
   839 	return KErrNone;
   770 	return KErrNone;
   840 	}
   771 }
   841 
   772 
   842 
       
   843 TInt CObeyFile::ParseSection()
       
   844 //
   773 //
   845 // Process the section keyword
   774 // Process the section keyword
   846 //
   775 // 
   847 	{
   776 TInt CObeyFile::ParseSection(){
   848 	TInt currentLine = iReader.CurrentLine();
   777 	TInt currentLine = iReader.CurrentLine();
   849 	if (iSectionPosition!=-1)
   778 	if (iSectionPosition!=-1)
   850 		return Print(EError, "Rom already sectioned.  Line %d\n", currentLine);
   779 		return Print(EError, "Rom already sectioned.  Line %d\n", currentLine);
   851 	TInt offset;
   780 	 
   852 	if (Val(offset, iReader.Word(1)))
   781 	if (!IsValidNumber(iReader.Word(1)))
   853 		return Print(EError, "Number required for 'section' keyword on line %d\n", currentLine);
   782 		return Print(EError, "Number required for 'section' keyword on line %d\n", currentLine);
   854 	iSectionStart=offset+iRomLinearBase;
   783 	TUint32 offset = 0 ;
   855 	if (offset>=iRomSize)
   784 	Val(offset,iReader.Word(1)) ; 
       
   785 	iSectionStart = offset + iRomLinearBase;
       
   786 	if (offset>=(TUint32)iRomSize)
   856 		return Print(EError, "Sectioned beyond end of Rom.  Line %d\n", currentLine);
   787 		return Print(EError, "Sectioned beyond end of Rom.  Line %d\n", currentLine);
   857 	if (offset&0x0fff)
   788 	if (offset&0x0fff)
   858 		return Print(EError, "Section must be on a 4K boundry.  Line %d\n", currentLine);
   789 		return Print(EError, "Section must be on a 4K boundry.  Line %d\n", currentLine);
   859 	iSectionPosition=iNumberOfDataFiles+iNumberOfPeFiles;
   790 	iSectionPosition=iNumberOfDataFiles + iNumberOfPeFiles;
   860 	iCurrentSectionNumber++;	
   791 	iCurrentSectionNumber++;	
   861 	return KErrNone;
   792 	return KErrNone;
   862 	}
   793 }
   863 
   794 
   864 TInt CObeyFile::ParseFileAttributes(TRomNode *aNode, TRomBuilderEntry* aFile)
   795 
   865 //
   796 //
   866 // Process any inline keywords
   797 // Process any inline keywords
   867 //
   798 // 
   868 	{
   799 TInt CObeyFile::ParseFileAttributes(TRomNode *aNode, TRomBuilderEntry* aFile) {
   869 	TInt currentLine = iReader.CurrentLine();
   800 	TInt currentLine = iReader.CurrentLine();
   870 	enum EFileAttribute attribute;
   801 	enum EFileAttribute attribute;
   871 	TInt r=KErrNone;
   802 	TInt r=KErrNone;
   872 	TInt index=3;
   803 	TInt index=3;
   873 	TText* arg=0;
   804 	char* arg=0;
   874 
   805 
   875 	while(r==KErrNone)
   806 	while(r==KErrNone) {
   876 		{
       
   877 		r=iReader.NextAttribute(index,(aFile!=0),attribute,arg);
   807 		r=iReader.NextAttribute(index,(aFile!=0),attribute,arg);
   878 		if (r!=KErrNone)
   808 		if (r!=KErrNone)
   879 			break;
   809 			break;
   880 		switch(attribute)
   810 		switch(attribute) {
   881 			{
       
   882 		case EAttributeStackReserve:
   811 		case EAttributeStackReserve:
   883 			r=aFile->SetStackReserve(arg);
   812 			r=aFile->SetStackReserve(arg);
   884 			break;
   813 			break;
   885 		case EAttributeStack:
   814 		case EAttributeStack:
   886 			r=aFile->SetStackSize(arg);
   815 			r=aFile->SetStackSize(arg);
   926 		case EAttributeKeepIAT:
   855 		case EAttributeKeepIAT:
   927 			aFile->iOverrideFlags |= KOverrideKeepIAT;
   856 			aFile->iOverrideFlags |= KOverrideKeepIAT;
   928 			break;
   857 			break;
   929 		case EAttributeHidden:
   858 		case EAttributeHidden:
   930 			if (aFile->Extension())
   859 			if (aFile->Extension())
   931  				return Print(EError, "Cannot hide Extension. Line %d.\n", currentLine);
   860 				return Print(EError, "Cannot hide Extension. Line %d.\n", currentLine);
   932 			aNode->iHidden=ETrue;
   861 			aNode->iHidden=ETrue;
   933 			break;
   862 			break;
   934 		case EAttributeArea:
   863 		case EAttributeArea: {
   935 			{
   864 				TRACE(TAREA, Print(EScreen, "Area Attribute: %s\n", arg));
   936 			TRACE(TAREA, Print(EScreen, "Area Attribute: %s\n", arg));
   865 				const Area* area = aFile->iArea;
   937 			const Area* area = aFile->iArea;
   866 				if (! ParseAreaAttribute(arg, currentLine, area))
   938 			if (! ParseAreaAttribute(arg, currentLine, area))
   867 					return KErrGeneral;
   939 				return KErrGeneral;
       
   940 			}
   868 			}
   941 			break;
   869 			break;
   942 		case EAttributeProcessSpecific:
   870 		case EAttributeProcessSpecific:
   943 			if (!IsValidFilePath(arg))
   871 			if (!IsValidFilePath(arg)) {
   944 				{
       
   945 				Print(EError, "Invalid file path for process attribute on line %d\n", currentLine);
   872 				Print(EError, "Invalid file path for process attribute on line %d\n", currentLine);
   946 				return KErrGeneral;
   873 				return KErrGeneral;
   947 				}
   874 			}
   948 			r=aFile->SetAttachProcess(arg);
   875 			r=aFile->SetAttachProcess(arg);
   949 			break;
   876 			break;
   950 		case EAttributeCapability:
   877 		case EAttributeCapability:
   951 			r=aFile->SetCapability(arg);
   878 			r=aFile->SetCapability(arg);
   952 			break;
   879 			break;
   956 		case EAttributeUnpaged:
   883 		case EAttributeUnpaged:
   957 			aFile->iOverrideFlags |= KOverrideCodeUnpaged | KOverrideDataUnpaged;
   884 			aFile->iOverrideFlags |= KOverrideCodeUnpaged | KOverrideDataUnpaged;
   958 			aFile->iOverrideFlags &= ~(KOverrideCodePaged | KOverrideDataPaged);
   885 			aFile->iOverrideFlags &= ~(KOverrideCodePaged | KOverrideDataPaged);
   959 			break;
   886 			break;
   960 		case EAttributePaged:
   887 		case EAttributePaged:
   961 			aFile->iOverrideFlags |= KOverrideCodePaged | KOverrideDataPaged;
   888 			aFile->iOverrideFlags |= KOverrideCodePaged;
   962 			aFile->iOverrideFlags &= ~(KOverrideCodeUnpaged | KOverrideDataUnpaged);
   889 			aFile->iOverrideFlags &= ~(KOverrideCodeUnpaged);
   963 			break;
   890 			break;
   964 		case EAttributeUnpagedCode:
   891 		case EAttributeUnpagedCode:
   965 			aFile->iOverrideFlags |= KOverrideCodeUnpaged;
   892 			aFile->iOverrideFlags |= KOverrideCodeUnpaged;
   966 			aFile->iOverrideFlags &= ~KOverrideCodePaged;
   893 			aFile->iOverrideFlags &= ~KOverrideCodePaged;
   967 			break;
   894 			break;
   978 			aFile->iOverrideFlags &= ~KOverrideDataUnpaged;
   905 			aFile->iOverrideFlags &= ~KOverrideDataUnpaged;
   979 			break;
   906 			break;
   980 
   907 
   981 		default:
   908 		default:
   982 			return Print(EError, "Unrecognised keyword in file attributes on line %d.\n",currentLine);
   909 			return Print(EError, "Unrecognised keyword in file attributes on line %d.\n",currentLine);
   983 			}
   910 		}
   984 		}
   911 	}
   985 
   912 
   986 	// aFile may be null if processing an extension ROM
   913 	// aFile may be null if processing an extension ROM
   987 	if (aFile && aFile->iPatched && ! aFile->iArea->IsDefault())
   914 	if (aFile && aFile->iPatched && ! aFile->iArea->IsDefault()) {
   988 		{
       
   989 		return Print(EError, "Relocation to area at line %d forbidden because file is patched\n", currentLine);
   915 		return Print(EError, "Relocation to area at line %d forbidden because file is patched\n", currentLine);
   990 		}
   916 	}
   991 
   917 
   992 	if (r==KErrEof)
   918 	if (r==KErrEof)
   993 		return KErrNone;
   919 		return KErrNone;
   994 	return r;
   920 	return r;
   995 	}
   921 }
   996 
   922 
   997 TUint32 CObeyFile::ParseVariant()
   923 TUint32 CObeyFile::ParseVariant() {
   998 	{
   924 	if (iReader.Count() == 0 || stricmp(iReader.Word(0), "rem")==0)
   999 	char* left=iReader.Suffix();
   925 		return KVariantIndependent;
       
   926 	const char* left=iReader.Suffix();
  1000 	if (left == 0 || *left=='\0')
   927 	if (left == 0 || *left=='\0')
  1001 		return KVariantIndependent;
   928 		return KVariantIndependent;
  1002 	const char* right=left+strlen(left)-1;
   929 	const char* right=left+strlen(left)-1;
  1003 	if (*left=='[' && *right==']')
   930 	if (*left=='[' && *right==']') { 
  1004 		{
       
  1005 		TUint variant;
       
  1006 		#ifdef __TOOLS2__
       
  1007 		string s(left+1);
   931 		string s(left+1);
  1008 		string s2=s.substr(0,right-(left+1));
   932 		string s2=s.substr(0,right-(left+1));
  1009 		istringstream val(s2,ios::in);
   933 		if(IsValidNumber(s2.c_str())){
  1010 		#else
   934 			TUint32 temp = 0 ;
  1011 		istrstream val(left+1, right-(left+1));
   935 			Val(temp,s2.c_str());
  1012 		#endif
   936 			return temp;
  1013 		
   937 		}
  1014 
   938 	}
  1015 #if defined(__MSVCDOTNET__) || defined(__TOOLS2__)
   939 	//#endif
  1016 		val >> setbase(0);
       
  1017 #endif //__MSVCDOTNET__
       
  1018 
       
  1019 		val >> variant;
       
  1020 		if (val.eof() && !val.fail())
       
  1021 			return variant;
       
  1022 		}
       
  1023 //#endif
       
  1024 	Print(EError,"Syntax error in variant, %s keyword on line %d\n", iReader.Word(0), iReader.CurrentLine());
   940 	Print(EError,"Syntax error in variant, %s keyword on line %d\n", iReader.Word(0), iReader.CurrentLine());
  1025 	return KVariantIndependent;
   941 	return KVariantIndependent;
  1026 	}
   942 }
  1027 
   943 
  1028 TBool CObeyFile::ProcessFile(TInt aAlign, enum EKeyword aKeyword)
       
  1029 //
   944 //
  1030 // Process a parsed line to set up one or more new TRomBuilder entry objects.
   945 // Process a parsed line to set up one or more new TRomBuilder entry objects.
  1031 // iWord[0] = the keyword (file, primary or secondary)
   946 // iWord[0] = the keyword (file, primary or secondary)
  1032 // iWord[1] = the PC pathname
   947 // iWord[1] = the PC pathname
  1033 // iWord[2] = the EPOC pathname
   948 // iWord[2] = the EPOC pathname
  1034 // iWord[3] = start of the file attributes
   949 // iWord[3] = start of the file attributes
  1035 //
   950 // 
  1036 	{
   951 TBool CObeyFile::ProcessFile(TInt aAlign, enum EKeyword aKeyword){
  1037 
   952 
  1038 	TUint imageFlags = 0;
   953 	TUint imageFlags = 0;
  1039 	TUint overrides = 0;
   954 	TUint overrides = 0;
  1040 	TBool isPeFile = ETrue;
   955 	TBool isPeFile = ETrue;
  1041 	TBool isResource = EFalse;
   956 	TBool isResource = EFalse;
  1043 	TUint compression = 0;
   958 	TUint compression = 0;
  1044 	TBool callEntryPoint = EFalse;
   959 	TBool callEntryPoint = EFalse;
  1045 	TUint hardwareVariant=KVariantIndependent;
   960 	TUint hardwareVariant=KVariantIndependent;
  1046 	TBool mustBeInSysBin = EFalse;
   961 	TBool mustBeInSysBin = EFalse;
  1047 	TBool tryForSysBin = EFalse;
   962 	TBool tryForSysBin = EFalse;
  1048  	TBool warnFlag = EFalse;
   963 	TBool warnFlag = EFalse;
  1049 
   964 
  1050 	// do some validation of the keyword
   965 	// do some validation of the keyword
  1051 	TInt currentLine = iReader.CurrentLine();
   966 	TInt currentLine = iReader.CurrentLine();
  1052 
   967 
  1053 	switch (aKeyword)
   968 	switch (aKeyword) {
  1054 		{
       
  1055 	case EKeywordPrimary:
   969 	case EKeywordPrimary:
  1056 		imageFlags |= KRomImageFlagPrimary;
   970 		imageFlags |= KRomImageFlagPrimary;
  1057 		overrides |= KOverrideCodeUnpaged | KOverrideDataUnpaged;
   971 		overrides |= KOverrideCodeUnpaged | KOverrideDataUnpaged;
  1058 		mustBeInSysBin = gPlatSecEnforceSysBin;
   972 		mustBeInSysBin = gPlatSecEnforceSysBin;
  1059  		warnFlag = gEnableStdPathWarning;		
   973 		warnFlag = gEnableStdPathWarning;		
  1060 		hardwareVariant=ParseVariant();
   974 		hardwareVariant=ParseVariant();
  1061 		if (iKernelModel==ESingleKernel && !THardwareVariant(hardwareVariant).IsIndependent())
   975 		if (iKernelModel==ESingleKernel && !THardwareVariant(hardwareVariant).IsIndependent()) {
  1062 			{
       
  1063 			Print(EError,"Kernel must be independent in single kernel ROMs\n");
   976 			Print(EError,"Kernel must be independent in single kernel ROMs\n");
  1064 			}
   977 		}
  1065 		break;
   978 		break;
  1066 
   979 
  1067 	case EKeywordSecondary:
   980 	case EKeywordSecondary:
  1068 		imageFlags |= KRomImageFlagSecondary;
   981 		imageFlags |= KRomImageFlagSecondary;
  1069 		mustBeInSysBin = gPlatSecEnforceSysBin;
   982 		mustBeInSysBin = gPlatSecEnforceSysBin;
  1070  		warnFlag = gEnableStdPathWarning;
   983 		warnFlag = gEnableStdPathWarning;
  1071 		hardwareVariant=ParseVariant();
   984 		hardwareVariant=ParseVariant();
  1072 		break;
   985 		break;
  1073 
   986 
  1074 	case EKeywordVariant:
   987 	case EKeywordVariant:
  1075 		imageFlags |= KRomImageFlagVariant;
   988 		imageFlags |= KRomImageFlagVariant;
  1076 		overrides |= KOverrideCodeUnpaged | KOverrideDataUnpaged;
   989 		overrides |= KOverrideCodeUnpaged | KOverrideDataUnpaged;
  1077 		mustBeInSysBin = gPlatSecEnforceSysBin;
   990 		mustBeInSysBin = gPlatSecEnforceSysBin;
  1078  		warnFlag = gEnableStdPathWarning;		
   991 		warnFlag = gEnableStdPathWarning;		
  1079 		hardwareVariant=ParseVariant();
   992 		hardwareVariant=ParseVariant();
  1080 		break;
   993 		break;
  1081 
   994 
  1082 	case EKeywordExtension:
   995 	case EKeywordExtension:
  1083 		imageFlags |= KRomImageFlagExtension;
   996 		imageFlags |= KRomImageFlagExtension;
  1084 		overrides |= KOverrideCodeUnpaged | KOverrideDataUnpaged;
   997 		overrides |= KOverrideCodeUnpaged | KOverrideDataUnpaged;
  1085 		mustBeInSysBin = gPlatSecEnforceSysBin;
   998 		mustBeInSysBin = gPlatSecEnforceSysBin;
  1086  		warnFlag = gEnableStdPathWarning;
   999 		warnFlag = gEnableStdPathWarning;
  1087 		hardwareVariant=ParseVariant();
  1000 		hardwareVariant=ParseVariant();
  1088 		break;
  1001 		break;
  1089 
  1002 
  1090 	case EKeywordDevice:
  1003 	case EKeywordDevice:
  1091 		imageFlags |= KRomImageFlagDevice;
  1004 		imageFlags |= KRomImageFlagDevice;
  1092 		overrides |= KOverrideCodeUnpaged | KOverrideDataUnpaged;
  1005 		overrides |= KOverrideCodeUnpaged | KOverrideDataUnpaged;
  1093 		mustBeInSysBin = gPlatSecEnforceSysBin;
  1006 		mustBeInSysBin = gPlatSecEnforceSysBin;
  1094  		warnFlag = gEnableStdPathWarning;		
  1007 		warnFlag = gEnableStdPathWarning;		
  1095 		hardwareVariant=ParseVariant();
  1008 		hardwareVariant=ParseVariant();
  1096 		break;
  1009 		break;
  1097 
  1010 
  1098 	case EKeywordExecutableCompressionMethodBytePair:
  1011 	case EKeywordExecutableCompressionMethodBytePair:
  1099 		compression=KUidCompressionBytePair;
  1012 		compression=KUidCompressionBytePair;
  1100 		
  1013 
  1101 	case EKeywordExecutableCompressionMethodInflate:
  1014 	case EKeywordExecutableCompressionMethodInflate:
  1102 	case EKeywordFileCompress:
  1015 	case EKeywordFileCompress:
  1103 		compression = compression ? compression : KUidCompressionDeflate;
  1016 		compression = compression ? compression : KUidCompressionDeflate;
  1104 
  1017 
  1105 	case EKeywordExecutableCompressionMethodNone:	
  1018 	case EKeywordExecutableCompressionMethodNone:	
  1126 		break;
  1039 		break;
  1127 
  1040 
  1128 	case EKeywordDll:
  1041 	case EKeywordDll:
  1129 		callEntryPoint = ETrue;
  1042 		callEntryPoint = ETrue;
  1130 		// and fall through to handling for "file"
  1043 		// and fall through to handling for "file"
  1131 	
  1044 
  1132 	case EKeywordFile:
  1045 	case EKeywordFile: {
  1133 		{
  1046 
  1134 			
  1047 		char* nname = NormaliseFileName(iReader.Word(1)); 
  1135 		char* nname = NormaliseFileName(iReader.Word(1));
       
  1136 		strupr(nname);
  1048 		strupr(nname);
  1137 		
  1049 		if( gCompressionMethod == 0 || NULL != strstr(nname, ".DLL") || callEntryPoint ) {
  1138 		if( gCompressionMethod == 0 || NULL != strstr(nname, ".DLL") || callEntryPoint )
       
  1139 		{
       
  1140 			mustBeInSysBin = gPlatSecEnforceSysBin;
  1050 			mustBeInSysBin = gPlatSecEnforceSysBin;
  1141  			warnFlag = gEnableStdPathWarning;			
  1051 			warnFlag = gEnableStdPathWarning;			
  1142 			hardwareVariant=ParseVariant();
  1052 			hardwareVariant=ParseVariant();
  1143 		}
  1053 		}
  1144 		else 
  1054 		else  {
  1145 		{
       
  1146 			compression = gCompressionMethod;
  1055 			compression = gCompressionMethod;
  1147 			hardwareVariant=ParseVariant();
  1056 			hardwareVariant=ParseVariant();
  1148 			tryForSysBin = gPlatSecEnforceSysBin;
  1057 			tryForSysBin = gPlatSecEnforceSysBin;
  1149 		}
  1058 		}
  1150 		}
  1059 		delete []nname ;
  1151 		break;
  1060 	}
       
  1061 	break;
  1152 
  1062 
  1153 	default:
  1063 	default:
  1154 		Print(EError,"Unexpected keyword '%s' on line %d.\n",iReader.Word(0),currentLine);
  1064 		Print(EError,"Unexpected keyword '%s' on line %d.\n",iReader.Word(0),currentLine);
  1155 		return EFalse;
  1065 		return EFalse;
  1156 		}
  1066 	}
  1157 
  1067 
  1158 	if (isPeFile)
  1068 	if (isPeFile)
  1159 		iNumberOfPeFiles++;
  1069 		iNumberOfPeFiles++;
  1160 
  1070 
  1161 	// check the PC file exists
  1071 	// check the PC file exists
  1162 	char* nname = NormaliseFileName(iReader.Word(1));
  1072 	char* nname = NormaliseFileName(iReader.Word(1)); 
  1163 
  1073 	ifstream test(nname,ios_base::binary | ios_base::in); 
  1164 #if defined(__MSVCDOTNET__) || defined(__TOOLS2__)
  1074 
  1165 	ifstream test(nname,ios_base::binary );
  1075 	if (!test.is_open()) {
  1166 #else //!__MSVCDOTNET__
       
  1167 	ifstream test(nname,ios::nocreate | ios::binary); 
       
  1168 #endif //__MSVCDOTNET__
       
  1169 
       
  1170 	if (!test.is_open())
       
  1171 		{
       
  1172 		Print(EError,"Cannot open file %s for input.\n",iReader.Word(1));
  1076 		Print(EError,"Cannot open file %s for input.\n",iReader.Word(1));
  1173 		if(EKeywordHardwareConfigRepositoryData == aKeyword)
  1077 		if(EKeywordHardwareConfigRepositoryData == aKeyword) {
  1174 			{
  1078 			delete []nname;
  1175 			free(nname);
       
  1176 			return EFalse ;
  1079 			return EFalse ;
  1177 			}
  1080 		}
  1178 		iMissingFiles++;
  1081 		iMissingFiles++;
  1179 		}
  1082 	}
  1180 		
  1083 	if(EKeywordHardwareConfigRepositoryData == aKeyword) { // check hcr file 
  1181 	if(EKeywordHardwareConfigRepositoryData == aKeyword)
       
  1182 		{ // check hcr file 
       
  1183 
  1084 
  1184 		TUint32 magicWord = 0;
  1085 		TUint32 magicWord = 0;
  1185 		test.read(reinterpret_cast<char*>(&magicWord),sizeof(TUint32));
  1086 		test.read(reinterpret_cast<char*>(&magicWord),sizeof(TUint32));
  1186 		if(0x66524348 != magicWord)
  1087 		if(0x66524348 != magicWord) {
  1187 			{
       
  1188 			Print(EError,"Invalid hardware configuration repository data file %s .\n",iReader.Word(1));
  1088 			Print(EError,"Invalid hardware configuration repository data file %s .\n",iReader.Word(1));
  1189 			test.close();
  1089 			test.close();
  1190 			free(nname);
  1090 			delete []nname;
  1191 			return EFalse;
  1091 			return EFalse;
  1192 			}
  1092 		}
  1193 
  1093 
  1194 		}
  1094 	}
  1195 	test.close();
  1095 	test.close();
  1196 	free(nname);
  1096 	delete []nname;
  1197  	
  1097 
  1198 
  1098 
  1199  	TBool endOfName=EFalse;
  1099 	TBool endOfName=EFalse; 
  1200 	TText *epocStartPtr=IsValidFilePath(iReader.Text(2));
  1100 	if (IsValidFilePath(iReader.Word(2)) == NULL) {
  1201 	if (epocStartPtr==NULL)
       
  1202 		{
       
  1203 		Print(EError, "Invalid destination path on line %d\n",currentLine);
  1101 		Print(EError, "Invalid destination path on line %d\n",currentLine);
  1204 		return EFalse;
  1102 		return EFalse;
  1205 		}
  1103 	}
  1206 	epocStartPtr = (TText*)NormaliseFileName((const char*)epocStartPtr);
  1104 	char* epocStartPtr = NormaliseFileName(iReader.Word(2));
  1207 
  1105 	char* savedPtr = epocStartPtr;
  1208 	if(tryForSysBin)
  1106 	if(*epocStartPtr == '/' ||*epocStartPtr == '\\')
  1209 		{
  1107 				epocStartPtr++ ;
  1210 		if(strnicmp((const char*)epocStartPtr, "system\\bin\\", 11)==0)
  1108 #ifdef __LINUX__
       
  1109 	if(tryForSysBin) {
       
  1110 		if(strnicmp(epocStartPtr, "system/bin/", 11)==0)
  1211 			mustBeInSysBin = 1;
  1111 			mustBeInSysBin = 1;
  1212 		if(strnicmp((const char*)epocStartPtr, "system\\libs\\", 12)==0)
  1112 		if(strnicmp(epocStartPtr, "system/libs/", 12)==0)
  1213 			mustBeInSysBin = 1;
  1113 			mustBeInSysBin = 1;
  1214 		if(strnicmp((const char*)epocStartPtr, "system\\programs\\", 16)==0)
  1114 		if(strnicmp(epocStartPtr, "system/programs/", 16)==0)
  1215 			mustBeInSysBin = 1;
  1115 			mustBeInSysBin = 1;
  1216 		}
  1116 	}
       
  1117 
       
  1118 	static const char sysBin[] = "sys/bin/";
       
  1119 #else
       
  1120 	if(tryForSysBin) {
       
  1121 		if(strnicmp(epocStartPtr, "system\\bin\\", 11)==0)
       
  1122 			mustBeInSysBin = 1;
       
  1123 		if(strnicmp(epocStartPtr, "system\\libs\\", 12)==0)
       
  1124 			mustBeInSysBin = 1;
       
  1125 		if(strnicmp(epocStartPtr, "system\\programs\\", 16)==0)
       
  1126 			mustBeInSysBin = 1;
       
  1127 	}
  1217 
  1128 
  1218 	static const char sysBin[] = "sys\\bin\\";
  1129 	static const char sysBin[] = "sys\\bin\\";
       
  1130 #endif
  1219 	static const int sysBinLength = sizeof(sysBin)-1;
  1131 	static const int sysBinLength = sizeof(sysBin)-1;
  1220 
  1132 
  1221  	if (strnicmp((const char*)epocStartPtr, sysBin, sysBinLength)!=0)
  1133 	if (strnicmp(epocStartPtr, sysBin, sysBinLength)!=0) {
  1222  	{		
  1134 		if(mustBeInSysBin) {
  1223  		if(mustBeInSysBin)
  1135 			TInt len = strlen((char*)epocStartPtr);
  1224 		{
  1136 			TInt i = len;
  1225  			TInt len = strlen((char*)epocStartPtr);
  1137 			while(--i>=0) if(epocStartPtr[i] == SLASH_CHAR) break;
  1226  			TInt i = len;
  1138 			++i;
  1227  			while(--i>=0) if(epocStartPtr[i]=='\\') break;
  1139 			char* old = (char*)epocStartPtr;
  1228  			++i;
  1140 			epocStartPtr = new char[sysBinLength+(len-i)+1];
  1229  			char* old = (char*)epocStartPtr;
  1141 			strcpy((char*)epocStartPtr,sysBin);
  1230  			epocStartPtr = (TText*)malloc(sysBinLength+(len-i)+1);
  1142 			strcat((char*)epocStartPtr,old+i);
  1231  			strcpy((char*)epocStartPtr,sysBin);
  1143 			delete []old;
  1232  			strcat((char*)epocStartPtr,old+i);
  1144 			savedPtr = epocStartPtr;
  1233 
  1145 			Print(EDiagnostic, "%s moved to %s\n", old, epocStartPtr); 
  1234  			Print(EDiagnostic, "%s moved to %s\n", old, epocStartPtr);
  1146 		}
  1235  			delete old;
  1147 		else if (warnFlag) {
  1236 		}
  1148 			Print(EWarning, "Outside standard path at %s\n", epocStartPtr);
  1237  		else if (warnFlag)
  1149 		}		
  1238  		{
  1150 	}	
  1239  			Print(EWarning, "Outside standard path at %s\n", epocStartPtr);
  1151 
  1240  		}		
  1152 	char *epocEndPtr=epocStartPtr; 
  1241  	}	
  1153 
  1242 
       
  1243 	TText *epocEndPtr=epocStartPtr;
       
  1244 	AUTO_FREE(epocStartPtr);	
       
  1245 		
       
  1246 	TRomNode* dir=iRootDirectory;
  1154 	TRomNode* dir=iRootDirectory;
  1247 	TRomNode* subDir=0;
  1155 	TRomNode* subDir=0;
  1248 	TRomBuilderEntry *file=0;
  1156 	TRomBuilderEntry *file=0;
  1249 	while (!endOfName)
  1157 	while (!endOfName) {
  1250 		{
  1158 		endOfName = GetNextBitOfFileName(epocEndPtr);
  1251 		endOfName = GetNextBitOfFileName(&epocEndPtr);
  1159 		if (endOfName){ // file 
  1252 		if (endOfName) // file
       
  1253 			{
       
  1254 			TRomNode* alreadyExists=dir->FindInDirectory(epocStartPtr,hardwareVariant);
  1160 			TRomNode* alreadyExists=dir->FindInDirectory(epocStartPtr,hardwareVariant);
  1255 			if (alreadyExists) // duplicate file
  1161 			if (alreadyExists) { // duplicate file 
  1256 				{
  1162 				if (gKeepGoing) {
  1257 				Print(EError, "Duplicate file for %s on line %d\n",iReader.Word(1),iReader.CurrentLine());
  1163 					Print(EWarning, "Duplicate file for %s on line %d, will be ignored\n",iReader.Word(1),iReader.CurrentLine());
  1258 				return EFalse;
  1164 					delete []savedPtr;
       
  1165 					switch (aKeyword) {
       
  1166 						case EKeywordExecutableCompressionMethodBytePair:
       
  1167 						case EKeywordExecutableCompressionMethodInflate:
       
  1168 						case EKeywordFileCompress:
       
  1169 						case EKeywordExecutableCompressionMethodNone:	
       
  1170 						case EKeywordFileUncompress:
       
  1171 						case EKeywordData:
       
  1172 							iNumberOfDataFiles--;
       
  1173 							break;
       
  1174 						case EKeywordHardwareConfigRepositoryData:
       
  1175 							iNumberOfHCRDataFiles -- ;
       
  1176 							break;	
       
  1177 						default:	
       
  1178 							break;
       
  1179 					}		
       
  1180 					if (isPeFile)
       
  1181 						iNumberOfPeFiles--;
       
  1182 					return ETrue;
       
  1183 				
  1259 				}
  1184 				}
       
  1185 				else {
       
  1186 					Print(EError, "Duplicate file for %s on line %d\n",iReader.Word(1),iReader.CurrentLine());
       
  1187 					delete []savedPtr;
       
  1188 					return EFalse;
       
  1189 				}
       
  1190 			}
  1260 			file = new TRomBuilderEntry(iReader.Word(1),epocStartPtr);
  1191 			file = new TRomBuilderEntry(iReader.Word(1),epocStartPtr);
  1261 			file->iRomImageFlags = imageFlags;
  1192 			file->iRomImageFlags = imageFlags;
  1262 			file->iResource = isResource;
  1193 			file->iResource = isResource;
  1263 			file->iNonXIP = isNonXIP;
  1194 			file->iNonXIP = isNonXIP;
  1264 			file->iCompression = compression;
  1195 			file->iCompression = compression;
  1265 			
  1196 
  1266 			file->iArea = iAreaSet.FindByName(AreaSet::KDefaultAreaName);
  1197 			file->iArea = iAreaSet.FindByName(AreaSet::KDefaultAreaName);
  1267 			file->iRomSectionNumber = iCurrentSectionNumber;
  1198 			file->iRomSectionNumber = iCurrentSectionNumber;
  1268 			file->iHardwareVariant = hardwareVariant;
  1199 			file->iHardwareVariant = hardwareVariant;
  1269 			file->iOverrideFlags |= overrides;
  1200 			file->iOverrideFlags |= overrides;
  1270 			if (callEntryPoint)
  1201 			if (callEntryPoint)
  1271 				file->SetCallEntryPoint(callEntryPoint);
  1202 				file->SetCallEntryPoint(callEntryPoint);
  1272 			file->iAlignment=aAlign;
  1203 			file->iAlignment=aAlign;
  1273 			TUint32 uid;
  1204 			TUint32 uid;
  1274 			file->iBareName = SplitFileName((const char*)file->iName, uid, file->iVersionInName, file->iVersionPresentInName);
  1205 			file->iBareName = SplitFileName(file->iName, uid, file->iVersionInName, file->iVersionPresentInName);
  1275 			assert(uid==0 && !(file->iVersionPresentInName & EUidPresent));
  1206 			assert(uid==0 && !(file->iVersionPresentInName & EUidPresent));
  1276 			if (strchr(file->iBareName, '{') || strchr(file->iBareName, '}'))
  1207 			if (strchr(file->iBareName, '{') || strchr(file->iBareName, '}')) {
  1277 				{
       
  1278 				Print(EError, "Illegal character in name %s on line %d\n", file->iName, iReader.CurrentLine());
  1208 				Print(EError, "Illegal character in name %s on line %d\n", file->iName, iReader.CurrentLine());
  1279 				delete file;
  1209 				delete file;
       
  1210 				delete []savedPtr;
  1280 				return EFalse;
  1211 				return EFalse;
  1281 				}
  1212 			}
  1282 			TRomNode* node=new TRomNode(epocStartPtr, file);
  1213 			TRomNode* node=new TRomNode(epocStartPtr, file);
  1283 			if (node==0){
  1214 			if (node==0){
  1284 				delete file;
  1215 				delete file;
       
  1216 				delete []savedPtr;
  1285 				return EFalse;
  1217 				return EFalse;
  1286 			}
  1218 			}
  1287 				
  1219 
  1288 			TInt r=ParseFileAttributes(node, file);
  1220 			TInt r=ParseFileAttributes(node, file);
  1289 			if (r!=KErrNone){
  1221 			if (r!=KErrNone){
  1290 				delete file;
  1222 				delete file;
  1291 				delete node;
  1223 				delete node;
       
  1224 				delete []savedPtr;
  1292 				return EFalse;
  1225 				return EFalse;
  1293 			}
  1226 			}
  1294 
  1227 
  1295 			TRACE(TAREA, Print(EScreen, "File %s area '%s'\n", iReader.Word(1), file->iArea->Name()));
  1228 			TRACE(TAREA, Print(EScreen, "File %s area '%s'\n", iReader.Word(1), file->iArea->Name()));
  1296 
  1229 
  1297 			// Apply some specific overrides to the primary
  1230 			// Apply some specific overrides to the primary
  1298 			if (imageFlags & KRomImageFlagPrimary)
  1231 			if (imageFlags & KRomImageFlagPrimary) {
  1299 				{
       
  1300 				if (file->iCodeAlignment < iPageSize)
  1232 				if (file->iCodeAlignment < iPageSize)
  1301 					file->iCodeAlignment = iPageSize;	// Kernel code is at least page aligned
  1233 					file->iCodeAlignment = iPageSize;	// Kernel code is at least page aligned
  1302 				file->iHeapSizeMin = iKernHeapMin;
  1234 				file->iHeapSizeMin = iKernHeapMin;
  1303 				file->iHeapSizeMax = iKernHeapMax;
  1235 				file->iHeapSizeMax = iKernHeapMax;
  1304 				file->iOverrideFlags |= KOverrideHeapMin+KOverrideHeapMax;
  1236 				file->iOverrideFlags |= KOverrideHeapMin+KOverrideHeapMax;
  1305 				}
  1237 			}
  1306 
  1238 
  1307 			if (!file->iPatched)
  1239 			if (!file->iPatched)
  1308 				dir->AddFile(node);	// to ROM directory structure, though possibly hidden
  1240 				dir->AddFile(node);	// to ROM directory structure, though possibly hidden
  1309 			if (isPeFile)
  1241 			if (isPeFile)
  1310 				TRomNode::AddExecutableFile(iLastExecutable, node);
  1242 				TRomNode::AddExecutableFile(iLastExecutable, node);
  1311 			
  1243 
  1312 			AddFile(file);
  1244 			AddFile(file);
  1313 			}		 
  1245 		}		 
  1314 		else // directory
  1246 		else // directory {
  1315 			{
       
  1316 			subDir = dir->FindInDirectory(epocStartPtr);
  1247 			subDir = dir->FindInDirectory(epocStartPtr);
  1317 			if (!subDir) // sub directory does not exist
  1248 		if (!subDir) { // sub directory does not exist 
  1318 				{
  1249 			subDir = dir->NewSubDir(epocStartPtr);
  1319 				subDir = dir->NewSubDir(epocStartPtr);
  1250 			if (!subDir){
  1320 				if (!subDir)
  1251 				delete []savedPtr;
  1321 					return EFalse;
  1252 				return EFalse;
  1322 				}
  1253 			}
  1323 			dir=subDir;
  1254 		}
  1324 			epocStartPtr = epocEndPtr;
  1255 		dir=subDir;
  1325 			}
  1256 		epocStartPtr = epocEndPtr;
  1326 		}
  1257 	}
  1327 	return ETrue;
  1258  
  1328 	}
  1259 	delete []savedPtr;
  1329 
  1260 	return ETrue;	
  1330 
  1261 }
  1331 void CObeyFile::AddFile(TRomBuilderEntry* aFile)
  1262 
  1332 	{
  1263 
       
  1264 void CObeyFile::AddFile(TRomBuilderEntry* aFile) {
  1333 	aFile->iArea->AddFile(aFile);
  1265 	aFile->iArea->AddFile(aFile);
  1334 
  1266 
  1335 	*iNextFilePtrPtr = aFile;
  1267 	*iNextFilePtrPtr = aFile;
  1336 	iNextFilePtrPtr = &(aFile->iNext);
  1268 	iNextFilePtrPtr = &(aFile->iNext);
  1337 	}
  1269 }
  1338 
  1270 
  1339 
  1271 
  1340 TBool CObeyFile::ProcessRenaming(enum EKeyword aKeyword)
  1272 TBool CObeyFile::ProcessRenaming(enum EKeyword aKeyword) {
  1341 	{
       
  1342 	TUint hardwareVariant=ParseVariant();
  1273 	TUint hardwareVariant=ParseVariant();
  1343 
  1274 
  1344 	// find existing file
  1275 	// find existing file
  1345 	TBool endOfName=EFalse;
  1276 	TBool endOfName=EFalse;
  1346 
  1277 
  1347 	// Store the current name and new name to maintain renamed file map
  1278 	// Store the current name and new name to maintain renamed file map
  1348 	String currentName=iReader.Word(1);
  1279 	string currentName=iReader.Word(1);
  1349 	String newName=iReader.Word(2);
  1280 	string newName=iReader.Word(2);
  1350 
  1281 
  1351 	TText *epocStartPtr=IsValidFilePath(iReader.Text(1));
  1282 	 
  1352 	if (epocStartPtr==NULL)
  1283 	if (IsValidFilePath(iReader.Word(1)) == NULL) {
  1353 		{
       
  1354 		Print(EError, "Invalid source path on line %d\n",iReader.CurrentLine());
  1284 		Print(EError, "Invalid source path on line %d\n",iReader.CurrentLine());
  1355 		return EFalse;
  1285 		return EFalse;
  1356 		}
  1286 	}
  1357 	epocStartPtr = (TText*)NormaliseFileName((const char*)epocStartPtr);
  1287 	char* epocStartPtr = NormaliseFileName(iReader.Word(1));
  1358 	TText *epocEndPtr=epocStartPtr;
  1288 	char* savedPtr = epocStartPtr;	
  1359 	AUTO_FREE(epocStartPtr);
  1289 	if(*epocStartPtr == '/' ||*epocStartPtr == '\\')
  1360 
  1290 		epocStartPtr++ ;
       
  1291 	char* epocEndPtr = epocStartPtr; 
  1361 	char saved_srcname[257];
  1292 	char saved_srcname[257];
  1362 	strcpy(saved_srcname, iReader.Word(1));
  1293 	strcpy(saved_srcname, iReader.Word(1));
  1363 
  1294 
  1364 	TRomNode* dir=iRootDirectory;
  1295 	TRomNode* dir=iRootDirectory;
  1365 	TRomNode* existingFile=0;
  1296 	TRomNode* existingFile=0;
  1366 	while (!endOfName)
  1297 	while (!endOfName) {
  1367 		{
  1298 		endOfName = GetNextBitOfFileName(epocEndPtr);
  1368 		endOfName = GetNextBitOfFileName(&epocEndPtr);
  1299 		if (endOfName) { // file 
  1369 		if (endOfName) // file
       
  1370 			{
       
  1371 			existingFile=dir->FindInDirectory(epocStartPtr,hardwareVariant);
  1300 			existingFile=dir->FindInDirectory(epocStartPtr,hardwareVariant);
  1372 			if (existingFile)
  1301 			if (existingFile) {
  1373 				{
       
  1374 				TInt fileCount=0;
  1302 				TInt fileCount=0;
  1375 				TInt dirCount=0;
  1303 				TInt dirCount=0;
  1376 				existingFile->CountDirectory(fileCount, dirCount);
  1304 				existingFile->CountDirectory(fileCount, dirCount);
  1377 				if (dirCount != 0 || fileCount != 0)
  1305 				if (dirCount != 0 || fileCount != 0) {					
  1378 					{
  1306 					Print(EError, "Keyword %s not applicable to directories - line %d\n",
  1379 					Print(EError, "Keyword %s not applicable to directories - line %d\n",iReader.Word(0),iReader.CurrentLine());
  1307 						iReader.Word(0),iReader.CurrentLine());
       
  1308 					delete []savedPtr;
  1380 					return EFalse;
  1309 					return EFalse;
  1381 					}
  1310 					
  1382 				}
  1311 				}
  1383 			}
  1312 			}
  1384 		else // directory
  1313 		}
  1385 			{
  1314 		else {// directory 
  1386 			TRomNode* subDir = dir->FindInDirectory(epocStartPtr);
  1315 			TRomNode* subDir = dir->FindInDirectory(epocStartPtr);
  1387 			if (!subDir) // sub directory does not exist
  1316 			if (!subDir) // sub directory does not exist
  1388 				break;
  1317 				break;
  1389 			dir=subDir;
  1318 			dir=subDir;
  1390 			epocStartPtr = epocEndPtr;
  1319 			epocStartPtr = epocEndPtr;
  1391 			}
  1320 		}
  1392 		}
  1321 	}
  1393 	if (aKeyword == EKeywordHide)
  1322 	if (aKeyword == EKeywordHide) {
  1394 		{
  1323 		if (!existingFile) {
  1395 		if (!existingFile)
       
  1396 			{
       
  1397 			Print(EWarning, "Hiding non-existent file %s on line %d\n", 
  1324 			Print(EWarning, "Hiding non-existent file %s on line %d\n", 
  1398 				saved_srcname, iReader.CurrentLine());
  1325 				saved_srcname, iReader.CurrentLine());
  1399 			// Just a warning, as we've achieved the right overall effect.
  1326 			// Just a warning, as we've achieved the right overall effect.
  1400 			}
  1327 		}
  1401 		else
  1328 		else {
  1402 			{
       
  1403 			existingFile->iHidden = ETrue;
  1329 			existingFile->iHidden = ETrue;
  1404 			}
  1330 		}
       
  1331 		delete []savedPtr;
  1405 		return ETrue;
  1332 		return ETrue;
  1406 		}
  1333 	}
  1407 
  1334 
  1408 	if (!existingFile)
  1335 	if (!existingFile) {
  1409 		{
       
  1410 		Print(EError, "Can't %s non-existent source file %s on line %d\n",
  1336 		Print(EError, "Can't %s non-existent source file %s on line %d\n",
  1411 			iReader.Word(0), saved_srcname, iReader.CurrentLine());
  1337 			iReader.Word(0), saved_srcname, iReader.CurrentLine());
       
  1338 		delete []savedPtr;
  1412 		return EFalse;
  1339 		return EFalse;
  1413 		}
  1340 	}
  1414 
  1341 	delete []savedPtr;
  1415 	epocStartPtr=IsValidFilePath(iReader.Text(2));
  1342 	epocStartPtr=(char*)IsValidFilePath(iReader.Word(2));
  1416 	epocEndPtr=epocStartPtr;
  1343 	epocEndPtr=epocStartPtr;
  1417 	endOfName=EFalse;
  1344 	endOfName=EFalse;
  1418 	if (epocStartPtr==NULL)
  1345 	if (epocStartPtr==NULL) {
  1419 		{
       
  1420 		Print(EError, "Invalid destination path on line %d\n",iReader.CurrentLine());
  1346 		Print(EError, "Invalid destination path on line %d\n",iReader.CurrentLine());
  1421 		return EFalse;
  1347 		return EFalse;
  1422 		}
  1348 	}
  1423 
  1349 
  1424 	TRomNode* newdir=iRootDirectory;
  1350 	TRomNode* newdir=iRootDirectory;
  1425 	while (!endOfName)
  1351 	while (!endOfName) {
  1426 		{
  1352 		endOfName = GetNextBitOfFileName(epocEndPtr);
  1427 		endOfName = GetNextBitOfFileName(&epocEndPtr);
  1353 		if (endOfName){ // file 
  1428 		if (endOfName) // file
       
  1429 			{
       
  1430 			TRomNode* alreadyExists=newdir->FindInDirectory(epocStartPtr,existingFile->HardwareVariant());
  1354 			TRomNode* alreadyExists=newdir->FindInDirectory(epocStartPtr,existingFile->HardwareVariant());
  1431 			if (alreadyExists) // duplicate file
  1355 			if (alreadyExists) { // duplicate file 
  1432 				{
  1356 				if (gKeepGoing) {
  1433 				Print(EError, "Duplicate file for %s on line %d\n",saved_srcname,iReader.CurrentLine());
  1357 					Print(EWarning, "Duplicate file for %s on line %d, renaming will be skipped\n",saved_srcname,iReader.CurrentLine());
  1434 				return EFalse;
  1358 					return ETrue;			
  1435 				}
  1359 				}
  1436 			}
  1360 				else {
  1437 		else // directory
  1361 					Print(EError, "Duplicate file for %s on line %d\n",saved_srcname,iReader.CurrentLine());
  1438 			{
  1362 					return EFalse;
       
  1363 				}
       
  1364 			}
       
  1365 		}
       
  1366 		else { // directory 
  1439 			TRomNode* subDir = newdir->FindInDirectory(epocStartPtr);
  1367 			TRomNode* subDir = newdir->FindInDirectory(epocStartPtr);
  1440 			if (!subDir) // sub directory does not exist
  1368 			if (!subDir) { // sub directory does not exist 
  1441 				{
       
  1442 				subDir = newdir->NewSubDir(epocStartPtr);
  1369 				subDir = newdir->NewSubDir(epocStartPtr);
  1443 				if (!subDir)
  1370 				if (!subDir)
  1444 					return EFalse;
  1371 					return EFalse;
  1445 				}
  1372 			}
  1446 			newdir=subDir;
  1373 			newdir=subDir;
  1447 			epocStartPtr = epocEndPtr;
  1374 			epocStartPtr = epocEndPtr;
  1448 			}
  1375 		}
  1449 		}
  1376 	}
  1450 
  1377 
  1451 	if (aKeyword == EKeywordRename)
  1378 	if (aKeyword == EKeywordRename) {
  1452 		{
       
  1453 		// rename => remove existingFile and insert into tree at new place
  1379 		// rename => remove existingFile and insert into tree at new place
  1454 		// has no effect on the iNextExecutable or iNextNodeForSameFile links
  1380 		// has no effect on the iNextExecutable or iNextNodeForSameFile links
  1455 
  1381 
  1456 		TInt r=ParseFileAttributes(existingFile, existingFile->iRomFile->iRbEntry);
  1382 		TInt r=ParseFileAttributes(existingFile, existingFile->iRomFile->iRbEntry);
  1457 		if (r!=KErrNone)
  1383 		if (r!=KErrNone)
  1458 			return EFalse;
  1384 			return EFalse;
  1459 		r = existingFile->Rename(dir, newdir, epocStartPtr);
  1385 		r = existingFile->Rename(dir, newdir, epocStartPtr);
  1460 		if (r==KErrBadName)
  1386 		if (r==KErrBadName) {
  1461 			{
       
  1462 			Print(EError, "Bad name %s at line %d\n", epocStartPtr, iReader.CurrentLine());
  1387 			Print(EError, "Bad name %s at line %d\n", epocStartPtr, iReader.CurrentLine());
  1463 			return EFalse;
  1388 			return EFalse;
  1464 			}
  1389 		}
  1465 		else if (r==KErrArgument)
  1390 		else if (r==KErrArgument) {
  1466 			{
       
  1467 			Print(EError, "Version in name %s does not match version in file header at line %d\n", epocStartPtr, iReader.CurrentLine());
  1391 			Print(EError, "Version in name %s does not match version in file header at line %d\n", epocStartPtr, iReader.CurrentLine());
  1468 			return EFalse;
  1392 			return EFalse;
  1469 			}
  1393 		}
  1470 		// Store the current and new name of file in the renamed file map.
  1394 		// Store the current and new name of file in the renamed file map.
  1471 		iPatchData->AddToRenamedFileMap(currentName, newName);
  1395 		iPatchData->AddToRenamedFileMap(currentName, newName);
  1472 		return ETrue;
  1396 		return ETrue;
  1473 		}
  1397 	}
  1474 	
  1398 
  1475 	// alias => create new TRomNode entry and insert into tree
  1399 	// alias => create new TRomNode entry and insert into tree
  1476 
  1400 
  1477 	TRomNode* node = new TRomNode(epocStartPtr, existingFile);
  1401 	TRomNode* node = new TRomNode(epocStartPtr, existingFile);
  1478 	if (node == 0)
  1402 	if (node == 0) {
  1479 		{
       
  1480 		Print(EError, "Out of memory\n");
  1403 		Print(EError, "Out of memory\n");
  1481 		return EFalse;
  1404 		return EFalse;
  1482 		}
  1405 	}
  1483 
  1406 
  1484 	TInt r = node->Alias(existingFile, iLastExecutable);
  1407 	TInt r = node->Alias(existingFile, iLastExecutable);
  1485 	if (r==KErrBadName)
  1408 	if (r==KErrBadName) {
  1486 		{
       
  1487 		Print(EError, "Bad name %s at line %d\n", epocStartPtr, iReader.CurrentLine());
  1409 		Print(EError, "Bad name %s at line %d\n", epocStartPtr, iReader.CurrentLine());
  1488 		return EFalse;
  1410 		return EFalse;
  1489 		}
  1411 	}
  1490 	else if (r==KErrArgument)
  1412 	else if (r==KErrArgument) {
  1491 		{
       
  1492 		Print(EError, "Version in name %s does not match version in file header at line %d\n", epocStartPtr, iReader.CurrentLine());
  1413 		Print(EError, "Version in name %s does not match version in file header at line %d\n", epocStartPtr, iReader.CurrentLine());
  1493 		return EFalse;
  1414 		return EFalse;
  1494 		}
  1415 	}
  1495 	r=ParseFileAttributes(node, 0);
  1416 	r=ParseFileAttributes(node, 0);
  1496 	if (r!=KErrNone)
  1417 	if (r!=KErrNone)
  1497 		return EFalse;
  1418 		return EFalse;
  1498 
  1419 
  1499 	newdir->AddFile(node);	// to ROM directory structure, though possibly hidden
  1420 	newdir->AddFile(node);	// to ROM directory structure, though possibly hidden
  1500 
  1421 
  1501 	return ETrue;
  1422 	return ETrue;
  1502 	}
  1423 }
  1503 
  1424 
  1504 
  1425 
  1505 TInt ParsePagingPolicy(const char* policy)
  1426 TInt ParsePagingPolicy(const char* policy) {
  1506 	{
       
  1507 	if(stricmp(policy,"NOPAGING")==0)
  1427 	if(stricmp(policy,"NOPAGING")==0)
  1508 		return EKernelConfigPagingPolicyNoPaging;
  1428 		return EKernelConfigPagingPolicyNoPaging;
  1509 	else if (stricmp(policy,"ALWAYSPAGE")==0)
  1429 	else if (stricmp(policy,"ALWAYSPAGE")==0)
  1510 		return EKernelConfigPagingPolicyAlwaysPage;
  1430 		return EKernelConfigPagingPolicyAlwaysPage;
  1511 	else if(stricmp(policy,"DEFAULTUNPAGED")==0)
  1431 	else if(stricmp(policy,"DEFAULTUNPAGED")==0)
  1512 		return EKernelConfigPagingPolicyDefaultUnpaged;
  1432 		return EKernelConfigPagingPolicyDefaultUnpaged;
  1513 	else if(stricmp(policy,"DEFAULTPAGED")==0)
  1433 	else if(stricmp(policy,"DEFAULTPAGED")==0)
  1514 		return EKernelConfigPagingPolicyDefaultPaged;
  1434 		return EKernelConfigPagingPolicyDefaultPaged;
  1515 	return KErrArgument;
  1435 	return KErrArgument;
  1516 	}
  1436 }
  1517 
  1437 
  1518 
  1438 
  1519 TBool CObeyFile::ProcessKeyword(enum EKeyword aKeyword)
  1439 TBool CObeyFile::ProcessKeyword(enum EKeyword aKeyword) {
  1520 	{
  1440 	TUint hardwareVariant=KVariantIndependent; 
  1521 	TUint hardwareVariant=KVariantIndependent;
       
  1522 
       
  1523 	#ifdef __TOOLS2__
       
  1524 	istringstream val(iReader.Word(1));
       
  1525 	#else
       
  1526 	istrstream val(iReader.Word(1),strlen(iReader.Word(1)));
       
  1527 	#endif
       
  1528 
       
  1529 #if defined(__MSVCDOTNET__) || defined (__TOOLS2__)
       
  1530 	val >> setbase(0);
       
  1531 #endif //__MSVCDOTNET__
       
  1532 
       
  1533 	TBool success = ETrue;
  1441 	TBool success = ETrue;
  1534 
  1442 	switch (aKeyword) {
  1535 	switch (aKeyword)
       
  1536 		{
       
  1537 	case EKeywordUnicode:
  1443 	case EKeywordUnicode:
  1538 		Unicode=ETrue;
  1444 		Unicode=ETrue;
  1539 		break;
  1445 		break;
  1540 	case EKeywordAscii:
  1446 	case EKeywordAscii:
  1541 		Unicode=EFalse;
  1447 		Unicode=EFalse;
  1547 	case EKeywordMultiKernel:
  1453 	case EKeywordMultiKernel:
  1548 		iKernelModel=EMultipleKernels;
  1454 		iKernelModel=EMultipleKernels;
  1549 		break;
  1455 		break;
  1550 
  1456 
  1551 	case EKeywordBootBinary:
  1457 	case EKeywordBootBinary:
  1552 		iReader.CopyWord(1, iBootFileName);
  1458 		iBootFileName = iReader.DupWord(1);
  1553 		break;
  1459 		break;
  1554 	case EKeywordRomName:
  1460 	case EKeywordRomName:
  1555 		iReader.CopyWord(1, iRomFileName);
  1461 		iRomFileName = iReader.DupWord(1);
  1556 		break;
  1462 		break;
  1557 	case EKeywordRomNameOdd:
  1463 	case EKeywordRomNameOdd:
  1558 		iReader.CopyWord(1, iRomOddFileName);
  1464 		iRomOddFileName = iReader.DupWord(1);
  1559 		break;
  1465 		break;
  1560 	case EKeywordRomNameEven:
  1466 	case EKeywordRomNameEven:
  1561 		iReader.CopyWord(1, iRomEvenFileName);
  1467 		iRomEvenFileName = iReader.DupWord(1);
  1562 		break;
  1468 		break;
  1563 	case EKeywordSRecordFileName:
  1469 	case EKeywordSRecordFileName:
  1564 		iReader.CopyWord(1, iSRecordFileName);
  1470 		iSRecordFileName = iReader.DupWord(1);
  1565 		break;
  1471 		break;
  1566 
  1472 
  1567 	case EKeywordRomLinearBase:
  1473 	case EKeywordRomLinearBase:
  1568 		val >> iRomLinearBase;
  1474 		Val(iRomLinearBase,iReader.Word(1));
  1569 		break;
  1475 		break;
  1570 	case EKeywordRomSize:
  1476 	case EKeywordRomSize:
  1571 		val >> iRomSize;
  1477 		Val(iRomSize,iReader.Word(1));
  1572 		break;
  1478 		break;
  1573 	case EKeywordRomAlign:
  1479 	case EKeywordRomAlign:
  1574 		val >> iRomAlign;
  1480 		Val(iRomAlign,iReader.Word(1));
  1575 		break;
  1481 		break;
  1576 	case EKeywordKernelDataAddress:
  1482 	case EKeywordKernelDataAddress:
  1577 		val >> iKernDataRunAddress;
  1483 		Val(iKernDataRunAddress,iReader.Word(1));
  1578 		break;
  1484 		break;
  1579 	case EKeywordKernelHeapMin:
  1485 	case EKeywordKernelHeapMin:
  1580 		val >> iKernHeapMin;
  1486 		Val(iKernHeapMin,iReader.Word(1));
  1581 		break;
  1487 		break;
  1582 	case EKeywordKernelHeapMax:
  1488 	case EKeywordKernelHeapMax:
  1583 		val >> iKernHeapMax;
  1489 		Val(iKernHeapMax,iReader.Word(1));
  1584 		break;
  1490 		break;
  1585 	case EKeywordDataAddress:
  1491 	case EKeywordDataAddress:
  1586 		val >> iDataRunAddress;
  1492 		Val(iDataRunAddress,iReader.Word(1));
  1587 		break;
  1493 		break;
  1588 	case EKeywordDefaultStackReserve:
  1494 	case EKeywordDefaultStackReserve:
  1589 		val >> iDefaultStackReserve;
  1495 		Val(iDefaultStackReserve,iReader.Word(1));
  1590 		break;
  1496 		break;
  1591 	case EKeywordVersion:
  1497 	case EKeywordVersion:
  1592 		val >> iVersion;
  1498 		{
       
  1499 			istringstream val(iReader.Word(1));
       
  1500 			val >> iVersion ;
       
  1501 		}
  1593 		break;
  1502 		break;
  1594 	case EKeywordSRecordBase:
  1503 	case EKeywordSRecordBase:
  1595 		val >> iSRecordBase;
  1504 		Val(iSRecordBase,iReader.Word(1));
  1596 		break;
  1505 		break;
  1597 	case EKeywordRomChecksum:
  1506 	case EKeywordRomChecksum:
  1598 		val >> iCheckSum;
  1507 		Val(iCheckSum,iReader.Word(1));
  1599 		break;
  1508 		break;
  1600 	case EKeywordHardware:
  1509 	case EKeywordHardware:
  1601 		val >> iHardware;
  1510 		Val(iHardware,iReader.Word(1));
  1602 		break;
  1511 		break;
  1603 	case EKeywordLanguages:
  1512 	case EKeywordLanguages:
  1604 		iReader.ProcessLanguages(iLanguage);
  1513 		iReader.ProcessLanguages(iLanguage);
  1605 		break;
  1514 		break;
  1606 	case EKeywordTime:
  1515 	case EKeywordTime:
  1607 		iReader.ProcessTime(iTime);
  1516 		iReader.ProcessTime(iTime);
  1608 		break;
  1517 		break;
  1609 	case EKeywordDllDataTop:
  1518 	case EKeywordDllDataTop:
  1610 		val >> iDllDataTop;
  1519 		Val(iDllDataTop,iReader.Word(1));
  1611 		break;
  1520 		break;
  1612 
  1521 
  1613 	case EKeywordMemModel:
  1522 	case EKeywordMemModel: {
  1614 		{
  1523 			const char* arg1=iReader.Word(1);
  1615 		char* arg1=iReader.Word(1);
  1524 			const char* arg2=iReader.Word(2);
  1616 		char* arg2=iReader.Word(2);
  1525 			const char* arg3=iReader.Word(3);
  1617 		char* arg3=iReader.Word(3);
  1526 			const char* arg4=iReader.Word(4);
  1618 		char* arg4=iReader.Word(4);
  1527 			if (strnicmp(arg1, "moving", 6)==0)
  1619 		if (strnicmp(arg1, "moving", 6)==0)
  1528 				iMemModel=E_MM_Moving;
  1620 			iMemModel=E_MM_Moving;
  1529 			else if (strnicmp(arg1, "direct", 6)==0)
  1621 		else if (strnicmp(arg1, "direct", 6)==0)
  1530 				iMemModel=E_MM_Direct;
  1622 			iMemModel=E_MM_Direct;
  1531 			else if (strnicmp(arg1, "multiple", 8)==0)
  1623 		else if (strnicmp(arg1, "multiple", 8)==0)
  1532 				iMemModel=E_MM_Multiple;
  1624 			iMemModel=E_MM_Multiple;
  1533 			else if (strnicmp(arg1, "flexible", 8)==0)
  1625 		else if (strnicmp(arg1, "flexible", 8)==0)
  1534 				iMemModel=E_MM_Flexible;
  1626 			iMemModel=E_MM_Flexible;
  1535 			else {
  1627 		else
  1536 				Print(EError, "Unknown memory model specified\n");
  1628 			{
  1537 				success = EFalse;
  1629 			Print(EError, "Unknown memory model specified\n");
  1538 			}
  1630 			success = EFalse;
  1539 			if (IsValidNumber(arg2)) { 
  1631 			}
  1540 				Val(iChunkSize,arg2); 
  1632 		if (strlen(arg2))
  1541 			}
  1633 			{
  1542 			if (iMemModel!=E_MM_Direct && IsValidNumber(arg3)) { 
  1634 			#ifdef __TOOLS2__
  1543 				 Val(iPageSize,arg3); 
  1635 			istringstream arg2s(arg2);
  1544 			}
  1636 			#else
  1545 			else if (iMemModel==E_MM_Direct)
  1637 			istrstream arg2s(arg2,strlen(arg2));
  1546 				iPageSize=iChunkSize;
  1638 			#endif
  1547 			if (iMemModel!=E_MM_Direct && IsValidNumber(arg4)) { 
  1639 
  1548 				Val(iVirtualAllocSize,arg4); 
  1640 #if defined(__MSVCDOTNET__) || defined(__TOOLS2__)
  1549 			}
  1641 			arg2s >> setbase(0);
  1550 			else
  1642 #endif //__MSVCDOTNET__
  1551 				iVirtualAllocSize = iPageSize;
  1643 
  1552 
  1644 			arg2s >> iChunkSize;
  1553 			break;
  1645 			}
       
  1646 		if (iMemModel!=E_MM_Direct && strlen(arg3))
       
  1647 			{
       
  1648 				#ifdef __TOOLS2__
       
  1649 			istringstream arg3s(arg3);
       
  1650 			#else
       
  1651 			istrstream arg3s(arg3,strlen(arg3));
       
  1652 			#endif
       
  1653 
       
  1654 #if defined(__MSVCDOTNET__) || defined(__TOOLS2__)
       
  1655 			arg3s >> setbase(0);
       
  1656 #endif //__MSVCDOTNET__
       
  1657 
       
  1658 			arg3s >> iPageSize;
       
  1659 			}
       
  1660 		else if (iMemModel==E_MM_Direct)
       
  1661 			iPageSize=iChunkSize;
       
  1662 		if (iMemModel!=E_MM_Direct && strlen(arg4))
       
  1663 			{
       
  1664 			#ifdef __TOOLS2__
       
  1665 			istringstream arg4s(arg4);
       
  1666 			#else
       
  1667 			istrstream arg4s(arg4,strlen(arg4));
       
  1668 			#endif
       
  1669 
       
  1670 #if defined(__MSVCDOTNET__) || defined(__TOOLS2__)
       
  1671 			arg4s >> setbase(0);
       
  1672 #endif //__MSVCDOTNET__
       
  1673 
       
  1674 			arg4s >> iVirtualAllocSize;
       
  1675 			}
       
  1676 		else
       
  1677 			iVirtualAllocSize = iPageSize;
       
  1678 		
       
  1679 		break;
       
  1680 		}
  1554 		}
  1681 	case EKeywordNoWrapper:
  1555 	case EKeywordNoWrapper:
  1682 		if (gHeaderType<0)
  1556 		if (gHeaderType<0)
  1683 			gHeaderType=0;
  1557 			gHeaderType=0;
  1684 		break;
  1558 		break;
  1703 		if(gPlatSecDiagnostics)
  1577 		if(gPlatSecDiagnostics)
  1704 			iKernelConfigFlags |= EKernelConfigPlatSecDiagnostics;
  1578 			iKernelConfigFlags |= EKernelConfigPlatSecDiagnostics;
  1705 		else
  1579 		else
  1706 			iKernelConfigFlags &= ~EKernelConfigPlatSecDiagnostics;
  1580 			iKernelConfigFlags &= ~EKernelConfigPlatSecDiagnostics;
  1707 		break;
  1581 		break;
  1708 	case EKeywordPlatSecProcessIsolation:
  1582 	case EKeywordPlatSecProcessIsolation: {
  1709 		{
  1583 			TInt processIsolation;
  1710 		TInt processIsolation;
  1584 			ParseBoolArg(processIsolation,iReader.Word(1));
  1711 		ParseBoolArg(processIsolation,iReader.Word(1));
  1585 			if(processIsolation)
  1712 		if(processIsolation)
  1586 				iKernelConfigFlags |= EKernelConfigPlatSecProcessIsolation;
  1713 			iKernelConfigFlags |= EKernelConfigPlatSecProcessIsolation;
  1587 			else
  1714 		else
  1588 				iKernelConfigFlags &= ~EKernelConfigPlatSecProcessIsolation;
  1715 			iKernelConfigFlags &= ~EKernelConfigPlatSecProcessIsolation;
  1589 			break;
  1716 		break;
  1590 		}
  1717 		}
  1591 	case EKeywordPlatSecEnforceSysBin: {
  1718 	case EKeywordPlatSecEnforceSysBin:
  1592 			ParseBoolArg(gPlatSecEnforceSysBin,iReader.Word(1));
  1719 		{
  1593 			if(gPlatSecEnforceSysBin)
  1720 		ParseBoolArg(gPlatSecEnforceSysBin,iReader.Word(1));
  1594 				iKernelConfigFlags |= EKernelConfigPlatSecEnforceSysBin;
  1721 		if(gPlatSecEnforceSysBin)
  1595 			else
  1722 			iKernelConfigFlags |= EKernelConfigPlatSecEnforceSysBin;
  1596 				iKernelConfigFlags &= ~EKernelConfigPlatSecEnforceSysBin;
  1723 		else
  1597 			break;
  1724 			iKernelConfigFlags &= ~EKernelConfigPlatSecEnforceSysBin;
       
  1725 		break;
       
  1726 		}
  1598 		}
  1727 	case EKeywordPlatSecDisabledCaps:
  1599 	case EKeywordPlatSecDisabledCaps:
  1728 		if(iPlatSecDisabledCapsParsed)
  1600 		if(iPlatSecDisabledCapsParsed)
  1729 			Print(EWarning, "PlatSecDisabledCaps redefined - previous values lost\n");
  1601 			Print(EWarning, "PlatSecDisabledCaps redefined - previous values lost\n"); {
  1730 		{
  1602 			ParseCapabilitiesArg(iPlatSecDisabledCaps, iReader.Word(1));
  1731 		ParseCapabilitiesArg(iPlatSecDisabledCaps, iReader.Word(1));
  1603 			gPlatSecDisabledCaps = iPlatSecDisabledCaps;
  1732 		gPlatSecDisabledCaps = iPlatSecDisabledCaps;
  1604 			iPlatSecDisabledCapsParsed=ETrue;
  1733 		iPlatSecDisabledCapsParsed=ETrue;
  1605 		}
  1734 		}
  1606 		break;
  1735 		break;
  1607 	case EKeywordPagingPolicy: {
  1736 	case EKeywordPagingPolicy:
  1608 			if(iPagingPolicyParsed)
  1737 		{
  1609 				Print(EWarning, "PagingPolicy redefined - previous PagingPolicy values lost\n");
  1738 		if(iPagingPolicyParsed)
  1610 			if(iCodePagingPolicyParsed)
  1739 			Print(EWarning, "PagingPolicy redefined - previous PagingPolicy values lost\n");
  1611 				Print(EWarning, "PagingPolicy defined - previous CodePagingPolicy values lost\n");
  1740 		if(iDataPagingPolicyParsed)
  1612 			iPagingPolicyParsed = true;
  1741 			Print(EWarning, "PagingPolicy defined - previous DataPagingPolicy values lost\n");
  1613 			iKernelConfigFlags &= ~(EKernelConfigCodePagingPolicyMask);
  1742 		if(iCodePagingPolicyParsed)
  1614 			TInt policy = ParsePagingPolicy(iReader.Word(1));
  1743 			Print(EWarning, "PagingPolicy defined - previous DataPagingPolicy values lost\n");
  1615 			if(policy<0) {
  1744 		iPagingPolicyParsed = true;
  1616 				Print(EError,"Unrecognized option for PAGINGPOLICY keyword\n");
  1745 		iKernelConfigFlags &= ~(EKernelConfigCodePagingPolicyMask|EKernelConfigDataPagingPolicyMask);
  1617 				success = false;
  1746 		TInt policy = ParsePagingPolicy(iReader.Word(1));
  1618 			}
  1747 		if(policy<0)
  1619 			else 	{
  1748 			{
       
  1749 			Print(EError,"Unrecognised option for PAGINGPOLICY keyword\n");
       
  1750 			success = false;
       
  1751 			}
       
  1752 		else 	{
       
  1753 #ifndef SYMBIAN_WRITABLE_DATA_PAGING
  1620 #ifndef SYMBIAN_WRITABLE_DATA_PAGING
  1754 			if ((policy != EKernelConfigPagingPolicyNoPaging) && (iMemModel == E_MM_Flexible))
  1621 				if ((policy != EKernelConfigPagingPolicyNoPaging) && (iMemModel == E_MM_Flexible))
  1755 				Print(EWarning, "SYMBIAN_WRITABLE_DATA_PAPING is not defined. Writable data paging is not warranted on this version of Symbian.");
  1622 					Print(EWarning, "SYMBIAN_WRITABLE_DATA_PAPING is not defined. Writable data paging is not warranted on this version of Symbian.");
  1756 #endif
  1623 #endif
  1757 			iKernelConfigFlags |= policy << EKernelConfigCodePagingPolicyShift;
  1624 				iKernelConfigFlags |= policy << EKernelConfigCodePagingPolicyShift;
  1758 			iKernelConfigFlags |= policy << EKernelConfigDataPagingPolicyShift;
  1625 				if((policy==EKernelConfigPagingPolicyNoPaging) || (policy==EKernelConfigPagingPolicyDefaultUnpaged))
  1759 			}
  1626 					iKernelConfigFlags |= policy << EKernelConfigDataPagingPolicyShift;
  1760 		}
  1627 			}
  1761 		break;
  1628 		}
  1762 	case EKeywordCodePagingPolicy:
  1629 		break;
  1763 		{
  1630 	case EKeywordCodePagingPolicy: {
  1764 		if(iCodePagingPolicyParsed)
  1631 			if(iCodePagingPolicyParsed)
  1765 			Print(EWarning, "CodePagingPolicy redefined - previous CodePagingPolicy values lost\n");
  1632 				Print(EWarning, "CodePagingPolicy redefined - previous CodePagingPolicy values lost\n");
  1766 		if(iPagingPolicyParsed)
  1633 			if(iPagingPolicyParsed)
  1767 			Print(EWarning, "CodePagingPolicy defined - previous PagingPolicy values lost\n");
  1634 				Print(EWarning, "CodePagingPolicy defined - previous PagingPolicy values lost\n");
  1768 		iCodePagingPolicyParsed = true;
  1635 			iCodePagingPolicyParsed = true;
  1769 		iKernelConfigFlags &= ~EKernelConfigCodePagingPolicyMask;
  1636 			iKernelConfigFlags &= ~EKernelConfigCodePagingPolicyMask;
  1770 		TInt policy = ParsePagingPolicy(iReader.Word(1));
  1637 			TInt policy = ParsePagingPolicy(iReader.Word(1));
  1771 		if(policy<0)
  1638 			if(policy<0) {
  1772 			{
  1639 				Print(EError,"Unrecognised option for CODEPAGINGPOLICY keyword\n");
  1773 			Print(EError,"Unrecognised option for CODEPAGINGPOLICY keyword\n");
  1640 				success = false;
  1774 			success = false;
  1641 			}
  1775 			}
  1642 			else
  1776 		else
  1643 				iKernelConfigFlags |= policy << EKernelConfigCodePagingPolicyShift;
  1777 			iKernelConfigFlags |= policy << EKernelConfigCodePagingPolicyShift;
  1644 		}
  1778 		}
  1645 		break;
  1779 		break;
  1646 	case EKeywordDataPagingPolicy: {
  1780 	case EKeywordDataPagingPolicy:
  1647 			if(iDataPagingPolicyParsed)
  1781 		{
  1648 				Print(EWarning, "DataPagingPolicy redefined - previous DataPagingPolicy values lost\n");
  1782 		if(iDataPagingPolicyParsed)
  1649 			if(iPagingPolicyParsed)
  1783 			Print(EWarning, "DataPagingPolicy redefined - previous DataPagingPolicy values lost\n");
  1650 				Print(EWarning, "DataPagingPolicy defined - previous PagingPolicy values lost\n");
  1784 		if(iPagingPolicyParsed)
  1651 			iDataPagingPolicyParsed = true;
  1785 			Print(EWarning, "DataPagingPolicy defined - previous PagingPolicy values lost\n");
  1652 			iKernelConfigFlags &= ~EKernelConfigDataPagingPolicyMask;
  1786 		iDataPagingPolicyParsed = true;
  1653 			TInt policy = ParsePagingPolicy(iReader.Word(1));
  1787 		iKernelConfigFlags &= ~EKernelConfigDataPagingPolicyMask;
  1654 			if(policy<0) {
  1788 		TInt policy = ParsePagingPolicy(iReader.Word(1));
  1655 				Print(EError,"Unrecognized option for DATAPAGINGPOLICY keyword\n");
  1789 		if(policy<0)
  1656 				success = false;
  1790 			{
  1657 			}
  1791 			Print(EError,"Unrecognised option for DATAPAGINGPOLICY keyword\n");
  1658 			else
  1792 			success = false;
       
  1793 			}
       
  1794 		else
       
  1795 #ifndef SYMBIAN_WRITABLE_DATA_PAGING
  1659 #ifndef SYMBIAN_WRITABLE_DATA_PAGING
  1796 			if ((policy != EKernelConfigPagingPolicyNoPaging) && (iMemModel == E_MM_Flexible))
  1660 				if ((policy != EKernelConfigPagingPolicyNoPaging) && (iMemModel == E_MM_Flexible))
  1797 				Print(EWarning, "SYMBIAN_WRITABLE_DATA_PAPING is not defined. Writable data paging is not warranted on this version of Symbian.");
  1661 					Print(EWarning, "SYMBIAN_WRITABLE_DATA_PAPING is not defined. Writable data paging is not warranted on this version of Symbian.");
  1798 #endif
  1662 #endif
  1799 			iKernelConfigFlags |= policy << EKernelConfigDataPagingPolicyShift;
  1663 			iKernelConfigFlags |= policy << EKernelConfigDataPagingPolicyShift;
  1800 		}
  1664 		}
  1801 		break;
  1665 		break;
  1802 	case EKeywordPagingOverride:
  1666 	case EKeywordPagingOverride: {
       
  1667 			if(iPagingOverrideParsed)
       
  1668 				Print(EWarning, "PagingOverride redefined - previous PagingOverride values lost\n");
       
  1669 			if(iCodePagingOverrideParsed)
       
  1670 				Print(EWarning, "PagingOverride defined - previous CodePagingOverride values lost\n");
       
  1671 			iPagingOverrideParsed = true;
       
  1672 			TInt policy = ParsePagingPolicy(iReader.Word(1));
       
  1673 			if(policy<0) {
       
  1674 				Print(EError,"Unrecognized option for PAGINGOVERRIDE keyword\n");
       
  1675 				success = false;
       
  1676 			}
       
  1677 			else {
       
  1678 				gCodePagingOverride = policy;
       
  1679 				if((policy==EKernelConfigPagingPolicyNoPaging) || (policy==EKernelConfigPagingPolicyDefaultUnpaged))
       
  1680 					gDataPagingOverride = policy;
       
  1681 			}
       
  1682 		}
       
  1683 		break;
       
  1684 	case EKeywordCodePagingOverride: {
       
  1685 			if(iCodePagingOverrideParsed)
       
  1686 				Print(EWarning, "CodePagingOverride redefined - previous CodePagingOverride values lost\n");
       
  1687 			if(iPagingOverrideParsed)
       
  1688 				Print(EWarning, "CodePagingOverride defined - previous PagingOverride values lost\n");
       
  1689 			iCodePagingOverrideParsed = true;
       
  1690 			TInt policy = ParsePagingPolicy(iReader.Word(1));
       
  1691 			if(policy<0) {
       
  1692 				Print(EError,"Unrecognised option for CODEPAGINGOVERRIDE keyword\n");
       
  1693 				success = false;
       
  1694 			}
       
  1695 			else
       
  1696 				gCodePagingOverride = policy;
       
  1697 		}
       
  1698 		break;
       
  1699 	case EKeywordDataPagingOverride: 
  1803 		{
  1700 		{
  1804 		if(iPagingOverrideParsed)
  1701 			if(iDataPagingOverrideParsed)
  1805 			Print(EWarning, "PagingOverride redefined - previous PagingOverride values lost\n");
  1702 				Print(EWarning, "DataPagingOverride redefined - previous DataPagingOverride values lost\n");
  1806 		if(iCodePagingOverrideParsed)
  1703 			if(iPagingOverrideParsed)
  1807 			Print(EWarning, "PagingOverride defined - previous CodePagingOverride valus lost\n");
  1704 				Print(EWarning, "DataPagingOverride defined - previous PagingOverride values lost\n");
  1808 		if(iDataPagingOverrideParsed)
  1705 			iDataPagingOverrideParsed = true;
  1809 			Print(EWarning, "PagingOverride defined - previous DataPagingOverride values lostn");
  1706 			TInt policy = ParsePagingPolicy(iReader.Word(1));
  1810 		iPagingOverrideParsed = true;
  1707 			if(policy<0) {
  1811 		TInt policy = ParsePagingPolicy(iReader.Word(1));
  1708 				Print(EError,"Unrecognised option for DATAPAGINGOVERRIDE keyword\n");
  1812 		if(policy<0)
  1709 				success = false;
  1813 			{
  1710 			}
  1814 			Print(EError,"Unrecognised option for PAGINGOVERRIDE keyword\n");
  1711 			else
  1815 			success = false;
  1712 				gDataPagingOverride = policy;
  1816 			}
  1713 		}
  1817 		else
  1714 		break;
  1818 			{
  1715 	case EKeywordDemandPagingConfig: 
  1819 			gCodePagingOverride = policy;
       
  1820 			gDataPagingOverride = policy;
       
  1821 			}
       
  1822 		}
       
  1823 		break;
       
  1824 	case EKeywordCodePagingOverride:
       
  1825 		{
  1716 		{
  1826 		if(iCodePagingOverrideParsed)
  1717 			memset(&gDemandPagingConfig,0,sizeof(gDemandPagingConfig));
  1827 			Print(EWarning, "CodePagingOverride redefined - previous CodePagingOverride values lost\n");
  1718 			Val(gDemandPagingConfig.iMinPages,iReader.Word(1));
  1828 		if(iPagingOverrideParsed)
  1719 			const char* tmp = iReader.Word(2);
  1829 			Print(EWarning, "CodePagingOverride defined - previous PagingOverride values lost\n");
  1720 			if(*tmp) {
  1830 		iCodePagingOverrideParsed = true;
  1721 				Val(gDemandPagingConfig.iMaxPages,tmp);
  1831 		TInt policy = ParsePagingPolicy(iReader.Word(1));
  1722 				tmp = iReader.Word(3);
  1832 		if(policy<0)
  1723 				if(*tmp){
  1833 			{
  1724 					Val(gDemandPagingConfig.iYoungOldRatio,tmp);
  1834 			Print(EError,"Unrecognised option for CODEPAGINGOVERRIDE keyword\n");
  1725 					for(int i = 1 ; i <= 2 ; i++){
  1835 			success = false;
  1726 						tmp = iReader.Word(4 + i);
  1836 			}
  1727 						if(0 == *tmp) break ;
  1837 		else
  1728 							Val(gDemandPagingConfig.iSpare[i],tmp);
  1838 			gCodePagingOverride = policy;
       
  1839 		}
       
  1840 		break;
       
  1841 	case EKeywordDataPagingOverride:
       
  1842 		{
       
  1843 		if(iDataPagingOverrideParsed)
       
  1844 			Print(EWarning, "DataPagingOverride redefined - previous DataPagingOverride values lost\n");
       
  1845 		if(iPagingOverrideParsed)
       
  1846 			Print(EWarning, "DataPagingOverride defined - previous PagingOverride values lost\n");
       
  1847 		iDataPagingOverrideParsed = true;
       
  1848 		TInt policy = ParsePagingPolicy(iReader.Word(1));
       
  1849 		if(policy<0)
       
  1850 			{
       
  1851 			Print(EError,"Unrecognised option for DATAPAGINGOVERRIDE keyword\n");
       
  1852 			success = false;
       
  1853 			}
       
  1854 		else
       
  1855 			gDataPagingOverride = policy;
       
  1856 		}
       
  1857 		break;
       
  1858 	case EKeywordDemandPagingConfig:
       
  1859 		{
       
  1860 		memset(&gDemandPagingConfig,0,sizeof(gDemandPagingConfig));
       
  1861 		val >> gDemandPagingConfig.iMinPages;
       
  1862 		if(strlen(iReader.Word(2)))
       
  1863 			{
       
  1864 			#ifdef __TOOLS2__
       
  1865 			istringstream val(iReader.Word(2));
       
  1866 			#else
       
  1867 			istrstream val(iReader.Word(2),strlen(iReader.Word(2)));
       
  1868 		    #endif
       
  1869 			val >> gDemandPagingConfig.iMaxPages;
       
  1870 			if(strlen(iReader.Word(3)))
       
  1871 				{
       
  1872 				#ifdef __TOOLS2__
       
  1873 				istringstream val(iReader.Word(3));
       
  1874 				#else
       
  1875 				istrstream val(iReader.Word(3),strlen(iReader.Word(3)));
       
  1876 				#endif
       
  1877 				val >> gDemandPagingConfig.iYoungOldRatio;
       
  1878 				for(int i=0; i<=2; i++)
       
  1879 					{
       
  1880 					if(!strlen(iReader.Word(4+i)))
       
  1881 						break;
       
  1882 					#ifdef __TOOLS2__
       
  1883 					istringstream val(iReader.Word(4+i));
       
  1884 					#else
       
  1885 					istrstream val(iReader.Word(4+i),strlen(iReader.Word(4+i)));
       
  1886 					#endif
       
  1887 					val >> gDemandPagingConfig.iSpare[i];
       
  1888 					}
  1729 					}
  1889 				}
  1730 				}
  1890 			}
  1731 			} 
  1891 		if(gDemandPagingConfig.iMaxPages && gDemandPagingConfig.iMaxPages<gDemandPagingConfig.iMinPages)
  1732 			if(gDemandPagingConfig.iMaxPages && gDemandPagingConfig.iMaxPages<gDemandPagingConfig.iMinPages) {
  1892 			{
  1733 				Print(EError,"DemandPagingConfig maxPages must be >= minPages\n");
  1893 			Print(EError,"DemandPagingConfig maxPages must be >= minPages\n");
  1734 				success = EFalse;
  1894 			success = EFalse;
  1735 				break;
  1895 			break;
       
  1896 			}
  1736 			}
  1897 		}
  1737 		}
  1898 		break;
  1738 		break;
  1899 	case EKeywordPagedRom:
  1739 	case EKeywordPagedRom:
  1900 		gPagedRom = ETrue;
  1740 		gPagedRom = ETrue;
  1901 		break;
  1741 		break;
  1902 
  1742 
  1903 	case EKeywordTrace:
  1743 	case EKeywordTrace:
  1904 		val >> TraceMask;
  1744 		Val(TraceMask,iReader.Word(1));
  1905 		break;
  1745 		break;
  1906 
  1746 
  1907 	case EKeywordKernelTrace:
  1747 	case EKeywordKernelTrace: 	
  1908 		{
  1748 		iTraceMask[0] = 0;
  1909 		TInt i;
  1749 		for(int i = 0 ; i < KNumTraceMaskWords ; i++) {
  1910 		val >> iTraceMask[0];
  1750 			const char* tmp = iReader.Word(i+1);
  1911 		i=1;
  1751 			if(0 == *tmp) break ;
  1912 		while(strlen(iReader.Word(i+1)) && i<KNumTraceMaskWords)
  1752 			Val(iTraceMask[i],tmp);
  1913 			{
  1753 		}	 
  1914 			#ifdef __TOOLS2__
  1754 		break;
  1915 			istringstream val(iReader.Word(i+1));
  1755 
  1916 			#else
  1756 	case EKeywordBTrace: 
  1917 			istrstream val(iReader.Word(i+1),strlen(iReader.Word(i+1)));
  1757 		iInitialBTraceFilter[0] = 0 ;
  1918 			#endif
  1758 		for(TUint i = 0 ; i < sizeof(iInitialBTraceFilter) / sizeof(iInitialBTraceFilter[0]); i++) {
  1919 			#if defined(__MSVCDOTNET__) || defined (__TOOLS2__)
  1759 			const char* tmp = iReader.Word(i+1);
  1920  				val >> setbase(0);
  1760 			if(0 == *tmp) break ;
  1921 			#endif
  1761 			Val(iInitialBTraceFilter[i],tmp);
  1922 			val >> iTraceMask[i];
       
  1923 			++i;
       
  1924 			}
       
  1925 		}
       
  1926 		break;
       
  1927 
       
  1928 	case EKeywordBTrace:
       
  1929 		{
       
  1930 		TUint i; 
       
  1931 		val >> iInitialBTraceFilter[0];
       
  1932 		i=1;
       
  1933 		while(strlen(iReader.Word(i+1)) && i<sizeof(iInitialBTraceFilter)/sizeof(TUint32))
       
  1934 			{
       
  1935 			#ifdef __TOOLS2__
       
  1936 			istringstream val(iReader.Word(i+1));
       
  1937 			#else
       
  1938 			istrstream val(iReader.Word(i+1),strlen(iReader.Word(i+1)));
       
  1939 			#endif
       
  1940 			#if defined(__MSVCDOTNET__) || defined (__TOOLS2__)
       
  1941  				val >> setbase(0);
       
  1942 			#endif
       
  1943 			val >> iInitialBTraceFilter[i];
       
  1944 			++i;
       
  1945 			}
       
  1946 		}
  1762 		}
  1947 		break;
  1763 		break;
  1948 
  1764 
  1949 	case EKeywordBTraceMode:
  1765 	case EKeywordBTraceMode:
  1950 		val >> iInitialBTraceMode;
  1766 		Val(iInitialBTraceMode,iReader.Word(1));
  1951 		break;
  1767 		break;
  1952 
  1768 
  1953 	case EKeywordBTraceBuffer:
  1769 	case EKeywordBTraceBuffer:
  1954 		val >> iInitialBTraceBuffer;
  1770 		Val(iInitialBTraceBuffer,iReader.Word(1));
  1955 		break;
  1771 		break;
  1956 
  1772 
  1957 	case EKeywordDebugPort:
  1773 	case EKeywordDebugPort:
  1958 		if (iDebugPortParsed)
  1774 		if (iDebugPortParsed)
  1959 			Print(EWarning, "DEBUGPORT redefined - previous value lost\n");
  1775 			Print(EWarning, "DEBUGPORT redefined - previous value lost\n");
  1960 		val >> iDebugPort;
  1776 		Val(iDebugPort,iReader.Word(1));
  1961 		iDebugPortParsed = ETrue;
  1777 		iDebugPortParsed = ETrue;
  1962 		break;
  1778 		break;
  1963 
  1779 
  1964 	case EKeywordCompress:
  1780 	case EKeywordCompress:
  1965 		gEnableCompress=ETrue; // Set ROM Compression on.
  1781 		gEnableCompress=ETrue; // Set ROM Compression on.
  1966 		break;
  1782 		break;
  1967 
  1783 
  1968 	case EKeywordCollapse:
  1784 	case EKeywordCollapse:
  1969 		if (strnicmp(iReader.Word(1), "arm", 3)!=0 || strnicmp(iReader.Word(2), "gcc", 3)!=0)
  1785 		if (strnicmp(iReader.Word(1), "arm", 3)!=0 || strnicmp(iReader.Word(2), "gcc", 3)!=0) {
  1970 			{
       
  1971 			Print(EWarning, "COLLAPSE only supported for ARM and GCC - keyword ignored\n");
  1786 			Print(EWarning, "COLLAPSE only supported for ARM and GCC - keyword ignored\n");
  1972 			}
  1787 		}
  1973 		else
  1788 		else {
  1974 			{
  1789 
  1975 			TInt cm;
  1790 			TUint32 cm = 0;
  1976 			#ifdef __TOOLS2__
  1791 			Val(cm,iReader.Word(3)); 
  1977 			istringstream cmval(iReader.Word(3));
  1792 			if ((cm & 0x80000000L) != 0 || cm > ECollapseAllChainBranches) {
  1978 			#else
       
  1979 			istrstream cmval(iReader.Word(3),strlen(iReader.Word(3)));
       
  1980 			#endif
       
  1981 
       
  1982 #if defined(__MSVCDOTNET__) || defined(__TOOLS2__)
       
  1983 			cmval >> setbase(0);
       
  1984 #endif //__MSVCDOTNET__
       
  1985 
       
  1986 			cmval>>cm;
       
  1987 			if (cm<0 || cm>ECollapseAllChainBranches)
       
  1988 				{
       
  1989 				Print(EWarning, "COLLAPSE mode unrecognised - keyword ignored\n");
  1793 				Print(EWarning, "COLLAPSE mode unrecognised - keyword ignored\n");
  1990 				}
  1794 			}
  1991 			else
  1795 			else
  1992 				iCollapseMode=cm;
  1796 				iCollapseMode=cm;
  1993 			}
  1797 		}
  1994 		break;
  1798 		break;
  1995 
  1799 
  1996 	case EKeywordPrimary:
  1800 	case EKeywordPrimary:
  1997 		iNumberOfPrimaries++;
  1801 		iNumberOfPrimaries++;
  1998 		break;
  1802 		break;
  1999 	case EKeywordVariant:
  1803 	case EKeywordVariant:
  2000 		hardwareVariant=ParseVariant();
  1804 		hardwareVariant=ParseVariant();
  2001 		if (THardwareVariant(hardwareVariant).IsVariant())
  1805 		if (THardwareVariant(hardwareVariant).IsVariant()) {
  2002 			{
       
  2003 			iNumberOfVariants++;
  1806 			iNumberOfVariants++;
  2004 			TUint layer=THardwareVariant(hardwareVariant).Layer();
  1807 			TUint layer=THardwareVariant(hardwareVariant).Layer();
  2005 			TUint vmask=THardwareVariant(hardwareVariant).VMask();
  1808 			TUint vmask=THardwareVariant(hardwareVariant).VMask();
  2006 			iAllVariantsMask[layer] |= vmask;
  1809 			iAllVariantsMask[layer] |= vmask;
  2007 			}
  1810 		}
  2008 		else
  1811 		else {
  2009 			{
       
  2010 			Print(EError,"Variant DLLs must belong to variant layer - line %d\n", iReader.CurrentLine());
  1812 			Print(EError,"Variant DLLs must belong to variant layer - line %d\n", iReader.CurrentLine());
  2011 			break;
  1813 			break;
  2012 			}
  1814 		}
  2013 
  1815 
  2014 		break;
  1816 		break;
  2015 	case EKeywordExtension:
  1817 	case EKeywordExtension:
  2016 		iNumberOfExtensions++;
  1818 		iNumberOfExtensions++;
  2017 		break;
  1819 		break;
  2029 		break;
  1831 		break;
  2030 
  1832 
  2031 	case EKeywordExecutableCompressionMethodNone:
  1833 	case EKeywordExecutableCompressionMethodNone:
  2032 		gCompressionMethod = 0;
  1834 		gCompressionMethod = 0;
  2033 		break;
  1835 		break;
  2034 		
  1836 
  2035 	case EKeywordExecutableCompressionMethodInflate:
  1837 	case EKeywordExecutableCompressionMethodInflate:
  2036 		gCompressionMethod = KUidCompressionDeflate;
  1838 		gCompressionMethod = KUidCompressionDeflate;
  2037 		break;
  1839 		break;
  2038 		
  1840 
  2039 	case EKeywordExecutableCompressionMethodBytePair:
  1841 	case EKeywordExecutableCompressionMethodBytePair:
  2040 		gCompressionMethod = KUidCompressionBytePair;
  1842 		gCompressionMethod = KUidCompressionBytePair;
  2041 		break;
  1843 		break;
  2042 		
  1844 
  2043 	case EKeywordKernelConfig:
  1845 	case EKeywordKernelConfig: 
  2044 		{
  1846 		{
  2045 		TInt bit, setTo;
  1847 			TUint32 bit = (TUint32)-1 ;
  2046 		val >> bit;
  1848 			Val(bit,iReader.Word(1)) ; 
  2047 		if(bit<0 || bit>31)
  1849 			TInt setTo = 0;
  2048 			{
  1850 			 
  2049 			Print(EError,"KernelConfig bit must be between 0 and 31\n");
  1851 			if(bit > 31) {
  2050 			success = EFalse;
  1852 				Print(EError,"KernelConfig bit must be between 0 and 31\n");
  2051 			break;
  1853 				success = EFalse;
  2052 			}
  1854 				break;
  2053 		if(ParseBoolArg(setTo,iReader.Word(2))!=KErrNone)
  1855 			}
  2054 			{
  1856 			if(ParseBoolArg(setTo,iReader.Word(2))!=KErrNone) {
  2055 			success = EFalse;
  1857 				success = EFalse;
  2056 			break;
  1858 				break;
  2057 			}
  1859 			}
  2058 		if(setTo)
  1860 			if(setTo)
  2059 			iKernelConfigFlags |= 1<<bit;
  1861 				iKernelConfigFlags |= 1<<bit;
  2060 		else
  1862 			else
  2061 			iKernelConfigFlags &= ~(1<<bit);
  1863 				iKernelConfigFlags &= ~(1<<bit);
  2062 		break;
  1864 			break;
  2063 		}
  1865 		}
  2064 		
  1866 
  2065 	case EKeywordMaxUnpagedMemSize:
  1867 	case EKeywordMaxUnpagedMemSize: 
  2066 		{
  1868 	{	
  2067 		TInt unpagedSize = -1;
  1869 		TUint32 unpagedSize = (TUint32)-1;
  2068 		val >> unpagedSize;
  1870 		Val(unpagedSize,iReader.Word(1)); 
  2069 			
  1871 		if (unpagedSize > 0x7FFFFFFF) {
  2070 		if (!val || unpagedSize < 0)
       
  2071 			{
       
  2072 			Print(EWarning, "Invalid value of MaxUnpagedSize (0 to 0x7FFFFFFF) - value ignored\n");
  1872 			Print(EWarning, "Invalid value of MaxUnpagedSize (0 to 0x7FFFFFFF) - value ignored\n");
  2073 			break;
  1873 			break;
  2074 			}
  1874 		}
  2075 			
  1875 
  2076 		iMaxUnpagedMemSize = unpagedSize;
  1876 		iMaxUnpagedMemSize = unpagedSize;
  2077 		
  1877 
  2078 		if(iUpdatedMaxUnpagedMemSize)
  1878 		if(iUpdatedMaxUnpagedMemSize) {
  2079 			{
       
  2080 			Print(EWarning, "MaxUnpagedSize redefined - previous values lost\n");
  1879 			Print(EWarning, "MaxUnpagedSize redefined - previous values lost\n");
  2081 			}
  1880 		}
  2082 		else
  1881 		else {
  2083 			{
       
  2084 			iUpdatedMaxUnpagedMemSize = ETrue;
  1882 			iUpdatedMaxUnpagedMemSize = ETrue;
  2085 			}
  1883 		}
  2086 		
  1884 
  2087 		break;
  1885 		break;
  2088 		}
  1886 	}
  2089 
  1887 
  2090 	default:
  1888 	default:
  2091 		// unexpected keyword iReader.Word(0)
  1889 		// unexpected keyword iReader.Word(0)
  2092 		break;
  1890 		break;
  2093 		}
  1891 	}
  2094 
  1892 
  2095 	return success;
  1893 	return success;
  2096 	}
  1894 }
  2097 
  1895 
  2098 TBool CObeyFile::GotKeyVariables()
       
  2099 //
  1896 //
  2100 // Checks that the obeyfile has supplied enough variables to continue
  1897 // Checks that the obeyfile has supplied enough variables to continue
  2101 //
  1898 // 
  2102    	{
  1899 TBool CObeyFile::GotKeyVariables() {
  2103 
  1900 
  2104 	TBool retVal=ETrue;
  1901 	TBool retVal=ETrue;
  2105 
  1902 
  2106 	// Mandatory keywords
  1903 	// Mandatory keywords
  2107 
  1904 
  2108 	if (iRomFileName==0)
  1905 	if (iRomFileName==0) {
  2109 		{
       
  2110 		Print(EAlways,"The name of the ROM has not been supplied.\n");
  1906 		Print(EAlways,"The name of the ROM has not been supplied.\n");
  2111 		Print(EAlways,"Use the keyword \"romname\".\n");
  1907 		Print(EAlways,"Use the keyword \"romname\".\n");
  2112 		retVal = EFalse;
  1908 		retVal = EFalse;
  2113 		}
  1909 	}
  2114 	if (iBootFileName==0)
  1910 	if (iBootFileName==0) {
  2115 		{
       
  2116 		Print(EAlways,"The name of the bootstrap binary has not been supplied.\n");
  1911 		Print(EAlways,"The name of the bootstrap binary has not been supplied.\n");
  2117 		Print(EAlways,"Use the keyword \"bootbinary\".\n");
  1912 		Print(EAlways,"Use the keyword \"bootbinary\".\n");
  2118 		retVal = EFalse;
  1913 		retVal = EFalse;
  2119 		}
  1914 	}
  2120 	if (iRomLinearBase==0xFFFFFFFF)
  1915 	if (iRomLinearBase==0xFFFFFFFF) {
  2121 		{
       
  2122 		Print(EAlways,"The base linear address of the ROM has not been supplied.\n");
  1916 		Print(EAlways,"The base linear address of the ROM has not been supplied.\n");
  2123 		Print(EAlways,"Use the keyword \"romlinearbase\".\n");
  1917 		Print(EAlways,"Use the keyword \"romlinearbase\".\n");
  2124 		retVal = EFalse;
  1918 		retVal = EFalse;
  2125 		}
  1919 	}
  2126 	if (iRomSize==0)
  1920 	if (iRomSize==0) {
  2127 		{
       
  2128 		Print(EAlways,"The size of the ROM has not been supplied.\n");
  1921 		Print(EAlways,"The size of the ROM has not been supplied.\n");
  2129 		Print(EAlways,"Use the keyword \"romsize\".\n");
  1922 		Print(EAlways,"Use the keyword \"romsize\".\n");
  2130 		retVal = EFalse;
  1923 		retVal = EFalse;
  2131 		}
  1924 	}
  2132 	if (iKernDataRunAddress==0)
  1925 	if (iKernDataRunAddress==0) {
  2133 		{
       
  2134 		Print(EAlways,"The address for the kernel's data section has not been supplied.\n");
  1926 		Print(EAlways,"The address for the kernel's data section has not been supplied.\n");
  2135 		Print(EAlways,"Use the keyword \"kerneldataaddress\".\n");
  1927 		Print(EAlways,"Use the keyword \"kerneldataaddress\".\n");
  2136 		retVal = EFalse;
  1928 		retVal = EFalse;
  2137 		}
  1929 	}
  2138 
  1930 
  2139 	// Validation
  1931 	// Validation
  2140 	if (iNumberOfPrimaries>1 && iKernelModel==ESingleKernel)
  1932 	if (iNumberOfPrimaries>1 && iKernelModel==ESingleKernel) {
  2141 		{
       
  2142 		Print(EError,"More than one primary in single-kernel ROM\n");
  1933 		Print(EError,"More than one primary in single-kernel ROM\n");
  2143 		retVal = EFalse;
  1934 		retVal = EFalse;
  2144 		}
  1935 	}
  2145 	if (iNumberOfPrimaries==0)
  1936 	if (iNumberOfPrimaries==0) {
  2146 		{
       
  2147 		Print(EError,"No primary file specified\n");
  1937 		Print(EError,"No primary file specified\n");
  2148 		retVal = EFalse;
  1938 		retVal = EFalse;
  2149 		}
  1939 	}
  2150 	if (iNumberOfVariants==0)
  1940 	if (iNumberOfVariants==0) {
  2151 		{
       
  2152 		Print(EError,"No variants specified\n");
  1941 		Print(EError,"No variants specified\n");
  2153 		retVal = EFalse;
  1942 		retVal = EFalse;
  2154 		}
  1943 	}
  2155 	if(iNumberOfHCRDataFiles > 1)
  1944 	if(iNumberOfHCRDataFiles > 1) {
  2156 		{
       
  2157 		Print(EError,"More than one hcr data files in ROM.\n");
  1945 		Print(EError,"More than one hcr data files in ROM.\n");
  2158 		retVal = EFalse ;
  1946 		retVal = EFalse ;
  2159 		}
  1947 	}
  2160 	// Warn about enabling data paging on OS versions where's it's not officially supported
  1948 	// Warn about enabling data paging on OS versions where's it's not officially supported
  2161 #ifndef SYMBIAN_WRITABLE_DATA_PAGING
  1949 #ifndef SYMBIAN_WRITABLE_DATA_PAGING
  2162 	if (iMemModel == E_MM_Flexible &&
  1950 	if (iMemModel == E_MM_Flexible &&
  2163 		(iKernelConfigFlags & EKernelConfigDataPagingPolicyMask) != EKernelConfigDataPagingPolicyNoPaging)
  1951 		(iKernelConfigFlags & EKernelConfigDataPagingPolicyMask) != EKernelConfigDataPagingPolicyNoPaging) {
  2164 		{
       
  2165 		Print(EWarning, "Writable data paging is not warranted on this version of Symbian OS.");
  1952 		Print(EWarning, "Writable data paging is not warranted on this version of Symbian OS.");
  2166 		}
  1953 	}
  2167 #endif
  1954 #endif
  2168 	
  1955 
  2169 	// Apply defaults as necessary
  1956 	// Apply defaults as necessary
  2170 	TheRomLinearAddress=iRomLinearBase;
  1957 	TheRomLinearAddress=iRomLinearBase;
  2171 
  1958 
  2172 	if (iDataRunAddress==0)
  1959 	if (iDataRunAddress==0) {
  2173 		{
       
  2174 		iDataRunAddress=0x400000;
  1960 		iDataRunAddress=0x400000;
  2175 		Print(EWarning,"The address for a running ROM app's data section (keyword \"dataaddress\") has not been supplied.\n");
  1961 		Print(EWarning,"The address for a running ROM app's data section (keyword \"dataaddress\") has not been supplied.\n");
  2176 		Print(EWarning,"Will use the default value of 0x%0x.\n", iDataRunAddress);
  1962 		Print(EWarning,"Will use the default value of 0x%0x.\n", iDataRunAddress);
  2177 		retVal = EFalse;
  1963 		retVal = EFalse;
  2178 		}
  1964 	}
  2179 	if (iRomAlign==0)
  1965 	if (iRomAlign==0) {
  2180 		{
       
  2181 		iRomAlign=0x1000;
  1966 		iRomAlign=0x1000;
  2182 		Print(EWarning,"The ROM section alignment (keyword \"romalign\") has not been supplied.\n");
  1967 		Print(EWarning,"The ROM section alignment (keyword \"romalign\") has not been supplied.\n");
  2183 		Print(EWarning,"Will use the default value of 0x%0x.\n", iRomAlign);
  1968 		Print(EWarning,"Will use the default value of 0x%0x.\n", iRomAlign);
  2184 		}
  1969 	}
  2185 	if (iRomAlign&0x3)
  1970 	if (iRomAlign&0x3) {
  2186 		{
       
  2187 		Print(EWarning, "Rounding rom alignment to multiple of 4.\n");
  1971 		Print(EWarning, "Rounding rom alignment to multiple of 4.\n");
  2188 		iRomAlign=(iRomAlign+0x3)&0xfffffffc;
  1972 		iRomAlign=(iRomAlign+0x3)&0xfffffffc;
  2189 		}
  1973 	}
  2190 	if (iKernHeapMin==0)
  1974 	if (iKernHeapMin==0) {
  2191 	 	{
  1975 		iKernHeapMin=0x10000;
  2192 	 	iKernHeapMin=0x10000;
       
  2193 		Print(EWarning,"The kernel heap min size (keyword \"kernelheapmin\") has not been supplied.\n");
  1976 		Print(EWarning,"The kernel heap min size (keyword \"kernelheapmin\") has not been supplied.\n");
  2194 		Print(EWarning,"Will use the default value of 0x%0x.\n", iKernHeapMin);
  1977 		Print(EWarning,"Will use the default value of 0x%0x.\n", iKernHeapMin);
  2195 		}
  1978 	}
  2196 	if (iKernHeapMax==0)
  1979 	if (iKernHeapMax==0) {
  2197 	 	{
  1980 		iKernHeapMax=0x100000;
  2198 	 	iKernHeapMax=0x100000;
       
  2199 		Print(EWarning,"The kernel heap max size (keyword \"kernelheapmax\") has not been supplied.\n");
  1981 		Print(EWarning,"The kernel heap max size (keyword \"kernelheapmax\") has not been supplied.\n");
  2200 		Print(EWarning,"Will use the default value of 0x%0x.\n", iKernHeapMax);
  1982 		Print(EWarning,"Will use the default value of 0x%0x.\n", iKernHeapMax);
  2201 		}
  1983 	}
  2202 
  1984 
  2203 	if (iTime==0)
  1985 	if (iTime==0) {
  2204 		{
       
  2205 		Print(ELog, "No timestamp specified. Using current time...\n");
  1986 		Print(ELog, "No timestamp specified. Using current time...\n");
  2206 		ObeyFileReader::TimeNow(iTime);
  1987 		ObeyFileReader::TimeNow(iTime);
  2207 		}
  1988 	}
  2208 
  1989 
  2209 	Print(ELog, "\nCreating Rom image %s\n", iRomFileName);
  1990 	Print(ELog, "\nCreating Rom image %s\n", iRomFileName);
  2210 	Print(ELog, "MemModel: %1d\nChunkSize: %08x\nPageSize: %08x\n", iMemModel, iChunkSize, iPageSize);
  1991 	Print(ELog, "MemModel: %1d\nChunkSize: %08x\nPageSize: %08x\n", iMemModel, iChunkSize, iPageSize);
  2211 	return retVal;
  1992 	return retVal;
  2212 	}
  1993 }
  2213 
  1994 
  2214 
  1995 
  2215 TText *CObeyFile::IsValidFilePath(TText *aPath)
       
  2216 //
  1996 //
  2217 // Check the path is valid
  1997 // Check the path is valid
  2218 //
  1998 // 
  2219 	{
  1999 const char* CObeyFile::IsValidFilePath(const char* aPath) {
  2220 	// skip leading "\"
  2000 	// skip leading "\"
  2221 	if (*aPath=='\\')
  2001 	if (*aPath == '/' || *aPath == '\\')
  2222 		aPath++;
  2002 		aPath++;
  2223 	if (*aPath==0)
  2003 	if (*aPath == 0)
  2224 		return NULL; // file ends in a backslash
  2004 		return NULL; // file ends in a backslash
  2225 
  2005 
  2226 	TText *p=aPath;
  2006 	const char *p = aPath;
  2227 	TInt len=0;
  2007 	TInt len=0;
  2228 	FOREVER
  2008 	while(*p) {			
  2229 		{
  2009 		if (*p == '/' || *p == '\\') {
  2230 		if (*p==0)
  2010 			if (len == 0)
  2231 			return (len ? aPath : NULL);
       
  2232 		if (*p=='\\')
       
  2233 			{
       
  2234 			if (len==0)
       
  2235 				return NULL;
  2011 				return NULL;
  2236 			len=0;
  2012 			len=0;
  2237 			}
  2013 		}
  2238 		len++;
  2014 		len++;
  2239 		p++;
  2015 		p++;
  2240 		}
  2016 	}
  2241 	}
  2017 	return (len ? aPath : NULL);
  2242 
  2018 }
  2243 TBool CObeyFile::GetNextBitOfFileName(TText **epocEndPtr)
  2019 
  2244 //
  2020 //
  2245 // Move the end pointer past the next directory separator, replacing it with 0
  2021 // Move the end pointer past the next directory separator, replacing it with 0
  2246 //
  2022 //
  2247 	{
  2023 TBool CObeyFile::GetNextBitOfFileName(char*& epocEndPtr) {
  2248 	while (**epocEndPtr != '\\') // until reach the directory separator
  2024 	while (*epocEndPtr != '/' && *epocEndPtr != '\\'){ // until reach the directory separator		
  2249 		{
  2025 		if (*epocEndPtr == 0) // if reach end of string, return TRUE, it's the filename
  2250 		if (**epocEndPtr==0) // if reach end of string, return TRUE, it's the filename
       
  2251 			return ETrue;
  2026 			return ETrue;
  2252 		(*epocEndPtr)++;
  2027 		epocEndPtr++;
  2253 		}
  2028 	}
  2254 	**epocEndPtr=0; // overwrite the directory separator with a 0
  2029 	*epocEndPtr = 0; // overwrite the directory separator with a 0
  2255 	(*epocEndPtr)++; // point past the 0 ready for the next one
  2030 	epocEndPtr++; // point past the 0 ready for the next one
  2256 	return EFalse;
  2031 	return EFalse;
  2257 	}
  2032 }
  2258 
  2033 
  2259 
  2034 
  2260 TBool CObeyFile::CheckHardwareVariants()
  2035 TBool CObeyFile::CheckHardwareVariants() {
  2261 	{
       
  2262 	iPrimaries=new TRomBuilderEntry*[iNumberOfPrimaries];
  2036 	iPrimaries=new TRomBuilderEntry*[iNumberOfPrimaries];
  2263 	iVariants=new TRomBuilderEntry*[iNumberOfVariants];
  2037 	iVariants=new TRomBuilderEntry*[iNumberOfVariants];
  2264 	THardwareVariant* primaryHwVariants=new THardwareVariant[iNumberOfPrimaries];
  2038 	THardwareVariant* primaryHwVariants=new THardwareVariant[iNumberOfPrimaries];
  2265 	TInt nVar=0;
  2039 	TInt nVar=0;
  2266 	TRomBuilderEntry* current=FirstFile();
  2040 	TRomBuilderEntry* current=FirstFile();
  2267 	THardwareVariant* variantHwVariants=new THardwareVariant[iNumberOfVariants];
  2041 	THardwareVariant* variantHwVariants=new THardwareVariant[iNumberOfVariants];
  2268 	while(current)
  2042 	while(current) {
  2269 		{
  2043 		if (current->Variant()) {
  2270 		if (current->Variant())
       
  2271 			{
       
  2272 			TInt i;
  2044 			TInt i;
  2273 			for(i=0; i<nVar; i++)
  2045 			for(i=0; i<nVar; i++) {
  2274 				{
  2046 				if (!current->iHardwareVariant.MutuallyExclusive(variantHwVariants[i])) {
  2275 				if (!current->iHardwareVariant.MutuallyExclusive(variantHwVariants[i]))
       
  2276 					{
       
  2277 					delete[] variantHwVariants;
  2047 					delete[] variantHwVariants;
  2278 					delete[] primaryHwVariants;
  2048 					delete[] primaryHwVariants;
  2279 					Print(EError,"Variants not mutually exclusive\n");
  2049 					Print(EError,"Variants not mutually exclusive\n");
  2280 					return EFalse;
  2050 					return EFalse;
  2281 					}
       
  2282 				}
  2051 				}
       
  2052 			}
  2283 			iVariants[nVar]=current;
  2053 			iVariants[nVar]=current;
  2284 			variantHwVariants[nVar++]=current->iHardwareVariant;
  2054 			variantHwVariants[nVar++]=current->iHardwareVariant;
  2285 			}
  2055 		}
  2286 		current=NextFile();
  2056 		current=NextFile();
  2287 		}
  2057 	}
  2288 	delete[] variantHwVariants;
  2058 	delete[] variantHwVariants;
  2289 	nVar=0;
  2059 	nVar=0;
  2290 	current=FirstFile();
  2060 	current=FirstFile();
  2291 	while(current)
  2061 	while(current) {
  2292 		{
       
  2293 		TInt i;
  2062 		TInt i;
  2294 		for (i=0; i<iNumberOfVariants; i++)
  2063 		for (i=0; i<iNumberOfVariants; i++) {
  2295 			{
       
  2296 			if (iVariants[i]->iHardwareVariant<=current->iHardwareVariant)
  2064 			if (iVariants[i]->iHardwareVariant<=current->iHardwareVariant)
  2297 				break;
  2065 				break;
  2298 			}
  2066 		}
  2299 		if (i==iNumberOfVariants)
  2067 		if (i==iNumberOfVariants) {
  2300 			{
       
  2301 			Print(EError,"File %s[%08x] does not correspond to any variant\n",
  2068 			Print(EError,"File %s[%08x] does not correspond to any variant\n",
  2302 									current->iName,TUint(current->iHardwareVariant));
  2069 				current->iName,TUint(current->iHardwareVariant));
  2303 			delete[] primaryHwVariants;
  2070 			delete[] primaryHwVariants;
  2304 			return EFalse;
  2071 			return EFalse;
  2305 			}
  2072 		}
  2306 		if (current->Primary())
  2073 		if (current->Primary()) {
  2307 			{
  2074 			for(i=0; i<nVar; i++) {
  2308 			for(i=0; i<nVar; i++)
  2075 				if (!current->iHardwareVariant.MutuallyExclusive(primaryHwVariants[i])) {
  2309 				{
       
  2310 				if (!current->iHardwareVariant.MutuallyExclusive(primaryHwVariants[i]))
       
  2311 					{
       
  2312 					delete[] primaryHwVariants;
  2076 					delete[] primaryHwVariants;
  2313 					Print(EError,"Primaries not mutually exclusive\n");
  2077 					Print(EError,"Primaries not mutually exclusive\n");
  2314 					return EFalse;
  2078 					return EFalse;
  2315 					}
       
  2316 				}
  2079 				}
       
  2080 			}
  2317 			iPrimaries[nVar]=current;
  2081 			iPrimaries[nVar]=current;
  2318 			primaryHwVariants[nVar++]=current->iHardwareVariant;
  2082 			primaryHwVariants[nVar++]=current->iHardwareVariant;
  2319 			}
  2083 		}
  2320 		current=NextFile();
  2084 		current=NextFile();
  2321 		}
  2085 	}
  2322 	delete[] primaryHwVariants;
  2086 	delete[] primaryHwVariants;
  2323 	if (iNumberOfExtensions)
  2087 	if (iNumberOfExtensions) {
  2324 		{
       
  2325 		nVar=0;
  2088 		nVar=0;
  2326 		iExtensions=new TRomBuilderEntry*[iNumberOfExtensions];
  2089 		iExtensions=new TRomBuilderEntry*[iNumberOfExtensions];
  2327 		TRomBuilderEntry* current=FirstFile();
  2090 		TRomBuilderEntry* current=FirstFile();
  2328 		while(current)
  2091 		while(current) {
  2329 			{
  2092 			if (current->Extension()) {
  2330 			if (current->Extension())
  2093 				if (current->iHardwareVariant.IsVariant()) {
  2331 				{
       
  2332 				if (current->iHardwareVariant.IsVariant())
       
  2333 					{
       
  2334 					TUint layer=current->iHardwareVariant.Layer();
  2094 					TUint layer=current->iHardwareVariant.Layer();
  2335 					TUint vmask=current->iHardwareVariant.VMask();
  2095 					TUint vmask=current->iHardwareVariant.VMask();
  2336 					if ((iAllVariantsMask[layer]&vmask)==0)
  2096 					if ((iAllVariantsMask[layer]&vmask)==0) {
  2337 						{
       
  2338 						Print(EError,"Variant-layer extension %s has no corresponding variant DLL\n",current->iName);
  2097 						Print(EError,"Variant-layer extension %s has no corresponding variant DLL\n",current->iName);
  2339 						return EFalse;
  2098 						return EFalse;
  2340 						}
       
  2341 					}
  2099 					}
       
  2100 				}
  2342 				iExtensions[nVar++]=current;
  2101 				iExtensions[nVar++]=current;
  2343 				}
  2102 			}
  2344 			current=NextFile();
  2103 			current=NextFile();
  2345 			}
  2104 		}
  2346 		}
  2105 	}
  2347 	if (iNumberOfDevices)
  2106 	if (iNumberOfDevices) {
  2348 		{
       
  2349 		nVar=0;
  2107 		nVar=0;
  2350 		iDevices=new TRomBuilderEntry*[iNumberOfDevices];
  2108 		iDevices=new TRomBuilderEntry*[iNumberOfDevices];
  2351 		TRomBuilderEntry* current=FirstFile();
  2109 		TRomBuilderEntry* current=FirstFile();
  2352 		while(current)
  2110 		while(current) {
  2353 			{
  2111 			if (current->Device()) {
  2354 			if (current->Device())
  2112 				if (current->iHardwareVariant.IsVariant()) {
  2355 				{
       
  2356 				if (current->iHardwareVariant.IsVariant())
       
  2357 					{
       
  2358 					TUint layer=current->iHardwareVariant.Layer();
  2113 					TUint layer=current->iHardwareVariant.Layer();
  2359 					TUint vmask=current->iHardwareVariant.VMask();
  2114 					TUint vmask=current->iHardwareVariant.VMask();
  2360 					if ((iAllVariantsMask[layer]&vmask)==0)
  2115 					if ((iAllVariantsMask[layer]&vmask)==0) {
  2361 						{
       
  2362 						Print(EError,"Variant-layer device %s has no corresponding variant DLL\n",current->iName);
  2116 						Print(EError,"Variant-layer device %s has no corresponding variant DLL\n",current->iName);
  2363 						return EFalse;
  2117 						return EFalse;
  2364 						}
       
  2365 					}
  2118 					}
       
  2119 				}
  2366 				iDevices[nVar++]=current;
  2120 				iDevices[nVar++]=current;
  2367 				}
  2121 			}
  2368 			current=NextFile();
  2122 			current=NextFile();
  2369 			}
  2123 		}
  2370 		}
  2124 	}
  2371 	NumberOfVariants=iNumberOfVariants;
  2125 	NumberOfVariants=iNumberOfVariants;
  2372 	return ETrue;
  2126 	return ETrue;
  2373 	}
  2127 }
  2374 
  2128 
  2375 
  2129 
  2376 TInt CObeyFile::ProcessExtensionRom(MRomImage*& aKernelRom)
  2130 TInt CObeyFile::ProcessExtensionRom(MRomImage*& aKernelRom) {
  2377 	{
       
  2378 	//
  2131 	//
  2379 	// First pass through the obey file to set up key variables
  2132 	// First pass through the obey file to set up key variables
  2380 	//
  2133 	//
  2381 
       
  2382 	iReader.Rewind();
  2134 	iReader.Rewind();
  2383 
  2135 
  2384 	enum EKeyword keyword;
  2136 	enum EKeyword keyword;
  2385 
  2137 
  2386 	// Deal with the "extensionrom" keyword, which should be first
  2138 	// Deal with the "extensionrom" keyword, which should be first
  2387 	
  2139 	// however, you may've found "time" before it.
  2388 	if (iReader.NextLine(1,keyword) != KErrNone)
  2140 	while(iReader.NextLine(1,keyword) != KErrEof) {
  2389 		return KErrEof;
  2141 		if(EKeywordExtensionRom == keyword)
  2390 	if (keyword != EKeywordExtensionRom)
  2142 			break ;		
  2391 		return Print(EError, "Unexpected keyword '%s' at start of extension rom - line %d\n",
  2143 	}
  2392 			iReader.Word(0), iReader.CurrentLine());
  2144 	if(EKeywordExtensionRom != keyword) return KErrEof;
  2393 	
  2145 
  2394 	iReader.CopyWord(1, iRomFileName);
  2146 	iRomFileName = iReader.DupWord(1);
  2395 	Print(ELog, "\n========================================================\n");
  2147 	Print(ELog, "\n========================================================\n");
  2396 	Print(ELog, "Extension ROM %s starting at line %d\n\n", iRomFileName, iReader.CurrentLine());
  2148 	Print(ELog, "Extension ROM %s starting at line %d\n\n", iRomFileName, iReader.CurrentLine());
  2397 
  2149 
  2398 	iReader.MarkNext();		// so that we rewind to the line after the extensionrom keyword
  2150 	iReader.MarkNext();		// so that we rewind to the line after the extensionrom keyword
  2399 
  2151 
  2400 	while (iReader.NextLine(1,keyword) != KErrEof)
  2152 	while (iReader.NextLine(1,keyword) != KErrEof) {
  2401 		{
       
  2402 		if (keyword == EKeywordExtensionRom)
  2153 		if (keyword == EKeywordExtensionRom)
  2403 			break;
  2154 			break;
  2404 		ProcessExtensionKeyword(keyword);
  2155 		ProcessExtensionKeyword(keyword);
  2405 		}
  2156 	}
  2406 
  2157 
  2407 	if (!GotExtensionVariables(aKernelRom))
  2158 	if (!GotExtensionVariables(aKernelRom))
  2408 		return KErrGeneral;
  2159 		return KErrGeneral;
  2409 
  2160 
  2410 	if (! CreateDefaultArea())
  2161 	if (! CreateDefaultArea())
  2421 	iLastExecutable = 0;
  2172 	iLastExecutable = 0;
  2422 	iRootDirectory = aKernelRom->CopyDirectory(iLastExecutable);
  2173 	iRootDirectory = aKernelRom->CopyDirectory(iLastExecutable);
  2423 
  2174 
  2424 
  2175 
  2425 	TInt align=0;
  2176 	TInt align=0;
  2426 	while (iReader.NextLine(2,keyword)!=KErrEof)
  2177 	while (iReader.NextLine(2,keyword)!=KErrEof) {
  2427 		{
       
  2428 		if (keyword == EKeywordExtensionRom)
  2178 		if (keyword == EKeywordExtensionRom)
  2429 			break;
  2179 			break;
  2430 
  2180 
  2431 		switch (keyword)
  2181 		switch (keyword) {
  2432 			{
       
  2433 		case EKeywordSection:
  2182 		case EKeywordSection:
  2434 		case EKeywordArea:
  2183 		case EKeywordArea:
  2435 		case EKeywordPrimary:
  2184 		case EKeywordPrimary:
  2436 		case EKeywordSecondary:
  2185 		case EKeywordSecondary:
  2437 		case EKeywordExtension:
  2186 		case EKeywordExtension:
  2451 		case EKeywordAlias:
  2200 		case EKeywordAlias:
  2452 		case EKeywordRename:
  2201 		case EKeywordRename:
  2453 			if (!ProcessRenaming(keyword))
  2202 			if (!ProcessRenaming(keyword))
  2454 				return KErrGeneral;
  2203 				return KErrGeneral;
  2455 			break;
  2204 			break;
  2456 		case EKeywordPatchDllData:
  2205 		case EKeywordPatchDllData: {
  2457 		{
  2206 				// Collect patchdata statements to process at the end
  2458 			// Collect patchdata statements to process at the end
  2207 				StringVector patchDataTokens;
  2459 			StringVector patchDataTokens;
  2208 				SplitPatchDataStatement(patchDataTokens); 
  2460 			SplitPatchDataStatement(patchDataTokens); 
  2209 				iPatchData->AddPatchDataStatement(patchDataTokens);										
  2461 			iPatchData->AddPatchDataStatement(patchDataTokens);										
  2210 				break;
  2462 			break;
  2211 			}
  2463 		}
       
  2464 
  2212 
  2465 		default:
  2213 		default:
  2466 			if (!ProcessFile(align, keyword))
  2214 			if (!ProcessFile(align, keyword))
  2467 				return KErrGeneral;
  2215 					return KErrGeneral;			
  2468 			align=0;
  2216 			align=0;
  2469 			break;
  2217 			break;
  2470 			}
  2218 		}
  2471 		}
  2219 	}
  2472 
  2220 	
  2473 	if( !ParsePatchDllData())
  2221 	if( !ParsePatchDllData())
  2474 		return KErrGeneral;
  2222 		return KErrGeneral;
  2475 
  2223 
  2476 	iReader.Mark();			// ready for processing the next extension rom(s)
  2224 	iReader.Mark();			// ready for processing the next extension rom(s)
  2477 
  2225 
  2478 	if (iMissingFiles!=0)
  2226 	if (iMissingFiles!=0)
  2479 		return KErrGeneral;
  2227 		return KErrGeneral;
  2480 	if (iNumberOfDataFiles+iNumberOfPeFiles==0)
  2228 	if (iNumberOfDataFiles+iNumberOfPeFiles==0) {
  2481 		{
       
  2482 		Print(EError, "No files specified.\n");
  2229 		Print(EError, "No files specified.\n");
  2483 		return KErrGeneral;
  2230 		return KErrGeneral;
  2484 		}
  2231 	}
  2485 	return KErrNone;
  2232 	return KErrNone;
  2486 	}
  2233 }
  2487 
  2234 
  2488 void CObeyFile::ProcessExtensionKeyword(enum EKeyword aKeyword)
  2235 void CObeyFile::ProcessExtensionKeyword(enum EKeyword aKeyword) {
  2489 	{
       
  2490 	#ifdef __TOOLS2__
       
  2491 	istringstream val(iReader.Word(1));
       
  2492 	#else
       
  2493 	istrstream val(iReader.Word(1),strlen(iReader.Word(1)));
       
  2494 	#endif
       
  2495 	
  2236 	
  2496 
  2237 	switch (aKeyword) {
  2497 #if defined(__MSVCDOTNET__) || defined(__TOOLS2__)
       
  2498 	val >> setbase(0);
       
  2499 #endif //__MSVCDOTNET__
       
  2500 
       
  2501 	switch (aKeyword)
       
  2502 		{
       
  2503 	case EKeywordKernelRomName:
  2238 	case EKeywordKernelRomName:
  2504 		iReader.CopyWord(1, iKernelRomName);
  2239 		iKernelRomName = iReader.DupWord(1);
  2505 		return;
  2240 		return;
  2506 	case EKeywordRomNameOdd:
  2241 	case EKeywordRomNameOdd:
  2507 		iReader.CopyWord(1, iRomOddFileName);
  2242 		iRomOddFileName = iReader.DupWord(1);
  2508 		return;
  2243 		return;
  2509 	case EKeywordRomNameEven:
  2244 	case EKeywordRomNameEven:
  2510 		iReader.CopyWord(1, iRomEvenFileName);
  2245 		iRomEvenFileName = iReader.DupWord(1);
  2511 		return;
  2246 		return;
  2512 	case EKeywordSRecordFileName:
  2247 	case EKeywordSRecordFileName:
  2513 		iReader.CopyWord(1, iSRecordFileName);
  2248 		iSRecordFileName = iReader.DupWord(1);
  2514 		return;
  2249 		return;
  2515 
  2250 
  2516 	case EKeywordRomLinearBase:
  2251 	case EKeywordRomLinearBase:
  2517 		val >> iRomLinearBase;
  2252 		Val(iRomLinearBase,iReader.Word(1));
  2518 		return;
  2253 		return;
  2519 	case EKeywordRomSize:
  2254 	case EKeywordRomSize:
  2520 		val >> iRomSize;
  2255 		Val(iRomSize,iReader.Word(1));
  2521 		return;
  2256 		return;
  2522 	case EKeywordRomAlign:
  2257 	case EKeywordRomAlign:
  2523 		val >> iRomAlign;
  2258 		Val(iRomAlign,iReader.Word(1));
  2524 		return;
  2259 		return;
  2525 
       
  2526 	case EKeywordDataAddress:
  2260 	case EKeywordDataAddress:
  2527 		val >> iDataRunAddress;
  2261 		Val(iDataRunAddress ,iReader.Word(1));
  2528 		return;
  2262 		return;
  2529 	case EKeywordDefaultStackReserve:
  2263 	case EKeywordDefaultStackReserve:
  2530 		val >> iDefaultStackReserve;
  2264 		Val(iDefaultStackReserve,iReader.Word(1));
  2531 		return;
  2265 		return;
  2532 	case EKeywordVersion:
  2266 	case EKeywordVersion:
  2533 		val >> iVersion;
  2267 		{
       
  2268 			istringstream val(iReader.Word(1));
       
  2269 			val >> iVersion;
       
  2270 		}
  2534 		return;
  2271 		return;
  2535 	case EKeywordSRecordBase:
  2272 	case EKeywordSRecordBase:
  2536 		val >> iSRecordBase;
  2273 		Val(iSRecordBase,iReader.Word(1));
  2537 		return;
  2274 		return;
  2538 	case EKeywordRomChecksum:
  2275 	case EKeywordRomChecksum:
  2539 		val >> iCheckSum;
  2276 		Val(iCheckSum,iReader.Word(1)); 
  2540 		return;
  2277 		return;
  2541 	case EKeywordTime:
  2278 	case EKeywordTime:
  2542 		iReader.ProcessTime(iTime);
  2279 		iReader.ProcessTime(iTime);
  2543 		return;
  2280 		return;
  2544 
  2281 
  2545 	case EKeywordTrace:
  2282 	case EKeywordTrace:
  2546 		val >> TraceMask;
  2283 		Val(TraceMask,iReader.Word(1));
  2547 		return;
  2284 		return;
  2548 
  2285 
  2549 	case EKeywordCollapse:
  2286 	case EKeywordCollapse:
  2550 		if (strnicmp(iReader.Word(1), "arm", 3)!=0 || strnicmp(iReader.Word(2), "gcc", 3)!=0)
  2287 		if (strnicmp(iReader.Word(1), "arm", 3)!=0 || strnicmp(iReader.Word(2), "gcc", 3)!=0) {
  2551 			{
       
  2552 			Print(EWarning, "COLLAPSE only supported for ARM and GCC - keyword ignored\n");
  2288 			Print(EWarning, "COLLAPSE only supported for ARM and GCC - keyword ignored\n");
  2553 			}
  2289 		}
  2554 		else
  2290 		else {
  2555 			{
  2291 			TUint32 cm = 0;
  2556 			TInt cm;
  2292 			Val(cm,iReader.Word(3)); 
  2557 			#ifdef __TOOLS2__
  2293 			if ( cm > ECollapseAllChainBranches) {
  2558 			istringstream cmval(iReader.Word(3));
       
  2559 			#else
       
  2560 			istrstream cmval(iReader.Word(3),strlen(iReader.Word(3)));
       
  2561 			#endif
       
  2562 
       
  2563 #if defined(__MSVCDOTNET__) || defined(__TOOLS2__)
       
  2564 			cmval >> setbase(0);
       
  2565 #endif //__MSVCDOTNET__
       
  2566 
       
  2567 			cmval>>cm;
       
  2568 			if (cm<0 || cm>ECollapseAllChainBranches)
       
  2569 				{
       
  2570 				Print(EWarning, "COLLAPSE mode unrecognised - keyword ignored\n");
  2294 				Print(EWarning, "COLLAPSE mode unrecognised - keyword ignored\n");
  2571 				}
  2295 			}
  2572 			else
  2296 			else {
  2573 				{
       
  2574 				Print(EWarning, "COLLAPSE not currently supported for extension roms\n");
  2297 				Print(EWarning, "COLLAPSE not currently supported for extension roms\n");
  2575 				}
  2298 			}
  2576 			}
  2299 		}
  2577 		return;
  2300 		return;
  2578 
  2301 
  2579 	case EKeywordCoreImage:
  2302 	case EKeywordCoreImage:
  2580 		//Already handled, skip it
  2303 		//Already handled, skip it
  2581 		return;
  2304 		return;
  2582 
  2305 
  2583 	default:
  2306 	default:
  2584 		Print(EError,"Keyword '%s' not valid in extension ROMs - line %d\n", iReader.Word(0), iReader.CurrentLine());
  2307 		Print(EError,"Keyword '%s' not valid in extension ROMs - line %d\n", iReader.Word(0), iReader.CurrentLine());
  2585 		break;
  2308 		break;
  2586 		}
  2309 	}
  2587 	return;
  2310 	return;
  2588 	}
  2311 }
  2589 
  2312 
  2590 TBool CObeyFile::GotExtensionVariables(MRomImage*& aRom)
       
  2591 //
  2313 //
  2592 // Checks that the obeyfile has supplied enough variables to continue
  2314 // Checks that the obeyfile has supplied enough variables to continue
  2593 //
  2315 // 
  2594    	{
  2316 TBool CObeyFile::GotExtensionVariables(MRomImage*& aRom){
  2595 
  2317 
  2596 	TBool retVal=ETrue;
  2318 	TBool retVal=ETrue;
  2597 	TText* kernelRomName = iKernelRomName;
  2319 	const char* kernelRomName = iKernelRomName ;
  2598 
  2320 
  2599 	// Mandatory keywords
  2321 	// Mandatory keywords
  2600 
  2322 
  2601 	if (iRomSize==0)
  2323 	if (iRomSize==0) {
  2602 		{
       
  2603 		Print(EAlways,"The size of the extension ROM has not been supplied.\n");
  2324 		Print(EAlways,"The size of the extension ROM has not been supplied.\n");
  2604 		Print(EAlways,"Use the keyword \"romsize\".\n");
  2325 		Print(EAlways,"Use the keyword \"romsize\".\n");
  2605 		retVal = EFalse;
  2326 		retVal = EFalse;
  2606 		}
  2327 	}
  2607 
  2328 
  2608 	// keywords we need if we don't already have a ROM image to work from
  2329 	// keywords we need if we don't already have a ROM image to work from
  2609 
  2330 
  2610 	if (aRom==0)
  2331 	if (aRom==0) {
  2611 		{
  2332 		if (iKernelRomName==0) {
  2612 		if (iKernelRomName==0)
       
  2613 			{
       
  2614 			Print(EAlways,"The name of the kernel ROM has not been supplied.\n");
  2333 			Print(EAlways,"The name of the kernel ROM has not been supplied.\n");
  2615 			Print(EAlways,"Use the keyword \"kernelromname\".\n");
  2334 			Print(EAlways,"Use the keyword \"kernelromname\".\n");
  2616 			retVal = EFalse;
  2335 			retVal = EFalse;
  2617 			}
  2336 		}
  2618 		if (iRomLinearBase==0xFFFFFFFF)
  2337 		if (iRomLinearBase==0xFFFFFFFF) {
  2619 			{
       
  2620 			Print(EAlways,"The base linear address of the ROM has not been supplied.\n");
  2338 			Print(EAlways,"The base linear address of the ROM has not been supplied.\n");
  2621 			Print(EAlways,"Use the keyword \"romlinearbase\".\n");
  2339 			Print(EAlways,"Use the keyword \"romlinearbase\".\n");
  2622 			retVal = EFalse;
  2340 			retVal = EFalse;
  2623 			}
  2341 		}
  2624 		}
  2342 	}
  2625 	else
  2343 	else {
  2626 		{
  2344 		if (iKernelRomName != 0) {
  2627 		if (iKernelRomName != 0)
       
  2628 			{
       
  2629 			Print(EWarning,"Keyword \"kernelromname\") ignored.\n");
  2345 			Print(EWarning,"Keyword \"kernelromname\") ignored.\n");
  2630 			}
  2346 		}
  2631 		kernelRomName = aRom->RomFileName();
  2347 		kernelRomName = aRom->RomFileName();
  2632 		}
  2348 	}
  2633 
  2349 
  2634 	// validation
  2350 	// validation
  2635 
  2351 
  2636 	// Apply defaults as necessary
  2352 	// Apply defaults as necessary
  2637 
  2353 
  2638 	if (iRomLinearBase==0xFFFFFFFF && aRom!=0)
  2354 	if (iRomLinearBase==0xFFFFFFFF && aRom!=0) {
  2639 		{
       
  2640 		iRomLinearBase = aRom->RomBase() + aRom->RomSize();
  2355 		iRomLinearBase = aRom->RomBase() + aRom->RomSize();
  2641 		Print(ELog,"Assuming extension ROM is contiguous with kernel ROM\n");
  2356 		Print(ELog,"Assuming extension ROM is contiguous with kernel ROM\n");
  2642 		Print(ELog,"Setting romlinearbase to 0x%08x\n", iRomLinearBase);
  2357 		Print(ELog,"Setting romlinearbase to 0x%08x\n", iRomLinearBase);
  2643 		}
  2358 	}
  2644 	TheRomLinearAddress=iRomLinearBase;
  2359 	TheRomLinearAddress=iRomLinearBase;
  2645 
  2360 
  2646 	if (iDataRunAddress==0)
  2361 	if (iDataRunAddress==0) {
  2647 		{
       
  2648 		iDataRunAddress= aRom->DataRunAddress();
  2362 		iDataRunAddress= aRom->DataRunAddress();
  2649 		Print(EWarning,"The address for a running ROM app's data section (keyword \"dataaddress\") has not been supplied.\n");
  2363 		Print(EWarning,"The address for a running ROM app's data section (keyword \"dataaddress\") has not been supplied.\n");
  2650 		Print(EWarning,"Will use the default value of 0x%0x.\n", iDataRunAddress);
  2364 		Print(EWarning,"Will use the default value of 0x%0x.\n", iDataRunAddress);
  2651 		}
  2365 	}
  2652 	if (iRomAlign==0)
  2366 	if (iRomAlign==0) {
  2653 		{
       
  2654 		iRomAlign = aRom->RomAlign();
  2367 		iRomAlign = aRom->RomAlign();
  2655 		Print(EWarning,"The ROM section alignment (keyword \"romalign\") has not been supplied.\n");
  2368 		Print(EWarning,"The ROM section alignment (keyword \"romalign\") has not been supplied.\n");
  2656 		Print(EWarning,"Will use the default value of 0x%0x.\n", iRomAlign);
  2369 		Print(EWarning,"Will use the default value of 0x%0x.\n", iRomAlign);
  2657 		}
  2370 	}
  2658 	if (iRomAlign&0x3)
  2371 	if (iRomAlign&0x3) {
  2659 		{
       
  2660 		Print(EWarning, "Rounding rom alignment to multiple of 4.\n");
  2372 		Print(EWarning, "Rounding rom alignment to multiple of 4.\n");
  2661 		iRomAlign=(iRomAlign+0x3)&0xfffffffc;
  2373 		iRomAlign=(iRomAlign+0x3)&0xfffffffc;
  2662 		}
  2374 	}
  2663 	if (iTime==0)
  2375 	if (iTime==0) {
  2664 		{
       
  2665 		Print(ELog, "No timestamp specified. Using current time...\n");
  2376 		Print(ELog, "No timestamp specified. Using current time...\n");
  2666 		ObeyFileReader::TimeNow(iTime);
  2377 		ObeyFileReader::TimeNow(iTime);
  2667 		}
  2378 	}
  2668 
  2379 
  2669 	// fix up "*" in romname
  2380 	// fix up "*" in romname
  2670 	TText newname[256];
  2381 	char newname[256];
  2671 	TText* p=newname;
  2382 	char* p=newname;
  2672 	TText* q=iRomFileName;
  2383 	char* q=iRomFileName;
  2673 	TText c;
  2384 	char c;
  2674 
  2385 
  2675 	while ((c=*q++)!='\0')
  2386 	while ((c=*q++)!='\0') {
  2676 		{
  2387 		if (c!='*') {
  2677 		if (c!='*')
       
  2678 			{
       
  2679 			*p++=c;
  2388 			*p++=c;
  2680 			continue;
  2389 			continue;
  2681 			}
  2390 		}
  2682 		TText *r=kernelRomName;
  2391 		const char *r = kernelRomName ? kernelRomName : "";
  2683 		while ((c=*r++)!='\0')
  2392 		while ((c=*r++)!='\0')
  2684 			*p++=c;
  2393 			*p++=c;
  2685 		}
  2394 	}
  2686 	*p = '\0';
  2395 	*p++ = '\0';
  2687 	free(iRomFileName);
  2396 	delete []iRomFileName;
  2688 	iRomFileName = (TText*)strdup((char*)newname);
  2397 	size_t len = p - newname ;
       
  2398 	iRomFileName = new char[len];
       
  2399 	memcpy(iRomFileName,newname,len);
  2689 
  2400 
  2690 	Print(ELog, "\nCreating Rom image %s\n", iRomFileName);
  2401 	Print(ELog, "\nCreating Rom image %s\n", iRomFileName);
  2691 	return retVal;
  2402 	return retVal;
  2692 	}
  2403 }
  2693 
  2404 
  2694 
  2405 
  2695 ////////////////////////////////////////////////////////////////////////
  2406 ////////////////////////////////////////////////////////////////////////
  2696 // AREA RELATED CODE
  2407 // AREA RELATED CODE
  2697 ////////////////////////////////////////////////////////////////////////
  2408 ////////////////////////////////////////////////////////////////////////
  2698 
  2409 
  2699 /**
  2410 /**
  2700  Process an area declaration.
  2411 Process an area declaration.
  2701  */
  2412 */
  2702 
  2413 
  2703 TBool CObeyFile::ParseAreaKeyword()
  2414 TBool CObeyFile::ParseAreaKeyword() {
  2704 	{
  2415 		 
       
  2416 	if(!IsValidNumber(iReader.Word(2)) || !IsValidNumber(iReader.Word(3))) {
       
  2417 		Print(EError, "Line %d: Wrong area specification: Should be <name> <start address> <length>\n",
       
  2418 			iReader.CurrentLine());
       
  2419 		return EFalse;
       
  2420 	}
  2705 	const char* name = iReader.Word(1);
  2421 	const char* name = iReader.Word(1);
  2706 	TLinAddr start;
  2422 	TLinAddr start = 0;
  2707 	TUint length;
  2423 	Val(start,iReader.Word(2)); 
  2708 	if(Val(start, iReader.Word(2)) != KErrNone || Val(length, iReader.Word(3)) != KErrNone)
  2424 	TUint length = 0;
  2709 		{
  2425 	Val(length,iReader.Word(3));
  2710 		Print(EError, "Line %d: Wrong area specification: Should be <name> <start address> <length>\n",
       
  2711 			  iReader.CurrentLine());
       
  2712 		return EFalse;
       
  2713 		}
       
  2714 
       
  2715 	if (! AddAreaAndHandleError(name, start, length, iReader.CurrentLine()))
  2426 	if (! AddAreaAndHandleError(name, start, length, iReader.CurrentLine()))
  2716 		return EFalse;
  2427 		return EFalse;
  2717 
  2428 
  2718 	return ETrue;
  2429 	return ETrue;
  2719 	}
  2430 }
  2720 
  2431 
  2721 
  2432 
  2722 /**
  2433 /**
  2723  Process an "area=xxx" file attribute.
  2434 Process an "area=xxx" file attribute.
  2724  */
  2435 */
  2725 
  2436 
  2726 TBool CObeyFile::ParseAreaAttribute(const TText* aArg, TInt aLineNumber, const Area*& aArea)
  2437 TBool CObeyFile::ParseAreaAttribute(const char* aArg, TInt aLineNumber, const Area*& aArea) {
  2727 	{
  2438 	if (iSectionPosition != -1) {
  2728 	if (iSectionPosition != -1)
       
  2729 		{
       
  2730 		Print(EError, "Line %d: Relocation to area forbidden in second section\n", aLineNumber);
  2439 		Print(EError, "Line %d: Relocation to area forbidden in second section\n", aLineNumber);
  2731 		return EFalse;
  2440 		return EFalse;
  2732 		}
  2441 	}
  2733 
  2442 
  2734 	aArea = iAreaSet.FindByName(reinterpret_cast<const char*>(aArg));
  2443 	aArea = iAreaSet.FindByName(reinterpret_cast<const char*>(aArg));
  2735 	if (aArea == 0)
  2444 	if (aArea == 0) {
  2736 		{
       
  2737 		Print(EError, "Line %d: Attempt to use an unknown area named '%s'\n", aLineNumber, aArg);
  2445 		Print(EError, "Line %d: Attempt to use an unknown area named '%s'\n", aLineNumber, aArg);
  2738 		return EFalse;
  2446 		return EFalse;
  2739 		}
  2447 	}
  2740 
  2448 
  2741 	return ETrue;
  2449 	return ETrue;
  2742 	}
  2450 }
  2743 
  2451 
  2744 
  2452 
  2745 TBool CObeyFile::CreateDefaultArea()
  2453 TBool CObeyFile::CreateDefaultArea() {
  2746 	{
       
  2747 	return AddAreaAndHandleError(AreaSet::KDefaultAreaName, iRomLinearBase, iRomSize);
  2454 	return AddAreaAndHandleError(AreaSet::KDefaultAreaName, iRomLinearBase, iRomSize);
  2748 	}
  2455 }
  2749 
  2456 
  2750 
  2457 
  2751 TBool CObeyFile::AddAreaAndHandleError(const char* aName, TLinAddr aDestBaseAddr, TUint aLength, TInt aLineNumber)
  2458 TBool CObeyFile::AddAreaAndHandleError(const char* aName, TLinAddr aDestBaseAddr, TUint aLength, TInt aLineNumber) {
  2752 	{
       
  2753 	TBool added = EFalse;
  2459 	TBool added = EFalse;
  2754 	
  2460 
  2755 	const char lineInfoFmt[] = "Line %d:";
  2461 	const char lineInfoFmt[] = "Line %d:";
  2756 	char lineInfo[sizeof(lineInfoFmt)+10];
  2462 	char lineInfo[sizeof(lineInfoFmt)+10];
  2757 	if (aLineNumber > 0)
  2463 	if (aLineNumber > 0)
  2758 		sprintf(lineInfo, lineInfoFmt, aLineNumber);
  2464 		sprintf(lineInfo, lineInfoFmt, aLineNumber);
  2759 	else
  2465 	else
  2760 		lineInfo[0] = '\0';
  2466 		lineInfo[0] = '\0';
  2761 
  2467 
  2762 	const char* overlappingArea;
  2468 	const char* overlappingArea;
  2763 	switch (iAreaSet.AddArea(aName, aDestBaseAddr, aLength, overlappingArea))
  2469 	switch (iAreaSet.AddArea(aName, aDestBaseAddr, aLength, overlappingArea)) {
  2764 		{
       
  2765 	case AreaSet::EAdded:
  2470 	case AreaSet::EAdded:
  2766 		TRACE(TAREA, Print(EScreen, "Area '%s' added to AreaSet\n", aName));
  2471 		TRACE(TAREA, Print(EScreen, "Area '%s' added to AreaSet\n", aName));
  2767 		added = ETrue;
  2472 		added = ETrue;
  2768 		break;
  2473 		break;
  2769 	case AreaSet::EOverlap:
  2474 	case AreaSet::EOverlap:
  2775 	case AreaSet::EOverflow:
  2480 	case AreaSet::EOverflow:
  2776 		Print(EError, "%s Area overflow (0x%X+0x%X > 0x%X)\n", lineInfo, aDestBaseAddr, aLength, -1);
  2481 		Print(EError, "%s Area overflow (0x%X+0x%X > 0x%X)\n", lineInfo, aDestBaseAddr, aLength, -1);
  2777 		break;
  2482 		break;
  2778 	default:
  2483 	default:
  2779 		assert(0);				// can't happen
  2484 		assert(0);				// can't happen
  2780 		}
  2485 	}
  2781 
  2486 
  2782 	return added;
  2487 	return added;
  2783 	}
  2488 }
  2784 
       
  2785 TInt getNumber(TText*);
       
  2786 
       
  2787 
  2489 
  2788 // Fuction to split patchdata statement 
  2490 // Fuction to split patchdata statement 
  2789 void CObeyFile::SplitPatchDataStatement(StringVector& aPatchDataTokens)
  2491 void CObeyFile::SplitPatchDataStatement(StringVector& aPatchDataTokens) {
  2790 {
       
  2791 	// Get the value of symbol size, address/ordinal and new value 
  2492 	// Get the value of symbol size, address/ordinal and new value 
  2792 	// to be patched from the patchdata statement.
  2493 	// to be patched from the patchdata statement.
  2793 	// Syntax of patchdata statements is as follows:
  2494 	// Syntax of patchdata statements is as follows:
  2794 	// 1)	patchdata dll_name  ordinal OrdinalNumber size_in_bytes   new_value 
  2495 	// 1)	patchdata dll_name  ordinal OrdinalNumber size_in_bytes   new_value 
  2795 	// 2)   patchdata dll_name  addr    Address       size_in_bytes   new_value
  2496 	// 2)   patchdata dll_name  addr    Address       size_in_bytes   new_value
  2796 	for(TInt count=1; count<=5; count++)	
  2497 	for(TInt count=1; count<=5; count++)	 {
  2797 	{
       
  2798 		aPatchDataTokens.push_back(iReader.Word(count));
  2498 		aPatchDataTokens.push_back(iReader.Word(count));
  2799 	}
  2499 	}
  2800 
  2500 
  2801 	// Store the the value of current line which will be used
  2501 	// Store the the value of current line which will be used
  2802 	// when displaying error messages.
  2502 	// when displaying error messages.
  2803 	OutputStringStream outStrStream;
  2503 	ostringstream outStrStream;
  2804 	outStrStream << iReader.CurrentLine();
  2504 	outStrStream << iReader.CurrentLine();
  2805     aPatchDataTokens.push_back(outStrStream.str());	
  2505 	aPatchDataTokens.push_back(outStrStream.str());	
  2806 }
  2506 }
  2807 
  2507 
  2808 TBool CObeyFile::ParsePatchDllData()
  2508 TBool CObeyFile::ParsePatchDllData() {
  2809 {
       
  2810 	// Get the list of patchdata statements
  2509 	// Get the list of patchdata statements
  2811 	VectorOfStringVector patchDataStatements=iPatchData->GetPatchDataStatements();
  2510 	VectorOfStringVector patchDataStatements=iPatchData->GetPatchDataStatements();
  2812 	// Get the list of renamed file map
  2511 	// Get the list of renamed file map
  2813 	MapOfString RenamedFileMap=iPatchData->GetRenamedFileMap();
  2512 	MapOfString RenamedFileMap=iPatchData->GetRenamedFileMap();
  2814 	DllDataEntry *aDllDataEntry=NULL;
  2513 	DllDataEntry *aDllDataEntry=NULL;
  2815 
  2514 
  2816 	for(TUint count=0; count<patchDataStatements.size(); count++)
  2515 	for(TUint count=0; count<patchDataStatements.size(); count++) {
  2817 	{
       
  2818 		StringVector strVector = patchDataStatements.at(count);
  2516 		StringVector strVector = patchDataStatements.at(count);
  2819 		String filename=strVector.at(0);
  2517 		string filename=strVector.at(0);
  2820 		String lineNoStr = strVector.at(5);
  2518 		string lineNoStr = strVector.at(5);
  2821 		TUint lineNo=getNumber(((TText*)lineNoStr.c_str()));
  2519 		TUint lineNo = 1 ;
       
  2520 		Val(lineNo,lineNoStr.c_str()); 
  2822 		TRomNode* existingFile = NULL;
  2521 		TRomNode* existingFile = NULL;
  2823 			
  2522 
  2824 		do
  2523 		do {
  2825 		{			
       
  2826 			TUint hardwareVariant=ParseVariant();
  2524 			TUint hardwareVariant=ParseVariant();
  2827 			TRomNode* dir=iRootDirectory;		
  2525 			TRomNode* dir=iRootDirectory;		
  2828 			TBool endOfName=EFalse;
  2526 			TBool endOfName=EFalse;
  2829 
  2527 
  2830 			TText *epocStartPtr=IsValidFilePath((TText*)filename.c_str());
  2528 		 
  2831 			if (epocStartPtr==NULL)
  2529 			if (IsValidFilePath(filename.c_str()) == NULL) {
  2832 			{
       
  2833 				Print(EError, "Invalid source path on line %d\n",lineNo);
  2530 				Print(EError, "Invalid source path on line %d\n",lineNo);
  2834 				return EFalse;
  2531 				return EFalse;
  2835 			}
  2532 			}
  2836 			epocStartPtr = (TText*)NormaliseFileName((const char*)epocStartPtr);
  2533 			char* epocStartPtr = NormaliseFileName(filename.c_str());
  2837 			TText *epocEndPtr=epocStartPtr;
  2534 			char* savedPtr = epocStartPtr;
  2838 
  2535 			if(*epocStartPtr == '/' ||*epocStartPtr == '\\')
  2839 			while (!endOfName)
  2536 				epocStartPtr++ ;
  2840 			{
  2537 			char* epocEndPtr=epocStartPtr;
  2841 				endOfName = GetNextBitOfFileName(&epocEndPtr);
  2538 
  2842 				if (endOfName) // file
  2539 			while (!endOfName) {
  2843 				{
  2540 				endOfName = GetNextBitOfFileName(epocEndPtr);
       
  2541 				if (endOfName) { // file 
  2844 					existingFile=dir->FindInDirectory(epocStartPtr,hardwareVariant,TRUE);
  2542 					existingFile=dir->FindInDirectory(epocStartPtr,hardwareVariant,TRUE);
  2845 					if (existingFile)
  2543 					if (existingFile) {
  2846 					{
       
  2847 						TInt fileCount=0;
  2544 						TInt fileCount=0;
  2848 						TInt dirCount=0;
  2545 						TInt dirCount=0;
  2849 						existingFile->CountDirectory(fileCount, dirCount);
  2546 						existingFile->CountDirectory(fileCount, dirCount);
  2850 						if (dirCount != 0 || fileCount != 0)
  2547 						if (dirCount != 0 || fileCount != 0) {
  2851 						{
       
  2852 							Print(EError, "Keyword %s not applicable to directories - line %d\n","patchdata",lineNo);
  2548 							Print(EError, "Keyword %s not applicable to directories - line %d\n","patchdata",lineNo);
       
  2549 							delete []savedPtr;
  2853 							return EFalse;
  2550 							return EFalse;
  2854 						}
  2551 						}
  2855 					}
  2552 					}
  2856 				}
  2553 				}
  2857 				else // directory
  2554 				else {// directory 
  2858 				{
       
  2859 					TRomNode* subDir = dir->FindInDirectory(epocStartPtr);
  2555 					TRomNode* subDir = dir->FindInDirectory(epocStartPtr);
  2860 					if (!subDir) // sub directory does not exist
  2556 					if (!subDir) // sub directory does not exist
  2861 						break;
  2557 						break;
  2862 					dir=subDir;
  2558 					dir=subDir;
  2863 					epocStartPtr = epocEndPtr;
  2559 					epocStartPtr = epocEndPtr;
  2864 				}
  2560 				}
  2865 			}
  2561 			}
  2866 
  2562 			delete []savedPtr;
  2867 			if( !existingFile )
  2563 			if( !existingFile ) {
  2868 			{
       
  2869 				MapOfStringIterator RenamedFileMapIterator;
  2564 				MapOfStringIterator RenamedFileMapIterator;
  2870 
  2565 
  2871 				// If the E32Image file to be patched is not included then check if the
  2566 				// If the E32Image file to be patched is not included then check if the
  2872 				// file was renamed.
  2567 				// file was renamed.
  2873 				if ((RenamedFileMapIterator=RenamedFileMap.find(filename)) != RenamedFileMap.end())
  2568 				if ((RenamedFileMapIterator=RenamedFileMap.find(filename)) != RenamedFileMap.end())
  2874 					filename = (*RenamedFileMapIterator).second; 
  2569 					filename = (*RenamedFileMapIterator).second; 
  2875 				else
  2570 				else {
  2876 				{
       
  2877 					Print(EError, "File %s not found - line %d\n", filename.c_str(), lineNo);
  2571 					Print(EError, "File %s not found - line %d\n", filename.c_str(), lineNo);
  2878 					return EFalse;
  2572 					return EFalse;
  2879 				}
  2573 				}
  2880 			}
  2574 			}
  2881 		}while(!existingFile);
  2575 		}while(!existingFile);
  2885 
  2579 
  2886 		aOrdinal = (TUint32)-1;
  2580 		aOrdinal = (TUint32)-1;
  2887 		aDataAddr = (TUint32)-1;
  2581 		aDataAddr = (TUint32)-1;
  2888 		aOffset = 0;
  2582 		aOffset = 0;
  2889 
  2583 
  2890 		String symbolSize = strVector.at(3);
  2584 		string symbolSize = strVector.at(3);
  2891 		aSize = getNumber((TText*)symbolSize.c_str());
  2585 		Val(aSize,symbolSize.c_str());
  2892 		String aValue = strVector.at(4);
  2586 		string aValue = strVector.at(4);
  2893 		aNewValue = getNumber( (TText*)aValue.c_str());
  2587 		Val(aNewValue,aValue.c_str());
  2894 
  2588 
  2895 		DllDataEntry *dataEntry = new DllDataEntry(aSize, aNewValue);
  2589 		DllDataEntry *dataEntry = new DllDataEntry(aSize, aNewValue);
  2896 
  2590 
  2897 		// Set the address of the data or the ordinal number specified in OBY statement.
  2591 		// Set the address of the data or the ordinal number specified in OBY statement.
  2898 		String keyword = strVector.at(1);
  2592 		string keyword = strVector.at(1);
  2899 		String keywordValue = strVector.at(2);
  2593 		string keywordValue = strVector.at(2);
  2900 
  2594 
  2901 		/* Check for +OFFSET at the end of the ordinal number or address */
  2595 		/* Check for +OFFSET at the end of the ordinal number or address */
  2902 		TUint plus = keywordValue.find("+",0);
  2596 		TUint plus = keywordValue.find("+",0);
  2903 		if (plus != std::string::npos)
  2597 		if (plus != string::npos) {
  2904 		{
       
  2905 			/* Get the offset that we found after the + sign */
  2598 			/* Get the offset that we found after the + sign */
  2906 			String offset = keywordValue.substr(plus+1);
  2599 			string offset = keywordValue.substr(plus+1);
  2907 			aOffset = getNumber((TText*)offset.c_str());
  2600 			Val(aOffset,offset.c_str());
  2908 
       
  2909 			keywordValue.resize(plus);		
  2601 			keywordValue.resize(plus);		
  2910 		}
  2602 		}
  2911 		if(stricmp ((char*)keyword.c_str(), "addr") == 0)
  2603 		if(stricmp (keyword.c_str(), "addr") == 0)
  2912 			aDataAddr = getNumber((TText*)keywordValue.c_str());
  2604 			Val(aDataAddr,keywordValue.c_str());
  2913 		
  2605 
  2914 		else 
  2606 		else 
  2915 			 aOrdinal = getNumber((TText*)keywordValue.c_str());
  2607 			Val(aOrdinal,keywordValue.c_str());
  2916 		
  2608 
  2917 		dataEntry->iDataAddress = aDataAddr;
  2609 		dataEntry->iDataAddress = aDataAddr;
  2918 		dataEntry->iOrdinal = aOrdinal;
  2610 		dataEntry->iOrdinal = aOrdinal;
  2919 		dataEntry->iOffset = aOffset;
  2611 		dataEntry->iOffset = aOffset;
  2920 		dataEntry->iRomNode = existingFile;
  2612 		dataEntry->iRomNode = existingFile;
  2921 
  2613 
  2922 		if (aDllDataEntry==NULL)
  2614 		if (aDllDataEntry==NULL) {
  2923 		{
       
  2924 			// Set the first node of the patchdata linked list
  2615 			// Set the first node of the patchdata linked list
  2925 			aDllDataEntry = dataEntry;
  2616 			aDllDataEntry = dataEntry;
  2926 			SetFirstDllDataEntry(aDllDataEntry);
  2617 			SetFirstDllDataEntry(aDllDataEntry);
  2927 		}
  2618 		}
  2928 		else
  2619 		else {
  2929 		{
       
  2930 			// Add the new node at the end of linked list
  2620 			// Add the new node at the end of linked list
  2931 			aDllDataEntry->AddDllDataEntry(dataEntry);
  2621 			aDllDataEntry->AddDllDataEntry(dataEntry);
  2932 			aDllDataEntry = aDllDataEntry->NextDllDataEntry();
  2622 			aDllDataEntry = aDllDataEntry->NextDllDataEntry();
  2933 		}
  2623 		}
  2934 	}
  2624 	}
  2935 	return ETrue;
  2625 	return ETrue;
  2936 }
  2626 }
  2937 
  2627 
  2938 int CObeyFile::SkipToExtension()
  2628 int CObeyFile::SkipToExtension() {
  2939 {
       
  2940 	int found = 0;
  2629 	int found = 0;
  2941 
  2630 
  2942 	iReader.Rewind();
  2631 	iReader.Rewind();
  2943 	enum EKeyword keyword;
  2632 	enum EKeyword keyword;
  2944 	while (iReader.NextLine(1,keyword) != KErrEof)
  2633 	while (iReader.NextLine(1,keyword) != KErrEof) {
  2945 	{
  2634 		if (keyword == EKeywordExtensionRom) {
  2946 		if (keyword == EKeywordExtensionRom)
       
  2947 		{
       
  2948 			found = 1;
  2635 			found = 1;
  2949 			iReader.Mark(); // ready for processing extension
  2636 			iReader.Mark(); // ready for processing extension
  2950 			break;
  2637 			break;
  2951 		}
  2638 		}
  2952 	}
  2639 	}
  2953 
  2640 
  2954 	if(!found)
  2641 	if(!found) {
  2955 	{
       
  2956 		Print(EError, "Coreimage option requires valid \"extensionrom\" keyword\n");
  2642 		Print(EError, "Coreimage option requires valid \"extensionrom\" keyword\n");
  2957 	}
  2643 	}
  2958 
  2644 
  2959 	return found;
  2645 	return found;
  2960 }
  2646 }
  2961 
  2647 
  2962 TText* CObeyFile::ProcessCoreImage()
  2648 char* CObeyFile::ProcessCoreImage() {
  2963 {
       
  2964 	// check for coreimage keyword and return filename
  2649 	// check for coreimage keyword and return filename
  2965 	iReader.Rewind();
  2650 	iReader.Rewind();
  2966 	enum EKeyword keyword;
  2651 	enum EKeyword keyword;
  2967 	TText* coreImageFileName = 0;
  2652 	char* coreImageFileName = 0;
  2968 
  2653 
  2969 	iRomAlign = KDefaultRomAlign;
  2654 	iRomAlign = KDefaultRomAlign;
  2970 	iDataRunAddress = KDefaultDataRunAddress;
  2655 	iDataRunAddress = KDefaultDataRunAddress;
  2971 
  2656 
  2972 	while (iReader.NextLine(1,keyword) != KErrEof)
  2657 	while (iReader.NextLine(1,keyword) != KErrEof) {
  2973 	{
  2658 		if (keyword == EKeywordCoreImage) {
  2974 		if (keyword == EKeywordCoreImage)
  2659 			coreImageFileName = iReader.DupWord(1);
  2975 		{
  2660 			break;
  2976 #if defined(__TOOLS2__) && defined (_STLP_THREADS)
  2661 		}
  2977 			istringstream val(iReader.Word(1),(ios_base::in+ios_base::out));	  
  2662 		else if ((keyword == EKeywordRomAlign) || (keyword == EKeywordDataAddress)) {
  2978 #elif __TOOLS2__
  2663 			if(keyword == EKeywordRomAlign) {
  2979 			istringstream val(iReader.Word(1),(std::_Ios_Openmode)(ios_base::in+ios_base::out));
  2664 				Val(iRomAlign,iReader.Word(1));
  2980 #else
  2665 			}
  2981 			istrstream val(iReader.Word(1),strlen(iReader.Word(1)));
  2666 			else {
  2982 #endif
  2667 				Val(iDataRunAddress,iReader.Word(1));
  2983 			iReader.CopyWord(1, coreImageFileName);
  2668 			}
  2984 			break;
  2669 		}
  2985 		}
  2670 	}
  2986 		else if ((keyword == EKeywordRomAlign) || (keyword == EKeywordDataAddress))
  2671 
  2987 		{
  2672 	if (iRomAlign&0x3) {
  2988 #ifdef __TOOLS2__
       
  2989 			istringstream val(iReader.Word(1));
       
  2990 #else
       
  2991 			istrstream val(iReader.Word(1),strlen(iReader.Word(1)));
       
  2992 #endif
       
  2993 #if defined(__MSVCDOTNET__) || defined(__TOOLS2__)
       
  2994 	val >> setbase(0);
       
  2995 #endif //__MSVCDOTNET__
       
  2996 			if(keyword == EKeywordRomAlign)
       
  2997 			{
       
  2998 				val >> iRomAlign;
       
  2999 			}
       
  3000 			else
       
  3001 			{
       
  3002 				val >> iDataRunAddress;
       
  3003 			}
       
  3004 		}
       
  3005 	}
       
  3006 
       
  3007 	if (iRomAlign&0x3)
       
  3008 	{
       
  3009 		//Rounding rom alignment to multiple of 4
  2673 		//Rounding rom alignment to multiple of 4
  3010 		iRomAlign=(iRomAlign+0x3)&0xfffffffc;
  2674 		iRomAlign=(iRomAlign+0x3)&0xfffffffc;
  3011 	}
  2675 	}
  3012 
  2676 
  3013 	return coreImageFileName;
  2677 	return coreImageFileName;
  3014 }
  2678 }
  3015