gdb: add 7.2a from newer OE
authorGrazvydas Ignotas <notasas@gmail.com>
Sat, 12 Jul 2014 23:28:42 +0000 (02:28 +0300)
committerGrazvydas Ignotas <notasas@gmail.com>
Sat, 12 Jul 2014 23:31:25 +0000 (02:31 +0300)
14 files changed:
recipes/gdb/files/gdb-fix-sim-ppc.patch [new file with mode: 0644]
recipes/gdb/gdb-7.2a/gdb-6.8-fix-compile-karmic.patch [new file with mode: 0644]
recipes/gdb/gdb-7.2a/gdb-6.8-mingw-3.patch [new file with mode: 0644]
recipes/gdb/gdb-7.2a/gdb-6.8-pr9638-ppc-canadian-configh.patch [new file with mode: 0644]
recipes/gdb/gdb-7.2a/gdb-tcsetpgrp.patch [new file with mode: 0644]
recipes/gdb/gdb-7.2a/gdbserver-cflags-last.diff [new file with mode: 0644]
recipes/gdb/gdb-7.2a/renesas-sh-native-support.patch [new file with mode: 0644]
recipes/gdb/gdb-common.inc
recipes/gdb/gdb-cross-sdk.inc [new file with mode: 0644]
recipes/gdb/gdb-cross-sdk_7.2a.bb [new file with mode: 0644]
recipes/gdb/gdb-cross_7.2a.bb [new file with mode: 0644]
recipes/gdb/gdb.inc
recipes/gdb/gdb_7.2a.bb [new file with mode: 0644]
recipes/gdb/gdbserver_7.2a.bb [new file with mode: 0644]

