|
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.io.DataInputStream; |
|
21 import java.io.File; |
|
22 import java.io.FileInputStream; |
|
23 import java.util.Enumeration; |
|
24 import java.util.Vector; |
|
25 |
|
26 import com.nokia.carbide.cpp.internal.pi.analyser.NpiInstanceRepository; |
|
27 import com.nokia.carbide.cpp.internal.pi.model.FunctionResolver; |
|
28 import com.nokia.carbide.cpp.internal.pi.model.GenericTrace; |
|
29 import com.nokia.carbide.cpp.internal.pi.model.ParsedTraceData; |
|
30 import com.nokia.carbide.cpp.internal.pi.model.Parser; |
|
31 import com.nokia.carbide.cpp.internal.pi.model.TraceDataRepository; |
|
32 import com.nokia.carbide.cpp.internal.pi.utils.QuickSortImpl; |
|
33 import com.nokia.carbide.cpp.internal.pi.utils.Sortable; |
|
34 import com.nokia.carbide.cpp.pi.util.GeneralMessages; |
|
35 |
|
36 |
|
37 public class IttTraceParser extends Parser |
|
38 { |
|
39 private boolean debug = false; |
|
40 private Vector<IttSample> samples; |
|
41 private IttTrace122 trace122; |
|
42 |
|
43 public IttTraceParser() |
|
44 { |
|
45 } |
|
46 |
|
47 public ParsedTraceData parseNoProgress(File f) throws Exception |
|
48 { |
|
49 return this.parse(f/*,null*/); |
|
50 } |
|
51 |
|
52 public ParsedTraceData parse(File f /*, ProgressBar progressBar*/) throws Exception |
|
53 { |
|
54 if (!f.exists() || f.isDirectory()) |
|
55 { |
|
56 throw new Exception(Messages.getString("IttTraceParser.cannotOpenTraceFile")); //$NON-NLS-1$ |
|
57 } |
|
58 |
|
59 parseIttTrace(f); |
|
60 ParsedTraceData ptd = new ParsedTraceData(); |
|
61 ptd.traceData = this.getTrace(); |
|
62 |
|
63 if (ptd.traceData instanceof IttTrace) |
|
64 { |
|
65 BinaryReader br = new BinaryReader(); |
|
66 AdvancedMemoryMap amm = new AdvancedMemoryMap(br); |
|
67 |
|
68 int analysisId = NpiInstanceRepository.getInstance().activeUid(); |
|
69 Enumeration resEnum = TraceDataRepository.getInstance().getResolvers(analysisId); |
|
70 |
|
71 FunctionResolver symbolFileParser = null; |
|
72 |
|
73 while(resEnum.hasMoreElements()) |
|
74 { |
|
75 FunctionResolver fr = (FunctionResolver)resEnum.nextElement(); |
|
76 if (fr.getResolverName().equals("Symbol")) //$NON-NLS-1$ |
|
77 { |
|
78 symbolFileParser = fr; |
|
79 break; |
|
80 } |
|
81 } |
|
82 |
|
83 if (symbolFileParser == null) |
|
84 { |
|
85 // unfortunately, GPP need to be read first in order to make Symbol function resolver available |
|
86 throw new Exception(Messages.getString("IttTraceParser.symbolResolverNotFound")); //$NON-NLS-1$ |
|
87 } |
|
88 |
|
89 Enumeration sEnum = ((IttTrace)this.getTrace()).getSamples(); |
|
90 int i = 0; |
|
91 int len = ((IttTrace)this.getTrace()).samples.size(); |
|
92 String progString = Messages.getString("IttTraceParser.traceProgress0Percent"); //$NON-NLS-1$ |
|
93 |
|
94 while (sEnum.hasMoreElements()) |
|
95 { |
|
96 IttSample itts = (IttSample) sEnum.nextElement(); |
|
97 |
|
98 if (symbolFileParser != null) |
|
99 { |
|
100 if (symbolFileParser.findBinaryNameForAddress( |
|
101 itts.programCounter).endsWith(Messages.getString("IttTraceParser.binaryNotFound"))) //$NON-NLS-1$ |
|
102 { |
|
103 amm.InsertSample(itts); |
|
104 } |
|
105 } |
|
106 else |
|
107 { |
|
108 amm.InsertSample(itts); |
|
109 } |
|
110 i++; |
|
111 |
|
112 String newProgString = Messages.getString("IttTraceParser.traceProgress1")+(i*100)/len+Messages.getString("IttTraceParser.traceProgress2"); //$NON-NLS-1$ //$NON-NLS-2$ |
|
113 if (!progString.equals(newProgString)) |
|
114 { |
|
115 progString = newProgString; |
|
116 |
|
117 if (symbolFileParser == null) |
|
118 progString +=Messages.getString("IttTraceParser.traceProgress3"); //$NON-NLS-1$ |
|
119 |
|
120 } |
|
121 } |
|
122 |
|
123 amm.postProcess(); |
|
124 |
|
125 ptd.functionResolvers = new FunctionResolver[]{amm}; |
|
126 } |
|
127 else if (ptd.traceData instanceof IttTrace122) |
|
128 { |
|
129 BinaryReader122 br122 = new BinaryReader122((IttTrace122)ptd.traceData); |
|
130 PiInstrFunctionResolver pifr = new PiInstrFunctionResolver(br122,(IttTrace122)ptd.traceData,br122.parsedMapFileCount()); |
|
131 ptd.functionResolvers = new FunctionResolver[]{pifr}; |
|
132 } |
|
133 |
|
134 return ptd; |
|
135 } |
|
136 |
|
137 private void parseIttTrace(File f) throws Exception |
|
138 { |
|
139 int instrPerSample = 4; |
|
140 |
|
141 DataInputStream dis = new DataInputStream(new FileInputStream(f)); |
|
142 //checks if the itt trace is valid |
|
143 |
|
144 byte[] traceArray = new byte[(int)f.length()]; |
|
145 |
|
146 dis.readFully(traceArray); |
|
147 |
|
148 String traceStart = new String(traceArray,0,30); |
|
149 int offset = 0; |
|
150 if (traceStart.indexOf("Bappea_ITT") != -1 ) //trace version 1.10 or later //$NON-NLS-1$ |
|
151 { |
|
152 offset = traceArray[0]; |
|
153 traceVersion = new String(traceArray,1,offset); |
|
154 traceVersion = traceVersion.substring(traceVersion.indexOf("_")+1); //$NON-NLS-1$ |
|
155 if (debug) System.out.println(Messages.getString("IttTraceParser.debugTraceVersion")+traceVersion); //$NON-NLS-1$ |
|
156 offset++; |
|
157 } |
|
158 else |
|
159 { |
|
160 traceVersion = "ITT pre 1.0"; //$NON-NLS-1$ |
|
161 if (debug) System.out.println(Messages.getString("IttTraceParser.debugTraceVersion1.0")); //$NON-NLS-1$ |
|
162 } |
|
163 |
|
164 //opens up to 1.10 version ITT traces. |
|
165 if (traceVersion.indexOf("ITT_V1.10") != -1 || traceVersion.equals("ITT pre 1.0")) //$NON-NLS-1$ //$NON-NLS-2$ |
|
166 { |
|
167 try |
|
168 { |
|
169 for (int i=offset;i<traceArray.length-16;) |
|
170 { |
|
171 long magic = this.getInt32From(traceArray,i); |
|
172 long repeat = this.getInt32From(traceArray,i+4); |
|
173 |
|
174 if (magic == 0xbabbeaaa) |
|
175 { |
|
176 int valueHi = (int)(((repeat & 0xffff0000) >>> 16) & 0xffff); |
|
177 int valueLo = (int)(repeat & 0xffff); |
|
178 if (valueHi + valueLo == 0xffff) |
|
179 { |
|
180 //System.out.println("Performing a repeat of "+valueLo); |
|
181 for (int m=0;m<valueLo;m++) |
|
182 { |
|
183 IttSample s = (IttSample)samples.lastElement(); |
|
184 IttSample newS = new IttSample(instrPerSample); |
|
185 |
|
186 // copy the fields, increase the synch time for each sample |
|
187 newS.checksum = s.checksum; |
|
188 newS.programCounter = s.programCounter; |
|
189 newS.sampleSynchTime = s.sampleSynchTime+1; |
|
190 //System.out.println("Sample: "+newS.sampleSynchTime); |
|
191 for (int k=0;k<s.instructions.length;k++) |
|
192 newS.instructions[k] = s.instructions[k]; |
|
193 |
|
194 this.printError(traceArray,i,newS); |
|
195 |
|
196 samples.add(newS); |
|
197 } |
|
198 i+=8; |
|
199 } |
|
200 else |
|
201 { |
|
202 parseNormalSample(magic,repeat,instrPerSample,traceArray,i+8); |
|
203 i+=(instrPerSample+3)*4; |
|
204 } |
|
205 } |
|
206 else |
|
207 { |
|
208 parseNormalSample(magic,repeat,instrPerSample,traceArray,i+8); |
|
209 i+=(instrPerSample+3)*4; |
|
210 } |
|
211 } |
|
212 } |
|
213 catch (Exception e) |
|
214 { |
|
215 // end of trace |
|
216 } |
|
217 } |
|
218 else if (traceVersion.indexOf("ITT_V1.22") != -1 || traceVersion.indexOf("ITT_V2.01") != -1) //$NON-NLS-1$ //$NON-NLS-2$ |
|
219 { |
|
220 boolean isVersion201 = traceVersion.indexOf("ITT_V2.01") != -1; //$NON-NLS-1$ |
|
221 this.trace122 = parse122IttTrace(traceArray, isVersion201); |
|
222 } |
|
223 else |
|
224 { |
|
225 GeneralMessages.showErrorMessage(Messages.getString("IttTraceParser.unsupportedTrace")+traceVersion); //$NON-NLS-1$ |
|
226 } |
|
227 } |
|
228 |
|
229 private IttTrace122 parse122IttTrace(byte[] traceArray, boolean isVersion201) |
|
230 { |
|
231 IttTrace122 trace = new IttTrace122(); |
|
232 |
|
233 int ptr = 0; |
|
234 |
|
235 // read the first header |
|
236 byte length = traceArray[ptr++]; |
|
237 String txt = new String(traceArray,ptr,length);ptr+=length; |
|
238 |
|
239 Vector sortables = new Vector(); |
|
240 |
|
241 class SortableString implements Sortable |
|
242 { |
|
243 String string; |
|
244 long value; |
|
245 long startAddress; |
|
246 long endAddress; |
|
247 double samplingTime; |
|
248 |
|
249 public long valueOf() |
|
250 { |
|
251 return this.value; |
|
252 } |
|
253 } |
|
254 |
|
255 int adjust = isVersion201 ? 12 : 8; |
|
256 |
|
257 while(ptr < traceArray.length) |
|
258 { |
|
259 IttEvent122 event = new IttEvent122(); |
|
260 try |
|
261 { |
|
262 length = traceArray[ptr++]; |
|
263 txt = new String(traceArray,ptr,(length-adjust)); |
|
264 ptr+=(length-adjust); |
|
265 event.binaryName = txt; |
|
266 } |
|
267 catch(Exception e) |
|
268 { |
|
269 e.printStackTrace(); |
|
270 break; |
|
271 } |
|
272 |
|
273 long adr = getUnsignedByte(traceArray[ptr++]); |
|
274 adr |= (getUnsignedByte(traceArray[ptr++])<<8); |
|
275 adr |= (getUnsignedByte(traceArray[ptr++])<<16); |
|
276 adr |= (getUnsignedByte(traceArray[ptr++])<<24); |
|
277 adr = (adr<<32)>>>32; |
|
278 event.binaryLocation = adr; |
|
279 |
|
280 long len = getUnsignedByte(traceArray[ptr++]); |
|
281 len |= (getUnsignedByte(traceArray[ptr++])<<8); |
|
282 len |= (getUnsignedByte(traceArray[ptr++])<<16); |
|
283 len |= (getUnsignedByte(traceArray[ptr++])<<24); |
|
284 len = (len<<32)>>>32; |
|
285 event.binaryLength = len; |
|
286 |
|
287 if (isVersion201) { |
|
288 long time = getUnsignedByte(traceArray[ptr++]); |
|
289 time |= (getUnsignedByte(traceArray[ptr++])<<8); |
|
290 time |= (getUnsignedByte(traceArray[ptr++])<<16); |
|
291 time |= (getUnsignedByte(traceArray[ptr++])<<24); |
|
292 time = (time<<32)>>>32; |
|
293 event.eventTime = time / 1000.0; |
|
294 } else { |
|
295 event.eventTime = 0.0; |
|
296 } |
|
297 |
|
298 event.createBinary(); |
|
299 |
|
300 trace.addEvent(event); |
|
301 if (debug) |
|
302 { |
|
303 SortableString s = new SortableString(); |
|
304 s.string = Long.toHexString(adr)+" - "+Long.toHexString(adr+len)+" \t "+event.binary.binaryName+" length:"+len; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ |
|
305 s.value = adr; |
|
306 s.startAddress = adr; |
|
307 s.endAddress = adr+len; |
|
308 s.samplingTime = event.eventTime; |
|
309 sortables.add(s); |
|
310 } |
|
311 } |
|
312 |
|
313 if (debug) |
|
314 { |
|
315 QuickSortImpl.sort(sortables); |
|
316 Enumeration e = sortables.elements(); |
|
317 SortableString prev = null; |
|
318 while (e.hasMoreElements()) |
|
319 { |
|
320 SortableString s = (SortableString)e.nextElement(); |
|
321 if (prev != null) |
|
322 { |
|
323 // System.out.println("Empty:"+(s.startAddress - prev.endAddress)+" bytes"); |
|
324 if (s.startAddress < prev.endAddress) { |
|
325 System.out.println(Messages.getString("IttTraceParser.debugOverlapping")); //$NON-NLS-1$ |
|
326 System.out.println(Messages.getString("IttTraceParser.previous") + prev.string); //$NON-NLS-1$ |
|
327 System.out.println(Messages.getString("IttTraceParser.this") + s.string); //$NON-NLS-1$ |
|
328 } |
|
329 } |
|
330 System.out.println(s.string); |
|
331 prev = s; |
|
332 } |
|
333 } |
|
334 |
|
335 return trace; |
|
336 } |
|
337 |
|
338 private int getUnsignedByte(byte b) |
|
339 { |
|
340 return ((b<<24)>>>24); |
|
341 } |
|
342 |
|
343 private long getInt32From(byte[] traceArray,int i) |
|
344 { |
|
345 long value = (traceArray[i]& 0xff) | ((traceArray[i+1] & 0xff) << 8) | |
|
346 ((traceArray[i+2]& 0xff) << 16) | ((traceArray[i+3]&0xff) << 24); |
|
347 return value; |
|
348 } |
|
349 |
|
350 private long getReversedInt32From(byte[] traceArray,int i) |
|
351 { |
|
352 long value = ((traceArray[i]& 0xff) << 24) | ((traceArray[i+1] & 0xff) << 16) | |
|
353 ((traceArray[i+2]& 0xff) << 8) | (traceArray[i+3]&0xff); |
|
354 return value; |
|
355 } |
|
356 |
|
357 private void parseNormalSample( long first,long second, |
|
358 int instrPerSample, |
|
359 byte[] traceArray,int i) throws Exception |
|
360 { |
|
361 IttSample sample = new IttSample(instrPerSample); |
|
362 // change the byte order of the instructions |
|
363 sample.instructions[0] = ((first & 0xff) << 24) | |
|
364 ((first >> 8) & 0xff) << 16 | |
|
365 ((first >> 16) & 0xff) << 8 | |
|
366 ((first >> 24) & 0xff); |
|
367 |
|
368 sample.instructions[1] = ((second & 0xff) << 24) | |
|
369 ((second >> 8) & 0xff) << 16 | |
|
370 ((second >> 16) & 0xff) << 8 | |
|
371 ((second >> 24) & 0xff); |
|
372 |
|
373 for (int k=2;k<instrPerSample;k++) |
|
374 { |
|
375 // read in reverse byte order |
|
376 sample.instructions[k] = this.getReversedInt32From(traceArray,i); |
|
377 i+=4; |
|
378 } |
|
379 |
|
380 sample.sampleSynchTime = this.getInt32From(traceArray,i); |
|
381 i+=4; |
|
382 |
|
383 |
|
384 sample.checksum = this.getInt32From(traceArray,i); |
|
385 i+=4; |
|
386 |
|
387 |
|
388 sample.programCounter = (((this.getInt32From(traceArray,i)) << 32) >>> 32); |
|
389 i+= 4; |
|
390 |
|
391 this.printError(traceArray,i,sample); |
|
392 |
|
393 this.samples.add(sample); |
|
394 } |
|
395 |
|
396 private void printError(byte[] traceArray,int i,IttSample newSample) |
|
397 { |
|
398 if (this.samples.size() > 0) |
|
399 { |
|
400 IttSample sample = (IttSample)this.samples.lastElement(); |
|
401 if ( sample.sampleSynchTime != newSample.sampleSynchTime-1) |
|
402 { |
|
403 System.out.println(Messages.getString("IttTraceParser.missingSample1")); //$NON-NLS-1$ |
|
404 |
|
405 System.out.println(Messages.getString("IttTraceParser.missingSample2")+sample.sampleSynchTime); //$NON-NLS-1$ |
|
406 System.out.println(Messages.getString("IttTraceParser.missingSample3")+Integer.toHexString((int)sample.programCounter)); //$NON-NLS-1$ |
|
407 System.out.println(Messages.getString("IttTraceParser.missingSample4")+Integer.toHexString((int)sample.checksum)+Messages.getString("IttTraceParser.missingSample5")); //$NON-NLS-1$ //$NON-NLS-2$ |
|
408 |
|
409 System.out.println(Messages.getString("IttTraceParser.missingSample6")+newSample.sampleSynchTime); //$NON-NLS-1$ |
|
410 System.out.println(Messages.getString("IttTraceParser.missingSample7")+Integer.toHexString((int)newSample.programCounter)); //$NON-NLS-1$ |
|
411 System.out.println(Messages.getString("IttTraceParser.missingSample8")+Integer.toHexString((int)newSample.checksum)+Messages.getString("IttTraceParser.missingSample9")); //$NON-NLS-1$ //$NON-NLS-2$ |
|
412 |
|
413 int v = 0; |
|
414 for (int k=i-48;k<i+48;k+=4) |
|
415 { |
|
416 v++; |
|
417 String s = Long.toHexString(this.getInt32From(traceArray,k)); |
|
418 if (s.length() > 8) s = s.substring(s.length()-8,s.length()); |
|
419 else if (s.length()<8) {for (int g=0;g<8-s.length();g++){s="0"+s;}} //$NON-NLS-1$ |
|
420 |
|
421 System.out.print("0x"+s+" "); //$NON-NLS-1$ //$NON-NLS-2$ |
|
422 if (v%4 == 0) System.out.print("\n"); //$NON-NLS-1$ |
|
423 } |
|
424 |
|
425 } |
|
426 } |
|
427 } |
|
428 |
|
429 public Enumeration getSamples() |
|
430 { |
|
431 return this.samples.elements(); |
|
432 } |
|
433 |
|
434 private GenericTrace getTrace() |
|
435 { |
|
436 if (this.trace122 == null) |
|
437 { |
|
438 IttTrace trace = new IttTrace(); |
|
439 Enumeration sEnum = this.samples.elements(); |
|
440 while(sEnum.hasMoreElements()) |
|
441 { |
|
442 IttSample s = (IttSample)sEnum.nextElement(); |
|
443 trace.addSample(s); |
|
444 } |
|
445 return trace; |
|
446 } |
|
447 else |
|
448 { |
|
449 return this.trace122; |
|
450 } |
|
451 } |
|
452 } |