projects/linux·blob master · refs

57 lines · 2.0 KiB

1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Three translation units linked with ThinLTO, two of which have a file-local
4 * helper of the same name.
5 *
6 * TU_C calls into both of the others, so ThinLTO imports entry_a and entry_b
7 * and with them the static helper each one calls. A file-local symbol which
8 * has to become visible is renamed helper.llvm.<hash>, and the hash is content
9 * derived -- so the two helpers get different hashes from each other, and
10 * TU_A's gets a different one again after the patch changes it. Only TU_A's
11 * changes: were both bodies to change, both would be cloned whichever way
12 * they were paired, and the pairing would not be observable.
13 *
14 * That leaves klp diff with two symbols in the original and two in the patched
15 * object, all four named differently, which have to be paired up correctly.
16 * Demangling alone gives "helper" for all of them; something else has to
17 * decide which is which.
18 *
19 * Only TU_A's helper changes. That is what makes a wrong pairing observable:
20 * paired correctly, one helper is changed and the other is not, so exactly one
21 * is cloned. Paired the wrong way round, both look changed -- or the wrong
22 * one does. If both bodies changed the outcome would be the same either way
23 * and the test would prove nothing.
24 *
25 * BASE differs between the two so their bodies are not identical to begin
26 * with.
27 */
28
29#if defined(TU_C)
30extern int entry_a(int x);
31extern int entry_b(int x);
32int glue(int x) { return entry_a(x) + entry_b(x + 1); }
33#else
34#ifdef TU_B
35#define ENTRY entry_b
36#define BASE 5
37#else
38#define ENTRY entry_a
39#define BASE 10
40static const char __modinfo[]
41 __attribute__((section(".modinfo"), used, aligned(1))) = "\0name=vmlinux";
42#endif
43static __attribute__((noinline)) int helper(int x, int len)
44{
45 int sum = 0, i;
46
47 for (i = 0; i < len; i++)
48#if defined(PATCHED) && !defined(TU_B)
49 sum += i * 2 + BASE; /* only TU_A's helper changes */
50#else
51 sum += i + BASE;
52#endif
53 return sum + x;
54}
55
56int ENTRY(int x) { return helper(x, 4); }
57#endif