btf_encoder: Support btf_type_tag attribute

[$ ~] cat t.c
  #define __tag1 __attribute__((btf_type_tag("tag1")))
  #define __tag2 __attribute__((btf_type_tag("tag2")))
  int __tag1 * __tag1 __tag2 *g __attribute__((section(".data..percpu")));
  [$ ~] clang -O2 -g -c t.c
  [$ ~] pahole -JV t.o
  Found per-CPU symbol 'g' at address 0x0
  Found 1 per-CPU variables!
  File t.o:
  [1] TYPE_TAG tag1 type_id=5
  [2] TYPE_TAG tag2 type_id=1
  [3] PTR (anon) type_id=2
  [4] TYPE_TAG tag1 type_id=6
  [5] PTR (anon) type_id=4
  [6] INT int size=4 nr_bits=32 encoding=SIGNED
  search cu 't.c' for percpu global variables.
  Variable 'g' from CU 't.c' at address 0x0 encoded
  [7] VAR g type=3 linkage=1
  [8] DATASEC .data..percpu size=8 vlen=1
          type=7 offset=0 size=8
  [$ ~]

You can see for the source:

  int __tag1 * __tag1 __tag2 *g __attribute__((section(".data..percpu")));

the following type chain is generated:

  var -> ptr -> tag2 -> tag1 -> ptr -> tag1 -> int

The following shows pahole option "--skip_encoding_btf_type_tag" can be
used to prevent BTF_KIND_TYPE_TAG generation.

  [$ ~] pahole -JV t.o --skip_encoding_btf_type_tag
  Found per-CPU symbol 'g' at address 0x0
  Found 1 per-CPU variables!
  File t.o:
  [1] PTR (anon) type_id=2
  [2] PTR (anon) type_id=3
  [3] INT int size=4 nr_bits=32 encoding=SIGNED
  search cu 't.c' for percpu global variables.
  Variable 'g' from CU 't.c' at address 0x0 encoded
  [4] VAR g type=1 linkage=1
  [5] DATASEC .data..percpu size=8 vlen=1
          type=4 offset=0 size=8
  [$ ~]

Committer testing:

  $ rm -f t.o; clang -O2 -g -c t.c
  $ llvm-dwarfdump t.o
  t.o:	file format elf64-x86-64

  .debug_info contents:
  0x00000000: Compile Unit: length = 0x0000005e, format = DWARF32, version = 0x0004, abbr_offset = 0x0000, addr_size = 0x08 (next unit at 0x00000062)

  0x0000000b: DW_TAG_compile_unit
                DW_AT_producer	("clang version 14.0.0 (https://github.com/llvm/llvm-project 0d3add216f04b99ed1db1a05c39975d4a9c83e6b)")
                DW_AT_language	(DW_LANG_C99)
                DW_AT_name	("t.c")
                DW_AT_stmt_list	(0x00000000)
                DW_AT_comp_dir	("/var/home/acme/git/pahole")

  0x0000001e:   DW_TAG_variable
                  DW_AT_name	("g")
                  DW_AT_type	(0x00000033 "int **")
                  DW_AT_external	(true)
                  DW_AT_decl_file	("/var/home/acme/git/pahole/t.c")
                  DW_AT_decl_line	(3)
                  DW_AT_location	(DW_OP_addr 0x0)

  0x00000033:   DW_TAG_pointer_type
                  DW_AT_type	(0x0000004b "int *")

  0x00000038:     DW_TAG_LLVM_annotation
                    DW_AT_name	("btf_type_tag")
                    DW_AT_const_value	("tag1")

  0x00000041:     DW_TAG_LLVM_annotation
                    DW_AT_name	("btf_type_tag")
                    DW_AT_const_value	("tag2")

  0x0000004a:     NULL

  0x0000004b:   DW_TAG_pointer_type
                  DW_AT_type	(0x0000005a "int")

  0x00000050:     DW_TAG_LLVM_annotation
                    DW_AT_name	("btf_type_tag")
                    DW_AT_const_value	("tag1")

  0x00000059:     NULL

  0x0000005a:   DW_TAG_base_type
                  DW_AT_name	("int")
                  DW_AT_encoding	(DW_ATE_signed)
                  DW_AT_byte_size	(0x04)

  0x00000061:   NULL
  $ pahole -JV t.o
  Found per-CPU symbol 'g' at address 0x0
  Found 1 per-CPU variables!
  File t.o:
  [1] TYPE_TAG tag1 type_id=5
  [2] TYPE_TAG tag2 type_id=1
  [3] PTR (anon) type_id=2
  [4] TYPE_TAG tag1 type_id=6
  [5] PTR (anon) type_id=4
  [6] INT int size=4 nr_bits=32 encoding=SIGNED
  search cu 't.c' for percpu global variables.
  Variable 'g' from CU 't.c' at address 0x0 encoded
  [7] VAR g type=3 linkage=1
  [8] DATASEC .data..percpu size=8 vlen=1
  	type=7 offset=0 size=8
  ⬢[acme@toolbox pahole]$ pahole -JV t.o --skip_encoding_btf_type_tag
  Found per-CPU symbol 'g' at address 0x0
  Found 1 per-CPU variables!
  File t.o:
  [1] PTR (anon) type_id=2
  [2] PTR (anon) type_id=3
  [3] INT int size=4 nr_bits=32 encoding=SIGNED
  search cu 't.c' for percpu global variables.
  Variable 'g' from CU 't.c' at address 0x0 encoded
  [4] VAR g type=1 linkage=1
  [5] DATASEC .data..percpu size=8 vlen=1
  	type=4 offset=0 size=8
  $

