1*41ca5150SSong Liu // SPDX-License-Identifier: GPL-2.0
2*41ca5150SSong Liu /*
3*41ca5150SSong Liu * A translation unit built with UBSAN, where only one of two functions is
4*41ca5150SSong Liu * patched.
5*41ca5150SSong Liu *
6*41ca5150SSong Liu * Every instrumented operation gets a per-callsite metadata object in an
7*41ca5150SSong Liu * anonymous data section -- .data..Lubsan_data and .data..Lubsan_type from
8*41ca5150SSong Liu * GCC, .data..L__unnamed_ from Clang -- and a call to a __ubsan_handle_*
9*41ca5150SSong Liu * routine. The names are compiler-generated and carry no meaning across a
10*41ca5150SSong Liu * rebuild, so klp diff has to treat those sections as uncorrelated rather than
11*41ca5150SSong Liu * pairing them up by name.
12*41ca5150SSong Liu *
13*41ca5150SSong Liu * untouched() is byte-identical in both builds and exists to catch the false
14*41ca5150SSong Liu * positive: if the metadata were correlated by name, its shifts would look
15*41ca5150SSong Liu * changed and it would be dragged into the patch.
16*41ca5150SSong Liu *
17*41ca5150SSong Liu * The shifts are what draw the instrumentation. A bounds check would do as
18*41ca5150SSong Liu * well but neither compiler emits one for an index it can prove in range.
19*41ca5150SSong Liu */
20*41ca5150SSong Liu
21*41ca5150SSong Liu static const char __modinfo[]
22*41ca5150SSong Liu __attribute__((section(".modinfo"), used, aligned(1))) = "\0name=vmlinux";
23*41ca5150SSong Liu
24*41ca5150SSong Liu int shift_by(int v, int n);
25*41ca5150SSong Liu
untouched(int v,int n)26*41ca5150SSong Liu int untouched(int v, int n)
27*41ca5150SSong Liu {
28*41ca5150SSong Liu int s = 0;
29*41ca5150SSong Liu
30*41ca5150SSong Liu s += v << (n & 31);
31*41ca5150SSong Liu s += v << ((n + 1) & 31);
32*41ca5150SSong Liu s += shift_by(v, n);
33*41ca5150SSong Liu
34*41ca5150SSong Liu return s;
35*41ca5150SSong Liu }
36*41ca5150SSong Liu
touched(int v,int n)37*41ca5150SSong Liu int touched(int v, int n)
38*41ca5150SSong Liu {
39*41ca5150SSong Liu int s = 0;
40*41ca5150SSong Liu
41*41ca5150SSong Liu s += v << (n & 31);
42*41ca5150SSong Liu #ifdef PATCHED
43*41ca5150SSong Liu s += v << ((n + 3) & 31);
44*41ca5150SSong Liu #else
45*41ca5150SSong Liu s += v << ((n + 2) & 31);
46*41ca5150SSong Liu #endif
47*41ca5150SSong Liu
48*41ca5150SSong Liu return s;
49*41ca5150SSong Liu }
50