SUPDrv-dtrace.cpp revision e80aaa9a63f82ac2cece3a2d5a415774a72b0c82
42576743851c3c956ad7e867e74df1084c30d434vboxsync/* $Id$ */
42576743851c3c956ad7e867e74df1084c30d434vboxsync/** @file
42576743851c3c956ad7e867e74df1084c30d434vboxsync * VBoxDrv - The VirtualBox Support Driver - DTrace Provider.
42576743851c3c956ad7e867e74df1084c30d434vboxsync */
42576743851c3c956ad7e867e74df1084c30d434vboxsync
42576743851c3c956ad7e867e74df1084c30d434vboxsync/*
42576743851c3c956ad7e867e74df1084c30d434vboxsync * Copyright (C) 2012 Oracle Corporation
42576743851c3c956ad7e867e74df1084c30d434vboxsync *
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 *
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 *
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
42576743851c3c956ad7e867e74df1084c30d434vboxsync
42576743851c3c956ad7e867e74df1084c30d434vboxsync/*******************************************************************************
42576743851c3c956ad7e867e74df1084c30d434vboxsync* Header Files *
42576743851c3c956ad7e867e74df1084c30d434vboxsync*******************************************************************************/
42576743851c3c956ad7e867e74df1084c30d434vboxsync#define LOG_GROUP LOG_GROUP_SUP_DRV
42576743851c3c956ad7e867e74df1084c30d434vboxsync#include "SUPDrvInternal.h"
42576743851c3c956ad7e867e74df1084c30d434vboxsync
42576743851c3c956ad7e867e74df1084c30d434vboxsync#include <VBox/err.h>
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync#include <VBox/log.h>
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync#include <VBox/VBoxTpG.h>
42576743851c3c956ad7e867e74df1084c30d434vboxsync
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync#include <iprt/assert.h>
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync#include <iprt/ctype.h>
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync#include <iprt/list.h>
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync#include <iprt/mem.h>
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync#include <iprt/semaphore.h>
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync#include <iprt/thread.h>
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync#ifdef RT_OS_DARWIN /** @todo figure this! */
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync# include "/Developer/SDKs/MacOSX10.6.sdk/usr/include/sys/dtrace.h"
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync#else
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync# include <sys/dtrace.h>
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync#endif
42576743851c3c956ad7e867e74df1084c30d434vboxsync
42576743851c3c956ad7e867e74df1084c30d434vboxsync
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync/*******************************************************************************
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync* Structures and Typedefs *
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync*******************************************************************************/
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync/**
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync * Data for a provider.
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync */
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsynctypedef struct SUPDRVDTPROVIDER
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync{
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync /** The entry in the provider list for this image. */
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync RTLISTNODE ListEntry;
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync /** The provider descriptor. */
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync PVTGDESCPROVIDER pDesc;
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync /** The VTG header. */
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync PVTGOBJHDR pHdr;
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync /** Pointer to the image this provider resides in. NULL if it's a
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync * driver. */
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync PSUPDRVLDRIMAGE pImage;
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync /** The session this provider is associated with if registered via
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync * SUPR0VtgRegisterDrv. NULL if pImage is set. */
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync PSUPDRVSESSION pSession;
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync /** The module name. */
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync const char *pszModName;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync /** Dtrace provider attributes. */
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync dtrace_pattr_t DtAttrs;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync /** The ID of this provider. */
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync dtrace_provider_id_t idDtProv;
06b49f334535705aeae0ac0572fc5142dc589153vboxsync /** The number of probes we've provided to DTrace. */
06b49f334535705aeae0ac0572fc5142dc589153vboxsync uint32_t cProvidedProbes;
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync /** Set when the module is unloaded or the driver deregisters its probes. */
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync bool fZombie;
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync /** The provider name (for logging purposes). */
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync char szName[1];
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync} SUPDRVDTPROVIDER;
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync/** Pointer to the data for a provider. */
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsynctypedef SUPDRVDTPROVIDER *PSUPDRVDTPROVIDER;
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync/* Seems there is some return code difference here. Keep the return code and
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync case it to whatever the host desires. */
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync#ifdef RT_OS_DARWIN
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsynctypedef void FNPOPS_ENABLE(void *, dtrace_id_t, void *);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync#else
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsynctypedef int FNPOPS_ENABLE(void *, dtrace_id_t, void *);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync#endif
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync
42576743851c3c956ad7e867e74df1084c30d434vboxsync
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync/*******************************************************************************
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync* Defined Constants And Macros *
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync*******************************************************************************/
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync#if 0
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync# define LOG_DTRACE(a_Args) SUPR0Printf a_Args
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync#else
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync# define LOG_DTRACE(a_Args) do { } while (0)
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync#endif
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync
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,
42576743851c3c956ad7e867e74df1084c30d434vboxsync dtrace_argdesc_t *pArgDesc);
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync#ifdef RT_OS_SOLARIS
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsyncstatic uint64_t supdrvDTracePOps_GetArgVal(void *pvProv, dtrace_id_t idProbe, void *pvProbe,
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync int iArg, int cFrames);
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync#endif
42576743851c3c956ad7e867e74df1084c30d434vboxsyncstatic void supdrvDTracePOps_Destroy(void *pvProv, dtrace_id_t idProbe, void *pvProbe);
42576743851c3c956ad7e867e74df1084c30d434vboxsync
42576743851c3c956ad7e867e74df1084c30d434vboxsync
42576743851c3c956ad7e867e74df1084c30d434vboxsync
42576743851c3c956ad7e867e74df1084c30d434vboxsync/*******************************************************************************
42576743851c3c956ad7e867e74df1084c30d434vboxsync* Global Variables *
42576743851c3c956ad7e867e74df1084c30d434vboxsync*******************************************************************************/
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync/**
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync * DTrace provider method table.
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync */
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsyncstatic const dtrace_pops_t g_SupDrvDTraceProvOps =
42576743851c3c956ad7e867e74df1084c30d434vboxsync{
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync /* .dtps_provide = */ supdrvDTracePOps_Provide,
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync /* .dtps_provide_module = */ NULL,
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync /* .dtps_enable = */ (FNPOPS_ENABLE *)supdrvDTracePOps_Enable,
42576743851c3c956ad7e867e74df1084c30d434vboxsync /* .dtps_disable = */ supdrvDTracePOps_Disable,
42576743851c3c956ad7e867e74df1084c30d434vboxsync /* .dtps_suspend = */ NULL,
42576743851c3c956ad7e867e74df1084c30d434vboxsync /* .dtps_resume = */ NULL,
42576743851c3c956ad7e867e74df1084c30d434vboxsync /* .dtps_getargdesc = */ supdrvDTracePOps_GetArgDesc,
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync#ifdef RT_OS_SOLARIS
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync /* .dtps_getargval = */ supdrvDTracePOps_GetArgVal,
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync#else
a5af4f8add719046631d3d68734b9b6d9ca9d046vboxsync /* .dtps_getargval = */ NULL/*supdrvDTracePOps_GetArgVal*/,
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync#endif
42576743851c3c956ad7e867e74df1084c30d434vboxsync /* .dtps_usermode = */ NULL,
42576743851c3c956ad7e867e74df1084c30d434vboxsync /* .dtps_destroy = */ supdrvDTracePOps_Destroy
42576743851c3c956ad7e867e74df1084c30d434vboxsync};
42576743851c3c956ad7e867e74df1084c30d434vboxsync
42576743851c3c956ad7e867e74df1084c30d434vboxsync
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsyncstatic int supdrvVtgValidateString(const char *psz)
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync{
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync size_t off = 0;
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync while (off < _4K)
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync {
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync char const ch = psz[off++];
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync if (!ch)
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync return VINF_SUCCESS;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync if ( !RTLocCIsAlNum(ch)
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync && ch != ' '
17290b489de4e6b4dd97bb37d815821246075668vboxsync && ch != '_'
17290b489de4e6b4dd97bb37d815821246075668vboxsync && ch != '-'
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync && ch != '('
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync && ch != ')'
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync && ch != ','
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync && ch != '*'
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync && ch != '&'
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync )
17290b489de4e6b4dd97bb37d815821246075668vboxsync {
17290b489de4e6b4dd97bb37d815821246075668vboxsync /*RTAssertMsg2("off=%u '%s'\n", off, psz);*/
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync return VERR_SUPDRV_VTG_BAD_STRING;
17290b489de4e6b4dd97bb37d815821246075668vboxsync }
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync }
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync return VERR_SUPDRV_VTG_STRING_TOO_LONG;
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync}
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync/**
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync * Validates the VTG data.
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync *
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.
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync */
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsyncstatic int supdrvVtgValidate(PVTGOBJHDR pVtgHdr, size_t cbVtgObj, const uint8_t *pbImage, size_t cbImage)
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync{
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync uintptr_t cbTmp;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync uintptr_t offTmp;
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync uintptr_t i;
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync int rc;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync uint32_t cProviders;
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync if (!pbImage || !cbImage)
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync {
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync pbImage = NULL;
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync cbImage = 0;
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync }
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync#define MY_VALIDATE_PTR(p, cb, cMin, cMax, cbUnit, rcBase) \
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync do { \
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync if ( (cb) >= cbVtgObj \
17290b489de4e6b4dd97bb37d815821246075668vboxsync || (uintptr_t)(p) - (uintptr_t)pVtgHdr > cbVtgObj - (cb) ) \
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync return rcBase ## _PTR; \
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync if ((cb) < (cMin) * (cbUnit)) \
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync return rcBase ## _TOO_FEW; \
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync if ((cb) >= (cMax) * (cbUnit)) \
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync return rcBase ## _TOO_MUCH; \
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync if ((cb) / (cbUnit) * (cbUnit) != (cb)) \
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync return rcBase ## _NOT_MULTIPLE; \
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync } while (0)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync#define MY_WITHIN_IMAGE(p, rc) \
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync do { \
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync if (pbImage) \
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync { \
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync if ((uintptr_t)(p) - (uintptr_t)pbImage > cbImage) \
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync return (rc); \
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync } \
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync else if (!RT_VALID_PTR(p)) \
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync return (rc); \
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync } while (0)
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync#define MY_VALIDATE_STR(offStrTab) \
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync do { \
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync if ((offStrTab) >= pVtgHdr->cbStrTab) \
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync return VERR_SUPDRV_VTG_STRTAB_OFF; \
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync rc = supdrvVtgValidateString(pVtgHdr->pachStrTab + (offStrTab)); \
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync if (rc != VINF_SUCCESS) \
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync return rc; \
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync } while (0)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync#define MY_VALIDATE_ATTR(Attr) \
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync do { \
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync if ((Attr).u8Code <= (uint8_t)kVTGStability_Invalid || (Attr).u8Code >= (uint8_t)kVTGStability_End) \
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync return VERR_SUPDRV_VTG_BAD_ATTR; \
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync if ((Attr).u8Data <= (uint8_t)kVTGStability_Invalid || (Attr).u8Data >= (uint8_t)kVTGStability_End) \
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync return VERR_SUPDRV_VTG_BAD_ATTR; \
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync if ((Attr).u8DataDep <= (uint8_t)kVTGClass_Invalid || (Attr).u8DataDep >= (uint8_t)kVTGClass_End) \
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync return VERR_SUPDRV_VTG_BAD_ATTR; \
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync } while (0)
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync /*
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync * The header.
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync */
17290b489de4e6b4dd97bb37d815821246075668vboxsync if (memcmp(pVtgHdr->szMagic, VTGOBJHDR_MAGIC, sizeof(pVtgHdr->szMagic)))
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync return VERR_SUPDRV_VTG_MAGIC;
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync if (pVtgHdr->cBits != ARCH_BITS)
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync return VERR_SUPDRV_VTG_BITS;
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync if (pVtgHdr->u32Reserved0)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync return VERR_SUPDRV_VTG_BAD_HDR;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync
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);
17290b489de4e6b4dd97bb37d815821246075668vboxsync
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)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync return VERR_SUPDRV_VTG_BAD_HDR_PTR;
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync cbTmp = (uintptr_t)pVtgHdr->paProbLocsEnd - (uintptr_t)pVtgHdr->paProbLocs;
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync if (cbTmp < sizeof(VTGPROBELOC))
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync return VERR_SUPDRV_VTG_BAD_HDR_TOO_FEW;
17290b489de4e6b4dd97bb37d815821246075668vboxsync if (cbTmp >= _128K * sizeof(VTGPROBELOC))
17290b489de4e6b4dd97bb37d815821246075668vboxsync return VERR_SUPDRV_VTG_BAD_HDR_TOO_MUCH;
17290b489de4e6b4dd97bb37d815821246075668vboxsync if (cbTmp / sizeof(VTGPROBELOC) * sizeof(VTGPROBELOC) != cbTmp)
17290b489de4e6b4dd97bb37d815821246075668vboxsync return VERR_SUPDRV_VTG_BAD_HDR_NOT_MULTIPLE;
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync if (pVtgHdr->cbProbes / sizeof(VTGDESCPROBE) != pVtgHdr->cbProbeEnabled)
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync return VERR_SUPDRV_VTG_BAD_HDR;
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync /*
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync * Validate the providers.
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync */
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync cProviders = i = pVtgHdr->cbProviders / sizeof(VTGDESCPROVIDER);
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync while (i-- > 0)
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync {
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync MY_VALIDATE_STR(pVtgHdr->paProviders[i].offName);
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync if (pVtgHdr->paProviders[i].iFirstProbe >= pVtgHdr->cbProbeEnabled)
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync return VERR_SUPDRV_VTG_BAD_PROVIDER;
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync if (pVtgHdr->paProviders[i].iFirstProbe + pVtgHdr->paProviders[i].cProbes > pVtgHdr->cbProbeEnabled)
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync return VERR_SUPDRV_VTG_BAD_PROVIDER;
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 if (pVtgHdr->paProviders[i].bReserved)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync return VERR_SUPDRV_VTG_BAD_PROVIDER;
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync }
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync /*
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync * Validate probes.
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync */
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync i = pVtgHdr->cbProbes / sizeof(VTGDESCPROBE);
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync while (i-- > 0)
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync {
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync PVTGDESCARGLIST pArgList;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync unsigned iArg;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync MY_VALIDATE_STR(pVtgHdr->paProbes[i].offName);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync if (pVtgHdr->paProbes[i].offArgList >= pVtgHdr->cbArgLists)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync return VERR_SUPDRV_VTG_BAD_PROBE;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync if (pVtgHdr->paProbes[i].offArgList & 3)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync return VERR_SUPDRV_VTG_BAD_PROBE;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync if (pVtgHdr->paProbes[i].idxEnabled != i) /* The lists are parallel. */
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync return VERR_SUPDRV_VTG_BAD_PROBE;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync if (pVtgHdr->paProbes[i].idxProvider >= cProviders)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync return VERR_SUPDRV_VTG_BAD_PROBE;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync if ( i - pVtgHdr->paProviders[pVtgHdr->paProbes[i].idxProvider].iFirstProbe
17290b489de4e6b4dd97bb37d815821246075668vboxsync >= pVtgHdr->paProviders[pVtgHdr->paProbes[i].idxProvider].cProbes)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync return VERR_SUPDRV_VTG_BAD_PROBE;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync if (pVtgHdr->paProbes[i].u32User)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync return VERR_SUPDRV_VTG_BAD_PROBE;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync /* The referenced argument list. */
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync pArgList = (PVTGDESCARGLIST)((uintptr_t)pVtgHdr->paArgLists + pVtgHdr->paProbes[i].offArgList);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync if (pArgList->cArgs > 16)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync return VERR_SUPDRV_VTG_BAD_ARGLIST;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync if ( pArgList->abReserved[0]
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync || pArgList->abReserved[1]
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync || pArgList->abReserved[2])
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync return VERR_SUPDRV_VTG_BAD_ARGLIST;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync iArg = pArgList->cArgs;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync while (iArg-- > 0)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync {
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync MY_VALIDATE_STR(pArgList->aArgs[iArg].offType);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync MY_VALIDATE_STR(pArgList->aArgs[iArg].offName);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync }
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync }
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync /*
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync * Check that pafProbeEnabled is all zero.
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync */
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync i = pVtgHdr->cbProbeEnabled;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync while (i-- > 0)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync if (pVtgHdr->pafProbeEnabled[0])
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync return VERR_SUPDRV_VTG_BAD_PROBE_ENABLED;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync /*
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync * Probe locations.
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync */
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync i = pVtgHdr->paProbLocsEnd - pVtgHdr->paProbLocs;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync while (i-- > 0)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync {
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync if (pVtgHdr->paProbLocs[i].uLine >= _1G)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync return VERR_SUPDRV_VTG_BAD_PROBE_LOC;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync if (pVtgHdr->paProbLocs[i].fEnabled)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync return VERR_SUPDRV_VTG_BAD_PROBE_LOC;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync if (pVtgHdr->paProbLocs[i].idProbe != UINT32_MAX)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync return VERR_SUPDRV_VTG_BAD_PROBE_LOC;
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 >= pVtgHdr->cbProbes)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync return VERR_SUPDRV_VTG_BAD_PROBE_LOC;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync if (offTmp / sizeof(VTGDESCPROBE) * sizeof(VTGDESCPROBE) != offTmp)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync return VERR_SUPDRV_VTG_BAD_PROBE_LOC;
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync }
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync return VINF_SUCCESS;
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync#undef MY_VALIDATE_STR
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync#undef MY_VALIDATE_PTR
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync#undef MY_WITHIN_IMAGE
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync}
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync/**
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync * Converts an attribute from VTG description speak to DTrace.
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync *
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync * @param pDtAttr The DTrace attribute (dst).
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync * @param pVtgAttr The VTG attribute descriptor (src).
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync */
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsyncstatic void supdrvVtgConvAttr(dtrace_attribute_t *pDtAttr, PCVTGDESCATTR pVtgAttr)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync{
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync pDtAttr->dtat_name = pVtgAttr->u8Code - 1;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync pDtAttr->dtat_data = pVtgAttr->u8Data - 1;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync pDtAttr->dtat_class = pVtgAttr->u8DataDep - 1;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync}
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync/**
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync * Gets a string from the string table.
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync *
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync * @returns Pointer to the string.
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync * @param pVtgHdr The VTG object header.
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync * @param offStrTab The string table offset.
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync */
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsyncstatic const char *supdrvVtgGetString(PVTGOBJHDR pVtgHdr, uint32_t offStrTab)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync{
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync Assert(offStrTab < pVtgHdr->cbStrTab);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync return &pVtgHdr->pachStrTab[offStrTab];
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync}
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync
42576743851c3c956ad7e867e74df1084c30d434vboxsync
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync/**
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync * Frees the provider structure and associated resources.
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync *
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync * @param pProv The provider to free.
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync */
b32be08cd134577ca98e517c019c867c416ec0f2vboxsyncstatic void supdrvVtgFreeProvider(PSUPDRVDTPROVIDER pProv)
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync{
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync LOG_DTRACE(("Freeing DTrace provider '%s' / %p\n", pProv->szName, pProv->idDtProv));
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync pProv->fZombie = true;
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync pProv->pDesc = NULL;
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync pProv->pHdr = NULL;
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync RTMemFree(pProv);
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync}
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync/**
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync * Deregisters a provider.
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync *
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync * If the provider is still busy, it will be put in the zombie list.
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync *
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync * @param pDevExt The device extension.
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync * @param pProv The provider.
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync *
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync * @remarks The caller owns mtxDTrace.
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync */
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsyncstatic void supdrvVtgDeregister(PSUPDRVDEVEXT pDevExt, PSUPDRVDTPROVIDER pProv)
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync{
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync int rc;
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync dtrace_invalidate(pProv->idDtProv);
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync rc = dtrace_unregister(pProv->idDtProv);
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync if (!rc)
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync {
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync supdrvVtgFreeProvider(pProv);
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync return;
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync }
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync pProv->fZombie = true;
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync RTListAppend(&pDevExt->DtProviderZombieList, &pProv->ListEntry);
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync LOG_DTRACE(("Invalidate DTrace provider '%s' / %p and put it on the zombie list\n", pProv->szName, pProv->idDtProv));
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync}
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync/**
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync * Processes the zombie list.
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync *
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync * @param pDevExt The device extension.
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync */
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsyncstatic void supdrvVtgProcessZombies(PSUPDRVDEVEXT pDevExt)
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync{
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync PSUPDRVDTPROVIDER pProv, pProvNext;
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync RTSemFastMutexRequest(pDevExt->mtxDTrace);
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync RTListForEachSafe(&pDevExt->DtProviderZombieList, pProv, pProvNext, SUPDRVDTPROVIDER, ListEntry)
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync {
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync int rc = dtrace_unregister(pProv->idDtProv);
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync if (!rc)
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync {
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync RTListNodeRemove(&pProv->ListEntry);
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync supdrvVtgFreeProvider(pProv);
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync }
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync }
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync RTSemFastMutexRelease(pDevExt->mtxDTrace);
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync}
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync
42576743851c3c956ad7e867e74df1084c30d434vboxsync/**
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync * Registers the VTG tracepoint providers of a driver.
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync *
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.
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync */
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsyncstatic int supdrvVtgRegister(PSUPDRVDEVEXT pDevExt, PVTGOBJHDR pVtgHdr, size_t cbVtgObj, PSUPDRVLDRIMAGE pImage,
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync PSUPDRVSESSION pSession, const char *pszModName)
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync{
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync int rc;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync unsigned i;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync PSUPDRVDTPROVIDER pProv;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync /*
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync * Validate input.
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync */
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync AssertPtrReturn(pDevExt, VERR_INVALID_POINTER);
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync AssertPtrReturn(pVtgHdr, VERR_INVALID_POINTER);
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync AssertPtrNullReturn(pImage, VERR_INVALID_POINTER);
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync AssertPtrNullReturn(pSession, VERR_INVALID_POINTER);
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync AssertPtrReturn(pszModName, VERR_INVALID_POINTER);
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync if (pImage)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync rc = supdrvVtgValidate(pVtgHdr, cbVtgObj, (const uint8_t *)pImage->pvImage, pImage->cbImageBits);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync else
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync rc = supdrvVtgValidate(pVtgHdr, cbVtgObj, NULL, 0);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync if (RT_FAILURE(rc))
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync return rc;
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync rc = RTSemFastMutexRequest(pDevExt->mtxDTrace);
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync if (RT_FAILURE(rc))
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync return rc;
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync RTListForEach(&pDevExt->DtProviderList, pProv, SUPDRVDTPROVIDER, ListEntry)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync {
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync if (pProv->pHdr == pVtgHdr)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync {
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync rc = VERR_SUPDRV_VTG_ALREADY_REGISTERED;
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync break;
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync }
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync if ( pProv->pSession == pSession
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync && pProv->pImage == pImage)
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync {
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync rc = VERR_SUPDRV_VTG_ONLY_ONCE_PER_SESSION;
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync break;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync }
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync }
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync RTSemFastMutexRelease(pDevExt->mtxDTrace);
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync if (RT_FAILURE(rc))
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync return rc;
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync /*
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync * Register the providers.
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync */
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync i = pVtgHdr->cbProviders / sizeof(VTGDESCPROVIDER);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync while (i-- > 0)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync {
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync PVTGDESCPROVIDER pDesc = &pVtgHdr->paProviders[i];
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync const char *pszName = supdrvVtgGetString(pVtgHdr, pDesc->offName);
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync size_t const cchName = strlen(pszName);
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync pProv = (PSUPDRVDTPROVIDER)RTMemAllocZ(RT_OFFSETOF(SUPDRVDTPROVIDER, szName[cchName + 1]));
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync if (pProv)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync {
06b49f334535705aeae0ac0572fc5142dc589153vboxsync pProv->pDesc = pDesc;
06b49f334535705aeae0ac0572fc5142dc589153vboxsync pProv->pHdr = pVtgHdr;
06b49f334535705aeae0ac0572fc5142dc589153vboxsync pProv->pImage = pImage;
06b49f334535705aeae0ac0572fc5142dc589153vboxsync pProv->pSession = pSession;
06b49f334535705aeae0ac0572fc5142dc589153vboxsync pProv->pszModName = pszModName;
06b49f334535705aeae0ac0572fc5142dc589153vboxsync pProv->idDtProv = 0;
06b49f334535705aeae0ac0572fc5142dc589153vboxsync pProv->cProvidedProbes = 0;
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync pProv->fZombie = false;
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync memcpy(pProv->szName, pszName, cchName + 1);
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
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync rc = dtrace_register(pProv->szName,
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync &pProv->DtAttrs,
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync DTRACE_PRIV_KERNEL,
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync NULL /* cred */,
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync &g_SupDrvDTraceProvOps,
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync pProv,
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync &pProv->idDtProv);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync if (!rc)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync {
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync rc = RTSemFastMutexRequest(pDevExt->mtxDTrace);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync if (RT_SUCCESS(rc))
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync {
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync RTListAppend(&pDevExt->DtProviderList, &pProv->ListEntry);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync RTSemFastMutexRelease(pDevExt->mtxDTrace);
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync LOG_DTRACE(("Registered DTrace provider '%s' in '%s' -> %p\n", pProv->szName, pszModName, pProv->idDtProv));
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync }
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync else
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync dtrace_unregister(pProv->idDtProv);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync }
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync else
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync rc = RTErrConvertFromErrno(rc);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync }
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync else
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync rc = VERR_NO_MEMORY;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync if (RT_FAILURE(rc))
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync {
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync PSUPDRVDTPROVIDER pProvNext;
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync supdrvVtgFreeProvider(pProv);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync RTSemFastMutexRequest(pDevExt->mtxDTrace);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync RTListForEachReverseSafe(&pDevExt->DtProviderList, pProv, pProvNext, SUPDRVDTPROVIDER, ListEntry)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync {
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync if (pProv->pHdr == pVtgHdr)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync {
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync RTListNodeRemove(&pProv->ListEntry);
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync supdrvVtgDeregister(pDevExt, pProv);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync }
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync }
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync RTSemFastMutexRelease(pDevExt->mtxDTrace);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync return rc;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync }
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync }
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync return VINF_SUCCESS;
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync}
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync/**
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync * Registers the VTG tracepoint providers of a driver.
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync *
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.
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync */
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsyncSUPR0DECL(int) SUPR0VtgRegisterDrv(PSUPDRVSESSION pSession, PVTGOBJHDR pVtgHdr, const char *pszName)
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync{
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync int rc;
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync
152aa5dc8bf917aa0a3f91b01869a74e062281dcvboxsync AssertReturn(SUP_IS_SESSION_VALID(pSession), VERR_INVALID_PARAMETER);
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync AssertPtrReturn(pszName, VERR_INVALID_POINTER);
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync AssertPtrReturn(pVtgHdr, VERR_INVALID_POINTER);
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync AssertReturn(pSession->R0Process == NIL_RTR0PROCESS, VERR_INVALID_PARAMETER);
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync rc = supdrvVtgRegister(pSession->pDevExt, pVtgHdr, _1M, NULL /*pImage*/, pSession, pszName);
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync /*
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync * Try unregister zombies while we have a chance.
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync */
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync supdrvVtgProcessZombies(pSession->pDevExt);
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync return rc;
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync}
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync/**
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync * Deregister the VTG tracepoint providers of a driver.
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync *
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync * @param pSession The support driver session handle.
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync * @param pVtgHdr The VTG header.
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync */
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsyncSUPR0DECL(void) SUPR0VtgDeregisterDrv(PSUPDRVSESSION pSession)
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync{
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync PSUPDRVDTPROVIDER pProv, pProvNext;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync PSUPDRVDEVEXT pDevExt;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync AssertReturnVoid(SUP_IS_SESSION_VALID(pSession));
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync AssertReturnVoid(pSession->R0Process == NIL_RTR0PROCESS);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync pDevExt = pSession->pDevExt;
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync /*
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync * Search for providers belonging to this driver session.
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync */
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync RTSemFastMutexRequest(pDevExt->mtxDTrace);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync RTListForEachSafe(&pDevExt->DtProviderList, pProv, pProvNext, SUPDRVDTPROVIDER, ListEntry)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync {
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync if (pProv->pSession == pSession)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync {
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync RTListNodeRemove(&pProv->ListEntry);
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync supdrvVtgDeregister(pDevExt, pProv);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync }
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync }
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync RTSemFastMutexRelease(pDevExt->mtxDTrace);
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync /*
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync * Try unregister zombies while we have a chance.
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync */
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync supdrvVtgProcessZombies(pDevExt);
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync}
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync/**
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync * Registers the VTG tracepoint providers of a module loaded by
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync * the support driver.
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync *
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync * This should be called from the ModuleInit code.
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync *
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync * @returns VBox status code.
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync * @param hMod The module handle.
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync * @param pVtgHdr The VTG header.
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync */
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsyncSUPR0DECL(int) SUPR0VtgRegisterModule(void *hMod, PVTGOBJHDR pVtgHdr)
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync{
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync PSUPDRVLDRIMAGE pImage = (PSUPDRVLDRIMAGE)hMod;
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync PSUPDRVDEVEXT pDevExt;
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync uintptr_t cbVtgObj;
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync int rc;
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync /*
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync * Validate input and context.
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync */
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync AssertPtrReturn(pImage, VERR_INVALID_HANDLE);
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync AssertPtrReturn(pVtgHdr, VERR_INVALID_POINTER);
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync pDevExt = pImage->pDevExt;
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync AssertPtrReturn(pDevExt, VERR_INVALID_POINTER);
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync AssertReturn(pDevExt->pLdrInitImage == pImage, VERR_WRONG_ORDER);
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync AssertReturn(pDevExt->hLdrInitThread == RTThreadNativeSelf(), VERR_WRONG_ORDER);
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync /*
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync * Calculate the max VTG object size and hand it over to the common code.
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync */
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync cbVtgObj = (uintptr_t)pVtgHdr - (uintptr_t)pImage->pvImage;
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync AssertMsgReturn(cbVtgObj /*off*/ < pImage->cbImageBits,
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync ("pVtgHdr=%p offVtgObj=%p cbImageBits=%p\n", pVtgHdr, cbVtgObj, pImage->cbImageBits),
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync VERR_INVALID_PARAMETER);
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync cbVtgObj = pImage->cbImageBits - cbVtgObj;
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync rc = supdrvVtgRegister(pDevExt, pVtgHdr, cbVtgObj, pImage, NULL, pImage->szName);
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync /*
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync * Try unregister zombies while we have a chance.
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync */
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync supdrvVtgProcessZombies(pDevExt);
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync return rc;
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync}
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync/**
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync * Module unloading hook, called after execution in the module have ceased.
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync *
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync * @param pDevExt The device extension structure.
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync * @param pImage The image being unloaded.
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync */
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsyncvoid VBOXCALL supdrvVtgModuleUnloading(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage)
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync{
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync PSUPDRVDTPROVIDER pProv, pProvNext;
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync /*
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync * Unregister all providers belonging to this image.
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync */
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync RTSemFastMutexRequest(pDevExt->mtxDTrace);
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync RTListForEachSafe(&pDevExt->DtProviderList, pProv, pProvNext, SUPDRVDTPROVIDER, ListEntry)
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync {
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync if (pProv->pImage == pImage)
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync {
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync RTListNodeRemove(&pProv->ListEntry);
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync supdrvVtgDeregister(pDevExt, pProv);
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync }
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync }
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync RTSemFastMutexRelease(pDevExt->mtxDTrace);
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync /*
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync * Try unregister zombies while we have a chance.
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync */
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync supdrvVtgProcessZombies(pDevExt);
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync}
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync/**
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync * Early module initialization hook.
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync *
42576743851c3c956ad7e867e74df1084c30d434vboxsync * @returns VBox status code.
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync * @param pDevExt The device extension structure.
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync * @param pVtgFireProbe Pointer to the SUPR0VtgFireProbe entry.
42576743851c3c956ad7e867e74df1084c30d434vboxsync */
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsyncint VBOXCALL supdrvVtgInit(PSUPDRVDEVEXT pDevExt, PSUPFUNC pVtgFireProbe)
42576743851c3c956ad7e867e74df1084c30d434vboxsync{
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync Assert(!strcmp(pVtgFireProbe->szName, "SUPR0VtgFireProbe"));
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync
42576743851c3c956ad7e867e74df1084c30d434vboxsync /*
42576743851c3c956ad7e867e74df1084c30d434vboxsync * Register a provider for this module.
42576743851c3c956ad7e867e74df1084c30d434vboxsync */
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync int rc = RTSemFastMutexCreate(&pDevExt->mtxDTrace);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync if (RT_SUCCESS(rc))
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync {
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync#ifdef RT_OS_SOLARIS
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync pVtgFireProbe->pfn = (void *)(uintptr_t)dtrace_probe;
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync#endif
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync RTListInit(&pDevExt->DtProviderList);
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync RTListInit(&pDevExt->DtProviderZombieList);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync rc = supdrvVtgRegister(pDevExt, &g_VTGObjHeader, _1M, NULL /*pImage*/, NULL /*pSession*/, "vboxdrv");
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync if (RT_SUCCESS(rc))
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync return rc;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync RTSemFastMutexDestroy(pDevExt->mtxDTrace);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync }
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync pDevExt->mtxDTrace = NIL_RTSEMFASTMUTEX;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync return rc;
42576743851c3c956ad7e867e74df1084c30d434vboxsync}
42576743851c3c956ad7e867e74df1084c30d434vboxsync
42576743851c3c956ad7e867e74df1084c30d434vboxsync
42576743851c3c956ad7e867e74df1084c30d434vboxsync/**
42576743851c3c956ad7e867e74df1084c30d434vboxsync * Late module termination hook.
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync *
42576743851c3c956ad7e867e74df1084c30d434vboxsync * @returns VBox status code.
42576743851c3c956ad7e867e74df1084c30d434vboxsync * @param pDevExt The device extension structure.
42576743851c3c956ad7e867e74df1084c30d434vboxsync */
b32be08cd134577ca98e517c019c867c416ec0f2vboxsyncvoid VBOXCALL supdrvVtgTerm(PSUPDRVDEVEXT pDevExt)
42576743851c3c956ad7e867e74df1084c30d434vboxsync{
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync PSUPDRVDTPROVIDER pProv, pProvNext;
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync uint32_t i;
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync LOG_DTRACE(("supdrvVtgTerm\n"));
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync
42576743851c3c956ad7e867e74df1084c30d434vboxsync /*
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync * Unregister all probes (there should only be one).
42576743851c3c956ad7e867e74df1084c30d434vboxsync */
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync RTSemFastMutexRequest(pDevExt->mtxDTrace);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync RTListForEachSafe(&pDevExt->DtProviderList, pProv, pProvNext, SUPDRVDTPROVIDER, ListEntry)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync {
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync RTListNodeRemove(&pProv->ListEntry);
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync supdrvVtgDeregister(pDevExt, pProv);
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync }
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync RTSemFastMutexRelease(pDevExt->mtxDTrace);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync /*
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync * Try unregister zombies now, sleep on busy ones.
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync */
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync for (i = 0; ; i++)
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync {
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync bool fEmpty;
42576743851c3c956ad7e867e74df1084c30d434vboxsync
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync RTSemFastMutexRequest(pDevExt->mtxDTrace);
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync RTListForEachSafe(&pDevExt->DtProviderZombieList, pProv, pProvNext, SUPDRVDTPROVIDER, ListEntry)
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync {
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync int rc;
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync LOG_DTRACE(("supdrvVtgTerm: Attemting to unregister '%s' / %p...\n", pProv->szName, pProv->idDtProv));
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync rc = dtrace_unregister(pProv->idDtProv);
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync if (!rc)
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync {
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync RTListNodeRemove(&pProv->ListEntry);
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync supdrvVtgFreeProvider(pProv);
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync }
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync else if (!(i & 0xf))
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync SUPR0Printf("supdrvVtgTerm: Waiting on busy provider '%s' / %p (rc=%d)\n", pProv->szName, pProv->idDtProv, rc);
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync else
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync LOG_DTRACE(("supdrvVtgTerm: Failed to unregister provider '%s' / %p - rc=%d\n", pProv->szName, pProv->idDtProv, rc));
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync }
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync fEmpty = RTListIsEmpty(&pDevExt->DtProviderZombieList);
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync RTSemFastMutexRelease(pDevExt->mtxDTrace);
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync if (fEmpty)
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync break;
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync /* Delay...*/
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync RTThreadSleep(1000);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync }
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync RTSemFastMutexDestroy(pDevExt->mtxDTrace);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync pDevExt->mtxDTrace = NIL_RTSEMFASTMUTEX;
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync LOG_DTRACE(("supdrvVtgTerm: Done\n"));
42576743851c3c956ad7e867e74df1084c30d434vboxsync}
42576743851c3c956ad7e867e74df1084c30d434vboxsync
42576743851c3c956ad7e867e74df1084c30d434vboxsync
42576743851c3c956ad7e867e74df1084c30d434vboxsync/**
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync * @callback_method_impl{dtrace_pops_t,dtps_provide}
42576743851c3c956ad7e867e74df1084c30d434vboxsync */
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsyncstatic void supdrvDTracePOps_Provide(void *pvProv, const dtrace_probedesc_t *pDtProbeDesc)
42576743851c3c956ad7e867e74df1084c30d434vboxsync{
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync PSUPDRVDTPROVIDER pProv = (PSUPDRVDTPROVIDER)pvProv;
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync uint16_t idxProv;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync PVTGPROBELOC pProbeLoc;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync PVTGPROBELOC pProbeLocEnd;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync char *pszFnNmBuf;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync size_t const cbFnNmBuf = _4K + _1K;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync if (pDtProbeDesc)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync return; /* We don't generate probes, so never mind these requests. */
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync if (pProv->fZombie)
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync return;
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync
06b49f334535705aeae0ac0572fc5142dc589153vboxsync if (pProv->cProvidedProbes >= pProv->pDesc->cProbes)
06b49f334535705aeae0ac0572fc5142dc589153vboxsync return;
06b49f334535705aeae0ac0572fc5142dc589153vboxsync
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync /* Need a buffer for extracting the function names and mangling them in
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync case of collision. */
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync pszFnNmBuf = (char *)RTMemAlloc(cbFnNmBuf);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync if (!pszFnNmBuf)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync return;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync /*
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync * Itereate the probe location list and register all probes related to
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync * this provider.
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync */
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync idxProv = (uint16_t)(&pProv->pHdr->paProviders[0] - pProv->pDesc);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync pProbeLoc = pProv->pHdr->paProbLocs;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync pProbeLocEnd = pProv->pHdr->paProbLocsEnd;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync while ((uintptr_t)pProbeLoc < (uintptr_t)pProbeLocEnd)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync {
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync PVTGDESCPROBE pProbeDesc = (PVTGDESCPROBE)pProbeLoc->pbProbe;
06b49f334535705aeae0ac0572fc5142dc589153vboxsync if ( pProbeDesc->idxProvider == idxProv
06b49f334535705aeae0ac0572fc5142dc589153vboxsync && pProbeLoc->idProbe == UINT32_MAX)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync {
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. */
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync const char *pszPrbName = supdrvVtgGetString(pProv->pHdr, pProbeDesc->offName);
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync const char *pszFunc = pProbeLoc->pszFunction;
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync const char *psz = strchr(pProbeLoc->pszFunction, '(');
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync size_t cch;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync if (psz)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync {
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync /* skip blanks preceeding the parameter parenthesis. */
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync while ( (uintptr_t)psz > (uintptr_t)pProbeLoc->pszFunction
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync && RT_C_IS_BLANK(psz[-1]))
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync psz--;
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync /* Find the start of the function name. */
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync pszFunc = psz - 1;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync while ((uintptr_t)pszFunc > (uintptr_t)pProbeLoc->pszFunction)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync {
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync char ch = pszFunc[-1];
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync if (!RT_C_IS_ALNUM(ch) && ch != '_' && ch != ':')
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync break;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync pszFunc--;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync }
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync cch = psz - pszFunc;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync }
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync else
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync cch = strlen(pszFunc);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync RTStrCopyEx(pszFnNmBuf, cbFnNmBuf, pszFunc, cch);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync
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 Assert(pProbeLoc->idProbe == UINT32_MAX);
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync if (dtrace_probe_lookup(pProv->idDtProv, pProv->pszModName, pszFnNmBuf, pszPrbName) != DTRACE_IDNONE)
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync {
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync RTStrPrintf(pszFnNmBuf+cch, cbFnNmBuf - cch, "-%u", pProbeLoc->uLine);
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync if (dtrace_probe_lookup(pProv->idDtProv, pProv->pszModName, pszFnNmBuf, pszPrbName) != DTRACE_IDNONE)
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync {
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync unsigned iOrd = 2;
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync while (iOrd < 128)
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync {
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync RTStrPrintf(pszFnNmBuf+cch, cbFnNmBuf - cch, "-%u-%u", pProbeLoc->uLine, iOrd);
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync if (dtrace_probe_lookup(pProv->idDtProv, pProv->pszModName, pszFnNmBuf, pszPrbName) == DTRACE_IDNONE)
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync break;
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync iOrd++;
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync }
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync if (iOrd >= 128)
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync {
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync LogRel(("VBoxDrv: More than 128 duplicate probe location instances in file %s at line %u, function %s [%s], probe %s\n",
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync pProbeLoc->pszFile, pProbeLoc->uLine, pProbeLoc->pszFunction, pszFnNmBuf, pszPrbName));
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync continue;
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync }
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync }
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync }
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync /* Create the probe. */
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync AssertCompile(sizeof(pProbeLoc->idProbe) == sizeof(dtrace_id_t));
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync pProbeLoc->idProbe = dtrace_probe_create(pProv->idDtProv, pProv->pszModName, pszFnNmBuf, pszPrbName,
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync 0 /*aframes*/, pProbeLoc);
06b49f334535705aeae0ac0572fc5142dc589153vboxsync pProv->cProvidedProbes++;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync }
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync pProbeLoc++;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync }
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync RTMemFree(pszFnNmBuf);
42576743851c3c956ad7e867e74df1084c30d434vboxsync}
42576743851c3c956ad7e867e74df1084c30d434vboxsync
42576743851c3c956ad7e867e74df1084c30d434vboxsync
42576743851c3c956ad7e867e74df1084c30d434vboxsync/**
42576743851c3c956ad7e867e74df1084c30d434vboxsync * @callback_method_impl{dtrace_pops_t,dtps_enable}
42576743851c3c956ad7e867e74df1084c30d434vboxsync */
42576743851c3c956ad7e867e74df1084c30d434vboxsyncstatic int supdrvDTracePOps_Enable(void *pvProv, dtrace_id_t idProbe, void *pvProbe)
42576743851c3c956ad7e867e74df1084c30d434vboxsync{
06b49f334535705aeae0ac0572fc5142dc589153vboxsync PSUPDRVDTPROVIDER pProv = (PSUPDRVDTPROVIDER)pvProv;
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync if (!pProv->fZombie)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync {
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync PVTGPROBELOC pProbeLoc = (PVTGPROBELOC)pvProbe;
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync PVTGDESCPROBE pProbeDesc = (PVTGDESCPROBE)pProbeLoc->pbProbe;
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync if (!pProbeLoc->fEnabled)
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync {
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync pProbeLoc->fEnabled = 1;
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync if (ASMAtomicIncU32(&pProbeDesc->u32User) == 1)
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync pProv->pHdr->pafProbeEnabled[pProbeDesc->idxEnabled] = 1;
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync }
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync }
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync return 0;
42576743851c3c956ad7e867e74df1084c30d434vboxsync}
42576743851c3c956ad7e867e74df1084c30d434vboxsync
42576743851c3c956ad7e867e74df1084c30d434vboxsync
42576743851c3c956ad7e867e74df1084c30d434vboxsync/**
42576743851c3c956ad7e867e74df1084c30d434vboxsync * @callback_method_impl{dtrace_pops_t,dtps_disable}
42576743851c3c956ad7e867e74df1084c30d434vboxsync */
42576743851c3c956ad7e867e74df1084c30d434vboxsyncstatic void supdrvDTracePOps_Disable(void *pvProv, dtrace_id_t idProbe, void *pvProbe)
42576743851c3c956ad7e867e74df1084c30d434vboxsync{
06b49f334535705aeae0ac0572fc5142dc589153vboxsync PSUPDRVDTPROVIDER pProv = (PSUPDRVDTPROVIDER)pvProv;
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync if (!pProv->fZombie)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync {
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync PVTGPROBELOC pProbeLoc = (PVTGPROBELOC)pvProbe;
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync PVTGDESCPROBE pProbeDesc = (PVTGDESCPROBE)pProbeLoc->pbProbe;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync if (pProbeLoc->fEnabled)
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync {
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync pProbeLoc->fEnabled = 0;
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync if (ASMAtomicDecU32(&pProbeDesc->u32User) == 0)
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync pProv->pHdr->pafProbeEnabled[pProbeDesc->idxEnabled] = 1;
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync }
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync }
42576743851c3c956ad7e867e74df1084c30d434vboxsync}
42576743851c3c956ad7e867e74df1084c30d434vboxsync
42576743851c3c956ad7e867e74df1084c30d434vboxsync
42576743851c3c956ad7e867e74df1084c30d434vboxsync/**
42576743851c3c956ad7e867e74df1084c30d434vboxsync * @callback_method_impl{dtrace_pops_t,dtps_getargdesc}
42576743851c3c956ad7e867e74df1084c30d434vboxsync */
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsyncstatic void supdrvDTracePOps_GetArgDesc(void *pvProv, dtrace_id_t idProbe, void *pvProbe,
42576743851c3c956ad7e867e74df1084c30d434vboxsync dtrace_argdesc_t *pArgDesc)
42576743851c3c956ad7e867e74df1084c30d434vboxsync{
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync PSUPDRVDTPROVIDER pProv = (PSUPDRVDTPROVIDER)pvProv;
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync unsigned uArg = pArgDesc->dtargd_ndx;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync if (!pProv->fZombie)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync {
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync PVTGPROBELOC pProbeLoc = (PVTGPROBELOC)pvProbe;
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync PVTGDESCPROBE pProbeDesc = (PVTGDESCPROBE)pProbeLoc->pbProbe;
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync PVTGDESCARGLIST pArgList = (PVTGDESCARGLIST)((uintptr_t)pProv->pHdr->paArgLists + pProbeDesc->offArgList);
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync Assert(pProbeDesc->offArgList < pProv->pHdr->cbArgLists);
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync if (pArgList->cArgs > uArg)
06b49f334535705aeae0ac0572fc5142dc589153vboxsync {
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync const char *pszType = supdrvVtgGetString(pProv->pHdr, pArgList->aArgs[uArg].offType);
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync size_t cchType = strlen(pszType);
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync if (cchType < sizeof(pArgDesc->dtargd_native))
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync {
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync memcpy(pArgDesc->dtargd_native, pszType, cchType + 1);
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync /** @todo mapping */
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync return;
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync }
06b49f334535705aeae0ac0572fc5142dc589153vboxsync }
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync }
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync pArgDesc->dtargd_ndx = DTRACE_ARGNONE;
42576743851c3c956ad7e867e74df1084c30d434vboxsync}
42576743851c3c956ad7e867e74df1084c30d434vboxsync
42576743851c3c956ad7e867e74df1084c30d434vboxsync
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync#ifdef RT_OS_SOLARIS
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync# ifdef __cplusplus
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsyncextern "C"
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync#endif
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsyncuint64_t dtrace_getarg(int iArg, int cFrames);
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync
42576743851c3c956ad7e867e74df1084c30d434vboxsync/**
42576743851c3c956ad7e867e74df1084c30d434vboxsync * @callback_method_impl{dtrace_pops_t,dtps_getargval}
42576743851c3c956ad7e867e74df1084c30d434vboxsync */
42576743851c3c956ad7e867e74df1084c30d434vboxsyncstatic uint64_t supdrvDTracePOps_GetArgVal(void *pvProv, dtrace_id_t idProbe, void *pvProbe,
42576743851c3c956ad7e867e74df1084c30d434vboxsync int iArg, int cFrames)
42576743851c3c956ad7e867e74df1084c30d434vboxsync{
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync /* dtrace_getarg on AMD64 has a different opinion about how to use the
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync cFrames argument than dtrace_caller() and/or dtrace_getpcstack(), at
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync least when the probe is fired by dtrace_probe() the way we do.
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync Setting aframes to 1 when calling dtrace_probe_create gives me the right
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync arguments, but the wrong 'caller'. Since I cannot do anything about
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync 'caller', the only solution is this hack.
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync Not sure why the Solaris guys hasn't seen this issue before, but maybe
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync there isn't anyone using the default argument getter path for ring-0
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync dtrace_probe() calls, SDT surely isn't.
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync WARNING! This code is subject to dtrace_getarg interface unstability! */
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync /** @todo File a solaris bug on dtrace_probe() + dtrace_getarg(). */
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync return dtrace_getarg(iArg, cFrames + 1);
42576743851c3c956ad7e867e74df1084c30d434vboxsync}
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync#endif /* RT_OS_SOLARIS */
42576743851c3c956ad7e867e74df1084c30d434vboxsync
42576743851c3c956ad7e867e74df1084c30d434vboxsync
42576743851c3c956ad7e867e74df1084c30d434vboxsync/**
42576743851c3c956ad7e867e74df1084c30d434vboxsync * @callback_method_impl{dtrace_pops_t,dtps_destroy}
42576743851c3c956ad7e867e74df1084c30d434vboxsync */
42576743851c3c956ad7e867e74df1084c30d434vboxsyncstatic void supdrvDTracePOps_Destroy(void *pvProv, dtrace_id_t idProbe, void *pvProbe)
42576743851c3c956ad7e867e74df1084c30d434vboxsync{
06b49f334535705aeae0ac0572fc5142dc589153vboxsync PSUPDRVDTPROVIDER pProv = (PSUPDRVDTPROVIDER)pvProv;
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync if (!pProv->fZombie)
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync {
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync PVTGPROBELOC pProbeLoc = (PVTGPROBELOC)pvProbe;
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync Assert(!pProbeLoc->fEnabled);
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync Assert(pProbeLoc->idProbe == idProbe); NOREF(idProbe);
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync pProbeLoc->idProbe = UINT32_MAX;
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync }
06b49f334535705aeae0ac0572fc5142dc589153vboxsync pProv->cProvidedProbes--;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync}
42576743851c3c956ad7e867e74df1084c30d434vboxsync