SUPDrvTracer.cpp revision 12243d78274fbfc0310d8f85a8bd2a515c285fd2
5b281ba489ca18f0380d7efc7a5108b606cce449vboxsync * VBoxDrv - The VirtualBox Support Driver - Tracer Interface.
1f1986470af9f0bb750dd859b142dc2e952deb20vboxsync * Copyright (C) 2012 Oracle Corporation
1f1986470af9f0bb750dd859b142dc2e952deb20vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
1f1986470af9f0bb750dd859b142dc2e952deb20vboxsync * available from http://www.virtualbox.org. This file is free software;
1f1986470af9f0bb750dd859b142dc2e952deb20vboxsync * you can redistribute it and/or modify it under the terms of the GNU
1f1986470af9f0bb750dd859b142dc2e952deb20vboxsync * General Public License (GPL) as published by the Free Software
1f1986470af9f0bb750dd859b142dc2e952deb20vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
1f1986470af9f0bb750dd859b142dc2e952deb20vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
1f1986470af9f0bb750dd859b142dc2e952deb20vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
1f1986470af9f0bb750dd859b142dc2e952deb20vboxsync * The contents of this file may alternatively be used under the terms
1f1986470af9f0bb750dd859b142dc2e952deb20vboxsync * of the Common Development and Distribution License Version 1.0
1f1986470af9f0bb750dd859b142dc2e952deb20vboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
1f1986470af9f0bb750dd859b142dc2e952deb20vboxsync * VirtualBox OSE distribution, in which case the provisions of the
1f1986470af9f0bb750dd859b142dc2e952deb20vboxsync * CDDL are applicable instead of those of the GPL.
1f1986470af9f0bb750dd859b142dc2e952deb20vboxsync * You may elect to license modified versions of this file under the
1f1986470af9f0bb750dd859b142dc2e952deb20vboxsync * terms and conditions of either the GPL or the CDDL or both.
1f1986470af9f0bb750dd859b142dc2e952deb20vboxsync/*******************************************************************************
1f1986470af9f0bb750dd859b142dc2e952deb20vboxsync* Header Files *
1f1986470af9f0bb750dd859b142dc2e952deb20vboxsync*******************************************************************************/
1f1986470af9f0bb750dd859b142dc2e952deb20vboxsync/*******************************************************************************
1f1986470af9f0bb750dd859b142dc2e952deb20vboxsync* Structures and Typedefs *
1f1986470af9f0bb750dd859b142dc2e952deb20vboxsync*******************************************************************************/
1f1986470af9f0bb750dd859b142dc2e952deb20vboxsync * Data for a tracepoint provider.
1f1986470af9f0bb750dd859b142dc2e952deb20vboxsync /** The entry in the provider list for this image. */
1f1986470af9f0bb750dd859b142dc2e952deb20vboxsync /** The core structure. */
1f1986470af9f0bb750dd859b142dc2e952deb20vboxsync /** Pointer to the image this provider resides in. NULL if it's a
1f1986470af9f0bb750dd859b142dc2e952deb20vboxsync * driver. */
1f1986470af9f0bb750dd859b142dc2e952deb20vboxsync /** The session this provider is associated with if registered via
1f1986470af9f0bb750dd859b142dc2e952deb20vboxsync * SUPR0VtgRegisterDrv. NULL if pImage is set. */
1f1986470af9f0bb750dd859b142dc2e952deb20vboxsync /** Used to indicate that we've called pfnProviderDeregistered already and it
1f1986470af9f0bb750dd859b142dc2e952deb20vboxsync * failed because the provider was busy. Next time we must try
fb98ad2c5db683e0704e0cba88f305e95dc1b73avboxsync * pfnProviderDeregisterZombie.
1f1986470af9f0bb750dd859b142dc2e952deb20vboxsync * @remarks This does not necessiarly mean the provider is in the zombie
fb98ad2c5db683e0704e0cba88f305e95dc1b73avboxsync * list. See supdrvTracerCommonDeregisterImpl. */
1f1986470af9f0bb750dd859b142dc2e952deb20vboxsync /** Set if the provider has been successfully registered with the
bool fRegistered;
#ifdef DEBUG_bird
if (!ch)
return VINF_SUCCESS;
return VERR_SUPDRV_VTG_BAD_STRING;
return VERR_SUPDRV_VTG_STRING_TOO_LONG;
static int supdrvVtgValidate(PVTGOBJHDR pVtgHdr, size_t cbVtgObj, const uint8_t *pbImage, size_t cbImage)
uintptr_t i;
int rc;
cbImage = 0;
SUPR0Printf("supdrvVtgValidate: " #rcBase "_TOO_PTR - p=%p cb=%#zx pVtgHdr=%p cbVtgHdr=%#zu line=%u %s\n", \
SUPR0Printf("supdrvVtgValidate: " #rcBase "_TOO_FEW - cb=%#zx cMin=%#zx cbUnit=%#zx line=%u %s\n", \
SUPR0Printf("supdrvVtgValidate: " #rcBase "_TOO_MUCH - cb=%#zx cMax=%#zx cbUnit=%#zx line=%u %s\n", \
if (pbImage) \
return (rc); \
else if (!RT_VALID_PTR(p)) \
return (rc); \
return VERR_SUPDRV_VTG_STRTAB_OFF; \
return rc; \
if ((Attr).u8Code <= (uint8_t)kVTGStability_Invalid || (Attr).u8Code >= (uint8_t)kVTGStability_End) \
return VERR_SUPDRV_VTG_BAD_ATTR; \
if ((Attr).u8Data <= (uint8_t)kVTGStability_Invalid || (Attr).u8Data >= (uint8_t)kVTGStability_End) \
return VERR_SUPDRV_VTG_BAD_ATTR; \
return VERR_SUPDRV_VTG_BAD_ATTR; \
return VERR_SUPDRV_VTG_MAGIC;
return VERR_SUPDRV_VTG_BITS;
return VERR_SUPDRV_VTG_BAD_HDR;
MY_VALIDATE_PTR(pVtgHdr->paProviders, pVtgHdr->cbProviders, 1, 16, sizeof(VTGDESCPROVIDER), VERR_SUPDRV_VTG_BAD_HDR);
MY_VALIDATE_PTR(pVtgHdr->paProbes, pVtgHdr->cbProbes, 1, _32K, sizeof(VTGDESCPROBE), VERR_SUPDRV_VTG_BAD_HDR);
MY_VALIDATE_PTR(pVtgHdr->pafProbeEnabled, pVtgHdr->cbProbeEnabled, 1, _32K, sizeof(bool), VERR_SUPDRV_VTG_BAD_HDR);
MY_VALIDATE_PTR(pVtgHdr->pachStrTab, pVtgHdr->cbStrTab, 4, _1M, sizeof(char), VERR_SUPDRV_VTG_BAD_HDR);
MY_VALIDATE_PTR(pVtgHdr->paArgLists, pVtgHdr->cbArgLists, 1, _32K, sizeof(uint32_t), VERR_SUPDRV_VTG_BAD_HDR);
return VERR_SUPDRV_VTG_BAD_HDR_PTR;
SUPR0Printf("supdrvVtgValidate: VERR_SUPDRV_VTG_BAD_HDR_TOO_FEW - cbTmp=%#zx paProbeLocs=%p paProbLocsEnd=%p\n",
return VERR_SUPDRV_VTG_BAD_HDR_TOO_FEW;
SUPR0Printf("supdrvVtgValidate: VERR_SUPDRV_VTG_BAD_HDR_TOO_MUCH - cbTmp=%#zx paProbeLocs=%p paProbLocsEnd=%p\n",
return VERR_SUPDRV_VTG_BAD_HDR_TOO_MUCH;
SUPR0Printf("supdrvVtgValidate: VERR_SUPDRV_VTG_BAD_HDR_NOT_MULTIPLE - cbTmp=%#zx cbUnit=%#zx paProbeLocs=%p paProbLocsEnd=%p\n",
return VERR_SUPDRV_VTG_BAD_HDR;
return VERR_SUPDRV_VTG_BAD_PROVIDER;
if (pVtgHdr->paProviders[i].iFirstProbe + pVtgHdr->paProviders[i].cProbes > pVtgHdr->cbProbeEnabled)
return VERR_SUPDRV_VTG_BAD_PROVIDER;
return VERR_SUPDRV_VTG_BAD_PROVIDER;
unsigned iArg;
bool fHaveLargeArgs;
return VERR_SUPDRV_VTG_BAD_PROBE;
return VERR_SUPDRV_VTG_BAD_PROBE;
return VERR_SUPDRV_VTG_BAD_PROBE;
return VERR_SUPDRV_VTG_BAD_PROBE;
return VERR_SUPDRV_VTG_BAD_PROBE;
return VERR_SUPDRV_VTG_BAD_PROBE;
return VERR_SUPDRV_VTG_BAD_ARGLIST;
return VERR_SUPDRV_VTG_BAD_ARGLIST;
return VERR_SUPDRV_VTG_BAD_ARGLIST;
fHaveLargeArgs = false;
while (iArg-- > 0)
return rc;
fHaveLargeArgs = true;
return VERR_SUPDRV_VTG_BAD_PROBE;
return VERR_SUPDRV_VTG_BAD_PROBE_LOC;
return VERR_SUPDRV_VTG_BAD_PROBE_LOC;
return VERR_SUPDRV_VTG_BAD_PROBE_LOC;
return VERR_SUPDRV_VTG_BAD_PROBE_LOC;
return VERR_SUPDRV_VTG_BAD_PROBE_LOC;
return VINF_SUCCESS;
LOG_TRACER(("Freeing tracepoint provider '%s' / %p\n", pProv->szName, pProv->Core.TracerData.DTrace.idProvider));
int rc;
RTListForEachSafe(&pDevExt->TracerProviderZombieList, pProv, pProvNext, SUPDRVTPPROVIDER, ListEntry)
uint32_t i;
bool fEmpty;
RTListForEachSafe(&pDevExt->TracerProviderZombieList, pProv, pProvNext, SUPDRVTPPROVIDER, ListEntry)
int rc;
if (!rc)
fEmpty = false;
if (fEmpty)
static int supdrvTracerRegisterVtgObj(PSUPDRVDEVEXT pDevExt, PVTGOBJHDR pVtgHdr, size_t cbVtgObj, PSUPDRVLDRIMAGE pImage,
int rc;
uintptr_t i;
if (pImage)
return rc;
return rc;
return rc;
if (pProv)
RTListForEachReverseSafe(&pDevExt->TracerProviderList, pProv, pProvNext, SUPDRVTPPROVIDER, ListEntry)
return rc;
return VINF_SUCCESS;
SUPR0DECL(int) SUPR0TracerRegisterDrv(PSUPDRVSESSION pSession, PVTGOBJHDR pVtgHdr, const char *pszName)
int rc;
LOG_TRACER(("SUPR0TracerRegisterDrv: pSession=%p pVtgHdr=%p pszName=%s\n", pSession, pVtgHdr, pszName));
rc = supdrvTracerRegisterVtgObj(pSession->pDevExt, pVtgHdr, _1M, NULL /*pImage*/, pSession, pszName);
return rc;
int rc;
return rc;
SUPR0DECL(int) SUPR0TracerRegisterImpl(void *hMod, PSUPDRVSESSION pSession, PCSUPDRVTRACERREG pReg, PCSUPDRVTRACERHLP *ppHlp)
int rc;
if (pImage)
return rc;
uint32_t i;
int rc;
cZombies++;
RTListForEachSafe(&pDevExt->TracerProviderZombieList, pProv, pProvNext, SUPDRVTPPROVIDER, ListEntry)
int rc;
cZombies++;
cZombies++;
if (cZombies == 0)
int rc;
if (pImage)
if ( pImage
return rc;
# if defined(RT_ARCH_AMD64)
int VBOXCALL supdrvIOCtl_TracerOpen(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, uint32_t uCookie, uintptr_t uArg)
int rc;
rc = pDevExt->pTracerOps->pfnTracerOpen(pDevExt->pTracerOps, pSession, uCookie, uArg, &pSession->uTracerData);
return rc;
int rc;
return rc;
int VBOXCALL supdrvIOCtl_TracerIOCtl(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, uintptr_t uCmd, uintptr_t uArg, int32_t *piRetVal)
int rc;
*piRetVal = 0;
rc = pDevExt->pTracerOps->pfnTracerIoCtl(pDevExt->pTracerOps, pSession, uTracerData, uCmd, uArg, piRetVal);
return rc;
#ifdef VBOX_WITH_DTRACE_R0DRV
rc = supdrvTracerRegisterVtgObj(pDevExt, &g_VTGObjHeader, _1M, NULL /*pImage*/, NULL /*pSession*/, "vboxdrv");
return rc;
return VINF_SUCCESS;
return rc;