diff -r 000000000000 -r a41df078684a kerneltest/e32utils/analyse/codespace.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/e32utils/analyse/codespace.cpp Mon Oct 19 15:55:17 2009 +0100 @@ -0,0 +1,203 @@ +// Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "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: +// + +#include +#include "analyse.h" +#include "codespace.h" + +#ifdef __MSVCDOTNET__ +#pragma warning(push, 3) // cannot compile MSVC's STL at warning level 4 +#pragma warning(disable: 4786 4710 4530) +#include +#include +#else //!__MSVCDOTNET__ +#include +#include +#endif //__MSVCDOTNET__ + +#include + +// class CodeSpace + +int CodeSpace::Size() const + { + return 1; + } + +int CodeSpace::Bucket(PC) const + { + return KOtherBucket; + } + +const char* CodeSpace::Name(int) const + { + return ""; + } + +CodeSpace::TOrder CodeSpace::Ordering() const + { + return ERandom; + } + + +// class AddressCodeSpace + +AddressCodeSpace::AddressCodeSpace(PC aBase, PC aLimit, unsigned aBucketSize, TType aType) + :iBase(aBase), iType(aType) + { + if (aBucketSize < 1) + aBucketSize = 1; + unsigned shift; + for (shift = 0; (aBucketSize >> shift) != 1; ++shift) + ; + iBucketShift = shift; + iBuckets = (aLimit - aBase + (1u << shift) - 1) >> shift; + } + +int AddressCodeSpace::Size() const + { + return iBuckets + 1; + } + +int AddressCodeSpace::Bucket(PC aPc) const + { + if (aPc >= iBase) + { + unsigned bucket = (aPc - iBase) >> iBucketShift; + if (bucket < iBuckets) + return bucket + 1; + } + return KOtherBucket; + } + +const char* AddressCodeSpace::Name(int aBucket) const + { + if (aBucket == KOtherBucket) + return CodeSpace::Name(aBucket); + + unsigned offset = ((aBucket - 1) << iBucketShift); + strstream s(iBuffer, sizeof(iBuffer), ios::out); + s << hex << setfill('0'); + if (iType == EAbsolute) + s << setw(8) << iBase + offset; + else + s << "+ " << setw(4) << offset; + s << setfill(' ') << '\0'; + return iBuffer; + } + +CodeSpace::TOrder AddressCodeSpace::Ordering() const + { + return (iType == EAbsolute) ? EOrdered : ELinear; + } + + +// class MappedCodeSpace + +MappedCodeSpace::MappedCodeSpace(const SymbolFile& aSymbols, MappedCodeSpace::Partition& aPartition) + { + aPartition.iCodeSpace = this; + aSymbols.Parse(aPartition); + } + +MappedCodeSpace::MappedCodeSpace() + {} + +const MappedCodeSpace::Element* MappedCodeSpace::Find(PC aPc) const +// +// Find and return the element which contains this PC value +// If not mapped return 0 +// + { + Map::const_iterator e = iMap.upper_bound(aPc); + + // ignore deleted segments + for(;e != iMap.end() && aPc >= e->second.iBase;e++) + if (!e->second.iUnloaded) + return &e->second; + return 0; + } + +std::pair MappedCodeSpace::Lookup(PC aPc) const + { + const Element* e = Find(aPc); + if (e == 0) + return std::pair(0, aPc); + return std::pair(e->iName, aPc - e->iBase); + } + +int MappedCodeSpace::Size() const + { + return iMap.size() + 1; + } + +int MappedCodeSpace::Bucket(PC aPc) const + { + const Element* e = Find(aPc); + return (e == 0) ? KOtherBucket : e->iBucket + 1; + } + +const char* MappedCodeSpace::Name(int aBucket) const + { + return (aBucket == KOtherBucket) ? CodeSpace::Name(aBucket) : iNames[aBucket - 1]; + } + +void MappedCodeSpace::Add(PC aBase, PC aLimit, const char* aName) + { + // insert + iMap.insert(Map::value_type(aLimit, Element(aBase, aLimit, aName))); + } + +void MappedCodeSpace::Done(PC aFirstPc, PC aLastPc, int aModuleId) + { + if (!aFirstPc) + { + iNames.clear(); + for (Map::iterator p = iMap.begin(), e = iMap.end(); p != e; ++p) + { + p->second.iBucket = iNames.size(); + iNames.push_back(p->second.iName); + } + } + else + { + Map::iterator p = iMap.find(aFirstPc); + _ASSERT(p != iMap.end()); + for (Map::iterator e = iMap.end(); p != e && p->first <= aLastPc; ++p) + { + if (p->second.iUnloaded) + continue; + + bool bFound = false; + NamesMap::iterator pMap = iNamesMap.find(p->second.iName); + if (pMap != iNamesMap.end()) + for(;!strcmp(p->second.iName, pMap->first);pMap++) + if (pMap->second.iId == aModuleId) + { + bFound = true; + break; + } + if (bFound) + p->second.iBucket = pMap->second.iIndex; + else + { + p->second.iBucket = iNames.size(); + iNames.push_back(p->second.iName); + iNamesMap.insert(NamesMap::value_type(p->second.iName, IdNames(aModuleId, p->second.iBucket))); + } + } + } + } +