|
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 |
|
18 using System; |
|
19 using System.Collections.Generic; |
|
20 using System.Text; |
|
21 using SymbianUtils.Tracer; |
|
22 using SymbianUtils.BasicTypes; |
|
23 using SymbianStructuresLib.Arm; |
|
24 using SymbianStructuresLib.Arm.Exceptions; |
|
25 using SymbianStructuresLib.Arm.SecurityMode; |
|
26 using SymbianStructuresLib.Arm.Instructions; |
|
27 using SymbianStructuresLib.Debug.Code; |
|
28 using SymbianDebugLib.PluginAPI.Types; |
|
29 using SymbianDebugLib.PluginAPI.Types.Code; |
|
30 using SymbianETMLib.Common.Types; |
|
31 using SymbianETMLib.Common.Buffer; |
|
32 using SymbianETMLib.Common.Engine; |
|
33 using SymbianETMLib.Common.Config; |
|
34 using SymbianETMLib.Common.Utilities; |
|
35 |
|
36 namespace SymbianETMLib.Common.State |
|
37 { |
|
38 public class ETMStateData : ITracer |
|
39 { |
|
40 #region Constructors |
|
41 internal ETMStateData( ETEngineBase aEngine ) |
|
42 { |
|
43 iEngine = aEngine; |
|
44 iCurrentState = new ETMDecodeStateUnsynchronized( this ); |
|
45 } |
|
46 #endregion |
|
47 |
|
48 #region API |
|
49 internal void PushBack( SymByte aByte ) |
|
50 { |
|
51 Buffer.PushBack( aByte ); |
|
52 iCurrentRawByte = iLastRawByte; |
|
53 --iPacketNumber; |
|
54 } |
|
55 |
|
56 internal void PrepareToHandleByte( SymByte aByte ) |
|
57 { |
|
58 iLastRawByte = iCurrentRawByte; |
|
59 iCurrentRawByte = aByte; |
|
60 // |
|
61 iCurrentState = iCurrentState.PrepareToHandleByte( aByte ); |
|
62 System.Diagnostics.Debug.Assert( iCurrentState != null ); |
|
63 // |
|
64 ++iPacketNumber; |
|
65 } |
|
66 |
|
67 internal void IncrementProcessedInstructionCounter() |
|
68 { |
|
69 ++iNumberOfProcessedInstructions; |
|
70 } |
|
71 |
|
72 internal uint IncrementPC() |
|
73 { |
|
74 if ( !iLastBranch.IsUnknown ) |
|
75 { |
|
76 uint instructionSize = (uint) CurrentInstructionSet; |
|
77 iPC.Address += instructionSize; |
|
78 } |
|
79 |
|
80 // Increment the instruction counter irrespective of whether or not we |
|
81 // know the program counter address |
|
82 IncrementProcessedInstructionCounter(); |
|
83 return iPC; |
|
84 } |
|
85 |
|
86 internal ETMInstruction FetchInstruction( uint aAddress ) |
|
87 { |
|
88 ETMInstruction ret = new ETMInstruction( aAddress ); |
|
89 // |
|
90 bool gotCode = false; |
|
91 if ( this.LastBranch.IsKnown && Engine.DebugEngineView != null ) |
|
92 { |
|
93 DbgViewCode codeView = Engine.DebugEngineView.Code; |
|
94 |
|
95 // In the case where we've been asked to fetch the code from the exception |
|
96 // vector, then bypass the rom/rofs code entirely. |
|
97 bool isExceptionVector = Config.IsExceptionVector( aAddress ); |
|
98 if ( isExceptionVector ) |
|
99 { |
|
100 System.Diagnostics.Debug.Assert( this.CurrentInstructionSet == TArmInstructionSet.EARM ); |
|
101 TArmExceptionVector vector = Config.MapToExceptionVector( aAddress ); |
|
102 uint rawInstruction = Config.GetExceptionVector( vector ); |
|
103 ret.Instruction = codeView.ConvertToInstruction( aAddress, TArmInstructionSet.EARM, rawInstruction ); |
|
104 } |
|
105 else |
|
106 { |
|
107 IArmInstruction[] instructions = null; |
|
108 gotCode = codeView.GetInstructions( aAddress, CurrentInstructionSet, 1, out instructions ); |
|
109 // |
|
110 if ( gotCode ) |
|
111 { |
|
112 System.Diagnostics.Debug.Assert( instructions != null && instructions.Length == 1 ); |
|
113 ret.Instruction = instructions[ 0 ]; |
|
114 } |
|
115 } |
|
116 } |
|
117 // |
|
118 return ret; |
|
119 } |
|
120 |
|
121 internal void SetUnsynchronized() |
|
122 { |
|
123 iSynchronized = false; |
|
124 } |
|
125 |
|
126 internal void SetSynchronized() |
|
127 { |
|
128 if ( !iSynchronized ) |
|
129 { |
|
130 uint pos = iPacketNumber; |
|
131 iEngine.OnSynchronised( pos ); |
|
132 iSynchronized = true; |
|
133 } |
|
134 } |
|
135 |
|
136 // <summary> |
|
137 // Set the known address bits of the program counter. We may not know all |
|
138 // bits until an I-sync packet is reached, or then until we see a full 5-byte |
|
139 // branch. |
|
140 // </summary> |
|
141 internal void SetKnownAddressBits( uint aAddress, int aNumberOfValidBits, TETMBranchType aBranchType ) |
|
142 { |
|
143 iLastBranch.SetKnownAddressBits( aAddress, aNumberOfValidBits ); |
|
144 |
|
145 iPC.Address = iLastBranch.Address; |
|
146 iPC.KnownBits = iLastBranch.KnownBits; |
|
147 |
|
148 // If we know the full branch address, then inform the engine |
|
149 if ( iPC.IsKnown ) |
|
150 { |
|
151 iEngine.OnBranch( iPC, iCurrentInstructionSet, iCurrentException, aBranchType ); |
|
152 } |
|
153 } |
|
154 |
|
155 internal void SetPC( uint aAddress ) |
|
156 { |
|
157 SetPC( aAddress, this.CurrentInstructionSet ); |
|
158 } |
|
159 |
|
160 internal void SetPC( uint aAddress, TArmInstructionSet aInstructionSet ) |
|
161 { |
|
162 iPC.Address = aAddress; |
|
163 iCurrentInstructionSet = aInstructionSet; |
|
164 |
|
165 // If BBC mode is enabled, i.e. branches are output even when a direct branch is taken |
|
166 // then we don't need to emit a branch event when seeing a 'Direct' branch type. |
|
167 bool isBBCModeEnabled = Config.BBCModeEnabled; |
|
168 if ( isBBCModeEnabled == false && iPC.IsKnown ) |
|
169 { |
|
170 iEngine.OnBranch( iPC, iCurrentInstructionSet, iCurrentException, TETMBranchType.EBranchDirect ); |
|
171 } |
|
172 } |
|
173 |
|
174 internal void SetContextID( uint aValue ) |
|
175 { |
|
176 // Tidy up the raw value. |
|
177 uint id = ( aValue >> 2 ); |
|
178 if ( iCurrentContextId != id ) |
|
179 { |
|
180 iCurrentContextId = id; |
|
181 iEngine.OnContextSwitch( iCurrentContextId ); |
|
182 } |
|
183 } |
|
184 #endregion |
|
185 |
|
186 #region Properties |
|
187 public uint PacketNumber |
|
188 { |
|
189 get { return iPacketNumber; } |
|
190 } |
|
191 |
|
192 public int NumberOfProcessedInstructions |
|
193 { |
|
194 get { return iNumberOfProcessedInstructions; } |
|
195 } |
|
196 |
|
197 public SymByte CurrentByte |
|
198 { |
|
199 get { return iCurrentRawByte; } |
|
200 } |
|
201 |
|
202 public SymByte LastByte |
|
203 { |
|
204 get { return iLastRawByte; } |
|
205 } |
|
206 |
|
207 public ETMDecodeState CurrentState |
|
208 { |
|
209 get { return iCurrentState; } |
|
210 } |
|
211 |
|
212 public TArmExceptionType CurrentException |
|
213 { |
|
214 get { return iCurrentException; } |
|
215 set |
|
216 { |
|
217 if ( iCurrentException != value ) |
|
218 { |
|
219 iCurrentException = value; |
|
220 Engine.OnExceptionModeChange( iCurrentException ); |
|
221 } |
|
222 } |
|
223 } |
|
224 |
|
225 public TArmSecurityMode CurrentSecurityMode |
|
226 { |
|
227 get { return iCurrentSecurityMode; } |
|
228 set |
|
229 { |
|
230 if ( iCurrentSecurityMode != value ) |
|
231 { |
|
232 iCurrentSecurityMode = value; |
|
233 Engine.OnExceptionModeChange( iCurrentException ); |
|
234 } |
|
235 } |
|
236 } |
|
237 |
|
238 public TArmInstructionSet CurrentInstructionSet |
|
239 { |
|
240 get { return iCurrentInstructionSet; } |
|
241 set |
|
242 { |
|
243 if ( iCurrentInstructionSet != value ) |
|
244 { |
|
245 iCurrentInstructionSet = value; |
|
246 } |
|
247 } |
|
248 } |
|
249 #endregion |
|
250 |
|
251 #region Internal properties |
|
252 internal SymAddress CurrentAddress |
|
253 { |
|
254 get { return iPC; } |
|
255 } |
|
256 |
|
257 internal SymAddressWithKnownBits LastBranch |
|
258 { |
|
259 get { return iLastBranch; } |
|
260 } |
|
261 |
|
262 internal ETEngineBase Engine |
|
263 { |
|
264 get { return iEngine; } |
|
265 } |
|
266 |
|
267 internal ETMInstruction LastInstruction |
|
268 { |
|
269 get { return iLastInstruction; } |
|
270 set { iLastInstruction = value; } |
|
271 } |
|
272 |
|
273 internal ETConfigBase Config |
|
274 { |
|
275 get { return iEngine.Config; } |
|
276 } |
|
277 |
|
278 private ETBufferBase Buffer |
|
279 { |
|
280 get { return iEngine.Buffer; } |
|
281 } |
|
282 #endregion |
|
283 |
|
284 #region Internal constants |
|
285 #endregion |
|
286 |
|
287 #region From ITracer |
|
288 public void Trace( string aText ) |
|
289 { |
|
290 iEngine.Trace( aText ); |
|
291 } |
|
292 |
|
293 public void Trace( string aFormat, params object[] aParams ) |
|
294 { |
|
295 iEngine.Trace( aFormat, aParams ); |
|
296 } |
|
297 #endregion |
|
298 |
|
299 #region From System.Object |
|
300 #endregion |
|
301 |
|
302 #region Data members |
|
303 private readonly ETEngineBase iEngine; |
|
304 private bool iSynchronized = false; |
|
305 private int iNumberOfProcessedInstructions = 0; |
|
306 private uint iPacketNumber = 0; |
|
307 private uint iCurrentContextId = uint.MaxValue; |
|
308 private ETMInstruction iLastInstruction = new ETMInstruction(); |
|
309 private SymAddressWithKnownBits iLastBranch = new SymAddressWithKnownBits(); |
|
310 private SymAddressWithKnownBits iPC = new SymAddressWithKnownBits(); |
|
311 private SymByte iCurrentRawByte = 0; |
|
312 private SymByte iLastRawByte = 0; |
|
313 private ETMDecodeState iCurrentState = null; |
|
314 private TArmExceptionType iCurrentException = TArmExceptionType.EUnknown; |
|
315 private TArmSecurityMode iCurrentSecurityMode = TArmSecurityMode.EUnknown; |
|
316 private TArmInstructionSet iCurrentInstructionSet = TArmInstructionSet.EARM; |
|
317 #endregion |
|
318 } |
|
319 } |