1.. SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) 2 3==================== 4BPF LLVM Relocations 5==================== 6 7This document describes LLVM BPF backend relocation types. 8 9Relocation Record 10================= 11 12LLVM BPF backend records each relocation with the following 16-byte 13ELF structure:: 14 15 typedef struct 16 { 17 Elf64_Addr r_offset; // Offset from the beginning of section. 18 Elf64_Xword r_info; // Relocation type and symbol index. 19 } Elf64_Rel; 20 21For example, for the following code:: 22 23 int g1 __attribute__((section("sec"))); 24 int g2 __attribute__((section("sec"))); 25 static volatile int l1 __attribute__((section("sec"))); 26 static volatile int l2 __attribute__((section("sec"))); 27 int test() { 28 return g1 + g2 + l1 + l2; 29 } 30 31Compiled with ``clang -target bpf -O2 -c test.c``, the following is 32the code with ``llvm-objdump -dr test.o``:: 33 34 0: 18 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 r1 = 0 ll 35 0000000000000000: R_BPF_64_64 g1 36 2: 61 11 00 00 00 00 00 00 r1 = *(u32 *)(r1 + 0) 37 3: 18 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 r2 = 0 ll 38 0000000000000018: R_BPF_64_64 g2 39 5: 61 20 00 00 00 00 00 00 r0 = *(u32 *)(r2 + 0) 40 6: 0f 10 00 00 00 00 00 00 r0 += r1 41 7: 18 01 00 00 08 00 00 00 00 00 00 00 00 00 00 00 r1 = 8 ll 42 0000000000000038: R_BPF_64_64 sec 43 9: 61 11 00 00 00 00 00 00 r1 = *(u32 *)(r1 + 0) 44 10: 0f 10 00 00 00 00 00 00 r0 += r1 45 11: 18 01 00 00 0c 00 00 00 00 00 00 00 00 00 00 00 r1 = 12 ll 46 0000000000000058: R_BPF_64_64 sec 47 13: 61 11 00 00 00 00 00 00 r1 = *(u32 *)(r1 + 0) 48 14: 0f 10 00 00 00 00 00 00 r0 += r1 49 15: 95 00 00 00 00 00 00 00 exit 50 51There are four relocations in the above for four ``LD_imm64`` instructions. 52The following ``llvm-readelf -r test.o`` shows the binary values of the four 53relocations:: 54 55 Relocation section '.rel.text' at offset 0x190 contains 4 entries: 56 Offset Info Type Symbol's Value Symbol's Name 57 0000000000000000 0000000600000001 R_BPF_64_64 0000000000000000 g1 58 0000000000000018 0000000700000001 R_BPF_64_64 0000000000000004 g2 59 0000000000000038 0000000400000001 R_BPF_64_64 0000000000000000 sec 60 0000000000000058 0000000400000001 R_BPF_64_64 0000000000000000 sec 61 62Each relocation is represented by ``Offset`` (8 bytes) and ``Info`` (8 bytes). 63For example, the first relocation corresponds to the first instruction 64(Offset 0x0) and the corresponding ``Info`` indicates the relocation type 65of ``R_BPF_64_64`` (type 1) and the entry in the symbol table (entry 6). 66The following is the symbol table with ``llvm-readelf -s test.o``:: 67 68 Symbol table '.symtab' contains 8 entries: 69 Num: Value Size Type Bind Vis Ndx Name 70 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND 71 1: 0000000000000000 0 FILE LOCAL DEFAULT ABS test.c 72 2: 0000000000000008 4 OBJECT LOCAL DEFAULT 4 l1 73 3: 000000000000000c 4 OBJECT LOCAL DEFAULT 4 l2 74 4: 0000000000000000 0 SECTION LOCAL DEFAULT 4 sec 75 5: 0000000000000000 128 FUNC GLOBAL DEFAULT 2 test 76 6: 0000000000000000 4 OBJECT GLOBAL DEFAULT 4 g1 77 7: 0000000000000004 4 OBJECT GLOBAL DEFAULT 4 g2 78 79The 6th entry is global variable ``g1`` with value 0. 80 81Similarly, the second relocation is at ``.text`` offset ``0x18``, instruction 3, 82has a type of ``R_BPF_64_64`` and refers to entry 7 in the symbol table. 83The second relocation resolves to global variable ``g2`` which has a symbol 84value 4. The symbol value represents the offset from the start of ``.data`` 85section where the initial value of the global variable ``g2`` is stored. 86 87The third and fourth relocations refer to static variables ``l1`` 88and ``l2``. From the ``.rel.text`` section above, it is not clear 89to which symbols they really refer as they both refer to 90symbol table entry 4, symbol ``sec``, which has ``STT_SECTION`` type 91and represents a section. So for a static variable or function, 92the section offset is written to the original insn 93buffer, which is called ``A`` (addend). Looking at 94above insn ``7`` and ``11``, they have section offset ``8`` and ``12``. 95From symbol table, we can find that they correspond to entries ``2`` 96and ``3`` for ``l1`` and ``l2``. 97 98In general, the ``A`` is 0 for global variables and functions, 99and is the section offset or some computation result based on 100section offset for static variables/functions. The non-section-offset 101case refers to function calls. See below for more details. 102 103Different Relocation Types 104========================== 105 106Six relocation types are supported. The following is an overview and 107``S`` represents the value of the symbol in the symbol table:: 108 109 Enum ELF Reloc Type Description BitSize Offset Calculation 110 0 R_BPF_NONE None 111 1 R_BPF_64_64 ld_imm64 insn 32 r_offset + 4 S + A 112 2 R_BPF_64_ABS64 normal data 64 r_offset S + A 113 3 R_BPF_64_ABS32 normal data 32 r_offset S + A 114 4 R_BPF_64_NODYLD32 .BTF[.ext] data 32 r_offset S + A 115 10 R_BPF_64_32 call insn 32 r_offset + 4 (S + A) / 8 - 1 116 117For example, ``R_BPF_64_64`` relocation type is used for ``ld_imm64`` instruction. 118The actual to-be-relocated data (0 or section offset) 119is stored at ``r_offset + 4`` and the read/write 120data bitsize is 32 (4 bytes). The relocation can be resolved with 121the symbol value plus implicit addend. Note that the ``BitSize`` is 32 which 122means the section offset must be less than or equal to ``UINT32_MAX`` and this 123is enforced by LLVM BPF backend. 124 125In another case, ``R_BPF_64_ABS64`` relocation type is used for normal 64-bit data. 126The actual to-be-relocated data is stored at ``r_offset`` and the read/write data 127bitsize is 64 (8 bytes). The relocation can be resolved with 128the symbol value plus implicit addend. 129 130Both ``R_BPF_64_ABS32`` and ``R_BPF_64_NODYLD32`` types are for 32-bit data. 131But ``R_BPF_64_NODYLD32`` specifically refers to relocations in ``.BTF`` and 132``.BTF.ext`` sections. For cases like bcc where llvm ``ExecutionEngine RuntimeDyld`` 133is involved, ``R_BPF_64_NODYLD32`` types of relocations should not be resolved 134to actual function/variable address. Otherwise, ``.BTF`` and ``.BTF.ext`` 135become unusable by bcc and kernel. 136 137Type ``R_BPF_64_32`` is used for call instruction. The call target section 138offset is stored at ``r_offset + 4`` (32bit) and calculated as 139``(S + A) / 8 - 1``. 140 141Examples 142======== 143 144Types ``R_BPF_64_64`` and ``R_BPF_64_32`` are used to resolve ``ld_imm64`` 145and ``call`` instructions. For example:: 146 147 __attribute__((noinline)) __attribute__((section("sec1"))) 148 int gfunc(int a, int b) { 149 return a * b; 150 } 151 static __attribute__((noinline)) __attribute__((section("sec1"))) 152 int lfunc(int a, int b) { 153 return a + b; 154 } 155 int global __attribute__((section("sec2"))); 156 int test(int a, int b) { 157 return gfunc(a, b) + lfunc(a, b) + global; 158 } 159 160Compiled with ``clang -target bpf -O2 -c test.c``, we will have 161following code with `llvm-objdump -dr test.o``:: 162 163 Disassembly of section .text: 164 165 0000000000000000 <test>: 166 0: bf 26 00 00 00 00 00 00 r6 = r2 167 1: bf 17 00 00 00 00 00 00 r7 = r1 168 2: 85 10 00 00 ff ff ff ff call -1 169 0000000000000010: R_BPF_64_32 gfunc 170 3: bf 08 00 00 00 00 00 00 r8 = r0 171 4: bf 71 00 00 00 00 00 00 r1 = r7 172 5: bf 62 00 00 00 00 00 00 r2 = r6 173 6: 85 10 00 00 02 00 00 00 call 2 174 0000000000000030: R_BPF_64_32 sec1 175 7: 0f 80 00 00 00 00 00 00 r0 += r8 176 8: 18 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 r1 = 0 ll 177 0000000000000040: R_BPF_64_64 global 178 10: 61 11 00 00 00 00 00 00 r1 = *(u32 *)(r1 + 0) 179 11: 0f 10 00 00 00 00 00 00 r0 += r1 180 12: 95 00 00 00 00 00 00 00 exit 181 182 Disassembly of section sec1: 183 184 0000000000000000 <gfunc>: 185 0: bf 20 00 00 00 00 00 00 r0 = r2 186 1: 2f 10 00 00 00 00 00 00 r0 *= r1 187 2: 95 00 00 00 00 00 00 00 exit 188 189 0000000000000018 <lfunc>: 190 3: bf 20 00 00 00 00 00 00 r0 = r2 191 4: 0f 10 00 00 00 00 00 00 r0 += r1 192 5: 95 00 00 00 00 00 00 00 exit 193 194The first relocation corresponds to ``gfunc(a, b)`` where ``gfunc`` has a value of 0, 195so the ``call`` instruction offset is ``(0 + 0)/8 - 1 = -1``. 196The second relocation corresponds to ``lfunc(a, b)`` where ``lfunc`` has a section 197offset ``0x18``, so the ``call`` instruction offset is ``(0 + 0x18)/8 - 1 = 2``. 198The third relocation corresponds to ld_imm64 of ``global``, which has a section 199offset ``0``. 200 201The following is an example to show how R_BPF_64_ABS64 could be generated:: 202 203 int global() { return 0; } 204 struct t { void *g; } gbl = { global }; 205 206Compiled with ``clang -target bpf -O2 -g -c test.c``, we will see a 207relocation below in ``.data`` section with command 208``llvm-readelf -r test.o``:: 209 210 Relocation section '.rel.data' at offset 0x458 contains 1 entries: 211 Offset Info Type Symbol's Value Symbol's Name 212 0000000000000000 0000000700000002 R_BPF_64_ABS64 0000000000000000 global 213 214The relocation says the first 8-byte of ``.data`` section should be 215filled with address of ``global`` variable. 216 217With ``llvm-readelf`` output, we can see that dwarf sections have a bunch of 218``R_BPF_64_ABS32`` and ``R_BPF_64_ABS64`` relocations:: 219 220 Relocation section '.rel.debug_info' at offset 0x468 contains 13 entries: 221 Offset Info Type Symbol's Value Symbol's Name 222 0000000000000006 0000000300000003 R_BPF_64_ABS32 0000000000000000 .debug_abbrev 223 000000000000000c 0000000400000003 R_BPF_64_ABS32 0000000000000000 .debug_str 224 0000000000000012 0000000400000003 R_BPF_64_ABS32 0000000000000000 .debug_str 225 0000000000000016 0000000600000003 R_BPF_64_ABS32 0000000000000000 .debug_line 226 000000000000001a 0000000400000003 R_BPF_64_ABS32 0000000000000000 .debug_str 227 000000000000001e 0000000200000002 R_BPF_64_ABS64 0000000000000000 .text 228 000000000000002b 0000000400000003 R_BPF_64_ABS32 0000000000000000 .debug_str 229 0000000000000037 0000000800000002 R_BPF_64_ABS64 0000000000000000 gbl 230 0000000000000040 0000000400000003 R_BPF_64_ABS32 0000000000000000 .debug_str 231 ...... 232 233The .BTF/.BTF.ext sections has R_BPF_64_NODYLD32 relocations:: 234 235 Relocation section '.rel.BTF' at offset 0x538 contains 1 entries: 236 Offset Info Type Symbol's Value Symbol's Name 237 0000000000000084 0000000800000004 R_BPF_64_NODYLD32 0000000000000000 gbl 238 239 Relocation section '.rel.BTF.ext' at offset 0x548 contains 2 entries: 240 Offset Info Type Symbol's Value Symbol's Name 241 000000000000002c 0000000200000004 R_BPF_64_NODYLD32 0000000000000000 .text 242 0000000000000040 0000000200000004 R_BPF_64_NODYLD32 0000000000000000 .text 243