]> granicus.if.org Git - strace/commitdiff
bpf: add support for new twelve fields in struct bpf_prog_info
authorDmitry V. Levin <ldv@altlinux.org>
Tue, 12 Mar 2019 11:17:20 +0000 (11:17 +0000)
committerDmitry V. Levin <ldv@altlinux.org>
Tue, 12 Mar 2019 11:17:20 +0000 (11:17 +0000)
* bpf_attr.h (struct bpf_prog_info_struct): Add btf_id,
func_info_rec_size, func_info, nr_func_info, nr_line_info, line_info,
jited_line_info, nr_jited_line_info, line_info_rec_size,
jited_line_info_rec_size, nr_prog_tags, and prog_tags fields.
* bpf.c (struct obj_get_info_saved): Add func_info_rec_size,
nr_func_info, nr_line_info, jited_line_info, nr_jited_line_info,
line_info_rec_size, jited_line_info_rec_size, and nr_prog_tags fields.
(print_bpf_prog_info): Decode the twelve fields introduced by Linux
commits v5.0-rc1~129^2~209^2~16^2~8, v5.0-rc1~129^2~114^2~5^2~6,
v5.0-rc1~129^2~114^2^2~2, and v5.0-rc1~129^2~15^2~22.
* NEWS: Mention the latest bpf decoding enhancements.
* tests/bpf-obj_get_info_by_fd.c (main): Update expected output.

Resolves: https://github.com/strace/strace/issues/94

NEWS
bpf.c
bpf_attr.h
tests/bpf-obj_get_info_by_fd.c

diff --git a/NEWS b/NEWS
index f56f88883834c8c5d8d48d8f8c5d1a596fd35e63..61f1b04c2c7b46d3e255e215254aa6d61866c8de 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,7 @@ Noteworthy changes in release ?.?? (????-??-??)
 
 * Improvements
   * Enhanced xlat styles support configured by -X option.
+  * Enhanced decoding of bpf syscall.
   * Enhanced decoding of PTRACE_PEEKUSER and PTRACE_POKEUSER on hppa.
   * Wired up kexec_file_load and rseq syscalls on aarch64, arc, metag, nios2,
     or1k, riscv, and tile architectures.
diff --git a/bpf.c b/bpf.c
index 83eeee1e146847324f94836c0573ffc05c534351..72f1640a0c1cc6e072a0edb3a57ec228913a5241 100644 (file)
--- a/bpf.c
+++ b/bpf.c
@@ -429,6 +429,15 @@ struct obj_get_info_saved {
        uint32_t nr_jited_func_lens;
        uint64_t jited_ksyms;
        uint64_t jited_func_lens;
+
+       uint32_t func_info_rec_size;
+       uint32_t nr_func_info;
+       uint32_t nr_line_info;
+       uint32_t nr_jited_line_info;
+       uint64_t jited_line_info;
+       uint32_t line_info_rec_size;
+       uint32_t jited_line_info_rec_size;
+       uint32_t nr_prog_tags;
 };
 
 static void
@@ -504,6 +513,15 @@ print_bpf_prog_info(struct tcb * const tcp, uint32_t bpf_fd,
                saved->jited_ksyms = info.jited_ksyms;
                saved->jited_func_lens = info.jited_func_lens;
 
+               saved->func_info_rec_size = info.func_info_rec_size;
+               saved->nr_func_info = info.nr_func_info;
+               saved->nr_line_info = info.nr_line_info;
+               saved->nr_jited_line_info = info.nr_jited_line_info;
+               saved->jited_line_info = info.jited_line_info;
+               saved->line_info_rec_size = info.line_info_rec_size;
+               saved->jited_line_info_rec_size = info.jited_line_info_rec_size;
+               saved->nr_prog_tags = info.nr_prog_tags;
+
                return;
        }
 
@@ -596,6 +614,66 @@ print_bpf_prog_info(struct tcb * const tcp, uint32_t bpf_fd,
        }
        printaddr64(info.jited_func_lens);
 
