]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - tools/lib/bpf/btf.c
Merge branch 'work.mount3' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
[linux.git] / tools / lib / bpf / btf.c
index d821107f55f90ff5c823d4ff1c19432268132a84..1aa189a9112a56f0b7dfda4a48e2af4e68ae78ec 100644 (file)
 #define BTF_MAX_NR_TYPES 0x7fffffff
 #define BTF_MAX_STR_OFFSET 0x7fffffff
 
-#define IS_MODIFIER(k) (((k) == BTF_KIND_TYPEDEF) || \
-               ((k) == BTF_KIND_VOLATILE) || \
-               ((k) == BTF_KIND_CONST) || \
-               ((k) == BTF_KIND_RESTRICT))
-
-#define IS_VAR(k) ((k) == BTF_KIND_VAR)
-
 static struct btf_type btf_void;
 
 struct btf {
@@ -43,47 +36,6 @@ struct btf {
        int fd;
 };
 
-struct btf_ext_info {
-       /*
-        * info points to the individual info section (e.g. func_info and
-        * line_info) from the .BTF.ext. It does not include the __u32 rec_size.
-        */
-       void *info;
-       __u32 rec_size;
-       __u32 len;
-};
-
-struct btf_ext {
-       union {
-               struct btf_ext_header *hdr;
-               void *data;
-       };
-       struct btf_ext_info func_info;
-       struct btf_ext_info line_info;
-       __u32 data_size;
-};
-
-struct btf_ext_info_sec {
-       __u32   sec_name_off;
-       __u32   num_info;
-       /* Followed by num_info * record_size number of bytes */
-       __u8    data[0];
-};
-
-/* The minimum bpf_func_info checked by the loader */
-struct bpf_func_info_min {
-       __u32   insn_off;
-       __u32   type_id;
-};
-
-/* The minimum bpf_line_info checked by the loader */
-struct bpf_line_info_min {
-       __u32   insn_off;
-       __u32   file_name_off;
-       __u32   line_off;
-       __u32   line_col;
-};
-
 static inline __u64 ptr_to_u64(const void *ptr)
 {
        return (__u64) (unsigned long) ptr;
@@ -193,9 +145,9 @@ static int btf_parse_str_sec(struct btf *btf)
 static int btf_type_size(struct btf_type *t)
 {
        int base_size = sizeof(struct btf_type);
-       __u16 vlen = BTF_INFO_VLEN(t->info);
+       __u16 vlen = btf_vlen(t);
 
-       switch (BTF_INFO_KIND(t->info)) {
+       switch (btf_kind(t)) {
        case BTF_KIND_FWD:
        case BTF_KIND_CONST:
        case BTF_KIND_VOLATILE:
@@ -220,7 +172,7 @@ static int btf_type_size(struct btf_type *t)
        case BTF_KIND_DATASEC:
                return base_size + vlen * sizeof(struct btf_var_secinfo);
        default:
-               pr_debug("Unsupported BTF_KIND:%u\n", BTF_INFO_KIND(t->info));
+               pr_debug("Unsupported BTF_KIND:%u\n", btf_kind(t));
                return -EINVAL;
        }
 }
@@ -264,7 +216,7 @@ const struct btf_type *btf__type_by_id(const struct btf *btf, __u32 type_id)
 
 static bool btf_type_is_void(const struct btf_type *t)
 {
-       return t == &btf_void || BTF_INFO_KIND(t->info) == BTF_KIND_FWD;
+       return t == &btf_void || btf_is_fwd(t);
 }
 
 static bool btf_type_is_void_or_null(const struct btf_type *t)
@@ -285,7 +237,7 @@ __s64 btf__resolve_size(const struct btf *btf, __u32 type_id)
        t = btf__type_by_id(btf, type_id);
        for (i = 0; i < MAX_RESOLVE_DEPTH && !btf_type_is_void_or_null(t);
             i++) {
-               switch (BTF_INFO_KIND(t->info)) {
+               switch (btf_kind(t)) {
                case BTF_KIND_INT:
                case BTF_KIND_STRUCT:
                case BTF_KIND_UNION:
@@ -304,7 +256,7 @@ __s64 btf__resolve_size(const struct btf *btf, __u32 type_id)
                        type_id = t->type;
                        break;
                case BTF_KIND_ARRAY:
-                       array = (const struct btf_array *)(t + 1);
+                       array = btf_array(t);
                        if (nelems && array->nelems > UINT32_MAX / nelems)
                                return -E2BIG;
                        nelems *= array->nelems;
@@ -335,8 +287,7 @@ int btf__resolve_type(const struct btf *btf, __u32 type_id)
        t = btf__type_by_id(btf, type_id);
        while (depth < MAX_RESOLVE_DEPTH &&
               !btf_type_is_void_or_null(t) &&
-              (IS_MODIFIER(BTF_INFO_KIND(t->info)) ||
-               IS_VAR(BTF_INFO_KIND(t->info)))) {
+              (btf_is_mod(t) || btf_is_typedef(t) || btf_is_var(t))) {
                type_id = t->type;
                t = btf__type_by_id(btf, type_id);
                depth++;
@@ -555,11 +506,11 @@ static int compare_vsi_off(const void *_a, const void *_b)
 static int btf_fixup_datasec(struct bpf_object *obj, struct btf *btf,
                             struct btf_type *t)
 {
-       __u32 size = 0, off = 0, i, vars = BTF_INFO_VLEN(t->info);
+       __u32 size = 0, off = 0, i, vars = btf_vlen(t);
        const char *name = btf__name_by_offset(btf, t->name_off);
        const struct btf_type *t_var;
        struct btf_var_secinfo *vsi;
-       struct btf_var *var;
+       const struct btf_var *var;
        int ret;
 
        if (!name) {
@@ -575,12 +526,11 @@ static int btf_fixup_datasec(struct bpf_object *obj, struct btf *btf,
 
        t->size = size;
 
-       for (i = 0, vsi = (struct btf_var_secinfo *)(t + 1);
-            i < vars; i++, vsi++) {
+       for (i = 0, vsi = btf_var_secinfos(t); i < vars; i++, vsi++) {
                t_var = btf__type_by_id(btf, vsi->type);
-               var = (struct btf_var *)(t_var + 1);
+               var = btf_var(t_var);
 
-               if (BTF_INFO_KIND(t_var->info) != BTF_KIND_VAR) {
+               if (!btf_is_var(t_var)) {
                        pr_debug("Non-VAR type seen in section %s\n", name);
                        return -EINVAL;
                }
@@ -596,7 +546,8 @@ static int btf_fixup_datasec(struct bpf_object *obj, struct btf *btf,
 
                ret = bpf_object__variable_offset(obj, name, &off);
                if (ret) {
-                       pr_debug("No offset found in symbol table for VAR %s\n", name);
+                       pr_debug("No offset found in symbol table for VAR %s\n",
+                                name);
                        return -ENOENT;
                }
 
@@ -620,7 +571,7 @@ int btf__finalize_data(struct bpf_object *obj, struct btf *btf)
                 * is section size and global variable offset. We use
                 * the info from the ELF itself for this purpose.
                 */
-               if (BTF_INFO_KIND(t->info) == BTF_KIND_DATASEC) {
+               if (btf_is_datasec(t)) {
                        err = btf_fixup_datasec(obj, btf, t);
                        if (err)
                                break;
@@ -775,14 +726,13 @@ int btf__get_map_kv_tids(const struct btf *btf, const char *map_name,
                return -EINVAL;
        }
 
-       if (BTF_INFO_KIND(container_type->info) != BTF_KIND_STRUCT ||
-           BTF_INFO_VLEN(container_type->info) < 2) {
+       if (!btf_is_struct(container_type) || btf_vlen(container_type) < 2) {
                pr_warning("map:%s container_name:%s is an invalid container struct\n",
                           map_name, container_name);
                return -EINVAL;
        }
 
-       key = (struct btf_member *)(container_type + 1);
+       key = btf_members(container_type);
        value = key + 1;
 
        key_size = btf__resolve_size(btf, key->type);
@@ -832,6 +782,9 @@ static int btf_ext_setup_info(struct btf_ext *btf_ext,
        /* The start of the info sec (including the __u32 record_size). */
        void *info;
 
+       if (ext_sec->len == 0)
+               return 0;
+
        if (ext_sec->off & 0x03) {
                pr_debug(".BTF.ext %s section is not aligned to 4 bytes\n",
                     ext_sec->desc);
@@ -935,11 +888,24 @@ static int btf_ext_setup_line_info(struct btf_ext *btf_ext)
        return btf_ext_setup_info(btf_ext, &param);
 }
 
+static int btf_ext_setup_offset_reloc(struct btf_ext *btf_ext)
+{
+       struct btf_ext_sec_setup_param param = {
+               .off = btf_ext->hdr->offset_reloc_off,
+               .len = btf_ext->hdr->offset_reloc_len,
+               .min_rec_size = sizeof(struct bpf_offset_reloc),
+               .ext_info = &btf_ext->offset_reloc_info,
+               .desc = "offset_reloc",
+       };
+
+       return btf_ext_setup_info(btf_ext, &param);
+}
+
 static int btf_ext_parse_hdr(__u8 *data, __u32 data_size)
 {
        const struct btf_ext_header *hdr = (struct btf_ext_header *)data;
 
-       if (data_size < offsetof(struct btf_ext_header, func_info_off) ||
+       if (data_size < offsetofend(struct btf_ext_header, hdr_len) ||
            data_size < hdr->hdr_len) {
                pr_debug("BTF.ext header not found");
                return -EINVAL;
@@ -997,6 +963,9 @@ struct btf_ext *btf_ext__new(__u8 *data, __u32 size)
        }
        memcpy(btf_ext->data, data, size);
 
+       if (btf_ext->hdr->hdr_len <
+           offsetofend(struct btf_ext_header, line_info_len))
+               goto done;
        err = btf_ext_setup_func_info(btf_ext);
        if (err)
                goto done;
@@ -1005,6 +974,13 @@ struct btf_ext *btf_ext__new(__u8 *data, __u32 size)
        if (err)
                goto done;
 
+       if (btf_ext->hdr->hdr_len <
+           offsetofend(struct btf_ext_header, offset_reloc_len))
+               goto done;
+       err = btf_ext_setup_offset_reloc(btf_ext);
+       if (err)
+               goto done;
+
 done:
        if (err) {
                btf_ext__free(btf_ext);
@@ -1441,10 +1417,9 @@ static struct btf_dedup *btf_dedup_new(struct btf *btf, struct btf_ext *btf_ext,
        d->map[0] = 0;
        for (i = 1; i <= btf->nr_types; i++) {
                struct btf_type *t = d->btf->types[i];
-               __u16 kind = BTF_INFO_KIND(t->info);
 
                /* VAR and DATASEC are never deduped and are self-canonical */
-               if (kind == BTF_KIND_VAR || kind == BTF_KIND_DATASEC)
+               if (btf_is_var(t) || btf_is_datasec(t))
                        d->map[i] = i;
                else
                        d->map[i] = BTF_UNPROCESSED_ID;
@@ -1485,11 +1460,11 @@ static int btf_for_each_str_off(struct btf_dedup *d, str_off_fn_t fn, void *ctx)
                if (r)
                        return r;
 
-               switch (BTF_INFO_KIND(t->info)) {
+               switch (btf_kind(t)) {
                case BTF_KIND_STRUCT:
                case BTF_KIND_UNION: {
-                       struct btf_member *m = (struct btf_member *)(t + 1);
-                       __u16 vlen = BTF_INFO_VLEN(t->info);
+                       struct btf_member *m = btf_members(t);
+                       __u16 vlen = btf_vlen(t);
 
                        for (j = 0; j < vlen; j++) {
                                r = fn(&m->name_off, ctx);
@@ -1500,8 +1475,8 @@ static int btf_for_each_str_off(struct btf_dedup *d, str_off_fn_t fn, void *ctx)
                        break;
                }
                case BTF_KIND_ENUM: {
-                       struct btf_enum *m = (struct btf_enum *)(t + 1);
-                       __u16 vlen = BTF_INFO_VLEN(t->info);
+                       struct btf_enum *m = btf_enum(t);
+                       __u16 vlen = btf_vlen(t);
 
                        for (j = 0; j < vlen; j++) {
                                r = fn(&m->name_off, ctx);
@@ -1512,8 +1487,8 @@ static int btf_for_each_str_off(struct btf_dedup *d, str_off_fn_t fn, void *ctx)
                        break;
                }
                case BTF_KIND_FUNC_PROTO: {
-                       struct btf_param *m = (struct btf_param *)(t + 1);
-                       __u16 vlen = BTF_INFO_VLEN(t->info);
+                       struct btf_param *m = btf_params(t);
+                       __u16 vlen = btf_vlen(t);
 
                        for (j = 0; j < vlen; j++) {
                                r = fn(&m->name_off, ctx);
@@ -1802,16 +1777,16 @@ static long btf_hash_enum(struct btf_type *t)
 /* Check structural equality of two ENUMs. */
 static bool btf_equal_enum(struct btf_type *t1, struct btf_type *t2)
 {
-       struct btf_enum *m1, *m2;
+       const struct btf_enum *m1, *m2;
        __u16 vlen;
        int i;
 
        if (!btf_equal_common(t1, t2))
                return false;
 
-       vlen = BTF_INFO_VLEN(t1->info);
-       m1 = (struct btf_enum *)(t1 + 1);
-       m2 = (struct btf_enum *)(t2 + 1);
+       vlen = btf_vlen(t1);
+       m1 = btf_enum(t1);
+       m2 = btf_enum(t2);
        for (i = 0; i < vlen; i++) {
                if (m1->name_off != m2->name_off || m1->val != m2->val)
                        return false;
@@ -1823,8 +1798,7 @@ static bool btf_equal_enum(struct btf_type *t1, struct btf_type *t2)
 
 static inline bool btf_is_enum_fwd(struct btf_type *t)
 {
-       return BTF_INFO_KIND(t->info) == BTF_KIND_ENUM &&
-              BTF_INFO_VLEN(t->info) == 0;
+       return btf_is_enum(t) && btf_vlen(t) == 0;
 }
 
 static bool btf_compat_enum(struct btf_type *t1, struct btf_type *t2)
@@ -1844,8 +1818,8 @@ static bool btf_compat_enum(struct btf_type *t1, struct btf_type *t2)
  */
 static long btf_hash_struct(struct btf_type *t)
 {
-       struct btf_member *member = (struct btf_member *)(t + 1);
-       __u32 vlen = BTF_INFO_VLEN(t->info);
+       const struct btf_member *member = btf_members(t);
+       __u32 vlen = btf_vlen(t);
        long h = btf_hash_common(t);
        int i;
 
@@ -1865,16 +1839,16 @@ static long btf_hash_struct(struct btf_type *t)
  */
 static bool btf_shallow_equal_struct(struct btf_type *t1, struct btf_type *t2)
 {
-       struct btf_member *m1, *m2;
+       const struct btf_member *m1, *m2;
        __u16 vlen;
        int i;
 
        if (!btf_equal_common(t1, t2))
                return false;
 
-       vlen = BTF_INFO_VLEN(t1->info);
-       m1 = (struct btf_member *)(t1 + 1);
-       m2 = (struct btf_member *)(t2 + 1);
+       vlen = btf_vlen(t1);
+       m1 = btf_members(t1);
+       m2 = btf_members(t2);
        for (i = 0; i < vlen; i++) {
                if (m1->name_off != m2->name_off || m1->offset != m2->offset)
                        return false;
@@ -1891,7 +1865,7 @@ static bool btf_shallow_equal_struct(struct btf_type *t1, struct btf_type *t2)
  */
 static long btf_hash_array(struct btf_type *t)
 {
-       struct btf_array *info = (struct btf_array *)(t + 1);
+       const struct btf_array *info = btf_array(t);
        long h = btf_hash_common(t);
 
        h = hash_combine(h, info->type);
@@ -1909,13 +1883,13 @@ static long btf_hash_array(struct btf_type *t)
  */
 static bool btf_equal_array(struct btf_type *t1, struct btf_type *t2)
 {
-       struct btf_array *info1, *info2;
+       const struct btf_array *info1, *info2;
 
        if (!btf_equal_common(t1, t2))
                return false;
 
-       info1 = (struct btf_array *)(t1 + 1);
-       info2 = (struct btf_array *)(t2 + 1);
+       info1 = btf_array(t1);
+       info2 = btf_array(t2);
        return info1->type == info2->type &&
               info1->index_type == info2->index_type &&
               info1->nelems == info2->nelems;
@@ -1928,14 +1902,10 @@ static bool btf_equal_array(struct btf_type *t1, struct btf_type *t2)
  */
 static bool btf_compat_array(struct btf_type *t1, struct btf_type *t2)
 {
-       struct btf_array *info1, *info2;
-
        if (!btf_equal_common(t1, t2))
                return false;
 
-       info1 = (struct btf_array *)(t1 + 1);
-       info2 = (struct btf_array *)(t2 + 1);
-       return info1->nelems == info2->nelems;
+       return btf_array(t1)->nelems == btf_array(t2)->nelems;
 }
 
 /*
@@ -1945,8 +1915,8 @@ static bool btf_compat_array(struct btf_type *t1, struct btf_type *t2)
  */
 static long btf_hash_fnproto(struct btf_type *t)
 {
-       struct btf_param *member = (struct btf_param *)(t + 1);
-       __u16 vlen = BTF_INFO_VLEN(t->info);
+       const struct btf_param *member = btf_params(t);
+       __u16 vlen = btf_vlen(t);
        long h = btf_hash_common(t);
        int i;
 
@@ -1967,16 +1937,16 @@ static long btf_hash_fnproto(struct btf_type *t)
  */
 static bool btf_equal_fnproto(struct btf_type *t1, struct btf_type *t2)
 {
-       struct btf_param *m1, *m2;
+       const struct btf_param *m1, *m2;
        __u16 vlen;
        int i;
 
        if (!btf_equal_common(t1, t2))
                return false;
 
-       vlen = BTF_INFO_VLEN(t1->info);
-       m1 = (struct btf_param *)(t1 + 1);
-       m2 = (struct btf_param *)(t2 + 1);
+       vlen = btf_vlen(t1);
+       m1 = btf_params(t1);
+       m2 = btf_params(t2);
        for (i = 0; i < vlen; i++) {
                if (m1->name_off != m2->name_off || m1->type != m2->type)
                        return false;
@@ -1993,7 +1963,7 @@ static bool btf_equal_fnproto(struct btf_type *t1, struct btf_type *t2)
  */
 static bool btf_compat_fnproto(struct btf_type *t1, struct btf_type *t2)
 {
-       struct btf_param *m1, *m2;
+       const struct btf_param *m1, *m2;
        __u16 vlen;
        int i;
 
@@ -2001,9 +1971,9 @@ static bool btf_compat_fnproto(struct btf_type *t1, struct btf_type *t2)
        if (t1->name_off != t2->name_off || t1->info != t2->info)
                return false;
 
-       vlen = BTF_INFO_VLEN(t1->info);
-       m1 = (struct btf_param *)(t1 + 1);
-       m2 = (struct btf_param *)(t2 + 1);
+       vlen = btf_vlen(t1);
+       m1 = btf_params(t1);
+       m2 = btf_params(t2);
        for (i = 0; i < vlen; i++) {
                if (m1->name_off != m2->name_off)
                        return false;
@@ -2029,7 +1999,7 @@ static int btf_dedup_prim_type(struct btf_dedup *d, __u32 type_id)
        __u32 cand_id;
        long h;
 
-       switch (BTF_INFO_KIND(t->info)) {
+       switch (btf_kind(t)) {
        case BTF_KIND_CONST:
        case BTF_KIND_VOLATILE:
        case BTF_KIND_RESTRICT:
@@ -2142,13 +2112,13 @@ static uint32_t resolve_fwd_id(struct btf_dedup *d, uint32_t type_id)
 {
        __u32 orig_type_id = type_id;
 
-       if (BTF_INFO_KIND(d->btf->types[type_id]->info) != BTF_KIND_FWD)
+       if (!btf_is_fwd(d->btf->types[type_id]))
                return type_id;
 
        while (is_type_mapped(d, type_id) && d->map[type_id] != type_id)
                type_id = d->map[type_id];
 
-       if (BTF_INFO_KIND(d->btf->types[type_id]->info) != BTF_KIND_FWD)
+       if (!btf_is_fwd(d->btf->types[type_id]))
                return type_id;
 
        return orig_type_id;
@@ -2157,7 +2127,7 @@ static uint32_t resolve_fwd_id(struct btf_dedup *d, uint32_t type_id)
 
 static inline __u16 btf_fwd_kind(struct btf_type *t)
 {
-       return BTF_INFO_KFLAG(t->info) ? BTF_KIND_UNION : BTF_KIND_STRUCT;
+       return btf_kflag(t) ? BTF_KIND_UNION : BTF_KIND_STRUCT;
 }
 
 /*
@@ -2278,8 +2248,8 @@ static int btf_dedup_is_equiv(struct btf_dedup *d, __u32 cand_id,
 
        cand_type = d->btf->types[cand_id];
        canon_type = d->btf->types[canon_id];
-       cand_kind = BTF_INFO_KIND(cand_type->info);
-       canon_kind = BTF_INFO_KIND(canon_type->info);
+       cand_kind = btf_kind(cand_type);
+       canon_kind = btf_kind(canon_type);
 
        if (cand_type->name_off != canon_type->name_off)
                return 0;
@@ -2328,12 +2298,12 @@ static int btf_dedup_is_equiv(struct btf_dedup *d, __u32 cand_id,
                return btf_dedup_is_equiv(d, cand_type->type, canon_type->type);
 
        case BTF_KIND_ARRAY: {
-               struct btf_array *cand_arr, *canon_arr;
+               const struct btf_array *cand_arr, *canon_arr;
 
                if (!btf_compat_array(cand_type, canon_type))
                        return 0;
-               cand_arr = (struct btf_array *)(cand_type + 1);
-               canon_arr = (struct btf_array *)(canon_type + 1);
+               cand_arr = btf_array(cand_type);
+               canon_arr = btf_array(canon_type);
                eq = btf_dedup_is_equiv(d,
                        cand_arr->index_type, canon_arr->index_type);
                if (eq <= 0)
@@ -2343,14 +2313,14 @@ static int btf_dedup_is_equiv(struct btf_dedup *d, __u32 cand_id,
 
        case BTF_KIND_STRUCT:
        case BTF_KIND_UNION: {
-               struct btf_member *cand_m, *canon_m;
+               const struct btf_member *cand_m, *canon_m;
                __u16 vlen;
 
                if (!btf_shallow_equal_struct(cand_type, canon_type))
                        return 0;
-               vlen = BTF_INFO_VLEN(cand_type->info);
-               cand_m = (struct btf_member *)(cand_type + 1);
-               canon_m = (struct btf_member *)(canon_type + 1);
+               vlen = btf_vlen(cand_type);
+               cand_m = btf_members(cand_type);
+               canon_m = btf_members(canon_type);
                for (i = 0; i < vlen; i++) {
                        eq = btf_dedup_is_equiv(d, cand_m->type, canon_m->type);
                        if (eq <= 0)
@@ -2363,7 +2333,7 @@ static int btf_dedup_is_equiv(struct btf_dedup *d, __u32 cand_id,
        }
 
        case BTF_KIND_FUNC_PROTO: {
-               struct btf_param *cand_p, *canon_p;
+               const struct btf_param *cand_p, *canon_p;
                __u16 vlen;
 
                if (!btf_compat_fnproto(cand_type, canon_type))
@@ -2371,9 +2341,9 @@ static int btf_dedup_is_equiv(struct btf_dedup *d, __u32 cand_id,
                eq = btf_dedup_is_equiv(d, cand_type->type, canon_type->type);
                if (eq <= 0)
                        return eq;
-               vlen = BTF_INFO_VLEN(cand_type->info);
-               cand_p = (struct btf_param *)(cand_type + 1);
-               canon_p = (struct btf_param *)(canon_type + 1);
+               vlen = btf_vlen(cand_type);
+               cand_p = btf_params(cand_type);
+               canon_p = btf_params(canon_type);
                for (i = 0; i < vlen; i++) {
                        eq = btf_dedup_is_equiv(d, cand_p->type, canon_p->type);
                        if (eq <= 0)
@@ -2428,8 +2398,8 @@ static void btf_dedup_merge_hypot_map(struct btf_dedup *d)
                targ_type_id = d->hypot_map[cand_type_id];
                t_id = resolve_type_id(d, targ_type_id);
                c_id = resolve_type_id(d, cand_type_id);
-               t_kind = BTF_INFO_KIND(d->btf->types[t_id]->info);
-               c_kind = BTF_INFO_KIND(d->btf->types[c_id]->info);
+               t_kind = btf_kind(d->btf->types[t_id]);
+               c_kind = btf_kind(d->btf->types[c_id]);
                /*
                 * Resolve FWD into STRUCT/UNION.
                 * It's ok to resolve FWD into STRUCT/UNION that's not yet
@@ -2498,7 +2468,7 @@ static int btf_dedup_struct_type(struct btf_dedup *d, __u32 type_id)
                return 0;
 
        t = d->btf->types[type_id];
-       kind = BTF_INFO_KIND(t->info);
+       kind = btf_kind(t);
 
        if (kind != BTF_KIND_STRUCT && kind != BTF_KIND_UNION)
                return 0;
@@ -2593,7 +2563,7 @@ static int btf_dedup_ref_type(struct btf_dedup *d, __u32 type_id)
        t = d->btf->types[type_id];
        d->map[type_id] = BTF_IN_PROGRESS_ID;
 
-       switch (BTF_INFO_KIND(t->info)) {
+       switch (btf_kind(t)) {
        case BTF_KIND_CONST:
        case BTF_KIND_VOLATILE:
        case BTF_KIND_RESTRICT:
@@ -2617,7 +2587,7 @@ static int btf_dedup_ref_type(struct btf_dedup *d, __u32 type_id)
                break;
 
        case BTF_KIND_ARRAY: {
-               struct btf_array *info = (struct btf_array *)(t + 1);
+               struct btf_array *info = btf_array(t);
 
                ref_type_id = btf_dedup_ref_type(d, info->type);
                if (ref_type_id < 0)
@@ -2651,8 +2621,8 @@ static int btf_dedup_ref_type(struct btf_dedup *d, __u32 type_id)
                        return ref_type_id;
                t->type = ref_type_id;
 
-               vlen = BTF_INFO_VLEN(t->info);
-               param = (struct btf_param *)(t + 1);
+               vlen = btf_vlen(t);
+               param = btf_params(t);
                for (i = 0; i < vlen; i++) {
                        ref_type_id = btf_dedup_ref_type(d, param->type);
                        if (ref_type_id < 0)
@@ -2792,7 +2762,7 @@ static int btf_dedup_remap_type(struct btf_dedup *d, __u32 type_id)
        struct btf_type *t = d->btf->types[type_id];
        int i, r;
 
-       switch (BTF_INFO_KIND(t->info)) {
+       switch (btf_kind(t)) {
        case BTF_KIND_INT:
        case BTF_KIND_ENUM:
                break;
@@ -2812,7 +2782,7 @@ static int btf_dedup_remap_type(struct btf_dedup *d, __u32 type_id)
                break;
 
        case BTF_KIND_ARRAY: {
-               struct btf_array *arr_info = (struct btf_array *)(t + 1);
+               struct btf_array *arr_info = btf_array(t);
 
                r = btf_dedup_remap_type_id(d, arr_info->type);
                if (r < 0)
@@ -2827,8 +2797,8 @@ static int btf_dedup_remap_type(struct btf_dedup *d, __u32 type_id)
 
        case BTF_KIND_STRUCT:
        case BTF_KIND_UNION: {
-               struct btf_member *member = (struct btf_member *)(t + 1);
-               __u16 vlen = BTF_INFO_VLEN(t->info);
+               struct btf_member *member = btf_members(t);
+               __u16 vlen = btf_vlen(t);
 
                for (i = 0; i < vlen; i++) {
                        r = btf_dedup_remap_type_id(d, member->type);
@@ -2841,8 +2811,8 @@ static int btf_dedup_remap_type(struct btf_dedup *d, __u32 type_id)
        }
 
        case BTF_KIND_FUNC_PROTO: {
-               struct btf_param *param = (struct btf_param *)(t + 1);
-               __u16 vlen = BTF_INFO_VLEN(t->info);
+               struct btf_param *param = btf_params(t);
+               __u16 vlen = btf_vlen(t);
 
                r = btf_dedup_remap_type_id(d, t->type);
                if (r < 0)
@@ -2860,8 +2830,8 @@ static int btf_dedup_remap_type(struct btf_dedup *d, __u32 type_id)
        }
 
        case BTF_KIND_DATASEC: {
-               struct btf_var_secinfo *var = (struct btf_var_secinfo *)(t + 1);
-               __u16 vlen = BTF_INFO_VLEN(t->info);
+               struct btf_var_secinfo *var = btf_var_secinfos(t);
+               __u16 vlen = btf_vlen(t);
 
                for (i = 0; i < vlen; i++) {
                        r = btf_dedup_remap_type_id(d, var->type);