185ec49f3SAdrian Chadd /*- 21de7b4b8SPedro F. Giffuni * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 31de7b4b8SPedro F. Giffuni * 485ec49f3SAdrian Chadd * Copyright (c) 2005-2007, Joseph Koshy 585ec49f3SAdrian Chadd * Copyright (c) 2007 The FreeBSD Foundation 685ec49f3SAdrian Chadd * All rights reserved. 785ec49f3SAdrian Chadd * 8*52467047SWarner Losh * Copyright (c) 2014 Netflix, Inc. 9*52467047SWarner Losh * Written by: Adrian Chadd <adrian@FreeBSD.org> 10*52467047SWarner Losh * 1185ec49f3SAdrian Chadd * Portions of this software were developed by A. Joseph Koshy under 1285ec49f3SAdrian Chadd * sponsorship from the FreeBSD Foundation and Google, Inc. 1385ec49f3SAdrian Chadd * 1485ec49f3SAdrian Chadd * Redistribution and use in source and binary forms, with or without 1585ec49f3SAdrian Chadd * modification, are permitted provided that the following conditions 1685ec49f3SAdrian Chadd * are met: 1785ec49f3SAdrian Chadd * 1. Redistributions of source code must retain the above copyright 1885ec49f3SAdrian Chadd * notice, this list of conditions and the following disclaimer. 1985ec49f3SAdrian Chadd * 2. Redistributions in binary form must reproduce the above copyright 2085ec49f3SAdrian Chadd * notice, this list of conditions and the following disclaimer in the 2185ec49f3SAdrian Chadd * documentation and/or other materials provided with the distribution. 2285ec49f3SAdrian Chadd * 2385ec49f3SAdrian Chadd * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 2485ec49f3SAdrian Chadd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2585ec49f3SAdrian Chadd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2685ec49f3SAdrian Chadd * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2785ec49f3SAdrian Chadd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2885ec49f3SAdrian Chadd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2985ec49f3SAdrian Chadd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3085ec49f3SAdrian Chadd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3185ec49f3SAdrian Chadd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3285ec49f3SAdrian Chadd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3385ec49f3SAdrian Chadd * SUCH DAMAGE. 3485ec49f3SAdrian Chadd */ 3585ec49f3SAdrian Chadd 3685ec49f3SAdrian Chadd /* 3785ec49f3SAdrian Chadd * Transform a hwpmc(4) log into human readable form, and into 3885ec49f3SAdrian Chadd * gprof(1) compatible profiles. 3985ec49f3SAdrian Chadd */ 4085ec49f3SAdrian Chadd 4185ec49f3SAdrian Chadd #include <sys/cdefs.h> 4285ec49f3SAdrian Chadd __FBSDID("$FreeBSD$"); 4385ec49f3SAdrian Chadd 4485ec49f3SAdrian Chadd #include <sys/param.h> 4585ec49f3SAdrian Chadd #include <sys/endian.h> 4685ec49f3SAdrian Chadd #include <sys/gmon.h> 4785ec49f3SAdrian Chadd #include <sys/imgact_aout.h> 4885ec49f3SAdrian Chadd #include <sys/imgact_elf.h> 4985ec49f3SAdrian Chadd #include <sys/mman.h> 5085ec49f3SAdrian Chadd #include <sys/pmc.h> 5185ec49f3SAdrian Chadd #include <sys/queue.h> 5285ec49f3SAdrian Chadd #include <sys/socket.h> 5385ec49f3SAdrian Chadd #include <sys/stat.h> 5485ec49f3SAdrian Chadd #include <sys/wait.h> 5585ec49f3SAdrian Chadd 5685ec49f3SAdrian Chadd #include <netinet/in.h> 5785ec49f3SAdrian Chadd 5885ec49f3SAdrian Chadd #include <assert.h> 5985ec49f3SAdrian Chadd #include <err.h> 6085ec49f3SAdrian Chadd #include <errno.h> 6185ec49f3SAdrian Chadd #include <fcntl.h> 6285ec49f3SAdrian Chadd #include <gelf.h> 6385ec49f3SAdrian Chadd #include <libgen.h> 6485ec49f3SAdrian Chadd #include <limits.h> 6585ec49f3SAdrian Chadd #include <netdb.h> 6685ec49f3SAdrian Chadd #include <pmc.h> 6785ec49f3SAdrian Chadd #include <pmclog.h> 6885ec49f3SAdrian Chadd #include <sysexits.h> 6985ec49f3SAdrian Chadd #include <stdint.h> 7085ec49f3SAdrian Chadd #include <stdio.h> 7185ec49f3SAdrian Chadd #include <stdlib.h> 7285ec49f3SAdrian Chadd #include <string.h> 7385ec49f3SAdrian Chadd #include <unistd.h> 7485ec49f3SAdrian Chadd 7585ec49f3SAdrian Chadd #include "pmcstat.h" 7685ec49f3SAdrian Chadd #include "pmcstat_log.h" 7785ec49f3SAdrian Chadd #include "pmcpl_annotate_cg.h" 7885ec49f3SAdrian Chadd 7985ec49f3SAdrian Chadd /* 8085ec49f3SAdrian Chadd * Record a callchain. 8185ec49f3SAdrian Chadd */ 8285ec49f3SAdrian Chadd 8385ec49f3SAdrian Chadd void 8485ec49f3SAdrian Chadd pmcpl_annotate_cg_process(struct pmcstat_process *pp, struct pmcstat_pmcrecord *pmcr, 8585ec49f3SAdrian Chadd uint32_t nsamples, uintfptr_t *cc, int usermode, uint32_t cpu) 8685ec49f3SAdrian Chadd { 8785ec49f3SAdrian Chadd struct pmcstat_pcmap *map; 8885ec49f3SAdrian Chadd struct pmcstat_symbol *sym; 8985ec49f3SAdrian Chadd uintfptr_t newpc; 9085ec49f3SAdrian Chadd struct pmcstat_image *image; 9185ec49f3SAdrian Chadd int i; 9285ec49f3SAdrian Chadd char filename[PATH_MAX], funcname[PATH_MAX]; 9385ec49f3SAdrian Chadd unsigned sline; 9485ec49f3SAdrian Chadd 9585ec49f3SAdrian Chadd (void) pmcr; (void) nsamples; (void) usermode; (void) cpu; 9685ec49f3SAdrian Chadd 9785ec49f3SAdrian Chadd for (i = 0; i < (int) nsamples; i++) { 9885ec49f3SAdrian Chadd map = NULL; 9985ec49f3SAdrian Chadd sym = NULL; 10085ec49f3SAdrian Chadd image = NULL; 10185ec49f3SAdrian Chadd filename[0] = '\0'; 10285ec49f3SAdrian Chadd funcname[0] = '\0'; 10385ec49f3SAdrian Chadd sline = 0; 10485ec49f3SAdrian Chadd 10585ec49f3SAdrian Chadd map = pmcstat_process_find_map(usermode ? pp : pmcstat_kernproc, cc[i]); 10685ec49f3SAdrian Chadd if (map != NULL) { 10785ec49f3SAdrian Chadd assert(cc[i] >= map->ppm_lowpc && cc[i] < map->ppm_highpc); 10885ec49f3SAdrian Chadd image = map->ppm_image; 10985ec49f3SAdrian Chadd newpc = cc[i] - (map->ppm_lowpc + 11085ec49f3SAdrian Chadd (image->pi_vaddr - image->pi_start)); 11185ec49f3SAdrian Chadd sym = pmcstat_symbol_search(image, newpc); 11285ec49f3SAdrian Chadd } 11385ec49f3SAdrian Chadd 11485ec49f3SAdrian Chadd if (map != NULL && image != NULL && sym != NULL) { 11585ec49f3SAdrian Chadd (void) pmcstat_image_addr2line(image, cc[i], 11685ec49f3SAdrian Chadd filename, sizeof(filename), &sline, funcname, sizeof(funcname)); 11785ec49f3SAdrian Chadd } 11885ec49f3SAdrian Chadd 11985ec49f3SAdrian Chadd if (map != NULL && sym != NULL) { 12085ec49f3SAdrian Chadd fprintf(args.pa_graphfile, "%p %s %s:%d\n", 12185ec49f3SAdrian Chadd (void *)cc[i], 12285ec49f3SAdrian Chadd funcname, 12385ec49f3SAdrian Chadd filename, 12485ec49f3SAdrian Chadd sline); 12585ec49f3SAdrian Chadd } else { 12685ec49f3SAdrian Chadd fprintf(args.pa_graphfile, "%p <unknown> ??:0\n", 12785ec49f3SAdrian Chadd (void *) cc[i]); 12885ec49f3SAdrian Chadd } 12985ec49f3SAdrian Chadd } 13085ec49f3SAdrian Chadd fprintf(args.pa_graphfile, "--\n"); 13185ec49f3SAdrian Chadd } 132