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 <crtdbg.h>
|
sl@0
|
17 |
#include "analyse.h"
|
sl@0
|
18 |
#include "codespace.h"
|
sl@0
|
19 |
|
sl@0
|
20 |
#ifdef __MSVCDOTNET__
|
sl@0
|
21 |
#pragma warning(push, 3) // cannot compile MSVC's STL at warning level 4
|
sl@0
|
22 |
#pragma warning(disable: 4786 4710 4530)
|
sl@0
|
23 |
#include <strstream>
|
sl@0
|
24 |
#include <iomanip>
|
sl@0
|
25 |
#else //!__MSVCDOTNET__
|
sl@0
|
26 |
#include <strstrea.h>
|
sl@0
|
27 |
#include <iomanip.h>
|
sl@0
|
28 |
#endif //__MSVCDOTNET__
|
sl@0
|
29 |
|
sl@0
|
30 |
#include <algorithm>
|
sl@0
|
31 |
|
sl@0
|
32 |
// class CodeSpace
|
sl@0
|
33 |
|
sl@0
|
34 |
int CodeSpace::Size() const
|
sl@0
|
35 |
{
|
sl@0
|
36 |
return 1;
|
sl@0
|
37 |
}
|
sl@0
|
38 |
|
sl@0
|
39 |
int CodeSpace::Bucket(PC) const
|
sl@0
|
40 |
{
|
sl@0
|
41 |
return KOtherBucket;
|
sl@0
|
42 |
}
|
sl@0
|
43 |
|
sl@0
|
44 |
const char* CodeSpace::Name(int) const
|
sl@0
|
45 |
{
|
sl@0
|
46 |
return "<other>";
|
sl@0
|
47 |
}
|
sl@0
|
48 |
|
sl@0
|
49 |
CodeSpace::TOrder CodeSpace::Ordering() const
|
sl@0
|
50 |
{
|
sl@0
|
51 |
return ERandom;
|
sl@0
|
52 |
}
|
sl@0
|
53 |
|
sl@0
|
54 |
|
sl@0
|
55 |
// class AddressCodeSpace
|
sl@0
|
56 |
|
sl@0
|
57 |
AddressCodeSpace::AddressCodeSpace(PC aBase, PC aLimit, unsigned aBucketSize, TType aType)
|
sl@0
|
58 |
:iBase(aBase), iType(aType)
|
sl@0
|
59 |
{
|
sl@0
|
60 |
if (aBucketSize < 1)
|
sl@0
|
61 |
aBucketSize = 1;
|
sl@0
|
62 |
unsigned shift;
|
sl@0
|
63 |
for (shift = 0; (aBucketSize >> shift) != 1; ++shift)
|
sl@0
|
64 |
;
|
sl@0
|
65 |
iBucketShift = shift;
|
sl@0
|
66 |
iBuckets = (aLimit - aBase + (1u << shift) - 1) >> shift;
|
sl@0
|
67 |
}
|
sl@0
|
68 |
|
sl@0
|
69 |
int AddressCodeSpace::Size() const
|
sl@0
|
70 |
{
|
sl@0
|
71 |
return iBuckets + 1;
|
sl@0
|
72 |
}
|
sl@0
|
73 |
|
sl@0
|
74 |
int AddressCodeSpace::Bucket(PC aPc) const
|
sl@0
|
75 |
{
|
sl@0
|
76 |
if (aPc >= iBase)
|
sl@0
|
77 |
{
|
sl@0
|
78 |
unsigned bucket = (aPc - iBase) >> iBucketShift;
|
sl@0
|
79 |
if (bucket < iBuckets)
|
sl@0
|
80 |
return bucket + 1;
|
sl@0
|
81 |
}
|
sl@0
|
82 |
return KOtherBucket;
|
sl@0
|
83 |
}
|
sl@0
|
84 |
|
sl@0
|
85 |
const char* AddressCodeSpace::Name(int aBucket) const
|
sl@0
|
86 |
{
|
sl@0
|
87 |
if (aBucket == KOtherBucket)
|
sl@0
|
88 |
return CodeSpace::Name(aBucket);
|
sl@0
|
89 |
|
sl@0
|
90 |
unsigned offset = ((aBucket - 1) << iBucketShift);
|
sl@0
|
91 |
strstream s(iBuffer, sizeof(iBuffer), ios::out);
|
sl@0
|
92 |
s << hex << setfill('0');
|
sl@0
|
93 |
if (iType == EAbsolute)
|
sl@0
|
94 |
s << setw(8) << iBase + offset;
|
sl@0
|
95 |
else
|
sl@0
|
96 |
s << "+ " << setw(4) << offset;
|
sl@0
|
97 |
s << setfill(' ') << '\0';
|
sl@0
|
98 |
return iBuffer;
|
sl@0
|
99 |
}
|
sl@0
|
100 |
|
sl@0
|
101 |
CodeSpace::TOrder AddressCodeSpace::Ordering() const
|
sl@0
|
102 |
{
|
sl@0
|
103 |
return (iType == EAbsolute) ? EOrdered : ELinear;
|
sl@0
|
104 |
}
|
sl@0
|
105 |
|
sl@0
|
106 |
|
sl@0
|
107 |
// class MappedCodeSpace
|
sl@0
|
108 |
|
sl@0
|
109 |
MappedCodeSpace::MappedCodeSpace(const SymbolFile& aSymbols, MappedCodeSpace::Partition& aPartition)
|
sl@0
|
110 |
{
|
sl@0
|
111 |
aPartition.iCodeSpace = this;
|
sl@0
|
112 |
aSymbols.Parse(aPartition);
|
sl@0
|
113 |
}
|
sl@0
|
114 |
|
sl@0
|
115 |
MappedCodeSpace::MappedCodeSpace()
|
sl@0
|
116 |
{}
|
sl@0
|
117 |
|
sl@0
|
118 |
const MappedCodeSpace::Element* MappedCodeSpace::Find(PC aPc) const
|
sl@0
|
119 |
//
|
sl@0
|
120 |
// Find and return the element which contains this PC value
|
sl@0
|
121 |
// If not mapped return 0
|
sl@0
|
122 |
//
|
sl@0
|
123 |
{
|
sl@0
|
124 |
Map::const_iterator e = iMap.upper_bound(aPc);
|
sl@0
|
125 |
|
sl@0
|
126 |
// ignore deleted segments
|
sl@0
|
127 |
for(;e != iMap.end() && aPc >= e->second.iBase;e++)
|
sl@0
|
128 |
if (!e->second.iUnloaded)
|
sl@0
|
129 |
return &e->second;
|
sl@0
|
130 |
return 0;
|
sl@0
|
131 |
}
|
sl@0
|
132 |
|
sl@0
|
133 |
std::pair<const char*,unsigned> MappedCodeSpace::Lookup(PC aPc) const
|
sl@0
|
134 |
{
|
sl@0
|
135 |
const Element* e = Find(aPc);
|
sl@0
|
136 |
if (e == 0)
|
sl@0
|
137 |
return std::pair<const char*,unsigned>(0, aPc);
|
sl@0
|
138 |
return std::pair<const char*,unsigned>(e->iName, aPc - e->iBase);
|
sl@0
|
139 |
}
|
sl@0
|
140 |
|
sl@0
|
141 |
int MappedCodeSpace::Size() const
|
sl@0
|
142 |
{
|
sl@0
|
143 |
return iMap.size() + 1;
|
sl@0
|
144 |
}
|
sl@0
|
145 |
|
sl@0
|
146 |
int MappedCodeSpace::Bucket(PC aPc) const
|
sl@0
|
147 |
{
|
sl@0
|
148 |
const Element* e = Find(aPc);
|
sl@0
|
149 |
return (e == 0) ? KOtherBucket : e->iBucket + 1;
|
sl@0
|
150 |
}
|
sl@0
|
151 |
|
sl@0
|
152 |
const char* MappedCodeSpace::Name(int aBucket) const
|
sl@0
|
153 |
{
|
sl@0
|
154 |
return (aBucket == KOtherBucket) ? CodeSpace::Name(aBucket) : iNames[aBucket - 1];
|
sl@0
|
155 |
}
|
sl@0
|
156 |
|
sl@0
|
157 |
void MappedCodeSpace::Add(PC aBase, PC aLimit, const char* aName)
|
sl@0
|
158 |
{
|
sl@0
|
159 |
// insert
|
sl@0
|
160 |
iMap.insert(Map::value_type(aLimit, Element(aBase, aLimit, aName)));
|
sl@0
|
161 |
}
|
sl@0
|
162 |
|
sl@0
|
163 |
void MappedCodeSpace::Done(PC aFirstPc, PC aLastPc, int aModuleId)
|
sl@0
|
164 |
{
|
sl@0
|
165 |
if (!aFirstPc)
|
sl@0
|
166 |
{
|
sl@0
|
167 |
iNames.clear();
|
sl@0
|
168 |
for (Map::iterator p = iMap.begin(), e = iMap.end(); p != e; ++p)
|
sl@0
|
169 |
{
|
sl@0
|
170 |
p->second.iBucket = iNames.size();
|
sl@0
|
171 |
iNames.push_back(p->second.iName);
|
sl@0
|
172 |
}
|
sl@0
|
173 |
}
|
sl@0
|
174 |
else
|
sl@0
|
175 |
{
|
sl@0
|
176 |
Map::iterator p = iMap.find(aFirstPc);
|
sl@0
|
177 |
_ASSERT(p != iMap.end());
|
sl@0
|
178 |
for (Map::iterator e = iMap.end(); p != e && p->first <= aLastPc; ++p)
|
sl@0
|
179 |
{
|
sl@0
|
180 |
if (p->second.iUnloaded)
|
sl@0
|
181 |
continue;
|
sl@0
|
182 |
|
sl@0
|
183 |
bool bFound = false;
|
sl@0
|
184 |
NamesMap::iterator pMap = iNamesMap.find(p->second.iName);
|
sl@0
|
185 |
if (pMap != iNamesMap.end())
|
sl@0
|
186 |
for(;!strcmp(p->second.iName, pMap->first);pMap++)
|
sl@0
|
187 |
if (pMap->second.iId == aModuleId)
|
sl@0
|
188 |
{
|
sl@0
|
189 |
bFound = true;
|
sl@0
|
190 |
break;
|
sl@0
|
191 |
}
|
sl@0
|
192 |
if (bFound)
|
sl@0
|
193 |
p->second.iBucket = pMap->second.iIndex;
|
sl@0
|
194 |
else
|
sl@0
|
195 |
{
|
sl@0
|
196 |
p->second.iBucket = iNames.size();
|
sl@0
|
197 |
iNames.push_back(p->second.iName);
|
sl@0
|
198 |
iNamesMap.insert(NamesMap::value_type(p->second.iName, IdNames(aModuleId, p->second.iBucket)));
|
sl@0
|
199 |
}
|
sl@0
|
200 |
}
|
sl@0
|
201 |
}
|
sl@0
|
202 |
}
|
sl@0
|
203 |
|