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. */
23 #include "libiberty.h"
26 #include "opcode/bpf.h"
31 #include "sim-options.h"
32 #include "sim-signal.h"
39 /***** Emulated hardware. *****/
41 /* Registers are 64-bit long.
42 11 general purpose registers, indexed by register number.
45 typedef uint64_t bpf_reg
;
64 /***** Emulated memory accessors. *****/
67 bpf_read_u8 (SIM_CPU
*cpu
, bfd_vma address
)
69 return sim_core_read_unaligned_1 (cpu
, 0, read_map
, address
);
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
);
86 return endian_le2h_2 (val
);
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
);
103 return endian_le2h_4 (val
);
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
);
120 return endian_le2h_8 (val
);
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
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
142 In this simulator, it uses the simulator's tracing interface
145 The format tags recognized by this helper are:
146 %d, %i, %u, %x, %ld, %li, %lu, %lx, %lld, %lli, %llu, %llx,
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. */
155 bpf_trace_printk (SIM_CPU
*cpu
)
157 SIM_DESC sd
= CPU_STATE (cpu
);
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
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
;)
177 uint8_t c
= bpf_read_u8 (cpu
, fmt_address
+ i
);
182 /* Check we are not exceeding the limit of three format
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
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
)))
197 trace_printf (sd
, cpu
, "%d", (int) value
);
200 trace_printf (sd
, cpu
, "%i", (int) value
);
203 trace_printf (sd
, cpu
, "%u", (unsigned int) value
);
206 trace_printf (sd
, cpu
, "%x", (unsigned int) value
);
212 switch (bpf_read_u8 (cpu
, fmt_address
+ i
))
215 trace_printf (sd
, cpu
, "%ld", (long) value
);
218 trace_printf (sd
, cpu
, "%li", (long) value
);
221 trace_printf (sd
, cpu
, "%lu", (unsigned long) value
);
224 trace_printf (sd
, cpu
, "%lx", (unsigned long) value
);
230 switch (bpf_read_u8 (cpu
, fmt_address
+ i
))
233 trace_printf (sd
, cpu
, "%lld", (long long) value
);
236 trace_printf (sd
, cpu
, "%lli", (long long) value
);
239 trace_printf (sd
, cpu
, "%llu", (unsigned long long) value
);
242 trace_printf (sd
, cpu
, "%llx", (unsigned long long) value
);
269 trace_printf (sd
, cpu
, "%c", c
);
276 return bytes_written
;
280 /****** Accessors to install in the CPU description. ******/
283 bpf_reg_get (SIM_CPU
*cpu
, int rn
, void *buf
, int length
)
286 unsigned char *memory
= buf
;
288 if (length
!= 8 || rn
>= 11)
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;
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;
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)
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]));
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]));
349 bpf_pc_get (sim_cpu
*cpu
)
355 bpf_pc_set (sim_cpu
*cpu
, sim_cia 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
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);
376 OPTION_BPF_SET_PROGRAM
= OPTION_START
,
377 OPTION_BPF_LIST_PROGRAMS
,
378 OPTION_BPF_VERIFY_PROGRAM
,
379 OPTION_BPF_SKB_DATA_OFFSET
,
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
}
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
);
411 case OPTION_BPF_LIST_PROGRAMS
:
412 /* XXX list programs. */
413 sim_io_printf (sd
, "BPF programs available:\n");
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
);
422 case OPTION_BPF_SKB_DATA_OFFSET
:
423 skb_data_offset
= strtoul (arg
, NULL
, 0);
427 sim_io_eprintf (sd
, "Unknown option `%s'\n", arg
);
435 /***** Instruction decoding. *****/
437 /* Decoded BPF instruction. */
442 int size
; /* Instruction size in bytes. */
450 /* Read an instruction word at the given PC. Note that we need to
451 return a big-endian 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
);
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
;
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
);
490 insn
->id
= opcode
->id
;
493 /* Extract operands using the instruction as a guide. */
494 for (p
= opcode
->normal
; *p
!= '\0';)
500 else if (strncmp (p
, "%dr", 3) == 0)
502 insn
->dst
= bpf_extract_dst (word
, endian
);
505 else if (strncmp (p
, "%sr", 3) == 0)
507 insn
->src
= bpf_extract_src (word
, endian
);
510 else if (strncmp (p
, "%dw", 3) == 0)
512 insn
->dst
= bpf_extract_dst (word
, endian
);
515 else if (strncmp (p
, "%sw", 3) == 0)
517 insn
->src
= bpf_extract_src (word
, endian
);
520 else if (strncmp (p
, "%i32", 4) == 0
521 || strncmp (p
, "%d32", 4) == 0)
524 insn
->imm32
= bpf_extract_imm32 (word
, endian
);
527 else if (strncmp (p
, "%o16", 4) == 0
528 || strncmp (p
, "%d16", 4) == 0)
530 insn
->offset16
= bpf_extract_offset16 (word
, endian
);
533 else if (strncmp (p
, "%i64", 4) == 0)
537 word2
= bpf_read_insn_word (cpu
, pc
+ 8);
538 insn
->imm64
= bpf_extract_imm64 (word
, word2
, endian
);
542 else if (strncmp (p
, "%w", 2) == 0
543 || strncmp (p
, "%W", 2) == 0)
545 /* Ignore these templates. */
549 /* Malformed opcode template. */
550 /* XXX ignore unknown tags? */
561 /***** Instruction semantics. *****/
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. */
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_. */
592 /* This is a call to a helper.
593 DISP32 contains the helper number. */
596 /* case TRACE_PRINTK: */
598 bpf_trace_printk (cpu
);
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)
615 #define BPF_TRACE(STR) \
619 printf ("%s", (STR)); \
625 /* Instruction to trap to GDB. */
627 BPF_TRACE ("BPF_INSN_BRKPT\n");
628 sim_engine_halt (CPU_STATE (cpu
), cpu
,
629 NULL
, bpf_pc
, sim_stopped
, SIM_SIGTRAP
);
631 /* ALU instructions. */
633 BPF_TRACE ("BPF_INSN_ADDR\n");
634 bpf_regs
[insn
->dst
] += bpf_regs
[insn
->src
];
637 BPF_TRACE ("BPF_INSN_ADDI\n");
638 bpf_regs
[insn
->dst
] += insn
->imm32
;
641 BPF_TRACE ("BPF_INSN_SUBR\n");
642 bpf_regs
[insn
->dst
] -= bpf_regs
[insn
->src
];
645 BPF_TRACE ("BPF_INSN_SUBI\n");
646 bpf_regs
[insn
->dst
] -= insn
->imm32
;
649 BPF_TRACE ("BPF_INSN_MULR\n");
650 bpf_regs
[insn
->dst
] *= bpf_regs
[insn
->src
];
653 BPF_TRACE ("BPF_INSN_MULI\n");
654 bpf_regs
[insn
->dst
] *= insn
->imm32
;
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
];
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
;
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
];
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
;
681 BPF_TRACE ("BPF_INSN_ORR\n");
682 bpf_regs
[insn
->dst
] |= bpf_regs
[insn
->src
];
685 BPF_TRACE ("BPF_INSN_ORI\n");
686 bpf_regs
[insn
->dst
] |= insn
->imm32
;
689 BPF_TRACE ("BPF_INSN_ANDR\n");
690 bpf_regs
[insn
->dst
] &= bpf_regs
[insn
->src
];
693 BPF_TRACE ("BPF_INSN_ANDI\n");
694 bpf_regs
[insn
->dst
] &= insn
->imm32
;
697 BPF_TRACE ("BPF_INSN_XORR\n");
698 bpf_regs
[insn
->dst
] ^= bpf_regs
[insn
->src
];
701 BPF_TRACE ("BPF_INSN_XORI\n");
702 bpf_regs
[insn
->dst
] ^= insn
->imm32
;
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
];
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
;
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
];
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
;
729 BPF_TRACE ("BPF_INSN_NEGR\n");
730 bpf_regs
[insn
->dst
] = - (int64_t) bpf_regs
[insn
->dst
];
733 BPF_TRACE ("BPF_INSN_LSHR\n");
734 bpf_regs
[insn
->dst
] <<= bpf_regs
[insn
->src
];
737 BPF_TRACE ("BPF_INSN_LSHI\n");
738 bpf_regs
[insn
->dst
] <<= insn
->imm32
;
741 BPF_TRACE ("BPF_INSN_RSHR\n");
742 bpf_regs
[insn
->dst
] >>= bpf_regs
[insn
->src
];
745 BPF_TRACE ("BPF_INSN_RSHI\n");
746 bpf_regs
[insn
->dst
] >>= insn
->imm32
;
749 BPF_TRACE ("BPF_INSN_ARSHR\n");
750 bpf_regs
[insn
->dst
] = (int64_t) bpf_regs
[insn
->dst
] >> bpf_regs
[insn
->src
];
753 BPF_TRACE ("BPF_INSN_ARSHI\n");
754 bpf_regs
[insn
->dst
] = (int64_t) bpf_regs
[insn
->dst
] >> insn
->imm32
;
757 BPF_TRACE ("BPF_INSN_MOVR\n");
758 bpf_regs
[insn
->dst
] = bpf_regs
[insn
->src
];
761 BPF_TRACE ("BPF_INSN_MOVI\n");
762 bpf_regs
[insn
->dst
] = insn
->imm32
;
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
];
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
;
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
];
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
;
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
];
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
;
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
];
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
;
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
];
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
;
814 BPF_TRACE ("BPF_INSN_OR32R\n");
815 bpf_regs
[insn
->dst
] = (uint32_t) bpf_regs
[insn
->dst
] | (int32_t) bpf_regs
[insn
->src
];
818 BPF_TRACE ("BPF_INSN_OR32I\n");
819 bpf_regs
[insn
->dst
] = (uint32_t) bpf_regs
[insn
->dst
] | (int32_t) insn
->imm32
;
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
];
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
;
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
];
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
;
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
];
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
;
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
];
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
;
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
]);
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
];
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
;
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
];
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
;
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
]);
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
);
889 case BPF_INSN_MOV32R
:
890 BPF_TRACE ("BPF_INSN_MOV32R\n");
891 bpf_regs
[insn
->dst
] = (uint32_t) bpf_regs
[insn
->src
];
893 case BPF_INSN_MOV32I
:
894 BPF_TRACE ("BPF_INSN_MOV32I\n");
895 bpf_regs
[insn
->dst
] = (uint32_t) insn
->imm32
;
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
]));
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
]));
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
]));
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
]));
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
]));
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
]));
922 /* 64-bit load instruction. */
924 BPF_TRACE ("BPF_INSN_LDDW\n");
925 bpf_regs
[insn
->dst
] = insn
->imm64
;
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
);
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
);
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
);
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
)
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
)
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
)
964 /* Generic load instructions (to register.) */
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
);
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
);
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
);
981 BPF_TRACE ("BPF_INSN_LDXDW\n");
982 bpf_regs
[insn
->dst
] = bpf_read_u64 (cpu
,
983 bpf_regs
[insn
->src
] + insn
->offset16
);
985 /* Generic store instructions (from register.) */
987 BPF_TRACE ("BPF_INSN_STXBR\n");
989 bpf_regs
[insn
->dst
] + insn
->offset16
,
990 bpf_regs
[insn
->src
]);
993 BPF_TRACE ("BPF_INSN_STXHR\n");
995 bpf_regs
[insn
->dst
] + insn
->offset16
,
996 bpf_regs
[insn
->src
]);
999 BPF_TRACE ("BPF_INSN_STXWR\n");
1001 bpf_regs
[insn
->dst
] + insn
->offset16
,
1002 bpf_regs
[insn
->src
]);
1004 case BPF_INSN_STXDWR
:
1005 BPF_TRACE ("BPF_INSN_STXDWR\n");
1007 bpf_regs
[insn
->dst
] + insn
->offset16
,
1008 bpf_regs
[insn
->src
]);
1010 /* Generic store instructions (from 32-bit immediate.) */
1011 case BPF_INSN_STXBI
:
1012 BPF_TRACE ("BPF_INSN_STXBI\n");
1014 bpf_regs
[insn
->dst
] + insn
->offset16
,
1017 case BPF_INSN_STXHI
:
1018 BPF_TRACE ("BPF_INSN_STXHI\n");
1020 bpf_regs
[insn
->dst
] + insn
->offset16
,
1023 case BPF_INSN_STXWI
:
1024 BPF_TRACE ("BPF_INSN_STXWI\n");
1026 bpf_regs
[insn
->dst
] + insn
->offset16
,
1029 case BPF_INSN_STXDWI
:
1030 BPF_TRACE ("BPF_INSN_STXDWI\n");
1032 bpf_regs
[insn
->dst
] + insn
->offset16
,
1035 /* Compare-and-jump instructions (reg OP reg). */
1037 BPF_TRACE ("BPF_INSN_JAR\n");
1038 next_pc
= bpf_pc
+ DISP (insn
->offset16
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
1095 case BPF_INSN_CALLR
:
1096 BPF_TRACE ("BPF_INSN_CALLR\n");
1097 bpf_call (cpu
, DISP (bpf_regs
[insn
->dst
]), insn
->src
);
1100 BPF_TRACE ("BPF_INSN_CALL\n");
1101 bpf_call (cpu
, insn
->imm32
, insn
->src
);
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 */);
1113 /* Compare-and-jump instructions (reg OP imm). */
1115 BPF_TRACE ("BPF_INSN_JEQI\n");
1116 if (bpf_regs
[insn
->dst
] == insn
->imm32
)
1117 next_pc
= bpf_pc
+ DISP (insn
->offset16
);
1120 BPF_TRACE ("BPF_INSN_JGTI\n");
1121 if (bpf_regs
[insn
->dst
] > insn
->imm32
)
1122 next_pc
= bpf_pc
+ DISP (insn
->offset16
);
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
);
1130 BPF_TRACE ("BPF_INSN_JGEI\n");
1131 if (bpf_regs
[insn
->dst
] >= insn
->imm32
)
1132 next_pc
= bpf_pc
+ DISP (insn
->offset16
);
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
);
1140 BPF_TRACE ("BPF_INSN_JLTI\n");
1141 if (bpf_regs
[insn
->dst
] < insn
->imm32
)
1142 next_pc
= bpf_pc
+ DISP (insn
->offset16
);
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
);
1150 BPF_TRACE ("BPF_INSN_JLEI\n");
1151 if (bpf_regs
[insn
->dst
] <= insn
->imm32
)
1152 next_pc
= bpf_pc
+ DISP (insn
->offset16
);
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
);
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
);
1165 BPF_TRACE ("BPF_INSN_JNEI\n");
1166 if (bpf_regs
[insn
->dst
] != insn
->imm32
)
1167 next_pc
= bpf_pc
+ DISP (insn
->offset16
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
1281 /* Atomic instructions. */
1283 BPF_TRACE ("BPF_INSN_AADD\n");
1285 bpf_regs
[insn
->dst
] + insn
->offset16
,
1286 bpf_read_u64 (cpu
, bpf_regs
[insn
->dst
] + insn
->offset16
)
1287 + bpf_regs
[insn
->src
]);
1289 case BPF_INSN_AADD32
:
1290 BPF_TRACE ("BPF_INSN_AADD32\n");
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
]);
1296 /* XXX Atomic instructions with fetching. */
1299 BPF_TRACE ("BPF_NOINSN\n");
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);
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. */
1325 addr
= bfd_get_start_address (abfd
);
1329 sim_pc_set (cpu
, addr
);
1334 /* Like sim_state_free, but free the cpu buffers as well. */
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. */
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
)
1361 if (sim_pre_argv_init (sd
, argv
[0]) != SIM_RC_OK
)
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
);
1371 /* The parser will print an error message for us, so we silently return. */
1372 if (sim_parse_args (sd
, argv
) != SIM_RC_OK
)
1375 /* Check for/establish the a reference program image. */
1376 if (sim_analyze_program (sd
, STATE_PROG_FILE (sd
), abfd
) != SIM_RC_OK
)
1379 /* Configure/verify the target byte order and other runtime
1380 configuration options. */
1381 if (sim_config (sd
) != SIM_RC_OK
)
1384 if (sim_post_argv_init (sd
) != SIM_RC_OK
)
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
;
1403 bpf_free_state (sd
);
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
;
1418 if (!decode (cpu
, bpf_pc
, &insn
))
1420 sim_io_eprintf (sd
, "couldn't decode instruction at PC 0x%" PRIx64
"\n",
1425 if (!execute (cpu
, &insn
))
1427 sim_io_eprintf (sd
, "couldn' execute instruction at PC 0x%" PRIx64
"\n",