On Fri, Feb 21, 2003 at 11:55:41AM -0500, David Dawes wrote:
>On Fri, Feb 21, 2003 at 01:19:08PM +0000, Dr Andrew C Aitchison wrote:
>>The setjmp/longjmp fix in
>>      xc/programs/Xserver/hw/xfree86/loader/xf86sym.c
>>and   xc/programs/Xserver/hw/xfree86/xf86cfg/loadmod.c
>>doesn't compile in
>>      RedHat 6.2      egcs-2.91.66
>>
>>It works fine with
>>      Red Hat 7.3     gcc 2.96
>>and
>>      Red Hat 8.0     gcc (GCC) 3.2 20020903 (Red Hat Linux 8.0 3.2-7)
>
>It looks like RH 6.2 and earlier (i.e. glibc before 2.2) uses a macro for
>setjmp():
>
>extern int __sigsetjmp __P ((jmp_buf __env, int __savemask));
>
>#ifndef __FAVOR_BSD
>/* Set ENV to the current position and return 0, not saving the signal mask.
>   This is just like `sigsetjmp (ENV, 0)'.
>   The ISO C standard says `setjmp' is a macro.  */
># define setjmp(env)    __sigsetjmp ((env), 0)
>#else
>/* We are in 4.3 BSD-compatibility mode in which `setjmp'
>   saves the signal mask like `sigsetjmp (ENV, 1)'.  */
># define setjmp(env)    __sigsetjmp ((env), 1)
>#endif /* Favor BSD.  */
>
>
>Harbison & Steele also refers to "the macro setjump" and "the function
>longjmp".
>
>This certainly complicates things.
>
>A couple of possibilities:
>
>  1. Include <setjmp.h> directly into modules that need it, ensure that the
>     necessary (platform-specific) entry points are exported, and accept that
>     modules that use it are not OS-neutral.
>
>  2. Provide aliases for the actual functions uses on the platforms we support,
>     and come up with a macro for xf86setjmp() that calls the correct one in
>     the correct way, probably by first querying a function in the core
>     server for which way to use.
>

