summaryrefslogtreecommitdiffstats
path: root/recipes-devtools/gdb/files/0001-Add-initial-port-of-linux-gdbserver.patch
diff options
context:
space:
mode:
authorNathan Rossi <nathan.rossi@xilinx.com>2013-12-16 16:48:36 +1000
committerNathan Rossi <nathan.rossi@xilinx.com>2013-12-16 16:48:36 +1000
commit74f73159e5c659d8ee52a3d48238932b36e4fe93 (patch)
tree824b4a830e733161d055a12d6993dc6c8cd45da3 /recipes-devtools/gdb/files/0001-Add-initial-port-of-linux-gdbserver.patch
parent3ec0d044ea0c5fca26eecc0335bb9847871255ea (diff)
downloadmeta-xilinx-74f73159e5c659d8ee52a3d48238932b36e4fe93.tar.gz
gdb: Add MicroBlaze support
* Import Xilinx gdb patches for MicroBlaze * Disable dependence on LTTng-UST for MicroBlaze, it is not supported Signed-off-by: Nathan Rossi <nathan.rossi@xilinx.com>
Diffstat (limited to 'recipes-devtools/gdb/files/0001-Add-initial-port-of-linux-gdbserver.patch')
-rw-r--r--recipes-devtools/gdb/files/0001-Add-initial-port-of-linux-gdbserver.patch471
1 files changed, 471 insertions, 0 deletions
diff --git a/recipes-devtools/gdb/files/0001-Add-initial-port-of-linux-gdbserver.patch b/recipes-devtools/gdb/files/0001-Add-initial-port-of-linux-gdbserver.patch
new file mode 100644
index 00000000..5c195538
--- /dev/null
+++ b/recipes-devtools/gdb/files/0001-Add-initial-port-of-linux-gdbserver.patch
@@ -0,0 +1,471 @@
1From: David Holsgrove <david.holsgrove@petalogix.com>
2Date: Mon, 6 Feb 2012 10:28:29 +1000
3Subject: Add initial port of linux gdbserver
4
5add 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>
22Upstream-Status: Pending
23---
24 gdb/configure.host | 3 +
25 gdb/gdbserver/linux-microblaze-low.c | 228 ++++++++++++++++++++++++++++++++++
26 gdb/microblaze-linux-tdep.c | 30 ++++-
27 gdb/microblaze-tdep.c | 35 ++++++
28 gdb/microblaze-tdep.h | 3 +-
29 gdb/regformats/reg-microblaze.dat | 39 ++++++
30 6 files changed, 336 insertions(+), 2 deletions(-)
31 create mode 100644 gdb/gdbserver/linux-microblaze-low.c
32 create mode 100644 gdb/regformats/reg-microblaze.dat
33
34diff --git a/gdb/configure.host b/gdb/configure.host
35index 85f4491..98b0f43 100644
36--- a/gdb/configure.host
37+++ b/gdb/configure.host
38@@ -47,6 +47,7 @@ i[34567]86*) gdb_host_cpu=i386 ;;
39 m68*) gdb_host_cpu=m68k ;;
40 m88*) gdb_host_cpu=m88k ;;
41 mips*) gdb_host_cpu=mips ;;
42+microblaze*) gdb_host_cpu=microblaze ;;
43 powerpc* | rs6000) gdb_host_cpu=powerpc ;;
44 sparcv9 | sparc64) gdb_host_cpu=sparc ;;
45 s390*) gdb_host_cpu=s390 ;;
46@@ -126,6 +127,8 @@ mips*-*-netbsd* | mips*-*-knetbsd*-gnu)
47 gdb_host=nbsd ;;
48 mips64*-*-openbsd*) gdb_host=obsd64 ;;
49
50+microblaze*-*linux*) gdb_host=linux ;;
51+
52 powerpc-*-aix* | rs6000-*-*)
53 gdb_host=aix ;;
54 powerpc*-*-freebsd*) gdb_host=fbsd ;;
55diff --git a/gdb/gdbserver/linux-microblaze-low.c b/gdb/gdbserver/linux-microblaze-low.c
56new file mode 100644
57index 0000000..279df9f
58--- /dev/null
59+++ b/gdb/gdbserver/linux-microblaze-low.c
60@@ -0,0 +1,228 @@
61+/* GNU/Linux/Microblaze specific low level interface, for the remote server for
62+ GDB.
63+ Copyright (C) 1995-2013 Free Software Foundation, Inc.
64+
65+ This file is part of GDB.
66+
67+ This program is free software; you can redistribute it and/or modify
68+ it under the terms of the GNU General Public License as published by
69+ the Free Software Foundation; either version 3 of the License, or
70+ (at your option) any later version.
71+
72+ This program is distributed in the hope that it will be useful,
73+ but WITHOUT ANY WARRANTY; without even the implied warranty of
74+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
75+ GNU General Public License for more details.
76+
77+ You should have received a copy of the GNU General Public License
78+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
79+
80+#include "server.h"
81+#include "linux-low.h"
82+
83+#include <asm/ptrace.h>
84+#include <sys/procfs.h>
85+#include <sys/ptrace.h>
86+
87+#include "gdb_proc_service.h"
88+
89+static int microblaze_regmap[] =
90+ {PT_GPR(0), PT_GPR(1), PT_GPR(2), PT_GPR(3),
91+ PT_GPR(4), PT_GPR(5), PT_GPR(6), PT_GPR(7),
92+ PT_GPR(8), PT_GPR(9), PT_GPR(10), PT_GPR(11),
93+ PT_GPR(12), PT_GPR(13), PT_GPR(14), PT_GPR(15),
94+ PT_GPR(16), PT_GPR(17), PT_GPR(18), PT_GPR(19),
95+ PT_GPR(20), PT_GPR(21), PT_GPR(22), PT_GPR(23),
96+ PT_GPR(24), PT_GPR(25), PT_GPR(26), PT_GPR(27),
97+ PT_GPR(28), PT_GPR(29), PT_GPR(30), PT_GPR(31),
98+ PT_PC, PT_MSR, PT_EAR, PT_ESR,
99+ PT_FSR
100+ };
101+
102+#define microblaze_num_regs (sizeof microblaze_regmap / sizeof microblaze_regmap[0])
103+
104+/* Defined in auto-generated file microblaze-linux.c. */
105+void init_registers_microblaze (void);
106+extern const struct target_desc *tdesc_microblaze;
107+
108+static int
109+microblaze_cannot_store_register (int regno)
110+{
111+ if (microblaze_regmap[regno] == -1 || regno == 0)
112+ return 1;
113+
114+ return 0;
115+}
116+
117+static int
118+microblaze_cannot_fetch_register (int regno)
119+{
120+ return 0;
121+}
122+
123+static CORE_ADDR
124+microblaze_get_pc (struct regcache *regcache)
125+{
126+ unsigned long pc;
127+
128+ collect_register_by_name (regcache, "pc", &pc);
129+ return (CORE_ADDR) pc;
130+}
131+
132+static void
133+microblaze_set_pc (struct regcache *regcache, CORE_ADDR pc)
134+{
135+ unsigned long newpc = pc;
136+
137+ supply_register_by_name (regcache, "pc", &newpc);
138+}
139+
140+/* dbtrap insn */
141+/* brki r16, 0x18; */
142+static const unsigned long microblaze_breakpoint = 0xba0c0018;
143+#define microblaze_breakpoint_len 4
144+
145+static int
146+microblaze_breakpoint_at (CORE_ADDR where)
147+{
148+ unsigned long insn;
149+
150+ (*the_target->read_memory) (where, (unsigned char *) &insn, 4);
151+ if (insn == microblaze_breakpoint)
152+ return 1;
153+ /* If necessary, recognize more trap instructions here. GDB only uses the
154+ one. */
155+ return 0;
156+}
157+
158+static CORE_ADDR
159+microblaze_reinsert_addr (struct regcache *regcache)
160+{
161+ unsigned long pc;
162+ collect_register_by_name (regcache, "r15", &pc);
163+ return pc;
164+}
165+
166+#ifdef HAVE_PTRACE_GETREGS
167+
168+static void
169+microblaze_collect_ptrace_register (struct regcache *regcache, int regno, char *buf)
170+{
171+ int size = register_size (regcache->tdesc, regno);
172+
173+ memset (buf, 0, sizeof (long));
174+
175+ if (size < sizeof (long))
176+ collect_register (regcache, regno, buf + sizeof (long) - size);
177+ else
178+ collect_register (regcache, regno, buf);
179+}
180+
181+static void
182+microblaze_supply_ptrace_register (struct regcache *regcache,
183+ int regno, const char *buf)
184+{
185+ int size = register_size (regcache->tdesc, regno);
186+
187+ if (regno == 0) {
188+ unsigned long regbuf_0 = 0;
189+ /* clobbering r0 so that it is always 0 as enforced by hardware */
190+ supply_register (regcache, regno, (const char*)&regbuf_0);
191+ } else {
192+ if (size < sizeof (long))
193+ supply_register (regcache, regno, buf + sizeof (long) - size);
194+ else
195+ supply_register (regcache, regno, buf);
196+ }
197+}
198+
199+/* Provide only a fill function for the general register set. ps_lgetregs
200+ will use this for NPTL support. */
201+
202+static void microblaze_fill_gregset (struct regcache *regcache, void *buf)
203+{
204+ int i;
205+
206+ for (i = 0; i < 32; i++)
207+ microblaze_collect_ptrace_register (regcache, i, (char *) buf + microblaze_regmap[i]);
208+}
209+
210+static void
211+microblaze_store_gregset (struct regcache *regcache, const void *buf)
212+{
213+ int i;
214+
215+ for (i = 0; i < 32; i++)
216+ supply_register (regcache, i, (char *) buf + microblaze_regmap[i]);
217+}
218+
219+#endif /* HAVE_PTRACE_GETREGS */
220+
221+static struct regset_info microblaze_regsets[] = {
222+#ifdef HAVE_PTRACE_GETREGS
223+ { PTRACE_GETREGS, PTRACE_SETREGS, 0, sizeof (elf_gregset_t), GENERAL_REGS, microblaze_fill_gregset, microblaze_store_gregset },
224+ { 0, 0, 0, -1, -1, NULL, NULL },
225+#endif /* HAVE_PTRACE_GETREGS */
226+ { 0, 0, 0, -1, -1, NULL, NULL }
227+};
228+
229+static struct regsets_info microblaze_regsets_info =
230+ {
231+ microblaze_regsets, /* regsets */
232+ 0, /* num_regsets */
233+ NULL, /* disabled_regsets */
234+ };
235+
236+static struct usrregs_info microblaze_usrregs_info =
237+ {
238+ microblaze_num_regs,
239+ microblaze_regmap,
240+ };
241+
242+static struct regs_info regs_info =
243+ {
244+ NULL, /* regset_bitmap */
245+ &microblaze_usrregs_info,
246+ &microblaze_regsets_info
247+ };
248+
249+static const struct regs_info *
250+microblaze_regs_info (void)
251+{
252+ return &regs_info;
253+}
254+
255+static void
256+microblaze_arch_setup (void)
257+{
258+ current_process ()->tdesc = tdesc_microblaze;
259+}
260+
261+struct linux_target_ops the_low_target = {
262+ microblaze_arch_setup,
263+ microblaze_regs_info,
264+ microblaze_cannot_fetch_register,
265+ microblaze_cannot_store_register,
266+ NULL, /* fetch_register */
267+ microblaze_get_pc,
268+ microblaze_set_pc,
269+ (const unsigned char *) &microblaze_breakpoint,
270+ microblaze_breakpoint_len,
271+ microblaze_reinsert_addr,
272+ 0,
273+ microblaze_breakpoint_at,
274+ NULL,
275+ NULL,
276+ NULL,
277+ NULL,
278+ microblaze_collect_ptrace_register,
279+ microblaze_supply_ptrace_register,
280+};
281+
282+void
283+initialize_low_arch (void)
284+{
285+ init_registers_microblaze ();
286+
287+ initialize_regsets_info (&microblaze_regsets_info);
288+}
289\ No newline at end of file
290diff --git a/gdb/microblaze-linux-tdep.c b/gdb/microblaze-linux-tdep.c
291index 99fc497..69c333e 100644
292--- a/gdb/microblaze-linux-tdep.c
293+++ b/gdb/microblaze-linux-tdep.c
294@@ -37,6 +37,22 @@
295 #include "tramp-frame.h"
296 #include "linux-tdep.h"
297
298+static int microblaze_debug_flag = 0;
299+
300+static void
301+microblaze_debug (const char *fmt, ...)
302+{
303+ if (microblaze_debug_flag)
304+ {
305+ va_list args;
306+
307+ va_start (args, fmt);
308+ printf_unfiltered ("MICROBLAZE LINUX: ");
309+ vprintf_unfiltered (fmt, args);
310+ va_end (args);
311+ }
312+}
313+
314 static int
315 microblaze_linux_memory_remove_breakpoint (struct gdbarch *gdbarch,
316 struct bp_target_info *bp_tgt)
317@@ -46,20 +62,27 @@ microblaze_linux_memory_remove_breakpoint (struct gdbarch *gdbarch,
318 int val;
319 int bplen;
320 gdb_byte old_contents[BREAKPOINT_MAX];
321+ struct cleanup *cleanup;
322
323 /* Determine appropriate breakpoint contents and size for this address. */
324 bp = gdbarch_breakpoint_from_pc (gdbarch, &addr, &bplen);
325 if (bp == NULL)
326 error (_("Software breakpoints not implemented for this target."));
327
328+ /* Make sure we see the memory breakpoints. */
329+ cleanup = make_show_memory_breakpoints_cleanup (1);
330 val = target_read_memory (addr, old_contents, bplen);
331
332 /* If our breakpoint is no longer at the address, this means that the
333 program modified the code on us, so it is wrong to put back the
334 old value. */
335 if (val == 0 && memcmp (bp, old_contents, bplen) == 0)
336- val = target_write_raw_memory (addr, bp_tgt->shadow_contents, bplen);
337+ {
338+ val = target_write_raw_memory (addr, bp_tgt->shadow_contents, bplen);
339+ microblaze_debug ("microblaze_linux_memory_remove_breakpoint writing back to memory at addr 0x%lx\n", addr);
340+ }
341
342+ do_cleanups (cleanup);
343 return val;
344 }
345
346@@ -135,6 +158,11 @@ microblaze_linux_init_abi (struct gdbarch_info info,
347 /* Trampolines. */
348 tramp_frame_prepend_unwinder (gdbarch,
349 &microblaze_linux_sighandler_tramp_frame);
350+
351+ /* Enable TLS support. */
352+ set_gdbarch_fetch_tls_load_module_address (gdbarch,
353+ svr4_fetch_objfile_link_map);
354+
355 }
356
357 /* -Wmissing-prototypes */
358diff --git a/gdb/microblaze-tdep.c b/gdb/microblaze-tdep.c
359index dcf556f..079d34e 100644
360--- a/gdb/microblaze-tdep.c
361+++ b/gdb/microblaze-tdep.c
362@@ -157,6 +157,39 @@ microblaze_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
363 return sp;
364 }
365
366+static int
367+microblaze_linux_memory_remove_breakpoint (struct gdbarch *gdbarch,
368+ struct bp_target_info *bp_tgt)
369+{
370+ CORE_ADDR addr = bp_tgt->placed_address;
371+ const unsigned char *bp;
372+ int val;
373+ int bplen;
374+ gdb_byte old_contents[BREAKPOINT_MAX];
375+ struct cleanup *cleanup;
376+
377+ /* Determine appropriate breakpoint contents and size for this address. */
378+ bp = gdbarch_breakpoint_from_pc (gdbarch, &addr, &bplen);
379+ if (bp == NULL)
380+ error (_("Software breakpoints not implemented for this target."));
381+
382+ /* Make sure we see the memory breakpoints. */
383+ cleanup = make_show_memory_breakpoints_cleanup (1);
384+ val = target_read_memory (addr, old_contents, bplen);
385+
386+ /* If our breakpoint is no longer at the address, this means that the
387+ program modified the code on us, so it is wrong to put back the
388+ old value. */
389+ if (val == 0 && memcmp (bp, old_contents, bplen) == 0)
390+ {
391+ val = target_write_raw_memory (addr, bp_tgt->shadow_contents, bplen);
392+ microblaze_debug ("microblaze_linux_memory_remove_breakpoint writing back to memory at addr 0x%lx\n", addr);
393+ }
394+
395+ do_cleanups (cleanup);
396+ return val;
397+}
398+
399 static const gdb_byte *
400 microblaze_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pc,
401 int *len)
402@@ -707,6 +740,8 @@ microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
403 /* Stack grows downward. */
404 set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
405
406+ set_gdbarch_memory_remove_breakpoint (gdbarch, microblaze_linux_memory_remove_breakpoint);
407+
408 set_gdbarch_breakpoint_from_pc (gdbarch, microblaze_breakpoint_from_pc);
409
410 set_gdbarch_frame_args_skip (gdbarch, 8);
411diff --git a/gdb/microblaze-tdep.h b/gdb/microblaze-tdep.h
412index ff4515e..9fdbda7 100644
413--- a/gdb/microblaze-tdep.h
414+++ b/gdb/microblaze-tdep.h
415@@ -115,6 +115,7 @@ enum microblaze_regnum
416
417 /* MICROBLAZE_BREAKPOINT defines the breakpoint that should be used.
418 Only used for native debugging. */
419-#define MICROBLAZE_BREAKPOINT {0xb9, 0xcc, 0x00, 0x60}
420+#define MICROBLAZE_BREAKPOINT {0xba, 0x0c, 0x00, 0x18}
421+#define MICROBLAZE_BREAKPOINT_LE {0x18, 0x00, 0x0c, 0xba}
422
423 #endif /* microblaze-tdep.h */
424diff --git a/gdb/regformats/reg-microblaze.dat b/gdb/regformats/reg-microblaze.dat
425new file mode 100644
426index 0000000..a5dd0a0
427--- /dev/null
428+++ b/gdb/regformats/reg-microblaze.dat
429@@ -0,0 +1,39 @@
430+name:microblaze
431+expedite:r1,pc
432+32:r0
433+32:r1
434+32:r2
435+32:r3
436+32:r4
437+32:r5
438+32:r6
439+32:r7
440+32:r8
441+32:r9
442+32:r10
443+32:r11
444+32:r12
445+32:r13
446+32:r14
447+32:r15
448+32:r16
449+32:r17
450+32:r18
451+32:r19
452+32:r20
453+32:r21
454+32:r22
455+32:r23
456+32:r24
457+32:r25
458+32:r26
459+32:r27
460+32:r28
461+32:r29
462+32:r30
463+32:r31
464+32:pc
465+32:msr
466+32:ear
467+32:esr
468+32:fsr
469--
4701.7.9.5
471