// 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 <stdint.h>
#include <signal.h>
#include <unistd.h>

#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;
}
