| // SPDX-License-Identifier: GPL-2.0 | |
| /* | |
| * A special section entry belonging to a patched function. SPECIAL_SEC picks | |
| * which section, since klp diff treats eight of them alike and each needs | |
| * extracting for the patched function and no other. | |
| * | |
| * The entry is written out by hand so the fixture builds without kernel | |
| * headers. Only the leading relocation matters to klp diff; the rest is | |
| * padded to the section's real entry size, because the entries have to be the | |
| * right length for the boundaries between them to fall in the right places. | |
| * | |
| * SPECIAL_RELOCS covers __ex_table, whose entries relocate both the faulting | |
| * instruction and its fixup; objtool rejects one with only the first. | |
| */ | |
| #ifndef SPECIAL_SEC | |
| #define SPECIAL_SEC "__bug_table" | |
| #endif | |
| #ifndef SPECIAL_ENTSIZE | |
| #define SPECIAL_ENTSIZE 12 | |
| #endif | |
| #ifndef SPECIAL_RELOCS | |
| #define SPECIAL_RELOCS 1 | |
| #endif | |
| #define STR_(x) #x | |
| #define STR(x) STR_(x) | |
| static const char __modinfo[] | |
| __attribute__((section(".modinfo"), used, aligned(1))) = "\0name=vmlinux"; | |
| /* | |
| * other() gets an entry of its own, so that "the untouched function's entry | |
| * was not dragged in" is a question the section can actually answer. With | |
| * only target() contributing, there is nothing for klp diff to leave behind | |
| * and the negative assertion holds however the extraction behaves. | |
| */ | |
| int other(int x) | |
| { | |
| asm volatile( | |
| "3: nop\n\t" | |
| "4:\n\t" | |
| ".pushsection " SPECIAL_SEC ", \"aM\", @progbits, " | |
| STR(SPECIAL_ENTSIZE) "\n\t" | |
| ".long 3b - .\n\t" | |
| #if SPECIAL_RELOCS > 1 | |
| ".long 4b - .\n\t" | |
| ".fill " STR(SPECIAL_ENTSIZE) " - 8, 1, 0\n\t" | |
| #else | |
| ".fill " STR(SPECIAL_ENTSIZE) " - 4, 1, 0\n\t" | |
| #endif | |
| ".popsection\n\t"); | |
| return x + 9; | |
| } | |
| int target(int x) | |
| { | |
| asm volatile( | |
| "1: nop\n\t" | |
| "2:\n\t" | |
| ".pushsection " SPECIAL_SEC ", \"aM\", @progbits, " | |
| STR(SPECIAL_ENTSIZE) "\n\t" | |
| ".long 1b - .\n\t" | |
| #if SPECIAL_RELOCS > 1 | |
| ".long 2b - .\n\t" | |
| ".fill " STR(SPECIAL_ENTSIZE) " - 8, 1, 0\n\t" | |
| #else | |
| ".fill " STR(SPECIAL_ENTSIZE) " - 4, 1, 0\n\t" | |
| #endif | |
| ".popsection\n\t"); | |
| #ifdef PATCHED | |
| return x + 2; | |
| #else | |
| return x + 1; | |
| #endif | |
| } |