Signed-off-by: Yonghong Song <yhs@fb.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Acked-by: Andrii Nakryiko <andrii@kernel.org>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: bpf@vger.kernel.org
Cc: dwarves@vger.kernel.org
Cc: kernel-team@fb.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
Yonghong Song 2021-11-22 20:56:33 -08:00 committed by Arnaldo Carvalho de Melo
parent 3da248c328
commit d99d551930
2 changed files with 12 additions and 0 deletions

View File

@ -143,6 +143,7 @@ static const char * const btf_kind_str[NR_BTF_KINDS] = {
[BTF_KIND_DATASEC] = "DATASEC",
[BTF_KIND_FLOAT] = "FLOAT",
[BTF_KIND_DECL_TAG] = "DECL_TAG",
[BTF_KIND_TYPE_TAG] = "TYPE_TAG",
};
static const char *btf__printable_name(const struct btf *btf, uint32_t offset)
@ -393,6 +394,9 @@ static int32_t btf_encoder__add_ref_type(struct btf_encoder *encoder, uint16_t k
case BTF_KIND_TYPEDEF:
id = btf__add_typedef(btf, name, type);
break;
case BTF_KIND_TYPE_TAG:
id = btf__add_type_tag(btf, name, type);
break;
case BTF_KIND_FWD:
id = btf__add_fwd(btf, name, kind_flag);
break;
@ -862,6 +866,9 @@ static int btf_encoder__encode_tag(struct btf_encoder *encoder, struct tag *tag,
case DW_TAG_typedef:
name = namespace__name(tag__namespace(tag));
return btf_encoder__add_ref_type(encoder, BTF_KIND_TYPEDEF, ref_type_id, name, false);
case DW_TAG_LLVM_annotation:
name = tag__btf_type_tag(tag)->value;
return btf_encoder__add_ref_type(encoder, BTF_KIND_TYPE_TAG, ref_type_id, name, false);
case DW_TAG_structure_type:
case DW_TAG_union_type:
case DW_TAG_class_type:

View File

@ -637,6 +637,11 @@ static inline struct btf_type_tag_ptr_type *tag__btf_type_tag_ptr(struct tag *ta
return (struct btf_type_tag_ptr_type *)tag;
}
static inline struct btf_type_tag_type *tag__btf_type_tag(struct tag *tag)
{
return (struct btf_type_tag_type *)tag;
}
/** struct namespace - base class for enums, structs, unions, typedefs, etc
*
* @tags - class_member, enumerators, etc