Codebase list gdb / 13f8687
Imported Debian patch 7.1-1+sh4 Nobuhiro Iwamatsu authored 14 years ago Hector Oron committed 12 years ago
3 changed file(s) with 1411 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
0 gdb (7.1-1+sh4) unreleased; urgency=low
1
2 * sh4 support.
3
4 -- Nobuhiro Iwamatsu <iwamatsu@debian.org> Thu, 25 Mar 2010 05:47:37 +0000
5
06 gdb (7.1-1) unstable; urgency=low
17
28 * New upstream release, including:
0 From 56915d38b2422deff54c90bd53ea03c834b3b513 Mon Sep 17 00:00:00 2001
1 From: Takashi YOSHII <yoshii.takashi@renesas.com>
2 Date: Mon, 8 Mar 2010 10:45:54 +0900
3 Subject: [PATCH] Add Renesas SuperH native support
4
5 ---
6 gdb/Makefile.in | 1 +
7 gdb/config/sh/linux.mh | 8 +
8 gdb/config/sh/nm-linux.h | 54 ++++
9 gdb/config/sh/xm-linux.h | 32 ++
10 gdb/configure.host | 1 +
11 gdb/sh-linux-nat.c | 269 ++++++++++++++++++
12 gdb/sh-linux-tdep.c | 519 ++++++++++++++++++++++++++++++++++
13 gdb/sh-tdep.c | 54 ++--
14 gdb/sh-tdep.h | 49 ++++
15 gdb/testsuite/gdb.asm/asm-source.exp | 5 +
16 gdb/testsuite/gdb.asm/sh-linux.inc | 78 +++++
17 gdb/testsuite/gdb.asm/sh.inc | 3 +-
18 gdb/testsuite/gdb.base/annota1.c | 6 +-
19 gdb/testsuite/gdb.base/annota3.c | 6 +-
20 gdb/testsuite/gdb.base/sigall.c | 6 +-
21 gdb/testsuite/gdb.base/signals.c | 8 +-
22 16 files changed, 1057 insertions(+), 42 deletions(-)
23 create mode 100644 gdb/config/sh/linux.mh
24 create mode 100644 gdb/config/sh/nm-linux.h
25 create mode 100644 gdb/config/sh/xm-linux.h
26 create mode 100644 gdb/sh-linux-nat.c
27 create mode 100644 gdb/testsuite/gdb.asm/sh-linux.inc
28
29 diff --git a/gdb/Makefile.in b/gdb/Makefile.in
30 index 72b546d..4325d5f 100644
31 --- a/gdb/Makefile.in
32 +++ b/gdb/Makefile.in
33 @@ -1476,6 +1476,7 @@ ALLDEPFILES = \
34 score-tdep.c \
35 ser-go32.c ser-pipe.c ser-tcp.c ser-mingw.c \
36 sh-tdep.c sh64-tdep.c shnbsd-tdep.c shnbsd-nat.c \
37 + sh-linux-tdep.c sh-linux-nat.c \
38 sol2-tdep.c \
39 solib-irix.c solib-svr4.c solib-sunos.c \
40 sparc-linux-nat.c sparc-linux-tdep.c \
41 diff --git a/gdb/config/sh/linux.mh b/gdb/config/sh/linux.mh
42 new file mode 100644
43 index 0000000..86fa8b9
44 --- /dev/null
45 +++ b/gdb/config/sh/linux.mh
46 @@ -0,0 +1,8 @@
47 +# Host: Renesas Super-H running GNU/Linux
48 +NAT_FILE= nm-linux.h
49 +NATDEPFILES= inf-ptrace.o fork-child.o corelow.o \
50 + sh-linux-nat.o \
51 + proc-service.o linux-thread-db.o gcore.o \
52 + linux-nat.o linux-fork.o
53 +
54 +LOADLIBES= -ldl -rdynamic
55 diff --git a/gdb/config/sh/nm-linux.h b/gdb/config/sh/nm-linux.h
56 new file mode 100644
57 index 0000000..4e6fd5a
58 --- /dev/null
59 +++ b/gdb/config/sh/nm-linux.h
60 @@ -0,0 +1,54 @@
61 +/* Native-dependent definitions for SuperH running Linux, for GDB.
62 + Copyright 2004 Free Software Foundation, Inc.
63 +
64 + This file is part of GDB.
65 +
66 + This program is free software; you can redistribute it and/or modify
67 + it under the terms of the GNU General Public License as published by
68 + the Free Software Foundation; either version 2 of the License, or
69 + (at your option) any later version.
70 +
71 + This program is distributed in the hope that it will be useful,
72 + but WITHOUT ANY WARRANTY; without even the implied warranty of
73 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
74 + GNU General Public License for more details.
75 +
76 + You should have received a copy of the GNU General Public License
77 + along with this program; if not, write to the Free Software
78 + Foundation, Inc., 59 Temple Place - Suite 330,
79 + Boston, MA 02111-1307, USA. */
80 +
81 +#ifndef NM_LINUX_H
82 +#define NM_LINUX_H
83 +
84 +/* Get generic Linux native definitions. */
85 +#include "config/nm-linux.h"
86 +/* Support for the user area. */
87 +
88 +/* Return the size of the user struct. */
89 +extern int kernel_u_size (void);
90 +#define KERNEL_U_SIZE kernel_u_size()
91 +
92 +/* This is the amount to substract from u.u_ar0 to get the offset in
93 + the core file of the register values. */
94 +#define KERNEL_U_ADDR 0
95 +
96 +#define U_REGS_OFFSET 0
97 +
98 +extern CORE_ADDR register_u_addr (CORE_ADDR blockend, int regnum);
99 +#define REGISTER_U_ADDR(addr, blockend, regnum) \
100 + (addr) = register_u_addr (blockend, regnum)
101 +
102 +/* Override copies of {fetch,store}_inferior_registers in `infptrace.c'. */
103 +#define FETCH_INFERIOR_REGISTERS
104 +
105 +/* Nevertheless, define CANNOT_{FETCH,STORE}_REGISTER, because we
106 + might fall back on the code `infptrace.c' (well a copy of that code
107 + in `sh-linux-nat.c' for now) and we can access only the
108 + general-purpose registers in that way. */
109 +extern int cannot_fetch_register (int regno);
110 +extern int cannot_store_register (int regno);
111 +#define CANNOT_FETCH_REGISTER(regno) cannot_fetch_register (regno)
112 +#define CANNOT_STORE_REGISTER(regno) cannot_store_register (regno)
113 +
114 +#endif /* NM_LINUX_H */
115 diff --git a/gdb/config/sh/xm-linux.h b/gdb/config/sh/xm-linux.h
116 new file mode 100644
117 index 0000000..6482093
118 --- /dev/null
119 +++ b/gdb/config/sh/xm-linux.h
120 @@ -0,0 +1,32 @@
121 +/* Native support for GNU/Linux, for GDB, the GNU debugger.
122 + Copyright (C) 2000 Free Software Foundation, Inc.
123 +
124 +This file is part of GDB.
125 +
126 +This program is free software; you can redistribute it and/or modify
127 +it under the terms of the GNU General Public License as published by
128 +the Free Software Foundation; either version 2 of the License, or
129 +(at your option) any later version.
130 +
131 +This program is distributed in the hope that it will be useful,
132 +but WITHOUT ANY WARRANTY; without even the implied warranty of
133 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
134 +GNU General Public License for more details.
135 +
136 +You should have received a copy of the GNU General Public License
137 +along with this program; if not, write to the Free Software
138 +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
139 +
140 +#ifndef XM_LINUX_H
141 +#define XM_LINUX_H
142 +
143 +#define HOST_BYTE_ORDER LITTLE_ENDIAN
144 +
145 +#define HAVE_TERMIOS
146 +
147 +#define NEED_POSIX_SETPGID
148 +
149 +/* Need R_OK etc, but USG isn't defined. */
150 +#include <unistd.h>
151 +
152 +#endif /* #ifndef XM_LINUX_H */
153 diff --git a/gdb/configure.host b/gdb/configure.host
154 index 794eeee..ebc209b 100644
155 --- a/gdb/configure.host
156 +++ b/gdb/configure.host
157 @@ -139,6 +139,7 @@ powerpc64-*-linux*) gdb_host=ppc64-linux
158
159 s390*-*-*) gdb_host=s390 ;;
160
161 +sh*-*-linux*) gdb_host=linux ;;
162 sh*-*-netbsdelf* | sh*-*-knetbsd*-gnu)
163 gdb_host=nbsd ;;
164 sh*-*-openbsd*) gdb_host=nbsd ;;
165 diff --git a/gdb/sh-linux-nat.c b/gdb/sh-linux-nat.c
166 new file mode 100644
167 index 0000000..18e423d
168 --- /dev/null
169 +++ b/gdb/sh-linux-nat.c
170 @@ -0,0 +1,269 @@
171 +/* Low level SH interface to ptrace, for GDB when running native.
172 + Copyright (C) 2002, 2004 Free Software Foundation, Inc.
173 +
174 +This file is part of GDB.
175 +
176 +This program is free software; you can redistribute it and/or modify
177 +it under the terms of the GNU General Public License as published by
178 +the Free Software Foundation; either version 2 of the License, or
179 +(at your option) any later version.
180 +
181 +This program is distributed in the hope that it will be useful,
182 +but WITHOUT ANY WARRANTY; without even the implied warranty of
183 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
184 +GNU General Public License for more details.
185 +
186 +You should have received a copy of the GNU General Public License
187 +along with this program; if not, write to the Free Software
188 +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
189 +
190 +#include "defs.h"
191 +#include "inferior.h"
192 +#include "gdbcore.h"
193 +#include "regcache.h"
194 +#include "linux-nat.h"
195 +#include "target.h"
196 +#include "arch-utils.h"
197 +
198 +#include "gdb_assert.h"
199 +#include "gdb_string.h"
200 +#include <sys/ptrace.h>
201 +#include <sys/user.h>
202 +#include <sys/procfs.h>
203 +#include <asm/ptrace.h>
204 +
205 +/* Prototypes for supply_gregset etc. */
206 +#include "gregset.h"
207 +#include "sh-tdep.h"
208 +
209 +/* Defines ps_err_e, struct ps_prochandle. */
210 +#include "gdb_proc_service.h"
211 +
212 +//#include <asm/elf.h>
213 +
214 +#define SH_LINUX_NUM_REGS 40
215 +/* This table must line up with REGISTER_NAME in "sh-tdep.c". */
216 +static const int regmap[] =
217 +{
218 + /* general registers 0-15 */
219 + REG_REG0 , REG_REG0+1 , REG_REG0+2 , REG_REG0+3,
220 + REG_REG0+4 , REG_REG0+5 , REG_REG0+6 , REG_REG0+7,
221 + REG_REG0+8 , REG_REG0+9 , REG_REG0+10, REG_REG0+11,
222 + REG_REG0+12, REG_REG0+13, REG_REG0+14, REG_REG0+15,
223 + /* 16 - 22 */
224 + REG_PC, REG_PR, REG_GBR, -1, REG_MACH, REG_MACL, REG_SR,
225 + /* 23, 24 */
226 + REG_FPUL, REG_FPSCR,
227 + /* floating point registers 25 - 40 */
228 + REG_FPREG0 , REG_FPREG0+1 , REG_FPREG0+2 , REG_FPREG0+3 ,
229 + REG_FPREG0+4 , REG_FPREG0+5 , REG_FPREG0+6 , REG_FPREG0+7 ,
230 + REG_FPREG0+8 , REG_FPREG0+9 , REG_FPREG0+10, REG_FPREG0+11,
231 + REG_FPREG0+12, REG_FPREG0+13, REG_FPREG0+14, REG_FPREG0+15,
232 +};
233 +
234 +CORE_ADDR
235 +register_u_addr (CORE_ADDR blockend, int regnum)
236 +{
237 + if (regnum < 0 || regnum >= sizeof regmap/sizeof regmap[0])
238 + return (CORE_ADDR)-1;
239 + return (blockend + 4 * regmap[regnum]);
240 +}
241 +
242 +
243 +/* Return the address in the core dump or inferior of register REGNO.
244 + BLOCKEND is the address of the end of the user structure. */
245 +
246 +CORE_ADDR
247 +register_addr (int regno, CORE_ADDR blockend)
248 +{
249 + CORE_ADDR addr;
250 +
251 + if (regno < 0 || regno >= SH_LINUX_NUM_REGS) {
252 + internal_error (__FILE__, __LINE__,
253 + _("Got request for bad register number %d."), regno);
254 + }
255 +
256 + REGISTER_U_ADDR (addr, blockend, regno);
257 +
258 + return addr;
259 +}
260 +
261 +/* Fetch one register. */
262 +
263 +static void
264 +fetch_register (struct regcache *regcache, int tid, int regno)
265 +{
266 + int val;
267 +
268 + if (cannot_fetch_register (regno))
269 + {
270 + regcache_raw_supply (regcache, regno, NULL);
271 + return;
272 + }
273 +
274 + errno = 0;
275 + val = ptrace (PTRACE_PEEKUSER, tid, register_addr (regno, 0), 0);
276 + if (errno != 0)
277 + perror_with_name (_("Couldn't get registers"));
278 +
279 + regcache_raw_supply (regcache, regno, &val);
280 +}
281 +
282 +/* Store one register. */
283 +
284 +static void
285 +store_register (struct regcache *regcache, int tid, int regno)
286 +{
287 + int val;
288 +
289 + if (cannot_store_register (regno))
290 + return;
291 +
292 + errno = 0;
293 + regcache_raw_collect (regcache, regno, &val);
294 + ptrace (PTRACE_POKEUSER, tid, register_addr (regno, 0), val);
295 + if (errno != 0)
296 + perror_with_name (_("Couldn't write registers"));
297 +}
298 +
299 +/* Transfering the general-purpose registers between GDB, inferiors
300 + and core files. */
301 +
302 +/* Fill GDB's register array with the general-purpose register values
303 + in *GREGSETP. */
304 +
305 +void
306 +supply_gregset (struct regcache *regcache, const elf_gregset_t *gregsetp)
307 +{
308 + elf_greg_t *regp = (elf_greg_t *) gregsetp;
309 + int i;
310 +
311 + for (i = 0; i < 23; i++)
312 + if (regmap[i] == -1)
313 + regcache_raw_supply (regcache, i, NULL);
314 + else
315 + regcache_raw_supply (regcache, i, (char *) (regp + regmap[i]));
316 +}
317 +
318 +/* Fill register REGNO (if it is a general-purpose register) in
319 + *GREGSETPS with the value in GDB's register array. If REGNO is -1,
320 + do this for all registers. */
321 +
322 +void
323 +fill_gregset (const struct regcache *regcache, elf_gregset_t *gregsetp, int regno)
324 +{
325 + elf_greg_t *regp = (elf_greg_t *) gregsetp;
326 + int i;
327 +
328 + for (i = 0; i < 23; i++)
329 + if (regmap[i] != -1 && (regno == -1 || regno == i))
330 + regcache_raw_collect (regcache, i, (char *) (regp + regmap[i]));
331 +}
332 +
333 +/* Transfering floating-point registers between GDB, inferiors and cores. */
334 +
335 +/* Fill GDB's register array with the floating-point register values in
336 + *FPREGSETP. */
337 +
338 +void
339 +supply_fpregset (struct regcache *regcache, const elf_fpregset_t *fpregsetp)
340 +{
341 + int i;
342 + long *regp = (long *)fpregsetp;
343 +
344 + for (i = 0; i < 16; i++)
345 + regcache_raw_supply (regcache, 25 + i, (char *) (regp + i));
346 + regcache_raw_supply (regcache, FPUL_REGNUM, (char *) (regp + REG_FPUL - REG_FPREG0));
347 + regcache_raw_supply (regcache, FPSCR_REGNUM, (char *) (regp + REG_FPSCR - REG_FPREG0));
348 +}
349 +
350 +/* Fill register REGNO (if it is a floating-point register) in
351 + *FPREGSETP with the value in GDB's register array. If REGNO is -1,
352 + do this for all registers. */
353 +
354 +void
355 +fill_fpregset (const struct regcache *regcache, elf_fpregset_t *fpregsetp, int regno)
356 +{
357 + int i;
358 + long *regp = (long *)fpregsetp;
359 +
360 + for (i = 0; i < 16; i++)
361 + if ((regno == -1) || (regno == i))
362 + regcache_raw_collect (regcache, 25 + i, (char *) (regp + i));
363 + if ((regno == -1) || regno == FPSCR_REGNUM)
364 + regcache_raw_collect (regcache, FPSCR_REGNUM, (char *) (regp + REG_FPSCR - REG_FPREG0));
365 + if ((regno == -1) || regno == FPUL_REGNUM)
366 + regcache_raw_collect (regcache, FPUL_REGNUM, (char *) (regp + REG_FPUL - REG_FPREG0));
367 +}
368 +
369 +/* Transferring arbitrary registers between GDB and inferior. */
370 +
371 +/* Check if register REGNO in the child process is accessible.
372 + If we are accessing registers directly via the U area, only the
373 + general-purpose registers are available.
374 + All registers should be accessible if we have GETREGS support. */
375 +
376 +int
377 +cannot_fetch_register (int regno)
378 +{
379 + return (regno < 0 || regno >= sizeof regmap / sizeof regmap[0] || regmap[regno] == -1);
380 +}
381 +
382 +int
383 +cannot_store_register (int regno)
384 +{
385 + return (regno < 0 || regno >= sizeof regmap / sizeof regmap[0] || regmap[regno] == -1);
386 +}
387 +
388 +/* Fetch register values from the inferior.
389 + If REGNO is negative, do this for all registers.
390 + Otherwise, REGNO specifies which register (so we can save time). */
391 +
392 +static void
393 +sh_linux_fetch_inferior_registers (struct target_ops *ops, struct regcache *regcache, int regno)
394 +{
395 + int i;
396 + int tid;
397 +
398 + /* GNU/Linux LWP ID's are process ID's. */
399 + if ((tid = TIDGET (inferior_ptid)) == 0)
400 + tid = PIDGET (inferior_ptid); /* Not a threaded program. */
401 +
402 + for (i = 0; i < SH_LINUX_NUM_REGS; i++)
403 + if (regno == -1 || regno == i)
404 + fetch_register (regcache, tid, i);
405 +}
406 +/* Store our register values back into the inferior.
407 + If REGNO is negative, do this for all registers.
408 + Otherwise, REGNO specifies which register (so we can save time). */
409 +
410 +static void
411 +sh_linux_store_inferior_registers (struct target_ops *ops, struct regcache *regcache, int regno)
412 +{
413 + int i;
414 + int tid;
415 +
416 + /* GNU/Linux LWP ID's are process ID's. */
417 + if ((tid = TIDGET (inferior_ptid)) == 0)
418 + tid = PIDGET (inferior_ptid); /* Not a threaded program. */
419 +
420 + for (i = 0; i < SH_LINUX_NUM_REGS; i++)
421 + if (regno == -1 || regno == i)
422 + store_register (regcache, tid, i);
423 +}
424 +
425 +void
426 +_initialize_sh_linux_nat (void)
427 +{
428 + struct target_ops *t;
429 +
430 + /* Fill in the generic GNU/Linux methods. */
431 + t = linux_target ();
432 +
433 + /* Add our register access methods. */
434 + t->to_fetch_registers = sh_linux_fetch_inferior_registers;
435 + t->to_store_registers = sh_linux_store_inferior_registers;
436 +
437 + /* Register the target. */
438 + linux_nat_add_target (t);
439 +}
440 diff --git a/gdb/sh-linux-tdep.c b/gdb/sh-linux-tdep.c
441 index da4137b..be95bc9 100644
442 --- a/gdb/sh-linux-tdep.c
443 +++ b/gdb/sh-linux-tdep.c
444 @@ -18,11 +18,34 @@
445 along with this program. If not, see <http://www.gnu.org/licenses/>. */
446
447 #include "defs.h"
448 +#include "gdbcore.h"
449 +#include "frame.h"
450 +#include "frame-base.h"
451 +#include "frame-unwind.h"
452 +#include "dwarf2-frame.h"
453 +#include "value.h"
454 +#include "regcache.h"
455 +#include "inferior.h"
456 #include "osabi.h"
457
458 +#include "reggroups.h"
459 +#include "arch-utils.h"
460 +#include "floatformat.h"
461 #include "solib-svr4.h"
462 #include "symtab.h"
463 +#include "gdb_string.h"
464 +#include "command.h"
465 +#include "gdb_assert.h"
466
467 +#include <sys/ptrace.h>
468 +#include <sys/types.h>
469 +#include <sys/param.h>
470 +#include <sys/user.h>
471 +#include <sys/syscall.h>
472 +
473 +#include <asm/ptrace.h>
474 +
475 +#include "regset.h"
476 #include "glibc-tdep.h"
477 #include "sh-tdep.h"
478
479 @@ -69,9 +92,505 @@ static const struct sh_corefile_regmap fpregs_table[] =
480 {-1 /* Terminator. */, 0}
481 };
482
483 +/* Recognizing signal handler frames. */
484 +
485 +/* GNU/Linux has two flavors of signals. Normal signal handlers, and
486 + "realtime" (RT) signals. The RT signals can provide additional
487 + information to the signal handler if the SA_SIGINFO flag is set
488 + when establishing a signal handler using `sigaction'. It is not
489 + unlikely that future versions of GNU/Linux will support SA_SIGINFO
490 + for normal signals too. */
491 +
492 +/* When the SH Linux kernel calls a signal handler and the
493 + SA_RESTORER flag isn't set, the return address points to a bit of
494 + code on the stack. This function returns whether the PC appears to
495 + be within this bit of code.
496 +
497 + The instruction sequence for normal signals is
498 + mov.w 1f,r3
499 + trapa #16
500 + or r0, r0
501 + or r0, r0
502 + or r0, r0
503 + or r0, r0
504 + or r0, r0
505 + 1: .word __NR_sigreturn
506 + or 0x9305 0xc310 0x200b 0x200b 0x200b 0x200b 0x200b 0x0077.
507 +
508 + Checking for the code sequence should be somewhat reliable, because
509 + the effect is to call the system call sigreturn. This is unlikely
510 + to occur anywhere other than a signal trampoline.
511 +
512 + It kind of sucks that we have to read memory from the process in
513 + order to identify a signal trampoline, but there doesn't seem to be
514 + any other way. The PC_IN_SIGTRAMP macro in tm-linux.h arranges to
515 + only call us if no function name could be identified, which should
516 + be the case since the code is on the stack.
517 +
518 + Detection of signal trampolines for handlers that set the
519 + SA_RESTORER flag is in general not possible. Unfortunately this is
520 + what the GNU C Library has been doing for quite some time now.
521 + However, as of version 2.1.2, the GNU C Library uses signal
522 + trampolines (named __restore and __restore_rt) that are identical
523 + to the ones used by the kernel. Therefore, these trampolines are
524 + supported too. */
525 +
526 +#define MOVW(n) (0x9300|((n)-2)) /* Move mem word at PC+n to R3 */
527 +#define TRAP16 0xc310 /* Syscall w/no args (NR in R3) */
528 +#define OR_R0_R0 0x200b /* or r0,r0 (insert to avoid hardware bug) */
529 +
530 +#define LINUX_SIGTRAMP_INSN0 MOVW(7) /* Move mem word at PC+7 to R3 */
531 +#define LINUX_SIGTRAMP_INSN1 TRAP16 /* Syscall w/no args (NR in R3) */
532 +#define LINUX_SIGTRAMP_INSN2 OR_R0_R0 /* or r0,r0 (insert to avoid hardware bug) */
533 +
534 +static const unsigned short linux_sigtramp_code[] =
535 +{
536 + LINUX_SIGTRAMP_INSN0,
537 + LINUX_SIGTRAMP_INSN1,
538 + LINUX_SIGTRAMP_INSN2,
539 + LINUX_SIGTRAMP_INSN2,
540 + LINUX_SIGTRAMP_INSN2,
541 + LINUX_SIGTRAMP_INSN2,
542 + LINUX_SIGTRAMP_INSN2,
543 + __NR_sigreturn
544 +};
545 +
546 +#define LINUX_SIGTRAMP_LEN (sizeof linux_sigtramp_code)
547 +
548 +/* If PC is in a sigtramp routine, return the address of the start of
549 + the routine. Otherwise, return 0. */
550 +
551 +static CORE_ADDR
552 +sh_linux_sigtramp_start (struct frame_info *next_frame)
553 +{
554 + CORE_ADDR pc = get_frame_pc (next_frame);
555 + gdb_byte buf[LINUX_SIGTRAMP_LEN];
556 +
557 + /* We only recognize a signal trampoline if PC is at the start of
558 + one of the three instructions. We optimize for finding the PC at
559 + the start, as will be the case when the trampoline is not the
560 + first frame on the stack. We assume that in the case where the
561 + PC is not at the start of the instruction sequence, there will be
562 + a few trailing readable bytes on the stack. */
563 +
564 + if (!safe_frame_unwind_memory (next_frame, pc, buf, LINUX_SIGTRAMP_LEN))
565 + return 0;
566 +
567 + if (buf[0] != LINUX_SIGTRAMP_INSN0)
568 + {
569 + if (buf[0] != LINUX_SIGTRAMP_INSN1)
570 + return 0;
571 +
572 + pc -= 2;
573 +
574 + if (!safe_frame_unwind_memory (next_frame, pc, buf, LINUX_SIGTRAMP_LEN))
575 + return 0;
576 + }
577 +
578 + if (memcmp (buf, linux_sigtramp_code, LINUX_SIGTRAMP_LEN) != 0)
579 + return 0;
580 +
581 + return pc;
582 +}
583 +
584 +/* This function does the same for RT signals. Here the instruction
585 + sequence is
586 + mov.w 1f,r3
587 + trapa #16
588 + or r0, r0
589 + or r0, r0
590 + or r0, r0
591 + or r0, r0
592 + or r0, r0
593 + 1: .word __NR_rt_sigreturn
594 + or 0x9305 0xc310 0x200b 0x200b 0x200b 0x200b 0x200b 0x00ad.
595 +
596 + The effect is to call the system call rt_sigreturn. */
597 +
598 +#define LINUX_RT_SIGTRAMP_INSN0 MOVW(7) /* Move mem word at PC+7 to R3 */
599 +#define LINUX_RT_SIGTRAMP_INSN1 TRAP16 /* Syscall w/no args (NR in R3) */
600 +#define LINUX_RT_SIGTRAMP_INSN2 OR_R0_R0 /* or r0,r0 (insert to avoid hardware bug) */
601 +
602 +static const unsigned short linux_rt_sigtramp_code[] =
603 +{
604 + LINUX_RT_SIGTRAMP_INSN0,
605 + LINUX_RT_SIGTRAMP_INSN1,
606 + LINUX_RT_SIGTRAMP_INSN2,
607 + LINUX_RT_SIGTRAMP_INSN2,
608 + LINUX_RT_SIGTRAMP_INSN2,
609 + LINUX_RT_SIGTRAMP_INSN2,
610 + LINUX_RT_SIGTRAMP_INSN2,
611 + __NR_rt_sigreturn
612 +};
613 +
614 +#define LINUX_RT_SIGTRAMP_LEN (sizeof linux_rt_sigtramp_code)
615 +
616 +/* If PC is in a RT sigtramp routine, return the address of the start
617 + of the routine. Otherwise, return 0. */
618 +
619 +static CORE_ADDR
620 +sh_linux_rt_sigtramp_start (struct frame_info *next_frame)
621 +{
622 + CORE_ADDR pc = get_frame_pc (next_frame);
623 + gdb_byte buf[LINUX_RT_SIGTRAMP_LEN];
624 +
625 + /* We only recognize a signal trampoline if PC is at the start of
626 + one of the two instructions. We optimize for finding the PC at
627 + the start, as will be the case when the trampoline is not the
628 + first frame on the stack. We assume that in the case where the
629 + PC is not at the start of the instruction sequence, there will be
630 + a few trailing readable bytes on the stack. */
631 +
632 + if (!safe_frame_unwind_memory (next_frame, pc, buf, LINUX_RT_SIGTRAMP_LEN))
633 + return 0;
634 +
635 + if (buf[0] != LINUX_RT_SIGTRAMP_INSN0)
636 + {
637 + if (buf[0] != LINUX_RT_SIGTRAMP_INSN1)
638 + return 0;
639 +
640 + pc -= 2;
641 +
642 + if (!safe_frame_unwind_memory (next_frame, pc, buf,
643 + LINUX_RT_SIGTRAMP_LEN))
644 + return 0;
645 + }
646 +
647 + if (memcmp (buf, linux_rt_sigtramp_code, LINUX_RT_SIGTRAMP_LEN) != 0)
648 + return 0;
649 +
650 + return pc;
651 +}
652 +
653 +/* Return whether PC is in a GNU/Linux sigtramp routine. */
654 +
655 +static int
656 +sh_linux_sigtramp_p (struct frame_info *this_frame)
657 +{
658 + CORE_ADDR pc = get_frame_pc (this_frame);
659 + char *name;
660 +
661 + find_pc_partial_function (pc, &name, NULL, NULL);
662 +
663 + /* If we have NAME, we can optimize the search. The trampolines are
664 + named __restore and __restore_rt. However, they aren't dynamically
665 + exported from the shared C library, so the trampoline may appear to
666 + be part of the preceding function. This should always be sigaction,
667 + __sigaction, or __libc_sigaction (all aliases to the same function). */
668 + if (name == NULL || strstr (name, "sigaction") != NULL)
669 + return (sh_linux_sigtramp_start (this_frame) != 0
670 + || sh_linux_rt_sigtramp_start (this_frame) != 0);
671 +
672 + return (strcmp ("__restore", name) == 0
673 + || strcmp ("__restore_rt", name) == 0);
674 +}
675 +
676 +/* Offset to struct sigcontext in ucontext, from <asm/ucontext.h>. */
677 +#define SH_LINUX_UCONTEXT_SIGCONTEXT_OFFSET 12
678 +
679 +
680 +/* Assuming NEXT_FRAME is a frame following a GNU/Linux sigtramp
681 + routine, return the address of the associated sigcontext structure. */
682 +
683 +static CORE_ADDR
684 +sh_linux_sigcontext_addr (struct frame_info *this_frame)
685 +{
686 + CORE_ADDR pc;
687 + CORE_ADDR sp;
688 +
689 + sp = get_frame_register_unsigned (this_frame, SP_REGNUM);
690 +
691 + pc = sh_linux_sigtramp_start (this_frame);
692 + if (pc)
693 + {
694 + return sp;
695 + }
696 +
697 + pc = sh_linux_rt_sigtramp_start (this_frame);
698 + if (pc)
699 + {
700 + CORE_ADDR ucontext_addr;
701 +
702 + /* The sigcontext structure is part of the user context. A
703 + pointer to the user context is passed as the third argument
704 + to the signal handler. */
705 + ucontext_addr = get_frame_register_unsigned (this_frame, ARG0_REGNUM+2);
706 + return ucontext_addr + SH_LINUX_UCONTEXT_SIGCONTEXT_OFFSET;
707 + }
708 +
709 + error ("Couldn't recognize signal trampoline.");
710 + return 0;
711 +}
712 +
713 +/* Signal trampolines. */
714 +extern struct sh_frame_cache *sh_alloc_frame_cache (void);
715 +
716 +static struct sh_frame_cache *
717 +sh_linux_sigtramp_frame_cache (struct frame_info *this_frame, void **this_cache)
718 +{
719 + struct sh_frame_cache *cache;
720 + struct gdbarch_tdep *tdep = gdbarch_tdep (get_current_arch ());
721 + CORE_ADDR sigcontext_addr;
722 +
723 + if (*this_cache)
724 + return *this_cache;
725 +
726 + cache = sh_alloc_frame_cache ();
727 +
728 + cache->base = get_frame_register_unsigned (this_frame, SP_REGNUM);
729 + sigcontext_addr = tdep->sigcontext_addr (this_frame);
730 + if (tdep->sc_reg_offset)
731 + {
732 + int i;
733 +
734 + gdb_assert (tdep->sc_num_regs <= SH_NUM_REGS);
735 +
736 + for (i = 0; i < tdep->sc_num_regs; i++)
737 + if (tdep->sc_reg_offset[i] != -1)
738 + cache->saved_regs[i] = sigcontext_addr + tdep->sc_reg_offset[i];
739 + }
740 +
741 + *this_cache = cache;
742 + return cache;
743 +}
744 +
745 +static void
746 +sh_linux_sigtramp_frame_this_id (struct frame_info *this_frame, void **this_cache,
747 + struct frame_id *this_id)
748 +{
749 + struct sh_frame_cache *cache =
750 + sh_linux_sigtramp_frame_cache (this_frame, this_cache);
751 +
752 + (*this_id) = frame_id_build (cache->base + 64, cache->pc);
753 +}
754 +
755 +extern struct value * sh_frame_prev_register ();
756 +static struct value *
757 +sh_linux_sigtramp_frame_prev_register (struct frame_info *this_frame,
758 + void **this_cache, int regnum)
759 +{
760 + sh_linux_sigtramp_frame_cache (this_frame, this_cache);
761 +
762 + return sh_frame_prev_register (this_frame, this_cache, regnum);
763 +}
764 +
765 +static int
766 +sh_linux_sigtramp_frame_sniffer (const struct frame_unwind *self,
767 + struct frame_info *this_frame,
768 + void **this_prologue_cache)
769 +{
770 + struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (this_frame));
771 +
772 + /* We shouldn't even bother if we don't have a sigcontext_addr
773 + handler. */
774 + if (tdep->sigcontext_addr == NULL)
775 + return 0;
776 +
777 + if (tdep->sigtramp_p != NULL)
778 + {
779 + if (tdep->sigtramp_p (this_frame))
780 + return 1;
781 + }
782 +
783 + return 0;
784 +}
785 +
786 +static const struct frame_unwind sh_linux_sigtramp_frame_unwind =
787 +{
788 + SIGTRAMP_FRAME,
789 + sh_linux_sigtramp_frame_this_id,
790 + sh_linux_sigtramp_frame_prev_register,
791 + NULL,
792 + sh_linux_sigtramp_frame_sniffer
793 +};
794 +
795 +/* Supply register REGNUM from the buffer specified by GREGS and LEN
796 + in the general-purpose register set REGSET to register cache
797 + REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
798 +
799 +void
800 +sh_supply_gregset (const struct regset *regset, struct regcache *regcache,
801 + int regnum, const void *gregs, size_t len)
802 +{
803 + const struct gdbarch_tdep *tdep = gdbarch_tdep (regset->arch);
804 + const char *regs = gregs;
805 + int i;
806 +
807 + gdb_assert (len == tdep->sizeof_gregset);
808 +
809 + for (i = 0; i < tdep->gregset_num_regs; i++)
810 + {
811 + if ((regnum == i || regnum == -1)
812 + && tdep->gregset_reg_offset[i] != -1)
813 + regcache_raw_supply (regcache, i, regs + tdep->gregset_reg_offset[i]);
814 + }
815 +}
816 +
817 +/* Collect register REGNUM from the register cache REGCACHE and store
818 + it in the buffer specified by GREGS and LEN as described by the
819 + general-purpose register set REGSET. If REGNUM is -1, do this for
820 + all registers in REGSET. */
821 +
822 +void
823 +sh_collect_gregset (const struct regset *regset,
824 + const struct regcache *regcache,
825 + int regnum, void *gregs, size_t len)
826 +{
827 + const struct gdbarch_tdep *tdep = gdbarch_tdep (regset->arch);
828 + char *regs = gregs;
829 + int i;
830 +
831 + gdb_assert (len == tdep->sizeof_gregset);
832 +
833 + for (i = 0; i < tdep->gregset_num_regs; i++)
834 + {
835 + if ((regnum == i || regnum == -1)
836 + && tdep->gregset_reg_offset[i] != -1)
837 + regcache_raw_collect (regcache, i, regs + tdep->gregset_reg_offset[i]);
838 + }
839 +}
840 +
841 +/* Supply register REGNUM from the buffer specified by FPREGS and LEN
842 + in the floating-point register set REGSET to register cache
843 + REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
844 +
845 +static void
846 +sh_supply_fpregset (const struct regset *regset, struct regcache *regcache,
847 + int regnum, const void *fpregs, size_t len)
848 +{
849 + const struct gdbarch_tdep *tdep = gdbarch_tdep (regset->arch);
850 + const char *regs = fpregs;
851 + int i;
852 +
853 + gdb_assert (len == tdep->sizeof_fpregset);
854 + for (i = 0; i < 16; i++)
855 + {
856 + if (regnum == i+25 || regnum == -1)
857 + regcache_raw_supply (regcache, i+25, regs + i*4);
858 + }
859 + if (regnum == FPSCR_REGNUM || regnum == -1)
860 + regcache_raw_supply (regcache, FPSCR_REGNUM, regs + 32*4);
861 + if (regnum == FPUL_REGNUM || regnum == -1)
862 + regcache_raw_supply (regcache, FPUL_REGNUM, regs + 33*4);
863 +}
864 +
865 +/* Collect register REGNUM from the register cache REGCACHE and store
866 + it in the buffer specified by FPREGS and LEN as described by the
867 + floating-point register set REGSET. If REGNUM is -1, do this for
868 + all registers in REGSET. */
869 +
870 +static void
871 +sh_collect_fpregset (const struct regset *regset,
872 + const struct regcache *regcache,
873 + int regnum, void *fpregs, size_t len)
874 +{
875 + const struct gdbarch_tdep *tdep = gdbarch_tdep (regset->arch);
876 + char *regs = fpregs;
877 + int i;
878 +
879 + gdb_assert (len == tdep->sizeof_fpregset);
880 + for (i = 0; i < 16; i++)
881 + {
882 + if (regnum == i+25 || regnum == -1)
883 + regcache_raw_collect (regcache, i+25, regs + i*4);
884 + }
885 + if (regnum == FPSCR_REGNUM || regnum == -1)
886 + regcache_raw_collect (regcache, FPSCR_REGNUM, regs + 32*4);
887 + if (regnum == FPUL_REGNUM || regnum == -1)
888 + regcache_raw_collect (regcache, FPUL_REGNUM, regs + 33*4);
889 +}
890 +
891 +/* Return the appropriate register set for the core section identified
892 + by SECT_NAME and SECT_SIZE. */
893 +
894 +const struct regset *
895 +sh_linux_regset_from_core_section (struct gdbarch *gdbarch,
896 + const char *sect_name, size_t sect_size)
897 +{
898 + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
899 +
900 + if (strcmp (sect_name, ".reg") == 0 && sect_size == tdep->sizeof_gregset)
901 + {
902 + if (tdep->gregset == NULL)
903 + tdep->gregset = regset_alloc (gdbarch, sh_supply_gregset,
904 + sh_collect_gregset);
905 + return tdep->gregset;
906 + }
907 +
908 + if ((strcmp (sect_name, ".reg2") == 0 && sect_size == tdep->sizeof_fpregset))
909 + {
910 + if (tdep->fpregset == NULL)
911 + tdep->fpregset = regset_alloc (gdbarch, sh_supply_fpregset,
912 + sh_collect_fpregset);
913 + return tdep->fpregset;
914 + }
915 +
916 + return NULL;
917 +}
918 +
919 +/* The register sets used in GNU/Linux ELF core-dumps are identical to
920 + the register sets in `struct user' that are used for a.out
921 + core-dumps. These are also used by ptrace(2). The corresponding
922 + types are `elf_gregset_t' for the general-purpose registers (with
923 + `elf_greg_t' the type of a single GP register) and `elf_fpregset_t'
924 + for the floating-point registers.
925 +
926 + Those types used to be available under the names `gregset_t' and
927 + `fpregset_t' too, and GDB used those names in the past. But those
928 + names are now used for the register sets used in the `mcontext_t'
929 + type, which have a different size and layout. */
930 +
931 +/* Mapping between the general-purpose registers in `struct user'
932 + format and GDB's register cache layout. */
933 +
934 +/* From <sys/reg.h>. */
935 +static int sh_linux_gregset_reg_offset[] =
936 +{
937 + 0, 4, 8, 12, 16, 20, 24, 28,
938 + 32, 36, 40, 44, 48, 52, 56, 60,
939 +
940 + REG_PC*4, REG_PR*4, REG_GBR*4, -1,
941 + REG_MACH*4, REG_MACL*4, REG_SR*4,
942 +};
943 +
944 +/* Mapping between the general-purpose registers in `struct
945 + sigcontext' format and GDB's register cache layout. */
946 +
947 +/* From <asm/sigcontext.h>. */
948 +static int sh_linux_sc_reg_offset[] =
949 +{
950 + 4, 8, 12, 16, 20, 24, 28, 32,
951 + 36, 40, 44, 48, 52, 56, 60, 64,
952 + 68, 72, 80, -1,
953 + 84, 88, 76
954 +};
955 +
956 static void
957 sh_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
958 {
959 + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
960 + bfd abfd;
961 +
962 + tdep->gregset_reg_offset = sh_linux_gregset_reg_offset;
963 + tdep->gregset_num_regs = ARRAY_SIZE (sh_linux_gregset_reg_offset);
964 + tdep->sizeof_gregset = 23 * 4;
965 +
966 + tdep->jb_pc_offset = 32; /* From <bits/setjmp.h>. */
967 +
968 + tdep->sigtramp_p = sh_linux_sigtramp_p;
969 + tdep->sigcontext_addr = sh_linux_sigcontext_addr;
970 + tdep->sc_reg_offset = sh_linux_sc_reg_offset;
971 + tdep->sc_num_regs = ARRAY_SIZE (sh_linux_sc_reg_offset);
972 +
973 + frame_unwind_append_unwinder(gdbarch, &sh_linux_sigtramp_frame_unwind);
974 +
975 + /* If we have a register mapping, enable the generic core file
976 + support, unless it has already been enabled. */
977 + if (tdep->gregset_reg_offset
978 + && !gdbarch_regset_from_core_section_p (gdbarch))
979 + set_gdbarch_regset_from_core_section (gdbarch,
980 + sh_linux_regset_from_core_section);
981 +
982 /* GNU/Linux uses SVR4-style shared libraries. */
983 set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
984 set_solib_svr4_fetch_link_map_offsets
985 diff --git a/gdb/sh-tdep.c b/gdb/sh-tdep.c
986 index 7e01469..735cc84 100644
987 --- a/gdb/sh-tdep.c
988 +++ b/gdb/sh-tdep.c
989 @@ -24,6 +24,9 @@
990 */
991
992 #include "defs.h"
993 +#include "arch-utils.h"
994 +#include "command.h"
995 +#include "dummy-frame.h"
996 #include "frame.h"
997 #include "frame-base.h"
998 #include "frame-unwind.h"
999 @@ -40,6 +43,7 @@
1000 #include "arch-utils.h"
1001 #include "floatformat.h"
1002 #include "regcache.h"
1003 +#include "regset.h"
1004 #include "doublest.h"
1005 #include "osabi.h"
1006 #include "reggroups.h"
1007 @@ -72,23 +76,6 @@ static const char *sh_active_calling_convention = sh_cc_gcc;
1008
1009 static void (*sh_show_regs) (struct frame_info *);
1010
1011 -#define SH_NUM_REGS 67
1012 -
1013 -struct sh_frame_cache
1014 -{
1015 - /* Base address. */
1016 - CORE_ADDR base;
1017 - LONGEST sp_offset;
1018 - CORE_ADDR pc;
1019 -
1020 - /* Flag showing that a frame has been created in the prologue code. */
1021 - int uses_fp;
1022 -
1023 - /* Saved registers. */
1024 - CORE_ADDR saved_regs[SH_NUM_REGS];
1025 - CORE_ADDR saved_sp;
1026 -};
1027 -
1028 static int
1029 sh_is_renesas_calling_convention (struct type *func_type)
1030 {
1031 @@ -1045,7 +1032,7 @@ sh_treat_as_flt_p (struct type *type)
1032 return 0;
1033 /* Otherwise if the type of that member is float, the whole type is
1034 treated as float. */
1035 - if (TYPE_CODE (TYPE_FIELD_TYPE (type, 0)) == TYPE_CODE_FLT)
1036 + if (TYPE_CODE (check_typedef (TYPE_FIELD_TYPE (type, 0))) == TYPE_CODE_FLT)
1037 return 1;
1038 /* Otherwise it's not treated as float. */
1039 return 0;
1040 @@ -1095,7 +1082,7 @@ sh_push_dummy_call_fpu (struct gdbarch *gdbarch,
1041 in four registers available. Loop thru args from first to last. */
1042 for (argnum = 0; argnum < nargs; argnum++)
1043 {
1044 - type = value_type (args[argnum]);
1045 + type = check_typedef (value_type (args[argnum]));
1046 len = TYPE_LENGTH (type);
1047 val = sh_justify_value_in_reg (gdbarch, args[argnum], len);
1048
1049 @@ -2485,7 +2472,7 @@ sh_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum,
1050 reg->how = DWARF2_FRAME_REG_UNDEFINED;
1051 }
1052
1053 -static struct sh_frame_cache *
1054 +struct sh_frame_cache *
1055 sh_alloc_frame_cache (void)
1056 {
1057 struct sh_frame_cache *cache;
1058 @@ -2512,7 +2499,7 @@ sh_alloc_frame_cache (void)
1059 return cache;
1060 }
1061
1062 -static struct sh_frame_cache *
1063 +struct sh_frame_cache *
1064 sh_frame_cache (struct frame_info *this_frame, void **this_cache)
1065 {
1066 struct gdbarch *gdbarch = get_frame_arch (this_frame);
1067 @@ -2570,9 +2557,9 @@ sh_frame_cache (struct frame_info *this_frame, void **this_cache)
1068 return cache;
1069 }
1070
1071 -static struct value *
1072 -sh_frame_prev_register (struct frame_info *this_frame,
1073 - void **this_cache, int regnum)
1074 +struct value *
1075 +sh_frame_prev_register (struct frame_info *this_frame, void **this_cache,
1076 + int regnum)
1077 {
1078 struct gdbarch *gdbarch = get_frame_arch (this_frame);
1079 struct sh_frame_cache *cache = sh_frame_cache (this_frame, this_cache);
1080 @@ -2586,7 +2573,7 @@ sh_frame_prev_register (struct frame_info *this_frame,
1081 the current frame. Frob regnum so that we pull the value from
1082 the correct place. */
1083 if (regnum == gdbarch_pc_regnum (gdbarch))
1084 - regnum = PR_REGNUM;
1085 + regnum = PR_REGNUM; /* XXX: really? */
1086
1087 if (regnum < SH_NUM_REGS && cache->saved_regs[regnum] != -1)
1088 return frame_unwind_got_memory (this_frame, regnum,
1089 @@ -2829,8 +2816,8 @@ sh_regset_from_core_section (struct gdbarch *gdbarch, const char *sect_name,
1090 static struct gdbarch *
1091 sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
1092 {
1093 - struct gdbarch *gdbarch;
1094 struct gdbarch_tdep *tdep;
1095 + struct gdbarch *gdbarch;
1096
1097 sh_show_regs = sh_generic_show_regs;
1098 switch (info.bfd_arch_info->mach)
1099 @@ -2893,6 +2880,18 @@ sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
1100 tdep = XZALLOC (struct gdbarch_tdep);
1101 gdbarch = gdbarch_alloc (&info, tdep);
1102
1103 + /* General-purpose registers. */
1104 + tdep->gregset = NULL;
1105 + tdep->gregset_reg_offset = NULL;
1106 + tdep->gregset_num_regs = 23;
1107 + tdep->sizeof_gregset = 0;
1108 +
1109 + /* Floating-point registers. */
1110 + tdep->fpregset = NULL;
1111 + tdep->sizeof_fpregset = 34*4;
1112 +
1113 + tdep->jb_pc_offset = -1;
1114 +
1115 set_gdbarch_short_bit (gdbarch, 2 * TARGET_CHAR_BIT);
1116 set_gdbarch_int_bit (gdbarch, 4 * TARGET_CHAR_BIT);
1117 set_gdbarch_long_bit (gdbarch, 4 * TARGET_CHAR_BIT);
1118 @@ -3038,10 +3037,11 @@ sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
1119 break;
1120 }
1121
1122 + dwarf2_append_unwinders (gdbarch);
1123 +
1124 /* Hook in ABI-specific overrides, if they have been registered. */
1125 gdbarch_init_osabi (info, gdbarch);
1126
1127 - dwarf2_append_unwinders (gdbarch);
1128 frame_unwind_append_unwinder (gdbarch, &sh_frame_unwind);
1129
1130 return gdbarch;
1131 diff --git a/gdb/sh-tdep.h b/gdb/sh-tdep.h
1132 index b53d412..f2bea7d 100644
1133 --- a/gdb/sh-tdep.h
1134 +++ b/gdb/sh-tdep.h
1135 @@ -22,6 +22,12 @@
1136
1137 /* Contributed by Steve Chamberlain sac@cygnus.com */
1138
1139 +struct frame_info;
1140 +struct gdbarch;
1141 +struct reggroup;
1142 +struct regset;
1143 +struct regcache;
1144 +
1145 /* Registers for all SH variants. Used also by sh3-rom.c. */
1146 enum
1147 {
1148 @@ -30,6 +36,7 @@ enum
1149 ARG0_REGNUM = 4,
1150 ARGLAST_REGNUM = 7,
1151 FP_REGNUM = 14,
1152 + SP_REGNUM = 15,
1153 PC_REGNUM = 16,
1154 PR_REGNUM = 17,
1155 GBR_REGNUM = 18,
1156 @@ -83,8 +90,26 @@ enum
1157 FV_LAST_REGNUM = 79
1158 };
1159
1160 +#define SH_NUM_REGS 67
1161 +
1162 +struct sh_frame_cache
1163 +{
1164 + /* Base address. */
1165 + CORE_ADDR base;
1166 + LONGEST sp_offset;
1167 + CORE_ADDR pc;
1168 +
1169 + /* Flag showing that a frame has been created in the prologue code. */
1170 + int uses_fp;
1171 +
1172 + /* Saved registers. */
1173 + CORE_ADDR saved_regs[SH_NUM_REGS];
1174 + CORE_ADDR saved_sp;
1175 +};
1176 +
1177 extern gdbarch_init_ftype sh64_gdbarch_init;
1178 extern void sh64_show_regs (struct frame_info *);
1179 +extern struct sh_frame_cache *sh_frame_cache (struct frame_info *next_frame, void **this_cache);
1180
1181 /* This structure describes a register in a core-file. */
1182 struct sh_corefile_regmap
1183 @@ -93,8 +118,32 @@ struct sh_corefile_regmap
1184 unsigned int offset;
1185 };
1186
1187 +/* sh architecture specific information. */
1188 struct gdbarch_tdep
1189 {
1190 + /* General-purpose registers. */
1191 + struct regset *gregset;
1192 + int *gregset_reg_offset;
1193 + int gregset_num_regs;
1194 + size_t sizeof_gregset;
1195 +
1196 + /* Floating-point registers. */
1197 + struct regset *fpregset;
1198 + size_t sizeof_fpregset;
1199 +
1200 + /* Offset of saved PC in jmp_buf. */
1201 + int jb_pc_offset;
1202 +
1203 + /* Detect sigtramp. */
1204 + int (*sigtramp_p) (struct frame_info *);
1205 +
1206 + /* Get address of sigcontext for sigtramp. */
1207 + CORE_ADDR (*sigcontext_addr) (struct frame_info *);
1208 +
1209 + /* Offset of registers in `struct sigcontext'. */
1210 + int *sc_reg_offset;
1211 + int sc_num_regs;
1212 +
1213 /* Non-NULL when debugging from a core file. Provides the offset
1214 where each general-purpose register is stored inside the associated
1215 core file section. */
1216 diff --git a/gdb/testsuite/gdb.asm/asm-source.exp b/gdb/testsuite/gdb.asm/asm-source.exp
1217 index 615182f..dd5ae09 100644
1218 --- a/gdb/testsuite/gdb.asm/asm-source.exp
1219 +++ b/gdb/testsuite/gdb.asm/asm-source.exp
1220 @@ -105,6 +105,11 @@ switch -glob -- [istarget] {
1221 "powerpc*-*" {
1222 set asm-arch powerpc
1223 }
1224 + "sh*-linux*" {
1225 + set asm-arch sh-linux
1226 + set asm-flags "-I${srcdir}/${subdir} -I${objdir}/${subdir}"
1227 + set debug-flags "-gdwarf-2"
1228 + }
1229 "sh*-*-*" {
1230 set asm-arch sh
1231 set debug-flags "-gdwarf-2"
1232 diff --git a/gdb/testsuite/gdb.asm/sh-linux.inc b/gdb/testsuite/gdb.asm/sh-linux.inc
1233 new file mode 100644
1234 index 0000000..4a0f669
1235 --- /dev/null
1236 +++ b/gdb/testsuite/gdb.asm/sh-linux.inc
1237 @@ -0,0 +1,78 @@
1238 +# You'll find a bunch of nop opcodes in the below macros. They are
1239 +# there to keep the code correctly aligned. Be careful to maintain
1240 +# them when changing the code.
1241 +
1242 + comment "subroutine declare"
1243 + .purgem gdbasm_declare
1244 + .macro gdbasm_declare name
1245 + .align 1
1246 + .global \name
1247 +\name:
1248 + .endm
1249 +
1250 + comment "subroutine prologue"
1251 + .macro gdbasm_enter
1252 + mov.l r14,@-r15
1253 + sts.l pr,@-r15
1254 + mov r15,r14
1255 + nop
1256 + .endm
1257 +
1258 + comment "subroutine epilogue"
1259 + .macro gdbasm_leave
1260 + mov r14,r15
1261 + lds.l @r15+,pr
1262 + mov.l @r15+,r14
1263 + rts
1264 + nop
1265 + nop
1266 + .endm
1267 +
1268 + comment "subroutine end"
1269 + .purgem gdbasm_end
1270 + .macro gdbasm_end name
1271 + .size \name, .-_foo1
1272 + .align 1
1273 + .endm
1274 +
1275 + comment "subroutine call"
1276 + .macro gdbasm_call subr
1277 + mov.l .Lconst\@,r1
1278 + bra .Lafterconst\@
1279 + nop
1280 + .align 2
1281 +.Lconst\@:
1282 + .long \subr
1283 +.Lafterconst\@:
1284 + jsr @r1
1285 + nop
1286 + .endm
1287 +
1288 + .macro gdbasm_several_nops
1289 + nop
1290 + nop
1291 + nop
1292 + nop
1293 + .endm
1294 +
1295 + comment "exit (0)"
1296 + .macro gdbasm_exit0
1297 + sleep
1298 + nop
1299 + .endm
1300 +
1301 + comment "crt0 startup"
1302 + .macro gdbasm_startup
1303 + mov #0,r14
1304 + .endm
1305 +
1306 + comment "Declare a data variable"
1307 + .purgem gdbasm_datavar
1308 + .macro gdbasm_datavar name value
1309 + .data
1310 + .align 2
1311 + .type \name, @object
1312 + .size \name, 4
1313 +\name:
1314 + .long \value
1315 + .endm
1316 diff --git a/gdb/testsuite/gdb.asm/sh.inc b/gdb/testsuite/gdb.asm/sh.inc
1317 index 9ea1b67..c1f189d 100644
1318 --- a/gdb/testsuite/gdb.asm/sh.inc
1319 +++ b/gdb/testsuite/gdb.asm/sh.inc
1320 @@ -40,9 +40,8 @@
1321 mov.l .Lconst\@,r1
1322 bra .Lafterconst\@
1323 nop
1324 - nop
1325 -.Lconst\@:
1326 .align 2
1327 +.Lconst\@:
1328 .long \subr
1329 .align 1
1330 .Lafterconst\@:
1331 diff --git a/gdb/testsuite/gdb.base/annota1.c b/gdb/testsuite/gdb.base/annota1.c
1332 index 6a13ee9..fb8aa53 100644
1333 --- a/gdb/testsuite/gdb.base/annota1.c
1334 +++ b/gdb/testsuite/gdb.base/annota1.c
1335 @@ -1,9 +1,9 @@
1336 #include <stdio.h>
1337 #include <signal.h>
1338
1339 -#ifdef __sh__
1340 -#define signal(a,b) /* Signals not supported on this target - make them go away */
1341 -#endif
1342 +
1343 +
1344 +
1345
1346
1347 #ifdef PROTOTYPES
1348 diff --git a/gdb/testsuite/gdb.base/annota3.c b/gdb/testsuite/gdb.base/annota3.c
1349 index 6a13ee9..fb8aa53 100644
1350 --- a/gdb/testsuite/gdb.base/annota3.c
1351 +++ b/gdb/testsuite/gdb.base/annota3.c
1352 @@ -1,9 +1,9 @@
1353 #include <stdio.h>
1354 #include <signal.h>
1355
1356 -#ifdef __sh__
1357 -#define signal(a,b) /* Signals not supported on this target - make them go away */
1358 -#endif
1359 +
1360 +
1361 +
1362
1363
1364 #ifdef PROTOTYPES
1365 diff --git a/gdb/testsuite/gdb.base/sigall.c b/gdb/testsuite/gdb.base/sigall.c
1366 index 28ae192..a8ff690 100644
1367 --- a/gdb/testsuite/gdb.base/sigall.c
1368 +++ b/gdb/testsuite/gdb.base/sigall.c
1369 @@ -1,9 +1,9 @@
1370 #include <signal.h>
1371 #include <unistd.h>
1372
1373 -#ifdef __sh__
1374 -#define signal(a,b) /* Signals not supported on this target - make them go away */
1375 -#endif
1376 +
1377 +
1378 +
1379
1380 /* Signal handlers, we set breakpoints in them to make sure that the
1381 signals really get delivered. */
1382 diff --git a/gdb/testsuite/gdb.base/signals.c b/gdb/testsuite/gdb.base/signals.c
1383 index f1ebcfc..cef4793 100644
1384 --- a/gdb/testsuite/gdb.base/signals.c
1385 +++ b/gdb/testsuite/gdb.base/signals.c
1386 @@ -3,10 +3,10 @@
1387 #include <signal.h>
1388 #include <unistd.h>
1389
1390 -#ifdef __sh__
1391 -#define signal(a,b) /* Signals not supported on this target - make them go away */
1392 -#define alarm(a) /* Ditto for alarm() */
1393 -#endif
1394 +
1395 +
1396 +
1397 +
1398
1399 static int count = 0;
1400
1401 --
1402 1.7.0.3
1403
66 man-page-args.patch
77 man-page-order.patch
88 tui-no-gdbarch.patch
9 renesas-sh-native-support.patch