Subject: [PATCH v3] scripts: Exclude Rust CUs with pahole

Version 1.24 of pahole has the capability to exclude compilation units
(CUs) of specific languages [1] [2]. Rust, as of writing, is not
currently supported by pahole and if it's used with a build that has
BTF debugging enabled it results in malformed kernel and module
binaries [3]. So it's better for pahole to exclude Rust CUs until
support for it arrives.

Link: https://git.kernel.org/pub/scm/devel/pahole/pahole.git/commit/?id=49358dfe2aaae4e90b072332c3e324019826783f [1]
Link: https://git.kernel.org/pub/scm/devel/pahole/pahole.git/commit/?id=8ee363790b7437283c53090a85a9fec2f0b0fbc4 [2]
Link: https://github.com/Rust-for-Linux/linux/issues/735 [3]

Co-developed-by: Eric Curtin <[email protected]>
Signed-off-by: Eric Curtin <[email protected]>
Signed-off-by: Martin Rodriguez Reboredo <[email protected]>
---
V2 -> V3: Enable pahole option upon comparing with version 1.24
V1 -> V2: Removed dependency on auto.conf

init/Kconfig | 2 +-
lib/Kconfig.debug | 9 +++++++++
scripts/pahole-flags.sh | 4 ++++
3 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/init/Kconfig b/init/Kconfig
index 694f7c160c9c..360aef8d7292 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1913,7 +1913,7 @@ config RUST
depends on !MODVERSIONS
depends on !GCC_PLUGINS
depends on !RANDSTRUCT
- depends on !DEBUG_INFO_BTF
+ depends on !DEBUG_INFO_BTF || PAHOLE_HAS_LANG_EXCLUDE
select CONSTRUCTORS
help
Enables Rust support in the kernel.
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index ea4c903c9868..d473d491e709 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -364,6 +364,15 @@ config PAHOLE_HAS_BTF_TAG
btf_decl_tag) or not. Currently only clang compiler implements
these attributes, so make the config depend on CC_IS_CLANG.

+config PAHOLE_HAS_LANG_EXCLUDE
+ def_bool PAHOLE_VERSION >= 124
+ help
+ Support for the --lang_exclude flag which makes pahole exclude
+ compilation units from the supplied language. Used in Kbuild to
+ omit Rust CUs which are not supported in version 1.24 of pahole,
+ otherwise it would emit malformed kernel and module binaries when
+ using DEBUG_INFO_BTF_MODULES.
+
config DEBUG_INFO_BTF_MODULES
def_bool y
depends on DEBUG_INFO_BTF && MODULES && PAHOLE_HAS_SPLIT_BTF
diff --git a/scripts/pahole-flags.sh b/scripts/pahole-flags.sh
index 0d99ef17e4a5..1f1f1d397c39 100755
--- a/scripts/pahole-flags.sh
+++ b/scripts/pahole-flags.sh
@@ -19,5 +19,9 @@ fi
if [ "${pahole_ver}" -ge "122" ]; then
extra_paholeopt="${extra_paholeopt} -j"
fi
+if [ "${pahole_ver}" -ge "124" ]; then
+ # see PAHOLE_HAS_LANG_EXCLUDE
+ extra_paholeopt="${extra_paholeopt} --lang_exclude=rust"
+fi

echo ${extra_paholeopt}
--
2.39.0


2023-01-11 16:39:08

by Neal Gompa

[permalink] [raw]
Subject: Re: [PATCH v3] scripts: Exclude Rust CUs with pahole

On Wed, Jan 11, 2023 at 11:16 AM Eric Curtin <[email protected]> wrote:
>
> On Wed, 11 Jan 2023 at 15:34, Neal Gompa <[email protected]> wrote:
> >
> > On Wed, Jan 11, 2023 at 10:21 AM Martin Rodriguez Reboredo
> > <[email protected]> wrote:
> > >
> > > Version 1.24 of pahole has the capability to exclude compilation units
> > > (CUs) of specific languages [1] [2]. Rust, as of writing, is not
> > > currently supported by pahole and if it's used with a build that has
> > > BTF debugging enabled it results in malformed kernel and module
> > > binaries [3]. So it's better for pahole to exclude Rust CUs until
> > > support for it arrives.
> > >
> > > Link: https://git.kernel.org/pub/scm/devel/pahole/pahole.git/commit/?id=49358dfe2aaae4e90b072332c3e324019826783f [1]
> > > Link: https://git.kernel.org/pub/scm/devel/pahole/pahole.git/commit/?id=8ee363790b7437283c53090a85a9fec2f0b0fbc4 [2]
> > > Link: https://github.com/Rust-for-Linux/linux/issues/735 [3]
> > >
> > > Co-developed-by: Eric Curtin <[email protected]>
> > > Signed-off-by: Eric Curtin <[email protected]>
> > > Signed-off-by: Martin Rodriguez Reboredo <[email protected]>
> > > ---
> > > V2 -> V3: Enable pahole option upon comparing with version 1.24
> > > V1 -> V2: Removed dependency on auto.conf
> > >
> > > init/Kconfig | 2 +-
> > > lib/Kconfig.debug | 9 +++++++++
> > > scripts/pahole-flags.sh | 4 ++++
> > > 3 files changed, 14 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/init/Kconfig b/init/Kconfig
> > > index 694f7c160c9c..360aef8d7292 100644
> > > --- a/init/Kconfig
> > > +++ b/init/Kconfig
> > > @@ -1913,7 +1913,7 @@ config RUST
> > > depends on !MODVERSIONS
> > > depends on !GCC_PLUGINS
> > > depends on !RANDSTRUCT
> > > - depends on !DEBUG_INFO_BTF
> > > + depends on !DEBUG_INFO_BTF || PAHOLE_HAS_LANG_EXCLUDE
> >
> > Does the order matter here? I'd rather it prefer a fixed pahole and
> > disable BTF only if we can't use pahole properly.
>
> The order won't matter.
>

Then it looks good to me!

Reviewed-by: Neal Gompa <[email protected]>


--
真実はいつも一つ!/ Always, there's only one truth!

2023-01-16 17:54:40

by Miguel Ojeda

[permalink] [raw]
Subject: Re: [PATCH v3] scripts: Exclude Rust CUs with pahole

On Mon, Jan 16, 2023 at 5:37 PM Daniel Borkmann <[email protected]> wrote:
>
> I presume Miguel will pick this up via rust tree? (Either way, would be nice to
> also get an Ack from Arnaldo.)

