Refactor os specific code for x86 (both 32 and 64 bit).

Move Linux specific code into ${arch}/Gos-linux.c
diff --git a/include/libunwind-common.h.in b/include/libunwind-common.h.in
index 9005a6c..228460a 100644
--- a/include/libunwind-common.h.in
+++ b/include/libunwind-common.h.in
@@ -220,6 +220,7 @@
 #define unw_set_fpreg		UNW_OBJ(set_fpreg)
 #define unw_get_save_loc	UNW_OBJ(get_save_loc)
 #define unw_is_signal_frame	UNW_OBJ(is_signal_frame)
+#define unw_handle_signal_frame	UNW_OBJ(handle_signal_frame)
 #define unw_get_proc_name	UNW_OBJ(get_proc_name)
 #define unw_set_caching_policy	UNW_OBJ(set_caching_policy)
 #define unw_regname		UNW_ARCH_OBJ(regname)
@@ -246,6 +247,7 @@
 extern int unw_set_fpreg (unw_cursor_t *, int, unw_fpreg_t);
 extern int unw_get_save_loc (unw_cursor_t *, int, unw_save_loc_t *);
 extern int unw_is_signal_frame (unw_cursor_t *);
+extern int unw_handle_signal_frame (unw_cursor_t *);
 extern int unw_get_proc_name (unw_cursor_t *, char *, size_t, unw_word_t *);
 extern const char *unw_strerror (int);
 
diff --git a/src/Makefile.am b/src/Makefile.am
index c110e76..2635d8d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -221,22 +221,24 @@
 
 # The list of files that go into libunwind:
 libunwind_la_SOURCES_x86 = $(libunwind_la_SOURCES_x86_common)		\
+        $(libunwind_la_SOURCES_x86_os_local)				\
 	$(libunwind_la_SOURCES_local)					\
 	$(dwarf_SOURCES_local)						\
 	dwarf/Lfind_proc_info-lsb.c					\
 	x86/Lcreate_addr_space.c x86/Lget_save_loc.c x86/Lglobal.c	\
 	x86/Linit.c x86/Linit_local.c x86/Linit_remote.c		\
-	x86/Lis_signal_frame.c x86/Lget_proc_info.c x86/Lregs.c		\
+	x86/Lget_proc_info.c x86/Lregs.c				\
 	x86/Lresume.c x86/Lstep.c x86/getcontext.S
 
 # The list of files that go into libunwind-x86:
 libunwind_x86_la_SOURCES_x86 = $(libunwind_la_SOURCES_x86_common)	\
+        $(libunwind_la_SOURCES_x86_os)					\
 	$(libunwind_la_SOURCES_generic)					\
 	$(dwarf_SOURCES_generic)					\
 	dwarf/Gfind_proc_info-lsb.c					\
 	x86/Gcreate_addr_space.c x86/Gget_save_loc.c x86/Gglobal.c	\
 	x86/Ginit.c x86/Ginit_local.c x86/Ginit_remote.c		\
-	x86/Gis_signal_frame.c x86/Gget_proc_info.c x86/Gregs.c		\
+	x86/Gget_proc_info.c x86/Gregs.c				\
 	x86/Gresume.c x86/Gstep.c
 
 # The list of files that go both into libunwind and libunwind-x86_64:
@@ -248,23 +250,25 @@
 
 # The list of files that go into libunwind:
 libunwind_la_SOURCES_x86_64 = $(libunwind_la_SOURCES_x86_64_common)	    \
+        $(libunwind_la_SOURCES_x86_64_os_local)			    	    \
 	$(libunwind_la_SOURCES_local)					    \
 	$(dwarf_SOURCES_local)						    \
 	dwarf/Lfind_proc_info-lsb.c					    \
-	x86_64/setcontext.S						\
+	x86_64/setcontext.S						    \
 	x86_64/Lcreate_addr_space.c x86_64/Lget_save_loc.c x86_64/Lglobal.c \
 	x86_64/Linit.c x86_64/Linit_local.c x86_64/Linit_remote.c	    \
-	x86_64/Lis_signal_frame.c x86_64/Lget_proc_info.c x86_64/Lregs.c    \
+	x86_64/Lget_proc_info.c x86_64/Lregs.c    			    \
 	x86_64/Lresume.c x86_64/Lstep.c x86_64/getcontext.S
 
 # The list of files that go into libunwind-x86_64:
 libunwind_x86_64_la_SOURCES_x86_64 = $(libunwind_la_SOURCES_x86_64_common)  \
