1fc8c262eSYonghong Song.. SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
2fc8c262eSYonghong Song
3fc8c262eSYonghong Song====================
4fc8c262eSYonghong SongBPF LLVM Relocations
5fc8c262eSYonghong Song====================
6fc8c262eSYonghong Song
7fc8c262eSYonghong SongThis document describes LLVM BPF backend relocation types.
8fc8c262eSYonghong Song
9fc8c262eSYonghong SongRelocation Record
10fc8c262eSYonghong Song=================
11fc8c262eSYonghong Song
12fc8c262eSYonghong SongLLVM BPF backend records each relocation with the following 16-byte
13fc8c262eSYonghong SongELF structure::
14fc8c262eSYonghong Song
15fc8c262eSYonghong Song  typedef struct
16fc8c262eSYonghong Song  {
17fc8c262eSYonghong Song    Elf64_Addr    r_offset;  // Offset from the beginning of section.
18fc8c262eSYonghong Song    Elf64_Xword   r_info;    // Relocation type and symbol index.
19fc8c262eSYonghong Song  } Elf64_Rel;
20fc8c262eSYonghong Song
21fc8c262eSYonghong SongFor example, for the following code::
22fc8c262eSYonghong Song
23fc8c262eSYonghong Song  int g1 __attribute__((section("sec")));
24fc8c262eSYonghong Song  int g2 __attribute__((section("sec")));
25fc8c262eSYonghong Song  static volatile int l1 __attribute__((section("sec")));
26fc8c262eSYonghong Song  static volatile int l2 __attribute__((section("sec")));
27fc8c262eSYonghong Song  int test() {
28fc8c262eSYonghong Song    return g1 + g2 + l1 + l2;
29fc8c262eSYonghong Song  }
30fc8c262eSYonghong Song
31bbaf1ff0SFangrui SongCompiled with ``clang --target=bpf -O2 -c test.c``, the following is
32fc8c262eSYonghong Songthe code with ``llvm-objdump -dr test.o``::
33fc8c262eSYonghong Song
34fc8c262eSYonghong Song       0:       18 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 r1 = 0 ll
35fc8c262eSYonghong Song                0000000000000000:  R_BPF_64_64  g1
36fc8c262eSYonghong Song       2:       61 11 00 00 00 00 00 00 r1 = *(u32 *)(r1 + 0)
37fc8c262eSYonghong Song       3:       18 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 r2 = 0 ll
38fc8c262eSYonghong Song                0000000000000018:  R_BPF_64_64  g2
39fc8c262eSYonghong Song       5:       61 20 00 00 00 00 00 00 r0 = *(u32 *)(r2 + 0)
40fc8c262eSYonghong Song       6:       0f 10 00 00 00 00 00 00 r0 += r1
41fc8c262eSYonghong Song       7:       18 01 00 00 08 00 00 00 00 00 00 00 00 00 00 00 r1 = 8 ll
42fc8c262eSYonghong Song                0000000000000038:  R_BPF_64_64  sec
43fc8c262eSYonghong Song       9:       61 11 00 00 00 00 00 00 r1 = *(u32 *)(r1 + 0)
44fc8c262eSYonghong Song      10:       0f 10 00 00 00 00 00 00 r0 += r1
45fc8c262eSYonghong Song      11:       18 01 00 00 0c 00 00 00 00 00 00 00 00 00 00 00 r1 = 12 ll
46fc8c262eSYonghong Song                0000000000000058:  R_BPF_64_64  sec
47fc8c262eSYonghong Song      13:       61 11 00 00 00 00 00 00 r1 = *(u32 *)(r1 + 0)
48fc8c262eSYonghong Song      14:       0f 10 00 00 00 00 00 00 r0 += r1
49fc8c262eSYonghong Song      15:       95 00 00 00 00 00 00 00 exit
50fc8c262eSYonghong Song
5169535186SWill HawkinsThere are four relocations in the above for four ``LD_imm64`` instructions.
52fc8c262eSYonghong SongThe following ``llvm-readelf -r test.o`` shows the binary values of the four
53fc8c262eSYonghong Songrelocations::
54fc8c262eSYonghong Song
55fc8c262eSYonghong Song  Relocation section '.rel.text' at offset 0x190 contains 4 entries:
56fc8c262eSYonghong Song      Offset             Info             Type               Symbol's Value  Symbol's Name
57fc8c262eSYonghong Song  0000000000000000  0000000600000001 R_BPF_64_64            0000000000000000 g1
58fc8c262eSYonghong Song  0000000000000018  0000000700000001 R_BPF_64_64            0000000000000004 g2
59fc8c262eSYonghong Song  0000000000000038  0000000400000001 R_BPF_64_64            0000000000000000 sec
60fc8c262eSYonghong Song  0000000000000058  0000000400000001 R_BPF_64_64            0000000000000000 sec
61fc8c262eSYonghong Song
62fc8c262eSYonghong SongEach relocation is represented by ``Offset`` (8 bytes) and ``Info`` (8 bytes).
63fc8c262eSYonghong SongFor example, the first relocation corresponds to the first instruction
64fc8c262eSYonghong Song(Offset 0x0) and the corresponding ``Info`` indicates the relocation type
65fc8c262eSYonghong Songof ``R_BPF_64_64`` (type 1) and the entry in the symbol table (entry 6).
66fc8c262eSYonghong SongThe following is the symbol table with ``llvm-readelf -s test.o``::
67fc8c262eSYonghong Song
68fc8c262eSYonghong Song  Symbol table '.symtab' contains 8 entries:
69fc8c262eSYonghong Song     Num:    Value          Size Type    Bind   Vis       Ndx Name
70fc8c262eSYonghong Song       0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT   UND
71fc8c262eSYonghong Song       1: 0000000000000000     0 FILE    LOCAL  DEFAULT   ABS test.c
72fc8c262eSYonghong Song       2: 0000000000000008     4 OBJECT  LOCAL  DEFAULT     4 l1
73fc8c262eSYonghong Song       3: 000000000000000c     4 OBJECT  LOCAL  DEFAULT     4 l2
74fc8c262eSYonghong Song       4: 0000000000000000     0 SECTION LOCAL  DEFAULT     4 sec
75fc8c262eSYonghong Song       5: 0000000000000000   128 FUNC    GLOBAL DEFAULT     2 test
76fc8c262eSYonghong Song       6: 0000000000000000     4 OBJECT  GLOBAL DEFAULT     4 g1
77fc8c262eSYonghong Song       7: 0000000000000004     4 OBJECT  GLOBAL DEFAULT     4 g2
78fc8c262eSYonghong Song
79fc8c262eSYonghong SongThe 6th entry is global variable ``g1`` with value 0.
80fc8c262eSYonghong Song
81fc8c262eSYonghong SongSimilarly, the second relocation is at ``.text`` offset ``0x18``, instruction 3,
8269535186SWill Hawkinshas a type of ``R_BPF_64_64`` and refers to entry 7 in the symbol table.
8369535186SWill HawkinsThe second relocation resolves to global variable ``g2`` which has a symbol
8469535186SWill Hawkinsvalue 4. The symbol value represents the offset from the start of ``.data``
8569535186SWill Hawkinssection where the initial value of the global variable ``g2`` is stored.
86fc8c262eSYonghong Song
8769535186SWill HawkinsThe third and fourth relocations refer to static variables ``l1``
8869535186SWill Hawkinsand ``l2``. From the ``.rel.text`` section above, it is not clear
8969535186SWill Hawkinsto which symbols they really refer as they both refer to
90fc8c262eSYonghong Songsymbol table entry 4, symbol ``sec``, which has ``STT_SECTION`` type
9169535186SWill Hawkinsand represents a section. So for a static variable or function,
92fc8c262eSYonghong Songthe section offset is written to the original insn
93fc8c262eSYonghong Songbuffer, which is called ``A`` (addend). Looking at
94fc8c262eSYonghong Songabove insn ``7`` and ``11``, they have section offset ``8`` and ``12``.
95fc8c262eSYonghong SongFrom symbol table, we can find that they correspond to entries ``2``
96fc8c262eSYonghong Songand ``3`` for ``l1`` and ``l2``.
97fc8c262eSYonghong Song
98fc8c262eSYonghong SongIn general, the ``A`` is 0 for global variables and functions,
99fc8c262eSYonghong Songand is the section offset or some computation result based on
100fc8c262eSYonghong Songsection offset for static variables/functions. The non-section-offset
101fc8c262eSYonghong Songcase refers to function calls. See below for more details.
102fc8c262eSYonghong Song
103fc8c262eSYonghong SongDifferent Relocation Types
104fc8c262eSYonghong Song==========================
105fc8c262eSYonghong Song
106fc8c262eSYonghong SongSix relocation types are supported. The following is an overview and
107fc8c262eSYonghong Song``S`` represents the value of the symbol in the symbol table::
108fc8c262eSYonghong Song
109fc8c262eSYonghong Song  Enum  ELF Reloc Type     Description      BitSize  Offset        Calculation
110fc8c262eSYonghong Song  0     R_BPF_NONE         None
111fc8c262eSYonghong Song  1     R_BPF_64_64        ld_imm64 insn    32       r_offset + 4  S + A
112fc8c262eSYonghong Song  2     R_BPF_64_ABS64     normal data      64       r_offset      S + A
113fc8c262eSYonghong Song  3     R_BPF_64_ABS32     normal data      32       r_offset      S + A
114fc8c262eSYonghong Song  4     R_BPF_64_NODYLD32  .BTF[.ext] data  32       r_offset      S + A
115fc8c262eSYonghong Song  10    R_BPF_64_32        call insn        32       r_offset + 4  (S + A) / 8 - 1
116fc8c262eSYonghong Song
117fc8c262eSYonghong SongFor example, ``R_BPF_64_64`` relocation type is used for ``ld_imm64`` instruction.
118fc8c262eSYonghong SongThe actual to-be-relocated data (0 or section offset)
119fc8c262eSYonghong Songis stored at ``r_offset + 4`` and the read/write
120fc8c262eSYonghong Songdata bitsize is 32 (4 bytes). The relocation can be resolved with
121fc8c262eSYonghong Songthe symbol value plus implicit addend. Note that the ``BitSize`` is 32 which
122fc8c262eSYonghong Songmeans the section offset must be less than or equal to ``UINT32_MAX`` and this
123fc8c262eSYonghong Songis enforced by LLVM BPF backend.
124fc8c262eSYonghong Song
125fc8c262eSYonghong SongIn another case, ``R_BPF_64_ABS64`` relocation type is used for normal 64-bit data.
126fc8c262eSYonghong SongThe actual to-be-relocated data is stored at ``r_offset`` and the read/write data
127fc8c262eSYonghong Songbitsize is 64 (8 bytes). The relocation can be resolved with
128fc8c262eSYonghong Songthe symbol value plus implicit addend.
129fc8c262eSYonghong Song
130fc8c262eSYonghong SongBoth ``R_BPF_64_ABS32`` and ``R_BPF_64_NODYLD32`` types are for 32-bit data.
131fc8c262eSYonghong SongBut ``R_BPF_64_NODYLD32`` specifically refers to relocations in ``.BTF`` and
132fc8c262eSYonghong Song``.BTF.ext`` sections. For cases like bcc where llvm ``ExecutionEngine RuntimeDyld``
133fc8c262eSYonghong Songis involved, ``R_BPF_64_NODYLD32`` types of relocations should not be resolved
134fc8c262eSYonghong Songto actual function/variable address. Otherwise, ``.BTF`` and ``.BTF.ext``
135fc8c262eSYonghong Songbecome unusable by bcc and kernel.
136fc8c262eSYonghong Song
137fc8c262eSYonghong SongType ``R_BPF_64_32`` is used for call instruction. The call target section
138fc8c262eSYonghong Songoffset is stored at ``r_offset + 4`` (32bit) and calculated as
139fc8c262eSYonghong Song``(S + A) / 8 - 1``.
140fc8c262eSYonghong Song
141fc8c262eSYonghong SongExamples
142fc8c262eSYonghong Song========
143fc8c262eSYonghong Song
144fc8c262eSYonghong SongTypes ``R_BPF_64_64`` and ``R_BPF_64_32`` are used to resolve ``ld_imm64``
145fc8c262eSYonghong Songand ``call`` instructions. For example::
146fc8c262eSYonghong Song
147fc8c262eSYonghong Song  __attribute__((noinline)) __attribute__((section("sec1")))
148fc8c262eSYonghong Song  int gfunc(int a, int b) {
149fc8c262eSYonghong Song    return a * b;
150fc8c262eSYonghong Song  }
151fc8c262eSYonghong Song  static __attribute__((noinline)) __attribute__((section("sec1")))
152fc8c262eSYonghong Song  int lfunc(int a, int b) {
153fc8c262eSYonghong Song    return a + b;
154fc8c262eSYonghong Song  }
155fc8c262eSYonghong Song  int global __attribute__((section("sec2")));
156fc8c262eSYonghong Song  int test(int a, int b) {
157fc8c262eSYonghong Song    return gfunc(a, b) +  lfunc(a, b) + global;
158fc8c262eSYonghong Song  }
159fc8c262eSYonghong Song
160bbaf1ff0SFangrui SongCompiled with ``clang --target=bpf -O2 -c test.c``, we will have
161fc8c262eSYonghong Songfollowing code with `llvm-objdump -dr test.o``::
162fc8c262eSYonghong Song
163fc8c262eSYonghong Song  Disassembly of section .text:
164fc8c262eSYonghong Song
165fc8c262eSYonghong Song  0000000000000000 <test>:
166fc8c262eSYonghong Song         0:       bf 26 00 00 00 00 00 00 r6 = r2
167fc8c262eSYonghong Song         1:       bf 17 00 00 00 00 00 00 r7 = r1
168fc8c262eSYonghong Song         2:       85 10 00 00 ff ff ff ff call -1
169fc8c262eSYonghong Song                  0000000000000010:  R_BPF_64_32  gfunc
170fc8c262eSYonghong Song         3:       bf 08 00 00 00 00 00 00 r8 = r0
171fc8c262eSYonghong Song         4:       bf 71 00 00 00 00 00 00 r1 = r7
172fc8c262eSYonghong Song         5:       bf 62 00 00 00 00 00 00 r2 = r6
173fc8c262eSYonghong Song         6:       85 10 00 00 02 00 00 00 call 2
174fc8c262eSYonghong Song                  0000000000000030:  R_BPF_64_32  sec1
175fc8c262eSYonghong Song         7:       0f 80 00 00 00 00 00 00 r0 += r8
176fc8c262eSYonghong Song         8:       18 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 r1 = 0 ll
177fc8c262eSYonghong Song                  0000000000000040:  R_BPF_64_64  global
178fc8c262eSYonghong Song        10:       61 11 00 00 00 00 00 00 r1 = *(u32 *)(r1 + 0)
179fc8c262eSYonghong Song        11:       0f 10 00 00 00 00 00 00 r0 += r1
180fc8c262eSYonghong Song        12:       95 00 00 00 00 00 00 00 exit
181fc8c262eSYonghong Song
182fc8c262eSYonghong Song  Disassembly of section sec1:
183fc8c262eSYonghong Song
184fc8c262eSYonghong Song  0000000000000000 <gfunc>:
185fc8c262eSYonghong Song         0:       bf 20 00 00 00 00 00 00 r0 = r2
186fc8c262eSYonghong Song         1:       2f 10 00 00 00 00 00 00 r0 *= r1
187fc8c262eSYonghong Song         2:       95 00 00 00 00 00 00 00 exit
188fc8c262eSYonghong Song
189fc8c262eSYonghong Song  0000000000000018 <lfunc>:
190fc8c262eSYonghong Song         3:       bf 20 00 00 00 00 00 00 r0 = r2
191fc8c262eSYonghong Song         4:       0f 10 00 00 00 00 00 00 r0 += r1
192fc8c262eSYonghong Song         5:       95 00 00 00 00 00 00 00 exit
193fc8c262eSYonghong Song
194fc8c262eSYonghong SongThe first relocation corresponds to ``gfunc(a, b)`` where ``gfunc`` has a value of 0,
195fc8c262eSYonghong Songso the ``call`` instruction offset is ``(0 + 0)/8 - 1 = -1``.
196fc8c262eSYonghong SongThe second relocation corresponds to ``lfunc(a, b)`` where ``lfunc`` has a section
197fc8c262eSYonghong Songoffset ``0x18``, so the ``call`` instruction offset is ``(0 + 0x18)/8 - 1 = 2``.
198fc8c262eSYonghong SongThe third relocation corresponds to ld_imm64 of ``global``, which has a section
199fc8c262eSYonghong Songoffset ``0``.
200fc8c262eSYonghong Song
201fc8c262eSYonghong SongThe following is an example to show how R_BPF_64_ABS64 could be generated::
202fc8c262eSYonghong Song
203fc8c262eSYonghong Song  int global() { return 0; }
204fc8c262eSYonghong Song  struct t { void *g; } gbl = { global };
205fc8c262eSYonghong Song
206bbaf1ff0SFangrui SongCompiled with ``clang --target=bpf -O2 -g -c test.c``, we will see a
207fc8c262eSYonghong Songrelocation below in ``.data`` section with command
208fc8c262eSYonghong Song``llvm-readelf -r test.o``::
209fc8c262eSYonghong Song
210fc8c262eSYonghong Song  Relocation section '.rel.data' at offset 0x458 contains 1 entries:
211fc8c262eSYonghong Song      Offset             Info             Type               Symbol's Value  Symbol's Name
212fc8c262eSYonghong Song  0000000000000000  0000000700000002 R_BPF_64_ABS64         0000000000000000 global
213fc8c262eSYonghong Song
214fc8c262eSYonghong SongThe relocation says the first 8-byte of ``.data`` section should be
215fc8c262eSYonghong Songfilled with address of ``global`` variable.
216fc8c262eSYonghong Song
217fc8c262eSYonghong SongWith ``llvm-readelf`` output, we can see that dwarf sections have a bunch of
218fc8c262eSYonghong Song``R_BPF_64_ABS32`` and ``R_BPF_64_ABS64`` relocations::
219fc8c262eSYonghong Song
220fc8c262eSYonghong Song  Relocation section '.rel.debug_info' at offset 0x468 contains 13 entries:
221fc8c262eSYonghong Song      Offset             Info             Type               Symbol's Value  Symbol's Name
222fc8c262eSYonghong Song  0000000000000006  0000000300000003 R_BPF_64_ABS32         0000000000000000 .debug_abbrev
223fc8c262eSYonghong Song  000000000000000c  0000000400000003 R_BPF_64_ABS32         0000000000000000 .debug_str
224fc8c262eSYonghong Song  0000000000000012  0000000400000003 R_BPF_64_ABS32         0000000000000000 .debug_str
225fc8c262eSYonghong Song  0000000000000016  0000000600000003 R_BPF_64_ABS32         0000000000000000 .debug_line
226fc8c262eSYonghong Song  000000000000001a  0000000400000003 R_BPF_64_ABS32         0000000000000000 .debug_str
227fc8c262eSYonghong Song  000000000000001e  0000000200000002 R_BPF_64_ABS64         0000000000000000 .text
228fc8c262eSYonghong Song  000000000000002b  0000000400000003 R_BPF_64_ABS32         0000000000000000 .debug_str
229fc8c262eSYonghong Song  0000000000000037  0000000800000002 R_BPF_64_ABS64         0000000000000000 gbl
230fc8c262eSYonghong Song  0000000000000040  0000000400000003 R_BPF_64_ABS32         0000000000000000 .debug_str
231fc8c262eSYonghong Song  ......
232fc8c262eSYonghong Song
233fc8c262eSYonghong SongThe .BTF/.BTF.ext sections has R_BPF_64_NODYLD32 relocations::
234fc8c262eSYonghong Song
235fc8c262eSYonghong Song  Relocation section '.rel.BTF' at offset 0x538 contains 1 entries:
236fc8c262eSYonghong Song      Offset             Info             Type               Symbol's Value  Symbol's Name
237fc8c262eSYonghong Song  0000000000000084  0000000800000004 R_BPF_64_NODYLD32      0000000000000000 gbl
238fc8c262eSYonghong Song
239fc8c262eSYonghong Song  Relocation section '.rel.BTF.ext' at offset 0x548 contains 2 entries:
240fc8c262eSYonghong Song      Offset             Info             Type               Symbol's Value  Symbol's Name
241fc8c262eSYonghong Song  000000000000002c  0000000200000004 R_BPF_64_NODYLD32      0000000000000000 .text
242fc8c262eSYonghong Song  0000000000000040  0000000200000004 R_BPF_64_NODYLD32      0000000000000000 .text
243be4033d3SEduard Zingerman
244be4033d3SEduard Zingerman.. _btf-co-re-relocations:
245be4033d3SEduard Zingerman
246be4033d3SEduard Zingerman=================
247be4033d3SEduard ZingermanCO-RE Relocations
248be4033d3SEduard Zingerman=================
249be4033d3SEduard Zingerman
250be4033d3SEduard ZingermanFrom object file point of view CO-RE mechanism is implemented as a set
251be4033d3SEduard Zingermanof CO-RE specific relocation records. These relocation records are not
252be4033d3SEduard Zingermanrelated to ELF relocations and are encoded in .BTF.ext section.
253*3888fa13SEduard ZingermanSee :ref:`Documentation/bpf/btf.rst <BTF_Ext_Section>` for more
254be4033d3SEduard Zingermaninformation on .BTF.ext structure.
255be4033d3SEduard Zingerman
256be4033d3SEduard ZingermanCO-RE relocations are applied to BPF instructions to update immediate
257be4033d3SEduard Zingermanor offset fields of the instruction at load time with information
258be4033d3SEduard Zingermanrelevant for target kernel.
259be4033d3SEduard Zingerman
260be4033d3SEduard ZingermanField to patch is selected basing on the instruction class:
261be4033d3SEduard Zingerman
262be4033d3SEduard Zingerman* For BPF_ALU, BPF_ALU64, BPF_LD `immediate` field is patched;
263be4033d3SEduard Zingerman* For BPF_LDX, BPF_STX, BPF_ST `offset` field is patched;
264be4033d3SEduard Zingerman* BPF_JMP, BPF_JMP32 instructions **should not** be patched.
265be4033d3SEduard Zingerman
266be4033d3SEduard ZingermanRelocation kinds
267be4033d3SEduard Zingerman================
268be4033d3SEduard Zingerman
269be4033d3SEduard ZingermanThere are several kinds of CO-RE relocations that could be split in
270be4033d3SEduard Zingermanthree groups:
271be4033d3SEduard Zingerman
272be4033d3SEduard Zingerman* Field-based - patch instruction with field related information, e.g.
273be4033d3SEduard Zingerman  change offset field of the BPF_LDX instruction to reflect offset
274be4033d3SEduard Zingerman  of a specific structure field in the target kernel.
275be4033d3SEduard Zingerman
276be4033d3SEduard Zingerman* Type-based - patch instruction with type related information, e.g.
277be4033d3SEduard Zingerman  change immediate field of the BPF_ALU move instruction to 0 or 1 to
278be4033d3SEduard Zingerman  reflect if specific type is present in the target kernel.
279be4033d3SEduard Zingerman
280be4033d3SEduard Zingerman* Enum-based - patch instruction with enum related information, e.g.
281be4033d3SEduard Zingerman  change immediate field of the BPF_LD_IMM64 instruction to reflect
282be4033d3SEduard Zingerman  value of a specific enum literal in the target kernel.
283be4033d3SEduard Zingerman
284be4033d3SEduard ZingermanThe complete list of relocation kinds is represented by the following enum:
285be4033d3SEduard Zingerman
286be4033d3SEduard Zingerman.. code-block:: c
287be4033d3SEduard Zingerman
288be4033d3SEduard Zingerman enum bpf_core_relo_kind {
289be4033d3SEduard Zingerman	BPF_CORE_FIELD_BYTE_OFFSET = 0,  /* field byte offset */
290be4033d3SEduard Zingerman	BPF_CORE_FIELD_BYTE_SIZE   = 1,  /* field size in bytes */
291be4033d3SEduard Zingerman	BPF_CORE_FIELD_EXISTS      = 2,  /* field existence in target kernel */
292be4033d3SEduard Zingerman	BPF_CORE_FIELD_SIGNED      = 3,  /* field signedness (0 - unsigned, 1 - signed) */
293be4033d3SEduard Zingerman	BPF_CORE_FIELD_LSHIFT_U64  = 4,  /* bitfield-specific left bitshift */
294be4033d3SEduard Zingerman	BPF_CORE_FIELD_RSHIFT_U64  = 5,  /* bitfield-specific right bitshift */
295be4033d3SEduard Zingerman	BPF_CORE_TYPE_ID_LOCAL     = 6,  /* type ID in local BPF object */
296be4033d3SEduard Zingerman	BPF_CORE_TYPE_ID_TARGET    = 7,  /* type ID in target kernel */
297be4033d3SEduard Zingerman	BPF_CORE_TYPE_EXISTS       = 8,  /* type existence in target kernel */
298be4033d3SEduard Zingerman	BPF_CORE_TYPE_SIZE         = 9,  /* type size in bytes */
299be4033d3SEduard Zingerman	BPF_CORE_ENUMVAL_EXISTS    = 10, /* enum value existence in target kernel */
300be4033d3SEduard Zingerman	BPF_CORE_ENUMVAL_VALUE     = 11, /* enum value integer value */
301be4033d3SEduard Zingerman	BPF_CORE_TYPE_MATCHES      = 12, /* type match in target kernel */
302be4033d3SEduard Zingerman };
303be4033d3SEduard Zingerman
304be4033d3SEduard ZingermanNotes:
305be4033d3SEduard Zingerman
306be4033d3SEduard Zingerman* ``BPF_CORE_FIELD_LSHIFT_U64`` and ``BPF_CORE_FIELD_RSHIFT_U64`` are
307be4033d3SEduard Zingerman  supposed to be used to read bitfield values using the following
308be4033d3SEduard Zingerman  algorithm:
309be4033d3SEduard Zingerman
310be4033d3SEduard Zingerman  .. code-block:: c
311be4033d3SEduard Zingerman
312be4033d3SEduard Zingerman     // To read bitfield ``f`` from ``struct s``
313be4033d3SEduard Zingerman     is_signed = relo(s->f, BPF_CORE_FIELD_SIGNED)
314be4033d3SEduard Zingerman     off = relo(s->f, BPF_CORE_FIELD_BYTE_OFFSET)
315be4033d3SEduard Zingerman     sz  = relo(s->f, BPF_CORE_FIELD_BYTE_SIZE)
316be4033d3SEduard Zingerman     l   = relo(s->f, BPF_CORE_FIELD_LSHIFT_U64)
317be4033d3SEduard Zingerman     r   = relo(s->f, BPF_CORE_FIELD_RSHIFT_U64)
318be4033d3SEduard Zingerman     // define ``v`` as signed or unsigned integer of size ``sz``
319be4033d3SEduard Zingerman     v = *({s|u}<sz> *)((void *)s + off)
320be4033d3SEduard Zingerman     v <<= l
321be4033d3SEduard Zingerman     v >>= r
322be4033d3SEduard Zingerman
323be4033d3SEduard Zingerman* The ``BPF_CORE_TYPE_MATCHES`` queries matching relation, defined as
324be4033d3SEduard Zingerman  follows:
325be4033d3SEduard Zingerman
326be4033d3SEduard Zingerman  * for integers: types match if size and signedness match;
327be4033d3SEduard Zingerman  * for arrays & pointers: target types are recursively matched;
328be4033d3SEduard Zingerman  * for structs & unions:
329be4033d3SEduard Zingerman
330be4033d3SEduard Zingerman    * local members need to exist in target with the same name;
331be4033d3SEduard Zingerman
332be4033d3SEduard Zingerman    * for each member we recursively check match unless it is already behind a
333be4033d3SEduard Zingerman      pointer, in which case we only check matching names and compatible kind;
334be4033d3SEduard Zingerman
335be4033d3SEduard Zingerman  * for enums:
336be4033d3SEduard Zingerman
337be4033d3SEduard Zingerman    * local variants have to have a match in target by symbolic name (but not
338be4033d3SEduard Zingerman      numeric value);
339be4033d3SEduard Zingerman
340be4033d3SEduard Zingerman    * size has to match (but enum may match enum64 and vice versa);
341be4033d3SEduard Zingerman
342be4033d3SEduard Zingerman  * for function pointers:
343be4033d3SEduard Zingerman
344be4033d3SEduard Zingerman    * number and position of arguments in local type has to match target;
345be4033d3SEduard Zingerman    * for each argument and the return value we recursively check match.
346be4033d3SEduard Zingerman
347be4033d3SEduard ZingermanCO-RE Relocation Record
348be4033d3SEduard Zingerman=======================
349be4033d3SEduard Zingerman
350be4033d3SEduard ZingermanRelocation record is encoded as the following structure:
351be4033d3SEduard Zingerman
352be4033d3SEduard Zingerman.. code-block:: c
353be4033d3SEduard Zingerman
354be4033d3SEduard Zingerman struct bpf_core_relo {
355be4033d3SEduard Zingerman	__u32 insn_off;
356be4033d3SEduard Zingerman	__u32 type_id;
357be4033d3SEduard Zingerman	__u32 access_str_off;
358be4033d3SEduard Zingerman	enum bpf_core_relo_kind kind;
359be4033d3SEduard Zingerman };
360be4033d3SEduard Zingerman
361be4033d3SEduard Zingerman* ``insn_off`` - instruction offset (in bytes) within a code section
362be4033d3SEduard Zingerman  associated with this relocation;
363be4033d3SEduard Zingerman
364be4033d3SEduard Zingerman* ``type_id`` - BTF type ID of the "root" (containing) entity of a
365be4033d3SEduard Zingerman  relocatable type or field;
366be4033d3SEduard Zingerman
367be4033d3SEduard Zingerman* ``access_str_off`` - offset into corresponding .BTF string section.
368be4033d3SEduard Zingerman  String interpretation depends on specific relocation kind:
369be4033d3SEduard Zingerman
370be4033d3SEduard Zingerman  * for field-based relocations, string encodes an accessed field using
371be4033d3SEduard Zingerman    a sequence of field and array indices, separated by colon (:). It's
372be4033d3SEduard Zingerman    conceptually very close to LLVM's `getelementptr <GEP_>`_ instruction's
373be4033d3SEduard Zingerman    arguments for identifying offset to a field. For example, consider the
374be4033d3SEduard Zingerman    following C code:
375be4033d3SEduard Zingerman
376be4033d3SEduard Zingerman    .. code-block:: c
377be4033d3SEduard Zingerman
378be4033d3SEduard Zingerman       struct sample {
379be4033d3SEduard Zingerman           int a;
380be4033d3SEduard Zingerman           int b;
381be4033d3SEduard Zingerman           struct { int c[10]; };
382be4033d3SEduard Zingerman       } __attribute__((preserve_access_index));
383be4033d3SEduard Zingerman       struct sample *s;
384be4033d3SEduard Zingerman
385be4033d3SEduard Zingerman    * Access to ``s[0].a`` would be encoded as ``0:0``:
386be4033d3SEduard Zingerman
387be4033d3SEduard Zingerman      * ``0``: first element of ``s`` (as if ``s`` is an array);
388be4033d3SEduard Zingerman      * ``0``: index of field ``a`` in ``struct sample``.
389be4033d3SEduard Zingerman
390be4033d3SEduard Zingerman    * Access to ``s->a`` would be encoded as ``0:0`` as well.
391be4033d3SEduard Zingerman    * Access to ``s->b`` would be encoded as ``0:1``:
392be4033d3SEduard Zingerman
393be4033d3SEduard Zingerman      * ``0``: first element of ``s``;
394be4033d3SEduard Zingerman      * ``1``: index of field ``b`` in ``struct sample``.
395be4033d3SEduard Zingerman
396be4033d3SEduard Zingerman    * Access to ``s[1].c[5]`` would be encoded as ``1:2:0:5``:
397be4033d3SEduard Zingerman
398be4033d3SEduard Zingerman      * ``1``: second element of ``s``;
399be4033d3SEduard Zingerman      * ``2``: index of anonymous structure field in ``struct sample``;
400be4033d3SEduard Zingerman      * ``0``: index of field ``c`` in anonymous structure;
401be4033d3SEduard Zingerman      * ``5``: access to array element #5.
402be4033d3SEduard Zingerman
403be4033d3SEduard Zingerman  * for type-based relocations, string is expected to be just "0";
404be4033d3SEduard Zingerman
405be4033d3SEduard Zingerman  * for enum value-based relocations, string contains an index of enum
406be4033d3SEduard Zingerman     value within its enum type;
407be4033d3SEduard Zingerman
408be4033d3SEduard Zingerman* ``kind`` - one of ``enum bpf_core_relo_kind``.
409be4033d3SEduard Zingerman
410be4033d3SEduard Zingerman.. _GEP: https://llvm.org/docs/LangRef.html#getelementptr-instruction
411be4033d3SEduard Zingerman
412be4033d3SEduard Zingerman.. _btf_co_re_relocation_examples:
413be4033d3SEduard Zingerman
414be4033d3SEduard ZingermanCO-RE Relocation Examples
415be4033d3SEduard Zingerman=========================
416be4033d3SEduard Zingerman
417be4033d3SEduard ZingermanFor the following C code:
418be4033d3SEduard Zingerman
419be4033d3SEduard Zingerman.. code-block:: c
420be4033d3SEduard Zingerman
421be4033d3SEduard Zingerman struct foo {
422be4033d3SEduard Zingerman   int a;
423be4033d3SEduard Zingerman   int b;
424be4033d3SEduard Zingerman   unsigned c:15;
425be4033d3SEduard Zingerman } __attribute__((preserve_access_index));
426be4033d3SEduard Zingerman
427be4033d3SEduard Zingerman enum bar { U, V };
428be4033d3SEduard Zingerman
429be4033d3SEduard ZingermanWith the following BTF definitions:
430be4033d3SEduard Zingerman
431be4033d3SEduard Zingerman.. code-block::
432be4033d3SEduard Zingerman
433be4033d3SEduard Zingerman ...
434be4033d3SEduard Zingerman [2] STRUCT 'foo' size=8 vlen=2
435be4033d3SEduard Zingerman        'a' type_id=3 bits_offset=0
436be4033d3SEduard Zingerman        'b' type_id=3 bits_offset=32
437be4033d3SEduard Zingerman        'c' type_id=4 bits_offset=64 bitfield_size=15
438be4033d3SEduard Zingerman [3] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED
439be4033d3SEduard Zingerman [4] INT 'unsigned int' size=4 bits_offset=0 nr_bits=32 encoding=(none)
440be4033d3SEduard Zingerman ...
441be4033d3SEduard Zingerman [16] ENUM 'bar' encoding=UNSIGNED size=4 vlen=2
442be4033d3SEduard Zingerman        'U' val=0
443be4033d3SEduard Zingerman        'V' val=1
444be4033d3SEduard Zingerman
445be4033d3SEduard ZingermanField offset relocations are generated automatically when
446be4033d3SEduard Zingerman``__attribute__((preserve_access_index))`` is used, for example:
447be4033d3SEduard Zingerman
448be4033d3SEduard Zingerman.. code-block:: c
449be4033d3SEduard Zingerman
450be4033d3SEduard Zingerman  void alpha(struct foo *s, volatile unsigned long *g) {
451be4033d3SEduard Zingerman    *g = s->a;
452be4033d3SEduard Zingerman    s->a = 1;
453be4033d3SEduard Zingerman  }
454be4033d3SEduard Zingerman
455be4033d3SEduard Zingerman  00 <alpha>:
456be4033d3SEduard Zingerman    0:  r3 = *(s32 *)(r1 + 0x0)
457be4033d3SEduard Zingerman           00:  CO-RE <byte_off> [2] struct foo::a (0:0)
458be4033d3SEduard Zingerman    1:  *(u64 *)(r2 + 0x0) = r3
459be4033d3SEduard Zingerman    2:  *(u32 *)(r1 + 0x0) = 0x1
460be4033d3SEduard Zingerman           10:  CO-RE <byte_off> [2] struct foo::a (0:0)
461be4033d3SEduard Zingerman    3:  exit
462be4033d3SEduard Zingerman
463be4033d3SEduard Zingerman
464be4033d3SEduard ZingermanAll relocation kinds could be requested via built-in functions.
465be4033d3SEduard ZingermanE.g. field-based relocations:
466be4033d3SEduard Zingerman
467be4033d3SEduard Zingerman.. code-block:: c
468be4033d3SEduard Zingerman
469be4033d3SEduard Zingerman  void bravo(struct foo *s, volatile unsigned long *g) {
470be4033d3SEduard Zingerman    *g = __builtin_preserve_field_info(s->b, 0 /* field byte offset */);
471be4033d3SEduard Zingerman    *g = __builtin_preserve_field_info(s->b, 1 /* field byte size */);
472be4033d3SEduard Zingerman    *g = __builtin_preserve_field_info(s->b, 2 /* field existence */);
473be4033d3SEduard Zingerman    *g = __builtin_preserve_field_info(s->b, 3 /* field signedness */);
474be4033d3SEduard Zingerman    *g = __builtin_preserve_field_info(s->c, 4 /* bitfield left shift */);
475be4033d3SEduard Zingerman    *g = __builtin_preserve_field_info(s->c, 5 /* bitfield right shift */);
476be4033d3SEduard Zingerman  }
477be4033d3SEduard Zingerman
478be4033d3SEduard Zingerman  20 <bravo>:
479be4033d3SEduard Zingerman     4:     r1 = 0x4
480be4033d3SEduard Zingerman            20:  CO-RE <byte_off> [2] struct foo::b (0:1)
481be4033d3SEduard Zingerman     5:     *(u64 *)(r2 + 0x0) = r1
482be4033d3SEduard Zingerman     6:     r1 = 0x4
483be4033d3SEduard Zingerman            30:  CO-RE <byte_sz> [2] struct foo::b (0:1)
484be4033d3SEduard Zingerman     7:     *(u64 *)(r2 + 0x0) = r1
485be4033d3SEduard Zingerman     8:     r1 = 0x1
486be4033d3SEduard Zingerman            40:  CO-RE <field_exists> [2] struct foo::b (0:1)
487be4033d3SEduard Zingerman     9:     *(u64 *)(r2 + 0x0) = r1
488be4033d3SEduard Zingerman    10:     r1 = 0x1
489be4033d3SEduard Zingerman            50:  CO-RE <signed> [2] struct foo::b (0:1)
490be4033d3SEduard Zingerman    11:     *(u64 *)(r2 + 0x0) = r1
491be4033d3SEduard Zingerman    12:     r1 = 0x31
492be4033d3SEduard Zingerman            60:  CO-RE <lshift_u64> [2] struct foo::c (0:2)
493be4033d3SEduard Zingerman    13:     *(u64 *)(r2 + 0x0) = r1
494be4033d3SEduard Zingerman    14:     r1 = 0x31
495be4033d3SEduard Zingerman            70:  CO-RE <rshift_u64> [2] struct foo::c (0:2)
496be4033d3SEduard Zingerman    15:     *(u64 *)(r2 + 0x0) = r1
497be4033d3SEduard Zingerman    16:     exit
498be4033d3SEduard Zingerman
499be4033d3SEduard Zingerman
500be4033d3SEduard ZingermanType-based relocations:
501be4033d3SEduard Zingerman
502be4033d3SEduard Zingerman.. code-block:: c
503be4033d3SEduard Zingerman
504be4033d3SEduard Zingerman  void charlie(struct foo *s, volatile unsigned long *g) {
505be4033d3SEduard Zingerman    *g = __builtin_preserve_type_info(*s, 0 /* type existence */);
506be4033d3SEduard Zingerman    *g = __builtin_preserve_type_info(*s, 1 /* type size */);
507be4033d3SEduard Zingerman    *g = __builtin_preserve_type_info(*s, 2 /* type matches */);
508be4033d3SEduard Zingerman    *g = __builtin_btf_type_id(*s, 0 /* type id in this object file */);
509be4033d3SEduard Zingerman    *g = __builtin_btf_type_id(*s, 1 /* type id in target kernel */);
510be4033d3SEduard Zingerman  }
511be4033d3SEduard Zingerman
512be4033d3SEduard Zingerman  88 <charlie>:
513be4033d3SEduard Zingerman    17:     r1 = 0x1
514be4033d3SEduard Zingerman            88:  CO-RE <type_exists> [2] struct foo
515be4033d3SEduard Zingerman    18:     *(u64 *)(r2 + 0x0) = r1
516be4033d3SEduard Zingerman    19:     r1 = 0xc
517be4033d3SEduard Zingerman            98:  CO-RE <type_size> [2] struct foo
518be4033d3SEduard Zingerman    20:     *(u64 *)(r2 + 0x0) = r1
519be4033d3SEduard Zingerman    21:     r1 = 0x1
520be4033d3SEduard Zingerman            a8:  CO-RE <type_matches> [2] struct foo
521be4033d3SEduard Zingerman    22:     *(u64 *)(r2 + 0x0) = r1
522be4033d3SEduard Zingerman    23:     r1 = 0x2 ll
523be4033d3SEduard Zingerman            b8:  CO-RE <local_type_id> [2] struct foo
524be4033d3SEduard Zingerman    25:     *(u64 *)(r2 + 0x0) = r1
525be4033d3SEduard Zingerman    26:     r1 = 0x2 ll
526be4033d3SEduard Zingerman            d0:  CO-RE <target_type_id> [2] struct foo
527be4033d3SEduard Zingerman    28:     *(u64 *)(r2 + 0x0) = r1
528be4033d3SEduard Zingerman    29:     exit
529be4033d3SEduard Zingerman
530be4033d3SEduard ZingermanEnum-based relocations:
531be4033d3SEduard Zingerman
532be4033d3SEduard Zingerman.. code-block:: c
533be4033d3SEduard Zingerman
534be4033d3SEduard Zingerman  void delta(struct foo *s, volatile unsigned long *g) {
535be4033d3SEduard Zingerman    *g = __builtin_preserve_enum_value(*(enum bar *)U, 0 /* enum literal existence */);
536be4033d3SEduard Zingerman    *g = __builtin_preserve_enum_value(*(enum bar *)V, 1 /* enum literal value */);
537be4033d3SEduard Zingerman  }
538be4033d3SEduard Zingerman
539be4033d3SEduard Zingerman  f0 <delta>:
540be4033d3SEduard Zingerman    30:     r1 = 0x1 ll
541be4033d3SEduard Zingerman            f0:  CO-RE <enumval_exists> [16] enum bar::U = 0
542be4033d3SEduard Zingerman    32:     *(u64 *)(r2 + 0x0) = r1
543be4033d3SEduard Zingerman    33:     r1 = 0x1 ll
544be4033d3SEduard Zingerman            108:  CO-RE <enumval_value> [16] enum bar::V = 1
545be4033d3SEduard Zingerman    35:     *(u64 *)(r2 + 0x0) = r1
546be4033d3SEduard Zingerman    36:     exit
547