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}