+        $(libunwind_la_SOURCES_x86_64_os)			    	    \
 	$(libunwind_la_SOURCES_generic)					    \
 	$(dwarf_SOURCES_generic)					    \
 	dwarf/Gfind_proc_info-lsb.c					    \
 	x86_64/Gcreate_addr_space.c x86_64/Gget_save_loc.c x86_64/Gglobal.c \
 	x86_64/Ginit.c x86_64/Ginit_local.c x86_64/Ginit_remote.c	    \
-	x86_64/Gis_signal_frame.c x86_64/Gget_proc_info.c x86_64/Gregs.c    \
+	x86_64/Gget_proc_info.c x86_64/Gregs.c    			    \
 	x86_64/Gresume.c x86_64/Gstep.c
 
 # The list of local files that go to Power 64 and 32:
@@ -342,8 +346,12 @@
 endif
 
 if OS_LINUX
- libunwind_la_SOURCES_os	= $(libunwind_la_SOURCES_os_linux)
- libunwind_la_SOURCES_os_local	= $(libunwind_la_SOURCES_os_linux_local)
+ libunwind_la_SOURCES_os	      = $(libunwind_la_SOURCES_os_linux)
+ libunwind_la_SOURCES_os_local	      = $(libunwind_la_SOURCES_os_linux_local)
+ libunwind_la_SOURCES_x86_os          = x86/Gos-linux.c
+ libunwind_la_SOURCES_x86_os_local    = x86/Los-linux.c
+ libunwind_la_SOURCES_x86_64_os       = x86_64/Gos-linux.c
+ libunwind_la_SOURCES_x86_64_os_local = x86_64/Los-linux.c
 endif
 
 if OS_HPUX
