Changeset 73397 in vbox for trunk/src/VBox
- Timestamp:
- Jul 30, 2018 3:25:28 PM (6 years ago)
- Location:
- trunk/src/VBox/VMM/VMMR3
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR3/DBGFAddrSpace.cpp
r70948 r73397 544 544 545 545 /* 546 * Make sure the handle hasis already in the database.546 * Make sure the handle is already in the database. 547 547 */ 548 548 int rc = VERR_NOT_FOUND; … … 559 559 rc = VINF_SUCCESS; 560 560 } 561 else 562 RTDbgAsRelease(hRealAliasFor); 561 563 DBGF_AS_DB_UNLOCK_WRITE(pUVM); 562 564 … … 1211 1213 } 1212 1214 1215 RTDbgAsRelease(hRealAS); 1213 1216 return rc; 1214 1217 } … … 1297 1300 } 1298 1301 1302 RTDbgAsRelease(hRealAS); 1299 1303 return rc; 1300 1304 } … … 1334 1338 * Do the lookup. 1335 1339 */ 1336 return RTDbgAsLineByAddr(hRealAS, pAddress->FlatPtr, poffDisp, pLine, phMod); 1340 int rc = RTDbgAsLineByAddr(hRealAS, pAddress->FlatPtr, poffDisp, pLine, phMod); 1341 1342 RTDbgAsRelease(hRealAS); 1343 return rc; 1337 1344 } 1338 1345 -
trunk/src/VBox/VMM/VMMR3/DBGFStack.cpp
r73388 r73397 52 52 VMCPUID m_idCpu; 53 53 RTDBGAS m_hAs; 54 55 uint64_t m_auRegs[16]; 54 56 uint64_t m_uPc; 55 uint64_t m_aGprs[16]; 57 uint64_t m_uRFlags; 58 uint16_t m_uCs; 59 uint16_t m_uSs; 56 60 57 61 RTDBGMOD m_hCached; … … 70 74 if (pInitialCtx) 71 75 { 72 m_aGprs[X86_GREG_xAX] = pInitialCtx->rax; 73 m_aGprs[X86_GREG_xCX] = pInitialCtx->rcx; 74 m_aGprs[X86_GREG_xDX] = pInitialCtx->rdx; 75 m_aGprs[X86_GREG_xBX] = pInitialCtx->rbx; 76 m_aGprs[X86_GREG_xSP] = pInitialCtx->rsp; 77 m_aGprs[X86_GREG_xBP] = pInitialCtx->rbp; 78 m_aGprs[X86_GREG_xSI] = pInitialCtx->rsi; 79 m_aGprs[X86_GREG_xDI] = pInitialCtx->rdi; 80 m_aGprs[X86_GREG_x8 ] = pInitialCtx->r8; 81 m_aGprs[X86_GREG_x9 ] = pInitialCtx->r9; 82 m_aGprs[X86_GREG_x10] = pInitialCtx->r10; 83 m_aGprs[X86_GREG_x11] = pInitialCtx->r11; 84 m_aGprs[X86_GREG_x12] = pInitialCtx->r12; 85 m_aGprs[X86_GREG_x13] = pInitialCtx->r13; 86 m_aGprs[X86_GREG_x14] = pInitialCtx->r14; 87 m_aGprs[X86_GREG_x15] = pInitialCtx->r15; 88 m_uPc = pInitialCtx->rip; 76 m_auRegs[X86_GREG_xAX] = pInitialCtx->rax; 77 m_auRegs[X86_GREG_xCX] = pInitialCtx->rcx; 78 m_auRegs[X86_GREG_xDX] = pInitialCtx->rdx; 79 m_auRegs[X86_GREG_xBX] = pInitialCtx->rbx; 80 m_auRegs[X86_GREG_xSP] = pInitialCtx->rsp; 81 m_auRegs[X86_GREG_xBP] = pInitialCtx->rbp; 82 m_auRegs[X86_GREG_xSI] = pInitialCtx->rsi; 83 m_auRegs[X86_GREG_xDI] = pInitialCtx->rdi; 84 m_auRegs[X86_GREG_x8 ] = pInitialCtx->r8; 85 m_auRegs[X86_GREG_x9 ] = pInitialCtx->r9; 86 m_auRegs[X86_GREG_x10] = pInitialCtx->r10; 87 m_auRegs[X86_GREG_x11] = pInitialCtx->r11; 88 m_auRegs[X86_GREG_x12] = pInitialCtx->r12; 89 m_auRegs[X86_GREG_x13] = pInitialCtx->r13; 90 m_auRegs[X86_GREG_x14] = pInitialCtx->r14; 91 m_auRegs[X86_GREG_x15] = pInitialCtx->r15; 92 m_uPc = pInitialCtx->rip; 93 m_uCs = pInitialCtx->cs.Sel; 94 m_uSs = pInitialCtx->ss.Sel; 95 m_uRFlags = pInitialCtx->rflags.u; 89 96 } 90 97 else 91 98 { 92 RT_BZERO(m_aGprs, sizeof(m_aGprs)); 93 m_uPc = 0; 94 } 99 RT_BZERO(m_auRegs, sizeof(m_auRegs)); 100 m_uPc = 0; 101 m_uCs = 0; 102 m_uSs = 0; 103 m_uRFlags = 0; 104 } 105 95 106 m_pUVM = pUVM; 96 107 m_idCpu = idCpu; 97 m_hAs = hAs;108 m_hAs = DBGFR3AsResolveAndRetain(pUVM, hAs); 98 109 99 110 m_hCached = NIL_RTDBGMOD; … … 134 145 { 135 146 dbgfR3UnwindCtxFlushCache(this); 136 } 137 138 147 if (m_hAs != NIL_RTDBGAS) 148 { 149 RTDbgAsRelease(m_hAs); 150 m_hAs = NIL_RTDBGAS; 151 } 152 } 153 154 155 /** 156 * Sets PC and SP. 157 * 158 * @returns true. 159 * @param pUnwindCtx The unwind context. 160 * @param pAddrPC The program counter (PC) value to set. 161 * @param pAddrStack The stack pointer (SP) value to set. 162 */ 139 163 static bool dbgfR3UnwindCtxSetPcAndSp(PDBGFUNWINDCTX pUnwindCtx, PCDBGFADDRESS pAddrPC, PCDBGFADDRESS pAddrStack) 140 164 { 141 pUnwindCtx->m_uPc = pAddrPC->FlatPtr; 142 pUnwindCtx->m_aGprs[X86_GREG_xSP] = pAddrStack->FlatPtr; 165 if (!DBGFADDRESS_IS_FAR(pAddrPC)) 166 pUnwindCtx->m_uPc = pAddrPC->FlatPtr; 167 else 168 { 169 pUnwindCtx->m_uPc = pAddrPC->off; 170 pUnwindCtx->m_uCs = pAddrPC->Sel; 171 } 172 if (!DBGFADDRESS_IS_FAR(pAddrStack)) 173 pUnwindCtx->m_auRegs[X86_GREG_xSP] = pAddrStack->FlatPtr; 174 else 175 { 176 pUnwindCtx->m_auRegs[X86_GREG_xSP] = pAddrStack->off; 177 pUnwindCtx->m_uSs = pAddrStack->Sel; 178 } 143 179 return true; 180 } 181 182 183 /** 184 * Try read a 16-bit value off the stack. 185 * 186 * @param pUnwindCtx The unwind context. 187 * @param uSrcAddr The stack address. 188 * @param puDst The read destination. 189 */ 190 static void dbgfR3UnwindCtxLoadU16(PDBGFUNWINDCTX pUnwindCtx, uint64_t uSrcAddr, uint16_t *puDst) 191 { 192 DBGFADDRESS SrcAddr; 193 DBGFR3MemRead(pUnwindCtx->m_pUVM, pUnwindCtx->m_idCpu, 194 DBGFR3AddrFromFlat(pUnwindCtx->m_pUVM, &SrcAddr, uSrcAddr), 195 puDst, sizeof(*puDst)); 144 196 } 145 197 … … 188 240 189 241 190 static bool dbgfR3UnwindCtxDoOneFrameCached(PDBGFUNWINDCTX pUnwindCtx, uint32_t uRvaRip, PDBGFADDRESS pAddrFrame) 242 /** 243 * Processes an IRET frame. 244 * 245 * @returns true. 246 * @param pUnwindCtx The unwind context. 247 * @param fErrCd Non-zero if there is an error code on the stack. 248 * @param pAddrFrame Where to return the frame pointer. 249 * @param penmRetType Where to return the return type. 250 */ 251 static bool dbgfR3UnwindCtxDoOneIRet(PDBGFUNWINDCTX pUnwindCtx, uint8_t fErrCd, 252 PDBGFADDRESS pAddrFrame, DBGFRETURNTYPE *penmRetType) 253 { 254 Assert(fErrCd <= 1); 255 if (fErrCd) 256 pUnwindCtx->m_auRegs[X86_GREG_xSP] += 8; /* error code */ 257 258 *penmRetType = DBGFRETURNTYPE_IRET64; 259 DBGFR3AddrFromFlat(pUnwindCtx->m_pUVM, pAddrFrame, 260 pUnwindCtx->m_auRegs[X86_GREG_xSP] - /* pretend rbp is pushed on the stack */ 8); 261 262 dbgfR3UnwindCtxLoadU64(pUnwindCtx, pUnwindCtx->m_auRegs[X86_GREG_xSP], &pUnwindCtx->m_uPc); 263 pUnwindCtx->m_auRegs[X86_GREG_xSP] += 8; /* RIP */ 264 265 dbgfR3UnwindCtxLoadU16(pUnwindCtx, pUnwindCtx->m_auRegs[X86_GREG_xSP], &pUnwindCtx->m_uCs); 266 pUnwindCtx->m_auRegs[X86_GREG_xSP] += 8; /* CS */ 267 268 dbgfR3UnwindCtxLoadU64(pUnwindCtx, pUnwindCtx->m_auRegs[X86_GREG_xSP], &pUnwindCtx->m_uRFlags); 269 pUnwindCtx->m_auRegs[X86_GREG_xSP] += 8; /* EFLAGS */ 270 271 uint64_t uNewRsp = (pUnwindCtx->m_auRegs[X86_GREG_xSP] - 8) & ~(uint64_t)15; 272 dbgfR3UnwindCtxLoadU64(pUnwindCtx, pUnwindCtx->m_auRegs[X86_GREG_xSP], &uNewRsp); 273 pUnwindCtx->m_auRegs[X86_GREG_xSP] += 8; /* RSP */ 274 275 dbgfR3UnwindCtxLoadU16(pUnwindCtx, pUnwindCtx->m_auRegs[X86_GREG_xSP], &pUnwindCtx->m_uSs); 276 pUnwindCtx->m_auRegs[X86_GREG_xSP] += 8; /* SS */ 277 278 pUnwindCtx->m_auRegs[X86_GREG_xSP] = uNewRsp; 279 return true; 280 } 281 282 283 /** 284 * Unwinds one frame using cached module info. 285 * 286 * @returns true on success, false on failure. 287 * @param pUnwindCtx The unwind context. 288 * @param uRvaRip The RVA of the RIP. 289 * @param pAddrFrame Where to return the frame pointer. 290 * @param penmRetType Where to return the return type. 291 */ 292 static bool dbgfR3UnwindCtxDoOneFrameCached(PDBGFUNWINDCTX pUnwindCtx, uint32_t uRvaRip, 293 PDBGFADDRESS pAddrFrame, DBGFRETURNTYPE *penmRetType) 191 294 { 192 295 /* … … 197 300 if (pEntry) 198 301 { 302 IMAGE_RUNTIME_FUNCTION_ENTRY ChainedEntry; 199 303 unsigned iFrameReg = ~0U; 200 304 unsigned offFrameReg = 0; 201 305 202 for (;;) 306 int fInEpilog = -1; /* -1: not-determined-assume-false; 0: false; 1: true. */ 307 uint8_t cbEpilog = 0; 308 uint8_t offEpilog = UINT8_MAX; 309 for (unsigned cChainLoops = 0; ; cChainLoops++) 203 310 { 204 311 /* … … 225 332 PCIMAGE_UNWIND_INFO pInfo = (PCIMAGE_UNWIND_INFO)&uBuf; 226 333 227 if (pInfo->Version != 1 )334 if (pInfo->Version != 1 && pInfo->Version != 2) 228 335 return false; 229 336 … … 234 341 unsigned iOpcode = 0; 235 342 236 /* First, skip opcodes that doesn't apply to us if we're the prolog. */ 237 uint32_t offPc = uRvaRip - pEntry->BeginAddress; 238 if (offPc < pInfo->SizeOfProlog) 239 while (iOpcode < cOpcodes && pInfo->aOpcodes[iOpcode].u.CodeOffset > offPc) 343 /* 344 * Check for epilog opcodes at the start and see if we're in an epilog. 345 */ 346 if ( pInfo->Version >= 2 347 && iOpcode < cOpcodes 348 && pInfo->aOpcodes[iOpcode].u.UnwindOp == IMAGE_AMD64_UWOP_EPILOG) 349 { 350 if (fInEpilog == -1) 351 { 352 cbEpilog = pInfo->aOpcodes[iOpcode].u.CodeOffset; 353 Assert(cbEpilog > 0); 354 355 uint32_t uRvaEpilog = pEntry->EndAddress - cbEpilog; 240 356 iOpcode++; 241 242 /* Execute. */ 243 if (pInfo->FrameRegister != 0) 244 { 245 iFrameReg = pInfo->FrameRegister; 246 offFrameReg = pInfo->FrameOffset * 16; 247 } 248 while (iOpcode < cOpcodes) 249 { 250 Assert(pInfo->aOpcodes[iOpcode].u.CodeOffset <= offPc); 251 switch (pInfo->aOpcodes[iOpcode].u.UnwindOp) 252 { 253 case IMAGE_AMD64_UWOP_PUSH_NONVOL: 254 pUnwindCtx->m_aGprs[X86_GREG_xSP] -= 8; 255 dbgfR3UnwindCtxLoadU64(pUnwindCtx, pUnwindCtx->m_aGprs[X86_GREG_xSP], 256 &pUnwindCtx->m_aGprs[pInfo->aOpcodes[iOpcode].u.OpInfo]); 257 iOpcode++; 258 break; 259 260 case IMAGE_AMD64_UWOP_ALLOC_LARGE: 261 iOpcode += 3; 262 AssertBreak(iOpcode <= cOpcodes); 263 pUnwindCtx->m_aGprs[X86_GREG_xSP] -= *(uint32_t const *)&pInfo->aOpcodes[iOpcode - 2]; 264 break; 265 266 case IMAGE_AMD64_UWOP_ALLOC_SMALL: 267 AssertBreak(iOpcode <= cOpcodes); 268 pUnwindCtx->m_aGprs[X86_GREG_xSP] -= pInfo->aOpcodes[iOpcode].u.OpInfo * 8 + 8; 269 iOpcode++; 270 break; 271 272 case IMAGE_AMD64_UWOP_SET_FPREG: 273 iFrameReg = pInfo->aOpcodes[iOpcode].u.OpInfo; 274 offFrameReg = pInfo->FrameOffset * 16; 275 break; 276 277 case IMAGE_AMD64_UWOP_SAVE_NONVOL: 278 case IMAGE_AMD64_UWOP_SAVE_NONVOL_FAR: 357 if ( (pInfo->aOpcodes[iOpcode - 1].u.OpInfo & 1) 358 && uRvaRip >= uRvaEpilog) 279 359 { 280 bool const fFar = pInfo->aOpcodes[iOpcode].u.UnwindOp == IMAGE_AMD64_UWOP_SAVE_NONVOL_FAR; 281 unsigned const iGreg = pInfo->aOpcodes[iOpcode].u.OpInfo; 282 uint32_t off = 0; 283 iOpcode++; 284 if (iOpcode < cOpcodes) 360 offEpilog = uRvaRip - uRvaEpilog; 361 fInEpilog = 1; 362 } 363 else 364 { 365 fInEpilog = 0; 366 while (iOpcode < cOpcodes && pInfo->aOpcodes[iOpcode].u.UnwindOp == IMAGE_AMD64_UWOP_EPILOG) 285 367 { 286 off = pInfo->aOpcodes[iOpcode].FrameOffset; 368 uRvaEpilog = pEntry->EndAddress 369 - (pInfo->aOpcodes[iOpcode].u.CodeOffset + (pInfo->aOpcodes[iOpcode].u.OpInfo << 8)); 287 370 iOpcode++; 288 if ( fFar && iOpcode < cOpcodes)371 if (uRvaRip - uRvaEpilog < cbEpilog) 289 372 { 290 off |= (uint32_t)pInfo->aOpcodes[iOpcode].FrameOffset << 16; 291 iOpcode++; 373 offEpilog = uRvaRip - uRvaEpilog; 374 fInEpilog = 1; 375 break; 292 376 } 293 377 } 294 off *= 8;295 dbgfR3UnwindCtxLoadU64(pUnwindCtx, pUnwindCtx->m_aGprs[X86_GREG_xSP] + off, &pUnwindCtx->m_aGprs[iGreg]);296 break;297 378 } 298 299 case IMAGE_AMD64_UWOP_SAVE_XMM128: 300 iOpcode += 2; 301 break; 302 303 case IMAGE_AMD64_UWOP_SAVE_XMM128_FAR: 304 iOpcode += 3; 305 break; 306 307 case IMAGE_AMD64_UWOP_PUSH_MACHFRAME: 379 } 380 while (iOpcode < cOpcodes && pInfo->aOpcodes[iOpcode].u.UnwindOp == IMAGE_AMD64_UWOP_EPILOG) 381 iOpcode++; 382 } 383 if (fInEpilog != 1) 384 { 385 /* 386 * Skip opcodes that doesn't apply to us if we're in the prolog. 387 */ 388 uint32_t offPc = uRvaRip - pEntry->BeginAddress; 389 if (offPc < pInfo->SizeOfProlog) 390 while (iOpcode < cOpcodes && pInfo->aOpcodes[iOpcode].u.CodeOffset > offPc) 391 iOpcode++; 392 393 /* 394 * Execute the opcodes. 395 */ 396 if (pInfo->FrameRegister != 0) 397 { 398 iFrameReg = pInfo->FrameRegister; 399 offFrameReg = pInfo->FrameOffset * 16; 400 } 401 while (iOpcode < cOpcodes) 402 { 403 Assert(pInfo->aOpcodes[iOpcode].u.CodeOffset <= offPc); 404 switch (pInfo->aOpcodes[iOpcode].u.UnwindOp) 308 405 { 309 Assert(pInfo->aOpcodes[iOpcode].u.OpInfo <= 1); 310 if (pInfo->aOpcodes[iOpcode].u.OpInfo) 311 pUnwindCtx->m_aGprs[X86_GREG_xSP] -= 8; /* error code */ 312 313 pUnwindCtx->m_aGprs[X86_GREG_xSP] -= 8; /* RIP */ 314 dbgfR3UnwindCtxLoadU64(pUnwindCtx, pUnwindCtx->m_aGprs[X86_GREG_xSP], &pUnwindCtx->m_uPc); 315 316 pUnwindCtx->m_aGprs[X86_GREG_xSP] -= 8; /* CS */ 317 //dbgfR3UnwindCtxLoadU16(pUnwindCtx, pUnwindCtx->m_aGprs[X86_GREG_xSP], &pUnwindCtx->m_uCs); 318 319 pUnwindCtx->m_aGprs[X86_GREG_xSP] -= 8; /* EFLAGS */ 320 //dbgfR3UnwindCtxLoadU64(pUnwindCtx, pUnwindCtx->m_aGprs[X86_GREG_xSP], &pUnwindCtx->m_uRFlags); 321 322 pUnwindCtx->m_aGprs[X86_GREG_xSP] -= 8; /* RSP */ 323 uint64_t uNewRsp = (pUnwindCtx->m_aGprs[X86_GREG_xSP] - 8) & ~(uint64_t)15; 324 dbgfR3UnwindCtxLoadU64(pUnwindCtx, pUnwindCtx->m_aGprs[X86_GREG_xSP], &uNewRsp); 325 326 pUnwindCtx->m_aGprs[X86_GREG_xSP] -= 8; /* SS */ 327 //dbgfR3UnwindCtxLoadU16(pUnwindCtx, pUnwindCtx->m_aGprs[X86_GREG_xSP], &pUnwindCtx->m_uSs); 328 329 pUnwindCtx->m_aGprs[X86_GREG_xSP] = uNewRsp; 330 return true; 406 case IMAGE_AMD64_UWOP_PUSH_NONVOL: 407 pUnwindCtx->m_auRegs[X86_GREG_xSP] += 8; 408 dbgfR3UnwindCtxLoadU64(pUnwindCtx, pUnwindCtx->m_auRegs[X86_GREG_xSP], 409 &pUnwindCtx->m_auRegs[pInfo->aOpcodes[iOpcode].u.OpInfo]); 410 iOpcode++; 411 break; 412 413 case IMAGE_AMD64_UWOP_ALLOC_LARGE: 414 if (pInfo->aOpcodes[iOpcode].u.OpInfo == 0) 415 { 416 iOpcode += 2; 417 AssertBreak(iOpcode <= cOpcodes); 418 pUnwindCtx->m_auRegs[X86_GREG_xSP] += pInfo->aOpcodes[iOpcode - 1].FrameOffset * 8; 419 } 420 else 421 { 422 iOpcode += 3; 423 AssertBreak(iOpcode <= cOpcodes); 424 pUnwindCtx->m_auRegs[X86_GREG_xSP] += RT_MAKE_U32(pInfo->aOpcodes[iOpcode - 2].FrameOffset, 425 pInfo->aOpcodes[iOpcode - 1].FrameOffset); 426 } 427 break; 428 429 case IMAGE_AMD64_UWOP_ALLOC_SMALL: 430 AssertBreak(iOpcode <= cOpcodes); 431 pUnwindCtx->m_auRegs[X86_GREG_xSP] += pInfo->aOpcodes[iOpcode].u.OpInfo * 8 + 8; 432 iOpcode++; 433 break; 434 435 case IMAGE_AMD64_UWOP_SET_FPREG: 436 iFrameReg = pInfo->aOpcodes[iOpcode].u.OpInfo; 437 offFrameReg = pInfo->FrameOffset * 16; 438 iOpcode++; 439 break; 440 441 case IMAGE_AMD64_UWOP_SAVE_NONVOL: 442 case IMAGE_AMD64_UWOP_SAVE_NONVOL_FAR: 443 { 444 bool const fFar = pInfo->aOpcodes[iOpcode].u.UnwindOp == IMAGE_AMD64_UWOP_SAVE_NONVOL_FAR; 445 unsigned const iGreg = pInfo->aOpcodes[iOpcode].u.OpInfo; 446 uint32_t off = 0; 447 iOpcode++; 448 if (iOpcode < cOpcodes) 449 { 450 off = pInfo->aOpcodes[iOpcode].FrameOffset; 451 iOpcode++; 452 if (fFar && iOpcode < cOpcodes) 453 { 454 off |= (uint32_t)pInfo->aOpcodes[iOpcode].FrameOffset << 16; 455 iOpcode++; 456 } 457 } 458 off *= 8; 459 dbgfR3UnwindCtxLoadU64(pUnwindCtx, pUnwindCtx->m_auRegs[X86_GREG_xSP] + off, &pUnwindCtx->m_auRegs[iGreg]); 460 break; 461 } 462 463 case IMAGE_AMD64_UWOP_SAVE_XMM128: 464 iOpcode += 2; 465 break; 466 467 case IMAGE_AMD64_UWOP_SAVE_XMM128_FAR: 468 iOpcode += 3; 469 break; 470 471 case IMAGE_AMD64_UWOP_PUSH_MACHFRAME: 472 return dbgfR3UnwindCtxDoOneIRet(pUnwindCtx, pInfo->aOpcodes[iOpcode].u.OpInfo, pAddrFrame, penmRetType); 473 474 case IMAGE_AMD64_UWOP_EPILOG: 475 iOpcode += 1; 476 break; 477 478 case IMAGE_AMD64_UWOP_RESERVED_7: 479 AssertFailedReturn(false); 480 481 default: 482 AssertMsgFailedReturn(("%u\n", pInfo->aOpcodes[iOpcode].u.UnwindOp), false); 331 483 } 332 333 case IMAGE_AMD64_UWOP_RESERVED_6: 334 AssertFailedReturn(false); 335 336 case IMAGE_AMD64_UWOP_RESERVED_7: 337 AssertFailedReturn(false); 338 339 default: 340 AssertMsgFailedReturn(("%u\n", pInfo->aOpcodes[iOpcode].u.UnwindOp), false); 484 } 485 } 486 else 487 { 488 /* 489 * We're in the POP sequence of an epilog. The POP sequence should 490 * mirror the PUSH sequence exactly. 491 * 492 * Note! We should only end up here for the initial frame (just consider 493 * RSP, stack allocations, non-volatile register restores, ++). 494 */ 495 while (iOpcode < cOpcodes) 496 { 497 switch (pInfo->aOpcodes[iOpcode].u.UnwindOp) 498 { 499 case IMAGE_AMD64_UWOP_PUSH_NONVOL: 500 pUnwindCtx->m_auRegs[X86_GREG_xSP] += 8; 501 if (offEpilog == 0) 502 dbgfR3UnwindCtxLoadU64(pUnwindCtx, pUnwindCtx->m_auRegs[X86_GREG_xSP], 503 &pUnwindCtx->m_auRegs[pInfo->aOpcodes[iOpcode].u.OpInfo]); 504 else 505 { 506 /* Decrement offEpilog by estimated POP instruction length. */ 507 offEpilog -= 1; 508 if (offEpilog > 0 && pInfo->aOpcodes[iOpcode].u.OpInfo >= 8) 509 offEpilog -= 1; 510 } 511 iOpcode++; 512 break; 513 514 case IMAGE_AMD64_UWOP_PUSH_MACHFRAME: /* Must terminate an epilog, so always execute this. */ 515 return dbgfR3UnwindCtxDoOneIRet(pUnwindCtx, pInfo->aOpcodes[iOpcode].u.OpInfo, pAddrFrame, penmRetType); 516 517 case IMAGE_AMD64_UWOP_ALLOC_SMALL: 518 case IMAGE_AMD64_UWOP_SET_FPREG: 519 case IMAGE_AMD64_UWOP_EPILOG: 520 iOpcode++; 521 break; 522 case IMAGE_AMD64_UWOP_SAVE_NONVOL: 523 case IMAGE_AMD64_UWOP_SAVE_XMM128: 524 iOpcode += 2; 525 break; 526 case IMAGE_AMD64_UWOP_ALLOC_LARGE: 527 case IMAGE_AMD64_UWOP_SAVE_NONVOL_FAR: 528 case IMAGE_AMD64_UWOP_SAVE_XMM128_FAR: 529 iOpcode += 3; 530 break; 531 532 default: 533 AssertMsgFailedReturn(("%u\n", pInfo->aOpcodes[iOpcode].u.UnwindOp), false); 534 } 341 535 } 342 536 } … … 347 541 if (!(pInfo->Flags & IMAGE_UNW_FLAGS_CHAININFO)) 348 542 break; 349 /** @todo impl chains. */ 350 break; 351 } 352 353 /** @todo do post processing. */ 543 ChainedEntry = *(PCIMAGE_RUNTIME_FUNCTION_ENTRY)&pInfo->aOpcodes[(cOpcodes + 1) & ~1]; 544 pEntry = &ChainedEntry; 545 AssertReturn(cChainLoops < 32, false); 546 } 547 548 /* 549 * RSP should now give us the return address, so perform a RET. 550 */ 551 *penmRetType = DBGFRETURNTYPE_NEAR64; 552 DBGFR3AddrFromFlat(pUnwindCtx->m_pUVM, pAddrFrame, 553 pUnwindCtx->m_auRegs[X86_GREG_xSP] - /* pretend rbp is pushed on the stack */ 8); 554 555 dbgfR3UnwindCtxLoadU64(pUnwindCtx, pUnwindCtx->m_auRegs[X86_GREG_xSP], &pUnwindCtx->m_uPc); 556 pUnwindCtx->m_auRegs[X86_GREG_xSP] += 8; 557 return true; 354 558 } 355 559 … … 359 563 360 564 361 static bool dbgfR3UnwindCtxDoOneFrame(PDBGFUNWINDCTX pUnwindCtx, PDBGFADDRESS pAddrFrame) 565 /** 566 * Tries to unwind one frame using unwind info. 567 * 568 * @returns true on success, false on failure. 569 * @param pUnwindCtx The unwind context. 570 * @param pAddrFrame Where to return the frame pointer. 571 * @param penmRetType Where to return the return type. 572 */ 573 static bool dbgfR3UnwindCtxDoOneFrame(PDBGFUNWINDCTX pUnwindCtx, PDBGFADDRESS pAddrFrame, DBGFRETURNTYPE *penmRetType) 362 574 { 363 575 /* … … 366 578 RTUINTPTR offCache = pUnwindCtx->m_uPc - pUnwindCtx->m_uCachedMapping; 367 579 if (offCache < pUnwindCtx->m_cbCachedMapping) 368 return dbgfR3UnwindCtxDoOneFrameCached(pUnwindCtx, offCache, pAddrFrame );580 return dbgfR3UnwindCtxDoOneFrameCached(pUnwindCtx, offCache, pAddrFrame, penmRetType); 369 581 370 582 /* … … 381 593 pUnwindCtx->m_hCached = hDbgMod; 382 594 pUnwindCtx->m_uCachedMapping = uBase; 383 pUnwindCtx->m_cbCachedMapping = RTDbgModSegmentSize(hDbgMod, idxSeg); 595 pUnwindCtx->m_cbCachedMapping = idxSeg == NIL_RTDBGSEGIDX ? RTDbgModImageSize(hDbgMod) 596 : RTDbgModSegmentSize(hDbgMod, idxSeg); 384 597 385 598 /* Play simple for now. */ 386 599 if ( idxSeg == NIL_RTDBGSEGIDX 387 && RTDbgModImageGetFormat(hDbgMod) == RTLDRFMT_ 32BIT_HACK /// @todo RTLDRFMT_PE (disabled code)600 && RTDbgModImageGetFormat(hDbgMod) == RTLDRFMT_PE 388 601 && RTDbgModImageGetArch(hDbgMod) == RTLDRARCH_AMD64) 389 602 { … … 391 604 * Try query the unwind data. 392 605 */ 606 uint32_t uDummy; 393 607 size_t cbNeeded = 0; 394 rc = RTDbgModImageQueryProp(hDbgMod, RTLDRPROP_UNWIND_TABLE, NULL, 0, &cbNeeded);608 rc = RTDbgModImageQueryProp(hDbgMod, RTLDRPROP_UNWIND_TABLE, &uDummy, 0, &cbNeeded); 395 609 if ( rc == VERR_BUFFER_OVERFLOW 396 610 && cbNeeded >= sizeof(*pUnwindCtx->m_paFunctions) … … 400 614 if (pvBuf) 401 615 { 402 rc = RTDbgModImageQueryProp(hDbgMod, RTLDRPROP_UNWIND_TABLE, p UnwindCtx->m_pbCachedInfo, cbNeeded, &cbNeeded);616 rc = RTDbgModImageQueryProp(hDbgMod, RTLDRPROP_UNWIND_TABLE, pvBuf, cbNeeded + 32, &cbNeeded); 403 617 if (RT_SUCCESS(rc)) 404 618 { … … 409 623 410 624 return dbgfR3UnwindCtxDoOneFrameCached(pUnwindCtx, pUnwindCtx->m_uPc - pUnwindCtx->m_uCachedMapping, 411 pAddrFrame );625 pAddrFrame, penmRetType); 412 626 } 413 627 RTMemFree(pvBuf); … … 458 672 * 4 return address 459 673 * 0 old ebp; current ebp points here 460 * 461 * @todo Add AMD64 support (needs teaming up with the module management for 462 * unwind tables). 463 */ 464 DECL_NO_INLINE(static, int) dbgfR3StackWalk(PUVM pUVM, VMCPUID idCpu, RTDBGAS hAs, PDBGFSTACKFRAME pFrame) 674 */ 675 DECL_NO_INLINE(static, int) dbgfR3StackWalk(PDBGFUNWINDCTX pUnwindCtx, PDBGFSTACKFRAME pFrame, bool fFirst) 465 676 { 466 677 /* … … 471 682 472 683 /* 473 * Read the raw frame data. 474 * We double cbRetAddr in case we find we have a far return. 475 */ 476 const DBGFADDRESS AddrOldPC = pFrame->AddrPC; 477 unsigned cbRetAddr = DBGFReturnTypeSize(pFrame->enmReturnType); 478 unsigned cbStackItem; 479 switch (AddrOldPC.fFlags & DBGFADDRESS_FLAGS_TYPE_MASK) 684 * Advance the frame (except for the first). 685 */ 686 if (!fFirst) /** @todo we can probably eliminate this fFirst business... */ 687 { 688 /* frame, pc and stack is taken from the existing frames return members. */ 689 pFrame->AddrFrame = pFrame->AddrReturnFrame; 690 pFrame->AddrPC = pFrame->AddrReturnPC; 691 pFrame->pSymPC = pFrame->pSymReturnPC; 692 pFrame->pLinePC = pFrame->pLineReturnPC; 693 694 /* increment the frame number. */ 695 pFrame->iFrame++; 696 697 /* UNWIND_INFO_RET -> USED_UNWIND; return type */ 698 if (!(pFrame->fFlags & DBGFSTACKFRAME_FLAGS_UNWIND_INFO_RET)) 699 pFrame->fFlags &= ~DBGFSTACKFRAME_FLAGS_USED_UNWIND_INFO; 700 else 701 { 702 pFrame->fFlags |= DBGFSTACKFRAME_FLAGS_USED_UNWIND_INFO; 703 pFrame->fFlags &= ~DBGFSTACKFRAME_FLAGS_UNWIND_INFO_RET; 704 if (pFrame->enmReturnFrameReturnType != DBGFRETURNTYPE_INVALID) 705 { 706 pFrame->enmReturnType = pFrame->enmReturnFrameReturnType; 707 pFrame->enmReturnFrameReturnType = DBGFRETURNTYPE_INVALID; 708 } 709 } 710 } 711 712 /* 713 * Figure the return address size and use the old PC to guess stack item size. 714 */ 715 /** @todo this is bogus... */ 716 unsigned cbRetAddr = DBGFReturnTypeSize(pFrame->enmReturnType); 717 unsigned cbStackItem; 718 switch (pFrame->AddrPC.fFlags & DBGFADDRESS_FLAGS_TYPE_MASK) 480 719 { 481 720 case DBGFADDRESS_FLAGS_FAR16: cbStackItem = 2; break; … … 507 746 } 508 747 748 /* 749 * Read the raw frame data. 750 * We double cbRetAddr in case we have a far return. 751 */ 509 752 union 510 753 { … … 522 765 523 766 Assert(DBGFADDRESS_IS_VALID(&pFrame->AddrFrame)); 524 int rc = dbgfR3StackRead(pUVM, idCpu, u.pv, 525 pFrame->fFlags & DBGFSTACKFRAME_FLAGS_ALL_VALID 526 ? &pFrame->AddrReturnFrame 527 : &pFrame->AddrFrame, 528 cbRead, &cbRead); 529 if ( RT_FAILURE(rc) 530 || cbRead < cbRetAddr + cbStackItem) 767 int rc = dbgfR3StackRead(pUnwindCtx->m_pUVM, pUnwindCtx->m_idCpu, u.pv, &pFrame->AddrFrame, cbRead, &cbRead); 768 if ( RT_FAILURE(rc) 769 || cbRead < cbRetAddr + cbStackItem) 531 770 pFrame->fFlags |= DBGFSTACKFRAME_FLAGS_LAST; 532 771 533 772 /* 534 * The first step is taken in a different way than the others.535 */536 if (!(pFrame->fFlags & DBGFSTACKFRAME_FLAGS_ALL_VALID))537 {538 pFrame->fFlags |= DBGFSTACKFRAME_FLAGS_ALL_VALID;539 pFrame->iFrame = 0;540 541 /* Current PC - set by caller, just find symbol & line. */542 if (DBGFADDRESS_IS_VALID(&pFrame->AddrPC))543 {544 pFrame->pSymPC = DBGFR3AsSymbolByAddrA(pUVM, hAs, &pFrame->AddrPC,545 RTDBGSYMADDR_FLAGS_LESS_OR_EQUAL | RTDBGSYMADDR_FLAGS_SKIP_ABS_IN_DEFERRED,546 NULL /*poffDisp*/, NULL /*phMod*/);547 pFrame->pLinePC = DBGFR3AsLineByAddrA(pUVM, hAs, &pFrame->AddrPC, NULL /*poffDisp*/, NULL /*phMod*/);548 }549 }550 else /* 2nd and subsequent steps */551 {552 /* frame, pc and stack is taken from the existing frames return members. */553 pFrame->AddrFrame = pFrame->AddrReturnFrame;554 pFrame->AddrPC = pFrame->AddrReturnPC;555 pFrame->pSymPC = pFrame->pSymReturnPC;556 pFrame->pLinePC = pFrame->pLineReturnPC;557 558 /* increment the frame number. */559 pFrame->iFrame++;560 }561 562 /*563 773 * Return Frame address. 774 * 775 * If we used unwind info to get here, the unwind register context will be 776 * positioned after the return instruction has been executed. We start by 777 * picking up the rBP register here for return frame and will try improve 778 * on it further down by using unwind info. 564 779 */ 565 780 pFrame->AddrReturnFrame = pFrame->AddrFrame; 566 switch (cbStackItem) 567 { 568 case 2: pFrame->AddrReturnFrame.off = *uBp.pu16; break; 569 case 4: pFrame->AddrReturnFrame.off = *uBp.pu32; break; 570 case 8: pFrame->AddrReturnFrame.off = *uBp.pu64; break; 571 default: AssertMsgFailedReturn(("cbStackItem=%d\n", cbStackItem), VERR_DBGF_STACK_IPE_1); 572 } 573 574 /* Watcom tries to keep the frame pointer odd for far returns. */ 575 if (cbStackItem <= 4) 576 { 577 if (pFrame->AddrReturnFrame.off & 1) 578 { 579 pFrame->AddrReturnFrame.off &= ~(RTGCUINTPTR)1; 580 if (pFrame->enmReturnType == DBGFRETURNTYPE_NEAR16) 581 { 582 pFrame->fFlags |= DBGFSTACKFRAME_FLAGS_USED_ODD_EVEN; 583 pFrame->enmReturnType = DBGFRETURNTYPE_FAR16; 584 cbRetAddr = 4; 781 if (pFrame->fFlags & DBGFSTACKFRAME_FLAGS_USED_UNWIND_INFO) 782 { 783 if ( pFrame->enmReturnType == DBGFRETURNTYPE_IRET32_PRIV 784 && pFrame->enmReturnType == DBGFRETURNTYPE_IRET64) 785 DBGFR3AddrFromSelOff(pUnwindCtx->m_pUVM, pUnwindCtx->m_idCpu, &pFrame->AddrReturnFrame, 786 pUnwindCtx->m_uSs, pUnwindCtx->m_auRegs[X86_GREG_xBP]); 787 else if (pFrame->enmReturnType == DBGFRETURNTYPE_IRET32_V86) 788 DBGFR3AddrFromFlat(pUnwindCtx->m_pUVM, &pFrame->AddrReturnFrame, 789 ((uint32_t)pUnwindCtx->m_uSs << 4) + pUnwindCtx->m_auRegs[X86_GREG_xBP]); 790 else 791 { 792 pFrame->AddrReturnFrame.off = pUnwindCtx->m_auRegs[X86_GREG_xBP]; 793 pFrame->AddrReturnFrame.FlatPtr += pFrame->AddrReturnFrame.off - pFrame->AddrFrame.off; 794 } 795 } 796 else 797 { 798 switch (cbStackItem) 799 { 800 case 2: pFrame->AddrReturnFrame.off = *uBp.pu16; break; 801 case 4: pFrame->AddrReturnFrame.off = *uBp.pu32; break; 802 case 8: pFrame->AddrReturnFrame.off = *uBp.pu64; break; 803 default: AssertMsgFailedReturn(("cbStackItem=%d\n", cbStackItem), VERR_DBGF_STACK_IPE_1); 804 } 805 806 /* Watcom tries to keep the frame pointer odd for far returns. */ 807 if ( cbStackItem <= 4 808 && !(pFrame->fFlags & DBGFSTACKFRAME_FLAGS_USED_UNWIND_INFO)) 809 { 810 if (pFrame->AddrReturnFrame.off & 1) 811 { 812 pFrame->AddrReturnFrame.off &= ~(RTGCUINTPTR)1; 813 if (pFrame->enmReturnType == DBGFRETURNTYPE_NEAR16) 814 { 815 pFrame->fFlags |= DBGFSTACKFRAME_FLAGS_USED_ODD_EVEN; 816 pFrame->enmReturnType = DBGFRETURNTYPE_FAR16; 817 cbRetAddr = 4; 818 } 819 else if (pFrame->enmReturnType == DBGFRETURNTYPE_NEAR32) 820 { 821 pFrame->fFlags |= DBGFSTACKFRAME_FLAGS_USED_ODD_EVEN; 822 pFrame->enmReturnType = DBGFRETURNTYPE_FAR32; 823 cbRetAddr = 8; 824 } 585 825 } 586 else if (pFrame->enmReturnType == DBGFRETURNTYPE_NEAR32) 587 { 588 pFrame->fFlags |= DBGFSTACKFRAME_FLAGS_USED_ODD_EVEN; 589 pFrame->enmReturnType = DBGFRETURNTYPE_FAR32; 590 cbRetAddr = 8; 826 else if (pFrame->fFlags & DBGFSTACKFRAME_FLAGS_USED_ODD_EVEN) 827 { 828 if (pFrame->enmReturnType == DBGFRETURNTYPE_FAR16) 829 { 830 pFrame->enmReturnType = DBGFRETURNTYPE_NEAR16; 831 cbRetAddr = 2; 832 } 833 else if (pFrame->enmReturnType == DBGFRETURNTYPE_NEAR32) 834 { 835 pFrame->enmReturnType = DBGFRETURNTYPE_FAR32; 836 cbRetAddr = 4; 837 } 838 pFrame->fFlags &= ~DBGFSTACKFRAME_FLAGS_USED_ODD_EVEN; 591 839 } 592 } 593 else if (pFrame->fFlags & DBGFSTACKFRAME_FLAGS_USED_ODD_EVEN) 594 { 595 if (pFrame->enmReturnType == DBGFRETURNTYPE_FAR16) 596 { 597 pFrame->enmReturnType = DBGFRETURNTYPE_NEAR16; 598 cbRetAddr = 2; 599 } 600 else if (pFrame->enmReturnType == DBGFRETURNTYPE_NEAR32) 601 { 602 pFrame->enmReturnType = DBGFRETURNTYPE_FAR32; 603 cbRetAddr = 4; 604 } 605 pFrame->fFlags &= ~DBGFSTACKFRAME_FLAGS_USED_ODD_EVEN; 606 } 607 uArgs.pb = u.pb + cbStackItem + cbRetAddr; 608 } 609 610 pFrame->AddrReturnFrame.FlatPtr += pFrame->AddrReturnFrame.off - pFrame->AddrFrame.off; 611 612 /* 613 * Return PC and Stack Addresses. 614 */ 615 /** @todo AddrReturnStack is not correct for stdcall and pascal. (requires scope info) */ 616 pFrame->AddrReturnStack = pFrame->AddrFrame; 617 pFrame->AddrReturnStack.off += cbStackItem + cbRetAddr; 618 pFrame->AddrReturnStack.FlatPtr += cbStackItem + cbRetAddr; 619 620 pFrame->AddrReturnPC = pFrame->AddrPC; 621 switch (pFrame->enmReturnType) 622 { 623 case DBGFRETURNTYPE_NEAR16: 624 if (DBGFADDRESS_IS_VALID(&pFrame->AddrReturnPC)) 625 { 626 pFrame->AddrReturnPC.FlatPtr += *uRet.pu16 - pFrame->AddrReturnPC.off; 627 pFrame->AddrReturnPC.off = *uRet.pu16; 628 } 629 else 630 DBGFR3AddrFromFlat(pUVM, &pFrame->AddrReturnPC, *uRet.pu16); 631 break; 632 case DBGFRETURNTYPE_NEAR32: 633 if (DBGFADDRESS_IS_VALID(&pFrame->AddrReturnPC)) 634 { 635 pFrame->AddrReturnPC.FlatPtr += *uRet.pu32 - pFrame->AddrReturnPC.off; 636 pFrame->AddrReturnPC.off = *uRet.pu32; 637 } 638 else 639 DBGFR3AddrFromFlat(pUVM, &pFrame->AddrReturnPC, *uRet.pu32); 640 break; 641 case DBGFRETURNTYPE_NEAR64: 642 if (DBGFADDRESS_IS_VALID(&pFrame->AddrReturnPC)) 643 { 644 pFrame->AddrReturnPC.FlatPtr += *uRet.pu64 - pFrame->AddrReturnPC.off; 645 pFrame->AddrReturnPC.off = *uRet.pu64; 646 } 647 else 648 DBGFR3AddrFromFlat(pUVM, &pFrame->AddrReturnPC, *uRet.pu64); 649 break; 650 case DBGFRETURNTYPE_FAR16: 651 DBGFR3AddrFromSelOff(pUVM, idCpu, &pFrame->AddrReturnPC, uRet.pu16[1], uRet.pu16[0]); 652 break; 653 case DBGFRETURNTYPE_FAR32: 654 DBGFR3AddrFromSelOff(pUVM, idCpu, &pFrame->AddrReturnPC, uRet.pu16[2], uRet.pu32[0]); 655 break; 656 case DBGFRETURNTYPE_FAR64: 657 DBGFR3AddrFromSelOff(pUVM, idCpu, &pFrame->AddrReturnPC, uRet.pu16[4], uRet.pu64[0]); 658 break; 659 case DBGFRETURNTYPE_IRET16: 660 DBGFR3AddrFromSelOff(pUVM, idCpu, &pFrame->AddrReturnPC, uRet.pu16[1], uRet.pu16[0]); 661 break; 662 case DBGFRETURNTYPE_IRET32: 663 DBGFR3AddrFromSelOff(pUVM, idCpu, &pFrame->AddrReturnPC, uRet.pu16[2], uRet.pu32[0]); 664 break; 665 case DBGFRETURNTYPE_IRET32_PRIV: 666 DBGFR3AddrFromSelOff(pUVM, idCpu, &pFrame->AddrReturnPC, uRet.pu16[2], uRet.pu32[0]); 667 break; 668 case DBGFRETURNTYPE_IRET32_V86: 669 DBGFR3AddrFromSelOff(pUVM, idCpu, &pFrame->AddrReturnPC, uRet.pu16[2], uRet.pu32[0]); 670 break; 671 case DBGFRETURNTYPE_IRET64: 672 DBGFR3AddrFromSelOff(pUVM, idCpu, &pFrame->AddrReturnPC, uRet.pu16[4], uRet.pu64[0]); 673 break; 674 default: 675 AssertMsgFailed(("enmReturnType=%d\n", pFrame->enmReturnType)); 676 return VERR_INVALID_PARAMETER; 677 } 678 679 pFrame->pSymReturnPC = DBGFR3AsSymbolByAddrA(pUVM, hAs, &pFrame->AddrReturnPC, 840 uArgs.pb = u.pb + cbStackItem + cbRetAddr; 841 } 842 843 pFrame->AddrReturnFrame.FlatPtr += pFrame->AddrReturnFrame.off - pFrame->AddrFrame.off; 844 } 845 846 /* 847 * Return Stack Address. 848 */ 849 pFrame->AddrReturnStack = pFrame->AddrReturnFrame; 850 if (pFrame->fFlags & DBGFSTACKFRAME_FLAGS_USED_UNWIND_INFO) 851 { 852 if ( pFrame->enmReturnType == DBGFRETURNTYPE_IRET32_PRIV 853 && pFrame->enmReturnType == DBGFRETURNTYPE_IRET64) 854 DBGFR3AddrFromSelOff(pUnwindCtx->m_pUVM, pUnwindCtx->m_idCpu, &pFrame->AddrReturnStack, 855 pUnwindCtx->m_uSs, pUnwindCtx->m_auRegs[X86_GREG_xSP]); 856 else if (pFrame->enmReturnType == DBGFRETURNTYPE_IRET32_V86) 857 DBGFR3AddrFromFlat(pUnwindCtx->m_pUVM, &pFrame->AddrReturnStack, 858 ((uint32_t)pUnwindCtx->m_uSs << 4) + pUnwindCtx->m_auRegs[X86_GREG_xSP]); 859 else 860 { 861 pFrame->AddrReturnStack.off = pUnwindCtx->m_auRegs[X86_GREG_xSP]; 862 pFrame->AddrReturnStack.FlatPtr += pFrame->AddrReturnStack.off - pFrame->AddrStack.off; 863 } 864 } 865 else 866 { 867 pFrame->AddrReturnStack.off += cbStackItem + cbRetAddr; 868 pFrame->AddrReturnStack.FlatPtr += cbStackItem + cbRetAddr; 869 } 870 871 /* 872 * Return PC. 873 */ 874 pFrame->AddrReturnPC = pFrame->AddrPC; 875 if (pFrame->fFlags & DBGFSTACKFRAME_FLAGS_USED_UNWIND_INFO) 876 { 877 if (DBGFReturnTypeIsNear(pFrame->enmReturnType)) 878 { 879 pFrame->AddrReturnPC.off = pUnwindCtx->m_uPc; 880 pFrame->AddrReturnPC.FlatPtr += pFrame->AddrReturnPC.off - pFrame->AddrPC.off; 881 } 882 else 883 DBGFR3AddrFromSelOff(pUnwindCtx->m_pUVM, pUnwindCtx->m_idCpu, &pFrame->AddrReturnPC, 884 pUnwindCtx->m_uCs, pUnwindCtx->m_uPc); 885 } 886 else 887 switch (pFrame->enmReturnType) 888 { 889 case DBGFRETURNTYPE_NEAR16: 890 if (DBGFADDRESS_IS_VALID(&pFrame->AddrReturnPC)) 891 { 892 pFrame->AddrReturnPC.FlatPtr += *uRet.pu16 - pFrame->AddrReturnPC.off; 893 pFrame->AddrReturnPC.off = *uRet.pu16; 894 } 895 else 896 DBGFR3AddrFromFlat(pUnwindCtx->m_pUVM, &pFrame->AddrReturnPC, *uRet.pu16); 897 break; 898 case DBGFRETURNTYPE_NEAR32: 899 if (DBGFADDRESS_IS_VALID(&pFrame->AddrReturnPC)) 900 { 901 pFrame->AddrReturnPC.FlatPtr += *uRet.pu32 - pFrame->AddrReturnPC.off; 902 pFrame->AddrReturnPC.off = *uRet.pu32; 903 } 904 else 905 DBGFR3AddrFromFlat(pUnwindCtx->m_pUVM, &pFrame->AddrReturnPC, *uRet.pu32); 906 break; 907 case DBGFRETURNTYPE_NEAR64: 908 if (DBGFADDRESS_IS_VALID(&pFrame->AddrReturnPC)) 909 { 910 pFrame->AddrReturnPC.FlatPtr += *uRet.pu64 - pFrame->AddrReturnPC.off; 911 pFrame->AddrReturnPC.off = *uRet.pu64; 912 } 913 else 914 DBGFR3AddrFromFlat(pUnwindCtx->m_pUVM, &pFrame->AddrReturnPC, *uRet.pu64); 915 break; 916 case DBGFRETURNTYPE_FAR16: 917 DBGFR3AddrFromSelOff(pUnwindCtx->m_pUVM, pUnwindCtx->m_idCpu, &pFrame->AddrReturnPC, uRet.pu16[1], uRet.pu16[0]); 918 break; 919 case DBGFRETURNTYPE_FAR32: 920 DBGFR3AddrFromSelOff(pUnwindCtx->m_pUVM, pUnwindCtx->m_idCpu, &pFrame->AddrReturnPC, uRet.pu16[2], uRet.pu32[0]); 921 break; 922 case DBGFRETURNTYPE_FAR64: 923 DBGFR3AddrFromSelOff(pUnwindCtx->m_pUVM, pUnwindCtx->m_idCpu, &pFrame->AddrReturnPC, uRet.pu16[4], uRet.pu64[0]); 924 break; 925 case DBGFRETURNTYPE_IRET16: 926 DBGFR3AddrFromSelOff(pUnwindCtx->m_pUVM, pUnwindCtx->m_idCpu, &pFrame->AddrReturnPC, uRet.pu16[1], uRet.pu16[0]); 927 break; 928 case DBGFRETURNTYPE_IRET32: 929 DBGFR3AddrFromSelOff(pUnwindCtx->m_pUVM, pUnwindCtx->m_idCpu, &pFrame->AddrReturnPC, uRet.pu16[2], uRet.pu32[0]); 930 break; 931 case DBGFRETURNTYPE_IRET32_PRIV: 932 DBGFR3AddrFromSelOff(pUnwindCtx->m_pUVM, pUnwindCtx->m_idCpu, &pFrame->AddrReturnPC, uRet.pu16[2], uRet.pu32[0]); 933 break; 934 case DBGFRETURNTYPE_IRET32_V86: 935 DBGFR3AddrFromSelOff(pUnwindCtx->m_pUVM, pUnwindCtx->m_idCpu, &pFrame->AddrReturnPC, uRet.pu16[2], uRet.pu32[0]); 936 break; 937 case DBGFRETURNTYPE_IRET64: 938 DBGFR3AddrFromSelOff(pUnwindCtx->m_pUVM, pUnwindCtx->m_idCpu, &pFrame->AddrReturnPC, uRet.pu16[4], uRet.pu64[0]); 939 break; 940 default: 941 AssertMsgFailed(("enmReturnType=%d\n", pFrame->enmReturnType)); 942 return VERR_INVALID_PARAMETER; 943 } 944 945 946 pFrame->pSymReturnPC = DBGFR3AsSymbolByAddrA(pUnwindCtx->m_pUVM, pUnwindCtx->m_hAs, &pFrame->AddrReturnPC, 680 947 RTDBGSYMADDR_FLAGS_LESS_OR_EQUAL | RTDBGSYMADDR_FLAGS_SKIP_ABS_IN_DEFERRED, 681 948 NULL /*poffDisp*/, NULL /*phMod*/); 682 pFrame->pLineReturnPC = DBGFR3AsLineByAddrA(pUVM, hAs, &pFrame->AddrReturnPC, NULL /*poffDisp*/, NULL /*phMod*/); 949 pFrame->pLineReturnPC = DBGFR3AsLineByAddrA(pUnwindCtx->m_pUVM, pUnwindCtx->m_hAs, &pFrame->AddrReturnPC, 950 NULL /*poffDisp*/, NULL /*phMod*/); 683 951 684 952 /* 685 953 * Frame bitness flag. 686 954 */ 955 /** @todo use previous return type for this? */ 956 pFrame->fFlags &= ~(DBGFSTACKFRAME_FLAGS_16BIT | DBGFSTACKFRAME_FLAGS_32BIT | DBGFSTACKFRAME_FLAGS_64BIT); 687 957 switch (cbStackItem) 688 958 { … … 697 967 */ 698 968 memcpy(&pFrame->Args, uArgs.pv, sizeof(pFrame->Args)); 969 970 /* 971 * Try use unwind information to locate the return frame pointer (for the 972 * next loop iteration). 973 */ 974 Assert(!(pFrame->fFlags & DBGFSTACKFRAME_FLAGS_UNWIND_INFO_RET)); 975 pFrame->enmReturnFrameReturnType = DBGFRETURNTYPE_INVALID; 976 if (!(pFrame->fFlags & DBGFSTACKFRAME_FLAGS_LAST)) 977 { 978 /* Set PC and SP if we didn't unwind our way here (context will then point 979 and the return PC and SP already). */ 980 if (!(pFrame->fFlags & DBGFSTACKFRAME_FLAGS_USED_UNWIND_INFO)) 981 { 982 dbgfR3UnwindCtxSetPcAndSp(pUnwindCtx, &pFrame->AddrReturnPC, &pFrame->AddrReturnStack); 983 } 984 /** @todo Reevaluate CS if the previous frame return type isn't near. */ 985 986 DBGFADDRESS AddrReturnFrame = pFrame->AddrReturnFrame; 987 DBGFRETURNTYPE enmReturnType = pFrame->enmReturnType; 988 if (dbgfR3UnwindCtxDoOneFrame(pUnwindCtx, &AddrReturnFrame, &enmReturnType)) 989 { 990 pFrame->fFlags |= DBGFSTACKFRAME_FLAGS_UNWIND_INFO_RET; 991 pFrame->AddrReturnFrame = AddrReturnFrame; 992 pFrame->enmReturnFrameReturnType = enmReturnType; 993 } 994 } 699 995 700 996 return VINF_SUCCESS; … … 793 1089 rc = DBGFR3AddrFromSelOff(pUVM, idCpu, &pCur->AddrStack, pCtx->ss.Sel, pCtx->rsp & fAddrMask); 794 1090 1091 Assert(!(pCur->fFlags & DBGFSTACKFRAME_FLAGS_USED_UNWIND_INFO)); 795 1092 if (pAddrFrame) 796 1093 pCur->AddrFrame = *pAddrFrame; 797 else 798 { 799 if ( RT_SUCCESS(rc) 800 && dbgfR3UnwindCtxSetPcAndSp(&UnwindCtx, &pCur->AddrPC, &pCur->AddrStack) 801 && dbgfR3UnwindCtxDoOneFrame(&UnwindCtx, &pCur->AddrFrame)) 802 { } 803 else if (enmCodeType != DBGFCODETYPE_GUEST) 804 DBGFR3AddrFromFlat(pUVM, &pCur->AddrFrame, pCtx->rbp & fAddrMask); 805 else if (RT_SUCCESS(rc)) 806 rc = DBGFR3AddrFromSelOff(pUVM, idCpu, &pCur->AddrFrame, pCtx->ss.Sel, pCtx->rbp & fAddrMask); 1094 else if ( RT_SUCCESS(rc) 1095 && dbgfR3UnwindCtxSetPcAndSp(&UnwindCtx, &pCur->AddrPC, &pCur->AddrStack) 1096 && dbgfR3UnwindCtxDoOneFrame(&UnwindCtx, &pCur->AddrFrame, &pCur->enmReturnType)) 1097 { 1098 pCur->fFlags |= DBGFSTACKFRAME_FLAGS_USED_UNWIND_INFO; 1099 } 1100 else if (enmCodeType != DBGFCODETYPE_GUEST) 1101 DBGFR3AddrFromFlat(pUVM, &pCur->AddrFrame, pCtx->rbp & fAddrMask); 1102 else if (RT_SUCCESS(rc)) 1103 rc = DBGFR3AddrFromSelOff(pUVM, idCpu, &pCur->AddrFrame, pCtx->ss.Sel, pCtx->rbp & fAddrMask); 1104 1105 /* 1106 * The first frame. 1107 */ 1108 if (RT_SUCCESS(rc)) 1109 { 1110 if (DBGFADDRESS_IS_VALID(&pCur->AddrPC)) 1111 { 1112 pCur->pSymPC = DBGFR3AsSymbolByAddrA(pUVM, hAs, &pCur->AddrPC, 1113 RTDBGSYMADDR_FLAGS_LESS_OR_EQUAL | RTDBGSYMADDR_FLAGS_SKIP_ABS_IN_DEFERRED, 1114 NULL /*poffDisp*/, NULL /*phMod*/); 1115 pCur->pLinePC = DBGFR3AsLineByAddrA(pUVM, hAs, &pCur->AddrPC, NULL /*poffDisp*/, NULL /*phMod*/); 1116 } 1117 1118 rc = dbgfR3StackWalk(&UnwindCtx, pCur, true /*fFirst*/); 807 1119 } 808 1120 } 809 1121 else 810 1122 pCur->enmReturnType = enmReturnType; 811 812 /*813 * The first frame.814 */815 if (RT_SUCCESS(rc))816 rc = dbgfR3StackWalk(pUVM, idCpu, hAs, pCur);817 1123 if (RT_FAILURE(rc)) 818 1124 { … … 828 1134 { 829 1135 /* try walk. */ 830 rc = dbgfR3StackWalk( pUVM, idCpu, hAs, &Next);1136 rc = dbgfR3StackWalk(&UnwindCtx, &Next, false /*fFirst*/); 831 1137 if (RT_FAILURE(rc)) 832 1138 break;
Note:
See TracChangeset
for help on using the changeset viewer.