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