mirror of
https://github.com/netdata/libbpf.git
synced 2026-11-05 17:30:15 +08:00
libbpf: Add support for BTF kinds LOC[_PARAM|_PROTO|SEC]
Add support for new kinds to libbpf. BTF_KIND_LOC_PARAM and BTF_KIND_LOC_PROTO are dedup-able so add support for their deduplication, whereas since BTF_KIND_LOCSEC contains a unique offset it is not. LOC_PARAM is considered a primary type since it contains no external references; LOC_PROTO is a reference type consisting of LOC_PARAM references so they are handled in the primary and reference dedup phases respectively. For BTF field iteration, BTF_KIND_LOCSEC needs 2 m_offs[] values for the associated KIND_FUNC and KIND_LOC_PROTO type ids in each LOCSEC entry. Add APIs to add location param, location prototypes and location sections and btf_is_* tests, data accessors for each. For BTF distillation we add location info to split BTF. Signed-off-by: Alan Maguire <alan.maguire@oracle.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Acked-by: Eduard Zingerman <eddyz87@gmail.com> Link: https://patch.msgid.link/20260924111428.75957-3-alan.maguire@oracle.com
This commit is contained in:
1 parent
d09ea52795
commit
b91d4d22cc
7 files changed
+491
-5
No files matched your search
@@ -57,6 +57,9 @@ static struct btf_layout layouts[NR_BTF_KINDS] = {
|
||||
[BTF_KIND_DECL_TAG] = { sizeof(struct btf_decl_tag), 0, 0 },
|
||||
[BTF_KIND_TYPE_TAG] = { 0, 0, 0 },
|
||||
[BTF_KIND_ENUM64] = { 0, sizeof(struct btf_enum64), 0 },
|
||||
[BTF_KIND_LOC_PARAM] = { sizeof(struct btf_loc_param), sizeof(__u32), 0 },
|
||||
[BTF_KIND_LOC_PROTO] = { 0, sizeof(__u32), 0 },
|
||||
[BTF_KIND_LOCSEC] = { 0, sizeof(struct btf_loc), 0 },
|
||||
};
|
||||
|
||||
struct btf {
|
||||
@@ -486,6 +489,12 @@ static int btf_type_size(const struct btf *btf, const struct btf_type *t)
|
||||
return base_size + vlen * sizeof(struct btf_var_secinfo);
|
||||
case BTF_KIND_DECL_TAG:
|
||||
return base_size + sizeof(struct btf_decl_tag);
|
||||
case BTF_KIND_LOC_PARAM:
|
||||
return base_size + sizeof(struct btf_loc_param) + vlen * sizeof(__u32);
|
||||
case BTF_KIND_LOC_PROTO:
|
||||
return base_size + vlen * sizeof(__u32);
|
||||
case BTF_KIND_LOCSEC:
|
||||
return base_size + vlen * sizeof(struct btf_loc);
|
||||
default:
|
||||
return btf_type_size_unknown(btf, t);
|
||||
}
|
||||
@@ -501,12 +510,15 @@ static void btf_bswap_type_base(struct btf_type *t)
|
||||
static int btf_bswap_type_rest(struct btf_type *t)
|
||||
{
|
||||
struct btf_var_secinfo *v;
|
||||
struct btf_loc_param *lp;
|
||||
struct btf_enum64 *e64;
|
||||
struct btf_member *m;
|
||||
struct btf_array *a;
|
||||
struct btf_param *p;
|
||||
struct btf_enum *e;
|
||||
struct btf_loc *l;
|
||||
__u32 vlen = btf_vlen(t);
|
||||
__u32 *d;
|
||||
int i;
|
||||
|
||||
switch (btf_kind(t)) {
|
||||
@@ -569,6 +581,23 @@ static int btf_bswap_type_rest(struct btf_type *t)
|
||||
case BTF_KIND_DECL_TAG:
|
||||
btf_decl_tag(t)->component_idx = bswap_32(btf_decl_tag(t)->component_idx);
|
||||
return 0;
|
||||
case BTF_KIND_LOC_PARAM:
|
||||
lp = btf_loc_param(t);
|
||||
lp->flags = bswap_32(lp->flags);
|
||||
for (i = 0, d = (__u32 *)(lp + 1); i < vlen; i++, d++)
|
||||
*d = bswap_32(*d);
|
||||
return 0;
|
||||
case BTF_KIND_LOC_PROTO:
|
||||
for (i = 0, d = btf_loc_proto_params(t); i < vlen; i++, d++)
|
||||
*d = bswap_32(*d);
|
||||
return 0;
|
||||
case BTF_KIND_LOCSEC:
|
||||
for (i = 0, l = btf_locsec_locs(t); i < vlen; i++, l++) {
|
||||
l->func = bswap_32(l->func);
|
||||
l->loc_proto = bswap_32(l->loc_proto);
|
||||
l->offset = bswap_32(l->offset);
|
||||
}
|
||||
return 0;
|
||||
default:
|
||||
pr_debug("Unsupported BTF_KIND:%u\n", btf_kind(t));
|
||||
return -EINVAL;
|
||||
@@ -745,6 +774,33 @@ static int btf_validate_type(const struct btf *btf, const struct btf_type *t, __
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BTF_KIND_LOC_PARAM:
|
||||
break;
|
||||
case BTF_KIND_LOC_PROTO: {
|
||||
__u32 *p = btf_loc_proto_params(t);
|
||||
|
||||
n = btf_vlen(t);
|
||||
for (i = 0; i < n; i++, p++) {
|
||||
err = btf_validate_id(btf, *p, id);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BTF_KIND_LOCSEC: {
|
||||
const struct btf_loc *l = btf_locsec_locs(t);
|
||||
|
||||
n = btf_vlen(t);
|
||||
for (i = 0; i < n; i++, l++) {
|
||||
if (!err)
|
||||
err = btf_validate_id(btf, l->func, id);
|
||||
if (!err)
|
||||
err = btf_validate_id(btf, l->loc_proto, id);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
/* Kind may be represented in kind layout information. */
|
||||
if (btf_type_size_unknown(btf, t) < 0) {
|
||||
@@ -3344,6 +3400,243 @@ int btf__add_decl_attr(struct btf *btf, const char *value, int ref_type_id,
|
||||
return btf_add_decl_tag(btf, value, ref_type_id, component_idx, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Append new BTF_KIND_LOC_PARAM with specified size and flags. Values are
|
||||
* added via btf__add_loc_param_value().
|
||||
*
|
||||
* - *byte_sz* - size of the type, in bytes (1 through 16);
|
||||
* - *flags* - combination of enum btf_loc_param_flags values
|
||||
*
|
||||
* Returns:
|
||||
* - >0, type ID of newly added BTF type;
|
||||
* - <0, on error.
|
||||
*/
|
||||
int btf__add_loc_param(struct btf *btf, __u32 byte_sz, __u32 flags)
|
||||
{
|
||||
struct btf_loc_param *p;
|
||||
struct btf_type *t;
|
||||
int sz, err;
|
||||
|
||||
if (!byte_sz || byte_sz > 16)
|
||||
return libbpf_err(-EINVAL);
|
||||
|
||||
err = btf_ensure_modifiable(btf);
|
||||
if (err)
|
||||
return libbpf_err(err);
|
||||
|
||||
sz = sizeof(struct btf_type) + sizeof(*p);
|
||||
t = btf_add_type_mem(btf, sz);
|
||||
if (!t)
|
||||
return libbpf_err(-ENOMEM);
|
||||
|
||||
t->name_off = 0;
|
||||
t->info = btf_type_info(BTF_KIND_LOC_PARAM, 0, 0);
|
||||
t->size = byte_sz;
|
||||
|
||||
p = btf_loc_param(t);
|
||||
p->flags = flags;
|
||||
|
||||
return btf_commit_type(btf, sz);
|
||||
}
|
||||
|
||||
/*
|
||||
* Append *value* to existing BTF_KIND_LOC_PARAM.
|
||||
*
|
||||
* Returns:
|
||||
* - 0 on success
|
||||
* - <0, on error.
|
||||
*/
|
||||
int btf__add_loc_param_value(struct btf *btf, __u32 value)
|
||||
{
|
||||
struct btf_type *t;
|
||||
int sz, err;
|
||||
__u32 *v;
|
||||
|
||||
/* last type should be BTF_KIND_LOC_PARAM */
|
||||
if (btf->nr_types == 0)
|
||||
return libbpf_err(-EINVAL);
|
||||
t = btf_last_type(btf);
|
||||
if (!btf_is_loc_param(t))
|
||||
return libbpf_err(-EINVAL);
|
||||
|
||||
/* decompose and invalidate raw data */
|
||||
err = btf_ensure_modifiable(btf);
|
||||
if (err)
|
||||
return libbpf_err(err);
|
||||
|
||||
sz = sizeof(value);
|
||||
v = btf_add_type_mem(btf, sz);
|
||||
if (!v)
|
||||
return libbpf_err(-ENOMEM);
|
||||
*v = value;
|
||||
|
||||
/* update parent type's vlen */
|
||||
t = btf_last_type(btf);
|
||||
err = btf_type_inc_vlen(t);
|
||||
if (err)
|
||||
return libbpf_err(err);
|
||||
|
||||
btf_hdr_update_type_len(btf, btf->hdr.type_len + sz);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Append new BTF_KIND_LOC_PROTO
|
||||
*
|
||||
* The prototype is then populated with 0 or more BTF_KIND_LOC_PARAMs via
|
||||
* btf__add_loc_proto_param(); similar to how btf__add_func_param() adds
|
||||
* parameters to a FUNC_PROTO.
|
||||
*
|
||||
* Returns:
|
||||
* - >0, type ID of newly added BTF type;
|
||||
* - <0, on error.
|
||||
*/
|
||||
int btf__add_loc_proto(struct btf *btf)
|
||||
{
|
||||
struct btf_type *t;
|
||||
int err;
|
||||
|
||||
err = btf_ensure_modifiable(btf);
|
||||
if (err)
|
||||
return libbpf_err(err);
|
||||
|
||||
t = btf_add_type_mem(btf, sizeof(struct btf_type));
|
||||
if (!t)
|
||||
return libbpf_err(-ENOMEM);
|
||||
|
||||
t->name_off = 0;
|
||||
t->info = btf_type_info(BTF_KIND_LOC_PROTO, 0, 0);
|
||||
t->size = 0;
|
||||
|
||||
return btf_commit_type(btf, sizeof(struct btf_type));
|
||||
}
|
||||
|
||||
/*
|
||||
* Append a BTF_KIND_LOC_PARAM id/0 to BTF_KIND_LOC_PROTO.
|
||||
*
|
||||
* Returns:
|
||||
* - 0 on success;
|
||||
* - <0, on error.
|
||||
|
||||
*/
|
||||
int btf__add_loc_proto_param(struct btf *btf, __u32 id)
|
||||
{
|
||||
struct btf_type *t;
|
||||
int sz, err;
|
||||
__u32 *p;
|
||||
|
||||
if (validate_type_id(id))
|
||||
return libbpf_err(-EINVAL);
|
||||
|
||||
/* last type should be BTF_KIND_LOC_PROTO */
|
||||
if (btf->nr_types == 0)
|
||||
return libbpf_err(-EINVAL);
|
||||
t = btf_last_type(btf);
|
||||
if (!btf_is_loc_proto(t))
|
||||
return libbpf_err(-EINVAL);
|
||||
|
||||
/* decompose and invalidate raw data */
|
||||
err = btf_ensure_modifiable(btf);
|
||||
if (err)
|
||||
return libbpf_err(err);
|
||||
|
||||
sz = sizeof(__u32);
|
||||
p = btf_add_type_mem(btf, sz);
|
||||
if (!p)
|
||||
return libbpf_err(-ENOMEM);
|
||||
*p = id;
|
||||
|
||||
/* update parent type's vlen */
|
||||
t = btf_last_type(btf);
|
||||
err = btf_type_inc_vlen(t);
|
||||
if (err)
|
||||
return libbpf_err(err);
|
||||
|
||||
btf_hdr_update_type_len(btf, btf->hdr.type_len + sz);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Append new BTF_KIND_LOCSEC type with:
|
||||
* - *name* - non-empty/non-NULL name;
|
||||
*
|
||||
* Location section is initially empty. Location info can be added with
|
||||
* btf__add_locsec_loc() calls, after btf__add_locsec() succeeds.
|
||||
*
|
||||
* Returns:
|
||||
* - >0, type ID of newly added BTF type;
|
||||
* - <0, on error.
|
||||
*/
|
||||
|
||||
int btf__add_locsec(struct btf *btf, const char *name)
|
||||
{
|
||||
struct btf_type *t;
|
||||
int name_off = 0;
|
||||
int err;
|
||||
|
||||
/* non-empty name */
|
||||
if (str_is_empty(name))
|
||||
return libbpf_err(-EINVAL);
|
||||
|
||||
err = btf_ensure_modifiable(btf);
|
||||
if (err)
|
||||
return libbpf_err(err);
|
||||
|
||||
t = btf_add_type_mem(btf, sizeof(struct btf_type));
|
||||
if (!t)
|
||||
return libbpf_err(-ENOMEM);
|
||||
|
||||
name_off = btf__add_str(btf, name);
|
||||
if (name_off < 0)
|
||||
return libbpf_err(name_off);
|
||||
t->name_off = name_off;
|
||||
t->info = btf_type_info(BTF_KIND_LOCSEC, 0, 0);
|
||||
t->size = 0;
|
||||
|
||||
return btf_commit_type(btf, sizeof(struct btf_type));
|
||||
}
|
||||
|
||||
int btf__add_locsec_loc(struct btf *btf, __u32 func, __u32 loc_proto,
|
||||
__u32 offset)
|
||||
{
|
||||
struct btf_type *t;
|
||||
struct btf_loc *l;
|
||||
int sz, err;
|
||||
|
||||
if (validate_type_id(func) || validate_type_id(loc_proto))
|
||||
return libbpf_err(-EINVAL);
|
||||
|
||||
/* last type should be BTF_KIND_LOCSEC */
|
||||
if (btf->nr_types == 0)
|
||||
return libbpf_err(-EINVAL);
|
||||
t = btf_last_type(btf);
|
||||
if (!btf_is_locsec(t))
|
||||
return libbpf_err(-EINVAL);
|
||||
|
||||
/* decompose and invalidate raw data */
|
||||
err = btf_ensure_modifiable(btf);
|
||||
if (err)
|
||||
return libbpf_err(err);
|
||||
|
||||
sz = sizeof(*l);
|
||||
l = btf_add_type_mem(btf, sz);
|
||||
if (!l)
|
||||
return libbpf_err(-ENOMEM);
|
||||
|
||||
l->func = func;
|
||||
l->loc_proto = loc_proto;
|
||||
l->offset = offset;
|
||||
|
||||
/* update parent type's vlen */
|
||||
t = btf_last_type(btf);
|
||||
err = btf_type_inc_vlen(t);
|
||||
if (err)
|
||||
return libbpf_err(err);
|
||||
|
||||
btf_hdr_update_type_len(btf, btf->hdr.type_len + sz);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct btf_ext_sec_info_param {
|
||||
__u32 off;
|
||||
__u32 len;
|
||||
@@ -4114,8 +4407,8 @@ static struct btf_dedup *btf_dedup_new(struct btf *btf, const struct btf_dedup_o
|
||||
for (i = 1; i < type_cnt; i++) {
|
||||
struct btf_type *t = btf_type_by_id(d->btf, i);
|
||||
|
||||
/* VAR and DATASEC are never deduped and are self-canonical */
|
||||
if (btf_is_var(t) || btf_is_datasec(t))
|
||||
/* VAR, DATASEC and LOCSEC are never deduped and are self-canonical */
|
||||
if (btf_is_var(t) || btf_is_datasec(t) || btf_is_locsec(t))
|
||||
d->map[i] = i;
|
||||
else
|
||||
d->map[i] = BTF_UNPROCESSED_ID;
|
||||
@@ -4395,6 +4688,47 @@ static bool btf_compat_enum(struct btf_type *t1, struct btf_type *t2)
|
||||
btf_is_any_enum(t1) && btf_is_any_enum(t2);
|
||||
}
|
||||
|
||||
static long btf_hash_loc_param(struct btf_type *t)
|
||||
{
|
||||
struct btf_loc_param *p = btf_loc_param(t);
|
||||
long h = btf_hash_common(t);
|
||||
int i, vlen = btf_vlen(t);
|
||||
|
||||
h = hash_combine(h, p->flags);
|
||||
|
||||
for (i = 0; i < vlen; i++)
|
||||
h = hash_combine(h, p->values[i]);
|
||||
return h;
|
||||
}
|
||||
|
||||
static long btf_hash_loc_proto(struct btf_type *t)
|
||||
{
|
||||
__u32 *p = btf_loc_proto_params(t);
|
||||
long h = btf_hash_common(t);
|
||||
int i, vlen = btf_vlen(t);
|
||||
|
||||
for (i = 0; i < vlen; i++, p++)
|
||||
h = hash_combine(h, *p);
|
||||
return h;
|
||||
}
|
||||
|
||||
static bool btf_equal_loc_param(struct btf_type *t1, struct btf_type *t2)
|
||||
{
|
||||
struct btf_loc_param *p1 = btf_loc_param(t1);
|
||||
struct btf_loc_param *p2 = btf_loc_param(t2);
|
||||
int i, vlen = btf_vlen(t1);
|
||||
|
||||
if (!btf_equal_common(t1, t2))
|
||||
return false;
|
||||
if (p1->flags != p2->flags)
|
||||
return false;
|
||||
for (i = 0; i < vlen; i++) {
|
||||
if (p1->values[i] != p2->values[i])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate type signature hash of STRUCT/UNION, ignoring referenced type IDs,
|
||||
* as referenced type IDs equivalence is established separately during type
|
||||
@@ -4589,7 +4923,8 @@ static int btf_dedup_prep(struct btf_dedup *d)
|
||||
switch (btf_kind(t)) {
|
||||
case BTF_KIND_VAR:
|
||||
case BTF_KIND_DATASEC:
|
||||
/* VAR and DATASEC are never hash/deduplicated */
|
||||
case BTF_KIND_LOCSEC:
|
||||
/* VAR DATASEC and LOCSEC are never hash/deduplicated */
|
||||
continue;
|
||||
case BTF_KIND_CONST:
|
||||
case BTF_KIND_VOLATILE:
|
||||
@@ -4622,6 +4957,12 @@ static int btf_dedup_prep(struct btf_dedup *d)
|
||||
case BTF_KIND_FUNC_PROTO:
|
||||
h = btf_hash_fnproto(t);
|
||||
break;
|
||||
case BTF_KIND_LOC_PARAM:
|
||||
h = btf_hash_loc_param(t);
|
||||
break;
|
||||
case BTF_KIND_LOC_PROTO:
|
||||
h = btf_hash_loc_proto(t);
|
||||
break;
|
||||
default:
|
||||
pr_debug("unknown kind %d for type [%d]\n", btf_kind(t), type_id);
|
||||
return -EINVAL;
|
||||
@@ -4664,6 +5005,8 @@ static int btf_dedup_prim_type(struct btf_dedup *d, __u32 type_id)
|
||||
case BTF_KIND_DATASEC:
|
||||
case BTF_KIND_DECL_TAG:
|
||||
case BTF_KIND_TYPE_TAG:
|
||||
case BTF_KIND_LOC_PROTO:
|
||||
case BTF_KIND_LOCSEC:
|
||||
return 0;
|
||||
|
||||
case BTF_KIND_INT:
|
||||
@@ -4713,6 +5056,18 @@ static int btf_dedup_prim_type(struct btf_dedup *d, __u32 type_id)
|
||||
}
|
||||
break;
|
||||
|
||||
case BTF_KIND_LOC_PARAM:
|
||||
h = btf_hash_loc_param(t);
|
||||
for_each_dedup_cand(d, hash_entry, h) {
|
||||
cand_id = hash_entry->value;
|
||||
cand = btf_type_by_id(d->btf, cand_id);
|
||||
if (btf_equal_loc_param(t, cand)) {
|
||||
new_id = cand_id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -5145,6 +5500,13 @@ static int btf_dedup_is_equiv(struct btf_dedup *d, __u32 cand_id,
|
||||
return 1;
|
||||
}
|
||||
|
||||
case BTF_KIND_LOC_PARAM:
|
||||
return btf_equal_loc_param(cand_type, canon_type);
|
||||
|
||||
case BTF_KIND_LOC_PROTO:
|
||||
case BTF_KIND_LOCSEC:
|
||||
return 0;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -5489,6 +5851,37 @@ static int btf_dedup_ref_type(struct btf_dedup *d, __u32 type_id)
|
||||
break;
|
||||
}
|
||||
|
||||
case BTF_KIND_LOC_PROTO: {
|
||||
__u32 *p1, *p2;
|
||||
__u32 i, vlen;
|
||||
|
||||
p1 = btf_loc_proto_params(t);
|
||||
vlen = btf_vlen(t);
|
||||
|
||||
for (i = 0; i < vlen; i++, p1++) {
|
||||
ref_type_id = btf_dedup_ref_type(d, *p1);
|
||||
if (ref_type_id < 0)
|
||||
return ref_type_id;
|
||||
*p1 = ref_type_id;
|
||||
}
|
||||
|
||||
h = btf_hash_loc_proto(t);
|
||||
for_each_dedup_cand(d, hash_entry, h) {
|
||||
cand_id = hash_entry->value;
|
||||
cand = btf_type_by_id(d->btf, cand_id);
|
||||
if (!btf_equal_common(t, cand))
|
||||
continue;
|
||||
vlen = btf_vlen(cand);
|
||||
p1 = btf_loc_proto_params(t);
|
||||
p2 = btf_loc_proto_params(cand);
|
||||
if (memcmp(p1, p2, vlen * sizeof(__u32)) == 0) {
|
||||
new_id = cand_id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -5970,8 +6363,11 @@ static int btf_add_distilled_type_ids(struct btf_distill *dist, __u32 i)
|
||||
case BTF_KIND_CONST:
|
||||
case BTF_KIND_RESTRICT:
|
||||
case BTF_KIND_VOLATILE:
|
||||
case BTF_KIND_FUNC:
|
||||
case BTF_KIND_FUNC_PROTO:
|
||||
case BTF_KIND_TYPE_TAG:
|
||||
case BTF_KIND_LOC_PARAM:
|
||||
case BTF_KIND_LOC_PROTO:
|
||||
dist->id_map[*id] = *id;
|
||||
break;
|
||||
default:
|
||||
@@ -5997,7 +6393,7 @@ static int btf_add_distilled_type_ids(struct btf_distill *dist, __u32 i)
|
||||
|
||||
static int btf_add_distilled_types(struct btf_distill *dist)
|
||||
{
|
||||
bool adding_to_base = dist->pipe.dst->start_id == 1;
|
||||
bool adding_to_base = dist->pipe.dst->base_btf == NULL;
|
||||
int id = btf__type_cnt(dist->pipe.dst);
|
||||
struct btf_type *t;
|
||||
int i, err = 0;
|
||||
@@ -6065,8 +6461,12 @@ static int btf_add_distilled_types(struct btf_distill *dist)
|
||||
case BTF_KIND_CONST:
|
||||
case BTF_KIND_RESTRICT:
|
||||
case BTF_KIND_VOLATILE:
|
||||
case BTF_KIND_FUNC:
|
||||
case BTF_KIND_FUNC_PROTO:
|
||||
case BTF_KIND_TYPE_TAG:
|
||||
case BTF_KIND_LOC_PARAM:
|
||||
case BTF_KIND_LOC_PROTO:
|
||||
case BTF_KIND_LOCSEC:
|
||||
/* All other types are added to split BTF. */
|
||||
if (adding_to_base)
|
||||
continue;
|
||||
|
||||
@@ -274,6 +274,20 @@ LIBBPF_API int btf__add_decl_tag(struct btf *btf, const char *value, int ref_typ
|
||||
LIBBPF_API int btf__add_decl_attr(struct btf *btf, const char *value, int ref_type_id,
|
||||
int component_idx);
|
||||
|
||||
/* location construction APIs */
|
||||
LIBBPF_API int btf__add_loc_param(struct btf *btf, __u32 size, __u32 flags);
|
||||
|
||||
LIBBPF_API int btf__add_loc_param_value(struct btf *btf, __u32 value);
|
||||
|
||||
LIBBPF_API int btf__add_loc_proto(struct btf *btf);
|
||||
|
||||
LIBBPF_API int btf__add_loc_proto_param(struct btf *btf, __u32 id);
|
||||
|
||||
LIBBPF_API int btf__add_locsec(struct btf *btf, const char *name);
|
||||
|
||||
LIBBPF_API int btf__add_locsec_loc(struct btf *btf, __u32 func, __u32 loc_proto,
|
||||
__u32 offset);
|
||||
|
||||
struct btf_dedup_opts {
|
||||
size_t sz;
|
||||
/* optional .BTF.ext info to dedup along the main BTF info */
|
||||
@@ -431,6 +445,12 @@ btf_dump__dump_type_data(struct btf_dump *d, __u32 id,
|
||||
#define BTF_KIND_DECL_TAG 17 /* Decl Tag */
|
||||
#define BTF_KIND_TYPE_TAG 18 /* Type Tag */
|
||||
#define BTF_KIND_ENUM64 19 /* Enum for up-to 64bit values */
|
||||
#define BTF_KIND_LOC_PARAM 20 /* Parameter at location */
|
||||
#define BTF_KIND_LOC_PROTO 21 /* Parameter set at location */
|
||||
#define BTF_KIND_LOCSEC 22 /* Section containing location info */
|
||||
|
||||
struct btf_loc_param;
|
||||
struct btf_loc;
|
||||
|
||||
static inline __u16 btf_kind(const struct btf_type *t)
|
||||
{
|
||||
@@ -569,6 +589,21 @@ static inline bool btf_is_any_enum(const struct btf_type *t)
|
||||
return btf_is_enum(t) || btf_is_enum64(t);
|
||||
}
|
||||
|
||||
static inline bool btf_is_loc_param(const struct btf_type *t)
|
||||
{
|
||||
return btf_kind(t) == BTF_KIND_LOC_PARAM;
|
||||
}
|
||||
|
||||
static inline bool btf_is_loc_proto(const struct btf_type *t)
|
||||
{
|
||||
return btf_kind(t) == BTF_KIND_LOC_PROTO;
|
||||
}
|
||||
|
||||
static inline bool btf_is_locsec(const struct btf_type *t)
|
||||
{
|
||||
return btf_kind(t) == BTF_KIND_LOCSEC;
|
||||
}
|
||||
|
||||
static inline bool btf_kind_core_compat(const struct btf_type *t1,
|
||||
const struct btf_type *t2)
|
||||
{
|
||||
@@ -683,6 +718,21 @@ static inline struct btf_decl_tag *btf_decl_tag(const struct btf_type *t)
|
||||
return (struct btf_decl_tag *)(t + 1);
|
||||
}
|
||||
|
||||
static inline struct btf_loc_param *btf_loc_param(const struct btf_type *t)
|
||||
{
|
||||
return (struct btf_loc_param *)(t + 1);
|
||||
}
|
||||
|
||||
static inline __u32 *btf_loc_proto_params(const struct btf_type *t)
|
||||
{
|
||||
return (__u32 *)(t + 1);
|
||||
}
|
||||
|
||||
static inline struct btf_loc *btf_locsec_locs(const struct btf_type *t)
|
||||
{
|
||||
return (struct btf_loc *)(t + 1);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
@@ -328,6 +328,9 @@ static int btf_dump_mark_referenced(struct btf_dump *d)
|
||||
case BTF_KIND_ENUM64:
|
||||
case BTF_KIND_FWD:
|
||||
case BTF_KIND_FLOAT:
|
||||
case BTF_KIND_LOC_PARAM:
|
||||
case BTF_KIND_LOC_PROTO:
|
||||
case BTF_KIND_LOCSEC:
|
||||
break;
|
||||
|
||||
case BTF_KIND_VOLATILE:
|
||||
@@ -609,6 +612,9 @@ static int btf_dump_order_type(struct btf_dump *d, __u32 id, bool through_ptr)
|
||||
case BTF_KIND_VAR:
|
||||
case BTF_KIND_DATASEC:
|
||||
case BTF_KIND_DECL_TAG:
|
||||
case BTF_KIND_LOC_PARAM:
|
||||
case BTF_KIND_LOC_PROTO:
|
||||
case BTF_KIND_LOCSEC:
|
||||
d->type_states[id].order_state = ORDERED;
|
||||
return 0;
|
||||
|
||||
@@ -2525,6 +2531,9 @@ static int btf_dump_dump_type_data(struct btf_dump *d,
|
||||
case BTF_KIND_FUNC:
|
||||
case BTF_KIND_FUNC_PROTO:
|
||||
case BTF_KIND_DECL_TAG:
|
||||
case BTF_KIND_LOC_PARAM:
|
||||
case BTF_KIND_LOC_PROTO:
|
||||
case BTF_KIND_LOCSEC:
|
||||
err = btf_dump_unsupported_data(d, t, id);
|
||||
break;
|
||||
case BTF_KIND_INT:
|
||||
|
||||
@@ -29,6 +29,7 @@ int btf_field_iter_init(struct btf_field_iter *it, struct btf_type *t,
|
||||
case BTF_KIND_FLOAT:
|
||||
case BTF_KIND_ENUM:
|
||||
case BTF_KIND_ENUM64:
|
||||
case BTF_KIND_LOC_PARAM:
|
||||
it->desc = (struct btf_field_desc) {};
|
||||
break;
|
||||
case BTF_KIND_FWD:
|
||||
@@ -71,6 +72,20 @@ int btf_field_iter_init(struct btf_field_iter *it, struct btf_type *t,
|
||||
1, {offsetof(struct btf_var_secinfo, type)}
|
||||
};
|
||||
break;
|
||||
case BTF_KIND_LOC_PROTO:
|
||||
it->desc = (struct btf_field_desc) {
|
||||
0, {},
|
||||
sizeof(__u32),
|
||||
1, {0}};
|
||||
break;
|
||||
case BTF_KIND_LOCSEC:
|
||||
it->desc = (struct btf_field_desc) {
|
||||
0, {},
|
||||
sizeof(struct btf_loc),
|
||||
2, {offsetof(struct btf_loc, func),
|
||||
offsetof(struct btf_loc, loc_proto)}};
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -94,6 +109,9 @@ int btf_field_iter_init(struct btf_field_iter *it, struct btf_type *t,
|
||||
case BTF_KIND_DECL_TAG:
|
||||
case BTF_KIND_TYPE_TAG:
|
||||
case BTF_KIND_DATASEC:
|
||||
case BTF_KIND_LOC_PARAM:
|
||||
case BTF_KIND_LOC_PROTO:
|
||||
case BTF_KIND_LOCSEC:
|
||||
it->desc = (struct btf_field_desc) {
|
||||
1, {offsetof(struct btf_type, name_off)}
|
||||
};
|
||||
|
||||
@@ -2524,6 +2524,9 @@ static const char *__btf_kind_str(__u16 kind)
|
||||
case BTF_KIND_DECL_TAG: return "decl_tag";
|
||||
case BTF_KIND_TYPE_TAG: return "type_tag";
|
||||
case BTF_KIND_ENUM64: return "enum64";
|
||||
case BTF_KIND_LOC_PARAM: return "loc_param";
|
||||
case BTF_KIND_LOC_PROTO: return "loc_proto";
|
||||
case BTF_KIND_LOCSEC: return "locsec";
|
||||
default: return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -463,6 +463,12 @@ LIBBPF_1.8.0 {
|
||||
bpf_program__attach_tracing_multi;
|
||||
bpf_program__clear_flags;
|
||||
bpf_program__clone;
|
||||
btf__add_loc_param;
|
||||
btf__add_loc_param_value;
|
||||
btf__add_loc_proto;
|
||||
btf__add_loc_proto_param;
|
||||
btf__add_locsec;
|
||||
btf__add_locsec_loc;
|
||||
btf__find_by_name_kind_own;
|
||||
btf__new_empty_opts;
|
||||
} LIBBPF_1.7.0;
|
||||
@@ -580,7 +580,7 @@ struct btf_field_desc {
|
||||
/* member struct size, or zero, if no members */
|
||||
int m_sz;
|
||||
/* repeated per-member offsets */
|
||||
int m_off_cnt, m_offs[1];
|
||||
int m_off_cnt, m_offs[2];
|
||||
};
|
||||
|
||||
struct btf_field_iter {
|
||||
|
||||
Reference in new issue
Block a user