public inbox for dwarves@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH dwarves v1 1/2] btf_loader: support for multiple BTF_DECL_TAGs pointing to same tag
@ 2024-12-11  2:12 Eduard Zingerman
  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 20:29 ` [PATCH dwarves v1 1/2] btf_loader: support for multiple BTF_DECL_TAGs pointing to same tag Alan Maguire
  0 siblings, 2 replies; 10+ messages in thread
From: Eduard Zingerman @ 2024-12-11  2:12 UTC (permalink / raw)
  To: dwarves, arnaldo.melo, alan.maguire
  Cc: bpf, kernel-team, ast, daniel, andrii, yonghong.song,
	Eduard Zingerman, Arnaldo Carvalho de Melo

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


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH dwarves v1 2/2] tests: verify that pfunct prints btf_decl_tags read from BTF
  2024-12-11  2:12 [PATCH dwarves v1 1/2] btf_loader: support for multiple BTF_DECL_TAGs pointing to same tag Eduard Zingerman
@ 2024-12-11  2:12 ` Eduard Zingerman
  2024-12-12 19:50   ` Alan Maguire
  2024-12-12 20:29 ` [PATCH dwarves v1 1/2] btf_loader: support for multiple BTF_DECL_TAGs pointing to same tag Alan Maguire
  1 sibling, 1 reply; 10+ messages in thread
From: Eduard Zingerman @ 2024-12-11  2:12 UTC (permalink / raw)
  To: dwarves, arnaldo.melo, alan.maguire
  Cc: bpf, kernel-team, ast, daniel, andrii, yonghong.song,
	Eduard Zingerman

When using BTF as a source, pfunct should now be able to print
btf_decl_tags for programs like below:

  #define __tag(x) __attribute__((btf_decl_tag(#x)))
  __tag(a) __tag(b) void foo(void) {}

This situation arises after recent kernel changes, where tags 'kfunc'
and 'bpf_fastcall' are added to some functions. To avoid dependency on
a recent kernel version test this by compiling a small C program using
clang with --target=bpf, which would instruct clang to generate .BTF
section.

Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
---
 tests/pfunct-btf-decl-tags.sh | 65 +++++++++++++++++++++++++++++++++++
 1 file changed, 65 insertions(+)
 create mode 100755 tests/pfunct-btf-decl-tags.sh

diff --git a/tests/pfunct-btf-decl-tags.sh b/tests/pfunct-btf-decl-tags.sh
new file mode 100755
index 0000000..7e7f547
--- /dev/null
+++ b/tests/pfunct-btf-decl-tags.sh
@@ -0,0 +1,65 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0-only
+
+# Check that pfunct can print btf_decl_tags read from BTF
+
+tmpobj=$(mktemp /tmp/pfunct-btf-decl-tags.sh.XXXXXX.o)
+
+cleanup()
+{
+	rm $tmpobj
+}
+
+trap cleanup EXIT
+
+CLANG=${CLANG:-clang}
+if ! command -v $CLANG > /dev/null; then
+	echo "Need clang for test $0"
+	exit 1
+fi
+
+(cat <<EOF
+#define __tag(x) __attribute__((btf_decl_tag(#x)))
+
+__tag(a) __tag(b) __tag(c) void foo(void) {}
+__tag(a) __tag(b)          void bar(void) {}
+__tag(a)                   void buz(void) {}
+
+EOF
+) | $CLANG --target=bpf -c -g -x c -o $tmpobj -
+
+# tags order is not guaranteed
+sort_tags=$(cat <<EOF
+{
+match(\$0,/^(.*) (void .*)/,tags_and_proto);
+tags  = tags_and_proto[1];
+proto = tags_and_proto[2];
+split(tags, tags_arr ,/ /);
+asort(tags_arr);
+for (t in tags_arr) printf "%s ", tags_arr[t];
+print proto;
+}
+EOF
+)
+
+expected=$(cat <<EOF
+a b c void foo(void);
+a b void bar(void);
+a void buz(void);
+EOF
+)
+
+out=$(pfunct -P -F btf $tmpobj | awk "$sort_tags" | sort)
+d=$(diff -u <(echo "$expected") <(echo "$out"))
+
+if [[ "$d" == "" ]]; then
+	echo "Ok"
+	exit 0
+else
+	echo "pfunct output does not match expected:"
+	echo "$d"
+	echo
+	echo "Complete output:"
+	echo "$out"
+	exit 1
+fi
-- 
2.47.0


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH dwarves v1 2/2] tests: verify that pfunct prints btf_decl_tags read from BTF
  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
  0 siblings, 2 replies; 10+ messages in thread
