unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
* Building Guile on IA64 HPUX
@ 2006-10-25 15:31 Hrvoje Nikšić
  2006-10-25 22:36 ` Neil Jerram
  0 siblings, 1 reply; 7+ messages in thread
From: Hrvoje Nikšić @ 2006-10-25 15:31 UTC (permalink / raw)


[-- Attachment #1: Type: text/plain, Size: 2151 bytes --]

We use Guile on a number of platforms, including HP-UX 11.23 on Itanium.
While Guile seems to build on IA64 HPUX, it crashes while running
because of GC failing to mark some objects reachable through the stack.

There are three distinct problems that require attention:

1. The checks for __ia64__ don't work on HPUX because its compilers set
__ia64, not __ia64__.

2. The GC code under #ifdef __ia64__ accesses Linux-specific fields of
ucontext_t and the Linux-specific variable
__libc_ia64_register_backing_store_base.

3. The implementation of continuations under IA64 Linux makes use of a
non-standard and (to the best of my knowledge) undocumented extension to
getcontext.  It declares getcontext to return two values, and uses the
second one to determine whether the code after getcontext is executed
linearly or as a result to a call to setcontext.


The first problem can be solved by either changing the ifdefs, or by
#definining __ia64__ if defined(__ia64) && !defined(__ia64__).  That's
the easy one.

The second problem can be solved by using the libuca library on HPUX to
retrieve the Itanium-specific fields of the opaque ucontext_t structure.
This requires a change to configure to detect libuca, but the change is
trivial, since libuca is a "system library", therefore not requiring
special link magic.  As for __libc_ia64_register_backing_store_base, its
HPUX equivalent can be retrieved using the `pstat_getprocvm', as is done
in the Boehm collector.

The third issue requires the addition of a simple boolean field to
scm_t_contregs, which make_continuation uses to keep track of whether
the context was reached by setcontext or by falling through the call to
getcontext.  As far as I can tell, the non-standard use of getcontext is
really not necessary for this to work.


Putting all this together, I assembled a patch which, when applied,
should make Guile buildable on both IA64 HPUX and Linux, without
affecting other architectures.  After applying the patch, you will need
to run autoconf and autoheader.  Unfortunately the patch is for Guile
1.6.7 (which we use locally), but it should be trivial to port to 1.8.1
or 1.6.8.


[-- Attachment #2: guile-patch --]
[-- Type: text/x-patch, Size: 6996 bytes --]

diff -ru guile-1.6.7-orig/configure guile-1.6.7/configure
--- guile-1.6.7-orig/configure.in	2004-08-27 04:16:31.000000000 +0200
+++ guile-1.6.7/configure.in	2006-10-25 15:33:15.000000000 +0200
@@ -220,6 +220,7 @@
 if test $ac_cv_func_connect = no; then
     AC_CHECK_LIB(socket, connect)
 fi
+AC_CHECK_LIB(uca, __uc_get_ar_bsp)
 
 # Check for dynamic linking
 
diff -ru guile-1.6.7-orig/libguile/continuations.c guile-1.6.7/libguile/continuations.c
--- guile-1.6.7-orig/libguile/continuations.c	2003-09-12 20:58:00.000000000 +0200
+++ guile-1.6.7/libguile/continuations.c	2006-10-25 16:06:30.000000000 +0200
@@ -114,15 +114,6 @@
   return 1;
 }
 
-#ifdef __ia64__
-struct rv
-{
-  long retval;
-  long first_return;
-};
-extern struct rv ia64_getcontext (ucontext_t *) __asm__ ("getcontext");
-#endif /* __ia64__ */
-
 /* this may return more than once: the first time with the escape
    procedure, then subsequently with the value to be passed to the
    continuation.  */
@@ -135,9 +126,6 @@
   scm_t_contregs *rootcont = SCM_CONTREGS (scm_rootcont);
   long stack_size;
   SCM_STACKITEM * src;
-#ifdef __ia64__
-  struct rv rv;
-#endif
 
   SCM_ENTER_A_SECTION;
   SCM_FLUSH_REGISTER_WINDOWS;
