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)