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

Reply via email to