aboutsummaryrefslogtreecommitdiffstats
path: root/tools/lib/bpf/btf.c
diff options
context:
space:
mode:
authorAndrii Nakryiko <andriin@fb.com>2019-02-08 14:19:36 -0500
committerAlexei Starovoitov <ast@kernel.org>2019-02-08 15:04:13 -0500
commitd29d87f7e61226c339d1212beff6b82f653acd67 (patch)
treea7b9c48234295bf780fa7476bf476efe29690b87 /tools/lib/bpf/btf.c
parenta4021a3579c52d5a5131820aeb94f531a7b082a7 (diff)
btf: separate btf creation and loading
This change splits out previous btf__new functionality of constructing struct btf and loading it into kernel into two: - btf__new() just creates and initializes struct btf - btf__load() attempts to load existing struct btf into kernel btf__free will still close BTF fd, if it was ever loaded successfully into kernel. This change allows users of libbpf to manipulate BTF using its API, without the need to unnecessarily load it into kernel. One of the intended use cases is pahole, which will do DWARF to BTF conversion and then use libbpf to do type deduplication, while then handling ELF sections overwriting and other concerns on its own. Fixes: 2d3feca8c44f ("bpf: btf: print map dump and lookup with btf info") Signed-off-by: Andrii Nakryiko <andriin@fb.com> Acked-by: Song Liu <songliubraving@fb.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Diffstat (limited to 'tools/lib/bpf/btf.c')
-rw-r--r--tools/lib/bpf/btf.c54
1 files changed, 30 insertions, 24 deletions
diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c
index 4324eb47d214..46db0a3b5cb7 100644
--- a/tools/lib/bpf/btf.c
+++ b/tools/lib/bpf/btf.c
@@ -367,8 +367,6 @@ void btf__free(struct btf *btf)
367 367
368struct btf *btf__new(__u8 *data, __u32 size) 368struct btf *btf__new(__u8 *data, __u32 size)
369{ 369{
370 __u32 log_buf_size = 0;
371 char *log_buf = NULL;
372 struct btf *btf; 370 struct btf *btf;
373 int err; 371 int err;
374 372
@@ -378,15 +376,6 @@ struct btf *btf__new(__u8 *data, __u32 size)
378 376
379 btf->fd = -1; 377 btf->fd = -1;
380 378
381 log_buf = malloc(BPF_LOG_BUF_SIZE);
382 if (!log_buf) {
383 err = -ENOMEM;
384 goto done;
385 }
386
387 *log_buf = 0;
388 log_buf_size = BPF_LOG_BUF_SIZE;
389
390 btf->data = malloc(size); 379 btf->data = malloc(size);
391 if (!btf->data) { 380 if (!btf->data) {
392 err = -ENOMEM; 381 err = -ENOMEM;
@@ -396,17 +385,6 @@ struct btf *btf__new(__u8 *data, __u32 size)
396 memcpy(btf->data, data, size); 385 memcpy(btf->data, data, size);
397 btf->data_size = size; 386 btf->data_size = size;
398 387
399 btf->fd = bpf_load_btf(btf->data, btf->data_size,
400 log_buf, log_buf_size, false);
401
402 if (btf->fd == -1) {
403 err = -errno;
404 pr_warning("Error loading BTF: %s(%d)\n", strerror(errno), errno);
405 if (log_buf && *log_buf)
406 pr_warning("%s\n", log_buf);
407 goto done;
408 }
409
410 err = btf_parse_hdr(btf); 388 err = btf_parse_hdr(btf);
411 if (err) 389 if (err)
412 goto done; 390 goto done;
@@ -418,8 +396,6 @@ struct btf *btf__new(__u8 *data, __u32 size)
418 err = btf_parse_type_sec(btf); 396 err = btf_parse_type_sec(btf);
419 397
420done: 398done:
421 free(log_buf);
422
423 if (err) { 399 if (err) {
424 btf__free(btf); 400 btf__free(btf);
425 return ERR_PTR(err); 401 return ERR_PTR(err);
@@ -428,6 +404,36 @@ done:
428 return btf; 404 return btf;
429} 405}
430 406
407int btf__load(struct btf *btf)
408{
409 __u32 log_buf_size = BPF_LOG_BUF_SIZE;
410 char *log_buf = NULL;
411 int err = 0;
412
413 if (btf->fd >= 0)
414 return -EEXIST;
415
416 log_buf = malloc(log_buf_size);
417 if (!log_buf)
418 return -ENOMEM;
419
420 *log_buf = 0;
421
422 btf->fd = bpf_load_btf(btf->data, btf->data_size,
423 log_buf, log_buf_size, false);
424 if (btf->fd < 0) {
425 err = -errno;
426 pr_warning("Error loading BTF: %s(%d)\n", strerror(errno), errno);
427 if (*log_buf)
428 pr_warning("%s\n", log_buf);
429 goto done;
430 }
431
432done:
433 free(log_buf);
434 return err;
435}
436
431int btf__fd(const struct btf *btf) 437int btf__fd(const struct btf *btf)
432{ 438{
433 return btf->fd; 439 return btf->fd;