/** * @interface_method_impl{DBGCCMDHLP,pfnVarFromDbgfAddr} */ static DECLCALLBACK(int) dbgcHlpVarFromDbgfAddr(PDBGCCMDHLP pCmdHlp, PCDBGFADDRESS pAddress, PDBGCVAR pResult) { AssertPtrReturn(pAddress, VERR_INVALID_POINTER); AssertReturn(DBGFADDRESS_IS_VALID(pAddress), VERR_INVALID_PARAMETER); AssertPtrReturn(pResult, VERR_INVALID_POINTER); switch (pAddress->fFlags & DBGFADDRESS_FLAGS_TYPE_MASK) { case DBGFADDRESS_FLAGS_FAR16: case DBGFADDRESS_FLAGS_FAR32: case DBGFADDRESS_FLAGS_FAR64: DBGCVAR_INIT_GC_FAR(pResult, pAddress->Sel, pAddress->off); break; case DBGFADDRESS_FLAGS_FLAT: DBGCVAR_INIT_GC_FLAT(pResult, pAddress->FlatPtr); break; case DBGFADDRESS_FLAGS_PHYS: DBGCVAR_INIT_GC_PHYS(pResult, pAddress->FlatPtr); break; default: DBGCVAR_INIT(pResult); AssertMsgFailedReturn(("%#x\n", pAddress->fFlags), VERR_INVALID_PARAMETER); break; } return VINF_SUCCESS; }
/** * Resolves a symbol (or tries to do so at least). * * @returns 0 on success. * @returns VBox status on failure. * @param pDbgc The debug console instance. * @param pszSymbol The symbol name. * @param enmType The result type. Specifying DBGCVAR_TYPE_GC_FAR may * cause failure, avoid it. * @param pResult Where to store the result. */ int dbgcSymbolGet(PDBGC pDbgc, const char *pszSymbol, DBGCVARTYPE enmType, PDBGCVAR pResult) { int rc; /* * Builtin? */ PCDBGCSYM pSymDesc = dbgcLookupRegisterSymbol(pDbgc, pszSymbol); if (pSymDesc) { if (!pSymDesc->pfnGet) return VERR_DBGC_PARSE_WRITEONLY_SYMBOL; return pSymDesc->pfnGet(pSymDesc, &pDbgc->CmdHlp, enmType, pResult); } /* * A typical register? (Guest only) */ static const char s_szSixLetterRegisters[] = "rflags;eflags;" ; static const char s_szThreeLetterRegisters[] = "eax;rax;" "r10;" "r8d;r8w;r8b;" "cr0;" "dr0;" "ebx;rbx;" "r11;" "r9d;r9w;r8b;" "dr1;" "ecx;rcx;" "r12;" "cr2;" "dr2;" "edx;rdx;" "r13;" "cr3;" "dr3;" "edi;rdi;dil;" "r14;" "cr4;" "dr4;" "esi;rsi;sil;" "r15;" "cr8;" "ebp;rbp;" "esp;rsp;" "dr6;" "rip;eip;" "dr7;" "efl;" ; static const char s_szTwoLetterRegisters[] = "ax;al;ah;" "r8;" "bx;bl;bh;" "r9;" "cx;cl;ch;" "cs;" "dx;dl;dh;" "ds;" "di;" "es;" "si;" "fs;" "bp;" "gs;" "sp;" "ss;" "ip;" ; size_t const cchSymbol = strlen(pszSymbol); if ( (cchSymbol == 2 && strstr(s_szTwoLetterRegisters, pszSymbol)) || (cchSymbol == 3 && strstr(s_szThreeLetterRegisters, pszSymbol)) || (cchSymbol == 6 && strstr(s_szSixLetterRegisters, pszSymbol))) { if (!strchr(pszSymbol, ';')) { DBGCVAR Var; DBGCVAR_INIT_SYMBOL(&Var, pszSymbol); rc = dbgcOpRegister(pDbgc, &Var, DBGCVAR_CAT_ANY, pResult); if (RT_SUCCESS(rc)) return DBGCCmdHlpConvert(&pDbgc->CmdHlp, pResult, enmType, false /*fConvSyms*/, pResult); } } /* * Ask PDM. */ /** @todo resolve symbols using PDM. */ /* * Ask the debug info manager. */ RTDBGSYMBOL Symbol; rc = DBGFR3AsSymbolByName(pDbgc->pVM, pDbgc->hDbgAs, pszSymbol, &Symbol, NULL); if (RT_SUCCESS(rc)) { /* * Default return is a flat gc address. */ DBGCVAR_INIT_GC_FLAT(pResult, Symbol.Value); if (Symbol.cb) DBGCVAR_SET_RANGE(pResult, DBGCVAR_RANGE_BYTES, Symbol.cb); switch (enmType) { /* nothing to do. */ case DBGCVAR_TYPE_GC_FLAT: case DBGCVAR_TYPE_ANY: return VINF_SUCCESS; /* impossible at the moment. */ case DBGCVAR_TYPE_GC_FAR: return VERR_DBGC_PARSE_CONVERSION_FAILED; /* simply make it numeric. */ case DBGCVAR_TYPE_NUMBER: pResult->enmType = DBGCVAR_TYPE_NUMBER; pResult->u.u64Number = Symbol.Value; return VINF_SUCCESS; /* cast it. */ case DBGCVAR_TYPE_GC_PHYS: case DBGCVAR_TYPE_HC_FLAT: case DBGCVAR_TYPE_HC_PHYS: return DBGCCmdHlpConvert(&pDbgc->CmdHlp, pResult, enmType, false /*fConvSyms*/, pResult); default: AssertMsgFailed(("Internal error enmType=%d\n", enmType)); return VERR_INVALID_PARAMETER; } } return VERR_DBGC_PARSE_NOT_IMPLEMENTED; }