netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Ian Rogers <irogers@google.com>
To: "Alexei Starovoitov" <ast@kernel.org>,
	"Daniel Borkmann" <daniel@iogearbox.net>,
	"Martin KaFai Lau" <kafai@fb.com>,
	"Song Liu" <songliubraving@fb.com>, "Yonghong Song" <yhs@fb.com>,
	"Andrii Nakryiko" <andriin@fb.com>,
	"John Fastabend" <john.fastabend@gmail.com>,
	"KP Singh" <kpsingh@chromium.org>,
	"Quentin Monnet" <quentin@isovalent.com>,
	"Jakub Kicinski" <kuba@kernel.org>,
	"Jiri Olsa" <jolsa@kernel.org>,
	"Toke Høiland-Jørgensen" <toke@redhat.com>,
	netdev@vger.kernel.org, bpf@vger.kernel.org,
	linux-kernel@vger.kernel.org
Cc: Stanislav Fomichev <sdf@google.com>, Ian Rogers <irogers@google.com>
Subject: [RFC PATCH] bpftool btf: Add prefix option to dump C
Date: Tue, 21 Jul 2020 22:43:14 -0700	[thread overview]
Message-ID: <20200722054314.2103880-1-irogers@google.com> (raw)

When bpftool dumps types and enum members into a header file for
inclusion the names match those in the original source. If the same
header file needs to be included in the original source and the bpf
program, the names of structs, unions, typedefs and enum members will
have naming collisions.

To avoid these collisions an approach is to redeclare the header file
types and enum members, which leads to duplication and possible
inconsistencies. Another approach is to use preprocessor macros
to rename conflicting names, but this can be cumbersome if there are
many conflicts.

This patch adds a prefix option for the dumped names. Use of this option
can avoid name conflicts and compile time errors.

Signed-off-by: Ian Rogers <irogers@google.com>
---
 .../bpf/bpftool/Documentation/bpftool-btf.rst |  7 ++++++-
 tools/bpf/bpftool/btf.c                       | 18 ++++++++++++++---
 tools/lib/bpf/btf.h                           |  1 +
 tools/lib/bpf/btf_dump.c                      | 20 +++++++++++++------
 4 files changed, 36 insertions(+), 10 deletions(-)

diff --git a/tools/bpf/bpftool/Documentation/bpftool-btf.rst b/tools/bpf/bpftool/Documentation/bpftool-btf.rst
index 896f4c6c2870..85d66bc69634 100644
--- a/tools/bpf/bpftool/Documentation/bpftool-btf.rst
+++ b/tools/bpf/bpftool/Documentation/bpftool-btf.rst
@@ -20,7 +20,7 @@ BTF COMMANDS
 =============
 
 |	**bpftool** **btf** { **show** | **list** } [**id** *BTF_ID*]
-|	**bpftool** **btf dump** *BTF_SRC* [**format** *FORMAT*]
+|	**bpftool** **btf dump** *BTF_SRC* [**format** *FORMAT*] [**prefix** *PREFIX*]
 |	**bpftool** **btf help**
 |
 |	*BTF_SRC* := { **id** *BTF_ID* | **prog** *PROG* | **map** *MAP* [{**key** | **value** | **kv** | **all**}] | **file** *FILE* }
@@ -66,6 +66,11 @@ DESCRIPTION
 		  output format. Raw (**raw**) or C-syntax (**c**) output
 		  formats are supported.
 
+		  With the C-syntax format the **prefix** option can
+                  be used to prefix all identifiers and enum members
+                  with *PREFIX*. This is useful to avoid naming
+                  collisions.
+
 	**bpftool btf help**
 		  Print short help message.
 
diff --git a/tools/bpf/bpftool/btf.c b/tools/bpf/bpftool/btf.c
index fc9bc7a23db6..6a428636fa6f 100644
--- a/tools/bpf/bpftool/btf.c
+++ b/tools/bpf/bpftool/btf.c
@@ -379,12 +379,15 @@ static void __printf(2, 0) btf_dump_printf(void *ctx,
 }
 
 static int dump_btf_c(const struct btf *btf,
-		      __u32 *root_type_ids, int root_type_cnt)
+		      __u32 *root_type_ids, int root_type_cnt, const char *name_prefix)
 {
 	struct btf_dump *d;
 	int err = 0, i;
+	struct btf_dump_opts opts = {
+		.name_prefix = name_prefix,
+	};
 
-	d = btf_dump__new(btf, NULL, NULL, btf_dump_printf);
+	d = btf_dump__new(btf, NULL, &opts, btf_dump_printf);
 	if (IS_ERR(d))
 		return PTR_ERR(d);
 
@@ -478,6 +481,7 @@ static int do_dump(int argc, char **argv)
 	bool dump_c = false;
 	__u32 btf_id = -1;
 	const char *src;
+	const char *c_prefix = NULL;
 	int fd = -1;
 	int err;
 
@@ -583,6 +587,14 @@ static int do_dump(int argc, char **argv)
 				goto done;
 			}
 			NEXT_ARG();
+		} else if (is_prefix(*argv, "prefix")) {
+			NEXT_ARG();
+			if (argc < 1 || !*argv) {
+				p_err("expecting value for 'prefix' option\n");
+				goto done;
+			}
+			c_prefix = *argv;
+			NEXT_ARG();
 		} else {
 			p_err("unrecognized option: '%s'", *argv);
 			goto done;
@@ -608,7 +620,7 @@ static int do_dump(int argc, char **argv)
 			err = -ENOTSUP;
 			goto done;
 		}
