Skip to content

Commit

Permalink
dwarf_loader: Track unspecified types in a separate list
Browse files Browse the repository at this point in the history
In recent discussion in BPF mailing list ([1]) participants agreed to
add a new DWARF representation for "btf_type_tag" annotations.
The agreed representation of void pointers uses unspecified types.
For example, consider the following C code:

    struct alpha {
      void __attribute__((btf_type_tag("__alpha_a"))) *a;
    } g;

And corresponding DWARF:

0x29:   DW_TAG_structure_type
          DW_AT_name      ("alpha")

0x2e:     DW_TAG_member
            DW_AT_name    ("a")
            DW_AT_type    (0x38 "void *")

0x38:   DW_TAG_pointer_type
          DW_AT_type      (0x41 "void")

0x41:   DW_TAG_unspecified_type
          DW_AT_name      ("void")

0x43:     DW_TAG_LLVM_annotation
            DW_AT_name    ("btf:type_tag")
            DW_AT_const_value     ("__alpha_a")

This is a preparatory patch for new type tags representation support,
specifically it adds `struct unspecified_type` and a new `cu` field
`struct cu::unspecified_types`. These would be used in a subsequent
patch to recode type tags attached to DW_TAG_unspecified_type
as in the example above.

[1] Mailing list discussion regarding `btf:type_tag`
    Various approaches are discussed, Solution acmel#2 is accepted
    https://lore.kernel.org/bpf/87r0w9jjoq.fsf@oracle.com/

Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
  • Loading branch information
eddyz87 committed Nov 16, 2023
1 parent 45ec840 commit 8925c8e
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 2 deletions.
36 changes: 34 additions & 2 deletions dwarf_loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -165,14 +165,19 @@ static struct dwarf_cu *dwarf_cu__new(struct cu *cu)
return dwarf_cu;
}

static void unspecified_type__delete(struct cu *cu, struct unspecified_type *utype);

static void dwarf_cu__delete(struct cu *cu)
{
if (cu == NULL || cu->priv == NULL)
return;

struct dwarf_cu *dcu = cu->priv;
struct list_head *pos, *n;

// dcu->hash_tags & dcu->hash_types are on cu->obstack
list_for_each_safe(pos, n, &cu->unspecified_types)
unspecified_type__delete(cu, container_of(pos, struct unspecified_type, node));
cu__free(cu, dcu);
cu->priv = NULL;
}
Expand Down Expand Up @@ -1386,6 +1391,33 @@ static struct tag *die__create_new_tag(Dwarf_Die *die, struct cu *cu)
return tag;
}

static struct tag *die__create_new_unspecified_type(Dwarf_Die *die, struct cu *cu,
struct conf_load *conf)
{
struct unspecified_type *tag;

tag = tag__alloc_with_spec(cu, sizeof(struct unspecified_type));
if (tag == NULL)
return NULL;

tag__init(&tag->tag, cu, die);
INIT_LIST_HEAD(&tag->node);

tag->name = attr_string(die, DW_AT_name, conf);

list_add(&tag->node, &cu->unspecified_types);

return &tag->tag;
}

static void unspecified_type__delete(struct cu *cu, struct unspecified_type *utype)
{
struct dwarf_tag *dtag = utype->tag.priv;

cu__free(cu, dtag);
cu__free(cu, utype);
}

static struct btf_type_tag_ptr_type *die__create_new_btf_type_tag_ptr_type(Dwarf_Die *die, struct cu *cu)
{
struct btf_type_tag_ptr_type *tag;
Expand Down Expand Up @@ -2186,10 +2218,10 @@ static struct tag *__die__process_tag(Dwarf_Die *die, struct cu *cu,
case DW_TAG_volatile_type:
case DW_TAG_atomic_type:
tag = die__create_new_tag(die, cu); break;
case DW_TAG_unspecified_type:
tag = die__create_new_tag(die, cu); break;
case DW_TAG_pointer_type:
tag = die__create_new_pointer_tag(die, cu, conf); break;
case DW_TAG_unspecified_type:
tag = die__create_new_unspecified_type(die, cu, conf); break;
case DW_TAG_ptr_to_member_type:
tag = die__create_new_ptr_to_member_type(die, cu); break;
case DW_TAG_enumeration_type:
Expand Down
1 change: 1 addition & 0 deletions dwarves.c
Original file line number Diff line number Diff line change
Expand Up @@ -681,6 +681,7 @@ struct cu *cu__new(const char *name, uint8_t addr_size,
cu->dfops = NULL;
INIT_LIST_HEAD(&cu->tags);
INIT_LIST_HEAD(&cu->tool_list);
INIT_LIST_HEAD(&cu->unspecified_types);

cu->addr_size = addr_size;
cu->extra_dbg_info = 0;
Expand Down
17 changes: 17 additions & 0 deletions dwarves.h
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,7 @@ struct cu {
struct list_head node;
struct list_head tags;
struct list_head tool_list; /* To be used by tools such as ctracer */
struct list_head unspecified_types;
struct ptr_table types_table;
struct ptr_table functions_table;
struct ptr_table tags_table;
Expand Down Expand Up @@ -705,6 +706,22 @@ static inline struct btf_type_tag_type *tag__btf_type_tag(struct tag *tag)
return (struct btf_type_tag_type *)tag;
}

/** struct unspecified_type - representation of DW_TAG_unspecified_type.
*
* @name - DW_AT_name associated with this tag
* @node - a node for cu::unspecified_types list
*/
struct unspecified_type {
struct tag tag;
const char *name;
struct list_head node;
};

static inline struct unspecified_type *tag__unspecified_type(struct tag *tag)
{
return (struct unspecified_type *)tag;
}

/** struct namespace - base class for enums, structs, unions, typedefs, etc
*
* @tags - class_member, enumerators, etc
Expand Down

0 comments on commit 8925c8e

Please sign in to comment.