@@ -162,19 +150,22 @@
   memcpy (continuation->stack, src, sizeof (SCM_STACKITEM) * stack_size);
 
 #ifdef __ia64__
-  rv = ia64_getcontext (&continuation->ctx);
-  if (rv.first_return)
+  continuation->fresh = 1;
+  getcontext (&continuation->ctx);
+  if (continuation->fresh)
     {
-      continuation->backing_store_size = 
-        continuation->ctx.uc_mcontext.sc_ar_bsp - 
-        __libc_ia64_register_backing_store_base;
+      continuation->backing_store_size =
+	(char *) scm_ia64_ar_bsp(&continuation->ctx)
+	-
+	(char *) scm_ia64_register_backing_store_base ();
       continuation->backing_store = NULL;
       continuation->backing_store = 
         scm_must_malloc (continuation->backing_store_size, FUNC_NAME);
       memcpy (continuation->backing_store, 
-              (void *) __libc_ia64_register_backing_store_base, 
+              (void *) scm_ia64_register_backing_store_base (), 
               continuation->backing_store_size);
       *first = 1;
+      continuation->fresh = 0;
       return cont;
     }
   else
@@ -235,7 +226,7 @@
 
   continuation->throw_value = val;
 #ifdef __ia64__
-  memcpy ((void *) __libc_ia64_register_backing_store_base,
+  memcpy (scm_ia64_register_backing_store_base (),
           continuation->backing_store,
           continuation->backing_store_size);
   setcontext (&continuation->ctx);
diff -ru guile-1.6.7-orig/libguile/continuations.h guile-1.6.7/libguile/continuations.h
--- guile-1.6.7-orig/libguile/continuations.h	2003-09-12 20:58:00.000000000 +0200
+++ guile-1.6.7/libguile/continuations.h	2006-10-25 16:29:55.000000000 +0200
@@ -46,10 +46,8 @@
 #include "libguile/__scm.h"
 
 #ifdef __ia64__
-#include <ucontext.h>
-extern unsigned long  __libc_ia64_register_backing_store_base;
+# include <ucontext.h>
 #endif
-\f
 
 /* a continuation SCM is a non-immediate pointing to a heap cell with:
    word 0: bits 0-15: smob type tag: scm_tc16_continuation.
@@ -68,6 +66,7 @@
   SCM dynenv;
 #ifdef __ia64__
   ucontext_t ctx;
+  int fresh;
   void *backing_store;
   unsigned long backing_store_size;
 #endif /* __ia64__ */
diff -ru guile-1.6.7-orig/libguile/gc.c guile-1.6.7/libguile/gc.c
--- guile-1.6.7-orig/libguile/gc.c	2004-09-11 17:54:23.000000000 +0200
+++ guile-1.6.7/libguile/gc.c	2006-10-25 16:37:15.000000000 +0200
@@ -53,11 +53,6 @@
 #include <string.h>
 #include <assert.h>
 
-#ifdef __ia64__
-#include <ucontext.h>
-extern unsigned long __libc_ia64_register_backing_store_base;
-#endif
-
 #include "libguile/_scm.h"
 #include "libguile/eval.h"
 #include "libguile/stime.h"
@@ -1034,15 +1029,15 @@
 scm_t_c_hook scm_after_gc_c_hook;
 
 #ifdef __ia64__
-# define SCM_MARK_BACKING_STORE() do {                                \
-    ucontext_t ctx;                                                   \
-    SCM_STACKITEM * top, * bot;                                       \
-    getcontext (&ctx);                                                \
-    scm_mark_locations ((SCM_STACKITEM *) &ctx.uc_mcontext,           \
-      ((size_t) (sizeof (SCM_STACKITEM) - 1 + sizeof ctx.uc_mcontext) \
-       / sizeof (SCM_STACKITEM)));                                    \
-    bot = (SCM_STACKITEM *) __libc_ia64_register_backing_store_base;  \
-    top = (SCM_STACKITEM *) ctx.uc_mcontext.sc_ar_bsp;                \
+# define SCM_MARK_BACKING_STORE() do {					\
+    ucontext_t ctx;							\
+    SCM_STACKITEM * top, * bot;						\
+    getcontext (&ctx);							\
+    scm_mark_locations ((SCM_STACKITEM *) &ctx.uc_mcontext,		\
+      ((size_t) (sizeof (SCM_STACKITEM) - 1 + sizeof ctx.uc_mcontext)	\
+       / sizeof (SCM_STACKITEM)));					\
+    bot = (SCM_STACKITEM *) scm_ia64_register_backing_store_base ();	\
+    top = (SCM_STACKITEM *) scm_ia64_ar_bsp (&ctx);			\
     scm_mark_locations (bot, top - bot); } while (0)
 #else
 # define SCM_MARK_BACKING_STORE()
