blob: cb1b7abd0712e6cbb4d004e857b04ead53df3fc6 [file] [log] [blame]
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001From 60ac68f601885ea6480229a5c8a89a0257da376c 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
4Subject: [PATCH 05/10] 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---
Brad Bishopd7bf8c12018-02-25 22:55:05 -050016 gdb/Makefile.in | 2 +
Patrick Williamsc0f7c042017-02-23 20:41:17 -060017 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 +
Brad Bishopd7bf8c12018-02-25 22:55:05 -050027 11 files changed, 618 insertions(+), 29 deletions(-)
Patrick Williamsc0f7c042017-02-23 20:41:17 -060028
29diff --git a/gdb/Makefile.in b/gdb/Makefile.in
Brad Bishopd7bf8c12018-02-25 22:55:05 -050030index 8be73ba423..e287ff6a2e 100644
Patrick Williamsc0f7c042017-02-23 20:41:17 -060031--- a/gdb/Makefile.in
32+++ b/gdb/Makefile.in
Brad Bishopd7bf8c12018-02-25 22:55:05 -050033@@ -2638,6 +2638,8 @@ ALLDEPFILES = \
34 sh-nbsd-tdep.c \
35 sh-tdep.c \
36 sh64-tdep.c \
37+ 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 Bishopd7bf8c12018-02-25 22:55:05 -050043index d74fd04934..be12de1446 100644
Patrick Williamsc0f7c042017-02-23 20:41:17 -060044--- a/gdb/configure.host
45+++ b/gdb/configure.host
Brad Bishopd7bf8c12018-02-25 22:55:05 -050046@@ -150,6 +150,7 @@ powerpc*-*-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 Bishopd7bf8c12018-02-25 22:55:05 -050055index c5c745d218..84e539aad3 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 Bishopd7bf8c12018-02-25 22:55:05 -0500603index 2c2b26847d..14f5281ed4 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"
616@@ -35,6 +38,7 @@
617 #include "arch-utils.h"
618 #include "floatformat.h"
619 #include "regcache.h"
620+#include "regset.h"
621 #include "doublest.h"
622 #include "osabi.h"
623 #include "reggroups.h"
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500624@@ -68,23 +72,6 @@ static const char *const sh_cc_enum[] = {
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600625
626 static const char *sh_active_calling_convention = sh_cc_gcc;
627
628-#define SH_NUM_REGS 67
629-
630-struct sh_frame_cache
631-{
632- /* Base address. */
633- CORE_ADDR base;
634- LONGEST sp_offset;
635- CORE_ADDR pc;
636-
637- /* Flag showing that a frame has been created in the prologue code. */
638- int uses_fp;
639-
640- /* Saved registers. */
641- CORE_ADDR saved_regs[SH_NUM_REGS];
642- CORE_ADDR saved_sp;
643-};
644-
645 static int
646 sh_is_renesas_calling_convention (struct type *func_type)
647 {
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500648@@ -1052,7 +1039,7 @@ sh_treat_as_flt_p (struct type *type)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600649 return 0;
650 /* Otherwise if the type of that member is float, the whole type is
651 treated as float. */
652- if (TYPE_CODE (TYPE_FIELD_TYPE (type, 0)) == TYPE_CODE_FLT)
653+ if (TYPE_CODE (check_typedef (TYPE_FIELD_TYPE (type, 0))) == TYPE_CODE_FLT)
654 return 1;
655 /* Otherwise it's not treated as float. */
656 return 0;
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500657@@ -1102,7 +1089,7 @@ sh_push_dummy_call_fpu (struct gdbarch *gdbarch,
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600658 in four registers available. Loop thru args from first to last. */
659 for (argnum = 0; argnum < nargs; argnum++)
660 {
661- type = value_type (args[argnum]);
662+ type = check_typedef (value_type (args[argnum]));
663 len = TYPE_LENGTH (type);
664 val = sh_justify_value_in_reg (gdbarch, args[argnum], len);
665
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500666@@ -1828,7 +1815,7 @@ sh_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum,
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600667 reg->how = DWARF2_FRAME_REG_UNDEFINED;
668 }
669
670-static struct sh_frame_cache *
671+struct sh_frame_cache *
672 sh_alloc_frame_cache (void)
673 {
674 struct sh_frame_cache *cache;
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500675@@ -1855,7 +1842,7 @@ sh_alloc_frame_cache (void)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600676 return cache;
677 }
678
679-static struct sh_frame_cache *
680+struct sh_frame_cache *
681 sh_frame_cache (struct frame_info *this_frame, void **this_cache)
682 {
683 struct gdbarch *gdbarch = get_frame_arch (this_frame);
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500684@@ -1922,9 +1909,9 @@ sh_frame_cache (struct frame_info *this_frame, void **this_cache)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600685 return cache;
686 }
687
688-static struct value *
689-sh_frame_prev_register (struct frame_info *this_frame,
690- void **this_cache, int regnum)
691+struct value *
692+sh_frame_prev_register (struct frame_info *this_frame, void **this_cache,
693+ int regnum)
694 {
695 struct gdbarch *gdbarch = get_frame_arch (this_frame);
696 struct sh_frame_cache *cache = sh_frame_cache (this_frame, this_cache);
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500697@@ -1938,7 +1925,7 @@ sh_frame_prev_register (struct frame_info *this_frame,
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600698 the current frame. Frob regnum so that we pull the value from
699 the correct place. */
700 if (regnum == gdbarch_pc_regnum (gdbarch))
701- regnum = PR_REGNUM;
702+ regnum = PR_REGNUM; /* XXX: really? */
703
704 if (regnum < SH_NUM_REGS && cache->saved_regs[regnum] != -1)
705 return frame_unwind_got_memory (this_frame, regnum,
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500706@@ -2247,8 +2234,8 @@ sh_return_in_first_hidden_param_p (struct gdbarch *gdbarch,
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600707 static struct gdbarch *
708 sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
709 {
710- struct gdbarch *gdbarch;
711 struct gdbarch_tdep *tdep;
712+ struct gdbarch *gdbarch;
713
714 /* SH5 is handled entirely in sh64-tdep.c. */
715 if (info.bfd_arch_info->mach == bfd_mach_sh5)
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500716@@ -2264,6 +2251,18 @@ sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600717 tdep = XCNEW (struct gdbarch_tdep);
718 gdbarch = gdbarch_alloc (&info, tdep);
719
720+ /* General-purpose registers. */
721+ tdep->gregset = NULL;
722+ tdep->gregset_reg_offset = NULL;
723+ tdep->gregset_num_regs = 23;
724+ tdep->sizeof_gregset = 0;
725+
726+ /* Floating-point registers. */
727+ tdep->fpregset = NULL;
728+ tdep->sizeof_fpregset = 34*4;
729+
730+ tdep->jb_pc_offset = -1;
731+
732 set_gdbarch_short_bit (gdbarch, 2 * TARGET_CHAR_BIT);
733 set_gdbarch_int_bit (gdbarch, 4 * TARGET_CHAR_BIT);
734 set_gdbarch_long_bit (gdbarch, 4 * TARGET_CHAR_BIT);
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500735@@ -2418,10 +2417,11 @@ sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600736 break;
737 }
738
739+ dwarf2_append_unwinders (gdbarch);
740+
741 /* Hook in ABI-specific overrides, if they have been registered. */
742 gdbarch_init_osabi (info, gdbarch);
743
744- dwarf2_append_unwinders (gdbarch);
745 frame_unwind_append_unwinder (gdbarch, &sh_stub_unwind);
746 frame_unwind_append_unwinder (gdbarch, &sh_frame_unwind);
747
748diff --git a/gdb/sh-tdep.h b/gdb/sh-tdep.h
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500749index d15ef050e0..c4642cefa4 100644
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600750--- a/gdb/sh-tdep.h
751+++ b/gdb/sh-tdep.h
752@@ -21,6 +21,12 @@
753
754 /* Contributed by Steve Chamberlain sac@cygnus.com. */
755
756+struct frame_info;
757+struct gdbarch;
758+struct reggroup;
759+struct regset;
760+struct regcache;
761+
762 /* Registers for all SH variants. Used also by sh3-rom.c. */
763 enum
764 {
765@@ -29,6 +35,7 @@ enum
766 ARG0_REGNUM = 4,
767 ARGLAST_REGNUM = 7,
768 FP_REGNUM = 14,
769+ SP_REGNUM = 15,
770 PC_REGNUM = 16,
771 PR_REGNUM = 17,
772 GBR_REGNUM = 18,
773@@ -81,6 +88,24 @@ enum
774 FV0_REGNUM = 76,
775 FV_LAST_REGNUM = 79
776 };
777+#define SH_NUM_REGS 67
778+
779+struct sh_frame_cache
780+{
781+ /* Base address. */
782+ CORE_ADDR base;
783+ LONGEST sp_offset;
784+ CORE_ADDR pc;
785+
786+ /* Flag showing that a frame has been created in the prologue code. */
787+ int uses_fp;
788+
789+ /* Saved registers. */
790+ CORE_ADDR saved_regs[SH_NUM_REGS];
791+ CORE_ADDR saved_sp;
792+};
793+
794+extern struct sh_frame_cache *sh_frame_cache (struct frame_info *next_frame, void **this_cache);
795
796 /* This structure describes a register in a core-file. */
797 struct sh_corefile_regmap
798@@ -89,8 +114,32 @@ struct sh_corefile_regmap
799 unsigned int offset;
800 };
801
802+/* sh architecture specific information. */
803 struct gdbarch_tdep
804 {
805+ /* General-purpose registers. */
806+ struct regset *gregset;
807+ int *gregset_reg_offset;
808+ int gregset_num_regs;
809+ size_t sizeof_gregset;
810+
811+ /* Floating-point registers. */
812+ struct regset *fpregset;
813+ size_t sizeof_fpregset;
814+
815+ /* Offset of saved PC in jmp_buf. */
816+ int jb_pc_offset;
817+
818+ /* Detect sigtramp. */
819+ int (*sigtramp_p) (struct frame_info *);
820+
821+ /* Get address of sigcontext for sigtramp. */
822+ CORE_ADDR (*sigcontext_addr) (struct frame_info *);
823+
824+ /* Offset of registers in `struct sigcontext'. */
825+ int *sc_reg_offset;
826+ int sc_num_regs;
827+
828 /* Non-NULL when debugging from a core file. Provides the offset
829 where each general-purpose register is stored inside the associated
830 core file section. */
831diff --git a/gdb/testsuite/gdb.asm/asm-source.exp b/gdb/testsuite/gdb.asm/asm-source.exp
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500832index e07e5543f2..f5e60e1002 100644
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600833--- a/gdb/testsuite/gdb.asm/asm-source.exp
834+++ b/gdb/testsuite/gdb.asm/asm-source.exp
835@@ -116,6 +116,11 @@ switch -glob -- [istarget] {
836 append link-flags " -m elf32ppc"
837 }
838 }
839+ "sh*-linux*" {
840+ set asm-arch sh-linux
841+ set asm-flags "-I${srcdir}/${subdir} -I${objdir}/${subdir}"
842+ set debug-flags "-gdwarf-2"
843+ }
844 "sh*-*-*" {
845 set asm-arch sh
846 set debug-flags "-gdwarf-2"
847diff --git a/gdb/testsuite/gdb.asm/sh.inc b/gdb/testsuite/gdb.asm/sh.inc
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500848index a4a5fc545e..89efed7795 100644
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600849--- a/gdb/testsuite/gdb.asm/sh.inc
850+++ b/gdb/testsuite/gdb.asm/sh.inc
851@@ -40,9 +40,8 @@
852 mov.l .Lconst\@,r1
853 bra .Lafterconst\@
854 nop
855- nop
856-.Lconst\@:
857 .align 2
858+.Lconst\@:
859 .long \subr
860 .align 1
861 .Lafterconst\@:
862diff --git a/gdb/testsuite/gdb.base/annota1.c b/gdb/testsuite/gdb.base/annota1.c
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500863index 424e1b8327..0de2e7b633 100644
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600864--- a/gdb/testsuite/gdb.base/annota1.c
865+++ b/gdb/testsuite/gdb.base/annota1.c
866@@ -1,6 +1,9 @@
867 #include <stdio.h>
868 #include <signal.h>
869
870+#ifdef __sh__
871+#define signal(a,b) /* Signals not supported on this target - make them go away */
872+#endif
873
874 void
875 handle_USR1 (int sig)
876diff --git a/gdb/testsuite/gdb.base/annota3.c b/gdb/testsuite/gdb.base/annota3.c
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500877index 424e1b8327..952aaf218a 100644
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600878--- a/gdb/testsuite/gdb.base/annota3.c
879+++ b/gdb/testsuite/gdb.base/annota3.c
880@@ -1,6 +1,10 @@
881 #include <stdio.h>
882 #include <signal.h>
883
884+#ifdef __sh__
885+#define signal(a,b) /* Signals not supported on this target - make them go away */
886+#endif
887+
888
889 void
890 handle_USR1 (int sig)
891diff --git a/gdb/testsuite/gdb.base/sigall.c b/gdb/testsuite/gdb.base/sigall.c
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500892index 81f3b08d6b..1574b2d6cb 100644
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600893--- a/gdb/testsuite/gdb.base/sigall.c
894+++ b/gdb/testsuite/gdb.base/sigall.c
895@@ -1,6 +1,9 @@
896 #include <signal.h>
897 #include <unistd.h>
898
899+#ifdef __sh__
900+#define signal(a,b) /* Signals not supported on this target - make them go away */
901+#endif
902
903 /* Signal handlers, we set breakpoints in them to make sure that the
904 signals really get delivered. */
905diff --git a/gdb/testsuite/gdb.base/signals.c b/gdb/testsuite/gdb.base/signals.c
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500906index 756606880f..1205a9bc9c 100644
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600907--- a/gdb/testsuite/gdb.base/signals.c
908+++ b/gdb/testsuite/gdb.base/signals.c
909@@ -3,6 +3,10 @@
910 #include <signal.h>
911 #include <unistd.h>
912
913+#ifdef __sh__
914+#define signal(a,b) /* Signals not supported on this target - make them go away */
915+#define alarm(a) /* Ditto for alarm() */
916+#endif
917
918 static int count = 0;
919
920--
Brad Bishopd7bf8c12018-02-25 22:55:05 -05009212.13.1
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600922