|
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 "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 using System; |
|
18 using System.IO; |
|
19 using System.Collections; |
|
20 using System.Collections.Generic; |
|
21 using SymbolLib.CodeSegDef; |
|
22 using SymbolLib.Engines.Common; |
|
23 using SymbolLib.Sources.Map.Engine; |
|
24 using SymbolLib.Sources.Map.Parser; |
|
25 using SymbolLib.Sources.Map.File; |
|
26 using SymbolLib.Sources.Symbol.Engine; |
|
27 using SymbolLib.Sources.Symbol.Collection; |
|
28 using SymbolLib.Sources.Symbol.File; |
|
29 using SymbolLib.Generics; |
|
30 using SymbianUtils; |
|
31 using SymbianUtils.Range; |
|
32 using SymbianUtils.Tracer; |
|
33 |
|
34 namespace SymbolLib.Engines.ROFS |
|
35 { |
|
36 public class ROFSEngine : SymbolEngineBase |
|
37 { |
|
38 #region Constructors |
|
39 internal ROFSEngine( ITracer aTracer ) |
|
40 : base( aTracer ) |
|
41 { |
|
42 iEngineMap = new MapFileEngineCollection( this ); |
|
43 iEngineMap.Observer += new SymbianUtils.AsyncReaderBase.Observer( MapEngine_Observer ); |
|
44 |
|
45 iEngineSymbol = new SymbolFileEngineCollection( this, SymbolFileEngine.TActivationType.EOnDemand, true ); |
|
46 iEngineSymbol.Observer += new SymbianUtils.AsyncReaderBase.Observer( SymbolEngine_Observer ); |
|
47 } |
|
48 #endregion |
|
49 |
|
50 #region API |
|
51 public static TFileType IsSupported( string aFileName ) |
|
52 { |
|
53 TFileType ret = TFileType.EFileNotSupported; |
|
54 // |
|
55 try |
|
56 { |
|
57 string extension = Path.GetExtension( aFileName ).ToLower(); |
|
58 if ( extension == ".symbol" ) |
|
59 { |
|
60 bool sawSomeValidContent = false; |
|
61 // |
|
62 SymbolFileEngine tempEngine = new SymbolFileEngine(null, SymbolFileEngine.TActivationType.EOnDemand, true ); |
|
63 SymbolsForBinary symbols = tempEngine.ReadFirstCollection( aFileName, out sawSomeValidContent ); |
|
64 |
|
65 // For a valid ROFS symbol file, the first symbol should have an address of zero. |
|
66 bool valid = ( symbols != null && symbols.Count > 0 && symbols[ 0 ].Address == 0 ); |
|
67 if ( valid ) |
|
68 { |
|
69 ret = TFileType.EFileRofsSymbol; |
|
70 } |
|
71 else if ( sawSomeValidContent ) |
|
72 { |
|
73 // Probably just a file containing data files rather than code, but that's okay. |
|
74 ret = TFileType.EFileRofsSymbol; |
|
75 } |
|
76 } |
|
77 else if ( extension == ".map" ) |
|
78 { |
|
79 ret = MapFileEngineCollection.IsSupported( aFileName ); |
|
80 } |
|
81 } |
|
82 catch(Exception) |
|
83 { |
|
84 } |
|
85 // |
|
86 return ret; |
|
87 } |
|
88 #endregion |
|
89 |
|
90 #region Properties |
|
91 public CodeSegDefinitionParser DefinitionParser |
|
92 { |
|
93 get { return iEngineMap.CodeSegParser; } |
|
94 } |
|
95 |
|
96 public CodeSegResolver DefinitionResolver |
|
97 { |
|
98 get { return iEngineMap.CodeSegResolver; } |
|
99 } |
|
100 |
|
101 public SymbolFileEngineCollection SymbolFiles |
|
102 { |
|
103 get { return iEngineSymbol; } |
|
104 } |
|
105 |
|
106 public string[] SymbolFileNames |
|
107 { |
|
108 get |
|
109 { |
|
110 string[] ret = iEngineSymbol.SymbolFileNames; |
|
111 return ret; |
|
112 } |
|
113 } |
|
114 |
|
115 public string[] SymbolFileCollectionFileNames |
|
116 { |
|
117 get |
|
118 { |
|
119 string[] ret = iEngineSymbol.BinaryFileNames; |
|
120 return ret; |
|
121 } |
|
122 } |
|
123 |
|
124 public List<string> MapFileNames |
|
125 { |
|
126 get |
|
127 { |
|
128 List<string> ret = new List<string>(); |
|
129 lock ( iEngineMap ) |
|
130 { |
|
131 ret.AddRange( iEngineMap.MapFileNames ); |
|
132 } |
|
133 return ret; |
|
134 } |
|
135 } |
|
136 #endregion |
|
137 |
|
138 #region From SymbolEngineBase |
|
139 public override bool AddressInRange( long aAddress ) |
|
140 { |
|
141 // Try map files first, then symbols (should be |
|
142 // quicker this way). |
|
143 bool ret = false; |
|
144 lock ( iEngineMap ) |
|
145 { |
|
146 ret = iEngineMap.Range.Contains( aAddress ); |
|
147 } |
|
148 if ( ret == false ) |
|
149 { |
|
150 lock ( iEngineSymbol ) |
|
151 { |
|
152 ret = iEngineSymbol.Range.Contains( aAddress ); |
|
153 } |
|
154 } |
|
155 // |
|
156 return ret; |
|
157 } |
|
158 |
|
159 public override int FileNameCount |
|
160 { |
|
161 get |
|
162 { |
|
163 int count = 0; |
|
164 // |
|
165 lock ( iEngineSymbol ) |
|
166 { |
|
167 count += iEngineSymbol.SymbolFileCount; |
|
168 } |
|
169 lock ( iEngineMap ) |
|
170 { |
|
171 count += iEngineMap.NumberOfCollections; |
|
172 } |
|
173 // |
|
174 return count; |
|
175 } |
|
176 } |
|
177 |
|
178 public override string FileName( int aIndex ) |
|
179 { |
|
180 string ret = string.Empty; |
|
181 // |
|
182 lock ( iEngineMap ) |
|
183 { |
|
184 lock ( iEngineSymbol ) |
|
185 { |
|
186 int countSymbolFiles = iEngineSymbol.SymbolFileCount; |
|
187 int countMapFiles = iEngineMap.NumberOfCollections; |
|
188 // |
|
189 if ( aIndex < countSymbolFiles ) |
|
190 { |
|
191 ret = iEngineSymbol.SymbolFileName( aIndex ); |
|
192 } |
|
193 else |
|
194 { |
|
195 // Must be a map index |
|
196 aIndex -= countSymbolFiles; |
|
197 // |
|
198 if ( aIndex >= 0 && aIndex < iEngineMap.NumberOfCollections ) |
|
199 { |
|
200 ret = iEngineMap.MapFileName( aIndex ); |
|
201 } |
|
202 } |
|
203 } |
|
204 } |
|
205 // |
|
206 return ret; |
|
207 } |
|
208 |
|
209 public override void LoadFromFile( string aFileName, TSynchronicity aSynchronicity ) |
|
210 { |
|
211 if ( SymbolFileEngine.IsSymbolFile( aFileName ) ) |
|
212 { |
|
213 iEngineSymbol.LoadFromFile( aFileName, aSynchronicity ); |
|
214 } |
|
215 else if ( MapFileEngine.IsMapFile( aFileName ) ) |
|
216 { |
|
217 iEngineMap.LoadFromFile( aFileName, aSynchronicity ); |
|
218 } |
|
219 else |
|
220 { |
|
221 throw new NotSupportedException(); |
|
222 } |
|
223 } |
|
224 |
|
225 public override bool LoadFromDefinition( CodeSegDefinition aDefinition, TSynchronicity aSynchronicity ) |
|
226 { |
|
227 // Try Symbol file first |
|
228 bool wasActivated = false; |
|
229 |
|
230 lock ( this ) |
|
231 { |
|
232 wasActivated = iEngineSymbol.Load( aDefinition ); |
|
233 if ( wasActivated == false ) |
|
234 { |
|
235 wasActivated = iEngineMap.Load( aDefinition, aSynchronicity ); |
|
236 } |
|
237 } |
|
238 |
|
239 return wasActivated; |
|
240 } |
|
241 |
|
242 public override void UnloadAll() |
|
243 { |
|
244 lock ( iEngineMap ) |
|
245 { |
|
246 iEngineMap.UnloadAll(); |
|
247 } |
|
248 lock ( iEngineSymbol ) |
|
249 { |
|
250 iEngineSymbol.UnloadAll(); |
|
251 } |
|
252 } |
|
253 |
|
254 public override bool Unload( CodeSegDefinition aDefinition ) |
|
255 { |
|
256 bool ret = false; |
|
257 lock ( this ) |
|
258 { |
|
259 ret = iEngineMap.Unload( aDefinition ); |
|
260 |
|
261 // Try with the Symbol engine if it wasn't a loaded map codeseg |
|
262 if ( ret == false ) |
|
263 { |
|
264 ret = iEngineSymbol.Unload( aDefinition ); |
|
265 } |
|
266 } |
|
267 |
|
268 return ret; |
|
269 } |
|
270 |
|
271 public override bool IsLoaded( CodeSegDefinition aDefinition ) |
|
272 { |
|
273 bool ret = false; |
|
274 lock ( iEngineMap ) |
|
275 { |
|
276 ret = iEngineMap.IsLoaded( aDefinition ); |
|
277 } |
|
278 if ( ret == false ) |
|
279 { |
|
280 // Try with the Symbol engine if it wasn't a loaded map codeseg |
|
281 lock( iEngineSymbol ) |
|
282 { |
|
283 ret = iEngineSymbol.IsLoaded( aDefinition ); |
|
284 } |
|
285 } |
|
286 |
|
287 return ret; |
|
288 } |
|
289 #endregion |
|
290 |
|
291 #region From GenericSymbolEngine |
|
292 public override bool IsReady |
|
293 { |
|
294 get |
|
295 { |
|
296 bool mapReady = false; |
|
297 lock( iEngineMap ) |
|
298 { |
|
299 mapReady = iEngineMap.IsReady; |
|
300 } |
|
301 // |
|
302 bool symbolReady = false; |
|
303 lock ( iEngineSymbol ) |
|
304 { |
|
305 symbolReady = iEngineSymbol.IsReady; |
|
306 } |
|
307 // |
|
308 bool ret = ( mapReady && symbolReady ); |
|
309 return ret; |
|
310 } |
|
311 } |
|
312 |
|
313 public override void Reset() |
|
314 { |
|
315 lock ( iEngineMap ) |
|
316 { |
|
317 iEngineMap.Reset(); |
|
318 } |
|
319 lock( iEngineSymbol ) |
|
320 { |
|
321 iEngineSymbol.Reset(); |
|
322 } |
|
323 } |
|
324 |
|
325 public override bool IsLoaded( string aFileName ) |
|
326 { |
|
327 bool loaded = false; |
|
328 lock ( iEngineMap ) |
|
329 { |
|
330 loaded = iEngineMap.IsLoaded( aFileName ); |
|
331 } |
|
332 if ( loaded == false ) |
|
333 { |
|
334 lock ( iEngineSymbol ) |
|
335 { |
|
336 loaded = iEngineSymbol.IsLoaded( aFileName ); |
|
337 } |
|
338 } |
|
339 // |
|
340 return loaded; |
|
341 } |
|
342 |
|
343 public override GenericSymbolCollection this[ int aIndex ] |
|
344 { |
|
345 get |
|
346 { |
|
347 GenericSymbolCollection ret = null; |
|
348 // |
|
349 lock ( iEngineMap ) |
|
350 { |
|
351 lock ( iEngineSymbol ) |
|
352 { |
|
353 int mapCount = iEngineMap.NumberOfCollections; |
|
354 if ( aIndex >= 0 && aIndex < mapCount ) |
|
355 { |
|
356 ret = iEngineMap[ aIndex ]; |
|
357 } |
|
358 else |
|
359 { |
|
360 int symbolBaseIndex = ( aIndex - mapCount ); |
|
361 int symbolCount = iEngineSymbol.NumberOfCollections; |
|
362 if ( symbolBaseIndex >= 0 && symbolBaseIndex < symbolCount ) |
|
363 { |
|
364 ret = iEngineSymbol[ symbolBaseIndex ]; |
|
365 } |
|
366 } |
|
367 } |
|
368 } |
|
369 // |
|
370 return ret; |
|
371 } |
|
372 } |
|
373 |
|
374 public override AddressRange Range |
|
375 { |
|
376 get |
|
377 { |
|
378 AddressRange ret = new AddressRange(); |
|
379 // |
|
380 lock ( iEngineMap ) |
|
381 { |
|
382 ret.Update( iEngineMap.Range ); |
|
383 } |
|
384 lock ( iEngineSymbol ) |
|
385 { |
|
386 ret.Update( iEngineSymbol.Range ); |
|
387 } |
|
388 // |
|
389 return ret; |
|
390 } |
|
391 } |
|
392 |
|
393 internal override void UnloadUntagged() |
|
394 { |
|
395 |
|
396 } |
|
397 #endregion |
|
398 |
|
399 #region From IGenericSymbolCollectionStatisticsInterface |
|
400 public override int NumberOfCollections |
|
401 { |
|
402 get |
|
403 { |
|
404 int count = 0; |
|
405 // |
|
406 lock ( iEngineMap ) |
|
407 { |
|
408 count += iEngineMap.NumberOfCollections; |
|
409 } |
|
410 lock ( iEngineSymbol ) |
|
411 { |
|
412 count += iEngineSymbol.NumberOfCollections; |
|
413 } |
|
414 // |
|
415 return count; |
|
416 } |
|
417 } |
|
418 #endregion |
|
419 |
|
420 #region Event handlers |
|
421 private void MapEngine_Observer( SymbianUtils.AsyncReaderBase.TEvent aEvent, SymbianUtils.AsyncReaderBase aSender ) |
|
422 { |
|
423 System.Diagnostics.Debug.Assert( aSender.Tag is MapFileEngine ); |
|
424 MapFileEngine engine = (MapFileEngine) aSender.Tag; |
|
425 // |
|
426 switch( aEvent ) |
|
427 { |
|
428 case SymbianUtils.AsyncReaderBase.TEvent.EReadingStarted: |
|
429 OnParsingStarted( engine.MapFileName ); |
|
430 break; |
|
431 case SymbianUtils.AsyncReaderBase.TEvent.EReadingProgress: |
|
432 OnParsingProgress( engine.MapFileName, aSender.Progress ); |
|
433 break; |
|
434 case SymbianUtils.AsyncReaderBase.TEvent.EReadingComplete: |
|
435 OnParsingCompleted( engine.MapFileName ); |
|
436 break; |
|
437 } |
|
438 } |
|
439 |
|
440 private void MapEngine_MapLoaded( CodeSegDefinition aLoadedEntry, MapFile aMapFile ) |
|
441 { |
|
442 OnCollectionCreated( aMapFile ); |
|
443 } |
|
444 |
|
445 private void SymbolEngine_Observer( SymbianUtils.AsyncReaderBase.TEvent aEvent, SymbianUtils.AsyncReaderBase aSender ) |
|
446 { |
|
447 System.Diagnostics.Debug.Assert( aSender.Tag is SymbolFileEngine ); |
|
448 SymbolFileEngine engine = (SymbolFileEngine) aSender.Tag; |
|
449 // |
|
450 switch( aEvent ) |
|
451 { |
|
452 case SymbianUtils.AsyncReaderBase.TEvent.EReadingStarted: |
|
453 OnParsingStarted( engine.SymbolFileName ); |
|
454 break; |
|
455 case SymbianUtils.AsyncReaderBase.TEvent.EReadingProgress: |
|
456 OnParsingProgress( engine.SymbolFileName, aSender.Progress ); |
|
457 break; |
|
458 case SymbianUtils.AsyncReaderBase.TEvent.EReadingComplete: |
|
459 OnParsingCompleted( engine.SymbolFileName ); |
|
460 break; |
|
461 } |
|
462 } |
|
463 #endregion |
|
464 |
|
465 #region Internal methods |
|
466 #endregion |
|
467 |
|
468 #region Data members |
|
469 private readonly MapFileEngineCollection iEngineMap; |
|
470 private readonly SymbolFileEngineCollection iEngineSymbol; |
|
471 #endregion |
|
472 } |
|
473 } |