sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.instr/src/com/nokia/carbide/cpp/pi/instr/ProcessedBinary.java
changeset 2 b9ab3b238396
child 5 844b047e260d
equal deleted inserted replaced
1:1050670c6980 2:b9ab3b238396
       
     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.File;
       
    21 import java.io.FileInputStream;
       
    22 import java.util.Enumeration;
       
    23 import java.util.Hashtable;
       
    24 import java.util.Vector;
       
    25 
       
    26 import com.nokia.carbide.cpp.internal.pi.model.Binary;
       
    27 import com.nokia.carbide.cpp.internal.pi.model.Function;
       
    28 
       
    29 
       
    30 public class ProcessedBinary extends Binary
       
    31 {
       
    32   private static final long serialVersionUID = 8267855662123433263L;
       
    33   	
       
    34   public File file;
       
    35   public byte[] data;
       
    36   private MapFile mapFile;
       
    37   private int[][] finalLookupTable;
       
    38   private boolean debug;
       
    39   private Hashtable<String,Function> knownFunctions = new Hashtable<String,Function>();
       
    40   
       
    41   public ProcessedBinary(File file) throws Exception
       
    42   {
       
    43   	//super(file.getName());
       
    44   	super(file.getAbsolutePath().substring(
       
    45   			file.getAbsolutePath().indexOf(File.separator),
       
    46 			file.getAbsolutePath().length()));
       
    47   	
       
    48   	//System.out.println("File name: "+file.getAbsolutePath().substring(
       
    49   	//		file.getAbsolutePath().indexOf("\\"),
       
    50 	//		file.getAbsolutePath().length()));
       
    51   	
       
    52   	this.file = file;
       
    53     this.length = (int)file.length();
       
    54     this.resolveType(file.getAbsolutePath());
       
    55     
       
    56     FileInputStream fis = new FileInputStream(file);
       
    57     data = new byte[(int)file.length()];
       
    58     fis.read(data,0,(int)file.length());
       
    59     fis.close();
       
    60     //System.out.println("Read "+length+" bytes from "+name);
       
    61     createLookupTable();
       
    62     
       
    63 	mapFile = new MapFile(new File(file.getAbsolutePath()+".map"), "", 0); //$NON-NLS-1$ //$NON-NLS-2$
       
    64     
       
    65     if (this.data.length > 0x7C)
       
    66     {
       
    67     	this.offsetToCodeStart = 	( (long)this.data[0x67] << 24)+
       
    68 									( (long)this.data[0x66] << 16)+
       
    69 									( (long)this.data[0x65] << 8)+
       
    70 									( (long)this.data[0x64] );
       
    71 	
       
    72     	this.offsetToCodeStart += 	( (long)this.data[0x4B] << 24)+
       
    73 									( (long)this.data[0x4A] << 16)+
       
    74 									( (long)this.data[0x49] << 8)+
       
    75 									( (long)this.data[0x48] );
       
    76     	
       
    77     	if (this.type == "thumb") this.offsetToCodeStart -=1; //$NON-NLS-1$
       
    78     	
       
    79     	if (this.offsetToCodeStart >= 4) this.offsetToCodeStart -=4;
       
    80     }
       
    81     
       
    82     //System.out.println("Bin "+this.binaryName+" offset "+this.offsetToCodeStart);
       
    83   }
       
    84   
       
    85   public long getOffsetFromBinaryStartForFunction(String functionName)
       
    86   {
       
    87   	if (this.mapFile != null)
       
    88   		return this.mapFile.getOffsetFromBinaryStartForFunction(functionName);
       
    89   	else 
       
    90   		return -1;
       
    91   }
       
    92   
       
    93   private void resolveType(String filePath)
       
    94   {
       
    95   	filePath = filePath.toLowerCase();
       
    96   	filePath = filePath.replace('\\','/');
       
    97   	
       
    98     if ( filePath.indexOf("/thumb/") != -1 ) //$NON-NLS-1$
       
    99     {
       
   100     	this.type = "thumb"; //$NON-NLS-1$
       
   101     }
       
   102     else if ( filePath.indexOf("/armi/") != -1 ) //$NON-NLS-1$
       
   103 			  
       
   104     {
       
   105     	this.type = "armi"; //$NON-NLS-1$
       
   106     }
       
   107     
       
   108     else if ( filePath.indexOf("/momap15xx/") != -1 ) //$NON-NLS-1$
       
   109     {
       
   110     	this.type = "momap15xx"; //$NON-NLS-1$
       
   111     }
       
   112 
       
   113     else if ( filePath.indexOf("/momap16xx/") != -1 ) //$NON-NLS-1$
       
   114     {
       
   115     	this.type = "momap16xx"; //$NON-NLS-1$
       
   116     }
       
   117 
       
   118     else if ( filePath.indexOf("/arm4/") != -1 ) //$NON-NLS-1$
       
   119     {
       
   120     	this.type = "arm4"; //$NON-NLS-1$
       
   121     }
       
   122     else this.type = Messages.getString("ProcessedBinary.unknownType"); //$NON-NLS-1$
       
   123 
       
   124   }
       
   125   
       
   126   public String getFunctionNameForOffset(long offset)
       
   127   {
       
   128   	if (this.mapFile == null) return Messages.getString("ProcessedBinary.mapFileForBinaryNotFound1")+this.binaryName+Messages.getString("ProcessedBinary.mapFileForBinaryNotFound2"); //$NON-NLS-1$ //$NON-NLS-2$
       
   129   	return this.mapFile.getFunctionNameForOffset(offset);
       
   130   }
       
   131   
       
   132   public Function getFunctionForOffset(long offset)
       
   133   {
       
   134   	if (this.mapFile == null) 
       
   135   	{
       
   136   		return null;
       
   137   	}
       
   138   	else
       
   139   	{
       
   140   		String name = this.mapFile.getFunctionNameForOffset(offset);
       
   141   		String dllName = this.binaryName;
       
   142   		
       
   143   		long offsetFromBinaryStart = this.mapFile.getOffsetFromBinaryStartForFunction(name); 
       
   144   		// this cannot be resolved here, since the address is not known
       
   145   		Long addr = new Long(0);
       
   146   		
       
   147   		String search = name + dllName;
       
   148   		Function f = this.knownFunctions.get(search);
       
   149   		
       
   150   		if (f == null) {
       
   151 	  		f = new Function(name,addr,dllName);
       
   152 	  		f.offsetFromBinaryStart = offsetFromBinaryStart;
       
   153 	  		f.length = this.mapFile.getFunctionLengthForOffset(offset);
       
   154 	  		this.knownFunctions.put(search, f);
       
   155   		}
       
   156   		
       
   157   		return f;
       
   158   	}
       
   159   	
       
   160   }
       
   161   
       
   162   public long getFunctionLengthForOffset(long offset)
       
   163   {
       
   164   	if (this.mapFile != null)
       
   165   		return this.mapFile.getFunctionLengthForOffset(offset);
       
   166   	else return 0;
       
   167   }
       
   168 
       
   169   private static class Value
       
   170   {
       
   171     int value;
       
   172 
       
   173     public Value(int value)
       
   174     {this.value = value;}
       
   175   }
       
   176 
       
   177   private void createLookupTable()
       
   178   {
       
   179     Vector[] lookupTable = new Vector[256];
       
   180 
       
   181     //System.out.println("Creating Lookup Table for "+this.name);
       
   182     for (int i=0;i<data.length-1;i++)
       
   183     {
       
   184       //System.out.println("Processing sequence "+Integer.toHexString(value.intValue())+"\n");
       
   185       int unsigned = ((int)data[i] & 0xff);
       
   186 
       
   187       if (lookupTable[unsigned] == null)
       
   188       {
       
   189         Vector v = new Vector();
       
   190         v.add(new Value(i));
       
   191         lookupTable[unsigned] = v;
       
   192         //System.out.println("New Value "+Integer.toHexString(unsigned));
       
   193       }
       
   194       else
       
   195       {
       
   196         Vector v = lookupTable[unsigned];
       
   197         v.add(new Value(i));
       
   198         //System.out.println("Old Value "+Integer.toHexString(unsigned));
       
   199         //System.out.print("e");
       
   200       }
       
   201       //if (i%40 == 0) System.out.print("\n");
       
   202     }
       
   203 
       
   204     this.finalLookupTable = new int[256][];
       
   205     for (int i=0;i<256;i++)
       
   206     {
       
   207       if (lookupTable[i] != null)
       
   208       {
       
   209         this.finalLookupTable[i] = new int[lookupTable[i].size()];
       
   210 
       
   211         Enumeration enumer = lookupTable[i].elements();
       
   212 
       
   213         int element = 0;
       
   214 
       
   215         while (enumer.hasMoreElements())
       
   216         {
       
   217           Value v = (Value) enumer.nextElement();
       
   218           this.finalLookupTable[i][element] = v.value;
       
   219           element++;
       
   220         }
       
   221       }
       
   222     }
       
   223   }
       
   224 
       
   225   public long getInstructionFromOffset(int offset)
       
   226   {
       
   227     long instruction = 0;
       
   228 
       
   229     instruction = ((long)(( (long)this.data[offset+3])   & 0xff));
       
   230     instruction += ((long)((((long)(this.data[offset+2])) & 0xff) << 8));
       
   231     instruction += ((long)((((long)(this.data[offset+1])) & 0xff) << 16));
       
   232     instruction += ((long)((((long)(this.data[offset])) & 0xff) << 24));
       
   233 
       
   234     //System.out.println("INSTRUCTION: "+Integer.toHexString((int)instruction));
       
   235 
       
   236     return instruction;
       
   237   }
       
   238 
       
   239   public long calculateXorChecksum(int startIndex, int lengthInInstructions)
       
   240   {
       
   241     long value = 0;
       
   242     for (int i=0;i<lengthInInstructions;i++)
       
   243     {
       
   244       long instruction = this.getInstructionFromOffset(startIndex+(i*4));
       
   245 
       
   246       // xor the value with the provious value
       
   247       value ^= instruction;
       
   248     }
       
   249     return value;
       
   250   }
       
   251 
       
   252   public int[] getIndicesForSequence(int sequence)
       
   253   {
       
   254     if (sequence < this.finalLookupTable.length)
       
   255     {
       
   256       return this.finalLookupTable[sequence];
       
   257     }
       
   258     else return null;
       
   259   }
       
   260 }