From: Alan Maguire @ 2024-12-12 19:50 UTC (permalink / raw)
  To: Eduard Zingerman, dwarves, arnaldo.melo
  Cc: bpf, kernel-team, ast, daniel, andrii, yonghong.song

On 11/12/2024 02:12, Eduard Zingerman wrote:
> When using BTF as a source, pfunct should now be able to print
> btf_decl_tags for programs like below:
> 
>   #define __tag(x) __attribute__((btf_decl_tag(#x)))
>   __tag(a) __tag(b) void foo(void) {}
> 
> This situation arises after recent kernel changes, where tags 'kfunc'
> and 'bpf_fastcall' are added to some functions. To avoid dependency on
> a recent kernel version test this by compiling a small C program using
> clang with --target=bpf, which would instruct clang to generate .BTF
> section.
> 
> Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>

nit: the test is great but it would be good to print out a description
even in non-verbose mode; when I run it via ./tests I see

  5: Ok

could we just echo the comment below, i.e.

5 : Check that pfunct can print btf_decl_tags read from BTF: Ok

?

Reviewed-by: Alan Maguire <alan.maguire@oracle.com>
Tested-by: Alan Maguire <alan.maguire@oracle.com>

> ---
>  tests/pfunct-btf-decl-tags.sh | 65 +++++++++++++++++++++++++++++++++++
>  1 file changed, 65 insertions(+)
>  create mode 100755 tests/pfunct-btf-decl-tags.sh
> 
> diff --git a/tests/pfunct-btf-decl-tags.sh b/tests/pfunct-btf-decl-tags.sh
> new file mode 100755
> index 0000000..7e7f547
> --- /dev/null
> +++ b/tests/pfunct-btf-decl-tags.sh
> @@ -0,0 +1,65 @@
> +#!/bin/bash
> +# SPDX-License-Identifier: GPL-2.0-only
> +
> +# Check that pfunct can print btf_decl_tags read from BTF
> +
> +tmpobj=$(mktemp /tmp/pfunct-btf-decl-tags.sh.XXXXXX.o)
> +
> +cleanup()
> +{
> +	rm $tmpobj
> +}
> +
> +trap cleanup EXIT
> +
> +CLANG=${CLANG:-clang}
> +if ! command -v $CLANG > /dev/null; then
> +	echo "Need clang for test $0"
> +	exit 1
> +fi
> +
> +(cat <<EOF
> +#define __tag(x) __attribute__((btf_decl_tag(#x)))
> +
> +__tag(a) __tag(b) __tag(c) void foo(void) {}
> +__tag(a) __tag(b)          void bar(void) {}
> +__tag(a)                   void buz(void) {}
> +
> +EOF
> +) | $CLANG --target=bpf -c -g -x c -o $tmpobj -
> +
> +# tags order is not guaranteed
> +sort_tags=$(cat <<EOF
> +{
> +match(\$0,/^(.*) (void .*)/,tags_and_proto);
> +tags  = tags_and_proto[1];
> +proto = tags_and_proto[2];
> +split(tags, tags_arr ,/ /);
> +asort(tags_arr);
> +for (t in tags_arr) printf "%s ", tags_arr[t];
> +print proto;
> +}
> +EOF
> +)
> +
> +expected=$(cat <<EOF
> +a b c void foo(void);
> +a b void bar(void);
> +a void buz(void);
> +EOF
> +)
> +
> +out=$(pfunct -P -F btf $tmpobj | awk "$sort_tags" | sort)
> +d=$(diff -u <(echo "$expected") <(echo "$out"))
> +
> +if [[ "$d" == "" ]]; then
> +	echo "Ok"
> +	exit 0
> +else
> +	echo "pfunct output does not match expected:"
> +	echo "$d"
> +	echo
> +	echo "Complete output:"
> +	echo "$out"
> +	exit 1
> +fi


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH dwarves v1 2/2] tests: verify that pfunct prints btf_decl_tags read from BTF
  2024-12-12 19:50   ` Alan Maguire
@ 2024-12-12 19:54     ` Eduard Zingerman
  2024-12-26 21:11     ` Arnaldo Carvalho de Melo
  1 sibling, 0 replies; 10+ messages in thread
From: Eduard Zingerman @ 2024-12-12 19:54 UTC (permalink / raw)
  To: Alan Maguire, dwarves, arnaldo.melo
  Cc: bpf, kernel-team, ast, daniel, andrii, yonghong.song

On Thu, 2024-12-12 at 19:50 +0000, Alan Maguire wrote:
> On 11/12/2024 02:12, Eduard Zingerman wrote:
> > When using BTF as a source, pfunct should now be able to print
> > btf_decl_tags for programs like below:
> > 
> >   #define __tag(x) __attribute__((btf_decl_tag(#x)))
> >   __tag(a) __tag(b) void foo(void) {}
> > 
> > This situation arises after recent kernel changes, where tags 'kfunc'
> > and 'bpf_fastcall' are added to some functions. To avoid dependency on
> > a recent kernel version test this by compiling a small C program using
> > clang with --target=bpf, which would instruct clang to generate .BTF
> > section.
> > 
> > Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
> 
> nit: the test is great but it would be good to print out a description
> even in non-verbose mode; when I run it via ./tests I see
> 
>   5: Ok
> 
> could we just echo the comment below, i.e.
> 
> 5 : Check that pfunct can print btf_decl_tags read from BTF: Ok
> 
> ?
> 
> Reviewed-by: Alan Maguire <alan.maguire@oracle.com>
> Tested-by: Alan Maguire <alan.maguire@oracle.com>

Makes sense, will change.
Will wait a bit and resend v2 in the evening.
Thank you.

[...]


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH dwarves v1 1/2] btf_loader: support for multiple BTF_DECL_TAGs pointing to same tag
  2024-12-11  2:12 [PATCH dwarves v1 1/2] btf_loader: support for multiple BTF_DECL_TAGs pointing to same tag Eduard Zingerman
  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 20:29 ` Alan Maguire
  2024-12-12 20:36   ` Eduard Zingerman
  1 sibling, 1 reply; 10+ messages in thread
From: Alan Maguire @ 2024-12-12 20:29 UTC (permalink / raw)
  To: Eduard Zingerman, dwarves, arnaldo.melo
  Cc: bpf, kernel-team, ast, daniel, andrii, yonghong.song,
	Arnaldo Carvalho de Melo

On 11/12/2024 02:12, Eduard Zingerman wrote:
> 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>

Looks good to me. I _think_ we're safe enough in assuming the tag
ordering "bpf_kfunc bpf_fastcall" in the btf_functions.sh test, right?

Reviewed-by: Alan Maguire <alan.maguire@oracle.com>
Tested-by: Alan Maguire <alan.maguire@oracle.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


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH dwarves v1 1/2] btf_loader: support for multiple BTF_DECL_TAGs pointing to same tag
  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
  0 siblings, 0 replies; 10+ messages in thread
From: Eduard Zingerman @ 2024-12-12 20:36 UTC (permalink / raw)
  To: Alan Maguire, dwarves, arnaldo.melo
  Cc: bpf, kernel-team, ast, daniel, andrii, yonghong.song,
	Arnaldo Carvalho de Melo

On Thu, 2024-12-12 at 20:29 +0000, Alan Maguire wrote:

[...]

> Looks good to me. I _think_ we're safe enough in assuming the tag
> ordering "bpf_kfunc bpf_fastcall" in the btf_functions.sh test, right?

For "bpf_kfunc bpf_fastcall" yes, we should be safe.
On the other hand, I don't think the below could be simplified with
this knowledge:

+	awk '{ gsub("^(bpf_kfunc |bpf_fastcall )+",""); print $0}'|sort|uniq

Because there are situations when only "bpf_kfunc" is present
and when both "bpf_kfunc", "bpf_fastcall" are present.

[...]


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH dwarves v1 2/2] tests: verify that pfunct prints btf_decl_tags read from BTF
  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
  1 sibling, 1 reply; 10+ messages in thread
From: Arnaldo Carvalho de Melo @ 2024-12-26 21:11 UTC (permalink / raw)
  To: Alan Maguire
  Cc: Eduard Zingerman, dwarves, arnaldo.melo, bpf, kernel-team, ast,
	daniel, andrii, yonghong.song

On Thu, Dec 12, 2024 at 07:50:57PM +0000, Alan Maguire wrote:
> On 11/12/2024 02:12, Eduard Zingerman wrote:
> > When using BTF as a source, pfunct should now be able to print
> > btf_decl_tags for programs like below:
> > 
> >   #define __tag(x) __attribute__((btf_decl_tag(#x)))
> >   __tag(a) __tag(b) void foo(void) {}
> > 
> > This situation arises after recent kernel changes, where tags 'kfunc'
> > and 'bpf_fastcall' are added to some functions. To avoid dependency on
> > a recent kernel version test this by compiling a small C program using
> > clang with --target=bpf, which would instruct clang to generate .BTF
> > section.
> > 
> > Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
> 
> nit: the test is great but it would be good to print out a description
> even in non-verbose mode; when I run it via ./tests I see
> 
>   5: Ok
> 
> could we just echo the comment below, i.e.
> 
> 5 : Check that pfunct can print btf_decl_tags read from BTF: Ok
> 
> ?
> 
> Reviewed-by: Alan Maguire <alan.maguire@oracle.com>
> Tested-by: Alan Maguire <alan.maguire@oracle.com>

Thanks, applied.

- Arnaldo


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH dwarves v1 2/2] tests: verify that pfunct prints btf_decl_tags read from BTF
  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
  0 siblings, 2 replies; 10+ messages in thread
From: Arnaldo Carvalho de Melo @ 2024-12-26 21:14 UTC (permalink / raw)
  To: Alan Maguire
  Cc: Eduard Zingerman, dwarves, arnaldo.melo, bpf, kernel-team, ast,
	daniel, andrii, yonghong.song

On Thu, Dec 26, 2024 at 06:11:57PM -0300, Arnaldo Carvalho de Melo wrote:
> On Thu, Dec 12, 2024 at 07:50:57PM +0000, Alan Maguire wrote:
> > On 11/12/2024 02:12, Eduard Zingerman wrote:
> > > When using BTF as a source, pfunct should now be able to print
> > > btf_decl_tags for programs like below:
> > > 
> > >   #define __tag(x) __attribute__((btf_decl_tag(#x)))
> > >   __tag(a) __tag(b) void foo(void) {}
> > > 
> > > This situation arises after recent kernel changes, where tags 'kfunc'
> > > and 'bpf_fastcall' are added to some functions. To avoid dependency on
> > > a recent kernel version test this by compiling a small C program using
> > > clang with --target=bpf, which would instruct clang to generate .BTF
> > > section.
> > > 
> > > Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
> > 
> > nit: the test is great but it would be good to print out a description
> > even in non-verbose mode; when I run it via ./tests I see
> > 
> >   5: Ok
> > 
> > could we just echo the comment below, i.e.
> > 
> > 5 : Check that pfunct can print btf_decl_tags read from BTF: Ok
> > 
> > ?

To clarify, I'm doing as Alan suggests and adding that message when the
test succeeds.
 
> > Reviewed-by: Alan Maguire <alan.maguire@oracle.com>
> > Tested-by: Alan Maguire <alan.maguire@oracle.com>
> 
> Thanks, applied.
> 
> - Arnaldo
> 

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH dwarves v1 2/2] tests: verify that pfunct prints btf_decl_tags read from BTF
  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
  1 sibling, 0 replies; 10+ messages in thread
From: Arnaldo Carvalho de Melo @ 2024-12-26 21:19 UTC (permalink / raw)
  To: Alan Maguire
  Cc: Eduard Zingerman, dwarves, arnaldo.melo, bpf, kernel-team, ast,
	daniel, andrii, yonghong.song

On Thu, Dec 26, 2024 at 06:14:12PM -0300, Arnaldo Carvalho de Melo wrote:
> On Thu, Dec 26, 2024 at 06:11:57PM -0300, Arnaldo Carvalho de Melo wrote:
> > On Thu, Dec 12, 2024 at 07:50:57PM +0000, Alan Maguire wrote:
> > > On 11/12/2024 02:12, Eduard Zingerman wrote:
> > > > When using BTF as a source, pfunct should now be able to print
> > > > btf_decl_tags for programs like below:
> > > > 
> > > >   #define __tag(x) __attribute__((btf_decl_tag(#x)))
> > > >   __tag(a) __tag(b) void foo(void) {}
> > > > 
> > > > This situation arises after recent kernel changes, where tags 'kfunc'
> > > > and 'bpf_fastcall' are added to some functions. To avoid dependency on
> > > > a recent kernel version test this by compiling a small C program using
> > > > clang with --target=bpf, which would instruct clang to generate .BTF
> > > > section.
> > > > 
> > > > Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
> > > 
> > > nit: the test is great but it would be good to print out a description
> > > even in non-verbose mode; when I run it via ./tests I see
> > > 
> > >   5: Ok
> > > 
> > > could we just echo the comment below, i.e.
> > > 
> > > 5 : Check that pfunct can print btf_decl_tags read from BTF: Ok
> > > 
> > > ?
> 
> To clarify, I'm doing as Alan suggests and adding that message when the
> test succeeds.

Running just this test:

root@number:/home/acme/git/pahole# tests/pfunct-btf-decl-tags.sh
Check that pfunct can print btf_decl_tags read from BTF: Ok
root@number:/home/acme/git/pahole#
  
> > > Reviewed-by: Alan Maguire <alan.maguire@oracle.com>
> > > Tested-by: Alan Maguire <alan.maguire@oracle.com>
> > 
> > Thanks, applied.
> > 
> > - Arnaldo
> > 

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH dwarves v1 2/2] tests: verify that pfunct prints btf_decl_tags read from BTF
  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
  1 sibling, 0 replies; 10+ messages in thread
From: Eduard Zingerman @ 2025-01-03  1:18 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo, Alan Maguire
  Cc: dwarves, arnaldo.melo, bpf, kernel-team, ast, daniel, andrii,
	yonghong.song

On Thu, 2024-12-26 at 18:14 -0300, Arnaldo Carvalho de Melo wrote:
> On Thu, Dec 26, 2024 at 06:11:57PM -0300, Arnaldo Carvalho de Melo wrote:
> > On Thu, Dec 12, 2024 at 07:50:57PM +0000, Alan Maguire wrote:
> > > On 11/12/2024 02:12, Eduard Zingerman wrote:
> > > > When using BTF as a source, pfunct should now be able to print
> > > > btf_decl_tags for programs like below:
> > > > 
> > > >   #define __tag(x) __attribute__((btf_decl_tag(#x)))
> > > >   __tag(a) __tag(b) void foo(void) {}
> > > > 
> > > > This situation arises after recent kernel changes, where tags 'kfunc'
> > > > and 'bpf_fastcall' are added to some functions. To avoid dependency on
> > > > a recent kernel version test this by compiling a small C program using
> > > > clang with --target=bpf, which would instruct clang to generate .BTF
> > > > section.
> > > > 
> > > > Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
> > > 
> > > nit: the test is great but it would be good to print out a description
> > > even in non-verbose mode; when I run it via ./tests I see
> > > 
> > >   5: Ok
> > > 
> > > could we just echo the comment below, i.e.
> > > 
> > > 5 : Check that pfunct can print btf_decl_tags read from BTF: Ok
> > > 
> > > ?
> 
> To clarify, I'm doing as Alan suggests and adding that message when the
> test succeeds.

Sure, thank you.
Sorry, I should have reposted v2 with this small change.


^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2025-01-03  1:18 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-12-11  2:12 [PATCH dwarves v1 1/2] btf_loader: support for multiple BTF_DECL_TAGs pointing to same tag Eduard Zingerman
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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox