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

Alan Maguire <[email protected]> Mon, 30 Mar 2026 10:05:26 +0100
Newsgroups org.kernel.vger.dwarves
Message-ID <[email protected]>
On 23/03/2026 21:15, Arnaldo Carvalho de Melo wrote:
> From: Arnaldo Carvalho de Melo <[email protected]>
> 
> 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.

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

Reviewed-by: Alan Maguire <[email protected]>

> ---
>  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;