]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/bpf-tdep.c
Fix indentation in loongarch code, preventing a compile time warning.
[thirdparty/binutils-gdb.git] / gdb / bpf-tdep.c
CommitLineData
39791af2
JM
1/* Target-dependent code for BPF.
2
4a94e368 3 Copyright (C) 2020-2022 Free Software Foundation, Inc.
39791af2
JM
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"
76eb8ef1 37#include "gdbarch.h"
39791af2
JM
38
39\f
40/* eBPF registers. */
41
42enum 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. */
345bd07c 61struct bpf_gdbarch_tdep : gdbarch_tdep
39791af2
JM
62{
63};
64
65\f
66/* Internal debugging facilities. */
67
68/* When this is set to non-zero debugging information will be
69 printed. */
70
71static unsigned int bpf_debug_flag = 0;
72
73/* The show callback for 'show debug bpf'. */
74
75static void
76show_bpf_debug (struct ui_file *file, int from_tty,
dda83cd7 77 struct cmd_list_element *c, const char *value)
39791af2 78{
6cb06a8c 79 gdb_printf (file, _("Debugging of BPF is %s.\n"), value);
39791af2
JM
80}
81
82\f
83/* BPF registers. */
84
85static 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
93static const char *
94bpf_register_name (struct gdbarch *gdbarch, int reg)
95{
96 if (reg >= 0 && reg < BPF_NUM_REGS)
97 return bpf_register_names[reg];
98 return NULL;
99}
100
101/* Return the GDB type of register REGNUM. */
102
103static struct type *
104bpf_register_type (struct gdbarch *gdbarch, int reg)
105{
106 if (reg == BPF_R10_REGNUM)
107 return builtin_type (gdbarch)->builtin_data_ptr;
108 else if (reg == BPF_PC_REGNUM)
109 return builtin_type (gdbarch)->builtin_func_ptr;
110 return builtin_type (gdbarch)->builtin_int64;
111}
112
113/* Return the GDB register number corresponding to DWARF's REG. */
114
115static int
116bpf_dwarf2_reg_to_regnum (struct gdbarch *gdbarch, int reg)
117{
118 if (reg >= 0 && reg < BPF_NUM_REGS)
119 return reg;
120 return -1;
121}
122
123/* Implement the "print_insn" gdbarch method. */
124
125static int
126bpf_gdb_print_insn (bfd_vma memaddr, disassemble_info *info)
127{
128 info->symbols = NULL;
129 return default_print_insn (memaddr, info);
130}
131
132\f
133/* Return PC of first real instruction of the function starting at
134 START_PC. */
135
136static CORE_ADDR
137bpf_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc)
138{
6cb06a8c
TT
139 gdb_printf (gdb_stdlog,
140 "Skipping prologue: start_pc=%s\n",
141 paddress (gdbarch, start_pc));
39791af2
JM
142 /* XXX: to be completed. */
143 return start_pc + 0;
144}
145
146\f
147/* Frame unwinder.
148
149 XXX it is not clear how to unwind in eBPF, since the stack is not
150 guaranteed to be contiguous, and therefore no relative stack
151 addressing can be done in the callee in order to access the
152 caller's stack frame. To explore with xBPF, which will relax this
153 restriction. */
154
155/* Given THIS_FRAME, return its ID. */
156
157static void
158bpf_frame_this_id (struct frame_info *this_frame,
159 void **this_prologue_cache,
160 struct frame_id *this_id)
161{
162 /* Note that THIS_ID defaults to the outermost frame if we don't set
163 anything here. See frame.c:compute_frame_id. */
164}
165
166/* Return the reason why we can't unwind past THIS_FRAME. */
167
168static enum unwind_stop_reason
169bpf_frame_unwind_stop_reason (struct frame_info *this_frame,
170 void **this_cache)
171{
172 return UNWIND_OUTERMOST;
173}
174
175/* Ask THIS_FRAME to unwind its register. */
176
177static struct value *
178bpf_frame_prev_register (struct frame_info *this_frame,
179 void **this_prologue_cache, int regnum)
180{
181 return frame_unwind_got_register (this_frame, regnum, regnum);
182}
183
184/* Frame unwinder machinery for BPF. */
185
186static const struct frame_unwind bpf_frame_unwind =
187{
a154d838 188 "bpf prologue",
39791af2
JM
189 NORMAL_FRAME,
190 bpf_frame_unwind_stop_reason,
191 bpf_frame_this_id,
192 bpf_frame_prev_register,
193 NULL,
194 default_frame_sniffer
195};
196
197\f
198/* Breakpoints. */
199
200/* Enum describing the different kinds of breakpoints. We currently
201 just support one, implemented by the brkpt xbpf instruction. */
202
203enum bpf_breakpoint_kinds
204{
205 BPF_BP_KIND_BRKPT = 0,
206};
207
208/* Implement the breakpoint_kind_from_pc gdbarch method. */
209
210static int
211bpf_breakpoint_kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *start_pc)
212{
213 /* We support just one kind of breakpoint. */
214 return BPF_BP_KIND_BRKPT;
215}
216
217/* Implement the sw_breakpoint_from_kind gdbarch method. */
218
219static const gdb_byte *
220bpf_sw_breakpoint_from_kind (struct gdbarch *gdbarch, int kind, int *size)
221{
222 static unsigned char brkpt_insn[]
223 = {0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
224
225 switch (kind)
226 {
227 case BPF_BP_KIND_BRKPT:
228 *size = 8;
229 return brkpt_insn;
230 default:
231 gdb_assert_not_reached ("unexpected BPF breakpoint kind");
232 }
233}
234
235\f
236/* Assuming THIS_FRAME is a dummy frame, return its frame ID. */
237
238static struct frame_id
239bpf_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
240{
241 CORE_ADDR sp = get_frame_register_unsigned (this_frame,
242 gdbarch_sp_regnum (gdbarch));
243 return frame_id_build (sp, get_frame_pc (this_frame));
244}
245
246/* Implement the push dummy call gdbarch callback. */
247
248static CORE_ADDR
249bpf_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
250 struct regcache *regcache, CORE_ADDR bp_addr,
251 int nargs, struct value **args, CORE_ADDR sp,
252 function_call_return_method return_method,
253 CORE_ADDR struct_addr)
254{
6cb06a8c
TT
255 gdb_printf (gdb_stdlog, "Pushing dummy call: sp=%s\n",
256 paddress (gdbarch, sp));
39791af2
JM
257 /* XXX writeme */
258 return sp;
259}
260
261/* Extract a function return value of TYPE from REGCACHE,
262 and copy it into VALBUF. */
263
264static void
265bpf_extract_return_value (struct type *type, struct regcache *regcache,
266 gdb_byte *valbuf)
267{
268 int len = TYPE_LENGTH (type);
269 gdb_byte vbuf[8];
270
271 gdb_assert (len <= 8);
272 regcache->cooked_read (BPF_R0_REGNUM, vbuf);
273 memcpy (valbuf, vbuf + 8 - len, len);
274}
275
276/* Store the function return value of type TYPE from VALBUF into REGNAME. */
277
278static void
279bpf_store_return_value (struct type *type, struct regcache *regcache,
280 const gdb_byte *valbuf)
281{
282 int len = TYPE_LENGTH (type);
283 gdb_byte vbuf[8];
284
285 gdb_assert (len <= 8);
286 memset (vbuf, 0, sizeof (vbuf));
287 memcpy (vbuf + 8 - len, valbuf, len);
288 regcache->cooked_write (BPF_R0_REGNUM, vbuf);
289}
290
291/* Handle function's return value. */
292
293static enum return_value_convention
294bpf_return_value (struct gdbarch *gdbarch, struct value *function,
295 struct type *type, struct regcache *regcache,
296 gdb_byte *readbuf, const gdb_byte *writebuf)
297{
298 int len = TYPE_LENGTH (type);
299
300 if (len > 8)
301 return RETURN_VALUE_STRUCT_CONVENTION;
302
303 if (readbuf != NULL)
304 bpf_extract_return_value (type, regcache, readbuf);
305 if (writebuf != NULL)
306 bpf_store_return_value (type, regcache, writebuf);
307
308 return RETURN_VALUE_REGISTER_CONVENTION;
309}
310
311\f
312/* Initialize the current architecture based on INFO. If possible, re-use an
313 architecture from ARCHES, which is a list of architectures already created
314 during this debugging session. */
315
316static struct gdbarch *
317bpf_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
318{
319 /* If there is already a candidate, use it. */
320 arches = gdbarch_list_lookup_by_info (arches, &info);
321 if (arches != NULL)
322 return arches->gdbarch;
323
324 /* Allocate space for the new architecture. */
345bd07c 325 bpf_gdbarch_tdep *tdep = new bpf_gdbarch_tdep;
39791af2
JM
326 struct gdbarch *gdbarch = gdbarch_alloc (&info, tdep);
327
328 /* Information about registers, etc. */
329 set_gdbarch_num_regs (gdbarch, BPF_NUM_REGS);
330 set_gdbarch_register_name (gdbarch, bpf_register_name);
331 set_gdbarch_register_type (gdbarch, bpf_register_type);
332
333 /* Register numbers of various important registers. */
334 set_gdbarch_sp_regnum (gdbarch, BPF_R10_REGNUM);
335 set_gdbarch_pc_regnum (gdbarch, BPF_PC_REGNUM);
336
337 /* Map DWARF2 registers to GDB registers. */
338 set_gdbarch_dwarf2_reg_to_regnum (gdbarch, bpf_dwarf2_reg_to_regnum);
339
340 /* Call dummy code. */
341 set_gdbarch_call_dummy_location (gdbarch, ON_STACK);
342 set_gdbarch_dummy_id (gdbarch, bpf_dummy_id);
343 set_gdbarch_push_dummy_call (gdbarch, bpf_push_dummy_call);
344
345 /* Returning results. */
346 set_gdbarch_return_value (gdbarch, bpf_return_value);
347
348 /* Advance PC across function entry code. */
349 set_gdbarch_skip_prologue (gdbarch, bpf_skip_prologue);
350
351 /* Stack grows downward. */
352 set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
353
354 /* Breakpoint manipulation. */
355 set_gdbarch_breakpoint_kind_from_pc (gdbarch, bpf_breakpoint_kind_from_pc);
356 set_gdbarch_sw_breakpoint_from_kind (gdbarch, bpf_sw_breakpoint_from_kind);
357
358 /* Frame handling. */
359 set_gdbarch_frame_args_skip (gdbarch, 8);
360
361 /* Disassembly. */
362 set_gdbarch_print_insn (gdbarch, bpf_gdb_print_insn);
363
364 /* Hook in ABI-specific overrides, if they have been registered. */
365 gdbarch_init_osabi (info, gdbarch);
366
367 /* Install unwinders. */
368 frame_unwind_append_unwinder (gdbarch, &bpf_frame_unwind);
369
370 return gdbarch;
371}
372
373void _initialize_bpf_tdep ();
374void
f39632d9 375_initialize_bpf_tdep ()
39791af2
JM
376{
377 register_gdbarch_init (bfd_arch_bpf, bpf_gdbarch_init);
378
379 /* Add commands 'set/show debug bpf'. */
380 add_setshow_zuinteger_cmd ("bpf", class_maintenance,
381 &bpf_debug_flag,
382 _("Set BPF debugging."),
383 _("Show BPF debugging."),
384 _("Enables BPF specific debugging output."),
385 NULL,
386 &show_bpf_debug,
387 &setdebuglist, &showdebuglist);
388}