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