The attached patch attempts to implement the second approach, and from
some limited testing it works OK for the two cases handled so far (where
setjmp is available directly as a function, and the glibc 2.[01] case
where it's a macro defined as above).

This approach method isn't always guaranteed to work given the limits that
ISO C places on the way setjmp() can be called.

Has anyone found any other platforms where setjmp isn't available
directly as a function?

David
--
David Dawes
Release Engineer/Architect                      The XFree86 Project
www.XFree86.org/~dawes
Index: lib/font/FreeType/ftstdlib.h
===================================================================
RCS file: /home/x-cvs/xc/lib/font/FreeType/ftstdlib.h,v
retrieving revision 1.4
diff -u -r1.4 ftstdlib.h
--- lib/font/FreeType/ftstdlib.h        2002/10/10 01:18:31     1.4
+++ lib/font/FreeType/ftstdlib.h        2003/02/21 18:39:01
@@ -58,6 +58,7 @@
 #define _XTYPEDEF_BOOL
 #include "Xdefs.h"
 #define DONT_DEFINE_WRAPPERS
+#define DEFINE_SETJMP_WRAPPERS
 #include "xf86_ansic.h"
 #undef DONT_DEFINE_WRAPPERS
 
@@ -94,9 +95,9 @@
 
 #define ft_atoi   xf86atoi
 
-#define ft_jmp_buf  xf86jmp_buf
-#define ft_setjmp   xf86setjmp
-#define ft_longjmp  xf86longjmp
+#define ft_jmp_buf  jmp_buf
+#define ft_setjmp   setjmp
+#define ft_longjmp  longjmp
 
 #endif /* FONTMODULE */
 
Index: programs/Xserver/hw/xfree86/loader/xf86sym.c
===================================================================
RCS file: /home/x-cvs/xc/programs/Xserver/hw/xfree86/loader/xf86sym.c,v
retrieving revision 1.225
diff -u -r1.225 xf86sym.c
--- programs/Xserver/hw/xfree86/loader/xf86sym.c        2003/02/21 03:11:57     1.225
+++ programs/Xserver/hw/xfree86/loader/xf86sym.c        2003/02/21 21:15:35
@@ -134,6 +134,17 @@
 #pragma weak __umodsi3
 #endif
 
+
+#if defined(setjmp) && \
+    defined(__GLIBC__) && __GLIBC__ == 2 && __GLIBC_MINOR__ < 2
+#undef setjmp
+extern int setjmp(jmp_buf env);
+#pragma weak setjmp
+#elif !defined(__GLIBC__)
+extern int __sigsetjmp(jmp_buf __env, int __savemask);
+#pragma weak __sigsetjmp
+#endif
+
 #if defined(__arm__) && defined(__linux__)
 #include <sys/io.h>
 #endif
@@ -889,7 +900,10 @@
    SYMFUNC(xf86shmdt)
    SYMFUNC(xf86shmctl)
    SYMFUNCALIAS("xf86setjmp",setjmp)
+   SYMFUNCALIAS("xf86setjmp1",__sigsetjmp)
    SYMFUNCALIAS("xf86longjmp",longjmp)
+   SYMFUNC(xf86getjmptype)
+   SYMFUNC(xf86setjmperror)
 #ifdef XF86DRI
                                /* These may have more general uses, but
                                    for now, they are only used by the DRI.
Index: programs/Xserver/hw/xfree86/os-support/xf86_ansic.h
===================================================================
RCS file: /home/x-cvs/xc/programs/Xserver/hw/xfree86/os-support/xf86_ansic.h,v
retrieving revision 3.48
diff -u -r3.48 xf86_ansic.h
--- programs/Xserver/hw/xfree86/os-support/xf86_ansic.h 2001/12/31 18:13:37     3.48
+++ programs/Xserver/hw/xfree86/os-support/xf86_ansic.h 2003/02/21 21:21:59
@@ -305,8 +305,16 @@
 extern char * xf86shmat(int id, char *addr, int xf86shmflg);
 extern int xf86shmdt(char *addr);
 extern int xf86shmctl(int id, int xf86cmd, pointer buf);
+
 extern int xf86setjmp(xf86jmp_buf env);
+extern int xf86setjmp1(xf86jmp_buf env, int);
+extern int xf86setjmperror(xf86jmp_buf env, int);
+extern int xf86getjmptype(void);
 extern void xf86longjmp(xf86jmp_buf env, int val);
+#define xf86setjmp_macro(env) \
+       (xf86getjmptype() == 0 ? xf86setjmp((env)) : \
+       (xf86getjmptype() == 1 ? xf86setjmp1((env), 0) : \
+               xf86setjmperror((env), xf86getjmptype())))
 
 #else /* XFree86LOADER || NEED_XF86_PROTOTYPES */
 #include <unistd.h>
Index: programs/Xserver/hw/xfree86/os-support/xf86_libc.h
===================================================================
RCS file: /home/x-cvs/xc/programs/Xserver/hw/xfree86/os-support/xf86_libc.h,v
retrieving revision 3.55
diff -u -r3.55 xf86_libc.h
--- programs/Xserver/hw/xfree86/os-support/xf86_libc.h  2003/02/21 03:11:57     3.55
+++ programs/Xserver/hw/xfree86/os-support/xf86_libc.h  2003/02/21 18:38:31
@@ -448,10 +448,6 @@
 #define shmdt(a)               xf86shmdt(a)
 #undef shmctl
 #define shmctl(a,b,c)          xf86shmctl(a,b,c)
-#undef setjmp
-#define setjmp(a)               xf86setjmp(a)
-#undef longjmp
-#define longjmp(a,b)            xf86longjmp(a,b) 
 
 #undef S_ISUID
 #define S_ISUID XF86_S_ISUID
@@ -507,8 +503,6 @@
 #define uid_t                   xf86uid_t
 #undef gid_t
 #define gid_t                   xf86gid_t
-#undef jmp_buf
-#define jmp_buf                 xf86jmp_buf
 #undef stat_t
 #define stat_t                 struct xf86stat
 
@@ -662,7 +656,17 @@
 /* Some ANSI macros */
 #undef FILENAME_MAX
 #define FILENAME_MAX           1024
+
+#endif /* XFree86LOADER  && !DONT_DEFINE_WRAPPERS */
 
-#endif /* XFree86LOADER */
+#if defined(XFree86LOADER) && \
+    (!defined(DONT_DEFINE_WRAPPERS) || defined(DEFINE_SETJMP_WRAPPERS))
+#undef setjmp
+#define setjmp(a)               xf86setjmp_macro(a)
+#undef longjmp
+#define longjmp(a,b)            xf86longjmp(a,b) 
+#undef jmp_buf
+#define jmp_buf                 xf86jmp_buf
+#endif
 
 #endif /* XF86_LIBC_H */
Index: programs/Xserver/hw/xfree86/os-support/shared/libc_wrapper.c
===================================================================
RCS file: /home/x-cvs/xc/programs/Xserver/hw/xfree86/os-support/shared/libc_wrapper.c,v
retrieving revision 1.87
diff -u -r1.87 libc_wrapper.c
--- programs/Xserver/hw/xfree86/os-support/shared/libc_wrapper.c        2003/02/21 
03:11:57     1.87
+++ programs/Xserver/hw/xfree86/os-support/shared/libc_wrapper.c        2003/02/21 
21:19:23
@@ -1944,3 +1944,19 @@
     return -1;
 }
 #endif /* HAVE_SYSV_IPC */
