1 /*******************************************************************************
2 * Copyright (c) 2013 Ericsson
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * Alexandre Montplaisir - Initial API and implementation
11 * Marc-Andre Laperle - Map from binary file
12 *******************************************************************************/
14 package org
.eclipse
.linuxtools
.tmf
.ui
.views
.callstack
;
16 import java
.io
.BufferedReader
;
18 import java
.io
.FileInputStream
;
19 import java
.io
.FileNotFoundException
;
20 import java
.io
.FileReader
;
21 import java
.io
.IOException
;
22 import java
.io
.InputStream
;
23 import java
.util
.ArrayList
;
24 import java
.util
.Collections
;
25 import java
.util
.HashMap
;
26 import java
.util
.List
;
29 import org
.eclipse
.cdt
.core
.CCorePlugin
;
30 import org
.eclipse
.cdt
.core
.IBinaryParser
;
31 import org
.eclipse
.cdt
.core
.IBinaryParser
.IBinaryFile
;
32 import org
.eclipse
.cdt
.core
.IBinaryParser
.ISymbol
;
33 import org
.eclipse
.core
.runtime
.IConfigurationElement
;
34 import org
.eclipse
.core
.runtime
.IPath
;
35 import org
.eclipse
.core
.runtime
.ISafeRunnable
;
36 import org
.eclipse
.core
.runtime
.Path
;
37 import org
.eclipse
.core
.runtime
.Platform
;
38 import org
.eclipse
.core
.runtime
.SafeRunner
;
39 import org
.eclipse
.jdt
.annotation
.Nullable
;
40 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.Activator
;
43 * Class containing the different methods to import an address->name mapping.
45 * @author Alexandre Montplaisir
47 class FunctionNameMapper
{
49 public static @Nullable Map
<String
, String
> mapFromNmTextFile(File mappingFile
) {
50 Map
<String
, String
> map
= new HashMap
<>();
52 try (FileReader fr
= new FileReader(mappingFile
);
53 BufferedReader reader
= new BufferedReader(fr
);) {
54 for (String line
= reader
.readLine(); line
!= null; line
= reader
.readLine()) {
55 String
[] elems
= line
.split(" "); //$NON-NLS-1$
56 /* Only lines with 3 elements contain addresses */
57 if (elems
.length
== 3) {
58 /* Strip the leading zeroes from the address */
59 String address
= elems
[0].replaceFirst("^0+(?!$)", ""); //$NON-NLS-1$ //$NON-NLS-2$;
60 String name
= elems
[elems
.length
- 1];
61 map
.put(address
, name
);
64 } catch (FileNotFoundException e
) {
66 } catch (IOException e
) {
67 /* Stop reading the file at this point */
73 return Collections
.unmodifiableMap(map
);
77 * Strip the leading zeroes from the address
79 private static String
stripLeadingZeros(String address
) {
80 return address
.replaceFirst("^0+(?!$)", ""); //$NON-NLS-1$ //$NON-NLS-2$;
83 public static @Nullable Map
<String
, String
> mapFromBinaryFile(File file
) {
84 Map
<String
, String
> map
= new HashMap
<>();
85 IBinaryParser
.IBinaryObject binaryObject
= getBinaryObject(file
);
86 if (binaryObject
!= null) {
87 ISymbol
[] symbols
= binaryObject
.getSymbols();
88 for (ISymbol symbol
: symbols
) {
89 String address
= symbol
.getAddress().toHexAddressString();
91 address
= address
.substring(2);
92 /* Strip the leading zeroes from the address */
93 address
= stripLeadingZeros(address
);
94 map
.put(address
, symbol
.getName());
101 private static @Nullable IBinaryParser
.IBinaryObject
getBinaryObject(File file
) {
102 IPath filePath
= new Path(file
.toString());
104 /* Get all the available binary parsers */
105 final List
<IBinaryParser
> binaryParsers
= new ArrayList
<>();
106 IConfigurationElement
[] elements
= Platform
.getExtensionRegistry()
107 .getConfigurationElementsFor(CCorePlugin
.BINARY_PARSER_UNIQ_ID
);
108 for (IConfigurationElement element
: elements
) {
109 IConfigurationElement
[] children
= element
.getChildren("run"); //$NON-NLS-1$
110 for (final IConfigurationElement run
: children
) {
111 SafeRunner
.run(new ISafeRunnable() {
113 public void run() throws Exception
{
114 IBinaryParser binaryParser
= (IBinaryParser
) run
.createExecutableExtension("class"); //$NON-NLS-1$
115 binaryParsers
.add(binaryParser
);
119 public void handleException(Throwable exception
) {
120 Activator
.getDefault().logError("Error creating binary parser", exception
); //$NON-NLS-1$
126 /* Find the maximum "hint" buffer size we'll need from all the parsers */
127 int hintBufferSize
= 0;
128 for (IBinaryParser parser
: binaryParsers
) {
129 if (parser
.getHintBufferSize() > hintBufferSize
) {
130 hintBufferSize
= Math
.max(hintBufferSize
, parser
.getHintBufferSize());
134 /* Read the initial "hint" bytes */
135 byte[] hintBuffer
= new byte[hintBufferSize
];
136 if (hintBufferSize
> 0) {
137 try (InputStream is
= new FileInputStream(file
) ){
140 // Make sure we read up to 'hints' bytes if we possibly can
141 while (count
< hintBufferSize
) {
142 int bytesRead
= is
.read(hintBuffer
, count
, hintBufferSize
- count
);
148 if (count
> 0 && count
< hintBuffer
.length
) {
149 byte[] array
= new byte[count
];
150 System
.arraycopy(hintBuffer
, 0, array
, 0, count
);
153 } catch (IOException e
) {
154 Activator
.getDefault().logError("Error reading initial bytes of binary file", e
); //$NON-NLS-1$
159 /* For all binary parsers, try to get a binary object */
160 for (IBinaryParser parser
: binaryParsers
) {
161 if (parser
.isBinary(hintBuffer
, filePath
)) {
164 binFile
= parser
.getBinary(hintBuffer
, filePath
);
165 if (binFile
!= null && binFile
instanceof IBinaryParser
.IBinaryObject
) {
166 return (IBinaryParser
.IBinaryObject
)binFile
;
168 } catch (IOException e
) {
169 Activator
.getDefault().logError("Error parsing binary file", e
); //$NON-NLS-1$