xref: /linux/tools/objtool/tests/generic/fixtures/abs_and_addressable.c (revision 5b6dca02b3e2254d2fd5706d76d7ab4610a67296)
1*91c67484SSong Liu // SPDX-License-Identifier: GPL-2.0
2*91c67484SSong Liu /*
3*91c67484SSong Liu  * Two constructs which appear all over the kernel and must not upset klp
4*91c67484SSong Liu  * checksum or klp diff.
5*91c67484SSong Liu  *
6*91c67484SSong Liu  * An absolute symbol (SHN_ABS) has no section, so anything walking sym->sec
7*91c67484SSong Liu  * without checking dereferences NULL.  The kernel makes them with linker
8*91c67484SSong Liu  * scripts and with .set in asm; VDSO and the fixed-address per-cpu bases are
9*91c67484SSong Liu  * the usual sources.
10*91c67484SSong Liu  *
11*91c67484SSong Liu  * __ADDRESSABLE() emits a pointer into .discard.addressable purely to keep a
12*91c67484SSong Liu  * symbol referenced.  It is discarded at link time and means nothing to a
13*91c67484SSong Liu  * livepatch, but the pointer is a relocation like any other and has to survive
14*91c67484SSong Liu  * being looked at.
15*91c67484SSong Liu  *
16*91c67484SSong Liu  * Neither is the subject of the patch; the point is that their presence does
17*91c67484SSong Liu  * not disturb the function that is.
18*91c67484SSong Liu  */
19*91c67484SSong Liu 
20*91c67484SSong Liu static const char __modinfo[]
21*91c67484SSong Liu 	__attribute__((section(".modinfo"), used, aligned(1))) = "\0name=vmlinux";
22*91c67484SSong Liu 
23*91c67484SSong Liu /* SHN_ABS, referenced from code. */
24*91c67484SSong Liu extern char abs_sym[];
25*91c67484SSong Liu __asm__(".globl abs_sym\n"
26*91c67484SSong Liu 	".set abs_sym, 0x1234\n");
27*91c67484SSong Liu 
28*91c67484SSong Liu int helper(int x);
helper(int x)29*91c67484SSong Liu int helper(int x) { return x + 1; }
30*91c67484SSong Liu 
31*91c67484SSong Liu /* The shape of __ADDRESSABLE(helper). */
32*91c67484SSong Liu __asm__(".pushsection .discard.addressable, \"aw\"\n"
33*91c67484SSong Liu 	".balign 8\n"
34*91c67484SSong Liu 	".quad helper\n"
35*91c67484SSong Liu 	".popsection\n");
36*91c67484SSong Liu 
target(int x)37*91c67484SSong Liu int target(int x)
38*91c67484SSong Liu {
39*91c67484SSong Liu #ifdef PATCHED
40*91c67484SSong Liu 	return helper(x) + (int)(long)abs_sym + 1;
41*91c67484SSong Liu #else
42*91c67484SSong Liu 	return helper(x) + (int)(long)abs_sym;
43*91c67484SSong Liu #endif
44*91c67484SSong Liu }
45