80
80
* @todo Add AMD64 support (needs teaming up with the module management for
83
static int dbgfR3StackWalk(PVM pVM, VMCPUID idCpu, PDBGFSTACKFRAME pFrame)
83
static int dbgfR3StackWalk(PVM pVM, VMCPUID idCpu, RTDBGAS hAs, PDBGFSTACKFRAME pFrame)
86
86
* Stop if we got a read error in the previous run.
100
100
case DBGFADDRESS_FLAGS_FAR32: cbStackItem = 4; break;
101
101
case DBGFADDRESS_FLAGS_FAR64: cbStackItem = 8; break;
102
102
case DBGFADDRESS_FLAGS_RING0: cbStackItem = sizeof(RTHCUINTPTR); break;
103
default: cbStackItem = 4; break; /// @todo 64-bit guests.
104
switch (pFrame->enmReturnType)
106
case DBGFRETURNTYPE_FAR16:
107
case DBGFRETURNTYPE_IRET16:
108
case DBGFRETURNTYPE_IRET32_V86:
109
case DBGFRETURNTYPE_NEAR16: cbStackItem = 2; break;
111
case DBGFRETURNTYPE_FAR32:
112
case DBGFRETURNTYPE_IRET32:
113
case DBGFRETURNTYPE_IRET32_PRIV:
114
case DBGFRETURNTYPE_NEAR32: cbStackItem = 4; break;
116
case DBGFRETURNTYPE_FAR64:
117
case DBGFRETURNTYPE_IRET64:
118
case DBGFRETURNTYPE_NEAR64: cbStackItem = 8; break;
121
AssertMsgFailed(("%d\n", pFrame->enmReturnType));
138
159
/* Current PC - set by caller, just find symbol & line. */
139
160
if (DBGFADDRESS_IS_VALID(&pFrame->AddrPC))
141
pFrame->pSymPC = DBGFR3SymbolByAddrAlloc(pVM, pFrame->AddrPC.FlatPtr, NULL);
162
pFrame->pSymPC = DBGFR3AsSymbolByAddrA(pVM, hAs, &pFrame->AddrPC, NULL /*offDisp*/, NULL /*phMod*/);
142
163
pFrame->pLinePC = DBGFR3LineByAddrAlloc(pVM, pFrame->AddrPC.FlatPtr, NULL);
234
255
return VERR_INVALID_PARAMETER;
237
pFrame->pSymReturnPC = DBGFR3SymbolByAddrAlloc(pVM, pFrame->AddrReturnPC.FlatPtr, NULL);
258
pFrame->pSymReturnPC = DBGFR3AsSymbolByAddrA(pVM, hAs, &pFrame->AddrReturnPC, NULL /*offDisp*/, NULL /*phMod*/);
238
259
pFrame->pLineReturnPC = DBGFR3LineByAddrAlloc(pVM, pFrame->AddrReturnPC.FlatPtr, NULL);
262
* Frame bitness flag.
266
case 2: pFrame->fFlags |= DBGFSTACKFRAME_FLAGS_16BIT; break;
267
case 4: pFrame->fFlags |= DBGFSTACKFRAME_FLAGS_32BIT; break;
268
case 8: pFrame->fFlags |= DBGFSTACKFRAME_FLAGS_64BIT; break;
269
default: AssertMsgFailed(("cbStackItem=%d\n", cbStackItem)); return VERR_INTERNAL_ERROR;
243
275
memcpy(&pFrame->Args, uArgs.pv, sizeof(pFrame->Args));
250
282
* Walks the entire stack allocating memory as we walk.
252
static DECLCALLBACK(int) dbgfR3StackWalkCtxFull(PVM pVM, VMCPUID idCpu, PCCPUMCTXCORE pCtxCore,
284
static DECLCALLBACK(int) dbgfR3StackWalkCtxFull(PVM pVM, VMCPUID idCpu, PCCPUMCTXCORE pCtxCore, RTDBGAS hAs,
253
285
DBGFCODETYPE enmCodeType,
254
286
PCDBGFADDRESS pAddrFrame,
255
287
PCDBGFADDRESS pAddrStack,
281
313
case DBGFADDRESS_FLAGS_FAR16: pCur->enmReturnType = DBGFRETURNTYPE_NEAR16; break;
282
314
case DBGFADDRESS_FLAGS_FAR32: pCur->enmReturnType = DBGFRETURNTYPE_NEAR32; break;
283
315
case DBGFADDRESS_FLAGS_FAR64: pCur->enmReturnType = DBGFRETURNTYPE_NEAR64; break;
284
case DBGFADDRESS_FLAGS_RING0: pCur->enmReturnType = (HC_ARCH_BITS == 64) ? DBGFRETURNTYPE_NEAR64 : DBGFRETURNTYPE_NEAR32; break;
316
case DBGFADDRESS_FLAGS_RING0: pCur->enmReturnType = HC_ARCH_BITS == 64 ? DBGFRETURNTYPE_NEAR64 : DBGFRETURNTYPE_NEAR32; break;
285
317
default: pCur->enmReturnType = DBGFRETURNTYPE_NEAR32; break; /// @todo 64-bit guests
288
uint64_t fAddrMask = UINT64_MAX;
289
321
if (enmCodeType == DBGFCODETYPE_RING0)
290
fAddrMask = (HC_ARCH_BITS == 64) ? UINT64_MAX : UINT32_MAX;
292
if (enmCodeType == DBGFCODETYPE_HYPER)
322
fAddrMask = HC_ARCH_BITS == 64 ? UINT64_MAX : UINT32_MAX;
323
else if (enmCodeType == DBGFCODETYPE_HYPER)
293
324
fAddrMask = UINT32_MAX;
294
325
else if (DBGFADDRESS_IS_FAR16(&pCur->AddrPC))
295
326
fAddrMask = UINT16_MAX;
296
327
else if (DBGFADDRESS_IS_FAR32(&pCur->AddrPC))
297
328
fAddrMask = UINT32_MAX;
298
else if (DBGFADDRESS_IS_FLAT(&pCur->AddrPC))
329
else if (DBGFADDRESS_IS_FAR64(&pCur->AddrPC))
330
fAddrMask = UINT64_MAX;
300
CPUMMODE CpuMode = CPUMGetGuestMode(VMMGetCpuById(pVM, idCpu));
333
PVMCPU pVCpu = VMMGetCpuById(pVM, idCpu);
334
CPUMMODE CpuMode = CPUMGetGuestMode(pVCpu);
301
335
if (CpuMode == CPUMMODE_REAL)
302
336
fAddrMask = UINT16_MAX;
303
else if (CpuMode == CPUMMODE_PROTECTED)
337
else if ( CpuMode == CPUMMODE_PROTECTED
338
|| !CPUMIsGuestIn64BitCode(pVCpu, pCtxCore))
304
339
fAddrMask = UINT32_MAX;
341
fAddrMask = UINT64_MAX;
321
358
* The first frame.
323
360
if (RT_SUCCESS(rc))
324
rc = dbgfR3StackWalk(pVM, idCpu, pCur);
361
rc = dbgfR3StackWalk(pVM, idCpu, hAs, pCur);
325
362
if (RT_FAILURE(rc))
327
364
DBGFR3StackWalkEnd(pCur);
335
372
while (!(pCur->fFlags & (DBGFSTACKFRAME_FLAGS_LAST | DBGFSTACKFRAME_FLAGS_MAX_DEPTH | DBGFSTACKFRAME_FLAGS_LOOP)))
338
rc = dbgfR3StackWalk(pVM, idCpu, &Next);
375
rc = dbgfR3StackWalk(pVM, idCpu, hAs, &Next);
339
376
if (RT_FAILURE(rc))
389
426
if (enmCodeType == DBGFCODETYPE_RING0)
390
427
return VINF_SUCCESS;
393
431
* Validate parameters.
395
433
*ppFirstFrame = NULL;
396
434
VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE);
397
AssertReturn(idCpu < pVM->cCPUs, VERR_INVALID_CPU_ID);
435
AssertReturn(idCpu < pVM->cCpus, VERR_INVALID_CPU_ID);
399
437
AssertReturn(DBGFR3AddrIsValid(pVM, pAddrFrame), VERR_INVALID_PARAMETER);
407
445
* Get the CPUM context pointer and pass it on the specified EMT.
409
448
PCCPUMCTXCORE pCtxCore;
410
449
switch (enmCodeType)
412
451
case DBGFCODETYPE_GUEST:
413
452
pCtxCore = CPUMGetGuestCtxCore(VMMGetCpuById(pVM, idCpu));
453
hAs = DBGF_AS_GLOBAL;
415
455
case DBGFCODETYPE_HYPER:
416
456
pCtxCore = CPUMGetHyperCtxCore(VMMGetCpuById(pVM, idCpu));
457
hAs = DBGF_AS_RC_AND_GC_GLOBAL;
418
459
case DBGFCODETYPE_RING0:
419
460
pCtxCore = NULL; /* No valid context present. */
422
464
AssertFailedReturn(VERR_INVALID_PARAMETER);
425
int rc = VMR3ReqCall(pVM, idCpu, &pReq, RT_INDEFINITE_WAIT,
426
(PFNRT)dbgfR3StackWalkCtxFull, 9,
427
pVM, idCpu, pCtxCore, enmCodeType,
428
pAddrFrame, pAddrStack, pAddrPC, enmReturnType, ppFirstFrame);
466
return VMR3ReqCallWait(pVM, idCpu, (PFNRT)dbgfR3StackWalkCtxFull, 10,
467
pVM, idCpu, pCtxCore, hAs, enmCodeType,
468
pAddrFrame, pAddrStack, pAddrPC, enmReturnType, ppFirstFrame);
547
581
pFrame->pLineReturnPC = NULL;
550
DBGFR3SymbolFree(pCur->pSymPC);
551
DBGFR3SymbolFree(pCur->pSymReturnPC);
584
RTDbgSymbolFree(pCur->pSymPC);
585
RTDbgSymbolFree(pCur->pSymReturnPC);
552
586
DBGFR3LineFree(pCur->pLinePC);
553
587
DBGFR3LineFree(pCur->pLineReturnPC);