diff options
| -rw-r--r-- | meta/recipes-devtools/gdb/gdb-common.inc | 2 | ||||
| -rw-r--r-- | meta/recipes-devtools/gdb/gdb.inc | 1 | ||||
| -rw-r--r-- | meta/recipes-devtools/gdb/gdb/renesas-sh-native-support.patch | 1389 | 
3 files changed, 1391 insertions, 1 deletions
| diff --git a/meta/recipes-devtools/gdb/gdb-common.inc b/meta/recipes-devtools/gdb/gdb-common.inc index b520353721..8836aa3091 100644 --- a/meta/recipes-devtools/gdb/gdb-common.inc +++ b/meta/recipes-devtools/gdb/gdb-common.inc @@ -12,7 +12,7 @@ LTTNGUST_mips64 = ""  LTTNGUST_mips64el = ""  LTTNGUST_sh4 = "" -INC_PR = "r8" +INC_PR = "r9"  LIC_FILES_CHKSUM = "file://COPYING;md5=59530bdf33659b29e73d4adb9f9f6552 \  		file://COPYING.LIB;md5=9f604d8a4f8e74f4f5140845a21b6674 \ diff --git a/meta/recipes-devtools/gdb/gdb.inc b/meta/recipes-devtools/gdb/gdb.inc index 9f5f34fed9..a620eca501 100644 --- a/meta/recipes-devtools/gdb/gdb.inc +++ b/meta/recipes-devtools/gdb/gdb.inc @@ -4,6 +4,7 @@ inherit gettext  SRC_URI += "file://kill_arm_map_symbols.patch \              file://gdbserver-cflags-last.diff;striplevel=0 \ +	    file://renesas-sh-native-support.patch \             "  #LDFLAGS_append = " -s"  #export CFLAGS_append=" -L${STAGING_LIBDIR}" diff --git a/meta/recipes-devtools/gdb/gdb/renesas-sh-native-support.patch b/meta/recipes-devtools/gdb/gdb/renesas-sh-native-support.patch new file mode 100644 index 0000000000..2b1ceb79f2 --- /dev/null +++ b/meta/recipes-devtools/gdb/gdb/renesas-sh-native-support.patch @@ -0,0 +1,1389 @@ +Description: Add Renesas SH (sh4) support + Add support for Renesas SH (sh4) architecture. + . + gdb (7.4-1~cvs20111117.2) experimental; urgency=low + . +   * Add Renesas SH (sh4) support (Closes: #576242) +     - Thanks Nobuhiro Iwamatsu, Takashi Yoshii. +Author: Hector Oron <zumbi@debian.org> +Bug-Debian: http://bugs.debian.org/576242 + +--- +The information above should follow the Patch Tagging Guidelines, please +checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here +are templates for supplementary fields that you might want to add: + +Forwarded: <no|not-needed|url proving that it has been forwarded> +Last-Update: <2011-11-17> + + +Upstream-Status: Pending +Signed-off-by: Khem Raj <raj.khem@gmail.com> + +Index: gdb-7.4/gdb/configure.host +=================================================================== +--- gdb-7.4.orig/gdb/configure.host	2012-04-24 07:06:35.085317177 -0700 ++++ gdb-7.4/gdb/configure.host	2012-04-24 07:09:14.365324889 -0700 +@@ -139,6 +139,7 @@ +  + s390*-*-*)		gdb_host=s390 ;; +  ++sh*-*-linux*)		gdb_host=linux ;; + sh*-*-netbsdelf* | sh*-*-knetbsd*-gnu) + 			gdb_host=nbsd ;; + sh*-*-openbsd*)		gdb_host=nbsd ;; +Index: gdb-7.4/gdb/Makefile.in +=================================================================== +--- gdb-7.4.orig/gdb/Makefile.in	2012-04-24 07:06:35.093317178 -0700 ++++ gdb-7.4/gdb/Makefile.in	2012-04-24 07:09:14.369324886 -0700 +@@ -1544,6 +1544,7 @@ + 	score-tdep.c \ + 	ser-go32.c ser-pipe.c ser-tcp.c ser-mingw.c \ + 	sh-tdep.c sh64-tdep.c shnbsd-tdep.c shnbsd-nat.c \ ++	sh-linux-tdep.c sh-linux-nat.c \ + 	sol2-tdep.c \ + 	solib-irix.c solib-svr4.c solib-sunos.c \ + 	sparc-linux-nat.c sparc-linux-tdep.c \ +Index: gdb-7.4/gdb/sh-linux-tdep.c +=================================================================== +--- gdb-7.4.orig/gdb/sh-linux-tdep.c	2012-04-24 07:06:35.073317177 -0700 ++++ gdb-7.4/gdb/sh-linux-tdep.c	2012-04-24 07:09:14.369324886 -0700 +@@ -18,11 +18,34 @@ +    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */ +  + #include "defs.h" ++#include "gdbcore.h" ++#include "frame.h" ++#include "frame-base.h" ++#include "frame-unwind.h" ++#include "dwarf2-frame.h" ++#include "value.h" ++#include "regcache.h" ++#include "inferior.h" + #include "osabi.h" +  ++#include "reggroups.h" ++#include "arch-utils.h" ++#include "floatformat.h" + #include "solib-svr4.h" + #include "symtab.h" ++#include "gdb_string.h" ++#include "command.h" ++#include "gdb_assert.h" +  ++#include <sys/ptrace.h> ++#include <sys/types.h> ++#include <sys/param.h> ++#include <sys/user.h> ++#include <sys/syscall.h> ++ ++#include <asm/ptrace.h> ++ ++#include "regset.h" + #include "glibc-tdep.h" + #include "sh-tdep.h" + #include "linux-tdep.h" +@@ -70,9 +93,505 @@ +   {-1 /* Terminator.  */, 0} + }; +  ++/* Recognizing signal handler frames.  */ ++ ++/* GNU/Linux has two flavors of signals.  Normal signal handlers, and ++   "realtime" (RT) signals.  The RT signals can provide additional ++   information to the signal handler if the SA_SIGINFO flag is set ++   when establishing a signal handler using `sigaction'.  It is not ++   unlikely that future versions of GNU/Linux will support SA_SIGINFO ++   for normal signals too.  */ ++ ++/* When the SH Linux kernel calls a signal handler and the ++   SA_RESTORER flag isn't set, the return address points to a bit of ++   code on the stack.  This function returns whether the PC appears to ++   be within this bit of code. ++ ++   The instruction sequence for normal signals is ++       mov.w  1f,r3 ++       trapa  #16 ++       or     r0, r0 ++       or     r0, r0 ++       or     r0, r0 ++       or     r0, r0 ++       or     r0, r0 ++    1: .word  __NR_sigreturn ++   or 0x9305 0xc310 0x200b 0x200b 0x200b 0x200b 0x200b 0x0077. ++ ++   Checking for the code sequence should be somewhat reliable, because ++   the effect is to call the system call sigreturn.  This is unlikely ++   to occur anywhere other than a signal trampoline. ++ ++   It kind of sucks that we have to read memory from the process in ++   order to identify a signal trampoline, but there doesn't seem to be ++   any other way.  The PC_IN_SIGTRAMP macro in tm-linux.h arranges to ++   only call us if no function name could be identified, which should ++   be the case since the code is on the stack. ++ ++   Detection of signal trampolines for handlers that set the ++   SA_RESTORER flag is in general not possible.  Unfortunately this is ++   what the GNU C Library has been doing for quite some time now. ++   However, as of version 2.1.2, the GNU C Library uses signal ++   trampolines (named __restore and __restore_rt) that are identical ++   to the ones used by the kernel.  Therefore, these trampolines are ++   supported too.  */ ++ ++#define MOVW(n)	 (0x9300|((n)-2))	/* Move mem word at PC+n to R3 */ ++#define TRAP16	 0xc310			/* Syscall w/no args (NR in R3) */ ++#define OR_R0_R0 0x200b			/* or r0,r0 (insert to avoid hardware bug) */ ++ ++#define LINUX_SIGTRAMP_INSN0	MOVW(7)		/* Move mem word at PC+7 to R3 */ ++#define LINUX_SIGTRAMP_INSN1	TRAP16		/* Syscall w/no args (NR in R3) */ ++#define LINUX_SIGTRAMP_INSN2	OR_R0_R0	/* or r0,r0 (insert to avoid hardware bug) */ ++ ++static const unsigned short linux_sigtramp_code[] = ++{ ++  LINUX_SIGTRAMP_INSN0, ++  LINUX_SIGTRAMP_INSN1, ++  LINUX_SIGTRAMP_INSN2, ++  LINUX_SIGTRAMP_INSN2, ++  LINUX_SIGTRAMP_INSN2, ++  LINUX_SIGTRAMP_INSN2, ++  LINUX_SIGTRAMP_INSN2, ++  __NR_sigreturn ++}; ++ ++#define LINUX_SIGTRAMP_LEN (sizeof linux_sigtramp_code) ++ ++/* If PC is in a sigtramp routine, return the address of the start of ++   the routine.  Otherwise, return 0.  */ ++ ++static CORE_ADDR ++sh_linux_sigtramp_start (struct frame_info *next_frame) ++{ ++  CORE_ADDR pc = get_frame_pc (next_frame); ++  gdb_byte buf[LINUX_SIGTRAMP_LEN]; ++ ++  /* We only recognize a signal trampoline if PC is at the start of ++     one of the three instructions.  We optimize for finding the PC at ++     the start, as will be the case when the trampoline is not the ++     first frame on the stack.  We assume that in the case where the ++     PC is not at the start of the instruction sequence, there will be ++     a few trailing readable bytes on the stack.  */ ++ ++  if (!safe_frame_unwind_memory (next_frame, pc, buf, LINUX_SIGTRAMP_LEN)) ++    return 0; ++ ++  if (buf[0] != LINUX_SIGTRAMP_INSN0) ++    { ++      if (buf[0] != LINUX_SIGTRAMP_INSN1) ++        return 0; ++ ++      pc -= 2; ++ ++      if (!safe_frame_unwind_memory (next_frame, pc, buf, LINUX_SIGTRAMP_LEN)) ++	return 0; ++    } ++ ++  if (memcmp (buf, linux_sigtramp_code, LINUX_SIGTRAMP_LEN) != 0) ++    return 0; ++ ++  return pc; ++} ++ ++/* This function does the same for RT signals.  Here the instruction ++   sequence is ++       mov.w  1f,r3 ++       trapa  #16 ++       or     r0, r0 ++       or     r0, r0 ++       or     r0, r0 ++       or     r0, r0 ++       or     r0, r0 ++    1: .word  __NR_rt_sigreturn ++   or 0x9305 0xc310 0x200b 0x200b 0x200b 0x200b 0x200b 0x00ad. ++ ++   The effect is to call the system call rt_sigreturn.  */ ++ ++#define LINUX_RT_SIGTRAMP_INSN0		MOVW(7)		/* Move mem word at PC+7 to R3 */ ++#define LINUX_RT_SIGTRAMP_INSN1		TRAP16		/* Syscall w/no args (NR in R3) */ ++#define LINUX_RT_SIGTRAMP_INSN2		OR_R0_R0	/* or r0,r0 (insert to avoid hardware bug) */ ++ ++static const unsigned short linux_rt_sigtramp_code[] = ++{ ++  LINUX_RT_SIGTRAMP_INSN0, ++  LINUX_RT_SIGTRAMP_INSN1, ++  LINUX_RT_SIGTRAMP_INSN2, ++  LINUX_RT_SIGTRAMP_INSN2, ++  LINUX_RT_SIGTRAMP_INSN2, ++  LINUX_RT_SIGTRAMP_INSN2, ++  LINUX_RT_SIGTRAMP_INSN2, ++  __NR_rt_sigreturn ++}; ++ ++#define LINUX_RT_SIGTRAMP_LEN (sizeof linux_rt_sigtramp_code) ++ ++/* If PC is in a RT sigtramp routine, return the address of the start ++   of the routine.  Otherwise, return 0.  */ ++ ++static CORE_ADDR ++sh_linux_rt_sigtramp_start (struct frame_info *next_frame) ++{ ++  CORE_ADDR pc = get_frame_pc (next_frame); ++  gdb_byte buf[LINUX_RT_SIGTRAMP_LEN]; ++ ++  /* We only recognize a signal trampoline if PC is at the start of ++     one of the two instructions.  We optimize for finding the PC at ++     the start, as will be the case when the trampoline is not the ++     first frame on the stack.  We assume that in the case where the ++     PC is not at the start of the instruction sequence, there will be ++     a few trailing readable bytes on the stack.  */ ++ ++  if (!safe_frame_unwind_memory (next_frame, pc, buf, LINUX_RT_SIGTRAMP_LEN)) ++    return 0; ++ ++  if (buf[0] != LINUX_RT_SIGTRAMP_INSN0) ++    { ++      if (buf[0] != LINUX_RT_SIGTRAMP_INSN1) ++	return 0; ++ ++      pc -= 2; ++ ++      if (!safe_frame_unwind_memory (next_frame, pc, buf, ++				     LINUX_RT_SIGTRAMP_LEN)) ++	return 0; ++    } ++ ++  if (memcmp (buf, linux_rt_sigtramp_code, LINUX_RT_SIGTRAMP_LEN) != 0) ++    return 0; ++ ++  return pc; ++} ++ ++/* Return whether PC is in a GNU/Linux sigtramp routine.  */ ++ ++static int ++sh_linux_sigtramp_p (struct frame_info *this_frame) ++{ ++  CORE_ADDR pc = get_frame_pc (this_frame); ++  char *name; ++ ++  find_pc_partial_function (pc, &name, NULL, NULL); ++ ++  /* If we have NAME, we can optimize the search.  The trampolines are ++     named __restore and __restore_rt.  However, they aren't dynamically ++     exported from the shared C library, so the trampoline may appear to ++     be part of the preceding function.  This should always be sigaction, ++     __sigaction, or __libc_sigaction (all aliases to the same function).  */ ++  if (name == NULL || strstr (name, "sigaction") != NULL) ++    return (sh_linux_sigtramp_start (this_frame) != 0 ++	    || sh_linux_rt_sigtramp_start (this_frame) != 0); ++ ++  return (strcmp ("__restore", name) == 0 ++	  || strcmp ("__restore_rt", name) == 0); ++} ++ ++/* Offset to struct sigcontext in ucontext, from <asm/ucontext.h>.  */ ++#define SH_LINUX_UCONTEXT_SIGCONTEXT_OFFSET 12 ++ ++ ++/* Assuming NEXT_FRAME is a frame following a GNU/Linux sigtramp ++   routine, return the address of the associated sigcontext structure.  */ ++ ++static CORE_ADDR ++sh_linux_sigcontext_addr (struct frame_info *this_frame) ++{ ++  CORE_ADDR pc; ++  CORE_ADDR sp; ++ ++  sp = get_frame_register_unsigned (this_frame, SP_REGNUM); ++ ++  pc = sh_linux_sigtramp_start (this_frame); ++  if (pc) ++    { ++      return sp; ++    } ++ ++  pc = sh_linux_rt_sigtramp_start (this_frame); ++  if (pc) ++    { ++      CORE_ADDR ucontext_addr; ++ ++      /* The sigcontext structure is part of the user context.  A ++	 pointer to the user context is passed as the third argument ++	 to the signal handler.  */ ++      ucontext_addr = get_frame_register_unsigned (this_frame, ARG0_REGNUM+2); ++      return ucontext_addr + SH_LINUX_UCONTEXT_SIGCONTEXT_OFFSET; ++    } ++ ++  error ("Couldn't recognize signal trampoline."); ++  return 0; ++} ++ ++/* Signal trampolines.  */ ++extern struct sh_frame_cache *sh_alloc_frame_cache (void); ++ ++static struct sh_frame_cache * ++sh_linux_sigtramp_frame_cache (struct frame_info *this_frame, void **this_cache) ++{ ++  struct sh_frame_cache *cache; ++  struct gdbarch_tdep *tdep = gdbarch_tdep (get_current_arch ()); ++  CORE_ADDR sigcontext_addr; ++ ++  if (*this_cache) ++    return *this_cache; ++ ++  cache = sh_alloc_frame_cache (); ++ ++  cache->base = get_frame_register_unsigned (this_frame, SP_REGNUM); ++  sigcontext_addr = tdep->sigcontext_addr (this_frame); ++  if (tdep->sc_reg_offset) ++    { ++      int i; ++ ++      gdb_assert (tdep->sc_num_regs <= SH_NUM_REGS); ++ ++      for (i = 0; i < tdep->sc_num_regs; i++) ++	if (tdep->sc_reg_offset[i] != -1) ++	  cache->saved_regs[i] = sigcontext_addr + tdep->sc_reg_offset[i]; ++    } ++ ++  *this_cache = cache; ++  return cache; ++} ++ ++static void ++sh_linux_sigtramp_frame_this_id (struct frame_info *this_frame, void **this_cache, ++			     struct frame_id *this_id) ++{ ++  struct sh_frame_cache *cache = ++    sh_linux_sigtramp_frame_cache (this_frame, this_cache); ++ ++  (*this_id) = frame_id_build (cache->base + 64, cache->pc); ++} ++ ++extern struct value * sh_frame_prev_register (); ++static struct value * ++sh_linux_sigtramp_frame_prev_register (struct frame_info *this_frame, ++                   void **this_cache, int regnum) ++{ ++  sh_linux_sigtramp_frame_cache (this_frame, this_cache); ++ ++  return sh_frame_prev_register (this_frame, this_cache, regnum); ++} ++ ++static int ++sh_linux_sigtramp_frame_sniffer (const struct frame_unwind *self, ++                 struct frame_info *this_frame, ++                 void **this_prologue_cache) ++{ ++  struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (this_frame)); ++ ++  /* We shouldn't even bother if we don't have a sigcontext_addr ++     handler.  */ ++  if (tdep->sigcontext_addr == NULL) ++    return 0; ++ ++  if (tdep->sigtramp_p != NULL) ++    { ++      if (tdep->sigtramp_p (this_frame)) ++    return 1; ++    } ++ ++  return 0; ++} ++ ++static const struct frame_unwind sh_linux_sigtramp_frame_unwind = ++{ ++  SIGTRAMP_FRAME, ++  sh_linux_sigtramp_frame_this_id, ++  sh_linux_sigtramp_frame_prev_register, ++  NULL, ++  sh_linux_sigtramp_frame_sniffer ++}; ++ ++/* Supply register REGNUM from the buffer specified by GREGS and LEN ++   in the general-purpose register set REGSET to register cache ++   REGCACHE.  If REGNUM is -1, do this for all registers in REGSET.  */ ++ ++void ++sh_supply_gregset (const struct regset *regset, struct regcache *regcache, ++             int regnum, const void *gregs, size_t len) ++{ ++  const struct gdbarch_tdep *tdep = gdbarch_tdep (regset->arch); ++  const char *regs = gregs; ++  int i; ++ ++  gdb_assert (len == tdep->sizeof_gregset); ++ ++  for (i = 0; i < tdep->gregset_num_regs; i++) ++    { ++      if ((regnum == i || regnum == -1) ++      && tdep->gregset_reg_offset[i] != -1) ++    regcache_raw_supply (regcache, i, regs + tdep->gregset_reg_offset[i]); ++    } ++} ++ ++/* Collect register REGNUM from the register cache REGCACHE and store ++   it in the buffer specified by GREGS and LEN as described by the ++   general-purpose register set REGSET.  If REGNUM is -1, do this for ++   all registers in REGSET.  */ ++ ++void ++sh_collect_gregset (const struct regset *regset, ++              const struct regcache *regcache, ++              int regnum, void *gregs, size_t len) ++{ ++  const struct gdbarch_tdep *tdep = gdbarch_tdep (regset->arch); ++  char *regs = gregs; ++  int i; ++ ++  gdb_assert (len == tdep->sizeof_gregset); ++ ++  for (i = 0; i < tdep->gregset_num_regs; i++) ++    { ++      if ((regnum == i || regnum == -1) ++      && tdep->gregset_reg_offset[i] != -1) ++    regcache_raw_collect (regcache, i, regs + tdep->gregset_reg_offset[i]); ++    } ++} ++ ++/* Supply register REGNUM from the buffer specified by FPREGS and LEN ++   in the floating-point register set REGSET to register cache ++   REGCACHE.  If REGNUM is -1, do this for all registers in REGSET.  */ ++ ++static void ++sh_supply_fpregset (const struct regset *regset, struct regcache *regcache, ++              int regnum, const void *fpregs, size_t len) ++{ ++  const struct gdbarch_tdep *tdep = gdbarch_tdep (regset->arch); ++  const char *regs = fpregs; ++  int i; ++ ++  gdb_assert (len == tdep->sizeof_fpregset); ++  for (i = 0; i < 16; i++) ++    { ++      if (regnum == i+25 || regnum == -1) ++    regcache_raw_supply (regcache, i+25, regs + i*4); ++    } ++  if (regnum == FPSCR_REGNUM || regnum == -1) ++    regcache_raw_supply (regcache, FPSCR_REGNUM, regs + 32*4); ++  if (regnum == FPUL_REGNUM || regnum == -1) ++    regcache_raw_supply (regcache, FPUL_REGNUM, regs + 33*4); ++} ++ ++/* Collect register REGNUM from the register cache REGCACHE and store ++   it in the buffer specified by FPREGS and LEN as described by the ++   floating-point register set REGSET.  If REGNUM is -1, do this for ++   all registers in REGSET.  */ ++ ++static void ++sh_collect_fpregset (const struct regset *regset, ++               const struct regcache *regcache, ++               int regnum, void *fpregs, size_t len) ++{ ++  const struct gdbarch_tdep *tdep = gdbarch_tdep (regset->arch); ++  char *regs = fpregs; ++  int i; ++ ++  gdb_assert (len == tdep->sizeof_fpregset); ++  for (i = 0; i < 16; i++) ++    { ++      if (regnum == i+25 || regnum == -1) ++    regcache_raw_collect (regcache, i+25, regs + i*4); ++    } ++  if (regnum == FPSCR_REGNUM || regnum == -1) ++    regcache_raw_collect (regcache, FPSCR_REGNUM, regs + 32*4); ++  if (regnum == FPUL_REGNUM || regnum == -1) ++    regcache_raw_collect (regcache, FPUL_REGNUM, regs + 33*4); ++} ++ ++/* Return the appropriate register set for the core section identified ++   by SECT_NAME and SECT_SIZE.  */ ++ ++const struct regset * ++sh_linux_regset_from_core_section (struct gdbarch *gdbarch, ++                   const char *sect_name, size_t sect_size) ++{ ++  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); ++ ++  if (strcmp (sect_name, ".reg") == 0 && sect_size == tdep->sizeof_gregset) ++    { ++      if (tdep->gregset == NULL) ++    tdep->gregset = regset_alloc (gdbarch, sh_supply_gregset, ++                      sh_collect_gregset); ++      return tdep->gregset; ++    } ++ ++  if ((strcmp (sect_name, ".reg2") == 0 && sect_size == tdep->sizeof_fpregset)) ++    { ++      if (tdep->fpregset == NULL) ++    tdep->fpregset = regset_alloc (gdbarch, sh_supply_fpregset, ++                       sh_collect_fpregset); ++      return tdep->fpregset; ++    } ++ ++  return NULL; ++} ++ ++/* The register sets used in GNU/Linux ELF core-dumps are identical to ++   the register sets in `struct user' that are used for a.out ++   core-dumps.  These are also used by ptrace(2).  The corresponding ++   types are `elf_gregset_t' for the general-purpose registers (with ++   `elf_greg_t' the type of a single GP register) and `elf_fpregset_t' ++   for the floating-point registers. ++ ++   Those types used to be available under the names `gregset_t' and ++   `fpregset_t' too, and GDB used those names in the past.  But those ++   names are now used for the register sets used in the `mcontext_t' ++   type, which have a different size and layout.  */ ++ ++/* Mapping between the general-purpose registers in `struct user' ++   format and GDB's register cache layout.  */ ++ ++/* From <sys/reg.h>.  */ ++static int sh_linux_gregset_reg_offset[] = ++{ ++ 0,	4,	8,	12,	16,	20,	24,	28, ++ 32,	36,	40,	44,	48,	52,	56,	60, ++ ++ REG_PC*4,   REG_PR*4,   REG_GBR*4,  -1, ++ REG_MACH*4, REG_MACL*4, REG_SR*4, ++}; ++ ++/* Mapping between the general-purpose registers in `struct ++   sigcontext' format and GDB's register cache layout.  */ ++ ++/* From <asm/sigcontext.h>.  */ ++static int sh_linux_sc_reg_offset[] = ++{ ++ 4,	8,	12,	16,	20,	24,	28,	32, ++ 36,	40,	44,	48,	52,	56,	60,	64, ++ 68,	72,	80,	-1, ++ 84,	88,	76 ++}; ++ + static void + sh_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) + { ++  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); ++  bfd abfd; ++ ++  tdep->gregset_reg_offset = sh_linux_gregset_reg_offset; ++  tdep->gregset_num_regs = ARRAY_SIZE (sh_linux_gregset_reg_offset); ++  tdep->sizeof_gregset = 23 * 4; ++ ++  tdep->jb_pc_offset = 32;     /* From <bits/setjmp.h>.  */ ++ ++  tdep->sigtramp_p = sh_linux_sigtramp_p; ++  tdep->sigcontext_addr = sh_linux_sigcontext_addr; ++  tdep->sc_reg_offset = sh_linux_sc_reg_offset; ++  tdep->sc_num_regs = ARRAY_SIZE (sh_linux_sc_reg_offset); ++ ++  frame_unwind_append_unwinder(gdbarch, &sh_linux_sigtramp_frame_unwind); ++ ++  /* If we have a register mapping, enable the generic core file ++     support, unless it has already been enabled.  */ ++  if (tdep->gregset_reg_offset ++      && !gdbarch_regset_from_core_section_p (gdbarch)) ++    set_gdbarch_regset_from_core_section (gdbarch, ++                                         sh_linux_regset_from_core_section); ++ +   linux_init_abi (info, gdbarch); +  +   /* GNU/Linux uses SVR4-style shared libraries.  */ +Index: gdb-7.4/gdb/sh-tdep.h +=================================================================== +--- gdb-7.4.orig/gdb/sh-tdep.h	2012-04-24 07:06:35.101317178 -0700 ++++ gdb-7.4/gdb/sh-tdep.h	2012-04-24 07:09:14.369324886 -0700 +@@ -21,6 +21,12 @@ +  + /* Contributed by Steve Chamberlain sac@cygnus.com.  */ +  ++struct frame_info; ++struct gdbarch; ++struct reggroup; ++struct regset; ++struct regcache; ++ + /* Registers for all SH variants.  Used also by sh3-rom.c.  */ + enum +   { +@@ -29,6 +35,7 @@ +     ARG0_REGNUM = 4, +     ARGLAST_REGNUM = 7, +     FP_REGNUM = 14, ++    SP_REGNUM = 15, +     PC_REGNUM = 16, +     PR_REGNUM = 17, +     GBR_REGNUM = 18, +@@ -82,8 +89,26 @@ +     FV_LAST_REGNUM = 79 +   }; +  ++#define SH_NUM_REGS 67 ++ ++struct sh_frame_cache ++{ ++  /* Base address.  */ ++  CORE_ADDR base; ++  LONGEST sp_offset; ++  CORE_ADDR pc; ++ ++  /* Flag showing that a frame has been created in the prologue code. */ ++  int uses_fp; ++ ++  /* Saved registers.  */ ++  CORE_ADDR saved_regs[SH_NUM_REGS]; ++  CORE_ADDR saved_sp; ++}; ++ + extern gdbarch_init_ftype sh64_gdbarch_init; + extern void sh64_show_regs (struct frame_info *); ++extern struct sh_frame_cache *sh_frame_cache (struct frame_info *next_frame, void **this_cache); +  + /* This structure describes a register in a core-file.  */ + struct sh_corefile_regmap +@@ -92,8 +117,32 @@ +   unsigned int offset; + }; +  ++/* sh architecture specific information.  */ + struct gdbarch_tdep + { ++  /* General-purpose registers.  */ ++  struct regset *gregset; ++  int *gregset_reg_offset; ++  int gregset_num_regs; ++  size_t sizeof_gregset; ++ ++  /* Floating-point registers.  */ ++  struct regset *fpregset; ++  size_t sizeof_fpregset; ++ ++  /* Offset of saved PC in jmp_buf.  */ ++  int jb_pc_offset; ++ ++  /* Detect sigtramp.  */ ++  int (*sigtramp_p) (struct frame_info *); ++ ++  /* Get address of sigcontext for sigtramp.  */ ++  CORE_ADDR (*sigcontext_addr) (struct frame_info *); ++ ++  /* Offset of registers in `struct sigcontext'.  */ ++  int *sc_reg_offset; ++  int sc_num_regs; ++ +   /* Non-NULL when debugging from a core file.  Provides the offset +      where each general-purpose register is stored inside the associated +      core file section.  */ +Index: gdb-7.4/gdb/sh-linux-nat.c +=================================================================== +--- /dev/null	1970-01-01 00:00:00.000000000 +0000 ++++ gdb-7.4/gdb/sh-linux-nat.c	2012-04-24 07:09:28.557325573 -0700 +@@ -0,0 +1,269 @@ ++/* Low level SH interface to ptrace, for GDB when running native. ++   Copyright (C) 2002, 2004 Free Software Foundation, Inc. ++ ++This file is part of GDB. ++ ++This program is free software; you can redistribute it and/or modify ++it under the terms of the GNU General Public License as published by ++the Free Software Foundation; either version 2 of the License, or ++(at your option) any later version. ++ ++This program is distributed in the hope that it will be useful, ++but WITHOUT ANY WARRANTY; without even the implied warranty of ++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the ++GNU General Public License for more details. ++ ++You should have received a copy of the GNU General Public License ++along with this program; if not, write to the Free Software ++Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */ ++ ++#include "defs.h" ++#include "inferior.h" ++#include "gdbcore.h" ++#include "regcache.h" ++#include "linux-nat.h" ++#include "target.h" ++#include "arch-utils.h" ++ ++#include "gdb_assert.h" ++#include "gdb_string.h" ++#include <sys/ptrace.h> ++#include <sys/user.h> ++#include <sys/procfs.h> ++#include <asm/ptrace.h> ++ ++/* Prototypes for supply_gregset etc. */ ++#include "gregset.h" ++#include "sh-tdep.h" ++ ++/* Defines ps_err_e, struct ps_prochandle.  */ ++#include "gdb_proc_service.h" ++ ++//#include <asm/elf.h> ++ ++#define SH_LINUX_NUM_REGS	40 ++/* This table must line up with REGISTER_NAME in "sh-tdep.c".  */ ++static const int regmap[] = ++{ ++  /* general registers 0-15 */ ++  REG_REG0   , REG_REG0+1 , REG_REG0+2 , REG_REG0+3, ++  REG_REG0+4 , REG_REG0+5 , REG_REG0+6 , REG_REG0+7, ++  REG_REG0+8 , REG_REG0+9 , REG_REG0+10, REG_REG0+11, ++  REG_REG0+12, REG_REG0+13, REG_REG0+14, REG_REG0+15, ++  /* 16 - 22 */ ++  REG_PC, REG_PR, REG_GBR, -1, REG_MACH, REG_MACL, REG_SR, ++  /* 23, 24 */ ++  REG_FPUL, REG_FPSCR, ++  /* floating point registers 25 - 40 */ ++  REG_FPREG0   , REG_FPREG0+1 , REG_FPREG0+2 , REG_FPREG0+3 , ++  REG_FPREG0+4 , REG_FPREG0+5 , REG_FPREG0+6 , REG_FPREG0+7 , ++  REG_FPREG0+8 , REG_FPREG0+9 , REG_FPREG0+10, REG_FPREG0+11, ++  REG_FPREG0+12, REG_FPREG0+13, REG_FPREG0+14, REG_FPREG0+15, ++}; ++ ++CORE_ADDR ++register_u_addr (CORE_ADDR blockend, int regnum) ++{ ++  if (regnum < 0 || regnum >= sizeof regmap/sizeof regmap[0]) ++    return (CORE_ADDR)-1; ++  return (blockend + 4 * regmap[regnum]); ++} ++ ++ ++/* Return the address in the core dump or inferior of register REGNO. ++   BLOCKEND is the address of the end of the user structure.  */ ++ ++CORE_ADDR ++register_addr (int regno, CORE_ADDR blockend) ++{ ++  CORE_ADDR addr; ++ ++  if (regno < 0 || regno >= SH_LINUX_NUM_REGS) { ++    internal_error (__FILE__, __LINE__, ++		  _("Got request for bad register number %d."), regno); ++  } ++ ++  REGISTER_U_ADDR (addr, blockend, regno); ++ ++  return addr; ++} ++ ++/* Fetch one register.  */ ++ ++static void ++fetch_register (struct regcache *regcache, int tid, int regno) ++{ ++  int val; ++ ++  if (cannot_fetch_register (regno)) ++    { ++      regcache_raw_supply (regcache, regno, NULL); ++      return; ++    } ++ ++  errno = 0; ++  val = ptrace (PTRACE_PEEKUSER, tid, register_addr (regno, 0), 0); ++  if (errno != 0) ++    perror_with_name (_("Couldn't get registers")); ++ ++  regcache_raw_supply (regcache, regno, &val); ++} ++ ++/* Store one register. */ ++ ++static void ++store_register (struct regcache *regcache, int tid, int regno) ++{ ++  int val; ++ ++  if (cannot_store_register (regno)) ++    return; ++ ++  errno = 0; ++  regcache_raw_collect (regcache, regno, &val); ++  ptrace (PTRACE_POKEUSER, tid, register_addr (regno, 0), val); ++  if (errno != 0) ++    perror_with_name (_("Couldn't write registers")); ++} ++ ++/* Transfering the general-purpose registers between GDB, inferiors ++   and core files.  */ ++ ++/* Fill GDB's register array with the general-purpose register values ++   in *GREGSETP.  */ ++ ++void ++supply_gregset (struct regcache *regcache, const elf_gregset_t *gregsetp) ++{ ++  elf_greg_t *regp = (elf_greg_t *) gregsetp; ++  int i; ++ ++  for (i = 0; i < 23; i++) ++    if (regmap[i] == -1) ++      regcache_raw_supply (regcache, i, NULL); ++    else ++      regcache_raw_supply (regcache, i, (char *) (regp + regmap[i])); ++} ++ ++/* Fill register REGNO (if it is a general-purpose register) in ++   *GREGSETPS with the value in GDB's register array.  If REGNO is -1, ++   do this for all registers.  */ ++ ++void ++fill_gregset (const struct regcache *regcache, elf_gregset_t *gregsetp, int regno) ++{ ++  elf_greg_t *regp = (elf_greg_t *) gregsetp; ++  int i; ++ ++  for (i = 0; i < 23; i++) ++    if (regmap[i] != -1 && (regno == -1 || regno == i)) ++      regcache_raw_collect (regcache, i, (char *) (regp + regmap[i])); ++} ++ ++/* Transfering floating-point registers between GDB, inferiors and cores.  */ ++ ++/* Fill GDB's register array with the floating-point register values in ++   *FPREGSETP.  */ ++ ++void ++supply_fpregset (struct regcache *regcache, const elf_fpregset_t *fpregsetp) ++{ ++  int i; ++  long *regp = (long *)fpregsetp; ++ ++  for (i = 0; i < 16; i++) ++    regcache_raw_supply (regcache, 25 + i, (char *) (regp + i)); ++  regcache_raw_supply (regcache, FPUL_REGNUM, (char *) (regp + REG_FPUL - REG_FPREG0)); ++  regcache_raw_supply (regcache, FPSCR_REGNUM, (char *) (regp + REG_FPSCR - REG_FPREG0)); ++} ++ ++/* Fill register REGNO (if it is a floating-point register) in ++   *FPREGSETP with the value in GDB's register array.  If REGNO is -1, ++   do this for all registers.  */ ++ ++void ++fill_fpregset (const struct regcache *regcache, elf_fpregset_t *fpregsetp, int regno) ++{ ++  int i; ++  long *regp = (long *)fpregsetp; ++ ++  for (i = 0; i < 16; i++) ++    if ((regno == -1) || (regno == i)) ++      regcache_raw_collect (regcache, 25 + i, (char *) (regp + i)); ++  if ((regno == -1) || regno == FPSCR_REGNUM) ++    regcache_raw_collect (regcache, FPSCR_REGNUM, (char *) (regp + REG_FPSCR - REG_FPREG0)); ++  if ((regno == -1) || regno == FPUL_REGNUM) ++    regcache_raw_collect (regcache, FPUL_REGNUM, (char *) (regp + REG_FPUL - REG_FPREG0)); ++} ++ ++/* Transferring arbitrary registers between GDB and inferior.  */ ++ ++/* Check if register REGNO in the child process is accessible. ++   If we are accessing registers directly via the U area, only the ++   general-purpose registers are available. ++   All registers should be accessible if we have GETREGS support.  */ ++ ++int ++cannot_fetch_register (int regno) ++{ ++  return (regno < 0 || regno >= sizeof regmap / sizeof regmap[0] || regmap[regno] == -1); ++} ++ ++int ++cannot_store_register (int regno) ++{ ++  return (regno < 0 || regno >= sizeof regmap / sizeof regmap[0] || regmap[regno] == -1); ++} ++ ++/* Fetch register values from the inferior. ++   If REGNO is negative, do this for all registers. ++   Otherwise, REGNO specifies which register (so we can save time). */ ++ ++static void ++sh_linux_fetch_inferior_registers (struct target_ops *ops, struct regcache *regcache, int regno) ++{ ++  int i; ++  int tid; ++ ++  /* GNU/Linux LWP ID's are process ID's.  */ ++  if ((tid = TIDGET (inferior_ptid)) == 0) ++    tid = PIDGET (inferior_ptid);	/* Not a threaded program.  */ ++ ++  for (i = 0; i < SH_LINUX_NUM_REGS; i++) ++    if (regno == -1 || regno == i) ++      fetch_register (regcache, tid, i); ++} ++/* Store our register values back into the inferior. ++   If REGNO is negative, do this for all registers. ++   Otherwise, REGNO specifies which register (so we can save time).  */ ++ ++static void ++sh_linux_store_inferior_registers (struct target_ops *ops, struct regcache *regcache, int regno) ++{ ++  int i; ++  int tid; ++ ++  /* GNU/Linux LWP ID's are process ID's.  */ ++  if ((tid = TIDGET (inferior_ptid)) == 0) ++    tid = PIDGET (inferior_ptid);	/* Not a threaded program.  */ ++ ++  for (i = 0; i < SH_LINUX_NUM_REGS; i++) ++    if (regno == -1 || regno == i) ++      store_register (regcache, tid, i); ++} ++ ++void ++_initialize_sh_linux_nat (void) ++{ ++  struct target_ops *t; ++ ++  /* Fill in the generic GNU/Linux methods.  */ ++  t = linux_target (); ++ ++  /* Add our register access methods.  */ ++  t->to_fetch_registers = sh_linux_fetch_inferior_registers; ++  t->to_store_registers = sh_linux_store_inferior_registers; ++ ++  /* Register the target.  */ ++  linux_nat_add_target (t); ++} +Index: gdb-7.4/gdb/sh-tdep.c +=================================================================== +--- gdb-7.4.orig/gdb/sh-tdep.c	2012-04-24 07:06:35.109317179 -0700 ++++ gdb-7.4/gdb/sh-tdep.c	2012-04-24 07:09:14.369324886 -0700 +@@ -21,6 +21,9 @@ +    sac@cygnus.com.  */ +  + #include "defs.h" ++#include "arch-utils.h" ++#include "command.h" ++#include "dummy-frame.h" + #include "frame.h" + #include "frame-base.h" + #include "frame-unwind.h" +@@ -37,6 +40,7 @@ + #include "arch-utils.h" + #include "floatformat.h" + #include "regcache.h" ++#include "regset.h" + #include "doublest.h" + #include "osabi.h" + #include "reggroups.h" +@@ -69,23 +73,6 @@ +  + static void (*sh_show_regs) (struct frame_info *); +  +-#define SH_NUM_REGS 67 +- +-struct sh_frame_cache +-{ +-  /* Base address.  */ +-  CORE_ADDR base; +-  LONGEST sp_offset; +-  CORE_ADDR pc; +- +-  /* Flag showing that a frame has been created in the prologue code.  */ +-  int uses_fp; +- +-  /* Saved registers.  */ +-  CORE_ADDR saved_regs[SH_NUM_REGS]; +-  CORE_ADDR saved_sp; +-}; +- + static int + sh_is_renesas_calling_convention (struct type *func_type) + { +@@ -1040,7 +1027,7 @@ +     return 0; +   /* Otherwise if the type of that member is float, the whole type is +      treated as float.  */ +-  if (TYPE_CODE (TYPE_FIELD_TYPE (type, 0)) == TYPE_CODE_FLT) ++  if (TYPE_CODE (check_typedef (TYPE_FIELD_TYPE (type, 0))) == TYPE_CODE_FLT) +     return 1; +   /* Otherwise it's not treated as float.  */ +   return 0; +@@ -1090,7 +1077,7 @@ +      in four registers available.  Loop thru args from first to last.  */ +   for (argnum = 0; argnum < nargs; argnum++) +     { +-      type = value_type (args[argnum]); ++      type = check_typedef (value_type (args[argnum])); +       len = TYPE_LENGTH (type); +       val = sh_justify_value_in_reg (gdbarch, args[argnum], len); +  +@@ -2508,7 +2495,7 @@ +     reg->how = DWARF2_FRAME_REG_UNDEFINED; + } +  +-static struct sh_frame_cache * ++struct sh_frame_cache * + sh_alloc_frame_cache (void) + { +   struct sh_frame_cache *cache; +@@ -2535,7 +2522,7 @@ +   return cache; + } +  +-static struct sh_frame_cache * ++struct sh_frame_cache * + sh_frame_cache (struct frame_info *this_frame, void **this_cache) + { +   struct gdbarch *gdbarch = get_frame_arch (this_frame); +@@ -2593,9 +2580,9 @@ +   return cache; + } +  +-static struct value * +-sh_frame_prev_register (struct frame_info *this_frame, +-			void **this_cache, int regnum) ++struct value * ++sh_frame_prev_register (struct frame_info *this_frame, void **this_cache, ++			int regnum) + { +   struct gdbarch *gdbarch = get_frame_arch (this_frame); +   struct sh_frame_cache *cache = sh_frame_cache (this_frame, this_cache); +@@ -2609,7 +2596,7 @@ +      the current frame.  Frob regnum so that we pull the value from +      the correct place.  */ +   if (regnum == gdbarch_pc_regnum (gdbarch)) +-    regnum = PR_REGNUM; ++    regnum = PR_REGNUM; /* XXX: really? */ +  +   if (regnum < SH_NUM_REGS && cache->saved_regs[regnum] != -1) +     return frame_unwind_got_memory (this_frame, regnum, +@@ -2853,8 +2840,8 @@ + static struct gdbarch * + sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) + { +-  struct gdbarch *gdbarch; +   struct gdbarch_tdep *tdep; ++  struct gdbarch *gdbarch; +  +   sh_show_regs = sh_generic_show_regs; +   switch (info.bfd_arch_info->mach) +@@ -2917,6 +2904,18 @@ +   tdep = XZALLOC (struct gdbarch_tdep); +   gdbarch = gdbarch_alloc (&info, tdep); +  ++  /* General-purpose registers.  */ ++  tdep->gregset = NULL; ++  tdep->gregset_reg_offset = NULL; ++  tdep->gregset_num_regs = 23; ++  tdep->sizeof_gregset = 0; ++ ++  /* Floating-point registers.  */ ++  tdep->fpregset = NULL; ++  tdep->sizeof_fpregset = 34*4; ++ ++  tdep->jb_pc_offset = -1; ++ +   set_gdbarch_short_bit (gdbarch, 2 * TARGET_CHAR_BIT); +   set_gdbarch_int_bit (gdbarch, 4 * TARGET_CHAR_BIT); +   set_gdbarch_long_bit (gdbarch, 4 * TARGET_CHAR_BIT); +@@ -3062,10 +3061,11 @@ +       break; +     } +  ++  dwarf2_append_unwinders (gdbarch); ++ +   /* Hook in ABI-specific overrides, if they have been registered.  */ +   gdbarch_init_osabi (info, gdbarch); +  +-  dwarf2_append_unwinders (gdbarch); +   frame_unwind_append_unwinder (gdbarch, &sh_frame_unwind); +  +   return gdbarch; +Index: gdb-7.4/gdb/testsuite/gdb.asm/sh-linux.inc +=================================================================== +--- /dev/null	1970-01-01 00:00:00.000000000 +0000 ++++ gdb-7.4/gdb/testsuite/gdb.asm/sh-linux.inc	2012-04-24 07:09:14.369324886 -0700 +@@ -0,0 +1,78 @@ ++# You'll find a bunch of nop opcodes in the below macros.  They are ++# there to keep the code correctly aligned.  Be careful to maintain ++# them when changing the code. ++ ++	comment "subroutine declare" ++	.purgem gdbasm_declare ++	.macro gdbasm_declare name ++	.align	1 ++	.global	\name ++\name: ++	.endm ++ ++	comment "subroutine prologue" ++	.macro gdbasm_enter ++	mov.l   r14,@-r15 ++	sts.l   pr,@-r15 ++	mov     r15,r14 ++	nop ++	.endm ++ ++	comment "subroutine epilogue" ++	.macro gdbasm_leave ++	mov     r14,r15 ++	lds.l   @r15+,pr ++	mov.l   @r15+,r14 ++	rts ++	nop ++	nop ++	.endm ++ ++	comment "subroutine end" ++	.purgem gdbasm_end ++	.macro gdbasm_end name ++	.size   \name, .-_foo1 ++	.align	1 ++	.endm ++ ++	comment "subroutine call" ++	.macro gdbasm_call subr ++	mov.l   .Lconst\@,r1 ++	bra	.Lafterconst\@ ++	nop ++	.align	2 ++.Lconst\@: ++	.long	\subr ++.Lafterconst\@: ++	jsr	@r1 ++	nop ++	.endm ++ ++	.macro gdbasm_several_nops ++	nop ++	nop ++	nop ++	nop ++	.endm ++ ++	comment "exit (0)" ++	.macro gdbasm_exit0 ++	sleep ++	nop ++	.endm ++ ++	comment "crt0 startup" ++	.macro gdbasm_startup ++	mov	#0,r14 ++	.endm ++ ++	comment "Declare a data variable" ++	.purgem gdbasm_datavar ++	.macro gdbasm_datavar name value ++	.data ++	.align 2 ++	.type	\name, @object ++	.size	\name, 4 ++\name: ++	.long	\value ++	.endm +Index: gdb-7.4/gdb/testsuite/gdb.asm/sh.inc +=================================================================== +--- gdb-7.4.orig/gdb/testsuite/gdb.asm/sh.inc	2012-04-24 07:06:35.001317175 -0700 ++++ gdb-7.4/gdb/testsuite/gdb.asm/sh.inc	2012-04-24 07:09:14.369324886 -0700 +@@ -40,9 +40,8 @@ + 	mov.l   .Lconst\@,r1 + 	bra	.Lafterconst\@ + 	nop +-	nop +-.Lconst\@: + 	.align	2 ++.Lconst\@: + 	.long	\subr + 	.align	1 + .Lafterconst\@: +Index: gdb-7.4/gdb/testsuite/gdb.asm/asm-source.exp +=================================================================== +--- gdb-7.4.orig/gdb/testsuite/gdb.asm/asm-source.exp	2012-04-24 07:06:35.009317179 -0700 ++++ gdb-7.4/gdb/testsuite/gdb.asm/asm-source.exp	2012-04-24 07:09:14.369324886 -0700 +@@ -110,6 +110,11 @@ +             append link-flags " -m elf32ppc" +         } +     } ++    "sh*-linux*" { ++        set asm-arch sh-linux ++        set asm-flags "-I${srcdir}/${subdir} -I${objdir}/${subdir}" ++	set debug-flags "-gdwarf-2" ++    } +     "sh*-*-*" { +         set asm-arch sh + 	set debug-flags "-gdwarf-2" +Index: gdb-7.4/gdb/testsuite/gdb.base/sigall.c +=================================================================== +--- gdb-7.4.orig/gdb/testsuite/gdb.base/sigall.c	2012-04-24 07:06:35.037317176 -0700 ++++ gdb-7.4/gdb/testsuite/gdb.base/sigall.c	2012-04-24 07:09:14.369324886 -0700 +@@ -1,9 +1,9 @@ + #include <signal.h> + #include <unistd.h> +  +-#ifdef __sh__ +-#define signal(a,b)	/* Signals not supported on this target - make them go away */ +-#endif ++ ++ ++ +  + /* Signal handlers, we set breakpoints in them to make sure that the +    signals really get delivered.  */ +Index: gdb-7.4/gdb/testsuite/gdb.base/signals.c +=================================================================== +--- gdb-7.4.orig/gdb/testsuite/gdb.base/signals.c	2012-04-24 07:06:35.049317176 -0700 ++++ gdb-7.4/gdb/testsuite/gdb.base/signals.c	2012-04-24 07:09:14.373324884 -0700 +@@ -3,10 +3,10 @@ + #include <signal.h> + #include <unistd.h> +  +-#ifdef __sh__ +-#define signal(a,b)	/* Signals not supported on this target - make them go away */ +-#define alarm(a)	/* Ditto for alarm() */ +-#endif ++ ++ ++ ++ +  + static int count = 0; +  +Index: gdb-7.4/gdb/testsuite/gdb.base/annota1.c +=================================================================== +--- gdb-7.4.orig/gdb/testsuite/gdb.base/annota1.c	2012-04-24 07:06:35.021317172 -0700 ++++ gdb-7.4/gdb/testsuite/gdb.base/annota1.c	2012-04-24 07:09:14.373324884 -0700 +@@ -1,9 +1,9 @@ + #include <stdio.h> + #include <signal.h> +  +-#ifdef __sh__ +-#define signal(a,b)	/* Signals not supported on this target - make them go away */ +-#endif ++ ++ ++ +  +  + #ifdef PROTOTYPES +Index: gdb-7.4/gdb/testsuite/gdb.base/annota3.c +=================================================================== +--- gdb-7.4.orig/gdb/testsuite/gdb.base/annota3.c	2012-04-24 07:06:35.029317176 -0700 ++++ gdb-7.4/gdb/testsuite/gdb.base/annota3.c	2012-04-24 07:09:14.373324884 -0700 +@@ -1,9 +1,9 @@ + #include <stdio.h> + #include <signal.h> +  +-#ifdef __sh__ +-#define signal(a,b)	/* Signals not supported on this target - make them go away */ +-#endif ++ ++ ++ +  +  + #ifdef PROTOTYPES +Index: gdb-7.4/gdb/config/sh/xm-linux.h +=================================================================== +--- /dev/null	1970-01-01 00:00:00.000000000 +0000 ++++ gdb-7.4/gdb/config/sh/xm-linux.h	2012-04-24 07:09:14.373324884 -0700 +@@ -0,0 +1,32 @@ ++/* Native support for GNU/Linux, for GDB, the GNU debugger. ++   Copyright (C) 2000 Free Software Foundation, Inc. ++ ++This file is part of GDB. ++ ++This program is free software; you can redistribute it and/or modify ++it under the terms of the GNU General Public License as published by ++the Free Software Foundation; either version 2 of the License, or ++(at your option) any later version. ++ ++This program is distributed in the hope that it will be useful, ++but WITHOUT ANY WARRANTY; without even the implied warranty of ++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the ++GNU General Public License for more details. ++ ++You should have received a copy of the GNU General Public License ++along with this program; if not, write to the Free Software ++Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */ ++ ++#ifndef XM_LINUX_H ++#define XM_LINUX_H ++ ++#define HOST_BYTE_ORDER LITTLE_ENDIAN ++ ++#define HAVE_TERMIOS ++ ++#define NEED_POSIX_SETPGID ++ ++/* Need R_OK etc, but USG isn't defined.  */ ++#include <unistd.h> ++ ++#endif	/* #ifndef XM_LINUX_H */ +Index: gdb-7.4/gdb/config/sh/nm-linux.h +=================================================================== +--- /dev/null	1970-01-01 00:00:00.000000000 +0000 ++++ gdb-7.4/gdb/config/sh/nm-linux.h	2012-04-24 07:09:14.373324884 -0700 +@@ -0,0 +1,54 @@ ++/* Native-dependent definitions for SuperH running Linux, for GDB. ++   Copyright 2004 Free Software Foundation, Inc. ++ ++   This file is part of GDB. ++ ++   This program is free software; you can redistribute it and/or modify ++   it under the terms of the GNU General Public License as published by ++   the Free Software Foundation; either version 2 of the License, or ++   (at your option) any later version. ++ ++   This program is distributed in the hope that it will be useful, ++   but WITHOUT ANY WARRANTY; without even the implied warranty of ++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the ++   GNU General Public License for more details. ++ ++   You should have received a copy of the GNU General Public License ++   along with this program; if not, write to the Free Software ++   Foundation, Inc., 59 Temple Place - Suite 330, ++   Boston, MA 02111-1307, USA.  */ ++ ++#ifndef NM_LINUX_H ++#define NM_LINUX_H ++ ++/* Get generic Linux native definitions.  */ ++#include "config/nm-linux.h" ++/* Support for the user area.  */ ++ ++/* Return the size of the user struct.  */ ++extern int kernel_u_size (void); ++#define KERNEL_U_SIZE kernel_u_size() ++ ++/* This is the amount to substract from u.u_ar0 to get the offset in ++   the core file of the register values.  */ ++#define KERNEL_U_ADDR 0 ++ ++#define U_REGS_OFFSET 0 ++ ++extern CORE_ADDR register_u_addr (CORE_ADDR blockend, int regnum); ++#define REGISTER_U_ADDR(addr, blockend, regnum) \ ++  (addr) = register_u_addr (blockend, regnum) ++ ++/* Override copies of {fetch,store}_inferior_registers in `infptrace.c'.  */ ++#define FETCH_INFERIOR_REGISTERS ++ ++/* Nevertheless, define CANNOT_{FETCH,STORE}_REGISTER, because we ++   might fall back on the code `infptrace.c' (well a copy of that code ++   in `sh-linux-nat.c' for now) and we can access only the ++   general-purpose registers in that way.  */ ++extern int cannot_fetch_register (int regno); ++extern int cannot_store_register (int regno); ++#define CANNOT_FETCH_REGISTER(regno) cannot_fetch_register (regno) ++#define CANNOT_STORE_REGISTER(regno) cannot_store_register (regno) ++ ++#endif /* NM_LINUX_H */ +Index: gdb-7.4/gdb/config/sh/linux.mh +=================================================================== +--- /dev/null	1970-01-01 00:00:00.000000000 +0000 ++++ gdb-7.4/gdb/config/sh/linux.mh	2012-04-24 07:36:11.709403160 -0700 +@@ -0,0 +1,8 @@ ++# Host: Renesas Super-H running GNU/Linux ++NAT_FILE= config/sh/nm-linux.h ++NATDEPFILES= inf-ptrace.o fork-child.o corelow.o sh-linux-nat.o \ ++	proc-service.o linux-thread-db.o gcore.o \ ++	linux-nat.o linux-osdata.o linux-fork.o linux-procfs.o ++ ++NAT_CDEPS = $(srcdir)/proc-service.list ++LOADLIBES= -ldl $(RDYNAMIC) | 
