xref: /freebsd/usr.sbin/pmc/view.hh (revision 880865783d9c3b807a26f4ea8ab3ef6ce1ca6ff8)
193da997eSAli Mashtizadeh /*-
293da997eSAli Mashtizadeh  * SPDX-License-Identifier: BSD-2-Clause
393da997eSAli Mashtizadeh  *
493da997eSAli Mashtizadeh  * Copyright (c) 2026, Netflix, Inc.
593da997eSAli Mashtizadeh  *
693da997eSAli Mashtizadeh  * This software was developed by Ali Mashtizadeh under the sponsorship from
793da997eSAli Mashtizadeh  * Netflix, Inc.
893da997eSAli Mashtizadeh  *
993da997eSAli Mashtizadeh  * Redistribution and use in source and binary forms, with or without
1093da997eSAli Mashtizadeh  * modification, are permitted provided that the following conditions
1193da997eSAli Mashtizadeh  * are met:
1293da997eSAli Mashtizadeh  * 1. Redistributions of source code must retain the above copyright
1393da997eSAli Mashtizadeh  *    notice, this list of conditions and the following disclaimer.
1493da997eSAli Mashtizadeh  * 2. Redistributions in binary form must reproduce the above copyright
1593da997eSAli Mashtizadeh  *    notice, this list of conditions and the following disclaimer in the
1693da997eSAli Mashtizadeh  *    documentation and/or other materials provided with the distribution.
1793da997eSAli Mashtizadeh  *
1893da997eSAli Mashtizadeh  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1993da997eSAli Mashtizadeh  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2093da997eSAli Mashtizadeh  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2193da997eSAli Mashtizadeh  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2293da997eSAli Mashtizadeh  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2393da997eSAli Mashtizadeh  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2493da997eSAli Mashtizadeh  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2593da997eSAli Mashtizadeh  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2693da997eSAli Mashtizadeh  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2793da997eSAli Mashtizadeh  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2893da997eSAli Mashtizadeh  * SUCH DAMAGE.
2993da997eSAli Mashtizadeh  *
3093da997eSAli Mashtizadeh  */
3193da997eSAli Mashtizadeh #ifndef __VIEW_HH__
3293da997eSAli Mashtizadeh #define __VIEW_HH__
3393da997eSAli Mashtizadeh 
3493da997eSAli Mashtizadeh #include <libdwarf.h>
3593da997eSAli Mashtizadeh #include <libelf.h>
3693da997eSAli Mashtizadeh #include <libutil.h>
3793da997eSAli Mashtizadeh #include <gelf.h>
3893da997eSAli Mashtizadeh 
39503f1618SEnji Cooper #include <vector>
40503f1618SEnji Cooper 
4193da997eSAli Mashtizadeh #include "headers.hh"
4293da997eSAli Mashtizadeh #include "util.hh"
4393da997eSAli Mashtizadeh 
4493da997eSAli Mashtizadeh /*
4593da997eSAli Mashtizadeh  * PMC counter state.
4693da997eSAli Mashtizadeh  */
4793da997eSAli Mashtizadeh struct pmcinfo
4893da997eSAli Mashtizadeh {
pmcinfopmcinfo4993da997eSAli Mashtizadeh 	pmcinfo() : name(), rate(-1), event(0), count(0) { }
pmcinfopmcinfo5093da997eSAli Mashtizadeh 	pmcinfo(struct pmclog_ev_pmcallocate &p) {
5193da997eSAli Mashtizadeh 		name = p.pl_evname;
5293da997eSAli Mashtizadeh 		rate = p.pl_rate;
5393da997eSAli Mashtizadeh 		event = p.pl_event;
5493da997eSAli Mashtizadeh 		count = 0;
5593da997eSAli Mashtizadeh 	}
pmcinfopmcinfo5693da997eSAli Mashtizadeh 	pmcinfo(struct pmclog_ev_pmcallocatedyn &p) {
5793da997eSAli Mashtizadeh 		name = p.pl_evname;
5893da997eSAli Mashtizadeh 		rate = 0;
5993da997eSAli Mashtizadeh 		event = p.pl_event;
6093da997eSAli Mashtizadeh 		count = 0;
6193da997eSAli Mashtizadeh 	}
~pmcinfopmcinfo6293da997eSAli Mashtizadeh 	~pmcinfo() { }
6393da997eSAli Mashtizadeh 	std::string			name;
6493da997eSAli Mashtizadeh 	int				rate;
6593da997eSAli Mashtizadeh 	uint32_t			event;
6693da997eSAli Mashtizadeh 	uint64_t			count; // Available for application use
6793da997eSAli Mashtizadeh };
6893da997eSAli Mashtizadeh 
6993da997eSAli Mashtizadeh /*
7093da997eSAli Mashtizadeh  * Extended pmcinfo structure stores the complete event description passed to
7193da997eSAli Mashtizadeh  * libpmc.
7293da997eSAli Mashtizadeh  */
7393da997eSAli Mashtizadeh struct pmcinfox
7493da997eSAli Mashtizadeh {
pmcinfoxpmcinfox7593da997eSAli Mashtizadeh 	pmcinfox() : rate(0), event() { }
pmcinfoxpmcinfox76*88086578SEnji Cooper 	pmcinfox(uint32_t rate_, std::string event_) : rate(rate_), event(event_) { }
~pmcinfoxpmcinfox7793da997eSAli Mashtizadeh 	~pmcinfox() { }
7893da997eSAli Mashtizadeh 	uint32_t			rate;
7993da997eSAli Mashtizadeh 	std::string			event;
8093da997eSAli Mashtizadeh };
8193da997eSAli Mashtizadeh 
8293da997eSAli Mashtizadeh /*
8393da997eSAli Mashtizadeh  * CPUID Leafs for X86 Logs
8493da997eSAli Mashtizadeh  */
8593da997eSAli Mashtizadeh struct cpuidleaf
8693da997eSAli Mashtizadeh {
8793da997eSAli Mashtizadeh 	uint32_t			eax;
8893da997eSAli Mashtizadeh 	uint32_t			ebx;
8993da997eSAli Mashtizadeh 	uint32_t			ecx;
9093da997eSAli Mashtizadeh 	uint32_t			edx;
9193da997eSAli Mashtizadeh };
9293da997eSAli Mashtizadeh 
9393da997eSAli Mashtizadeh /*
9493da997eSAli Mashtizadeh  * Stores the address range for an executable segment in the process.
9593da997eSAli Mashtizadeh  */
9693da997eSAli Mashtizadeh struct vmmap
9793da997eSAli Mashtizadeh {
vmmapvmmap9893da997eSAli Mashtizadeh 	vmmap() : lowpc(0), highpc(0), image("") { }
~vmmapvmmap9993da997eSAli Mashtizadeh 	~vmmap() { }
10093da997eSAli Mashtizadeh 	uint64_t			lowpc;
10193da997eSAli Mashtizadeh 	uint64_t			highpc;
10293da997eSAli Mashtizadeh 	std::string			image;
10393da997eSAli Mashtizadeh };
10493da997eSAli Mashtizadeh 
10593da997eSAli Mashtizadeh struct threadinfo
10693da997eSAli Mashtizadeh {
threadinfothreadinfo10793da997eSAli Mashtizadeh 	threadinfo() : name("") { }
threadinfothreadinfo108fd809148SEnji Cooper 	threadinfo(const std::string &name_) : name(name_) { }
~threadinfothreadinfo10993da997eSAli Mashtizadeh 	~threadinfo() { }
11093da997eSAli Mashtizadeh 	std::string			name;
11193da997eSAli Mashtizadeh };
11293da997eSAli Mashtizadeh 
11393da997eSAli Mashtizadeh struct procinfo
11493da997eSAli Mashtizadeh {
procinfoprocinfo11593da997eSAli Mashtizadeh 	procinfo() : name(""), fullpath(""), map(), threads(),
11693da997eSAli Mashtizadeh 	    baseaddr(0), dynaddr(0) { }
procinfoprocinfo11793da997eSAli Mashtizadeh 	procinfo(struct pmclog_ev_proccreate &p) {
11893da997eSAli Mashtizadeh 		std::string pname = p.pl_pcomm;
11993da997eSAli Mashtizadeh 
12093da997eSAli Mashtizadeh 		if ((p.pl_flags & P_KPROC) != 0)
12193da997eSAli Mashtizadeh 			name = "[" + pname + "]";
12293da997eSAli Mashtizadeh 		else
12393da997eSAli Mashtizadeh 			name = pname;
12493da997eSAli Mashtizadeh 		map = std::map<uint64_t, vmmap>();
12593da997eSAli Mashtizadeh 		threads = std::map<pid_t, threadinfo>();
12693da997eSAli Mashtizadeh 		baseaddr = 0;
12793da997eSAli Mashtizadeh 		dynaddr = 0;
12893da997eSAli Mashtizadeh 	}
~procinfoprocinfo12993da997eSAli Mashtizadeh 	~procinfo() { }
13093da997eSAli Mashtizadeh 	std::string			name;
13193da997eSAli Mashtizadeh 	std::string			fullpath;
13293da997eSAli Mashtizadeh 	std::map<uint64_t, vmmap>	map;
13393da997eSAli Mashtizadeh 	std::map<pid_t, threadinfo>	threads;
13493da997eSAli Mashtizadeh 	uint64_t			baseaddr;
13593da997eSAli Mashtizadeh 	uint64_t			dynaddr;
13693da997eSAli Mashtizadeh };
13793da997eSAli Mashtizadeh 
13893da997eSAli Mashtizadeh /*
13993da997eSAli Mashtizadeh  * Symbol information
14093da997eSAli Mashtizadeh  */
14193da997eSAli Mashtizadeh struct syminfo
14293da997eSAli Mashtizadeh {
syminfosyminfo14393da997eSAli Mashtizadeh 	syminfo() : binary(""), name(""), offset(0), length(0), funcoff(0),
14493da997eSAli Mashtizadeh 	    line(0), column(0) { }
~syminfosyminfo14593da997eSAli Mashtizadeh 	~syminfo() { }
14693da997eSAli Mashtizadeh 	std::string to_string(bool show_line = true);
14793da997eSAli Mashtizadeh 	std::string			binary;
14893da997eSAli Mashtizadeh 	std::string			name;
14993da997eSAli Mashtizadeh 	uint64_t			offset;
15093da997eSAli Mashtizadeh 	uint64_t			length;
15193da997eSAli Mashtizadeh 	uint64_t			funcoff;
15293da997eSAli Mashtizadeh 	uint32_t			line;
15393da997eSAli Mashtizadeh 	uint32_t			column;
15493da997eSAli Mashtizadeh };
15593da997eSAli Mashtizadeh 
15693da997eSAli Mashtizadeh struct image
15793da997eSAli Mashtizadeh {
imageimage15893da997eSAli Mashtizadeh 	image() : isdynamic(false), vaddr(0), start(0), end(0),
15993da997eSAli Mashtizadeh 	    offset(0), name(""), binary(""), path(""), loader(""),
16093da997eSAli Mashtizadeh 	    dwarf(""), symbols(), dbg_fd(-1), dbg_elf(NULL) { }
~imageimage16193da997eSAli Mashtizadeh 	~image() { }
16293da997eSAli Mashtizadeh 	bool				isdynamic;
16393da997eSAli Mashtizadeh 	uint64_t			vaddr;
16493da997eSAli Mashtizadeh 	uint64_t			start;
16593da997eSAli Mashtizadeh 	uint64_t			end;
16693da997eSAli Mashtizadeh 	uint64_t			offset;
16793da997eSAli Mashtizadeh 	std::string			name;
16893da997eSAli Mashtizadeh 	std::string			binary;
16993da997eSAli Mashtizadeh 	std::string			path;
17093da997eSAli Mashtizadeh 	std::string			loader;
17193da997eSAli Mashtizadeh 	std::string			dwarf;
17293da997eSAli Mashtizadeh 	std::map<uint64_t, syminfo>	symbols;
17393da997eSAli Mashtizadeh 	int				dbg_fd;
17493da997eSAli Mashtizadeh 	Elf				*dbg_elf;
17593da997eSAli Mashtizadeh 	Dwarf_Debug			dbg_dwarf;
17693da997eSAli Mashtizadeh };
17793da997eSAli Mashtizadeh 
17893da997eSAli Mashtizadeh struct pmcfilter
17993da997eSAli Mashtizadeh {
pmcfilterpmcfilter18093da997eSAli Mashtizadeh 	pmcfilter() : filterpid(false), filtertid(false),
18193da997eSAli Mashtizadeh 	    filterprogram(false), filterthread(false),
18293da997eSAli Mashtizadeh 	    filterevent(false), filtercpu(false),
18393da997eSAli Mashtizadeh 	    kernelonly(false), useronly(false),
18493da997eSAli Mashtizadeh 	    pids(), tids(), programs(), threads(),
18593da997eSAli Mashtizadeh 	    ibs_ldlat(0), ibs_oplat(0) { CPU_ZERO(&cpus); }
~pmcfilterpmcfilter18693da997eSAli Mashtizadeh 	~pmcfilter() { }
18793da997eSAli Mashtizadeh 	bool				filterpid;
18893da997eSAli Mashtizadeh 	bool				filtertid;
18993da997eSAli Mashtizadeh 	bool				filterprogram;
19093da997eSAli Mashtizadeh 	bool				filterthread;
19193da997eSAli Mashtizadeh 	bool				filterevent;
19293da997eSAli Mashtizadeh 	bool				filtercpu;
19393da997eSAli Mashtizadeh 	bool				kernelonly;
19493da997eSAli Mashtizadeh 	bool				useronly;
19593da997eSAli Mashtizadeh 	std::unordered_set<int>		pids;
19693da997eSAli Mashtizadeh 	std::unordered_set<int>		tids;
19793da997eSAli Mashtizadeh 	std::unordered_set<std::string>	programs;
19893da997eSAli Mashtizadeh 	std::unordered_set<std::string>	threads;
19993da997eSAli Mashtizadeh 	std::unordered_set<std::string>	events;
20093da997eSAli Mashtizadeh 	cpuset_t			cpus;
20193da997eSAli Mashtizadeh 	/*
20293da997eSAli Mashtizadeh 	 * Advanced filters for AMD IBS but should be generalized to support
20393da997eSAli Mashtizadeh 	 * other processors.
20493da997eSAli Mashtizadeh 	 */
20593da997eSAli Mashtizadeh 	uint64_t			ibs_ldlat;
20693da997eSAli Mashtizadeh 	uint64_t			ibs_oplat;
20793da997eSAli Mashtizadeh 	bool				ibs_mmio;
addpidspmcfilter20893da997eSAli Mashtizadeh 	void addpids(const char *ids) {
20993da997eSAli Mashtizadeh 		split_and_insert(&pids, ids);
21093da997eSAli Mashtizadeh 		filterpid = true;
21193da997eSAli Mashtizadeh 	}
addtidspmcfilter21293da997eSAli Mashtizadeh 	void addtids(const char *ids) {
21393da997eSAli Mashtizadeh 		split_and_insert(&tids, ids);
21493da997eSAli Mashtizadeh 		filtertid = true;
21593da997eSAli Mashtizadeh 	}
addthreadspmcfilter21693da997eSAli Mashtizadeh 	void addthreads(const char *ids) {
21793da997eSAli Mashtizadeh 		split_and_insert(&threads, ids);
21893da997eSAli Mashtizadeh 		filterthread = true;
21993da997eSAli Mashtizadeh 	}
addprogramspmcfilter22093da997eSAli Mashtizadeh 	void addprograms(const char *ids) {
22193da997eSAli Mashtizadeh 		split_and_insert(&programs, ids);
22293da997eSAli Mashtizadeh 		filterprogram = true;
22393da997eSAli Mashtizadeh 	}
addeventspmcfilter22493da997eSAli Mashtizadeh 	void addevents(const char *ids) {
22593da997eSAli Mashtizadeh 		split_and_insert(&events, ids);
22693da997eSAli Mashtizadeh 		filterevent = true;
22793da997eSAli Mashtizadeh 	}
addcpuspmcfilter22893da997eSAli Mashtizadeh 	void addcpus(const char *ids) {
22993da997eSAli Mashtizadeh 		if (cpuset_parselist(ids, &cpus) == CPUSET_PARSE_OK)
23093da997eSAli Mashtizadeh 			filtercpu = true;
23193da997eSAli Mashtizadeh 		else
23293da997eSAli Mashtizadeh 			fprintf(stderr, "Cannot parse cpulist");
23393da997eSAli Mashtizadeh 	}
23493da997eSAli Mashtizadeh };
23593da997eSAli Mashtizadeh 
23693da997eSAli Mashtizadeh /*
23793da997eSAli Mashtizadeh  * These macros help provide a uniform filter facility across all passes.
23893da997eSAli Mashtizadeh  * Filter options that are specific to a special feature, e.g., IBS, should
23993da997eSAli Mashtizadeh  * only be accessible through long options, and we reserve option number 0-9
24093da997eSAli Mashtizadeh  * for tool specific arguments.
24193da997eSAli Mashtizadeh  */
24293da997eSAli Mashtizadeh #define PMCFILTER_PRINTOPTS()							\
24393da997eSAli Mashtizadeh 	do {									\
24493da997eSAli Mashtizadeh 		printf("Filter Options:\n");					\
24593da997eSAli Mashtizadeh 		printf("\t-t,--lwps         Filter by thread id\n");		\
24693da997eSAli Mashtizadeh 		printf("\t-p,--pids         Filter by process id\n");		\
24793da997eSAli Mashtizadeh 		printf("\t-T,--threads      Filter by thread name\n");		\
24893da997eSAli Mashtizadeh 		printf("\t-P,--processes    Filter by process name\n");		\
24993da997eSAli Mashtizadeh 		printf("\t-e,--event        Filter by event\n");		\
25093da997eSAli Mashtizadeh 		printf("\t-c,--cpus         Filter by CPU id\n");		\
25193da997eSAli Mashtizadeh 		printf("\t-k,--kernel       Show only kernel events\n");	\
25293da997eSAli Mashtizadeh 		printf("\t-u,--user         Show only user events\n");		\
25393da997eSAli Mashtizadeh 		printf("\nIBS Fetch Options:\n");				\
25493da997eSAli Mashtizadeh 		printf("\t--ldlat           Filter by load latency\n");		\
25593da997eSAli Mashtizadeh 		printf("\nIBS Op Options:\n");					\
25693da997eSAli Mashtizadeh 		printf("\t--ldlat           Filter by load latency\n");		\
25793da997eSAli Mashtizadeh 		printf("\t--oplat           Filter by operation latency\n");	\
25893da997eSAli Mashtizadeh 		printf("\t--mmio            Show only mmio events\n");		\
25993da997eSAli Mashtizadeh 	} while (0)
26093da997eSAli Mashtizadeh #define PMCFILTER_LOPTS						\
26193da997eSAli Mashtizadeh 	{ "lwps",	required_argument,	NULL,	't' },	\
26293da997eSAli Mashtizadeh 	{ "pids",	required_argument,	NULL,	'p' },	\
26393da997eSAli Mashtizadeh 	{ "threads",	required_argument,	NULL,	'T' },	\
26493da997eSAli Mashtizadeh 	{ "processes",	required_argument,	NULL,	'P' },	\
26593da997eSAli Mashtizadeh 	{ "events",	required_argument,	NULL,	'e' },	\
26693da997eSAli Mashtizadeh 	{ "cpus",	required_argument,	NULL,	'c' },	\
26793da997eSAli Mashtizadeh 	{ "kernel",	no_argument,		NULL,	'k' },	\
26893da997eSAli Mashtizadeh 	{ "user",	no_argument,		NULL,	'u' },	\
26993da997eSAli Mashtizadeh 	{ "ldlat",	required_argument,	NULL,	10  },	\
27093da997eSAli Mashtizadeh 	{ "oplat",	required_argument,	NULL,	11  },	\
27193da997eSAli Mashtizadeh 	{ "mmio",	no_argument,		NULL,	12  }
27293da997eSAli Mashtizadeh #define PMCFILTER_SOPTS "t:p:T:P:e:c:ku"
27393da997eSAli Mashtizadeh #define PMCFILTER_CASE(_filt) \
27493da997eSAli Mashtizadeh 	case 't':						\
27593da997eSAli Mashtizadeh 		_filt.addtids(optarg);				\
27693da997eSAli Mashtizadeh 		break;						\
27793da997eSAli Mashtizadeh 	case 'p':						\
27893da997eSAli Mashtizadeh 		_filt.addpids(optarg);				\
27993da997eSAli Mashtizadeh 		break;						\
28093da997eSAli Mashtizadeh 	case 'T':						\
28193da997eSAli Mashtizadeh 		_filt.addthreads(optarg);			\
28293da997eSAli Mashtizadeh 		break;						\
28393da997eSAli Mashtizadeh 	case 'P':						\
28493da997eSAli Mashtizadeh 		_filt.addprograms(optarg);			\
28593da997eSAli Mashtizadeh 		break;						\
28693da997eSAli Mashtizadeh 	case 'e':						\
28793da997eSAli Mashtizadeh 		_filt.addevents(optarg);			\
28893da997eSAli Mashtizadeh 		break;						\
28993da997eSAli Mashtizadeh 	case 'c':						\
29093da997eSAli Mashtizadeh 		_filt.addcpus(optarg);				\
29193da997eSAli Mashtizadeh 		break;						\
29293da997eSAli Mashtizadeh 	case 'k':						\
29393da997eSAli Mashtizadeh 		_filt.kernelonly = true;			\
29493da997eSAli Mashtizadeh 		break;						\
29593da997eSAli Mashtizadeh 	case 'u':						\
29693da997eSAli Mashtizadeh 		_filt.useronly = true;			\
29793da997eSAli Mashtizadeh 		break;						\
29893da997eSAli Mashtizadeh 	case 10:						\
29993da997eSAli Mashtizadeh 		_filt.ibs_ldlat = atoi(optarg);			\
30093da997eSAli Mashtizadeh 		break;						\
30193da997eSAli Mashtizadeh 	case 11:						\
30293da997eSAli Mashtizadeh 		_filt.ibs_oplat = atoi(optarg);			\
30393da997eSAli Mashtizadeh 		break;						\
30493da997eSAli Mashtizadeh 	case 12:						\
30593da997eSAli Mashtizadeh 		_filt.ibs_mmio = true;				\
30693da997eSAli Mashtizadeh 		break;
30793da997eSAli Mashtizadeh 
30893da997eSAli Mashtizadeh struct ibsfetchinfo
30993da997eSAli Mashtizadeh {
31093da997eSAli Mashtizadeh 	int				len;
31193da997eSAli Mashtizadeh 	uint64_t			ctl;
31293da997eSAli Mashtizadeh 	uint64_t			extctl;
31393da997eSAli Mashtizadeh 	uint64_t			linaddr;
31493da997eSAli Mashtizadeh 	uint64_t			physaddr;
31593da997eSAli Mashtizadeh };
31693da997eSAli Mashtizadeh 
31793da997eSAli Mashtizadeh struct ibsopinfo
31893da997eSAli Mashtizadeh {
31993da997eSAli Mashtizadeh 	int				len;
32093da997eSAli Mashtizadeh 	uint64_t			ctl;
32193da997eSAli Mashtizadeh 	uint64_t			rip;
32293da997eSAli Mashtizadeh 	uint64_t			data;
32393da997eSAli Mashtizadeh 	uint64_t			data2;
32493da997eSAli Mashtizadeh 	uint64_t			data3;
32593da997eSAli Mashtizadeh 	uint64_t			linaddr;
32693da997eSAli Mashtizadeh 	uint64_t			physaddr;
32793da997eSAli Mashtizadeh 	uint64_t			tgtrip;
32893da997eSAli Mashtizadeh 	uint64_t			data4;
32993da997eSAli Mashtizadeh };
33093da997eSAli Mashtizadeh 
33193da997eSAli Mashtizadeh class pmcview
33293da997eSAli Mashtizadeh {
33393da997eSAli Mashtizadeh protected:
33493da997eSAli Mashtizadeh 	pmcview();
33593da997eSAli Mashtizadeh 	virtual ~pmcview();
33693da997eSAli Mashtizadeh public:
33793da997eSAli Mashtizadeh 	// Filter
33893da997eSAli Mashtizadeh 	void setfilter(const pmcfilter &pmcfilter);
33993da997eSAli Mashtizadeh 	// View Hooks
proccreate(__unused pid_t pid)34093da997eSAli Mashtizadeh 	virtual void proccreate(__unused pid_t pid) { };
procexec(__unused pid_t pid)34193da997eSAli Mashtizadeh 	virtual void procexec(__unused pid_t pid) { };
procexit(__unused pid_t pid)34293da997eSAli Mashtizadeh 	virtual void procexit(__unused pid_t pid) { };
callchain(struct pmclog_ev_callchain & p,__unused ibsfetchinfo & f,uintfptr_t * cc,int len)34393da997eSAli Mashtizadeh 	virtual void callchain(struct pmclog_ev_callchain &p,
34493da997eSAli Mashtizadeh 	    __unused ibsfetchinfo &f, uintfptr_t *cc, int len) {
34593da997eSAli Mashtizadeh 		callchain(p, cc, len);
34693da997eSAli Mashtizadeh 	}
callchain(struct pmclog_ev_callchain & p,__unused ibsopinfo & o,uintfptr_t * cc,int len)34793da997eSAli Mashtizadeh 	virtual void callchain(struct pmclog_ev_callchain &p,
34893da997eSAli Mashtizadeh 	    __unused ibsopinfo &o, uintfptr_t *cc, int len) {
34993da997eSAli Mashtizadeh 		callchain(p, cc, len);
35093da997eSAli Mashtizadeh 	}
callchain(struct pmclog_ev_callchain & p,__unused uintfptr_t * cc,__unused int len)35193da997eSAli Mashtizadeh 	virtual void callchain(struct pmclog_ev_callchain &p,
35293da997eSAli Mashtizadeh 	    __unused uintfptr_t *cc, __unused int len) {
35393da997eSAli Mashtizadeh 		callchain(p);
35493da997eSAli Mashtizadeh 	}
callchain(__unused struct pmclog_ev_callchain & p)35593da997eSAli Mashtizadeh 	virtual void callchain(__unused struct pmclog_ev_callchain &p) { }
35693da997eSAli Mashtizadeh 	// Console/File output
print()35793da997eSAli Mashtizadeh 	virtual void print() { };
35893da997eSAli Mashtizadeh 	virtual int process_sysinfo(int logfd, const pmchdr_infohdr &infohdr);
35993da997eSAli Mashtizadeh 	virtual int process_pmcinfo(int logfd, const pmchdr_infohdr &infohdr);
36093da997eSAli Mashtizadeh 	virtual int process_cpuidinfo(int logfd, const pmchdr_infohdr &infohdr);
36193da997eSAli Mashtizadeh 	// Process log
36293da997eSAli Mashtizadeh 	virtual void process(int logfd);
36393da997eSAli Mashtizadeh 	virtual void process(struct pmclog_ev &p);
36493da997eSAli Mashtizadeh 	virtual void process(struct pmclog_parse_state *ps);
36593da997eSAli Mashtizadeh 	// Generic events
36693da997eSAli Mashtizadeh 	virtual void process(struct pmclog_ev_initialize &p);
36793da997eSAli Mashtizadeh 	virtual void process(struct pmclog_ev_closelog &p);
36893da997eSAli Mashtizadeh 	virtual void process(struct pmclog_ev_pmcallocate &p);
36993da997eSAli Mashtizadeh 	virtual void process(struct pmclog_ev_pmcallocatedyn &p);
37093da997eSAli Mashtizadeh 	// Process events
37193da997eSAli Mashtizadeh 	virtual void process(struct pmclog_ev_proccreate &p);
37293da997eSAli Mashtizadeh 	virtual void process(struct pmclog_ev_procexit &p);
37393da997eSAli Mashtizadeh 	virtual void process(struct pmclog_ev_procexec &p);
37493da997eSAli Mashtizadeh 	virtual void process(struct pmclog_ev_procfork &p);
37593da997eSAli Mashtizadeh 	virtual void process(struct pmclog_ev_sysexit &p);
37693da997eSAli Mashtizadeh 	// Thread events
37793da997eSAli Mashtizadeh 	virtual void process(struct pmclog_ev_threadcreate &p);
37893da997eSAli Mashtizadeh 	virtual void process(struct pmclog_ev_threadexit &p);
37993da997eSAli Mashtizadeh 	// Map events
38093da997eSAli Mashtizadeh 	virtual void process(struct pmclog_ev_map_in &p);
38193da997eSAli Mashtizadeh 	virtual void process(struct pmclog_ev_map_out &p);
38293da997eSAli Mashtizadeh 	// Callchain events
38393da997eSAli Mashtizadeh 	virtual void process(struct pmclog_ev_callchain &p);
38493da997eSAli Mashtizadeh protected:
38593da997eSAli Mashtizadeh 	// Helper functions for views
38693da997eSAli Mashtizadeh 	uint32_t pmcidtoeventid(uint32_t pmcid);
38793da997eSAli Mashtizadeh 	std::string pidtoname(pid_t pid);
38893da997eSAli Mashtizadeh 	syminfo addrtosymbol(pid_t pid, uint64_t addr);
38993da997eSAli Mashtizadeh 	void printvm(pid_t pid);
39093da997eSAli Mashtizadeh 	// Fields available to views
39193da997eSAli Mashtizadeh 	uint64_t				tscfreq;
39293da997eSAli Mashtizadeh 	std::unordered_map<uint32_t, uint32_t>	pmcid;
393fd809148SEnji Cooper 	std::unordered_map<uint32_t, struct pmcinfo> pmcinfo;
394fd809148SEnji Cooper 	std::unordered_map<pid_t, struct procinfo> procs;
39593da997eSAli Mashtizadeh 	std::unordered_map<pid_t, pid_t>	tidtopid;
39693da997eSAli Mashtizadeh 	std::unordered_map<std::string, image>	images;
39793da997eSAli Mashtizadeh 	std::string				sysroot;
39893da997eSAli Mashtizadeh 	pmcfilter				filter;
39993da997eSAli Mashtizadeh 	// Extended info
40093da997eSAli Mashtizadeh 	int					arch;
40193da997eSAli Mashtizadeh 	std::string				cpumodel;
40293da997eSAli Mashtizadeh 	std::string				osrelease;
40393da997eSAli Mashtizadeh 	std::string				buildid;
404fd809148SEnji Cooper 	std::vector<struct pmcinfox>		extpmcinfo;
405fd809148SEnji Cooper 	std::map<uint32_t, struct cpuidleaf>	cpuid; // x86 Only
40693da997eSAli Mashtizadeh private:
40793da997eSAli Mashtizadeh 	image loadimage(const std::string &path);
40893da997eSAli Mashtizadeh 	void mapimage(pid_t pid, const image &im, uint64_t linkaddr);
40993da997eSAli Mashtizadeh 	void loadsymboltable(image *im, Elf *e, Elf_Scn *scn, GElf_Shdr *sh);
41093da997eSAli Mashtizadeh 	void loadsymbols(image *im);
41193da997eSAli Mashtizadeh };
41293da997eSAli Mashtizadeh 
41393da997eSAli Mashtizadeh #endif /* __VIEW_HH__ */
414