Skip to content

Commit 22541a9

Browse files
iii-iAlexei Starovoitov
authored andcommitted
libbpf: Add BTF_KIND_FLOAT support
The logic follows that of BTF_KIND_INT most of the time. Sanitization replaces BTF_KIND_FLOATs with equally-sized empty BTF_KIND_STRUCTs on older kernels, for example, the following: [4] FLOAT 'float' size=4 becomes the following: [4] STRUCT '(anon)' size=4 vlen=0 With dwarves patch [1] and this patch, the older kernels, which were failing with the floating-point-related errors, will now start working correctly. [1] iii-i/dwarves@btf-kind-float-v2 Signed-off-by: Ilya Leoshkevich <[email protected]> Signed-off-by: Alexei Starovoitov <[email protected]> Acked-by: Andrii Nakryiko <[email protected]> Link: https://lore.kernel.org/bpf/[email protected]
1 parent 1b1ce92 commit 22541a9

File tree

6 files changed

+94
-1
lines changed

6 files changed

+94
-1
lines changed

tools/lib/bpf/btf.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,7 @@ static int btf_type_size(const struct btf_type *t)
291291
case BTF_KIND_PTR:
292292
case BTF_KIND_TYPEDEF:
293293
case BTF_KIND_FUNC:
294+
case BTF_KIND_FLOAT:
294295
return base_size;
295296
case BTF_KIND_INT:
296297
return base_size + sizeof(__u32);
@@ -338,6 +339,7 @@ static int btf_bswap_type_rest(struct btf_type *t)
338339
case BTF_KIND_PTR:
339340
case BTF_KIND_TYPEDEF:
340341
case BTF_KIND_FUNC:
342+
case BTF_KIND_FLOAT:
341343
return 0;
342344
case BTF_KIND_INT:
343345
*(__u32 *)(t + 1) = bswap_32(*(__u32 *)(t + 1));
@@ -578,6 +580,7 @@ __s64 btf__resolve_size(const struct btf *btf, __u32 type_id)
578580
case BTF_KIND_UNION:
579581
case BTF_KIND_ENUM:
580582
case BTF_KIND_DATASEC:
583+
case BTF_KIND_FLOAT:
581584
size = t->size;
582585
goto done;
583586
case BTF_KIND_PTR:
@@ -621,6 +624,7 @@ int btf__align_of(const struct btf *btf, __u32 id)
621624
switch (kind) {
622625
case BTF_KIND_INT:
623626
case BTF_KIND_ENUM:
627+
case BTF_KIND_FLOAT:
624628
return min(btf_ptr_sz(btf), (size_t)t->size);
625629
case BTF_KIND_PTR:
626630
return btf_ptr_sz(btf);
@@ -1756,6 +1760,47 @@ int btf__add_int(struct btf *btf, const char *name, size_t byte_sz, int encoding
17561760
return btf_commit_type(btf, sz);
17571761
}
17581762

1763+
/*
1764+
* Append new BTF_KIND_FLOAT type with:
1765+
* - *name* - non-empty, non-NULL type name;
1766+
* - *sz* - size of the type, in bytes;
1767+
* Returns:
1768+
* - >0, type ID of newly added BTF type;
1769+
* - <0, on error.
1770+
*/
1771+
int btf__add_float(struct btf *btf, const char *name, size_t byte_sz)
1772+
{
1773+
struct btf_type *t;
1774+
int sz, name_off;
1775+
1776+
/* non-empty name */
1777+
if (!name || !name[0])
1778+
return -EINVAL;
1779+
1780+
/* byte_sz must be one of the explicitly allowed values */
1781+
if (byte_sz != 2 && byte_sz != 4 && byte_sz != 8 && byte_sz != 12 &&
1782+
byte_sz != 16)
1783+
return -EINVAL;
1784+
1785+
if (btf_ensure_modifiable(btf))
1786+
return -ENOMEM;
1787+
1788+
sz = sizeof(struct btf_type);
1789+
t = btf_add_type_mem(btf, sz);
1790+
if (!t)
1791+
return -ENOMEM;
1792+
1793+
name_off = btf__add_str(btf, name);
1794+
if (name_off < 0)
1795+
return name_off;
1796+
1797+
t->name_off = name_off;
1798+
t->info = btf_type_info(BTF_KIND_FLOAT, 0, 0);
1799+
t->size = byte_sz;
1800+
1801+
return btf_commit_type(btf, sz);
1802+
}
1803+
17591804
/* it's completely legal to append BTF types with type IDs pointing forward to
17601805
* types that haven't been appended yet, so we only make sure that id looks
17611806
* sane, we can't guarantee that ID will always be valid
@@ -3626,6 +3671,7 @@ static int btf_dedup_prep(struct btf_dedup *d)
36263671
case BTF_KIND_FWD:
36273672
case BTF_KIND_TYPEDEF:
36283673
case BTF_KIND_FUNC:
3674+
case BTF_KIND_FLOAT:
36293675
h = btf_hash_common(t);
36303676
break;
36313677
case BTF_KIND_INT:
@@ -3722,6 +3768,7 @@ static int btf_dedup_prim_type(struct btf_dedup *d, __u32 type_id)
37223768
break;
37233769

37243770
case BTF_KIND_FWD:
3771+
case BTF_KIND_FLOAT:
37253772
h = btf_hash_common(t);
37263773
for_each_dedup_cand(d, hash_entry, h) {
37273774
cand_id = (__u32)(long)hash_entry->value;
@@ -3983,6 +4030,7 @@ static int btf_dedup_is_equiv(struct btf_dedup *d, __u32 cand_id,
39834030
return btf_compat_enum(cand_type, canon_type);
39844031

39854032
case BTF_KIND_FWD:
4033+
case BTF_KIND_FLOAT:
39864034
return btf_equal_common(cand_type, canon_type);
39874035

39884036
case BTF_KIND_CONST:
@@ -4479,6 +4527,7 @@ static int btf_dedup_remap_type(struct btf_dedup *d, __u32 type_id)
44794527
switch (btf_kind(t)) {
44804528
case BTF_KIND_INT:
44814529
case BTF_KIND_ENUM:
4530+
case BTF_KIND_FLOAT:
44824531
break;
44834532

44844533
case BTF_KIND_FWD:

tools/lib/bpf/btf.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ LIBBPF_API int btf__find_str(struct btf *btf, const char *s);
9595
LIBBPF_API int btf__add_str(struct btf *btf, const char *s);
9696

9797
LIBBPF_API int btf__add_int(struct btf *btf, const char *name, size_t byte_sz, int encoding);
98+
LIBBPF_API int btf__add_float(struct btf *btf, const char *name, size_t byte_sz);
9899
LIBBPF_API int btf__add_ptr(struct btf *btf, int ref_type_id);
99100
LIBBPF_API int btf__add_array(struct btf *btf,
100101
int index_type_id, int elem_type_id, __u32 nr_elems);
@@ -294,6 +295,11 @@ static inline bool btf_is_datasec(const struct btf_type *t)
294295
return btf_kind(t) == BTF_KIND_DATASEC;
295296
}
296297

298+
static inline bool btf_is_float(const struct btf_type *t)
299+
{
300+
return btf_kind(t) == BTF_KIND_FLOAT;
301+
}
302+
297303
static inline __u8 btf_int_encoding(const struct btf_type *t)
298304
{
299305
return BTF_INT_ENCODING(*(__u32 *)(t + 1));

tools/lib/bpf/btf_dump.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,7 @@ static int btf_dump_mark_referenced(struct btf_dump *d)
279279
case BTF_KIND_INT:
280280
case BTF_KIND_ENUM:
281281
case BTF_KIND_FWD:
282+
case BTF_KIND_FLOAT:
282283
break;
283284

284285
case BTF_KIND_VOLATILE:
@@ -453,6 +454,7 @@ static int btf_dump_order_type(struct btf_dump *d, __u32 id, bool through_ptr)
453454

454455
switch (btf_kind(t)) {
455456
case BTF_KIND_INT:
457+
case BTF_KIND_FLOAT:
456458
tstate->order_state = ORDERED;
457459
return 0;
458460

@@ -1133,6 +1135,7 @@ static void btf_dump_emit_type_decl(struct btf_dump *d, __u32 id,
11331135
case BTF_KIND_STRUCT:
11341136
case BTF_KIND_UNION:
11351137
case BTF_KIND_TYPEDEF:
1138+
case BTF_KIND_FLOAT:
11361139
goto done;
11371140
default:
11381141
pr_warn("unexpected type in decl chain, kind:%u, id:[%u]\n",
@@ -1247,6 +1250,7 @@ static void btf_dump_emit_type_chain(struct btf_dump *d,
12471250

12481251
switch (kind) {
12491252
case BTF_KIND_INT:
1253+
case BTF_KIND_FLOAT:
12501254
btf_dump_emit_mods(d, decls);
12511255
name = btf_name_of(d, t->name_off);
12521256
btf_dump_printf(d, "%s", name);

tools/lib/bpf/libbpf.c

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,8 @@ enum kern_feature_id {
178178
FEAT_PROG_BIND_MAP,
179179
/* Kernel support for module BTFs */
180180
FEAT_MODULE_BTF,
181+
/* BTF_KIND_FLOAT support */
182+
FEAT_BTF_FLOAT,
181183
__FEAT_CNT,
182184
};
183185

