From: Andrii Nakryiko <andriin@fb.com>
To: <bpf@vger.kernel.org>, <netdev@vger.kernel.org>, <ast@fb.com>,
<daniel@iogearbox.net>
Cc: <andrii.nakryiko@gmail.com>, <kernel-team@fb.com>,
Andrii Nakryiko <andriin@fb.com>
Subject: [PATCH v3 bpf-next 07/17] libbpf: expose BTF-to-C type declaration emitting API
Date: Fri, 13 Dec 2019 14:32:04 -0800 [thread overview]
Message-ID: <20191213223214.2791885-8-andriin@fb.com> (raw)
In-Reply-To: <20191213223214.2791885-1-andriin@fb.com>
Expose API that allows to emit type declaration and field/variable definition
(if optional field name is specified) in valid C syntax for any provided BTF
type. This is going to be used by bpftool when emitting data section layout as
a struct. As part of making this API useful in a stand-alone fashion, move
initialization of some of the internal btf_dump state to earlier phase.
Acked-by: Martin KaFai Lau <kafai@fb.com>
Signed-off-by: Andrii Nakryiko <andriin@fb.com>
---
tools/lib/bpf/btf.h | 22 ++++++++++++++
tools/lib/bpf/btf_dump.c | 62 +++++++++++++++++++++++-----------------
tools/lib/bpf/libbpf.map | 1 +
3 files changed, 59 insertions(+), 26 deletions(-)
diff --git a/tools/lib/bpf/btf.h b/tools/lib/bpf/btf.h
index a114c8ef4f08..1f9625946ead 100644
--- a/tools/lib/bpf/btf.h
+++ b/tools/lib/bpf/btf.h
@@ -126,6 +126,28 @@ LIBBPF_API void btf_dump__free(struct btf_dump *d);
LIBBPF_API int btf_dump__dump_type(struct btf_dump *d, __u32 id);
+struct btf_dump_emit_type_decl_opts {
+ /* size of this struct, for forward/backward compatiblity */
+ size_t sz;
+ /* optional field name for type declaration, e.g.:
+ * - struct my_struct <FNAME>
+ * - void (*<FNAME>)(int)
+ * - char (*<FNAME>)[123]
+ */
+ const char *field_name;
+ /* extra indentation level (in number of tabs) to emit for multi-line
+ * type declarations (e.g., anonymous struct); applies for lines
+ * starting from the second one (first line is assumed to have
+ * necessary indentation already
+ */
+ int indent_level;
+};
+#define btf_dump_emit_type_decl_opts__last_field attach_prog_fd
+
+LIBBPF_API void
+btf_dump__emit_type_decl(struct btf_dump *d, __u32 id,
+ const struct btf_dump_emit_type_decl_opts *opts);
+
/*
* A set of helpers for easier BTF types handling
*/
diff --git a/tools/lib/bpf/btf_dump.c b/tools/lib/bpf/btf_dump.c
index 53393026d085..b7a7a2ef785a 100644
--- a/tools/lib/bpf/btf_dump.c
+++ b/tools/lib/bpf/btf_dump.c
@@ -116,6 +116,8 @@ static void btf_dump_printf(const struct btf_dump *d, const char *fmt, ...)
va_end(args);
}
+static int btf_dump_mark_referenced(struct btf_dump *d);
+
struct btf_dump *btf_dump__new(const struct btf *btf,
const struct btf_ext *btf_ext,
const struct btf_dump_opts *opts,
@@ -137,18 +139,39 @@ struct btf_dump *btf_dump__new(const struct btf *btf,
if (IS_ERR(d->type_names)) {
err = PTR_ERR(d->type_names);
d->type_names = NULL;
- btf_dump__free(d);
- return ERR_PTR(err);
}
d->ident_names = hashmap__new(str_hash_fn, str_equal_fn, NULL);
if (IS_ERR(d->ident_names)) {
err = PTR_ERR(d->ident_names);
d->ident_names = NULL;
- btf_dump__free(d);
- return ERR_PTR(err);
+ goto err;
+ }
+ d->type_states = calloc(1 + btf__get_nr_types(d->btf),
+ sizeof(d->type_states[0]));
+ if (!d->type_states) {
+ err = -ENOMEM;
+ goto err;
+ }
+ d->cached_names = calloc(1 + btf__get_nr_types(d->btf),
+ sizeof(d->cached_names[0]));
+ if (!d->cached_names) {
+ err = -ENOMEM;
+ goto err;
}
+ /* VOID is special */
+ d->type_states[0].order_state = ORDERED;
+ d->type_states[0].emit_state = EMITTED;
+
+ /* eagerly determine referenced types for anon enums */
+ err = btf_dump_mark_referenced(d);
+ if (err)
+ goto err;
+
return d;
+err:
+ btf_dump__free(d);
+ return ERR_PTR(err);
}
void btf_dump__free(struct btf_dump *d)
@@ -175,7 +198,6 @@ void btf_dump__free(struct btf_dump *d)
free(d);
}
-static int btf_dump_mark_referenced(struct btf_dump *d);
static int btf_dump_order_type(struct btf_dump *d, __u32 id, bool through_ptr);
static void btf_dump_emit_type(struct btf_dump *d, __u32 id, __u32 cont_id);
@@ -202,27 +224,6 @@ int btf_dump__dump_type(struct btf_dump *d, __u32 id)
if (id > btf__get_nr_types(d->btf))
return -EINVAL;
- /* type states are lazily allocated, as they might not be needed */
- if (!d->type_states) {
- d->type_states = calloc(1 + btf__get_nr_types(d->btf),
- sizeof(d->type_states[0]));
- if (!d->type_states)
- return -ENOMEM;
- d->cached_names = calloc(1 + btf__get_nr_types(d->btf),
- sizeof(d->cached_names[0]));
- if (!d->cached_names)
- return -ENOMEM;
-
- /* VOID is special */
- d->type_states[0].order_state = ORDERED;
- d->type_states[0].emit_state = EMITTED;
-
- /* eagerly determine referenced types for anon enums */
- err = btf_dump_mark_referenced(d);
- if (err)
- return err;
- }
-
d->emit_queue_cnt = 0;
err = btf_dump_order_type(d, id, false);
if (err < 0)
@@ -1016,6 +1017,15 @@ static int btf_dump_push_decl_stack_id(struct btf_dump *d, __u32 id)
* of a stack frame. Some care is required to "pop" stack frames after
* processing type declaration chain.
*/
+void btf_dump__emit_type_decl(struct btf_dump *d, __u32 id,
+ const struct btf_dump_emit_type_decl_opts *opts)
+{
+ const char *fname = OPTS_GET(opts, field_name, NULL);
+ int lvl = OPTS_GET(opts, indent_level, 0);
+
+ btf_dump_emit_type_decl(d, id, fname, lvl);
+}
+
static void btf_dump_emit_type_decl(struct btf_dump *d, __u32 id,
const char *fname, int lvl)
{
diff --git a/tools/lib/bpf/libbpf.map b/tools/lib/bpf/libbpf.map
index e7fcca36f186..990c7c0e2d9f 100644
--- a/tools/lib/bpf/libbpf.map
+++ b/tools/lib/bpf/libbpf.map
@@ -211,6 +211,7 @@ LIBBPF_0.0.6 {
LIBBPF_0.0.7 {
global:
+ btf_dump__emit_type_decl;
bpf_program__attach;
btf__align_of;
} LIBBPF_0.0.6;
--
2.17.1
next prev parent reply other threads:[~2019-12-13 22:32 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-12-13 22:31 [PATCH v3 bpf-next 00/17] Add code-generated BPF object skeleton support Andrii Nakryiko
2019-12-13 22:31 ` [PATCH v3 bpf-next 01/17] libbpf: don't require root for bpf_object__open() Andrii Nakryiko
2019-12-13 22:31 ` [PATCH v3 bpf-next 02/17] libbpf: add generic bpf_program__attach() Andrii Nakryiko
2019-12-13 22:32 ` [PATCH v3 bpf-next 03/17] libbpf: move non-public APIs from libbpf.h to libbpf_internal.h Andrii Nakryiko
2019-12-13 22:32 ` [PATCH v3 bpf-next 04/17] libbpf: add BPF_EMBED_OBJ macro for embedding BPF .o files Andrii Nakryiko
2019-12-13 22:32 ` [PATCH v3 bpf-next 05/17] libbpf: extract common user-facing helpers Andrii Nakryiko
2019-12-13 22:32 ` [PATCH v3 bpf-next 06/17] libbpf: expose btf__align_of() API Andrii Nakryiko
2019-12-13 22:32 ` Andrii Nakryiko [this message]
2019-12-13 23:50 ` [PATCH v3 bpf-next 07/17] libbpf: expose BTF-to-C type declaration emitting API Alexei Starovoitov
2019-12-14 1:06 ` Andrii Nakryiko
2019-12-13 22:32 ` [PATCH v3 bpf-next 08/17] libbpf: expose BPF program's function name Andrii Nakryiko
2019-12-13 22:32 ` [PATCH v3 bpf-next 09/17] libbpf: refactor global data map initialization Andrii Nakryiko
2019-12-13 22:32 ` [PATCH v3 bpf-next 10/17] libbpf: postpone BTF ID finding for TRACING programs to load phase Andrii Nakryiko
2019-12-13 22:32 ` [PATCH v3 bpf-next 11/17] libbpf: reduce log level of supported section names dump Andrii Nakryiko
2019-12-13 22:32 ` [PATCH v3 bpf-next 12/17] libbpf: add BPF object skeleton support Andrii Nakryiko
2019-12-13 23:59 ` Alexei Starovoitov
2019-12-14 1:07 ` Andrii Nakryiko
2019-12-13 22:32 ` [PATCH v3 bpf-next 13/17] bpftool: add skeleton codegen command Andrii Nakryiko
2019-12-13 22:32 ` [PATCH v3 bpf-next 14/17] selftests/bpf: add BPF skeletons selftests and convert attach_probe.c Andrii Nakryiko
2019-12-14 0:00 ` Alexei Starovoitov
2019-12-13 22:32 ` [PATCH v3 bpf-next 15/17] selftests/bpf: convert few more selftest to skeletons Andrii Nakryiko
2019-12-14 0:01 ` Alexei Starovoitov
2019-12-13 22:32 ` [PATCH v3 bpf-next 16/17] selftests/bpf: add test validating data section to struct convertion layout Andrii Nakryiko
2019-12-13 22:32 ` [PATCH v3 bpf-next 17/17] bpftool: add `gen skeleton` BASH completions Andrii Nakryiko
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20191213223214.2791885-8-andriin@fb.com \
--to=andriin@fb.com \
--cc=andrii.nakryiko@gmail.com \
--cc=ast@fb.com \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=kernel-team@fb.com \
--cc=netdev@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox