xref: /linux/tools/objtool/tests/x86/fixtures/special_sections.c (revision 2bbf68f4cfc3518d51e5202b065bf032e9a92938)
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