All of lore.kernel.org
 help / color / mirror / Atom feed
From: Eduard Zingerman <eddyz87@gmail.com>
To: dwarves@vger.kernel.org, arnaldo.melo@gmail.com, alan.maguire@oracle.com
Cc: bpf@vger.kernel.org, kernel-team@fb.com, ast@kernel.org,
	daniel@iogearbox.net, andrii@kernel.org, yonghong.song@linux.dev,
	Eduard Zingerman <eddyz87@gmail.com>,
	Arnaldo Carvalho de Melo <acme@kernel.org>
Subject: [PATCH dwarves v1 1/2] btf_loader: support for multiple BTF_DECL_TAGs pointing to same tag
Date: Tue, 10 Dec 2024 18:12:26 -0800	[thread overview]
Message-ID: <20241211021227.2341735-1-eddyz87@gmail.com> (raw)

btf_loader issues a warning when it sees several BTF_DECL_TAGs
pointing to the same type. Such situation is possible in practice
after patch [0], that marks certain functions with kfunc and
bpf_fastcall tags. E.g.:

  $ pfunct vmlinux -F btf -f bpf_rdonly_cast
WARNING: still unsuported BTF_KIND_DECL_TAG(bpf_fastcall) for bpf_cast_to_kern_ctx already with attribute (bpf_kfunc), ignoring
WARNING: still unsuported BTF_KIND_DECL_TAG(bpf_fastcall) for bpf_rdonly_cast already with attribute (bpf_kfunc), ignoring
  bpf_kfunc void * bpf_rdonly_cast(const void  * obj__ign, u32 btf_id__k);

This commit extends 'struct tag' to allow attaching multiple
attributes. Define 'struct attributes' as follows:

  struct attributes {
        uint64_t cnt;
        const char *values[];
  };

In order to avoid adding counter field in 'struct tag',
as not many instances of 'struct tag' would have attributes.

Same command after this patch:

  $ pfunct vmlinux -F btf -f bpf_rdonly_cast
  bpf_kfunc bpf_fastcall void * bpf_rdonly_cast(const void  * obj__ign, u32 btf_id__k);

[0] https://lore.kernel.org/dwarves/094b626d44e817240ae8e44b6f7933b13c26d879.camel@gmail.com/T/#m8a6cb49a99d1b2ba38d616495a540ae8fc5f3a76

Reported-by: Arnaldo Carvalho de Melo <acme@kernel.org>
Closes: https://lore.kernel.org/dwarves/Z1dFXVFYmQ-nHSVO@x1/
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
---
 btf_loader.c           | 31 +++++++++++++++++++++++--------
 dwarf_loader.c         |  2 +-
 dwarves.c              |  3 +++
 dwarves.h              |  8 +++++++-
 dwarves_fprintf.c      |  6 ++++--
 tests/btf_functions.sh |  2 +-
 6 files changed, 39 insertions(+), 13 deletions(-)

diff --git a/btf_loader.c b/btf_loader.c
index 4814f29..af9e1db 100644
--- a/btf_loader.c
+++ b/btf_loader.c
@@ -459,9 +459,28 @@ static int create_new_tag(struct cu *cu, int type, const struct btf_type *tp, ui
 	return 0;
 }
 
+static struct attributes *attributes__realloc(struct attributes *attributes, const char *value)
+{
+	struct attributes *result;
+	uint64_t cnt;
+	size_t sz;
+
+	cnt = attributes ? attributes->cnt : 0;
+	sz = sizeof(*attributes) + (cnt + 1) * sizeof(*attributes->values);
+	result = realloc(attributes, sz);
+	if (!result)
+		return NULL;
+	if (!attributes)
+		result->cnt = 0;
+	result->values[cnt] = value;
+	result->cnt++;
+	return result;
+}
+
 static int process_decl_tag(struct cu *cu, const struct btf_type *tp)
 {
 	struct tag *tag = cu__type(cu, tp->type);
+	struct attributes *tmp;
 
 	if (tag == NULL)
 		tag = cu__function(cu, tp->type);
@@ -475,15 +494,11 @@ static int process_decl_tag(struct cu *cu, const struct btf_type *tp)
 	}
 
 	const char *attribute = cu__btf_str(cu, tp->name_off);
+	tmp = attributes__realloc(tag->attributes, attribute);
+	if (!tmp)
+		return -ENOMEM;
 
-	if (tag->attribute != NULL) {
-		char bf[128];
-
-		fprintf(stderr, "WARNING: still unsuported BTF_KIND_DECL_TAG(%s) for %s already with attribute (%s), ignoring\n",
-		       attribute, tag__name(tag, cu, bf, sizeof(bf), NULL), tag->attribute);
-	} else {
-		tag->attribute = attribute;
-	}
+	tag->attributes = tmp;
 
 	return 0;
 }
diff --git a/dwarf_loader.c b/dwarf_loader.c
index 598fde4..34376b2 100644
--- a/dwarf_loader.c
+++ b/dwarf_loader.c
@@ -513,7 +513,7 @@ static void tag__init(struct tag *tag, struct cu *cu, Dwarf_Die *die)
 
 	dwarf_tag__set_attr_type(dtag, abstract_origin, die, DW_AT_abstract_origin);
 	tag->recursivity_level = 0;
