]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/bpf-tdep.c
be01e8bdcd182477f751542c1096b351af98867a
[thirdparty/binutils-gdb.git] / gdb / bpf-tdep.c
1 /* Target-dependent code for BPF.
2
3 Copyright (C) 2020-2025 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 "arch-utils.h"
21 #include "dis-asm.h"
22 #include "frame.h"
23 #include "frame-unwind.h"
24 #include "trad-frame.h"
25 #include "symtab.h"
26 #include "value.h"
27 #include "cli/cli-cmds.h"
28 #include "breakpoint.h"
29 #include "inferior.h"
30 #include "regcache.h"
31 #include "target.h"
32 #include "dwarf2/frame.h"
33 #include "osabi.h"
34 #include "target-descriptions.h"
35 #include "remote.h"
36 #include "gdbarch.h"
37
38 \f
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 bpf_gdbarch_tdep : gdbarch_tdep_base
61 {
62 };
63
64 \f
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 gdb_printf (file, _("Debugging of BPF is %s.\n"), value);
79 }
80
81 \f
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 static_assert (ARRAY_SIZE (bpf_register_names) == BPF_NUM_REGS);
96 return bpf_register_names[reg];
97 }
98
99 /* Return the GDB type of register REGNUM. */
100
101 static struct type *
102 bpf_register_type (struct gdbarch *gdbarch, int reg)
103 {
104 if (reg == BPF_R10_REGNUM)
105 return builtin_type (gdbarch)->builtin_data_ptr;
106 else if (reg == BPF_PC_REGNUM)
107 return builtin_type (gdbarch)->builtin_func_ptr;
108 return builtin_type (gdbarch)->builtin_int64;
109 }
110
111 /* Return the GDB register number corresponding to DWARF's REG. */
112
113 static int
114 bpf_dwarf2_reg_to_regnum (struct gdbarch *gdbarch, int reg)
115 {
116 if (reg >= 0 && reg < BPF_NUM_REGS)
117 return reg;
118 return -1;
119 }
120
121 /* Implement the "print_insn" gdbarch method. */
122
123 static int
124 bpf_gdb_print_insn (bfd_vma memaddr, disassemble_info *info)
125 {
126 info->symbols = NULL;
127 return default_print_insn (memaddr, info);
128 }
129
130 \f
131 /* Return PC of first real instruction of the function starting at
132 START_PC. */
133
134 static CORE_ADDR
135 bpf_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc)
136 {
137 gdb_printf (gdb_stdlog,
138 "Skipping prologue: start_pc=%s\n",
139 paddress (gdbarch, start_pc));
140 /* XXX: to be completed. */
141 return start_pc + 0;
142 }
143
144 \f
145 /* Frame unwinder.
146
147 XXX it is not clear how to unwind in eBPF, since the stack is not
148 guaranteed to be contiguous, and therefore no relative stack
149 addressing can be done in the callee in order to access the
150 caller's stack frame. To explore with xBPF, which will relax this
151 restriction. */
152
153 /* Given THIS_FRAME, return its ID. */
154
155 static void
156 bpf_frame_this_id (const frame_info_ptr &this_frame,
157 void **this_prologue_cache,
158 struct frame_id *this_id)
159 {
160 /* Note that THIS_ID defaults to the outermost frame if we don't set
161 anything here. See frame.c:compute_frame_id. */
162 }
163
164 /* Return the reason why we can't unwind past THIS_FRAME. */
165
166 static enum unwind_stop_reason
167 bpf_frame_unwind_stop_reason (const frame_info_ptr &this_frame,
168 void **this_cache)
169 {
170 return UNWIND_OUTERMOST;
171 }
172
173 /* Ask THIS_FRAME to unwind its register. */
174
175 static struct value *
176 bpf_frame_prev_register (const frame_info_ptr &this_frame,
177 void **this_prologue_cache, int regnum)
178 {
179 return frame_unwind_got_register (this_frame, regnum, regnum);
180 }
181
182 /* Frame unwinder machinery for BPF. */
183
184 static const struct frame_unwind_legacy bpf_frame_unwind (
185 "bpf prologue",
186 NORMAL_FRAME,
187 FRAME_UNWIND_ARCH,
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 \f
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 \f
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, const frame_info_ptr &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 gdb_printf (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 ();
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 ();
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 ();
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 \f
310 /* Initialize the current architecture based on INFO. If possible, reuse 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 gdbarch *gdbarch
324 = gdbarch_alloc (&info, gdbarch_tdep_up (new bpf_gdbarch_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 INIT_GDB_FILE (bpf_tdep)
372 {
373 gdbarch_register (bfd_arch_bpf, bpf_gdbarch_init);
374
375 /* Add commands 'set/show debug bpf'. */
376 add_setshow_zuinteger_cmd ("bpf", class_maintenance,
377 &bpf_debug_flag,
378 _("Set BPF debugging."),
379 _("Show BPF debugging."),
380 _("Enables BPF specific debugging output."),
381 NULL,
382 &show_bpf_debug,
383 &setdebuglist, &showdebuglist);
384 }