I am happy to, but I think it would be great if BPF takes it whenever
you think it is a good time. And indeed, let's give time to Arnaldo to
take a look.

Cheers,
Miguel

2023-01-16 18:03:22

by Daniel Borkmann

[permalink] [raw]
Subject: Re: [PATCH v3] scripts: Exclude Rust CUs with pahole

On 1/11/23 4:20 PM, Martin Rodriguez Reboredo wrote:
> Version 1.24 of pahole has the capability to exclude compilation units
> (CUs) of specific languages [1] [2]. Rust, as of writing, is not
> currently supported by pahole and if it's used with a build that has
> BTF debugging enabled it results in malformed kernel and module
> binaries [3]. So it's better for pahole to exclude Rust CUs until
> support for it arrives.
>
> Link: https://git.kernel.org/pub/scm/devel/pahole/pahole.git/commit/?id=49358dfe2aaae4e90b072332c3e324019826783f [1]
> Link: https://git.kernel.org/pub/scm/devel/pahole/pahole.git/commit/?id=8ee363790b7437283c53090a85a9fec2f0b0fbc4 [2]
> Link: https://github.com/Rust-for-Linux/linux/issues/735 [3]
>
> Co-developed-by: Eric Curtin <[email protected]>
> Signed-off-by: Eric Curtin <[email protected]>
> Signed-off-by: Martin Rodriguez Reboredo <[email protected]>
> ---
> V2 -> V3: Enable pahole option upon comparing with version 1.24
> V1 -> V2: Removed dependency on auto.conf
>
> init/Kconfig | 2 +-
> lib/Kconfig.debug | 9 +++++++++
> scripts/pahole-flags.sh | 4 ++++
> 3 files changed, 14 insertions(+), 1 deletion(-)
>
> diff --git a/init/Kconfig b/init/Kconfig
> index 694f7c160c9c..360aef8d7292 100644
> --- a/init/Kconfig
> +++ b/init/Kconfig
> @@ -1913,7 +1913,7 @@ config RUST
> depends on !MODVERSIONS
> depends on !GCC_PLUGINS
> depends on !RANDSTRUCT
> - depends on !DEBUG_INFO_BTF
> + depends on !DEBUG_INFO_BTF || PAHOLE_HAS_LANG_EXCLUDE
> select CONSTRUCTORS
> help
> Enables Rust support in the kernel.
> diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
> index ea4c903c9868..d473d491e709 100644
> --- a/lib/Kconfig.debug
> +++ b/lib/Kconfig.debug
> @@ -364,6 +364,15 @@ config PAHOLE_HAS_BTF_TAG
> btf_decl_tag) or not. Currently only clang compiler implements
> these attributes, so make the config depend on CC_IS_CLANG.
>
> +config PAHOLE_HAS_LANG_EXCLUDE
> + def_bool PAHOLE_VERSION >= 124
> + help
> + Support for the --lang_exclude flag which makes pahole exclude
> + compilation units from the supplied language. Used in Kbuild to
> + omit Rust CUs which are not supported in version 1.24 of pahole,
> + otherwise it would emit malformed kernel and module binaries when
> + using DEBUG_INFO_BTF_MODULES.
> +
> config DEBUG_INFO_BTF_MODULES
> def_bool y
> depends on DEBUG_INFO_BTF && MODULES && PAHOLE_HAS_SPLIT_BTF
> diff --git a/scripts/pahole-flags.sh b/scripts/pahole-flags.sh
> index 0d99ef17e4a5..1f1f1d397c39 100755
> --- a/scripts/pahole-flags.sh
> +++ b/scripts/pahole-flags.sh
> @@ -19,5 +19,9 @@ fi
> if [ "${pahole_ver}" -ge "122" ]; then
> extra_paholeopt="${extra_paholeopt} -j"
> fi
> +if [ "${pahole_ver}" -ge "124" ]; then
> + # see PAHOLE_HAS_LANG_EXCLUDE
> + extra_paholeopt="${extra_paholeopt} --lang_exclude=rust"
> +fi
>
> echo ${extra_paholeopt}

I presume Miguel will pick this up via rust tree? (Either way, would be nice to
also get an Ack from Arnaldo.)

Thanks,
Daniel

2023-01-16 18:03:33

by Daniel Borkmann

[permalink] [raw]
Subject: Re: [PATCH v3] scripts: Exclude Rust CUs with pahole

On 1/16/23 5:52 PM, Miguel Ojeda wrote:
> On Mon, Jan 16, 2023 at 5:37 PM Daniel Borkmann <[email protected]> wrote:
>>
>> I presume Miguel will pick this up via rust tree? (Either way, would be nice to
>> also get an Ack from Arnaldo.)
>
> I am happy to, but I think it would be great if BPF takes it whenever
> you think it is a good time. And indeed, let's give time to Arnaldo to
> take a look.

Ok, if you could ack it for the rust bits, we can route it via bpf-next.

Thanks,
Daniel

2023-01-16 18:04:02

by Miguel Ojeda

[permalink] [raw]
Subject: Re: [PATCH v3] scripts: Exclude Rust CUs with pahole

On Mon, Jan 16, 2023 at 6:06 PM Daniel Borkmann <[email protected]> wrote:
>
> Ok, if you could ack it for the rust bits, we can route it via bpf-next.

Of course:

Acked-by: Miguel Ojeda <[email protected]>

Cheers,
Miguel

2023-01-16 19:38:20

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: Re: [PATCH v3] scripts: Exclude Rust CUs with pahole

