Changeset 53667 in vbox for trunk/src/VBox
- Timestamp:
- Jan 2, 2015 12:32:53 PM (10 years ago)
- svn:sync-xref-src-repo-rev:
- 97444
- Location:
- trunk/src/VBox/ExtPacks/VBoxDTrace
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/ExtPacks/VBoxDTrace/VBoxDTraceR0/VBoxDTraceR0.cpp
r53666 r53667 34 34 *******************************************************************************/ 35 35 #include <VBox/sup.h> 36 #include <VBox/log.h> 36 37 37 38 #include <iprt/asm-amd64-x86.h> 38 39 #include <iprt/assert.h> 40 #include <iprt/ctype.h> 39 41 #include <iprt/err.h> 40 42 #include <iprt/mem.h> 41 43 #include <iprt/mp.h> 44 #include <iprt/spinlock.h> 42 45 #include <iprt/string.h> 43 46 #include <iprt/time.h> 44 47 45 48 #include <sys/dtrace_impl.h> 49 50 #include <VBox/VBoxTpG.h> 51 46 52 47 53 … … 54 60 RTDEV uMajor; 55 61 }; 62 63 64 /** Caller indicator. */ 65 typedef enum VBOXDTCALLER 66 { 67 kVBoxDtCaller_Invalid = 0, 68 kVBoxDtCaller_Generic, 69 kVBoxDtCaller_ProbeFireUser, 70 kVBoxDtCaller_ProbeFireKernel 71 } VBOXDTCALLER; 72 73 /** 74 * Stack data used for thread structure and such. 75 * 76 * This is planted in every external entry point and used to emulate solaris 77 * curthread, CRED, curproc and similar. It is also used to get at the 78 * uncached probe arguments. 79 */ 80 typedef struct VBoxDtStackData 81 { 82 /** Eyecatcher no. 1 (VBDT_STACK_DATA_MAGIC2). */ 83 uint32_t u32Magic1; 84 /** Eyecatcher no. 2 (VBDT_STACK_DATA_MAGIC2). */ 85 uint32_t u32Magic2; 86 /** The format of the caller specific data. */ 87 VBOXDTCALLER enmCaller; 88 /** Caller specific data. */ 89 union 90 { 91 /** kVBoxDtCaller_ProbeFireKernel. */ 92 struct 93 { 94 /** The caller. */ 95 uintptr_t uCaller; 96 /** Pointer to the stack arguments of a probe function call. */ 97 uintptr_t *pauStackArgs; 98 } ProbeFireKernel; 99 /** kVBoxDtCaller_ProbeFireUser. */ 100 struct 101 { 102 /** The user context. */ 103 PCSUPDRVTRACERUSRCTX pCtx; 104 } ProbeFireUser; 105 } u; 106 /** Credentials allocated by VBoxDtGetCurrentCreds. */ 107 struct VBoxDtCred *pCred; 108 /** Pointer to this structure. 109 * This is the final bit of integrity checking. */ 110 struct VBoxDtStackData *pSelf; 111 } VBDTSTACKDATA; 112 /** Pointer to the on-stack thread specific data. */ 113 typedef VBDTSTACKDATA *PVBDTSTACKDATA; 114 115 /** The first magic value. */ 116 #define VBDT_STACK_DATA_MAGIC1 RT_MAKE_U32_FROM_U8('V', 'B', 'o', 'x') 117 /** The second magic value. */ 118 #define VBDT_STACK_DATA_MAGIC2 RT_MAKE_U32_FROM_U8('D', 'T', 'r', 'c') 119 120 /** The alignment of the stack data. 121 * The data doesn't require more than sizeof(uintptr_t) alignment, but the 122 * greater alignment the quicker lookup. */ 123 #define VBDT_STACK_DATA_ALIGN 32 124 125 /** Plants the stack data. */ 126 #define VBDT_SETUP_STACK_DATA(a_enmCaller) \ 127 uint8_t abBlob[sizeof(VBoxDtStackData) + VBDT_STACK_DATA_ALIGN - 1]; \ 128 PVBDTSTACKDATA pStackData = (PVBDTSTACKDATA)( (uintptr_t)&abBlob[VBDT_STACK_DATA_ALIGN - 1] \ 129 & ~(uintptr_t)(VBDT_STACK_DATA_ALIGN - 1)); \ 130 pStackData->u32Magic1 = VBDT_STACK_DATA_MAGIC1; \ 131 pStackData->u32Magic2 = VBDT_STACK_DATA_MAGIC2; \ 132 pStackData->enmCaller = a_enmCaller; \ 133 pStackData->pCred = NULL; \ 134 pStackData->pSelf = pStackData 135 136 /** Passifies the stack data and frees up resource held within it. */ 137 #define VBDT_CLEAR_STACK_DATA() \ 138 do \ 139 { \ 140 pStackData->u32Magic1 = 0; \ 141 pStackData->u32Magic2 = 0; \ 142 pStackData->pSelf = NULL; \ 143 if (pStackData->pCred) \ 144 crfree(pStackData->pCred); \ 145 } while (0) 56 146 57 147 … … 80 170 void (*dtrace_debugger_fini)(void); 81 171 dtrace_cacheid_t dtrace_predcache_id = DTRACE_CACHEIDNONE + 1; 172 173 174 /** 175 * Gets the stack data. 176 * 177 * @returns Pointer to the stack data. Never NULL. 178 */ 179 static PVBDTSTACKDATA vboxDtGetStackData(void) 180 { 181 int volatile iDummy = 1; /* use this to get the stack address. */ 182 PVBDTSTACKDATA pData = (PVBDTSTACKDATA)( ((uintptr_t)&iDummy + VBDT_STACK_DATA_ALIGN - 1) 183 & ~(uintptr_t)(VBDT_STACK_DATA_ALIGN - 1)); 184 for (;;) 185 { 186 if ( pData->u32Magic1 == VBDT_STACK_DATA_MAGIC1 187 && pData->u32Magic2 == VBDT_STACK_DATA_MAGIC2 188 && pData->pSelf == pData) 189 return pData; 190 pData = (PVBDTSTACKDATA)((uintptr_t)pData + VBDT_STACK_DATA_ALIGN); 191 } 192 } 82 193 83 194 … … 312 423 uintptr_t dtrace_caller(int cCallFrames) 313 424 { 314 /** @todo Will fix dtrace_probe this so it won't be necessary. */ 315 return (uintptr_t)~0; 425 PVBDTSTACKDATA pData = vboxDtGetStackData(); 426 if (pData->enmCaller == kVBoxDtCaller_ProbeFireKernel) 427 return pData->u.ProbeFireKernel.uCaller; 428 return ~(uintptr_t)0; 316 429 } 317 430 … … 326 439 uint64_t dtrace_getarg(int iArg, int cCallFrames) 327 440 { 328 /** @todo Will fix dtrace_probe this so that this will be easier to do on all 329 * platforms (MSC sucks, no frames on AMD64). */ 330 return 0xdeadbeef; 441 PVBDTSTACKDATA pData = vboxDtGetStackData(); 442 AssertReturn(iArg >= 5, UINT64_MAX); 443 444 if (pData->enmCaller == kVBoxDtCaller_ProbeFireKernel) 445 return pData->u.ProbeFireKernel.pauStackArgs[iArg - 5]; 446 return UINT64_MAX; 331 447 } 332 448 … … 521 637 cred_t *VBoxDtGetCurrentCreds(void) 522 638 { 523 struct VBoxDtThread *pThread = VBoxDtGetCurrentThread(); 524 if (!pThread) 525 return NULL; 526 return pThread->t_proc->p_cred; 639 PVBDTSTACKDATA pData = vboxDtGetStackData(); 640 if (!pData->pCred) 641 { 642 struct VBoxDtCred *pCred; 643 int rc = RTMemAllocEx(sizeof(*pCred), 0, RTMEMALLOCEX_FLAGS_ANY_CTX, (void **)&pCred); 644 AssertFatalRC(rc); 645 pCred->cr_refs = 1; 646 /** @todo get the right creds on unix systems. */ 647 pCred->cr_uid = 0; 648 pCred->cr_ruid = 0; 649 pCred->cr_suid = 0; 650 pCred->cr_gid = 0; 651 pCred->cr_rgid = 0; 652 pCred->cr_sgid = 0; 653 pCred->cr_zone = 0; 654 pData->pCred = pCred; 655 } 656 657 return pData->pCred; 527 658 } 528 659 … … 546 677 547 678 548 /* ddi_driver_major implementation. */ 549 major_t VBoxDtDdiDriverMajor(struct VBoxDtDevInfo *pDevInfo) 550 { 551 Assert(pDevInfo == &g_DevInfo); 552 return pDevInfo->uMajor; 553 } 554 555 /* ddi_report_dev stub.*/ 556 void VBoxDtDdiReportDev(struct VBoxDtDevInfo *pDevInfo) 557 { 558 Assert(pDevInfo == &g_DevInfo); 559 } 560 561 562 //VBoxDtDdiSoftStateAllocZ 563 //VBoxDtDdiSoftStateFree 564 //VBoxDtDdiSoftStateGet 565 //VBoxDtDdiSoftStateInit 566 //VBoxDtDdiSoftStateTerm 567 568 679 /** The number of bits per chunk. 680 * @remarks The 32 bytes are for heap headers and such like. */ 681 #define VBOXDTVMEMCHUNK_BITS ( ((_64K - 32 - sizeof(uint32_t) * 2) / sizeof(uint32_t)) * 32) 682 683 /** 684 * Resource allocator chunk. 685 */ 686 typedef struct VBoxDtVMemChunk 687 { 688 /** The ordinal (unbased) of the first item. */ 689 uint32_t iFirst; 690 /** The current number of free items in this chunk. */ 691 uint32_t cCurFree; 692 /** The allocation bitmap. */ 693 uint32_t bm[VBOXDTVMEMCHUNK_BITS / 32]; 694 } VBOXDTVMEMCHUNK; 695 /** Pointer to a resource allocator chunk. */ 696 typedef VBOXDTVMEMCHUNK *PVBOXDTVMEMCHUNK; 697 698 699 700 /** 701 * Resource allocator instance. 702 */ 703 typedef struct VBoxDtVMem 704 { 705 /** Spinlock protecting the data. */ 706 RTSPINLOCK hSpinlock; 707 /** Magic value. */ 708 uint32_t u32Magic; 709 /** The current number of free items in the chunks. */ 710 uint32_t cCurFree; 711 /** The current number of chunks that we have allocated. */ 712 uint32_t cCurChunks; 713 /** The configured resource base. */ 714 uint32_t uBase; 715 /** The configured resource end (base included). */ 716 uint32_t uEnd; 717 /** The size of the apChunks array. */ 718 uint32_t cMaxChunks; 719 /** Array of chunk pointers. 720 * (The size is determined at creation.) */ 721 PVBOXDTVMEMCHUNK apChunks[1]; 722 } VBOXDTVMEM; 723 /** Pointer to a resource allocator instance. */ 724 typedef VBOXDTVMEM *PVBOXDTVMEM; 725 726 /** Magic value for the VBOXDTVMEM structure. */ 727 #define VBOXDTVMEM_MAGIC RT_MAKE_U32_FROM_U8('V', 'M', 'e', 'm') 728 729 730 /* vmem_create implementation */ 731 struct VBoxDtVMem *VBoxDtVMemCreate(const char *pszName, void *pvBase, size_t cb, size_t cbUnit, 732 PFNRT pfnAlloc, PFNRT pfnFree, struct VBoxDtVMem *pSrc, 733 size_t cbQCacheMax, uint32_t fFlags) 734 { 735 /* 736 * Assert preconditions of this implementation. 737 */ 738 AssertMsgReturn((uintptr_t)pvBase <= UINT32_MAX, ("%p\n", pvBase), NULL); 739 AssertMsgReturn((uintptr_t)pvBase + cb - 1 <= UINT32_MAX, ("%p %zu\n", pvBase, cb), NULL); 740 AssertMsgReturn(cbUnit == 1, ("%zu\n", cbUnit), NULL); 741 AssertReturn(!pfnAlloc, NULL); 742 AssertReturn(!pfnFree, NULL); 743 AssertReturn(!pSrc, NULL); 744 AssertReturn(!cbQCacheMax, NULL); 745 AssertReturn(fFlags & VM_SLEEP, NULL); 746 AssertReturn(fFlags & VMC_IDENTIFIER, NULL); 747 748 /* 749 * Allocate the instance. 750 */ 751 uint32_t cChunks = (uint32_t)(cb - (uintptr_t)pvBase); 752 cChunks += VBOXDTVMEMCHUNK_BITS - 1; 753 cChunks /= VBOXDTVMEMCHUNK_BITS; 754 PVBOXDTVMEM pThis = (PVBOXDTVMEM)RTMemAllocZ(RT_OFFSETOF(VBOXDTVMEM, apChunks[cChunks])); 755 if (!pThis) 756 return NULL; 757 int rc = RTSpinlockCreate(&pThis->hSpinlock); 758 if (RT_FAILURE(rc)) 759 { 760 RTMemFree(pThis); 761 return NULL; 762 } 763 pThis->u32Magic = VBOXDTVMEM_MAGIC; 764 pThis->cCurFree = 0; 765 pThis->cCurChunks = 0; 766 pThis->uBase = (uint32_t)(uintptr_t)pvBase; 767 pThis->uEnd = (uint32_t)cb; 768 pThis->cMaxChunks = cChunks; 769 770 return pThis; 771 } 772 773 774 /* vmem_destroy implementation */ 775 void VBoxDtVMemDestroy(struct VBoxDtVMem *pThis) 776 { 777 if (!pThis) 778 return; 779 AssertPtrReturnVoid(pThis); 780 AssertReturnVoid(pThis->u32Magic == VBOXDTVMEM_MAGIC); 781 782 /* 783 * Invalidate the instance. 784 */ 785 RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER; 786 RTSpinlockAcquireNoInts(pThis->hSpinlock, &Tmp); /* paranoia */ 787 pThis->u32Magic = 0; 788 RTSpinlockRelease(pThis->hSpinlock, &Tmp); 789 RTSpinlockDestroy(pThis->hSpinlock); 790 791 /* 792 * Free the chunks, then the instance. 793 */ 794 uint32_t iChunk = pThis->cCurChunks; 795 while (iChunk-- > 0) 796 { 797 RTMemFree(pThis->apChunks[iChunk]); 798 pThis->apChunks[iChunk] = NULL; 799 } 800 RTMemFree(pThis); 801 } 802 803 804 /* vmem_alloc implementation */ 805 void *VBoxDtVMemAlloc(struct VBoxDtVMem *pThis, size_t cbMem, uint32_t fFlags) 806 { 807 /* 808 * Validate input. 809 */ 810 AssertReturn(fFlags & VM_BESTFIT, NULL); 811 AssertReturn(fFlags & VM_SLEEP, NULL); 812 AssertReturn(cbMem == 1, NULL); 813 AssertPtrReturn(pThis, NULL); 814 AssertReturn(pThis->u32Magic == VBOXDTVMEM_MAGIC, NULL); 815 816 /* 817 * Allocation loop. 818 */ 819 RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER; 820 RTSpinlockAcquireNoInts(pThis->hSpinlock, &Tmp); 821 for (;;) 822 { 823 PVBOXDTVMEMCHUNK pChunk; 824 uint32_t const cChunks = pThis->cCurChunks; 825 826 if (RT_LIKELY(pThis->cCurFree > 0)) 827 { 828 for (uint32_t iChunk = 0; iChunk < cChunks; iChunk++) 829 { 830 pChunk = pThis->apChunks[iChunk]; 831 if (pChunk->cCurFree > 0) 832 { 833 int iBit = ASMBitFirstClear(pChunk->bm, VBOXDTVMEMCHUNK_BITS); 834 AssertMsgReturnStmt(iBit >= 0 && (unsigned)iBit < VBOXDTVMEMCHUNK_BITS, ("%d\n", iBit), 835 RTSpinlockRelease(pThis->hSpinlock, &Tmp), 836 NULL); 837 838 ASMBitSet(pChunk->bm, iBit); 839 pChunk->cCurFree--; 840 pThis->cCurFree--; 841 842 uint32_t iRet = (uint32_t)iBit + pChunk->iFirst + pThis->uBase; 843 RTSpinlockRelease(pThis->hSpinlock, &Tmp); 844 return (void *)(uintptr_t)iRet; 845 } 846 } 847 AssertFailedBreak(); 848 } 849 850 /* Out of resources? */ 851 if (cChunks >= pThis->cMaxChunks) 852 break; 853 854 /* 855 * Allocate another chunk. 856 */ 857 uint32_t const iFirstBit = cChunks > 0 ? pThis->apChunks[cChunks - 1]->iFirst + VBOXDTVMEMCHUNK_BITS : 0; 858 uint32_t const cFreeBits = cChunks + 1 == pThis->cMaxChunks 859 ? pThis->uEnd - pThis->uBase - iFirstBit 860 : VBOXDTVMEMCHUNK_BITS; 861 Assert(cFreeBits <= VBOXDTVMEMCHUNK_BITS); 862 863 RTSpinlockRelease(pThis->hSpinlock, &Tmp); 864 865 pChunk = (PVBOXDTVMEMCHUNK)RTMemAllocZ(sizeof(*pChunk)); 866 if (!pChunk) 867 return NULL; 868 869 pChunk->iFirst = iFirstBit; 870 pChunk->cCurFree = cFreeBits; 871 if (cFreeBits != VBOXDTVMEMCHUNK_BITS) 872 { 873 /* lazy bird. */ 874 uint32_t iBit = cFreeBits; 875 while (iBit < VBOXDTVMEMCHUNK_BITS) 876 { 877 ASMBitSet(pChunk->bm, iBit); 878 iBit++; 879 } 880 } 881 882 RTSpinlockAcquireNoInts(pThis->hSpinlock, &Tmp); 883 884 /* 885 * Insert the new chunk. If someone raced us here, we'll drop it to 886 * avoid wasting resources. 887 */ 888 if (pThis->cCurChunks == cChunks) 889 { 890 pThis->apChunks[cChunks] = pChunk; 891 pThis->cCurFree += pChunk->cCurFree; 892 pThis->cCurChunks += 1; 893 } 894 else 895 { 896 RTSpinlockRelease(pThis->hSpinlock, &Tmp); 897 RTMemFree(pChunk); 898 RTSpinlockAcquireNoInts(pThis->hSpinlock, &Tmp); 899 } 900 } 901 RTSpinlockRelease(pThis->hSpinlock, &Tmp); 902 903 return NULL; 904 } 905 906 /* vmem_free implementation */ 907 void VBoxDtVMemFree(struct VBoxDtVMem *pThis, void *pvMem, size_t cbMem) 908 { 909 /* 910 * Validate input. 911 */ 912 AssertReturnVoid(cbMem == 1); 913 AssertPtrReturnVoid(pThis); 914 AssertReturnVoid(pThis->u32Magic == VBOXDTVMEM_MAGIC); 915 916 AssertReturnVoid((uintptr_t)pvMem < UINT32_MAX); 917 uint32_t uMem = (uint32_t)(uintptr_t)pvMem; 918 AssertReturnVoid(uMem >= pThis->uBase); 919 AssertReturnVoid(uMem < pThis->uEnd); 920 921 uMem -= pThis->uBase; 922 923 /* 924 * Free it. 925 */ 926 RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER; 927 RTSpinlockAcquireNoInts(pThis->hSpinlock, &Tmp); 928 uint32_t const iChunk = uMem / VBOXDTVMEMCHUNK_BITS; 929 if (iChunk < pThis->cCurChunks) 930 { 931 PVBOXDTVMEMCHUNK pChunk = pThis->apChunks[iChunk]; 932 uint32_t iBit = uMem - pChunk->iFirst; 933 AssertReturnVoidStmt(iBit < VBOXDTVMEMCHUNK_BITS, RTSpinlockRelease(pThis->hSpinlock, &Tmp)); 934 AssertReturnVoidStmt(ASMBitTestAndClear(pChunk->bm, iBit), RTSpinlockRelease(pThis->hSpinlock, &Tmp)); 935 936 pChunk->cCurFree++; 937 pThis->cCurFree++; 938 } 939 940 RTSpinlockRelease(pThis->hSpinlock, &Tmp); 941 } 569 942 570 943 #if 0 571 944 VBoxDtMutexIsOwner 945 VBoxDtMutexExit 946 VBoxDtMutexEnter 947 948 VBoxDtKMemFree 949 VBoxDtKMemCacheFree 950 VBoxDtKMemCacheDestroy 951 VBoxDtKMemCacheCreate 952 VBoxDtKMemCacheAlloc 953 954 VBoxDtKMemAllocZ 955 VBoxDtKMemAlloc 956 957 VBoxDtGetKernelBase 958 VBoxDtGetCurrentThread 572 959 VBoxDtGetCurrentProc 573 VBoxDtGetCurrentThread574 VBoxDtGetKernelBase575 576 VBoxDtKMemAlloc577 VBoxDtKMemAllocZ578 VBoxDtKMemCacheAlloc579 VBoxDtKMemCacheCreate580 VBoxDtKMemCacheDestroy581 VBoxDtKMemCacheFree582 VBoxDtKMemFree583 VBoxDtMutexEnter584 VBoxDtMutexExit585 VBoxDtMutexIsOwner586 VBoxDtVMemAlloc587 VBoxDtVMemCreate588 VBoxDtVMemDestroy589 VBoxDtVMemFree590 591 592 dtrace_xcall593 nocrt_strncpy594 RTErrConvertToErrno595 960 #endif 596 961 597 962 598 599 #if 0 600 #define VBDTR0_IOC_OPEN UINT32_C(0xfeed0001) 601 602 DECLEXPORT(int) VBoxDTraceR0SrvReqHandler(PSUPDRVSESSION pSession, uint32_t uOperation, 603 uint64_t u64Arg, PSUPR0SERVICEREQHDR pReqHdr) 604 { 605 /* 606 * 607 */ 608 if (uOperation == VBDTR0_IOC_OPEN) 609 { 610 611 } 612 613 } 614 #endif 615 963 /* 964 * 965 * Helpers for handling VTG structures. 966 * Helpers for handling VTG structures. 967 * Helpers for handling VTG structures. 968 * 969 */ 970 971 972 973 /** 974 * Converts an attribute from VTG description speak to DTrace. 975 * 976 * @param pDtAttr The DTrace attribute (dst). 977 * @param pVtgAttr The VTG attribute descriptor (src). 978 */ 979 static void vboxDtVtgConvAttr(dtrace_attribute_t *pDtAttr, PCVTGDESCATTR pVtgAttr) 980 { 981 pDtAttr->dtat_name = pVtgAttr->u8Code - 1; 982 pDtAttr->dtat_data = pVtgAttr->u8Data - 1; 983 pDtAttr->dtat_class = pVtgAttr->u8DataDep - 1; 984 } 985 986 /** 987 * Gets a string from the string table. 988 * 989 * @returns Pointer to the string. 990 * @param pVtgHdr The VTG object header. 991 * @param offStrTab The string table offset. 992 */ 993 static const char *vboxDtVtgGetString(PVTGOBJHDR pVtgHdr, uint32_t offStrTab) 994 { 995 Assert(offStrTab < pVtgHdr->cbStrTab); 996 return &pVtgHdr->pachStrTab[offStrTab]; 997 } 998 999 1000 1001 /* 1002 * 1003 * DTrace Provider Interface. 1004 * DTrace Provider Interface. 1005 * DTrace Provider Interface. 1006 * 1007 */ 1008 1009 1010 /** 1011 * @callback_method_impl{dtrace_pops_t,dtps_provide} 1012 */ 1013 static void vboxDtPOps_Provide(void *pvProv, const dtrace_probedesc_t *pDtProbeDesc) 1014 { 1015 PSUPDRVVDTPROVIDERCORE pProv = (PSUPDRVVDTPROVIDERCORE)pvProv; 1016 PVTGPROBELOC pProbeLoc = pProv->pHdr->paProbLocs; 1017 PVTGPROBELOC pProbeLocEnd = pProv->pHdr->paProbLocsEnd; 1018 dtrace_provider_id_t idProvider = pProv->TracerData.DTrace.idProvider; 1019 size_t const cbFnNmBuf = _4K + _1K; 1020 char *pszFnNmBuf; 1021 uint16_t idxProv; 1022 1023 if (pDtProbeDesc) 1024 return; /* We don't generate probes, so never mind these requests. */ 1025 1026 if (pProv->TracerData.DTrace.fZombie) 1027 return; 1028 1029 if (pProv->TracerData.DTrace.cProvidedProbes >= pProbeLocEnd - pProbeLoc) 1030 return; 1031 1032 /* Need a buffer for extracting the function names and mangling them in 1033 case of collision. */ 1034 pszFnNmBuf = (char *)RTMemAlloc(cbFnNmBuf); 1035 if (!pszFnNmBuf) 1036 return; 1037 1038 /* 1039 * Itereate the probe location list and register all probes related to 1040 * this provider. 1041 */ 1042 idxProv = (uint16_t)(&pProv->pHdr->paProviders[0] - pProv->pDesc); 1043 while ((uintptr_t)pProbeLoc < (uintptr_t)pProbeLocEnd) 1044 { 1045 PVTGDESCPROBE pProbeDesc = (PVTGDESCPROBE)pProbeLoc->pbProbe; 1046 if ( pProbeDesc->idxProvider == idxProv 1047 && pProbeLoc->idProbe == UINT32_MAX) 1048 { 1049 /* The function name normally needs to be stripped since we're 1050 using C++ compilers for most of the code. ASSUMES nobody are 1051 brave/stupid enough to use function pointer returns without 1052 typedef'ing properly them. */ 1053 const char *pszPrbName = vboxDtVtgGetString(pProv->pHdr, pProbeDesc->offName); 1054 const char *pszFunc = pProbeLoc->pszFunction; 1055 const char *psz = strchr(pProbeLoc->pszFunction, '('); 1056 size_t cch; 1057 if (psz) 1058 { 1059 /* skip blanks preceeding the parameter parenthesis. */ 1060 while ( (uintptr_t)psz > (uintptr_t)pProbeLoc->pszFunction 1061 && RT_C_IS_BLANK(psz[-1])) 1062 psz--; 1063 1064 /* Find the start of the function name. */ 1065 pszFunc = psz - 1; 1066 while ((uintptr_t)pszFunc > (uintptr_t)pProbeLoc->pszFunction) 1067 { 1068 char ch = pszFunc[-1]; 1069 if (!RT_C_IS_ALNUM(ch) && ch != '_' && ch != ':') 1070 break; 1071 pszFunc--; 1072 } 1073 cch = psz - pszFunc; 1074 } 1075 else 1076 cch = strlen(pszFunc); 1077 RTStrCopyEx(pszFnNmBuf, cbFnNmBuf, pszFunc, cch); 1078 1079 /* Look up the probe, if we have one in the same function, mangle 1080 the function name a little to avoid having to deal with having 1081 multiple location entries with the same probe ID. (lazy bird) */ 1082 Assert(pProbeLoc->idProbe == UINT32_MAX); 1083 if (dtrace_probe_lookup(idProvider, pProv->pszModName, pszFnNmBuf, pszPrbName) != DTRACE_IDNONE) 1084 { 1085 RTStrPrintf(pszFnNmBuf+cch, cbFnNmBuf - cch, "-%u", pProbeLoc->uLine); 1086 if (dtrace_probe_lookup(idProvider, pProv->pszModName, pszFnNmBuf, pszPrbName) != DTRACE_IDNONE) 1087 { 1088 unsigned iOrd = 2; 1089 while (iOrd < 128) 1090 { 1091 RTStrPrintf(pszFnNmBuf+cch, cbFnNmBuf - cch, "-%u-%u", pProbeLoc->uLine, iOrd); 1092 if (dtrace_probe_lookup(idProvider, pProv->pszModName, pszFnNmBuf, pszPrbName) == DTRACE_IDNONE) 1093 break; 1094 iOrd++; 1095 } 1096 if (iOrd >= 128) 1097 { 1098 LogRel(("VBoxDrv: More than 128 duplicate probe location instances in file %s at line %u, function %s [%s], probe %s\n", 1099 pProbeLoc->pszFile, pProbeLoc->uLine, pProbeLoc->pszFunction, pszFnNmBuf, pszPrbName)); 1100 continue; 1101 } 1102 } 1103 } 1104 1105 /* Create the probe. */ 1106 AssertCompile(sizeof(pProbeLoc->idProbe) == sizeof(dtrace_id_t)); 1107 pProbeLoc->idProbe = dtrace_probe_create(idProvider, pProv->pszModName, pszFnNmBuf, pszPrbName, 1108 0 /*aframes*/, pProbeLoc); 1109 pProv->TracerData.DTrace.cProvidedProbes++; 1110 } 1111 1112 pProbeLoc++; 1113 } 1114 1115 RTMemFree(pszFnNmBuf); 1116 } 1117 1118 1119 /** 1120 * @callback_method_impl{dtrace_pops_t,dtps_enable} 1121 */ 1122 static int vboxDtPOps_Enable(void *pvProv, dtrace_id_t idProbe, void *pvProbe) 1123 { 1124 PSUPDRVVDTPROVIDERCORE pProv = (PSUPDRVVDTPROVIDERCORE)pvProv; 1125 if (!pProv->TracerData.DTrace.fZombie) 1126 { 1127 PVTGPROBELOC pProbeLoc = (PVTGPROBELOC)pvProbe; 1128 PVTGDESCPROBE pProbeDesc = (PVTGDESCPROBE)pProbeLoc->pbProbe; 1129 1130 if (!pProbeLoc->fEnabled) 1131 { 1132 pProbeLoc->fEnabled = 1; 1133 if (ASMAtomicIncU32(&pProbeDesc->u32User) == 1) 1134 pProv->pHdr->pafProbeEnabled[pProbeDesc->idxEnabled] = 1; 1135 } 1136 } 1137 1138 return 0; 1139 } 1140 1141 1142 /** 1143 * @callback_method_impl{dtrace_pops_t,dtps_disable} 1144 */ 1145 static void vboxDtPOps_Disable(void *pvProv, dtrace_id_t idProbe, void *pvProbe) 1146 { 1147 PSUPDRVVDTPROVIDERCORE pProv = (PSUPDRVVDTPROVIDERCORE)pvProv; 1148 if (!pProv->TracerData.DTrace.fZombie) 1149 { 1150 PVTGPROBELOC pProbeLoc = (PVTGPROBELOC)pvProbe; 1151 PVTGDESCPROBE pProbeDesc = (PVTGDESCPROBE)pProbeLoc->pbProbe; 1152 1153 if (pProbeLoc->fEnabled) 1154 { 1155 pProbeLoc->fEnabled = 0; 1156 if (ASMAtomicDecU32(&pProbeDesc->u32User) == 0) 1157 pProv->pHdr->pafProbeEnabled[pProbeDesc->idxEnabled] = 1; 1158 } 1159 } 1160 } 1161 1162 1163 /** 1164 * @callback_method_impl{dtrace_pops_t,dtps_getargdesc} 1165 */ 1166 static void vboxDtPOps_GetArgDesc(void *pvProv, dtrace_id_t idProbe, void *pvProbe, 1167 dtrace_argdesc_t *pArgDesc) 1168 { 1169 PSUPDRVVDTPROVIDERCORE pProv = (PSUPDRVVDTPROVIDERCORE)pvProv; 1170 unsigned uArg = pArgDesc->dtargd_ndx; 1171 1172 if (!pProv->TracerData.DTrace.fZombie) 1173 { 1174 PVTGPROBELOC pProbeLoc = (PVTGPROBELOC)pvProbe; 1175 PVTGDESCPROBE pProbeDesc = (PVTGDESCPROBE)pProbeLoc->pbProbe; 1176 PVTGDESCARGLIST pArgList = (PVTGDESCARGLIST)((uintptr_t)pProv->pHdr->paArgLists + pProbeDesc->offArgList); 1177 1178 Assert(pProbeDesc->offArgList < pProv->pHdr->cbArgLists); 1179 if (pArgList->cArgs > uArg) 1180 { 1181 const char *pszType = vboxDtVtgGetString(pProv->pHdr, pArgList->aArgs[uArg].offType); 1182 size_t cchType = strlen(pszType); 1183 if (cchType < sizeof(pArgDesc->dtargd_native)) 1184 { 1185 memcpy(pArgDesc->dtargd_native, pszType, cchType + 1); 1186 /** @todo mapping */ 1187 return; 1188 } 1189 } 1190 } 1191 1192 pArgDesc->dtargd_ndx = DTRACE_ARGNONE; 1193 } 1194 1195 1196 /** 1197 * @callback_method_impl{dtrace_pops_t,dtps_getargval} 1198 */ 1199 static uint64_t vboxDtPOps_GetArgVal(void *pvProv, dtrace_id_t idProbe, void *pvProbe, 1200 int iArg, int cFrames) 1201 { 1202 PVBDTSTACKDATA pData = vboxDtGetStackData(); 1203 AssertReturn(iArg >= 5, UINT64_MAX); 1204 1205 if (pData->enmCaller == kVBoxDtCaller_ProbeFireKernel) 1206 return pData->u.ProbeFireKernel.pauStackArgs[iArg - 5]; 1207 1208 if (pData->enmCaller == kVBoxDtCaller_ProbeFireUser) 1209 { 1210 PCSUPDRVTRACERUSRCTX pCtx = pData->u.ProbeFireUser.pCtx; 1211 if (pCtx->cBits == 32) 1212 { 1213 if ((unsigned)iArg < RT_ELEMENTS(pCtx->u.X86.aArgs)) 1214 return pCtx->u.X86.aArgs[iArg]; 1215 } 1216 else if (pCtx->cBits == 64) 1217 { 1218 if ((unsigned)iArg < RT_ELEMENTS(pCtx->u.Amd64.aArgs)) 1219 return pCtx->u.Amd64.aArgs[iArg]; 1220 } 1221 else 1222 AssertFailed(); 1223 } 1224 1225 return UINT64_MAX; 1226 } 1227 1228 1229 /** 1230 * @callback_method_impl{dtrace_pops_t,dtps_destroy} 1231 */ 1232 static void vboxDtPOps_Destroy(void *pvProv, dtrace_id_t idProbe, void *pvProbe) 1233 { 1234 PSUPDRVVDTPROVIDERCORE pProv = (PSUPDRVVDTPROVIDERCORE)pvProv; 1235 if (!pProv->TracerData.DTrace.fZombie) 1236 { 1237 PVTGPROBELOC pProbeLoc = (PVTGPROBELOC)pvProbe; 1238 Assert(!pProbeLoc->fEnabled); 1239 Assert(pProbeLoc->idProbe == idProbe); NOREF(idProbe); 1240 pProbeLoc->idProbe = UINT32_MAX; 1241 } 1242 pProv->TracerData.DTrace.cProvidedProbes--; 1243 } 1244 1245 1246 1247 /** 1248 * DTrace provider method table. 1249 */ 1250 static const dtrace_pops_t g_vboxDtVtgProvOps = 1251 { 1252 /* .dtps_provide = */ vboxDtPOps_Provide, 1253 /* .dtps_provide_module = */ NULL, 1254 /* .dtps_enable = */ vboxDtPOps_Enable, 1255 /* .dtps_disable = */ vboxDtPOps_Disable, 1256 /* .dtps_suspend = */ NULL, 1257 /* .dtps_resume = */ NULL, 1258 /* .dtps_getargdesc = */ vboxDtPOps_GetArgDesc, 1259 /* .dtps_getargval = */ vboxDtPOps_GetArgVal, 1260 /* .dtps_usermode = */ NULL, 1261 /* .dtps_destroy = */ vboxDtPOps_Destroy 1262 }; 1263 1264 1265 1266 1267 /* 1268 * 1269 * Support Driver Tracer Interface. 1270 * Support Driver Tracer Interface. 1271 * Support Driver Tracer Interface. 1272 * 1273 */ 1274 1275 1276 1277 /** 1278 * interface_method_impl{SUPDRVTRACERREG,pfnProbeFireUser} 1279 */ 1280 static DECLCALLBACK(void) vbdt_ProbeFireKernel(struct VTGPROBELOC *pVtgProbeLoc, uintptr_t uArg0, uintptr_t uArg1, uintptr_t uArg2, 1281 uintptr_t uArg3, uintptr_t uArg4) 1282 { 1283 VBDT_SETUP_STACK_DATA(kVBoxDtCaller_ProbeFireKernel); 1284 1285 pStackData->u.ProbeFireKernel.uCaller = (uintptr_t)ASMReturnAddress(); 1286 pStackData->u.ProbeFireKernel.pauStackArgs = &uArg4 + 1; 1287 dtrace_probe(pVtgProbeLoc->idProbe, uArg0, uArg1, uArg2, uArg3, uArg4); 1288 1289 VBDT_CLEAR_STACK_DATA(); 1290 return ; 1291 } 1292 1293 1294 /** 1295 * interface_method_impl{SUPDRVTRACERREG,pfnProbeFireUser} 1296 */ 1297 static DECLCALLBACK(void) vbdt_ProbeFireUser(PCSUPDRVTRACERREG pThis, PSUPDRVSESSION pSession, PCSUPDRVTRACERUSRCTX pCtx) 1298 { 1299 VBDT_SETUP_STACK_DATA(kVBoxDtCaller_ProbeFireUser); 1300 1301 pStackData->u.ProbeFireUser.pCtx = pCtx; 1302 if (pCtx->cBits == 32) 1303 dtrace_probe(pCtx->idProbe, 1304 pCtx->u.X86.aArgs[0], 1305 pCtx->u.X86.aArgs[1], 1306 pCtx->u.X86.aArgs[2], 1307 pCtx->u.X86.aArgs[3], 1308 pCtx->u.X86.aArgs[4]); 1309 else if (pCtx->cBits == 64) 1310 dtrace_probe(pCtx->idProbe, 1311 pCtx->u.Amd64.aArgs[0], 1312 pCtx->u.Amd64.aArgs[1], 1313 pCtx->u.Amd64.aArgs[2], 1314 pCtx->u.Amd64.aArgs[3], 1315 pCtx->u.Amd64.aArgs[4]); 1316 else 1317 AssertFailed(); 1318 1319 VBDT_CLEAR_STACK_DATA(); 1320 } 1321 1322 1323 /** 1324 * interface_method_impl{SUPDRVTRACERREG,pfnTracerOpen} 1325 */ 1326 static DECLCALLBACK(int) vbdt_TracerOpen(PCSUPDRVTRACERREG pThis, PSUPDRVSESSION pSession, uint32_t uCookie, uintptr_t uArg, 1327 uintptr_t *puSessionData) 1328 { 1329 if (uCookie != RT_MAKE_U32_FROM_U8('V', 'B', 'D', 'T')) 1330 return VERR_INVALID_MAGIC; 1331 if (uArg) 1332 return VERR_INVALID_PARAMETER; 1333 1334 VBDT_SETUP_STACK_DATA(kVBoxDtCaller_Generic); 1335 1336 int rc = dtrace_open((dtrace_state_t **)puSessionData, VBoxDtGetCurrentCreds()); 1337 1338 VBDT_CLEAR_STACK_DATA(); 1339 return RTErrConvertFromErrno(rc); 1340 } 1341 1342 1343 /** 1344 * interface_method_impl{SUPDRVTRACERREG,pfnTracerClose} 1345 */ 1346 static DECLCALLBACK(int) vbdt_TracerIoCtl(PCSUPDRVTRACERREG pThis, PSUPDRVSESSION pSession, uintptr_t uSessionData, 1347 uintptr_t uCmd, uintptr_t uArg, int32_t *piRetVal) 1348 { 1349 AssertPtrReturn(uSessionData, VERR_INVALID_POINTER); 1350 VBDT_SETUP_STACK_DATA(kVBoxDtCaller_Generic); 1351 1352 int rc = dtrace_ioctl((dtrace_state_t *)uSessionData, (intptr_t)uCmd, (intptr_t)uArg, piRetVal); 1353 1354 VBDT_CLEAR_STACK_DATA(); 1355 return VINF_SUCCESS; 1356 } 1357 1358 1359 /** 1360 * interface_method_impl{SUPDRVTRACERREG,pfnTracerClose} 1361 */ 1362 static DECLCALLBACK(void) vbdt_TracerClose(PCSUPDRVTRACERREG pThis, PSUPDRVSESSION pSession, uintptr_t uSessionData) 1363 { 1364 AssertPtrReturnVoid(uSessionData); 1365 VBDT_SETUP_STACK_DATA(kVBoxDtCaller_Generic); 1366 1367 dtrace_close((dtrace_state_t *)uSessionData); 1368 1369 VBDT_CLEAR_STACK_DATA(); 1370 } 1371 1372 1373 /** 1374 * interface_method_impl{SUPDRVTRACERREG,pfnProviderRegister} 1375 */ 1376 static DECLCALLBACK(int) vbdt_ProviderRegister(PCSUPDRVTRACERREG pThis, PSUPDRVVDTPROVIDERCORE pCore) 1377 { 1378 AssertReturn(pCore->TracerData.DTrace.idProvider == UINT32_MAX || pCore->TracerData.DTrace.idProvider == 0, 1379 VERR_INTERNAL_ERROR_3); 1380 VBDT_SETUP_STACK_DATA(kVBoxDtCaller_Generic); 1381 1382 PVTGDESCPROVIDER pDesc = pCore->pDesc; 1383 dtrace_pattr_t DtAttrs; 1384 vboxDtVtgConvAttr(&DtAttrs.dtpa_provider, &pDesc->AttrSelf); 1385 vboxDtVtgConvAttr(&DtAttrs.dtpa_mod, &pDesc->AttrModules); 1386 vboxDtVtgConvAttr(&DtAttrs.dtpa_func, &pDesc->AttrFunctions); 1387 vboxDtVtgConvAttr(&DtAttrs.dtpa_name, &pDesc->AttrNames); 1388 vboxDtVtgConvAttr(&DtAttrs.dtpa_args, &pDesc->AttrArguments); 1389 1390 dtrace_provider_id_t idProvider; 1391 int rc = dtrace_register(pCore->pszName, 1392 &DtAttrs, 1393 DTRACE_PRIV_KERNEL, 1394 NULL /* cred */, 1395 &g_vboxDtVtgProvOps, 1396 pCore, 1397 &idProvider); 1398 if (!rc) 1399 { 1400 Assert(idProvider != UINT32_MAX && idProvider != 0); 1401 pCore->TracerData.DTrace.idProvider = idProvider; 1402 Assert(pCore->TracerData.DTrace.idProvider == idProvider); 1403 rc = VINF_SUCCESS; 1404 } 1405 else 1406 rc = RTErrConvertFromErrno(rc); 1407 1408 VBDT_CLEAR_STACK_DATA(); 1409 return rc; 1410 } 1411 1412 1413 /** 1414 * interface_method_impl{SUPDRVTRACERREG,pfnProviderDeregister} 1415 */ 1416 static DECLCALLBACK(int) vbdt_ProviderDeregister(PCSUPDRVTRACERREG pThis, PSUPDRVVDTPROVIDERCORE pCore) 1417 { 1418 uint32_t idProvider = pCore->TracerData.DTrace.idProvider; 1419 AssertReturn(idProvider != UINT32_MAX && idProvider != 0, VERR_INTERNAL_ERROR_4); 1420 VBDT_SETUP_STACK_DATA(kVBoxDtCaller_Generic); 1421 1422 dtrace_invalidate(idProvider); 1423 int rc = dtrace_unregister(idProvider); 1424 if (!rc) 1425 { 1426 pCore->TracerData.DTrace.idProvider = UINT32_MAX; 1427 rc = VINF_SUCCESS; 1428 } 1429 else 1430 { 1431 AssertMsg(rc == EBUSY, ("%d\n", rc)); 1432 rc = VERR_TRY_AGAIN; 1433 } 1434 1435 VBDT_CLEAR_STACK_DATA(); 1436 return rc; 1437 } 1438 1439 1440 /** 1441 * interface_method_impl{SUPDRVTRACERREG,pfnProviderDeregisterZombie} 1442 */ 1443 static DECLCALLBACK(int) vbdt_ProviderDeregisterZombie(PCSUPDRVTRACERREG pThis, PSUPDRVVDTPROVIDERCORE pCore) 1444 { 1445 uint32_t idProvider = pCore->TracerData.DTrace.idProvider; 1446 AssertReturn(idProvider != UINT32_MAX && idProvider != 0, VERR_INTERNAL_ERROR_4); 1447 VBDT_SETUP_STACK_DATA(kVBoxDtCaller_Generic); 1448 1449 int rc = dtrace_unregister(idProvider); 1450 if (!rc) 1451 { 1452 pCore->TracerData.DTrace.idProvider = UINT32_MAX; 1453 rc = VINF_SUCCESS; 1454 } 1455 else 1456 { 1457 AssertMsg(rc == EBUSY, ("%d\n", rc)); 1458 rc = VERR_TRY_AGAIN; 1459 } 1460 1461 VBDT_CLEAR_STACK_DATA(); 1462 return rc; 1463 } 1464 1465 1466 1467 /** 1468 * The tracer registration record of the VBox DTrace implementation 1469 */ 1470 static SUPDRVTRACERREG g_VBoxDTraceReg = 1471 { 1472 SUPDRVTRACERREG_MAGIC, 1473 SUPDRVTRACERREG_VERSION, 1474 vbdt_ProbeFireKernel, 1475 vbdt_ProbeFireUser, 1476 vbdt_TracerOpen, 1477 vbdt_TracerIoCtl, 1478 vbdt_TracerClose, 1479 vbdt_ProviderRegister, 1480 vbdt_ProviderDeregister, 1481 vbdt_ProviderDeregisterZombie, 1482 SUPDRVTRACERREG_MAGIC 1483 }; 1484 -
trunk/src/VBox/ExtPacks/VBoxDTrace/include/VBoxDTraceTypes.h
r53665 r53667 230 230 231 231 232 typedef struct VBoxDtProcess 232 typedef struct VBoxDtProcess proc_t; 233 # if 0 /* not needed ? */ 234 struct VBoxDtProcess proc_t; 233 235 { 234 uint32_t p_flag; 236 /* uint32_t p_flag; - don't bother with this */ 235 237 RTPROCESS p_pid; 236 238 struct dtrace_helpers *p_dtrace_helpers; 237 struct VBoxDtCred *p_cred; 238 } proc_t; 239 } 239 240 proc_t *VBoxDtGetCurrentProc(void); 240 #define curproc (VBoxDtGetCurrentProc()) 241 242 #define SNOCD RT_BIT(0) 243 241 # define curproc (VBoxDtGetCurrentProc()) 242 /*# define SNOCD RT_BIT(0) - don't bother with this */ 243 # endif 244 244 245 245 typedef struct VBoxDtTaskQueue taskq_t; … … 331 331 332 332 333 typedef struct VBoxDtVMem 334 { 335 size_t cbTodo; 336 void *pvTodo; 337 } vmem_t; 333 typedef struct VBoxDtVMem vmem_t; 338 334 #define VM_SLEEP RT_BIT(0) 339 335 #define VM_BESTFIT RT_BIT(1) … … 372 368 * DDI 373 369 */ 374 #define DDI_SUCCESS (0) 375 #define DDI_FAILURE (-1) 376 #define ddi_soft_state_init VBoxDtDdiSoftStateInit 377 #define ddi_soft_state_fini VBoxDtDdiSoftStateTerm 378 #define ddi_soft_state_zalloc VBoxDtDdiSoftStateAllocZ 379 #define ddi_get_soft_state VBoxDtDdiSoftStateGet 380 #define ddi_soft_state_free VBoxDtDdiSoftStateFree 370 # define DDI_SUCCESS (0) 371 # define DDI_FAILURE (-1) 372 # if 0 /* not needed */ 373 # define ddi_soft_state_init VBoxDtDdiSoftStateInit 374 # define ddi_soft_state_fini VBoxDtDdiSoftStateTerm 375 # define ddi_soft_state_zalloc VBoxDtDdiSoftStateAllocZ 376 # define ddi_get_soft_state VBoxDtDdiSoftStateGet 377 # define ddi_soft_state_free VBoxDtDdiSoftStateFree 381 378 int VBoxDtDdiSoftStateInit(void **ppvSoftStates, size_t cbSoftState, uint32_t cMaxItems); 382 379 int VBoxDtDdiSoftStateTerm(void **ppvSoftStates); … … 384 381 int VBoxDtDdiSoftStateFree(void *pvSoftStates, RTDEV uMinor); 385 382 void *VBoxDtDdiSoftStateGet(void *pvSoftStates, RTDEV uMinor); 386 387 typedef struct VBoxDtDevInfo dev_info_t; 383 # endif 384 388 385 typedef enum { DDI_ATT_CMD_DUMMY } ddi_attach_cmd_t; 389 386 typedef enum { DDI_DETACH, DDI_SUSPEND } ddi_detach_cmd_t; 390 #define ddi_driver_major VBoxDtDdiDriverMajor 391 #define ddi_report_dev VBoxDtDdiReportDev 387 # if 0 /* not needed */ 388 typedef struct VBoxDtDevInfo dev_info_t; 389 # define ddi_driver_major VBoxDtDdiDriverMajor 390 # define ddi_report_dev VBoxDtDdiReportDev 392 391 major_t VBoxDtDdiDriverMajor(struct VBoxDtDevInfo *pDevInfo); 393 392 void VBoxDtDdiReportDev(struct VBoxDtDevInfo *pDevInfo); 393 # endif 394 394 395 395 /* 396 396 * DTrace bits we've made external. 397 397 */ 398 extern int dtrace_attach(dev_info_t *devi, ddi_attach_cmd_t cmd); 399 extern int dtrace_detach(dev_info_t *dip, ddi_detach_cmd_t cmd); 400 extern int dtrace_ioctl(dev_t dev, int cmd, intptr_t arg, int md, cred_t *cr, int *rv); 398 extern int dtrace_attach(ddi_attach_cmd_t cmd); 399 extern int dtrace_detach(ddi_detach_cmd_t cmd); 400 struct dtrace_state; 401 extern int dtrace_open(struct dtrace_state **ppState, struct VBoxDtCred *cred_p); 402 extern int dtrace_ioctl(struct dtrace_state *state, int cmd, intptr_t arg, int32_t *rv); 403 extern int dtrace_close(struct dtrace_state *state); 401 404 402 405 #endif /* IN_RING0 */ -
trunk/src/VBox/ExtPacks/VBoxDTrace/onnv/uts/common/dtrace/dtrace.c
r53666 r53667 206 206 * DTrace Internal Variables 207 207 */ 208 #ifndef VBOX 208 209 static dev_info_t *dtrace_devi; /* device info */ 210 #endif 209 211 static vmem_t *dtrace_arena; /* probe ID arena */ 212 #ifndef VBOX 210 213 static vmem_t *dtrace_minor; /* minor number arena */ 211 #ifndef VBOX212 214 static taskq_t *dtrace_taskq; /* task queue */ 213 215 #endif … … 218 220 static int dtrace_opens; /* number of opens */ 219 221 static int dtrace_helpers; /* number of helpers */ 222 #ifndef VBOX 220 223 static void *dtrace_softstate; /* softstate pointer */ 224 #endif 221 225 static dtrace_hash_t *dtrace_bymod; /* probes hashed by module */ 222 226 static dtrace_hash_t *dtrace_byfunc; /* probes hashed by function */ … … 518 522 static void dtrace_enabling_matchall(void); 519 523 static dtrace_state_t *dtrace_anon_grab(void); 524 #ifndef VBOX 520 525 static uint64_t dtrace_helper(int, dtrace_mstate_t *, 521 526 dtrace_state_t *, uint64_t, uint64_t); 522 527 static dtrace_helpers_t *dtrace_helpers_create(proc_t *); 528 #endif 523 529 static void dtrace_buffer_drop(dtrace_buffer_t *); 524 530 static intptr_t dtrace_buffer_reserve(dtrace_buffer_t *, size_t, size_t, … … 1152 1158 dtrace_priv_proc_common_nocd(VBDTVOID) 1153 1159 { 1160 #ifndef VBOX 1154 1161 proc_t *proc; 1155 1162 … … 1159 1166 1160 1167 return (0); 1168 #else 1169 return (1); 1170 #endif 1161 1171 } 1162 1172 … … 2519 2529 } 2520 2530 2531 #ifdef VBOX 2532 /** */ 2533 static DECLCALLBACK(void) dtrace_speculation_clean_here_wrapper(RTCPUID idCpu, void *pvUser1, void *pvUser2) 2534 { 2535 dtrace_speculation_clean_here((dtrace_state_t *)pvUser1); 2536 NOREF(pvUser2); NOREF(idCpu); 2537 } 2538 #endif 2539 2521 2540 /* 2522 2541 * Note: not called from probe context. This function is called … … 2549 2568 return; 2550 2569 2570 #ifndef VBOX 2551 2571 dtrace_xcall(DTRACE_CPUALL, 2552 2572 (dtrace_xcall_t)dtrace_speculation_clean_here, state); 2573 #else 2574 RTMpOnAll(dtrace_speculation_clean_here_wrapper, state, NULL); 2575 #endif 2553 2576 2554 2577 /* … … 5692 5715 break; 5693 5716 5717 #ifndef VBOX 5694 5718 sym = (char *)(uintptr_t)dtrace_helper( 5695 5719 DTRACE_HELPER_ACTION_USTACK, 5696 5720 mstate, state, pcs[i], fps[i]); 5721 #else 5722 sym = NULL; 5723 #endif 5697 5724 5698 5725 /* … … 5929 5956 s_cr->cr_gid != cr->cr_rgid || 5930 5957 s_cr->cr_gid != cr->cr_sgid || 5958 #ifndef VBOX 5931 5959 (proc = VBDT_GET_PROC()) == NULL || 5932 5960 (proc->p_flag & SNOCD)) 5961 #else 5962 0) 5963 5964 #endif 5933 5965 continue; 5934 5966 } … … 6105 6137 } 6106 6138 6139 #ifndef VBOX /* no helpers */ 6107 6140 if (DTRACE_USTACK_STRSIZE(rec->dtrd_arg) != 0 && 6108 6141 curproc->p_dtrace_helpers != NULL) { … … 6119 6152 continue; 6120 6153 } 6154 #endif 6121 6155 6122 6156 DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT); … … 7277 7311 */ 7278 7312 ASSERT(old == dtrace_provider); 7313 #ifndef VBOX 7279 7314 ASSERT(dtrace_devi != NULL); 7315 #endif 7280 7316 ASSERT(MUTEX_HELD(&dtrace_provider_lock)); 7281 7317 ASSERT(MUTEX_HELD(&dtrace_lock)); … … 7380 7416 7381 7417 if ((prev = dtrace_provider) == old) { 7418 #ifndef VBOX 7382 7419 ASSERT(self || dtrace_devi == NULL); 7383 7420 ASSERT(old->dtpv_next == NULL || dtrace_devi == NULL); 7421 #endif 7384 7422 dtrace_provider = old->dtpv_next; 7385 7423 } else { … … 10348 10386 } 10349 10387 10388 #ifdef VBOX 10389 static DECLCALLBACK(void) dtrace_buffer_switch_wrapper(RTCPUID idCpu, void *pvUser1, void *pvUser2) 10390 { 10391 dtrace_buffer_switch((dtrace_buffer_t *)pvUser1); 10392 NOREF(pvUser2); NOREF(idCpu); 10393 } 10394 #endif 10395 10350 10396 /* 10351 10397 * Note: called from cross call context. This function activates a buffer … … 10374 10420 dtrace_interrupt_enable(cookie); 10375 10421 } 10422 10423 #ifdef VBOX 10424 static DECLCALLBACK(void) dtrace_buffer_activate_wrapper(RTCPUID idCpu, void *pvUser1, void *pvUser2) 10425 { 10426 dtrace_buffer_activate((dtrace_state_t *)pvUser1); 10427 NOREF(pvUser2); NOREF(idCpu); 10428 } 10429 #endif 10376 10430 10377 10431 static int … … 12451 12505 12452 12506 VBDTSTATIC dtrace_state_t * 12507 #ifdef VBOX 12508 dtrace_state_create(cred_t *cr) 12509 #else 12453 12510 dtrace_state_create(dev_t *devp, cred_t *cr) 12511 #endif 12454 12512 { 12455 12513 minor_t minor; … … 12463 12521 ASSERT(MUTEX_HELD(&cpu_lock)); 12464 12522 12523 #ifndef VBOX 12465 12524 minor = (minor_t)(uintptr_t)vmem_alloc(dtrace_minor, 1, 12466 12525 VM_BESTFIT | VM_SLEEP); … … 12472 12531 12473 12532 state = ddi_get_soft_state(dtrace_softstate, minor); 12533 #else 12534 state = kmem_alloc(sizeof (*state), KM_SLEEP); 12535 if (!state) { 12536 return (NULL); 12537 } 12538 #endif 12474 12539 state->dts_epid = DTRACE_EPIDNONE + 1; 12475 12540 … … 12478 12543 NULL, NULL, NULL, 0, VM_SLEEP | VMC_IDENTIFIER); 12479 12544 12545 #ifndef VBOX 12480 12546 if (devp != NULL) { 12481 12547 major = getemajor(*devp); … … 12488 12554 if (devp != NULL) 12489 12555 *devp = state->dts_dev; 12556 #endif 12490 12557 12491 12558 /* … … 13031 13098 * processing all of them. 13032 13099 */ 13100 #ifndef VBOX 13033 13101 dtrace_xcall(DTRACE_CPUALL, 13034 13102 (dtrace_xcall_t)dtrace_buffer_activate, state); 13103 #else 13104 RTMpOnAll(dtrace_buffer_activate_wrapper, state, NULL); 13105 #endif 13035 13106 goto out; 13036 13107 … … 13178 13249 dtrace_ecb_t *ecb; 13179 13250 dtrace_vstate_t *vstate = &state->dts_vstate; 13251 #ifndef VBOX 13180 13252 minor_t minor = getminor(state->dts_dev); 13253 #endif 13181 13254 int i, bufsize = NCPU * sizeof (dtrace_buffer_t); 13182 13255 dtrace_speculation_t *spec = state->dts_speculations; … … 13285 13358 13286 13359 vmem_destroy(state->dts_aggid_arena); 13360 #ifndef VBOX 13287 13361 ddi_soft_state_free(dtrace_softstate, minor); 13288 13362 vmem_free(dtrace_minor, (void *)(uintptr_t)minor, 1); 13363 #else 13364 kmem_free(state, sizeof (*state)); 13365 #endif 13289 13366 } 13290 13367 … … 13420 13497 * DTrace Helper Functions 13421 13498 */ 13499 #ifndef VBOX /* No helper stuff */ 13422 13500 static void 13423 13501 dtrace_helper_trace(dtrace_helper_action_t *helper, … … 14415 14493 } 14416 14494 14417 #ifndef VBOX14418 14419 14495 /* 14420 14496 * DTrace Hook Functions … … 14697 14773 * DTrace Driver Cookbook Functions 14698 14774 */ 14699 #ifndef VBOX 14775 #ifdef VBOX 14776 int dtrace_attach(ddi_attach_cmd_t cmd) 14777 #else 14700 14778 /*ARGSUSED*/ 14701 14779 static int 14702 14780 dtrace_attach(dev_info_t *devi, ddi_attach_cmd_t cmd) 14703 #else14704 int dtrace_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)14705 14781 #endif 14706 14782 { … … 14713 14789 mutex_enter(&dtrace_lock); 14714 14790 14791 #ifndef VBOX 14715 14792 if (ddi_soft_state_init(&dtrace_softstate, 14716 14793 sizeof (dtrace_state_t), 0) != 0) { … … 14722 14799 } 14723 14800 14724 #ifndef VBOX14725 14801 if (ddi_create_minor_node(devi, DTRACEMNR_DTRACE, S_IFCHR, 14726 14802 DTRACEMNRN_DTRACE, DDI_PSEUDO, NULL) == DDI_FAILURE || … … 14735 14811 return (DDI_FAILURE); 14736 14812 } 14737 #endif14738 14813 14739 14814 ddi_report_dev(devi); 14740 14815 dtrace_devi = devi; 14741 14816 14742 #ifndef VBOX14743 14817 dtrace_modload = dtrace_module_loaded; 14744 14818 dtrace_modunload = dtrace_module_unloaded; … … 14760 14834 dtrace_arena = vmem_create("dtrace", (void *)1, UINT32_MAX, 1, 14761 14835 NULL, NULL, NULL, 0, VM_SLEEP | VMC_IDENTIFIER); 14836 #ifndef VBOX 14762 14837 dtrace_minor = vmem_create("dtrace_minor", (void *)DTRACEMNRN_CLONE, 14763 14838 UINT32_MAX - DTRACEMNRN_CLONE, 1, NULL, NULL, NULL, 0, 14764 14839 VM_SLEEP | VMC_IDENTIFIER); 14765 #ifndef VBOX14766 14840 dtrace_taskq = taskq_create("dtrace_taskq", 1, maxclsyspri, 14767 14841 1, INT_MAX, 0); … … 14878 14952 } 14879 14953 14954 #ifdef VBOX 14955 int dtrace_open(dtrace_state_t **ppState, cred_t *cred_p) 14956 #else 14880 14957 /*ARGSUSED*/ 14881 14958 static int 14882 14959 dtrace_open(dev_t *devp, int flag, int otyp, cred_t *cred_p) 14960 #endif 14883 14961 { 14884 14962 dtrace_state_t *state; … … 14887 14965 zoneid_t zoneid; 14888 14966 14967 #ifndef VBOX 14889 14968 if (getminor(*devp) == DTRACEMNRN_HELPER) 14890 14969 return (0); … … 14896 14975 if (getminor(*devp) != DTRACEMNRN_DTRACE) 14897 14976 return (ENXIO); 14977 #endif /* !VBOX */ 14898 14978 14899 14979 /* … … 14930 15010 #endif 14931 15011 15012 #ifndef VBOX 14932 15013 state = dtrace_state_create(devp, cred_p); 15014 #else 15015 state = dtrace_state_create(cred_p); 15016 #endif 14933 15017 mutex_exit(&cpu_lock); 14934 15018 … … 14944 15028 mutex_exit(&dtrace_lock); 14945 15029 15030 #ifdef VBOX 15031 *ppState = state; 15032 #endif 14946 15033 return (0); 14947 15034 } 14948 15035 15036 #ifdef VBOX 15037 int dtrace_close(dtrace_state_t *state) 15038 #else 14949 15039 /*ARGSUSED*/ 14950 15040 static int 14951 15041 dtrace_close(dev_t dev, int flag, int otyp, cred_t *cred_p) 14952 { 15042 #endif 15043 { 15044 #ifndef VBOX 14953 15045 minor_t minor = getminor(dev); 14954 15046 dtrace_state_t *state; … … 14958 15050 14959 15051 state = ddi_get_soft_state(dtrace_softstate, minor); 15052 #endif 14960 15053 14961 15054 mutex_enter(&cpu_lock); … … 15046 15139 #endif /* !VBOX */ 15047 15140 15141 #ifdef VBOX 15142 int dtrace_ioctl(dtrace_state_t *state, int cmd, intptr_t arg, int32_t *rv) 15143 #else 15048 15144 /*ARGSUSED*/ 15049 #ifndef VBOX15050 15145 static int 15051 15146 dtrace_ioctl(dev_t dev, int cmd, intptr_t arg, int md, cred_t *cr, int *rv) 15052 #else15053 int dtrace_ioctl(dev_t dev, int cmd, intptr_t arg, int md, cred_t *cr, int *rv)15054 15147 #endif 15055 15148 { 15149 #ifndef VBOX 15056 15150 minor_t minor = getminor(dev); 15057 15151 dtrace_state_t *state; 15152 #endif 15058 15153 int rval; 15059 15154 … … 15061 15156 if (minor == DTRACEMNRN_HELPER) 15062 15157 return (dtrace_ioctl_helper(cmd, arg, rv)); 15158 15159 state = ddi_get_soft_state(dtrace_softstate, minor); 15063 15160 #endif 15064 15065 state = ddi_get_soft_state(dtrace_softstate, minor);15066 15161 15067 15162 if (state->dts_anon) { … … 15281 15376 dtrace_vstate_t *vstate; 15282 15377 int err = 0; 15378 #ifdef VBOX 15379 cred_t *cr = CRED(); 15380 #endif 15283 15381 15284 15382 *rv = 0; … … 15372 15470 uid_t uid; 15373 15471 zoneid_t zoneid; 15472 #ifdef VBOX 15473 cred_t *cr = CRED(); 15474 #endif 15374 15475 15375 15476 if (copyin((void *)arg, &desc, sizeof (desc)) != 0) … … 15629 15730 ASSERT(!(buf->dtb_flags & DTRACEBUF_NOSWITCH)); 15630 15731 15732 #ifndef VBOX 15631 15733 dtrace_xcall(desc.dtbd_cpu, 15632 15734 (dtrace_xcall_t)dtrace_buffer_switch, buf); 15735 #else 15736 if ((int32_t)desc.dtbd_cpu == DTRACE_CPUALL) 15737 RTMpOnAll(dtrace_buffer_switch_wrapper, buf, NULL); 15738 else 15739 RTMpOnSpecific(desc.dtbd_cpu, dtrace_buffer_switch_wrapper, buf, NULL); 15740 #endif 15633 15741 15634 15742 state->dts_errors += buf->dtb_xamot_errors; … … 15809 15917 } 15810 15918 15811 #ifndef VBOX 15919 #ifdef VBOX 15920 int dtrace_detach(ddi_detach_cmd_t cmd) 15921 #else 15812 15922 /*ARGSUSED*/ 15813 15923 static int 15814 15924 dtrace_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 15815 #else15816 int dtrace_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)15817 15925 #endif 15818 15926 { … … 15903 16011 15904 16012 kmem_cache_destroy(dtrace_state_cache); 16013 #ifndef VBOX 15905 16014 vmem_destroy(dtrace_minor); 16015 #endif 15906 16016 vmem_destroy(dtrace_arena); 15907 16017 … … 15916 16026 #ifndef VBOX 15917 16027 ddi_remove_minor_node(dtrace_devi, NULL); 16028 dtrace_devi = NULL; 16029 16030 ddi_soft_state_fini(&dtrace_softstate); 15918 16031 #endif 15919 dtrace_devi = NULL;15920 15921 ddi_soft_state_fini(&dtrace_softstate);15922 16032 15923 16033 ASSERT(dtrace_vtime_references == 0); -
trunk/src/VBox/ExtPacks/VBoxDTrace/onnv/uts/common/sys/dtrace_impl.h
r53642 r53667 1102 1102 */ 1103 1103 struct dtrace_state { 1104 #ifndef VBOX 1104 1105 dev_t dts_dev; /* device */ 1106 #endif 1105 1107 int dts_necbs; /* total number of ECBs */ 1106 1108 dtrace_ecb_t **dts_ecbs; /* array of ECBs */
Note:
See TracChangeset
for help on using the changeset viewer.