xref: /freebsd/lib/libpmc/libpmc_json.cc (revision f992dd4b5c6635e079c572fe1b59e34f0e28ad6d)
1*f992dd4bSMatt Macy /*-
2*f992dd4bSMatt Macy  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3*f992dd4bSMatt Macy  *
4*f992dd4bSMatt Macy  * Copyright (c) 2018, Matthew Macy
5*f992dd4bSMatt Macy  *
6*f992dd4bSMatt Macy  * Redistribution and use in source and binary forms, with or without
7*f992dd4bSMatt Macy  * modification, are permitted provided that the following conditions
8*f992dd4bSMatt Macy  * are met:
9*f992dd4bSMatt Macy  * 1. Redistributions of source code must retain the above copyright
10*f992dd4bSMatt Macy  *    notice, this list of conditions and the following disclaimer.
11*f992dd4bSMatt Macy  * 2. Redistributions in binary form must reproduce the above copyright
12*f992dd4bSMatt Macy  *    notice, this list of conditions and the following disclaimer in the
13*f992dd4bSMatt Macy  *    documentation and/or other materials provided with the distribution.
14*f992dd4bSMatt Macy  *
15*f992dd4bSMatt Macy  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16*f992dd4bSMatt Macy  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17*f992dd4bSMatt Macy  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18*f992dd4bSMatt Macy  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19*f992dd4bSMatt Macy  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20*f992dd4bSMatt Macy  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21*f992dd4bSMatt Macy  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22*f992dd4bSMatt Macy  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23*f992dd4bSMatt Macy  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24*f992dd4bSMatt Macy  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25*f992dd4bSMatt Macy  * SUCH DAMAGE.
26*f992dd4bSMatt Macy  *
27*f992dd4bSMatt Macy  * $FreeBSD$
28*f992dd4bSMatt Macy  *
29*f992dd4bSMatt Macy  */
30*f992dd4bSMatt Macy 
31*f992dd4bSMatt Macy #include <sys/types.h>
32*f992dd4bSMatt Macy #include <sys/errno.h>
33*f992dd4bSMatt Macy #include <sys/sysctl.h>
34*f992dd4bSMatt Macy #include <stddef.h>
35*f992dd4bSMatt Macy #include <stdlib.h>
36*f992dd4bSMatt Macy #include <err.h>
37*f992dd4bSMatt Macy #include <limits.h>
38*f992dd4bSMatt Macy #include <string.h>
39*f992dd4bSMatt Macy #include <pmc.h>
40*f992dd4bSMatt Macy #include <pmclog.h>
41*f992dd4bSMatt Macy #include <assert.h>
42*f992dd4bSMatt Macy #include <string>
43*f992dd4bSMatt Macy #include <sysexits.h>
44*f992dd4bSMatt Macy #include <pmcformat.h>
45*f992dd4bSMatt Macy 
46*f992dd4bSMatt Macy using std::string;
47*f992dd4bSMatt Macy 
48*f992dd4bSMatt Macy static const char *typenames[] = {
49*f992dd4bSMatt Macy 	"",
50*f992dd4bSMatt Macy 	"{\"type\": \"closelog\"}\n",
51*f992dd4bSMatt Macy 	"{\"type\": \"dropnotify\"}\n",
52*f992dd4bSMatt Macy 	"{\"type\": \"initialize\"",
53*f992dd4bSMatt Macy 	"",
54*f992dd4bSMatt Macy 	"{\"type\": \"pmcallocate\"",
55*f992dd4bSMatt Macy 	"{\"type\": \"pmcattach\"",
56*f992dd4bSMatt Macy 	"{\"type\": \"pmcdetach\"",
57*f992dd4bSMatt Macy 	"{\"type\": \"proccsw\"",
58*f992dd4bSMatt Macy 	"{\"type\": \"procexec\"",
59*f992dd4bSMatt Macy 	"{\"type\": \"procexit\"",
60*f992dd4bSMatt Macy 	"{\"type\": \"procfork\"",
61*f992dd4bSMatt Macy 	"{\"type\": \"sysexit\"",
62*f992dd4bSMatt Macy 	"{\"type\": \"userdata\"",
63*f992dd4bSMatt Macy 	"{\"type\": \"map_in\"",
64*f992dd4bSMatt Macy 	"{\"type\": \"map_out\"",
65*f992dd4bSMatt Macy 	"{\"type\": \"callchain\"",
66*f992dd4bSMatt Macy 	"{\"type\": \"pmcallocatedyn\"",
67*f992dd4bSMatt Macy 	"{\"type\": \"thr_create\"",
68*f992dd4bSMatt Macy 	"{\"type\": \"thr_exit\"",
69*f992dd4bSMatt Macy 	"{\"type\": \"proc_create\"",
70*f992dd4bSMatt Macy };
71*f992dd4bSMatt Macy 
72*f992dd4bSMatt Macy static string
73*f992dd4bSMatt Macy startentry(struct pmclog_ev *ev)
74*f992dd4bSMatt Macy {
75*f992dd4bSMatt Macy 	char eventbuf[128];
76*f992dd4bSMatt Macy 
77*f992dd4bSMatt Macy 	snprintf(eventbuf, sizeof(eventbuf), "%s, \"tsc\": \"%jd\"",
78*f992dd4bSMatt Macy 	    typenames[ev->pl_type], (intmax_t)ev->pl_ts.tv_sec);
79*f992dd4bSMatt Macy 	return (string(eventbuf));
80*f992dd4bSMatt Macy }
81*f992dd4bSMatt Macy 
82*f992dd4bSMatt Macy static string
83*f992dd4bSMatt Macy initialize_to_json(struct pmclog_ev *ev)
84*f992dd4bSMatt Macy {
85*f992dd4bSMatt Macy 	char eventbuf[256];
86*f992dd4bSMatt Macy 	string startent;
87*f992dd4bSMatt Macy 
88*f992dd4bSMatt Macy 	startent = startentry(ev);
89*f992dd4bSMatt Macy 	snprintf(eventbuf, sizeof(eventbuf),
90*f992dd4bSMatt Macy 	    "%s, \"version\": \"0x%08x\", \"arch\": \"0x%08x\", \"cpuid\": \"%s\", "
91*f992dd4bSMatt Macy 		"\"tsc_freq\": \"%jd\", \"sec\": \"%jd\", \"nsec\": \"%jd\"}\n",
92*f992dd4bSMatt Macy 		startent.c_str(), ev->pl_u.pl_i.pl_version, ev->pl_u.pl_i.pl_arch,
93*f992dd4bSMatt Macy 		ev->pl_u.pl_i.pl_cpuid, (uintmax_t)ev->pl_u.pl_i.pl_tsc_freq,
94*f992dd4bSMatt Macy 		(uintmax_t)ev->pl_u.pl_i.pl_ts.tv_sec, (uintmax_t)ev->pl_u.pl_i.pl_ts.tv_nsec);
95*f992dd4bSMatt Macy 	return string(eventbuf);
96*f992dd4bSMatt Macy }
97*f992dd4bSMatt Macy 
98*f992dd4bSMatt Macy static string
99*f992dd4bSMatt Macy pmcallocate_to_json(struct pmclog_ev *ev)
100*f992dd4bSMatt Macy {
101*f992dd4bSMatt Macy 	char eventbuf[256];
102*f992dd4bSMatt Macy 	string startent;
103*f992dd4bSMatt Macy 
104*f992dd4bSMatt Macy 	startent = startentry(ev);
105*f992dd4bSMatt Macy 	snprintf(eventbuf, sizeof(eventbuf),
106*f992dd4bSMatt Macy 	    "%s, \"pmcid\": \"0x%08x\", \"event\": \"0x%08x\", \"flags\": \"0x%08x\", "
107*f992dd4bSMatt Macy 	    "\"rate\": \"%jd\"}\n",
108*f992dd4bSMatt Macy 		startent.c_str(), ev->pl_u.pl_a.pl_pmcid, ev->pl_u.pl_a.pl_event,
109*f992dd4bSMatt Macy 	    ev->pl_u.pl_a.pl_flags, (intmax_t)ev->pl_u.pl_a.pl_rate);
110*f992dd4bSMatt Macy 	return string(eventbuf);
111*f992dd4bSMatt Macy }
112*f992dd4bSMatt Macy 
113*f992dd4bSMatt Macy static string
114*f992dd4bSMatt Macy pmcattach_to_json(struct pmclog_ev *ev)
115*f992dd4bSMatt Macy {
116*f992dd4bSMatt Macy 	char eventbuf[2048];
117*f992dd4bSMatt Macy 	string startent;
118*f992dd4bSMatt Macy 
119*f992dd4bSMatt Macy 	startent = startentry(ev);
120*f992dd4bSMatt Macy 	snprintf(eventbuf, sizeof(eventbuf),
121*f992dd4bSMatt Macy 	    "%s, \"pmcid\": \"0x%08x\", \"pid\": \"%d\", \"pathname\": \"%s\"}\n",
122*f992dd4bSMatt Macy 		startent.c_str(), ev->pl_u.pl_t.pl_pmcid, ev->pl_u.pl_t.pl_pid,
123*f992dd4bSMatt Macy 	    ev->pl_u.pl_t.pl_pathname);
124*f992dd4bSMatt Macy 	return string(eventbuf);
125*f992dd4bSMatt Macy }
126*f992dd4bSMatt Macy 
127*f992dd4bSMatt Macy static string
128*f992dd4bSMatt Macy pmcdetach_to_json(struct pmclog_ev *ev)
129*f992dd4bSMatt Macy {
130*f992dd4bSMatt Macy 	char eventbuf[128];
131*f992dd4bSMatt Macy 	string startent;
132*f992dd4bSMatt Macy 
133*f992dd4bSMatt Macy 	startent = startentry(ev);
134*f992dd4bSMatt Macy 	snprintf(eventbuf, sizeof(eventbuf),
135*f992dd4bSMatt Macy 		"%s, \"pmcid\": \"0x%08x\", \"pid\": \"%d\"}\n",
136*f992dd4bSMatt Macy 			 startent.c_str(), ev->pl_u.pl_d.pl_pmcid, ev->pl_u.pl_d.pl_pid);
137*f992dd4bSMatt Macy 	return string(eventbuf);
138*f992dd4bSMatt Macy }
139*f992dd4bSMatt Macy 
140*f992dd4bSMatt Macy 
141*f992dd4bSMatt Macy static string
142*f992dd4bSMatt Macy proccsw_to_json(struct pmclog_ev *ev)
143*f992dd4bSMatt Macy {
144*f992dd4bSMatt Macy 	char eventbuf[128];
145*f992dd4bSMatt Macy 	string startent;
146*f992dd4bSMatt Macy 
147*f992dd4bSMatt Macy 	startent = startentry(ev);
148*f992dd4bSMatt Macy 	snprintf(eventbuf, sizeof(eventbuf), "%s, \"pmcid\": \"0x%08x\", \"pid\": \"%d\" "
149*f992dd4bSMatt Macy 	    "\"tid\": \"%d\", \"value\": \"0x%016jx\"}\n",
150*f992dd4bSMatt Macy 		startent.c_str(), ev->pl_u.pl_c.pl_pmcid, ev->pl_u.pl_c.pl_pid,
151*f992dd4bSMatt Macy 	    ev->pl_u.pl_c.pl_tid, (uintmax_t)ev->pl_u.pl_c.pl_value);
152*f992dd4bSMatt Macy 	return string(eventbuf);
153*f992dd4bSMatt Macy }
154*f992dd4bSMatt Macy 
155*f992dd4bSMatt Macy static string
156*f992dd4bSMatt Macy procexec_to_json(struct pmclog_ev *ev)
157*f992dd4bSMatt Macy {
158*f992dd4bSMatt Macy 	char eventbuf[2048];
159*f992dd4bSMatt Macy 	string startent;
160*f992dd4bSMatt Macy 
161*f992dd4bSMatt Macy 	startent = startentry(ev);
162*f992dd4bSMatt Macy 	snprintf(eventbuf, sizeof(eventbuf),
163*f992dd4bSMatt Macy 		"%s, \"pmcid\": \"0x%08x\", \"pid\": \"%d\", "
164*f992dd4bSMatt Macy 	    "\"start\": \"0x%016jx\", \"pathname\": \"%s\"}\n",
165*f992dd4bSMatt Macy 		startent.c_str(), ev->pl_u.pl_x.pl_pmcid, ev->pl_u.pl_x.pl_pid,
166*f992dd4bSMatt Macy 	    ev->pl_u.pl_x.pl_entryaddr, ev->pl_u.pl_x.pl_pathname);
167*f992dd4bSMatt Macy 	return string(eventbuf);
168*f992dd4bSMatt Macy }
169*f992dd4bSMatt Macy 
170*f992dd4bSMatt Macy static string
171*f992dd4bSMatt Macy procexit_to_json(struct pmclog_ev *ev)
172*f992dd4bSMatt Macy {
173*f992dd4bSMatt Macy 	char eventbuf[128];
174*f992dd4bSMatt Macy 	string startent;
175*f992dd4bSMatt Macy 
176*f992dd4bSMatt Macy 	startent = startentry(ev);
177*f992dd4bSMatt Macy 	snprintf(eventbuf, sizeof(eventbuf),
178*f992dd4bSMatt Macy 		"%s, \"pmcid\": \"0x%08x\", \"pid\": \"%d\", "
179*f992dd4bSMatt Macy 	    "\"value\": \"0x%016jx\"}\n",
180*f992dd4bSMatt Macy 		startent.c_str(), ev->pl_u.pl_e.pl_pmcid, ev->pl_u.pl_e.pl_pid,
181*f992dd4bSMatt Macy 	    (uintmax_t)ev->pl_u.pl_e.pl_value);
182*f992dd4bSMatt Macy 	return string(eventbuf);
183*f992dd4bSMatt Macy }
184*f992dd4bSMatt Macy 
185*f992dd4bSMatt Macy static string
186*f992dd4bSMatt Macy procfork_to_json(struct pmclog_ev *ev)
187*f992dd4bSMatt Macy {
188*f992dd4bSMatt Macy 	char eventbuf[128];
189*f992dd4bSMatt Macy 	string startent;
190*f992dd4bSMatt Macy 
191*f992dd4bSMatt Macy 	startent = startentry(ev);
192*f992dd4bSMatt Macy 	snprintf(eventbuf, sizeof(eventbuf),
193*f992dd4bSMatt Macy 		"%s, \"oldpid\": \"%d\", \"newpid\": \"%d\"}\n",
194*f992dd4bSMatt Macy 		startent.c_str(), ev->pl_u.pl_f.pl_oldpid, ev->pl_u.pl_f.pl_newpid);
195*f992dd4bSMatt Macy 	return string(eventbuf);
196*f992dd4bSMatt Macy }
197*f992dd4bSMatt Macy 
198*f992dd4bSMatt Macy static string
199*f992dd4bSMatt Macy sysexit_to_json(struct pmclog_ev *ev)
200*f992dd4bSMatt Macy {
201*f992dd4bSMatt Macy 	char eventbuf[128];
202*f992dd4bSMatt Macy 	string startent;
203*f992dd4bSMatt Macy 
204*f992dd4bSMatt Macy 	startent = startentry(ev);
205*f992dd4bSMatt Macy 	snprintf(eventbuf, sizeof(eventbuf), "%s, \"pid\": \"%d\"}\n",
206*f992dd4bSMatt Macy 		startent.c_str(), ev->pl_u.pl_se.pl_pid);
207*f992dd4bSMatt Macy 	return string(eventbuf);
208*f992dd4bSMatt Macy }
209*f992dd4bSMatt Macy 
210*f992dd4bSMatt Macy static string
211*f992dd4bSMatt Macy userdata_to_json(struct pmclog_ev *ev)
212*f992dd4bSMatt Macy {
213*f992dd4bSMatt Macy 	char eventbuf[128];
214*f992dd4bSMatt Macy 	string startent;
215*f992dd4bSMatt Macy 
216*f992dd4bSMatt Macy 	startent = startentry(ev);
217*f992dd4bSMatt Macy 	snprintf(eventbuf, sizeof(eventbuf), "%s, \"userdata\": \"0x%08x\"}\n",
218*f992dd4bSMatt Macy 	    startent.c_str(), ev->pl_u.pl_u.pl_userdata);
219*f992dd4bSMatt Macy 	return string(eventbuf);
220*f992dd4bSMatt Macy }
221*f992dd4bSMatt Macy 
222*f992dd4bSMatt Macy static string
223*f992dd4bSMatt Macy map_in_to_json(struct pmclog_ev *ev)
224*f992dd4bSMatt Macy {
225*f992dd4bSMatt Macy 	char eventbuf[2048];
226*f992dd4bSMatt Macy 	string startent;
227*f992dd4bSMatt Macy 
228*f992dd4bSMatt Macy 	startent = startentry(ev);
229*f992dd4bSMatt Macy 	snprintf(eventbuf, sizeof(eventbuf), "%s, \"pid\": \"%d\", "
230*f992dd4bSMatt Macy 	    "\"start\": \"0x%016jx\", \"pathname\": \"%s\"}\n",
231*f992dd4bSMatt Macy 	    startent.c_str(), ev->pl_u.pl_mi.pl_pid,
232*f992dd4bSMatt Macy 	    (uintmax_t)ev->pl_u.pl_mi.pl_start, ev->pl_u.pl_mi.pl_pathname);
233*f992dd4bSMatt Macy 	return string(eventbuf);
234*f992dd4bSMatt Macy }
235*f992dd4bSMatt Macy 
236*f992dd4bSMatt Macy static string
237*f992dd4bSMatt Macy map_out_to_json(struct pmclog_ev *ev)
238*f992dd4bSMatt Macy {
239*f992dd4bSMatt Macy 	char eventbuf[256];
240*f992dd4bSMatt Macy 	string startent;
241*f992dd4bSMatt Macy 
242*f992dd4bSMatt Macy 	startent = startentry(ev);
243*f992dd4bSMatt Macy 	snprintf(eventbuf, sizeof(eventbuf), "%s, \"pid\": \"%d\", "
244*f992dd4bSMatt Macy 	    "\"start\": \"0x%016jx\", \"end\": \"0x%016jx\"}\n",
245*f992dd4bSMatt Macy 	    startent.c_str(), ev->pl_u.pl_mi.pl_pid,
246*f992dd4bSMatt Macy 	    (uintmax_t)ev->pl_u.pl_mi.pl_start,
247*f992dd4bSMatt Macy 	    (uintmax_t)ev->pl_u.pl_mo.pl_end);
248*f992dd4bSMatt Macy 	return string(eventbuf);
249*f992dd4bSMatt Macy }
250*f992dd4bSMatt Macy 
251*f992dd4bSMatt Macy static string
252*f992dd4bSMatt Macy callchain_to_json(struct pmclog_ev *ev)
253*f992dd4bSMatt Macy {
254*f992dd4bSMatt Macy 	char eventbuf[1024];
255*f992dd4bSMatt Macy 	string result;
256*f992dd4bSMatt Macy 	uint32_t i;
257*f992dd4bSMatt Macy 	string startent;
258*f992dd4bSMatt Macy 
259*f992dd4bSMatt Macy 	startent = startentry(ev);
260*f992dd4bSMatt Macy 	snprintf(eventbuf, sizeof(eventbuf),
261*f992dd4bSMatt Macy 	    "%s, \"pmcid\": \"0x%08x\", \"pid\": \"%d\", \"tid\": \"%d\", "
262*f992dd4bSMatt Macy 	    "\"cpuflags\": \"0x%08x\", \"cpuflags2\": \"0x%08x\", \"pc\": [ ",
263*f992dd4bSMatt Macy 		startent.c_str(), ev->pl_u.pl_cc.pl_pmcid, ev->pl_u.pl_cc.pl_pid,
264*f992dd4bSMatt Macy 	    ev->pl_u.pl_cc.pl_tid, ev->pl_u.pl_cc.pl_cpuflags, ev->pl_u.pl_cc.pl_cpuflags2);
265*f992dd4bSMatt Macy 	result = string(eventbuf);
266*f992dd4bSMatt Macy 	for (i = 0; i < ev->pl_u.pl_cc.pl_npc - 1; i++) {
267*f992dd4bSMatt Macy 		snprintf(eventbuf, sizeof(eventbuf), "\"0x%016jx\", ", ev->pl_u.pl_cc.pl_pc[i]);
268*f992dd4bSMatt Macy 		result += string(eventbuf);
269*f992dd4bSMatt Macy 	}
270*f992dd4bSMatt Macy 	snprintf(eventbuf, sizeof(eventbuf), "\"0x%016jx\"]}\n", ev->pl_u.pl_cc.pl_pc[i]);
271*f992dd4bSMatt Macy 	result += string(eventbuf);
272*f992dd4bSMatt Macy 	return (result);
273*f992dd4bSMatt Macy }
274*f992dd4bSMatt Macy 
275*f992dd4bSMatt Macy static string
276*f992dd4bSMatt Macy pmcallocatedyn_to_json(struct pmclog_ev *ev)
277*f992dd4bSMatt Macy {
278*f992dd4bSMatt Macy 	char eventbuf[2048];
279*f992dd4bSMatt Macy 	string startent;
280*f992dd4bSMatt Macy 
281*f992dd4bSMatt Macy 	startent = startentry(ev);
282*f992dd4bSMatt Macy 	snprintf(eventbuf, sizeof(eventbuf),
283*f992dd4bSMatt Macy 	    "%s, \"pmcid\": \"0x%08x\", \"event\": \"%d\", \"flags\": \"0x%08x\", \"evname\": \"%s\"}\n",
284*f992dd4bSMatt Macy 	    startent.c_str(), ev->pl_u.pl_ad.pl_pmcid, ev->pl_u.pl_ad.pl_event,
285*f992dd4bSMatt Macy 	    ev->pl_u.pl_ad.pl_flags, ev->pl_u.pl_ad.pl_evname);
286*f992dd4bSMatt Macy 	return string(eventbuf);
287*f992dd4bSMatt Macy }
288*f992dd4bSMatt Macy 
289*f992dd4bSMatt Macy static string
290*f992dd4bSMatt Macy proccreate_to_json(struct pmclog_ev *ev)
291*f992dd4bSMatt Macy {
292*f992dd4bSMatt Macy 	char eventbuf[2048];
293*f992dd4bSMatt Macy 	string startent;
294*f992dd4bSMatt Macy 
295*f992dd4bSMatt Macy 	startent = startentry(ev);
296*f992dd4bSMatt Macy 	snprintf(eventbuf, sizeof(eventbuf),
297*f992dd4bSMatt Macy 	    "%s, \"pid\": \"%d\", \"flags\": \"0x%08x\", \"pcomm\": \"%s\"}\n",
298*f992dd4bSMatt Macy 	    startent.c_str(), ev->pl_u.pl_pc.pl_pid,
299*f992dd4bSMatt Macy 	    ev->pl_u.pl_pc.pl_flags, ev->pl_u.pl_pc.pl_pcomm);
300*f992dd4bSMatt Macy 	return string(eventbuf);
301*f992dd4bSMatt Macy }
302*f992dd4bSMatt Macy 
303*f992dd4bSMatt Macy static string
304*f992dd4bSMatt Macy threadcreate_to_json(struct pmclog_ev *ev)
305*f992dd4bSMatt Macy {
306*f992dd4bSMatt Macy 	char eventbuf[2048];
307*f992dd4bSMatt Macy 	string startent;
308*f992dd4bSMatt Macy 
309*f992dd4bSMatt Macy 	startent = startentry(ev);
310*f992dd4bSMatt Macy 	snprintf(eventbuf, sizeof(eventbuf),
311*f992dd4bSMatt Macy 	    "%s, \"tid\": \"%d\", \"pid\": \"%d\", \"flags\": \"0x%08x\", \"tdname\": \"%s\"}\n",
312*f992dd4bSMatt Macy 	    startent.c_str(), ev->pl_u.pl_tc.pl_tid, ev->pl_u.pl_tc.pl_pid,
313*f992dd4bSMatt Macy 	    ev->pl_u.pl_tc.pl_flags, ev->pl_u.pl_tc.pl_tdname);
314*f992dd4bSMatt Macy 	return string(eventbuf);
315*f992dd4bSMatt Macy }
316*f992dd4bSMatt Macy 
317*f992dd4bSMatt Macy static string
318*f992dd4bSMatt Macy threadexit_to_json(struct pmclog_ev *ev)
319*f992dd4bSMatt Macy {
320*f992dd4bSMatt Macy 	char eventbuf[256];
321*f992dd4bSMatt Macy 	string startent;
322*f992dd4bSMatt Macy 
323*f992dd4bSMatt Macy 	startent = startentry(ev);
324*f992dd4bSMatt Macy 	snprintf(eventbuf, sizeof(eventbuf), "%s, \"tid\": \"%d\"}\n",
325*f992dd4bSMatt Macy 	    startent.c_str(), ev->pl_u.pl_te.pl_tid);
326*f992dd4bSMatt Macy 	return string(eventbuf);
327*f992dd4bSMatt Macy }
328*f992dd4bSMatt Macy 
329*f992dd4bSMatt Macy static string
330*f992dd4bSMatt Macy stub_to_json(struct pmclog_ev *ev)
331*f992dd4bSMatt Macy {
332*f992dd4bSMatt Macy 	string startent;
333*f992dd4bSMatt Macy 
334*f992dd4bSMatt Macy 	startent = startentry(ev);
335*f992dd4bSMatt Macy 	startent += string("}\n");
336*f992dd4bSMatt Macy 	return startent;
337*f992dd4bSMatt Macy }
338*f992dd4bSMatt Macy 
339*f992dd4bSMatt Macy typedef string (*jconv) (struct pmclog_ev*);
340*f992dd4bSMatt Macy 
341*f992dd4bSMatt Macy static jconv jsonconvert[] = {
342*f992dd4bSMatt Macy 	NULL,
343*f992dd4bSMatt Macy 	stub_to_json,
344*f992dd4bSMatt Macy 	stub_to_json,
345*f992dd4bSMatt Macy 	initialize_to_json,
346*f992dd4bSMatt Macy 	NULL,
347*f992dd4bSMatt Macy 	pmcallocate_to_json,
348*f992dd4bSMatt Macy 	pmcattach_to_json,
349*f992dd4bSMatt Macy 	pmcdetach_to_json,
350*f992dd4bSMatt Macy 	proccsw_to_json,
351*f992dd4bSMatt Macy 	procexec_to_json,
352*f992dd4bSMatt Macy 	procexit_to_json,
353*f992dd4bSMatt Macy 	procfork_to_json,
354*f992dd4bSMatt Macy 	sysexit_to_json,
355*f992dd4bSMatt Macy 	userdata_to_json,
356*f992dd4bSMatt Macy 	map_in_to_json,
357*f992dd4bSMatt Macy 	map_out_to_json,
358*f992dd4bSMatt Macy 	callchain_to_json,
359*f992dd4bSMatt Macy 	pmcallocatedyn_to_json,
360*f992dd4bSMatt Macy 	threadcreate_to_json,
361*f992dd4bSMatt Macy 	threadexit_to_json,
362*f992dd4bSMatt Macy 	proccreate_to_json,
363*f992dd4bSMatt Macy };
364*f992dd4bSMatt Macy 
365*f992dd4bSMatt Macy string
366*f992dd4bSMatt Macy event_to_json(struct pmclog_ev *ev){
367*f992dd4bSMatt Macy 
368*f992dd4bSMatt Macy 	switch (ev->pl_type) {
369*f992dd4bSMatt Macy 	case PMCLOG_TYPE_DROPNOTIFY:
370*f992dd4bSMatt Macy 	case PMCLOG_TYPE_CLOSELOG:
371*f992dd4bSMatt Macy 	case PMCLOG_TYPE_INITIALIZE:
372*f992dd4bSMatt Macy 	case PMCLOG_TYPE_PMCALLOCATE:
373*f992dd4bSMatt Macy 	case PMCLOG_TYPE_PMCATTACH:
374*f992dd4bSMatt Macy 	case PMCLOG_TYPE_PMCDETACH:
375*f992dd4bSMatt Macy 	case PMCLOG_TYPE_PROCCSW:
376*f992dd4bSMatt Macy 	case PMCLOG_TYPE_PROCEXEC:
377*f992dd4bSMatt Macy 	case PMCLOG_TYPE_PROCEXIT:
378*f992dd4bSMatt Macy 	case PMCLOG_TYPE_PROCFORK:
379*f992dd4bSMatt Macy 	case PMCLOG_TYPE_SYSEXIT:
380*f992dd4bSMatt Macy 	case PMCLOG_TYPE_USERDATA:
381*f992dd4bSMatt Macy 	case PMCLOG_TYPE_MAP_IN:
382*f992dd4bSMatt Macy 	case PMCLOG_TYPE_MAP_OUT:
383*f992dd4bSMatt Macy 	case PMCLOG_TYPE_CALLCHAIN:
384*f992dd4bSMatt Macy 	case PMCLOG_TYPE_PMCALLOCATEDYN:
385*f992dd4bSMatt Macy 	case PMCLOG_TYPE_THR_CREATE:
386*f992dd4bSMatt Macy 	case PMCLOG_TYPE_THR_EXIT:
387*f992dd4bSMatt Macy 	case PMCLOG_TYPE_PROC_CREATE:
388*f992dd4bSMatt Macy 		return jsonconvert[ev->pl_type](ev);
389*f992dd4bSMatt Macy 	default:
390*f992dd4bSMatt Macy 		errx(EX_USAGE, "ERROR: unrecognized event type: %d\n", ev->pl_type);
391*f992dd4bSMatt Macy 	}
392*f992dd4bSMatt Macy }
393*f992dd4bSMatt Macy 
394