+
+int
+xf86getjmptype()
+{
+#if defined(__GLIBC__) && ((__GLIBC__ == 2) && (__GLIBC_MINOR__ <= 1))
+    return 1;
+#else
+    return 0;
+#endif
+}
+
+int
+xf86setjmperror(xf86jmp_buf env, int type)
+{
+    FatalError("Don't know how to handle setjmp() type %d\n");
+}
Index: programs/Xserver/hw/xfree86/xf86cfg/loadmod.c
===================================================================
RCS file: /home/x-cvs/xc/programs/Xserver/hw/xfree86/xf86cfg/loadmod.c,v
retrieving revision 1.12
diff -u -r1.12 loadmod.c
--- programs/Xserver/hw/xfree86/xf86cfg/loadmod.c       2003/02/21 03:11:58     1.12
+++ programs/Xserver/hw/xfree86/xf86cfg/loadmod.c       2003/02/21 21:23:27
@@ -75,6 +75,16 @@
 FontModule *font_module;
 int numFontModules;
 
+#if defined(setjmp) && \
+    defined(__GLIBC__) && __GLIBC__ == 2 && __GLIBC_MINOR__ < 2
+#undef setjmp
+extern int setjmp(jmp_buf env);
+#pragma weak setjmp
+#elif !defined(__GLIBC__)
+extern int __sigsetjmp(jmp_buf __env, int __savemask);
+#pragma weak __sigsetjmp
+#endif
+
 extern int noverify, error_level;
 
 int xf86ShowUnresolved = 1;
@@ -266,7 +276,10 @@
    SYMFUNC(xf86shmdt)
    SYMFUNC(xf86shmctl)
    SYMFUNCALIAS("xf86setjmp",setjmp)
+   SYMFUNCALIAS("xf86setjmp1",__sigsetjmp)
    SYMFUNCALIAS("xf86longjmp",longjmp)
+   SYMFUNC(xf86getjmptype)
+   SYMFUNC(xf86setjmperror)
 
     SYMFUNC(xf86AddDriver)
     SYMFUNC(xf86ServerIsOnlyDetecting)

Reply via email to