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