From 99caab779f76364d17790cd9a5fe0c112d05161b Mon Sep 17 00:00:00 2001 From: John van Groningen Date: Tue, 27 Apr 2004 10:10:35 +0000 Subject: add -stdwin flag to send std io to Console/Message window instead of to the terminal or console, add mach exception handling code for detecting stack overflows --- mcon.c | 252 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 229 insertions(+), 23 deletions(-) diff --git a/mcon.c b/mcon.c index 1f543c6..672d6c4 100644 --- a/mcon.c +++ b/mcon.c @@ -8,6 +8,7 @@ #define NEW_HEADERS #ifdef MACHO # define MACOSX +# define MACHO_EXCEPTIONS #endif #ifdef MACOSX # define FLUSH_PORT_BUFFER @@ -68,6 +69,9 @@ void first_function (void) #ifdef STACK_OVERFLOW_EXCEPTION_HANDLER # ifdef MACHO # include +# ifdef MACHO_EXCEPTIONS +# include +# endif # else # include # include @@ -1786,6 +1790,7 @@ void *allocate_a_stack (int size) extern int *halt_sp; extern void stack_overflow (void); +#ifndef MACHO_EXCEPTIONS struct sigaction old_BUS_sa,old_SEGV_sa; static void clean_exception_handler (int sig,void *sip,struct sigcontext *scp) @@ -1832,6 +1837,154 @@ static void clean_exception_handler (int sig,void *sip,struct sigcontext *scp) call_function_3 (sig,sip,scp,old_sa_p->sa_handler); # endif } +#else +# define N_OLD_EXCEPTION_PORTS 64 + +static mach_msg_type_number_t n_ports; +static exception_mask_t old_exception_masks[N_OLD_EXCEPTION_PORTS]; +static exception_handler_t old_exception_handlers[N_OLD_EXCEPTION_PORTS]; +static exception_behavior_t old_exception_behaviors[N_OLD_EXCEPTION_PORTS]; +static thread_state_flavor_t old_thread_state_flavors[N_OLD_EXCEPTION_PORTS]; + +static mach_port_t exception_port; + +static kern_return_t forward_exception (mach_port_t thread,mach_port_t task,exception_type_t exception,exception_data_t code,mach_msg_type_number_t code_count) +{ + exception_mask_t exception_mask; + exception_behavior_t behavior; + int port_n; + + exception_mask=1<msgh_size,0,msg->msgh_local_port,0,MACH_PORT_NULL)!=KERN_SUCCESS){ + /* printf ("mach_msg failed\n"); */ + exit (1); + } + } +} +#endif # ifndef MACHO extern int *get_TOC (void); @@ -1866,9 +2019,9 @@ static void install_clean_exception_handler (void) if (r!=0) return; -#ifndef MACHO +# ifndef MACHO stack_top=(int*)(vm_address+vm_size); -#endif +# endif do { previous_address=vm_address; @@ -1884,7 +2037,7 @@ static void install_clean_exception_handler (void) b_stack_guard_page=(int*)((int)previous_address-4096); -#ifndef MACHO +# ifndef MACHO { int stack_size_aligned_4k; @@ -1894,39 +2047,40 @@ static void install_clean_exception_handler (void) vm_protect (mach_task_self(),(int)b_stack_guard_page,4096,0,0); } } -#endif +# endif } +# ifndef MACHO_EXCEPTIONS { struct sigaltstack sa_stack; void *signal_stack; struct sigaction sa; -# ifdef MACHO +# ifdef MACHO signal_stack=(int*)malloc (MINSIGSTKSZ); -# else +# else signal_stack=(int*)NewPtr (8192); -# endif +# endif if (signal_stack!=NULL){ -# ifndef MACHO +# ifndef MACHO int *handler_trampoline; -# endif +# endif sa_stack.ss_sp=signal_stack; -# ifdef MACHO +# ifdef MACHO sa_stack.ss_size=MINSIGSTKSZ; -# else +# else sa_stack.ss_size=8192; -# endif +# endif sa_stack.ss_flags=0; sigaltstack (&sa_stack,NULL); -# ifdef MACHO +# ifdef MACHO sa.sa_handler=&clean_exception_handler; sigemptyset (&sa.sa_mask); sa.sa_flags=SA_ONSTACK;//SA_SIGINFO; -# else +# else handler_trampoline = (int*) NewPtr (24); if (handler_trampoline!=NULL){ int *handler_address,*toc_register; @@ -1934,13 +2088,13 @@ static void install_clean_exception_handler (void) handler_address=*(int**)&clean_exception_handler; toc_register=get_TOC(); -# define i_dai_i(i,rd,ra,si)((i<<26)|((rd)<<21)|((ra)<<16)|((unsigned short)(si))) -# define addis_i(rd,ra,si) i_dai_i (15,rd,ra,si) -# define addi_i(rd,ra,si) i_dai_i (14,rd,ra,si) -# define lis_i(rd,si) addis_i (rd,0,si) -# define bctr_i() ((19<<26)|(20<<21)|(528<<1)) -# define mtspr_i(spr,rs) ((31<<26)|((rs)<<21)|(spr<<16)|(467<<1)) -# define mtctr_i(rs) mtspr_i (9,rs) +# define i_dai_i(i,rd,ra,si)((i<<26)|((rd)<<21)|((ra)<<16)|((unsigned short)(si))) +# define addis_i(rd,ra,si) i_dai_i (15,rd,ra,si) +# define addi_i(rd,ra,si) i_dai_i (14,rd,ra,si) +# define lis_i(rd,si) addis_i (rd,0,si) +# define bctr_i() ((19<<26)|(20<<21)|(528<<1)) +# define mtspr_i(spr,rs) ((31<<26)|((rs)<<21)|(spr<<16)|(467<<1)) +# define mtctr_i(rs) mtspr_i (9,rs) handler_trampoline[0]=lis_i (6,((int)handler_address-(short)handler_address)>>16); handler_trampoline[1]=addi_i (6,6,(short)handler_address); @@ -1956,11 +2110,60 @@ static void install_clean_exception_handler (void) sa.sa_mask=0; sa.sa_flags=1; } -# endif +# endif sigaction (SIGSEGV,&sa,&old_SEGV_sa); sigaction (SIGBUS,&sa,&old_BUS_sa); } } +#else + { + mach_port_t my_mach_task; + pthread_attr_t attr; + pthread_t pthread; + + my_mach_task=mach_task_self(); + + if (mach_port_allocate (my_mach_task,MACH_PORT_RIGHT_RECEIVE,&exception_port)!=KERN_SUCCESS){ + /* printf ("mach_port_allocate failed\n"); */ + return; + } + + if (mach_port_insert_right (my_mach_task,exception_port,exception_port,MACH_MSG_TYPE_MAKE_SEND)!=KERN_SUCCESS){ + /* printf ("mach_port_insert_right failed\n"); */ + return; + } + + if (task_get_exception_ports (my_mach_task,EXC_MASK_BAD_ACCESS,old_exception_masks,&n_ports,old_exception_handlers,old_exception_behaviors,old_thread_state_flavors)!=KERN_SUCCESS){ + /* printf ("task_get_exception_ports failed\n"); */ + return; + } + + if (task_set_exception_ports (my_mach_task,EXC_MASK_BAD_ACCESS,exception_port,EXCEPTION_DEFAULT,MACHINE_THREAD_STATE)!=KERN_SUCCESS){ + /* printf ("task_get_exception_ports failed\n"); */ + return; + } + + if (pthread_attr_init (&attr)!=0){ + /* printf ("pthread_attr_init failed\n"); */ + return; + } + + if (pthread_attr_setdetachstate (&attr,PTHREAD_CREATE_DETACHED)!=0){ + /* printf ("pthread_attr_setdetach_state failed\n"); */ + return; + } + + if (pthread_create (&pthread,&attr,my_pthread,NULL)!=0){ + /* printf ("pthread_create failed\n"); */ + return; + } + + if (pthread_attr_destroy (&attr)!=0){ + /* printf ("pthread_attr_destroy failed\n"); */ + return; + } + } +# endif } #endif @@ -1992,7 +2195,10 @@ int main (void) char *s; s=argv[i]; - if (s[0]=='-' && s[1]=='p' && s[2]=='s' && s[3]=='n'){ + if (s[0]=='-' && + ((s[1]=='p' && s[2]=='s' && s[3]=='n') || + (s[1]=='s' && s[2]=='t' && s[3]=='d' && s[4]=='w' && s[5]=='i' && s[6]=='n' && s[7]=='\0') ) + ){ use_stdio=0; break; } -- cgit v1.2.3