1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kerneltest/e32utils/analyse/symbols.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,243 @@
1.4 +// Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +//
1.18 +
1.19 +#include "analyse.h"
1.20 +#include "symbols.h"
1.21 +
1.22 +#ifdef __MSVCDOTNET__
1.23 +#include <fstream>
1.24 +#else //!__MSVCDOTNET__
1.25 +#include <fstream.h>
1.26 +#endif //__MSVCDOTNET__
1.27 +
1.28 +namespace {
1.29 +unsigned ParseHex(const char* aText, int aLength)
1.30 + {
1.31 + unsigned value = 0;
1.32 + const char* end = aText + aLength;
1.33 + do
1.34 + {
1.35 + unsigned c = *aText++ - '0';
1.36 + if (c > 9)
1.37 + c -= 'a' - '0' - 10;
1.38 + value = (value << 4) + c;
1.39 + } while (aText < end);
1.40 + return value;
1.41 + }
1.42 +};
1.43 +
1.44 +
1.45 +// class SymbolFile
1.46 +
1.47 +SymbolFile::SymbolFile(const char* aSymbolFile, bool aRofs)
1.48 + :iText(0), iTextLower(0)
1.49 + {
1.50 + ifstream file;
1.51 +#ifdef __MSVCDOTNET__
1.52 + file.open(aSymbolFile, ios::binary);
1.53 +#else //!__MSVCDOTNET__
1.54 + file.open(aSymbolFile, ios::nocreate | ios::binary);
1.55 +#endif //__MSVCDOTNET__
1.56 + if (!file)
1.57 + {
1.58 + cerr << "Unable to open ROM symbol file '" << aSymbolFile << '\'' << endl;
1.59 + Analyse::Abort();
1.60 + }
1.61 +//
1.62 + file.seekg(0, ios::end);
1.63 + iLength = file.tellg();
1.64 +//
1.65 + iText = new char[iLength+1];
1.66 + file.seekg(0, ios::beg);
1.67 + file.read(iText, iLength);
1.68 + iText[iLength] = '\0';
1.69 +//
1.70 + file.close();
1.71 +
1.72 + if (aRofs)
1.73 + {
1.74 + iTextLower = new char[iLength+1];
1.75 + for(char *p = iTextLower, *c = iText, *end = iText + iLength;c < end;c++, p++)
1.76 + *p = tolower(*c);
1.77 + }
1.78 + }
1.79 +
1.80 +SymbolFile::~SymbolFile()
1.81 + {
1.82 + delete [] iText;
1.83 + if (iTextLower)
1.84 + delete [] iTextLower;
1.85 + }
1.86 +
1.87 +bool SymbolFile::Parse(SymbolFile::Parser& aParser, const char* aModuleName, PC aAddress, PC aModuleLength, int aModuleId) const
1.88 + {
1.89 + char* text = 0;
1.90 + PC first_pc_limit = 0, last_pc_limit = 0;
1.91 + TState state = EPreFile;
1.92 + PC lastPC = 0;
1.93 + bool inSyms = false;
1.94 + const char *prevName = 0;
1.95 + int lastLen = 0;
1.96 +
1.97 + if (aModuleName) // should parse only one module
1.98 + {
1.99 + bool not_found = false;
1.100 + char * name = strstr(iTextLower, aModuleName);
1.101 + if (name)
1.102 + {
1.103 + for(char * p = name; p != iTextLower && *p != '\n';p--);
1.104 + if (*p == '\n' || p == iTextLower)
1.105 + {
1.106 + name = ++p;
1.107 + text = iText + (name - iTextLower);
1.108 + }
1.109 + else
1.110 + not_found = true;
1.111 + }
1.112 + else
1.113 + not_found = true;
1.114 +
1.115 + if (not_found)
1.116 + return false;
1.117 +
1.118 + state = EFile;
1.119 + }
1.120 + else
1.121 + text = iText;
1.122 +
1.123 + const char* end = iText + iLength;
1.124 + while (text < end && state != EError)
1.125 + {
1.126 + char* endl = strchr(text, '\r');
1.127 + if (endl == 0)
1.128 + {
1.129 + if (!aModuleName)
1.130 + {
1.131 + state = EError;
1.132 + break;
1.133 + }
1.134 + else
1.135 + {
1.136 + char* p = text + strlen(text);
1.137 + if (*(p+1) == '\n')
1.138 + endl = p;
1.139 + else
1.140 + {
1.141 + state = EError;
1.142 + break;
1.143 + }
1.144 + }
1.145 + }
1.146 + switch (state)
1.147 + {
1.148 + case EPreFile:
1.149 + if (endl != text)
1.150 + state = EError;
1.151 + else
1.152 + state = EFile;
1.153 + break;
1.154 + case EFile:
1.155 + if (strncmp(text, "From", 4) != 0)
1.156 + state = EError;
1.157 + else
1.158 + {
1.159 + *endl = '\0';
1.160 + char* name = strrchr(text, '\\');
1.161 + if (name == 0)
1.162 + name = text + 8;
1.163 + else
1.164 + ++name;
1.165 + aParser.File(name);
1.166 + state = EPostFile;
1.167 + }
1.168 + break;
1.169 + case EPostFile:
1.170 + if (endl != text)
1.171 + state = EError;
1.172 + else
1.173 + state = ESymbol;
1.174 + break;
1.175 + case ESymbol:
1.176 + if (text == endl)
1.177 + {
1.178 + if (aModuleName)
1.179 + goto Quit;
1.180 + else
1.181 + state = EFile;
1.182 + }
1.183 + else
1.184 + {
1.185 + PC pc = ParseHex(text, 8);
1.186 + pc &= ~1; // should be odd address, error in symbol table
1.187 +
1.188 + if(aModuleName)
1.189 + pc += aAddress;
1.190 +
1.191 + *endl = '\0';
1.192 +
1.193 + char* codeType = strrchr(text+20, '(');
1.194 +
1.195 + if ( codeType == NULL || (strcmp(codeType,"(.data)") != 0 &&
1.196 + strcmp(codeType,"(.bss)") != 0 &&
1.197 + strcmp(codeType,"(.init_array)") != 0 &&
1.198 + strcmp(codeType,"(linker$$defined$$symbols)") != 0 &&
1.199 + strcmp(codeType,"(ExportTable)") != 0) )
1.200 + {
1.201 + if(inSyms && (pc > (lastPC + lastLen)))
1.202 + {
1.203 + memcpy((void *)(prevName - 15), "<static> after ", 15);
1.204 + aParser.Symbol(prevName - 15, lastPC + lastLen, pc - (lastPC + lastLen));
1.205 + }
1.206 +
1.207 + int length = ParseHex(text + 12, 4);
1.208 +
1.209 + if(pc >= lastPC + lastLen)
1.210 + {
1.211 + bool is_added = aParser.Symbol(text + 20, pc, length);
1.212 + if (is_added && aModuleName && !first_pc_limit)
1.213 + {
1.214 + first_pc_limit = pc + length;
1.215 + last_pc_limit = pc + aModuleLength;
1.216 + }
1.217 + }
1.218 +
1.219 + prevName = text + 20;
1.220 + if(pc + length > lastPC + lastLen)
1.221 + {
1.222 + lastLen = length;
1.223 + lastPC = pc;
1.224 + }
1.225 + inSyms = true;
1.226 + }
1.227 + }
1.228 + break;
1.229 + case EError:
1.230 + break;
1.231 + }
1.232 + text = endl + 2;
1.233 + }
1.234 + if (state == EError)
1.235 + Analyse::Abort("Bad ROM symbol file format");
1.236 +
1.237 +Quit:
1.238 + if(aModuleName && lastPC == first_pc_limit && (lastPC + lastLen) < last_pc_limit)
1.239 + {
1.240 + memcpy((void *)(prevName - 10), "<anon> in ", 10);
1.241 + aParser.Symbol(prevName - 10, lastPC + lastLen, last_pc_limit - (lastPC + lastLen));
1.242 + }
1.243 + aParser.Done(first_pc_limit, last_pc_limit, aModuleId);
1.244 +
1.245 + return true;
1.246 + }