sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/resolvers/SymbolFileFunctionResolver.java
changeset 2 b9ab3b238396
child 12 ae255c9aa552
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/resolvers/SymbolFileFunctionResolver.java	Thu Feb 11 15:32:31 2010 +0200
@@ -0,0 +1,216 @@
+/*
+ * 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.internal.pi.resolvers;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import com.nokia.carbide.cpp.pi.util.GeneralMessages;
+
+public class SymbolFileFunctionResolver extends CachedFunctionResolver {
+	private boolean debug = false;
+	
+	@Override
+	public void parseAndProcessSymbolFile(File symbolFile) {
+	{
+		/*
+		 * From    \\epoc32\\release\\armv5\\urel\\foobar.exe
+		 * f80130b4    0000    __some_func                              k_entry_.o(.emb_text)
+		 * f8013e5c    0014    NKern::SomeFunc(unsigned long&, unsigned long&)  _reka2_ekern.in(.emb_text)
+		 * f9165ea8    0008    thunk{-4} to SomeClass::SomeFunc(CustType*, int(*)(const void*))  SVGEngine.in(.text)
+		 */
+		
+		Pattern binaryLinePattern  = Pattern.compile("From\\p{Blank}+(\\S.+)\\p{Blank}*");	//$NON-NLS-1$
+  		Pattern symbolLinePattern1 = Pattern.compile("(\\p{XDigit}+)\\p{Blank}+(\\p{XDigit}+)\\p{Blank}+((?!\\d)\\S.+)\\p{Blank}+(\\S.+)");	//$NON-NLS-1$
+ 
+		ArrayList<SymbolFileDllItem> dllTable = new ArrayList<SymbolFileDllItem>();
+		SymbolFileDllItem currentDll = null;
+
+	    BufferedReader br;
+		try {
+		    SymbolFileFunctionItem pendingItem = null;
+		    SymbolFileFunctionItem previousItem = null;
+		    
+		    Matcher symbolLineMatcher;
+		    
+			long lineNumber = 0;
+			br = new BufferedReader(new FileReader(symbolFile));
+			this.ableToResolve = true;
+
+			while(br.ready())
+		    {
+		    	String line = br.readLine();
+		    	++lineNumber;
+		    	if (line == null)
+		    		continue;
+		      
+		    	symbolLineMatcher = symbolLinePattern1.matcher(line);
+				
+				if (symbolLineMatcher.matches()) {
+					
+		            long address = Long.parseLong(symbolLineMatcher.group(1),16);
+		            long length = Long.parseLong(symbolLineMatcher.group(2),16);
+		            String name = symbolLineMatcher.group(3).trim();
+		            String section = symbolLineMatcher.group(4);
+		            
+		            if (skipSymbolFromSection(section, length)) {
+		            	continue;
+		            }
+		            
+		            if (currentDll.uninitialised == true)
+		            {
+		              currentDll.uninitialised = false;
+		              currentDll.start = address;
+		            }
+
+		            if ((address+length) <= (currentDll.start+(1024*1024*20)) 
+		            		&& (address+length) >= currentDll.end 
+		            		&& address != 0xffffffffL )
+		            {
+		            	if (pendingItem != null)
+		            	{
+		            		// the pending item has to be completed with the 
+		            		// address known about this function
+		            		long pendingLength = address-pendingItem.address;
+		           			pendingItem.length = pendingLength;
+		           			// the pending item could be completed, add it to the function list
+		           			currentDll.data.add(pendingItem);
+		            		
+		            		pendingItem = null;
+		            	}
+		            	
+		            	if (previousItem != null)
+		            	{
+		            		if (previousItem.address+previousItem.length < address)
+		            		{
+		            			long gapAddress = previousItem.address+previousItem.length;
+		            			long gapLength = address-previousItem.address-previousItem.length;
+		            			
+		           				String gapName = Messages.getString("SymbolFileFunctionResolver.possibleStaticFunction1")+(gapLength)+Messages.getString("SymbolFileFunctionResolver.possibleStaticFunction2")+ //$NON-NLS-1$ //$NON-NLS-2$
+											 	Long.toHexString(gapAddress)+Messages.getString("SymbolFileFunctionResolver.possibleStaticFunction3")+ //$NON-NLS-1$
+											 	Long.toHexString(address);
+		           				SymbolFileFunctionItem gapItem = new SymbolFileFunctionItem(gapName,gapAddress,gapLength,currentDll);
+		           			
+		           				currentDll.data.add(gapItem);
+		            		}
+		            		
+		            		else if (previousItem.address+previousItem.length > address)
+		            		{
+		            			//These overlaps happen in symbol files from some device's ROM
+		            			//and don't seems to be a problem in our code.
+		            			if (debug) {
+			            			String outString = Messages.getString("SymbolFileFunctionResolver.debugOverlap1")+ //$NON-NLS-1$
+	            					Long.toHexString(previousItem.address+previousItem.length)+
+									Messages.getString("SymbolFileFunctionResolver.debugOverlap2")+ //$NON-NLS-1$
+									Long.toHexString(address)+Messages.getString("SymbolFileFunctionResolver.debugOverlap3")+previousItem.name+Messages.getString("SymbolFileFunctionResolver.debugOverlap4")+name; //$NON-NLS-1$ //$NON-NLS-2$
+			            			//GeneralMessages.showWarningMessage(outString);
+		            				System.out.println(outString);
+		            			}
+		            		}
+		            	}
+		            	
+		        		if (length == 0)
+		                {
+		                	currentDll.end = address;
+		                	
+		        			// if the length of this function is not known,
+		        			// add it to be completed when the next function is parsed
+		        			// this assumes that the length of the function is the space
+		        			// between this function and the next function
+		                	pendingItem = new SymbolFileFunctionItem(name,address,length,currentDll);
+		                	
+		                	// update the previous item
+		                	previousItem = pendingItem;
+		                }
+		        		else
+		        		{
+		                	currentDll.end = address+length;
+		                    SymbolFileFunctionItem function = new SymbolFileFunctionItem(name,address,length,currentDll);
+		                    currentDll.data.add(function);
+		                    
+		                    // update the previous item
+		                    previousItem = function;
+		                    
+		                    // there is no pending item since the function was added here
+		                    pendingItem = null;
+		        		}
+		            }
+
+	            } else if (binaryLinePattern.matcher(line).matches()) {
+					
+		          	pendingItem = null;
+		          	previousItem = null;
+
+		            currentDll = new SymbolFileDllItem();
+		            if (line.indexOf('\\') != -1)
+		            {
+		            	currentDll.name = line.substring(line.indexOf('\\'),line.length());
+		            }
+		            else
+		            {
+		            	currentDll.name = line.substring(0,line.length());
+		            }
+		            dllTable.add(currentDll);
+		            
+				} else {
+						
+	            	if (debug) System.out.println(Messages.getString("SymbolFileFunctionResolver.skippingLine")+line); //$NON-NLS-1$
+				}
+		    }
+
+		    if (br != null)
+		    	br.close();
+		} catch (FileNotFoundException e) {
+			GeneralMessages.PiLog(Messages.getString("SymbolFileFunctionResolver.symbol.file1") +  symbolFile + Messages.getString("SymbolFileFunctionResolver.not.found"), GeneralMessages.ERROR); //$NON-NLS-1$ //$NON-NLS-2$
+		} catch (IOException e) {
+			String myMessage = Messages.getString("SymbolFileFunctionResolver.symbol.file2") +  symbolFile + Messages.getString("SymbolFileFunctionResolver.ioexception"); //$NON-NLS-1$ //$NON-NLS-2$
+			GeneralMessages.showErrorMessage(myMessage);
+			GeneralMessages.PiLog(myMessage, GeneralMessages.ERROR);
+		}
+
+	    // this breaks the symbol file parser, use for testing itt trace
+	    //dllTable.clear();
+	    
+	    if (debug) System.out.println(Messages.getString("SymbolFileFunctionResolver.dllCount")+dllTable.size()); //$NON-NLS-1$
+	    addAllToDllList(dllTable);
+	  }
+	}
+
+	private boolean skipSymbolFromSection(String section, long length) {
+        
+        if (section.endsWith("(.data)") || section.endsWith("(.bss)") || section.endsWith("(linker$$defined$$symbols)")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        	return true;
+        }
+        
+        if (length == 0 && section.endsWith("(.init_array)")) { //$NON-NLS-1$
+        	return true;
+        }
+        
+        if (section.contains("(.data_")) {	// (.data__ZZ33ifPowerTraceIdIsEnabledCallCbOncePFvPvES_mE9isPrinted) //$NON-NLS-1$
+        	return true;
+        }
+        
+		return false;
+	}
+}