Re: [PATCH 1/2] libtraceevent: Add loading of BTF to the tep handle
Steven Rostedt <[email protected]> Mon, 4 Aug 2025 08:43:22 -0400
| Newsgroups | org.kernel.vger.linux-trace-devel |
|---|---|
| Message-ID | <[email protected]> |
On Mon, 4 Aug 2025 12:47:31 +0100 Douglas Raillard <[email protected]> wrote: > > +int tep_btf_print_args(struct tep_handle *tep, struct trace_seq *s, void *args, > > + int nmem, int size, const char *func) > > +{ > > + struct tep_btf *btf = tep->btf; > > + struct btf_type *type = tep_btf_find_func(btf, func); > > + struct btf_param *param; > > + unsigned long long arg; > > + unsigned int encode; > > + const char *param_name; > > + int a, p, x, nr; > > + > > + if (size != 4 && size != 8) > > + return -1; > > + > > + if (!type) { > > + for (int i = 0; i < nmem; i++) { > > + assign_arg(&arg, args, size, i); > > + trace_seq_printf(s, "%llx", arg); > > + if (i + 1 < nmem) > > + trace_seq_puts(s, ", "); > > + } > > + return 0; > > + } > > + > > + if (BTF_INFO_KIND(type->info) != BTF_KIND_FUNC) { > > + printf("Invalid func type %d %s\n", BTF_INFO_KIND(type->info), > > + btf_type_str(type)); > > + return -1; > > + } > > + > > + /* Get the function proto */ > > + type = btf_get_type(btf, type->type); > > + > > + /* No proto means "()" ? */ > > + if (!type) > > + return 0; > > + > > + if (BTF_INFO_KIND(type->info) != BTF_KIND_FUNC_PROTO) { > > + printf("Invalid func proto type %d %s\n", BTF_INFO_KIND(type->info), > > + btf_type_str(type)); > > + return -1; > > + } > > + > > + /* Get the number of parameters */ > > + nr = BTF_INFO_VLEN(type->info); > > + > > + /* The parameters are right after the FUNC_PROTO type */ > > + param = ((void *)type) + sizeof(*type); > > + > > + for (a = 0, p = 0; p < nr; a++, p++) { > > + struct btf_type *t; > > + > > + if (p) > > + trace_seq_puts(s, ", "); > > + > > + if (a == nmem) { > > + trace_seq_puts(s, "..."); > > + break; > > + } > > + > > + assign_arg(&arg, args, size, a); > > + > > + param_name = btf_name(btf, param[p].name_off); > > + if (param_name) > > + trace_seq_printf(s, "%s=", param_name); > > + > > + t = btf_skip_modifiers(btf, param[p].type); > > + > > + switch (t ? BTF_INFO_KIND(t->info) : BTF_KIND_UNKN) { > > + case BTF_KIND_UNKN: > > + trace_seq_putc(s, '?'); > > + /* Still print unknown type values */ > > + /* fallthough */ > > + case BTF_KIND_PTR: > > + trace_seq_printf(s, "0x%llx", arg); > > + break; > > + case BTF_KIND_INT: > > + encode = *(int *)((void *)t + sizeof(*t)); > > + /* Print unsigned ints as hex */ > > + if (BTF_INT_ENCODING(encode) & BTF_INT_SIGNED) > > BTF_INT_OFFSET() and BTF_INT_VAL() values should also be used to shift and mask > appropriately. You meant to the "arg" passed in? > > I assume that regardless of BTF_INT_CHAR and BTF_INT_BOOL value, BTF_INT_SIGNED is > set appropriately. > > > + trace_seq_printf(s, "%lld", arg); > > + else > > + trace_seq_printf(s, "0x%llx", arg); > > + break; > > + case BTF_KIND_ENUM: > > Could add as well: case BTF_KIND_ENUM64: Of course then we would need to check if this is a 32 bit infrastructure. I'm assuming it would be treated differently. More like a struct? > > > + trace_seq_printf(s, "%lld", arg); > > This could probably be improved to display the enum variant name, with the caveats that: If btf has it, sure! But that can come later. Thanks, -- Steve > > 1. C allows values that are not that of any enumerator AFAIR, so you'd need the > raw int display fallback. > 2. GNU C allows enum forward declaration. This is not ISO C and BTF has no specific > representation for that. As a result, last time I checked you end up with > BTF_KIND_ENUM and info.vlen == 0. Another entry with info.vlen != 0 should > also exist and give the actual enumerators list. Those forward decl provide an > incomplete type though, so you should not encounter it directly in function > parameters. > > > + break; > > > + default: > > + /* This does not handle complex arguments */ > > + trace_seq_printf(s, "(%s)[0x%llx", btf_type_str(t), arg); > > + for (x = sizeof(long); x < t->size; x += sizeof(long)) { > > + trace_seq_putc(s, ':'); > > + if (++a == nmem) { > > + trace_seq_puts(s, "...]"); > > + return 0; > > + } > > + assign_arg(&arg, args, size, a); > > + trace_seq_printf(s, "0x%llx", arg); > > + } > > + trace_seq_putc(s, ']'); > > + break; > > + } > > + } > > + return 0; > > +}