Re: BTF type tags not emitted properly when using macros

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 





On 2/20/22 11:22 AM, Yonghong Song wrote:


On 2/19/22 11:13 PM, Kumar Kartikeya Dwivedi wrote:
Hi list,

I noticed another problem in LLVM HEAD wrt BTF type tags.

When I have a file like bad.c:

  ; cat bad.c
#define __kptr __attribute__((btf_type_tag("btf_id")))
#define __kptr_ref __kptr __attribute__((btf_type_tag("ref")))
#define __kptr_percpu __kptr __attribute__((btf_type_tag("percpu")))
#define __kptr_user __kptr __attribute__((btf_type_tag("user")))

struct map_value {
         int __kptr *a;
         int __kptr_ref *b;
         int __kptr_percpu *c;
         int __kptr_user *d;
};

struct map_value *func(void);

int main(void)
{
         struct map_value *p = func();
         return *p->a + *p->b + *p->c + *p->d;
}

All tags are not emitted to BTF (neither are they there in llvm-dwarfdump output):

  ; ./src/linux/kptr-map/tools/bpf/bpftool/bpftool btf dump file bad.o format raw
[1] FUNC_PROTO '(anon)' ret_type_id=2 vlen=0
[2] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED
[3] FUNC 'main' type_id=1 linkage=global
[4] FUNC_PROTO '(anon)' ret_type_id=5 vlen=0
[5] PTR '(anon)' type_id=6
[6] STRUCT 'map_value' size=32 vlen=4
         'a' type_id=8 bits_offset=0
         'b' type_id=11 bits_offset=64
         'c' type_id=11 bits_offset=128
         'd' type_id=11 bits_offset=192
[7] TYPE_TAG 'btf_id' type_id=2
[8] PTR '(anon)' type_id=7
[9] TYPE_TAG 'btf_id' type_id=2
[10] TYPE_TAG 'ref' type_id=9
[11] PTR '(anon)' type_id=10
[12] FUNC 'func' type_id=4 linkage=extern

Notice that only btf_id (__kptr) and btf_id + ref (__kptr_ref) are emitted properly, and then rest of members use type_id=11, instead of emitting more type
tags.

Thanks for reporting. I think clang frontend may have bugs in handling nested macros. Will debug this.

I just submitted a clang patch to fix this issue.
See https://reviews.llvm.org/D120296

It should fix your above test case like
  struct map_value {
          int __kptr *a;
          int __kptr_ref *b;
          int __kptr_percpu *c;
          int __kptr_user *d;
  };
or
  struct map_value {
          int __attribute__((btf_type_tag("btf_id"))) *a;
int __attribute__((btf_type_tag("btf_id"))) __attribute__((btf_type_tag("ref"))) *b;
          ...
  }
etc.

It should work with the pure or mix of macro-defined-attribute and/or
raw-attribute. Please give a try. Thanks!



When I use a mix of macro and direct attributes, or just attributes, it does work:

; cat good.c
#define __kptr __attribute__((btf_type_tag("btf_id")))

struct map_value {
         int __kptr *a;
         int __kptr __attribute__((btf_type_tag("ref"))) *b;
         int __kptr __attribute__((btf_type_tag("percpu"))) *c;
         int __kptr __attribute__((btf_type_tag("user"))) *d;
};

[...]



[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux