]>
Commit | Line | Data |
---|---|---|
d218e7fe JM |
1 | /* bpf.h - BPF opcode list for binutils. |
2 | Copyright (C) 2023 Free Software Foundation, Inc. | |
3 | ||
4 | Contributed by Oracle Inc. | |
5 | ||
6 | This file is part of the GNU binutils. | |
7 | ||
8 | This is free software; you can redistribute them and/or modify them | |
9 | under the terms of the GNU General Public License as published by | |
10 | the Free Software Foundation; either version 3, or (at your option) | |
11 | any later version. | |
12 | ||
13 | This program is distributed in the hope that it will be useful, but | |
14 | WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
16 | General Public License for more details. | |
17 | ||
18 | You should have received a copy of the GNU General Public License | |
19 | along with this program; see the file COPYING3. If not, | |
20 | see <http://www.gnu.org/licenses/>. */ | |
21 | ||
22 | #ifndef _BPF_H_ | |
23 | #define _BPF_H_ | |
24 | ||
25 | #include <stdint.h> | |
26 | ||
27 | /* The BPF ISA has little-endian and big-endian variants. */ | |
28 | ||
29 | enum bpf_endian | |
30 | { | |
31 | BPF_ENDIAN_LITTLE, | |
32 | BPF_ENDIAN_BIG | |
33 | }; | |
34 | ||
35 | /* Most BPF instructions are conformed by a single 64-bit instruction | |
36 | word. The lddw instruction is conformed by two consecutive 64-bit | |
37 | instruction words. */ | |
38 | ||
39 | typedef uint64_t bpf_insn_word; | |
40 | ||
41 | /* There are several versions of the BPF ISA. */ | |
42 | ||
43 | #define BPF_V1 0x1 | |
44 | #define BPF_V2 0x2 | |
45 | #define BPF_V3 0x3 | |
46 | #define BPF_V4 0x4 | |
47 | #define BPF_XBPF 0xff | |
48 | ||
49 | /* Masks for the several instruction fields in a BPF instruction. | |
50 | These assume big-endian BPF instructions. */ | |
51 | ||
52 | #define BPF_CODE 0xff00000000000000UL | |
53 | #define BPF_REGS 0x00ff000000000000UL | |
54 | #define BPF_DST 0x00f0000000000000UL | |
55 | #define BPF_SRC 0x000f000000000000UL | |
56 | #define BPF_OFFSET16 0x0000ffff00000000UL | |
57 | #define BPF_IMM32 0x00000000ffffffffUL | |
58 | ||
59 | /* The BPF opcode instruction field is eight bits long and its | |
60 | interpretation depends on the instruction class. | |
61 | ||
62 | For arithmetic and jump instructions the 8-bit opcode field is | |
63 | subdivided in: | |
64 | ||
65 | op-code:4 op-src:1 op-class:3 | |
66 | ||
67 | For load/store instructions, the 8-bit opcode field is subdivided | |
68 | in: | |
69 | ||
70 | op-mode:3 op-size:2 op-class:3 | |
71 | ||
72 | All the constants defined below are to be applied on the first | |
73 | 64-bit word of a BPF instruction. Please define them assuming | |
74 | big-endian instructions; the matching and writing routines using | |
75 | the instruction table know how to handle the endianness groups. */ | |
76 | ||
77 | #define BPF_SRC_X ((uint64_t)0x08 << 56) | |
78 | #define BPF_SRC_K ((uint64_t)0x00 << 56) | |
79 | ||
80 | #define BPF_CODE_ADD ((uint64_t)0x00 << 56) | |
81 | #define BPF_CODE_SUB ((uint64_t)0x10 << 56) | |
82 | #define BPF_CODE_MUL ((uint64_t)0x20 << 56) | |
83 | #define BPF_CODE_DIV ((uint64_t)0x30 << 56) | |
84 | #define BPF_CODE_OR ((uint64_t)0x40 << 56) | |
85 | #define BPF_CODE_AND ((uint64_t)0x50 << 56) | |
86 | #define BPF_CODE_LSH ((uint64_t)0x60 << 56) | |
87 | #define BPF_CODE_RSH ((uint64_t)0x70 << 56) | |
88 | #define BPF_CODE_NEG ((uint64_t)0x80 << 56) | |
89 | #define BPF_CODE_MOD ((uint64_t)0x90 << 56) | |
90 | #define BPF_CODE_XOR ((uint64_t)0xa0 << 56) | |
91 | #define BPF_CODE_MOV ((uint64_t)0xb0 << 56) | |
92 | #define BPF_CODE_ARSH ((uint64_t)0xc0 << 56) | |
93 | #define BPF_CODE_END ((uint64_t)0xd0 << 56) | |
94 | ||
95 | #define BPF_CODE_JA ((uint64_t)0x00 << 56) | |
96 | #define BPF_CODE_JEQ ((uint64_t)0x10 << 56) | |
97 | #define BPF_CODE_JGT ((uint64_t)0x20 << 56) | |
98 | #define BPF_CODE_JGE ((uint64_t)0x30 << 56) | |
99 | #define BPF_CODE_JSET ((uint64_t)0x40 << 56) | |
100 | #define BPF_CODE_JNE ((uint64_t)0x50 << 56) | |
101 | #define BPF_CODE_JSGT ((uint64_t)0x60 << 56) | |
102 | #define BPF_CODE_JSGE ((uint64_t)0x70 << 56) | |
103 | #define BPF_CODE_CALL ((uint64_t)0x80 << 56) | |
104 | #define BPF_CODE_EXIT ((uint64_t)0x90 << 56) | |
105 | #define BPF_CODE_JLT ((uint64_t)0xa0 << 56) | |
106 | #define BPF_CODE_JLE ((uint64_t)0xb0 << 56) | |
107 | #define BPF_CODE_JSLT ((uint64_t)0xc0 << 56) | |
108 | #define BPF_CODE_JSLE ((uint64_t)0xd0 << 56) | |
109 | ||
110 | #define BPF_MODE_IMM ((uint64_t)0x00 << 56) | |
111 | #define BPF_MODE_ABS ((uint64_t)0x20 << 56) | |
112 | #define BPF_MODE_IND ((uint64_t)0x40 << 56) | |
113 | #define BPF_MODE_MEM ((uint64_t)0x60 << 56) | |
114 | #define BPF_MODE_ATOMIC ((uint64_t)0xc0 << 56) | |
c24fd954 | 115 | #define BPF_MODE_SMEM ((uint64_t)0x80 << 56) |
d218e7fe JM |
116 | |
117 | #define BPF_SIZE_W ((uint64_t)0x00 << 56) | |
118 | #define BPF_SIZE_H ((uint64_t)0x08 << 56) | |
119 | #define BPF_SIZE_B ((uint64_t)0x10 << 56) | |
120 | #define BPF_SIZE_DW ((uint64_t)0x18 << 56) | |
121 | ||
122 | #define BPF_CLASS_LD ((uint64_t)0x00 << 56) | |
123 | #define BPF_CLASS_LDX ((uint64_t)0x01 << 56) | |
124 | #define BPF_CLASS_ST ((uint64_t)0x02 << 56) | |
125 | #define BPF_CLASS_STX ((uint64_t)0x03 << 56) | |
126 | #define BPF_CLASS_ALU ((uint64_t)0x04 << 56) | |
127 | #define BPF_CLASS_JMP ((uint64_t)0x05 << 56) | |
128 | #define BPF_CLASS_JMP32 ((uint64_t)0x06 << 56) | |
129 | #define BPF_CLASS_ALU64 ((uint64_t)0x07 << 56) | |
130 | ||
131 | /* Certain instructions (ab)use other instruction fields as opcodes, | |
132 | even if these are multi-byte or infra-byte. Bleh. */ | |
133 | ||
134 | #define BPF_OFFSET16_SDIVMOD ((uint64_t)0x1 << 32) | |
2f3dbc5f JM |
135 | #define BPF_OFFSET16_MOVS8 ((uint64_t)8 << 32) |
136 | #define BPF_OFFSET16_MOVS16 ((uint64_t)16 << 32) | |
137 | #define BPF_OFFSET16_MOVS32 ((uint64_t)32 << 32) | |
d218e7fe JM |
138 | |
139 | #define BPF_IMM32_END16 ((uint64_t)0x00000010) | |
140 | #define BPF_IMM32_END32 ((uint64_t)0x00000020) | |
141 | #define BPF_IMM32_END64 ((uint64_t)0x00000040) | |
142 | ||
143 | #define BPF_IMM32_AADD ((uint64_t)0x00000000) | |
144 | #define BPF_IMM32_AOR ((uint64_t)0x00000040) | |
145 | #define BPF_IMM32_AAND ((uint64_t)0x00000050) | |
146 | #define BPF_IMM32_AXOR ((uint64_t)0x000000a0) | |
147 | #define BPF_IMM32_AFADD ((uint64_t)0x00000001) | |
148 | #define BPF_IMM32_AFOR ((uint64_t)0x00000041) | |
149 | #define BPF_IMM32_AFAND ((uint64_t)0x00000051) | |
150 | #define BPF_IMM32_AFXOR ((uint64_t)0x000000a1) | |
151 | #define BPF_IMM32_AXCHG ((uint64_t)0x000000e1) | |
152 | #define BPF_IMM32_ACMP ((uint64_t)b0x000000f1) | |
153 | ||
154 | /* Unique identifiers for BPF instructions. */ | |
155 | ||
156 | enum bpf_insn_id | |
157 | { | |
158 | BPF_NOINSN = 0, | |
159 | /* 64-bit load instruction. */ | |
160 | BPF_INSN_LDDW, | |
161 | /* ALU instructions. */ | |
162 | BPF_INSN_ADDR, BPF_INSN_ADDI, BPF_INSN_SUBR, BPF_INSN_SUBI, | |
163 | BPF_INSN_MULR, BPF_INSN_MULI, BPF_INSN_SDIVR, BPF_INSN_SDIVI, | |
164 | BPF_INSN_SMODR, BPF_INSN_SMODI, BPF_INSN_DIVR, BPF_INSN_DIVI, | |
165 | BPF_INSN_MODR, BPF_INSN_MODI, BPF_INSN_ORR, BPF_INSN_ORI, | |
166 | BPF_INSN_ANDR, BPF_INSN_ANDI, BPF_INSN_XORR, BPF_INSN_XORI, | |
167 | BPF_INSN_NEGR, BPF_INSN_NEGI, BPF_INSN_LSHR, BPF_INSN_LSHI, | |
168 | BPF_INSN_RSHR, BPF_INSN_RSHI, BPF_INSN_ARSHR, BPF_INSN_ARSHI, | |
2f3dbc5f | 169 | BPF_INSN_MOVS8R, BPF_INSN_MOVS16R, BPF_INSN_MOVS32R, |
d218e7fe JM |
170 | BPF_INSN_MOVR, BPF_INSN_MOVI, |
171 | /* ALU32 instructions. */ | |
172 | BPF_INSN_ADD32R, BPF_INSN_ADD32I, BPF_INSN_SUB32R, BPF_INSN_SUB32I, | |
173 | BPF_INSN_MUL32R, BPF_INSN_MUL32I, BPF_INSN_SDIV32R, BPF_INSN_SDIV32I, | |
174 | BPF_INSN_SMOD32R, BPF_INSN_SMOD32I, BPF_INSN_DIV32R, BPF_INSN_DIV32I, | |
175 | BPF_INSN_MOD32R, BPF_INSN_MOD32I, BPF_INSN_OR32R, BPF_INSN_OR32I, | |
176 | BPF_INSN_AND32R, BPF_INSN_AND32I, BPF_INSN_XOR32R, BPF_INSN_XOR32I, | |
177 | BPF_INSN_NEG32R, BPF_INSN_NEG32I, BPF_INSN_LSH32R, BPF_INSN_LSH32I, | |
178 | BPF_INSN_RSH32R, BPF_INSN_RSH32I, BPF_INSN_ARSH32R, BPF_INSN_ARSH32I, | |
2f3dbc5f | 179 | BPF_INSN_MOVS328R, BPF_INSN_MOVS3216R, BPF_INSN_MOVS3232R, |
d218e7fe JM |
180 | BPF_INSN_MOV32R, BPF_INSN_MOV32I, |
181 | /* Endianness conversion instructions. */ | |
182 | BPF_INSN_ENDLE16, BPF_INSN_ENDLE32, BPF_INSN_ENDLE64, | |
183 | BPF_INSN_ENDBE16, BPF_INSN_ENDBE32, BPF_INSN_ENDBE64, | |
184 | /* Absolute load instructions. */ | |
185 | BPF_INSN_LDABSB, BPF_INSN_LDABSH, BPF_INSN_LDABSW, BPF_INSN_LDABSDW, | |
186 | /* Indirect load instructions. */ | |
187 | BPF_INSN_LDINDB, BPF_INSN_LDINDH, BPF_INSN_LDINDW, BPF_INSN_LDINDDW, | |
188 | /* Generic load instructions (to register.) */ | |
189 | BPF_INSN_LDXB, BPF_INSN_LDXH, BPF_INSN_LDXW, BPF_INSN_LDXDW, | |
c24fd954 JM |
190 | /* Generic signed load instructions. */ |
191 | BPF_INSN_LDXSB, BPF_INSN_LDXSH, BPF_INSN_LDXSW, BPF_INSN_LDXSDW, | |
d218e7fe JM |
192 | /* Generic store instructions (from register.) */ |
193 | BPF_INSN_STXBR, BPF_INSN_STXHR, BPF_INSN_STXWR, BPF_INSN_STXDWR, | |
194 | BPF_INSN_STXBI, BPF_INSN_STXHI, BPF_INSN_STXWI, BPF_INSN_STXDWI, | |
195 | /* Compare-and-jump instructions (reg OP reg.) */ | |
196 | BPF_INSN_JAR, BPF_INSN_JEQR, BPF_INSN_JGTR, BPF_INSN_JSGTR, | |
197 | BPF_INSN_JGER, BPF_INSN_JSGER, BPF_INSN_JLTR, BPF_INSN_JSLTR, | |
198 | BPF_INSN_JSLER, BPF_INSN_JLER, BPF_INSN_JSETR, BPF_INSN_JNER, | |
199 | BPF_INSN_CALLR, BPF_INSN_CALL, BPF_INSN_EXIT, | |
200 | /* Compare-and-jump instructions (reg OP imm.) */ | |
201 | BPF_INSN_JEQI, BPF_INSN_JGTI, BPF_INSN_JSGTI, | |
202 | BPF_INSN_JGEI, BPF_INSN_JSGEI, BPF_INSN_JLTI, BPF_INSN_JSLTI, | |
203 | BPF_INSN_JSLEI, BPF_INSN_JLEI, BPF_INSN_JSETI, BPF_INSN_JNEI, | |
204 | BPF_INSN_CALLI, | |
205 | /* 32-bit compare-and-jump instructions (reg OP reg.) */ | |
206 | BPF_INSN_JEQ32R, BPF_INSN_JGT32R, BPF_INSN_JSGT32R, | |
207 | BPF_INSN_JGE32R, BPF_INSN_JSGE32R, BPF_INSN_JLT32R, BPF_INSN_JSLT32R, | |
208 | BPF_INSN_JSLE32R, BPF_INSN_JLE32R, BPF_INSN_JSET32R, BPF_INSN_JNE32R, | |
209 | /* 32-bit compare-and-jump instructions (reg OP imm.) */ | |
210 | BPF_INSN_JEQ32I, BPF_INSN_JGT32I, BPF_INSN_JSGT32I, | |
211 | BPF_INSN_JGE32I, BPF_INSN_JSGE32I, BPF_INSN_JLT32I, BPF_INSN_JSLT32I, | |
212 | BPF_INSN_JSLE32I, BPF_INSN_JLE32I, BPF_INSN_JSET32I, BPF_INSN_JNE32I, | |
213 | /* Atomic instructions. */ | |
214 | BPF_INSN_AADD, BPF_INSN_AOR, BPF_INSN_AAND, BPF_INSN_AXOR, | |
215 | /* Atomic instructions with fetching. */ | |
216 | BPF_INSN_AFADD, BPF_INSN_AFOR, BPF_INSN_AFAND, BPF_INSN_AFXOR, | |
217 | /* Atomic instructions (32-bit.) */ | |
218 | BPF_INSN_AADD32, BPF_INSN_AOR32, BPF_INSN_AAND32, BPF_INSN_AXOR32, | |
219 | /* Atomic instructions with fetching (32-bit.) */ | |
220 | BPF_INSN_AFADD32, BPF_INSN_AFOR32, BPF_INSN_AFAND32, BPF_INSN_AFXOR32, | |
221 | /* GNU simulator specific instruction. */ | |
222 | BPF_INSN_BRKPT, | |
223 | }; | |
224 | ||
225 | /* Entry for a BPF instruction in the opcodes table. */ | |
226 | ||
227 | struct bpf_opcode | |
228 | { | |
229 | /* Unique numerical code for the instruction. */ | |
230 | enum bpf_insn_id id; | |
231 | ||
232 | /* The instruction template defines both the syntax of the | |
233 | instruction and the set of the different operands that appear in | |
234 | the instruction. | |
235 | ||
236 | Tags: | |
237 | %% - literal %. | |
238 | %dr - destination 64-bit register. | |
239 | %dw - destination 32-bit register. | |
240 | %sr - source 64-bit register. | |
241 | %sw - source 32-bit register. | |
242 | %d32 - 32-bit signed displacement (in 64-bit words minus one.) | |
243 | %d16 - 16-bit signed displacement (in 64-bit words minus one.) | |
244 | %o16 - 16-bit signed offset (in bytes.) | |
245 | %i32 - 32-bit signed immediate. | |
246 | %I32 - Like %i32. | |
247 | %i64 - 64-bit signed immediate. | |
248 | %w - expect zero or more white spaces and print a single space. | |
249 | %W - expect one or more white spaces and print a single space. | |
250 | ||
251 | When parsing and printing %o16 and %I32 (but not %i32) an | |
252 | explicit sign is always expected and included. Therefore, to | |
253 | denote something like `[%r3 + 10]', please use a template like `[ | |
254 | %sr %o16]' instead of `[ %sr + %o16 ]'. | |
255 | ||
256 | If %dr, %dw, %sr or %sw are found multiple times in a template, | |
257 | they refer to the same register, i.e. `%rd = le64 %rd' denotes | |
258 | `r2 = le64 r2', but not `r2 = le64 r1'. | |
259 | ||
260 | If %i64 appears in a template then the instruction is 128-bits | |
261 | long and composed by two consecutive 64-bit instruction words. | |
262 | ||
263 | A white space character means to expect zero or more white | |
264 | spaces, and to print no space. | |
265 | ||
266 | There are two templates defined per instruction, corresponding to | |
267 | two used different dialects: a "normal" assembly-like syntax and | |
268 | a "pseudo-c" syntax. Some toolchains support just one of these | |
269 | dialects. The GNU Toolchain supports both. */ | |
270 | const char *normal; | |
271 | const char *pseudoc; | |
272 | ||
273 | /* The version that introduced this instruction. Instructions are | |
274 | generally not removed once they get introduced. */ | |
275 | uint8_t version; | |
276 | ||
277 | /* Maks marking the opcode fields in the instruction, and the | |
278 | opcodes characterizing it. | |
279 | ||
280 | In multi-word instructions these apply to the first word in the | |
281 | instruction. Note that these values assumes big-endian | |
282 | instructions; code using these field must be aware of the | |
283 | endianness groups to which BPF instructions must conform to and | |
284 | DTRT. */ | |
285 | bpf_insn_word mask; | |
286 | bpf_insn_word opcode; | |
287 | }; | |
288 | ||
289 | /* Try to match a BPF instruction given its first instruction word. | |
290 | If no matching instruction is found, return NULL. */ | |
291 | ||
292 | const struct bpf_opcode *bpf_match_insn (bpf_insn_word word, | |
293 | enum bpf_endian endian, | |
294 | int version); | |
295 | ||
296 | /* Operand extractors. | |
297 | ||
298 | These all get big-endian instruction words. Note how the extractor | |
299 | for 64-bit signed immediates requires two instruction words. */ | |
300 | ||
301 | uint8_t bpf_extract_src (bpf_insn_word word, enum bpf_endian endian); | |
302 | uint8_t bpf_extract_dst (bpf_insn_word word, enum bpf_endian endian); | |
303 | int16_t bpf_extract_offset16 (bpf_insn_word word, enum bpf_endian endian); | |
304 | int32_t bpf_extract_imm32 (bpf_insn_word word, enum bpf_endian endian); | |
305 | int64_t bpf_extract_imm64 (bpf_insn_word word1, bpf_insn_word word2, | |
306 | enum bpf_endian endian); | |
307 | ||
308 | /* Get the opcode occupying the INDEX position in the opcodes table. | |
309 | The INDEX is zero based. If the provided index overflows the | |
310 | opcodes table then NULL is returned. */ | |
311 | ||
312 | const struct bpf_opcode *bpf_get_opcode (unsigned int index); | |
313 | ||
314 | #endif /* !_BPF_H_ */ |