bpf-tdep.c revision 1.1.1.1
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
41enum 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.  */
60struct 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
70static unsigned int bpf_debug_flag = 0;
71
72/* The show callback for 'show debug bpf'.  */
73
74static void
75show_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
84static 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
92static const char *
93bpf_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
102static struct type *
103bpf_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
114static int
115bpf_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
124static int
125bpf_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
135static CORE_ADDR
136bpf_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
156static void
157bpf_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
167static enum unwind_stop_reason
168bpf_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
176static struct value *
177bpf_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
185static 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
201enum bpf_breakpoint_kinds
202{
203  BPF_BP_KIND_BRKPT = 0,
204};
205
206/* Implement the breakpoint_kind_from_pc gdbarch method.  */
207
208static int
209bpf_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
217static const gdb_byte *
218bpf_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
236static struct frame_id
237bpf_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
246static CORE_ADDR
247bpf_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
262static void
263bpf_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
276static void
277bpf_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
291static enum return_value_convention
292bpf_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
314static struct gdbarch *
315bpf_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
371void _initialize_bpf_tdep ();
372void
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