Re: ERROR: INT DW_ATE_unsigned_1 Error emitting BTF type

From: Sedat Dilek
Date: Sat Feb 06 2021 - 06:28:41 EST


On Sat, Feb 6, 2021 at 11:23 AM Sedat Dilek <sedat.dilek@xxxxxxxxx> wrote:
>
> [ SNIP ]
>
> > > > > > Please help do a test. I can submit a formal patch tomorrow.
> > > > >
> > > > > Thanks for the patch.
> > > > >
> > > > > Can you attach the diff as Gmail has totally truncated/malformed it?
> > > > >
> > > > > For the Linux breakage - you will need some additional Clang specific patches.
> > > > > Is this Linux 5.11-rcX?
> > > > > The "Blocking bugs" are listed in the first post of "Linux 5.11 release cycle".
> > > > > Hope this helps.
> > > > >
> > > > > This is cool co-working :-).
> > > > >
> > > > > - Sedat -
> > > > >
> > > > > [1] https://github.com/ClangBuiltLinux/linux/issues/1228
> > > >
> > > > With the attached diff and new selfmade pahole looks good here.
> > > >
> > > > Passed (see line-numbers):
> > > >
> > > > 11090:+ info LD .tmp_vmlinux.btf
> > > > 11099:+ info BTF .btf.vmlinux.bin.o
> > > > 11103:+ LLVM_OBJCOPY=llvm-objcopy /opt/pahole/bin/pahole -J .tmp_vmlinux.btf
> > > > 11121:+ info LD .tmp_vmlinux.kallsyms1
> > > > 11139:+ info KSYMS .tmp_vmlinux.kallsyms1.S
> > > > 11145:+ info AS .tmp_vmlinux.kallsyms1.S
> > > > 11160:+ info LD .tmp_vmlinux.kallsyms2
> > > > 11178:+ info KSYMS .tmp_vmlinux.kallsyms2.S
> > > > 11184:+ info AS .tmp_vmlinux.kallsyms2.S
> > > > 11200:+ info LD vmlinux
> > > > 11210:+ info BTFIDS vmlinux
> > > > 11216:+ info SORTTAB vmlinux
> > > >
> > > > Still building linux-kernel...
> > > >
> > > > Will report later if I was able to boot on bare metal.
> > > >
> > >
> > > When running scripts/Makefile.modfinal:
> > >
> > > ...
> > > not supported bit_size 160
> > > Encountered error while encoding BTF.
> > > ...
> > > make[5]: *** [scripts/Makefile.modfinal:59:
> > > drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.ko] Error 1
> > > make[5]: *** Deleting file
> > > 'drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.ko'
> > >
> >
> > I added "bit_size 160" to libbtf.c:
> >
> > 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;
> > }
> >
> > It still breaks with:
> >
> > [521367] INT DW_ATE_unsigned_160 Error emitting BTF type
> > Encountered error while encoding BTF.
> > make[5]: *** [scripts/Makefile.modfinal:58:
> > drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.ko] Error 1
> > make[5]: *** Deleting file
> > 'drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.ko'
> >
> > Comments?
> >
>
> Indeed there is DW_ATE_unsigned_160:
>
> $ /opt/llvm-toolchain/bin/llvm-dwarfdump
> drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.o | grep DW_AT_name
> | grep DW_ATE_ | sort -u
> DW_AT_name ("DW_ATE_signed_32")
> DW_AT_name ("DW_ATE_signed_64")
> DW_AT_name ("DW_ATE_unsigned_1")
> DW_AT_name ("DW_ATE_unsigned_128")
> DW_AT_name ("DW_ATE_unsigned_16")
> DW_AT_name ("DW_ATE_unsigned_160")
> DW_AT_name ("DW_ATE_unsigned_32")
> DW_AT_name ("DW_ATE_unsigned_64")
> DW_AT_name ("DW_ATE_unsigned_8")
>
> Attached is diff v2 with the "bit_size 160" fix.
>

With attached diff v4 I was able to build and boot into bare metal.

$ cat /proc/version
Linux version 5.11.0-rc6-14-amd64-clang12-ias
(sedat.dilek@xxxxxxxxx@iniza) (dileks clang version 12.0.0
(https://github.com/llvm/llvm-project.git 8364f5369eeeb2da8db2
bae7716c549930d8df93), LLD 12.0.0
(https://github.com/llvm/llvm-project.git
8364f5369eeeb2da8db2bae7716c549930d8df93)) #14~bullseye+dileks1 SMP
2021-02-06

This is the diffconfig to my previous build:

$ scripts/diffconfig /boot/config-5.11.0-rc6-10-amd64-clang12-bfd .config
BUILD_SALT "5.11.0-rc6-10-amd64-clang12-bfd" ->
"5.11.0-rc6-14-amd64-clang12-ias"
DEBUG_INFO_COMPRESSED y -> n
DEBUG_INFO_DWARF4 y -> n
LD_VERSION 235020000 -> 0
LLD_VERSION 0 -> 120000
+DEBUG_INFO_DWARF5 y
+LD_IS_LLD y
+TOOLS_SUPPORT_RELR y

Attached is also my linux-config.

Thanks to all involved people.

- Sedat -
diff --git a/dwarf_loader.c b/dwarf_loader.c
index b73d7867e1e6..d927c415b191 100644
--- a/dwarf_loader.c
+++ b/dwarf_loader.c
@@ -467,8 +467,18 @@ 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.
+ * Process DW_ATE_unsigned_160 the same way.
+ */
+ if (strcmp(name, "DW_ATE_unsigned_1") == 0)
+ bt->bit_size = 1;
+ if (strcmp(name, "DW_ATE_unsigned_160") == 0)
+ bt->bit_size = 20;
+ 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..44db29e83433 100644
--- a/libbtf.c
+++ b/libbtf.c
@@ -367,13 +367,32 @@ 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;
+ /* 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 +403,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 {

Attachment: config-5.11.0-rc6-14-amd64-clang12-ias
Description: Binary data