1*c8304204SSong Liu // SPDX-License-Identifier: GPL-2.0
2*c8304204SSong Liu /*
3*c8304204SSong Liu * Symbols calculate_checksums() must not give an entry of their own.
4*c8304204SSong Liu *
5*c8304204SSong Liu * Three kinds are skipped, for two different reasons:
6*c8304204SSong Liu *
7*c8304204SSong Liu * zero-length there is nothing to hash, and an entry keyed on the
8*c8304204SSong Liu * symbol's address would collide with whatever really lives
9*c8304204SSong Liu * there.
10*c8304204SSong Liu * alias a second name for an address already checksummed.
11*c8304204SSong Liu * cold part hashed as part of its parent, which func_for_each_insn()
12*c8304204SSong Liu * walks into, so a separate entry would double-count it.
13*c8304204SSong Liu *
14*c8304204SSong Liu * An entry per address is the invariant: .discard.sym_checksum is looked up by
15*c8304204SSong Liu * the address a relocation points at, so two entries for one address make the
16*c8304204SSong Liu * lookup ambiguous and one of the two checksums unreachable.
17*c8304204SSong Liu */
18*c8304204SSong Liu
19*c8304204SSong Liu static const char __modinfo[]
20*c8304204SSong Liu __attribute__((section(".modinfo"), used, aligned(1))) = "\0name=vmlinux";
21*c8304204SSong Liu
22*c8304204SSong Liu /* Zero-length: an object symbol of size 0, in a section of its own. */
23*c8304204SSong Liu extern char empty_marker[];
24*c8304204SSong Liu __asm__(".pushsection .data.empty_marker,\"aw\",@progbits\n"
25*c8304204SSong Liu ".globl empty_marker\n"
26*c8304204SSong Liu ".type empty_marker, @object\n"
27*c8304204SSong Liu "empty_marker:\n"
28*c8304204SSong Liu ".size empty_marker, 0\n"
29*c8304204SSong Liu ".popsection\n");
30*c8304204SSong Liu
31*c8304204SSong Liu int real_function(int x);
real_function(int x)32*c8304204SSong Liu int real_function(int x)
33*c8304204SSong Liu {
34*c8304204SSong Liu #ifdef PATCHED
35*c8304204SSong Liu return x + 2;
36*c8304204SSong Liu #else
37*c8304204SSong Liu return x + 1;
38*c8304204SSong Liu #endif
39*c8304204SSong Liu }
40*c8304204SSong Liu
41*c8304204SSong Liu /* Alias: a second name for real_function's address. */
42*c8304204SSong Liu int alias_function(int x) __attribute__((alias("real_function")));
43*c8304204SSong Liu
target(int x)44*c8304204SSong Liu int target(int x)
45*c8304204SSong Liu {
46*c8304204SSong Liu return real_function(x) + alias_function(x) + (int)(long)empty_marker;
47*c8304204SSong Liu }
48