diff --git a/recipes/gdb/files/gdb-fix-sim-ppc.patch b/recipes/gdb/files/gdb-fix-sim-ppc.patch
new file mode 100644 (file)
index 0000000..9457991
--- /dev/null
@@ -0,0 +1,13 @@
+Index: gdb-7.1/sim/ppc/Makefile.in
+===================================================================
+--- gdb-7.1.orig/sim/ppc/Makefile.in   2010-06-15 16:37:51.103007443 +0400
++++ gdb-7.1/sim/ppc/Makefile.in        2010-06-15 16:38:07.417068246 +0400
+@@ -551,7 +551,7 @@
+ PACKAGE_OBJ = @sim_pk_obj@
+-psim: $(TARGETLIB) main.o $(LIBIBERTY_LIB) $(BFD_LIB) $(LIBS) $(LIBINTL_DEP)
++psim: $(TARGETLIB) main.o $(LIBIBERTY_LIB) $(BFD_LIB) $(LIBINTL_DEP)
+       $(CC) $(CFLAGS) $(SIM_CFLAGS) $(LDFLAGS) -o psim$(EXEEXT) main.o $(TARGETLIB) $(BFD_LIB) $(LIBINTL) $(LIBIBERTY_LIB) $(LIBS)
+ run: psim
diff --git a/recipes/gdb/gdb-7.2a/gdb-6.8-fix-compile-karmic.patch b/recipes/gdb/gdb-7.2a/gdb-6.8-fix-compile-karmic.patch
new file mode 100644 (file)
index 0000000..1080b16
--- /dev/null
@@ -0,0 +1,22 @@
+fix this on karmic
+
+cc1: warnings being treated as errors
+/home/ich/build/arm/armv5t/tmp/work/i686-armv5te-sdk-oe-linux-gnueabi/gdb-cross-sdk-6.8-r2/gdb-6.8/gdb/eval.c: In function 'evaluate_subexp_standard':
+/home/ich/build/arm/armv5t/tmp/work/i686-armv5te-sdk-oe-linux-gnueabi/gdb-cross-sdk-6.8-r2/gdb-6.8/gdb/eval.c:1705: error: 'subscript_array' may be used uninitialized in this function
+/home/ich/build/arm/armv5t/tmp/work/i686-armv5te-sdk-oe-linux-gnueabi/gdb-cross-sdk-6.8-r2/gdb-6.8/gdb/eval.c:1644: note: 'subscript_array' was declared here
+
+
+
+Index: gdb-6.8/gdb/eval.c
+===================================================================
+--- gdb-6.8.orig/gdb/eval.c    2009-08-02 03:25:20.000000000 +0200
++++ gdb-6.8/gdb/eval.c 2009-08-02 03:53:39.000000000 +0200
+@@ -1656,6 +1656,8 @@
+       if (nargs != ndimensions)
+         error (_("Wrong number of subscripts"));
++        memset(&subscript_array, 0, sizeof(subscript_array));
++
+       /* Now that we know we have a legal array subscript expression 
+          let us actually find out where this element exists in the array. */
diff --git a/recipes/gdb/gdb-7.2a/gdb-6.8-mingw-3.patch b/recipes/gdb/gdb-7.2a/gdb-6.8-mingw-3.patch
new file mode 100644 (file)
index 0000000..5bede42
--- /dev/null
@@ -0,0 +1,374 @@
+Index: gdb-7.0/gdb/gdbserver/remote-utils.c
+===================================================================
+--- gdb-7.0.orig/gdb/gdbserver/remote-utils.c  2009-07-06 11:31:20.000000000 -0700
++++ gdb-7.0/gdb/gdbserver/remote-utils.c       2009-10-13 15:16:16.495396950 -0700
+@@ -778,7 +778,12 @@ input_interrupt (int unused)
+       cc = read (remote_desc, &c, 1);
++#ifdef _WIN32_WINNT
++      // its normal in windows for current_inferior to be null.
++      if (cc != 1 || c != '\003' /*|| current_inferior == NULL*/)
++#else
+       if (cc != 1 || c != '\003' || current_inferior == NULL)
++#endif
+       {
+         fprintf (stderr, "input_interrupt, count = %d c = %d ('%c')\n",
+                  cc, c, c);
+Index: gdb-7.0/gdb/gdbserver/server.c
+===================================================================
+--- gdb-7.0.orig/gdb/gdbserver/server.c        2009-06-30 09:35:25.000000000 -0700
++++ gdb-7.0/gdb/gdbserver/server.c     2009-10-13 15:18:08.065401029 -0700
+@@ -31,6 +31,9 @@
+ #if HAVE_MALLOC_H
+ #include <malloc.h>
+ #endif
++#ifdef _WIN32
++#include <windows.h>
++#endif
+ ptid_t cont_thread;
+ ptid_t general_thread;
+@@ -502,6 +505,20 @@ monitor_show_help (void)
+   monitor_output ("    Enable h/w breakpoint/watchpoint debugging messages\n");
+   monitor_output ("  set remote-debug <0|1>\n");
+   monitor_output ("    Enable remote protocol debugging messages\n");
++#ifdef _WIN32
++  monitor_output ("  get processlist\n");
++  monitor_output ("    List remote processes with names and pid\n");
++  monitor_output ("  get processlistmi\n");
++  monitor_output ("    Process list in an MI-like format\n");
++#endif
++  monitor_output ("  set env <name=value>\n");
++  monitor_output ("    Set environment variable in remote environment\n");
++  monitor_output ("  cd <directory>\n");
++  monitor_output ("    Change current working directory\n");
++  monitor_output ("  pwd\n");
++  monitor_output ("    Print current working directory\n");
++  monitor_output ("  shell <command line>\n");
++  monitor_output ("    Execute command on remote target\n");
+   monitor_output ("  exit\n");
+   monitor_output ("    Quit GDBserver\n");
+ }
+@@ -660,6 +677,47 @@ handle_search_memory (char *own_buf, int
+       return;                                 \
+     }
++#ifdef _WIN32
++typedef DWORD (__stdcall *GETPROCESSIMAGEFILENAME)(HANDLE hProcess, LPTSTR lpImageFileName, DWORD nSize);
++typedef BOOL (__stdcall *ENUMPROCESSES)(DWORD* pProcessIds, DWORD cb, DWORD* pBytesReturned);
++
++# define HAS_DEVICE(P) \
++((((P)[0] >= 'A' && (P)[0] <= 'Z') || ((P)[0] >= 'a' && (P)[0] <= 'z')) \
++&& (P)[1] == ':')
++# define FILE_SYSTEM_PREFIX_LEN(P) (HAS_DEVICE (P) ? 2 : 0)
++# define ISSLASH(C) ((C) == '/' || (C) == '\\')
++
++char *
++__basename (char const *name)
++{
++      char const *base = name += FILE_SYSTEM_PREFIX_LEN (name);
++      int all_slashes = 1;
++      char const *p;
++      
++      for (p = name; *p; p++)
++    {
++              if (ISSLASH (*p))
++                      base = p + 1;
++              else
++                      all_slashes = 0;
++    }
++      
++      /* If NAME is all slashes, arrange to return `/'.  */
++      if (*base == '\0' && ISSLASH (*name) && all_slashes)
++              --base;
++      
++      /* Make sure the last byte is not a slash.  */
++      //assert (all_slashes || !ISSLASH (*(p - 1)));
++      
++      return (char *) base;
++}
++#endif
++
++#ifndef _POSIX_PATH_MAX
++#define _POSIX_PATH_MAX 1024
++#define _POSIX_PATH_MAX_WAS_UNDEFINED
++#endif
++
+ /* Handle all of the extended 'q' packets.  */
+ void
+ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
+@@ -1216,6 +1274,158 @@ handle_query (char *own_buf, int packet_
+         debug_threads = 1;
+         monitor_output ("Debug output enabled.\n");
+       }
++#ifdef _WIN32
++  else if (strncmp (mon, "get processlist", 15) == 0)
++  {
++        HINSTANCE lib = LoadLibrary("PSAPI.DLL");
++        GETPROCESSIMAGEFILENAME imageFilename = (GETPROCESSIMAGEFILENAME)GetProcAddress(lib, "GetProcessImageFileNameA");
++        ENUMPROCESSES enumProcesses = (ENUMPROCESSES)GetProcAddress(lib, "EnumProcesses");
++        
++        char* name = (char*)malloc(MAX_PATH);
++        
++        int miMode = (strcmp(mon, "get processlistmi") == 0);
++        
++        DWORD* pids = (DWORD*)malloc(sizeof(DWORD)*1024);
++        memset(pids, 0, sizeof(pids));
++        DWORD size = 0;
++        
++        if (!enumProcesses(pids, 1024 * sizeof(DWORD), &size))
++        {
++                free(pids);
++                free(mon);
++                return;
++        }
++        
++        int cnt = 0;
++        int number = size / sizeof(DWORD);
++        
++        char* miOutput = NULL;
++        
++        if (!miMode) 
++                monitor_output("Remote process list:\n");
++        else
++        {
++                miOutput = (char*)malloc((number * 255) * sizeof(char));
++                strcpy(miOutput, "^done,processlist=[");
++        }
++        
++        for (cnt = 0; cnt < number; cnt++)
++        {
++                HMODULE hProcess = (HMODULE)OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pids[cnt]);
++                strcpy(name, "");
++                printf(name);
++                
++                imageFilename(hProcess, name, MAX_PATH);
++                
++                if (pids[cnt] > 4 && strcmp(name, "") != 0)
++                {
++                        char item[2048] = "";
++                        char tmp[24] = "0";
++                        itoa(pids[cnt], tmp, 10);
++                        strcat(item, tmp);
++                        strcat(item, "=");
++                        strcat(item, __basename(name));
++                        
++                        if (!miMode)
++                        {
++                                strcat(item, "\n");
++                                monitor_output(item);
++                        }
++                        else
++                        {
++                                strcat(miOutput, item);
++                                strcat(miOutput, ",");
++                        }
++                }
++                
++                CloseHandle(hProcess);
++        }
++        
++        if (miMode)
++        {
++                strcat(miOutput, "]\n");
++                monitor_output(miOutput);
++                free(miOutput);
++        }
++        
++        FreeLibrary(lib);
++        
++        free(pids);
++        free(name);     
++  }
++#endif                
++  else if (strncmp (mon, "set env ", 8) == 0)
++  {
++        char* envLine = mon + 8;
++        char* envName = strtok(envLine, "= ");
++        char* envValue = strtok(NULL, "= ");
++        if (envName && envValue)
++        {
++#ifdef _WIN32
++                SetEnvironmentVariable(envName, envValue);
++#else
++                setenv(envName, envValue, 1);
++#endif 
++                monitor_output("Target environment variable set (");
++                monitor_output(envName);
++                monitor_output(" = ");
++                monitor_output(envValue);
++                monitor_output(").\n");
++        }
++        else
++                monitor_output("Incorrect format for environment variable.\n");
++  }
++  else if (strncmp (mon, "cd ", 3) == 0)
++  {
++        char* dir = mon + 3;
++        if (strlen(dir) > 0)
++                chdir(dir);
++  }
++  else if (strcmp(mon, "pwd") == 0)
++  {
++        long size = _POSIX_PATH_MAX;
++        char* current_directory = (char*)malloc(size);          
++        getcwd(current_directory, size);
++        if (strlen(current_directory) > 0)
++        {
++                monitor_output(current_directory);
++                monitor_output("\n");
++        }
++        free(current_directory);
++  }
++  else if (strncmp (mon, "shell ", 6) == 0)
++  {
++        char* arg = mon + 6;
++        
++        if (strlen(arg) == 0)
++        {
++                monitor_output("Inferior shells are not supported.");
++                free(mon);
++                return;
++        }
++        
++        long size = _POSIX_PATH_MAX;
++        char* current_directory = (char*)malloc(size);  
++        getcwd(current_directory, size);
++
++        int rc = system (arg);
++        char msg[255];
++        if (rc == -1)
++        {
++                sprintf(msg, "Cannot execute '%s': %s.\n", arg, strerror(errno));
++                monitor_output(msg);
++        }
++        else if (rc != -1)
++        {
++                sprintf(msg, "'%s' exited with status %d.\n", arg, rc);
++                monitor_output(msg);
++        }
++
++        /* Make sure to return to the directory GDB thinks it is, in case the
++         shell command we just ran changed it.  */
++        chdir(current_directory);
++        free(current_directory);
++  }
+       else if (strcmp (mon, "set debug 0") == 0)
+       {
+         debug_threads = 0;
+@@ -1295,6 +1505,11 @@ handle_query (char *own_buf, int packet_
+   own_buf[0] = 0;
+ }
++#ifdef _POSIX_PATH_MAX_WAS_UNDEFINED
++#undef _POSIX_PATH_MAX
++#undef _POSIX_PATH_MAX_WAS_UNDEFINED
++#endif
++
+ /* Parse vCont packets.  */
+ void
+ handle_v_cont (char *own_buf)
+Index: gdb-7.0/gdb/gdbserver/win32-low.c
+===================================================================
+--- gdb-7.0.orig/gdb/gdbserver/win32-low.c     2009-07-04 11:13:28.000000000 -0700
++++ gdb-7.0/gdb/gdbserver/win32-low.c  2009-10-13 15:16:16.495396950 -0700
+@@ -38,7 +38,7 @@
+ #include <sys/cygwin.h>
+ #endif
+-#define LOG 0
++#define LOG 1
+ #define OUTMSG(X) do { printf X; fflush (stdout); } while (0)
+ #if LOG
+@@ -556,9 +556,9 @@ win32_create_inferior (char *program, ch
+     }
+   OUTMSG2 (("Command line is \"%s\"\n", args));
+-#ifdef CREATE_NEW_PROCESS_GROUP
++//#ifdef CREATE_NEW_PROCESS_GROUP
+   flags |= CREATE_NEW_PROCESS_GROUP;
+-#endif
++//#endif
+   ret = create_process (program, args, flags, &pi);
+   err = GetLastError ();
+@@ -699,8 +699,37 @@ win32_kill (int pid)
+   if (current_process_handle == NULL)
+     return -1;
+-  TerminateProcess (current_process_handle, 0);
+-  for (;;)
++      TerminateProcess (current_process_handle, 0);
++
++      // BKS - fix for terminating apps prior to their exit, lets go of execs.
++      winapi_DebugActiveProcessStop DebugActiveProcessStop = NULL;
++      winapi_DebugSetProcessKillOnExit DebugSetProcessKillOnExit = NULL;
++#ifdef _WIN32_WCE
++      HMODULE dll = GetModuleHandle (_T("COREDLL.DLL"));
++#else
++      HMODULE dll = GetModuleHandle (_T("KERNEL32.DLL"));
++#endif
++      DebugActiveProcessStop = GETPROCADDRESS (dll, DebugActiveProcessStop);
++      DebugSetProcessKillOnExit = GETPROCADDRESS (dll, DebugSetProcessKillOnExit);
++
++      if (DebugSetProcessKillOnExit != NULL
++              && DebugActiveProcessStop != NULL)
++      {
++              {
++                      struct thread_resume resume;
++                      resume.thread = -1;
++                      resume.step = 0;
++                      resume.sig = 0;
++                      resume.leave_stopped = 0;
++                      win32_resume (&resume);
++              }
++
++              DebugActiveProcessStop (current_process_id);
++              DebugSetProcessKillOnExit (FALSE);
++      }
++      // end BKS
++
++   for (;;)
+     {
+       if (!child_continue (DBG_CONTINUE, -1))
+       break;
+@@ -1207,6 +1236,7 @@ handle_exception (struct target_waitstat
+   ourstatus->kind = TARGET_WAITKIND_STOPPED;
++      //printf("handle exception....................%X\n", (unsigned int)code);
+   switch (code)
+     {
+     case EXCEPTION_ACCESS_VIOLATION:
+@@ -1217,7 +1247,13 @@ handle_exception (struct target_waitstat
+       OUTMSG2 (("STATUS_STACK_OVERFLOW"));
+       ourstatus->value.sig = TARGET_SIGNAL_SEGV;
+       break;
+-    case STATUS_FLOAT_DENORMAL_OPERAND:
++      // BKS
++      case STATUS_INVALID_HANDLE:
++      OUTMSG2 (("STATUS_INVALID_HANDLE"));
++        ourstatus->value.sig = TARGET_SIGNAL_TRAP;
++        break;
++      // BKS
++      case STATUS_FLOAT_DENORMAL_OPERAND:
+       OUTMSG2 (("STATUS_FLOAT_DENORMAL_OPERAND"));
+       ourstatus->value.sig = TARGET_SIGNAL_FPE;
+       break;
+Index: gdb-7.0/gdb/windows-nat.c
+===================================================================
+--- gdb-7.0.orig/gdb/windows-nat.c     2009-09-30 00:40:10.000000000 -0700
++++ gdb-7.0/gdb/windows-nat.c  2009-10-13 15:16:16.505397243 -0700
+@@ -1035,6 +1035,10 @@ handle_exception (struct target_waitstat
+       DEBUG_EXCEPTION_SIMPLE ("STATUS_STACK_OVERFLOW");
+       ourstatus->value.sig = TARGET_SIGNAL_SEGV;
+       break;
++      case STATUS_INVALID_HANDLE:
++        DEBUG_EXCEPTION_SIMPLE ("STATUS_INVALID_HANDLE");
++        ourstatus->value.sig = TARGET_SIGNAL_TRAP;
++        break;
+     case STATUS_FLOAT_DENORMAL_OPERAND:
+       DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DENORMAL_OPERAND");
+       ourstatus->value.sig = TARGET_SIGNAL_FPE;
diff --git a/recipes/gdb/gdb-7.2a/gdb-6.8-pr9638-ppc-canadian-configh.patch b/recipes/gdb/gdb-7.2a/gdb-6.8-pr9638-ppc-canadian-configh.patch
new file mode 100644 (file)
index 0000000..83e85ba
--- /dev/null
@@ -0,0 +1,179 @@
+diff -urN gdb-6.8-pl1/sim/ppc/Makefile.in gdb-6.8-pl2/sim/ppc/Makefile.in
+--- gdb-6.8-pl1/sim/ppc/Makefile.in    2006-05-31 17:14:45.000000000 +0200
++++ gdb-6.8-pl2/sim/ppc/Makefile.in    2008-09-30 15:56:33.000000000 +0200
+@@ -61,7 +61,7 @@
+ AR = @AR@
+ AR_FLAGS = rc
+ CC = @CC@
+-CFLAGS = @CFLAGS@
++CFLAGS = @CFLAGS@ -DHAVE_CONFIG_H
+ CC_FOR_BUILD = @CC_FOR_BUILD@
+ CFLAGS_FOR_BUILD = @CFLAGS_FOR_BUILD@
+ BISON = bison
+@@ -115,8 +115,8 @@
+   $(DEVZERO_CFLAGS)
+ SIM_FPU_CFLAGS = @sim_fpu_cflags@
+-STD_CFLAGS    = $(CFLAGS) $(INLINE_CFLAGS) $(CONFIG_CFLAGS) $(WARNING_CFLAGS) $(SIM_CFLAGS) $(HDEFINES) $(TDEFINES) $(INCLUDES) $(INTL_CFLAGS) $(SIM_FPU_CFLAGS)
+-NOWARN_CFLAGS = $(CFLAGS) $(INLINE_CFLAGS) $(CONFIG_CFLAGS) $(SIM_CFLAGS) $(HDEFINES) $(TDEFINES) $(INCLUDES)  $(SIM_FPU_CFLAGS)
++STD_CFLAGS    = $(CFLAGS) -DHAVE_CONFIG_H $(INLINE_CFLAGS) $(CONFIG_CFLAGS) $(WARNING_CFLAGS) $(SIM_CFLAGS) $(HDEFINES) $(TDEFINES) $(INCLUDES) $(INTL_CFLAGS) $(SIM_FPU_CFLAGS)
++NOWARN_CFLAGS = $(CFLAGS) -DHAVE_CONFIG_H $(INLINE_CFLAGS) $(CONFIG_CFLAGS) $(SIM_CFLAGS) $(HDEFINES) $(TDEFINES) $(INCLUDES)  $(SIM_FPU_CFLAGS)
+ BUILD_CFLAGS  = $(CFLAGS_FOR_BUILD) $(INCLUDES) $(WARNING_CFLAGS)
+ BUILD_LDFLAGS =
+diff -urN gdb-6.8-orig/sim/ppc/basics.h gdb-6.8-pl1/sim/ppc/basics.h
+--- gdb-6.8-orig/sim/ppc/basics.h      1999-04-16 03:35:08.000000000 +0200
++++ gdb-6.8-pl1/sim/ppc/basics.h       2008-09-30 15:12:32.000000000 +0200
+@@ -86,7 +86,9 @@
+ /* Basic configuration */
++#ifdef HAVE_CONFIG_H
+ #include "config.h"
++#endif
+ #include "ppc-config.h"
+ #include "inline.h"
+diff -urN gdb-6.8-orig/sim/ppc/debug.c gdb-6.8-pl1/sim/ppc/debug.c
+--- gdb-6.8-orig/sim/ppc/debug.c       1999-04-16 03:35:08.000000000 +0200
++++ gdb-6.8-pl1/sim/ppc/debug.c        2008-09-30 15:12:27.000000000 +0200
+@@ -22,7 +22,9 @@
+ #ifndef _DEBUG_C_
+ #define _DEBUG_C_
++#ifdef HAVE_CONFIG_H
+ #include "config.h"
++#endif
+ #include "basics.h"
+ #ifdef HAVE_STDLIB_H
+diff -urN gdb-6.8-orig/sim/ppc/dgen.c gdb-6.8-pl1/sim/ppc/dgen.c
+--- gdb-6.8-orig/sim/ppc/dgen.c        1999-04-16 03:35:08.000000000 +0200
++++ gdb-6.8-pl1/sim/ppc/dgen.c 2008-09-30 15:12:22.000000000 +0200
+@@ -27,7 +27,9 @@
+ #include <ctype.h>
+ #include <stdarg.h>
++#ifdef HAVE_CONFIG_H
+ #include "config.h"
++#endif
+ #include "misc.h"
+ #include "lf.h"
+ #include "table.h"
+diff -urN gdb-6.8-orig/sim/ppc/filter.c gdb-6.8-pl1/sim/ppc/filter.c
+--- gdb-6.8-orig/sim/ppc/filter.c      1999-04-16 03:35:09.000000000 +0200
++++ gdb-6.8-pl1/sim/ppc/filter.c       2008-09-30 15:12:15.000000000 +0200
+@@ -21,7 +21,9 @@
+ #include <stdio.h>
++#ifdef HAVE_CONFIG_H
+ #include "config.h"
++#endif
+ #ifdef HAVE_STRING_H
+ #include <string.h>
+diff -urN gdb-6.8-orig/sim/ppc/filter_filename.c gdb-6.8-pl1/sim/ppc/filter_filename.c
+--- gdb-6.8-orig/sim/ppc/filter_filename.c     1999-04-16 03:35:08.000000000 +0200
++++ gdb-6.8-pl1/sim/ppc/filter_filename.c      2008-09-30 15:12:11.000000000 +0200
+@@ -18,7 +18,9 @@
+  
+     */
++#ifdef HAVE_CONFIG_H
+ #include "config.h"
++#endif
+ #include "ppc-config.h"
+ #include "filter_filename.h"
+diff -urN gdb-6.8-orig/sim/ppc/igen.c gdb-6.8-pl1/sim/ppc/igen.c
+--- gdb-6.8-orig/sim/ppc/igen.c        2003-06-20 05:59:33.000000000 +0200
++++ gdb-6.8-pl1/sim/ppc/igen.c 2008-09-30 15:12:06.000000000 +0200
+@@ -25,7 +25,9 @@
+ #include "misc.h"
+ #include "lf.h"
+ #include "table.h"
++#ifdef HAVE_CONFIG_H
+ #include "config.h"
++#endif
+ #include "filter.h"
+diff -urN gdb-6.8-orig/sim/ppc/inline.c gdb-6.8-pl1/sim/ppc/inline.c
+--- gdb-6.8-orig/sim/ppc/inline.c      1999-04-16 03:35:10.000000000 +0200
++++ gdb-6.8-pl1/sim/ppc/inline.c       2008-09-30 15:11:58.000000000 +0200
+@@ -22,7 +22,9 @@
+ #ifndef _INLINE_C_
+ #define _INLINE_C_
++#ifdef HAVE_CONFIG_H
+ #include "config.h"
++#endif
+ #include "ppc-config.h"
+ #include "inline.h"
+diff -urN gdb-6.8-orig/sim/ppc/lf.c gdb-6.8-pl1/sim/ppc/lf.c
+--- gdb-6.8-orig/sim/ppc/lf.c  2002-05-30 17:07:06.000000000 +0200
++++ gdb-6.8-pl1/sim/ppc/lf.c   2008-09-30 15:33:35.000000000 +0200
+@@ -23,7 +23,9 @@
+ #include <stdarg.h>
+ #include <ctype.h>
++#ifdef HAVE_CONFIG_H
+ #include "config.h"
++#endif
+ #include "misc.h"
+ #include "lf.h"
+diff -urN gdb-6.8-orig/sim/ppc/misc.c gdb-6.8-pl1/sim/ppc/misc.c
+--- gdb-6.8-orig/sim/ppc/misc.c        1999-04-16 03:35:11.000000000 +0200
++++ gdb-6.8-pl1/sim/ppc/misc.c 2008-09-30 15:11:54.000000000 +0200
+@@ -23,7 +23,9 @@
+ #include <stdarg.h>
+ #include <ctype.h>
++#ifdef HAVE_CONFIG_H
+ #include "config.h"
++#endif
+ #include "misc.h"
+ #ifdef HAVE_STDLIB_H
+diff -urN gdb-6.8-orig/sim/ppc/misc.h gdb-6.8-pl1/sim/ppc/misc.h
+--- gdb-6.8-orig/sim/ppc/misc.h        2002-01-12 11:21:12.000000000 +0100
++++ gdb-6.8-pl1/sim/ppc/misc.h 2008-09-30 15:11:49.000000000 +0200
+@@ -21,7 +21,9 @@
+ /* Frustrating header junk */
++#ifdef HAVE_CONFIG_H
+ #include "config.h"
++#endif
+ #include <stdio.h>
+ #include <ctype.h>
+diff -urN gdb-6.8-orig/sim/ppc/sim-endian.c gdb-6.8-pl1/sim/ppc/sim-endian.c
+--- gdb-6.8-orig/sim/ppc/sim-endian.c  1999-04-16 03:35:11.000000000 +0200
++++ gdb-6.8-pl1/sim/ppc/sim-endian.c   2008-09-30 15:11:44.000000000 +0200
+@@ -22,7 +22,9 @@
+ #ifndef _SIM_ENDIAN_C_
+ #define _SIM_ENDIAN_C_
++#ifdef HAVE_CONFIG_H
+ #include "config.h"
++#endif
+ #include "basics.h"
+diff -urN gdb-6.8-orig/sim/ppc/table.c gdb-6.8-pl1/sim/ppc/table.c
+--- gdb-6.8-orig/sim/ppc/table.c       2002-01-12 11:21:12.000000000 +0100
++++ gdb-6.8-pl1/sim/ppc/table.c        2008-09-30 15:11:38.000000000 +0200
+@@ -25,7 +25,9 @@
+ #include <fcntl.h>
+ #include <ctype.h>
++#ifdef HAVE_CONFIG_H
+ #include "config.h"
++#endif
+ #include "misc.h"
+ #include "lf.h"
+ #include "table.h"
diff --git a/recipes/gdb/gdb-7.2a/gdb-tcsetpgrp.patch b/recipes/gdb/gdb-7.2a/gdb-tcsetpgrp.patch
new file mode 100644 (file)
index 0000000..d642721
--- /dev/null
@@ -0,0 +1,43 @@
+Stuart Hughes, stuarth@freescale.com 8th April 05
+
+Extracted from:
+
+From: Davin Milun (milun@cs.buffalo.edu)
+Subject: Re: xxgdb for Solaris
+View: Complete Thread (4 articles)
+Original Format
+Newsgroups: comp.unix.solaris
+Date: 1995/05/05
+
+Geraldo Veiga <ggv@research.att.com> wrote:
+>Now, how do I avoid those
+>
+>[tcsetpgrp failed in terminal_inferior: Inappropriate ioctl for device]
+>
+>messages at every step the program takes under mxgdb (and xxgdb)?.  I am
+>running GDB4.13 under Solaris 2.4.  
+
+You need to patch inflow.c.
+
+
+ diff --exclude CVS -uNr gdb-6.0/gdb/inflow.c gdb-6.0.modified/gdb/inflow.c
+Index: gdb-7.1/gdb/inflow.c
+===================================================================
+--- gdb-7.1.orig/gdb/inflow.c  2010-01-21 06:26:12.000000000 -0800
++++ gdb-7.1/gdb/inflow.c       2010-06-09 13:59:33.761358724 -0700
+@@ -308,13 +308,13 @@ terminal_inferior (void)
+       {
+ #ifdef HAVE_TERMIOS
+         result = tcsetpgrp (0, tinfo->process_group);
+-        if (!inf->attach_flag)
++        if (!inf->attach_flag && errno != ENOTTY)
+           OOPSY ("tcsetpgrp");
+ #endif
+ #ifdef HAVE_SGTTY
+         result = ioctl (0, TIOCSPGRP, &tinfo->process_group);
+-        if (!inf->attach_flag)
++        if (!inf->attach_flag && errno != ENOTTY)
+           OOPSY ("TIOCSPGRP");
+ #endif
+       }
diff --git a/recipes/gdb/gdb-7.2a/gdbserver-cflags-last.diff b/recipes/gdb/gdb-7.2a/gdbserver-cflags-last.diff
new file mode 100644 (file)
index 0000000..57e78f6
--- /dev/null
@@ -0,0 +1,15 @@
+Index: gdb/gdbserver/Makefile.in
+===================================================================
+--- gdb/gdbserver/Makefile.in.orig     2009-07-31 08:23:20.000000000 -0700
++++ gdb/gdbserver/Makefile.in  2009-10-13 14:47:21.365401025 -0700
+@@ -89,8 +89,8 @@ WARN_CFLAGS = -Wall
+ CFLAGS = @CFLAGS@
+ # INTERNAL_CFLAGS is the aggregate of all other *CFLAGS macros.
+-INTERNAL_CFLAGS =  $(WARN_CFLAGS) ${CFLAGS} ${GLOBAL_CFLAGS} \
+-      ${PROFILE_CFLAGS} ${INCLUDE_CFLAGS}
++INTERNAL_CFLAGS =  $(WARN_CFLAGS) ${GLOBAL_CFLAGS} \
++      ${PROFILE_CFLAGS} ${INCLUDE_CFLAGS} ${CFLAGS}
+ # LDFLAGS is specifically reserved for setting from the command line
+ # when running make.
diff --git a/recipes/gdb/gdb-7.2a/renesas-sh-native-support.patch b/recipes/gdb/gdb-7.2a/renesas-sh-native-support.patch
new file mode 100644 (file)
index 0000000..2495516
--- /dev/null
@@ -0,0 +1,1410 @@
+This patch is taken from http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=576242
+to support build GDB natively for SH target.
+
+-Khem
+
+
+From 56915d38b2422deff54c90bd53ea03c834b3b513 Mon Sep 17 00:00:00 2001
+From: Takashi YOSHII <yoshii.takashi@renesas.com>
+Date: Mon, 8 Mar 2010 10:45:54 +0900
+Subject: [PATCH] Add Renesas SuperH native support
+
+---
+ gdb/Makefile.in                      |    1 +
+ gdb/config/sh/linux.mh               |    8 +
+ gdb/config/sh/nm-linux.h             |   54 ++++
+ gdb/config/sh/xm-linux.h             |   32 ++
+ gdb/configure.host                   |    1 +
+ gdb/sh-linux-nat.c                   |  269 ++++++++++++++++++
+ gdb/sh-linux-tdep.c                  |  519 ++++++++++++++++++++++++++++++++++
+ gdb/sh-tdep.c                        |   54 ++--
+ gdb/sh-tdep.h                        |   49 ++++
+ gdb/testsuite/gdb.asm/asm-source.exp |    5 +
+ gdb/testsuite/gdb.asm/sh-linux.inc   |   78 +++++
+ gdb/testsuite/gdb.asm/sh.inc         |    3 +-
+ gdb/testsuite/gdb.base/annota1.c     |    6 +-
+ gdb/testsuite/gdb.base/annota3.c     |    6 +-
+ gdb/testsuite/gdb.base/sigall.c      |    6 +-
+ gdb/testsuite/gdb.base/signals.c     |    8 +-
+ 16 files changed, 1057 insertions(+), 42 deletions(-)
+ create mode 100644 gdb/config/sh/linux.mh
+ create mode 100644 gdb/config/sh/nm-linux.h
+ create mode 100644 gdb/config/sh/xm-linux.h
+ create mode 100644 gdb/sh-linux-nat.c
+ create mode 100644 gdb/testsuite/gdb.asm/sh-linux.inc
+
+diff --git a/gdb/Makefile.in b/gdb/Makefile.in
+index 72b546d..4325d5f 100644
+--- a/gdb/Makefile.in
++++ b/gdb/Makefile.in
+@@ -1476,6 +1476,7 @@ ALLDEPFILES = \
+       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 \
+diff --git a/gdb/config/sh/linux.mh b/gdb/config/sh/linux.mh
+new file mode 100644
+index 0000000..86fa8b9
+--- /dev/null
++++ b/gdb/config/sh/linux.mh
+@@ -0,0 +1,8 @@
++# Host: Renesas Super-H running GNU/Linux
++NAT_FILE= 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-fork.o
++
++LOADLIBES= -ldl -rdynamic
+diff --git a/gdb/config/sh/nm-linux.h b/gdb/config/sh/nm-linux.h
+new file mode 100644
+index 0000000..4e6fd5a
+--- /dev/null
++++ b/gdb/config/sh/nm-linux.h
+@@ -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 */
+diff --git a/gdb/config/sh/xm-linux.h b/gdb/config/sh/xm-linux.h
+new file mode 100644
+index 0000000..6482093
+--- /dev/null
++++ b/gdb/config/sh/xm-linux.h
+@@ -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 */
+diff --git a/gdb/configure.host b/gdb/configure.host
+index 794eeee..ebc209b 100644
+--- a/gdb/configure.host
++++ b/gdb/configure.host
+@@ -139,6 +139,7 @@ powerpc64-*-linux*)     gdb_host=ppc64-linux
+ s390*-*-*)            gdb_host=s390 ;;
++sh*-*-linux*)         gdb_host=linux ;;
+ sh*-*-netbsdelf* | sh*-*-knetbsd*-gnu)
+                       gdb_host=nbsd ;;
+ sh*-*-openbsd*)               gdb_host=nbsd ;;
+diff --git a/gdb/sh-linux-nat.c b/gdb/sh-linux-nat.c
+new file mode 100644
+index 0000000..18e423d
+--- /dev/null
++++ b/gdb/sh-linux-nat.c
+@@ -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]);
++}
++
++\f
++/* 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);
++}
+diff --git a/gdb/sh-linux-tdep.c b/gdb/sh-linux-tdep.c
+index da4137b..be95bc9 100644
+--- a/gdb/sh-linux-tdep.c
++++ b/gdb/sh-linux-tdep.c
+@@ -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"
+@@ -69,9 +92,505 @@ static const struct sh_corefile_regmap fpregs_table[] =
+   {-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);
++
+   /* GNU/Linux uses SVR4-style shared libraries.  */
+   set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
+   set_solib_svr4_fetch_link_map_offsets
+diff --git a/gdb/sh-tdep.c b/gdb/sh-tdep.c
+index 7e01469..735cc84 100644
+--- a/gdb/sh-tdep.c
++++ b/gdb/sh-tdep.c
+@@ -24,6 +24,9 @@
+  */
+ #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"
+@@ -40,6 +43,7 @@
+ #include "arch-utils.h"
+ #include "floatformat.h"
+ #include "regcache.h"
++#include "regset.h"
+ #include "doublest.h"
+ #include "osabi.h"
+ #include "reggroups.h"
+@@ -72,23 +76,6 @@ static const char *sh_active_calling_convention = sh_cc_gcc;
+ 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)
+ {
+@@ -1045,7 +1032,7 @@ sh_treat_as_flt_p (struct type *type)
+     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;
+@@ -1095,7 +1082,7 @@ sh_push_dummy_call_fpu (struct gdbarch *gdbarch,
+      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);
+@@ -2485,7 +2472,7 @@ sh_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum,
+     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;
+@@ -2512,7 +2499,7 @@ sh_alloc_frame_cache (void)
+   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);
+@@ -2570,9 +2557,9 @@ sh_frame_cache (struct frame_info *this_frame, void **this_cache)
+   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);
+@@ -2586,7 +2573,7 @@ sh_frame_prev_register (struct frame_info *this_frame,
+      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,
+@@ -2829,8 +2816,8 @@ sh_regset_from_core_section (struct gdbarch *gdbarch, const char *sect_name,
+ 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)
+@@ -2893,6 +2880,18 @@ sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
+   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);
+@@ -3038,10 +3037,11 @@ sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
+       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;
+diff --git a/gdb/sh-tdep.h b/gdb/sh-tdep.h
+index b53d412..f2bea7d 100644
+--- a/gdb/sh-tdep.h
++++ b/gdb/sh-tdep.h
+@@ -22,6 +22,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
+   {
+@@ -30,6 +36,7 @@ enum
+     ARG0_REGNUM = 4,
+     ARGLAST_REGNUM = 7,
+     FP_REGNUM = 14,
++    SP_REGNUM = 15,
+     PC_REGNUM = 16,
+     PR_REGNUM = 17,
+     GBR_REGNUM = 18,
+@@ -83,8 +90,26 @@ enum
+     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
+@@ -93,8 +118,32 @@ struct sh_corefile_regmap
+   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.  */
+diff --git a/gdb/testsuite/gdb.asm/asm-source.exp b/gdb/testsuite/gdb.asm/asm-source.exp
+index 615182f..dd5ae09 100644
+--- a/gdb/testsuite/gdb.asm/asm-source.exp
++++ b/gdb/testsuite/gdb.asm/asm-source.exp
+@@ -105,6 +105,11 @@ switch -glob -- [istarget] {
+     "powerpc*-*" {
+         set asm-arch powerpc
+     }
++    "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"
+diff --git a/gdb/testsuite/gdb.asm/sh-linux.inc b/gdb/testsuite/gdb.asm/sh-linux.inc
+new file mode 100644
+index 0000000..4a0f669
+--- /dev/null
++++ b/gdb/testsuite/gdb.asm/sh-linux.inc
+@@ -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
+diff --git a/gdb/testsuite/gdb.asm/sh.inc b/gdb/testsuite/gdb.asm/sh.inc
+index 9ea1b67..c1f189d 100644
+--- a/gdb/testsuite/gdb.asm/sh.inc
++++ b/gdb/testsuite/gdb.asm/sh.inc
+@@ -40,9 +40,8 @@
+       mov.l   .Lconst\@,r1
+       bra     .Lafterconst\@
+       nop
+-      nop
+-.Lconst\@:
+       .align  2
++.Lconst\@:
+       .long   \subr
+       .align  1
+ .Lafterconst\@:
+diff --git a/gdb/testsuite/gdb.base/annota1.c b/gdb/testsuite/gdb.base/annota1.c
+index 6a13ee9..fb8aa53 100644
+--- a/gdb/testsuite/gdb.base/annota1.c
++++ b/gdb/testsuite/gdb.base/annota1.c
+@@ -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
+diff --git a/gdb/testsuite/gdb.base/annota3.c b/gdb/testsuite/gdb.base/annota3.c
+index 6a13ee9..fb8aa53 100644
+--- a/gdb/testsuite/gdb.base/annota3.c
++++ b/gdb/testsuite/gdb.base/annota3.c
+@@ -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
+diff --git a/gdb/testsuite/gdb.base/sigall.c b/gdb/testsuite/gdb.base/sigall.c
+index 28ae192..a8ff690 100644
+--- a/gdb/testsuite/gdb.base/sigall.c
++++ b/gdb/testsuite/gdb.base/sigall.c
+@@ -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.  */
+diff --git a/gdb/testsuite/gdb.base/signals.c b/gdb/testsuite/gdb.base/signals.c
+index f1ebcfc..cef4793 100644
+--- a/gdb/testsuite/gdb.base/signals.c
++++ b/gdb/testsuite/gdb.base/signals.c
+@@ -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;
+-- 
+1.7.0.3
+
index 0c23692..6b582e5 100644 (file)
@@ -20,3 +20,25 @@ export CPPFLAGS_FOR_BUILD = "${BUILD_CPPFLAGS}"
 S = "${WORKDIR}/gdb-${PV}"
 B = "${WORKDIR}/build-${TARGET_SYS}"
 
+do_install_append() {
+       # these mo and doc files from gdb-cross-sdk clash with files from
+       # binutils-cross-sdk when building sdk archives. Drop them for now as a
+       # way to restore toolchains.
+       rm -f ${D}${datadir}/locale/*/LC_MESSAGES/{bfd,opcodes}.mo
+       rm -rf ${D}${docdir}/bfd.html
+
+       # we don't care about these infos, installed from binutils
+       rm -f ${D}${infodir}/{configure,standards,bfd}.info
+       rm -f ${D}${docdir}/{configure,standards,bfd,libiberty}.html
+       rm -f ${D}${infodir}/dir
+
+       # We use libiberty from binutils
+       rm -f ${D}${prefix}/${TARGET_SYS}/lib/libiberty.a
+       rm -f ${D}${prefix}/lib{,64}/libiberty.a
+
+       # Use libbfd from binutils.
+       rm -f ${D}${prefix}/lib/libbfd.{,l}a
+
+       # Use libopcodes from binutils.
+       rm -f ${D}${prefix}/lib/libopcodes.{,l}a
+}
diff --git a/recipes/gdb/gdb-cross-sdk.inc b/recipes/gdb/gdb-cross-sdk.inc
new file mode 100644 (file)
index 0000000..5b757f4
--- /dev/null
@@ -0,0 +1,24 @@
+require gdb-cross.inc
+LICENSE = "GPLv3"
+
+inherit sdk
+EXTRA_OEMAKE = "'SUBDIRS=intl mmalloc libiberty opcodes bfd sim gdb etc utils' LDFLAGS='${BUILD_LDFLAGS}'"
+
+# Since we statically link against the required host libraries we don't 
+# add a depenency on the -sdk versions of them.
+do_configure_append () {
+       cd ${B}
+       oe_runconf
+       oe_runmake configure-host
+       sed -e 's,-lncurses,${STAGING_LIBDIR_NATIVE}/libncurses.a ${STAGING_LIBDIR_NATIVE}/libtinfo.a ,g' -i ${B}/gdb/Makefile
+       sed -e 's,-lz, ${STAGING_LIBDIR_NATIVE}/libz.a ,g' -i ${B}/gdb/Makefile
+       sed -e 's,-lexpat, ${STAGING_LIBDIR_NATIVE}/libexpat.a ,g' -i ${B}/gdb/Makefile
+       sed -e 's,libexpat.so,libexpat.a ,g' -i ${B}/gdb/Makefile
+       for SIM in ${B}/sim/*/Makefile
+       do
+               if [ -f $SIM ]
+               then
+                       sed -e 's,-lz, ${STAGING_LIBDIR_NATIVE}/libz.a ,g' -i $SIM
+               fi
+       done
+}
diff --git a/recipes/gdb/gdb-cross-sdk_7.2a.bb b/recipes/gdb/gdb-cross-sdk_7.2a.bb
new file mode 100644 (file)
index 0000000..9ff8cd1
--- /dev/null
@@ -0,0 +1,13 @@
+require gdb-cross-sdk.inc
+
+INC_PR = r1
+PR = "${INC_PR}.0"
+
+SRC_URI += "\
+            file://gdb-6.8-fix-compile-karmic.patch;patch=1 \
+           file://gdb-fix-sim-ppc.patch;patch=1 \
+          "
+S = ${WORKDIR}/gdb-7.2
+
+SRC_URI[md5sum] = "950b766466bee748e554765c86b8b495"
+SRC_URI[sha256sum] = "34919cb51334c8149ae36ed086f35e79fe3fa2b2a85b568d7c0edad20cd972d4"
diff --git a/recipes/gdb/gdb-cross_7.2a.bb b/recipes/gdb/gdb-cross_7.2a.bb
new file mode 100644 (file)
index 0000000..4c36889
--- /dev/null
@@ -0,0 +1,15 @@
+require gdb-cross.inc
+LICENSE = "GPLv3"
+
+INC_PR = r1
+PR = "${INC_PR}.0"
+
+SRC_URI += " \
+            file://gdb-6.8-fix-compile-karmic.patch;patch=1 \
+           file://gdb-fix-sim-ppc.patch;patch=1 \
+           "
+S = ${WORKDIR}/gdb-7.2
+
+SRC_URI[md5sum] = "a9a8d0ea1ae57837fada5415bd0f92ff"
+SRC_URI[sha256sum] = "9f51739cd45c158aa5df2e7abb703a304b5370e2e9e43c70f5cc0b1c4be5d0c2"
+
index a519cef..10224ea 100644 (file)
@@ -2,7 +2,7 @@ require gdb-common.inc
 
 DEFAULT_PREFERENCE_avr32 = "-99"
 
-DEPENDS = "ncurses readline zlib flex-native"
+DEPENDS = "ncurses readline zlib flex-native bison-native"
 
 PACKAGES =+ "gdbserver"
 FILES_gdbserver = "${bindir}/gdbserver"
@@ -24,7 +24,7 @@ EXTRA_OEMAKE = "'SUBDIRS=intl mmalloc libiberty opcodes bfd sim gdb etc utils'"
 
 EXTRA_OECONF = "--disable-gdbtk --disable-tui --disable-x \
                 --with-curses --disable-multilib --with-readline --disable-sim \
-                --program-prefix=''"
+                --program-prefix='' --disable-lto"
 
 LDFLAGS_append = " -s"
 export CFLAGS_append=" -L${STAGING_LIBDIR}"
diff --git a/recipes/gdb/gdb_7.2a.bb b/recipes/gdb/gdb_7.2a.bb
new file mode 100644 (file)
index 0000000..df734ee
--- /dev/null
@@ -0,0 +1,26 @@
+require gdb.inc
+LICENSE = "GPLv3"
+
+DEPENDS += "libelf"
+
+INC_PR = r1
+PR = "${INC_PR}.0"
+# there is a bug in GCC for SH4 it ICE's at Optlevel >O1
+# so workaround that for now.
+
+CFLAGS_append_sh4 = " -O1"
+SRC_URI += "file://gdb-6.8-fix-compile-karmic.patch;patch=1 \
+           file://gdb-tcsetpgrp.patch;patch=1 \
+           file://gdb-fix-sim-ppc.patch;patch=1 \
+           file://renesas-sh-native-support.patch;patch=1 \
+          "
+S = ${WORKDIR}/${PN}-7.2
+
+# Work-around problems while creating libbfd.a
+#EXTRA_OECONF += "--enable-static"
+
+EXTRA_OECONF += "--with-libelf=${STAGING_DIR_NATIVE}/usr"
+
+SRC_URI[md5sum] = "a9a8d0ea1ae57837fada5415bd0f92ff"
+SRC_URI[sha256sum] = "9f51739cd45c158aa5df2e7abb703a304b5370e2e9e43c70f5cc0b1c4be5d0c2"
+
diff --git a/recipes/gdb/gdbserver_7.2a.bb b/recipes/gdb/gdbserver_7.2a.bb
new file mode 100644 (file)
index 0000000..430cc51
--- /dev/null
@@ -0,0 +1,12 @@
+require gdbserver.inc
+
+LICENSE = "GPLv3"
+
+INC_PR = r1
+PR = "${INC_PR}.0"
+
+S = ${WORKDIR}/gdb-7.2
+
+SRC_URI[md5sum] = "a9a8d0ea1ae57837fada5415bd0f92ff"
+SRC_URI[sha256sum] = "9f51739cd45c158aa5df2e7abb703a304b5370e2e9e43c70f5cc0b1c4be5d0c2"
+