1*d27927f7SRuslan Bukin /*- 2*d27927f7SRuslan Bukin * Copyright (c) 2003-2008 Joseph Koshy 3*d27927f7SRuslan Bukin * Copyright (c) 2017 Ruslan Bukin <br@bsdpad.com> 4*d27927f7SRuslan Bukin * All rights reserved. 5*d27927f7SRuslan Bukin * 6*d27927f7SRuslan Bukin * This software was developed by BAE Systems, the University of Cambridge 7*d27927f7SRuslan Bukin * Computer Laboratory, and Memorial University under DARPA/AFRL contract 8*d27927f7SRuslan Bukin * FA8650-15-C-7558 ("CADETS"), as part of the DARPA Transparent Computing 9*d27927f7SRuslan Bukin * (TC) research program. 10*d27927f7SRuslan Bukin * 11*d27927f7SRuslan Bukin * Redistribution and use in source and binary forms, with or without 12*d27927f7SRuslan Bukin * modification, are permitted provided that the following conditions 13*d27927f7SRuslan Bukin * are met: 14*d27927f7SRuslan Bukin * 1. Redistributions of source code must retain the above copyright 15*d27927f7SRuslan Bukin * notice, this list of conditions and the following disclaimer. 16*d27927f7SRuslan Bukin * 2. Redistributions in binary form must reproduce the above copyright 17*d27927f7SRuslan Bukin * notice, this list of conditions and the following disclaimer in the 18*d27927f7SRuslan Bukin * documentation and/or other materials provided with the distribution. 19*d27927f7SRuslan Bukin * 20*d27927f7SRuslan Bukin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 21*d27927f7SRuslan Bukin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22*d27927f7SRuslan Bukin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23*d27927f7SRuslan Bukin * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 24*d27927f7SRuslan Bukin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25*d27927f7SRuslan Bukin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26*d27927f7SRuslan Bukin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27*d27927f7SRuslan Bukin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28*d27927f7SRuslan Bukin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29*d27927f7SRuslan Bukin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30*d27927f7SRuslan Bukin * SUCH DAMAGE. 31*d27927f7SRuslan Bukin */ 32*d27927f7SRuslan Bukin 33*d27927f7SRuslan Bukin #include <sys/cdefs.h> 34*d27927f7SRuslan Bukin __FBSDID("$FreeBSD$"); 35*d27927f7SRuslan Bukin 36*d27927f7SRuslan Bukin #include <sys/types.h> 37*d27927f7SRuslan Bukin #include <sys/cpuset.h> 38*d27927f7SRuslan Bukin #include <sys/event.h> 39*d27927f7SRuslan Bukin #include <sys/param.h> 40*d27927f7SRuslan Bukin #include <sys/socket.h> 41*d27927f7SRuslan Bukin #include <sys/stat.h> 42*d27927f7SRuslan Bukin #include <sys/module.h> 43*d27927f7SRuslan Bukin #include <sys/pmc.h> 44*d27927f7SRuslan Bukin 45*d27927f7SRuslan Bukin #include <assert.h> 46*d27927f7SRuslan Bukin #include <err.h> 47*d27927f7SRuslan Bukin #include <pmc.h> 48*d27927f7SRuslan Bukin #include <pmclog.h> 49*d27927f7SRuslan Bukin #include <stdbool.h> 50*d27927f7SRuslan Bukin #include <stdio.h> 51*d27927f7SRuslan Bukin #include <stdlib.h> 52*d27927f7SRuslan Bukin #include <string.h> 53*d27927f7SRuslan Bukin 54*d27927f7SRuslan Bukin #include "libpmcstat.h" 55*d27927f7SRuslan Bukin 56*d27927f7SRuslan Bukin struct pmcstat_symbol * 57*d27927f7SRuslan Bukin pmcstat_symbol_search_by_name(struct pmcstat_process *pp, 58*d27927f7SRuslan Bukin const char *pi_name, const char *name, uintptr_t *addr_start, 59*d27927f7SRuslan Bukin uintptr_t *addr_end) 60*d27927f7SRuslan Bukin { 61*d27927f7SRuslan Bukin struct pmcstat_symbol *sym; 62*d27927f7SRuslan Bukin struct pmcstat_image *image; 63*d27927f7SRuslan Bukin struct pmcstat_pcmap *pcm; 64*d27927f7SRuslan Bukin const char *name1; 65*d27927f7SRuslan Bukin const char *name2; 66*d27927f7SRuslan Bukin bool found; 67*d27927f7SRuslan Bukin size_t i; 68*d27927f7SRuslan Bukin 69*d27927f7SRuslan Bukin found = 0; 70*d27927f7SRuslan Bukin 71*d27927f7SRuslan Bukin if (pp == NULL) 72*d27927f7SRuslan Bukin return (NULL); 73*d27927f7SRuslan Bukin 74*d27927f7SRuslan Bukin TAILQ_FOREACH(pcm, &pp->pp_map, ppm_next) { 75*d27927f7SRuslan Bukin image = pcm->ppm_image; 76*d27927f7SRuslan Bukin if (image->pi_name == NULL) 77*d27927f7SRuslan Bukin continue; 78*d27927f7SRuslan Bukin name1 = pmcstat_string_unintern(image->pi_name); 79*d27927f7SRuslan Bukin if (strcmp(name1, pi_name) == 0) { 80*d27927f7SRuslan Bukin found = 1; 81*d27927f7SRuslan Bukin break; 82*d27927f7SRuslan Bukin } 83*d27927f7SRuslan Bukin } 84*d27927f7SRuslan Bukin 85*d27927f7SRuslan Bukin if (!found || image->pi_symbols == NULL) 86*d27927f7SRuslan Bukin return (NULL); 87*d27927f7SRuslan Bukin 88*d27927f7SRuslan Bukin found = 0; 89*d27927f7SRuslan Bukin 90*d27927f7SRuslan Bukin for (i = 0; i < image->pi_symcount; i++) { 91*d27927f7SRuslan Bukin sym = &image->pi_symbols[i]; 92*d27927f7SRuslan Bukin name2 = pmcstat_string_unintern(sym->ps_name); 93*d27927f7SRuslan Bukin if (strcmp(name2, name) == 0) { 94*d27927f7SRuslan Bukin found = 1; 95*d27927f7SRuslan Bukin break; 96*d27927f7SRuslan Bukin } 97*d27927f7SRuslan Bukin } 98*d27927f7SRuslan Bukin 99*d27927f7SRuslan Bukin if (!found) 100*d27927f7SRuslan Bukin return (NULL); 101*d27927f7SRuslan Bukin 102*d27927f7SRuslan Bukin *addr_start = (image->pi_vaddr - image->pi_start + 103*d27927f7SRuslan Bukin pcm->ppm_lowpc + sym->ps_start); 104*d27927f7SRuslan Bukin *addr_end = (image->pi_vaddr - image->pi_start + 105*d27927f7SRuslan Bukin pcm->ppm_lowpc + sym->ps_end); 106*d27927f7SRuslan Bukin 107*d27927f7SRuslan Bukin return (sym); 108*d27927f7SRuslan Bukin } 109*d27927f7SRuslan Bukin 110*d27927f7SRuslan Bukin /* 111*d27927f7SRuslan Bukin * Helper function. 112*d27927f7SRuslan Bukin */ 113*d27927f7SRuslan Bukin 114*d27927f7SRuslan Bukin int 115*d27927f7SRuslan Bukin pmcstat_symbol_compare(const void *a, const void *b) 116*d27927f7SRuslan Bukin { 117*d27927f7SRuslan Bukin const struct pmcstat_symbol *sym1, *sym2; 118*d27927f7SRuslan Bukin 119*d27927f7SRuslan Bukin sym1 = (const struct pmcstat_symbol *) a; 120*d27927f7SRuslan Bukin sym2 = (const struct pmcstat_symbol *) b; 121*d27927f7SRuslan Bukin 122*d27927f7SRuslan Bukin if (sym1->ps_end <= sym2->ps_start) 123*d27927f7SRuslan Bukin return (-1); 124*d27927f7SRuslan Bukin if (sym1->ps_start >= sym2->ps_end) 125*d27927f7SRuslan Bukin return (1); 126*d27927f7SRuslan Bukin return (0); 127*d27927f7SRuslan Bukin } 128*d27927f7SRuslan Bukin 129*d27927f7SRuslan Bukin /* 130*d27927f7SRuslan Bukin * Map an address to a symbol in an image. 131*d27927f7SRuslan Bukin */ 132*d27927f7SRuslan Bukin 133*d27927f7SRuslan Bukin struct pmcstat_symbol * 134*d27927f7SRuslan Bukin pmcstat_symbol_search(struct pmcstat_image *image, uintfptr_t addr) 135*d27927f7SRuslan Bukin { 136*d27927f7SRuslan Bukin struct pmcstat_symbol sym; 137*d27927f7SRuslan Bukin 138*d27927f7SRuslan Bukin if (image->pi_symbols == NULL) 139*d27927f7SRuslan Bukin return (NULL); 140*d27927f7SRuslan Bukin 141*d27927f7SRuslan Bukin sym.ps_name = NULL; 142*d27927f7SRuslan Bukin sym.ps_start = addr; 143*d27927f7SRuslan Bukin sym.ps_end = addr + 1; 144*d27927f7SRuslan Bukin 145*d27927f7SRuslan Bukin return (bsearch((void *) &sym, image->pi_symbols, 146*d27927f7SRuslan Bukin image->pi_symcount, sizeof(struct pmcstat_symbol), 147*d27927f7SRuslan Bukin pmcstat_symbol_compare)); 148*d27927f7SRuslan Bukin } 149