@@ -1946,6 +1948,7 @@ static const char *btf_kind_str(const struct btf_type *t)
19461948
case BTF_KIND_FUNC_PROTO: return "func_proto";
19471949
case BTF_KIND_VAR: return "var";
19481950
case BTF_KIND_DATASEC: return "datasec";
1951+
case BTF_KIND_FLOAT: return "float";
19491952
default: return "unknown";
19501953
}
19511954
}
@@ -2395,15 +2398,17 @@ static bool btf_needs_sanitization(struct bpf_object *obj)
23952398
{
23962399
bool has_func_global = kernel_supports(FEAT_BTF_GLOBAL_FUNC);
23972400
bool has_datasec = kernel_supports(FEAT_BTF_DATASEC);
2401+
bool has_float = kernel_supports(FEAT_BTF_FLOAT);
23982402
bool has_func = kernel_supports(FEAT_BTF_FUNC);
23992403

2400-
return !has_func || !has_datasec || !has_func_global;
2404+
return !has_func || !has_datasec || !has_func_global || !has_float;
24012405
}
24022406

24032407
static void bpf_object__sanitize_btf(struct bpf_object *obj, struct btf *btf)
24042408
{
24052409
bool has_func_global = kernel_supports(FEAT_BTF_GLOBAL_FUNC);
24062410
bool has_datasec = kernel_supports(FEAT_BTF_DATASEC);
2411+
bool has_float = kernel_supports(FEAT_BTF_FLOAT);
24072412
bool has_func = kernel_supports(FEAT_BTF_FUNC);
24082413
struct btf_type *t;
24092414
int i, j, vlen;
@@ -2456,6 +2461,13 @@ static void bpf_object__sanitize_btf(struct bpf_object *obj, struct btf *btf)
24562461
} else if (!has_func_global && btf_is_func(t)) {
24572462
/* replace BTF_FUNC_GLOBAL with BTF_FUNC_STATIC */
24582463
t->info = BTF_INFO_ENC(BTF_KIND_FUNC, 0, 0);
2464+
} else if (!has_float && btf_is_float(t)) {
2465+
/* replace FLOAT with an equally-sized empty STRUCT;
2466+
* since C compilers do not accept e.g. "float" as a
2467+
* valid struct name, make it anonymous
2468+
*/
2469+
t->name_off = 0;
2470+
t->info = BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 0);
24592471
}
24602472
}
24612473
}
@@ -3927,6 +3939,18 @@ static int probe_kern_btf_datasec(void)
39273939
strs, sizeof(strs)));
39283940
}
39293941

