From: Dmitry V. Levin Date: Wed, 13 Mar 2019 18:38:51 +0000 (+0000) Subject: bpf: implement decoding of BPF_BTF_LOAD command X-Git-Tag: v5.0~17 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=bc4224a8fa641819d42639ac5b3252681304bfc3;p=strace bpf: implement decoding of BPF_BTF_LOAD command BPF_BTF_LOAD command was introduced by Linux commit v4.18-rc1~114^2~417^2~1^2~5. * bpf_attr.h (struct BPF_BTF_LOAD_struct): New type. (BPF_BTF_LOAD_struct_size, expected_BPF_BTF_LOAD_struct_size): New macros. * bpf.c (BEGIN_BPF_CMD_DECODER(BPF_BTF_LOAD)): New bpf command decoder. (SYS_FUNC(bpf)) : Add BPF_CMD_ENTRY(BPF_BTF_LOAD). * tests/bpf.c (union bpf_attr_data): Add BPF_ATTR_DATA_FIELD(BPF_BTF_LOAD). (init_BPF_BTF_LOAD_attr): New function. (BPF_BTF_LOAD_checks): New checks array. (main) : Add CHK(BPF_BTF_LOAD). --- diff --git a/bpf.c b/bpf.c index fbd77dcf..5fedbd18 100644 --- a/bpf.c +++ b/bpf.c @@ -825,6 +825,18 @@ BEGIN_BPF_CMD_DECODER(BPF_RAW_TRACEPOINT_OPEN) } END_BPF_CMD_DECODER(RVAL_DECODED) +BEGIN_BPF_CMD_DECODER(BPF_BTF_LOAD) +{ + tprints("{btf="); + print_big_u64_addr(attr.btf); + printstrn(tcp, attr.btf, attr.btf_size); + PRINT_FIELD_ADDR64(", ", attr, btf_log_buf); + PRINT_FIELD_U(", ", attr, btf_size); + PRINT_FIELD_U(", ", attr, btf_log_size); + PRINT_FIELD_U(", ", attr, btf_log_level); +} +END_BPF_CMD_DECODER(RVAL_DECODED | RVAL_FD) + SYS_FUNC(bpf) { static const bpf_cmd_decoder_t bpf_cmd_decoders[] = { @@ -846,6 +858,7 @@ SYS_FUNC(bpf) BPF_CMD_ENTRY(BPF_OBJ_GET_INFO_BY_FD), BPF_CMD_ENTRY(BPF_PROG_QUERY), BPF_CMD_ENTRY(BPF_RAW_TRACEPOINT_OPEN), + BPF_CMD_ENTRY(BPF_BTF_LOAD), }; const unsigned int cmd = tcp->u_arg[0]; diff --git a/bpf_attr.h b/bpf_attr.h index b34983a8..a04f79ee 100644 --- a/bpf_attr.h +++ b/bpf_attr.h @@ -227,6 +227,18 @@ struct BPF_RAW_TRACEPOINT_OPEN_struct /* raw_tracepoint */ { offsetofend(struct BPF_RAW_TRACEPOINT_OPEN_struct, prog_fd) # define expected_BPF_RAW_TRACEPOINT_OPEN_struct_size 12 +struct BPF_BTF_LOAD_struct { + uint64_t ATTRIBUTE_ALIGNED(8) btf; + uint64_t ATTRIBUTE_ALIGNED(8) btf_log_buf; + uint32_t btf_size; + uint32_t btf_log_size; + uint32_t btf_log_level; +}; + +# define BPF_BTF_LOAD_struct_size \ + offsetofend(struct BPF_BTF_LOAD_struct, btf_log_level) +# define expected_BPF_BTF_LOAD_struct_size 28 + struct bpf_map_info_struct { uint32_t type; uint32_t id; diff --git a/tests/bpf.c b/tests/bpf.c index b18a056e..85b27d5d 100644 --- a/tests/bpf.c +++ b/tests/bpf.c @@ -71,6 +71,7 @@ union bpf_attr_data { BPF_ATTR_DATA_FIELD(BPF_OBJ_GET_INFO_BY_FD); BPF_ATTR_DATA_FIELD(BPF_PROG_QUERY); BPF_ATTR_DATA_FIELD(BPF_RAW_TRACEPOINT_OPEN); + BPF_ATTR_DATA_FIELD(BPF_BTF_LOAD); char char_data[256]; }; @@ -1078,6 +1079,44 @@ static struct bpf_attr_check BPF_RAW_TRACEPOINT_OPEN_checks[] = { } }; +static void +init_BPF_BTF_LOAD_attr(struct bpf_attr_check *check) +{ + static const char sample_btf_data[] = "bPf\0daTum"; + + static char *btf_data; + if (!btf_data) + btf_data = tail_memdup(sample_btf_data, + sizeof(sample_btf_data) - 1); + + struct BPF_BTF_LOAD_struct *attr = &check->data.BPF_BTF_LOAD_data; + attr->btf = (uintptr_t) btf_data; +} + +static struct bpf_attr_check BPF_BTF_LOAD_checks[] = { + { + .data = { .BPF_BTF_LOAD_data = { .btf = 0 } }, + .size = offsetofend(struct BPF_BTF_LOAD_struct, btf), + .str = "btf=NULL, btf_log_buf=NULL, btf_size=0" + ", btf_log_size=0, btf_log_level=0" + }, + { /* 1 */ + .data = { .BPF_BTF_LOAD_data = { + .btf_log_buf = 0xfacefeeddeadbeefULL, + .btf_size = 9, + .btf_log_size = -1U, + .btf_log_level = 42 + } }, + .size = offsetofend(struct BPF_BTF_LOAD_struct, btf_log_level), + .init_fn = init_BPF_BTF_LOAD_attr, + .str = "btf=\"bPf\\0daTum\"" + ", btf_log_buf=0xfacefeeddeadbeef" + ", btf_size=9" + ", btf_log_size=4294967295" + ", btf_log_level=42" + } +}; + #define CHK(cmd_) \ { \ @@ -1108,6 +1147,7 @@ main(void) CHK(BPF_OBJ_GET_INFO_BY_FD), CHK(BPF_PROG_QUERY), CHK(BPF_RAW_TRACEPOINT_OPEN), + CHK(BPF_BTF_LOAD), }; page_size = get_page_size();