1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * A special section entry belonging to a patched function. SPECIAL_SEC picks
4 * which section, since klp diff treats eight of them alike and each needs
5 * extracting for the patched function and no other.
6 *
7 * The entry is written out by hand so the fixture builds without kernel
8 * headers. Only the leading relocation matters to klp diff; the rest is
9 * padded to the section's real entry size, because the entries have to be the
10 * right length for the boundaries between them to fall in the right places.
11 *
12 * SPECIAL_RELOCS covers __ex_table, whose entries relocate both the faulting
13 * instruction and its fixup; objtool rejects one with only the first.
14 */
15
16 #ifndef SPECIAL_SEC
17 #define SPECIAL_SEC "__bug_table"
18 #endif
19 #ifndef SPECIAL_ENTSIZE
20 #define SPECIAL_ENTSIZE 12
21 #endif
22 #ifndef SPECIAL_RELOCS
23 #define SPECIAL_RELOCS 1
24 #endif
25
26 #define STR_(x) #x
27 #define STR(x) STR_(x)
28
29 static const char __modinfo[]
30 __attribute__((section(".modinfo"), used, aligned(1))) = "\0name=vmlinux";
31
32 /*
33 * other() gets an entry of its own, so that "the untouched function's entry
34 * was not dragged in" is a question the section can actually answer. With
35 * only target() contributing, there is nothing for klp diff to leave behind
36 * and the negative assertion holds however the extraction behaves.
37 */
other(int x)38 int other(int x)
39 {
40 asm volatile(
41 "3: nop\n\t"
42 "4:\n\t"
43 ".pushsection " SPECIAL_SEC ", \"aM\", @progbits, "
44 STR(SPECIAL_ENTSIZE) "\n\t"
45 ".long 3b - .\n\t"
46 #if SPECIAL_RELOCS > 1
47 ".long 4b - .\n\t"
48 ".fill " STR(SPECIAL_ENTSIZE) " - 8, 1, 0\n\t"
49 #else
50 ".fill " STR(SPECIAL_ENTSIZE) " - 4, 1, 0\n\t"
51 #endif
52 ".popsection\n\t");
53
54 return x + 9;
55 }
56
target(int x)57 int target(int x)
58 {
59 asm volatile(
60 "1: nop\n\t"
61 "2:\n\t"
62 ".pushsection " SPECIAL_SEC ", \"aM\", @progbits, "
63 STR(SPECIAL_ENTSIZE) "\n\t"
64 ".long 1b - .\n\t"
65 #if SPECIAL_RELOCS > 1
66 ".long 2b - .\n\t"
67 ".fill " STR(SPECIAL_ENTSIZE) " - 8, 1, 0\n\t"
68 #else
69 ".fill " STR(SPECIAL_ENTSIZE) " - 4, 1, 0\n\t"
70 #endif
71 ".popsection\n\t");
72 #ifdef PATCHED
73 return x + 2;
74 #else
75 return x + 1;
76 #endif
77 }
78