RISC-V: Don't report warnings when linking different privileged spec objects.
[binutils-gdb.git] / sim / bpf / bpf-sim.c
blobc1f103823fb2de7353d86456c656f000a1514539
1 /* Simulator for BPF.
2 Copyright (C) 2020-2024 Free Software Foundation, Inc.
4 Contributed by Oracle Inc.
6 This file is part of GDB, the GNU debugger.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
21 /* This must come before any other includes. */
22 #include "defs.h"
23 #include "libiberty.h"
25 #include "bfd.h"
26 #include "opcode/bpf.h"
27 #include "sim/sim.h"
28 #include "sim-main.h"
29 #include "sim-core.h"
30 #include "sim-base.h"
31 #include "sim-options.h"
32 #include "sim-signal.h"
33 #include "bpf-sim.h"
35 #include <assert.h>
36 #include <stdlib.h>
39 /***** Emulated hardware. *****/
41 /* Registers are 64-bit long.
42 11 general purpose registers, indexed by register number.
43 1 program counter. */
45 typedef uint64_t bpf_reg;
47 bpf_reg bpf_pc;
48 bpf_reg bpf_regs[11];
50 #define BPF_R0 0
51 #define BPF_R1 1
52 #define BPF_R2 2
53 #define BPF_R3 3
54 #define BPF_R4 4
55 #define BPF_R5 5
56 #define BPF_R6 6
57 #define BPF_R7 7
58 #define BPF_R8 8
59 #define BPF_R9 9
60 #define BPF_R10 10
61 #define BPF_FP 10
64 /***** Emulated memory accessors. *****/
66 static uint8_t
67 bpf_read_u8 (SIM_CPU *cpu, bfd_vma address)
69 return sim_core_read_unaligned_1 (cpu, 0, read_map, address);
72 static void
73 bpf_write_u8 (SIM_CPU *cpu, bfd_vma address, uint8_t value)
75 sim_core_write_unaligned_1 (cpu, 0, write_map, address, value);
78 static uint16_t ATTRIBUTE_UNUSED
79 bpf_read_u16 (SIM_CPU *cpu, bfd_vma address)
81 uint16_t val = sim_core_read_unaligned_2 (cpu, 0, read_map, address);
83 if (current_target_byte_order == BFD_ENDIAN_LITTLE)
84 return endian_le2h_2 (val);
85 else
86 return endian_le2h_2 (val);
89 static void
90 bpf_write_u16 (SIM_CPU *cpu, bfd_vma address, uint16_t value)
92 sim_core_write_unaligned_2 (cpu, 0, write_map, address, endian_h2le_2 (value));
95 static uint32_t ATTRIBUTE_UNUSED
96 bpf_read_u32 (SIM_CPU *cpu, bfd_vma address)
98 uint32_t val = sim_core_read_unaligned_4 (cpu, 0, read_map, address);
100 if (current_target_byte_order == BFD_ENDIAN_LITTLE)
101 return endian_le2h_4 (val);
102 else
103 return endian_le2h_4 (val);
106 static void
107 bpf_write_u32 (SIM_CPU *cpu, bfd_vma address, uint32_t value)
109 sim_core_write_unaligned_4 (cpu, 0, write_map, address, endian_h2le_4 (value));
112 static uint64_t ATTRIBUTE_UNUSED
113 bpf_read_u64 (SIM_CPU *cpu, bfd_vma address)
115 uint64_t val = sim_core_read_unaligned_8 (cpu, 0, read_map, address);
117 if (current_target_byte_order == BFD_ENDIAN_LITTLE)
118 return endian_le2h_8 (val);
119 else
120 return endian_le2h_8 (val);
123 static void
124 bpf_write_u64 (SIM_CPU *cpu, bfd_vma address, uint64_t value)
126 sim_core_write_unaligned_8 (cpu, 0, write_map, address, endian_h2le_8 (value));
130 /***** Emulation of the BPF kernel helpers. *****/
132 /* BPF programs rely on the existence of several helper functions,
133 which are provided by the kernel. This simulator provides an
134 implementation of the helpers, which can be customized by the
135 user. */
137 /* bpf_trace_printk is a printk-like facility for debugging.
139 In the kernel, it appends a line to the Linux's tracing debugging
140 interface.
142 In this simulator, it uses the simulator's tracing interface
143 instead.
145 The format tags recognized by this helper are:
146 %d, %i, %u, %x, %ld, %li, %lu, %lx, %lld, %lli, %llu, %llx,
147 %p, %s
149 A maximum of three tags are supported.
151 This helper returns the number of bytes written, or a negative
152 value in case of failure. */
154 static int
155 bpf_trace_printk (SIM_CPU *cpu)
157 SIM_DESC sd = CPU_STATE (cpu);
159 bfd_vma fmt_address;
160 uint32_t size, tags_processed;
161 size_t i, bytes_written = 0;
163 /* The first argument is the format string, which is passed as a
164 pointer in %r1. */
165 fmt_address = bpf_regs[BPF_R1];
167 /* The second argument is the length of the format string, as an
168 unsigned 32-bit number in %r2. */
169 size = bpf_regs[BPF_R2];
171 /* Read the format string from the memory pointed by %r2, printing
172 out the stuff as we go. There is a maximum of three format tags
173 supported, which are read from %r3, %r4 and %r5 respectively. */
174 for (i = 0, tags_processed = 0; i < size;)
176 uint64_t value;
177 uint8_t c = bpf_read_u8 (cpu, fmt_address + i);
179 switch (c)
181 case '%':
182 /* Check we are not exceeding the limit of three format
183 tags. */
184 if (tags_processed > 2)
185 return -1; /* XXX look for kernel error code. */
187 /* Depending on the kind of tag, extract the value from the
188 proper argument. */
189 if (i++ >= size)
190 return -1; /* XXX look for kernel error code. */
192 value = bpf_regs[BPF_R3 + tags_processed];
194 switch ((bpf_read_u8 (cpu, fmt_address + i)))
196 case 'd':
197 trace_printf (sd, cpu, "%d", (int) value);
198 break;
199 case 'i':
200 trace_printf (sd, cpu, "%i", (int) value);
201 break;
202 case 'u':
203 trace_printf (sd, cpu, "%u", (unsigned int) value);
204 break;
205 case 'x':
206 trace_printf (sd, cpu, "%x", (unsigned int) value);
207 break;
208 case 'l':
210 if (i++ >= size)
211 return -1;
212 switch (bpf_read_u8 (cpu, fmt_address + i))
214 case 'd':
215 trace_printf (sd, cpu, "%ld", (long) value);
216 break;
217 case 'i':
218 trace_printf (sd, cpu, "%li", (long) value);
219 break;
220 case 'u':
221 trace_printf (sd, cpu, "%lu", (unsigned long) value);
222 break;
223 case 'x':
224 trace_printf (sd, cpu, "%lx", (unsigned long) value);
225 break;
226 case 'l':
228 if (i++ >= size)
229 return -1;
230 switch (bpf_read_u8 (cpu, fmt_address + i))
232 case 'd':
233 trace_printf (sd, cpu, "%lld", (long long) value);
234 break;
235 case 'i':
236 trace_printf (sd, cpu, "%lli", (long long) value);
237 break;
238 case 'u':
239 trace_printf (sd, cpu, "%llu", (unsigned long long) value);
240 break;
241 case 'x':
242 trace_printf (sd, cpu, "%llx", (unsigned long long) value);
243 break;
244 default:
245 assert (0);
246 break;
248 break;
250 default:
251 assert (0);
252 break;
254 break;
256 default:
257 /* XXX completeme */
258 assert (0);
259 break;
262 tags_processed++;
263 i++;
264 break;
265 case '\0':
266 i = size;
267 break;
268 default:
269 trace_printf (sd, cpu, "%c", c);
270 bytes_written++;
271 i++;
272 break;
276 return bytes_written;
280 /****** Accessors to install in the CPU description. ******/
282 static int
283 bpf_reg_get (SIM_CPU *cpu, int rn, void *buf, int length)
285 bpf_reg val;
286 unsigned char *memory = buf;
288 if (length != 8 || rn >= 11)
289 return 0;
291 val = bpf_regs[rn];
293 if (current_target_byte_order == BFD_ENDIAN_LITTLE)
295 memory[7] = (val >> 56) & 0xff;
296 memory[6] = (val >> 48) & 0xff;
297 memory[5] = (val >> 40) & 0xff;
298 memory[4] = (val >> 32) & 0xff;
299 memory[3] = (val >> 24) & 0xff;
300 memory[2] = (val >> 16) & 0xff;
301 memory[1] = (val >> 8) & 0xff;
302 memory[0] = val & 0xff;
304 else
306 memory[0] = (val >> 56) & 0xff;
307 memory[1] = (val >> 48) & 0xff;
308 memory[2] = (val >> 40) & 0xff;
309 memory[3] = (val >> 32) & 0xff;
310 memory[4] = (val >> 24) & 0xff;
311 memory[5] = (val >> 16) & 0xff;
312 memory[6] = (val >> 8) & 0xff;
313 memory[7] = val & 0xff;
316 return 8;
319 static int
320 bpf_reg_set (SIM_CPU *cpu, int rn, const void *buf, int length)
322 const unsigned char *memory = buf;
324 if (length != 8 || rn >= 11)
325 return 0;
327 if (current_target_byte_order == BFD_ENDIAN_LITTLE)
328 bpf_regs[rn] = (((uint64_t) memory[7] << 56)
329 | ((uint64_t) memory[6] << 48)
330 | ((uint64_t) memory[5] << 40)
331 | ((uint64_t) memory[4] << 32)
332 | ((uint64_t) memory[3] << 24)
333 | ((uint64_t) memory[2] << 16)
334 | ((uint64_t) memory[1] << 8)
335 | ((uint64_t) memory[0]));
336 else
337 bpf_regs[rn] = (((uint64_t) memory[0] << 56)
338 | ((uint64_t) memory[1] << 48)
339 | ((uint64_t) memory[2] << 40)
340 | ((uint64_t) memory[3] << 32)
341 | ((uint64_t) memory[4] << 24)
342 | ((uint64_t) memory[5] << 16)
343 | ((uint64_t) memory[6] << 8)
344 | ((uint64_t) memory[7]));
345 return 8;
348 static sim_cia
349 bpf_pc_get (sim_cpu *cpu)
351 return bpf_pc;
354 static void
355 bpf_pc_set (sim_cpu *cpu, sim_cia pc)
357 bpf_pc = pc;
361 /***** Other global state. ******/
363 static int64_t skb_data_offset;
365 /* String with the name of the section containing the BPF program to
366 run. */
367 static char *bpf_program_section = NULL;
370 /***** Handle BPF-specific command line options. *****/
372 static SIM_RC bpf_option_handler (SIM_DESC, sim_cpu *, int, char *, int);
374 typedef enum
376 OPTION_BPF_SET_PROGRAM = OPTION_START,
377 OPTION_BPF_LIST_PROGRAMS,
378 OPTION_BPF_VERIFY_PROGRAM,
379 OPTION_BPF_SKB_DATA_OFFSET,
380 } BPF_OPTION;
382 static const OPTION bpf_options[] =
384 { {"bpf-set-program", required_argument, NULL, OPTION_BPF_SET_PROGRAM},
385 '\0', "SECTION_NAME", "Set the entry point",
386 bpf_option_handler },
387 { {"bpf-list-programs", no_argument, NULL, OPTION_BPF_LIST_PROGRAMS},
388 '\0', "", "List loaded bpf programs",
389 bpf_option_handler },
390 { {"bpf-verify-program", required_argument, NULL, OPTION_BPF_VERIFY_PROGRAM},
391 '\0', "PROGRAM", "Run the verifier on the given BPF program",
392 bpf_option_handler },
393 { {"skb-data-offset", required_argument, NULL, OPTION_BPF_SKB_DATA_OFFSET},
394 '\0', "OFFSET", "Configure offsetof(struct sk_buff, data)",
395 bpf_option_handler },
397 { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL, NULL }
400 static SIM_RC
401 bpf_option_handler (SIM_DESC sd, sim_cpu *cpu ATTRIBUTE_UNUSED, int opt,
402 char *arg, int is_command ATTRIBUTE_UNUSED)
404 switch ((BPF_OPTION) opt)
406 case OPTION_BPF_VERIFY_PROGRAM:
407 /* XXX call the verifier. */
408 sim_io_printf (sd, "Verifying BPF program %s...\n", arg);
409 break;
411 case OPTION_BPF_LIST_PROGRAMS:
412 /* XXX list programs. */
413 sim_io_printf (sd, "BPF programs available:\n");
414 break;
416 case OPTION_BPF_SET_PROGRAM:
417 /* XXX: check that the section exists and tell the user about a
418 new start_address. */
419 bpf_program_section = xstrdup (arg);
420 break;
422 case OPTION_BPF_SKB_DATA_OFFSET:
423 skb_data_offset = strtoul (arg, NULL, 0);
424 break;
426 default:
427 sim_io_eprintf (sd, "Unknown option `%s'\n", arg);
428 return SIM_RC_FAIL;
431 return SIM_RC_OK;
435 /***** Instruction decoding. *****/
437 /* Decoded BPF instruction. */
439 struct bpf_insn
441 enum bpf_insn_id id;
442 int size; /* Instruction size in bytes. */
443 bpf_reg dst;
444 bpf_reg src;
445 int16_t offset16;
446 int32_t imm32;
447 int64_t imm64;
450 /* Read an instruction word at the given PC. Note that we need to
451 return a big-endian word. */
453 static bpf_insn_word
454 bpf_read_insn_word (SIM_CPU *cpu, uint64_t pc)
456 bpf_insn_word word = sim_core_read_unaligned_8 (cpu, 0, read_map, pc);
458 if (current_target_byte_order == BFD_ENDIAN_LITTLE)
459 word = endian_le2h_8 (word);
460 else
461 word = endian_be2h_8 (word);
463 return endian_h2be_8 (word);
466 /* Decode and return a BPF instruction at the given PC. Return 0 if
467 no valid instruction is found, 1 otherwise. */
469 static int ATTRIBUTE_UNUSED
470 decode (SIM_CPU *cpu, uint64_t pc, struct bpf_insn *insn)
472 const struct bpf_opcode *opcode;
473 bpf_insn_word word;
474 const char *p;
475 enum bpf_endian endian
476 = (current_target_byte_order == BFD_ENDIAN_LITTLE
477 ? BPF_ENDIAN_LITTLE : BPF_ENDIAN_BIG);
479 /* Initialize the insn struct. */
480 memset (insn, 0, sizeof (struct bpf_insn));
482 /* Read a 64-bit instruction word at PC. */
483 word = bpf_read_insn_word (cpu, pc);
485 /* See if it is a valid instruction and get the opcodes. */
486 opcode = bpf_match_insn (word, endian, BPF_V4);
487 if (!opcode)
488 return 0;
490 insn->id = opcode->id;
491 insn->size = 8;
493 /* Extract operands using the instruction as a guide. */
494 for (p = opcode->normal; *p != '\0';)
496 if (*p == '%')
498 if (*(p + 1) == '%')
499 p += 2;
500 else if (strncmp (p, "%dr", 3) == 0)
502 insn->dst = bpf_extract_dst (word, endian);
503 p += 3;
505 else if (strncmp (p, "%sr", 3) == 0)
507 insn->src = bpf_extract_src (word, endian);
508 p += 3;
510 else if (strncmp (p, "%dw", 3) == 0)
512 insn->dst = bpf_extract_dst (word, endian);
513 p += 3;
515 else if (strncmp (p, "%sw", 3) == 0)
517 insn->src = bpf_extract_src (word, endian);
518 p += 3;
520 else if (strncmp (p, "%i32", 4) == 0
521 || strncmp (p, "%d32", 4) == 0)
524 insn->imm32 = bpf_extract_imm32 (word, endian);
525 p += 4;
527 else if (strncmp (p, "%o16", 4) == 0
528 || strncmp (p, "%d16", 4) == 0)
530 insn->offset16 = bpf_extract_offset16 (word, endian);
531 p += 4;
533 else if (strncmp (p, "%i64", 4) == 0)
535 bpf_insn_word word2;
536 /* XXX PC + 8 */
537 word2 = bpf_read_insn_word (cpu, pc + 8);
538 insn->imm64 = bpf_extract_imm64 (word, word2, endian);
539 insn->size = 16;
540 p += 4;
542 else if (strncmp (p, "%w", 2) == 0
543 || strncmp (p, "%W", 2) == 0)
545 /* Ignore these templates. */
546 p += 2;
548 else
549 /* Malformed opcode template. */
550 /* XXX ignore unknown tags? */
551 assert (0);
553 else
554 p += 1;
557 return 1;
561 /***** Instruction semantics. *****/
563 static void
564 bpf_call (SIM_CPU *cpu, int32_t disp32, uint8_t src)
566 /* eBPF supports two kind of CALL instructions: the so called pseudo
567 calls ("bpf to bpf") and external calls ("bpf to helper").
569 Both kind of calls use the same instruction (CALL). However,
570 external calls are constructed by passing a constant argument to
571 the instruction, that identifies the helper, whereas pseudo calls
572 result from expressions involving symbols.
574 We distinguish calls from pseudo-calls with the later having a 1
575 stored in the SRC field of the instruction. */
577 if (src == 1)
579 /* This is a pseudo-call. */
581 /* XXX allocate a new stack frame and transfer control. For
582 that we need to analyze the target function, like the kernel
583 verifier does. We better populate a cache
584 (function_start_address -> frame_size) so we avoid
585 calculating this more than once. But it is easier to just
586 allocate the maximum stack size per stack frame? */
587 /* XXX note that disp32 is PC-relative in number of 64-bit
588 words, _minus one_. */
590 else
592 /* This is a call to a helper.
593 DISP32 contains the helper number. */
595 switch (disp32) {
596 /* case TRACE_PRINTK: */
597 case 7:
598 bpf_trace_printk (cpu);
599 break;
600 default:;
605 static int
606 execute (SIM_CPU *cpu, struct bpf_insn *insn)
608 uint64_t next_pc = bpf_pc + insn->size;
610 /* Displacements in instructions are encoded in number of 64-bit
611 words _minus one_, and not in bytes. */
612 #define DISP(OFFSET) (((OFFSET) + 1) * 8)
614 /* For debugging. */
615 #define BPF_TRACE(STR) \
616 do \
618 if (0) \
619 printf ("%s", (STR)); \
621 while (0)
623 switch (insn->id)
625 /* Instruction to trap to GDB. */
626 case BPF_INSN_BRKPT:
627 BPF_TRACE ("BPF_INSN_BRKPT\n");
628 sim_engine_halt (CPU_STATE (cpu), cpu,
629 NULL, bpf_pc, sim_stopped, SIM_SIGTRAP);
630 break;
631 /* ALU instructions. */
632 case BPF_INSN_ADDR:
633 BPF_TRACE ("BPF_INSN_ADDR\n");
634 bpf_regs[insn->dst] += bpf_regs[insn->src];
635 break;
636 case BPF_INSN_ADDI:
637 BPF_TRACE ("BPF_INSN_ADDI\n");
638 bpf_regs[insn->dst] += insn->imm32;
639 break;
640 case BPF_INSN_SUBR:
641 BPF_TRACE ("BPF_INSN_SUBR\n");
642 bpf_regs[insn->dst] -= bpf_regs[insn->src];
643 break;
644 case BPF_INSN_SUBI:
645 BPF_TRACE ("BPF_INSN_SUBI\n");
646 bpf_regs[insn->dst] -= insn->imm32;
647 break;
648 case BPF_INSN_MULR:
649 BPF_TRACE ("BPF_INSN_MULR\n");
650 bpf_regs[insn->dst] *= bpf_regs[insn->src];
651 break;
652 case BPF_INSN_MULI:
653 BPF_TRACE ("BPF_INSN_MULI\n");
654 bpf_regs[insn->dst] *= insn->imm32;
655 break;
656 case BPF_INSN_DIVR:
657 BPF_TRACE ("BPF_INSN_DIVR\n");
658 if (bpf_regs[insn->src] == 0)
659 sim_engine_halt (CPU_STATE (cpu), cpu, NULL, bpf_pc, sim_signalled, SIM_SIGFPE);
660 bpf_regs[insn->dst] /= bpf_regs[insn->src];
661 break;
662 case BPF_INSN_DIVI:
663 BPF_TRACE ("BPF_INSN_DIVI\n");
664 if (insn->imm32 == 0)
665 sim_engine_halt (CPU_STATE (cpu), cpu, NULL, bpf_pc, sim_signalled, SIM_SIGFPE);
666 bpf_regs[insn->dst] /= insn->imm32;
667 break;
668 case BPF_INSN_MODR:
669 BPF_TRACE ("BPF_INSN_MODR\n");
670 if (bpf_regs[insn->src] == 0)
671 sim_engine_halt (CPU_STATE (cpu), cpu, NULL, bpf_pc, sim_signalled, SIM_SIGFPE);
672 bpf_regs[insn->dst] %= bpf_regs[insn->src];
673 break;
674 case BPF_INSN_MODI:
675 BPF_TRACE ("BPF_INSN_MODI\n");
676 if (insn->imm32 == 0)
677 sim_engine_halt (CPU_STATE (cpu), cpu, NULL, bpf_pc, sim_signalled, SIM_SIGFPE);
678 bpf_regs[insn->dst] %= insn->imm32;
679 break;
680 case BPF_INSN_ORR:
681 BPF_TRACE ("BPF_INSN_ORR\n");
682 bpf_regs[insn->dst] |= bpf_regs[insn->src];
683 break;
684 case BPF_INSN_ORI:
685 BPF_TRACE ("BPF_INSN_ORI\n");
686 bpf_regs[insn->dst] |= insn->imm32;
687 break;
688 case BPF_INSN_ANDR:
689 BPF_TRACE ("BPF_INSN_ANDR\n");
690 bpf_regs[insn->dst] &= bpf_regs[insn->src];
691 break;
692 case BPF_INSN_ANDI:
693 BPF_TRACE ("BPF_INSN_ANDI\n");
694 bpf_regs[insn->dst] &= insn->imm32;
695 break;
696 case BPF_INSN_XORR:
697 BPF_TRACE ("BPF_INSN_XORR\n");
698 bpf_regs[insn->dst] ^= bpf_regs[insn->src];
699 break;
700 case BPF_INSN_XORI:
701 BPF_TRACE ("BPF_INSN_XORI\n");
702 bpf_regs[insn->dst] ^= insn->imm32;
703 break;
704 case BPF_INSN_SDIVR:
705 BPF_TRACE ("BPF_INSN_SDIVR\n");
706 if (bpf_regs[insn->src] == 0)
707 sim_engine_halt (CPU_STATE (cpu), cpu, NULL, bpf_pc, sim_signalled, SIM_SIGFPE);
708 bpf_regs[insn->dst] = (int64_t) bpf_regs[insn->dst] / (int64_t) bpf_regs[insn->src];
709 break;
710 case BPF_INSN_SDIVI:
711 BPF_TRACE ("BPF_INSN_SDIVI\n");
712 if (insn->imm32 == 0)
713 sim_engine_halt (CPU_STATE (cpu), cpu, NULL, bpf_pc, sim_signalled, SIM_SIGFPE);
714 bpf_regs[insn->dst] = (int64_t) bpf_regs[insn->dst] / (int64_t) insn->imm32;
715 break;
716 case BPF_INSN_SMODR:
717 BPF_TRACE ("BPF_INSN_SMODR\n");
718 if (bpf_regs[insn->src] == 0)
719 sim_engine_halt (CPU_STATE (cpu), cpu, NULL, bpf_pc, sim_signalled, SIM_SIGFPE);
720 bpf_regs[insn->dst] = (int64_t) bpf_regs[insn->dst] % (int64_t) bpf_regs[insn->src];
721 break;
722 case BPF_INSN_SMODI:
723 BPF_TRACE ("BPF_INSN_SMODI\n");
724 if (insn->imm32 == 0)
725 sim_engine_halt (CPU_STATE (cpu), cpu, NULL, bpf_pc, sim_signalled, SIM_SIGFPE);
726 bpf_regs[insn->dst] = (int64_t) bpf_regs[insn->dst] % (int64_t) insn->imm32;
727 break;
728 case BPF_INSN_NEGR:
729 BPF_TRACE ("BPF_INSN_NEGR\n");
730 bpf_regs[insn->dst] = - (int64_t) bpf_regs[insn->dst];
731 break;
732 case BPF_INSN_LSHR:
733 BPF_TRACE ("BPF_INSN_LSHR\n");
734 bpf_regs[insn->dst] <<= bpf_regs[insn->src];
735 break;
736 case BPF_INSN_LSHI:
737 BPF_TRACE ("BPF_INSN_LSHI\n");
738 bpf_regs[insn->dst] <<= insn->imm32;
739 break;
740 case BPF_INSN_RSHR:
741 BPF_TRACE ("BPF_INSN_RSHR\n");
742 bpf_regs[insn->dst] >>= bpf_regs[insn->src];
743 break;
744 case BPF_INSN_RSHI:
745 BPF_TRACE ("BPF_INSN_RSHI\n");
746 bpf_regs[insn->dst] >>= insn->imm32;
747 break;
748 case BPF_INSN_ARSHR:
749 BPF_TRACE ("BPF_INSN_ARSHR\n");
750 bpf_regs[insn->dst] = (int64_t) bpf_regs[insn->dst] >> bpf_regs[insn->src];
751 break;
752 case BPF_INSN_ARSHI:
753 BPF_TRACE ("BPF_INSN_ARSHI\n");
754 bpf_regs[insn->dst] = (int64_t) bpf_regs[insn->dst] >> insn->imm32;
755 break;
756 case BPF_INSN_MOVR:
757 BPF_TRACE ("BPF_INSN_MOVR\n");
758 bpf_regs[insn->dst] = bpf_regs[insn->src];
759 break;
760 case BPF_INSN_MOVI:
761 BPF_TRACE ("BPF_INSN_MOVI\n");
762 bpf_regs[insn->dst] = insn->imm32;
763 break;
764 /* ALU32 instructions. */
765 case BPF_INSN_ADD32R:
766 BPF_TRACE ("BPF_INSN_ADD32R\n");
767 bpf_regs[insn->dst] = (int32_t) bpf_regs[insn->dst] + (int32_t) bpf_regs[insn->src];
768 break;
769 case BPF_INSN_ADD32I:
770 BPF_TRACE ("BPF_INSN_ADD32I\n");
771 bpf_regs[insn->dst] = (int32_t) bpf_regs[insn->dst] + insn->imm32;
772 break;
773 case BPF_INSN_SUB32R:
774 BPF_TRACE ("BPF_INSN_SUB32R\n");
775 bpf_regs[insn->dst] = (int32_t) bpf_regs[insn->dst] - (int32_t) bpf_regs[insn->src];
776 break;
777 case BPF_INSN_SUB32I:
778 BPF_TRACE ("BPF_INSN_SUB32I\n");
779 bpf_regs[insn->dst] = (int32_t) bpf_regs[insn->dst] - insn->imm32;
780 break;
781 case BPF_INSN_MUL32R:
782 BPF_TRACE ("BPF_INSN_MUL32R\n");
783 bpf_regs[insn->dst] = (int32_t) bpf_regs[insn->dst] * (int32_t) bpf_regs[insn->src];
784 break;
785 case BPF_INSN_MUL32I:
786 BPF_TRACE ("BPF_INSN_MUL32I\n");
787 bpf_regs[insn->dst] = (int32_t) bpf_regs[insn->dst] * (int32_t) insn->imm32;
788 break;
789 case BPF_INSN_DIV32R:
790 BPF_TRACE ("BPF_INSN_DIV32R\n");
791 if (bpf_regs[insn->src] == 0)
792 sim_engine_halt (CPU_STATE (cpu), cpu, NULL, bpf_pc, sim_signalled, SIM_SIGFPE);
793 bpf_regs[insn->dst] = (uint32_t) bpf_regs[insn->dst] / (uint32_t) bpf_regs[insn->src];
794 break;
795 case BPF_INSN_DIV32I:
796 BPF_TRACE ("BPF_INSN_DIV32I\n");
797 if (insn->imm32 == 0)
798 sim_engine_halt (CPU_STATE (cpu), cpu, NULL, bpf_pc, sim_signalled, SIM_SIGFPE);
799 bpf_regs[insn->dst] = (uint32_t) bpf_regs[insn->dst] / (uint32_t) insn->imm32;
800 break;
801 case BPF_INSN_MOD32R:
802 BPF_TRACE ("BPF_INSN_MOD32R\n");
803 if (bpf_regs[insn->src] == 0)
804 sim_engine_halt (CPU_STATE (cpu), cpu, NULL, bpf_pc, sim_signalled, SIM_SIGFPE);
805 bpf_regs[insn->dst] = (uint32_t) bpf_regs[insn->dst] % (uint32_t) bpf_regs[insn->src];
806 break;
807 case BPF_INSN_MOD32I:
808 BPF_TRACE ("BPF_INSN_MOD32I\n");
809 if (insn->imm32 == 0)
810 sim_engine_halt (CPU_STATE (cpu), cpu, NULL, bpf_pc, sim_signalled, SIM_SIGFPE);
811 bpf_regs[insn->dst] = (uint32_t) bpf_regs[insn->dst] % (uint32_t) insn->imm32;
812 break;
813 case BPF_INSN_OR32R:
814 BPF_TRACE ("BPF_INSN_OR32R\n");
815 bpf_regs[insn->dst] = (uint32_t) bpf_regs[insn->dst] | (int32_t) bpf_regs[insn->src];
816 break;
817 case BPF_INSN_OR32I:
818 BPF_TRACE ("BPF_INSN_OR32I\n");
819 bpf_regs[insn->dst] = (uint32_t) bpf_regs[insn->dst] | (int32_t) insn->imm32;
820 break;
821 case BPF_INSN_AND32R:
822 BPF_TRACE ("BPF_INSN_AND32R\n");
823 bpf_regs[insn->dst] = (uint32_t) bpf_regs[insn->dst] & (int32_t) bpf_regs[insn->src];
824 break;
825 case BPF_INSN_AND32I:
826 BPF_TRACE ("BPF_INSN_AND32I\n");
827 bpf_regs[insn->dst] = (uint32_t) bpf_regs[insn->dst] & (int32_t) insn->imm32;
828 break;
829 case BPF_INSN_XOR32R:
830 BPF_TRACE ("BPF_INSN_XOR32R\n");
831 bpf_regs[insn->dst] = (uint32_t) bpf_regs[insn->dst] ^ (int32_t) bpf_regs[insn->src];
832 break;
833 case BPF_INSN_XOR32I:
834 BPF_TRACE ("BPF_INSN_XOR32I\n");
835 bpf_regs[insn->dst] = (uint32_t) bpf_regs[insn->dst] ^ (int32_t) insn->imm32;
836 break;
837 case BPF_INSN_SDIV32R:
838 BPF_TRACE ("BPF_INSN_SDIV32R\n");
839 if (bpf_regs[insn->src] == 0)
840 sim_engine_halt (CPU_STATE (cpu), cpu, NULL, bpf_pc, sim_signalled, SIM_SIGFPE);
841 bpf_regs[insn->dst] = (int32_t) bpf_regs[insn->dst] / (int32_t) bpf_regs[insn->src];
842 break;
843 case BPF_INSN_SDIV32I:
844 BPF_TRACE ("BPF_INSN_SDIV32I\n");
845 if (insn->imm32 == 0)
846 sim_engine_halt (CPU_STATE (cpu), cpu, NULL, bpf_pc, sim_signalled, SIM_SIGFPE);
847 bpf_regs[insn->dst] = (int32_t) bpf_regs[insn->dst] / (int32_t) insn->imm32;
848 break;
849 case BPF_INSN_SMOD32R:
850 BPF_TRACE ("BPF_INSN_SMOD32R\n");
851 if (bpf_regs[insn->src] == 0)
852 sim_engine_halt (CPU_STATE (cpu), cpu, NULL, bpf_pc, sim_signalled, SIM_SIGFPE);
853 bpf_regs[insn->dst] = (int32_t) bpf_regs[insn->dst] % (int32_t) bpf_regs[insn->src];
854 break;
855 case BPF_INSN_SMOD32I:
856 BPF_TRACE ("BPF_INSN_SMOD32I\n");
857 if (insn->imm32 == 0)
858 sim_engine_halt (CPU_STATE (cpu), cpu, NULL, bpf_pc, sim_signalled, SIM_SIGFPE);
859 bpf_regs[insn->dst] = (int32_t) bpf_regs[insn->dst] % (int32_t) insn->imm32;
860 break;
861 case BPF_INSN_NEG32R:
862 BPF_TRACE ("BPF_INSN_NEG32R\n");
863 bpf_regs[insn->dst] = (uint32_t) (- (int32_t) bpf_regs[insn->dst]);
864 break;
865 case BPF_INSN_LSH32R:
866 BPF_TRACE ("BPF_INSN_LSH32R\n");
867 bpf_regs[insn->dst] = (uint32_t) bpf_regs[insn->dst] << bpf_regs[insn->src];
868 break;
869 case BPF_INSN_LSH32I:
870 BPF_TRACE ("BPF_INSN_LSH32I\n");
871 bpf_regs[insn->dst] = (uint32_t) bpf_regs[insn->dst] << insn->imm32;
872 break;
873 case BPF_INSN_RSH32R:
874 BPF_TRACE ("BPF_INSN_RSH32R\n");
875 bpf_regs[insn->dst] = (uint32_t) bpf_regs[insn->dst] >> bpf_regs[insn->src];
876 break;
877 case BPF_INSN_RSH32I:
878 BPF_TRACE ("BPF_INSN_RSH32I\n");
879 bpf_regs[insn->dst] = (uint32_t) bpf_regs[insn->dst] >> insn->imm32;
880 break;
881 case BPF_INSN_ARSH32R:
882 BPF_TRACE ("BPF_INSN_ARSH32R\n");
883 bpf_regs[insn->dst] = (uint32_t)((int32_t)(uint32_t) bpf_regs[insn->dst] >> bpf_regs[insn->src]);
884 break;
885 case BPF_INSN_ARSH32I:
886 BPF_TRACE ("BPF_INSN_ARSH32I\n");
887 bpf_regs[insn->dst] = (uint32_t)((int32_t)(uint32_t) bpf_regs[insn->dst] >> insn->imm32);
888 break;
889 case BPF_INSN_MOV32R:
890 BPF_TRACE ("BPF_INSN_MOV32R\n");
891 bpf_regs[insn->dst] = (uint32_t) bpf_regs[insn->src];
892 break;
893 case BPF_INSN_MOV32I:
894 BPF_TRACE ("BPF_INSN_MOV32I\n");
895 bpf_regs[insn->dst] = (uint32_t) insn->imm32;
896 break;
897 /* Endianness conversion instructions. */
898 case BPF_INSN_ENDLE16:
899 BPF_TRACE ("BPF_INSN_ENDLE16\n");
900 bpf_regs[insn->dst] = endian_h2le_2 (endian_t2h_2 (bpf_regs[insn->dst]));
901 break;
902 case BPF_INSN_ENDLE32:
903 BPF_TRACE ("BPF_INSN_ENDLE32\n");
904 bpf_regs[insn->dst] = endian_h2le_4 (endian_t2h_4 (bpf_regs[insn->dst]));
905 break;
906 case BPF_INSN_ENDLE64:
907 BPF_TRACE ("BPF_INSN_ENDLE64\n");
908 bpf_regs[insn->dst] = endian_h2le_8 (endian_t2h_8 (bpf_regs[insn->dst]));
909 break;
910 case BPF_INSN_ENDBE16:
911 BPF_TRACE ("BPF_INSN_ENDBE16\n");
912 bpf_regs[insn->dst] = endian_h2be_2 (endian_t2h_2 (bpf_regs[insn->dst]));
913 break;
914 case BPF_INSN_ENDBE32:
915 BPF_TRACE ("BPF_INSN_ENDBE32\n");
916 bpf_regs[insn->dst] = endian_h2be_4 (endian_t2h_4 (bpf_regs[insn->dst]));
917 break;
918 case BPF_INSN_ENDBE64:
919 BPF_TRACE ("BPF_INSN_ENDBE64\n");
920 bpf_regs[insn->dst] = endian_h2be_8 (endian_t2h_8 (bpf_regs[insn->dst]));
921 break;
922 /* 64-bit load instruction. */
923 case BPF_INSN_LDDW:
924 BPF_TRACE ("BPF_INSN_LDDW\n");
925 bpf_regs[insn->dst] = insn->imm64;
926 break;
927 /* Indirect load instructions. */
928 case BPF_INSN_LDINDB:
929 BPF_TRACE ("BPF_INSN_LDINDB\n");
930 bpf_regs[BPF_R0] = bpf_read_u8 (cpu,
931 bpf_read_u64 (cpu, bpf_regs[BPF_R6] + skb_data_offset)
932 + bpf_regs[insn->src] + insn->imm32);
933 break;
934 case BPF_INSN_LDINDH:
935 BPF_TRACE ("BPF_INSN_LDINDH\n");
936 bpf_regs[BPF_R0] = bpf_read_u16 (cpu,
937 bpf_read_u64 (cpu, bpf_regs[BPF_R6] + skb_data_offset)
938 + bpf_regs[insn->src] + insn->imm32);
939 break;
940 case BPF_INSN_LDINDW:
941 BPF_TRACE ("BPF_INSN_LDINDW\n");
942 bpf_regs[BPF_R0] = bpf_read_u32 (cpu,
943 bpf_read_u64 (cpu, bpf_regs[BPF_R6] + skb_data_offset)
944 + bpf_regs[insn->src] + insn->imm32);
945 break;
946 case BPF_INSN_LDABSB:
947 BPF_TRACE ("BPF_INSN_LDABSB\n");
948 bpf_regs[BPF_R0] = bpf_read_u8 (cpu,
949 bpf_read_u64 (cpu, bpf_regs[BPF_R6] + skb_data_offset)
950 + insn->imm32);
951 break;
952 case BPF_INSN_LDABSH:
953 BPF_TRACE ("BPF_INSN_LDABSH\n");
954 bpf_regs[BPF_R0] = bpf_read_u16 (cpu,
955 bpf_read_u64 (cpu, bpf_regs[BPF_R6] + skb_data_offset)
956 + insn->imm32);
957 break;
958 case BPF_INSN_LDABSW:
959 BPF_TRACE ("BPF_INSN_LDABSW\n");
960 bpf_regs[BPF_R0] = bpf_read_u32 (cpu,
961 bpf_read_u64 (cpu, bpf_regs[BPF_R6] + skb_data_offset)
962 + insn->imm32);
963 break;
964 /* Generic load instructions (to register.) */
965 case BPF_INSN_LDXB:
966 BPF_TRACE ("BPF_INSN_LDXB\n");
967 bpf_regs[insn->dst] = (int8_t) bpf_read_u8 (cpu,
968 bpf_regs[insn->src] + insn->offset16);
969 break;
970 case BPF_INSN_LDXH:
971 BPF_TRACE ("BPF_INSN_LDXH\n");
972 bpf_regs[insn->dst] = (int16_t) bpf_read_u16 (cpu,
973 bpf_regs[insn->src] + insn->offset16);
974 break;
975 case BPF_INSN_LDXW:
976 BPF_TRACE ("BPF_INSN_LDXW\n");
977 bpf_regs[insn->dst] = (int32_t) bpf_read_u32 (cpu,
978 bpf_regs[insn->src] + insn->offset16);
979 break;
980 case BPF_INSN_LDXDW:
981 BPF_TRACE ("BPF_INSN_LDXDW\n");
982 bpf_regs[insn->dst] = bpf_read_u64 (cpu,
983 bpf_regs[insn->src] + insn->offset16);
984 break;
985 /* Generic store instructions (from register.) */
986 case BPF_INSN_STXBR:
987 BPF_TRACE ("BPF_INSN_STXBR\n");
988 bpf_write_u8 (cpu,
989 bpf_regs[insn->dst] + insn->offset16,
990 bpf_regs[insn->src]);
991 break;
992 case BPF_INSN_STXHR:
993 BPF_TRACE ("BPF_INSN_STXHR\n");
994 bpf_write_u16 (cpu,
995 bpf_regs[insn->dst] + insn->offset16,
996 bpf_regs[insn->src]);
997 break;
998 case BPF_INSN_STXWR:
999 BPF_TRACE ("BPF_INSN_STXWR\n");
1000 bpf_write_u32 (cpu,
1001 bpf_regs[insn->dst] + insn->offset16,
1002 bpf_regs[insn->src]);
1003 break;
1004 case BPF_INSN_STXDWR:
1005 BPF_TRACE ("BPF_INSN_STXDWR\n");
1006 bpf_write_u64 (cpu,
1007 bpf_regs[insn->dst] + insn->offset16,
1008 bpf_regs[insn->src]);
1009 break;
1010 /* Generic store instructions (from 32-bit immediate.) */
1011 case BPF_INSN_STXBI:
1012 BPF_TRACE ("BPF_INSN_STXBI\n");
1013 bpf_write_u8 (cpu,
1014 bpf_regs[insn->dst] + insn->offset16,
1015 insn->imm32);
1016 break;
1017 case BPF_INSN_STXHI:
1018 BPF_TRACE ("BPF_INSN_STXHI\n");
1019 bpf_write_u16 (cpu,
1020 bpf_regs[insn->dst] + insn->offset16,
1021 insn->imm32);
1022 break;
1023 case BPF_INSN_STXWI:
1024 BPF_TRACE ("BPF_INSN_STXWI\n");
1025 bpf_write_u32 (cpu,
1026 bpf_regs[insn->dst] + insn->offset16,
1027 insn->imm32);
1028 break;
1029 case BPF_INSN_STXDWI:
1030 BPF_TRACE ("BPF_INSN_STXDWI\n");
1031 bpf_write_u64 (cpu,
1032 bpf_regs[insn->dst] + insn->offset16,
1033 insn->imm32);
1034 break;
1035 /* Compare-and-jump instructions (reg OP reg). */
1036 case BPF_INSN_JAR:
1037 BPF_TRACE ("BPF_INSN_JAR\n");
1038 next_pc = bpf_pc + DISP (insn->offset16);
1039 break;
1040 case BPF_INSN_JEQR:
1041 BPF_TRACE ("BPF_INSN_JEQR\n");
1042 if (bpf_regs[insn->dst] == bpf_regs[insn->src])
1043 next_pc = bpf_pc + DISP (insn->offset16);
1044 break;
1045 case BPF_INSN_JGTR:
1046 BPF_TRACE ("BPF_INSN_JGTR\n");
1047 if (bpf_regs[insn->dst] > bpf_regs[insn->src])
1048 next_pc = bpf_pc + DISP (insn->offset16);
1049 break;
1050 case BPF_INSN_JSGTR:
1051 BPF_TRACE ("BPF_INSN_JSGTR\n");
1052 if ((int64_t) bpf_regs[insn->dst] > (int64_t) bpf_regs[insn->src])
1053 next_pc = bpf_pc + DISP (insn->offset16);
1054 break;
1055 case BPF_INSN_JGER:
1056 BPF_TRACE ("BPF_INSN_JGER\n");
1057 if (bpf_regs[insn->dst] >= bpf_regs[insn->src])
1058 next_pc = bpf_pc + DISP (insn->offset16);
1059 break;
1060 case BPF_INSN_JSGER:
1061 BPF_TRACE ("BPF_INSN_JSGER\n");
1062 if ((int64_t) bpf_regs[insn->dst] >= (int64_t) bpf_regs[insn->src])
1063 next_pc = bpf_pc + DISP (insn->offset16);
1064 break;
1065 case BPF_INSN_JLTR:
1066 BPF_TRACE ("BPF_INSN_JLTR\n");
1067 if (bpf_regs[insn->dst] < bpf_regs[insn->src])
1068 next_pc = bpf_pc + DISP (insn->offset16);
1069 break;
1070 case BPF_INSN_JSLTR:
1071 BPF_TRACE ("BPF_INSN_JSLTR\n");
1072 if ((int64_t) bpf_regs[insn->dst] < (int64_t) bpf_regs[insn->src])
1073 next_pc = bpf_pc + DISP (insn->offset16);
1074 break;
1075 case BPF_INSN_JLER:
1076 BPF_TRACE ("BPF_INSN_JLER\n");
1077 if (bpf_regs[insn->dst] <= bpf_regs[insn->src])
1078 next_pc = bpf_pc + DISP (insn->offset16);
1079 break;
1080 case BPF_INSN_JSLER:
1081 BPF_TRACE ("BPF_INSN_JSLER\n");
1082 if ((int64_t) bpf_regs[insn->dst] <= (int64_t) bpf_regs[insn->src])
1083 next_pc = bpf_pc + DISP (insn->offset16);
1084 break;
1085 case BPF_INSN_JSETR:
1086 BPF_TRACE ("BPF_INSN_JSETR\n");
1087 if (bpf_regs[insn->dst] & bpf_regs[insn->src])
1088 next_pc = bpf_pc + DISP (insn->offset16);
1089 break;
1090 case BPF_INSN_JNER:
1091 BPF_TRACE ("BPF_INSN_JNER\n");
1092 if (bpf_regs[insn->dst] != bpf_regs[insn->src])
1093 next_pc = bpf_pc + DISP (insn->offset16);
1094 break;
1095 case BPF_INSN_CALLR:
1096 BPF_TRACE ("BPF_INSN_CALLR\n");
1097 bpf_call (cpu, DISP (bpf_regs[insn->dst]), insn->src);
1098 break;
1099 case BPF_INSN_CALL:
1100 BPF_TRACE ("BPF_INSN_CALL\n");
1101 bpf_call (cpu, insn->imm32, insn->src);
1102 break;
1103 case BPF_INSN_EXIT:
1104 BPF_TRACE ("BPF_INSN_EXIT\n");
1106 SIM_DESC sd = CPU_STATE (cpu);
1107 printf ("exit %" PRId64 " (0x%" PRIx64 ")\n",
1108 bpf_regs[BPF_R0], bpf_regs[BPF_R0]);
1109 sim_engine_halt (sd, cpu, NULL, bpf_pc,
1110 sim_exited, 0 /* sigrc */);
1111 break;
1113 /* Compare-and-jump instructions (reg OP imm). */
1114 case BPF_INSN_JEQI:
1115 BPF_TRACE ("BPF_INSN_JEQI\n");
1116 if (bpf_regs[insn->dst] == insn->imm32)
1117 next_pc = bpf_pc + DISP (insn->offset16);
1118 break;
1119 case BPF_INSN_JGTI:
1120 BPF_TRACE ("BPF_INSN_JGTI\n");
1121 if (bpf_regs[insn->dst] > insn->imm32)
1122 next_pc = bpf_pc + DISP (insn->offset16);
1123 break;
1124 case BPF_INSN_JSGTI:
1125 BPF_TRACE ("BPF_INSN_JSGTI\n");
1126 if ((int64_t) bpf_regs[insn->dst] > insn->imm32)
1127 next_pc = bpf_pc + DISP (insn->offset16);
1128 break;
1129 case BPF_INSN_JGEI:
1130 BPF_TRACE ("BPF_INSN_JGEI\n");
1131 if (bpf_regs[insn->dst] >= insn->imm32)
1132 next_pc = bpf_pc + DISP (insn->offset16);
1133 break;
1134 case BPF_INSN_JSGEI:
1135 BPF_TRACE ("BPF_INSN_JSGEI\n");
1136 if ((int64_t) bpf_regs[insn->dst] >= (int64_t) insn->imm32)
1137 next_pc = bpf_pc + DISP (insn->offset16);
1138 break;
1139 case BPF_INSN_JLTI:
1140 BPF_TRACE ("BPF_INSN_JLTI\n");
1141 if (bpf_regs[insn->dst] < insn->imm32)
1142 next_pc = bpf_pc + DISP (insn->offset16);
1143 break;
1144 case BPF_INSN_JSLTI:
1145 BPF_TRACE ("BPF_INSN_JSLTI\n");
1146 if ((int64_t) bpf_regs[insn->dst] < (int64_t) insn->imm32)
1147 next_pc = bpf_pc + DISP (insn->offset16);
1148 break;
1149 case BPF_INSN_JLEI:
1150 BPF_TRACE ("BPF_INSN_JLEI\n");
1151 if (bpf_regs[insn->dst] <= insn->imm32)
1152 next_pc = bpf_pc + DISP (insn->offset16);
1153 break;
1154 case BPF_INSN_JSLEI:
1155 BPF_TRACE ("BPF_INSN_JSLEI\n");
1156 if ((int64_t) bpf_regs[insn->dst] <= (int64_t) insn->imm32)
1157 next_pc = bpf_pc + DISP (insn->offset16);
1158 break;
1159 case BPF_INSN_JSETI:
1160 BPF_TRACE ("BPF_INSN_JSETI\n");
1161 if (bpf_regs[insn->dst] & insn->imm32)
1162 next_pc = bpf_pc + DISP (insn->offset16);
1163 break;
1164 case BPF_INSN_JNEI:
1165 BPF_TRACE ("BPF_INSN_JNEI\n");
1166 if (bpf_regs[insn->dst] != insn->imm32)
1167 next_pc = bpf_pc + DISP (insn->offset16);
1168 break;
1169 /* 32-bit compare-and-jump instructions (reg OP reg). */
1170 case BPF_INSN_JEQ32R:
1171 BPF_TRACE ("BPF_INSN_JEQ32R\n");
1172 if ((uint32_t) bpf_regs[insn->dst] == (uint32_t) bpf_regs[insn->src])
1173 next_pc = bpf_pc + DISP (insn->offset16);
1174 break;
1175 case BPF_INSN_JGT32R:
1176 BPF_TRACE ("BPF_INSN_JGT32R\n");
1177 if ((uint32_t) bpf_regs[insn->dst] > (uint32_t) bpf_regs[insn->src])
1178 next_pc = bpf_pc + DISP (insn->offset16);
1179 break;
1180 case BPF_INSN_JSGT32R:
1181 BPF_TRACE ("BPF_INSN_JSGT32R\n");
1182 if ((int32_t) bpf_regs[insn->dst] > (int32_t) bpf_regs[insn->src])
1183 next_pc = bpf_pc + DISP (insn->offset16);
1184 break;
1185 case BPF_INSN_JGE32R:
1186 BPF_TRACE ("BPF_INSN_JGE32R\n");
1187 if ((uint32_t) bpf_regs[insn->dst] >= (uint32_t) bpf_regs[insn->src])
1188 next_pc = bpf_pc + DISP (insn->offset16);
1189 break;
1190 case BPF_INSN_JSGE32R:
1191 BPF_TRACE ("BPF_INSN_JSGE32R\n");
1192 if ((int32_t) bpf_regs[insn->dst] >= (int32_t) bpf_regs[insn->src])
1193 next_pc = bpf_pc + DISP (insn->offset16);
1194 break;
1195 case BPF_INSN_JLT32R:
1196 BPF_TRACE ("BPF_INSN_JLT32R\n");
1197 if ((uint32_t) bpf_regs[insn->dst] < (uint32_t) bpf_regs[insn->src])
1198 next_pc = bpf_pc + DISP (insn->offset16);
1199 break;
1200 case BPF_INSN_JSLT32R:
1201 BPF_TRACE ("BPF_INSN_JSLT32R\n");
1202 if ((int32_t) bpf_regs[insn->dst] < (int32_t) bpf_regs[insn->src])
1203 next_pc = bpf_pc + DISP (insn->offset16);
1204 break;
1205 case BPF_INSN_JLE32R:
1206 BPF_TRACE ("BPF_INSN_JLE32R\n");
1207 if ((uint32_t) bpf_regs[insn->dst] <= (uint32_t) bpf_regs[insn->src])
1208 next_pc = bpf_pc + DISP (insn->offset16);
1209 break;
1210 case BPF_INSN_JSLE32R:
1211 BPF_TRACE ("BPF_INSN_JSLE32R\n");
1212 if ((int32_t) bpf_regs[insn->dst] <= (int32_t) bpf_regs[insn->src])
1213 next_pc = bpf_pc + DISP (insn->offset16);
1214 break;
1215 case BPF_INSN_JSET32R:
1216 BPF_TRACE ("BPF_INSN_JSET32R\n");
1217 if ((uint32_t) bpf_regs[insn->dst] & (uint32_t) bpf_regs[insn->src])
1218 next_pc = bpf_pc + DISP (insn->offset16);
1219 break;
1220 case BPF_INSN_JNE32R:
1221 BPF_TRACE ("BPF_INSN_JNE32R\n");
1222 if ((uint32_t) bpf_regs[insn->dst] != (uint32_t) bpf_regs[insn->src])
1223 next_pc = bpf_pc + DISP (insn->offset16);
1224 break;
1225 /* 32-bit compare-and-jump instructions (reg OP imm). */
1226 case BPF_INSN_JEQ32I:
1227 BPF_TRACE ("BPF_INSN_JEQ32I\n");
1228 if ((uint32_t) bpf_regs[insn->dst] == insn->imm32)
1229 next_pc = bpf_pc + DISP (insn->offset16);
1230 break;
1231 case BPF_INSN_JGT32I:
1232 BPF_TRACE ("BPF_INSN_JGT32I\n");
1233 if ((uint32_t) bpf_regs[insn->dst] > insn->imm32)
1234 next_pc = bpf_pc + DISP (insn->offset16);
1235 break;
1236 case BPF_INSN_JSGT32I:
1237 BPF_TRACE ("BPF_INSN_JSGT32I\n");
1238 if ((int32_t) bpf_regs[insn->dst] > insn->imm32)
1239 next_pc = bpf_pc + DISP (insn->offset16);
1240 break;
1241 case BPF_INSN_JGE32I:
1242 BPF_TRACE ("BPF_INSN_JGE32I\n");
1243 if ((uint32_t) bpf_regs[insn->dst] >= insn->imm32)
1244 next_pc = bpf_pc + DISP (insn->offset16);
1245 break;
1246 case BPF_INSN_JSGE32I:
1247 BPF_TRACE ("BPF_INSN_JSGE32I\n");
1248 if ((int32_t) bpf_regs[insn->dst] >= (int32_t) insn->imm32)
1249 next_pc = bpf_pc + DISP (insn->offset16);
1250 break;
1251 case BPF_INSN_JLT32I:
1252 BPF_TRACE ("BPF_INSN_JLT32I\n");
1253 if ((uint32_t) bpf_regs[insn->dst] < insn->imm32)
1254 next_pc = bpf_pc + DISP (insn->offset16);
1255 break;
1256 case BPF_INSN_JSLT32I:
1257 BPF_TRACE ("BPF_INSN_JSLT32I\n");
1258 if ((int32_t) bpf_regs[insn->dst] < (int32_t) insn->imm32)
1259 next_pc = bpf_pc + DISP (insn->offset16);
1260 break;
1261 case BPF_INSN_JLE32I:
1262 BPF_TRACE ("BPF_INSN_JLE32I\n");
1263 if ((uint32_t) bpf_regs[insn->dst] <= insn->imm32)
1264 next_pc = bpf_pc + DISP (insn->offset16);
1265 break;
1266 case BPF_INSN_JSLE32I:
1267 BPF_TRACE ("BPF_INSN_JSLE32I\n");
1268 if ((int32_t) bpf_regs[insn->dst] <= (int32_t) insn->imm32)
1269 next_pc = bpf_pc + DISP (insn->offset16);
1270 break;
1271 case BPF_INSN_JSET32I:
1272 BPF_TRACE ("BPF_INSN_JSET32I\n");
1273 if ((uint32_t) bpf_regs[insn->dst] & insn->imm32)
1274 next_pc = bpf_pc + DISP (insn->offset16);
1275 break;
1276 case BPF_INSN_JNE32I:
1277 BPF_TRACE ("BPF_INSN_JNE32I\n");
1278 if ((uint32_t) bpf_regs[insn->dst] != insn->imm32)
1279 next_pc = bpf_pc + DISP (insn->offset16);
1280 break;
1281 /* Atomic instructions. */
1282 case BPF_INSN_AADD:
1283 BPF_TRACE ("BPF_INSN_AADD\n");
1284 bpf_write_u64 (cpu,
1285 bpf_regs[insn->dst] + insn->offset16,
1286 bpf_read_u64 (cpu, bpf_regs[insn->dst] + insn->offset16)
1287 + bpf_regs[insn->src]);
1288 break;
1289 case BPF_INSN_AADD32:
1290 BPF_TRACE ("BPF_INSN_AADD32\n");
1291 bpf_write_u32 (cpu,
1292 bpf_regs[insn->dst] + insn->offset16,
1293 (int32_t) bpf_read_u32 (cpu, bpf_regs[insn->dst] + insn->offset16)
1294 + bpf_regs[insn->src]);
1295 break;
1296 /* XXX Atomic instructions with fetching. */
1297 default: /* XXX */
1298 case BPF_NOINSN:
1299 BPF_TRACE ("BPF_NOINSN\n");
1300 return 0;
1301 break;
1304 /* Set new PC. */
1305 bpf_pc = next_pc;
1307 return 1;
1310 /* Entry points. */
1312 SIM_RC
1313 sim_create_inferior (SIM_DESC sd, struct bfd *abfd,
1314 char * const *argv, char * const *env)
1316 SIM_CPU *cpu = STATE_CPU (sd, 0);
1317 bfd_vma addr;
1319 /* Determine the start address.
1321 XXX acknowledge bpf_program_section. If it is NULL, emit a
1322 warning explaining that we are using the ELF file start address,
1323 which often is not what is actually wanted. */
1324 if (abfd != NULL)
1325 addr = bfd_get_start_address (abfd);
1326 else
1327 addr = 0;
1329 sim_pc_set (cpu, addr);
1331 return SIM_RC_OK;
1334 /* Like sim_state_free, but free the cpu buffers as well. */
1336 static void
1337 bpf_free_state (SIM_DESC sd)
1339 if (STATE_MODULES (sd) != NULL)
1340 sim_module_uninstall (sd);
1342 sim_cpu_free_all (sd);
1343 sim_state_free (sd);
1346 /* Create an instance of the simulator. */
1348 SIM_DESC
1349 sim_open (SIM_OPEN_KIND kind, host_callback *cb,
1350 struct bfd *abfd, char * const *argv)
1352 SIM_DESC sd = sim_state_alloc_extra (kind, cb, sizeof (struct bpf_sim_state));
1353 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
1355 /* Set default options before parsing user options. */
1356 current_target_byte_order = BFD_ENDIAN_LITTLE;
1358 if (sim_cpu_alloc_all_extra (sd, 0, sizeof (struct bpf_sim_state)) != SIM_RC_OK)
1359 goto error;
1361 if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
1362 goto error;
1364 /* Add the BPF-specific option list to the simulator. */
1365 if (sim_add_option_table (sd, NULL, bpf_options) != SIM_RC_OK)
1367 bpf_free_state (sd);
1368 return 0;
1371 /* The parser will print an error message for us, so we silently return. */
1372 if (sim_parse_args (sd, argv) != SIM_RC_OK)
1373 goto error;
1375 /* Check for/establish the a reference program image. */
1376 if (sim_analyze_program (sd, STATE_PROG_FILE (sd), abfd) != SIM_RC_OK)
1377 goto error;
1379 /* Configure/verify the target byte order and other runtime
1380 configuration options. */
1381 if (sim_config (sd) != SIM_RC_OK)
1382 goto error;
1384 if (sim_post_argv_init (sd) != SIM_RC_OK)
1385 goto error;
1387 /* Initialize properties of the simulated CPU. */
1389 assert (MAX_NR_PROCESSORS == 1);
1391 SIM_CPU *cpu = STATE_CPU (sd, i);
1393 cpu = STATE_CPU (sd, 0);
1394 CPU_PC_FETCH (cpu) = bpf_pc_get;
1395 CPU_PC_STORE (cpu) = bpf_pc_set;
1396 CPU_REG_FETCH (cpu) = bpf_reg_get;
1397 CPU_REG_STORE (cpu) = bpf_reg_set;
1400 return sd;
1402 error:
1403 bpf_free_state (sd);
1404 return NULL;
1407 void
1408 sim_engine_run (SIM_DESC sd,
1409 int next_cpu_nr ATTRIBUTE_UNUSED,
1410 int nr_cpus ATTRIBUTE_UNUSED,
1411 int siggnal ATTRIBUTE_UNUSED)
1413 SIM_CPU *cpu = STATE_CPU (sd, 0);
1414 struct bpf_insn insn;
1416 while (1)
1418 if (!decode (cpu, bpf_pc, &insn))
1420 sim_io_eprintf (sd, "couldn't decode instruction at PC 0x%" PRIx64 "\n",
1421 bpf_pc);
1422 break;
1425 if (!execute (cpu, &insn))
1427 sim_io_eprintf (sd, "couldn' execute instruction at PC 0x%" PRIx64 "\n",
1428 bpf_pc);
1429 break;