os/kernelhwsrv/kerneltest/e32utils/analyse/symbols.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
// Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of the License "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
//
sl@0
    15
sl@0
    16
#include "analyse.h"
sl@0
    17
#include "symbols.h"
sl@0
    18
sl@0
    19
#ifdef __MSVCDOTNET__
sl@0
    20
#include <fstream>
sl@0
    21
#else //!__MSVCDOTNET__
sl@0
    22
#include <fstream.h>
sl@0
    23
#endif //__MSVCDOTNET__
sl@0
    24
sl@0
    25
namespace {
sl@0
    26
unsigned ParseHex(const char* aText, int aLength)
sl@0
    27
	{
sl@0
    28
	unsigned value = 0;
sl@0
    29
	const char* end = aText + aLength;
sl@0
    30
	do
sl@0
    31
		{
sl@0
    32
		unsigned c = *aText++ - '0';
sl@0
    33
		if (c > 9)
sl@0
    34
			c -= 'a' - '0' - 10;
sl@0
    35
		value = (value << 4) + c;
sl@0
    36
		} while (aText < end);
sl@0
    37
	return value;
sl@0
    38
	}
sl@0
    39
};
sl@0
    40
sl@0
    41
sl@0
    42
// class SymbolFile
sl@0
    43
sl@0
    44
SymbolFile::SymbolFile(const char* aSymbolFile, bool aRofs)
sl@0
    45
	:iText(0), iTextLower(0)
sl@0
    46
	{
sl@0
    47
	ifstream file;
sl@0
    48
#ifdef __MSVCDOTNET__
sl@0
    49
	file.open(aSymbolFile, ios::binary);
sl@0
    50
#else //!__MSVCDOTNET__
sl@0
    51
	file.open(aSymbolFile, ios::nocreate | ios::binary);
sl@0
    52
#endif //__MSVCDOTNET__
sl@0
    53
	if (!file)
sl@0
    54
		{
sl@0
    55
		cerr << "Unable to open ROM symbol file '" << aSymbolFile << '\'' << endl;
sl@0
    56
		Analyse::Abort();
sl@0
    57
		}
sl@0
    58
//
sl@0
    59
	file.seekg(0, ios::end);
sl@0
    60
	iLength = file.tellg();
sl@0
    61
//
sl@0
    62
	iText = new char[iLength+1];
sl@0
    63
	file.seekg(0, ios::beg);
sl@0
    64
	file.read(iText, iLength);
sl@0
    65
	iText[iLength] = '\0';
sl@0
    66
//
sl@0
    67
	file.close();
sl@0
    68
sl@0
    69
	if (aRofs)
sl@0
    70
		{
sl@0
    71
		iTextLower = new char[iLength+1];
sl@0
    72
		for(char *p = iTextLower, *c = iText, *end = iText + iLength;c < end;c++, p++) 
sl@0
    73
			*p = tolower(*c);
sl@0
    74
		}
sl@0
    75
	}
sl@0
    76
sl@0
    77
SymbolFile::~SymbolFile()
sl@0
    78
	{
sl@0
    79
	delete [] iText;
sl@0
    80
	if (iTextLower)
sl@0
    81
		delete [] iTextLower;
sl@0
    82
	}
sl@0
    83
sl@0
    84
