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) 30 extern int entry_a(int x); 31 extern int entry_b(int x); 32 int 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 40 static const char __modinfo[] 41 __attribute__((section(".modinfo"), used, aligned(1))) = "\0name=vmlinux"; 42 #endif 43 static __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 56 int ENTRY(int x) { return helper(x, 4); } 57 #endif 58