|
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 } |