sl@0: // Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of the License "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // sl@0: sl@0: #include sl@0: #include "analyse.h" sl@0: #include "codespace.h" sl@0: sl@0: #ifdef __MSVCDOTNET__ sl@0: #pragma warning(push, 3) // cannot compile MSVC's STL at warning level 4 sl@0: #pragma warning(disable: 4786 4710 4530) sl@0: #include sl@0: #include sl@0: #else //!__MSVCDOTNET__ sl@0: #include sl@0: #include sl@0: #endif //__MSVCDOTNET__ sl@0: sl@0: #include sl@0: sl@0: // class CodeSpace sl@0: sl@0: int CodeSpace::Size() const sl@0: { sl@0: return 1; sl@0: } sl@0: sl@0: int CodeSpace::Bucket(PC) const sl@0: { sl@0: return KOtherBucket; sl@0: } sl@0: sl@0: const char* CodeSpace::Name(int) const sl@0: { sl@0: return ""; sl@0: } sl@0: sl@0: CodeSpace::TOrder CodeSpace::Ordering() const sl@0: { sl@0: return ERandom; sl@0: } sl@0: sl@0: sl@0: // class AddressCodeSpace sl@0: sl@0: AddressCodeSpace::AddressCodeSpace(PC aBase, PC aLimit, unsigned aBucketSize, TType aType) sl@0: :iBase(aBase), iType(aType) sl@0: { sl@0: if (aBucketSize < 1) sl@0: aBucketSize = 1; sl@0: unsigned shift; sl@0: for (shift = 0; (aBucketSize >> shift) != 1; ++shift) sl@0: ; sl@0: iBucketShift = shift; sl@0: iBuckets = (aLimit - aBase + (1u << shift) - 1) >> shift; sl@0: } sl@0: sl@0: int AddressCodeSpace::Size() const sl@0: { sl@0: return iBuckets + 1; sl@0: } sl@0: sl@0: int AddressCodeSpace::Bucket(PC aPc) const sl@0: { sl@0: if (aPc >= iBase) sl@0: { sl@0: unsigned bucket = (aPc - iBase) >> iBucketShift; sl@0: if (bucket < iBuckets) sl@0: return bucket + 1; sl@0: } sl@0: return KOtherBucket; sl@0: } sl@0: sl@0: const char* AddressCodeSpace::Name(int aBucket) const sl@0: { sl@0: if (aBucket == KOtherBucket) sl@0: return CodeSpace::Name(aBucket); sl@0: sl@0: unsigned offset = ((aBucket - 1) << iBucketShift); sl@0: strstream s(iBuffer, sizeof(iBuffer), ios::out); sl@0: s << hex << setfill('0'); sl@0: if (iType == EAbsolute) sl@0: s << setw(8) << iBase + offset; sl@0: else sl@0: s << "+ " << setw(4) << offset; sl@0: s << setfill(' ') << '\0'; sl@0: return iBuffer; sl@0: } sl@0: sl@0: CodeSpace::TOrder AddressCodeSpace::Ordering() const sl@0: { sl@0: return (iType == EAbsolute) ? EOrdered : ELinear; sl@0: } sl@0: sl@0: sl@0: // class MappedCodeSpace sl@0: sl@0: MappedCodeSpace::MappedCodeSpace(const SymbolFile& aSymbols, MappedCodeSpace::Partition& aPartition) sl@0: { sl@0: aPartition.iCodeSpace = this; sl@0: aSymbols.Parse(aPartition); sl@0: } sl@0: sl@0: MappedCodeSpace::MappedCodeSpace() sl@0: {} sl@0: sl@0: const MappedCodeSpace::Element* MappedCodeSpace::Find(PC aPc) const sl@0: // sl@0: // Find and return the element which contains this PC value sl@0: // If not mapped return 0 sl@0: // sl@0: { sl@0: Map::const_iterator e = iMap.upper_bound(aPc); sl@0: sl@0: // ignore deleted segments sl@0: for(;e != iMap.end() && aPc >= e->second.iBase;e++) sl@0: if (!e->second.iUnloaded) sl@0: return &e->second; sl@0: return 0; sl@0: } sl@0: sl@0: std::pair MappedCodeSpace::Lookup(PC aPc) const sl@0: { sl@0: const Element* e = Find(aPc); sl@0: if (e == 0) sl@0: return std::pair(0, aPc); sl@0: return std::pair(e->iName, aPc - e->iBase); sl@0: } sl@0: sl@0: int MappedCodeSpace::Size() const sl@0: { sl@0: return iMap.size() + 1; sl@0: } sl@0: sl@0: int MappedCodeSpace::Bucket(PC aPc) const sl@0: { sl@0: const Element* e = Find(aPc); sl@0: return (e == 0) ? KOtherBucket : e->iBucket + 1; sl@0: } sl@0: sl@0: const char* MappedCodeSpace::Name(int aBucket) const sl@0: { sl@0: return (aBucket == KOtherBucket) ? CodeSpace::Name(aBucket) : iNames[aBucket - 1]; sl@0: } sl@0: sl@0: void MappedCodeSpace::Add(PC aBase, PC aLimit, const char* aName) sl@0: { sl@0: // insert sl@0: iMap.insert(Map::value_type(aLimit, Element(aBase, aLimit, aName))); sl@0: } sl@0: sl@0: void MappedCodeSpace::Done(PC aFirstPc, PC aLastPc, int aModuleId) sl@0: { sl@0: if (!aFirstPc) sl@0: { sl@0: iNames.clear(); sl@0: for (Map::iterator p = iMap.begin(), e = iMap.end(); p != e; ++p) sl@0: { sl@0: p->second.iBucket = iNames.size(); sl@0: iNames.push_back(p->second.iName); sl@0: } sl@0: } sl@0: else sl@0: { sl@0: Map::iterator p = iMap.find(aFirstPc); sl@0: _ASSERT(p != iMap.end()); sl@0: for (Map::iterator e = iMap.end(); p != e && p->first <= aLastPc; ++p) sl@0: { sl@0: if (p->second.iUnloaded) sl@0: continue; sl@0: sl@0: bool bFound = false; sl@0: NamesMap::iterator pMap = iNamesMap.find(p->second.iName); sl@0: if (pMap != iNamesMap.end()) sl@0: for(;!strcmp(p->second.iName, pMap->first);pMap++) sl@0: if (pMap->second.iId == aModuleId) sl@0: { sl@0: bFound = true; sl@0: break; sl@0: } sl@0: if (bFound) sl@0: p->second.iBucket = pMap->second.iIndex; sl@0: else sl@0: { sl@0: p->second.iBucket = iNames.size(); sl@0: iNames.push_back(p->second.iName); sl@0: iNamesMap.insert(NamesMap::value_type(p->second.iName, IdNames(aModuleId, p->second.iBucket))); sl@0: } sl@0: } sl@0: } sl@0: } sl@0: