Commit 69eaab04 authored by Andrii Nakryiko's avatar Andrii Nakryiko Committed by Daniel Borkmann

btf: extract BTF type size calculation

This pre-patch extracts calculation of amount of space taken by BTF type descriptor
for later reuse by btf_dedup functionality.
Signed-off-by: default avatarAndrii Nakryiko <andriin@fb.com>
Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
parent a8a1f7d0
......@@ -182,50 +182,53 @@ static int btf_parse_str_sec(struct btf *btf)
return 0;
}
static int btf_parse_type_sec(struct btf *btf)
static int btf_type_size(struct btf_type *t)
{
struct btf_header *hdr = btf->hdr;
void *nohdr_data = btf->nohdr_data;
void *next_type = nohdr_data + hdr->type_off;
void *end_type = nohdr_data + hdr->str_off;
while (next_type < end_type) {
struct btf_type *t = next_type;
int base_size = sizeof(struct btf_type);
__u16 vlen = BTF_INFO_VLEN(t->info);
int err;
next_type += sizeof(*t);
switch (BTF_INFO_KIND(t->info)) {
case BTF_KIND_FWD:
case BTF_KIND_CONST:
case BTF_KIND_VOLATILE:
case BTF_KIND_RESTRICT:
case BTF_KIND_PTR:
case BTF_KIND_TYPEDEF:
case BTF_KIND_FUNC:
return base_size;
case BTF_KIND_INT:
next_type += sizeof(int);
break;
return base_size + sizeof(__u32);
case BTF_KIND_ENUM:
return base_size + vlen * sizeof(struct btf_enum);
case BTF_KIND_ARRAY:
next_type += sizeof(struct btf_array);
break;
return base_size + sizeof(struct btf_array);
case BTF_KIND_STRUCT:
case BTF_KIND_UNION:
next_type += vlen * sizeof(struct btf_member);
break;
case BTF_KIND_ENUM:
next_type += vlen * sizeof(struct btf_enum);
break;
return base_size + vlen * sizeof(struct btf_member);
case BTF_KIND_FUNC_PROTO:
next_type += vlen * sizeof(struct btf_param);
break;
case BTF_KIND_FUNC:
case BTF_KIND_TYPEDEF:
case BTF_KIND_PTR:
case BTF_KIND_FWD:
case BTF_KIND_VOLATILE:
case BTF_KIND_CONST:
case BTF_KIND_RESTRICT:
break;
return base_size + vlen * sizeof(struct btf_param);
default:
pr_debug("Unsupported BTF_KIND:%u\n",
BTF_INFO_KIND(t->info));
pr_debug("Unsupported BTF_KIND:%u\n", BTF_INFO_KIND(t->info));
return -EINVAL;
}
}
static int btf_parse_type_sec(struct btf *btf)
{
struct btf_header *hdr = btf->hdr;
void *nohdr_data = btf->nohdr_data;
void *next_type = nohdr_data + hdr->type_off;
void *end_type = nohdr_data + hdr->str_off;
while (next_type < end_type) {
struct btf_type *t = next_type;
int type_size;
int err;
type_size = btf_type_size(t);
if (type_size < 0)
return type_size;
next_type += type_size;
err = btf_add_type(btf, t);
if (err)
return err;
......@@ -252,21 +255,6 @@ static bool btf_type_is_void_or_null(const struct btf_type *t)
return !t || btf_type_is_void(t);
}
static __s64 btf_type_size(const struct btf_type *t)
{
switch (BTF_INFO_KIND(t->info)) {
case BTF_KIND_INT:
case BTF_KIND_STRUCT:
case BTF_KIND_UNION:
case BTF_KIND_ENUM:
return t->size;
case BTF_KIND_PTR:
return sizeof(void *);
default:
return -EINVAL;
}
}
#define MAX_RESOLVE_DEPTH 32
__s64 btf__resolve_size(const struct btf *btf, __u32 type_id)
......@@ -280,11 +268,16 @@ __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++) {
size = btf_type_size(t);
if (size >= 0)
break;
switch (BTF_INFO_KIND(t->info)) {
case BTF_KIND_INT:
case BTF_KIND_STRUCT:
case BTF_KIND_UNION:
case BTF_KIND_ENUM:
size = t->size;
goto done;
case BTF_KIND_PTR:
size = sizeof(void *);
goto done;
case BTF_KIND_TYPEDEF:
case BTF_KIND_VOLATILE:
case BTF_KIND_CONST:
......@@ -308,6 +301,7 @@ __s64 btf__resolve_size(const struct btf *btf, __u32 type_id)
if (size < 0)
return -EINVAL;
done:
if (nelems && size > UINT32_MAX / nelems)
return -E2BIG;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment