Index: /trunk/include/VBox/sup.h
===================================================================
--- /trunk/include/VBox/sup.h	(revision 40980)
+++ /trunk/include/VBox/sup.h	(revision 40981)
@@ -1175,6 +1175,48 @@
 SUPR3DECL(int) SUPR3TracerIoCtl(uintptr_t uCmd, uintptr_t uArg, int32_t *piRetVal);
 
+/**
+ * Registers the user module with the tracer.
+ *
+ * @returns VBox status code.
+ * @param   hModNative          Native module handle.  Pass ~(uintptr_t)0 if not
+ *                              at hand.
+ * @param   pszModule           The module name.
+ * @param   pVtgHdr             The VTG header.
+ * @param   fFlags              See SUP_TRACER_UMOD_FLAGS_XXX
+ */
+SUPR3DECL(int) SUPR3TracerRegisterModule(uintptr_t hModNative, const char *pszModule, struct VTGOBJHDR *pVtgHdr, uint32_t fFlags);
+
+/**
+ * Deregisters the user module.
+ *
+ * @returns VBox status code.
+ * @param   pVtgHdr             The VTG header.
+ */
+SUPR3DECL(int) SUPR3TracerDeregisterModule(struct VTGOBJHDR *pVtgHdr);
+
+/**
+ * Fire the probe.
+ *
+ * @param   pVtgProbeLoc        The probe location record.
+ * @param   uArg0               Raw probe argument 0.
+ * @param   uArg1               Raw probe argument 1.
+ * @param   uArg2               Raw probe argument 2.
+ * @param   uArg3               Raw probe argument 3.
+ * @param   uArg4               Raw probe argument 4.
+ */
+SUPDECL(void)  SUPTracerFireProbe(struct VTGPROBELOC *pVtgProbeLoc, uintptr_t uArg0, uintptr_t uArg1, uintptr_t uArg2,
+                                  uintptr_t uArg3, uintptr_t uArg4);
 /** @} */
 #endif /* IN_RING3 */
+
+/** @name User mode module flags (SUPR3TracerRegisterModule & SUP_IOCTL_TRACER_UMOD_REG).
+ * @{ */
+/** Executable image. */
+#define SUP_TRACER_UMOD_FLAGS_EXE           UINT32_C(1)
+/** Shared library (DLL, DYLIB, SO, etc). */
+#define SUP_TRACER_UMOD_FLAGS_SHARED        UINT32_C(2)
+/** Image type mask. */
+#define SUP_TRACER_UMOD_FLAGS_TYPE_MASK     UINT32_C(3)
+/** @} */
 
 
@@ -1561,5 +1603,5 @@
 SUPR0DECL(void) SUPR0TracerDeregisterDrv(PSUPDRVSESSION pSession);
 SUPR0DECL(int)  SUPR0TracerRegisterModule(void *hMod, struct VTGOBJHDR *pVtgHdr);
-SUPR0DECL(void) SUPR0TracerFireProbe(uint32_t idProbe, uintptr_t uArg0, uintptr_t uArg1, uintptr_t uArg2,
+SUPR0DECL(void) SUPR0TracerFireProbe(struct VTGPROBELOC *pVtgProbeLoc, uintptr_t uArg0, uintptr_t uArg1, uintptr_t uArg2,
                                      uintptr_t uArg3, uintptr_t uArg4);
 /** @}  */
Index: /trunk/src/VBox/HostDrivers/Support/SUPDrv.c
===================================================================
--- /trunk/src/VBox/HostDrivers/Support/SUPDrv.c	(revision 40980)
+++ /trunk/src/VBox/HostDrivers/Support/SUPDrv.c	(revision 40981)
@@ -1789,4 +1789,26 @@
         }
 
