/** * Query a symbol by name. * * The symbol can be prefixed by a module name pattern to scope the search. The * pattern is a simple string pattern with '*' and '?' as wild chars. See * RTStrSimplePatternMatch(). * * @returns VBox status code. See RTDbgAsSymbolByAddr. * * @param pUVM The user mode VM handle. * @param hDbgAs The address space handle. * @param pszSymbol The symbol to search for, maybe prefixed by a * module pattern. * @param pSymbol Where to return the symbol information. * The returned symbol name will be prefixed by * the module name as far as space allows. * @param phMod Where to return the module handle. Optional. */ VMMR3DECL(int) DBGFR3AsSymbolByName(PUVM pUVM, RTDBGAS hDbgAs, const char *pszSymbol, PRTDBGSYMBOL pSymbol, PRTDBGMOD phMod) { /* * Implement the special address space aliases the lazy way. */ if (hDbgAs == DBGF_AS_RC_AND_GC_GLOBAL) { int rc = DBGFR3AsSymbolByName(pUVM, DBGF_AS_RC, pszSymbol, pSymbol, phMod); if (RT_FAILURE(rc)) rc = DBGFR3AsSymbolByName(pUVM, DBGF_AS_GLOBAL, pszSymbol, pSymbol, phMod); return rc; } /* * Input validation. */ UVM_ASSERT_VALID_EXT_RETURN(pUVM, VERR_INVALID_VM_HANDLE); AssertPtrReturn(pSymbol, VERR_INVALID_POINTER); AssertPtrNullReturn(phMod, VERR_INVALID_POINTER); if (phMod) *phMod = NIL_RTDBGMOD; RTDBGAS hRealAS = DBGFR3AsResolveAndRetain(pUVM, hDbgAs); if (hRealAS == NIL_RTDBGAS) return VERR_INVALID_HANDLE; /* * Do the lookup. */ RTDBGMOD hMod; int rc = RTDbgAsSymbolByName(hRealAS, pszSymbol, pSymbol, &hMod); if (RT_SUCCESS(rc)) { dbgfR3AsSymbolJoinNames(pSymbol, hMod); if (!phMod) RTDbgModRelease(hMod); } /* Temporary conversion. */ else if (hDbgAs == DBGF_AS_GLOBAL) { DBGFSYMBOL DbgfSym; rc = DBGFR3SymbolByName(pUVM->pVM, pszSymbol, &DbgfSym); if (RT_SUCCESS(rc)) dbgfR3AsSymbolConvert(pSymbol, &DbgfSym); } return rc; }
/** * 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; }