+       /*
+        * The next twelve fields were introduced by Linux commits
+        * v5.0-rc1~129^2~209^2~16^2~8
+        * v5.0-rc1~129^2~114^2~5^2~6
+        * v5.0-rc1~129^2~114^2^2~2
+        * v5.0-rc1~129^2~15^2~22
+        */
+       if (len <= offsetof(struct bpf_prog_info_struct, btf_id))
+               goto print_bpf_prog_info_end;
+
+       PRINT_FIELD_U(", ", info, btf_id);
+
+       tprints(", func_info_rec_size=");
+       if (saved->func_info_rec_size != info.func_info_rec_size)
+               tprintf("%" PRIu32 " => ", saved->func_info_rec_size);
+       tprintf("%" PRIu32, info.func_info_rec_size);
+
+       PRINT_FIELD_ADDR64(", ", info, func_info);
+
+       tprints(", nr_func_info=");
+       if (saved->nr_func_info != info.nr_func_info)
+               tprintf("%" PRIu32 " => ", saved->nr_func_info);
+       tprintf("%" PRIu32, info.nr_func_info);
+
+       tprints(", nr_line_info=");
+       if (saved->nr_line_info != info.nr_line_info)
+               tprintf("%" PRIu32 " => ", saved->nr_line_info);
+       tprintf("%" PRIu32, info.nr_line_info);
+
+       PRINT_FIELD_ADDR64(", ", info, line_info);
+
+       tprints(", jited_line_info=");
+       if (saved->jited_line_info != info.jited_line_info) {
+               printaddr64(saved->jited_line_info);
+               tprints(" => ");
+       }
+       printaddr64(info.jited_line_info);
+
+       tprints(", nr_jited_line_info=");
+       if (saved->nr_jited_line_info != info.nr_jited_line_info)
+               tprintf("%" PRIu32 " => ", saved->nr_jited_line_info);
+       tprintf("%" PRIu32, info.nr_jited_line_info);
+
+       tprints(", line_info_rec_size=");
+       if (saved->line_info_rec_size != info.line_info_rec_size)
+               tprintf("%" PRIu32 " => ", saved->line_info_rec_size);
+       tprintf("%" PRIu32, info.line_info_rec_size);
+
+       tprints(", jited_line_info_rec_size=");
+       if (saved->jited_line_info_rec_size != info.jited_line_info_rec_size)
+               tprintf("%" PRIu32 " => ", saved->jited_line_info_rec_size);
+       tprintf("%" PRIu32, info.jited_line_info_rec_size);
+
+       tprints(", nr_prog_tags=");
+       if (saved->nr_prog_tags != info.nr_prog_tags)
+               tprintf("%" PRIu32 " => ", saved->nr_prog_tags);
+       tprintf("%" PRIu32, info.nr_prog_tags);
+
+       PRINT_FIELD_ADDR64(", ", info, prog_tags);
+
        decode_attr_extra_data(tcp, info_buf, size, bpf_prog_info_struct_size);
 
 print_bpf_prog_info_end:
index 3a8786f7639277b4f148580e32a38ad082b4f7ed..b34983a84c41734ee6d2863241806cdb0d2ed3d4 100644 (file)
@@ -276,10 +276,22 @@ struct bpf_prog_info_struct {
        uint32_t nr_jited_func_lens;
        uint64_t ATTRIBUTE_ALIGNED(8) jited_ksyms;
        uint64_t ATTRIBUTE_ALIGNED(8) jited_func_lens;
+       uint32_t btf_id;
+       uint32_t func_info_rec_size;
+       uint64_t ATTRIBUTE_ALIGNED(8) func_info;
+       uint32_t nr_func_info;
+       uint32_t nr_line_info;
+       uint64_t ATTRIBUTE_ALIGNED(8) line_info;
+       uint64_t ATTRIBUTE_ALIGNED(8) jited_line_info;
+       uint32_t nr_jited_line_info;
+       uint32_t line_info_rec_size;
+       uint32_t jited_line_info_rec_size;
+       uint32_t nr_prog_tags;
+       uint64_t ATTRIBUTE_ALIGNED(8) prog_tags;
 };
 
 # define bpf_prog_info_struct_size \
        sizeof(struct bpf_prog_info_struct)
-# define expected_bpf_prog_info_struct_size 128
+# define expected_bpf_prog_info_struct_size 192
 
 #endif /* !STRACE_BPF_ATTR_H */
