On 13/03/2023 02:17, Eduard Zingerman wrote: > "btf:type_tag" is an DW_TAG_LLVM_annotation object that encodes > btf_type_tag attributes in DWARF. Contrary to existing "btf_type_tag" > it allows to associate such attributes with non-pointer types. > When "btf:type_tag" is attached to a type it applies to this type. > > For example the following C code: > > struct echo { > int __attribute__((btf_type_tag("__c"))) c; > } > > Produces the following DWARF: > > 0x29: DW_TAG_structure_type > DW_AT_name ("echo") > > 0x40: DW_TAG_member > DW_AT_name ("c") > DW_AT_type (0x8c "int") > > 0x8c: DW_TAG_base_type > DW_AT_name ("int") > DW_AT_encoding (DW_ATE_signed) > DW_AT_byte_size (0x04) > > 0x90: DW_TAG_LLVM_annotation > DW_AT_name ("btf:type_tag") > DW_AT_const_value ("__c") > > Meaning that type 0x8c is an `int` with type tag `__c`. > Corresponding BTF looks as follows: > > [1] STRUCT 'echo' > ... > 'c' type_id=8 bits_offset=128 > [4] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED > [8] TYPE_TAG '__c' type_id=4 > > Void pointers with type tag annotations are represented as objects > of unspecified type with name "void", here is an example: > > struct st { > void __attribute__((btf_type_tag("__d"))) *d; > } > > And corresponding DWARF: > > 0x29: DW_TAG_structure_type > DW_AT_name ("st") > > 0x49: DW_TAG_member > DW_AT_name ("d") > DW_AT_type (0xa6 "void *") > > 0xa6: DW_TAG_pointer_type > DW_AT_type (0xaf "void") > > 0xaf: DW_TAG_unspecified_type > DW_AT_name ("void") > > 0xb1: DW_TAG_LLVM_annotation > DW_AT_name ("btf:type_tag") > DW_AT_const_value ("__d") > > This commit adds support for DW_TAG_LLVM_annotation "btf:type_tag" > attached to the following entities: > - base types; > - arrays; > - pointers; > - structs > - unions; > - enums; > - typedefs. > > This is achieved via the following modifications: > - Types `struct btf_type_tag_type` and `struct llvm_annotation` are > consolidated as a single type `struct llvm_annotation`, in order to > reside in a single `annots` list associated with struct/union/enum > or typedef. > - `struct unspecified_type` is added to handle `void *` types annotated > with `btf:type_tag`. > - `struct tag` is extended with `annots` list. > - DWARF load phase is modified to fill `annots` fields for the above > mentioned types. > - Recode phase is split in two sub-phases: > - The existing `tag__recode_dwarf_type()` is executed first; > - Newly added `update_btf_type_tag_refs()` is executed to update > `->type` field of each tag if that type refers to an object with > `btf:type_tag` annotation. The id of the type is replaced by id > of the type tag. > - When `btf:type_tag` annotations are present in compilation unit, > all `btf_type_tag` annotations are ignored during BTF dump. > > See also: > [1] Mailing list discussion regarding `btf:type_tag` > https://lore.kernel.org/bpf/87r0w9jjoq.fsf@xxxxxxxxxx/ > I know there's a v2 coming but one suggestion and one other issue below.. this is a great explanation, thanks for the details! one other thing that might help here is specifying that the solution adopted is option 2 described in that discussion (at least I think it is?). > Signed-off-by: Eduard Zingerman <eddyz87@xxxxxxxxx> > --- > btf_encoder.c | 13 +- > btf_loader.c | 15 +- > dwarf_loader.c | 763 +++++++++++++++++++++++++++++++++++++--------- > dwarves.c | 1 + > dwarves.h | 68 +++-- > dwarves_fprintf.c | 13 + > 6 files changed, 693 insertions(+), 180 deletions(-) > <snip> > -static void ftype__recode_dwarf_types(struct tag *tag, struct cu *cu); > +/** Add @tuple to @ctx->mappings array, extend it if necessary. */ > +static int push_btf_type_tag_mapping(struct btf_type_tag_mapping *tuple, > + struct recode_context *ctx) > +{ > + if (ctx->nr_allocated == ctx->nr_entries) { > + uint32_t new_nr = ctx->nr_allocated * 2; > + void *new_array = reallocarray(ctx->mappings, new_nr, > + sizeof(ctx->mappings[0])); older libcs won't have reallocarray; might be good to either replace with realloc or define our own variant in dutil.h like was done with libbpf_reallocarray()?