Re: [PATCH 2/3] dwarf_loader: Initial support for DW_TAG_subprogram in DW_TAG_enumeration

Arnaldo Carvalho de Melo
2026-03-30T22:39:48Z

On Mon, Mar 30, 2026 at 10:05:26AM +0100, Alan Maguire wrote:
> On 23/03/2026 21:15, Arnaldo Carvalho de Melo wrote:
> > In Rust enums can have subprograms, add initial support for it.

> I guess we'd need some form of enhanced enumerator kind to support this in BTF,
> since I don't see any means to enhance the existing enumerator kind info to
> support references to other type ids like functions.

Right, the internal representation for the DWARF tags should cover all
languages aspects, be it Rust, C, C++, Go, etc.

But BTF is about being compact, so no forward thinking about supporting
other languages, Like Rust, that is for DWARF, that ends up being not
compact.

I think the best we can do at this point is to support as many aspects
of Rust as can be encoded in BTF and that may end up being enough for a
subset of Rust to be used to generate BTF bytecode CO-RE able.

I'll do some more work on checking how much of Rust we can encode in BTF
as it is possible right now.

Also I want to have a way to output rust code from DWARF/BTF/whatever,
as we have now for C and C++ in pahole :-)

- Arnaldo

> > Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
>
> Reviewed-by: Alan Maguire <alan.maguire@oracle.com>
>
> > ---
> > dwarf_loader.c | 38 ++++++++++++++++++++++++++++++--------
> > 1 file changed, 30 insertions(+), 8 deletions(-)
> >
> > diff --git a/dwarf_loader.c b/dwarf_loader.c
> > index f0833e8c44a944a8..b5a92160ecf82f74 100644
> > --- a/dwarf_loader.c
> > +++ b/dwarf_loader.c
> > @@ -1943,6 +1943,8 @@ out_delete:
> > return NULL;
> > }
> >
> > +static struct tag *die__create_new_function(Dwarf_Die *die, struct cu *cu, struct conf_load *conf);
> > +
> > static struct tag *die__create_new_enumeration(Dwarf_Die *die, struct cu *cu, struct conf_load *conf)
> > {
> > Dwarf_Die child;
> > @@ -1964,18 +1966,38 @@ static struct tag *die__create_new_enumeration(Dwarf_Die *die, struct cu *cu, st
> >
> > die = &child;
> > do {
> > - struct enumerator *enumerator;
> > + switch (dwarf_tag(die)) {
> > + case DW_TAG_enumerator: {
> > + struct enumerator *enumerator = enumerator__new(die, cu, conf);
> > +
> > + if (enumerator == NULL)
> > + goto out_delete;
> > +
> > + enumeration__add(enumeration, enumerator);
> > + cu__hash(cu, &enumerator->tag);
> > + }
> > + continue;
> > + case DW_TAG_subprogram: {
> > + struct tag *tag = die__create_new_function(die, cu, conf);
> > + uint32_t id;
> > +
> > + if (tag == NULL)
> > + goto out_delete;
> >
> > - if (dwarf_tag(die) != DW_TAG_enumerator) {
> > + if (cu__add_tag(cu, tag, &id) < 0) {
> > + tag__delete(tag, cu);
> > + goto out_delete;
> > + }
> > +
> > + cu__hash(cu, tag);
> > + struct dwarf_tag *dtag = tag__dwarf(tag);
> > + dtag->small_id = id;
> > + break;
> > + }
> > + default:
> > cu__tag_not_handled(cu, die);
> > continue;
> > }
> > - enumerator = enumerator__new(die, cu, conf);
> > - if (enumerator == NULL)
> > - goto out_delete;
> > -
> > - enumeration__add(enumeration, enumerator);
> > - cu__hash(cu, &enumerator->tag);
> > } while (dwarf_siblingof(die, die) == 0);
> > out:
> > return &enumeration->namespace.tag;