// Signals end-to-end regression for GNO: install a SIGALRM handler via our // signal() (which routes the kernel callback through __sigTrampoline), arm a // 1-second alarm, and pause(). The kernel delivers SIGALRM through the // trampoline, which adapts the ORCA/C callee-pops frame to our arg0-in-A // handler; the handler flips a flag + drops a marker, pause() returns (EINTR), // and main verifies the handler ran and control resumed cleanly (proving the // trampoline's ORCA callee-pop return kept the kernel's context-restore stack // intact). // // Bank-2 absolute uint16 markers (DBR-independent), gnoHeapProbe convention: // 0x025000 C0DE reached end (pause returned; no hang/crash) // 0x025010 C41D the SIGALRM handler actually executed // 0x025012 0001 handler-ran flag observed after pause (0xDEAD if not) #include #include #include #define M(a) (*(volatile uint16_t *)(a)) static volatile uint16_t rang; static void onAlarm(int sig) { (void)sig; rang = 1; M(0x025010UL) = 0xC41D; // handler executed via the trampoline } int main(void) { M(0x025000UL) = 0x0000; M(0x025010UL) = 0x0000; M(0x025012UL) = 0x0000; rang = 0; signal(SIGALRM, onAlarm); // install through __sigTrampoline alarm(1); // fire SIGALRM in ~1 second pause(); // block until the signal is delivered M(0x025012UL) = rang ? 0x0001 : 0xDEAD; M(0x025000UL) = 0xC0DE; // reached end (returned cleanly) for (volatile unsigned long j = 0; j < 300000UL; j++) { } return 0; }