Em Mon, Jan 16, 2023 at 05:37:08PM +0100, Daniel Borkmann escreveu:
> On 1/11/23 4:20 PM, Martin Rodriguez Reboredo wrote:
> > Version 1.24 of pahole has the capability to exclude compilation units
> > (CUs) of specific languages [1] [2]. Rust, as of writing, is not
> > currently supported by pahole and if it's used with a build that has
> > BTF debugging enabled it results in malformed kernel and module
> > binaries [3]. So it's better for pahole to exclude Rust CUs until
> > support for it arrives.
> >
> > Link: https://git.kernel.org/pub/scm/devel/pahole/pahole.git/commit/?id=49358dfe2aaae4e90b072332c3e324019826783f [1]
> > Link: https://git.kernel.org/pub/scm/devel/pahole/pahole.git/commit/?id=8ee363790b7437283c53090a85a9fec2f0b0fbc4 [2]
> > Link: https://github.com/Rust-for-Linux/linux/issues/735 [3]
> >
> > Co-developed-by: Eric Curtin <[email protected]>
> > Signed-off-by: Eric Curtin <[email protected]>
> > Signed-off-by: Martin Rodriguez Reboredo <[email protected]>
> > ---
> > V2 -> V3: Enable pahole option upon comparing with version 1.24
> > V1 -> V2: Removed dependency on auto.conf
> >
> > init/Kconfig | 2 +-
> > lib/Kconfig.debug | 9 +++++++++
> > scripts/pahole-flags.sh | 4 ++++
> > 3 files changed, 14 insertions(+), 1 deletion(-)
> >
> > diff --git a/init/Kconfig b/init/Kconfig
> > index 694f7c160c9c..360aef8d7292 100644
> > --- a/init/Kconfig
> > +++ b/init/Kconfig
> > @@ -1913,7 +1913,7 @@ config RUST
> > depends on !MODVERSIONS
> > depends on !GCC_PLUGINS
> > depends on !RANDSTRUCT
> > - depends on !DEBUG_INFO_BTF
> > + depends on !DEBUG_INFO_BTF || PAHOLE_HAS_LANG_EXCLUDE
> > select CONSTRUCTORS
> > help
> > Enables Rust support in the kernel.
> > diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
> > index ea4c903c9868..d473d491e709 100644
> > --- a/lib/Kconfig.debug
> > +++ b/lib/Kconfig.debug
> > @@ -364,6 +364,15 @@ config PAHOLE_HAS_BTF_TAG
> > btf_decl_tag) or not. Currently only clang compiler implements
> > these attributes, so make the config depend on CC_IS_CLANG.
> > +config PAHOLE_HAS_LANG_EXCLUDE
> > + def_bool PAHOLE_VERSION >= 124
> > + help
> > + Support for the --lang_exclude flag which makes pahole exclude
> > + compilation units from the supplied language. Used in Kbuild to
> > + omit Rust CUs which are not supported in version 1.24 of pahole,
> > + otherwise it would emit malformed kernel and module binaries when
> > + using DEBUG_INFO_BTF_MODULES.
> > +
> > config DEBUG_INFO_BTF_MODULES
> > def_bool y
> > depends on DEBUG_INFO_BTF && MODULES && PAHOLE_HAS_SPLIT_BTF
> > diff --git a/scripts/pahole-flags.sh b/scripts/pahole-flags.sh
> > index 0d99ef17e4a5..1f1f1d397c39 100755
> > --- a/scripts/pahole-flags.sh
> > +++ b/scripts/pahole-flags.sh
> > @@ -19,5 +19,9 @@ fi
> > if [ "${pahole_ver}" -ge "122" ]; then
> > extra_paholeopt="${extra_paholeopt} -j"
> > fi
> > +if [ "${pahole_ver}" -ge "124" ]; then
> > + # see PAHOLE_HAS_LANG_EXCLUDE
> > + extra_paholeopt="${extra_paholeopt} --lang_exclude=rust"
> > +fi
> > echo ${extra_paholeopt}
>
> I presume Miguel will pick this up via rust tree? (Either way, would be nice to
> also get an Ack from Arnaldo.)

I haven't had the time to actually go and test it from top to bottom
(which I'm about to do), but it _looks_ ok, so:

Acked-by: Arnaldo Carvalho de Melo <[email protected]>

- Arnaldo

2023-01-17 17:32:46

by patchwork-bot+netdevbpf

[permalink] [raw]
Subject: Re: [PATCH v3] scripts: Exclude Rust CUs with pahole

Hello:

This patch was applied to bpf/bpf-next.git (master)
by Daniel Borkmann <[email protected]>:

On Wed, 11 Jan 2023 12:20:50 -0300 you wrote:
> Version 1.24 of pahole has the capability to exclude compilation units
> (CUs) of specific languages [1] [2]. Rust, as of writing, is not
> currently supported by pahole and if it's used with a build that has
> BTF debugging enabled it results in malformed kernel and module
> binaries [3]. So it's better for pahole to exclude Rust CUs until
> support for it arrives.
>
> [...]

Here is the summary with links:
- [v3] scripts: Exclude Rust CUs with pahole
https://git.kernel.org/bpf/bpf-next/c/c1177979af9c

You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html


2023-02-10 20:48:46

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: [PATCH 1/1] pahole/Rust: Check that we're adding DW_TAG_member sorted by byte offset

Hi Miguel, after a long winter, I'm trying to get Rust properly
supported on pahole, please check that this specific use case is working
for you as well.

I'll go thru the others to see if they are easy (or at least restricted
to Rust CUs) as this one.

Thanks,

- Arnaldo

---

Rust may reorder struct fields and pahole assumes them to be in order,
as is the case for languages like C and C++, etc. So after having the
class member bit and byte offsets sorted out, sort Rust CU types by
offset.

Using: https://github.com/Rust-for-Linux/pahole-rust-cases/blob/main/inverted.o

Before:

$ pahole --show_private_classes ../pahole-rust-cases/inverted.o
struct S {

/* XXX 4 bytes hole, try to pack */

bool a __attribute__((__aligned__(1))); /* 4 1 */

/* XXX 65531 bytes hole, try to pack */
/* Bitfield combined with previous fields */

u32 b __attribute__((__aligned__(4))); /* 0 4 */

/* size: 8, cachelines: 1, members: 2 */
/* sum members: 5, holes: 2, sum holes: 65535 */
/* padding: 4 */
/* forced alignments: 2, forced holes: 2, sum forced holes: 65535 */
/* last cacheline: 8 bytes */

/* BRAIN FART ALERT! 8 bytes != 5 (member bytes) + 0 (member bits) + 65535 (byte holes) + 0 (bit holes), diff = -524288 bits */
} __attribute__((__aligned__(4)));
$

After:

$ readelf -wi ../pahole-rust-cases/inverted.o | grep DW_TAG_compile_unit -A9
<0><b>: Abbrev Number: 1 (DW_TAG_compile_unit)
<c> DW_AT_producer : (indirect string, offset: 0x0): clang LLVM (rustc version 1.60.0 (7737e0b5c 2022-04-04))
<10> DW_AT_language : 28 (Rust)
<12> DW_AT_name : (indirect string, offset: 0x39): inverted.rs/@/inverted.c4dda47b-cgu.0
<16> DW_AT_stmt_list : 0x0
<1a> DW_AT_comp_dir : (indirect string, offset: 0x5f): /root/pahole-rust
<1e> DW_AT_GNU_pubnames: 1
<1e> DW_AT_low_pc : 0x0
<26> DW_AT_high_pc : 0x62
<1><2a>: Abbrev Number: 2 (DW_TAG_namespace)
$ pahole --show_private_classes ../pahole-rust-cases/inverted.o
struct S {
u32 b __attribute__((__aligned__(4))); /* 0 4 */
bool a __attribute__((__aligned__(1))); /* 4 1 */

/* size: 8, cachelines: 1, members: 2 */
/* padding: 3 */
/* forced alignments: 2 */
/* last cacheline: 8 bytes */
} __attribute__((__aligned__(4)));
$

