diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c index 6098c8d1e26a..af4eb27d2f54 100644 --- a/tools/lib/bpf/btf.c +++ b/tools/lib/bpf/btf.c @@ -115,7 +115,7 @@ struct btf { * | Header | Types | Strings | Optional kind layout| * raw_data----->+----------+---------+-----------+---------------------+ */ - struct btf_header *hdr; /* separately-allocated header data */ + struct btf_header hdr; /* copy of the header data */ void *types_data; size_t types_data_cap; /* used size stored in hdr->type_len */ @@ -307,46 +307,41 @@ static int btf_parse_hdr(struct btf *btf) return -EINVAL; } - /* At this point, we have basic header information, so allocate btf->hdr */ - btf->hdr = calloc(1, sizeof(struct btf_header)); - if (!btf->hdr) { - pr_debug("BTF header allocation failed\n"); - return -ENOMEM; - } - memcpy(btf->hdr, hdr, min((size_t)hdr_len, sizeof(struct btf_header))); + /* At this point, we have basic header information, so copy to btf->hdr */ + memcpy(&btf->hdr, hdr, min((size_t)hdr_len, sizeof(struct btf_header))); meta_left = btf->raw_size - hdr_len; - if (meta_left < (long long)btf->hdr->str_off + btf->hdr->str_len) { + if (meta_left < (long long)btf->hdr.str_off + btf->hdr.str_len) { pr_debug("Invalid BTF total size: %u\n", btf->raw_size); return -EINVAL; } - if ((long long)btf->hdr->type_off + btf->hdr->type_len > btf->hdr->str_off) { + if ((long long)btf->hdr.type_off + btf->hdr.type_len > btf->hdr.str_off) { pr_debug("Invalid BTF data sections layout: type data at %u + %u, strings data at %u + %u\n", - btf->hdr->type_off, btf->hdr->type_len, btf->hdr->str_off, - btf->hdr->str_len); + btf->hdr.type_off, btf->hdr.type_len, btf->hdr.str_off, + btf->hdr.str_len); return -EINVAL; } - if (btf->hdr->type_off % 4) { + if (btf->hdr.type_off % 4) { pr_debug("BTF type section is not aligned to 4 bytes\n"); return -EINVAL; } - if (btf->hdr->kind_layout_len == 0) + if (btf->hdr.kind_layout_len == 0) return 0; - if (btf->hdr->kind_layout_off % 4) { + if (btf->hdr.kind_layout_off % 4) { pr_debug("BTF kind_layout section is not aligned to 4 bytes\n"); return -EINVAL; } - if (btf->hdr->kind_layout_off < btf->hdr->str_off + btf->hdr->str_len) { + if (btf->hdr.kind_layout_off < btf->hdr.str_off + btf->hdr.str_len) { pr_debug("Invalid BTF data sections layout: strings data at %u + %u, kind layout data at %u + %u\n", - btf->hdr->str_off, btf->hdr->str_len, - btf->hdr->kind_layout_off, btf->hdr->kind_layout_len); + btf->hdr.str_off, btf->hdr.str_len, + btf->hdr.kind_layout_off, btf->hdr.kind_layout_len); return -EINVAL; } - if (btf->hdr->kind_layout_off + btf->hdr->kind_layout_len > meta_left) { + if (btf->hdr.kind_layout_off + btf->hdr.kind_layout_len > meta_left) { pr_debug("Invalid BTF total size: %u\n", btf->raw_size); return -EINVAL; } @@ -355,9 +350,9 @@ static int btf_parse_hdr(struct btf *btf) static int btf_parse_str_sec(struct btf *btf) { - const struct btf_header *hdr = btf->hdr; + const struct btf_header *hdr = &btf->hdr; const char *start = btf->strs_data; - const char *end = start + btf->hdr->str_len; + const char *end = start + btf->hdr.str_len; if (btf->base_btf && hdr->str_len == 0) return 0; @@ -374,7 +369,7 @@ static int btf_parse_str_sec(struct btf *btf) static int btf_parse_kind_layout_sec(struct btf *btf) { - const struct btf_header *hdr = btf->hdr; + const struct btf_header *hdr = &btf->hdr; if (!hdr->kind_layout_len) return 0; @@ -383,7 +378,7 @@ static int btf_parse_kind_layout_sec(struct btf *btf) pr_debug("Invalid BTF kind layout section\n"); return -EINVAL; } - btf->kind_layout = btf->raw_data + btf->hdr->hdr_len + btf->hdr->kind_layout_off; + btf->kind_layout = btf->raw_data + btf->hdr.hdr_len + btf->hdr.kind_layout_off; return 0; } @@ -397,7 +392,7 @@ static int btf_type_size_unknown(const struct btf *btf, const struct btf_type *t __u8 kind = btf_kind(t); __u32 off = kind * sizeof(struct btf_kind_layout); - if (!btf->kind_layout || off >= btf->hdr->kind_layout_len) { + if (!btf->kind_layout || off >= btf->hdr.kind_layout_len) { pr_debug("Unsupported BTF_KIND: %u\n", btf_kind(t)); return -EINVAL; } @@ -535,7 +530,7 @@ static int btf_bswap_type_rest(struct btf_type *t) static int btf_parse_type_sec(struct btf *btf) { - struct btf_header *hdr = btf->hdr; + struct btf_header *hdr = &btf->hdr; void *next_type = btf->types_data; void *end_type = next_type + hdr->type_len; int err, type_size; @@ -1105,7 +1100,6 @@ void btf__free(struct btf *btf) strset__free(btf->strs_set); free(btf->kind_layout); } - free(btf->hdr); btf_free_raw_data(btf); free(btf->raw_data_swapped); free(btf->type_offs); @@ -1135,7 +1129,7 @@ static struct btf *btf_new_empty(struct btf_new_opts *opts) if (base_btf) { btf->base_btf = base_btf; btf->start_id = btf__type_cnt(base_btf); - btf->start_str_off = base_btf->hdr->str_len + base_btf->start_str_off; + btf->start_str_off = base_btf->hdr.str_len + base_btf->start_str_off; btf->swapped_endian = base_btf->swapped_endian; } @@ -1157,20 +1151,13 @@ static struct btf *btf_new_empty(struct btf_new_opts *opts) btf->types_data = btf->raw_data + hdr->hdr_len; btf->strs_data = btf->raw_data + hdr->hdr_len; hdr->str_len = base_btf ? 0 : 1; /* empty string at offset 0 */ - btf->hdr = calloc(1, sizeof(struct btf_header)); - if (!btf->hdr) { - free(btf->raw_data); - free(btf); - return ERR_PTR(-ENOMEM); - } - if (add_kind_layout) { hdr->kind_layout_len = sizeof(kind_layouts); hdr->kind_layout_off = roundup(hdr->str_len, 4); btf->kind_layout = btf->raw_data + hdr->hdr_len + hdr->kind_layout_off; memcpy(btf->kind_layout, kind_layouts, sizeof(kind_layouts)); } - memcpy(btf->hdr, hdr, sizeof(*hdr)); + memcpy(&btf->hdr, hdr, sizeof(*hdr)); return btf; } @@ -1216,7 +1203,7 @@ static struct btf *btf_new(const void *data, __u32 size, struct btf *base_btf, b if (base_btf) { btf->base_btf = base_btf; btf->start_id = btf__type_cnt(base_btf); - btf->start_str_off = base_btf->hdr->str_len + base_btf->start_str_off; + btf->start_str_off = base_btf->hdr.str_len + base_btf->start_str_off; } if (is_mmap) { @@ -1237,8 +1224,8 @@ static struct btf *btf_new(const void *data, __u32 size, struct btf *base_btf, b if (err) goto done; - btf->strs_data = btf->raw_data + btf->hdr->hdr_len + btf->hdr->str_off; - btf->types_data = btf->raw_data + btf->hdr->hdr_len + btf->hdr->type_off; + btf->strs_data = btf->raw_data + btf->hdr.hdr_len + btf->hdr.str_off; + btf->types_data = btf->raw_data + btf->hdr.hdr_len + btf->hdr.type_off; err = btf_parse_str_sec(btf); err = err ?: btf_parse_kind_layout_sec(btf); @@ -1692,7 +1679,7 @@ static const void *btf_strs_data(const struct btf *btf) static void *btf_get_raw_data(const struct btf *btf, __u32 *size, bool swap_endian) { - struct btf_header *hdr = btf->hdr; + const struct btf_header *hdr = &btf->hdr; struct btf_type *t; void *data, *p; __u32 data_sz; @@ -1774,7 +1761,7 @@ const char *btf__str_by_offset(const struct btf *btf, __u32 offset) { if (offset < btf->start_str_off) return btf__str_by_offset(btf->base_btf, offset); - else if (offset - btf->start_str_off < btf->hdr->str_len) + else if (offset - btf->start_str_off < btf->hdr.str_len) return btf_strs_data(btf) + (offset - btf->start_str_off); else return errno = EINVAL, NULL; @@ -1897,21 +1884,21 @@ static int btf_ensure_modifiable(struct btf *btf) } /* split raw data into memory regions; btf->hdr is done already. */ - types = malloc(btf->hdr->type_len); + types = malloc(btf->hdr.type_len); if (!types) goto err_out; - memcpy(types, btf->types_data, btf->hdr->type_len); + memcpy(types, btf->types_data, btf->hdr.type_len); - if (btf->hdr->kind_layout_len) { - kind_layout = malloc(btf->hdr->kind_layout_len); + if (btf->hdr.kind_layout_len) { + kind_layout = malloc(btf->hdr.kind_layout_len); if (!kind_layout) goto err_out; - memcpy(kind_layout, btf->raw_data + btf->hdr->hdr_len + btf->hdr->kind_layout_off, - btf->hdr->kind_layout_len); + memcpy(kind_layout, btf->raw_data + btf->hdr.hdr_len + btf->hdr.kind_layout_off, + btf->hdr.kind_layout_len); } /* build lookup index for all strings */ - set = strset__new(BTF_MAX_STR_OFFSET, btf->strs_data, btf->hdr->str_len); + set = strset__new(BTF_MAX_STR_OFFSET, btf->strs_data, btf->hdr.str_len); if (IS_ERR(set)) { err = PTR_ERR(set); goto err_out; @@ -1919,7 +1906,7 @@ static int btf_ensure_modifiable(struct btf *btf) /* only when everything was successful, update internal state */ btf->types_data = types; - btf->types_data_cap = btf->hdr->type_len; + btf->types_data_cap = btf->hdr.type_len; btf->strs_data = NULL; btf->strs_set = set; if (kind_layout) @@ -1927,9 +1914,9 @@ static int btf_ensure_modifiable(struct btf *btf) /* if BTF was created from scratch, all strings are guaranteed to be * unique and deduplicated */ - if (btf->hdr->str_len == 0) + if (btf->hdr.str_len == 0) btf->strs_deduped = true; - if (!btf->base_btf && btf->hdr->str_len == 1) + if (!btf->base_btf && btf->hdr.str_len == 1) btf->strs_deduped = true; /* invalidate raw_data representation */ @@ -1995,7 +1982,7 @@ int btf__add_str(struct btf *btf, const char *s) if (off < 0) return libbpf_err(off); - btf->hdr->str_len = strset__data_size(btf->strs_set); + btf->hdr.str_len = strset__data_size(btf->strs_set); return btf->start_str_off + off; } @@ -2003,7 +1990,7 @@ int btf__add_str(struct btf *btf, const char *s) static void *btf_add_type_mem(struct btf *btf, size_t add_sz) { return libbpf_add_mem(&btf->types_data, &btf->types_data_cap, 1, - btf->hdr->type_len, UINT_MAX, add_sz); + btf->hdr.type_len, UINT_MAX, add_sz); } static void btf_type_inc_vlen(struct btf_type *t) @@ -2013,28 +2000,28 @@ static void btf_type_inc_vlen(struct btf_type *t) static void btf_hdr_update_type_len(struct btf *btf, int new_len) { - btf->hdr->type_len = new_len; - btf->hdr->str_off = new_len; + btf->hdr.type_len = new_len; + btf->hdr.str_off = new_len; if (btf->kind_layout) - btf->hdr->kind_layout_off = btf->hdr->type_len + roundup(btf->hdr->str_len, 4); + btf->hdr.kind_layout_off = btf->hdr.type_len + roundup(btf->hdr.str_len, 4); } static void btf_hdr_update_str_len(struct btf *btf, int new_len) { - btf->hdr->str_len = new_len; + btf->hdr.str_len = new_len; if (btf->kind_layout) - btf->hdr->kind_layout_off = btf->hdr->type_len + roundup(new_len, 4); + btf->hdr.kind_layout_off = btf->hdr.type_len + roundup(new_len, 4); } static int btf_commit_type(struct btf *btf, int data_sz) { int err; - err = btf_add_type_idx_entry(btf, btf->hdr->type_len); + err = btf_add_type_idx_entry(btf, btf->hdr.type_len); if (err) return libbpf_err(err); - btf_hdr_update_type_len(btf, btf->hdr->type_len + data_sz); + btf_hdr_update_type_len(btf, btf->hdr.type_len + data_sz); btf->nr_types++; return btf->start_id + btf->nr_types - 1; } @@ -2138,9 +2125,9 @@ int btf__add_btf(struct btf *btf, const struct btf *src_btf) /* remember original strings section size if we have to roll back * partial strings section changes */ - old_strs_len = btf->hdr->str_len; + old_strs_len = btf->hdr.str_len; - data_sz = src_btf->hdr->type_len; + data_sz = src_btf->hdr.type_len; cnt = btf__type_cnt(src_btf) - 1; /* pre-allocate enough memory for new types */ @@ -2214,7 +2201,7 @@ int btf__add_btf(struct btf *btf, const struct btf *src_btf) * update type count and various internal offsets and sizes to * "commit" the changes and made them visible to the outside world. */ - btf_hdr_update_type_len(btf, btf->hdr->type_len + data_sz); + btf_hdr_update_type_len(btf, btf->hdr.type_len + data_sz); btf->nr_types += cnt; hashmap__free(p.str_off_map); @@ -2225,8 +2212,8 @@ int btf__add_btf(struct btf *btf, const struct btf *src_btf) /* zero out preallocated memory as if it was just allocated with * libbpf_add_mem() */ - memset(btf->types_data + btf->hdr->type_len, 0, data_sz); - memset(btf->strs_data + old_strs_len, 0, btf->hdr->str_len - old_strs_len); + memset(btf->types_data + btf->hdr.type_len, 0, data_sz); + memset(btf->strs_data + old_strs_len, 0, btf->hdr.str_len - old_strs_len); /* and now restore original strings section size; types data size * wasn't modified, so doesn't need restoring, see big comment above @@ -2549,7 +2536,7 @@ int btf__add_field(struct btf *btf, const char *name, int type_id, /* update parent type's vlen and kflag */ t->info = btf_type_info(btf_kind(t), btf_vlen(t) + 1, is_bitfield || btf_kflag(t)); - btf_hdr_update_type_len(btf, btf->hdr->type_len + sz); + btf_hdr_update_type_len(btf, btf->hdr.type_len + sz); return 0; } @@ -2658,7 +2645,7 @@ int btf__add_enum_value(struct btf *btf, const char *name, __s64 value) if (value < 0) t->info = btf_type_info(btf_kind(t), btf_vlen(t), true); - btf_hdr_update_type_len(btf, btf->hdr->type_len + sz); + btf_hdr_update_type_len(btf, btf->hdr.type_len + sz); return 0; } @@ -2729,7 +2716,7 @@ int btf__add_enum64_value(struct btf *btf, const char *name, __u64 value) t = btf_last_type(btf); btf_type_inc_vlen(t); - btf_hdr_update_type_len(btf, btf->hdr->type_len + sz); + btf_hdr_update_type_len(btf, btf->hdr.type_len + sz); return 0; } @@ -2967,7 +2954,7 @@ int btf__add_func_param(struct btf *btf, const char *name, int type_id) t = btf_last_type(btf); btf_type_inc_vlen(t); - btf_hdr_update_type_len(btf, btf->hdr->type_len + sz); + btf_hdr_update_type_len(btf, btf->hdr.type_len + sz); return 0; } @@ -3103,7 +3090,7 @@ int btf__add_datasec_var_info(struct btf *btf, int var_type_id, __u32 offset, __ t = btf_last_type(btf); btf_type_inc_vlen(t); - btf_hdr_update_type_len(btf, btf->hdr->type_len + sz); + btf_hdr_update_type_len(btf, btf->hdr.type_len + sz); return 0; } @@ -5514,18 +5501,18 @@ static int btf_dedup_compact_types(struct btf_dedup *d) /* shrink struct btf's internal types index and update btf_header */ d->btf->nr_types = next_type_id - d->btf->start_id; d->btf->type_offs_cap = d->btf->nr_types; - d->btf->hdr->type_len = p - d->btf->types_data; + d->btf->hdr.type_len = p - d->btf->types_data; new_offs = libbpf_reallocarray(d->btf->type_offs, d->btf->type_offs_cap, sizeof(*new_offs)); if (d->btf->type_offs_cap && !new_offs) return -ENOMEM; d->btf->type_offs = new_offs; - d->btf->hdr->str_off = d->btf->hdr->type_len; - d->btf->raw_size = d->btf->hdr->hdr_len + d->btf->hdr->type_len + d->btf->hdr->str_len; + d->btf->hdr.str_off = d->btf->hdr.type_len; + d->btf->raw_size = d->btf->hdr.hdr_len + d->btf->hdr.type_len + d->btf->hdr.str_len; if (d->btf->kind_layout) { - d->btf->hdr->kind_layout_off = d->btf->hdr->str_off + roundup(d->btf->hdr->str_len, + d->btf->hdr.kind_layout_off = d->btf->hdr.str_off + roundup(d->btf->hdr.str_len, 4); - d->btf->raw_size = roundup(d->btf->raw_size, 4) + d->btf->hdr->kind_layout_len; + d->btf->raw_size = roundup(d->btf->raw_size, 4) + d->btf->hdr.kind_layout_len; } return 0; } @@ -5984,7 +5971,7 @@ int btf__distill_base(const struct btf *src_btf, struct btf **new_base_btf, goto done; } dist.split_start_id = btf__type_cnt(old_base); - dist.split_start_str = old_base->hdr->str_len; + dist.split_start_str = old_base->hdr.str_len; /* Pass over src split BTF; generate the list of base BTF type ids it * references; these will constitute our distilled BTF set to be @@ -6053,14 +6040,14 @@ int btf__distill_base(const struct btf *src_btf, struct btf **new_base_btf, const struct btf_header *btf_header(const struct btf *btf) { - return btf->hdr; + return &btf->hdr; } void btf_set_base_btf(struct btf *btf, const struct btf *base_btf) { btf->base_btf = (struct btf *)base_btf; btf->start_id = btf__type_cnt(base_btf); - btf->start_str_off = base_btf->hdr->str_len + base_btf->start_str_off; + btf->start_str_off = base_btf->hdr.str_len + base_btf->start_str_off; } int btf__relocate(struct btf *btf, const struct btf *base_btf)