SUPDrvTracer.cpp revision cb70b5cc08e3b666361766188f99cc86ed1626fb
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * VBoxDrv - The VirtualBox Support Driver - Tracer Interface.
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync * Copyright (C) 2012 Oracle Corporation
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * available from http://www.virtualbox.org. This file is free software;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * you can redistribute it and/or modify it under the terms of the GNU
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * General Public License (GPL) as published by the Free Software
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * The contents of this file may alternatively be used under the terms
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * of the Common Development and Distribution License Version 1.0
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * VirtualBox OSE distribution, in which case the provisions of the
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * CDDL are applicable instead of those of the GPL.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * You may elect to license modified versions of this file under the
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * terms and conditions of either the GPL or the CDDL or both.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync/*******************************************************************************
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync* Header Files *
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync*******************************************************************************/
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync/*******************************************************************************
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync* Structures and Typedefs *
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync*******************************************************************************/
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync * Data for a tracepoint provider.
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync /** The entry in the provider list for this image. */
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync /** The core structure. */
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync /** Pointer to the image this provider resides in. NULL if it's a
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * driver. */
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync /** The session this provider is associated with if registered via
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * SUPR0VtgRegisterDrv. NULL if pImage is set. */
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync /** Used to indicate that we've called pfnProviderDeregistered already and it
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync * failed because the provider was busy. Next time we must try
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync * pfnProviderDeregisterZombie.
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync * @remarks This does not necessiarly mean the provider is in the zombie
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * list. See supdrvTracerCommonDeregisterImpl. */
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync /** Set if the provider has been successfully registered with the
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync * tracer. */
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync /** The provider name (for logging purposes). */
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync/** Pointer to the data for a tracepoint provider. */
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync/*******************************************************************************
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync* Defined Constants And Macros *
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync*******************************************************************************/
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync/** Simple SUPR0Printf-style logging. */
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync/*******************************************************************************
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync* Global Variables *
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync*******************************************************************************/
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync/** The address of the current probe fire routine for kernel mode. */
6b07d9a23ed1c650aa0a3b8de9d19f51b6b67e9fvboxsyncPFNRT g_pfnSupdrvProbeFireKernel = supdrvTracerProbeFireStub;
6b07d9a23ed1c650aa0a3b8de9d19f51b6b67e9fvboxsync * Validates a VTG string against length and characterset limitations.
6b07d9a23ed1c650aa0a3b8de9d19f51b6b67e9fvboxsync * @returns VINF_SUCCESS, VERR_SUPDRV_VTG_BAD_STRING or
6b07d9a23ed1c650aa0a3b8de9d19f51b6b67e9fvboxsync * VERR_SUPDRV_VTG_STRING_TOO_LONG.
6b07d9a23ed1c650aa0a3b8de9d19f51b6b67e9fvboxsync * @param psz The string.
529e6bec97f5ef2e005c99c205c9624583ecb7f0vboxsync /*RTAssertMsg2("off=%u '%s'\n", off, psz);*/
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * Validates the VTG data.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * @returns VBox status code.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * @param pVtgHdr The VTG object header of the data to validate.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * @param cbVtgObj The size of the VTG object.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * @param pbImage The image base. For validating the probe
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * locations.
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync * @param cbImage The image size to go with @a pbImage.
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsyncstatic int supdrvVtgValidate(PVTGOBJHDR pVtgHdr, size_t cbVtgObj, const uint8_t *pbImage, size_t cbImage)
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync#define MY_VALIDATE_PTR(p, cb, cMin, cMax, cbUnit, rcBase) \
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync || (uintptr_t)(p) - (uintptr_t)pVtgHdr > cbVtgObj - (cb) ) \
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync SUPR0Printf("supdrvVtgValidate: " #rcBase "_TOO_PTR - p=%p cb=%#zx pVtgHdr=%p cbVtgHdr=%#zu line=%u %s\n", \
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync p, (size_t)(cb), pVtgHdr, cbVtgObj, __LINE__, #p); \
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync SUPR0Printf("supdrvVtgValidate: " #rcBase "_TOO_FEW - cb=%#zx cMin=%#zx cbUnit=%#zx line=%u %s\n", \
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync (size_t)(cb), (size_t)(cMin), (size_t)cbUnit, __LINE__, #p); \
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync SUPR0Printf("supdrvVtgValidate: " #rcBase "_TOO_MUCH - cb=%#zx cMax=%#zx cbUnit=%#zx line=%u %s\n", \
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync (size_t)(cb), (size_t)(cMax), (size_t)cbUnit, __LINE__, #p); \
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync SUPR0Printf("supdrvVtgValidate: " #rcBase "_NOT_MULTIPLE - cb=%#zx cbUnit=%#zx line=%u %s\n", \
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync } while (0)
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync if ((uintptr_t)(p) - (uintptr_t)pbImage > cbImage) \
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync SUPR0Printf("supdrvVtgValidate: " #rc " - p=%p pbImage=%p cbImage=%#zxline=%u %s\n", \
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync return (rc); \
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync else if (!RT_VALID_PTR(p)) \
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync return (rc); \
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync } while (0)
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync rc = supdrvVtgValidateString(pVtgHdr->pachStrTab + (offStrTab)); \
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync } while (0)
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync if ((Attr).u8Code <= (uint8_t)kVTGStability_Invalid || (Attr).u8Code >= (uint8_t)kVTGStability_End) \
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync if ((Attr).u8Data <= (uint8_t)kVTGStability_Invalid || (Attr).u8Data >= (uint8_t)kVTGStability_End) \
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync if ((Attr).u8DataDep <= (uint8_t)kVTGClass_Invalid || (Attr).u8DataDep >= (uint8_t)kVTGClass_End) \
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync } while (0)
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync * The header.
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync if (memcmp(pVtgHdr->szMagic, VTGOBJHDR_MAGIC, sizeof(pVtgHdr->szMagic)))
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync MY_VALIDATE_PTR(pVtgHdr->paProviders, pVtgHdr->cbProviders, 1, 16, sizeof(VTGDESCPROVIDER), VERR_SUPDRV_VTG_BAD_HDR);
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync MY_VALIDATE_PTR(pVtgHdr->paProbes, pVtgHdr->cbProbes, 1, _32K, sizeof(VTGDESCPROBE), VERR_SUPDRV_VTG_BAD_HDR);
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync MY_VALIDATE_PTR(pVtgHdr->pafProbeEnabled, pVtgHdr->cbProbeEnabled, 1, _32K, sizeof(bool), VERR_SUPDRV_VTG_BAD_HDR);
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync MY_VALIDATE_PTR(pVtgHdr->pachStrTab, pVtgHdr->cbStrTab, 4, _1M, sizeof(char), VERR_SUPDRV_VTG_BAD_HDR);
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync MY_VALIDATE_PTR(pVtgHdr->paArgLists, pVtgHdr->cbArgLists, 1, _32K, sizeof(uint32_t), VERR_SUPDRV_VTG_BAD_HDR);
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync MY_WITHIN_IMAGE(pVtgHdr->paProbLocs, VERR_SUPDRV_VTG_BAD_HDR_PTR);
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync MY_WITHIN_IMAGE(pVtgHdr->paProbLocsEnd, VERR_SUPDRV_VTG_BAD_HDR_PTR);
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync if ((uintptr_t)pVtgHdr->paProbLocs > (uintptr_t)pVtgHdr->paProbLocsEnd)
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync SUPR0Printf("supdrvVtgValidate: VERR_SUPDRV_VTG_BAD_HDR_PTR - paProbeLocs=%p > paProbLocsEnd=%p\n",
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync cbTmp = (uintptr_t)pVtgHdr->paProbLocsEnd - (uintptr_t)pVtgHdr->paProbLocs;
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync SUPR0Printf("supdrvVtgValidate: VERR_SUPDRV_VTG_BAD_HDR_TOO_FEW - cbTmp=%#zx paProbeLocs=%p paProbLocsEnd=%p\n",
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync cbTmp, pVtgHdr->paProbLocs, pVtgHdr->paProbLocsEnd);
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync SUPR0Printf("supdrvVtgValidate: VERR_SUPDRV_VTG_BAD_HDR_TOO_MUCH - cbTmp=%#zx paProbeLocs=%p paProbLocsEnd=%p\n",
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync cbTmp, pVtgHdr->paProbLocs, pVtgHdr->paProbLocsEnd);
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync if (cbTmp / sizeof(VTGPROBELOC) * sizeof(VTGPROBELOC) != cbTmp)
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync SUPR0Printf("supdrvVtgValidate: VERR_SUPDRV_VTG_BAD_HDR_NOT_MULTIPLE - cbTmp=%#zx cbUnit=%#zx paProbeLocs=%p paProbLocsEnd=%p\n",
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync cbTmp, sizeof(VTGPROBELOC), pVtgHdr->paProbLocs, pVtgHdr->paProbLocsEnd);
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync if (pVtgHdr->cbProbes / sizeof(VTGDESCPROBE) != pVtgHdr->cbProbeEnabled)
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync SUPR0Printf("supdrvVtgValidate: VERR_SUPDRV_VTG_BAD_HDR - cbProbeEnabled=%#zx cbProbes=%#zx\n",
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync * Validate the providers.
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync cProviders = i = pVtgHdr->cbProviders / sizeof(VTGDESCPROVIDER);
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync while (i-- > 0)
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync if (pVtgHdr->paProviders[i].iFirstProbe >= pVtgHdr->cbProbeEnabled)
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync if (pVtgHdr->paProviders[i].iFirstProbe + pVtgHdr->paProviders[i].cProbes > pVtgHdr->cbProbeEnabled)
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync MY_VALIDATE_ATTR(pVtgHdr->paProviders[i].AttrSelf);
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync MY_VALIDATE_ATTR(pVtgHdr->paProviders[i].AttrModules);
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync MY_VALIDATE_ATTR(pVtgHdr->paProviders[i].AttrFunctions);
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync MY_VALIDATE_ATTR(pVtgHdr->paProviders[i].AttrNames);
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync MY_VALIDATE_ATTR(pVtgHdr->paProviders[i].AttrArguments);
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync * Validate probes.
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync while (i-- > 0)
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync if (pVtgHdr->paProbes[i].offArgList >= pVtgHdr->cbArgLists)
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync if (pVtgHdr->paProbes[i].idxEnabled != i) /* The lists are parallel. */
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync if (pVtgHdr->paProbes[i].idxProvider >= cProviders)
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync if ( i - pVtgHdr->paProviders[pVtgHdr->paProbes[i].idxProvider].iFirstProbe
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync >= pVtgHdr->paProviders[pVtgHdr->paProbes[i].idxProvider].cProbes)
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync /* The referenced argument list. */
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync pArgList = (PVTGDESCARGLIST)((uintptr_t)pVtgHdr->paArgLists + pVtgHdr->paProbes[i].offArgList);
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync while (iArg-- > 0)
529e6bec97f5ef2e005c99c205c9624583ecb7f0vboxsync * Check that pafProbeEnabled is all zero.
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync while (i-- > 0)
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync * Probe locations.
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync while (i-- > 0)
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync MY_WITHIN_IMAGE(pVtgHdr->paProbLocs[i].pszFunction, VERR_SUPDRV_VTG_BAD_PROBE_LOC);
529e6bec97f5ef2e005c99c205c9624583ecb7f0vboxsync offTmp = (uintptr_t)pVtgHdr->paProbLocs[i].pbProbe - (uintptr_t)pVtgHdr->paProbes;
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync if (offTmp / sizeof(VTGDESCPROBE) * sizeof(VTGDESCPROBE) != offTmp)
529e6bec97f5ef2e005c99c205c9624583ecb7f0vboxsync * Gets a string from the string table.
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync * @returns Pointer to the string.
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync * @param pVtgHdr The VTG object header.
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync * @param offStrTab The string table offset.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsyncstatic const char *supdrvVtgGetString(PVTGOBJHDR pVtgHdr, uint32_t offStrTab)
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * Frees the provider structure and associated resources.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * @param pProv The provider to free.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsyncstatic void supdrvTracerFreeProvider(PSUPDRVTPPROVIDER pProv)
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync LOG_TRACER(("Freeing tracepoint provider '%s' / %p\n", pProv->szName, pProv->Core.TracerData.DTrace.idProvider));
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * Deregisters a provider.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * If the provider is still busy, it will be put in the zombie list.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * @param pDevExt The device extension.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * @param pProv The provider.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * @remarks The caller owns mtxTracer.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsyncstatic void supdrvTracerDeregisterVtgObj(PSUPDRVDEVEXT pDevExt, PSUPDRVTPPROVIDER pProv)
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync rc = pDevExt->pTracerOps->pfnProviderDeregister(pDevExt->pTracerOps, &pProv->Core);
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync RTListAppend(&pDevExt->TracerProviderZombieList, &pProv->ListEntry);
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync LOG_TRACER(("Invalidated provider '%s' / %p and put it on the zombie list (rc=%Rrc)\n",
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync pProv->szName, pProv->Core.TracerData.DTrace.idProvider, rc));
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * Processes the zombie list.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * @param pDevExt The device extension.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsyncstatic void supdrvTracerProcessZombies(PSUPDRVDEVEXT pDevExt)
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync RTListForEachSafe(&pDevExt->TracerProviderZombieList, pProv, pProvNext, SUPDRVTPPROVIDER, ListEntry)
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync int rc = pDevExt->pTracerOps->pfnProviderDeregisterZombie(pDevExt->pTracerOps, &pProv->Core);
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * Unregisters all providers, including zombies, waiting for busy providers to
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * go idle and unregister smoothly.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * This may block.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * @param pDevExt The device extension.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsyncstatic void supdrvTracerRemoveAllProviders(PSUPDRVDEVEXT pDevExt)
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * Unregister all probes (there should only be one).
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync RTListForEachSafe(&pDevExt->TracerProviderList, pProv, pProvNext, SUPDRVTPPROVIDER, ListEntry)
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * Try unregister zombies now, sleep on busy ones and tracer opens.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync for (i = 0; ; i++)
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync /* Zombies */
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync RTListForEachSafe(&pDevExt->TracerProviderZombieList, pProv, pProvNext, SUPDRVTPPROVIDER, ListEntry)
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync LOG_TRACER(("supdrvTracerRemoveAllProviders: Attemting to unregister '%s' / %p...\n",
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync pProv->szName, pProv->Core.TracerData.DTrace.idProvider));
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync rc = pDevExt->pTracerOps->pfnProviderDeregisterZombie(pDevExt->pTracerOps, &pProv->Core);
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync else if (!(i & 0xf))
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync SUPR0Printf("supdrvTracerRemoveAllProviders: Waiting on busy provider '%s' / %p (rc=%d)\n",
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync pProv->szName, pProv->Core.TracerData.DTrace.idProvider, rc);
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync LOG_TRACER(("supdrvTracerRemoveAllProviders: Failed to unregister provider '%s' / %p - rc=%d\n",
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync pProv->szName, pProv->Core.TracerData.DTrace.idProvider, rc));
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync fEmpty = RTListIsEmpty(&pDevExt->TracerProviderZombieList);
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync /* Tracer opens. */
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync if (!(i & 0xf))
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync SUPR0Printf("supdrvTracerRemoveAllProviders: Waiting on %u opens\n", pDevExt->cTracerOpens);
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync LOG_TRACER(("supdrvTracerRemoveAllProviders: Waiting on %u opens\n", pDevExt->cTracerOpens));
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync /* Delay...*/
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * Registers the VTG tracepoint providers of a driver.
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync * @returns VBox status code.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * @param pszName The driver name.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * @param pVtgHdr The VTG object header.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * @param pVtgObj The size of the VTG object.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * @param pImage The image if applicable.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * @param pSession The session if applicable.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * @param pszModName The module name.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsyncstatic int supdrvTracerRegisterVtgObj(PSUPDRVDEVEXT pDevExt, PVTGOBJHDR pVtgHdr, size_t cbVtgObj, PSUPDRVLDRIMAGE pImage,
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * Validate input.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync AssertPtrNullReturn(pSession, VERR_INVALID_POINTER);
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync rc = supdrvVtgValidate(pVtgHdr, cbVtgObj, (const uint8_t *)pImage->pvImage, pImage->cbImageBits);
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync rc = supdrvVtgValidate(pVtgHdr, cbVtgObj, NULL, 0);
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync RTListForEach(&pDevExt->TracerProviderList, pProv, SUPDRVTPPROVIDER, ListEntry)
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * Register the providers.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync i = pVtgHdr->cbProviders / sizeof(VTGDESCPROVIDER);
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync while (i-- > 0)
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync const char *pszName = supdrvVtgGetString(pVtgHdr, pDesc->offName);
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync pProv = (PSUPDRVTPPROVIDER)RTMemAllocZ(RT_OFFSETOF(SUPDRVTPPROVIDER, szName[cchName + 1]));
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync rc = pDevExt->pTracerOps->pfnProviderRegister(pDevExt->pTracerOps, &pProv->Core);
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync RTListAppend(&pDevExt->TracerProviderList, &pProv->ListEntry);
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync LOG_TRACER(("Registered tracepoint provider '%s' in '%s' -> %p\n",
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync pProv->szName, pszModName, pProv->Core.TracerData.DTrace.idProvider));
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync LOG_TRACER(("Failed to register tracepoint provider '%s' in '%s' -> %Rrc\n",
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync RTListForEachReverseSafe(&pDevExt->TracerProviderList, pProv, pProvNext, SUPDRVTPPROVIDER, ListEntry)
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * Registers the VTG tracepoint providers of a driver.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * @returns VBox status code.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * @param pSession The support driver session handle.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * @param pVtgHdr The VTG header.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * @param pszName The driver name.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsyncSUPR0DECL(int) SUPR0TracerRegisterDrv(PSUPDRVSESSION pSession, PVTGOBJHDR pVtgHdr, const char *pszName)
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync AssertReturn(SUP_IS_SESSION_VALID(pSession), VERR_INVALID_PARAMETER);
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync AssertReturn(pSession->R0Process == NIL_RTR0PROCESS, VERR_INVALID_PARAMETER);
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync LOG_TRACER(("SUPR0TracerRegisterDrv: pSession=%p pVtgHdr=%p pszName=%s\n", pSession, pVtgHdr, pszName));
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync rc = supdrvTracerRegisterVtgObj(pSession->pDevExt, pVtgHdr, _1M, NULL /*pImage*/, pSession, pszName);
6b07d9a23ed1c650aa0a3b8de9d19f51b6b67e9fvboxsync * Try unregister zombies while we have a chance.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * Deregister the VTG tracepoint providers of a driver.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * @param pSession The support driver session handle.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * @param pVtgHdr The VTG header.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsyncSUPR0DECL(void) SUPR0TracerDeregisterDrv(PSUPDRVSESSION pSession)
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync AssertReturnVoid(pSession->R0Process == NIL_RTR0PROCESS);
6b07d9a23ed1c650aa0a3b8de9d19f51b6b67e9fvboxsync LOG_TRACER(("SUPR0TracerDeregisterDrv: pSession=%p\n", pSession));
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * Search for providers belonging to this driver session.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync RTListForEachSafe(&pDevExt->TracerProviderList, pProv, pProvNext, SUPDRVTPPROVIDER, ListEntry)
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * Try unregister zombies while we have a chance.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * Registers the VTG tracepoint providers of a module loaded by
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * the support driver.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * This should be called from the ModuleInit code.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * @returns VBox status code.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * @param hMod The module handle.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * @param pVtgHdr The VTG header.
07557d07616212d7ba6e7ab3059e85cb14633775vboxsyncSUPR0DECL(int) SUPR0TracerRegisterModule(void *hMod, PVTGOBJHDR pVtgHdr)
7c19e11502220292d5270519296442234c2493cdvboxsync LOG_TRACER(("SUPR0TracerRegisterModule: %p\n", pVtgHdr));
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync * Validate input and context.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync AssertReturn(pDevExt->pLdrInitImage == pImage, VERR_WRONG_ORDER);
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync AssertReturn(pDevExt->hLdrInitThread == RTThreadNativeSelf(), VERR_WRONG_ORDER);
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * Calculate the max VTG object size and hand it over to the common code.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync cbVtgObj = (uintptr_t)pVtgHdr - (uintptr_t)pImage->pvImage;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync AssertMsgReturn(cbVtgObj /*off*/ < pImage->cbImageBits,
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync ("pVtgHdr=%p offVtgObj=%p cbImageBits=%p\n", pVtgHdr, cbVtgObj, pImage->cbImageBits),
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync rc = supdrvTracerRegisterVtgObj(pDevExt, pVtgHdr, cbVtgObj, pImage, NULL, pImage->szName);
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync LOG_TRACER(("SUPR0TracerRegisterModule: rc=%d\n", rc));
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * Try unregister zombies while we have a chance.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * Registers the tracer implementation.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * This should be called from the ModuleInit code or from a ring-0 session.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * @returns VBox status code.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * @param hMod The module handle.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * @param pSession Ring-0 session handle.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * @param pReg Pointer to the tracer registration structure.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * @param ppHlp Where to return the tracer helper method table.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsyncSUPR0DECL(int) SUPR0TracerRegisterImpl(void *hMod, PSUPDRVSESSION pSession, PCSUPDRVTRACERREG pReg, PCSUPDRVTRACERHLP *ppHlp)
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * Validate input and context.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync AssertReturn(pSession == NULL, VERR_INVALID_PARAMETER);
529e6bec97f5ef2e005c99c205c9624583ecb7f0vboxsync AssertReturn(pDevExt->pLdrInitImage == pImage, VERR_WRONG_ORDER);
529e6bec97f5ef2e005c99c205c9624583ecb7f0vboxsync AssertReturn(pDevExt->hLdrInitThread == RTThreadNativeSelf(), VERR_WRONG_ORDER);
e819feefdc34d50781a3c95edecda1072e8575d0vboxsync AssertReturn(SUP_IS_SESSION_VALID(pSession), VERR_INVALID_PARAMETER);
e819feefdc34d50781a3c95edecda1072e8575d0vboxsync AssertReturn(pSession->R0Process == NIL_RTR0PROCESS, VERR_INVALID_PARAMETER);
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync AssertReturn(pReg->u32Magic == SUPDRVTRACERREG_MAGIC, VERR_INVALID_MAGIC);
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync AssertReturn(pReg->u32Version == SUPDRVTRACERREG_VERSION, VERR_VERSION_MISMATCH);
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync AssertReturn(pReg->uEndMagic == SUPDRVTRACERREG_MAGIC, VERR_VERSION_MISMATCH);
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync AssertPtrReturn(pReg->pfnProbeFireKernel, VERR_INVALID_POINTER);
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync AssertPtrReturn(pReg->pfnProbeFireUser, VERR_INVALID_POINTER);
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync AssertPtrReturn(pReg->pfnTracerOpen, VERR_INVALID_POINTER);
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync AssertPtrReturn(pReg->pfnTracerIoCtl, VERR_INVALID_POINTER);
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync AssertPtrReturn(pReg->pfnTracerClose, VERR_INVALID_POINTER);
e819feefdc34d50781a3c95edecda1072e8575d0vboxsync AssertPtrReturn(pReg->pfnProviderRegister, VERR_INVALID_POINTER);
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync AssertPtrReturn(pReg->pfnProviderDeregister, VERR_INVALID_POINTER);
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync AssertPtrReturn(pReg->pfnProviderDeregisterZombie, VERR_INVALID_POINTER);
6b07d9a23ed1c650aa0a3b8de9d19f51b6b67e9fvboxsync * Do the job.
6b07d9a23ed1c650aa0a3b8de9d19f51b6b67e9fvboxsync LOG_TRACER(("SUPR0TracerRegisterImpl: pReg=%p\n", pReg));
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync g_pfnSupdrvProbeFireKernel = (PFNRT)pDevExt->pTracerOps->pfnProbeFireKernel;
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync * Iterate the already loaded modules and register their providers.
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync RTListForEach(&pDevExt->TracerProviderList, pProv, SUPDRVTPPROVIDER, ListEntry)
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync int rc2 = pDevExt->pTracerOps->pfnProviderRegister(pDevExt->pTracerOps, &pProv->Core);
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync SUPR0Printf("SUPR0TracerRegisterImpl: Failed to register provider %s::%s - rc=%d\n",
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync * Common tracer implementation deregistration code.
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync * The caller sets fTracerUnloading prior to calling this function.
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync * @param pDevExt The device extension structure.
07557d07616212d7ba6e7ab3059e85cb14633775vboxsyncstatic void supdrvTracerCommonDeregisterImpl(PSUPDRVDEVEXT pDevExt)
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync * Reinstall the stub probe-fire function.
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync g_pfnSupdrvProbeFireKernel = supdrvTracerProbeFireStub;
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync * Disassociate the tracer implementation from all providers.
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync * We will have to wait on busy providers.
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync for (i = 0; ; i++)
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync /* Live providers. */
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync RTListForEachSafe(&pDevExt->TracerProviderList, pProv, pProvNext, SUPDRVTPPROVIDER, ListEntry)
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync LOG_TRACER(("supdrvTracerCommonDeregisterImpl: Attemting to unregister '%s' / %p...\n",
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync pProv->szName, pProv->Core.TracerData.DTrace.idProvider));
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync rc = pDevExt->pTracerOps->pfnProviderDeregister(pDevExt->pTracerOps, &pProv->Core);
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync rc = pDevExt->pTracerOps->pfnProviderDeregisterZombie(pDevExt->pTracerOps, &pProv->Core);
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync if (!(i & 0xf))
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync SUPR0Printf("supdrvTracerCommonDeregisterImpl: Waiting on busy provider '%s' / %p (rc=%d)\n",
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync pProv->szName, pProv->Core.TracerData.DTrace.idProvider, rc);
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync LOG_TRACER(("supdrvTracerCommonDeregisterImpl: Failed to unregister provider '%s' / %p - rc=%d\n",
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync pProv->szName, pProv->Core.TracerData.DTrace.idProvider, rc));
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync /* Zombies providers. */
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync RTListForEachSafe(&pDevExt->TracerProviderZombieList, pProv, pProvNext, SUPDRVTPPROVIDER, ListEntry)
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync LOG_TRACER(("supdrvTracerCommonDeregisterImpl: Attemting to unregister '%s' / %p (zombie)...\n",
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync pProv->szName, pProv->Core.TracerData.DTrace.idProvider));
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync rc = pDevExt->pTracerOps->pfnProviderDeregisterZombie(pDevExt->pTracerOps, &pProv->Core);
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync if (!(i & 0xf))
e819feefdc34d50781a3c95edecda1072e8575d0vboxsync SUPR0Printf("supdrvTracerCommonDeregisterImpl: Waiting on busy provider '%s' / %p (rc=%d)\n",
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync pProv->szName, pProv->Core.TracerData.DTrace.idProvider, rc);
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync LOG_TRACER(("supdrvTracerCommonDeregisterImpl: Failed to unregister provider '%s' / %p - rc=%d\n",
e819feefdc34d50781a3c95edecda1072e8575d0vboxsync pProv->szName, pProv->Core.TracerData.DTrace.idProvider, rc));
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync /* Tracer opens. */
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync if (!(i & 0xf))
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync SUPR0Printf("supdrvTracerCommonDeregisterImpl: Waiting on %u opens\n", pDevExt->cTracerOpens);
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync LOG_TRACER(("supdrvTracerCommonDeregisterImpl: Waiting on %u opens\n", pDevExt->cTracerOpens));
e819feefdc34d50781a3c95edecda1072e8575d0vboxsync /* Done? */
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync /* Delay...*/
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync * Deregister the tracer implementation.
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync * Deregister a tracer implementation.
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync * This should be called from the ModuleTerm code or from a ring-0 session.
815647972e1e2746466be1ea725e702459693cd5vboxsync * @returns VBox status code.
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync * @param hMod The module handle.
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync * @param pSession Ring-0 session handle.
07557d07616212d7ba6e7ab3059e85cb14633775vboxsyncSUPR0DECL(int) SUPR0TracerDeregisterImpl(void *hMod, PSUPDRVSESSION pSession)
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync * Validate input and context.
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync AssertReturn(pSession == NULL, VERR_INVALID_PARAMETER);
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync AssertReturn(SUP_IS_SESSION_VALID(pSession), VERR_INVALID_PARAMETER);
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync AssertReturn(pSession->R0Process == NIL_RTR0PROCESS, VERR_INVALID_PARAMETER);
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync * Do the job.
815647972e1e2746466be1ea725e702459693cd5vboxsync LOG_TRACER(("SUPR0TracerDeregisterImpl: Unloading ...\n"));
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync LOG_TRACER(("SUPR0TracerDeregisterImpl: ... done.\n"));
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync * The probe function is a bit more fun since we need tail jump optimizating.
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync * Since we cannot ship yasm sources for linux and freebsd, owing to the cursed
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync * rebuilding of the kernel module from scratch at install time, we have to
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync * deploy some ugly gcc inline assembly here.
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync#if defined(__GNUC__) && (defined(RT_OS_FREEBSD) || defined(RT_OS_LINUX))
815647972e1e2746466be1ea725e702459693cd5vboxsync .section .text \n\
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync .p2align 2,,3 \n\
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync .global SUPR0TracerFireProbe \n\
07557d07616212d7ba6e7ab3059e85cb14633775vboxsyncSUPR0TracerFireProbe: \n\
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync movq g_pfnSupdrvProbeFireKernel(%rip), %rax \n\
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync jmp *%rax \n\
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync movl g_pfnSupdrvProbeFireKernel, %eax \n\
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync jmp *%eax \n\
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync .type supdrvTracerProbeFireStub,@function \n\
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync .global supdrvTracerProbeFireStub \n\
07557d07616212d7ba6e7ab3059e85cb14633775vboxsyncsupdrvTracerProbeFireStub: \n\
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync .previous \n\
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync# if 0 /* Slickedit on windows highlighting fix */
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync * Module unloading hook, called after execution in the module have ceased.
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync * @param pDevExt The device extension structure.
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync * @param pImage The image being unloaded.
07557d07616212d7ba6e7ab3059e85cb14633775vboxsyncvoid VBOXCALL supdrvTracerModuleUnloading(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage)
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync * If it is the tracer image, we have to unload all the providers.
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync LOG_TRACER(("supdrvTracerModuleUnloading: Unloading tracer ...\n"));
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync LOG_TRACER(("supdrvTracerModuleUnloading: ... done.\n"));
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync * Unregister all providers belonging to this image.
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync RTListForEachSafe(&pDevExt->TracerProviderList, pProv, pProvNext, SUPDRVTPPROVIDER, ListEntry)
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync * Try unregister zombies while we have a chance.
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync * Called when a session is being cleaned up.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * @param pDevExt The device extension structure.
529e6bec97f5ef2e005c99c205c9624583ecb7f0vboxsync * @param pSession The session that is being torn down.
07557d07616212d7ba6e7ab3059e85cb14633775vboxsyncvoid VBOXCALL supdrvTracerCleanupSession(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession)
529e6bec97f5ef2e005c99c205c9624583ecb7f0vboxsync * If ring-0 session, make sure it has deregistered VTG objects and the tracer.
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync RTListForEachSafe(&pDevExt->TracerProviderList, pProv, pProvNext, SUPDRVTPPROVIDER, ListEntry)
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync * Clean up instance data the trace may have associated with the session.
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync * Open the tracer.
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync * @returns VBox status code
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync * @param pDevExt The device extension structure.
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync * @param pSession The current session.
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync * @param uCookie The tracer cookie.
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync * @param uArg The tracer open argument.
529e6bec97f5ef2e005c99c205c9624583ecb7f0vboxsyncint VBOXCALL supdrvIOCtl_TracerOpen(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, uint32_t uCookie, uintptr_t uArg)
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync rc = pDevExt->pTracerOps->pfnTracerOpen(pDevExt->pTracerOps, pSession, uCookie, uArg, &pSession->uTracerData);
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * Closes the tracer.
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync * @returns VBox status code.
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync * @param pDevExt The device extension structure.
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync * @param pSession The current session.
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsyncint VBOXCALL supdrvIOCtl_TracerClose(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession)
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync pDevExt->pTracerOps->pfnTracerClose(pDevExt->pTracerOps, pSession, uTracerData);
529e6bec97f5ef2e005c99c205c9624583ecb7f0vboxsync * Performs a tracer I/O control request.
7c19e11502220292d5270519296442234c2493cdvboxsync * @returns VBox status code.
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync * @param pDevExt The device extension structure.
7c19e11502220292d5270519296442234c2493cdvboxsync * @param pSession The current session.
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync * @param uCmd The tracer command.
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync * @param uArg The tracer argument.
7c19e11502220292d5270519296442234c2493cdvboxsync * @param piRetVal Where to store the tracer specific return value.
7c19e11502220292d5270519296442234c2493cdvboxsyncint VBOXCALL supdrvIOCtl_TracerIOCtl(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, uintptr_t uCmd, uintptr_t uArg, int32_t *piRetVal)
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync rc = pDevExt->pTracerOps->pfnTracerIoCtl(pDevExt->pTracerOps, pSession, uTracerData, uCmd, uArg, piRetVal);
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * Early module initialization hook.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * @returns VBox status code.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * @param pDevExt The device extension structure.
6b07d9a23ed1c650aa0a3b8de9d19f51b6b67e9fvboxsyncint VBOXCALL supdrvTracerInit(PSUPDRVDEVEXT pDevExt)
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * Initialize the tracer.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync int rc = RTSemFastMutexCreate(&pDevExt->mtxTracer);
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync pDevExt->TracerHlp.uVersion = SUPDRVTRACERHLP_VERSION;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync /** @todo */
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync pDevExt->TracerHlp.uEndVersion = SUPDRVTRACERHLP_VERSION;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync g_pfnSupdrvProbeFireKernel = (PFNRT)pDevExt->pTracerOps->pfnProbeFireKernel;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * Register the provider for this module, if compiled in.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync rc = supdrvTracerRegisterVtgObj(pDevExt, &g_VTGObjHeader, _1M, NULL /*pImage*/, NULL /*pSession*/, "vboxdrv");
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync SUPR0Printf("supdrvTracerInit: supdrvTracerRegisterVtgObj failed with rc=%d\n", rc);
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * Late module termination hook.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * @returns VBox status code.
815647972e1e2746466be1ea725e702459693cd5vboxsync * @param pDevExt The device extension structure.