When dealing with BTF encoding of multiple CUs, special `void` type should be handled explicitly. This is already handled for all BTF types except recently added FUNC_PROTO. Without this fix, any `void` type directly referenced from FUNC_PROTO will turn into last type from previous CU (see example below, for FUNC_PROTO [4]). $ cat test1.c void (*foo)(void); int main() { return 0; } $ cat test2.c void (*bar)(void); $ cc -g test1.c test2.c -o test Without fix: $ LLVM_OBJCOPY=objcopy ~/local/pahole/build/pahole -JV /tmp/test File /tmp/test: [1] INT int size=4 bit_offset=0 nr_bits=32 encoding=SIGNED [2] FUNC_PROTO (anon) return=0 args=(void) [3] PTR (anon) type_id=2 [4] FUNC_PROTO (anon) return=3 args=(void) [5] PTR (anon) type_id=4 With fix: $ LLVM_OBJCOPY=objcopy ~/local/pahole/build/pahole -JV /tmp/test File /tmp/test: [1] INT int size=4 bit_offset=0 nr_bits=32 encoding=SIGNED [2] FUNC_PROTO (anon) return=0 args=(void) [3] PTR (anon) type_id=2 [4] FUNC_PROTO (anon) return=0 args=(void) [5] PTR (anon) type_id=4 Signed-off-by: Andrii Nakryiko <andriin@xxxxxx> --- libbtf.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libbtf.c b/libbtf.c index 478393b..c988d2a 100644 --- a/libbtf.c +++ b/libbtf.c @@ -535,7 +535,7 @@ int32_t btf__add_func_proto(struct btf *btf, struct ftype *ftype, t.name_off = 0; t.info = BTF_INFO_ENCODE(BTF_KIND_FUNC_PROTO, 0, nr_params); - t.type = type_id_off + ftype->tag.type; + t.type = ftype->tag.type == 0 ? 0 : type_id_off + ftype->tag.type; ++btf->type_index; if (gobuffer__add(&btf->types, &t, sizeof(t)) >= 0) { @@ -552,9 +552,12 @@ int32_t btf__add_func_proto(struct btf *btf, struct ftype *ftype, /* add parameters */ param_idx = 0; ftype__for_each_parameter(ftype, param) { + uint32_t param_type_id = param->tag.type == 0 + ? 0 + : type_id_off + param->tag.type; ++param_idx; if (btf__add_func_proto_param(btf, param->name, - type_id_off + param->tag.type, + param_type_id, param_idx == nr_params)) return -1; } -- 2.17.1