xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/bpf-tdep.c (revision d16b7486a53dcb8072b60ec6fcb4373a2d0c27b7)
1 /* Target-dependent code for BPF.
2 
3    Copyright (C) 2020 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 
38 
39 /* eBPF registers.  */
40 
41 enum bpf_regnum
42 {
43   BPF_R0_REGNUM,		/* return value */
44   BPF_R1_REGNUM,
45   BPF_R2_REGNUM,
46   BPF_R3_REGNUM,
47   BPF_R4_REGNUM,
48   BPF_R5_REGNUM,
49   BPF_R6_REGNUM,
50   BPF_R7_REGNUM,
51   BPF_R8_REGNUM,
52   BPF_R9_REGNUM,
53   BPF_R10_REGNUM,		/* sp */
54   BPF_PC_REGNUM,
55 };
56 
57 #define BPF_NUM_REGS	(BPF_PC_REGNUM + 1)
58 
59 /* Target-dependent structure in gdbarch.  */
60 struct gdbarch_tdep
61 {
62 };
63 
64 
65 /* Internal debugging facilities.  */
66 
67 /* When this is set to non-zero debugging information will be
68    printed.  */
69 
70 static unsigned int bpf_debug_flag = 0;
71 
72 /* The show callback for 'show debug bpf'.  */
73 
74 static void
75 show_bpf_debug (struct ui_file *file, int from_tty,
76 	        struct cmd_list_element *c, const char *value)
77 {
78   fprintf_filtered (file, _("Debugging of BPF is %s.\n"), value);
79 }
80 
81 
82 /* BPF registers.  */
83 
84 static const char *bpf_register_names[] =
85 {
86   "r0",   "r1",  "r2",    "r3",   "r4",   "r5",   "r6",   "r7",
87   "r8",   "r9",  "r10",   "pc"
88 };
89 
90 /* Return the name of register REGNUM.  */
91 
92 static const char *
93 bpf_register_name (struct gdbarch *gdbarch, int reg)
94 {
95   if (reg >= 0 && reg < BPF_NUM_REGS)
96     return bpf_register_names[reg];
97   return NULL;
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   fprintf_unfiltered (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 (struct frame_info *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 (struct frame_info *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 (struct frame_info *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   NORMAL_FRAME,
188   bpf_frame_unwind_stop_reason,
189   bpf_frame_this_id,
190   bpf_frame_prev_register,
191   NULL,
192   default_frame_sniffer
193 };
194 
195 
196 /* Breakpoints.  */
197 
198 /* Enum describing the different kinds of breakpoints.  We currently
199    just support one, implemented by the brkpt xbpf instruction.   */
200 
201 enum bpf_breakpoint_kinds
202 {
203   BPF_BP_KIND_BRKPT = 0,
204 };
205 
206 /* Implement the breakpoint_kind_from_pc gdbarch method.  */
207 
208 static int
209 bpf_breakpoint_kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *start_pc)
210 {
211   /* We support just one kind of breakpoint.  */
212   return BPF_BP_KIND_BRKPT;
213 }
214 
215 /* Implement the sw_breakpoint_from_kind gdbarch method.  */
216 
217 static const gdb_byte *
218 bpf_sw_breakpoint_from_kind (struct gdbarch *gdbarch, int kind, int *size)
219 {
220   static unsigned char brkpt_insn[]
221     = {0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
222 
223   switch (kind)
224     {
225     case BPF_BP_KIND_BRKPT:
226       *size = 8;
227       return brkpt_insn;
228     default:
229       gdb_assert_not_reached ("unexpected BPF breakpoint kind");
230     }
231 }
232 
233 
234 /* Assuming THIS_FRAME is a dummy frame, return its frame ID.  */
235 
236 static struct frame_id
237 bpf_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
238 {
239   CORE_ADDR sp = get_frame_register_unsigned (this_frame,
240 					      gdbarch_sp_regnum (gdbarch));
241   return frame_id_build (sp, get_frame_pc (this_frame));
242 }
243 
244 /* Implement the push dummy call gdbarch callback.  */
245 
246 static CORE_ADDR
247 bpf_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
248 		     struct regcache *regcache, CORE_ADDR bp_addr,
249 		     int nargs, struct value **args, CORE_ADDR sp,
250 		     function_call_return_method return_method,
251 		     CORE_ADDR struct_addr)
252 {
253   fprintf_unfiltered (gdb_stdlog, "Pushing dummy call: sp=%s\n",
254 		      paddress (gdbarch, sp));
255   /* XXX writeme  */
256   return sp;
257 }
258 
259 /* Extract a function return value of TYPE from REGCACHE,
260    and copy it into VALBUF.  */
261 
262 static void
263 bpf_extract_return_value (struct type *type, struct regcache *regcache,
264 			  gdb_byte *valbuf)
265 {
266   int len = TYPE_LENGTH (type);
267   gdb_byte vbuf[8];
268 
269   gdb_assert (len <= 8);
270   regcache->cooked_read (BPF_R0_REGNUM, vbuf);
271   memcpy (valbuf, vbuf + 8 - len, len);
272 }
273 
274 /* Store the function return value of type TYPE from VALBUF into REGNAME.  */
275 
276 static void
277 bpf_store_return_value (struct type *type, struct regcache *regcache,
278 			const gdb_byte *valbuf)
279 {
280   int len = TYPE_LENGTH (type);
281   gdb_byte vbuf[8];
282 
283   gdb_assert (len <= 8);
284   memset (vbuf, 0, sizeof (vbuf));
285   memcpy (vbuf + 8 - len, valbuf, len);
286   regcache->cooked_write (BPF_R0_REGNUM, vbuf);
287 }
288 
289 /* Handle function's return value.  */
290 
291 static enum return_value_convention
292 bpf_return_value (struct gdbarch *gdbarch, struct value *function,
293 		  struct type *type, struct regcache *regcache,
294 		  gdb_byte *readbuf, const gdb_byte *writebuf)
295 {
296   int len = TYPE_LENGTH (type);
297 
298   if (len > 8)
299     return RETURN_VALUE_STRUCT_CONVENTION;
300 
301   if (readbuf != NULL)
302     bpf_extract_return_value (type, regcache, readbuf);
303   if (writebuf != NULL)
304     bpf_store_return_value (type, regcache, writebuf);
305 
306   return RETURN_VALUE_REGISTER_CONVENTION;
307 }
308 
309 
310 /* Initialize the current architecture based on INFO.  If possible, re-use an
311    architecture from ARCHES, which is a list of architectures already created
312    during this debugging session.  */
313 
314 static struct gdbarch *
315 bpf_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
316 {
317   /* If there is already a candidate, use it.  */
318   arches = gdbarch_list_lookup_by_info (arches, &info);
319   if (arches != NULL)
320     return arches->gdbarch;
321 
322   /* Allocate space for the new architecture.  */
323   struct gdbarch_tdep *tdep = XCNEW (struct gdbarch_tdep);
324   struct gdbarch *gdbarch = gdbarch_alloc (&info, tdep);
325 
326   /* Information about registers, etc.  */
327   set_gdbarch_num_regs (gdbarch, BPF_NUM_REGS);
328   set_gdbarch_register_name (gdbarch, bpf_register_name);
329   set_gdbarch_register_type (gdbarch, bpf_register_type);
330 
331   /* Register numbers of various important registers.  */
332   set_gdbarch_sp_regnum (gdbarch, BPF_R10_REGNUM);
333   set_gdbarch_pc_regnum (gdbarch, BPF_PC_REGNUM);
334 
335   /* Map DWARF2 registers to GDB registers.  */
336   set_gdbarch_dwarf2_reg_to_regnum (gdbarch, bpf_dwarf2_reg_to_regnum);
337 
338   /* Call dummy code.  */
339   set_gdbarch_call_dummy_location (gdbarch, ON_STACK);
340   set_gdbarch_dummy_id (gdbarch, bpf_dummy_id);
341   set_gdbarch_push_dummy_call (gdbarch, bpf_push_dummy_call);
342 
343   /* Returning results.  */
344   set_gdbarch_return_value (gdbarch, bpf_return_value);
345 
346   /* Advance PC across function entry code.  */
347   set_gdbarch_skip_prologue (gdbarch, bpf_skip_prologue);
348 
349   /* Stack grows downward.  */
350   set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
351 
352   /* Breakpoint manipulation.  */
353   set_gdbarch_breakpoint_kind_from_pc (gdbarch, bpf_breakpoint_kind_from_pc);
354   set_gdbarch_sw_breakpoint_from_kind (gdbarch, bpf_sw_breakpoint_from_kind);
355 
356   /* Frame handling.  */
357   set_gdbarch_frame_args_skip (gdbarch, 8);
358 
359   /* Disassembly.  */
360   set_gdbarch_print_insn (gdbarch, bpf_gdb_print_insn);
361 
362   /* Hook in ABI-specific overrides, if they have been registered.  */
363   gdbarch_init_osabi (info, gdbarch);
364 
365   /* Install unwinders.  */
366   frame_unwind_append_unwinder (gdbarch, &bpf_frame_unwind);
367 
368   return gdbarch;
369 }
370 
371 void _initialize_bpf_tdep ();
372 void
373 _initialize_bpf_tdep (void)
374 {
375   register_gdbarch_init (bfd_arch_bpf, bpf_gdbarch_init);
376 
377   /* Add commands 'set/show debug bpf'.  */
378   add_setshow_zuinteger_cmd ("bpf", class_maintenance,
379 			     &bpf_debug_flag,
380 			     _("Set BPF debugging."),
381 			     _("Show BPF debugging."),
382 			     _("Enables BPF specific debugging output."),
383 			     NULL,
384 			     &show_bpf_debug,
385 			     &setdebuglist, &showdebuglist);
386 }
387