// SPDX-License-Identifier: GPL-2.0 /* * A function whose position in the section changes between the two builds, * without the function itself changing. * * target() calls callee() twice, and a call within the same section needs no * relocation: the displacement is in the instruction. It is that displacement * which moves, and hashing those bytes makes the checksum move with it. Both * must therefore share a section, which is why the test passes * -fno-function-sections. * * What has to change is the distance between the two, and PATCHED changes it * by aligning them rather than by inserting a function between them. Where a * compiler puts an added function is its own business: gcc emits these in * source order, so a function written between callee() and target() separates * them, but clang emits target() immediately before callee() whatever the * source says, and an added function lands ahead of both. That moves target() * without moving it relative to callee(), the displacement comes out identical * in both builds, and the test passes without having asked anything. * * Alignment moves the functions apart on both, and moves neither function's * own instructions -- which is exactly the distinction under test. */ #ifdef PATCHED #define MOVED __attribute__((aligned(64))) #else #define MOVED #endif static const char __modinfo[] __attribute__((section(".modinfo"), used, aligned(1))) = "\0name=vmlinux"; __attribute__((noinline)) MOVED static int callee(int x) { return x * 5 + 1; } __attribute__((noinline)) MOVED int target(int x) { return callee(x) + callee(x + 1); }