$ cp ../pahole-rust-cases/inverted.o .
$ pahole --btf_encode inverted.o
$ readelf -SW inverted.o | grep -i BTF
[26] .BTF PROGBITS 0000000000000000 000922 00006c 00 0 0 1
$
$ pahole -F btf inverted.o
struct S {
u32 b; /* 0 4 */
bool a; /* 4 1 */

/* size: 8, cachelines: 1, members: 2 */
/* padding: 3 */
/* last cacheline: 8 bytes */
};
$

Reported-by: Miguel Ojeda <[email protected]>
Cc: Alexei Starovoitov <[email protected]>
Cc: Andrii Nakryiko <[email protected]>
Cc: Eric Curtin <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: Martin Rodriguez Reboredo <[email protected]>
Cc: Neal Gompa <[email protected]>
Cc: Yonghong Song <[email protected]>
Cc: Daniel Borkmann <[email protected]>
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
dwarf_loader.c | 42 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 42 insertions(+)

diff --git a/dwarf_loader.c b/dwarf_loader.c
index 253c5efaf3b55a93..a77598dc3affca88 100644
--- a/dwarf_loader.c
+++ b/dwarf_loader.c
@@ -2835,9 +2835,51 @@ static int class_member__cache_byte_size(struct tag *tag, struct cu *cu,
return 0;
}

+static bool cu__language_reorders_offsets(const struct cu *cu)
+{
+ return cu->language == DW_LANG_Rust;
+}
+
+static int type__sort_by_offset(struct tag *tag, struct cu *cu, void *cookie __maybe_unused)
+{
+ if (!tag__is_type(tag))
+ return 0;
+
+ struct type *type = tag__type(tag);
+ struct class_member *current_member;
+
+ // There may be more than DW_TAG_members entries in the type tags, so do a simple
+ // bubble sort for now, so that the other non tags stay where they are.
+restart:
+ type__for_each_data_member(type, current_member) {
+ if (list_is_last(&current_member->tag.node, &type->namespace.tags))
+ break;
+
+ struct class_member *next_member = list_entry(current_member->tag.node.next, typeof(*current_member), tag.node);
+
+ if (current_member->byte_offset < next_member->byte_offset)
+ continue;
+
+ list_del(&current_member->tag.node);
+ list_add(&current_member->tag.node, &next_member->tag.node);
+ goto restart;
+ }
+
+ return 0;
+}
+
+static void cu__sort_types_by_offset(struct cu *cu, struct conf_load *conf)
+{
+ cu__for_all_tags(cu, type__sort_by_offset, conf);
+}
+
static int cu__finalize(struct cu *cu, struct conf_load *conf, void *thr_data)
{
cu__for_all_tags(cu, class_member__cache_byte_size, conf);
+
+ if (cu__language_reorders_offsets(cu))
+ cu__sort_types_by_offset(cu, conf);
+
if (conf && conf->steal) {
return conf->steal(cu, conf, thr_data);
}
--
2.39.1


2023-02-13 12:10:16

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: pahole issues with Rust DWARF was: Re: [PATCH 1/1] pahole/Rust: Check that we're adding DW_TAG_member sorted by byte offset

Em Fri, Feb 10, 2023 at 05:48:36PM -0300, Arnaldo Carvalho de Melo escreveu:
> I'll go thru the others to see if they are easy (or at least restricted
> to Rust CUs) as this one.

The namespace.o seems to be ok:

⬢[acme@toolbox pahole]$ cat ../pahole-rust-cases/namespace.rs
pub struct S {
pub a: i32,
}

pub static S: (i32, S) = (42, S { a: 42 });
⬢[acme@toolbox pahole]$

⬢[acme@toolbox pahole]$ pahole --show_private_classes ../pahole-rust-cases/namespace.o
struct S {
i32 a __attribute__((__aligned__(4))); /* 0 4 */

/* size: 4, cachelines: 1, members: 1 */
/* forced alignments: 1 */
/* last cacheline: 4 bytes */
} __attribute__((__aligned__(4)));
struct (i32, namespace::S) {
i32 __0 __attribute__((__aligned__(4))); /* 0 4 */
struct S __1 __attribute__((__aligned__(4))); /* 4 4 */

/* size: 8, cachelines: 1, members: 2 */
/* forced alignments: 2 */
/* last cacheline: 8 bytes */
} __attribute__((__aligned__(4)));
⬢[acme@toolbox pahole]$

And encoding/decoding BTF for it:

⬢[acme@toolbox pahole]$ cp ../pahole-rust-cases/namespace.o .
⬢[acme@toolbox pahole]$ pahole --btf_encode namespace.o
⬢[acme@toolbox pahole]$ pahole -F btf namespace.o
struct S {
i32 a; /* 0 4 */

/* size: 4, cachelines: 1, members: 1 */
/* last cacheline: 4 bytes */
};
struct (i32, namespace::S) {
i32 __0; /* 0 4 */
struct S __1; /* 4 4 */

/* size: 8, cachelines: 1, members: 2 */
/* last cacheline: 8 bytes */
};
⬢[acme@toolbox pahole]$ readelf -SW namespace.o | grep BTF
[18] .BTF PROGBITS 0000000000000000 00065c 000089 00 0 0 1
⬢[acme@toolbox pahole]$


The core one needs work:

⬢[acme@toolbox pahole]$ pahole ../pahole-rust-cases/core.o |& head
die__process_class: tag not supported 0x2f (template_type_parameter)!
die__process_class: tag not supported 0x33 (variant_part)!
die__create_new_enumeration: DW_TAG_subprogram (0x2e) @ <0x2fd8d> not handled!
die__create_new_enumeration: DW_TAG_subprogram (0x2e) @ <0x2fdf7> not handled!
die__create_new_enumeration: DW_TAG_subprogram (0x2e) @ <0x2fe61> not handled!
die__create_new_enumeration: DW_TAG_subprogram (0x2e) @ <0x2fecb> not handled!
die__create_new_enumeration: DW_TAG_subprogram (0x2e) @ <0x2ff35> not handled!
die__create_new_enumeration: DW_TAG_subprogram (0x2e) @ <0x2ff9f> not handled!
die__create_new_enumeration: DW_TAG_subprogram (0x2e) @ <0x30009> not handled!
die__create_new_enumeration: DW_TAG_subprogram (0x2e) @ <0x30073> not handled!
⬢[acme@toolbox pahole]$

