1203790Sfabient/*- 2203790Sfabient * Copyright (c) 2005-2007, Joseph Koshy 3203790Sfabient * Copyright (c) 2007 The FreeBSD Foundation 4203790Sfabient * All rights reserved. 5203790Sfabient * 6203790Sfabient * Portions of this software were developed by A. Joseph Koshy under 7203790Sfabient * sponsorship from the FreeBSD Foundation and Google, Inc. 8203790Sfabient * 9203790Sfabient * Redistribution and use in source and binary forms, with or without 10203790Sfabient * modification, are permitted provided that the following conditions 11203790Sfabient * are met: 12203790Sfabient * 1. Redistributions of source code must retain the above copyright 13203790Sfabient * notice, this list of conditions and the following disclaimer. 14203790Sfabient * 2. Redistributions in binary form must reproduce the above copyright 15203790Sfabient * notice, this list of conditions and the following disclaimer in the 16203790Sfabient * documentation and/or other materials provided with the distribution. 17203790Sfabient * 18203790Sfabient * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19203790Sfabient * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20203790Sfabient * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21203790Sfabient * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22203790Sfabient * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23203790Sfabient * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24203790Sfabient * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25203790Sfabient * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26203790Sfabient * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27203790Sfabient * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28203790Sfabient * SUCH DAMAGE. 29203790Sfabient */ 30203790Sfabient 31203790Sfabient/* 32203790Sfabient * Transform a hwpmc(4) log into human readable form, and into 33203790Sfabient * gprof(1) compatible profiles. 34203790Sfabient */ 35203790Sfabient 36203790Sfabient#include <sys/cdefs.h> 37203790Sfabient__FBSDID("$FreeBSD$"); 38203790Sfabient 39203790Sfabient#include <sys/param.h> 40203790Sfabient#include <sys/endian.h> 41203790Sfabient#include <sys/gmon.h> 42203790Sfabient#include <sys/imgact_aout.h> 43203790Sfabient#include <sys/imgact_elf.h> 44203790Sfabient#include <sys/mman.h> 45203790Sfabient#include <sys/pmc.h> 46203790Sfabient#include <sys/queue.h> 47203790Sfabient#include <sys/socket.h> 48203790Sfabient#include <sys/stat.h> 49203790Sfabient#include <sys/wait.h> 50203790Sfabient 51203790Sfabient#include <netinet/in.h> 52203790Sfabient 53203790Sfabient#include <assert.h> 54203790Sfabient#include <err.h> 55203790Sfabient#include <errno.h> 56203790Sfabient#include <fcntl.h> 57203790Sfabient#include <gelf.h> 58203790Sfabient#include <libgen.h> 59203790Sfabient#include <limits.h> 60203790Sfabient#include <netdb.h> 61203790Sfabient#include <pmc.h> 62203790Sfabient#include <pmclog.h> 63203790Sfabient#include <sysexits.h> 64203790Sfabient#include <stdint.h> 65203790Sfabient#include <stdio.h> 66203790Sfabient#include <stdlib.h> 67203790Sfabient#include <string.h> 68203790Sfabient#include <unistd.h> 69203790Sfabient 70203790Sfabient#include "pmcstat.h" 71203790Sfabient#include "pmcstat_log.h" 72203790Sfabient#include "pmcpl_annotate.h" 73203790Sfabient 74203790Sfabient/* 75203790Sfabient * Record a callchain. 76203790Sfabient */ 77203790Sfabient 78203790Sfabientvoid 79203790Sfabientpmcpl_annotate_process(struct pmcstat_process *pp, struct pmcstat_pmcrecord *pmcr, 80203790Sfabient uint32_t nsamples, uintfptr_t *cc, int usermode, uint32_t cpu) 81203790Sfabient{ 82203790Sfabient struct pmcstat_pcmap *map; 83203790Sfabient struct pmcstat_symbol *sym; 84203790Sfabient uintfptr_t newpc; 85203790Sfabient struct pmcstat_image *image; 86203790Sfabient 87203790Sfabient (void) pmcr; (void) nsamples; (void) usermode; (void) cpu; 88203790Sfabient 89203790Sfabient map = pmcstat_process_find_map(usermode ? pp : pmcstat_kernproc, cc[0]); 90203790Sfabient if (map == NULL) { 91203790Sfabient /* Unknown offset. */ 92203790Sfabient pmcstat_stats.ps_samples_unknown_offset++; 93203790Sfabient return; 94203790Sfabient } 95203790Sfabient 96203790Sfabient assert(cc[0] >= map->ppm_lowpc && cc[0] < map->ppm_highpc); 97203790Sfabient 98203790Sfabient image = map->ppm_image; 99203790Sfabient newpc = cc[0] - (map->ppm_lowpc + 100203790Sfabient (image->pi_vaddr - image->pi_start)); 101203790Sfabient sym = pmcstat_symbol_search(image, newpc); 102203790Sfabient if (sym == NULL) 103203790Sfabient return; 104203790Sfabient 105203790Sfabient fprintf(args.pa_graphfile, "%p %s 0x%jx 0x%jx\n", 106203790Sfabient (void *)cc[0], 107203790Sfabient pmcstat_string_unintern(sym->ps_name), 108203790Sfabient (uintmax_t)(sym->ps_start + 109203790Sfabient image->pi_vaddr), (uintmax_t)(sym->ps_end + 110203790Sfabient image->pi_vaddr)); 111203790Sfabient} 112