xref: /linux/tools/objtool/tests/generic/fixtures/static_call.c (revision 5b6dca02b3e2254d2fd5706d76d7ab4610a67296)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Static call site in a patched function, laid out by hand as for
4  * jump_label.c.  MODNAME selects whether the key belongs to vmlinux or a
5  * module.
6  *
7  * objtool's check pass would emit the site, and klp-write-tests.txt says to
8  * let it.  Not here: it does not emit the ANNOTATE_DATA_SPECIAL describing
9  * the entry boundaries -- in the kernel that comes from the static_call
10  * macros -- and NO_ANNOTATE below has to be able to take it away.  A fixture
11  * which varies the annotation has to write the entry that goes with it.
12  *
13  * NO_ANNOTATE drops the ANNOTATE_DATA_SPECIAL block from the patched build,
14  * leaving .static_call_sites with no annotation to describe its entry
15  * boundaries.  The section carries no entsize either, so klp diff has to fall
16  * back on the annotations it can still see -- and when the patched object is
17  * the only one that lost them, the two sides disagree about how the section is
18  * divided up.
19  *
20  * NEW_CALL puts the call site behind PATCHED, so the patch introduces one
21  * where the original had none.  The .static_call_sites entry is then new, with
22  * nothing in the original to correlate it against.
23  */
24 
25 #ifndef MODNAME
26 #define MODNAME "vmlinux"
27 #endif
28 
29 static const char __modinfo[]
30 	__attribute__((section(".modinfo"), used, aligned(1))) = "\0name=" MODNAME;
31 
32 long __SCK__klp_test_call;
33 
target(int x)34 int target(int x)
35 {
36 #if defined(NEW_CALL) && !defined(PATCHED)
37 	/* The original has no static call at all. */
38 	return x + 1;
39 #else
40 	__asm__ volatile(
41 		"1:	nop\n\t"
42 		".pushsection	.static_call_sites, \"aw\"\n\t"
43 		".balign	8\n\t"
44 		"912:\n\t"
45 #if !(defined(PATCHED) && defined(NO_ANNOTATE))
46 		".pushsection	.discard.annotate_data, \"M\", @progbits, 8\n\t"
47 		".long		912b - ., 1\n\t"
48 		".popsection\n\t"
49 #endif
50 		".long		1b - ., %c0 - .\n\t"
51 		".popsection\n\t"
52 		:: "i" (&__SCK__klp_test_call));
53 #endif
54 #ifdef PATCHED
55 	return x + 2;
56 #else
57 	return x + 1;
58 #endif
59 }
60