Skip to content

Commit b0f5206

Browse files
committed
libbpf: Introduce BTF_KIND_FLOAT
Some BPF programs compiled on s390 fail to load, because s390 arch-specific linux headers contain float and double types. Introduce support for such types to libbpf by representing them using the new BTF_KIND_FLOAT. Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
1 parent 0d415f6 commit b0f5206

File tree

5 files changed

+61
-5
lines changed

5 files changed

+61
-5
lines changed

.gitmodules

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
[submodule "lib/bpf"]
22
path = lib/bpf
3-
url = https://github.com/libbpf/libbpf
3+
url = https://github.com/iii-i/libbpf

btf_loader.c

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ static struct variable *variable__new(strings_t name, uint32_t linkage)
160160
return var;
161161
}
162162

163-
static int create_new_base_type(struct btf_elf *btfe, const struct btf_type *tp, uint32_t id)
163+
static int create_new_int_type(struct btf_elf *btfe, const struct btf_type *tp, uint32_t id)
164164
{
165165
uint32_t attrs = btf_int_encoding(tp);
166166
strings_t name = tp->name_off;
@@ -175,6 +175,20 @@ static int create_new_base_type(struct btf_elf *btfe, const struct btf_type *tp,
175175
return 0;
176176
}
177177

178+
static int create_new_float_type(struct btf_elf *btfe, const struct btf_type *tp, uint32_t id)
179+
{
180+
strings_t name = tp->name_off;
181+
struct base_type *base = base_type__new(name, 0, BT_FP_SINGLE, tp->size * 8);
182+
183+
if (base == NULL)
184+
return -ENOMEM;
185+
186+
base->tag.tag = DW_TAG_base_type;
187+
cu__add_tag_with_id(btfe->priv, &base->tag, id);
188+
189+
return 0;
190+
}
191+
178192
static int create_new_array(struct btf_elf *btfe, const struct btf_type *tp, uint32_t id)
179193
{
180194
struct btf_array *ap = btf_array(tp);
@@ -397,7 +411,7 @@ static int btf_elf__load_types(struct btf_elf *btfe)
397411

398412
switch (type) {
399413
case BTF_KIND_INT:
400-
err = create_new_base_type(btfe, type_ptr, type_index);
414+
err = create_new_int_type(btfe, type_ptr, type_index);
401415
break;
402416
case BTF_KIND_ARRAY:
403417
err = create_new_array(btfe, type_ptr, type_index);
@@ -442,6 +456,9 @@ static int btf_elf__load_types(struct btf_elf *btfe)
442456
// BTF_KIND_FUNC corresponding to a defined subprogram.
443457
err = create_new_function(btfe, type_ptr, type_index);
444458
break;
459+
case BTF_KIND_FLOAT:
460+
err = create_new_float_type(btfe, type_ptr, type_index);
461+
break;
445462
default:
446463
fprintf(stderr, "BTF: idx: %d, Unknown kind %d\n", type_index, type);
447464
fflush(stderr);

dwarf_loader.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,16 @@ static struct ptr_to_member_type *ptr_to_member_type__new(Dwarf_Die *die,
461461
return ptr;
462462
}
463463

464+
static uint8_t encoding_to_float_type(uint64_t encoding)
465+
{
466+
switch (encoding) {
467+
case DW_ATE_complex_float: return BT_FP_CMPLX;
468+
case DW_ATE_float: return BT_FP_SINGLE;
469+
case DW_ATE_imaginary_float: return BT_FP_IMGRY;
470+
default: return 0;
471+
}
472+
}
473+
464474
static struct base_type *base_type__new(Dwarf_Die *die, struct cu *cu)
465475
{
466476
struct base_type *bt = tag__alloc(cu, sizeof(*bt));
@@ -474,6 +484,7 @@ static struct base_type *base_type__new(Dwarf_Die *die, struct cu *cu)
474484
bt->is_signed = encoding == DW_ATE_signed;
475485
bt->is_varargs = false;
476486
bt->name_has_encoding = true;
487+
bt->float_type = encoding_to_float_type(encoding);
477488
}
478489

479490
return bt;

libbtf.c

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ static const char * const btf_kind_str[NR_BTF_KINDS] = {
227227
[BTF_KIND_FUNC_PROTO] = "FUNC_PROTO",
228228
[BTF_KIND_VAR] = "VAR",
229229
[BTF_KIND_DATASEC] = "DATASEC",
230+
[BTF_KIND_FLOAT] = "FLOAT",
230231
};
231232

232233
static const char *btf_elf__printable_name(const struct btf_elf *btfe, uint32_t offset)
@@ -367,6 +368,27 @@ static void btf_log_func_param(const struct btf_elf *btfe,
367368
}
368369
}
369370

371+
static int32_t btf_elf__add_float_type(struct btf_elf *btfe,
372+
const struct base_type *bt,
373+
const char *name)
374+
{
375+
int32_t id;
376+
377+
id = btf__add_float(btfe->btf, name, BITS_ROUNDUP_BYTES(bt->bit_size));
378+
if (id < 0) {
379+
btf_elf__log_err(btfe, BTF_KIND_FLOAT, name, true, "Error emitting BTF type");
380+
} else {
381+
const struct btf_type *t;
382+
383+
t = btf__type_by_id(btfe->btf, id);
384+
btf_elf__log_type(btfe, t, false, true,
385+
"size=%u nr_bits=%u",
386+
t->size, bt->bit_size);
387+
}
388+
389+
return id;
390+
}
391+
370392
int32_t btf_elf__add_base_type(struct btf_elf *btfe, const struct base_type *bt,
371393
const char *name)
372394
{
@@ -380,7 +402,11 @@ int32_t btf_elf__add_base_type(struct btf_elf *btfe, const struct base_type *bt,
380402
} else if (bt->is_bool) {
381403
encoding = BTF_INT_BOOL;
382404
} else if (bt->float_type) {
383-
fprintf(stderr, "float_type is not supported\n");
405+
if (bt->float_type == BT_FP_SINGLE ||
406+
bt->float_type == BT_FP_DOUBLE ||
407+
bt->float_type == BT_FP_LDBL)
408+
return btf_elf__add_float_type(btfe, bt, name);
409+
fprintf(stderr, "Complex, interval and imaginary float types are not supported\n");
384410
return -1;
385411
}
386412

@@ -820,6 +846,8 @@ int btf_elf__encode(struct btf_elf *btfe, uint8_t flags)
820846
{
821847
struct btf *btf = btfe->btf;
822848

849+
libbpf_set_print(libbpf_log);
850+
823851
/* Empty file, nothing to do, so... done! */
824852
if (btf__get_nr_types(btf) == 0)
825853
return 0;

0 commit comments

Comments
 (0)