<1><90>: Abbrev Number: 7 (DW_TAG_namespace)
<91> DW_AT_name : (indirect string, offset: 0x147): core
<2><95>: Abbrev Number: 7 (DW_TAG_namespace)
<96> DW_AT_name : (indirect string, offset: 0x14c): str
<3><9a>: Abbrev Number: 7 (DW_TAG_namespace)
<9b> DW_AT_name : (indirect string, offset: 0x150): iter
<4><9f>: Abbrev Number: 8 (DW_TAG_structure_type)
<a0> DW_AT_name : (indirect string, offset: 0x2e1): Split<core::str::IsWhitespace>
<a4> DW_AT_byte_size : 64
<a5> DW_AT_alignment : 8
<5><a6>: Abbrev Number: 9 (DW_TAG_template_type_param)
<a7> DW_AT_type : <0x41fc>
<ab> DW_AT_name : (indirect string, offset: 0x162): P
<5><af>: Abbrev Number: 4 (DW_TAG_member)
<b0> DW_AT_name : (indirect string, offset: 0x164): __0
<b4> DW_AT_type : <0xbb>
<b8> DW_AT_alignment : 8
<b9> DW_AT_data_member_location: 0
<5><ba>: Abbrev Number: 0
<4><bb>: Abbrev Number: 8 (DW_TAG_structure_type)
<bc> DW_AT_name : (indirect string, offset: 0x2ba): SplitInternal<core::str::IsWhitespace>
<c0> DW_AT_byte_size : 64
<c1> DW_AT_alignment : 8
<5><c2>: Abbrev Number: 9 (DW_TAG_template_type_param)
<c3> DW_AT_type : <0x41fc>
<c7> DW_AT_name : (indirect string, offset: 0x162): P

- Arnaldo

2023-02-13 12:45:42

by Miguel Ojeda

[permalink] [raw]
Subject: Re: pahole issues with Rust DWARF was: Re: [PATCH 1/1] pahole/Rust: Check that we're adding DW_TAG_member sorted by byte offset

Hi Arnaldo,

On Mon, Feb 13, 2023 at 1:09 PM Arnaldo Carvalho de Melo
<[email protected]> wrote:
>
> The namespace.o seems to be ok:

I saw the other message too -- this looks great, thanks a ton.

> The core one needs work:

If `core.o` works, then I think it is likely other things will work :)

I can try to extract the cases for those into simpler `.o` files, if
you would find simpler test cases useful (perhaps for the test suite
etc.).

Cheers,
Miguel

2023-02-13 12:54:55

by Eric Curtin

[permalink] [raw]
Subject: Re: pahole issues with Rust DWARF was: Re: [PATCH 1/1] pahole/Rust: Check that we're adding DW_TAG_member sorted by byte offset

On Mon, 13 Feb 2023 at 12:45, Miguel Ojeda
<[email protected]> wrote:
>
> Hi Arnaldo,
>
> On Mon, Feb 13, 2023 at 1:09 PM Arnaldo Carvalho de Melo
> <[email protected]> wrote:
> >
> > The namespace.o seems to be ok:
>
> I saw the other message too -- this looks great, thanks a ton.
>
> > The core one needs work:
>
> If `core.o` works, then I think it is likely other things will work :)

Hi Guys,

I'll leave this to the experts, but if we get this to the point where
we are happy to enable again for Rust CUs, could we request another
version bump? It just makes it easier to integrate with the kernel
scripts when we want to enable again.

>
> I can try to extract the cases for those into simpler `.o` files, if
> you would find simpler test cases useful (perhaps for the test suite
> etc.).
>
> Cheers,
> Miguel
>


2023-02-13 21:05:56

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: Re: pahole issues with Rust DWARF was: Re: [PATCH 1/1] pahole/Rust: Check that we're adding DW_TAG_member sorted by byte offset

Em Mon, Feb 13, 2023 at 01:45:02PM +0100, Miguel Ojeda escreveu:
> On Mon, Feb 13, 2023 at 1:09 PM Arnaldo Carvalho de Melo <[email protected]> wrote:
> > The namespace.o seems to be ok:

> I saw the other message too -- this looks great, thanks a ton.

> > The core one needs work:

> If `core.o` works, then I think it is likely other things will work :)

> I can try to extract the cases for those into simpler `.o` files, if
> you would find simpler test cases useful (perhaps for the test suite
> etc.).

That would be great!

I tried starting this path with this, spitted out by ChatGPT (minus the
'pub' in from of main):

⬢[acme@toolbox pahole-rust-cases]$ cat template_type.rs
// Provided by ChatGPT

use std::ops::Add;

// Define a generic struct template with a single type parameter `T`.
struct Point<T> {
x: T,
y: T,
}

// Implement a method for the `Point` struct that adds two points together.
// The method uses the `Add` trait to ensure that the type `T` supports addition.
impl<T: Add<Output=T>> Point<T> {
fn add_points(self, other: Point<T>) -> Point<T> {
Point {
x: self.x + other.x,
y: self.y + other.y,
}
}
}

pub fn main() {
// Create two `Point` instances, using `i32` as the type parameter.
let p1 = Point { x: 1, y: 2 };
let p2 = Point { x: 3, y: 4 };

// Add the two points together using the `add_points` method.
let p3 = p1.add_points(p2);

// Print the result.
println!("Point: ({}, {})", p3.x, p3.y);
}
⬢[acme@toolbox pahole-rust-cases]$

And then handle the DW_TAG_template_type_parameter for a
DW_TAG_subroutine:

