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;
};
[...]