1262424Sadrian/*- 2262424Sadrian * Copyright (c) 2005-2007, Joseph Koshy 3262424Sadrian * Copyright (c) 2007 The FreeBSD Foundation 4265604Sscottl * Copyright (c) 2014, Adrian Chadd, Netflix Inc. 5262424Sadrian * All rights reserved. 6262424Sadrian * 7262424Sadrian * Portions of this software were developed by A. Joseph Koshy under 8262424Sadrian * sponsorship from the FreeBSD Foundation and Google, Inc. 9262424Sadrian * 10262424Sadrian * Redistribution and use in source and binary forms, with or without 11262424Sadrian * modification, are permitted provided that the following conditions 12262424Sadrian * are met: 13262424Sadrian * 1. Redistributions of source code must retain the above copyright 14262424Sadrian * notice, this list of conditions and the following disclaimer. 15262424Sadrian * 2. Redistributions in binary form must reproduce the above copyright 16262424Sadrian * notice, this list of conditions and the following disclaimer in the 17262424Sadrian * documentation and/or other materials provided with the distribution. 18262424Sadrian * 19262424Sadrian * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 20262424Sadrian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21262424Sadrian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22262424Sadrian * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 23262424Sadrian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24262424Sadrian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25262424Sadrian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26262424Sadrian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27262424Sadrian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28262424Sadrian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29262424Sadrian * SUCH DAMAGE. 30262424Sadrian */ 31262424Sadrian 32262424Sadrian/* 33262424Sadrian * Transform a hwpmc(4) log into human readable form, and into 34262424Sadrian * gprof(1) compatible profiles. 35262424Sadrian */ 36262424Sadrian 37262424Sadrian#include <sys/cdefs.h> 38262424Sadrian__FBSDID("$FreeBSD$"); 39262424Sadrian 40262424Sadrian#include <sys/param.h> 41262424Sadrian#include <sys/endian.h> 42262424Sadrian#include <sys/gmon.h> 43262424Sadrian#include <sys/imgact_aout.h> 44262424Sadrian#include <sys/imgact_elf.h> 45262424Sadrian#include <sys/mman.h> 46262424Sadrian#include <sys/pmc.h> 47262424Sadrian#include <sys/queue.h> 48262424Sadrian#include <sys/socket.h> 49262424Sadrian#include <sys/stat.h> 50262424Sadrian#include <sys/wait.h> 51262424Sadrian 52262424Sadrian#include <netinet/in.h> 53262424Sadrian 54262424Sadrian#include <assert.h> 55262424Sadrian#include <err.h> 56262424Sadrian#include <errno.h> 57262424Sadrian#include <fcntl.h> 58262424Sadrian#include <gelf.h> 59262424Sadrian#include <libgen.h> 60262424Sadrian#include <limits.h> 61262424Sadrian#include <netdb.h> 62262424Sadrian#include <pmc.h> 63262424Sadrian#include <pmclog.h> 64262424Sadrian#include <sysexits.h> 65262424Sadrian#include <stdint.h> 66262424Sadrian#include <stdio.h> 67262424Sadrian#include <stdlib.h> 68262424Sadrian#include <string.h> 69262424Sadrian#include <unistd.h> 70262424Sadrian 71262424Sadrian#include "pmcstat.h" 72262424Sadrian#include "pmcstat_log.h" 73262424Sadrian#include "pmcpl_annotate_cg.h" 74262424Sadrian 75262424Sadrian/* 76262424Sadrian * Record a callchain. 77262424Sadrian */ 78262424Sadrian 79262424Sadrianvoid 80262424Sadrianpmcpl_annotate_cg_process(struct pmcstat_process *pp, struct pmcstat_pmcrecord *pmcr, 81262424Sadrian uint32_t nsamples, uintfptr_t *cc, int usermode, uint32_t cpu) 82262424Sadrian{ 83262424Sadrian struct pmcstat_pcmap *map; 84262424Sadrian struct pmcstat_symbol *sym; 85262424Sadrian uintfptr_t newpc; 86262424Sadrian struct pmcstat_image *image; 87262424Sadrian int i; 88262424Sadrian char filename[PATH_MAX], funcname[PATH_MAX]; 89262424Sadrian unsigned sline; 90262424Sadrian 91262424Sadrian (void) pmcr; (void) nsamples; (void) usermode; (void) cpu; 92262424Sadrian 93262424Sadrian for (i = 0; i < (int) nsamples; i++) { 94262424Sadrian map = NULL; 95262424Sadrian sym = NULL; 96262424Sadrian image = NULL; 97262424Sadrian filename[0] = '\0'; 98262424Sadrian funcname[0] = '\0'; 99262424Sadrian sline = 0; 100262424Sadrian 101262424Sadrian map = pmcstat_process_find_map(usermode ? pp : pmcstat_kernproc, cc[i]); 102262424Sadrian if (map != NULL) { 103262424Sadrian assert(cc[i] >= map->ppm_lowpc && cc[i] < map->ppm_highpc); 104262424Sadrian image = map->ppm_image; 105262424Sadrian newpc = cc[i] - (map->ppm_lowpc + 106262424Sadrian (image->pi_vaddr - image->pi_start)); 107262424Sadrian sym = pmcstat_symbol_search(image, newpc); 108262424Sadrian } 109262424Sadrian 110262424Sadrian if (map != NULL && image != NULL && sym != NULL) { 111262424Sadrian (void) pmcstat_image_addr2line(image, cc[i], 112262424Sadrian filename, sizeof(filename), &sline, funcname, sizeof(funcname)); 113262424Sadrian } 114262424Sadrian 115262424Sadrian if (map != NULL && sym != NULL) { 116262424Sadrian fprintf(args.pa_graphfile, "%p %s %s:%d\n", 117262424Sadrian (void *)cc[i], 118262424Sadrian funcname, 119262424Sadrian filename, 120262424Sadrian sline); 121262424Sadrian } else { 122262424Sadrian fprintf(args.pa_graphfile, "%p <unknown> ??:0\n", 123262424Sadrian (void *) cc[i]); 124262424Sadrian } 125262424Sadrian } 126262424Sadrian fprintf(args.pa_graphfile, "--\n"); 127262424Sadrian} 128