* bpftool fails on 32-bit hosts when -Wa,--compress-debug-sections is used
@ 2023-12-11 12:49 Sergei Trofimovich
2023-12-13 0:10 ` Andrii Nakryiko
0 siblings, 1 reply; 5+ messages in thread
From: Sergei Trofimovich @ 2023-12-11 12:49 UTC (permalink / raw)
To: bpf
Hi bpf@!
Tl;DR:
BPF programs built with `clang`'s `-g -Wa,--compress-debug-sections`
fail when processed by `bpftool` on section alignment checks as:
$ cat src/core/bpf/socket_bind/bpf.c
struct socket_bind_map_t { int value; };
struct socket_bind_map_t sd_bind_allow __attribute__((section(".maps"), used));
$ clang-16 -target bpf -fno-stack-protector -c src/core/bpf/socket_bind/bpf.c -o bpf.unstripped.o -g -Wa,--compress-debug-sections
$ bpftool gen object bpf.o bpf.unstripped.o
libbpf: ELF section #9 has inconsistent alignment addr=8 != d=4 in bpf.unstripped.o
Error: failed to link 'bpf.unstripped.o': Invalid argument (22)
This happens only when `bpftool` is a 32-bit ELF binary. 64-bit
`bpftool` seems to work as expected.
More words:
Here is my understanding of the failure. Without the
`-Wa,--compress-debug-sections` option `clang` generates byte-aligned
uncompressed `.debug` sections:
$ clang -target bpf -fno-stack-protector -c src/core/bpf/socket_bind/bpf.c -o bpf.unstripped.o -g
$ readelf -SW bpf.unstripped.o
There are 19 section headers, starting at offset 0x530:
Section Headers:
[Nr] Name Type Address Off Size ES Flg Lk Inf Al
[ 0] NULL 0000000000000000 000000 000000 00 0 0 0
[ 1] .strtab STRTAB 0000000000000000 000471 0000b8 00 0 0 1
[ 2] .text PROGBITS 0000000000000000 000040 000000 00 AX 0 0 4
[ 3] .maps PROGBITS 0000000000000000 000040 000004 00 WA 0 0 4
[ 4] .debug_abbrev PROGBITS 0000000000000000 000044 00004c 00 0 0 1
[ 5] .debug_info PROGBITS 0000000000000000 000090 00003d 00 0 0 1
[ 6] .rel.debug_info REL 0000000000000000 000380 000040 10 I 18 5 8
[ 7] .debug_str_offsets PROGBITS 0000000000000000 0000cd 000024 00 0 0 1
[ 8] .rel.debug_str_offsets REL 0000000000000000 0003c0 000070 10 I 18 7 8
[ 9] .debug_str PROGBITS 0000000000000000 0000f1 000080 01 MS 0 0 1
[10] .debug_addr PROGBITS 0000000000000000 000171 000010 00 0 0 1
[11] .rel.debug_addr REL 0000000000000000 000430 000010 10 I 18 10 8
[12] .BTF PROGBITS 0000000000000000 000184 000099 00 0 0 4
[13] .rel.BTF REL 0000000000000000 000440 000010 10 I 18 12 8
[14] .debug_line PROGBITS 0000000000000000 00021d 000043 00 0 0 1
[15] .rel.debug_line REL 0000000000000000 000450 000020 10 I 18 14 8
[16] .debug_line_str PROGBITS 0000000000000000 000260 000041 01 MS 0 0 1
[17] .llvm_addrsig LOOS+0xfff4c03 0000000000000000 000470 000001 00 E 18 0 1
[18] .symtab SYMTAB 0000000000000000 0002a8 0000d8 18 1 8 8
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
L (link order), O (extra OS processing required), G (group), T (TLS),
C (compressed), x (unknown), o (OS specific), E (exclude),
D (mbind), p (processor specific)
Note how `.debug_str` has `alignment=1` here. Loading of such a section
has no problems on x86_64 or i686.
But when we add `-Wa,--compress-debug-sections` some debug sections
become aligned 8 bytes (usual `ELF64`) alignment:
$ clang -target bpf -fno-stack-protector -c src/core/bpf/socket_bind/bpf.c -o bpf.unstripped.o -g -Wa,--compress-debug-sections
$ LANG=C readelf -SW bpf.unstripped.o
There are 19 section headers, starting at offset 0x530:
Section Headers:
[Nr] Name Type Address Off Size ES Flg Lk Inf Al
[ 0] NULL 0000000000000000 000000 000000 00 0 0 0
[ 1] .strtab STRTAB 0000000000000000 000471 0000b8 00 0 0 1
[ 2] .text PROGBITS 0000000000000000 000040 000000 00 AX 0 0 4
[ 3] .maps PROGBITS 0000000000000000 000040 000004 00 WA 0 0 4
[ 4] .debug_abbrev PROGBITS 0000000000000000 000044 00004c 00 0 0 1
[ 5] .debug_info PROGBITS 0000000000000000 000090 00003d 00 0 0 1
[ 6] .rel.debug_info REL 0000000000000000 000380 000040 10 I 18 5 8
[ 7] .debug_str_offsets PROGBITS 0000000000000000 0000cd 000024 00 0 0 1
[ 8] .rel.debug_str_offsets REL 0000000000000000 0003c0 000070 10 I 18 7 8
[ 9] .debug_str PROGBITS 0000000000000000 0000f1 000086 01 MSC 0 0 8
[10] .debug_addr PROGBITS 0000000000000000 000177 000010 00 0 0 1
[11] .rel.debug_addr REL 0000000000000000 000430 000010 10 I 18 10 8
[12] .BTF PROGBITS 0000000000000000 000188 000099 00 0 0 4
[13] .rel.BTF REL 0000000000000000 000440 000010 10 I 18 12 8
[14] .debug_line PROGBITS 0000000000000000 000221 000043 00 0 0 1
[15] .rel.debug_line REL 0000000000000000 000450 000020 10 I 18 14 8
[16] .debug_line_str PROGBITS 0000000000000000 000264 000041 01 MS 0 0 1
[17] .llvm_addrsig LOOS+0xfff4c03 0000000000000000 000470 000001 00 E 18 0 1
[18] .symtab SYMTAB 0000000000000000 0002a8 0000d8 18 1 8 8
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
L (link order), O (extra OS processing required), G (group), T (TLS),
C (compressed), x (unknown), o (OS specific), E (exclude),
D (mbind), p (processor specific)
Note how `.debug_str` alignment changed from 1-byte to 8-byte alignment.
AFAIU 8-byte alignment of compressed section for `ELF64` files is expected:
compressed sections all have a small header that consistes of a few
64-bit values (compression type, uncompressed size, uncompressed data
alignment).
Thus the binary loads as expected by `x86_64` `bpftool` and fails when
loaded by `i686` `bpftool`.
Should `bpftool` work in this scenario? Or compressed sections are not
supported on 32-bit hosts?
It feels like debugging sections with strings should be easily
decompressable on any host type.
Thanks!
--
Sergei
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: bpftool fails on 32-bit hosts when -Wa,--compress-debug-sections is used
2023-12-11 12:49 bpftool fails on 32-bit hosts when -Wa,--compress-debug-sections is used Sergei Trofimovich
@ 2023-12-13 0:10 ` Andrii Nakryiko
2023-12-19 11:03 ` [PATCH] libbpf: skip DWARF sections in linker sanity check Alyssa Ross
0 siblings, 1 reply; 5+ messages in thread
From: Andrii Nakryiko @ 2023-12-13 0:10 UTC (permalink / raw)
To: Sergei Trofimovich; +Cc: bpf
On Mon, Dec 11, 2023 at 4:49 AM Sergei Trofimovich <slyich@gmail.com> wrote:
>
> Hi bpf@!
>
> Tl;DR:
>
> BPF programs built with `clang`'s `-g -Wa,--compress-debug-sections`
> fail when processed by `bpftool` on section alignment checks as:
>
> $ cat src/core/bpf/socket_bind/bpf.c
> struct socket_bind_map_t { int value; };
> struct socket_bind_map_t sd_bind_allow __attribute__((section(".maps"), used));
>
> $ clang-16 -target bpf -fno-stack-protector -c src/core/bpf/socket_bind/bpf.c -o bpf.unstripped.o -g -Wa,--compress-debug-sections
> $ bpftool gen object bpf.o bpf.unstripped.o
> libbpf: ELF section #9 has inconsistent alignment addr=8 != d=4 in bpf.unstripped.o
So we are talking about this check in libbpf's linker:
if (sec->shdr->sh_addralign != sec->data->d_align)
And it's confusing that it would be ok to have actual data alignment
that doesn't match declared alignment in section header? Is that
expected in ELF in general?
Having said that, I think we can mitigate all this easily by ignoring
DWARF sections. Libbpf linker drops all that while linking, see
is_ignored_sec() check, but when doing a sanity check we still
validate everything for DWARF sections.
So perhaps an easy way out is just to ignore DWARF sections in sanity
checks as well?
> Error: failed to link 'bpf.unstripped.o': Invalid argument (22)
>
> This happens only when `bpftool` is a 32-bit ELF binary. 64-bit
> `bpftool` seems to work as expected.
>
> More words:
>
> Here is my understanding of the failure. Without the
> `-Wa,--compress-debug-sections` option `clang` generates byte-aligned
> uncompressed `.debug` sections:
>
> $ clang -target bpf -fno-stack-protector -c src/core/bpf/socket_bind/bpf.c -o bpf.unstripped.o -g
> $ readelf -SW bpf.unstripped.o
> There are 19 section headers, starting at offset 0x530:
>
> Section Headers:
> [Nr] Name Type Address Off Size ES Flg Lk Inf Al
> [ 0] NULL 0000000000000000 000000 000000 00 0 0 0
> [ 1] .strtab STRTAB 0000000000000000 000471 0000b8 00 0 0 1
> [ 2] .text PROGBITS 0000000000000000 000040 000000 00 AX 0 0 4
> [ 3] .maps PROGBITS 0000000000000000 000040 000004 00 WA 0 0 4
> [ 4] .debug_abbrev PROGBITS 0000000000000000 000044 00004c 00 0 0 1
> [ 5] .debug_info PROGBITS 0000000000000000 000090 00003d 00 0 0 1
> [ 6] .rel.debug_info REL 0000000000000000 000380 000040 10 I 18 5 8
> [ 7] .debug_str_offsets PROGBITS 0000000000000000 0000cd 000024 00 0 0 1
> [ 8] .rel.debug_str_offsets REL 0000000000000000 0003c0 000070 10 I 18 7 8
> [ 9] .debug_str PROGBITS 0000000000000000 0000f1 000080 01 MS 0 0 1
> [10] .debug_addr PROGBITS 0000000000000000 000171 000010 00 0 0 1
> [11] .rel.debug_addr REL 0000000000000000 000430 000010 10 I 18 10 8
> [12] .BTF PROGBITS 0000000000000000 000184 000099 00 0 0 4
> [13] .rel.BTF REL 0000000000000000 000440 000010 10 I 18 12 8
> [14] .debug_line PROGBITS 0000000000000000 00021d 000043 00 0 0 1
> [15] .rel.debug_line REL 0000000000000000 000450 000020 10 I 18 14 8
> [16] .debug_line_str PROGBITS 0000000000000000 000260 000041 01 MS 0 0 1
> [17] .llvm_addrsig LOOS+0xfff4c03 0000000000000000 000470 000001 00 E 18 0 1
> [18] .symtab SYMTAB 0000000000000000 0002a8 0000d8 18 1 8 8
> Key to Flags:
> W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
> L (link order), O (extra OS processing required), G (group), T (TLS),
> C (compressed), x (unknown), o (OS specific), E (exclude),
> D (mbind), p (processor specific)
>
> Note how `.debug_str` has `alignment=1` here. Loading of such a section
> has no problems on x86_64 or i686.
>
> But when we add `-Wa,--compress-debug-sections` some debug sections
> become aligned 8 bytes (usual `ELF64`) alignment:
>
> $ clang -target bpf -fno-stack-protector -c src/core/bpf/socket_bind/bpf.c -o bpf.unstripped.o -g -Wa,--compress-debug-sections
> $ LANG=C readelf -SW bpf.unstripped.o
> There are 19 section headers, starting at offset 0x530:
>
> Section Headers:
> [Nr] Name Type Address Off Size ES Flg Lk Inf Al
> [ 0] NULL 0000000000000000 000000 000000 00 0 0 0
> [ 1] .strtab STRTAB 0000000000000000 000471 0000b8 00 0 0 1
> [ 2] .text PROGBITS 0000000000000000 000040 000000 00 AX 0 0 4
> [ 3] .maps PROGBITS 0000000000000000 000040 000004 00 WA 0 0 4
> [ 4] .debug_abbrev PROGBITS 0000000000000000 000044 00004c 00 0 0 1
> [ 5] .debug_info PROGBITS 0000000000000000 000090 00003d 00 0 0 1
> [ 6] .rel.debug_info REL 0000000000000000 000380 000040 10 I 18 5 8
> [ 7] .debug_str_offsets PROGBITS 0000000000000000 0000cd 000024 00 0 0 1
> [ 8] .rel.debug_str_offsets REL 0000000000000000 0003c0 000070 10 I 18 7 8
> [ 9] .debug_str PROGBITS 0000000000000000 0000f1 000086 01 MSC 0 0 8
> [10] .debug_addr PROGBITS 0000000000000000 000177 000010 00 0 0 1
> [11] .rel.debug_addr REL 0000000000000000 000430 000010 10 I 18 10 8
> [12] .BTF PROGBITS 0000000000000000 000188 000099 00 0 0 4
> [13] .rel.BTF REL 0000000000000000 000440 000010 10 I 18 12 8
> [14] .debug_line PROGBITS 0000000000000000 000221 000043 00 0 0 1
> [15] .rel.debug_line REL 0000000000000000 000450 000020 10 I 18 14 8
> [16] .debug_line_str PROGBITS 0000000000000000 000264 000041 01 MS 0 0 1
> [17] .llvm_addrsig LOOS+0xfff4c03 0000000000000000 000470 000001 00 E 18 0 1
> [18] .symtab SYMTAB 0000000000000000 0002a8 0000d8 18 1 8 8
> Key to Flags:
> W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
> L (link order), O (extra OS processing required), G (group), T (TLS),
> C (compressed), x (unknown), o (OS specific), E (exclude),
> D (mbind), p (processor specific)
>
> Note how `.debug_str` alignment changed from 1-byte to 8-byte alignment.
>
> AFAIU 8-byte alignment of compressed section for `ELF64` files is expected:
> compressed sections all have a small header that consistes of a few
> 64-bit values (compression type, uncompressed size, uncompressed data
> alignment).
>
> Thus the binary loads as expected by `x86_64` `bpftool` and fails when
> loaded by `i686` `bpftool`.
>
> Should `bpftool` work in this scenario? Or compressed sections are not
> supported on 32-bit hosts?
>
> It feels like debugging sections with strings should be easily
> decompressable on any host type.
>
> Thanks!
>
> --
>
> Sergei
>
^ permalink raw reply [flat|nested] 5+ messages in thread* [PATCH] libbpf: skip DWARF sections in linker sanity check
2023-12-13 0:10 ` Andrii Nakryiko
@ 2023-12-19 11:03 ` Alyssa Ross
2023-12-20 15:28 ` Daniel Borkmann
2023-12-20 23:40 ` patchwork-bot+netdevbpf
0 siblings, 2 replies; 5+ messages in thread
From: Alyssa Ross @ 2023-12-19 11:03 UTC (permalink / raw)
To: bpf, Andrii Nakryiko; +Cc: patches, Sergei Trofimovich
clang can generate (with -g -Wa,--compress-debug-sections) 4-byte
aligned DWARF sections that declare themselves to be 8-byte aligned in
the section header. Since DWARF sections are dropped during linking
anyway, just skip running the sanity checks on them.
Reported-by: Sergei Trofimovich <slyich@gmail.com>
Suggested-by: Andrii Nakryiko <andrii.nakryiko@gmail.com>
Closes: https://lore.kernel.org/bpf/ZXcFRJVKbKxtEL5t@nz.home/
Signed-off-by: Alyssa Ross <hi@alyssa.is>
---
tools/lib/bpf/linker.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/tools/lib/bpf/linker.c b/tools/lib/bpf/linker.c
index 52a2901e8bd0..16bca56002ab 100644
--- a/tools/lib/bpf/linker.c
+++ b/tools/lib/bpf/linker.c
@@ -719,6 +719,9 @@ static int linker_sanity_check_elf(struct src_obj *obj)
return -EINVAL;
}
+ if (is_dwarf_sec_name(sec->sec_name))
+ continue;
+
if (sec->shdr->sh_addralign && !is_pow_of_2(sec->shdr->sh_addralign)) {
pr_warn("ELF section #%zu alignment %llu is non pow-of-2 alignment in %s\n",
sec->sec_idx, (long long unsigned)sec->shdr->sh_addralign,
base-commit: 733763285acfe8dffd6e39ad2ed3d1222b32a901
--
2.42.0
^ permalink raw reply related [flat|nested] 5+ messages in thread* Re: [PATCH] libbpf: skip DWARF sections in linker sanity check
2023-12-19 11:03 ` [PATCH] libbpf: skip DWARF sections in linker sanity check Alyssa Ross
@ 2023-12-20 15:28 ` Daniel Borkmann
2023-12-20 23:40 ` patchwork-bot+netdevbpf
1 sibling, 0 replies; 5+ messages in thread
From: Daniel Borkmann @ 2023-12-20 15:28 UTC (permalink / raw)
To: Alyssa Ross, bpf, Andrii Nakryiko; +Cc: patches, Sergei Trofimovich
On 12/19/23 12:03 PM, Alyssa Ross wrote:
> clang can generate (with -g -Wa,--compress-debug-sections) 4-byte
> aligned DWARF sections that declare themselves to be 8-byte aligned in
> the section header. Since DWARF sections are dropped during linking
> anyway, just skip running the sanity checks on them.
>
> Reported-by: Sergei Trofimovich <slyich@gmail.com>
> Suggested-by: Andrii Nakryiko <andrii.nakryiko@gmail.com>
> Closes: https://lore.kernel.org/bpf/ZXcFRJVKbKxtEL5t@nz.home/
> Signed-off-by: Alyssa Ross <hi@alyssa.is>
Looks reasonable to skip, thus:
Acked-by: Daniel Borkmann <daniel@iogearbox.net>
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] libbpf: skip DWARF sections in linker sanity check
2023-12-19 11:03 ` [PATCH] libbpf: skip DWARF sections in linker sanity check Alyssa Ross
2023-12-20 15:28 ` Daniel Borkmann
@ 2023-12-20 23:40 ` patchwork-bot+netdevbpf
1 sibling, 0 replies; 5+ messages in thread
From: patchwork-bot+netdevbpf @ 2023-12-20 23:40 UTC (permalink / raw)
To: Alyssa Ross; +Cc: bpf, andrii.nakryiko, patches, slyich
Hello:
This patch was applied to bpf/bpf-next.git (master)
by Andrii Nakryiko <andrii@kernel.org>:
On Tue, 19 Dec 2023 12:03:24 +0100 you wrote:
> clang can generate (with -g -Wa,--compress-debug-sections) 4-byte
> aligned DWARF sections that declare themselves to be 8-byte aligned in
> the section header. Since DWARF sections are dropped during linking
> anyway, just skip running the sanity checks on them.
>
> Reported-by: Sergei Trofimovich <slyich@gmail.com>
> Suggested-by: Andrii Nakryiko <andrii.nakryiko@gmail.com>
> Closes: https://lore.kernel.org/bpf/ZXcFRJVKbKxtEL5t@nz.home/
> Signed-off-by: Alyssa Ross <hi@alyssa.is>
>
> [...]
Here is the summary with links:
- libbpf: skip DWARF sections in linker sanity check
https://git.kernel.org/bpf/bpf-next/c/a4897b87775c
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2023-12-20 23:40 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-12-11 12:49 bpftool fails on 32-bit hosts when -Wa,--compress-debug-sections is used Sergei Trofimovich
2023-12-13 0:10 ` Andrii Nakryiko
2023-12-19 11:03 ` [PATCH] libbpf: skip DWARF sections in linker sanity check Alyssa Ross
2023-12-20 15:28 ` Daniel Borkmann
2023-12-20 23:40 ` patchwork-bot+netdevbpf
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox