1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Two constructs which appear all over the kernel and must not upset klp
4 * checksum or klp diff.
5 *
6 * An absolute symbol (SHN_ABS) has no section, so anything walking sym->sec
7 * without checking dereferences NULL. The kernel makes them with linker
8 * scripts and with .set in asm; VDSO and the fixed-address per-cpu bases are
9 * the usual sources.
10 *
11 * __ADDRESSABLE() emits a pointer into .discard.addressable purely to keep a
12 * symbol referenced. It is discarded at link time and means nothing to a
13 * livepatch, but the pointer is a relocation like any other and has to survive
14 * being looked at.
15 *
16 * Neither is the subject of the patch; the point is that their presence does
17 * not disturb the function that is.
18 */
19
20 static const char __modinfo[]
21 __attribute__((section(".modinfo"), used, aligned(1))) = "\0name=vmlinux";
22
23 /* SHN_ABS, referenced from code. */
24 extern char abs_sym[];
25 __asm__(".globl abs_sym\n"
26 ".set abs_sym, 0x1234\n");
27
28 int helper(int x);
helper(int x)29 int helper(int x) { return x + 1; }
30
31 /* The shape of __ADDRESSABLE(helper). */
32 __asm__(".pushsection .discard.addressable, \"aw\"\n"
33 ".balign 8\n"
34 ".quad helper\n"
35 ".popsection\n");
36
target(int x)37 int target(int x)
38 {
39 #ifdef PATCHED
40 return helper(x) + (int)(long)abs_sym + 1;
41 #else
42 return helper(x) + (int)(long)abs_sym;
43 #endif
44 }
45