diff --git a/src/x86/Gis_signal_frame.c b/src/x86/Gis_signal_frame.c
deleted file mode 100644
index 686da02..0000000
--- a/src/x86/Gis_signal_frame.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/* libunwind - a platform-independent unwind library
-   Copyright (C) 2002-2003 Hewlett-Packard Co
-	Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
-
-This file is part of libunwind.
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
-
-#include "unwind_i.h"
-
-PROTECTED int
-unw_is_signal_frame (unw_cursor_t *cursor)
-{
-#ifdef __linux__
-  struct cursor *c = (struct cursor *) cursor;
-  unw_word_t w0, w1, ip;
-  unw_addr_space_t as;
-  unw_accessors_t *a;
-  void *arg;
-  int ret;
-
-  as = c->dwarf.as;
-  a = unw_get_accessors (as);
-  arg = c->dwarf.as_arg;
-
-  /* Check if EIP points at sigreturn() sequence.  On Linux, this is:
-
-    __restore:
-	0x58				pop %eax
-	0xb8 0x77 0x00 0x00 0x00	movl 0x77,%eax
-	0xcd 0x80			int 0x80
-
-     without SA_SIGINFO, and
-
-    __restore_rt:
-       0xb8 0xad 0x00 0x00 0x00        movl 0xad,%eax
-       0xcd 0x80                       int 0x80
-       0x00                            
-
-     if SA_SIGINFO is specified.
-  */
-  ip = c->dwarf.ip;
-  if ((ret = (*a->access_mem) (as, ip, &w0, 0, arg)) < 0
-      || (ret = (*a->access_mem) (as, ip + 4, &w1, 0, arg)) < 0)
-    return ret;
-  ret = ((w0 == 0x0077b858 && w1 == 0x80cd0000)
-	 || (w0 == 0x0000adb8 && (w1 & 0xffffff) == 0x80cd00));
-  Debug (16, "returning %d\n", ret);
-  return ret;
-#else
-  printf ("%s: implement me\n", __FUNCTION__);
-#endif
-  return -UNW_ENOINFO;
-}
diff --git a/src/x86/Gos-linux.c b/src/x86/Gos-linux.c
new file mode 100644
index 0000000..63888a5
--- /dev/null
+++ b/src/x86/Gos-linux.c
@@ -0,0 +1,137 @@
+/* libunwind - a platform-independent unwind library
+   Copyright (C) 2002-2004 Hewlett-Packard Co
+	Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
+
+#include "unwind_i.h"
+#include "offsets.h"
+
+PROTECTED int
+unw_is_signal_frame (unw_cursor_t *cursor)
+{
+  struct cursor *c = (struct cursor *) cursor;
+  unw_word_t w0, w1, ip;
+  unw_addr_space_t as;
+  unw_accessors_t *a;
+  void *arg;
+  int ret;
+
+  as = c->dwarf.as;
+  a = unw_get_accessors (as);
+  arg = c->dwarf.as_arg;
+
+  /* Check if EIP points at sigreturn() sequence.  On Linux, this is:
+
+    __restore:
+	0x58				pop %eax
+	0xb8 0x77 0x00 0x00 0x00	movl 0x77,%eax
+	0xcd 0x80			int 0x80
+
+     without SA_SIGINFO, and
+
+    __restore_rt:
+       0xb8 0xad 0x00 0x00 0x00        movl 0xad,%eax
+       0xcd 0x80                       int 0x80
+       0x00                            
+
+     if SA_SIGINFO is specified.
+  */
+  ip = c->dwarf.ip;
+  if ((ret = (*a->access_mem) (as, ip, &w0, 0, arg)) < 0
+      || (ret = (*a->access_mem) (as, ip + 4, &w1, 0, arg)) < 0)
+    return ret;
+  ret = ((w0 == 0x0077b858 && w1 == 0x80cd0000)
+	 || (w0 == 0x0000adb8 && (w1 & 0xffffff) == 0x80cd00));
+  Debug (16, "returning %d\n", ret);
+  return ret;
+}
+
+PROTECTED int
+unw_handle_signal_frame (unw_cursor_t *cursor)
+{
+  struct cursor *c = (struct cursor *) cursor;
+  int ret;
+
+  /* c->esp points at the arguments to the handler.  Without
+     SA_SIGINFO, the arguments consist of a signal number
+     followed by a struct sigcontext.  With SA_SIGINFO, the
+     arguments consist a signal number, a siginfo *, and a
+     ucontext *. */
+  unw_word_t sc_addr;
+  unw_word_t siginfo_ptr_addr = c->dwarf.cfa + 4;
+  unw_word_t sigcontext_ptr_addr = c->dwarf.cfa + 8;
+  unw_word_t siginfo_ptr, sigcontext_ptr;
+  struct dwarf_loc esp_loc, siginfo_ptr_loc, sigcontext_ptr_loc;
+
+  siginfo_ptr_loc = DWARF_LOC (siginfo_ptr_addr, 0);
+  sigcontext_ptr_loc = DWARF_LOC (sigcontext_ptr_addr, 0);
+  ret = (dwarf_get (&c->dwarf, siginfo_ptr_loc, &siginfo_ptr)
+	 | dwarf_get (&c->dwarf, sigcontext_ptr_loc, &sigcontext_ptr));
+  if (ret < 0)
+    {
+      Debug (2, "returning 0\n");
+      return 0;
+    }
+  if (siginfo_ptr < c->dwarf.cfa
+      || siginfo_ptr > c->dwarf.cfa + 256
+      || sigcontext_ptr < c->dwarf.cfa
+      || sigcontext_ptr > c->dwarf.cfa + 256)
+    {
+      /* Not plausible for SA_SIGINFO signal */
+      c->sigcontext_format = X86_SCF_LINUX_SIGFRAME;
+      c->sigcontext_addr = sc_addr = c->dwarf.cfa + 4;
+    }
+  else
+    {
+      /* If SA_SIGINFO were not specified, we actually read
+	 various segment pointers instead.  We believe that at
+	 least fs and _fsh are always zero for linux, so it is
+	 not just unlikely, but impossible that we would end
+	 up here. */
+      c->sigcontext_format = X86_SCF_LINUX_RT_SIGFRAME;
+      c->sigcontext_addr = sigcontext_ptr;
+      sc_addr = sigcontext_ptr + LINUX_UC_MCONTEXT_OFF;
+    }
+  esp_loc = DWARF_LOC (sc_addr + LINUX_SC_ESP_OFF, 0);
+  ret = dwarf_get (&c->dwarf, esp_loc, &c->dwarf.cfa);
+  if (ret < 0)
+    {
+      Debug (2, "returning 0\n");
+      return 0;
+    }
+
+  c->dwarf.loc[EAX] = DWARF_LOC (sc_addr + LINUX_SC_EAX_OFF, 0);
+  c->dwarf.loc[ECX] = DWARF_LOC (sc_addr + LINUX_SC_ECX_OFF, 0);
+  c->dwarf.loc[EDX] = DWARF_LOC (sc_addr + LINUX_SC_EDX_OFF, 0);
+  c->dwarf.loc[EBX] = DWARF_LOC (sc_addr + LINUX_SC_EBX_OFF, 0);
+  c->dwarf.loc[EBP] = DWARF_LOC (sc_addr + LINUX_SC_EBP_OFF, 0);
+  c->dwarf.loc[ESI] = DWARF_LOC (sc_addr + LINUX_SC_ESI_OFF, 0);
+  c->dwarf.loc[EDI] = DWARF_LOC (sc_addr + LINUX_SC_EDI_OFF, 0);
+  c->dwarf.loc[EFLAGS] = DWARF_NULL_LOC;
+  c->dwarf.loc[TRAPNO] = DWARF_NULL_LOC;
+  c->dwarf.loc[ST0] = DWARF_NULL_LOC;
+  c->dwarf.loc[EIP] = DWARF_LOC (sc_addr + LINUX_SC_EIP_OFF, 0);
+  c->dwarf.loc[ESP] = DWARF_LOC (sc_addr + LINUX_SC_ESP_OFF, 0);
+
+  return 0;
+}
diff --git a/src/x86/Gstep.c b/src/x86/Gstep.c
index 266f89f..e4055ae 100644
--- a/src/x86/Gstep.c
+++ b/src/x86/Gstep.c
@@ -56,70 +56,14 @@
       Debug (13, "dwarf_step() failed (ret=%d), trying frame-chain\n", ret);
 
       if (unw_is_signal_frame (cursor))
