On Wed, Sep 23, 2020 at 06:46:25PM +0100, Alan Maguire wrote:
+static int bpf_btf_printf_prepare(struct btf_ptr *ptr, u32 btf_ptr_size,
u64 flags, const struct btf **btf,
s32 *btf_id)
+{
- u8 btf_kind = BTF_KIND_TYPEDEF;
- char type_name[KSYM_NAME_LEN];
- const struct btf_type *t;
- const char *btf_type;
- int ret;
- if (unlikely(flags & ~(BTF_F_ALL)))
return -EINVAL;
- if (btf_ptr_size != sizeof(struct btf_ptr))
return -EINVAL;
- *btf = bpf_get_btf_vmlinux();
- if (IS_ERR_OR_NULL(*btf))
return PTR_ERR(*btf);
- if (ptr->type != NULL) {
ret = copy_from_kernel_nofault(type_name, ptr->type,
sizeof(type_name));
nofault copy from bpf program global data... hmm... I guess that works, but...
if (ret)
return ret;
btf_type = type_name;
if (strncmp(btf_type, "struct ", strlen("struct ")) == 0) {
btf_kind = BTF_KIND_STRUCT;
btf_type += strlen("struct ");
} else if (strncmp(btf_type, "union ", strlen("union ")) == 0) {
btf_kind = BTF_KIND_UNION;
btf_type += strlen("union ");
} else if (strncmp(btf_type, "enum ", strlen("enum ")) == 0) {
btf_kind = BTF_KIND_ENUM;
btf_type += strlen("enum ");
}
if (strlen(btf_type) == 0)
return -EINVAL;
/* Assume type specified is a typedef as there's not much
* benefit in specifying int types other than wasting time
* on BTF lookups; we optimize for the most useful path.
*
* Fall back to BTF_KIND_INT if this fails.
*/
*btf_id = btf_find_by_name_kind(*btf, btf_type, btf_kind);
if (*btf_id < 0)
*btf_id = btf_find_by_name_kind(*btf, btf_type,
BTF_KIND_INT);
with all that fragility...
- } else if (ptr->type_id > 0)
*btf_id = ptr->type_id;
since __builtin_btf_type_id() landed in llvm in February and it works may be support type_id only?
Manually specifying type name as a string is error prone. Plus that copy_from_kernel... which is doing copy from bpf prog. I slept on it, but still feels unclean. May be do type_id only for now and if we really really need string types we can add it later after initial patches land?