/** * Initializes the tracing. * * @returns VBox status code * @param pVM The cross context VM structure. * @param cbEntry The trace entry size. * @param cEntries The number of entries. */ static int dbgfR3TraceEnable(PVM pVM, uint32_t cbEntry, uint32_t cEntries) { /* * Don't enable it twice. */ if (pVM->hTraceBufR3 != NIL_RTTRACEBUF) return VERR_ALREADY_EXISTS; /* * Resolve default parameter values. */ int rc; if (!cbEntry) { rc = CFGMR3QueryU32Def(CFGMR3GetChild(CFGMR3GetRoot(pVM), "DBGF"), "TraceBufEntrySize", &cbEntry, 128); AssertRCReturn(rc, rc); } if (!cEntries) { rc = CFGMR3QueryU32Def(CFGMR3GetChild(CFGMR3GetRoot(pVM), "DBGF"), "TraceBufEntries", &cEntries, 4096); AssertRCReturn(rc, rc); } /* * Figure the required size. */ RTTRACEBUF hTraceBuf; size_t cbBlock = 0; rc = RTTraceBufCarve(&hTraceBuf, cEntries, cbEntry, 0 /*fFlags*/, NULL, &cbBlock); if (rc != VERR_BUFFER_OVERFLOW) { AssertReturn(!RT_SUCCESS_NP(rc), VERR_IPE_UNEXPECTED_INFO_STATUS); return rc; } /* * Allocate a hyper heap block and carve a trace buffer out of it. * * Note! We ASSUME that the returned trace buffer handle has the same value * as the heap block. */ cbBlock = RT_ALIGN_Z(cbBlock, PAGE_SIZE); void *pvBlock; rc = MMR3HyperAllocOnceNoRel(pVM, cbBlock, PAGE_SIZE, MM_TAG_DBGF, &pvBlock); if (RT_FAILURE(rc)) return rc; rc = RTTraceBufCarve(&hTraceBuf, cEntries, cbEntry, 0 /*fFlags*/, pvBlock, &cbBlock); AssertRCReturn(rc, rc); AssertRelease(hTraceBuf == (RTTRACEBUF)pvBlock); AssertRelease((void *)hTraceBuf == pvBlock); pVM->hTraceBufR3 = hTraceBuf; pVM->hTraceBufR0 = MMHyperCCToR0(pVM, hTraceBuf); pVM->hTraceBufRC = MMHyperCCToRC(pVM, hTraceBuf); return VINF_SUCCESS; }
/** * Initialize the global 1 halt method. * * @return VBox status code. * @param pUVM Pointer to the user mode VM structure. */ static DECLCALLBACK(int) vmR3HaltGlobal1Init(PUVM pUVM) { /* * The defaults. */ uint32_t cNsResolution = SUPSemEventMultiGetResolution(pUVM->vm.s.pSession); if (cNsResolution > 5*RT_NS_100US) pUVM->vm.s.Halt.Global1.cNsSpinBlockThresholdCfg = 50000; else if (cNsResolution > RT_NS_100US) pUVM->vm.s.Halt.Global1.cNsSpinBlockThresholdCfg = cNsResolution / 4; else pUVM->vm.s.Halt.Global1.cNsSpinBlockThresholdCfg = 2000; /* * Query overrides. * * I don't have time to bother with niceties such as invalid value checks * here right now. sorry. */ PCFGMNODE pCfg = CFGMR3GetChild(CFGMR3GetRoot(pUVM->pVM), "/VMM/HaltedGlobal1"); if (pCfg) { uint32_t u32; if (RT_SUCCESS(CFGMR3QueryU32(pCfg, "SpinBlockThreshold", &u32))) pUVM->vm.s.Halt.Global1.cNsSpinBlockThresholdCfg = u32; } LogRel(("HaltedGlobal1 config: cNsSpinBlockThresholdCfg=%u\n", pUVM->vm.s.Halt.Global1.cNsSpinBlockThresholdCfg)); return VINF_SUCCESS; }
static void doGeneralTests(PCFGMNODE pRoot) { /* test multilevel node creation */ PCFGMNODE pChild = NULL; RTTESTI_CHECK_RC_RETV(CFGMR3InsertNode(pRoot, "First/Second/Third//Final", &pChild), VINF_SUCCESS); RTTESTI_CHECK_RETV(RT_VALID_PTR(pChild)); RTTESTI_CHECK(CFGMR3GetChild(pRoot, "First/Second/Third/Final") == pChild); /* * Boolean queries. */ RTTESTI_CHECK_RC(CFGMR3InsertInteger(pChild, "BoolValue", 1), VINF_SUCCESS); bool f = false; RTTESTI_CHECK_RC(CFGMR3QueryBool(pChild, "BoolValue", &f), VINF_SUCCESS); RTTESTI_CHECK(f == true); RTTESTI_CHECK_RC(CFGMR3QueryBool(pRoot, "BoolValue", &f), VERR_CFGM_VALUE_NOT_FOUND); RTTESTI_CHECK_RC(CFGMR3QueryBool(NULL, "BoolValue", &f), VERR_CFGM_NO_PARENT); RTTESTI_CHECK_RC(CFGMR3QueryBoolDef(pChild, "ValueNotFound", &f, true), VINF_SUCCESS); RTTESTI_CHECK(f == true); RTTESTI_CHECK_RC(CFGMR3QueryBoolDef(pChild, "ValueNotFound", &f, false), VINF_SUCCESS); RTTESTI_CHECK(f == false); RTTESTI_CHECK_RC(CFGMR3QueryBoolDef(NULL, "BoolValue", &f, true), VINF_SUCCESS); RTTESTI_CHECK(f == true); RTTESTI_CHECK_RC(CFGMR3QueryBoolDef(NULL, "BoolValue", &f, false), VINF_SUCCESS); RTTESTI_CHECK(f == false); }
tstVMMConfigConstructor(PVM pVM, void *pvUser) { int rc = CFGMR3ConstructDefaultTree(pVM); if ( RT_SUCCESS(rc) && g_cCpus > 1) { PCFGMNODE pRoot = CFGMR3GetRoot(pVM); CFGMR3RemoveValue(pRoot, "NumCPUs"); rc = CFGMR3InsertInteger(pRoot, "NumCPUs", g_cCpus); RTTESTI_CHECK_MSG_RET(RT_SUCCESS(rc), ("CFGMR3InsertInteger(pRoot,\"NumCPUs\",) -> %Rrc\n", rc), rc); CFGMR3RemoveValue(pRoot, "HwVirtExtForced"); rc = CFGMR3InsertInteger(pRoot, "HwVirtExtForced", true); RTTESTI_CHECK_MSG_RET(RT_SUCCESS(rc), ("CFGMR3InsertInteger(pRoot,\"HwVirtExtForced\",) -> %Rrc\n", rc), rc); PCFGMNODE pHwVirtExt = CFGMR3GetChild(pRoot, "HWVirtExt"); CFGMR3RemoveNode(pHwVirtExt); rc = CFGMR3InsertNode(pRoot, "HWVirtExt", &pHwVirtExt); RTTESTI_CHECK_MSG_RET(RT_SUCCESS(rc), ("CFGMR3InsertNode(pRoot,\"HWVirtExt\",) -> %Rrc\n", rc), rc); rc = CFGMR3InsertInteger(pHwVirtExt, "Enabled", true); RTTESTI_CHECK_MSG_RET(RT_SUCCESS(rc), ("CFGMR3InsertInteger(pHwVirtExt,\"Enabled\",) -> %Rrc\n", rc), rc); rc = CFGMR3InsertInteger(pHwVirtExt, "64bitEnabled", false); RTTESTI_CHECK_MSG_RET(RT_SUCCESS(rc), ("CFGMR3InsertInteger(pHwVirtExt,\"64bitEnabled\",) -> %Rrc\n", rc), rc); } return rc; }
/** * Initializes the tracing. * * @returns VBox status code * @param pVM The cross context VM structure. */ int dbgfR3TraceInit(PVM pVM) { /* * Initialize the trace buffer handles. */ Assert(NIL_RTTRACEBUF == (RTTRACEBUF)NULL); pVM->hTraceBufR3 = NIL_RTTRACEBUF; pVM->hTraceBufRC = NIL_RTRCPTR; pVM->hTraceBufR0 = NIL_RTR0PTR; /* * Check the config and enable tracing if requested. */ PCFGMNODE pDbgfNode = CFGMR3GetChild(CFGMR3GetRoot(pVM), "DBGF"); #if defined(DEBUG) || defined(RTTRACE_ENABLED) bool const fDefault = false; const char * const pszConfigDefault = ""; #else bool const fDefault = false; const char * const pszConfigDefault = ""; #endif bool fTracingEnabled; int rc = CFGMR3QueryBoolDef(pDbgfNode, "TracingEnabled", &fTracingEnabled, fDefault); AssertRCReturn(rc, rc); if (fTracingEnabled) { rc = dbgfR3TraceEnable(pVM, 0, 0); if (RT_SUCCESS(rc)) { if (pDbgfNode) { char *pszTracingConfig; rc = CFGMR3QueryStringAllocDef(pDbgfNode, "TracingConfig", &pszTracingConfig, pszConfigDefault); if (RT_SUCCESS(rc)) { rc = DBGFR3TraceConfig(pVM, pszTracingConfig); if (RT_FAILURE(rc)) rc = VMSetError(pVM, rc, RT_SRC_POS, "TracingConfig=\"%s\" -> %Rrc", pszTracingConfig, rc); MMR3HeapFree(pszTracingConfig); } } else { rc = DBGFR3TraceConfig(pVM, pszConfigDefault); if (RT_FAILURE(rc)) rc = VMSetError(pVM, rc, RT_SRC_POS, "TracingConfig=\"%s\" (default) -> %Rrc", pszConfigDefault, rc); } } } /* * Register a debug info item that will dump the trace buffer content. */ if (RT_SUCCESS(rc)) rc = DBGFR3InfoRegisterInternal(pVM, "tracebuf", "Display the trace buffer content. No arguments.", dbgfR3TraceInfo); return rc; }
/** * Same as dbgfR3AsSearchEnv, except that the path is taken from the DBGF config * (CFGM). * * Nothing is done if the CFGM variable isn't set. * * @returns VBox status code. * @param pszFilename The filename. * @param pszCfgValue The name of the config variable (under /DBGF/). * @param pfnOpen The open callback function. * @param pvUser User argument for the callback. */ static int dbgfR3AsSearchCfgPath(PVM pVM, const char *pszFilename, const char *pszCfgValue, PFNDBGFR3ASSEARCHOPEN pfnOpen, void *pvUser) { char *pszPath; int rc = CFGMR3QueryStringAllocDef(CFGMR3GetChild(CFGMR3GetRoot(pVM), "/DBGF"), pszCfgValue, &pszPath, NULL); if (RT_FAILURE(rc)) return rc; if (!pszPath) return VERR_FILE_NOT_FOUND; rc = dbgfR3AsSearchPath(pszFilename, pszPath, pfnOpen, pvUser); MMR3HeapFree(pszPath); return rc; }
/** * Initialize the configuration of halt method 1 & 2. * * @return VBox status code. Failure on invalid CFGM data. * @param pVM Pointer to the VM. */ static int vmR3HaltMethod12ReadConfigU(PUVM pUVM) { /* * The defaults. */ #if 1 /* DEBUGGING STUFF - REMOVE LATER */ pUVM->vm.s.Halt.Method12.u32LagBlockIntervalDivisorCfg = 4; pUVM->vm.s.Halt.Method12.u32MinBlockIntervalCfg = 2*1000000; pUVM->vm.s.Halt.Method12.u32MaxBlockIntervalCfg = 75*1000000; pUVM->vm.s.Halt.Method12.u32StartSpinningCfg = 30*1000000; pUVM->vm.s.Halt.Method12.u32StopSpinningCfg = 20*1000000; #else pUVM->vm.s.Halt.Method12.u32LagBlockIntervalDivisorCfg = 4; pUVM->vm.s.Halt.Method12.u32MinBlockIntervalCfg = 5*1000000; pUVM->vm.s.Halt.Method12.u32MaxBlockIntervalCfg = 200*1000000; pUVM->vm.s.Halt.Method12.u32StartSpinningCfg = 20*1000000; pUVM->vm.s.Halt.Method12.u32StopSpinningCfg = 2*1000000; #endif /* * Query overrides. * * I don't have time to bother with niceties such as invalid value checks * here right now. sorry. */ PCFGMNODE pCfg = CFGMR3GetChild(CFGMR3GetRoot(pUVM->pVM), "/VMM/HaltedMethod1"); if (pCfg) { uint32_t u32; if (RT_SUCCESS(CFGMR3QueryU32(pCfg, "LagBlockIntervalDivisor", &u32))) pUVM->vm.s.Halt.Method12.u32LagBlockIntervalDivisorCfg = u32; if (RT_SUCCESS(CFGMR3QueryU32(pCfg, "MinBlockInterval", &u32))) pUVM->vm.s.Halt.Method12.u32MinBlockIntervalCfg = u32; if (RT_SUCCESS(CFGMR3QueryU32(pCfg, "MaxBlockInterval", &u32))) pUVM->vm.s.Halt.Method12.u32MaxBlockIntervalCfg = u32; if (RT_SUCCESS(CFGMR3QueryU32(pCfg, "StartSpinning", &u32))) pUVM->vm.s.Halt.Method12.u32StartSpinningCfg = u32; if (RT_SUCCESS(CFGMR3QueryU32(pCfg, "StopSpinning", &u32))) pUVM->vm.s.Halt.Method12.u32StopSpinningCfg = u32; LogRel(("HaltedMethod1 config: %d/%d/%d/%d/%d\n", pUVM->vm.s.Halt.Method12.u32LagBlockIntervalDivisorCfg, pUVM->vm.s.Halt.Method12.u32MinBlockIntervalCfg, pUVM->vm.s.Halt.Method12.u32MaxBlockIntervalCfg, pUVM->vm.s.Halt.Method12.u32StartSpinningCfg, pUVM->vm.s.Halt.Method12.u32StopSpinningCfg)); } return VINF_SUCCESS; }
/** * @interface_method_impl{PDMDRVREG,pfnConstruct} */ DECLCALLBACK(int) Nvram::drvNvram_Construct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags) { RT_NOREF(fFlags); PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns); LogFlowFunc(("iInstance/#%d pCfg=%p fFlags=%x\n", pDrvIns->iInstance, pCfg, fFlags)); PNVRAM pThis = PDMINS_2_DATA(pDrvIns, PNVRAM); /* * Initalize instance data variables first. */ //pThis->pNvram = NULL; //pThis->cLoadedVariables = 0; //pThis->fPermanentSave = false; pThis->pCfgVarRoot = CFGMR3GetChild(pCfg, "Vars"); //pThis->pLastVarNode = NULL; pThis->idxLastVar = UINT32_MAX / 2; pDrvIns->IBase.pfnQueryInterface = Nvram::drvNvram_QueryInterface; pThis->INvramConnector.pfnVarQueryByIndex = drvNvram_VarQueryByIndex; pThis->INvramConnector.pfnVarStoreSeqBegin = drvNvram_VarStoreSeqBegin; pThis->INvramConnector.pfnVarStoreSeqPut = drvNvram_VarStoreSeqPut; pThis->INvramConnector.pfnVarStoreSeqEnd = drvNvram_VarStoreSeqEnd; /* * Validate and read configuration. */ if (!CFGMR3AreValuesValid(pCfg, "Object\0" "PermanentSave\0")) return VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES; AssertMsgReturn(PDMDrvHlpNoAttach(pDrvIns) == VERR_PDM_NO_ATTACHED_DRIVER, ("Configuration error: Not possible to attach anything to this driver!\n"), VERR_PDM_DRVINS_NO_ATTACH); int rc = CFGMR3QueryPtr(pCfg, "Object", (void **)&pThis->pNvram); AssertMsgRCReturn(rc, ("Configuration error: No/bad \"Object\" value! rc=%Rrc\n", rc), rc); rc = CFGMR3QueryBoolDef(pCfg, "PermanentSave", &pThis->fPermanentSave, false); AssertRCReturn(rc, rc); /* * Let the associated class instance know about us. */ pThis->pNvram->mpDrv = pThis; return VINF_SUCCESS; }
/** * Changes the halt method. * * @returns VBox status code. * @param pUVM Pointer to the user mode VM structure. * @param enmHaltMethod The new halt method. * @thread EMT. */ int vmR3SetHaltMethodU(PUVM pUVM, VMHALTMETHOD enmHaltMethod) { PVM pVM = pUVM->pVM; Assert(pVM); VM_ASSERT_EMT(pVM); AssertReturn(enmHaltMethod > VMHALTMETHOD_INVALID && enmHaltMethod < VMHALTMETHOD_END, VERR_INVALID_PARAMETER); /* * Resolve default (can be overridden in the configuration). */ if (enmHaltMethod == VMHALTMETHOD_DEFAULT) { uint32_t u32; int rc = CFGMR3QueryU32(CFGMR3GetChild(CFGMR3GetRoot(pVM), "VM"), "HaltMethod", &u32); if (RT_SUCCESS(rc)) { enmHaltMethod = (VMHALTMETHOD)u32; if (enmHaltMethod <= VMHALTMETHOD_INVALID || enmHaltMethod >= VMHALTMETHOD_END) return VMSetError(pVM, VERR_INVALID_PARAMETER, RT_SRC_POS, N_("Invalid VM/HaltMethod value %d"), enmHaltMethod); } else if (rc == VERR_CFGM_VALUE_NOT_FOUND || rc == VERR_CFGM_CHILD_NOT_FOUND) return VMSetError(pVM, rc, RT_SRC_POS, N_("Failed to Query VM/HaltMethod as uint32_t")); else enmHaltMethod = VMHALTMETHOD_GLOBAL_1; //enmHaltMethod = VMHALTMETHOD_1; //enmHaltMethod = VMHALTMETHOD_OLD; } LogRel(("VM: Halt method %s (%d)\n", vmR3GetHaltMethodName(enmHaltMethod), enmHaltMethod)); /* * Find the descriptor. */ unsigned i = 0; while ( i < RT_ELEMENTS(g_aHaltMethods) && g_aHaltMethods[i].enmHaltMethod != enmHaltMethod) i++; AssertReturn(i < RT_ELEMENTS(g_aHaltMethods), VERR_INVALID_PARAMETER); /* * This needs to be done while the other EMTs are not sleeping or otherwise messing around. */ return VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_ONCE, vmR3SetHaltMethodCallback, (void *)(uintptr_t)i); }
/** * @interface_method_impl{VBOXEXTPACKREG,pfnVMConfigureVMM */ static DECLCALLBACK(int) vboxBusMouseExtPack_VMConfigureVMM(PCVBOXEXTPACKREG pThis, IConsole *pConsole, PVM pVM) { /* * Find the bus mouse module and tell PDM to load it. * ASSUME /PDM/Devices exists. */ char szPath[RTPATH_MAX]; int rc = g_pHlp->pfnFindModule(g_pHlp, "VBoxBusMouseR3", NULL, VBOXEXTPACKMODKIND_R3, szPath, sizeof(szPath), NULL); if (RT_FAILURE(rc)) return rc; PCFGMNODE pCfgRoot = CFGMR3GetRoot(pVM); AssertReturn(pCfgRoot, VERR_INTERNAL_ERROR_3); PCFGMNODE pCfgDevices = CFGMR3GetChild(pCfgRoot, "PDM/Devices"); AssertReturn(pCfgDevices, VERR_INTERNAL_ERROR_3); PCFGMNODE pCfgMine; rc = CFGMR3InsertNode(pCfgDevices, "VBoxBusMouse", &pCfgMine); AssertRCReturn(rc, rc); rc = CFGMR3InsertString(pCfgMine, "Path", szPath); AssertRCReturn(rc, rc); /* * Tell PDM where to find the R0 and RC modules for the bus mouse device. */ #ifdef VBOX_WITH_RAW_MODE rc = g_pHlp->pfnFindModule(g_pHlp, "VBoxBusMouseRC", NULL, VBOXEXTPACKMODKIND_RC, szPath, sizeof(szPath), NULL); AssertRCReturn(rc, rc); RTPathStripFilename(szPath); rc = CFGMR3InsertString(pCfgMine, "RCSearchPath", szPath); AssertRCReturn(rc, rc); #endif rc = g_pHlp->pfnFindModule(g_pHlp, "VBoxBusMouseR0", NULL, VBOXEXTPACKMODKIND_R0, szPath, sizeof(szPath), NULL); AssertRCReturn(rc, rc); RTPathStripFilename(szPath); rc = CFGMR3InsertString(pCfgMine, "R0SearchPath", szPath); AssertRCReturn(rc, rc); return VINF_SUCCESS; }
/** * Initializes the address space parts of DBGF. * * @returns VBox status code. * @param pUVM The user mode VM handle. */ int dbgfR3AsInit(PUVM pUVM) { Assert(pUVM->pVM); /* * Create the semaphore. */ int rc = RTSemRWCreate(&pUVM->dbgf.s.hAsDbLock); AssertRCReturn(rc, rc); /* * Create the debugging config instance and set it up, defaulting to * deferred loading in order to keep things fast. */ rc = RTDbgCfgCreate(&pUVM->dbgf.s.hDbgCfg, NULL, true /*fNativePaths*/); AssertRCReturn(rc, rc); rc = RTDbgCfgChangeUInt(pUVM->dbgf.s.hDbgCfg, RTDBGCFGPROP_FLAGS, RTDBGCFGOP_PREPEND, RTDBGCFG_FLAGS_DEFERRED); AssertRCReturn(rc, rc); static struct { RTDBGCFGPROP enmProp; const char *pszEnvName; const char *pszCfgName; } const s_aProps[] = { { RTDBGCFGPROP_FLAGS, "VBOXDBG_FLAGS", "Flags" }, { RTDBGCFGPROP_PATH, "VBOXDBG_PATH", "Path" }, { RTDBGCFGPROP_SUFFIXES, "VBOXDBG_SUFFIXES", "Suffixes" }, { RTDBGCFGPROP_SRC_PATH, "VBOXDBG_SRC_PATH", "SrcPath" }, }; PCFGMNODE pCfgDbgf = CFGMR3GetChild(CFGMR3GetRootU(pUVM), "/DBGF"); for (unsigned i = 0; i < RT_ELEMENTS(s_aProps); i++) { char szEnvValue[8192]; rc = RTEnvGetEx(RTENV_DEFAULT, s_aProps[i].pszEnvName, szEnvValue, sizeof(szEnvValue), NULL); if (RT_SUCCESS(rc)) { rc = RTDbgCfgChangeString(pUVM->dbgf.s.hDbgCfg, s_aProps[i].enmProp, RTDBGCFGOP_PREPEND, szEnvValue); if (RT_FAILURE(rc)) return VMR3SetError(pUVM, rc, RT_SRC_POS, "DBGF Config Error: %s=%s -> %Rrc", s_aProps[i].pszEnvName, szEnvValue, rc); } else if (rc != VERR_ENV_VAR_NOT_FOUND) return VMR3SetError(pUVM, rc, RT_SRC_POS, "DBGF Config Error: Error querying env.var. %s: %Rrc", s_aProps[i].pszEnvName, rc); char *pszCfgValue; rc = CFGMR3QueryStringAllocDef(pCfgDbgf, s_aProps[i].pszCfgName, &pszCfgValue, NULL); if (RT_FAILURE(rc)) return VMR3SetError(pUVM, rc, RT_SRC_POS, "DBGF Config Error: Querying /DBGF/%s -> %Rrc", s_aProps[i].pszCfgName, rc); if (pszCfgValue) { rc = RTDbgCfgChangeString(pUVM->dbgf.s.hDbgCfg, s_aProps[i].enmProp, RTDBGCFGOP_PREPEND, pszCfgValue); if (RT_FAILURE(rc)) return VMR3SetError(pUVM, rc, RT_SRC_POS, "DBGF Config Error: /DBGF/%s=%s -> %Rrc", s_aProps[i].pszCfgName, pszCfgValue, rc); } } /* * Prepend the NoArch and VBoxDbgSyms directories to the path. */ char szPath[RTPATH_MAX]; rc = RTPathAppPrivateNoArch(szPath, sizeof(szPath)); AssertRCReturn(rc, rc); #ifdef RT_OS_DARWIN rc = RTPathAppend(szPath, sizeof(szPath), "../Resources/VBoxDbgSyms/"); #else rc = RTDbgCfgChangeString(pUVM->dbgf.s.hDbgCfg, RTDBGCFGPROP_PATH, RTDBGCFGOP_PREPEND, szPath); AssertRCReturn(rc, rc); rc = RTPathAppend(szPath, sizeof(szPath), "VBoxDbgSyms/"); #endif AssertRCReturn(rc, rc); rc = RTDbgCfgChangeString(pUVM->dbgf.s.hDbgCfg, RTDBGCFGPROP_PATH, RTDBGCFGOP_PREPEND, szPath); AssertRCReturn(rc, rc); /* * Create the standard address spaces. */ RTDBGAS hDbgAs; rc = RTDbgAsCreate(&hDbgAs, 0, RTGCPTR_MAX, "Global"); AssertRCReturn(rc, rc); rc = DBGFR3AsAdd(pUVM, hDbgAs, NIL_RTPROCESS); AssertRCReturn(rc, rc); RTDbgAsRetain(hDbgAs); pUVM->dbgf.s.ahAsAliases[DBGF_AS_ALIAS_2_INDEX(DBGF_AS_GLOBAL)] = hDbgAs; RTDbgAsRetain(hDbgAs); pUVM->dbgf.s.ahAsAliases[DBGF_AS_ALIAS_2_INDEX(DBGF_AS_KERNEL)] = hDbgAs; rc = RTDbgAsCreate(&hDbgAs, 0, RTGCPHYS_MAX, "Physical"); AssertRCReturn(rc, rc); rc = DBGFR3AsAdd(pUVM, hDbgAs, NIL_RTPROCESS); AssertRCReturn(rc, rc); RTDbgAsRetain(hDbgAs); pUVM->dbgf.s.ahAsAliases[DBGF_AS_ALIAS_2_INDEX(DBGF_AS_PHYS)] = hDbgAs; rc = RTDbgAsCreate(&hDbgAs, 0, RTRCPTR_MAX, "HyperRawMode"); AssertRCReturn(rc, rc); rc = DBGFR3AsAdd(pUVM, hDbgAs, NIL_RTPROCESS); AssertRCReturn(rc, rc); RTDbgAsRetain(hDbgAs); pUVM->dbgf.s.ahAsAliases[DBGF_AS_ALIAS_2_INDEX(DBGF_AS_RC)] = hDbgAs; RTDbgAsRetain(hDbgAs); pUVM->dbgf.s.ahAsAliases[DBGF_AS_ALIAS_2_INDEX(DBGF_AS_RC_AND_GC_GLOBAL)] = hDbgAs; rc = RTDbgAsCreate(&hDbgAs, 0, RTR0PTR_MAX, "HyperRing0"); AssertRCReturn(rc, rc); rc = DBGFR3AsAdd(pUVM, hDbgAs, NIL_RTPROCESS); AssertRCReturn(rc, rc); RTDbgAsRetain(hDbgAs); pUVM->dbgf.s.ahAsAliases[DBGF_AS_ALIAS_2_INDEX(DBGF_AS_R0)] = hDbgAs; return VINF_SUCCESS; }
/** * Reads the CFGM configuration of the DBGC. * * Popuplates the PDBGC::pszHistoryFile, PDBGC::pszGlobalInitScript and * PDBGC::pszLocalInitScript members. * * @returns VBox status code. * @param pDbgc The console instance. * @param pUVM The user mode VM handle. */ static int dbgcReadConfig(PDBGC pDbgc, PUVM pUVM) { /* * Get and validate the configuration node. */ PCFGMNODE pNode = CFGMR3GetChild(CFGMR3GetRootU(pUVM), "DBGC"); int rc = CFGMR3ValidateConfig(pNode, "/DBGC/", "Enabled|" "HistoryFile|" "LocalInitScript|" "GlobalInitScript", "", "DBGC", 0); AssertRCReturn(rc, rc); /* * Query the values. */ char szHomeDefault[RTPATH_MAX]; rc = RTPathUserHome(szHomeDefault, sizeof(szHomeDefault) - 32); AssertLogRelRCReturn(rc, rc); size_t cchHome = strlen(szHomeDefault); /** @cfgm{/DBGC/HistoryFile, string, ${HOME}/.vboxdbgc-history} * The command history file of the VBox debugger. */ rc = RTPathAppend(szHomeDefault, sizeof(szHomeDefault), ".vboxdbgc-history"); AssertLogRelRCReturn(rc, rc); char szPath[RTPATH_MAX]; rc = CFGMR3QueryStringDef(pNode, "HistoryFile", szPath, sizeof(szPath), szHomeDefault); AssertLogRelRCReturn(rc, rc); pDbgc->pszHistoryFile = RTStrDup(szPath); AssertReturn(pDbgc->pszHistoryFile, VERR_NO_STR_MEMORY); /** @cfgm{/DBGC/GlobalInitFile, string, ${HOME}/.vboxdbgc-init} * The global init script of the VBox debugger. */ szHomeDefault[cchHome] = '\0'; rc = RTPathAppend(szHomeDefault, sizeof(szHomeDefault), ".vboxdbgc-init"); AssertLogRelRCReturn(rc, rc); rc = CFGMR3QueryStringDef(pNode, "GlobalInitScript", szPath, sizeof(szPath), szHomeDefault); AssertLogRelRCReturn(rc, rc); pDbgc->pszGlobalInitScript = RTStrDup(szPath); AssertReturn(pDbgc->pszGlobalInitScript, VERR_NO_STR_MEMORY); /** @cfgm{/DBGC/LocalInitFile, string, none} * The VM local init script of the VBox debugger. */ rc = CFGMR3QueryString(pNode, "LocalInitScript", szPath, sizeof(szPath)); if (RT_SUCCESS(rc)) { pDbgc->pszLocalInitScript = RTStrDup(szPath); AssertReturn(pDbgc->pszLocalInitScript, VERR_NO_STR_MEMORY); } else { AssertLogRelReturn(rc == VERR_CFGM_VALUE_NOT_FOUND || rc == VERR_CFGM_NO_PARENT, rc); pDbgc->pszLocalInitScript = NULL; } return VINF_SUCCESS; }
/** * Initialize the network shaper. * * @returns VBox status code * @param pVM Pointer to the VM. */ int pdmR3NetShaperInit(PVM pVM) { LogFlowFunc((": pVM=%p\n", pVM)); VM_ASSERT_EMT(pVM); PPDMNETSHAPER pNetShaper = NULL; int rc = MMR3HeapAllocZEx(pVM, MM_TAG_PDM_NET_SHAPER, sizeof(PDMNETSHAPER), (void **)&pNetShaper); if (RT_SUCCESS(rc)) { PCFGMNODE pCfgRoot = CFGMR3GetRoot(pVM); PCFGMNODE pCfgNetShaper = CFGMR3GetChild(CFGMR3GetChild(pCfgRoot, "PDM"), "NetworkShaper"); pNetShaper->pVM = pVM; rc = RTCritSectInit(&pNetShaper->cs); if (RT_SUCCESS(rc)) { /* Create all bandwidth groups. */ PCFGMNODE pCfgBwGrp = CFGMR3GetChild(pCfgNetShaper, "BwGroups"); if (pCfgBwGrp) { for (PCFGMNODE pCur = CFGMR3GetFirstChild(pCfgBwGrp); pCur; pCur = CFGMR3GetNextChild(pCur)) { uint64_t cbMax; size_t cbName = CFGMR3GetNameLen(pCur) + 1; char *pszBwGrpId = (char *)RTMemAllocZ(cbName); if (!pszBwGrpId) { rc = VERR_NO_MEMORY; break; } rc = CFGMR3GetName(pCur, pszBwGrpId, cbName); AssertRC(rc); if (RT_SUCCESS(rc)) rc = CFGMR3QueryU64(pCur, "Max", &cbMax); if (RT_SUCCESS(rc)) rc = pdmNsBwGroupCreate(pNetShaper, pszBwGrpId, cbMax); RTMemFree(pszBwGrpId); if (RT_FAILURE(rc)) break; } } if (RT_SUCCESS(rc)) { PUVM pUVM = pVM->pUVM; AssertMsg(!pUVM->pdm.s.pNetShaper, ("Network shaper was already initialized\n")); char szDesc[64]; static unsigned s_iThread; RTStrPrintf(szDesc, sizeof(szDesc), "PDMNsTx-%d", ++s_iThread); rc = PDMR3ThreadCreate(pVM, &pNetShaper->hTxThread, pNetShaper, pdmR3NsTxThread, pdmR3NsTxWakeUp, 0, RTTHREADTYPE_IO, szDesc); if (RT_SUCCESS(rc)) { pUVM->pdm.s.pNetShaper = pNetShaper; return VINF_SUCCESS; } } RTCritSectDelete(&pNetShaper->cs); } MMR3HeapFree(pNetShaper); } LogFlowFunc((": pVM=%p rc=%Rrc\n", pVM, rc)); return rc; }
/** * Initialize the network shaper. * * @returns VBox status code * @param pVM The cross context VM structure. */ int pdmR3NetShaperInit(PVM pVM) { LogFlow(("pdmR3NetShaperInit: pVM=%p\n", pVM)); VM_ASSERT_EMT(pVM); PUVM pUVM = pVM->pUVM; AssertMsgReturn(!pUVM->pdm.s.pNetShaper, ("Network shaper was already initialized\n"), VERR_WRONG_ORDER); PPDMNETSHAPER pShaper; int rc = MMR3HeapAllocZEx(pVM, MM_TAG_PDM_NET_SHAPER, sizeof(PDMNETSHAPER), (void **)&pShaper); if (RT_SUCCESS(rc)) { PCFGMNODE pCfgNetShaper = CFGMR3GetChild(CFGMR3GetChild(CFGMR3GetRoot(pVM), "PDM"), "NetworkShaper"); pShaper->pVM = pVM; rc = RTCritSectInit(&pShaper->Lock); if (RT_SUCCESS(rc)) { /* Create all bandwidth groups. */ PCFGMNODE pCfgBwGrp = CFGMR3GetChild(pCfgNetShaper, "BwGroups"); if (pCfgBwGrp) { for (PCFGMNODE pCur = CFGMR3GetFirstChild(pCfgBwGrp); pCur; pCur = CFGMR3GetNextChild(pCur)) { size_t cbName = CFGMR3GetNameLen(pCur) + 1; char *pszBwGrpId = (char *)RTMemAllocZ(cbName); if (pszBwGrpId) { rc = CFGMR3GetName(pCur, pszBwGrpId, cbName); if (RT_SUCCESS(rc)) { uint64_t cbMax; rc = CFGMR3QueryU64(pCur, "Max", &cbMax); if (RT_SUCCESS(rc)) rc = pdmNsBwGroupCreate(pShaper, pszBwGrpId, cbMax); } RTMemFree(pszBwGrpId); } else rc = VERR_NO_MEMORY; if (RT_FAILURE(rc)) break; } } if (RT_SUCCESS(rc)) { rc = PDMR3ThreadCreate(pVM, &pShaper->pTxThread, pShaper, pdmR3NsTxThread, pdmR3NsTxWakeUp, 0 /*cbStack*/, RTTHREADTYPE_IO, "PDMNsTx"); if (RT_SUCCESS(rc)) { pUVM->pdm.s.pNetShaper = pShaper; return VINF_SUCCESS; } } RTCritSectDelete(&pShaper->Lock); } MMR3HeapFree(pShaper); } LogFlow(("pdmR3NetShaperInit: pVM=%p rc=%Rrc\n", pVM, rc)); return rc; }
int main() { /* * Init runtime. */ RTR3InitExeNoArguments(RTR3INIT_FLAGS_SUPLIB); /* * Create empty VM structure and init SSM. */ PVM pVM; int rc = SUPR3Init(NULL); if (RT_SUCCESS(rc)) rc = SUPR3PageAlloc(RT_ALIGN_Z(sizeof(*pVM), PAGE_SIZE) >> PAGE_SHIFT, (void **)&pVM); if (RT_FAILURE(rc)) { RTPrintf("Fatal error: SUP Failure! rc=%Rrc\n", rc); return 1; } static UVM s_UVM; PUVM pUVM = &s_UVM; pUVM->pVM = pVM; pVM->pUVM = pUVM; rc = STAMR3InitUVM(pUVM); if (RT_FAILURE(rc)) { RTPrintf("FAILURE: STAMR3Init failed. rc=%Rrc\n", rc); return 1; } rc = MMR3InitUVM(pUVM); if (RT_FAILURE(rc)) { RTPrintf("FAILURE: STAMR3Init failed. rc=%Rrc\n", rc); return 1; } rc = CFGMR3Init(pVM, NULL, NULL); if (RT_FAILURE(rc)) { RTPrintf("FAILURE: CFGMR3Init failed. rc=%Rrc\n", rc); return 1; } if (!CFGMR3GetRoot(pVM)) { RTPrintf("FAILURE: CFGMR3GetRoot failed\n"); return 1; } /* integer */ uint64_t u64; rc = CFGMR3QueryU64(CFGMR3GetRoot(pVM), "RamSize", &u64); if (RT_FAILURE(rc)) { RTPrintf("FAILURE: CFGMR3QueryU64(,\"RamSize\",) failed. rc=%Rrc\n", rc); return 1; } size_t cb; rc = CFGMR3QuerySize(CFGMR3GetRoot(pVM), "RamSize", &cb); if (RT_FAILURE(rc)) { RTPrintf("FAILURE: CFGMR3QuerySize(,\"RamSize\",) failed. rc=%Rrc\n", rc); return 1; } if (cb != sizeof(uint64_t)) { RTPrintf("FAILURE: Incorrect valuesize %d for \"RamSize\" value.\n", cb); return 1; } /* string */ char *pszName = NULL; rc = CFGMR3QueryStringAlloc(CFGMR3GetRoot(pVM), "Name", &pszName); if (RT_FAILURE(rc)) { RTPrintf("FAILURE: CFGMR3QueryStringAlloc(,\"Name\" failed. rc=%Rrc\n", rc); return 1; } rc = CFGMR3QuerySize(CFGMR3GetRoot(pVM), "Name", &cb); if (RT_FAILURE(rc)) { RTPrintf("FAILURE: CFGMR3QuerySize(,\"RamSize\",) failed. rc=%Rrc\n", rc); return 1; } if (cb != strlen(pszName) + 1) { RTPrintf("FAILURE: Incorrect valuesize %d for \"Name\" value '%s'.\n", cb, pszName); return 1; } MMR3HeapFree(pszName); /* test multilevel node creation */ PCFGMNODE pChild = NULL; rc = CFGMR3InsertNode(CFGMR3GetRoot(pVM), "First/Second/Third//Final", &pChild); if (RT_FAILURE(rc)) { RTPrintf("FAILURE: CFGMR3InsertNode(,\"First/Second/Third//Final\" failed. rc=%Rrc\n", rc); return 1; } rc = CFGMR3InsertInteger(pChild, "BoolValue", 1); if (RT_FAILURE(rc)) { RTPrintf("FAILURE: CFGMR3InsertInteger(,\"BoolValue\", 1) failed. rc=%Rrc\n", rc); return 1; } PCFGMNODE pNode = CFGMR3GetChild(CFGMR3GetRoot(pVM), "First/Second/Third/Final"); if (pNode != pChild) { RTPrintf("FAILURE: CFGMR3GetChild(,\"First/Second/Third/Final/BoolValue\") failed. pNode=%p expected %p\n", pNode, pChild); return 1; } bool f = false; rc = CFGMR3QueryBool(pNode, "BoolValue", &f); if (RT_FAILURE(rc) || !f) { RTPrintf("FAILURE: CFGMR3QueryBool(,\"BoolValue\",) failed. rc=%Rrc f=%d\n", rc, f); return 1; } /* done */ rc = CFGMR3Term(pVM); if (RT_FAILURE(rc)) { RTPrintf("FAILURE: CFGMR3QueryU64(,\"RamSize\" failed. rc=%Rrc\n", rc); return 1; } RTPrintf("tstCFGM: SUCCESS\n"); return rc; }
/** * Initialize the debug info for a VM. * * This will check the CFGM for any symbols or symbol files * which needs loading. * * @returns VBox status code. * @param pVM The VM handle. */ int dbgfR3SymInit(PVM pVM) { int rc; /* * Initialize the symbol table. */ pVM->dbgf.s.pSymbolSpace = (PRTSTRSPACE)MMR3HeapAllocZ(pVM, MM_TAG_DBGF_SYMBOL, sizeof(*pVM->dbgf.s.pSymbolSpace)); AssertReturn(pVM->dbgf.s.pSymbolSpace, VERR_NO_MEMORY); #ifndef HAVE_DBGHELP /* modules & lines later */ rc = dbgfR3SymbolInit(pVM); if (RT_FAILURE(rc)) return rc; pVM->dbgf.s.fSymInited = true; #endif /* * Check if there are 'loadsyms' commands in the configuration. */ PCFGMNODE pNode = CFGMR3GetChild(CFGMR3GetRoot(pVM), "/DBGF/loadsyms/"); if (pNode) { /* * Enumerate the commands. */ for (PCFGMNODE pCmdNode = CFGMR3GetFirstChild(pNode); pCmdNode; pCmdNode = CFGMR3GetNextChild(pCmdNode)) { char szCmdName[128]; CFGMR3GetName(pCmdNode, &szCmdName[0], sizeof(szCmdName)); /* File */ char *pszFilename; rc = CFGMR3QueryStringAlloc(pCmdNode, "Filename", &pszFilename); AssertMsgRCReturn(rc, ("rc=%Rrc querying the 'File' attribute of '/DBGF/loadsyms/%s'!\n", rc, szCmdName), rc); /* Delta (optional) */ RTGCINTPTR offDelta; rc = CFGMR3QueryGCPtrS(pNode, "Delta", &offDelta); if (rc == VERR_CFGM_VALUE_NOT_FOUND) offDelta = 0; else AssertMsgRCReturn(rc, ("rc=%Rrc querying the 'Delta' attribute of '/DBGF/loadsyms/%s'!\n", rc, szCmdName), rc); /* Module (optional) */ char *pszModule; rc = CFGMR3QueryStringAlloc(pCmdNode, "Module", &pszModule); if (rc == VERR_CFGM_VALUE_NOT_FOUND) pszModule = NULL; else AssertMsgRCReturn(rc, ("rc=%Rrc querying the 'Module' attribute of '/DBGF/loadsyms/%s'!\n", rc, szCmdName), rc); /* Module (optional) */ RTGCUINTPTR ModuleAddress; rc = CFGMR3QueryGCPtrU(pNode, "ModuleAddress", &ModuleAddress); if (rc == VERR_CFGM_VALUE_NOT_FOUND) ModuleAddress = 0; else AssertMsgRCReturn(rc, ("rc=%Rrc querying the 'ModuleAddress' attribute of '/DBGF/loadsyms/%s'!\n", rc, szCmdName), rc); /* Image size (optional) */ RTGCUINTPTR cbModule; rc = CFGMR3QueryGCPtrU(pNode, "ModuleSize", &cbModule); if (rc == VERR_CFGM_VALUE_NOT_FOUND) cbModule = 0; else AssertMsgRCReturn(rc, ("rc=%Rrc querying the 'ModuleAddress' attribute of '/DBGF/loadsyms/%s'!\n", rc, szCmdName), rc); /* * Execute the command. */ rc = DBGFR3ModuleLoad(pVM, pszFilename, offDelta, pszModule, ModuleAddress, cbModule); AssertMsgRCReturn(rc, ("pszFilename=%s offDelta=%RGv pszModule=%s ModuleAddress=%RGv cbModule=%RGv\n", pszFilename, offDelta, pszModule, ModuleAddress, cbModule), rc); MMR3HeapFree(pszModule); MMR3HeapFree(pszFilename); } } /* * Check if there are any 'symadd' commands in the configuration. */ return VINF_SUCCESS; }