-	{
-	  /* XXX This code is Linux-specific! */
-
-	  /* c->esp points at the arguments to the handler.  Without
-	     SA_SIGINFO, the arguments consist of a signal number
-	     followed by a struct sigcontext.  With SA_SIGINFO, the
-	     arguments consist a signal number, a siginfo *, and a
-	     ucontext *. */
-	  unw_word_t sc_addr;
-	  unw_word_t siginfo_ptr_addr = c->dwarf.cfa + 4;
-	  unw_word_t sigcontext_ptr_addr = c->dwarf.cfa + 8;
-	  unw_word_t siginfo_ptr, sigcontext_ptr;
-	  struct dwarf_loc esp_loc, siginfo_ptr_loc, sigcontext_ptr_loc;
-
-	  siginfo_ptr_loc = DWARF_LOC (siginfo_ptr_addr, 0);
-	  sigcontext_ptr_loc = DWARF_LOC (sigcontext_ptr_addr, 0);
-	  ret = (dwarf_get (&c->dwarf, siginfo_ptr_loc, &siginfo_ptr)
-		 | dwarf_get (&c->dwarf, sigcontext_ptr_loc, &sigcontext_ptr));
+        {
+          ret = unw_handle_signal_frame(cursor);
 	  if (ret < 0)
 	    {
 	      Debug (2, "returning 0\n");
 	      return 0;
 	    }
-	  if (siginfo_ptr < c->dwarf.cfa
-	      || siginfo_ptr > c->dwarf.cfa + 256
-	      || sigcontext_ptr < c->dwarf.cfa
-	      || sigcontext_ptr > c->dwarf.cfa + 256)
-	    {
-	      /* Not plausible for SA_SIGINFO signal */
-	      c->sigcontext_format = X86_SCF_LINUX_SIGFRAME;
-	      c->sigcontext_addr = sc_addr = c->dwarf.cfa + 4;
-	    }
-	  else
-	    {
-	      /* If SA_SIGINFO were not specified, we actually read
-		 various segment pointers instead.  We believe that at
-		 least fs and _fsh are always zero for linux, so it is
-		 not just unlikely, but impossible that we would end
-		 up here. */
-	      c->sigcontext_format = X86_SCF_LINUX_RT_SIGFRAME;
-	      c->sigcontext_addr = sigcontext_ptr;
-	      sc_addr = sigcontext_ptr + LINUX_UC_MCONTEXT_OFF;
-	    }
-	  esp_loc = DWARF_LOC (sc_addr + LINUX_SC_ESP_OFF, 0);
-	  ebp_loc = DWARF_LOC (sc_addr + LINUX_SC_EBP_OFF, 0);
-	  eip_loc = DWARF_LOC (sc_addr + LINUX_SC_EIP_OFF, 0);
-	  ret = dwarf_get (&c->dwarf, esp_loc, &c->dwarf.cfa);
-	  if (ret < 0)
-	    {
-	      Debug (2, "returning 0\n");
-	      return 0;
-	    }
-
-	  c->dwarf.loc[EAX] = DWARF_LOC (sc_addr + LINUX_SC_EAX_OFF, 0);
-	  c->dwarf.loc[ECX] = DWARF_LOC (sc_addr + LINUX_SC_ECX_OFF, 0);
-	  c->dwarf.loc[EDX] = DWARF_LOC (sc_addr + LINUX_SC_EDX_OFF, 0);
-	  c->dwarf.loc[EBX] = DWARF_LOC (sc_addr + LINUX_SC_EBX_OFF, 0);
-	  c->dwarf.loc[EBP] = DWARF_LOC (sc_addr + LINUX_SC_EBP_OFF, 0);
-	  c->dwarf.loc[ESI] = DWARF_LOC (sc_addr + LINUX_SC_ESI_OFF, 0);
-	  c->dwarf.loc[EDI] = DWARF_LOC (sc_addr + LINUX_SC_EDI_OFF, 0);
-	  c->dwarf.loc[EFLAGS] = DWARF_NULL_LOC;
-	  c->dwarf.loc[TRAPNO] = DWARF_NULL_LOC;
-	  c->dwarf.loc[ST0] = DWARF_NULL_LOC;
-	}
+        }
       else
 	{
 	  ret = dwarf_get (&c->dwarf, c->dwarf.loc[EBP], &c->dwarf.cfa);
@@ -141,9 +85,10 @@
 	     EIP.  */
 	  for (i = 0; i < DWARF_NUM_PRESERVED_REGS; ++i)
 	    c->dwarf.loc[i] = DWARF_NULL_LOC;
+
+          c->dwarf.loc[EBP] = ebp_loc;
+          c->dwarf.loc[EIP] = eip_loc;
 	}
