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