On 10/15/18 3:30 PM, Daniel Borkmann wrote: > On 10/12/2018 08:54 PM, Yonghong Song wrote: >> This patch adds BTF_KIND_FUNC and BTF_KIND_FUNC_PROTO >> support to the type section. BTF_KIND_FUNC_PROTO is used >> to specify the type of a function pointer. With this, >> BTF has a complete set of C types (except float). >> >> BTF_KIND_FUNC is used to specify the signature of a >> defined subprogram. BTF_KIND_FUNC_PROTO can be referenced >> by another type, e.g., a pointer type, and BTF_KIND_FUNC >> type cannot be referenced by another type. >> >> For both BTF_KIND_FUNC and BTF_KIND_FUNC_PROTO types, >> the func return type is in t->type (where t is a >> "struct btf_type" object). The func args are an array of >> u32s immediately following object "t". >> >> As a concrete example, for the C program below, >> $ cat test.c >> int foo(int (*bar)(int)) { return bar(5); } >> with latest llvm trunk built with Debug mode, we have >> $ clang -target bpf -g -O2 -mllvm -debug-only=btf -c test.c >> Type Table: >> [1] FUNC name_off=1 info=0x0c000001 size/type=2 >> param_type=3 >> [2] INT name_off=11 info=0x01000000 size/type=4 >> desc=0x01000020 >> [3] PTR name_off=0 info=0x02000000 size/type=4 >> [4] FUNC_PROTO name_off=0 info=0x0d000001 size/type=2 >> param_type=2 >> >> String Table: >> 0 : >> 1 : foo >> 5 : .text >> 11 : int >> 15 : test.c >> 22 : int foo(int (*bar)(int)) { return bar(5); } >> >> FuncInfo Table: >> sec_name_off=5 >> insn_offset=<Omitted> type_id=1 >> >> ... >> >> (Eventually we shall have bpftool to dump btf information >> like the above.) >> >> Function "foo" has a FUNC type (type_id = 1). >> The parameter of "foo" has type_id 3 which is PTR->FUNC_PROTO, >> where FUNC_PROTO refers to function pointer "bar". > > Should also "bar" be part of the string table (at least at some point in > future)?
Yes, we can do it. The dwarf for the abovee example looks like 0x00000043: DW_TAG_formal_parameter DW_AT_location (0x00000000 [0x0000000000000000, 0x0000000000000008): DW_OP_reg1 W1 [0x0000000000000008, 0x0000000000000018): DW_OP_reg2 W2) DW_AT_name ("bar") DW_AT_decl_file ("/home/yhs/tmp/t.c") DW_AT_decl_line (1) DW_AT_type (0x0000005a "subroutine int*") 0x0000005a: DW_TAG_pointer_type DW_AT_type (0x0000005f "subroutine int") 0x0000005f: DW_TAG_subroutine_type DW_AT_type (0x00000053 "int") DW_AT_prototyped (true) 0x00000064: DW_TAG_formal_parameter DW_AT_type (0x00000053 "int") 0x00000069: NULL 0x0000006a: NULL The current llvm implementation does not record func parameter name, so "bar" got lost. We could associate "bar" with pointer type in the future implementation. > Iow, if verifier hints to an issue in the program when it would for example > walk > pointers and rewrite ctx access, then it could dump the var name along with > it. > It might be useful as well in combination with 22 from str table, when > annotating > the source. We might need support for variadic functions, though. How is LLVM > handling the latter with the recent BTF support? The LLVM implementation does support variadic functions. The last type id 0 indicates a variadic function. > >> In FuncInfo Table, for section .text, the function, >> with to-be-determined offset (marked as <Omitted>), >> has type_id=1 which refers to a FUNC type. >> This way, the function signature is >> available to both kernel and user space. >> Here, the insn offset is not available during the dump time >> as relocation is resolved pretty late in the compilation process. >> >> Signed-off-by: Martin KaFai Lau <ka...@fb.com> >> Signed-off-by: Yonghong Song <y...@fb.com>