pmcstat_log.c revision 174396
1/*-
2 * Copyright (c) 2005-2007, Joseph Koshy
3 * Copyright (c) 2007 The FreeBSD Foundation
4 * All rights reserved.
5 *
6 * Portions of this software were developed by A. Joseph Koshy under
7 * sponsorship from the FreeBSD Foundation and Google, Inc.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 *    notice, this list of conditions and the following disclaimer in the
16 *    documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31/*
32 * Transform a hwpmc(4) log into human readable form, and into
33 * gprof(1) compatible profiles.
34 */
35
36#include <sys/cdefs.h>
37__FBSDID("$FreeBSD: head/usr.sbin/pmcstat/pmcstat_log.c 174396 2007-12-07 08:26:21Z jkoshy $");
38
39#include <sys/param.h>
40#include <sys/endian.h>
41#include <sys/gmon.h>
42#include <sys/imgact_aout.h>
43#include <sys/imgact_elf.h>
44#include <sys/mman.h>
45#include <sys/pmc.h>
46#include <sys/queue.h>
47#include <sys/socket.h>
48#include <sys/stat.h>
49#include <sys/wait.h>
50
51#include <netinet/in.h>
52
53#include <assert.h>
54#include <err.h>
55#include <errno.h>
56#include <fcntl.h>
57#include <gelf.h>
58#include <libgen.h>
59#include <limits.h>
60#include <netdb.h>
61#include <pmc.h>
62#include <pmclog.h>
63#include <sysexits.h>
64#include <stdint.h>
65#include <stdio.h>
66#include <stdlib.h>
67#include <string.h>
68#include <unistd.h>
69
70#include "pmcstat.h"
71
72#define	min(A,B)		((A) < (B) ? (A) : (B))
73#define	max(A,B)		((A) > (B) ? (A) : (B))
74
75#define	PMCSTAT_ALLOCATE		1
76
77/*
78 * PUBLIC INTERFACES
79 *
80 * pmcstat_initialize_logging()	initialize this module, called first
81 * pmcstat_shutdown_logging()		orderly shutdown, called last
82 * pmcstat_open_log()			open an eventlog for processing
83 * pmcstat_process_log()		print/convert an event log
84 * pmcstat_close_log()			finish processing an event log
85 *
86 * IMPLEMENTATION NOTES
87 *
88 * We correlate each 'callchain' or 'sample' entry seen in the event
89 * log back to an executable object in the system. Executable objects
90 * include:
91 * 	- program executables,
92 *	- shared libraries loaded by the runtime loader,
93 *	- dlopen()'ed objects loaded by the program,
94 *	- the runtime loader itself,
95 *	- the kernel and kernel modules.
96 *
97 * Each process that we know about is treated as a set of regions that
98 * map to executable objects.  Processes are described by
99 * 'pmcstat_process' structures.  Executable objects are tracked by
100 * 'pmcstat_image' structures.  The kernel and kernel modules are
101 * common to all processes (they reside at the same virtual addresses
102 * for all processes).  Individual processes can have their text
103 * segments and shared libraries loaded at process-specific locations.
104 *
105 * A given executable object can be in use by multiple processes
106 * (e.g., libc.so) and loaded at a different address in each.
107 * pmcstat_pcmap structures track per-image mappings.
108 *
109 * The sample log could have samples from multiple PMCs; we
110 * generate one 'gmon.out' profile per PMC.
111 *
112 * IMPLEMENTATION OF GMON OUTPUT
113 *
114 * Each executable object gets one 'gmon.out' profile, per PMC in
115 * use.  Creation of 'gmon.out' profiles is done lazily.  The
116 * 'gmon.out' profiles generated for a given sampling PMC are
117 * aggregates of all the samples for that particular executable
118 * object.
119 *
120 * IMPLEMENTATION OF SYSTEM-WIDE CALLGRAPH OUTPUT
121 *
122 * Each active pmcid has its own callgraph structure, described by a
123 * 'struct pmcstat_callgraph'.  Given a process id and a list of pc
124 * values, we map each pc value to a tuple (image, symbol), where
125 * 'image' denotes an executable object and 'symbol' is the closest
126 * symbol that precedes the pc value.  Each pc value in the list is
127 * also given a 'rank' that reflects its depth in the call stack.
128 */
129
130typedef const void *pmcstat_interned_string;
131
132/*
133 * 'pmcstat_pmcrecord' is a mapping from PMC ids to human-readable
134 * names.
135 */
136
137struct pmcstat_pmcrecord {
138	LIST_ENTRY(pmcstat_pmcrecord)	pr_next;
139	pmc_id_t			pr_pmcid;
140	pmcstat_interned_string	pr_pmcname;
141};
142
143static LIST_HEAD(,pmcstat_pmcrecord)	pmcstat_pmcs =
144	LIST_HEAD_INITIALIZER(&pmcstat_pmcs);
145
146
147/*
148 * struct pmcstat_gmonfile tracks a given 'gmon.out' file.  These
149 * files are mmap()'ed in as needed.
150 */
151
152struct pmcstat_gmonfile {
153	LIST_ENTRY(pmcstat_gmonfile)	pgf_next; /* list of entries */
154	int		pgf_overflow;	/* whether a count overflowed */
155	pmc_id_t	pgf_pmcid;	/* id of the associated pmc */
156	size_t		pgf_nbuckets;	/* #buckets in this gmon.out */
157	unsigned int	pgf_nsamples;	/* #samples in this gmon.out */
158	pmcstat_interned_string pgf_name;	/* pathname of gmon.out file */
159	size_t		pgf_ndatabytes;	/* number of bytes mapped */
160	void		*pgf_gmondata;	/* pointer to mmap'ed data */
161	FILE		*pgf_file;	/* used when writing gmon arcs */
162};
163
164/*
165 * A 'pmcstat_image' structure describes an executable program on
166 * disk.  'pi_execpath' is a cookie representing the pathname of
167 * the executable.  'pi_start' and 'pi_end' are the least and greatest
168 * virtual addresses for the text segments in the executable.
169 * 'pi_gmonlist' contains a linked list of gmon.out files associated
170 * with this image.
171 */
172
173enum pmcstat_image_type {
174	PMCSTAT_IMAGE_UNKNOWN = 0,	/* never looked at the image */
175	PMCSTAT_IMAGE_INDETERMINABLE,	/* can't tell what the image is */
176	PMCSTAT_IMAGE_ELF32,		/* ELF 32 bit object */
177	PMCSTAT_IMAGE_ELF64,		/* ELF 64 bit object */
178	PMCSTAT_IMAGE_AOUT		/* AOUT object */
179};
180
181struct pmcstat_image {
182	LIST_ENTRY(pmcstat_image) pi_next;	/* hash link */
183	TAILQ_ENTRY(pmcstat_image) pi_lru;	/* LRU list */
184	pmcstat_interned_string	pi_execpath;    /* cookie */
185	pmcstat_interned_string pi_samplename;  /* sample path name */
186	pmcstat_interned_string pi_fullpath;    /* path to FS object */
187
188	enum pmcstat_image_type pi_type;	/* executable type */
189
190	/*
191	 * Executables have pi_start and pi_end; these are zero
192	 * for shared libraries.
193	 */
194	uintfptr_t	pi_start;	/* start address (inclusive) */
195	uintfptr_t	pi_end;		/* end address (exclusive) */
196	uintfptr_t	pi_entry;	/* entry address */
197	uintfptr_t	pi_vaddr;	/* virtual address where loaded */
198	int		pi_isdynamic;	/* whether a dynamic object */
199	int		pi_iskernelmodule;
200	pmcstat_interned_string pi_dynlinkerpath; /* path in .interp */
201
202	/* All symbols associated with this object. */
203	struct pmcstat_symbol *pi_symbols;
204	size_t		pi_symcount;
205
206	/*
207	 * An image can be associated with one or more gmon.out files;
208	 * one per PMC.
209	 */
210	LIST_HEAD(,pmcstat_gmonfile) pi_gmlist;
211};
212
213/*
214 * All image descriptors are kept in a hash table.
215 */
216static LIST_HEAD(,pmcstat_image)	pmcstat_image_hash[PMCSTAT_NHASH];
217
218/*
219 * A 'pmcstat_pcmap' structure maps a virtual address range to an
220 * underlying 'pmcstat_image' descriptor.
221 */
222struct pmcstat_pcmap {
223	TAILQ_ENTRY(pmcstat_pcmap) ppm_next;
224	uintfptr_t	ppm_lowpc;
225	uintfptr_t	ppm_highpc;
226	struct pmcstat_image *ppm_image;
227};
228
229/*
230 * A 'pmcstat_process' structure models processes.  Each process is
231 * associated with a set of pmcstat_pcmap structures that map
232 * addresses inside it to executable objects.  This set is implemented
233 * as a list, kept sorted in ascending order of mapped addresses.
234 *
235 * 'pp_pid' holds the pid of the process.  When a process exits, the
236 * 'pp_isactive' field is set to zero, but the process structure is
237 * not immediately reclaimed because there may still be samples in the
238 * log for this process.
239 */
240
241struct pmcstat_process {
242	LIST_ENTRY(pmcstat_process) pp_next;	/* hash-next */
243	pid_t			pp_pid;		/* associated pid */
244	int			pp_isactive;	/* whether active */
245	uintfptr_t		pp_entryaddr;	/* entry address */
246	TAILQ_HEAD(,pmcstat_pcmap) pp_map;	/* address range map */
247};
248
249/*
250 * All process descriptors are kept in a hash table.
251 */
252static LIST_HEAD(,pmcstat_process) pmcstat_process_hash[PMCSTAT_NHASH];
253
254static struct pmcstat_process *pmcstat_kernproc; /* kernel 'process' */
255
256/*
257 * Each function symbol tracked by pmcstat(8).
258 */
259
260struct pmcstat_symbol {
261	pmcstat_interned_string ps_name;
262	uint64_t	ps_start;
263	uint64_t	ps_end;
264};
265
266/*
267 * Each call graph node is tracked by a pmcstat_cgnode struct.
268 */
269
270struct pmcstat_cgnode {
271	struct pmcstat_image	*pcg_image;
272	uintfptr_t		pcg_func;
273	uint32_t		pcg_count;
274	uint32_t		pcg_nchildren;
275	LIST_ENTRY(pmcstat_cgnode) pcg_sibling;
276	LIST_HEAD(,pmcstat_cgnode) pcg_children;
277};
278
279struct pmcstat_cgnode_hash {
280	struct pmcstat_cgnode  *pch_cgnode;
281	uint32_t		pch_pmcid;
282	LIST_ENTRY(pmcstat_cgnode_hash) pch_next;
283};
284
285static int pmcstat_cgnode_hash_count;
286static pmcstat_interned_string pmcstat_previous_filename_printed;
287
288/*
289 * The toplevel CG nodes (i.e., with rank == 0) are placed in a hash table.
290 */
291
292static LIST_HEAD(,pmcstat_cgnode_hash) pmcstat_cgnode_hash[PMCSTAT_NHASH];
293
294/* Misc. statistics */
295static struct pmcstat_stats {
296	int ps_exec_aout;	/* # a.out executables seen */
297	int ps_exec_elf;	/* # elf executables seen */
298	int ps_exec_errors;	/* # errors processing executables */
299	int ps_exec_indeterminable; /* # unknown executables seen */
300	int ps_samples_total;	/* total number of samples processed */
301	int ps_samples_skipped; /* #samples filtered out for any reason */
302	int ps_samples_unknown_offset;	/* #samples of rank 0 not in a map */
303	int ps_samples_indeterminable;	/* #samples in indeterminable images */
304	int ps_callchain_dubious_frames;/* #dubious frame pointers seen */
305} pmcstat_stats;
306
307
308/*
309 * Prototypes
310 */
311
312static void	pmcstat_gmon_create_file(struct pmcstat_gmonfile *_pgf,
313    struct pmcstat_image *_image);
314static pmcstat_interned_string pmcstat_gmon_create_name(const char *_sd,
315    struct pmcstat_image *_img, pmc_id_t _pmcid);
316static void	pmcstat_gmon_map_file(struct pmcstat_gmonfile *_pgf);
317static void	pmcstat_gmon_unmap_file(struct pmcstat_gmonfile *_pgf);
318
319static void pmcstat_image_determine_type(struct pmcstat_image *_image,
320    struct pmcstat_args *_a);
321static struct pmcstat_gmonfile *pmcstat_image_find_gmonfile(struct
322    pmcstat_image *_i, pmc_id_t _id);
323static struct pmcstat_image *pmcstat_image_from_path(pmcstat_interned_string
324    _path, int _iskernelmodule);
325static void pmcstat_image_get_aout_params(struct pmcstat_image *_image,
326    struct pmcstat_args *_a);
327static void pmcstat_image_get_elf_params(struct pmcstat_image *_image,
328    struct pmcstat_args *_a);
329static void	pmcstat_image_increment_bucket(struct pmcstat_pcmap *_pcm,
330    uintfptr_t _pc, pmc_id_t _pmcid, struct pmcstat_args *_a);
331static void	pmcstat_image_link(struct pmcstat_process *_pp,
332    struct pmcstat_image *_i, uintfptr_t _lpc);
333
334static void	pmcstat_pmcid_add(pmc_id_t _pmcid,
335    pmcstat_interned_string _name, struct pmcstat_args *_a);
336static const char *pmcstat_pmcid_to_name(pmc_id_t _pmcid);
337
338static void	pmcstat_process_aout_exec(struct pmcstat_process *_pp,
339    struct pmcstat_image *_image, uintfptr_t _entryaddr,
340    struct pmcstat_args *_a);
341static void	pmcstat_process_elf_exec(struct pmcstat_process *_pp,
342    struct pmcstat_image *_image, uintfptr_t _entryaddr,
343    struct pmcstat_args *_a);
344static void	pmcstat_process_exec(struct pmcstat_process *_pp,
345    pmcstat_interned_string _path, uintfptr_t _entryaddr,
346    struct pmcstat_args *_ao);
347static struct pmcstat_process *pmcstat_process_lookup(pid_t _pid,
348    int _allocate);
349static struct pmcstat_pcmap *pmcstat_process_find_map(
350    struct pmcstat_process *_p, uintfptr_t _pc);
351
352static int	pmcstat_string_compute_hash(const char *_string);
353static void pmcstat_string_initialize(void);
354static pmcstat_interned_string pmcstat_string_intern(const char *_s);
355static pmcstat_interned_string pmcstat_string_lookup(const char *_s);
356static int	pmcstat_string_lookup_hash(pmcstat_interned_string _is);
357static void pmcstat_string_shutdown(void);
358static const char *pmcstat_string_unintern(pmcstat_interned_string _is);
359
360
361/*
362 * A simple implementation of interned strings.  Each interned string
363 * is assigned a unique address, so that subsequent string compares
364 * can be done by a simple pointer comparision instead of using
365 * strcmp().  This speeds up hash table lookups and saves memory if
366 * duplicate strings are the norm.
367 */
368struct pmcstat_string {
369	LIST_ENTRY(pmcstat_string)	ps_next;	/* hash link */
370	int		ps_len;
371	int		ps_hash;
372	char		*ps_string;
373};
374
375static LIST_HEAD(,pmcstat_string)	pmcstat_string_hash[PMCSTAT_NHASH];
376
377/*
378 * Compute a 'hash' value for a string.
379 */
380
381static int
382pmcstat_string_compute_hash(const char *s)
383{
384	int hash;
385
386	for (hash = 0; *s; s++)
387		hash ^= *s;
388
389	return (hash & PMCSTAT_HASH_MASK);
390}
391
392/*
393 * Intern a copy of string 's', and return a pointer to the
394 * interned structure.
395 */
396
397static pmcstat_interned_string
398pmcstat_string_intern(const char *s)
399{
400	struct pmcstat_string *ps;
401	const struct pmcstat_string *cps;
402	int hash, len;
403
404	if ((cps = pmcstat_string_lookup(s)) != NULL)
405		return (cps);
406
407	hash = pmcstat_string_compute_hash(s);
408	len  = strlen(s);
409
410	if ((ps = malloc(sizeof(*ps))) == NULL)
411		err(EX_OSERR, "ERROR: Could not intern string");
412	ps->ps_len = len;
413	ps->ps_hash = hash;
414	ps->ps_string = strdup(s);
415	LIST_INSERT_HEAD(&pmcstat_string_hash[hash], ps, ps_next);
416	return ((pmcstat_interned_string) ps);
417}
418
419static const char *
420pmcstat_string_unintern(pmcstat_interned_string str)
421{
422	const char *s;
423
424	s = ((const struct pmcstat_string *) str)->ps_string;
425	return (s);
426}
427
428static pmcstat_interned_string
429pmcstat_string_lookup(const char *s)
430{
431	struct pmcstat_string *ps;
432	int hash, len;
433
434	hash = pmcstat_string_compute_hash(s);
435	len = strlen(s);
436
437	LIST_FOREACH(ps, &pmcstat_string_hash[hash], ps_next)
438	    if (ps->ps_len == len && ps->ps_hash == hash &&
439		strcmp(ps->ps_string, s) == 0)
440		    return (ps);
441	return (NULL);
442}
443
444static int
445pmcstat_string_lookup_hash(pmcstat_interned_string s)
446{
447	const struct pmcstat_string *ps;
448
449	ps = (const struct pmcstat_string *) s;
450	return (ps->ps_hash);
451}
452
453/*
454 * Initialize the string interning facility.
455 */
456
457static void
458pmcstat_string_initialize(void)
459{
460	int i;
461
462	for (i = 0; i < PMCSTAT_NHASH; i++)
463		LIST_INIT(&pmcstat_string_hash[i]);
464}
465
466/*
467 * Destroy the string table, free'ing up space.
468 */
469
470static void
471pmcstat_string_shutdown(void)
472{
473	int i;
474	struct pmcstat_string *ps, *pstmp;
475
476	for (i = 0; i < PMCSTAT_NHASH; i++)
477		LIST_FOREACH_SAFE(ps, &pmcstat_string_hash[i], ps_next,
478		    pstmp) {
479			LIST_REMOVE(ps, ps_next);
480			free(ps->ps_string);
481			free(ps);
482		}
483}
484
485/*
486 * Create a gmon.out file and size it.
487 */
488
489static void
490pmcstat_gmon_create_file(struct pmcstat_gmonfile *pgf,
491    struct pmcstat_image *image)
492{
493	int fd;
494	size_t count;
495	struct gmonhdr gm;
496	const char *pathname;
497	char buffer[DEFAULT_BUFFER_SIZE];
498
499	pathname = pmcstat_string_unintern(pgf->pgf_name);
500	if ((fd = open(pathname, O_RDWR|O_NOFOLLOW|O_CREAT,
501		 S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) < 0)
502		err(EX_OSERR, "ERROR: Cannot open \"%s\"", pathname);
503
504	gm.lpc = image->pi_start;
505	gm.hpc = image->pi_end;
506	gm.ncnt = (pgf->pgf_nbuckets * sizeof(HISTCOUNTER)) +
507	    sizeof(struct gmonhdr);
508	gm.version = GMONVERSION;
509	gm.profrate = 0;		/* use ticks */
510	gm.histcounter_type = 0;	/* compatibility with moncontrol() */
511	gm.spare[0] = gm.spare[1] = 0;
512
513	/* Write out the gmon header */
514	if (write(fd, &gm, sizeof(gm)) < 0)
515		goto error;
516
517	/* Zero fill the samples[] array */
518	(void) memset(buffer, 0, sizeof(buffer));
519
520	count = pgf->pgf_ndatabytes - sizeof(struct gmonhdr);
521	while (count > sizeof(buffer)) {
522		if (write(fd, &buffer, sizeof(buffer)) < 0)
523			goto error;
524		count -= sizeof(buffer);
525	}
526
527	if (write(fd, &buffer, count) < 0)
528		goto error;
529
530	(void) close(fd);
531
532	return;
533
534 error:
535	err(EX_OSERR, "ERROR: Cannot write \"%s\"", pathname);
536}
537
538/*
539 * Determine the full pathname of a gmon.out file for a given
540 * (image,pmcid) combination.  Return the interned string.
541 */
542
543pmcstat_interned_string
544pmcstat_gmon_create_name(const char *samplesdir, struct pmcstat_image *image,
545    pmc_id_t pmcid)
546{
547	const char *pmcname;
548	char fullpath[PATH_MAX];
549
550	pmcname = pmcstat_pmcid_to_name(pmcid);
551
552	(void) snprintf(fullpath, sizeof(fullpath),
553	    "%s/%s/%s", samplesdir, pmcname,
554	    pmcstat_string_unintern(image->pi_samplename));
555
556	return (pmcstat_string_intern(fullpath));
557}
558
559
560/*
561 * Mmap in a gmon.out file for processing.
562 */
563
564static void
565pmcstat_gmon_map_file(struct pmcstat_gmonfile *pgf)
566{
567	int fd;
568	const char *pathname;
569
570	pathname = pmcstat_string_unintern(pgf->pgf_name);
571
572	/* the gmon.out file must already exist */
573	if ((fd = open(pathname, O_RDWR | O_NOFOLLOW, 0)) < 0)
574		err(EX_OSERR, "ERROR: cannot open \"%s\"", pathname);
575
576	pgf->pgf_gmondata = mmap(NULL, pgf->pgf_ndatabytes,
577	    PROT_READ|PROT_WRITE, MAP_NOSYNC|MAP_SHARED, fd, 0);
578
579	if (pgf->pgf_gmondata == MAP_FAILED)
580		err(EX_OSERR, "ERROR: cannot map \"%s\"", pathname);
581
582	(void) close(fd);
583}
584
585/*
586 * Unmap a gmon.out file after sync'ing its data to disk.
587 */
588
589static void
590pmcstat_gmon_unmap_file(struct pmcstat_gmonfile *pgf)
591{
592	(void) msync(pgf->pgf_gmondata, pgf->pgf_ndatabytes,
593	    MS_SYNC);
594	(void) munmap(pgf->pgf_gmondata, pgf->pgf_ndatabytes);
595	pgf->pgf_gmondata = NULL;
596}
597
598static void
599pmcstat_gmon_append_arc(struct pmcstat_image *image, pmc_id_t pmcid,
600    uintptr_t rawfrom, uintptr_t rawto, uint32_t count)
601{
602	struct rawarc arc;	/* from <sys/gmon.h> */
603	const char *pathname;
604	struct pmcstat_gmonfile *pgf;
605
606	if ((pgf = pmcstat_image_find_gmonfile(image, pmcid)) == NULL)
607		return;
608
609	if (pgf->pgf_file == NULL) {
610		pathname = pmcstat_string_unintern(pgf->pgf_name);
611		if ((pgf->pgf_file = fopen(pathname, "a")) == NULL)
612			return;
613	}
614
615	arc.raw_frompc = rawfrom + image->pi_vaddr;
616	arc.raw_selfpc = rawto + image->pi_vaddr;
617	arc.raw_count = count;
618
619	(void) fwrite(&arc, sizeof(arc), 1, pgf->pgf_file);
620
621}
622
623static struct pmcstat_gmonfile *
624pmcstat_image_find_gmonfile(struct pmcstat_image *image, pmc_id_t pmcid)
625{
626	struct pmcstat_gmonfile *pgf;
627	LIST_FOREACH(pgf, &image->pi_gmlist, pgf_next)
628	    if (pgf->pgf_pmcid == pmcid)
629		    return (pgf);
630	return (NULL);
631}
632
633
634/*
635 * Determine whether a given executable image is an A.OUT object, and
636 * if so, fill in its parameters from the text file.
637 * Sets image->pi_type.
638 */
639
640static void
641pmcstat_image_get_aout_params(struct pmcstat_image *image,
642    struct pmcstat_args *a)
643{
644	int fd;
645	ssize_t nbytes;
646	struct exec ex;
647	const char *path;
648	char buffer[PATH_MAX];
649
650	path = pmcstat_string_unintern(image->pi_execpath);
651	assert(path != NULL);
652
653	if (image->pi_iskernelmodule)
654		errx(EX_SOFTWARE, "ERROR: a.out kernel modules are "
655		    "unsupported \"%s\"", path);
656
657	(void) snprintf(buffer, sizeof(buffer), "%s%s",
658	    a->pa_fsroot, path);
659
660	if ((fd = open(buffer, O_RDONLY, 0)) < 0 ||
661	    (nbytes = read(fd, &ex, sizeof(ex))) < 0) {
662		warn("WARNING: Cannot determine type of \"%s\"", path);
663		image->pi_type = PMCSTAT_IMAGE_INDETERMINABLE;
664		if (fd != -1)
665			(void) close(fd);
666		return;
667	}
668
669	(void) close(fd);
670
671	if ((unsigned) nbytes != sizeof(ex) ||
672	    N_BADMAG(ex))
673		return;
674
675	image->pi_type = PMCSTAT_IMAGE_AOUT;
676
677	/* TODO: the rest of a.out processing */
678
679	return;
680}
681
682/*
683 * Helper function.
684 */
685
686static int
687pmcstat_symbol_compare(const void *a, const void *b)
688{
689	const struct pmcstat_symbol *sym1, *sym2;
690
691	sym1 = (const struct pmcstat_symbol *) a;
692	sym2 = (const struct pmcstat_symbol *) b;
693
694	if (sym1->ps_end <= sym2->ps_start)
695		return (-1);
696	if (sym1->ps_start >= sym2->ps_end)
697		return (1);
698	return (0);
699}
700
701/*
702 * Map an address to a symbol in an image.
703 */
704
705static struct pmcstat_symbol *
706pmcstat_symbol_search(struct pmcstat_image *image, uintfptr_t addr)
707{
708	struct pmcstat_symbol sym;
709
710	if (image->pi_symbols == NULL)
711		return (NULL);
712
713	sym.ps_name  = NULL;
714	sym.ps_start = addr;
715	sym.ps_end   = addr + 1;
716
717	return (bsearch((void *) &sym, image->pi_symbols,
718		    image->pi_symcount, sizeof(struct pmcstat_symbol),
719		    pmcstat_symbol_compare));
720}
721
722/*
723 * Add the list of symbols in the given section to the list associated
724 * with the object.
725 */
726static void
727pmcstat_image_add_symbols(struct pmcstat_image *image, Elf *e,
728    Elf_Scn *scn, GElf_Shdr *sh)
729{
730	int firsttime;
731	size_t n, newsyms, nshsyms, nfuncsyms;
732	struct pmcstat_symbol *symptr;
733	char *fnname;
734	GElf_Sym sym;
735	Elf_Data *data;
736
737	if ((data = elf_getdata(scn, NULL)) == NULL)
738		return;
739
740	/*
741	 * Determine the number of functions named in this
742	 * section.
743	 */
744
745	nshsyms = sh->sh_size / sh->sh_entsize;
746	for (n = nfuncsyms = 0; n < nshsyms; n++) {
747		if (gelf_getsym(data, (int) n, &sym) != &sym)
748			return;
749		if (GELF_ST_TYPE(sym.st_info) == STT_FUNC)
750			nfuncsyms++;
751	}
752
753	if (nfuncsyms == 0)
754		return;
755
756	/*
757	 * Allocate space for the new entries.
758	 */
759	firsttime = image->pi_symbols == NULL;
760	symptr = realloc(image->pi_symbols,
761	    sizeof(*symptr) * (image->pi_symcount + nfuncsyms));
762	if (symptr == image->pi_symbols) /* realloc() failed. */
763		return;
764	image->pi_symbols = symptr;
765
766	/*
767	 * Append new symbols to the end of the current table.
768	 */
769	symptr += image->pi_symcount;
770
771	for (n = newsyms = 0; n < nshsyms; n++) {
772		if (gelf_getsym(data, (int) n, &sym) != &sym)
773			return;
774		if (GELF_ST_TYPE(sym.st_info) != STT_FUNC)
775			continue;
776
777		if (!firsttime && pmcstat_symbol_search(image, sym.st_value))
778			continue; /* We've seen this symbol already. */
779
780		if ((fnname = elf_strptr(e, sh->sh_link, sym.st_name))
781		    == NULL)
782			continue;
783
784		symptr->ps_name  = pmcstat_string_intern(fnname);
785		symptr->ps_start = sym.st_value - image->pi_vaddr;
786		symptr->ps_end   = symptr->ps_start + sym.st_size;
787		symptr++;
788
789		newsyms++;
790	}
791
792	image->pi_symcount += newsyms;
793
794	assert(newsyms <= nfuncsyms);
795
796	/*
797	 * Return space to the system if there were duplicates.
798	 */
799	if (newsyms < nfuncsyms)
800		image->pi_symbols = realloc(image->pi_symbols,
801		    sizeof(*symptr) * image->pi_symcount);
802
803	/*
804	 * Keep the list of symbols sorted.
805	 */
806	qsort(image->pi_symbols, image->pi_symcount, sizeof(*symptr),
807	    pmcstat_symbol_compare);
808
809	/*
810	 * Deal with function symbols that have a size of 'zero' by
811	 * making them extend to the next higher address.  These
812	 * symbols are usually defined in assembly code.
813	 */
814	for (symptr = image->pi_symbols;
815	     symptr < image->pi_symbols + (image->pi_symcount - 1);
816	     symptr++)
817		if (symptr->ps_start == symptr->ps_end)
818			symptr->ps_end = (symptr+1)->ps_start;
819}
820
821/*
822 * Examine an ELF file to determine the size of its text segment.
823 * Sets image->pi_type if anything conclusive can be determined about
824 * this image.
825 */
826
827static void
828pmcstat_image_get_elf_params(struct pmcstat_image *image,
829    struct pmcstat_args *a)
830{
831	int fd;
832	size_t i, nph, nsh;
833	const char *path, *elfbase;
834	uintfptr_t minva, maxva;
835	Elf *e;
836	Elf_Scn *scn;
837	GElf_Ehdr eh;
838	GElf_Phdr ph;
839	GElf_Shdr sh;
840	enum pmcstat_image_type image_type;
841	char buffer[PATH_MAX];
842
843	assert(image->pi_type == PMCSTAT_IMAGE_UNKNOWN);
844
845	image->pi_start = minva = ~(uintfptr_t) 0;
846	image->pi_end = maxva = (uintfptr_t) 0;
847	image->pi_type = image_type = PMCSTAT_IMAGE_INDETERMINABLE;
848	image->pi_isdynamic = 0;
849	image->pi_dynlinkerpath = NULL;
850	image->pi_vaddr = 0;
851
852	path = pmcstat_string_unintern(image->pi_execpath);
853	assert(path != NULL);
854
855	/*
856	 * Look for kernel modules under FSROOT/KERNELPATH/NAME,
857	 * and user mode executable objects under FSROOT/PATHNAME.
858	 */
859	if (image->pi_iskernelmodule)
860		(void) snprintf(buffer, sizeof(buffer), "%s%s/%s",
861		    a->pa_fsroot, a->pa_kernel, path);
862	else
863		(void) snprintf(buffer, sizeof(buffer), "%s%s",
864		    a->pa_fsroot, path);
865
866	e = NULL;
867	if ((fd = open(buffer, O_RDONLY, 0)) < 0 ||
868	    (e = elf_begin(fd, ELF_C_READ, NULL)) == NULL ||
869	    (elf_kind(e) != ELF_K_ELF)) {
870		warnx("WARNING: Cannot determine the type of \"%s\".",
871		    buffer);
872		goto done;
873	}
874
875	if (gelf_getehdr(e, &eh) != &eh) {
876		warnx("WARNING: Cannot retrieve the ELF Header for "
877		    "\"%s\": %s.", buffer, elf_errmsg(-1));
878		goto done;
879	}
880
881	if (eh.e_type != ET_EXEC && eh.e_type != ET_DYN &&
882	    !(image->pi_iskernelmodule && eh.e_type == ET_REL)) {
883		warnx("WARNING: \"%s\" is of an unsupported ELF type.",
884		    buffer);
885		goto done;
886	}
887
888	image_type = eh.e_ident[EI_CLASS] == ELFCLASS32 ?
889	    PMCSTAT_IMAGE_ELF32 : PMCSTAT_IMAGE_ELF64;
890
891	/*
892	 * Determine the virtual address where an executable would be
893	 * loaded.  Additionally, for dynamically linked executables,
894	 * save the pathname to the runtime linker.
895	 */
896	if (eh.e_type == ET_EXEC) {
897		if (elf_getphnum(e, &nph) == 0) {
898			warnx("WARNING: Could not determine the number of "
899			    "program headers in \"%s\": %s.", buffer,
900			    elf_errmsg(-1));
901			goto done;
902		}
903		for (i = 0; i < eh.e_phnum; i++) {
904			if (gelf_getphdr(e, i, &ph) != &ph) {
905				warnx("WARNING: Retrieval of PHDR entry #%ju "
906				    "in \"%s\" failed: %s.", (uintmax_t) i,
907				    buffer, elf_errmsg(-1));
908				goto done;
909			}
910			switch (ph.p_type) {
911			case PT_DYNAMIC:
912				image->pi_isdynamic = 1;
913				break;
914			case PT_INTERP:
915				if ((elfbase = elf_rawfile(e, NULL)) == NULL) {
916					warnx("WARNING: Cannot retrieve the "
917					    "interpreter for \"%s\": %s.",
918					    buffer, elf_errmsg(-1));
919					goto done;
920				}
921				image->pi_dynlinkerpath =
922				    pmcstat_string_intern(elfbase +
923					ph.p_offset);
924				break;
925			case PT_LOAD:
926				if (ph.p_offset == 0)
927					image->pi_vaddr = ph.p_vaddr;
928				break;
929			}
930		}
931	}
932
933	/*
934	 * Get the min and max VA associated with this ELF object.
935	 */
936	if (elf_getshnum(e, &nsh) == 0) {
937		warnx("WARNING: Could not determine the number of sections "
938		    "for \"%s\": %s.", buffer, elf_errmsg(-1));
939		goto done;
940	}
941
942	for (i = 0; i < nsh; i++) {
943		if ((scn = elf_getscn(e, i)) == NULL ||
944		    gelf_getshdr(scn, &sh) != &sh) {
945			warnx("WARNING: Could not retrieve section header "
946			    "#%ju in \"%s\": %s.", (uintmax_t) i, buffer,
947			    elf_errmsg(-1));
948			goto done;
949		}
950		if (sh.sh_flags & SHF_EXECINSTR) {
951			minva = min(minva, sh.sh_addr);
952			maxva = max(maxva, sh.sh_addr + sh.sh_size);
953		}
954		if (sh.sh_type == SHT_SYMTAB || sh.sh_type == SHT_DYNSYM)
955			pmcstat_image_add_symbols(image, e, scn, &sh);
956	}
957
958	image->pi_start = minva;
959	image->pi_end   = maxva;
960	image->pi_type  = image_type;
961	image->pi_fullpath = pmcstat_string_intern(buffer);
962
963 done:
964	(void) elf_end(e);
965	if (fd >= 0)
966		(void) close(fd);
967	return;
968}
969
970/*
971 * Given an image descriptor, determine whether it is an ELF, or AOUT.
972 * If no handler claims the image, set its type to 'INDETERMINABLE'.
973 */
974
975static void
976pmcstat_image_determine_type(struct pmcstat_image *image,
977    struct pmcstat_args *a)
978{
979	assert(image->pi_type == PMCSTAT_IMAGE_UNKNOWN);
980
981	/* Try each kind of handler in turn */
982	if (image->pi_type == PMCSTAT_IMAGE_UNKNOWN)
983		pmcstat_image_get_elf_params(image, a);
984	if (image->pi_type == PMCSTAT_IMAGE_UNKNOWN)
985		pmcstat_image_get_aout_params(image, a);
986
987	/*
988	 * Otherwise, remember that we tried to determine
989	 * the object's type and had failed.
990	 */
991	if (image->pi_type == PMCSTAT_IMAGE_UNKNOWN)
992		image->pi_type = PMCSTAT_IMAGE_INDETERMINABLE;
993}
994
995/*
996 * Locate an image descriptor given an interned path, adding a fresh
997 * descriptor to the cache if necessary.  This function also finds a
998 * suitable name for this image's sample file.
999 *
1000 * We defer filling in the file format specific parts of the image
1001 * structure till the time we actually see a sample that would fall
1002 * into this image.
1003 */
1004
1005static struct pmcstat_image *
1006pmcstat_image_from_path(pmcstat_interned_string internedpath,
1007    int iskernelmodule)
1008{
1009	int count, hash, nlen;
1010	struct pmcstat_image *pi;
1011	char *sn;
1012	char name[NAME_MAX];
1013
1014	hash = pmcstat_string_lookup_hash(internedpath);
1015
1016	/* First, look for an existing entry. */
1017	LIST_FOREACH(pi, &pmcstat_image_hash[hash], pi_next)
1018	    if (pi->pi_execpath == internedpath &&
1019		  pi->pi_iskernelmodule == iskernelmodule)
1020		    return (pi);
1021
1022	/*
1023	 * Allocate a new entry and place it at the head of the hash
1024	 * and LRU lists.
1025	 */
1026	pi = malloc(sizeof(*pi));
1027	if (pi == NULL)
1028		return (NULL);
1029
1030	pi->pi_type = PMCSTAT_IMAGE_UNKNOWN;
1031	pi->pi_execpath = internedpath;
1032	pi->pi_start = ~0;
1033	pi->pi_end = 0;
1034	pi->pi_entry = 0;
1035	pi->pi_vaddr = 0;
1036	pi->pi_isdynamic = 0;
1037	pi->pi_iskernelmodule = iskernelmodule;
1038	pi->pi_dynlinkerpath = NULL;
1039	pi->pi_symbols = NULL;
1040	pi->pi_symcount = 0;
1041
1042	/*
1043	 * Look for a suitable name for the sample files associated
1044	 * with this image: if `basename(path)`+".gmon" is available,
1045	 * we use that, otherwise we try iterating through
1046	 * `basename(path)`+ "~" + NNN + ".gmon" till we get a free
1047	 * entry.
1048	 */
1049	if ((sn = basename(pmcstat_string_unintern(internedpath))) == NULL)
1050		err(EX_OSERR, "ERROR: Cannot process \"%s\"",
1051		    pmcstat_string_unintern(internedpath));
1052
1053	nlen = strlen(sn);
1054	nlen = min(nlen, (int) (sizeof(name) - sizeof(".gmon")));
1055
1056	snprintf(name, sizeof(name), "%.*s.gmon", nlen, sn);
1057
1058	/* try use the unabridged name first */
1059	if (pmcstat_string_lookup(name) == NULL)
1060		pi->pi_samplename = pmcstat_string_intern(name);
1061	else {
1062		/*
1063		 * Otherwise use a prefix from the original name and
1064		 * upto 3 digits.
1065		 */
1066		nlen = strlen(sn);
1067		nlen = min(nlen, (int) (sizeof(name)-sizeof("~NNN.gmon")));
1068		count = 0;
1069		do {
1070			if (++count > 999)
1071				errx(EX_CANTCREAT, "ERROR: cannot create a "
1072				    "gmon file for \"%s\"", name);
1073			snprintf(name, sizeof(name), "%.*s~%3.3d.gmon",
1074			    nlen, sn, count);
1075			if (pmcstat_string_lookup(name) == NULL) {
1076				pi->pi_samplename =
1077				    pmcstat_string_intern(name);
1078				count = 0;
1079			}
1080		} while (count > 0);
1081	}
1082
1083
1084	LIST_INIT(&pi->pi_gmlist);
1085
1086	LIST_INSERT_HEAD(&pmcstat_image_hash[hash], pi, pi_next);
1087
1088	return (pi);
1089}
1090
1091/*
1092 * Increment the bucket in the gmon.out file corresponding to 'pmcid'
1093 * and 'pc'.
1094 */
1095
1096static void
1097pmcstat_image_increment_bucket(struct pmcstat_pcmap *map, uintfptr_t pc,
1098    pmc_id_t pmcid, struct pmcstat_args *a)
1099{
1100	struct pmcstat_image *image;
1101	struct pmcstat_gmonfile *pgf;
1102	uintfptr_t bucket;
1103	HISTCOUNTER *hc;
1104
1105	assert(pc >= map->ppm_lowpc && pc < map->ppm_highpc);
1106
1107	image = map->ppm_image;
1108
1109	/*
1110	 * If this is the first time we are seeing a sample for
1111	 * this executable image, try determine its parameters.
1112	 */
1113	if (image->pi_type == PMCSTAT_IMAGE_UNKNOWN)
1114		pmcstat_image_determine_type(image, a);
1115
1116	assert(image->pi_type != PMCSTAT_IMAGE_UNKNOWN);
1117
1118	/* Ignore samples in images that we know nothing about. */
1119	if (image->pi_type == PMCSTAT_IMAGE_INDETERMINABLE) {
1120		pmcstat_stats.ps_samples_indeterminable++;
1121		return;
1122	}
1123
1124	/*
1125	 * Find the gmon file corresponding to 'pmcid', creating it if
1126	 * needed.
1127	 */
1128	pgf = pmcstat_image_find_gmonfile(image, pmcid);
1129	if (pgf == NULL) {
1130		if ((pgf = calloc(1, sizeof(*pgf))) == NULL)
1131			err(EX_OSERR, "ERROR:");
1132
1133		pgf->pgf_gmondata = NULL;	/* mark as unmapped */
1134		pgf->pgf_name = pmcstat_gmon_create_name(a->pa_samplesdir,
1135		    image, pmcid);
1136		pgf->pgf_pmcid = pmcid;
1137		assert(image->pi_end > image->pi_start);
1138		pgf->pgf_nbuckets = (image->pi_end - image->pi_start) /
1139		    FUNCTION_ALIGNMENT;	/* see <machine/profile.h> */
1140		pgf->pgf_ndatabytes = sizeof(struct gmonhdr) +
1141		    pgf->pgf_nbuckets * sizeof(HISTCOUNTER);
1142		pgf->pgf_nsamples = 0;
1143		pgf->pgf_file = NULL;
1144
1145		pmcstat_gmon_create_file(pgf, image);
1146
1147		LIST_INSERT_HEAD(&image->pi_gmlist, pgf, pgf_next);
1148	}
1149
1150	/*
1151	 * Map the gmon file in if needed.  It may have been mapped
1152	 * out under memory pressure.
1153	 */
1154	if (pgf->pgf_gmondata == NULL)
1155		pmcstat_gmon_map_file(pgf);
1156
1157	assert(pgf->pgf_gmondata != NULL);
1158
1159	/*
1160	 *
1161	 */
1162
1163	bucket = (pc - map->ppm_lowpc) / FUNCTION_ALIGNMENT;
1164
1165	assert(bucket < pgf->pgf_nbuckets);
1166
1167	hc = (HISTCOUNTER *) ((uintptr_t) pgf->pgf_gmondata +
1168	    sizeof(struct gmonhdr));
1169
1170	/* saturating add */
1171	if (hc[bucket] < 0xFFFFU)  /* XXX tie this to sizeof(HISTCOUNTER) */
1172		hc[bucket]++;
1173	else /* mark that an overflow occurred */
1174		pgf->pgf_overflow = 1;
1175
1176	pgf->pgf_nsamples++;
1177}
1178
1179/*
1180 * Record the fact that PC values from 'start' to 'end' come from
1181 * image 'image'.
1182 */
1183
1184static void
1185pmcstat_image_link(struct pmcstat_process *pp, struct pmcstat_image *image,
1186    uintfptr_t start)
1187{
1188	struct pmcstat_pcmap *pcm, *pcmnew;
1189	uintfptr_t offset;
1190
1191	assert(image->pi_type != PMCSTAT_IMAGE_UNKNOWN &&
1192	    image->pi_type != PMCSTAT_IMAGE_INDETERMINABLE);
1193
1194	if ((pcmnew = malloc(sizeof(*pcmnew))) == NULL)
1195		err(EX_OSERR, "ERROR: Cannot create a map entry");
1196
1197	/*
1198	 * Adjust the map entry to only cover the text portion
1199	 * of the object.
1200	 */
1201
1202	offset = start - image->pi_vaddr;
1203	pcmnew->ppm_lowpc  = image->pi_start + offset;
1204	pcmnew->ppm_highpc = image->pi_end + offset;
1205	pcmnew->ppm_image  = image;
1206
1207	assert(pcmnew->ppm_lowpc < pcmnew->ppm_highpc);
1208
1209	/* Overlapped mmap()'s are assumed to never occur. */
1210	TAILQ_FOREACH(pcm, &pp->pp_map, ppm_next)
1211	    if (pcm->ppm_lowpc >= pcmnew->ppm_highpc)
1212		    break;
1213
1214	if (pcm == NULL)
1215		TAILQ_INSERT_TAIL(&pp->pp_map, pcmnew, ppm_next);
1216	else
1217		TAILQ_INSERT_BEFORE(pcm, pcmnew, ppm_next);
1218}
1219
1220/*
1221 * Unmap images in the range [start..end) associated with process
1222 * 'pp'.
1223 */
1224
1225static void
1226pmcstat_image_unmap(struct pmcstat_process *pp, uintfptr_t start,
1227    uintfptr_t end)
1228{
1229	struct pmcstat_pcmap *pcm, *pcmtmp, *pcmnew;
1230
1231	assert(pp != NULL);
1232	assert(start < end);
1233
1234	/*
1235	 * Cases:
1236	 * - we could have the range completely in the middle of an
1237	 *   existing pcmap; in this case we have to split the pcmap
1238	 *   structure into two (i.e., generate a 'hole').
1239	 * - we could have the range covering multiple pcmaps; these
1240	 *   will have to be removed.
1241	 * - we could have either 'start' or 'end' falling in the
1242	 *   middle of a pcmap; in this case shorten the entry.
1243	 */
1244	TAILQ_FOREACH_SAFE(pcm, &pp->pp_map, ppm_next, pcmtmp) {
1245		assert(pcm->ppm_lowpc < pcm->ppm_highpc);
1246		if (pcm->ppm_highpc <= start)
1247			continue;
1248		if (pcm->ppm_lowpc >= end)
1249			return;
1250		if (pcm->ppm_lowpc >= start && pcm->ppm_highpc <= end) {
1251			/*
1252			 * The current pcmap is completely inside the
1253			 * unmapped range: remove it entirely.
1254			 */
1255			TAILQ_REMOVE(&pp->pp_map, pcm, ppm_next);
1256			free(pcm);
1257		} else if (pcm->ppm_lowpc < start && pcm->ppm_highpc > end) {
1258			/*
1259			 * Split this pcmap into two; curtail the
1260			 * current map to end at [start-1], and start
1261			 * the new one at [end].
1262			 */
1263			if ((pcmnew = malloc(sizeof(*pcmnew))) == NULL)
1264				err(EX_OSERR, "ERROR: Cannot split a map "
1265				    "entry");
1266
1267			pcmnew->ppm_image = pcm->ppm_image;
1268
1269			pcmnew->ppm_lowpc = end;
1270			pcmnew->ppm_highpc = pcm->ppm_highpc;
1271
1272			pcm->ppm_highpc = start;
1273
1274			TAILQ_INSERT_AFTER(&pp->pp_map, pcm, pcmnew, ppm_next);
1275
1276			return;
1277		} else if (pcm->ppm_lowpc < start && pcm->ppm_highpc <= end)
1278			pcm->ppm_highpc = start;
1279		else if (pcm->ppm_lowpc >= start && pcm->ppm_highpc > end)
1280			pcm->ppm_lowpc = end;
1281		else
1282			assert(0);
1283	}
1284}
1285
1286/*
1287 * Add a {pmcid,name} mapping.
1288 */
1289
1290static void
1291pmcstat_pmcid_add(pmc_id_t pmcid, pmcstat_interned_string ps,
1292    struct pmcstat_args *a)
1293{
1294	struct pmcstat_pmcrecord *pr;
1295	struct stat st;
1296	char fullpath[PATH_MAX];
1297
1298	/* Replace an existing name for the PMC. */
1299	LIST_FOREACH(pr, &pmcstat_pmcs, pr_next)
1300	    if (pr->pr_pmcid == pmcid) {
1301		    pr->pr_pmcname = ps;
1302		    return;
1303	    }
1304
1305	/*
1306	 * Otherwise, allocate a new descriptor and create the
1307	 * appropriate directory to hold gmon.out files.
1308	 */
1309	if ((pr = malloc(sizeof(*pr))) == NULL)
1310		err(EX_OSERR, "ERROR: Cannot allocate pmc record");
1311
1312	pr->pr_pmcid = pmcid;
1313	pr->pr_pmcname = ps;
1314	LIST_INSERT_HEAD(&pmcstat_pmcs, pr, pr_next);
1315
1316	(void) snprintf(fullpath, sizeof(fullpath), "%s/%s", a->pa_samplesdir,
1317	    pmcstat_string_unintern(ps));
1318
1319	/* If the path name exists, it should be a directory */
1320	if (stat(fullpath, &st) == 0 && S_ISDIR(st.st_mode))
1321		return;
1322
1323	if (mkdir(fullpath, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) < 0)
1324		err(EX_OSERR, "ERROR: Cannot create directory \"%s\"",
1325		    fullpath);
1326}
1327
1328/*
1329 * Given a pmcid in use, find its human-readable name.
1330 */
1331
1332static const char *
1333pmcstat_pmcid_to_name(pmc_id_t pmcid)
1334{
1335	struct pmcstat_pmcrecord *pr;
1336	char fullpath[PATH_MAX];
1337
1338	LIST_FOREACH(pr, &pmcstat_pmcs, pr_next)
1339	    if (pr->pr_pmcid == pmcid)
1340		    return (pmcstat_string_unintern(pr->pr_pmcname));
1341
1342	/* create a default name and add this entry */
1343	if ((pr = malloc(sizeof(*pr))) == NULL)
1344		err(EX_OSERR, "ERROR: ");
1345	pr->pr_pmcid = pmcid;
1346
1347	(void) snprintf(fullpath, sizeof(fullpath), "%X", (unsigned int) pmcid);
1348	pr->pr_pmcname = pmcstat_string_intern(fullpath);
1349
1350	LIST_INSERT_HEAD(&pmcstat_pmcs, pr, pr_next);
1351
1352	return (pmcstat_string_unintern(pr->pr_pmcname));
1353}
1354
1355/*
1356 * Associate an AOUT image with a process.
1357 */
1358
1359static void
1360pmcstat_process_aout_exec(struct pmcstat_process *pp,
1361    struct pmcstat_image *image, uintfptr_t entryaddr,
1362    struct pmcstat_args *a)
1363{
1364	(void) pp;
1365	(void) image;
1366	(void) entryaddr;
1367	(void) a;
1368	/* TODO Implement a.out handling */
1369}
1370
1371/*
1372 * Associate an ELF image with a process.
1373 */
1374
1375static void
1376pmcstat_process_elf_exec(struct pmcstat_process *pp,
1377    struct pmcstat_image *image, uintfptr_t entryaddr,
1378    struct pmcstat_args *a)
1379{
1380	uintmax_t libstart;
1381	struct pmcstat_image *rtldimage;
1382
1383	assert(image->pi_type == PMCSTAT_IMAGE_ELF32 ||
1384	    image->pi_type == PMCSTAT_IMAGE_ELF64);
1385
1386	/* Create a map entry for the base executable. */
1387	pmcstat_image_link(pp, image, image->pi_vaddr);
1388
1389	/*
1390	 * For dynamically linked executables we need to determine
1391	 * where the dynamic linker was mapped to for this process,
1392	 * Subsequent executable objects that are mapped in by the
1393	 * dynamic linker will be tracked by log events of type
1394	 * PMCLOG_TYPE_MAP_IN.
1395	 */
1396
1397	if (image->pi_isdynamic) {
1398
1399		/*
1400		 * The runtime loader gets loaded just after the maximum
1401		 * possible heap address.  Like so:
1402		 *
1403		 * [  TEXT DATA BSS HEAP -->*RTLD  SHLIBS   <--STACK]
1404		 * ^					            ^
1405		 * 0				   VM_MAXUSER_ADDRESS
1406
1407		 *
1408		 * The exact address where the loader gets mapped in
1409		 * will vary according to the size of the executable
1410		 * and the limits on the size of the process'es data
1411		 * segment at the time of exec().  The entry address
1412		 * recorded at process exec time corresponds to the
1413		 * 'start' address inside the dynamic linker.  From
1414		 * this we can figure out the address where the
1415		 * runtime loader's file object had been mapped to.
1416		 */
1417		rtldimage = pmcstat_image_from_path(image->pi_dynlinkerpath,
1418		    0);
1419		if (rtldimage == NULL) {
1420			warnx("WARNING: Cannot find image for \"%s\".",
1421			    pmcstat_string_unintern(image->pi_dynlinkerpath));
1422			pmcstat_stats.ps_exec_errors++;
1423			return;
1424		}
1425
1426		if (rtldimage->pi_type == PMCSTAT_IMAGE_UNKNOWN)
1427			pmcstat_image_get_elf_params(rtldimage, a);
1428
1429		if (rtldimage->pi_type != PMCSTAT_IMAGE_ELF32 &&
1430		    rtldimage->pi_type != PMCSTAT_IMAGE_ELF64) {
1431			warnx("WARNING: rtld not an ELF object \"%s\".",
1432			    pmcstat_string_unintern(image->pi_dynlinkerpath));
1433			return;
1434		}
1435
1436		libstart = entryaddr - rtldimage->pi_entry;
1437		pmcstat_image_link(pp, rtldimage, libstart);
1438	}
1439}
1440
1441/*
1442 * Find the process descriptor corresponding to a PID.  If 'allocate'
1443 * is zero, we return a NULL if a pid descriptor could not be found or
1444 * a process descriptor process.  If 'allocate' is non-zero, then we
1445 * will attempt to allocate a fresh process descriptor.  Zombie
1446 * process descriptors are only removed if a fresh allocation for the
1447 * same PID is requested.
1448 */
1449
1450static struct pmcstat_process *
1451pmcstat_process_lookup(pid_t pid, int allocate)
1452{
1453	uint32_t hash;
1454	struct pmcstat_pcmap *ppm, *ppmtmp;
1455	struct pmcstat_process *pp, *pptmp;
1456
1457	hash = (uint32_t) pid & PMCSTAT_HASH_MASK;	/* simplicity wins */
1458
1459	LIST_FOREACH_SAFE(pp, &pmcstat_process_hash[hash], pp_next, pptmp)
1460	    if (pp->pp_pid == pid) {
1461		    /* Found a descriptor, check and process zombies */
1462		    if (allocate && pp->pp_isactive == 0) {
1463			    /* remove maps */
1464			    TAILQ_FOREACH_SAFE(ppm, &pp->pp_map, ppm_next,
1465				ppmtmp) {
1466				    TAILQ_REMOVE(&pp->pp_map, ppm, ppm_next);
1467				    free(ppm);
1468			    }
1469			    /* remove process entry */
1470			    LIST_REMOVE(pp, pp_next);
1471			    free(pp);
1472			    break;
1473		    }
1474		    return (pp);
1475	    }
1476
1477	if (!allocate)
1478		return (NULL);
1479
1480	if ((pp = malloc(sizeof(*pp))) == NULL)
1481		err(EX_OSERR, "ERROR: Cannot allocate pid descriptor");
1482
1483	pp->pp_pid = pid;
1484	pp->pp_isactive = 1;
1485
1486	TAILQ_INIT(&pp->pp_map);
1487
1488	LIST_INSERT_HEAD(&pmcstat_process_hash[hash], pp, pp_next);
1489	return (pp);
1490}
1491
1492/*
1493 * Associate an image and a process.
1494 */
1495
1496static void
1497pmcstat_process_exec(struct pmcstat_process *pp,
1498    pmcstat_interned_string path, uintfptr_t entryaddr,
1499    struct pmcstat_args *a)
1500{
1501	struct pmcstat_image *image;
1502
1503	if ((image = pmcstat_image_from_path(path, 0)) == NULL) {
1504		pmcstat_stats.ps_exec_errors++;
1505		return;
1506	}
1507
1508	if (image->pi_type == PMCSTAT_IMAGE_UNKNOWN)
1509		pmcstat_image_determine_type(image, a);
1510
1511	assert(image->pi_type != PMCSTAT_IMAGE_UNKNOWN);
1512
1513	switch (image->pi_type) {
1514	case PMCSTAT_IMAGE_ELF32:
1515	case PMCSTAT_IMAGE_ELF64:
1516		pmcstat_stats.ps_exec_elf++;
1517		pmcstat_process_elf_exec(pp, image, entryaddr, a);
1518		break;
1519
1520	case PMCSTAT_IMAGE_AOUT:
1521		pmcstat_stats.ps_exec_aout++;
1522		pmcstat_process_aout_exec(pp, image, entryaddr, a);
1523		break;
1524
1525	case PMCSTAT_IMAGE_INDETERMINABLE:
1526		pmcstat_stats.ps_exec_indeterminable++;
1527		break;
1528
1529	default:
1530		err(EX_SOFTWARE, "ERROR: Unsupported executable type for "
1531		    "\"%s\"", pmcstat_string_unintern(path));
1532	}
1533}
1534
1535
1536/*
1537 * Find the map entry associated with process 'p' at PC value 'pc'.
1538 */
1539
1540static struct pmcstat_pcmap *
1541pmcstat_process_find_map(struct pmcstat_process *p, uintfptr_t pc)
1542{
1543	struct pmcstat_pcmap *ppm;
1544
1545	TAILQ_FOREACH(ppm, &p->pp_map, ppm_next) {
1546		if (pc >= ppm->ppm_lowpc && pc < ppm->ppm_highpc)
1547			return (ppm);
1548		if (pc < ppm->ppm_lowpc)
1549			return (NULL);
1550	}
1551
1552	return (NULL);
1553}
1554
1555static struct pmcstat_cgnode *
1556pmcstat_cgnode_allocate(struct pmcstat_image *image, uintfptr_t pc)
1557{
1558	struct pmcstat_cgnode *cg;
1559
1560	if ((cg = malloc(sizeof(*cg))) == NULL)
1561		err(EX_OSERR, "ERROR: Cannot allocate callgraph node");
1562
1563	cg->pcg_image = image;
1564	cg->pcg_func = pc;
1565
1566	cg->pcg_count = 0;
1567	cg->pcg_nchildren = 0;
1568	LIST_INIT(&cg->pcg_children);
1569
1570	return (cg);
1571}
1572
1573/*
1574 * Free a node and its children.
1575 */
1576static void
1577pmcstat_cgnode_free(struct pmcstat_cgnode *cg)
1578{
1579	struct pmcstat_cgnode *cgc, *cgtmp;
1580
1581	LIST_FOREACH_SAFE(cgc, &cg->pcg_children, pcg_sibling, cgtmp)
1582		pmcstat_cgnode_free(cgc);
1583	free(cg);
1584}
1585
1586/*
1587 * Look for a callgraph node associated with pmc `pmcid' in the global
1588 * hash table that corresponds to the given `pc' value in the process
1589 * `pp'.
1590 */
1591static struct pmcstat_cgnode *
1592pmcstat_cgnode_hash_lookup_pc(struct pmcstat_process *pp, uint32_t pmcid,
1593    uintfptr_t pc, int usermode)
1594{
1595	struct pmcstat_pcmap *ppm;
1596	struct pmcstat_symbol *sym;
1597	struct pmcstat_image *image;
1598	struct pmcstat_cgnode *cg;
1599	struct pmcstat_cgnode_hash *h;
1600	uintfptr_t loadaddress;
1601	unsigned int i, hash;
1602
1603	ppm = pmcstat_process_find_map(usermode ? pp : pmcstat_kernproc, pc);
1604	if (ppm == NULL)
1605		return (NULL);
1606
1607	image = ppm->ppm_image;
1608
1609	loadaddress = ppm->ppm_lowpc + image->pi_vaddr - image->pi_start;
1610	pc -= loadaddress;	/* Convert to an offset in the image. */
1611
1612	/*
1613	 * Try determine the function at this offset.  If we can't
1614	 * find a function round leave the `pc' value alone.
1615	 */
1616	if ((sym = pmcstat_symbol_search(image, pc)) != NULL)
1617		pc = sym->ps_start;
1618
1619	for (hash = i = 0; i < sizeof(uintfptr_t); i++)
1620		hash += (pc >> i) & 0xFF;
1621
1622	hash &= PMCSTAT_HASH_MASK;
1623
1624	cg = NULL;
1625	LIST_FOREACH(h, &pmcstat_cgnode_hash[hash], pch_next)
1626	{
1627		if (h->pch_pmcid != pmcid)
1628			continue;
1629
1630		cg = h->pch_cgnode;
1631
1632		assert(cg != NULL);
1633
1634		if (cg->pcg_image == image && cg->pcg_func == pc)
1635			return (cg);
1636	}
1637
1638	/*
1639	 * We haven't seen this (pmcid, pc) tuple yet, so allocate a
1640	 * new callgraph node and a new hash table entry for it.
1641	 */
1642	cg = pmcstat_cgnode_allocate(image, pc);
1643	if ((h = malloc(sizeof(*h))) == NULL)
1644		err(EX_OSERR, "ERROR: Could not allocate callgraph node");
1645
1646	h->pch_pmcid = pmcid;
1647	h->pch_cgnode = cg;
1648	LIST_INSERT_HEAD(&pmcstat_cgnode_hash[hash], h, pch_next);
1649
1650	pmcstat_cgnode_hash_count++;
1651
1652	return (cg);
1653}
1654
1655/*
1656 * Compare two callgraph nodes for sorting.
1657 */
1658static int
1659pmcstat_cgnode_compare(const void *a, const void *b)
1660{
1661	const struct pmcstat_cgnode *const *pcg1, *const *pcg2, *cg1, *cg2;
1662
1663	pcg1 = (const struct pmcstat_cgnode *const *) a;
1664	cg1 = *pcg1;
1665	pcg2 = (const struct pmcstat_cgnode *const *) b;
1666	cg2 = *pcg2;
1667
1668	/* Sort in reverse order */
1669	if (cg1->pcg_count < cg2->pcg_count)
1670		return (1);
1671	if (cg1->pcg_count > cg2->pcg_count)
1672		return (-1);
1673	return (0);
1674}
1675
1676/*
1677 * Find (allocating if a needed) a callgraph node in the given
1678 * parent with the same (image, pcoffset) pair.
1679 */
1680
1681static struct pmcstat_cgnode *
1682pmcstat_cgnode_find(struct pmcstat_cgnode *parent, struct pmcstat_image *image,
1683    uintfptr_t pcoffset)
1684{
1685	struct pmcstat_cgnode *child;
1686
1687	LIST_FOREACH(child, &parent->pcg_children, pcg_sibling) {
1688		if (child->pcg_image == image &&
1689		    child->pcg_func == pcoffset)
1690			return (child);
1691	}
1692
1693	/*
1694	 * Allocate a new structure.
1695	 */
1696
1697	child = pmcstat_cgnode_allocate(image, pcoffset);
1698
1699	/*
1700	 * Link it into the parent.
1701	 */
1702	LIST_INSERT_HEAD(&parent->pcg_children, child, pcg_sibling);
1703	parent->pcg_nchildren++;
1704
1705	return (child);
1706}
1707
1708/*
1709 * Print one callgraph node.  The output format is:
1710 *
1711 * indentation %(parent's samples) #nsamples function@object
1712 */
1713static void
1714pmcstat_cgnode_print(struct pmcstat_args *a, struct pmcstat_cgnode *cg,
1715    int depth, uint32_t total)
1716{
1717	uint32_t n;
1718	const char *space;
1719	struct pmcstat_symbol *sym;
1720	struct pmcstat_cgnode **sortbuffer, **cgn, *pcg;
1721
1722	space = " ";
1723
1724	if (depth > 0)
1725		(void) fprintf(a->pa_graphfile, "%*s", depth, space);
1726
1727	if (cg->pcg_count == total)
1728		(void) fprintf(a->pa_graphfile, "100.0%% ");
1729	else
1730		(void) fprintf(a->pa_graphfile, "%05.2f%% ",
1731		    100.0 * cg->pcg_count / total);
1732
1733	n = fprintf(a->pa_graphfile, " [%u] ", cg->pcg_count);
1734
1735	/* #samples is a 12 character wide field. */
1736	if (n < 12)
1737		(void) fprintf(a->pa_graphfile, "%*s", 12 - n, space);
1738
1739	if (depth > 0)
1740		(void) fprintf(a->pa_graphfile, "%*s", depth, space);
1741
1742	sym = pmcstat_symbol_search(cg->pcg_image, cg->pcg_func);
1743	if (sym)
1744		(void) fprintf(a->pa_graphfile, "%s",
1745		    pmcstat_string_unintern(sym->ps_name));
1746	else
1747		(void) fprintf(a->pa_graphfile, "%p",
1748		    (void *) (cg->pcg_image->pi_vaddr + cg->pcg_func));
1749
1750	if (pmcstat_previous_filename_printed !=
1751	    cg->pcg_image->pi_fullpath) {
1752		pmcstat_previous_filename_printed = cg->pcg_image->pi_fullpath;
1753		(void) fprintf(a->pa_graphfile, " @ %s\n",
1754		    pmcstat_string_unintern(
1755		    pmcstat_previous_filename_printed));
1756	} else
1757		(void) fprintf(a->pa_graphfile, "\n");
1758
1759	if (cg->pcg_nchildren == 0)
1760		return;
1761
1762	if ((sortbuffer = (struct pmcstat_cgnode **)
1763		malloc(sizeof(struct pmcstat_cgnode *) *
1764		    cg->pcg_nchildren)) == NULL)
1765		err(EX_OSERR, "ERROR: Cannot print callgraph");
1766	cgn = sortbuffer;
1767
1768	LIST_FOREACH(pcg, &cg->pcg_children, pcg_sibling)
1769	    *cgn++ = pcg;
1770
1771	assert(cgn - sortbuffer == (int) cg->pcg_nchildren);
1772
1773	qsort(sortbuffer, cg->pcg_nchildren, sizeof(struct pmcstat_cgnode *),
1774	    pmcstat_cgnode_compare);
1775
1776	for (cgn = sortbuffer, n = 0; n < cg->pcg_nchildren; n++, cgn++)
1777		pmcstat_cgnode_print(a, *cgn, depth+1, cg->pcg_count);
1778
1779	free(sortbuffer);
1780}
1781
1782/*
1783 * Record a callchain.
1784 */
1785
1786static void
1787pmcstat_record_callchain(struct pmcstat_process *pp, uint32_t pmcid,
1788    uint32_t nsamples, uintfptr_t *cc, int usermode, struct pmcstat_args *a)
1789{
1790	uintfptr_t pc, loadaddress;
1791	uint32_t n;
1792	struct pmcstat_image *image;
1793	struct pmcstat_pcmap *ppm;
1794	struct pmcstat_symbol *sym;
1795	struct pmcstat_cgnode *parent, *child;
1796
1797	/*
1798	 * Find the callgraph node recorded in the global hash table
1799	 * for this (pmcid, pc).
1800	 */
1801
1802	pc = cc[0];
1803	parent = pmcstat_cgnode_hash_lookup_pc(pp, pmcid, pc, usermode);
1804	if (parent == NULL) {
1805		pmcstat_stats.ps_callchain_dubious_frames++;
1806		return;
1807	}
1808
1809	parent->pcg_count++;
1810
1811	/*
1812	 * For each return address in the call chain record, subject
1813	 * to the maximum depth desired.
1814	 * - Find the image associated with the sample.  Stop if there
1815	 *   there is no valid image at that address.
1816	 * - Find the function that overlaps the return address.
1817	 * - If found: use the start address of the function.
1818	 *   If not found (say an object's symbol table is not present or
1819	 *   is incomplete), round down to th gprof bucket granularity.
1820	 * - Convert return virtual address to an offset in the image.
1821	 * - Look for a child with the same {offset,image} tuple,
1822	 *   inserting one if needed.
1823	 * - Increment the count of occurrences of the child.
1824	 */
1825
1826	for (n = 1; n < (uint32_t) a->pa_graphdepth && n < nsamples; n++,
1827	    parent = child) {
1828		pc = cc[n];
1829
1830		ppm = pmcstat_process_find_map(usermode ? pp :
1831		    pmcstat_kernproc, pc);
1832		if (ppm == NULL)
1833			return;
1834
1835		image = ppm->ppm_image;
1836		loadaddress = ppm->ppm_lowpc + image->pi_vaddr -
1837		    image->pi_start;
1838		pc -= loadaddress;
1839
1840		if ((sym = pmcstat_symbol_search(image, pc)) != NULL)
1841			pc = sym->ps_start;
1842
1843		child = pmcstat_cgnode_find(parent, image, pc);
1844		child->pcg_count++;
1845	}
1846}
1847
1848/*
1849 * Printing a callgraph for a PMC.
1850 */
1851static void
1852pmcstat_callgraph_print_for_pmcid(struct pmcstat_args *a,
1853    struct pmcstat_pmcrecord *pmcr)
1854{
1855	int n, nentries;
1856	uint32_t nsamples, pmcid;
1857	struct pmcstat_cgnode **sortbuffer, **cgn;
1858	struct pmcstat_cgnode_hash *pch;
1859
1860	/*
1861	 * We pull out all callgraph nodes in the top-level hash table
1862	 * with a matching PMC id.  We then sort these based on the
1863	 * frequency of occurrence.  Each callgraph node is then
1864	 * printed.
1865	 */
1866
1867	nsamples = 0;
1868	pmcid = pmcr->pr_pmcid;
1869	if ((sortbuffer = (struct pmcstat_cgnode **)
1870	    malloc(sizeof(struct pmcstat_cgnode *) *
1871	    pmcstat_cgnode_hash_count)) == NULL)
1872		err(EX_OSERR, "ERROR: Cannot sort callgraph");
1873	cgn = sortbuffer;
1874
1875	memset(sortbuffer, 0xFF, pmcstat_cgnode_hash_count *
1876	    sizeof(struct pmcstat_cgnode **));
1877
1878	for (n = 0; n < PMCSTAT_NHASH; n++)
1879		LIST_FOREACH(pch, &pmcstat_cgnode_hash[n], pch_next)
1880		    if (pch->pch_pmcid == pmcid) {
1881			    nsamples += pch->pch_cgnode->pcg_count;
1882			    *cgn++ = pch->pch_cgnode;
1883		    }
1884
1885	nentries = cgn - sortbuffer;
1886	assert(nentries <= pmcstat_cgnode_hash_count);
1887
1888	if (nentries == 0)
1889		return;
1890
1891	qsort(sortbuffer, nentries, sizeof(struct pmcstat_cgnode *),
1892	    pmcstat_cgnode_compare);
1893
1894	(void) fprintf(a->pa_graphfile,
1895	    "@ %s [%u samples]\n\n",
1896	    pmcstat_string_unintern(pmcr->pr_pmcname),
1897	    nsamples);
1898
1899	for (cgn = sortbuffer, n = 0; n < nentries; n++, cgn++) {
1900		pmcstat_previous_filename_printed = NULL;
1901		pmcstat_cgnode_print(a, *cgn, 0, nsamples);
1902		(void) fprintf(a->pa_graphfile, "\n");
1903	}
1904
1905	free(sortbuffer);
1906}
1907
1908/*
1909 * Print out callgraphs.
1910 */
1911
1912static void
1913pmcstat_callgraph_print(struct pmcstat_args *a)
1914{
1915	struct pmcstat_pmcrecord *pmcr;
1916
1917	LIST_FOREACH(pmcr, &pmcstat_pmcs, pr_next)
1918	    pmcstat_callgraph_print_for_pmcid(a, pmcr);
1919}
1920
1921static void
1922pmcstat_cgnode_do_gmon_arcs(struct pmcstat_cgnode *cg, pmc_id_t pmcid)
1923{
1924	struct pmcstat_cgnode *cgc;
1925
1926	/*
1927	 * Look for child nodes that belong to the same image.
1928	 */
1929
1930	LIST_FOREACH(cgc, &cg->pcg_children, pcg_sibling) {
1931		if (cgc->pcg_image == cg->pcg_image)
1932			pmcstat_gmon_append_arc(cg->pcg_image, pmcid,
1933			    cgc->pcg_func, cg->pcg_func, cgc->pcg_count);
1934		if (cgc->pcg_nchildren > 0)
1935			pmcstat_cgnode_do_gmon_arcs(cgc, pmcid);
1936	}
1937}
1938
1939static void
1940pmcstat_callgraph_do_gmon_arcs_for_pmcid(pmc_id_t pmcid)
1941{
1942	int n;
1943	struct pmcstat_cgnode_hash *pch;
1944
1945	for (n = 0; n < PMCSTAT_NHASH; n++)
1946		LIST_FOREACH(pch, &pmcstat_cgnode_hash[n], pch_next)
1947			if (pch->pch_pmcid == pmcid &&
1948			    pch->pch_cgnode->pcg_nchildren > 1)
1949				pmcstat_cgnode_do_gmon_arcs(pch->pch_cgnode,
1950				    pmcid);
1951}
1952
1953
1954static void
1955pmcstat_callgraph_do_gmon_arcs(void)
1956{
1957	struct pmcstat_pmcrecord *pmcr;
1958
1959	LIST_FOREACH(pmcr, &pmcstat_pmcs, pr_next)
1960		pmcstat_callgraph_do_gmon_arcs_for_pmcid(pmcr->pr_pmcid);
1961}
1962
1963/*
1964 * Convert a hwpmc(4) log to profile information.  A system-wide
1965 * callgraph is generated if FLAG_DO_CALLGRAPHS is set.  gmon.out
1966 * files usable by gprof(1) are created if FLAG_DO_GPROF is set.
1967 */
1968static int
1969pmcstat_analyze_log(struct pmcstat_args *a)
1970{
1971	uint32_t cpu, cpuflags;
1972	uintfptr_t pc;
1973	pid_t pid;
1974	struct pmcstat_image *image;
1975	struct pmcstat_process *pp, *ppnew;
1976	struct pmcstat_pcmap *ppm, *ppmtmp;
1977	struct pmclog_ev ev;
1978	pmcstat_interned_string image_path;
1979
1980	assert(a->pa_flags & FLAG_DO_ANALYSIS);
1981
1982	if (elf_version(EV_CURRENT) == EV_NONE)
1983		err(EX_UNAVAILABLE, "Elf library intialization failed");
1984
1985	while (pmclog_read(a->pa_logparser, &ev) == 0) {
1986		assert(ev.pl_state == PMCLOG_OK);
1987
1988		switch (ev.pl_type) {
1989		case PMCLOG_TYPE_INITIALIZE:
1990			if ((ev.pl_u.pl_i.pl_version & 0xFF000000) !=
1991			    PMC_VERSION_MAJOR << 24 && a->pa_verbosity > 0)
1992				warnx("WARNING: Log version 0x%x does not "
1993				    "match compiled version 0x%x.",
1994				    ev.pl_u.pl_i.pl_version,
1995				    PMC_VERSION_MAJOR);
1996			break;
1997
1998		case PMCLOG_TYPE_MAP_IN:
1999			/*
2000			 * Introduce an address range mapping for a
2001			 * userland process or the kernel (pid == -1).
2002			 *
2003			 * We always allocate a process descriptor so
2004			 * that subsequent samples seen for this
2005			 * address range are mapped to the current
2006			 * object being mapped in.
2007			 */
2008			pid = ev.pl_u.pl_mi.pl_pid;
2009			if (pid == -1)
2010				pp = pmcstat_kernproc;
2011			else
2012				pp = pmcstat_process_lookup(pid,
2013				    PMCSTAT_ALLOCATE);
2014
2015			assert(pp != NULL);
2016
2017			image_path = pmcstat_string_intern(ev.pl_u.pl_mi.
2018			    pl_pathname);
2019			image = pmcstat_image_from_path(image_path, pid == -1);
2020			if (image->pi_type == PMCSTAT_IMAGE_UNKNOWN)
2021				pmcstat_image_determine_type(image, a);
2022			if (image->pi_type != PMCSTAT_IMAGE_INDETERMINABLE)
2023				pmcstat_image_link(pp, image,
2024				    ev.pl_u.pl_mi.pl_start);
2025			break;
2026
2027		case PMCLOG_TYPE_MAP_OUT:
2028			/*
2029			 * Remove an address map.
2030			 */
2031			pid = ev.pl_u.pl_mo.pl_pid;
2032			if (pid == -1)
2033				pp = pmcstat_kernproc;
2034			else
2035				pp = pmcstat_process_lookup(pid, 0);
2036
2037			if (pp == NULL)	/* unknown process */
2038				break;
2039
2040			pmcstat_image_unmap(pp, ev.pl_u.pl_mo.pl_start,
2041			    ev.pl_u.pl_mo.pl_end);
2042			break;
2043
2044		case PMCLOG_TYPE_PCSAMPLE:
2045			/*
2046			 * Note: the `PCSAMPLE' log entry is not
2047			 * generated by hpwmc(4) after version 2.
2048			 */
2049
2050			/*
2051			 * We bring in the gmon file for the image
2052			 * currently associated with the PMC & pid
2053			 * pair and increment the appropriate entry
2054			 * bin inside this.
2055			 */
2056			pmcstat_stats.ps_samples_total++;
2057
2058			pc = ev.pl_u.pl_s.pl_pc;
2059			pp = pmcstat_process_lookup(ev.pl_u.pl_s.pl_pid,
2060			    PMCSTAT_ALLOCATE);
2061			if ((ppm = pmcstat_process_find_map(pp, pc)) == NULL &&
2062			    (ppm = pmcstat_process_find_map(pmcstat_kernproc,
2063				pc)) == NULL) {	/* unknown process,offset pair */
2064				pmcstat_stats.ps_samples_unknown_offset++;
2065				break;
2066			}
2067
2068			pmcstat_image_increment_bucket(ppm, pc,
2069			    ev.pl_u.pl_s.pl_pmcid, a);
2070
2071			break;
2072
2073		case PMCLOG_TYPE_CALLCHAIN:
2074			pmcstat_stats.ps_samples_total++;
2075
2076			cpuflags = ev.pl_u.pl_cc.pl_cpuflags;
2077			cpu = PMC_CALLCHAIN_CPUFLAGS_TO_CPU(cpuflags);
2078
2079			/* Filter on the CPU id. */
2080			if ((a->pa_cpumask & (1 << cpu)) == 0) {
2081				pmcstat_stats.ps_samples_skipped++;
2082				break;
2083			}
2084
2085			pp = pmcstat_process_lookup(ev.pl_u.pl_cc.pl_pid,
2086			    PMCSTAT_ALLOCATE);
2087
2088			pmcstat_record_callchain(pp,
2089			    ev.pl_u.pl_cc.pl_pmcid, ev.pl_u.pl_cc.pl_npc,
2090			    ev.pl_u.pl_cc.pl_pc,
2091			    PMC_CALLCHAIN_CPUFLAGS_TO_USERMODE(cpuflags), a);
2092
2093			if ((a->pa_flags & FLAG_DO_GPROF) == 0)
2094				break;
2095
2096			pc = ev.pl_u.pl_cc.pl_pc[0];
2097			if ((ppm = pmcstat_process_find_map(pp, pc)) == NULL &&
2098			    (ppm = pmcstat_process_find_map(pmcstat_kernproc,
2099				pc)) == NULL) { /* unknown offset */
2100				pmcstat_stats.ps_samples_unknown_offset++;
2101				break;
2102			}
2103
2104			pmcstat_image_increment_bucket(ppm, pc,
2105			    ev.pl_u.pl_cc.pl_pmcid, a);
2106
2107			break;
2108
2109		case PMCLOG_TYPE_PMCALLOCATE:
2110			/*
2111			 * Record the association pmc id between this
2112			 * PMC and its name.
2113			 */
2114			pmcstat_pmcid_add(ev.pl_u.pl_a.pl_pmcid,
2115			    pmcstat_string_intern(ev.pl_u.pl_a.pl_evname), a);
2116			break;
2117
2118		case PMCLOG_TYPE_PROCEXEC:
2119
2120			/*
2121			 * Change the executable image associated with
2122			 * a process.
2123			 */
2124			pp = pmcstat_process_lookup(ev.pl_u.pl_x.pl_pid,
2125			    PMCSTAT_ALLOCATE);
2126
2127			/* delete the current process map */
2128			TAILQ_FOREACH_SAFE(ppm, &pp->pp_map, ppm_next, ppmtmp) {
2129				TAILQ_REMOVE(&pp->pp_map, ppm, ppm_next);
2130				free(ppm);
2131			}
2132
2133			/* associate this process  image */
2134			image_path = pmcstat_string_intern(
2135				ev.pl_u.pl_x.pl_pathname);
2136			assert(image_path != NULL);
2137			pmcstat_process_exec(pp, image_path,
2138			    ev.pl_u.pl_x.pl_entryaddr, a);
2139			break;
2140
2141		case PMCLOG_TYPE_PROCEXIT:
2142
2143			/*
2144			 * Due to the way the log is generated, the
2145			 * last few samples corresponding to a process
2146			 * may appear in the log after the process
2147			 * exit event is recorded.  Thus we keep the
2148			 * process' descriptor and associated data
2149			 * structures around, but mark the process as
2150			 * having exited.
2151			 */
2152			pp = pmcstat_process_lookup(ev.pl_u.pl_e.pl_pid, 0);
2153			if (pp == NULL)
2154				break;
2155			pp->pp_isactive = 0;	/* mark as a zombie */
2156			break;
2157
2158		case PMCLOG_TYPE_SYSEXIT:
2159			pp = pmcstat_process_lookup(ev.pl_u.pl_se.pl_pid, 0);
2160			if (pp == NULL)
2161				break;
2162			pp->pp_isactive = 0;	/* make a zombie */
2163			break;
2164
2165		case PMCLOG_TYPE_PROCFORK:
2166
2167			/*
2168			 * Allocate a process descriptor for the new
2169			 * (child) process.
2170			 */
2171			ppnew =
2172			    pmcstat_process_lookup(ev.pl_u.pl_f.pl_newpid,
2173				PMCSTAT_ALLOCATE);
2174
2175			/*
2176			 * If we had been tracking the parent, clone
2177			 * its address maps.
2178			 */
2179			pp = pmcstat_process_lookup(ev.pl_u.pl_f.pl_oldpid, 0);
2180			if (pp == NULL)
2181				break;
2182			TAILQ_FOREACH(ppm, &pp->pp_map, ppm_next)
2183			    pmcstat_image_link(ppnew, ppm->ppm_image,
2184				ppm->ppm_lowpc);
2185			break;
2186
2187		default:	/* other types of entries are not relevant */
2188			break;
2189		}
2190	}
2191
2192	if (ev.pl_state == PMCLOG_EOF)
2193		return (PMCSTAT_FINISHED);
2194	else if (ev.pl_state == PMCLOG_REQUIRE_DATA)
2195		return (PMCSTAT_RUNNING);
2196
2197	err(EX_DATAERR, "ERROR: event parsing failed (record %jd, "
2198	    "offset 0x%jx)", (uintmax_t) ev.pl_count + 1, ev.pl_offset);
2199}
2200
2201/*
2202 * Print log entries as text.
2203 */
2204
2205static int
2206pmcstat_print_log(struct pmcstat_args *a)
2207{
2208	struct pmclog_ev ev;
2209	uint32_t npc;
2210
2211	while (pmclog_read(a->pa_logparser, &ev) == 0) {
2212		assert(ev.pl_state == PMCLOG_OK);
2213		switch (ev.pl_type) {
2214		case PMCLOG_TYPE_CALLCHAIN:
2215			PMCSTAT_PRINT_ENTRY(a, "callchain",
2216			    "%d 0x%x %d %d %c", ev.pl_u.pl_cc.pl_pid,
2217			    ev.pl_u.pl_cc.pl_pmcid,
2218			    PMC_CALLCHAIN_CPUFLAGS_TO_CPU(ev.pl_u.pl_cc. \
2219				pl_cpuflags), ev.pl_u.pl_cc.pl_npc,
2220			    PMC_CALLCHAIN_CPUFLAGS_TO_USERMODE(ev.pl_u.pl_cc.\
2221			        pl_cpuflags) ? 'u' : 's');
2222			for (npc = 0; npc < ev.pl_u.pl_cc.pl_npc; npc++)
2223				PMCSTAT_PRINT_ENTRY(a, "...", "%p",
2224				    (void *) ev.pl_u.pl_cc.pl_pc[npc]);
2225			break;
2226		case PMCLOG_TYPE_CLOSELOG:
2227			PMCSTAT_PRINT_ENTRY(a,"closelog",);
2228			break;
2229		case PMCLOG_TYPE_DROPNOTIFY:
2230			PMCSTAT_PRINT_ENTRY(a,"drop",);
2231			break;
2232		case PMCLOG_TYPE_INITIALIZE:
2233			PMCSTAT_PRINT_ENTRY(a,"initlog","0x%x \"%s\"",
2234			    ev.pl_u.pl_i.pl_version,
2235			    pmc_name_of_cputype(ev.pl_u.pl_i.pl_arch));
2236			if ((ev.pl_u.pl_i.pl_version & 0xFF000000) !=
2237			    PMC_VERSION_MAJOR << 24 && a->pa_verbosity > 0)
2238				warnx("WARNING: Log version 0x%x != expected "
2239				    "version 0x%x.", ev.pl_u.pl_i.pl_version,
2240				    PMC_VERSION);
2241			break;
2242		case PMCLOG_TYPE_MAP_IN:
2243			PMCSTAT_PRINT_ENTRY(a,"map-in","%d %p \"%s\"",
2244			    ev.pl_u.pl_mi.pl_pid,
2245			    (void *) ev.pl_u.pl_mi.pl_start,
2246			    ev.pl_u.pl_mi.pl_pathname);
2247			break;
2248		case PMCLOG_TYPE_MAP_OUT:
2249			PMCSTAT_PRINT_ENTRY(a,"map-out","%d %p %p",
2250			    ev.pl_u.pl_mo.pl_pid,
2251			    (void *) ev.pl_u.pl_mo.pl_start,
2252			    (void *) ev.pl_u.pl_mo.pl_end);
2253			break;
2254		case PMCLOG_TYPE_PCSAMPLE:
2255			PMCSTAT_PRINT_ENTRY(a,"sample","0x%x %d %p %c",
2256			    ev.pl_u.pl_s.pl_pmcid,
2257			    ev.pl_u.pl_s.pl_pid,
2258			    (void *) ev.pl_u.pl_s.pl_pc,
2259			    ev.pl_u.pl_s.pl_usermode ? 'u' : 's');
2260			break;
2261		case PMCLOG_TYPE_PMCALLOCATE:
2262			PMCSTAT_PRINT_ENTRY(a,"allocate","0x%x \"%s\" 0x%x",
2263			    ev.pl_u.pl_a.pl_pmcid,
2264			    ev.pl_u.pl_a.pl_evname,
2265			    ev.pl_u.pl_a.pl_flags);
2266			break;
2267		case PMCLOG_TYPE_PMCATTACH:
2268			PMCSTAT_PRINT_ENTRY(a,"attach","0x%x %d \"%s\"",
2269			    ev.pl_u.pl_t.pl_pmcid,
2270			    ev.pl_u.pl_t.pl_pid,
2271			    ev.pl_u.pl_t.pl_pathname);
2272			break;
2273		case PMCLOG_TYPE_PMCDETACH:
2274			PMCSTAT_PRINT_ENTRY(a,"detach","0x%x %d",
2275			    ev.pl_u.pl_d.pl_pmcid,
2276			    ev.pl_u.pl_d.pl_pid);
2277			break;
2278		case PMCLOG_TYPE_PROCCSW:
2279			PMCSTAT_PRINT_ENTRY(a,"cswval","0x%x %d %jd",
2280			    ev.pl_u.pl_c.pl_pmcid,
2281			    ev.pl_u.pl_c.pl_pid,
2282			    ev.pl_u.pl_c.pl_value);
2283			break;
2284		case PMCLOG_TYPE_PROCEXEC:
2285			PMCSTAT_PRINT_ENTRY(a,"exec","0x%x %d %p \"%s\"",
2286			    ev.pl_u.pl_x.pl_pmcid,
2287			    ev.pl_u.pl_x.pl_pid,
2288			    (void *) ev.pl_u.pl_x.pl_entryaddr,
2289			    ev.pl_u.pl_x.pl_pathname);
2290			break;
2291		case PMCLOG_TYPE_PROCEXIT:
2292			PMCSTAT_PRINT_ENTRY(a,"exitval","0x%x %d %jd",
2293			    ev.pl_u.pl_e.pl_pmcid,
2294			    ev.pl_u.pl_e.pl_pid,
2295			    ev.pl_u.pl_e.pl_value);
2296			break;
2297		case PMCLOG_TYPE_PROCFORK:
2298			PMCSTAT_PRINT_ENTRY(a,"fork","%d %d",
2299			    ev.pl_u.pl_f.pl_oldpid,
2300			    ev.pl_u.pl_f.pl_newpid);
2301			break;
2302		case PMCLOG_TYPE_USERDATA:
2303			PMCSTAT_PRINT_ENTRY(a,"userdata","0x%x",
2304			    ev.pl_u.pl_u.pl_userdata);
2305			break;
2306		case PMCLOG_TYPE_SYSEXIT:
2307			PMCSTAT_PRINT_ENTRY(a,"exit","%d",
2308			    ev.pl_u.pl_se.pl_pid);
2309			break;
2310		default:
2311			fprintf(a->pa_printfile, "unknown event (type %d).\n",
2312			    ev.pl_type);
2313		}
2314	}
2315
2316	if (ev.pl_state == PMCLOG_EOF)
2317		return (PMCSTAT_FINISHED);
2318	else if (ev.pl_state ==  PMCLOG_REQUIRE_DATA)
2319		return (PMCSTAT_RUNNING);
2320
2321	errx(EX_DATAERR, "ERROR: event parsing failed "
2322	    "(record %jd, offset 0x%jx).",
2323	    (uintmax_t) ev.pl_count + 1, ev.pl_offset);
2324	/*NOTREACHED*/
2325}
2326
2327/*
2328 * Public Interfaces.
2329 */
2330
2331/*
2332 * Close a logfile, after first flushing all in-module queued data.
2333 */
2334
2335int
2336pmcstat_close_log(struct pmcstat_args *a)
2337{
2338	if (pmc_flush_logfile() < 0 ||
2339	    pmc_configure_logfile(-1) < 0)
2340		err(EX_OSERR, "ERROR: logging failed");
2341	a->pa_flags &= ~(FLAG_HAS_OUTPUT_LOGFILE | FLAG_HAS_PIPE);
2342	return (a->pa_flags & FLAG_HAS_PIPE ? PMCSTAT_EXITING :
2343	    PMCSTAT_FINISHED);
2344}
2345
2346
2347
2348/*
2349 * Open a log file, for reading or writing.
2350 *
2351 * The function returns the fd of a successfully opened log or -1 in
2352 * case of failure.
2353 */
2354
2355int
2356pmcstat_open_log(const char *path, int mode)
2357{
2358	int error, fd;
2359	size_t hlen;
2360	const char *p, *errstr;
2361	struct addrinfo hints, *res, *res0;
2362	char hostname[MAXHOSTNAMELEN];
2363
2364	errstr = NULL;
2365	fd = -1;
2366
2367	/*
2368	 * If 'path' is "-" then open one of stdin or stdout depending
2369	 * on the value of 'mode'.
2370	 *
2371	 * If 'path' contains a ':' and does not start with a '/' or '.',
2372	 * and is being opened for writing, treat it as a "host:port"
2373	 * specification and open a network socket.
2374	 *
2375	 * Otherwise, treat 'path' as a file name and open that.
2376	 */
2377	if (path[0] == '-' && path[1] == '\0')
2378		fd = (mode == PMCSTAT_OPEN_FOR_READ) ? 0 : 1;
2379	else if (mode == PMCSTAT_OPEN_FOR_WRITE && path[0] != '/' &&
2380	    path[0] != '.' && strchr(path, ':') != NULL) {
2381
2382		p = strrchr(path, ':');
2383		hlen = p - path;
2384		if (p == path || hlen >= sizeof(hostname)) {
2385			errstr = strerror(EINVAL);
2386			goto done;
2387		}
2388
2389		assert(hlen < sizeof(hostname));
2390		(void) strncpy(hostname, path, hlen);
2391		hostname[hlen] = '\0';
2392
2393		(void) memset(&hints, 0, sizeof(hints));
2394		hints.ai_family = AF_UNSPEC;
2395		hints.ai_socktype = SOCK_STREAM;
2396		if ((error = getaddrinfo(hostname, p+1, &hints, &res0)) != 0) {
2397			errstr = gai_strerror(error);
2398			goto done;
2399		}
2400
2401		fd = -1;
2402		for (res = res0; res; res = res->ai_next) {
2403			if ((fd = socket(res->ai_family, res->ai_socktype,
2404			    res->ai_protocol)) < 0) {
2405				errstr = strerror(errno);
2406				continue;
2407			}
2408			if (connect(fd, res->ai_addr, res->ai_addrlen) < 0) {
2409				errstr = strerror(errno);
2410				(void) close(fd);
2411				fd = -1;
2412				continue;
2413			}
2414			errstr = NULL;
2415			break;
2416		}
2417		freeaddrinfo(res0);
2418
2419	} else if ((fd = open(path, mode == PMCSTAT_OPEN_FOR_READ ?
2420		    O_RDONLY : (O_WRONLY|O_CREAT|O_TRUNC),
2421		    S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) < 0)
2422			errstr = strerror(errno);
2423
2424  done:
2425	if (errstr)
2426		errx(EX_OSERR, "ERROR: Cannot open \"%s\" for %s: %s.", path,
2427		    (mode == PMCSTAT_OPEN_FOR_READ ? "reading" : "writing"),
2428		    errstr);
2429
2430	return (fd);
2431}
2432
2433/*
2434 * Process a log file in offline analysis mode.
2435 */
2436
2437int
2438pmcstat_process_log(struct pmcstat_args *a)
2439{
2440
2441	/*
2442	 * If analysis has not been asked for, just print the log to
2443	 * the current output file.
2444	 */
2445	if (a->pa_flags & FLAG_DO_PRINT)
2446		return (pmcstat_print_log(a));
2447	else
2448		return (pmcstat_analyze_log(a));
2449}
2450
2451/*
2452 * Initialize module.
2453 */
2454
2455void
2456pmcstat_initialize_logging(struct pmcstat_args *a)
2457{
2458	int i;
2459
2460	(void) a;
2461
2462	/* use a convenient format for 'ldd' output */
2463	if (setenv("LD_TRACE_LOADED_OBJECTS_FMT1","%o \"%p\" %x\n",1) != 0)
2464		err(EX_OSERR, "ERROR: Cannot setenv");
2465
2466	/* Initialize hash tables */
2467	pmcstat_string_initialize();
2468	for (i = 0; i < PMCSTAT_NHASH; i++) {
2469		LIST_INIT(&pmcstat_image_hash[i]);
2470		LIST_INIT(&pmcstat_process_hash[i]);
2471	}
2472
2473	/*
2474	 * Create a fake 'process' entry for the kernel with pid -1.
2475	 * hwpmc(4) will subsequently inform us about where the kernel
2476	 * and any loaded kernel modules are mapped.
2477	 */
2478	if ((pmcstat_kernproc = pmcstat_process_lookup((pid_t) -1,
2479		 PMCSTAT_ALLOCATE)) == NULL)
2480		err(EX_OSERR, "ERROR: Cannot initialize logging");
2481}
2482
2483/*
2484 * Shutdown module.
2485 */
2486
2487void
2488pmcstat_shutdown_logging(struct pmcstat_args *a)
2489{
2490	int i;
2491	FILE *mf;
2492	struct pmcstat_gmonfile *pgf, *pgftmp;
2493	struct pmcstat_image *pi, *pitmp;
2494	struct pmcstat_process *pp, *pptmp;
2495	struct pmcstat_cgnode_hash *pch, *pchtmp;
2496
2497	/* determine where to send the map file */
2498	mf = NULL;
2499	if (a->pa_mapfilename != NULL)
2500		mf = (strcmp(a->pa_mapfilename, "-") == 0) ?
2501		    a->pa_printfile : fopen(a->pa_mapfilename, "w");
2502
2503	if (mf == NULL && a->pa_flags & FLAG_DO_GPROF &&
2504	    a->pa_verbosity >= 2)
2505		mf = a->pa_printfile;
2506
2507	if (mf)
2508		(void) fprintf(mf, "MAP:\n");
2509
2510
2511	if (a->pa_flags & FLAG_DO_CALLGRAPHS)
2512		pmcstat_callgraph_print(a);
2513
2514	/*
2515	 * Sync back all gprof flat profile data.
2516	 */
2517	for (i = 0; i < PMCSTAT_NHASH; i++) {
2518		LIST_FOREACH(pi, &pmcstat_image_hash[i], pi_next) {
2519			if (mf)
2520				(void) fprintf(mf, " \"%s\" => \"%s\"",
2521				    pmcstat_string_unintern(pi->pi_execpath),
2522				    pmcstat_string_unintern(
2523				    pi->pi_samplename));
2524
2525			/* flush gmon.out data to disk */
2526			LIST_FOREACH(pgf, &pi->pi_gmlist, pgf_next) {
2527				pmcstat_gmon_unmap_file(pgf);
2528				if (mf)
2529					(void) fprintf(mf, " %s/%d",
2530					    pmcstat_pmcid_to_name(
2531					    pgf->pgf_pmcid),
2532					    pgf->pgf_nsamples);
2533				if (pgf->pgf_overflow && a->pa_verbosity >= 1)
2534					warnx("WARNING: profile \"%s\" "
2535					    "overflowed.",
2536					    pmcstat_string_unintern(
2537					        pgf->pgf_name));
2538			}
2539
2540			if (mf)
2541				(void) fprintf(mf, "\n");
2542		}
2543	}
2544
2545	/*
2546	 * Compute arcs and add these to the gprof files.
2547	 */
2548	if (a->pa_flags & FLAG_DO_GPROF && a->pa_graphdepth > 1)
2549		pmcstat_callgraph_do_gmon_arcs();
2550
2551	/*
2552	 * Free memory.
2553	 */
2554	for (i = 0; i < PMCSTAT_NHASH; i++) {
2555		LIST_FOREACH_SAFE(pch, &pmcstat_cgnode_hash[i], pch_next,
2556		    pchtmp) {
2557			pmcstat_cgnode_free(pch->pch_cgnode);
2558			free(pch);
2559		}
2560	}
2561
2562	for (i = 0; i < PMCSTAT_NHASH; i++) {
2563		LIST_FOREACH_SAFE(pi, &pmcstat_image_hash[i], pi_next, pitmp)
2564		{
2565			LIST_FOREACH_SAFE(pgf, &pi->pi_gmlist, pgf_next,
2566			    pgftmp) {
2567				if (pgf->pgf_file)
2568					(void) fclose(pgf->pgf_file);
2569				LIST_REMOVE(pgf, pgf_next);
2570				free(pgf);
2571			}
2572			if (pi->pi_symbols)
2573				free(pi->pi_symbols);
2574
2575			LIST_REMOVE(pi, pi_next);
2576			free(pi);
2577		}
2578
2579		LIST_FOREACH_SAFE(pp, &pmcstat_process_hash[i], pp_next,
2580		    pptmp) {
2581			LIST_REMOVE(pp, pp_next);
2582			free(pp);
2583		}
2584	}
2585
2586	pmcstat_string_shutdown();
2587
2588	/*
2589	 * Print errors unless -q was specified.  Print all statistics
2590	 * if verbosity > 1.
2591	 */
2592#define	PRINT(N,V,A) do {						\
2593		if (pmcstat_stats.ps_##V || (A)->pa_verbosity >= 2)	\
2594			(void) fprintf((A)->pa_printfile, " %-40s %d\n",\
2595			    N, pmcstat_stats.ps_##V);			\
2596	} while (0)
2597
2598	if (a->pa_verbosity >= 1 && a->pa_flags & FLAG_DO_GPROF) {
2599		(void) fprintf(a->pa_printfile, "CONVERSION STATISTICS:\n");
2600		PRINT("#exec/a.out", exec_aout, a);
2601		PRINT("#exec/elf", exec_elf, a);
2602		PRINT("#exec/unknown", exec_indeterminable, a);
2603		PRINT("#exec handling errors", exec_errors, a);
2604		PRINT("#samples/total", samples_total, a);
2605		PRINT("#samples/unclaimed", samples_unknown_offset, a);
2606		PRINT("#samples/unknown-object", samples_indeterminable, a);
2607		PRINT("#callchain/dubious-frames", callchain_dubious_frames,
2608		    a);
2609	}
2610
2611	if (mf)
2612		(void) fclose(mf);
2613}
2614