-		err = dump_btf_c(btf, root_type_ids, root_type_cnt);
+		err = dump_btf_c(btf, root_type_ids, root_type_cnt, c_prefix);
 	} else {
 		err = dump_btf_raw(btf, root_type_ids, root_type_cnt);
 	}
diff --git a/tools/lib/bpf/btf.h b/tools/lib/bpf/btf.h
index 491c7b41ffdc..fea4baab00bd 100644
--- a/tools/lib/bpf/btf.h
+++ b/tools/lib/bpf/btf.h
@@ -117,6 +117,7 @@ struct btf_dump;
 
 struct btf_dump_opts {
 	void *ctx;
+	const char *name_prefix;
 };
 
 typedef void (*btf_dump_printf_fn_t)(void *ctx, const char *fmt, va_list args);
diff --git a/tools/lib/bpf/btf_dump.c b/tools/lib/bpf/btf_dump.c
index e1c344504cae..baf2b4d82e1e 100644
--- a/tools/lib/bpf/btf_dump.c
+++ b/tools/lib/bpf/btf_dump.c
@@ -138,6 +138,7 @@ struct btf_dump *btf_dump__new(const struct btf *btf,
 	d->btf_ext = btf_ext;
 	d->printf_fn = printf_fn;
 	d->opts.ctx = opts ? opts->ctx : NULL;
+	d->opts.name_prefix = opts ? opts->name_prefix : NULL;
 
 	d->type_names = hashmap__new(str_hash_fn, str_equal_fn, NULL);
 	if (IS_ERR(d->type_names)) {
@@ -903,6 +904,7 @@ static void btf_dump_emit_enum_def(struct btf_dump *d, __u32 id,
 	const struct btf_enum *v = btf_enum(t);
 	__u16 vlen = btf_vlen(t);
 	const char *name;
+	const char *name_prefix = d->opts.name_prefix;
 	size_t dup_cnt;
 	int i;
 
@@ -912,17 +914,19 @@ static void btf_dump_emit_enum_def(struct btf_dump *d, __u32 id,
 
 	if (vlen) {
 		btf_dump_printf(d, " {");
+		if (!name_prefix)
+			name_prefix = "";
 		for (i = 0; i < vlen; i++, v++) {
 			name = btf_name_of(d, v->name_off);
 			/* enumerators share namespace with typedef idents */
 			dup_cnt = btf_dump_name_dups(d, d->ident_names, name);
 			if (dup_cnt > 1) {
-				btf_dump_printf(d, "\n%s%s___%zu = %u,",
-						pfx(lvl + 1), name, dup_cnt,
+				btf_dump_printf(d, "\n%s%s%s___%zu = %u,",
+						pfx(lvl + 1), name_prefix, name, dup_cnt,
 						(__u32)v->val);
 			} else {
-				btf_dump_printf(d, "\n%s%s = %u,",
-						pfx(lvl + 1), name,
+				btf_dump_printf(d, "\n%s%s%s = %u,",
+						pfx(lvl + 1), name_prefix, name,
 						(__u32)v->val);
 			}
 		}
@@ -1360,6 +1364,7 @@ static const char *btf_dump_resolve_name(struct btf_dump *d, __u32 id,
 	const struct btf_type *t = btf__type_by_id(d->btf, id);
 	const char *orig_name = btf_name_of(d, t->name_off);
 	const char **cached_name = &d->cached_names[id];
+	const char *prefix = d->opts.name_prefix;
 	size_t dup_cnt;
 
 	if (t->name_off == 0)
@@ -1369,11 +1374,14 @@ static const char *btf_dump_resolve_name(struct btf_dump *d, __u32 id,
 		return *cached_name ? *cached_name : orig_name;
 
 	dup_cnt = btf_dump_name_dups(d, name_map, orig_name);
-	if (dup_cnt > 1) {
+	if (dup_cnt > 1 || prefix) {
 		const size_t max_len = 256;
 		char new_name[max_len];
 
-		snprintf(new_name, max_len, "%s___%zu", orig_name, dup_cnt);
+		if (dup_cnt > 1)
+			snprintf(new_name, max_len, "%s%s___%zu", prefix, orig_name, dup_cnt);
+		else
+			snprintf(new_name, max_len, "%s%s", prefix, orig_name);
 		*cached_name = strdup(new_name);
 	}
 
-- 
2.28.0.rc0.105.gf9edc3c819-goog


             reply	other threads:[~2020-07-22  5:43 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-07-22  5:43 Ian Rogers [this message]
2020-07-22  6:57 ` [RFC PATCH] bpftool btf: Add prefix option to dump C Andrii Nakryiko
2020-08-01  1:47   ` Ian Rogers
2020-08-01  3:47     ` Andrii Nakryiko
2020-08-06 17:58       ` Andrii Nakryiko
2020-08-06 19:42         ` Ian Rogers
2020-08-07  0:29           ` 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=20200722054314.2103880-1-irogers@google.com \
    --to=irogers@google.com \
    --cc=andriin@fb.com \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=john.fastabend@gmail.com \
    --cc=jolsa@kernel.org \
    --cc=kafai@fb.com \
    --cc=kpsingh@chromium.org \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=quentin@isovalent.com \
    --cc=sdf@google.com \
    --cc=songliubraving@fb.com \
    --cc=toke@redhat.com \
    --cc=yhs@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;
as well as URLs for NNTP newsgroup(s).