+        case SUP_CTL_CODE_NO_SIZE(SUP_IOCTL_TRACER_UMOD_REG):
+        {
+            /* validate */
+            PSUPTRACERUMODREG pReq = (PSUPTRACERUMODREG)pReqHdr;
+            REQ_CHECK_SIZES(SUP_IOCTL_TRACER_UMOD_REG);
+
+            /* execute */
+            pReqHdr->rc = supdrvIOCtl_TracerUmodRegister(pDevExt, pSession, pReq->u.In.pVtgHdr, pReq->u.In.szName, pReq->u.In.fFlags);
+            return 0;
+        }
+
+        case SUP_CTL_CODE_NO_SIZE(SUP_IOCTL_TRACER_UMOD_DEREG):
+        {
+            /* validate */
+            PSUPTRACERUMODDEREG pReq = (PSUPTRACERUMODDEREG)pReqHdr;
+            REQ_CHECK_SIZES(SUP_IOCTL_TRACER_UMOD_DEREG);
+
+            /* execute */
+            pReqHdr->rc = supdrvIOCtl_TracerUmodDeregister(pDevExt, pSession, pReq->u.In.pVtgHdr);
+            return 0;
+        }
+
         default:
             Log(("Unknown IOCTL %#lx\n", (long)uIOCtl));
Index: /trunk/src/VBox/HostDrivers/Support/SUPDrvIOC.h
===================================================================
--- /trunk/src/VBox/HostDrivers/Support/SUPDrvIOC.h	(revision 40980)
+++ /trunk/src/VBox/HostDrivers/Support/SUPDrvIOC.h	(revision 40981)
@@ -1249,4 +1249,58 @@
 
 
+/** @name SUP_IOCTL_TRACER_UMOD_REG
+ * Registers tracepoints in a user mode module.
+ *
+ * @{
+ */
+#define SUP_IOCTL_TRACER_UMOD_REG                       SUP_CTL_CODE_SIZE(31, SUP_IOCTL_TRACER_UMOD_REG)
+#define SUP_IOCTL_TRACER_UMOD_REG_SIZE                  sizeof(SUPTRACERUMODREG)
+#define SUP_IOCTL_TRACER_UMOD_REG_SIZE_IN               sizeof(SUPTRACERUMODREG)
+#define SUP_IOCTL_TRACER_UMOD_REG_SIZE_OUT              sizeof(SUPREQHDR)
+typedef struct SUPTRACERUMODREG
+{
+    /** The header. */
+    SUPREQHDR               Hdr;
+    union
+    {
+        struct
+        {
+            /** Pointer to the VTG header. */
+            RTR3PTR         pVtgHdr;
+            /** Future flags, MBZ.  */
+            uint32_t        fFlags;
+            /** The module name. */
+            char            szName[64];
+        } In;
+    } u;
+} SUPTRACERUMODREG, *PSUPTRACERUMODREG;
+/** @} */
+
+
+/** @name SUP_IOCTL_TRACER_UMOD_DEREG
+ * Deregisters tracepoints in a user mode module.
+ *
+ * @{
+ */
+#define SUP_IOCTL_TRACER_UMOD_DEREG                     SUP_CTL_CODE_SIZE(32, SUP_IOCTL_TRACER_UMOD_DEREG)
+#define SUP_IOCTL_TRACER_UMOD_DEREG_SIZE                sizeof(SUPTRACERUMODDEREG)
+#define SUP_IOCTL_TRACER_UMOD_DEREG_SIZE_IN             sizeof(SUPTRACERUMODDEREG)
+#define SUP_IOCTL_TRACER_UMOD_DEREG_SIZE_OUT            sizeof(SUPREQHDR)
+typedef struct SUPTRACERUMODDEREG
+{
+    /** The header. */
+    SUPREQHDR               Hdr;
+    union
+    {
+        struct
+        {
+            /** Pointer to the VTG header. */
+            RTR3PTR         pVtgHdr;
+        } In;
+    } u;
+} SUPTRACERUMODDEREG, *PSUPTRACERUMODDEREG;
+/** @} */
+
+
 #pragma pack()                          /* paranoia */
 