-      c->dwarf.loc[EBP] = ebp_loc;
-      c->dwarf.loc[EIP] = eip_loc;
       c->dwarf.ret_addr_column = EIP;
 
       if (!DWARF_IS_NULL_LOC (c->dwarf.loc[EBP]))
diff --git a/src/x86/Lis_signal_frame.c b/src/x86/Los-linux.c
similarity index 78%
rename from src/x86/Lis_signal_frame.c
rename to src/x86/Los-linux.c
index b9a7c4f..3cc18aa 100644
--- a/src/x86/Lis_signal_frame.c
+++ b/src/x86/Los-linux.c
@@ -1,5 +1,5 @@
 #define UNW_LOCAL_ONLY
 #include <libunwind.h>
 #if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
-#include "Gis_signal_frame.c"
+#include "Gos-linux.c"
 #endif
diff --git a/src/x86_64/Gis_signal_frame.c b/src/x86_64/Gis_signal_frame.c
deleted file mode 100644
index 72edf46..0000000
--- a/src/x86_64/Gis_signal_frame.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/* libunwind - a platform-independent unwind library
-   Copyright (C) 2002-2003 Hewlett-Packard Co
-	Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
-
-   Modified for x86_64 by Max Asbock <masbock@us.ibm.com>
-
-This file is part of libunwind.
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
-
-#include "unwind_i.h"
-
-#ifdef __linux__
-PROTECTED int
-unw_is_signal_frame (unw_cursor_t *cursor)
-{
-  struct cursor *c = (struct cursor *) cursor;
-  unw_word_t w0, w1, ip;
-  unw_addr_space_t as;
-  unw_accessors_t *a;
-  void *arg;
-  int ret;
-
-  as = c->dwarf.as;
-  a = unw_get_accessors (as);
-  arg = c->dwarf.as_arg;
-
-  /* Check if RIP points at sigreturn sequence.
-     on x86_64 Linux that is (see libc.so):
-     48 c7 c0 0f 00 00 00 mov $0xf,%rax
-     0f 05                syscall
-     66                   data16
-  */
-
-  ip = c->dwarf.ip;
-  if ((ret = (*a->access_mem) (as, ip, &w0, 0, arg)) < 0
-      || (ret = (*a->access_mem) (as, ip + 8, &w1, 0, arg)) < 0)
-    return 0;
-  w1 &= 0xff;
-  return (w0 == 0x0f0000000fc0c748 && w1 == 0x05);
-}
-
-#else /* __linux__ */
-
-PROTECTED int
-unw_is_signal_frame (unw_cursor_t *cursor)
-{
-  printf ("%s: implement me\n", __FUNCTION__);
-  return -UNW_ENOINFO;
-}
-#endif /* __linux__ */
diff --git a/src/x86_64/Gos-linux.c b/src/x86_64/Gos-linux.c
new file mode 100644
index 0000000..4b99e28
--- /dev/null
+++ b/src/x86_64/Gos-linux.c
@@ -0,0 +1,99 @@
+/* libunwind - a platform-independent unwind library
+   Copyright (C) 2002-2003 Hewlett-Packard Co
+	Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+
+   Modified for x86_64 by Max Asbock <masbock@us.ibm.com>
+
+This file is part of libunwind.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
+
+#include "unwind_i.h"
+#include "ucontext_i.h"
+
+PROTECTED int
+unw_is_signal_frame (unw_cursor_t *cursor)
+{
+  struct cursor *c = (struct cursor *) cursor;
+  unw_word_t w0, w1, ip;
+  unw_addr_space_t as;
+  unw_accessors_t *a;
+  void *arg;
+  int ret;
+
+  as = c->dwarf.as;
+  a = unw_get_accessors (as);
+  arg = c->dwarf.as_arg;
+
+  /* Check if RIP points at sigreturn sequence.
+     on x86_64 Linux that is (see libc.so):
+     48 c7 c0 0f 00 00 00 mov $0xf,%rax
+     0f 05                syscall
+     66                   data16
+  */
+
+  ip = c->dwarf.ip;
+  if ((ret = (*a->access_mem) (as, ip, &w0, 0, arg)) < 0
+      || (ret = (*a->access_mem) (as, ip + 8, &w1, 0, arg)) < 0)
+    return 0;
+  w1 &= 0xff;
+  return (w0 == 0x0f0000000fc0c748 && w1 == 0x05);
+}
+
+PROTECTED int
+unw_handle_signal_frame (unw_cursor_t *cursor)
+{
+  struct cursor *c = (struct cursor *) cursor;
+  int ret;
+  unw_word_t ucontext = c->dwarf.cfa;
+
+  Debug(1, "signal frame, skip over trampoline\n");
+
+  c->sigcontext_format = X86_64_SCF_LINUX_RT_SIGFRAME;
+  c->sigcontext_addr = c->dwarf.cfa;
+
+  struct dwarf_loc rsp_loc = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RSP, 0);
+  ret = dwarf_get (&c->dwarf, rsp_loc, &c->dwarf.cfa);
+  if (ret < 0)
+    {
+      Debug (2, "returning %d\n", ret);
+      return ret;
+    }
+
+  c->dwarf.loc[RAX] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RAX, 0);
+  c->dwarf.loc[RDX] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RDX, 0);
+  c->dwarf.loc[RCX] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RCX, 0);
+  c->dwarf.loc[RBX] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RBX, 0);
+  c->dwarf.loc[RSI] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RSI, 0);
+  c->dwarf.loc[RDI] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RDI, 0);
+  c->dwarf.loc[RBP] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RBP, 0);
+  c->dwarf.loc[RSP] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RSP, 0);
+  c->dwarf.loc[ R8] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R8, 0);
+  c->dwarf.loc[ R9] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R9, 0);
+  c->dwarf.loc[R10] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R10, 0);
+  c->dwarf.loc[R11] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R11, 0);
+  c->dwarf.loc[R12] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R12, 0);
+  c->dwarf.loc[R13] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R13, 0);
+  c->dwarf.loc[R14] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R14, 0);
+  c->dwarf.loc[R15] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R15, 0);
+  c->dwarf.loc[RIP] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RIP, 0);
+
+  return 0;
+}
diff --git a/src/x86_64/Gstep.c b/src/x86_64/Gstep.c
index 2da1c25..d23be8e 100644
--- a/src/x86_64/Gstep.c
+++ b/src/x86_64/Gstep.c
@@ -26,7 +26,6 @@
 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
 
 #include "unwind_i.h"
