auxtrace.c (6b652de2b27c0a4020ce0e8f277e782b6af76096) | auxtrace.c (1b36c03e356936d62abbe2accaae1573d3b66f14) |
---|---|
1/* 2 * auxtrace.c: AUX area trace support 3 * Copyright (c) 2013-2015, Intel Corporation. 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms and conditions of the GNU General Public License, 7 * version 2, as published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 * more details. 13 * 14 */ 15 16#include <sys/types.h> 17#include <sys/mman.h> 18#include <stdbool.h> | 1/* 2 * auxtrace.c: AUX area trace support 3 * Copyright (c) 2013-2015, Intel Corporation. 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms and conditions of the GNU General Public License, 7 * version 2, as published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 * more details. 13 * 14 */ 15 16#include <sys/types.h> 17#include <sys/mman.h> 18#include <stdbool.h> |
19#include <ctype.h> 20#include <string.h> 21#include <limits.h> 22#include <errno.h> |
|
19 20#include <linux/kernel.h> 21#include <linux/perf_event.h> 22#include <linux/types.h> 23#include <linux/bitops.h> 24#include <linux/log2.h> 25#include <linux/string.h> 26 27#include <sys/param.h> 28#include <stdlib.h> 29#include <stdio.h> 30#include <string.h> 31#include <limits.h> 32#include <errno.h> 33#include <linux/list.h> 34 35#include "../perf.h" 36#include "util.h" 37#include "evlist.h" | 23 24#include <linux/kernel.h> 25#include <linux/perf_event.h> 26#include <linux/types.h> 27#include <linux/bitops.h> 28#include <linux/log2.h> 29#include <linux/string.h> 30 31#include <sys/param.h> 32#include <stdlib.h> 33#include <stdio.h> 34#include <string.h> 35#include <limits.h> 36#include <errno.h> 37#include <linux/list.h> 38 39#include "../perf.h" 40#include "util.h" 41#include "evlist.h" |
42#include "dso.h" 43#include "map.h" 44#include "pmu.h" 45#include "evsel.h" |
|
38#include "cpumap.h" 39#include "thread_map.h" 40#include "asm/bug.h" | 46#include "cpumap.h" 47#include "thread_map.h" 48#include "asm/bug.h" |
49#include "symbol/kallsyms.h" |
|
41#include "auxtrace.h" 42 43#include <linux/hash.h> 44 45#include "event.h" 46#include "session.h" 47#include "debug.h" 48#include <subcmd/parse-options.h> --- 1345 unchanged lines hidden (view full) --- 1394 hlist = &c->hashtable[hash_32(key, c->bits)]; 1395 hlist_for_each_entry(entry, hlist, hash) { 1396 if (entry->key == key) 1397 return entry; 1398 } 1399 1400 return NULL; 1401} | 50#include "auxtrace.h" 51 52#include <linux/hash.h> 53 54#include "event.h" 55#include "session.h" 56#include "debug.h" 57#include <subcmd/parse-options.h> --- 1345 unchanged lines hidden (view full) --- 1403 hlist = &c->hashtable[hash_32(key, c->bits)]; 1404 hlist_for_each_entry(entry, hlist, hash) { 1405 if (entry->key == key) 1406 return entry; 1407 } 1408 1409 return NULL; 1410} |
1411 1412static void addr_filter__free_str(struct addr_filter *filt) 1413{ 1414 free(filt->str); 1415 filt->action = NULL; 1416 filt->sym_from = NULL; 1417 filt->sym_to = NULL; 1418 filt->filename = NULL; 1419 filt->str = NULL; 1420} 1421 1422static struct addr_filter *addr_filter__new(void) 1423{ 1424 struct addr_filter *filt = zalloc(sizeof(*filt)); 1425 1426 if (filt) 1427 INIT_LIST_HEAD(&filt->list); 1428 1429 return filt; 1430} 1431 1432static void addr_filter__free(struct addr_filter *filt) 1433{ 1434 if (filt) 1435 addr_filter__free_str(filt); 1436 free(filt); 1437} 1438 1439static void addr_filters__add(struct addr_filters *filts, 1440 struct addr_filter *filt) 1441{ 1442 list_add_tail(&filt->list, &filts->head); 1443 filts->cnt += 1; 1444} 1445 1446static void addr_filters__del(struct addr_filters *filts, 1447 struct addr_filter *filt) 1448{ 1449 list_del_init(&filt->list); 1450 filts->cnt -= 1; 1451} 1452 1453void addr_filters__init(struct addr_filters *filts) 1454{ 1455 INIT_LIST_HEAD(&filts->head); 1456 filts->cnt = 0; 1457} 1458 1459void addr_filters__exit(struct addr_filters *filts) 1460{ 1461 struct addr_filter *filt, *n; 1462 1463 list_for_each_entry_safe(filt, n, &filts->head, list) { 1464 addr_filters__del(filts, filt); 1465 addr_filter__free(filt); 1466 } 1467} 1468 1469static int parse_num_or_str(char **inp, u64 *num, const char **str, 1470 const char *str_delim) 1471{ 1472 *inp += strspn(*inp, " "); 1473 1474 if (isdigit(**inp)) { 1475 char *endptr; 1476 1477 if (!num) 1478 return -EINVAL; 1479 errno = 0; 1480 *num = strtoull(*inp, &endptr, 0); 1481 if (errno) 1482 return -errno; 1483 if (endptr == *inp) 1484 return -EINVAL; 1485 *inp = endptr; 1486 } else { 1487 size_t n; 1488 1489 if (!str) 1490 return -EINVAL; 1491 *inp += strspn(*inp, " "); 1492 *str = *inp; 1493 n = strcspn(*inp, str_delim); 1494 if (!n) 1495 return -EINVAL; 1496 *inp += n; 1497 if (**inp) { 1498 **inp = '\0'; 1499 *inp += 1; 1500 } 1501 } 1502 return 0; 1503} 1504 1505static int parse_action(struct addr_filter *filt) 1506{ 1507 if (!strcmp(filt->action, "filter")) { 1508 filt->start = true; 1509 filt->range = true; 1510 } else if (!strcmp(filt->action, "start")) { 1511 filt->start = true; 1512 } else if (!strcmp(filt->action, "stop")) { 1513 filt->start = false; 1514 } else if (!strcmp(filt->action, "tracestop")) { 1515 filt->start = false; 1516 filt->range = true; 1517 filt->action += 5; /* Change 'tracestop' to 'stop' */ 1518 } else { 1519 return -EINVAL; 1520 } 1521 return 0; 1522} 1523 1524static int parse_sym_idx(char **inp, int *idx) 1525{ 1526 *idx = -1; 1527 1528 *inp += strspn(*inp, " "); 1529 1530 if (**inp != '#') 1531 return 0; 1532 1533 *inp += 1; 1534 1535 if (**inp == 'g' || **inp == 'G') { 1536 *inp += 1; 1537 *idx = 0; 1538 } else { 1539 unsigned long num; 1540 char *endptr; 1541 1542 errno = 0; 1543 num = strtoul(*inp, &endptr, 0); 1544 if (errno) 1545 return -errno; 1546 if (endptr == *inp || num > INT_MAX) 1547 return -EINVAL; 1548 *inp = endptr; 1549 *idx = num; 1550 } 1551 1552 return 0; 1553} 1554 1555static int parse_addr_size(char **inp, u64 *num, const char **str, int *idx) 1556{ 1557 int err = parse_num_or_str(inp, num, str, " "); 1558 1559 if (!err && *str) 1560 err = parse_sym_idx(inp, idx); 1561 1562 return err; 1563} 1564 1565static int parse_one_filter(struct addr_filter *filt, const char **filter_inp) 1566{ 1567 char *fstr; 1568 int err; 1569 1570 filt->str = fstr = strdup(*filter_inp); 1571 if (!fstr) 1572 return -ENOMEM; 1573 1574 err = parse_num_or_str(&fstr, NULL, &filt->action, " "); 1575 if (err) 1576 goto out_err; 1577 1578 err = parse_action(filt); 1579 if (err) 1580 goto out_err; 1581 1582 err = parse_addr_size(&fstr, &filt->addr, &filt->sym_from, 1583 &filt->sym_from_idx); 1584 if (err) 1585 goto out_err; 1586 1587 fstr += strspn(fstr, " "); 1588 1589 if (*fstr == '/') { 1590 fstr += 1; 1591 err = parse_addr_size(&fstr, &filt->size, &filt->sym_to, 1592 &filt->sym_to_idx); 1593 if (err) 1594 goto out_err; 1595 filt->range = true; 1596 } 1597 1598 fstr += strspn(fstr, " "); 1599 1600 if (*fstr == '@') { 1601 fstr += 1; 1602 err = parse_num_or_str(&fstr, NULL, &filt->filename, " ,"); 1603 if (err) 1604 goto out_err; 1605 } 1606 1607 fstr += strspn(fstr, " ,"); 1608 1609 *filter_inp += fstr - filt->str; 1610 1611 return 0; 1612 1613out_err: 1614 addr_filter__free_str(filt); 1615 1616 return err; 1617} 1618 1619int addr_filters__parse_bare_filter(struct addr_filters *filts, 1620 const char *filter) 1621{ 1622 struct addr_filter *filt; 1623 const char *fstr = filter; 1624 int err; 1625 1626 while (*fstr) { 1627 filt = addr_filter__new(); 1628 err = parse_one_filter(filt, &fstr); 1629 if (err) { 1630 addr_filter__free(filt); 1631 addr_filters__exit(filts); 1632 return err; 1633 } 1634 addr_filters__add(filts, filt); 1635 } 1636 1637 return 0; 1638} 1639 1640struct sym_args { 1641 const char *name; 1642 u64 start; 1643 u64 size; 1644 int idx; 1645 int cnt; 1646 bool started; 1647 bool global; 1648 bool selected; 1649 bool duplicate; 1650 bool near; 1651}; 1652 1653static bool kern_sym_match(struct sym_args *args, const char *name, char type) 1654{ 1655 /* A function with the same name, and global or the n'th found or any */ 1656 return symbol_type__is_a(type, MAP__FUNCTION) && 1657 !strcmp(name, args->name) && 1658 ((args->global && isupper(type)) || 1659 (args->selected && ++(args->cnt) == args->idx) || 1660 (!args->global && !args->selected)); 1661} 1662 1663static int find_kern_sym_cb(void *arg, const char *name, char type, u64 start) 1664{ 1665 struct sym_args *args = arg; 1666 1667 if (args->started) { 1668 if (!args->size) 1669 args->size = start - args->start; 1670 if (args->selected) { 1671 if (args->size) 1672 return 1; 1673 } else if (kern_sym_match(args, name, type)) { 1674 args->duplicate = true; 1675 return 1; 1676 } 1677 } else if (kern_sym_match(args, name, type)) { 1678 args->started = true; 1679 args->start = start; 1680 } 1681 1682 return 0; 1683} 1684 1685static int print_kern_sym_cb(void *arg, const char *name, char type, u64 start) 1686{ 1687 struct sym_args *args = arg; 1688 1689 if (kern_sym_match(args, name, type)) { 1690 pr_err("#%d\t0x%"PRIx64"\t%c\t%s\n", 1691 ++args->cnt, start, type, name); 1692 args->near = true; 1693 } else if (args->near) { 1694 args->near = false; 1695 pr_err("\t\twhich is near\t\t%s\n", name); 1696 } 1697 1698 return 0; 1699} 1700 1701static int sym_not_found_error(const char *sym_name, int idx) 1702{ 1703 if (idx > 0) { 1704 pr_err("N'th occurrence (N=%d) of symbol '%s' not found.\n", 1705 idx, sym_name); 1706 } else if (!idx) { 1707 pr_err("Global symbol '%s' not found.\n", sym_name); 1708 } else { 1709 pr_err("Symbol '%s' not found.\n", sym_name); 1710 } 1711 pr_err("Note that symbols must be functions.\n"); 1712 1713 return -EINVAL; 1714} 1715 1716static int find_kern_sym(const char *sym_name, u64 *start, u64 *size, int idx) 1717{ 1718 struct sym_args args = { 1719 .name = sym_name, 1720 .idx = idx, 1721 .global = !idx, 1722 .selected = idx > 0, 1723 }; 1724 int err; 1725 1726 *start = 0; 1727 *size = 0; 1728 1729 err = kallsyms__parse("/proc/kallsyms", &args, find_kern_sym_cb); 1730 if (err < 0) { 1731 pr_err("Failed to parse /proc/kallsyms\n"); 1732 return err; 1733 } 1734 1735 if (args.duplicate) { 1736 pr_err("Multiple kernel symbols with name '%s'\n", sym_name); 1737 args.cnt = 0; 1738 kallsyms__parse("/proc/kallsyms", &args, print_kern_sym_cb); 1739 pr_err("Disambiguate symbol name by inserting #n after the name e.g. %s #2\n", 1740 sym_name); 1741 pr_err("Or select a global symbol by inserting #0 or #g or #G\n"); 1742 return -EINVAL; 1743 } 1744 1745 if (!args.started) { 1746 pr_err("Kernel symbol lookup: "); 1747 return sym_not_found_error(sym_name, idx); 1748 } 1749 1750 *start = args.start; 1751 *size = args.size; 1752 1753 return 0; 1754} 1755 1756static int find_entire_kern_cb(void *arg, const char *name __maybe_unused, 1757 char type, u64 start) 1758{ 1759 struct sym_args *args = arg; 1760 1761 if (!symbol_type__is_a(type, MAP__FUNCTION)) 1762 return 0; 1763 1764 if (!args->started) { 1765 args->started = true; 1766 args->start = start; 1767 } 1768 /* Don't know exactly where the kernel ends, so we add a page */ 1769 args->size = round_up(start, page_size) + page_size - args->start; 1770 1771 return 0; 1772} 1773 1774static int addr_filter__entire_kernel(struct addr_filter *filt) 1775{ 1776 struct sym_args args = { .started = false }; 1777 int err; 1778 1779 err = kallsyms__parse("/proc/kallsyms", &args, find_entire_kern_cb); 1780 if (err < 0 || !args.started) { 1781 pr_err("Failed to parse /proc/kallsyms\n"); 1782 return err; 1783 } 1784 1785 filt->addr = args.start; 1786 filt->size = args.size; 1787 1788 return 0; 1789} 1790 1791static int check_end_after_start(struct addr_filter *filt, u64 start, u64 size) 1792{ 1793 if (start + size >= filt->addr) 1794 return 0; 1795 1796 if (filt->sym_from) { 1797 pr_err("Symbol '%s' (0x%"PRIx64") comes before '%s' (0x%"PRIx64")\n", 1798 filt->sym_to, start, filt->sym_from, filt->addr); 1799 } else { 1800 pr_err("Symbol '%s' (0x%"PRIx64") comes before address 0x%"PRIx64")\n", 1801 filt->sym_to, start, filt->addr); 1802 } 1803 1804 return -EINVAL; 1805} 1806 1807static int addr_filter__resolve_kernel_syms(struct addr_filter *filt) 1808{ 1809 bool no_size = false; 1810 u64 start, size; 1811 int err; 1812 1813 if (symbol_conf.kptr_restrict) { 1814 pr_err("Kernel addresses are restricted. Unable to resolve kernel symbols.\n"); 1815 return -EINVAL; 1816 } 1817 1818 if (filt->sym_from && !strcmp(filt->sym_from, "*")) 1819 return addr_filter__entire_kernel(filt); 1820 1821 if (filt->sym_from) { 1822 err = find_kern_sym(filt->sym_from, &start, &size, 1823 filt->sym_from_idx); 1824 if (err) 1825 return err; 1826 filt->addr = start; 1827 if (filt->range && !filt->size && !filt->sym_to) { 1828 filt->size = size; 1829 no_size = !!size; 1830 } 1831 } 1832 1833 if (filt->sym_to) { 1834 err = find_kern_sym(filt->sym_to, &start, &size, 1835 filt->sym_to_idx); 1836 if (err) 1837 return err; 1838 1839 err = check_end_after_start(filt, start, size); 1840 if (err) 1841 return err; 1842 filt->size = start + size - filt->addr; 1843 no_size = !!size; 1844 } 1845 1846 /* The very last symbol in kallsyms does not imply a particular size */ 1847 if (no_size) { 1848 pr_err("Cannot determine size of symbol '%s'\n", 1849 filt->sym_to ? filt->sym_to : filt->sym_from); 1850 return -EINVAL; 1851 } 1852 1853 return 0; 1854} 1855 1856static struct dso *load_dso(const char *name) 1857{ 1858 struct map *map; 1859 struct dso *dso; 1860 1861 map = dso__new_map(name); 1862 if (!map) 1863 return NULL; 1864 1865 map__load(map); 1866 1867 dso = dso__get(map->dso); 1868 1869 map__put(map); 1870 1871 return dso; 1872} 1873 1874static bool dso_sym_match(struct symbol *sym, const char *name, int *cnt, 1875 int idx) 1876{ 1877 /* Same name, and global or the n'th found or any */ 1878 return !arch__compare_symbol_names(name, sym->name) && 1879 ((!idx && sym->binding == STB_GLOBAL) || 1880 (idx > 0 && ++*cnt == idx) || 1881 idx < 0); 1882} 1883 1884static void print_duplicate_syms(struct dso *dso, const char *sym_name) 1885{ 1886 struct symbol *sym; 1887 bool near = false; 1888 int cnt = 0; 1889 1890 pr_err("Multiple symbols with name '%s'\n", sym_name); 1891 1892 sym = dso__first_symbol(dso, MAP__FUNCTION); 1893 while (sym) { 1894 if (dso_sym_match(sym, sym_name, &cnt, -1)) { 1895 pr_err("#%d\t0x%"PRIx64"\t%c\t%s\n", 1896 ++cnt, sym->start, 1897 sym->binding == STB_GLOBAL ? 'g' : 1898 sym->binding == STB_LOCAL ? 'l' : 'w', 1899 sym->name); 1900 near = true; 1901 } else if (near) { 1902 near = false; 1903 pr_err("\t\twhich is near\t\t%s\n", sym->name); 1904 } 1905 sym = dso__next_symbol(sym); 1906 } 1907 1908 pr_err("Disambiguate symbol name by inserting #n after the name e.g. %s #2\n", 1909 sym_name); 1910 pr_err("Or select a global symbol by inserting #0 or #g or #G\n"); 1911} 1912 1913static int find_dso_sym(struct dso *dso, const char *sym_name, u64 *start, 1914 u64 *size, int idx) 1915{ 1916 struct symbol *sym; 1917 int cnt = 0; 1918 1919 *start = 0; 1920 *size = 0; 1921 1922 sym = dso__first_symbol(dso, MAP__FUNCTION); 1923 while (sym) { 1924 if (*start) { 1925 if (!*size) 1926 *size = sym->start - *start; 1927 if (idx > 0) { 1928 if (*size) 1929 return 1; 1930 } else if (dso_sym_match(sym, sym_name, &cnt, idx)) { 1931 print_duplicate_syms(dso, sym_name); 1932 return -EINVAL; 1933 } 1934 } else if (dso_sym_match(sym, sym_name, &cnt, idx)) { 1935 *start = sym->start; 1936 *size = sym->end - sym->start; 1937 } 1938 sym = dso__next_symbol(sym); 1939 } 1940 1941 if (!*start) 1942 return sym_not_found_error(sym_name, idx); 1943 1944 return 0; 1945} 1946 1947static int addr_filter__entire_dso(struct addr_filter *filt, struct dso *dso) 1948{ 1949 struct symbol *first_sym = dso__first_symbol(dso, MAP__FUNCTION); 1950 struct symbol *last_sym = dso__last_symbol(dso, MAP__FUNCTION); 1951 1952 if (!first_sym || !last_sym) { 1953 pr_err("Failed to determine filter for %s\nNo symbols found.\n", 1954 filt->filename); 1955 return -EINVAL; 1956 } 1957 1958 filt->addr = first_sym->start; 1959 filt->size = last_sym->end - first_sym->start; 1960 1961 return 0; 1962} 1963 1964static int addr_filter__resolve_syms(struct addr_filter *filt) 1965{ 1966 u64 start, size; 1967 struct dso *dso; 1968 int err = 0; 1969 1970 if (!filt->sym_from && !filt->sym_to) 1971 return 0; 1972 1973 if (!filt->filename) 1974 return addr_filter__resolve_kernel_syms(filt); 1975 1976 dso = load_dso(filt->filename); 1977 if (!dso) { 1978 pr_err("Failed to load symbols from: %s\n", filt->filename); 1979 return -EINVAL; 1980 } 1981 1982 if (filt->sym_from && !strcmp(filt->sym_from, "*")) { 1983 err = addr_filter__entire_dso(filt, dso); 1984 goto put_dso; 1985 } 1986 1987 if (filt->sym_from) { 1988 err = find_dso_sym(dso, filt->sym_from, &start, &size, 1989 filt->sym_from_idx); 1990 if (err) 1991 goto put_dso; 1992 filt->addr = start; 1993 if (filt->range && !filt->size && !filt->sym_to) 1994 filt->size = size; 1995 } 1996 1997 if (filt->sym_to) { 1998 err = find_dso_sym(dso, filt->sym_to, &start, &size, 1999 filt->sym_to_idx); 2000 if (err) 2001 goto put_dso; 2002 2003 err = check_end_after_start(filt, start, size); 2004 if (err) 2005 return err; 2006 2007 filt->size = start + size - filt->addr; 2008 } 2009 2010put_dso: 2011 dso__put(dso); 2012 2013 return err; 2014} 2015 2016static char *addr_filter__to_str(struct addr_filter *filt) 2017{ 2018 char filename_buf[PATH_MAX]; 2019 const char *at = ""; 2020 const char *fn = ""; 2021 char *filter; 2022 int err; 2023 2024 if (filt->filename) { 2025 at = "@"; 2026 fn = realpath(filt->filename, filename_buf); 2027 if (!fn) 2028 return NULL; 2029 } 2030 2031 if (filt->range) { 2032 err = asprintf(&filter, "%s 0x%"PRIx64"/0x%"PRIx64"%s%s", 2033 filt->action, filt->addr, filt->size, at, fn); 2034 } else { 2035 err = asprintf(&filter, "%s 0x%"PRIx64"%s%s", 2036 filt->action, filt->addr, at, fn); 2037 } 2038 2039 return err < 0 ? NULL : filter; 2040} 2041 2042static int parse_addr_filter(struct perf_evsel *evsel, const char *filter, 2043 int max_nr) 2044{ 2045 struct addr_filters filts; 2046 struct addr_filter *filt; 2047 int err; 2048 2049 addr_filters__init(&filts); 2050 2051 err = addr_filters__parse_bare_filter(&filts, filter); 2052 if (err) 2053 goto out_exit; 2054 2055 if (filts.cnt > max_nr) { 2056 pr_err("Error: number of address filters (%d) exceeds maximum (%d)\n", 2057 filts.cnt, max_nr); 2058 err = -EINVAL; 2059 goto out_exit; 2060 } 2061 2062 list_for_each_entry(filt, &filts.head, list) { 2063 char *new_filter; 2064 2065 err = addr_filter__resolve_syms(filt); 2066 if (err) 2067 goto out_exit; 2068 2069 new_filter = addr_filter__to_str(filt); 2070 if (!new_filter) { 2071 err = -ENOMEM; 2072 goto out_exit; 2073 } 2074 2075 if (perf_evsel__append_addr_filter(evsel, new_filter)) { 2076 err = -ENOMEM; 2077 goto out_exit; 2078 } 2079 } 2080 2081out_exit: 2082 addr_filters__exit(&filts); 2083 2084 if (err) { 2085 pr_err("Failed to parse address filter: '%s'\n", filter); 2086 pr_err("Filter format is: filter|start|stop|tracestop <start symbol or address> [/ <end symbol or size>] [@<file name>]\n"); 2087 pr_err("Where multiple filters are separated by space or comma.\n"); 2088 } 2089 2090 return err; 2091} 2092 2093static struct perf_pmu *perf_evsel__find_pmu(struct perf_evsel *evsel) 2094{ 2095 struct perf_pmu *pmu = NULL; 2096 2097 while ((pmu = perf_pmu__scan(pmu)) != NULL) { 2098 if (pmu->type == evsel->attr.type) 2099 break; 2100 } 2101 2102 return pmu; 2103} 2104 2105static int perf_evsel__nr_addr_filter(struct perf_evsel *evsel) 2106{ 2107 struct perf_pmu *pmu = perf_evsel__find_pmu(evsel); 2108 int nr_addr_filters = 0; 2109 2110 if (!pmu) 2111 return 0; 2112 2113 perf_pmu__scan_file(pmu, "nr_addr_filters", "%d", &nr_addr_filters); 2114 2115 return nr_addr_filters; 2116} 2117 2118int auxtrace_parse_filters(struct perf_evlist *evlist) 2119{ 2120 struct perf_evsel *evsel; 2121 char *filter; 2122 int err, max_nr; 2123 2124 evlist__for_each_entry(evlist, evsel) { 2125 filter = evsel->filter; 2126 max_nr = perf_evsel__nr_addr_filter(evsel); 2127 if (!filter || !max_nr) 2128 continue; 2129 evsel->filter = NULL; 2130 err = parse_addr_filter(evsel, filter, max_nr); 2131 free(filter); 2132 if (err) 2133 return err; 2134 pr_debug("Address filter: %s\n", evsel->filter); 2135 } 2136 2137 return 0; 2138} |
|