<3><12d>: Abbrev Number: 5 (DW_TAG_structure_type)
<12e> DW_AT_name : (indirect string, offset: 0x299): ArgumentV1
<132> DW_AT_byte_size : 16
<133> DW_AT_alignment : 8
<4><134>: Abbrev Number: 6 (DW_TAG_member)
<135> DW_AT_name : (indirect string, offset: 0xd7): value
<139> DW_AT_type : <0x43a>
<13d> DW_AT_alignment : 8
<13e> DW_AT_data_member_location: 0
<4><13f>: Abbrev Number: 6 (DW_TAG_member)
<140> DW_AT_name : (indirect string, offset: 0x10e): formatter
<144> DW_AT_type : <0x447>
<148> DW_AT_alignment : 8
<149> DW_AT_data_member_location: 8
<4><14a>: Abbrev Number: 11 (DW_TAG_subprogram)
<14b> DW_AT_linkage_name: (indirect string, offset: 0x2a8): _ZN4core3fmt10ArgumentV13new17h167b8c43a2ee7614E
<14f> DW_AT_name : (indirect string, offset: 0x2d9): new<i32>
<153> DW_AT_decl_file : 2
<154> DW_AT_decl_line : 333
<156> DW_AT_type : <0x12d>
<15a> DW_AT_inline : 1 (inlined)
<5><15b>: Abbrev Number: 12 (DW_TAG_template_type_param)
<15c> DW_AT_type : <0x4e3>
<160> DW_AT_name : (indirect string, offset: 0x125): T
<5><164>: Abbrev Number: 13 (DW_TAG_variable)

I'll have to stop now, but was at the point of changing ftype__fprintf()
somehow to show that template type parameter, with the patch at the end
of this message I get this:

⬢[acme@toolbox pahole]$ pahole --show_private_classes ../pahole-rust-cases/template_type.o
die__process_class: tag not supported 0x33 (variant_part)!
die__process_class: tag not supported 0x2f (template_type_parameter)!
struct Argument {
usize position __attribute__((__aligned__(8))); /* 0 8 */
struct FormatSpec format __attribute__((__aligned__(8))); /* 8 48 */

/* XXX last struct has 7 bytes of padding */

/* size: 56, cachelines: 1, members: 2 */
/* paddings: 1, sum paddings: 7 */
/* forced alignments: 2 */
/* last cacheline: 56 bytes */
} __attribute__((__aligned__(8)));
struct FormatSpec {
struct Count precision __attribute__((__aligned__(8))); /* 0 16 */

/* XXX last struct has 16 bytes of padding */

struct Count width __attribute__((__aligned__(8))); /* 16 16 */

/* XXX last struct has 16 bytes of padding */

char fill __attribute__((__aligned__(4))); /* 32 4 */
u32 flags __attribute__((__aligned__(4))); /* 36 4 */
enum Alignment align __attribute__((__aligned__(1))); /* 40 1 */

/* size: 48, cachelines: 1, members: 5 */
/* padding: 7 */
/* paddings: 2, sum paddings: 32 */
/* forced alignments: 5 */
/* last cacheline: 48 bytes */
} __attribute__((__aligned__(8)));
struct Is {

/* XXX 8 bytes hole, try to pack */

usize __0 __attribute__((__aligned__(8))); /* 8 8 */

/* size: 16, cachelines: 1, members: 1 */
/* sum members: 8, holes: 1, sum holes: 8 */
/* forced alignments: 1, forced holes: 1, sum forced holes: 8 */
/* last cacheline: 16 bytes */
} __attribute__((__aligned__(8)));
struct Param {

/* XXX 8 bytes hole, try to pack */

usize __0 __attribute__((__aligned__(8))); /* 8 8 */

/* size: 16, cachelines: 1, members: 1 */
/* sum members: 8, holes: 1, sum holes: 8 */
/* forced alignments: 1, forced holes: 1, sum forced holes: 8 */
/* last cacheline: 16 bytes */
} __attribute__((__aligned__(8)));
struct Implied {

/* size: 16, cachelines: 1, members: 0 */
/* padding: 16 */
/* last cacheline: 16 bytes */
} __attribute__((__aligned__(8)));
struct Count {

/* size: 16, cachelines: 1, members: 0 */
/* padding: 16 */
/* last cacheline: 16 bytes */
} __attribute__((__aligned__(8)));
struct ArgumentV1 {
struct Opaque * value __attribute__((__aligned__(8))); /* 0 8 */
struct Result<(), core::fmt::Error> (*formatter)(struct Opaque *, struct Formatter *) __attribute__((__aligned__(8))); /* 8 8 */

/* size: 16, cachelines: 1, members: 2 */
/* forced alignments: 2 */
/* last cacheline: 16 bytes */
} __attribute__((__aligned__(8)));
struct Opaque {

/* size: 0, cachelines: 0, members: 0 */
} __attribute__((__aligned__(1)));
struct Error {

/* size: 0, cachelines: 0, members: 0 */
} __attribute__((__aligned__(1)));
struct Formatter {
struct Option<usize> width __attribute__((__aligned__(8))); /* 0 16 */

/* XXX last struct has 16 bytes of padding */

struct Option<usize> precision __attribute__((__aligned__(8))); /* 16 16 */

/* XXX last struct has 16 bytes of padding */

struct &mut dyn core::fmt::Write buf __attribute__((__aligned__(8))); /* 32 16 */
u32 flags __attribute__((__aligned__(4))); /* 48 4 */
char fill __attribute__((__aligned__(4))); /* 52 4 */
enum Alignment align __attribute__((__aligned__(1))); /* 56 1 */

/* size: 64, cachelines: 1, members: 6 */
/* padding: 7 */
/* paddings: 2, sum paddings: 32 */
/* forced alignments: 6 */
} __attribute__((__aligned__(8)));
struct Arguments {
struct &[&str] pieces __attribute__((__aligned__(8))); /* 0 16 */
struct Option<&[core::fmt::rt::v1::Argument]> fmt __attribute__((__aligned__(8))); /* 16 16 */

/* XXX last struct has 16 bytes of padding */

struct &[core::fmt::ArgumentV1] args __attribute__((__aligned__(8))); /* 32 16 */

/* size: 48, cachelines: 1, members: 3 */
/* paddings: 1, sum paddings: 16 */
/* forced alignments: 3 */
/* last cacheline: 48 bytes */
} __attribute__((__aligned__(8)));
struct Ok {

/* XXX 1 byte hole, try to pack */

() __0 __attribute__((__aligned__(1))); /* 1 0 */

/* size: 1, cachelines: 1, members: 1 */
/* forced alignments: 1, forced holes: 1, sum forced holes: 1 */
/* last cacheline: 1 bytes */
} __attribute__((__aligned__(1)));
struct Err {

/* XXX 1 byte hole, try to pack */

struct Error __0 __attribute__((__aligned__(1))); /* 1 0 */

/* size: 1, cachelines: 1, members: 1 */
/* forced alignments: 1, forced holes: 1, sum forced holes: 1 */
/* last cacheline: 1 bytes */
} __attribute__((__aligned__(1)));
struct Result<(), core::fmt::Error> {

/* size: 1, cachelines: 0, members: 0 */
/* padding: 1 */
/* last cacheline: 1 bytes */
} __attribute__((__aligned__(1)));
struct None {

/* size: 16, cachelines: 1, members: 0 */
/* padding: 16 */
/* last cacheline: 16 bytes */
} __attribute__((__aligned__(8)));
struct Some {

/* XXX 8 bytes hole, try to pack */

usize __0 __attribute__((__aligned__(8))); /* 8 8 */

/* size: 16, cachelines: 1, members: 1 */
/* sum members: 8, holes: 1, sum holes: 8 */
/* forced alignments: 1, forced holes: 1, sum forced holes: 8 */
/* last cacheline: 16 bytes */
} __attribute__((__aligned__(8)));
struct Option<usize> {

/* size: 16, cachelines: 1, members: 0 */
/* padding: 16 */
/* last cacheline: 16 bytes */
} __attribute__((__aligned__(8)));
struct Some {
struct &[core::fmt::rt::v1::Argument] __0 __attribute__((__aligned__(8))); /* 0 16 */

/* size: 16, cachelines: 1, members: 1 */
/* forced alignments: 1 */
/* last cacheline: 16 bytes */
} __attribute__((__aligned__(8)));
struct Option<&[core::fmt::rt::v1::Argument]> {

/* size: 16, cachelines: 1, members: 0 */
/* padding: 16 */
/* last cacheline: 16 bytes */
} __attribute__((__aligned__(8)));
struct &mut dyn core::fmt::Write {
struct dyn core::fmt::Write * pointer __attribute__((__aligned__(8))); /* 0 8 */
usize * vtable __attribute__((__aligned__(8))); /* 8 8 */

/* size: 16, cachelines: 1, members: 2 */
/* forced alignments: 2 */
/* last cacheline: 16 bytes */
} __attribute__((__aligned__(8)));
struct dyn core::fmt::Write {

/* size: 0, cachelines: 0, members: 0 */
} __attribute__((__aligned__(1)));
struct &[&str] {
struct &str * data_ptr __attribute__((__aligned__(8))); /* 0 8 */
usize length __attribute__((__aligned__(8))); /* 8 8 */

/* size: 16, cachelines: 1, members: 2 */
/* forced alignments: 2 */
/* last cacheline: 16 bytes */
} __attribute__((__aligned__(8)));
struct &str {
u8 * data_ptr __attribute__((__aligned__(8))); /* 0 8 */
usize length __attribute__((__aligned__(8))); /* 8 8 */

/* size: 16, cachelines: 1, members: 2 */
/* forced alignments: 2 */
/* last cacheline: 16 bytes */
} __attribute__((__aligned__(8)));
struct &[core::fmt::rt::v1::Argument] {
struct Argument * data_ptr __attribute__((__aligned__(8))); /* 0 8 */
usize length __attribute__((__aligned__(8))); /* 8 8 */

/* size: 16, cachelines: 1, members: 2 */
/* forced alignments: 2 */
/* last cacheline: 16 bytes */
} __attribute__((__aligned__(8)));
struct &[core::fmt::ArgumentV1] {
struct ArgumentV1 * data_ptr __attribute__((__aligned__(8))); /* 0 8 */
usize length __attribute__((__aligned__(8))); /* 8 8 */

/* size: 16, cachelines: 1, members: 2 */
/* forced alignments: 2 */
/* last cacheline: 16 bytes */
} __attribute__((__aligned__(8)));
struct Point<i32> {
i32 x __attribute__((__aligned__(4))); /* 0 4 */
i32 y __attribute__((__aligned__(4))); /* 4 4 */

/* size: 8, cachelines: 1, members: 2 */
/* forced alignments: 2 */
/* last cacheline: 8 bytes */
} __attribute__((__aligned__(4)));
⬢[acme@toolbox pahole]$