-#include "ucontext_i.h"
 #include <signal.h>
 
 PROTECTED int
@@ -79,40 +78,12 @@
 
       if (unw_is_signal_frame (cursor))
 	{
-	  unw_word_t ucontext = c->dwarf.cfa;
-
-	  Debug(1, "signal frame, skip over trampoline\n");
-
-	  c->sigcontext_format = X86_64_SCF_LINUX_RT_SIGFRAME;
-	  c->sigcontext_addr = c->dwarf.cfa;
-
-	  rsp_loc = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RSP, 0);
-	  rbp_loc = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RBP, 0);
-	  rip_loc = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RIP, 0);
-
-	  ret = dwarf_get (&c->dwarf, rsp_loc, &c->dwarf.cfa);
+          ret = unw_handle_signal_frame(cursor);
 	  if (ret < 0)
 	    {
-	      Debug (2, "returning %d\n", ret);
-	      return ret;
+	      Debug (2, "returning 0\n");
+	      return 0;
 	    }
-
-	  c->dwarf.loc[RAX] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RAX, 0);
-	  c->dwarf.loc[RDX] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RDX, 0);
-	  c->dwarf.loc[RCX] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RCX, 0);
-	  c->dwarf.loc[RBX] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RBX, 0);
-	  c->dwarf.loc[RSI] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RSI, 0);
-	  c->dwarf.loc[RDI] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RDI, 0);
-	  c->dwarf.loc[RBP] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RBP, 0);
-	  c->dwarf.loc[ R8] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R8, 0);
-	  c->dwarf.loc[ R9] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R9, 0);
-	  c->dwarf.loc[R10] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R10, 0);
-	  c->dwarf.loc[R11] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R11, 0);
-	  c->dwarf.loc[R12] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R12, 0);
-	  c->dwarf.loc[R13] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R13, 0);
-	  c->dwarf.loc[R14] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R14, 0);
-	  c->dwarf.loc[R15] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_R15, 0);
-	  c->dwarf.loc[RIP] = DWARF_LOC (ucontext + UC_MCONTEXT_GREGS_RIP, 0);
 	}
       else
 	{
@@ -153,11 +124,12 @@
 	  /* Mark all registers unsaved */
 	  for (i = 0; i < DWARF_NUM_PRESERVED_REGS; ++i)
 	    c->dwarf.loc[i] = DWARF_NULL_LOC;
+
+          c->dwarf.loc[RBP] = rbp_loc;
+          c->dwarf.loc[RSP] = rsp_loc;
+          c->dwarf.loc[RIP] = rip_loc;
 	}
 
