e32tools/elf2e32/source/deffile.cpp
changeset 0 044383f39525
child 682 2c32f186fa1f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/e32tools/elf2e32/source/deffile.cpp	Tue Oct 27 16:36:35 2009 +0000
@@ -0,0 +1,1002 @@
+// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// Implementation of the Class DefFile for the elf2e32 tool
+// @internalComponent
+// @released
+// 
+//
+
+//
+#include <stdio.h>
+#include <iostream>
+#include <stdlib.h>
+
+#include "pl_symbol.h"
+#include "deffile.h"
+#include "errorhandler.h"
+
+#ifdef __LINUX__
+    #include "h_utl.h"
+    #define STRUPR strupr
+#else 
+    #define STRUPR _strupr
+#endif
+
+using std::cerr;
+using std::cout;
+using std::endl;
+
+#define SUCCESS 1
+#define FAILURE 0
+
+/**
+Destructor to release all the allocated memory
+@internalComponent
+@released
+*/
+DefFile::~DefFile()
+{
+	if(iSymbolList && iSymbolList->size())
+	{
+		SymbolList::iterator aItr = iSymbolList->begin();
+		SymbolList::iterator last = iSymbolList->end();
+		Symbol *temp;
+
+		while(aItr != last)
+		{
+			temp = *aItr;
+			aItr++;
+			delete temp;
+		}
+		iSymbolList->clear();
+	}
+	delete iSymbolList;
+}
+/**
+Function to Get File Size.
+@param fptrDef - File pointer to DEF file
+@internalComponent
+@released
+*/
+int DefFile::GetFileSize(FILE *fptrDef)
+{
+	int fileSize,status;
+
+	status=fseek(fptrDef, 0, SEEK_END);
+	if(status!=0)
+	{
+		throw FileError(FILEREADERROR,iFileName);
+	}
+	fileSize=ftell(fptrDef);
+	rewind(fptrDef);
+
+	return fileSize;
+
+}
+
+/**
+Function to Open File and read it in memory.
+@param defFile - DEF File name
+@internalComponent
+@released
+*/
+char* DefFile::OpenDefFile(char * defFile)
+{
+	int fileSize;
+	char *defFileEntries;
+	FILE *fptrDef;
+
+	iFileName=defFile;
+	if((fptrDef=fopen(defFile,"rb"))==NULL)
+	{
+		throw FileError(FILEOPENERROR,defFile);
+	}
+
+	fileSize=GetFileSize(fptrDef);
+
+	if((defFileEntries= new char[fileSize+2]) ==NULL)
+	{
+		throw MemoryAllocationError(MEMORYALLOCATIONERROR,defFile);
+	}
+
+	//Getting whole file in memory
+	if(!fread(defFileEntries, fileSize, 1, fptrDef))
+	{
+		throw FileError(FILEREADERROR,defFile);
+	}
+
+	//Adding ENTER at end
+	*(defFileEntries+fileSize)='\n';
+	//Adding '\0' at end
+	*(defFileEntries+fileSize+1)='\0';
+
+	fclose(fptrDef);
+
+	return defFileEntries;
+
+}
+
+/**
+Function to Parse Def File which has been read in buffer.
+@param defFileEntries - pointer to def file entries which has been read in buffer
+@internalComponent
+@released
+*/
+void DefFile::ParseDefFile(char *defFileEntries)
+{
+	iSymbolList = new SymbolList;
+
+	int ordinalNo = 0;
+	int symbolType=SymbolTypeCode;
+	int PreviousOrdinal=0;
+	char MultiLineStatement[1024]="";
+	bool NAMEorLIBRARYallowed=true;
+	int LineNum = 0;
+	bool isComment;
+
+	char *lineToken;
+	int aLineLength = 0, width = 0;
+	unsigned i;
+	char *ptrEntry,*ptrEntryType;
+	char entryType[256];
+	bool entryFlag;
+
+
+	lineToken=strtok(defFileEntries,"\n");
+	while(lineToken != NULL)
+	{
+		symbolType=SymbolTypeCode;
+		isComment=false;
+		entryType[0]='\0';
+		aLineLength = strlen(lineToken);
+		LineNum++;
+
+		if (lineToken == NULL || lineToken[0]==13)
+		{
+			lineToken=strtok(NULL,"\n");
+			continue;
+		}
+
+		// comment lines
+		if (lineToken[0] == ';')
+		{
+			lineToken=strtok(NULL,"\n");
+			continue;
+		}
+
+		ptrEntry=lineToken;
+
+		if((!strstr(lineToken, "NONAME") && ((ptrEntryType=strstr(lineToken, "NAME")) != NULL)) ||
+			((ptrEntryType=strstr(lineToken, "EXPORTS")) != NULL) ||
+			((ptrEntryType=strstr(lineToken, "IMPORTS")) != NULL) ||
+			((ptrEntryType=strstr(lineToken, "SECTIONS")) != NULL) ||
+			((ptrEntryType=strstr(lineToken, "LIBRARY")) != NULL) ||
+			((ptrEntryType=strstr(lineToken, "DESCRIPTION")) != NULL)||
+			((ptrEntryType=strstr(lineToken, "STACKSIZE")) != NULL)||
+			((ptrEntryType=strstr(lineToken, "VERSION")) != NULL)
+			)
+		{
+			entryFlag=true;
+
+			for(i=0; ptrEntry!=ptrEntryType; i++,ptrEntry++)
+			{
+				switch(lineToken[i])
+				{
+				case ' ':
+				case '\t':
+					continue;
+				default:
+					entryFlag=false;
+					break;
+				}
+				if(entryFlag==false)
+					break;
+			}
+
+			if(entryFlag==false && !strcmp(MultiLineStatement,""))
+			{
+				throw DEFFileError(UNRECOGNIZEDTOKEN,iFileName,LineNum,lineToken);
+			}
+
+			if(entryFlag==true)
+			{
+				switch(ptrEntryType[0])
+				{
+				case 'E':
+				case 'I':
+				case 'L':
+				case 'V':
+					width=7;
+					break;
+				case 'S':
+					if(ptrEntryType[1]=='E')
+						width=8;
+					else
+						width=9;
+					break;
+				case 'N':
+					width=4;
+					break;
+				case 'D':
+					width=11;
+					break;
+				}
+			}
+
+			if(entryFlag==true)
+			{
+  				for(i=i+width; i<strlen(lineToken); i++)
+				{
+					switch(lineToken[i])
+					{
+					case ' ':
+					case '\t':
+						continue;
+					case '\r':
+					case '\0':
+						break;
+					default:
+						entryFlag=false;
+						break;
+					}
+
+					if(entryFlag==false)
+						break;
+				}
+			}
+
+			if(entryFlag==false && !strcmp(MultiLineStatement,""))
+			{
+				throw DEFFileError(UNRECOGNIZEDTOKEN,iFileName,LineNum,lineToken+i);
+			}
+
+			if(entryFlag==true)
+			{
+				strncpy(entryType, ptrEntryType, width);
+				entryType[width]='\0';
+
+				switch(ptrEntryType[0])
+				{
+				case 'E':		// check for multi-line sections starting
+					strcpy(MultiLineStatement, STRUPR(entryType)); // Uppercase token
+					NAMEorLIBRARYallowed = false;
+					lineToken = strtok(NULL, "\n" ); // Get the next line
+					continue;
+				case 'N':
+					break;
+				case 'L':
+					break;
+				case 'D':
+					break;
+				case 'S':
+				case 'V':
+					if(entryType[1]!='E')
+					{
+						// set MULTI-LINE statement to OFF
+						strcpy(MultiLineStatement, STRUPR(entryType)); // Uppercase token
+						// check single-line statements are specified correctly
+						// check NAME or LIBRARY statements aren't supplied incorrectly
+						if (!strcmp(entryType, "NAME") ||
+							!strcmp(entryType, "LIBRARY")
+							)
+						{
+							if (NAMEorLIBRARYallowed == false)
+							{
+								throw DEFFileError(NAMELIBRARYNOTCORRECT,iFileName,LineNum,lineToken);
+							}
+							lineToken=strtok(NULL,"\n");
+							continue;
+						}
+						NAMEorLIBRARYallowed = false;
+						lineToken=strtok(NULL,"\n");
+						continue;
+					}
+					continue;
+				case 'I':
+					strcpy(MultiLineStatement, STRUPR(entryType)); // Uppercase token
+					lineToken = strtok(NULL, "\n" ); // Get the next line
+					continue;
+				}
+			}
+
+		}
+		else
+		{
+			if (!strcmp(MultiLineStatement,""))
+		    {
+				throw DEFFileError(EXPORTSEXPECTED,iFileName,LineNum,lineToken);
+			}
+		}	
+			
+		// Get Export entries
+		if (!strcmp(MultiLineStatement,"EXPORTS"))
+		{
+			Symbol aSymbol(NULL, SymbolTypeCode);
+			if( Tokenize(lineToken, LineNum, aSymbol) )
+			{
+				Symbol *newSymbolEntry = new Symbol(aSymbol);
+				iSymbolList->push_back(newSymbolEntry);
+
+				ordinalNo = aSymbol.OrdNum();
+				//Check for ordinal sequence
+				if (ordinalNo != PreviousOrdinal+1)
+		   		{
+					throw DEFFileError(ORDINALSEQUENCEERROR,iFileName,LineNum,(char*)aSymbol.SymbolName());
+				}
+
+				PreviousOrdinal = ordinalNo;
+
+			}
+			lineToken=strtok(NULL,"\n");
+			continue;
+		}
+		else if(strcmp(MultiLineStatement,"")!=0)//For entry other than exports
+			lineToken = strtok(NULL, "\n" ); // Get the next line
+
+	}//End of while
+}
+
+/**
+This Function calls LineToken's Tokenize function.
+@param aTokens   - Input string at the current line number
+@param aLineNum  - Current line number
+@param aSymbol   - Symbol to be populated while parsing the line.
+Return value     - It returns true if a valid def file entry is found.
+@internalComponent
+@released
+*/
+bool DefFile::Tokenize(char* aTokens, int aLineNum, Symbol& aSymbol)
+{
+	/*
+	 * Pattern to match is:
+	 * START\s*(\S+)\s+@\s*(d+)\s*(NONAME)?\s*(R3UNUSED)?\s*(ABSENT)?\s*(;\s*(.*))END
+	 */
+	LineToken aLine(iFileName, aLineNum, aTokens, &aSymbol);
+	return aLine.Tokenize();
+}
+
+
+char * DefFilePatterns[] =
+	{
+		"NONAME",//index 0
+		"DATA",
+		"R3UNUSED",
+		"ABSENT"
+	};
+
+#define DEF_NONAME		0
+#define DEF_DATA		1
+#define DEF_R3UNUSED	2
+#define DEF_ABSENT		3
+
+/**
+This constructor creates an instance of LineToken class.
+@param aFileName - Def File Name.
+@param aLineNum  - Current line number
+@param aLn       - Input string at the current line number
+@param aSym      - Symbol to be populated while parsing the line.
+@internalComponent
+@released
+*/
+LineToken::LineToken(char* aFileName, int aLineNum, char *aLn, Symbol* aSym) : \
+		iLine(aLn) , iSymbol(aSym) , iOffset(0), iState(EInitState),iFileName(aFileName), iLineNum(aLineNum) 
+{
+}
+
+/**
+This function tokenizes the line and populates a symbol entry 
+if there is one.
+Return Value - True, if the current line has a valid def entry.
+@internalComponent
+@released
+*/
+bool LineToken::Tokenize()
+{
+	while (1) 
+	{
+		switch( iState )
+		{
+		case EFinalState:
+			return true;
+		case EInitState:
+			if( *(iLine + iOffset) == '\0' || 
+				*(iLine + iOffset) == '\r' || 
+				*(iLine + iOffset) == '\n')
+			{
+				/*
+				 * Skip empty lines.
+				 */
+				return false;
+			}
+			else
+			{
+				NextToken();
+			}
+			break;
+		default:
+			NextToken();
+			break;
+		}
+	}
+	return false;
+}
+
+/**
+This function parses a line of the def file based on the current 
+state it is in.
+@internalComponent
+@released
+*/
+void LineToken::NextToken()
+{
+	int aCurrentPos = 0;
+	char *aSymbolName;
+
+	switch( iState )
+	{
+	case EInitState:
+		if(IsWhiteSpace((iLine + iOffset), aCurrentPos))
+		{
+			IncrOffset(aCurrentPos);
+		}
+
+		if(IsWord(iLine + iOffset, aCurrentPos))
+		{
+			SetState(ESymbolName);
+		}
+	break;
+
+	case ESymbolName:
+	{
+		// Get the length of the symbol
+		IsWord(iLine + iOffset, aCurrentPos);
+
+		char *cmt = strchr(iLine + iOffset, ';');
+		char *aAlias = strchr(iLine + iOffset, '=');
+
+		if( aAlias && (!cmt || (aAlias < cmt)) )
+		{
+			int aAliasPos = aAlias - (iLine+ iOffset);
+
+			//Check if alias name is also supplied, they should be separated 
+			// by whitespace, i.e., SymbolName=AliasName is valid while, 
+			// SymbolName =AliasName is invalid.
+			if( aAliasPos > aCurrentPos)
+			{
+				char *aToken = (iLine + iOffset + aCurrentPos);
+				throw DEFFileError(UNRECOGNIZEDTOKEN, iFileName, iLineNum, aToken);
+			}
+
+			aSymbolName = new char[aAliasPos+1];
+			strncpy(aSymbolName, iLine + iOffset, aAliasPos);
+			aSymbolName[aAliasPos] = '\0';
+			char *aExportName = new char[aCurrentPos - aAliasPos + 1];
+			strncpy(aExportName, aAlias +1, (aCurrentPos - aAliasPos));
+			aExportName[(aCurrentPos - aAliasPos)] = '\0';
+			iSymbol->ExportName(aExportName);
+		}
+		else
+		{
+			aSymbolName = new char[aCurrentPos+1];
+			strncpy(aSymbolName, iLine+ iOffset, aCurrentPos);
+			aSymbolName[aCurrentPos] = '\0';
+		}
+		iSymbol->SymbolName(aSymbolName);
+		
+		IncrOffset(aCurrentPos);
+
+		if(IsWhiteSpace((iLine + iOffset), aCurrentPos))
+		{
+			IncrOffset(aCurrentPos);
+		}
+		
+		if(*(iLine+iOffset) == '@')
+		{
+			SetState(EAtSymbol);
+			IncrOffset(1);
+		}
+		else
+		{
+			/*
+			 * The first non-whitespace entry in a line is assumed to be the 
+			 * symbol name and a symbol name might also have a '@' char. Hence
+			 * there MUST be a whitespace between symbol name and '@'.
+			 */
+			throw DEFFileError(ATRATEMISSING,iFileName,iLineNum,(iLine+iOffset));
+		}
+	}
+	break;
+
+	case EAtSymbol:
+		if(IsWhiteSpace((iLine + iOffset), aCurrentPos))
+		{
+			IncrOffset(aCurrentPos);
+		}
+		
+		SetState(EOrdinal);
+		break;
+	case EOrdinal:
+	{
+		if(!IsDigit(iLine+iOffset, aCurrentPos ) )
+		{
+			throw DEFFileError(ORDINALNOTANUMBER, iFileName, iLineNum, (iLine+iOffset));
+		}
+		char aTmp[32];
+		strncpy(aTmp, iLine+iOffset, aCurrentPos);
+		aTmp[aCurrentPos] = '\0';
+		int aOrdinal = atoi(aTmp);
+		iSymbol->SetOrdinal(aOrdinal);
+
+		IncrOffset(aCurrentPos);
+
+		if(IsWhiteSpace((iLine + iOffset), aCurrentPos))
+		{
+			IncrOffset(aCurrentPos);
+		}
+		SetState(EOptionals);
+	}
+	break;
+
+	case EOptionals:
+		{
+		int aPrevPatternIndex, aPatternIdx = 0;
+		aPrevPatternIndex = -1;
+		while (*(iLine + iOffset) != '\n' || *(iLine + iOffset) != '\r')
+		{
+			if(IsPattern(iLine+iOffset, aCurrentPos, aPatternIdx) )
+			{
+				switch(aPatternIdx)
+				{
+				case DEF_NONAME:
+					break;
+				case DEF_DATA:
+					iSymbol->CodeDataType(SymbolTypeData);
+
+					IncrOffset(aCurrentPos);
+					if(IsWhiteSpace((iLine + iOffset), aCurrentPos))
+					{
+						IncrOffset(aCurrentPos);
+					}
+					if(IsDigit(iLine+iOffset, aCurrentPos ) )
+					{
+						char aSymSz[16];
+						strncpy(aSymSz, (iLine + iOffset), aCurrentPos);
+						aSymSz[aCurrentPos] = '\0';
+						iSymbol->SetSymbolSize(atoi(aSymSz));
+					}
+					break;
+				case DEF_R3UNUSED:
+					iSymbol->R3Unused(true);
+					break;
+				case DEF_ABSENT:
+					iSymbol->SetAbsent(true);
+					break;
+				default:
+					break;
+				}
+
+				/*
+				 * NONAME , DATA, R3UNUSED and ABSENT, all the 3 are optional. But, if more than
+				 * one of them appear, they MUST appear in that order. 
+				 * Else, it is not accepted.
+				 */
+				if( aPrevPatternIndex >= aPatternIdx)
+				{
+					throw DEFFileError(UNRECOGNIZEDTOKEN, iFileName, iLineNum,(iLine + iOffset));
+				}
+				aPrevPatternIndex = aPatternIdx;
+
+				IncrOffset(aCurrentPos);
+				
+				if(IsWhiteSpace((iLine + iOffset), aCurrentPos))
+				{
+					IncrOffset(aCurrentPos);
+				}
+			}
+			else
+			{
+				if( *(iLine + iOffset) == ';' )
+				{
+					SetState(EComment);
+					IncrOffset(1);
+					return;
+				}
+				else if( *(iLine + iOffset) == '\0' || 
+						 *(iLine + iOffset) == '\r' || 
+						 *(iLine + iOffset) == '\n')
+				{
+					SetState(EFinalState);
+					return;
+				}
+				else
+				{
+					throw DEFFileError(UNRECOGNIZEDTOKEN, iFileName, iLineNum,(iLine + iOffset));
+				}
+			}
+		}
+		}
+	break;
+
+	case EComment:
+	{
+		if(IsWhiteSpace(iLine + iOffset, aCurrentPos))
+		{
+			IncrOffset(aCurrentPos);
+		}
+		
+	
+		int aLen = strlen(iLine + iOffset);
+		if( *(iLine + iOffset + aLen - 1 ) == '\n' ||  *(iLine + iOffset + aLen - 1 ) == '\r')
+			aLen -=1;
+
+		char * aComment = new char[ aLen + 1];
+		strncpy( aComment, iLine + iOffset, aLen);
+		aComment[aLen] = '\0';
+
+		IncrOffset(aLen);
+
+		iSymbol->Comment(aComment);
+		SetState(EFinalState);
+	}
+	break;
+
+	case EFinalState:
+		return;
+	default:
+		break;	
+	}
+}
+
+/**
+This function returns true if the string starts with one
+of the fixed patterns.
+It also updates the length  and index of this pattern.
+@param aChar - Line Token
+@param aTill - Length of the pattern
+@param aTill - Index of the pattern
+Return Value - True, if the string starts with one of the patterns.
+@internalComponent
+@released
+*/
+bool LineToken::IsPattern(char* aStr, int& aTill, int& aIndex)
+{
+	int pos = 0;
+	int aLength;
+	int size = sizeof(DefFilePatterns)/sizeof(char*);
+	while(size > pos)
+	{
+		aLength = strlen(DefFilePatterns[pos]);
+		if(!strncmp(aStr, DefFilePatterns[pos], aLength))
+		{
+			aTill = aLength;
+			aIndex = pos;
+			return true;
+		}
+		pos++;
+	}
+	return false;
+}
+
+/**
+This function returns true if the string starts with digits.
+It also updates the length of this digit string.
+@param aChar - Line Token
+@param aTill - Length of the digit string
+Return Value - True, if the string starts with digit(s)
+@internalComponent
+@released
+*/
+bool LineToken::IsDigit(char *aChar, int &aTill)
+{
+	int pos = 0;
+	if( aChar[pos] - '0' >= 0 &&  aChar[pos] - '0' <= 9)
+	{
+		pos++;
+		while(aChar[pos] - '0' >= 0 &&  aChar[pos] - '0' <= 9)
+		{
+			pos++;
+		}
+		aTill = pos;
+		return true;
+	}
+	else
+	{
+		return false;
+	}
+}
+
+/**
+This function returns true if the string starts with white space.
+It also updates the length of this white string!
+@param aStr - Line Token
+@param aTill - Length of the white string
+Return Value - True, if the string starts with whitespace
+@internalComponent
+@released
+*/
+bool LineToken::IsWhiteSpace(char *aStr, int &aTill)
+{
+	int pos = 0;
+	switch( aStr[pos] )
+	{
+	case ' ':
+	case '\t':
+		break;
+	default:
+		return false;
+	}
+
+	pos++;
+	while( aStr[pos])
+	{
+		switch(aStr[pos])
+		{
+			case ' ':
+			case '\t':
+				pos++;
+			break;
+			default:
+				aTill = pos;
+				return true;
+		}
+
+	}
+	aTill = pos;
+	return true;
+}
+
+/**
+This function returns true if the string starts with non-whitespace.
+It also updates the length of this word.
+@param aStr  - Line Token
+@param aTill - Length of the word
+Return Value - True, if the string starts with non-whitespace chars.
+It also updates the length of the word.
+@internalComponent
+@released
+*/
+bool LineToken::IsWord(char *aStr, int &aTill)
+{
+	int pos = 0;
+	switch( aStr[pos] )
+	{
+	case '\0':
+	case ' ':
+	case '\t':
+	case '\r':
+	case '\n':
+		return false;
+	default:
+		break;
+	}
+
+	pos++;
+	while( aStr[pos])
+	{
+		switch(aStr[pos])
+		{
+			case ' ':
+			case '\t':
+			case '\r':
+			case '\n':
+				aTill = pos;
+				return true;
+			default:
+				pos++;
+				break;
+		}
+
+	}
+	aTill = pos;
+	return true;
+}
+
+/**
+This function increments the current offset.
+@param aOff  - increment by this value
+@internalComponent
+@released
+*/
+void LineToken::IncrOffset(int aOff)
+{ 
+	iOffset += aOff;
+}
+
+/**
+This function sets the state of the tokenizer that is parsing 
+the line.
+@param aState  - next state
+@internalComponent
+@released
+*/
+void LineToken::SetState(DefStates aState)
+{
+	iState = aState;
+}
+
+/**
+Function to Read def file and get the internal representation in structure.
+@param defFile - DEF File name
+@internalComponent
+@released
+*/
+SymbolList* DefFile::ReadDefFile(char *defFile)
+{
+	char *defFileEntries;
+
+	defFileEntries=OpenDefFile(defFile);
+	ParseDefFile(defFileEntries);
+
+	delete [] defFileEntries;//Free the memory which was required to read def file
+
+	return iSymbolList;
+
+}
+
+/**
+Function to get the internal representation of Def File.
+@param defFile - DEF File name
+@internalComponent
+@released
+*/
+SymbolList* DefFile::GetSymbolEntryList(char *defFile)
+{
+	if(iSymbolList)
+	{
+		return iSymbolList;
+	}
+	else
+	{
+		iSymbolList=ReadDefFile(defFile);
+		return iSymbolList;
+	}
+
+}
+
+/**
+Function to write DEF file from symbol entry List.
+@param fileName - Def file name
+@param newSymbolList - pointer to SymbolList which we get as an input for writing in DEF File
+@internalComponent
+@released
+*/
+void DefFile::WriteDefFile(char *fileName, SymbolList * newSymbolList)
+{
+
+	char ordinal[6];
+	int newDefEntry=0;
+	FILE *fptr;
+
+	if((fptr=fopen(fileName,"wb"))==NULL)
+	{
+		throw FileError(FILEOPENERROR,fileName);
+	}
+	else
+	{
+		SymbolList::iterator aItr = newSymbolList->begin();
+		SymbolList::iterator last = newSymbolList->end();
+		Symbol *aSym;
+
+		fputs("EXPORTS",fptr);
+		fputs("\r\n",fptr);
+		while( aItr != last)
+		{
+			aSym = *aItr;
+			//Do not write now if its a new entry
+			if(aSym->GetSymbolStatus()==New)
+			{
+				newDefEntry=1;
+				aItr++;
+				continue;
+			}
+
+			//Make it comment if its missing def entry
+			if(aSym->GetSymbolStatus()==Missing)
+				fputs("; MISSING:",fptr);
+
+			fputs("\t",fptr);
+			if((aSym->ExportName()) && strcmp(aSym->SymbolName(),aSym->ExportName())!=0)
+			{
+				fputs(aSym->ExportName(),fptr);
+				fputs("=",fptr);
+			}
+			fputs(aSym->SymbolName(),fptr);
+			fputs(" @ ",fptr);
+			sprintf(ordinal,"%d",aSym->OrdNum());
+			fputs(ordinal,fptr);
+			fputs(" NONAME",fptr);
+			if(aSym->CodeDataType()==SymbolTypeData) {
+				fputs(" DATA",fptr);
+				fputs(" ",fptr);
+				char aSymSize[16];
+				sprintf(aSymSize, "%d", aSym->SymbolSize());
+				fputs(aSymSize,fptr);
+			}
+			if(aSym->R3unused())
+				fputs(" R3UNUSED",fptr);
+			if(aSym->Absent())
+				fputs(" ABSENT",fptr);
+				
+			if(aSym->Comment()!=NULL)
+			{
+				fputs(" ; ",fptr);
+				fputs(aSym->Comment(),fptr);
+			}
+			fputs("\r\n",fptr);
+			aItr++;
+		}
+
+		//This is for writing new def entry in DEF File
+		if(newDefEntry)
+		{
+			fputs("; NEW:",fptr);
+			fputs("\r\n",fptr);
+			aItr = newSymbolList->begin();
+			last = newSymbolList->end();
+
+			while( aItr != last)
+			{
+				aSym = *aItr;
+				if(aSym->GetSymbolStatus()!=New)
+				{
+					aItr++;
+					continue;
+				}
+				fputs("\t",fptr);
+				if((aSym->ExportName()) && strcmp(aSym->SymbolName(),aSym->ExportName())!=0)
+				{
+					fputs(aSym->ExportName(),fptr);
+					fputs("=",fptr);
+				}
+				fputs(aSym->SymbolName(),fptr);
+				fputs(" @ ",fptr);
+				sprintf(ordinal,"%d",aSym->OrdNum());
+				fputs(ordinal,fptr);
+				fputs(" NONAME",fptr);
+
+				if(aSym->CodeDataType()==SymbolTypeData) {
+					fputs(" DATA",fptr);
+					fputs(" ",fptr);
+					char aSymSize[16];
+					sprintf(aSymSize, "%d", aSym->SymbolSize());
+					fputs(aSymSize,fptr);
+				}
+
+				if(aSym->R3unused())
+					fputs(" R3UNUSED",fptr);
+				if(aSym->Absent())
+					fputs(" ABSENT",fptr);
+
+				if(aSym->Comment()!=NULL)
+				{
+					if(aSym->CodeDataType()!=SymbolTypeCode &&
+						aSym->CodeDataType()!=SymbolTypeData)
+					{
+						fputs(" ; ",fptr);
+						fputs(aSym->Comment(),fptr);
+					}
+					else
+					{
+						fputs(" ",fptr);
+						fputs(aSym->Comment(),fptr);
+					}
+				}
+				fputs("\r\n",fptr);
+				aItr++;
+			}
+		}
+		fputs("\r\n",fptr);
+		fclose(fptr);
+	}
+}