xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/bpf-tdep.c (revision 6881a4007f077b54e5f51159c52b9b25f57deb0d)
1 /* Target-dependent code for BPF.
2 
3    Copyright (C) 2020-2023 Free Software Foundation, Inc.
4 
5    This file is part of GDB.
6 
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11 
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19 
20 #include "defs.h"
21 #include "arch-utils.h"
22 #include "dis-asm.h"
23 #include "frame.h"
24 #include "frame-unwind.h"
25 #include "trad-frame.h"
26 #include "symtab.h"
27 #include "value.h"
28 #include "gdbcmd.h"
29 #include "breakpoint.h"
30 #include "inferior.h"
31 #include "regcache.h"
32 #include "target.h"
33 #include "dwarf2/frame.h"
34 #include "osabi.h"
35 #include "target-descriptions.h"
36 #include "remote.h"
37 #include "gdbarch.h"
38 
39 
40 /* eBPF registers.  */
41 
42 enum bpf_regnum
43 {
44   BPF_R0_REGNUM,		/* return value */
45   BPF_R1_REGNUM,
46   BPF_R2_REGNUM,
47   BPF_R3_REGNUM,
48   BPF_R4_REGNUM,
49   BPF_R5_REGNUM,
50   BPF_R6_REGNUM,
51   BPF_R7_REGNUM,
52   BPF_R8_REGNUM,
53   BPF_R9_REGNUM,
54   BPF_R10_REGNUM,		/* sp */
55   BPF_PC_REGNUM,
56 };
57 
58 #define BPF_NUM_REGS	(BPF_PC_REGNUM + 1)
59 
60 /* Target-dependent structure in gdbarch.  */
61 struct bpf_gdbarch_tdep : gdbarch_tdep_base
62 {
63 };
64 
65 
66 /* Internal debugging facilities.  */
67 
68 /* When this is set to non-zero debugging information will be
69    printed.  */
70 
71 static unsigned int bpf_debug_flag = 0;
72 
73 /* The show callback for 'show debug bpf'.  */
74 
75 static void
76 show_bpf_debug (struct ui_file *file, int from_tty,
77 		struct cmd_list_element *c, const char *value)
78 {
79   gdb_printf (file, _("Debugging of BPF is %s.\n"), value);
80 }
81 
82 
83 /* BPF registers.  */
84 
85 static const char *bpf_register_names[] =
86 {
87   "r0",   "r1",  "r2",    "r3",   "r4",   "r5",   "r6",   "r7",
88   "r8",   "r9",  "r10",   "pc"
89 };
90 
91 /* Return the name of register REGNUM.  */
92 
93 static const char *
94 bpf_register_name (struct gdbarch *gdbarch, int reg)
95 {
96   gdb_static_assert (ARRAY_SIZE (bpf_register_names) == BPF_NUM_REGS);
97   return bpf_register_names[reg];
98 }
99 
100 /* Return the GDB type of register REGNUM.  */
101 
102 static struct type *
103 bpf_register_type (struct gdbarch *gdbarch, int reg)
104 {
105   if (reg == BPF_R10_REGNUM)
106     return builtin_type (gdbarch)->builtin_data_ptr;
107   else if (reg == BPF_PC_REGNUM)
108     return builtin_type (gdbarch)->builtin_func_ptr;
109   return builtin_type (gdbarch)->builtin_int64;
110 }
111 
112 /* Return the GDB register number corresponding to DWARF's REG.  */
113 
114 static int
115 bpf_dwarf2_reg_to_regnum (struct gdbarch *gdbarch, int reg)
116 {
117   if (reg >= 0 && reg < BPF_NUM_REGS)
118     return reg;
119   return -1;
120 }
121 
122 /* Implement the "print_insn" gdbarch method.  */
123 
124 static int
125 bpf_gdb_print_insn (bfd_vma memaddr, disassemble_info *info)
126 {
127   info->symbols = NULL;
128   return default_print_insn (memaddr, info);
129 }
130 
131 
132 /* Return PC of first real instruction of the function starting at
133    START_PC.  */
134 
135 static CORE_ADDR
136 bpf_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc)
137 {
138   gdb_printf (gdb_stdlog,
139 	      "Skipping prologue: start_pc=%s\n",
140 	      paddress (gdbarch, start_pc));
141   /* XXX: to be completed.  */
142   return start_pc + 0;
143 }
144 
145 
146 /* Frame unwinder.
147 
148    XXX it is not clear how to unwind in eBPF, since the stack is not
149    guaranteed to be contiguous, and therefore no relative stack
150    addressing can be done in the callee in order to access the
151    caller's stack frame.  To explore with xBPF, which will relax this
152    restriction.  */
153 
154 /* Given THIS_FRAME, return its ID.  */
155 
156 static void
157 bpf_frame_this_id (frame_info_ptr this_frame,
158 		   void **this_prologue_cache,
159 		   struct frame_id *this_id)
160 {
161   /* Note that THIS_ID defaults to the outermost frame if we don't set
162      anything here.  See frame.c:compute_frame_id.  */
163 }
164 
165 /* Return the reason why we can't unwind past THIS_FRAME.  */
166 
167 static enum unwind_stop_reason
168 bpf_frame_unwind_stop_reason (frame_info_ptr this_frame,
169 			      void **this_cache)
170 {
171   return UNWIND_OUTERMOST;
172 }
173 
174 /* Ask THIS_FRAME to unwind its register.  */
175 
176 static struct value *
177 bpf_frame_prev_register (frame_info_ptr this_frame,
178 			 void **this_prologue_cache, int regnum)
179 {
180   return frame_unwind_got_register (this_frame, regnum, regnum);
181 }
182 
183 /* Frame unwinder machinery for BPF.  */
184 
185 static const struct frame_unwind bpf_frame_unwind =
186 {
187   "bpf prologue",
188   NORMAL_FRAME,
189   bpf_frame_unwind_stop_reason,
190   bpf_frame_this_id,
191   bpf_frame_prev_register,
192   NULL,
193   default_frame_sniffer
194 };
195 
196 
197 /* Breakpoints.  */
198 
199 /* Enum describing the different kinds of breakpoints.  We currently
200    just support one, implemented by the brkpt xbpf instruction.   */
201 
202 enum bpf_breakpoint_kinds
203 {
204   BPF_BP_KIND_BRKPT = 0,
205 };
206 
207 /* Implement the breakpoint_kind_from_pc gdbarch method.  */
208 
209 static int
210 bpf_breakpoint_kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *start_pc)
211 {
212   /* We support just one kind of breakpoint.  */
213   return BPF_BP_KIND_BRKPT;
214 }
215 
216 /* Implement the sw_breakpoint_from_kind gdbarch method.  */
217 
218 static const gdb_byte *
219 bpf_sw_breakpoint_from_kind (struct gdbarch *gdbarch, int kind, int *size)
220 {
221   static unsigned char brkpt_insn[]
222     = {0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
223 
224   switch (kind)
225     {
226     case BPF_BP_KIND_BRKPT:
227       *size = 8;
228       return brkpt_insn;
229     default:
230       gdb_assert_not_reached ("unexpected BPF breakpoint kind");
231     }
232 }
233 
234 
235 /* Assuming THIS_FRAME is a dummy frame, return its frame ID.  */
236 
237 static struct frame_id
238 bpf_dummy_id (struct gdbarch *gdbarch, frame_info_ptr this_frame)
239 {
240   CORE_ADDR sp = get_frame_register_unsigned (this_frame,
241 					      gdbarch_sp_regnum (gdbarch));
242   return frame_id_build (sp, get_frame_pc (this_frame));
243 }
244 
245 /* Implement the push dummy call gdbarch callback.  */
246 
247 static CORE_ADDR
248 bpf_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
249 		     struct regcache *regcache, CORE_ADDR bp_addr,
250 		     int nargs, struct value **args, CORE_ADDR sp,
251 		     function_call_return_method return_method,
252 		     CORE_ADDR struct_addr)
253 {
254   gdb_printf (gdb_stdlog, "Pushing dummy call: sp=%s\n",
255 	      paddress (gdbarch, sp));
256   /* XXX writeme  */
257   return sp;
258 }
259 
260 /* Extract a function return value of TYPE from REGCACHE,
261    and copy it into VALBUF.  */
262 
263 static void
264 bpf_extract_return_value (struct type *type, struct regcache *regcache,
265 			  gdb_byte *valbuf)
266 {
267   int len = type->length ();
268   gdb_byte vbuf[8];
269 
270   gdb_assert (len <= 8);
271   regcache->cooked_read (BPF_R0_REGNUM, vbuf);
272   memcpy (valbuf, vbuf + 8 - len, len);
273 }
274 
275 /* Store the function return value of type TYPE from VALBUF into REGNAME.  */
276 
277 static void
278 bpf_store_return_value (struct type *type, struct regcache *regcache,
279 			const gdb_byte *valbuf)
280 {
281   int len = type->length ();
282   gdb_byte vbuf[8];
283 
284   gdb_assert (len <= 8);
285   memset (vbuf, 0, sizeof (vbuf));
286   memcpy (vbuf + 8 - len, valbuf, len);
287   regcache->cooked_write (BPF_R0_REGNUM, vbuf);
288 }
289 
290 /* Handle function's return value.  */
291 
292 static enum return_value_convention
293 bpf_return_value (struct gdbarch *gdbarch, struct value *function,
294 		  struct type *type, struct regcache *regcache,
295 		  gdb_byte *readbuf, const gdb_byte *writebuf)
296 {
297   int len = type->length ();
298 
299   if (len > 8)
300     return RETURN_VALUE_STRUCT_CONVENTION;
301 
302   if (readbuf != NULL)
303     bpf_extract_return_value (type, regcache, readbuf);
304   if (writebuf != NULL)
305     bpf_store_return_value (type, regcache, writebuf);
306 
307   return RETURN_VALUE_REGISTER_CONVENTION;
308 }
309 
310 
311 /* Initialize the current architecture based on INFO.  If possible, re-use an
312    architecture from ARCHES, which is a list of architectures already created
313    during this debugging session.  */
314 
315 static struct gdbarch *
316 bpf_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
317 {
318   /* If there is already a candidate, use it.  */
319   arches = gdbarch_list_lookup_by_info (arches, &info);
320   if (arches != NULL)
321     return arches->gdbarch;
322 
323   /* Allocate space for the new architecture.  */
324   bpf_gdbarch_tdep *tdep = new bpf_gdbarch_tdep;
325   struct gdbarch *gdbarch = gdbarch_alloc (&info, tdep);
326 
327   /* Information about registers, etc.  */
328   set_gdbarch_num_regs (gdbarch, BPF_NUM_REGS);
329   set_gdbarch_register_name (gdbarch, bpf_register_name);
330   set_gdbarch_register_type (gdbarch, bpf_register_type);
331 
332   /* Register numbers of various important registers.  */
333   set_gdbarch_sp_regnum (gdbarch, BPF_R10_REGNUM);
334   set_gdbarch_pc_regnum (gdbarch, BPF_PC_REGNUM);
335 
336   /* Map DWARF2 registers to GDB registers.  */
337   set_gdbarch_dwarf2_reg_to_regnum (gdbarch, bpf_dwarf2_reg_to_regnum);
338 
339   /* Call dummy code.  */
340   set_gdbarch_call_dummy_location (gdbarch, ON_STACK);
341   set_gdbarch_dummy_id (gdbarch, bpf_dummy_id);
342   set_gdbarch_push_dummy_call (gdbarch, bpf_push_dummy_call);
343 
344   /* Returning results.  */
345   set_gdbarch_return_value (gdbarch, bpf_return_value);
346 
347   /* Advance PC across function entry code.  */
348   set_gdbarch_skip_prologue (gdbarch, bpf_skip_prologue);
349 
350   /* Stack grows downward.  */
351   set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
352 
353   /* Breakpoint manipulation.  */
354   set_gdbarch_breakpoint_kind_from_pc (gdbarch, bpf_breakpoint_kind_from_pc);
355   set_gdbarch_sw_breakpoint_from_kind (gdbarch, bpf_sw_breakpoint_from_kind);
356 
357   /* Frame handling.  */
358   set_gdbarch_frame_args_skip (gdbarch, 8);
359 
360   /* Disassembly.  */
361   set_gdbarch_print_insn (gdbarch, bpf_gdb_print_insn);
362 
363   /* Hook in ABI-specific overrides, if they have been registered.  */
364   gdbarch_init_osabi (info, gdbarch);
365 
366   /* Install unwinders.  */
367   frame_unwind_append_unwinder (gdbarch, &bpf_frame_unwind);
368 
369   return gdbarch;
370 }
371 
372 void _initialize_bpf_tdep ();
373 void
374 _initialize_bpf_tdep ()
375 {
376   gdbarch_register (bfd_arch_bpf, bpf_gdbarch_init);
377 
378   /* Add commands 'set/show debug bpf'.  */
379   add_setshow_zuinteger_cmd ("bpf", class_maintenance,
380 			     &bpf_debug_flag,
381 			     _("Set BPF debugging."),
382 			     _("Show BPF debugging."),
383 			     _("Enables BPF specific debugging output."),
384 			     NULL,
385 			     &show_bpf_debug,
386 			     &setdebuglist, &showdebuglist);
387 }
388