VirtualBox

source: vbox/trunk/src/VBox/HostDrivers/Support/SUPDrv-dtrace.cpp@ 40601

Last change on this file since 40601 was 40601, checked in by vboxsync, 13 years ago

VBoxTpG/SupDrv: -> laptop.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 15.1 KB
Line 
1/* $Id: SUPDrv-dtrace.cpp 40601 2012-03-24 09:31:11Z vboxsync $ */
2/** @file
3 * VBoxDrv - The VirtualBox Support Driver - DTrace Provider.
4 */
5
6/*
7 * Copyright (C) 2012 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28/*******************************************************************************
29* Header Files *
30*******************************************************************************/
31#define LOG_GROUP LOG_GROUP_SUP_DRV
32#include "SUPDrvInternal.h"
33
34#include <VBox/err.h>
35#include <VBox/VBoxTpG.h>
36#include <iprt/assert.h>
37
38#include <sys/dtrace.h>
39
40
41/*******************************************************************************
42* Structures and Typedefs *
43*******************************************************************************/
44/**
45 * Data for a provider.
46 */
47typedef struct SUPDRVDTPROVIDER
48{
49 /** The entry in the provider list for this image. */
50 RTLISTNODE ListEntry;
51
52 /** The provider descriptor. */
53 PVTGDESCPROVIDER pDesc;
54 /** The VTG header. */
55 PVTGOBJHDR pHdr;
56
57 /** Pointer to the image this provider resides in. NULL if it's a
58 * driver. */
59 PSUPDRVLDRIMAGE pImage;
60 /** The session this provider is associated with if registered via
61 * SUPR0VtgRegisterDrv. NULL if pImage is set. */
62 PSUPDRVSESSION pSession;
63 /** The module name. */
64 const char *pszModName;
65} SUPDRVDTPROVIDER;
66/** Pointer to the data for a provider. */
67typedef SUPDRVDTPROVIDER *PSUPDRVDTPROVIDER;
68
69
70/*******************************************************************************
71* Internal Functions *
72*******************************************************************************/
73static void supdrvDTracePOps_ProvideModule(void *pvProv, struct modctl *pMod);
74static int supdrvDTracePOps_Enable(void *pvProv, dtrace_id_t idProbe, void *pvProbe);
75static void supdrvDTracePOps_Disable(void *pvProv, dtrace_id_t idProbe, void *pvProbe);
76static void supdrvDTracePOps_GetArgDesc(void *pvProv, dtrace_id_t idProbe, void *pvProbe,
77 dtrace_argdesc_t *pArgDesc);
78/*static uint64_t supdrvDTracePOps_GetArgVal(void *pvProv, dtrace_id_t idProbe, void *pvProbe,
79 int iArg, int cFrames);*/
80static void supdrvDTracePOps_Destroy(void *pvProv, dtrace_id_t idProbe, void *pvProbe);
81
82
83
84/*******************************************************************************
85* Global Variables *
86*******************************************************************************/
87/** The default provider attributes. */
88static dtrace_pattr_t g_DefProvAttrs =
89{ /* .dtat_name, .dtat_data, .dtat_class */
90 /* .dtpa_provider = */ { DTRACE_STABILITY_UNSTABLE, DTRACE_STABILITY_UNSTABLE, DTRACE_CLASS_ISA },
91 /* .dtpa_mod = */ { DTRACE_STABILITY_UNSTABLE, DTRACE_STABILITY_UNSTABLE, DTRACE_CLASS_ISA },
92 /* .dtpa_func = */ { DTRACE_STABILITY_UNSTABLE, DTRACE_STABILITY_UNSTABLE, DTRACE_CLASS_ISA },
93 /* .dtpa_name = */ { DTRACE_STABILITY_UNSTABLE, DTRACE_STABILITY_UNSTABLE, DTRACE_CLASS_ISA },
94 /* .dtpa_args = */ { DTRACE_STABILITY_UNSTABLE, DTRACE_STABILITY_UNSTABLE, DTRACE_CLASS_ISA },
95};
96
97/**
98 * DTrace provider method table.
99 */
100static const dtrace_pops_t g_SupDrvDTraceProvOps =
101{
102 /* .dtps_provide = */ NULL,
103 /* .dtps_provide_module = */ supdrvDTracePOps_ProvideModule,
104 /* .dtps_enable = */ supdrvDTracePOps_Enable,
105 /* .dtps_disable = */ supdrvDTracePOps_Disable,
106 /* .dtps_suspend = */ NULL,
107 /* .dtps_resume = */ NULL,
108 /* .dtps_getargdesc = */ supdrvDTracePOps_GetArgDesc,
109 /* .dtps_getargval = */ NULL/*supdrvDTracePOps_GetArgVal*/,
110 /* .dtps_usermode = */ NULL,
111 /* .dtps_destroy = */ supdrvDTracePOps_Destroy
112};
113
114
115#define VERR_SUPDRV_VTG_MAGIC (-3704)
116#define VERR_SUPDRV_VTG_BITS (-3705)
117#define VERR_SUPDRV_VTG_RESERVED (-3705)
118#define VERR_SUPDRV_VTG_BAD_PTR (-3706)
119#define VERR_SUPDRV_VTG_TOO_FEW (-3707)
120#define VERR_SUPDRV_VTG_TOO_MUCH (-3708)
121#define VERR_SUPDRV_VTG_NOT_MULTIPLE (-3709)
122
123
124static int supdrvVtgValidateString(const char *psz)
125{
126 size_t off = 0;
127 while (off < _4K)
128 {
129 char const ch = psz[off++];
130 if (!ch)
131 return VINF_SUCCESS;
132 if ( !RTLocCIsAlNum(ch)
133 && ch != ' '
134 && ch != '('
135 && ch != ')'
136 && ch != ','
137 && ch != '*'
138 && ch != '&'
139 )
140 return VERR_SUPDRV_VTG_BAD_STRING;
141 }
142 return VERR_SUPDRV_VTG_STRING_TOO_LONG;
143}
144
145/**
146 * Validates the VTG data.
147 *
148 * @returns VBox status code.
149 * @param pVtgHdr The VTG object header of the data to validate.
150 * @param cbVtgObj The size of the VTG object.
151 * @param pbImage The image base. For validating the probe
152 * locations.
153 * @param cbImage The image size to go with @a pbImage.
154 */
155static int supdrvVtgValidate(PVTGOBJHDR pVtgHdr, size_t cbVtgObj, uint8_t *pbImage, size_t cbImage)
156{
157 uintptr_t cbTmp;
158 uintptr_t i;
159 int rc;
160
161 if (!pbImage || !cbImage)
162 {
163 pbImage = NULL;
164 cbImage = 0;
165 }
166
167#define MY_VALIDATE_PTR(p, cb, cMin, cMax, cbUnit) \
168 do { \
169 if ( (cb) >= cbVtgObj \
170 || (uintptr_t)(p) - (uintptr_t)pVtgHdr < cbVtgObj - (cb) ) \
171 return VERR_SUPDRV_VTG_BAD_PTR; \
172 if ((cb) < (cMin) * (cbUnit)) \
173 return VERR_SUPDRV_VTG_TOO_FEW; \
174 if ((cb) >= (cMax) * (cbUnit)) \
175 return VERR_SUPDRV_VTG_TOO_MUCH; \
176 if ((cb) / (cbUnit) * (cbUnit) != (cb)) \
177 return VERR_SUPDRV_VTG_NOT_MULTIPLE; \
178 } while (0)
179#define MY_WITHIN_IMAGE(p) \
180 do { \
181 if (pbImage) \
182 { \
183 if ((uintptr_t)(p) - (uintptr_t)pbImage > cbImage) \
184 return VERR_SUPDRV_VTG_BAD_PTR; \
185 } \
186 else if (!RT_VALID_PTR(p)) \
187 return VERR_SUPDRV_VTG_BAD_PTR; \
188 } while (0)
189#define MY_WITHIN_IMAGE_RANGE(p, cb)
190 do { \
191 if (pbImage) \
192 { \
193 if ( (cb) > cbImage \
194 || (uintptr_t)(p) - (uintptr_t)pbImage > cbImage - (cb)) \
195 return VERR_SUPDRV_VTG_BAD_PTR; \
196 } \
197 else if (!RT_VALID_PTR(p) || RT_VALID_PTR((uint8_t *)(p) + cb)) \
198 return VERR_SUPDRV_VTG_BAD_PTR; \
199 } while (0)
200#define MY_VALIDATE_STR(offStrTab) \
201 do { \
202 if ((offStrTab) >= pVtgHdr->cbStrTab) \
203 return VERR_SUPDRV_VTG_STRTAB_OFF; \
204 rc = supdrvVtgValidateString(pVtgHdr->pachStrTab + (offStrTab)); \
205 if (rc != VINF_SUCCESS) \
206 return rc; \
207 } while (0)
208#define MY_VALIDATE_ATTR(Attr)
209 do { \
210 if ((Attr).u8Code <= (uint8_t)kVTGStability_Invalid || (Attr).u8Code >= (uint8_t)kVTGStability_End) \
211 return VERR_SUPDRV_VTG_BAD_ATTR; \
212 if ((Attr).u8Data <= (uint8_t)kVTGStability_Invalid || (Attr).u8Data >= (uint8_t)kVTGStability_End) \
213 return VERR_SUPDRV_VTG_BAD_ATTR; \
214 if ((Attr).u8DataDep <= (uint8_t)kVTGClass_Invalid || (Attr).u8DataDep >= (uint8_t)kVTGClass_End) \
215 return VERR_SUPDRV_VTG_BAD_ATTR; \
216 } while (0)
217
218 /*
219 * The header.
220 */
221 if (!memcmp(pVtgHdr->szMagic, VTGOBJHDR_MAGIC, sizeof(pVtgHdr->szMagic)))
222 return VERR_SUPDRV_VTG_MAGIC;
223 if (pVtgHdr->cBits != ARCH_BITS)
224 return VERR_SUPDRV_VTG_BITS;
225 if (pVtgHdr->u32Reserved0)
226 return VERR_SUPDRV_VTG_RESERVED;
227
228 MY_VALIDATE_PTR(pVtgHdr->paProviders, pVtgHdr->cbProviders, 1, 16, sizeof(VTGDESCPROVIDER));
229 MY_VALIDATE_PTR(pVtgHdr->paProbes, pVtgHdr->cbProbes, 1, _32K, sizeof(VTGDESCPROBE));
230 MY_VALIDATE_PTR(pVtgHdr->pafProbeEnabled, pVtgHdr->cbProbeEnabled, 1, _32K, sizeof(bool));
231 MY_VALIDATE_PTR(pVtgHdr->pachStrTab, pVtgHdr->cbStrTab, 4, _1M, sizeof(char));
232 MY_VALIDATE_PTR(pVtgHdr->paArgLists, pVtgHdr->cbArgLists, 0, _32K, sizeof(uint32_t));
233 MY_WITHIN_IMAGE(pVtgHdr->paProbLocs);
234 MY_WITHIN_IMAGE(pVtgHdr->paProbLocsEnd);
235 if ((uintptr_t)pVtgHdr->paProbLocs > (uintptr_t)pVtgHdr->paProbLocsEnd)
236 return VERR_SUPDRV_VTG_BAD_PTR;
237 cbTmp = (uintptr_t)pVtgHdr->paProbLocsEnd - (uintptr_t)pVtgHdr->paProbLocs;
238 MY_VALIDATE_PTR(pVtgHdr->paProbLocs, cbTmp, 1, _128K, sizeof(VTGPROBELOC))
239 if (cbTmp < sizeof(VTGPROBELOC))
240 return VERR_SUPDRV_VTG_TOO_FEW;
241
242 if (pVtgHdr->cbProbes / sizeof(VTGDESCPROBE) != pVtgHdr->cbProbeEnabled)
243 return VERR_SUPDRV_VTG_BAD_HDR;
244
245 /*
246 * Validate the providers.
247 */
248 i = pVtgHdr->cbProviders / sizeof(VTGDESCPROVIDER);
249 while (i-- > 0)
250 {
251 MY_VALIDATE_STR(pVtgHdr->paProviders[i].offName);
252 if (pVtgHdr->paProviders[i].iFirstProbe >= pVtgHdr->cbProbeEnabled)
253 return VERR_SUPDRV_VTG_BAD_PROVIDER;
254 if (pVtgHdr->paProviders[i].iFirstProbe + pVtgHdr->paProviders[i].cProbes > pVtgHdr->cbProbeEnabled)
255 return VERR_SUPDRV_VTG_BAD_PROVIDER;
256 MY_VALIDATE_ATTR(pVtgHdr->paProviders[i].AttrSelf);
257 MY_VALIDATE_ATTR(pVtgHdr->paProviders[i].AttrModules);
258 MY_VALIDATE_ATTR(pVtgHdr->paProviders[i].AttrFunctions);
259 MY_VALIDATE_ATTR(pVtgHdr->paProviders[i].AttrName);
260 MY_VALIDATE_ATTR(pVtgHdr->paProviders[i].AttrArguments);
261 if (pVtgHdr->paProviders[i].bReserved)
262 return VERR_SUPDRV_VTG_RESERVED;
263 }
264
265 /*
266 * Validate probes.
267 */
268 i = pVtgHdr->cbProbes / sizeof(VTGDESCPROBE);
269 while (i-- > 0)
270 {
271 MY_VALIDATE_STR(pVtgHdr->paProbes[i].offName);
272 }
273
274 return VINF_SUCCESS;
275#undef MY_VALIDATE_STR
276#undef MY_VALIDATE_PTR
277#undef MY_WITHIN_IMAGE
278#undef MY_WITHIN_IMAGE_RANGE
279}
280
281
282/**
283 * Registers the VTG tracepoint providers of a driver.
284 *
285 * @returns VBox status code.
286 * @param pszName The driver name.
287 * @param pVtgHdr The VTG header.
288 * @param pImage The image if applicable.
289 * @param pSession The session if applicable.
290 * @param pszModName The module name.
291 */
292static int supdrvVtgRegister(PSUPDRVDEVEXT pDevExt, PVTGOBJHDR pVtgHdr, PSUPDRVLDRIMAGE pImage, PSUPDRVSESSION pSession,
293 const char *pszModName)
294{
295 /*
296 * Validate input.
297 */
298 AssertPtrReturn(pDevExt, VERR_INVALID_POINTER);
299 AssertPtrReturn(pVtgHdr, VERR_INVALID_POINTER);
300 AssertPtrNullReturn(pImage, VERR_INVALID_POINTER);
301 AssertPtrNullReturn(pSession, VERR_INVALID_POINTER);
302 AssertPtrReturn(pszModName, VERR_INVALID_POINTER);
303 AssertReturn((pImage == NULL) != (pSession != NULL), VERR_INVALID_PARAMETER);
304
305
306
307 /*
308 *
309 */
310
311}
312
313
314
315/**
316 * Registers the VTG tracepoint providers of a driver.
317 *
318 * @returns VBox status code.
319 * @param pSession The support driver session handle.
320 * @param pVtgHdr The VTG header.
321 * @param pszName The driver name.
322 */
323SUPR0DECL(int) SUPR0VtgRegisterDrv(PSUPDRVSESSION pSession, PVTGOBJHDR pVtgHdr, const char *pszName)
324{
325 AssertReturn(SUP_IS_SESSION_VALID(pSession), NULL);
326 AssertPtrReturn(pszName, VERR_INVALID_POINTER);
327 AssertPtrReturn(pVtgHdr, VERR_INVALID_POINTER);
328
329 return supdrvVtgRegister(pSession->pDevExt, pVtgHdr, NULL, pSession, pszName);
330}
331
332
333
334/**
335 * Deregister the VTG tracepoint providers of a driver.
336 *
337 * @param pSession The support driver session handle.
338 * @param pVtgHdr The VTG header.
339 */
340SUPR0DECL(void) SUPR0VtgDeregisterDrv(PSUPDRVSESSION pSession, PVTGOBJHDR pVtgHdr)
341{
342}
343
344
345
346/**
347 * Early module initialization hook.
348 *
349 * @returns VBox status code.
350 * @param pDevExt The device extension structure.
351 */
352int supdrvDTraceInit(PSUPDRVDEVEXT pDevExt)
353{
354 /*
355 * Register a provider for this module.
356 */
357
358 return VINF_SUCCESS;
359}
360
361
362/**
363 * Late module termination hook.
364 *
365 * @returns VBox status code.
366 * @param pDevExt The device extension structure.
367 */
368int supdrvDTraceTerm(PSUPDRVDEVEXT pDevExt)
369{
370 /*
371 * Undo what we did in supdrvDTraceInit.
372 */
373
374 return VINF_SUCCESS;
375}
376
377
378/**
379 * Module loading hook, called before calling into the module.
380 *
381 * @returns VBox status code.
382 * @param pDevExt The device extension structure.
383 */
384int supdrvDTraceModuleLoading(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage)
385{
386 /*
387 * Check for DTrace probes in the module, register a new provider for them
388 * if found.
389 */
390
391 return VINF_SUCCESS;
392}
393
394
395/**
396 * Module unloading hook, called after execution in the module
397 * have ceased.
398 *
399 * @returns VBox status code.
400 * @param pDevExt The device extension structure.
401 */
402int supdrvDTraceModuleUnloading(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage)
403{
404 /*
405 * Undo what we did in supdrvDTraceModuleLoading.
406 */
407 return VINF_SUCCESS;
408}
409
410
411
412
413
414/**
415 * @callback_method_impl{dtrace_pops_t,dtps_provide_module}
416 */
417static void supdrvDTracePOps_ProvideModule(void *pvProv, struct modctl *pMod)
418{
419 return;
420}
421
422
423/**
424 * @callback_method_impl{dtrace_pops_t,dtps_enable}
425 */
426static int supdrvDTracePOps_Enable(void *pvProv, dtrace_id_t idProbe, void *pvProbe)
427{
428 return -1;
429}
430
431
432/**
433 * @callback_method_impl{dtrace_pops_t,dtps_disable}
434 */
435static void supdrvDTracePOps_Disable(void *pvProv, dtrace_id_t idProbe, void *pvProbe)
436{
437}
438
439
440/**
441 * @callback_method_impl{dtrace_pops_t,dtps_getargdesc}
442 */
443static void supdrvDTracePOps_GetArgDesc(void *pvProv, dtrace_id_t idProbe, void *pvProbe,
444 dtrace_argdesc_t *pArgDesc)
445{
446 pArgDesc->dtargd_ndx = DTRACE_ARGNONE;
447}
448
449
450#if 0
451/**
452 * @callback_method_impl{dtrace_pops_t,dtps_getargval}
453 */
454static uint64_t supdrvDTracePOps_GetArgVal(void *pvProv, dtrace_id_t idProbe, void *pvProbe,
455 int iArg, int cFrames)
456{
457 return 0xbeef;
458}
459#endif
460
461
462/**
463 * @callback_method_impl{dtrace_pops_t,dtps_destroy}
464 */
465static void supdrvDTracePOps_Destroy(void *pvProv, dtrace_id_t idProbe, void *pvProbe)
466{
467}
468
469
Note: See TracBrowser for help on using the repository browser.

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