|
1 /* |
|
2 * Copyright (c) 2004 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 |
|
19 #ifndef __TRKDRIVER_H__ |
|
20 #define __TRKDRIVER_H__ |
|
21 |
|
22 // Debug messages |
|
23 #ifdef _DEBUG |
|
24 #define LOG_MSG(x) __KTRACE_OPT(KDEBUGGER, Kern::Printf(x)) |
|
25 #define LOG_MSG2(x, y) __KTRACE_OPT(KDEBUGGER, Kern::Printf(x, y)) |
|
26 #else |
|
27 #define LOG_MSG(x) |
|
28 #define LOG_MSG2(x, y) |
|
29 #endif |
|
30 |
|
31 |
|
32 // |
|
33 // Macros |
|
34 // |
|
35 const TUint32 KArmBreakPoint = 0xE7F123F4; |
|
36 const TUint16 KThumbBreakPoint = 0xDE56; |
|
37 |
|
38 // From mmboot.h header |
|
39 const TLinAddr KDataSectionEnd =0x40000000u; |
|
40 const TLinAddr KRomLinearBase =0xF8000000u; |
|
41 |
|
42 const TLinAddr KSuperPageMovingLinAddr =0x60000000u; |
|
43 const TLinAddr KSuperPageMultipleLinAddr =0xC0000000u; |
|
44 const TLinAddr KKernDataEndMovingLinAddr =0x655FFFFFu;//0xF3FFFFFFu; |
|
45 const TLinAddr KKernDataEndMultipleLinAddr =0xFFEFFFFFu; |
|
46 |
|
47 #define NUMBER_OF_TEMP_BREAKPOINTS 10 |
|
48 #define NUMBER_OF_EVENTS_TO_QUEUE 50 |
|
49 #define NUMBER_OF_LIBS_TO_REGISTER 100 |
|
50 #define ROM_LINEAR_BASE KRomLinearBase |
|
51 |
|
52 //for multiple memory model |
|
53 #define NUMBER_OF_MAX_BREAKPOINTS 100 |
|
54 |
|
55 // Result checking |
|
56 #define ReturnIfError(x) { TInt y = x; if (KErrNone != y) return y; } |
|
57 |
|
58 // Register definitions |
|
59 #define SP_REGISTER 13 |
|
60 #define LINK_REGISTER 14 |
|
61 #define PC_REGISTER 15 |
|
62 #define STATUS_REGISTER 16 |
|
63 |
|
64 // ARM instruction bitmasks |
|
65 #define ARM_OPCODE(x) (((TUint32)(x) & 0x0E000000) >> 25) |
|
66 |
|
67 // Generic instruction defines |
|
68 #define ARM_RM(x) ((TUint32)(x) & 0x0000000F) // bit 0- 4 |
|
69 #define ARM_RS(x) (((TUint32)(x) & 0x00000F00) >> 8) // bit 8-11 |
|
70 #define ARM_RD(x) (((TUint32)(x) & 0x0000F000) >> 12) // bit 12-15 |
|
71 #define ARM_RN(x) (((TUint32)(x) & 0x000F0000) >> 16) // bit 16-19 |
|
72 #define ARM_LOAD(x) (((TUint32)(x) & 0x00100000) >> 20) // bit 20 |
|
73 |
|
74 // Data processing instruction defines |
|
75 #define ARM_DATA_SHIFT(x) (((TUint32)(x) & 0x00000060) >> 5) // bit 5- 6 |
|
76 #define ARM_DATA_C(x) (((TUint32)(x) & 0x00000F80) >> 7) // bit 7-11 |
|
77 #define ARM_DATA_IMM(x) ((TUint32)(x) & 0x000000FF) // bit 0-7 |
|
78 #define ARM_DATA_ROT(x) (((TUint32)(x) & 0x00000F00) >> 8) // bit 8-11 |
|
79 |
|
80 // Single date transfer instruction defines |
|
81 #define ARM_SINGLE_IMM(x) ((TUint32)(x) & 0x00000FFF) // bit 0-11 |
|
82 #define ARM_SINGLE_BYTE(x) (((TUint32)(x) & 0x00400000) >> 22) // bit 22 |
|
83 #define ARM_SINGLE_U(x) (((TUint32)(x) & 0x00800000) >> 23) // bit 23 |
|
84 #define ARM_SINGLE_PRE(x) (((TUint32)(x) & 0x01000000) >> 24) // bit 24 |
|
85 |
|
86 // Block data transfer instruction defines |
|
87 #define ARM_BLOCK_REGLIST(x) ((TUint32)(x) & 0x0000FFFF) // bit 0-15 |
|
88 #define ARM_BLOCK_U(x) (((TUint32)(x) & 0x00800000) >> 23) // bit 23 |
|
89 #define ARM_BLOCK_PRE(x) (((TUint32)(x) & 0x01000000) >> 24) // bit 24 |
|
90 |
|
91 // Branch instruction defines |
|
92 #define ARM_B_ADDR(x) ((x & 0x00800000) ? ((TUint32)(x) & 0x00FFFFFF | 0xFF000000) : (TUint32)(x) & 0x00FFFFFF) |
|
93 #define ARM_INSTR_B_DEST(x,a) (ARM_B_ADDR(x) << 2) + ((TUint32)(a) + 8) |
|
94 |
|
95 #define ARM_CARRY_BIT 0x20000000 // bit 30 |
|
96 |
|
97 |
|
98 // Thumb instruction bitmasks |
|
99 #define THUMB_OPCODE(x) (((TUint16)(x) & 0xF800) >> 11) |
|
100 #define THUMB_INST_7_15(x) (((TUint16)(x) & 0xFF80) >> 7) |
|
101 #define THUMB_INST_8_15(x) (((TUint16)(x) & 0xFF00) >> 8) |
|
102 |
|
103 |
|
104 const TUint8 KArm4Stub[8] = { 0x00, 0xC0, 0x9F, 0xE5, 0x00, 0xF0, 0x9C, 0xE5 }; |
|
105 const TUint8 KArmIStub[12] = { 0x04, 0xC0, 0x9F, 0xE5, 0x00, 0xC0, 0x9C, 0xE5, 0x1C, 0xFF, 0x2F, 0xE1 }; |
|
106 const TUint8 KFastArmIStub[12] = { 0x04, 0xC0, 0x9F, 0xE5, 0x1C, 0xFF, 0x2F, 0xE1, 0x00, 0x00, 0x00, 0x00 }; |
|
107 const TUint8 KThumbStub[12] = { 0x40, 0xB4, 0x02, 0x4E, 0x36, 0x68, 0xB4, 0x46, 0x40, 0xBC, 0x60, 0x47 }; |
|
108 const TUint8 KThumbStub2[8] = { 0x01, 0x4B, 0x1B, 0x68, 0x18, 0x47, 0xC0, 0x46 }; |
|
109 const TUint8 KFastThumbStub[12] = { 0x40, 0xB4, 0x02, 0x4E, 0xB4, 0x46, 0x40, 0xBC, 0x60, 0x47, 0xC0, 0x46 }; |
|
110 const TUint8 KFastThumbStub2[8] = { 0x01, 0x4B, 0x18, 0x47, 0xC0, 0x46, 0xC0, 0x46 }; |
|
111 |
|
112 const unsigned char KRvctArm4Stub[4] = { 0x04, 0xF0, 0x1F, 0xE5 }; |
|
113 |
|
114 // |
|
115 // class TBreakEntry |
|
116 // |
|
117 class TBreakEntry |
|
118 { |
|
119 public: |
|
120 |
|
121 inline TBreakEntry() { Reset(); }; |
|
122 |
|
123 inline TBreakEntry(TUint32 aId, TUint32 aThreadId, TUint32 aAddress, TBool aThumbMode) |
|
124 : iId(aId), |
|
125 iThreadId(aThreadId), |
|
126 iAddress(aAddress), |
|
127 iThumbMode(aThumbMode) |
|
128 { |
|
129 iInstruction.FillZ(4); |
|
130 iPageAddress = 0; |
|
131 iDisabledForStep = EFalse; |
|
132 iObsoleteLibraryBreakpoint = EFalse; |
|
133 iResumeOnceOutOfRange = EFalse; |
|
134 iSteppingInto = EFalse; |
|
135 iRangeStart = 0; |
|
136 iRangeEnd = 0; |
|
137 iThreadSpecific = EFalse; |
|
138 }; |
|
139 |
|
140 inline void Reset() |
|
141 { |
|
142 iThreadId = 0; |
|
143 iAddress = 0; |
|
144 iThumbMode = EFalse; |
|
145 iInstruction.FillZ(4); |
|
146 iPageAddress = 0; |
|
147 iDisabledForStep = EFalse; |
|
148 iObsoleteLibraryBreakpoint = EFalse; |
|
149 iResumeOnceOutOfRange = EFalse; |
|
150 iSteppingInto = EFalse; |
|
151 iRangeStart = 0; |
|
152 iRangeEnd = 0; |
|
153 }; |
|
154 |
|
155 public: |
|
156 |
|
157 TInt32 iId; |
|
158 TUint32 iThreadId; |
|
159 TUint32 iAddress; |
|
160 TBool iThumbMode; |
|
161 TBuf8<4> iInstruction; |
|
162 TUint32 iPageAddress; |
|
163 TBool iDisabledForStep; |
|
164 TBool iObsoleteLibraryBreakpoint; |
|
165 TBool iResumeOnceOutOfRange; |
|
166 TBool iSteppingInto; |
|
167 TUint32 iRangeStart; |
|
168 TUint32 iRangeEnd; |
|
169 TBool iThreadSpecific; |
|
170 }; |
|
171 |
|
172 class TProcessInfo |
|
173 { |
|
174 public: |
|
175 |
|
176 inline TProcessInfo() { Reset(); } |
|
177 |
|
178 inline TProcessInfo(TUint32 aId, TUint32 aCodeAddress, TUint32 aCodeSize, TUint32 aDataAddress) |
|
179 : iId(aId), |
|
180 iCodeAddress(aCodeAddress), |
|
181 iCodeSize(aCodeSize), |
|
182 iDataAddress(aDataAddress) { } |
|
183 |
|
184 inline void Reset() |
|
185 { |
|
186 iId = 0; |
|
187 iCodeAddress = 0; |
|
188 iCodeSize = 0; |
|
189 iDataAddress = 0; |
|
190 } |
|
191 |
|
192 public: |
|
193 TUint32 iId; |
|
194 TUint32 iCodeAddress; |
|
195 TUint32 iCodeSize; |
|
196 TUint32 iDataAddress; |
|
197 }; |
|
198 |
|
199 |
|
200 // |
|
201 // class DMetroTrkDriverFactory |
|
202 // |
|
203 class DMetroTrkDriverFactory : public DLogicalDevice |
|
204 { |
|
205 public: |
|
206 |
|
207 DMetroTrkDriverFactory(); |
|
208 virtual TInt Install(); |
|
209 virtual void GetCaps(TDes8& aDes) const; |
|
210 virtual TInt Create(DLogicalChannelBase*& aChannel); |
|
211 }; |
|
212 |
|
213 class DMetroTrkEventHandler; |
|
214 // |
|
215 // DMetroTrkChannel |
|
216 // |
|
217 class DMetroTrkChannel : public DLogicalChannel |
|
218 { |
|
219 public: |
|
220 |
|
221 DMetroTrkChannel(DLogicalDevice* aLogicalDevice); |
|
222 ~DMetroTrkChannel(); |
|
223 |
|
224 virtual TInt DoCreate(TInt aUnit, const TDesC* anInfo, const TVersion& aVer); |
|
225 virtual void HandleMsg(TMessageBase* aMsg); |
|
226 |
|
227 //called from the event handler |
|
228 void AddProcess(DProcess *aProcess, DThread* aThread); |
|
229 void StartThread(DThread *aThread); |
|
230 void RemoveProcess(DProcess *aProcess); |
|
231 void AddLibrary(DLibrary *aLibrary, DThread *aThread); |
|
232 void RemoveLibrary(DLibrary *aLibrary); |
|
233 void AddCodeSegment(DCodeSeg *aCodeSeg, DProcess *aProcess); |
|
234 void RemoveCodeSegment(DCodeSeg *aCodeSeg, DProcess *aProcess); |
|
235 TBool HandleEventKillThread(DThread* aThread); |
|
236 TBool HandleSwException(TExcType aExcType); |
|
237 TBool HandleHwException(TArmExcInfo* aExcInfo); |
|
238 TBool HandleUserTrace(TText* aStr, TInt aLen); |
|
239 |
|
240 protected: |
|
241 virtual void DoCancel(TInt aReqNo); |
|
242 virtual void DoRequest(TInt aReqNo, TRequestStatus* aStatus, TAny* a1, TAny* a2); |
|
243 virtual TInt DoControl(TInt aFunction, TAny *a1, TAny *a2); |
|
244 |
|
245 private: |
|
246 void HandleException(SEventInfo& aEventInfo, DThread* aCurrentThread); |
|
247 |
|
248 TInt SetBreak(TUint32 aThreadId, TMetroTrkBreakInfo* aBreakInfo); |
|
249 TInt StepRange(DThread* aThread, TMetroTrkStepInfo* aStepInfo); |
|
250 TInt ReadMemory(DThread* aThread, TMetroTrkMemoryInfo* aMemoryInfo); |
|
251 TInt WriteMemory(DThread* aThread, TMetroTrkMemoryInfo* aMemoryInfo); |
|
252 TInt ReadRegisters(DThread* aThread, TMetroTrkRegisterInfo* aRegisterInfo); |
|
253 TInt WriteRegisters(DThread* aThread, TMetroTrkRegisterInfo* aRegisterInfo); |
|
254 TInt GetProcessInfo(TInt aIndex, TMetroTrkTaskInfo* aTaskInfo); |
|
255 TInt GetThreadInfo(TInt aIndex, TMetroTrkTaskInfo* aTaskInfo); |
|
256 TInt GetProcessAddresses(DThread* aThread, TMetroTrkProcessInfo* aProcessInfo); |
|
257 TInt GetStaticLibraryInfo(TInt aIndex, SEventInfo* aEventInfo); |
|
258 TInt GetLibraryInfo(TMetroTrkLibInfo* aLibInfo); |
|
259 TInt GetExeInfo(TMetroTrkExeInfo* aExeInfo); |
|
260 TInt GetProcUidInfo(TMetroTrkProcUidInfo* aProcUidInfo); |
|
261 TInt DetachProcess(DProcess* aProcess); |
|
262 |
|
263 TInt DoSetBreak(const TUint32 aProcessId, const TUint32 aThreadId, const TUint32 aAddress, const TBool aThumbMode, TInt32 &aId); |
|
264 TInt DoEnableBreak(TBreakEntry &aEntry, TBool aSaveOldInstruction); |
|
265 TInt DoClearBreak(const TInt32 aId); |
|
266 TInt DoChangeBreakThread(TUint32 aThreadId, TInt32 aId); |
|
267 TInt DoSuspendThread(DThread *aThread); |
|
268 TInt DoResumeThread(DThread *aThread); |
|
269 TInt DoStepRange(DThread *aThread, const TUint32 aStartAddress, const TUint32 aStopAddress, TBool aStepInto, TBool aResumeOnceOutOfRange, TBool aUserRequest = EFalse); |
|
270 TInt DoReadMemory(DThread *aThread, const TUint32 aAddress, const TInt16 aLength, TDes8 &aData); |
|
271 TInt DoWriteMemory(DThread *aThread, const TUint32 aAddress, const TInt16 aLength, TDes8 &aData); |
|
272 TInt DoReadRegisters(DThread *aThread, const TInt16 aFirstRegister, const TInt16 aLastRegister, TDes8 &aValues); |
|
273 TInt DoWriteRegisters(DThread *aThread, const TInt16 aFirstRegister, const TInt16 aLastRegister, TDesC8 &aValues); |
|
274 TInt DoGetProcessInfo(const TInt aIndex, TMetroTrkTaskInfo *aInfo); |
|
275 TInt DoGetThreadInfo(const TInt aIndex, TMetroTrkTaskInfo *aInfo); |
|
276 TInt DoGetProcessAddresses(DThread *aThread, TUint32 &aCodeAddress, TUint32 &aDataAddress); |
|
277 TInt DoGetStaticLibraryInfo(const TInt aIndex, SEventInfo *aInfo); |
|
278 TInt DoGetLibraryInfo(TDesC8 &aDllName, TMetroTrkLibInfo* aLibInfo); |
|
279 TInt DoGetExeInfo(TDesC8 &aExeName, TMetroTrkExeInfo* aExeInfo); |
|
280 TInt DoGetProcUidInfo(TMetroTrkProcUidInfo* aProcUidInfo); |
|
281 |
|
282 TBool DoSecurityCheck(); |
|
283 TInt TryToReadMemory(DThread *aThread, TAny *aSrc, TAny *aDest, TInt16 aLength); |
|
284 TInt TryToWriteMemory(DThread *aThread, TAny *aDest, TAny *aSrc, TInt16 aLength); |
|
285 TInt32 ReadRegister(DThread *aThread, TInt aNum); |
|
286 TInt ModifyBreaksForStep(DThread *aThread, TUint32 aRangeStart, TUint32 aRangeEnd, TBool aStepInto, TBool aResumeOnceOutOfRange, TBool aCheckForStubs); |
|
287 TBool IsExecuted(TUint8 aCondition, TUint32 aStatusRegister); |
|
288 void ClearAllBreakPoints(); |
|
289 TInt DisableBreakAtAddress(TUint32 aAddress); |
|
290 TInt DoEnableDisabledBreak(TUint32 aThreadId); |
|
291 TUint32 ShiftedRegValue(DThread *aThread, TUint32 aInstruction, TUint32 aCurrentPC, TUint32 aStatusRegister); |
|
292 TBool InstructionModifiesPC(DThread *aThread, TUint8 *aInstruction, TBool aThumbMode, TBool aStepInto); |
|
293 TUint32 PCAfterInstructionExecutes(DThread *aThread, TUint32 aCurrentPC, TUint32 aStatusRegister, TInt aInstSize, TBool aStepInto, TUint32 &aNewRangeEnd, TBool &aChangingModes); |
|
294 void DecodeDataProcessingInstruction(TUint8 aOpcode, TUint32 aOp1, TUint32 aOp2, TUint32 aStatusRegister, TUint32 &aBreakAddress); |
|
295 TBool IsPreviousInstructionMovePCToLR(DThread *aThread); |
|
296 |
|
297 TBool IsAddressInRom(TUint32 aAddress); |
|
298 TBool IsAddressSecure(TUint32 aAddress); |
|
299 TBool IsRegisterSecure(TInt registerIndex); |
|
300 |
|
301 TInt AllocateShadowPageIfNecessary(TUint32 aAddress, TUint32 &aPageAddress); |
|
302 TInt FreeShadowPageIfNecessary(TUint32 aAddress, TUint32 aPageAddress); |
|
303 |
|
304 void NotifyEvent(SEventInfo aEventInfo, TBool isTraceEvent=EFalse); |
|
305 DThread* ThreadFromId(TUint32 aId); |
|
306 DProcess* ProcessFromId(TUint32 aId); |
|
307 TBool GetSystemThreadRegisters(TArmRegSet* aArmRegSet); |
|
308 TInt DoGetLibInfoFromCodeSegList(TDesC8 &aDllName, TMetroTrkLibInfo *aInfo); |
|
309 TInt DoGetLibInfoFromKernLibContainer(TDesC8 &aDllName, TMetroTrkLibInfo *aInfo); |
|
310 |
|
311 TBool HasManufacturerCaps(DThread* aThread); |
|
312 TBool IsBeingDebugged(const DThread* aThread); |
|
313 |
|
314 void CheckLibraryNotifyList(TUint32 aProcessId); |
|
315 |
|
316 private: |
|
317 DThread* iClientThread; |
|
318 DMetroTrkEventHandler* iEventHandler; |
|
319 |
|
320 TUint32 iExcludedROMAddressStart; |
|
321 TUint32 iExcludedROMAddressEnd; |
|
322 |
|
323 RArray<TBreakEntry> iBreakPointList; |
|
324 TInt iNextBreakId; |
|
325 |
|
326 SEventInfo *iEventInfo; |
|
327 RArray<SEventInfo> iEventQueue; |
|
328 RArray<SEventInfo> iTraceEventQueue; |
|
329 TRequestStatus* iRequestGetEventStatus; |
|
330 |
|
331 TUint32 iPageSize; |
|
332 |
|
333 TBool iNotifyLibLoadedEvent; |
|
334 TBool iMultipleMemModel; |
|
335 |
|
336 RArray<TProcessInfo> iDebugProcessList; //processes that we are debugging |
|
337 RArray<SEventInfo> iProcessNotifyList; |
|
338 |
|
339 TDfcQue* iDFCQue; |
|
340 |
|
341 TArmExcInfo iCurrentExcInfo; |
|
342 TBool iExcInfoValid; |
|
343 TBool iDebugging; |
|
344 // PANIC_BACKPORT |
|
345 RPointerArray<NFastSemaphore> iFrozenThreadSemaphores; |
|
346 // END PANIC_BACKPORT |
|
347 RArray<TTrkLibName> iLibraryNotifyList; |
|
348 |
|
349 }; |
|
350 |
|
351 #endif //__TRKDRIVER_H__ |