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)