|
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.Text; |
|
19 using System.Collections.Generic; |
|
20 using System.ComponentModel; |
|
21 using CrashItemLib.Crash; |
|
22 using CrashItemLib.Crash.Base; |
|
23 using CrashItemLib.Crash.Messages; |
|
24 using CrashItemLib.Crash.Container; |
|
25 using CrashItemLib.Crash.Threads; |
|
26 using SymbianStructuresLib.Arm.Registers; |
|
27 |
|
28 namespace CrashItemLib.Crash.Registers.Special |
|
29 { |
|
30 public class CIRegisterExcCode : CIRegister |
|
31 { |
|
32 #region Enumerations |
|
33 public enum TExceptionCode |
|
34 { |
|
35 EExceptionCodeUnknown = -1, |
|
36 |
|
37 [Description( "EExcGeneral" )] |
|
38 EExceptionCodeGeneral = 0, |
|
39 |
|
40 [Description( "EExcIntegerDivideByZero" )] |
|
41 EExceptionCodeIntegerDivideByZero = 1, |
|
42 |
|
43 [Description( "EExcSingleStep" )] |
|
44 EExceptionCodeSingleStep = 2, |
|
45 |
|
46 [Description( "EExcBreakPoint" )] |
|
47 EExceptionCodeBreakPoint = 3, |
|
48 |
|
49 [Description( "EExcIntegerOverflow" )] |
|
50 EExceptionCodeIntegerOverflow = 4, |
|
51 |
|
52 [Description( "EExcBoundsCheck" )] |
|
53 EExceptionCodeBoundsCheck = 5, |
|
54 |
|
55 [Description( "EExcInvalidOpCode" )] |
|
56 EExceptionCodeInvalidOpCode = 6, |
|
57 |
|
58 [Description( "EExcDoubleFault" )] |
|
59 EExceptionCodeDoubleFault = 7, |
|
60 |
|
61 [Description( "EExcStackFault" )] |
|
62 EExceptionCodeStackFault = 8, |
|
63 |
|
64 [Description( "EExcAccessViolation" )] |
|
65 EExceptionCodeAccessViolation = 9, |
|
66 |
|
67 [Description( "EExcPrivInstruction" )] |
|
68 EExceptionCodePrivInstruction = 10, |
|
69 |
|
70 [Description( "EExcAlignment" )] |
|
71 EExceptionCodeAlignment = 11, |
|
72 |
|
73 [Description( "EExcPageFault" )] |
|
74 EExceptionCodePageFault = 12, |
|
75 |
|
76 [Description( "EExcFloatDenormal" )] |
|
77 EExceptionCodeFloatDenormal = 13, |
|
78 |
|
79 [Description( "EExcFloatDivideByZero" )] |
|
80 EExceptionCodeFloatDivideByZero = 14, |
|
81 |
|
82 [Description( "EExcFloatInexactResult" )] |
|
83 EExceptionCodeFloatInexactResult = 15, |
|
84 |
|
85 [Description( "EExcFloatInvalidOperation" )] |
|
86 EExceptionCodeFloatInvalidOperation = 16, |
|
87 |
|
88 [Description( "EExcFloatOverflow" )] |
|
89 EExceptionCodeFloatOverflow = 17, |
|
90 |
|
91 [Description( "EExcFloatStackCheck" )] |
|
92 EExceptionCodeFloatStackCheck = 18, |
|
93 |
|
94 [Description( "EExcFloatUnderflow" )] |
|
95 EExceptionCodeFloatUnderflow = 19, |
|
96 |
|
97 [Description( "EExcAbort" )] |
|
98 EExceptionAbort = 20, |
|
99 |
|
100 [Description( "EExcKill" )] |
|
101 EExceptionCodeKill = 21, |
|
102 |
|
103 [Description( "EExcUserInterrupt" )] |
|
104 EExceptionCodeUserInterrupt = 22, |
|
105 |
|
106 [Description( "EExcDataAbort" )] |
|
107 EExceptionCodeDataAbort = 23, |
|
108 |
|
109 [Description( "EExcCodeAbort" )] |
|
110 EExceptionCodeAbort = 24, |
|
111 |
|
112 [Description( "EExcMaxNumber" )] |
|
113 EExceptionCodeMaxNumber = 25, |
|
114 |
|
115 [Description( "EExcInvalidVector" )] |
|
116 EExceptionCodeInvalidVector = 26, |
|
117 // |
|
118 EExceptionCodeLast = EExceptionCodeInvalidVector |
|
119 } |
|
120 #endregion |
|
121 |
|
122 #region Constructors |
|
123 public CIRegisterExcCode( CIRegisterList aCollection, uint aValue ) |
|
124 : base( aCollection, TArmRegisterType.EArmReg_EXCCODE, aValue ) |
|
125 { |
|
126 iDescription = CreateMessage(); |
|
127 base.AddChild( iDescription ); |
|
128 } |
|
129 #endregion |
|
130 |
|
131 #region API |
|
132 /// <summary> |
|
133 /// D_EXC is only aware of 3 different exception types. |
|
134 /// |
|
135 /// 0 = prefetch abort |
|
136 /// 1 = data abort |
|
137 /// 2 = undefined instruction |
|
138 /// |
|
139 /// Symbian ELF Core dump does this mapping for us automatically. |
|
140 /// </summary> |
|
141 public void ExpandToFullExceptionRange() |
|
142 { |
|
143 switch ( (TBasicExceptionCode) Value ) |
|
144 { |
|
145 case TBasicExceptionCode.EBasicExceptionPrefechAbort: |
|
146 iExcCode = TExceptionCode.EExceptionCodeAbort; |
|
147 break; |
|
148 case TBasicExceptionCode.EBasicExceptionDataAbort: |
|
149 iExcCode = TExceptionCode.EExceptionCodeDataAbort; |
|
150 break; |
|
151 case TBasicExceptionCode.EBasicExceptionUndefinedInstruction: |
|
152 iExcCode = TExceptionCode.EExceptionCodeInvalidOpCode; |
|
153 break; |
|
154 default: |
|
155 break; |
|
156 } |
|
157 |
|
158 // Prod back updated value to underlying register item |
|
159 base.Value = (uint) iExcCode; |
|
160 |
|
161 // Re-prepare the message |
|
162 UpdateMessage( iDescription ); |
|
163 } |
|
164 #endregion |
|
165 |
|
166 #region Properties |
|
167 public TExceptionCode ExceptionCode |
|
168 { |
|
169 get |
|
170 { |
|
171 TExceptionCode ret = TExceptionCode.EExceptionCodeUnknown; |
|
172 // |
|
173 uint type = base.Value; |
|
174 if ( type >= (uint) TExceptionCode.EExceptionCodeGeneral && type <= (uint) TExceptionCode.EExceptionCodeLast ) |
|
175 { |
|
176 ret = (TExceptionCode) type; |
|
177 } |
|
178 // |
|
179 return ret; |
|
180 } |
|
181 } |
|
182 |
|
183 public string ExceptionCodeDescription |
|
184 { |
|
185 get |
|
186 { |
|
187 string type = "Unknown"; |
|
188 // |
|
189 switch ( iExcCode ) |
|
190 { |
|
191 default: |
|
192 case TExceptionCode.EExceptionCodeUnknown: |
|
193 break; |
|
194 case TExceptionCode.EExceptionCodeGeneral: |
|
195 type = "General Exception"; |
|
196 break; |
|
197 case TExceptionCode.EExceptionCodeIntegerDivideByZero: |
|
198 type = "Integer Divide by Zero"; |
|
199 break; |
|
200 case TExceptionCode.EExceptionCodeSingleStep: |
|
201 type = "Single Step"; |
|
202 break; |
|
203 case TExceptionCode.EExceptionCodeBreakPoint: |
|
204 type = "Break Point"; |
|
205 break; |
|
206 case TExceptionCode.EExceptionCodeIntegerOverflow: |
|
207 type = "Integer Overflow"; |
|
208 break; |
|
209 case TExceptionCode.EExceptionCodeBoundsCheck: |
|
210 type = "Bounds Check"; |
|
211 break; |
|
212 case TExceptionCode.EExceptionCodeInvalidOpCode: |
|
213 type = "Invalid Op. Code"; |
|
214 break; |
|
215 case TExceptionCode.EExceptionCodeDoubleFault: |
|
216 type = "Double Fault"; |
|
217 break; |
|
218 case TExceptionCode.EExceptionCodeStackFault: |
|
219 type = "Stack Fault"; |
|
220 break; |
|
221 case TExceptionCode.EExceptionCodeAccessViolation: |
|
222 type = "Access Violation"; |
|
223 break; |
|
224 case TExceptionCode.EExceptionCodePrivInstruction: |
|
225 type = "Priv. Instruction"; |
|
226 break; |
|
227 case TExceptionCode.EExceptionCodeAlignment: |
|
228 type = "Alignment Fault"; |
|
229 break; |
|
230 case TExceptionCode.EExceptionCodePageFault: |
|
231 type = "Page Fault"; |
|
232 break; |
|
233 case TExceptionCode.EExceptionCodeFloatDenormal: |
|
234 type = "Float Denormal"; |
|
235 break; |
|
236 case TExceptionCode.EExceptionCodeFloatDivideByZero: |
|
237 type = "Float Divide by Zero"; |
|
238 break; |
|
239 case TExceptionCode.EExceptionCodeFloatInexactResult: |
|
240 type = "Inexact Float Result"; |
|
241 break; |
|
242 case TExceptionCode.EExceptionCodeFloatInvalidOperation: |
|
243 type = "Invalid Float Operation"; |
|
244 break; |
|
245 case TExceptionCode.EExceptionCodeFloatOverflow: |
|
246 type = "Float Overflow"; |
|
247 break; |
|
248 case TExceptionCode.EExceptionCodeFloatStackCheck: |
|
249 type = "Float Stack Check"; |
|
250 break; |
|
251 case TExceptionCode.EExceptionCodeFloatUnderflow: |
|
252 type = "Float Underflow"; |
|
253 break; |
|
254 case TExceptionCode.EExceptionAbort: |
|
255 type = "Abort"; |
|
256 break; |
|
257 case TExceptionCode.EExceptionCodeKill: |
|
258 type = "Kill"; |
|
259 break; |
|
260 case TExceptionCode.EExceptionCodeUserInterrupt: |
|
261 type = "User Interrupt"; |
|
262 break; |
|
263 case TExceptionCode.EExceptionCodeDataAbort: |
|
264 type = "Data Abort"; |
|
265 break; |
|
266 case TExceptionCode.EExceptionCodeAbort: |
|
267 type = "Code Abort"; |
|
268 break; |
|
269 case TExceptionCode.EExceptionCodeMaxNumber: |
|
270 type = "Max Number"; |
|
271 break; |
|
272 case TExceptionCode.EExceptionCodeInvalidVector: |
|
273 type = "Invalid Vector"; |
|
274 break; |
|
275 } |
|
276 // |
|
277 return type; |
|
278 } |
|
279 } |
|
280 #endregion |
|
281 |
|
282 #region Operators |
|
283 public static implicit operator TExceptionCode( CIRegisterExcCode aReg ) |
|
284 { |
|
285 return aReg.ExceptionCode; |
|
286 } |
|
287 #endregion |
|
288 |
|
289 #region Internal enumerations |
|
290 private enum TBasicExceptionCode |
|
291 { |
|
292 EBasicExceptionPrefechAbort = 0, |
|
293 EBasicExceptionDataAbort = 1, |
|
294 EBasicExceptionUndefinedInstruction = 2 |
|
295 } |
|
296 #endregion |
|
297 |
|
298 #region Internal methods |
|
299 private CIMessage CreateMessage() |
|
300 { |
|
301 CIMessage message = CIMessage.NewMessage( Container ); |
|
302 // |
|
303 UpdateMessage( message ); |
|
304 // |
|
305 return message; |
|
306 } |
|
307 |
|
308 private void UpdateMessage( CIMessage aMessage ) |
|
309 { |
|
310 SymbianUtils.SymDebug.SymDebugger.Assert( aMessage != null ); |
|
311 // |
|
312 aMessage.Title = "Exception Code"; |
|
313 aMessage.SetLineFormatted( "The Exception Code register indicates that the processor encountered an exception of type [{0}].", ExceptionCodeDescription ); |
|
314 } |
|
315 #endregion |
|
316 |
|
317 #region Data members |
|
318 private readonly CIMessage iDescription; |
|
319 private TExceptionCode iExcCode = TExceptionCode.EExceptionCodeUnknown; |
|
320 #endregion |
|
321 } |
|
322 } |