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