|
1 /* |
|
2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of the License "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 package com.nokia.carbide.cpp.pi.instr; |
|
19 |
|
20 import java.util.Enumeration; |
|
21 import java.util.Hashtable; |
|
22 import java.util.Vector; |
|
23 |
|
24 import com.nokia.carbide.cpp.internal.pi.model.Binary; |
|
25 import com.nokia.carbide.cpp.internal.pi.model.Function; |
|
26 |
|
27 |
|
28 public class DecidedPool |
|
29 { |
|
30 private boolean debug = false; |
|
31 private MemoryLayout memLayout; |
|
32 private AdvancedMemoryMap amm; |
|
33 |
|
34 public DecidedPool(AdvancedMemoryMap amm) |
|
35 { |
|
36 this.memLayout = new MemoryLayout(); |
|
37 this.amm = amm; |
|
38 } |
|
39 |
|
40 public boolean insertSample(IttSample sample) |
|
41 { |
|
42 Vector binaries = this.memLayout.findBinariesForAddress(sample.programCounter); |
|
43 Enumeration binEnum = binaries.elements(); |
|
44 |
|
45 Vector okBins = new Vector(); |
|
46 while (binEnum.hasMoreElements()) |
|
47 { |
|
48 Binary b = (Binary)binEnum.nextElement(); |
|
49 if (this.trySampleWithBinary(sample,b,4) == true) |
|
50 { |
|
51 okBins.add(b); |
|
52 } |
|
53 } |
|
54 |
|
55 if (okBins.size() == 0) |
|
56 { |
|
57 // no matching binaries |
|
58 return false; |
|
59 } |
|
60 else if (okBins.size() == 1) |
|
61 { |
|
62 // homma bueno |
|
63 return true; |
|
64 } |
|
65 else if (okBins.size() > 1) |
|
66 { |
|
67 Vector okOkBins = new Vector(); |
|
68 Enumeration okBinEnum = binaries.elements(); |
|
69 while (okBinEnum.hasMoreElements()) |
|
70 { |
|
71 Binary b = (Binary)okBinEnum.nextElement(); |
|
72 if (this.trySampleWithBinary(sample,b,0) == true) |
|
73 { |
|
74 okOkBins.add(b); |
|
75 } |
|
76 } |
|
77 |
|
78 if (okOkBins.size() > 1) |
|
79 { |
|
80 Enumeration okOkBinEnum = okOkBins.elements(); |
|
81 int winnerSupSamples = 0; |
|
82 while (okOkBinEnum.hasMoreElements()) |
|
83 { |
|
84 Binary b = (Binary)okOkBinEnum.nextElement(); |
|
85 DecidedLocation dl = this.memLayout.getDecidedLocationForBinary(b); |
|
86 if (dl.getSupportingSamples().size() > winnerSupSamples) |
|
87 { |
|
88 winnerSupSamples = dl.getSupportingSamples().size(); |
|
89 } |
|
90 } |
|
91 } |
|
92 |
|
93 return true; |
|
94 } |
|
95 else |
|
96 { |
|
97 if (debug)System.out.println(Messages.getString("DecidedPool.debugDecidedPool")); //$NON-NLS-1$ |
|
98 return false; |
|
99 } |
|
100 } |
|
101 |
|
102 public boolean isThereAnyBinaryInMemoryIn(long address) |
|
103 { |
|
104 if (this.memLayout.findBinariesForAddress(address).size() == 0) |
|
105 { |
|
106 return false; |
|
107 } |
|
108 else |
|
109 { |
|
110 return true; |
|
111 } |
|
112 } |
|
113 |
|
114 public Function getFunctionForAddress(long address) |
|
115 { |
|
116 Vector binaries = this.memLayout.findBinariesForAddress(address); |
|
117 Enumeration binEnum = binaries.elements(); |
|
118 |
|
119 Binary winner = null; |
|
120 int winnerSupport = -100000; |
|
121 |
|
122 while (binEnum.hasMoreElements()) |
|
123 { |
|
124 Binary b = (Binary)binEnum.nextElement(); |
|
125 DecidedLocation dl = this.memLayout.getDecidedLocationForBinary(b); |
|
126 int support = dl.supportingSamples.size()-dl.nonSupportingSamples.size(); |
|
127 if (support > winnerSupport) |
|
128 { |
|
129 winner = b; |
|
130 winnerSupport = support; |
|
131 } |
|
132 } |
|
133 if (winner != null) |
|
134 { |
|
135 ProcessedBinary pb = this.amm.getBinaryReader(). |
|
136 getProcessedBinaryForName(winner.binaryName); |
|
137 |
|
138 |
|
139 String fName = pb.getFunctionNameForOffset( |
|
140 address-(winner.startAddress+winner.offsetToCodeStart)); |
|
141 |
|
142 String bName = winner.binaryName; |
|
143 long fOffset = pb.getOffsetFromBinaryStartForFunction(fName); |
|
144 Long fStart = new Long(winner.startAddress+winner.offsetToCodeStart+fOffset); |
|
145 |
|
146 Function f = new Function(fName,fStart,bName); |
|
147 f.length = pb.getFunctionLengthForOffset(fOffset); |
|
148 |
|
149 return f; |
|
150 |
|
151 } |
|
152 |
|
153 return null; |
|
154 } |
|
155 |
|
156 public boolean trySampleWithBinary(IttSample sample, Binary b,int allowErrors) |
|
157 { |
|
158 if (b != null) |
|
159 { |
|
160 if (amm.getBinaryReader().checkSampleInBinary(sample,b,allowErrors) == true) |
|
161 { |
|
162 //System.out.println("Located 0x"+Long.toHexString(sample.programCounter)+" to "+b.binaryName); |
|
163 DecidedLocation dl = this.memLayout.getDecidedLocationForBinary(b); |
|
164 dl.insertSupportingSample(sample); |
|
165 |
|
166 return true; |
|
167 } |
|
168 else |
|
169 { |
|
170 // binary is not a match with the sample, register the sample as |
|
171 // a non-supporting sample. These will be processed at a later time |
|
172 |
|
173 DecidedLocation dl = this.memLayout.getDecidedLocationForBinary(b); |
|
174 dl.insertNonSupportingSample(sample); |
|
175 |
|
176 //System.out.println("Binary "+b.binaryName+" might be in a wrong place - n:"+ |
|
177 // dl.getNonSupportingSamples().size()+" s:"+dl.getSupportingSamples().size()); |
|
178 |
|
179 return false; |
|
180 } |
|
181 } |
|
182 else |
|
183 { |
|
184 return false; |
|
185 } |
|
186 } |
|
187 |
|
188 public void insertDecidedBinary(Binary binary,Vector samples) |
|
189 { |
|
190 Vector currentBins = this.memLayout.isOccupiedBy(binary.startAddress,binary.length); |
|
191 |
|
192 if (currentBins.size() == 0) |
|
193 { |
|
194 if (debug) System.out.println(Messages.getString("DecidedPool.analysisResolved1")+binary.binaryName+Messages.getString("DecidedPool.analysisResolved2")+Long.toHexString(binary.startAddress+binary.offsetToCodeStart)+ //$NON-NLS-1$ //$NON-NLS-2$ |
|
195 Messages.getString("DecidedPool.analysisResolved3")+Long.toHexString(binary.startAddress+binary.offsetToCodeStart+binary.length)); //$NON-NLS-1$ |
|
196 |
|
197 DecidedLocation dl = new DecidedLocation(binary); |
|
198 dl.insertSupportingSamples(samples); |
|
199 |
|
200 this.memLayout.insertArea(dl); |
|
201 } |
|
202 else |
|
203 { |
|
204 Enumeration curEnum = currentBins.elements(); |
|
205 while (curEnum.hasMoreElements()) |
|
206 { |
|
207 Binary b = (Binary)curEnum.nextElement(); |
|
208 |
|
209 boolean okForThis = true; |
|
210 int okCount = 0; |
|
211 Enumeration sampEnum = samples.elements(); |
|
212 |
|
213 while (sampEnum.hasMoreElements()) |
|
214 { |
|
215 IttSample is = (IttSample)sampEnum.nextElement(); |
|
216 |
|
217 if (is.programCounter >= b.startAddress && is.programCounter <= b.startAddress+b.length) |
|
218 { |
|
219 if (this.trySampleWithBinary(is,b,4) == false) |
|
220 okForThis=false; |
|
221 else |
|
222 okCount++; |
|
223 } |
|
224 } |
|
225 |
|
226 if (okForThis == true) |
|
227 { |
|
228 //System.out.println(okCount+" samples in "+binary.binaryName+" match to "+b.binaryName); |
|
229 } |
|
230 } |
|
231 |
|
232 DecidedLocation dl = new DecidedLocation(binary); |
|
233 dl.insertSupportingSamples(samples); |
|
234 |
|
235 this.memLayout.insertArea(dl); |
|
236 |
|
237 /* |
|
238 System.out.println(overLap+" Area at "+Long.toHexString(currentBin.startAddress)+"-" |
|
239 +Long.toHexString(currentBin.startAddress+currentBin.length) |
|
240 +" is occupied by " |
|
241 +currentBin.binaryName+" - unable to locate "+binary.binaryName+" to " |
|
242 +Long.toHexString(binary.startAddress)+"-" |
|
243 +Long.toHexString(binary.startAddress+binary.length)); |
|
244 */ |
|
245 } |
|
246 } |
|
247 |
|
248 public Enumeration getSupportingSamplesForBinary(Binary b) |
|
249 { |
|
250 DecidedLocation dl = this.memLayout.getDecidedLocationForBinary(b); |
|
251 if (dl != null) |
|
252 { |
|
253 return dl.supportingSamples.elements(); |
|
254 } |
|
255 else |
|
256 { |
|
257 return new Vector().elements(); |
|
258 } |
|
259 } |
|
260 |
|
261 public Enumeration getNonSupportingSamplesForBinary(Binary b) |
|
262 { |
|
263 DecidedLocation dl = this.memLayout.getDecidedLocationForBinary(b); |
|
264 if (dl != null) |
|
265 { |
|
266 return dl.nonSupportingSamples.elements(); |
|
267 } |
|
268 else |
|
269 { |
|
270 return new Vector().elements(); |
|
271 } |
|
272 } |
|
273 |
|
274 public Binary getBinaryWithName(String binaryName) |
|
275 { |
|
276 return this.memLayout.getBinaryWithName(binaryName); |
|
277 } |
|
278 |
|
279 public Binary findBinaryForSample(IttSample sample) |
|
280 { |
|
281 Vector binaries = this.memLayout.findBinariesForAddress(sample.programCounter+4); |
|
282 if (binaries == null) return null; |
|
283 if (binaries.size() == 0) return null; |
|
284 |
|
285 Vector okBins = new Vector(); |
|
286 Enumeration enumer = binaries.elements(); |
|
287 |
|
288 while (enumer.hasMoreElements()) |
|
289 { |
|
290 Binary b = (Binary)enumer.nextElement(); |
|
291 if (this.trySampleWithBinary(sample,b,6)) |
|
292 { |
|
293 okBins.add(b); |
|
294 } |
|
295 } |
|
296 |
|
297 if (okBins.size() <= 0) |
|
298 { |
|
299 if (binaries.size() == 1) |
|
300 { |
|
301 // there is only one binary at this location in memory, |
|
302 // guess that it is the one we are looking for even though |
|
303 // the samples don't match |
|
304 Binary binary = (Binary)binaries.firstElement(); |
|
305 //System.out.println("Guessing that "+binary.binaryName+" is at 0x"+Long.toHexString(sample.programCounter)); |
|
306 return binary; |
|
307 } |
|
308 else if (binaries.size() > 1) |
|
309 { |
|
310 Enumeration binEnum = binaries.elements(); |
|
311 DecidedLocation bestGuess = this.memLayout.getDecidedLocationForBinary( |
|
312 (Binary)binEnum.nextElement()); |
|
313 while (binEnum.hasMoreElements()) |
|
314 { |
|
315 DecidedLocation dl = this.memLayout.getDecidedLocationForBinary( |
|
316 (Binary)binEnum.nextElement()); |
|
317 |
|
318 if ( (dl.supportingSamples.size()-dl.nonSupportingSamples.size()) > |
|
319 (bestGuess.supportingSamples.size()-bestGuess.nonSupportingSamples.size()) ) |
|
320 { |
|
321 bestGuess = dl; |
|
322 } |
|
323 } |
|
324 // return the binary that has most support for its location |
|
325 return bestGuess.binary; |
|
326 } |
|
327 } |
|
328 else if (okBins.size() == 1) |
|
329 { |
|
330 return (Binary)okBins.firstElement(); |
|
331 } |
|
332 else if (okBins.size() > 1) |
|
333 { |
|
334 Enumeration okEnum = okBins.elements(); |
|
335 |
|
336 Vector okOkVec = new Vector(); |
|
337 |
|
338 while (okEnum.hasMoreElements()) |
|
339 { |
|
340 Binary okBin = (Binary)okEnum.nextElement(); |
|
341 if (this.trySampleWithBinary(sample,okBin,0) == true) |
|
342 { |
|
343 okOkVec.add(okBin); |
|
344 } |
|
345 } |
|
346 |
|
347 if (okOkVec.size() == 1) return (Binary)okOkVec.firstElement(); |
|
348 |
|
349 else if (okOkVec.size() <= 0) return null; |
|
350 |
|
351 else if (okOkVec.size() > 1) |
|
352 { |
|
353 Enumeration okOkEnum = okOkVec.elements(); |
|
354 |
|
355 Binary winner = null; |
|
356 int winnerSupSamples = 0; |
|
357 //System.out.println("Conflict: "+okOkVec.size()+" binaries"); |
|
358 |
|
359 while (okOkEnum.hasMoreElements()) |
|
360 { |
|
361 Binary b = (Binary)okOkEnum.nextElement(); |
|
362 DecidedLocation dl = this.memLayout.getDecidedLocationForBinary(b); |
|
363 if (dl.getSupportingSamples().size() > winnerSupSamples) |
|
364 { |
|
365 winnerSupSamples = dl.getSupportingSamples().size(); |
|
366 winner = b; |
|
367 //System.out.println("bin: "+b.binaryName+""+dl.getSupportingSamples().size()); |
|
368 } |
|
369 } |
|
370 /* |
|
371 if (winner != null) |
|
372 System.out.println("Winner: "+winner.binaryName+"\n"); |
|
373 else |
|
374 System.out.println("NO WINNER???"); |
|
375 */ |
|
376 return winner; |
|
377 } |
|
378 } |
|
379 |
|
380 return null; |
|
381 } |
|
382 |
|
383 private static class DecidedLocation |
|
384 { |
|
385 private Binary binary; |
|
386 private Vector supportingSamples; |
|
387 private Vector nonSupportingSamples; |
|
388 |
|
389 public DecidedLocation(Binary binary) |
|
390 { |
|
391 this.binary = binary; |
|
392 this.supportingSamples = new Vector(); |
|
393 this.nonSupportingSamples = new Vector(); |
|
394 } |
|
395 |
|
396 public void insertSupportingSample(IttSample sample) |
|
397 { |
|
398 this.supportingSamples.add(sample); |
|
399 } |
|
400 |
|
401 public void insertSupportingSamples(Vector samples) |
|
402 { |
|
403 Enumeration enumer = samples.elements(); |
|
404 while (enumer.hasMoreElements()) |
|
405 { |
|
406 IttSample s = (IttSample)enumer.nextElement(); |
|
407 if (!this.supportingSamples.contains(s)) |
|
408 { |
|
409 this.insertSupportingSample(s); |
|
410 } |
|
411 } |
|
412 } |
|
413 |
|
414 public void insertNonSupportingSample(IttSample sample) |
|
415 { |
|
416 if (!this.nonSupportingSamples.contains(sample)) |
|
417 { |
|
418 this.nonSupportingSamples.add(sample); |
|
419 } |
|
420 } |
|
421 |
|
422 public Vector getSupportingSamples() |
|
423 { |
|
424 return this.supportingSamples; |
|
425 } |
|
426 |
|
427 public Vector getNonSupportingSamples() |
|
428 { |
|
429 return this.nonSupportingSamples; |
|
430 } |
|
431 |
|
432 } |
|
433 |
|
434 private static class MemoryLayout |
|
435 { |
|
436 public Hashtable decidedLocations; |
|
437 |
|
438 public MemoryLayout() |
|
439 { |
|
440 // keys are the binaries |
|
441 // decided locations are the elements |
|
442 this.decidedLocations = new Hashtable(); |
|
443 } |
|
444 |
|
445 public void insertArea(DecidedLocation dl) |
|
446 { |
|
447 this.decidedLocations.put(dl.binary,dl); |
|
448 } |
|
449 |
|
450 public Vector isOccupiedBy(long start, long length) |
|
451 { |
|
452 Vector binaries = new Vector(); |
|
453 |
|
454 Enumeration enumer = this.decidedLocations.keys(); |
|
455 while (enumer.hasMoreElements()) |
|
456 { |
|
457 Binary b = (Binary)enumer.nextElement(); |
|
458 long bStart = b.startAddress; |
|
459 long bEnd = b.startAddress+b.length; |
|
460 long end = start+length; |
|
461 |
|
462 // starts within the area |
|
463 if (start <= bEnd && start >= bStart) |
|
464 { |
|
465 binaries.add(b); |
|
466 } |
|
467 |
|
468 // ends within the area |
|
469 else if (end <= bEnd && end >= bStart) |
|
470 { |
|
471 binaries.add(b); |
|
472 } |
|
473 |
|
474 // is over the area |
|
475 else if (start <= bStart && end >= bEnd) |
|
476 { |
|
477 binaries.add(b); |
|
478 } |
|
479 |
|
480 } |
|
481 return binaries; |
|
482 } |
|
483 |
|
484 public DecidedLocation getDecidedLocationForBinary(Binary b) |
|
485 { |
|
486 if (this.decidedLocations.containsKey(b)) |
|
487 { |
|
488 return (DecidedLocation)this.decidedLocations.get(b); |
|
489 } |
|
490 else |
|
491 { |
|
492 return null; |
|
493 } |
|
494 } |
|
495 |
|
496 public Vector findBinariesForAddress(long address) |
|
497 { |
|
498 Enumeration enumer = this.decidedLocations.keys(); |
|
499 Vector binaries = new Vector(); |
|
500 |
|
501 while (enumer.hasMoreElements()) |
|
502 { |
|
503 Binary b = (Binary)enumer.nextElement(); |
|
504 long bStart = b.startAddress; |
|
505 long bEnd = b.startAddress+b.length; |
|
506 |
|
507 if (address >= bStart && address <= bEnd) |
|
508 { |
|
509 binaries.add(b); |
|
510 } |
|
511 |
|
512 } |
|
513 return binaries; |
|
514 } |
|
515 |
|
516 public Binary getBinaryWithName(String binaryName) |
|
517 { |
|
518 Enumeration dls = this.decidedLocations.keys(); |
|
519 while (dls.hasMoreElements()) |
|
520 { |
|
521 Binary b = (Binary)dls.nextElement(); |
|
522 if (b.binaryName.toLowerCase().equals(binaryName.toLowerCase())) return b; |
|
523 } |
|
524 return null; |
|
525 } |
|
526 |
|
527 } |
|
528 |
|
529 } |