sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.instr/src/com/nokia/carbide/cpp/pi/instr/IttTraceParser.java
changeset 2 b9ab3b238396
child 5 844b047e260d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.instr/src/com/nokia/carbide/cpp/pi/instr/IttTraceParser.java	Thu Feb 11 15:32:31 2010 +0200
@@ -0,0 +1,452 @@
+/*
+ * Copyright (c) 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: 
+ *
+ */
+
+package com.nokia.carbide.cpp.pi.instr;
+
+import java.io.DataInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import com.nokia.carbide.cpp.internal.pi.analyser.NpiInstanceRepository;
+import com.nokia.carbide.cpp.internal.pi.model.FunctionResolver;
+import com.nokia.carbide.cpp.internal.pi.model.GenericTrace;
+import com.nokia.carbide.cpp.internal.pi.model.ParsedTraceData;
+import com.nokia.carbide.cpp.internal.pi.model.Parser;
+import com.nokia.carbide.cpp.internal.pi.model.TraceDataRepository;
+import com.nokia.carbide.cpp.internal.pi.utils.QuickSortImpl;
+import com.nokia.carbide.cpp.internal.pi.utils.Sortable;
+import com.nokia.carbide.cpp.pi.util.GeneralMessages;
+
+
+public class IttTraceParser extends Parser
+{
+  private boolean debug = false;
+  private Vector<IttSample> samples;
+  private IttTrace122 trace122;
+
+  public IttTraceParser()
+  {
+  }
+  
+  public ParsedTraceData parseNoProgress(File f) throws Exception
+  {
+	  return this.parse(f/*,null*/);
+  }
+  
+  public ParsedTraceData parse(File f /*, ProgressBar progressBar*/) throws Exception 
+  {
+  		if (!f.exists() || f.isDirectory())
+  	    {
+  	      throw new Exception(Messages.getString("IttTraceParser.cannotOpenTraceFile")); //$NON-NLS-1$
+  	    }
+
+  		parseIttTrace(f);
+  		ParsedTraceData ptd = new ParsedTraceData();
+		ptd.traceData = this.getTrace();
+		
+		if (ptd.traceData instanceof IttTrace) 
+		{
+			BinaryReader br = new BinaryReader();
+			AdvancedMemoryMap amm = new AdvancedMemoryMap(br);
+			
+	  		int analysisId = NpiInstanceRepository.getInstance().activeUid();
+        	Enumeration resEnum = TraceDataRepository.getInstance().getResolvers(analysisId);
+        	
+        	FunctionResolver symbolFileParser = null;
+        	
+        	while(resEnum.hasMoreElements())
+        	{
+        		FunctionResolver fr = (FunctionResolver)resEnum.nextElement();
+        		if (fr.getResolverName().equals("Symbol"))  //$NON-NLS-1$
+        		{
+        			symbolFileParser = fr;
+        			break;
+        		}
+        	}
+			
+      		if (symbolFileParser == null)
+      	    {
+      			// unfortunately, GPP need to be read first in order to make Symbol function resolver available
+      	      throw new Exception(Messages.getString("IttTraceParser.symbolResolverNotFound")); //$NON-NLS-1$
+      	    }
+			
+            Enumeration sEnum = ((IttTrace)this.getTrace()).getSamples();
+            int i = 0;
+            int len = ((IttTrace)this.getTrace()).samples.size();
+            String progString = Messages.getString("IttTraceParser.traceProgress0Percent"); //$NON-NLS-1$
+            
+            while (sEnum.hasMoreElements())
+            {
+        		IttSample itts = (IttSample) sEnum.nextElement();
+
+            	if (symbolFileParser != null)
+            	{
+            		if (symbolFileParser.findBinaryNameForAddress(
+                				itts.programCounter).endsWith(Messages.getString("IttTraceParser.binaryNotFound"))) //$NON-NLS-1$
+            		{
+            			amm.InsertSample(itts);
+            		}
+            	}
+            	else
+            	{
+            		amm.InsertSample(itts);
+            	}
+                i++;
+                
+                String newProgString = Messages.getString("IttTraceParser.traceProgress1")+(i*100)/len+Messages.getString("IttTraceParser.traceProgress2"); //$NON-NLS-1$ //$NON-NLS-2$
+                if (!progString.equals(newProgString))
+                {
+                	progString = newProgString;
+                	
+                	if (symbolFileParser == null)
+                		progString +=Messages.getString("IttTraceParser.traceProgress3"); //$NON-NLS-1$
+                		
+                 }
+            }
+
+             amm.postProcess();
+			
+			ptd.functionResolvers = new FunctionResolver[]{amm};
+		}
+		else if (ptd.traceData instanceof IttTrace122)
+		{
+			BinaryReader122 br122 = new BinaryReader122((IttTrace122)ptd.traceData);
+			PiInstrFunctionResolver pifr = new PiInstrFunctionResolver(br122,(IttTrace122)ptd.traceData,br122.parsedMapFileCount());
+			ptd.functionResolvers = new FunctionResolver[]{pifr};
+		}
+		
+		return ptd;
+	}
+
+  private void parseIttTrace(File f) throws Exception
+  {
+    int instrPerSample = 4;
+
+    DataInputStream dis = new DataInputStream(new FileInputStream(f));
+    //checks if the itt trace is valid
+    
+    byte[] traceArray = new byte[(int)f.length()];
+    
+    dis.readFully(traceArray);
+    
+    String traceStart = new String(traceArray,0,30);
+    int offset = 0;
+    if (traceStart.indexOf("Bappea_ITT") != -1 ) //trace version 1.10 or later //$NON-NLS-1$
+    {
+        offset = traceArray[0];
+        traceVersion = new String(traceArray,1,offset);
+        traceVersion = traceVersion.substring(traceVersion.indexOf("_")+1); //$NON-NLS-1$
+        if (debug) System.out.println(Messages.getString("IttTraceParser.debugTraceVersion")+traceVersion);  //$NON-NLS-1$
+        offset++;
+    }
+    else
+    {
+        traceVersion = "ITT pre 1.0"; //$NON-NLS-1$
+        if (debug) System.out.println(Messages.getString("IttTraceParser.debugTraceVersion1.0")); //$NON-NLS-1$
+    }
+
+    //opens up to 1.10 version ITT traces.
+    if (traceVersion.indexOf("ITT_V1.10") != -1 || traceVersion.equals("ITT pre 1.0")) //$NON-NLS-1$ //$NON-NLS-2$
+    {
+	   	try
+		{
+	   		for (int i=offset;i<traceArray.length-16;)
+	   		{
+	   			long magic = this.getInt32From(traceArray,i);
+	   			long repeat = this.getInt32From(traceArray,i+4);
+	   			
+	   			if (magic == 0xbabbeaaa)
+	   			{
+	   				int valueHi = (int)(((repeat & 0xffff0000) >>> 16) & 0xffff);
+	   				int valueLo = (int)(repeat & 0xffff);
+	   				if (valueHi + valueLo == 0xffff)
+	   				{
+	   					//System.out.println("Performing a repeat of "+valueLo);
+	   					for (int m=0;m<valueLo;m++)
+	   					{
+	   						IttSample s = (IttSample)samples.lastElement();
+	   						IttSample newS = new IttSample(instrPerSample);
+	   						
+	   						// copy the fields, increase the synch time for each sample
+	   						newS.checksum = s.checksum;
+	   						newS.programCounter = s.programCounter;
+	   						newS.sampleSynchTime = s.sampleSynchTime+1;
+	   						//System.out.println("Sample: "+newS.sampleSynchTime);
+	   						for (int k=0;k<s.instructions.length;k++)
+	   							newS.instructions[k] = s.instructions[k];
+	   						
+	   						this.printError(traceArray,i,newS);
+	   						
+	   						samples.add(newS);
+	   					}
+	   					i+=8;
+	   				}
+	   				else
+	   				{
+	   					parseNormalSample(magic,repeat,instrPerSample,traceArray,i+8);
+	   					i+=(instrPerSample+3)*4;
+	   				}
+	   			}
+	   			else
+	   			{
+	   				parseNormalSample(magic,repeat,instrPerSample,traceArray,i+8);
+	   				i+=(instrPerSample+3)*4;
+	   			}
+	   		}
+		}
+	   	catch (Exception e)
+		{
+	   		// end of trace
+	   	}
+    }
+    else if (traceVersion.indexOf("ITT_V1.22") != -1 || traceVersion.indexOf("ITT_V2.01") != -1) //$NON-NLS-1$ //$NON-NLS-2$
+    {
+    	boolean isVersion201 = traceVersion.indexOf("ITT_V2.01") != -1; //$NON-NLS-1$
+    	this.trace122 = parse122IttTrace(traceArray, isVersion201);
+    }
+    else
+    {
+        GeneralMessages.showErrorMessage(Messages.getString("IttTraceParser.unsupportedTrace")+traceVersion); //$NON-NLS-1$
+    }
+  }
+   
+  private IttTrace122 parse122IttTrace(byte[] traceArray, boolean isVersion201)
+  {
+	  IttTrace122 trace = new IttTrace122();
+	  
+	  int ptr = 0;
+
+	  // read the first header
+	  byte length = traceArray[ptr++];
+	  String txt = new String(traceArray,ptr,length);ptr+=length;
+	  
+	  Vector sortables = new Vector();
+	  
+	  class SortableString implements Sortable
+	  {
+		  String string;
+		  long value;
+		  long startAddress;
+		  long endAddress;
+		  double samplingTime;
+		  
+		  public long valueOf()
+		  {
+			  return this.value;
+		  }
+	  }
+	  
+	  int adjust = isVersion201 ? 12 : 8;
+	  
+	  while(ptr < traceArray.length)
+	  {
+		  IttEvent122 event = new IttEvent122();
+		  try
+		  {
+		  length = traceArray[ptr++];
+		  txt = new String(traceArray,ptr,(length-adjust));
+		  ptr+=(length-adjust);
+		  event.binaryName = txt;
+		  }
+		  catch(Exception e)
+		  {
+			  e.printStackTrace();
+			  break;
+		  }
+		  
+		  long adr = getUnsignedByte(traceArray[ptr++]);
+		  adr |= (getUnsignedByte(traceArray[ptr++])<<8);
+		  adr |= (getUnsignedByte(traceArray[ptr++])<<16);
+		  adr |= (getUnsignedByte(traceArray[ptr++])<<24);
+		  adr = (adr<<32)>>>32;
+		  event.binaryLocation = adr;
+		  
+		  long len = getUnsignedByte(traceArray[ptr++]);
+		  len |= (getUnsignedByte(traceArray[ptr++])<<8);
+		  len |= (getUnsignedByte(traceArray[ptr++])<<16);
+		  len |= (getUnsignedByte(traceArray[ptr++])<<24);
+		  len = (len<<32)>>>32;
+		  event.binaryLength = len;
+		  
+		  if (isVersion201) {
+			  long time = getUnsignedByte(traceArray[ptr++]);
+			  time |= (getUnsignedByte(traceArray[ptr++])<<8);
+			  time |= (getUnsignedByte(traceArray[ptr++])<<16);
+			  time |= (getUnsignedByte(traceArray[ptr++])<<24);
+			  time = (time<<32)>>>32;
+			  event.eventTime = time / 1000.0;
+		  } else {
+			  event.eventTime = 0.0;
+		  }
+
+		  event.createBinary();
+		  
+		  trace.addEvent(event);
+		  if (debug)
+		  {
+			  SortableString s = new SortableString();
+			  s.string = Long.toHexString(adr)+" - "+Long.toHexString(adr+len)+" \t "+event.binary.binaryName+" length:"+len; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+			  s.value = adr;
+			  s.startAddress = adr;
+			  s.endAddress = adr+len;
+			  s.samplingTime = event.eventTime;
+			  sortables.add(s);
+		  }
+	  }
+	  
+	  if (debug)
+	  {
+		  QuickSortImpl.sort(sortables);
+		  Enumeration e = sortables.elements();
+		  SortableString prev = null;
+		  while (e.hasMoreElements())
+		  {
+			  SortableString s = (SortableString)e.nextElement();
+			  if (prev != null)
+			  {
+				 // System.out.println("Empty:"+(s.startAddress - prev.endAddress)+" bytes");
+				  if (s.startAddress < prev.endAddress) {
+					  System.out.println(Messages.getString("IttTraceParser.debugOverlapping")); //$NON-NLS-1$
+					  System.out.println(Messages.getString("IttTraceParser.previous") + prev.string); //$NON-NLS-1$
+					  System.out.println(Messages.getString("IttTraceParser.this") + s.string); //$NON-NLS-1$
+				  }
+			  }
+			  System.out.println(s.string);
+			  prev = s;
+		  }
+	  }
+	  
+	  return trace;
+  }
+  
+  private int getUnsignedByte(byte b)
+  {
+	  return ((b<<24)>>>24);
+  }
+  
+  private long getInt32From(byte[] traceArray,int i)
+  {
+  	long value = (traceArray[i]& 0xff) | ((traceArray[i+1] & 0xff) << 8) |
+			((traceArray[i+2]& 0xff) << 16) | ((traceArray[i+3]&0xff) << 24);
+  	return value;
+  }
+  
+  private long getReversedInt32From(byte[] traceArray,int i)
+  {
+  	long value = ((traceArray[i]& 0xff) << 24) | ((traceArray[i+1] & 0xff) << 16) |
+					((traceArray[i+2]& 0xff) << 8) | (traceArray[i+3]&0xff);
+  	return value;
+  }
+  
+  private void parseNormalSample(	long first,long second,
+  										int instrPerSample,
+										byte[] traceArray,int i) throws Exception
+  {
+    IttSample sample = new IttSample(instrPerSample);
+    // change the byte order of the instructions
+    sample.instructions[0] = ((first & 0xff) << 24) | 
+							 ((first >> 8) & 0xff) << 16 |
+							 ((first >> 16) & 0xff) << 8 |
+							 ((first >> 24) & 0xff);
+
+    sample.instructions[1]  = ((second & 0xff) << 24) | 
+							  ((second >> 8) & 0xff) << 16 |
+							  ((second >> 16) & 0xff) << 8 |
+							  ((second >> 24) & 0xff);
+    
+    for (int k=2;k<instrPerSample;k++)
+    {
+    	// read in reverse byte order
+    	sample.instructions[k] = this.getReversedInt32From(traceArray,i);
+    	i+=4;
+    }
+
+    sample.sampleSynchTime = this.getInt32From(traceArray,i);
+    i+=4;
+
+    
+    sample.checksum = this.getInt32From(traceArray,i);
+    i+=4;
+
+
+    sample.programCounter = (((this.getInt32From(traceArray,i)) << 32) >>> 32);
+    i+= 4;
+
+    this.printError(traceArray,i,sample);
+    
+    this.samples.add(sample);
+  }
+
+  private void printError(byte[] traceArray,int i,IttSample newSample)
+  {
+    if (this.samples.size() > 0)
+    {
+    	IttSample sample = (IttSample)this.samples.lastElement();
+        if ( sample.sampleSynchTime != newSample.sampleSynchTime-1)
+        {
+        	System.out.println(Messages.getString("IttTraceParser.missingSample1")); //$NON-NLS-1$
+            
+            System.out.println(Messages.getString("IttTraceParser.missingSample2")+sample.sampleSynchTime); //$NON-NLS-1$
+            System.out.println(Messages.getString("IttTraceParser.missingSample3")+Integer.toHexString((int)sample.programCounter)); //$NON-NLS-1$
+            System.out.println(Messages.getString("IttTraceParser.missingSample4")+Integer.toHexString((int)sample.checksum)+Messages.getString("IttTraceParser.missingSample5")); //$NON-NLS-1$ //$NON-NLS-2$
+            
+            System.out.println(Messages.getString("IttTraceParser.missingSample6")+newSample.sampleSynchTime); //$NON-NLS-1$
+            System.out.println(Messages.getString("IttTraceParser.missingSample7")+Integer.toHexString((int)newSample.programCounter)); //$NON-NLS-1$
+            System.out.println(Messages.getString("IttTraceParser.missingSample8")+Integer.toHexString((int)newSample.checksum)+Messages.getString("IttTraceParser.missingSample9")); //$NON-NLS-1$ //$NON-NLS-2$
+
+            int v = 0;
+        	for (int k=i-48;k<i+48;k+=4)
+        	{
+        		v++;
+        		String s = Long.toHexString(this.getInt32From(traceArray,k));
+        		if (s.length() > 8) s = s.substring(s.length()-8,s.length());
+        		else if (s.length()<8) {for (int g=0;g<8-s.length();g++){s="0"+s;}} //$NON-NLS-1$
+        		
+        		System.out.print("0x"+s+" "); //$NON-NLS-1$ //$NON-NLS-2$
+        		if (v%4 == 0) System.out.print("\n"); //$NON-NLS-1$
+        	}
+        	
+        }
+    }
+  }
+
+  public Enumeration getSamples()
+  {
+    return this.samples.elements();
+  }
+
+  private GenericTrace getTrace()
+  {
+	  if (this.trace122 == null)
+	  {
+		  IttTrace trace = new IttTrace();
+		  Enumeration sEnum = this.samples.elements();
+		  while(sEnum.hasMoreElements())
+		  {
+			  IttSample s = (IttSample)sEnum.nextElement();
+			  trace.addSample(s);
+		  }	
+		  return trace;
+	  }
+	  else
+	  {
+		  return this.trace122;
+	  }
+  }
+}