VirtualBox

儲存庫 vbox 的更動 40851


忽略:
時間撮記:
2012-4-10 下午02:13:26 (13 年 以前)
作者:
vboxsync
訊息:

SUPDrv,VBoxTpG: Redid the solaris(/darwin) DTrace support to use the generic tracer bits.

位置:
trunk
檔案:
修改 6 筆資料

圖例:

未更動
新增
刪除
  • trunk/include/VBox/VBoxTpG.h

    r40839 r40851  
    3636    const char *pszFunction;
    3737    uint8_t    *pbProbe;
     38#if ARCH_BITS == 64
     39    uintptr_t   uAlignment;
     40#endif
    3841} VTGPROBELOC;
     42AssertCompileSizeAlignment(VTGPROBELOC, 16);
    3943/** Pointer to a probe location. */
    4044typedef VTGPROBELOC *PVTGPROBELOC;
     
    224228
    225229/** The current VTGOBJHDR::szMagic value. */
    226 #define VTGOBJHDR_MAGIC     "VTG Object Header v1.1\0"
     230#define VTGOBJHDR_MAGIC     "VTG Object Header v1.2\0"
    227231
    228232/** The name of the VTG data object header symbol in the object file. */
  • trunk/src/VBox/HostDrivers/Support/Makefile.kmk

    r40795 r40851  
    297297 #VBoxDrv_LDFLAGS.darwin    = -v -Wl,-whyload -Wl,-v -Wl,-whatsloaded
    298298 VBoxDrv_LDFLAGS.solaris += -N misc/ctf
     299 VBoxDrv_LDFLAGS.solaris += -N misc/dtrace
    299300 VBoxDrv_LDFLAGS.win.x86  = -Entry:DriverEntry@8
    300301 VBoxDrv_LDFLAGS.win.amd64= -Entry:DriverEntry
    301302
    302303 VBoxDrv_SOURCES.darwin   = darwin/SUPDrv-darwin.cpp
    303  VBoxDrv_SOURCES.solaris  = solaris/SUPDrv-solaris.c
     304 VBoxDrv_SOURCES.solaris  = \
     305        solaris/SUPDrv-solaris.c
    304306 VBoxDrv_SOURCES.win      = \
    305307        win/SUPDrv-win.cpp \
     
    311313        SUPDrvTracer.cpp \
    312314        SUPDrv.d
     315 ifdef VBOX_WITH_NATIVE_DTRACE_R0DRV
     316  VBoxDrv_SOURCES        += \
     317        SUPDrv-dtrace.cpp
     318 endif
    313319 ifn1of ($(KBUILD_TARGET), linux freebsd)
    314320  VBoxDrv_SOURCES        += \
     
    318324  VBoxDrv_SOURCES.linux  += \
    319325        linux/SUPDrv-linux.mod.c
    320  endif
    321 
    322  ifdef VBOX_WITH_DTRACE_R0DRV # FIXME
    323   VBoxDrv_SOURCES        += \
    324         SUPDrv-dtrace.cpp
    325   VBoxDrv_DTRACE_OBJ_FLAGS.solaris = --probe-fn-name=dtrace_probe
    326   VBoxDrv_LDFLAGS.solaris+= -N misc/dtrace
    327326 endif
    328327
  • trunk/src/VBox/HostDrivers/Support/SUPDrv-dtrace.cpp

    r40777 r40851  
    1 #error FIXME
    21/* $Id$ */
    32/** @file
     
    2625 */
    2726
    28 /** @todo Convert this to a generic tracer implementation. */
    2927
    3028/*******************************************************************************
     
    4038#include <iprt/assert.h>
    4139#include <iprt/ctype.h>
    42 #include <iprt/list.h>
    4340#include <iprt/mem.h>
    44 #include <iprt/semaphore.h>
    45 #include <iprt/thread.h>
    4641
    4742#ifdef RT_OS_DARWIN /** @todo figure this! */
     
    5550*   Structures and Typedefs                                                    *
    5651*******************************************************************************/
    57 /**
    58  * Data for a provider.
    59  */
    60 typedef struct SUPDRVDTPROVIDER
    61 {
    62     /** The entry in the provider list for this image. */
    63     RTLISTNODE          ListEntry;
    64 
    65     /** The provider descriptor. */
    66     PVTGDESCPROVIDER    pDesc;
    67     /** The VTG header. */
    68     PVTGOBJHDR          pHdr;
    69 
    70     /** Pointer to the image this provider resides in.  NULL if it's a
    71      * driver. */
    72     PSUPDRVLDRIMAGE     pImage;
    73     /** The session this provider is associated with if registered via
    74      * SUPR0VtgRegisterDrv.  NULL if pImage is set. */
    75     PSUPDRVSESSION      pSession;
    76     /** The module name. */
    77     const char         *pszModName;
    78 
    79     /** Dtrace provider attributes. */
    80     dtrace_pattr_t      DtAttrs;
    81     /** The ID of this provider. */
    82     dtrace_provider_id_t idDtProv;
    83     /** The number of probes we've provided to DTrace. */
    84     uint32_t            cProvidedProbes;
    85     /** Set when the module is unloaded or the driver deregisters its probes. */
    86     bool                fZombie;
    87     /** The provider name (for logging purposes). */
    88     char                szName[1];
    89 } SUPDRVDTPROVIDER;
    90 /** Pointer to the data for a provider. */
    91 typedef SUPDRVDTPROVIDER *PSUPDRVDTPROVIDER;
    92 
    9352/* Seems there is some return code difference here. Keep the return code and
    9453   case it to whatever the host desires. */
     
    10059
    10160
    102 /*******************************************************************************
    103 *   Defined Constants And Macros                                               *
    104 *******************************************************************************/
    105 #if 0
    106 # define LOG_DTRACE(a_Args)  SUPR0Printf a_Args
    107 #else
    108 # define LOG_DTRACE(a_Args)  do { } while (0)
    109 #endif
    110 
    111 /*******************************************************************************
    112 *   Internal Functions                                                         *
    113 *******************************************************************************/
    114 static void     supdrvDTracePOps_Provide(void *pvProv, const dtrace_probedesc_t *pDtProbeDesc);
    115 static int      supdrvDTracePOps_Enable(void *pvProv, dtrace_id_t idProbe, void *pvProbe);
    116 static void     supdrvDTracePOps_Disable(void *pvProv, dtrace_id_t idProbe, void *pvProbe);
    117 static void     supdrvDTracePOps_GetArgDesc(void *pvProv, dtrace_id_t idProbe, void *pvProbe,
    118                                             dtrace_argdesc_t *pArgDesc);
    119 #ifdef RT_OS_SOLARIS
    120 static uint64_t supdrvDTracePOps_GetArgVal(void *pvProv, dtrace_id_t idProbe, void *pvProbe,
    121                                            int iArg, int cFrames);
    122 #endif
    123 static void     supdrvDTracePOps_Destroy(void *pvProv, dtrace_id_t idProbe, void *pvProbe);
    124 
     61/**
     62 * Stack data planted before calling dtrace_probe so that we can easily find the
     63 * stack argument later.
     64 */
     65typedef struct SUPDRVDTSTACKDATA
     66{
     67    /** Eyecatcher no. 1 (SUPDRVDT_STACK_DATA_MAGIC2). */
     68    uint32_t                    u32Magic1;
     69    /** Eyecatcher no. 2 (SUPDRVDT_STACK_DATA_MAGIC2). */
     70    uint32_t                    u32Magic2;
     71    /** Pointer to the stack arguments of a probe function call. */
     72    uintptr_t                  *pauStackArgs;
     73    /** Pointer to this structure.
     74     * This is the final bit of integrity checking. */
     75    struct SUPDRVDTSTACKDATA   *pSelf;
     76} SUPDRVDTSTACKDATA;
     77/** Pointer to the on-stack thread specific data. */
     78typedef SUPDRVDTSTACKDATA *PSUPDRVDTSTACKDATA;
     79
     80/** The first magic value. */
     81#define SUPDRVDT_STACK_DATA_MAGIC1      RT_MAKE_U32_FROM_U8('S', 'U', 'P', 'D')
     82/** The second magic value. */
     83#define SUPDRVDT_STACK_DATA_MAGIC2      RT_MAKE_U32_FROM_U8('D', 'T', 'r', 'c')
     84
     85/** The alignment of the stack data.
     86 * The data doesn't require more than sizeof(uintptr_t) alignment, but the
     87 * greater alignment the quicker lookup. */
     88#define SUPDRVDT_STACK_DATA_ALIGN       32
     89
     90/** Plants the stack data. */
     91#define SUPDRVDT_SETUP_STACK_DATA() \
     92    uint8_t abBlob[sizeof(SUPDRVDTSTACKDATA) + SUPDRVDT_STACK_DATA_ALIGN - 1]; \
     93    PSUPDRVDTSTACKDATA pStackData = (PSUPDRVDTSTACKDATA)(   (uintptr_t)&abBlob[SUPDRVDT_STACK_DATA_ALIGN - 1] \
     94                                                         & ~(uintptr_t)(SUPDRVDT_STACK_DATA_ALIGN - 1)); \
     95    pStackData->u32Magic1   = SUPDRVDT_STACK_DATA_MAGIC1; \
     96    pStackData->u32Magic2   = SUPDRVDT_STACK_DATA_MAGIC2; \
     97    pStackData->pSelf       = pStackData
     98
     99/** Passifies the stack data and frees up resource held within it. */
     100#define SUPDRVDT_CLEAR_STACK_DATA() \
     101    do \
     102    { \
     103        pStackData->u32Magic1   = 0; \
     104        pStackData->u32Magic2   = 0; \
     105        pStackData->pSelf       = NULL; \
     106    } while (0)
    125107
    126108
     
    128110*   Global Variables                                                           *
    129111*******************************************************************************/
    130 /**
    131  * DTrace provider method table.
    132  */
    133 static const dtrace_pops_t g_SupDrvDTraceProvOps =
    134 {
    135     /* .dtps_provide         = */ supdrvDTracePOps_Provide,
    136     /* .dtps_provide_module  = */ NULL,
    137     /* .dtps_enable          = */ (FNPOPS_ENABLE *)supdrvDTracePOps_Enable,
    138     /* .dtps_disable         = */ supdrvDTracePOps_Disable,
    139     /* .dtps_suspend         = */ NULL,
    140     /* .dtps_resume          = */ NULL,
    141     /* .dtps_getargdesc      = */ supdrvDTracePOps_GetArgDesc,
    142 #ifdef RT_OS_SOLARIS
    143     /* .dtps_getargval       = */ supdrvDTracePOps_GetArgVal,
    144 #else
    145     /* .dtps_getargval       = */ NULL/*supdrvDTracePOps_GetArgVal*/,
     112#ifdef RT_OS_DARWIN
     113/** @name DTrace kernel interface used on Darwin
     114 * @{ */
     115static void        (* dtrace_probe)(dtrace_id_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t);
     116static dtrace_id_t (* dtrace_probe_create)(dtrace_provider_id_t, const char *, const char *, const char *, int, void *);
     117static dtrace_id_t (* dtrace_probe_lookup)(dtrace_provider_id_t, const char *, const char *, const char *);
     118static int         (* dtrace_register)(const char *, const dtrace_pattr_t *, uint32_t, /*cred_t*/ void *,
     119                                       const dtrace_pops_t *, void *, dtrace_provider_id_t *);
     120static void        (* dtrace_invalidate)(dtrace_provider_id_t);
     121static int         (* dtrace_unregister)(dtrace_provider_id_t);
     122/** @} */
    146123#endif
    147     /* .dtps_usermode        = */ NULL,
    148     /* .dtps_destroy         = */ supdrvDTracePOps_Destroy
    149 };
    150 
    151 
    152 static int supdrvVtgValidateString(const char *psz)
    153 {
    154     size_t off = 0;
    155     while (off < _4K)
    156     {
    157         char const ch = psz[off++];
    158         if (!ch)
    159             return VINF_SUCCESS;
    160         if (   !RTLocCIsAlNum(ch)
    161             && ch != ' '
    162             && ch != '_'
    163             && ch != '-'
    164             && ch != '('
    165             && ch != ')'
    166             && ch != ','
    167             && ch != '*'
    168             && ch != '&'
    169            )
    170         {
    171             /*RTAssertMsg2("off=%u '%s'\n",  off, psz);*/
    172             return VERR_SUPDRV_VTG_BAD_STRING;
    173         }
    174     }
    175     return VERR_SUPDRV_VTG_STRING_TOO_LONG;
    176 }
    177 
    178 /**
    179  * Validates the VTG data.
    180  *
    181  * @returns VBox status code.
    182  * @param   pVtgHdr             The VTG object header of the data to validate.
    183  * @param   cbVtgObj            The size of the VTG object.
    184  * @param   pbImage             The image base. For validating the probe
    185  *                              locations.
    186  * @param   cbImage             The image size to go with @a pbImage.
    187  */
    188 static int supdrvVtgValidate(PVTGOBJHDR pVtgHdr, size_t cbVtgObj, const uint8_t *pbImage, size_t cbImage)
    189 {
    190     uintptr_t   cbTmp;
    191     uintptr_t   offTmp;
    192     uintptr_t   i;
    193     int         rc;
    194     uint32_t    cProviders;
    195 
    196     if (!pbImage || !cbImage)
    197     {
    198         pbImage = NULL;
    199         cbImage = 0;
    200     }
    201 
    202 #define MY_VALIDATE_PTR(p, cb, cMin, cMax, cbUnit, rcBase) \
    203     do { \
    204         if (   (cb) >= cbVtgObj \
    205             || (uintptr_t)(p) - (uintptr_t)pVtgHdr > cbVtgObj - (cb) ) \
    206             return rcBase ## _PTR; \
    207         if ((cb) <  (cMin) * (cbUnit)) \
    208             return rcBase ## _TOO_FEW; \
    209         if ((cb) >= (cMax) * (cbUnit)) \
    210             return rcBase ## _TOO_MUCH; \
    211         if ((cb) / (cbUnit) * (cbUnit) != (cb)) \
    212             return rcBase ## _NOT_MULTIPLE; \
    213     } while (0)
    214 #define MY_WITHIN_IMAGE(p, rc) \
    215     do { \
    216         if (pbImage) \
    217         { \
    218             if ((uintptr_t)(p) - (uintptr_t)pbImage > cbImage) \
    219                 return (rc); \
    220         } \
    221         else if (!RT_VALID_PTR(p)) \
    222             return (rc); \
    223     } while (0)
    224 #define MY_VALIDATE_STR(offStrTab) \
    225     do { \
    226         if ((offStrTab) >= pVtgHdr->cbStrTab) \
    227             return VERR_SUPDRV_VTG_STRTAB_OFF; \
    228         rc = supdrvVtgValidateString(pVtgHdr->pachStrTab + (offStrTab)); \
    229         if (rc != VINF_SUCCESS) \
    230             return rc; \
    231     } while (0)
    232 #define MY_VALIDATE_ATTR(Attr) \
    233     do { \
    234         if ((Attr).u8Code    <= (uint8_t)kVTGStability_Invalid || (Attr).u8Code    >= (uint8_t)kVTGStability_End) \
    235             return VERR_SUPDRV_VTG_BAD_ATTR; \
    236         if ((Attr).u8Data    <= (uint8_t)kVTGStability_Invalid || (Attr).u8Data    >= (uint8_t)kVTGStability_End) \
    237             return VERR_SUPDRV_VTG_BAD_ATTR; \
    238         if ((Attr).u8DataDep <= (uint8_t)kVTGClass_Invalid     || (Attr).u8DataDep >= (uint8_t)kVTGClass_End) \
    239             return VERR_SUPDRV_VTG_BAD_ATTR; \
    240     } while (0)
    241 
    242     /*
    243      * The header.
    244      */
    245     if (memcmp(pVtgHdr->szMagic, VTGOBJHDR_MAGIC, sizeof(pVtgHdr->szMagic)))
    246         return VERR_SUPDRV_VTG_MAGIC;
    247     if (pVtgHdr->cBits != ARCH_BITS)
    248         return VERR_SUPDRV_VTG_BITS;
    249     if (pVtgHdr->u32Reserved0)
    250         return VERR_SUPDRV_VTG_BAD_HDR;
    251 
    252     MY_VALIDATE_PTR(pVtgHdr->paProviders,       pVtgHdr->cbProviders,    1,    16, sizeof(VTGDESCPROVIDER), VERR_SUPDRV_VTG_BAD_HDR);
    253     MY_VALIDATE_PTR(pVtgHdr->paProbes,          pVtgHdr->cbProbes,       1,  _32K, sizeof(VTGDESCPROBE),    VERR_SUPDRV_VTG_BAD_HDR);
    254     MY_VALIDATE_PTR(pVtgHdr->pafProbeEnabled,   pVtgHdr->cbProbeEnabled, 1,  _32K, sizeof(bool),            VERR_SUPDRV_VTG_BAD_HDR);
    255     MY_VALIDATE_PTR(pVtgHdr->pachStrTab,        pVtgHdr->cbStrTab,       4,   _1M, sizeof(char),            VERR_SUPDRV_VTG_BAD_HDR);
    256     MY_VALIDATE_PTR(pVtgHdr->paArgLists,        pVtgHdr->cbArgLists,     1,  _32K, sizeof(uint32_t),        VERR_SUPDRV_VTG_BAD_HDR);
    257 
    258     MY_WITHIN_IMAGE(pVtgHdr->paProbLocs,    VERR_SUPDRV_VTG_BAD_HDR_PTR);
    259     MY_WITHIN_IMAGE(pVtgHdr->paProbLocsEnd, VERR_SUPDRV_VTG_BAD_HDR_PTR);
    260     if ((uintptr_t)pVtgHdr->paProbLocs > (uintptr_t)pVtgHdr->paProbLocsEnd)
    261         return VERR_SUPDRV_VTG_BAD_HDR_PTR;
    262     cbTmp = (uintptr_t)pVtgHdr->paProbLocsEnd - (uintptr_t)pVtgHdr->paProbLocs;
    263     if (cbTmp < sizeof(VTGPROBELOC))
    264         return VERR_SUPDRV_VTG_BAD_HDR_TOO_FEW;
    265     if (cbTmp >= _128K * sizeof(VTGPROBELOC))
    266         return VERR_SUPDRV_VTG_BAD_HDR_TOO_MUCH;
    267     if (cbTmp / sizeof(VTGPROBELOC) * sizeof(VTGPROBELOC) != cbTmp)
    268         return VERR_SUPDRV_VTG_BAD_HDR_NOT_MULTIPLE;
    269 
    270     if (pVtgHdr->cbProbes / sizeof(VTGDESCPROBE) != pVtgHdr->cbProbeEnabled)
    271         return VERR_SUPDRV_VTG_BAD_HDR;
    272 
    273     /*
    274      * Validate the providers.
    275      */
    276     cProviders = i = pVtgHdr->cbProviders / sizeof(VTGDESCPROVIDER);
    277     while (i-- > 0)
    278     {
    279         MY_VALIDATE_STR(pVtgHdr->paProviders[i].offName);
    280         if (pVtgHdr->paProviders[i].iFirstProbe >= pVtgHdr->cbProbeEnabled)
    281             return VERR_SUPDRV_VTG_BAD_PROVIDER;
    282         if (pVtgHdr->paProviders[i].iFirstProbe + pVtgHdr->paProviders[i].cProbes > pVtgHdr->cbProbeEnabled)
    283             return VERR_SUPDRV_VTG_BAD_PROVIDER;
    284         MY_VALIDATE_ATTR(pVtgHdr->paProviders[i].AttrSelf);
    285         MY_VALIDATE_ATTR(pVtgHdr->paProviders[i].AttrModules);
    286         MY_VALIDATE_ATTR(pVtgHdr->paProviders[i].AttrFunctions);
    287         MY_VALIDATE_ATTR(pVtgHdr->paProviders[i].AttrNames);
    288         MY_VALIDATE_ATTR(pVtgHdr->paProviders[i].AttrArguments);
    289         if (pVtgHdr->paProviders[i].bReserved)
    290             return VERR_SUPDRV_VTG_BAD_PROVIDER;
    291     }
    292 
    293     /*
    294      * Validate probes.
    295      */
    296     i = pVtgHdr->cbProbes / sizeof(VTGDESCPROBE);
    297     while (i-- > 0)
    298     {
    299         PVTGDESCARGLIST pArgList;
    300         unsigned        iArg;
    301 
    302         MY_VALIDATE_STR(pVtgHdr->paProbes[i].offName);
    303         if (pVtgHdr->paProbes[i].offArgList >= pVtgHdr->cbArgLists)
    304             return VERR_SUPDRV_VTG_BAD_PROBE;
    305         if (pVtgHdr->paProbes[i].offArgList & 3)
    306             return VERR_SUPDRV_VTG_BAD_PROBE;
    307         if (pVtgHdr->paProbes[i].idxEnabled != i) /* The lists are parallel. */
    308             return VERR_SUPDRV_VTG_BAD_PROBE;
    309         if (pVtgHdr->paProbes[i].idxProvider >= cProviders)
    310             return VERR_SUPDRV_VTG_BAD_PROBE;
    311         if (  i - pVtgHdr->paProviders[pVtgHdr->paProbes[i].idxProvider].iFirstProbe
    312             >= pVtgHdr->paProviders[pVtgHdr->paProbes[i].idxProvider].cProbes)
    313             return VERR_SUPDRV_VTG_BAD_PROBE;
    314         if (pVtgHdr->paProbes[i].u32User)
    315             return VERR_SUPDRV_VTG_BAD_PROBE;
    316 
    317         /* The referenced argument list. */
    318         pArgList = (PVTGDESCARGLIST)((uintptr_t)pVtgHdr->paArgLists + pVtgHdr->paProbes[i].offArgList);
    319         if (pArgList->cArgs > 16)
    320             return VERR_SUPDRV_VTG_BAD_ARGLIST;
    321         if (   pArgList->abReserved[0]
    322             || pArgList->abReserved[1]
    323             || pArgList->abReserved[2])
    324             return VERR_SUPDRV_VTG_BAD_ARGLIST;
    325         iArg = pArgList->cArgs;
    326         while (iArg-- > 0)
    327         {
    328             MY_VALIDATE_STR(pArgList->aArgs[iArg].offType);
    329             MY_VALIDATE_STR(pArgList->aArgs[iArg].offName);
    330         }
    331     }
    332 
    333     /*
    334      * Check that pafProbeEnabled is all zero.
    335      */
    336     i = pVtgHdr->cbProbeEnabled;
    337     while (i-- > 0)
    338         if (pVtgHdr->pafProbeEnabled[0])
    339             return VERR_SUPDRV_VTG_BAD_PROBE_ENABLED;
    340 
    341     /*
    342      * Probe locations.
    343      */
    344     i = pVtgHdr->paProbLocsEnd - pVtgHdr->paProbLocs;
    345     while (i-- > 0)
    346     {
    347         if (pVtgHdr->paProbLocs[i].uLine >= _1G)
    348             return VERR_SUPDRV_VTG_BAD_PROBE_LOC;
    349         if (pVtgHdr->paProbLocs[i].fEnabled)
    350             return VERR_SUPDRV_VTG_BAD_PROBE_LOC;
    351         if (pVtgHdr->paProbLocs[i].idProbe != UINT32_MAX)
    352             return VERR_SUPDRV_VTG_BAD_PROBE_LOC;
    353         MY_WITHIN_IMAGE(pVtgHdr->paProbLocs[i].pszFunction, VERR_SUPDRV_VTG_BAD_PROBE_LOC);
    354         MY_WITHIN_IMAGE(pVtgHdr->paProbLocs[i].pszFile,     VERR_SUPDRV_VTG_BAD_PROBE_LOC);
    355         offTmp = (uintptr_t)pVtgHdr->paProbLocs[i].pbProbe - (uintptr_t)pVtgHdr->paProbes;
    356         if (offTmp >= pVtgHdr->cbProbes)
    357             return VERR_SUPDRV_VTG_BAD_PROBE_LOC;
    358         if (offTmp / sizeof(VTGDESCPROBE) * sizeof(VTGDESCPROBE) != offTmp)
    359             return VERR_SUPDRV_VTG_BAD_PROBE_LOC;
    360     }
    361 
    362     return VINF_SUCCESS;
    363 #undef MY_VALIDATE_STR
    364 #undef MY_VALIDATE_PTR
    365 #undef MY_WITHIN_IMAGE
    366 }
     124
     125
     126/*
     127 *
     128 * Helpers for handling VTG structures.
     129 * Helpers for handling VTG structures.
     130 * Helpers for handling VTG structures.
     131 *
     132 */
     133
    367134
    368135
     
    373140 * @param   pVtgAttr            The VTG attribute descriptor (src).
    374141 */
    375 static void supdrvVtgConvAttr(dtrace_attribute_t *pDtAttr, PCVTGDESCATTR pVtgAttr)
     142static void vboxDtVtgConvAttr(dtrace_attribute_t *pDtAttr, PCVTGDESCATTR pVtgAttr)
    376143{
    377144    pDtAttr->dtat_name  = pVtgAttr->u8Code - 1;
     
    387154 * @param   offStrTab           The string table offset.
    388155 */
    389 static const char *supdrvVtgGetString(PVTGOBJHDR pVtgHdr,  uint32_t offStrTab)
     156static const char *vboxDtVtgGetString(PVTGOBJHDR pVtgHdr,  uint32_t offStrTab)
    390157{
    391158    Assert(offStrTab < pVtgHdr->cbStrTab);
     
    394161
    395162
    396 /**
    397  * Frees the provider structure and associated resources.
    398  *
    399  * @param   pProv               The provider to free.
    400  */
    401 static void supdrvVtgFreeProvider(PSUPDRVDTPROVIDER pProv)
    402 {
    403     LOG_DTRACE(("Freeing DTrace provider '%s' / %p\n", pProv->szName, pProv->idDtProv));
    404     pProv->fZombie = true;
    405     pProv->pDesc   = NULL;
    406     pProv->pHdr    = NULL;
    407     RTMemFree(pProv);
    408 }
    409 
    410 
    411 /**
    412  * Deregisters a provider.
    413  *
    414  * If the provider is still busy, it will be put in the zombie list.
    415  *
    416  * @param   pDevExt             The device extension.
    417  * @param   pProv               The provider.
    418  *
    419  * @remarks The caller owns mtxDTrace.
    420  */
    421 static void supdrvVtgDeregister(PSUPDRVDEVEXT pDevExt, PSUPDRVDTPROVIDER pProv)
    422 {
    423     int rc;
    424 
    425     dtrace_invalidate(pProv->idDtProv);
    426     rc = dtrace_unregister(pProv->idDtProv);
    427     if (!rc)
    428     {
    429         supdrvVtgFreeProvider(pProv);
    430         return;
    431     }
    432 
    433     pProv->fZombie = true;
    434     RTListAppend(&pDevExt->DtProviderZombieList, &pProv->ListEntry);
    435     LOG_DTRACE(("Invalidate DTrace provider '%s' / %p and put it on the zombie list\n", pProv->szName, pProv->idDtProv));
    436 }
    437 
    438 
    439 /**
    440  * Processes the zombie list.
    441  *
    442  * @param   pDevExt             The device extension.
    443  */
    444 static void supdrvVtgProcessZombies(PSUPDRVDEVEXT pDevExt)
    445 {
    446     PSUPDRVDTPROVIDER pProv, pProvNext;
    447 
    448     RTSemFastMutexRequest(pDevExt->mtxDTrace);
    449     RTListForEachSafe(&pDevExt->DtProviderZombieList, pProv, pProvNext, SUPDRVDTPROVIDER, ListEntry)
    450     {
    451         int rc = dtrace_unregister(pProv->idDtProv);
    452         if (!rc)
    453         {
    454             RTListNodeRemove(&pProv->ListEntry);
    455             supdrvVtgFreeProvider(pProv);
    456         }
    457     }
    458     RTSemFastMutexRelease(pDevExt->mtxDTrace);
    459 }
    460 
    461 
    462 /**
    463  * Registers the VTG tracepoint providers of a driver.
    464  *
    465  * @returns VBox status code.
    466  * @param   pszName             The driver name.
    467  * @param   pVtgHdr             The VTG object header.
    468  * @param   pVtgObj             The size of the VTG object.
    469  * @param   pImage              The image if applicable.
    470  * @param   pSession            The session if applicable.
    471  * @param   pszModName          The module name.
    472  */
    473 static int supdrvVtgRegister(PSUPDRVDEVEXT pDevExt, PVTGOBJHDR pVtgHdr, size_t cbVtgObj, PSUPDRVLDRIMAGE pImage,
    474                              PSUPDRVSESSION pSession, const char *pszModName)
    475 {
    476     int                 rc;
    477     unsigned            i;
    478     PSUPDRVDTPROVIDER   pProv;
    479 
    480     /*
    481      * Validate input.
    482      */
    483     AssertPtrReturn(pDevExt, VERR_INVALID_POINTER);
    484     AssertPtrReturn(pVtgHdr, VERR_INVALID_POINTER);
    485     AssertPtrNullReturn(pImage, VERR_INVALID_POINTER);
    486     AssertPtrNullReturn(pSession, VERR_INVALID_POINTER);
    487     AssertPtrReturn(pszModName, VERR_INVALID_POINTER);
    488 
    489     if (pImage)
    490         rc = supdrvVtgValidate(pVtgHdr, cbVtgObj, (const uint8_t *)pImage->pvImage, pImage->cbImageBits);
    491     else
    492         rc = supdrvVtgValidate(pVtgHdr, cbVtgObj, NULL, 0);
    493     if (RT_FAILURE(rc))
    494         return rc;
    495 
    496     rc = RTSemFastMutexRequest(pDevExt->mtxDTrace);
    497     if (RT_FAILURE(rc))
    498         return rc;
    499     RTListForEach(&pDevExt->DtProviderList, pProv, SUPDRVDTPROVIDER, ListEntry)
    500     {
    501         if (pProv->pHdr == pVtgHdr)
    502         {
    503             rc = VERR_SUPDRV_VTG_ALREADY_REGISTERED;
    504             break;
    505         }
    506         if (   pProv->pSession == pSession
    507             && pProv->pImage   == pImage)
    508         {
    509             rc = VERR_SUPDRV_VTG_ONLY_ONCE_PER_SESSION;
    510             break;
    511         }
    512     }
    513     RTSemFastMutexRelease(pDevExt->mtxDTrace);
    514     if (RT_FAILURE(rc))
    515         return rc;
    516 
    517     /*
    518      * Register the providers.
    519      */
    520     i = pVtgHdr->cbProviders / sizeof(VTGDESCPROVIDER);
    521     while (i-- > 0)
    522     {
    523         PVTGDESCPROVIDER pDesc   = &pVtgHdr->paProviders[i];
    524         const char      *pszName = supdrvVtgGetString(pVtgHdr, pDesc->offName);
    525         size_t const     cchName = strlen(pszName);
    526         pProv = (PSUPDRVDTPROVIDER)RTMemAllocZ(RT_OFFSETOF(SUPDRVDTPROVIDER, szName[cchName + 1]));
    527         if (pProv)
    528         {
    529             pProv->pDesc            = pDesc;
    530             pProv->pHdr             = pVtgHdr;
    531             pProv->pImage           = pImage;
    532             pProv->pSession         = pSession;
    533             pProv->pszModName       = pszModName;
    534             pProv->idDtProv         = 0;
    535             pProv->cProvidedProbes  = 0;
    536             pProv->fZombie          = false;
    537             memcpy(pProv->szName, pszName, cchName + 1);
    538             supdrvVtgConvAttr(&pProv->DtAttrs.dtpa_provider, &pDesc->AttrSelf);
    539             supdrvVtgConvAttr(&pProv->DtAttrs.dtpa_mod,      &pDesc->AttrModules);
    540             supdrvVtgConvAttr(&pProv->DtAttrs.dtpa_func,     &pDesc->AttrFunctions);
    541             supdrvVtgConvAttr(&pProv->DtAttrs.dtpa_name,     &pDesc->AttrNames);
    542             supdrvVtgConvAttr(&pProv->DtAttrs.dtpa_args,     &pDesc->AttrArguments);
    543 
    544             rc = dtrace_register(pProv->szName,
    545                                  &pProv->DtAttrs,
    546                                  DTRACE_PRIV_KERNEL,
    547                                  NULL /* cred */,
    548                                  &g_SupDrvDTraceProvOps,
    549                                  pProv,
    550                                  &pProv->idDtProv);
    551             if (!rc)
    552             {
    553                 rc = RTSemFastMutexRequest(pDevExt->mtxDTrace);
    554                 if (RT_SUCCESS(rc))
    555                 {
    556                     RTListAppend(&pDevExt->DtProviderList, &pProv->ListEntry);
    557                     RTSemFastMutexRelease(pDevExt->mtxDTrace);
    558                     LOG_DTRACE(("Registered DTrace provider '%s' in '%s' -> %p\n", pProv->szName, pszModName, pProv->idDtProv));
    559                 }
    560                 else
    561                     dtrace_unregister(pProv->idDtProv);
    562             }
    563             else
    564                 rc = RTErrConvertFromErrno(rc);
    565         }
    566         else
    567             rc = VERR_NO_MEMORY;
    568 
    569         if (RT_FAILURE(rc))
    570         {
    571             PSUPDRVDTPROVIDER   pProvNext;
    572             supdrvVtgFreeProvider(pProv);
    573 
    574             RTSemFastMutexRequest(pDevExt->mtxDTrace);
    575             RTListForEachReverseSafe(&pDevExt->DtProviderList, pProv, pProvNext, SUPDRVDTPROVIDER, ListEntry)
    576             {
    577                 if (pProv->pHdr == pVtgHdr)
    578                 {
    579                     RTListNodeRemove(&pProv->ListEntry);
    580                     supdrvVtgDeregister(pDevExt, pProv);
    581                 }
    582             }
    583             RTSemFastMutexRelease(pDevExt->mtxDTrace);
    584             return rc;
    585         }
    586     }
    587 
    588     return VINF_SUCCESS;
    589 }
    590 
    591 
    592 /**
    593  * Registers the VTG tracepoint providers of a driver.
    594  *
    595  * @returns VBox status code.
    596  * @param   pSession            The support driver session handle.
    597  * @param   pVtgHdr             The VTG header.
    598  * @param   pszName             The driver name.
    599  */
    600 SUPR0DECL(int) SUPR0TracerRegisterDrv(PSUPDRVSESSION pSession, PVTGOBJHDR pVtgHdr, const char *pszName)
    601 {
    602     int rc;
    603 
    604     AssertReturn(SUP_IS_SESSION_VALID(pSession), VERR_INVALID_PARAMETER);
    605     AssertPtrReturn(pszName, VERR_INVALID_POINTER);
    606     AssertPtrReturn(pVtgHdr, VERR_INVALID_POINTER);
    607     AssertReturn(pSession->R0Process == NIL_RTR0PROCESS, VERR_INVALID_PARAMETER);
    608 
    609     rc = supdrvVtgRegister(pSession->pDevExt, pVtgHdr, _1M, NULL /*pImage*/, pSession, pszName);
    610 
    611     /*
    612      * Try unregister zombies while we have a chance.
    613      */
    614     supdrvVtgProcessZombies(pSession->pDevExt);
    615 
    616     return rc;
    617 }
    618 
    619 
    620 /**
    621  * Deregister the VTG tracepoint providers of a driver.
    622  *
    623  * @param   pSession            The support driver session handle.
    624  * @param   pVtgHdr             The VTG header.
    625  */
    626 SUPR0DECL(void) SUPR0TracerDeregisterDrv(PSUPDRVSESSION pSession)
    627 {
    628     PSUPDRVDTPROVIDER pProv, pProvNext;
    629     PSUPDRVDEVEXT     pDevExt;
    630     AssertReturnVoid(SUP_IS_SESSION_VALID(pSession));
    631     AssertReturnVoid(pSession->R0Process == NIL_RTR0PROCESS);
    632 
    633     pDevExt = pSession->pDevExt;
    634 
    635     /*
    636      * Search for providers belonging to this driver session.
    637      */
    638     RTSemFastMutexRequest(pDevExt->mtxDTrace);
    639     RTListForEachSafe(&pDevExt->DtProviderList, pProv, pProvNext, SUPDRVDTPROVIDER, ListEntry)
    640     {
    641         if (pProv->pSession == pSession)
    642         {
    643             RTListNodeRemove(&pProv->ListEntry);
    644             supdrvVtgDeregister(pDevExt, pProv);
    645         }
    646     }
    647     RTSemFastMutexRelease(pDevExt->mtxDTrace);
    648 
    649     /*
    650      * Try unregister zombies while we have a chance.
    651      */
    652     supdrvVtgProcessZombies(pDevExt);
    653 }
    654 
    655 
    656 /**
    657  * Registers the VTG tracepoint providers of a module loaded by
    658  * the support driver.
    659  *
    660  * This should be called from the ModuleInit code.
    661  *
    662  * @returns VBox status code.
    663  * @param   hMod                The module handle.
    664  * @param   pVtgHdr             The VTG header.
    665  */
    666 SUPR0DECL(int) SUPR0TracerRegisterModule(void *hMod, PVTGOBJHDR pVtgHdr)
    667 {
    668     PSUPDRVLDRIMAGE pImage = (PSUPDRVLDRIMAGE)hMod;
    669     PSUPDRVDEVEXT   pDevExt;
    670     uintptr_t       cbVtgObj;
    671     int             rc;
    672 
    673     /*
    674      * Validate input and context.
    675      */
    676     AssertPtrReturn(pImage,  VERR_INVALID_HANDLE);
    677     AssertPtrReturn(pVtgHdr, VERR_INVALID_POINTER);
    678 
    679     pDevExt = pImage->pDevExt;
    680     AssertPtrReturn(pDevExt, VERR_INVALID_POINTER);
    681     AssertReturn(pDevExt->pLdrInitImage  == pImage, VERR_WRONG_ORDER);
    682     AssertReturn(pDevExt->hLdrInitThread == RTThreadNativeSelf(), VERR_WRONG_ORDER);
    683 
    684     /*
    685      * Calculate the max VTG object size and hand it over to the common code.
    686      */
    687     cbVtgObj = (uintptr_t)pVtgHdr - (uintptr_t)pImage->pvImage;
    688     AssertMsgReturn(cbVtgObj /*off*/ < pImage->cbImageBits,
    689                     ("pVtgHdr=%p offVtgObj=%p cbImageBits=%p\n", pVtgHdr, cbVtgObj, pImage->cbImageBits),
    690                     VERR_INVALID_PARAMETER);
    691     cbVtgObj = pImage->cbImageBits - cbVtgObj;
    692 
    693     rc = supdrvVtgRegister(pDevExt, pVtgHdr, cbVtgObj, pImage, NULL, pImage->szName);
    694 
    695     /*
    696      * Try unregister zombies while we have a chance.
    697      */
    698     supdrvVtgProcessZombies(pDevExt);
    699 
    700     return rc;
    701 }
    702 
    703 
    704 /**
    705  * Module unloading hook, called after execution in the module have ceased.
    706  *
    707  * @param   pDevExt             The device extension structure.
    708  * @param   pImage              The image being unloaded.
    709  */
    710 void VBOXCALL supdrvVtgModuleUnloading(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage)
    711 {
    712     PSUPDRVDTPROVIDER pProv, pProvNext;
    713 
    714     /*
    715      * Unregister all providers belonging to this image.
    716      */
    717     RTSemFastMutexRequest(pDevExt->mtxDTrace);
    718     RTListForEachSafe(&pDevExt->DtProviderList, pProv, pProvNext, SUPDRVDTPROVIDER, ListEntry)
    719     {
    720         if (pProv->pImage == pImage)
    721         {
    722             RTListNodeRemove(&pProv->ListEntry);
    723             supdrvVtgDeregister(pDevExt, pProv);
    724         }
    725     }
    726     RTSemFastMutexRelease(pDevExt->mtxDTrace);
    727 
    728     /*
    729      * Try unregister zombies while we have a chance.
    730      */
    731     supdrvVtgProcessZombies(pDevExt);
    732 }
    733 
    734 
    735 /**
    736  * Early module initialization hook.
    737  *
    738  * @returns VBox status code.
    739  * @param   pDevExt             The device extension structure.
    740  * @param   pFireProbeEntry     Pointer to the SUPR0TracerFireProbe entry.
    741  */
    742 int VBOXCALL supdrvVtgInit(PSUPDRVDEVEXT pDevExt, PSUPFUNC pFireProbeEntry)
    743 {
    744     Assert(!strcmp(pFireProbeEntry->szName, "SUPR0TracerFireProbe"));
    745 
    746     /*
    747      * Register a provider for this module.
    748      */
    749     int rc = RTSemFastMutexCreate(&pDevExt->mtxDTrace);
    750     if (RT_SUCCESS(rc))
    751     {
    752 #ifdef RT_OS_SOLARIS
    753         pFireProbeEntry->pfn = (void *)(uintptr_t)dtrace_probe;
    754 #endif
    755         RTListInit(&pDevExt->DtProviderList);
    756         RTListInit(&pDevExt->DtProviderZombieList);
    757         rc = supdrvVtgRegister(pDevExt, &g_VTGObjHeader, _1M, NULL /*pImage*/, NULL /*pSession*/, "vboxdrv");
    758         if (RT_SUCCESS(rc))
    759             return rc;
    760         RTSemFastMutexDestroy(pDevExt->mtxDTrace);
    761     }
    762     pDevExt->mtxDTrace = NIL_RTSEMFASTMUTEX;
    763     return rc;
    764 }
    765 
    766 
    767 /**
    768  * Late module termination hook.
    769  *
    770  * @returns VBox status code.
    771  * @param   pDevExt             The device extension structure.
    772  */
    773 void VBOXCALL supdrvVtgTerm(PSUPDRVDEVEXT pDevExt)
    774 {
    775     PSUPDRVDTPROVIDER pProv, pProvNext;
    776     uint32_t i;
    777     LOG_DTRACE(("supdrvVtgTerm\n"));
    778 
    779     /*
    780      * Unregister all probes (there should only be one).
    781      */
    782     RTSemFastMutexRequest(pDevExt->mtxDTrace);
    783     RTListForEachSafe(&pDevExt->DtProviderList, pProv, pProvNext, SUPDRVDTPROVIDER, ListEntry)
    784     {
    785         RTListNodeRemove(&pProv->ListEntry);
    786         supdrvVtgDeregister(pDevExt, pProv);
    787     }
    788     RTSemFastMutexRelease(pDevExt->mtxDTrace);
    789 
    790     /*
    791      * Try unregister zombies now, sleep on busy ones.
    792      */
    793     for (i = 0; ; i++)
    794     {
    795         bool fEmpty;
    796 
    797         RTSemFastMutexRequest(pDevExt->mtxDTrace);
    798         RTListForEachSafe(&pDevExt->DtProviderZombieList, pProv, pProvNext, SUPDRVDTPROVIDER, ListEntry)
    799         {
    800             int rc;
    801             LOG_DTRACE(("supdrvVtgTerm: Attemting to unregister '%s' / %p...\n", pProv->szName, pProv->idDtProv));
    802             rc = dtrace_unregister(pProv->idDtProv);
    803             if (!rc)
    804             {
    805                 RTListNodeRemove(&pProv->ListEntry);
    806                 supdrvVtgFreeProvider(pProv);
    807             }
    808             else if (!(i & 0xf))
    809                 SUPR0Printf("supdrvVtgTerm: Waiting on busy provider '%s' / %p (rc=%d)\n", pProv->szName, pProv->idDtProv, rc);
    810             else
    811                 LOG_DTRACE(("supdrvVtgTerm: Failed to unregister provider '%s' / %p - rc=%d\n", pProv->szName, pProv->idDtProv, rc));
    812         }
    813 
    814         fEmpty = RTListIsEmpty(&pDevExt->DtProviderZombieList);
    815         RTSemFastMutexRelease(pDevExt->mtxDTrace);
    816         if (fEmpty)
    817             break;
    818 
    819         /* Delay...*/
    820         RTThreadSleep(1000);
    821     }
    822 
    823     RTSemFastMutexDestroy(pDevExt->mtxDTrace);
    824     pDevExt->mtxDTrace = NIL_RTSEMFASTMUTEX;
    825     LOG_DTRACE(("supdrvVtgTerm: Done\n"));
    826 }
     163
     164/*
     165 *
     166 * DTrace Provider Interface.
     167 * DTrace Provider Interface.
     168 * DTrace Provider Interface.
     169 *
     170 */
    827171
    828172
     
    830174 * @callback_method_impl{dtrace_pops_t,dtps_provide}
    831175 */
    832 static void     supdrvDTracePOps_Provide(void *pvProv, const dtrace_probedesc_t *pDtProbeDesc)
    833 {
    834     PSUPDRVDTPROVIDER   pProv      = (PSUPDRVDTPROVIDER)pvProv;
    835     uint16_t            idxProv;
    836     PVTGPROBELOC        pProbeLoc;
    837     PVTGPROBELOC        pProbeLocEnd;
    838     char               *pszFnNmBuf;
    839     size_t const        cbFnNmBuf = _4K + _1K;
     176static void     supdrvDtPOps_Provide(void *pvProv, const dtrace_probedesc_t *pDtProbeDesc)
     177{
     178    PSUPDRVVDTPROVIDERCORE  pProv        = (PSUPDRVVDTPROVIDERCORE)pvProv;
     179    PVTGPROBELOC            pProbeLoc    = pProv->pHdr->paProbLocs;
     180    PVTGPROBELOC            pProbeLocEnd = pProv->pHdr->paProbLocsEnd;
     181    dtrace_provider_id_t    idProvider   = pProv->TracerData.DTrace.idProvider;
     182    size_t const            cbFnNmBuf    = _4K + _1K;
     183    char                   *pszFnNmBuf;
     184    uint16_t                idxProv;
    840185
    841186    if (pDtProbeDesc)
    842187        return;  /* We don't generate probes, so never mind these requests. */
    843188
    844     if (pProv->fZombie)
     189    if (pProv->TracerData.DTrace.fZombie)
    845190        return;
    846191
    847     if (pProv->cProvidedProbes >= pProv->pDesc->cProbes)
     192    if (pProv->TracerData.DTrace.cProvidedProbes >= pProbeLocEnd - pProbeLoc)
    848193        return;
    849194
     
    859204      */
    860205     idxProv      = (uint16_t)(&pProv->pHdr->paProviders[0] - pProv->pDesc);
    861      pProbeLoc    = pProv->pHdr->paProbLocs;
    862      pProbeLocEnd = pProv->pHdr->paProbLocsEnd;
    863206     while ((uintptr_t)pProbeLoc < (uintptr_t)pProbeLocEnd)
    864207     {
     
    871214                brave/stupid enough to use function pointer returns without
    872215                typedef'ing properly them. */
    873              const char *pszPrbName = supdrvVtgGetString(pProv->pHdr, pProbeDesc->offName);
     216             const char *pszPrbName = vboxDtVtgGetString(pProv->pHdr, pProbeDesc->offName);
    874217             const char *pszFunc    = pProbeLoc->pszFunction;
    875218             const char *psz        = strchr(pProbeLoc->pszFunction, '(');
     
    901244                multiple location entries with the same probe ID. (lazy bird) */
    902245             Assert(pProbeLoc->idProbe == UINT32_MAX);
    903              if (dtrace_probe_lookup(pProv->idDtProv, pProv->pszModName, pszFnNmBuf, pszPrbName) != DTRACE_IDNONE)
     246             if (dtrace_probe_lookup(idProvider, pProv->pszModName, pszFnNmBuf, pszPrbName) != DTRACE_IDNONE)
    904247             {
    905248                 RTStrPrintf(pszFnNmBuf+cch, cbFnNmBuf - cch, "-%u",  pProbeLoc->uLine);
    906                  if (dtrace_probe_lookup(pProv->idDtProv, pProv->pszModName, pszFnNmBuf, pszPrbName) != DTRACE_IDNONE)
     249                 if (dtrace_probe_lookup(idProvider, pProv->pszModName, pszFnNmBuf, pszPrbName) != DTRACE_IDNONE)
    907250                 {
    908251                     unsigned iOrd = 2;
     
    910253                     {
    911254                         RTStrPrintf(pszFnNmBuf+cch, cbFnNmBuf - cch, "-%u-%u",  pProbeLoc->uLine, iOrd);
    912                          if (dtrace_probe_lookup(pProv->idDtProv, pProv->pszModName, pszFnNmBuf, pszPrbName) == DTRACE_IDNONE)
     255                         if (dtrace_probe_lookup(idProvider, pProv->pszModName, pszFnNmBuf, pszPrbName) == DTRACE_IDNONE)
    913256                             break;
    914257                         iOrd++;
     
    916259                     if (iOrd >= 128)
    917260                     {
    918                          LogRel(("VBoxDrv: More than 128 duplicate probe location instances in file %s at line %u, function %s [%s], probe %s\n",
    919                                  pProbeLoc->pszFile, pProbeLoc->uLine, pProbeLoc->pszFunction, pszFnNmBuf, pszPrbName));
     261                         LogRel(("VBoxDrv: More than 128 duplicate probe location instances %s at line %u in function %s [%s], probe %s\n",
     262                                 pProbeLoc->uLine, pProbeLoc->pszFunction, pszFnNmBuf, pszPrbName));
    920263                         continue;
    921264                     }
     
    925268             /* Create the probe. */
    926269             AssertCompile(sizeof(pProbeLoc->idProbe) == sizeof(dtrace_id_t));
    927              pProbeLoc->idProbe = dtrace_probe_create(pProv->idDtProv, pProv->pszModName, pszFnNmBuf, pszPrbName,
    928                                                       0 /*aframes*/, pProbeLoc);
    929              pProv->cProvidedProbes++;
     270             pProbeLoc->idProbe = dtrace_probe_create(idProvider, pProv->pszModName, pszFnNmBuf, pszPrbName,
     271                                                      1 /*aframes*/, pProbeLoc);
     272             pProv->TracerData.DTrace.cProvidedProbes++;
    930273         }
    931274
     
    940283 * @callback_method_impl{dtrace_pops_t,dtps_enable}
    941284 */
    942 static int      supdrvDTracePOps_Enable(void *pvProv, dtrace_id_t idProbe, void *pvProbe)
    943 {
    944     PSUPDRVDTPROVIDER   pProv      = (PSUPDRVDTPROVIDER)pvProv;
    945     if (!pProv->fZombie)
     285static int      supdrvDtPOps_Enable(void *pvProv, dtrace_id_t idProbe, void *pvProbe)
     286{
     287    PSUPDRVVDTPROVIDERCORE  pProv  = (PSUPDRVVDTPROVIDERCORE)pvProv;
     288    if (!pProv->TracerData.DTrace.fZombie)
    946289    {
    947290        PVTGPROBELOC    pProbeLoc  = (PVTGPROBELOC)pvProbe;
     
    963306 * @callback_method_impl{dtrace_pops_t,dtps_disable}
    964307 */
    965 static void     supdrvDTracePOps_Disable(void *pvProv, dtrace_id_t idProbe, void *pvProbe)
    966 {
    967     PSUPDRVDTPROVIDER   pProv      = (PSUPDRVDTPROVIDER)pvProv;
    968     if (!pProv->fZombie)
     308static void     supdrvDtPOps_Disable(void *pvProv, dtrace_id_t idProbe, void *pvProbe)
     309{
     310    PSUPDRVVDTPROVIDERCORE  pProv  = (PSUPDRVVDTPROVIDERCORE)pvProv;
     311    if (!pProv->TracerData.DTrace.fZombie)
    969312    {
    970313        PVTGPROBELOC    pProbeLoc  = (PVTGPROBELOC)pvProbe;
     
    984327 * @callback_method_impl{dtrace_pops_t,dtps_getargdesc}
    985328 */
    986 static void     supdrvDTracePOps_GetArgDesc(void *pvProv, dtrace_id_t idProbe, void *pvProbe,
    987                                             dtrace_argdesc_t *pArgDesc)
    988 {
    989     PSUPDRVDTPROVIDER   pProv      = (PSUPDRVDTPROVIDER)pvProv;
    990     unsigned            uArg       = pArgDesc->dtargd_ndx;
    991 
    992     if (!pProv->fZombie)
     329static void     supdrvDtPOps_GetArgDesc(void *pvProv, dtrace_id_t idProbe, void *pvProbe,
     330                                        dtrace_argdesc_t *pArgDesc)
     331{
     332    PSUPDRVVDTPROVIDERCORE  pProv  = (PSUPDRVVDTPROVIDERCORE)pvProv;
     333    unsigned                uArg   = pArgDesc->dtargd_ndx;
     334
     335    if (!pProv->TracerData.DTrace.fZombie)
    993336    {
    994337        PVTGPROBELOC    pProbeLoc  = (PVTGPROBELOC)pvProbe;
     
    999342        if (pArgList->cArgs > uArg)
    1000343        {
    1001             const char *pszType = supdrvVtgGetString(pProv->pHdr, pArgList->aArgs[uArg].offType);
     344            const char *pszType = vboxDtVtgGetString(pProv->pHdr, pArgList->aArgs[uArg].offType);
    1002345            size_t      cchType = strlen(pszType);
    1003346            if (cchType < sizeof(pArgDesc->dtargd_native))
     
    1014357
    1015358
    1016 #ifdef RT_OS_SOLARIS
    1017 
    1018 # ifdef __cplusplus
    1019 extern "C"
    1020 #endif
    1021 uint64_t dtrace_getarg(int iArg, int cFrames);
    1022 
    1023 /**
    1024  * @callback_method_impl{dtrace_pops_t,dtps_getargval}
    1025  */
    1026 static uint64_t supdrvDTracePOps_GetArgVal(void *pvProv, dtrace_id_t idProbe, void *pvProbe,
    1027                                            int iArg, int cFrames)
    1028 {
    1029     /* dtrace_getarg on AMD64 has a different opinion about how to use the
    1030        cFrames argument than dtrace_caller() and/or dtrace_getpcstack(), at
    1031        least when the probe is fired by dtrace_probe() the way we do.
    1032 
    1033        Setting aframes to 1 when calling dtrace_probe_create gives me the right
    1034        arguments, but the wrong 'caller'.  Since I cannot do anything about
    1035        'caller', the only solution is this hack.
    1036 
    1037        Not sure why the Solaris guys hasn't seen this issue before, but maybe
    1038        there isn't anyone using the default argument getter path for ring-0
    1039        dtrace_probe() calls, SDT surely isn't.
    1040 
    1041        WARNING! This code is subject to dtrace_getarg interface unstability! */
    1042     /** @todo File a solaris bug on dtrace_probe() + dtrace_getarg(). */
    1043     return dtrace_getarg(iArg, cFrames + 1);
    1044 }
    1045 
    1046 #endif /* RT_OS_SOLARIS */
     359/**
     360 * @callback_method_impl{dtrace_pops_t,dtps_getargval}
     361 * 
     362 * 
     363 * We just cook our own stuff here, using a stack marker for finding the
     364 * required information.  That's more reliable than subjecting oneself to the
     365 * solaris bugs and 32-bit apple peculiarities.
     366 * 
     367 * 
     368 * @remarks Solaris Bug
     369 * 
     370 * dtrace_getarg on AMD64 has a different opinion about how to use the cFrames
     371 * argument than dtrace_caller() and/or dtrace_getpcstack(), at least when the
     372 * probe is fired by dtrace_probe() the way we do.
     373 *
     374 * Setting aframes to 1 when calling dtrace_probe_create gives me the right
     375 * arguments, but the wrong 'caller'.  Since I cannot do anything about
     376 * 'caller', the only solution is this hack.
     377 *
     378 * Not sure why the  Solaris guys hasn't seen this issue before, but maybe there
     379 * isn't anyone using the default argument getter path for ring-0 dtrace_probe()
     380 * calls, SDT surely isn't.
     381 *
     382 * @todo File a solaris bug on dtrace_probe() + dtrace_getarg().
     383 * 
     384 * 
     385 * @remarks 32-bit XNU (Apple)
     386 * 
     387 * The dtrace_probe arguments are 64-bit unsigned integers instead of uintptr_t,
     388 * so we need to make an extra call.
     389 * 
     390 */
     391static uint64_t supdrvDtPOps_GetArgVal(void *pvProv, dtrace_id_t idProbe, void *pvProbe,
     392                                       int iArg, int cFrames)
     393{
     394    AssertReturn(iArg >= 5, UINT64_MAX);
     395
     396    /* Locate the caller of probe_dtrace, . */
     397    int volatile        iDummy = 1; /* use this to get the stack address. */
     398    PSUPDRVDTSTACKDATA  pData = (PSUPDRVDTSTACKDATA)(  ((uintptr_t)&iDummy + SUPDRVDT_STACK_DATA_ALIGN - 1)
     399                                                     & ~(uintptr_t)(SUPDRVDT_STACK_DATA_ALIGN - 1));
     400    for (;;)
     401    {
     402        if (   pData->u32Magic1 == SUPDRVDT_STACK_DATA_MAGIC1
     403            && pData->u32Magic2 == SUPDRVDT_STACK_DATA_MAGIC2
     404            && pData->pSelf     == pData)
     405            break;
     406        pData = (PSUPDRVDTSTACKDATA)((uintptr_t)pData + SUPDRVDT_STACK_DATA_ALIGN);
     407    }
     408
     409    /* Get the stack data. */
     410    return pData->pauStackArgs[iArg - 5];
     411}
    1047412
    1048413
     
    1050415 * @callback_method_impl{dtrace_pops_t,dtps_destroy}
    1051416 */
    1052 static void    supdrvDTracePOps_Destroy(void *pvProv, dtrace_id_t idProbe, void *pvProbe)
    1053 {
    1054     PSUPDRVDTPROVIDER   pProv      = (PSUPDRVDTPROVIDER)pvProv;
    1055     if (!pProv->fZombie)
     417static void    supdrvDtPOps_Destroy(void *pvProv, dtrace_id_t idProbe, void *pvProbe)
     418{
     419    PSUPDRVVDTPROVIDERCORE  pProv  = (PSUPDRVVDTPROVIDERCORE)pvProv;
     420    if (!pProv->TracerData.DTrace.fZombie)
    1056421    {
    1057422        PVTGPROBELOC    pProbeLoc  = (PVTGPROBELOC)pvProbe;
     
    1060425        pProbeLoc->idProbe = UINT32_MAX;
    1061426    }
    1062     pProv->cProvidedProbes--;
    1063 }
    1064 
     427    pProv->TracerData.DTrace.cProvidedProbes--;
     428}
     429
     430
     431
     432/**
     433 * DTrace provider method table.
     434 */
     435static const dtrace_pops_t g_vboxDtVtgProvOps =
     436{
     437    /* .dtps_provide         = */ supdrvDtPOps_Provide,
     438    /* .dtps_provide_module  = */ NULL,
     439    /* .dtps_enable          = */ (FNPOPS_ENABLE *)supdrvDtPOps_Enable,
     440    /* .dtps_disable         = */ supdrvDtPOps_Disable,
     441    /* .dtps_suspend         = */ NULL,
     442    /* .dtps_resume          = */ NULL,
     443    /* .dtps_getargdesc      = */ supdrvDtPOps_GetArgDesc,
     444    /* .dtps_getargval       = */ supdrvDtPOps_GetArgVal,
     445    /* .dtps_usermode        = */ NULL,
     446    /* .dtps_destroy         = */ supdrvDtPOps_Destroy
     447};
     448
     449
     450
     451
     452/*
     453 *
     454 * Support Driver Tracer Interface.
     455 * Support Driver Tracer Interface.
     456 * Support Driver Tracer Interface.
     457 *
     458 */
     459
     460
     461
     462/**
     463 * interface_method_impl{SUPDRVTRACERREG,pfnProbeFireUser}
     464 */
     465static DECLCALLBACK(void) supdrvDtTOps_ProbeFireKernel(struct VTGPROBELOC *pVtgProbeLoc, uintptr_t uArg0, uintptr_t uArg1, uintptr_t uArg2,
     466                                                       uintptr_t uArg3, uintptr_t uArg4)
     467{
     468    SUPDRVDT_SETUP_STACK_DATA();
     469
     470    pStackData->pauStackArgs = &uArg4 + 1;
     471    dtrace_probe(pVtgProbeLoc->idProbe, uArg0, uArg1, uArg2, uArg3, uArg4);
     472
     473    SUPDRVDT_CLEAR_STACK_DATA();
     474}
     475
     476
     477/**
     478 * interface_method_impl{SUPDRVTRACERREG,pfnProbeFireUser}
     479 */
     480static DECLCALLBACK(void) supdrvDtTOps_ProbeFireUser(PCSUPDRVTRACERREG pThis, PSUPDRVSESSION pSession, PCSUPDRVTRACERUSRCTX pCtx)
     481{
     482    NOREF(pThis); NOREF(pSession); NOREF(pCtx);
     483    return;
     484}
     485
     486
     487/**
     488 * interface_method_impl{SUPDRVTRACERREG,pfnTracerOpen}
     489 */
     490static DECLCALLBACK(int) supdrvDtTOps_TracerOpen(PCSUPDRVTRACERREG pThis, PSUPDRVSESSION pSession, uint32_t uCookie,
     491                                                 uintptr_t uArg, uintptr_t *puSessionData)
     492{
     493    NOREF(pThis); NOREF(pSession); NOREF(uCookie); NOREF(uArg);
     494    *puSessionData = 0;
     495    return VERR_NOT_SUPPORTED;
     496}
     497
     498
     499/**
     500 * interface_method_impl{SUPDRVTRACERREG,pfnTracerClose}
     501 */
     502static DECLCALLBACK(int) supdrvDtTOps_TracerIoCtl(PCSUPDRVTRACERREG pThis, PSUPDRVSESSION pSession, uintptr_t uSessionData,
     503                                                  uintptr_t uCmd, uintptr_t uArg, int32_t *piRetVal)
     504{
     505    NOREF(pThis); NOREF(pSession); NOREF(uSessionData);
     506    NOREF(uCmd); NOREF(uArg); NOREF(piRetVal);
     507    return VERR_NOT_SUPPORTED;
     508}
     509
     510
     511/**
     512 * interface_method_impl{SUPDRVTRACERREG,pfnTracerClose}
     513 */
     514static DECLCALLBACK(void) supdrvDtTOps_TracerClose(PCSUPDRVTRACERREG pThis, PSUPDRVSESSION pSession, uintptr_t uSessionData)
     515{
     516    NOREF(pThis); NOREF(pSession); NOREF(uSessionData);
     517    return;
     518}
     519
     520
     521/**
     522 * interface_method_impl{SUPDRVTRACERREG,pfnProviderRegister}
     523 */
     524static DECLCALLBACK(int) supdrvDtTOps_ProviderRegister(PCSUPDRVTRACERREG pThis, PSUPDRVVDTPROVIDERCORE pCore)
     525{
     526    AssertReturn(pCore->TracerData.DTrace.idProvider == UINT32_MAX || pCore->TracerData.DTrace.idProvider == 0,
     527                 VERR_INTERNAL_ERROR_3);
     528
     529    PVTGDESCPROVIDER    pDesc = pCore->pDesc;
     530    dtrace_pattr_t      DtAttrs;
     531    vboxDtVtgConvAttr(&DtAttrs.dtpa_provider, &pDesc->AttrSelf);
     532    vboxDtVtgConvAttr(&DtAttrs.dtpa_mod,      &pDesc->AttrModules);
     533    vboxDtVtgConvAttr(&DtAttrs.dtpa_func,     &pDesc->AttrFunctions);
     534    vboxDtVtgConvAttr(&DtAttrs.dtpa_name,     &pDesc->AttrNames);
     535    vboxDtVtgConvAttr(&DtAttrs.dtpa_args,     &pDesc->AttrArguments);
     536
     537    dtrace_provider_id_t idProvider;
     538    int rc = dtrace_register(pCore->pszName,
     539                             &DtAttrs,
     540                             DTRACE_PRIV_KERNEL,
     541                             NULL /* cred */,
     542                             &g_vboxDtVtgProvOps,
     543                             pCore,
     544                             &idProvider);
     545    if (!rc)
     546    {
     547        Assert(idProvider != UINT32_MAX && idProvider != 0);
     548        pCore->TracerData.DTrace.idProvider = idProvider;
     549        Assert(pCore->TracerData.DTrace.idProvider == idProvider);
     550        rc = VINF_SUCCESS;
     551    }
     552    else
     553        rc = RTErrConvertFromErrno(rc);
     554
     555    return rc;
     556}
     557
     558
     559/**
     560 * interface_method_impl{SUPDRVTRACERREG,pfnProviderDeregister}
     561 */
     562static DECLCALLBACK(int) supdrvDtTOps_ProviderDeregister(PCSUPDRVTRACERREG pThis, PSUPDRVVDTPROVIDERCORE pCore)
     563{
     564    uintptr_t idProvider = pCore->TracerData.DTrace.idProvider;
     565    AssertReturn(idProvider != UINT32_MAX && idProvider != 0, VERR_INTERNAL_ERROR_4);
     566
     567    dtrace_invalidate(idProvider);
     568    int rc = dtrace_unregister(idProvider);
     569    if (!rc)
     570    {
     571        pCore->TracerData.DTrace.idProvider = UINT32_MAX;
     572        rc = VINF_SUCCESS;
     573    }
     574    else
     575    {
     576        AssertMsg(rc == EBUSY, ("%d\n", rc));
     577        pCore->TracerData.DTrace.fZombie = true;
     578        rc = VERR_TRY_AGAIN;
     579    }
     580
     581    return rc;
     582}
     583
     584
     585/**
     586 * interface_method_impl{SUPDRVTRACERREG,pfnProviderDeregisterZombie}
     587 */
     588static DECLCALLBACK(int) supdrvDtTOps_ProviderDeregisterZombie(PCSUPDRVTRACERREG pThis, PSUPDRVVDTPROVIDERCORE pCore)
     589{
     590    uintptr_t idProvider = pCore->TracerData.DTrace.idProvider;
     591    AssertReturn(idProvider != UINT32_MAX && idProvider != 0, VERR_INTERNAL_ERROR_4);
     592    Assert(pCore->TracerData.DTrace.fZombie);
     593
     594    int rc = dtrace_unregister(idProvider);
     595    if (!rc)
     596    {
     597        pCore->TracerData.DTrace.idProvider = UINT32_MAX;
     598        rc = VINF_SUCCESS;
     599    }
     600    else
     601    {
     602        AssertMsg(rc == EBUSY, ("%d\n", rc));
     603        rc = VERR_TRY_AGAIN;
     604    }
     605
     606    return rc;
     607}
     608
     609
     610
     611/**
     612 * The tracer registration record of the VBox DTrace implementation
     613 */
     614static SUPDRVTRACERREG g_supdrvDTraceReg =
     615{
     616    SUPDRVTRACERREG_MAGIC,
     617    SUPDRVTRACERREG_VERSION,
     618    supdrvDtTOps_ProbeFireKernel,
     619    supdrvDtTOps_ProbeFireUser,
     620    supdrvDtTOps_TracerOpen,
     621    supdrvDtTOps_TracerIoCtl,
     622    supdrvDtTOps_TracerClose,
     623    supdrvDtTOps_ProviderRegister,
     624    supdrvDtTOps_ProviderDeregister,
     625    supdrvDtTOps_ProviderDeregisterZombie,
     626    SUPDRVTRACERREG_MAGIC
     627};
     628
     629
     630
     631/**
     632 * Module initialization code.
     633 *
     634 * @param   hMod            Opque module handle.
     635 */
     636const SUPDRVTRACERREG * VBOXCALL supdrvDTraceInit(void)
     637{
     638#ifdef RT_OS_DARWIN
     639    /*
     640     * Resolve the kernel symbols we need.
     641     */
     642    RTDBGKRNLINFO hKrnlInfo;
     643    int rc = RTR0DbgKrnlInfoOpen(&hKrnlInfo, 0);
     644    if (RT_FAILURE(rc))
     645    {
     646        SUPR0Printf("supdrvDTraceInit: RTR0DbgKrnlInfoOpen failed with rc=%d.\n", rc);
     647        return NULL;
     648    }
     649
     650    static const struct
     651    {
     652        const char *pszName;
     653        PFNRT      *ppfn;
     654    } s_aDTraceFunctions[] =
     655    {   
     656        { "dtrace_probe",        (PFNRT*)&dtrace_probe        },
     657        { "dtrace_probe_create", (PFNRT*)&dtrace_probe_create },
     658        { "dtrace_probe_lookup", (PFNRT*)&dtrace_probe_lookup },
     659        { "dtrace_register",     (PFNRT*)&dtrace_register     },
     660        { "dtrace_invalidate",   (PFNRT*)&dtrace_invalidate   },
     661        { "dtrace_unregister",   (PFNRT*)&dtrace_unregister   },
     662    };
     663    for (unsigned i = 0; i < RT_ELEMENTS(s_aDTraceFunctions); i++)
     664    {
     665        rc = RTR0DbgKrnlInfoQuerySymbol(hKrnlInfo, NULL, s_aDTraceFunctions[i].pszName,
     666                                        (void **)s_aDTraceFunctions[i].ppfn);
     667        if (RT_FAILURE(rc))
     668        {
     669            SUPR0Printf("supdrvDTraceInit: Failed to resolved '%s' (rc=%Rrc, i=%u).\n", s_aDTraceFunctions[i].pszName, rc, i);
     670            break;
     671        }
     672    }
     673
     674    RTR0DbgKrnlInfoRelease(hKrnlInfo);
     675    if (RT_FAILURE(rc))
     676        return NULL;
     677#endif
     678
     679    return &g_supdrvDTraceReg;
     680}
     681
     682#ifndef VBOX_WITH_NATIVE_DTRACE_R0DRV
     683# error "VBOX_WITH_NATIVE_DTRACE_R0DRV is not defined as it should"
     684#endif
     685
  • trunk/src/VBox/HostDrivers/Support/SUPDrvInternal.h

    r40819 r40851  
    661661DECLASM(void)   supdrvTracerProbeFireStub(void);
    662662
     663#ifdef VBOX_WITH_NATIVE_DTRACE_R0DRV
     664const SUPDRVTRACERREG * VBOXCALL supdrvDTraceInit(void);
     665#endif
    663666
    664667RT_C_DECLS_END
  • trunk/src/VBox/HostDrivers/Support/SUPDrvTracer.cpp

    r40839 r40851  
    163163        if (   (cb) >= cbVtgObj \
    164164            || (uintptr_t)(p) - (uintptr_t)pVtgHdr > cbVtgObj - (cb) ) \
     165        { \
     166            SUPR0Printf("supdrvVtgValidate: " #rcBase "_TOO_PTR - p=%p cb=%#zx pVtgHdr=%p cbVtgHdr=%#zu line=%u %s\n", \
     167                        p, (size_t)(cb), pVtgHdr, cbVtgObj, __LINE__, #p); \
    165168            return rcBase ## _PTR; \
     169        } \
    166170        if ((cb) <  (cMin) * (cbUnit)) \
     171        { \
     172            SUPR0Printf("supdrvVtgValidate: " #rcBase "_TOO_FEW - cb=%#zx cMin=%#zx cbUnit=%#zx line=%u %s\n", \
     173                        (size_t)(cb), (size_t)(cMin), (size_t)cbUnit, __LINE__, #p); \
    167174            return rcBase ## _TOO_FEW; \
     175        } \
    168176        if ((cb) >= (cMax) * (cbUnit)) \
     177        { \
     178            SUPR0Printf("supdrvVtgValidate: " #rcBase "_TOO_MUCH - cb=%#zx cMax=%#zx cbUnit=%#zx line=%u %s\n", \
     179                        (size_t)(cb), (size_t)(cMax), (size_t)cbUnit, __LINE__, #p); \
    169180            return rcBase ## _TOO_MUCH; \
     181        } \
    170182        if ((cb) / (cbUnit) * (cbUnit) != (cb)) \
     183        { \
     184            SUPR0Printf("supdrvVtgValidate: " #rcBase "_NOT_MULTIPLE - cb=%#zx cbUnit=%#zx line=%u %s\n", \
     185                        (size_t)(cb), (size_t)cbUnit, __LINE__, #p); \
    171186            return rcBase ## _NOT_MULTIPLE; \
     187        } \
    172188    } while (0)
    173189#define MY_WITHIN_IMAGE(p, rc) \
     
    176192        { \
    177193            if ((uintptr_t)(p) - (uintptr_t)pbImage > cbImage) \
     194            { \
     195                SUPR0Printf("supdrvVtgValidate: " #rc " - p=%p pbImage=%p cbImage=%#zxline=%u %s\n", \
     196                            p, pbImage, cbImage, #p); \
    178197                return (rc); \
     198            } \
    179199        } \
    180200        else if (!RT_VALID_PTR(p)) \
     
    218238    MY_WITHIN_IMAGE(pVtgHdr->paProbLocsEnd, VERR_SUPDRV_VTG_BAD_HDR_PTR);
    219239    if ((uintptr_t)pVtgHdr->paProbLocs > (uintptr_t)pVtgHdr->paProbLocsEnd)
     240    {
     241        SUPR0Printf("supdrvVtgValidate: VERR_SUPDRV_VTG_BAD_HDR_PTR - paProbeLocs=%p > paProbLocsEnd=%p\n",
     242                    pVtgHdr->paProbLocs, pVtgHdr->paProbLocsEnd);
    220243        return VERR_SUPDRV_VTG_BAD_HDR_PTR;
     244    }
    221245    cbTmp = (uintptr_t)pVtgHdr->paProbLocsEnd - (uintptr_t)pVtgHdr->paProbLocs;
    222246    if (cbTmp < sizeof(VTGPROBELOC))
     247    {
     248        SUPR0Printf("supdrvVtgValidate: VERR_SUPDRV_VTG_BAD_HDR_TOO_FEW - cbTmp=%#zx paProbeLocs=%p paProbLocsEnd=%p\n",
     249                    cbTmp, pVtgHdr->paProbLocs, pVtgHdr->paProbLocsEnd);
    223250        return VERR_SUPDRV_VTG_BAD_HDR_TOO_FEW;
     251    }
    224252    if (cbTmp >= _128K * sizeof(VTGPROBELOC))
     253    {
     254        SUPR0Printf("supdrvVtgValidate: VERR_SUPDRV_VTG_BAD_HDR_TOO_MUCH - cbTmp=%#zx paProbeLocs=%p paProbLocsEnd=%p\n",
     255                    cbTmp, pVtgHdr->paProbLocs, pVtgHdr->paProbLocsEnd);
    225256        return VERR_SUPDRV_VTG_BAD_HDR_TOO_MUCH;
     257    }
    226258    if (cbTmp / sizeof(VTGPROBELOC) * sizeof(VTGPROBELOC) != cbTmp)
     259    {
     260        SUPR0Printf("supdrvVtgValidate: VERR_SUPDRV_VTG_BAD_HDR_NOT_MULTIPLE - cbTmp=%#zx cbUnit=%#zx paProbeLocs=%p paProbLocsEnd=%p\n",
     261                    cbTmp, sizeof(VTGPROBELOC), pVtgHdr->paProbLocs, pVtgHdr->paProbLocsEnd);
    227262        return VERR_SUPDRV_VTG_BAD_HDR_NOT_MULTIPLE;
     263    }
    228264
    229265    if (pVtgHdr->cbProbes / sizeof(VTGDESCPROBE) != pVtgHdr->cbProbeEnabled)
     266    {
     267        SUPR0Printf("supdrvVtgValidate: VERR_SUPDRV_VTG_BAD_HDR - cbProbeEnabled=%#zx cbProbes=%#zx\n",
     268                    pVtgHdr->cbProbeEnabled, pVtgHdr->cbProbes);
    230269        return VERR_SUPDRV_VTG_BAD_HDR;
     270    }
    231271
    232272    /*
     
    589629                {
    590630                    RTSemFastMutexRelease(pDevExt->mtxTracer);
     631                    LOG_TRACER(("Failed to register tracepoint provider '%s' in '%s' -> %Rrc\n",
     632                                pProv->szName, pszModName, rc));
    591633                    RTMemFree(pProv);
    592634                }
     
    635677    AssertPtrReturn(pVtgHdr, VERR_INVALID_POINTER);
    636678    AssertReturn(pSession->R0Process == NIL_RTR0PROCESS, VERR_INVALID_PARAMETER);
     679    LOG_TRACER(("SUPR0TracerRegisterDrv: pSession=%p pVtgHdr=%p pszName=%s\n", pSession, pVtgHdr, pszName));
    637680
    638681    rc = supdrvTracerRegisterVtgObj(pSession->pDevExt, pVtgHdr, _1M, NULL /*pImage*/, pSession, pszName);
     
    659702    AssertReturnVoid(SUP_IS_SESSION_VALID(pSession));
    660703    AssertReturnVoid(pSession->R0Process == NIL_RTR0PROCESS);
     704    LOG_TRACER(("SUPR0TracerDeregisterDrv: pSession=%p\n", pSession));
    661705
    662706    pDevExt = pSession->pDevExt;
     
    13171361{
    13181362    /*
    1319      * Register a provider for this module.
     1363     * Initialize the tracer.
    13201364     */
    13211365    int rc = RTSemFastMutexCreate(&pDevExt->mtxTracer);
     
    13281372        RTListInit(&pDevExt->TracerProviderZombieList);
    13291373
     1374#ifdef VBOX_WITH_NATIVE_DTRACE_R0DRV
     1375        pDevExt->pTracerOps = supdrvDTraceInit();
     1376#endif
     1377
     1378        /*
     1379         * Register the provider for this module, if compiled in.
     1380         */
    13301381#ifdef VBOX_WITH_DTRACE_R0DRV
    13311382        rc = supdrvTracerRegisterVtgObj(pDevExt, &g_VTGObjHeader, _1M, NULL /*pImage*/, NULL /*pSession*/, "vboxdrv");
    13321383        if (RT_SUCCESS(rc))
     1384            return rc;
     1385        SUPR0Printf("supdrvTracerInit: supdrvTracerRegisterVtgObj failed with rc=%d\n", rc);
     1386        RTSemFastMutexDestroy(pDevExt->mtxTracer);
     1387#else
     1388
     1389        return VINF_SUCCESS;
    13331390#endif
    1334             return rc;
    1335         RTSemFastMutexDestroy(pDevExt->mtxTracer);
    13361391    }
    13371392    pDevExt->mtxTracer = NIL_RTSEMFASTMUTEX;
  • trunk/src/bldprogs/VBoxTpG.cpp

    r40839 r40851  
    461461                    " %%endmacro\n"
    462462                    " [section VTGPrLc.Begin data align=64]\n"
    463                     /*"   times 24 db 0xcc\n"*/
     463                    /*"   times 16 db 0xcc\n"*/
    464464                    "VTG_GLOBAL g_aVTGPrLc, data\n"
    465465                    " [section VTGPrLc.Data  data align=4]\n"
    466466                    " [section VTGPrLc.End   data align=4]\n"
    467467                    "VTG_GLOBAL g_aVTGPrLc_End, data\n"
    468                     /*"   times 24 db 0xcc\n"*/
     468                    /*"   times 16 db 0xcc\n"*/
    469469                    " [section VTGObj   data align=32]\n"
    470470                    "\n"
     
    474474                    "  NAME(%%1):\n"
    475475                    " %%endmacro\n"
    476                     " [section .VTGPrLc.Start progbits alloc noexec write align=1]\n"
     476                    " [section .VTGPrLc.Begin progbits alloc noexec write align=4096]\n"
    477477                    "VTG_GLOBAL g_aVTGPrLc, data\n"
    478                     " [section .VTGPrLc progbits alloc noexec write align=1]\n"
    479                     " [section .VTGPrLc.End progbits alloc noexec write align=1]\n"
     478                    " [section .VTGPrLc       progbits alloc noexec write align=1]\n"
     479                    " [section .VTGPrLc.End   progbits alloc noexec write align=1]\n"
    480480                    "VTG_GLOBAL g_aVTGPrLc_End, data\n"
    481481                    " [section .VTGData progbits alloc noexec write align=4096]\n"
     
    489489                    "                ;0         1         2         3\n"
    490490                    "                ;012345678901234567890123456789012\n"
    491                     "    db          'VTG Object Header v1.1', 0, 0\n"
     491                    "    db          'VTG Object Header v1.2', 0, 0\n"
    492492                    "    dd          %u\n"
    493493                    "    dd          0\n"
注意: 瀏覽 TracChangeset 來幫助您使用更動檢視器

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette