[Cegcc-devel] WinCE Exception handling support in gcc
Guys, I've been digging in gcc internals and succeeded in implementing stuff that allows us to write code such as int main(int argc, char *argv[]) __attribute__((__exception_handler__(handler))); to indicate that handler is the exception handler for function main. The patch is attached, it only affects four files in gcc. What this gcc patch does is to generate an additional couple of lines of assembler code for those functions that have an exception handler. Attached is an example in C and the assembler code generated for it. In the arm-wince-mingw32ce world, only patches to gcc are required, no changes to any runtime are needed. (I need to look into the cegcc environment, things are slightly different there because a default exception handler is in place there.) Comments are welcome as always. Pedro, is it ok to commit this to SVN ? Danny -- Danny Backx ; danny.backx - at - scarlet.be ; http://danny.backx.info #include #include #include struct _DISPATCHER_CONTEXT; void handler(struct _EXCEPTION_RECORD *ExceptionRecord, void *EstablisherFrame, struct _CONTEXT *ContextRecord, struct _DISPATCHER_CONTEXT *DispatcherContext) { MessageBoxW(0, L"Crash Handler", L"WinCE Exception", 0); exit(0); } int main(int argc, char *argv[]) __attribute__((__exception_handler__(handler))); int main(int argc, char *argv[]) { int *i; i = 0; *i = 1; MessageBoxW(0, L"Main", L"Survived", 0); exit(0); } .file "syntax.c" .section .rdata .align 0 .LC0: .ascii "C\000r\000a\000s\000h\000 \000H\000a\000n\000d\000l" .ascii "\000e\000r\000\000\000" .align 0 .LC1: .ascii "W\000i\000n\000C\000E\000 \000E\000x\000c\000e\000p" .ascii "\000t\000i\000o\000n\000\000\000" .text .align 0 .global handler .defhandler;.scl2; .type 32; .endef handler: @ args = 0, pretend = 0, frame = 16 @ frame_needed = 1, uses_anonymous_args = 0 mov ip, sp stmfd sp!, {fp, ip, lr, pc} sub fp, ip, #4 sub sp, sp, #16 str r0, [fp, #-16] str r1, [fp, #-20] str r2, [fp, #-24] str r3, [fp, #-28] mov r0, #0 ldr r1, .L3 ldr r2, .L3+4 mov r3, #0 bl MessageBoxW mov r0, #0 bl exit .L4: .align 0 .L3: .word .LC0 .word .LC1 .def__gccmain; .scl2; .type 32; .endef .section .rdata .align 0 .LC2: .ascii "M\000a\000i\000n\000\000\000" .align 0 .LC3: .ascii "S\000u\000r\000v\000i\000v\000e\000d\000\000\000" .text .align 0 .global main @ main has exception handler handler .section .pdata .word main .word 0xc002 | _cegcc_main_end - main) / 4) & 0x3ff) << 8) /* _cegcc_main size */ .text @ .global _cegcc_main_data _cegcc_main_data: .word handler /* _cegcc_main_handler */ .word 0 /* _cegcc_main_handler_data */ .defmain; .scl2; .type 32; .endef main: @ args = 0, pretend = 0, frame = 12 @ frame_needed = 1, uses_anonymous_args = 0 mov ip, sp stmfd sp!, {fp, ip, lr, pc} sub fp, ip, #4 sub sp, sp, #12 str r0, [fp, #-20] str r1, [fp, #-24] bl __gccmain mov r3, #0 str r3, [fp, #-16] ldr r2, [fp, #-16] mov r3, #1 str r3, [r2, #0] mov r0, #0 ldr r1, .L7 ldr r2, .L7+4 mov r3, #0 bl MessageBoxW mov r0, #0 bl exit .L8: .align 0 .L7: .word .LC2 .word .LC3 _cegcc_main_end: .defexit; .scl2; .type 32; .endef .defMessageBoxW;.scl2; .type 32; .endef Index: gcc/gcc/c-common.c === --- gcc/gcc/c-common.c (revision 1020) +++ gcc/gcc/c-common.c (working copy) @@ -505,6 +505,8 @@ static tree handle_noinline_attribute (tree *, tree, tree, int, bool *); static tree handle_always_inline_attribute (tree *, tree, tree, int, bool *); +static tree handle_exception_handler_attribute (tree *, tree, tree, int, + bool *); static tree handle_flatten_attribute (tree *, tree, tree, int, bool *); static tree handle_used_attribute (tree *, tree, tree, int, bool *); static tree handle_unused_attribute (tree *, tree, tree, int, bool *); @@ -633,6 +635,8 @@ handle_cleanup_attribute }, { "warn_unused_result", 0, 0, false, true, true, handle_warn_unused_result_attribute }, + { "exception_handler", 1, 1, true, false, false, + handle_exception_handler_attribute }, { "sentinel",
Re: [Cegcc-devel] Building pthread.
Hi Pedro, thanks for the hints, I got libpthread compiling now. Since __MINGW32__ is defined, the code assumes some things that are not true for WinCE, e.g. like having errno. Instead of modifying mingw32ce now I just modify the pthread-w32-2.8.0 code and add a few more compiler flags, see the attached diff file. I compile with make CROSS=arm-wince-mingw32ce- CC="arm-wince-mingw32ce-g++ -DWINCE -DNEED_ERRNO -D_ARM_ -D__CRTDLL__ -D_DLL" clean GC PS: I still can't compile jamvm because of missing liltdl. Do you know where I can find it for WinCE? It seems to be part of glibc... Kind Regards, Leonardo. - Ursprüngliche Mail Von: Pedro Alves <[EMAIL PROTECTED]> An: Leonardo Weiss Chaves <[EMAIL PROTECTED]> CC: cegcc-devel@lists.sourceforge.net Gesendet: Freitag, den 20. Juli 2007, 16:01:45 Uhr Betreff: Re: AW: [Cegcc-devel] Building pthread. Leonardo Weiss Chaves wrote: > I am still not able to compile any kind of pthreads with cegcc/mingw32ce. > > I did some smaller modifications to the source of mingw32e and to > pthread-w32-2.8.0, and it almost compiles. But at the end I get lots of > undefined references. This is strange, since the compiler flag "-DWINCE" > should take care of this, for instance by using the errno hack you mentioned. > > I commented the following lines out on mingw32Ce files: > errno.h 12,13,14,109 > signal.h 12 > process.h 99,102 > You shouldn't do this. That include_next is there to make it as if the files didn't exist. Either provide your own versions of these files in the include path (-I), so the include_next picks them up, or don't include them in the first place: #ifndef _WIN32_WCE #include #endif or, #ifdef HAVE_ERRNO_H #include #endif or similar. > arm-wince-mingw32ce-g++ -DWINCE -D__CLEANUP_C -O3 -finline-functions -shared > -o pthreadGC2.dll attr.o barrier.o cancel.o cleanup.o condvar.o create.o > dll.o errno.o exit.o fork.o global.o misc.o mutex.o nonportable.o private.o > rwlock.o sched.o semaphore.o signal.o spin.o sync.o tsd.o version.o I don't see any libs being linked in here? Where is the -lws2 ? > condvar.o:condvar.c:(.text+0x184): undefined reference to `errno' > condvar.o:condvar.c:(.text+0x25c): undefined reference to `errno' > condvar.o:condvar.c:(.text+0x400): undefined reference to `errno' > condvar.o:condvar.c:(.text+0x5a0): undefined reference to `errno' > condvar.o:condvar.c:(.text+0x6f0): undefined reference to `errno' > condvar.o:condvar.c:(.text+0x848): more undefined references to `errno' follow > create.o:create.c:(.text+0x108): undefined reference to `_beginthread' > exit.o:exit.c:(.text+0x2c): undefined reference to `_endthread' > misc.o:misc.c:(.text+0x224): undefined reference to `ptw32_mcs_lock_acquire' > misc.o:misc.c:(.text+0x244): undefined reference to `ptw32_mcs_lock_release' > misc.o:misc.c:(.text+0x274): undefined reference to `ptw32_mcs_lock_release' > mutex.o:mutex.c:(.text+0x3c8): undefined reference to `ptw32_relmillisecs' > mutex.o:mutex.c:(.text+0x550): undefined reference to `ptw32_relmillisecs' > private.o:private.c:(.text+0xe4): undefined reference to `errno' > private.o:private.c:(.text+0x2b8): undefined reference to `_endthread' > private.o:private.c:(.text+0x4d4): undefined reference to `_endthread' > sched.o:sched.c:(.text+0x1c): undefined reference to `errno' > sched.o:sched.c:(.text+0x3c): undefined reference to `errno' > sched.o:sched.c:(.text+0xb4): undefined reference to `errno' > sched.o:sched.c:(.text+0x130): undefined reference to `errno' > semaphore.o:semaphore.c:(.text+0x14): undefined reference to `errno' > semaphore.o:semaphore.c:(.text+0x2c): more undefined references to `errno' > follow > semaphore.o:semaphore.c:(.text+0x32c): undefined reference to > `ptw32_relmillisecs' > semaphore.o:semaphore.c:(.text+0x3ec): undefined reference to `errno' > semaphore.o:semaphore.c:(.text+0x550): undefined reference to `errno' > semaphore.o:semaphore.c:(.text+0x61c): undefined reference to `errno' > semaphore.o:semaphore.c:(.text+0x6d4): undefined reference to `errno' Looks like you are missing some .o's in the link command line. Try to find where the 'int errno' is defined as opposed to just declared (extern int errno). Same for _beginthread/_endthread, they should be defined somewhere in the pthreads WinCE port, as WinCE doesn't provide those. > tsd.o:tsd.c:(.text+0x18): undefined reference to `WSAGetLastError' > tsd.o:tsd.c:(.text+0x38): undefined reference to `WSASetLastError' These come from ws2.dll, but you don't have it in the command line... (-lws2) Cheers, Pedro Alves __ Die etwas anderen Infos rund um das Thema Reisen. BE A BETTER WELTENBUMMLER! www.yahoo.de/cleverdiff pthreads-w32-2-8-0-release/create.c pthreads-w32-2-8-0-wince/create.c 203c203 < #if ! defined (__MINGW32__) || defined (__MSVCRT__) || defined (__DMC__) --- > #if ! defined (__MINGW32__) || defined (__MSVCRT__) || defined (__DMC__) || > defined (WINCE) 20
Re: [Cegcc-devel] Building pthread.
On Mon, 2007-07-23 at 12:25 -0700, Leonardo Weiss Chaves wrote: > Hi Pedro, > > thanks for the hints, I got libpthread compiling now. Since __MINGW32__ is > defined, the code assumes some things that are not true for WinCE, e.g. like > having errno. Instead of modifying mingw32ce now I just modify the > pthread-w32-2.8.0 code and add a few more compiler flags, see the attached > diff file. I compile with > > make CROSS=arm-wince-mingw32ce- CC="arm-wince-mingw32ce-g++ -DWINCE > -DNEED_ERRNO -D_ARM_ -D__CRTDLL__ -D_DLL" clean GC > > PS: I still can't compile jamvm because of missing liltdl. Do you know where > I can find it for WinCE? It seems to be part of glibc... > > Kind Regards, > Leonardo. Which library is that, which symbols are you still missing ? Danny -- Danny Backx ; danny.backx - at - scarlet.be ; http://danny.backx.info signature.asc Description: This is a digitally signed message part - This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/___ Cegcc-devel mailing list Cegcc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/cegcc-devel