From: Andrii Nakryiko <andrii@kernel.org>
To: <bpf@vger.kernel.org>, <ast@kernel.org>, <daniel@iogearbox.net>
Cc: <andrii@kernel.org>, <kernel-team@fb.com>,
Song Liu <songliubraving@fb.com>
Subject: [PATCH v2 bpf-next 06/10] bpftool: improve skeleton generation for data maps without DATASEC type
Date: Wed, 20 Oct 2021 18:44:00 -0700 [thread overview]
Message-ID: <20211021014404.2635234-7-andrii@kernel.org> (raw)
In-Reply-To: <20211021014404.2635234-1-andrii@kernel.org>
It can happen that some data sections (e.g., .rodata.cst16, containing
compiler populated string constants) won't have a corresponding BTF
DATASEC type. Now that libbpf supports .rodata.* and .data.* sections,
situation like that will cause invalid BPF skeleton to be generated that
won't compile successfully, as some parts of skeleton would assume
memory-mapped struct definitions for each special data section.
Fix this by generating empty struct definitions for such data sections.
Acked-by: Song Liu <songliubraving@fb.com>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
---
tools/bpf/bpftool/gen.c | 51 ++++++++++++++++++++++++++++++++++++-----
1 file changed, 45 insertions(+), 6 deletions(-)
diff --git a/tools/bpf/bpftool/gen.c b/tools/bpf/bpftool/gen.c
index 59afe9a2ca3c..c446405ab73f 100644
--- a/tools/bpf/bpftool/gen.c
+++ b/tools/bpf/bpftool/gen.c
@@ -213,22 +213,61 @@ static int codegen_datasecs(struct bpf_object *obj, const char *obj_name)
struct btf *btf = bpf_object__btf(obj);
int n = btf__get_nr_types(btf);
struct btf_dump *d;
+ struct bpf_map *map;
+ const struct btf_type *sec;
+ char sec_ident[256], map_ident[256];
int i, err = 0;
d = btf_dump__new(btf, NULL, NULL, codegen_btf_dump_printf);
if (IS_ERR(d))
return PTR_ERR(d);
- for (i = 1; i <= n; i++) {
- const struct btf_type *t = btf__type_by_id(btf, i);
+ bpf_object__for_each_map(map, obj) {
+ /* only generate definitions for memory-mapped internal maps */
+ if (!bpf_map__is_internal(map))
+ continue;
+ if (!(bpf_map__def(map)->map_flags & BPF_F_MMAPABLE))
+ continue;
- if (!btf_is_datasec(t))
+ if (!get_map_ident(map, map_ident, sizeof(map_ident)))
continue;
- err = codegen_datasec_def(obj, btf, d, t, obj_name);
- if (err)
- goto out;
+ sec = NULL;
+ for (i = 1; i <= n; i++) {
+ const struct btf_type *t = btf__type_by_id(btf, i);
+ const char *name;
+
+ if (!btf_is_datasec(t))
+ continue;
+
+ name = btf__str_by_offset(btf, t->name_off);
+ if (!get_datasec_ident(name, sec_ident, sizeof(sec_ident)))
+ continue;
+
+ if (strcmp(sec_ident, map_ident) == 0) {
+ sec = t;
+ break;
+ }
+ }
+
+ /* In some cases (e.g., sections like .rodata.cst16 containing
+ * compiler allocated string constants only) there will be
+ * special internal maps with no corresponding DATASEC BTF
+ * type. In such case, generate empty structs for each such
+ * map. It will still be memory-mapped and its contents
+ * accessible from user-space through BPF skeleton.
+ */
+ if (!sec) {
+ printf(" struct %s__%s {\n", obj_name, map_ident);
+ printf(" } *%s;\n", map_ident);
+ } else {
+ err = codegen_datasec_def(obj, btf, d, sec, obj_name);
+ if (err)
+ goto out;
+ }
}
+
+
out:
btf_dump__free(d);
return err;
--
2.30.2
next prev parent reply other threads:[~2021-10-21 1:44 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-10-21 1:43 [PATCH v2 bpf-next 00/10] libbpf: support custom .rodata.*/.data.* sections Andrii Nakryiko
2021-10-21 1:43 ` [PATCH v2 bpf-next 01/10] libbpf: deprecate btf__finalize_data() and move it into libbpf.c Andrii Nakryiko
2021-10-21 1:43 ` [PATCH v2 bpf-next 02/10] libbpf: extract ELF processing state into separate struct Andrii Nakryiko
2021-10-21 1:43 ` [PATCH v2 bpf-next 03/10] libbpf: use Elf64-specific types explicitly for dealing with ELF Andrii Nakryiko
2021-10-21 1:43 ` [PATCH v2 bpf-next 04/10] libbpf: remove assumptions about uniqueness of .rodata/.data/.bss maps Andrii Nakryiko
2021-10-21 1:43 ` [PATCH v2 bpf-next 05/10] bpftool: support multiple .rodata/.data internal maps in skeleton Andrii Nakryiko
2021-10-21 1:44 ` Andrii Nakryiko [this message]
2021-10-21 1:44 ` [PATCH v2 bpf-next 07/10] libbpf: support multiple .rodata.* and .data.* BPF maps Andrii Nakryiko
2021-10-21 1:44 ` [PATCH v2 bpf-next 08/10] selftests/bpf: demonstrate use of custom .rodata/.data sections Andrii Nakryiko
2021-10-21 1:44 ` [PATCH v2 bpf-next 09/10] libbpf: simplify look up by name of internal maps Andrii Nakryiko
2021-10-21 1:44 ` [PATCH v2 bpf-next 10/10] selftests/bpf: switch to ".bss"/".rodata"/".data" lookups for " 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=20211021014404.2635234-7-andrii@kernel.org \
--to=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=kernel-team@fb.com \
--cc=songliubraving@fb.com \
/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