@@ -2915,8 +2910,49 @@
 #include "libguile/gc.x"
 }
 
+#ifdef __ia64__
+# ifdef __hpux
+#  include <sys/param.h>
+#  include <sys/pstat.h>
+void *
+scm_ia64_register_backing_store_base (void)
+{
+  struct pst_vm_status vm_status;
+  int i = 0;
+  while (pstat_getprocvm (&vm_status, sizeof (vm_status), 0, i++) == 1)
+    if (vm_status.pst_type == PS_RSESTACK)
+      return (void *) vm_status.pst_vaddr;
+  abort ();
+}
+void *
+scm_ia64_ar_bsp (const void *ctx)
+{
+  uint64_t bsp;
+  __uc_get_ar_bsp(ctx, &bsp);
+  return (void *) bsp;
+}
+# endif /* hpux */
+# ifdef linux
+#  include <ucontext.h>
+void *
+scm_ia64_register_backing_store_base (void)
+{
+  extern void *__libc_ia64_register_backing_store_base;
+  return __libc_ia64_register_backing_store_base;
+}
+void *
+scm_ia64_ar_bsp (const void *opaque)
+{
+  ucontext_t *ctx = opaque;
+  return (void *) ctx->uc_mcontext.sc_ar_bsp;
+}
+# endif	/* linux */
+#endif /* __ia64__ */
+
 #endif /*MARK_DEPENDENCIES*/
 
+
+
 /*
   Local Variables:
   c-file-style: "gnu"
diff -ru guile-1.6.7-orig/libguile/gc.h guile-1.6.7/libguile/gc.h
--- guile-1.6.7-orig/libguile/gc.h	2004-09-11 17:54:23.000000000 +0200
+++ guile-1.6.7/libguile/gc.h	2006-10-25 16:01:42.000000000 +0200
@@ -395,6 +395,11 @@
 extern void *scm_get_stack_base (void);
 extern void scm_init_gc (void);
 
+#ifdef __ia64__
+void *scm_ia64_register_backing_store_base (void);
+void *scm_ia64_ar_bsp (const void *);
+#endif
+
 \f
 
 #if (SCM_DEBUG_DEPRECATED == 0)
diff -ru guile-1.6.7-orig/libguile/_scm.h guile-1.6.7/libguile/_scm.h
--- guile-1.6.7-orig/libguile/_scm.h	2002-12-07 23:41:31.000000000 +0100
+++ guile-1.6.7/libguile/_scm.h	2006-10-25 16:06:49.000000000 +0200
@@ -57,6 +57,9 @@
    should go in __scm.h.  */
 
 
+#if defined(__ia64) && !defined(__ia64__)
+# define __ia64__
+#endif
 
 /* Include headers for those files central to the implementation.  The
    rest should be explicitly #included in the C files themselves.  */

[-- Attachment #3: Type: text/plain, Size: 143 bytes --]

_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-devel

^ permalink raw reply	[flat|nested] 7+ messages in thread
[parent not found: <200611012157.NAA20914@hpsje.cup.hp.com>]

end of thread, other threads:[~2006-11-02 21:15 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-10-25 15:31 Building Guile on IA64 HPUX Hrvoje Nikšić
2006-10-25 22:36 ` Neil Jerram
2006-10-26  7:13   ` Hrvoje Nikšić
2006-10-27  0:06     ` Neil Jerram
2006-10-27  7:16       ` Hrvoje Nikšić
     [not found] <200611012157.NAA20914@hpsje.cup.hp.com>
2006-11-02  8:29 ` Hrvoje Nikšić
2006-11-02 21:15 ` Neil Jerram

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).