|
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 #include "TrkEngine.h" |
|
20 #include "TrkDispatchLayer.h" |
|
21 #include "DateTimeConverter.h" |
|
22 |
|
23 #ifndef __TEXT_SHELL__ |
|
24 #include "TrkSwInstall.h" |
|
25 #endif |
|
26 |
|
27 // |
|
28 // Macros |
|
29 // |
|
30 |
|
31 // |
|
32 // Version Information |
|
33 // |
|
34 |
|
35 #define MAJOR_VERSION_NUMBER 3 |
|
36 #define MINOR_VERSION_NUMBER 2 |
|
37 #define BUILD_NUMBER 4 |
|
38 |
|
39 |
|
40 // |
|
41 // Support Information |
|
42 // |
|
43 |
|
44 #define DS_SUPPORT_MASK_00_07 0x7E // kDSConnect, kDSDisconnect, kDSReset, kDSVersions, kDSSupportMask, kDSCPUType */ |
|
45 #define DS_SUPPORT_MASK_08_0F 0x00 |
|
46 #define DS_SUPPORT_MASK_10_17 0x4f // R/W Memory, R/W Registers, FlushCache |
|
47 #define DS_SUPPORT_MASK_18_1F 0x5f // kDSContinue, kDSStep, kDSStop, kDSSetBreak, kDSClearBreak |
|
48 #define DS_SUPPORT_MASK_20_27 0x01 // kDSNotifyFileInput |
|
49 #define DS_SUPPORT_MASK_28_2F 0x00 |
|
50 #define DS_SUPPORT_MASK_30_37 0x00 |
|
51 #define DS_SUPPORT_MASK_38_3F 0x00 |
|
52 #define DS_SUPPORT_MASK_40_47 0x0f // OS Create/Delete Item, OS Read/Write Info |
|
53 #define DS_SUPPORT_MASK_48_4F 0x1f // OS Read/Write/Open/Close/Position File |
|
54 #define DS_SUPPORT_MASK_50_57 0x00 |
|
55 #define DS_SUPPORT_MASK_58_5F 0x00 |
|
56 #define DS_SUPPORT_MASK_60_67 0x00 |
|
57 #define DS_SUPPORT_MASK_68_6F 0x00 |
|
58 #define DS_SUPPORT_MASK_70_77 0x00 |
|
59 #define DS_SUPPORT_MASK_78_7F 0x00 |
|
60 #define DS_SUPPORT_MASK_80_87 0x01 // kDSReplyACK |
|
61 #define DS_SUPPORT_MASK_88_8F 0x00 |
|
62 #define DS_SUPPORT_MASK_90_97 0x11 // kDSNotifyStopped, kDSNotifyStopped2 |
|
63 #define DS_SUPPORT_MASK_98_9F 0x00 |
|
64 #define DS_SUPPORT_MASK_A0_A7 0x03 // kDSOSNotifyCreated, kDSOSNotifyDeleted |
|
65 #define DS_SUPPORT_MASK_A8_AF 0x00 |
|
66 #define DS_SUPPORT_MASK_B0_B7 0x00 |
|
67 #define DS_SUPPORT_MASK_B8_BF 0x00 |
|
68 #define DS_SUPPORT_MASK_C0_C7 0x00 |
|
69 #define DS_SUPPORT_MASK_C8_CF 0x00 |
|
70 #define DS_SUPPORT_MASK_D0_D7 0x03 // kDSWriteFile, kDSReadFile |
|
71 #define DS_SUPPORT_MASK_D8_DF 0x00 |
|
72 #define DS_SUPPORT_MASK_E0_E7 0x00 |
|
73 #define DS_SUPPORT_MASK_E8_EF 0x00 |
|
74 #define DS_SUPPORT_MASK_F0_F7 0x00 |
|
75 #define DS_SUPPORT_MASK_F8_FF 0x80 // kDSReplyNAK |
|
76 |
|
77 #define KProcessKilled 0x4B696C6C // "Kill" |
|
78 |
|
79 #ifdef EKA2 |
|
80 #define EUSER_LIBPATH _L("Z:\\Sys\\Bin\\euser.dll") |
|
81 #else |
|
82 #define EUSER_LIBPATH _L("Z:\\System\\Libs\\euser.dll") |
|
83 #endif |
|
84 |
|
85 #ifdef __OEM_TRK__ |
|
86 #define TRK_TYPE_DESCRIPTION _L8("System TRK") |
|
87 #else |
|
88 #define TRK_TYPE_DESCRIPTION _L8("Application TRK") |
|
89 #endif |
|
90 |
|
91 |
|
92 // |
|
93 // Swap2 |
|
94 // |
|
95 // Byte-swaps a 2-byte value. Used to convert to/from little/big endian. |
|
96 // |
|
97 static TUint16 Swap2(TUint16 aSource) |
|
98 { |
|
99 TUint16 dest = 0; |
|
100 for (TInt i=0; i<2; i++) |
|
101 { |
|
102 dest <<= 8; |
|
103 dest |= aSource & 0xFF; |
|
104 aSource >>= 8; |
|
105 } |
|
106 |
|
107 return dest; |
|
108 } |
|
109 |
|
110 // |
|
111 // Swap4 |
|
112 // |
|
113 // Byte-swaps a 4-byte value. Used to convert to/from little/big endian. |
|
114 // |
|
115 static TUint32 Swap4(TUint32 aSource) |
|
116 { |
|
117 TUint32 dest = 0; |
|
118 for (TInt i=0; i<4; i++) |
|
119 { |
|
120 dest <<= 8; |
|
121 dest |= aSource & 0xFF; |
|
122 aSource >>= 8; |
|
123 } |
|
124 |
|
125 return dest; |
|
126 } |
|
127 |
|
128 // |
|
129 // Swap4xN |
|
130 // |
|
131 // Byte-swaps N 4-byte values *in place*. Used to convert to/from little/big endian. |
|
132 // |
|
133 void Swap4xN(TUint32 *aSource, TInt aCount) |
|
134 { |
|
135 while (aCount--) |
|
136 { |
|
137 TUint32 temp = Swap4(*aSource); |
|
138 *aSource++ = temp; |
|
139 } |
|
140 } |
|
141 |
|
142 |
|
143 // |
|
144 // |
|
145 // CExitTrapper implementation |
|
146 // |
|
147 // |
|
148 |
|
149 // |
|
150 // CExitTrapper constructor |
|
151 // |
|
152 // Accepts CTrkDispatchLayer interface and the process ID of the |
|
153 // process to watch |
|
154 // |
|
155 CExitTrapper::CExitTrapper(CTrkDispatchLayer *aDispatch, TUint32 aProcessId) |
|
156 : CActive(EPriorityStandard), |
|
157 iProcessId(aProcessId), |
|
158 iDispatch(aDispatch) |
|
159 { |
|
160 CActiveScheduler::Add(this); |
|
161 |
|
162 TInt error = iProcess.Open(iProcessId); |
|
163 if (KErrNone != error) |
|
164 User::Panic(_L("Unable to open process"), __LINE__); |
|
165 } |
|
166 |
|
167 // |
|
168 // CExitTrapper destructor |
|
169 // |
|
170 CExitTrapper::~CExitTrapper() |
|
171 { |
|
172 Cancel(); |
|
173 Deque(); |
|
174 iProcess.Close(); |
|
175 } |
|
176 |
|
177 // |
|
178 // CExitTrapper::Watch |
|
179 // |
|
180 // Watch for the process to exit |
|
181 // |
|
182 void CExitTrapper::Watch() |
|
183 { |
|
184 iProcess.Logon(iStatus); |
|
185 SetActive(); |
|
186 } |
|
187 |
|
188 // |
|
189 // CExitTrapper::RunL |
|
190 // |
|
191 // Called when the process exits |
|
192 // |
|
193 void CExitTrapper::RunL() |
|
194 { |
|
195 // sometimes this is run when the process has yet to exit |
|
196 if (iProcess.ExitType() == EExitPending) |
|
197 { |
|
198 iProcess.LogonCancel(iStatus); |
|
199 Watch(); |
|
200 } |
|
201 else |
|
202 { |
|
203 iDispatch->DoNotifyProcessDiedL(iProcessId, iProcess.ExitReason()); |
|
204 } |
|
205 } |
|
206 |
|
207 // |
|
208 // CExitTrapper::DoCancel |
|
209 // |
|
210 // Stop waiting for this process to exit |
|
211 // |
|
212 void CExitTrapper::DoCancel() |
|
213 { |
|
214 iProcess.LogonCancel(iStatus); |
|
215 } |
|
216 |
|
217 |
|
218 // |
|
219 // |
|
220 // CEventTrapper implementation |
|
221 // |
|
222 // |
|
223 |
|
224 // |
|
225 // CEventTrapper constructor |
|
226 // |
|
227 // Accepts CTrkDispatchLayer interface |
|
228 // |
|
229 CEventTrapper::CEventTrapper(CTrkDispatchLayer *aDispatch) |
|
230 : CActive(CActive::EPriorityStandard), |
|
231 iDispatch(aDispatch) |
|
232 { |
|
233 CActiveScheduler::Add(this); |
|
234 } |
|
235 |
|
236 // |
|
237 // CEventTrapper destructor |
|
238 // |
|
239 CEventTrapper::~CEventTrapper() |
|
240 { |
|
241 Cancel(); |
|
242 Deque(); |
|
243 } |
|
244 |
|
245 // |
|
246 // CEventTrapper::Watch |
|
247 // |
|
248 // Start listening for events |
|
249 // |
|
250 void CEventTrapper::Watch() |
|
251 { |
|
252 iDispatch->iKernelDriver.GetEvent(iStatus, iEventInfo); |
|
253 SetActive(); |
|
254 } |
|
255 |
|
256 // |
|
257 // CEventTrapper::RunL |
|
258 // |
|
259 // Called when an event occurs |
|
260 // |
|
261 void CEventTrapper::RunL() |
|
262 { |
|
263 // determine the type of event and handle accordingly |
|
264 switch (iEventInfo.iEventType) |
|
265 { |
|
266 case SEventInfo::EThreadBreakPoint: |
|
267 { |
|
268 iDispatch->DoNotifyStoppedL(iEventInfo.iProcessId, iEventInfo.iThreadId, iEventInfo.iCurrentPC, KNullDesC8); |
|
269 break; |
|
270 } |
|
271 case SEventInfo::EThreadException: |
|
272 { |
|
273 TBuf8<100> buf; |
|
274 |
|
275 switch(iEventInfo.iExceptionNumber) |
|
276 { |
|
277 case EExcIntegerDivideByZero: |
|
278 { |
|
279 buf.Format(_L8("An integer divide by zero exception has occurred.")); |
|
280 break; |
|
281 } |
|
282 case EExcIntegerOverflow: |
|
283 { |
|
284 buf.Format(_L8("An integer overflow exception has occurred.")); |
|
285 break; |
|
286 } |
|
287 case EExcBoundsCheck: |
|
288 { |
|
289 buf.Format(_L8("An bounds check exception has occurred.")); |
|
290 break; |
|
291 } |
|
292 case EExcInvalidOpCode: |
|
293 { |
|
294 buf.Format(_L8("An invalid instruction exception has occurred.")); |
|
295 break; |
|
296 } |
|
297 case EExcDoubleFault: |
|
298 { |
|
299 buf.Format(_L8("A double fault exception has occurred.")); |
|
300 break; |
|
301 } |
|
302 case EExcStackFault: |
|
303 { |
|
304 buf.Format(_L8("A stack fault exception has occurred.")); |
|
305 break; |
|
306 } |
|
307 case EExcAccessViolation: |
|
308 { |
|
309 buf.Format(_L8("An access violation exception has occurred.")); |
|
310 break; |
|
311 } |
|
312 case EExcPrivInstruction: |
|
313 { |
|
314 buf.Format(_L8("A priveledged instruction exception has occurred.")); |
|
315 break; |
|
316 } |
|
317 case EExcAlignment: |
|
318 { |
|
319 buf.Format(_L8("An alignment exception has occurred.")); |
|
320 break; |
|
321 } |
|
322 case EExcPageFault: |
|
323 { |
|
324 buf.Format(_L8("A page fault exception has occurred.")); |
|
325 break; |
|
326 } |
|
327 case EExcFloatDenormal: |
|
328 case EExcFloatDivideByZero: |
|
329 case EExcFloatInexactResult: |
|
330 case EExcFloatInvalidOperation: |
|
331 case EExcFloatOverflow: |
|
332 case EExcFloatStackCheck: |
|
333 case EExcFloatUnderflow: |
|
334 { |
|
335 buf.Format(_L8("A floating point exception has occurred.")); |
|
336 break; |
|
337 } |
|
338 case EExcAbort: |
|
339 { |
|
340 buf.Format(_L8("An abort exception has occurred.")); |
|
341 break; |
|
342 } |
|
343 case EExcUserInterrupt: |
|
344 { |
|
345 buf.Format(_L8("A user interrupt exception has occurred.")); |
|
346 break; |
|
347 } |
|
348 case EExcDataAbort: |
|
349 { |
|
350 buf.Format(_L8("A data abort exception has occurred.")); |
|
351 break; |
|
352 } |
|
353 case EExcCodeAbort: |
|
354 { |
|
355 buf.Format(_L8("A code abort exception has occurred.")); |
|
356 break; |
|
357 } |
|
358 case EExcGeneral: |
|
359 case EExcSingleStep: |
|
360 case EExcBreakPoint: |
|
361 case EExcKill: |
|
362 case EExcMaxNumber: |
|
363 case EExcInvalidVector: |
|
364 default: |
|
365 { |
|
366 buf.Format(_L8("An unknown exception (%d) has occurred."), iEventInfo.iExceptionNumber); |
|
367 break; |
|
368 } |
|
369 } |
|
370 |
|
371 iDispatch->DoNotifyStoppedL(iEventInfo.iProcessId, iEventInfo.iThreadId, iEventInfo.iCurrentPC, buf); |
|
372 break; |
|
373 } |
|
374 case SEventInfo::EThreadPanic: |
|
375 { |
|
376 TBuf8<100> buf; |
|
377 // buf.Format(_L8("Thread 0x%x has panicked.\nCategory: %S\nReason: %d"), iEventInfo.iThreadId, &iEventInfo.iPanicCategory, iEventInfo.iExceptionNumber); |
|
378 buf.Format(_L8("Thread 0x%x has panicked. Category: %S; Reason: %d"), iEventInfo.iThreadId, &iEventInfo.iPanicCategory, iEventInfo.iPanicReason); |
|
379 |
|
380 iDispatch->DoNotifyStoppedL(iEventInfo.iProcessId, iEventInfo.iThreadId, iEventInfo.iCurrentPC, buf, true, iEventInfo.iExceptionNumber); |
|
381 break; |
|
382 } |
|
383 case SEventInfo::EProcessPanic: |
|
384 { |
|
385 TBuf8<100> buf; |
|
386 buf.Format(_L8("Process 0x%x has panicked.\nCategory: %S\nReason: %d"), iEventInfo.iProcessId, &iEventInfo.iPanicCategory, iEventInfo.iExceptionNumber); |
|
387 |
|
388 iDispatch->DoNotifyStoppedL(iEventInfo.iProcessId, iEventInfo.iThreadId, iEventInfo.iCurrentPC, buf); |
|
389 break; |
|
390 } |
|
391 case SEventInfo::ELibraryLoaded: |
|
392 { |
|
393 // a library has been loaded. we get statically linked library loaded notifications |
|
394 // the very first time the process is created. we want to ignore these because we |
|
395 // handle static libs in another way. if the process the library was loaded for is |
|
396 // not being debugging, just resume the thread and ignore the event. if the process |
|
397 // is being debugged but it hasn't yet been created, then this must be a static lib |
|
398 // and we ignore it. note that we do not bother resuming the thread since it has not |
|
399 // been started yet! |
|
400 |
|
401 TBool created = EFalse; |
|
402 TBool found = EFalse; |
|
403 |
|
404 for (TInt i=0; i<iDispatch->iDebugProcessList.Count(); i++) |
|
405 { |
|
406 if (iDispatch->iDebugProcessList[i]->ProcessId() == iEventInfo.iProcessId) |
|
407 { |
|
408 created = iDispatch->iDebugProcessList[i]->iReadyForLibraryLoadNotification; |
|
409 found = ETrue; |
|
410 break; |
|
411 } |
|
412 } |
|
413 |
|
414 #ifndef EKA2 |
|
415 if (!iEventInfo.iCodeAddress) |
|
416 { |
|
417 TBuf<KMaxPath> libName; |
|
418 libName.Copy(iEventInfo.iFileName); |
|
419 |
|
420 RLibrary lib; |
|
421 TInt err = lib.LoadRomLibrary(libName, KNullDesC); |
|
422 if (KErrNone == err) |
|
423 { |
|
424 iEventInfo.iCodeAddress = (TUint32)lib.EntryPoint(); |
|
425 lib.Close(); |
|
426 } |
|
427 } |
|
428 #endif |
|
429 |
|
430 if (!created || !iEventInfo.iCodeAddress || !found) |
|
431 { |
|
432 iDispatch->iKernelDriver.ResumeThread(iEventInfo.iThreadId); |
|
433 } |
|
434 else |
|
435 { |
|
436 iDispatch->DoNotifyLibraryLoadedL(iEventInfo.iFileName, iEventInfo.iProcessId, iEventInfo.iThreadId, iEventInfo.iCodeAddress, iEventInfo.iDataAddress); |
|
437 } |
|
438 break; |
|
439 } |
|
440 case SEventInfo::ELibraryUnloaded: |
|
441 { |
|
442 TBool found = EFalse; |
|
443 |
|
444 for (TInt i=0; i<iDispatch->iDebugProcessList.Count(); i++) |
|
445 { |
|
446 if (iDispatch->iDebugProcessList[i]->ProcessId() == iEventInfo.iProcessId) |
|
447 { |
|
448 found = ETrue; |
|
449 break; |
|
450 } |
|
451 } |
|
452 |
|
453 if (!found) |
|
454 { |
|
455 iDispatch->iKernelDriver.ResumeThread(iEventInfo.iThreadId); |
|
456 } |
|
457 else |
|
458 { |
|
459 iDispatch->DoNotifyLibraryUnloadedL(iEventInfo.iFileName, iEventInfo.iProcessId, iEventInfo.iThreadId); |
|
460 } |
|
461 |
|
462 break; |
|
463 } |
|
464 case SEventInfo::EUserTrace: |
|
465 { |
|
466 iDispatch->DoNotifyUserTraceL(iEventInfo.iTraceData); |
|
467 break; |
|
468 } |
|
469 case SEventInfo::EProcessAdded: |
|
470 { |
|
471 iDispatch->DoNotifyProcessAddedL(iEventInfo.iFileName, iEventInfo.iProcessId, |
|
472 iEventInfo.iThreadId, iEventInfo.iUid, |
|
473 iEventInfo.iCodeAddress, iEventInfo.iDataAddress); |
|
474 break; |
|
475 } |
|
476 case SEventInfo::EUnknown: |
|
477 default: |
|
478 User::Panic(_L("Unknown event type"), __LINE__); |
|
479 break; |
|
480 } |
|
481 |
|
482 // reset the values |
|
483 iEventInfo.Reset(); |
|
484 |
|
485 // keep listening for more events |
|
486 Watch(); |
|
487 } |
|
488 |
|
489 // |
|
490 // CEventTrapper::DoCancel |
|
491 // |
|
492 // Stop listening for events |
|
493 // |
|
494 void CEventTrapper::DoCancel() |
|
495 { |
|
496 iDispatch->iKernelDriver.CancelGetEvent(); |
|
497 } |
|
498 |
|
499 |
|
500 // |
|
501 // |
|
502 // CDebugProcess implementation |
|
503 // |
|
504 // |
|
505 |
|
506 // |
|
507 // CDebugProcess::NewL |
|
508 // |
|
509 // Accepts CTrkDispatchLayer interface and the process ID and main |
|
510 // thread ID of a process being debugged |
|
511 // |
|
512 CDebugProcess* CDebugProcess::NewL(CTrkDispatchLayer *aDispatch, TUint32 aProcessId, TUint32 aMainThreadId) |
|
513 { |
|
514 CDebugProcess* self = new(ELeave) CDebugProcess(); |
|
515 self->ConstructL(aDispatch, aProcessId, aMainThreadId); |
|
516 return self; |
|
517 } |
|
518 |
|
519 // |
|
520 // CDebugProcess::ConstructL |
|
521 // |
|
522 // Accepts CTrkDispatchLayer interface and the process ID and main |
|
523 // thread ID of a process being debugged |
|
524 // |
|
525 void CDebugProcess::ConstructL(CTrkDispatchLayer *aDispatch, TUint32 aProcessId, TUint32 aMainThreadId) |
|
526 { |
|
527 iProcessId = aProcessId; |
|
528 iMainThreadId = aMainThreadId; |
|
529 iReadyForLibraryLoadNotification = EFalse; |
|
530 |
|
531 // start waiting for this process to exit |
|
532 iExitTrapper = new(ELeave) CExitTrapper(aDispatch, aProcessId); |
|
533 iExitTrapper->Watch(); |
|
534 } |
|
535 |
|
536 // |
|
537 // CDebugProcess destructor |
|
538 // |
|
539 CDebugProcess::~CDebugProcess() |
|
540 { |
|
541 SafeDelete(iExitTrapper); |
|
542 } |
|
543 |
|
544 #ifndef __TEXT_SHELL__ |
|
545 |
|
546 // |
|
547 // CPhoneInfo implementation |
|
548 // |
|
549 CPhoneInfo::CPhoneInfo(): |
|
550 CActive(EPriorityStandard), |
|
551 iPhoneIdV1Pckg(iPhoneIdV1), |
|
552 iDispatchLayer(NULL) |
|
553 { |
|
554 CActiveScheduler::Add(this); |
|
555 } |
|
556 |
|
557 CPhoneInfo* CPhoneInfo::NewL() |
|
558 { |
|
559 CPhoneInfo* self = new(ELeave) CPhoneInfo(); |
|
560 CleanupStack::PushL(self); |
|
561 self->ConstructL(); |
|
562 CleanupStack::Pop(); |
|
563 return self; |
|
564 } |
|
565 |
|
566 void CPhoneInfo::ConstructL() |
|
567 { |
|
568 iTelephony = CTelephony::NewL(); |
|
569 } |
|
570 |
|
571 CPhoneInfo::~CPhoneInfo() |
|
572 { |
|
573 Cancel(); |
|
574 Deque(); |
|
575 SafeDelete(iTelephony); |
|
576 } |
|
577 |
|
578 void CPhoneInfo::GetPhoneName(CTrkDispatchLayer* aDispatchLayer) |
|
579 { |
|
580 iDispatchLayer = aDispatchLayer; |
|
581 iTelephony->GetPhoneId(iStatus, iPhoneIdV1Pckg); |
|
582 SetActive(); |
|
583 } |
|
584 |
|
585 void CPhoneInfo::RunL() |
|
586 { |
|
587 if(iStatus == KErrNone) |
|
588 { |
|
589 iDispatchLayer->UpdatePhoneNameInfo(iPhoneIdV1.iModel); |
|
590 } |
|
591 } |
|
592 |
|
593 void CPhoneInfo::DoCancel() |
|
594 { |
|
595 iTelephony->CancelAsync(CTelephony::EGetPhoneIdCancel); |
|
596 } |
|
597 #endif |
|
598 |
|
599 // |
|
600 // |
|
601 // CTrkDispatchLayer implementation |
|
602 // |
|
603 // |
|
604 |
|
605 // |
|
606 // CTrkDispatchLayer constructor |
|
607 // |
|
608 CTrkDispatchLayer::CTrkDispatchLayer() |
|
609 : iEngine(NULL), |
|
610 iFramingLayer(NULL), |
|
611 #ifndef __TEXT_SHELL__ |
|
612 iPhoneInfo(NULL), |
|
613 #endif |
|
614 iFileState(EFileUnknown), |
|
615 iDebugProcessList(1), |
|
616 iProcessList(1), |
|
617 iThreadList(1), |
|
618 iSuspendedThreadList(1), |
|
619 iEventTrapper(NULL), |
|
620 iIsConnected(EFalse), |
|
621 iPhoneNameInfoAvailable(EFalse) |
|
622 |
|
623 #ifdef __OEM_TRK__ |
|
624 ,iUseTcbServer(EFalse) |
|
625 #endif |
|
626 { |
|
627 } |
|
628 |
|
629 // |
|
630 // CTrkDispatchLayer::NewL |
|
631 // |
|
632 CTrkDispatchLayer* CTrkDispatchLayer::NewL(CTrkCommPort *aPort, CTrkEngine* aEngine) |
|
633 { |
|
634 CTrkDispatchLayer* self = new(ELeave) CTrkDispatchLayer(); |
|
635 self->ConstructL(aPort, aEngine); |
|
636 return self; |
|
637 } |
|
638 |
|
639 // |
|
640 // CTrkDispatchLayer destructor |
|
641 // |
|
642 CTrkDispatchLayer::~CTrkDispatchLayer() |
|
643 { |
|
644 SafeDelete(iFramingLayer); |
|
645 |
|
646 SafeDelete(iInputBuffer); |
|
647 SafeDelete(iReplyBuffer); |
|
648 #ifndef __TEXT_SHELL__ |
|
649 SafeDelete(iPhoneInfo); |
|
650 #endif |
|
651 // just in case a disconnect never happened |
|
652 SafeDelete(iEventTrapper); |
|
653 |
|
654 #ifndef __WINS__ |
|
655 iKernelDriver.Close(); |
|
656 #endif |
|
657 |
|
658 CloseTcbServer(); |
|
659 iProcessList.Close(); |
|
660 iThreadList.Close(); |
|
661 iSuspendedThreadList.Close(); |
|
662 |
|
663 iDebugProcessList.ResetAndDestroy(); |
|
664 iDebugProcessList.Close(); |
|
665 //Notify the server that Debugging is ended |
|
666 if (iEngine) |
|
667 iEngine->DebuggingEnded(); |
|
668 |
|
669 } |
|
670 // |
|
671 // CTrkDispathcLayer::CloseTcbServer() |
|
672 // |
|
673 void CTrkDispatchLayer::CloseTcbServer() |
|
674 { |
|
675 #ifdef __OEM_TRK__ |
|
676 //Shutdown the tcb server. |
|
677 if (iUseTcbServer) |
|
678 { |
|
679 iTrkTcbSession.ShutDownServer(); |
|
680 iTrkTcbSession.Close(); |
|
681 iUseTcbServer = EFalse; |
|
682 } |
|
683 #endif |
|
684 |
|
685 } |
|
686 |
|
687 // |
|
688 // CTrkDispatchLayer::ConstructL |
|
689 // |
|
690 void CTrkDispatchLayer::ConstructL(CTrkCommPort *aPort, CTrkEngine* aEngine) |
|
691 { |
|
692 iEngine = aEngine; |
|
693 |
|
694 // create the framing layer interface |
|
695 iFramingLayer = new CTrkFramingLayer(aPort); |
|
696 |
|
697 // At a minimum, we assume that the host debugger supports 3.3 version of the protocol |
|
698 // From 3.0 to 3.3, TRK is backwards compatible. Starting with version 3.4, TRK sends |
|
699 // process created notifications as part of notify created event. Unless the host |
|
700 // debugger sets the supported protocol version to 3.4, we are not going to send this |
|
701 // new notification. Going forward, we should check for the protocol version before |
|
702 // we send new notifications. |
|
703 iHostVersion.iMajor = DS_PROTOCOL_MAJOR_VERSION_3; |
|
704 iHostVersion.iMinor = DS_PROTOCOL_MINOR_VERSION_3; |
|
705 |
|
706 //To find the sw version runnning in the phone |
|
707 FindPhoneSWVersion(); |
|
708 |
|
709 // On techview, this functionality is not available for some reason. |
|
710 // This needs to be investigated further, but this functionality is not critical for techview platform right now. |
|
711 #ifdef __S60__ |
|
712 // To find the name of the phone. |
|
713 TRAPD(err1, FindPhoneNameL()); |
|
714 if (err1 != KErrNone) |
|
715 #endif |
|
716 { |
|
717 iPhoneNameInfoAvailable = EFalse; |
|
718 } |
|
719 } |
|
720 |
|
721 // |
|
722 // CTrkDispathLayer::FindPhoneSWVersion() |
|
723 // |
|
724 // Finds out the software version of the phone |
|
725 // |
|
726 void CTrkDispatchLayer::FindPhoneSWVersion() |
|
727 { |
|
728 #ifndef __TEXT_SHELL__ |
|
729 TBuf<KSysUtilVersionTextLength> version; |
|
730 if (SysUtil::GetSWVersion( version ) == KErrNone ) |
|
731 { |
|
732 iPhoneVersion.Copy(version); |
|
733 } |
|
734 #endif |
|
735 } |
|
736 |
|
737 // |
|
738 // CTrkDispathLayer::FindPhoneName() |
|
739 // |
|
740 // Finds the name of the phone |
|
741 // |
|
742 void CTrkDispatchLayer::FindPhoneNameL() |
|
743 { |
|
744 #ifndef __TEXT_SHELL__ |
|
745 iPhoneInfo = CPhoneInfo::NewL(); |
|
746 iPhoneInfo->GetPhoneName(this); |
|
747 #endif |
|
748 } |
|
749 |
|
750 // |
|
751 // CTrkDispatchLayer::Listen |
|
752 // |
|
753 // Start listening to the communications port for messages from the host debugger |
|
754 // |
|
755 void CTrkDispatchLayer::Listen() |
|
756 { |
|
757 iFramingLayer->Listen(this); |
|
758 } |
|
759 |
|
760 // |
|
761 // CTrkDispatchLayer::StopListening |
|
762 // |
|
763 // Stop listening to the communications port for messages from the host debugger |
|
764 // |
|
765 void CTrkDispatchLayer::StopListening() |
|
766 { |
|
767 // just in case the user quit MetroTrk while something was being debugged. |
|
768 RProcess process; |
|
769 for (TInt i=0; i<iDebugProcessList.Count(); i++) |
|
770 { |
|
771 if (KErrNone == process.Open(iDebugProcessList[i]->ProcessId())) |
|
772 { |
|
773 #ifdef EKA2 |
|
774 process.Kill(KErrNone); |
|
775 #else |
|
776 process.Kill(KProcessKilled); |
|
777 #endif |
|
778 process.Close(); |
|
779 } |
|
780 } |
|
781 |
|
782 iFramingLayer->StopListening(); |
|
783 } |
|
784 |
|
785 // |
|
786 // CTrkDispatchLayer::GetVersionInfo |
|
787 // |
|
788 // Get the current version of MetroTrk |
|
789 // |
|
790 void CTrkDispatchLayer::GetVersionInfo(TInt &aMajorVersion, TInt &aMinorVersion, TInt &aMajorAPIVersion, TInt &aMinorAPIVersion, TInt &aBuildNumber) |
|
791 { |
|
792 aMajorVersion = MAJOR_VERSION_NUMBER; |
|
793 aMinorVersion = MINOR_VERSION_NUMBER; |
|
794 aMajorAPIVersion = DS_PROTOCOL_MAJOR_VERSION; |
|
795 aMinorAPIVersion = DS_PROTOCOL_MINOR_VERSION; |
|
796 aBuildNumber = BUILD_NUMBER; |
|
797 } |
|
798 |
|
799 // |
|
800 // CTrkDispatchLayer::HandleMsg |
|
801 // |
|
802 // Handle a command sent by the host debugger |
|
803 // |
|
804 void CTrkDispatchLayer::HandleMsg(const TDesC8& aMsg) |
|
805 { |
|
806 TInt error = KErrNone; |
|
807 |
|
808 // reset the input buffer and set it to the new unframed message |
|
809 SafeDelete(iInputBuffer); |
|
810 iInputBuffer = aMsg.Alloc(); |
|
811 |
|
812 if (!iInputBuffer) |
|
813 User::Panic(_L("Failed to allocate input buffer"), __LINE__); |
|
814 |
|
815 TRAP(error, DispatchMsgL()); |
|
816 |
|
817 if (error < 0) |
|
818 { |
|
819 // its a symbian os error |
|
820 error = kDSReplyOsError; |
|
821 } |
|
822 |
|
823 // handle errors raised during command execution |
|
824 switch(error) |
|
825 { |
|
826 // no error and ack was sent by handler |
|
827 case kDSReplyNoError: |
|
828 break; |
|
829 |
|
830 // there was a problem with the packet received |
|
831 case kDSReplyPacketSizeError: |
|
832 case kDSReplyEscapeError: |
|
833 case kDSReplyBadFCS: |
|
834 case kDSReplyOverflow: |
|
835 case kDSReplySequenceMissing: |
|
836 iFramingLayer->RespondErr(kDSReplyNAK, error); |
|
837 break; |
|
838 |
|
839 // command and format were OK, but failed for some other reason |
|
840 default: |
|
841 iFramingLayer->RespondErr(kDSReplyACK, error); |
|
842 } |
|
843 } |
|
844 |
|
845 // |
|
846 // CTrkDispatchLayer::DispatchMsgL |
|
847 // |
|
848 // Handle the command sent by the host debugger |
|
849 // |
|
850 void CTrkDispatchLayer::DispatchMsgL() |
|
851 { |
|
852 // make sure the input buffer is setup |
|
853 User::LeaveIfNull(iInputBuffer); |
|
854 |
|
855 // iInputBuffer holds the unframed message from the host |
|
856 switch (iInputBuffer->Ptr()[0]) |
|
857 { |
|
858 case kDSPing: |
|
859 { |
|
860 // nothing to do |
|
861 iFramingLayer->RespondOkL(KNullDesC8); |
|
862 break; |
|
863 } |
|
864 case kDSConnect: |
|
865 { |
|
866 DoConnectL(); |
|
867 break; |
|
868 } |
|
869 case kDSDisconnect: |
|
870 { |
|
871 DoDisconnectL(); |
|
872 break; |
|
873 } |
|
874 case kDSVersions: |
|
875 { |
|
876 DoVersionsL(); |
|
877 break; |
|
878 } |
|
879 case kDSVersions2: |
|
880 { |
|
881 DoVersions2L(); |
|
882 break; |
|
883 } |
|
884 case kDSVersions3: |
|
885 { |
|
886 DoVersions3L(); |
|
887 break; |
|
888 } |
|
889 case kDSHostVersions: |
|
890 { |
|
891 DoHostVersionsL(); |
|
892 break; |
|
893 } |
|
894 case kDSSupportMask: |
|
895 { |
|
896 DoSupportMaskL(); |
|
897 break; |
|
898 } |
|
899 case kDSCPUType: |
|
900 { |
|
901 DoCPUTypeL(); |
|
902 break; |
|
903 } |
|
904 case kDSReadMemory: |
|
905 { |
|
906 DoReadMemoryL(); |
|
907 break; |
|
908 } |
|
909 case kDSWriteMemory: |
|
910 { |
|
911 DoWriteMemoryL(); |
|
912 break; |
|
913 } |
|
914 case kDSReadRegisters: |
|
915 { |
|
916 DoReadRegistersL(); |
|
917 break; |
|
918 } |
|
919 case kDSWriteRegisters: |
|
920 { |
|
921 DoWriteRegistersL(); |
|
922 break; |
|
923 } |
|
924 case kDSContinue: |
|
925 { |
|
926 DoContinueL(); |
|
927 break; |
|
928 } |
|
929 case kDSStep: |
|
930 { |
|
931 DoStepL(); |
|
932 break; |
|
933 } |
|
934 case kDSStop: |
|
935 { |
|
936 DoStopL(); |
|
937 break; |
|
938 } |
|
939 case kDSSetBreak: |
|
940 { |
|
941 DoSetBreakL(); |
|
942 break; |
|
943 } |
|
944 case kDSClearBreak: |
|
945 { |
|
946 DoClearBreakL(); |
|
947 break; |
|
948 } |
|
949 case kDSModifyBreakThread: |
|
950 { |
|
951 DoModifyBreakThreadL(); |
|
952 break; |
|
953 } |
|
954 case kDSOSCreateItem: |
|
955 { |
|
956 DoCreateItemL(); |
|
957 break; |
|
958 } |
|
959 case kDSOSDeleteItem: |
|
960 { |
|
961 DoDeleteItemL(); |
|
962 break; |
|
963 } |
|
964 case kDSOSReadInfo: |
|
965 { |
|
966 DoReadInfoL(); |
|
967 break; |
|
968 } |
|
969 case kDSOSWriteInfo: |
|
970 { |
|
971 DoWriteInfoL(); |
|
972 break; |
|
973 } |
|
974 case kDSOSWriteFile: |
|
975 { |
|
976 DoWriteFileL(); |
|
977 break; |
|
978 } |
|
979 case kDSOSReadFile: |
|
980 { |
|
981 DoReadFileL(); |
|
982 break; |
|
983 } |
|
984 case kDSOSOpenFile: |
|
985 { |
|
986 DoOpenFileL(); |
|
987 break; |
|
988 } |
|
989 case kDSOSCloseFile: |
|
990 { |
|
991 DoCloseFileL(); |
|
992 break; |
|
993 } |
|
994 case kDSOSPositionFile: |
|
995 { |
|
996 DoPositionFileL(); |
|
997 break; |
|
998 } |
|
999 case kDSOSInstallFile: |
|
1000 { |
|
1001 DoInstallFileL(); |
|
1002 break; |
|
1003 } |
|
1004 case kDSOSInstallFile2: |
|
1005 { |
|
1006 DoInstallFile2L(); |
|
1007 break; |
|
1008 } |
|
1009 case kDSOSPhoneSWVersion: |
|
1010 { |
|
1011 DoGetPhoneSWVersionL(); |
|
1012 break; |
|
1013 } |
|
1014 case kDSOSPhoneName: |
|
1015 { |
|
1016 DoGetPhoneNameL(); |
|
1017 break; |
|
1018 } |
|
1019 |
|
1020 case kDSReplyACK: |
|
1021 case kDSReplyNAK: |
|
1022 break; |
|
1023 |
|
1024 case kDSReset: |
|
1025 case kDSFillMemory: |
|
1026 case kDSCopyMemory: |
|
1027 case kDSFlushCache: |
|
1028 case kDSDownload: |
|
1029 case kDSNotifyFileInput: |
|
1030 default: |
|
1031 { |
|
1032 // unsupported command |
|
1033 iFramingLayer->RespondErr(kDSReplyACK, kDSReplyUnsupportedCommandError); |
|
1034 break; |
|
1035 } |
|
1036 } |
|
1037 } |
|
1038 |
|
1039 // |
|
1040 // CTrkDispatchLayer::DoConnectL |
|
1041 // |
|
1042 // The host debugger is starting a new debug session |
|
1043 // |
|
1044 void CTrkDispatchLayer::DoConnectL() |
|
1045 { |
|
1046 // make sure we got here from DispatchMsgL |
|
1047 TUint8 command = 0; |
|
1048 GetDataFromBufferL(&command, 1); |
|
1049 |
|
1050 if (kDSConnect != command) |
|
1051 User::Leave(kDSReplyError); |
|
1052 |
|
1053 // if we're already connected for some reason, we need to cleanup so we're ready |
|
1054 // for a new debug session |
|
1055 if (iIsConnected) |
|
1056 { |
|
1057 // reset the sequence ids for the next debug session |
|
1058 iFramingLayer->ResetSequenceIDs(); |
|
1059 |
|
1060 //stop listening for events |
|
1061 SafeDelete(iEventTrapper); |
|
1062 |
|
1063 // let the kernel side driver cleanup |
|
1064 iKernelDriver.Close(); |
|
1065 |
|
1066 iIsConnected = EFalse; |
|
1067 } |
|
1068 |
|
1069 // reset the lists so that they are ready for use |
|
1070 iProcessList.Reset(); |
|
1071 iThreadList.Reset(); |
|
1072 iSuspendedThreadList.Reset(); |
|
1073 iDebugProcessList.ResetAndDestroy(); |
|
1074 |
|
1075 TMetroTrkDriverInfo info; |
|
1076 #ifndef EKA2 |
|
1077 RLibrary euser; |
|
1078 User::LeaveIfError(euser.Load(EUSER_LIBPATH)); |
|
1079 CleanupClosePushL(euser); |
|
1080 |
|
1081 info.iPanic1Address = (TUint32)euser.Lookup(812); // RThread::Panic |
|
1082 info.iPanic2Address = (TUint32)euser.Lookup(813); // RProcess::Panic |
|
1083 info.iException1Address = (TUint32)euser.Lookup(868); // RThread::RaiseException |
|
1084 info.iException2Address = (TUint32)euser.Lookup(520); // User::HandleException |
|
1085 info.iLibraryLoadedAddress = (TUint32)euser.Lookup(636); // UserSvr::LibraryLoaded |
|
1086 |
|
1087 // calculate the end address of the user library. breakpoints and stepping will not |
|
1088 // be allowed from the start of ROM to the end of the user library since stopping a |
|
1089 // kernel thread could end up freezing the target |
|
1090 RFs fs; |
|
1091 User::LeaveIfError(fs.Connect()); |
|
1092 CleanupClosePushL(fs); |
|
1093 |
|
1094 RFile file; |
|
1095 User::LeaveIfError(file.Open(fs, EUSER_LIBPATH, EFileStream|EFileRead|EFileShareReadersOnly)); |
|
1096 CleanupClosePushL(file); |
|
1097 |
|
1098 TInt size; |
|
1099 User::LeaveIfError(file.Size(size)); |
|
1100 |
|
1101 info.iUserLibraryEnd = (TUint32)euser.EntryPoint() + size; |
|
1102 |
|
1103 CleanupStack::PopAndDestroy(); // file |
|
1104 CleanupStack::PopAndDestroy(); // fs |
|
1105 CleanupStack::PopAndDestroy(); // euser |
|
1106 #endif |
|
1107 |
|
1108 // start the kernel side driver |
|
1109 User::LeaveIfError(iKernelDriver.Open(info)); |
|
1110 |
|
1111 // start listening for events |
|
1112 iEventTrapper = new(ELeave) CEventTrapper(this); |
|
1113 iEventTrapper->Watch(); |
|
1114 |
|
1115 iIsConnected = ETrue; |
|
1116 #ifdef __S60__ |
|
1117 // now close close crash logger |
|
1118 CloseCrashLogger(); |
|
1119 #endif |
|
1120 |
|
1121 if (iEngine) |
|
1122 iEngine->DebuggingStarted(); |
|
1123 |
|
1124 iFramingLayer->RespondOkL(KNullDesC8); |
|
1125 } |
|
1126 |
|
1127 // |
|
1128 // CTrkDispatchLayer::DoDisconnectL |
|
1129 // |
|
1130 // The host debugger is stopping the current debug session |
|
1131 // |
|
1132 void CTrkDispatchLayer::DoDisconnectL() |
|
1133 { |
|
1134 // make sure we got here from DispatchMsgL |
|
1135 TUint8 command = 0; |
|
1136 GetDataFromBufferL(&command, 1); |
|
1137 |
|
1138 if (kDSDisconnect != command) |
|
1139 User::Leave(kDSReplyError); |
|
1140 |
|
1141 // make sure we're connected |
|
1142 if (!iIsConnected) |
|
1143 { |
|
1144 User::Leave(KErrCouldNotDisconnect); |
|
1145 } |
|
1146 |
|
1147 //stop listening for events |
|
1148 SafeDelete(iEventTrapper); |
|
1149 |
|
1150 iIsConnected = EFalse; |
|
1151 |
|
1152 iFramingLayer->RespondOkL(KNullDesC8); |
|
1153 |
|
1154 // let the kernel side driver cleanup |
|
1155 iKernelDriver.Close(); |
|
1156 |
|
1157 //Shutdown the tcb server. |
|
1158 CloseTcbServer(); |
|
1159 |
|
1160 // send the callback to the trk server |
|
1161 if (iEngine) |
|
1162 iEngine->DebuggingEnded(); |
|
1163 |
|
1164 } |
|
1165 |
|
1166 // |
|
1167 // CTrkDispatchLayer::DoVersionsL |
|
1168 // |
|
1169 // The host debugger is requesting MetroTrk version information |
|
1170 // |
|
1171 void CTrkDispatchLayer::DoVersionsL() |
|
1172 { |
|
1173 // make sure we got here from DispatchMsgL |
|
1174 TUint8 command = 0; |
|
1175 GetDataFromBufferL(&command, 1); |
|
1176 |
|
1177 if (kDSVersions != command) |
|
1178 User::Leave(kDSReplyError); |
|
1179 |
|
1180 TUint8 kernelMajorVersion = MAJOR_VERSION_NUMBER; |
|
1181 TUint8 kernelMinorVersion = MINOR_VERSION_NUMBER; |
|
1182 TUint8 protocolMajorVersion = DS_PROTOCOL_MAJOR_VERSION; |
|
1183 TUint8 protocolMinorVersion = DS_PROTOCOL_MINOR_VERSION; |
|
1184 |
|
1185 AddToReplyBufferL(kernelMajorVersion, true); |
|
1186 AddToReplyBufferL(kernelMinorVersion); |
|
1187 AddToReplyBufferL(protocolMajorVersion); |
|
1188 AddToReplyBufferL(protocolMinorVersion); |
|
1189 |
|
1190 RespondOkL(); |
|
1191 } |
|
1192 |
|
1193 // |
|
1194 // CTrkDispatchLayer::DoVersionsL |
|
1195 // |
|
1196 // The host debugger is requesting MetroTrk version information |
|
1197 // |
|
1198 void CTrkDispatchLayer::DoVersions2L() |
|
1199 { |
|
1200 // make sure we got here from DispatchMsgL |
|
1201 TUint8 command = 0; |
|
1202 GetDataFromBufferL(&command, 1); |
|
1203 |
|
1204 if (kDSVersions2 != command) |
|
1205 User::Leave(kDSReplyError); |
|
1206 |
|
1207 TUint8 kernelMajorVersion = MAJOR_VERSION_NUMBER; |
|
1208 TUint8 kernelMinorVersion = MINOR_VERSION_NUMBER; |
|
1209 TUint8 protocolMajorVersion = DS_PROTOCOL_MAJOR_VERSION; |
|
1210 TUint8 protocolMinorVersion = DS_PROTOCOL_MINOR_VERSION; |
|
1211 TUint8 buildNumber = BUILD_NUMBER; |
|
1212 |
|
1213 AddToReplyBufferL(kernelMajorVersion, true); |
|
1214 AddToReplyBufferL(kernelMinorVersion); |
|
1215 AddToReplyBufferL(protocolMajorVersion); |
|
1216 AddToReplyBufferL(protocolMinorVersion); |
|
1217 AddToReplyBufferL(buildNumber); |
|
1218 |
|
1219 RespondOkL(); |
|
1220 } |
|
1221 |
|
1222 // |
|
1223 // CTrkDispatchLayer::DoVersions3L |
|
1224 // |
|
1225 // The host debugger is requesting MetroTrk version information |
|
1226 // |
|
1227 void CTrkDispatchLayer::DoVersions3L() |
|
1228 { |
|
1229 // make sure we got here from DispatchMsgL |
|
1230 TUint8 command = 0; |
|
1231 GetDataFromBufferL(&command, 1); |
|
1232 |
|
1233 if (kDSVersions3 != command) |
|
1234 User::Leave(kDSReplyError); |
|
1235 |
|
1236 TUint8 kernelMajorVersion = MAJOR_VERSION_NUMBER; |
|
1237 TUint8 kernelMinorVersion = MINOR_VERSION_NUMBER; |
|
1238 TUint8 protocolMajorVersion = DS_PROTOCOL_MAJOR_VERSION; |
|
1239 TUint8 protocolMinorVersion = DS_PROTOCOL_MINOR_VERSION; |
|
1240 TUint8 buildNumber = BUILD_NUMBER; |
|
1241 |
|
1242 AddToReplyBufferL(kernelMajorVersion, true); |
|
1243 AddToReplyBufferL(kernelMinorVersion); |
|
1244 AddToReplyBufferL(protocolMajorVersion); |
|
1245 AddToReplyBufferL(protocolMinorVersion); |
|
1246 AddToReplyBufferL(buildNumber); |
|
1247 |
|
1248 TUint16 len = TRK_TYPE_DESCRIPTION.Length(); |
|
1249 |
|
1250 AddToReplyBufferL(len); |
|
1251 AddToReplyBufferL(TRK_TYPE_DESCRIPTION); |
|
1252 |
|
1253 RespondOkL(); |
|
1254 } |
|
1255 |
|
1256 // |
|
1257 // CTrkDispatchLayer::DoHostVersionsL |
|
1258 // |
|
1259 // The host debugger is sending the supported protocol version |
|
1260 // |
|
1261 void CTrkDispatchLayer::DoHostVersionsL() |
|
1262 { |
|
1263 // make sure we got here from DispatchMsgL |
|
1264 TUint8 command = 0; |
|
1265 GetDataFromBufferL(&command, 1); |
|
1266 |
|
1267 if (kDSHostVersions != command) |
|
1268 User::Leave(kDSReplyError); |
|
1269 |
|
1270 GetDataFromBufferL(&iHostVersion.iMajor, 1); |
|
1271 GetDataFromBufferL(&iHostVersion.iMinor, 1); |
|
1272 |
|
1273 iFramingLayer->RespondOkL(KNullDesC8); |
|
1274 } |
|
1275 |
|
1276 // |
|
1277 // CTrkDispatchLayer::DoSupportMaskL |
|
1278 // |
|
1279 // The host debugger is requesting MetroTrk capabilities |
|
1280 // |
|
1281 void CTrkDispatchLayer::DoSupportMaskL() |
|
1282 { |
|
1283 // make sure we got here from DispatchMsgL |
|
1284 TUint8 command = 0; |
|
1285 GetDataFromBufferL(&command, 1); |
|
1286 |
|
1287 if (kDSSupportMask != command) |
|
1288 User::Leave(kDSReplyError); |
|
1289 |
|
1290 TBuf8<32> supportMask; |
|
1291 TUint8 level = DS_PROTOCOL_RTOS; |
|
1292 |
|
1293 supportMask.Zero(); |
|
1294 supportMask.Append(DS_SUPPORT_MASK_00_07); |
|
1295 supportMask.Append(DS_SUPPORT_MASK_08_0F); |
|
1296 supportMask.Append(DS_SUPPORT_MASK_10_17); |
|
1297 supportMask.Append(DS_SUPPORT_MASK_18_1F); |
|
1298 supportMask.Append(DS_SUPPORT_MASK_20_27); |
|
1299 supportMask.Append(DS_SUPPORT_MASK_28_2F); |
|
1300 supportMask.Append(DS_SUPPORT_MASK_30_37); |
|
1301 supportMask.Append(DS_SUPPORT_MASK_38_3F); |
|
1302 supportMask.Append(DS_SUPPORT_MASK_40_47); |
|
1303 supportMask.Append(DS_SUPPORT_MASK_48_4F); |
|
1304 supportMask.Append(DS_SUPPORT_MASK_50_57); |
|
1305 supportMask.Append(DS_SUPPORT_MASK_58_5F); |
|
1306 supportMask.Append(DS_SUPPORT_MASK_60_67); |
|
1307 supportMask.Append(DS_SUPPORT_MASK_68_6F); |
|
1308 supportMask.Append(DS_SUPPORT_MASK_70_77); |
|
1309 supportMask.Append(DS_SUPPORT_MASK_78_7F); |
|
1310 supportMask.Append(DS_SUPPORT_MASK_80_87); |
|
1311 supportMask.Append(DS_SUPPORT_MASK_88_8F); |
|
1312 supportMask.Append(DS_SUPPORT_MASK_90_97); |
|
1313 supportMask.Append(DS_SUPPORT_MASK_98_9F); |
|
1314 supportMask.Append(DS_SUPPORT_MASK_A0_A7); |
|
1315 supportMask.Append(DS_SUPPORT_MASK_A8_AF); |
|
1316 supportMask.Append(DS_SUPPORT_MASK_B0_B7); |
|
1317 supportMask.Append(DS_SUPPORT_MASK_B8_BF); |
|
1318 supportMask.Append(DS_SUPPORT_MASK_C0_C7); |
|
1319 supportMask.Append(DS_SUPPORT_MASK_C8_CF); |
|
1320 supportMask.Append(DS_SUPPORT_MASK_D0_D7); |
|
1321 supportMask.Append(DS_SUPPORT_MASK_D8_DF); |
|
1322 supportMask.Append(DS_SUPPORT_MASK_E0_E7); |
|
1323 supportMask.Append(DS_SUPPORT_MASK_E8_EF); |
|
1324 supportMask.Append(DS_SUPPORT_MASK_F0_F7); |
|
1325 supportMask.Append(DS_SUPPORT_MASK_F8_FF); |
|
1326 |
|
1327 AddToReplyBufferL(supportMask, true); |
|
1328 AddToReplyBufferL(level); |
|
1329 |
|
1330 RespondOkL(); |
|
1331 } |
|
1332 |
|
1333 // |
|
1334 // CTrkDispatchLayer::DoCPUTypeL |
|
1335 // |
|
1336 // The host debugger is requesting cpu information |
|
1337 // |
|
1338 void CTrkDispatchLayer::DoCPUTypeL() |
|
1339 { |
|
1340 // make sure we got here from DispatchMsgL |
|
1341 TUint8 command = 0; |
|
1342 GetDataFromBufferL(&command, 1); |
|
1343 |
|
1344 if (kDSCPUType != command) |
|
1345 User::Leave(kDSReplyError); |
|
1346 |
|
1347 TUint8 cpuMajor = DS_CPU_MAJOR_ARM; |
|
1348 TUint8 cpuMinor = 0; |
|
1349 TUint8 bigEndian = iFramingLayer->IsBigEndian() ? 1 : 0; |
|
1350 TUint8 defaultTypeSize = 4; |
|
1351 TUint8 fpTypeSize = 0; |
|
1352 TUint8 extended1TypeSize = 0; |
|
1353 TUint8 extended2TypeSize = 0; |
|
1354 |
|
1355 AddToReplyBufferL(cpuMajor, true); |
|
1356 AddToReplyBufferL(cpuMinor); |
|
1357 AddToReplyBufferL(bigEndian); |
|
1358 AddToReplyBufferL(defaultTypeSize); |
|
1359 AddToReplyBufferL(fpTypeSize); |
|
1360 AddToReplyBufferL(extended1TypeSize); |
|
1361 AddToReplyBufferL(extended2TypeSize); |
|
1362 |
|
1363 RespondOkL(); |
|
1364 } |
|
1365 |
|
1366 // |
|
1367 // CTrkDispatchLayer::DoReadMemoryL |
|
1368 // |
|
1369 // Read memory from the target device and return to the host |
|
1370 // |
|
1371 void CTrkDispatchLayer::DoReadMemoryL() |
|
1372 { |
|
1373 // make sure we're connected |
|
1374 if (!iIsConnected) |
|
1375 { |
|
1376 User::Leave(KErrGeneral); |
|
1377 } |
|
1378 |
|
1379 // make sure we got here from DispatchMsgL |
|
1380 TUint8 command = 0; |
|
1381 GetDataFromBufferL(&command, 1); |
|
1382 |
|
1383 if (kDSReadMemory != command) |
|
1384 User::Leave(kDSReplyError); |
|
1385 |
|
1386 // get the options |
|
1387 TUint8 options = 0; |
|
1388 GetDataFromBufferL(&options, 1); |
|
1389 |
|
1390 if ((options & DS_MSG_MEMORY_EXTENDED) != 0) |
|
1391 User::Leave(kDSReplyUnsupportedOptionError); |
|
1392 |
|
1393 // get the length to read |
|
1394 TUint16 length = 0; |
|
1395 GetDataFromBufferL(&length, 2); |
|
1396 |
|
1397 if (length > DS_MAXREADWRITELENGTH) |
|
1398 User::Leave(kDSReplyParameterError); |
|
1399 |
|
1400 // get the start address |
|
1401 TUint32 address = 0; |
|
1402 GetDataFromBufferL(&address, 4); |
|
1403 |
|
1404 // get the process id |
|
1405 TUint32 processId = 0; |
|
1406 GetDataFromBufferL(&processId, 4); |
|
1407 |
|
1408 // get the thread id |
|
1409 TUint32 threadId = 0; |
|
1410 GetDataFromBufferL(&threadId, 4); |
|
1411 |
|
1412 // allocate enough room for the data |
|
1413 HBufC8 *data = HBufC8::NewLC(length); |
|
1414 TPtr8 ptr(data->Des()); |
|
1415 |
|
1416 TInt err = iKernelDriver.ReadMemory(threadId, address, length, ptr); |
|
1417 if (KErrNone != err) |
|
1418 { |
|
1419 CleanupStack::PopAndDestroy(data); |
|
1420 User::Leave(err); |
|
1421 } |
|
1422 |
|
1423 AddToReplyBufferL(length, true); |
|
1424 AddToReplyBufferL(ptr); |
|
1425 |
|
1426 RespondOkL(); |
|
1427 |
|
1428 CleanupStack::PopAndDestroy(data); |
|
1429 } |
|
1430 |
|
1431 // |
|
1432 // CTrkDispatchLayer::DoWriteMemoryL |
|
1433 // |
|
1434 // Write memory from the host to the target device |
|
1435 // |
|
1436 void CTrkDispatchLayer::DoWriteMemoryL() |
|
1437 { |
|
1438 // make sure we're connected |
|
1439 if (!iIsConnected) |
|
1440 { |
|
1441 User::Leave(KErrGeneral); |
|
1442 } |
|
1443 |
|
1444 // make sure we got here from DispatchMsgL |
|
1445 TUint8 command = 0; |
|
1446 GetDataFromBufferL(&command, 1); |
|
1447 |
|
1448 if (kDSWriteMemory != command) |
|
1449 User::Leave(kDSReplyError); |
|
1450 |
|
1451 // get the options |
|
1452 TUint8 options = 0; |
|
1453 GetDataFromBufferL(&options, 1); |
|
1454 |
|
1455 if ((options & DS_MSG_MEMORY_EXTENDED) != 0) |
|
1456 User::Leave(kDSReplyUnsupportedOptionError); |
|
1457 |
|
1458 // get the length to write |
|
1459 TUint16 length = 0; |
|
1460 GetDataFromBufferL(&length, 2); |
|
1461 |
|
1462 if (length > DS_MAXREADWRITELENGTH) |
|
1463 User::Leave(kDSReplyParameterError); |
|
1464 |
|
1465 // get the start address |
|
1466 TUint32 address = 0; |
|
1467 GetDataFromBufferL(&address, 4); |
|
1468 |
|
1469 // get the process id |
|
1470 TUint32 processId = 0; |
|
1471 GetDataFromBufferL(&processId, 4); |
|
1472 |
|
1473 // get the thread id |
|
1474 TUint32 threadId = 0; |
|
1475 GetDataFromBufferL(&threadId, 4); |
|
1476 |
|
1477 User::LeaveIfError(iKernelDriver.WriteMemory(threadId, address, length, *iInputBuffer)); |
|
1478 |
|
1479 AddToReplyBufferL(length, true); |
|
1480 |
|
1481 RespondOkL(); |
|
1482 } |
|
1483 |
|
1484 // |
|
1485 // CTrkDispatchLayer::DoReadRegistersL |
|
1486 // |
|
1487 // Read registers from the target device and return to the host |
|
1488 // |
|
1489 void CTrkDispatchLayer::DoReadRegistersL() |
|
1490 { |
|
1491 // make sure we're connected |
|
1492 if (!iIsConnected) |
|
1493 { |
|
1494 User::Leave(KErrGeneral); |
|
1495 } |
|
1496 |
|
1497 // make sure we got here from DispatchMsgL |
|
1498 TUint8 command = 0; |
|
1499 GetDataFromBufferL(&command, 1); |
|
1500 |
|
1501 if (kDSReadRegisters != command) |
|
1502 User::Leave(kDSReplyError); |
|
1503 |
|
1504 // get the options |
|
1505 TUint8 options = 0; |
|
1506 GetDataFromBufferL(&options, 1); |
|
1507 |
|
1508 if (DS_MSG_REGISTERS_TYPE(options) != kDSRegistersDefault) |
|
1509 User::Leave(kDSReplyUnsupportedOptionError); |
|
1510 |
|
1511 // get the first register |
|
1512 TInt16 firstRegister = 0; |
|
1513 GetDataFromBufferL(&firstRegister, 2); |
|
1514 |
|
1515 // get the last register |
|
1516 TInt16 lastRegister = 0; |
|
1517 GetDataFromBufferL(&lastRegister, 2); |
|
1518 |
|
1519 if ((firstRegister < 0) || (lastRegister > 16)) |
|
1520 User::Leave(kDSReplyInvalidRegisterRange); |
|
1521 |
|
1522 // get the process id |
|
1523 TUint32 processId = 0; |
|
1524 GetDataFromBufferL(&processId, 4); |
|
1525 |
|
1526 // get the thread id |
|
1527 TUint32 threadId = 0; |
|
1528 GetDataFromBufferL(&threadId, 4); |
|
1529 |
|
1530 // allocate enough space to hold the values |
|
1531 HBufC8 *values = HBufC8::NewLC((lastRegister - firstRegister + 1) * 4); |
|
1532 TPtr8 ptr(values->Des()); |
|
1533 |
|
1534 TInt err = iKernelDriver.ReadRegisters(threadId, firstRegister, lastRegister, ptr); |
|
1535 if (KErrNone != err) |
|
1536 { |
|
1537 CleanupStack::PopAndDestroy(values); |
|
1538 User::Leave(err); |
|
1539 } |
|
1540 |
|
1541 for (int i=0; i<=lastRegister - firstRegister; i++) |
|
1542 AddToReplyBufferL(*(TUint32 *)&ptr.Ptr()[i*4], i==0 ? true : false); |
|
1543 |
|
1544 RespondOkL(); |
|
1545 |
|
1546 CleanupStack::PopAndDestroy(values); |
|
1547 } |
|
1548 |
|
1549 // |
|
1550 // CTrkDispatchLayer::DoWriteRegistersL |
|
1551 // |
|
1552 // Write registers from the host to the target device |
|
1553 // |
|
1554 void CTrkDispatchLayer::DoWriteRegistersL() |
|
1555 { |
|
1556 // make sure we're connected |
|
1557 if (!iIsConnected) |
|
1558 { |
|
1559 User::Leave(KErrGeneral); |
|
1560 } |
|
1561 |
|
1562 // make sure we got here from DispatchMsgL |
|
1563 TUint8 command = 0; |
|
1564 GetDataFromBufferL(&command, 1); |
|
1565 |
|
1566 if (kDSWriteRegisters != command) |
|
1567 User::Leave(kDSReplyError); |
|
1568 |
|
1569 // get the options |
|
1570 TUint8 options = 0; |
|
1571 GetDataFromBufferL(&options, 1); |
|
1572 |
|
1573 if (DS_MSG_REGISTERS_TYPE(options) != kDSRegistersDefault) |
|
1574 User::Leave(kDSReplyUnsupportedOptionError); |
|
1575 |
|
1576 // get the first register |
|
1577 TInt16 firstRegister = 0; |
|
1578 GetDataFromBufferL(&firstRegister, 2); |
|
1579 |
|
1580 // get the last register |
|
1581 TInt16 lastRegister = 0; |
|
1582 GetDataFromBufferL(&lastRegister, 2); |
|
1583 |
|
1584 if ((firstRegister < 0) || (lastRegister > 16)) |
|
1585 User::Leave(kDSReplyInvalidRegisterRange); |
|
1586 |
|
1587 // get the process id |
|
1588 TUint32 processId = 0; |
|
1589 GetDataFromBufferL(&processId, 4); |
|
1590 |
|
1591 // get the thread id |
|
1592 TUint32 threadId = 0; |
|
1593 GetDataFromBufferL(&threadId, 4); |
|
1594 |
|
1595 // MetroTrk register values come in as big endian so we may need to swap them |
|
1596 if (!iFramingLayer->IsBigEndian()) |
|
1597 { |
|
1598 Swap4xN((TUint32 *)iInputBuffer->Ptr(), lastRegister-firstRegister + 1); |
|
1599 } |
|
1600 |
|
1601 User::LeaveIfError(iKernelDriver.WriteRegisters(threadId, firstRegister, lastRegister, *iInputBuffer)); |
|
1602 |
|
1603 iFramingLayer->RespondOkL(KNullDesC8); |
|
1604 } |
|
1605 |
|
1606 // |
|
1607 // CTrkDispatchLayer::DoContinueL |
|
1608 // |
|
1609 // Resume thread execution |
|
1610 // |
|
1611 void CTrkDispatchLayer::DoContinueL() |
|
1612 { |
|
1613 // make sure we're connected |
|
1614 if (!iIsConnected) |
|
1615 { |
|
1616 User::Leave(KErrGeneral); |
|
1617 } |
|
1618 |
|
1619 // make sure we got here from DispatchMsgL |
|
1620 TUint8 command = 0; |
|
1621 GetDataFromBufferL(&command, 1); |
|
1622 |
|
1623 if (kDSContinue != command) |
|
1624 User::Leave(kDSReplyError); |
|
1625 |
|
1626 // get the process id |
|
1627 TUint32 processId = 0; |
|
1628 GetDataFromBufferL(&processId, 4); |
|
1629 |
|
1630 // get the thread id |
|
1631 TUint32 threadId = 0; |
|
1632 GetDataFromBufferL(&threadId, 4); |
|
1633 |
|
1634 // see if this thread is in the the suspended threads list |
|
1635 // if so, remove it and resume. otherwise we need to handle |
|
1636 // the special case of the first time a thread is resumed |
|
1637 TInt index = iSuspendedThreadList.Find(threadId); |
|
1638 if (index >= 0) |
|
1639 { |
|
1640 iSuspendedThreadList.Remove(index); |
|
1641 User::LeaveIfError(iKernelDriver.ResumeThread(threadId)); |
|
1642 iFramingLayer->RespondOkL(KNullDesC8); |
|
1643 } |
|
1644 else |
|
1645 { |
|
1646 // if it's not in the suspended list then this is the first time it has been |
|
1647 // resumed (the process has just been created). see if there are statically |
|
1648 // linked libraries that we need to report to the host debugger. if so, we |
|
1649 // don't really want to resume yet. let the host debugger set any breakpoints |
|
1650 // in the libraries first. it will call resume again once it's done. |
|
1651 |
|
1652 // since we never mark it as suspended, we'll actually get here when the host |
|
1653 // debugger calls resume the second time. we really don't want to mark it as |
|
1654 // suspended because then the host debugger will try to draw the thread window |
|
1655 TBool found = EFalse; |
|
1656 for (TInt i=0; i<iDebugProcessList.Count(); i++) |
|
1657 { |
|
1658 if (iDebugProcessList[i]->ProcessId() == processId) |
|
1659 { |
|
1660 found = ETrue; |
|
1661 // if we're already marked it as ready, just resume and return |
|
1662 if (iDebugProcessList[i]->iReadyForLibraryLoadNotification) |
|
1663 { |
|
1664 User::LeaveIfError(iKernelDriver.ResumeThread(threadId)); |
|
1665 iFramingLayer->RespondOkL(KNullDesC8); |
|
1666 return; |
|
1667 } |
|
1668 |
|
1669 iDebugProcessList[i]->iReadyForLibraryLoadNotification = ETrue; |
|
1670 break; |
|
1671 } |
|
1672 } |
|
1673 // For RUN mode, we created the process but we didn't put it into the list |
|
1674 // therefore we do not want to notify the host debugger about static libraries |
|
1675 // so just resume and return (see DoCreateExeL) |
|
1676 // The host debugger will soon disconnect in this mode |
|
1677 if (!found) |
|
1678 { |
|
1679 User::LeaveIfError(iKernelDriver.ResumeThread(threadId)); |
|
1680 iFramingLayer->RespondOkL(KNullDesC8); |
|
1681 return; |
|
1682 } |
|
1683 |
|
1684 // the process has been created and the host debugger is listening for messages |
|
1685 // see if there are any statically linked libraries for this process. if so, let |
|
1686 // the host debugger know about them now. note that the host debugger will send |
|
1687 // another resume command once it's handled the static libraries. if there are |
|
1688 // not static libraries for this process, we really do need to resume the thread. |
|
1689 |
|
1690 TInt err = KErrNone; |
|
1691 TInt i = 0; |
|
1692 for (i=0; KErrNone==err; i++) |
|
1693 { |
|
1694 SEventInfo info; |
|
1695 info.iProcessId = processId; |
|
1696 info.iThreadId = threadId; |
|
1697 err = iKernelDriver.GetStaticLibraryInfo(i, info); |
|
1698 |
|
1699 if (KErrNone == err) |
|
1700 { |
|
1701 DoNotifyLibraryLoadedL(info.iFileName, info.iProcessId, 0xFFFFFFFF, info.iCodeAddress, info.iDataAddress); |
|
1702 } |
|
1703 //else if (0 == i) |
|
1704 //{ |
|
1705 // there are no static libraries for this process |
|
1706 //User::LeaveIfError(iKernelDriver.ResumeThread(threadId)); |
|
1707 //} |
|
1708 } |
|
1709 //Always resume the thread instead of asking the host debugger to resume when sending the last static library notification. |
|
1710 User::LeaveIfError(iKernelDriver.ResumeThread(threadId)); |
|
1711 iFramingLayer->RespondOkL(KNullDesC8); |
|
1712 } |
|
1713 } |
|
1714 |
|
1715 // |
|
1716 // CTrkDispatchLayer::DoStepL |
|
1717 // |
|
1718 // Execute one instruction in a thread |
|
1719 // |
|
1720 void CTrkDispatchLayer::DoStepL() |
|
1721 { |
|
1722 // make sure we're connected |
|
1723 if (!iIsConnected) |
|
1724 { |
|
1725 User::Leave(KErrGeneral); |
|
1726 } |
|
1727 |
|
1728 // make sure we got here from DispatchMsgL |
|
1729 TUint8 command = 0; |
|
1730 GetDataFromBufferL(&command, 1); |
|
1731 |
|
1732 if (kDSStep != command) |
|
1733 User::Leave(kDSReplyError); |
|
1734 |
|
1735 // get the options |
|
1736 TUint8 options = 0; |
|
1737 GetDataFromBufferL(&options, 1); |
|
1738 |
|
1739 // we only support stepping out of a range of instructions |
|
1740 if ((kDSStepIntoRange != options) && (kDSStepOverRange != options)) |
|
1741 { |
|
1742 User::Leave(kDSReplyUnsupportedOptionError); |
|
1743 } |
|
1744 |
|
1745 // get the range start address |
|
1746 TUint32 startAddress = 0; |
|
1747 GetDataFromBufferL(&startAddress, 4); |
|
1748 |
|
1749 // get the range stop address |
|
1750 TUint32 stopAddress = 0; |
|
1751 GetDataFromBufferL(&stopAddress, 4); |
|
1752 |
|
1753 // get the process id |
|
1754 TUint32 processId = 0; |
|
1755 GetDataFromBufferL(&processId, 4); |
|
1756 |
|
1757 // get the thread id |
|
1758 TUint32 threadId = 0; |
|
1759 GetDataFromBufferL(&threadId, 4); |
|
1760 |
|
1761 User::LeaveIfError(iKernelDriver.StepRange(threadId, startAddress, stopAddress, (kDSStepIntoRange == options))); |
|
1762 |
|
1763 iFramingLayer->RespondOkL(KNullDesC8); |
|
1764 } |
|
1765 |
|
1766 // |
|
1767 // CTrkDispatchLayer::DoStopL |
|
1768 // |
|
1769 // Stop the execution of a thread |
|
1770 // |
|
1771 void CTrkDispatchLayer::DoStopL() |
|
1772 { |
|
1773 // make sure we're connected |
|
1774 if (!iIsConnected) |
|
1775 { |
|
1776 User::Leave(KErrGeneral); |
|
1777 } |
|
1778 |
|
1779 // make sure we got here from DispatchMsgL |
|
1780 TUint8 command = 0; |
|
1781 GetDataFromBufferL(&command, 1); |
|
1782 |
|
1783 if (kDSStop != command) |
|
1784 User::Leave(kDSReplyError); |
|
1785 |
|
1786 // get the options |
|
1787 TUint8 options = 0; |
|
1788 GetDataFromBufferL(&options, 1); |
|
1789 |
|
1790 TUint32 processId = 0; |
|
1791 TUint32 threadId = 0; |
|
1792 |
|
1793 switch(options) |
|
1794 { |
|
1795 case kDSStopThread: |
|
1796 { |
|
1797 // get the process id |
|
1798 GetDataFromBufferL(&processId, 4); |
|
1799 |
|
1800 // get the thread id |
|
1801 GetDataFromBufferL(&threadId, 4); |
|
1802 |
|
1803 User::LeaveIfError(iKernelDriver.SuspendThread(threadId)); |
|
1804 |
|
1805 break; |
|
1806 } |
|
1807 case kDSStopSystem: |
|
1808 case kDSStopProcess: |
|
1809 default: |
|
1810 { |
|
1811 User::Leave(kDSReplyUnsupportedOptionError); |
|
1812 break; |
|
1813 } |
|
1814 } |
|
1815 |
|
1816 iFramingLayer->RespondOkL(KNullDesC8); |
|
1817 |
|
1818 TBuf8<4> currentPC; |
|
1819 |
|
1820 User::LeaveIfError(iKernelDriver.ReadRegisters(threadId, 15, 15, currentPC)); |
|
1821 |
|
1822 DoNotifyStoppedL(processId, threadId, *(TUint32 *)currentPC.Ptr(), KNullDesC8); |
|
1823 } |
|
1824 |
|
1825 // |
|
1826 // CTrkDispatchLayer::DoSetBreakL |
|
1827 // |
|
1828 // Set a breakpoint |
|
1829 // |
|
1830 void CTrkDispatchLayer::DoSetBreakL() |
|
1831 { |
|
1832 // make sure we're connected |
|
1833 if (!iIsConnected) |
|
1834 { |
|
1835 User::Leave(KErrGeneral); |
|
1836 } |
|
1837 |
|
1838 // make sure we got here from DispatchMsgL |
|
1839 TUint8 command = 0; |
|
1840 GetDataFromBufferL(&command, 1); |
|
1841 |
|
1842 if (kDSSetBreak != command) |
|
1843 User::Leave(kDSReplyError); |
|
1844 |
|
1845 // get the options - unused |
|
1846 TUint8 options = 0; |
|
1847 GetDataFromBufferL(&options, 1); |
|
1848 |
|
1849 // get the mode |
|
1850 TUint8 thumbMode = 0; |
|
1851 GetDataFromBufferL(&thumbMode, 1); |
|
1852 |
|
1853 // get the address |
|
1854 TUint32 address = 0; |
|
1855 GetDataFromBufferL(&address, 4); |
|
1856 |
|
1857 // get the length |
|
1858 TUint32 length = 0; |
|
1859 GetDataFromBufferL(&length, 4); |
|
1860 |
|
1861 // get the count |
|
1862 TUint32 count = 0; |
|
1863 GetDataFromBufferL(&count, 4); |
|
1864 |
|
1865 // get the process id |
|
1866 TUint32 processId = 0; |
|
1867 GetDataFromBufferL(&processId, 4); |
|
1868 |
|
1869 // get the thread id |
|
1870 TUint32 threadId = 0; |
|
1871 GetDataFromBufferL(&threadId, 4); |
|
1872 |
|
1873 TInt32 breakId = 0; |
|
1874 User::LeaveIfError(iKernelDriver.SetBreak(processId, threadId, address, thumbMode, breakId)); |
|
1875 |
|
1876 // return the id of this breakpoint to the host debugger |
|
1877 AddToReplyBufferL((TUint32)breakId, true); |
|
1878 |
|
1879 RespondOkL(); |
|
1880 } |
|
1881 |
|
1882 // |
|
1883 // CTrkDispatchLayer::DoClearBreakL |
|
1884 // |
|
1885 // Clear a breakpoint |
|
1886 // |
|
1887 void CTrkDispatchLayer::DoClearBreakL() |
|
1888 { |
|
1889 // make sure we're connected |
|
1890 if (!iIsConnected) |
|
1891 { |
|
1892 User::Leave(KErrGeneral); |
|
1893 } |
|
1894 |
|
1895 // make sure we got here from DispatchMsgL |
|
1896 TUint8 command = 0; |
|
1897 GetDataFromBufferL(&command, 1); |
|
1898 |
|
1899 if (kDSClearBreak != command) |
|
1900 User::Leave(kDSReplyError); |
|
1901 |
|
1902 // get the breakpoint id |
|
1903 TUint32 breakId = 0; |
|
1904 GetDataFromBufferL(&breakId, 4); |
|
1905 |
|
1906 User::LeaveIfError(iKernelDriver.ClearBreak(breakId)); |
|
1907 |
|
1908 iFramingLayer->RespondOkL(KNullDesC8); |
|
1909 } |
|
1910 |
|
1911 // |
|
1912 // CTrkDispatchLayer::DoModifyBreakThreadL |
|
1913 // |
|
1914 // Change the thread(s) that a breakpoint is associated with |
|
1915 // |
|
1916 void CTrkDispatchLayer::DoModifyBreakThreadL() |
|
1917 { |
|
1918 // make sure we're connected |
|
1919 if (!iIsConnected) |
|
1920 { |
|
1921 User::Leave(KErrGeneral); |
|
1922 } |
|
1923 |
|
1924 // make sure we got here from DispatchMsgL |
|
1925 TUint8 command = 0; |
|
1926 GetDataFromBufferL(&command, 1); |
|
1927 |
|
1928 if (kDSModifyBreakThread != command) |
|
1929 User::Leave(kDSReplyError); |
|
1930 |
|
1931 // get the breakpoint id |
|
1932 TUint32 breakId = 0; |
|
1933 GetDataFromBufferL(&breakId, 4); |
|
1934 |
|
1935 // get the thread id |
|
1936 TUint32 threadId = 0; |
|
1937 GetDataFromBufferL(&threadId, 4); |
|
1938 |
|
1939 User::LeaveIfError(iKernelDriver.ChangeBreakThread(threadId, breakId)); |
|
1940 |
|
1941 iFramingLayer->RespondOkL(KNullDesC8); |
|
1942 } |
|
1943 |
|
1944 // |
|
1945 // CTrkDispatchLayer::DoCreateItemL |
|
1946 // |
|
1947 // Create a new OS item on the target device |
|
1948 // |
|
1949 void CTrkDispatchLayer::DoCreateItemL() |
|
1950 { |
|
1951 // make sure we're connected |
|
1952 if (!iIsConnected) |
|
1953 { |
|
1954 User::Leave(KErrGeneral); |
|
1955 } |
|
1956 |
|
1957 // make sure we got here from DispatchMsgL |
|
1958 TUint8 command = 0; |
|
1959 GetDataFromBufferL(&command, 1); |
|
1960 |
|
1961 if (kDSOSCreateItem != command) |
|
1962 User::Leave(kDSReplyError); |
|
1963 |
|
1964 // get the item type |
|
1965 TUint16 type = 0; |
|
1966 GetDataFromBufferL(&type, 2); |
|
1967 |
|
1968 switch(type) |
|
1969 { |
|
1970 case kDSOSProcessItem: |
|
1971 { |
|
1972 DoCreateProcessL(); |
|
1973 break; |
|
1974 } |
|
1975 case kDSOSProcRunItem: |
|
1976 { |
|
1977 DoCreateProcessL(ETrue); |
|
1978 break; |
|
1979 } |
|
1980 case kDSOSProcAttachItem: |
|
1981 { |
|
1982 DoAttachProcessL(kDSOSProcAttachItem); |
|
1983 break; |
|
1984 } |
|
1985 case kDSOSProcAttach2Item: |
|
1986 { |
|
1987 DoAttachProcessL(kDSOSProcAttach2Item); |
|
1988 break; |
|
1989 } |
|
1990 case kDSOSProcAttach3Item: |
|
1991 { |
|
1992 DoAttachProcessL(kDSOSProcAttach3Item); |
|
1993 break; |
|
1994 } |
|
1995 case kDSOSThreadItem: |
|
1996 case kDSOSDLLItem: |
|
1997 case kDSOSAppItem: |
|
1998 case kDSOSMemBlockItem: |
|
1999 case kDSOSThreadAttachItem: |
|
2000 default: |
|
2001 { |
|
2002 User::Leave(kDSReplyUnsupportedOptionError); |
|
2003 break; |
|
2004 } |
|
2005 } |
|
2006 } |
|
2007 |
|
2008 // |
|
2009 // CTrkDispatchLayer::DoDeleteItemL |
|
2010 // |
|
2011 // Delete an OS item from the target device |
|
2012 // |
|
2013 void CTrkDispatchLayer::DoDeleteItemL() |
|
2014 { |
|
2015 // make sure we're connected |
|
2016 if (!iIsConnected) |
|
2017 { |
|
2018 User::Leave(KErrGeneral); |
|
2019 } |
|
2020 |
|
2021 // make sure we got here from DispatchMsgL |
|
2022 TUint8 command = 0; |
|
2023 GetDataFromBufferL(&command, 1); |
|
2024 |
|
2025 if (kDSOSDeleteItem != command) |
|
2026 User::Leave(kDSReplyError); |
|
2027 |
|
2028 // get the item type |
|
2029 TUint16 type = 0; |
|
2030 GetDataFromBufferL(&type, 2); |
|
2031 |
|
2032 switch(type) |
|
2033 { |
|
2034 case kDSOSProcessItem: |
|
2035 { |
|
2036 DoKillProcessL(); |
|
2037 break; |
|
2038 } |
|
2039 case kDSOSProcAttachItem: |
|
2040 { |
|
2041 DoDetachProcessL(); |
|
2042 break; |
|
2043 } |
|
2044 case kDSOSThreadItem: |
|
2045 case kDSOSDLLItem: |
|
2046 case kDSOSAppItem: |
|
2047 case kDSOSMemBlockItem: |
|
2048 case kDSOSThreadAttachItem: |
|
2049 default: |
|
2050 { |
|
2051 User::Leave(kDSReplyUnsupportedOptionError); |
|
2052 break; |
|
2053 } |
|
2054 } |
|
2055 } |
|
2056 |
|
2057 // |
|
2058 // CTrkDispatchLayer::DoReadInfoL |
|
2059 // |
|
2060 // Read OS information from the target device |
|
2061 // |
|
2062 void CTrkDispatchLayer::DoReadInfoL() |
|
2063 { |
|
2064 // make sure we're connected |
|
2065 if (!iIsConnected) |
|
2066 { |
|
2067 User::Leave(KErrGeneral); |
|
2068 } |
|
2069 |
|
2070 // make sure we got here from DispatchMsgL |
|
2071 TUint8 command = 0; |
|
2072 GetDataFromBufferL(&command, 1); |
|
2073 |
|
2074 if (kDSOSReadInfo != command) |
|
2075 User::Leave(kDSReplyError); |
|
2076 |
|
2077 // get the type of info requested |
|
2078 TUint16 type = 0; |
|
2079 GetDataFromBufferL(&type, 2); |
|
2080 |
|
2081 // get the start index |
|
2082 TUint32 index = 0; |
|
2083 GetDataFromBufferL(&index, 4); |
|
2084 |
|
2085 switch(type) |
|
2086 { |
|
2087 case kDSOSProcessList: |
|
2088 { |
|
2089 DoReadProcessListL(index); |
|
2090 break; |
|
2091 } |
|
2092 case kDSOSThreadList: |
|
2093 { |
|
2094 DoReadThreadListL(index); |
|
2095 break; |
|
2096 } |
|
2097 case kDSOSDLLInfo: |
|
2098 { |
|
2099 TUint16 nameLength = 0; |
|
2100 GetDataFromBufferL(&nameLength, 2); |
|
2101 |
|
2102 // make sure the length of the message is correct |
|
2103 if (iInputBuffer->Length() != nameLength) |
|
2104 User::Leave(kDSReplyPacketSizeError); |
|
2105 |
|
2106 TBuf8<KMaxFileName> fileName; |
|
2107 fileName.Copy(*iInputBuffer); |
|
2108 fileName.ZeroTerminate(); |
|
2109 |
|
2110 DoReadLibraryInfoL(fileName); |
|
2111 break; |
|
2112 } |
|
2113 case kDSOSProcessInfo: |
|
2114 { |
|
2115 TUint32 uid3 = 0; |
|
2116 GetDataFromBufferL(&uid3, 4); |
|
2117 TUint16 nameLength = 0; |
|
2118 GetDataFromBufferL(&nameLength, 2); |
|
2119 |
|
2120 // make sure the length of the message is correct |
|
2121 if (iInputBuffer->Length() != nameLength) |
|
2122 User::Leave(kDSReplyPacketSizeError); |
|
2123 |
|
2124 TBuf8<KMaxFileName> fileName; |
|
2125 fileName.Copy(*iInputBuffer); |
|
2126 fileName.ZeroTerminate(); |
|
2127 |
|
2128 DoReadProcessInfoL(uid3, fileName); |
|
2129 break; |
|
2130 } |
|
2131 case kDSOSProcessState: |
|
2132 case kDSOSThreadState: |
|
2133 case kDSOSDLLList: |
|
2134 case kDSOSDLLState: |
|
2135 default: |
|
2136 { |
|
2137 User::Leave(kDSReplyUnsupportedOptionError); |
|
2138 break; |
|
2139 } |
|
2140 } |
|
2141 } |
|
2142 |
|
2143 // |
|
2144 // CTrkDispatchLayer::DoWriteInfoL |
|
2145 // |
|
2146 // Set options for the Trk |
|
2147 // |
|
2148 void CTrkDispatchLayer::DoWriteInfoL() |
|
2149 { |
|
2150 // make sure we got here from DispatchMsgL |
|
2151 TUint8 command = 0; |
|
2152 GetDataFromBufferL(&command, 1); |
|
2153 |
|
2154 if (kDSOSWriteInfo != command) |
|
2155 User::Leave(kDSReplyError); |
|
2156 |
|
2157 // get the type of info requested |
|
2158 TUint16 type = 0; |
|
2159 GetDataFromBufferL(&type, 2); |
|
2160 |
|
2161 // get the start index |
|
2162 TUint32 index = 0; |
|
2163 GetDataFromBufferL(&index, 4); |
|
2164 |
|
2165 // no options supported yet. might add something for auto-target libraries later |
|
2166 User::Leave(kDSReplyUnsupportedOptionError); |
|
2167 } |
|
2168 |
|
2169 // |
|
2170 // CTrkDispatchLayer::DoOpenFileL |
|
2171 // |
|
2172 // Open or create a file on the target |
|
2173 // |
|
2174 void CTrkDispatchLayer::DoOpenFileL() |
|
2175 { |
|
2176 // make sure we got here from DispatchMsgL |
|
2177 TUint8 command = 0; |
|
2178 GetDataFromBufferL(&command, 1); |
|
2179 |
|
2180 if (kDSOSOpenFile != command) |
|
2181 User::Leave(kDSReplyError); |
|
2182 |
|
2183 // get the file mode(s) |
|
2184 TUint8 modes = 0; |
|
2185 GetDataFromBufferL(&modes, 1); |
|
2186 |
|
2187 if ((modes & kDSFileOpenAppend) || (modes & kDSFileOpenCreate)) |
|
2188 modes |= kDSFileOpenWrite; |
|
2189 |
|
2190 TUint16 nameLength = 0; |
|
2191 GetDataFromBufferL(&nameLength, 2); |
|
2192 |
|
2193 // make sure the length of the message is correct |
|
2194 if (iInputBuffer->Length() != nameLength) |
|
2195 User::Leave(kDSReplyPacketSizeError); |
|
2196 |
|
2197 TBuf<KMaxPath> fullpath; |
|
2198 fullpath.Copy(*iInputBuffer); |
|
2199 fullpath.ZeroTerminate(); |
|
2200 |
|
2201 TUint mode = EFileShareExclusive; |
|
2202 |
|
2203 // get the file mode(s) |
|
2204 if (modes & kDSFileOpenRead) |
|
2205 mode |= EFileRead; |
|
2206 |
|
2207 if (modes & kDSFileOpenWrite) |
|
2208 mode |= EFileWrite; |
|
2209 |
|
2210 if (modes & kDSFileOpenAppend) |
|
2211 mode |= EFileWrite; |
|
2212 |
|
2213 if (modes & kDSFileOpenCreate) |
|
2214 mode |= EFileWrite; |
|
2215 |
|
2216 |
|
2217 //for getting the modification date |
|
2218 TTime time; |
|
2219 |
|
2220 OpenFileL(fullpath, mode, time); |
|
2221 |
|
2222 TDateTime dateTime = time.DateTime(); |
|
2223 |
|
2224 TDateTimeConverter winTime(dateTime); |
|
2225 |
|
2226 TUint32 timestamp = winTime.GetWinTimeDate(); |
|
2227 |
|
2228 TUint32 handle = 1; |
|
2229 TUint8 err = 0; |
|
2230 |
|
2231 AddToReplyBufferL(err, true); |
|
2232 AddToReplyBufferL(handle); |
|
2233 AddToReplyBufferL(timestamp); |
|
2234 |
|
2235 RespondOkL(); |
|
2236 } |
|
2237 |
|
2238 // |
|
2239 // CTrkDispatchLayer::OpenFileL |
|
2240 // |
|
2241 // Open a file on the target, if plat security is enabled, uses TrkTcbServer to open the file. |
|
2242 // |
|
2243 void CTrkDispatchLayer::OpenFileL(const TDesC& aFullPath, TUint aMode, TTime& aTime) |
|
2244 { |
|
2245 |
|
2246 #ifdef __OEM_TRK__ |
|
2247 //Check to see if TCB capability is enforced, if so, connect to the tcb server as well. |
|
2248 if (!iUseTcbServer && PlatSec::IsCapabilityEnforced(ECapabilityTCB)) |
|
2249 { |
|
2250 if (!iTrkTcbSession.Connect()) |
|
2251 { |
|
2252 iUseTcbServer = ETrue; |
|
2253 } |
|
2254 } |
|
2255 |
|
2256 if (iUseTcbServer) |
|
2257 { |
|
2258 User::LeaveIfError(iTrkTcbSession.OpenFile(aFullPath, aMode, aTime)); |
|
2259 } |
|
2260 else |
|
2261 #endif |
|
2262 { |
|
2263 #ifndef __OEM_TRK__ |
|
2264 if (IsRestrictedFolder(aFullPath)) |
|
2265 User::Leave(KErrAccessDenied); |
|
2266 #endif |
|
2267 // connect to the file server |
|
2268 User::LeaveIfError(iFs.Connect()); |
|
2269 |
|
2270 TInt error = iFs.MkDirAll(aFullPath); |
|
2271 |
|
2272 if ((KErrNone != error) && (KErrAlreadyExists != error)) |
|
2273 { |
|
2274 iFs.Close(); |
|
2275 User::Leave(error); |
|
2276 } |
|
2277 |
|
2278 error = iFile.Open(iFs, aFullPath, aMode); |
|
2279 |
|
2280 if (KErrNone != error) |
|
2281 User::LeaveIfError(iFile.Replace(iFs, aFullPath, aMode)); |
|
2282 |
|
2283 User::LeaveIfError(iFile.Modified(aTime)); |
|
2284 iFileState = EFileOpened; |
|
2285 } |
|
2286 } |
|
2287 |
|
2288 // |
|
2289 // CTrkDispatchLayer::DoReadFileL |
|
2290 // |
|
2291 // Read data from a file on the target |
|
2292 // |
|
2293 void CTrkDispatchLayer::DoReadFileL() |
|
2294 { |
|
2295 // make sure we got here from DispatchMsgL |
|
2296 TUint8 command = 0; |
|
2297 GetDataFromBufferL(&command, 1); |
|
2298 |
|
2299 if (kDSOSReadFile != command) |
|
2300 User::Leave(kDSReplyError); |
|
2301 |
|
2302 // make sure the length of the message is correct |
|
2303 if (iInputBuffer->Length() != 6) |
|
2304 User::Leave(kDSReplyPacketSizeError); |
|
2305 |
|
2306 // remove the handle |
|
2307 iInputBuffer->Des().Delete(0, 4); |
|
2308 |
|
2309 // get the length |
|
2310 TUint8 err = 0; |
|
2311 TUint16 length = 0; |
|
2312 GetDataFromBufferL(&length, 2); |
|
2313 |
|
2314 // allocate a buffer large enough for the data |
|
2315 HBufC8 *buffer = HBufC8::NewLC(length); |
|
2316 TPtr8 ptr(buffer->Des()); |
|
2317 |
|
2318 // CleanupStack::PushL(buffer); |
|
2319 |
|
2320 TInt error = ReadFileL(length, ptr); |
|
2321 if (KErrNone != error) |
|
2322 { |
|
2323 CleanupStack::PopAndDestroy(buffer); |
|
2324 User::Leave(error); |
|
2325 } |
|
2326 |
|
2327 length = buffer->Length(); |
|
2328 |
|
2329 AddToReplyBufferL(err, true); |
|
2330 AddToReplyBufferL(length); |
|
2331 // AddToReplyBufferL(buffer[0], length); |
|
2332 AddToReplyBufferL(ptr); |
|
2333 RespondOkL(); |
|
2334 |
|
2335 CleanupStack::PopAndDestroy(buffer); |
|
2336 } |
|
2337 |
|
2338 // |
|
2339 // CTrkDispatchLayer::ReadFileL |
|
2340 // |
|
2341 // Reads data from a file on the target |
|
2342 // |
|
2343 TInt CTrkDispatchLayer::ReadFileL(TUint16 aLength, TPtr8& aData) |
|
2344 { |
|
2345 TInt error = KErrNone; |
|
2346 |
|
2347 #ifdef __OEM_TRK__ |
|
2348 if (iUseTcbServer) |
|
2349 { |
|
2350 User::LeaveIfError(iTrkTcbSession.ReadFile(aLength, aData)); |
|
2351 } |
|
2352 else |
|
2353 #endif |
|
2354 { |
|
2355 iFileState = EFileReading; |
|
2356 error = iFile.Read(aData); |
|
2357 } |
|
2358 return error; |
|
2359 } |
|
2360 |
|
2361 // |
|
2362 // CTrkDispatchLayer::DoWriteFileL |
|
2363 // |
|
2364 // Write data to a file on the target |
|
2365 // |
|
2366 void CTrkDispatchLayer::DoWriteFileL() |
|
2367 { |
|
2368 // make sure we got here from DispatchMsgL |
|
2369 TUint8 command = 0; |
|
2370 GetDataFromBufferL(&command, 1); |
|
2371 |
|
2372 if (kDSOSWriteFile != command) |
|
2373 User::Leave(kDSReplyError); |
|
2374 |
|
2375 // get the length |
|
2376 TUint32 handle = 0; |
|
2377 GetDataFromBufferL(&handle, 4); |
|
2378 |
|
2379 if (handle != 1) |
|
2380 User::Leave(kDSReplyParameterError); |
|
2381 |
|
2382 // get the length |
|
2383 TUint8 err = 0; |
|
2384 TUint16 length = 0; |
|
2385 GetDataFromBufferL(&length, 2); |
|
2386 |
|
2387 // make sure the length of the message is correct |
|
2388 if (iInputBuffer->Length() != length) |
|
2389 User::Leave(kDSReplyPacketSizeError); |
|
2390 |
|
2391 WriteFileL(*iInputBuffer); |
|
2392 |
|
2393 length = iInputBuffer->Length(); |
|
2394 |
|
2395 AddToReplyBufferL(err, true); |
|
2396 AddToReplyBufferL(length); |
|
2397 RespondOkL(); |
|
2398 } |
|
2399 |
|
2400 // |
|
2401 // CTrkDispatchLayer::WriteFileL |
|
2402 // |
|
2403 // Write data to a file on the target. If plat sec is enabled, uses Trk Tcb Server. |
|
2404 // |
|
2405 void CTrkDispatchLayer::WriteFileL(TDesC8& aData) |
|
2406 { |
|
2407 #ifdef __OEM_TRK__ |
|
2408 if (iUseTcbServer) |
|
2409 { |
|
2410 User::LeaveIfError(iTrkTcbSession.WriteFile(aData)); |
|
2411 } |
|
2412 else |
|
2413 #endif |
|
2414 { |
|
2415 if (iFileState == EFileOpened) |
|
2416 { |
|
2417 iFile.SetSize(0); |
|
2418 iFileState = EFileWriting; |
|
2419 } |
|
2420 User::LeaveIfError(iFile.Write(aData)); |
|
2421 User::LeaveIfError(iFile.Flush()); |
|
2422 } |
|
2423 } |
|
2424 |
|
2425 // |
|
2426 // CTrkDispatchLayer::DoPositionFileL |
|
2427 // |
|
2428 // Change the current file position of a file on the target |
|
2429 // |
|
2430 void CTrkDispatchLayer::DoPositionFileL() |
|
2431 { |
|
2432 // make sure we got here from DispatchMsgL |
|
2433 TUint8 command = 0; |
|
2434 GetDataFromBufferL(&command, 1); |
|
2435 |
|
2436 if (kDSOSPositionFile != command) |
|
2437 User::Leave(kDSReplyError); |
|
2438 |
|
2439 // make sure the length of the message is correct |
|
2440 if (iInputBuffer->Length() != 9) |
|
2441 User::Leave(kDSReplyPacketSizeError); |
|
2442 |
|
2443 // get the positioning mode |
|
2444 TUint8 mode = 0; |
|
2445 GetDataFromBufferL(&mode, 1); |
|
2446 |
|
2447 // remove the handle |
|
2448 iInputBuffer->Des().Delete(0, 4); |
|
2449 |
|
2450 TUint8 err = 0; |
|
2451 TUint32 offset = 0; |
|
2452 GetDataFromBufferL(&offset, 4); |
|
2453 |
|
2454 TSeek seek; |
|
2455 |
|
2456 // convert mode to native parameter and set the position accordingly |
|
2457 switch(mode) |
|
2458 { |
|
2459 default: |
|
2460 case kDSFileSeekSet: |
|
2461 { |
|
2462 seek = ESeekStart; |
|
2463 break; |
|
2464 } |
|
2465 case kDSFileSeekCur: |
|
2466 { |
|
2467 seek = ESeekCurrent; |
|
2468 break; |
|
2469 } |
|
2470 case kDSFileSeekEnd: |
|
2471 { |
|
2472 seek = ESeekEnd; |
|
2473 break; |
|
2474 } |
|
2475 } |
|
2476 |
|
2477 PositionFileL(seek, (TInt &)offset); |
|
2478 |
|
2479 AddToReplyBufferL(err, true); |
|
2480 |
|
2481 RespondOkL(); |
|
2482 } |
|
2483 |
|
2484 // |
|
2485 // CTrkDispatchLayer::PositionFileL |
|
2486 // |
|
2487 // Change the current file position of a file on the target. If plat sec is enabled, |
|
2488 // uses Trk Tcb Server. |
|
2489 // |
|
2490 void CTrkDispatchLayer::PositionFileL(TSeek aSeek, TInt& aOffset) |
|
2491 { |
|
2492 #ifdef __OEM_TRK__ |
|
2493 if (iUseTcbServer) |
|
2494 { |
|
2495 User::LeaveIfError(iTrkTcbSession.PositionFile(aSeek, aOffset)); |
|
2496 } |
|
2497 else |
|
2498 #endif |
|
2499 { |
|
2500 User::LeaveIfError(iFile.Seek(aSeek, aOffset)); |
|
2501 } |
|
2502 } |
|
2503 |
|
2504 |
|
2505 // |
|
2506 // CTrkDispatchLayer::DoCloseFileL |
|
2507 // |
|
2508 // Close a file on the target |
|
2509 // |
|
2510 void CTrkDispatchLayer::DoCloseFileL() |
|
2511 { |
|
2512 // make sure we got here from DispatchMsgL |
|
2513 TUint8 command = 0; |
|
2514 GetDataFromBufferL(&command, 1); |
|
2515 |
|
2516 if (kDSOSCloseFile != command) |
|
2517 User::Leave(kDSReplyError); |
|
2518 |
|
2519 // make sure the length of the message is correct |
|
2520 if (iInputBuffer->Length() != 8) |
|
2521 User::Leave(kDSReplyPacketSizeError); |
|
2522 |
|
2523 // remove the handle |
|
2524 iInputBuffer->Des().Delete(0, 4); |
|
2525 |
|
2526 TUint8 err = 0; |
|
2527 TUint32 timestamp = 0; |
|
2528 GetDataFromBufferL(×tamp, 4); |
|
2529 |
|
2530 TDateTimeConverter epocTime(timestamp); |
|
2531 |
|
2532 CloseFileL(epocTime.GetEpocTimeDate()); |
|
2533 |
|
2534 AddToReplyBufferL(err, true); |
|
2535 |
|
2536 RespondOkL(); |
|
2537 } |
|
2538 |
|
2539 // |
|
2540 // CTrkDispatchLayer::CloseFileL |
|
2541 // |
|
2542 // Close a file on the target. If plat sec is enabled, uses Trk Tcb Server. |
|
2543 // |
|
2544 void CTrkDispatchLayer::CloseFileL(const TTime& aModifiedTime) |
|
2545 { |
|
2546 #ifdef __OEM_TRK__ |
|
2547 if (iUseTcbServer) |
|
2548 { |
|
2549 User::LeaveIfError(iTrkTcbSession.CloseFile(aModifiedTime)); |
|
2550 } |
|
2551 else |
|
2552 #endif |
|
2553 { |
|
2554 User::LeaveIfError(iFile.SetModified(aModifiedTime)); |
|
2555 User::LeaveIfError(iFile.Flush()); |
|
2556 |
|
2557 iFile.Close(); |
|
2558 iFs.Close(); |
|
2559 iFileState = EFileClosed; |
|
2560 } |
|
2561 } |
|
2562 |
|
2563 // |
|
2564 // CTrkDispatchLayer::DoInstallFileL |
|
2565 // |
|
2566 // Install the application, supplied as a SIS file. |
|
2567 // |
|
2568 void CTrkDispatchLayer::DoInstallFileL() |
|
2569 { |
|
2570 // make sure we're connected |
|
2571 if (!iIsConnected) |
|
2572 { |
|
2573 User::Leave(KErrGeneral); |
|
2574 } |
|
2575 |
|
2576 #ifndef __TEXT_SHELL__ |
|
2577 // make sure we got here from DispatchMsgL |
|
2578 TUint8 command = 0; |
|
2579 GetDataFromBufferL(&command, 1); |
|
2580 |
|
2581 if (kDSOSInstallFile != command) |
|
2582 User::Leave(kDSReplyError); |
|
2583 |
|
2584 // get the installation drive |
|
2585 TUint8 drive = 'C'; |
|
2586 GetDataFromBufferL(&drive, 1); |
|
2587 |
|
2588 TChar installDrive(drive); |
|
2589 |
|
2590 TUint16 nameLength = 0; |
|
2591 GetDataFromBufferL(&nameLength, 2); |
|
2592 |
|
2593 // make sure the length of the message is correct |
|
2594 if (iInputBuffer->Length() != nameLength) |
|
2595 User::Leave(kDSReplyPacketSizeError); |
|
2596 |
|
2597 TBuf<KMaxPath> fullpath; |
|
2598 fullpath.Copy(*iInputBuffer); |
|
2599 fullpath.ZeroTerminate(); |
|
2600 |
|
2601 TUint8 err = 0; |
|
2602 // Temporarily disable the lib loaded event before launching the SW Installer. |
|
2603 // This is necessary when launching the SIS installer since launching the |
|
2604 // installer causes several libraries to be loaded. The driver suspends the |
|
2605 // thread thats loaded the library. This suspension might potentially cause |
|
2606 // a deadlock as the event handling active object will never get a chance to |
|
2607 // run as the Install function below blocks until the installation is completed. |
|
2608 User::LeaveIfError(iKernelDriver.DisableLibLoadedEvent()); |
|
2609 |
|
2610 // now launch the installer |
|
2611 User::LeaveIfError(CTrkSwInstall::SilentInstallL(fullpath, installDrive)); |
|
2612 |
|
2613 // now enable the lib loaded event |
|
2614 iKernelDriver.EnableLibLoadedEvent(); |
|
2615 |
|
2616 AddToReplyBufferL(err, true); |
|
2617 RespondOkL(); |
|
2618 #else |
|
2619 User::LeaveIfError(-1); |
|
2620 #endif |
|
2621 } |
|
2622 |
|
2623 // |
|
2624 // CTrkDispatchLayer::DoInstallFileL |
|
2625 // |
|
2626 // Install the application, supplied as a SIS file. |
|
2627 // |
|
2628 void CTrkDispatchLayer::DoInstallFile2L() |
|
2629 { |
|
2630 // make sure we're connected |
|
2631 if (!iIsConnected) |
|
2632 { |
|
2633 User::Leave(KErrGeneral); |
|
2634 } |
|
2635 |
|
2636 #ifndef __TEXT_SHELL__ |
|
2637 // make sure we got here from DispatchMsgL |
|
2638 TUint8 command = 0; |
|
2639 GetDataFromBufferL(&command, 1); |
|
2640 |
|
2641 if (kDSOSInstallFile2 != command) |
|
2642 User::Leave(kDSReplyError); |
|
2643 |
|
2644 TUint16 nameLength = 0; |
|
2645 GetDataFromBufferL(&nameLength, 2); |
|
2646 |
|
2647 // make sure the length of the message is correct |
|
2648 if (iInputBuffer->Length() != nameLength) |
|
2649 User::Leave(kDSReplyPacketSizeError); |
|
2650 |
|
2651 TBuf<KMaxPath> fullpath; |
|
2652 fullpath.Copy(*iInputBuffer); |
|
2653 fullpath.ZeroTerminate(); |
|
2654 |
|
2655 TUint8 err = 0; |
|
2656 // Temporarily disable the lib loaded event before launching the SW Installer. |
|
2657 // This is necessary when launching the SIS installer since launching the |
|
2658 // installer causes several libraries to be loaded. The driver suspends the |
|
2659 // thread thats loaded the library. This suspension might potentially cause |
|
2660 // a deadlock as the event handling active object will never get a chance to |
|
2661 // run as the Install function below blocks until the installation is completed. |
|
2662 User::LeaveIfError(iKernelDriver.DisableLibLoadedEvent()); |
|
2663 |
|
2664 // now launch the installer |
|
2665 User::LeaveIfError(CTrkSwInstall::Install(fullpath)); |
|
2666 |
|
2667 // now enable the lib loaded event |
|
2668 iKernelDriver.EnableLibLoadedEvent(); |
|
2669 |
|
2670 AddToReplyBufferL(err); |
|
2671 RespondOkL(); |
|
2672 #else |
|
2673 User::LeaveIfError(-1); |
|
2674 #endif |
|
2675 } |
|
2676 |
|
2677 |
|
2678 // |
|
2679 // CTrkDispathLayer::DoGetPhoneSWVesionL() |
|
2680 // |
|
2681 // sends the software version of the phone to reply buffer |
|
2682 // |
|
2683 void CTrkDispatchLayer::DoGetPhoneSWVersionL() |
|
2684 { |
|
2685 // make sure we got here from DispatchMsgL |
|
2686 |
|
2687 TUint8 command = 0; |
|
2688 GetDataFromBufferL(&command, 1); |
|
2689 |
|
2690 if (kDSOSPhoneSWVersion != command) |
|
2691 { |
|
2692 User::Leave(kDSReplyError); |
|
2693 } |
|
2694 #ifndef __TEXT_SHELL__ |
|
2695 if (iPhoneVersion.Size()>0 ) |
|
2696 { |
|
2697 TUint16 versionNameLength = iPhoneVersion.Length(); |
|
2698 AddToReplyBufferL(versionNameLength, ETrue); |
|
2699 AddToReplyBufferL(iPhoneVersion); |
|
2700 RespondOkL(); |
|
2701 } |
|
2702 else |
|
2703 #endif |
|
2704 { |
|
2705 User::Leave(KErrGeneral); |
|
2706 } |
|
2707 |
|
2708 } |
|
2709 |
|
2710 |
|
2711 // |
|
2712 //CTrkDispathLayer::DoGetPhoneNameL() |
|
2713 // |
|
2714 //sends the phone model name to the reply buffer |
|
2715 // |
|
2716 void CTrkDispatchLayer::DoGetPhoneNameL() |
|
2717 { |
|
2718 TUint8 command = 0; |
|
2719 GetDataFromBufferL(&command, 1); |
|
2720 |
|
2721 if (kDSOSPhoneName != command) |
|
2722 { |
|
2723 User::Leave(kDSReplyError); |
|
2724 } |
|
2725 |
|
2726 #ifndef __TEXT_SHELL__ |
|
2727 if (iPhoneNameInfoAvailable) |
|
2728 { |
|
2729 TUint16 phoneModelLen = iPhoneModel.Length(); |
|
2730 AddToReplyBufferL(phoneModelLen, true); |
|
2731 AddToReplyBufferL(iPhoneModel); |
|
2732 RespondOkL(); |
|
2733 } |
|
2734 else |
|
2735 #endif |
|
2736 { |
|
2737 User::Leave(KErrGeneral); |
|
2738 } |
|
2739 } |
|
2740 // |
|
2741 //To Update the phone model name |
|
2742 // |
|
2743 //callback function from the CPhoneInfo |
|
2744 // |
|
2745 void CTrkDispatchLayer::UpdatePhoneNameInfo(TDesC16& aPhoneModel) |
|
2746 { |
|
2747 #ifndef __TEXT_SHELL__ |
|
2748 iPhoneModel.Copy(aPhoneModel); |
|
2749 iPhoneNameInfoAvailable = ETrue; |
|
2750 #endif |
|
2751 } |
|
2752 |
|
2753 // |
|
2754 // CTrkDispatchLayer::DoCreateProcessL |
|
2755 // |
|
2756 // Create a new process on the target device |
|
2757 // |
|
2758 void CTrkDispatchLayer::DoCreateProcessL(TBool aRun) |
|
2759 { |
|
2760 // remove the options - currently unused |
|
2761 iInputBuffer->Des().Delete(0, 1); |
|
2762 |
|
2763 // get the length of the data |
|
2764 TUint16 length = 0; |
|
2765 GetDataFromBufferL(&length, 2); |
|
2766 |
|
2767 // make sure the length of the message is correct |
|
2768 if (iInputBuffer->Length() != length) |
|
2769 User::Leave(kDSReplyPacketSizeError); |
|
2770 |
|
2771 // extract the filename and path, command line args, and working directory |
|
2772 TPtrC8 exec8(iInputBuffer->Ptr()); |
|
2773 TPtrC8 args8(exec8.Ptr() + exec8.Length() + 1); |
|
2774 |
|
2775 // convert the filename and args to unicode descriptors |
|
2776 HBufC* exec = HBufC::NewLC(exec8.Length()); |
|
2777 exec->Des().Copy(exec8); |
|
2778 |
|
2779 HBufC* args = HBufC::NewLC(args8.Length()); |
|
2780 args->Des().Copy(args8); |
|
2781 |
|
2782 // open the file and get the type (app, exe, etc.) |
|
2783 RFs fs; |
|
2784 |
|
2785 // connect to the file server |
|
2786 User::LeaveIfError(fs.Connect()); |
|
2787 |
|
2788 TEntry entry; |
|
2789 |
|
2790 User::LeaveIfError(fs.Entry(*exec, entry)); |
|
2791 |
|
2792 fs.Close(); |
|
2793 |
|
2794 TCreateProcessData data; |
|
2795 |
|
2796 switch(entry[0].iUid) |
|
2797 { |
|
2798 case 0x1000007a: |
|
2799 { |
|
2800 // EXE |
|
2801 DoCreateExeL(*exec, *args, data, aRun); |
|
2802 break; |
|
2803 } |
|
2804 default: |
|
2805 User::Leave(KErrGeneral); |
|
2806 } |
|
2807 |
|
2808 CleanupStack::PopAndDestroy(args); |
|
2809 CleanupStack::PopAndDestroy(exec); |
|
2810 |
|
2811 AddToReplyBufferL(data.iProcessId, true); |
|
2812 AddToReplyBufferL(data.iMainThreadId); |
|
2813 if (!aRun) |
|
2814 { |
|
2815 AddToReplyBufferL(data.iCodeAddr); |
|
2816 AddToReplyBufferL(data.iDataAddr); |
|
2817 } |
|
2818 |
|
2819 RespondOkL(); |
|
2820 } |
|
2821 |
|
2822 // |
|
2823 // CTrkDispatchLayer::DoCreateExeL |
|
2824 // |
|
2825 // Create a new executable on the target device |
|
2826 // |
|
2827 void CTrkDispatchLayer::DoCreateExeL(const TDesC& aPath, const TDesC& aArgs, TCreateProcessData& aData, TBool aRun) |
|
2828 { |
|
2829 RProcess process; |
|
2830 User::LeaveIfError(process.Create(aPath, aArgs)); |
|
2831 CleanupClosePushL(process); |
|
2832 |
|
2833 aData.iProcessId = process.Id(); |
|
2834 |
|
2835 HBufC* threadName = HBufC::NewLC(KMaxFullName); |
|
2836 |
|
2837 *threadName = process.Name(); |
|
2838 _LIT(KMainThreadSuffix, "::Main"); |
|
2839 threadName->Des().Append(KMainThreadSuffix); |
|
2840 |
|
2841 // this function should be (indirectly) called when the debuggee |
|
2842 // has been created but not yet resumed. So it should have a main |
|
2843 // thread whose name ends with "::Main", and so the following call |
|
2844 // should not fail. |
|
2845 RThread thread; |
|
2846 User::LeaveIfError(thread.Open(*threadName)); |
|
2847 |
|
2848 aData.iMainThreadId = thread.Id(); |
|
2849 thread.Close(); |
|
2850 |
|
2851 if (!aRun) |
|
2852 { |
|
2853 CDebugProcess *proc = CDebugProcess::NewL(this, aData.iProcessId, aData.iMainThreadId); |
|
2854 iDebugProcessList.Append(proc); |
|
2855 |
|
2856 User::LeaveIfError(iKernelDriver.GetProcessAddresses(aData.iMainThreadId, aData.iCodeAddr, aData.iDataAddr)); |
|
2857 } |
|
2858 |
|
2859 CleanupStack::PopAndDestroy(threadName); |
|
2860 CleanupStack::PopAndDestroy(); // process |
|
2861 } |
|
2862 |
|
2863 // |
|
2864 // CTrkDispatchLayer::DoKillProcessL |
|
2865 // |
|
2866 // Kill an existing process |
|
2867 // |
|
2868 void CTrkDispatchLayer::DoKillProcessL() |
|
2869 { |
|
2870 // get the process id |
|
2871 TUint32 processId = 0; |
|
2872 GetDataFromBufferL(&processId, 4); |
|
2873 |
|
2874 RProcess process; |
|
2875 User::LeaveIfError(process.Open(processId)); |
|
2876 #ifdef EKA2 |
|
2877 process.Kill(KErrNone); |
|
2878 #else |
|
2879 process.Kill(KProcessKilled); |
|
2880 #endif |
|
2881 process.Close(); |
|
2882 |
|
2883 iFramingLayer->RespondOkL(KNullDesC8); |
|
2884 } |
|
2885 |
|
2886 // |
|
2887 // CTrkDispatchLayer::DoAttachProcessL |
|
2888 // |
|
2889 // Create a new process on the target device |
|
2890 // |
|
2891 void CTrkDispatchLayer::DoAttachProcessL(DSOSItemTypes aAttachType) |
|
2892 { |
|
2893 // remove the options - currently unused |
|
2894 iInputBuffer->Des().Delete(0, 1); |
|
2895 |
|
2896 // get the length of the data |
|
2897 TUint32 processId = 0; |
|
2898 GetDataFromBufferL(&processId, 4); |
|
2899 |
|
2900 RProcess process; |
|
2901 User::LeaveIfError(process.Open(processId)); |
|
2902 CleanupClosePushL(process); |
|
2903 |
|
2904 // do not allow attaching to a system, protected, or the MetroTrk process because |
|
2905 // if the user were to stop the wrong thread, the whole system could stop |
|
2906 #ifdef EKA2 |
|
2907 if ((TUint)processId == RProcess().Id()) |
|
2908 #else |
|
2909 if (process.System() || process.Protected() || ((TUint)processId == RProcess().Id())) |
|
2910 #endif |
|
2911 { |
|
2912 User::Leave(kDSReplyUnsupportedOptionError); |
|
2913 } |
|
2914 |
|
2915 TMetroTrkTaskInfo threadInfo(processId); |
|
2916 User::LeaveIfError(iKernelDriver.GetThreadInfo(0, threadInfo)); |
|
2917 |
|
2918 |
|
2919 TUint32 codeAddr; |
|
2920 TUint32 dataAddr; |
|
2921 User::LeaveIfError(iKernelDriver.GetProcessAddresses(threadInfo.iId, codeAddr, dataAddr)); |
|
2922 //this is necessary to get the process died notifications and also any other event for this process |
|
2923 CDebugProcess *proc = CDebugProcess::NewL(this, processId, threadInfo.iId); |
|
2924 // For processes that we are attaching, we need to set this flag to true. |
|
2925 // otherwise library load notifications for this process will be ignored |
|
2926 proc->iReadyForLibraryLoadNotification = ETrue; |
|
2927 iDebugProcessList.Append(proc); |
|
2928 |
|
2929 AddToReplyBufferL(threadInfo.iId, true); |
|
2930 if (aAttachType == kDSOSProcAttach3Item) |
|
2931 { |
|
2932 // now get the UID3 for this process |
|
2933 // and add it to the reply |
|
2934 TMetroTrkProcUidInfo procUidInfo(processId); |
|
2935 User::LeaveIfError(iKernelDriver.GetProcUidInfo(procUidInfo)); |
|
2936 AddToReplyBufferL(procUidInfo.iUid3); |
|
2937 } |
|
2938 if (aAttachType == kDSOSProcAttach3Item || aAttachType == kDSOSProcAttach2Item) |
|
2939 { |
|
2940 AddToReplyBufferL(codeAddr); |
|
2941 AddToReplyBufferL(dataAddr); |
|
2942 |
|
2943 TBuf8<KMaxFullName> procName; |
|
2944 procName.Copy(process.Name()); |
|
2945 TUint16 nameLength = procName.Length(); |
|
2946 |
|
2947 AddToReplyBufferL(nameLength); |
|
2948 AddToReplyBufferL(procName); |
|
2949 } |
|
2950 |
|
2951 CleanupStack::PopAndDestroy(); // process |
|
2952 RespondOkL(); |
|
2953 } |
|
2954 |
|
2955 // |
|
2956 // CTrkDispatchLayer::DoDetachProcessL |
|
2957 // |
|
2958 // To detach the process from the list of processes |
|
2959 // |
|
2960 void CTrkDispatchLayer::DoDetachProcessL() |
|
2961 { |
|
2962 TUint32 processId = 0; |
|
2963 GetDataFromBufferL(&processId, 4); |
|
2964 |
|
2965 RProcess process; |
|
2966 User::LeaveIfError(process.Open(processId)); |
|
2967 |
|
2968 for (TInt i=0 ; i<iDebugProcessList.Count(); i++) |
|
2969 { |
|
2970 if(iDebugProcessList[i]->ProcessId()== processId) |
|
2971 { |
|
2972 SafeDelete(iDebugProcessList[i]); |
|
2973 iDebugProcessList.Remove(i); |
|
2974 } |
|
2975 } |
|
2976 User::LeaveIfError(iKernelDriver.DetachProcess(processId)); |
|
2977 |
|
2978 iFramingLayer->RespondOkL(KNullDesC8); |
|
2979 } |
|
2980 |
|
2981 |
|
2982 // |
|
2983 // CTrkDispatchLayer::DoReadProcessListL |
|
2984 // |
|
2985 // Return a list of the current processes to the host debugger |
|
2986 // |
|
2987 void CTrkDispatchLayer::DoReadProcessListL(TInt32 aIndex) |
|
2988 { |
|
2989 // remove the options - unused |
|
2990 iInputBuffer->Des().Delete(0, 1); |
|
2991 |
|
2992 // remove the filter - unused |
|
2993 iInputBuffer->Des().Delete(0, 4); |
|
2994 |
|
2995 // an index of zero means we start fresh. and index other than zero means |
|
2996 // we were not able to return all of the processes in the last round due to |
|
2997 // message size limitations, so we need to pick up where we left off |
|
2998 if (aIndex == 0) |
|
2999 { |
|
3000 DoReBuildProcessList(); |
|
3001 } |
|
3002 |
|
3003 TInt32 totalCount = iProcessList.Count(); |
|
3004 TInt32 returnedCount = 0; |
|
3005 TInt32 bytesRemaining = MAXMESSAGESIZE_V2 - 30; // minus the framing bytes |
|
3006 TInt32 restOfMsgSize = sizeof(TUint32) // process id |
|
3007 + sizeof(TUint32) // priority |
|
3008 + sizeof(TUint8); // NULL character |
|
3009 |
|
3010 for (TInt32 i=aIndex; i<totalCount; i++) |
|
3011 { |
|
3012 // make sure there is enough room left in the message |
|
3013 if (bytesRemaining >= (iProcessList[i].iName.Length() + restOfMsgSize)) |
|
3014 { |
|
3015 returnedCount++; |
|
3016 bytesRemaining -= (iProcessList[i].iName.Length() + restOfMsgSize); |
|
3017 } |
|
3018 else |
|
3019 break; |
|
3020 } |
|
3021 |
|
3022 // add values for returnedCount and totalCount |
|
3023 AddToReplyBufferL((TUint32)returnedCount, true); |
|
3024 AddToReplyBufferL((TUint32)totalCount); |
|
3025 |
|
3026 for (TInt32 i=aIndex; i<(aIndex + returnedCount); i++) |
|
3027 { |
|
3028 // add this process info to the buffer |
|
3029 AddToReplyBufferL(iProcessList[i].iId); |
|
3030 AddToReplyBufferL(iProcessList[i].iPriority); |
|
3031 AddToReplyBufferL(iProcessList[i].iName); |
|
3032 |
|
3033 // host expects the name to be a null terminated string |
|
3034 AddToReplyBufferL((TUint8)0); |
|
3035 } |
|
3036 |
|
3037 RespondOkL(); |
|
3038 } |
|
3039 |
|
3040 // |
|
3041 // CTrkDispatchLayer::DoReadThreadListL |
|
3042 // |
|
3043 // Return a list of the current threads for a process to the host debugger |
|
3044 // |
|
3045 void CTrkDispatchLayer::DoReadThreadListL(TInt32 aIndex) |
|
3046 { |
|
3047 // remove the options - unused |
|
3048 iInputBuffer->Des().Delete(0, 1); |
|
3049 |
|
3050 // get the process id |
|
3051 TUint32 processId = 0; |
|
3052 GetDataFromBufferL(&processId, 4); |
|
3053 |
|
3054 // an index of zero means we start fresh. and index other than zero means |
|
3055 // we were not able to return all of the threads in the last round due to |
|
3056 // message size limitations, so we need to pick up where we left off |
|
3057 if (aIndex == 0) |
|
3058 { |
|
3059 DoReBuildThreadList(processId); |
|
3060 } |
|
3061 |
|
3062 TInt32 totalCount = iThreadList.Count(); |
|
3063 TInt32 returnedCount = 0; |
|
3064 TInt32 bytesRemaining = MAXMESSAGESIZE_V2 - 30; // minus the framing bytes |
|
3065 TInt32 restOfMsgSize = sizeof(TUint32) // process id |
|
3066 + sizeof(TUint32) // priority |
|
3067 + sizeof(TUint8) // state |
|
3068 + sizeof(TUint8); // NULL character |
|
3069 |
|
3070 |
|
3071 for (TInt32 i=aIndex; i<totalCount; i++) |
|
3072 { |
|
3073 // make sure there is enough room left in the message |
|
3074 if (bytesRemaining >= (iThreadList[i].iName.Length() + restOfMsgSize)) |
|
3075 { |
|
3076 returnedCount++; |
|
3077 bytesRemaining -= (iThreadList[i].iName.Length() + restOfMsgSize); |
|
3078 } |
|
3079 else |
|
3080 break; |
|
3081 } |
|
3082 |
|
3083 // add values for returnedCount and totalCount |
|
3084 AddToReplyBufferL((TUint32)returnedCount, true); |
|
3085 AddToReplyBufferL((TUint32)totalCount); |
|
3086 |
|
3087 for (TInt32 i=aIndex; i<(aIndex + returnedCount); i++) |
|
3088 { |
|
3089 // add this thread info to the buffer |
|
3090 AddToReplyBufferL(iThreadList[i].iId); |
|
3091 AddToReplyBufferL(iThreadList[i].iPriority); |
|
3092 AddToReplyBufferL(IsThreadSuspended(iThreadList[i].iId)); |
|
3093 AddToReplyBufferL(iThreadList[i].iName); |
|
3094 |
|
3095 // host expects the name to be a null terminated string |
|
3096 AddToReplyBufferL((TUint8)0); |
|
3097 } |
|
3098 |
|
3099 RespondOkL(); |
|
3100 } |
|
3101 |
|
3102 // |
|
3103 // CTrkDispatchLayer::DoReBuildProcessList |
|
3104 // |
|
3105 // Build a list of the current processes |
|
3106 // |
|
3107 void CTrkDispatchLayer::DoReBuildProcessList() |
|
3108 { |
|
3109 TInt err = KErrNone; |
|
3110 |
|
3111 // reset the process list |
|
3112 iProcessList.Reset(); |
|
3113 |
|
3114 // fill up the process list |
|
3115 for (TInt i=0; KErrNone==err; i++) |
|
3116 { |
|
3117 TMetroTrkTaskInfo processInfo(0); |
|
3118 err = iKernelDriver.GetProcessInfo(i, processInfo); |
|
3119 |
|
3120 //Get a Handle to the process |
|
3121 RProcess proc; |
|
3122 if(KErrNone == err && KErrNone == proc.Open(TProcessId(processInfo.iId))) |
|
3123 { |
|
3124 //Only display currently running processes |
|
3125 if(EExitPending == proc.ExitType()) |
|
3126 { |
|
3127 iProcessList.Append(processInfo); |
|
3128 } |
|
3129 proc.Close(); |
|
3130 } |
|
3131 } |
|
3132 } |
|
3133 |
|
3134 // |
|
3135 // CTrkDispatchLayer::DoReBuildThreadList |
|
3136 // |
|
3137 // Build a list of the current threads for a process |
|
3138 // |
|
3139 void CTrkDispatchLayer::DoReBuildThreadList(TUint32 aProcessId) |
|
3140 { |
|
3141 TInt err = KErrNone; |
|
3142 |
|
3143 // reset the thread list |
|
3144 iThreadList.Reset(); |
|
3145 |
|
3146 // fill up the thread list |
|
3147 for (TInt i=0; KErrNone==err; i++) |
|
3148 { |
|
3149 TMetroTrkTaskInfo threadInfo(aProcessId); |
|
3150 err = iKernelDriver.GetThreadInfo(i, threadInfo); |
|
3151 |
|
3152 //Get a Handle to the thread |
|
3153 RThread thread; |
|
3154 if(KErrNone == err && KErrNone == thread.Open(TThreadId(threadInfo.iId))) |
|
3155 { |
|
3156 //Only display currently running processes |
|
3157 if(EExitPending == thread.ExitType()) |
|
3158 { |
|
3159 iThreadList.Append(threadInfo); |
|
3160 } |
|
3161 thread.Close(); |
|
3162 } |
|
3163 } |
|
3164 } |
|
3165 |
|
3166 // CTrkDispatchLayer::DoNotifyStoppedL |
|
3167 // |
|
3168 // Notify the host debugger that a thread has stopped |
|
3169 // |
|
3170 // START_PANIC |
|
3171 //void CTrkDispatchLayer::DoNotifyStoppedL(TUint32 aProcessId, TUint32 aThreadId, TUint32 aCurrentPC, const TDesC8 &aDescription) |
|
3172 void CTrkDispatchLayer::DoNotifyStoppedL(TUint32 aProcessId, TUint32 aThreadId, TUint32 aCurrentPC, const TDesC8 &aDescription, TBool aAddException, const TUint16 aExceptionNumber) |
|
3173 // END_PANIC |
|
3174 { |
|
3175 // add this thread to the suspended threads list |
|
3176 iSuspendedThreadList.Append(aThreadId); |
|
3177 |
|
3178 // TUint8 event = (aAddException==true) ? kDSNotifyStopped2 : kDSNotifyStopped; |
|
3179 TUint8 event = kDSNotifyStopped; |
|
3180 TUint16 descLength = aDescription.Length(); |
|
3181 |
|
3182 AddToReplyBufferL(event, true); |
|
3183 AddToReplyBufferL(aCurrentPC); |
|
3184 AddToReplyBufferL(aProcessId); |
|
3185 AddToReplyBufferL(aThreadId); |
|
3186 AddToReplyBufferL(descLength); |
|
3187 |
|
3188 if (descLength) |
|
3189 { |
|
3190 AddToReplyBufferL(aDescription); |
|
3191 |
|
3192 // host expects the string to be a null terminated string |
|
3193 AddToReplyBufferL((TUint8)0); |
|
3194 } |
|
3195 // START_PANIC |
|
3196 if (aAddException) |
|
3197 AddToReplyBufferL(aExceptionNumber); |
|
3198 // END_PANIC |
|
3199 |
|
3200 InformEventL(); |
|
3201 } |
|
3202 |
|
3203 // |
|
3204 // CTrkDispatchLayer::DoNotifyProcessDiedL |
|
3205 // |
|
3206 // Notify the host debugger that a process has exited |
|
3207 // |
|
3208 void CTrkDispatchLayer::DoNotifyProcessDiedL(TUint32 aProcessId, TInt aExitCode) |
|
3209 { |
|
3210 // remove this process from our list |
|
3211 for (TInt i=0; i<iDebugProcessList.Count(); i++) |
|
3212 { |
|
3213 if (iDebugProcessList[i]->ProcessId() == aProcessId) |
|
3214 { |
|
3215 SafeDelete(iDebugProcessList[i]); |
|
3216 iDebugProcessList.Remove(i); |
|
3217 } |
|
3218 } |
|
3219 |
|
3220 TUint8 event = kDSOSNotifyDeleted; |
|
3221 TUint16 type = kDSOSProcessItem; |
|
3222 |
|
3223 AddToReplyBufferL(event, true); |
|
3224 AddToReplyBufferL(type); |
|
3225 AddToReplyBufferL((TUint32)aExitCode); |
|
3226 AddToReplyBufferL(aProcessId); |
|
3227 |
|
3228 InformEventL(); |
|
3229 } |
|
3230 |
|
3231 // |
|
3232 // CTrkDispatchLayer::DoNotifyLibraryLoadedL |
|
3233 // |
|
3234 // Notify the host debugger that a library in now loaded |
|
3235 // |
|
3236 void CTrkDispatchLayer::DoNotifyLibraryLoadedL(TDesC8 &aName, TUint32 aProcessId, TUint32 aThreadId, TUint32 aCodeBaseAddress, TUint32 aDataBaseAddress) |
|
3237 { |
|
3238 TUint8 event = kDSOSNotifyCreated; |
|
3239 TUint16 type = kDSOSDLLItem; |
|
3240 |
|
3241 TUint16 nameLength = aName.Length(); |
|
3242 |
|
3243 AddToReplyBufferL(event, true); |
|
3244 AddToReplyBufferL(type); |
|
3245 AddToReplyBufferL(aProcessId); |
|
3246 AddToReplyBufferL(aThreadId); |
|
3247 AddToReplyBufferL(aCodeBaseAddress); |
|
3248 AddToReplyBufferL(aDataBaseAddress); |
|
3249 AddToReplyBufferL(nameLength); |
|
3250 AddToReplyBufferL(aName); |
|
3251 |
|
3252 InformEventL(); |
|
3253 } |
|
3254 |
|
3255 // |
|
3256 // CTrkDispatchLayer::DoNotifyLibraryUnloadedL |
|
3257 // |
|
3258 // Notify the host debugger that a library has been unloaded |
|
3259 // |
|
3260 void CTrkDispatchLayer::DoNotifyLibraryUnloadedL(TDesC8 &aName, TUint32 aProcessId, TUint32 aThreadId) |
|
3261 { |
|
3262 TUint8 event = kDSOSNotifyDeleted; |
|
3263 TUint16 type = kDSOSDLLItem; |
|
3264 |
|
3265 TUint16 nameLength = aName.Length(); |
|
3266 |
|
3267 AddToReplyBufferL(event, true); |
|
3268 AddToReplyBufferL(type); |
|
3269 AddToReplyBufferL(aProcessId); |
|
3270 AddToReplyBufferL(aThreadId); |
|
3271 AddToReplyBufferL(nameLength); |
|
3272 AddToReplyBufferL(aName); |
|
3273 |
|
3274 InformEventL(); |
|
3275 } |
|
3276 |
|
3277 // |
|
3278 // CTrkDispatchLayer::GetDataFromBufferL |
|
3279 // |
|
3280 // Notify the host debugger that trace data has been recieved |
|
3281 // |
|
3282 void CTrkDispatchLayer::DoNotifyUserTraceL(TDesC8 &aTrace) |
|
3283 { |
|
3284 if (iIsConnected) |
|
3285 iFramingLayer->SendRawMsgL(aTrace); |
|
3286 } |
|
3287 |
|
3288 void CTrkDispatchLayer::DoNotifyProcessAddedL(TDesC8 &aName, TUint32 aProcessId, TUint32 aThreadId, TUint32 aUid, TUint32 aCodeBaseAddress, TUint32 aDataBaseAddress) |
|
3289 { |
|
3290 // check to see if the host supported protocol handles this event, |
|
3291 // otherwise just resume the thread. If not, this thread would get suspended indefinitely. |
|
3292 if (iHostVersion.iMajor < 3 || (iHostVersion.iMajor == 3 && iHostVersion.iMinor <= 3)) |
|
3293 { |
|
3294 iKernelDriver.ResumeThread(aThreadId); |
|
3295 } |
|
3296 else |
|
3297 { |
|
3298 TUint8 event = kDSOSNotifyCreated; |
|
3299 TUint16 type = kDSOSProcessItem; |
|
3300 |
|
3301 TUint16 nameLength = aName.Length(); |
|
3302 |
|
3303 AddToReplyBufferL(event, true); |
|
3304 AddToReplyBufferL(type); |
|
3305 AddToReplyBufferL(aProcessId); |
|
3306 AddToReplyBufferL(aThreadId); |
|
3307 AddToReplyBufferL(aUid); |
|
3308 AddToReplyBufferL(aCodeBaseAddress); |
|
3309 AddToReplyBufferL(aDataBaseAddress); |
|
3310 AddToReplyBufferL(nameLength); |
|
3311 AddToReplyBufferL(aName); |
|
3312 |
|
3313 InformEventL(); |
|
3314 } |
|
3315 } |
|
3316 |
|
3317 // |
|
3318 // CTrkDispatchLayer::DoReadLibraryInfoL() |
|
3319 // |
|
3320 void CTrkDispatchLayer::DoReadLibraryInfoL(TDesC8& aFileName) |
|
3321 { |
|
3322 TMetroTrkLibInfo libInfo(aFileName.Length(), &aFileName); |
|
3323 |
|
3324 TInt err = iKernelDriver.GetLibraryInfo(libInfo); |
|
3325 |
|
3326 if (err == KErrNone) |
|
3327 { |
|
3328 AddToReplyBufferL(libInfo.iCodeAddress, true); |
|
3329 AddToReplyBufferL(libInfo.iDataAddress); |
|
3330 AddToReplyBufferL(libInfo.iAttachProcessId); |
|
3331 AddToReplyBufferL(libInfo.iAttachThreadId); |
|
3332 |
|
3333 RespondOkL(); |
|
3334 } |
|
3335 else |
|
3336 { |
|
3337 User::Leave(err); |
|
3338 } |
|
3339 } |
|
3340 |
|
3341 // |
|
3342 // CTrkDispatchLayer::DoReadProcessInfoL() |
|
3343 // |
|
3344 void CTrkDispatchLayer::DoReadProcessInfoL(TUint32 aUid, TDesC8& aFileName) |
|
3345 { |
|
3346 TMetroTrkExeInfo exeInfo(aUid, aFileName.Length(), &aFileName); |
|
3347 |
|
3348 TInt err = iKernelDriver.GetExeInfo(exeInfo); |
|
3349 |
|
3350 if (err == KErrNone) |
|
3351 { |
|
3352 AddToReplyBufferL(exeInfo.iProcessID, true); |
|
3353 AddToReplyBufferL(exeInfo.iThreadID); |
|
3354 AddToReplyBufferL(exeInfo.iCodeAddress); |
|
3355 AddToReplyBufferL(exeInfo.iDataAddress); |
|
3356 |
|
3357 RespondOkL(); |
|
3358 } |
|
3359 else |
|
3360 { |
|
3361 User::Leave(err); |
|
3362 } |
|
3363 } |
|
3364 |
|
3365 // |
|
3366 // CTrkDispatchLayer::GetDataFromBufferL |
|
3367 // |
|
3368 // Get data from the input buffer |
|
3369 // |
|
3370 void CTrkDispatchLayer::GetDataFromBufferL(TAny* aData, TInt aLength) |
|
3371 { |
|
3372 if (aLength > iInputBuffer->Length()) |
|
3373 User::Leave(kDSReplyPacketSizeError); |
|
3374 |
|
3375 if (iFramingLayer->IsBigEndian()) |
|
3376 { |
|
3377 Mem::Copy(aData, iInputBuffer->Ptr(), aLength); |
|
3378 } |
|
3379 else |
|
3380 { |
|
3381 TUint8 *p = (TUint8 *)aData; |
|
3382 for (int i=aLength-1, j=0; i>=0; i--, j++) |
|
3383 p[j] = iInputBuffer->Ptr()[i]; |
|
3384 } |
|
3385 |
|
3386 // now remove it from the buffer |
|
3387 iInputBuffer->Des().Delete(0, aLength); |
|
3388 } |
|
3389 |
|
3390 // |
|
3391 // CTrkDispatchLayer::AddToReplyBufferL |
|
3392 // |
|
3393 // Add data to the buffer which will be sent back to the host as a reply |
|
3394 // |
|
3395 void CTrkDispatchLayer::AddToReplyBufferL(TUint8 aData, TBool aReset) |
|
3396 { |
|
3397 if (aReset) |
|
3398 { |
|
3399 // free the memory associated with the old reply buffer and allocate a new one |
|
3400 SafeDelete(iReplyBuffer); |
|
3401 iReplyBuffer = HBufC8::New(sizeof(TUint8)); |
|
3402 } |
|
3403 else |
|
3404 { |
|
3405 // reallocate to make enough room for the new data |
|
3406 iReplyBuffer = iReplyBuffer->ReAlloc(iReplyBuffer->Length() + sizeof(TUint8)); |
|
3407 } |
|
3408 |
|
3409 // make sure the above worked |
|
3410 if (!iReplyBuffer) |
|
3411 User::Leave(KErrNoMemory); |
|
3412 |
|
3413 iReplyBuffer->Des().Append(aData); |
|
3414 } |
|
3415 |
|
3416 // |
|
3417 // CTrkDispatchLayer::AddToReplyBufferL |
|
3418 // |
|
3419 // Add data to the buffer which will be sent back to the host as a reply |
|
3420 // |
|
3421 void CTrkDispatchLayer::AddToReplyBufferL(TUint16 aData, TBool aReset) |
|
3422 { |
|
3423 TUint16 temp = aData; |
|
3424 |
|
3425 if (aReset) |
|
3426 { |
|
3427 // free the memory associated with the old reply buffer and allocate a new one |
|
3428 SafeDelete(iReplyBuffer); |
|
3429 iReplyBuffer = HBufC8::New(sizeof(TUint16)); |
|
3430 } |
|
3431 else |
|
3432 { |
|
3433 // reallocate to make enough room for the new data |
|
3434 iReplyBuffer = iReplyBuffer->ReAlloc(iReplyBuffer->Length() + sizeof(TUint16)); |
|
3435 } |
|
3436 |
|
3437 // make sure the above worked |
|
3438 if (!iReplyBuffer) |
|
3439 User::Leave(KErrNoMemory); |
|
3440 |
|
3441 // the host expects all values except for raw data to be returned in big endian format |
|
3442 if (!iFramingLayer->IsBigEndian()) |
|
3443 { |
|
3444 temp = Swap2(aData); |
|
3445 } |
|
3446 |
|
3447 iReplyBuffer->Des().Append((TUint8 *)&temp, sizeof(TUint16)); |
|
3448 } |
|
3449 |
|
3450 // |
|
3451 // CTrkDispatchLayer::AddToReplyBufferL |
|
3452 // |
|
3453 // Add data to the buffer which will be sent back to the host as a reply |
|
3454 // |
|
3455 void CTrkDispatchLayer::AddToReplyBufferL(TUint32 aData, TBool aReset) |
|
3456 { |
|
3457 TUint32 temp = aData; |
|
3458 |
|
3459 if (aReset) |
|
3460 { |
|
3461 // free the memory associated with the old reply buffer and allocate a new one |
|
3462 SafeDelete(iReplyBuffer); |
|
3463 iReplyBuffer = HBufC8::New(sizeof(TUint32)); |
|
3464 } |
|
3465 else |
|
3466 { |
|
3467 // reallocate to make enough room for the new data |
|
3468 iReplyBuffer = iReplyBuffer->ReAlloc(iReplyBuffer->Length() + sizeof(TUint32)); |
|
3469 } |
|
3470 |
|
3471 // make sure the above worked |
|
3472 if (!iReplyBuffer) |
|
3473 User::Leave(KErrNoMemory); |
|
3474 |
|
3475 // the host expects all values except for raw data to be returned in big endian format |
|
3476 if (!iFramingLayer->IsBigEndian()) |
|
3477 { |
|
3478 temp = Swap4(aData); |
|
3479 } |
|
3480 |
|
3481 iReplyBuffer->Des().Append((TUint8 *)&temp, sizeof(TUint32)); |
|
3482 } |
|
3483 |
|
3484 // |
|
3485 // CTrkDispatchLayer::AddToReplyBufferL |
|
3486 // |
|
3487 // Add data to the buffer which will be sent back to the host as a reply |
|
3488 // |
|
3489 void CTrkDispatchLayer::AddToReplyBufferL(const TDesC8 &aData, TBool aReset) |
|
3490 { |
|
3491 if (aReset) |
|
3492 { |
|
3493 // free the memory associated with the old reply buffer and allocate a new one |
|
3494 SafeDelete(iReplyBuffer); |
|
3495 iReplyBuffer = HBufC8::New(aData.Length()); |
|
3496 } |
|
3497 else |
|
3498 { |
|
3499 // reallocate to make enough room for the new data |
|
3500 iReplyBuffer = iReplyBuffer->ReAlloc(iReplyBuffer->Length() + aData.Length()); |
|
3501 } |
|
3502 |
|
3503 // make sure the above worked |
|
3504 if (!iReplyBuffer) |
|
3505 User::Leave(KErrNoMemory); |
|
3506 |
|
3507 iReplyBuffer->Des().Append(aData); |
|
3508 } |
|
3509 |
|
3510 // |
|
3511 // CTrkDispatchLayer::IsThreadSuspended |
|
3512 // |
|
3513 // Determines whether or not a thread is suspended |
|
3514 // |
|
3515 TUint8 CTrkDispatchLayer::IsThreadSuspended(TUint32 aThreadId) |
|
3516 { |
|
3517 if (iSuspendedThreadList.Find(aThreadId) >= 0) |
|
3518 return 1; |
|
3519 |
|
3520 return 0; |
|
3521 } |
|
3522 |
|
3523 // |
|
3524 // CTrkDispatchLayer::IsRestrictedFolder |
|
3525 // |
|
3526 // Check to see if the path is any of the data caged paths like \sys\ or \private\ or \resource\ |
|
3527 // |
|
3528 TBool CTrkDispatchLayer::IsRestrictedFolder(const TDesC& aPath) |
|
3529 { |
|
3530 _LIT(KSYS, "\\sys\\"); |
|
3531 _LIT(KRESOURCE, "\\resource\\"); |
|
3532 _LIT(KPRIVATE, "\\private\\"); |
|
3533 |
|
3534 if ( (aPath.FindC(KSYS)>=0) || (aPath.FindC(KRESOURCE)>=0) || (aPath.FindC(KPRIVATE)>=0) ) |
|
3535 return ETrue; |
|
3536 |
|
3537 return EFalse; |
|
3538 } |
|
3539 |
|
3540 |
|
3541 TInt CTrkDispatchLayer::CloseCrashLogger() |
|
3542 { |
|
3543 TInt err = KErrNone; |
|
3544 |
|
3545 //The old mobile crash file name is "d_exc_mc.exe" and the new one is "mc_useragent.exe" |
|
3546 //This is the string that needs to be passed to the RProcess::Open call to get a handle. |
|
3547 //The complete process name actually includes the UID info as well. |
|
3548 //Instead of hard coding the process name, its better to just |
|
3549 //search for the process and find it that way. |
|
3550 //_LIT16(KCrashLoggerName, "mc_useragent.exe[1020e519]0001"); |
|
3551 _LIT16(KOldCrashLoggerName, "d_exc_mc*"); |
|
3552 _LIT16(KCrashLoggerName, "mc_useragent*"); |
|
3553 |
|
3554 err = TerminateProcess(KOldCrashLoggerName); |
|
3555 err = TerminateProcess(KCrashLoggerName); |
|
3556 |
|
3557 return err; |
|
3558 } |
|
3559 |
|
3560 TInt CTrkDispatchLayer::TerminateProcess(const TDesC& aProcessName) |
|
3561 { |
|
3562 TFindProcess find(aProcessName); |
|
3563 TFullName name; |
|
3564 |
|
3565 TInt err = find.Next(name); |
|
3566 if (KErrNone == err) |
|
3567 { |
|
3568 RProcess process; |
|
3569 err = process.Open(find); |
|
3570 |
|
3571 if (KErrNone == err) |
|
3572 { |
|
3573 process.Kill(KErrNone); |
|
3574 } |
|
3575 } |
|
3576 return err; |
|
3577 } |