objtool/klp: Add test for the alignment of cloned data sections

A cloned data section has to keep its sh_addralign.  Plenty of kernel data
is aligned for correctness rather than speed -- per-CPU variables, anything
touched by an aligned vector move, structures padded to own a cacheline --
and a clone that lands under-aligned either faults on first use or silently
shares a line it was laid out to avoid.  Neither shows up until the patch
is loaded on hardware that cares.

The fixture's data is new in the patched build, so klp diff has to clone it
rather than reference the kernel's copy, and it asserts that premise before
asserting the result.

Commit 2f2600decb ("objtool/klp: fix data alignment in __clone_symbol()")
cannot be reverted to check this -- the revert is a no-op against the
current code, which has been rewritten since.  Verified instead by forcing
the clone's alignment to 1, which the test reports as "alignment 1,
expected 64".

Assisted-by: Claude:claude-opus-4
Based-on-test-by: Joe Lawrence <joe.lawrence@redhat.com>
Assisted-by: Claude:claude-opus-5
Signed-off-by: Song Liu <song@kernel.org>
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Link: https://patch.msgid.link/20260916184351.2720310-54-song@kernel.org
This commit is contained in:
Song Liu 2026-09-16 11:43:46 -07:00 committed by Ingo Molnar
parent 32b2cf1130
commit 8abe5c94bf
2 changed files with 69 additions and 0 deletions

View File

@ -0,0 +1,29 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Data with an alignment stricter than its size.
*
* A cloned data section has to keep its sh_addralign. The kernel has plenty
* of data whose alignment is a correctness property rather than an
* optimisation -- per-CPU variables, anything touched by an aligned SSE move,
* cacheline-aligned locks -- and a clone that lands under-aligned faults or
* silently shares a cacheline it was written to avoid.
*
* The object is new in the patched build, so klp diff has to clone it rather
* than reference the kernel's copy.
*/
static const char __modinfo[]
__attribute__((section(".modinfo"), used, aligned(1))) = "\0name=vmlinux";
#ifdef PATCHED
int aligned_data[2] __attribute__((aligned(64))) = { 1, 2 };
#endif
int target(int x)
{
#ifdef PATCHED
return x + aligned_data[0];
#else
return x;
#endif
}

View File

@ -0,0 +1,40 @@
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
#
# A cloned data section keeps its alignment.
#
# Plenty of kernel data is aligned for correctness rather than speed: per-CPU
# variables, anything touched by an aligned vector move, structures padded to
# own a cacheline. A clone that lands under-aligned either faults on first use
# or silently shares a line it was laid out to avoid, and neither shows up
# until the patch is loaded on hardware that cares.
#
# Fixed by 2f2600decb30 ("objtool/klp: Fix alignment of cloned data
# sections").
#
# Covers the same ground as corpus/x86_64/cloned-data-alignment in Joe
# Lawrence's klp-build unit test corpus.
. "$(dirname "$0")/../lib.sh"
setup
build_pair data_alignment.c
# The premise: the compiler really did over-align it, and the object is new in
# the patch so it has to be cloned rather than referenced.
want="$(in_sections patched.o | sed 's/^ *\[[ 0-9]*\] *//' |
awk '$1 == ".data.aligned_data" { print $NF }')"
[ "$want" = 64 ] ||
probe_skip "compiler gave .data.aligned_data alignment '$want', not 64"
has_input_section orig.o .data.aligned_data &&
fail "fixture put aligned_data in the original; nothing to clone"
run_diff
assert_section .data.aligned_data
got="$(out_sections | sed 's/^ *\[[ 0-9]*\] *//' |
awk '$1 == ".data.aligned_data" { print $NF }')"
[ "$got" = "$want" ] ||
fail "cloned .data.aligned_data has alignment $got, expected $want"
pass "cloned data section keeps its alignment"