index dca680d7c812f6d4893087d366fa92be01a196bc..229608ae9e9f527407f24ab0e4ef8e0d0120410d 100644 (file)
@@ -360,6 +360,14 @@ main(void)
                prog_info->jited_prog_len = 0;
                prog_info->nr_jited_ksyms = 0;
                prog_info->nr_jited_func_lens = 0;
+               prog_info->func_info_rec_size = 0;
+               prog_info->nr_func_info = 0;
+               prog_info->nr_line_info = 0;
+               prog_info->nr_jited_line_info = 0;
+               prog_info->jited_line_info = 0;
+               prog_info->line_info_rec_size = 0;
+               prog_info->jited_line_info_rec_size = 0;
+               prog_info->nr_prog_tags = 0;
                memset(prog_info + 1, 0, PROG_INFO_SZ - sizeof(*prog_info));
                switch (i) {
                case 1:
@@ -506,6 +514,64 @@ main(void)
                    offsetof(struct bpf_prog_info_struct, jited_func_lens))
                        printf(", jited_func_lens=NULL");
 
+               if (bpf_prog_get_info_attr.info_len >
+                   offsetof(struct bpf_prog_info_struct, btf_id))
+                       PRINT_FIELD_U(", ", *prog_info, btf_id);
+               if (bpf_prog_get_info_attr.info_len >
+                   offsetof(struct bpf_prog_info_struct, func_info_rec_size)) {
+                       printf(", func_info_rec_size=0");
+                       if (prog_info->func_info_rec_size)
+                               printf(" => %u", prog_info->func_info_rec_size);
+               }
+               if (bpf_prog_get_info_attr.info_len >
+                   offsetof(struct bpf_prog_info_struct, func_info))
+                       printf(", func_info=NULL");
+               if (bpf_prog_get_info_attr.info_len >
+                   offsetof(struct bpf_prog_info_struct, nr_func_info)) {
+                       printf(", nr_func_info=0");
+                       if (prog_info->nr_func_info)
+                               printf(" => %u", prog_info->nr_func_info);
+               }
+               if (bpf_prog_get_info_attr.info_len >
+                   offsetof(struct bpf_prog_info_struct, nr_line_info)) {
+                       printf(", nr_line_info=0");
+                       if (prog_info->nr_line_info)
+                               printf(" => %u", prog_info->nr_line_info);
+               }
+               if (bpf_prog_get_info_attr.info_len >
+                   offsetof(struct bpf_prog_info_struct, line_info))
+                       printf(", line_info=NULL");
+               if (bpf_prog_get_info_attr.info_len >
+                   offsetof(struct bpf_prog_info_struct, jited_line_info))
+                       printf(", jited_line_info=NULL");
+               if (bpf_prog_get_info_attr.info_len >
+                   offsetof(struct bpf_prog_info_struct, nr_jited_line_info)) {
+                       printf(", nr_jited_line_info=0");
+                       if (prog_info->nr_jited_line_info)
+                               printf(" => %u", prog_info->nr_jited_line_info);
+               }
+               if (bpf_prog_get_info_attr.info_len >
+                   offsetof(struct bpf_prog_info_struct, line_info_rec_size)) {
+                       printf(", line_info_rec_size=0");
+                       if (prog_info->line_info_rec_size)
+                               printf(" => %u", prog_info->line_info_rec_size);
+               }
+               if (bpf_prog_get_info_attr.info_len >
+                   offsetof(struct bpf_prog_info_struct, jited_line_info_rec_size)) {
+                       printf(", jited_line_info_rec_size=0");
+                       if (prog_info->jited_line_info_rec_size)
+                               printf(" => %u", prog_info->jited_line_info_rec_size);
+               }
+               if (bpf_prog_get_info_attr.info_len >
+                   offsetof(struct bpf_prog_info_struct, nr_prog_tags)) {
+                       printf(", nr_prog_tags=0");
+                       if (prog_info->nr_prog_tags)
+                               printf(" => %u", prog_info->nr_prog_tags);
+               }
+               if (bpf_prog_get_info_attr.info_len >
+                   offsetof(struct bpf_prog_info_struct, prog_tags))
+                       printf(", prog_tags=NULL");
+
                printf("}");
 # else /* !VERBOSE */
                printf("%p", prog_info);