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