xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/bpf-tdep.c (revision 6881a4007f077b54e5f51159c52b9b25f57deb0d)
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