I'll cut version 1.25 with what is in the 'master' and 'next' now as
binutils 2.40 is out and emitting DW_TAG_unspecified_type, that isn't
supported by pahole 1.24 and also Alan's work on optimized functions,
etc.

- Arnaldo

diff --git a/dwarf_loader.c b/dwarf_loader.c
index a77598dc3affca88..b767bcaa9322c95a 100644
--- a/dwarf_loader.c
+++ b/dwarf_loader.c
@@ -1093,6 +1093,18 @@ static struct parameter *parameter__new(Dwarf_Die *die, struct cu *cu,
return parm;
}

+static struct template_type_parameter *template_type_parameter__new(Dwarf_Die *die, struct cu *cu, struct conf_load *conf)
+{
+ struct template_type_parameter *parm = tag__alloc(cu, sizeof(*parm));
+
+ if (parm != NULL) {
+ tag__init(&parm->tag, cu, die);
+ parm->name = attr_string(die, DW_AT_name, conf);
+ }
+
+ return parm;
+}
+
static struct inline_expansion *inline_expansion__new(Dwarf_Die *die, struct cu *cu, struct conf_load *conf)
{
struct inline_expansion *exp = tag__alloc(cu, sizeof(*exp));
@@ -1211,6 +1223,7 @@ static void ftype__init(struct ftype *ftype, Dwarf_Die *die, struct cu *cu)
#endif
tag__init(&ftype->tag, cu, die);
INIT_LIST_HEAD(&ftype->parms);
+ INIT_LIST_HEAD(&ftype->template_type_parms);
ftype->nr_parms = 0;
ftype->unspec_parms = 0;
}
@@ -1566,6 +1579,19 @@ static struct tag *die__create_new_parameter(Dwarf_Die *die,
return &parm->tag;
}

