blob: 4a3e22c4458607ed0f80c245801deb0e81a04f32 [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001From 407cb13cfb70697f45dfb761304e005e1ecbd0e9 Mon Sep 17 00:00:00 2001
2From: Khem Raj <raj.khem@gmail.com>
3Date: Mon, 2 Mar 2015 02:31:12 +0000
4Subject: [PATCH 3/3] Add support for Renesas SH (sh4) architecture.
5
6gdb (7.4-1~cvs20111117.2) experimental; urgency=low
7 .
8 * Add Renesas SH (sh4) support (Closes: #576242)
9 - Thanks Nobuhiro Iwamatsu, Takashi Yoshii.
10Author: Hector Oron <zumbi@debian.org>
11Bug-Debian: http://bugs.debian.org/576242
12
13Upstream-Status: Pending
14Signed-off-by: Khem Raj <raj.khem@gmail.com>
15---
16 gdb/Makefile.in | 1 +
17 gdb/configure.host | 1 +
18 gdb/sh-linux-tdep.c | 519 +++++++++++++++++++++++++++++++++++
19 gdb/sh-tdep.c | 54 ++--
20 gdb/sh-tdep.h | 49 ++++
21 gdb/testsuite/gdb.asm/asm-source.exp | 5 +
22 gdb/testsuite/gdb.asm/sh.inc | 3 +-
23 gdb/testsuite/gdb.base/annota1.c | 3 +
24 gdb/testsuite/gdb.base/annota3.c | 4 +
25 gdb/testsuite/gdb.base/sigall.c | 3 +
26 gdb/testsuite/gdb.base/signals.c | 4 +
27 11 files changed, 617 insertions(+), 29 deletions(-)
28
29diff --git a/gdb/Makefile.in b/gdb/Makefile.in
30index 7937801..63baf81 100644
31--- a/gdb/Makefile.in
32+++ b/gdb/Makefile.in
33@@ -1707,6 +1707,7 @@ ALLDEPFILES = \
34 score-tdep.c \
35 ser-go32.c ser-pipe.c ser-tcp.c ser-mingw.c \
36 sh-tdep.c sh64-tdep.c shnbsd-tdep.c shnbsd-nat.c \
37+ sh-linux-tdep.c sh-linux-nat.c \
38 sol2-tdep.c \
39 solib-svr4.c \
40 sparc-linux-nat.c sparc-linux-tdep.c \
41diff --git a/gdb/configure.host b/gdb/configure.host
42index d07be4b..b6391c5 100644
43--- a/gdb/configure.host
44+++ b/gdb/configure.host
45@@ -150,6 +150,7 @@ powerpc*-*-linux*) gdb_host=linux ;;
46
47 s390*-*-linux*) gdb_host=linux ;;
48
49+sh*-*-linux*) gdb_host=linux ;;
50 sh*-*-netbsdelf* | sh*-*-knetbsd*-gnu)
51 gdb_host=nbsd ;;
52 sh*-*-openbsd*) gdb_host=nbsd ;;
53diff --git a/gdb/sh-linux-tdep.c b/gdb/sh-linux-tdep.c
54index 2ff2ee8..1a11262 100644
55--- a/gdb/sh-linux-tdep.c
56+++ b/gdb/sh-linux-tdep.c
57@@ -18,14 +18,37 @@
58 along with this program. If not, see <http://www.gnu.org/licenses/>. */
59
60 #include "defs.h"
61+#include "gdbcore.h"
62+#include "frame.h"
63+#include "frame-base.h"
64+#include "frame-unwind.h"
65+#include "dwarf2-frame.h"
66+#include "value.h"
67+#include "regcache.h"
68+#include "inferior.h"
69 #include "osabi.h"
70
71+#include "reggroups.h"
72+#include "arch-utils.h"
73+#include "floatformat.h"
74 #include "solib-svr4.h"
75 #include "symtab.h"
76+#include "gdb_string.h"
77+#include "command.h"
78+#include "gdb_assert.h"
79
80 #include "trad-frame.h"
81 #include "tramp-frame.h"
82
83+#include <sys/ptrace.h>
84+#include <sys/types.h>
85+#include <sys/param.h>
86+#include <sys/user.h>
87+#include <sys/syscall.h>
88+
89+#include <asm/ptrace.h>
90+
91+#include "regset.h"
92 #include "glibc-tdep.h"
93 #include "sh-tdep.h"
94 #include "linux-tdep.h"
95@@ -180,9 +203,505 @@ static struct tramp_frame sh_linux_rt_sigreturn_tramp_frame = {
96 sh_linux_rt_sigreturn_init
97 };
98
99+/* Recognizing signal handler frames. */
100+
101+/* GNU/Linux has two flavors of signals. Normal signal handlers, and
102+ "realtime" (RT) signals. The RT signals can provide additional
103+ information to the signal handler if the SA_SIGINFO flag is set
104+ when establishing a signal handler using `sigaction'. It is not
105+ unlikely that future versions of GNU/Linux will support SA_SIGINFO
106+ for normal signals too. */
107+
108+/* When the SH Linux kernel calls a signal handler and the
109+ SA_RESTORER flag isn't set, the return address points to a bit of
110+ code on the stack. This function returns whether the PC appears to
111+ be within this bit of code.
112+
113+ The instruction sequence for normal signals is
114+ mov.w 1f,r3
115+ trapa #16
116+ or r0, r0
117+ or r0, r0
118+ or r0, r0
119+ or r0, r0
120+ or r0, r0
121+ 1: .word __NR_sigreturn
122+ or 0x9305 0xc310 0x200b 0x200b 0x200b 0x200b 0x200b 0x0077.
123+
124+ Checking for the code sequence should be somewhat reliable, because
125+ the effect is to call the system call sigreturn. This is unlikely
126+ to occur anywhere other than a signal trampoline.
127+
128+ It kind of sucks that we have to read memory from the process in
129+ order to identify a signal trampoline, but there doesn't seem to be
130+ any other way. The PC_IN_SIGTRAMP macro in tm-linux.h arranges to
131+ only call us if no function name could be identified, which should
132+ be the case since the code is on the stack.
133+
134+ Detection of signal trampolines for handlers that set the
135+ SA_RESTORER flag is in general not possible. Unfortunately this is
136+ what the GNU C Library has been doing for quite some time now.
137+ However, as of version 2.1.2, the GNU C Library uses signal
138+ trampolines (named __restore and __restore_rt) that are identical
139+ to the ones used by the kernel. Therefore, these trampolines are
140+ supported too. */
141+
142+#define MOVW(n) (0x9300|((n)-2)) /* Move mem word at PC+n to R3 */
143+#define TRAP16 0xc310 /* Syscall w/no args (NR in R3) */
144+#define OR_R0_R0 0x200b /* or r0,r0 (insert to avoid hardware bug) */
145+
146+#define LINUX_SIGTRAMP_INSN0 MOVW(7) /* Move mem word at PC+7 to R3 */
147+#define LINUX_SIGTRAMP_INSN1 TRAP16 /* Syscall w/no args (NR in R3) */
148+#define LINUX_SIGTRAMP_INSN2 OR_R0_R0 /* or r0,r0 (insert to avoid hardware bug) */
149+
150+static const unsigned short linux_sigtramp_code[] =
151+{
152+ LINUX_SIGTRAMP_INSN0,
153+ LINUX_SIGTRAMP_INSN1,
154+ LINUX_SIGTRAMP_INSN2,
155+ LINUX_SIGTRAMP_INSN2,
156+ LINUX_SIGTRAMP_INSN2,
157+ LINUX_SIGTRAMP_INSN2,
158+ LINUX_SIGTRAMP_INSN2,
159+ __NR_sigreturn
160+};
161+
162+#define LINUX_SIGTRAMP_LEN (sizeof linux_sigtramp_code)
163+
164+/* If PC is in a sigtramp routine, return the address of the start of
165+ the routine. Otherwise, return 0. */
166+
167+static CORE_ADDR
168+sh_linux_sigtramp_start (struct frame_info *next_frame)
169+{
170+ CORE_ADDR pc = get_frame_pc (next_frame);
171+ gdb_byte buf[LINUX_SIGTRAMP_LEN];
172+
173+ /* We only recognize a signal trampoline if PC is at the start of
174+ one of the three instructions. We optimize for finding the PC at
175+ the start, as will be the case when the trampoline is not the
176+ first frame on the stack. We assume that in the case where the
177+ PC is not at the start of the instruction sequence, there will be
178+ a few trailing readable bytes on the stack. */
179+
180+ if (!safe_frame_unwind_memory (next_frame, pc, buf, LINUX_SIGTRAMP_LEN))
181+ return 0;
182+
183+ if (buf[0] != LINUX_SIGTRAMP_INSN0)
184+ {
185+ if (buf[0] != LINUX_SIGTRAMP_INSN1)
186+ return 0;
187+
188+ pc -= 2;
189+
190+ if (!safe_frame_unwind_memory (next_frame, pc, buf, LINUX_SIGTRAMP_LEN))
191+ return 0;
192+ }
193+
194+ if (memcmp (buf, linux_sigtramp_code, LINUX_SIGTRAMP_LEN) != 0)
195+ return 0;
196+
197+ return pc;
198+}
199+
200+/* This function does the same for RT signals. Here the instruction
201+ sequence is
202+ mov.w 1f,r3
203+ trapa #16
204+ or r0, r0
205+ or r0, r0
206+ or r0, r0
207+ or r0, r0
208+ or r0, r0
209+ 1: .word __NR_rt_sigreturn
210+ or 0x9305 0xc310 0x200b 0x200b 0x200b 0x200b 0x200b 0x00ad.
211+
212+ The effect is to call the system call rt_sigreturn. */
213+
214+#define LINUX_RT_SIGTRAMP_INSN0 MOVW(7) /* Move mem word at PC+7 to R3 */
215+#define LINUX_RT_SIGTRAMP_INSN1 TRAP16 /* Syscall w/no args (NR in R3) */
216+#define LINUX_RT_SIGTRAMP_INSN2 OR_R0_R0 /* or r0,r0 (insert to avoid hardware bug) */
217+
218+static const unsigned short linux_rt_sigtramp_code[] =
219+{
220+ LINUX_RT_SIGTRAMP_INSN0,
221+ LINUX_RT_SIGTRAMP_INSN1,
222+ LINUX_RT_SIGTRAMP_INSN2,
223+ LINUX_RT_SIGTRAMP_INSN2,
224+ LINUX_RT_SIGTRAMP_INSN2,
225+ LINUX_RT_SIGTRAMP_INSN2,
226+ LINUX_RT_SIGTRAMP_INSN2,
227+ __NR_rt_sigreturn
228+};
229+
230+#define LINUX_RT_SIGTRAMP_LEN (sizeof linux_rt_sigtramp_code)
231+
232+/* If PC is in a RT sigtramp routine, return the address of the start
233+ of the routine. Otherwise, return 0. */
234+
235+static CORE_ADDR
236+sh_linux_rt_sigtramp_start (struct frame_info *next_frame)
237+{
238+ CORE_ADDR pc = get_frame_pc (next_frame);
239+ gdb_byte buf[LINUX_RT_SIGTRAMP_LEN];
240+
241+ /* We only recognize a signal trampoline if PC is at the start of
242+ one of the two instructions. We optimize for finding the PC at
243+ the start, as will be the case when the trampoline is not the
244+ first frame on the stack. We assume that in the case where the
245+ PC is not at the start of the instruction sequence, there will be
246+ a few trailing readable bytes on the stack. */
247+
248+ if (!safe_frame_unwind_memory (next_frame, pc, buf, LINUX_RT_SIGTRAMP_LEN))
249+ return 0;
250+
251+ if (buf[0] != LINUX_RT_SIGTRAMP_INSN0)
252+ {
253+ if (buf[0] != LINUX_RT_SIGTRAMP_INSN1)
254+ return 0;
255+
256+ pc -= 2;
257+
258+ if (!safe_frame_unwind_memory (next_frame, pc, buf,
259+ LINUX_RT_SIGTRAMP_LEN))
260+ return 0;
261+ }
262+
263+ if (memcmp (buf, linux_rt_sigtramp_code, LINUX_RT_SIGTRAMP_LEN) != 0)
264+ return 0;
265+
266+ return pc;
267+}
268+
269+/* Return whether PC is in a GNU/Linux sigtramp routine. */
270+
271+static int
272+sh_linux_sigtramp_p (struct frame_info *this_frame)
273+{
274+ CORE_ADDR pc = get_frame_pc (this_frame);
275+ char *name;
276+
277+ find_pc_partial_function (pc, &name, NULL, NULL);
278+
279+ /* If we have NAME, we can optimize the search. The trampolines are
280+ named __restore and __restore_rt. However, they aren't dynamically
281+ exported from the shared C library, so the trampoline may appear to
282+ be part of the preceding function. This should always be sigaction,
283+ __sigaction, or __libc_sigaction (all aliases to the same function). */
284+ if (name == NULL || strstr (name, "sigaction") != NULL)
285+ return (sh_linux_sigtramp_start (this_frame) != 0
286+ || sh_linux_rt_sigtramp_start (this_frame) != 0);
287+
288+ return (strcmp ("__restore", name) == 0
289+ || strcmp ("__restore_rt", name) == 0);
290+}
291+
292+/* Offset to struct sigcontext in ucontext, from <asm/ucontext.h>. */
293+#define SH_LINUX_UCONTEXT_SIGCONTEXT_OFFSET 12
294+
295+
296+/* Assuming NEXT_FRAME is a frame following a GNU/Linux sigtramp
297+ routine, return the address of the associated sigcontext structure. */
298+
299+static CORE_ADDR
300+sh_linux_sigcontext_addr (struct frame_info *this_frame)
301+{
302+ CORE_ADDR pc;
303+ CORE_ADDR sp;
304+
305+ sp = get_frame_register_unsigned (this_frame, SP_REGNUM);
306+
307+ pc = sh_linux_sigtramp_start (this_frame);
308+ if (pc)
309+ {
310+ return sp;
311+ }
312+
313+ pc = sh_linux_rt_sigtramp_start (this_frame);
314+ if (pc)
315+ {
316+ CORE_ADDR ucontext_addr;
317+
318+ /* The sigcontext structure is part of the user context. A
319+ pointer to the user context is passed as the third argument
320+ to the signal handler. */
321+ ucontext_addr = get_frame_register_unsigned (this_frame, ARG0_REGNUM+2);
322+ return ucontext_addr + SH_LINUX_UCONTEXT_SIGCONTEXT_OFFSET;
323+ }
324+
325+ error ("Couldn't recognize signal trampoline.");
326+ return 0;
327+}
328+
329+/* Signal trampolines. */
330+extern struct sh_frame_cache *sh_alloc_frame_cache (void);
331+
332+static struct sh_frame_cache *
333+sh_linux_sigtramp_frame_cache (struct frame_info *this_frame, void **this_cache)
334+{
335+ struct sh_frame_cache *cache;
336+ struct gdbarch_tdep *tdep = gdbarch_tdep (get_current_arch ());
337+ CORE_ADDR sigcontext_addr;
338+
339+ if (*this_cache)
340+ return *this_cache;
341+
342+ cache = sh_alloc_frame_cache ();
343+
344+ cache->base = get_frame_register_unsigned (this_frame, SP_REGNUM);
345+ sigcontext_addr = tdep->sigcontext_addr (this_frame);
346+ if (tdep->sc_reg_offset)
347+ {
348+ int i;
349+
350+ gdb_assert (tdep->sc_num_regs <= SH_NUM_REGS);
351+
352+ for (i = 0; i < tdep->sc_num_regs; i++)
353+ if (tdep->sc_reg_offset[i] != -1)
354+ cache->saved_regs[i] = sigcontext_addr + tdep->sc_reg_offset[i];
355+ }
356+
357+ *this_cache = cache;
358+ return cache;
359+}
360+
361+static void
362+sh_linux_sigtramp_frame_this_id (struct frame_info *this_frame, void **this_cache,
363+ struct frame_id *this_id)
364+{
365+ struct sh_frame_cache *cache =
366+ sh_linux_sigtramp_frame_cache (this_frame, this_cache);
367+
368+ (*this_id) = frame_id_build (cache->base + 64, cache->pc);
369+}
370+
371+extern struct value * sh_frame_prev_register ();
372+static struct value *
373+sh_linux_sigtramp_frame_prev_register (struct frame_info *this_frame,
374+ void **this_cache, int regnum)
375+{
376+ sh_linux_sigtramp_frame_cache (this_frame, this_cache);
377+
378+ return sh_frame_prev_register (this_frame, this_cache, regnum);
379+}
380+
381+static int
382+sh_linux_sigtramp_frame_sniffer (const struct frame_unwind *self,
383+ struct frame_info *this_frame,
384+ void **this_prologue_cache)
385+{
386+ struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (this_frame));
387+
388+ /* We shouldn't even bother if we don't have a sigcontext_addr
389+ handler. */
390+ if (tdep->sigcontext_addr == NULL)
391+ return 0;
392+
393+ if (tdep->sigtramp_p != NULL)
394+ {
395+ if (tdep->sigtramp_p (this_frame))
396+ return 1;
397+ }
398+
399+ return 0;
400+}
401+
402+static const struct frame_unwind sh_linux_sigtramp_frame_unwind =
403+{
404+ SIGTRAMP_FRAME,
405+ sh_linux_sigtramp_frame_this_id,
406+ sh_linux_sigtramp_frame_prev_register,
407+ NULL,
408+ sh_linux_sigtramp_frame_sniffer
409+};
410+
411+/* Supply register REGNUM from the buffer specified by GREGS and LEN
412+ in the general-purpose register set REGSET to register cache
413+ REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
414+
415+void
416+sh_supply_gregset (const struct regset *regset, struct regcache *regcache,
417+ int regnum, const void *gregs, size_t len)
418+{
419+ const struct gdbarch_tdep *tdep = gdbarch_tdep (regset->arch);
420+ const char *regs = gregs;
421+ int i;
422+
423+ gdb_assert (len == tdep->sizeof_gregset);
424+
425+ for (i = 0; i < tdep->gregset_num_regs; i++)
426+ {
427+ if ((regnum == i || regnum == -1)
428+ && tdep->gregset_reg_offset[i] != -1)
429+ regcache_raw_supply (regcache, i, regs + tdep->gregset_reg_offset[i]);
430+ }
431+}
432+
433+/* Collect register REGNUM from the register cache REGCACHE and store
434+ it in the buffer specified by GREGS and LEN as described by the
435+ general-purpose register set REGSET. If REGNUM is -1, do this for
436+ all registers in REGSET. */
437+
438+void
439+sh_collect_gregset (const struct regset *regset,
440+ const struct regcache *regcache,
441+ int regnum, void *gregs, size_t len)
442+{
443+ const struct gdbarch_tdep *tdep = gdbarch_tdep (regset->arch);
444+ char *regs = gregs;
445+ int i;
446+
447+ gdb_assert (len == tdep->sizeof_gregset);
448+
449+ for (i = 0; i < tdep->gregset_num_regs; i++)
450+ {
451+ if ((regnum == i || regnum == -1)
452+ && tdep->gregset_reg_offset[i] != -1)
453+ regcache_raw_collect (regcache, i, regs + tdep->gregset_reg_offset[i]);
454+ }
455+}
456+
457+/* Supply register REGNUM from the buffer specified by FPREGS and LEN
458+ in the floating-point register set REGSET to register cache
459+ REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
460+
461+static void
462+sh_supply_fpregset (const struct regset *regset, struct regcache *regcache,
463+ int regnum, const void *fpregs, size_t len)
464+{
465+ const struct gdbarch_tdep *tdep = gdbarch_tdep (regset->arch);
466+ const char *regs = fpregs;
467+ int i;
468+
469+ gdb_assert (len == tdep->sizeof_fpregset);
470+ for (i = 0; i < 16; i++)
471+ {
472+ if (regnum == i+25 || regnum == -1)
473+ regcache_raw_supply (regcache, i+25, regs + i*4);
474+ }
475+ if (regnum == FPSCR_REGNUM || regnum == -1)
476+ regcache_raw_supply (regcache, FPSCR_REGNUM, regs + 32*4);
477+ if (regnum == FPUL_REGNUM || regnum == -1)
478+ regcache_raw_supply (regcache, FPUL_REGNUM, regs + 33*4);
479+}
480+
481+/* Collect register REGNUM from the register cache REGCACHE and store
482+ it in the buffer specified by FPREGS and LEN as described by the
483+ floating-point register set REGSET. If REGNUM is -1, do this for
484+ all registers in REGSET. */
485+
486+static void
487+sh_collect_fpregset (const struct regset *regset,
488+ const struct regcache *regcache,
489+ int regnum, void *fpregs, size_t len)
490+{
491+ const struct gdbarch_tdep *tdep = gdbarch_tdep (regset->arch);
492+ char *regs = fpregs;
493+ int i;
494+
495+ gdb_assert (len == tdep->sizeof_fpregset);
496+ for (i = 0; i < 16; i++)
497+ {
498+ if (regnum == i+25 || regnum == -1)
499+ regcache_raw_collect (regcache, i+25, regs + i*4);
500+ }
501+ if (regnum == FPSCR_REGNUM || regnum == -1)
502+ regcache_raw_collect (regcache, FPSCR_REGNUM, regs + 32*4);
503+ if (regnum == FPUL_REGNUM || regnum == -1)
504+ regcache_raw_collect (regcache, FPUL_REGNUM, regs + 33*4);
505+}
506+
507+/* Return the appropriate register set for the core section identified
508+ by SECT_NAME and SECT_SIZE. */
509+
510+const struct regset *
511+sh_linux_regset_from_core_section (struct gdbarch *gdbarch,
512+ const char *sect_name, size_t sect_size)
513+{
514+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
515+
516+ if (strcmp (sect_name, ".reg") == 0 && sect_size == tdep->sizeof_gregset)
517+ {
518+ if (tdep->gregset == NULL)
519+ tdep->gregset = regset_alloc (gdbarch, sh_supply_gregset,
520+ sh_collect_gregset);
521+ return tdep->gregset;
522+ }
523+
524+ if ((strcmp (sect_name, ".reg2") == 0 && sect_size == tdep->sizeof_fpregset))
525+ {
526+ if (tdep->fpregset == NULL)
527+ tdep->fpregset = regset_alloc (gdbarch, sh_supply_fpregset,
528+ sh_collect_fpregset);
529+ return tdep->fpregset;
530+ }
531+
532+ return NULL;
533+}
534+
535+/* The register sets used in GNU/Linux ELF core-dumps are identical to
536+ the register sets in `struct user' that are used for a.out
537+ core-dumps. These are also used by ptrace(2). The corresponding
538+ types are `elf_gregset_t' for the general-purpose registers (with
539+ `elf_greg_t' the type of a single GP register) and `elf_fpregset_t'
540+ for the floating-point registers.
541+
542+ Those types used to be available under the names `gregset_t' and
543+ `fpregset_t' too, and GDB used those names in the past. But those
544+ names are now used for the register sets used in the `mcontext_t'
545+ type, which have a different size and layout. */
546+
547+/* Mapping between the general-purpose registers in `struct user'
548+ format and GDB's register cache layout. */
549+
550+/* From <sys/reg.h>. */
551+static int sh_linux_gregset_reg_offset[] =
552+{
553+ 0, 4, 8, 12, 16, 20, 24, 28,
554+ 32, 36, 40, 44, 48, 52, 56, 60,
555+
556+ REG_PC*4, REG_PR*4, REG_GBR*4, -1,
557+ REG_MACH*4, REG_MACL*4, REG_SR*4,
558+};
559+
560+/* Mapping between the general-purpose registers in `struct
561+ sigcontext' format and GDB's register cache layout. */
562+
563+/* From <asm/sigcontext.h>. */
564+static int sh_linux_sc_reg_offset[] =
565+{
566+ 4, 8, 12, 16, 20, 24, 28, 32,
567+ 36, 40, 44, 48, 52, 56, 60, 64,
568+ 68, 72, 80, -1,
569+ 84, 88, 76
570+};
571+
572 static void
573 sh_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
574 {
575+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
576+ bfd abfd;
577+
578+ tdep->gregset_reg_offset = sh_linux_gregset_reg_offset;
579+ tdep->gregset_num_regs = ARRAY_SIZE (sh_linux_gregset_reg_offset);
580+ tdep->sizeof_gregset = 23 * 4;
581+
582+ tdep->jb_pc_offset = 32; /* From <bits/setjmp.h>. */
583+
584+ tdep->sigtramp_p = sh_linux_sigtramp_p;
585+ tdep->sigcontext_addr = sh_linux_sigcontext_addr;
586+ tdep->sc_reg_offset = sh_linux_sc_reg_offset;
587+ tdep->sc_num_regs = ARRAY_SIZE (sh_linux_sc_reg_offset);
588+
589+ frame_unwind_append_unwinder(gdbarch, &sh_linux_sigtramp_frame_unwind);
590+
591+ /* If we have a register mapping, enable the generic core file
592+ support, unless it has already been enabled. */
593+ if (tdep->gregset_reg_offset
594+ && !gdbarch_regset_from_core_section_p (gdbarch))
595+ set_gdbarch_regset_from_core_section (gdbarch,
596+ sh_linux_regset_from_core_section);
597+
598 linux_init_abi (info, gdbarch);
599
600 /* GNU/Linux uses SVR4-style shared libraries. */
601diff --git a/gdb/sh-tdep.c b/gdb/sh-tdep.c
602index 82cf2f4..b443e46 100644
603--- a/gdb/sh-tdep.c
604+++ b/gdb/sh-tdep.c
605@@ -21,6 +21,9 @@
606 sac@cygnus.com. */
607
608 #include "defs.h"
609+#include "arch-utils.h"
610+#include "command.h"
611+#include "dummy-frame.h"
612 #include "frame.h"
613 #include "frame-base.h"
614 #include "frame-unwind.h"
615@@ -35,6 +38,7 @@
616 #include "arch-utils.h"
617 #include "floatformat.h"
618 #include "regcache.h"
619+#include "regset.h"
620 #include "doublest.h"
621 #include "osabi.h"
622 #include "reggroups.h"
623@@ -67,23 +71,6 @@ static const char *const sh_cc_enum[] = {
624
625 static const char *sh_active_calling_convention = sh_cc_gcc;
626
627-#define SH_NUM_REGS 67
628-
629-struct sh_frame_cache
630-{
631- /* Base address. */
632- CORE_ADDR base;
633- LONGEST sp_offset;
634- CORE_ADDR pc;
635-
636- /* Flag showing that a frame has been created in the prologue code. */
637- int uses_fp;
638-
639- /* Saved registers. */
640- CORE_ADDR saved_regs[SH_NUM_REGS];
641- CORE_ADDR saved_sp;
642-};
643-
644 static int
645 sh_is_renesas_calling_convention (struct type *func_type)
646 {
647@@ -1043,7 +1030,7 @@ sh_treat_as_flt_p (struct type *type)
648 return 0;
649 /* Otherwise if the type of that member is float, the whole type is
650 treated as float. */
651- if (TYPE_CODE (TYPE_FIELD_TYPE (type, 0)) == TYPE_CODE_FLT)
652+ if (TYPE_CODE (check_typedef (TYPE_FIELD_TYPE (type, 0))) == TYPE_CODE_FLT)
653 return 1;
654 /* Otherwise it's not treated as float. */
655 return 0;
656@@ -1093,7 +1080,7 @@ sh_push_dummy_call_fpu (struct gdbarch *gdbarch,
657 in four registers available. Loop thru args from first to last. */
658 for (argnum = 0; argnum < nargs; argnum++)
659 {
660- type = value_type (args[argnum]);
661+ type = check_typedef (value_type (args[argnum]));
662 len = TYPE_LENGTH (type);
663 val = sh_justify_value_in_reg (gdbarch, args[argnum], len);
664
665@@ -1821,7 +1808,7 @@ sh_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum,
666 reg->how = DWARF2_FRAME_REG_UNDEFINED;
667 }
668
669-static struct sh_frame_cache *
670+struct sh_frame_cache *
671 sh_alloc_frame_cache (void)
672 {
673 struct sh_frame_cache *cache;
674@@ -1848,7 +1835,7 @@ sh_alloc_frame_cache (void)
675 return cache;
676 }
677
678-static struct sh_frame_cache *
679+struct sh_frame_cache *
680 sh_frame_cache (struct frame_info *this_frame, void **this_cache)
681 {
682 struct gdbarch *gdbarch = get_frame_arch (this_frame);
683@@ -1915,9 +1902,9 @@ sh_frame_cache (struct frame_info *this_frame, void **this_cache)
684 return cache;
685 }
686
687-static struct value *
688-sh_frame_prev_register (struct frame_info *this_frame,
689- void **this_cache, int regnum)
690+struct value *
691+sh_frame_prev_register (struct frame_info *this_frame, void **this_cache,
692+ int regnum)
693 {
694 struct gdbarch *gdbarch = get_frame_arch (this_frame);
695 struct sh_frame_cache *cache = sh_frame_cache (this_frame, this_cache);
696@@ -1931,7 +1918,7 @@ sh_frame_prev_register (struct frame_info *this_frame,
697 the current frame. Frob regnum so that we pull the value from
698 the correct place. */
699 if (regnum == gdbarch_pc_regnum (gdbarch))
700- regnum = PR_REGNUM;
701+ regnum = PR_REGNUM; /* XXX: really? */
702
703 if (regnum < SH_NUM_REGS && cache->saved_regs[regnum] != -1)
704 return frame_unwind_got_memory (this_frame, regnum,
705@@ -2237,8 +2224,8 @@ sh_return_in_first_hidden_param_p (struct gdbarch *gdbarch,
706 static struct gdbarch *
707 sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
708 {
709- struct gdbarch *gdbarch;
710 struct gdbarch_tdep *tdep;
711+ struct gdbarch *gdbarch;
712
713 /* SH5 is handled entirely in sh64-tdep.c. */
714 if (info.bfd_arch_info->mach == bfd_mach_sh5)
715@@ -2254,6 +2241,18 @@ sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
716 tdep = XCNEW (struct gdbarch_tdep);
717 gdbarch = gdbarch_alloc (&info, tdep);
718
719+ /* General-purpose registers. */
720+ tdep->gregset = NULL;
721+ tdep->gregset_reg_offset = NULL;
722+ tdep->gregset_num_regs = 23;
723+ tdep->sizeof_gregset = 0;
724+
725+ /* Floating-point registers. */
726+ tdep->fpregset = NULL;
727+ tdep->sizeof_fpregset = 34*4;
728+
729+ tdep->jb_pc_offset = -1;
730+
731 set_gdbarch_short_bit (gdbarch, 2 * TARGET_CHAR_BIT);
732 set_gdbarch_int_bit (gdbarch, 4 * TARGET_CHAR_BIT);
733 set_gdbarch_long_bit (gdbarch, 4 * TARGET_CHAR_BIT);
734@@ -2404,10 +2403,11 @@ sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
735 break;
736 }
737
738+ dwarf2_append_unwinders (gdbarch);
739+
740 /* Hook in ABI-specific overrides, if they have been registered. */
741 gdbarch_init_osabi (info, gdbarch);
742
743- dwarf2_append_unwinders (gdbarch);
744 frame_unwind_append_unwinder (gdbarch, &sh_stub_unwind);
745 frame_unwind_append_unwinder (gdbarch, &sh_frame_unwind);
746
747diff --git a/gdb/sh-tdep.h b/gdb/sh-tdep.h
748index fc671a5..699f59f 100644
749--- a/gdb/sh-tdep.h
750+++ b/gdb/sh-tdep.h
751@@ -21,6 +21,12 @@
752
753 /* Contributed by Steve Chamberlain sac@cygnus.com. */
754
755+struct frame_info;
756+struct gdbarch;
757+struct reggroup;
758+struct regset;
759+struct regcache;
760+
761 /* Registers for all SH variants. Used also by sh3-rom.c. */
762 enum
763 {
764@@ -29,6 +35,7 @@ enum
765 ARG0_REGNUM = 4,
766 ARGLAST_REGNUM = 7,
767 FP_REGNUM = 14,
768+ SP_REGNUM = 15,
769 PC_REGNUM = 16,
770 PR_REGNUM = 17,
771 GBR_REGNUM = 18,
772@@ -81,6 +88,24 @@ enum
773 FV0_REGNUM = 76,
774 FV_LAST_REGNUM = 79
775 };
776+#define SH_NUM_REGS 67
777+
778+struct sh_frame_cache
779+{
780+ /* Base address. */
781+ CORE_ADDR base;
782+ LONGEST sp_offset;
783+ CORE_ADDR pc;
784+
785+ /* Flag showing that a frame has been created in the prologue code. */
786+ int uses_fp;
787+
788+ /* Saved registers. */
789+ CORE_ADDR saved_regs[SH_NUM_REGS];
790+ CORE_ADDR saved_sp;
791+};
792+
793+extern struct sh_frame_cache *sh_frame_cache (struct frame_info *next_frame, void **this_cache);
794
795 /* This structure describes a register in a core-file. */
796 struct sh_corefile_regmap
797@@ -89,8 +114,32 @@ struct sh_corefile_regmap
798 unsigned int offset;
799 };
800
801+/* sh architecture specific information. */
802 struct gdbarch_tdep
803 {
804+ /* General-purpose registers. */
805+ struct regset *gregset;
806+ int *gregset_reg_offset;
807+ int gregset_num_regs;
808+ size_t sizeof_gregset;
809+
810+ /* Floating-point registers. */
811+ struct regset *fpregset;
812+ size_t sizeof_fpregset;
813+
814+ /* Offset of saved PC in jmp_buf. */
815+ int jb_pc_offset;
816+
817+ /* Detect sigtramp. */
818+ int (*sigtramp_p) (struct frame_info *);
819+
820+ /* Get address of sigcontext for sigtramp. */
821+ CORE_ADDR (*sigcontext_addr) (struct frame_info *);
822+
823+ /* Offset of registers in `struct sigcontext'. */
824+ int *sc_reg_offset;
825+ int sc_num_regs;
826+
827 /* Non-NULL when debugging from a core file. Provides the offset
828 where each general-purpose register is stored inside the associated
829 core file section. */
830diff --git a/gdb/testsuite/gdb.asm/asm-source.exp b/gdb/testsuite/gdb.asm/asm-source.exp
831index 8854af0..ef44682 100644
832--- a/gdb/testsuite/gdb.asm/asm-source.exp
833+++ b/gdb/testsuite/gdb.asm/asm-source.exp
834@@ -113,6 +113,11 @@ switch -glob -- [istarget] {
835 append link-flags " -m elf32ppc"
836 }
837 }
838+ "sh*-linux*" {
839+ set asm-arch sh-linux
840+ set asm-flags "-I${srcdir}/${subdir} -I${objdir}/${subdir}"
841+ set debug-flags "-gdwarf-2"
842+ }
843 "sh*-*-*" {
844 set asm-arch sh
845 set debug-flags "-gdwarf-2"
846diff --git a/gdb/testsuite/gdb.asm/sh.inc b/gdb/testsuite/gdb.asm/sh.inc
847index a4a5fc5..89efed7 100644
848--- a/gdb/testsuite/gdb.asm/sh.inc
849+++ b/gdb/testsuite/gdb.asm/sh.inc
850@@ -40,9 +40,8 @@
851 mov.l .Lconst\@,r1
852 bra .Lafterconst\@
853 nop
854- nop
855-.Lconst\@:
856 .align 2
857+.Lconst\@:
858 .long \subr
859 .align 1
860 .Lafterconst\@:
861diff --git a/gdb/testsuite/gdb.base/annota1.c b/gdb/testsuite/gdb.base/annota1.c
862index 424e1b8..0de2e7b 100644
863--- a/gdb/testsuite/gdb.base/annota1.c
864+++ b/gdb/testsuite/gdb.base/annota1.c
865@@ -1,6 +1,9 @@
866 #include <stdio.h>
867 #include <signal.h>
868
869+#ifdef __sh__
870+#define signal(a,b) /* Signals not supported on this target - make them go away */
871+#endif
872
873 void
874 handle_USR1 (int sig)
875diff --git a/gdb/testsuite/gdb.base/annota3.c b/gdb/testsuite/gdb.base/annota3.c
876index 424e1b8..952aaf2 100644
877--- a/gdb/testsuite/gdb.base/annota3.c
878+++ b/gdb/testsuite/gdb.base/annota3.c
879@@ -1,6 +1,10 @@
880 #include <stdio.h>
881 #include <signal.h>
882
883+#ifdef __sh__
884+#define signal(a,b) /* Signals not supported on this target - make them go away */
885+#endif
886+
887
888 void
889 handle_USR1 (int sig)
890diff --git a/gdb/testsuite/gdb.base/sigall.c b/gdb/testsuite/gdb.base/sigall.c
891index 81f3b08..1574b2d 100644
892--- a/gdb/testsuite/gdb.base/sigall.c
893+++ b/gdb/testsuite/gdb.base/sigall.c
894@@ -1,6 +1,9 @@
895 #include <signal.h>
896 #include <unistd.h>
897
898+#ifdef __sh__
899+#define signal(a,b) /* Signals not supported on this target - make them go away */
900+#endif
901
902 /* Signal handlers, we set breakpoints in them to make sure that the
903 signals really get delivered. */
904diff --git a/gdb/testsuite/gdb.base/signals.c b/gdb/testsuite/gdb.base/signals.c
905index 7566068..1205a9b 100644
906--- a/gdb/testsuite/gdb.base/signals.c
907+++ b/gdb/testsuite/gdb.base/signals.c
908@@ -3,6 +3,10 @@
909 #include <signal.h>
910 #include <unistd.h>
911
912+#ifdef __sh__
913+#define signal(a,b) /* Signals not supported on this target - make them go away */
914+#define alarm(a) /* Ditto for alarm() */
915+#endif
916
917 static int count = 0;
918
919--
9202.1.4
921