sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.instr/src/com/nokia/carbide/cpp/pi/instr/MapFile.java
changeset 5 844b047e260d
parent 2 b9ab3b238396
child 12 ae255c9aa552
equal deleted inserted replaced
4:615035072f7e 5:844b047e260d
    44 	private ArrayList<Function> sortedFunctionData;
    44 	private ArrayList<Function> sortedFunctionData;
    45 	private Long currentGccLibEndingOffset = new Long(0);
    45 	private Long currentGccLibEndingOffset = new Long(0);
    46 	private Function lastGccFunction = null;
    46 	private Function lastGccFunction = null;
    47 	
    47 	
    48 	// RVCT/RVDS map file line
    48 	// RVCT/RVDS map file line
    49 	private static final Pattern rvctLinePattern = Pattern.compile("\\p{Blank}*((?!\\d)\\S.+)\\p{Blank}+(0[x|X]\\p{XDigit}+|\\d+)\\p{Blank}+(?:ARM Code|Thumb Code)\\p{Blank}+(0x\\p{XDigit}+|\\d+)\\p{Blank}*.*");	//$NON-NLS-1$
    49 	private static final Pattern rvctLinePattern = Pattern.compile("^\\p{Blank}*((?!\\d)\\S.+)\\p{Blank}+(0[x|X]\\p{XDigit}+|\\d+)\\p{Blank}+(?:ARM Code|Thumb Code)\\p{Blank}+(0x\\p{XDigit}+|\\d+)\\p{Blank}.*\\(\\.text\\)$");	//$NON-NLS-1$
    50 
    50 
    51 	// a GCC map file line looks like this:
    51 	// a GCC map file line looks like this:
    52 	// <%x|%d> <symbol name> for function symbols
    52 	// <%x|%d> <symbol name> for function symbols
    53 	// symbol name cannot be number (e.g. first non space is not a digit)
    53 	// symbol name cannot be number (e.g. first non space is not a digit)
    54 	private static final Pattern gccFuncLinePattern  = Pattern.compile("\\p{Blank}*(0[x|X]\\p{XDigit}+|\\d+)\\p{Blank}+((?!\\d)\\S.+)");	//$NON-NLS-1$
    54 	private static final Pattern gccFuncLinePattern  = Pattern.compile("\\p{Blank}*(0[x|X]\\p{XDigit}+|\\d+)\\p{Blank}+((?!\\d)\\S.+)");	//$NON-NLS-1$
    55 
    55 
    56 	// <section> <%x|%d> <%x|%d> <symbol name>	for whole library
    56 	// <section> <%x|%d> <%x|%d> <symbol name>	for whole library
    57 	// *fill* <%x|%d> <%x|%d> 00000000 for filler
    57 	// *fill* <%x|%d> <%x|%d> 00000000 for filler
    58 	private static final Pattern gccLibOrFillerLinePattern = Pattern.compile("\\p{Blank}*(?:\\S*)\\p{Blank}*(0[x|X]\\p{XDigit}+|\\d+)\\p{Blank}+(0[x|X]\\p{XDigit}+|\\d+)\\p{Blank}+(\\S.+)"); //$NON-NLS-1$
    58 	private static final Pattern gccLibOrFillerLinePattern = Pattern.compile("\\p{Blank}*(?:\\S*)\\p{Blank}*(0[x|X]\\p{XDigit}+|\\d+)\\p{Blank}+(0[x|X]\\p{XDigit}+|\\d+)\\p{Blank}+(\\S.+)"); //$NON-NLS-1$
    59 
    59 
       
    60 	private static final String EXPORTED = " (EXPORTED)";
    60 
    61 
    61 	public MapFile(File file, String referencePath, long referenceLineNumber)
    62 	public MapFile(File file, String referencePath, long referenceLineNumber)
    62 	{
    63 	{
    63 		if (!file.exists())
    64 		if (!file.exists())
    64 		{
    65 		{
   105 		for (Function f : sortedFunctionData)
   106 		for (Function f : sortedFunctionData)
   106 		{
   107 		{
   107 			// is the asked offset within the area of this function
   108 			// is the asked offset within the area of this function
   108 			// test first is the offset equal or past the first
   109 			// test first is the offset equal or past the first
   109 			// instruction of the function
   110 			// instruction of the function
   110 			if (offset >= f.offsetFromBinaryStart)
   111 			if (offset >= f.getOffsetFromBinaryStart())
   111 			{
   112 			{
   112 				// if so, make sure that the offset is less
   113 				// if so, make sure that the offset is less
   113 				// or equal to the last instruction within 
   114 				// or equal to the last instruction within 
   114 				// this function
   115 				// this function
   115 				if (offset < (f.offsetFromBinaryStart+f.length))
   116 				if (offset < (f.getOffsetFromBinaryStart()+f.getLength()))
   116 				{
   117 				{
   117 					return f.functionName;
   118 					return f.getFunctionName();
   118 				}
   119 				}
   119 			}
   120 			}
   120 		}
   121 		}
   121 		
   122 		
   122 		return Messages.getString("MapFile.functionWithOffsetNotFound1")+offset+Messages.getString("MapFile.functionWithOffsetNotFound2")+this.name+ //$NON-NLS-1$ //$NON-NLS-2$
   123 		return Messages.getString("MapFile.functionWithOffsetNotFound1")+offset+Messages.getString("MapFile.functionWithOffsetNotFound2")+this.name+ //$NON-NLS-1$ //$NON-NLS-2$
   123 				Messages.getString("MapFile.functionWithOffsetNotFound3")+ //$NON-NLS-1$
   124 				Messages.getString("MapFile.functionWithOffsetNotFound3")+ //$NON-NLS-1$
   124 				(this.sortedFunctionData.get(this.sortedFunctionData.size() - 1)).offsetFromBinaryStart; 		 //$NON-NLS-1$
   125 				(this.sortedFunctionData.get(this.sortedFunctionData.size() - 1)).getOffsetFromBinaryStart(); 		 //$NON-NLS-1$
   125 	}
   126 	}
   126 	
   127 	
   127 	public Function getFunctionForOffset(long offset)
   128 	public Function getFunctionForOffset(long offset)
   128 	{
   129 	{
   129 		if (!this.parsedMapFile) {
   130 		if (!this.parsedMapFile) {
   134 		for (Function f : sortedFunctionData)
   135 		for (Function f : sortedFunctionData)
   135 		{
   136 		{
   136 			// is the asked offset within the area of this function
   137 			// is the asked offset within the area of this function
   137 			// test first is the offset equal or past the first
   138 			// test first is the offset equal or past the first
   138 			// instruction of the function
   139 			// instruction of the function
   139 			if (offset >= f.offsetFromBinaryStart)
   140 			if (offset >= f.getOffsetFromBinaryStart())
   140 			{
   141 			{
   141 				// if so, make sure that the offset is less
   142 				// if so, make sure that the offset is less
   142 				// or equal to the last instruction within 
   143 				// or equal to the last instruction within 
   143 				// this function
   144 				// this function
   144 				if (offset < (f.offsetFromBinaryStart+f.length))
   145 				if (offset < (f.getOffsetFromBinaryStart()+f.getLength()))
   145 				{
   146 				{
   146 					return f;
   147 					return f;
   147 				}
   148 				}
   148 			}
   149 			}
   149 		}
   150 		}
   161 		for (Function f : sortedFunctionData)
   162 		for (Function f : sortedFunctionData)
   162 		{
   163 		{
   163 			// is the asked offset within the area of this function
   164 			// is the asked offset within the area of this function
   164 			// test first is the offset equal or past the first
   165 			// test first is the offset equal or past the first
   165 			// instruction of the function
   166 			// instruction of the function
   166 			if (offset >= f.offsetFromBinaryStart)
   167 			if (offset >= f.getOffsetFromBinaryStart())
   167 			{
   168 			{
   168 				// if so, make sure that the offset is less
   169 				// if so, make sure that the offset is less
   169 				// or equal to the last instruction within 
   170 				// or equal to the last instruction within 
   170 				// this function
   171 				// this function
   171 				if (offset < (f.offsetFromBinaryStart+f.length))
   172 				if (offset < (f.getOffsetFromBinaryStart()+f.getLength()))
   172 				{
   173 				{
   173 					return f.length;
   174 					return f.getLength();
   174 				}
   175 				}
   175 			}
   176 			}
   176 		}
   177 		}
   177 		return 0; 		
   178 		return 0; 		
   178 	}
   179 	}
   184 			this.copyToSortedFunctionData();
   185 			this.copyToSortedFunctionData();
   185 		}
   186 		}
   186 
   187 
   187 		for (Function f : sortedFunctionData)
   188 		for (Function f : sortedFunctionData)
   188 		{
   189 		{
   189 			if (f.functionName.equals(functionName))
   190 			if (f.getFunctionName().equals(functionName))
   190 			{
   191 			{
   191 				return f.offsetFromBinaryStart;
   192 				return f.getOffsetFromBinaryStart();
   192 			}
   193 			}
   193 		}
   194 		}
   194 		return -1;
   195 		return -1;
   195 	}
   196 	}
   196 	
   197 	
   197 	private Function FunctionFromTokens(String funcNameToken, String funcOffsetToken, String funcLengthToken)
   198 	private Function FunctionFromTokens(String funcNameToken, String funcOffsetToken, String funcLengthToken)
   198 	{	
   199 	{	
   199 		Function f = new Function(funcNameToken,new Long(0),null);
   200 		Function f = new Function(funcNameToken,Long.valueOf(0),null);
   200 		// look for length, set it tentatively
   201 		// look for length, set it tentatively
   201 		// we may adjust it later
   202 		// we may adjust it later
   202 		f.length = Long.decode(funcLengthToken);
   203 		f.setLength(Long.decode(funcLengthToken));
   203 		f.offsetFromBinaryStart = Long.decode(funcOffsetToken);
   204 		f.setOffsetFromBinaryStart( Long.decode(funcOffsetToken));
   204 
   205 
   205 		return f;
   206 		return f;
   206 	}
   207 	}
   207 	
   208 	
   208 	private void parseMapFile()
   209 	private void parseMapFile()
   294 		{
   295 		{
   295 			String funcNameToken = rvctLineMatcher.group(1).trim();
   296 			String funcNameToken = rvctLineMatcher.group(1).trim();
   296 			// internal symbol, not a function
   297 			// internal symbol, not a function
   297 			if (funcNameToken.indexOf(Messages.getString("MapFile.dollarSign")) != -1) //$NON-NLS-1$
   298 			if (funcNameToken.indexOf(Messages.getString("MapFile.dollarSign")) != -1) //$NON-NLS-1$
   298 				return;
   299 				return;
       
   300 			if(funcNameToken.endsWith(EXPORTED)){
       
   301 				funcNameToken = funcNameToken.substring(0, funcNameToken.lastIndexOf(EXPORTED));
       
   302 			}
   299 			
   303 			
   300 			String funcOffsetToken = rvctLineMatcher.group(2).trim();
   304 			String funcOffsetToken = rvctLineMatcher.group(2).trim();
   301 			
   305 			
   302 			if (funcOffsetToken.equalsIgnoreCase("0x00000001") && line.contains("Thumb Code"))
   306 			if (funcOffsetToken.equalsIgnoreCase("0x00000001") && line.contains("Thumb Code")) //$NON-NLS-1$ //$NON-NLS-2$
   303 				return;
   307 				return;
   304 			
   308 			
   305 			String funcLengthToken = rvctLineMatcher.group(3).trim();
   309 			String funcLengthToken = rvctLineMatcher.group(3).trim();
   306 			
   310 			
   307 			Function f = FunctionFromTokens(funcNameToken, funcOffsetToken, funcLengthToken);
   311 			Function f = FunctionFromTokens(funcNameToken, funcOffsetToken, funcLengthToken);
   362 			String funcLengthToken = Messages.getString("MapFile.zero"); //$NON-NLS-1$
   366 			String funcLengthToken = Messages.getString("MapFile.zero"); //$NON-NLS-1$
   363 			
   367 			
   364 			f = FunctionFromTokens(funcNameToken, funcOffsetToken, funcLengthToken);
   368 			f = FunctionFromTokens(funcNameToken, funcOffsetToken, funcLengthToken);
   365 			
   369 			
   366 			// Some GCC symbol may be bogus
   370 			// Some GCC symbol may be bogus
   367 			if (qualifyGCCSymbol(f.offsetFromBinaryStart, funcNameToken)) {
   371 			if (qualifyGCCSymbol(f.getOffsetFromBinaryStart(), funcNameToken)) {
   368 				this.insertToFunctionData(f);
   372 				this.insertToFunctionData(f);
   369 			} 
   373 			} 
   370 			
   374 			
   371 			if (lastGccFunction != null){
   375 			if (lastGccFunction != null){
   372 				// calculate size of last function with offset from current line
   376 				// calculate size of last function with offset from current line
   373 				if (f.offsetFromBinaryStart > lastGccFunction.offsetFromBinaryStart &&
   377 				if (f.getOffsetFromBinaryStart() > lastGccFunction.getOffsetFromBinaryStart() &&
   374 						f.offsetFromBinaryStart < currentGccLibEndingOffset) {
   378 						f.getOffsetFromBinaryStart() < currentGccLibEndingOffset) {
   375 					currentLineOffset = f.offsetFromBinaryStart;
   379 					currentLineOffset = f.getOffsetFromBinaryStart();
   376 				}
   380 				}
   377 			}
   381 			}
   378 			
   382 			
   379 		} else if (gccLibOrFillerLineMatcher.matches()) {
   383 		} else if (gccLibOrFillerLineMatcher.matches()) {
   380 			String libOffsetToken = gccLibOrFillerLineMatcher.group(1).trim();
   384 			String libOffsetToken = gccLibOrFillerLineMatcher.group(1).trim();
   387 		}
   391 		}
   388 		
   392 		
   389 		// update last function's size if needed
   393 		// update last function's size if needed
   390 		if (lastGccFunction != null)
   394 		if (lastGccFunction != null)
   391 		{
   395 		{
   392 			if (currentLineOffset > lastGccFunction.offsetFromBinaryStart) {
   396 			if (currentLineOffset > lastGccFunction.getOffsetFromBinaryStart()) {
   393 				lastGccFunction.length = currentLineOffset - lastGccFunction.offsetFromBinaryStart;
   397 				lastGccFunction.setLength(currentLineOffset - lastGccFunction.getOffsetFromBinaryStart());
   394 			}
   398 			}
   395 		}
   399 		}
   396 		
   400 		
   397 		// track function on this line as last function, or null if this line is not a function
   401 		// track function on this line as last function, or null if this line is not a function
   398 		lastGccFunction = f;
   402 		lastGccFunction = f;
   403 	{
   407 	{
   404 		if (functionData.size() == 0) 
   408 		if (functionData.size() == 0) 
   405 		{
   409 		{
   406 			functionData.addFirst(function);
   410 			functionData.addFirst(function);
   407 		}
   411 		}
   408 		else if ((functionData.getFirst()).offsetFromBinaryStart 
   412 		else if ((functionData.getFirst()).getOffsetFromBinaryStart() 
   409 					< function.offsetFromBinaryStart)
   413 					< function.getOffsetFromBinaryStart())
   410 		{
   414 		{
   411 			functionData.addFirst(function);
   415 			functionData.addFirst(function);
   412 		}
   416 		}
   413 		else if ((functionData.getLast()).offsetFromBinaryStart 
   417 		else if ((functionData.getLast()).getOffsetFromBinaryStart() 
   414 					> function.offsetFromBinaryStart)
   418 					> function.getOffsetFromBinaryStart())
   415 		{
   419 		{
   416 			functionData.addLast(function);
   420 			functionData.addLast(function);
   417 		}
   421 		}
   418 		else
   422 		else
   419 		{
   423 		{
   420 			for (int i=0;i<functionData.size();i++)
   424 			for (int i=0;i<functionData.size();i++)
   421 			{
   425 			{
   422 				if ((functionData.get(i)).offsetFromBinaryStart 
   426 				if ((functionData.get(i)).getOffsetFromBinaryStart() 
   423 						< function.offsetFromBinaryStart)
   427 						< function.getOffsetFromBinaryStart())
   424 				{
   428 				{
   425 					functionData.add(i,function);
   429 					functionData.add(i,function);
   426 					break;
   430 					break;
   427 				}
   431 				}
   428 			}
   432 			}
   433 	{
   437 	{
   434 		if (this.functionData.size() <= 0) {
   438 		if (this.functionData.size() <= 0) {
   435 			return;
   439 			return;
   436 		}
   440 		}
   437 		this.sortedFunctionData.clear();
   441 		this.sortedFunctionData.clear();
   438 		long start = (this.functionData.getLast()).offsetFromBinaryStart;
   442 		long start = (this.functionData.getLast()).getOffsetFromBinaryStart();
   439 		Function previous = null;
   443 		Function previous = null;
   440 		boolean reallyAdded = false;
   444 		boolean reallyAdded = false;
   441 		
   445 		
   442 		for (int i=this.functionData.size()-1;i>=0;i--)
   446 		for (int i=this.functionData.size()-1;i>=0;i--)
   443 		{
   447 		{
   444 			//System.out.println(i);
   448 			//System.out.println(i);
   445 			Function f = this.functionData.get(i);
   449 			Function f = this.functionData.get(i);
   446 			f.offsetFromBinaryStart = f.offsetFromBinaryStart - start;
   450 			f.setOffsetFromBinaryStart(f.getOffsetFromBinaryStart() - start);
   447 			
   451 			
   448 			if (this.sortedFunctionData.size() == 0)
   452 			if (this.sortedFunctionData.size() == 0)
   449 			{
   453 			{
   450 				// add the function if the vector is empty
   454 				// add the function if the vector is empty
   451 				this.sortedFunctionData.add(f);
   455 				this.sortedFunctionData.add(f);
   452 				reallyAdded = true;
   456 				reallyAdded = true;
   453 			}
   457 			}
   454 			else if ( (this.sortedFunctionData.get(this.sortedFunctionData.size()-1)).offsetFromBinaryStart != f.offsetFromBinaryStart)
   458 			else if ( (this.sortedFunctionData.get(this.sortedFunctionData.size()-1)).getOffsetFromBinaryStart() != f.getOffsetFromBinaryStart())
   455 			{
   459 			{
   456 				// add the function if the offset is not the same as with the previous line
   460 				// add the function if the offset is not the same as with the previous line
   457 				this.sortedFunctionData.add(f);
   461 				this.sortedFunctionData.add(f);
   458 				reallyAdded = true;
   462 				reallyAdded = true;
   459 			}	
   463 			}	
   460 			else if ( (this.sortedFunctionData.get(this.sortedFunctionData.size()-1)).functionName.startsWith("_")) //$NON-NLS-1$
   464 			else if ( (this.sortedFunctionData.get(this.sortedFunctionData.size()-1)).getFunctionName().startsWith("_")) //$NON-NLS-1$
   461 			{	
   465 			{	
   462 				// if there is a key with this offset, discard the previous with prefix "_"
   466 				// if there is a key with this offset, discard the previous with prefix "_"
   463 				this.sortedFunctionData.remove(this.sortedFunctionData.get(this.sortedFunctionData.size()-1));
   467 				this.sortedFunctionData.remove(this.sortedFunctionData.get(this.sortedFunctionData.size()-1));
   464 				// add the new function with the same key
   468 				// add the new function with the same key
   465 				this.sortedFunctionData.add(f);
   469 				this.sortedFunctionData.add(f);
   469 			// do this only if we really added the function to the sorted list
   473 			// do this only if we really added the function to the sorted list
   470 			if (reallyAdded == true)
   474 			if (reallyAdded == true)
   471 			{
   475 			{
   472 				// store the length of the previous function
   476 				// store the length of the previous function
   473 				if (previous != null)
   477 				if (previous != null)
   474 					previous.length = f.offsetFromBinaryStart - previous.offsetFromBinaryStart;
   478 					previous.setLength(f.getOffsetFromBinaryStart() - previous.getOffsetFromBinaryStart());
   475 				previous = f;	
   479 				previous = f;	
   476 				reallyAdded = false;
   480 				reallyAdded = false;
   477 			}
   481 			}
   478 			
   482 			
   479 		}
   483 		}
   493 		}
   497 		}
   494 	}
   498 	}
   495 	*/
   499 	*/
   496 	
   500 	
   497 	private void flagFileNotFound(File file, String referencePath, long referenceLineNumber) {
   501 	private void flagFileNotFound(File file, String referencePath, long referenceLineNumber) {
   498 		  String myMessage = Messages.getString("MapFile.map.file") +  file.getAbsoluteFile().getName() + Messages.getString("MapFile.not.found"); //$NON-NLS-1$ //$NON-NLS-2$
   502 		  String myMessage = Messages.getString("MapFile.map.file") +  file.getAbsoluteFile() + Messages.getString("MapFile.not.found"); //$NON-NLS-1$ //$NON-NLS-2$
       
   503 		  myMessage += Messages.getString("MapFile.map.check.project"); //$NON-NLS-1$
   499 		  if (referencePath != null && referencePath.length() > 0) {
   504 		  if (referencePath != null && referencePath.length() > 0) {
   500 			  myMessage += Messages.getString("MapFile.referenced.by") + referencePath; //$NON-NLS-1$
   505 			  myMessage += Messages.getString("MapFile.referenced.by") + referencePath; //$NON-NLS-1$
   501 		  }
   506 		  }
   502 		  if (referenceLineNumber > 0) {
   507 		  if (referenceLineNumber > 0) {
   503 			  myMessage += Messages.getString("MapFile.line.number") + referenceLineNumber; //$NON-NLS-1$
   508 			  myMessage += Messages.getString("MapFile.line.number") + referenceLineNumber; //$NON-NLS-1$
   504 		  }
   509 		  }
   505 
   510 		  
   506     	  GeneralMessages.PiLog(myMessage, GeneralMessages.ERROR);
   511     	  GeneralMessages.PiLog(myMessage, GeneralMessages.WARNING);
   507 	}
   512 	}
   508 
   513 
   509 	private void flagIOException(File file, String referencePath, long referenceLineNumber) {
   514 	private void flagIOException(File file, String referencePath, long referenceLineNumber) {
   510 		  String myMessage = Messages.getString("MapFile.map.file") + file.getAbsoluteFile().getName() + Messages.getString("MapFile.ioexception"); //$NON-NLS-1$ //$NON-NLS-2$
   515 		  String myMessage = Messages.getString("MapFile.map.file") + file.getAbsoluteFile().getName() + Messages.getString("MapFile.ioexception"); //$NON-NLS-1$ //$NON-NLS-2$
   511 		  if (referencePath != null && referencePath.length() > 0) {
   516 		  if (referencePath != null && referencePath.length() > 0) {