bpf: get JITed image lengths of functions via syscall
authorSandipan Das <sandipan@linux.vnet.ibm.com>
Thu, 24 May 2018 06:56:52 +0000 (12:26 +0530)
committerDaniel Borkmann <daniel@iogearbox.net>
Thu, 24 May 2018 07:20:49 +0000 (09:20 +0200)
This adds new two new fields to struct bpf_prog_info. For
multi-function programs, these fields can be used to pass
a list of the JITed image lengths of each function for a
given program to userspace using the bpf system call with
the BPF_OBJ_GET_INFO_BY_FD command.

This can be used by userspace applications like bpftool
to split up the contiguous JITed dump, also obtained via
the system call, into more relatable chunks corresponding
to each function.

Signed-off-by: Sandipan Das <sandipan@linux.vnet.ibm.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
include/uapi/linux/bpf.h
kernel/bpf/syscall.c

index 0be90965867ddf9ba0d62f48222a429b69363ce3..344d2ddcef49d75fd46d5e0d498440db81edf624 100644 (file)
@@ -2206,7 +2206,9 @@ struct bpf_prog_info {
        __u64 netns_dev;
        __u64 netns_ino;
        __u32 nr_jited_ksyms;
+       __u32 nr_jited_func_lens;
        __aligned_u64 jited_ksyms;
+       __aligned_u64 jited_func_lens;
 } __attribute__((aligned(8)));
 
 struct bpf_map_info {
index c8e987a612b57bb4ff04af1c4dbb56105a3ff50a..788456c186178acf0a46c545eb99268d73f5b916 100644 (file)
@@ -2037,6 +2037,26 @@ static int bpf_prog_get_info_by_fd(struct bpf_prog *prog,
                }
        }
 
+       ulen = info.nr_jited_func_lens;
+       info.nr_jited_func_lens = prog->aux->func_cnt;
+       if (info.nr_jited_func_lens && ulen) {
+               if (bpf_dump_raw_ok()) {
+                       u32 __user *user_lens;
+                       u32 func_len, i;
+
+                       /* copy the JITed image lengths for each function */
+                       ulen = min_t(u32, info.nr_jited_func_lens, ulen);
+                       user_lens = u64_to_user_ptr(info.jited_func_lens);
+                       for (i = 0; i < ulen; i++) {
+                               func_len = prog->aux->func[i]->jited_len;
+                               if (put_user(func_len, &user_lens[i]))
+                                       return -EFAULT;
+                       }
+               } else {
+                       info.jited_func_lens = 0;
+               }
+       }
+
 done:
        if (copy_to_user(uinfo, &info, info_len) ||
            put_user(info_len, &uattr->info.info_len))