From: Thomas Weißschuh <hidden> Date: 2026-09-08 06:33:49
The compiler can emit absolute relocations in vDSO code,
which are invalid in vDSO code.
Detect them at compile-time.
libc elf.h is missing some of the relocation constants,
so make use of the kernels own UAPI headers instead.
Patches 13 onward contain the architecture specific changes,
interesting for the architecture maintaines.
Kbuild and Rust folks: This contains custom definitions of hostprog
bindgen and rust library commands.
These are currently only defined inside the subsystem directory.
Let me know if they should go into scripts/Makefile.host.
Signed-off-by: Thomas Weißschuh <redacted>
---
Changes in v5:
- Rebase on v7.3-rc1
- s/HOSTRUSTLIB/HOSTRUSTC L/
- Pick up review tags.
- Also handle SPARC.
- Build 'vdsocheck' during the prepare phase.
- Drop now unnecessary riscv LTO preparation patches.
- Link to v4: https://lore.kernel.org/r/20250812-vdso-absolute-reloc-v4-0-61a8b615e5ec@linutronix.de
Changes in v4:
- Replace the inline shell logic with a dedicated build-time tool
- Link to v3: https://lore.kernel.org/r/20250611-vdso-absolute-reloc-v3-0-47897d73784b@linutronix.de
Changes in v3:
- Drop already applied bugfix for arm64
- Disable LTO for the riscv vDSO, as it is incompatible
- Link to v2: https://lore.kernel.org/r/20250430-vdso-absolute-reloc-v2-0-5efcc3bc4b26@linutronix.de
Changes in v2:
- Link to openend (invalid) GCC bug containing more explanations
- Refine commit messages
- Don't fail on commit absolute relocations in debug info
- Link to v1: https://lore.kernel.org/r/20250429-vdso-absolute-reloc-v1-0-987a0afd10b5@linutronix.de
---
Thomas Weißschuh (24):
elf, uapi: Add a header for relocation constants
x86/elf, um/x86/elf: Move relocation constants to UAPI
ARM: elf: Move relocation constants to UAPI
arm64: elf: Move relocation constants to UAPI
powerpc/elf: Move relocation constants to UAPI
riscv: elf: Move relocation constants to UAPI
LoongArch: Move relocation constants to UAPI
s390/elf: Move relocation constants to UAPI
MIPS: ELF: Move relocation constants to UAPI
sparc: elf: Move relocation constants to UAPI
tools headers UAPI: Sync ELF headers with the kernel sources
vdso: Add the vdsocheck tool
x86/vdso: Enable the vdsocheck tool
ARM: vdso: Enable the vdsocheck tool
arm64: vdso: Enable the vdsocheck tool
powerpc/elf: Add 32-bit REL16 relocation definitions
powerpc/vdso: Enable the vdsocheck tool
riscv: vdso: Enable the vdsocheck tool
LoongArch: vDSO: Enable the vdsocheck tool
s390/vdso: Enable the vdsocheck tool
MIPS: ELF: Add more PC-relative relocation definitions
MIPS: vdso: Enable the vdsocheck tool
sparc: vdso: Enable the vdsocheck tool
vDSO: Automatically enable VDSO_CHECK
Makefile | 19 +
arch/arm/include/asm/elf.h | 24 -
arch/arm/vdso/Makefile | 4 +-
arch/arm64/include/asm/elf.h | 55 ---
arch/arm64/kernel/vdso/Makefile | 4 +-
arch/loongarch/include/asm/elf.h | 130 -----
arch/loongarch/vdso/Makefile | 4 +-
arch/mips/include/asm/elf.h | 55 ---
arch/mips/vdso/Makefile | 8 +-
arch/powerpc/include/uapi/asm/elf.h | 201 --------
arch/powerpc/kernel/vdso/Makefile | 4 +-
arch/riscv/include/uapi/asm/elf.h | 66 ---
arch/riscv/kernel/vdso/Makefile | 4 +-
arch/s390/include/asm/elf.h | 83 ----
arch/s390/kernel/vdso/Makefile | 4 +-
arch/sparc/include/asm/elf_32.h | 43 --
arch/sparc/include/asm/elf_64.h | 44 --
arch/sparc/vdso/Makefile | 5 +-
arch/x86/entry/vdso/common/Makefile.include | 2 +-
arch/x86/include/asm/elf.h | 33 --
arch/x86/um/asm/elf.h | 33 --
include/uapi/linux/elf-r.h | 705 ++++++++++++++++++++++++++++
include/uapi/linux/elf.h | 1 +
lib/vdso/Kconfig | 7 +
lib/vdso/Makefile | 2 +
lib/vdso/Makefile.include | 14 +
lib/vdso/check/.gitignore | 3 +
lib/vdso/check/Makefile | 34 ++
lib/vdso/check/elf.rs | 498 ++++++++++++++++++++
lib/vdso/check/vdsocheck.rs | 299 ++++++++++++
tools/include/uapi/linux/elf-em.h | 71 +++
tools/include/uapi/linux/elf-r.h | 705 ++++++++++++++++++++++++++++
tools/include/uapi/linux/elf.h | 112 ++++-
33 files changed, 2479 insertions(+), 797 deletions(-)
---
base-commit: 2f737a133fad3808f9993f704fb27fd7791a0a41
change-id: 20250428-vdso-absolute-reloc-a226293c1761
Best regards,
--
Thomas Weißschuh [off-list ref]
From: Thomas Weißschuh <hidden> Date: 2026-09-08 06:33:49
While the numeric constants for relocations are architecture specific,
it is still useful to get access to them from other architectures.
Also the definitions are useful for userspace in general.
For example tools processing elf files during a kernel cross-compilation
can make use of them.
Introduce a dedicated header for them, similar to the elf-em.h header.
For now the header is empty but it will be filled step by step in
upcomming commits.
Signed-off-by: Thomas Weißschuh <redacted>
---
include/uapi/linux/elf-r.h | 5 +++++
include/uapi/linux/elf.h | 1 +
2 files changed, 6 insertions(+)
From: Thomas Weißschuh <hidden> Date: 2026-09-08 06:33:50
These constants are useful for cross-platform userspace, for example to
process ELF files during kernel cross-compilation.
Move them from the kernel-private architecture-specific header to the UAPI.
Signed-off-by: Thomas Weißschuh <redacted>
---
arch/x86/include/asm/elf.h | 33 ---------------------------------
arch/x86/um/asm/elf.h | 33 ---------------------------------
include/uapi/linux/elf-r.h | 34 ++++++++++++++++++++++++++++++++++
3 files changed, 34 insertions(+), 66 deletions(-)
@@ -44,26 +31,6 @@ typedef struct user_i387_struct elf_fpregset_t;#else-/* x86-64 relocation types */-#define R_X86_64_NONE 0 /* No reloc */-#define R_X86_64_64 1 /* Direct 64 bit */-#define R_X86_64_PC32 2 /* PC relative 32 bit signed */-#define R_X86_64_GOT32 3 /* 32 bit GOT entry */-#define R_X86_64_PLT32 4 /* 32 bit PLT address */-#define R_X86_64_COPY 5 /* Copy symbol at runtime */-#define R_X86_64_GLOB_DAT 6 /* Create GOT entry */-#define R_X86_64_JUMP_SLOT 7 /* Create PLT entry */-#define R_X86_64_RELATIVE 8 /* Adjust by program base */-#define R_X86_64_GOTPCREL 9 /* 32 bit signed pc relative-offsettoGOT*/-#define R_X86_64_32 10 /* Direct 32 bit zero extended */-#define R_X86_64_32S 11 /* Direct 32 bit sign extended */-#define R_X86_64_16 12 /* Direct 16 bit zero extended */-#define R_X86_64_PC16 13 /* 16 bit sign extended pc relative */-#define R_X86_64_8 14 /* Direct 8 bit sign extended */-#define R_X86_64_PC8 15 /* 8 bit sign extended pc relative */-#define R_X86_64_PC64 24 /* Place relative 64-bit signed */-/**Theseareusedtosetparametersinthecoredumps.*/
@@ -72,26 +59,6 @@#else-/* x86-64 relocation types, taken from asm-x86_64/elf.h */-#define R_X86_64_NONE 0 /* No reloc */-#define R_X86_64_64 1 /* Direct 64 bit */-#define R_X86_64_PC32 2 /* PC relative 32 bit signed */-#define R_X86_64_GOT32 3 /* 32 bit GOT entry */-#define R_X86_64_PLT32 4 /* 32 bit PLT address */-#define R_X86_64_COPY 5 /* Copy symbol at runtime */-#define R_X86_64_GLOB_DAT 6 /* Create GOT entry */-#define R_X86_64_JUMP_SLOT 7 /* Create PLT entry */-#define R_X86_64_RELATIVE 8 /* Adjust by program base */-#define R_X86_64_GOTPCREL 9 /* 32 bit signed pc relative-offsettoGOT*/-#define R_X86_64_32 10 /* Direct 32 bit zero extended */-#define R_X86_64_32S 11 /* Direct 32 bit sign extended */-#define R_X86_64_16 12 /* Direct 16 bit zero extended */-#define R_X86_64_PC16 13 /* 16 bit sign extended pc relative */-#define R_X86_64_8 14 /* Direct 8 bit sign extended */-#define R_X86_64_PC8 15 /* 8 bit sign extended pc relative */-#define R_X86_64_PC64 24 /* Place relative 64-bit signed */-/**Thisisusedtoensurewedon'tloadsomethingforthewrongarchitecture.*/
From: Thomas Weißschuh <hidden> Date: 2026-09-08 06:33:50
These constants are useful for cross-platform userspace, for example to
process ELF files during kernel cross-compilation.
Move them from the kernel-private architecture-specific header to the UAPI.
One arm64 header is also changed as it duplicates an arm definition.
Signed-off-by: Thomas Weißschuh <redacted>
---
arch/arm/include/asm/elf.h | 24 ------------------------
arch/arm64/include/asm/elf.h | 1 -
include/uapi/linux/elf-r.h | 25 +++++++++++++++++++++++++
3 files changed, 25 insertions(+), 25 deletions(-)
From: Thomas Weißschuh <hidden> Date: 2026-09-08 06:33:51
These constants are useful for cross-platform userspace, for example to
process ELF files during kernel cross-compilation.
Move them from the kernel-private architecture-specific header to the UAPI.
Signed-off-by: Thomas Weißschuh <redacted>
---
arch/arm64/include/asm/elf.h | 54 --------------------------------------------
include/uapi/linux/elf-r.h | 52 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 52 insertions(+), 54 deletions(-)
From: Thomas Weißschuh <hidden> Date: 2026-09-08 06:33:53
These constants are useful for cross-platform userspace, for example to
process ELF files during kernel cross-compilation.
Move them from the kernel-private architecture-specific header to the UAPI.
Signed-off-by: Thomas Weißschuh <redacted>
---
arch/powerpc/include/uapi/asm/elf.h | 201 ------------------------------------
include/uapi/linux/elf-r.h | 201 ++++++++++++++++++++++++++++++++++++
2 files changed, 201 insertions(+), 201 deletions(-)
From: Thomas Weißschuh <hidden> Date: 2026-09-08 06:33:53
These constants are useful for cross-platform userspace, for example to
process ELF files during kernel cross-compilation.
Move them from the kernel-private architecture-specific header to the UAPI.
Signed-off-by: Thomas Weißschuh <redacted>
Acked-by: Palmer Dabbelt <palmer@dabbelt.com>
---
arch/riscv/include/uapi/asm/elf.h | 66 ---------------------------------------
include/uapi/linux/elf-r.h | 66 +++++++++++++++++++++++++++++++++++++++
2 files changed, 66 insertions(+), 66 deletions(-)
From: Thomas Weißschuh <hidden> Date: 2026-09-08 06:33:55
These constants are useful for cross-platform userspace, for example to
process ELF files during kernel cross-compilation.
Move them from the kernel-private architecture-specific header to the UAPI.
Signed-off-by: Thomas Weißschuh <redacted>
---
arch/mips/include/asm/elf.h | 55 --------------------------------------------
include/uapi/linux/elf-r.h | 56 +++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 56 insertions(+), 55 deletions(-)
From: Thomas Weißschuh <hidden> Date: 2026-09-08 06:33:55
These constants are useful for cross-platform userspace, for example to
process ELF files during kernel cross-compilation.
Move them from the kernel-private architecture-specific header to the UAPI.
Signed-off-by: Thomas Weißschuh <redacted>
---
arch/loongarch/include/asm/elf.h | 130 ---------------------------------------
include/uapi/linux/elf-r.h | 130 +++++++++++++++++++++++++++++++++++++++
2 files changed, 130 insertions(+), 130 deletions(-)
From: Thomas Weißschuh <hidden> Date: 2026-09-08 06:33:55
These constants are useful for cross-platform userspace, for example to
process ELF files during kernel cross-compilation.
Move them from the kernel-private architecture-specific header to the UAPI.
Signed-off-by: Thomas Weißschuh <redacted>
---
arch/sparc/include/asm/elf_32.h | 43 ----------------------------------------
arch/sparc/include/asm/elf_64.h | 44 -----------------------------------------
include/uapi/linux/elf-r.h | 44 +++++++++++++++++++++++++++++++++++++++++
3 files changed, 44 insertions(+), 87 deletions(-)
From: Thomas Weißschuh <hidden> Date: 2026-09-08 06:33:55
These constants are useful for cross-platform userspace, for example to
process ELF files during kernel cross-compilation.
Move them from the kernel-private architecture-specific header to the UAPI.
Signed-off-by: Thomas Weißschuh <redacted>
---
arch/s390/include/asm/elf.h | 83 ---------------------------------------------
include/uapi/linux/elf-r.h | 83 +++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 83 insertions(+), 83 deletions(-)
@@ -8,89 +8,6 @@#ifndef __ASMS390_ELF_H#define __ASMS390_ELF_H-/* s390 relocations defined by the ABIs */-#define R_390_NONE 0 /* No reloc. */-#define R_390_8 1 /* Direct 8 bit. */-#define R_390_12 2 /* Direct 12 bit. */-#define R_390_16 3 /* Direct 16 bit. */-#define R_390_32 4 /* Direct 32 bit. */-#define R_390_PC32 5 /* PC relative 32 bit. */-#define R_390_GOT12 6 /* 12 bit GOT offset. */-#define R_390_GOT32 7 /* 32 bit GOT offset. */-#define R_390_PLT32 8 /* 32 bit PC relative PLT address. */-#define R_390_COPY 9 /* Copy symbol at runtime. */-#define R_390_GLOB_DAT 10 /* Create GOT entry. */-#define R_390_JMP_SLOT 11 /* Create PLT entry. */-#define R_390_RELATIVE 12 /* Adjust by program base. */-#define R_390_GOTOFF32 13 /* 32 bit offset to GOT. */-#define R_390_GOTPC 14 /* 32 bit PC rel. offset to GOT. */-#define R_390_GOT16 15 /* 16 bit GOT offset. */-#define R_390_PC16 16 /* PC relative 16 bit. */-#define R_390_PC16DBL 17 /* PC relative 16 bit shifted by 1. */-#define R_390_PLT16DBL 18 /* 16 bit PC rel. PLT shifted by 1. */-#define R_390_PC32DBL 19 /* PC relative 32 bit shifted by 1. */-#define R_390_PLT32DBL 20 /* 32 bit PC rel. PLT shifted by 1. */-#define R_390_GOTPCDBL 21 /* 32 bit PC rel. GOT shifted by 1. */-#define R_390_64 22 /* Direct 64 bit. */-#define R_390_PC64 23 /* PC relative 64 bit. */-#define R_390_GOT64 24 /* 64 bit GOT offset. */-#define R_390_PLT64 25 /* 64 bit PC relative PLT address. */-#define R_390_GOTENT 26 /* 32 bit PC rel. to GOT entry >> 1. */-#define R_390_GOTOFF16 27 /* 16 bit offset to GOT. */-#define R_390_GOTOFF64 28 /* 64 bit offset to GOT. */-#define R_390_GOTPLT12 29 /* 12 bit offset to jump slot. */-#define R_390_GOTPLT16 30 /* 16 bit offset to jump slot. */-#define R_390_GOTPLT32 31 /* 32 bit offset to jump slot. */-#define R_390_GOTPLT64 32 /* 64 bit offset to jump slot. */-#define R_390_GOTPLTENT 33 /* 32 bit rel. offset to jump slot. */-#define R_390_PLTOFF16 34 /* 16 bit offset from GOT to PLT. */-#define R_390_PLTOFF32 35 /* 32 bit offset from GOT to PLT. */-#define R_390_PLTOFF64 36 /* 16 bit offset from GOT to PLT. */-#define R_390_TLS_LOAD 37 /* Tag for load insn in TLS code. */-#define R_390_TLS_GDCALL 38 /* Tag for function call in general-dynamicTLScode.*/-#define R_390_TLS_LDCALL 39 /* Tag for function call in local-dynamicTLScode.*/-#define R_390_TLS_GD32 40 /* Direct 32 bit for general dynamic-threadlocaldata.*/-#define R_390_TLS_GD64 41 /* Direct 64 bit for general dynamic-threadlocaldata.*/-#define R_390_TLS_GOTIE12 42 /* 12 bit GOT offset for static TLS-blockoffset.*/-#define R_390_TLS_GOTIE32 43 /* 32 bit GOT offset for static TLS-blockoffset.*/-#define R_390_TLS_GOTIE64 44 /* 64 bit GOT offset for static TLS-blockoffset.*/-#define R_390_TLS_LDM32 45 /* Direct 32 bit for local dynamic-threadlocaldatainLDcode.*/-#define R_390_TLS_LDM64 46 /* Direct 64 bit for local dynamic-threadlocaldatainLDcode.*/-#define R_390_TLS_IE32 47 /* 32 bit address of GOT entry for-negatedstaticTLSblockoffset.*/-#define R_390_TLS_IE64 48 /* 64 bit address of GOT entry for-negatedstaticTLSblockoffset.*/-#define R_390_TLS_IEENT 49 /* 32 bit rel. offset to GOT entry for-negatedstaticTLSblockoffset.*/-#define R_390_TLS_LE32 50 /* 32 bit negated offset relative to-staticTLSblock.*/-#define R_390_TLS_LE64 51 /* 64 bit negated offset relative to-staticTLSblock.*/-#define R_390_TLS_LDO32 52 /* 32 bit offset relative to TLS-block.*/-#define R_390_TLS_LDO64 53 /* 64 bit offset relative to TLS-block.*/-#define R_390_TLS_DTPMOD 54 /* ID of module containing symbol. */-#define R_390_TLS_DTPOFF 55 /* Offset in TLS block. */-#define R_390_TLS_TPOFF 56 /* Negate offset in static TLS-block.*/-#define R_390_20 57 /* Direct 20 bit. */-#define R_390_GOT20 58 /* 20 bit GOT offset. */-#define R_390_GOTPLT20 59 /* 20 bit offset to jump slot. */-#define R_390_TLS_GOTIE20 60 /* 20 bit GOT offset for static TLS-blockoffset.*/-/* Keep this the last entry. */-#define R_390_NUM 61-/**HWCAPflags-forAT_HWCAP*
@@ -510,4 +510,87 @@#define R_LARCH_TLS_DESC_PCADD_HI20 138#define R_LARCH_TLS_DESC_PCADD_LO12 139+/* s390 relocations defined by the ABIs */+#define R_390_NONE 0 /* No reloc. */+#define R_390_8 1 /* Direct 8 bit. */+#define R_390_12 2 /* Direct 12 bit. */+#define R_390_16 3 /* Direct 16 bit. */+#define R_390_32 4 /* Direct 32 bit. */+#define R_390_PC32 5 /* PC relative 32 bit. */+#define R_390_GOT12 6 /* 12 bit GOT offset. */+#define R_390_GOT32 7 /* 32 bit GOT offset. */+#define R_390_PLT32 8 /* 32 bit PC relative PLT address. */+#define R_390_COPY 9 /* Copy symbol at runtime. */+#define R_390_GLOB_DAT 10 /* Create GOT entry. */+#define R_390_JMP_SLOT 11 /* Create PLT entry. */+#define R_390_RELATIVE 12 /* Adjust by program base. */+#define R_390_GOTOFF32 13 /* 32 bit offset to GOT. */+#define R_390_GOTPC 14 /* 32 bit PC rel. offset to GOT. */+#define R_390_GOT16 15 /* 16 bit GOT offset. */+#define R_390_PC16 16 /* PC relative 16 bit. */+#define R_390_PC16DBL 17 /* PC relative 16 bit shifted by 1. */+#define R_390_PLT16DBL 18 /* 16 bit PC rel. PLT shifted by 1. */+#define R_390_PC32DBL 19 /* PC relative 32 bit shifted by 1. */+#define R_390_PLT32DBL 20 /* 32 bit PC rel. PLT shifted by 1. */+#define R_390_GOTPCDBL 21 /* 32 bit PC rel. GOT shifted by 1. */+#define R_390_64 22 /* Direct 64 bit. */+#define R_390_PC64 23 /* PC relative 64 bit. */+#define R_390_GOT64 24 /* 64 bit GOT offset. */+#define R_390_PLT64 25 /* 64 bit PC relative PLT address. */+#define R_390_GOTENT 26 /* 32 bit PC rel. to GOT entry >> 1. */+#define R_390_GOTOFF16 27 /* 16 bit offset to GOT. */+#define R_390_GOTOFF64 28 /* 64 bit offset to GOT. */+#define R_390_GOTPLT12 29 /* 12 bit offset to jump slot. */+#define R_390_GOTPLT16 30 /* 16 bit offset to jump slot. */+#define R_390_GOTPLT32 31 /* 32 bit offset to jump slot. */+#define R_390_GOTPLT64 32 /* 64 bit offset to jump slot. */+#define R_390_GOTPLTENT 33 /* 32 bit rel. offset to jump slot. */+#define R_390_PLTOFF16 34 /* 16 bit offset from GOT to PLT. */+#define R_390_PLTOFF32 35 /* 32 bit offset from GOT to PLT. */+#define R_390_PLTOFF64 36 /* 16 bit offset from GOT to PLT. */+#define R_390_TLS_LOAD 37 /* Tag for load insn in TLS code. */+#define R_390_TLS_GDCALL 38 /* Tag for function call in general+dynamicTLScode.*/+#define R_390_TLS_LDCALL 39 /* Tag for function call in local+dynamicTLScode.*/+#define R_390_TLS_GD32 40 /* Direct 32 bit for general dynamic+threadlocaldata.*/+#define R_390_TLS_GD64 41 /* Direct 64 bit for general dynamic+threadlocaldata.*/+#define R_390_TLS_GOTIE12 42 /* 12 bit GOT offset for static TLS+blockoffset.*/+#define R_390_TLS_GOTIE32 43 /* 32 bit GOT offset for static TLS+blockoffset.*/+#define R_390_TLS_GOTIE64 44 /* 64 bit GOT offset for static TLS+blockoffset.*/+#define R_390_TLS_LDM32 45 /* Direct 32 bit for local dynamic+threadlocaldatainLDcode.*/+#define R_390_TLS_LDM64 46 /* Direct 64 bit for local dynamic+threadlocaldatainLDcode.*/+#define R_390_TLS_IE32 47 /* 32 bit address of GOT entry for+negatedstaticTLSblockoffset.*/+#define R_390_TLS_IE64 48 /* 64 bit address of GOT entry for+negatedstaticTLSblockoffset.*/+#define R_390_TLS_IEENT 49 /* 32 bit rel. offset to GOT entry for+negatedstaticTLSblockoffset.*/+#define R_390_TLS_LE32 50 /* 32 bit negated offset relative to+staticTLSblock.*/+#define R_390_TLS_LE64 51 /* 64 bit negated offset relative to+staticTLSblock.*/+#define R_390_TLS_LDO32 52 /* 32 bit offset relative to TLS+block.*/+#define R_390_TLS_LDO64 53 /* 64 bit offset relative to TLS+block.*/+#define R_390_TLS_DTPMOD 54 /* ID of module containing symbol. */+#define R_390_TLS_DTPOFF 55 /* Offset in TLS block. */+#define R_390_TLS_TPOFF 56 /* Negate offset in static TLS+block.*/+#define R_390_20 57 /* Direct 20 bit. */+#define R_390_GOT20 58 /* 20 bit GOT offset. */+#define R_390_GOTPLT20 59 /* 20 bit offset to jump slot. */+#define R_390_TLS_GOTIE20 60 /* 20 bit GOT offset for static TLS+blockoffset.*/+/* Keep this the last entry. */+#define R_390_NUM 61+#endif /* _UAPI_LINUX_ELF_R_H */
From: Thomas Weißschuh <hidden> Date: 2026-09-08 06:33:56
Pick up changes from the UAPI ELF header files.
This picks up general changes to elf.h, elf-em.h which was forgotten
previously and the new elf-r.h.
Signed-off-by: Thomas Weißschuh <redacted>
---
Cc: Arnaldo Carvalho de Melo <redacted>
---
tools/include/uapi/linux/elf-em.h | 71 ++++
tools/include/uapi/linux/elf-r.h | 696 ++++++++++++++++++++++++++++++++++++++
tools/include/uapi/linux/elf.h | 112 +++++-
3 files changed, 868 insertions(+), 11 deletions(-)
From: Thomas Weißschuh <hidden> Date: 2026-09-08 06:33:57
All vDSO code needs to be completely position independent. Symbol
references are marked as hidden so the compiler emits PC-relative
relocations. However there are cases where the compiler may still
emit absolute relocations, as they are valid in regular PIC DSO code.
These would be resolved by the linker and will break at runtime.
This has been observed on arm64, see commit 0c314cda9325 ("arm64: vdso:
Work around invalid absolute relocations from GCC")
Introduce a tool to check for absolute relocations during the build,
as the current inline-shell logic is not expressive enough.
The check is done on the object files as the relocations will not exist
anymore in the final DSO. As there is no extension point for the
compilation of each object file, perform the validation in vdso_check.
Signed-off-by: Thomas Weißschuh <redacted>
---
Makefile | 19 ++
lib/vdso/Kconfig | 5 +
lib/vdso/Makefile | 2 +
lib/vdso/Makefile.include | 14 ++
lib/vdso/check/.gitignore | 3 +
lib/vdso/check/Makefile | 34 +++
lib/vdso/check/elf.rs | 498 ++++++++++++++++++++++++++++++++++++++++++++
lib/vdso/check/vdsocheck.rs | 154 ++++++++++++++
8 files changed, 729 insertions(+)
@@ -1559,6 +1559,25 @@ vdso_install: export INSTALL_FILES = $(vdso-install-y)vdso_install:$(Q)$(MAKE)-f$(srctree)/scripts/Makefile.vdsoinst+# ---------------------------------------------------------------------------+# vDSO check++ifdef CONFIG_RUST_IS_AVAILABLE+ifdef CONFIG_VDSO_CHECK++# Build the checker early.+prepare:vdsocheck++# If the architecture builds the vDSO early, make sure to be earlier.+PHONY+=vdso_prepare+vdso_prepare:vdsocheck++PHONY+=vdsocheck+vdsocheck:+$(Q)$(MAKE)$(build)=lib/vdso/check$@+endif+endif+# ---------------------------------------------------------------------------# Tools
@@ -6,6 +6,12 @@ GENERIC_VDSO_DIR := $(dir $(GENERIC_VDSO_MK_PATH))c-gettimeofday-$(CONFIG_GENERIC_GETTIMEOFDAY):=$(addprefix$(GENERIC_VDSO_DIR),gettimeofday.c)c-getrandom-$(CONFIG_VDSO_GETRANDOM):=$(addprefix$(GENERIC_VDSO_DIR),getrandom.c)+ifeq ($(CONFIG_RUST_IS_AVAILABLE)$(CONFIG_VDSO_CHECK),yy)+vdsocheck:=lib/vdso/check/vdsocheck+else+vdsocheck:=+endif+# This cmd checks that the vdso library does not contain dynamic relocations.# It has to be called after the linking of the vdso library and requires it# as a parameter.
@@ -13,6 +19,14 @@ c-getrandom-$(CONFIG_VDSO_GETRANDOM) := $(addprefix $(GENERIC_VDSO_DIR), getrand# As a workaround for some GNU ld ports which produce unneeded R_*_NONE# dynamic relocations, ignore R_*_NONE.quiet_cmd_vdso_check=VDSOCHK$@+ifneq ($(vdsocheck),)+cmd_vdso_check=$(vdsocheck)$(filter%.o,$(real-prereqs))$@+elsecmd_vdso_check=if$(READELF)-rW$@|grep-v_NONE|grep-q" R_\w*_";\then(echo>&2"$@: dynamic relocations are not supported";\rm-f$@;/bin/false);fi+endif++# Variant of cmd_ld which does not try to link the vdsocheck tool.+quiet_cmd_ld_vdso=VDSOLD$@+cmd_ld_vdso=$(LD)$(ld_flags)$(filter-out$(vdsocheck),$(real-prereqs))-o$@
@@ -0,0 +1,34 @@+# SPDX-License-Identifier: GPL-2.0-only++quiet_cmd_host_bindgen=HOSTBINDGEN$@+cmd_host_bindgen=$(BINDGEN)$<-o$@--depfile$(depfile)--$(HOSTBINDGEN_FLAGS)++quiet_cmd_host_rustlib=HOSTRUSTCL$@+cmd_host_rustlib=\+$(HOSTRUSTC)$(hostrust_flags)\+--emit=dep-info=$(depfile)--emit=link=$@\+--crate-typerlib\+--crate-name$(patsubst%.rlib,%,$(notdir$@))$<++uapi-directory:=$(srctree)/tools/include/uapi++# bindings.rs will be generated in the build directory, but rustc can not use+# source code from both the source and build directory together.+# Compile the binding code into a library first.+$(obj)/bindings.rs:HOSTBINDGEN_FLAGS := -I$(uapi-directory)+$(obj)/bindings.rs:$(uapi-directory)/linux/elf.hFORCE+$(callif_changed_dep,host_bindgen)++HOSTRUSTFLAGS_libbindings:=-Amissing_docs-Anon-camel-case-types+$(obj)/libbindings.rlib:$(obj)/bindings.rsFORCE+$(callif_changed_dep,host_rustlib)++targets+=bindings.rslibbindings.rlib++hostprogs+=vdsocheck+vdsocheck-rust:=y+HOSTRUSTFLAGS_vdsocheck:=--extern=bindings=$(obj)/libbindings.rlib+$(obj)/vdsocheck:$(obj)/libbindings.rlib++PHONY+=vdsocheck+vdsocheck:$(obj)/vdsocheck
@@ -0,0 +1,498 @@+// SPDX-License-Identifier: GPL-2.0++#![allow(unreachable_pub)]++usecore::fmt;+usecore::iter::Iterator;+usecore::result::Result;+usecore::str;++use::bindings;++#[derive(Debug, Copy, Clone)]+enumByteOrder{+LittleEndian,+BigEndian,+}++traitToCpu{+fnto_cpu(self,byteorder:ByteOrder)->Self;+}++macro_rules!declare_to_cpu{+($t:ty)=>{+implToCpufor$t{+fnto_cpu(self,byteorder:ByteOrder)->Self{+matchbyteorder{+ByteOrder::LittleEndian=>Self::from_le(self),+ByteOrder::BigEndian=>Self::from_be(self),+}+}+}+};+}++declare_to_cpu!(u16);+declare_to_cpu!(u32);+declare_to_cpu!(u64);++#[derive(Debug, Copy, Clone)]+enumClass{+Elf32,+Elf64,+}++enumClassAlternative<T32,T64>{+Elf32(T32),+Elf64(T64),+}++#[derive(Debug)]+pubenumParseError{+InvalidFileMagic([u8;4]),+InvalidFileClass(u32),+InvalidFileByteOrder(u32),+InvalidSectionSize,+MissingStringTable,+StrtabIndexOutOfRange,+IndexOutOfRange,+StrtabInvalidData(str::Utf8Error),+}++pubtypeParseResult<T>=Result<T,ParseError>;++implfmt::DisplayforParseError{+fnfmt(&self,f:&mutfmt::Formatter<'_>)->fmt::Result{+matchself{+ParseError::InvalidFileMagic(m)=>write!(f,"Invalid ELF magic {:?}",m),+ParseError::InvalidFileClass(c)=>write!(f,"Invalid ELF class {}",c),+ParseError::InvalidFileByteOrder(b)=>write!(f,"Invalid ELF byteorder {}",b),+ParseError::InvalidSectionSize=>write!(f,"Invalid ELF section size"),+ParseError::MissingStringTable=>write!(f,"Missing string table"),+ParseError::IndexOutOfRange=>write!(f,"Index out of range"),+ParseError::StrtabIndexOutOfRange=>write!(f,"String table index out of range"),+ParseError::StrtabInvalidData(e)=>write!(f,"Invalid data in string table: {}",e),+}+}+}++fnread_from_bytes<T:Copy>(data:&[u8])->ParseResult<T>{+ifdata.len()<core::mem::size_of::<T>(){+Err(ParseError::IndexOutOfRange)?+}+letptr=data.as_ptr()as*constT;+// SAFETY: `T` is `Copy` by the type constraints.+// `ptr` is valid as it is derived from the slice `data` above.+// `self.data.len()` being large enough is guaranteed by the runtime check above.+Ok(unsafe{ptr.read_unaligned()})+}++fnget_data_subslice(data:&[u8],offset:u64,size:u64)->ParseResult<&[u8]>{+letstart:usize=offset.try_into().map_err(|_|ParseError::IndexOutOfRange)?;+letsize:usize=size.try_into().map_err(|_|ParseError::IndexOutOfRange)?;+letend=start.checked_add(size).ok_or(ParseError::IndexOutOfRange)?;++Ok(&data[start..end])+}++/// Representation of a complete ELF file.+#[derive(Debug)]+pubstructFile<'a>{+byteorder:ByteOrder,+class:Class,+pubtype_:u16,+pubmachine:u16,+pubdata:&'a[u8],+section_headers:SectionInfo<'a>,+section_names:StrtabSection<'a>,+}++impl<'a>File<'a>{+pubfnnew_from_bytes(data:&'a[u8])->Result<Self,ParseError>{+constELF_MAGIC:[u8;4]=[+bindings::ELFMAG0asu8,+bindings::ELFMAG1asu8,+bindings::ELFMAG2asu8,+bindings::ELFMAG3asu8,+];+letehdr:bindings::elf32_hdr=read_from_bytes(data)?;++letmagic=[+ehdr.e_ident[bindings::EI_MAG0asusize],+ehdr.e_ident[bindings::EI_MAG1asusize],+ehdr.e_ident[bindings::EI_MAG2asusize],+ehdr.e_ident[bindings::EI_MAG3asusize],+];++ifmagic!=ELF_MAGIC{+returnErr(ParseError::InvalidFileMagic(magic));+}++letclass=matchehdr.e_ident[bindings::EI_CLASSasusize]asu32{+bindings::ELFCLASS32=>Class::Elf32,+bindings::ELFCLASS64=>Class::Elf64,+c=>returnErr(ParseError::InvalidFileClass(c)),+};++letbyteorder=matchehdr.e_ident[bindings::EI_DATAasusize]asu32{+bindings::ELFDATA2LSB=>ByteOrder::LittleEndian,+bindings::ELFDATA2MSB=>ByteOrder::BigEndian,+b=>returnErr(ParseError::InvalidFileByteOrder(b)),+};++let(type_,machine,shnum,shoff,shentsize,shstrndx)=matchclass{+Class::Elf32=>{+letehdr:bindings::elf32_hdr=read_from_bytes(data)?;+(+ehdr.e_type.to_cpu(byteorder),+ehdr.e_machine.to_cpu(byteorder),+ehdr.e_shnum.to_cpu(byteorder),+ehdr.e_shoff.to_cpu(byteorder).into(),+ehdr.e_shentsize.to_cpu(byteorder),+ehdr.e_shstrndx.to_cpu(byteorder),+)+}+Class::Elf64=>{+letehdr:bindings::elf64_hdr=read_from_bytes(data)?;+(+ehdr.e_type.to_cpu(byteorder),+ehdr.e_machine.to_cpu(byteorder),+ehdr.e_shnum.to_cpu(byteorder),+ehdr.e_shoff.to_cpu(byteorder),+ehdr.e_shentsize.to_cpu(byteorder),+ehdr.e_shstrndx.to_cpu(byteorder),+)+}+};++letsection_headers=SectionInfo{+byteorder,+class,+entsize:shentsize.into(),+data:get_data_subslice(data,shoff,u64::from(shnum)*u64::from(shentsize))?,+name:"<section headers>",+};++letstring_table=SectionHeaderIterator::new(§ion_headers,data)?+.nth(shstrndx.into())+.ok_or(ParseError::MissingStringTable)??;++letsection_names=StrtabSection(SectionInfo{+name:"<section header names>",+byteorder,+class,+data:string_table.data,+entsize:string_table.entsize,+});++Ok(File{+byteorder,+class,+type_,+machine,+section_headers,+section_names,+data,+})+}++pubfnsections(&self)->ParseResult<SectionIterator<'_>>{+Ok(SectionIterator{+file:self,+section_headers:SectionHeaderIterator::new(&self.section_headers,self.data)?,+})+}+}++/// High-level representation of an ELF section.+#[derive(Clone, Debug)]+pubstructSectionInfo<'a>{+byteorder:ByteOrder,+class:Class,+pubname:&'astr,+entsize:u64,+pubdata:&'a[u8],+}++/// Typed high-level iterator over all sections in a `File`.+#[derive(Debug)]+pubenumSection<'a>{+Null(SectionInfo<'a>),+Rel(RelSection<'a>),+Rela(RelaSection<'a>),+Strtab(StrtabSection<'a>),+Unknown(SectionInfo<'a>),+}++impl<'a>Section<'a>{+pubfninfo(&'aself)->&'aSectionInfo<'a>{+matchself{+Section::Null(info)|Section::Unknown(info)=>info,+Section::Rel(rel)=>&rel.0,+Section::Rela(rela)=>&rela.0,+Section::Strtab(strtab)=>&strtab.0,+}+}+}++pubstructSectionIterator<'a>{+file:&'aFile<'a>,+section_headers:SectionHeaderIterator<'a,'a>,+}++impl<'a>IteratorforSectionIterator<'a>{+typeItem=ParseResult<Section<'a>>;++fnnext(&mutself)->Option<Self::Item>{+self.section_headers.next().map(|header|{+letheader=header?;+letinfo=SectionInfo{+byteorder:self.file.byteorder,+class:self.file.class,+name:self.file.section_names.entry(header.name)?,+entsize:header.entsize,+data:header.data,+};++Ok(matchheader.type_{+bindings::SHT_NULL=>Section::Null(info),+bindings::SHT_RELA=>Section::Rela(RelaSection(info)),+bindings::SHT_REL=>Section::Rel(RelSection(info)),+bindings::SHT_STRTAB=>Section::Strtab(StrtabSection(info)),+_=>Section::Unknown(info),+})+})+}+}++/// Iterator over a section of data containing instances of type `T`.+structSectionEntityIterator<'a,T:Copy>{+data:&'a[u8],+byteorder:ByteOrder,+_phantom:core::marker::PhantomData<T>,+}++impl<'a,T:Copy>SectionEntityIterator<'a,T>{+constENTITY_SIZE:usize=core::mem::size_of::<T>();++fnnew(section:&'aSectionInfo<'a>)->ParseResult<Self>{+letdata=section.data;++ifsection.entsize!=Self::ENTITY_SIZEasu64{+returnErr(ParseError::InvalidSectionSize);+}++if!data.len().is_multiple_of(Self::ENTITY_SIZE){+returnErr(ParseError::InvalidSectionSize);+}++Ok(Self{+data,+byteorder:section.byteorder,+_phantom:core::marker::PhantomData,+})+}+}++impl<'a,T:Copy>IteratorforSectionEntityIterator<'a,T>{+typeItem=T;++fnnext(&mutself)->Option<Self::Item>{+ifself.data.len()!=0{+letptr=self.data.as_ptr()as*constT;+// SAFETY: `T` is `Copy` by the type constraints.+// `ptr` is valid as it is derived from the slice `data` above.+// `self.data.len()` being a multiple of `Self::ENTITY_SIZE` is+// guaranteed by `SectionEntityIterator::new`.+letentity:T=unsafe{ptr.read_unaligned()};+self.data=&self.data[Self::ENTITY_SIZE..];+Some(entity)+}else{+None+}+}+}++/// Class-independent representation of an entry in a section header table.+#[derive(Debug)]+structSectionHeader<'a>{+name:u32,+type_:u32,+entsize:u64,+data:&'a[u8],+}++/// Iterator over the section header table.+structSectionHeaderIterator<'f:'a,'a>(+ClassAlternative<+SectionEntityIterator<'a,bindings::elf32_shdr>,+SectionEntityIterator<'a,bindings::elf64_shdr>,+>,+&'f[u8],+);++impl<'f:'a,'a>SectionHeaderIterator<'f,'a>{+fnnew(section:&'aSectionInfo<'a>,file_data:&'f[u8])->ParseResult<Self>{+Ok(Self(+matchsection.class{+Class::Elf32=>ClassAlternative::Elf32(SectionEntityIterator::new(section)?),+Class::Elf64=>ClassAlternative::Elf64(SectionEntityIterator::new(section)?),+},+file_data,+))+}+}++impl<'f:'a,'a>IteratorforSectionHeaderIterator<'f,'a>{+typeItem=ParseResult<SectionHeader<'f>>;++fnnext(&mutself)->Option<Self::Item>{+letfile_data=self.1;++match&mutself.0{+ClassAlternative::Elf32(iter)=>iter.next().map(|n|{+Ok(SectionHeader{+name:n.sh_name.to_cpu(iter.byteorder).into(),+type_:n.sh_type.to_cpu(iter.byteorder).into(),+entsize:n.sh_entsize.to_cpu(iter.byteorder).into(),+data:get_data_subslice(+file_data,+n.sh_offset.to_cpu(iter.byteorder).into(),+n.sh_size.to_cpu(iter.byteorder).into(),+)?,+})+}),+ClassAlternative::Elf64(iter)=>iter.next().map(|n|{+Ok(SectionHeader{+name:n.sh_name.to_cpu(iter.byteorder).into(),+type_:n.sh_type.to_cpu(iter.byteorder).into(),+entsize:n.sh_entsize.to_cpu(iter.byteorder).into(),+data:get_data_subslice(+file_data,+n.sh_offset.to_cpu(iter.byteorder).into(),+n.sh_size.to_cpu(iter.byteorder).into(),+)?,+})+}),+}+}+}++/// High-level interface to a SHT_STRTAB string table.+#[derive(Debug)]+pubstructStrtabSection<'a>(SectionInfo<'a>);++impl<'a>StrtabSection<'a>{+pubfnentry(&'aself,index:u32)->ParseResult<&'astr>{+letdata=self.0.data;+letindex=indexasusize;++ifindex>=data.len(){+Err(ParseError::StrtabIndexOutOfRange)+}else{+letlen=data[index..]+.iter()+.position(|b|*b==0x00)+.ok_or(ParseError::StrtabIndexOutOfRange)?;+lets=str::from_utf8(&data[index..index+len])+.map_err(|e|ParseError::StrtabInvalidData(e))?;+Ok(s)+}+}+}++/// High-level interface to a SHT_REL relocation table.+#[derive(Debug)]+pubstructRelSection<'a>(SectionInfo<'a>);++impl<'a>RelSection<'a>{+pubfnentries(&'aself)->ParseResult<RelSectionIterator<'a>>{+RelSectionIterator::new(&self.0)+}+}++#[derive(Debug)]+pubstructRel{+pubtype_:u32,+}++pubstructRelSectionIterator<'a>(+ClassAlternative<+SectionEntityIterator<'a,bindings::elf32_rel>,+SectionEntityIterator<'a,bindings::elf64_rel>,+>,+);++impl<'a>RelSectionIterator<'a>{+fnnew(section:&'aSectionInfo<'a>)->ParseResult<Self>{+Ok(Self(matchsection.class{+Class::Elf32=>ClassAlternative::Elf32(SectionEntityIterator::new(section)?),+Class::Elf64=>ClassAlternative::Elf64(SectionEntityIterator::new(section)?),+}))+}+}++impl<'a>IteratorforRelSectionIterator<'a>{+typeItem=Rel;++fnnext(&mutself)->Option<Self::Item>{+match&mutself.0{+ClassAlternative::Elf32(iter)=>iter.next().map(|n|{+lettype_=n.r_info.to_cpu(iter.byteorder)&0xff;+Self::Item{type_}+}),+ClassAlternative::Elf64(iter)=>iter.next().map(|n|{+lettype_=n.r_info.to_cpu(iter.byteorder)asu32;+Self::Item{type_}+}),+}+}+}++/// High-level interface to a SHT_RELA relocation table.+#[derive(Debug)]+pubstructRelaSection<'a>(SectionInfo<'a>);++impl<'a>RelaSection<'a>{+pubfnentries(&'aself)->ParseResult<RelaSectionIterator<'a>>{+RelaSectionIterator::new(&self.0)+}+}++#[derive(Debug)]+pubstructRela{+pubtype_:u32,+}++pubstructRelaSectionIterator<'a>(+ClassAlternative<+SectionEntityIterator<'a,bindings::elf32_rela>,+SectionEntityIterator<'a,bindings::elf64_rela>,+>,+);++impl<'a>RelaSectionIterator<'a>{+fnnew(section:&'aSectionInfo<'a>)->ParseResult<Self>{+Ok(Self(matchsection.class{+Class::Elf32=>ClassAlternative::Elf32(SectionEntityIterator::new(section)?),+Class::Elf64=>ClassAlternative::Elf64(SectionEntityIterator::new(section)?),+}))+}+}++impl<'a>IteratorforRelaSectionIterator<'a>{+typeItem=Rela;++fnnext(&mutself)->Option<Self::Item>{+match&mutself.0{+ClassAlternative::Elf32(iter)=>iter.next().map(|n|{+lettype_=n.r_info.to_cpu(iter.byteorder)&0xff;+Self::Item{type_}+}),+ClassAlternative::Elf64(iter)=>iter.next().map(|n|{+lettype_=n.r_info.to_cpu(iter.byteorder)asu32;+Self::Item{type_}+}),+}+}+}
From: Thomas Weißschuh <hidden> Date: 2026-09-08 06:33:58
The vdsocheck tool validates the object files and final .so library.
It can detect if the compiler created relocations which are incompatible
with the vDSO which need to be worked around.
Wire it up for the architecture.
Signed-off-by: Thomas Weißschuh <redacted>
---
arch/x86/Kconfig | 1 +
arch/x86/entry/vdso/common/Makefile.include | 2 +-
lib/vdso/check/vdsocheck.rs | 14 ++++++++++++++
3 files changed, 16 insertions(+), 1 deletion(-)
From: Thomas Weißschuh <hidden> Date: 2026-09-08 06:33:59
The vdsocheck tool validates the object files and final .so library.
It can detect if the compiler created relocations which are incompatible
with the vDSO which need to be worked around.
Wire it up for the architecture.
Signed-off-by: Thomas Weißschuh <redacted>
---
arch/arm/mm/Kconfig | 1 +
arch/arm/vdso/Makefile | 4 ++--
lib/vdso/check/vdsocheck.rs | 9 +++++++++
3 files changed, 12 insertions(+), 2 deletions(-)
@@ -37,7 +37,7 @@ endif$(obj)/vdso.o :$(obj)/vdso.so# Link rule for the .so file-$(obj)/vdso.so.raw:$(obj)/vdso.lds$(obj-vdso)FORCE+$(obj)/vdso.so.raw:$(obj)/vdso.lds$(obj-vdso)$(vdsocheck)FORCE$(callif_changed,vdsold_and_vdso_check)$(obj)/vdso.so.dbg:$(obj)/vdso.so.raw$(obj)/vdsomungeFORCE
@@ -50,7 +50,7 @@ $(obj)/%.so: $(obj)/%.so.dbg FORCE# Actual build commandsquiet_cmd_vdsold_and_vdso_check=LD$@-cmd_vdsold_and_vdso_check=$(cmd_ld);$(cmd_vdso_check)+cmd_vdsold_and_vdso_check=$(cmd_ld_vdso);$(cmd_vdso_check)quiet_cmd_vdsomunge=MUNGE$@cmd_vdsomunge=$(objtree)/$(obj)/vdsomunge$<$@
From: Thomas Weißschuh <hidden> Date: 2026-09-08 06:34:00
The vdsocheck tool validates the object files and final .so library.
It can detect if the compiler created relocations which are incompatible
with the vDSO which need to be worked around.
Wire it up for the architecture.
The compat vDSO will be handled by the existing 32-bit ARM configuration.
Signed-off-by: Thomas Weißschuh <redacted>
---
arch/arm64/Kconfig | 1 +
arch/arm64/kernel/vdso/Makefile | 4 ++--
lib/vdso/check/vdsocheck.rs | 12 ++++++++++++
3 files changed, 15 insertions(+), 2 deletions(-)
@@ -61,7 +61,7 @@ targets += vdso.ldsCPPFLAGS_vdso.lds+=-P-C-U$(ARCH)# Link rule for the .so file, .lds has to be first-$(obj)/vdso.so.dbg:$(obj)/vdso.lds$(obj-vdso)FORCE+$(obj)/vdso.so.dbg:$(obj)/vdso.lds$(obj-vdso)$(vdsocheck)FORCE$(callif_changed,vdsold_and_vdso_check)# Strip rule for the .so file
@@ -79,4 +79,4 @@ include/generated/vdso-offsets.h: $(obj)/vdso.so.dbg FORCE# Actual build commandsquiet_cmd_vdsold_and_vdso_check=LD$@-cmd_vdsold_and_vdso_check=$(cmd_ld);$(cmd_vdso_check)+cmd_vdsold_and_vdso_check=$(cmd_ld_vdso);$(cmd_vdso_check)
From: Thomas Weißschuh <hidden> Date: 2026-09-08 06:34:02
These are used by userspace and are necessary for the vdsocheck tool.
They share the numbers with their 64-bit variants.
Also update the copy in tools/ so they can be used by vdsocheck.
Signed-off-by: Thomas Weißschuh <redacted>
---
include/uapi/linux/elf-r.h | 7 ++++++-
tools/include/uapi/linux/elf-r.h | 7 ++++++-
2 files changed, 12 insertions(+), 2 deletions(-)
From: Thomas Weißschuh <hidden> Date: 2026-09-08 06:34:03
The vdsocheck tool validates the object files and final .so library.
It can detect if the compiler created relocations which are incompatible
with the vDSO which need to be worked around.
Wire it up for the architecture.
Signed-off-by: Thomas Weißschuh <redacted>
---
arch/powerpc/Kconfig | 1 +
arch/powerpc/kernel/vdso/Makefile | 4 ++--
lib/vdso/check/vdsocheck.rs | 27 +++++++++++++++++++++++++++
3 files changed, 30 insertions(+), 2 deletions(-)
@@ -81,9 +81,9 @@ targets += vdso64.ldsCPPFLAGS_vdso64.lds+=-P-C# link rule for the .so file, .lds has to be first-$(obj)/vdso32.so.dbg:$(obj)/vdso32.lds$(obj-vdso32)$(obj)/vgettimeofday-32.o$(obj)/vgetrandom-32.o$(obj)/crtsavres-32.oFORCE+$(obj)/vdso32.so.dbg:$(obj)/vdso32.lds$(obj-vdso32)$(obj)/vgettimeofday-32.o$(obj)/vgetrandom-32.o$(obj)/crtsavres-32.o$(vdsocheck)FORCE$(callif_changed,vdso32ld_and_check)-$(obj)/vdso64.so.dbg:$(obj)/vdso64.lds$(obj-vdso64)$(obj)/vgettimeofday-64.o$(obj)/vgetrandom-64.oFORCE+$(obj)/vdso64.so.dbg:$(obj)/vdso64.lds$(obj-vdso64)$(obj)/vgettimeofday-64.o$(obj)/vgetrandom-64.o$(vdsocheck)FORCE$(callif_changed,vdso64ld_and_check)# assembly rules for the .S files
From: Thomas Weißschuh <hidden> Date: 2026-09-08 06:34:04
The vdsocheck tool validates the object files and final .so library.
It can detect if the compiler created relocations which are incompatible
with the vDSO which need to be worked around.
Wire it up for the architecture.
Signed-off-by: Thomas Weißschuh <redacted>
---
arch/riscv/Kconfig | 1 +
arch/riscv/kernel/vdso/Makefile | 4 ++--
lib/vdso/check/vdsocheck.rs | 26 ++++++++++++++++++++++++++
3 files changed, 29 insertions(+), 2 deletions(-)
@@ -74,7 +74,7 @@ endif$(obj)/$(vdso_o):$(obj)/$(vdso_so)# link rule for the .so file, .lds has to be first-$(obj)/$(vdso_so_dbg):$(obj)/$(vdso_lds)$(obj-vdso)FORCE+$(obj)/$(vdso_so_dbg):$(obj)/$(vdso_lds)$(obj-vdso)$(vdsocheck)FORCE$(callif_changed,vdsold_and_check)LDFLAGS_$(vdso_so_dbg)=-shared-soname=linux-vdso.so.1\--build-id=sha1--eh-frame-hdr
@@ -96,7 +96,7 @@ include/generated/$(vdso_offsets): $(obj)/$(vdso_so_dbg) FORCE# The DSO images are built using a special linker script# Make sure only to export the intended __vdso_xxx symbol offsets.quiet_cmd_vdsold_and_check=VDSOLD$@-cmd_vdsold_and_check=$(LD)$(CFI_FULL)$(ld_flags)-T$(filter-outFORCE,$^)-o$@.tmp&&\+cmd_vdsold_and_check=$(LD)$(CFI_FULL)$(ld_flags)-T$(filter-outFORCE$(vdsocheck),$^)-o$@.tmp&&\$(OBJCOPY)$(patsubst%,-G__vdso_%,$(vdso-syms))$@.tmp$@&&\rm$@.tmp&&\$(cmd_vdso_check)
From: Thomas Weißschuh <hidden> Date: 2026-09-08 06:34:05
The vdsocheck tool validates the object files and final .so library.
It can detect if the compiler created relocations which are incompatible
with the vDSO which need to be worked around.
Wire it up for the architecture.
Signed-off-by: Thomas Weißschuh <redacted>
---
arch/loongarch/Kconfig | 1 +
arch/loongarch/vdso/Makefile | 4 ++--
lib/vdso/check/vdsocheck.rs | 26 ++++++++++++++++++++++++++
3 files changed, 29 insertions(+), 2 deletions(-)
From: Thomas Weißschuh <hidden> Date: 2026-09-08 06:34:07
The vdsocheck tool validates the object files and final .so library.
It can detect if the compiler created relocations which are incompatible
with the vDSO which need to be worked around.
Wire it up for the architecture.
Signed-off-by: Thomas Weißschuh <redacted>
---
arch/s390/Kconfig | 1 +
arch/s390/kernel/vdso/Makefile | 4 ++--
lib/vdso/check/vdsocheck.rs | 9 +++++++++
3 files changed, 12 insertions(+), 2 deletions(-)
@@ -44,10 +44,10 @@ CPPFLAGS_vdso.lds += -P -C -U$(ARCH)$(obj)/vdso_wrapper.o :$(obj)/vdso.soquiet_cmd_vdso_and_check=VDSO$@-cmd_vdso_and_check=$(cmd_ld);$(cmd_vdso_check)+cmd_vdso_and_check=$(cmd_ld_vdso);$(cmd_vdso_check)# link rule for the .so file, .lds has to be first-$(obj)/vdso.so.dbg:$(obj)/vdso.lds$(obj-vdso)$(obj-cvdso)FORCE+$(obj)/vdso.so.dbg:$(obj)/vdso.lds$(obj-vdso)$(obj-cvdso)$(vdsocheck)FORCE$(callif_changed,vdso_and_check)# strip rule for the .so file
From: Thomas Weißschuh <hidden> Date: 2026-09-08 06:34:07
These are used by userspace and are necessary for the vdsocheck tool.
Also update the copy in tools/ so they can be used by vdsocheck.
Signed-off-by: Thomas Weißschuh <redacted>
---
include/uapi/linux/elf-r.h | 4 ++++
tools/include/uapi/linux/elf-r.h | 4 ++++
2 files changed, 8 insertions(+)
From: Thomas Weißschuh <hidden> Date: 2026-09-08 06:34:08
The vdsocheck tool validates the object files and final .so library.
It can detect if the compiler created relocations which are incompatible
with the vDSO which need to be worked around.
Wire it up for the architecture.
Signed-off-by: Thomas Weißschuh <redacted>
---
arch/mips/Kconfig | 1 +
arch/mips/vdso/Makefile | 8 ++++----
lib/vdso/check/vdsocheck.rs | 15 +++++++++++++++
3 files changed, 20 insertions(+), 4 deletions(-)
From: Thomas Weißschuh <hidden> Date: 2026-09-08 06:34:09
The vdsocheck tool validates the object files and final .so library.
It can detect if the compiler created relocations which are incompatible
with the vDSO which need to be worked around.
Wire it up for the architecture.
Signed-off-by: Thomas Weißschuh <redacted>
---
arch/sparc/Kconfig | 1 +
arch/sparc/vdso/Makefile | 5 +++--
lib/vdso/check/vdsocheck.rs | 7 +++++++
3 files changed, 11 insertions(+), 2 deletions(-)
From: Peter Zijlstra <peterz@infradead.org> Date: 2026-09-08 07:19:25
On Tue, Sep 08, 2026 at 08:33:46AM +0200, Thomas Weißschuh wrote:
All vDSO code needs to be completely position independent. Symbol
references are marked as hidden so the compiler emits PC-relative
relocations. However there are cases where the compiler may still
emit absolute relocations, as they are valid in regular PIC DSO code.
These would be resolved by the linker and will break at runtime.
This has been observed on arm64, see commit 0c314cda9325 ("arm64: vdso:
Work around invalid absolute relocations from GCC")
Introduce a tool to check for absolute relocations during the build,
as the current inline-shell logic is not expressive enough.
The check is done on the object files as the relocations will not exist
anymore in the final DSO. As there is no extension point for the
compilation of each object file, perform the validation in vdso_check.
Signed-off-by: Thomas Weißschuh <redacted>
---
Makefile | 19 ++
lib/vdso/Kconfig | 5 +
lib/vdso/Makefile | 2 +
lib/vdso/Makefile.include | 14 ++
lib/vdso/check/.gitignore | 3 +
lib/vdso/check/Makefile | 34 +++
lib/vdso/check/elf.rs | 498 ++++++++++++++++++++++++++++++++++++++++++++
lib/vdso/check/vdsocheck.rs | 154 ++++++++++++++
8 files changed, 729 insertions(+)
Urgh, does this mean I have to have rust installed just to build a
kernel now?
From: Thomas Weißschuh <hidden> Date: 2026-09-08 07:35:49
On Tue, Sep 08, 2026 at 09:19:11AM +0200, Peter Zijlstra wrote:
On Tue, Sep 08, 2026 at 08:33:46AM +0200, Thomas Weißschuh wrote:
quoted
All vDSO code needs to be completely position independent. Symbol
references are marked as hidden so the compiler emits PC-relative
relocations. However there are cases where the compiler may still
emit absolute relocations, as they are valid in regular PIC DSO code.
These would be resolved by the linker and will break at runtime.
This has been observed on arm64, see commit 0c314cda9325 ("arm64: vdso:
Work around invalid absolute relocations from GCC")
Introduce a tool to check for absolute relocations during the build,
as the current inline-shell logic is not expressive enough.
The check is done on the object files as the relocations will not exist
anymore in the final DSO. As there is no extension point for the
compilation of each object file, perform the validation in vdso_check.
Signed-off-by: Thomas Weißschuh <redacted>
---
Makefile | 19 ++
lib/vdso/Kconfig | 5 +
lib/vdso/Makefile | 2 +
lib/vdso/Makefile.include | 14 ++
lib/vdso/check/.gitignore | 3 +
lib/vdso/check/Makefile | 34 +++
lib/vdso/check/elf.rs | 498 ++++++++++++++++++++++++++++++++++++++++++++
lib/vdso/check/vdsocheck.rs | 154 ++++++++++++++
8 files changed, 729 insertions(+)
Urgh, does this mean I have to have rust installed just to build a
kernel now?
No.
If you don't have rust installed the build will instead use the existing shell
script for a less thorough check. We only need one build machine at some point
to have rust installed to report issues and this check to be useful.
Thomas
From: Peter Zijlstra <peterz@infradead.org> Date: 2026-09-08 07:37:14
On Tue, Sep 08, 2026 at 09:35:46AM +0200, Thomas Weißschuh wrote:
On Tue, Sep 08, 2026 at 09:19:11AM +0200, Peter Zijlstra wrote:
quoted
On Tue, Sep 08, 2026 at 08:33:46AM +0200, Thomas Weißschuh wrote:
quoted
All vDSO code needs to be completely position independent. Symbol
references are marked as hidden so the compiler emits PC-relative
relocations. However there are cases where the compiler may still
emit absolute relocations, as they are valid in regular PIC DSO code.
These would be resolved by the linker and will break at runtime.
This has been observed on arm64, see commit 0c314cda9325 ("arm64: vdso:
Work around invalid absolute relocations from GCC")
Introduce a tool to check for absolute relocations during the build,
as the current inline-shell logic is not expressive enough.
The check is done on the object files as the relocations will not exist
anymore in the final DSO. As there is no extension point for the
compilation of each object file, perform the validation in vdso_check.
Signed-off-by: Thomas Weißschuh <redacted>
---
Makefile | 19 ++
lib/vdso/Kconfig | 5 +
lib/vdso/Makefile | 2 +
lib/vdso/Makefile.include | 14 ++
lib/vdso/check/.gitignore | 3 +
lib/vdso/check/Makefile | 34 +++
lib/vdso/check/elf.rs | 498 ++++++++++++++++++++++++++++++++++++++++++++
lib/vdso/check/vdsocheck.rs | 154 ++++++++++++++
8 files changed, 729 insertions(+)
Urgh, does this mean I have to have rust installed just to build a
kernel now?
No.
If you don't have rust installed the build will instead use the existing shell
script for a less thorough check. We only need one build machine at some point
to have rust installed to report issues and this check to be useful.
Pick up changes from the UAPI ELF header files.
This picks up general changes to elf.h, elf-em.h which was forgotten
previously and the new elf-r.h.
Signed-off-by: Thomas Weißschuh <redacted>
---
Cc: Arnaldo Carvalho de Melo <redacted>
---
tools/include/uapi/linux/elf-em.h | 71 ++++
tools/include/uapi/linux/elf-r.h | 696 ++++++++++++++++++++++++++++++++++++++
tools/include/uapi/linux/elf.h | 112 +++++-
3 files changed, 868 insertions(+), 11 deletions(-)
Getting the following warning when applying this series with 'b4 shazam'.
/home/chleroy/linux-powerpc/.git/rebase-apply/patch:846: trailing whitespace.
Seems to come from here.
While the numeric constants for relocations are architecture specific,
it is still useful to get access to them from other architectures.
Also the definitions are useful for userspace in general.
For example tools processing elf files during a kernel cross-compilation
can make use of them.
Introduce a dedicated header for them, similar to the elf-em.h header.
For now the header is empty but it will be filled step by step in
upcomming commits.
Signed-off-by: Thomas Weißschuh <redacted>
These constants are useful for cross-platform userspace, for example to
process ELF files during kernel cross-compilation.
Move them from the kernel-private architecture-specific header to the UAPI.
Signed-off-by: Thomas Weißschuh <redacted>
Pick up changes from the UAPI ELF header files.
This picks up general changes to elf.h, elf-em.h which was forgotten
previously and the new elf-r.h.
Signed-off-by: Thomas Weißschuh <redacted>
---
Cc: Arnaldo Carvalho de Melo <redacted>
---
tools/include/uapi/linux/elf-em.h | 71 ++++
tools/include/uapi/linux/elf-r.h | 696 ++++++++++++++++++++++++++++++++++++++
tools/include/uapi/linux/elf.h | 112 +++++-
3 files changed, 868 insertions(+), 11 deletions(-)
These are used by userspace and are necessary for the vdsocheck tool.
They share the numbers with their 64-bit variants.
Also update the copy in tools/ so they can be used by vdsocheck.
Signed-off-by: Thomas Weißschuh <redacted>
From: Thomas Weißschuh <hidden> Date: 2026-09-08 09:37:37
On Tue, Sep 08, 2026 at 10:56:58AM +0200, Christophe Leroy (CS GROUP) wrote:
Le 08/09/2026 à 08:33, Thomas Weißschuh a écrit :
quoted
Pick up changes from the UAPI ELF header files.
This picks up general changes to elf.h, elf-em.h which was forgotten
previously and the new elf-r.h.
Signed-off-by: Thomas Weißschuh <redacted>
---
Cc: Arnaldo Carvalho de Melo <redacted>
---
tools/include/uapi/linux/elf-em.h | 71 ++++
tools/include/uapi/linux/elf-r.h | 696 ++++++++++++++++++++++++++++++++++++++
tools/include/uapi/linux/elf.h | 112 +++++-
3 files changed, 868 insertions(+), 11 deletions(-)
Getting the following warning when applying this series with 'b4 shazam'.
/home/chleroy/linux-powerpc/.git/rebase-apply/patch:846: trailing
whitespace.
Seems to come from here.
That's also present in include/uapi/linux/elf.h.
I'll add a fix for that, too.
On Tue, Sep 08, 2026 at 08:33:36AM +0200, Thomas Weißschuh wrote:
These constants are useful for cross-platform userspace, for example to
process ELF files during kernel cross-compilation.
Move them from the kernel-private architecture-specific header to the UAPI.
From: R Nageswara Sastry <hidden> Date: 2026-09-08 14:03:22
On 08.09.2026 12:03 PM, Thomas Weißschuh wrote:
These constants are useful for cross-platform userspace, for example to
process ELF files during kernel cross-compilation.
Move them from the kernel-private architecture-specific header to the UAPI.
Signed-off-by: Thomas Weißschuh <redacted>
Tested-by: R Nageswara Sastry <redacted>
System: ppc64le LPAR (IBM POWER), Linux 7.3-rc2
From: R Nageswara Sastry <hidden> Date: 2026-09-08 14:03:48
On 08.09.2026 12:03 PM, Thomas Weißschuh wrote:
These are used by userspace and are necessary for the vdsocheck tool.
They share the numbers with their 64-bit variants.
Also update the copy in tools/ so they can be used by vdsocheck.
Signed-off-by: Thomas Weißschuh <redacted>
Tested-by: R Nageswara Sastry <redacted>
System: ppc64le LPAR (IBM POWER), Linux 7.3-rc2
From: R Nageswara Sastry <hidden> Date: 2026-09-08 14:04:22
On 08.09.2026 12:03 PM, Thomas Weißschuh wrote:
The vdsocheck tool validates the object files and final .so library.
It can detect if the compiler created relocations which are incompatible
with the vDSO which need to be worked around.
Wire it up for the architecture.
Signed-off-by: Thomas Weißschuh <redacted>
Tested-by: R Nageswara Sastry <redacted>
System: ppc64le LPAR (IBM POWER), Linux 7.3-rc2
@@ -81,9 +81,9 @@ targets += vdso64.ldsCPPFLAGS_vdso64.lds+=-P-C # link rule for the .so file, .lds has to be first-$(obj)/vdso32.so.dbg:$(obj)/vdso32.lds$(obj-vdso32)$(obj)/vgettimeofday-32.o$(obj)/vgetrandom-32.o$(obj)/crtsavres-32.oFORCE+$(obj)/vdso32.so.dbg:$(obj)/vdso32.lds$(obj-vdso32)$(obj)/vgettimeofday-32.o$(obj)/vgetrandom-32.o$(obj)/crtsavres-32.o$(vdsocheck)FORCE$(callif_changed,vdso32ld_and_check)-$(obj)/vdso64.so.dbg:$(obj)/vdso64.lds$(obj-vdso64)$(obj)/vgettimeofday-64.o$(obj)/vgetrandom-64.oFORCE+$(obj)/vdso64.so.dbg:$(obj)/vdso64.lds$(obj-vdso64)$(obj)/vgettimeofday-64.o$(obj)/vgetrandom-64.o$(vdsocheck)FORCE$(callif_changed,vdso64ld_and_check) # assembly rules for the .S files
From: Thomas Weißschuh <hidden> Date: 2026-09-08 14:26:10
On Tue, Sep 08, 2026 at 06:55:13AM -0700, Borislav Petkov wrote:
On Tue, Sep 08, 2026 at 08:33:36AM +0200, Thomas Weißschuh wrote:
quoted
These constants are useful for cross-platform userspace, for example to
process ELF files during kernel cross-compilation.
Move them from the kernel-private architecture-specific header to the UAPI.
Why UAPI?
Why not include/linux/ ?
The existing, generic ELF definitions are there.
The ELF stuff in include/linux/ is highly specific to Linux.
Also later in the patchset I want to expose the definitions to the
tools/ build. Exposing generic UAPI definitions to tools/ is a much
easier sell than include/linux/.
Thomas
On Tue, Sep 08, 2026 at 08:33:36AM +0200, Thomas Weißschuh wrote:
quoted
These constants are useful for cross-platform userspace, for example to
process ELF files during kernel cross-compilation.
Move them from the kernel-private architecture-specific header to the UAPI.
Why UAPI?
Why not include/linux/ ?
I guess because on some architectures it is already in UAPI, see for instance powerpc in patch 5 ?
Christophe
The vdsocheck tool validates the object files and final .so library.
It can detect if the compiler created relocations which are incompatible
with the vDSO which need to be worked around.
Wire it up for the architecture.
Signed-off-by: Thomas Weißschuh <redacted>
---
arch/powerpc/Kconfig | 1 +
arch/powerpc/kernel/vdso/Makefile | 4 ++--
lib/vdso/check/vdsocheck.rs | 27 +++++++++++++++++++++++++++
3 files changed, 30 insertions(+), 2 deletions(-)
@@ -81,9 +81,9 @@ targets += vdso64.ldsCPPFLAGS_vdso64.lds+=-P-C # link rule for the .so file, .lds has to be first-$(obj)/vdso32.so.dbg:$(obj)/vdso32.lds$(obj-vdso32)$(obj)/vgettimeofday-32.o$(obj)/vgetrandom-32.o$(obj)/crtsavres-32.oFORCE+$(obj)/vdso32.so.dbg:$(obj)/vdso32.lds$(obj-vdso32)$(obj)/vgettimeofday-32.o$(obj)/vgetrandom-32.o$(obj)/crtsavres-32.o$(vdsocheck)FORCE$(callif_changed,vdso32ld_and_check)-$(obj)/vdso64.so.dbg:$(obj)/vdso64.lds$(obj-vdso64)$(obj)/vgettimeofday-64.o$(obj)/vgetrandom-64.oFORCE+$(obj)/vdso64.so.dbg:$(obj)/vdso64.lds$(obj-vdso64)$(obj)/vgettimeofday-64.o$(obj)/vgetrandom-64.o$(vdsocheck)FORCE$(callif_changed,vdso64ld_and_check) # assembly rules for the .S files
On Tue, Sep 08, 2026 at 04:26:00PM +0200, Thomas Weißschuh wrote:
The existing, generic ELF definitions are there.
The ELF stuff in include/linux/ is highly specific to Linux.
And putting them in UAPI casts them in stone. I wouldn't want to maintain them
forever if not necessary.
Also later in the patchset I want to expose the definitions to the
tools/ build. Exposing generic UAPI definitions to tools/ is a much
easier sell than include/linux/.
tools/ *copies* kernel headers on a "they're needed" basis. No need to put
anything in UAPI for that.
It's even written down: tools/include/uapi/README
--
Regards/Gruss,
Boris.
https://people.kernel.org/tglx/notes-about-netiquette
From: Thomas Weißschuh <hidden> Date: 2026-09-09 05:59:53
On Tue, Sep 08, 2026 at 08:12:38AM -0700, Borislav Petkov wrote:
On Tue, Sep 08, 2026 at 04:26:00PM +0200, Thomas Weißschuh wrote:
quoted
The existing, generic ELF definitions are there.
The ELF stuff in include/linux/ is highly specific to Linux.
And putting them in UAPI casts them in stone. I wouldn't want to maintain them
forever if not necessary.
These names and numbers are defined by the architectures' ELF specifications.
They are already cast in stone. For example see Table 4.9 of [0].
Changing them would break compilers, linkers, loaders and more or less every
existing ELF binary.
quoted
Also later in the patchset I want to expose the definitions to the
tools/ build. Exposing generic UAPI definitions to tools/ is a much
easier sell than include/linux/.
tools/ *copies* kernel headers on a "they're needed" basis. No need to put
anything in UAPI for that.
It's even written down: tools/include/uapi/README
@@ -81,9 +81,9 @@ targets += vdso64.ldsCPPFLAGS_vdso64.lds+=-P-C # link rule for the .so file, .lds has to be first-$(obj)/vdso32.so.dbg:$(obj)/vdso32.lds$(obj-vdso32)$(obj)/vgettimeofday-32.o$(obj)/vgetrandom-32.o$(obj)/crtsavres-32.oFORCE+$(obj)/vdso32.so.dbg:$(obj)/vdso32.lds$(obj-vdso32)$(obj)/vgettimeofday-32.o$(obj)/vgetrandom-32.o$(obj)/crtsavres-32.o$(vdsocheck)FORCE$(callif_changed,vdso32ld_and_check)-$(obj)/vdso64.so.dbg:$(obj)/vdso64.lds$(obj-vdso64)$(obj)/vgettimeofday-64.o$(obj)/vgetrandom-64.oFORCE+$(obj)/vdso64.so.dbg:$(obj)/vdso64.lds$(obj-vdso64)$(obj)/vgettimeofday-64.o$(obj)/vgetrandom-64.o$(vdsocheck)FORCE$(callif_changed,vdso64ld_and_check) # assembly rules for the .S files
Not sure this is correct, see commit 42ed6d56ade2 ("powerpc/vdso: Block
R_PPC_REL24 relocations")
(...)
The mentioned commit prevents the relocation in the final vDSO,
while my patch allows it in the intermediate object files.
In the final vDSO no relocations are accepted whatsovever.
On Wed, Sep 09, 2026 at 07:59:51AM +0200, Thomas Weißschuh wrote:
These names and numbers are defined by the architectures' ELF specifications.
They are already cast in stone. For example see Table 4.9 of [0].
Changing them would break compilers, linkers, loaders and more or less every
existing ELF binary.
So?
Your goal is to provide them to tools/. You want to provide them to
*everything*. See the discrepance here?
That is the documentation for the tools UAPI headers.
Did you even read that file?
"Why we want a copy of kernel headers in tools?
==============================================
There used to be no copies, with tools/ code using kernel headers
directly. From time to time tools/perf/ broke due to legitimate kernel
hacking. At some point Linus complained about such direct usage. Then we
adopted the current model.
The way these headers are used in perf are not restricted to just
including them to compile something.
..."
Just read the damn thing before you reply.
Also we already have other, closely related, ELF constants in the UAPI,
see {,tools/}include/uapi/linux/elf{,-em}.h.
Srsly?!?
You moved them there:
commit 626fd35278295fbb21f2da331cd8028e9738d965
Author: Thomas Weißschuh [off-list ref]
Date: Wed Feb 26 12:44:46 2025 +0100
tools/include: Add uapi/linux/elf.h
It will be used by the vDSO selftests.
Looking at the rest, it looks like some elf bits got exported, you added some
more and that ship has sailed. I still think us providing headers is
completely unnecessary and it will come to cause conflicts eventually but hey,
not my problem.
--
Regards/Gruss,
Boris.
https://people.kernel.org/tglx/notes-about-netiquette
From: "H. Peter Anvin" <hpa@zytor.com> Date: 2026-09-09 19:30:15
On September 9, 2026 7:49:30 AM PDT, Borislav Petkov [off-list ref] wrote:
On Wed, Sep 09, 2026 at 07:59:51AM +0200, Thomas Weißschuh wrote:
quoted
These names and numbers are defined by the architectures' ELF specifications.
They are already cast in stone. For example see Table 4.9 of [0].
Changing them would break compilers, linkers, loaders and more or less every
existing ELF binary.
So?
Your goal is to provide them to tools/. You want to provide them to
*everything*. See the discrepance here?
quoted
That is the documentation for the tools UAPI headers.
Did you even read that file?
"Why we want a copy of kernel headers in tools?
==============================================
There used to be no copies, with tools/ code using kernel headers
directly. From time to time tools/perf/ broke due to legitimate kernel
hacking. At some point Linus complained about such direct usage. Then we
adopted the current model.
The way these headers are used in perf are not restricted to just
including them to compile something.
..."
Just read the damn thing before you reply.
quoted
Also we already have other, closely related, ELF constants in the UAPI,
see {,tools/}include/uapi/linux/elf{,-em}.h.
Srsly?!?
You moved them there:
commit 626fd35278295fbb21f2da331cd8028e9738d965
Author: Thomas Weißschuh [off-list ref]
Date: Wed Feb 26 12:44:46 2025 +0100
tools/include: Add uapi/linux/elf.h
It will be used by the vDSO selftests.
Looking at the rest, it looks like some elf bits got exported, you added some
more and that ship has sailed. I still think us providing headers is
completely unnecessary and it will come to cause conflicts eventually but hey,
not my problem.
I do believe there are *some* headers that would be reasonably to export to tools/ beyond what it is in uapi; a major reason for that is that the tools are suffering from a crazy level of internal inconsistency right now.
Basically uapi ⊂ treewide ⊂ kernel, but also treewide ⊂ tools common ⊂ tool-specific...
From: "H. Peter Anvin" <hpa@zytor.com> Date: 2026-09-09 19:33:20
On September 8, 2026 12:19:11 AM PDT, Peter Zijlstra [off-list ref] wrote:
On Tue, Sep 08, 2026 at 08:33:46AM +0200, Thomas Weißschuh wrote:
quoted
All vDSO code needs to be completely position independent. Symbol
references are marked as hidden so the compiler emits PC-relative
relocations. However there are cases where the compiler may still
emit absolute relocations, as they are valid in regular PIC DSO code.
These would be resolved by the linker and will break at runtime.
This has been observed on arm64, see commit 0c314cda9325 ("arm64: vdso:
Work around invalid absolute relocations from GCC")
Introduce a tool to check for absolute relocations during the build,
as the current inline-shell logic is not expressive enough.
The check is done on the object files as the relocations will not exist
anymore in the final DSO. As there is no extension point for the
compilation of each object file, perform the validation in vdso_check.
Signed-off-by: Thomas Weißschuh <redacted>
---
Makefile | 19 ++
lib/vdso/Kconfig | 5 +
lib/vdso/Makefile | 2 +
lib/vdso/Makefile.include | 14 ++
lib/vdso/check/.gitignore | 3 +
lib/vdso/check/Makefile | 34 +++
lib/vdso/check/elf.rs | 498 ++++++++++++++++++++++++++++++++++++++++++++
lib/vdso/check/vdsocheck.rs | 154 ++++++++++++++
8 files changed, 729 insertions(+)
Urgh, does this mean I have to have rust installed just to build a
kernel now?
It was going to happen, and now we'll have to suffer the instability of rust...
On Wed, Sep 09, 2026 at 12:27:30PM -0700, H. Peter Anvin wrote:
I do believe there are *some* headers that would be reasonably to export to
tools/ beyond what it is in uapi; a major reason for that is that the tools
are suffering from a crazy level of internal inconsistency right now.
On Tue, Sep 08, 2026 at 08:33:39AM +0200, Thomas Weißschuh wrote:
quoted hunk
These constants are useful for cross-platform userspace, for example to
process ELF files during kernel cross-compilation.
Move them from the kernel-private architecture-specific header to the UAPI.
Signed-off-by: Thomas Weißschuh <redacted>
---
arch/powerpc/include/uapi/asm/elf.h | 201 ------------------------------------
include/uapi/linux/elf-r.h | 201 ++++++++++++++++++++++++++++++++++++
2 files changed, 201 insertions(+), 201 deletions(-)
On Tue, Sep 08, 2026 at 08:33:35AM +0200, Thomas Weißschuh wrote:
quoted hunk
While the numeric constants for relocations are architecture specific,
it is still useful to get access to them from other architectures.
Also the definitions are useful for userspace in general.
For example tools processing elf files during a kernel cross-compilation
can make use of them.
Introduce a dedicated header for them, similar to the elf-em.h header.
For now the header is empty but it will be filled step by step in
upcomming commits.
Signed-off-by: Thomas Weißschuh <redacted>
---
include/uapi/linux/elf-r.h | 5 +++++
include/uapi/linux/elf.h | 1 +
2 files changed, 6 insertions(+)
On Tue, Sep 08, 2026 at 08:33:46AM +0200, Thomas Weißschuh wrote:
quoted hunk
All vDSO code needs to be completely position independent. Symbol
references are marked as hidden so the compiler emits PC-relative
relocations. However there are cases where the compiler may still
emit absolute relocations, as they are valid in regular PIC DSO code.
These would be resolved by the linker and will break at runtime.
This has been observed on arm64, see commit 0c314cda9325 ("arm64: vdso:
Work around invalid absolute relocations from GCC")
Introduce a tool to check for absolute relocations during the build,
as the current inline-shell logic is not expressive enough.
The check is done on the object files as the relocations will not exist
anymore in the final DSO. As there is no extension point for the
compilation of each object file, perform the validation in vdso_check.
Signed-off-by: Thomas Weißschuh <redacted>
---
Makefile | 19 ++
lib/vdso/Kconfig | 5 +
lib/vdso/Makefile | 2 +
lib/vdso/Makefile.include | 14 ++
lib/vdso/check/.gitignore | 3 +
lib/vdso/check/Makefile | 34 +++
lib/vdso/check/elf.rs | 498 ++++++++++++++++++++++++++++++++++++++++++++
lib/vdso/check/vdsocheck.rs | 154 ++++++++++++++
8 files changed, 729 insertions(+)
@@ -1559,6 +1559,25 @@ vdso_install: export INSTALL_FILES = $(vdso-install-y)vdso_install:$(Q)$(MAKE)-f$(srctree)/scripts/Makefile.vdsoinst+# ---------------------------------------------------------------------------+# vDSO check++ifdef CONFIG_RUST_IS_AVAILABLE+ifdef CONFIG_VDSO_CHECK++# Build the checker early.+prepare:vdsocheck++# If the architecture builds the vDSO early, make sure to be earlier.+PHONY+=vdso_prepare+vdso_prepare:vdsocheck++PHONY+=vdsocheck+vdsocheck:+$(Q)$(MAKE)$(build)=lib/vdso/check$@+endif+endif+# ---------------------------------------------------------------------------# Tools
From: Thomas Weißschuh <hidden> Date: 2026-09-10 08:33:10
On Wed, Sep 09, 2026 at 07:49:30AM -0700, Borislav Petkov wrote:
On Wed, Sep 09, 2026 at 07:59:51AM +0200, Thomas Weißschuh wrote:
quoted
These names and numbers are defined by the architectures' ELF specifications.
They are already cast in stone. For example see Table 4.9 of [0].
Changing them would break compilers, linkers, loaders and more or less every
existing ELF binary.
So?
This was a direct response to your "And putting them in UAPI casts them in
stone". With the idea that we can't possibly cast them more into stone
than they already are.
Your goal is to provide them to tools/. You want to provide them to
*everything*. See the discrepance here?
My goal is to make my tool work. For that I can just as well add ad-hoc
relocation constants definitions in my own code. Just as everybody else
has done, in what seems like a well-honed tradition.
Unifying the constant definitions was a preparatory cleanup step I put
in my series.
Some architectures (like x86) define the relocation constants in internal
kernel headers, but others do so in their UAPI headers, so we can't have it
in include/linux/.
As the UAPI is the common superset, and given that we already have quite some
ELF definitions in the UAPI I this is where I put the relocation constants.
We can add a tools/-specific header which is not shared with include/linux/
but then we still have duplication with the regular kernel code.
As a coincidence, these definitions in the UAPI would also be useful
for nolibc static PIE support, but that is more of a weird curiousity
and not something I want to bring up as reason here.
(...)
quoted
Also we already have other, closely related, ELF constants in the UAPI,
see {,tools/}include/uapi/linux/elf{,-em}.h.
Srsly?!?
You moved them there:
commit 626fd35278295fbb21f2da331cd8028e9738d965
Author: Thomas Weißschuh [off-list ref]
Date: Wed Feb 26 12:44:46 2025 +0100
tools/include: Add uapi/linux/elf.h
It will be used by the vDSO selftests.
I think we are talking past each other. To me the act of "exposing
something to UAPI" is adding it to include/uapi/ (or the arch/ variants).
That is an actual change worthy of discussion, which I am happy to have.
Copying headers (UAPI or not) to tools/include/ is a rote administrative task.
The commit above is the latter.
elf.h has been part of the UAPI for as long as the UAPI exists.
Looking at the rest, it looks like some elf bits got exported, you added some
more and that ship has sailed.
"some elf bits got exported" undersells it a bit. There are 14 years of dozens
of people adding constants to include/uapi/linux/elf.h. So far it doesn't seem
to have been a problem.
I still think us providing headers is completely unnecessary and it will come
to cause conflicts eventually but hey, not my problem.
As there is pushback, I'll just drop all of the header changes.
Maybe somebody else wants to deal with it at some point. Not my problem either.
Thomas