btf_encoder: Preserve and encode exported functions as BTF_KIND_FUNC
Add encoding of DWARF's DW_TAG_subprogram_type into BTF's BTF_KIND_FUNC (plus corresponding BTF_KIND_FUNC_PROTO). Only exported functions are converted for now. This allows to capture all the exported kernel functions, same subset that's exposed through /proc/kallsyms. Committer testing: Before: $ readelf -SW vmlinux | grep BTF [78] .BTF PROGBITS 0000000000000000 26a27da9 1e5543 00 0 0 1 $ After: $ pahole -J vmlinux $ readelf -SW vmlinux | grep BTF [78] .BTF PROGBITS 0000000000000000 26a27da9 2d5f47 00 0 0 1 $ >>> 0x2d5f47 - 0x1e5543 985604 The kernel has a lot of functions! :-) $ pahole -VJ vmlinux > /tmp/pahole-btf-encoding-verbose-output.txt $ grep -w FUNC /tmp/pahole-btf-encoding-verbose-output.txt | wc -l 22871 [acme@quaco pahole]$ grep -w FUNC /tmp/pahole-btf-encoding-verbose-output.txt | tail [4511543] FUNC copy_from_user_nmi type_id=4511542 [4512934] FUNC memcpy_page_flushcache type_id=4512933 [4512936] FUNC __memcpy_flushcache type_id=4512935 [4512938] FUNC __copy_user_flushcache type_id=4512937 [4512940] FUNC arch_wb_cache_pmem type_id=4512939 [4512942] FUNC mcsafe_handle_tail type_id=4512941 [4512944] FUNC copy_user_handle_tail type_id=4512943 [4512946] FUNC clear_user type_id=4512945 [4512948] FUNC __clear_user type_id=4512947 [4512950] FUNC memcpy type_id=4512949 $ grep -w FUNC_PROTO /tmp/pahole-btf-encoding-verbose-output.txt | tail [4512902] FUNC_PROTO (anon) return=4511725 args=(4512097 (anon), 4511544 (anon)) [4512933] FUNC_PROTO (anon) return=0 args=(4511598 to, 4511725 page, 4511610 offset, 4511610 len) [4512935] FUNC_PROTO (anon) return=0 args=(4511638 _dst, 4511759 _src, 4511610 size) [4512937] FUNC_PROTO (anon) return=4511585 args=(4511638 dst, 4511759 src, 4511552 size) [4512939] FUNC_PROTO (anon) return=0 args=(4511638 addr, 4511610 size) [4512941] FUNC_PROTO (anon) return=4511544 args=(4511598 to, 4511598 from, 4511552 len) [4512943] FUNC_PROTO (anon) return=4511544 args=(4511598 to, 4511598 from, 4511552 len) [4512945] FUNC_PROTO (anon) return=4511544 args=(4511638 to, 4511544 n) [4512947] FUNC_PROTO (anon) return=4511544 args=(4511638 addr, 4511544 size) [4512949] FUNC_PROTO (anon) return=4511638 args=(4511638 p, 4511759 q, 4511591 size) $ grep -w FUNC_PROTO /tmp/pahole-btf-encoding-verbose-output.txt |grep 4511542 [4511542] FUNC_PROTO (anon) return=4510159 args=(4510254 to, 4510374 from, 4510159 n) $ With a little change to pdwtags to see DW_TAG_subroutine_type, which is what BTF's KIND_FUNC_PROTO maps to, we see some of those last prototypes: [acme@quaco pahole]$ pdwtags -F btf vmlinux | grep '()(' | tail void ()(struct insn * insn); /* size: 45404744 */ int ()(struct insn * insn); /* size: 4 */ void ()(struct insn * insn, const void * kaddr, int buf_len, int x86_64); /* size: 45405032 */ long unsigned int ()(const char * purpose); /* size: 8 */ void ()(char * to, struct page * page, size_t offset, size_t len); /* size: 45405864 */ void ()(void * _dst, const void * _src, size_t size); /* size: 45406200 */ long int ()(void * dst, const void * src, unsigned int size); /* size: 8 */ long unsigned int ()(char * to, char * from, unsigned int len); /* size: 8 */ long unsigned int ()(void * to, long unsigned int n); /* size: 8 */ long unsigned int ()(void * addr, long unsigned int size); /* size: 8 */ [acme@quaco pahole]$ I.e.: [4512941] FUNC_PROTO (anon) return=4511544 args=(4511598 to, 4511598 from, 4511552 len) gets decoded by pdwtags as: long unsigned int ()(char * to, char * from, unsigned int len); /* size: 8 */ $ grep '\[\(4511544\|4511598\|4511550\|4511552\)\]' /tmp/pahole-btf-encoding-verbose-output.txt [4511544] INT long unsigned int size=8 bit_offset=0 nr_bits=64 encoding=(none) [4511550] INT char size=1 bit_offset=0 nr_bits=8 encoding=(none) [4511552] INT unsigned int size=4 bit_offset=0 nr_bits=32 encoding=(none) [4511598] PTR (anon) type_id=4511550 $ Signed-off-by: Andrii Nakryiko <andriin@fb.com> Tested-by: Alexei Starovoitov <ast@kernel.org> Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com> Acked-by: Alexei Starovoitov <ast@kernel.org> Cc: Alexei Starovoitov <ast@fb.com> Cc: Andrii Nakryiko <andrii.nakryiko@gmail.com> Cc: Yonghong Song <yhs@fb.com> 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:
parent
910e060b5c
commit
3c5f2a224a
|
@ -173,6 +173,7 @@ int cu__encode_btf(struct cu *cu, int verbose)
|
|||
bool add_index_type = false;
|
||||
uint32_t type_id_off;
|
||||
uint32_t core_id;
|
||||
struct function *fn;
|
||||
struct tag *pos;
|
||||
int err = 0;
|
||||
|
||||
|
@ -225,6 +226,21 @@ int cu__encode_btf(struct cu *cu, int verbose)
|
|||
btf_elf__add_base_type(btfe, &bt);
|
||||
}
|
||||
|
||||
cu__for_each_function(cu, core_id, fn) {
|
||||
int btf_fnproto_id, btf_fn_id;
|
||||
|
||||
if (fn->declaration || !fn->external)
|
||||
continue;
|
||||
|
||||
btf_fnproto_id = btf_elf__add_func_proto(btfe, &fn->proto, type_id_off);
|
||||
btf_fn_id = btf_elf__add_ref_type(btfe, BTF_KIND_FUNC, btf_fnproto_id, fn->name, false);
|
||||
if (btf_fnproto_id < 0 || btf_fn_id < 0) {
|
||||
err = -1;
|
||||
printf("error: failed to encode function '%s'\n", function__name(fn, cu));
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
if (err)
|
||||
btf_elf__delete(btfe);
|
||||
|
|
|
@ -920,6 +920,7 @@ static struct function *function__new(Dwarf_Die *die, struct cu *cu)
|
|||
func->name = strings__add(strings, attr_string(die, DW_AT_name));
|
||||
func->linkage_name = strings__add(strings, attr_string(die, DW_AT_MIPS_linkage_name));
|
||||
func->inlined = attr_numeric(die, DW_AT_inline);
|
||||
func->declaration = dwarf_hasattr(die, DW_AT_declaration);
|
||||
func->external = dwarf_hasattr(die, DW_AT_external);
|
||||
func->abstract_origin = dwarf_hasattr(die, DW_AT_abstract_origin);
|
||||
dwarf_tag__set_spec(func->proto.tag.priv,
|
||||
|
|
|
@ -784,6 +784,7 @@ struct function {
|
|||
uint8_t external:1;
|
||||
uint8_t accessibility:2; /* DW_ACCESS_{public,protected,private} */
|
||||
uint8_t virtuality:2; /* DW_VIRTUALITY_{none,virtual,pure_virtual} */
|
||||
uint8_t declaration:1;
|
||||
int32_t vtable_entry;
|
||||
struct list_head vtable_node;
|
||||
/* fields used by tools */
|
||||
|
|
Loading…
Reference in New Issue