blob: f840cafe2eb179cba7d921b2d3938ff6c0693ea9 [file] [log] [blame]
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001From 215486b53a7a6dfca064cd2e9196a9de6ed6f0c2 Mon Sep 17 00:00:00 2001
Patrick Williamsc0f7c042017-02-23 20:41:17 -06002From: Khem Raj <raj.khem@gmail.com>
3Date: Mon, 2 Mar 2015 02:31:12 +0000
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08004Subject: [PATCH 05/11] Add support for Renesas SH (sh4) architecture.
Patrick Williamsc0f7c042017-02-23 20:41:17 -06005
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---
Brad Bishopd7bf8c12018-02-25 22:55:05 -050016 gdb/Makefile.in | 2 +
Patrick Williamsc0f7c042017-02-23 20:41:17 -060017 gdb/configure.host | 1 +
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080018 gdb/sh-linux-tdep.c | 519 +++++++++++++++++++++++++++
19 gdb/sh-tdep.c | 53 ++-
20 gdb/sh-tdep.h | 49 +++
Patrick Williamsc0f7c042017-02-23 20:41:17 -060021 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 +
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080027 11 files changed, 617 insertions(+), 29 deletions(-)
Patrick Williamsc0f7c042017-02-23 20:41:17 -060028
29diff --git a/gdb/Makefile.in b/gdb/Makefile.in
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080030index c76a4e4394..921fdadb49 100644
Patrick Williamsc0f7c042017-02-23 20:41:17 -060031--- a/gdb/Makefile.in
32+++ b/gdb/Makefile.in
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080033@@ -2326,6 +2326,8 @@ ALLDEPFILES = \
34 sh-nbsd-nat.c \
Brad Bishopd7bf8c12018-02-25 22:55:05 -050035 sh-nbsd-tdep.c \
36 sh-tdep.c \
Brad Bishopd7bf8c12018-02-25 22:55:05 -050037+ sh-linux-tdep.c \
38+ sh-linux-nat.c \
Patrick Williamsc0f7c042017-02-23 20:41:17 -060039 sol2-tdep.c \
Brad Bishopd7bf8c12018-02-25 22:55:05 -050040 solib-aix.c \
41 solib-spu.c \
Patrick Williamsc0f7c042017-02-23 20:41:17 -060042diff --git a/gdb/configure.host b/gdb/configure.host
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080043index 23a2f16399..39a886ec53 100644
Patrick Williamsc0f7c042017-02-23 20:41:17 -060044--- a/gdb/configure.host
45+++ b/gdb/configure.host
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080046@@ -153,6 +153,7 @@ riscv*-*-linux*) gdb_host=linux ;;
Patrick Williamsc0f7c042017-02-23 20:41:17 -060047
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
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080055index db93967910..4109c549e8 100644
Patrick Williamsc0f7c042017-02-23 20:41:17 -060056--- 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@@ -180,9 +203,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
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800603index fe64cf979a..4417114cd0 100644
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600604--- 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"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800616@@ -66,23 +69,6 @@ static const char *const sh_cc_enum[] = {
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600617
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 {
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800640@@ -1050,7 +1036,7 @@ sh_treat_as_flt_p (struct type *type)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600641 return 0;
642 /* Otherwise if the type of that member is float, the whole type is
643 treated as float. */
644- if (TYPE_CODE (TYPE_FIELD_TYPE (type, 0)) == TYPE_CODE_FLT)
645+ if (TYPE_CODE (check_typedef (TYPE_FIELD_TYPE (type, 0))) == TYPE_CODE_FLT)
646 return 1;
647 /* Otherwise it's not treated as float. */
648 return 0;
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800649@@ -1100,7 +1086,7 @@ sh_push_dummy_call_fpu (struct gdbarch *gdbarch,
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600650 in four registers available. Loop thru args from first to last. */
651 for (argnum = 0; argnum < nargs; argnum++)
652 {
653- type = value_type (args[argnum]);
654+ type = check_typedef (value_type (args[argnum]));
655 len = TYPE_LENGTH (type);
656 val = sh_justify_value_in_reg (gdbarch, args[argnum], len);
657
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800658@@ -1834,7 +1820,7 @@ sh_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum,
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600659 reg->how = DWARF2_FRAME_REG_UNDEFINED;
660 }
661
662-static struct sh_frame_cache *
663+struct sh_frame_cache *
664 sh_alloc_frame_cache (void)
665 {
666 struct sh_frame_cache *cache;
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800667@@ -1861,7 +1847,7 @@ sh_alloc_frame_cache (void)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600668 return cache;
669 }
670
671-static struct sh_frame_cache *
672+struct sh_frame_cache *
673 sh_frame_cache (struct frame_info *this_frame, void **this_cache)
674 {
675 struct gdbarch *gdbarch = get_frame_arch (this_frame);
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800676@@ -1928,9 +1914,9 @@ sh_frame_cache (struct frame_info *this_frame, void **this_cache)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600677 return cache;
678 }
679
680-static struct value *
681-sh_frame_prev_register (struct frame_info *this_frame,
682- void **this_cache, int regnum)
683+struct value *
684+sh_frame_prev_register (struct frame_info *this_frame, void **this_cache,
685+ int regnum)
686 {
687 struct gdbarch *gdbarch = get_frame_arch (this_frame);
688 struct sh_frame_cache *cache = sh_frame_cache (this_frame, this_cache);
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800689@@ -1944,7 +1930,7 @@ sh_frame_prev_register (struct frame_info *this_frame,
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600690 the current frame. Frob regnum so that we pull the value from
691 the correct place. */
692 if (regnum == gdbarch_pc_regnum (gdbarch))
693- regnum = PR_REGNUM;
694+ regnum = PR_REGNUM; /* XXX: really? */
695
696 if (regnum < SH_NUM_REGS && cache->saved_regs[regnum] != -1)
697 return frame_unwind_got_memory (this_frame, regnum,
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800698@@ -2255,8 +2241,8 @@ sh_return_in_first_hidden_param_p (struct gdbarch *gdbarch,
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600699 static struct gdbarch *
700 sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
701 {
702- struct gdbarch *gdbarch;
703 struct gdbarch_tdep *tdep;
704+ struct gdbarch *gdbarch;
705
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800706 /* If there is already a candidate, use it. */
707 arches = gdbarch_list_lookup_by_info (arches, &info);
708@@ -2268,6 +2254,18 @@ sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600709 tdep = XCNEW (struct gdbarch_tdep);
710 gdbarch = gdbarch_alloc (&info, tdep);
711
712+ /* General-purpose registers. */
713+ tdep->gregset = NULL;
714+ tdep->gregset_reg_offset = NULL;
715+ tdep->gregset_num_regs = 23;
716+ tdep->sizeof_gregset = 0;
717+
718+ /* Floating-point registers. */
719+ tdep->fpregset = NULL;
720+ tdep->sizeof_fpregset = 34*4;
721+
722+ tdep->jb_pc_offset = -1;
723+
724 set_gdbarch_short_bit (gdbarch, 2 * TARGET_CHAR_BIT);
725 set_gdbarch_int_bit (gdbarch, 4 * TARGET_CHAR_BIT);
726 set_gdbarch_long_bit (gdbarch, 4 * TARGET_CHAR_BIT);
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800727@@ -2422,10 +2420,11 @@ sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600728 break;
729 }
730
731+ dwarf2_append_unwinders (gdbarch);
732+
733 /* Hook in ABI-specific overrides, if they have been registered. */
734 gdbarch_init_osabi (info, gdbarch);
735
736- dwarf2_append_unwinders (gdbarch);
737 frame_unwind_append_unwinder (gdbarch, &sh_stub_unwind);
738 frame_unwind_append_unwinder (gdbarch, &sh_frame_unwind);
739
740diff --git a/gdb/sh-tdep.h b/gdb/sh-tdep.h
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800741index 59acd35b88..be3f998d84 100644
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600742--- a/gdb/sh-tdep.h
743+++ b/gdb/sh-tdep.h
744@@ -21,6 +21,12 @@
745
746 /* Contributed by Steve Chamberlain sac@cygnus.com. */
747
748+struct frame_info;
749+struct gdbarch;
750+struct reggroup;
751+struct regset;
752+struct regcache;
753+
754 /* Registers for all SH variants. Used also by sh3-rom.c. */
755 enum
756 {
757@@ -29,6 +35,7 @@ enum
758 ARG0_REGNUM = 4,
759 ARGLAST_REGNUM = 7,
760 FP_REGNUM = 14,
761+ SP_REGNUM = 15,
762 PC_REGNUM = 16,
763 PR_REGNUM = 17,
764 GBR_REGNUM = 18,
765@@ -81,6 +88,24 @@ enum
766 FV0_REGNUM = 76,
767 FV_LAST_REGNUM = 79
768 };
769+#define SH_NUM_REGS 67
770+
771+struct sh_frame_cache
772+{
773+ /* Base address. */
774+ CORE_ADDR base;
775+ LONGEST sp_offset;
776+ CORE_ADDR pc;
777+
778+ /* Flag showing that a frame has been created in the prologue code. */
779+ int uses_fp;
780+
781+ /* Saved registers. */
782+ CORE_ADDR saved_regs[SH_NUM_REGS];
783+ CORE_ADDR saved_sp;
784+};
785+
786+extern struct sh_frame_cache *sh_frame_cache (struct frame_info *next_frame, void **this_cache);
787
788 /* This structure describes a register in a core-file. */
789 struct sh_corefile_regmap
790@@ -89,8 +114,32 @@ struct sh_corefile_regmap
791 unsigned int offset;
792 };
793
794+/* sh architecture specific information. */
795 struct gdbarch_tdep
796 {
797+ /* General-purpose registers. */
798+ struct regset *gregset;
799+ int *gregset_reg_offset;
800+ int gregset_num_regs;
801+ size_t sizeof_gregset;
802+
803+ /* Floating-point registers. */
804+ struct regset *fpregset;
805+ size_t sizeof_fpregset;
806+
807+ /* Offset of saved PC in jmp_buf. */
808+ int jb_pc_offset;
809+
810+ /* Detect sigtramp. */
811+ int (*sigtramp_p) (struct frame_info *);
812+
813+ /* Get address of sigcontext for sigtramp. */
814+ CORE_ADDR (*sigcontext_addr) (struct frame_info *);
815+
816+ /* Offset of registers in `struct sigcontext'. */
817+ int *sc_reg_offset;
818+ int sc_num_regs;
819+
820 /* Non-NULL when debugging from a core file. Provides the offset
821 where each general-purpose register is stored inside the associated
822 core file section. */
823diff --git a/gdb/testsuite/gdb.asm/asm-source.exp b/gdb/testsuite/gdb.asm/asm-source.exp
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800824index 9879f0ca47..cbc0e4d5f7 100644
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600825--- a/gdb/testsuite/gdb.asm/asm-source.exp
826+++ b/gdb/testsuite/gdb.asm/asm-source.exp
827@@ -116,6 +116,11 @@ switch -glob -- [istarget] {
828 append link-flags " -m elf32ppc"
829 }
830 }
831+ "sh*-linux*" {
832+ set asm-arch sh-linux
833+ set asm-flags "-I${srcdir}/${subdir} -I${objdir}/${subdir}"
834+ set debug-flags "-gdwarf-2"
835+ }
836 "sh*-*-*" {
837 set asm-arch sh
838 set debug-flags "-gdwarf-2"
839diff --git a/gdb/testsuite/gdb.asm/sh.inc b/gdb/testsuite/gdb.asm/sh.inc
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500840index a4a5fc545e..89efed7795 100644
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600841--- a/gdb/testsuite/gdb.asm/sh.inc
842+++ b/gdb/testsuite/gdb.asm/sh.inc
843@@ -40,9 +40,8 @@
844 mov.l .Lconst\@,r1
845 bra .Lafterconst\@
846 nop
847- nop
848-.Lconst\@:
849 .align 2
850+.Lconst\@:
851 .long \subr
852 .align 1
853 .Lafterconst\@:
854diff --git a/gdb/testsuite/gdb.base/annota1.c b/gdb/testsuite/gdb.base/annota1.c
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500855index 424e1b8327..0de2e7b633 100644
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600856--- a/gdb/testsuite/gdb.base/annota1.c
857+++ b/gdb/testsuite/gdb.base/annota1.c
858@@ -1,6 +1,9 @@
859 #include <stdio.h>
860 #include <signal.h>
861
862+#ifdef __sh__
863+#define signal(a,b) /* Signals not supported on this target - make them go away */
864+#endif
865
866 void
867 handle_USR1 (int sig)
868diff --git a/gdb/testsuite/gdb.base/annota3.c b/gdb/testsuite/gdb.base/annota3.c
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500869index 424e1b8327..952aaf218a 100644
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600870--- a/gdb/testsuite/gdb.base/annota3.c
871+++ b/gdb/testsuite/gdb.base/annota3.c
872@@ -1,6 +1,10 @@
873 #include <stdio.h>
874 #include <signal.h>
875
876+#ifdef __sh__
877+#define signal(a,b) /* Signals not supported on this target - make them go away */
878+#endif
879+
880
881 void
882 handle_USR1 (int sig)
883diff --git a/gdb/testsuite/gdb.base/sigall.c b/gdb/testsuite/gdb.base/sigall.c
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500884index 81f3b08d6b..1574b2d6cb 100644
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600885--- a/gdb/testsuite/gdb.base/sigall.c
886+++ b/gdb/testsuite/gdb.base/sigall.c
887@@ -1,6 +1,9 @@
888 #include <signal.h>
889 #include <unistd.h>
890
891+#ifdef __sh__
892+#define signal(a,b) /* Signals not supported on this target - make them go away */
893+#endif
894
895 /* Signal handlers, we set breakpoints in them to make sure that the
896 signals really get delivered. */
897diff --git a/gdb/testsuite/gdb.base/signals.c b/gdb/testsuite/gdb.base/signals.c
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500898index 756606880f..1205a9bc9c 100644
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600899--- a/gdb/testsuite/gdb.base/signals.c
900+++ b/gdb/testsuite/gdb.base/signals.c
901@@ -3,6 +3,10 @@
902 #include <signal.h>
903 #include <unistd.h>
904
905+#ifdef __sh__
906+#define signal(a,b) /* Signals not supported on this target - make them go away */
907+#define alarm(a) /* Ditto for alarm() */
908+#endif
909
910 static int count = 0;
911
912--
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08009132.18.0
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600914