1/*-
2 * Copyright (c) 2005-2007, Joseph Koshy
3 * Copyright (c) 2007 The FreeBSD Foundation
4 * Copyright (c) 2009, Fabien Thomas
5 * All rights reserved.
6 *
7 * Portions of this software were developed by A. Joseph Koshy under
8 * sponsorship from the FreeBSD Foundation and Google, Inc.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 *
31 * $FreeBSD$
32 */
33
34#ifndef	_PMCSTAT_LOG_H_
35#define	_PMCSTAT_LOG_H_
36
37typedef const void *pmcstat_interned_string;
38
39/*
40 * A 'pmcstat_process' structure models processes.  Each process is
41 * associated with a set of pmcstat_pcmap structures that map
42 * addresses inside it to executable objects.  This set is implemented
43 * as a list, kept sorted in ascending order of mapped addresses.
44 *
45 * 'pp_pid' holds the pid of the process.  When a process exits, the
46 * 'pp_isactive' field is set to zero, but the process structure is
47 * not immediately reclaimed because there may still be samples in the
48 * log for this process.
49 */
50
51struct pmcstat_process {
52	LIST_ENTRY(pmcstat_process) pp_next;	/* hash-next */
53	pid_t			pp_pid;		/* associated pid */
54	int			pp_isactive;	/* whether active */
55	uintfptr_t		pp_entryaddr;	/* entry address */
56	TAILQ_HEAD(,pmcstat_pcmap) pp_map;	/* address range map */
57};
58extern LIST_HEAD(pmcstat_process_hash_list, pmcstat_process) pmcstat_process_hash[PMCSTAT_NHASH];
59
60/*
61 * A 'pmcstat_image' structure describes an executable program on
62 * disk.  'pi_execpath' is a cookie representing the pathname of
63 * the executable.  'pi_start' and 'pi_end' are the least and greatest
64 * virtual addresses for the text segments in the executable.
65 * 'pi_gmonlist' contains a linked list of gmon.out files associated
66 * with this image.
67 */
68
69enum pmcstat_image_type {
70	PMCSTAT_IMAGE_UNKNOWN = 0,	/* never looked at the image */
71	PMCSTAT_IMAGE_INDETERMINABLE,	/* can't tell what the image is */
72	PMCSTAT_IMAGE_ELF32,		/* ELF 32 bit object */
73	PMCSTAT_IMAGE_ELF64,		/* ELF 64 bit object */
74	PMCSTAT_IMAGE_AOUT		/* AOUT object */
75};
76
77struct pmcstat_image {
78	LIST_ENTRY(pmcstat_image) pi_next;	/* hash link */
79	TAILQ_ENTRY(pmcstat_image) pi_lru;	/* LRU list */
80	pmcstat_interned_string	pi_execpath;    /* cookie */
81	pmcstat_interned_string pi_samplename;  /* sample path name */
82	pmcstat_interned_string pi_fullpath;    /* path to FS object */
83	pmcstat_interned_string pi_name;	/* display name */
84
85	enum pmcstat_image_type pi_type;	/* executable type */
86
87	/*
88	 * Executables have pi_start and pi_end; these are zero
89	 * for shared libraries.
90	 */
91	uintfptr_t	pi_start;	/* start address (inclusive) */
92	uintfptr_t	pi_end;		/* end address (exclusive) */
93	uintfptr_t	pi_entry;	/* entry address */
94	uintfptr_t	pi_vaddr;	/* virtual address where loaded */
95	int		pi_isdynamic;	/* whether a dynamic object */
96	int		pi_iskernelmodule;
97	pmcstat_interned_string pi_dynlinkerpath; /* path in .interp */
98
99	/* All symbols associated with this object. */
100	struct pmcstat_symbol *pi_symbols;
101	size_t		pi_symcount;
102
103	/* Handle to addr2line for this image. */
104	FILE *pi_addr2line;
105
106	/*
107	 * Plugins private data
108	 */
109
110	/* gprof:
111	 * An image can be associated with one or more gmon.out files;
112	 * one per PMC.
113	 */
114	LIST_HEAD(,pmcstat_gmonfile) pi_gmlist;
115};
116extern LIST_HEAD(pmcstat_image_hash_list, pmcstat_image) pmcstat_image_hash[PMCSTAT_NHASH];
117
118/*
119 * A 'pmcstat_pcmap' structure maps a virtual address range to an
120 * underlying 'pmcstat_image' descriptor.
121 */
122struct pmcstat_pcmap {
123	TAILQ_ENTRY(pmcstat_pcmap) ppm_next;
124	uintfptr_t	ppm_lowpc;
125	uintfptr_t	ppm_highpc;
126	struct pmcstat_image *ppm_image;
127};
128
129/*
130 * Each function symbol tracked by pmcstat(8).
131 */
132
133struct pmcstat_symbol {
134	pmcstat_interned_string ps_name;
135	uint64_t	ps_start;
136	uint64_t	ps_end;
137};
138
139/*
140 * 'pmcstat_pmcrecord' is a mapping from PMC ids to human-readable
141 * names.
142 */
143
144struct pmcstat_pmcrecord {
145	LIST_ENTRY(pmcstat_pmcrecord)	pr_next;
146	pmc_id_t			pr_pmcid;
147	int				pr_pmcin;
148	pmcstat_interned_string		pr_pmcname;
149	int				pr_samples;
150	int				pr_dubious_frames;
151	struct pmcstat_pmcrecord	*pr_merge;
152};
153extern LIST_HEAD(pmcstat_pmcs, pmcstat_pmcrecord) pmcstat_pmcs; /* PMC list */
154
155/*
156 * Misc. statistics
157 */
158struct pmcstat_stats {
159	int ps_exec_aout;	/* # a.out executables seen */
160	int ps_exec_elf;	/* # elf executables seen */
161	int ps_exec_errors;	/* # errors processing executables */
162	int ps_exec_indeterminable; /* # unknown executables seen */
163	int ps_samples_total;	/* total number of samples processed */
164	int ps_samples_skipped; /* #samples filtered out for any reason */
165	int ps_samples_unknown_offset;	/* #samples of rank 0 not in a map */
166	int ps_samples_indeterminable;	/* #samples in indeterminable images */
167	int ps_samples_unknown_function;/* #samples with unknown function at offset */
168	int ps_callchain_dubious_frames;/* #dubious frame pointers seen */
169};
170extern struct pmcstat_stats pmcstat_stats; /* statistics */
171
172extern struct pmcstat_process *pmcstat_kernproc; /* kernel 'process' */
173
174extern int pmcstat_npmcs; /* PMC count. */
175
176/*
177 * Top mode global options.
178 */
179float pmcstat_threshold; /* Threshold to filter node. */
180int pmcstat_pmcinfilter; /* PMC index displayed. */
181
182/* Function prototypes */
183const char *pmcstat_pmcid_to_name(pmc_id_t _pmcid);
184const char *pmcstat_pmcindex_to_name(int pmcin);
185struct pmcstat_pmcrecord *pmcstat_pmcindex_to_pmcr(int pmcin);
186struct pmcstat_pcmap *pmcstat_process_find_map(struct pmcstat_process *_p,
187	uintfptr_t _pc);
188struct pmcstat_symbol *pmcstat_symbol_search(struct pmcstat_image *image,
189	uintfptr_t addr);
190const char *pmcstat_string_unintern(pmcstat_interned_string _is);
191pmcstat_interned_string pmcstat_string_intern(const char *_s);
192void pmcstat_image_determine_type(struct pmcstat_image *_image);
193pmcstat_interned_string pmcstat_string_lookup(const char *_s);
194int pmcstat_image_addr2line(struct pmcstat_image *image, uintfptr_t addr,
195    char *sourcefile, size_t sourcefile_len, unsigned *sourceline,
196    char *funcname, size_t funcname_len);
197
198#endif	/* _PMCSTAT_LOG_H_ */
199
200