1203790Sfabient/*-
2203790Sfabient * Copyright (c) 2005-2007, Joseph Koshy
3203790Sfabient * Copyright (c) 2007 The FreeBSD Foundation
4203790Sfabient * Copyright (c) 2009, Fabien Thomas
5203790Sfabient * All rights reserved.
6203790Sfabient *
7203790Sfabient * Portions of this software were developed by A. Joseph Koshy under
8203790Sfabient * sponsorship from the FreeBSD Foundation and Google, Inc.
9203790Sfabient *
10203790Sfabient * Redistribution and use in source and binary forms, with or without
11203790Sfabient * modification, are permitted provided that the following conditions
12203790Sfabient * are met:
13203790Sfabient * 1. Redistributions of source code must retain the above copyright
14203790Sfabient *    notice, this list of conditions and the following disclaimer.
15203790Sfabient * 2. Redistributions in binary form must reproduce the above copyright
16203790Sfabient *    notice, this list of conditions and the following disclaimer in the
17203790Sfabient *    documentation and/or other materials provided with the distribution.
18203790Sfabient *
19203790Sfabient * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20203790Sfabient * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21203790Sfabient * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22203790Sfabient * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23203790Sfabient * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24203790Sfabient * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25203790Sfabient * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26203790Sfabient * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27203790Sfabient * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28203790Sfabient * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29203790Sfabient * SUCH DAMAGE.
30203790Sfabient *
31203790Sfabient * $FreeBSD$
32203790Sfabient */
33203790Sfabient
34203790Sfabient#ifndef	_PMCSTAT_LOG_H_
35203790Sfabient#define	_PMCSTAT_LOG_H_
36203790Sfabient
37203790Sfabienttypedef const void *pmcstat_interned_string;
38203790Sfabient
39203790Sfabient/*
40203790Sfabient * A 'pmcstat_process' structure models processes.  Each process is
41203790Sfabient * associated with a set of pmcstat_pcmap structures that map
42203790Sfabient * addresses inside it to executable objects.  This set is implemented
43203790Sfabient * as a list, kept sorted in ascending order of mapped addresses.
44203790Sfabient *
45203790Sfabient * 'pp_pid' holds the pid of the process.  When a process exits, the
46203790Sfabient * 'pp_isactive' field is set to zero, but the process structure is
47203790Sfabient * not immediately reclaimed because there may still be samples in the
48203790Sfabient * log for this process.
49203790Sfabient */
50203790Sfabient
51203790Sfabientstruct pmcstat_process {
52203790Sfabient	LIST_ENTRY(pmcstat_process) pp_next;	/* hash-next */
53203790Sfabient	pid_t			pp_pid;		/* associated pid */
54203790Sfabient	int			pp_isactive;	/* whether active */
55203790Sfabient	uintfptr_t		pp_entryaddr;	/* entry address */
56203790Sfabient	TAILQ_HEAD(,pmcstat_pcmap) pp_map;	/* address range map */
57203790Sfabient};
58203790Sfabientextern LIST_HEAD(pmcstat_process_hash_list, pmcstat_process) pmcstat_process_hash[PMCSTAT_NHASH];
59203790Sfabient
60203790Sfabient/*
61203790Sfabient * A 'pmcstat_image' structure describes an executable program on
62203790Sfabient * disk.  'pi_execpath' is a cookie representing the pathname of
63203790Sfabient * the executable.  'pi_start' and 'pi_end' are the least and greatest
64203790Sfabient * virtual addresses for the text segments in the executable.
65203790Sfabient * 'pi_gmonlist' contains a linked list of gmon.out files associated
66203790Sfabient * with this image.
67203790Sfabient */
68203790Sfabient
69203790Sfabientenum pmcstat_image_type {
70203790Sfabient	PMCSTAT_IMAGE_UNKNOWN = 0,	/* never looked at the image */
71203790Sfabient	PMCSTAT_IMAGE_INDETERMINABLE,	/* can't tell what the image is */
72203790Sfabient	PMCSTAT_IMAGE_ELF32,		/* ELF 32 bit object */
73203790Sfabient	PMCSTAT_IMAGE_ELF64,		/* ELF 64 bit object */
74203790Sfabient	PMCSTAT_IMAGE_AOUT		/* AOUT object */
75203790Sfabient};
76203790Sfabient
77203790Sfabientstruct pmcstat_image {
78203790Sfabient	LIST_ENTRY(pmcstat_image) pi_next;	/* hash link */
79203790Sfabient	TAILQ_ENTRY(pmcstat_image) pi_lru;	/* LRU list */
80203790Sfabient	pmcstat_interned_string	pi_execpath;    /* cookie */
81203790Sfabient	pmcstat_interned_string pi_samplename;  /* sample path name */
82203790Sfabient	pmcstat_interned_string pi_fullpath;    /* path to FS object */
83203790Sfabient	pmcstat_interned_string pi_name;	/* display name */
84203790Sfabient
85203790Sfabient	enum pmcstat_image_type pi_type;	/* executable type */
86203790Sfabient
87203790Sfabient	/*
88203790Sfabient	 * Executables have pi_start and pi_end; these are zero
89203790Sfabient	 * for shared libraries.
90203790Sfabient	 */
91203790Sfabient	uintfptr_t	pi_start;	/* start address (inclusive) */
92203790Sfabient	uintfptr_t	pi_end;		/* end address (exclusive) */
93203790Sfabient	uintfptr_t	pi_entry;	/* entry address */
94203790Sfabient	uintfptr_t	pi_vaddr;	/* virtual address where loaded */
95203790Sfabient	int		pi_isdynamic;	/* whether a dynamic object */
96203790Sfabient	int		pi_iskernelmodule;
97203790Sfabient	pmcstat_interned_string pi_dynlinkerpath; /* path in .interp */
98203790Sfabient
99203790Sfabient	/* All symbols associated with this object. */
100203790Sfabient	struct pmcstat_symbol *pi_symbols;
101203790Sfabient	size_t		pi_symcount;
102203790Sfabient
103203790Sfabient	/* Handle to addr2line for this image. */
104203790Sfabient	FILE *pi_addr2line;
105203790Sfabient
106203790Sfabient	/*
107203790Sfabient	 * Plugins private data
108203790Sfabient	 */
109203790Sfabient
110203790Sfabient	/* gprof:
111203790Sfabient	 * An image can be associated with one or more gmon.out files;
112203790Sfabient	 * one per PMC.
113203790Sfabient	 */
114203790Sfabient	LIST_HEAD(,pmcstat_gmonfile) pi_gmlist;
115203790Sfabient};
116203790Sfabientextern LIST_HEAD(pmcstat_image_hash_list, pmcstat_image) pmcstat_image_hash[PMCSTAT_NHASH];
117203790Sfabient
118203790Sfabient/*
119203790Sfabient * A 'pmcstat_pcmap' structure maps a virtual address range to an
120203790Sfabient * underlying 'pmcstat_image' descriptor.
121203790Sfabient */
122203790Sfabientstruct pmcstat_pcmap {
123203790Sfabient	TAILQ_ENTRY(pmcstat_pcmap) ppm_next;
124203790Sfabient	uintfptr_t	ppm_lowpc;
125203790Sfabient	uintfptr_t	ppm_highpc;
126203790Sfabient	struct pmcstat_image *ppm_image;
127203790Sfabient};
128203790Sfabient
129203790Sfabient/*
130203790Sfabient * Each function symbol tracked by pmcstat(8).
131203790Sfabient */
132203790Sfabient
133203790Sfabientstruct pmcstat_symbol {
134203790Sfabient	pmcstat_interned_string ps_name;
135203790Sfabient	uint64_t	ps_start;
136203790Sfabient	uint64_t	ps_end;
137203790Sfabient};
138203790Sfabient
139203790Sfabient/*
140203790Sfabient * 'pmcstat_pmcrecord' is a mapping from PMC ids to human-readable
141203790Sfabient * names.
142203790Sfabient */
143203790Sfabient
144203790Sfabientstruct pmcstat_pmcrecord {
145203790Sfabient	LIST_ENTRY(pmcstat_pmcrecord)	pr_next;
146203790Sfabient	pmc_id_t			pr_pmcid;
147203790Sfabient	int				pr_pmcin;
148203790Sfabient	pmcstat_interned_string		pr_pmcname;
149206090Sfabient	int				pr_samples;
150206090Sfabient	int				pr_dubious_frames;
151203790Sfabient	struct pmcstat_pmcrecord	*pr_merge;
152203790Sfabient};
153203790Sfabientextern LIST_HEAD(pmcstat_pmcs, pmcstat_pmcrecord) pmcstat_pmcs; /* PMC list */
154203790Sfabient
155203790Sfabient/*
156203790Sfabient * Misc. statistics
157203790Sfabient */
158203790Sfabientstruct pmcstat_stats {
159203790Sfabient	int ps_exec_aout;	/* # a.out executables seen */
160203790Sfabient	int ps_exec_elf;	/* # elf executables seen */
161203790Sfabient	int ps_exec_errors;	/* # errors processing executables */
162203790Sfabient	int ps_exec_indeterminable; /* # unknown executables seen */
163203790Sfabient	int ps_samples_total;	/* total number of samples processed */
164203790Sfabient	int ps_samples_skipped; /* #samples filtered out for any reason */
165203790Sfabient	int ps_samples_unknown_offset;	/* #samples of rank 0 not in a map */
166203790Sfabient	int ps_samples_indeterminable;	/* #samples in indeterminable images */
167212176Sfabient	int ps_samples_unknown_function;/* #samples with unknown function at offset */
168203790Sfabient	int ps_callchain_dubious_frames;/* #dubious frame pointers seen */
169203790Sfabient};
170203790Sfabientextern struct pmcstat_stats pmcstat_stats; /* statistics */
171203790Sfabient
172203790Sfabientextern struct pmcstat_process *pmcstat_kernproc; /* kernel 'process' */
173203790Sfabient
174203790Sfabientextern int pmcstat_npmcs; /* PMC count. */
175203790Sfabient
176203790Sfabient/*
177203790Sfabient * Top mode global options.
178203790Sfabient */
179241737Sedextern float pmcstat_threshold; /* Threshold to filter node. */
180241737Sedextern int pmcstat_pmcinfilter; /* PMC index displayed. */
181203790Sfabient
182203790Sfabient/* Function prototypes */
183203790Sfabientconst char *pmcstat_pmcid_to_name(pmc_id_t _pmcid);
184203790Sfabientconst char *pmcstat_pmcindex_to_name(int pmcin);
185203790Sfabientstruct pmcstat_pmcrecord *pmcstat_pmcindex_to_pmcr(int pmcin);
186203790Sfabientstruct pmcstat_pcmap *pmcstat_process_find_map(struct pmcstat_process *_p,
187203790Sfabient	uintfptr_t _pc);
188203790Sfabientstruct pmcstat_symbol *pmcstat_symbol_search(struct pmcstat_image *image,
189203790Sfabient	uintfptr_t addr);
190203790Sfabientconst char *pmcstat_string_unintern(pmcstat_interned_string _is);
191203790Sfabientpmcstat_interned_string pmcstat_string_intern(const char *_s);
192203790Sfabientvoid pmcstat_image_determine_type(struct pmcstat_image *_image);
193203790Sfabientpmcstat_interned_string pmcstat_string_lookup(const char *_s);
194203790Sfabientint pmcstat_image_addr2line(struct pmcstat_image *image, uintfptr_t addr,
195203790Sfabient    char *sourcefile, size_t sourcefile_len, unsigned *sourceline,
196203790Sfabient    char *funcname, size_t funcname_len);
197203790Sfabient
198203790Sfabient#endif	/* _PMCSTAT_LOG_H_ */
199203790Sfabient
200