On 23/06/2020 14.07, Alan Maguire wrote: > diff --git a/include/linux/printk.h b/include/linux/printk.h > index fc8f03c..8f8f5d2 100644 > --- a/include/linux/printk.h > +++ b/include/linux/printk.h > @@ -618,4 +618,20 @@ static inline void print_hex_dump_debug(const char *prefix_str, int prefix_type, > #define print_hex_dump_bytes(prefix_str, prefix_type, buf, len) \ > print_hex_dump_debug(prefix_str, prefix_type, 16, 1, buf, len, true) > > +/** > + * struct btf_ptr is used for %pT (typed pointer) display; the > + * additional type string/BTF id are used to render the pointer > + * data as the appropriate type. > + */ > +struct btf_ptr { > + void *ptr; > + const char *type; > + u32 id; > +}; > + > +#define BTF_PTR_TYPE(ptrval, typeval) \ > + (&((struct btf_ptr){.ptr = ptrval, .type = #typeval})) > + > +#define BTF_PTR_ID(ptrval, idval) \ > + (&((struct btf_ptr){.ptr = ptrval, .id = idval})) Isn't there some better place to put this than printk.h? Anyway, you probably want the ptr member to be "const void*", to avoid "... discards const qualifier" warnings when somebody happens to have a "const struct foobar *". > #endif > diff --git a/lib/vsprintf.c b/lib/vsprintf.c > index 259e558..c0d209d 100644 > --- a/lib/vsprintf.c > +++ b/lib/vsprintf.c > @@ -44,6 +44,7 @@ > #ifdef CONFIG_BLOCK > #include <linux/blkdev.h> > #endif > +#include <linux/btf.h> > > #include "../mm/internal.h" /* For the trace_print_flags arrays */ > > @@ -2092,6 +2093,87 @@ char *fwnode_string(char *buf, char *end, struct fwnode_handle *fwnode, > return widen_string(buf, buf - buf_start, end, spec); > } > > +#define btf_modifier_flag(c) (c == 'c' ? BTF_SHOW_COMPACT : \ > + c == 'N' ? BTF_SHOW_NONAME : \ > + c == 'x' ? BTF_SHOW_PTR_RAW : \ > + c == 'u' ? BTF_SHOW_UNSAFE : \ > + c == '0' ? BTF_SHOW_ZERO : 0) > + > +static noinline_for_stack > +char *btf_string(char *buf, char *end, void *ptr, struct printf_spec spec, > + const char *fmt) > +{ > + struct btf_ptr *bp = (struct btf_ptr *)ptr; > + u8 btf_kind = BTF_KIND_TYPEDEF; > + const struct btf_type *t; > + const struct btf *btf; > + char *buf_start = buf; > + const char *btf_type; > + u64 flags = 0, mod; > + s32 btf_id; > + > + if (check_pointer(&buf, end, ptr, spec)) > + return buf; > + > + if (check_pointer(&buf, end, bp->ptr, spec)) > + return buf; > + > + while (isalnum(*fmt)) { > + mod = btf_modifier_flag(*fmt); > + if (!mod) > + break; > + flags |= mod; > + fmt++; > + } > + > + btf = bpf_get_btf_vmlinux(); AFAICT, this function is only compiled if CONFIG_BPF=y and CONFIG_BPF_SYSCALL=y, and I don't see any static inline stub defined anywhere. Have you built the kernel with one or both of those turned off? Rasmus