diff options
author | Jose E. Marchesi <jose.marchesi@oracle.com> | 2023-07-17 18:35:22 +0200 |
---|---|---|
committer | Jose E. Marchesi <jose.marchesi@oracle.com> | 2023-07-21 12:40:50 +0200 |
commit | 7bb9f0c2be98d6c8853e3a0bf992f49c5422bf3e (patch) | |
tree | 8113ef4868964ecbc001b765842a81db29922df3 /sim/bpf/bpf.c | |
parent | d218e7fedc74d67837d2134120917f4ac877454c (diff) | |
download | binutils-7bb9f0c2be98d6c8853e3a0bf992f49c5422bf3e.zip binutils-7bb9f0c2be98d6c8853e3a0bf992f49c5422bf3e.tar.gz binutils-7bb9f0c2be98d6c8853e3a0bf992f49c5422bf3e.tar.bz2 |
sim/bpf: desCGENization of the BPF simulator
The BPF port in binutils has been rewritten (commit
d218e7fedc74d67837d2134120917f4ac877454c) in order to not be longer
based on CGEN. Please see that commit log for more information.
This patch updates the BPF simulator accordingly. The new
implementation is much simpler and it is based on the new BPF opcodes.
Tested with target bpf-unknown-none with both 64-bit little-endian
host and 32-bit little-endian host.
Note that I have not tested in a big-endian host yet. I will do so
once this lands upstream so I can use the GCC compiler farm.
Diffstat (limited to 'sim/bpf/bpf.c')
-rw-r--r-- | sim/bpf/bpf.c | 329 |
1 files changed, 0 insertions, 329 deletions
diff --git a/sim/bpf/bpf.c b/sim/bpf/bpf.c deleted file mode 100644 index 212952a..0000000 --- a/sim/bpf/bpf.c +++ /dev/null @@ -1,329 +0,0 @@ -/* eBPF simulator support code - Copyright (C) 2020-2023 Free Software Foundation, Inc. - - This file is part of GDB, the GNU debugger. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. */ - -/* This must come before any other includes. */ -#include "defs.h" - -#define WANT_CPU_BPFBF -#define WANT_CPU bpfbf - -#include "sim-main.h" -#include "sim-fpu.h" -#include "sim-signal.h" -#include "cgen-mem.h" -#include "cgen-ops.h" -#include "cpuall.h" -#include "decode.h" - -#include "decode-be.h" -#include "decode-le.h" - -#include "defs-le.h" /* For SCACHE */ -#include "bpf-helpers.h" - -uint64_t skb_data_offset; - -IDESC *bpf_idesc_le; -IDESC *bpf_idesc_be; - - -int -bpfbf_fetch_register (SIM_CPU *current_cpu, - int rn, - void *buf, - int len) -{ - if (rn == 11) - SETTDI (buf, CPU_PC_GET (current_cpu)); - else if (0 <= rn && rn < 10) - SETTDI (buf, GET_H_GPR (rn)); - else - return 0; - - return len; -} - -int -bpfbf_store_register (SIM_CPU *current_cpu, - int rn, - const void *buf, - int len) -{ - if (rn == 11) - CPU_PC_SET (current_cpu, GETTDI (buf)); - else if (0 <= rn && rn < 10) - SET_H_GPR (rn, GETTDI (buf)); - else - return 0; - - return len; -} - -void -bpfbf_model_insn_before (SIM_CPU *current_cpu, int first_p) -{ - /* XXX */ -} - -void -bpfbf_model_insn_after (SIM_CPU *current_cpu, int first_p, int cycles) -{ - /* XXX */ -} - - -/***** Instruction helpers. *****/ - -/* The semantic routines for most instructions are expressed in RTL in - the cpu/bpf.cpu file, and automatically translated to C in the - sem-*.c files in this directory. - - However, some of the semantic routines make use of helper C - functions. This happens when the semantics of the instructions - can't be expressed in RTL alone in a satisfactory way, or not at - all. - - The following functions implement these C helpers. */ - -DI -bpfbf_endle (SIM_CPU *current_cpu, DI value, UINT bitsize) -{ - switch (bitsize) - { - case 16: return endian_h2le_2(endian_t2h_2(value)); - case 32: return endian_h2le_4(endian_t2h_4(value)); - case 64: return endian_h2le_8(endian_t2h_8(value)); - default: assert(0); - } - return value; -} - -DI -bpfbf_endbe (SIM_CPU *current_cpu, DI value, UINT bitsize) -{ - switch (bitsize) - { - case 16: return endian_h2be_2(endian_t2h_2(value)); - case 32: return endian_h2be_4(endian_t2h_4(value)); - case 64: return endian_h2be_8(endian_t2h_8(value)); - default: assert(0); - } - return value; -} - -DI -bpfbf_skb_data_offset (SIM_CPU *current_cpu) -{ - /* Simply return the user-configured value. - This will be 0 if it has not been set. */ - return skb_data_offset; -} - - -VOID -bpfbf_call (SIM_CPU *current_cpu, INT disp32, UINT src) -{ - /* eBPF supports two kind of CALL instructions: the so called pseudo - calls ("bpf to bpf") and external calls ("bpf to helper"). - - Both kind of calls use the same instruction (CALL). However, - external calls are constructed by passing a constant argument to - the instruction, that identifies the helper, whereas pseudo calls - result from expressions involving symbols. - - We distinguish calls from pseudo-calls with the later having a 1 - stored in the SRC field of the instruction. */ - - if (src == 1) - { - /* This is a pseudo-call. */ - - /* XXX allocate a new stack frame and transfer control. For - that we need to analyze the target function, like the kernel - verifier does. We better populate a cache - (function_start_address -> frame_size) so we avoid - calculating this more than once. */ - /* XXX note that disp32 is PC-relative in number of 64-bit - words, _minus one_. */ - } - else - { - /* This is a call to a helper. - - DISP32 contains the helper number. Dispatch to the - corresponding helper emulator in bpf-helpers.c. */ - - switch (disp32) { - /* case TRACE_PRINTK: */ - case 7: - bpf_trace_printk (current_cpu); - break; - default:; - } - } -} - -VOID -bpfbf_exit (SIM_CPU *current_cpu) -{ - SIM_DESC sd = CPU_STATE (current_cpu); - - /* r0 holds "return code" */ - DI r0 = GET_H_GPR (0); - - printf ("exit %" PRId64 " (0x%" PRIx64 ")\n", r0, r0); - - sim_engine_halt (sd, current_cpu, NULL, CPU_PC_GET (current_cpu), - sim_exited, 0 /* sigrc */); -} - -VOID -bpfbf_breakpoint (SIM_CPU *current_cpu) -{ - SIM_DESC sd = CPU_STATE (current_cpu); - - sim_engine_halt (sd, current_cpu, NULL, CPU_PC_GET (current_cpu), - sim_stopped, SIM_SIGTRAP); -} - -/* We use the definitions below instead of the cgen-generated model.c, - because the later is not really able to work with cpus featuring - several ISAs. This should be fixed in CGEN. */ - -static void -bpf_def_model_init (SIM_CPU *cpu) -{ - /* Do nothing. */ -} - -static void -bpfbf_prepare_run (SIM_CPU *cpu) -{ - /* Nothing. */ -} - -static void -bpf_engine_run_full (SIM_CPU *cpu) -{ - if (CURRENT_TARGET_BYTE_ORDER == BFD_ENDIAN_LITTLE) - { - if (!bpf_idesc_le) - { - bpfbf_ebpfle_init_idesc_table (cpu); - bpf_idesc_le = CPU_IDESC (cpu); - } - else - CPU_IDESC (cpu) = bpf_idesc_le; - - bpfbf_ebpfle_engine_run_full (cpu); - } - else - { - if (!bpf_idesc_be) - { - bpfbf_ebpfbe_init_idesc_table (cpu); - bpf_idesc_be = CPU_IDESC (cpu); - } - else - CPU_IDESC (cpu) = bpf_idesc_be; - - bpfbf_ebpfbe_engine_run_full (cpu); - } -} - -#if WITH_FAST - -void -bpf_engine_run_fast (SIM_CPU *cpu) -{ - if (CURRENT_TARGET_BYTE_ORDER == BFD_ENDIAN_LITTLE) - { - if (!bpf_idesc_le) - { - bpfbf_ebpfle_init_idesc_table (cpu); - bpf_idesc_le = CPU_IDESC (cpu); - } - else - CPU_IDESC (cpu) = bpf_idesc_le; - - bpfbf_ebpfle_engine_run_fast (cpu); - } - else - { - if (!bpf_idesc_be) - { - bpfbf_ebpfbe_init_idesc_table (cpu); - bpf_idesc_be = CPU_IDESC (cpu); - } - else - CPU_IDESC (cpu) = bpf_idesc_be; - - bpfbf_ebpfbe_engine_run_fast (cpu); - } -} - -#endif /* WITH_FAST */ - -static const CGEN_INSN * -bpfbf_get_idata (SIM_CPU *cpu, int inum) -{ - return CPU_IDESC (cpu) [inum].idata; -} - -static void -bpf_init_cpu (SIM_CPU *cpu) -{ - CPU_REG_FETCH (cpu) = bpfbf_fetch_register; - CPU_REG_STORE (cpu) = bpfbf_store_register; - CPU_PC_FETCH (cpu) = bpfbf_h_pc_get; - CPU_PC_STORE (cpu) = bpfbf_h_pc_set; - CPU_GET_IDATA (cpu) = bpfbf_get_idata; - /* Only used by profiling. 0 disables it. */ - CPU_MAX_INSNS (cpu) = 0; - CPU_INSN_NAME (cpu) = cgen_insn_name; - CPU_FULL_ENGINE_FN (cpu) = bpf_engine_run_full; -#if WITH_FAST - CPU_FAST_ENGINE_FN (cpu) = bpf_engine_run_fast; -#else - CPU_FAST_ENGINE_FN (cpu) = bpf_engine_run_full; -#endif -} - -static const SIM_MODEL bpf_models[] = -{ - { "bpf-def", & bpf_mach, MODEL_BPF_DEF, NULL, bpf_def_model_init }, - { 0 } -}; - -static const SIM_MACH_IMP_PROPERTIES bpfbf_imp_properties = -{ - sizeof (SIM_CPU), -#if WITH_SCACHE - sizeof (SCACHE) -#else - 0 -#endif -}; - -const SIM_MACH bpf_mach = -{ - "bpf", "bpf", MACH_BPF, - 32, 32, & bpf_models[0], & bpfbf_imp_properties, - bpf_init_cpu, - bpfbf_prepare_run -}; |