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 */ 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 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