diff options
Diffstat (limited to 'tools/lib/bpf/libbpf.c')
-rw-r--r-- | tools/lib/bpf/libbpf.c | 34 |
1 files changed, 23 insertions, 11 deletions
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index 794dd5064ae8..2586b6cb8f34 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <inttypes.h> | 20 | #include <inttypes.h> |
21 | #include <string.h> | 21 | #include <string.h> |
22 | #include <unistd.h> | 22 | #include <unistd.h> |
23 | #include <endian.h> | ||
23 | #include <fcntl.h> | 24 | #include <fcntl.h> |
24 | #include <errno.h> | 25 | #include <errno.h> |
25 | #include <asm/unistd.h> | 26 | #include <asm/unistd.h> |
@@ -612,10 +613,10 @@ errout: | |||
612 | 613 | ||
613 | static int bpf_object__check_endianness(struct bpf_object *obj) | 614 | static int bpf_object__check_endianness(struct bpf_object *obj) |
614 | { | 615 | { |
615 | #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ | 616 | #if __BYTE_ORDER == __LITTLE_ENDIAN |
616 | if (obj->efile.ehdr.e_ident[EI_DATA] == ELFDATA2LSB) | 617 | if (obj->efile.ehdr.e_ident[EI_DATA] == ELFDATA2LSB) |
617 | return 0; | 618 | return 0; |
618 | #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ | 619 | #elif __BYTE_ORDER == __BIG_ENDIAN |
619 | if (obj->efile.ehdr.e_ident[EI_DATA] == ELFDATA2MSB) | 620 | if (obj->efile.ehdr.e_ident[EI_DATA] == ELFDATA2MSB) |
620 | return 0; | 621 | return 0; |
621 | #else | 622 | #else |
@@ -1377,8 +1378,13 @@ static void bpf_object__sanitize_btf(struct bpf_object *obj) | |||
1377 | if (!has_datasec && kind == BTF_KIND_VAR) { | 1378 | if (!has_datasec && kind == BTF_KIND_VAR) { |
1378 | /* replace VAR with INT */ | 1379 | /* replace VAR with INT */ |
1379 | t->info = BTF_INFO_ENC(BTF_KIND_INT, 0, 0); | 1380 | t->info = BTF_INFO_ENC(BTF_KIND_INT, 0, 0); |
1380 | t->size = sizeof(int); | 1381 | /* |
1381 | *(int *)(t+1) = BTF_INT_ENC(0, 0, 32); | 1382 | * using size = 1 is the safest choice, 4 will be too |
1383 | * big and cause kernel BTF validation failure if | ||
1384 | * original variable took less than 4 bytes | ||
1385 | */ | ||
1386 | t->size = 1; | ||
1387 | *(int *)(t+1) = BTF_INT_ENC(0, 0, 8); | ||
1382 | } else if (!has_datasec && kind == BTF_KIND_DATASEC) { | 1388 | } else if (!has_datasec && kind == BTF_KIND_DATASEC) { |
1383 | /* replace DATASEC with STRUCT */ | 1389 | /* replace DATASEC with STRUCT */ |
1384 | struct btf_var_secinfo *v = (void *)(t + 1); | 1390 | struct btf_var_secinfo *v = (void *)(t + 1); |
@@ -1500,6 +1506,12 @@ static int bpf_object__sanitize_and_load_btf(struct bpf_object *obj) | |||
1500 | BTF_ELF_SEC, err); | 1506 | BTF_ELF_SEC, err); |
1501 | btf__free(obj->btf); | 1507 | btf__free(obj->btf); |
1502 | obj->btf = NULL; | 1508 | obj->btf = NULL; |
1509 | /* btf_ext can't exist without btf, so free it as well */ | ||
1510 | if (obj->btf_ext) { | ||
1511 | btf_ext__free(obj->btf_ext); | ||
1512 | obj->btf_ext = NULL; | ||
1513 | } | ||
1514 | |||
1503 | if (bpf_object__is_btf_mandatory(obj)) | 1515 | if (bpf_object__is_btf_mandatory(obj)) |
1504 | return err; | 1516 | return err; |
1505 | } | 1517 | } |
@@ -4507,13 +4519,13 @@ struct perf_buffer *perf_buffer__new(int map_fd, size_t page_cnt, | |||
4507 | const struct perf_buffer_opts *opts) | 4519 | const struct perf_buffer_opts *opts) |
4508 | { | 4520 | { |
4509 | struct perf_buffer_params p = {}; | 4521 | struct perf_buffer_params p = {}; |
4510 | struct perf_event_attr attr = { | 4522 | struct perf_event_attr attr = { 0, }; |
4511 | .config = PERF_COUNT_SW_BPF_OUTPUT, | 4523 | |
4512 | .type = PERF_TYPE_SOFTWARE, | 4524 | attr.config = PERF_COUNT_SW_BPF_OUTPUT, |
4513 | .sample_type = PERF_SAMPLE_RAW, | 4525 | attr.type = PERF_TYPE_SOFTWARE; |
4514 | .sample_period = 1, | 4526 | attr.sample_type = PERF_SAMPLE_RAW; |
4515 | .wakeup_events = 1, | 4527 | attr.sample_period = 1; |
4516 | }; | 4528 | attr.wakeup_events = 1; |
4517 | 4529 | ||
4518 | p.attr = &attr; | 4530 | p.attr = &attr; |
4519 | p.sample_cb = opts ? opts->sample_cb : NULL; | 4531 | p.sample_cb = opts ? opts->sample_cb : NULL; |