+static struct tag *die__create_new_template_type_parameter(Dwarf_Die *die, struct ftype *ftype,
+ struct cu *cu, struct conf_load *conf)
+{
+ struct template_type_parameter *parm = template_type_parameter__new(die, cu, conf);
+
+ if (parm == NULL)
+ return NULL;
+
+ ftype__add_template_type_parameter(ftype, parm);
+
+ return &parm->tag;
+}
+
static struct tag *die__create_new_label(Dwarf_Die *die,
struct lexblock *lexblock,
struct cu *cu, struct conf_load *conf)
@@ -1989,6 +2015,8 @@ static int die__process_function(Dwarf_Die *die, struct ftype *ftype,
case DW_TAG_GNU_template_template_param:
#endif
case DW_TAG_template_type_parameter:
+ tag = die__create_new_template_type_parameter(die, ftype, cu, conf);
+ break;
case DW_TAG_template_value_parameter:
/* FIXME: probably we'll have to attach this as a list of
* template parameters to use at class__fprintf time...
diff --git a/dwarves.c b/dwarves.c
index b43031c93c5cab58..6a8feccc2d45c60d 100644
--- a/dwarves.c
+++ b/dwarves.c
@@ -1391,6 +1391,12 @@ void ftype__add_parameter(struct ftype *ftype, struct parameter *parm)
list_add_tail(&parm->tag.node, &ftype->parms);
}

+void ftype__add_template_type_parameter(struct ftype *ftype, struct template_type_parameter *parm)
+{
+ ++ftype->nr_template_type_parms;
+ list_add_tail(&parm->tag.node, &ftype->template_type_parms);
+}
+
void lexblock__add_tag(struct lexblock *block, struct tag *tag)
{
list_add_tail(&tag->node, &block->tags);
diff --git a/dwarves.h b/dwarves.h
index 24a1909a60389dee..5c9952bfddaed301 100644
--- a/dwarves.h
+++ b/dwarves.h
@@ -825,13 +825,30 @@ static inline const char *parameter__name(const struct parameter *parm)
return parm->name;
}

+struct template_type_parameter {
+ struct tag tag;
+ const char *name;
+};
+
+static inline struct template_type_parameter *tag__template_type_parameter(const struct tag *tag)
+{
+ return (struct template_type_parameter *)tag;
+}
+
+static inline const char *template_type_parameter__name(const struct template_type_parameter *parm)
+{
+ return parm->name;
+}
+
/*
* tag.tag can be DW_TAG_subprogram_type or DW_TAG_subroutine_type.
*/
struct ftype {
struct tag tag;
struct list_head parms;
+ struct list_head template_type_parms;
uint16_t nr_parms;
+ uint16_t nr_template_type_parms;
uint8_t unspec_parms:1; /* just one bit is needed */
uint8_t optimized_parms:1;
uint8_t processed:1;
@@ -872,6 +889,8 @@ void ftype__delete(struct ftype *ftype);
list_for_each_entry_safe_reverse(pos, n, &(ftype)->parms, tag.node)

void ftype__add_parameter(struct ftype *ftype, struct parameter *parm);
+void ftype__add_template_type_parameter(struct ftype *ftype, struct template_type_parameter *parm);
+
size_t ftype__fprintf(const struct ftype *ftype, const struct cu *cu,
const char *name, const int inlined,
const int is_pointer, const int type_spacing, bool is_prototype,

2023-02-13 21:53:56

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: Re: pahole issues with Rust DWARF was: Re: [PATCH 1/1] pahole/Rust: Check that we're adding DW_TAG_member sorted by byte offset

Em Mon, Feb 13, 2023 at 12:53:38PM +0000, Eric Curtin escreveu:
> On Mon, 13 Feb 2023 at 12:45, Miguel Ojeda
> <[email protected]> wrote:
> >
> > Hi Arnaldo,
> >
> > On Mon, Feb 13, 2023 at 1:09 PM Arnaldo Carvalho de Melo
> > <[email protected]> wrote:
> > >
> > > The namespace.o seems to be ok:
> >
> > I saw the other message too -- this looks great, thanks a ton.
> >
> > > The core one needs work:
> >
> > If `core.o` works, then I think it is likely other things will work :)
>
> Hi Guys,
>
> I'll leave this to the experts, but if we get this to the point where
> we are happy to enable again for Rust CUs, could we request another
> version bump? It just makes it easier to integrate with the kernel

Sure, as we improve the support for encoding BTF from DWARF generated
for Rust code, and the subset that is used in the kernel is handled, we
will just adjust scripts/pahole-flags.sh to skip Rust DWARF if the
version is >= the version where excluding DWARF generated from some
languages (Rust in this case) but < the version where we're confortable
with generating BTF for Rust DWARF.

- Arnaldo

> scripts when we want to enable again.
>
> >
> > I can try to extract the cases for those into simpler `.o` files, if
> > you would find simpler test cases useful (perhaps for the test suite
> > etc.).
> >
> > Cheers,
> > Miguel
> >
>

--

- Arnaldo

2023-02-14 21:22:38

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: Re: [PATCH 1/1] pahole/Rust: Check that we're adding DW_TAG_member sorted by byte offset

Em Fri, Feb 10, 2023 at 05:48:36PM -0300, Arnaldo Carvalho de Melo escreveu:
> Hi Miguel, after a long winter, I'm trying to get Rust properly
> supported on pahole, please check that this specific use case is working
> for you as well.
>
> I'll go thru the others to see if they are easy (or at least restricted
> to Rust CUs) as this one.

I needed to add this one on top:

From 1231b6b9b4d88e0084bef4254eb1a05eb9935c99 Mon Sep 17 00:00:00 2001
From: Arnaldo Carvalho de Melo <[email protected]>
Date: Tue, 14 Feb 2023 18:13:59 -0300
Subject: [PATCH 1/1] dwarf_loader: Fix sorting of Rust structs

We may have structs with fields on the same offset, don't move anything
in that case, otherwise we get into an eternal loop, doh.

Tested with the Linux kernel built with CONFIG_RUST + all the code
examples, first Rust struct where this happened was:

(gdb) p type->namespace.name
$2 = 0x7fffda938497 "((), char)"
(gdb) p type->nr_members
$3 = 2
(gdb) p current_member->name
$4 = 0x7fffda918f36 "__1"
(gdb) p next_member->name
$5 = 0x7fffda91765c "__0"
(gdb) p current_member->byte_offset
$6 = 0
(gdb) p next_member->byte_offset
$7 = 0

But this shows that --lang_exclude should be better positioned as we're
now needlessly loading all the tags for Rust DWARF to then just trow it
away at the cu__filter() in pahole :-\

Too late in the 1.25 release cycle for that, optimize it in 1.26.

Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
dwarf_loader.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/dwarf_loader.c b/dwarf_loader.c
index a77598dc3affca88..acdb68d5dd33f148 100644
--- a/dwarf_loader.c
+++ b/dwarf_loader.c
@@ -2857,7 +2857,7 @@ restart:

struct class_member *next_member = list_entry(current_member->tag.node.next, typeof(*current_member), tag.node);

- if (current_member->byte_offset < next_member->byte_offset)
+ if (current_member->byte_offset <= next_member->byte_offset)
continue;

list_del(&current_member->tag.node);
--
2.39.1