fasttrap_impl.h revision 262047
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22/*
23 * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24 * Use is subject to license terms.
25 */
26
27#ifndef	_FASTTRAP_IMPL_H
28#define	_FASTTRAP_IMPL_H
29
30#pragma ident	"%Z%%M%	%I%	%E% SMI"
31
32#include <sys/types.h>
33#include <sys/dtrace.h>
34#include <sys/proc.h>
35#include <sys/fasttrap.h>
36#include <sys/fasttrap_isa.h>
37
38#ifdef	__cplusplus
39extern "C" {
40#endif
41
42/*
43 * Fasttrap Providers, Probes and Tracepoints
44 *
45 * Each Solaris process can have multiple providers -- the pid provider as
46 * well as any number of user-level statically defined tracing (USDT)
47 * providers. Those providers are each represented by a fasttrap_provider_t.
48 * All providers for a given process have a pointer to a shared
49 * fasttrap_proc_t. The fasttrap_proc_t has two states: active or defunct.
50 * When the count of active providers goes to zero it becomes defunct; a
51 * provider drops its active count when it is removed individually or as part
52 * of a mass removal when a process exits or performs an exec.
53 *
54 * Each probe is represented by a fasttrap_probe_t which has a pointer to
55 * its associated provider as well as a list of fasttrap_id_tp_t structures
56 * which are tuples combining a fasttrap_id_t and a fasttrap_tracepoint_t.
57 * A fasttrap_tracepoint_t represents the actual point of instrumentation
58 * and it contains two lists of fasttrap_id_t structures (to be fired pre-
59 * and post-instruction emulation) that identify the probes attached to the
60 * tracepoint. Tracepoints also have a pointer to the fasttrap_proc_t for the
61 * process they trace which is used when looking up a tracepoint both when a
62 * probe fires and when enabling and disabling probes.
63 *
64 * It's important to note that probes are preallocated with the necessary
65 * number of tracepoints, but that tracepoints can be shared by probes and
66 * swapped between probes. If a probe's preallocated tracepoint is enabled
67 * (and, therefore, the associated probe is enabled), and that probe is
68 * then disabled, ownership of that tracepoint may be exchanged for an
69 * unused tracepoint belonging to another probe that was attached to the
70 * enabled tracepoint.
71 */
72
73typedef struct fasttrap_proc {
74	pid_t ftpc_pid;				/* process ID for this proc */
75	uint64_t ftpc_acount;			/* count of active providers */
76	uint64_t ftpc_rcount;			/* count of extant providers */
77	kmutex_t ftpc_mtx;			/* lock on all but acount */
78	struct fasttrap_proc *ftpc_next;	/* next proc in hash chain */
79} fasttrap_proc_t;
80
81typedef struct fasttrap_provider {
82	pid_t ftp_pid;				/* process ID for this prov */
83	char ftp_name[DTRACE_PROVNAMELEN];	/* prov name (w/o the pid) */
84	dtrace_provider_id_t ftp_provid;	/* DTrace provider handle */
85	uint_t ftp_marked;			/* mark for possible removal */
86	uint_t ftp_retired;			/* mark when retired */
87	kmutex_t ftp_mtx;			/* provider lock */
88	kmutex_t ftp_cmtx;			/* lock on creating probes */
89	uint64_t ftp_rcount;			/* enabled probes ref count */
90	uint64_t ftp_ccount;			/* consumers creating probes */
91	uint64_t ftp_mcount;			/* meta provider count */
92	fasttrap_proc_t *ftp_proc;		/* shared proc for all provs */
93	struct fasttrap_provider *ftp_next;	/* next prov in hash chain */
94} fasttrap_provider_t;
95
96typedef struct fasttrap_id fasttrap_id_t;
97typedef struct fasttrap_probe fasttrap_probe_t;
98typedef struct fasttrap_tracepoint fasttrap_tracepoint_t;
99
100struct fasttrap_id {
101	fasttrap_probe_t *fti_probe;		/* referrring probe */
102	fasttrap_id_t *fti_next;		/* enabled probe list on tp */
103	fasttrap_probe_type_t fti_ptype;	/* probe type */
104};
105
106typedef struct fasttrap_id_tp {
107	fasttrap_id_t fit_id;
108	fasttrap_tracepoint_t *fit_tp;
109} fasttrap_id_tp_t;
110
111struct fasttrap_probe {
112	dtrace_id_t ftp_id;			/* DTrace probe identifier */
113	pid_t ftp_pid;				/* pid for this probe */
114	fasttrap_provider_t *ftp_prov;		/* this probe's provider */
115	uintptr_t ftp_faddr;			/* associated function's addr */
116	size_t ftp_fsize;			/* associated function's size */
117	uint64_t ftp_gen;			/* modification generation */
118	uint64_t ftp_ntps;			/* number of tracepoints */
119	uint8_t *ftp_argmap;			/* native to translated args */
120	uint8_t ftp_nargs;			/* translated argument count */
121	uint8_t ftp_enabled;			/* is this probe enabled */
122	char *ftp_xtypes;			/* translated types index */
123	char *ftp_ntypes;			/* native types index */
124	fasttrap_id_tp_t ftp_tps[1];		/* flexible array */
125};
126
127#define	FASTTRAP_ID_INDEX(id)	\
128((fasttrap_id_tp_t *)(((char *)(id) - offsetof(fasttrap_id_tp_t, fit_id))) - \
129&(id)->fti_probe->ftp_tps[0])
130
131struct fasttrap_tracepoint {
132	fasttrap_proc_t *ftt_proc;		/* associated process struct */
133	uintptr_t ftt_pc;			/* address of tracepoint */
134	pid_t ftt_pid;				/* pid of tracepoint */
135	fasttrap_machtp_t ftt_mtp;		/* ISA-specific portion */
136	fasttrap_id_t *ftt_ids;			/* NULL-terminated list */
137	fasttrap_id_t *ftt_retids;		/* NULL-terminated list */
138	fasttrap_tracepoint_t *ftt_next;	/* link in global hash */
139};
140
141typedef struct fasttrap_bucket {
142	kmutex_t ftb_mtx;			/* bucket lock */
143	void *ftb_data;				/* data payload */
144
145	uint8_t ftb_pad[64 - sizeof (kmutex_t) - sizeof (void *)];
146} fasttrap_bucket_t;
147
148typedef struct fasttrap_hash {
149	ulong_t fth_nent;			/* power-of-2 num. of entries */
150	ulong_t fth_mask;			/* fth_nent - 1 */
151	fasttrap_bucket_t *fth_table;		/* array of buckets */
152} fasttrap_hash_t;
153
154/*
155 * If at some future point these assembly functions become observable by
156 * DTrace, then these defines should become separate functions so that the
157 * fasttrap provider doesn't trigger probes during internal operations.
158 */
159#define	fasttrap_copyout	copyout
160#define	fasttrap_fuword32	fuword32
161#define	fasttrap_suword32	suword32
162#define	fasttrap_suword64	suword64
163
164#ifdef __amd64__
165#define	fasttrap_fulword	fuword64
166#define	fasttrap_sulword	suword64
167#else
168#define	fasttrap_fulword	fuword32
169#define	fasttrap_sulword	suword32
170#endif
171
172extern void fasttrap_sigtrap(proc_t *, kthread_t *, uintptr_t);
173
174extern dtrace_id_t 		fasttrap_probe_id;
175extern fasttrap_hash_t		fasttrap_tpoints;
176
177#define	FASTTRAP_TPOINTS_INDEX(pid, pc) \
178	(((pc) / sizeof (fasttrap_instr_t) + (pid)) & fasttrap_tpoints.fth_mask)
179
180/*
181 * Must be implemented by fasttrap_isa.c
182 */
183extern int fasttrap_tracepoint_init(proc_t *, fasttrap_tracepoint_t *,
184    uintptr_t, fasttrap_probe_type_t);
185extern int fasttrap_tracepoint_install(proc_t *, fasttrap_tracepoint_t *);
186extern int fasttrap_tracepoint_remove(proc_t *, fasttrap_tracepoint_t *);
187
188struct reg;
189extern int fasttrap_pid_probe(struct reg *);
190extern int fasttrap_return_probe(struct reg *);
191
192extern uint64_t fasttrap_pid_getarg(void *, dtrace_id_t, void *, int, int);
193extern uint64_t fasttrap_usdt_getarg(void *, dtrace_id_t, void *, int, int);
194
195#ifdef	__cplusplus
196}
197#endif
198
199#endif	/* _FASTTRAP_IMPL_H */
200