Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

perf dso: Support BPF programs in dso__read_symbol()

Set the buffer to the code in the BPF linear info. This enables BPF
JIT code disassembly by LLVM and capstone.

Move the common but minimal disassmble_bpf_image call to
disassemble_objdump so that it is only called after falling back to the
objdump option.

Similarly move the disassmble_bpf function to disassemble_objdump and
rename to disassmble_bpf_libbfd to make it clearer that this support
relies on libbfd.

Signed-off-by: Ian Rogers <irogers@google.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Alexandre Ghiti <alexghiti@rivosinc.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Athira Rajeev <atrajeev@linux.ibm.com>
Cc: Bill Wendling <morbo@google.com>
Cc: Charlie Jenkins <charlie@rivosinc.com>
Cc: Collin Funk <collin.funk1@gmail.com>
Cc: Dmitriy Vyukov <dvyukov@google.com>
Cc: Dr. David Alan Gilbert <linux@treblig.org>
Cc: Eric Biggers <ebiggers@kernel.org>
Cc: Haibo Xu <haibo1.xu@intel.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@linaro.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Justin Stitt <justinstitt@google.com>
Cc: Li Huafei <lihuafei1@huawei.com>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Nathan Chancellor <nathan@kernel.org>
Cc: Nick Desaulniers <nick.desaulniers+lkml@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Song Liu <song@kernel.org>
Cc: Stephen Brennan <stephen.s.brennan@oracle.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Ian Rogers and committed by
Arnaldo Carvalho de Melo
aa04707f 9518e10c

