e32tools/elf2e32/source/messageimplementation.cpp
changeset 0 044383f39525
equal deleted inserted replaced
-1:000000000000 0:044383f39525
       
     1 // Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // Message Implementation Operations for elf2e32 tool
       
    15 // @internalComponent
       
    16 // @released
       
    17 // 
       
    18 //
       
    19 
       
    20 
       
    21 #include "messageimplementation.h"
       
    22 #include "errorhandler.h"
       
    23 #include<iostream>
       
    24 #include<stdarg.h>
       
    25 #include<string>
       
    26 #include <stdio.h>
       
    27 
       
    28 using std::endl;
       
    29 using std::cout;
       
    30 typedef std::string String;
       
    31 
       
    32 char *errorMssgPrefix="elf2e32 : Error: E";
       
    33 char *warnMssgPrefix="elf2e32 : Warning: W";
       
    34 char *infoMssgPrefix="elf2e32 : Information: I";
       
    35 char *colSpace=": ";
       
    36 
       
    37 enum MessageArraySize{MAX=66};
       
    38 
       
    39 //Messages stored required for the program
       
    40 struct EnglishMessage MessageArray[MAX]=
       
    41 {
       
    42 	{FILEOPENERROR,"Could not open file : %s."},
       
    43 	{FILEREADERROR,"Could not read file : %s."},
       
    44 	{FILEWRITEERROR,"Could not write file : %s."},
       
    45 	{ELFMAGICERROR,"Invalid ELF magic in file : %s."},
       
    46 	{ELFCLASSERROR,"ELF file %s is not 32 bit."},
       
    47 	{ELFABIVERSIONERROR,"ELF file %s is not BPABI conformant."},
       
    48 	{ELFLEERROR,"ELF file %s is not Little Endian."},
       
    49 	{ELFARMERROR,"ELF file %s does not target ARM."},
       
    50 	{ELFEXECUTABLEERROR,"ELF file %s is neither executable (ET_EXEC) or shared (ET_DYN)."},
       
    51 	{ELFSHSTRINDEXERROR,"Error in ELF Section Header String Index : %s."},
       
    52 	{NAMELIBRARYNOTCORRECT,"Name or Library not supplied correctly : %s[Line No=%d][%s]"},
       
    53 	{ORDINALSEQUENCEERROR,"Ordinal number is not in sequence : %s[Line No=%d][%s]."},
       
    54 	{ARGUMENTNAMEERROR,"Argument %s is not correct."},
       
    55 	{OPTIONNAMEERROR,"Option %s is Unrecognized."},
       
    56 	{NOARGUMENTERROR,"Missing arguments for option : %s."},
       
    57 	{OPTIONPREFIXERROR,"Option %s is neither preceedded by '-' nor '--'."},
       
    58 	{NOREQUIREDOPTIONERROR,"Missing options : %s."},
       
    59 	{NOFILENAMEERROR,"Missing argument for option : %s."},
       
    60 	{INVALIDARGUMENTERROR,"Argument '%s' not permitted for option %s."},
       
    61 	{HUFFMANBUFFEROVERFLOWERROR,"Huffman buffer overflow during E32Image compression."},
       
    62 	{HUFFMANTOOMANYCODESERROR,"Too many Huffman codes during E32Image compression."},
       
    63 	{HUFFMANINVALIDCODINGERROR,"Invalid Huffman coding during E32Image compression."},
       
    64 	{CAPABILITYALLINVERSIONERROR,"-ALL not a valid capability."},
       
    65 	{CAPABILITYNONEINVERSIONERROR,"+NONE not a valid capability."},
       
    66 	{UNRECOGNISEDCAPABILITYERROR,"Unrecognized capability : %s."},
       
    67 	{NOSTATICSYMBOLSERROR,"ELF File %s contains no static symbols."},
       
    68 	{DLLHASINITIALISEDDATAERROR,"ELF File %s contains initialized writable data."},
       
    69 	{DLLHASUNINITIALISEDDATAERROR,"ELF File %s contains uninitialized writable data."},
       
    70 	{ENTRYPOINTCORRUPTERROR,"ELF File %s has corrupt entry point."},
       
    71 	{ENTRYPOINTNOTSUPPORTEDERROR,"ELF File %s has unsupported entry point type."},
       
    72 	{EXCEPTIONDESCRIPTOROUTSIDEROERROR,"ELF File %s has invalid exception descriptor."},
       
    73 	{NOEXCEPTIONDESCRIPTORERROR,"ELF File %s has no exception descriptor."},
       
    74 	{NEEDSECTIONVIEWERROR,"ELF File %s has no section headers."},
       
    75 	{DSONOTFOUNDERROR,"DSO %s not found."},
       
    76 	{UNDEFINEDSYMBOLERROR,"Undefined Symbol %s found in ELF File %s."},
       
    77 	{SYMBOLMISSINGFROMELFERROR,"Symbol %s Missing from ELF File : %s."},
       
    78 	{MEMORYALLOCATIONERROR,"Memory allocation failure : %s."},
       
    79 	{E32IMAGEERROR,"Not able to write E32 Image file."},
       
    80 	{INVALIDINVOCATIONERROR,"Invalid invocation of elf2e32."},
       
    81 	{TARGETTYPENOTSPECIFIEDERROR,"Target Type Not Specified."},
       
    82 	{UNSUPPORTEDTARGETTYPEERROR,"Unsupported Target Type '%s'."},
       
    83 	{INDEXNOMESSAGEERROR,"There is no message for the message index[%d]."},
       
    84 	{INDEXNOTREQUIREDERROR,"Message index[%d] not required in message file."},
       
    85 	{INDEXNOTFOUNDERROR,"Message index [%d] not found in message file"},
       
    86 	{NOMESSAGEFILEERROR,"There is no message file."},
       
    87 	{ENTRYPOINTNOTSETERROR,"Entry point is not set for %s."},
       
    88 	{UNDEFINEDENTRYPOINTERROR,"Entry point and Text segment base both 0, can't tell if entry point set for %s."},
       
    89 	{ORDINALNOTANUMBER,"Ordinal not a Number : %s[Line No=%d][%s]."},
       
    90 	{UNRECOGNIZEDTOKEN,"Unrecognized Token : %s[Line No=%d][%s]."},
       
    91 	{NONAMEMISSING,"NONAME Missing : %s[Line No=%d][%s]."},
       
    92 	{EXPORTSEXPECTED,"EXPORTS expected before first export entry : %s[Line No=%d][%s]."},
       
    93 	{ATRATEMISSING,"@ Missing : %s[Line No=%d][%s]."},
       
    94 	{SYSDEFSMISMATCHERROR,"Symbol %s passed through '--sysdef' option is not at the specified ordinal in the DEF file %s."},
       
    95 	{SYSDEFERROR,"Ordinal number is not provided as input to the option: %s"},
       
    96 	{INVALIDE32IMAGEERROR,"%s is not a valid E32Image file."},
       
    97 	{HUFFMANBUFFERUNDERFLOWERROR,"Huffman buffer underflow on deflate."},
       
    98 	{HUFFMANINCONSISTENTSIZEERROR,"Inconsistent sizes discovered during uncompression."},
       
    99 	{MULTIPLESYSDEFERROR, "Multiple system definitions passed to %s should be separated by ';'"},
       
   100 	{SYSDEFNOSYMBOLERROR, "Symbol Name is not provided as input to the option: %s"},
       
   101 	{VALUEIGNOREDWARNING, "Value passed to '%s' is ignored"},
       
   102 	{ELFFILEERROR,"Error while processing the ELF file %s."},
       
   103 	{SYMBOLCOUNTMISMATCHERROR, "Symbol count provided by DT_ARM_SYMTABSZ is not same as that in the Hash Table in %s"},
       
   104 	{POSTLINKERERROR,"Fatal Error in Postlinker"},
       
   105 	{BYTEPAIRINCONSISTENTSIZEERROR, "Inconsistent sizes discovered during Byte pair uncompression." },
       
   106 	{ILLEGALEXPORTFROMDATASEGMENT,"'%s' : '%s' Import relocation does not refer to code segment."},
       
   107 	{VALIDATIONERROR,"Image failed validation"}
       
   108 };
       
   109 
       
   110 /**
       
   111 Constructor to reset the logging option flag.
       
   112 
       
   113 @internalComponent
       
   114 @released
       
   115 */
       
   116 MessageImplementation::MessageImplementation()
       
   117 {
       
   118     iLogging = false;
       
   119 }
       
   120 
       
   121 /**
       
   122 Destructor to close log file if logging is enabled and to clear the messaged.
       
   123 @internalComponent
       
   124 @released
       
   125 */
       
   126 MessageImplementation::~MessageImplementation()
       
   127 {
       
   128     if(iLogging)
       
   129     {
       
   130 		fclose(iLogPtr);
       
   131     }
       
   132 	iMessage.clear();
       
   133 }
       
   134 
       
   135 /**
       
   136 Function to Get Message stored in map.
       
   137 
       
   138 @internalComponent
       
   139 @released
       
   140 
       
   141 @param aMessageIndex
       
   142 Index of the Message to be displayed
       
   143 @return Message string to be displayed
       
   144 */
       
   145 char * MessageImplementation::GetMessageString(int aMessageIndex)
       
   146 {
       
   147 	Map::iterator p;
       
   148 
       
   149 	if(iMessage.empty())
       
   150 	{
       
   151 		if(aMessageIndex <= MAX)
       
   152 		{
       
   153 			return MessageArray[aMessageIndex-1].message;
       
   154 		}
       
   155 		else
       
   156 		{
       
   157 			return NULL;
       
   158 		}
       
   159 	}
       
   160 	else
       
   161 	{
       
   162 		p=iMessage.find(aMessageIndex);
       
   163 		if(p == iMessage.end())
       
   164 		{
       
   165 			if(aMessageIndex <= MAX)
       
   166 			{
       
   167 				return MessageArray[aMessageIndex-1].message;
       
   168 			}
       
   169 			else
       
   170 			{
       
   171 				return NULL;
       
   172 			}
       
   173 		}
       
   174 
       
   175 		if(aMessageIndex <= MAX)
       
   176 		{
       
   177 			return p->second;
       
   178 		}
       
   179 		else
       
   180 		{
       
   181 			return NULL;
       
   182 		}
       
   183 	}
       
   184 }
       
   185 
       
   186 /**
       
   187 Function to display output and log message in log file if logging is enable.
       
   188 
       
   189 @internalComponent
       
   190 @released
       
   191 
       
   192 @param aString
       
   193 Message to be displayed
       
   194 */
       
   195 void MessageImplementation::Output(const char *aString)
       
   196 {
       
   197 
       
   198     if (iLogging)
       
   199     {
       
   200 		fputs(aString,iLogPtr);
       
   201 		fputs("\n",iLogPtr);
       
   202     }
       
   203 	cout << aString << endl;
       
   204 }
       
   205 
       
   206 /**
       
   207 Function to Get Message stored in map and to display the Message
       
   208 
       
   209 @internalComponent
       
   210 @released
       
   211 
       
   212 @param
       
   213 The type of the message, whether it is Error or Warning or Information.
       
   214 @param
       
   215 The index of the information and the corresponding arguments.
       
   216 */
       
   217 void MessageImplementation::ReportMessage(int aMessageType, int aMsgIndex,...)
       
   218 {
       
   219 	char *reportMessage, *ptr, *tmpMessage;
       
   220 	char intStr[16];
       
   221 	char mssgNo[MAXMSSGNOLENGTH];
       
   222 	int mssgIndex,k;
       
   223 
       
   224 	va_list ap;
       
   225 	va_start(ap,aMsgIndex);
       
   226 	
       
   227 	reportMessage=GetMessageString(aMsgIndex);
       
   228 	
       
   229 	if(reportMessage)
       
   230 	{
       
   231 		String message;
       
   232 		switch (aMessageType)
       
   233 		{
       
   234 			case ERROR:
       
   235 				message = errorMssgPrefix;
       
   236 				break;
       
   237 			case WARNING:
       
   238 				message = warnMssgPrefix;
       
   239 				break;
       
   240 			case INFORMATION:
       
   241 				message = infoMssgPrefix;
       
   242 				break;
       
   243 		}
       
   244 		mssgIndex = BASEMSSGNO + aMsgIndex;
       
   245 		sprintf(mssgNo,"%d",mssgIndex);
       
   246 		message += mssgNo;
       
   247 		message += colSpace;
       
   248 
       
   249 		ptr = strchr(reportMessage,'%');
       
   250 
       
   251 		while( ptr != NULL && (ptr[0]) == '%' )
       
   252 		{
       
   253 			tmpMessage=new char[ptr - reportMessage + 1];
       
   254 			strncpy(tmpMessage, reportMessage, ptr - reportMessage+1);
       
   255 			tmpMessage[ptr - reportMessage]='\0';
       
   256 			message += tmpMessage;
       
   257 			delete tmpMessage;
       
   258 			ptr++;
       
   259 			switch(ptr[0])
       
   260 			{
       
   261 				case 'd':
       
   262 					k = va_arg(ap, int);
       
   263 					sprintf(intStr,"%d",k);
       
   264 					message += intStr;
       
   265 					ptr++;
       
   266 					reportMessage = ptr;
       
   267 					break;
       
   268 				case 's':
       
   269 					message += va_arg(ap, char *);
       
   270 					ptr++;
       
   271 					reportMessage = ptr;
       
   272 					break;
       
   273 				case '%':
       
   274 					message += ptr[0];
       
   275 					reportMessage = ptr;
       
   276 				default:
       
   277 					break;
       
   278 			}
       
   279 			ptr=strchr(reportMessage,'%');
       
   280 		}
       
   281 		message += reportMessage;
       
   282 		Output(message.c_str());
       
   283 	}
       
   284 }
       
   285 
       
   286 /**
       
   287 Function to start logging.
       
   288 
       
   289 @internalComponent
       
   290 @released
       
   291 
       
   292 @param aFileName
       
   293 Name of the Log file
       
   294 */
       
   295 void MessageImplementation::StartLogging(char *aFileName)
       
   296 {
       
   297 	char logFile[1024];
       
   298 	FILE *fptr;
       
   299 
       
   300 	strcpy(logFile,aFileName);
       
   301 
       
   302 	// open file for log etc.
       
   303 	if((fptr=fopen(logFile,"w"))==NULL)
       
   304 	{
       
   305 		ReportMessage(WARNING, FILEOPENERROR,aFileName);
       
   306 	}
       
   307 	else
       
   308 	{
       
   309 	    iLogging = true;
       
   310 		iLogPtr=fptr;
       
   311 	}
       
   312 }
       
   313 
       
   314 /**
       
   315 Function to Create Messages file.
       
   316 
       
   317 @internalComponent
       
   318 @released
       
   319 @param aFileName
       
   320 Name of the Message file to be dumped
       
   321 */
       
   322 void MessageImplementation::CreateMessageFile(char *aFileName)
       
   323 {
       
   324 	int i;
       
   325 	FILE *fptr;
       
   326 
       
   327 	// open file for writing messages.
       
   328 	if((fptr=fopen(aFileName,"w"))==NULL)
       
   329 	{
       
   330 		ReportMessage(WARNING, FILEOPENERROR,aFileName);
       
   331 	}
       
   332 	else
       
   333 	{
       
   334 		for(i=0;i<MAX;i++)
       
   335 		{
       
   336 			fprintf(fptr,"%d,%s\n",i+1,MessageArray[i].message);
       
   337 		}
       
   338 			
       
   339 		fclose(fptr);
       
   340 	}
       
   341 
       
   342 }
       
   343 
       
   344 /**
       
   345 Function to put Message string in map which is stored in message file.
       
   346 If file is not available the put message in map from Message Array structure.
       
   347 
       
   348 @internalComponent
       
   349 @released
       
   350 
       
   351 @param aFileName
       
   352 Name of the Message file passed in
       
   353 */
       
   354 void MessageImplementation::InitializeMessages(char *aFileName)
       
   355 {
       
   356 	char index[16];
       
   357 	char *message, *errStr;
       
   358 	int i, lineLength;
       
   359 	int fileSize;
       
   360 	char *messageEntries, *lineToken;
       
   361 
       
   362 	FILE *fptr;
       
   363 
       
   364 	if(aFileName && (fptr=fopen(aFileName,"rb"))!=NULL)
       
   365 	{
       
   366 
       
   367 		iMessage.clear();
       
   368 		//Getting File size
       
   369 		fseek(fptr, 0, SEEK_END);
       
   370 		fileSize=ftell(fptr);
       
   371 		rewind(fptr);
       
   372 
       
   373 		messageEntries= new char[fileSize+2];
       
   374 
       
   375 		//Getting whole file in memory
       
   376 		fread(messageEntries, fileSize, 1, fptr);
       
   377 
       
   378 		//Adding ENTER at end
       
   379 		*(messageEntries+fileSize)='\n';
       
   380 		//Adding '\0' at end
       
   381 		*(messageEntries+fileSize+1)='\0';
       
   382 
       
   383 		fclose(fptr);
       
   384 
       
   385 		lineToken=strtok(messageEntries,"\n");
       
   386 		while(lineToken != NULL)
       
   387 		{
       
   388 			if( lineToken[0] == '\n' || lineToken[0] == '\r' )
       
   389 			{
       
   390 				lineToken=strtok(NULL,"\n");
       
   391 				continue;
       
   392 			}
       
   393 
       
   394 			lineLength=strlen(lineToken);
       
   395 
       
   396 			if( lineToken[strlen(lineToken)-1] == '\r' )
       
   397 			{
       
   398 				lineToken[strlen(lineToken)-1]='\0';
       
   399 			}
       
   400 
       
   401 			message=strchr(lineToken,',');
       
   402 			strncpy(index,lineToken,message-lineToken);
       
   403 			index[message-lineToken]='\0';
       
   404 			errStr = new char[strlen(message+1) + 1];
       
   405 			strcpy(errStr, (message+1));
       
   406 			iMessage.insert(std::pair<int,char*>(atoi(index),errStr));
       
   407 
       
   408 			lineToken=strtok(lineToken+lineLength+1,"\n");
       
   409 		}
       
   410 
       
   411 		delete messageEntries;
       
   412 
       
   413 	}
       
   414 	else
       
   415 	{
       
   416 		for(i=0;i<MAX;i++)
       
   417 		{
       
   418 			errStr = new char[strlen(MessageArray[i].message) + 1];
       
   419 			strcpy(errStr, MessageArray[i].message);
       
   420 			iMessage.insert(std::pair<int,char*>(MessageArray[i].index,errStr));
       
   421 		}
       
   422 	}
       
   423 }
       
   424 
       
   425