Skip to content

Commit cfa3eb6

Browse files
committed
Merge branch 'bpf-libbpf-btf-parsing'
Andrii Nakryiko says: ==================== It's pretty common for applications to want to parse raw (binary) BTF data from file, as opposed to parsing it from ELF sections. It's also pretty common for tools to not care whether given file is ELF or raw BTF format. This patch series exposes internal raw BTF parsing API and adds generic variant of BTF parsing, which will efficiently determine the format of a given fail and will parse BTF appropriately. Patches #2 and #3 removes re-implementations of such APIs from bpftool and resolve_btfids tools. ==================== Signed-off-by: Daniel Borkmann <[email protected]>
2 parents 041549b + f86ca3c commit cfa3eb6

File tree

6 files changed

+89
-148
lines changed

6 files changed

+89
-148
lines changed

tools/bpf/bpftool/btf.c

Lines changed: 1 addition & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -422,54 +422,6 @@ static int dump_btf_c(const struct btf *btf,
422422
return err;
423423
}
424424

425-
static struct btf *btf__parse_raw(const char *file)
426-
{
427-
struct btf *btf;
428-
struct stat st;
429-
__u8 *buf;
430-
FILE *f;
431-
432-
if (stat(file, &st))
433-
return NULL;
434-
435-
f = fopen(file, "rb");
436-
if (!f)
437-
return NULL;
438-
439-
buf = malloc(st.st_size);
440-
if (!buf) {
441-
btf = ERR_PTR(-ENOMEM);
442-
goto exit_close;
443-
}
444-
445-
if ((size_t) st.st_size != fread(buf, 1, st.st_size, f)) {
446-
btf = ERR_PTR(-EINVAL);
447-
goto exit_free;
448-
}
449-
450-
btf = btf__new(buf, st.st_size);
451-
452-
exit_free:
453-
free(buf);
454-
exit_close:
455-
fclose(f);
456-
return btf;
457-
}
458-
459-
static bool is_btf_raw(const char *file)
460-
{
461-
__u16 magic = 0;
462-
int fd, nb_read;
463-
464-
fd = open(file, O_RDONLY);
465-
if (fd < 0)
466-
return false;
467-
468-
nb_read = read(fd, &magic, sizeof(magic));
469-
close(fd);
470-
return nb_read == sizeof(magic) && magic == BTF_MAGIC;
471-
}
472-
473425
static int do_dump(int argc, char **argv)
474426
{
475427
struct btf *btf = NULL;
@@ -547,11 +499,7 @@ static int do_dump(int argc, char **argv)
547499
}
548500
NEXT_ARG();
549501
} else if (is_prefix(src, "file")) {
550-
if (is_btf_raw(*argv))
551-
btf = btf__parse_raw(*argv);
552-
else
553-
btf = btf__parse_elf(*argv, NULL);
554-
502+
btf = btf__parse(*argv, NULL);
555503
if (IS_ERR(btf)) {
556504
err = -PTR_ERR(btf);
557505
btf = NULL;

tools/bpf/resolve_btfids/.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/FEATURE-DUMP.libbpf
2+
/bpf_helper_defs.h
3+
/fixdep
4+
/resolve_btfids

tools/bpf/resolve_btfids/main.c

Lines changed: 1 addition & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -403,62 +403,6 @@ static int symbols_collect(struct object *obj)
403403
return 0;
404404
}
405405

406-
static struct btf *btf__parse_raw(const char *file)
407-
{
408-
struct btf *btf;
409-
struct stat st;
410-
__u8 *buf;
411-
FILE *f;
412-
413-
if (stat(file, &st))
414-
return NULL;
415-
416-
f = fopen(file, "rb");
417-
if (!f)
418-
return NULL;
419-
420-
buf = malloc(st.st_size);
421-
if (!buf) {
422-
btf = ERR_PTR(-ENOMEM);
423-
goto exit_close;
424-
}
425-
426-
if ((size_t) st.st_size != fread(buf, 1, st.st_size, f)) {
427-
btf = ERR_PTR(-EINVAL);
428-
goto exit_free;
429-
}
430-
431-
btf = btf__new(buf, st.st_size);
432-
433-
exit_free:
434-
free(buf);
435-
exit_close:
436-
fclose(f);
437-
return btf;
438-
}
439-
440-
static bool is_btf_raw(const char *file)
441-
{
442-
__u16 magic = 0;
443-
int fd, nb_read;
444-
445-
fd = open(file, O_RDONLY);
446-
if (fd < 0)
447-
return false;
448-
449-
nb_read = read(fd, &magic, sizeof(magic));
450-
close(fd);
451-
return nb_read == sizeof(magic) && magic == BTF_MAGIC;
452-
}
453-
454-
static struct btf *btf_open(const char *path)
455-
{
456-
if (is_btf_raw(path))
457-
return btf__parse_raw(path);
458-
else
459-
return btf__parse_elf(path, NULL);
460-
}
461-
462406
static int symbols_resolve(struct object *obj)
463407
{
464408
int nr_typedefs = obj->nr_typedefs;
@@ -469,7 +413,7 @@ static int symbols_resolve(struct object *obj)
469413
struct btf *btf;
470414
__u32 nr;
471415

472-
btf = btf_open(obj->btf ?: obj->path);
416+
btf = btf__parse(obj->btf ?: obj->path, NULL);
473417
err = libbpf_get_error(btf);
474418
if (err) {
475419
pr_err("FAILED: load BTF from %s: %s",

tools/lib/bpf/btf.c

Lines changed: 78 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,83 @@ struct btf *btf__parse_elf(const char *path, struct btf_ext **btf_ext)
562562
return btf;
563563
}
564564

565+
struct btf *btf__parse_raw(const char *path)
566+
{
567+
void *data = NULL;
568+
struct btf *btf;
569+
FILE *f = NULL;
570+
__u16 magic;
571+
int err = 0;
572+
long sz;
573+
574+
f = fopen(path, "rb");
575+
if (!f) {
576+
err = -errno;
577+
goto err_out;
578+
}
579+
580+
/* check BTF magic */
581+
if (fread(&magic, 1, sizeof(magic), f) < sizeof(magic)) {
582+
err = -EIO;
583+
goto err_out;
584+
}
585+
if (magic != BTF_MAGIC) {
586+
/* definitely not a raw BTF */
587+
err = -EPROTO;
588+
goto err_out;
589+
}
590+
591+
/* get file size */
592+
if (fseek(f, 0, SEEK_END)) {
593+
err = -errno;
594+
goto err_out;
595+
}
596+
sz = ftell(f);
597+
if (sz < 0) {
598+
err = -errno;
599+
goto err_out;
600+
}
601+
/* rewind to the start */
602+
if (fseek(f, 0, SEEK_SET)) {
603+
err = -errno;
604+
goto err_out;
605+
}
606+
607+
/* pre-alloc memory and read all of BTF data */
608+
data = malloc(sz);
609+
if (!data) {
610+
err = -ENOMEM;
611+
goto err_out;
612+
}
613+
if (fread(data, 1, sz, f) < sz) {
614+
err = -EIO;
615+
goto err_out;
616+
}
617+
618+
/* finally parse BTF data */
619+
btf = btf__new(data, sz);
620+
621+
err_out:
622+
free(data);
623+
if (f)
624+
fclose(f);
625+
return err ? ERR_PTR(err) : btf;
626+
}
627+
628+
struct btf *btf__parse(const char *path, struct btf_ext **btf_ext)
629+
{
630+
struct btf *btf;
631+
632+
if (btf_ext)
633+
*btf_ext = NULL;
634+
635+
btf = btf__parse_raw(path);
636+
if (!IS_ERR(btf) || PTR_ERR(btf) != -EPROTO)
637+
return btf;
638+
639+
return btf__parse_elf(path, btf_ext);
640+
}
641+
565642
static int compare_vsi_off(const void *_a, const void *_b)
566643
{
567644
const struct btf_var_secinfo *a = _a;
@@ -2951,41 +3028,6 @@ static int btf_dedup_remap_types(struct btf_dedup *d)
29513028
return 0;
29523029
}
29533030

2954-
static struct btf *btf_load_raw(const char *path)
2955-
{
2956-
struct btf *btf;
2957-
size_t read_cnt;
2958-
struct stat st;
2959-
void *data;
2960-
FILE *f;
2961-
2962-
if (stat(path, &st))
2963-
return ERR_PTR(-errno);
2964-
2965-
data = malloc(st.st_size);
2966-
if (!data)
2967-
return ERR_PTR(-ENOMEM);
2968-
2969-
f = fopen(path, "rb");
2970-
if (!f) {
2971-
btf = ERR_PTR(-errno);
2972-
goto cleanup;
2973-
}
2974-
2975-
read_cnt = fread(data, 1, st.st_size, f);
2976-
fclose(f);
2977-
if (read_cnt < st.st_size) {
2978-
btf = ERR_PTR(-EBADF);
2979-
goto cleanup;
2980-
}
2981-
2982-
btf = btf__new(data, read_cnt);
2983-
2984-
cleanup:
2985-
free(data);
2986-
return btf;
2987-
}
2988-
29893031
/*
29903032
* Probe few well-known locations for vmlinux kernel image and try to load BTF
29913033
* data out of it to use for target BTF.
@@ -3021,7 +3063,7 @@ struct btf *libbpf_find_kernel_btf(void)
30213063
continue;
30223064

30233065
if (locations[i].raw_btf)
3024-
btf = btf_load_raw(path);
3066+
btf = btf__parse_raw(path);
30253067
else
30263068
btf = btf__parse_elf(path, NULL);
30273069

tools/lib/bpf/btf.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,9 @@ struct btf_ext_header {
6464

6565
LIBBPF_API void btf__free(struct btf *btf);
6666
LIBBPF_API struct btf *btf__new(const void *data, __u32 size);
67-
LIBBPF_API struct btf *btf__parse_elf(const char *path,
68-
struct btf_ext **btf_ext);
67+
LIBBPF_API struct btf *btf__parse(const char *path, struct btf_ext **btf_ext);
68+
LIBBPF_API struct btf *btf__parse_elf(const char *path, struct btf_ext **btf_ext);
69+
LIBBPF_API struct btf *btf__parse_raw(const char *path);
6970
LIBBPF_API int btf__finalize_data(struct bpf_object *obj, struct btf *btf);
7071
LIBBPF_API int btf__load(struct btf *btf);
7172
LIBBPF_API __s32 btf__find_by_name(const struct btf *btf,

tools/lib/bpf/libbpf.map

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,5 +293,7 @@ LIBBPF_0.1.0 {
293293
bpf_program__is_sk_lookup;
294294
bpf_program__set_autoload;
295295
bpf_program__set_sk_lookup;
296+
btf__parse;
297+
btf__parse_raw;
296298
btf__set_fd;
297299
} LIBBPF_0.0.9;

0 commit comments

Comments
 (0)