summaryrefslogtreecommitdiff
path: root/tools/objtool/tests/generic
AgeCommit message (Collapse)Author
2026-09-21objtool/klp: Add test for ThinLTO symbols sharing a demangled nameSong Liu
A file-local symbol which ThinLTO has to make visible is renamed helper.llvm.<hash>. With two such helpers in one link, the original and the patched object hold two each, all four spelled differently, and demangling gives "helper" for every one of them -- so the name alone cannot say which corresponds to which. Three translation units, two with a static helper of the same name and a third calling into both, which is what forces the promotion. Only one helper changes: paired correctly that means exactly one is cloned, and paired the wrong way round the other is, or both are. Had both bodies changed, both would be cloned either way and the test would prove nothing -- which is how the first version of this was written. The outcome is asserted, not the machinery. With the clang tested here the pairing survives disabling the .llvm.<hash> suffix map and stubbing out llvm_suffix() entirely, so no single-line sabotage distinguishes it; the tiered matcher this case was written for is not needed for this shape. The test says so rather than implying otherwise. Assisted-by: Claude:claude-opus-4 Based-on-test-by: Joe Lawrence <joe.lawrence@redhat.com> Assisted-by: Claude:claude-opus-5 Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://patch.msgid.link/20260916184351.2720310-59-song@kernel.org
2026-09-21objtool/klp: Add test for Clang switch jump tablesSong Liu
For a dense enough switch Clang emits the targets as a table in .rodata..Lswitch.table.<function> -- named after the function but not part of it. The patched function indexes into that table, so a clone which does not bring it along jumps through whatever the kernel's copy holds, which after a patch that changed the switch is the wrong set of targets. An indirect jump to a stale address reports nothing at build or load time. The fixture asserts its own premise twice over, since both halves depend on what this Clang chose to do: that a table was built rather than a chain of comparisons, and that the added case actually changed it. objtool has no switch-specific code -- the table is carried by the general mechanism for data a cloned function references -- so this guards that mechanism reaching an easily-mishandled shape rather than a particular line, and the test says so. Making the table uncorrelated, the nearest available sabotage, does not change the outcome. Assisted-by: Claude:claude-opus-4 Based-on-test-by: Joe Lawrence <joe.lawrence@redhat.com> Assisted-by: Claude:claude-opus-5 Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://patch.msgid.link/20260916184351.2720310-58-song@kernel.org
2026-09-21objtool/klp: Add test for UBSAN metadata in an unchanged functionSong Liu
Every instrumented operation gets a per-callsite metadata object in an anonymous data section -- .data..Lubsan_data and .data..Lubsan_type from GCC, .data..L__unnamed_ from Clang -- whose names are compiler-generated and mean nothing across a rebuild. is_uncorrelated_section() exists so klp diff does not try to pair them up, and nothing tested it. The failure it prevents is a false positive, which is the direction this suite has least coverage of. Metadata belonging to a function nobody touched compares as different and drags that function into the patch. That is not a build failure: it is a larger livepatch than intended, pulling in dependencies with it, and every extra function is one more that can fail to correlate or to apply. The fixture is built with -fsanitize=shift, which both compilers instrument; neither emits a bounds check for an index it can prove in range. One function changes, the other is byte-identical and carries instrumentation of its own, and the test asserts the second is left alone. Verified by removing each rule from is_uncorrelated_section() in turn, which splits neatly by toolchain: dropping the .data..Lubsan rule fails the test under gcc, dropping .data..L__unnamed_ fails it under clang. One test, two code paths, each checked by the compiler that reaches it. Assisted-by: Claude:claude-opus-4 Based-on-test-by: Joe Lawrence <joe.lawrence@redhat.com> Assisted-by: Claude:claude-opus-5 Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://patch.msgid.link/20260916184351.2720310-57-song@kernel.org
2026-09-21objtool/klp: Add test for absolute and __ADDRESSABLE symbolsSong Liu
A SHN_ABS symbol has no section, so any walk of sym->sec which does not check dereferences NULL, and the kernel has plenty of them -- from linker scripts and from .set in assembly. __ADDRESSABLE() emits a pointer into .discard.addressable purely to keep a symbol referenced; it means nothing to a livepatch and is discarded at link time, but it is a relocation like any other and gets looked at. Neither is what the patch changes. What this guards against is not a wrong answer but a crash or an error on input the kernel produces routinely, which would make every function near one unpatchable. Not isolated to a single line, and the test says so: the absolute symbol here has zero length, so it is excluded before the section check is reached and removing that check alone changes nothing observable. Assisted-by: Claude:claude-opus-4 Based-on-test-by: Joe Lawrence <joe.lawrence@redhat.com> Assisted-by: Claude:claude-opus-5 Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://patch.msgid.link/20260916184351.2720310-56-song@kernel.org
2026-09-21objtool/klp: Add test for a patch which strips a data annotationSong Liu
klp diff needs entry boundaries for a special section: either an entsize, or ANNOTATE_DATA_SPECIAL annotations naming where each entry starts. .static_call_sites has no entsize, so the annotations are all there is -- and a patch can remove the last one in a translation unit while leaving the section itself in place, so that only the patched side has lost them. The section still has to be handled. Dropping it leaves the patched function's static call unregistered; misreading its boundaries attaches the entry to the wrong code. Neither is reported at build time. Give the fixture a NO_ANNOTATE knob and assert the premise -- annotation present in the original, absent in the patched object, section present in both -- before asserting the result. Fixed by commit 3de711fba73a ("objtool/klp: Fix create_fake_symbols() skipping entsize-based sections"). Verified by making klp diff skip .static_call_sites when cloning special sections: the test fails. Assisted-by: Claude:claude-opus-4 Based-on-test-by: Joe Lawrence <joe.lawrence@redhat.com> Assisted-by: Claude:claude-opus-5 Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://patch.msgid.link/20260916184351.2720310-55-song@kernel.org
2026-09-21objtool/klp: Add test for the alignment of cloned data sectionsSong Liu
A cloned data section has to keep its sh_addralign. Plenty of kernel data is aligned for correctness rather than speed -- per-CPU variables, anything touched by an aligned vector move, structures padded to own a cacheline -- and a clone that lands under-aligned either faults on first use or silently shares a line it was laid out to avoid. Neither shows up until the patch is loaded on hardware that cares. The fixture's data is new in the patched build, so klp diff has to clone it rather than reference the kernel's copy, and it asserts that premise before asserting the result. Commit 2f2600decb30 ("objtool/klp: fix data alignment in __clone_symbol()") cannot be reverted to check this -- the revert is a no-op against the current code, which has been rewritten since. Verified instead by forcing the clone's alignment to 1, which the test reports as "alignment 1, expected 64". Assisted-by: Claude:claude-opus-4 Based-on-test-by: Joe Lawrence <joe.lawrence@redhat.com> Assisted-by: Claude:claude-opus-5 Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://patch.msgid.link/20260916184351.2720310-54-song@kernel.org
2026-09-21objtool/klp: Add test for instruction operand checksumsSong Liu
checksum_update_insn() hashes an instruction's bytes and then what any relocation on it refers to: a string section contributes the string's contents, anything else the target symbol's name and adjusted addend, with a reference to a static resolved through its section symbol first. None of that shows up in the bytes. A rel32 operand is zero in the object and supplied by the relocation, so calling a different function, editing a literal the code passes, or reading a different index of an array all leave the encoded instruction byte-identical. A checksum stopping at the bytes reports the function unchanged and the patch silently does not contain the fix. test-checksum-position is the other half: what must *not* change the checksum when a function merely moves. Each of the four is verified by sabotaging the line it covers. The static case needed a writer the compiler cannot see through -- without one it proves the array is never written, folds every read to zero, and emits no relocation at all, so the reference under test does not exist and the variant passes having compared two identical objects. Assisted-by: Claude:claude-opus-4 Based-on-test-by: Joe Lawrence <joe.lawrence@redhat.com> Assisted-by: Claude:claude-opus-5 Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://patch.msgid.link/20260916184351.2720310-52-song@kernel.org
2026-09-21objtool/klp: Add test for a static call introduced by the patchSong Liu
The counterpart to the static branch case: a patch may add a static call to a function which had none, so the .static_call_sites entry is new and there is nothing in the original to correlate it against. Where the key lives still decides whether that is allowed. A vmlinux key is reachable; a module-owned one is not, for the same reason an existing module key is not -- late module patching lets the livepatch load first and the unresolved entry is dereferenced when the module arrives. Both halves are here because they fail in opposite directions: dropping the new entry leaves a static call the kernel never patches, and accepting a new module-owned one is the corruption the check exists to prevent. Both halves are one test over one fixture: built with -DNEW_CALL the key is vmlinux's and the new entry has to be carried in; built with -DMODNAME as well the key belongs to a module, klp diff has to reject it, and no output object may be left behind. The premise is asserted first -- the original must have no .static_call_sites at all -- since otherwise this is a second copy of test-static-call-module-key. Covers the same ground as corpus/x86_64/static-call-vmlinux-new and corpus/x86_64/static-call-module-new in Joe Lawrence's klp-build unit test corpus. Assisted-by: Claude:claude-opus-4 Based-on-test-by: Joe Lawrence <joe.lawrence@redhat.com> Assisted-by: Claude:claude-opus-5 Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://patch.msgid.link/20260916184351.2720310-51-song@kernel.org
2026-09-21objtool/klp: Add test for tracepoint and pr_debug static branch keysSong Liu
A module-owned static branch key is normally fatal, because late module patching lets the livepatch load before the module it depends on and jump_label_add_module() then dereferences an unresolved entry. Tracepoints and pr_debug() generate such keys everywhere, so refusing them outright would make any function containing a trace_*() call or a pr_debug() unpatchable. klp diff drops the entry, warns, and carries on: the patched code works with that one tracepoint or debug print permanently off. Both halves matter, and the test asserts both. A build which fails is a function nobody can patch; an entry left in place is the corruption the rejection exists to prevent. Give the fixture a KEY_NAME knob so the same static branch can be built with either special name. Verified by removing each exemption in turn -- the test fails for both. That the entry is then dropped is asserted but not isolated, and the test says so. Assisted-by: Claude:claude-opus-4 Based-on-test-by: Joe Lawrence <joe.lawrence@redhat.com> Assisted-by: Claude:claude-opus-5 Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://patch.msgid.link/20260916184351.2720310-50-song@kernel.org
2026-09-21objtool/klp: Add test for a static branch introduced by the patchSong Liu
Patching a function which already has a static branch and adding one to a function which had none are different cases. In the second the __jump_table entry is itself new, so there is nothing in the original to correlate it against: klp diff has to carry the entry into the patch from scratch and reach the key the way it reaches any other vmlinux symbol. Dropping it is silent. The patched function keeps a static branch the kernel never patches, so it takes the same arm forever whatever the key is set to. Give the fixture a NEW_KEY knob which puts the whole branch behind PATCHED, and assert the premise -- that the original really has no __jump_table -- before asserting the result, since otherwise this is just a second copy of test-jump-label-key. Verified by making klp diff skip __jump_table when cloning special sections: the test fails. Assisted-by: Claude:claude-opus-4 Based-on-test-by: Joe Lawrence <joe.lawrence@redhat.com> Assisted-by: Claude:claude-opus-5 Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://patch.msgid.link/20260916184351.2720310-49-song@kernel.org
2026-09-21objtool/klp: Add test for symbols with no checksum entry of their ownSong Liu
.discard.sym_checksum is an array of { address, checksum } looked up by the address a relocation points at, so the invariant is one entry per address. calculate_checksums() skips zero-length symbols, aliases and cold parts to keep it, and nothing checked that it does. A duplicate entry is not a build failure. It makes the lookup ambiguous, and whichever checksum loses is never consulted again -- so a function whose code changed can be read as unchanged and dropped from the patch. The alias skip is verified the usual way: remove it and the test fails. The other two are not isolated, and the test says so rather than implying otherwise. A zero-length symbol is excluded by several of the guards at once -- its section has no data either -- so removing any one of them changes nothing observable; the assertion stands as a check on the behaviour, not on the line that produces it. The cold-part skip needs a compiler that splits functions and is not reached here at all. Which of an aliased pair keeps the entry falls out of symbol table order, so the test requires exactly one of the two rather than naming a winner -- as written first it named real_function and failed, because gcc kept the alias. Assisted-by: Claude:claude-opus-4 Based-on-test-by: Joe Lawrence <joe.lawrence@redhat.com> Assisted-by: Claude:claude-opus-5 Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://patch.msgid.link/20260916184351.2720310-48-song@kernel.org
2026-09-21objtool/klp: Add test for data object checksumsSong Liu
klp checksum hashes a data symbol's length, its bytes, and every relocation it carries -- as the target's name and adjusted addend, except a reference into a string section, which contributes the string's contents instead. Nothing covered any of it. Each is load-bearing, and the failure is always the same shape: a checksum which ignores one calls a changed object unchanged, klp diff leaves it out of the patch, and the patched code goes on reading the kernel's old copy. The string case cannot be caught by hashing bytes: the pointer is identical, same section and same offset, and only the text it refers to moved. One fixture, six variants applied to the patched build alone. Each was verified by sabotaging the line it covers and watching the test fail: raw bytes initialiser change length a .bss object grows; its bytes are never hashed string contents literal edited in place, pointer untouched reloc target name pointer moved to another function reloc addend same array, different index section-symbol path the same, via a static's section symbol Two of those needed the fixture rebuilding. An initialised array does not isolate the length, because growing one changes the hashed bytes too -- hence .bss, where there are none. And a named char[] does not reach the contents-hashing path at all: that keys on SHF_STRINGS, which the compiler sets on the mergeable section a literal lands in and not on an array given a section of its own. Assisted-by: Claude:claude-opus-4 Based-on-test-by: Joe Lawrence <joe.lawrence@redhat.com> Assisted-by: Claude:claude-opus-5 Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://patch.msgid.link/20260916184351.2720310-47-song@kernel.org
2026-09-21objtool/klp: Test rejection of a file-local static branch keySong Liu
A static branch key owned by a module cannot be reached with a klp reloc: late module patching allows the livepatch module to load first, leaving the __jump_table entry unresolved for jump_label_add_module() to dereference. validate_special_section_klp_reloc() rejects it at build time. test-jump-label-module-key covers that for a global key. A file-local one takes a different route to the same check: the compiler references a static through its section symbol plus an addend, so the key has to be resolved from the section before it can be recognised as STT_OBJECT at all. Until commit f9fb44b0ecef ("objtool/klp: Fix detection of corrupt static branch/call entries") it was not, and the reference was silently emitted. Give the fixture a STATIC_KEY knob and cover it. The test checks that the input really does reference the key through its section, since without that it is only a second copy of the existing test. Verified by reverting commit f9fb44b0ecef ("objtool/klp: Fix detection of corrupt static branch/call entries"): klp diff accepts the input and the test fails, under both gcc and clang. Assisted-by: Claude:claude-opus-4 Based-on-test-by: Joe Lawrence <joe.lawrence@redhat.com> Assisted-by: Claude:claude-opus-5 Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://patch.msgid.link/20260916184351.2720310-44-song@kernel.org
2026-09-21objtool/klp: Add test for symbols whose linkage the patch changesSong Liu
A patch can move a symbol between static and global without renaming it: dropping "static" from a helper so something else can call it, or adding it to one that is no longer shared. Correlation keys off more than the name, so a symbol whose binding moved has to still pair with itself. Failing to is not a build failure. The symbol looks new, and a new data symbol is either rejected or cloned as a second copy -- at which point the patched code updates its own private variable while the rest of the kernel keeps reading the original. The test covers both directions in one fixture, a function going global and a variable going static, and asserts the outcome rather than the absence of a warning: each symbol resolves back to the kernel's copy through a klp symbol, and neither is cloned into the patch. An earlier version asserted only that no "no correlation" or "changed data" message appeared, and passed with correlation deliberately broken. What the messages say and what the patch contains are not the same question. Verified to fail with correlation made to require matching symbol bindings. Assisted-by: Claude:claude-opus-4 Based-on-test-by: Joe Lawrence <joe.lawrence@redhat.com> Assisted-by: Claude:claude-opus-5 Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://patch.msgid.link/20260916184351.2720310-43-song@kernel.org
2026-09-21objtool/klp: Add test for static locals which must not be correlatedSong Liu
Most static locals have to be correlated so the patched code keeps using the running kernel's copy. Two kinds must not: anything in .data..once, the flag behind WARN_ONCE and friends, and the well-known names the kernel generates for per-instance things (__warned, __key, __func__). Sharing a .data..once flag means a patch inherits "already warned" from before it was applied, and the warning it was meant to surface never fires. The fixture deliberately does not name its .data..once variable __warned: the name rule would then catch it and the section rule would go untested. gcc spells these <var>.<id> and Clang <func>.<var>, so both are covered. This tests the behavior of commit ff529864e738 ("objtool/klp: Fix .data..once static local non-correlation") and commit 84c304a534b8 ("objtool/klp: Fix is_uncorrelated_static_local() for Clang"). Assisted-by: Claude:claude-opus-4 Based-on-test-by: Joe Lawrence <joe.lawrence@redhat.com> Assisted-by: Claude:claude-opus-5 Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://patch.msgid.link/20260916184351.2720310-40-song@kernel.org
2026-09-21objtool/klp: Add test for sympos resolved against a linked vmlinuxSong Liu
vmlinux is not like a module: the final link reorders sub-sections, so a symbol's position has to come from the linked image rather than from symbol table order. klp diff bridges that with .klp.symid, and looks for it only when the object it was handed is called vmlinux.o with a vmlinux beside it. This was assigned to an end-to-end test on the assumption that it needs a real kernel build. It needs "ld -r" and "ld -e 0", and takes a fraction of a second. The fixture places the static appearing first in the symbol table at the higher address, and the link passes --sort-section=name to force the reordering the kernel's linker script performs. Without that the two ways of computing sympos agree, and a first version passed with the vmlinux path disabled. Assisted-by: Claude:claude-opus-4 Based-on-test-by: Joe Lawrence <joe.lawrence@redhat.com> Assisted-by: Claude:claude-opus-5 Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://patch.msgid.link/20260916184351.2720310-39-song@kernel.org
2026-09-21objtool/klp: Add test for sympos in module objectsSong Liu
klp-sympos.c had no coverage at all. sympos disambiguates same-named symbols for livepatch, counting from 1, with 0 meaning the name is unique. Resolving to the wrong one is not a load failure -- it is a patch quietly wired to the wrong object. Covers the module path, where the position is a count in symbol table order and klp diff can work it out from the object alone. Assisted-by: Claude:claude-opus-4 Based-on-test-by: Joe Lawrence <joe.lawrence@redhat.com> Assisted-by: Claude:claude-opus-5 Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://patch.msgid.link/20260916184351.2720310-38-song@kernel.org
2026-09-21objtool/klp: Add test for position-independent checksumsSong Liu
A function that only moves has not changed, and its checksum must not move with it. Otherwise every patch reports as changed everything that shifted because something ahead of it grew. The fixture is built with -fno-function-sections, overriding the harness default: with per-function sections every function sits at offset 0 of its own section and nothing ever moves, so the test would prove nothing. It also calls across to another function rather than looping within itself -- a loop branch keeps the same displacement wherever the function goes, so it is not position-dependent to begin with. This tests the behavior of commit cca84cb12908 ("objtool/klp: Fix position-dependent checksums for non-relocated jumps/calls"). Assisted-by: Claude:claude-opus-4 Based-on-test-by: Joe Lawrence <joe.lawrence@redhat.com> Assisted-by: Claude:claude-opus-5 Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://patch.msgid.link/20260916184351.2720310-37-song@kernel.org
2026-09-21objtool/klp: Add test for recorded checksum valuesSong Liu
Whether klp diff treats a function as changed is decided by its checksum, and until now nothing looked at one. A test asserting only that the right functions were cloned cannot tell a correct checksum from one that happens to differ. Asserts both directions -- the changed function's checksum moves, the untouched one's does not -- and that checksumming identical input twice gives the same answer, since otherwise every rebuild reports spurious changes. Assisted-by: Claude:claude-opus-4 Based-on-test-by: Joe Lawrence <joe.lawrence@redhat.com> Assisted-by: Claude:claude-opus-5 Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://patch.msgid.link/20260916184351.2720310-36-song@kernel.org
2026-09-21objtool/klp: Add test for new references to exported symbolsSong Liu
A patch may introduce a reference the original object did not have. That is fine when the export belongs to vmlinux, and not fine when it belongs to a module: the livepatch would gain a module dependency nobody declared, and late module patching lets the patch load first. This tests the behavior of commit 72d76d0c18eb ("objtool/klp: Allow new references to module exports"). Assisted-by: Claude:claude-opus-4 Based-on-test-by: Joe Lawrence <joe.lawrence@redhat.com> Assisted-by: Claude:claude-opus-5 Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://patch.msgid.link/20260916184351.2720310-34-song@kernel.org
2026-09-21objtool/klp: Add test for EXPORT_SYMBOL_FOR_MODULES referencesSong Liu
A symbol exported with EXPORT_SYMBOL_FOR_MODULES() is reachable only by the modules named in its namespace, and a livepatch module is never one of them. So a reference to it cannot be an ordinary relocation resolved by the module loader; it has to be a klp relocation applied at patch time. Getting this wrong is silent. The module links, loads, and reads the wrong thing, or fails to load for a reason that does not name the cause. This tests the behavior of commit 4cd3cfb8b54f ("objtool/klp: Fix relocations for EXPORT_SYMBOL_FOR_MODULES() symbols"). Which object the resulting relocation is filed under is a separate question, and one this test cannot ask: the patched object here is vmlinux, so the vmlinux section is the one produced either way. That is covered by the module case, in "objtool/klp: Add test for vmlinux relocs in a patched module". Assisted-by: Claude:claude-opus-4 Based-on-test-by: Joe Lawrence <joe.lawrence@redhat.com> Assisted-by: Claude:claude-opus-5 Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://patch.msgid.link/20260916184351.2720310-33-song@kernel.org
2026-09-21objtool/klp: Add test for the contents of the klp_funcs listSong Liu
The patch list is what livepatch acts on, and asserting only that it exists does not say it is right. A function that should have been patched and is missing leaves the bug in place; one that should not be there patches code nobody changed. The fixture changes two of three functions and asserts on all three: the two by name, and the third by its absence. It checks the strings in .rodata.klp.str1.1 as well as the relocations, since the names the kernel matches on are real strings. Assisted-by: Claude:claude-opus-4 Based-on-test-by: Joe Lawrence <joe.lawrence@redhat.com> Assisted-by: Claude:claude-opus-5 Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://patch.msgid.link/20260916184351.2720310-32-song@kernel.org
2026-09-21objtool/klp: Add test for Module.symvers path normalizationSong Liu
Module.symvers names an export's owner by build path, and the kernel knows modules by their runtime name. Without normalizing one to the other, an export owned by a module is not recognised as owned by anything, and a reference that should become a klp relocation stays an ordinary one. This tests the behavior of commit 8668bf91e050 ("objtool/klp: Normalize Module.symvers paths to module names"). Assisted-by: Claude:claude-opus-4 Based-on-test-by: Joe Lawrence <joe.lawrence@redhat.com> Assisted-by: Claude:claude-opus-5 Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://patch.msgid.link/20260916184351.2720310-31-song@kernel.org
2026-09-21objtool/klp: Add test for vmlinux relocs in a patched moduleSong Liu
The kernel refuses a module-targeted klp relocation which names a vmlinux symbol. An EXPORT_SYMBOL_FOR_MODULES() symbol needs a klp relocation, so patching a module function that references one only loads if klp diff files that relocation under vmlinux rather than under the patched module. This fails at load, not at build: klp-build produces a module and static checks of it find nothing wrong. Hence the assertion on which object the relocation is filed against. Reported by Dylan Hatch, whose mod-ns-lp branch carries the kernel-side half of this case. Co-developed-by: Dylan Hatch <dylanbhatch@google.com> Signed-off-by: Dylan Hatch <dylanbhatch@google.com> Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Assisted-by: Claude:claude-opus-5 Link: https://patch.msgid.link/20260916184351.2720310-30-song@kernel.org
2026-09-21objtool/klp: Add test for klp reloc section naming in module objectsSong Liu
klp diff names the intermediate __klp_relocs section after the object the relocation belongs to, and post-link turns that into .klp.rela.<object>.<sec>. Name it after the wrong object and the kernel applies the relocation when the wrong module loads, or never. The fixture is the first here to honour MODNAME: most hardcode name=vmlinux, so passing -DMODNAME to them silently does nothing and the test quietly becomes a vmlinux test. This tests the behavior of commit 07f14d6af9d7 ("objtool/klp: Fix cross-module klp relocation section naming"). Assisted-by: Claude:claude-opus-4 Based-on-test-by: Joe Lawrence <joe.lawrence@redhat.com> Assisted-by: Claude:claude-opus-5 Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://patch.msgid.link/20260916184351.2720310-29-song@kernel.org
2026-09-21objtool/klp: Add klp diff and post-link regression testsSong Liu
Five tests covering behaviour the harness could reach but nothing exercised. Each was verified to fail against the code it guards, by reverting the fix or sabotaging the exact line; where a first attempt passed against broken code, the fixture was wrong and was rebuilt. post-link first coverage of the subcommand at all local-vs-export local symbols must not match exports symvers-parse-error Module.symvers parse error line numbers checksum-debug the --debug-checksum format klp-build reads function-removal the "no correlation" path local-vs-export tests the behavior of commit 86a697572c62 ("objtool/klp: Don't match local symbols against exports"), and symvers-parse-error that of commit 51c1de134863 ("objtool/klp: Fix line numbers in Module.symvers parse errors"). Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Assisted-by: Claude:claude-opus-5 Link: https://patch.msgid.link/20260916184351.2720310-28-song@kernel.org
2026-09-21objtool/klp: Add test for unchecksummed inputPuranjay Mohan
klp diff decides what changed by comparing the per-function checksums klp checksum records in .discard.sym_checksum. Handed an object which was never checksummed it has to say so; silently concluding that nothing changed would be the worst available answer. Signed-off-by: Puranjay Mohan <puranjay@kernel.org> Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Assisted-by: Claude:claude-opus-5 Link: https://patch.msgid.link/20260916184351.2720310-27-song@kernel.org
2026-09-21objtool/klp: Add test for objects without .modinfoPuranjay Mohan
The module name recorded in .modinfo ends up in the livepatch's klp_object, and also decides whether a static branch key counts as belonging to vmlinux or to a module. An object without one cannot be diffed. Signed-off-by: Puranjay Mohan <puranjay@kernel.org> Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Assisted-by: Claude:claude-opus-5 Link: https://patch.msgid.link/20260916184351.2720310-26-song@kernel.org
2026-09-21objtool/klp: Add test for correlation across ThinLTO name manglingPuranjay Mohan
ThinLTO promotes the file-local symbols an imported function touches, renaming them name.llvm.<hash>. The hash is content derived, so it changes whenever the module does: original: counter.llvm.13663304415433785070 patched: counter.llvm.10543383937958011340 Correlating the two objects therefore requires demangling the suffix; matching raw names would see two unrelated symbols and treat the variable as new. The resulting klp relocation also has to name the original symbol, since that is the one in the running kernel's kallsyms. Naming the patched build's symbol produces a relocation which can never be resolved. ThinLTO is a clang feature, so the test declares itself clang-only. It also needs an lld from the same LLVM release as $CC; a mismatched pair fails with "Invalid summary version", which reads like a broken test rather than a broken environment, so probe for a working lld and skip if there is none. Signed-off-by: Puranjay Mohan <puranjay@kernel.org> Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Assisted-by: Claude:claude-opus-5 Link: https://patch.msgid.link/20260916184351.2720310-25-song@kernel.org
2026-09-21objtool/klp: Add test for rejecting references to init code/dataPuranjay Mohan
Init code and data are freed once boot finishes, so a klp relocation against them can never resolve. Signed-off-by: Puranjay Mohan <puranjay@kernel.org> Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Assisted-by: Claude:claude-opus-5 Link: https://patch.msgid.link/20260916184351.2720310-24-song@kernel.org
2026-09-21objtool/klp: Add test for symids in discarded sectionsPuranjay Mohan
.klp.symid records duplicate-named locals so klp diff can work out their sympos. Symbols in sections the vmlinux link throws away have to be left out, or the table references symbols which no longer exist and the link fails: `__exitcall_foo' referenced in section `.klp.symid' of vmlinux.o: defined in discarded section `.exitcall.exit' of vmlinux.o Two translation units are compiled from one fixture and partially linked so the result has duplicate locals, which symid_needed() requires. One duplicate is in a live section and one in .exitcall.exit. Checking the live duplicate as well keeps the test honest: it would otherwise pass just as happily if symid generation stopped working entirely. Signed-off-by: Puranjay Mohan <puranjay@kernel.org> Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Assisted-by: Claude:claude-opus-5 Link: https://patch.msgid.link/20260916184351.2720310-23-song@kernel.org
2026-09-21objtool/klp: Add test for rejecting module-owned static call keysPuranjay Mohan
Static calls carry the same constraint as static branches. Check that a vmlinux-owned key is accepted and a module-owned one is refused. Signed-off-by: Puranjay Mohan <puranjay@kernel.org> Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Assisted-by: Claude:claude-opus-5 Link: https://patch.msgid.link/20260916184351.2720310-22-song@kernel.org
2026-09-21objtool/klp: Add test for rejecting module-owned static branch keysPuranjay Mohan
A static branch key belonging to a module cannot be reached with a klp relocation: the patch may be applied after that module's static branch init has run, which corrupts the code. Emitting one anyway produces a module which loads and then BUG()s the first time the key changes state, so klp diff has to refuse it. The fixture differs from the accepted case only in the module name recorded in .modinfo. Signed-off-by: Puranjay Mohan <puranjay@kernel.org> Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Assisted-by: Claude:claude-opus-5 Link: https://patch.msgid.link/20260916184351.2720310-21-song@kernel.org
2026-09-21objtool/klp: Add test for jump table key relocationsPuranjay Mohan
A cloned __jump_table entry must keep a relocation in its key slot. objtool parses the table again after klp diff to convert the static branch's scaffold instruction, and an empty slot leaves it unable to do so. The scaffold then stays as emitted and the module trips BUG() in __jump_label_patch() once the key's state differs from its compile-time default. Check both halves for a vmlinux-owned key: unexported gives a tombstone plus a klp relocation, exported gives an ordinary relocation and no klp machinery. The fixture defines the key as an STT_OBJECT, which is what the kernel emits. validate_special_section_klp_reloc() ignores anything else, so a fixture using an undefined extern would skip the interesting paths. Signed-off-by: Puranjay Mohan <puranjay@kernel.org> Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Assisted-by: Claude:claude-opus-5 Link: https://patch.msgid.link/20260916184351.2720310-20-song@kernel.org
2026-09-21objtool/klp: Add test for selective special section extractionPuranjay Mohan
Two functions contribute entries to one special section but only one is patched. Cloning the neighbouring entry drags in whatever it points at, which is how a livepatch ends up holding relocations against unrelated code. Signed-off-by: Puranjay Mohan <puranjay@kernel.org> Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Assisted-by: Claude:claude-opus-5 Link: https://patch.msgid.link/20260916184351.2720310-19-song@kernel.org
2026-09-21objtool/klp: Add test for special section extractionPuranjay Mohan
create_fake_symbols() gives each special section entry a symbol so entries can be extracted individually. Entries with ANNOTATE_DATA_SPECIAL are handled first; the rest have their boundaries derived from the entry or relocation size. The second pass has to key off whether the first one created symbols, not off whether the section already has something at offset 0. Clang puts an assembler-local label at the start of .kcfi_traps, and treating that as already handled means nothing is extracted: klp diff still reports the changed function and succeeds, but the special section is missing from the module. The fixture reproduces the shape without needing CFI or x86. Signed-off-by: Puranjay Mohan <puranjay@kernel.org> Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Assisted-by: Claude:claude-opus-5 Link: https://patch.msgid.link/20260916184351.2720310-18-song@kernel.org
2026-09-21objtool/klp: Add test for cold function halvesPuranjay Mohan
The compiler splits unlikely code into a separate foo.cold symbol. Both halves are the same function and both belong in the livepatch: carrying only the hot part leaves the cold path branching into unpatched code. GCC needs -freorder-blocks-and-partition to split reliably. The flag is probed rather than assumed, and the test skips when the compiler declines to split at all. Signed-off-by: Puranjay Mohan <puranjay@kernel.org> Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Assisted-by: Claude:claude-opus-5 Link: https://patch.msgid.link/20260916184351.2720310-17-song@kernel.org
2026-09-21objtool/klp: Add test for static local correlationPuranjay Mohan
A static local must be correlated with its original rather than duplicated. The replacement has to reach the existing variable through a klp relocation; a fresh definition would discard whatever state the running kernel accumulated. Signed-off-by: Puranjay Mohan <puranjay@kernel.org> Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Assisted-by: Claude:claude-opus-5 Link: https://patch.msgid.link/20260916184351.2720310-16-song@kernel.org
2026-09-21objtool/klp: Add test for newly introduced functionsPuranjay Mohan
A function added by the patch has no original to correlate against, and still has to be carried into the livepatch or the changed caller ends up referencing something which does not exist. The helper is noinline so the case survives the optimiser; otherwise the compiler folds it into its only caller and the test covers nothing. Signed-off-by: Puranjay Mohan <puranjay@kernel.org> Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Assisted-by: Claude:claude-opus-5 Link: https://patch.msgid.link/20260916184351.2720310-15-song@kernel.org
2026-09-21objtool/klp: Add test for newly introduced dataPuranjay Mohan
Adding data differs from changing it: nothing in the running kernel refers to a new variable, so it is safe and has to travel into the livepatch with the function using it. Signed-off-by: Puranjay Mohan <puranjay@kernel.org> Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Assisted-by: Claude:claude-opus-5 Link: https://patch.msgid.link/20260916184351.2720310-14-song@kernel.org
2026-09-21objtool/klp: Add test for rejecting changed dataPuranjay Mohan
Livepatching replaces functions. Nothing can swap a variable which live code already refers to, so a patch which changes one has to be refused rather than applied with the old value left in place. Signed-off-by: Puranjay Mohan <puranjay@kernel.org> Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Assisted-by: Claude:claude-opus-5 Link: https://patch.msgid.link/20260916184351.2720310-13-song@kernel.org
2026-09-21objtool/klp: Group the klp tests by architectureSong Liu
Which architecture a test is for is expressed by where it lives: tests are in generic/ or in a directory named for their architecture, each carrying its own fixtures, and the runner executes generic/ plus the one that matches. A test which cannot apply here is then not run at all, rather than running in order to announce that it did not. Layout does this better than a declaration would. There is no x86_only(), and no lookup letting a fixtures/<arch>/ file shadow a generic one of the same name -- an arch-specific test simply carries its own fixtures. Compilers cannot work the same way: CI varies CC over the same tree, so a compiler requirement stays a declaration in the test. What a run leaves out is reported once: # not run: 5 tests in x86/ (this run is arm64) Silence would have been cheaper and wrong. A run covering less than the tree holds must not look like a run that covered all of it. Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Assisted-by: Claude:claude-opus-5 Link: https://patch.msgid.link/20260916184351.2720310-4-song@kernel.org