Linux passes the arguments in registers, but our compiler expects arguments on the stack. Signal handlers got garbage instead of the signal number. Some handlers, like the one in lang/m2/libm2/sigtrp.c, need the correct signal number. I write a "bridge" in PowerPC assembly that moves the arguments to the stack. I put the bridge in sigaction(), so I provide a signal() that calls sigaction(). I remove the *.c glob or wildcard from build.lua, so linuxppc only compiles its own signal.c, not the other signal.c for linux386 and linux68k. My bridge uses sigprocmask(), so I also add sigprocmask(). Because linux386 and linux68k use globs, they also get sigprocmask(). I sync the header files so all three Linux platforms declare execve(), sigprocmask(), and unlink(), but not remove(), because we have remove() in <stdio.h>. I am using sigaction.s to test some features that we recently added to our PowerPC assembler. These are the "hi16[...]" and "lo16[...]" syntax, and also the extended names like "beq", "cmpwi", "li", "subi".
		
			
				
	
	
		
			19 lines
		
	
	
	
		
			449 B
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			19 lines
		
	
	
	
		
			449 B
		
	
	
	
		
			C
		
	
	
	
	
	
#include <signal.h>
 | 
						|
 | 
						|
/*
 | 
						|
 * Uses our bridge in sigaction.s when calling the signal handler.
 | 
						|
 * Mimics Linux __NR_signal by using SA_NODEFER | SA_RESETHAND.
 | 
						|
 */
 | 
						|
sighandler_t signal(int signum, sighandler_t handler) {
 | 
						|
	struct sigaction new, old;
 | 
						|
	int i;
 | 
						|
 | 
						|
	new.sa_handler = handler;
 | 
						|
	new.sa_mask = 0; /* empty set */
 | 
						|
	new.sa_flags = SA_NODEFER | SA_RESETHAND;
 | 
						|
 | 
						|
	i = sigaction(signum, &new, &old);
 | 
						|
	if (i < 0)
 | 
						|
		return SIG_ERR;
 | 
						|
	return old.sa_handler;
 | 
						|
}
 |