-	tag->attribute = NULL;
+	tag->attributes = NULL;
 
 	if (cu->extra_dbg_info) {
 		pthread_mutex_lock(&libdw__lock);
diff --git a/dwarves.c b/dwarves.c
index ae512b9..f970dd2 100644
--- a/dwarves.c
+++ b/dwarves.c
@@ -210,6 +210,9 @@ void tag__delete(struct tag *tag, struct cu *cu)
 
 	assert(list_empty(&tag->node));
 
+	if (tag->attributes)
+		free(tag->attributes);
+
 	switch (tag->tag) {
 	case DW_TAG_union_type:
 		type__delete(tag__type(tag), cu);		break;
diff --git a/dwarves.h b/dwarves.h
index 1cb0d62..0a4d5a2 100644
--- a/dwarves.h
+++ b/dwarves.h
@@ -516,10 +516,16 @@ int cu__for_all_tags(struct cu *cu,
 				     struct cu *cu, void *cookie),
 		     void *cookie);
 
+struct attributes {
+	uint64_t cnt;
+	const char *values[];
+};
+
 /** struct tag - basic representation of a debug info element
  * @priv - extra data, for instance, DWARF offset, id, decl_{file,line}
  * @top_level -
  * @shared_tags: used by struct namespace
+ * @attributes - attributes specified by BTF_DECL_TAGs targeting this tag
  */
 struct tag {
 	struct list_head node;
@@ -530,7 +536,7 @@ struct tag {
 	bool		 has_btf_type_tag:1;
 	bool		 shared_tags:1;
 	uint8_t		 recursivity_level;
-	const char	 *attribute;
+	struct attributes *attributes;
 };
 
 // To use with things like type->type_enum == perf_event_type+perf_user_event_type
diff --git a/dwarves_fprintf.c b/dwarves_fprintf.c
index e16a6b4..c3e7f3c 100644
--- a/dwarves_fprintf.c
+++ b/dwarves_fprintf.c
@@ -1405,9 +1405,11 @@ static size_t function__fprintf(const struct tag *tag, const struct cu *cu,
 	struct ftype *ftype = func->btf ? tag__ftype(cu__type(cu, func->proto.tag.type)) : &func->proto;
 	size_t printed = 0;
 	bool inlined = !conf->strip_inline && function__declared_inline(func);
+	int i;
 
-	if (tag->attribute)
-		printed += fprintf(fp, "%s ", tag->attribute);
+	if (tag->attributes)
+		for (i = 0; i < tag->attributes->cnt; ++i)
+			printed += fprintf(fp, "%s ", tag->attributes->values[i]);
 
 	if (func->virtuality == DW_VIRTUALITY_virtual ||
 	    func->virtuality == DW_VIRTUALITY_pure_virtual)
diff --git a/tests/btf_functions.sh b/tests/btf_functions.sh
index 61f8a00..c92e5ae 100755
--- a/tests/btf_functions.sh
+++ b/tests/btf_functions.sh
@@ -66,7 +66,7 @@ pfunct --all --no_parm_names --format_path=dwarf $vmlinux | \
 	sort|uniq > $outdir/dwarf.funcs
 # all functions from BTF (removing bpf_kfunc prefix where found)
 pfunct --all --no_parm_names --format_path=btf $outdir/vmlinux.btf 2>/dev/null|\
-	awk '{ gsub("^bpf_kfunc ",""); print $0}'|sort|uniq > $outdir/btf.funcs
+	awk '{ gsub("^(bpf_kfunc |bpf_fastcall )+",""); print $0}'|sort|uniq > $outdir/btf.funcs
 
 exact=0
 inline=0
-- 
2.47.0


             reply	other threads:[~2024-12-11  2:12 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-12-11  2:12 Eduard Zingerman [this message]
2024-12-11  2:12 ` [PATCH dwarves v1 2/2] tests: verify that pfunct prints btf_decl_tags read from BTF Eduard Zingerman
2024-12-12 19:50   ` Alan Maguire
2024-12-12 19:54     ` Eduard Zingerman
2024-12-26 21:11     ` Arnaldo Carvalho de Melo
2024-12-26 21:14       ` Arnaldo Carvalho de Melo
2024-12-26 21:19         ` Arnaldo Carvalho de Melo
2025-01-03  1:18         ` Eduard Zingerman
2024-12-12 20:29 ` [PATCH dwarves v1 1/2] btf_loader: support for multiple BTF_DECL_TAGs pointing to same tag Alan Maguire
2024-12-12 20:36   ` Eduard Zingerman

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=20241211021227.2341735-1-eddyz87@gmail.com \
    --to=eddyz87@gmail.com \
    --cc=acme@kernel.org \
    --cc=alan.maguire@oracle.com \
    --cc=andrii@kernel.org \
    --cc=arnaldo.melo@gmail.com \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=dwarves@vger.kernel.org \
    --cc=kernel-team@fb.com \
    --cc=yonghong.song@linux.dev \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.