43 lines
1.6 KiB
C
43 lines
1.6 KiB
C
// 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;
|
|
}
|