+83 -45
+7 -5
tools/perf/util/disasm.c
··· 1521 1521 struct child_process objdump_process; 1522 1522 int err; 1523 1523 1524 + if (dso__binary_type(dso) == DSO_BINARY_TYPE__BPF_PROG_INFO) 1525 + return symbol__disassemble_bpf_libbfd(sym, args); 1526 + 1527 + if (dso__binary_type(dso) == DSO_BINARY_TYPE__BPF_IMAGE) 1528 + return symbol__disassemble_bpf_image(sym, args); 1529 + 1524 1530 err = asprintf(&command, 1525 1531 "%s %s%s --start-address=0x%016" PRIx64 1526 1532 " --stop-address=0x%016" PRIx64 ··· 1661 1655 1662 1656 pr_debug("annotating [%p] %30s : [%p] %30s\n", dso, dso__long_name(dso), sym, sym->name); 1663 1657 1664 - if (dso__binary_type(dso) == DSO_BINARY_TYPE__BPF_PROG_INFO) { 1665 - return symbol__disassemble_bpf(sym, args); 1666 - } else if (dso__binary_type(dso) == DSO_BINARY_TYPE__BPF_IMAGE) { 1667 - return symbol__disassemble_bpf_image(sym, args); 1668 - } else if (dso__binary_type(dso) == DSO_BINARY_TYPE__NOT_FOUND) { 1658 + if (dso__binary_type(dso) == DSO_BINARY_TYPE__NOT_FOUND) { 1669 1659 return SYMBOL_ANNOTATE_ERRNO__COULDNT_DETERMINE_FILE_TYPE; 1670 1660 } else if (dso__is_kcore(dso)) { 1671 1661 kce.addr = map__rip_2objdump(map, sym->start);
+71 -35
tools/perf/util/dso.c
··· 1816 1816 return 0; 1817 1817 } 1818 1818 1819 - const u8 *dso__read_symbol(struct dso *dso, const char *symfs_filename, 1820 - const struct map *map, const struct symbol *sym, 1821 - u8 **out_buf, u64 *out_buf_len, bool *is_64bit) 1819 + static const u8 *__dso__read_symbol(struct dso *dso, const char *symfs_filename, 1820 + u64 start, size_t len, 1821 + u8 **out_buf, u64 *out_buf_len, bool *is_64bit) 1822 1822 { 1823 1823 struct nscookie nsc; 1824 - u64 start = map__rip_2objdump(map, sym->start); 1825 - u64 end = map__rip_2objdump(map, sym->end); 1826 - int fd, count; 1827 - u8 *buf = NULL; 1828 - size_t len; 1824 + int fd; 1825 + ssize_t count; 1829 1826 struct find_file_offset_data data = { 1830 1827 .ip = start, 1831 1828 }; 1832 - 1833 - *out_buf = NULL; 1834 - *out_buf_len = 0; 1835 - *is_64bit = false; 1829 + u8 *code_buf = NULL; 1836 1830 1837 1831 nsinfo__mountns_enter(dso__nsinfo(dso), &nsc); 1838 1832 fd = open(symfs_filename, O_RDONLY); ··· 1834 1840 if (fd < 0) 1835 1841 return NULL; 1836 1842 1837 - if (file__read_maps(fd, /*exe=*/true, find_file_offset, &data, is_64bit) == 0) 1838 - goto err; 1839 - 1840 - len = end - start; 1841 - buf = malloc(len); 1842 - if (buf == NULL) 1843 - goto err; 1844 - 1845 - count = pread(fd, buf, len, data.offset); 1846 - close(fd); 1847 - fd = -1; 1848 - 1849 - if ((u64)count != len) 1850 - goto err; 1851 - 1852 - *out_buf = buf; 1853 - *out_buf_len = len; 1854 - return buf; 1855 - 1856 - err: 1857 - if (fd >= 0) 1843 + if (file__read_maps(fd, /*exe=*/true, find_file_offset, &data, is_64bit) == 0) { 1858 1844 close(fd); 1859 - free(buf); 1860 - return NULL; 1845 + return NULL; 1846 + } 1847 + code_buf = malloc(len); 1848 + if (code_buf == NULL) { 1849 + close(fd); 1850 + return NULL; 1851 + } 1852 + count = pread(fd, code_buf, len, data.offset); 1853 + close(fd); 1854 + if ((u64)count != len) { 1855 + free(code_buf); 1856 + return NULL; 1857 + } 1858 + *out_buf = code_buf; 1859 + *out_buf_len = len; 1860 + return code_buf; 1861 + } 1862 + 1863 + /* 1864 + * Read a symbol into memory for disassembly by a library like capstone of 1865 + * libLLVM. If memory is allocated out_buf holds it. 1866 + */ 1867 + const u8 *dso__read_symbol(struct dso *dso, const char *symfs_filename, 1868 + const struct map *map, const struct symbol *sym, 1869 + u8 **out_buf, u64 *out_buf_len, bool *is_64bit) 1870 + { 1871 + u64 start = map__rip_2objdump(map, sym->start); 1872 + u64 end = map__rip_2objdump(map, sym->end); 1873 + size_t len = end - start; 1874 + 1875 + *out_buf = NULL; 1876 + *out_buf_len = 0; 1877 + *is_64bit = false; 1878 + 1879 + if (dso__binary_type(dso) == DSO_BINARY_TYPE__BPF_IMAGE) { 1880 + /* 1881 + * Note, there is fallback BPF image disassembly in the objdump 1882 + * version but it currently does nothing. 1883 + */ 1884 + return NULL; 1885 + } 1886 + if (dso__binary_type(dso) == DSO_BINARY_TYPE__BPF_PROG_INFO) { 1887 + #ifdef HAVE_LIBBPF_SUPPORT 1888 + struct bpf_prog_info_node *info_node; 1889 + struct perf_bpil *info_linear; 1890 + 1891 + *is_64bit = sizeof(void *) == sizeof(u64); 1892 + info_node = perf_env__find_bpf_prog_info(dso__bpf_prog(dso)->env, 1893 + dso__bpf_prog(dso)->id); 1894 + if (!info_node) { 1895 + errno = SYMBOL_ANNOTATE_ERRNO__BPF_MISSING_BTF; 1896 + return NULL; 1897 + } 1898 + info_linear = info_node->info_linear; 1899 + assert(len <= info_linear->info.jited_prog_len); 1900 + *out_buf_len = len; 1901 + return (const u8 *)(uintptr_t)(info_linear->info.jited_prog_insns); 1902 + #else 1903 + pr_debug("No BPF program disassembly support\n"); 1904 + return NULL; 1905 + #endif 1906 + } 1907 + return __dso__read_symbol(dso, symfs_filename, start, len, 1908 + out_buf, out_buf_len, is_64bit); 1861 1909 }
+2 -2
tools/perf/util/libbfd.c
··· 448 448 return err; 449 449 } 450 450 451 - int symbol__disassemble_bpf(struct symbol *sym __maybe_unused, 452 - struct annotate_args *args __maybe_unused) 451 + int symbol__disassemble_bpf_libbfd(struct symbol *sym __maybe_unused, 452 + struct annotate_args *args __maybe_unused) 453 453 { 454 454 #ifdef HAVE_LIBBPF_SUPPORT 455 455 struct annotation *notes = symbol__annotation(sym);
+3 -3
tools/perf/util/libbfd.h
··· 29 29 30 30 int libbfd_filename__read_debuglink(const char *filename, char *debuglink, size_t size); 31 31 32 - int symbol__disassemble_bpf(struct symbol *sym, struct annotate_args *args); 32 + int symbol__disassemble_bpf_libbfd(struct symbol *sym, struct annotate_args *args); 33 33 34 34 #else // !defined(HAVE_LIBBFD_SUPPORT) 35 35 #include "annotate.h" ··· 72 72 return -1; 73 73 } 74 74 75 - static inline int symbol__disassemble_bpf(struct symbol *sym __always_unused, 76 - struct annotate_args *args __always_unused) 75 + static inline int symbol__disassemble_bpf_libbfd(struct symbol *sym __always_unused, 76 + struct annotate_args *args __always_unused) 77 77 { 78 78 return SYMBOL_ANNOTATE_ERRNO__NO_LIBOPCODES_FOR_BPF; 79 79 }