summaryrefslogtreecommitdiffstats
path: root/meta-microblaze/recipes-devtools/gdb/gdb/0001-Patch-MicroBlaze.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-microblaze/recipes-devtools/gdb/gdb/0001-Patch-MicroBlaze.patch')
-rw-r--r--meta-microblaze/recipes-devtools/gdb/gdb/0001-Patch-MicroBlaze.patch505
1 files changed, 505 insertions, 0 deletions
diff --git a/meta-microblaze/recipes-devtools/gdb/gdb/0001-Patch-MicroBlaze.patch b/meta-microblaze/recipes-devtools/gdb/gdb/0001-Patch-MicroBlaze.patch
new file mode 100644
index 00000000..b5a2726b
--- /dev/null
+++ b/meta-microblaze/recipes-devtools/gdb/gdb/0001-Patch-MicroBlaze.patch
@@ -0,0 +1,505 @@
1From b7b3c1eb19b770b2d700dd3c9fa23a7ae225a72b Mon Sep 17 00:00:00 2001
2From: Mahesh Bodapati <mbodapat@xilinx.com>
3Date: Thu, 16 Jun 2022 09:50:14 +0530
4Subject: [PATCH 01/10] [Patch,MicroBlaze] : Add initial port of linux
5 gdbserver add gdb_proc_service_h to gdbserver microblaze-linux
6
7gdbserver needs to initialise the microblaze registers
8
9other archs use this step to run a *_arch_setup() to carry out all
10architecture specific setup - may need to add in future
11
12 * add linux-ptrace.o to gdbserver configure
13 * Update breakpoint opcode
14 * fix segfault on connecting gdbserver
15 * add microblaze_linux_memory_remove_breakpoint
16 * add set_solib_svr4_fetch_link_map_offsets
17 * add set_gdbarch_fetch_tls_load_module_address
18 * Force reading of r0 as 0, prevent stores
19
20Signed-off-by: David Holsgrove <david.holsgrove@petalogix.com>
21Signed-off-by: Nathan Rossi <nathan.rossi@petalogix.com>
22
23Conflicts:
24 gdbserver/Makefile.in
25---
26 gdb/configure.host | 3 +
27 gdb/features/microblaze-linux.xml | 12 ++
28 gdb/gdbserver/linux-microblaze-low.c | 189 +++++++++++++++++++++++++++
29 gdb/microblaze-linux-tdep.c | 29 +++-
30 gdb/microblaze-tdep.c | 35 ++++-
31 gdb/microblaze-tdep.h | 4 +-
32 gdb/regformats/reg-microblaze.dat | 41 ++++++
33 gdbserver/Makefile.in | 6 +-
34 gdbserver/configure.srv | 8 ++
35 9 files changed, 323 insertions(+), 4 deletions(-)
36 create mode 100644 gdb/features/microblaze-linux.xml
37 create mode 100644 gdb/gdbserver/linux-microblaze-low.c
38 create mode 100644 gdb/regformats/reg-microblaze.dat
39
40diff --git a/gdb/configure.host b/gdb/configure.host
41index ce528237291..cf1a08e8b28 100644
42--- a/gdb/configure.host
43+++ b/gdb/configure.host
44@@ -65,6 +65,7 @@ hppa*) gdb_host_cpu=pa ;;
45 i[34567]86*) gdb_host_cpu=i386 ;;
46 m68*) gdb_host_cpu=m68k ;;
47 mips*) gdb_host_cpu=mips ;;
48+microblaze*) gdb_host_cpu=microblaze ;;
49 powerpc* | rs6000) gdb_host_cpu=powerpc ;;
50 sparcv9 | sparc64) gdb_host_cpu=sparc ;;
51 s390*) gdb_host_cpu=s390 ;;
52@@ -133,6 +134,8 @@ mips*-*-netbsd* | mips*-*-knetbsd*-gnu)
53 mips*-*-freebsd*) gdb_host=fbsd ;;
54 mips64*-*-openbsd*) gdb_host=obsd64 ;;
55
56+microblaze*-*linux*) gdb_host=linux ;;
57+
58 powerpc-*-aix* | rs6000-*-* | powerpc64-*-aix*)
59 gdb_host=aix ;;
60 powerpc*-*-freebsd*) gdb_host=fbsd ;;
61diff --git a/gdb/features/microblaze-linux.xml b/gdb/features/microblaze-linux.xml
62new file mode 100644
63index 00000000000..8983e66eb3d
64--- /dev/null
65+++ b/gdb/features/microblaze-linux.xml
66@@ -0,0 +1,12 @@
67+<?xml version="1.0"?>
68+<!-- Copyright (C) 2014-2018 Free Software Foundation, Inc.
69+
70+ Copying and distribution of this file, with or without modification,
71+ are permitted in any medium without royalty provided the copyright
72+ notice and this notice are preserved. -->
73+
74+<!DOCTYPE target SYSTEM "gdb-target.dtd">
75+<target>
76+ <osabi>GNU/Linux</osabi>
77+ <xi:include href="microblaze-core.xml"/>
78+</target>
79diff --git a/gdb/gdbserver/linux-microblaze-low.c b/gdb/gdbserver/linux-microblaze-low.c
80new file mode 100644
81index 00000000000..cba5d6fc585
82--- /dev/null
83+++ b/gdb/gdbserver/linux-microblaze-low.c
84@@ -0,0 +1,189 @@
85+/* GNU/Linux/Microblaze specific low level interface, for the remote server for
86+ GDB.
87+ Copyright (C) 1995-2013 Free Software Foundation, Inc.
88+
89+ This file is part of GDB.
90+
91+ This program is free software; you can redistribute it and/or modify
92+ it under the terms of the GNU General Public License as published by
93+ the Free Software Foundation; either version 3 of the License, or
94+ (at your option) any later version.
95+
96+ This program is distributed in the hope that it will be useful,
97+ but WITHOUT ANY WARRANTY; without even the implied warranty of
98+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
99+ GNU General Public License for more details.
100+
101+ You should have received a copy of the GNU General Public License
102+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
103+
104+#include "server.h"
105+#include "linux-low.h"
106+
107+#include <asm/ptrace.h>
108+#include <sys/procfs.h>
109+#include <sys/ptrace.h>
110+
111+#include "gdb_proc_service.h"
112+
113+static int microblaze_regmap[] =
114+ {PT_GPR(0), PT_GPR(1), PT_GPR(2), PT_GPR(3),
115+ PT_GPR(4), PT_GPR(5), PT_GPR(6), PT_GPR(7),
116+ PT_GPR(8), PT_GPR(9), PT_GPR(10), PT_GPR(11),
117+ PT_GPR(12), PT_GPR(13), PT_GPR(14), PT_GPR(15),
118+ PT_GPR(16), PT_GPR(17), PT_GPR(18), PT_GPR(19),
119+ PT_GPR(20), PT_GPR(21), PT_GPR(22), PT_GPR(23),
120+ PT_GPR(24), PT_GPR(25), PT_GPR(26), PT_GPR(27),
121+ PT_GPR(28), PT_GPR(29), PT_GPR(30), PT_GPR(31),
122+ PT_PC, PT_MSR, PT_EAR, PT_ESR,
123+ PT_FSR
124+ };
125+
126+#define microblaze_num_regs (sizeof microblaze_regmap / sizeof microblaze_regmap[0])
127+
128+/* Defined in auto-generated file microblaze-linux.c. */
129+void init_registers_microblaze (void);
130+
131+static int
132+microblaze_cannot_store_register (int regno)
133+{
134+ if (microblaze_regmap[regno] == -1 || regno == 0)
135+ return 1;
136+
137+ return 0;
138+}
139+
140+static int
141+microblaze_cannot_fetch_register (int regno)
142+{
143+ return 0;
144+}
145+
146+static CORE_ADDR
147+microblaze_get_pc (struct regcache *regcache)
148+{
149+ unsigned long pc;
150+
151+ collect_register_by_name (regcache, "pc", &pc);
152+ return (CORE_ADDR) pc;
153+}
154+
155+static void
156+microblaze_set_pc (struct regcache *regcache, CORE_ADDR pc)
157+{
158+ unsigned long newpc = pc;
159+
160+ supply_register_by_name (regcache, "pc", &newpc);
161+}
162+
163+/* dbtrap insn */
164+/* brki r16, 0x18; */
165+static const unsigned long microblaze_breakpoint = 0xba0c0018;
166+#define microblaze_breakpoint_len 4
167+
168+static int
169+microblaze_breakpoint_at (CORE_ADDR where)
170+{
171+ unsigned long insn;
172+
173+ (*the_target->read_memory) (where, (unsigned char *) &insn, 4);
174+ if (insn == microblaze_breakpoint)
175+ return 1;
176+ /* If necessary, recognize more trap instructions here. GDB only uses the
177+ one. */
178+ return 0;
179+}
180+
181+static CORE_ADDR
182+microblaze_reinsert_addr (struct regcache *regcache)
183+{
184+ unsigned long pc;
185+ collect_register_by_name (regcache, "r15", &pc);
186+ return pc;
187+}
188+
189+#ifdef HAVE_PTRACE_GETREGS
190+
191+static void
192+microblaze_collect_ptrace_register (struct regcache *regcache, int regno, char *buf)
193+{
194+ int size = register_size (regno);
195+
196+ memset (buf, 0, sizeof (long));
197+
198+ if (size < sizeof (long))
199+ collect_register (regcache, regno, buf + sizeof (long) - size);
200+ else
201+ collect_register (regcache, regno, buf);
202+}
203+
204+static void
205+microblaze_supply_ptrace_register (struct regcache *regcache,
206+ int regno, const char *buf)
207+{
208+ int size = register_size (regno);
209+
210+ if (regno == 0) {
211+ unsigned long regbuf_0 = 0;
212+ /* clobbering r0 so that it is always 0 as enforced by hardware */
213+ supply_register (regcache, regno, (const char*)&regbuf_0);
214+ } else {
215+ if (size < sizeof (long))
216+ supply_register (regcache, regno, buf + sizeof (long) - size);
217+ else
218+ supply_register (regcache, regno, buf);
219+ }
220+}
221+
222+/* Provide only a fill function for the general register set. ps_lgetregs
223+ will use this for NPTL support. */
224+
225+static void microblaze_fill_gregset (struct regcache *regcache, void *buf)
226+{
227+ int i;
228+
229+ for (i = 0; i < 32; i++)
230+ microblaze_collect_ptrace_register (regcache, i, (char *) buf + microblaze_regmap[i]);
231+}
232+
233+static void
234+microblaze_store_gregset (struct regcache *regcache, const void *buf)
235+{
236+ int i;
237+
238+ for (i = 0; i < 32; i++)
239+ supply_register (regcache, i, (char *) buf + microblaze_regmap[i]);
240+}
241+
242+#endif /* HAVE_PTRACE_GETREGS */
243+
244+struct regset_info target_regsets[] = {
245+#ifdef HAVE_PTRACE_GETREGS
246+ { PTRACE_GETREGS, PTRACE_SETREGS, 0, sizeof (elf_gregset_t), GENERAL_REGS, microblaze_fill_gregset, microblaze_store_gregset },
247+ { 0, 0, 0, -1, -1, NULL, NULL },
248+#endif /* HAVE_PTRACE_GETREGS */
249+ { 0, 0, 0, -1, -1, NULL, NULL }
250+};
251+
252+struct linux_target_ops the_low_target = {
253+ init_registers_microblaze,
254+ microblaze_num_regs,
255+ microblaze_regmap,
256+ NULL,
257+ microblaze_cannot_fetch_register,
258+ microblaze_cannot_store_register,
259+ NULL, /* fetch_register */
260+ microblaze_get_pc,
261+ microblaze_set_pc,
262+ (const unsigned char *) &microblaze_breakpoint,
263+ microblaze_breakpoint_len,
264+ microblaze_reinsert_addr,
265+ 0,
266+ microblaze_breakpoint_at,
267+ NULL,
268+ NULL,
269+ NULL,
270+ NULL,
271+ microblaze_collect_ptrace_register,
272+ microblaze_supply_ptrace_register,
273+};
274diff --git a/gdb/microblaze-linux-tdep.c b/gdb/microblaze-linux-tdep.c
275index 3fc5e768120..0322b4ea813 100644
276--- a/gdb/microblaze-linux-tdep.c
277+++ b/gdb/microblaze-linux-tdep.c
278@@ -37,6 +37,22 @@
279 #include "tramp-frame.h"
280 #include "linux-tdep.h"
281
282+static int microblaze_debug_flag = 0;
283+
284+static void
285+microblaze_debug (const char *fmt, ...)
286+{
287+ if (microblaze_debug_flag)
288+ {
289+ va_list args;
290+
291+ va_start (args, fmt);
292+ printf_unfiltered ("MICROBLAZE LINUX: ");
293+ vprintf_unfiltered (fmt, args);
294+ va_end (args);
295+ }
296+}
297+
298 static int
299 microblaze_linux_memory_remove_breakpoint (struct gdbarch *gdbarch,
300 struct bp_target_info *bp_tgt)
301@@ -50,13 +66,20 @@ microblaze_linux_memory_remove_breakpoint (struct gdbarch *gdbarch,
302 /* Determine appropriate breakpoint contents and size for this address. */
303 bp = gdbarch_breakpoint_from_pc (gdbarch, &addr, &bplen);
304
305+ /* Make sure we see the memory breakpoints. */
306+ scoped_restore restore_memory
307+ = make_scoped_restore_show_memory_breakpoints (1);
308+
309 val = target_read_memory (addr, old_contents, bplen);
310
311 /* If our breakpoint is no longer at the address, this means that the
312 program modified the code on us, so it is wrong to put back the
313 old value. */
314 if (val == 0 && memcmp (bp, old_contents, bplen) == 0)
315- val = target_write_raw_memory (addr, bp_tgt->shadow_contents, bplen);
316+ {
317+ val = target_write_raw_memory (addr, bp_tgt->shadow_contents, bplen);
318+ microblaze_debug ("microblaze_linux_memory_remove_breakpoint writing back to memory at addr 0x%lx\n", addr);
319+ }
320
321 return val;
322 }
323@@ -129,6 +152,10 @@ microblaze_linux_init_abi (struct gdbarch_info info,
324 /* Trampolines. */
325 tramp_frame_prepend_unwinder (gdbarch,
326 &microblaze_linux_sighandler_tramp_frame);
327+
328+ /* Enable TLS support. */
329+ set_gdbarch_fetch_tls_load_module_address (gdbarch,
330+ svr4_fetch_objfile_link_map);
331 }
332
333 void _initialize_microblaze_linux_tdep ();
334diff --git a/gdb/microblaze-tdep.c b/gdb/microblaze-tdep.c
335index c263228856f..28c2ed9a74c 100644
336--- a/gdb/microblaze-tdep.c
337+++ b/gdb/microblaze-tdep.c
338@@ -137,7 +137,38 @@ microblaze_fetch_instruction (CORE_ADDR pc)
339 constexpr gdb_byte microblaze_break_insn[] = MICROBLAZE_BREAKPOINT;
340
341 typedef BP_MANIPULATION (microblaze_break_insn) microblaze_breakpoint;
342-
343+static int
344+microblaze_linux_memory_remove_breakpoint (struct gdbarch *gdbarch,
345+ struct bp_target_info *bp_tgt)
346+{
347+ CORE_ADDR addr = bp_tgt->placed_address;
348+ const unsigned char *bp;
349+ int val;
350+ int bplen;
351+ gdb_byte old_contents[BREAKPOINT_MAX];
352+
353+ /* Determine appropriate breakpoint contents and size for this address. */
354+ bp = gdbarch_breakpoint_from_pc (gdbarch, &addr, &bplen);
355+ if (bp == NULL)
356+ error (_("Software breakpoints not implemented for this target."));
357+
358+ /* Make sure we see the memory breakpoints. */
359+ scoped_restore restore_memory
360+ = make_scoped_restore_show_memory_breakpoints (1);
361+
362+ val = target_read_memory (addr, old_contents, bplen);
363+
364+ /* If our breakpoint is no longer at the address, this means that the
365+ program modified the code on us, so it is wrong to put back the
366+ old value. */
367+ if (val == 0 && memcmp (bp, old_contents, bplen) == 0)
368+ {
369+ val = target_write_raw_memory (addr, bp_tgt->shadow_contents, bplen);
370+ microblaze_debug ("microblaze_linux_memory_remove_breakpoint writing back to memory at addr 0x%lx\n", addr);
371+ }
372+
373+ return val;
374+}
375
376 /* Allocate and initialize a frame cache. */
377
378@@ -731,6 +762,7 @@ microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
379 microblaze_breakpoint::kind_from_pc);
380 set_gdbarch_sw_breakpoint_from_kind (gdbarch,
381 microblaze_breakpoint::bp_from_kind);
382+ set_gdbarch_memory_remove_breakpoint (gdbarch, microblaze_linux_memory_remove_breakpoint);
383
384 set_gdbarch_frame_args_skip (gdbarch, 8);
385
386@@ -771,4 +803,5 @@ When non-zero, microblaze specific debugging is enabled."),
387 NULL,
388 &setdebuglist, &showdebuglist);
389
390+
391 }
392diff --git a/gdb/microblaze-tdep.h b/gdb/microblaze-tdep.h
393index 08af0d191c5..8a429cbf001 100644
394--- a/gdb/microblaze-tdep.h
395+++ b/gdb/microblaze-tdep.h
396@@ -117,6 +117,8 @@ struct microblaze_frame_cache
397
398 /* MICROBLAZE_BREAKPOINT defines the breakpoint that should be used.
399 Only used for native debugging. */
400-#define MICROBLAZE_BREAKPOINT {0xb9, 0xcc, 0x00, 0x60}
401+#define MICROBLAZE_BREAKPOINT {0xba, 0x0c, 0x00, 0x18}
402+#define MICROBLAZE_BREAKPOINT_LE {0x18, 0x00, 0x0c, 0xba}
403+
404
405 #endif /* microblaze-tdep.h */
406diff --git a/gdb/regformats/reg-microblaze.dat b/gdb/regformats/reg-microblaze.dat
407new file mode 100644
408index 00000000000..bd8a4384424
409--- /dev/null
410+++ b/gdb/regformats/reg-microblaze.dat
411@@ -0,0 +1,41 @@
412+name:microblaze
413+expedite:r1,pc
414+32:r0
415+32:r1
416+32:r2
417+32:r3
418+32:r4
419+32:r5
420+32:r6
421+32:r7
422+32:r8
423+32:r9
424+32:r10
425+32:r11
426+32:r12
427+32:r13
428+32:r14
429+32:r15
430+32:r16
431+32:r17
432+32:r18
433+32:r19
434+32:r20
435+32:r21
436+32:r22
437+32:r23
438+32:r24
439+32:r25
440+32:r26
441+32:r27
442+32:r28
443+32:r29
444+32:r30
445+32:r31
446+32:pc
447+32:msr
448+32:ear
449+32:esr
450+32:fsr
451+32:slr
452+32:shr
453diff --git a/gdbserver/Makefile.in b/gdbserver/Makefile.in
454index 2bd3a578932..46b5a0c7c60 100644
455--- a/gdbserver/Makefile.in
456+++ b/gdbserver/Makefile.in
457@@ -184,7 +184,8 @@ SFILES = \
458 $(srcdir)/linux-ia64-low.cc \
459 $(srcdir)/linux-low.cc \
460 $(srcdir)/linux-m68k-low.cc \
461- $(srcdir)/linux-mips-low.cc \
462+ $(srcdir)/linux-microblaze-low.c \
463+ $(srcdir)/linux-mips-low.cc \
464 $(srcdir)/linux-nios2-low.cc \
465 $(srcdir)/linux-ppc-low.cc \
466 $(srcdir)/linux-riscv-low.cc \
467@@ -221,6 +222,7 @@ SFILES = \
468 $(srcdir)/../gdb/nat/linux-namespaces.c \
469 $(srcdir)/../gdb/nat/linux-osdata.c \
470 $(srcdir)/../gdb/nat/linux-personality.c \
471+ $(srcdir)/../gdb/nat/microblaze-linux.c \
472 $(srcdir)/../gdb/nat/mips-linux-watch.c \
473 $(srcdir)/../gdb/nat/ppc-linux.c \
474 $(srcdir)/../gdb/nat/riscv-linux-tdesc.c \
475@@ -562,6 +564,8 @@ target/%.o: ../gdb/target/%.c
476
477 %-generated.cc: ../gdb/regformats/rs6000/%.dat $(regdat_sh)
478 $(ECHO_REGDAT) $(SHELL) $(regdat_sh) $< $@
479+microblaze-linux.c : $(srcdir)/../regformats/reg-microblaze.dat $(regdat_sh)
480+ $(ECHO_REGDAT) $(SHELL) $(regdat_sh) $(srcdir)/../regformats/reg-microblaze.dat microblaze-linux.c
481
482 #
483 # Dependency tracking.
484diff --git a/gdbserver/configure.srv b/gdbserver/configure.srv
485index 0cb5072c8ab..9d68c24a92d 100644
486--- a/gdbserver/configure.srv
487+++ b/gdbserver/configure.srv
488@@ -166,6 +166,14 @@ case "${gdbserver_host}" in
489 srv_linux_usrregs=yes
490 srv_linux_thread_db=yes
491 ;;
492+ microblaze*-*-linux*) srv_regobj="microblaze-linux.o"
493+ srv_tgtobj="linux-low.o linux-osdata.o linux-microblaze-low.o "
494+ srv_tgtobj="${srv_tgtobj} linux-procfs.o linux-ptrace.o"
495+ srv_xmlfiles="microblaze-linux.xml"
496+ srv_linux_regsets=yes
497+ srv_linux_usrregs=yes
498+ srv_linux_thread_db=yes
499+ ;;
500 powerpc*-*-linux*) srv_regobj="powerpc-32l.o"
501 srv_regobj="${srv_regobj} powerpc-altivec32l.o"
502 srv_regobj="${srv_regobj} powerpc-vsx32l.o"
503--
5042.17.1
505