bool SymbolFile::Parse(SymbolFile::Parser& aParser, const char* aModuleName, PC aAddress, PC aModuleLength, int aModuleId) const
sl@0
    85
	{
sl@0
    86
	char* text = 0;
sl@0
    87
	PC first_pc_limit = 0, last_pc_limit = 0;
sl@0
    88
	TState state = EPreFile;
sl@0
    89
	PC lastPC = 0;
sl@0
    90
	bool inSyms = false;
sl@0
    91
	const char *prevName = 0;
sl@0
    92
	int lastLen = 0;
sl@0
    93
sl@0
    94
	if (aModuleName) // should parse only one module 
sl@0
    95
		{
sl@0
    96
		bool not_found = false;
sl@0
    97
		char * name = strstr(iTextLower, aModuleName);
sl@0
    98
		if (name)
sl@0
    99
			{
sl@0
   100
			for(char * p = name; p != iTextLower && *p != '\n';p--);
sl@0
   101
			if (*p == '\n' || p == iTextLower) 
sl@0
   102
				{
sl@0
   103
				name = ++p;
sl@0
   104
				text = iText + (name - iTextLower);
sl@0
   105
				}
sl@0
   106
			else
sl@0
   107
				not_found = true;
sl@0
   108
			}
sl@0
   109
		else
sl@0
   110
			not_found = true;
sl@0
   111
sl@0
   112
		if (not_found)
sl@0
   113
			return false;
sl@0
   114
sl@0
   115
		state = EFile;
sl@0
   116
		}
sl@0
   117
	else
sl@0
   118
		text = iText;
sl@0
   119
		
sl@0
   120
	const char* end = iText + iLength;
sl@0
   121
	while (text < end && state != EError)
sl@0
   122
		{
sl@0
   123
		char* endl = strchr(text, '\r');
sl@0
   124
		if (endl == 0)
sl@0
   125
			{
sl@0
   126
			if (!aModuleName)
sl@0
   127
				{
sl@0
   128
				state = EError;
sl@0
   129
				break;
sl@0
   130
				}
sl@0
   131
			else
sl@0
   132
				{
sl@0
   133
				char* p = text + strlen(text);
sl@0
   134
				if (*(p+1) == '\n')
sl@0
   135
					endl = p;
sl@0
   136
				else
sl@0
   137
					{
sl@0
   138
					state = EError;
sl@0
   139
					break;
sl@0
   140
					}
sl@0
   141
				}
sl@0
   142
			}
sl@0
   143
		switch (state)
sl@0
   144
			{
sl@0
   145
		case EPreFile:
sl@0
   146
			if (endl != text)
sl@0
   147
				state = EError;
sl@0
   148
			else
sl@0
   149
				state = EFile;
sl@0
   150
			break;
sl@0
   151
		case EFile:
sl@0
   152
			if (strncmp(text, "From", 4) != 0)
sl@0
   153
				state = EError;
sl@0
   154
			else
sl@0
   155
				{
sl@0
   156
				*endl = '\0';
sl@0
   157
				char* name = strrchr(text, '\\');
sl@0
   158
				if (name == 0)
sl@0
   159
					name = text + 8;
sl@0
   160
				else
sl@0
   161
					++name;
sl@0
   162
				aParser.File(name);
sl@0
   163
				state = EPostFile;
sl@0
   164
				}
sl@0
   165
			break;
sl@0
   166
		case EPostFile:
sl@0
   167
			if (endl != text)
sl@0
   168
				state = EError;
sl@0
   169
			else
sl@0
   170
				state = ESymbol;
sl@0
   171
			break;
sl@0
   172
		case ESymbol:
sl@0
   173
			if (text == endl)
sl@0
   174
				{
sl@0
   175
				if (aModuleName)
sl@0
   176
					goto Quit; 
sl@0
   177
				else
sl@0
   178
					state = EFile;
sl@0
   179
				}
sl@0
   180
			else
sl@0
   181
				{
sl@0
   182
				PC pc = ParseHex(text, 8);
sl@0
   183
				pc &= ~1; // should be odd address, error in symbol table
sl@0
   184
sl@0
   185
				if(aModuleName)
sl@0
   186
					pc += aAddress;
sl@0
   187
sl@0
   188
				*endl = '\0';
sl@0
   189
sl@0
   190
				char* codeType = strrchr(text+20, '(');
sl@0
   191
sl@0
   192
				if ( codeType == NULL || (strcmp(codeType,"(.data)") != 0 &&
sl@0
   193
					 strcmp(codeType,"(.bss)") != 0 &&
sl@0
   194
					 strcmp(codeType,"(.init_array)") != 0 &&
sl@0
   195
					 strcmp(codeType,"(linker$$defined$$symbols)") != 0 &&
sl@0
   196
					 strcmp(codeType,"(ExportTable)") != 0) )
sl@0
   197
					{
sl@0
   198
					if(inSyms && (pc > (lastPC + lastLen)))
sl@0
   199
						{
sl@0
   200
						memcpy((void *)(prevName - 15), "<static> after ", 15);
sl@0
   201
						aParser.Symbol(prevName - 15, lastPC + lastLen, pc - (lastPC + lastLen));
sl@0
   202
						}
sl@0
   203
sl@0
   204
					int length = ParseHex(text + 12, 4);
sl@0
   205
sl@0
   206
					if(pc >= lastPC + lastLen)
sl@0
   207
						{
sl@0
   208
						bool is_added = aParser.Symbol(text + 20, pc, length);
sl@0
   209
						if (is_added && aModuleName && !first_pc_limit) 
sl@0
   210
							{
sl@0
   211
							first_pc_limit = pc + length;
sl@0
   212
							last_pc_limit = pc + aModuleLength;
sl@0
   213
							}
sl@0
   214
						}
sl@0
   215
sl@0
   216
					prevName = text + 20;
sl@0
   217
					if(pc + length > lastPC + lastLen)
sl@0
   218
						{
sl@0
   219
						lastLen = length;
sl@0
   220
						lastPC = pc;
sl@0
   221
						}
sl@0
   222
					inSyms = true;
sl@0
   223
					}
sl@0
   224
				}
sl@0
   225
			break;
sl@0
   226
		case EError:
sl@0
   227
			break;
sl@0
   228
			}
sl@0
   229
		text = endl + 2;
sl@0
   230
		}
sl@0
   231
	if (state == EError)
sl@0
   232
		Analyse::Abort("Bad ROM symbol file format");
sl@0
   233
sl@0
   234
Quit:
sl@0
   235
	if(aModuleName && lastPC == first_pc_limit && (lastPC + lastLen) < last_pc_limit)
sl@0
   236
		{
sl@0
   237
		memcpy((void *)(prevName - 10), "<anon> in ", 10);
sl@0
   238
		aParser.Symbol(prevName - 10, lastPC + lastLen, last_pc_limit - (lastPC + lastLen));
sl@0
   239
		}
sl@0
   240
	aParser.Done(first_pc_limit, last_pc_limit, aModuleId);
sl@0
   241
sl@0
   242
	return true;
sl@0
   243
	}