On Wed, Nov 05, 2025 at 01:53:13PM -0800, Omar Sandoval wrote:
Here's a script that reproduces it:
#!/bin/sh set -e host_arch=x86_64 compiler_version="12.4.0" compiler_dir="/tmp/arm64-gcc-$compiler_version" if [ ! -e "$compiler_dir" ]; then rm -rf "$compiler_dir.tmp" mkdir "$compiler_dir.tmp" curl -L "https://mirrors.kernel.org/pub/tools/crosstool/files/bin/$host_arch/$compiler_version/$host_arch-gcc-$compiler_version-nolibc-aarch64-linux.tar.xz" | tar -C "$compiler_dir.tmp" -Jx mv "$compiler_dir.tmp" "$compiler_dir" fi export PATH="$compiler_dir/gcc-$compiler_version-nolibc/aarch64-linux/bin:$PATH" make ARCH=arm64 CROSS_COMPILE=aarch64-linux- tinyconfig make ARCH=arm64 CROSS_COMPILE=aarch64-linux- -j$(nproc) vmlinux readelf -W -l vmlinux | awk '$1 == "LOAD" && $6 ~ /0x0+\>/'It prints something like:
LOAD 0x1ef008 0x0000000000000000 0xffff800080220000 0x000000 0x000000 R 0x10000
I.e., a segment with FileSiz and MemSiz 0.
Thank you, that was incredibly helpful.
Using a newer crosstool version fixes it, so maybe this was a GCC or binutils bug.
Good observation, as this was reproducible with GCC 12.4.0 from kernel.org but not GCC 12.5.0, which I noticed has a newer binutils version. I was able to reproduce it with a self compiled copy of binutils 2.42 but not with binutils 2.44 so I reverse bisected the fix to [1], which certainly makes sense :)
The diff of 'readelf -lW' before that change:
diff --git a/tmp/.psub.9QY0ZO b/tmp/.psub.6lHG9T index 7f7f4de7be8..ea3a9b4ffb0 100644 --- a/tmp/.psub.9QY0ZO +++ b/tmp/.psub.6lHG9T @@ -7,14 +7,14 @@ Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align LOAD 0x010000 0xffff800080000000 0xffff800080000000 0x14f000 0x14f000 R E 0x10000 LOAD 0x160000 0xffff800080150000 0xffff800080150000 0x08f008 0x0c4c40 RWE 0x10000 - LOAD 0x1f0000 0xffff800080220000 0xffff800080220000 0x000d08 0x000d08 R 0x10000 + LOAD 0x1ef008 0x0000000000000000 0xffff800080220000 0x000000 0x000000 R 0x10000 NOTE 0x1860f8 0xffff8000801760f8 0xffff8000801760f8 0x000054 0x000054 R 0x4 - GNU_STACK 0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW 0x10 + GNU_STACK 0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW 0x8
Section to Segment mapping: Segment Sections... 00 .head.text .text 01 .rodata __param __ex_table .notes .rodata.text .init.text .exit.text .altinstructions .init.data runtime_shift_d_hash_shift runtime_ptr_dentry_hashtable .data..percpu .data .mmuoff.data.write .mmuoff.data.read .bss - 02 .modinfo + 02 03 .notes 04
After:
diff --git a/tmp/.psub.x5uqM8 b/tmp/.psub.LHoP7d index 7f7f4de7be8..27bda6ea7cc 100644 --- a/tmp/.psub.x5uqM8 +++ b/tmp/.psub.LHoP7d @@ -1,20 +1,18 @@
Elf file type is EXEC (Executable file) Entry point 0xffff800080000000 -There are 5 program headers, starting at offset 64 +There are 4 program headers, starting at offset 64
Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align LOAD 0x010000 0xffff800080000000 0xffff800080000000 0x14f000 0x14f000 R E 0x10000 LOAD 0x160000 0xffff800080150000 0xffff800080150000 0x08f008 0x0c4c40 RWE 0x10000 - LOAD 0x1f0000 0xffff800080220000 0xffff800080220000 0x000d08 0x000d08 R 0x10000 NOTE 0x1860f8 0xffff8000801760f8 0xffff8000801760f8 0x000054 0x000054 R 0x4 - GNU_STACK 0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW 0x10 + GNU_STACK 0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW 0x8
Section to Segment mapping: Segment Sections... 00 .head.text .text 01 .rodata __param __ex_table .notes .rodata.text .init.text .exit.text .altinstructions .init.data runtime_shift_d_hash_shift runtime_ptr_dentry_hashtable .data..percpu .data .mmuoff.data.write .mmuoff.data.read .bss - 02 .modinfo - 03 .notes - 04 + 02 .notes + 03
I am not really sure how to workaround this in a concise way... at least for arm64 since it does not seem to use PHDRS to describe ELF segments, it just relies on the default linker heuristics? It also seems seems like this is a generic problem not specific to .modinfo, we just so happen to see it with this section since it is in its own segment and we are removing it.
[1]: https://sourceware.org/git/?p=binutils-gdb.git%3Ba=commit%3Bh=7f26d260ef76a4...
Cheers, Nathan