17d62b00eSchristos /* Target-dependent code for BPF. 27d62b00eSchristos 3*6881a400Schristos Copyright (C) 2020-2023 Free Software Foundation, Inc. 47d62b00eSchristos 57d62b00eSchristos This file is part of GDB. 67d62b00eSchristos 77d62b00eSchristos This program is free software; you can redistribute it and/or modify 87d62b00eSchristos it under the terms of the GNU General Public License as published by 97d62b00eSchristos the Free Software Foundation; either version 3 of the License, or 107d62b00eSchristos (at your option) any later version. 117d62b00eSchristos 127d62b00eSchristos This program is distributed in the hope that it will be useful, 137d62b00eSchristos but WITHOUT ANY WARRANTY; without even the implied warranty of 147d62b00eSchristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 157d62b00eSchristos GNU General Public License for more details. 167d62b00eSchristos 177d62b00eSchristos You should have received a copy of the GNU General Public License 187d62b00eSchristos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 197d62b00eSchristos 207d62b00eSchristos #include "defs.h" 217d62b00eSchristos #include "arch-utils.h" 227d62b00eSchristos #include "dis-asm.h" 237d62b00eSchristos #include "frame.h" 247d62b00eSchristos #include "frame-unwind.h" 257d62b00eSchristos #include "trad-frame.h" 267d62b00eSchristos #include "symtab.h" 277d62b00eSchristos #include "value.h" 287d62b00eSchristos #include "gdbcmd.h" 297d62b00eSchristos #include "breakpoint.h" 307d62b00eSchristos #include "inferior.h" 317d62b00eSchristos #include "regcache.h" 327d62b00eSchristos #include "target.h" 337d62b00eSchristos #include "dwarf2/frame.h" 347d62b00eSchristos #include "osabi.h" 357d62b00eSchristos #include "target-descriptions.h" 367d62b00eSchristos #include "remote.h" 37*6881a400Schristos #include "gdbarch.h" 387d62b00eSchristos 397d62b00eSchristos 407d62b00eSchristos /* eBPF registers. */ 417d62b00eSchristos 427d62b00eSchristos enum bpf_regnum 437d62b00eSchristos { 447d62b00eSchristos BPF_R0_REGNUM, /* return value */ 457d62b00eSchristos BPF_R1_REGNUM, 467d62b00eSchristos BPF_R2_REGNUM, 477d62b00eSchristos BPF_R3_REGNUM, 487d62b00eSchristos BPF_R4_REGNUM, 497d62b00eSchristos BPF_R5_REGNUM, 507d62b00eSchristos BPF_R6_REGNUM, 517d62b00eSchristos BPF_R7_REGNUM, 527d62b00eSchristos BPF_R8_REGNUM, 537d62b00eSchristos BPF_R9_REGNUM, 547d62b00eSchristos BPF_R10_REGNUM, /* sp */ 557d62b00eSchristos BPF_PC_REGNUM, 567d62b00eSchristos }; 577d62b00eSchristos 587d62b00eSchristos #define BPF_NUM_REGS (BPF_PC_REGNUM + 1) 597d62b00eSchristos 607d62b00eSchristos /* Target-dependent structure in gdbarch. */ 61*6881a400Schristos struct bpf_gdbarch_tdep : gdbarch_tdep_base 627d62b00eSchristos { 637d62b00eSchristos }; 647d62b00eSchristos 657d62b00eSchristos 667d62b00eSchristos /* Internal debugging facilities. */ 677d62b00eSchristos 687d62b00eSchristos /* When this is set to non-zero debugging information will be 697d62b00eSchristos printed. */ 707d62b00eSchristos 717d62b00eSchristos static unsigned int bpf_debug_flag = 0; 727d62b00eSchristos 737d62b00eSchristos /* The show callback for 'show debug bpf'. */ 747d62b00eSchristos 757d62b00eSchristos static void 767d62b00eSchristos show_bpf_debug (struct ui_file *file, int from_tty, 777d62b00eSchristos struct cmd_list_element *c, const char *value) 787d62b00eSchristos { 79*6881a400Schristos gdb_printf (file, _("Debugging of BPF is %s.\n"), value); 807d62b00eSchristos } 817d62b00eSchristos 827d62b00eSchristos 837d62b00eSchristos /* BPF registers. */ 847d62b00eSchristos 857d62b00eSchristos static const char *bpf_register_names[] = 867d62b00eSchristos { 877d62b00eSchristos "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 887d62b00eSchristos "r8", "r9", "r10", "pc" 897d62b00eSchristos }; 907d62b00eSchristos 917d62b00eSchristos /* Return the name of register REGNUM. */ 927d62b00eSchristos 937d62b00eSchristos static const char * 947d62b00eSchristos bpf_register_name (struct gdbarch *gdbarch, int reg) 957d62b00eSchristos { 96*6881a400Schristos gdb_static_assert (ARRAY_SIZE (bpf_register_names) == BPF_NUM_REGS); 977d62b00eSchristos return bpf_register_names[reg]; 987d62b00eSchristos } 997d62b00eSchristos 1007d62b00eSchristos /* Return the GDB type of register REGNUM. */ 1017d62b00eSchristos 1027d62b00eSchristos static struct type * 1037d62b00eSchristos bpf_register_type (struct gdbarch *gdbarch, int reg) 1047d62b00eSchristos { 1057d62b00eSchristos if (reg == BPF_R10_REGNUM) 1067d62b00eSchristos return builtin_type (gdbarch)->builtin_data_ptr; 1077d62b00eSchristos else if (reg == BPF_PC_REGNUM) 1087d62b00eSchristos return builtin_type (gdbarch)->builtin_func_ptr; 1097d62b00eSchristos return builtin_type (gdbarch)->builtin_int64; 1107d62b00eSchristos } 1117d62b00eSchristos 1127d62b00eSchristos /* Return the GDB register number corresponding to DWARF's REG. */ 1137d62b00eSchristos 1147d62b00eSchristos static int 1157d62b00eSchristos bpf_dwarf2_reg_to_regnum (struct gdbarch *gdbarch, int reg) 1167d62b00eSchristos { 1177d62b00eSchristos if (reg >= 0 && reg < BPF_NUM_REGS) 1187d62b00eSchristos return reg; 1197d62b00eSchristos return -1; 1207d62b00eSchristos } 1217d62b00eSchristos 1227d62b00eSchristos /* Implement the "print_insn" gdbarch method. */ 1237d62b00eSchristos 1247d62b00eSchristos static int 1257d62b00eSchristos bpf_gdb_print_insn (bfd_vma memaddr, disassemble_info *info) 1267d62b00eSchristos { 1277d62b00eSchristos info->symbols = NULL; 1287d62b00eSchristos return default_print_insn (memaddr, info); 1297d62b00eSchristos } 1307d62b00eSchristos 1317d62b00eSchristos 1327d62b00eSchristos /* Return PC of first real instruction of the function starting at 1337d62b00eSchristos START_PC. */ 1347d62b00eSchristos 1357d62b00eSchristos static CORE_ADDR 1367d62b00eSchristos bpf_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc) 1377d62b00eSchristos { 138*6881a400Schristos gdb_printf (gdb_stdlog, 1397d62b00eSchristos "Skipping prologue: start_pc=%s\n", 1407d62b00eSchristos paddress (gdbarch, start_pc)); 1417d62b00eSchristos /* XXX: to be completed. */ 1427d62b00eSchristos return start_pc + 0; 1437d62b00eSchristos } 1447d62b00eSchristos 1457d62b00eSchristos 1467d62b00eSchristos /* Frame unwinder. 1477d62b00eSchristos 1487d62b00eSchristos XXX it is not clear how to unwind in eBPF, since the stack is not 1497d62b00eSchristos guaranteed to be contiguous, and therefore no relative stack 1507d62b00eSchristos addressing can be done in the callee in order to access the 1517d62b00eSchristos caller's stack frame. To explore with xBPF, which will relax this 1527d62b00eSchristos restriction. */ 1537d62b00eSchristos 1547d62b00eSchristos /* Given THIS_FRAME, return its ID. */ 1557d62b00eSchristos 1567d62b00eSchristos static void 157*6881a400Schristos bpf_frame_this_id (frame_info_ptr this_frame, 1587d62b00eSchristos void **this_prologue_cache, 1597d62b00eSchristos struct frame_id *this_id) 1607d62b00eSchristos { 1617d62b00eSchristos /* Note that THIS_ID defaults to the outermost frame if we don't set 1627d62b00eSchristos anything here. See frame.c:compute_frame_id. */ 1637d62b00eSchristos } 1647d62b00eSchristos 1657d62b00eSchristos /* Return the reason why we can't unwind past THIS_FRAME. */ 1667d62b00eSchristos 1677d62b00eSchristos static enum unwind_stop_reason 168*6881a400Schristos bpf_frame_unwind_stop_reason (frame_info_ptr this_frame, 1697d62b00eSchristos void **this_cache) 1707d62b00eSchristos { 1717d62b00eSchristos return UNWIND_OUTERMOST; 1727d62b00eSchristos } 1737d62b00eSchristos 1747d62b00eSchristos /* Ask THIS_FRAME to unwind its register. */ 1757d62b00eSchristos 1767d62b00eSchristos static struct value * 177*6881a400Schristos bpf_frame_prev_register (frame_info_ptr this_frame, 1787d62b00eSchristos void **this_prologue_cache, int regnum) 1797d62b00eSchristos { 1807d62b00eSchristos return frame_unwind_got_register (this_frame, regnum, regnum); 1817d62b00eSchristos } 1827d62b00eSchristos 1837d62b00eSchristos /* Frame unwinder machinery for BPF. */ 1847d62b00eSchristos 1857d62b00eSchristos static const struct frame_unwind bpf_frame_unwind = 1867d62b00eSchristos { 187*6881a400Schristos "bpf prologue", 1887d62b00eSchristos NORMAL_FRAME, 1897d62b00eSchristos bpf_frame_unwind_stop_reason, 1907d62b00eSchristos bpf_frame_this_id, 1917d62b00eSchristos bpf_frame_prev_register, 1927d62b00eSchristos NULL, 1937d62b00eSchristos default_frame_sniffer 1947d62b00eSchristos }; 1957d62b00eSchristos 1967d62b00eSchristos 1977d62b00eSchristos /* Breakpoints. */ 1987d62b00eSchristos 1997d62b00eSchristos /* Enum describing the different kinds of breakpoints. We currently 2007d62b00eSchristos just support one, implemented by the brkpt xbpf instruction. */ 2017d62b00eSchristos 2027d62b00eSchristos enum bpf_breakpoint_kinds 2037d62b00eSchristos { 2047d62b00eSchristos BPF_BP_KIND_BRKPT = 0, 2057d62b00eSchristos }; 2067d62b00eSchristos 2077d62b00eSchristos /* Implement the breakpoint_kind_from_pc gdbarch method. */ 2087d62b00eSchristos 2097d62b00eSchristos static int 2107d62b00eSchristos bpf_breakpoint_kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *start_pc) 2117d62b00eSchristos { 2127d62b00eSchristos /* We support just one kind of breakpoint. */ 2137d62b00eSchristos return BPF_BP_KIND_BRKPT; 2147d62b00eSchristos } 2157d62b00eSchristos 2167d62b00eSchristos /* Implement the sw_breakpoint_from_kind gdbarch method. */ 2177d62b00eSchristos 2187d62b00eSchristos static const gdb_byte * 2197d62b00eSchristos bpf_sw_breakpoint_from_kind (struct gdbarch *gdbarch, int kind, int *size) 2207d62b00eSchristos { 2217d62b00eSchristos static unsigned char brkpt_insn[] 2227d62b00eSchristos = {0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 2237d62b00eSchristos 2247d62b00eSchristos switch (kind) 2257d62b00eSchristos { 2267d62b00eSchristos case BPF_BP_KIND_BRKPT: 2277d62b00eSchristos *size = 8; 2287d62b00eSchristos return brkpt_insn; 2297d62b00eSchristos default: 2307d62b00eSchristos gdb_assert_not_reached ("unexpected BPF breakpoint kind"); 2317d62b00eSchristos } 2327d62b00eSchristos } 2337d62b00eSchristos 2347d62b00eSchristos 2357d62b00eSchristos /* Assuming THIS_FRAME is a dummy frame, return its frame ID. */ 2367d62b00eSchristos 2377d62b00eSchristos static struct frame_id 238*6881a400Schristos bpf_dummy_id (struct gdbarch *gdbarch, frame_info_ptr this_frame) 2397d62b00eSchristos { 2407d62b00eSchristos CORE_ADDR sp = get_frame_register_unsigned (this_frame, 2417d62b00eSchristos gdbarch_sp_regnum (gdbarch)); 2427d62b00eSchristos return frame_id_build (sp, get_frame_pc (this_frame)); 2437d62b00eSchristos } 2447d62b00eSchristos 2457d62b00eSchristos /* Implement the push dummy call gdbarch callback. */ 2467d62b00eSchristos 2477d62b00eSchristos static CORE_ADDR 2487d62b00eSchristos bpf_push_dummy_call (struct gdbarch *gdbarch, struct value *function, 2497d62b00eSchristos struct regcache *regcache, CORE_ADDR bp_addr, 2507d62b00eSchristos int nargs, struct value **args, CORE_ADDR sp, 2517d62b00eSchristos function_call_return_method return_method, 2527d62b00eSchristos CORE_ADDR struct_addr) 2537d62b00eSchristos { 254*6881a400Schristos gdb_printf (gdb_stdlog, "Pushing dummy call: sp=%s\n", 2557d62b00eSchristos paddress (gdbarch, sp)); 2567d62b00eSchristos /* XXX writeme */ 2577d62b00eSchristos return sp; 2587d62b00eSchristos } 2597d62b00eSchristos 2607d62b00eSchristos /* Extract a function return value of TYPE from REGCACHE, 2617d62b00eSchristos and copy it into VALBUF. */ 2627d62b00eSchristos 2637d62b00eSchristos static void 2647d62b00eSchristos bpf_extract_return_value (struct type *type, struct regcache *regcache, 2657d62b00eSchristos gdb_byte *valbuf) 2667d62b00eSchristos { 267*6881a400Schristos int len = type->length (); 2687d62b00eSchristos gdb_byte vbuf[8]; 2697d62b00eSchristos 2707d62b00eSchristos gdb_assert (len <= 8); 2717d62b00eSchristos regcache->cooked_read (BPF_R0_REGNUM, vbuf); 2727d62b00eSchristos memcpy (valbuf, vbuf + 8 - len, len); 2737d62b00eSchristos } 2747d62b00eSchristos 2757d62b00eSchristos /* Store the function return value of type TYPE from VALBUF into REGNAME. */ 2767d62b00eSchristos 2777d62b00eSchristos static void 2787d62b00eSchristos bpf_store_return_value (struct type *type, struct regcache *regcache, 2797d62b00eSchristos const gdb_byte *valbuf) 2807d62b00eSchristos { 281*6881a400Schristos int len = type->length (); 2827d62b00eSchristos gdb_byte vbuf[8]; 2837d62b00eSchristos 2847d62b00eSchristos gdb_assert (len <= 8); 2857d62b00eSchristos memset (vbuf, 0, sizeof (vbuf)); 2867d62b00eSchristos memcpy (vbuf + 8 - len, valbuf, len); 2877d62b00eSchristos regcache->cooked_write (BPF_R0_REGNUM, vbuf); 2887d62b00eSchristos } 2897d62b00eSchristos 2907d62b00eSchristos /* Handle function's return value. */ 2917d62b00eSchristos 2927d62b00eSchristos static enum return_value_convention 2937d62b00eSchristos bpf_return_value (struct gdbarch *gdbarch, struct value *function, 2947d62b00eSchristos struct type *type, struct regcache *regcache, 2957d62b00eSchristos gdb_byte *readbuf, const gdb_byte *writebuf) 2967d62b00eSchristos { 297*6881a400Schristos int len = type->length (); 2987d62b00eSchristos 2997d62b00eSchristos if (len > 8) 3007d62b00eSchristos return RETURN_VALUE_STRUCT_CONVENTION; 3017d62b00eSchristos 3027d62b00eSchristos if (readbuf != NULL) 3037d62b00eSchristos bpf_extract_return_value (type, regcache, readbuf); 3047d62b00eSchristos if (writebuf != NULL) 3057d62b00eSchristos bpf_store_return_value (type, regcache, writebuf); 3067d62b00eSchristos 3077d62b00eSchristos return RETURN_VALUE_REGISTER_CONVENTION; 3087d62b00eSchristos } 3097d62b00eSchristos 3107d62b00eSchristos 3117d62b00eSchristos /* Initialize the current architecture based on INFO. If possible, re-use an 3127d62b00eSchristos architecture from ARCHES, which is a list of architectures already created 3137d62b00eSchristos during this debugging session. */ 3147d62b00eSchristos 3157d62b00eSchristos static struct gdbarch * 3167d62b00eSchristos bpf_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) 3177d62b00eSchristos { 3187d62b00eSchristos /* If there is already a candidate, use it. */ 3197d62b00eSchristos arches = gdbarch_list_lookup_by_info (arches, &info); 3207d62b00eSchristos if (arches != NULL) 3217d62b00eSchristos return arches->gdbarch; 3227d62b00eSchristos 3237d62b00eSchristos /* Allocate space for the new architecture. */ 324*6881a400Schristos bpf_gdbarch_tdep *tdep = new bpf_gdbarch_tdep; 3257d62b00eSchristos struct gdbarch *gdbarch = gdbarch_alloc (&info, tdep); 3267d62b00eSchristos 3277d62b00eSchristos /* Information about registers, etc. */ 3287d62b00eSchristos set_gdbarch_num_regs (gdbarch, BPF_NUM_REGS); 3297d62b00eSchristos set_gdbarch_register_name (gdbarch, bpf_register_name); 3307d62b00eSchristos set_gdbarch_register_type (gdbarch, bpf_register_type); 3317d62b00eSchristos 3327d62b00eSchristos /* Register numbers of various important registers. */ 3337d62b00eSchristos set_gdbarch_sp_regnum (gdbarch, BPF_R10_REGNUM); 3347d62b00eSchristos set_gdbarch_pc_regnum (gdbarch, BPF_PC_REGNUM); 3357d62b00eSchristos 3367d62b00eSchristos /* Map DWARF2 registers to GDB registers. */ 3377d62b00eSchristos set_gdbarch_dwarf2_reg_to_regnum (gdbarch, bpf_dwarf2_reg_to_regnum); 3387d62b00eSchristos 3397d62b00eSchristos /* Call dummy code. */ 3407d62b00eSchristos set_gdbarch_call_dummy_location (gdbarch, ON_STACK); 3417d62b00eSchristos set_gdbarch_dummy_id (gdbarch, bpf_dummy_id); 3427d62b00eSchristos set_gdbarch_push_dummy_call (gdbarch, bpf_push_dummy_call); 3437d62b00eSchristos 3447d62b00eSchristos /* Returning results. */ 3457d62b00eSchristos set_gdbarch_return_value (gdbarch, bpf_return_value); 3467d62b00eSchristos 3477d62b00eSchristos /* Advance PC across function entry code. */ 3487d62b00eSchristos set_gdbarch_skip_prologue (gdbarch, bpf_skip_prologue); 3497d62b00eSchristos 3507d62b00eSchristos /* Stack grows downward. */ 3517d62b00eSchristos set_gdbarch_inner_than (gdbarch, core_addr_lessthan); 3527d62b00eSchristos 3537d62b00eSchristos /* Breakpoint manipulation. */ 3547d62b00eSchristos set_gdbarch_breakpoint_kind_from_pc (gdbarch, bpf_breakpoint_kind_from_pc); 3557d62b00eSchristos set_gdbarch_sw_breakpoint_from_kind (gdbarch, bpf_sw_breakpoint_from_kind); 3567d62b00eSchristos 3577d62b00eSchristos /* Frame handling. */ 3587d62b00eSchristos set_gdbarch_frame_args_skip (gdbarch, 8); 3597d62b00eSchristos 3607d62b00eSchristos /* Disassembly. */ 3617d62b00eSchristos set_gdbarch_print_insn (gdbarch, bpf_gdb_print_insn); 3627d62b00eSchristos 3637d62b00eSchristos /* Hook in ABI-specific overrides, if they have been registered. */ 3647d62b00eSchristos gdbarch_init_osabi (info, gdbarch); 3657d62b00eSchristos 3667d62b00eSchristos /* Install unwinders. */ 3677d62b00eSchristos frame_unwind_append_unwinder (gdbarch, &bpf_frame_unwind); 3687d62b00eSchristos 3697d62b00eSchristos return gdbarch; 3707d62b00eSchristos } 3717d62b00eSchristos 3727d62b00eSchristos void _initialize_bpf_tdep (); 3737d62b00eSchristos void 374*6881a400Schristos _initialize_bpf_tdep () 3757d62b00eSchristos { 376*6881a400Schristos gdbarch_register (bfd_arch_bpf, bpf_gdbarch_init); 3777d62b00eSchristos 3787d62b00eSchristos /* Add commands 'set/show debug bpf'. */ 3797d62b00eSchristos add_setshow_zuinteger_cmd ("bpf", class_maintenance, 3807d62b00eSchristos &bpf_debug_flag, 3817d62b00eSchristos _("Set BPF debugging."), 3827d62b00eSchristos _("Show BPF debugging."), 3837d62b00eSchristos _("Enables BPF specific debugging output."), 3847d62b00eSchristos NULL, 3857d62b00eSchristos &show_bpf_debug, 3867d62b00eSchristos &setdebuglist, &showdebuglist); 3877d62b00eSchristos } 388