1/*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (c) 2005-2007 Joseph Koshy
5 * Copyright (c) 2007 The FreeBSD Foundation
6 * All rights reserved.
7 *
8 * Portions of this software were developed by A. Joseph Koshy under
9 * sponsorship from the FreeBSD Foundation and Google, Inc.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 *    notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 *    notice, this list of conditions and the following disclaimer in the
18 *    documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 */
32
33#ifndef	_PMCLOG_H_
34#define	_PMCLOG_H_
35
36#include <sys/cdefs.h>
37#include <sys/pmclog.h>
38
39enum pmclog_state {
40	PMCLOG_OK,
41	PMCLOG_EOF,
42	PMCLOG_REQUIRE_DATA,
43	PMCLOG_ERROR
44};
45
46struct pmclog_ev_callchain {
47	uint32_t	pl_pid;
48	uint32_t	pl_tid;
49	uint32_t	pl_pmcid;
50	uint32_t	pl_cpuflags;
51	uint32_t	pl_cpuflags2;
52	uint32_t	pl_npc;
53	uintfptr_t	pl_pc[PMC_CALLCHAIN_DEPTH_MAX];
54};
55
56struct pmclog_ev_dropnotify {
57};
58
59struct pmclog_ev_closelog {
60};
61
62struct pmclog_ev_initialize {
63	uint32_t	pl_version;
64	uint32_t	pl_arch;
65	uint64_t	pl_tsc_freq;
66	struct timespec pl_ts;
67	char		pl_cpuid[PATH_MAX];
68};
69
70struct pmclog_ev_map_in {
71	pid_t		pl_pid;
72	uintfptr_t	pl_start;
73	char		pl_pathname[PATH_MAX];
74};
75
76struct pmclog_ev_map_out {
77	pid_t		pl_pid;
78	uintfptr_t	pl_start;
79	uintfptr_t	pl_end;
80};
81
82struct pmclog_ev_pcsample {
83	uintfptr_t	pl_pc;
84	pid_t		pl_pid;
85	pid_t		pl_tid;
86	pmc_id_t	pl_pmcid;
87	uint32_t	pl_flags;
88	uint32_t	pl_usermode;
89};
90
91struct pmclog_ev_pmcallocate {
92	const char *	pl_evname;
93	uint64_t	pl_rate;
94	uint32_t	pl_event;
95	uint32_t	pl_flags;
96	pmc_id_t	pl_pmcid;
97};
98
99struct pmclog_ev_pmcallocatedyn {
100	char 		pl_evname[PMC_NAME_MAX];
101	uint32_t	pl_event;
102	uint32_t	pl_flags;
103	pmc_id_t	pl_pmcid;
104};
105
106struct pmclog_ev_pmcattach {
107	pmc_id_t	pl_pmcid;
108	pid_t		pl_pid;
109	char		pl_pathname[PATH_MAX];
110};
111
112struct pmclog_ev_pmcdetach {
113	pmc_id_t	pl_pmcid;
114	pid_t		pl_pid;
115};
116
117struct pmclog_ev_proccsw {
118	pid_t		pl_pid;
119	pid_t		pl_tid;
120	pmc_id_t	pl_pmcid;
121	pmc_value_t	pl_value;
122};
123
124struct pmclog_ev_proccreate {
125	pid_t		pl_pid;
126	uint32_t	pl_flags;
127	char		pl_pcomm[MAXCOMLEN+1];
128};
129
130struct pmclog_ev_procexec {
131	pid_t		pl_pid;
132	pmc_id_t	pl_pmcid;
133	uintptr_t	pl_baseaddr;
134	uintptr_t	pl_dynaddr;
135	char		pl_pathname[PATH_MAX];
136};
137
138struct pmclog_ev_procexit {
139	uint32_t	pl_pid;
140	pmc_id_t	pl_pmcid;
141	pmc_value_t	pl_value;
142};
143
144struct pmclog_ev_procfork {
145	pid_t		pl_oldpid;
146	pid_t		pl_newpid;
147};
148
149struct pmclog_ev_sysexit {
150	pid_t		pl_pid;
151};
152
153struct pmclog_ev_threadcreate {
154	pid_t		pl_tid;
155	pid_t		pl_pid;
156	uint32_t	pl_flags;
157	char		pl_tdname[MAXCOMLEN+1];
158};
159
160struct pmclog_ev_threadexit {
161	pid_t		pl_tid;
162};
163
164struct pmclog_ev_userdata {
165	uint32_t	pl_userdata;
166};
167
168struct pmclog_ev {
169	enum pmclog_state pl_state;	/* state after 'get_event()' */
170	off_t		  pl_offset;	/* byte offset in stream */
171	size_t		  pl_count;	/* count of records so far */
172	struct timespec   pl_ts;	/* log entry timestamp */
173	enum pmclog_type  pl_type;	/* type of log entry */
174	void		 *pl_data;
175	int		  pl_len;
176	union { 			/* log entry data */
177		struct pmclog_ev_callchain	pl_cc;
178		struct pmclog_ev_closelog	pl_cl;
179		struct pmclog_ev_dropnotify	pl_dn;
180		struct pmclog_ev_initialize	pl_i;
181		struct pmclog_ev_map_in		pl_mi;
182		struct pmclog_ev_map_out	pl_mo;
183		struct pmclog_ev_pmcallocate	pl_a;
184		struct pmclog_ev_pmcallocatedyn	pl_ad;
185		struct pmclog_ev_pmcattach	pl_t;
186		struct pmclog_ev_pmcdetach	pl_d;
187		struct pmclog_ev_proccsw	pl_c;
188		struct pmclog_ev_proccreate	pl_pc;
189		struct pmclog_ev_procexec	pl_x;
190		struct pmclog_ev_procexit	pl_e;
191		struct pmclog_ev_procfork	pl_f;
192		struct pmclog_ev_sysexit	pl_se;
193		struct pmclog_ev_threadcreate	pl_tc;
194		struct pmclog_ev_threadexit	pl_te;
195		struct pmclog_ev_userdata	pl_u;
196	} pl_u;
197};
198
199enum pmclog_parser_state {
200	PL_STATE_NEW_RECORD,		/* in-between records */
201	PL_STATE_EXPECTING_HEADER,	/* header being read */
202	PL_STATE_PARTIAL_RECORD,	/* header present but not the record */
203	PL_STATE_ERROR			/* parsing error encountered */
204};
205
206struct pmclog_parse_state {
207	enum pmclog_parser_state ps_state;
208	enum pmc_cputype	ps_arch;	/* log file architecture */
209	uint32_t		ps_version;	/* hwpmc version */
210	int			ps_initialized;	/* whether initialized */
211	int			ps_count;	/* count of records processed */
212	off_t			ps_offset;	/* stream byte offset */
213	union pmclog_entry	ps_saved;	/* saved partial log entry */
214	int			ps_svcount;	/* #bytes saved */
215	int			ps_fd;		/* active fd or -1 */
216	char			*ps_buffer;	/* scratch buffer if fd != -1 */
217	char			*ps_data;	/* current parse pointer */
218	char			*ps_cpuid;	/* log cpuid */
219	size_t			ps_len;		/* length of buffered data */
220};
221
222#define	PMCLOG_FD_NONE				(-1)
223
224__BEGIN_DECLS
225void	*pmclog_open(int _fd);
226int	pmclog_feed(void *_cookie, char *_data, int _len);
227int	pmclog_read(void *_cookie, struct pmclog_ev *_ev);
228void	pmclog_close(void *_cookie);
229__END_DECLS
230
231#endif
232
233