-      c->dwarf.loc[RBP] = rbp_loc;
-      c->dwarf.loc[RSP] = rsp_loc;
-      c->dwarf.loc[RIP] = rip_loc;
       c->dwarf.ret_addr_column = RIP;
 
       if (!DWARF_IS_NULL_LOC (c->dwarf.loc[RBP]))
diff --git a/src/x86/Lis_signal_frame.c b/src/x86_64/Los-linux.c
similarity index 78%
copy from src/x86/Lis_signal_frame.c
copy to src/x86_64/Los-linux.c
index b9a7c4f..3cc18aa 100644
--- a/src/x86/Lis_signal_frame.c
+++ b/src/x86_64/Los-linux.c
@@ -1,5 +1,5 @@
 #define UNW_LOCAL_ONLY
 #include <libunwind.h>
 #if defined(UNW_LOCAL_ONLY) && !defined(UNW_REMOTE_ONLY)
-#include "Gis_signal_frame.c"
+#include "Gos-linux.c"
 #endif
diff --git a/tests/check-namespace.sh.in b/tests/check-namespace.sh.in
index 66078a1..343349f 100644
--- a/tests/check-namespace.sh.in
+++ b/tests/check-namespace.sh.in
@@ -83,6 +83,7 @@
     match _UL${plat}_init_local
     match _UL${plat}_init_remote
     match _UL${plat}_is_signal_frame
+    match _UL${plat}_handle_signal_frame
     match _UL${plat}_local_addr_space
     match _UL${plat}_resume
     match _UL${plat}_set_caching_policy
@@ -144,6 +145,7 @@
     match _U${plat}_init_local
     match _U${plat}_init_remote
     match _U${plat}_is_signal_frame
+    match _U${plat}_handle_signal_frame
     match _U${plat}_local_addr_space
     match _U${plat}_regname
     match _U${plat}_resume