From 6b92bd97ee36e37750236e87ce8c4db2b10d4ec6 Mon Sep 17 00:00:00 2001 From: Nick Alcock Date: Mon, 29 Apr 2013 13:57:15 +0100 Subject: [PATCH] Revamp and split up DTrace headers. Add ioctl() debugging machinery. It has always been annoying that we have a duplicate set of DTrace headers in userspace, and further annoying that the DTrace header we have is such a monolithic monster. This fixes both of these, at the cost of a (very) little extra complexity when maintaining the headers. It also adds automated machinery to verify that each of the new headers is 'standalone enough'. What does 'standalone enough' mean? This is the problem that has stopped us sharing DTrace headers between userspace and kernelspace for a long time: they depend on types that come from different places and have different definitions in the kernel and in userspace, and can never be made to come from the same place. So we fix this by dictating that the headers are standalone *given* that certain headers are included first. For userspace, this set is , , and ; for kernelspace, the set is and a newly-introduced header included as . We avoid exposing this requirement to header users by arranging for the header included as "dtrace.h" in kernelspace and as to include the prerequisite headers, and enough other headers that the users of those headers can keep using them exactly as they did before. (There is a single exception for dtrace/iocl.h: see below.) Where have the headers gone? They have been split in two directions (and the Kbuild machinery has been adjusted to have its include paths point at the appropriate places). All DTrace headers, even in the global kernel tree, have had 'defines headers' split out of them, named ${header}_defines.h. These headers contain all typedefs, enums and #defines which do not depend on visibility into structure definitions declared in the main non-defines header, and opaque forwardings for all structure definitions declared in that header. This means that users can include the defines header if they only want opaque use of structures and relevant constants. (This has necessitated some mechanical changes to the DTrace headers to convert uses of foo_t typedefs into 'struct foo' where necessary. Not all uses have been converted: only those that need to be). An _defines header is always accompanied by a corresponding non _defines header (even if it is just one #include), but the reverse is not true. In addition to this split, the core dtrace.h header has been split into three pieces: - dtrace/include/uapi/linux/dtrace/*.h contains the majority of the headers, split into _defines and further by section roughly corresponding with the comment-delimited sections in the original file. The include paths have been set up so that these can be used via #include in both userspace and kernelspace. #include includes all the headers in the same order as they were originally. These headers are installed in userspace and used by dtrace-util. They should always contain a CDDL license header, and should not use any kernel-specific types (modulo those that userspace normally uses, such as those related to kernel-specific functionality such as ioctl()). If you use a new kernel-specific type, please add a definition of it to uts/common/sys/dtrace_types.h in userspace too. The old dtrace_ioctl.h has been renamed to and moved in here too. It has gained some extra machinery to help debug ioctl() type size conflicts. If you call dtrace_ioctl_sizes(), then dtrace_size_dbg_print() (not defined here) is repeatedly called with two parameters, the name of each ioctl() type and the size of that type. Please keep this list up to date, it is useful! There is one unfortunate exception to the userspace-types rule here: ioctl.h needs types from , which is not even a userspace-installed header. So userspace must provide a copy of this header with appropriate typedefs as well. (This should probably be fixed in due course.) defines constants and types used by virtually everything in any way related to dtrace. - dtrace/include/dtrace/*.h contains headers that are not shared with userspace, included as : - : this contains the kernel-side definitions of types used in the shared headers. (It has not been 'gardened' in any way, so probably contains a lot of other types as well). This header is installed into the same place as the shared userspace headers. This header needs a bit of care maintaining, as not everything kernel- side is allowable in it: see below. - : The provider API, and its corresponding defines header. This includes itself, so should be standalone -- however, this has not been in any way tested yet, unlike for the userspace headers. This header is also installed into the same place as the shared userspace headers. - and . These headers contain definitions used only by the DTrace core, and are not installed anywhere. Note that because of the rules regarding kernel-specific types in the UAPI DTrace headers, a number of uses of CONFIG_64BIT and CONFIG_BIG_ENDIAN have been reverted to their Solaris-era-and-userspace _LP64 and _LITTLE_ENDIAN forms; translates between the two. (We have also fixed up a couple of places in core DTrace where the nonexistent _BIG_ENDIAN was used.) There are several things called dtrace.h now, which might get confusing: - dtrace.h at the top level is for the DTrace core and included providers alone. Anything goes in here. It is never installed anywhere, and not even standalone providers can see it. - dtrace/include/uapi/linux/dtrace/dtrace.h is shared with userspace and with standalone providers, and needs to follow the same rules as all such shared headers. We have two new packages, dtrace-modules-$kver-headers and dtrace-modules-$kver-provider-headers; to make it easy for people to Require them, they provide features named 'dtrace-modules-headers' and 'dtrace-modules-provider-headers' using the same incrementing API version number as 'dtrace-kernel-interface' (both currently 1). dtrace-modules-headers serves much the same purpose as dtrace-kernel-interface, tracking changes in the userspace/kernelspace API: the dtrace-modules-provider-headers version number tracks changes in the DTrace core/provider API. The top-level Makefile has acquired two new rules, headers_install and headers_check. The former is a simple emulation of the top-level headers_install rule, and is used by the RPM build system. The latter checks to be sure that the userspace-side headers can be #included on their own (modulo only et al, as above), and that dtrace/ioctl.h has all its types in scope with appropriate sizes, since if they aren't everything will appear to work until userspace tries to invoke the ioctl() and gets an -ENOTTY error. The latter is particularly difficult, since the size-checking machinery only works for kernelspace builds, and the headers_check build is userspace. So that machinery hacks up a sort of halfway-house to the kernel environment, enough to do the ioctl() size checks but not enough to #include arbitrary kernel headers (among other things, there are no CONFIG constants here). This means that changes to those kernel-side headers which are included by this machinery (in particular dtrace/types.h, dtrace_os.h) need to include a headers_check run to make sure that machinery hasn't broken. In general, surrounding suspect definitions with an #ifndef HEADERS_CHECK should suffice: nearly all of dtrace_os.h is so surrounded (and if we ever move dtrace_id_t out into the shared headers, as perhaps we should, this problem will become less serious). (Feel free to make the headers_check dtrace/ioctl.h compilation environment more like that used for the real kernel.) Signed-off-by: Nick Alcock --- dtrace/Kbuild | 4 +- dtrace/Makefile | 24 + dtrace/dtrace-module.spec | 44 +- dtrace/dtrace.h | 2440 +---------------- dtrace/dtrace_dev.c | 17 +- dtrace/dtrace_dif.c | 6 +- dtrace/include/dtrace/dtrace_impl.h | 904 ++++++ dtrace/include/dtrace/dtrace_impl_defines.h | 246 ++ dtrace/include/dtrace/provider.h | 930 +++++++ dtrace/include/dtrace/provider_defines.h | 49 + dtrace/include/dtrace/types.h | 141 + dtrace/include/uapi/linux/dtrace/actions.h | 30 + .../uapi/linux/dtrace/actions_defines.h | 171 ++ dtrace/include/uapi/linux/dtrace/arg.h | 60 + .../include/uapi/linux/dtrace/arg_defines.h | 39 + dtrace/include/uapi/linux/dtrace/buffer.h | 61 + .../uapi/linux/dtrace/buffer_defines.h | 39 + dtrace/include/uapi/linux/dtrace/conf.h | 53 + .../include/uapi/linux/dtrace/conf_defines.h | 39 + dtrace/include/uapi/linux/dtrace/dif.h | 78 + .../include/uapi/linux/dtrace/dif_defines.h | 305 +++ dtrace/include/uapi/linux/dtrace/difo.h | 75 + .../include/uapi/linux/dtrace/difo_defines.h | 39 + dtrace/include/uapi/linux/dtrace/dof.h | 214 ++ .../include/uapi/linux/dtrace/dof_defines.h | 210 ++ dtrace/include/uapi/linux/dtrace/dtrace.h | 59 + dtrace/include/uapi/linux/dtrace/enabling.h | 94 + .../uapi/linux/dtrace/enabling_defines.h | 43 + dtrace/include/uapi/linux/dtrace/faults.h | 38 + .../uapi/linux/dtrace/faults_defines.h | 57 + dtrace/include/uapi/linux/dtrace/helpers.h | 119 + .../uapi/linux/dtrace/helpers_defines.h | 39 + dtrace/include/uapi/linux/dtrace/ioctl.h | 90 + dtrace/include/uapi/linux/dtrace/metadesc.h | 99 + .../uapi/linux/dtrace/metadesc_defines.h | 42 + dtrace/include/uapi/linux/dtrace/options.h | 38 + .../uapi/linux/dtrace/options_defines.h | 88 + dtrace/include/uapi/linux/dtrace/stability.h | 70 + .../uapi/linux/dtrace/stability_defines.h | 71 + dtrace/include/uapi/linux/dtrace/status.h | 68 + dtrace/include/uapi/linux/dtrace/universal.h | 65 + 41 files changed, 4850 insertions(+), 2448 deletions(-) create mode 100644 dtrace/include/dtrace/dtrace_impl.h create mode 100644 dtrace/include/dtrace/dtrace_impl_defines.h create mode 100644 dtrace/include/dtrace/provider.h create mode 100644 dtrace/include/dtrace/provider_defines.h create mode 100644 dtrace/include/dtrace/types.h create mode 100644 dtrace/include/uapi/linux/dtrace/actions.h create mode 100644 dtrace/include/uapi/linux/dtrace/actions_defines.h create mode 100644 dtrace/include/uapi/linux/dtrace/arg.h create mode 100644 dtrace/include/uapi/linux/dtrace/arg_defines.h create mode 100644 dtrace/include/uapi/linux/dtrace/buffer.h create mode 100644 dtrace/include/uapi/linux/dtrace/buffer_defines.h create mode 100644 dtrace/include/uapi/linux/dtrace/conf.h create mode 100644 dtrace/include/uapi/linux/dtrace/conf_defines.h create mode 100644 dtrace/include/uapi/linux/dtrace/dif.h create mode 100644 dtrace/include/uapi/linux/dtrace/dif_defines.h create mode 100644 dtrace/include/uapi/linux/dtrace/difo.h create mode 100644 dtrace/include/uapi/linux/dtrace/difo_defines.h create mode 100644 dtrace/include/uapi/linux/dtrace/dof.h create mode 100644 dtrace/include/uapi/linux/dtrace/dof_defines.h create mode 100644 dtrace/include/uapi/linux/dtrace/dtrace.h create mode 100644 dtrace/include/uapi/linux/dtrace/enabling.h create mode 100644 dtrace/include/uapi/linux/dtrace/enabling_defines.h create mode 100644 dtrace/include/uapi/linux/dtrace/faults.h create mode 100644 dtrace/include/uapi/linux/dtrace/faults_defines.h create mode 100644 dtrace/include/uapi/linux/dtrace/helpers.h create mode 100644 dtrace/include/uapi/linux/dtrace/helpers_defines.h create mode 100644 dtrace/include/uapi/linux/dtrace/ioctl.h create mode 100644 dtrace/include/uapi/linux/dtrace/metadesc.h create mode 100644 dtrace/include/uapi/linux/dtrace/metadesc_defines.h create mode 100644 dtrace/include/uapi/linux/dtrace/options.h create mode 100644 dtrace/include/uapi/linux/dtrace/options_defines.h create mode 100644 dtrace/include/uapi/linux/dtrace/stability.h create mode 100644 dtrace/include/uapi/linux/dtrace/stability_defines.h create mode 100644 dtrace/include/uapi/linux/dtrace/status.h create mode 100644 dtrace/include/uapi/linux/dtrace/universal.h diff --git a/dtrace/Kbuild b/dtrace/Kbuild index 42e78c2b1c49..10df621587dd 100644 --- a/dtrace/Kbuild +++ b/dtrace/Kbuild @@ -21,12 +21,12 @@ # # CDDL HEADER END # -# Copyright 2011 Oracle, Inc. All rights reserved. +# Copyright 2011 -- 2013 Oracle, Inc. All rights reserved. # Use is subject to license terms. GCOV_PROFILE := y -EXTRA_CFLAGS := -Ikernel/dtrace +EXTRA_CFLAGS := -I$(src)/include -I$(src)/include/uapi obj-$(CONFIG_DT_CORE) += dtrace.o obj-$(CONFIG_DT_FASTTRAP) += fasttrap.o diff --git a/dtrace/Makefile b/dtrace/Makefile index 0adc58f76630..94dc1d77ea20 100644 --- a/dtrace/Makefile +++ b/dtrace/Makefile @@ -10,3 +10,27 @@ install:: modules_install %:: $(MAKE) -C $(KERNELDIR) M=`pwd` $@ + +# One header, ioctl.h, has to be compiled in kernel mode so that typechecking +# is enabled. The rest get compiled in user mode. We go to some lengths +# to use any ioctl() identifiers, since typechecking only kicks in at +# time of use. + +headers_check: + @for name in $(notdir $(wildcard include/uapi/linux/dtrace/*.h)); do \ + if [[ $$name = ioctl.h ]]; then \ + INC="-I../arch/x86/include -I../include -I../include/asm-generic -Iinclude -D__KERNEL__ -include linux/types.h -include dtrace/types.h"; \ + else \ + INC="-include sys/types.h -include sys/ctf_types.h -include unistd.h -I../include"; \ + fi; \ + echo -e "#include \nint main (void) { long junk[] = { $$(grep '#define ' include/uapi/linux/dtrace/$$name | grep -E 'IO[RW]' | sed 's@.*#define \([^ \t]*\).*$$@\1,@')};}" | \ + $(CC) -c -x c - -o /dev/null -D_GNU_SOURCE -DHEADERS_CHECK \ + $$INC -Iinclude/uapi $$INC -include linux/dtrace_os.h || \ + { echo "$$name is not standalone." >&2; exit 1; } \ + done + +headers_install: + mkdir -p $(INSTALL_HDR_PATH)/usr/include/linux/dtrace + for name in include/dtrace/provider*.h include/dtrace/types*.h include/uapi/linux/dtrace/*.h; do \ + install -m 0644 $$name $(INSTALL_HDR_PATH)/usr/include/linux/dtrace; \ + done diff --git a/dtrace/dtrace-module.spec b/dtrace/dtrace-module.spec index 7a25b0a10467..17903484770e 100644 --- a/dtrace/dtrace-module.spec +++ b/dtrace/dtrace-module.spec @@ -5,13 +5,18 @@ %define karch x86_64 %endif +# Set this to the version of the kernel this module is compiled against. %define kver 2.6.39-201.0.1.el6uek +# Increment this whenever the DTrace/userspace interface changes in an +# incompatible way. +%define dtrace_kernel_interface 1 + Name: dtrace-modules-%{kver} Summary: dtrace module -Version: 0.3.0 -Release: 2.el6 -Provides: dtrace-kernel-interface = 2 +Version: 0.4.0 +Release: 1.el6 +Provides: dtrace-kernel-interface = %{dtrace_kernel_interface} License: CDDL Group: System Environment/Kernel Requires: kernel-uek-dtrace = %{kver} @@ -32,13 +37,28 @@ Maintainers: Nick Alcock Kris van Hees +%package headers +Summary: Header files for communication with the DTrace kernel module. +Requires: dtrace-modules-%{kver} +Provides: dtrace-modules-headers = %{dtrace_kernel_interface} +%description headers +This package contains header files describing the protocol used by userspace to +communicate with the DTrace kernel module. + +%package provider-headers +Summary: Header files for implementation of DTrace providers. +Requires: dtrace-modules-headers-%{kver} +Provides: dtrace-modules-provider-headers = %{dtrace_kernel_interface} +%description provider-headers +This package contains header files defining the API used to implement DTrace +providers. + %prep rm -rf %{BuildRoot} %setup -c -n %{name} %build -ls cd dtrace KSRC=/usr/src/kernels/%{kver}.%{karch} make KERNELDIR=$KSRC karch=%{karch} modules @@ -49,6 +69,9 @@ mkdir -p %{buildroot}/lib/modules/%{kver}.%{karch}/kernel/drivers/dtrace install -m0644 ${RPM_BUILD_DIR}/%{name}/dtrace/*.ko %{buildroot}/lib/modules/%{kver}.%{karch}/kernel/drivers/dtrace/ mkdir -p %{buildroot}/usr/share/doc/dtrace-modules-%{kver} install -m0644 ${RPM_BUILD_DIR}/%{name}/dtrace/NEWS %{buildroot}/usr/share/doc/dtrace-modules-%{kver} +cd dtrace +KSRC=/usr/src/kernels/%{kver}.%{karch} +make KERNELDIR=$KSRC karch=%{karch} headers_install INSTALL_HDR_PATH=%{buildroot} %post depmod -a %{kver}.%{karch} > /dev/null 2> /dev/null @@ -59,7 +82,18 @@ rm -rf %{buildroot} %files %defattr(-,root,root,-) /lib -/usr +/usr/share/doc + +%files headers +%defattr(-,root,root,-) +/usr/include/linux/dtrace +%exclude /usr/include/linux/dtrace/provider*.h +%exclude /usr/include/linux/dtrace/types.h + +%files provider-headers +%defattr(-,root,root,-) +/usr/include/linux/dtrace/provider*.h +/usr/include/linux/dtrace/types.h %changelog * Mon Sep 17 2012 Kris Van Hees - 0.3.0-2 diff --git a/dtrace/dtrace.h b/dtrace/dtrace.h index 09868ac6d248..c3daaa96a018 100644 --- a/dtrace/dtrace.h +++ b/dtrace/dtrace.h @@ -1,2450 +1,18 @@ #ifndef _DTRACE_H_ #define _DTRACE_H_ -#include -#include #include #include -#include -#include -#include -#include #include -#include #include -#include -#include -#include #include "dtrace_debug.h" -#define UINT8_MAX (0xff) -#define UINT8_MIN 0 -#define UINT16_MAX (0xffff) -#define UINT16_MIN 0 -#define UINT32_MAX (0xffffffff) -#define UINT32_MIN 0 -#define UINT64_MAX (~0ULL) -#define UINT64_MIN (0) -#define INT64_MAX ((long long)(~0ULL>>1)) -#define INT64_MIN (-INT64_MAX - 1LL) +#include -#define NBBY (__BITS_PER_LONG / sizeof (long)) +#include -/* - * This is a bit unusual, but OpenSolaris seems to like it. Basically, the - * values below are the number of time units (sec, milli, micro, nano) that - * comprise 1 second. As such, it is the value of the respective multiplier. - */ -#define SEC 1 -#define MILLISEC 1000 -#define MICROSEC 1000000 -#define NANOSEC 1000000000 - -#define DTRACE_CPUALL -1 -#define DTRACE_IDNONE 0 -#define DTRACE_EPIDNONE 0 -#define DTRACE_AGGIDNONE 0 -#define DTRACE_AGGVARIDNONE 0 -#define DTRACE_CACHEIDNONE 0 -#define DTRACE_PROVNONE 0 -#define DTRACE_METAPROVNONE 0 -#define DTRACE_ARGNONE -1 - -#define DTRACE_PROVNAMELEN 64 -#define DTRACE_MODNAMELEN 64 -#define DTRACE_FUNCNAMELEN 128 -#define DTRACE_NAMELEN 64 -#define DTRACE_FULLNAMELEN (DTRACE_PROVNAMELEN + DTRACE_MODNAMELEN + \ - DTRACE_FUNCNAMELEN + DTRACE_NAMELEN + 4) -#define DTRACE_ARGTYPELEN 128 - -#define DTRACE_PROBEKEY_MAXDEPTH 8 - -#define DTRACE_STABILITY_INTERNAL 0 -#define DTRACE_STABILITY_PRIVATE 1 -#define DTRACE_STABILITY_OBSOLETE 2 -#define DTRACE_STABILITY_EXTERNAL 3 -#define DTRACE_STABILITY_UNSTABLE 4 -#define DTRACE_STABILITY_EVOLVING 5 -#define DTRACE_STABILITY_STABLE 6 -#define DTRACE_STABILITY_STANDARD 7 -#define DTRACE_STABILITY_MAX 7 - -#define DTRACE_CLASS_UNKNOWN 0 -#define DTRACE_CLASS_CPU 1 -#define DTRACE_CLASS_PLATFORM 2 -#define DTRACE_CLASS_GROUP 3 -#define DTRACE_CLASS_ISA 4 -#define DTRACE_CLASS_COMMON 5 -#define DTRACE_CLASS_MAX 5 - -#define DTRACE_COND_OWNER 0x01 -#define DTRACE_COND_USERMODE 0x02 - -#define DTRACE_ACCESS_KERNEL 0x1 - -#define DTRACE_CRA_PROC 0x0001 -#define DTRACE_CRA_PROC_CONTROL 0x0002 -#define DTRACE_CRA_PROC_DESTRUCTIVE_ALLUSER 0x0004 -#define DTRACE_CRA_PROC_DESTRUCTIVE_CREDCHG 0x0010 -#define DTRACE_CRA_KERNEL 0x0020 -#define DTRACE_CRA_KERNEL_DESTRUCTIVE 0x0040 - -#define DTRACE_CRA_ALL (DTRACE_CRA_PROC | \ - DTRACE_CRA_PROC_CONTROL | \ - DTRACE_CRA_PROC_DESTRUCTIVE_ALLUSER | \ - DTRACE_CRA_PROC_DESTRUCTIVE_CREDCHG | \ - DTRACE_CRA_KERNEL | \ - DTRACE_CRA_KERNEL_DESTRUCTIVE) - -#define DTRACE_CRV_ALLPROC 0x01 -#define DTRACE_CRV_KERNEL 0x02 -#define DTRACE_CRV_ALL (DTRACE_CRV_ALLPROC | DTRACE_CRV_KERNEL) - -#define DTRACE_MATCH_FAIL -1 -#define DTRACE_MATCH_NEXT 0 -#define DTRACE_MATCH_DONE 1 - -#define DTRACE_PRIV_NONE 0x0000 -#define DTRACE_PRIV_KERNEL 0x0001 -#define DTRACE_PRIV_USER 0x0002 -#define DTRACE_PRIV_PROC 0x0004 -#define DTRACE_PRIV_OWNER 0x0008 -#define DTRACE_PRIV_ALL (DTRACE_PRIV_KERNEL | DTRACE_PRIV_USER | \ - DTRACE_PRIV_PROC | DTRACE_PRIV_OWNER) - -#define DTRACE_QUANTIZE_NBUCKETS \ - (((sizeof (uint64_t) * NBBY) - 1) * 2 + 1) - -#define DTRACE_QUANTIZE_ZEROBUCKET ((sizeof (uint64_t) * NBBY) - 1) - -#define DTRACE_QUANTIZE_BUCKETVAL(buck) \ - (int64_t)((buck) < DTRACE_QUANTIZE_ZEROBUCKET ? \ - -(1LL << (DTRACE_QUANTIZE_ZEROBUCKET - 1 - (buck))) : \ - (buck) == DTRACE_QUANTIZE_ZEROBUCKET ? 0 : \ - 1LL << ((buck) - DTRACE_QUANTIZE_ZEROBUCKET - 1)) - -#define DTRACE_LQUANTIZE_STEPSHIFT 48 -#define DTRACE_LQUANTIZE_STEPMASK ((uint64_t)UINT16_MAX << 48) -#define DTRACE_LQUANTIZE_LEVELSHIFT 32 -#define DTRACE_LQUANTIZE_LEVELMASK ((uint64_t)UINT16_MAX << 32) -#define DTRACE_LQUANTIZE_BASESHIFT 0 -#define DTRACE_LQUANTIZE_BASEMASK UINT32_MAX - -#define DTRACE_LQUANTIZE_STEP(x) \ - (uint16_t)(((x) & DTRACE_LQUANTIZE_STEPMASK) >> \ - DTRACE_LQUANTIZE_STEPSHIFT) - -#define DTRACE_LQUANTIZE_LEVELS(x) \ - (uint16_t)(((x) & DTRACE_LQUANTIZE_LEVELMASK) >> \ - DTRACE_LQUANTIZE_LEVELSHIFT) - -#define DTRACE_LQUANTIZE_BASE(x) \ - (int32_t)(((x) & DTRACE_LQUANTIZE_BASEMASK) >> \ - DTRACE_LQUANTIZE_BASESHIFT) - -#define DTRACE_USTACK_NFRAMES(x) (uint32_t)((x) & UINT32_MAX) -#define DTRACE_USTACK_STRSIZE(x) (uint32_t)((x) >> 32) -#define DTRACE_USTACK_ARG(x, y) \ - ((((uint64_t)(y)) << 32) | ((x) & UINT32_MAX)) - -#ifndef CONFIG_64BIT -# ifndef __LITTLE_ENDIAN -# define DTRACE_PTR(type, name) uint32_t name##pad; type *name -# else -# define DTRACE_PTR(type, name) type *name; uint32_t name##pad -# endif -#else -# define DTRACE_PTR(type, name) type *name -#endif - -#define DTRACEACT_NONE 0 -#define DTRACEACT_DIFEXPR 1 -#define DTRACEACT_EXIT 2 -#define DTRACEACT_PRINTF 3 -#define DTRACEACT_PRINTA 4 -#define DTRACEACT_LIBACT 5 - -#define DTRACEACT_PROC 0x0100 -#define DTRACEACT_USTACK (DTRACEACT_PROC + 1) -#define DTRACEACT_JSTACK (DTRACEACT_PROC + 2) -#define DTRACEACT_USYM (DTRACEACT_PROC + 3) -#define DTRACEACT_UMOD (DTRACEACT_PROC + 4) -#define DTRACEACT_UADDR (DTRACEACT_PROC + 5) - -#define DTRACEACT_PROC_DESTRUCTIVE 0x0200 -#define DTRACEACT_STOP (DTRACEACT_PROC_DESTRUCTIVE + 1) -#define DTRACEACT_RAISE (DTRACEACT_PROC_DESTRUCTIVE + 2) -#define DTRACEACT_SYSTEM (DTRACEACT_PROC_DESTRUCTIVE + 3) -#define DTRACEACT_FREOPEN (DTRACEACT_PROC_DESTRUCTIVE + 4) - -#define DTRACEACT_PROC_CONTROL 0x0300 - -#define DTRACEACT_KERNEL 0x0400 -#define DTRACEACT_STACK (DTRACEACT_KERNEL + 1) -#define DTRACEACT_SYM (DTRACEACT_KERNEL + 2) -#define DTRACEACT_MOD (DTRACEACT_KERNEL + 3) - -#define DTRACEACT_KERNEL_DESTRUCTIVE 0x0500 -#define DTRACEACT_BREAKPOINT (DTRACEACT_KERNEL_DESTRUCTIVE + 1) -#define DTRACEACT_PANIC (DTRACEACT_KERNEL_DESTRUCTIVE + 2) -#define DTRACEACT_CHILL (DTRACEACT_KERNEL_DESTRUCTIVE + 3) - -#define DTRACEACT_SPECULATIVE 0x0600 -#define DTRACEACT_SPECULATE (DTRACEACT_SPECULATIVE + 1) -#define DTRACEACT_COMMIT (DTRACEACT_SPECULATIVE + 2) -#define DTRACEACT_DISCARD (DTRACEACT_SPECULATIVE + 3) - -#define DTRACEACT_AGGREGATION 0x0700 -#define DTRACEAGG_COUNT (DTRACEACT_AGGREGATION + 1) -#define DTRACEAGG_MIN (DTRACEACT_AGGREGATION + 2) -#define DTRACEAGG_MAX (DTRACEACT_AGGREGATION + 3) -#define DTRACEAGG_AVG (DTRACEACT_AGGREGATION + 4) -#define DTRACEAGG_SUM (DTRACEACT_AGGREGATION + 5) -#define DTRACEAGG_STDDEV (DTRACEACT_AGGREGATION + 6) -#define DTRACEAGG_QUANTIZE (DTRACEACT_AGGREGATION + 7) -#define DTRACEAGG_LQUANTIZE (DTRACEACT_AGGREGATION + 8) - -#define DTRACEACT_CLASS(x) ((x) & 0xff00) - -#define DTRACEACT_ISAGG(x) \ - (DTRACEACT_CLASS(x) == DTRACEACT_AGGREGATION) - -#define DTRACEACT_ISDESTRUCTIVE(x) \ - (DTRACEACT_CLASS(x) == DTRACEACT_PROC_DESTRUCTIVE || \ - DTRACEACT_CLASS(x) == DTRACEACT_KERNEL_DESTRUCTIVE) - -#define DTRACEACT_ISSPECULATIVE(x) \ - (DTRACEACT_CLASS(x) == DTRACEACT_SPECULATIVE) - -#define DTRACEACT_ISPRINTFLIKE(x) \ - ((x) == DTRACEACT_PRINTF || (x) == DTRACEACT_PRINTA || \ - (x) == DTRACEACT_SYSTEM || (x) == DTRACEACT_FREOPEN) - -/* - * DTrace Faults - * - * The constants below DTRACEFLT_LIBRARY indicate probe processing faults; - * constants at or above DTRACEFLT_LIBRARY indicate faults in probe - * postprocessing at user-level. Probe processing faults induce an ERROR - * probe and are replicated in unistd.d to allow users' ERROR probes to decode - * the error condition using thse symbolic labels. - */ -#define DTRACEFLT_UNKNOWN 0 /* Unknown fault */ -#define DTRACEFLT_BADADDR 1 /* Bad address */ -#define DTRACEFLT_BADALIGN 2 /* Bad alignment */ -#define DTRACEFLT_ILLOP 3 /* Illegal operation */ -#define DTRACEFLT_DIVZERO 4 /* Divide-by-zero */ -#define DTRACEFLT_NOSCRATCH 5 /* Out of scratch space */ -#define DTRACEFLT_KPRIV 6 /* Illegal kernel access */ -#define DTRACEFLT_UPRIV 7 /* Illegal user access */ -#define DTRACEFLT_TUPOFLOW 8 /* Tuple stack overflow */ -#define DTRACEFLT_BADSTACK 9 /* Bad stack */ - -#define DTRACEFLT_LIBRARY 1000 /* Library-level fault */ - -#define DTRACEOPT_BUFSIZE 0 -#define DTRACEOPT_BUFPOLICY 1 -#define DTRACEOPT_DYNVARSIZE 2 -#define DTRACEOPT_AGGSIZE 3 -#define DTRACEOPT_SPECSIZE 4 -#define DTRACEOPT_NSPEC 5 -#define DTRACEOPT_STRSIZE 6 -#define DTRACEOPT_CLEANRATE 7 -#define DTRACEOPT_CPU 8 -#define DTRACEOPT_BUFRESIZE 9 -#define DTRACEOPT_GRABANON 10 -#define DTRACEOPT_FLOWINDENT 11 -#define DTRACEOPT_QUIET 12 -#define DTRACEOPT_STACKFRAMES 13 -#define DTRACEOPT_USTACKFRAMES 14 -#define DTRACEOPT_AGGRATE 15 -#define DTRACEOPT_SWITCHRATE 16 -#define DTRACEOPT_STATUSRATE 17 -#define DTRACEOPT_DESTRUCTIVE 18 -#define DTRACEOPT_STACKINDENT 19 -#define DTRACEOPT_RAWBYTES 20 -#define DTRACEOPT_JSTACKFRAMES 21 -#define DTRACEOPT_JSTACKSTRSIZE 22 -#define DTRACEOPT_AGGSORTKEY 23 -#define DTRACEOPT_AGGSORTREV 24 -#define DTRACEOPT_AGGSORTPOS 25 -#define DTRACEOPT_AGGSORTKEYPOS 26 -#define DTRACEOPT_QUIETRESIZE 27 -#define DTRACEOPT_MAX 28 - -#define DTRACEOPT_UNSET (dtrace_optval_t)-2 - -#define DTRACEOPT_BUFPOLICY_RING 0 -#define DTRACEOPT_BUFPOLICY_FILL 1 -#define DTRACEOPT_BUFPOLICY_SWITCH 2 - -#define DTRACEOPT_BUFRESIZE_AUTO 0 -#define DTRACEOPT_BUFRESIZE_MANUAL 1 - -typedef unsigned char uchar_t; -typedef unsigned int uint_t; -typedef unsigned long ulong_t; - -typedef long intptr_t; - -typedef uint8_t dtrace_stability_t; -typedef uint8_t dtrace_class_t; - -typedef uint16_t dtrace_actkind_t; - -typedef uint32_t dtrace_aggid_t; -typedef uint32_t dtrace_cacheid_t; -typedef uint32_t dtrace_epid_t; -typedef uint32_t dtrace_optid_t; -typedef uint32_t dtrace_specid_t; - -typedef uint64_t dtrace_aggvarid_t; -typedef uint64_t dtrace_genid_t; -typedef uint64_t dtrace_optval_t; - -typedef enum { - TRUE = -1, - FALSE = 0 -} boolean_t; - -typedef struct cred cred_t; -typedef __be32 ipaddr_t; - -typedef typeof(((struct pt_regs *)0)->ip) pc_t; - -#define P2ROUNDUP(x, a) (-(-(x) & -(a))) - -#if (BITS_PER_LONG == 64) || defined(CONFIG_KTIME_SCALAR) -# define KTIME_INIT(s, ns) { .tv64 = (s64)(s) * NSEC_PER_SEC + (s64)(ns) } -#else -# define KTIME_INIT(n, ns) { .tv = { .sec = (s), .nsec = (ns) } } -#endif -#define ktime_lt(t0, t1) ((t0).tv64 < (t1).tv64) -#define ktime_le(t0, t1) ((t0).tv64 <= (t1).tv64) -#define ktime_ge(t0, t1) ((t0).tv64 >= (t1).tv64) -#define ktime_gt(t0, t1) ((t0).tv64 > (t1).tv64) -#define ktime_nz(t0) ((t0).tv64 != 0LL) -#define ktime_cp(t0, t1) ((t0).tv64 = (t1).tv64) - -typedef struct dtrace_ppriv { - uint32_t dtpp_flags; - uid_t dtpp_uid; -} dtrace_ppriv_t; - -typedef struct dtrace_attribute { - dtrace_stability_t dtat_name; - dtrace_stability_t dtat_data; - dtrace_class_t dtat_class; -} dtrace_attribute_t; - -typedef struct dtrace_pattr { - dtrace_attribute_t dtpa_provider; - dtrace_attribute_t dtpa_mod; - dtrace_attribute_t dtpa_func; - dtrace_attribute_t dtpa_name; - dtrace_attribute_t dtpa_args; -} dtrace_pattr_t; - -typedef struct dtrace_providerdesc { - char dtvd_name[DTRACE_PROVNAMELEN]; - dtrace_pattr_t dtvd_attr; - dtrace_ppriv_t dtvd_priv; -} dtrace_providerdesc_t; - -// Defined in . -// typedef uint32_t dtrace_id_t; - -typedef struct dtrace_probedesc { - dtrace_id_t dtpd_id; - char dtpd_provider[DTRACE_PROVNAMELEN]; - char dtpd_mod[DTRACE_MODNAMELEN]; - char dtpd_func[DTRACE_FUNCNAMELEN]; - char dtpd_name[DTRACE_NAMELEN]; -} dtrace_probedesc_t; - -typedef struct dtrace_repldesc { - dtrace_probedesc_t dtrpd_match; - dtrace_probedesc_t dtrpd_create; -} dtrace_repldesc_t; - -typedef struct dtrace_argdesc { - dtrace_id_t dtargd_id; - int dtargd_ndx; - int dtargd_mapping; - char dtargd_native[DTRACE_ARGTYPELEN]; - char dtargd_xlate[DTRACE_ARGTYPELEN]; -} dtrace_argdesc_t; - -typedef struct dtrace_pops { - void (*dtps_provide)(void *, const dtrace_probedesc_t *); - void (*dtps_provide_module)(void *, struct module *); - int (*dtps_enable)(void *, dtrace_id_t, void *); - void (*dtps_disable)(void *, dtrace_id_t, void *); - void (*dtps_suspend)(void *, dtrace_id_t, void *); - void (*dtps_resume)(void *, dtrace_id_t, void *); - void (*dtps_getargdesc)(void *, dtrace_id_t, void *, - dtrace_argdesc_t *); - uint64_t (*dtps_getargval)(void *, dtrace_id_t, void *, int, int); - int (*dtps_usermode)(void *, dtrace_id_t, void *); - void (*dtps_destroy)(void *, dtrace_id_t, void *); -} dtrace_pops_t; - -typedef struct dtrace_helper_probedesc { - char *dthpb_mod; - char *dthpb_func; - char *dthpb_name; - uint64_t dthpb_base; - uint32_t *dthpb_offs; - uint32_t *dthpb_enoffs; - uint32_t dthpb_noffs; - uint32_t dthpb_nenoffs; - uint8_t *dthpb_args; - uint8_t dthpb_xargc; - uint8_t dthpb_nargc; - char *dthpb_xtypes; - char *dthpb_ntypes; -} dtrace_helper_probedesc_t; - -typedef struct dtrace_helper_provdesc { - char *dthpv_provname; - dtrace_pattr_t dthpv_pattr; -} dtrace_helper_provdesc_t; - -typedef struct dtrace_mops { - void (*dtms_create_probe)(void *, void *, dtrace_helper_probedesc_t *); - void *(*dtms_provide_pid)(void *, dtrace_helper_provdesc_t *, pid_t); - void (*dtms_remove_pid)(void *, dtrace_helper_provdesc_t *, pid_t); -} dtrace_mops_t; - -typedef struct dtrace_provider { - dtrace_pattr_t dtpv_attr; - dtrace_ppriv_t dtpv_priv; - dtrace_pops_t dtpv_pops; - char *dtpv_name; - void *dtpv_arg; - uint_t dtpv_defunct; - struct dtrace_provider *dtpv_next; -} dtrace_provider_t; - -typedef uint32_t dif_instr_t; - -typedef struct dtrace_diftype { - uint8_t dtdt_kind; - uint8_t dtdt_ckind; - uint8_t dtdt_flags; - uint8_t dtdt_pad; - uint32_t dtdt_size; -} dtrace_diftype_t; - -typedef struct dtrace_difv { - uint32_t dtdv_name; - uint32_t dtdv_id; - uint8_t dtdv_kind; - uint8_t dtdv_scope; - uint16_t dtdv_flags; - dtrace_diftype_t dtdv_type; -} dtrace_difv_t; - -typedef struct dtrace_difo { - dif_instr_t *dtdo_buf; - uint64_t *dtdo_inttab; - char *dtdo_strtab; - dtrace_difv_t *dtdo_vartab; - uint_t dtdo_len; - uint_t dtdo_intlen; - uint_t dtdo_strlen; - uint_t dtdo_varlen; - dtrace_diftype_t dtdo_rtype; - uint_t dtdo_refcnt; - uint_t dtdo_destructive; -#ifndef __KERNEL__ - dtrace_diftype_t orig_dtdo_rtype; - dof_relodesc_t *dtdo_kreltab; - dof_relodesc_t *dtdo_ureltab; - struct dt_node **dtdo_xlmtab; - uint_t dtdo_krelen; - uint_t dtdo_urelen; - uint_t dtdo_xlmlen; -#endif -} dtrace_difo_t; - -typedef struct dtrace_actdesc { - dtrace_difo_t *dtad_difo; - struct dtrace_actdesc *dtad_next; - dtrace_actkind_t dtad_kind; - uint32_t dtad_ntuple; - uint64_t dtad_arg; - uint64_t dtad_uarg; - int dtad_refcnt; -} dtrace_actdesc_t; - -typedef struct dtrace_predicate { - dtrace_difo_t *dtp_difo; - dtrace_cacheid_t dtp_cacheid; - int dtp_refcnt; -} dtrace_predicate_t; - -typedef struct dtrace_preddesc { - dtrace_difo_t *dtpdd_difo; - dtrace_predicate_t *dtpdd_predicate; -} dtrace_preddesc_t; - -typedef struct dtrace_ecbdesc { - dtrace_actdesc_t *dted_action; - dtrace_preddesc_t dted_pred; - dtrace_probedesc_t dted_probe; - uint64_t dted_uarg; - int dted_refcnt; -} dtrace_ecbdesc_t; - -typedef struct dtrace_statvar { - uint64_t dtsv_data; - size_t dtsv_size; - int dtsv_refcnt; - dtrace_difv_t dtsv_var; -} dtrace_statvar_t; - -/* - * DTrace Metadata Description Structures - * - * DTrace separates the trace data stream from the metadata stream. The only - * metadata tokens placed in the data stream are enabled probe identifiers - * (EPIDs) or (in the case of aggregations) aggregation identifiers. In order - * to determine the structure of the data, DTrace consumers pass the token to - * the kernel, and receive in return a corresponding description of the enabled - * probe (via the dtrace_eprobedesc structure) or the aggregation (via the - * dtrace_aggdesc structure). Both of these structures are expressed in terms - * of record descriptions (via the dtrace_recdesc structure) that describe the - * exact structure of the data. Some record descriptions may also contain a - * format identifier; this additional bit of metadata can be retrieved from the - * kernel, for which a format description is returned via the dtrace_fmtdesc - * structure. Note that all four of these structures must be bitness-neutral - * to allow for a 32-bit DTrace consumer on a 64-bit kernel. - */ -typedef struct dtrace_recdesc { - dtrace_actkind_t dtrd_action; /* kind of action */ - uint32_t dtrd_size; /* size of record */ - uint32_t dtrd_offset; /* offset in ECB's data */ - uint16_t dtrd_alignment; /* required alignment */ - uint16_t dtrd_format; /* format, if any */ - uint64_t dtrd_arg; /* action argument */ - uint64_t dtrd_uarg; /* user argument */ -} dtrace_recdesc_t; - -typedef struct dtrace_eprobedesc { - dtrace_epid_t dtepd_epid; /* enabled probe ID */ - dtrace_id_t dtepd_probeid; /* probe ID */ - uint64_t dtepd_uarg; /* library argument */ - uint32_t dtepd_size; /* total size */ - int dtepd_nrecs; /* number of records */ - dtrace_recdesc_t dtepd_rec[1]; /* recods themselves */ -} dtrace_eprobedesc_t; - -typedef struct dtrace_aggdesc { - DTRACE_PTR(char, dtagd_name); /* not filled in by kernel */ - dtrace_aggvarid_t dtagd_varid; /* not filled in by kernel */ - int dtagd_flags; /* not filled in by kernel */ - dtrace_aggid_t dtagd_id; /* aggregation ID */ - dtrace_epid_t dtagd_epid; /* enabled probe ID */ - uint32_t dtagd_size; /* size in bytes */ - int dtagd_nrecs; /* number of records */ - uint32_t dtagd_pad; /* explicit padding */ - dtrace_recdesc_t dtagd_rec[1]; /* record descriptions */ -} dtrace_aggdesc_t; - -typedef struct dtrace_fmtdesc { - DTRACE_PTR(char, dtfd_string); /* format string */ - int dtfd_length; /* length of format string */ - uint16_t dtfd_format; /* format identifier */ -} dtrace_fmtdesc_t; - -typedef struct dtrace_action { - dtrace_actkind_t dta_kind; - uint16_t dta_intuple; - uint32_t dta_refcnt; - dtrace_difo_t *dta_difo; - dtrace_recdesc_t dta_rec; - struct dtrace_action *dta_prev; - struct dtrace_action *dta_next; -} dtrace_action_t; - -struct dtrace_ecb; -typedef struct dtrace_ecb dtrace_ecb_t; - -typedef struct dtrace_probe { - dtrace_id_t dtpr_id; - dtrace_ecb_t *dtpr_ecb; - dtrace_ecb_t *dtpr_ecb_last; - void *dtpr_arg; - dtrace_cacheid_t dtpr_predcache; - int dtpr_aframes; - dtrace_provider_t *dtpr_provider; - char *dtpr_mod; - char *dtpr_func; - char *dtpr_name; - struct dtrace_probe *dtpr_nextmod; - struct dtrace_probe *dtpr_prevmod; - struct dtrace_probe *dtpr_nextfunc; - struct dtrace_probe *dtpr_prevfunc; - struct dtrace_probe *dtpr_nextname; - struct dtrace_probe *dtpr_prevname; - dtrace_genid_t dtpr_gen; -} dtrace_probe_t; - -struct dtrace_state; -typedef struct dtrace_state dtrace_state_t; - -struct dtrace_ecb { - dtrace_epid_t dte_epid; - uint32_t dte_alignment; - size_t dte_needed; - size_t dte_size; - dtrace_predicate_t *dte_predicate; - dtrace_action_t *dte_action; - struct dtrace_ecb *dte_next; - dtrace_state_t *dte_state; - uint32_t dte_cond; - dtrace_probe_t *dte_probe; - dtrace_action_t *dte_action_last; - uint64_t dte_uarg; -}; - -typedef enum dtrace_activity { - DTRACE_ACTIVITY_INACTIVE = 0, - DTRACE_ACTIVITY_WARMUP, - DTRACE_ACTIVITY_ACTIVE, - DTRACE_ACTIVITY_DRAINING, - DTRACE_ACTIVITY_COOLDOWN, - DTRACE_ACTIVITY_STOPPED, - DTRACE_ACTIVITY_KILLED -} dtrace_activity_t; - -typedef enum dtrace_dstate_state { - DTRACE_DSTATE_CLEAN = 0, - DTRACE_DSTATE_EMPTY, - DTRACE_DSTATE_DIRTY, - DTRACE_DSTATE_RINSING -} dtrace_dstate_state_t; - -typedef struct dtrace_key { - uint64_t dttk_value; - uint64_t dttk_size; -} dtrace_key_t; - -typedef struct dtrace_tuple { - uint32_t dtt_nkeys; - uint32_t dtt_pad; - dtrace_key_t dtt_key[1]; -} dtrace_tuple_t; - -typedef struct dtrace_dynvar { - uint64_t dtdv_hashval; - struct dtrace_dynvar *dtdv_next; - void *dtdv_data; - dtrace_tuple_t dtdv_tuple; -} dtrace_dynvar_t; - -typedef enum dtrace_dynvar_op { - DTRACE_DYNVAR_ALLOC, - DTRACE_DYNVAR_NOALLOC, - DTRACE_DYNVAR_DEALLOC -} dtrace_dynvar_op_t; - -typedef struct dtrace_dstate_percpu { - dtrace_dynvar_t *dtdsc_free; - dtrace_dynvar_t *dtdsc_dirty; - dtrace_dynvar_t *dtdsc_rinsing; - dtrace_dynvar_t *dtdsc_clean; - uint64_t dtdsc_drops; - uint64_t dtdsc_dirty_drops; - uint64_t dtdsc_rinsing_drops; -#ifdef CONFIG_64BIT - uint64_t dtdsc_pad; -#else - uint64_t dtdsc_pad[2]; -#endif -} dtrace_dstate_percpu_t; - -typedef struct dtrace_dynhash { - dtrace_dynvar_t *dtdh_chain; - uintptr_t dtdh_lock; -#ifdef CONFIG_64BIT - uintptr_t dtdh_pad[6]; -#else - uintptr_t dtdh_pad[14]; -#endif -} dtrace_dynhash_t; - -typedef struct dtrace_dstate { - void *dtds_base; - size_t dtds_size; - size_t dtds_hashsize; - size_t dtds_chunksize; - dtrace_dynhash_t *dtds_hash; - dtrace_dstate_state_t dtds_state; - dtrace_dstate_percpu_t *dtds_percpu; -} dtrace_dstate_t; - -typedef struct dtrace_vstate { - dtrace_state_t *dtvs_state; - dtrace_statvar_t **dtvs_globals; - int dtvs_nglobals; - dtrace_difv_t *dtvs_tlocals; - int dtvs_ntlocals; - dtrace_statvar_t **dtvs_locals; - int dtvs_nlocals; - dtrace_dstate_t dtvs_dynvars; -} dtrace_vstate_t; - -/* - * DTrace Machine State - * - * In the process of processing a fired probe, DTrace needs to track and/or - * cache some per-CPU state associated with that particular firing. This is - * state that is always discarded after the probe firing has completed, and - * much of it is not specific to any DTrace consumer, remaining valid across - * all ECBs. This state is tracked in the dtrace_mstate structure. - */ -#define DTRACE_MSTATE_ARGS 0x00000001 -#define DTRACE_MSTATE_PROBE 0x00000002 -#define DTRACE_MSTATE_EPID 0x00000004 -#define DTRACE_MSTATE_TIMESTAMP 0x00000008 -#define DTRACE_MSTATE_STACKDEPTH 0x00000010 -#define DTRACE_MSTATE_CALLER 0x00000020 -#define DTRACE_MSTATE_IPL 0x00000040 -#define DTRACE_MSTATE_FLTOFFS 0x00000080 -#define DTRACE_MSTATE_USTACKDEPTH 0x00000100 -#define DTRACE_MSTATE_UCALLER 0x00000200 - -typedef struct dtrace_mstate { - uintptr_t dtms_scratch_base; - uintptr_t dtms_scratch_ptr; - size_t dtms_scratch_size; - uint32_t dtms_present; - uint64_t dtms_arg[5]; - dtrace_epid_t dtms_epid; - ktime_t dtms_timestamp; - int dtms_stackdepth; - int dtms_ustackdepth; - struct dtrace_probe *dtms_probe; - uintptr_t dtms_caller; - uint64_t dtms_ucaller; - int dtms_ipl; - int dtms_fltoffs; - uintptr_t dtms_strtok; - uint32_t dtms_access; - dtrace_difo_t *dtms_difo; -} dtrace_mstate_t; - -typedef struct dtrace_buffer { - uint64_t dtb_offset; - uint64_t dtb_size; - uint32_t dtb_flags; - uint32_t dtb_drops; - caddr_t dtb_tomax; - caddr_t dtb_xamot; - uint32_t dtb_xamot_flags; - uint32_t dtb_xamot_drops; - uint64_t dtb_xamot_offset; - uint32_t dtb_errors; - uint32_t dtb_xamot_errors; -#ifndef CONFIG_64BIT - uint64_t dtb_pad1; -#endif -} dtrace_buffer_t; - -typedef enum dtrace_speculation_state { - DTRACESPEC_INACTIVE = 0, - DTRACESPEC_ACTIVE, - DTRACESPEC_ACTIVEONE, - DTRACESPEC_ACTIVEMANY, - DTRACESPEC_COMMITTING, - DTRACESPEC_COMMITTINGMANY, - DTRACESPEC_DISCARDING -} dtrace_speculation_state_t; - -typedef struct dtrace_speculation { - dtrace_speculation_state_t dtsp_state; - int dtsp_cleaning; - dtrace_buffer_t *dtsp_buffer; -} dtrace_speculation_t; - -typedef struct dtrace_aggregation { - dtrace_action_t dtag_action; - dtrace_aggid_t dtag_id; - dtrace_ecb_t *dtag_ecb; - dtrace_action_t *dtag_first; - uint32_t dtag_base; - uint8_t dtag_hasarg; - uint64_t dtag_initial; - void (*dtag_aggregate)(uint64_t *, uint64_t, uint64_t); -} dtrace_aggregation_t; - -typedef struct dtrace_cred { - const cred_t *dcr_cred; - uint8_t dcr_destructive; - uint8_t dcr_visible; - uint16_t dcr_action; -} dtrace_cred_t; - -struct dtrace_state { - dev_t dts_dev; - int dts_necbs; - dtrace_ecb_t **dts_ecbs; - dtrace_epid_t dts_epid; - size_t dts_needed; - struct dtrace_state *dts_anon; - dtrace_activity_t dts_activity; - dtrace_vstate_t dts_vstate; - dtrace_buffer_t *dts_buffer; - dtrace_buffer_t *dts_aggbuffer; - dtrace_speculation_t *dts_speculations; - int dts_nspeculations; - struct idr dts_agg_idr; - int dts_naggs; - uint64_t dts_errors; - uint32_t dts_speculations_busy; - uint32_t dts_speculations_unavail; - uint32_t dts_stkstroverflows; - uint32_t dts_dblerrors; - uint32_t dts_reserve; - ktime_t dts_laststatus; - cyclic_id_t dts_cleaner; - cyclic_id_t dts_deadman; - ktime_t dts_alive; - char dts_speculates; - char dts_destructive; - int dts_nformats; - char **dts_formats; - dtrace_optval_t dts_options[DTRACEOPT_MAX]; - dtrace_cred_t dts_cred; - size_t dts_nretained; -}; - -typedef struct dtrace_enabling { - dtrace_ecbdesc_t **dten_desc; - int dten_ndesc; - int dten_maxdesc; - dtrace_vstate_t *dten_vstate; - dtrace_genid_t dten_probegen; - dtrace_ecbdesc_t *dten_current; - int dten_error; - int dten_primed; - struct dtrace_enabling *dten_prev; - struct dtrace_enabling *dten_next; -} dtrace_enabling_t; - -typedef int dtrace_probekey_f(const char *, const char *, int); - -typedef struct dtrace_probekey { - const char *dtpk_prov; - dtrace_probekey_f *dtpk_pmatch; - const char *dtpk_mod; - dtrace_probekey_f *dtpk_mmatch; - const char *dtpk_func; - dtrace_probekey_f *dtpk_fmatch; - const char *dtpk_name; - dtrace_probekey_f *dtpk_nmatch; - dtrace_id_t dtpk_id; -} dtrace_probekey_t; - -typedef struct dtrace_hashbucket { - struct dtrace_hashbucket *dthb_next; - dtrace_probe_t *dthb_chain; - int dthb_len; -} dtrace_hashbucket_t; - -typedef struct dtrace_hash { - dtrace_hashbucket_t **dth_tab; - int dth_size; - int dth_mask; - int dth_nbuckets; - uintptr_t dth_nextoffs; - uintptr_t dth_prevoffs; - uintptr_t dth_stroffs; -} dtrace_hash_t; - -/* - * DTrace supports safe loads from probe context; if the address turns out to - * be invalid, a bit will be set by the kernel indicating that DTrace - * encountered a memory error, and DTrace will propagate the error to the user - * accordingly. However, there may exist some regions of memory in which an - * arbitrary load can change system state, and from which it is impossible to - * recover from such a load after it has been attempted. Examples of this may - * include memory in which programmable I/O registers are mapped (for which a - * read may have some implications for the device) or (in the specific case of - * UltraSPARC-I and -II) the virtual address hole. The platform is required - * to make DTrace aware of these toxic ranges; DTrace will then check that - * target addresses are not in a toxic range before attempting to issue a - * safe load. - */ -typedef struct dtrace_toxrange { - uintptr_t dtt_base; - uintptr_t dtt_limit; -} dtrace_toxrange_t; - -/* - * DTrace Helpers - * - * In general, DTrace establishes probes in processes and takes actions on - * processes without knowing their specific user-level structures. Instead of - * existing in the framework, process-specific knowledge is contained by the - * enabling D program -- which can apply process-specific knowledge by making - * appropriate use of DTrace primitives like copyin() and copyinstr() to - * operate on user-level data. However, there may exist some specific probes - * of particular semantic relevance that the application developer may wish to - * explicitly export. For example, an application may wish to export a probe - * at the point that it begins and ends certain well-defined transactions. In - * addition to providing probes, programs may wish to offer assistance for - * certain actions. For example, in highly dynamic environments (e.g., Java), - * it may be difficult to obtain a stack trace in terms of meaningful symbol - * names (the translation from instruction addresses to corresponding symbol - * names may only be possible in situ); these environments may wish to define - * a series of actions to be applied in situ to obtain a meaningful stack - * trace. - * - * These two mechanisms -- user-level statically defined tracing and assisting - * DTrace actions -- are provided via DTrace _helpers_. Helpers are specified - * via DOF, but unlike enabling DOF, helper DOF may contain definitions of - * providers, probes and their arguments. If a helper wishes to provide - * action assistance, probe descriptions and corresponding DIF actions may be - * specified in the helper DOF. For such helper actions, however, the probe - * description describes the specific helper: all DTrace helpers have the - * provider name "dtrace" and the module name "helper", and the name of the - * helper is contained in the function name (for example, the ustack() helper - * is named "ustack"). Any helper-specific name may be contained in the name - * (for example, if a helper were to have a constructor, it might be named - * "dtrace:helper::init"). Helper actions are only called when the - * action that they are helping is taken. Helper actions may only return DIF - * expressions, and may only call the following subroutines: - * - * alloca() <= Allocates memory out of the consumer's scratch space - * bcopy() <= Copies memory to scratch space - * copyin() <= Copies memory from user-level into consumer's scratch - * copyinto() <= Copies memory into a specific location in scratch - * copyinstr() <= Copies a string into a specific location in scratch - * - * Helper actions may only access the following built-in variables: - * - * curthread <= Current kthread_t pointer - * tid <= Current thread identifier - * pid <= Current process identifier - * ppid <= Parent process identifier - * uid <= Current user ID - * gid <= Current group ID - * execname <= Current executable name - * zonename <= Current zone name - * - * Helper actions may not manipulate or allocate dynamic variables, but they - * may have clause-local and statically-allocated global variables. The - * helper action variable state is specific to the helper action -- variables - * used by the helper action may not be accessed outside of the helper - * action, and the helper action may not access variables that like outside - * of it. Helper actions may not load from kernel memory at-large; they are - * restricting to loading current user state (via copyin() and variants) and - * scratch space. As with probe enablings, helper actions are executed in - * program order. The result of the helper action is the result of the last - * executing helper expression. - * - * Helpers -- composed of either providers/probes or probes/actions (or both) - * -- are added by opening the "helper" minor node, and issuing an ioctl(2) - * (DTRACEHIOC_ADDDOF) that specifies the dof_helper_t structure. This - * encapsulates the name and base address of the user-level library or - * executable publishing the helpers and probes as well as the DOF that - * contains the definitions of those helpers and probes. - * - * The DTRACEHIOC_ADD and DTRACEHIOC_REMOVE are left in place for legacy - * helpers and should no longer be used. No other ioctls are valid on the - * helper minor node. - */ -typedef struct dof_helper { - char dofhp_mod[DTRACE_MODNAMELEN]; /* executable or library name */ - uint64_t dofhp_addr; /* base address of object */ - uint64_t dofhp_dof; /* address of helper DOF */ -} dof_helper_t; - -/* - * DTrace Helper Implementation - * - * A description of the helper architecture may be found in . - * Each process contains a pointer to its helpers in its dtrace_helpers - * member. This is a pointer to a dtrace_helpers structure, which contains an - * array of pointers to dtrace_helper structures, helper variable state (shared - * among a process's helpers) and a generation count. (The generation count is - * used to provide an identifier when a helper is added so that it may be - * subsequently removed.) The dtrace_helper structure is self-explanatory, - * containing pointers to the objects needed to execute the helper. Note that - * helpers are _duplicated_ across fork(2), and destroyed on exec(2). No more - * than dtrace_helpers_max are allowed per-process. - */ -#define DTRACE_HELPER_ACTION_USTACK 0 -#define DTRACE_NHELPER_ACTIONS 1 - -typedef struct dtrace_helper_action { - int dtha_generation; /* helper action generation */ - int dtha_nactions; /* number of actions */ - dtrace_difo_t *dtha_predicate; /* helper action predicate */ - dtrace_difo_t **dtha_actions; /* array of actions */ - struct dtrace_helper_action *dtha_next; /* next helper action */ -} dtrace_helper_action_t; - -typedef struct dtrace_helper_provider { - int dthp_generation; /* helper provider generation */ - uint32_t dthp_ref; /* reference count */ - dof_helper_t dthp_prov; /* DOF w/ provider and probes */ -} dtrace_helper_provider_t; - -typedef struct dtrace_helpers { - dtrace_helper_action_t **dthps_actions; /* array of helper actions */ - dtrace_vstate_t dthps_vstate; /* helper action var. state */ - dtrace_helper_provider_t **dthps_provs; /* array of providers */ - uint_t dthps_nprovs; /* count of providers */ - uint_t dthps_maxprovs; /* provider array size */ - int dthps_generation; /* current generation */ - pid_t dthps_pid; /* pid of associated proc */ - int dthps_deferred; /* helper in deferred list */ - struct dtrace_helpers *dthps_next; /* next pointer */ - struct dtrace_helpers *dthps_prev; /* prev pointer */ -} dtrace_helpers_t; - -/* - * DTrace Helper Action Tracing - * - * Debugging helper actions can be arduous. To ease the development and - * debugging of helpers, DTrace contains a tracing-framework-within-a-tracing- - * framework: helper tracing. If dtrace_helptrace_enabled is non-zero (which - * it is by default on DEBUG kernels), all helper activity will be traced to a - * global, in-kernel ring buffer. Each entry includes a pointer to the specific - * helper, the location within the helper, and a trace of all local variables. - * The ring buffer may be displayed in a human-readable format with the - * ::dtrace_helptrace mdb(1) dcmd. - */ -#define DTRACE_HELPTRACE_NEXT (-1) -#define DTRACE_HELPTRACE_DONE (-2) -#define DTRACE_HELPTRACE_ERR (-3) - -typedef struct dtrace_helptrace { - dtrace_helper_action_t *dtht_helper; /* helper action */ - int dtht_where; /* where in helper action */ - int dtht_nlocals; /* number of locals */ - int dtht_fault; /* type of fault (if any) */ - int dtht_fltoffs; /* DIF offset */ - uint64_t dtht_illval; /* faulting value */ - uint64_t dtht_locals[1]; /* local variables */ -} dtrace_helptrace_t; - -extern struct mutex dtrace_lock; -extern struct mutex dtrace_provider_lock; -extern struct mutex dtrace_meta_lock; - -extern dtrace_genid_t dtrace_probegen; - -extern dtrace_pops_t dtrace_provider_ops; - -extern int dtrace_opens; -extern int dtrace_err_verbose; - -extern dtrace_toxrange_t *dtrace_toxrange; -extern int dtrace_toxranges; - -extern void dtrace_nullop(void); -extern int dtrace_enable_nullop(void); -extern int dtrace_istoxic(uintptr_t, size_t); - -/* - * DTrace Buffer Interface - * - * In order to get a snapshot of the principal or aggregation buffer, - * user-level passes a buffer description to the kernel with the dtrace_bufdesc - * structure. This describes which CPU user-level is interested in, and - * where user-level wishes the kernel to snapshot the buffer to (the - * dtbd_data field). The kernel uses the same structure to pass back some - * information regarding the buffer: the size of data actually copied out, the - * number of drops, the number of errors, and the offset of the oldest record. - * If the buffer policy is a "switch" policy, taking a snapshot of the - * principal buffer has the additional effect of switching the active and - * inactive buffers. Taking a snapshot of the aggregation buffer _always_ has - * the additional effect of switching the active and inactive buffers. - */ -typedef struct dtrace_bufdesc { - uint64_t dtbd_size; /* size of buffer */ - uint32_t dtbd_cpu; /* CPU or DTRACE_CPUALL */ - uint32_t dtbd_errors; /* number of errors */ - uint64_t dtbd_drops; /* number of drops */ - DTRACE_PTR(char, dtbd_data); /* data */ - uint64_t dtbd_oldest; /* offset of oldest record */ -} dtrace_bufdesc_t; - -/* - * DTrace Status - * - * The status of DTrace is relayed via the dtrace_status structure. This - * structure contains members to count drops other than the capacity drops - * available via the buffer interface (see above). This consists of dynamic - * drops (including capacity dynamic drops, rinsing drops and dirty drops), and - * speculative drops (including capacity speculative drops, drops due to busy - * speculative buffers and drops due to unavailable speculative buffers). - * Additionally, the status structure contains a field to indicate the number - * of "fill"-policy buffers have been filled and a boolean field to indicate - * that exit() has been called. If the dtst_exiting field is non-zero, no - * further data will be generated until tracing is stopped (at which time any - * enablings of the END action will be processed); if user-level sees that - * this field is non-zero, tracing should be stopped as soon as possible. - */ -typedef struct dtrace_status { - uint64_t dtst_dyndrops; /* dynamic drops */ - uint64_t dtst_dyndrops_rinsing; /* dyn drops due to rinsing */ - uint64_t dtst_dyndrops_dirty; /* dyn drops due to dirty */ - uint64_t dtst_specdrops; /* speculative drops */ - uint64_t dtst_specdrops_busy; /* spec drops due to busy */ - uint64_t dtst_specdrops_unavail; /* spec drops due to unavail */ - uint64_t dtst_errors; /* total errors */ - uint64_t dtst_filled; /* number of filled bufs */ - uint64_t dtst_stkstroverflows; /* stack string tab overflows */ - uint64_t dtst_dblerrors; /* errors in ERROR probes */ - char dtst_killed; /* non-zero if killed */ - char dtst_exiting; /* non-zero if exit() called */ - char dtst_pad[6]; /* pad out to 64-bit align */ -} dtrace_status_t; - -/* - * DTrace Configuration - * - * User-level may need to understand some elements of the kernel DTrace - * configuration in order to generate correct DIF. This information is - * conveyed via the dtrace_conf structure. - */ -typedef struct dtrace_conf { - uint_t dtc_difversion; /* supported DIF version */ - uint_t dtc_difintregs; /* # of DIF integer registers */ - uint_t dtc_diftupregs; /* # of DIF tuple registers */ - uint_t dtc_ctfmodel; /* CTF data model */ - /* Deviation from Solaris... Used to just be 8 padding entries. */ - uint_t dtc_maxbufs; /* max # of buffers */ - uint_t dtc_pad[7]; /* reserved for future use */ -} dtrace_conf_t; - -/* - * DTrace Probe Context Functions - */ -#undef ASSERT -#ifdef CONFIG_DT_DEBUG -# define ASSERT(x) ((void)((x) || dtrace_assfail(#x, __FILE__, __LINE__))) -#else -# define ASSERT(x) ((void)0) -#endif - -extern void dtrace_panic(const char *, ...); -extern int dtrace_assfail(const char *, const char *, int); -extern void dtrace_aggregate_min(uint64_t *, uint64_t, uint64_t); -extern void dtrace_aggregate_max(uint64_t *, uint64_t, uint64_t); -extern void dtrace_aggregate_quantize(uint64_t *, uint64_t, uint64_t); -extern void dtrace_aggregate_lquantize(uint64_t *, uint64_t, uint64_t); -extern void dtrace_aggregate_avg(uint64_t *, uint64_t, uint64_t); -extern void dtrace_aggregate_stddev(uint64_t *, uint64_t, uint64_t); -extern void dtrace_aggregate_count(uint64_t *, uint64_t, uint64_t); -extern void dtrace_aggregate_sum(uint64_t *, uint64_t, uint64_t); -extern void dtrace_aggregate(dtrace_aggregation_t *, dtrace_buffer_t *, - intptr_t, dtrace_buffer_t *, uint64_t, uint64_t); - -/* - * DTrace Probe Hashing Functions - */ -#define DTRACE_HASHNEXT(hash, probe) \ - (dtrace_probe_t **)((uintptr_t)(probe) + (hash)->dth_nextoffs) -#define DTRACE_HASHPREV(hash, probe) \ - (dtrace_probe_t **)((uintptr_t)(probe) + (hash)->dth_prevoffs) - -extern dtrace_hash_t *dtrace_hash_create(uintptr_t, uintptr_t, uintptr_t); -extern void dtrace_hash_add(dtrace_hash_t *, dtrace_probe_t *); -extern dtrace_probe_t *dtrace_hash_lookup(dtrace_hash_t *, dtrace_probe_t *); -extern int dtrace_hash_collisions(dtrace_hash_t *, dtrace_probe_t *); -extern void dtrace_hash_remove(dtrace_hash_t *, dtrace_probe_t *); - -/* - * DTrace Speculation Functions - */ -extern int dtrace_speculation(dtrace_state_t *); -extern void dtrace_speculation_commit(dtrace_state_t *, processorid_t, - dtrace_specid_t); -extern void dtrace_speculation_discard(dtrace_state_t *, processorid_t, - dtrace_specid_t); -extern void dtrace_speculation_clean(dtrace_state_t *); -extern dtrace_buffer_t *dtrace_speculation_buffer(dtrace_state_t *, - processorid_t, dtrace_specid_t); - -/* - * DTrace Non-Probe Context Utility Functions - */ - -/* - * DTrace Matching Functions - */ -extern dtrace_hash_t *dtrace_bymod; -extern dtrace_hash_t *dtrace_byfunc; -extern dtrace_hash_t *dtrace_byname; - -extern int dtrace_match_priv(const dtrace_probe_t *, uint32_t, uid_t); -extern int dtrace_match_probe(const dtrace_probe_t *, - const dtrace_probekey_t *, uint32_t, uid_t); -extern int dtrace_match_glob(const char *, const char *, int); -extern int dtrace_match_string(const char *, const char *, int); -extern int dtrace_match_nul(const char *, const char *, int); -extern int dtrace_match_nonzero(const char *, const char *, int); -extern int dtrace_match(const dtrace_probekey_t *, uint32_t, uid_t, - int (*matched)(dtrace_probe_t *, void *), void *); -extern void dtrace_probekey(const dtrace_probedesc_t *, dtrace_probekey_t *); - -/* - * DTrace Provider-to-Framework API Functions - */ -typedef uintptr_t dtrace_provider_id_t; -typedef uintptr_t dtrace_meta_provider_id_t; - -typedef struct dtrace_meta { - dtrace_mops_t dtm_mops; - char *dtm_name; - void *dtm_arg; - uint64_t dtm_count; -} dtrace_meta_t; - -extern dtrace_provider_t *dtrace_provider; -extern dtrace_meta_t *dtrace_meta_pid; -extern dtrace_helpers_t *dtrace_deferred_pid; - -extern int dtrace_register(const char *, const dtrace_pattr_t *, uint32_t, - const cred_t *, const dtrace_pops_t *, void *, - dtrace_provider_id_t *); -extern int dtrace_unregister(dtrace_provider_id_t); -extern void dtrace_invalidate(dtrace_provider_id_t); -extern int dtrace_attached(void); -extern int dtrace_condense(dtrace_provider_id_t); - -extern int dtrace_meta_register(const char *, const dtrace_mops_t *, void *, - dtrace_meta_provider_id_t *); -extern int dtrace_meta_unregister(dtrace_meta_provider_id_t); - -/* - * DTrace Privilege Check Functions - */ -extern int dtrace_priv_proc_destructive(dtrace_state_t *); -extern int dtrace_priv_proc_control(dtrace_state_t *); -extern int dtrace_priv_proc(dtrace_state_t *); -extern int dtrace_priv_kernel(dtrace_state_t *); - -/* - * DTrace Probe Management Functions - */ -#define DTRACE_ANCHORED(probe) ((probe)->dtpr_func[0] != '\0') -#define DTRACE_FLAGS2FLT(flags) \ - (((flags) & CPU_DTRACE_BADADDR) ? DTRACEFLT_BADADDR : \ - ((flags) & CPU_DTRACE_ILLOP) ? DTRACEFLT_ILLOP : \ - ((flags) & CPU_DTRACE_DIVZERO) ? DTRACEFLT_DIVZERO : \ - ((flags) & CPU_DTRACE_KPRIV) ? DTRACEFLT_KPRIV : \ - ((flags) & CPU_DTRACE_UPRIV) ? DTRACEFLT_UPRIV : \ - ((flags) & CPU_DTRACE_TUPOFLOW) ? DTRACEFLT_TUPOFLOW : \ - ((flags) & CPU_DTRACE_BADALIGN) ? DTRACEFLT_BADALIGN : \ - ((flags) & CPU_DTRACE_NOSCRATCH) ? DTRACEFLT_NOSCRATCH : \ - ((flags) & CPU_DTRACE_BADSTACK) ? DTRACEFLT_BADSTACK : \ - DTRACEFLT_UNKNOWN) - - -extern dtrace_id_t dtrace_probe_create(dtrace_provider_id_t, const char *, - const char *, const char *, int, - void *); -extern int dtrace_probe_enable(const dtrace_probedesc_t *, - dtrace_enabling_t *); -extern void *dtrace_probe_arg(dtrace_provider_id_t, dtrace_id_t); -extern void dtrace_probe_description(const dtrace_probe_t *, - dtrace_probedesc_t *); -extern void dtrace_probe_provide(dtrace_probedesc_t *, dtrace_provider_t *); -extern void dtrace_probe(dtrace_id_t, uintptr_t, uintptr_t, uintptr_t, - uintptr_t, uintptr_t); -extern void dtrace_probe_init(void); -extern void dtrace_probe_exit(void); -extern void dtrace_probe_remove_id(dtrace_id_t); -extern dtrace_probe_t *dtrace_probe_lookup_id(dtrace_id_t); -extern dtrace_id_t dtrace_probe_lookup(dtrace_provider_id_t, const char *, - const char *, const char *); -extern dtrace_probe_t *dtrace_probe_get_next(dtrace_id_t); -extern int dtrace_probe_for_each(int (*)(int, void *, void *), void *); - -/* - * DTrace Kernel Hooks - */ -extern void (*dtrace_modload)(struct module *); -extern void (*dtrace_modunload)(struct module *); - -/* - * DTrace DIF Object Functions - * - * DTrace Intermediate Format (DIF) - * - * The following definitions describe the DTrace Intermediate Format (DIF), a - * a RISC-like instruction set and program encoding used to represent - * predicates and actions that can be bound to DTrace probes. The constants - * below defining the number of available registers are suggested minimums; the - * compiler should use DTRACEIOC_CONF to dynamically obtain the number of - * registers provided by the current DTrace implementation. - */ -#define DIF_VERSION_1 1 -#define DIF_VERSION_2 2 -#define DIF_VERSION DIF_VERSION_2 -#define DIF_DIR_NREGS 8 -#define DIF_DTR_NREGS 8 - -#define DIF_OP_OR 1 /* or r1, r2, rd */ -#define DIF_OP_XOR 2 /* xor r1, r2, rd */ -#define DIF_OP_AND 3 /* and r1, r2, rd */ -#define DIF_OP_SLL 4 /* sll r1, r2, rd */ -#define DIF_OP_SRL 5 /* srl r1, r2, rd */ -#define DIF_OP_SUB 6 /* sub r1, r2, rd */ -#define DIF_OP_ADD 7 /* add r1, r2, rd */ -#define DIF_OP_MUL 8 /* mul r1, r2, rd */ -#define DIF_OP_SDIV 9 /* sdiv r1, r2, rd */ -#define DIF_OP_UDIV 10 /* udiv r1, r2, rd */ -#define DIF_OP_SREM 11 /* srem r1, r2, rd */ -#define DIF_OP_UREM 12 /* urem r1, r2, rd */ -#define DIF_OP_NOT 13 /* not r1, rd */ -#define DIF_OP_MOV 14 /* mov r1, rd */ -#define DIF_OP_CMP 15 /* cmp r1, r2 */ -#define DIF_OP_TST 16 /* tst r1 */ -#define DIF_OP_BA 17 /* ba label */ -#define DIF_OP_BE 18 /* be label */ -#define DIF_OP_BNE 19 /* bne label */ -#define DIF_OP_BG 20 /* bg label */ -#define DIF_OP_BGU 21 /* bgu label */ -#define DIF_OP_BGE 22 /* bge label */ -#define DIF_OP_BGEU 23 /* bgeu label */ -#define DIF_OP_BL 24 /* bl label */ -#define DIF_OP_BLU 25 /* blu label */ -#define DIF_OP_BLE 26 /* ble label */ -#define DIF_OP_BLEU 27 /* bleu label */ -#define DIF_OP_LDSB 28 /* ldsb [r1], rd */ -#define DIF_OP_LDSH 29 /* ldsh [r1], rd */ -#define DIF_OP_LDSW 30 /* ldsw [r1], rd */ -#define DIF_OP_LDUB 31 /* ldub [r1], rd */ -#define DIF_OP_LDUH 32 /* lduh [r1], rd */ -#define DIF_OP_LDUW 33 /* lduw [r1], rd */ -#define DIF_OP_LDX 34 /* ldx [r1], rd */ -#define DIF_OP_RET 35 /* ret rd */ -#define DIF_OP_NOP 36 /* nop */ -#define DIF_OP_SETX 37 /* setx intindex, rd */ -#define DIF_OP_SETS 38 /* sets strindex, rd */ -#define DIF_OP_SCMP 39 /* scmp r1, r2 */ -#define DIF_OP_LDGA 40 /* ldga var, ri, rd */ -#define DIF_OP_LDGS 41 /* ldgs var, rd */ -#define DIF_OP_STGS 42 /* stgs var, rs */ -#define DIF_OP_LDTA 43 /* ldta var, ri, rd */ -#define DIF_OP_LDTS 44 /* ldts var, rd */ -#define DIF_OP_STTS 45 /* stts var, rs */ -#define DIF_OP_SRA 46 /* sra r1, r2, rd */ -#define DIF_OP_CALL 47 /* call subr, rd */ -#define DIF_OP_PUSHTR 48 /* pushtr type, rs, rr */ -#define DIF_OP_PUSHTV 49 /* pushtv type, rs, rv */ -#define DIF_OP_POPTS 50 /* popts */ -#define DIF_OP_FLUSHTS 51 /* flushts */ -#define DIF_OP_LDGAA 52 /* ldgaa var, rd */ -#define DIF_OP_LDTAA 53 /* ldtaa var, rd */ -#define DIF_OP_STGAA 54 /* stgaa var, rs */ -#define DIF_OP_STTAA 55 /* sttaa var, rs */ -#define DIF_OP_LDLS 56 /* ldls var, rd */ -#define DIF_OP_STLS 57 /* stls var, rs */ -#define DIF_OP_ALLOCS 58 /* allocs r1, rd */ -#define DIF_OP_COPYS 59 /* copys r1, r2, rd */ -#define DIF_OP_STB 60 /* stb r1, [rd] */ -#define DIF_OP_STH 61 /* sth r1, [rd] */ -#define DIF_OP_STW 62 /* stw r1, [rd] */ -#define DIF_OP_STX 63 /* stx r1, [rd] */ -#define DIF_OP_ULDSB 64 /* uldsb [r1], rd */ -#define DIF_OP_ULDSH 65 /* uldsh [r1], rd */ -#define DIF_OP_ULDSW 66 /* uldsw [r1], rd */ -#define DIF_OP_ULDUB 67 /* uldub [r1], rd */ -#define DIF_OP_ULDUH 68 /* ulduh [r1], rd */ -#define DIF_OP_ULDUW 69 /* ulduw [r1], rd */ -#define DIF_OP_ULDX 70 /* uldx [r1], rd */ -#define DIF_OP_RLDSB 71 /* rldsb [r1], rd */ -#define DIF_OP_RLDSH 72 /* rldsh [r1], rd */ -#define DIF_OP_RLDSW 73 /* rldsw [r1], rd */ -#define DIF_OP_RLDUB 74 /* rldub [r1], rd */ -#define DIF_OP_RLDUH 75 /* rlduh [r1], rd */ -#define DIF_OP_RLDUW 76 /* rlduw [r1], rd */ -#define DIF_OP_RLDX 77 /* rldx [r1], rd */ -#define DIF_OP_XLATE 78 /* xlate xlrindex, rd */ -#define DIF_OP_XLARG 79 /* xlarg xlrindex, rd */ - -#define DIF_INTOFF_MAX 0xffff -#define DIF_STROFF_MAX 0xffff -#define DIF_REGISTER_MAX 0xff -#define DIF_VARIABLE_MAX 0xffff -#define DIF_SUBROUTINE_MAX 0xffff - -#define DIF_VAR_ARRAY_MIN 0x0000 -#define DIF_VAR_ARRAY_UBASE 0x0080 -#define DIF_VAR_ARRAY_MAX 0x00ff - -#define DIF_VAR_OTHER_MIN 0x0100 -#define DIF_VAR_OTHER_UBASE 0x0500 -#define DIF_VAR_OTHER_MAX 0xffff - -#define DIF_VAR_ARGS 0x0000 -#define DIF_VAR_REGS 0x0001 -#define DIF_VAR_UREGS 0x0002 -#define DIF_VAR_CURTHREAD 0x0100 -#define DIF_VAR_TIMESTAMP 0x0101 -#define DIF_VAR_VTIMESTAMP 0x0102 -#define DIF_VAR_IPL 0x0103 -#define DIF_VAR_EPID 0x0104 -#define DIF_VAR_ID 0x0105 -#define DIF_VAR_ARG0 0x0106 -#define DIF_VAR_ARG1 0x0107 -#define DIF_VAR_ARG2 0x0108 -#define DIF_VAR_ARG3 0x0109 -#define DIF_VAR_ARG4 0x010a -#define DIF_VAR_ARG5 0x010b -#define DIF_VAR_ARG6 0x010c -#define DIF_VAR_ARG7 0x010d -#define DIF_VAR_ARG8 0x010e -#define DIF_VAR_ARG9 0x010f -#define DIF_VAR_STACKDEPTH 0x0110 -#define DIF_VAR_CALLER 0x0111 -#define DIF_VAR_PROBEPROV 0x0112 -#define DIF_VAR_PROBEMOD 0x0113 -#define DIF_VAR_PROBEFUNC 0x0114 -#define DIF_VAR_PROBENAME 0x0115 -#define DIF_VAR_PID 0x0116 -#define DIF_VAR_TID 0x0117 -#define DIF_VAR_EXECNAME 0x0118 -#define DIF_VAR_ZONENAME 0x0119 -#define DIF_VAR_WALLTIMESTAMP 0x011a -#define DIF_VAR_USTACKDEPTH 0x011b -#define DIF_VAR_UCALLER 0x011c -#define DIF_VAR_PPID 0x011d -#define DIF_VAR_UID 0x011e -#define DIF_VAR_GID 0x011f -#define DIF_VAR_ERRNO 0x0120 -#define DIF_VAR_CURCPU 0x0121 - -#define DIF_SUBR_RAND 0 -#define DIF_SUBR_MUTEX_OWNED 1 -#define DIF_SUBR_MUTEX_OWNER 2 -#define DIF_SUBR_MUTEX_TYPE_ADAPTIVE 3 -#define DIF_SUBR_MUTEX_TYPE_SPIN 4 -#define DIF_SUBR_RW_READ_HELD 5 -#define DIF_SUBR_RW_WRITE_HELD 6 -#define DIF_SUBR_RW_ISWRITER 7 -#define DIF_SUBR_COPYIN 8 -#define DIF_SUBR_COPYINSTR 9 -#define DIF_SUBR_SPECULATION 10 -#define DIF_SUBR_PROGENYOF 11 -#define DIF_SUBR_STRLEN 12 -#define DIF_SUBR_COPYOUT 13 -#define DIF_SUBR_COPYOUTSTR 14 -#define DIF_SUBR_ALLOCA 15 -#define DIF_SUBR_BCOPY 16 -#define DIF_SUBR_COPYINTO 17 -#define DIF_SUBR_MSGDSIZE 18 -#define DIF_SUBR_MSGSIZE 19 -#define DIF_SUBR_GETMAJOR 20 -#define DIF_SUBR_GETMINOR 21 -#define DIF_SUBR_DDI_PATHNAME 22 -#define DIF_SUBR_STRJOIN 23 -#define DIF_SUBR_LLTOSTR 24 -#define DIF_SUBR_BASENAME 25 -#define DIF_SUBR_DIRNAME 26 -#define DIF_SUBR_CLEANPATH 27 -#define DIF_SUBR_STRCHR 28 -#define DIF_SUBR_STRRCHR 29 -#define DIF_SUBR_STRSTR 30 -#define DIF_SUBR_STRTOK 31 -#define DIF_SUBR_SUBSTR 32 -#define DIF_SUBR_INDEX 33 -#define DIF_SUBR_RINDEX 34 -#define DIF_SUBR_HTONS 35 -#define DIF_SUBR_HTONL 36 -#define DIF_SUBR_HTONLL 37 -#define DIF_SUBR_NTOHS 38 -#define DIF_SUBR_NTOHL 39 -#define DIF_SUBR_NTOHLL 40 -#define DIF_SUBR_INET_NTOP 41 -#define DIF_SUBR_INET_NTOA 42 -#define DIF_SUBR_INET_NTOA6 43 -#define DIF_SUBR_D_PATH 44 - -#define DIF_SUBR_MAX 44 - -#define DIF_INSTR_OP(i) (((i) >> 24) & 0xff) -#define DIF_INSTR_R1(i) (((i) >> 16) & 0xff) -#define DIF_INSTR_R2(i) (((i) >> 8) & 0xff) -#define DIF_INSTR_RD(i) ((i) & 0xff) -#define DIF_INSTR_RS(i) ((i) & 0xff) -#define DIF_INSTR_LABEL(i) ((i) & 0xffffff) -#define DIF_INSTR_VAR(i) (((i) >> 8) & 0xffff) -#define DIF_INSTR_INTEGER(i) (((i) >> 8) & 0xffff) -#define DIF_INSTR_STRING(i) (((i) >> 8) & 0xffff) -#define DIF_INSTR_SUBR(i) (((i) >> 8) & 0xffff) -#define DIF_INSTR_TYPE(i) (((i) >> 16) & 0xff) -#define DIF_INSTR_XLREF(i) (((i) >> 8) & 0xffff) -#define DIF_INSTR_FMT(op, r1, r2, d) \ - (((op) << 24) | ((r1) << 16) | ((r2) << 8) | (d)) - -#define DIF_INSTR_NOT(r1, d) (DIF_INSTR_FMT(DIF_OP_NOT, r1, 0, d)) -#define DIF_INSTR_MOV(r1, d) (DIF_INSTR_FMT(DIF_OP_MOV, r1, 0, d)) -#define DIF_INSTR_CMP(op, r1, r2) (DIF_INSTR_FMT(op, r1, r2, 0)) -#define DIF_INSTR_TST(r1) (DIF_INSTR_FMT(DIF_OP_TST, r1, 0, 0)) -#define DIF_INSTR_BRANCH(op, label) (((op) << 24) | (label)) -#define DIF_INSTR_LOAD(op, r1, d) (DIF_INSTR_FMT(op, r1, 0, d)) -#define DIF_INSTR_STORE(op, r1, d) (DIF_INSTR_FMT(op, r1, 0, d)) -#define DIF_INSTR_SETX(i, d) ((DIF_OP_SETX << 24) | ((i) << 8) | (d)) -#define DIF_INSTR_SETS(s, d) ((DIF_OP_SETS << 24) | ((s) << 8) | (d)) -#define DIF_INSTR_RET(d) (DIF_INSTR_FMT(DIF_OP_RET, 0, 0, d)) -#define DIF_INSTR_NOP (DIF_OP_NOP << 24) -#define DIF_INSTR_LDA(op, v, r, d) (DIF_INSTR_FMT(op, v, r, d)) -#define DIF_INSTR_LDV(op, v, d) (((op) << 24) | ((v) << 8) | (d)) -#define DIF_INSTR_STV(op, v, rs) (((op) << 24) | ((v) << 8) | (rs)) -#define DIF_INSTR_CALL(s, d) ((DIF_OP_CALL << 24) | ((s) << 8) | (d)) -#define DIF_INSTR_PUSHTS(op, t, r2, rs) (DIF_INSTR_FMT(op, t, r2, rs)) -#define DIF_INSTR_POPTS (DIF_OP_POPTS << 24) -#define DIF_INSTR_FLUSHTS (DIF_OP_FLUSHTS << 24) -#define DIF_INSTR_ALLOCS(r1, d) (DIF_INSTR_FMT(DIF_OP_ALLOCS, r1, 0, d)) -#define DIF_INSTR_COPYS(r1, r2, d) (DIF_INSTR_FMT(DIF_OP_COPYS, r1, r2, d)) -#define DIF_INSTR_XLATE(op, r, d) (((op) << 24) | ((r) << 8) | (d)) - -#define DIF_REG_R0 0 - -#define DIF_TYPE_CTF 0 -#define DIF_TYPE_STRING 1 - -#define DIF_TF_BYREF 0x1 - -#define DIFV_KIND_ARRAY 0 -#define DIFV_KIND_SCALAR 1 - -#define DIFV_SCOPE_GLOBAL 0 -#define DIFV_SCOPE_THREAD 1 -#define DIFV_SCOPE_LOCAL 2 - -#define DIFV_F_REF 0x1 -#define DIFV_F_MOD 0x2 - -/* - * Test whether alloc_sz bytes will fit in the scratch region. We isolate - * alloc_sz on the righthand side of the comparison in order to avoid overflow - * or underflow in the comparison with it. This is simpler than the INRANGE - * check above, because we know that the dtms_scratch_ptr is valid in the - * range. Allocations of size zero are allowed. - */ -#define DTRACE_INSCRATCH(mstate, alloc_sz) \ - ((mstate)->dtms_scratch_base + (mstate)->dtms_scratch_size - \ - (mstate)->dtms_scratch_ptr >= (alloc_sz)) - -extern uint8_t dtrace_load8(uintptr_t); -extern uint16_t dtrace_load16(uintptr_t); -extern uint32_t dtrace_load32(uintptr_t); -extern uint64_t dtrace_load64(uintptr_t); - -extern void dtrace_bzero(void *, size_t); - -extern int dtrace_vcanload(void *, dtrace_diftype_t *, dtrace_mstate_t *, - dtrace_vstate_t *); - -extern int dtrace_difo_validate(dtrace_difo_t *, dtrace_vstate_t *, uint_t, - const cred_t *); -extern int dtrace_difo_validate_helper(dtrace_difo_t *); -extern int dtrace_difo_cacheable(dtrace_difo_t *); -extern void dtrace_difo_hold(dtrace_difo_t *); -extern void dtrace_difo_init(dtrace_difo_t *, dtrace_vstate_t *); -extern void dtrace_difo_release(dtrace_difo_t *, dtrace_vstate_t *); - -extern uint64_t dtrace_dif_emulate(dtrace_difo_t *, dtrace_mstate_t *, - dtrace_vstate_t *, dtrace_state_t *); - -/* - * DTrace Format Functions - */ -extern uint16_t dtrace_format_add(dtrace_state_t *, char *); -extern void dtrace_format_remove(dtrace_state_t *, uint16_t); -extern void dtrace_format_destroy(dtrace_state_t *); - -/* - * DTrace Predicate Functions - */ -extern dtrace_predicate_t *dtrace_predicate_create(dtrace_difo_t *); -extern void dtrace_predicate_hold(dtrace_predicate_t *); -extern void dtrace_predicate_release(dtrace_predicate_t *, dtrace_vstate_t *); - -/* - * DTrace Action Description Functions - */ -extern dtrace_actdesc_t *dtrace_actdesc_create(dtrace_actkind_t, uint32_t, - uint64_t, uint64_t); -extern void dtrace_actdesc_hold(dtrace_actdesc_t *); -extern void dtrace_actdesc_release(dtrace_actdesc_t *, dtrace_vstate_t *); - -/* - * DTrace Helper Functions - */ -extern void dtrace_helpers_destroy(struct task_struct *); -extern uint64_t dtrace_helper(int, dtrace_mstate_t *, dtrace_state_t *, - uint64_t, uint64_t); - -/* - * DTrace ECB Functions - */ -extern dtrace_ecb_t *dtrace_ecb_create_cache; - -extern int dtrace_ecb_create_enable(dtrace_probe_t *, void *); -extern void dtrace_ecb_disable(dtrace_ecb_t *); -extern void dtrace_ecb_destroy(dtrace_ecb_t *); -extern void dtrace_ecb_resize(dtrace_ecb_t *); -extern int dtrace_ecb_enable(dtrace_ecb_t *); -extern dtrace_ecb_t *dtrace_epid2ecb(dtrace_state_t *, dtrace_epid_t); -extern dtrace_aggregation_t *dtrace_aggid2agg(dtrace_state_t *, - dtrace_aggid_t); - -/* - * DTrace Buffer Functions - * - * DTrace Buffers - * - * Principal buffers, aggregation buffers, and speculative buffers are all - * managed with the dtrace_buffer structure. By default, this structure - * includes twin data buffers -- dtb_tomax and dtb_xamot -- that serve as the - * active and passive buffers, respectively. For speculative buffers, - * dtb_xamot will be NULL; for "ring" and "fill" buffers, dtb_xamot will point - * to a scratch buffer. For all buffer types, the dtrace_buffer structure is - * always allocated on a per-CPU basis; a single dtrace_buffer structure is - * never shared among CPUs. (That is, there is never true sharing of the - * dtrace_buffer structure; to prevent false sharing of the structure, it must - * always be aligned to the coherence granularity -- generally 64 bytes.) - * - * One of the critical design decisions of DTrace is that a given ECB always - * stores the same quantity and type of data. This is done to assure that the - * only metadata required for an ECB's traced data is the EPID. That is, from - * the EPID, the consumer can determine the data layout. (The data buffer - * layout is shown schematically below.) By assuring that one can determine - * data layout from the EPID, the metadata stream can be separated from the - * data stream -- simplifying the data stream enormously. - * - * base of data buffer ---> +------+--------------------+------+ - * | EPID | data | EPID | - * +------+--------+------+----+------+ - * | data | EPID | data | - * +---------------+------+-----------+ - * | data, cont. | - * +------+--------------------+------+ - * | EPID | data | | - * +------+--------------------+ | - * | || | - * | || | - * | \/ | - * : : - * . . - * . . - * . . - * : : - * | | - * limit of data buffer ---> +----------------------------------+ - * - * When evaluating an ECB, dtrace_probe() determines if the ECB's needs of the - * principal buffer (both scratch and payload) exceed the available space. If - * the ECB's needs exceed available space (and if the principal buffer policy - * is the default "switch" policy), the ECB is dropped, the buffer's drop count - * is incremented, and processing advances to the next ECB. If the ECB's needs - * can be met with the available space, the ECB is processed, but the offset in - * the principal buffer is only advanced if the ECB completes processing - * without error. - * - * When a buffer is to be switched (either because the buffer is the principal - * buffer with a "switch" policy or because it is an aggregation buffer), a - * cross call is issued to the CPU associated with the buffer. In the cross - * call context, interrupts are disabled, and the active and the inactive - * buffers are atomically switched. This involves switching the data pointers, - * copying the various state fields (offset, drops, errors, etc.) into their - * inactive equivalents, and clearing the state fields. Because interrupts are - * disabled during this procedure, the switch is guaranteed to appear atomic to - * dtrace_probe(). - * - * DTrace Ring Buffering - * - * To process a ring buffer correctly, one must know the oldest valid record. - * Processing starts at the oldest record in the buffer and continues until - * the end of the buffer is reached. Processing then resumes starting with - * the record stored at offset 0 in the buffer, and continues until the - * youngest record is processed. If trace records are of a fixed-length, - * determining the oldest record is trivial: - * - * - If the ring buffer has not wrapped, the oldest record is the record - * stored at offset 0. - * - * - If the ring buffer has wrapped, the oldest record is the record stored - * at the current offset. - * - * With variable length records, however, just knowing the current offset - * doesn't suffice for determining the oldest valid record: assuming that one - * allows for arbitrary data, one has no way of searching forward from the - * current offset to find the oldest valid record. (That is, one has no way - * of separating data from metadata.) It would be possible to simply refuse to - * process any data in the ring buffer between the current offset and the - * limit, but this leaves (potentially) an enormous amount of otherwise valid - * data unprocessed. - * - * To effect ring buffering, we track two offsets in the buffer: the current - * offset and the _wrapped_ offset. If a request is made to reserve some - * amount of data, and the buffer has wrapped, the wrapped offset is - * incremented until the wrapped offset minus the current offset is greater - * than or equal to the reserve request. This is done by repeatedly looking - * up the ECB corresponding to the EPID at the current wrapped offset, and - * incrementing the wrapped offset by the size of the data payload - * corresponding to that ECB. If this offset is greater than or equal to the - * limit of the data buffer, the wrapped offset is set to 0. Thus, the - * current offset effectively "chases" the wrapped offset around the buffer. - * Schematically: - * - * base of data buffer ---> +------+--------------------+------+ - * | EPID | data | EPID | - * +------+--------+------+----+------+ - * | data | EPID | data | - * +---------------+------+-----------+ - * | data, cont. | - * +------+---------------------------+ - * | EPID | data | - * current offset ---> +------+---------------------------+ - * | invalid data | - * wrapped offset ---> +------+--------------------+------+ - * | EPID | data | EPID | - * +------+--------+------+----+------+ - * | data | EPID | data | - * +---------------+------+-----------+ - * : : - * . . - * . ... valid data ... . - * . . - * : : - * +------+-------------+------+------+ - * | EPID | data | EPID | data | - * +------+------------++------+------+ - * | data, cont. | leftover | - * limit of data buffer ---> +-------------------+--------------+ - * - * If the amount of requested buffer space exceeds the amount of space - * available between the current offset and the end of the buffer: - * - * (1) all words in the data buffer between the current offset and the limit - * of the data buffer (marked "leftover", above) are set to - * DTRACE_EPIDNONE - * - * (2) the wrapped offset is set to zero - * - * (3) the iteration process described above occurs until the wrapped offset - * is greater than the amount of desired space. - * - * The wrapped offset is implemented by (re-)using the inactive offset. - * In a "switch" buffer policy, the inactive offset stores the offset in - * the inactive buffer; in a "ring" buffer policy, it stores the wrapped - * offset. - * - * DTrace Scratch Buffering - * - * Some ECBs may wish to allocate dynamically-sized temporary scratch memory. - * To accommodate such requests easily, scratch memory may be allocated in - * the buffer beyond the current offset plus the needed memory of the current - * ECB. If there isn't sufficient room in the buffer for the requested amount - * of scratch space, the allocation fails and an error is generated. Scratch - * memory is tracked in the dtrace_mstate_t and is automatically freed when - * the ECB ceases processing. Note that ring buffers cannot allocate their - * scratch from the principal buffer -- lest they needlessly overwrite older, - * valid data. Ring buffers therefore have their own dedicated scratch buffer - * from which scratch is allocated. - */ - -#define DTRACEBUF_RING 0x0001 /* bufpolicy set to "ring" */ -#define DTRACEBUF_FILL 0x0002 /* bufpolicy set to "fill" */ -#define DTRACEBUF_NOSWITCH 0x0004 /* do not switch buffer */ -#define DTRACEBUF_WRAPPED 0x0008 /* ring buffer has wrapped */ -#define DTRACEBUF_DROPPED 0x0010 /* drops occurred */ -#define DTRACEBUF_ERROR 0x0020 /* errors occurred */ -#define DTRACEBUF_FULL 0x0040 /* "fill" buffer is full */ -#define DTRACEBUF_CONSUMED 0x0080 /* buffer has been consumed */ -#define DTRACEBUF_INACTIVE 0x0100 /* buffer is not yet active */ - -#define DTRACE_STORE(type, tomax, offset, what) \ - do { \ - *((type *)((uintptr_t)(tomax) + (uintptr_t)(offset))) = (type)(what); \ - } while (0) - -extern void dtrace_buffer_switch(dtrace_buffer_t *); -extern void dtrace_buffer_activate(dtrace_state_t *); -extern int dtrace_buffer_alloc(dtrace_buffer_t *, size_t, int, processorid_t); -extern void dtrace_buffer_drop(dtrace_buffer_t *); -extern intptr_t dtrace_buffer_reserve(dtrace_buffer_t *, size_t, size_t, - dtrace_state_t *, dtrace_mstate_t *); -extern void dtrace_buffer_polish(dtrace_buffer_t *); -extern void dtrace_buffer_free(dtrace_buffer_t *); - -/* - * DTrace Enabling Functions - */ -extern dtrace_enabling_t *dtrace_retained; -extern dtrace_genid_t dtrace_retained_gen; - -extern dtrace_enabling_t *dtrace_enabling_create(dtrace_vstate_t *); -extern void dtrace_enabling_add(dtrace_enabling_t *, dtrace_ecbdesc_t *); -extern void dtrace_enabling_dump(dtrace_enabling_t *); -extern void dtrace_enabling_destroy(dtrace_enabling_t *); -extern int dtrace_enabling_retain(dtrace_enabling_t *); -extern int dtrace_enabling_replicate(dtrace_state_t *, dtrace_probedesc_t *, - dtrace_probedesc_t *); -extern void dtrace_enabling_retract(dtrace_state_t *); -extern int dtrace_enabling_match(dtrace_enabling_t *, int *); -extern void dtrace_enabling_matchall(void); -extern void dtrace_enabling_prime(dtrace_state_t *); -extern void dtrace_enabling_provide(dtrace_provider_t *); - -/* - * DTrace DOF Functions - */ - -/* - * DTrace Object Format (DOF) - * - * DTrace programs can be persistently encoded in the DOF format so that they - * may be embedded in other programs (for example, in an ELF file) or in the - * dtrace driver configuration file for use in anonymous tracing. The DOF - * format is versioned and extensible so that it can be revised and so that - * internal data structures can be modified or extended compatibly. All DOF - * structures use fixed-size types, so the 32-bit and 64-bit representations - * are identical and consumers can use either data model transparently. - * - * The file layout is structured as follows: - * - * +---------------+-------------------+----- ... ----+---- ... ------+ - * | dof_hdr_t | dof_sec_t[ ... ] | loadable | non-loadable | - * | (file header) | (section headers) | section data | section data | - * +---------------+-------------------+----- ... ----+---- ... ------+ - * |<------------ dof_hdr.dofh_loadsz --------------->| | - * |<------------ dof_hdr.dofh_filesz ------------------------------->| - * - * The file header stores meta-data including a magic number, data model for - * the instrumentation, data encoding, and properties of the DIF code within. - * The header describes its own size and the size of the section headers. By - * convention, an array of section headers follows the file header, and then - * the data for all loadable sections and unloadable sections. This permits - * consumer code to easily download the headers and all loadable data into the - * DTrace driver in one contiguous chunk, omitting other extraneous sections. - * - * The section headers describe the size, offset, alignment, and section type - * for each section. Sections are described using a set of #defines that tell - * the consumer what kind of data is expected. Sections can contain links to - * other sections by storing a dof_secidx_t, an index into the section header - * array, inside of the section data structures. The section header includes - * an entry size so that sections with data arrays can grow their structures. - * - * The DOF data itself can contain many snippets of DIF (i.e. >1 DIFOs), which - * are represented themselves as a collection of related DOF sections. This - * permits us to change the set of sections associated with a DIFO over time, - * and also permits us to encode DIFOs that contain different sets of sections. - * When a DOF section wants to refer to a DIFO, it stores the dof_secidx_t of a - * section of type DOF_SECT_DIFOHDR. This section's data is then an array of - * dof_secidx_t's which in turn denote the sections associated with this DIFO. - * - * This loose coupling of the file structure (header and sections) to the - * structure of the DTrace program itself (ECB descriptions, action - * descriptions, and DIFOs) permits activities such as relocation processing - * to occur in a single pass without having to understand D program structure. - * - * Finally, strings are always stored in ELF-style string tables along with a - * string table section index and string table offset. Therefore strings in - * DOF are always arbitrary-length and not bound to the current implementation. - */ - -#define DOF_ID_SIZE 16 /* total size of dofh_ident[] in bytes */ - -typedef struct dof_hdr { - uint8_t dofh_ident[DOF_ID_SIZE]; - uint32_t dofh_flags; - uint32_t dofh_hdrsize; - uint32_t dofh_secsize; - uint32_t dofh_secnum; - uint64_t dofh_secoff; - uint64_t dofh_loadsz; - uint64_t dofh_filesz; - uint64_t dofh_pad; -} dof_hdr_t; - -#define DOF_ID_MAG0 0 -#define DOF_ID_MAG1 1 -#define DOF_ID_MAG2 2 -#define DOF_ID_MAG3 3 -#define DOF_ID_MODEL 4 -#define DOF_ID_ENCODING 5 -#define DOF_ID_VERSION 6 -#define DOF_ID_DIFVERS 7 -#define DOF_ID_DIFIREG 8 -#define DOF_ID_DIFTREG 9 -#define DOF_ID_PAD 10 - -#define DOF_MAG_MAG0 0x7F -#define DOF_MAG_MAG1 'D' -#define DOF_MAG_MAG2 'O' -#define DOF_MAG_MAG3 'F' - -#define DOF_MAG_STRING "\177DOF" -#define DOF_MAG_STRLEN 4 - -#define DOF_MODEL_NONE 0 -#define DOF_MODEL_ILP32 1 -#define DOF_MODEL_LP64 2 - -#ifdef CONFIG_64BIT -#define DOF_MODEL_NATIVE DOF_MODEL_LP64 -#else -#define DOF_MODEL_NATIVE DOF_MODEL_ILP32 -#endif - -#define DOF_ENCODE_NONE 0 -#define DOF_ENCODE_LSB 1 -#define DOF_ENCODE_MSB 2 - -#ifdef _BIG_ENDIAN -#define DOF_ENCODE_NATIVE DOF_ENCODE_MSB -#else -#define DOF_ENCODE_NATIVE DOF_ENCODE_LSB -#endif - -#define DOF_VERSION_1 1 -#define DOF_VERSION_2 2 -#define DOF_VERSION DOF_VERSION_2 - -#define DOF_FL_VALID 0 - -typedef uint32_t dof_secidx_t; -typedef uint32_t dof_stridx_t; - -#define DOF_SECIDX_NONE -1U -#define DOF_STRIDX_NONE -1U - -typedef struct dof_sec { - uint32_t dofs_type; - uint32_t dofs_align; - uint32_t dofs_flags; - uint32_t dofs_entsize; - uint64_t dofs_offset; - uint64_t dofs_size; -} dof_sec_t; - -#define DOF_SECT_NONE 0 -#define DOF_SECT_COMMENTS 1 -#define DOF_SECT_SOURCE 2 -#define DOF_SECT_ECBDESC 3 -#define DOF_SECT_PROBEDESC 4 -#define DOF_SECT_ACTDESC 5 -#define DOF_SECT_DIFOHDR 6 -#define DOF_SECT_DIF 7 -#define DOF_SECT_STRTAB 8 -#define DOF_SECT_VARTAB 9 -#define DOF_SECT_RELTAB 10 -#define DOF_SECT_TYPTAB 11 -#define DOF_SECT_URELHDR 12 -#define DOF_SECT_KRELHDR 13 -#define DOF_SECT_OPTDESC 14 -#define DOF_SECT_PROVIDER 15 -#define DOF_SECT_PROBES 16 -#define DOF_SECT_PRARGS 17 -#define DOF_SECT_PROFFS 18 -#define DOF_SECT_INTTAB 19 -#define DOF_SECT_UTSNAME 20 -#define DOF_SECT_XLTAB 21 -#define DOF_SECT_XLMEMBERS 22 -#define DOF_SECT_XLIMPORT 23 -#define DOF_SECT_XLEXPORT 24 -#define DOF_SECT_PREXPORT 25 -#define DOF_SECT_PRENOFFS 26 - -#define DOF_SECF_LOAD 1 - -#define DOF_SEC_ISLOADABLE(x) \ - (((x) == DOF_SECT_ECBDESC) || ((x) == DOF_SECT_PROBEDESC) || \ - ((x) == DOF_SECT_ACTDESC) || ((x) == DOF_SECT_DIFOHDR) || \ - ((x) == DOF_SECT_DIF) || ((x) == DOF_SECT_STRTAB) || \ - ((x) == DOF_SECT_VARTAB) || ((x) == DOF_SECT_RELTAB) || \ - ((x) == DOF_SECT_TYPTAB) || ((x) == DOF_SECT_URELHDR) || \ - ((x) == DOF_SECT_KRELHDR) || ((x) == DOF_SECT_OPTDESC) || \ - ((x) == DOF_SECT_PROVIDER) || ((x) == DOF_SECT_PROBES) || \ - ((x) == DOF_SECT_PRARGS) || ((x) == DOF_SECT_PROFFS) || \ - ((x) == DOF_SECT_INTTAB) || ((x) == DOF_SECT_XLTAB) || \ - ((x) == DOF_SECT_XLMEMBERS) || ((x) == DOF_SECT_XLIMPORT) || \ - ((x) == DOF_SECT_XLIMPORT) || ((x) == DOF_SECT_XLEXPORT) || \ - ((x) == DOF_SECT_PREXPORT) || ((x) == DOF_SECT_PRENOFFS)) - -typedef struct dof_ecbdesc { - dof_secidx_t dofe_probes; - dof_secidx_t dofe_pred; - dof_secidx_t dofe_actions; - uint32_t dofe_pad; - uint64_t dofe_uarg; -} dof_ecbdesc_t; - -typedef struct dof_probedesc { - dof_secidx_t dofp_strtab; - dof_stridx_t dofp_provider; - dof_stridx_t dofp_mod; - dof_stridx_t dofp_func; - dof_stridx_t dofp_name; - uint32_t dofp_id; -} dof_probedesc_t; - -typedef struct dof_actdesc { - dof_secidx_t dofa_difo; - dof_secidx_t dofa_strtab; - uint32_t dofa_kind; - uint32_t dofa_ntuple; - uint64_t dofa_arg; - uint64_t dofa_uarg; -} dof_actdesc_t; - -typedef struct dof_difohdr { - dtrace_diftype_t dofd_rtype; - dof_secidx_t dofd_links[1]; - } dof_difohdr_t; - -typedef struct dof_relohdr { - dof_secidx_t dofr_strtab; - dof_secidx_t dofr_relsec; - dof_secidx_t dofr_tgtsec; -} dof_relohdr_t; - -typedef struct dof_relodesc { - dof_stridx_t dofr_name; - uint32_t dofr_type; - uint64_t dofr_offset; - uint64_t dofr_data; -} dof_relodesc_t; - -#define DOF_RELO_NONE 0 -#define DOF_RELO_SETX 1 - -typedef struct dof_optdesc { - uint32_t dofo_option; - dof_secidx_t dofo_strtab; - uint64_t dofo_value; -} dof_optdesc_t; - -typedef uint32_t dof_attr_t; - -#define DOF_ATTR(n, d, c) (((n) << 24) | ((d) << 16) | ((c) << 8)) -#define DOF_ATTR_NAME(a) (((a) >> 24) & 0xff) -#define DOF_ATTR_DATA(a) (((a) >> 16) & 0xff) -#define DOF_ATTR_CLASS(a) (((a) >> 8) & 0xff) - -typedef struct dof_provider { - dof_secidx_t dofpv_strtab; - dof_secidx_t dofpv_probes; - dof_secidx_t dofpv_prargs; - dof_secidx_t dofpv_proffs; - dof_stridx_t dofpv_name; - dof_attr_t dofpv_provattr; - dof_attr_t dofpv_modattr; - dof_attr_t dofpv_funcattr; - dof_attr_t dofpv_nameattr; - dof_attr_t dofpv_argsattr; - dof_secidx_t dofpv_prenoffs; -} dof_provider_t; - -typedef struct dof_probe { - uint64_t dofpr_addr; - dof_stridx_t dofpr_func; - dof_stridx_t dofpr_name; - dof_stridx_t dofpr_nargv; - dof_stridx_t dofpr_xargv; - uint32_t dofpr_argidx; - uint32_t dofpr_offidx; - uint8_t dofpr_nargc; - uint8_t dofpr_xargc; - uint16_t dofpr_noffs; - uint32_t dofpr_enoffidx; - uint16_t dofpr_nenoffs; - uint16_t dofpr_pad1; - uint32_t dofpr_pad2; -} dof_probe_t; - -typedef struct dof_xlator { - dof_secidx_t dofxl_members; - dof_secidx_t dofxl_strtab; - dof_stridx_t dofxl_argv; - uint32_t dofxl_argc; - dof_stridx_t dofxl_type; - dof_attr_t dofxl_attr; -} dof_xlator_t; - -typedef struct dof_xlmember { - dof_secidx_t dofxm_difo; - dof_stridx_t dofxm_name; - dtrace_diftype_t dofxm_type; -} dof_xlmember_t; - -typedef struct dof_xlref { - dof_secidx_t dofxr_xlator; - uint32_t dofxr_member; - uint32_t dofxr_argn; -} dof_xlref_t; - -extern void dtrace_dof_error(dof_hdr_t *, const char *); -extern dof_hdr_t *dtrace_dof_create(dtrace_state_t *); -extern dof_hdr_t *dtrace_dof_copyin(void __user *, int *); -extern dof_hdr_t *dtrace_dof_property(const char *); -extern void dtrace_dof_destroy(dof_hdr_t *); -extern int dtrace_dof_slurp(dof_hdr_t *, dtrace_vstate_t *, const cred_t *, - dtrace_enabling_t **, uint64_t, int); -extern int dtrace_dof_options(dof_hdr_t *, dtrace_state_t *); -extern void dtrace_helper_provide(dof_helper_t *dhp, pid_t pid); -extern int dtrace_helper_slurp(dof_hdr_t *, dof_helper_t *); -extern int dtrace_helper_destroygen(int); - -/* - * DTrace Anonymous Enabling Functions - */ -typedef struct dtrace_anon { - dtrace_state_t *dta_state; - dtrace_enabling_t *dta_enabling; - processorid_t dta_beganon; -} dtrace_anon_t; - -extern dtrace_anon_t dtrace_anon; - -extern dtrace_state_t *dtrace_anon_grab(void); -extern void dtrace_anon_property(void); - -/* - * DTrace Consumer State Functions - */ -extern struct kmem_cache *dtrace_state_cache; -extern size_t dtrace_strsize_default; - -extern ktime_t dtrace_deadman_timeout; -extern int dtrace_destructive_disallow; - -extern dtrace_id_t dtrace_probeid_begin; -extern dtrace_id_t dtrace_probeid_end; -extern dtrace_id_t dtrace_probeid_error; - -extern dtrace_dynvar_t dtrace_dynhash_sink; - -extern int dtrace_dstate_init(dtrace_dstate_t *, size_t); -extern void dtrace_dstate_fini(dtrace_dstate_t *); -extern void dtrace_vstate_fini(dtrace_vstate_t *); -extern dtrace_state_t *dtrace_state_create(struct file *); -extern int dtrace_state_go(dtrace_state_t *, processorid_t *); -extern int dtrace_state_stop(dtrace_state_t *, processorid_t *); -extern int dtrace_state_option(dtrace_state_t *, dtrace_optid_t, - dtrace_optval_t); -extern void dtrace_state_destroy(dtrace_state_t *); - -/* - * DTrace Utility Functions - */ -extern void *dtrace_vzalloc(unsigned long); -extern void *dtrace_vzalloc_try(unsigned long); -extern char *dtrace_strdup(const char *); -extern int dtrace_strncmp(char *, char *, size_t); -extern size_t dtrace_strlen(const char *, size_t); -extern int dtrace_badattr(const dtrace_attribute_t *); -extern int dtrace_badname(const char *); -extern void dtrace_cred2priv(const cred_t *, uint32_t *, uid_t *); - -extern void ctf_forceload(void); - -#define DT_PROVIDER_POPS(name) \ - static unsigned int name##_refc = 0; \ - \ - static int name##_enable(void *arg, dtrace_id_t id, void *parg) \ - { \ - int rc = 0; \ - \ - if (name##_refc++ == 0) { \ - if ((rc = try_module_get(THIS_MODULE)) == 0) \ - return 0; \ - } \ - \ - if ((rc = _##name##_enable(arg, id, parg)) != 0) { \ - if (--name##_refc == 0) \ - module_put(THIS_MODULE); \ - } \ - \ - return rc; \ - } \ - \ - static void name##_disable(void *arg, dtrace_id_t id, void *parg) \ - { \ - _##name##_disable(arg, id, parg); \ - \ - if (--name##_refc == 0) \ - module_put(THIS_MODULE); \ - } - -#define DT_PROVIDER_MODULE(name, priv) \ - dtrace_provider_id_t name##_id; \ - \ - static int __init name##_init(void) \ - { \ - int ret = 0; \ - \ - ret = name##_dev_init(); \ - if (ret) \ - goto failed; \ - \ - ret = dtrace_register(__stringify(name), &name##_attr, priv, \ - NULL, &name##_pops, NULL, &name##_id); \ - if (ret) \ - goto failed; \ - \ - return 0; \ - \ - failed: \ - return ret; \ - } \ - \ - static void __exit name##_exit(void) \ - { \ - dtrace_unregister(name##_id); \ - name##_dev_exit(); \ - } \ - \ - module_init(name##_init); \ - module_exit(name##_exit); - -#define DT_META_PROVIDER_MODULE(name) \ - dtrace_meta_provider_id_t name##_id; \ - \ - static int __init name##_init(void) \ - { \ - int ret = 0; \ - \ - ret = name##_dev_init(); \ - if (ret) \ - goto failed; \ - \ - ret = dtrace_meta_register(__stringify(name), &name##_mops, \ - NULL, &name##_id); \ - if (ret) \ - goto failed; \ - \ - return 0; \ - \ - failed: \ - return ret; \ - } \ - \ - static void __exit name##_exit(void) \ - { \ - dtrace_meta_unregister(name##_id); \ - name##_dev_exit(); \ - } \ - \ - module_init(name##_init); \ - module_exit(name##_exit); - -typedef struct dtrace_mprovider { - char *dtmp_name; - char *dtmp_pref; - dtrace_pattr_t *dtmp_attr; - uint32_t dtmp_priv; - dtrace_pops_t *dtmp_pops; - dtrace_provider_id_t dtmp_id; -} dtrace_mprovider_t; - -#define DT_MULTI_PROVIDER_MODULE(name, plist) \ - static int __init name##_init(void) \ - { \ - int ret = 0; \ - dtrace_mprovider_t *prov; \ - \ - ret = name##_dev_init(); \ - if (ret) \ - goto failed; \ - \ - for (prov = plist; prov->dtmp_name != NULL; prov++) { \ - if (dtrace_register(prov->dtmp_name, prov->dtmp_attr, \ - prov->dtmp_priv, NULL, \ - prov->dtmp_pops, prov, \ - &prov->dtmp_id) != 0) \ - pr_warning("Failed to register sdt provider %s",\ - prov->dtmp_name); \ - } \ - \ - return 0; \ - \ - failed: \ - return ret; \ - } \ - \ - static void __exit name##_exit(void) \ - { \ - int ret = 0; \ - dtrace_mprovider_t *prov; \ - \ - for (prov = plist; prov->dtmp_name != NULL; prov++) { \ - if (prov->dtmp_id != DTRACE_PROVNONE) { \ - ret = dtrace_unregister(prov->dtmp_id); \ - if (ret != 0) \ - return; \ - \ - prov->dtmp_id = DTRACE_PROVNONE; \ - } \ - } \ - \ - name##_dev_exit(); \ - } \ - \ - module_init(name##_init); \ - module_exit(name##_exit); - -#define dtrace_membar_producer() mb() -#define dtrace_membar_consumer() mb() - -typedef unsigned long dtrace_icookie_t; - -extern struct mutex cpu_lock; - -extern void dtrace_sync(void); -extern void dtrace_toxic_ranges(void (*)(uintptr_t, uintptr_t)); -extern void dtrace_vpanic(const char *, va_list); -extern int dtrace_getipl(void); - -extern ktime_t dtrace_gethrestime(void); - -typedef enum dtrace_vtime_state { - DTRACE_VTIME_INACTIVE = 0, /* No DTrace, no TNF */ - DTRACE_VTIME_ACTIVE, /* DTrace virtual time, no TNF */ - DTRACE_VTIME_INACTIVE_TNF, /* No DTrace, TNF active */ - DTRACE_VTIME_ACTIVE_TNF /* DTrace virtual time _and_ TNF */ -} dtrace_vtime_state_t; - -extern dtrace_vtime_state_t dtrace_vtime_active; - -extern void dtrace_vtime_enable(void); -extern void dtrace_vtime_disable(void); - -extern ktime_t dtrace_gethrtime(void); -extern ktime_t dtrace_getwalltime(void); - -extern dtrace_icookie_t dtrace_interrupt_disable(void); -extern void dtrace_interrupt_enable(dtrace_icookie_t); - -typedef void (*dtrace_xcall_t)(void *); - -extern void dtrace_xcall(processorid_t, dtrace_xcall_t, void *); - -extern uint8_t dtrace_fuword8(void *); -extern uint16_t dtrace_fuword16(void *); -extern uint32_t dtrace_fuword32(void *); -extern uint64_t dtrace_fuword64(void *); - -extern void dtrace_probe_error(dtrace_state_t *, dtrace_epid_t, int, int, int, - uintptr_t); - -extern void dtrace_getpcstack(uint64_t *, int, int, uint32_t *); -extern void dtrace_getupcstack(uint64_t *, int); -extern void dtrace_getufpstack(uint64_t *, uint64_t *, int); -extern uintptr_t dtrace_getfp(void); -extern uint64_t dtrace_getarg(int, int); -extern int dtrace_getstackdepth(int); -extern int dtrace_getustackdepth(void); -extern ulong_t dtrace_getreg(struct task_struct *, uint_t); -extern void dtrace_copyin(uintptr_t, uintptr_t, size_t, volatile uint16_t *); -extern void dtrace_copyout(uintptr_t, uintptr_t, size_t, volatile uint16_t *); -extern void dtrace_copyinstr(uintptr_t, uintptr_t, size_t, - volatile uint16_t *); -extern void dtrace_copyoutstr(uintptr_t, uintptr_t, size_t, - volatile uint16_t *); -extern uintptr_t dtrace_caller(int); - -extern void debug_enter(char *); - -#define KERNELBASE (uintptr_t)_text - -/* - * regset.h information - */ -#ifdef __i386__ -# define REG_SS 18 /* only stored on a privilege transition */ -# define REG_UESP 17 /* only stored on a privilege transition */ -# define REG_EFL 16 -# define REG_CS 15 -# define REG_EIP 14 -# define REG_ERR 13 -# define REG_TRAPNO 12 -# define REG_EAX 11 -# define REG_ECX 10 -# define REG_EDX 9 -# define REG_EBX 8 -# define REG_ESP 7 -# define REG_EBP 6 -# define REG_ESI 5 -# define REG_EDI 4 -# define REG_DS 3 -# define REG_ES 2 -# define REG_FS 1 -# define REG_GS 0 -#else -# define REG_GS 24 -# define REG_FS 23 -# define REG_ES 22 -# define REG_DS 21 -# define REG_SS 20 -# define REG_RSP 19 -# define REG_RFL 18 -# define REG_CS 17 -# define REG_RIP 16 -# define REG_ERR 15 -# define REG_TRAPNO 15 -# define REG_RDI 14 -# define REG_RSI 13 -# define REG_RDX 12 -# define REG_RCX 11 -# define REG_RAX 10 -# define REG_R8 9 -# define REG_R9 8 -# define REG_R10 7 -# define REG_R11 6 -# define REG_RBX 5 -# define REG_RBP 4 -# define REG_R12 3 -# define REG_R13 2 -# define REG_R14 1 -# define REG_R15 0 -#endif - -#if defined(__i386__) || defined(__x86_64__) -# define DTRACE_INVOP_PUSHL_EBP 1 -# define DTRACE_INVOP_POPL_EBP 2 -# define DTRACE_INVOP_LEAVE 3 -# define DTRACE_INVOP_NOP 4 -# define DTRACE_INVOP_RET 5 -#endif - -#ifdef CONFIG_DT_DEBUG_MUTEX -# define _mutex_lock(x) mutex_lock(x) -# define _mutex_unlock(x) mutex_unlock(x) - -# define mutex_lock(x) do { \ - printk(KERN_DEBUG \ - "mutex_lock(%s) at %s::%d\n", \ - __stringify(x), \ - __FILE__, __LINE__); \ - _mutex_lock(x); \ - } while (0) -# define mutex_unlock(x) do { \ - printk(KERN_DEBUG \ - "mutex_unlock(%s) at %s::%d\n", \ - __stringify(x), \ - __FILE__, __LINE__); \ - _mutex_unlock(x); \ - } while (0) -#endif - -#define MUTEX_HELD(lock) mutex_owned(lock) +#include +#include #endif /* _DTRACE_H_ */ diff --git a/dtrace/dtrace_dev.c b/dtrace/dtrace_dev.c index cb9686c11900..f78ed2da2bc2 100644 --- a/dtrace/dtrace_dev.c +++ b/dtrace/dtrace_dev.c @@ -26,8 +26,8 @@ */ #include -#include -#include +#include +#include #include #include #include @@ -912,6 +912,15 @@ static long dtrace_ioctl(struct file *file, return -ENOTTY; } +#ifdef CONFIG_DT_DEBUG + +void dtrace_size_dbg_print(const char *type, size_t size) +{ + dt_dbg_ioctl("Size of %s: %lx\n", type, size); +} + +#endif + static int dtrace_close(struct inode *inode, struct file *file) { dtrace_state_t *state = file->private_data; @@ -1288,6 +1297,10 @@ int dtrace_dev_init(void) mutex_lock(&dtrace_provider_lock); mutex_lock(&dtrace_lock); +#ifdef CONFIG_DT_DEBUG + dtrace_ioctl_sizes(); +#endif + /* * Register the device for the DTrace core. */ diff --git a/dtrace/dtrace_dif.c b/dtrace/dtrace_dif.c index c23b5f7c3f63..dc6c970c7820 100644 --- a/dtrace/dtrace_dif.c +++ b/dtrace/dtrace_dif.c @@ -3281,7 +3281,7 @@ static void dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs, case DIF_SUBR_HTONS: case DIF_SUBR_NTOHS: -#ifdef _BIG_ENDIAN +#ifndef __LITTLE_ENDIAN regs[rd] = (uint16_t)tupregs[0].dttk_value; #else regs[rd] = DT_BSWAP_16((uint16_t)tupregs[0].dttk_value); @@ -3291,7 +3291,7 @@ static void dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs, case DIF_SUBR_HTONL: case DIF_SUBR_NTOHL: -#ifdef _BIG_ENDIAN +#ifndef __LITTLE_ENDIAN regs[rd] = (uint32_t)tupregs[0].dttk_value; #else regs[rd] = DT_BSWAP_32((uint32_t)tupregs[0].dttk_value); @@ -3301,7 +3301,7 @@ static void dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs, case DIF_SUBR_HTONLL: case DIF_SUBR_NTOHLL: -#ifdef _BIG_ENDIAN +#ifndef __LITTLE_ENDIAN regs[rd] = (uint64_t)tupregs[0].dttk_value; #else regs[rd] = DT_BSWAP_64((uint64_t)tupregs[0].dttk_value); diff --git a/dtrace/include/dtrace/dtrace_impl.h b/dtrace/include/dtrace/dtrace_impl.h new file mode 100644 index 000000000000..8aa1c6fb6c71 --- /dev/null +++ b/dtrace/include/dtrace/dtrace_impl.h @@ -0,0 +1,904 @@ +#ifndef _LINUX_DTRACE_IMPL_H +#define _LINUX_DTRACE_IMPL_H + +/* + * DTrace Dynamic Tracing Software: DTrace Implementation + * + * Note: The contents of this file are private to the implementation of the + * DTrace subsystem and are subject to change at any time without notice. + */ + +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + * + * Copyright 2009 -- 2013 Oracle, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef struct dtrace_provider { + dtrace_pattr_t dtpv_attr; + dtrace_ppriv_t dtpv_priv; + dtrace_pops_t dtpv_pops; + char *dtpv_name; + void *dtpv_arg; + uint_t dtpv_defunct; + struct dtrace_provider *dtpv_next; +} dtrace_provider_t; + +typedef struct dtrace_predicate { + struct dtrace_difo *dtp_difo; + dtrace_cacheid_t dtp_cacheid; + int dtp_refcnt; +} dtrace_predicate_t; + +typedef struct dtrace_statvar { + uint64_t dtsv_data; + size_t dtsv_size; + int dtsv_refcnt; + dtrace_difv_t dtsv_var; +} dtrace_statvar_t; + +typedef struct dtrace_action { + dtrace_actkind_t dta_kind; + uint16_t dta_intuple; + uint32_t dta_refcnt; + dtrace_difo_t *dta_difo; + dtrace_recdesc_t dta_rec; + struct dtrace_action *dta_prev; + struct dtrace_action *dta_next; +} dtrace_action_t; + +struct dtrace_ecb; +typedef struct dtrace_ecb dtrace_ecb_t; + +typedef struct dtrace_probe { + dtrace_id_t dtpr_id; + dtrace_ecb_t *dtpr_ecb; + dtrace_ecb_t *dtpr_ecb_last; + void *dtpr_arg; + dtrace_cacheid_t dtpr_predcache; + int dtpr_aframes; + dtrace_provider_t *dtpr_provider; + char *dtpr_mod; + char *dtpr_func; + char *dtpr_name; + struct dtrace_probe *dtpr_nextmod; + struct dtrace_probe *dtpr_prevmod; + struct dtrace_probe *dtpr_nextfunc; + struct dtrace_probe *dtpr_prevfunc; + struct dtrace_probe *dtpr_nextname; + struct dtrace_probe *dtpr_prevname; + dtrace_genid_t dtpr_gen; +} dtrace_probe_t; + +struct dtrace_state; +typedef struct dtrace_state dtrace_state_t; + +struct dtrace_ecb { + dtrace_epid_t dte_epid; + uint32_t dte_alignment; + size_t dte_needed; + size_t dte_size; + dtrace_predicate_t *dte_predicate; + dtrace_action_t *dte_action; + struct dtrace_ecb *dte_next; + dtrace_state_t *dte_state; + uint32_t dte_cond; + dtrace_probe_t *dte_probe; + dtrace_action_t *dte_action_last; + uint64_t dte_uarg; +}; + +typedef struct dtrace_key { + uint64_t dttk_value; + uint64_t dttk_size; +} dtrace_key_t; + +typedef struct dtrace_tuple { + uint32_t dtt_nkeys; + uint32_t dtt_pad; + dtrace_key_t dtt_key[1]; +} dtrace_tuple_t; + +typedef struct dtrace_dynvar { + uint64_t dtdv_hashval; + struct dtrace_dynvar *dtdv_next; + void *dtdv_data; + dtrace_tuple_t dtdv_tuple; +} dtrace_dynvar_t; + +typedef struct dtrace_dstate_percpu { + dtrace_dynvar_t *dtdsc_free; + dtrace_dynvar_t *dtdsc_dirty; + dtrace_dynvar_t *dtdsc_rinsing; + dtrace_dynvar_t *dtdsc_clean; + uint64_t dtdsc_drops; + uint64_t dtdsc_dirty_drops; + uint64_t dtdsc_rinsing_drops; +#ifdef CONFIG_64BIT + uint64_t dtdsc_pad; +#else + uint64_t dtdsc_pad[2]; +#endif +} dtrace_dstate_percpu_t; + +typedef struct dtrace_dynhash { + dtrace_dynvar_t *dtdh_chain; + uintptr_t dtdh_lock; +#ifdef CONFIG_64BIT + uintptr_t dtdh_pad[6]; +#else + uintptr_t dtdh_pad[14]; +#endif +} dtrace_dynhash_t; + +typedef struct dtrace_dstate { + void *dtds_base; + size_t dtds_size; + size_t dtds_hashsize; + size_t dtds_chunksize; + dtrace_dynhash_t *dtds_hash; + dtrace_dstate_state_t dtds_state; + dtrace_dstate_percpu_t *dtds_percpu; +} dtrace_dstate_t; + +typedef struct dtrace_vstate { + dtrace_state_t *dtvs_state; + dtrace_statvar_t **dtvs_globals; + int dtvs_nglobals; + dtrace_difv_t *dtvs_tlocals; + int dtvs_ntlocals; + dtrace_statvar_t **dtvs_locals; + int dtvs_nlocals; + dtrace_dstate_t dtvs_dynvars; +} dtrace_vstate_t; + +/* + * DTrace Machine State + * + * In the process of processing a fired probe, DTrace needs to track and/or + * cache some per-CPU state associated with that particular firing. This is + * state that is always discarded after the probe firing has completed, and + * much of it is not specific to any DTrace consumer, remaining valid across + * all ECBs. This state is tracked in the dtrace_mstate structure. + */ + +typedef struct dtrace_mstate { + uintptr_t dtms_scratch_base; + uintptr_t dtms_scratch_ptr; + size_t dtms_scratch_size; + uint32_t dtms_present; + uint64_t dtms_arg[5]; + dtrace_epid_t dtms_epid; + ktime_t dtms_timestamp; + int dtms_stackdepth; + int dtms_ustackdepth; + struct dtrace_probe *dtms_probe; + uintptr_t dtms_caller; + uint64_t dtms_ucaller; + int dtms_ipl; + int dtms_fltoffs; + uintptr_t dtms_strtok; + uint32_t dtms_access; + dtrace_difo_t *dtms_difo; +} dtrace_mstate_t; + +typedef struct dtrace_buffer { + uint64_t dtb_offset; + uint64_t dtb_size; + uint32_t dtb_flags; + uint32_t dtb_drops; + caddr_t dtb_tomax; + caddr_t dtb_xamot; + uint32_t dtb_xamot_flags; + uint32_t dtb_xamot_drops; + uint64_t dtb_xamot_offset; + uint32_t dtb_errors; + uint32_t dtb_xamot_errors; +#ifndef CONFIG_64BIT + uint64_t dtb_pad1; +#endif +} dtrace_buffer_t; + +typedef struct dtrace_speculation { + dtrace_speculation_state_t dtsp_state; + int dtsp_cleaning; + dtrace_buffer_t *dtsp_buffer; +} dtrace_speculation_t; + +typedef struct dtrace_aggregation { + dtrace_action_t dtag_action; + dtrace_aggid_t dtag_id; + dtrace_ecb_t *dtag_ecb; + dtrace_action_t *dtag_first; + uint32_t dtag_base; + uint8_t dtag_hasarg; + uint64_t dtag_initial; + void (*dtag_aggregate)(uint64_t *, uint64_t, uint64_t); +} dtrace_aggregation_t; + +typedef struct dtrace_cred { + const cred_t *dcr_cred; + uint8_t dcr_destructive; + uint8_t dcr_visible; + uint16_t dcr_action; +} dtrace_cred_t; + +struct dtrace_state { + dev_t dts_dev; + int dts_necbs; + dtrace_ecb_t **dts_ecbs; + dtrace_epid_t dts_epid; + size_t dts_needed; + struct dtrace_state *dts_anon; + dtrace_activity_t dts_activity; + dtrace_vstate_t dts_vstate; + dtrace_buffer_t *dts_buffer; + dtrace_buffer_t *dts_aggbuffer; + dtrace_speculation_t *dts_speculations; + int dts_nspeculations; + struct idr dts_agg_idr; + int dts_naggs; + uint64_t dts_errors; + uint32_t dts_speculations_busy; + uint32_t dts_speculations_unavail; + uint32_t dts_stkstroverflows; + uint32_t dts_dblerrors; + uint32_t dts_reserve; + ktime_t dts_laststatus; + cyclic_id_t dts_cleaner; + cyclic_id_t dts_deadman; + ktime_t dts_alive; + char dts_speculates; + char dts_destructive; + int dts_nformats; + char **dts_formats; + dtrace_optval_t dts_options[DTRACEOPT_MAX]; + dtrace_cred_t dts_cred; + size_t dts_nretained; +}; + +typedef struct dtrace_enabling { + dtrace_ecbdesc_t **dten_desc; + int dten_ndesc; + int dten_maxdesc; + dtrace_vstate_t *dten_vstate; + dtrace_genid_t dten_probegen; + dtrace_ecbdesc_t *dten_current; + int dten_error; + int dten_primed; + struct dtrace_enabling *dten_prev; + struct dtrace_enabling *dten_next; +} dtrace_enabling_t; + +typedef int dtrace_probekey_f(const char *, const char *, int); + +typedef struct dtrace_probekey { + const char *dtpk_prov; + dtrace_probekey_f *dtpk_pmatch; + const char *dtpk_mod; + dtrace_probekey_f *dtpk_mmatch; + const char *dtpk_func; + dtrace_probekey_f *dtpk_fmatch; + const char *dtpk_name; + dtrace_probekey_f *dtpk_nmatch; + dtrace_id_t dtpk_id; +} dtrace_probekey_t; + +typedef struct dtrace_hashbucket { + struct dtrace_hashbucket *dthb_next; + dtrace_probe_t *dthb_chain; + int dthb_len; +} dtrace_hashbucket_t; + +typedef struct dtrace_hash { + dtrace_hashbucket_t **dth_tab; + int dth_size; + int dth_mask; + int dth_nbuckets; + uintptr_t dth_nextoffs; + uintptr_t dth_prevoffs; + uintptr_t dth_stroffs; +} dtrace_hash_t; + +/* + * DTrace supports safe loads from probe context; if the address turns out to + * be invalid, a bit will be set by the kernel indicating that DTrace + * encountered a memory error, and DTrace will propagate the error to the user + * accordingly. However, there may exist some regions of memory in which an + * arbitrary load can change system state, and from which it is impossible to + * recover from such a load after it has been attempted. Examples of this may + * include memory in which programmable I/O registers are mapped (for which a + * read may have some implications for the device) or (in the specific case of + * UltraSPARC-I and -II) the virtual address hole. The platform is required + * to make DTrace aware of these toxic ranges; DTrace will then check that + * target addresses are not in a toxic range before attempting to issue a + * safe load. + */ +typedef struct dtrace_toxrange { + uintptr_t dtt_base; + uintptr_t dtt_limit; +} dtrace_toxrange_t; + +/* + * DTrace Helper Implementation + * + * A description of the helper architecture may be found in . + * Each process contains a pointer to its helpers in its dtrace_helpers + * member. This is a pointer to a dtrace_helpers structure, which contains an + * array of pointers to dtrace_helper structures, helper variable state (shared + * among a process's helpers) and a generation count. (The generation count is + * used to provide an identifier when a helper is added so that it may be + * subsequently removed.) The dtrace_helper structure is self-explanatory, + * containing pointers to the objects needed to execute the helper. Note that + * helpers are _duplicated_ across fork(2), and destroyed on exec(2). No more + * than dtrace_helpers_max are allowed per-process. + */ +typedef struct dtrace_helper_action { + int dtha_generation; /* helper action generation */ + int dtha_nactions; /* number of actions */ + dtrace_difo_t *dtha_predicate; /* helper action predicate */ + dtrace_difo_t **dtha_actions; /* array of actions */ + struct dtrace_helper_action *dtha_next; /* next helper action */ +} dtrace_helper_action_t; + +typedef struct dtrace_helper_provider { + int dthp_generation; /* helper provider generation */ + uint32_t dthp_ref; /* reference count */ + dof_helper_t dthp_prov; /* DOF w/ provider and probes */ +} dtrace_helper_provider_t; + +typedef struct dtrace_helpers { + dtrace_helper_action_t **dthps_actions; /* array of helper actions */ + dtrace_vstate_t dthps_vstate; /* helper action var. state */ + dtrace_helper_provider_t **dthps_provs; /* array of providers */ + uint_t dthps_nprovs; /* count of providers */ + uint_t dthps_maxprovs; /* provider array size */ + int dthps_generation; /* current generation */ + pid_t dthps_pid; /* pid of associated proc */ + int dthps_deferred; /* helper in deferred list */ + struct dtrace_helpers *dthps_next; /* next pointer */ + struct dtrace_helpers *dthps_prev; /* prev pointer */ +} dtrace_helpers_t; + +/* + * DTrace Helper Action Tracing + * + * Debugging helper actions can be arduous. To ease the development and + * debugging of helpers, DTrace contains a tracing-framework-within-a-tracing- + * framework: helper tracing. If dtrace_helptrace_enabled is non-zero (which + * it is by default on DEBUG kernels), all helper activity will be traced to a + * global, in-kernel ring buffer. Each entry includes a pointer to the specific + * helper, the location within the helper, and a trace of all local variables. + * The ring buffer may be displayed in a human-readable format with the + * ::dtrace_helptrace mdb(1) dcmd. + */ +typedef struct dtrace_helptrace { + dtrace_helper_action_t *dtht_helper; /* helper action */ + int dtht_where; /* where in helper action */ + int dtht_nlocals; /* number of locals */ + int dtht_fault; /* type of fault (if any) */ + int dtht_fltoffs; /* DIF offset */ + uint64_t dtht_illval; /* faulting value */ + uint64_t dtht_locals[1]; /* local variables */ +} dtrace_helptrace_t; + +extern struct mutex dtrace_lock; +extern struct mutex dtrace_provider_lock; +extern struct mutex dtrace_meta_lock; + +extern dtrace_genid_t dtrace_probegen; + +extern dtrace_pops_t dtrace_provider_ops; + +extern int dtrace_opens; +extern int dtrace_err_verbose; + +extern dtrace_toxrange_t *dtrace_toxrange; +extern int dtrace_toxranges; + +extern void dtrace_nullop(void); +extern int dtrace_enable_nullop(void); +extern int dtrace_istoxic(uintptr_t, size_t); + +/* + * DTrace Probe Context Functions + */ + +extern void dtrace_panic(const char *, ...); +extern int dtrace_assfail(const char *, const char *, int); +extern void dtrace_aggregate_min(uint64_t *, uint64_t, uint64_t); +extern void dtrace_aggregate_max(uint64_t *, uint64_t, uint64_t); +extern void dtrace_aggregate_quantize(uint64_t *, uint64_t, uint64_t); +extern void dtrace_aggregate_lquantize(uint64_t *, uint64_t, uint64_t); +extern void dtrace_aggregate_avg(uint64_t *, uint64_t, uint64_t); +extern void dtrace_aggregate_stddev(uint64_t *, uint64_t, uint64_t); +extern void dtrace_aggregate_count(uint64_t *, uint64_t, uint64_t); +extern void dtrace_aggregate_sum(uint64_t *, uint64_t, uint64_t); +extern void dtrace_aggregate(dtrace_aggregation_t *, dtrace_buffer_t *, + intptr_t, dtrace_buffer_t *, uint64_t, uint64_t); + +/* + * DTrace Probe Hashing Functions + */ + +extern dtrace_hash_t *dtrace_hash_create(uintptr_t, uintptr_t, uintptr_t); +extern void dtrace_hash_add(dtrace_hash_t *, dtrace_probe_t *); +extern dtrace_probe_t *dtrace_hash_lookup(dtrace_hash_t *, dtrace_probe_t *); +extern int dtrace_hash_collisions(dtrace_hash_t *, dtrace_probe_t *); +extern void dtrace_hash_remove(dtrace_hash_t *, dtrace_probe_t *); + +/* + * DTrace Speculation Functions + */ +extern int dtrace_speculation(dtrace_state_t *); +extern void dtrace_speculation_commit(dtrace_state_t *, processorid_t, + dtrace_specid_t); +extern void dtrace_speculation_discard(dtrace_state_t *, processorid_t, + dtrace_specid_t); +extern void dtrace_speculation_clean(dtrace_state_t *); +extern dtrace_buffer_t *dtrace_speculation_buffer(dtrace_state_t *, + processorid_t, dtrace_specid_t); + +/* + * DTrace Non-Probe Context Utility Functions + */ + +/* + * DTrace Matching Functions + */ +extern dtrace_hash_t *dtrace_bymod; +extern dtrace_hash_t *dtrace_byfunc; +extern dtrace_hash_t *dtrace_byname; + +extern int dtrace_match_priv(const dtrace_probe_t *, uint32_t, uid_t); +extern int dtrace_match_probe(const dtrace_probe_t *, + const dtrace_probekey_t *, uint32_t, uid_t); +extern int dtrace_match_glob(const char *, const char *, int); +extern int dtrace_match_string(const char *, const char *, int); +extern int dtrace_match_nul(const char *, const char *, int); +extern int dtrace_match_nonzero(const char *, const char *, int); +extern int dtrace_match(const dtrace_probekey_t *, uint32_t, uid_t, + int (*matched)(dtrace_probe_t *, void *), void *); +extern void dtrace_probekey(const dtrace_probedesc_t *, dtrace_probekey_t *); + +/* + * DTrace Provider-to-Framework API Functions + */ + +extern dtrace_provider_t *dtrace_provider; +extern dtrace_meta_t *dtrace_meta_pid; +extern dtrace_helpers_t *dtrace_deferred_pid; + +/* + * DTrace Privilege Check Functions + */ +extern int dtrace_priv_proc_destructive(dtrace_state_t *); +extern int dtrace_priv_proc_control(dtrace_state_t *); +extern int dtrace_priv_proc(dtrace_state_t *); +extern int dtrace_priv_kernel(dtrace_state_t *); + +/* + * DTrace Probe Management Functions + */ + +extern int dtrace_probe_enable(const dtrace_probedesc_t *, + dtrace_enabling_t *); +extern void dtrace_probe_description(const dtrace_probe_t *, + dtrace_probedesc_t *); +extern void dtrace_probe_provide(dtrace_probedesc_t *, dtrace_provider_t *); +extern void dtrace_probe_init(void); +extern void dtrace_probe_exit(void); +extern void dtrace_probe_remove_id(dtrace_id_t); +extern dtrace_probe_t *dtrace_probe_lookup_id(dtrace_id_t); +extern dtrace_probe_t *dtrace_probe_get_next(dtrace_id_t); +extern int dtrace_probe_for_each(int (*)(int, void *, void *), void *); + +/* + * DTrace Kernel Hooks + */ +extern void (*dtrace_modload)(struct module *); +extern void (*dtrace_modunload)(struct module *); + +extern uint8_t dtrace_load8(uintptr_t); +extern uint16_t dtrace_load16(uintptr_t); +extern uint32_t dtrace_load32(uintptr_t); +extern uint64_t dtrace_load64(uintptr_t); + +extern void dtrace_bzero(void *, size_t); + +extern int dtrace_vcanload(void *, dtrace_diftype_t *, dtrace_mstate_t *, + dtrace_vstate_t *); + +extern int dtrace_difo_validate(dtrace_difo_t *, dtrace_vstate_t *, uint_t, + const cred_t *); +extern int dtrace_difo_validate_helper(dtrace_difo_t *); +extern int dtrace_difo_cacheable(dtrace_difo_t *); +extern void dtrace_difo_hold(dtrace_difo_t *); +extern void dtrace_difo_init(dtrace_difo_t *, dtrace_vstate_t *); +extern void dtrace_difo_release(dtrace_difo_t *, dtrace_vstate_t *); + +extern uint64_t dtrace_dif_emulate(dtrace_difo_t *, dtrace_mstate_t *, + dtrace_vstate_t *, dtrace_state_t *); + +/* + * DTrace Format Functions + */ +extern uint16_t dtrace_format_add(dtrace_state_t *, char *); +extern void dtrace_format_remove(dtrace_state_t *, uint16_t); +extern void dtrace_format_destroy(dtrace_state_t *); + +/* + * DTrace Predicate Functions + */ +extern dtrace_predicate_t *dtrace_predicate_create(dtrace_difo_t *); +extern void dtrace_predicate_hold(dtrace_predicate_t *); +extern void dtrace_predicate_release(dtrace_predicate_t *, dtrace_vstate_t *); + +/* + * DTrace Action Description Functions + */ +extern dtrace_actdesc_t *dtrace_actdesc_create(dtrace_actkind_t, uint32_t, + uint64_t, uint64_t); +extern void dtrace_actdesc_hold(dtrace_actdesc_t *); +extern void dtrace_actdesc_release(dtrace_actdesc_t *, dtrace_vstate_t *); + +/* + * DTrace Helper Functions + */ +extern void dtrace_helpers_destroy(struct task_struct *); +extern uint64_t dtrace_helper(int, dtrace_mstate_t *, dtrace_state_t *, + uint64_t, uint64_t); + +/* + * DTrace ECB Functions + */ +extern dtrace_ecb_t *dtrace_ecb_create_cache; + +extern int dtrace_ecb_create_enable(dtrace_probe_t *, void *); +extern void dtrace_ecb_disable(dtrace_ecb_t *); +extern void dtrace_ecb_destroy(dtrace_ecb_t *); +extern void dtrace_ecb_resize(dtrace_ecb_t *); +extern int dtrace_ecb_enable(dtrace_ecb_t *); +extern dtrace_ecb_t *dtrace_epid2ecb(dtrace_state_t *, dtrace_epid_t); +extern dtrace_aggregation_t *dtrace_aggid2agg(dtrace_state_t *, + dtrace_aggid_t); + +/* + * DTrace Buffer Functions + * + * DTrace Buffers + * + * Principal buffers, aggregation buffers, and speculative buffers are all + * managed with the dtrace_buffer structure. By default, this structure + * includes twin data buffers -- dtb_tomax and dtb_xamot -- that serve as the + * active and passive buffers, respectively. For speculative buffers, + * dtb_xamot will be NULL; for "ring" and "fill" buffers, dtb_xamot will point + * to a scratch buffer. For all buffer types, the dtrace_buffer structure is + * always allocated on a per-CPU basis; a single dtrace_buffer structure is + * never shared among CPUs. (That is, there is never true sharing of the + * dtrace_buffer structure; to prevent false sharing of the structure, it must + * always be aligned to the coherence granularity -- generally 64 bytes.) + * + * One of the critical design decisions of DTrace is that a given ECB always + * stores the same quantity and type of data. This is done to assure that the + * only metadata required for an ECB's traced data is the EPID. That is, from + * the EPID, the consumer can determine the data layout. (The data buffer + * layout is shown schematically below.) By assuring that one can determine + * data layout from the EPID, the metadata stream can be separated from the + * data stream -- simplifying the data stream enormously. + * + * base of data buffer ---> +------+--------------------+------+ + * | EPID | data | EPID | + * +------+--------+------+----+------+ + * | data | EPID | data | + * +---------------+------+-----------+ + * | data, cont. | + * +------+--------------------+------+ + * | EPID | data | | + * +------+--------------------+ | + * | || | + * | || | + * | \/ | + * : : + * . . + * . . + * . . + * : : + * | | + * limit of data buffer ---> +----------------------------------+ + * + * When evaluating an ECB, dtrace_probe() determines if the ECB's needs of the + * principal buffer (both scratch and payload) exceed the available space. If + * the ECB's needs exceed available space (and if the principal buffer policy + * is the default "switch" policy), the ECB is dropped, the buffer's drop count + * is incremented, and processing advances to the next ECB. If the ECB's needs + * can be met with the available space, the ECB is processed, but the offset in + * the principal buffer is only advanced if the ECB completes processing + * without error. + * + * When a buffer is to be switched (either because the buffer is the principal + * buffer with a "switch" policy or because it is an aggregation buffer), a + * cross call is issued to the CPU associated with the buffer. In the cross + * call context, interrupts are disabled, and the active and the inactive + * buffers are atomically switched. This involves switching the data pointers, + * copying the various state fields (offset, drops, errors, etc.) into their + * inactive equivalents, and clearing the state fields. Because interrupts are + * disabled during this procedure, the switch is guaranteed to appear atomic to + * dtrace_probe(). + * + * DTrace Ring Buffering + * + * To process a ring buffer correctly, one must know the oldest valid record. + * Processing starts at the oldest record in the buffer and continues until + * the end of the buffer is reached. Processing then resumes starting with + * the record stored at offset 0 in the buffer, and continues until the + * youngest record is processed. If trace records are of a fixed-length, + * determining the oldest record is trivial: + * + * - If the ring buffer has not wrapped, the oldest record is the record + * stored at offset 0. + * + * - If the ring buffer has wrapped, the oldest record is the record stored + * at the current offset. + * + * With variable length records, however, just knowing the current offset + * doesn't suffice for determining the oldest valid record: assuming that one + * allows for arbitrary data, one has no way of searching forward from the + * current offset to find the oldest valid record. (That is, one has no way + * of separating data from metadata.) It would be possible to simply refuse to + * process any data in the ring buffer between the current offset and the + * limit, but this leaves (potentially) an enormous amount of otherwise valid + * data unprocessed. + * + * To effect ring buffering, we track two offsets in the buffer: the current + * offset and the _wrapped_ offset. If a request is made to reserve some + * amount of data, and the buffer has wrapped, the wrapped offset is + * incremented until the wrapped offset minus the current offset is greater + * than or equal to the reserve request. This is done by repeatedly looking + * up the ECB corresponding to the EPID at the current wrapped offset, and + * incrementing the wrapped offset by the size of the data payload + * corresponding to that ECB. If this offset is greater than or equal to the + * limit of the data buffer, the wrapped offset is set to 0. Thus, the + * current offset effectively "chases" the wrapped offset around the buffer. + * Schematically: + * + * base of data buffer ---> +------+--------------------+------+ + * | EPID | data | EPID | + * +------+--------+------+----+------+ + * | data | EPID | data | + * +---------------+------+-----------+ + * | data, cont. | + * +------+---------------------------+ + * | EPID | data | + * current offset ---> +------+---------------------------+ + * | invalid data | + * wrapped offset ---> +------+--------------------+------+ + * | EPID | data | EPID | + * +------+--------+------+----+------+ + * | data | EPID | data | + * +---------------+------+-----------+ + * : : + * . . + * . ... valid data ... . + * . . + * : : + * +------+-------------+------+------+ + * | EPID | data | EPID | data | + * +------+------------++------+------+ + * | data, cont. | leftover | + * limit of data buffer ---> +-------------------+--------------+ + * + * If the amount of requested buffer space exceeds the amount of space + * available between the current offset and the end of the buffer: + * + * (1) all words in the data buffer between the current offset and the limit + * of the data buffer (marked "leftover", above) are set to + * DTRACE_EPIDNONE + * + * (2) the wrapped offset is set to zero + * + * (3) the iteration process described above occurs until the wrapped offset + * is greater than the amount of desired space. + * + * The wrapped offset is implemented by (re-)using the inactive offset. + * In a "switch" buffer policy, the inactive offset stores the offset in + * the inactive buffer; in a "ring" buffer policy, it stores the wrapped + * offset. + * + * DTrace Scratch Buffering + * + * Some ECBs may wish to allocate dynamically-sized temporary scratch memory. + * To accommodate such requests easily, scratch memory may be allocated in + * the buffer beyond the current offset plus the needed memory of the current + * ECB. If there isn't sufficient room in the buffer for the requested amount + * of scratch space, the allocation fails and an error is generated. Scratch + * memory is tracked in the dtrace_mstate_t and is automatically freed when + * the ECB ceases processing. Note that ring buffers cannot allocate their + * scratch from the principal buffer -- lest they needlessly overwrite older, + * valid data. Ring buffers therefore have their own dedicated scratch buffer + * from which scratch is allocated. + */ + +extern void dtrace_buffer_switch(dtrace_buffer_t *); +extern void dtrace_buffer_activate(dtrace_state_t *); +extern int dtrace_buffer_alloc(dtrace_buffer_t *, size_t, int, processorid_t); +extern void dtrace_buffer_drop(dtrace_buffer_t *); +extern intptr_t dtrace_buffer_reserve(dtrace_buffer_t *, size_t, size_t, + dtrace_state_t *, dtrace_mstate_t *); +extern void dtrace_buffer_polish(dtrace_buffer_t *); +extern void dtrace_buffer_free(dtrace_buffer_t *); + +/* + * DTrace Enabling Functions + */ +extern dtrace_enabling_t *dtrace_retained; +extern dtrace_genid_t dtrace_retained_gen; + +extern dtrace_enabling_t *dtrace_enabling_create(dtrace_vstate_t *); +extern void dtrace_enabling_add(dtrace_enabling_t *, dtrace_ecbdesc_t *); +extern void dtrace_enabling_dump(dtrace_enabling_t *); +extern void dtrace_enabling_destroy(dtrace_enabling_t *); +extern int dtrace_enabling_retain(dtrace_enabling_t *); +extern int dtrace_enabling_replicate(dtrace_state_t *, dtrace_probedesc_t *, + dtrace_probedesc_t *); +extern void dtrace_enabling_retract(dtrace_state_t *); +extern int dtrace_enabling_match(dtrace_enabling_t *, int *); +extern void dtrace_enabling_matchall(void); +extern void dtrace_enabling_prime(dtrace_state_t *); +extern void dtrace_enabling_provide(dtrace_provider_t *); + +/* + * DOF functions + */ +extern void dtrace_dof_error(dof_hdr_t *, const char *); +extern dof_hdr_t *dtrace_dof_create(dtrace_state_t *); +extern dof_hdr_t *dtrace_dof_copyin(void __user *, int *); +extern dof_hdr_t *dtrace_dof_property(const char *); +extern void dtrace_dof_destroy(dof_hdr_t *); +extern int dtrace_dof_slurp(dof_hdr_t *, dtrace_vstate_t *, const cred_t *, + dtrace_enabling_t **, uint64_t, int); +extern int dtrace_dof_options(dof_hdr_t *, dtrace_state_t *); +extern void dtrace_helper_provide(dof_helper_t *dhp, pid_t pid); +extern int dtrace_helper_slurp(dof_hdr_t *, dof_helper_t *); +extern int dtrace_helper_destroygen(int); + +/* + * DTrace Anonymous Enabling Functions + */ +typedef struct dtrace_anon { + dtrace_state_t *dta_state; + dtrace_enabling_t *dta_enabling; + processorid_t dta_beganon; +} dtrace_anon_t; + +extern dtrace_anon_t dtrace_anon; + +extern dtrace_state_t *dtrace_anon_grab(void); +extern void dtrace_anon_property(void); + +/* + * DTrace Consumer State Functions + */ +extern struct kmem_cache *dtrace_state_cache; +extern size_t dtrace_strsize_default; + +extern ktime_t dtrace_deadman_timeout; +extern int dtrace_destructive_disallow; + +extern dtrace_id_t dtrace_probeid_begin; +extern dtrace_id_t dtrace_probeid_end; +extern dtrace_id_t dtrace_probeid_error; + +extern dtrace_dynvar_t dtrace_dynhash_sink; + +extern int dtrace_dstate_init(dtrace_dstate_t *, size_t); +extern void dtrace_dstate_fini(dtrace_dstate_t *); +extern void dtrace_vstate_fini(dtrace_vstate_t *); +extern dtrace_state_t *dtrace_state_create(struct file *); +extern int dtrace_state_go(dtrace_state_t *, processorid_t *); +extern int dtrace_state_stop(dtrace_state_t *, processorid_t *); +extern int dtrace_state_option(dtrace_state_t *, dtrace_optid_t, + dtrace_optval_t); +extern void dtrace_state_destroy(dtrace_state_t *); + +/* + * DTrace Utility Functions + */ +extern void *dtrace_vzalloc(unsigned long); +extern void *dtrace_vzalloc_try(unsigned long); +extern char *dtrace_strdup(const char *); +extern int dtrace_strncmp(char *, char *, size_t); +extern size_t dtrace_strlen(const char *, size_t); +extern int dtrace_badattr(const dtrace_attribute_t *); +extern int dtrace_badname(const char *); +extern void dtrace_cred2priv(const cred_t *, uint32_t *, uid_t *); + +extern void ctf_forceload(void); + +#define dtrace_membar_producer() mb() +#define dtrace_membar_consumer() mb() + +typedef unsigned long dtrace_icookie_t; + +extern struct mutex cpu_lock; + +extern void dtrace_sync(void); +extern void dtrace_toxic_ranges(void (*)(uintptr_t, uintptr_t)); +extern void dtrace_vpanic(const char *, va_list); +extern int dtrace_getipl(void); + +extern ktime_t dtrace_gethrestime(void); + +extern dtrace_vtime_state_t dtrace_vtime_active; + +extern void dtrace_vtime_enable(void); +extern void dtrace_vtime_disable(void); + +extern ktime_t dtrace_gethrtime(void); +extern ktime_t dtrace_getwalltime(void); + +extern dtrace_icookie_t dtrace_interrupt_disable(void); +extern void dtrace_interrupt_enable(dtrace_icookie_t); + +typedef void (*dtrace_xcall_t)(void *); + +extern void dtrace_xcall(processorid_t, dtrace_xcall_t, void *); + +extern uint8_t dtrace_fuword8(void *); +extern uint16_t dtrace_fuword16(void *); +extern uint32_t dtrace_fuword32(void *); +extern uint64_t dtrace_fuword64(void *); + +extern void dtrace_probe_error(dtrace_state_t *, dtrace_epid_t, int, int, int, + uintptr_t); + +extern void dtrace_getpcstack(uint64_t *, int, int, uint32_t *); +extern void dtrace_getupcstack(uint64_t *, int); +extern void dtrace_getufpstack(uint64_t *, uint64_t *, int); +extern uintptr_t dtrace_getfp(void); +extern uint64_t dtrace_getarg(int, int); +extern int dtrace_getstackdepth(int); +extern int dtrace_getustackdepth(void); +extern ulong_t dtrace_getreg(struct task_struct *, uint_t); +extern void dtrace_copyin(uintptr_t, uintptr_t, size_t, volatile uint16_t *); +extern void dtrace_copyout(uintptr_t, uintptr_t, size_t, volatile uint16_t *); +extern void dtrace_copyinstr(uintptr_t, uintptr_t, size_t, + volatile uint16_t *); +extern void dtrace_copyoutstr(uintptr_t, uintptr_t, size_t, + volatile uint16_t *); +extern uintptr_t dtrace_caller(int); + +extern void debug_enter(char *); + +#endif /* _LINUX_DTRACE_IMPL_H */ diff --git a/dtrace/include/dtrace/dtrace_impl_defines.h b/dtrace/include/dtrace/dtrace_impl_defines.h new file mode 100644 index 000000000000..3765321b23b4 --- /dev/null +++ b/dtrace/include/dtrace/dtrace_impl_defines.h @@ -0,0 +1,246 @@ +#ifndef _LINUX_DTRACE_IMPL_DEFINES_H +#define _LINUX_DTRACE_IMPL_DEFINES_H + +/* + * DTrace Dynamic Tracing Software: DTrace Implementation defines + * + * Note: The contents of this file are private to the implementation of the + * DTrace subsystem and are subject to change at any time without notice. + */ + +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + * + * Copyright 2009 -- 2013 Oracle, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include +#include + +typedef typeof(((struct pt_regs *)0)->ip) pc_t; + +typedef enum dtrace_activity { + DTRACE_ACTIVITY_INACTIVE = 0, + DTRACE_ACTIVITY_WARMUP, + DTRACE_ACTIVITY_ACTIVE, + DTRACE_ACTIVITY_DRAINING, + DTRACE_ACTIVITY_COOLDOWN, + DTRACE_ACTIVITY_STOPPED, + DTRACE_ACTIVITY_KILLED +} dtrace_activity_t; + +typedef enum dtrace_dstate_state { + DTRACE_DSTATE_CLEAN = 0, + DTRACE_DSTATE_EMPTY, + DTRACE_DSTATE_DIRTY, + DTRACE_DSTATE_RINSING +} dtrace_dstate_state_t; + +typedef enum dtrace_dynvar_op { + DTRACE_DYNVAR_ALLOC, + DTRACE_DYNVAR_NOALLOC, + DTRACE_DYNVAR_DEALLOC +} dtrace_dynvar_op_t; + +#define DTRACE_MSTATE_ARGS 0x00000001 +#define DTRACE_MSTATE_PROBE 0x00000002 +#define DTRACE_MSTATE_EPID 0x00000004 +#define DTRACE_MSTATE_TIMESTAMP 0x00000008 +#define DTRACE_MSTATE_STACKDEPTH 0x00000010 +#define DTRACE_MSTATE_CALLER 0x00000020 +#define DTRACE_MSTATE_IPL 0x00000040 +#define DTRACE_MSTATE_FLTOFFS 0x00000080 +#define DTRACE_MSTATE_USTACKDEPTH 0x00000100 +#define DTRACE_MSTATE_UCALLER 0x00000200 + +#define DTRACE_PROBEKEY_MAXDEPTH 8 + +typedef enum dtrace_speculation_state { + DTRACESPEC_INACTIVE = 0, + DTRACESPEC_ACTIVE, + DTRACESPEC_ACTIVEONE, + DTRACESPEC_ACTIVEMANY, + DTRACESPEC_COMMITTING, + DTRACESPEC_COMMITTINGMANY, + DTRACESPEC_DISCARDING +} dtrace_speculation_state_t; + +#define DTRACE_HELPER_ACTION_USTACK 0 +#define DTRACE_NHELPER_ACTIONS 1 + +#define DTRACE_HELPTRACE_NEXT (-1) +#define DTRACE_HELPTRACE_DONE (-2) +#define DTRACE_HELPTRACE_ERR (-3) + +#undef ASSERT +#ifdef CONFIG_DT_DEBUG +# define ASSERT(x) ((void)((x) || dtrace_assfail(#x, __FILE__, __LINE__))) +#else +# define ASSERT(x) ((void)0) +#endif + +/* + * DTrace Probe Hashing + */ + +#define DTRACE_HASHNEXT(hash, probe) \ + (dtrace_probe_t **)((uintptr_t)(probe) + (hash)->dth_nextoffs) +#define DTRACE_HASHPREV(hash, probe) \ + (dtrace_probe_t **)((uintptr_t)(probe) + (hash)->dth_prevoffs) + +/* + * DTrace Probe Management + */ +#define DTRACE_ANCHORED(probe) ((probe)->dtpr_func[0] != '\0') +#define DTRACE_FLAGS2FLT(flags) \ + (((flags) & CPU_DTRACE_BADADDR) ? DTRACEFLT_BADADDR : \ + ((flags) & CPU_DTRACE_ILLOP) ? DTRACEFLT_ILLOP : \ + ((flags) & CPU_DTRACE_DIVZERO) ? DTRACEFLT_DIVZERO : \ + ((flags) & CPU_DTRACE_KPRIV) ? DTRACEFLT_KPRIV : \ + ((flags) & CPU_DTRACE_UPRIV) ? DTRACEFLT_UPRIV : \ + ((flags) & CPU_DTRACE_TUPOFLOW) ? DTRACEFLT_TUPOFLOW : \ + ((flags) & CPU_DTRACE_BADALIGN) ? DTRACEFLT_BADALIGN : \ + ((flags) & CPU_DTRACE_NOSCRATCH) ? DTRACEFLT_NOSCRATCH : \ + ((flags) & CPU_DTRACE_BADSTACK) ? DTRACEFLT_BADSTACK : \ + DTRACEFLT_UNKNOWN) + +/* + * Test whether alloc_sz bytes will fit in the scratch region. We isolate + * alloc_sz on the righthand side of the comparison in order to avoid overflow + * or underflow in the comparison with it. This is simpler than the INRANGE + * check above, because we know that the dtms_scratch_ptr is valid in the + * range. Allocations of size zero are allowed. + */ +#define DTRACE_INSCRATCH(mstate, alloc_sz) \ + ((mstate)->dtms_scratch_base + (mstate)->dtms_scratch_size - \ + (mstate)->dtms_scratch_ptr >= (alloc_sz)) + +/* + * Buffering. + */ + +#define DTRACEBUF_RING 0x0001 /* bufpolicy set to "ring" */ +#define DTRACEBUF_FILL 0x0002 /* bufpolicy set to "fill" */ +#define DTRACEBUF_NOSWITCH 0x0004 /* do not switch buffer */ +#define DTRACEBUF_WRAPPED 0x0008 /* ring buffer has wrapped */ +#define DTRACEBUF_DROPPED 0x0010 /* drops occurred */ +#define DTRACEBUF_ERROR 0x0020 /* errors occurred */ +#define DTRACEBUF_FULL 0x0040 /* "fill" buffer is full */ +#define DTRACEBUF_CONSUMED 0x0080 /* buffer has been consumed */ +#define DTRACEBUF_INACTIVE 0x0100 /* buffer is not yet active */ + +#define DTRACE_STORE(type, tomax, offset, what) \ + do { \ + *((type *)((uintptr_t)(tomax) + (uintptr_t)(offset))) = (type)(what); \ + } while (0) + +typedef enum dtrace_vtime_state { + DTRACE_VTIME_INACTIVE = 0, /* No DTrace, no TNF */ + DTRACE_VTIME_ACTIVE, /* DTrace virtual time, no TNF */ + DTRACE_VTIME_INACTIVE_TNF, /* No DTrace, TNF active */ + DTRACE_VTIME_ACTIVE_TNF /* DTrace virtual time _and_ TNF */ +} dtrace_vtime_state_t; + +#define KERNELBASE (uintptr_t)_text + +/* + * regset.h information + */ +#ifdef __i386__ +# define REG_SS 18 /* only stored on a privilege transition */ +# define REG_UESP 17 /* only stored on a privilege transition */ +# define REG_EFL 16 +# define REG_CS 15 +# define REG_EIP 14 +# define REG_ERR 13 +# define REG_TRAPNO 12 +# define REG_EAX 11 +# define REG_ECX 10 +# define REG_EDX 9 +# define REG_EBX 8 +# define REG_ESP 7 +# define REG_EBP 6 +# define REG_ESI 5 +# define REG_EDI 4 +# define REG_DS 3 +# define REG_ES 2 +# define REG_FS 1 +# define REG_GS 0 +#else +# define REG_GS 24 +# define REG_FS 23 +# define REG_ES 22 +# define REG_DS 21 +# define REG_SS 20 +# define REG_RSP 19 +# define REG_RFL 18 +# define REG_CS 17 +# define REG_RIP 16 +# define REG_ERR 15 +# define REG_TRAPNO 15 +# define REG_RDI 14 +# define REG_RSI 13 +# define REG_RDX 12 +# define REG_RCX 11 +# define REG_RAX 10 +# define REG_R8 9 +# define REG_R9 8 +# define REG_R10 7 +# define REG_R11 6 +# define REG_RBX 5 +# define REG_RBP 4 +# define REG_R12 3 +# define REG_R13 2 +# define REG_R14 1 +# define REG_R15 0 +#endif + +#if defined(__i386__) || defined(__x86_64__) +# define DTRACE_INVOP_PUSHL_EBP 1 +# define DTRACE_INVOP_POPL_EBP 2 +# define DTRACE_INVOP_LEAVE 3 +# define DTRACE_INVOP_NOP 4 +# define DTRACE_INVOP_RET 5 +#endif + +#ifdef CONFIG_DT_DEBUG_MUTEX +# define _mutex_lock(x) mutex_lock(x) +# define _mutex_unlock(x) mutex_unlock(x) + +# define mutex_lock(x) do { \ + printk(KERN_DEBUG \ + "mutex_lock(%s) at %s::%d\n", \ + __stringify(x), \ + __FILE__, __LINE__); \ + _mutex_lock(x); \ + } while (0) +# define mutex_unlock(x) do { \ + printk(KERN_DEBUG \ + "mutex_unlock(%s) at %s::%d\n", \ + __stringify(x), \ + __FILE__, __LINE__); \ + _mutex_unlock(x); \ + } while (0) +#endif + +#define MUTEX_HELD(lock) mutex_owned(lock) + +#endif /* _LINUX_DTRACE_IMPL_DEFINES_H */ diff --git a/dtrace/include/dtrace/provider.h b/dtrace/include/dtrace/provider.h new file mode 100644 index 000000000000..a6eb7c160700 --- /dev/null +++ b/dtrace/include/dtrace/provider.h @@ -0,0 +1,930 @@ +#ifndef _DTRACE_PROVIDER_H +#define _DTRACE_PROVIDER_H + +/* + * DTrace Dynamic Tracing Software: DTrace Provider API + * + * Note: The contents of this file are private to the implementation of the + * DTrace subsystem and are subject to change at any time without notice. + */ + +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + * + * Copyright 2009 -- 2013 Oracle, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* + * The following functions are implemented by the DTrace framework and are + * used to implement separate in-kernel DTrace providers. + * + * The provider API has two halves: the API that the providers consume from + * DTrace, and the API that providers make available to DTrace. + * + * 1 Framework-to-Provider API + * + * 1.1 Overview + * + * The Framework-to-Provider API is represented by the dtrace_pops structure + * that the provider passes to the framework when registering itself. This + * structure consists of the following members: + * + * dtps_provide() <-- Provide all probes, all modules + * dtps_provide_module() <-- Provide all probes in specified module + * dtps_enable() <-- Enable specified probe + * dtps_disable() <-- Disable specified probe + * dtps_suspend() <-- Suspend specified probe + * dtps_resume() <-- Resume specified probe + * dtps_getargdesc() <-- Get the argument description for args[X] + * dtps_getargval() <-- Get the value for an argX or args[X] variable + * dtps_usermode() <-- Find out if the probe was fired in user mode + * dtps_destroy() <-- Destroy all state associated with this probe + * + * 1.2 void dtps_provide(void *arg, const dtrace_probedesc_t *spec) + * + * 1.2.1 Overview + * + * Called to indicate that the provider should provide all probes. If the + * specified description is non-NULL, dtps_provide() is being called because + * no probe matched a specified probe -- if the provider has the ability to + * create custom probes, it may wish to create a probe that matches the + * specified description. + * + * 1.2.2 Arguments and notes + * + * The first argument is the cookie as passed to dtrace_register(). The + * second argument is a pointer to a probe description that the provider may + * wish to consider when creating custom probes. The provider is expected to + * call back into the DTrace framework via dtrace_probe_create() to create + * any necessary probes. dtps_provide() may be called even if the provider + * has made available all probes; the provider should check the return value + * of dtrace_probe_create() to handle this case. Note that the provider need + * not implement both dtps_provide() and dtps_provide_module(); see + * "Arguments and Notes" for dtrace_register(), below. + * + * 1.2.3 Return value + * + * None. + * + * 1.2.4 Caller's context + * + * dtps_provide() is typically called from open() or ioctl() context, but may + * be called from other contexts as well. The DTrace framework is locked in + * such a way that providers may not register or unregister. This means that + * the provider may not call any DTrace API that affects its registration with + * the framework, including dtrace_register(), dtrace_unregister(), + * dtrace_invalidate(), and dtrace_condense(). However, the context is such + * that the provider may (and indeed, is expected to) call probe-related + * DTrace routines, including dtrace_probe_create(), dtrace_probe_lookup(), + * and dtrace_probe_arg(). + * + * 1.3 void dtps_provide_module(void *arg, struct modctl *mp) + * + * 1.3.1 Overview + * + * Called to indicate that the provider should provide all probes in the + * specified module. + * + * 1.3.2 Arguments and notes + * + * The first argument is the cookie as passed to dtrace_register(). The + * second argument is a pointer to a modctl structure that indicates the + * module for which probes should be created. + * + * 1.3.3 Return value + * + * None. + * + * 1.3.4 Caller's context + * + * dtps_provide_module() may be called from open() or ioctl() context, but + * may also be called from a module loading context. mod_lock is held, and + * the DTrace framework is locked in such a way that providers may not + * register or unregister. This means that the provider may not call any + * DTrace API that affects its registration with the framework, including + * dtrace_register(), dtrace_unregister(), dtrace_invalidate(), and + * dtrace_condense(). However, the context is such that the provider may (and + * indeed, is expected to) call probe-related DTrace routines, including + * dtrace_probe_create(), dtrace_probe_lookup(), and dtrace_probe_arg(). Note + * that the provider need not implement both dtps_provide() and + * dtps_provide_module(); see "Arguments and Notes" for dtrace_register(), + * below. + * + * 1.4 int dtps_enable(void *arg, dtrace_id_t id, void *parg) + * + * 1.4.1 Overview + * + * Called to enable the specified probe. + * + * 1.4.2 Arguments and notes + * + * The first argument is the cookie as passed to dtrace_register(). The + * second argument is the identifier of the probe to be enabled. The third + * argument is the probe argument as passed to dtrace_probe_create(). + * dtps_enable() will be called when a probe transitions from not being + * enabled at all to having one or more ECB. The number of ECBs associated + * with the probe may change without subsequent calls into the provider. + * When the number of ECBs drops to zero, the provider will be explicitly + * told to disable the probe via dtps_disable(). dtrace_probe() should never + * be called for a probe identifier that hasn't been explicitly enabled via + * dtps_enable(). + * + * 1.4.3 Return value + * + * On success, dtps_enable() should return 0. On failure, -1 should be + * returned. + * + * 1.4.4 Caller's context + * + * The DTrace framework is locked in such a way that it may not be called + * back into at all. cpu_lock is held. mod_lock is not held and may not + * be acquired. + * + * 1.5 void dtps_disable(void *arg, dtrace_id_t id, void *parg) + * + * 1.5.1 Overview + * + * Called to disable the specified probe. + * + * 1.5.2 Arguments and notes + * + * The first argument is the cookie as passed to dtrace_register(). The + * second argument is the identifier of the probe to be disabled. The third + * argument is the probe argument as passed to dtrace_probe_create(). + * dtps_disable() will be called when a probe transitions from being enabled + * to having zero ECBs. dtrace_probe() should never be called for a probe + * identifier that has been explicitly enabled via dtps_disable(). + * + * 1.5.3 Return value + * + * None. + * + * 1.5.4 Caller's context + * + * The DTrace framework is locked in such a way that it may not be called + * back into at all. cpu_lock is held. mod_lock is not held and may not + * be acquired. + * + * 1.6 void dtps_suspend(void *arg, dtrace_id_t id, void *parg) + * + * 1.6.1 Overview + * + * Called to suspend the specified enabled probe. This entry point is for + * providers that may need to suspend some or all of their probes when CPUs + * are being powered on or when the boot monitor is being entered for a + * prolonged period of time. + * + * 1.6.2 Arguments and notes + * + * The first argument is the cookie as passed to dtrace_register(). The + * second argument is the identifier of the probe to be suspended. The + * third argument is the probe argument as passed to dtrace_probe_create(). + * dtps_suspend will only be called on an enabled probe. Providers that + * provide a dtps_suspend entry point will want to take roughly the action + * that it takes for dtps_disable. + * + * 1.6.3 Return value + * + * None. + * + * 1.6.4 Caller's context + * + * Interrupts are disabled. The DTrace framework is in a state such that the + * specified probe cannot be disabled or destroyed for the duration of + * dtps_suspend(). As interrupts are disabled, the provider is afforded + * little latitude; the provider is expected to do no more than a store to + * memory. + * + * 1.7 void dtps_resume(void *arg, dtrace_id_t id, void *parg) + * + * 1.7.1 Overview + * + * Called to resume the specified enabled probe. This entry point is for + * providers that may need to resume some or all of their probes after the + * completion of an event that induced a call to dtps_suspend(). + * + * 1.7.2 Arguments and notes + * + * The first argument is the cookie as passed to dtrace_register(). The + * second argument is the identifier of the probe to be resumed. The + * third argument is the probe argument as passed to dtrace_probe_create(). + * dtps_resume will only be called on an enabled probe. Providers that + * provide a dtps_resume entry point will want to take roughly the action + * that it takes for dtps_enable. + * + * 1.7.3 Return value + * + * None. + * + * 1.7.4 Caller's context + * + * Interrupts are disabled. The DTrace framework is in a state such that the + * specified probe cannot be disabled or destroyed for the duration of + * dtps_resume(). As interrupts are disabled, the provider is afforded + * little latitude; the provider is expected to do no more than a store to + * memory. + * + * 1.8 void dtps_getargdesc(void *arg, dtrace_id_t id, void *parg, + * dtrace_argdesc_t *desc) + * + * 1.8.1 Overview + * + * Called to retrieve the argument description for an args[X] variable. + * + * 1.8.2 Arguments and notes + * + * The first argument is the cookie as passed to dtrace_register(). The + * second argument is the identifier of the current probe. The third + * argument is the probe argument as passed to dtrace_probe_create(). The + * fourth argument is a pointer to the argument description. This + * description is both an input and output parameter: it contains the + * index of the desired argument in the dtargd_ndx field, and expects + * the other fields to be filled in upon return. If there is no argument + * corresponding to the specified index, the dtargd_ndx field should be set + * to DTRACE_ARGNONE. + * + * 1.8.3 Return value + * + * None. The dtargd_ndx, dtargd_native, dtargd_xlate and dtargd_mapping + * members of the dtrace_argdesc_t structure are all output values. + * + * 1.8.4 Caller's context + * + * dtps_getargdesc() is called from ioctl() context. mod_lock is held, and + * the DTrace framework is locked in such a way that providers may not + * register or unregister. This means that the provider may not call any + * DTrace API that affects its registration with the framework, including + * dtrace_register(), dtrace_unregister(), dtrace_invalidate(), and + * dtrace_condense(). + * + * 1.9 uint64_t dtps_getargval(void *arg, dtrace_id_t id, void *parg, + * int argno, int aframes) + * + * 1.9.1 Overview + * + * Called to retrieve a value for an argX or args[X] variable. + * + * 1.9.2 Arguments and notes + * + * The first argument is the cookie as passed to dtrace_register(). The + * second argument is the identifier of the current probe. The third + * argument is the probe argument as passed to dtrace_probe_create(). The + * fourth argument is the number of the argument (the X in the example in + * 1.9.1). The fifth argument is the number of stack frames that were used + * to get from the actual place in the code that fired the probe to + * dtrace_probe() itself, the so-called artificial frames. This argument may + * be used to descend an appropriate number of frames to find the correct + * values. If this entry point is left NULL, the dtrace_getarg() built-in + * function is used. + * + * 1.9.3 Return value + * + * The value of the argument. + * + * 1.9.4 Caller's context + * + * This is called from within dtrace_probe() meaning that interrupts + * are disabled. No locks should be taken within this entry point. + * + * 1.10 int dtps_usermode(void *arg, dtrace_id_t id, void *parg) + * + * 1.10.1 Overview + * + * Called to determine if the probe was fired in a user context. + * + * 1.10.2 Arguments and notes + * + * The first argument is the cookie as passed to dtrace_register(). The + * second argument is the identifier of the current probe. The third + * argument is the probe argument as passed to dtrace_probe_create(). This + * entry point must not be left NULL for providers whose probes allow for + * mixed mode tracing, that is to say those probes that can fire during + * kernel- _or_ user-mode execution + * + * 1.10.3 Return value + * + * A boolean value. + * + * 1.10.4 Caller's context + * + * This is called from within dtrace_probe() meaning that interrupts + * are disabled. No locks should be taken within this entry point. + * + * 1.11 void dtps_destroy(void *arg, dtrace_id_t id, void *parg) + * + * 1.11.1 Overview + * + * Called to destroy the specified probe. + * + * 1.11.2 Arguments and notes + * + * The first argument is the cookie as passed to dtrace_register(). The + * second argument is the identifier of the probe to be destroyed. The third + * argument is the probe argument as passed to dtrace_probe_create(). The + * provider should free all state associated with the probe. The framework + * guarantees that dtps_destroy() is only called for probes that have either + * been disabled via dtps_disable() or were never enabled via dtps_enable(). + * Once dtps_disable() has been called for a probe, no further call will be + * made specifying the probe. + * + * 1.11.3 Return value + * + * None. + * + * 1.11.4 Caller's context + * + * The DTrace framework is locked in such a way that it may not be called + * back into at all. mod_lock is held. cpu_lock is not held, and may not be + * acquired. + * + * + * 2 Provider-to-Framework API + * + * 2.1 Overview + * + * The Provider-to-Framework API provides the mechanism for the provider to + * register itself with the DTrace framework, to create probes, to lookup + * probes and (most importantly) to fire probes. The Provider-to-Framework + * consists of: + * + * dtrace_register() <-- Register a provider with the DTrace framework + * dtrace_unregister() <-- Remove a provider's DTrace registration + * dtrace_meta_register() <-- Register a metaprovider with the DTrace framework + * dtrace_meta_unregister()<-- Remove a metaprovider's DTrace registration + * dtrace_invalidate() <-- Invalidate the specified provider + * dtrace_condense() <-- Remove a provider's unenabled probes + * dtrace_attached() <-- Indicates whether or not DTrace has attached + * dtrace_probe_create() <-- Create a DTrace probe + * dtrace_probe_lookup() <-- Lookup a DTrace probe based on its name + * dtrace_probe_arg() <-- Return the probe argument for a specific probe + * dtrace_probe() <-- Fire the specified probe + * + * 2.2 int dtrace_register(const char *name, const dtrace_pattr_t *pap, + * uint32_t priv, cred_t *cr, const dtrace_pops_t *pops, void *arg, + * dtrace_provider_id_t *idp) + * + * 2.2.1 Overview + * + * dtrace_register() registers the calling provider with the DTrace + * framework. It should generally be called by DTrace providers in their + * attach(9E) entry point. + * + * 2.2.2 Arguments and Notes + * + * The first argument is the name of the provider. The second argument is a + * pointer to the stability attributes for the provider. The third argument + * is the privilege flags for the provider, and must be some combination of: + * + * DTRACE_PRIV_NONE <= All users may enable probes from this provider + * + * DTRACE_PRIV_PROC <= Any user with privilege of PRIV_DTRACE_PROC may + * enable probes from this provider + * + * DTRACE_PRIV_USER <= Any user with privilege of PRIV_DTRACE_USER may + * enable probes from this provider + * + * DTRACE_PRIV_KERNEL <= Any user with privilege of PRIV_DTRACE_KERNEL + * may enable probes from this provider + * + * DTRACE_PRIV_OWNER <= This flag places an additional constraint on + * the privilege requirements above. These probes + * require either (a) a user ID matching the user + * ID of the cred passed in the fourth argument + * or (b) the PRIV_PROC_OWNER privilege. + * + * Note that these flags designate the _visibility_ of the probes, not + * the conditions under which they may or may not fire. + * + * The fourth argument is the credential that is associated with the provider. + * This argument should be NULL if the privilege flags don't include + * DTRACE_PRIV_OWNER. If non-NULL, the framework stashes the uid represented + * by this credential for use at probe-time, in implicit predicates. These + * limit visibility of the probes to users which have sufficient privilege to + * access them. + * + * The fifth argument is a DTrace provider operations vector, which provides + * the implementation for the Framework-to-Provider API. (See Section 1, + * above.) This must be non-NULL, and each member must be non-NULL. The + * exceptions to this are (1) the dtps_provide() and dtps_provide_module() + * members (if the provider so desires, _one_ of these members may be left + * NULL -- denoting that the provider only implements the other) and (2) + * the dtps_suspend() and dtps_resume() members, which must either both be + * NULL or both be non-NULL. + * + * The sixth argument is a cookie to be specified as the first argument for + * each function in the Framework-to-Provider API. This argument may have + * any value. + * + * The final argument is a pointer to dtrace_provider_id_t. If + * dtrace_register() successfully completes, the provider identifier will be + * stored in the memory pointed to be this argument. This argument must be + * non-NULL. + * + * 2.2.3 Return value + * + * On success, dtrace_register() returns 0 and stores the new provider's + * identifier into the memory pointed to by the idp argument. On failure, + * dtrace_register() returns an errno: + * + * EINVAL The arguments passed to dtrace_register() were somehow invalid. + * This may because a parameter that must be non-NULL was NULL, + * because the name was invalid (either empty or an illegal + * provider name) or because the attributes were invalid. + * + * No other failure code is returned. + * + * 2.2.4 Caller's context + * + * dtrace_register() may induce calls to dtrace_provide(); the provider must + * hold no locks across dtrace_register() that may also be acquired by + * dtrace_provide(). cpu_lock and mod_lock must not be held. + * + * 2.3 int dtrace_unregister(dtrace_provider_t id) + * + * 2.3.1 Overview + * + * Unregisters the specified provider from the DTrace framework. It should + * generally be called by DTrace providers in their detach(9E) entry point. + * + * 2.3.2 Arguments and Notes + * + * The only argument is the provider identifier, as returned from a + * successful call to dtrace_register(). As a result of calling + * dtrace_unregister(), the DTrace framework will call back into the provider + * via the dtps_destroy() entry point. Once dtrace_unregister() successfully + * completes, however, the DTrace framework will no longer make calls through + * the Framework-to-Provider API. + * + * 2.3.3 Return value + * + * On success, dtrace_unregister returns 0. On failure, dtrace_unregister() + * returns an errno: + * + * EBUSY There are currently processes that have the DTrace pseudodevice + * open, or there exists an anonymous enabling that hasn't yet + * been claimed. + * + * No other failure code is returned. + * + * 2.3.4 Caller's context + * + * Because a call to dtrace_unregister() may induce calls through the + * Framework-to-Provider API, the caller may not hold any lock across + * dtrace_register() that is also acquired in any of the Framework-to- + * Provider API functions. Additionally, mod_lock may not be held. + * + * 2.4 void dtrace_invalidate(dtrace_provider_id_t id) + * + * 2.4.1 Overview + * + * Invalidates the specified provider. All subsequent probe lookups for the + * specified provider will fail, but its probes will not be removed. + * + * 2.4.2 Arguments and note + * + * The only argument is the provider identifier, as returned from a + * successful call to dtrace_register(). In general, a provider's probes + * always remain valid; dtrace_invalidate() is a mechanism for invalidating + * an entire provider, regardless of whether or not probes are enabled or + * not. Note that dtrace_invalidate() will _not_ prevent already enabled + * probes from firing -- it will merely prevent any new enablings of the + * provider's probes. + * + * 2.5 int dtrace_condense(dtrace_provider_id_t id) + * + * 2.5.1 Overview + * + * Removes all the unenabled probes for the given provider. This function is + * not unlike dtrace_unregister(), except that it doesn't remove the + * provider just as many of its associated probes as it can. + * + * 2.5.2 Arguments and Notes + * + * As with dtrace_unregister(), the sole argument is the provider identifier + * as returned from a successful call to dtrace_register(). As a result of + * calling dtrace_condense(), the DTrace framework will call back into the + * given provider's dtps_destroy() entry point for each of the provider's + * unenabled probes. + * + * 2.5.3 Return value + * + * Currently, dtrace_condense() always returns 0. However, consumers of this + * function should check the return value as appropriate; its behavior may + * change in the future. + * + * 2.5.4 Caller's context + * + * As with dtrace_unregister(), the caller may not hold any lock across + * dtrace_condense() that is also acquired in the provider's entry points. + * Also, mod_lock may not be held. + * + * 2.6 int dtrace_attached() + * + * 2.6.1 Overview + * + * Indicates whether or not DTrace has attached. + * + * 2.6.2 Arguments and Notes + * + * For most providers, DTrace makes initial contact beyond registration. + * That is, once a provider has registered with DTrace, it waits to hear + * from DTrace to create probes. However, some providers may wish to + * proactively create probes without first being told by DTrace to do so. + * If providers wish to do this, they must first call dtrace_attached() to + * determine if DTrace itself has attached. If dtrace_attached() returns 0, + * the provider must not make any other Provider-to-Framework API call. + * + * 2.6.3 Return value + * + * dtrace_attached() returns 1 if DTrace has attached, 0 otherwise. + * + * 2.7 int dtrace_probe_create(dtrace_provider_t id, const char *mod, + * const char *func, const char *name, int aframes, void *arg) + * + * 2.7.1 Overview + * + * Creates a probe with specified module name, function name, and name. + * + * 2.7.2 Arguments and Notes + * + * The first argument is the provider identifier, as returned from a + * successful call to dtrace_register(). The second, third, and fourth + * arguments are the module name, function name, and probe name, + * respectively. Of these, module name and function name may both be NULL + * (in which case the probe is considered to be unanchored), or they may both + * be non-NULL. The name must be non-NULL, and must point to a non-empty + * string. + * + * The fifth argument is the number of artificial stack frames that will be + * found on the stack when dtrace_probe() is called for the new probe. These + * artificial frames will be automatically be pruned should the stack() or + * stackdepth() functions be called as part of one of the probe's ECBs. If + * the parameter doesn't add an artificial frame, this parameter should be + * zero. + * + * The final argument is a probe argument that will be passed back to the + * provider when a probe-specific operation is called. (e.g., via + * dtps_enable(), dtps_disable(), etc.) + * + * Note that it is up to the provider to be sure that the probe that it + * creates does not already exist -- if the provider is unsure of the probe's + * existence, it should assure its absence with dtrace_probe_lookup() before + * calling dtrace_probe_create(). + * + * 2.7.3 Return value + * + * dtrace_probe_create() always succeeds, and always returns the identifier + * of the newly-created probe. + * + * 2.7.4 Caller's context + * + * While dtrace_probe_create() is generally expected to be called from + * dtps_provide() and/or dtps_provide_module(), it may be called from other + * non-DTrace contexts. Neither cpu_lock nor mod_lock may be held. + * + * 2.8 dtrace_id_t dtrace_probe_lookup(dtrace_provider_t id, const char *mod, + * const char *func, const char *name) + * + * 2.8.1 Overview + * + * Looks up a probe based on provdider and one or more of module name, + * function name and probe name. + * + * 2.8.2 Arguments and Notes + * + * The first argument is the provider identifier, as returned from a + * successful call to dtrace_register(). The second, third, and fourth + * arguments are the module name, function name, and probe name, + * respectively. Any of these may be NULL; dtrace_probe_lookup() will return + * the identifier of the first probe that is provided by the specified + * provider and matches all of the non-NULL matching criteria. + * dtrace_probe_lookup() is generally used by a provider to be check the + * existence of a probe before creating it with dtrace_probe_create(). + * + * 2.8.3 Return value + * + * If the probe exists, returns its identifier. If the probe does not exist, + * return DTRACE_IDNONE. + * + * 2.8.4 Caller's context + * + * While dtrace_probe_lookup() is generally expected to be called from + * dtps_provide() and/or dtps_provide_module(), it may also be called from + * other non-DTrace contexts. Neither cpu_lock nor mod_lock may be held. + * + * 2.9 void *dtrace_probe_arg(dtrace_provider_t id, dtrace_id_t probe) + * + * 2.9.1 Overview + * + * Returns the probe argument associated with the specified probe. + * + * 2.9.2 Arguments and Notes + * + * The first argument is the provider identifier, as returned from a + * successful call to dtrace_register(). The second argument is a probe + * identifier, as returned from dtrace_probe_lookup() or + * dtrace_probe_create(). This is useful if a probe has multiple + * provider-specific components to it: the provider can create the probe + * once with provider-specific state, and then add to the state by looking + * up the probe based on probe identifier. + * + * 2.9.3 Return value + * + * Returns the argument associated with the specified probe. If the + * specified probe does not exist, or if the specified probe is not provided + * by the specified provider, NULL is returned. + * + * 2.9.4 Caller's context + * + * While dtrace_probe_arg() is generally expected to be called from + * dtps_provide() and/or dtps_provide_module(), it may also be called from + * other non-DTrace contexts. Neither cpu_lock nor mod_lock may be held. + * + * 2.10 void dtrace_probe(dtrace_id_t probe, uintptr_t arg0, uintptr_t arg1, + * uintptr_t arg2, uintptr_t arg3, uintptr_t arg4) + * + * 2.10.1 Overview + * + * The epicenter of DTrace: fires the specified probes with the specified + * arguments. + * + * 2.10.2 Arguments and Notes + * + * The first argument is a probe identifier as returned by + * dtrace_probe_create() or dtrace_probe_lookup(). The second through sixth + * arguments are the values to which the D variables "arg0" through "arg4" + * will be mapped. + * + * dtrace_probe() should be called whenever the specified probe has fired -- + * however the provider defines it. + * + * 2.10.3 Return value + * + * None. + * + * 2.10.4 Caller's context + * + * dtrace_probe() may be called in virtually any context: kernel, user, + * interrupt, high-level interrupt, with arbitrary adaptive locks held, with + * dispatcher locks held, with interrupts disabled, etc. The only latitude + * that must be afforded to DTrace is the ability to make calls within + * itself (and to its in-kernel subroutines) and the ability to access + * arbitrary (but mapped) memory. On some platforms, this constrains + * context. For example, on UltraSPARC, dtrace_probe() cannot be called + * from any context in which TL is greater than zero. dtrace_probe() may + * also not be called from any routine which may be called by dtrace_probe() + * -- which includes functions in the DTrace framework and some in-kernel + * DTrace subroutines. All such functions "dtrace_"; providers that + * instrument the kernel arbitrarily should be sure to not instrument these + * routines. + */ + +#include +#include +#include +#include +#include +#include + +typedef struct dtrace_pops { + void (*dtps_provide)(void *, const struct dtrace_probedesc *); + void (*dtps_provide_module)(void *, struct module *); + int (*dtps_enable)(void *, dtrace_id_t, void *); + void (*dtps_disable)(void *, dtrace_id_t, void *); + void (*dtps_suspend)(void *, dtrace_id_t, void *); + void (*dtps_resume)(void *, dtrace_id_t, void *); + void (*dtps_getargdesc)(void *, dtrace_id_t, void *, + struct dtrace_argdesc *); + uint64_t (*dtps_getargval)(void *, dtrace_id_t, void *, int, int); + int (*dtps_usermode)(void *, dtrace_id_t, void *); + void (*dtps_destroy)(void *, dtrace_id_t, void *); +} dtrace_pops_t; + +typedef struct dtrace_helper_probedesc { + char *dthpb_mod; + char *dthpb_func; + char *dthpb_name; + uint64_t dthpb_base; + uint32_t *dthpb_offs; + uint32_t *dthpb_enoffs; + uint32_t dthpb_noffs; + uint32_t dthpb_nenoffs; + uint8_t *dthpb_args; + uint8_t dthpb_xargc; + uint8_t dthpb_nargc; + char *dthpb_xtypes; + char *dthpb_ntypes; +} dtrace_helper_probedesc_t; + +typedef struct dtrace_helper_provdesc { + char *dthpv_provname; + struct dtrace_pattr dthpv_pattr; +} dtrace_helper_provdesc_t; + +typedef struct dtrace_mops { + void (*dtms_create_probe)(void *, void *, dtrace_helper_probedesc_t *); + void *(*dtms_provide_pid)(void *, dtrace_helper_provdesc_t *, pid_t); + void (*dtms_remove_pid)(void *, dtrace_helper_provdesc_t *, pid_t); +} dtrace_mops_t; + +/* + * DTrace Provider-to-Framework API Functions + */ + +typedef struct dtrace_meta { + dtrace_mops_t dtm_mops; + char *dtm_name; + void *dtm_arg; + uint64_t dtm_count; +} dtrace_meta_t; + +typedef struct dtrace_mprovider { + char *dtmp_name; + char *dtmp_pref; + dtrace_pattr_t *dtmp_attr; + uint32_t dtmp_priv; + dtrace_pops_t *dtmp_pops; + dtrace_provider_id_t dtmp_id; +} dtrace_mprovider_t; + +extern int dtrace_register(const char *, const dtrace_pattr_t *, uint32_t, + const cred_t *, const dtrace_pops_t *, void *, + dtrace_provider_id_t *); +extern int dtrace_unregister(dtrace_provider_id_t); +extern void dtrace_invalidate(dtrace_provider_id_t); +extern int dtrace_condense(dtrace_provider_id_t); +extern int dtrace_attached(void); + +extern int dtrace_meta_register(const char *, const dtrace_mops_t *, void *, + dtrace_meta_provider_id_t *); +extern int dtrace_meta_unregister(dtrace_meta_provider_id_t); + +extern dtrace_id_t dtrace_probe_create(dtrace_provider_id_t, const char *, + const char *, const char *, int, + void *); +extern void *dtrace_probe_arg(dtrace_provider_id_t, dtrace_id_t); +extern dtrace_id_t dtrace_probe_lookup(dtrace_provider_id_t, const char *, + const char *, const char *); +extern void dtrace_probe(dtrace_id_t, uintptr_t, uintptr_t, uintptr_t, + uintptr_t, uintptr_t); + +/* + * Provider creation. + */ + +#define DT_PROVIDER_POPS(name) \ + static unsigned int name##_refc = 0; \ + \ + static int name##_enable(void *arg, dtrace_id_t id, void *parg) \ + { \ + int rc = 0; \ + \ + if (name##_refc++ == 0) { \ + if ((rc = try_module_get(THIS_MODULE)) == 0) \ + return 0; \ + } \ + \ + if ((rc = _##name##_enable(arg, id, parg)) != 0) { \ + if (--name##_refc == 0) \ + module_put(THIS_MODULE); \ + } \ + \ + return rc; \ + } \ + \ + static void name##_disable(void *arg, dtrace_id_t id, void *parg) \ + { \ + _##name##_disable(arg, id, parg); \ + \ + if (--name##_refc == 0) \ + module_put(THIS_MODULE); \ + } + +#define DT_PROVIDER_MODULE(name, priv) \ + dtrace_provider_id_t name##_id; \ + \ + static int __init name##_init(void) \ + { \ + int ret = 0; \ + \ + ret = name##_dev_init(); \ + if (ret) \ + goto failed; \ + \ + ret = dtrace_register(__stringify(name), &name##_attr, priv, \ + NULL, &name##_pops, NULL, &name##_id); \ + if (ret) \ + goto failed; \ + \ + return 0; \ + \ + failed: \ + return ret; \ + } \ + \ + static void __exit name##_exit(void) \ + { \ + dtrace_unregister(name##_id); \ + name##_dev_exit(); \ + } \ + \ + module_init(name##_init); \ + module_exit(name##_exit); + +#define DT_META_PROVIDER_MODULE(name) \ + dtrace_meta_provider_id_t name##_id; \ + \ + static int __init name##_init(void) \ + { \ + int ret = 0; \ + \ + ret = name##_dev_init(); \ + if (ret) \ + goto failed; \ + \ + ret = dtrace_meta_register(__stringify(name), &name##_mops, \ + NULL, &name##_id); \ + if (ret) \ + goto failed; \ + \ + return 0; \ + \ + failed: \ + return ret; \ + } \ + \ + static void __exit name##_exit(void) \ + { \ + dtrace_meta_unregister(name##_id); \ + name##_dev_exit(); \ + } \ + \ + module_init(name##_init); \ + module_exit(name##_exit); + +#define DT_MULTI_PROVIDER_MODULE(name, plist) \ + static int __init name##_init(void) \ + { \ + int ret = 0; \ + dtrace_mprovider_t *prov; \ + \ + ret = name##_dev_init(); \ + if (ret) \ + goto failed; \ + \ + for (prov = plist; prov->dtmp_name != NULL; prov++) { \ + if (dtrace_register(prov->dtmp_name, prov->dtmp_attr, \ + prov->dtmp_priv, NULL, \ + prov->dtmp_pops, prov, \ + &prov->dtmp_id) != 0) \ + pr_warning("Failed to register sdt provider %s",\ + prov->dtmp_name); \ + } \ + \ + return 0; \ + \ + failed: \ + return ret; \ + } \ + \ + static void __exit name##_exit(void) \ + { \ + int ret = 0; \ + dtrace_mprovider_t *prov; \ + \ + for (prov = plist; prov->dtmp_name != NULL; prov++) { \ + if (prov->dtmp_id != DTRACE_PROVNONE) { \ + ret = dtrace_unregister(prov->dtmp_id); \ + if (ret != 0) \ + return; \ + \ + prov->dtmp_id = DTRACE_PROVNONE; \ + } \ + } \ + \ + name##_dev_exit(); \ + } \ + \ + module_init(name##_init); \ + module_exit(name##_exit); + + +#endif /* _DTRACE_PROVIDER_H */ diff --git a/dtrace/include/dtrace/provider_defines.h b/dtrace/include/dtrace/provider_defines.h new file mode 100644 index 000000000000..676a98726d83 --- /dev/null +++ b/dtrace/include/dtrace/provider_defines.h @@ -0,0 +1,49 @@ +#ifndef _DTRACE_PROVIDER_DEFINES_H +#define _DTRACE_PROVIDER_DEFINES_H + +/* + * DTrace Dynamic Tracing Software: DTrace Provider defines + * + * Note: The contents of this file are private to the implementation of the + * DTrace subsystem and are subject to change at any time without notice. + */ + +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + * + * Copyright 2009 -- 2013 Oracle, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include +#include + +typedef uintptr_t dtrace_provider_id_t; +typedef uintptr_t dtrace_meta_provider_id_t; +typedef struct cred cred_t; +typedef __be32 ipaddr_t; + +struct dtrace_pops; +struct dtrace_helper_probedesc; +struct dtrace_helper_provdesc; +struct dtrace_mops; +struct dtrace_meta; + +#endif /* _DTRACE_PROVIDER_DEFINES_H */ diff --git a/dtrace/include/dtrace/types.h b/dtrace/include/dtrace/types.h new file mode 100644 index 000000000000..978cdc0bc440 --- /dev/null +++ b/dtrace/include/dtrace/types.h @@ -0,0 +1,141 @@ +#ifndef _DTRACE_TYPES_H +#define _DTRACE_TYPES_H + +/* + * DTrace Dynamic Tracing Software: DTrace kernel types + * + * Note: The contents of this file are private to the implementation of the + * DTrace subsystem and are subject to change at any time without notice. + */ + +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + * + * Copyright 2009 -- 2013 Oracle, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* + * This file contains types needed to parse the DTrace shared userspace/ kernel + * headers, and a few others (it has not been gardened to remove constants used + * only by the DTrace core). Userspace has its own version of these types + * (mostly from ). + * + * This file is compiled both in a normal kernel environment and in a peculiar + * halfway-house environment used for headers_checking of , in which + * among other things, no config.h symbols are available. As a result, you + * should be careful about #including kernel headers here: many will break + * headers_check if added. So far, it has always been sufficient to add them to + * dtrace/dtrace.h instead; if this turns out to be insufficient later (perhaps + * because DTrace core files cease to #include all of ), the + * HEADERS_CHECK #define may prove useful to disable kernel-only portions of + * this file. + */ + +#include +#include + +typedef unsigned char uchar_t; +typedef unsigned int uint_t; +typedef unsigned long ulong_t; + +typedef long intptr_t; + +#define UINT8_MAX (0xff) +#define UINT8_MIN 0 +#define UINT16_MAX (0xffff) +#define UINT16_MIN 0 +#define UINT32_MAX (0xffffffff) +#define UINT32_MIN 0 +#define UINT64_MAX (~0ULL) +#define UINT64_MIN (0) +#define INT64_MAX ((long long)(~0ULL>>1)) +#define INT64_MIN (-INT64_MAX - 1LL) + +#define NBBY (__BITS_PER_LONG / sizeof (long)) + +/* + * This is a bit unusual, but OpenSolaris seems to like it. Basically, the + * values below are the number of time units (sec, milli, micro, nano) that + * comprise 1 second. As such, it is the value of the respective multiplier. + */ +#define SEC 1 +#define MILLISEC 1000 +#define MICROSEC 1000000 +#define NANOSEC 1000000000 + +typedef enum { + TRUE = -1, + FALSE = 0 +} boolean_t; + + +#define DTRACE_ACCESS_KERNEL 0x1 + +#define DTRACE_CRA_PROC 0x0001 +#define DTRACE_CRA_PROC_CONTROL 0x0002 +#define DTRACE_CRA_PROC_DESTRUCTIVE_ALLUSER 0x0004 +#define DTRACE_CRA_PROC_DESTRUCTIVE_CREDCHG 0x0010 +#define DTRACE_CRA_KERNEL 0x0020 +#define DTRACE_CRA_KERNEL_DESTRUCTIVE 0x0040 + +#define DTRACE_CRA_ALL (DTRACE_CRA_PROC | \ + DTRACE_CRA_PROC_CONTROL | \ + DTRACE_CRA_PROC_DESTRUCTIVE_ALLUSER | \ + DTRACE_CRA_PROC_DESTRUCTIVE_CREDCHG | \ + DTRACE_CRA_KERNEL | \ + DTRACE_CRA_KERNEL_DESTRUCTIVE) + +#define DTRACE_CRV_ALLPROC 0x01 +#define DTRACE_CRV_KERNEL 0x02 +#define DTRACE_CRV_ALL (DTRACE_CRV_ALLPROC | DTRACE_CRV_KERNEL) + +#define DTRACE_MATCH_FAIL -1 +#define DTRACE_MATCH_NEXT 0 +#define DTRACE_MATCH_DONE 1 + +#define DTRACE_COND_OWNER 0x01 +#define DTRACE_COND_USERMODE 0x02 + +#define P2ROUNDUP(x, a) (-(-(x) & -(a))) + +#if (BITS_PER_LONG == 64) || defined(CONFIG_KTIME_SCALAR) +# define KTIME_INIT(s, ns) { .tv64 = (s64)(s) * NSEC_PER_SEC + (s64)(ns) } +#else +# define KTIME_INIT(n, ns) { .tv = { .sec = (s), .nsec = (ns) } } +#endif +#define ktime_lt(t0, t1) ((t0).tv64 < (t1).tv64) +#define ktime_le(t0, t1) ((t0).tv64 <= (t1).tv64) +#define ktime_ge(t0, t1) ((t0).tv64 >= (t1).tv64) +#define ktime_gt(t0, t1) ((t0).tv64 > (t1).tv64) +#define ktime_nz(t0) ((t0).tv64 != 0LL) +#define ktime_cp(t0, t1) ((t0).tv64 = (t1).tv64) + +/* + * Translate between kernel config options and userspace-compatible definitions. + */ +#ifdef CONFIG_64BIT +#define _LP64 1 +#endif +#ifdef __LITTLE_ENDIAN +#define _LITTLE_ENDIAN 1 +#endif + +#endif /* _DTRACE_TYPES_H */ diff --git a/dtrace/include/uapi/linux/dtrace/actions.h b/dtrace/include/uapi/linux/dtrace/actions.h new file mode 100644 index 000000000000..304c01d59275 --- /dev/null +++ b/dtrace/include/uapi/linux/dtrace/actions.h @@ -0,0 +1,30 @@ +#ifndef _LINUX_DTRACE_ACTIONS_H +#define _LINUX_DTRACE_ACTIONS_H + +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + * + * Copyright 2009 -- 2013 Oracle, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include + +#endif /* _LINUX_DTRACE_ACTIONS_H */ diff --git a/dtrace/include/uapi/linux/dtrace/actions_defines.h b/dtrace/include/uapi/linux/dtrace/actions_defines.h new file mode 100644 index 000000000000..05a5e28518be --- /dev/null +++ b/dtrace/include/uapi/linux/dtrace/actions_defines.h @@ -0,0 +1,171 @@ +#ifndef _LINUX_DTRACE_ACTIONS_DEFINES_H +#define _LINUX_DTRACE_ACTIONS_DEFINES_H + +/* + * DTrace Dynamic Tracing Software: DTrace Actions defines + * + * Note: The contents of this file are private to the implementation of the + * DTrace subsystem and are subject to change at any time without notice. + */ + +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + * + * Copyright 2009 -- 2013 Oracle, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include + +/* + * The upper byte determines the class of the action; the low bytes determines + * the specific action within that class. The classes of actions are as + * follows: + * + * [ no class ] <= May record process- or kernel-related data + * DTRACEACT_PROC <= Only records process-related data + * DTRACEACT_PROC_DESTRUCTIVE <= Potentially destructive to processes + * DTRACEACT_KERNEL <= Only records kernel-related data + * DTRACEACT_KERNEL_DESTRUCTIVE <= Potentially destructive to the kernel + * DTRACEACT_SPECULATIVE <= Speculation-related action + * DTRACEACT_AGGREGATION <= Aggregating action + */ +#define DTRACEACT_NONE 0 /* no action */ +#define DTRACEACT_DIFEXPR 1 /* action is DIF expression */ +#define DTRACEACT_EXIT 2 /* exit() action */ +#define DTRACEACT_PRINTF 3 /* printf() action */ +#define DTRACEACT_PRINTA 4 /* printa() action */ +#define DTRACEACT_LIBACT 5 /* library-controlled action */ + +#define DTRACEACT_PROC 0x0100 +#define DTRACEACT_USTACK (DTRACEACT_PROC + 1) +#define DTRACEACT_JSTACK (DTRACEACT_PROC + 2) +#define DTRACEACT_USYM (DTRACEACT_PROC + 3) +#define DTRACEACT_UMOD (DTRACEACT_PROC + 4) +#define DTRACEACT_UADDR (DTRACEACT_PROC + 5) + +#define DTRACEACT_PROC_DESTRUCTIVE 0x0200 +#define DTRACEACT_STOP (DTRACEACT_PROC_DESTRUCTIVE + 1) +#define DTRACEACT_RAISE (DTRACEACT_PROC_DESTRUCTIVE + 2) +#define DTRACEACT_SYSTEM (DTRACEACT_PROC_DESTRUCTIVE + 3) +#define DTRACEACT_FREOPEN (DTRACEACT_PROC_DESTRUCTIVE + 4) + +#define DTRACEACT_PROC_CONTROL 0x0300 + +#define DTRACEACT_KERNEL 0x0400 +#define DTRACEACT_STACK (DTRACEACT_KERNEL + 1) +#define DTRACEACT_SYM (DTRACEACT_KERNEL + 2) +#define DTRACEACT_MOD (DTRACEACT_KERNEL + 3) + +#define DTRACEACT_KERNEL_DESTRUCTIVE 0x0500 +#define DTRACEACT_BREAKPOINT (DTRACEACT_KERNEL_DESTRUCTIVE + 1) +#define DTRACEACT_PANIC (DTRACEACT_KERNEL_DESTRUCTIVE + 2) +#define DTRACEACT_CHILL (DTRACEACT_KERNEL_DESTRUCTIVE + 3) + +#define DTRACEACT_SPECULATIVE 0x0600 +#define DTRACEACT_SPECULATE (DTRACEACT_SPECULATIVE + 1) +#define DTRACEACT_COMMIT (DTRACEACT_SPECULATIVE + 2) +#define DTRACEACT_DISCARD (DTRACEACT_SPECULATIVE + 3) + +#define DTRACEACT_CLASS(x) ((x) & 0xff00) + +#define DTRACEACT_ISAGG(x) \ + (DTRACEACT_CLASS(x) == DTRACEACT_AGGREGATION) + +#define DTRACEACT_ISDESTRUCTIVE(x) \ + (DTRACEACT_CLASS(x) == DTRACEACT_PROC_DESTRUCTIVE || \ + DTRACEACT_CLASS(x) == DTRACEACT_KERNEL_DESTRUCTIVE) + +#define DTRACEACT_ISSPECULATIVE(x) \ + (DTRACEACT_CLASS(x) == DTRACEACT_SPECULATIVE) + +#define DTRACEACT_ISPRINTFLIKE(x) \ + ((x) == DTRACEACT_PRINTF || (x) == DTRACEACT_PRINTA || \ + (x) == DTRACEACT_SYSTEM || (x) == DTRACEACT_FREOPEN) + +/* + * DTrace Aggregating Actions + * + * These are functions f(x) for which the following is true: + * + * f(f(x_0) U f(x_1) U ... U f(x_n)) = f(x_0 U x_1 U ... U x_n) + * + * where x_n is a set of arbitrary data. Aggregating actions are in their own + * DTrace action class, DTTRACEACT_AGGREGATION. The macros provided here allow + * for easier processing of the aggregation argument and data payload for a few + * aggregating actions (notably: quantize(), lquantize(), and ustack()). + */ + +#define DTRACEACT_AGGREGATION 0x0700 +#define DTRACEAGG_COUNT (DTRACEACT_AGGREGATION + 1) +#define DTRACEAGG_MIN (DTRACEACT_AGGREGATION + 2) +#define DTRACEAGG_MAX (DTRACEACT_AGGREGATION + 3) +#define DTRACEAGG_AVG (DTRACEACT_AGGREGATION + 4) +#define DTRACEAGG_SUM (DTRACEACT_AGGREGATION + 5) +#define DTRACEAGG_STDDEV (DTRACEACT_AGGREGATION + 6) +#define DTRACEAGG_QUANTIZE (DTRACEACT_AGGREGATION + 7) +#define DTRACEAGG_LQUANTIZE (DTRACEACT_AGGREGATION + 8) + +#define DTRACE_QUANTIZE_NBUCKETS \ + (((sizeof (uint64_t) * NBBY) - 1) * 2 + 1) + +#define DTRACE_QUANTIZE_ZEROBUCKET ((sizeof (uint64_t) * NBBY) - 1) + +#define DTRACE_QUANTIZE_BUCKETVAL(buck) \ + (int64_t)((buck) < DTRACE_QUANTIZE_ZEROBUCKET ? \ + -(1LL << (DTRACE_QUANTIZE_ZEROBUCKET - 1 - (buck))) : \ + (buck) == DTRACE_QUANTIZE_ZEROBUCKET ? 0 : \ + 1LL << ((buck) - DTRACE_QUANTIZE_ZEROBUCKET - 1)) + +#define DTRACE_LQUANTIZE_STEPSHIFT 48 +#define DTRACE_LQUANTIZE_STEPMASK ((uint64_t)UINT16_MAX << 48) +#define DTRACE_LQUANTIZE_LEVELSHIFT 32 +#define DTRACE_LQUANTIZE_LEVELMASK ((uint64_t)UINT16_MAX << 32) +#define DTRACE_LQUANTIZE_BASESHIFT 0 +#define DTRACE_LQUANTIZE_BASEMASK UINT32_MAX + +#define DTRACE_LQUANTIZE_STEP(x) \ + (uint16_t)(((x) & DTRACE_LQUANTIZE_STEPMASK) >> \ + DTRACE_LQUANTIZE_STEPSHIFT) + +#define DTRACE_LQUANTIZE_LEVELS(x) \ + (uint16_t)(((x) & DTRACE_LQUANTIZE_LEVELMASK) >> \ + DTRACE_LQUANTIZE_LEVELSHIFT) + +#define DTRACE_LQUANTIZE_BASE(x) \ + (int32_t)(((x) & DTRACE_LQUANTIZE_BASEMASK) >> \ + DTRACE_LQUANTIZE_BASESHIFT) + +#define DTRACE_USTACK_NFRAMES(x) (uint32_t)((x) & UINT32_MAX) +#define DTRACE_USTACK_STRSIZE(x) (uint32_t)((x) >> 32) +#define DTRACE_USTACK_ARG(x, y) \ + ((((uint64_t)(y)) << 32) | ((x) & UINT32_MAX)) + +#ifndef _LP64 +# ifndef _LITTLE_ENDIAN +# define DTRACE_PTR(type, name) uint32_t name##pad; type *name +# else +# define DTRACE_PTR(type, name) type *name; uint32_t name##pad +# endif +#else +# define DTRACE_PTR(type, name) type *name +#endif + +#endif /* _LINUX_DTRACE_ACTIONS_DEFINES_H */ diff --git a/dtrace/include/uapi/linux/dtrace/arg.h b/dtrace/include/uapi/linux/dtrace/arg.h new file mode 100644 index 000000000000..1ee5fc4f01e4 --- /dev/null +++ b/dtrace/include/uapi/linux/dtrace/arg.h @@ -0,0 +1,60 @@ +#ifndef _LINUX_DTRACE_ARG_H +#define _LINUX_DTRACE_ARG_H + +/* + * DTrace Dynamic Tracing Software: DTrace Argument Types + * + * Note: The contents of this file are private to the implementation of the + * DTrace subsystem and are subject to change at any time without notice. + */ + +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + * + * Copyright 2009 -- 2013 Oracle, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include +#include + +/* + * Because it would waste both space and time, argument types do not reside + * with the probe. In order to determine argument types for args[X] + * variables, the D compiler queries for argument types on a probe-by-probe + * basis. (This optimizes for the common case that arguments are either not + * used or used in an untyped fashion.) Typed arguments are specified with a + * string of the type name in the dtragd_native member of the argument + * description structure. Typed arguments may be further translated to types + * of greater stability; the provider indicates such a translated argument by + * filling in the dtargd_xlate member with the string of the translated type. + * Finally, the provider may indicate which argument value a given argument + * maps to by setting the dtargd_mapping member -- allowing a single argument + * to map to multiple args[X] variables. + */ +typedef struct dtrace_argdesc { + dtrace_id_t dtargd_id; + int dtargd_ndx; + int dtargd_mapping; + char dtargd_native[DTRACE_ARGTYPELEN]; + char dtargd_xlate[DTRACE_ARGTYPELEN]; +} dtrace_argdesc_t; + +#endif /* _LINUX_DTRACE_ARG_H */ diff --git a/dtrace/include/uapi/linux/dtrace/arg_defines.h b/dtrace/include/uapi/linux/dtrace/arg_defines.h new file mode 100644 index 000000000000..28dad982ad39 --- /dev/null +++ b/dtrace/include/uapi/linux/dtrace/arg_defines.h @@ -0,0 +1,39 @@ +#ifndef _LINUX_DTRACE_ARG_DEFINES_H +#define _LINUX_DTRACE_ARG_DEFINES_H + +/* + * DTrace Dynamic Tracing Software: DTrace Argument Types defines + * + * Note: The contents of this file are private to the implementation of the + * DTrace subsystem and are subject to change at any time without notice. + */ + +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + * + * Copyright 2009 -- 2013 Oracle, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include + +struct dtrace_argdesc; + +#endif /* _LINUX_DTRACE_ARG_DEFINES_H */ diff --git a/dtrace/include/uapi/linux/dtrace/buffer.h b/dtrace/include/uapi/linux/dtrace/buffer.h new file mode 100644 index 000000000000..d00cced2cc4d --- /dev/null +++ b/dtrace/include/uapi/linux/dtrace/buffer.h @@ -0,0 +1,61 @@ +#ifndef _LINUX_DTRACE_BUFFER_H +#define _LINUX_DTRACE_BUFFER_H + +/* + * DTrace Dynamic Tracing Software: DTrace Buffer Interface + * + * Note: The contents of this file are private to the implementation of the + * DTrace subsystem and are subject to change at any time without notice. + */ + +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + * + * Copyright 2009 -- 2013 Oracle, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include +#include +#include + +/* + * In order to get a snapshot of the principal or aggregation buffer, + * user-level passes a buffer description to the kernel with the dtrace_bufdesc + * structure. This describes which CPU user-level is interested in, and + * where user-level wishes the kernel to snapshot the buffer to (the + * dtbd_data field). The kernel uses the same structure to pass back some + * information regarding the buffer: the size of data actually copied out, the + * number of drops, the number of errors, and the offset of the oldest record. + * If the buffer policy is a "switch" policy, taking a snapshot of the + * principal buffer has the additional effect of switching the active and + * inactive buffers. Taking a snapshot of the aggregation buffer _always_ has + * the additional effect of switching the active and inactive buffers. + */ +typedef struct dtrace_bufdesc { + uint64_t dtbd_size; /* size of buffer */ + uint32_t dtbd_cpu; /* CPU or DTRACE_CPUALL */ + uint32_t dtbd_errors; /* number of errors */ + uint64_t dtbd_drops; /* number of drops */ + DTRACE_PTR(char, dtbd_data); /* data */ + uint64_t dtbd_oldest; /* offset of oldest record */ +} dtrace_bufdesc_t; + +#endif /* _LINUX_DTRACE_BUFFER_H */ diff --git a/dtrace/include/uapi/linux/dtrace/buffer_defines.h b/dtrace/include/uapi/linux/dtrace/buffer_defines.h new file mode 100644 index 000000000000..eaa12ab96505 --- /dev/null +++ b/dtrace/include/uapi/linux/dtrace/buffer_defines.h @@ -0,0 +1,39 @@ +#ifndef _LINUX_DTRACE_BUFFER_DEFINES_H +#define _LINUX_DTRACE_BUFFER_DEFINES_H + +/* + * DTrace Dynamic Tracing Software: DTrace Buffer Interface + * + * Note: The contents of this file are private to the implementation of the + * DTrace subsystem and are subject to change at any time without notice. + */ + +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + * + * Copyright 2009 -- 2013 Oracle, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include + +struct dtrace_bufdesc; + +#endif /* _LINUX_DTRACE_BUFFER_DEFINES_H */ diff --git a/dtrace/include/uapi/linux/dtrace/conf.h b/dtrace/include/uapi/linux/dtrace/conf.h new file mode 100644 index 000000000000..06bcdc0641a6 --- /dev/null +++ b/dtrace/include/uapi/linux/dtrace/conf.h @@ -0,0 +1,53 @@ +#ifndef _LINUX_DTRACE_CONF_H +#define _LINUX_DTRACE_CONF_H + +/* + * DTrace Dynamic Tracing Software: DTrace Configuration + * + * Note: The contents of this file are private to the implementation of the + * DTrace subsystem and are subject to change at any time without notice. + */ + +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + * + * Copyright 2009 -- 2013 Oracle, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include +#include + +/* + * User-level may need to understand some elements of the kernel DTrace + * configuration in order to generate correct DIF. This information is + * conveyed via the dtrace_conf structure. + */ +typedef struct dtrace_conf { + uint_t dtc_difversion; /* supported DIF version */ + uint_t dtc_difintregs; /* # of DIF integer registers */ + uint_t dtc_diftupregs; /* # of DIF tuple registers */ + uint_t dtc_ctfmodel; /* CTF data model */ + /* Deviation from Solaris... Used to just be 8 padding entries. */ + uint_t dtc_maxbufs; /* max # of buffers */ + uint_t dtc_pad[7]; /* reserved for future use */ +} dtrace_conf_t; + +#endif /* _LINUX_DTRACE_CONF_H */ diff --git a/dtrace/include/uapi/linux/dtrace/conf_defines.h b/dtrace/include/uapi/linux/dtrace/conf_defines.h new file mode 100644 index 000000000000..950b3475a467 --- /dev/null +++ b/dtrace/include/uapi/linux/dtrace/conf_defines.h @@ -0,0 +1,39 @@ +#ifndef _LINUX_DTRACE_CONF_DEFINES_H +#define _LINUX_DTRACE_CONF_DEFINES_H + +/* + * DTrace Dynamic Tracing Software: DTrace Configuration defines + * + * Note: The contents of this file are private to the implementation of the + * DTrace subsystem and are subject to change at any time without notice. + */ + +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + * + * Copyright 2009 -- 2013 Oracle, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include + +struct dtrace_conf; + +#endif /* _LINUX_DTRACE_CONF_DEFINES_H */ diff --git a/dtrace/include/uapi/linux/dtrace/dif.h b/dtrace/include/uapi/linux/dtrace/dif.h new file mode 100644 index 000000000000..80c115699dc0 --- /dev/null +++ b/dtrace/include/uapi/linux/dtrace/dif.h @@ -0,0 +1,78 @@ +#ifndef _LINUX_DTRACE_DIF_H +#define _LINUX_DTRACE_DIF_H + +/* + * DTrace Dynamic Tracing Software: DTrace Intermediate Format (DIF) + * + * Note: The contents of this file are private to the implementation of the + * DTrace subsystem and are subject to change at any time without notice. + */ + +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + * + * Copyright 2009 -- 2013 Oracle, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include +#include + +/* + * The following definitions describe the DTrace Intermediate Format (DIF), a a + * RISC-like instruction set and program encoding used to represent predicates + * and actions that can be bound to DTrace probes. The constants below defining + * the number of available registers are suggested minimums; the compiler should + * use DTRACEIOC_CONF to dynamically obtain the number of registers provided by + * the current DTrace implementation. + */ + +/* + * A DTrace Intermediate Format Type (DIF Type) is used to represent the types + * of variables, function and associative array arguments, and the return type + * for each DIF object (shown below). It contains a description of the type, + * its size in bytes, and a module identifier. + */ + +typedef struct dtrace_diftype { + uint8_t dtdt_kind; + uint8_t dtdt_ckind; + uint8_t dtdt_flags; + uint8_t dtdt_pad; + uint32_t dtdt_size; +} dtrace_diftype_t; + +/* + * A DTrace Intermediate Format variable record is used to describe each of the + * variables referenced by a given DIF object. It contains an integer variable + * identifier along with variable scope and properties, as shown below. The + * size of this structure must be sizeof (int) aligned. + */ + +typedef struct dtrace_difv { + uint32_t dtdv_name; + uint32_t dtdv_id; + uint8_t dtdv_kind; + uint8_t dtdv_scope; + uint16_t dtdv_flags; + dtrace_diftype_t dtdv_type; +} dtrace_difv_t; + +#endif /* _LINUX_DTRACE_DIF_H */ diff --git a/dtrace/include/uapi/linux/dtrace/dif_defines.h b/dtrace/include/uapi/linux/dtrace/dif_defines.h new file mode 100644 index 000000000000..9e6e4db2f0cc --- /dev/null +++ b/dtrace/include/uapi/linux/dtrace/dif_defines.h @@ -0,0 +1,305 @@ +#ifndef _LINUX_DTRACE_DIF_DEFINES_H +#define _LINUX_DTRACE_DIF_DEFINES_H + +/* + * DTrace Dynamic Tracing Software: DTrace Intermediate Format (DIF) defines + * + * Note: The contents of this file are private to the implementation of the + * DTrace subsystem and are subject to change at any time without notice. + */ + +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + * + * Copyright 2009 -- 2013 Oracle, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include + +/* + * The following definitions describe the DTrace Intermediate Format (DIF), a a + * RISC-like instruction set and program encoding used to represent predicates + * and actions that can be bound to DTrace probes. The constants below defining + * the number of available registers are suggested minimums; the compiler should + * use DTRACEIOC_CONF to dynamically obtain the number of registers provided by + * the current DTrace implementation. + */ + +#define DIF_VERSION_1 1 +#define DIF_VERSION_2 2 +#define DIF_VERSION DIF_VERSION_2 +#define DIF_DIR_NREGS 8 /* number of DIF integer registers */ +#define DIF_DTR_NREGS 8 /* number of DIF tuple registers */ + +#define DIF_OP_OR 1 /* or r1, r2, rd */ +#define DIF_OP_XOR 2 /* xor r1, r2, rd */ +#define DIF_OP_AND 3 /* and r1, r2, rd */ +#define DIF_OP_SLL 4 /* sll r1, r2, rd */ +#define DIF_OP_SRL 5 /* srl r1, r2, rd */ +#define DIF_OP_SUB 6 /* sub r1, r2, rd */ +#define DIF_OP_ADD 7 /* add r1, r2, rd */ +#define DIF_OP_MUL 8 /* mul r1, r2, rd */ +#define DIF_OP_SDIV 9 /* sdiv r1, r2, rd */ +#define DIF_OP_UDIV 10 /* udiv r1, r2, rd */ +#define DIF_OP_SREM 11 /* srem r1, r2, rd */ +#define DIF_OP_UREM 12 /* urem r1, r2, rd */ +#define DIF_OP_NOT 13 /* not r1, rd */ +#define DIF_OP_MOV 14 /* mov r1, rd */ +#define DIF_OP_CMP 15 /* cmp r1, r2 */ +#define DIF_OP_TST 16 /* tst r1 */ +#define DIF_OP_BA 17 /* ba label */ +#define DIF_OP_BE 18 /* be label */ +#define DIF_OP_BNE 19 /* bne label */ +#define DIF_OP_BG 20 /* bg label */ +#define DIF_OP_BGU 21 /* bgu label */ +#define DIF_OP_BGE 22 /* bge label */ +#define DIF_OP_BGEU 23 /* bgeu label */ +#define DIF_OP_BL 24 /* bl label */ +#define DIF_OP_BLU 25 /* blu label */ +#define DIF_OP_BLE 26 /* ble label */ +#define DIF_OP_BLEU 27 /* bleu label */ +#define DIF_OP_LDSB 28 /* ldsb [r1], rd */ +#define DIF_OP_LDSH 29 /* ldsh [r1], rd */ +#define DIF_OP_LDSW 30 /* ldsw [r1], rd */ +#define DIF_OP_LDUB 31 /* ldub [r1], rd */ +#define DIF_OP_LDUH 32 /* lduh [r1], rd */ +#define DIF_OP_LDUW 33 /* lduw [r1], rd */ +#define DIF_OP_LDX 34 /* ldx [r1], rd */ +#define DIF_OP_RET 35 /* ret rd */ +#define DIF_OP_NOP 36 /* nop */ +#define DIF_OP_SETX 37 /* setx intindex, rd */ +#define DIF_OP_SETS 38 /* sets strindex, rd */ +#define DIF_OP_SCMP 39 /* scmp r1, r2 */ +#define DIF_OP_LDGA 40 /* ldga var, ri, rd */ +#define DIF_OP_LDGS 41 /* ldgs var, rd */ +#define DIF_OP_STGS 42 /* stgs var, rs */ +#define DIF_OP_LDTA 43 /* ldta var, ri, rd */ +#define DIF_OP_LDTS 44 /* ldts var, rd */ +#define DIF_OP_STTS 45 /* stts var, rs */ +#define DIF_OP_SRA 46 /* sra r1, r2, rd */ +#define DIF_OP_CALL 47 /* call subr, rd */ +#define DIF_OP_PUSHTR 48 /* pushtr type, rs, rr */ +#define DIF_OP_PUSHTV 49 /* pushtv type, rs, rv */ +#define DIF_OP_POPTS 50 /* popts */ +#define DIF_OP_FLUSHTS 51 /* flushts */ +#define DIF_OP_LDGAA 52 /* ldgaa var, rd */ +#define DIF_OP_LDTAA 53 /* ldtaa var, rd */ +#define DIF_OP_STGAA 54 /* stgaa var, rs */ +#define DIF_OP_STTAA 55 /* sttaa var, rs */ +#define DIF_OP_LDLS 56 /* ldls var, rd */ +#define DIF_OP_STLS 57 /* stls var, rs */ +#define DIF_OP_ALLOCS 58 /* allocs r1, rd */ +#define DIF_OP_COPYS 59 /* copys r1, r2, rd */ +#define DIF_OP_STB 60 /* stb r1, [rd] */ +#define DIF_OP_STH 61 /* sth r1, [rd] */ +#define DIF_OP_STW 62 /* stw r1, [rd] */ +#define DIF_OP_STX 63 /* stx r1, [rd] */ +#define DIF_OP_ULDSB 64 /* uldsb [r1], rd */ +#define DIF_OP_ULDSH 65 /* uldsh [r1], rd */ +#define DIF_OP_ULDSW 66 /* uldsw [r1], rd */ +#define DIF_OP_ULDUB 67 /* uldub [r1], rd */ +#define DIF_OP_ULDUH 68 /* ulduh [r1], rd */ +#define DIF_OP_ULDUW 69 /* ulduw [r1], rd */ +#define DIF_OP_ULDX 70 /* uldx [r1], rd */ +#define DIF_OP_RLDSB 71 /* rldsb [r1], rd */ +#define DIF_OP_RLDSH 72 /* rldsh [r1], rd */ +#define DIF_OP_RLDSW 73 /* rldsw [r1], rd */ +#define DIF_OP_RLDUB 74 /* rldub [r1], rd */ +#define DIF_OP_RLDUH 75 /* rlduh [r1], rd */ +#define DIF_OP_RLDUW 76 /* rlduw [r1], rd */ +#define DIF_OP_RLDX 77 /* rldx [r1], rd */ +#define DIF_OP_XLATE 78 /* xlate xlrindex, rd */ +#define DIF_OP_XLARG 79 /* xlarg xlrindex, rd */ + +#define DIF_INTOFF_MAX 0xffff /* highest integer table offset */ +#define DIF_STROFF_MAX 0xffff /* highest string table offset */ +#define DIF_REGISTER_MAX 0xff /* highest register number */ +#define DIF_VARIABLE_MAX 0xffff /* highest variable identifier */ +#define DIF_SUBROUTINE_MAX 0xffff /* highest subroutine code */ + +#define DIF_VAR_ARRAY_MIN 0x0000 /* lowest numbered array variable */ +#define DIF_VAR_ARRAY_UBASE 0x0080 /* lowest user-defined array */ +#define DIF_VAR_ARRAY_MAX 0x00ff /* highest numbered array variable */ + +#define DIF_VAR_OTHER_MIN 0x0100 /* lowest numbered scalar or assc */ +#define DIF_VAR_OTHER_UBASE 0x0500 /* lowest user-defined scalar or assc */ +#define DIF_VAR_OTHER_MAX 0xffff /* highest numbered scalar or assc */ + +#define DIF_VAR_ARGS 0x0000 +#define DIF_VAR_REGS 0x0001 +#define DIF_VAR_UREGS 0x0002 +#define DIF_VAR_CURTHREAD 0x0100 +#define DIF_VAR_TIMESTAMP 0x0101 +#define DIF_VAR_VTIMESTAMP 0x0102 +#define DIF_VAR_IPL 0x0103 +#define DIF_VAR_EPID 0x0104 +#define DIF_VAR_ID 0x0105 +#define DIF_VAR_ARG0 0x0106 +#define DIF_VAR_ARG1 0x0107 +#define DIF_VAR_ARG2 0x0108 +#define DIF_VAR_ARG3 0x0109 +#define DIF_VAR_ARG4 0x010a +#define DIF_VAR_ARG5 0x010b +#define DIF_VAR_ARG6 0x010c +#define DIF_VAR_ARG7 0x010d +#define DIF_VAR_ARG8 0x010e +#define DIF_VAR_ARG9 0x010f +#define DIF_VAR_STACKDEPTH 0x0110 +#define DIF_VAR_CALLER 0x0111 +#define DIF_VAR_PROBEPROV 0x0112 +#define DIF_VAR_PROBEMOD 0x0113 +#define DIF_VAR_PROBEFUNC 0x0114 +#define DIF_VAR_PROBENAME 0x0115 +#define DIF_VAR_PID 0x0116 +#define DIF_VAR_TID 0x0117 +#define DIF_VAR_EXECNAME 0x0118 +#define DIF_VAR_ZONENAME 0x0119 +#define DIF_VAR_WALLTIMESTAMP 0x011a +#define DIF_VAR_USTACKDEPTH 0x011b +#define DIF_VAR_UCALLER 0x011c +#define DIF_VAR_PPID 0x011d +#define DIF_VAR_UID 0x011e +#define DIF_VAR_GID 0x011f +#define DIF_VAR_ERRNO 0x0120 +#define DIF_VAR_CURCPU 0x0121 + +#define DIF_SUBR_RAND 0 +#define DIF_SUBR_MUTEX_OWNED 1 +#define DIF_SUBR_MUTEX_OWNER 2 +#define DIF_SUBR_MUTEX_TYPE_ADAPTIVE 3 +#define DIF_SUBR_MUTEX_TYPE_SPIN 4 +#define DIF_SUBR_RW_READ_HELD 5 +#define DIF_SUBR_RW_WRITE_HELD 6 +#define DIF_SUBR_RW_ISWRITER 7 +#define DIF_SUBR_COPYIN 8 +#define DIF_SUBR_COPYINSTR 9 +#define DIF_SUBR_SPECULATION 10 +#define DIF_SUBR_PROGENYOF 11 +#define DIF_SUBR_STRLEN 12 +#define DIF_SUBR_COPYOUT 13 +#define DIF_SUBR_COPYOUTSTR 14 +#define DIF_SUBR_ALLOCA 15 +#define DIF_SUBR_BCOPY 16 +#define DIF_SUBR_COPYINTO 17 +#define DIF_SUBR_MSGDSIZE 18 +#define DIF_SUBR_MSGSIZE 19 +#define DIF_SUBR_GETMAJOR 20 +#define DIF_SUBR_GETMINOR 21 +#define DIF_SUBR_DDI_PATHNAME 22 +#define DIF_SUBR_STRJOIN 23 +#define DIF_SUBR_LLTOSTR 24 +#define DIF_SUBR_BASENAME 25 +#define DIF_SUBR_DIRNAME 26 +#define DIF_SUBR_CLEANPATH 27 +#define DIF_SUBR_STRCHR 28 +#define DIF_SUBR_STRRCHR 29 +#define DIF_SUBR_STRSTR 30 +#define DIF_SUBR_STRTOK 31 +#define DIF_SUBR_SUBSTR 32 +#define DIF_SUBR_INDEX 33 +#define DIF_SUBR_RINDEX 34 +#define DIF_SUBR_HTONS 35 +#define DIF_SUBR_HTONL 36 +#define DIF_SUBR_HTONLL 37 +#define DIF_SUBR_NTOHS 38 +#define DIF_SUBR_NTOHL 39 +#define DIF_SUBR_NTOHLL 40 +#define DIF_SUBR_INET_NTOP 41 +#define DIF_SUBR_INET_NTOA 42 +#define DIF_SUBR_INET_NTOA6 43 +#define DIF_SUBR_D_PATH 44 + +#define DIF_SUBR_MAX 44 + +typedef uint32_t dif_instr_t; + +#define DIF_INSTR_OP(i) (((i) >> 24) & 0xff) +#define DIF_INSTR_R1(i) (((i) >> 16) & 0xff) +#define DIF_INSTR_R2(i) (((i) >> 8) & 0xff) +#define DIF_INSTR_RD(i) ((i) & 0xff) +#define DIF_INSTR_RS(i) ((i) & 0xff) +#define DIF_INSTR_LABEL(i) ((i) & 0xffffff) +#define DIF_INSTR_VAR(i) (((i) >> 8) & 0xffff) +#define DIF_INSTR_INTEGER(i) (((i) >> 8) & 0xffff) +#define DIF_INSTR_STRING(i) (((i) >> 8) & 0xffff) +#define DIF_INSTR_SUBR(i) (((i) >> 8) & 0xffff) +#define DIF_INSTR_TYPE(i) (((i) >> 16) & 0xff) +#define DIF_INSTR_XLREF(i) (((i) >> 8) & 0xffff) +#define DIF_INSTR_FMT(op, r1, r2, d) \ + (((op) << 24) | ((r1) << 16) | ((r2) << 8) | (d)) + +#define DIF_INSTR_NOT(r1, d) (DIF_INSTR_FMT(DIF_OP_NOT, r1, 0, d)) +#define DIF_INSTR_MOV(r1, d) (DIF_INSTR_FMT(DIF_OP_MOV, r1, 0, d)) +#define DIF_INSTR_CMP(op, r1, r2) (DIF_INSTR_FMT(op, r1, r2, 0)) +#define DIF_INSTR_TST(r1) (DIF_INSTR_FMT(DIF_OP_TST, r1, 0, 0)) +#define DIF_INSTR_BRANCH(op, label) (((op) << 24) | (label)) +#define DIF_INSTR_LOAD(op, r1, d) (DIF_INSTR_FMT(op, r1, 0, d)) +#define DIF_INSTR_STORE(op, r1, d) (DIF_INSTR_FMT(op, r1, 0, d)) +#define DIF_INSTR_SETX(i, d) ((DIF_OP_SETX << 24) | ((i) << 8) | (d)) +#define DIF_INSTR_SETS(s, d) ((DIF_OP_SETS << 24) | ((s) << 8) | (d)) +#define DIF_INSTR_RET(d) (DIF_INSTR_FMT(DIF_OP_RET, 0, 0, d)) +#define DIF_INSTR_NOP (DIF_OP_NOP << 24) +#define DIF_INSTR_LDA(op, v, r, d) (DIF_INSTR_FMT(op, v, r, d)) +#define DIF_INSTR_LDV(op, v, d) (((op) << 24) | ((v) << 8) | (d)) +#define DIF_INSTR_STV(op, v, rs) (((op) << 24) | ((v) << 8) | (rs)) +#define DIF_INSTR_CALL(s, d) ((DIF_OP_CALL << 24) | ((s) << 8) | (d)) +#define DIF_INSTR_PUSHTS(op, t, r2, rs) (DIF_INSTR_FMT(op, t, r2, rs)) +#define DIF_INSTR_POPTS (DIF_OP_POPTS << 24) +#define DIF_INSTR_FLUSHTS (DIF_OP_FLUSHTS << 24) +#define DIF_INSTR_ALLOCS(r1, d) (DIF_INSTR_FMT(DIF_OP_ALLOCS, r1, 0, d)) +#define DIF_INSTR_COPYS(r1, r2, d) (DIF_INSTR_FMT(DIF_OP_COPYS, r1, r2, d)) +#define DIF_INSTR_XLATE(op, r, d) (((op) << 24) | ((r) << 8) | (d)) + +#define DIF_REG_R0 0 + +/* + * A DTrace Intermediate Format Type (DIF Type) is used to represent the types + * of variables, function and associative array arguments, and the return type + * for each DIF object (shown below). It contains a description of the type, + * its size in bytes, and a module identifier. + */ + +#define DIF_TYPE_CTF 0 +#define DIF_TYPE_STRING 1 + +#define DIF_TF_BYREF 0x1 + +/* + * A DTrace Intermediate Format variable record is used to describe each of the + * variables referenced by a given DIF object. It contains an integer variable + * identifier along with variable scope and properties, as shown below. The + * size of this structure must be sizeof (int) aligned. + */ + +#define DIFV_KIND_ARRAY 0 +#define DIFV_KIND_SCALAR 1 + +#define DIFV_SCOPE_GLOBAL 0 +#define DIFV_SCOPE_THREAD 1 +#define DIFV_SCOPE_LOCAL 2 + +#define DIFV_F_REF 0x1 +#define DIFV_F_MOD 0x2 + +struct dtrace_diftype; +struct dtrace_difv; + +#endif /* _LINUX_DTRACE_DIF_DEFINES_H */ diff --git a/dtrace/include/uapi/linux/dtrace/difo.h b/dtrace/include/uapi/linux/dtrace/difo.h new file mode 100644 index 000000000000..10922263f8f2 --- /dev/null +++ b/dtrace/include/uapi/linux/dtrace/difo.h @@ -0,0 +1,75 @@ +#ifndef _LINUX_DTRACE_DIFO_H +#define _LINUX_DTRACE_DIFO_H + +/* + * DTrace Dynamic Tracing Software: DTrace Intermediate Format Object (DIFO) + * + * Note: The contents of this file are private to the implementation of the + * DTrace subsystem and are subject to change at any time without notice. + */ + +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + * + * Copyright 2009 -- 2013 Oracle, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include +#include +#include + +/* + * A DIFO is used to store the compiled DIF for a D expression, its return + * type, and its string and variable tables. The string table is a single + * buffer of character data into which sets instructions and variable + * references can reference strings using a byte offset. The variable table + * is an array of dtrace_difv_t structures that describe the name and type of + * each variable and the id used in the DIF code. This structure is described + * above in the DIF section of this header file. The DIFO is used at both + * user-level (in the library) and in the kernel, but the structure is never + * passed between the two: the DOF structures form the only interface. As a + * result, the definition can change depending on the presence of _KERNEL. + */ + +typedef struct dtrace_difo { + dif_instr_t *dtdo_buf; /* instruction buffer */ + uint64_t *dtdo_inttab; /* integer table (optional) */ + char *dtdo_strtab; /* string table (optional) */ + dtrace_difv_t *dtdo_vartab; /* variable table (optional) */ + uint_t dtdo_len; /* length of instruction buffer */ + uint_t dtdo_intlen; /* length of integer table */ + uint_t dtdo_strlen; /* length of string table */ + uint_t dtdo_varlen; /* length of variable table */ + dtrace_diftype_t dtdo_rtype; /* return type */ + uint_t dtdo_refcnt; /* owner reference count */ + uint_t dtdo_destructive; /* invokes destructive subroutines */ +#ifndef _KERNEL + dtrace_diftype_t orig_dtdo_rtype; /* orignal return type */ + struct dof_relodesc *dtdo_kreltab; /* kernel relocations */ + struct dof_relodesc *dtdo_ureltab; /* user relocations */ + struct dt_node **dtdo_xlmtab; /* translator references */ + uint_t dtdo_krelen; /* length of krelo table */ + uint_t dtdo_urelen; /* length of urelo table */ + uint_t dtdo_xlmlen; /* length of translator table */ +#endif +} dtrace_difo_t; + +#endif /* _LINUX_DTRACE_DIFO_H */ diff --git a/dtrace/include/uapi/linux/dtrace/difo_defines.h b/dtrace/include/uapi/linux/dtrace/difo_defines.h new file mode 100644 index 000000000000..ee5a854fd6af --- /dev/null +++ b/dtrace/include/uapi/linux/dtrace/difo_defines.h @@ -0,0 +1,39 @@ +#ifndef _LINUX_DTRACE_DIFO_DEFINES_H +#define _LINUX_DTRACE_DIFO_DEFINES_H + +/* + * DTrace Dynamic Tracing Software: DTrace Intermediate Format Object (DIFO) defines + * + * Note: The contents of this file are private to the implementation of the + * DTrace subsystem and are subject to change at any time without notice. + */ + +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + * + * Copyright 2009 -- 2013 Oracle, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include + +struct dtrace_difo; + +#endif /* _LINUX_DTRACE_DIFO_DEFINES_H */ diff --git a/dtrace/include/uapi/linux/dtrace/dof.h b/dtrace/include/uapi/linux/dtrace/dof.h new file mode 100644 index 000000000000..e6521891d90e --- /dev/null +++ b/dtrace/include/uapi/linux/dtrace/dof.h @@ -0,0 +1,214 @@ +#ifndef _LINUX_DTRACE_DOF_H +#define _LINUX_DTRACE_DOF_H + +/* + * DTrace Dynamic Tracing Software: DTrace Object Format (DOF) + * + * Note: The contents of this file are private to the implementation of the + * DTrace subsystem and are subject to change at any time without notice. + */ + +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + * + * Copyright 2009 -- 2013 Oracle, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include +#include +#include + +/* + * DTrace programs can be persistently encoded in the DOF format so that they + * may be embedded in other programs (for example, in an ELF file) or in the + * dtrace driver configuration file for use in anonymous tracing. The DOF + * format is versioned and extensible so that it can be revised and so that + * internal data structures can be modified or extended compatibly. All DOF + * structures use fixed-size types, so the 32-bit and 64-bit representations + * are identical and consumers can use either data model transparently. + * + * The file layout is structured as follows: + * + * +---------------+-------------------+----- ... ----+---- ... ------+ + * | dof_hdr_t | dof_sec_t[ ... ] | loadable | non-loadable | + * | (file header) | (section headers) | section data | section data | + * +---------------+-------------------+----- ... ----+---- ... ------+ + * |<------------ dof_hdr.dofh_loadsz --------------->| | + * |<------------ dof_hdr.dofh_filesz ------------------------------->| + * + * The file header stores meta-data including a magic number, data model for + * the instrumentation, data encoding, and properties of the DIF code within. + * The header describes its own size and the size of the section headers. By + * convention, an array of section headers follows the file header, and then + * the data for all loadable sections and unloadable sections. This permits + * consumer code to easily download the headers and all loadable data into the + * DTrace driver in one contiguous chunk, omitting other extraneous sections. + * + * The section headers describe the size, offset, alignment, and section type + * for each section. Sections are described using a set of #defines that tell + * the consumer what kind of data is expected. Sections can contain links to + * other sections by storing a dof_secidx_t, an index into the section header + * array, inside of the section data structures. The section header includes + * an entry size so that sections with data arrays can grow their structures. + * + * The DOF data itself can contain many snippets of DIF (i.e. >1 DIFOs), which + * are represented themselves as a collection of related DOF sections. This + * permits us to change the set of sections associated with a DIFO over time, + * and also permits us to encode DIFOs that contain different sets of sections. + * When a DOF section wants to refer to a DIFO, it stores the dof_secidx_t of a + * section of type DOF_SECT_DIFOHDR. This section's data is then an array of + * dof_secidx_t's which in turn denote the sections associated with this DIFO. + * + * This loose coupling of the file structure (header and sections) to the + * structure of the DTrace program itself (ECB descriptions, action + * descriptions, and DIFOs) permits activities such as relocation processing + * to occur in a single pass without having to understand D program structure. + * + * Finally, strings are always stored in ELF-style string tables along with a + * string table section index and string table offset. Therefore strings in + * DOF are always arbitrary-length and not bound to the current implementation. + */ + +typedef struct dof_hdr { + uint8_t dofh_ident[DOF_ID_SIZE]; /* identification bytes (see defines) */ + uint32_t dofh_flags; /* file attribute flags (if any) */ + uint32_t dofh_hdrsize; /* size of file header in bytes */ + uint32_t dofh_secsize; /* size of section header in bytes */ + uint32_t dofh_secnum; /* number of section headers */ + uint64_t dofh_secoff; /* file offset of section headers */ + uint64_t dofh_loadsz; /* file size of loadable portion */ + uint64_t dofh_filesz; /* file size of entire DOF file */ + uint64_t dofh_pad; /* reserved for future use */ +} dof_hdr_t; + +typedef struct dof_sec { + uint32_t dofs_type; /* section type (see defines) */ + uint32_t dofs_align; /* section data memory alignment */ + uint32_t dofs_flags; /* section flags (if any) */ + uint32_t dofs_entsize; /* size of section entry (if table) */ + uint64_t dofs_offset; /* offset of section data within file */ + uint64_t dofs_size; /* size of section data in bytes */ +} dof_sec_t; + + +typedef struct dof_ecbdesc { + dof_secidx_t dofe_probes; /* link to DOF_SECT_PROBEDESC */ + dof_secidx_t dofe_pred; /* link to DOF_SECT_DIFOHDR */ + dof_secidx_t dofe_actions; /* link to DOF_SECT_ACTDESC */ + uint32_t dofe_pad; /* reserved for future use */ + uint64_t dofe_uarg; /* user-supplied library argument */ +} dof_ecbdesc_t; + +typedef struct dof_probedesc { + dof_secidx_t dofp_strtab; /* link to DOF_SECT_STRTAB section */ + dof_stridx_t dofp_provider; /* provider string */ + dof_stridx_t dofp_mod; /* module string */ + dof_stridx_t dofp_func; /* function string */ + dof_stridx_t dofp_name; /* name string */ + uint32_t dofp_id; /* probe identifier (or zero) */ +} dof_probedesc_t; + +typedef struct dof_actdesc { + dof_secidx_t dofa_difo; /* link to DOF_SECT_DIFOHDR */ + dof_secidx_t dofa_strtab; /* link to DOF_SECT_STRTAB section */ + uint32_t dofa_kind; /* action kind (DTRACEACT_* constant) */ + uint32_t dofa_ntuple; /* number of subsequent tuple actions */ + uint64_t dofa_arg; /* kind-specific argument */ + uint64_t dofa_uarg; /* user-supplied argument */ +} dof_actdesc_t; + +typedef struct dof_difohdr { + dtrace_diftype_t dofd_rtype; /* return type for this fragment */ + dof_secidx_t dofd_links[1]; /* variable length array of indices */ +} dof_difohdr_t; + +typedef struct dof_relohdr { + dof_secidx_t dofr_strtab; /* link to DOF_SECT_STRTAB for names */ + dof_secidx_t dofr_relsec; /* link to DOF_SECT_RELTAB for relos */ + dof_secidx_t dofr_tgtsec; /* link to section we are relocating */ +} dof_relohdr_t; + +typedef struct dof_relodesc { + dof_stridx_t dofr_name; /* string name of relocation symbol */ + uint32_t dofr_type; /* relo type (DOF_RELO_* constant) */ + uint64_t dofr_offset; /* byte offset for relocation */ + uint64_t dofr_data; /* additional type-specific data */ +} dof_relodesc_t; + +typedef struct dof_optdesc { + uint32_t dofo_option; /* option identifier */ + dof_secidx_t dofo_strtab; /* string table, if string option */ + uint64_t dofo_value; /* option value or string index */ +} dof_optdesc_t; + +typedef struct dof_provider { + dof_secidx_t dofpv_strtab; /* link to DOF_SECT_STRTAB section */ + dof_secidx_t dofpv_probes; /* link to DOF_SECT_PROBES section */ + dof_secidx_t dofpv_prargs; /* link to DOF_SECT_PRARGS section */ + dof_secidx_t dofpv_proffs; /* link to DOF_SECT_PROFFS section */ + dof_stridx_t dofpv_name; /* provider name string */ + dof_attr_t dofpv_provattr; /* provider attributes */ + dof_attr_t dofpv_modattr; /* module attributes */ + dof_attr_t dofpv_funcattr; /* function attributes */ + dof_attr_t dofpv_nameattr; /* name attributes */ + dof_attr_t dofpv_argsattr; /* args attributes */ + dof_secidx_t dofpv_prenoffs; /* link to DOF_SECT_PRENOFFS section */ +} dof_provider_t; + +typedef struct dof_probe { + uint64_t dofpr_addr; /* probe base address or offset */ + dof_stridx_t dofpr_func; /* probe function string */ + dof_stridx_t dofpr_name; /* probe name string */ + dof_stridx_t dofpr_nargv; /* native argument type strings */ + dof_stridx_t dofpr_xargv; /* translated argument type strings */ + uint32_t dofpr_argidx; /* index of first argument mapping */ + uint32_t dofpr_offidx; /* index of first offset entry */ + uint8_t dofpr_nargc; /* native argument count */ + uint8_t dofpr_xargc; /* translated argument count */ + uint16_t dofpr_noffs; /* number of offset entries for probe */ + uint32_t dofpr_enoffidx; /* index of first is-enabled offset */ + uint16_t dofpr_nenoffs; /* number of is-enabled offsets */ + uint16_t dofpr_pad1; /* reserved for future use */ + uint32_t dofpr_pad2; /* reserved for future use */ +} dof_probe_t; + +typedef struct dof_xlator { + dof_secidx_t dofxl_members; /* link to DOF_SECT_XLMEMBERS section */ + dof_secidx_t dofxl_strtab; /* link to DOF_SECT_STRTAB section */ + dof_stridx_t dofxl_argv; /* input parameter type strings */ + uint32_t dofxl_argc; /* input parameter list length */ + dof_stridx_t dofxl_type; /* output type string name */ + dof_attr_t dofxl_attr; /* output stability attributes */ +} dof_xlator_t; + +typedef struct dof_xlmember { + dof_secidx_t dofxm_difo; /* member link to DOF_SECT_DIFOHDR */ + dof_stridx_t dofxm_name; /* member name */ + dtrace_diftype_t dofxm_type; /* member type */ +} dof_xlmember_t; + +typedef struct dof_xlref { + dof_secidx_t dofxr_xlator; /* link to DOF_SECT_XLATORS section */ + uint32_t dofxr_member; /* index of referenced dof_xlmember */ + uint32_t dofxr_argn; /* index of argument for DIF_OP_XLARG */ +} dof_xlref_t; + +#endif /* _LINUX_DTRACE_DOF_H */ diff --git a/dtrace/include/uapi/linux/dtrace/dof_defines.h b/dtrace/include/uapi/linux/dtrace/dof_defines.h new file mode 100644 index 000000000000..68d7e69f7dc7 --- /dev/null +++ b/dtrace/include/uapi/linux/dtrace/dof_defines.h @@ -0,0 +1,210 @@ +#ifndef _LINUX_DTRACE_DOF_DEFINES_H +#define _LINUX_DTRACE_DOF_DEFINES_H + +/* + * DTrace Dynamic Tracing Software: DTrace Object Format (DOF) defines + * + * Note: The contents of this file are private to the implementation of the + * DTrace subsystem and are subject to change at any time without notice. + */ + +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + * + * Copyright 2009 -- 2013 Oracle, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include + +/* + * DTrace programs can be persistently encoded in the DOF format so that they + * may be embedded in other programs (for example, in an ELF file) or in the + * dtrace driver configuration file for use in anonymous tracing. The DOF + * format is versioned and extensible so that it can be revised and so that + * internal data structures can be modified or extended compatibly. All DOF + * structures use fixed-size types, so the 32-bit and 64-bit representations + * are identical and consumers can use either data model transparently. + * + * The file layout is structured as follows: + * + * +---------------+-------------------+----- ... ----+---- ... ------+ + * | dof_hdr_t | dof_sec_t[ ... ] | loadable | non-loadable | + * | (file header) | (section headers) | section data | section data | + * +---------------+-------------------+----- ... ----+---- ... ------+ + * |<------------ dof_hdr.dofh_loadsz --------------->| | + * |<------------ dof_hdr.dofh_filesz ------------------------------->| + * + * The file header stores meta-data including a magic number, data model for + * the instrumentation, data encoding, and properties of the DIF code within. + * The header describes its own size and the size of the section headers. By + * convention, an array of section headers follows the file header, and then + * the data for all loadable sections and unloadable sections. This permits + * consumer code to easily download the headers and all loadable data into the + * DTrace driver in one contiguous chunk, omitting other extraneous sections. + * + * The section headers describe the size, offset, alignment, and section type + * for each section. Sections are described using a set of #defines that tell + * the consumer what kind of data is expected. Sections can contain links to + * other sections by storing a dof_secidx_t, an index into the section header + * array, inside of the section data structures. The section header includes + * an entry size so that sections with data arrays can grow their structures. + * + * The DOF data itself can contain many snippets of DIF (i.e. >1 DIFOs), which + * are represented themselves as a collection of related DOF sections. This + * permits us to change the set of sections associated with a DIFO over time, + * and also permits us to encode DIFOs that contain different sets of sections. + * When a DOF section wants to refer to a DIFO, it stores the dof_secidx_t of a + * section of type DOF_SECT_DIFOHDR. This section's data is then an array of + * dof_secidx_t's which in turn denote the sections associated with this DIFO. + * + * This loose coupling of the file structure (header and sections) to the + * structure of the DTrace program itself (ECB descriptions, action + * descriptions, and DIFOs) permits activities such as relocation processing + * to occur in a single pass without having to understand D program structure. + * + * Finally, strings are always stored in ELF-style string tables along with a + * string table section index and string table offset. Therefore strings in + * DOF are always arbitrary-length and not bound to the current implementation. + */ + +#define DOF_ID_SIZE 16 /* total size of dofh_ident[] in bytes */ + +#define DOF_ID_MAG0 0 +#define DOF_ID_MAG1 1 +#define DOF_ID_MAG2 2 +#define DOF_ID_MAG3 3 +#define DOF_ID_MODEL 4 +#define DOF_ID_ENCODING 5 +#define DOF_ID_VERSION 6 +#define DOF_ID_DIFVERS 7 +#define DOF_ID_DIFIREG 8 /* DIF integer registers used by compiler */ +#define DOF_ID_DIFTREG 9 /* DIF tuple registers used by compiler */ +#define DOF_ID_PAD 10 /* start of padding bytes (all zeroes) */ + +#define DOF_MAG_MAG0 0x7F /* DOF_ID_MAG[0-3] */ +#define DOF_MAG_MAG1 'D' +#define DOF_MAG_MAG2 'O' +#define DOF_MAG_MAG3 'F' + +#define DOF_MAG_STRING "\177DOF" +#define DOF_MAG_STRLEN 4 + +#define DOF_MODEL_NONE 0 /* DOF_ID_MODEL */ +#define DOF_MODEL_ILP32 1 +#define DOF_MODEL_LP64 2 + +#ifdef _LP64 +#define DOF_MODEL_NATIVE DOF_MODEL_LP64 +#else +#define DOF_MODEL_NATIVE DOF_MODEL_ILP32 +#endif + +#define DOF_ENCODE_NONE 0 /* DOF_ID_ENCODING */ +#define DOF_ENCODE_LSB 1 +#define DOF_ENCODE_MSB 2 + +#ifndef _LITTLE_ENDIAN +#define DOF_ENCODE_NATIVE DOF_ENCODE_MSB +#else +#define DOF_ENCODE_NATIVE DOF_ENCODE_LSB +#endif + +#define DOF_VERSION_1 1 +#define DOF_VERSION_2 2 +#define DOF_VERSION DOF_VERSION_2 + +#define DOF_FL_VALID 0 /* mask of all valid dofh_flags bits */ + +typedef uint32_t dof_secidx_t; /* section header table index type */ +typedef uint32_t dof_stridx_t; /* string table index type */ + +#define DOF_SECIDX_NONE -1U /* null value for section indices */ +#define DOF_STRIDX_NONE -1U /* null value for string indices */ + +#define DOF_SECT_NONE 0 /* null section */ +#define DOF_SECT_COMMENTS 1 /* compiler comments */ +#define DOF_SECT_SOURCE 2 /* D program source code */ +#define DOF_SECT_ECBDESC 3 /* dof_ecbdesc_t */ +#define DOF_SECT_PROBEDESC 4 /* dof_probedesc_t */ +#define DOF_SECT_ACTDESC 5 /* dof_actdesc_t array */ +#define DOF_SECT_DIFOHDR 6 /* dof_difohdr_t (variable length) */ +#define DOF_SECT_DIF 7 /* uint32_t array of byte code */ +#define DOF_SECT_STRTAB 8 /* string table */ +#define DOF_SECT_VARTAB 9 /* dtrace_difv_t array */ +#define DOF_SECT_RELTAB 10 /* dof_relodesc_t array */ +#define DOF_SECT_TYPTAB 11 /* dtrace_diftype_t array */ +#define DOF_SECT_URELHDR 12 /* dof_relohdr_t (user relocations) */ +#define DOF_SECT_KRELHDR 13 /* dof_relohdr_t (kernel relocations) */ +#define DOF_SECT_OPTDESC 14 /* dof_optdesc_t array */ +#define DOF_SECT_PROVIDER 15 /* dof_provider_t */ +#define DOF_SECT_PROBES 16 /* dof_probe_t array */ +#define DOF_SECT_PRARGS 17 /* uint8_t array (probe arg mappings) */ +#define DOF_SECT_PROFFS 18 /* uint32_t array (probe arg offsets) */ +#define DOF_SECT_INTTAB 19 /* uint64_t array */ +#define DOF_SECT_UTSNAME 20 /* struct utsname */ +#define DOF_SECT_XLTAB 21 /* dof_xlref_t array */ +#define DOF_SECT_XLMEMBERS 22 /* dof_xlmember_t array */ +#define DOF_SECT_XLIMPORT 23 /* dof_xlator_t */ +#define DOF_SECT_XLEXPORT 24 /* dof_xlator_t */ +#define DOF_SECT_PREXPORT 25 /* dof_secidx_t array (exported objs) */ +#define DOF_SECT_PRENOFFS 26 /* uint32_t array (enabled offsets) */ + +#define DOF_SECF_LOAD 1 /* section should be loaded */ + +#define DOF_SEC_ISLOADABLE(x) \ + (((x) == DOF_SECT_ECBDESC) || ((x) == DOF_SECT_PROBEDESC) || \ + ((x) == DOF_SECT_ACTDESC) || ((x) == DOF_SECT_DIFOHDR) || \ + ((x) == DOF_SECT_DIF) || ((x) == DOF_SECT_STRTAB) || \ + ((x) == DOF_SECT_VARTAB) || ((x) == DOF_SECT_RELTAB) || \ + ((x) == DOF_SECT_TYPTAB) || ((x) == DOF_SECT_URELHDR) || \ + ((x) == DOF_SECT_KRELHDR) || ((x) == DOF_SECT_OPTDESC) || \ + ((x) == DOF_SECT_PROVIDER) || ((x) == DOF_SECT_PROBES) || \ + ((x) == DOF_SECT_PRARGS) || ((x) == DOF_SECT_PROFFS) || \ + ((x) == DOF_SECT_INTTAB) || ((x) == DOF_SECT_XLTAB) || \ + ((x) == DOF_SECT_XLMEMBERS) || ((x) == DOF_SECT_XLIMPORT) || \ + ((x) == DOF_SECT_XLIMPORT) || ((x) == DOF_SECT_XLEXPORT) || \ + ((x) == DOF_SECT_PREXPORT) || ((x) == DOF_SECT_PRENOFFS)) + +#define DOF_RELO_NONE 0 /* empty relocation entry */ +#define DOF_RELO_SETX 1 /* relocate setx value */ + +typedef uint32_t dof_attr_t; /* encoded stability attributes */ + +#define DOF_ATTR(n, d, c) (((n) << 24) | ((d) << 16) | ((c) << 8)) +#define DOF_ATTR_NAME(a) (((a) >> 24) & 0xff) +#define DOF_ATTR_DATA(a) (((a) >> 16) & 0xff) +#define DOF_ATTR_CLASS(a) (((a) >> 8) & 0xff) + +struct dof_hdr; +struct dof_sec; +struct dof_ecbdesc; +struct dof_probedesc; +struct dof_actdesc; +struct dof_difohdr; +struct dof_relohdr; +struct dof_relodesc; +struct dof_optdesc; +struct dof_provider; +struct dof_xlator; +struct dof_xlmember; +struct dof_xlref; + +#endif /* _LINUX_DTRACE_DOF_DEFINES_H */ diff --git a/dtrace/include/uapi/linux/dtrace/dtrace.h b/dtrace/include/uapi/linux/dtrace/dtrace.h new file mode 100644 index 000000000000..6f30bc429764 --- /dev/null +++ b/dtrace/include/uapi/linux/dtrace/dtrace.h @@ -0,0 +1,59 @@ +#ifndef _LINUX_DTRACE_H_ +#define _LINUX_DTRACE_H_ + +/* + * DTrace Dynamic Tracing Software: Kernel Interfaces + * + * Note: The contents of this file are private to the implementation of the + * DTrace subsystem and are subject to change at any time without notice. + */ + +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + * + * Copyright 2009 -- 2013 Oracle, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +} +#endif + +#endif /* _LINUX_DTRACE_H_ */ diff --git a/dtrace/include/uapi/linux/dtrace/enabling.h b/dtrace/include/uapi/linux/dtrace/enabling.h new file mode 100644 index 000000000000..44c00688409c --- /dev/null +++ b/dtrace/include/uapi/linux/dtrace/enabling.h @@ -0,0 +1,94 @@ +#ifndef _LINUX_DTRACE_ENABLING_H +#define _LINUX_DTRACE_ENABLING_H + +/* + * DTrace Dynamic Tracing Software: DTrace Enabling Description Structures + * + * Note: The contents of this file are private to the implementation of the + * DTrace subsystem and are subject to change at any time without notice. + */ + +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + * + * Copyright 2009 -- 2013 Oracle, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include +#include +#include + +/* + * When DTrace is tracking the description of a DTrace enabling entity (probe, + * predicate, action, ECB, record, etc.), it does so in a description + * structure. These structures all end in "desc", and are used at both + * user-level and in the kernel -- but (with the exception of + * dtrace_probedesc_t) they are never passed between them. Typically, + * user-level will use the description structures when assembling an enabling. + * It will then distill those description structures into a DOF object (see + * above), and send it into the kernel. The kernel will again use the + * description structures to create a description of the enabling as it reads + * the DOF. When the description is complete, the enabling will be actually + * created -- turning it into the structures that represent the enabling + * instead of merely describing it. Not surprisingly, the description + * structures bear a strong resemblance to the DOF structures that act as their + * conduit. + */ + +struct dtrace_predicate; + +typedef struct dtrace_probedesc { + dtrace_id_t dtpd_id; /* probe identifier */ + char dtpd_provider[DTRACE_PROVNAMELEN]; /* probe provider name */ + char dtpd_mod[DTRACE_MODNAMELEN]; /* probe module name */ + char dtpd_func[DTRACE_FUNCNAMELEN]; /* probe function name */ + char dtpd_name[DTRACE_NAMELEN]; /* probe name */ +} dtrace_probedesc_t; + +typedef struct dtrace_repldesc { + dtrace_probedesc_t dtrpd_match; /* probe descr. to match */ + dtrace_probedesc_t dtrpd_create; /* probe descr. to create */ +} dtrace_repldesc_t; + +typedef struct dtrace_preddesc { + struct dtrace_difo *dtpdd_difo; /* pointer to DIF object */ + struct dtrace_predicate *dtpdd_predicate; /* pointer to predicate */ +} dtrace_preddesc_t; + +typedef struct dtrace_actdesc { + struct dtrace_difo *dtad_difo; /* pointer to DIF object */ + struct dtrace_actdesc *dtad_next; /* next action */ + dtrace_actkind_t dtad_kind; /* kind of action */ + uint32_t dtad_ntuple; /* number in tuple */ + uint64_t dtad_arg; /* action argument */ + uint64_t dtad_uarg; /* user argument */ + int dtad_refcnt; /* reference count */ +} dtrace_actdesc_t; + +typedef struct dtrace_ecbdesc { + dtrace_actdesc_t *dted_action; /* action description(s) */ + dtrace_preddesc_t dted_pred; /* predicate description */ + dtrace_probedesc_t dted_probe; /* probe description */ + uint64_t dted_uarg; /* library argument */ + int dted_refcnt; /* reference count */ +} dtrace_ecbdesc_t; + +#endif /* _LINUX_DTRACE_ENABLING_H */ diff --git a/dtrace/include/uapi/linux/dtrace/enabling_defines.h b/dtrace/include/uapi/linux/dtrace/enabling_defines.h new file mode 100644 index 000000000000..68824148421f --- /dev/null +++ b/dtrace/include/uapi/linux/dtrace/enabling_defines.h @@ -0,0 +1,43 @@ +#ifndef _LINUX_DTRACE_ENABLING_DEFINES_H +#define _LINUX_DTRACE_ENABLING_DEFINES_H + +/* + * DTrace Dynamic Tracing Software: DTrace Enabling Description Structures + * + * Note: The contents of this file are private to the implementation of the + * DTrace subsystem and are subject to change at any time without notice. + */ + +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + * + * Copyright 2009 -- 2013 Oracle, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include + +struct dtrace_probedesc; +struct dtrace_repldesc; +struct dtrace_preddesc; +struct dtrace_actdesc; +struct dtrace_ecbdesc; + +#endif /* _LINUX_DTRACE_ENABLING_DEFINES_H */ diff --git a/dtrace/include/uapi/linux/dtrace/faults.h b/dtrace/include/uapi/linux/dtrace/faults.h new file mode 100644 index 000000000000..abcbe8ed023a --- /dev/null +++ b/dtrace/include/uapi/linux/dtrace/faults.h @@ -0,0 +1,38 @@ +#ifndef _LINUX_DTRACE_FAULTS_H +#define _LINUX_DTRACE_FAULTS_H + +/* + * DTrace Dynamic Tracing Software: DTrace Faults + * + * Note: The contents of this file are private to the implementation of the + * DTrace subsystem and are subject to change at any time without notice. + */ + +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + * + * Copyright 2009 -- 2013 Oracle, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include +#include + +#endif /* _LINUX_DTRACE_FAULTS_H */ diff --git a/dtrace/include/uapi/linux/dtrace/faults_defines.h b/dtrace/include/uapi/linux/dtrace/faults_defines.h new file mode 100644 index 000000000000..4531ced2aeb3 --- /dev/null +++ b/dtrace/include/uapi/linux/dtrace/faults_defines.h @@ -0,0 +1,57 @@ +#ifndef _LINUX_DTRACE_FAULTS_DEFINES_H +#define _LINUX_DTRACE_FAULTS_DEFINES_H + +/* + * DTrace Dynamic Tracing Software: DTrace Faults + * + * Note: The contents of this file are private to the implementation of the + * DTrace subsystem and are subject to change at any time without notice. + */ + +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + * + * Copyright 2009 -- 2013 Oracle, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include + +/* + * The constants below DTRACEFLT_LIBRARY indicate probe processing faults; + * constants at or above DTRACEFLT_LIBRARY indicate faults in probe + * postprocessing at user-level. Probe processing faults induce an ERROR + * probe and are replicated in unistd.d to allow users' ERROR probes to decode + * the error condition using thse symbolic labels. + */ +#define DTRACEFLT_UNKNOWN 0 /* Unknown fault */ +#define DTRACEFLT_BADADDR 1 /* Bad address */ +#define DTRACEFLT_BADALIGN 2 /* Bad alignment */ +#define DTRACEFLT_ILLOP 3 /* Illegal operation */ +#define DTRACEFLT_DIVZERO 4 /* Divide-by-zero */ +#define DTRACEFLT_NOSCRATCH 5 /* Out of scratch space */ +#define DTRACEFLT_KPRIV 6 /* Illegal kernel access */ +#define DTRACEFLT_UPRIV 7 /* Illegal user access */ +#define DTRACEFLT_TUPOFLOW 8 /* Tuple stack overflow */ +#define DTRACEFLT_BADSTACK 9 /* Bad stack */ + +#define DTRACEFLT_LIBRARY 1000 /* Library-level fault */ + +#endif /* _LINUX_DTRACE_FAULTS_DEFINES_H */ diff --git a/dtrace/include/uapi/linux/dtrace/helpers.h b/dtrace/include/uapi/linux/dtrace/helpers.h new file mode 100644 index 000000000000..5e61b6f8f494 --- /dev/null +++ b/dtrace/include/uapi/linux/dtrace/helpers.h @@ -0,0 +1,119 @@ +#ifndef _LINUX_DTRACE_HELPERS_H +#define _LINUX_DTRACE_HELPERS_H + +/* + * DTrace Dynamic Tracing Software: DTrace Helpers + * + * Note: The contents of this file are private to the implementation of the + * DTrace subsystem and are subject to change at any time without notice. + */ + +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + * + * Copyright 2009 -- 2013 Oracle, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include +#include + +/* + * DTrace Helpers + * + * In general, DTrace establishes probes in processes and takes actions on + * processes without knowing their specific user-level structures. Instead of + * existing in the framework, process-specific knowledge is contained by the + * enabling D program -- which can apply process-specific knowledge by making + * appropriate use of DTrace primitives like copyin() and copyinstr() to + * operate on user-level data. However, there may exist some specific probes + * of particular semantic relevance that the application developer may wish to + * explicitly export. For example, an application may wish to export a probe + * at the point that it begins and ends certain well-defined transactions. In + * addition to providing probes, programs may wish to offer assistance for + * certain actions. For example, in highly dynamic environments (e.g., Java), + * it may be difficult to obtain a stack trace in terms of meaningful symbol + * names (the translation from instruction addresses to corresponding symbol + * names may only be possible in situ); these environments may wish to define + * a series of actions to be applied in situ to obtain a meaningful stack + * trace. + * + * These two mechanisms -- user-level statically defined tracing and assisting + * DTrace actions -- are provided via DTrace _helpers_. Helpers are specified + * via DOF, but unlike enabling DOF, helper DOF may contain definitions of + * providers, probes and their arguments. If a helper wishes to provide + * action assistance, probe descriptions and corresponding DIF actions may be + * specified in the helper DOF. For such helper actions, however, the probe + * description describes the specific helper: all DTrace helpers have the + * provider name "dtrace" and the module name "helper", and the name of the + * helper is contained in the function name (for example, the ustack() helper + * is named "ustack"). Any helper-specific name may be contained in the name + * (for example, if a helper were to have a constructor, it might be named + * "dtrace:helper::init"). Helper actions are only called when the + * action that they are helping is taken. Helper actions may only return DIF + * expressions, and may only call the following subroutines: + * + * alloca() <= Allocates memory out of the consumer's scratch space + * bcopy() <= Copies memory to scratch space + * copyin() <= Copies memory from user-level into consumer's scratch + * copyinto() <= Copies memory into a specific location in scratch + * copyinstr() <= Copies a string into a specific location in scratch + * + * Helper actions may only access the following built-in variables: + * + * curthread <= Current kthread_t pointer + * tid <= Current thread identifier + * pid <= Current process identifier + * ppid <= Parent process identifier + * uid <= Current user ID + * gid <= Current group ID + * execname <= Current executable name + * zonename <= Current zone name + * + * Helper actions may not manipulate or allocate dynamic variables, but they + * may have clause-local and statically-allocated global variables. The + * helper action variable state is specific to the helper action -- variables + * used by the helper action may not be accessed outside of the helper + * action, and the helper action may not access variables that like outside + * of it. Helper actions may not load from kernel memory at-large; they are + * restricting to loading current user state (via copyin() and variants) and + * scratch space. As with probe enablings, helper actions are executed in + * program order. The result of the helper action is the result of the last + * executing helper expression. + * + * Helpers -- composed of either providers/probes or probes/actions (or both) + * -- are added by opening the "helper" minor node, and issuing an ioctl(2) + * (DTRACEHIOC_ADDDOF) that specifies the dof_helper_t structure. This + * encapsulates the name and base address of the user-level library or + * executable publishing the helpers and probes as well as the DOF that + * contains the definitions of those helpers and probes. + * + * The DTRACEHIOC_ADD and DTRACEHIOC_REMOVE are left in place for legacy + * helpers and should no longer be used. No other ioctls are valid on the + * helper minor node. + */ + +typedef struct dof_helper { + char dofhp_mod[DTRACE_MODNAMELEN]; /* executable or library name */ + uint64_t dofhp_addr; /* base address of object */ + uint64_t dofhp_dof; /* address of helper DOF */ +} dof_helper_t; + +#endif /* _LINUX_DTRACE_HELPERS_H */ diff --git a/dtrace/include/uapi/linux/dtrace/helpers_defines.h b/dtrace/include/uapi/linux/dtrace/helpers_defines.h new file mode 100644 index 000000000000..e8c4aa29d405 --- /dev/null +++ b/dtrace/include/uapi/linux/dtrace/helpers_defines.h @@ -0,0 +1,39 @@ +#ifndef _LINUX_DTRACE_HELPERS_DEFINES_H +#define _LINUX_DTRACE_HELPERS_DEFINES_H + +/* + * DTrace Dynamic Tracing Software: DTrace Helpers defines + * + * Note: The contents of this file are private to the implementation of the + * DTrace subsystem and are subject to change at any time without notice. + */ + +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + * + * Copyright 2009 -- 2013 Oracle, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include + +struct dof_helper; + +#endif /* _LINUX_DTRACE_HELPERS_DEFINES_H */ diff --git a/dtrace/include/uapi/linux/dtrace/ioctl.h b/dtrace/include/uapi/linux/dtrace/ioctl.h new file mode 100644 index 000000000000..8c8bfd1a0dfc --- /dev/null +++ b/dtrace/include/uapi/linux/dtrace/ioctl.h @@ -0,0 +1,90 @@ +/* Copyright (C) 2011, 2012, 2013 Oracle, Inc. */ + +#ifndef _LINUX_DTRACE_IOCTL_H_ +#define _LINUX_DTRACE_IOCTL_H_ + +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + * + * Copyright 2009 -- 2013 Oracle, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DTRACEIOC 0xd4 +#define DTRACEIOC_PROVIDER _IOR(DTRACEIOC, 1, dtrace_providerdesc_t) +#define DTRACEIOC_PROBES _IOR(DTRACEIOC, 2, dtrace_probedesc_t) +#define DTRACEIOC_BUFSNAP _IOR(DTRACEIOC, 4, dtrace_bufdesc_t) +#define DTRACEIOC_PROBEMATCH _IOR(DTRACEIOC, 5, dtrace_probedesc_t) +#define DTRACEIOC_ENABLE _IOW(DTRACEIOC, 6, void *) +#define DTRACEIOC_AGGSNAP _IOR(DTRACEIOC, 7, dtrace_bufdesc_t) +#define DTRACEIOC_EPROBE _IOW(DTRACEIOC, 8, dtrace_eprobedesc_t) +#define DTRACEIOC_PROBEARG _IOR(DTRACEIOC, 9, dtrace_argdesc_t) +#define DTRACEIOC_CONF _IOR(DTRACEIOC, 10, dtrace_conf_t) +#define DTRACEIOC_STATUS _IOR(DTRACEIOC, 11, dtrace_status_t) +#define DTRACEIOC_GO _IOW(DTRACEIOC, 12, processorid_t) +#define DTRACEIOC_STOP _IOW(DTRACEIOC, 13, processorid_t) +#define DTRACEIOC_AGGDESC _IOR(DTRACEIOC, 15, dtrace_aggdesc_t) +#define DTRACEIOC_FORMAT _IOR(DTRACEIOC, 16, dtrace_fmtdesc_t) +#define DTRACEIOC_DOFGET _IOR(DTRACEIOC, 17, dof_hdr_t) +#define DTRACEIOC_REPLICATE _IOR(DTRACEIOC, 18, void *) + +#define DTRACEHIOC 0xd8 +#define DTRACEHIOC_ADD _IOW(DTRACEHIOC, 1, dof_hdr_t) +#define DTRACEHIOC_REMOVE _IOW(DTRACEHIOC, 2, int) +#define DTRACEHIOC_ADDDOF _IOW(DTRACEHIOC, 3, dof_helper_t) + +/* + * This file can be #included by DTrace itself, which cannot parse C functions. + */ +#ifndef __SUNW_D + +void dtrace_size_dbg_print(const char *type, size_t size); + +static void dtrace_ioctl_sizes(void) { +#define DBG_PRINT(x) dtrace_size_dbg_print(#x, sizeof(x)) + DBG_PRINT(dtrace_providerdesc_t); + DBG_PRINT(dtrace_probedesc_t); + DBG_PRINT(dtrace_bufdesc_t); + DBG_PRINT(dtrace_eprobedesc_t); + DBG_PRINT(dtrace_argdesc_t); + DBG_PRINT(dtrace_conf_t); + DBG_PRINT(dtrace_status_t); + DBG_PRINT(processorid_t); + DBG_PRINT(dtrace_aggdesc_t); + DBG_PRINT(dtrace_fmtdesc_t); + DBG_PRINT(dof_hdr_t); +#undef DBG_PRINT +} + +#endif + +#endif /* _LINUX_DTRACE_IOCTL_H */ diff --git a/dtrace/include/uapi/linux/dtrace/metadesc.h b/dtrace/include/uapi/linux/dtrace/metadesc.h new file mode 100644 index 000000000000..ce09f865afac --- /dev/null +++ b/dtrace/include/uapi/linux/dtrace/metadesc.h @@ -0,0 +1,99 @@ +#ifndef _LINUX_DTRACE_METADESC_H +#define _LINUX_DTRACE_METADESC_H + +/* + * DTrace Dynamic Tracing Software: DTrace Metadata Description Structures + * + * Note: The contents of this file are private to the implementation of the + * DTrace subsystem and are subject to change at any time without notice. + */ + +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + * + * Copyright 2009 -- 2013 Oracle, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include +#include +#include + +/* + * DTrace separates the trace data stream from the metadata stream. The only + * metadata tokens placed in the data stream are enabled probe identifiers + * (EPIDs) or (in the case of aggregations) aggregation identifiers. In order + * to determine the structure of the data, DTrace consumers pass the token to + * the kernel, and receive in return a corresponding description of the enabled + * probe (via the dtrace_eprobedesc structure) or the aggregation (via the + * dtrace_aggdesc structure). Both of these structures are expressed in terms + * of record descriptions (via the dtrace_recdesc structure) that describe the + * exact structure of the data. Some record descriptions may also contain a + * format identifier; this additional bit of metadata can be retrieved from the + * kernel, for which a format description is returned via the dtrace_fmtdesc + * structure. Note that all four of these structures must be bitness-neutral + * to allow for a 32-bit DTrace consumer on a 64-bit kernel. + */ +typedef struct dtrace_recdesc { + dtrace_actkind_t dtrd_action; /* kind of action */ + uint32_t dtrd_size; /* size of record */ + uint32_t dtrd_offset; /* offset in ECB's data */ + uint16_t dtrd_alignment; /* required alignment */ + uint16_t dtrd_format; /* format, if any */ + uint64_t dtrd_arg; /* action argument */ + uint64_t dtrd_uarg; /* user argument */ +} dtrace_recdesc_t; + +typedef struct dtrace_eprobedesc { + dtrace_epid_t dtepd_epid; /* enabled probe ID */ + dtrace_id_t dtepd_probeid; /* probe ID */ + uint64_t dtepd_uarg; /* library argument */ + uint32_t dtepd_size; /* total size */ + int dtepd_nrecs; /* number of records */ + dtrace_recdesc_t dtepd_rec[1]; /* recods themselves */ +} dtrace_eprobedesc_t; + +typedef struct dtrace_aggdesc { + DTRACE_PTR(char, dtagd_name); /* not filled in by kernel */ + dtrace_aggvarid_t dtagd_varid; /* not filled in by kernel */ + int dtagd_flags; /* not filled in by kernel */ + dtrace_aggid_t dtagd_id; /* aggregation ID */ + dtrace_epid_t dtagd_epid; /* enabled probe ID */ + uint32_t dtagd_size; /* size in bytes */ + int dtagd_nrecs; /* number of records */ + uint32_t dtagd_pad; /* explicit padding */ + dtrace_recdesc_t dtagd_rec[1]; /* record descriptions */ +} dtrace_aggdesc_t; + +typedef struct dtrace_fmtdesc { + DTRACE_PTR(char, dtfd_string); /* format string */ + int dtfd_length; /* length of format string */ + uint16_t dtfd_format; /* format identifier */ +} dtrace_fmtdesc_t; + +#define DTRACE_SIZEOF_EPROBEDESC(desc) \ + (sizeof (dtrace_eprobedesc_t) + ((desc)->dtepd_nrecs ? \ + (((desc)->dtepd_nrecs - 1) * sizeof (dtrace_recdesc_t)) : 0)) + +#define DTRACE_SIZEOF_AGGDESC(desc) \ + (sizeof (dtrace_aggdesc_t) + ((desc)->dtagd_nrecs ? \ + (((desc)->dtagd_nrecs - 1) * sizeof (dtrace_recdesc_t)) : 0)) + +#endif /* _LINUX_DTRACE_METADESC_H */ diff --git a/dtrace/include/uapi/linux/dtrace/metadesc_defines.h b/dtrace/include/uapi/linux/dtrace/metadesc_defines.h new file mode 100644 index 000000000000..16cb16fe0860 --- /dev/null +++ b/dtrace/include/uapi/linux/dtrace/metadesc_defines.h @@ -0,0 +1,42 @@ +#ifndef _LINUX_DTRACE_METADESC_DEFINES_H +#define _LINUX_DTRACE_METADESC_DEFINES_H + +/* + * DTrace Dynamic Tracing Software: DTrace Metadata Description Structures defines + * + * Note: The contents of this file are private to the implementation of the + * DTrace subsystem and are subject to change at any time without notice. + */ + +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + * + * Copyright 2009 -- 2013 Oracle, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include + +struct dtrace_recdesc; +struct dtrace_eprobedesc; +struct dtrace_aggdesc; +struct dtrace_fmtdesc; + +#endif /* _LINUX_DTRACE_METADESC_DEFINES_H */ diff --git a/dtrace/include/uapi/linux/dtrace/options.h b/dtrace/include/uapi/linux/dtrace/options.h new file mode 100644 index 000000000000..ef3bf0a2048d --- /dev/null +++ b/dtrace/include/uapi/linux/dtrace/options.h @@ -0,0 +1,38 @@ +#ifndef _LINUX_DTRACE_OPTIONS_H +#define _LINUX_DTRACE_OPTIONS_H + +/* + * DTrace Dynamic Tracing Software: DTrace Option Interface + * + * Note: The contents of this file are private to the implementation of the + * DTrace subsystem and are subject to change at any time without notice. + */ + +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + * + * Copyright 2009 -- 2013 Oracle, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include +#include + +#endif /* _LINUX_DTRACE_OPTIONS_H */ diff --git a/dtrace/include/uapi/linux/dtrace/options_defines.h b/dtrace/include/uapi/linux/dtrace/options_defines.h new file mode 100644 index 000000000000..c6c4cd13245a --- /dev/null +++ b/dtrace/include/uapi/linux/dtrace/options_defines.h @@ -0,0 +1,88 @@ +#ifndef _LINUX_DTRACE_OPTIONS_DEFINES_H +#define _LINUX_DTRACE_OPTIONS_DEFINES_H + +/* + * DTrace Dynamic Tracing Software: DTrace Option Interface defines + * + * Note: The contents of this file are private to the implementation of the + * DTrace subsystem and are subject to change at any time without notice. + */ + +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + * + * Copyright 2009 -- 2013 Oracle, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include + +/* + * Run-time DTrace options are set and retrieved via DOF_SECT_OPTDESC sections + * in a DOF image. The dof_optdesc structure contains an option identifier and + * an option value. The valid option identifiers are found below; the mapping + * between option identifiers and option identifying strings is maintained at + * user-level. Note that the value of DTRACEOPT_UNSET is such that all of the + * following are potentially valid option values: all positive integers, zero + * and negative one. Some options (notably "bufpolicy" and "bufresize") take + * predefined tokens as their values; these are defined with + * DTRACEOPT_{option}_{token}. + */ + +#define DTRACEOPT_BUFSIZE 0 /* buffer size */ +#define DTRACEOPT_BUFPOLICY 1 /* buffer policy */ +#define DTRACEOPT_DYNVARSIZE 2 /* dynamic variable size */ +#define DTRACEOPT_AGGSIZE 3 /* aggregation size */ +#define DTRACEOPT_SPECSIZE 4 /* speculation size */ +#define DTRACEOPT_NSPEC 5 /* number of speculations */ +#define DTRACEOPT_STRSIZE 6 /* string size */ +#define DTRACEOPT_CLEANRATE 7 /* dynvar cleaning rate */ +#define DTRACEOPT_CPU 8 /* CPU to trace */ +#define DTRACEOPT_BUFRESIZE 9 /* buffer resizing policy */ +#define DTRACEOPT_GRABANON 10 /* grab anonymous state, if any */ +#define DTRACEOPT_FLOWINDENT 11 /* indent function entry/return */ +#define DTRACEOPT_QUIET 12 /* only output explicitly traced data */ +#define DTRACEOPT_STACKFRAMES 13 /* number of stack frames */ +#define DTRACEOPT_USTACKFRAMES 14 /* number of user stack frames */ +#define DTRACEOPT_AGGRATE 15 /* aggregation snapshot rate */ +#define DTRACEOPT_SWITCHRATE 16 /* buffer switching rate */ +#define DTRACEOPT_STATUSRATE 17 /* status rate */ +#define DTRACEOPT_DESTRUCTIVE 18 /* destructive actions allowed */ +#define DTRACEOPT_STACKINDENT 19 /* output indent for stack traces */ +#define DTRACEOPT_RAWBYTES 20 /* always print bytes in raw form */ +#define DTRACEOPT_JSTACKFRAMES 21 /* number of jstack() frames */ +#define DTRACEOPT_JSTACKSTRSIZE 22 /* size of jstack() string table */ +#define DTRACEOPT_AGGSORTKEY 23 /* sort aggregations by key */ +#define DTRACEOPT_AGGSORTREV 24 /* reverse-sort aggregations */ +#define DTRACEOPT_AGGSORTPOS 25 /* agg. position to sort on */ +#define DTRACEOPT_AGGSORTKEYPOS 26 /* agg. key position to sort on */ +#define DTRACEOPT_QUIETRESIZE 27 /* quieten buffer-resize messages */ +#define DTRACEOPT_MAX 28 /* number of options */ + +#define DTRACEOPT_UNSET (dtrace_optval_t)-2 /* unset option */ + +#define DTRACEOPT_BUFPOLICY_RING 0 /* ring buffer */ +#define DTRACEOPT_BUFPOLICY_FILL 1 /* fill buffer, then stop */ +#define DTRACEOPT_BUFPOLICY_SWITCH 2 /* switch buffers */ + +#define DTRACEOPT_BUFRESIZE_AUTO 0 /* automatic resizing */ +#define DTRACEOPT_BUFRESIZE_MANUAL 1 /* manual resizing */ + +#endif /* _LINUX_DTRACE_OPTIONS_DEFINES_H */ diff --git a/dtrace/include/uapi/linux/dtrace/stability.h b/dtrace/include/uapi/linux/dtrace/stability.h new file mode 100644 index 000000000000..9b9eb142dcc8 --- /dev/null +++ b/dtrace/include/uapi/linux/dtrace/stability.h @@ -0,0 +1,70 @@ +#ifndef _LINUX_DTRACE_STABILITY_H +#define _LINUX_DTRACE_STABILITY_H + +/* + * DTrace Dynamic Tracing Software: DTrace Stability Attributes + * + * Note: The contents of this file are private to the implementation of the + * DTrace subsystem and are subject to change at any time without notice. + */ + +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + * + * Copyright 2009 -- 2013 Oracle, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include +#include + +/* + * Each DTrace provider advertises the name and data stability of each of its + * probe description components, as well as its architectural dependencies. The + * D compiler can query the provider attributes (dtrace_pattr_t) in order to + * compute the properties of an input program and report them. + */ + +typedef struct dtrace_ppriv { + uint32_t dtpp_flags; /* privilege flags */ + uid_t dtpp_uid; /* user ID */ +} dtrace_ppriv_t; + +typedef struct dtrace_attribute { + dtrace_stability_t dtat_name; /* entity name stability */ + dtrace_stability_t dtat_data; /* entity data stability */ + dtrace_class_t dtat_class; /* entity data dependency */ +} dtrace_attribute_t; + +typedef struct dtrace_pattr { + dtrace_attribute_t dtpa_provider; /* provider attributes */ + dtrace_attribute_t dtpa_mod; /* module attributes */ + dtrace_attribute_t dtpa_func; /* function attributes */ + dtrace_attribute_t dtpa_name; /* name attributes */ + dtrace_attribute_t dtpa_args; /* args[] attributes */ +} dtrace_pattr_t; + +typedef struct dtrace_providerdesc { + char dtvd_name[DTRACE_PROVNAMELEN]; /* provider name */ + dtrace_pattr_t dtvd_attr; /* stability attributes */ + dtrace_ppriv_t dtvd_priv; /* privileges required */ +} dtrace_providerdesc_t; + +#endif /* _LINUX_DTRACE_STABILITY_H */ diff --git a/dtrace/include/uapi/linux/dtrace/stability_defines.h b/dtrace/include/uapi/linux/dtrace/stability_defines.h new file mode 100644 index 000000000000..64f0449a9e3c --- /dev/null +++ b/dtrace/include/uapi/linux/dtrace/stability_defines.h @@ -0,0 +1,71 @@ +#ifndef _LINUX_DTRACE_STABILITY_DEFINES_H +#define _LINUX_DTRACE_STABILITY_DEFINES_H + +/* + * DTrace Dynamic Tracing Software: DTrace Stability Attributes + * + * Note: The contents of this file are private to the implementation of the + * DTrace subsystem and are subject to change at any time without notice. + */ + +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + * + * Copyright 2009 -- 2013 Oracle, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include + +typedef uint8_t dtrace_stability_t; /* stability code */ +typedef uint8_t dtrace_class_t; /* architectural dependency class */ + +#define DTRACE_STABILITY_INTERNAL 0 /* private to DTrace itself */ +#define DTRACE_STABILITY_PRIVATE 1 /* private to Sun (see docs) */ +#define DTRACE_STABILITY_OBSOLETE 2 /* scheduled for removal */ +#define DTRACE_STABILITY_EXTERNAL 3 /* not controlled by Sun */ +#define DTRACE_STABILITY_UNSTABLE 4 /* new or rapidly changing */ +#define DTRACE_STABILITY_EVOLVING 5 /* less rapidly changing */ +#define DTRACE_STABILITY_STABLE 6 /* mature interface from Sun */ +#define DTRACE_STABILITY_STANDARD 7 /* industry standard */ +#define DTRACE_STABILITY_MAX 7 /* maximum valid stability */ + +#define DTRACE_CLASS_UNKNOWN 0 /* unknown architectural dependency */ +#define DTRACE_CLASS_CPU 1 /* CPU-module-specific */ +#define DTRACE_CLASS_PLATFORM 2 /* platform-specific (uname -i) */ +#define DTRACE_CLASS_GROUP 3 /* hardware-group-specific (uname -m) */ +#define DTRACE_CLASS_ISA 4 /* ISA-specific (uname -p) */ +#define DTRACE_CLASS_COMMON 5 /* common to all systems */ +#define DTRACE_CLASS_MAX 5 /* maximum valid class */ + +#define DTRACE_PRIV_NONE 0x0000 +#define DTRACE_PRIV_KERNEL 0x0001 +#define DTRACE_PRIV_USER 0x0002 +#define DTRACE_PRIV_PROC 0x0004 +#define DTRACE_PRIV_OWNER 0x0008 +#define DTRACE_PRIV_ALL (DTRACE_PRIV_KERNEL | DTRACE_PRIV_USER | \ + DTRACE_PRIV_PROC | DTRACE_PRIV_OWNER) + +struct dtrace_ppriv; +struct dtrace_attribute; +struct dtrace_pattr; +struct dtrace_providerdesc; + +#endif /* _LINUX_DTRACE_STABILITY_DEFINES_H */ diff --git a/dtrace/include/uapi/linux/dtrace/status.h b/dtrace/include/uapi/linux/dtrace/status.h new file mode 100644 index 000000000000..e9f04af75876 --- /dev/null +++ b/dtrace/include/uapi/linux/dtrace/status.h @@ -0,0 +1,68 @@ +#ifndef _LINUX_DTRACE_STATUS_H +#define _LINUX_DTRACE_STATUS_H + +/* + * DTrace Dynamic Tracing Software: DTrace Status + * + * Note: The contents of this file are private to the implementation of the + * DTrace subsystem and are subject to change at any time without notice. + */ + +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + * + * Copyright 2009 -- 2013 Oracle, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include + +/* + * The status of DTrace is relayed via the dtrace_status structure. This + * structure contains members to count drops other than the capacity drops + * available via the buffer interface (see above). This consists of dynamic + * drops (including capacity dynamic drops, rinsing drops and dirty drops), and + * speculative drops (including capacity speculative drops, drops due to busy + * speculative buffers and drops due to unavailable speculative buffers). + * Additionally, the status structure contains a field to indicate the number + * of "fill"-policy buffers have been filled and a boolean field to indicate + * that exit() has been called. If the dtst_exiting field is non-zero, no + * further data will be generated until tracing is stopped (at which time any + * enablings of the END action will be processed); if user-level sees that + * this field is non-zero, tracing should be stopped as soon as possible. + */ + +typedef struct dtrace_status { + uint64_t dtst_dyndrops; /* dynamic drops */ + uint64_t dtst_dyndrops_rinsing; /* dyn drops due to rinsing */ + uint64_t dtst_dyndrops_dirty; /* dyn drops due to dirty */ + uint64_t dtst_specdrops; /* speculative drops */ + uint64_t dtst_specdrops_busy; /* spec drops due to busy */ + uint64_t dtst_specdrops_unavail; /* spec drops due to unavail */ + uint64_t dtst_errors; /* total errors */ + uint64_t dtst_filled; /* number of filled bufs */ + uint64_t dtst_stkstroverflows; /* stack string tab overflows */ + uint64_t dtst_dblerrors; /* errors in ERROR probes */ + char dtst_killed; /* non-zero if killed */ + char dtst_exiting; /* non-zero if exit() called */ + char dtst_pad[6]; /* pad out to 64-bit align */ +} dtrace_status_t; + +#endif /* _LINUX_DTRACE_STATUS_H */ diff --git a/dtrace/include/uapi/linux/dtrace/universal.h b/dtrace/include/uapi/linux/dtrace/universal.h new file mode 100644 index 000000000000..808cdcf931f3 --- /dev/null +++ b/dtrace/include/uapi/linux/dtrace/universal.h @@ -0,0 +1,65 @@ +#ifndef _LINUX_DTRACE_UNIVERSAL_H_ +#define _LINUX_DTRACE_UNIVERSAL_H_ + +/* + * DTrace Dynamic Tracing Software: Universal Constants and Typedefs + * + * Note: The contents of this file are private to the implementation of the + * DTrace subsystem and are subject to change at any time without notice. + */ + +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + * + * Copyright 2009 -- 2013 Oracle, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#define DTRACE_CPUALL -1 /* all CPUs */ +#define DTRACE_IDNONE 0 /* invalid probe identifier */ +#define DTRACE_EPIDNONE 0 /* invalid enabled probe identifier */ +#define DTRACE_AGGIDNONE 0 /* invalid aggregation identifier */ +#define DTRACE_AGGVARIDNONE 0 /* invalid aggregation variable ID */ +#define DTRACE_CACHEIDNONE 0 /* invalid predicate cache */ +#define DTRACE_PROVNONE 0 /* invalid provider identifier */ +#define DTRACE_METAPROVNONE 0 /* invalid meta-provider identifier */ +#define DTRACE_ARGNONE -1 /* invalid argument index */ + +#define DTRACE_PROVNAMELEN 64 +#define DTRACE_MODNAMELEN 64 +#define DTRACE_FUNCNAMELEN 128 +#define DTRACE_NAMELEN 64 +#define DTRACE_FULLNAMELEN (DTRACE_PROVNAMELEN + DTRACE_MODNAMELEN + \ + DTRACE_FUNCNAMELEN + DTRACE_NAMELEN + 4) +#define DTRACE_ARGTYPELEN 128 + +typedef uint16_t dtrace_actkind_t; /* action kind */ + +typedef uint32_t dtrace_aggid_t; /* aggregation identifier */ +typedef uint32_t dtrace_cacheid_t; /* predicate cache identifier */ +typedef uint32_t dtrace_epid_t; /* enabled probe identifier */ +typedef uint32_t dtrace_optid_t; /* option identifier */ +typedef uint32_t dtrace_specid_t; /* speculation identifier */ + +typedef uint64_t dtrace_aggvarid_t; /* aggregation variable id */ +typedef uint64_t dtrace_genid_t; /* generation identifier */ +typedef uint64_t dtrace_optval_t; /* option value */ + +#endif /* _LINUX_DTRACE_UNIVERSAL_H_ */ -- 2.50.1