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 Liuint 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 Liuint 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