diff options
author | Andrii Nakryiko <andriin@fb.com> | 2019-08-13 14:54:43 -0400 |
---|---|---|
committer | Daniel Borkmann <daniel@iogearbox.net> | 2019-08-13 17:19:42 -0400 |
commit | a1916a153c254cd0ad13b23bed262ed56922cc7a (patch) | |
tree | 5534805c878ae24eb57d84b6d784c1f6f4b4cd7c | |
parent | 7fd785685e2243bb639b31557e258d11464c3489 (diff) |
libbpf: attempt to load kernel BTF from sysfs first
Add support for loading kernel BTF from sysfs (/sys/kernel/btf/vmlinux)
as a target BTF. Also extend the list of on disk search paths for
vmlinux ELF image with entries that perf is searching for.
Signed-off-by: Andrii Nakryiko <andriin@fb.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
-rw-r--r-- | tools/lib/bpf/libbpf.c | 64 |
1 files changed, 57 insertions, 7 deletions
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index 3abf2dd1b3b5..8462dab02812 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c | |||
@@ -2807,15 +2807,61 @@ static int bpf_core_reloc_insn(struct bpf_program *prog, int insn_off, | |||
2807 | return 0; | 2807 | return 0; |
2808 | } | 2808 | } |
2809 | 2809 | ||
2810 | static struct btf *btf_load_raw(const char *path) | ||
2811 | { | ||
2812 | struct btf *btf; | ||
2813 | size_t read_cnt; | ||
2814 | struct stat st; | ||
2815 | void *data; | ||
2816 | FILE *f; | ||
2817 | |||
2818 | if (stat(path, &st)) | ||
2819 | return ERR_PTR(-errno); | ||
2820 | |||
2821 | data = malloc(st.st_size); | ||
2822 | if (!data) | ||
2823 | return ERR_PTR(-ENOMEM); | ||
2824 | |||
2825 | f = fopen(path, "rb"); | ||
2826 | if (!f) { | ||
2827 | btf = ERR_PTR(-errno); | ||
2828 | goto cleanup; | ||
2829 | } | ||
2830 | |||
2831 | read_cnt = fread(data, 1, st.st_size, f); | ||
2832 | fclose(f); | ||
2833 | if (read_cnt < st.st_size) { | ||
2834 | btf = ERR_PTR(-EBADF); | ||
2835 | goto cleanup; | ||
2836 | } | ||
2837 | |||
2838 | btf = btf__new(data, read_cnt); | ||
2839 | |||
2840 | cleanup: | ||
2841 | free(data); | ||
2842 | return btf; | ||
2843 | } | ||
2844 | |||
2810 | /* | 2845 | /* |
2811 | * Probe few well-known locations for vmlinux kernel image and try to load BTF | 2846 | * Probe few well-known locations for vmlinux kernel image and try to load BTF |
2812 | * data out of it to use for target BTF. | 2847 | * data out of it to use for target BTF. |
2813 | */ | 2848 | */ |
2814 | static struct btf *bpf_core_find_kernel_btf(void) | 2849 | static struct btf *bpf_core_find_kernel_btf(void) |
2815 | { | 2850 | { |
2816 | const char *locations[] = { | 2851 | struct { |
2817 | "/lib/modules/%1$s/vmlinux-%1$s", | 2852 | const char *path_fmt; |
2818 | "/usr/lib/modules/%1$s/kernel/vmlinux", | 2853 | bool raw_btf; |
2854 | } locations[] = { | ||
2855 | /* try canonical vmlinux BTF through sysfs first */ | ||
2856 | { "/sys/kernel/btf/vmlinux", true /* raw BTF */ }, | ||
2857 | /* fall back to trying to find vmlinux ELF on disk otherwise */ | ||
2858 | { "/boot/vmlinux-%1$s" }, | ||
2859 | { "/lib/modules/%1$s/vmlinux-%1$s" }, | ||
2860 | { "/lib/modules/%1$s/build/vmlinux" }, | ||
2861 | { "/usr/lib/modules/%1$s/kernel/vmlinux" }, | ||
2862 | { "/usr/lib/debug/boot/vmlinux-%1$s" }, | ||
2863 | { "/usr/lib/debug/boot/vmlinux-%1$s.debug" }, | ||
2864 | { "/usr/lib/debug/lib/modules/%1$s/vmlinux" }, | ||
2819 | }; | 2865 | }; |
2820 | char path[PATH_MAX + 1]; | 2866 | char path[PATH_MAX + 1]; |
2821 | struct utsname buf; | 2867 | struct utsname buf; |
@@ -2825,14 +2871,18 @@ static struct btf *bpf_core_find_kernel_btf(void) | |||
2825 | uname(&buf); | 2871 | uname(&buf); |
2826 | 2872 | ||
2827 | for (i = 0; i < ARRAY_SIZE(locations); i++) { | 2873 | for (i = 0; i < ARRAY_SIZE(locations); i++) { |
2828 | snprintf(path, PATH_MAX, locations[i], buf.release); | 2874 | snprintf(path, PATH_MAX, locations[i].path_fmt, buf.release); |
2829 | 2875 | ||
2830 | if (access(path, R_OK)) | 2876 | if (access(path, R_OK)) |
2831 | continue; | 2877 | continue; |
2832 | 2878 | ||
2833 | btf = btf__parse_elf(path, NULL); | 2879 | if (locations[i].raw_btf) |
2834 | pr_debug("kernel BTF load from '%s': %ld\n", | 2880 | btf = btf_load_raw(path); |
2835 | path, PTR_ERR(btf)); | 2881 | else |
2882 | btf = btf__parse_elf(path, NULL); | ||
2883 | |||
2884 | pr_debug("loading kernel BTF '%s': %ld\n", | ||
2885 | path, IS_ERR(btf) ? PTR_ERR(btf) : 0); | ||
2836 | if (IS_ERR(btf)) | 2886 | if (IS_ERR(btf)) |
2837 | continue; | 2887 | continue; |
2838 | 2888 | ||