1*85ec49f3SAdrian Chadd /*- 2*85ec49f3SAdrian Chadd * Copyright (c) 2005-2007, Joseph Koshy 3*85ec49f3SAdrian Chadd * Copyright (c) 2007 The FreeBSD Foundation 4*85ec49f3SAdrian Chadd * All rights reserved. 5*85ec49f3SAdrian Chadd * 6*85ec49f3SAdrian Chadd * Portions of this software were developed by A. Joseph Koshy under 7*85ec49f3SAdrian Chadd * sponsorship from the FreeBSD Foundation and Google, Inc. 8*85ec49f3SAdrian Chadd * 9*85ec49f3SAdrian Chadd * Redistribution and use in source and binary forms, with or without 10*85ec49f3SAdrian Chadd * modification, are permitted provided that the following conditions 11*85ec49f3SAdrian Chadd * are met: 12*85ec49f3SAdrian Chadd * 1. Redistributions of source code must retain the above copyright 13*85ec49f3SAdrian Chadd * notice, this list of conditions and the following disclaimer. 14*85ec49f3SAdrian Chadd * 2. Redistributions in binary form must reproduce the above copyright 15*85ec49f3SAdrian Chadd * notice, this list of conditions and the following disclaimer in the 16*85ec49f3SAdrian Chadd * documentation and/or other materials provided with the distribution. 17*85ec49f3SAdrian Chadd * 18*85ec49f3SAdrian Chadd * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19*85ec49f3SAdrian Chadd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20*85ec49f3SAdrian Chadd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21*85ec49f3SAdrian Chadd * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22*85ec49f3SAdrian Chadd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23*85ec49f3SAdrian Chadd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24*85ec49f3SAdrian Chadd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25*85ec49f3SAdrian Chadd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26*85ec49f3SAdrian Chadd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27*85ec49f3SAdrian Chadd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28*85ec49f3SAdrian Chadd * SUCH DAMAGE. 29*85ec49f3SAdrian Chadd */ 30*85ec49f3SAdrian Chadd 31*85ec49f3SAdrian Chadd /* 32*85ec49f3SAdrian Chadd * Transform a hwpmc(4) log into human readable form, and into 33*85ec49f3SAdrian Chadd * gprof(1) compatible profiles. 34*85ec49f3SAdrian Chadd */ 35*85ec49f3SAdrian Chadd 36*85ec49f3SAdrian Chadd #include <sys/cdefs.h> 37*85ec49f3SAdrian Chadd __FBSDID("$FreeBSD$"); 38*85ec49f3SAdrian Chadd 39*85ec49f3SAdrian Chadd #include <sys/param.h> 40*85ec49f3SAdrian Chadd #include <sys/endian.h> 41*85ec49f3SAdrian Chadd #include <sys/gmon.h> 42*85ec49f3SAdrian Chadd #include <sys/imgact_aout.h> 43*85ec49f3SAdrian Chadd #include <sys/imgact_elf.h> 44*85ec49f3SAdrian Chadd #include <sys/mman.h> 45*85ec49f3SAdrian Chadd #include <sys/pmc.h> 46*85ec49f3SAdrian Chadd #include <sys/queue.h> 47*85ec49f3SAdrian Chadd #include <sys/socket.h> 48*85ec49f3SAdrian Chadd #include <sys/stat.h> 49*85ec49f3SAdrian Chadd #include <sys/wait.h> 50*85ec49f3SAdrian Chadd 51*85ec49f3SAdrian Chadd #include <netinet/in.h> 52*85ec49f3SAdrian Chadd 53*85ec49f3SAdrian Chadd #include <assert.h> 54*85ec49f3SAdrian Chadd #include <err.h> 55*85ec49f3SAdrian Chadd #include <errno.h> 56*85ec49f3SAdrian Chadd #include <fcntl.h> 57*85ec49f3SAdrian Chadd #include <gelf.h> 58*85ec49f3SAdrian Chadd #include <libgen.h> 59*85ec49f3SAdrian Chadd #include <limits.h> 60*85ec49f3SAdrian Chadd #include <netdb.h> 61*85ec49f3SAdrian Chadd #include <pmc.h> 62*85ec49f3SAdrian Chadd #include <pmclog.h> 63*85ec49f3SAdrian Chadd #include <sysexits.h> 64*85ec49f3SAdrian Chadd #include <stdint.h> 65*85ec49f3SAdrian Chadd #include <stdio.h> 66*85ec49f3SAdrian Chadd #include <stdlib.h> 67*85ec49f3SAdrian Chadd #include <string.h> 68*85ec49f3SAdrian Chadd #include <unistd.h> 69*85ec49f3SAdrian Chadd 70*85ec49f3SAdrian Chadd #include "pmcstat.h" 71*85ec49f3SAdrian Chadd #include "pmcstat_log.h" 72*85ec49f3SAdrian Chadd #include "pmcpl_annotate_cg.h" 73*85ec49f3SAdrian Chadd 74*85ec49f3SAdrian Chadd /* 75*85ec49f3SAdrian Chadd * Record a callchain. 76*85ec49f3SAdrian Chadd */ 77*85ec49f3SAdrian Chadd 78*85ec49f3SAdrian Chadd void 79*85ec49f3SAdrian Chadd pmcpl_annotate_cg_process(struct pmcstat_process *pp, struct pmcstat_pmcrecord *pmcr, 80*85ec49f3SAdrian Chadd uint32_t nsamples, uintfptr_t *cc, int usermode, uint32_t cpu) 81*85ec49f3SAdrian Chadd { 82*85ec49f3SAdrian Chadd struct pmcstat_pcmap *map; 83*85ec49f3SAdrian Chadd struct pmcstat_symbol *sym; 84*85ec49f3SAdrian Chadd uintfptr_t newpc; 85*85ec49f3SAdrian Chadd struct pmcstat_image *image; 86*85ec49f3SAdrian Chadd int i; 87*85ec49f3SAdrian Chadd char filename[PATH_MAX], funcname[PATH_MAX]; 88*85ec49f3SAdrian Chadd unsigned sline; 89*85ec49f3SAdrian Chadd 90*85ec49f3SAdrian Chadd (void) pmcr; (void) nsamples; (void) usermode; (void) cpu; 91*85ec49f3SAdrian Chadd 92*85ec49f3SAdrian Chadd for (i = 0; i < (int) nsamples; i++) { 93*85ec49f3SAdrian Chadd map = NULL; 94*85ec49f3SAdrian Chadd sym = NULL; 95*85ec49f3SAdrian Chadd image = NULL; 96*85ec49f3SAdrian Chadd filename[0] = '\0'; 97*85ec49f3SAdrian Chadd funcname[0] = '\0'; 98*85ec49f3SAdrian Chadd sline = 0; 99*85ec49f3SAdrian Chadd 100*85ec49f3SAdrian Chadd map = pmcstat_process_find_map(usermode ? pp : pmcstat_kernproc, cc[i]); 101*85ec49f3SAdrian Chadd if (map != NULL) { 102*85ec49f3SAdrian Chadd assert(cc[i] >= map->ppm_lowpc && cc[i] < map->ppm_highpc); 103*85ec49f3SAdrian Chadd image = map->ppm_image; 104*85ec49f3SAdrian Chadd newpc = cc[i] - (map->ppm_lowpc + 105*85ec49f3SAdrian Chadd (image->pi_vaddr - image->pi_start)); 106*85ec49f3SAdrian Chadd sym = pmcstat_symbol_search(image, newpc); 107*85ec49f3SAdrian Chadd } 108*85ec49f3SAdrian Chadd 109*85ec49f3SAdrian Chadd if (map != NULL && image != NULL && sym != NULL) { 110*85ec49f3SAdrian Chadd (void) pmcstat_image_addr2line(image, cc[i], 111*85ec49f3SAdrian Chadd filename, sizeof(filename), &sline, funcname, sizeof(funcname)); 112*85ec49f3SAdrian Chadd } 113*85ec49f3SAdrian Chadd 114*85ec49f3SAdrian Chadd if (map != NULL && sym != NULL) { 115*85ec49f3SAdrian Chadd fprintf(args.pa_graphfile, "%p %s %s:%d\n", 116*85ec49f3SAdrian Chadd (void *)cc[i], 117*85ec49f3SAdrian Chadd funcname, 118*85ec49f3SAdrian Chadd filename, 119*85ec49f3SAdrian Chadd sline); 120*85ec49f3SAdrian Chadd } else { 121*85ec49f3SAdrian Chadd fprintf(args.pa_graphfile, "%p <unknown> ??:0\n", 122*85ec49f3SAdrian Chadd (void *) cc[i]); 123*85ec49f3SAdrian Chadd } 124*85ec49f3SAdrian Chadd } 125*85ec49f3SAdrian Chadd fprintf(args.pa_graphfile, "--\n"); 126*85ec49f3SAdrian Chadd } 127