diff --git a/dwarf_loader.c b/dwarf_loader.c index b73d7867e1e6..aba14679a07e 100644 --- a/dwarf_loader.c +++ b/dwarf_loader.c @@ -467,8 +467,15 @@ static struct base_type *base_type__new(Dwarf_Die *die, struct cu *cu) if (bt != NULL) { tag__init(&bt->tag, cu, die); - bt->name = strings__add(strings, attr_string(die, DW_AT_name)); - bt->bit_size = attr_numeric(die, DW_AT_byte_size) * 8; + const char *name = attr_string(die, DW_AT_name); + bt->name = strings__add(strings, name); + /* DW_ATE_unsigned_1 has DW_AT_byte_size == 0. + * specially process it. + */ + if (strcmp(name, "DW_ATE_unsigned_1") == 0) + bt->bit_size = 1; + else + bt->bit_size = attr_numeric(die, DW_AT_byte_size) * 8; uint64_t encoding = attr_numeric(die, DW_AT_encoding); bt->is_bool = encoding == DW_ATE_boolean; bt->is_signed = encoding == DW_ATE_signed; diff --git a/libbtf.c b/libbtf.c index 9f7628304495..48ba57394090 100644 --- a/libbtf.c +++ b/libbtf.c @@ -367,13 +367,34 @@ static void btf_log_func_param(const struct btf_elf *btfe, } } +/* btf requires power-of-2 bytes, yet dwarf may have something like + * DW_ATE_unsigned_24 which encodes as 24 bits (3 bytes). + */ +static int bits_to_int_bytes(uint16_t bit_size) +{ + if (bit_size <= 8) + return 1; + if (bit_size <= 16) + return 2; + if (bit_size <= 32) + return 4; + if (bit_size <= 64) + return 8; + if (bit_size <= 128) + return 16; + if (bit_size <= 160) + return 20; + /* BTF supports upto 16byte int (__int128). */ + return -1; +} + int32_t btf_elf__add_base_type(struct btf_elf *btfe, const struct base_type *bt, const char *name) { struct btf *btf = btfe->btf; const struct btf_type *t; uint8_t encoding = 0; - int32_t id; + int32_t id, nbytes; if (bt->is_signed) { encoding = BTF_INT_SIGNED; @@ -384,7 +405,13 @@ int32_t btf_elf__add_base_type(struct btf_elf *btfe, const struct base_type *bt, return -1; } - id = btf__add_int(btf, name, BITS_ROUNDUP_BYTES(bt->bit_size), encoding); + nbytes = bits_to_int_bytes(bt->bit_size); + if (nbytes < 0) { + fprintf(stderr, "not supported bit_size %hu\n", bt->bit_size); + return -1; + } + + id = btf__add_int(btf, name, nbytes, encoding); if (id < 0) { btf_elf__log_err(btfe, BTF_KIND_INT, name, true, "Error emitting BTF type"); } else {