3942+
static int probe_kern_btf_float(void)
3943+
{
3944+
static const char strs[] = "\0float";
3945+
__u32 types[] = {
3946+
/* float */
3947+
BTF_TYPE_FLOAT_ENC(1, 4),
3948+
};
3949+
3950+
return probe_fd(libbpf__load_raw_btf((char *)types, sizeof(types),
3951+
strs, sizeof(strs)));
3952+
}
3953+
39303954
static int probe_kern_array_mmap(void)
39313955
{
39323956
struct bpf_create_map_attr attr = {
@@ -4106,6 +4130,9 @@ static struct kern_feature_desc {
41064130
[FEAT_MODULE_BTF] = {
41074131
"module BTF support", probe_module_btf,
41084132
},
4133+
[FEAT_BTF_FLOAT] = {
4134+
"BTF_KIND_FLOAT support", probe_kern_btf_float,
4135+
},
41094136
};
41104137

41114138
static bool kernel_supports(enum kern_feature_id feat_id)

tools/lib/bpf/libbpf.map

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,3 +350,8 @@ LIBBPF_0.3.0 {
350350
xsk_setup_xdp_prog;
351351
xsk_socket__update_xskmap;
352352
} LIBBPF_0.2.0;
353+
354+
LIBBPF_0.4.0 {
355+
global:
356+
btf__add_float;
357+
} LIBBPF_0.3.0;

tools/lib/bpf/libbpf_internal.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
#define BTF_MEMBER_ENC(name, type, bits_offset) (name), (type), (bits_offset)
3232
#define BTF_PARAM_ENC(name, type) (name), (type)
3333
#define BTF_VAR_SECINFO_ENC(type, offset, size) (type), (offset), (size)
34+
#define BTF_TYPE_FLOAT_ENC(name, sz) \
35+
BTF_TYPE_ENC(name, BTF_INFO_ENC(BTF_KIND_FLOAT, 0, 0), sz)
3436

3537
#ifndef likely
3638
#define likely(x) __builtin_expect(!!(x), 1)

0 commit comments

Comments
 (0)