Index: /trunk/src/VBox/HostDrivers/Support/SUPDrvInternal.h
===================================================================
--- /trunk/src/VBox/HostDrivers/Support/SUPDrvInternal.h	(revision 40980)
+++ /trunk/src/VBox/HostDrivers/Support/SUPDrvInternal.h	(revision 40981)
@@ -661,4 +661,8 @@
 DECLASM(void)   supdrvTracerProbeFireStub(void);
 
+int  VBOXCALL   supdrvIOCtl_TracerUmodRegister(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, RTR3PTR pVtgHdr, const char *pszModName, uint32_t fFlags);
+int  VBOXCALL   supdrvIOCtl_TracerUmodDeregister(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, RTR3PTR pVtgHdr);
+void  VBOXCALL  supdrvIOCtl_TracerUmodProbeFire(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, PCSUPDRVTRACERUSRCTX pCtx);
+
 #ifdef VBOX_WITH_NATIVE_DTRACE
 const SUPDRVTRACERREG * VBOXCALL supdrvDTraceInit(void);
Index: /trunk/src/VBox/HostDrivers/Support/SUPDrvTracer.cpp
===================================================================
--- /trunk/src/VBox/HostDrivers/Support/SUPDrvTracer.cpp	(revision 40980)
+++ /trunk/src/VBox/HostDrivers/Support/SUPDrvTracer.cpp	(revision 40981)
@@ -1233,4 +1233,20 @@
 
 
+int  VBOXCALL   supdrvIOCtl_TracerUmodRegister(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, RTR3PTR pVtgHdr, const char *pszModName, uint32_t fFlags)
+{
+    return VERR_NOT_IMPLEMENTED;
+}
+
+int  VBOXCALL   supdrvIOCtl_TracerUmodDeregister(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, RTR3PTR pVtgHdr)
+{
+    return VERR_NOT_IMPLEMENTED;
+}
+
+void  VBOXCALL  supdrvIOCtl_TracerUmodProbeFire(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, PCSUPDRVTRACERUSRCTX pCtx)
+{
+
+}
+
+
 /**
  * Open the tracer.
Index: /trunk/src/VBox/HostDrivers/Support/SUPLib.cpp
===================================================================
--- /trunk/src/VBox/HostDrivers/Support/SUPLib.cpp	(revision 40980)
+++ /trunk/src/VBox/HostDrivers/Support/SUPLib.cpp	(revision 40981)
@@ -2387,11 +2387,7 @@
 }
 
-extern "C"
-{
-    SUPDECL(void) SUPTracerFireProbe(uint32_t idProbe, uintptr_t uArg0, uintptr_t uArg1, uintptr_t uArg2,
-                                     uintptr_t uArg3, uintptr_t uArg4);
-}
-
-SUPDECL(void) SUPTracerFireProbe(uint32_t idProbe, uintptr_t uArg0, uintptr_t uArg1, uintptr_t uArg2,
+
+
+SUPDECL(void) SUPTracerFireProbe(struct VTGPROBELOC *pVtgProbeLoc, uintptr_t uArg0, uintptr_t uArg1, uintptr_t uArg2,
                                  uintptr_t uArg3, uintptr_t uArg4)
 {
@@ -2399,2 +2395,89 @@
 }
 
+
+SUPR3DECL(int) SUPR3TracerRegisterModule(uintptr_t hModNative, const char *pszModule, struct VTGOBJHDR *pVtgHdr, uint32_t fFlags)
+{
+    /* Validate input. */
+    NOREF(hModNative);
+    AssertPtrReturn(pVtgHdr, VERR_INVALID_POINTER);
+    AssertPtrReturn(pszModule, VERR_INVALID_POINTER);
+    size_t cchModule = strlen(pszModule);
+    AssertReturn(cchModule < RT_SIZEOFMEMB(SUPTRACERUMODREG, u.In.szName), VERR_FILENAME_TOO_LONG);
+    AssertReturn(!RTPathHavePath(pszModule), VERR_INVALID_PARAMETER);
+    AssertReturn(fFlags == SUP_TRACER_UMOD_FLAGS_EXE || fFlags == SUP_TRACER_UMOD_FLAGS_SHARED, VERR_INVALID_PARAMETER);
+
+    /* fake */
+    if (RT_UNLIKELY(g_u32FakeMode))
+        return VINF_SUCCESS;
+
+    /*
+     * Issue IOCtl to the SUPDRV kernel module.
+     */
+    SUPTRACERUMODREG Req;
+    Req.Hdr.u32Cookie       = g_u32Cookie;
+    Req.Hdr.u32SessionCookie= g_u32SessionCookie;
+    Req.Hdr.cbIn            = SUP_IOCTL_TRACER_UMOD_REG_SIZE_IN;
+    Req.Hdr.cbOut           = SUP_IOCTL_TRACER_UMOD_REG_SIZE_OUT;
+    Req.Hdr.fFlags          = SUPREQHDR_FLAGS_DEFAULT;
+    Req.Hdr.rc              = VERR_INTERNAL_ERROR;
+    Req.u.In.pVtgHdr        = pVtgHdr;
+    Req.u.In.fFlags         = fFlags;
+
+    memcpy(Req.u.In.szName, pszModule, cchModule);
+    if (!RTPathHasExt(Req.u.In.szName))
+    {
+        /* Add the default suffix if none is given. */
+        switch (fFlags & SUP_TRACER_UMOD_FLAGS_TYPE_MASK)
+        {
+#if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2)
+            case SUP_TRACER_UMOD_FLAGS_EXE:
+                if (cchModule + sizeof(".exe") <= sizeof(Req.u.In.szName))
+                    strcpy(&Req.u.In.szName[cchModule], ".exe");
+                break;
+#endif
+
+            case SUP_TRACER_UMOD_FLAGS_SHARED:
+            {
+                const char *pszSuff = RTLdrGetSuff();
+                size_t      cchSuff = strlen(pszSuff);
+                if (cchModule + cchSuff < sizeof(Req.u.In.szName))
+                    memcpy(&Req.u.In.szName[cchModule], pszSuff, cchSuff + 1);
+                break;
+            }
+        }
+    }
+
+    int rc = suplibOsIOCtl(&g_supLibData, SUP_IOCTL_TRACER_UMOD_REG, &Req, SUP_IOCTL_TRACER_UMOD_REG_SIZE);
+    if (RT_SUCCESS(rc))
+        rc = Req.Hdr.rc;
+    return rc;
+}
+
+
+SUPR3DECL(int) SUPR3TracerDeregisterModule(struct VTGOBJHDR *pVtgHdr)
+{
+    /* Validate input. */
+    AssertPtrReturn(pVtgHdr, VERR_INVALID_POINTER);
+
+    /* fake */
+    if (RT_UNLIKELY(g_u32FakeMode))
+        return VINF_SUCCESS;
+
+    /*
+     * Issue IOCtl to the SUPDRV kernel module.
+     */
+    SUPTRACERUMODDEREG Req;
+    Req.Hdr.u32Cookie       = g_u32Cookie;
+    Req.Hdr.u32SessionCookie= g_u32SessionCookie;
+    Req.Hdr.cbIn            = SUP_IOCTL_TRACER_UMOD_REG_SIZE_IN;
+    Req.Hdr.cbOut           = SUP_IOCTL_TRACER_UMOD_REG_SIZE_OUT;
+    Req.Hdr.fFlags          = SUPREQHDR_FLAGS_DEFAULT;
+    Req.Hdr.rc              = VERR_INTERNAL_ERROR;
+    Req.u.In.pVtgHdr        = pVtgHdr;
+
+    int rc = suplibOsIOCtl(&g_supLibData, SUP_IOCTL_TRACER_UMOD_DEREG, &Req, SUP_IOCTL_TRACER_UMOD_DEREG_SIZE);
+    if (RT_SUCCESS(rc))
+        rc = Req.Hdr.rc;
+    return rc;
+}
+
