lkml.org 
[lkml]   [2023]   [Jul]   [21]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    From
    SubjectRe: [PATCH v2 3/9] bpf/btf: Add a function to search a member of a struct/union
    On Thu, 20 Jul 2023 23:34:42 +0100
    Alan Maguire <alan.maguire@oracle.com> wrote:

    > On 17/07/2023 16:23, Masami Hiramatsu (Google) wrote:
    > > From: Masami Hiramatsu (Google) <mhiramat@kernel.org>
    > >
    > > Add btf_find_struct_member() API to search a member of a given data structure
    > > or union from the member's name.
    > >
    > > Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
    >
    > A few small things below, but
    >
    > Reviewed-by: Alan Maguire <alan.maguire@oracle.com>

    Thanks

    >
    > > ---
    > > include/linux/btf.h | 3 +++
    > > kernel/bpf/btf.c | 38 ++++++++++++++++++++++++++++++++++++++
    > > 2 files changed, 41 insertions(+)
    > >
    > > diff --git a/include/linux/btf.h b/include/linux/btf.h
    > > index 98fbbcdd72ec..097fe9b51562 100644
    > > --- a/include/linux/btf.h
    > > +++ b/include/linux/btf.h
    > > @@ -225,6 +225,9 @@ const struct btf_type *btf_find_func_proto(struct btf *btf,
    > > const char *func_name);
    > > const struct btf_param *btf_get_func_param(const struct btf_type *func_proto,
    > > s32 *nr);
    > > +const struct btf_member *btf_find_struct_member(struct btf *btf,
    > > + const struct btf_type *type,
    > > + const char *member_name);
    > >
    > > #define for_each_member(i, struct_type, member) \
    > > for (i = 0, member = btf_type_member(struct_type); \
    > > diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
    > > index e015b52956cb..452ffb0393d6 100644
    > > --- a/kernel/bpf/btf.c
    > > +++ b/kernel/bpf/btf.c
    > > @@ -1992,6 +1992,44 @@ const struct btf_param *btf_get_func_param(const struct btf_type *func_proto, s3
    > > return NULL;
    > > }
    > >
    > > +/*
    > > + * Find a member of data structure/union by name and return it.
    > > + * Return NULL if not found, or -EINVAL if parameter is invalid.
    > > + */
    > > +const struct btf_member *btf_find_struct_member(struct btf *btf,
    > > + const struct btf_type *type,
    > > + const char *member_name)
    > > +{
    > > + const struct btf_member *members, *ret;
    > > + const char *name;
    > > + int i, vlen;
    > > +
    > > + if (!btf || !member_name || !btf_type_is_struct(type))
    > > + return ERR_PTR(-EINVAL);
    > > +
    > > + vlen = btf_type_vlen(type);
    > > + members = (const struct btf_member *)(type + 1);
    > > +
    > > + for (i = 0; i < vlen; i++) {
    >
    > could use for_each_member() here I think, or perhaps use
    > btf_type_member(type) when getting member pointer above.

    Thanks! I missed that macro.

    >
    > > + if (!members[i].name_off) {
    > > + /* unnamed union: dig deeper */
    > > + type = btf_type_by_id(btf, members[i].type);
    > > + if (!IS_ERR_OR_NULL(type)) {
    > > + ret = btf_find_struct_member(btf, type,
    > > + member_name);
    >
    > You'll need to skip modifiers before calling btf_find_struct_member()
    > here I think; it's possible to have a const anonymous union for example,

    Yeah, it is possible. Let me add it.

    > so to get to the union you'd need to skip the modifiers first. Otherwise
    > you could fail the btf_type_is_struct() test on re-entry.

    Indeed.

    Thank you!

    >
    >
    > > + if (!IS_ERR_OR_NULL(ret))
    > > + return ret;
    > > + }
    > > + } else {
    > > + name = btf_name_by_offset(btf, members[i].name_off);
    > > + if (name && !strcmp(member_name, name))
    > > + return &members[i];
    > > + }
    > > + }
    > > +
    > > + return NULL;
    > > +}
    > > +
    > > static u32 btf_resolved_type_id(const struct btf *btf, u32 type_id)
    > > {
    > > while (type_id < btf->start_id)
    > >
    > >


    --
    Masami Hiramatsu (Google) <mhiramat@kernel.org>

    \
     
     \ /
      Last update: 2023-07-21 16:23    [W:6.026 / U:0.008 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site