Kurt Harriman
2005-Nov-25 19:39 UTC
[LLVMdev] Re: setjmp/longjmp interoperable between llvm and gcc?
On Mon, 21 Nov 2005 16:53:58 -0600 (CST), Chris wrote: >On Mon, 21 Nov 2005, Kurt Harriman wrote: >> I would like to build an x86 executable consisting of a number of >> subsystems (mostly legacy C code). One subsystem will be compiled >> to native code using llvm. It calls, and is called by, the other >> subsystems, many of which have to be compiled using gcc because they >> use small amounts of inline assembly. All of the subsystems catch >> and throw errors to one another using setjmp/longjmp. >> >> When gcc-built code calls longjmp(), the destination might be a >> setjmp() in llvm-built code, and vice versa. At present the >> gcc-built code uses the setjmp/longjmp implementations provided >> by the gnu C library; and presumably the llvm-built code will use >> llvm's setjmp/longjmp intrinsics. Are the two implementations >> safely interoperable? > >No, not right now. EH in general doesn't interoperate. This will be >fixed in the future, but is problematic for the time being. > >> Alternatives would be to force the llvm-built code to use the libgc >> setjmp/longjmp; force the gcc-built code to use a setjmp/longjmp >> borrowed from llvm; or perhaps make each setjmp tag the jmpbuf to >> show which flavor of longjmp is required. > >I depends on what sort of thing you want to do. Another option is to >compile everything with LLVM if possible. > >-Chris I'm having success with the third alternative, in which each setjmp tags the jmpbuf to show which flavor of longjmp is required. Below is the header file that I defined to wrap the setjmp/longjmp calls. ZZ_SIGSETJMP augments the jmpbuf with a function pointer to a longjmp call that is compiled in the same compilation unit as the setjmp. ZZ_SIGLONGJMP calls through this function pointer. This way, an llvm-compiled longjmp is used for every longjmp to an llvm-compiled setjmp; and a gcc-compiled longjmp is used for every longmp to a gcc-compiled setjmp. C++ exceptions or destructors wouldn't be handled properly, but that doesn't matter in this application because it is all in C. Note also that it is necessary to invoke llc with the --enable-correct-eh-support flag to enable setjmp/longjmp. Regards, ... kurt /*-------------setjmpwrapper.h-------------*/ #include <setjmp.h> /* llvm doesn't support sigsetjmp; use plain setjmp instead */ #undef sigsetjmp #define sigjmp_buf jmp_buf #define sigsetjmp(x,y) setjmp(x) #define siglongjmp longjmp typedef struct ZZ_SIGJMP_BUF { void (*zz_siglongjmp)(struct ZZ_SIGJMP_BUF *self, int value) __attribute__((__noreturn__)); sigjmp_buf jmpbuf; } ZZ_SIGJMP_BUF; static void zz_siglongjmp(struct ZZ_SIGJMP_BUF *self, int value) __attribute__((__noreturn__)) __attribute__((__always_inline__)); void zz_siglongjmp(struct ZZ_SIGJMP_BUF *self, int value) { siglongjmp(self->jmpbuf, value); } #define ZZ_SIGSETJMP(zz_sigjmp_buf, savesigs) \ ( (zz_sigjmp_buf).zz_siglongjmp = zz_siglongjmp, \ sigsetjmp((zz_sigjmp_buf).jmpbuf, (savesigs)) ) #define ZZ_SIGLONGJMP(zz_sigjmp_buf, value) \ ( (zz_sigjmp_buf).zz_siglongjmp(&(zz_sigjmp_buf), (value)) ) /*-----------------------------------------*/
Apparently Analagous Threads
- [LLVMdev] setjmp/longjmp interoperable between llvm and gcc?
- compiling R on sparc-solaris
- Fix build error with GCC 10 due to multiple definition of `toplevel'
- [PATCH RESEND] tftp-hpa: Fix build error with GCC 10 due to multiple definition of `toplevel'
- ia64 mis-merge