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/mem.h>
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync#include <iprt/errno.h>
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync#ifdef RT_OS_DARWIN
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync# include <iprt/dbg.h>
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync#endif
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync#ifdef RT_OS_DARWIN
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync# include VBOX_PATH_MACOSX_DTRACE_H
c6b3d55ef646614cc689faa1fa4ddc961712b6ffvboxsync#elif defined(RT_OS_LINUX)
f714516da18876b1836a804fc0cac5e8ff589e83vboxsync/* Avoid type and define conflicts. */
f714516da18876b1836a804fc0cac5e8ff589e83vboxsync# undef UINT8_MAX
f714516da18876b1836a804fc0cac5e8ff589e83vboxsync# undef UINT16_MAX
f714516da18876b1836a804fc0cac5e8ff589e83vboxsync# undef UINT32_MAX
f714516da18876b1836a804fc0cac5e8ff589e83vboxsync# undef UINT64_MAX
f714516da18876b1836a804fc0cac5e8ff589e83vboxsync# undef INT64_MAX
f714516da18876b1836a804fc0cac5e8ff589e83vboxsync# undef INT64_MIN
f714516da18876b1836a804fc0cac5e8ff589e83vboxsync# define intptr_t dtrace_intptr_t
f714516da18876b1836a804fc0cac5e8ff589e83vboxsync
f714516da18876b1836a804fc0cac5e8ff589e83vboxsync# if 0
f714516da18876b1836a804fc0cac5e8ff589e83vboxsync/* DTrace experiments with the Unbreakable Enterprise Kernel (UEK2)
c6b3d55ef646614cc689faa1fa4ddc961712b6ffvboxsync (Oracle Linux).
99a5f7beff5f7bbf1f73923087d60070ddb717d4vboxsync 1. The dtrace.h here is from the dtrace module source, not
c6b3d55ef646614cc689faa1fa4ddc961712b6ffvboxsync /usr/include/sys/dtrace.h nor /usr/include/dtrace.h.
99a5f7beff5f7bbf1f73923087d60070ddb717d4vboxsync 2. To generate the missing entries for the dtrace module in Module.symvers
c6b3d55ef646614cc689faa1fa4ddc961712b6ffvboxsync of UEK:
c6b3d55ef646614cc689faa1fa4ddc961712b6ffvboxsync nm /lib/modules/....../kernel/drivers/dtrace/dtrace.ko \
c6b3d55ef646614cc689faa1fa4ddc961712b6ffvboxsync | grep _crc_ \
c6b3d55ef646614cc689faa1fa4ddc961712b6ffvboxsync | sed -e 's/^......../0x/' -e 's/ A __crc_/\t/' \
c6b3d55ef646614cc689faa1fa4ddc961712b6ffvboxsync -e 's/$/\tdrivers\/dtrace\/dtrace\tEXPORT_SYMBOL/' \
c6b3d55ef646614cc689faa1fa4ddc961712b6ffvboxsync >> Module.symvers
f714516da18876b1836a804fc0cac5e8ff589e83vboxsync Update: Althernative workaround (active), resolve symbols dynamically.
99a5f7beff5f7bbf1f73923087d60070ddb717d4vboxsync 3. No tracepoints in vboxdrv, vboxnet* or vboxpci yet. This requires yasm
99a5f7beff5f7bbf1f73923087d60070ddb717d4vboxsync and VBoxTpG and build time. */
f714516da18876b1836a804fc0cac5e8ff589e83vboxsync# include "dtrace.h"
f714516da18876b1836a804fc0cac5e8ff589e83vboxsync# else
f714516da18876b1836a804fc0cac5e8ff589e83vboxsync/* DTrace experiments with the Unbreakable Enterprise Kernel (UEKR3)
f714516da18876b1836a804fc0cac5e8ff589e83vboxsync (Oracle Linux).
f714516da18876b1836a804fc0cac5e8ff589e83vboxsync 1. To generate the missing entries for the dtrace module in Module.symvers
f714516da18876b1836a804fc0cac5e8ff589e83vboxsync of UEK:
f714516da18876b1836a804fc0cac5e8ff589e83vboxsync nm /lib/modules/....../kernel/drivers/dtrace/dtrace.ko \
f714516da18876b1836a804fc0cac5e8ff589e83vboxsync | grep _crc_ \
f714516da18876b1836a804fc0cac5e8ff589e83vboxsync | sed -e 's/^......../0x/' -e 's/ A __crc_/\t/' \
f714516da18876b1836a804fc0cac5e8ff589e83vboxsync -e 's/$/\tdrivers\/dtrace\/dtrace\tEXPORT_SYMBOL/' \
f714516da18876b1836a804fc0cac5e8ff589e83vboxsync >> Module.symvers
f714516da18876b1836a804fc0cac5e8ff589e83vboxsync Update: Althernative workaround (active), resolve symbols dynamically.
f714516da18876b1836a804fc0cac5e8ff589e83vboxsync 2. No tracepoints in vboxdrv, vboxnet* or vboxpci yet. This requires yasm
f714516da18876b1836a804fc0cac5e8ff589e83vboxsync and VBoxTpG and build time. */
f714516da18876b1836a804fc0cac5e8ff589e83vboxsync# include <dtrace/provider.h>
f714516da18876b1836a804fc0cac5e8ff589e83vboxsync# include <dtrace/enabling.h> /* Missing from provider.h. */
f714516da18876b1836a804fc0cac5e8ff589e83vboxsync# include <dtrace/arg.h> /* Missing from provider.h. */
f714516da18876b1836a804fc0cac5e8ff589e83vboxsync# endif
f714516da18876b1836a804fc0cac5e8ff589e83vboxsync# include <linux/kallsyms.h>
f714516da18876b1836a804fc0cac5e8ff589e83vboxsync/** Status code fixer (UEK uses linux convension unlike the others). */
43bc5c863e4a7f97ef53171421559ea863af4b11vboxsync# define FIX_UEK_RC(a_rc) (-(a_rc))
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync#else
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync# include <sys/dtrace.h>
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync#endif
42576743851c3c956ad7e867e74df1084c30d434vboxsync
42576743851c3c956ad7e867e74df1084c30d434vboxsync
99a5f7beff5f7bbf1f73923087d60070ddb717d4vboxsync/**
99a5f7beff5f7bbf1f73923087d60070ddb717d4vboxsync * The UEK DTrace port is trying to be smart and seems to have turned all
43bc5c863e4a7f97ef53171421559ea863af4b11vboxsync * errno return codes negative. While this conforms to the linux kernel way of
99a5f7beff5f7bbf1f73923087d60070ddb717d4vboxsync * doing things, it breaks with the way the interfaces work on Solaris and
43bc5c863e4a7f97ef53171421559ea863af4b11vboxsync * Mac OS X.
43bc5c863e4a7f97ef53171421559ea863af4b11vboxsync */
43bc5c863e4a7f97ef53171421559ea863af4b11vboxsync#ifndef FIX_UEK_RC
99a5f7beff5f7bbf1f73923087d60070ddb717d4vboxsync# define FIX_UEK_RC(a_rc) (a_rc)
43bc5c863e4a7f97ef53171421559ea863af4b11vboxsync#endif
43bc5c863e4a7f97ef53171421559ea863af4b11vboxsync
43bc5c863e4a7f97ef53171421559ea863af4b11vboxsync
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync/*******************************************************************************
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync* Structures and Typedefs *
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync*******************************************************************************/
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync/* Seems there is some return code difference here. Keep the return code and
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync case it to whatever the host desires. */
43d42414bba4afb4e2aa2565d9278a3194f09304vboxsync#ifdef RT_OS_DARWIN
43d42414bba4afb4e2aa2565d9278a3194f09304vboxsync# if MAC_OS_X_VERSION_MIN_REQUIRED < 1070
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsynctypedef void FNPOPS_ENABLE(void *, dtrace_id_t, void *);
43d42414bba4afb4e2aa2565d9278a3194f09304vboxsync# else
43d42414bba4afb4e2aa2565d9278a3194f09304vboxsynctypedef int FNPOPS_ENABLE(void *, dtrace_id_t, void *);
43d42414bba4afb4e2aa2565d9278a3194f09304vboxsync# endif
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync#else
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsynctypedef int FNPOPS_ENABLE(void *, dtrace_id_t, void *);
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync#endif
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync/** Caller indicator. */
2d66abeefb9716ed570bb5714884d3fe08629452vboxsynctypedef enum VBOXDTCALLER
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync{
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync kVBoxDtCaller_Invalid = 0,
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync kVBoxDtCaller_Generic,
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync kVBoxDtCaller_ProbeFireUser,
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync kVBoxDtCaller_ProbeFireKernel
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync} VBOXDTCALLER;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync
42576743851c3c956ad7e867e74df1084c30d434vboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync/**
1379dfd407ada5fab15655776896f13b61a951fdvboxsync * Stack data planted before calling dtrace_probe so that we can easily find the
1379dfd407ada5fab15655776896f13b61a951fdvboxsync * stack argument later.
1379dfd407ada5fab15655776896f13b61a951fdvboxsync */
2d66abeefb9716ed570bb5714884d3fe08629452vboxsynctypedef struct VBDTSTACKDATA
1379dfd407ada5fab15655776896f13b61a951fdvboxsync{
1379dfd407ada5fab15655776896f13b61a951fdvboxsync /** Eyecatcher no. 1 (SUPDRVDT_STACK_DATA_MAGIC2). */
1379dfd407ada5fab15655776896f13b61a951fdvboxsync uint32_t u32Magic1;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync /** Eyecatcher no. 2 (SUPDRVDT_STACK_DATA_MAGIC2). */
1379dfd407ada5fab15655776896f13b61a951fdvboxsync uint32_t u32Magic2;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync /** The format of the caller specific data. */
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync VBOXDTCALLER enmCaller;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync /** Caller specific data. */
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync union
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync {
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync /** kVBoxDtCaller_ProbeFireKernel. */
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync struct
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync {
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync /** Pointer to the stack arguments of a probe function call. */
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync uintptr_t *pauStackArgs;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync } ProbeFireKernel;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync /** kVBoxDtCaller_ProbeFireUser. */
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync struct
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync {
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync /** The user context. */
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync PCSUPDRVTRACERUSRCTX pCtx;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync /** The argument displacement caused by 64-bit arguments passed directly to
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync * dtrace_probe. */
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync int offArg;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync } ProbeFireUser;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync } u;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync /** Pointer to this structure.
1379dfd407ada5fab15655776896f13b61a951fdvboxsync * This is the final bit of integrity checking. */
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync struct VBDTSTACKDATA *pSelf;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync} VBDTSTACKDATA;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync/** Pointer to the on-stack thread specific data. */
2d66abeefb9716ed570bb5714884d3fe08629452vboxsynctypedef VBDTSTACKDATA *PVBDTSTACKDATA;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync/*******************************************************************************
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync* Defined Constants And Macros *
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync*******************************************************************************/
1379dfd407ada5fab15655776896f13b61a951fdvboxsync/** The first magic value. */
1379dfd407ada5fab15655776896f13b61a951fdvboxsync#define SUPDRVDT_STACK_DATA_MAGIC1 RT_MAKE_U32_FROM_U8('S', 'U', 'P', 'D')
1379dfd407ada5fab15655776896f13b61a951fdvboxsync/** The second magic value. */
1379dfd407ada5fab15655776896f13b61a951fdvboxsync#define SUPDRVDT_STACK_DATA_MAGIC2 RT_MAKE_U32_FROM_U8('D', 'T', 'r', 'c')
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync/** The alignment of the stack data.
1379dfd407ada5fab15655776896f13b61a951fdvboxsync * The data doesn't require more than sizeof(uintptr_t) alignment, but the
1379dfd407ada5fab15655776896f13b61a951fdvboxsync * greater alignment the quicker lookup. */
1379dfd407ada5fab15655776896f13b61a951fdvboxsync#define SUPDRVDT_STACK_DATA_ALIGN 32
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync/** Plants the stack data. */
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync#define VBDT_SETUP_STACK_DATA(a_enmCaller) \
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync uint8_t abBlob[sizeof(VBDTSTACKDATA) + SUPDRVDT_STACK_DATA_ALIGN - 1]; \
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync PVBDTSTACKDATA pStackData = (PVBDTSTACKDATA)( (uintptr_t)&abBlob[SUPDRVDT_STACK_DATA_ALIGN - 1] \
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync & ~(uintptr_t)(SUPDRVDT_STACK_DATA_ALIGN - 1)); \
1379dfd407ada5fab15655776896f13b61a951fdvboxsync pStackData->u32Magic1 = SUPDRVDT_STACK_DATA_MAGIC1; \
1379dfd407ada5fab15655776896f13b61a951fdvboxsync pStackData->u32Magic2 = SUPDRVDT_STACK_DATA_MAGIC2; \
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync pStackData->enmCaller = a_enmCaller; \
1379dfd407ada5fab15655776896f13b61a951fdvboxsync pStackData->pSelf = pStackData
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync/** Passifies the stack data and frees up resource held within it. */
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync#define VBDT_CLEAR_STACK_DATA() \
1379dfd407ada5fab15655776896f13b61a951fdvboxsync do \
1379dfd407ada5fab15655776896f13b61a951fdvboxsync { \
1379dfd407ada5fab15655776896f13b61a951fdvboxsync pStackData->u32Magic1 = 0; \
1379dfd407ada5fab15655776896f13b61a951fdvboxsync pStackData->u32Magic2 = 0; \
1379dfd407ada5fab15655776896f13b61a951fdvboxsync pStackData->pSelf = NULL; \
1379dfd407ada5fab15655776896f13b61a951fdvboxsync } while (0)
42576743851c3c956ad7e867e74df1084c30d434vboxsync
cb70b5cc08e3b666361766188f99cc86ed1626fbvboxsync/** Simple SUPR0Printf-style logging. */
cb70b5cc08e3b666361766188f99cc86ed1626fbvboxsync#if 0 /*def DEBUG_bird*/
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync# define LOG_DTRACE(a) SUPR0Printf a
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync#else
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync# define LOG_DTRACE(a) do { } while (0)
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync#endif
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync
42576743851c3c956ad7e867e74df1084c30d434vboxsync
42576743851c3c956ad7e867e74df1084c30d434vboxsync/*******************************************************************************
42576743851c3c956ad7e867e74df1084c30d434vboxsync* Global Variables *
42576743851c3c956ad7e867e74df1084c30d434vboxsync*******************************************************************************/
f714516da18876b1836a804fc0cac5e8ff589e83vboxsync#if defined(RT_OS_DARWIN) || defined(RT_OS_LINUX)
f714516da18876b1836a804fc0cac5e8ff589e83vboxsync/** @name DTrace kernel interface used on Darwin and Linux.
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync * @{ */
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsyncstatic void (* g_pfnDTraceProbeFire)(dtrace_id_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t);
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsyncstatic dtrace_id_t (* g_pfnDTraceProbeCreate)(dtrace_provider_id_t, const char *, const char *, const char *, int, void *);
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsyncstatic dtrace_id_t (* g_pfnDTraceProbeLookup)(dtrace_provider_id_t, const char *, const char *, const char *);
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsyncstatic int (* g_pfnDTraceProviderRegister)(const char *, const dtrace_pattr_t *, uint32_t, /*cred_t*/ void *,
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync const dtrace_pops_t *, void *, dtrace_provider_id_t *);
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsyncstatic void (* g_pfnDTraceProviderInvalidate)(dtrace_provider_id_t);
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsyncstatic int (* g_pfnDTraceProviderUnregister)(dtrace_provider_id_t);
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync#define dtrace_probe g_pfnDTraceProbeFire
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync#define dtrace_probe_create g_pfnDTraceProbeCreate
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync#define dtrace_probe_lookup g_pfnDTraceProbeLookup
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync#define dtrace_register g_pfnDTraceProviderRegister
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync#define dtrace_invalidate g_pfnDTraceProviderInvalidate
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync#define dtrace_unregister g_pfnDTraceProviderUnregister
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync/** @} */
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync#endif
42576743851c3c956ad7e867e74df1084c30d434vboxsync
2d0371c5f4b5bf0651da37a13cd3ae7479dd0432vboxsync
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync/**
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync * Gets the stack data.
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync *
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync * @returns Pointer to the stack data. Never NULL.
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync */
2d66abeefb9716ed570bb5714884d3fe08629452vboxsyncstatic PVBDTSTACKDATA vboxDtGetStackData(void)
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync{
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync /*
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync * Locate the caller of probe_dtrace.
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync */
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync int volatile iDummy = 1; /* use this to get the stack address. */
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync PVBDTSTACKDATA pData = (PVBDTSTACKDATA)( ((uintptr_t)&iDummy + SUPDRVDT_STACK_DATA_ALIGN - 1)
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync & ~(uintptr_t)(SUPDRVDT_STACK_DATA_ALIGN - 1));
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync for (;;)
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync {
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync if ( pData->u32Magic1 == SUPDRVDT_STACK_DATA_MAGIC1
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync && pData->u32Magic2 == SUPDRVDT_STACK_DATA_MAGIC2
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync && pData->pSelf == pData)
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync return pData;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync pData = (PVBDTSTACKDATA)((uintptr_t)pData + SUPDRVDT_STACK_DATA_ALIGN);
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync }
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync}
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync/*
1379dfd407ada5fab15655776896f13b61a951fdvboxsync *
1379dfd407ada5fab15655776896f13b61a951fdvboxsync * Helpers for handling VTG structures.
1379dfd407ada5fab15655776896f13b61a951fdvboxsync * Helpers for handling VTG structures.
1379dfd407ada5fab15655776896f13b61a951fdvboxsync * Helpers for handling VTG structures.
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync *
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync */
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync
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 */
1379dfd407ada5fab15655776896f13b61a951fdvboxsyncstatic void vboxDtVtgConvAttr(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 */
2d66abeefb9716ed570bb5714884d3fe08629452vboxsyncstatic const char *vboxDtVtgGetString(PVTGOBJHDR pVtgHdr, uint32_t offStrTab)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync{
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync Assert(offStrTab < pVtgHdr->cbStrTab);
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync return (const char *)pVtgHdr + pVtgHdr->offStrTab + offStrTab;
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync}
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync
42576743851c3c956ad7e867e74df1084c30d434vboxsync
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync/*
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync *
1379dfd407ada5fab15655776896f13b61a951fdvboxsync * DTrace Provider Interface.
1379dfd407ada5fab15655776896f13b61a951fdvboxsync * DTrace Provider Interface.
1379dfd407ada5fab15655776896f13b61a951fdvboxsync * DTrace Provider Interface.
02f73b88a6e96b7f1b8ab0bbb98cfb798b566fbdvboxsync *
42576743851c3c956ad7e867e74df1084c30d434vboxsync */
42576743851c3c956ad7e867e74df1084c30d434vboxsync
42576743851c3c956ad7e867e74df1084c30d434vboxsync
42576743851c3c956ad7e867e74df1084c30d434vboxsync/**
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync * @callback_method_impl{dtrace_pops_t,dtps_provide}
42576743851c3c956ad7e867e74df1084c30d434vboxsync */
2d66abeefb9716ed570bb5714884d3fe08629452vboxsyncstatic void vboxDtPOps_Provide(void *pvProv, const dtrace_probedesc_t *pDtProbeDesc)
42576743851c3c956ad7e867e74df1084c30d434vboxsync{
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync PSUPDRVVDTPROVIDERCORE pProv = (PSUPDRVVDTPROVIDERCORE)pvProv;
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync AssertPtrReturnVoid(pProv);
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync LOG_DTRACE(("%s: %p / %p pDtProbeDesc=%p\n", __FUNCTION__, pProv, pProv->TracerData.DTrace.idProvider, pDtProbeDesc));
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync if (pDtProbeDesc)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync return; /* We don't generate probes, so never mind these requests. */
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync if (pProv->TracerData.DTrace.fZombie)
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync return;
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync dtrace_provider_id_t const idProvider = pProv->TracerData.DTrace.idProvider;
f4d2071f8959189ae2c0c2faa4d2944ee37523d9vboxsync AssertPtrReturnVoid(idProvider);
81614fc60e096e714022d10d38b70a36b9b21d48vboxsync
f4d2071f8959189ae2c0c2faa4d2944ee37523d9vboxsync AssertPtrReturnVoid(pProv->pHdr);
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync AssertReturnVoid(pProv->pHdr->offProbeLocs != 0);
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync uint32_t const cProbeLocs = pProv->pHdr->cbProbeLocs / sizeof(VTGPROBELOC);
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync /* Need a buffer for extracting the function names and mangling them in
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync case of collision. */
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync size_t const cbFnNmBuf = _4K + _1K;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync char *pszFnNmBuf = (char *)RTMemAlloc(cbFnNmBuf);
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync if (!pszFnNmBuf)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync return;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync /*
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync * Itereate the probe location list and register all probes related to
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync * this provider.
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync */
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync uint16_t const idxProv = (uint16_t)((PVTGDESCPROVIDER)((uintptr_t)pProv->pHdr + pProv->pHdr->offProviders) - pProv->pDesc);
c6b3d55ef646614cc689faa1fa4ddc961712b6ffvboxsync uint32_t idxProbeLoc;
c6b3d55ef646614cc689faa1fa4ddc961712b6ffvboxsync for (idxProbeLoc = 0; idxProbeLoc < cProbeLocs; idxProbeLoc++)
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync {
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync /* Skip probe location belonging to other providers or once that
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync we've already reported. */
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync PCVTGPROBELOC pProbeLocRO = &pProv->paProbeLocsRO[idxProbeLoc];
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync PVTGDESCPROBE pProbeDesc = pProbeLocRO->pProbe;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync if (pProbeDesc->idxProvider != idxProv)
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync continue;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync uint32_t *pidProbe;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync if (!pProv->fUmod)
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync pidProbe = (uint32_t *)&pProbeLocRO->idProbe;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync else
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync pidProbe = &pProv->paR0ProbeLocs[idxProbeLoc].idProbe;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync if (*pidProbe != 0)
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync continue;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync /* The function name may need to be stripped since we're using C++
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync compilers for most of the code. ASSUMES nobody are brave/stupid
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync enough to use function pointer returns without typedef'ing
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync properly them (e.g. signal). */
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync const char *pszPrbName = vboxDtVtgGetString(pProv->pHdr, pProbeDesc->offName);
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync const char *pszFunc = pProbeLocRO->pszFunction;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync const char *psz = strchr(pProbeLocRO->pszFunction, '(');
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync size_t cch;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync if (psz)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync {
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync /* skip blanks preceeding the parameter parenthesis. */
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync while ( (uintptr_t)psz > (uintptr_t)pProbeLocRO->pszFunction
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync && RT_C_IS_BLANK(psz[-1]))
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync psz--;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync /* Find the start of the function name. */
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync pszFunc = psz - 1;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync while ((uintptr_t)pszFunc > (uintptr_t)pProbeLocRO->pszFunction)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync {
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync char ch = pszFunc[-1];
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync if (!RT_C_IS_ALNUM(ch) && ch != '_' && ch != ':')
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync break;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync pszFunc--;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync }
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync cch = psz - pszFunc;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync }
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync else
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync cch = strlen(pszFunc);
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync RTStrCopyEx(pszFnNmBuf, cbFnNmBuf, pszFunc, cch);
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync /* Look up the probe, if we have one in the same function, mangle
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync the function name a little to avoid having to deal with having
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync multiple location entries with the same probe ID. (lazy bird) */
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync Assert(!*pidProbe);
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync if (dtrace_probe_lookup(idProvider, pProv->pszModName, pszFnNmBuf, pszPrbName) != DTRACE_IDNONE)
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync {
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync RTStrPrintf(pszFnNmBuf+cch, cbFnNmBuf - cch, "-%u", pProbeLocRO->uLine);
1379dfd407ada5fab15655776896f13b61a951fdvboxsync if (dtrace_probe_lookup(idProvider, pProv->pszModName, pszFnNmBuf, pszPrbName) != DTRACE_IDNONE)
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync {
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync unsigned iOrd = 2;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync while (iOrd < 128)
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync {
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync RTStrPrintf(pszFnNmBuf+cch, cbFnNmBuf - cch, "-%u-%u", pProbeLocRO->uLine, iOrd);
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync if (dtrace_probe_lookup(idProvider, pProv->pszModName, pszFnNmBuf, pszPrbName) == DTRACE_IDNONE)
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync break;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync iOrd++;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync }
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync if (iOrd >= 128)
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync {
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync LogRel(("VBoxDrv: More than 128 duplicate probe location instances %s at line %u in function %s [%s], probe %s\n",
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync pProbeLocRO->uLine, pProbeLocRO->pszFunction, pszFnNmBuf, pszPrbName));
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync continue;
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync }
6998b7cea7c904f33047cd17b05bea760a5839a9vboxsync }
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync }
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync /* Create the probe. */
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync AssertCompile(sizeof(*pidProbe) == sizeof(dtrace_id_t));
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync *pidProbe = dtrace_probe_create(idProvider, pProv->pszModName, pszFnNmBuf, pszPrbName,
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync 1 /*aframes*/, (void *)(uintptr_t)idxProbeLoc);
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync pProv->TracerData.DTrace.cProvidedProbes++;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync }
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync RTMemFree(pszFnNmBuf);
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync LOG_DTRACE(("%s: returns\n", __FUNCTION__));
42576743851c3c956ad7e867e74df1084c30d434vboxsync}
42576743851c3c956ad7e867e74df1084c30d434vboxsync
42576743851c3c956ad7e867e74df1084c30d434vboxsync
42576743851c3c956ad7e867e74df1084c30d434vboxsync/**
42576743851c3c956ad7e867e74df1084c30d434vboxsync * @callback_method_impl{dtrace_pops_t,dtps_enable}
42576743851c3c956ad7e867e74df1084c30d434vboxsync */
2d66abeefb9716ed570bb5714884d3fe08629452vboxsyncstatic int vboxDtPOps_Enable(void *pvProv, dtrace_id_t idProbe, void *pvProbe)
42576743851c3c956ad7e867e74df1084c30d434vboxsync{
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync PSUPDRVVDTPROVIDERCORE pProv = (PSUPDRVVDTPROVIDERCORE)pvProv;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync LOG_DTRACE(("%s: %p / %p - %#x / %p\n", __FUNCTION__, pProv, pProv->TracerData.DTrace.idProvider, idProbe, pvProbe));
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync AssertPtrReturn(pProv->TracerData.DTrace.idProvider, EINVAL);
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync if (!pProv->TracerData.DTrace.fZombie)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync {
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync uint32_t idxProbeLoc = (uint32_t)(uintptr_t)pvProbe;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync PVTGPROBELOC32 pProbeLocEn = (PVTGPROBELOC32)( (uintptr_t)pProv->pvProbeLocsEn + idxProbeLoc * pProv->cbProbeLocsEn);
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync PCVTGPROBELOC pProbeLocRO = (PVTGPROBELOC)&pProv->paProbeLocsRO[idxProbeLoc];
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync PCVTGDESCPROBE pProbeDesc = pProbeLocRO->pProbe;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync uint32_t const idxProbe = pProbeDesc->idxEnabled;
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync if (!pProv->fUmod)
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync {
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync if (!pProbeLocEn->fEnabled)
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync {
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync pProbeLocEn->fEnabled = 1;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync ASMAtomicIncU32(&pProv->pacProbeEnabled[idxProbe]);
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync }
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync }
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync else
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync {
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync /* Update kernel mode structure */
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync if (!pProv->paR0ProbeLocs[idxProbeLoc].fEnabled)
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync {
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync pProv->paR0ProbeLocs[idxProbeLoc].fEnabled = 1;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync ASMAtomicIncU32(&pProv->paR0Probes[idxProbe].cEnabled);
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync }
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync /* Update user mode structure. */
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync pProbeLocEn->fEnabled = 1;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync pProv->pacProbeEnabled[idxProbe] = pProv->paR0Probes[idxProbe].cEnabled;
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync }
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync }
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync return 0;
42576743851c3c956ad7e867e74df1084c30d434vboxsync}
42576743851c3c956ad7e867e74df1084c30d434vboxsync
42576743851c3c956ad7e867e74df1084c30d434vboxsync
42576743851c3c956ad7e867e74df1084c30d434vboxsync/**
42576743851c3c956ad7e867e74df1084c30d434vboxsync * @callback_method_impl{dtrace_pops_t,dtps_disable}
42576743851c3c956ad7e867e74df1084c30d434vboxsync */
2d66abeefb9716ed570bb5714884d3fe08629452vboxsyncstatic void vboxDtPOps_Disable(void *pvProv, dtrace_id_t idProbe, void *pvProbe)
42576743851c3c956ad7e867e74df1084c30d434vboxsync{
1379dfd407ada5fab15655776896f13b61a951fdvboxsync PSUPDRVVDTPROVIDERCORE pProv = (PSUPDRVVDTPROVIDERCORE)pvProv;
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync AssertPtrReturnVoid(pProv);
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync LOG_DTRACE(("%s: %p / %p - %#x / %p\n", __FUNCTION__, pProv, pProv->TracerData.DTrace.idProvider, idProbe, pvProbe));
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync AssertPtrReturnVoid(pProv->TracerData.DTrace.idProvider);
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync if (!pProv->TracerData.DTrace.fZombie)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync {
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync uint32_t idxProbeLoc = (uint32_t)(uintptr_t)pvProbe;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync PVTGPROBELOC32 pProbeLocEn = (PVTGPROBELOC32)( (uintptr_t)pProv->pvProbeLocsEn + idxProbeLoc * pProv->cbProbeLocsEn);
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync PCVTGPROBELOC pProbeLocRO = (PVTGPROBELOC)&pProv->paProbeLocsRO[idxProbeLoc];
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync PCVTGDESCPROBE pProbeDesc = pProbeLocRO->pProbe;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync uint32_t const idxProbe = pProbeDesc->idxEnabled;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync if (!pProv->fUmod)
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync {
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync if (pProbeLocEn->fEnabled)
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync {
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync pProbeLocEn->fEnabled = 0;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync ASMAtomicDecU32(&pProv->pacProbeEnabled[idxProbe]);
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync }
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync }
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync else
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync {
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync /* Update kernel mode structure */
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync if (pProv->paR0ProbeLocs[idxProbeLoc].fEnabled)
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync {
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync pProv->paR0ProbeLocs[idxProbeLoc].fEnabled = 0;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync ASMAtomicDecU32(&pProv->paR0Probes[idxProbe].cEnabled);
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync }
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync /* Update user mode structure. */
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync pProbeLocEn->fEnabled = 0;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync pProv->pacProbeEnabled[idxProbe] = pProv->paR0Probes[idxProbe].cEnabled;
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync }
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync }
42576743851c3c956ad7e867e74df1084c30d434vboxsync}
42576743851c3c956ad7e867e74df1084c30d434vboxsync
42576743851c3c956ad7e867e74df1084c30d434vboxsync
42576743851c3c956ad7e867e74df1084c30d434vboxsync/**
42576743851c3c956ad7e867e74df1084c30d434vboxsync * @callback_method_impl{dtrace_pops_t,dtps_getargdesc}
42576743851c3c956ad7e867e74df1084c30d434vboxsync */
2d66abeefb9716ed570bb5714884d3fe08629452vboxsyncstatic void vboxDtPOps_GetArgDesc(void *pvProv, dtrace_id_t idProbe, void *pvProbe,
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync dtrace_argdesc_t *pArgDesc)
42576743851c3c956ad7e867e74df1084c30d434vboxsync{
1379dfd407ada5fab15655776896f13b61a951fdvboxsync PSUPDRVVDTPROVIDERCORE pProv = (PSUPDRVVDTPROVIDERCORE)pvProv;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync unsigned uArg = pArgDesc->dtargd_ndx;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync pArgDesc->dtargd_ndx = DTRACE_ARGNONE;
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync AssertPtrReturnVoid(pProv);
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync LOG_DTRACE(("%s: %p / %p - %#x / %p uArg=%d\n", __FUNCTION__, pProv, pProv->TracerData.DTrace.idProvider, idProbe, pvProbe, uArg));
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync AssertPtrReturnVoid(pProv->TracerData.DTrace.idProvider);
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync if (!pProv->TracerData.DTrace.fZombie)
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync {
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync uint32_t idxProbeLoc = (uint32_t)(uintptr_t)pvProbe;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync PCVTGPROBELOC pProbeLocRO = (PVTGPROBELOC)&pProv->paProbeLocsRO[idxProbeLoc];
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync PCVTGDESCPROBE pProbeDesc = pProbeLocRO->pProbe;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync PCVTGDESCARGLIST pArgList = (PCVTGDESCARGLIST)( (uintptr_t)pProv->pHdr
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync + pProv->pHdr->offArgLists
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync + pProbeDesc->offArgList);
62eba2c4d39256b293dc23f1608c5ae26d412c0fvboxsync AssertReturnVoid(pProbeDesc->offArgList < pProv->pHdr->cbArgLists);
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync
62eba2c4d39256b293dc23f1608c5ae26d412c0fvboxsync if (uArg < pArgList->cArgs)
06b49f334535705aeae0ac0572fc5142dc589153vboxsync {
1379dfd407ada5fab15655776896f13b61a951fdvboxsync const char *pszType = vboxDtVtgGetString(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);
e250515922582e0410c9bcb6d24b0f17bef083a0vboxsync /** @todo mapping? */
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync pArgDesc->dtargd_ndx = uArg;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync LOG_DTRACE(("%s: returns dtargd_native = %s\n", __FUNCTION__, pArgDesc->dtargd_native));
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync return;
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync }
06b49f334535705aeae0ac0572fc5142dc589153vboxsync }
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync }
42576743851c3c956ad7e867e74df1084c30d434vboxsync}
42576743851c3c956ad7e867e74df1084c30d434vboxsync
42576743851c3c956ad7e867e74df1084c30d434vboxsync
42576743851c3c956ad7e867e74df1084c30d434vboxsync/**
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync * @callback_method_impl{dtrace_pops_t,dtps_getargval}
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync *
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync *
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync * We just cook our own stuff here, using a stack marker for finding the
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync * required information. That's more reliable than subjecting oneself to the
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync * solaris bugs and 32-bit apple peculiarities.
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync *
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync *
1379dfd407ada5fab15655776896f13b61a951fdvboxsync * @remarks Solaris Bug
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync *
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync * dtrace_getarg on AMD64 has a different opinion about how to use the cFrames
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync * argument than dtrace_caller() and/or dtrace_getpcstack(), at least when the
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync * probe is fired by dtrace_probe() the way we do.
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync *
1379dfd407ada5fab15655776896f13b61a951fdvboxsync * Setting aframes to 1 when calling dtrace_probe_create gives me the right
1379dfd407ada5fab15655776896f13b61a951fdvboxsync * arguments, but the wrong 'caller'. Since I cannot do anything about
1379dfd407ada5fab15655776896f13b61a951fdvboxsync * 'caller', the only solution is this hack.
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync *
1379dfd407ada5fab15655776896f13b61a951fdvboxsync * Not sure why the Solaris guys hasn't seen this issue before, but maybe there
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync * isn't anyone using the default argument getter path for ring-0 dtrace_probe()
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync * calls, SDT surely isn't.
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync *
1379dfd407ada5fab15655776896f13b61a951fdvboxsync * @todo File a solaris bug on dtrace_probe() + dtrace_getarg().
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync *
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync *
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync * @remarks 32-bit XNU (Apple)
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync *
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync * The dtrace_probe arguments are 64-bit unsigned integers instead of uintptr_t,
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync * so we need to make an extra call.
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync *
42576743851c3c956ad7e867e74df1084c30d434vboxsync */
2d66abeefb9716ed570bb5714884d3fe08629452vboxsyncstatic uint64_t vboxDtPOps_GetArgVal(void *pvProv, dtrace_id_t idProbe, void *pvProbe,
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync int iArg, int cFrames)
42576743851c3c956ad7e867e74df1084c30d434vboxsync{
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync PSUPDRVVDTPROVIDERCORE pProv = (PSUPDRVVDTPROVIDERCORE)pvProv;
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync AssertPtrReturn(pProv, UINT64_MAX);
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync LOG_DTRACE(("%s: %p / %p - %#x / %p iArg=%d cFrames=%u\n", __FUNCTION__, pProv, pProv->TracerData.DTrace.idProvider, idProbe, pvProbe, iArg, cFrames));
1379dfd407ada5fab15655776896f13b61a951fdvboxsync AssertReturn(iArg >= 5, UINT64_MAX);
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync if (pProv->TracerData.DTrace.fZombie)
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync return UINT64_MAX;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync uint32_t idxProbeLoc = (uint32_t)(uintptr_t)pvProbe;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync PCVTGPROBELOC pProbeLocRO = (PVTGPROBELOC)&pProv->paProbeLocsRO[idxProbeLoc];
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync PCVTGDESCPROBE pProbeDesc = pProbeLocRO->pProbe;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync PCVTGDESCARGLIST pArgList = (PCVTGDESCARGLIST)( (uintptr_t)pProv->pHdr
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync + pProv->pHdr->offArgLists
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync + pProbeDesc->offArgList);
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync AssertReturn(pProbeDesc->offArgList < pProv->pHdr->cbArgLists, UINT64_MAX);
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync PVBDTSTACKDATA pData = vboxDtGetStackData();
68f6401ff0e0eac2b9dcb0c71f233cd27b289c24vboxsync
20f21077abf35d7b7b618acb159267933907407fvboxsync /*
20f21077abf35d7b7b618acb159267933907407fvboxsync * Get the stack data. This is a wee bit complicated on 32-bit systems
20f21077abf35d7b7b618acb159267933907407fvboxsync * since we want to support 64-bit integer arguments.
20f21077abf35d7b7b618acb159267933907407fvboxsync */
e250515922582e0410c9bcb6d24b0f17bef083a0vboxsync uint64_t u64Ret;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync if (iArg >= 20)
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync u64Ret = UINT64_MAX;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync else if (pData->enmCaller == kVBoxDtCaller_ProbeFireKernel)
e250515922582e0410c9bcb6d24b0f17bef083a0vboxsync {
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync#if ARCH_BITS == 64
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync u64Ret = pData->u.ProbeFireKernel.pauStackArgs[iArg - 5];
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync#else
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync if ( !pArgList->fHaveLargeArgs
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync || iArg >= pArgList->cArgs)
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync u64Ret = pData->u.ProbeFireKernel.pauStackArgs[iArg - 5];
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync else
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync {
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync /* Similar to what we did for mac in when calling dtrace_probe(). */
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync uint32_t offArg = 0;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync for (int i = 5; i < iArg; i++)
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync if (VTG_TYPE_IS_LARGE(pArgList->aArgs[iArg].fType))
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync offArg++;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync u64Ret = pData->u.ProbeFireKernel.pauStackArgs[iArg - 5 + offArg];
20f21077abf35d7b7b618acb159267933907407fvboxsync if (VTG_TYPE_IS_LARGE(pArgList->aArgs[iArg].fType))
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync u64Ret |= (uint64_t)pData->u.ProbeFireKernel.pauStackArgs[iArg - 5 + offArg + 1] << 32;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync }
e250515922582e0410c9bcb6d24b0f17bef083a0vboxsync#endif
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync }
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync else if (pData->enmCaller == kVBoxDtCaller_ProbeFireUser)
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync {
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync int offArg = pData->u.ProbeFireUser.offArg;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync PCSUPDRVTRACERUSRCTX pCtx = pData->u.ProbeFireUser.pCtx;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync AssertPtrReturn(pCtx, UINT64_MAX);
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync if (pCtx->cBits == 32)
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync {
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync if ( !pArgList->fHaveLargeArgs
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync || iArg >= pArgList->cArgs)
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync {
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync if (iArg + offArg < (int)RT_ELEMENTS(pCtx->u.X86.aArgs))
905ba1bf8a49cf348eeade2c0b98658e5a32684cvboxsync u64Ret = pCtx->u.X86.aArgs[iArg + offArg];
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync else
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync u64Ret = UINT64_MAX;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync }
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync else
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync {
c6b3d55ef646614cc689faa1fa4ddc961712b6ffvboxsync int i;
c6b3d55ef646614cc689faa1fa4ddc961712b6ffvboxsync for (i = 5; i < iArg; i++)
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync if (VTG_TYPE_IS_LARGE(pArgList->aArgs[iArg].fType))
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync offArg++;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync if (offArg + iArg < (int)RT_ELEMENTS(pCtx->u.X86.aArgs))
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync {
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync u64Ret = pCtx->u.X86.aArgs[iArg + offArg];
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync if ( VTG_TYPE_IS_LARGE(pArgList->aArgs[iArg].fType)
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync && offArg + iArg + 1 < (int)RT_ELEMENTS(pCtx->u.X86.aArgs))
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync u64Ret |= (uint64_t)pCtx->u.X86.aArgs[iArg + offArg + 1] << 32;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync }
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync else
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync u64Ret = UINT64_MAX;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync }
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync }
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync else
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync {
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync if (iArg + offArg < (int)RT_ELEMENTS(pCtx->u.Amd64.aArgs))
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync u64Ret = pCtx->u.Amd64.aArgs[iArg + offArg];
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync else
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync u64Ret = UINT64_MAX;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync }
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync }
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync else
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync AssertFailedReturn(UINT64_MAX);
e250515922582e0410c9bcb6d24b0f17bef083a0vboxsync
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync LOG_DTRACE(("%s: returns %#llx\n", __FUNCTION__, u64Ret));
e250515922582e0410c9bcb6d24b0f17bef083a0vboxsync return u64Ret;
42576743851c3c956ad7e867e74df1084c30d434vboxsync}
e80aaa9a63f82ac2cece3a2d5a415774a72b0c82vboxsync
42576743851c3c956ad7e867e74df1084c30d434vboxsync
42576743851c3c956ad7e867e74df1084c30d434vboxsync/**
42576743851c3c956ad7e867e74df1084c30d434vboxsync * @callback_method_impl{dtrace_pops_t,dtps_destroy}
42576743851c3c956ad7e867e74df1084c30d434vboxsync */
2d66abeefb9716ed570bb5714884d3fe08629452vboxsyncstatic void vboxDtPOps_Destroy(void *pvProv, dtrace_id_t idProbe, void *pvProbe)
42576743851c3c956ad7e867e74df1084c30d434vboxsync{
1379dfd407ada5fab15655776896f13b61a951fdvboxsync PSUPDRVVDTPROVIDERCORE pProv = (PSUPDRVVDTPROVIDERCORE)pvProv;
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync AssertPtrReturnVoid(pProv);
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync LOG_DTRACE(("%s: %p / %p - %#x / %p\n", __FUNCTION__, pProv, pProv->TracerData.DTrace.idProvider, idProbe, pvProbe));
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync AssertReturnVoid(pProv->TracerData.DTrace.cProvidedProbes > 0);
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync AssertPtrReturnVoid(pProv->TracerData.DTrace.idProvider);
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync if (!pProv->TracerData.DTrace.fZombie)
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync {
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync uint32_t idxProbeLoc = (uint32_t)(uintptr_t)pvProbe;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync PCVTGPROBELOC pProbeLocRO = (PVTGPROBELOC)&pProv->paProbeLocsRO[idxProbeLoc];
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync uint32_t *pidProbe;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync if (!pProv->fUmod)
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync {
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync pidProbe = (uint32_t *)&pProbeLocRO->idProbe;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync Assert(!pProbeLocRO->fEnabled);
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync Assert(*pidProbe == idProbe);
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync }
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync else
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync {
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync pidProbe = &pProv->paR0ProbeLocs[idxProbeLoc].idProbe;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync Assert(!pProv->paR0ProbeLocs[idxProbeLoc].fEnabled);
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync Assert(*pidProbe == idProbe); NOREF(idProbe);
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync }
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync *pidProbe = 0;
b32be08cd134577ca98e517c019c867c416ec0f2vboxsync }
1379dfd407ada5fab15655776896f13b61a951fdvboxsync pProv->TracerData.DTrace.cProvidedProbes--;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync}
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync/**
1379dfd407ada5fab15655776896f13b61a951fdvboxsync * DTrace provider method table.
1379dfd407ada5fab15655776896f13b61a951fdvboxsync */
1379dfd407ada5fab15655776896f13b61a951fdvboxsyncstatic const dtrace_pops_t g_vboxDtVtgProvOps =
1379dfd407ada5fab15655776896f13b61a951fdvboxsync{
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync /* .dtps_provide = */ vboxDtPOps_Provide,
1379dfd407ada5fab15655776896f13b61a951fdvboxsync /* .dtps_provide_module = */ NULL,
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync /* .dtps_enable = */ (FNPOPS_ENABLE *)vboxDtPOps_Enable,
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync /* .dtps_disable = */ vboxDtPOps_Disable,
1379dfd407ada5fab15655776896f13b61a951fdvboxsync /* .dtps_suspend = */ NULL,
1379dfd407ada5fab15655776896f13b61a951fdvboxsync /* .dtps_resume = */ NULL,
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync /* .dtps_getargdesc = */ vboxDtPOps_GetArgDesc,
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync /* .dtps_getargval = */ vboxDtPOps_GetArgVal,
1379dfd407ada5fab15655776896f13b61a951fdvboxsync /* .dtps_usermode = */ NULL,
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync /* .dtps_destroy = */ vboxDtPOps_Destroy
1379dfd407ada5fab15655776896f13b61a951fdvboxsync};
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync/*
1379dfd407ada5fab15655776896f13b61a951fdvboxsync *
1379dfd407ada5fab15655776896f13b61a951fdvboxsync * Support Driver Tracer Interface.
1379dfd407ada5fab15655776896f13b61a951fdvboxsync * Support Driver Tracer Interface.
1379dfd407ada5fab15655776896f13b61a951fdvboxsync * Support Driver Tracer Interface.
1379dfd407ada5fab15655776896f13b61a951fdvboxsync *
1379dfd407ada5fab15655776896f13b61a951fdvboxsync */
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync/**
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync * interface_method_impl{SUPDRVTRACERREG,pfnProbeFireKernel}
1379dfd407ada5fab15655776896f13b61a951fdvboxsync */
2d66abeefb9716ed570bb5714884d3fe08629452vboxsyncstatic DECLCALLBACK(void) vboxDtTOps_ProbeFireKernel(struct VTGPROBELOC *pVtgProbeLoc, uintptr_t uArg0, uintptr_t uArg1, uintptr_t uArg2,
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync uintptr_t uArg3, uintptr_t uArg4)
1379dfd407ada5fab15655776896f13b61a951fdvboxsync{
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync AssertPtrReturnVoid(pVtgProbeLoc);
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync LOG_DTRACE(("%s: %p / %p\n", __FUNCTION__, pVtgProbeLoc, pVtgProbeLoc->idProbe));
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync AssertPtrReturnVoid(pVtgProbeLoc->pProbe);
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync AssertPtrReturnVoid(pVtgProbeLoc->pszFunction);
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync VBDT_SETUP_STACK_DATA(kVBoxDtCaller_ProbeFireKernel);
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync pStackData->u.ProbeFireKernel.pauStackArgs = &uArg4 + 1;
20f21077abf35d7b7b618acb159267933907407fvboxsync
20f21077abf35d7b7b618acb159267933907407fvboxsync#if defined(RT_OS_DARWIN) && ARCH_BITS == 32
20f21077abf35d7b7b618acb159267933907407fvboxsync /*
20f21077abf35d7b7b618acb159267933907407fvboxsync * Convert arguments from uintptr_t to uint64_t.
20f21077abf35d7b7b618acb159267933907407fvboxsync */
b556787c0dbf5af57c6e9d5f4edfbf52403fd89fvboxsync PVTGDESCPROBE pProbe = (PVTGDESCPROBE)((PVTGPROBELOC)pVtgProbeLoc)->pProbe;
20f21077abf35d7b7b618acb159267933907407fvboxsync AssertPtrReturnVoid(pProbe);
20f21077abf35d7b7b618acb159267933907407fvboxsync PVTGOBJHDR pVtgHdr = (PVTGOBJHDR)((uintptr_t)pProbe + pProbe->offObjHdr);
20f21077abf35d7b7b618acb159267933907407fvboxsync AssertPtrReturnVoid(pVtgHdr);
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync PVTGDESCARGLIST pArgList = (PVTGDESCARGLIST)((uintptr_t)pVtgHdr + pVtgHdr->offArgLists + pProbe->offArgList);
20f21077abf35d7b7b618acb159267933907407fvboxsync AssertPtrReturnVoid(pArgList);
20f21077abf35d7b7b618acb159267933907407fvboxsync if (!pArgList->fHaveLargeArgs)
20f21077abf35d7b7b618acb159267933907407fvboxsync dtrace_probe(pVtgProbeLoc->idProbe, uArg0, uArg1, uArg2, uArg3, uArg4);
20f21077abf35d7b7b618acb159267933907407fvboxsync else
20f21077abf35d7b7b618acb159267933907407fvboxsync {
20f21077abf35d7b7b618acb159267933907407fvboxsync uintptr_t *auSrcArgs = &uArg0;
20f21077abf35d7b7b618acb159267933907407fvboxsync uint32_t iSrcArg = 0;
20f21077abf35d7b7b618acb159267933907407fvboxsync uint32_t iDstArg = 0;
20f21077abf35d7b7b618acb159267933907407fvboxsync uint64_t au64DstArgs[5];
20f21077abf35d7b7b618acb159267933907407fvboxsync
20f21077abf35d7b7b618acb159267933907407fvboxsync while ( iDstArg < RT_ELEMENTS(au64DstArgs)
20f21077abf35d7b7b618acb159267933907407fvboxsync && iSrcArg < pArgList->cArgs)
20f21077abf35d7b7b618acb159267933907407fvboxsync {
20f21077abf35d7b7b618acb159267933907407fvboxsync au64DstArgs[iDstArg] = auSrcArgs[iSrcArg];
20f21077abf35d7b7b618acb159267933907407fvboxsync if (VTG_TYPE_IS_LARGE(pArgList->aArgs[iDstArg].fType))
20f21077abf35d7b7b618acb159267933907407fvboxsync au64DstArgs[iDstArg] |= (uint64_t)auSrcArgs[++iSrcArg] << 32;
20f21077abf35d7b7b618acb159267933907407fvboxsync iSrcArg++;
20f21077abf35d7b7b618acb159267933907407fvboxsync iDstArg++;
20f21077abf35d7b7b618acb159267933907407fvboxsync }
20f21077abf35d7b7b618acb159267933907407fvboxsync while (iDstArg < RT_ELEMENTS(au64DstArgs))
20f21077abf35d7b7b618acb159267933907407fvboxsync au64DstArgs[iDstArg++] = auSrcArgs[iSrcArg++];
20f21077abf35d7b7b618acb159267933907407fvboxsync
b556787c0dbf5af57c6e9d5f4edfbf52403fd89fvboxsync pStackData->u.ProbeFireKernel.pauStackArgs = &auSrcArgs[iSrcArg];
20f21077abf35d7b7b618acb159267933907407fvboxsync dtrace_probe(pVtgProbeLoc->idProbe, au64DstArgs[0], au64DstArgs[1], au64DstArgs[2], au64DstArgs[3], au64DstArgs[4]);
20f21077abf35d7b7b618acb159267933907407fvboxsync }
20f21077abf35d7b7b618acb159267933907407fvboxsync#else
1379dfd407ada5fab15655776896f13b61a951fdvboxsync dtrace_probe(pVtgProbeLoc->idProbe, uArg0, uArg1, uArg2, uArg3, uArg4);
20f21077abf35d7b7b618acb159267933907407fvboxsync#endif
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync VBDT_CLEAR_STACK_DATA();
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync LOG_DTRACE(("%s: returns\n", __FUNCTION__));
1379dfd407ada5fab15655776896f13b61a951fdvboxsync}
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync/**
1379dfd407ada5fab15655776896f13b61a951fdvboxsync * interface_method_impl{SUPDRVTRACERREG,pfnProbeFireUser}
1379dfd407ada5fab15655776896f13b61a951fdvboxsync */
2d66abeefb9716ed570bb5714884d3fe08629452vboxsyncstatic DECLCALLBACK(void) vboxDtTOps_ProbeFireUser(PCSUPDRVTRACERREG pThis, PSUPDRVSESSION pSession, PCSUPDRVTRACERUSRCTX pCtx,
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync PCVTGOBJHDR pVtgHdr, PCVTGPROBELOC pProbeLocRO)
1379dfd407ada5fab15655776896f13b61a951fdvboxsync{
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync LOG_DTRACE(("%s: %p / %p\n", __FUNCTION__, pCtx, pCtx->idProbe));
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync AssertPtrReturnVoid(pProbeLocRO);
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync AssertPtrReturnVoid(pVtgHdr);
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync VBDT_SETUP_STACK_DATA(kVBoxDtCaller_ProbeFireUser);
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync if (pCtx->cBits == 32)
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync {
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync pStackData->u.ProbeFireUser.pCtx = pCtx;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync pStackData->u.ProbeFireUser.offArg = 0;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync#if ARCH_BITS == 64 || defined(RT_OS_DARWIN)
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync /*
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync * Combine two 32-bit arguments into one 64-bit argument where needed.
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync */
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync PVTGDESCPROBE pProbeDesc = pProbeLocRO->pProbe;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync AssertPtrReturnVoid(pProbeDesc);
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync PVTGDESCARGLIST pArgList = (PVTGDESCARGLIST)((uintptr_t)pVtgHdr + pVtgHdr->offArgLists + pProbeDesc->offArgList);
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync AssertPtrReturnVoid(pArgList);
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync if (!pArgList->fHaveLargeArgs)
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync dtrace_probe(pCtx->idProbe,
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync pCtx->u.X86.aArgs[0],
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync pCtx->u.X86.aArgs[1],
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync pCtx->u.X86.aArgs[2],
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync pCtx->u.X86.aArgs[3],
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync pCtx->u.X86.aArgs[4]);
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync else
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync {
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync uint32_t const *auSrcArgs = &pCtx->u.X86.aArgs[0];
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync uint32_t iSrcArg = 0;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync uint32_t iDstArg = 0;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync uint64_t au64DstArgs[5];
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync while ( iDstArg < RT_ELEMENTS(au64DstArgs)
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync && iSrcArg < pArgList->cArgs)
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync {
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync au64DstArgs[iDstArg] = auSrcArgs[iSrcArg];
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync if (VTG_TYPE_IS_LARGE(pArgList->aArgs[iDstArg].fType))
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync au64DstArgs[iDstArg] |= (uint64_t)auSrcArgs[++iSrcArg] << 32;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync iSrcArg++;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync iDstArg++;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync }
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync while (iDstArg < RT_ELEMENTS(au64DstArgs))
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync au64DstArgs[iDstArg++] = auSrcArgs[iSrcArg++];
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync pStackData->u.ProbeFireUser.offArg = iSrcArg - RT_ELEMENTS(au64DstArgs);
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync dtrace_probe(pCtx->idProbe, au64DstArgs[0], au64DstArgs[1], au64DstArgs[2], au64DstArgs[3], au64DstArgs[4]);
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync }
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync#else
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync dtrace_probe(pCtx->idProbe,
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync pCtx->u.X86.aArgs[0],
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync pCtx->u.X86.aArgs[1],
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync pCtx->u.X86.aArgs[2],
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync pCtx->u.X86.aArgs[3],
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync pCtx->u.X86.aArgs[4]);
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync#endif
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync }
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync else if (pCtx->cBits == 64)
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync {
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync pStackData->u.ProbeFireUser.pCtx = pCtx;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync pStackData->u.ProbeFireUser.offArg = 0;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync dtrace_probe(pCtx->idProbe,
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync pCtx->u.Amd64.aArgs[0],
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync pCtx->u.Amd64.aArgs[1],
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync pCtx->u.Amd64.aArgs[2],
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync pCtx->u.Amd64.aArgs[3],
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync pCtx->u.Amd64.aArgs[4]);
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync }
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync else
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync AssertFailed();
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync VBDT_CLEAR_STACK_DATA();
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync LOG_DTRACE(("%s: returns\n", __FUNCTION__));
1379dfd407ada5fab15655776896f13b61a951fdvboxsync}
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync/**
1379dfd407ada5fab15655776896f13b61a951fdvboxsync * interface_method_impl{SUPDRVTRACERREG,pfnTracerOpen}
1379dfd407ada5fab15655776896f13b61a951fdvboxsync */
2d66abeefb9716ed570bb5714884d3fe08629452vboxsyncstatic DECLCALLBACK(int) vboxDtTOps_TracerOpen(PCSUPDRVTRACERREG pThis, PSUPDRVSESSION pSession, uint32_t uCookie,
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync uintptr_t uArg, uintptr_t *puSessionData)
1379dfd407ada5fab15655776896f13b61a951fdvboxsync{
1379dfd407ada5fab15655776896f13b61a951fdvboxsync NOREF(pThis); NOREF(pSession); NOREF(uCookie); NOREF(uArg);
1379dfd407ada5fab15655776896f13b61a951fdvboxsync *puSessionData = 0;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync return VERR_NOT_SUPPORTED;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync}
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync/**
1379dfd407ada5fab15655776896f13b61a951fdvboxsync * interface_method_impl{SUPDRVTRACERREG,pfnTracerClose}
1379dfd407ada5fab15655776896f13b61a951fdvboxsync */
2d66abeefb9716ed570bb5714884d3fe08629452vboxsyncstatic DECLCALLBACK(int) vboxDtTOps_TracerIoCtl(PCSUPDRVTRACERREG pThis, PSUPDRVSESSION pSession, uintptr_t uSessionData,
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync uintptr_t uCmd, uintptr_t uArg, int32_t *piRetVal)
1379dfd407ada5fab15655776896f13b61a951fdvboxsync{
1379dfd407ada5fab15655776896f13b61a951fdvboxsync NOREF(pThis); NOREF(pSession); NOREF(uSessionData);
1379dfd407ada5fab15655776896f13b61a951fdvboxsync NOREF(uCmd); NOREF(uArg); NOREF(piRetVal);
1379dfd407ada5fab15655776896f13b61a951fdvboxsync return VERR_NOT_SUPPORTED;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync}
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync/**
1379dfd407ada5fab15655776896f13b61a951fdvboxsync * interface_method_impl{SUPDRVTRACERREG,pfnTracerClose}
1379dfd407ada5fab15655776896f13b61a951fdvboxsync */
2d66abeefb9716ed570bb5714884d3fe08629452vboxsyncstatic DECLCALLBACK(void) vboxDtTOps_TracerClose(PCSUPDRVTRACERREG pThis, PSUPDRVSESSION pSession, uintptr_t uSessionData)
1379dfd407ada5fab15655776896f13b61a951fdvboxsync{
1379dfd407ada5fab15655776896f13b61a951fdvboxsync NOREF(pThis); NOREF(pSession); NOREF(uSessionData);
1379dfd407ada5fab15655776896f13b61a951fdvboxsync return;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync}
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync/**
1379dfd407ada5fab15655776896f13b61a951fdvboxsync * interface_method_impl{SUPDRVTRACERREG,pfnProviderRegister}
1379dfd407ada5fab15655776896f13b61a951fdvboxsync */
2d66abeefb9716ed570bb5714884d3fe08629452vboxsyncstatic DECLCALLBACK(int) vboxDtTOps_ProviderRegister(PCSUPDRVTRACERREG pThis, PSUPDRVVDTPROVIDERCORE pCore)
1379dfd407ada5fab15655776896f13b61a951fdvboxsync{
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync LOG_DTRACE(("%s: %p %s/%s\n", __FUNCTION__, pThis, pCore->pszModName, pCore->pszName));
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync AssertReturn(pCore->TracerData.DTrace.idProvider == 0, VERR_INTERNAL_ERROR_3);
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync PVTGDESCPROVIDER pDesc = pCore->pDesc;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync dtrace_pattr_t DtAttrs;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync vboxDtVtgConvAttr(&DtAttrs.dtpa_provider, &pDesc->AttrSelf);
1379dfd407ada5fab15655776896f13b61a951fdvboxsync vboxDtVtgConvAttr(&DtAttrs.dtpa_mod, &pDesc->AttrModules);
1379dfd407ada5fab15655776896f13b61a951fdvboxsync vboxDtVtgConvAttr(&DtAttrs.dtpa_func, &pDesc->AttrFunctions);
1379dfd407ada5fab15655776896f13b61a951fdvboxsync vboxDtVtgConvAttr(&DtAttrs.dtpa_name, &pDesc->AttrNames);
1379dfd407ada5fab15655776896f13b61a951fdvboxsync vboxDtVtgConvAttr(&DtAttrs.dtpa_args, &pDesc->AttrArguments);
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync /* Note! DTrace may call us back before dtrace_register returns, so we
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync have to point it to pCore->TracerData.DTrace.idProvider. */
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync AssertCompile(sizeof(dtrace_provider_id_t) == sizeof(pCore->TracerData.DTrace.idProvider));
1379dfd407ada5fab15655776896f13b61a951fdvboxsync int rc = dtrace_register(pCore->pszName,
1379dfd407ada5fab15655776896f13b61a951fdvboxsync &DtAttrs,
1379dfd407ada5fab15655776896f13b61a951fdvboxsync DTRACE_PRIV_KERNEL,
1379dfd407ada5fab15655776896f13b61a951fdvboxsync NULL /* cred */,
1379dfd407ada5fab15655776896f13b61a951fdvboxsync &g_vboxDtVtgProvOps,
1379dfd407ada5fab15655776896f13b61a951fdvboxsync pCore,
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync &pCore->TracerData.DTrace.idProvider);
1379dfd407ada5fab15655776896f13b61a951fdvboxsync if (!rc)
1379dfd407ada5fab15655776896f13b61a951fdvboxsync {
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync LOG_DTRACE(("%s: idProvider=%p\n", __FUNCTION__, pCore->TracerData.DTrace.idProvider));
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync AssertPtr(pCore->TracerData.DTrace.idProvider);
1379dfd407ada5fab15655776896f13b61a951fdvboxsync rc = VINF_SUCCESS;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync }
1379dfd407ada5fab15655776896f13b61a951fdvboxsync else
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync {
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync pCore->TracerData.DTrace.idProvider = 0;
43bc5c863e4a7f97ef53171421559ea863af4b11vboxsync rc = RTErrConvertFromErrno(FIX_UEK_RC(rc));
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync }
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync LOG_DTRACE(("%s: returns %Rrc\n", __FUNCTION__, rc));
1379dfd407ada5fab15655776896f13b61a951fdvboxsync return rc;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync}
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync/**
1379dfd407ada5fab15655776896f13b61a951fdvboxsync * interface_method_impl{SUPDRVTRACERREG,pfnProviderDeregister}
1379dfd407ada5fab15655776896f13b61a951fdvboxsync */
2d66abeefb9716ed570bb5714884d3fe08629452vboxsyncstatic DECLCALLBACK(int) vboxDtTOps_ProviderDeregister(PCSUPDRVTRACERREG pThis, PSUPDRVVDTPROVIDERCORE pCore)
1379dfd407ada5fab15655776896f13b61a951fdvboxsync{
1379dfd407ada5fab15655776896f13b61a951fdvboxsync uintptr_t idProvider = pCore->TracerData.DTrace.idProvider;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync LOG_DTRACE(("%s: %p / %p\n", __FUNCTION__, pThis, idProvider));
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync AssertPtrReturn(idProvider, VERR_INTERNAL_ERROR_3);
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync dtrace_invalidate(idProvider);
1379dfd407ada5fab15655776896f13b61a951fdvboxsync int rc = dtrace_unregister(idProvider);
1379dfd407ada5fab15655776896f13b61a951fdvboxsync if (!rc)
1379dfd407ada5fab15655776896f13b61a951fdvboxsync {
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync pCore->TracerData.DTrace.idProvider = 0;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync rc = VINF_SUCCESS;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync }
1379dfd407ada5fab15655776896f13b61a951fdvboxsync else
1379dfd407ada5fab15655776896f13b61a951fdvboxsync {
43bc5c863e4a7f97ef53171421559ea863af4b11vboxsync AssertMsg(FIX_UEK_RC(rc) == EBUSY, ("%d\n", rc));
1379dfd407ada5fab15655776896f13b61a951fdvboxsync pCore->TracerData.DTrace.fZombie = true;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync rc = VERR_TRY_AGAIN;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync }
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync LOG_DTRACE(("%s: returns %Rrc\n", __FUNCTION__, rc));
1379dfd407ada5fab15655776896f13b61a951fdvboxsync return rc;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync}
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync/**
1379dfd407ada5fab15655776896f13b61a951fdvboxsync * interface_method_impl{SUPDRVTRACERREG,pfnProviderDeregisterZombie}
1379dfd407ada5fab15655776896f13b61a951fdvboxsync */
2d66abeefb9716ed570bb5714884d3fe08629452vboxsyncstatic DECLCALLBACK(int) vboxDtTOps_ProviderDeregisterZombie(PCSUPDRVTRACERREG pThis, PSUPDRVVDTPROVIDERCORE pCore)
1379dfd407ada5fab15655776896f13b61a951fdvboxsync{
1379dfd407ada5fab15655776896f13b61a951fdvboxsync uintptr_t idProvider = pCore->TracerData.DTrace.idProvider;
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync LOG_DTRACE(("%s: %p / %p\n", __FUNCTION__, pThis, idProvider));
e89bf42607ac3c1b6c60fabbf6067a38adb1284bvboxsync AssertPtrReturn(idProvider, VERR_INTERNAL_ERROR_3);
1379dfd407ada5fab15655776896f13b61a951fdvboxsync Assert(pCore->TracerData.DTrace.fZombie);
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync int rc = dtrace_unregister(idProvider);
1379dfd407ada5fab15655776896f13b61a951fdvboxsync if (!rc)
1379dfd407ada5fab15655776896f13b61a951fdvboxsync {
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync pCore->TracerData.DTrace.idProvider = 0;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync rc = VINF_SUCCESS;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync }
1379dfd407ada5fab15655776896f13b61a951fdvboxsync else
1379dfd407ada5fab15655776896f13b61a951fdvboxsync {
43bc5c863e4a7f97ef53171421559ea863af4b11vboxsync AssertMsg(FIX_UEK_RC(rc) == EBUSY, ("%d\n", rc));
1379dfd407ada5fab15655776896f13b61a951fdvboxsync rc = VERR_TRY_AGAIN;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync }
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync LOG_DTRACE(("%s: returns %Rrc\n", __FUNCTION__, rc));
1379dfd407ada5fab15655776896f13b61a951fdvboxsync return rc;
cdcfac625bb49f1d4b67aaf8fb8b1cdb69fe49c2vboxsync}
42576743851c3c956ad7e867e74df1084c30d434vboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync/**
1379dfd407ada5fab15655776896f13b61a951fdvboxsync * The tracer registration record of the VBox DTrace implementation
1379dfd407ada5fab15655776896f13b61a951fdvboxsync */
2d66abeefb9716ed570bb5714884d3fe08629452vboxsyncstatic SUPDRVTRACERREG g_VBoxDTraceReg =
1379dfd407ada5fab15655776896f13b61a951fdvboxsync{
1379dfd407ada5fab15655776896f13b61a951fdvboxsync SUPDRVTRACERREG_MAGIC,
1379dfd407ada5fab15655776896f13b61a951fdvboxsync SUPDRVTRACERREG_VERSION,
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync vboxDtTOps_ProbeFireKernel,
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync vboxDtTOps_ProbeFireUser,
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync vboxDtTOps_TracerOpen,
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync vboxDtTOps_TracerIoCtl,
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync vboxDtTOps_TracerClose,
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync vboxDtTOps_ProviderRegister,
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync vboxDtTOps_ProviderDeregister,
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync vboxDtTOps_ProviderDeregisterZombie,
1379dfd407ada5fab15655776896f13b61a951fdvboxsync SUPDRVTRACERREG_MAGIC
1379dfd407ada5fab15655776896f13b61a951fdvboxsync};
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync/**
1379dfd407ada5fab15655776896f13b61a951fdvboxsync * Module initialization code.
1379dfd407ada5fab15655776896f13b61a951fdvboxsync *
1379dfd407ada5fab15655776896f13b61a951fdvboxsync * @param hMod Opque module handle.
1379dfd407ada5fab15655776896f13b61a951fdvboxsync */
1379dfd407ada5fab15655776896f13b61a951fdvboxsyncconst SUPDRVTRACERREG * VBOXCALL supdrvDTraceInit(void)
1379dfd407ada5fab15655776896f13b61a951fdvboxsync{
f714516da18876b1836a804fc0cac5e8ff589e83vboxsync#if defined(RT_OS_DARWIN) || defined(RT_OS_LINUX)
1379dfd407ada5fab15655776896f13b61a951fdvboxsync /*
1379dfd407ada5fab15655776896f13b61a951fdvboxsync * Resolve the kernel symbols we need.
1379dfd407ada5fab15655776896f13b61a951fdvboxsync */
f714516da18876b1836a804fc0cac5e8ff589e83vboxsync# ifndef RT_OS_LINUX
1379dfd407ada5fab15655776896f13b61a951fdvboxsync RTDBGKRNLINFO hKrnlInfo;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync int rc = RTR0DbgKrnlInfoOpen(&hKrnlInfo, 0);
1379dfd407ada5fab15655776896f13b61a951fdvboxsync if (RT_FAILURE(rc))
1379dfd407ada5fab15655776896f13b61a951fdvboxsync {
1379dfd407ada5fab15655776896f13b61a951fdvboxsync SUPR0Printf("supdrvDTraceInit: RTR0DbgKrnlInfoOpen failed with rc=%d.\n", rc);
1379dfd407ada5fab15655776896f13b61a951fdvboxsync return NULL;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync }
f714516da18876b1836a804fc0cac5e8ff589e83vboxsync# endif
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
1379dfd407ada5fab15655776896f13b61a951fdvboxsync static const struct
1379dfd407ada5fab15655776896f13b61a951fdvboxsync {
1379dfd407ada5fab15655776896f13b61a951fdvboxsync const char *pszName;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync PFNRT *ppfn;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync } s_aDTraceFunctions[] =
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync {
1379dfd407ada5fab15655776896f13b61a951fdvboxsync { "dtrace_probe", (PFNRT*)&dtrace_probe },
1379dfd407ada5fab15655776896f13b61a951fdvboxsync { "dtrace_probe_create", (PFNRT*)&dtrace_probe_create },
1379dfd407ada5fab15655776896f13b61a951fdvboxsync { "dtrace_probe_lookup", (PFNRT*)&dtrace_probe_lookup },
1379dfd407ada5fab15655776896f13b61a951fdvboxsync { "dtrace_register", (PFNRT*)&dtrace_register },
1379dfd407ada5fab15655776896f13b61a951fdvboxsync { "dtrace_invalidate", (PFNRT*)&dtrace_invalidate },
1379dfd407ada5fab15655776896f13b61a951fdvboxsync { "dtrace_unregister", (PFNRT*)&dtrace_unregister },
1379dfd407ada5fab15655776896f13b61a951fdvboxsync };
f714516da18876b1836a804fc0cac5e8ff589e83vboxsync unsigned i;
f714516da18876b1836a804fc0cac5e8ff589e83vboxsync for (i = 0; i < RT_ELEMENTS(s_aDTraceFunctions); i++)
1379dfd407ada5fab15655776896f13b61a951fdvboxsync {
f714516da18876b1836a804fc0cac5e8ff589e83vboxsync# ifndef RT_OS_LINUX
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync rc = RTR0DbgKrnlInfoQuerySymbol(hKrnlInfo, NULL, s_aDTraceFunctions[i].pszName,
1379dfd407ada5fab15655776896f13b61a951fdvboxsync (void **)s_aDTraceFunctions[i].ppfn);
1379dfd407ada5fab15655776896f13b61a951fdvboxsync if (RT_FAILURE(rc))
1379dfd407ada5fab15655776896f13b61a951fdvboxsync {
1379dfd407ada5fab15655776896f13b61a951fdvboxsync SUPR0Printf("supdrvDTraceInit: Failed to resolved '%s' (rc=%Rrc, i=%u).\n", s_aDTraceFunctions[i].pszName, rc, i);
1379dfd407ada5fab15655776896f13b61a951fdvboxsync break;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync }
f714516da18876b1836a804fc0cac5e8ff589e83vboxsync# else
f714516da18876b1836a804fc0cac5e8ff589e83vboxsync unsigned long ulAddr = kallsyms_lookup_name(s_aDTraceFunctions[i].pszName);
f714516da18876b1836a804fc0cac5e8ff589e83vboxsync if (!ulAddr)
f714516da18876b1836a804fc0cac5e8ff589e83vboxsync {
f714516da18876b1836a804fc0cac5e8ff589e83vboxsync SUPR0Printf("supdrvDTraceInit: Failed to resolved '%s' (i=%u).\n", s_aDTraceFunctions[i].pszName, i);
694748dd5c1c5b465fbe00cd200cd49a9e484dc7vboxsync return NULL;
f714516da18876b1836a804fc0cac5e8ff589e83vboxsync }
f714516da18876b1836a804fc0cac5e8ff589e83vboxsync *s_aDTraceFunctions[i].ppfn = (PFNRT)ulAddr;
f714516da18876b1836a804fc0cac5e8ff589e83vboxsync# endif
1379dfd407ada5fab15655776896f13b61a951fdvboxsync }
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
f714516da18876b1836a804fc0cac5e8ff589e83vboxsync# ifndef RT_OS_LINUX
1379dfd407ada5fab15655776896f13b61a951fdvboxsync RTR0DbgKrnlInfoRelease(hKrnlInfo);
1379dfd407ada5fab15655776896f13b61a951fdvboxsync if (RT_FAILURE(rc))
1379dfd407ada5fab15655776896f13b61a951fdvboxsync return NULL;
694748dd5c1c5b465fbe00cd200cd49a9e484dc7vboxsync# else
694748dd5c1c5b465fbe00cd200cd49a9e484dc7vboxsync /** @todo grab a reference to the dtrace module... */
f714516da18876b1836a804fc0cac5e8ff589e83vboxsync# endif
1379dfd407ada5fab15655776896f13b61a951fdvboxsync#endif
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
2d66abeefb9716ed570bb5714884d3fe08629452vboxsync return &g_VBoxDTraceReg;
1379dfd407ada5fab15655776896f13b61a951fdvboxsync}
1379dfd407ada5fab15655776896f13b61a951fdvboxsync
81614fc60e096e714022d10d38b70a36b9b21d48vboxsync#ifndef VBOX_WITH_NATIVE_DTRACE
81614fc60e096e714022d10d38b70a36b9b21d48vboxsync# error "VBOX_WITH_NATIVE_DTRACE is not defined as it should"
1379dfd407ada5fab15655776896f13b61a951fdvboxsync#endif
1379dfd407ada5fab15655776896f13b61a951fdvboxsync