SUPDrv-dtrace.cpp revision cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2
42576743851c3c956ad7e867e74df1084c30d434vboxsync * VBoxDrv - The VirtualBox Support Driver - DTrace Provider.
42576743851c3c956ad7e867e74df1084c30d434vboxsync * Copyright (C) 2012 Oracle Corporation
42576743851c3c956ad7e867e74df1084c30d434vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
42576743851c3c956ad7e867e74df1084c30d434vboxsync * available from http://www.virtualbox.org. This file is free software;
42576743851c3c956ad7e867e74df1084c30d434vboxsync * you can redistribute it and/or modify it under the terms of the GNU
42576743851c3c956ad7e867e74df1084c30d434vboxsync * General Public License (GPL) as published by the Free Software
42576743851c3c956ad7e867e74df1084c30d434vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
42576743851c3c956ad7e867e74df1084c30d434vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
42576743851c3c956ad7e867e74df1084c30d434vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
42576743851c3c956ad7e867e74df1084c30d434vboxsync * The contents of this file may alternatively be used under the terms
42576743851c3c956ad7e867e74df1084c30d434vboxsync * of the Common Development and Distribution License Version 1.0
42576743851c3c956ad7e867e74df1084c30d434vboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
42576743851c3c956ad7e867e74df1084c30d434vboxsync * VirtualBox OSE distribution, in which case the provisions of the
42576743851c3c956ad7e867e74df1084c30d434vboxsync * CDDL are applicable instead of those of the GPL.
42576743851c3c956ad7e867e74df1084c30d434vboxsync * You may elect to license modified versions of this file under the
42576743851c3c956ad7e867e74df1084c30d434vboxsync * terms and conditions of either the GPL or the CDDL or both.
42576743851c3c956ad7e867e74df1084c30d434vboxsync/*******************************************************************************
42576743851c3c956ad7e867e74df1084c30d434vboxsync* Header Files *
42576743851c3c956ad7e867e74df1084c30d434vboxsync*******************************************************************************/
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync# include "/Developer/SDKs/MacOSX10.6.sdk/usr/include/sys/dtrace.h"
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync/*******************************************************************************
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync* Structures and Typedefs *
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync*******************************************************************************/
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync * Data for a provider.
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync /** The entry in the provider list for this image. */
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync /** The provider descriptor. */
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync /** The VTG header. */
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync /** Pointer to the image this provider resides in. NULL if it's a
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync * driver. */
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync /** The session this provider is associated with if registered via
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync * SUPR0VtgRegisterDrv. NULL if pImage is set. */
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync /** The module name. */
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync /** Dtrace provider attributes. */
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync /** The ID of this provider. */
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync/** Pointer to the data for a provider. */
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync/* Seems there is some return code difference here. Keep the return code and
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync case it to whatever the host desires. */
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsynctypedef void FNPOPS_ENABLE(void *, dtrace_id_t, void *);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsynctypedef int FNPOPS_ENABLE(void *, dtrace_id_t, void *);
42576743851c3c956ad7e867e74df1084c30d434vboxsync/*******************************************************************************
42576743851c3c956ad7e867e74df1084c30d434vboxsync* Internal Functions *
42576743851c3c956ad7e867e74df1084c30d434vboxsync*******************************************************************************/
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsyncstatic void supdrvDTracePOps_Provide(void *pvProv, const dtrace_probedesc_t *pDtProbeDesc);
42576743851c3c956ad7e867e74df1084c30d434vboxsyncstatic int supdrvDTracePOps_Enable(void *pvProv, dtrace_id_t idProbe, void *pvProbe);
42576743851c3c956ad7e867e74df1084c30d434vboxsyncstatic void supdrvDTracePOps_Disable(void *pvProv, dtrace_id_t idProbe, void *pvProbe);
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsyncstatic void supdrvDTracePOps_GetArgDesc(void *pvProv, dtrace_id_t idProbe, void *pvProbe,
a5af4f8add719046631d3d68734b9b6d9ca9d046vboxsync/*static uint64_t supdrvDTracePOps_GetArgVal(void *pvProv, dtrace_id_t idProbe, void *pvProbe,
a5af4f8add719046631d3d68734b9b6d9ca9d046vboxsync int iArg, int cFrames);*/
42576743851c3c956ad7e867e74df1084c30d434vboxsyncstatic void supdrvDTracePOps_Destroy(void *pvProv, dtrace_id_t idProbe, void *pvProbe);
42576743851c3c956ad7e867e74df1084c30d434vboxsync/*******************************************************************************
42576743851c3c956ad7e867e74df1084c30d434vboxsync* Global Variables *
42576743851c3c956ad7e867e74df1084c30d434vboxsync*******************************************************************************/
42576743851c3c956ad7e867e74df1084c30d434vboxsync/** The default provider attributes. */
42576743851c3c956ad7e867e74df1084c30d434vboxsync{ /* .dtat_name, .dtat_data, .dtat_class */
42576743851c3c956ad7e867e74df1084c30d434vboxsync /* .dtpa_provider = */ { DTRACE_STABILITY_UNSTABLE, DTRACE_STABILITY_UNSTABLE, DTRACE_CLASS_ISA },
42576743851c3c956ad7e867e74df1084c30d434vboxsync /* .dtpa_mod = */ { DTRACE_STABILITY_UNSTABLE, DTRACE_STABILITY_UNSTABLE, DTRACE_CLASS_ISA },
42576743851c3c956ad7e867e74df1084c30d434vboxsync /* .dtpa_func = */ { DTRACE_STABILITY_UNSTABLE, DTRACE_STABILITY_UNSTABLE, DTRACE_CLASS_ISA },
42576743851c3c956ad7e867e74df1084c30d434vboxsync /* .dtpa_name = */ { DTRACE_STABILITY_UNSTABLE, DTRACE_STABILITY_UNSTABLE, DTRACE_CLASS_ISA },
42576743851c3c956ad7e867e74df1084c30d434vboxsync /* .dtpa_args = */ { DTRACE_STABILITY_UNSTABLE, DTRACE_STABILITY_UNSTABLE, DTRACE_CLASS_ISA },
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync * DTrace provider method table.
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync /* .dtps_enable = */ (FNPOPS_ENABLE *)supdrvDTracePOps_Enable,
42576743851c3c956ad7e867e74df1084c30d434vboxsync /* .dtps_getargdesc = */ supdrvDTracePOps_GetArgDesc,
a5af4f8add719046631d3d68734b9b6d9ca9d046vboxsync /* .dtps_getargval = */ NULL/*supdrvDTracePOps_GetArgVal*/,
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync//#define VERR_SUPDRV_VTG_RESERVED (-3705)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync#define VERR_SUPDRV_VTG_BAD_HDR_NOT_MULTIPLE (-3709)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync#define VERR_SUPDRV_VTG_ONLY_ONCE_PER_SESSION (-1111)
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync * Validates the VTG data.
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync * @returns VBox status code.
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync * @param pVtgHdr The VTG object header of the data to validate.
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync * @param cbVtgObj The size of the VTG object.
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync * @param pbImage The image base. For validating the probe
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync * locations.
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync * @param cbImage The image size to go with @a pbImage.
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsyncstatic int supdrvVtgValidate(PVTGOBJHDR pVtgHdr, size_t cbVtgObj, const uint8_t *pbImage, size_t cbImage)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync#define MY_VALIDATE_PTR(p, cb, cMin, cMax, cbUnit, rcBase) \
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync || (uintptr_t)(p) - (uintptr_t)pVtgHdr < cbVtgObj - (cb) ) \
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync } while (0)
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync if ((uintptr_t)(p) - (uintptr_t)pbImage > cbImage) \
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync return (rc); \
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync else if (!RT_VALID_PTR(p)) \
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync return (rc); \
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync } while (0)
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync rc = supdrvVtgValidateString(pVtgHdr->pachStrTab + (offStrTab)); \
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync } while (0)
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync if ((Attr).u8Code <= (uint8_t)kVTGStability_Invalid || (Attr).u8Code >= (uint8_t)kVTGStability_End) \
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync if ((Attr).u8Data <= (uint8_t)kVTGStability_Invalid || (Attr).u8Data >= (uint8_t)kVTGStability_End) \
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync if ((Attr).u8DataDep <= (uint8_t)kVTGClass_Invalid || (Attr).u8DataDep >= (uint8_t)kVTGClass_End) \
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync } while (0)
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync * The header.
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync if (!memcmp(pVtgHdr->szMagic, VTGOBJHDR_MAGIC, sizeof(pVtgHdr->szMagic)))
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync MY_VALIDATE_PTR(pVtgHdr->paProviders, pVtgHdr->cbProviders, 1, 16, sizeof(VTGDESCPROVIDER), VERR_SUPDRV_VTG_BAD_HDR);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync MY_VALIDATE_PTR(pVtgHdr->paProbes, pVtgHdr->cbProbes, 1, _32K, sizeof(VTGDESCPROBE), VERR_SUPDRV_VTG_BAD_HDR);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync MY_VALIDATE_PTR(pVtgHdr->pafProbeEnabled, pVtgHdr->cbProbeEnabled, 1, _32K, sizeof(bool), VERR_SUPDRV_VTG_BAD_HDR);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync MY_VALIDATE_PTR(pVtgHdr->pachStrTab, pVtgHdr->cbStrTab, 4, _1M, sizeof(char), VERR_SUPDRV_VTG_BAD_HDR);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync MY_VALIDATE_PTR(pVtgHdr->paArgLists, pVtgHdr->cbArgLists, 1, _32K, sizeof(uint32_t), VERR_SUPDRV_VTG_BAD_HDR);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync MY_WITHIN_IMAGE(pVtgHdr->paProbLocs, VERR_SUPDRV_VTG_BAD_HDR_PTR);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync MY_WITHIN_IMAGE(pVtgHdr->paProbLocsEnd, VERR_SUPDRV_VTG_BAD_HDR_PTR);
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync if ((uintptr_t)pVtgHdr->paProbLocs > (uintptr_t)pVtgHdr->paProbLocsEnd)
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync cbTmp = (uintptr_t)pVtgHdr->paProbLocsEnd - (uintptr_t)pVtgHdr->paProbLocs;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync MY_VALIDATE_PTR(pVtgHdr->paProbLocs, cbTmp, 1, _128K, sizeof(VTGPROBELOC), VERR_SUPDRV_VTG_BAD_HDR);
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync if (pVtgHdr->cbProbes / sizeof(VTGDESCPROBE) != pVtgHdr->cbProbeEnabled)
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync * Validate the providers.
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync cProviders = i = pVtgHdr->cbProviders / sizeof(VTGDESCPROVIDER);
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync while (i-- > 0)
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync if (pVtgHdr->paProviders[i].iFirstProbe >= pVtgHdr->cbProbeEnabled)
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync if (pVtgHdr->paProviders[i].iFirstProbe + pVtgHdr->paProviders[i].cProbes > pVtgHdr->cbProbeEnabled)
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync MY_VALIDATE_ATTR(pVtgHdr->paProviders[i].AttrSelf);
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync MY_VALIDATE_ATTR(pVtgHdr->paProviders[i].AttrModules);
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync MY_VALIDATE_ATTR(pVtgHdr->paProviders[i].AttrFunctions);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync MY_VALIDATE_ATTR(pVtgHdr->paProviders[i].AttrNames);
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync MY_VALIDATE_ATTR(pVtgHdr->paProviders[i].AttrArguments);
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync * Validate probes.
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync while (i-- > 0)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync if (pVtgHdr->paProbes[i].offArgList >= pVtgHdr->cbArgLists)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync if (pVtgHdr->paProbes[i].idxEnabled != i) /* The lists are parallel. */
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync if (pVtgHdr->paProbes[i].idxProvider >= cProviders)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync if ( i - pVtgHdr->paProviders[pVtgHdr->paProbes[i].idxProvider].iFirstProbe
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync < pVtgHdr->paProviders[pVtgHdr->paProbes[i].idxProvider].cProbes)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync /* The referenced argument list. */
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync pArgList = (PVTGDESCARGLIST)((uintptr_t)pVtgHdr->paArgLists + pVtgHdr->paProbes[i].offArgList);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync while (iArg-- > 0)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync * Check that pafProbeEnabled is all zero.
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync while (i-- > 0)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync * Probe locations.
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync while (i-- > 0)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync MY_WITHIN_IMAGE(pVtgHdr->paProbLocs[i].pszFunction, VERR_SUPDRV_VTG_BAD_PROBE_LOC);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync MY_WITHIN_IMAGE(pVtgHdr->paProbLocs[i].pszFile, VERR_SUPDRV_VTG_BAD_PROBE_LOC);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync offTmp = (uintptr_t)pVtgHdr->paProbLocs[i].pbProbe - (uintptr_t)pVtgHdr->paProbes;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync if (offTmp / sizeof(VTGDESCPROBE) * sizeof(VTGDESCPROBE) != offTmp)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync * Converts an attribute from VTG description speak to DTrace.
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync * @param pDtAttr The DTrace attribute (dst).
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync * @param pVtgAttr The VTG attribute descriptor (src).
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsyncstatic void supdrvVtgConvAttr(dtrace_attribute_t *pDtAttr, PCVTGDESCATTR pVtgAttr)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync * Gets a string from the string table.
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync * @returns Pointer to the string.
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync * @param pVtgHdr The VTG object header.
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync * @param offStrTab The string table offset.
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsyncstatic const char *supdrvVtgGetString(PVTGOBJHDR pVtgHdr, uint32_t offStrTab)
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync * Registers the VTG tracepoint providers of a driver.
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync * @returns VBox status code.
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync * @param pszName The driver name.
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync * @param pVtgHdr The VTG object header.
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync * @param pVtgObj The size of the VTG object.
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync * @param pImage The image if applicable.
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync * @param pSession The session if applicable.
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync * @param pszModName The module name.
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsyncstatic int supdrvVtgRegister(PSUPDRVDEVEXT pDevExt, PVTGOBJHDR pVtgHdr, size_t cbVtgObj, PSUPDRVLDRIMAGE pImage, PSUPDRVSESSION pSession,
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync unsigned i;
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync * Validate input.
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync AssertPtrNullReturn(pSession, VERR_INVALID_POINTER);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync rc = supdrvVtgValidate(pVtgHdr, cbVtgObj, (const uint8_t *)pImage->pvImage, pImage->cbImageBits);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync rc = supdrvVtgValidate(pVtgHdr, cbVtgObj, NULL, 0);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync RTListForEach(&pDevExt->DtProviderList, pProv, SUPDRVDTPROVIDER, ListEntry)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync * Register the providers.
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync i = pVtgHdr->cbProviders / sizeof(VTGDESCPROVIDER);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync while (i-- > 0)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync pProv = (PSUPDRVDTPROVIDER)RTMemAllocZ(sizeof(*pProv));
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync supdrvVtgConvAttr(&pProv->DtAttrs.dtpa_provider, &pDesc->AttrSelf);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync supdrvVtgConvAttr(&pProv->DtAttrs.dtpa_mod, &pDesc->AttrModules);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync supdrvVtgConvAttr(&pProv->DtAttrs.dtpa_func, &pDesc->AttrFunctions);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync supdrvVtgConvAttr(&pProv->DtAttrs.dtpa_name, &pDesc->AttrNames);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync supdrvVtgConvAttr(&pProv->DtAttrs.dtpa_args, &pDesc->AttrArguments);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync rc = dtrace_register(supdrvVtgGetString(pVtgHdr, pDesc->offName),
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync RTListAppend(&pDevExt->DtProviderList, &pProv->ListEntry);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync RTListForEachReverseSafe(&pDevExt->DtProviderList, pProv, pProvNext, SUPDRVDTPROVIDER, ListEntry)
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync * Registers the VTG tracepoint providers of a driver.
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync * @returns VBox status code.
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync * @param pSession The support driver session handle.
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync * @param pVtgHdr The VTG header.
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync * @param pszName The driver name.
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsyncSUPR0DECL(int) SUPR0VtgRegisterDrv(PSUPDRVSESSION pSession, PVTGOBJHDR pVtgHdr, const char *pszName)
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync AssertReturn(SUP_IS_SESSION_VALID(pSession), NULL);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync return supdrvVtgRegister(pSession->pDevExt, pVtgHdr, _1M, NULL /*pImage*/, pSession, pszName);
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync * Deregister the VTG tracepoint providers of a driver.
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync * @param pSession The support driver session handle.
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync * @param pVtgHdr The VTG header.
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsyncSUPR0DECL(void) SUPR0VtgDeregisterDrv(PSUPDRVSESSION pSession)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync RTListForEachSafe(&pDevExt->DtProviderList, pProv, pProvNext, SUPDRVDTPROVIDER, ListEntry)
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync * Early module initialization hook.
42576743851c3c956ad7e867e74df1084c30d434vboxsync * @returns VBox status code.
42576743851c3c956ad7e867e74df1084c30d434vboxsync * @param pDevExt The device extension structure.
42576743851c3c956ad7e867e74df1084c30d434vboxsync * Register a provider for this module.
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync int rc = RTSemFastMutexCreate(&pDevExt->mtxDTrace);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync rc = supdrvVtgRegister(pDevExt, &g_VTGObjHeader, _1M, NULL /*pImage*/, NULL /*pSession*/, "vboxdrv");
42576743851c3c956ad7e867e74df1084c30d434vboxsync * Late module termination hook.
42576743851c3c956ad7e867e74df1084c30d434vboxsync * @returns VBox status code.
42576743851c3c956ad7e867e74df1084c30d434vboxsync * @param pDevExt The device extension structure.
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync * Unregister all probes (there should only be one).
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync RTListForEachSafe(&pDevExt->DtProviderList, pProv, pProvNext, SUPDRVDTPROVIDER, ListEntry)
42576743851c3c956ad7e867e74df1084c30d434vboxsync * Module loading hook, called before calling into the module.
42576743851c3c956ad7e867e74df1084c30d434vboxsync * @returns VBox status code.
42576743851c3c956ad7e867e74df1084c30d434vboxsync * @param pDevExt The device extension structure.
42576743851c3c956ad7e867e74df1084c30d434vboxsyncint supdrvDTraceModuleLoading(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage)
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync * Check for DTrace probes in the module, register a new provider for them
42576743851c3c956ad7e867e74df1084c30d434vboxsync * if found.
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync * Module unloading hook, called after execution in the module
42576743851c3c956ad7e867e74df1084c30d434vboxsync * have ceased.
42576743851c3c956ad7e867e74df1084c30d434vboxsync * @returns VBox status code.
42576743851c3c956ad7e867e74df1084c30d434vboxsync * @param pDevExt The device extension structure.
42576743851c3c956ad7e867e74df1084c30d434vboxsyncint supdrvDTraceModuleUnloading(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage)
42576743851c3c956ad7e867e74df1084c30d434vboxsync * Undo what we did in supdrvDTraceModuleLoading.
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync * @callback_method_impl{dtrace_pops_t,dtps_provide}
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsyncstatic void supdrvDTracePOps_Provide(void *pvProv, const dtrace_probedesc_t *pDtProbeDesc)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync PSUPDRVDTPROVIDER pProv = (PSUPDRVDTPROVIDER)pvProv;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync uint16_t const idxProv = (uint16_t)(&pProv->pHdr->paProviders[0] - pProv->pDesc);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync return; /* We don't generate probes, so never mind these requests. */
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync /* Need a buffer for extracting the function names and mangling them in
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync case of collision. */
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync * Itereate the probe location list and register all probes related to
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync * this provider.
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync while ((uintptr_t)pProbeLoc < (uintptr_t)pProbeLocEnd)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync PVTGDESCPROBE pProbeDesc = (PVTGDESCPROBE)pProbeLoc->pbProbe;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync /* The function name normally needs to be stripped since we're
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync using C++ compilers for most of the code. ASSUMES nobody are
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync brave/stupid enough to use function pointer returns without
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync typedef'ing properly them. */
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync const char *pszName = supdrvVtgGetString(pProv->pHdr, pProbeDesc->offName);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync const char *psz = strchr(pProbeLoc->pszFunction, '(');
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync pszFunc = psz - 1; /* ASSUMES not space... FIXME */
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync while ((uintptr_t)pszFunc > (uintptr_t)pProbeLoc->pszFunction)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync /* Look up the probe, if we have one in the same function, mangle
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync the function name a little to avoid having to deal with having
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync multiple location entries with the same probe ID. (lazy bird) */
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync //dtrace_probe_lookup()
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync //dtrace_probe_create()
42576743851c3c956ad7e867e74df1084c30d434vboxsync * @callback_method_impl{dtrace_pops_t,dtps_enable}
42576743851c3c956ad7e867e74df1084c30d434vboxsyncstatic int supdrvDTracePOps_Enable(void *pvProv, dtrace_id_t idProbe, void *pvProbe)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync PVTGDESCPROBE pProbeDesc = (PVTGDESCPROBE)pProbeLoc->pbProbe;
42576743851c3c956ad7e867e74df1084c30d434vboxsync * @callback_method_impl{dtrace_pops_t,dtps_disable}
42576743851c3c956ad7e867e74df1084c30d434vboxsyncstatic void supdrvDTracePOps_Disable(void *pvProv, dtrace_id_t idProbe, void *pvProbe)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync PVTGDESCPROBE pProbeDesc = (PVTGDESCPROBE)pProbeLoc->pbProbe;
42576743851c3c956ad7e867e74df1084c30d434vboxsync * @callback_method_impl{dtrace_pops_t,dtps_getargdesc}
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsyncstatic void supdrvDTracePOps_GetArgDesc(void *pvProv, dtrace_id_t idProbe, void *pvProbe,
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync PSUPDRVDTPROVIDER pProv = (PSUPDRVDTPROVIDER)pvProv;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync PVTGDESCPROBE pProbeDesc = (PVTGDESCPROBE)pProbeLoc->pbProbe;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync PVTGDESCARGLIST pArgList = (PVTGDESCARGLIST)((uintptr_t)pProv->pHdr->paArgLists + pProbeDesc->offArgList);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync Assert(pProbeDesc->offArgList < pProv->pHdr->cbArgLists);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync const char *pszType = supdrvVtgGetString(pProv->pHdr, pArgList->aArgs[pArgDesc->dtargd_ndx].offType);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync memcpy(pArgDesc->dtargd_native, pszType, cchType + 1);
42576743851c3c956ad7e867e74df1084c30d434vboxsync * @callback_method_impl{dtrace_pops_t,dtps_getargval}
42576743851c3c956ad7e867e74df1084c30d434vboxsyncstatic uint64_t supdrvDTracePOps_GetArgVal(void *pvProv, dtrace_id_t idProbe, void *pvProbe,
42576743851c3c956ad7e867e74df1084c30d434vboxsync return 0xbeef;
42576743851c3c956ad7e867e74df1084c30d434vboxsync * @callback_method_impl{dtrace_pops_t,dtps_destroy}
42576743851c3c956ad7e867e74df1084c30d434vboxsyncstatic void supdrvDTracePOps_Destroy(void *pvProv, dtrace_id_t idProbe, void *pvProbe)