Add --asm option to elf2e32, so that GCCE builds can use --asm=gas with --dump=a and get a usable .s file (Bug 1405)
// 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:
// Message Implementation Operations for elf2e32 tool
// @internalComponent
// @released
//
//
#include "messageimplementation.h"
#include "errorhandler.h"
#include<iostream>
#include<stdarg.h>
#include<string>
#include <stdio.h>
using std::endl;
using std::cout;
typedef std::string String;
char *errorMssgPrefix="elf2e32 : Error: E";
char *warnMssgPrefix="elf2e32 : Warning: W";
char *infoMssgPrefix="elf2e32 : Information: I";
char *colSpace=": ";
enum MessageArraySize{MAX=66};
//Messages stored required for the program
struct EnglishMessage MessageArray[MAX]=
{
{FILEOPENERROR,"Could not open file : %s."},
{FILEREADERROR,"Could not read file : %s."},
{FILEWRITEERROR,"Could not write file : %s."},
{ELFMAGICERROR,"Invalid ELF magic in file : %s."},
{ELFCLASSERROR,"ELF file %s is not 32 bit."},
{ELFABIVERSIONERROR,"ELF file %s is not BPABI conformant."},
{ELFLEERROR,"ELF file %s is not Little Endian."},
{ELFARMERROR,"ELF file %s does not target ARM."},
{ELFEXECUTABLEERROR,"ELF file %s is neither executable (ET_EXEC) or shared (ET_DYN)."},
{ELFSHSTRINDEXERROR,"Error in ELF Section Header String Index : %s."},
{NAMELIBRARYNOTCORRECT,"Name or Library not supplied correctly : %s[Line No=%d][%s]"},
{ORDINALSEQUENCEERROR,"Ordinal number is not in sequence : %s[Line No=%d][%s]."},
{ARGUMENTNAMEERROR,"Argument %s is not correct."},
{OPTIONNAMEERROR,"Option %s is Unrecognized."},
{NOARGUMENTERROR,"Missing arguments for option : %s."},
{OPTIONPREFIXERROR,"Option %s is neither preceedded by '-' nor '--'."},
{NOREQUIREDOPTIONERROR,"Missing options : %s."},
{NOFILENAMEERROR,"Missing argument for option : %s."},
{INVALIDARGUMENTERROR,"Argument '%s' not permitted for option %s."},
{HUFFMANBUFFEROVERFLOWERROR,"Huffman buffer overflow during E32Image compression."},
{HUFFMANTOOMANYCODESERROR,"Too many Huffman codes during E32Image compression."},
{HUFFMANINVALIDCODINGERROR,"Invalid Huffman coding during E32Image compression."},
{CAPABILITYALLINVERSIONERROR,"-ALL not a valid capability."},
{CAPABILITYNONEINVERSIONERROR,"+NONE not a valid capability."},
{UNRECOGNISEDCAPABILITYERROR,"Unrecognized capability : %s."},
{NOSTATICSYMBOLSERROR,"ELF File %s contains no static symbols."},
{DLLHASINITIALISEDDATAERROR,"ELF File %s contains initialized writable data."},
{DLLHASUNINITIALISEDDATAERROR,"ELF File %s contains uninitialized writable data."},
{ENTRYPOINTCORRUPTERROR,"ELF File %s has corrupt entry point."},
{ENTRYPOINTNOTSUPPORTEDERROR,"ELF File %s has unsupported entry point type."},
{EXCEPTIONDESCRIPTOROUTSIDEROERROR,"ELF File %s has invalid exception descriptor."},
{NOEXCEPTIONDESCRIPTORERROR,"ELF File %s has no exception descriptor."},
{NEEDSECTIONVIEWERROR,"ELF File %s has no section headers."},
{DSONOTFOUNDERROR,"DSO %s not found."},
{UNDEFINEDSYMBOLERROR,"Undefined Symbol %s found in ELF File %s."},
{SYMBOLMISSINGFROMELFERROR,"Symbol %s Missing from ELF File : %s."},
{MEMORYALLOCATIONERROR,"Memory allocation failure : %s."},
{E32IMAGEERROR,"Not able to write E32 Image file."},
{INVALIDINVOCATIONERROR,"Invalid invocation of elf2e32."},
{TARGETTYPENOTSPECIFIEDERROR,"Target Type Not Specified."},
{UNSUPPORTEDTARGETTYPEERROR,"Unsupported Target Type '%s'."},
{INDEXNOMESSAGEERROR,"There is no message for the message index[%d]."},
{INDEXNOTREQUIREDERROR,"Message index[%d] not required in message file."},
{INDEXNOTFOUNDERROR,"Message index [%d] not found in message file"},
{NOMESSAGEFILEERROR,"There is no message file."},
{ENTRYPOINTNOTSETERROR,"Entry point is not set for %s."},
{UNDEFINEDENTRYPOINTERROR,"Entry point and Text segment base both 0, can't tell if entry point set for %s."},
{ORDINALNOTANUMBER,"Ordinal not a Number : %s[Line No=%d][%s]."},
{UNRECOGNIZEDTOKEN,"Unrecognized Token : %s[Line No=%d][%s]."},
{NONAMEMISSING,"NONAME Missing : %s[Line No=%d][%s]."},
{EXPORTSEXPECTED,"EXPORTS expected before first export entry : %s[Line No=%d][%s]."},
{ATRATEMISSING,"@ Missing : %s[Line No=%d][%s]."},
{SYSDEFSMISMATCHERROR,"Symbol %s passed through '--sysdef' option is not at the specified ordinal in the DEF file %s."},
{SYSDEFERROR,"Ordinal number is not provided as input to the option: %s"},
{INVALIDE32IMAGEERROR,"%s is not a valid E32Image file."},
{HUFFMANBUFFERUNDERFLOWERROR,"Huffman buffer underflow on deflate."},
{HUFFMANINCONSISTENTSIZEERROR,"Inconsistent sizes discovered during uncompression."},
{MULTIPLESYSDEFERROR, "Multiple system definitions passed to %s should be separated by ';'"},
{SYSDEFNOSYMBOLERROR, "Symbol Name is not provided as input to the option: %s"},
{VALUEIGNOREDWARNING, "Value passed to '%s' is ignored"},
{ELFFILEERROR,"Error while processing the ELF file %s."},
{SYMBOLCOUNTMISMATCHERROR, "Symbol count provided by DT_ARM_SYMTABSZ is not same as that in the Hash Table in %s"},
{POSTLINKERERROR,"Fatal Error in Postlinker"},
{BYTEPAIRINCONSISTENTSIZEERROR, "Inconsistent sizes discovered during Byte pair uncompression." },
{ILLEGALEXPORTFROMDATASEGMENT,"'%s' : '%s' Import relocation does not refer to code segment."},
{VALIDATIONERROR,"Image failed validation"}
};
/**
Constructor to reset the logging option flag.
@internalComponent
@released
*/
MessageImplementation::MessageImplementation()
{
iLogging = false;
}
/**
Destructor to close log file if logging is enabled and to clear the messaged.
@internalComponent
@released
*/
MessageImplementation::~MessageImplementation()
{
if(iLogging)
{
fclose(iLogPtr);
}
iMessage.clear();
}
/**
Function to Get Message stored in map.
@internalComponent
@released
@param aMessageIndex
Index of the Message to be displayed
@return Message string to be displayed
*/
char * MessageImplementation::GetMessageString(int aMessageIndex)
{
Map::iterator p;
if(iMessage.empty())
{
if(aMessageIndex <= MAX)
{
return MessageArray[aMessageIndex-1].message;
}
else
{
return NULL;
}
}
else
{
p=iMessage.find(aMessageIndex);
if(p == iMessage.end())
{
if(aMessageIndex <= MAX)
{
return MessageArray[aMessageIndex-1].message;
}
else
{
return NULL;
}
}
if(aMessageIndex <= MAX)
{
return p->second;
}
else
{
return NULL;
}
}
}
/**
Function to display output and log message in log file if logging is enable.
@internalComponent
@released
@param aString
Message to be displayed
*/
void MessageImplementation::Output(const char *aString)
{
if (iLogging)
{
fputs(aString,iLogPtr);
fputs("\n",iLogPtr);
}
cout << aString << endl;
}
/**
Function to Get Message stored in map and to display the Message
@internalComponent
@released
@param
The type of the message, whether it is Error or Warning or Information.
@param
The index of the information and the corresponding arguments.
*/
void MessageImplementation::ReportMessage(int aMessageType, int aMsgIndex,...)
{
char *reportMessage, *ptr, *tmpMessage;
char intStr[16];
char mssgNo[MAXMSSGNOLENGTH];
int mssgIndex,k;
va_list ap;
va_start(ap,aMsgIndex);
reportMessage=GetMessageString(aMsgIndex);
if(reportMessage)
{
String message;
switch (aMessageType)
{
case ERROR:
message = errorMssgPrefix;
break;
case WARNING:
message = warnMssgPrefix;
break;
case INFORMATION:
message = infoMssgPrefix;
break;
}
mssgIndex = BASEMSSGNO + aMsgIndex;
sprintf(mssgNo,"%d",mssgIndex);
message += mssgNo;
message += colSpace;
ptr = strchr(reportMessage,'%');
while( ptr != NULL && (ptr[0]) == '%' )
{
tmpMessage=new char[ptr - reportMessage + 1];
strncpy(tmpMessage, reportMessage, ptr - reportMessage+1);
tmpMessage[ptr - reportMessage]='\0';
message += tmpMessage;
delete tmpMessage;
ptr++;
switch(ptr[0])
{
case 'd':
k = va_arg(ap, int);
sprintf(intStr,"%d",k);
message += intStr;
ptr++;
reportMessage = ptr;
break;
case 's':
message += va_arg(ap, char *);
ptr++;
reportMessage = ptr;
break;
case '%':
message += ptr[0];
reportMessage = ptr;
default:
break;
}
ptr=strchr(reportMessage,'%');
}
message += reportMessage;
Output(message.c_str());
}
}
/**
Function to start logging.
@internalComponent
@released
@param aFileName
Name of the Log file
*/
void MessageImplementation::StartLogging(char *aFileName)
{
char logFile[1024];
FILE *fptr;
strcpy(logFile,aFileName);
// open file for log etc.
if((fptr=fopen(logFile,"w"))==NULL)
{
ReportMessage(WARNING, FILEOPENERROR,aFileName);
}
else
{
iLogging = true;
iLogPtr=fptr;
}
}
/**
Function to Create Messages file.
@internalComponent
@released
@param aFileName
Name of the Message file to be dumped
*/
void MessageImplementation::CreateMessageFile(char *aFileName)
{
int i;
FILE *fptr;
// open file for writing messages.
if((fptr=fopen(aFileName,"w"))==NULL)
{
ReportMessage(WARNING, FILEOPENERROR,aFileName);
}
else
{
for(i=0;i<MAX;i++)
{
fprintf(fptr,"%d,%s\n",i+1,MessageArray[i].message);
}
fclose(fptr);
}
}
/**
Function to put Message string in map which is stored in message file.
If file is not available the put message in map from Message Array structure.
@internalComponent
@released
@param aFileName
Name of the Message file passed in
*/
void MessageImplementation::InitializeMessages(char *aFileName)
{
char index[16];
char *message, *errStr;
int i, lineLength;
int fileSize;
char *messageEntries, *lineToken;
FILE *fptr;
if(aFileName && (fptr=fopen(aFileName,"rb"))!=NULL)
{
iMessage.clear();
//Getting File size
fseek(fptr, 0, SEEK_END);
fileSize=ftell(fptr);
rewind(fptr);
messageEntries= new char[fileSize+2];
//Getting whole file in memory
fread(messageEntries, fileSize, 1, fptr);
//Adding ENTER at end
*(messageEntries+fileSize)='\n';
//Adding '\0' at end
*(messageEntries+fileSize+1)='\0';
fclose(fptr);
lineToken=strtok(messageEntries,"\n");
while(lineToken != NULL)
{
if( lineToken[0] == '\n' || lineToken[0] == '\r' )
{
lineToken=strtok(NULL,"\n");
continue;
}
lineLength=strlen(lineToken);
if( lineToken[strlen(lineToken)-1] == '\r' )
{
lineToken[strlen(lineToken)-1]='\0';
}
message=strchr(lineToken,',');
strncpy(index,lineToken,message-lineToken);
index[message-lineToken]='\0';
errStr = new char[strlen(message+1) + 1];
strcpy(errStr, (message+1));
iMessage.insert(std::pair<int,char*>(atoi(index),errStr));
lineToken=strtok(lineToken+lineLength+1,"\n");
}
delete messageEntries;
}
else
{
for(i=0;i<MAX;i++)
{
errStr = new char[strlen(MessageArray[i].message) + 1];
strcpy(errStr, MessageArray[i].message);
iMessage.insert(std::pair<int,char*>(MessageArray[i].index,errStr));
}
}
}