diff --git a/c/signal/README.md b/c/signal/README.md new file mode 100644 index 00000000..c262c316 --- /dev/null +++ b/c/signal/README.md @@ -0,0 +1,25 @@ +# Native signal bindings + +The macOS arm64 and Linux amd64/arm64 bindings are classified from a unified libc generation using unmodified llcppg commit `da227ff4aaf07718d7ec0dea62e23dab03ac57fb`. The header baselines are macOS 14.0 and Bootlin stable 2017.05 with glibc 2.24. Other targets keep the existing implementation. + +| Target | Build constraint | Direct Go dependencies | +| --- | --- | --- | +| macOS arm64 | `darwin && arm64 && !ios` | `c`, `unsafe` | +| Linux amd64 | `linux && amd64 && !android` | `c`, `c/time`, `unsafe` | +| Linux arm64 | `linux && arm64 && !android` | `c`, `c/time`, `unsafe` | + +`Signal(sig c.Int, handler SignalHandler) c.Int` retains its existing contract: it installs the handler through `Sigaction` and returns that call's status. Its implementation uses the generated `SigactionT` and union accessors. `NativeSignal` binds C `signal` and returns the previous handler, so it remains a distinct API rather than replacing `Signal`. The generated `Kill` declaration keeps its established public name. No existing public function signature changes in this update. + +Native signal records and their field accessors retain their original sizes, alignments and offsets. The previously approved opaque `c.Pointer` for Linux sigevent's optional pthread attributes avoids a package dependency cycle. Necessary implementation types and generated anonymous union storage remain present; their names do not introduce private C runtime entry points. + +Private C implementation entry points are excluded: macOS `__sigbits` and its generated C wrapper, and Linux `__sigismember`, `__sigaddset`, `__sigdelset`, `__sysv_signal`, `__libc_current_sigrtmin` and `__libc_current_sigrtmax`. The private macOS wrapper source and its `LLGoFiles` metadata are removed. Linux also excludes `SysSiglist` with explicit approval: the old headers declare `sys_siglist`, but current glibc retains only versioned compatibility exports and cannot resolve an ordinary reference. macOS keeps `SysSiglist` and `SysSigname`. Legacy public C functions retain their native behavior; Linux amd64 `Sigreturn` is a glibc stub and has link/prototype coverage. + +Each retained C function has a live symbol-address check and a prototype check against facts independently compiled from the original headers. Types, fields, constants, native globals and every generated union accessor are checked as well. The source inventory test rejects missing public symbol coverage. Go storage records whose sole field is `_xgo_union` are classified as C unions; their original size and alignment checks still apply. + +Linux `TimerCreate` uses a compile-time function-signature assignment and per-slot ABI checks. Its link-address and complete timer lifecycle tests remain enabled. This avoids reflecting the full signature, which currently requires missing `c/time` method wrappers while that dependency uses `LLGoPackage="decl"`. The dependency and compiler are unchanged; this test accommodation does not repair that reflection limitation. + +Runtime tests exercise empty/fill/add/delete/member signal-set operations, guarded `sigaction` output, handler installation and restoration, real delivery with `Raise`, and `Kill(self, 0)`. Linux additionally exercises sigevent layout and a non-notifying timer's create/query/disarm/delete lifecycle. Handler callbacks only store the received signal number and do not allocate. These tests run with GC and `nogc` on all three targets. + +Validation composes the root `c` files from PR #45 at `99ddac92c7335a53a1c996174e1753bcd72c5050` and `c/time` from PR #51 at `855f0c294499b32a0d3380d1d608592255155e89`. Merge those prerequisites first; this PR changes only `c/signal`. Tests use LLGo v1.0.8 (`c171abfa130108bc6451e01fcf15a8a3474eb0a7`), with LLVM 22 and LLD 23.1.3 for native macOS linking. The header baselines do not establish a minimum supported executable runtime version. + +`llcppg.cfg` contains only the prepared-header directory for local dependency discovery; it is not a standalone generation recipe. Actual generation uses the unified libc inputs followed by classification. `llcppg.pub` describes the classified public C type mappings. Inputs, scripts and header caches remain local and are not included in this PR. diff --git a/c/signal/libc_darwin_arm64.go b/c/signal/libc_darwin_arm64.go new file mode 100644 index 00000000..9af90a76 --- /dev/null +++ b/c/signal/libc_darwin_arm64.go @@ -0,0 +1,464 @@ +//go:build darwin && arm64 && !ios + +// Code generated by llcppg; DO NOT EDIT. +// Classified from the common libc binding. + +package signal + +import ( + "github.com/goplus/lib/c" + "unsafe" +) + +// llgo:type C +type llcppgCallback17 = func(_llcppg_param1 c.Int) + +// llgo:type C +type llcppgCallback16 = func(_llcppg_param1 c.Int) + +//go:linkname SysSigname C.sys_signame +var SysSigname [32]*c.Char + +//go:linkname SysSiglist C.sys_siglist +var SysSiglist [32]*c.Char + +//go:linkname Raise C.raise +func Raise(_llcppg_param1 c.Int) c.Int + +//go:linkname BsdSignal C.bsd_signal +func BsdSignal(_llcppg_param1 c.Int, _llcppg_param2 llcppgCallback17) func(_llcppg_param1 c.Int) + +//go:linkname Kill C.kill +func Kill(_llcppg_param1 c.Int, _llcppg_param2 c.Int) c.Int + +//go:linkname Killpg C.killpg +func Killpg(_llcppg_param1 c.Int, _llcppg_param2 c.Int) c.Int + +//go:linkname Sigaction C.sigaction +func Sigaction(_llcppg_param1 c.Int, _llcppg_param2 *SigactionT, _llcppg_param3 *SigactionT) c.Int + +//go:linkname Sigaddset C.sigaddset +func Sigaddset(_llcppg_param1 *c.Uint, _llcppg_param2 c.Int) c.Int + +// llgo:link (*StackT).Sigaltstack C.sigaltstack +func (self *StackT) Sigaltstack(_llcppg_param2 *StackT) c.Int { + return 0 +} + +//go:linkname Sigdelset C.sigdelset +func Sigdelset(_llcppg_param1 *c.Uint, _llcppg_param2 c.Int) c.Int + +//go:linkname Sigemptyset C.sigemptyset +func Sigemptyset(_llcppg_param1 *c.Uint) c.Int + +//go:linkname Sigfillset C.sigfillset +func Sigfillset(_llcppg_param1 *c.Uint) c.Int + +//go:linkname Sighold C.sighold +func Sighold(_llcppg_param1 c.Int) c.Int + +//go:linkname Sigignore C.sigignore +func Sigignore(_llcppg_param1 c.Int) c.Int + +//go:linkname Siginterrupt C.siginterrupt +func Siginterrupt(_llcppg_param1 c.Int, _llcppg_param2 c.Int) c.Int + +//go:linkname Sigismember C.sigismember +func Sigismember(_llcppg_param1 *c.Uint, _llcppg_param2 c.Int) c.Int + +//go:linkname Sigpause C.sigpause +func Sigpause(_llcppg_param1 c.Int) c.Int + +//go:linkname Sigpending C.sigpending +func Sigpending(_llcppg_param1 *c.Uint) c.Int + +//go:linkname Sigprocmask C.sigprocmask +func Sigprocmask(_llcppg_param1 c.Int, _llcppg_param2 *c.Uint, _llcppg_param3 *c.Uint) c.Int + +//go:linkname Sigrelse C.sigrelse +func Sigrelse(_llcppg_param1 c.Int) c.Int + +//go:linkname Sigset C.sigset +func Sigset(_llcppg_param1 c.Int, _llcppg_param2 llcppgCallback16) func(_llcppg_param1 c.Int) + +//go:linkname Sigsuspend C.sigsuspend +func Sigsuspend(_llcppg_param1 *c.Uint) c.Int + +//go:linkname Sigwait C.sigwait +func Sigwait(_llcppg_param1 *c.Uint, _llcppg_param2 *c.Int) c.Int + +//go:linkname Psignal C.psignal +func Psignal(_llcppg_param1 c.Int, _llcppg_param2 *c.Char) + +//go:linkname Sigblock C.sigblock +func Sigblock(_llcppg_param1 c.Int) c.Int + +//go:linkname Sigsetmask C.sigsetmask +func Sigsetmask(_llcppg_param1 c.Int) c.Int + +//go:linkname Sigvec C.sigvec +func Sigvec(_llcppg_param1 c.Int, _llcppg_param2 *SigvecT, _llcppg_param3 *SigvecT) c.Int + +type X__DarwinSigaltstack struct { + SsSp unsafe.Pointer + SsSize c.Ulong + SsFlags c.Int +} + +// [???] signal stack +type StackT = X__DarwinSigaltstack + +const NSIG = 32 + +const ( + // hangup + SIGHUP = 1 + // interrupt + SIGINT = 2 + // quit + SIGQUIT = 3 + // illegal instruction (not reset when caught) + SIGILL = 4 + // trace trap (not reset when caught) + SIGTRAP = 5 + // abort() + SIGABRT = 6 +) + +const ( + // compatibility + SIGIOT = 6 + // EMT instruction + SIGEMT = 7 +) + +const ( + // floating point exception + SIGFPE = 8 + // kill (cannot be caught or ignored) + SIGKILL = 9 + // bus error + SIGBUS = 10 + // segmentation violation + SIGSEGV = 11 + // bad argument to system call + SIGSYS = 12 + // write on a pipe with no one to read it + SIGPIPE = 13 + // alarm clock + SIGALRM = 14 + // software termination signal from kill + SIGTERM = 15 + // urgent condition on IO channel + SIGURG = 16 + // sendable stop signal not from tty + SIGSTOP = 17 + // stop signal from tty + SIGTSTP = 18 + // continue a stopped process + SIGCONT = 19 + // to parent on child stop or exit + SIGCHLD = 20 + // to readers pgrp upon background tty read + SIGTTIN = 21 + // like TTIN for output if (tp->t_local<OSTOP) + SIGTTOU = 22 +) + +// input/output possible signal +const SIGIO = 23 + +const ( + // exceeded CPU time limit + SIGXCPU = 24 + // exceeded file size limit + SIGXFSZ = 25 + // virtual time alarm + SIGVTALRM = 26 + // profiling time alarm + SIGPROF = 27 +) + +const ( + // window size changes + SIGWINCH = 28 + // information request + SIGINFO = 29 +) + +const ( + // user defined signal 1 + SIGUSR1 = 30 + // user defined signal 2 + SIGUSR2 = 31 +) + +const ( + // No async notification + SIGEV_NONE = 0 + // aio - completion notification + SIGEV_SIGNAL = 1 + // [NOTIMP] [RTS] call notification function + SIGEV_THREAD = 3 +) + +// if only I knew... +const ILL_NOOP = 0 + +const ( + // [XSI] illegal opcode + ILL_ILLOPC = 1 + // [XSI] illegal trap + ILL_ILLTRP = 2 + // [XSI] privileged opcode + ILL_PRVOPC = 3 + // [XSI] illegal operand -NOTIMP + ILL_ILLOPN = 4 + // [XSI] illegal addressing mode -NOTIMP + ILL_ILLADR = 5 + // [XSI] privileged register -NOTIMP + ILL_PRVREG = 6 + // [XSI] coprocessor error -NOTIMP + ILL_COPROC = 7 + // [XSI] internal stack error -NOTIMP + ILL_BADSTK = 8 +) + +// if only I knew... +const FPE_NOOP = 0 + +const ( + // [XSI] floating point divide by zero + FPE_FLTDIV = 1 + // [XSI] floating point overflow + FPE_FLTOVF = 2 + // [XSI] floating point underflow + FPE_FLTUND = 3 + // [XSI] floating point inexact result + FPE_FLTRES = 4 + // [XSI] invalid floating point operation + FPE_FLTINV = 5 + // [XSI] subscript out of range -NOTIMP + FPE_FLTSUB = 6 + // [XSI] integer divide by zero + FPE_INTDIV = 7 + // [XSI] integer overflow + FPE_INTOVF = 8 +) + +// if only I knew... +const SEGV_NOOP = 0 + +const ( + // [XSI] address not mapped to object + SEGV_MAPERR = 1 + // [XSI] invalid permission for mapped object + SEGV_ACCERR = 2 +) + +// if only I knew... +const BUS_NOOP = 0 + +const ( + // [XSI] Invalid address alignment + BUS_ADRALN = 1 + // [XSI] Nonexistent physical address -NOTIMP + BUS_ADRERR = 2 + // [XSI] Object-specific HW error - NOTIMP + BUS_OBJERR = 3 +) + +// Codes for SIGTRAP +const ( + TRAP_BRKPT = 1 + // [XSI] Process trace trap -NOTIMP + TRAP_TRACE = 2 +) + +// if only I knew... +const CLD_NOOP = 0 + +const ( + // [XSI] child has exited + CLD_EXITED = 1 + // [XSI] terminated abnormally, no core file + CLD_KILLED = 2 + // [XSI] terminated abnormally, core file + CLD_DUMPED = 3 + // [XSI] traced child has trapped + CLD_TRAPPED = 4 + // [XSI] child has stopped + CLD_STOPPED = 5 + // [XSI] stopped child has continued + CLD_CONTINUED = 6 +) + +// Codes for SIGPOLL +const ( + POLL_IN = 1 + // [XSR] Output buffers available + POLL_OUT = 2 + // [XSR] Input message available + POLL_MSG = 3 + // [XSR] I/O error + POLL_ERR = 4 + // [XSR] High priority input available + POLL_PRI = 5 + // [XSR] Device disconnected + POLL_HUP = 6 +) + +const ( + // take signal on signal stack + SA_ONSTACK = 1 + // restart system on signal return + SA_RESTART = 2 + // reset to SIG_DFL when taking signal + SA_RESETHAND = 4 + // do not generate SIGCHLD on child stop + SA_NOCLDSTOP = 8 + // don't mask the signal we're delivering + SA_NODEFER = 16 + // don't keep zombies around + SA_NOCLDWAIT = 32 + // signal handler with SA_SIGINFO args + SA_SIGINFO = 64 +) + +// do not bounce off kernel's sigtramp +const SA_USERTRAMP = 256 + +// This will provide 64bit register set in a 32bit user address space +const SA_64REGSET = 512 + +// the following are the only bits we support from user space, the +// rest are for kernel use only. +const SA_USERSPACE_MASK = 127 + +// Flags for sigprocmask: +const ( + SIG_BLOCK = 1 + // unblock specified signal set + SIG_UNBLOCK = 2 + // set specified signal set + SIG_SETMASK = 3 +) + +// POSIX 1003.1b required values. +const ( + SI_USER = 65537 + // [CX] signal from sigqueue() + SI_QUEUE = 65538 + // [CX] timer expiration + SI_TIMER = 65539 + // [CX] aio request completion + SI_ASYNCIO = 65540 + // [CX] from message arrival on empty queue + SI_MESGQ = 65541 +) + +const ( + // take signal on signal stack + SS_ONSTACK = 1 + // disable taking signals on alternate stack + SS_DISABLE = 4 + // (32K)minimum allowable stack + MINSIGSTKSZ = 32768 + // (128K)recommended stack size + SIGSTKSZ = 131072 +) + +const ( + SV_ONSTACK = 1 + // same bit, opposite sense + SV_INTERRUPT = 2 + SV_RESETHAND = 4 + SV_NODEFER = 16 + SV_NOCLDSTOP = 8 + SV_SIGINFO = 64 +) + +type Sigval struct { + _xgo_union [1]uint64 +} + +type X__Siginfo struct { + SiSigno c.Int + SiErrno c.Int + SiCode c.Int + SiPid c.Int + SiUid c.Uint + SiStatus c.Int + SiAddr unsafe.Pointer + SiValue Sigval + SiBand c.Long + X__Pad [7]c.Ulong +} + +type X__SigactionU struct { + _xgo_union [1]uint64 +} + +// Signal vector "template" used in sigaction call. +type SigactionT struct { + X__SigactionU X__SigactionU + SaMask c.Uint + SaFlags c.Int +} + +type SigvecT struct { + SvHandler llcppgCallback19 + SvMask c.Int + SvFlags c.Int +} + +type SiginfoT = X__Siginfo + +// union for signal handlers +// +// llgo:type C +type llcppgCallback21 = func(_llcppg_param1 c.Int, _llcppg_param2 *X__Siginfo, _llcppg_param3 unsafe.Pointer) + +// llgo:type C +type llcppgCallback22 = func(_llcppg_param1 c.Int) + +// 4.3 compatibility: +// Signal vector "template" used in sigvec call. +// +// llgo:type C +type llcppgCallback19 = func(_llcppg_param1 c.Int) + +// llgo:type C +type llcppgCallback18 = func(_llcppg_param1 c.Int) + +func (p *Sigval) XGof_ref_sival_int() *c.Int { + return (*c.Int)(unsafe.Pointer(p)) +} + +func (p *Sigval) XGof_ref_sival_ptr() *unsafe.Pointer { + return (*unsafe.Pointer)(unsafe.Pointer(p)) +} + +func (p *X__SigactionU) XGof_ref___sa_handler() *llcppgCallback22 { + return (*llcppgCallback22)(unsafe.Pointer(p)) +} + +func (p *X__SigactionU) XGof_ref___sa_sigaction() *llcppgCallback21 { + return (*llcppgCallback21)(unsafe.Pointer(p)) +} + +//go:linkname NativeSignal C.signal +func NativeSignal(_llcppg_param1 c.Int, _llcppg_param2 llcppgCallback18) func(_llcppg_param1 c.Int) + +type SigsetT = c.Uint + +const LLGoPackage = "link" + +//llgo:type C +type SignalHandler func(c.Int) + +func Signal(sig c.Int, handler SignalHandler) c.Int { + var action SigactionT + *action.X__SigactionU.XGof_ref___sa_handler() = handler + return Sigaction(sig, &action, nil) +} diff --git a/c/signal/libc_linux_amd64.go b/c/signal/libc_linux_amd64.go new file mode 100644 index 00000000..ae674b93 --- /dev/null +++ b/c/signal/libc_linux_amd64.go @@ -0,0 +1,674 @@ +//go:build linux && amd64 && !android + +// Code generated by llcppg; DO NOT EDIT. +// Classified from the common libc binding. + +package signal + +import ( + "github.com/goplus/lib/c" + lltime "github.com/goplus/lib/c/time" + "unsafe" +) + +// Bits in `sa_flags'. +const ( + SA_NOCLDSTOP = 1 + // Don't create zombie on child death. + SA_NOCLDWAIT = 2 + // Invoke signal-catching function with + // three arguments instead of one. + SA_SIGINFO = 4 +) + +// Use signal stack by using `sa_restorer'. +const SA_ONSTACK = 134217728 + +const ( + // Restart syscall on signal return. + SA_RESTART = 268435456 + // Don't automatically block the signal when + // its handler is being executed. + SA_NODEFER = 1073741824 +) + +// Reset to SIG_DFL on entry to handler. +const SA_RESETHAND = 2147483648 + +// Historical no-op. +const SA_INTERRUPT = 536870912 + +// Some aliases for the SA_ constants. +const ( + SA_NOMASK = 1073741824 + SA_ONESHOT = 2147483648 + SA_STACK = 134217728 +) + +// Values for the HOW argument to `sigprocmask'. +const ( + SIG_BLOCK = 0 + // Unblock signals. + SIG_UNBLOCK = 1 + // Set the set of blocked signals. + SIG_SETMASK = 2 +) + +type SigactionT struct { + X__SigactionHandler _llcppg_anon_7 + SaMask SigsetT + SaFlags c.Int + SaRestorer llcppgCallback3 +} + +// Structure describing the action to be taken when a signal arrives. +// +// llgo:type C +type llcppgCallback3 = func() + +// llgo:type C +type llcppgCallback4 = func(_llcppg_param1 c.Int, _llcppg_param2 *SiginfoT, _llcppg_param3 unsafe.Pointer) + +type _llcppg_anon_7 struct { + _xgo_union [1]uint64 +} + +func (p *_llcppg_anon_7) XGof_ref_sa_handler() *X__SighandlerT { + return (*X__SighandlerT)(unsafe.Pointer(p)) +} + +func (p *_llcppg_anon_7) XGof_ref_sa_sigaction() *llcppgCallback4 { + return (*llcppgCallback4)(unsafe.Pointer(p)) +} + +type X_fpxreg struct { + Significand [4]uint16 + Exponent uint16 + Padding [3]uint16 +} + +type X_xmmreg struct { + Element [4]c.Uint +} + +type X_fpstate struct { + Cwd c.Uint16T + Swd c.Uint16T + Ftw c.Uint16T + Fop c.Uint16T + Rip c.Ulong + Rdp c.Ulong + Mxcsr c.Uint + MxcrMask c.Uint + X_st [8]X_fpxreg + X_xmm [16]X_xmmreg + Padding [24]c.Uint +} + +type Sigcontext struct { + R8 c.Ulong + R9 c.Ulong + R10 c.Ulong + R11 c.Ulong + R12 c.Ulong + R13 c.Ulong + R14 c.Ulong + R15 c.Ulong + Rdi c.Ulong + Rsi c.Ulong + Rbp c.Ulong + Rbx c.Ulong + Rdx c.Ulong + Rax c.Ulong + Rcx c.Ulong + Rsp c.Ulong + Rip c.Ulong + Eflags c.Ulong + Cs uint16 + Gs uint16 + Fs uint16 + X__Pad0 uint16 + Err c.Ulong + Trapno c.Ulong + Oldmask c.Ulong + Cr2 c.Ulong + _llcppg_anon_8 + X__Reserved1 [8]c.Ulong +} + +type _llcppg_anon_8 struct { + _xgo_union [1]uint64 +} + +func (p *_llcppg_anon_8) XGof_ref_fpstate() **X_fpstate { + return (**X_fpstate)(unsafe.Pointer(p)) +} + +func (p *_llcppg_anon_8) XGof_ref___fpstate_word() *c.Ulong { + return (*c.Ulong)(unsafe.Pointer(p)) +} + +type Sigval struct { + _xgo_union [1]uint64 +} + +type SiginfoT struct { + SiSigno c.Int + SiErrno c.Int + SiCode c.Int + X_sifields _llcppg_anon_5 +} + +// Values for `si_code'. Positive values are reserved for kernel-generated +// signals. +const ( + SI_ASYNCNL = -60 + SI_TKILL = -6 + SI_SIGIO = -5 + SI_ASYNCIO = -4 + SI_MESGQ = -3 + SI_TIMER = -2 + SI_QUEUE = -1 + SI_USER = 0 + // Send by kernel. + SI_KERNEL = 128 +) + +// `si_code' values for SIGILL signal. +const ( + ILL_ILLOPC = 1 + ILL_ILLOPN = 2 + ILL_ILLADR = 3 + ILL_ILLTRP = 4 + ILL_PRVOPC = 5 + ILL_PRVREG = 6 + ILL_COPROC = 7 + // Internal stack error. + ILL_BADSTK = 8 +) + +// `si_code' values for SIGFPE signal. +const ( + FPE_INTDIV = 1 + FPE_INTOVF = 2 + FPE_FLTDIV = 3 + FPE_FLTOVF = 4 + FPE_FLTUND = 5 + FPE_FLTRES = 6 + FPE_FLTINV = 7 + // Subscript out of range. + FPE_FLTSUB = 8 +) + +// `si_code' values for SIGSEGV signal. +const ( + SEGV_MAPERR = 1 + // Invalid permissions for mapped object. + SEGV_ACCERR = 2 +) + +// `si_code' values for SIGBUS signal. +const ( + BUS_ADRALN = 1 + BUS_ADRERR = 2 + BUS_OBJERR = 3 + BUS_MCEERR_AR = 4 + // Hardware memory error: action optional. + BUS_MCEERR_AO = 5 +) + +// `si_code' values for SIGCHLD signal. +const ( + CLD_EXITED = 1 + CLD_KILLED = 2 + CLD_DUMPED = 3 + CLD_TRAPPED = 4 + CLD_STOPPED = 5 + // Stopped child has continued. + CLD_CONTINUED = 6 +) + +// `si_code' values for SIGPOLL signal. +const ( + POLL_IN = 1 + POLL_OUT = 2 + POLL_MSG = 3 + POLL_ERR = 4 + POLL_PRI = 5 + // Device disconnected. + POLL_HUP = 6 +) + +type Sigevent struct { + SigevValue SigvalT + SigevSigno c.Int + SigevNotify c.Int + X_sigevUn _llcppg_anon_6 +} + +// `sigev_notify' values. +const ( + SIGEV_SIGNAL = 0 + SIGEV_NONE = 1 + SIGEV_THREAD = 2 + // Send signal to specific thread. + SIGEV_THREAD_ID = 4 +) + +// Type for data associated with a signal. +type SigvalT = Sigval + +type _llcppg_anon_5 struct { + _xgo_union [14]uint64 +} + +// llgo:type C +type llcppgCallback5 = func(_llcppg_param1 SigvalT) + +type _llcppg_anon_6 struct { + _xgo_union [6]uint64 +} + +func (p *Sigval) XGof_ref_sival_int() *c.Int { + return (*c.Int)(unsafe.Pointer(p)) +} + +func (p *Sigval) XGof_ref_sival_ptr() *unsafe.Pointer { + return (*unsafe.Pointer)(unsafe.Pointer(p)) +} + +func (p *_llcppg_anon_5) XGof_ref__pad() *[28]c.Int { + return (*[28]c.Int)(unsafe.Pointer(p)) +} + +// kill(). +type _llcppg_anon_24 struct { + SiPid c.Int + SiUid c.Uint +} + +func (p *_llcppg_anon_5) XGof_ref__kill() *_llcppg_anon_24 { + return (*_llcppg_anon_24)(unsafe.Pointer(p)) +} + +// POSIX.1b timers. +type _llcppg_anon_25 struct { + SiTid c.Int + SiOverrun c.Int + SiSigval SigvalT +} + +func (p *_llcppg_anon_5) XGof_ref__timer() *_llcppg_anon_25 { + return (*_llcppg_anon_25)(unsafe.Pointer(p)) +} + +// POSIX.1b signals. +type _llcppg_anon_26 struct { + SiPid c.Int + SiUid c.Uint + SiSigval SigvalT +} + +func (p *_llcppg_anon_5) XGof_ref__rt() *_llcppg_anon_26 { + return (*_llcppg_anon_26)(unsafe.Pointer(p)) +} + +// SIGCHLD. +type _llcppg_anon_27 struct { + SiPid c.Int + SiUid c.Uint + SiStatus c.Int + SiUtime c.Long + SiStime c.Long +} + +func (p *_llcppg_anon_5) XGof_ref__sigchld() *_llcppg_anon_27 { + return (*_llcppg_anon_27)(unsafe.Pointer(p)) +} + +// SIGILL, SIGFPE, SIGSEGV, SIGBUS. +type _llcppg_anon_28 struct { + SiAddr unsafe.Pointer + SiAddrLsb int16 + SiAddrBnd _llcppg_anon_29 +} + +type _llcppg_anon_29 struct { + X_lower unsafe.Pointer + X_upper unsafe.Pointer +} + +func (p *_llcppg_anon_5) XGof_ref__sigfault() *_llcppg_anon_28 { + return (*_llcppg_anon_28)(unsafe.Pointer(p)) +} + +// SIGPOLL. +type _llcppg_anon_30 struct { + SiBand c.Long + SiFd c.Int +} + +func (p *_llcppg_anon_5) XGof_ref__sigpoll() *_llcppg_anon_30 { + return (*_llcppg_anon_30)(unsafe.Pointer(p)) +} + +// SIGSYS. +type _llcppg_anon_31 struct { + X_callAddr unsafe.Pointer + X_syscall c.Int + X_arch c.Uint +} + +func (p *_llcppg_anon_5) XGof_ref__sigsys() *_llcppg_anon_31 { + return (*_llcppg_anon_31)(unsafe.Pointer(p)) +} + +func (p *_llcppg_anon_6) XGof_ref__pad() *[12]c.Int { + return (*[12]c.Int)(unsafe.Pointer(p)) +} + +func (p *_llcppg_anon_6) XGof_ref__tid() *c.Int { + return (*c.Int)(unsafe.Pointer(p)) +} + +type _llcppg_anon_32 struct { + X_function llcppgCallback5 + X_attribute c.Pointer +} + +func (p *_llcppg_anon_6) XGof_ref__sigev_thread() *_llcppg_anon_32 { + return (*_llcppg_anon_32)(unsafe.Pointer(p)) +} + +// Signals. +const ( + SIGHUP = 1 + // Interrupt (ANSI). + SIGINT = 2 + // Quit (POSIX). + SIGQUIT = 3 + // Illegal instruction (ANSI). + SIGILL = 4 + // Trace trap (POSIX). + SIGTRAP = 5 + // Abort (ANSI). + SIGABRT = 6 + // IOT trap (4.2 BSD). + SIGIOT = 6 + // BUS error (4.2 BSD). + SIGBUS = 7 + // Floating-point exception (ANSI). + SIGFPE = 8 + // Kill, unblockable (POSIX). + SIGKILL = 9 + // User-defined signal 1 (POSIX). + SIGUSR1 = 10 + // Segmentation violation (ANSI). + SIGSEGV = 11 + // User-defined signal 2 (POSIX). + SIGUSR2 = 12 + // Broken pipe (POSIX). + SIGPIPE = 13 + // Alarm clock (POSIX). + SIGALRM = 14 + // Termination (ANSI). + SIGTERM = 15 + // Stack fault. + SIGSTKFLT = 16 + // Child status has changed (POSIX). + SIGCHLD = 17 + // Continue (POSIX). + SIGCONT = 18 + // Stop, unblockable (POSIX). + SIGSTOP = 19 + // Keyboard stop (POSIX). + SIGTSTP = 20 + // Background read from tty (POSIX). + SIGTTIN = 21 + // Background write to tty (POSIX). + SIGTTOU = 22 + // Urgent condition on socket (4.2 BSD). + SIGURG = 23 + // CPU limit exceeded (4.2 BSD). + SIGXCPU = 24 + // File size limit exceeded (4.2 BSD). + SIGXFSZ = 25 + // Virtual alarm clock (4.2 BSD). + SIGVTALRM = 26 + // Profiling alarm clock (4.2 BSD). + SIGPROF = 27 + // Window size change (4.3 BSD, Sun). + SIGWINCH = 28 + // I/O now possible (4.2 BSD). + SIGIO = 29 + // Power failure restart (System V). + SIGPWR = 30 + // Bad system call. + SIGSYS = 31 + SIGUNUSED = 31 +) + +// Structure describing a signal stack (obsolete). +type SigstackT struct { + SsSp unsafe.Pointer + SsOnstack c.Int +} + +// Alternate, preferred interface. +type Sigaltstack struct { + SsSp unsafe.Pointer + SsFlags c.Int + SsSize c.SizeT +} + +const NSIG = 65 + +// Type of a signal handler. +// +// llgo:type C +type X__SighandlerT = func(_llcppg_param1 c.Int) + +//go:linkname NativeSignal C.signal +func NativeSignal(__sig c.Int, __handler X__SighandlerT) X__SighandlerT + +//go:linkname Kill C.kill +func Kill(__pid c.Int, __sig c.Int) c.Int + +// Send SIG to all processes in process group PGRP. +// If PGRP is zero, send SIG to all processes in +// the current process's process group. +// +//go:linkname Killpg C.killpg +func Killpg(__pgrp c.Int, __sig c.Int) c.Int + +// Raise signal SIG, i.e., send SIG to yourself. +// +//go:linkname Raise C.raise +func Raise(__sig c.Int) c.Int + +// SVID names for the same things. +// +//go:linkname Ssignal C.ssignal +func Ssignal(__sig c.Int, __handler X__SighandlerT) X__SighandlerT + +//go:linkname Gsignal C.gsignal +func Gsignal(__sig c.Int) c.Int + +// Print a message describing the meaning of the given signal number. +// +//go:linkname Psignal C.psignal +func Psignal(__sig c.Int, __s *c.Char) + +// Print a message describing the meaning of the given signal information. +// +// llgo:link (*SiginfoT).Psiginfo C.psiginfo +func (self *SiginfoT) Psiginfo(__s *c.Char) { +} + +// Block signals in MASK, returning the old mask. +// +//go:linkname Sigblock C.sigblock +func Sigblock(__mask c.Int) c.Int + +// Set the mask of blocked signals to MASK, returning the old mask. +// +//go:linkname Sigsetmask C.sigsetmask +func Sigsetmask(__mask c.Int) c.Int + +// Return currently selected signal mask. +// +//go:linkname Siggetmask C.siggetmask +func Siggetmask() c.Int + +// Clear all signals from SET. +// +// llgo:link (*SigsetT).Sigemptyset C.sigemptyset +func (self *SigsetT) Sigemptyset() c.Int { + return 0 +} + +// Set all signals in SET. +// +// llgo:link (*SigsetT).Sigfillset C.sigfillset +func (self *SigsetT) Sigfillset() c.Int { + return 0 +} + +// Add SIGNO to SET. +// +// llgo:link (*SigsetT).Sigaddset C.sigaddset +func (self *SigsetT) Sigaddset(__signo c.Int) c.Int { + return 0 +} + +// Remove SIGNO from SET. +// +// llgo:link (*SigsetT).Sigdelset C.sigdelset +func (self *SigsetT) Sigdelset(__signo c.Int) c.Int { + return 0 +} + +// Return 1 if SIGNO is in SET, 0 if not. +// +// llgo:link (*SigsetT).Sigismember C.sigismember +func (self *SigsetT) Sigismember(__signo c.Int) c.Int { + return 0 +} + +// Get and/or change the set of blocked signals. +// +//go:linkname Sigprocmask C.sigprocmask +func Sigprocmask(__how c.Int, __set *SigsetT, __oset *SigsetT) c.Int + +// Change the set of blocked signals to SET, +// wait until a signal arrives, and restore the set of blocked signals. +// +// This function is a cancellation point and therefore not marked with +// __THROW. +// +// llgo:link (*SigsetT).Sigsuspend C.sigsuspend +func (self *SigsetT) Sigsuspend() c.Int { + return 0 +} + +// Get and/or set the action for signal SIG. +// +//go:linkname Sigaction C.sigaction +func Sigaction(__sig c.Int, __act *SigactionT, __oact *SigactionT) c.Int + +// Put in SET all signals that are blocked and waiting to be delivered. +// +// llgo:link (*SigsetT).Sigpending C.sigpending +func (self *SigsetT) Sigpending() c.Int { + return 0 +} + +// Select any of pending signals from SET or wait for any to arrive. +// +// This function is a cancellation point and therefore not marked with +// __THROW. +// +// llgo:link (*SigsetT).Sigwait C.sigwait +func (self *SigsetT) Sigwait(__sig *c.Int) c.Int { + return 0 +} + +// Select any of pending signals from SET and place information in INFO. +// +// This function is a cancellation point and therefore not marked with +// __THROW. +// +// llgo:link (*SigsetT).Sigwaitinfo C.sigwaitinfo +func (self *SigsetT) Sigwaitinfo(__info *SiginfoT) c.Int { + return 0 +} + +// Select any of pending signals from SET and place information in INFO. +// Wait the time specified by TIMEOUT if no signal is pending. +// +// This function is a cancellation point and therefore not marked with +// __THROW. +// +// llgo:link (*SigsetT).Sigtimedwait C.sigtimedwait +func (self *SigsetT) Sigtimedwait(__info *SiginfoT, __timeout *lltime.Timespec) c.Int { + return 0 +} + +// Send signal SIG to the process PID. Associate data in VAL with the +// signal. +// +//go:linkname Sigqueue C.sigqueue +func Sigqueue(__pid c.Int, __sig c.Int, __val Sigval) c.Int + +// Restore the state saved in SCP. +// +// llgo:link (*Sigcontext).Sigreturn C.sigreturn +func (self *Sigcontext) Sigreturn() c.Int { + return 0 +} + +// If INTERRUPT is nonzero, make signal SIG interrupt system calls +// (causing them to fail with EINTR); if INTERRUPT is zero, make system +// calls be restarted after signal SIG. +// +//go:linkname Siginterrupt C.siginterrupt +func Siginterrupt(__sig c.Int, __interrupt c.Int) c.Int + +// Run signals handlers on the stack specified by SS (if not NULL). +// If OSS is not NULL, it is filled in with the old signal stack status. +// This interface is obsolete and on many platform not implemented. +// +//go:linkname Sigstack C.sigstack +func Sigstack(__ss *SigstackT, __oss *SigstackT) c.Int + +// Alternate signal handler stack interface. +// This interface should always be preferred over `sigstack'. +// +// llgo:link (*Sigaltstack).Sigaltstack C.sigaltstack +func (self *Sigaltstack) Sigaltstack(__oss *Sigaltstack) c.Int { + return 0 +} + +// Create new per-process timer using CLOCK_ID. +// +//go:linkname TimerCreate C.timer_create +func TimerCreate(__clock_id lltime.ClockidT, __evp *Sigevent, __timerid *lltime.TimerT) c.Int + +type SigsetT = X__SigsetT + +type X__SigsetT struct { + X__Val [16]c.Ulong +} + +const LLGoPackage = "link" + +//llgo:type C +type SignalHandler func(c.Int) + +func Signal(sig c.Int, handler SignalHandler) c.Int { + var action SigactionT + *action.X__SigactionHandler.XGof_ref_sa_handler() = handler + return Sigaction(sig, &action, nil) +} + +type SigeventT = Sigevent diff --git a/c/signal/libc_linux_arm64.go b/c/signal/libc_linux_arm64.go new file mode 100644 index 00000000..70c23330 --- /dev/null +++ b/c/signal/libc_linux_arm64.go @@ -0,0 +1,594 @@ +//go:build linux && arm64 && !android + +// Code generated by llcppg; DO NOT EDIT. +// Classified from the common libc binding. + +package signal + +import ( + "github.com/goplus/lib/c" + lltime "github.com/goplus/lib/c/time" + "unsafe" +) + +// Bits in `sa_flags'. +const ( + SA_NOCLDSTOP = 1 + // Don't create zombie on child death. + SA_NOCLDWAIT = 2 + // Invoke signal-catching function with + // three arguments instead of one. + SA_SIGINFO = 4 +) + +// Use signal stack by using `sa_restorer'. +const SA_ONSTACK = 134217728 + +const ( + // Restart syscall on signal return. + SA_RESTART = 268435456 + // Don't automatically block the signal when + // its handler is being executed. + SA_NODEFER = 1073741824 +) + +// Reset to SIG_DFL on entry to handler. +const SA_RESETHAND = 2147483648 + +// Historical no-op. +const SA_INTERRUPT = 536870912 + +// Some aliases for the SA_ constants. +const ( + SA_NOMASK = 1073741824 + SA_ONESHOT = 2147483648 + SA_STACK = 134217728 +) + +// Values for the HOW argument to `sigprocmask'. +const ( + SIG_BLOCK = 0 + // Unblock signals. + SIG_UNBLOCK = 1 + // Set the set of blocked signals. + SIG_SETMASK = 2 +) + +type SigactionT struct { + X__SigactionHandler _llcppg_anon_7 + SaMask SigsetT + SaFlags c.Int + SaRestorer llcppgCallback3 +} + +// Structure describing the action to be taken when a signal arrives. +// +// llgo:type C +type llcppgCallback3 = func() + +// llgo:type C +type llcppgCallback4 = func(_llcppg_param1 c.Int, _llcppg_param2 *SiginfoT, _llcppg_param3 unsafe.Pointer) + +type _llcppg_anon_7 struct { + _xgo_union [1]uint64 +} + +func (p *_llcppg_anon_7) XGof_ref_sa_handler() *X__SighandlerT { + return (*X__SighandlerT)(unsafe.Pointer(p)) +} + +func (p *_llcppg_anon_7) XGof_ref_sa_sigaction() *llcppgCallback4 { + return (*llcppgCallback4)(unsafe.Pointer(p)) +} + +type Sigval struct { + _xgo_union [1]uint64 +} + +type SiginfoT struct { + SiSigno c.Int + SiErrno c.Int + SiCode c.Int + X_sifields _llcppg_anon_5 +} + +// Values for `si_code'. Positive values are reserved for kernel-generated +// signals. +const ( + SI_ASYNCNL = -60 + SI_TKILL = -6 + SI_SIGIO = -5 + SI_ASYNCIO = -4 + SI_MESGQ = -3 + SI_TIMER = -2 + SI_QUEUE = -1 + SI_USER = 0 + // Send by kernel. + SI_KERNEL = 128 +) + +// `si_code' values for SIGILL signal. +const ( + ILL_ILLOPC = 1 + ILL_ILLOPN = 2 + ILL_ILLADR = 3 + ILL_ILLTRP = 4 + ILL_PRVOPC = 5 + ILL_PRVREG = 6 + ILL_COPROC = 7 + // Internal stack error. + ILL_BADSTK = 8 +) + +// `si_code' values for SIGFPE signal. +const ( + FPE_INTDIV = 1 + FPE_INTOVF = 2 + FPE_FLTDIV = 3 + FPE_FLTOVF = 4 + FPE_FLTUND = 5 + FPE_FLTRES = 6 + FPE_FLTINV = 7 + // Subscript out of range. + FPE_FLTSUB = 8 +) + +// `si_code' values for SIGSEGV signal. +const ( + SEGV_MAPERR = 1 + // Invalid permissions for mapped object. + SEGV_ACCERR = 2 +) + +// `si_code' values for SIGBUS signal. +const ( + BUS_ADRALN = 1 + BUS_ADRERR = 2 + BUS_OBJERR = 3 + BUS_MCEERR_AR = 4 + // Hardware memory error: action optional. + BUS_MCEERR_AO = 5 +) + +// `si_code' values for SIGCHLD signal. +const ( + CLD_EXITED = 1 + CLD_KILLED = 2 + CLD_DUMPED = 3 + CLD_TRAPPED = 4 + CLD_STOPPED = 5 + // Stopped child has continued. + CLD_CONTINUED = 6 +) + +// `si_code' values for SIGPOLL signal. +const ( + POLL_IN = 1 + POLL_OUT = 2 + POLL_MSG = 3 + POLL_ERR = 4 + POLL_PRI = 5 + // Device disconnected. + POLL_HUP = 6 +) + +type Sigevent struct { + SigevValue SigvalT + SigevSigno c.Int + SigevNotify c.Int + X_sigevUn _llcppg_anon_6 +} + +// `sigev_notify' values. +const ( + SIGEV_SIGNAL = 0 + SIGEV_NONE = 1 + SIGEV_THREAD = 2 + // Send signal to specific thread. + SIGEV_THREAD_ID = 4 +) + +// Type for data associated with a signal. +type SigvalT = Sigval + +type _llcppg_anon_5 struct { + _xgo_union [14]uint64 +} + +// llgo:type C +type llcppgCallback5 = func(_llcppg_param1 SigvalT) + +type _llcppg_anon_6 struct { + _xgo_union [6]uint64 +} + +func (p *Sigval) XGof_ref_sival_int() *c.Int { + return (*c.Int)(unsafe.Pointer(p)) +} + +func (p *Sigval) XGof_ref_sival_ptr() *unsafe.Pointer { + return (*unsafe.Pointer)(unsafe.Pointer(p)) +} + +func (p *_llcppg_anon_5) XGof_ref__pad() *[28]c.Int { + return (*[28]c.Int)(unsafe.Pointer(p)) +} + +// kill(). +type _llcppg_anon_23 struct { + SiPid c.Int + SiUid c.Uint +} + +func (p *_llcppg_anon_5) XGof_ref__kill() *_llcppg_anon_23 { + return (*_llcppg_anon_23)(unsafe.Pointer(p)) +} + +// POSIX.1b timers. +type _llcppg_anon_24 struct { + SiTid c.Int + SiOverrun c.Int + SiSigval SigvalT +} + +func (p *_llcppg_anon_5) XGof_ref__timer() *_llcppg_anon_24 { + return (*_llcppg_anon_24)(unsafe.Pointer(p)) +} + +// POSIX.1b signals. +type _llcppg_anon_25 struct { + SiPid c.Int + SiUid c.Uint + SiSigval SigvalT +} + +func (p *_llcppg_anon_5) XGof_ref__rt() *_llcppg_anon_25 { + return (*_llcppg_anon_25)(unsafe.Pointer(p)) +} + +// SIGCHLD. +type _llcppg_anon_26 struct { + SiPid c.Int + SiUid c.Uint + SiStatus c.Int + SiUtime c.Long + SiStime c.Long +} + +func (p *_llcppg_anon_5) XGof_ref__sigchld() *_llcppg_anon_26 { + return (*_llcppg_anon_26)(unsafe.Pointer(p)) +} + +// SIGILL, SIGFPE, SIGSEGV, SIGBUS. +type _llcppg_anon_27 struct { + SiAddr unsafe.Pointer + SiAddrLsb int16 +} + +func (p *_llcppg_anon_5) XGof_ref__sigfault() *_llcppg_anon_27 { + return (*_llcppg_anon_27)(unsafe.Pointer(p)) +} + +// SIGPOLL. +type _llcppg_anon_28 struct { + SiBand c.Long + SiFd c.Int +} + +func (p *_llcppg_anon_5) XGof_ref__sigpoll() *_llcppg_anon_28 { + return (*_llcppg_anon_28)(unsafe.Pointer(p)) +} + +// SIGSYS. +type _llcppg_anon_29 struct { + X_callAddr unsafe.Pointer + X_syscall c.Int + X_arch c.Uint +} + +func (p *_llcppg_anon_5) XGof_ref__sigsys() *_llcppg_anon_29 { + return (*_llcppg_anon_29)(unsafe.Pointer(p)) +} + +func (p *_llcppg_anon_6) XGof_ref__pad() *[12]c.Int { + return (*[12]c.Int)(unsafe.Pointer(p)) +} + +func (p *_llcppg_anon_6) XGof_ref__tid() *c.Int { + return (*c.Int)(unsafe.Pointer(p)) +} + +type _llcppg_anon_30 struct { + X_function llcppgCallback5 + X_attribute c.Pointer +} + +func (p *_llcppg_anon_6) XGof_ref__sigev_thread() *_llcppg_anon_30 { + return (*_llcppg_anon_30)(unsafe.Pointer(p)) +} + +// Signals. +const ( + SIGHUP = 1 + // Interrupt (ANSI). + SIGINT = 2 + // Quit (POSIX). + SIGQUIT = 3 + // Illegal instruction (ANSI). + SIGILL = 4 + // Trace trap (POSIX). + SIGTRAP = 5 + // Abort (ANSI). + SIGABRT = 6 + // IOT trap (4.2 BSD). + SIGIOT = 6 + // BUS error (4.2 BSD). + SIGBUS = 7 + // Floating-point exception (ANSI). + SIGFPE = 8 + // Kill, unblockable (POSIX). + SIGKILL = 9 + // User-defined signal 1 (POSIX). + SIGUSR1 = 10 + // Segmentation violation (ANSI). + SIGSEGV = 11 + // User-defined signal 2 (POSIX). + SIGUSR2 = 12 + // Broken pipe (POSIX). + SIGPIPE = 13 + // Alarm clock (POSIX). + SIGALRM = 14 + // Termination (ANSI). + SIGTERM = 15 + // Stack fault. + SIGSTKFLT = 16 + // Child status has changed (POSIX). + SIGCHLD = 17 + // Continue (POSIX). + SIGCONT = 18 + // Stop, unblockable (POSIX). + SIGSTOP = 19 + // Keyboard stop (POSIX). + SIGTSTP = 20 + // Background read from tty (POSIX). + SIGTTIN = 21 + // Background write to tty (POSIX). + SIGTTOU = 22 + // Urgent condition on socket (4.2 BSD). + SIGURG = 23 + // CPU limit exceeded (4.2 BSD). + SIGXCPU = 24 + // File size limit exceeded (4.2 BSD). + SIGXFSZ = 25 + // Virtual alarm clock (4.2 BSD). + SIGVTALRM = 26 + // Profiling alarm clock (4.2 BSD). + SIGPROF = 27 + // Window size change (4.3 BSD, Sun). + SIGWINCH = 28 + // I/O now possible (4.2 BSD). + SIGIO = 29 + // Power failure restart (System V). + SIGPWR = 30 + // Bad system call. + SIGSYS = 31 + SIGUNUSED = 31 +) + +// Structure describing a signal stack (obsolete). +type SigstackT struct { + SsSp unsafe.Pointer + SsOnstack c.Int +} + +// Alternate, preferred interface. +type Sigaltstack struct { + SsSp unsafe.Pointer + SsFlags c.Int + SsSize c.SizeT +} + +const NSIG = 65 + +// Type of a signal handler. +// +// llgo:type C +type X__SighandlerT = func(_llcppg_param1 c.Int) + +//go:linkname NativeSignal C.signal +func NativeSignal(__sig c.Int, __handler X__SighandlerT) X__SighandlerT + +//go:linkname Kill C.kill +func Kill(__pid c.Int, __sig c.Int) c.Int + +// Send SIG to all processes in process group PGRP. +// If PGRP is zero, send SIG to all processes in +// the current process's process group. +// +//go:linkname Killpg C.killpg +func Killpg(__pgrp c.Int, __sig c.Int) c.Int + +// Raise signal SIG, i.e., send SIG to yourself. +// +//go:linkname Raise C.raise +func Raise(__sig c.Int) c.Int + +// SVID names for the same things. +// +//go:linkname Ssignal C.ssignal +func Ssignal(__sig c.Int, __handler X__SighandlerT) X__SighandlerT + +//go:linkname Gsignal C.gsignal +func Gsignal(__sig c.Int) c.Int + +// Print a message describing the meaning of the given signal number. +// +//go:linkname Psignal C.psignal +func Psignal(__sig c.Int, __s *uint8) + +// Print a message describing the meaning of the given signal information. +// +// llgo:link (*SiginfoT).Psiginfo C.psiginfo +func (self *SiginfoT) Psiginfo(__s *uint8) { +} + +// Block signals in MASK, returning the old mask. +// +//go:linkname Sigblock C.sigblock +func Sigblock(__mask c.Int) c.Int + +// Set the mask of blocked signals to MASK, returning the old mask. +// +//go:linkname Sigsetmask C.sigsetmask +func Sigsetmask(__mask c.Int) c.Int + +// Return currently selected signal mask. +// +//go:linkname Siggetmask C.siggetmask +func Siggetmask() c.Int + +// Clear all signals from SET. +// +// llgo:link (*SigsetT).Sigemptyset C.sigemptyset +func (self *SigsetT) Sigemptyset() c.Int { + return 0 +} + +// Set all signals in SET. +// +// llgo:link (*SigsetT).Sigfillset C.sigfillset +func (self *SigsetT) Sigfillset() c.Int { + return 0 +} + +// Add SIGNO to SET. +// +// llgo:link (*SigsetT).Sigaddset C.sigaddset +func (self *SigsetT) Sigaddset(__signo c.Int) c.Int { + return 0 +} + +// Remove SIGNO from SET. +// +// llgo:link (*SigsetT).Sigdelset C.sigdelset +func (self *SigsetT) Sigdelset(__signo c.Int) c.Int { + return 0 +} + +// Return 1 if SIGNO is in SET, 0 if not. +// +// llgo:link (*SigsetT).Sigismember C.sigismember +func (self *SigsetT) Sigismember(__signo c.Int) c.Int { + return 0 +} + +// Get and/or change the set of blocked signals. +// +//go:linkname Sigprocmask C.sigprocmask +func Sigprocmask(__how c.Int, __set *SigsetT, __oset *SigsetT) c.Int + +// Change the set of blocked signals to SET, +// wait until a signal arrives, and restore the set of blocked signals. +// +// This function is a cancellation point and therefore not marked with +// __THROW. +// +// llgo:link (*SigsetT).Sigsuspend C.sigsuspend +func (self *SigsetT) Sigsuspend() c.Int { + return 0 +} + +// Get and/or set the action for signal SIG. +// +//go:linkname Sigaction C.sigaction +func Sigaction(__sig c.Int, __act *SigactionT, __oact *SigactionT) c.Int + +// Put in SET all signals that are blocked and waiting to be delivered. +// +// llgo:link (*SigsetT).Sigpending C.sigpending +func (self *SigsetT) Sigpending() c.Int { + return 0 +} + +// Select any of pending signals from SET or wait for any to arrive. +// +// This function is a cancellation point and therefore not marked with +// __THROW. +// +// llgo:link (*SigsetT).Sigwait C.sigwait +func (self *SigsetT) Sigwait(__sig *c.Int) c.Int { + return 0 +} + +// Select any of pending signals from SET and place information in INFO. +// +// This function is a cancellation point and therefore not marked with +// __THROW. +// +// llgo:link (*SigsetT).Sigwaitinfo C.sigwaitinfo +func (self *SigsetT) Sigwaitinfo(__info *SiginfoT) c.Int { + return 0 +} + +// Select any of pending signals from SET and place information in INFO. +// Wait the time specified by TIMEOUT if no signal is pending. +// +// This function is a cancellation point and therefore not marked with +// __THROW. +// +// llgo:link (*SigsetT).Sigtimedwait C.sigtimedwait +func (self *SigsetT) Sigtimedwait(__info *SiginfoT, __timeout *lltime.Timespec) c.Int { + return 0 +} + +// Send signal SIG to the process PID. Associate data in VAL with the +// signal. +// +//go:linkname Sigqueue C.sigqueue +func Sigqueue(__pid c.Int, __sig c.Int, __val Sigval) c.Int + +// If INTERRUPT is nonzero, make signal SIG interrupt system calls +// (causing them to fail with EINTR); if INTERRUPT is zero, make system +// calls be restarted after signal SIG. +// +//go:linkname Siginterrupt C.siginterrupt +func Siginterrupt(__sig c.Int, __interrupt c.Int) c.Int + +// Run signals handlers on the stack specified by SS (if not NULL). +// If OSS is not NULL, it is filled in with the old signal stack status. +// This interface is obsolete and on many platform not implemented. +// +//go:linkname Sigstack C.sigstack +func Sigstack(__ss *SigstackT, __oss *SigstackT) c.Int + +// Alternate signal handler stack interface. +// This interface should always be preferred over `sigstack'. +// +// llgo:link (*Sigaltstack).Sigaltstack C.sigaltstack +func (self *Sigaltstack) Sigaltstack(__oss *Sigaltstack) c.Int { + return 0 +} + +// Create new per-process timer using CLOCK_ID. +// +//go:linkname TimerCreate C.timer_create +func TimerCreate(__clock_id lltime.ClockidT, __evp *Sigevent, __timerid *lltime.TimerT) c.Int + +type SigsetT = X__SigsetT + +type X__SigsetT struct { + X__Val [16]c.Ulong +} + +const LLGoPackage = "link" + +//llgo:type C +type SignalHandler func(c.Int) + +func Signal(sig c.Int, handler SignalHandler) c.Int { + var action SigactionT + *action.X__SigactionHandler.XGof_ref_sa_handler() = handler + return Sigaction(sig, &action, nil) +} + +type SigeventT = Sigevent diff --git a/c/signal/llcppg.cfg b/c/signal/llcppg.cfg new file mode 100644 index 00000000..75e27be3 --- /dev/null +++ b/c/signal/llcppg.cfg @@ -0,0 +1,3 @@ +{ + "Dir": ".sysroot/include" +} diff --git a/c/signal/llcppg.pub b/c/signal/llcppg.pub new file mode 100644 index 00000000..a1d5ed3f --- /dev/null +++ b/c/signal/llcppg.pub @@ -0,0 +1,20 @@ +T __darwin_sigaltstack X__DarwinSigaltstack +T __sigaction_u X__SigactionU +T __sighandler_t X__SighandlerT +T __siginfo X__Siginfo +T __sigset_t X__SigsetT +T _fpstate X_fpstate +T _fpxreg X_fpxreg +T _xmmreg X_xmmreg +T sigaction SigactionT +T sigaltstack Sigaltstack +T sigcontext Sigcontext +T sigevent Sigevent +T sigevent_t SigeventT +T siginfo_t SiginfoT +T sigset_t SigsetT +T sigstack SigstackT +T sigval Sigval +T sigval_t SigvalT +T sigvec SigvecT +T stack_t StackT diff --git a/c/signal/native_darwin_arm64_llgo_test.go b/c/signal/native_darwin_arm64_llgo_test.go new file mode 100644 index 00000000..43d3b599 --- /dev/null +++ b/c/signal/native_darwin_arm64_llgo_test.go @@ -0,0 +1,107 @@ +//go:build llgo && darwin && arm64 && !ios + +package signal + +import ( + "os" + "testing" + "unsafe" + + "github.com/goplus/lib/c" +) + +const ( + nativeActionSize = 16 + nativeActionFlagsOffset = 12 + nativeSigsetSize = 4 + nativeSigsetAlign = 4 + nativeSiginfoSize = 104 + nativeUserSignal = 30 + nativeNoNotification = 0 +) + +func nativeEmptySet(set *SigsetT) c.Int { return Sigemptyset(set) } +func nativeFillSet(set *SigsetT) c.Int { return Sigfillset(set) } +func nativeAddSet(set *SigsetT, number c.Int) c.Int { return Sigaddset(set, number) } +func nativeDeleteSet(set *SigsetT, number c.Int) c.Int { return Sigdelset(set, number) } +func nativeSetMember(set *SigsetT, number c.Int) c.Int { return Sigismember(set, number) } + +func TestNativeSignalActionLayout(t *testing.T) { + var action SigactionT + checks := []struct { + name string + got, want uintptr + }{ + {"size", unsafe.Sizeof(action), nativeActionSize}, + {"alignment", unsafe.Alignof(action), 8}, + {"handler offset", unsafe.Offsetof(action.X__SigactionU), 0}, + {"handler width", unsafe.Sizeof(*action.X__SigactionU.XGof_ref___sa_handler()), 8}, + {"mask offset", unsafe.Offsetof(action.SaMask), 8}, + {"mask width", unsafe.Sizeof(action.SaMask), nativeSigsetSize}, + {"flags offset", unsafe.Offsetof(action.SaFlags), nativeActionFlagsOffset}, + } + for _, check := range checks { + if check.got != check.want { + t.Errorf("%s = %d, want %d", check.name, check.got, check.want) + } + } + if t.Failed() { + return + } + var query struct { + before [8]byte + action SigactionT + after [8]byte + } + for i := range query.before { + query.before[i] = 0xa5 + query.after[i] = 0xa5 + } + if result := Sigaction(nativeUserSignal, nil, &query.action); result != 0 { + t.Fatalf("sigaction query = %d", result) + } + for i := range query.before { + if query.before[i] != 0xa5 || query.after[i] != 0xa5 { + t.Fatalf("sigaction query overwrote a boundary guard at %d", i) + } + } +} + +func TestNativeSignalWrapper(t *testing.T) { + var original SigactionT + if result := Sigaction(nativeUserSignal, nil, &original); result != 0 { + t.Fatalf("read original action = %d", result) + } + defer func() { + if result := Sigaction(nativeUserSignal, &original, nil); result != 0 { + t.Errorf("restore original action = %d", result) + } + }() + deliveredSignal = 0 + handler := SignalHandler(func(number c.Int) { deliveredSignal = number }) + if result := Signal(nativeUserSignal, handler); result != 0 { + t.Fatalf("Signal = %d", result) + } + var actual SigactionT + if result := Sigaction(nativeUserSignal, nil, &actual); result != 0 { + t.Fatalf("read installed action = %d", result) + } + want := *(*unsafe.Pointer)(unsafe.Pointer(&handler)) + got := *(*unsafe.Pointer)(unsafe.Pointer(actual.X__SigactionU.XGof_ref___sa_handler())) + if got != want { + t.Fatalf("installed handler = %p, want %p", got, want) + } + if actual.SaMask != 0 || actual.SaFlags != 0 { + t.Fatalf("installed mask/flags = %d/%d, want 0/0", actual.SaMask, actual.SaFlags) + } + if result := Raise(nativeUserSignal); result != 0 { + t.Fatalf("raise = %d", result) + } + if deliveredSignal != nativeUserSignal { + t.Fatalf("delivered signal = %d, want %d", deliveredSignal, nativeUserSignal) + } + if result := Kill(c.Int(os.Getpid()), 0); result != 0 { + t.Fatalf("kill(self, 0) = %d", result) + } + +} diff --git a/c/signal/native_linux_llgo_test.go b/c/signal/native_linux_llgo_test.go new file mode 100644 index 00000000..b364fa5c --- /dev/null +++ b/c/signal/native_linux_llgo_test.go @@ -0,0 +1,156 @@ +//go:build llgo && linux && (amd64 || arm64) && !android + +package signal + +import ( + "os" + "testing" + "unsafe" + + "github.com/goplus/lib/c" + lltime "github.com/goplus/lib/c/time" +) + +const ( + nativeActionSize = 152 + nativeActionFlagsOffset = 136 + nativeSigsetSize = 128 + nativeSigsetAlign = 8 + nativeSiginfoSize = 128 + nativeUserSignal = 10 + nativeNoNotification = 1 +) + +func nativeEmptySet(set *SigsetT) c.Int { return set.Sigemptyset() } +func nativeFillSet(set *SigsetT) c.Int { return set.Sigfillset() } +func nativeAddSet(set *SigsetT, number c.Int) c.Int { return set.Sigaddset(number) } +func nativeDeleteSet(set *SigsetT, number c.Int) c.Int { return set.Sigdelset(number) } +func nativeSetMember(set *SigsetT, number c.Int) c.Int { return set.Sigismember(number) } + +func TestNativeSigeventLayout(t *testing.T) { + var event Sigevent + if unsafe.Sizeof(event) != 64 || unsafe.Alignof(event) != 8 { + t.Fatalf("sigevent = %d/%d, want 64/8", unsafe.Sizeof(event), unsafe.Alignof(event)) + } + thread := event.X_sigevUn.XGof_ref__sigev_thread() + offset := unsafe.Offsetof(event.X_sigevUn) + unsafe.Offsetof(thread.X_attribute) + if unsafe.Sizeof(*thread) != 16 || unsafe.Sizeof(thread.X_function) != 8 || offset != 24 { + t.Fatalf("sigevent thread layout: size=%d function=%d attribute offset=%d", unsafe.Sizeof(*thread), unsafe.Sizeof(thread.X_function), offset) + } + var marker uintptr + thread.X_attribute = c.Pointer(&marker) + if got := *(*c.Pointer)(unsafe.Add(unsafe.Pointer(&event), offset)); got != c.Pointer(&marker) { + t.Fatalf("attribute pointer = %p, want %p", got, &marker) + } +} + +func TestNativeSignalTimerLifecycle(t *testing.T) { + var event Sigevent + event.SigevNotify = SIGEV_NONE + var timer lltime.TimerT + if result := TimerCreate(lltime.CLOCK_MONOTONIC, &event, &timer); result != 0 { + t.Fatalf("timer_create = %d", result) + } + defer func() { + if result := timer.TimerDelete(); result != 0 { + t.Errorf("timer_delete = %d", result) + } + }() + state := lltime.Itimerspec{ItInterval: lltime.Timespec{Sec: 123, Nsec: 456}, ItValue: lltime.Timespec{Sec: 789, Nsec: 123}} + if result := timer.TimerGettime(&state); result != 0 { + t.Fatalf("timer_gettime = %d", result) + } + if state.ItInterval.Sec != 0 || state.ItInterval.Nsec != 0 || state.ItValue.Sec != 0 || state.ItValue.Nsec != 0 { + t.Fatalf("new timer is not disarmed: %+v", state) + } + disabled := lltime.Itimerspec{} + old := lltime.Itimerspec{ItValue: lltime.Timespec{Sec: 123, Nsec: 456}} + if result := timer.TimerSettime(0, &disabled, &old); result != 0 { + t.Fatalf("timer_settime(disarm) = %d", result) + } + if old.ItValue.Sec != 0 || old.ItValue.Nsec != 0 { + t.Fatalf("old timer value = %+v, want zero", old) + } +} + +func TestNativeSignalActionLayout(t *testing.T) { + var action SigactionT + checks := []struct { + name string + got, want uintptr + }{ + {"size", unsafe.Sizeof(action), nativeActionSize}, + {"alignment", unsafe.Alignof(action), 8}, + {"handler offset", unsafe.Offsetof(action.X__SigactionHandler), 0}, + {"handler width", unsafe.Sizeof(action.X__SigactionHandler), 8}, + {"mask offset", unsafe.Offsetof(action.SaMask), 8}, + {"mask width", unsafe.Sizeof(action.SaMask), nativeSigsetSize}, + {"flags offset", unsafe.Offsetof(action.SaFlags), nativeActionFlagsOffset}, + {"restorer offset", unsafe.Offsetof(action.SaRestorer), 144}, + {"restorer width", unsafe.Sizeof(action.SaRestorer), 8}, + } + for _, check := range checks { + if check.got != check.want { + t.Errorf("%s = %d, want %d", check.name, check.got, check.want) + } + } + if t.Failed() { + return // The current smaller layout must not be passed to a C output parameter. + } + var query struct { + before [8]byte + action SigactionT + after [8]byte + } + for i := range query.before { + query.before[i] = 0xa5 + query.after[i] = 0xa5 + } + if result := Sigaction(nativeUserSignal, nil, &query.action); result != 0 { + t.Fatalf("sigaction query = %d", result) + } + for i := range query.before { + if query.before[i] != 0xa5 || query.after[i] != 0xa5 { + t.Fatalf("sigaction query overwrote a boundary guard at %d", i) + } + } +} + +func TestNativeSignalWrapper(t *testing.T) { + var original SigactionT + if result := Sigaction(nativeUserSignal, nil, &original); result != 0 { + t.Fatalf("read original signal action = %d", result) + } + defer func() { + if result := Sigaction(nativeUserSignal, &original, nil); result != 0 { + t.Errorf("restore original signal action = %d", result) + } + }() + deliveredSignal = 0 + handler := SignalHandler(func(number c.Int) { deliveredSignal = number }) + if result := Signal(nativeUserSignal, handler); result != 0 { + t.Fatalf("Signal = %d", result) + } + var actual SigactionT + if result := Sigaction(nativeUserSignal, nil, &actual); result != 0 { + t.Fatalf("read installed signal action = %d", result) + } + got := *(*unsafe.Pointer)(unsafe.Pointer(actual.X__SigactionHandler.XGof_ref_sa_handler())) + want := *(*unsafe.Pointer)(unsafe.Pointer(&handler)) + if got != want { + t.Fatalf("handler = %p, want %p", got, want) + } + if member := actual.SaMask.Sigismember(nativeUserSignal); member != 0 { + t.Fatalf("signal mask membership = %d, want 0", member) + } + if result := Raise(nativeUserSignal); result != 0 { + t.Fatalf("raise = %d", result) + } + if deliveredSignal != nativeUserSignal { + t.Fatalf("delivered signal = %d, want %d", deliveredSignal, nativeUserSignal) + } + if result := Kill(c.Int(os.Getpid()), 0); result != 0 { + t.Fatalf("kill(self, 0) = %d", result) + } + +} diff --git a/c/signal/native_llgo_test.go b/c/signal/native_llgo_test.go new file mode 100644 index 00000000..69ec5229 --- /dev/null +++ b/c/signal/native_llgo_test.go @@ -0,0 +1,56 @@ +//go:build llgo && ((darwin && arm64 && !ios) || (linux && (amd64 || arm64) && !android)) + +// Copyright (c) 2026 The XGo Authors. Licensed under the Apache License 2.0. + +package signal + +import ( + "testing" + + "github.com/goplus/lib/c" +) + +// The C signal callback only stores the signal number; it does not allocate. +var deliveredSignal c.Int + +type signalABISlot struct { + size, align uintptr + class int +} + +func TestNativeSignalConstants(t *testing.T) { + if SIGUSR1 != nativeUserSignal { + t.Fatalf("SIGUSR1 = %d, want %d", SIGUSR1, nativeUserSignal) + } + if SIGEV_NONE != nativeNoNotification { + t.Fatalf("SIGEV_NONE = %d, want %d", SIGEV_NONE, nativeNoNotification) + } +} + +func TestNativeSignalSetOperations(t *testing.T) { + var set SigsetT + if result := nativeEmptySet(&set); result != 0 { + t.Fatalf("sigemptyset = %d", result) + } + if got := nativeSetMember(&set, nativeUserSignal); got != 0 { + t.Fatalf("empty membership = %d, want 0", got) + } + if result := nativeAddSet(&set, nativeUserSignal); result != 0 { + t.Fatalf("sigaddset = %d", result) + } + if got := nativeSetMember(&set, nativeUserSignal); got != 1 { + t.Fatalf("added membership = %d, want 1", got) + } + if result := nativeDeleteSet(&set, nativeUserSignal); result != 0 { + t.Fatalf("sigdelset = %d", result) + } + if got := nativeSetMember(&set, nativeUserSignal); got != 0 { + t.Fatalf("deleted membership = %d, want 0", got) + } + if result := nativeFillSet(&set); result != 0 { + t.Fatalf("sigfillset = %d", result) + } + if got := nativeSetMember(&set, nativeUserSignal); got != 1 { + t.Fatalf("filled membership = %d, want 1", got) + } +} diff --git a/c/signal/signal.go b/c/signal/signal.go index 250241e0..fe8d12fe 100644 --- a/c/signal/signal.go +++ b/c/signal/signal.go @@ -1,3 +1,5 @@ +//go:build !((darwin && arm64 && !ios) || (linux && (amd64 || arm64) && !android)) + package signal import ( diff --git a/c/signal/symbols_darwin_arm64_llgo_test.go b/c/signal/symbols_darwin_arm64_llgo_test.go new file mode 100644 index 00000000..73de1302 --- /dev/null +++ b/c/signal/symbols_darwin_arm64_llgo_test.go @@ -0,0 +1,545 @@ +//go:build llgo && darwin && arm64 && !ios + +package signal + +import ( + "github.com/goplus/lib/c" + "go/ast" + "go/parser" + "go/token" + "reflect" + "runtime" + "strings" + "testing" + "unsafe" +) + +func TestNativeSignalDataLayouts(t *testing.T) { + // Expected values are compiled from original macOS 14 SDK headers. + var signalFunctionSymbols = []struct { + name string + address unsafe.Pointer + }{ + {"Raise", c.Func(Raise)}, + {"BsdSignal", c.Func(BsdSignal)}, + {"Kill", c.Func(Kill)}, + {"Killpg", c.Func(Killpg)}, + {"Sigaction", c.Func(Sigaction)}, + {"Sigaddset", c.Func(Sigaddset)}, + {"*StackT.Sigaltstack", c.Func((*StackT).Sigaltstack)}, + {"Sigdelset", c.Func(Sigdelset)}, + {"Sigemptyset", c.Func(Sigemptyset)}, + {"Sigfillset", c.Func(Sigfillset)}, + {"Sighold", c.Func(Sighold)}, + {"Sigignore", c.Func(Sigignore)}, + {"Siginterrupt", c.Func(Siginterrupt)}, + {"Sigismember", c.Func(Sigismember)}, + {"Sigpause", c.Func(Sigpause)}, + {"Sigpending", c.Func(Sigpending)}, + {"Sigprocmask", c.Func(Sigprocmask)}, + {"Sigrelse", c.Func(Sigrelse)}, + {"Sigset", c.Func(Sigset)}, + {"Sigsuspend", c.Func(Sigsuspend)}, + {"Sigwait", c.Func(Sigwait)}, + {"Psignal", c.Func(Psignal)}, + {"Sigblock", c.Func(Sigblock)}, + {"Sigsetmask", c.Func(Sigsetmask)}, + {"Sigvec", c.Func(Sigvec)}, + {"NativeSignal", c.Func(NativeSignal)}, + } + var signalFunctionPrototypes = []struct { + name string + signature reflect.Type + inputs []signalABISlot + output *signalABISlot + variadic bool + }{ + {"Raise", reflect.TypeOf(Raise), []signalABISlot{{4, 4, 1}}, &signalABISlot{4, 4, 1}, false}, + {"BsdSignal", reflect.TypeOf(BsdSignal), []signalABISlot{{4, 4, 1}, {8, 8, 5}}, &signalABISlot{8, 8, 5}, false}, + {"Kill", reflect.TypeOf(Kill), []signalABISlot{{4, 4, 1}, {4, 4, 1}}, &signalABISlot{4, 4, 1}, false}, + {"Killpg", reflect.TypeOf(Killpg), []signalABISlot{{4, 4, 1}, {4, 4, 1}}, &signalABISlot{4, 4, 1}, false}, + {"Sigaction", reflect.TypeOf(Sigaction), []signalABISlot{{4, 4, 1}, {8, 8, 5}, {8, 8, 5}}, &signalABISlot{4, 4, 1}, false}, + {"Sigaddset", reflect.TypeOf(Sigaddset), []signalABISlot{{8, 8, 5}, {4, 4, 1}}, &signalABISlot{4, 4, 1}, false}, + {"*StackT.Sigaltstack", reflect.TypeOf((*StackT).Sigaltstack), []signalABISlot{{8, 8, 5}, {8, 8, 5}}, &signalABISlot{4, 4, 1}, false}, + {"Sigdelset", reflect.TypeOf(Sigdelset), []signalABISlot{{8, 8, 5}, {4, 4, 1}}, &signalABISlot{4, 4, 1}, false}, + {"Sigemptyset", reflect.TypeOf(Sigemptyset), []signalABISlot{{8, 8, 5}}, &signalABISlot{4, 4, 1}, false}, + {"Sigfillset", reflect.TypeOf(Sigfillset), []signalABISlot{{8, 8, 5}}, &signalABISlot{4, 4, 1}, false}, + {"Sighold", reflect.TypeOf(Sighold), []signalABISlot{{4, 4, 1}}, &signalABISlot{4, 4, 1}, false}, + {"Sigignore", reflect.TypeOf(Sigignore), []signalABISlot{{4, 4, 1}}, &signalABISlot{4, 4, 1}, false}, + {"Siginterrupt", reflect.TypeOf(Siginterrupt), []signalABISlot{{4, 4, 1}, {4, 4, 1}}, &signalABISlot{4, 4, 1}, false}, + {"Sigismember", reflect.TypeOf(Sigismember), []signalABISlot{{8, 8, 5}, {4, 4, 1}}, &signalABISlot{4, 4, 1}, false}, + {"Sigpause", reflect.TypeOf(Sigpause), []signalABISlot{{4, 4, 1}}, &signalABISlot{4, 4, 1}, false}, + {"Sigpending", reflect.TypeOf(Sigpending), []signalABISlot{{8, 8, 5}}, &signalABISlot{4, 4, 1}, false}, + {"Sigprocmask", reflect.TypeOf(Sigprocmask), []signalABISlot{{4, 4, 1}, {8, 8, 5}, {8, 8, 5}}, &signalABISlot{4, 4, 1}, false}, + {"Sigrelse", reflect.TypeOf(Sigrelse), []signalABISlot{{4, 4, 1}}, &signalABISlot{4, 4, 1}, false}, + {"Sigset", reflect.TypeOf(Sigset), []signalABISlot{{4, 4, 1}, {8, 8, 5}}, &signalABISlot{8, 8, 5}, false}, + {"Sigsuspend", reflect.TypeOf(Sigsuspend), []signalABISlot{{8, 8, 5}}, &signalABISlot{4, 4, 1}, false}, + {"Sigwait", reflect.TypeOf(Sigwait), []signalABISlot{{8, 8, 5}, {8, 8, 5}}, &signalABISlot{4, 4, 1}, false}, + {"Psignal", reflect.TypeOf(Psignal), []signalABISlot{{4, 4, 1}, {8, 8, 5}}, nil, false}, + {"Sigblock", reflect.TypeOf(Sigblock), []signalABISlot{{4, 4, 1}}, &signalABISlot{4, 4, 1}, false}, + {"Sigsetmask", reflect.TypeOf(Sigsetmask), []signalABISlot{{4, 4, 1}}, &signalABISlot{4, 4, 1}, false}, + {"Sigvec", reflect.TypeOf(Sigvec), []signalABISlot{{4, 4, 1}, {8, 8, 5}, {8, 8, 5}}, &signalABISlot{4, 4, 1}, false}, + {"NativeSignal", reflect.TypeOf(NativeSignal), []signalABISlot{{4, 4, 1}, {8, 8, 5}}, &signalABISlot{8, 8, 5}, false}, + } + var signalStaticFunctionPrototypes = []struct { + name string + slots []struct { + label string + goType reflect.Type + got, want signalABISlot + } + }{} + var signalTypeLayouts = []struct { + symbol, property string + got, want uintptr + }{ + {"X__DarwinSigaltstack", "size", unsafe.Sizeof(*new(X__DarwinSigaltstack)), 24}, + {"X__DarwinSigaltstack", "alignment", unsafe.Alignof(*new(X__DarwinSigaltstack)), 8}, + {"X__DarwinSigaltstack", "SsSp offset", unsafe.Offsetof((*new(X__DarwinSigaltstack)).SsSp), 0}, + {"X__DarwinSigaltstack", "SsSp size", unsafe.Sizeof((*new(X__DarwinSigaltstack)).SsSp), 8}, + {"X__DarwinSigaltstack", "SsSp alignment", unsafe.Alignof((*new(X__DarwinSigaltstack)).SsSp), 8}, + {"X__DarwinSigaltstack", "SsSize offset", unsafe.Offsetof((*new(X__DarwinSigaltstack)).SsSize), 8}, + {"X__DarwinSigaltstack", "SsSize size", unsafe.Sizeof((*new(X__DarwinSigaltstack)).SsSize), 8}, + {"X__DarwinSigaltstack", "SsSize alignment", unsafe.Alignof((*new(X__DarwinSigaltstack)).SsSize), 8}, + {"X__DarwinSigaltstack", "SsFlags offset", unsafe.Offsetof((*new(X__DarwinSigaltstack)).SsFlags), 16}, + {"X__DarwinSigaltstack", "SsFlags size", unsafe.Sizeof((*new(X__DarwinSigaltstack)).SsFlags), 4}, + {"X__DarwinSigaltstack", "SsFlags alignment", unsafe.Alignof((*new(X__DarwinSigaltstack)).SsFlags), 4}, + {"StackT", "size", unsafe.Sizeof(*new(StackT)), 24}, + {"StackT", "alignment", unsafe.Alignof(*new(StackT)), 8}, + {"Sigval", "size", unsafe.Sizeof(*new(Sigval)), 8}, + {"Sigval", "alignment", unsafe.Alignof(*new(Sigval)), 8}, + {"X__Siginfo", "size", unsafe.Sizeof(*new(X__Siginfo)), 104}, + {"X__Siginfo", "alignment", unsafe.Alignof(*new(X__Siginfo)), 8}, + {"X__Siginfo", "SiSigno offset", unsafe.Offsetof((*new(X__Siginfo)).SiSigno), 0}, + {"X__Siginfo", "SiSigno size", unsafe.Sizeof((*new(X__Siginfo)).SiSigno), 4}, + {"X__Siginfo", "SiSigno alignment", unsafe.Alignof((*new(X__Siginfo)).SiSigno), 4}, + {"X__Siginfo", "SiErrno offset", unsafe.Offsetof((*new(X__Siginfo)).SiErrno), 4}, + {"X__Siginfo", "SiErrno size", unsafe.Sizeof((*new(X__Siginfo)).SiErrno), 4}, + {"X__Siginfo", "SiErrno alignment", unsafe.Alignof((*new(X__Siginfo)).SiErrno), 4}, + {"X__Siginfo", "SiCode offset", unsafe.Offsetof((*new(X__Siginfo)).SiCode), 8}, + {"X__Siginfo", "SiCode size", unsafe.Sizeof((*new(X__Siginfo)).SiCode), 4}, + {"X__Siginfo", "SiCode alignment", unsafe.Alignof((*new(X__Siginfo)).SiCode), 4}, + {"X__Siginfo", "SiPid offset", unsafe.Offsetof((*new(X__Siginfo)).SiPid), 12}, + {"X__Siginfo", "SiPid size", unsafe.Sizeof((*new(X__Siginfo)).SiPid), 4}, + {"X__Siginfo", "SiPid alignment", unsafe.Alignof((*new(X__Siginfo)).SiPid), 4}, + {"X__Siginfo", "SiUid offset", unsafe.Offsetof((*new(X__Siginfo)).SiUid), 16}, + {"X__Siginfo", "SiUid size", unsafe.Sizeof((*new(X__Siginfo)).SiUid), 4}, + {"X__Siginfo", "SiUid alignment", unsafe.Alignof((*new(X__Siginfo)).SiUid), 4}, + {"X__Siginfo", "SiStatus offset", unsafe.Offsetof((*new(X__Siginfo)).SiStatus), 20}, + {"X__Siginfo", "SiStatus size", unsafe.Sizeof((*new(X__Siginfo)).SiStatus), 4}, + {"X__Siginfo", "SiStatus alignment", unsafe.Alignof((*new(X__Siginfo)).SiStatus), 4}, + {"X__Siginfo", "SiAddr offset", unsafe.Offsetof((*new(X__Siginfo)).SiAddr), 24}, + {"X__Siginfo", "SiAddr size", unsafe.Sizeof((*new(X__Siginfo)).SiAddr), 8}, + {"X__Siginfo", "SiAddr alignment", unsafe.Alignof((*new(X__Siginfo)).SiAddr), 8}, + {"X__Siginfo", "SiValue offset", unsafe.Offsetof((*new(X__Siginfo)).SiValue), 32}, + {"X__Siginfo", "SiValue size", unsafe.Sizeof((*new(X__Siginfo)).SiValue), 8}, + {"X__Siginfo", "SiValue alignment", unsafe.Alignof((*new(X__Siginfo)).SiValue), 8}, + {"X__Siginfo", "SiBand offset", unsafe.Offsetof((*new(X__Siginfo)).SiBand), 40}, + {"X__Siginfo", "SiBand size", unsafe.Sizeof((*new(X__Siginfo)).SiBand), 8}, + {"X__Siginfo", "SiBand alignment", unsafe.Alignof((*new(X__Siginfo)).SiBand), 8}, + {"X__Siginfo", "X__Pad offset", unsafe.Offsetof((*new(X__Siginfo)).X__Pad), 48}, + {"X__Siginfo", "X__Pad size", unsafe.Sizeof((*new(X__Siginfo)).X__Pad), 56}, + {"X__Siginfo", "X__Pad alignment", unsafe.Alignof((*new(X__Siginfo)).X__Pad), 8}, + {"X__SigactionU", "size", unsafe.Sizeof(*new(X__SigactionU)), 8}, + {"X__SigactionU", "alignment", unsafe.Alignof(*new(X__SigactionU)), 8}, + {"SigactionT", "size", unsafe.Sizeof(*new(SigactionT)), 16}, + {"SigactionT", "alignment", unsafe.Alignof(*new(SigactionT)), 8}, + {"SigactionT", "X__SigactionU offset", unsafe.Offsetof((*new(SigactionT)).X__SigactionU), 0}, + {"SigactionT", "X__SigactionU size", unsafe.Sizeof((*new(SigactionT)).X__SigactionU), 8}, + {"SigactionT", "X__SigactionU alignment", unsafe.Alignof((*new(SigactionT)).X__SigactionU), 8}, + {"SigactionT", "SaMask offset", unsafe.Offsetof((*new(SigactionT)).SaMask), 8}, + {"SigactionT", "SaMask size", unsafe.Sizeof((*new(SigactionT)).SaMask), 4}, + {"SigactionT", "SaMask alignment", unsafe.Alignof((*new(SigactionT)).SaMask), 4}, + {"SigactionT", "SaFlags offset", unsafe.Offsetof((*new(SigactionT)).SaFlags), 12}, + {"SigactionT", "SaFlags size", unsafe.Sizeof((*new(SigactionT)).SaFlags), 4}, + {"SigactionT", "SaFlags alignment", unsafe.Alignof((*new(SigactionT)).SaFlags), 4}, + {"SigvecT", "size", unsafe.Sizeof(*new(SigvecT)), 16}, + {"SigvecT", "alignment", unsafe.Alignof(*new(SigvecT)), 8}, + {"SigvecT", "SvHandler offset", unsafe.Offsetof((*new(SigvecT)).SvHandler), 0}, + {"SigvecT", "SvHandler size", unsafe.Sizeof((*new(SigvecT)).SvHandler), 8}, + {"SigvecT", "SvHandler alignment", unsafe.Alignof((*new(SigvecT)).SvHandler), 8}, + {"SigvecT", "SvMask offset", unsafe.Offsetof((*new(SigvecT)).SvMask), 8}, + {"SigvecT", "SvMask size", unsafe.Sizeof((*new(SigvecT)).SvMask), 4}, + {"SigvecT", "SvMask alignment", unsafe.Alignof((*new(SigvecT)).SvMask), 4}, + {"SigvecT", "SvFlags offset", unsafe.Offsetof((*new(SigvecT)).SvFlags), 12}, + {"SigvecT", "SvFlags size", unsafe.Sizeof((*new(SigvecT)).SvFlags), 4}, + {"SigvecT", "SvFlags alignment", unsafe.Alignof((*new(SigvecT)).SvFlags), 4}, + {"SiginfoT", "size", unsafe.Sizeof(*new(SiginfoT)), 104}, + {"SiginfoT", "alignment", unsafe.Alignof(*new(SiginfoT)), 8}, + {"SigsetT", "size", unsafe.Sizeof(*new(SigsetT)), 4}, + {"SigsetT", "alignment", unsafe.Alignof(*new(SigsetT)), 4}, + {"SignalHandler", "size", unsafe.Sizeof(*new(SignalHandler)), 8}, + {"SignalHandler", "alignment", unsafe.Alignof(*new(SignalHandler)), 8}, + {"SysSigname", "global size", unsafe.Sizeof(SysSigname), 256}, + {"SysSigname", "global alignment", unsafe.Alignof(SysSigname), 8}, + {"SysSiglist", "global size", unsafe.Sizeof(SysSiglist), 256}, + {"SysSiglist", "global alignment", unsafe.Alignof(SysSiglist), 8}, + } + var signalIntegerConstants = []struct { + name string + got, want int64 + }{ + {"NSIG", int64(NSIG), 32}, + {"SIGHUP", int64(SIGHUP), 1}, + {"SIGINT", int64(SIGINT), 2}, + {"SIGQUIT", int64(SIGQUIT), 3}, + {"SIGILL", int64(SIGILL), 4}, + {"SIGTRAP", int64(SIGTRAP), 5}, + {"SIGABRT", int64(SIGABRT), 6}, + {"SIGIOT", int64(SIGIOT), 6}, + {"SIGEMT", int64(SIGEMT), 7}, + {"SIGFPE", int64(SIGFPE), 8}, + {"SIGKILL", int64(SIGKILL), 9}, + {"SIGBUS", int64(SIGBUS), 10}, + {"SIGSEGV", int64(SIGSEGV), 11}, + {"SIGSYS", int64(SIGSYS), 12}, + {"SIGPIPE", int64(SIGPIPE), 13}, + {"SIGALRM", int64(SIGALRM), 14}, + {"SIGTERM", int64(SIGTERM), 15}, + {"SIGURG", int64(SIGURG), 16}, + {"SIGSTOP", int64(SIGSTOP), 17}, + {"SIGTSTP", int64(SIGTSTP), 18}, + {"SIGCONT", int64(SIGCONT), 19}, + {"SIGCHLD", int64(SIGCHLD), 20}, + {"SIGTTIN", int64(SIGTTIN), 21}, + {"SIGTTOU", int64(SIGTTOU), 22}, + {"SIGIO", int64(SIGIO), 23}, + {"SIGXCPU", int64(SIGXCPU), 24}, + {"SIGXFSZ", int64(SIGXFSZ), 25}, + {"SIGVTALRM", int64(SIGVTALRM), 26}, + {"SIGPROF", int64(SIGPROF), 27}, + {"SIGWINCH", int64(SIGWINCH), 28}, + {"SIGINFO", int64(SIGINFO), 29}, + {"SIGUSR1", int64(SIGUSR1), 30}, + {"SIGUSR2", int64(SIGUSR2), 31}, + {"SIGEV_NONE", int64(SIGEV_NONE), 0}, + {"SIGEV_SIGNAL", int64(SIGEV_SIGNAL), 1}, + {"SIGEV_THREAD", int64(SIGEV_THREAD), 3}, + {"ILL_NOOP", int64(ILL_NOOP), 0}, + {"ILL_ILLOPC", int64(ILL_ILLOPC), 1}, + {"ILL_ILLTRP", int64(ILL_ILLTRP), 2}, + {"ILL_PRVOPC", int64(ILL_PRVOPC), 3}, + {"ILL_ILLOPN", int64(ILL_ILLOPN), 4}, + {"ILL_ILLADR", int64(ILL_ILLADR), 5}, + {"ILL_PRVREG", int64(ILL_PRVREG), 6}, + {"ILL_COPROC", int64(ILL_COPROC), 7}, + {"ILL_BADSTK", int64(ILL_BADSTK), 8}, + {"FPE_NOOP", int64(FPE_NOOP), 0}, + {"FPE_FLTDIV", int64(FPE_FLTDIV), 1}, + {"FPE_FLTOVF", int64(FPE_FLTOVF), 2}, + {"FPE_FLTUND", int64(FPE_FLTUND), 3}, + {"FPE_FLTRES", int64(FPE_FLTRES), 4}, + {"FPE_FLTINV", int64(FPE_FLTINV), 5}, + {"FPE_FLTSUB", int64(FPE_FLTSUB), 6}, + {"FPE_INTDIV", int64(FPE_INTDIV), 7}, + {"FPE_INTOVF", int64(FPE_INTOVF), 8}, + {"SEGV_NOOP", int64(SEGV_NOOP), 0}, + {"SEGV_MAPERR", int64(SEGV_MAPERR), 1}, + {"SEGV_ACCERR", int64(SEGV_ACCERR), 2}, + {"BUS_NOOP", int64(BUS_NOOP), 0}, + {"BUS_ADRALN", int64(BUS_ADRALN), 1}, + {"BUS_ADRERR", int64(BUS_ADRERR), 2}, + {"BUS_OBJERR", int64(BUS_OBJERR), 3}, + {"TRAP_BRKPT", int64(TRAP_BRKPT), 1}, + {"TRAP_TRACE", int64(TRAP_TRACE), 2}, + {"CLD_NOOP", int64(CLD_NOOP), 0}, + {"CLD_EXITED", int64(CLD_EXITED), 1}, + {"CLD_KILLED", int64(CLD_KILLED), 2}, + {"CLD_DUMPED", int64(CLD_DUMPED), 3}, + {"CLD_TRAPPED", int64(CLD_TRAPPED), 4}, + {"CLD_STOPPED", int64(CLD_STOPPED), 5}, + {"CLD_CONTINUED", int64(CLD_CONTINUED), 6}, + {"POLL_IN", int64(POLL_IN), 1}, + {"POLL_OUT", int64(POLL_OUT), 2}, + {"POLL_MSG", int64(POLL_MSG), 3}, + {"POLL_ERR", int64(POLL_ERR), 4}, + {"POLL_PRI", int64(POLL_PRI), 5}, + {"POLL_HUP", int64(POLL_HUP), 6}, + {"SA_ONSTACK", int64(SA_ONSTACK), 1}, + {"SA_RESTART", int64(SA_RESTART), 2}, + {"SA_RESETHAND", int64(SA_RESETHAND), 4}, + {"SA_NOCLDSTOP", int64(SA_NOCLDSTOP), 8}, + {"SA_NODEFER", int64(SA_NODEFER), 16}, + {"SA_NOCLDWAIT", int64(SA_NOCLDWAIT), 32}, + {"SA_SIGINFO", int64(SA_SIGINFO), 64}, + {"SA_USERTRAMP", int64(SA_USERTRAMP), 256}, + {"SA_64REGSET", int64(SA_64REGSET), 512}, + {"SA_USERSPACE_MASK", int64(SA_USERSPACE_MASK), 127}, + {"SIG_BLOCK", int64(SIG_BLOCK), 1}, + {"SIG_UNBLOCK", int64(SIG_UNBLOCK), 2}, + {"SIG_SETMASK", int64(SIG_SETMASK), 3}, + {"SI_USER", int64(SI_USER), 65537}, + {"SI_QUEUE", int64(SI_QUEUE), 65538}, + {"SI_TIMER", int64(SI_TIMER), 65539}, + {"SI_ASYNCIO", int64(SI_ASYNCIO), 65540}, + {"SI_MESGQ", int64(SI_MESGQ), 65541}, + {"SS_ONSTACK", int64(SS_ONSTACK), 1}, + {"SS_DISABLE", int64(SS_DISABLE), 4}, + {"MINSIGSTKSZ", int64(MINSIGSTKSZ), 32768}, + {"SIGSTKSZ", int64(SIGSTKSZ), 131072}, + {"SV_ONSTACK", int64(SV_ONSTACK), 1}, + {"SV_INTERRUPT", int64(SV_INTERRUPT), 2}, + {"SV_RESETHAND", int64(SV_RESETHAND), 4}, + {"SV_NODEFER", int64(SV_NODEFER), 16}, + {"SV_NOCLDSTOP", int64(SV_NOCLDSTOP), 8}, + {"SV_SIGINFO", int64(SV_SIGINFO), 64}, + } + var signalVariableSymbols = []struct { + name string + address unsafe.Pointer + }{ + {"SysSigname", unsafe.Pointer(&SysSigname)}, + {"SysSiglist", unsafe.Pointer(&SysSiglist)}, + } + var signalAccessorChecks = []struct { + name string + check func() (uintptr, uintptr, uintptr) + offset, size, align uintptr + }{ + {"*Sigval.XGof_ref_sival_int", func() (uintptr, uintptr, uintptr) { + var value Sigval + view := value.XGof_ref_sival_int() + return uintptr(unsafe.Pointer(view)) - uintptr(unsafe.Pointer(&value)), unsafe.Sizeof(*view), unsafe.Alignof(*view) + }, 0, 4, 4}, + {"*Sigval.XGof_ref_sival_ptr", func() (uintptr, uintptr, uintptr) { + var value Sigval + view := value.XGof_ref_sival_ptr() + return uintptr(unsafe.Pointer(view)) - uintptr(unsafe.Pointer(&value)), unsafe.Sizeof(*view), unsafe.Alignof(*view) + }, 0, 8, 8}, + {"*X__SigactionU.XGof_ref___sa_handler", func() (uintptr, uintptr, uintptr) { + var value X__SigactionU + view := value.XGof_ref___sa_handler() + return uintptr(unsafe.Pointer(view)) - uintptr(unsafe.Pointer(&value)), unsafe.Sizeof(*view), unsafe.Alignof(*view) + }, 0, 8, 8}, + {"*X__SigactionU.XGof_ref___sa_sigaction", func() (uintptr, uintptr, uintptr) { + var value X__SigactionU + view := value.XGof_ref___sa_sigaction() + return uintptr(unsafe.Pointer(view)) - uintptr(unsafe.Pointer(&value)), unsafe.Sizeof(*view), unsafe.Alignof(*view) + }, 0, 8, 8}, + } + + t.Run("function symbols", func(t *testing.T) { + for _, symbol := range signalFunctionSymbols { + t.Run(symbol.name, func(t *testing.T) { + if symbol.address == nil { + t.Fatal("C function address is nil") + } + t.Logf("C function address: %p", symbol.address) + }) + } + }) + t.Run("native prototypes", func(t *testing.T) { + check := func(name string, got reflect.Type, want signalABISlot) { + if got.Size() != want.size || uintptr(got.Align()) != want.align { + t.Errorf("%s size/alignment = %d/%d, C = %d/%d", name, got.Size(), got.Align(), want.size, want.align) + } + class := 0 + switch got.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + class = 1 + case reflect.Ptr, reflect.UnsafePointer, reflect.Func: + class = 5 + case reflect.Float32, reflect.Float64: + class = 8 + case reflect.Struct: + class = 12 + if got.NumField() == 1 && got.Field(0).Name == "_xgo_union" { + class = 13 + } + } + if class != want.class { + t.Errorf("%s ABI class = %d (%v), C = %d", name, class, got.Kind(), want.class) + } + } + for _, tc := range signalFunctionPrototypes { + t.Run(tc.name, func(t *testing.T) { + inputs := len(tc.inputs) + if tc.variadic { + inputs++ + } + if tc.signature.Kind() != reflect.Func || tc.signature.NumIn() != inputs || tc.signature.IsVariadic() != tc.variadic { + t.Fatalf("Go signature = %v, C fixed parameters = %d, variadic = %v", tc.signature, len(tc.inputs), tc.variadic) + } + for i, slot := range tc.inputs { + check(tc.name+" parameter", tc.signature.In(i), slot) + } + outputs := 0 + if tc.output != nil { + outputs = 1 + } + if tc.signature.NumOut() != outputs { + t.Fatalf("Go result count = %d, C = %d", tc.signature.NumOut(), outputs) + } + if tc.output != nil { + check(tc.name+" result", tc.signature.Out(0), *tc.output) + } + }) + } + for _, tc := range signalStaticFunctionPrototypes { + t.Run(tc.name, func(t *testing.T) { + for _, slot := range tc.slots { + if slot.goType != nil { + check(tc.name+" "+slot.label, slot.goType, slot.want) + } else if slot.got != slot.want { + t.Errorf("%s %s ABI = %+v, C = %+v", tc.name, slot.label, slot.got, slot.want) + } + } + }) + } + + }) + t.Run("native types and globals", func(t *testing.T) { + for _, tc := range signalTypeLayouts { + t.Run(tc.symbol+"/"+tc.property, func(t *testing.T) { + if tc.got != tc.want { + t.Fatalf("Go layout = %d, C headers = %d", tc.got, tc.want) + } + }) + } + for _, symbol := range signalVariableSymbols { + if symbol.address == nil { + t.Errorf("%s C variable address is nil", symbol.name) + } + t.Logf("%s C variable address: %p", symbol.name, symbol.address) + } + }) + t.Run("native constants", func(t *testing.T) { + for _, tc := range signalIntegerConstants { + t.Run(tc.name, func(t *testing.T) { + if tc.got != tc.want { + t.Fatalf("Go constant = %d, C headers = %d", tc.got, tc.want) + } + }) + } + }) + t.Run("union accessors", func(t *testing.T) { + for _, tc := range signalAccessorChecks { + t.Run(tc.name, func(t *testing.T) { + offset, size, align := tc.check() + if offset != tc.offset || size != tc.size || align != tc.align { + t.Fatalf("Go field offset/size/alignment = %d/%d/%d, C = %d/%d/%d", offset, size, align, tc.offset, tc.size, tc.align) + } + }) + } + }) + t.Run("symbol inventory", func(t *testing.T) { + functions, prototypes, types, constants, variables := map[string]bool{}, map[string]bool{}, map[string]bool{}, map[string]bool{}, map[string]bool{} + for _, tc := range signalFunctionPrototypes { + prototypes[tc.name] = true + } + for _, tc := range signalStaticFunctionPrototypes { + prototypes[tc.name] = true + } + + for _, symbol := range signalFunctionSymbols { + functions[symbol.name] = true + if !prototypes[symbol.name] { + t.Errorf("%s has no native prototype test", symbol.name) + } + } + for _, tc := range signalAccessorChecks { + functions[tc.name] = true + } + for _, tc := range signalTypeLayouts { + types[tc.symbol] = true + } + for _, tc := range signalIntegerConstants { + constants[tc.name] = true + } + for _, symbol := range signalVariableSymbols { + variables[symbol.name] = true + } + constants["LLGoPackage"] = true + functions["Signal"] = true + if LLGoPackage != "link" { + t.Errorf("LLGoPackage = %q, want link", LLGoPackage) + } + files := []string{"libc_" + runtime.GOOS + "_" + runtime.GOARCH + ".go"} + + for _, filename := range files { + source, err := parser.ParseFile(token.NewFileSet(), filename, nil, parser.ParseComments) + if err != nil { + t.Fatal(err) + } + for _, declaration := range source.Decls { + switch decl := declaration.(type) { + case *ast.FuncDecl: + name := decl.Name.Name + if !ast.IsExported(name) { + continue + } + if decl.Recv != nil { + receiver, prefix := decl.Recv.List[0].Type, "" + if pointer, ok := receiver.(*ast.StarExpr); ok { + receiver, prefix = pointer.X, "*" + } + name = prefix + receiver.(*ast.Ident).Name + "." + name + } + if !functions[name] { + t.Errorf("%s: function %s has no test", filename, name) + } + if strings.HasPrefix(decl.Name.Name, "Native") && decl.Name.Name != "NativeSignal" { + t.Errorf("%s retains duplicate %s", filename, name) + } + if decl.Doc != nil { + for _, comment := range decl.Doc.List { + for _, private := range []string{"C._llcppg_", "C.__sig", "C.__sysv_signal", "C.__libc_current_sigrt"} { + if strings.Contains(comment.Text, private) { + t.Errorf("%s still exposes private C entry point %s", filename, private) + } + } + } + } + case *ast.GenDecl: + for _, specification := range decl.Specs { + switch spec := specification.(type) { + case *ast.TypeSpec: + if ast.IsExported(spec.Name.Name) && !types[spec.Name.Name] { + t.Errorf("%s: type %s has no ABI test", filename, spec.Name.Name) + } + case *ast.ValueSpec: + for _, name := range spec.Names { + if !ast.IsExported(name.Name) { + continue + } + if decl.Tok == token.CONST && !constants[name.Name] { + t.Errorf("%s: constant %s has no test", filename, name.Name) + } + if decl.Tok == token.VAR && !variables[name.Name] { + t.Errorf("%s: variable %s has no test", filename, name.Name) + } + } + } + } + } + } + } + t.Logf("coverage: %d C functions, %d Go union accessors, %d types/global layouts, %d constants, %d globals", len(signalFunctionSymbols), len(signalAccessorChecks), len(signalTypeLayouts), len(constants), len(signalVariableSymbols)) + }) + + var set SigsetT + var info SiginfoT + var value Sigval + if unsafe.Sizeof(set) != nativeSigsetSize || unsafe.Alignof(set) != nativeSigsetAlign { + t.Fatalf("sigset_t = %d/%d, want %d/%d", unsafe.Sizeof(set), unsafe.Alignof(set), nativeSigsetSize, nativeSigsetAlign) + } + if unsafe.Sizeof(info) != nativeSiginfoSize || unsafe.Alignof(info) != 8 { + t.Fatalf("siginfo_t = %d/%d, want %d/8", unsafe.Sizeof(info), unsafe.Alignof(info), nativeSiginfoSize) + } + if unsafe.Offsetof(info.SiSigno) != 0 || unsafe.Offsetof(info.SiErrno) != 4 || unsafe.Offsetof(info.SiCode) != 8 { + t.Fatalf("siginfo_t header offsets = %d/%d/%d", unsafe.Offsetof(info.SiSigno), unsafe.Offsetof(info.SiErrno), unsafe.Offsetof(info.SiCode)) + } + if unsafe.Sizeof(value) != 8 || unsafe.Alignof(value) != 8 { + t.Fatalf("sigval = %d/%d, want 8/8", unsafe.Sizeof(value), unsafe.Alignof(value)) + } + *value.XGof_ref_sival_int() = -7 + if got := *(*c.Int)(unsafe.Pointer(&value)); got != -7 { + t.Fatalf("sigval integer storage = %d, want -7", got) + } + var marker uintptr + *value.XGof_ref_sival_ptr() = unsafe.Pointer(&marker) + if got := *(*unsafe.Pointer)(unsafe.Pointer(&value)); got != unsafe.Pointer(&marker) { + t.Fatalf("sigval pointer storage = %p, want %p", got, &marker) + } + +} diff --git a/c/signal/symbols_linux_amd64_llgo_test.go b/c/signal/symbols_linux_amd64_llgo_test.go new file mode 100644 index 00000000..be639b40 --- /dev/null +++ b/c/signal/symbols_linux_amd64_llgo_test.go @@ -0,0 +1,849 @@ +//go:build llgo && linux && amd64 && !android + +package signal + +import ( + "github.com/goplus/lib/c" + lltime "github.com/goplus/lib/c/time" + "go/ast" + "go/parser" + "go/token" + "reflect" + "runtime" + "strings" + "testing" + "unsafe" +) + +func TestNativeSignalDataLayouts(t *testing.T) { + // Expected values are compiled from original Bootlin glibc 2.24 headers. + var signalFunctionSymbols = []struct { + name string + address unsafe.Pointer + }{ + {"NativeSignal", c.Func(NativeSignal)}, + {"Kill", c.Func(Kill)}, + {"Killpg", c.Func(Killpg)}, + {"Raise", c.Func(Raise)}, + {"Ssignal", c.Func(Ssignal)}, + {"Gsignal", c.Func(Gsignal)}, + {"Psignal", c.Func(Psignal)}, + {"*SiginfoT.Psiginfo", c.Func((*SiginfoT).Psiginfo)}, + {"Sigblock", c.Func(Sigblock)}, + {"Sigsetmask", c.Func(Sigsetmask)}, + {"Siggetmask", c.Func(Siggetmask)}, + {"*SigsetT.Sigemptyset", c.Func((*SigsetT).Sigemptyset)}, + {"*SigsetT.Sigfillset", c.Func((*SigsetT).Sigfillset)}, + {"*SigsetT.Sigaddset", c.Func((*SigsetT).Sigaddset)}, + {"*SigsetT.Sigdelset", c.Func((*SigsetT).Sigdelset)}, + {"*SigsetT.Sigismember", c.Func((*SigsetT).Sigismember)}, + {"Sigprocmask", c.Func(Sigprocmask)}, + {"*SigsetT.Sigsuspend", c.Func((*SigsetT).Sigsuspend)}, + {"Sigaction", c.Func(Sigaction)}, + {"*SigsetT.Sigpending", c.Func((*SigsetT).Sigpending)}, + {"*SigsetT.Sigwait", c.Func((*SigsetT).Sigwait)}, + {"*SigsetT.Sigwaitinfo", c.Func((*SigsetT).Sigwaitinfo)}, + {"*SigsetT.Sigtimedwait", c.Func((*SigsetT).Sigtimedwait)}, + {"Sigqueue", c.Func(Sigqueue)}, + {"*Sigcontext.Sigreturn", c.Func((*Sigcontext).Sigreturn)}, + {"Siginterrupt", c.Func(Siginterrupt)}, + {"Sigstack", c.Func(Sigstack)}, + {"*Sigaltstack.Sigaltstack", c.Func((*Sigaltstack).Sigaltstack)}, + {"TimerCreate", c.Func(TimerCreate)}, + } + var signalFunctionPrototypes = []struct { + name string + signature reflect.Type + inputs []signalABISlot + output *signalABISlot + variadic bool + }{ + {"NativeSignal", reflect.TypeOf(NativeSignal), []signalABISlot{{4, 4, 1}, {8, 8, 5}}, &signalABISlot{8, 8, 5}, false}, + {"Kill", reflect.TypeOf(Kill), []signalABISlot{{4, 4, 1}, {4, 4, 1}}, &signalABISlot{4, 4, 1}, false}, + {"Killpg", reflect.TypeOf(Killpg), []signalABISlot{{4, 4, 1}, {4, 4, 1}}, &signalABISlot{4, 4, 1}, false}, + {"Raise", reflect.TypeOf(Raise), []signalABISlot{{4, 4, 1}}, &signalABISlot{4, 4, 1}, false}, + {"Ssignal", reflect.TypeOf(Ssignal), []signalABISlot{{4, 4, 1}, {8, 8, 5}}, &signalABISlot{8, 8, 5}, false}, + {"Gsignal", reflect.TypeOf(Gsignal), []signalABISlot{{4, 4, 1}}, &signalABISlot{4, 4, 1}, false}, + {"Psignal", reflect.TypeOf(Psignal), []signalABISlot{{4, 4, 1}, {8, 8, 5}}, nil, false}, + {"*SiginfoT.Psiginfo", reflect.TypeOf((*SiginfoT).Psiginfo), []signalABISlot{{8, 8, 5}, {8, 8, 5}}, nil, false}, + {"Sigblock", reflect.TypeOf(Sigblock), []signalABISlot{{4, 4, 1}}, &signalABISlot{4, 4, 1}, false}, + {"Sigsetmask", reflect.TypeOf(Sigsetmask), []signalABISlot{{4, 4, 1}}, &signalABISlot{4, 4, 1}, false}, + {"Siggetmask", reflect.TypeOf(Siggetmask), []signalABISlot{}, &signalABISlot{4, 4, 1}, false}, + {"*SigsetT.Sigemptyset", reflect.TypeOf((*SigsetT).Sigemptyset), []signalABISlot{{8, 8, 5}}, &signalABISlot{4, 4, 1}, false}, + {"*SigsetT.Sigfillset", reflect.TypeOf((*SigsetT).Sigfillset), []signalABISlot{{8, 8, 5}}, &signalABISlot{4, 4, 1}, false}, + {"*SigsetT.Sigaddset", reflect.TypeOf((*SigsetT).Sigaddset), []signalABISlot{{8, 8, 5}, {4, 4, 1}}, &signalABISlot{4, 4, 1}, false}, + {"*SigsetT.Sigdelset", reflect.TypeOf((*SigsetT).Sigdelset), []signalABISlot{{8, 8, 5}, {4, 4, 1}}, &signalABISlot{4, 4, 1}, false}, + {"*SigsetT.Sigismember", reflect.TypeOf((*SigsetT).Sigismember), []signalABISlot{{8, 8, 5}, {4, 4, 1}}, &signalABISlot{4, 4, 1}, false}, + {"Sigprocmask", reflect.TypeOf(Sigprocmask), []signalABISlot{{4, 4, 1}, {8, 8, 5}, {8, 8, 5}}, &signalABISlot{4, 4, 1}, false}, + {"*SigsetT.Sigsuspend", reflect.TypeOf((*SigsetT).Sigsuspend), []signalABISlot{{8, 8, 5}}, &signalABISlot{4, 4, 1}, false}, + {"Sigaction", reflect.TypeOf(Sigaction), []signalABISlot{{4, 4, 1}, {8, 8, 5}, {8, 8, 5}}, &signalABISlot{4, 4, 1}, false}, + {"*SigsetT.Sigpending", reflect.TypeOf((*SigsetT).Sigpending), []signalABISlot{{8, 8, 5}}, &signalABISlot{4, 4, 1}, false}, + {"*SigsetT.Sigwait", reflect.TypeOf((*SigsetT).Sigwait), []signalABISlot{{8, 8, 5}, {8, 8, 5}}, &signalABISlot{4, 4, 1}, false}, + {"*SigsetT.Sigwaitinfo", reflect.TypeOf((*SigsetT).Sigwaitinfo), []signalABISlot{{8, 8, 5}, {8, 8, 5}}, &signalABISlot{4, 4, 1}, false}, + {"*SigsetT.Sigtimedwait", reflect.TypeOf((*SigsetT).Sigtimedwait), []signalABISlot{{8, 8, 5}, {8, 8, 5}, {8, 8, 5}}, &signalABISlot{4, 4, 1}, false}, + {"Sigqueue", reflect.TypeOf(Sigqueue), []signalABISlot{{4, 4, 1}, {4, 4, 1}, {8, 8, 13}}, &signalABISlot{4, 4, 1}, false}, + {"*Sigcontext.Sigreturn", reflect.TypeOf((*Sigcontext).Sigreturn), []signalABISlot{{8, 8, 5}}, &signalABISlot{4, 4, 1}, false}, + {"Siginterrupt", reflect.TypeOf(Siginterrupt), []signalABISlot{{4, 4, 1}, {4, 4, 1}}, &signalABISlot{4, 4, 1}, false}, + {"Sigstack", reflect.TypeOf(Sigstack), []signalABISlot{{8, 8, 5}, {8, 8, 5}}, &signalABISlot{4, 4, 1}, false}, + {"*Sigaltstack.Sigaltstack", reflect.TypeOf((*Sigaltstack).Sigaltstack), []signalABISlot{{8, 8, 5}, {8, 8, 5}}, &signalABISlot{4, 4, 1}, false}, + } + // The static assignment checks arity, result, and exact Go parameter types. + // Reflecting the full signature would require missing c/time decl-mode method wrappers. + var _ func(lltime.ClockidT, *Sigevent, *lltime.TimerT) c.Int = TimerCreate + var signalStaticFunctionPrototypes = []struct { + name string + slots []struct { + label string + goType reflect.Type + got, want signalABISlot + } + }{ + {"TimerCreate", []struct { + label string + goType reflect.Type + got, want signalABISlot + }{ + {"clock", reflect.TypeOf(lltime.ClockidT(0)), signalABISlot{}, signalABISlot{4, 4, 1}}, + {"event", nil, signalABISlot{unsafe.Sizeof((*Sigevent)(nil)), unsafe.Alignof((*Sigevent)(nil)), 5}, signalABISlot{8, 8, 5}}, + {"timer", nil, signalABISlot{unsafe.Sizeof((*lltime.TimerT)(nil)), unsafe.Alignof((*lltime.TimerT)(nil)), 5}, signalABISlot{8, 8, 5}}, + {"result", reflect.TypeOf(c.Int(0)), signalABISlot{}, signalABISlot{4, 4, 1}}, + }}, + } + var signalTypeLayouts = []struct { + symbol, property string + got, want uintptr + }{ + {"SigactionT", "size", unsafe.Sizeof(*new(SigactionT)), 152}, + {"SigactionT", "alignment", unsafe.Alignof(*new(SigactionT)), 8}, + {"SigactionT", "X__SigactionHandler offset", unsafe.Offsetof((*new(SigactionT)).X__SigactionHandler), 0}, + {"SigactionT", "X__SigactionHandler size", unsafe.Sizeof((*new(SigactionT)).X__SigactionHandler), 8}, + {"SigactionT", "X__SigactionHandler alignment", unsafe.Alignof((*new(SigactionT)).X__SigactionHandler), 8}, + {"SigactionT", "SaMask offset", unsafe.Offsetof((*new(SigactionT)).SaMask), 8}, + {"SigactionT", "SaMask size", unsafe.Sizeof((*new(SigactionT)).SaMask), 128}, + {"SigactionT", "SaMask alignment", unsafe.Alignof((*new(SigactionT)).SaMask), 8}, + {"SigactionT", "SaFlags offset", unsafe.Offsetof((*new(SigactionT)).SaFlags), 136}, + {"SigactionT", "SaFlags size", unsafe.Sizeof((*new(SigactionT)).SaFlags), 4}, + {"SigactionT", "SaFlags alignment", unsafe.Alignof((*new(SigactionT)).SaFlags), 4}, + {"SigactionT", "SaRestorer offset", unsafe.Offsetof((*new(SigactionT)).SaRestorer), 144}, + {"SigactionT", "SaRestorer size", unsafe.Sizeof((*new(SigactionT)).SaRestorer), 8}, + {"SigactionT", "SaRestorer alignment", unsafe.Alignof((*new(SigactionT)).SaRestorer), 8}, + {"X_fpxreg", "size", unsafe.Sizeof(*new(X_fpxreg)), 16}, + {"X_fpxreg", "alignment", unsafe.Alignof(*new(X_fpxreg)), 2}, + {"X_fpxreg", "Significand offset", unsafe.Offsetof((*new(X_fpxreg)).Significand), 0}, + {"X_fpxreg", "Significand size", unsafe.Sizeof((*new(X_fpxreg)).Significand), 8}, + {"X_fpxreg", "Significand alignment", unsafe.Alignof((*new(X_fpxreg)).Significand), 2}, + {"X_fpxreg", "Exponent offset", unsafe.Offsetof((*new(X_fpxreg)).Exponent), 8}, + {"X_fpxreg", "Exponent size", unsafe.Sizeof((*new(X_fpxreg)).Exponent), 2}, + {"X_fpxreg", "Exponent alignment", unsafe.Alignof((*new(X_fpxreg)).Exponent), 2}, + {"X_fpxreg", "Padding offset", unsafe.Offsetof((*new(X_fpxreg)).Padding), 10}, + {"X_fpxreg", "Padding size", unsafe.Sizeof((*new(X_fpxreg)).Padding), 6}, + {"X_fpxreg", "Padding alignment", unsafe.Alignof((*new(X_fpxreg)).Padding), 2}, + {"X_xmmreg", "size", unsafe.Sizeof(*new(X_xmmreg)), 16}, + {"X_xmmreg", "alignment", unsafe.Alignof(*new(X_xmmreg)), 4}, + {"X_xmmreg", "Element offset", unsafe.Offsetof((*new(X_xmmreg)).Element), 0}, + {"X_xmmreg", "Element size", unsafe.Sizeof((*new(X_xmmreg)).Element), 16}, + {"X_xmmreg", "Element alignment", unsafe.Alignof((*new(X_xmmreg)).Element), 4}, + {"X_fpstate", "size", unsafe.Sizeof(*new(X_fpstate)), 512}, + {"X_fpstate", "alignment", unsafe.Alignof(*new(X_fpstate)), 8}, + {"X_fpstate", "Cwd offset", unsafe.Offsetof((*new(X_fpstate)).Cwd), 0}, + {"X_fpstate", "Cwd size", unsafe.Sizeof((*new(X_fpstate)).Cwd), 2}, + {"X_fpstate", "Cwd alignment", unsafe.Alignof((*new(X_fpstate)).Cwd), 2}, + {"X_fpstate", "Swd offset", unsafe.Offsetof((*new(X_fpstate)).Swd), 2}, + {"X_fpstate", "Swd size", unsafe.Sizeof((*new(X_fpstate)).Swd), 2}, + {"X_fpstate", "Swd alignment", unsafe.Alignof((*new(X_fpstate)).Swd), 2}, + {"X_fpstate", "Ftw offset", unsafe.Offsetof((*new(X_fpstate)).Ftw), 4}, + {"X_fpstate", "Ftw size", unsafe.Sizeof((*new(X_fpstate)).Ftw), 2}, + {"X_fpstate", "Ftw alignment", unsafe.Alignof((*new(X_fpstate)).Ftw), 2}, + {"X_fpstate", "Fop offset", unsafe.Offsetof((*new(X_fpstate)).Fop), 6}, + {"X_fpstate", "Fop size", unsafe.Sizeof((*new(X_fpstate)).Fop), 2}, + {"X_fpstate", "Fop alignment", unsafe.Alignof((*new(X_fpstate)).Fop), 2}, + {"X_fpstate", "Rip offset", unsafe.Offsetof((*new(X_fpstate)).Rip), 8}, + {"X_fpstate", "Rip size", unsafe.Sizeof((*new(X_fpstate)).Rip), 8}, + {"X_fpstate", "Rip alignment", unsafe.Alignof((*new(X_fpstate)).Rip), 8}, + {"X_fpstate", "Rdp offset", unsafe.Offsetof((*new(X_fpstate)).Rdp), 16}, + {"X_fpstate", "Rdp size", unsafe.Sizeof((*new(X_fpstate)).Rdp), 8}, + {"X_fpstate", "Rdp alignment", unsafe.Alignof((*new(X_fpstate)).Rdp), 8}, + {"X_fpstate", "Mxcsr offset", unsafe.Offsetof((*new(X_fpstate)).Mxcsr), 24}, + {"X_fpstate", "Mxcsr size", unsafe.Sizeof((*new(X_fpstate)).Mxcsr), 4}, + {"X_fpstate", "Mxcsr alignment", unsafe.Alignof((*new(X_fpstate)).Mxcsr), 4}, + {"X_fpstate", "MxcrMask offset", unsafe.Offsetof((*new(X_fpstate)).MxcrMask), 28}, + {"X_fpstate", "MxcrMask size", unsafe.Sizeof((*new(X_fpstate)).MxcrMask), 4}, + {"X_fpstate", "MxcrMask alignment", unsafe.Alignof((*new(X_fpstate)).MxcrMask), 4}, + {"X_fpstate", "X_st offset", unsafe.Offsetof((*new(X_fpstate)).X_st), 32}, + {"X_fpstate", "X_st size", unsafe.Sizeof((*new(X_fpstate)).X_st), 128}, + {"X_fpstate", "X_st alignment", unsafe.Alignof((*new(X_fpstate)).X_st), 2}, + {"X_fpstate", "X_xmm offset", unsafe.Offsetof((*new(X_fpstate)).X_xmm), 160}, + {"X_fpstate", "X_xmm size", unsafe.Sizeof((*new(X_fpstate)).X_xmm), 256}, + {"X_fpstate", "X_xmm alignment", unsafe.Alignof((*new(X_fpstate)).X_xmm), 4}, + {"X_fpstate", "Padding offset", unsafe.Offsetof((*new(X_fpstate)).Padding), 416}, + {"X_fpstate", "Padding size", unsafe.Sizeof((*new(X_fpstate)).Padding), 96}, + {"X_fpstate", "Padding alignment", unsafe.Alignof((*new(X_fpstate)).Padding), 4}, + {"Sigcontext", "size", unsafe.Sizeof(*new(Sigcontext)), 256}, + {"Sigcontext", "alignment", unsafe.Alignof(*new(Sigcontext)), 8}, + {"Sigcontext", "R8 offset", unsafe.Offsetof((*new(Sigcontext)).R8), 0}, + {"Sigcontext", "R8 size", unsafe.Sizeof((*new(Sigcontext)).R8), 8}, + {"Sigcontext", "R8 alignment", unsafe.Alignof((*new(Sigcontext)).R8), 8}, + {"Sigcontext", "R9 offset", unsafe.Offsetof((*new(Sigcontext)).R9), 8}, + {"Sigcontext", "R9 size", unsafe.Sizeof((*new(Sigcontext)).R9), 8}, + {"Sigcontext", "R9 alignment", unsafe.Alignof((*new(Sigcontext)).R9), 8}, + {"Sigcontext", "R10 offset", unsafe.Offsetof((*new(Sigcontext)).R10), 16}, + {"Sigcontext", "R10 size", unsafe.Sizeof((*new(Sigcontext)).R10), 8}, + {"Sigcontext", "R10 alignment", unsafe.Alignof((*new(Sigcontext)).R10), 8}, + {"Sigcontext", "R11 offset", unsafe.Offsetof((*new(Sigcontext)).R11), 24}, + {"Sigcontext", "R11 size", unsafe.Sizeof((*new(Sigcontext)).R11), 8}, + {"Sigcontext", "R11 alignment", unsafe.Alignof((*new(Sigcontext)).R11), 8}, + {"Sigcontext", "R12 offset", unsafe.Offsetof((*new(Sigcontext)).R12), 32}, + {"Sigcontext", "R12 size", unsafe.Sizeof((*new(Sigcontext)).R12), 8}, + {"Sigcontext", "R12 alignment", unsafe.Alignof((*new(Sigcontext)).R12), 8}, + {"Sigcontext", "R13 offset", unsafe.Offsetof((*new(Sigcontext)).R13), 40}, + {"Sigcontext", "R13 size", unsafe.Sizeof((*new(Sigcontext)).R13), 8}, + {"Sigcontext", "R13 alignment", unsafe.Alignof((*new(Sigcontext)).R13), 8}, + {"Sigcontext", "R14 offset", unsafe.Offsetof((*new(Sigcontext)).R14), 48}, + {"Sigcontext", "R14 size", unsafe.Sizeof((*new(Sigcontext)).R14), 8}, + {"Sigcontext", "R14 alignment", unsafe.Alignof((*new(Sigcontext)).R14), 8}, + {"Sigcontext", "R15 offset", unsafe.Offsetof((*new(Sigcontext)).R15), 56}, + {"Sigcontext", "R15 size", unsafe.Sizeof((*new(Sigcontext)).R15), 8}, + {"Sigcontext", "R15 alignment", unsafe.Alignof((*new(Sigcontext)).R15), 8}, + {"Sigcontext", "Rdi offset", unsafe.Offsetof((*new(Sigcontext)).Rdi), 64}, + {"Sigcontext", "Rdi size", unsafe.Sizeof((*new(Sigcontext)).Rdi), 8}, + {"Sigcontext", "Rdi alignment", unsafe.Alignof((*new(Sigcontext)).Rdi), 8}, + {"Sigcontext", "Rsi offset", unsafe.Offsetof((*new(Sigcontext)).Rsi), 72}, + {"Sigcontext", "Rsi size", unsafe.Sizeof((*new(Sigcontext)).Rsi), 8}, + {"Sigcontext", "Rsi alignment", unsafe.Alignof((*new(Sigcontext)).Rsi), 8}, + {"Sigcontext", "Rbp offset", unsafe.Offsetof((*new(Sigcontext)).Rbp), 80}, + {"Sigcontext", "Rbp size", unsafe.Sizeof((*new(Sigcontext)).Rbp), 8}, + {"Sigcontext", "Rbp alignment", unsafe.Alignof((*new(Sigcontext)).Rbp), 8}, + {"Sigcontext", "Rbx offset", unsafe.Offsetof((*new(Sigcontext)).Rbx), 88}, + {"Sigcontext", "Rbx size", unsafe.Sizeof((*new(Sigcontext)).Rbx), 8}, + {"Sigcontext", "Rbx alignment", unsafe.Alignof((*new(Sigcontext)).Rbx), 8}, + {"Sigcontext", "Rdx offset", unsafe.Offsetof((*new(Sigcontext)).Rdx), 96}, + {"Sigcontext", "Rdx size", unsafe.Sizeof((*new(Sigcontext)).Rdx), 8}, + {"Sigcontext", "Rdx alignment", unsafe.Alignof((*new(Sigcontext)).Rdx), 8}, + {"Sigcontext", "Rax offset", unsafe.Offsetof((*new(Sigcontext)).Rax), 104}, + {"Sigcontext", "Rax size", unsafe.Sizeof((*new(Sigcontext)).Rax), 8}, + {"Sigcontext", "Rax alignment", unsafe.Alignof((*new(Sigcontext)).Rax), 8}, + {"Sigcontext", "Rcx offset", unsafe.Offsetof((*new(Sigcontext)).Rcx), 112}, + {"Sigcontext", "Rcx size", unsafe.Sizeof((*new(Sigcontext)).Rcx), 8}, + {"Sigcontext", "Rcx alignment", unsafe.Alignof((*new(Sigcontext)).Rcx), 8}, + {"Sigcontext", "Rsp offset", unsafe.Offsetof((*new(Sigcontext)).Rsp), 120}, + {"Sigcontext", "Rsp size", unsafe.Sizeof((*new(Sigcontext)).Rsp), 8}, + {"Sigcontext", "Rsp alignment", unsafe.Alignof((*new(Sigcontext)).Rsp), 8}, + {"Sigcontext", "Rip offset", unsafe.Offsetof((*new(Sigcontext)).Rip), 128}, + {"Sigcontext", "Rip size", unsafe.Sizeof((*new(Sigcontext)).Rip), 8}, + {"Sigcontext", "Rip alignment", unsafe.Alignof((*new(Sigcontext)).Rip), 8}, + {"Sigcontext", "Eflags offset", unsafe.Offsetof((*new(Sigcontext)).Eflags), 136}, + {"Sigcontext", "Eflags size", unsafe.Sizeof((*new(Sigcontext)).Eflags), 8}, + {"Sigcontext", "Eflags alignment", unsafe.Alignof((*new(Sigcontext)).Eflags), 8}, + {"Sigcontext", "Cs offset", unsafe.Offsetof((*new(Sigcontext)).Cs), 144}, + {"Sigcontext", "Cs size", unsafe.Sizeof((*new(Sigcontext)).Cs), 2}, + {"Sigcontext", "Cs alignment", unsafe.Alignof((*new(Sigcontext)).Cs), 2}, + {"Sigcontext", "Gs offset", unsafe.Offsetof((*new(Sigcontext)).Gs), 146}, + {"Sigcontext", "Gs size", unsafe.Sizeof((*new(Sigcontext)).Gs), 2}, + {"Sigcontext", "Gs alignment", unsafe.Alignof((*new(Sigcontext)).Gs), 2}, + {"Sigcontext", "Fs offset", unsafe.Offsetof((*new(Sigcontext)).Fs), 148}, + {"Sigcontext", "Fs size", unsafe.Sizeof((*new(Sigcontext)).Fs), 2}, + {"Sigcontext", "Fs alignment", unsafe.Alignof((*new(Sigcontext)).Fs), 2}, + {"Sigcontext", "X__Pad0 offset", unsafe.Offsetof((*new(Sigcontext)).X__Pad0), 150}, + {"Sigcontext", "X__Pad0 size", unsafe.Sizeof((*new(Sigcontext)).X__Pad0), 2}, + {"Sigcontext", "X__Pad0 alignment", unsafe.Alignof((*new(Sigcontext)).X__Pad0), 2}, + {"Sigcontext", "Err offset", unsafe.Offsetof((*new(Sigcontext)).Err), 152}, + {"Sigcontext", "Err size", unsafe.Sizeof((*new(Sigcontext)).Err), 8}, + {"Sigcontext", "Err alignment", unsafe.Alignof((*new(Sigcontext)).Err), 8}, + {"Sigcontext", "Trapno offset", unsafe.Offsetof((*new(Sigcontext)).Trapno), 160}, + {"Sigcontext", "Trapno size", unsafe.Sizeof((*new(Sigcontext)).Trapno), 8}, + {"Sigcontext", "Trapno alignment", unsafe.Alignof((*new(Sigcontext)).Trapno), 8}, + {"Sigcontext", "Oldmask offset", unsafe.Offsetof((*new(Sigcontext)).Oldmask), 168}, + {"Sigcontext", "Oldmask size", unsafe.Sizeof((*new(Sigcontext)).Oldmask), 8}, + {"Sigcontext", "Oldmask alignment", unsafe.Alignof((*new(Sigcontext)).Oldmask), 8}, + {"Sigcontext", "Cr2 offset", unsafe.Offsetof((*new(Sigcontext)).Cr2), 176}, + {"Sigcontext", "Cr2 size", unsafe.Sizeof((*new(Sigcontext)).Cr2), 8}, + {"Sigcontext", "Cr2 alignment", unsafe.Alignof((*new(Sigcontext)).Cr2), 8}, + {"Sigcontext", "X__Reserved1 offset", unsafe.Offsetof((*new(Sigcontext)).X__Reserved1), 192}, + {"Sigcontext", "X__Reserved1 size", unsafe.Sizeof((*new(Sigcontext)).X__Reserved1), 64}, + {"Sigcontext", "X__Reserved1 alignment", unsafe.Alignof((*new(Sigcontext)).X__Reserved1), 8}, + {"Sigval", "size", unsafe.Sizeof(*new(Sigval)), 8}, + {"Sigval", "alignment", unsafe.Alignof(*new(Sigval)), 8}, + {"SiginfoT", "size", unsafe.Sizeof(*new(SiginfoT)), 128}, + {"SiginfoT", "alignment", unsafe.Alignof(*new(SiginfoT)), 8}, + {"SiginfoT", "SiSigno offset", unsafe.Offsetof((*new(SiginfoT)).SiSigno), 0}, + {"SiginfoT", "SiSigno size", unsafe.Sizeof((*new(SiginfoT)).SiSigno), 4}, + {"SiginfoT", "SiSigno alignment", unsafe.Alignof((*new(SiginfoT)).SiSigno), 4}, + {"SiginfoT", "SiErrno offset", unsafe.Offsetof((*new(SiginfoT)).SiErrno), 4}, + {"SiginfoT", "SiErrno size", unsafe.Sizeof((*new(SiginfoT)).SiErrno), 4}, + {"SiginfoT", "SiErrno alignment", unsafe.Alignof((*new(SiginfoT)).SiErrno), 4}, + {"SiginfoT", "SiCode offset", unsafe.Offsetof((*new(SiginfoT)).SiCode), 8}, + {"SiginfoT", "SiCode size", unsafe.Sizeof((*new(SiginfoT)).SiCode), 4}, + {"SiginfoT", "SiCode alignment", unsafe.Alignof((*new(SiginfoT)).SiCode), 4}, + {"SiginfoT", "X_sifields offset", unsafe.Offsetof((*new(SiginfoT)).X_sifields), 16}, + {"SiginfoT", "X_sifields size", unsafe.Sizeof((*new(SiginfoT)).X_sifields), 112}, + {"SiginfoT", "X_sifields alignment", unsafe.Alignof((*new(SiginfoT)).X_sifields), 8}, + {"Sigevent", "size", unsafe.Sizeof(*new(Sigevent)), 64}, + {"Sigevent", "alignment", unsafe.Alignof(*new(Sigevent)), 8}, + {"Sigevent", "SigevValue offset", unsafe.Offsetof((*new(Sigevent)).SigevValue), 0}, + {"Sigevent", "SigevValue size", unsafe.Sizeof((*new(Sigevent)).SigevValue), 8}, + {"Sigevent", "SigevValue alignment", unsafe.Alignof((*new(Sigevent)).SigevValue), 8}, + {"Sigevent", "SigevSigno offset", unsafe.Offsetof((*new(Sigevent)).SigevSigno), 8}, + {"Sigevent", "SigevSigno size", unsafe.Sizeof((*new(Sigevent)).SigevSigno), 4}, + {"Sigevent", "SigevSigno alignment", unsafe.Alignof((*new(Sigevent)).SigevSigno), 4}, + {"Sigevent", "SigevNotify offset", unsafe.Offsetof((*new(Sigevent)).SigevNotify), 12}, + {"Sigevent", "SigevNotify size", unsafe.Sizeof((*new(Sigevent)).SigevNotify), 4}, + {"Sigevent", "SigevNotify alignment", unsafe.Alignof((*new(Sigevent)).SigevNotify), 4}, + {"Sigevent", "X_sigevUn offset", unsafe.Offsetof((*new(Sigevent)).X_sigevUn), 16}, + {"Sigevent", "X_sigevUn size", unsafe.Sizeof((*new(Sigevent)).X_sigevUn), 48}, + {"Sigevent", "X_sigevUn alignment", unsafe.Alignof((*new(Sigevent)).X_sigevUn), 8}, + {"SigvalT", "size", unsafe.Sizeof(*new(SigvalT)), 8}, + {"SigvalT", "alignment", unsafe.Alignof(*new(SigvalT)), 8}, + {"SigstackT", "size", unsafe.Sizeof(*new(SigstackT)), 16}, + {"SigstackT", "alignment", unsafe.Alignof(*new(SigstackT)), 8}, + {"SigstackT", "SsSp offset", unsafe.Offsetof((*new(SigstackT)).SsSp), 0}, + {"SigstackT", "SsSp size", unsafe.Sizeof((*new(SigstackT)).SsSp), 8}, + {"SigstackT", "SsSp alignment", unsafe.Alignof((*new(SigstackT)).SsSp), 8}, + {"SigstackT", "SsOnstack offset", unsafe.Offsetof((*new(SigstackT)).SsOnstack), 8}, + {"SigstackT", "SsOnstack size", unsafe.Sizeof((*new(SigstackT)).SsOnstack), 4}, + {"SigstackT", "SsOnstack alignment", unsafe.Alignof((*new(SigstackT)).SsOnstack), 4}, + {"Sigaltstack", "size", unsafe.Sizeof(*new(Sigaltstack)), 24}, + {"Sigaltstack", "alignment", unsafe.Alignof(*new(Sigaltstack)), 8}, + {"Sigaltstack", "SsSp offset", unsafe.Offsetof((*new(Sigaltstack)).SsSp), 0}, + {"Sigaltstack", "SsSp size", unsafe.Sizeof((*new(Sigaltstack)).SsSp), 8}, + {"Sigaltstack", "SsSp alignment", unsafe.Alignof((*new(Sigaltstack)).SsSp), 8}, + {"Sigaltstack", "SsFlags offset", unsafe.Offsetof((*new(Sigaltstack)).SsFlags), 8}, + {"Sigaltstack", "SsFlags size", unsafe.Sizeof((*new(Sigaltstack)).SsFlags), 4}, + {"Sigaltstack", "SsFlags alignment", unsafe.Alignof((*new(Sigaltstack)).SsFlags), 4}, + {"Sigaltstack", "SsSize offset", unsafe.Offsetof((*new(Sigaltstack)).SsSize), 16}, + {"Sigaltstack", "SsSize size", unsafe.Sizeof((*new(Sigaltstack)).SsSize), 8}, + {"Sigaltstack", "SsSize alignment", unsafe.Alignof((*new(Sigaltstack)).SsSize), 8}, + {"X__SighandlerT", "size", unsafe.Sizeof(*new(X__SighandlerT)), 8}, + {"X__SighandlerT", "alignment", unsafe.Alignof(*new(X__SighandlerT)), 8}, + {"SigsetT", "size", unsafe.Sizeof(*new(SigsetT)), 128}, + {"SigsetT", "alignment", unsafe.Alignof(*new(SigsetT)), 8}, + {"X__SigsetT", "size", unsafe.Sizeof(*new(X__SigsetT)), 128}, + {"X__SigsetT", "alignment", unsafe.Alignof(*new(X__SigsetT)), 8}, + {"X__SigsetT", "X__Val offset", unsafe.Offsetof((*new(X__SigsetT)).X__Val), 0}, + {"X__SigsetT", "X__Val size", unsafe.Sizeof((*new(X__SigsetT)).X__Val), 128}, + {"X__SigsetT", "X__Val alignment", unsafe.Alignof((*new(X__SigsetT)).X__Val), 8}, + {"SignalHandler", "size", unsafe.Sizeof(*new(SignalHandler)), 8}, + {"SignalHandler", "alignment", unsafe.Alignof(*new(SignalHandler)), 8}, + {"SigeventT", "size", unsafe.Sizeof(*new(SigeventT)), 64}, + {"SigeventT", "alignment", unsafe.Alignof(*new(SigeventT)), 8}, + {"_llcppg_anon_7", "size", unsafe.Sizeof(*new(_llcppg_anon_7)), 8}, + {"_llcppg_anon_7", "alignment", unsafe.Alignof(*new(_llcppg_anon_7)), 8}, + {"_llcppg_anon_5", "size", unsafe.Sizeof(*new(_llcppg_anon_5)), 112}, + {"_llcppg_anon_5", "alignment", unsafe.Alignof(*new(_llcppg_anon_5)), 8}, + {"_llcppg_anon_6", "size", unsafe.Sizeof(*new(_llcppg_anon_6)), 48}, + {"_llcppg_anon_6", "alignment", unsafe.Alignof(*new(_llcppg_anon_6)), 8}, + {"_llcppg_anon_24", "size", unsafe.Sizeof(*new(_llcppg_anon_24)), 8}, + {"_llcppg_anon_24", "alignment", unsafe.Alignof(*new(_llcppg_anon_24)), 4}, + {"_llcppg_anon_24", "SiPid offset", unsafe.Offsetof((*new(_llcppg_anon_24)).SiPid), 0}, + {"_llcppg_anon_24", "SiPid size", unsafe.Sizeof((*new(_llcppg_anon_24)).SiPid), 4}, + {"_llcppg_anon_24", "SiPid alignment", unsafe.Alignof((*new(_llcppg_anon_24)).SiPid), 4}, + {"_llcppg_anon_24", "SiUid offset", unsafe.Offsetof((*new(_llcppg_anon_24)).SiUid), 4}, + {"_llcppg_anon_24", "SiUid size", unsafe.Sizeof((*new(_llcppg_anon_24)).SiUid), 4}, + {"_llcppg_anon_24", "SiUid alignment", unsafe.Alignof((*new(_llcppg_anon_24)).SiUid), 4}, + {"_llcppg_anon_25", "size", unsafe.Sizeof(*new(_llcppg_anon_25)), 16}, + {"_llcppg_anon_25", "alignment", unsafe.Alignof(*new(_llcppg_anon_25)), 8}, + {"_llcppg_anon_25", "SiTid offset", unsafe.Offsetof((*new(_llcppg_anon_25)).SiTid), 0}, + {"_llcppg_anon_25", "SiTid size", unsafe.Sizeof((*new(_llcppg_anon_25)).SiTid), 4}, + {"_llcppg_anon_25", "SiTid alignment", unsafe.Alignof((*new(_llcppg_anon_25)).SiTid), 4}, + {"_llcppg_anon_25", "SiOverrun offset", unsafe.Offsetof((*new(_llcppg_anon_25)).SiOverrun), 4}, + {"_llcppg_anon_25", "SiOverrun size", unsafe.Sizeof((*new(_llcppg_anon_25)).SiOverrun), 4}, + {"_llcppg_anon_25", "SiOverrun alignment", unsafe.Alignof((*new(_llcppg_anon_25)).SiOverrun), 4}, + {"_llcppg_anon_25", "SiSigval offset", unsafe.Offsetof((*new(_llcppg_anon_25)).SiSigval), 8}, + {"_llcppg_anon_25", "SiSigval size", unsafe.Sizeof((*new(_llcppg_anon_25)).SiSigval), 8}, + {"_llcppg_anon_25", "SiSigval alignment", unsafe.Alignof((*new(_llcppg_anon_25)).SiSigval), 8}, + {"_llcppg_anon_26", "size", unsafe.Sizeof(*new(_llcppg_anon_26)), 16}, + {"_llcppg_anon_26", "alignment", unsafe.Alignof(*new(_llcppg_anon_26)), 8}, + {"_llcppg_anon_26", "SiPid offset", unsafe.Offsetof((*new(_llcppg_anon_26)).SiPid), 0}, + {"_llcppg_anon_26", "SiPid size", unsafe.Sizeof((*new(_llcppg_anon_26)).SiPid), 4}, + {"_llcppg_anon_26", "SiPid alignment", unsafe.Alignof((*new(_llcppg_anon_26)).SiPid), 4}, + {"_llcppg_anon_26", "SiUid offset", unsafe.Offsetof((*new(_llcppg_anon_26)).SiUid), 4}, + {"_llcppg_anon_26", "SiUid size", unsafe.Sizeof((*new(_llcppg_anon_26)).SiUid), 4}, + {"_llcppg_anon_26", "SiUid alignment", unsafe.Alignof((*new(_llcppg_anon_26)).SiUid), 4}, + {"_llcppg_anon_26", "SiSigval offset", unsafe.Offsetof((*new(_llcppg_anon_26)).SiSigval), 8}, + {"_llcppg_anon_26", "SiSigval size", unsafe.Sizeof((*new(_llcppg_anon_26)).SiSigval), 8}, + {"_llcppg_anon_26", "SiSigval alignment", unsafe.Alignof((*new(_llcppg_anon_26)).SiSigval), 8}, + {"_llcppg_anon_27", "size", unsafe.Sizeof(*new(_llcppg_anon_27)), 32}, + {"_llcppg_anon_27", "alignment", unsafe.Alignof(*new(_llcppg_anon_27)), 8}, + {"_llcppg_anon_27", "SiPid offset", unsafe.Offsetof((*new(_llcppg_anon_27)).SiPid), 0}, + {"_llcppg_anon_27", "SiPid size", unsafe.Sizeof((*new(_llcppg_anon_27)).SiPid), 4}, + {"_llcppg_anon_27", "SiPid alignment", unsafe.Alignof((*new(_llcppg_anon_27)).SiPid), 4}, + {"_llcppg_anon_27", "SiUid offset", unsafe.Offsetof((*new(_llcppg_anon_27)).SiUid), 4}, + {"_llcppg_anon_27", "SiUid size", unsafe.Sizeof((*new(_llcppg_anon_27)).SiUid), 4}, + {"_llcppg_anon_27", "SiUid alignment", unsafe.Alignof((*new(_llcppg_anon_27)).SiUid), 4}, + {"_llcppg_anon_27", "SiStatus offset", unsafe.Offsetof((*new(_llcppg_anon_27)).SiStatus), 8}, + {"_llcppg_anon_27", "SiStatus size", unsafe.Sizeof((*new(_llcppg_anon_27)).SiStatus), 4}, + {"_llcppg_anon_27", "SiStatus alignment", unsafe.Alignof((*new(_llcppg_anon_27)).SiStatus), 4}, + {"_llcppg_anon_27", "SiUtime offset", unsafe.Offsetof((*new(_llcppg_anon_27)).SiUtime), 16}, + {"_llcppg_anon_27", "SiUtime size", unsafe.Sizeof((*new(_llcppg_anon_27)).SiUtime), 8}, + {"_llcppg_anon_27", "SiUtime alignment", unsafe.Alignof((*new(_llcppg_anon_27)).SiUtime), 8}, + {"_llcppg_anon_27", "SiStime offset", unsafe.Offsetof((*new(_llcppg_anon_27)).SiStime), 24}, + {"_llcppg_anon_27", "SiStime size", unsafe.Sizeof((*new(_llcppg_anon_27)).SiStime), 8}, + {"_llcppg_anon_27", "SiStime alignment", unsafe.Alignof((*new(_llcppg_anon_27)).SiStime), 8}, + {"_llcppg_anon_28", "size", unsafe.Sizeof(*new(_llcppg_anon_28)), 32}, + {"_llcppg_anon_28", "alignment", unsafe.Alignof(*new(_llcppg_anon_28)), 8}, + {"_llcppg_anon_28", "SiAddr offset", unsafe.Offsetof((*new(_llcppg_anon_28)).SiAddr), 0}, + {"_llcppg_anon_28", "SiAddr size", unsafe.Sizeof((*new(_llcppg_anon_28)).SiAddr), 8}, + {"_llcppg_anon_28", "SiAddr alignment", unsafe.Alignof((*new(_llcppg_anon_28)).SiAddr), 8}, + {"_llcppg_anon_28", "SiAddrLsb offset", unsafe.Offsetof((*new(_llcppg_anon_28)).SiAddrLsb), 8}, + {"_llcppg_anon_28", "SiAddrLsb size", unsafe.Sizeof((*new(_llcppg_anon_28)).SiAddrLsb), 2}, + {"_llcppg_anon_28", "SiAddrLsb alignment", unsafe.Alignof((*new(_llcppg_anon_28)).SiAddrLsb), 2}, + {"_llcppg_anon_28", "SiAddrBnd offset", unsafe.Offsetof((*new(_llcppg_anon_28)).SiAddrBnd), 16}, + {"_llcppg_anon_28", "SiAddrBnd size", unsafe.Sizeof((*new(_llcppg_anon_28)).SiAddrBnd), 16}, + {"_llcppg_anon_28", "SiAddrBnd alignment", unsafe.Alignof((*new(_llcppg_anon_28)).SiAddrBnd), 8}, + {"_llcppg_anon_30", "size", unsafe.Sizeof(*new(_llcppg_anon_30)), 16}, + {"_llcppg_anon_30", "alignment", unsafe.Alignof(*new(_llcppg_anon_30)), 8}, + {"_llcppg_anon_30", "SiBand offset", unsafe.Offsetof((*new(_llcppg_anon_30)).SiBand), 0}, + {"_llcppg_anon_30", "SiBand size", unsafe.Sizeof((*new(_llcppg_anon_30)).SiBand), 8}, + {"_llcppg_anon_30", "SiBand alignment", unsafe.Alignof((*new(_llcppg_anon_30)).SiBand), 8}, + {"_llcppg_anon_30", "SiFd offset", unsafe.Offsetof((*new(_llcppg_anon_30)).SiFd), 8}, + {"_llcppg_anon_30", "SiFd size", unsafe.Sizeof((*new(_llcppg_anon_30)).SiFd), 4}, + {"_llcppg_anon_30", "SiFd alignment", unsafe.Alignof((*new(_llcppg_anon_30)).SiFd), 4}, + {"_llcppg_anon_31", "size", unsafe.Sizeof(*new(_llcppg_anon_31)), 16}, + {"_llcppg_anon_31", "alignment", unsafe.Alignof(*new(_llcppg_anon_31)), 8}, + {"_llcppg_anon_31", "X_callAddr offset", unsafe.Offsetof((*new(_llcppg_anon_31)).X_callAddr), 0}, + {"_llcppg_anon_31", "X_callAddr size", unsafe.Sizeof((*new(_llcppg_anon_31)).X_callAddr), 8}, + {"_llcppg_anon_31", "X_callAddr alignment", unsafe.Alignof((*new(_llcppg_anon_31)).X_callAddr), 8}, + {"_llcppg_anon_31", "X_syscall offset", unsafe.Offsetof((*new(_llcppg_anon_31)).X_syscall), 8}, + {"_llcppg_anon_31", "X_syscall size", unsafe.Sizeof((*new(_llcppg_anon_31)).X_syscall), 4}, + {"_llcppg_anon_31", "X_syscall alignment", unsafe.Alignof((*new(_llcppg_anon_31)).X_syscall), 4}, + {"_llcppg_anon_31", "X_arch offset", unsafe.Offsetof((*new(_llcppg_anon_31)).X_arch), 12}, + {"_llcppg_anon_31", "X_arch size", unsafe.Sizeof((*new(_llcppg_anon_31)).X_arch), 4}, + {"_llcppg_anon_31", "X_arch alignment", unsafe.Alignof((*new(_llcppg_anon_31)).X_arch), 4}, + {"_llcppg_anon_32", "size", unsafe.Sizeof(*new(_llcppg_anon_32)), 16}, + {"_llcppg_anon_32", "alignment", unsafe.Alignof(*new(_llcppg_anon_32)), 8}, + {"_llcppg_anon_32", "X_function offset", unsafe.Offsetof((*new(_llcppg_anon_32)).X_function), 0}, + {"_llcppg_anon_32", "X_function size", unsafe.Sizeof((*new(_llcppg_anon_32)).X_function), 8}, + {"_llcppg_anon_32", "X_function alignment", unsafe.Alignof((*new(_llcppg_anon_32)).X_function), 8}, + {"_llcppg_anon_32", "X_attribute offset", unsafe.Offsetof((*new(_llcppg_anon_32)).X_attribute), 8}, + {"_llcppg_anon_32", "X_attribute size", unsafe.Sizeof((*new(_llcppg_anon_32)).X_attribute), 8}, + {"_llcppg_anon_32", "X_attribute alignment", unsafe.Alignof((*new(_llcppg_anon_32)).X_attribute), 8}, + {"_llcppg_anon_29", "size", unsafe.Sizeof(*new(_llcppg_anon_29)), 16}, + {"_llcppg_anon_29", "alignment", unsafe.Alignof(*new(_llcppg_anon_29)), 8}, + {"_llcppg_anon_29", "X_lower offset", unsafe.Offsetof((*new(_llcppg_anon_29)).X_lower), 0}, + {"_llcppg_anon_29", "X_lower size", unsafe.Sizeof((*new(_llcppg_anon_29)).X_lower), 8}, + {"_llcppg_anon_29", "X_lower alignment", unsafe.Alignof((*new(_llcppg_anon_29)).X_lower), 8}, + {"_llcppg_anon_29", "X_upper offset", unsafe.Offsetof((*new(_llcppg_anon_29)).X_upper), 8}, + {"_llcppg_anon_29", "X_upper size", unsafe.Sizeof((*new(_llcppg_anon_29)).X_upper), 8}, + {"_llcppg_anon_29", "X_upper alignment", unsafe.Alignof((*new(_llcppg_anon_29)).X_upper), 8}, + } + var signalIntegerConstants = []struct { + name string + got, want int64 + }{ + {"SA_NOCLDSTOP", int64(SA_NOCLDSTOP), 1}, + {"SA_NOCLDWAIT", int64(SA_NOCLDWAIT), 2}, + {"SA_SIGINFO", int64(SA_SIGINFO), 4}, + {"SA_ONSTACK", int64(SA_ONSTACK), 134217728}, + {"SA_RESTART", int64(SA_RESTART), 268435456}, + {"SA_NODEFER", int64(SA_NODEFER), 1073741824}, + {"SA_RESETHAND", int64(SA_RESETHAND), 2147483648}, + {"SA_INTERRUPT", int64(SA_INTERRUPT), 536870912}, + {"SA_NOMASK", int64(SA_NOMASK), 1073741824}, + {"SA_ONESHOT", int64(SA_ONESHOT), 2147483648}, + {"SA_STACK", int64(SA_STACK), 134217728}, + {"SIG_BLOCK", int64(SIG_BLOCK), 0}, + {"SIG_UNBLOCK", int64(SIG_UNBLOCK), 1}, + {"SIG_SETMASK", int64(SIG_SETMASK), 2}, + {"SI_ASYNCNL", int64(SI_ASYNCNL), -60}, + {"SI_TKILL", int64(SI_TKILL), -6}, + {"SI_SIGIO", int64(SI_SIGIO), -5}, + {"SI_ASYNCIO", int64(SI_ASYNCIO), -4}, + {"SI_MESGQ", int64(SI_MESGQ), -3}, + {"SI_TIMER", int64(SI_TIMER), -2}, + {"SI_QUEUE", int64(SI_QUEUE), -1}, + {"SI_USER", int64(SI_USER), 0}, + {"SI_KERNEL", int64(SI_KERNEL), 128}, + {"ILL_ILLOPC", int64(ILL_ILLOPC), 1}, + {"ILL_ILLOPN", int64(ILL_ILLOPN), 2}, + {"ILL_ILLADR", int64(ILL_ILLADR), 3}, + {"ILL_ILLTRP", int64(ILL_ILLTRP), 4}, + {"ILL_PRVOPC", int64(ILL_PRVOPC), 5}, + {"ILL_PRVREG", int64(ILL_PRVREG), 6}, + {"ILL_COPROC", int64(ILL_COPROC), 7}, + {"ILL_BADSTK", int64(ILL_BADSTK), 8}, + {"FPE_INTDIV", int64(FPE_INTDIV), 1}, + {"FPE_INTOVF", int64(FPE_INTOVF), 2}, + {"FPE_FLTDIV", int64(FPE_FLTDIV), 3}, + {"FPE_FLTOVF", int64(FPE_FLTOVF), 4}, + {"FPE_FLTUND", int64(FPE_FLTUND), 5}, + {"FPE_FLTRES", int64(FPE_FLTRES), 6}, + {"FPE_FLTINV", int64(FPE_FLTINV), 7}, + {"FPE_FLTSUB", int64(FPE_FLTSUB), 8}, + {"SEGV_MAPERR", int64(SEGV_MAPERR), 1}, + {"SEGV_ACCERR", int64(SEGV_ACCERR), 2}, + {"BUS_ADRALN", int64(BUS_ADRALN), 1}, + {"BUS_ADRERR", int64(BUS_ADRERR), 2}, + {"BUS_OBJERR", int64(BUS_OBJERR), 3}, + {"BUS_MCEERR_AR", int64(BUS_MCEERR_AR), 4}, + {"BUS_MCEERR_AO", int64(BUS_MCEERR_AO), 5}, + {"CLD_EXITED", int64(CLD_EXITED), 1}, + {"CLD_KILLED", int64(CLD_KILLED), 2}, + {"CLD_DUMPED", int64(CLD_DUMPED), 3}, + {"CLD_TRAPPED", int64(CLD_TRAPPED), 4}, + {"CLD_STOPPED", int64(CLD_STOPPED), 5}, + {"CLD_CONTINUED", int64(CLD_CONTINUED), 6}, + {"POLL_IN", int64(POLL_IN), 1}, + {"POLL_OUT", int64(POLL_OUT), 2}, + {"POLL_MSG", int64(POLL_MSG), 3}, + {"POLL_ERR", int64(POLL_ERR), 4}, + {"POLL_PRI", int64(POLL_PRI), 5}, + {"POLL_HUP", int64(POLL_HUP), 6}, + {"SIGEV_SIGNAL", int64(SIGEV_SIGNAL), 0}, + {"SIGEV_NONE", int64(SIGEV_NONE), 1}, + {"SIGEV_THREAD", int64(SIGEV_THREAD), 2}, + {"SIGEV_THREAD_ID", int64(SIGEV_THREAD_ID), 4}, + {"SIGHUP", int64(SIGHUP), 1}, + {"SIGINT", int64(SIGINT), 2}, + {"SIGQUIT", int64(SIGQUIT), 3}, + {"SIGILL", int64(SIGILL), 4}, + {"SIGTRAP", int64(SIGTRAP), 5}, + {"SIGABRT", int64(SIGABRT), 6}, + {"SIGIOT", int64(SIGIOT), 6}, + {"SIGBUS", int64(SIGBUS), 7}, + {"SIGFPE", int64(SIGFPE), 8}, + {"SIGKILL", int64(SIGKILL), 9}, + {"SIGUSR1", int64(SIGUSR1), 10}, + {"SIGSEGV", int64(SIGSEGV), 11}, + {"SIGUSR2", int64(SIGUSR2), 12}, + {"SIGPIPE", int64(SIGPIPE), 13}, + {"SIGALRM", int64(SIGALRM), 14}, + {"SIGTERM", int64(SIGTERM), 15}, + {"SIGSTKFLT", int64(SIGSTKFLT), 16}, + {"SIGCHLD", int64(SIGCHLD), 17}, + {"SIGCONT", int64(SIGCONT), 18}, + {"SIGSTOP", int64(SIGSTOP), 19}, + {"SIGTSTP", int64(SIGTSTP), 20}, + {"SIGTTIN", int64(SIGTTIN), 21}, + {"SIGTTOU", int64(SIGTTOU), 22}, + {"SIGURG", int64(SIGURG), 23}, + {"SIGXCPU", int64(SIGXCPU), 24}, + {"SIGXFSZ", int64(SIGXFSZ), 25}, + {"SIGVTALRM", int64(SIGVTALRM), 26}, + {"SIGPROF", int64(SIGPROF), 27}, + {"SIGWINCH", int64(SIGWINCH), 28}, + {"SIGIO", int64(SIGIO), 29}, + {"SIGPWR", int64(SIGPWR), 30}, + {"SIGSYS", int64(SIGSYS), 31}, + {"SIGUNUSED", int64(SIGUNUSED), 31}, + {"NSIG", int64(NSIG), 65}, + } + var signalVariableSymbols = []struct { + name string + address unsafe.Pointer + }{} + var signalAccessorChecks = []struct { + name string + check func() (uintptr, uintptr, uintptr) + offset, size, align uintptr + }{ + {"*_llcppg_anon_7.XGof_ref_sa_handler", func() (uintptr, uintptr, uintptr) { + var value _llcppg_anon_7 + view := value.XGof_ref_sa_handler() + return uintptr(unsafe.Pointer(view)) - uintptr(unsafe.Pointer(&value)), unsafe.Sizeof(*view), unsafe.Alignof(*view) + }, 0, 8, 8}, + {"*_llcppg_anon_7.XGof_ref_sa_sigaction", func() (uintptr, uintptr, uintptr) { + var value _llcppg_anon_7 + view := value.XGof_ref_sa_sigaction() + return uintptr(unsafe.Pointer(view)) - uintptr(unsafe.Pointer(&value)), unsafe.Sizeof(*view), unsafe.Alignof(*view) + }, 0, 8, 8}, + {"*_llcppg_anon_8.XGof_ref_fpstate", func() (uintptr, uintptr, uintptr) { + var value Sigcontext + view := value._llcppg_anon_8.XGof_ref_fpstate() + return uintptr(unsafe.Pointer(view)) - uintptr(unsafe.Pointer(&value)), unsafe.Sizeof(*view), unsafe.Alignof(*view) + }, 184, 8, 8}, + {"*_llcppg_anon_8.XGof_ref___fpstate_word", func() (uintptr, uintptr, uintptr) { + var value Sigcontext + view := value._llcppg_anon_8.XGof_ref___fpstate_word() + return uintptr(unsafe.Pointer(view)) - uintptr(unsafe.Pointer(&value)), unsafe.Sizeof(*view), unsafe.Alignof(*view) + }, 184, 8, 8}, + {"*Sigval.XGof_ref_sival_int", func() (uintptr, uintptr, uintptr) { + var value Sigval + view := value.XGof_ref_sival_int() + return uintptr(unsafe.Pointer(view)) - uintptr(unsafe.Pointer(&value)), unsafe.Sizeof(*view), unsafe.Alignof(*view) + }, 0, 4, 4}, + {"*Sigval.XGof_ref_sival_ptr", func() (uintptr, uintptr, uintptr) { + var value Sigval + view := value.XGof_ref_sival_ptr() + return uintptr(unsafe.Pointer(view)) - uintptr(unsafe.Pointer(&value)), unsafe.Sizeof(*view), unsafe.Alignof(*view) + }, 0, 8, 8}, + {"*_llcppg_anon_5.XGof_ref__pad", func() (uintptr, uintptr, uintptr) { + var value _llcppg_anon_5 + view := value.XGof_ref__pad() + return uintptr(unsafe.Pointer(view)) - uintptr(unsafe.Pointer(&value)), unsafe.Sizeof(*view), unsafe.Alignof(*view) + }, 0, 112, 4}, + {"*_llcppg_anon_5.XGof_ref__kill", func() (uintptr, uintptr, uintptr) { + var value _llcppg_anon_5 + view := value.XGof_ref__kill() + return uintptr(unsafe.Pointer(view)) - uintptr(unsafe.Pointer(&value)), unsafe.Sizeof(*view), unsafe.Alignof(*view) + }, 0, 8, 4}, + {"*_llcppg_anon_5.XGof_ref__timer", func() (uintptr, uintptr, uintptr) { + var value _llcppg_anon_5 + view := value.XGof_ref__timer() + return uintptr(unsafe.Pointer(view)) - uintptr(unsafe.Pointer(&value)), unsafe.Sizeof(*view), unsafe.Alignof(*view) + }, 0, 16, 8}, + {"*_llcppg_anon_5.XGof_ref__rt", func() (uintptr, uintptr, uintptr) { + var value _llcppg_anon_5 + view := value.XGof_ref__rt() + return uintptr(unsafe.Pointer(view)) - uintptr(unsafe.Pointer(&value)), unsafe.Sizeof(*view), unsafe.Alignof(*view) + }, 0, 16, 8}, + {"*_llcppg_anon_5.XGof_ref__sigchld", func() (uintptr, uintptr, uintptr) { + var value _llcppg_anon_5 + view := value.XGof_ref__sigchld() + return uintptr(unsafe.Pointer(view)) - uintptr(unsafe.Pointer(&value)), unsafe.Sizeof(*view), unsafe.Alignof(*view) + }, 0, 32, 8}, + {"*_llcppg_anon_5.XGof_ref__sigfault", func() (uintptr, uintptr, uintptr) { + var value _llcppg_anon_5 + view := value.XGof_ref__sigfault() + return uintptr(unsafe.Pointer(view)) - uintptr(unsafe.Pointer(&value)), unsafe.Sizeof(*view), unsafe.Alignof(*view) + }, 0, 32, 8}, + {"*_llcppg_anon_5.XGof_ref__sigpoll", func() (uintptr, uintptr, uintptr) { + var value _llcppg_anon_5 + view := value.XGof_ref__sigpoll() + return uintptr(unsafe.Pointer(view)) - uintptr(unsafe.Pointer(&value)), unsafe.Sizeof(*view), unsafe.Alignof(*view) + }, 0, 16, 8}, + {"*_llcppg_anon_5.XGof_ref__sigsys", func() (uintptr, uintptr, uintptr) { + var value _llcppg_anon_5 + view := value.XGof_ref__sigsys() + return uintptr(unsafe.Pointer(view)) - uintptr(unsafe.Pointer(&value)), unsafe.Sizeof(*view), unsafe.Alignof(*view) + }, 0, 16, 8}, + {"*_llcppg_anon_6.XGof_ref__pad", func() (uintptr, uintptr, uintptr) { + var value _llcppg_anon_6 + view := value.XGof_ref__pad() + return uintptr(unsafe.Pointer(view)) - uintptr(unsafe.Pointer(&value)), unsafe.Sizeof(*view), unsafe.Alignof(*view) + }, 0, 48, 4}, + {"*_llcppg_anon_6.XGof_ref__tid", func() (uintptr, uintptr, uintptr) { + var value _llcppg_anon_6 + view := value.XGof_ref__tid() + return uintptr(unsafe.Pointer(view)) - uintptr(unsafe.Pointer(&value)), unsafe.Sizeof(*view), unsafe.Alignof(*view) + }, 0, 4, 4}, + {"*_llcppg_anon_6.XGof_ref__sigev_thread", func() (uintptr, uintptr, uintptr) { + var value _llcppg_anon_6 + view := value.XGof_ref__sigev_thread() + return uintptr(unsafe.Pointer(view)) - uintptr(unsafe.Pointer(&value)), unsafe.Sizeof(*view), unsafe.Alignof(*view) + }, 0, 16, 8}, + } + + t.Run("function symbols", func(t *testing.T) { + for _, symbol := range signalFunctionSymbols { + t.Run(symbol.name, func(t *testing.T) { + if symbol.address == nil { + t.Fatal("C function address is nil") + } + t.Logf("C function address: %p", symbol.address) + }) + } + }) + t.Run("native prototypes", func(t *testing.T) { + check := func(name string, got reflect.Type, want signalABISlot) { + if got.Size() != want.size || uintptr(got.Align()) != want.align { + t.Errorf("%s size/alignment = %d/%d, C = %d/%d", name, got.Size(), got.Align(), want.size, want.align) + } + class := 0 + switch got.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + class = 1 + case reflect.Ptr, reflect.UnsafePointer, reflect.Func: + class = 5 + case reflect.Float32, reflect.Float64: + class = 8 + case reflect.Struct: + class = 12 + if got.NumField() == 1 && got.Field(0).Name == "_xgo_union" { + class = 13 + } + } + if class != want.class { + t.Errorf("%s ABI class = %d (%v), C = %d", name, class, got.Kind(), want.class) + } + } + for _, tc := range signalFunctionPrototypes { + t.Run(tc.name, func(t *testing.T) { + inputs := len(tc.inputs) + if tc.variadic { + inputs++ + } + if tc.signature.Kind() != reflect.Func || tc.signature.NumIn() != inputs || tc.signature.IsVariadic() != tc.variadic { + t.Fatalf("Go signature = %v, C fixed parameters = %d, variadic = %v", tc.signature, len(tc.inputs), tc.variadic) + } + for i, slot := range tc.inputs { + check(tc.name+" parameter", tc.signature.In(i), slot) + } + outputs := 0 + if tc.output != nil { + outputs = 1 + } + if tc.signature.NumOut() != outputs { + t.Fatalf("Go result count = %d, C = %d", tc.signature.NumOut(), outputs) + } + if tc.output != nil { + check(tc.name+" result", tc.signature.Out(0), *tc.output) + } + }) + } + for _, tc := range signalStaticFunctionPrototypes { + t.Run(tc.name, func(t *testing.T) { + for _, slot := range tc.slots { + if slot.goType != nil { + check(tc.name+" "+slot.label, slot.goType, slot.want) + } else if slot.got != slot.want { + t.Errorf("%s %s ABI = %+v, C = %+v", tc.name, slot.label, slot.got, slot.want) + } + } + }) + } + + }) + t.Run("native types and globals", func(t *testing.T) { + for _, tc := range signalTypeLayouts { + t.Run(tc.symbol+"/"+tc.property, func(t *testing.T) { + if tc.got != tc.want { + t.Fatalf("Go layout = %d, C headers = %d", tc.got, tc.want) + } + }) + } + for _, symbol := range signalVariableSymbols { + if symbol.address == nil { + t.Errorf("%s C variable address is nil", symbol.name) + } + t.Logf("%s C variable address: %p", symbol.name, symbol.address) + } + }) + t.Run("native constants", func(t *testing.T) { + for _, tc := range signalIntegerConstants { + t.Run(tc.name, func(t *testing.T) { + if tc.got != tc.want { + t.Fatalf("Go constant = %d, C headers = %d", tc.got, tc.want) + } + }) + } + }) + t.Run("union accessors", func(t *testing.T) { + for _, tc := range signalAccessorChecks { + t.Run(tc.name, func(t *testing.T) { + offset, size, align := tc.check() + if offset != tc.offset || size != tc.size || align != tc.align { + t.Fatalf("Go field offset/size/alignment = %d/%d/%d, C = %d/%d/%d", offset, size, align, tc.offset, tc.size, tc.align) + } + }) + } + }) + t.Run("symbol inventory", func(t *testing.T) { + functions, prototypes, types, constants, variables := map[string]bool{}, map[string]bool{}, map[string]bool{}, map[string]bool{}, map[string]bool{} + for _, tc := range signalFunctionPrototypes { + prototypes[tc.name] = true + } + for _, tc := range signalStaticFunctionPrototypes { + prototypes[tc.name] = true + } + + for _, symbol := range signalFunctionSymbols { + functions[symbol.name] = true + if !prototypes[symbol.name] { + t.Errorf("%s has no native prototype test", symbol.name) + } + } + for _, tc := range signalAccessorChecks { + functions[tc.name] = true + } + for _, tc := range signalTypeLayouts { + types[tc.symbol] = true + } + for _, tc := range signalIntegerConstants { + constants[tc.name] = true + } + for _, symbol := range signalVariableSymbols { + variables[symbol.name] = true + } + constants["LLGoPackage"] = true + functions["Signal"] = true + if LLGoPackage != "link" { + t.Errorf("LLGoPackage = %q, want link", LLGoPackage) + } + files := []string{"libc_" + runtime.GOOS + "_" + runtime.GOARCH + ".go"} + + for _, filename := range files { + source, err := parser.ParseFile(token.NewFileSet(), filename, nil, parser.ParseComments) + if err != nil { + t.Fatal(err) + } + for _, declaration := range source.Decls { + switch decl := declaration.(type) { + case *ast.FuncDecl: + name := decl.Name.Name + if !ast.IsExported(name) { + continue + } + if decl.Recv != nil { + receiver, prefix := decl.Recv.List[0].Type, "" + if pointer, ok := receiver.(*ast.StarExpr); ok { + receiver, prefix = pointer.X, "*" + } + name = prefix + receiver.(*ast.Ident).Name + "." + name + } + if !functions[name] { + t.Errorf("%s: function %s has no test", filename, name) + } + if strings.HasPrefix(decl.Name.Name, "Native") && decl.Name.Name != "NativeSignal" { + t.Errorf("%s retains duplicate %s", filename, name) + } + if decl.Doc != nil { + for _, comment := range decl.Doc.List { + for _, private := range []string{"C._llcppg_", "C.__sig", "C.__sysv_signal", "C.__libc_current_sigrt"} { + if strings.Contains(comment.Text, private) { + t.Errorf("%s still exposes private C entry point %s", filename, private) + } + } + } + } + case *ast.GenDecl: + for _, specification := range decl.Specs { + switch spec := specification.(type) { + case *ast.TypeSpec: + if ast.IsExported(spec.Name.Name) && !types[spec.Name.Name] { + t.Errorf("%s: type %s has no ABI test", filename, spec.Name.Name) + } + case *ast.ValueSpec: + for _, name := range spec.Names { + if !ast.IsExported(name.Name) { + continue + } + if decl.Tok == token.CONST && !constants[name.Name] { + t.Errorf("%s: constant %s has no test", filename, name.Name) + } + if decl.Tok == token.VAR && !variables[name.Name] { + t.Errorf("%s: variable %s has no test", filename, name.Name) + } + } + } + } + } + } + } + t.Logf("coverage: %d C functions, %d Go union accessors, %d types/global layouts, %d constants, %d globals", len(signalFunctionSymbols), len(signalAccessorChecks), len(signalTypeLayouts), len(constants), len(signalVariableSymbols)) + }) + + var set SigsetT + var info SiginfoT + var value Sigval + if unsafe.Sizeof(set) != nativeSigsetSize || unsafe.Alignof(set) != nativeSigsetAlign { + t.Fatalf("sigset_t = %d/%d, want %d/%d", unsafe.Sizeof(set), unsafe.Alignof(set), nativeSigsetSize, nativeSigsetAlign) + } + if unsafe.Sizeof(info) != nativeSiginfoSize || unsafe.Alignof(info) != 8 { + t.Fatalf("siginfo_t = %d/%d, want %d/8", unsafe.Sizeof(info), unsafe.Alignof(info), nativeSiginfoSize) + } + if unsafe.Offsetof(info.SiSigno) != 0 || unsafe.Offsetof(info.SiErrno) != 4 || unsafe.Offsetof(info.SiCode) != 8 { + t.Fatalf("siginfo_t header offsets = %d/%d/%d", unsafe.Offsetof(info.SiSigno), unsafe.Offsetof(info.SiErrno), unsafe.Offsetof(info.SiCode)) + } + if unsafe.Sizeof(value) != 8 || unsafe.Alignof(value) != 8 { + t.Fatalf("sigval = %d/%d, want 8/8", unsafe.Sizeof(value), unsafe.Alignof(value)) + } + *value.XGof_ref_sival_int() = -7 + if got := *(*c.Int)(unsafe.Pointer(&value)); got != -7 { + t.Fatalf("sigval integer storage = %d, want -7", got) + } + var marker uintptr + *value.XGof_ref_sival_ptr() = unsafe.Pointer(&marker) + if got := *(*unsafe.Pointer)(unsafe.Pointer(&value)); got != unsafe.Pointer(&marker) { + t.Fatalf("sigval pointer storage = %p, want %p", got, &marker) + } + +} diff --git a/c/signal/symbols_linux_arm64_llgo_test.go b/c/signal/symbols_linux_arm64_llgo_test.go new file mode 100644 index 00000000..c814fb96 --- /dev/null +++ b/c/signal/symbols_linux_arm64_llgo_test.go @@ -0,0 +1,692 @@ +//go:build llgo && linux && arm64 && !android + +package signal + +import ( + "github.com/goplus/lib/c" + lltime "github.com/goplus/lib/c/time" + "go/ast" + "go/parser" + "go/token" + "reflect" + "runtime" + "strings" + "testing" + "unsafe" +) + +func TestNativeSignalDataLayouts(t *testing.T) { + // Expected values are compiled from original Bootlin glibc 2.24 headers. + var signalFunctionSymbols = []struct { + name string + address unsafe.Pointer + }{ + {"NativeSignal", c.Func(NativeSignal)}, + {"Kill", c.Func(Kill)}, + {"Killpg", c.Func(Killpg)}, + {"Raise", c.Func(Raise)}, + {"Ssignal", c.Func(Ssignal)}, + {"Gsignal", c.Func(Gsignal)}, + {"Psignal", c.Func(Psignal)}, + {"*SiginfoT.Psiginfo", c.Func((*SiginfoT).Psiginfo)}, + {"Sigblock", c.Func(Sigblock)}, + {"Sigsetmask", c.Func(Sigsetmask)}, + {"Siggetmask", c.Func(Siggetmask)}, + {"*SigsetT.Sigemptyset", c.Func((*SigsetT).Sigemptyset)}, + {"*SigsetT.Sigfillset", c.Func((*SigsetT).Sigfillset)}, + {"*SigsetT.Sigaddset", c.Func((*SigsetT).Sigaddset)}, + {"*SigsetT.Sigdelset", c.Func((*SigsetT).Sigdelset)}, + {"*SigsetT.Sigismember", c.Func((*SigsetT).Sigismember)}, + {"Sigprocmask", c.Func(Sigprocmask)}, + {"*SigsetT.Sigsuspend", c.Func((*SigsetT).Sigsuspend)}, + {"Sigaction", c.Func(Sigaction)}, + {"*SigsetT.Sigpending", c.Func((*SigsetT).Sigpending)}, + {"*SigsetT.Sigwait", c.Func((*SigsetT).Sigwait)}, + {"*SigsetT.Sigwaitinfo", c.Func((*SigsetT).Sigwaitinfo)}, + {"*SigsetT.Sigtimedwait", c.Func((*SigsetT).Sigtimedwait)}, + {"Sigqueue", c.Func(Sigqueue)}, + {"Siginterrupt", c.Func(Siginterrupt)}, + {"Sigstack", c.Func(Sigstack)}, + {"*Sigaltstack.Sigaltstack", c.Func((*Sigaltstack).Sigaltstack)}, + {"TimerCreate", c.Func(TimerCreate)}, + } + var signalFunctionPrototypes = []struct { + name string + signature reflect.Type + inputs []signalABISlot + output *signalABISlot + variadic bool + }{ + {"NativeSignal", reflect.TypeOf(NativeSignal), []signalABISlot{{4, 4, 1}, {8, 8, 5}}, &signalABISlot{8, 8, 5}, false}, + {"Kill", reflect.TypeOf(Kill), []signalABISlot{{4, 4, 1}, {4, 4, 1}}, &signalABISlot{4, 4, 1}, false}, + {"Killpg", reflect.TypeOf(Killpg), []signalABISlot{{4, 4, 1}, {4, 4, 1}}, &signalABISlot{4, 4, 1}, false}, + {"Raise", reflect.TypeOf(Raise), []signalABISlot{{4, 4, 1}}, &signalABISlot{4, 4, 1}, false}, + {"Ssignal", reflect.TypeOf(Ssignal), []signalABISlot{{4, 4, 1}, {8, 8, 5}}, &signalABISlot{8, 8, 5}, false}, + {"Gsignal", reflect.TypeOf(Gsignal), []signalABISlot{{4, 4, 1}}, &signalABISlot{4, 4, 1}, false}, + {"Psignal", reflect.TypeOf(Psignal), []signalABISlot{{4, 4, 1}, {8, 8, 5}}, nil, false}, + {"*SiginfoT.Psiginfo", reflect.TypeOf((*SiginfoT).Psiginfo), []signalABISlot{{8, 8, 5}, {8, 8, 5}}, nil, false}, + {"Sigblock", reflect.TypeOf(Sigblock), []signalABISlot{{4, 4, 1}}, &signalABISlot{4, 4, 1}, false}, + {"Sigsetmask", reflect.TypeOf(Sigsetmask), []signalABISlot{{4, 4, 1}}, &signalABISlot{4, 4, 1}, false}, + {"Siggetmask", reflect.TypeOf(Siggetmask), []signalABISlot{}, &signalABISlot{4, 4, 1}, false}, + {"*SigsetT.Sigemptyset", reflect.TypeOf((*SigsetT).Sigemptyset), []signalABISlot{{8, 8, 5}}, &signalABISlot{4, 4, 1}, false}, + {"*SigsetT.Sigfillset", reflect.TypeOf((*SigsetT).Sigfillset), []signalABISlot{{8, 8, 5}}, &signalABISlot{4, 4, 1}, false}, + {"*SigsetT.Sigaddset", reflect.TypeOf((*SigsetT).Sigaddset), []signalABISlot{{8, 8, 5}, {4, 4, 1}}, &signalABISlot{4, 4, 1}, false}, + {"*SigsetT.Sigdelset", reflect.TypeOf((*SigsetT).Sigdelset), []signalABISlot{{8, 8, 5}, {4, 4, 1}}, &signalABISlot{4, 4, 1}, false}, + {"*SigsetT.Sigismember", reflect.TypeOf((*SigsetT).Sigismember), []signalABISlot{{8, 8, 5}, {4, 4, 1}}, &signalABISlot{4, 4, 1}, false}, + {"Sigprocmask", reflect.TypeOf(Sigprocmask), []signalABISlot{{4, 4, 1}, {8, 8, 5}, {8, 8, 5}}, &signalABISlot{4, 4, 1}, false}, + {"*SigsetT.Sigsuspend", reflect.TypeOf((*SigsetT).Sigsuspend), []signalABISlot{{8, 8, 5}}, &signalABISlot{4, 4, 1}, false}, + {"Sigaction", reflect.TypeOf(Sigaction), []signalABISlot{{4, 4, 1}, {8, 8, 5}, {8, 8, 5}}, &signalABISlot{4, 4, 1}, false}, + {"*SigsetT.Sigpending", reflect.TypeOf((*SigsetT).Sigpending), []signalABISlot{{8, 8, 5}}, &signalABISlot{4, 4, 1}, false}, + {"*SigsetT.Sigwait", reflect.TypeOf((*SigsetT).Sigwait), []signalABISlot{{8, 8, 5}, {8, 8, 5}}, &signalABISlot{4, 4, 1}, false}, + {"*SigsetT.Sigwaitinfo", reflect.TypeOf((*SigsetT).Sigwaitinfo), []signalABISlot{{8, 8, 5}, {8, 8, 5}}, &signalABISlot{4, 4, 1}, false}, + {"*SigsetT.Sigtimedwait", reflect.TypeOf((*SigsetT).Sigtimedwait), []signalABISlot{{8, 8, 5}, {8, 8, 5}, {8, 8, 5}}, &signalABISlot{4, 4, 1}, false}, + {"Sigqueue", reflect.TypeOf(Sigqueue), []signalABISlot{{4, 4, 1}, {4, 4, 1}, {8, 8, 13}}, &signalABISlot{4, 4, 1}, false}, + {"Siginterrupt", reflect.TypeOf(Siginterrupt), []signalABISlot{{4, 4, 1}, {4, 4, 1}}, &signalABISlot{4, 4, 1}, false}, + {"Sigstack", reflect.TypeOf(Sigstack), []signalABISlot{{8, 8, 5}, {8, 8, 5}}, &signalABISlot{4, 4, 1}, false}, + {"*Sigaltstack.Sigaltstack", reflect.TypeOf((*Sigaltstack).Sigaltstack), []signalABISlot{{8, 8, 5}, {8, 8, 5}}, &signalABISlot{4, 4, 1}, false}, + } + // The static assignment checks arity, result, and exact Go parameter types. + // Reflecting the full signature would require missing c/time decl-mode method wrappers. + var _ func(lltime.ClockidT, *Sigevent, *lltime.TimerT) c.Int = TimerCreate + var signalStaticFunctionPrototypes = []struct { + name string + slots []struct { + label string + goType reflect.Type + got, want signalABISlot + } + }{ + {"TimerCreate", []struct { + label string + goType reflect.Type + got, want signalABISlot + }{ + {"clock", reflect.TypeOf(lltime.ClockidT(0)), signalABISlot{}, signalABISlot{4, 4, 1}}, + {"event", nil, signalABISlot{unsafe.Sizeof((*Sigevent)(nil)), unsafe.Alignof((*Sigevent)(nil)), 5}, signalABISlot{8, 8, 5}}, + {"timer", nil, signalABISlot{unsafe.Sizeof((*lltime.TimerT)(nil)), unsafe.Alignof((*lltime.TimerT)(nil)), 5}, signalABISlot{8, 8, 5}}, + {"result", reflect.TypeOf(c.Int(0)), signalABISlot{}, signalABISlot{4, 4, 1}}, + }}, + } + var signalTypeLayouts = []struct { + symbol, property string + got, want uintptr + }{ + {"SigactionT", "size", unsafe.Sizeof(*new(SigactionT)), 152}, + {"SigactionT", "alignment", unsafe.Alignof(*new(SigactionT)), 8}, + {"SigactionT", "X__SigactionHandler offset", unsafe.Offsetof((*new(SigactionT)).X__SigactionHandler), 0}, + {"SigactionT", "X__SigactionHandler size", unsafe.Sizeof((*new(SigactionT)).X__SigactionHandler), 8}, + {"SigactionT", "X__SigactionHandler alignment", unsafe.Alignof((*new(SigactionT)).X__SigactionHandler), 8}, + {"SigactionT", "SaMask offset", unsafe.Offsetof((*new(SigactionT)).SaMask), 8}, + {"SigactionT", "SaMask size", unsafe.Sizeof((*new(SigactionT)).SaMask), 128}, + {"SigactionT", "SaMask alignment", unsafe.Alignof((*new(SigactionT)).SaMask), 8}, + {"SigactionT", "SaFlags offset", unsafe.Offsetof((*new(SigactionT)).SaFlags), 136}, + {"SigactionT", "SaFlags size", unsafe.Sizeof((*new(SigactionT)).SaFlags), 4}, + {"SigactionT", "SaFlags alignment", unsafe.Alignof((*new(SigactionT)).SaFlags), 4}, + {"SigactionT", "SaRestorer offset", unsafe.Offsetof((*new(SigactionT)).SaRestorer), 144}, + {"SigactionT", "SaRestorer size", unsafe.Sizeof((*new(SigactionT)).SaRestorer), 8}, + {"SigactionT", "SaRestorer alignment", unsafe.Alignof((*new(SigactionT)).SaRestorer), 8}, + {"Sigval", "size", unsafe.Sizeof(*new(Sigval)), 8}, + {"Sigval", "alignment", unsafe.Alignof(*new(Sigval)), 8}, + {"SiginfoT", "size", unsafe.Sizeof(*new(SiginfoT)), 128}, + {"SiginfoT", "alignment", unsafe.Alignof(*new(SiginfoT)), 8}, + {"SiginfoT", "SiSigno offset", unsafe.Offsetof((*new(SiginfoT)).SiSigno), 0}, + {"SiginfoT", "SiSigno size", unsafe.Sizeof((*new(SiginfoT)).SiSigno), 4}, + {"SiginfoT", "SiSigno alignment", unsafe.Alignof((*new(SiginfoT)).SiSigno), 4}, + {"SiginfoT", "SiErrno offset", unsafe.Offsetof((*new(SiginfoT)).SiErrno), 4}, + {"SiginfoT", "SiErrno size", unsafe.Sizeof((*new(SiginfoT)).SiErrno), 4}, + {"SiginfoT", "SiErrno alignment", unsafe.Alignof((*new(SiginfoT)).SiErrno), 4}, + {"SiginfoT", "SiCode offset", unsafe.Offsetof((*new(SiginfoT)).SiCode), 8}, + {"SiginfoT", "SiCode size", unsafe.Sizeof((*new(SiginfoT)).SiCode), 4}, + {"SiginfoT", "SiCode alignment", unsafe.Alignof((*new(SiginfoT)).SiCode), 4}, + {"SiginfoT", "X_sifields offset", unsafe.Offsetof((*new(SiginfoT)).X_sifields), 16}, + {"SiginfoT", "X_sifields size", unsafe.Sizeof((*new(SiginfoT)).X_sifields), 112}, + {"SiginfoT", "X_sifields alignment", unsafe.Alignof((*new(SiginfoT)).X_sifields), 8}, + {"Sigevent", "size", unsafe.Sizeof(*new(Sigevent)), 64}, + {"Sigevent", "alignment", unsafe.Alignof(*new(Sigevent)), 8}, + {"Sigevent", "SigevValue offset", unsafe.Offsetof((*new(Sigevent)).SigevValue), 0}, + {"Sigevent", "SigevValue size", unsafe.Sizeof((*new(Sigevent)).SigevValue), 8}, + {"Sigevent", "SigevValue alignment", unsafe.Alignof((*new(Sigevent)).SigevValue), 8}, + {"Sigevent", "SigevSigno offset", unsafe.Offsetof((*new(Sigevent)).SigevSigno), 8}, + {"Sigevent", "SigevSigno size", unsafe.Sizeof((*new(Sigevent)).SigevSigno), 4}, + {"Sigevent", "SigevSigno alignment", unsafe.Alignof((*new(Sigevent)).SigevSigno), 4}, + {"Sigevent", "SigevNotify offset", unsafe.Offsetof((*new(Sigevent)).SigevNotify), 12}, + {"Sigevent", "SigevNotify size", unsafe.Sizeof((*new(Sigevent)).SigevNotify), 4}, + {"Sigevent", "SigevNotify alignment", unsafe.Alignof((*new(Sigevent)).SigevNotify), 4}, + {"Sigevent", "X_sigevUn offset", unsafe.Offsetof((*new(Sigevent)).X_sigevUn), 16}, + {"Sigevent", "X_sigevUn size", unsafe.Sizeof((*new(Sigevent)).X_sigevUn), 48}, + {"Sigevent", "X_sigevUn alignment", unsafe.Alignof((*new(Sigevent)).X_sigevUn), 8}, + {"SigvalT", "size", unsafe.Sizeof(*new(SigvalT)), 8}, + {"SigvalT", "alignment", unsafe.Alignof(*new(SigvalT)), 8}, + {"SigstackT", "size", unsafe.Sizeof(*new(SigstackT)), 16}, + {"SigstackT", "alignment", unsafe.Alignof(*new(SigstackT)), 8}, + {"SigstackT", "SsSp offset", unsafe.Offsetof((*new(SigstackT)).SsSp), 0}, + {"SigstackT", "SsSp size", unsafe.Sizeof((*new(SigstackT)).SsSp), 8}, + {"SigstackT", "SsSp alignment", unsafe.Alignof((*new(SigstackT)).SsSp), 8}, + {"SigstackT", "SsOnstack offset", unsafe.Offsetof((*new(SigstackT)).SsOnstack), 8}, + {"SigstackT", "SsOnstack size", unsafe.Sizeof((*new(SigstackT)).SsOnstack), 4}, + {"SigstackT", "SsOnstack alignment", unsafe.Alignof((*new(SigstackT)).SsOnstack), 4}, + {"Sigaltstack", "size", unsafe.Sizeof(*new(Sigaltstack)), 24}, + {"Sigaltstack", "alignment", unsafe.Alignof(*new(Sigaltstack)), 8}, + {"Sigaltstack", "SsSp offset", unsafe.Offsetof((*new(Sigaltstack)).SsSp), 0}, + {"Sigaltstack", "SsSp size", unsafe.Sizeof((*new(Sigaltstack)).SsSp), 8}, + {"Sigaltstack", "SsSp alignment", unsafe.Alignof((*new(Sigaltstack)).SsSp), 8}, + {"Sigaltstack", "SsFlags offset", unsafe.Offsetof((*new(Sigaltstack)).SsFlags), 8}, + {"Sigaltstack", "SsFlags size", unsafe.Sizeof((*new(Sigaltstack)).SsFlags), 4}, + {"Sigaltstack", "SsFlags alignment", unsafe.Alignof((*new(Sigaltstack)).SsFlags), 4}, + {"Sigaltstack", "SsSize offset", unsafe.Offsetof((*new(Sigaltstack)).SsSize), 16}, + {"Sigaltstack", "SsSize size", unsafe.Sizeof((*new(Sigaltstack)).SsSize), 8}, + {"Sigaltstack", "SsSize alignment", unsafe.Alignof((*new(Sigaltstack)).SsSize), 8}, + {"X__SighandlerT", "size", unsafe.Sizeof(*new(X__SighandlerT)), 8}, + {"X__SighandlerT", "alignment", unsafe.Alignof(*new(X__SighandlerT)), 8}, + {"SigsetT", "size", unsafe.Sizeof(*new(SigsetT)), 128}, + {"SigsetT", "alignment", unsafe.Alignof(*new(SigsetT)), 8}, + {"X__SigsetT", "size", unsafe.Sizeof(*new(X__SigsetT)), 128}, + {"X__SigsetT", "alignment", unsafe.Alignof(*new(X__SigsetT)), 8}, + {"X__SigsetT", "X__Val offset", unsafe.Offsetof((*new(X__SigsetT)).X__Val), 0}, + {"X__SigsetT", "X__Val size", unsafe.Sizeof((*new(X__SigsetT)).X__Val), 128}, + {"X__SigsetT", "X__Val alignment", unsafe.Alignof((*new(X__SigsetT)).X__Val), 8}, + {"SignalHandler", "size", unsafe.Sizeof(*new(SignalHandler)), 8}, + {"SignalHandler", "alignment", unsafe.Alignof(*new(SignalHandler)), 8}, + {"SigeventT", "size", unsafe.Sizeof(*new(SigeventT)), 64}, + {"SigeventT", "alignment", unsafe.Alignof(*new(SigeventT)), 8}, + {"_llcppg_anon_7", "size", unsafe.Sizeof(*new(_llcppg_anon_7)), 8}, + {"_llcppg_anon_7", "alignment", unsafe.Alignof(*new(_llcppg_anon_7)), 8}, + {"_llcppg_anon_5", "size", unsafe.Sizeof(*new(_llcppg_anon_5)), 112}, + {"_llcppg_anon_5", "alignment", unsafe.Alignof(*new(_llcppg_anon_5)), 8}, + {"_llcppg_anon_6", "size", unsafe.Sizeof(*new(_llcppg_anon_6)), 48}, + {"_llcppg_anon_6", "alignment", unsafe.Alignof(*new(_llcppg_anon_6)), 8}, + {"_llcppg_anon_23", "size", unsafe.Sizeof(*new(_llcppg_anon_23)), 8}, + {"_llcppg_anon_23", "alignment", unsafe.Alignof(*new(_llcppg_anon_23)), 4}, + {"_llcppg_anon_23", "SiPid offset", unsafe.Offsetof((*new(_llcppg_anon_23)).SiPid), 0}, + {"_llcppg_anon_23", "SiPid size", unsafe.Sizeof((*new(_llcppg_anon_23)).SiPid), 4}, + {"_llcppg_anon_23", "SiPid alignment", unsafe.Alignof((*new(_llcppg_anon_23)).SiPid), 4}, + {"_llcppg_anon_23", "SiUid offset", unsafe.Offsetof((*new(_llcppg_anon_23)).SiUid), 4}, + {"_llcppg_anon_23", "SiUid size", unsafe.Sizeof((*new(_llcppg_anon_23)).SiUid), 4}, + {"_llcppg_anon_23", "SiUid alignment", unsafe.Alignof((*new(_llcppg_anon_23)).SiUid), 4}, + {"_llcppg_anon_24", "size", unsafe.Sizeof(*new(_llcppg_anon_24)), 16}, + {"_llcppg_anon_24", "alignment", unsafe.Alignof(*new(_llcppg_anon_24)), 8}, + {"_llcppg_anon_24", "SiTid offset", unsafe.Offsetof((*new(_llcppg_anon_24)).SiTid), 0}, + {"_llcppg_anon_24", "SiTid size", unsafe.Sizeof((*new(_llcppg_anon_24)).SiTid), 4}, + {"_llcppg_anon_24", "SiTid alignment", unsafe.Alignof((*new(_llcppg_anon_24)).SiTid), 4}, + {"_llcppg_anon_24", "SiOverrun offset", unsafe.Offsetof((*new(_llcppg_anon_24)).SiOverrun), 4}, + {"_llcppg_anon_24", "SiOverrun size", unsafe.Sizeof((*new(_llcppg_anon_24)).SiOverrun), 4}, + {"_llcppg_anon_24", "SiOverrun alignment", unsafe.Alignof((*new(_llcppg_anon_24)).SiOverrun), 4}, + {"_llcppg_anon_24", "SiSigval offset", unsafe.Offsetof((*new(_llcppg_anon_24)).SiSigval), 8}, + {"_llcppg_anon_24", "SiSigval size", unsafe.Sizeof((*new(_llcppg_anon_24)).SiSigval), 8}, + {"_llcppg_anon_24", "SiSigval alignment", unsafe.Alignof((*new(_llcppg_anon_24)).SiSigval), 8}, + {"_llcppg_anon_25", "size", unsafe.Sizeof(*new(_llcppg_anon_25)), 16}, + {"_llcppg_anon_25", "alignment", unsafe.Alignof(*new(_llcppg_anon_25)), 8}, + {"_llcppg_anon_25", "SiPid offset", unsafe.Offsetof((*new(_llcppg_anon_25)).SiPid), 0}, + {"_llcppg_anon_25", "SiPid size", unsafe.Sizeof((*new(_llcppg_anon_25)).SiPid), 4}, + {"_llcppg_anon_25", "SiPid alignment", unsafe.Alignof((*new(_llcppg_anon_25)).SiPid), 4}, + {"_llcppg_anon_25", "SiUid offset", unsafe.Offsetof((*new(_llcppg_anon_25)).SiUid), 4}, + {"_llcppg_anon_25", "SiUid size", unsafe.Sizeof((*new(_llcppg_anon_25)).SiUid), 4}, + {"_llcppg_anon_25", "SiUid alignment", unsafe.Alignof((*new(_llcppg_anon_25)).SiUid), 4}, + {"_llcppg_anon_25", "SiSigval offset", unsafe.Offsetof((*new(_llcppg_anon_25)).SiSigval), 8}, + {"_llcppg_anon_25", "SiSigval size", unsafe.Sizeof((*new(_llcppg_anon_25)).SiSigval), 8}, + {"_llcppg_anon_25", "SiSigval alignment", unsafe.Alignof((*new(_llcppg_anon_25)).SiSigval), 8}, + {"_llcppg_anon_26", "size", unsafe.Sizeof(*new(_llcppg_anon_26)), 32}, + {"_llcppg_anon_26", "alignment", unsafe.Alignof(*new(_llcppg_anon_26)), 8}, + {"_llcppg_anon_26", "SiPid offset", unsafe.Offsetof((*new(_llcppg_anon_26)).SiPid), 0}, + {"_llcppg_anon_26", "SiPid size", unsafe.Sizeof((*new(_llcppg_anon_26)).SiPid), 4}, + {"_llcppg_anon_26", "SiPid alignment", unsafe.Alignof((*new(_llcppg_anon_26)).SiPid), 4}, + {"_llcppg_anon_26", "SiUid offset", unsafe.Offsetof((*new(_llcppg_anon_26)).SiUid), 4}, + {"_llcppg_anon_26", "SiUid size", unsafe.Sizeof((*new(_llcppg_anon_26)).SiUid), 4}, + {"_llcppg_anon_26", "SiUid alignment", unsafe.Alignof((*new(_llcppg_anon_26)).SiUid), 4}, + {"_llcppg_anon_26", "SiStatus offset", unsafe.Offsetof((*new(_llcppg_anon_26)).SiStatus), 8}, + {"_llcppg_anon_26", "SiStatus size", unsafe.Sizeof((*new(_llcppg_anon_26)).SiStatus), 4}, + {"_llcppg_anon_26", "SiStatus alignment", unsafe.Alignof((*new(_llcppg_anon_26)).SiStatus), 4}, + {"_llcppg_anon_26", "SiUtime offset", unsafe.Offsetof((*new(_llcppg_anon_26)).SiUtime), 16}, + {"_llcppg_anon_26", "SiUtime size", unsafe.Sizeof((*new(_llcppg_anon_26)).SiUtime), 8}, + {"_llcppg_anon_26", "SiUtime alignment", unsafe.Alignof((*new(_llcppg_anon_26)).SiUtime), 8}, + {"_llcppg_anon_26", "SiStime offset", unsafe.Offsetof((*new(_llcppg_anon_26)).SiStime), 24}, + {"_llcppg_anon_26", "SiStime size", unsafe.Sizeof((*new(_llcppg_anon_26)).SiStime), 8}, + {"_llcppg_anon_26", "SiStime alignment", unsafe.Alignof((*new(_llcppg_anon_26)).SiStime), 8}, + {"_llcppg_anon_27", "size", unsafe.Sizeof(*new(_llcppg_anon_27)), 16}, + {"_llcppg_anon_27", "alignment", unsafe.Alignof(*new(_llcppg_anon_27)), 8}, + {"_llcppg_anon_27", "SiAddr offset", unsafe.Offsetof((*new(_llcppg_anon_27)).SiAddr), 0}, + {"_llcppg_anon_27", "SiAddr size", unsafe.Sizeof((*new(_llcppg_anon_27)).SiAddr), 8}, + {"_llcppg_anon_27", "SiAddr alignment", unsafe.Alignof((*new(_llcppg_anon_27)).SiAddr), 8}, + {"_llcppg_anon_27", "SiAddrLsb offset", unsafe.Offsetof((*new(_llcppg_anon_27)).SiAddrLsb), 8}, + {"_llcppg_anon_27", "SiAddrLsb size", unsafe.Sizeof((*new(_llcppg_anon_27)).SiAddrLsb), 2}, + {"_llcppg_anon_27", "SiAddrLsb alignment", unsafe.Alignof((*new(_llcppg_anon_27)).SiAddrLsb), 2}, + {"_llcppg_anon_28", "size", unsafe.Sizeof(*new(_llcppg_anon_28)), 16}, + {"_llcppg_anon_28", "alignment", unsafe.Alignof(*new(_llcppg_anon_28)), 8}, + {"_llcppg_anon_28", "SiBand offset", unsafe.Offsetof((*new(_llcppg_anon_28)).SiBand), 0}, + {"_llcppg_anon_28", "SiBand size", unsafe.Sizeof((*new(_llcppg_anon_28)).SiBand), 8}, + {"_llcppg_anon_28", "SiBand alignment", unsafe.Alignof((*new(_llcppg_anon_28)).SiBand), 8}, + {"_llcppg_anon_28", "SiFd offset", unsafe.Offsetof((*new(_llcppg_anon_28)).SiFd), 8}, + {"_llcppg_anon_28", "SiFd size", unsafe.Sizeof((*new(_llcppg_anon_28)).SiFd), 4}, + {"_llcppg_anon_28", "SiFd alignment", unsafe.Alignof((*new(_llcppg_anon_28)).SiFd), 4}, + {"_llcppg_anon_29", "size", unsafe.Sizeof(*new(_llcppg_anon_29)), 16}, + {"_llcppg_anon_29", "alignment", unsafe.Alignof(*new(_llcppg_anon_29)), 8}, + {"_llcppg_anon_29", "X_callAddr offset", unsafe.Offsetof((*new(_llcppg_anon_29)).X_callAddr), 0}, + {"_llcppg_anon_29", "X_callAddr size", unsafe.Sizeof((*new(_llcppg_anon_29)).X_callAddr), 8}, + {"_llcppg_anon_29", "X_callAddr alignment", unsafe.Alignof((*new(_llcppg_anon_29)).X_callAddr), 8}, + {"_llcppg_anon_29", "X_syscall offset", unsafe.Offsetof((*new(_llcppg_anon_29)).X_syscall), 8}, + {"_llcppg_anon_29", "X_syscall size", unsafe.Sizeof((*new(_llcppg_anon_29)).X_syscall), 4}, + {"_llcppg_anon_29", "X_syscall alignment", unsafe.Alignof((*new(_llcppg_anon_29)).X_syscall), 4}, + {"_llcppg_anon_29", "X_arch offset", unsafe.Offsetof((*new(_llcppg_anon_29)).X_arch), 12}, + {"_llcppg_anon_29", "X_arch size", unsafe.Sizeof((*new(_llcppg_anon_29)).X_arch), 4}, + {"_llcppg_anon_29", "X_arch alignment", unsafe.Alignof((*new(_llcppg_anon_29)).X_arch), 4}, + {"_llcppg_anon_30", "size", unsafe.Sizeof(*new(_llcppg_anon_30)), 16}, + {"_llcppg_anon_30", "alignment", unsafe.Alignof(*new(_llcppg_anon_30)), 8}, + {"_llcppg_anon_30", "X_function offset", unsafe.Offsetof((*new(_llcppg_anon_30)).X_function), 0}, + {"_llcppg_anon_30", "X_function size", unsafe.Sizeof((*new(_llcppg_anon_30)).X_function), 8}, + {"_llcppg_anon_30", "X_function alignment", unsafe.Alignof((*new(_llcppg_anon_30)).X_function), 8}, + {"_llcppg_anon_30", "X_attribute offset", unsafe.Offsetof((*new(_llcppg_anon_30)).X_attribute), 8}, + {"_llcppg_anon_30", "X_attribute size", unsafe.Sizeof((*new(_llcppg_anon_30)).X_attribute), 8}, + {"_llcppg_anon_30", "X_attribute alignment", unsafe.Alignof((*new(_llcppg_anon_30)).X_attribute), 8}, + } + var signalIntegerConstants = []struct { + name string + got, want int64 + }{ + {"SA_NOCLDSTOP", int64(SA_NOCLDSTOP), 1}, + {"SA_NOCLDWAIT", int64(SA_NOCLDWAIT), 2}, + {"SA_SIGINFO", int64(SA_SIGINFO), 4}, + {"SA_ONSTACK", int64(SA_ONSTACK), 134217728}, + {"SA_RESTART", int64(SA_RESTART), 268435456}, + {"SA_NODEFER", int64(SA_NODEFER), 1073741824}, + {"SA_RESETHAND", int64(SA_RESETHAND), 2147483648}, + {"SA_INTERRUPT", int64(SA_INTERRUPT), 536870912}, + {"SA_NOMASK", int64(SA_NOMASK), 1073741824}, + {"SA_ONESHOT", int64(SA_ONESHOT), 2147483648}, + {"SA_STACK", int64(SA_STACK), 134217728}, + {"SIG_BLOCK", int64(SIG_BLOCK), 0}, + {"SIG_UNBLOCK", int64(SIG_UNBLOCK), 1}, + {"SIG_SETMASK", int64(SIG_SETMASK), 2}, + {"SI_ASYNCNL", int64(SI_ASYNCNL), -60}, + {"SI_TKILL", int64(SI_TKILL), -6}, + {"SI_SIGIO", int64(SI_SIGIO), -5}, + {"SI_ASYNCIO", int64(SI_ASYNCIO), -4}, + {"SI_MESGQ", int64(SI_MESGQ), -3}, + {"SI_TIMER", int64(SI_TIMER), -2}, + {"SI_QUEUE", int64(SI_QUEUE), -1}, + {"SI_USER", int64(SI_USER), 0}, + {"SI_KERNEL", int64(SI_KERNEL), 128}, + {"ILL_ILLOPC", int64(ILL_ILLOPC), 1}, + {"ILL_ILLOPN", int64(ILL_ILLOPN), 2}, + {"ILL_ILLADR", int64(ILL_ILLADR), 3}, + {"ILL_ILLTRP", int64(ILL_ILLTRP), 4}, + {"ILL_PRVOPC", int64(ILL_PRVOPC), 5}, + {"ILL_PRVREG", int64(ILL_PRVREG), 6}, + {"ILL_COPROC", int64(ILL_COPROC), 7}, + {"ILL_BADSTK", int64(ILL_BADSTK), 8}, + {"FPE_INTDIV", int64(FPE_INTDIV), 1}, + {"FPE_INTOVF", int64(FPE_INTOVF), 2}, + {"FPE_FLTDIV", int64(FPE_FLTDIV), 3}, + {"FPE_FLTOVF", int64(FPE_FLTOVF), 4}, + {"FPE_FLTUND", int64(FPE_FLTUND), 5}, + {"FPE_FLTRES", int64(FPE_FLTRES), 6}, + {"FPE_FLTINV", int64(FPE_FLTINV), 7}, + {"FPE_FLTSUB", int64(FPE_FLTSUB), 8}, + {"SEGV_MAPERR", int64(SEGV_MAPERR), 1}, + {"SEGV_ACCERR", int64(SEGV_ACCERR), 2}, + {"BUS_ADRALN", int64(BUS_ADRALN), 1}, + {"BUS_ADRERR", int64(BUS_ADRERR), 2}, + {"BUS_OBJERR", int64(BUS_OBJERR), 3}, + {"BUS_MCEERR_AR", int64(BUS_MCEERR_AR), 4}, + {"BUS_MCEERR_AO", int64(BUS_MCEERR_AO), 5}, + {"CLD_EXITED", int64(CLD_EXITED), 1}, + {"CLD_KILLED", int64(CLD_KILLED), 2}, + {"CLD_DUMPED", int64(CLD_DUMPED), 3}, + {"CLD_TRAPPED", int64(CLD_TRAPPED), 4}, + {"CLD_STOPPED", int64(CLD_STOPPED), 5}, + {"CLD_CONTINUED", int64(CLD_CONTINUED), 6}, + {"POLL_IN", int64(POLL_IN), 1}, + {"POLL_OUT", int64(POLL_OUT), 2}, + {"POLL_MSG", int64(POLL_MSG), 3}, + {"POLL_ERR", int64(POLL_ERR), 4}, + {"POLL_PRI", int64(POLL_PRI), 5}, + {"POLL_HUP", int64(POLL_HUP), 6}, + {"SIGEV_SIGNAL", int64(SIGEV_SIGNAL), 0}, + {"SIGEV_NONE", int64(SIGEV_NONE), 1}, + {"SIGEV_THREAD", int64(SIGEV_THREAD), 2}, + {"SIGEV_THREAD_ID", int64(SIGEV_THREAD_ID), 4}, + {"SIGHUP", int64(SIGHUP), 1}, + {"SIGINT", int64(SIGINT), 2}, + {"SIGQUIT", int64(SIGQUIT), 3}, + {"SIGILL", int64(SIGILL), 4}, + {"SIGTRAP", int64(SIGTRAP), 5}, + {"SIGABRT", int64(SIGABRT), 6}, + {"SIGIOT", int64(SIGIOT), 6}, + {"SIGBUS", int64(SIGBUS), 7}, + {"SIGFPE", int64(SIGFPE), 8}, + {"SIGKILL", int64(SIGKILL), 9}, + {"SIGUSR1", int64(SIGUSR1), 10}, + {"SIGSEGV", int64(SIGSEGV), 11}, + {"SIGUSR2", int64(SIGUSR2), 12}, + {"SIGPIPE", int64(SIGPIPE), 13}, + {"SIGALRM", int64(SIGALRM), 14}, + {"SIGTERM", int64(SIGTERM), 15}, + {"SIGSTKFLT", int64(SIGSTKFLT), 16}, + {"SIGCHLD", int64(SIGCHLD), 17}, + {"SIGCONT", int64(SIGCONT), 18}, + {"SIGSTOP", int64(SIGSTOP), 19}, + {"SIGTSTP", int64(SIGTSTP), 20}, + {"SIGTTIN", int64(SIGTTIN), 21}, + {"SIGTTOU", int64(SIGTTOU), 22}, + {"SIGURG", int64(SIGURG), 23}, + {"SIGXCPU", int64(SIGXCPU), 24}, + {"SIGXFSZ", int64(SIGXFSZ), 25}, + {"SIGVTALRM", int64(SIGVTALRM), 26}, + {"SIGPROF", int64(SIGPROF), 27}, + {"SIGWINCH", int64(SIGWINCH), 28}, + {"SIGIO", int64(SIGIO), 29}, + {"SIGPWR", int64(SIGPWR), 30}, + {"SIGSYS", int64(SIGSYS), 31}, + {"SIGUNUSED", int64(SIGUNUSED), 31}, + {"NSIG", int64(NSIG), 65}, + } + var signalVariableSymbols = []struct { + name string + address unsafe.Pointer + }{} + var signalAccessorChecks = []struct { + name string + check func() (uintptr, uintptr, uintptr) + offset, size, align uintptr + }{ + {"*_llcppg_anon_7.XGof_ref_sa_handler", func() (uintptr, uintptr, uintptr) { + var value _llcppg_anon_7 + view := value.XGof_ref_sa_handler() + return uintptr(unsafe.Pointer(view)) - uintptr(unsafe.Pointer(&value)), unsafe.Sizeof(*view), unsafe.Alignof(*view) + }, 0, 8, 8}, + {"*_llcppg_anon_7.XGof_ref_sa_sigaction", func() (uintptr, uintptr, uintptr) { + var value _llcppg_anon_7 + view := value.XGof_ref_sa_sigaction() + return uintptr(unsafe.Pointer(view)) - uintptr(unsafe.Pointer(&value)), unsafe.Sizeof(*view), unsafe.Alignof(*view) + }, 0, 8, 8}, + {"*Sigval.XGof_ref_sival_int", func() (uintptr, uintptr, uintptr) { + var value Sigval + view := value.XGof_ref_sival_int() + return uintptr(unsafe.Pointer(view)) - uintptr(unsafe.Pointer(&value)), unsafe.Sizeof(*view), unsafe.Alignof(*view) + }, 0, 4, 4}, + {"*Sigval.XGof_ref_sival_ptr", func() (uintptr, uintptr, uintptr) { + var value Sigval + view := value.XGof_ref_sival_ptr() + return uintptr(unsafe.Pointer(view)) - uintptr(unsafe.Pointer(&value)), unsafe.Sizeof(*view), unsafe.Alignof(*view) + }, 0, 8, 8}, + {"*_llcppg_anon_5.XGof_ref__pad", func() (uintptr, uintptr, uintptr) { + var value _llcppg_anon_5 + view := value.XGof_ref__pad() + return uintptr(unsafe.Pointer(view)) - uintptr(unsafe.Pointer(&value)), unsafe.Sizeof(*view), unsafe.Alignof(*view) + }, 0, 112, 4}, + {"*_llcppg_anon_5.XGof_ref__kill", func() (uintptr, uintptr, uintptr) { + var value _llcppg_anon_5 + view := value.XGof_ref__kill() + return uintptr(unsafe.Pointer(view)) - uintptr(unsafe.Pointer(&value)), unsafe.Sizeof(*view), unsafe.Alignof(*view) + }, 0, 8, 4}, + {"*_llcppg_anon_5.XGof_ref__timer", func() (uintptr, uintptr, uintptr) { + var value _llcppg_anon_5 + view := value.XGof_ref__timer() + return uintptr(unsafe.Pointer(view)) - uintptr(unsafe.Pointer(&value)), unsafe.Sizeof(*view), unsafe.Alignof(*view) + }, 0, 16, 8}, + {"*_llcppg_anon_5.XGof_ref__rt", func() (uintptr, uintptr, uintptr) { + var value _llcppg_anon_5 + view := value.XGof_ref__rt() + return uintptr(unsafe.Pointer(view)) - uintptr(unsafe.Pointer(&value)), unsafe.Sizeof(*view), unsafe.Alignof(*view) + }, 0, 16, 8}, + {"*_llcppg_anon_5.XGof_ref__sigchld", func() (uintptr, uintptr, uintptr) { + var value _llcppg_anon_5 + view := value.XGof_ref__sigchld() + return uintptr(unsafe.Pointer(view)) - uintptr(unsafe.Pointer(&value)), unsafe.Sizeof(*view), unsafe.Alignof(*view) + }, 0, 32, 8}, + {"*_llcppg_anon_5.XGof_ref__sigfault", func() (uintptr, uintptr, uintptr) { + var value _llcppg_anon_5 + view := value.XGof_ref__sigfault() + return uintptr(unsafe.Pointer(view)) - uintptr(unsafe.Pointer(&value)), unsafe.Sizeof(*view), unsafe.Alignof(*view) + }, 0, 16, 8}, + {"*_llcppg_anon_5.XGof_ref__sigpoll", func() (uintptr, uintptr, uintptr) { + var value _llcppg_anon_5 + view := value.XGof_ref__sigpoll() + return uintptr(unsafe.Pointer(view)) - uintptr(unsafe.Pointer(&value)), unsafe.Sizeof(*view), unsafe.Alignof(*view) + }, 0, 16, 8}, + {"*_llcppg_anon_5.XGof_ref__sigsys", func() (uintptr, uintptr, uintptr) { + var value _llcppg_anon_5 + view := value.XGof_ref__sigsys() + return uintptr(unsafe.Pointer(view)) - uintptr(unsafe.Pointer(&value)), unsafe.Sizeof(*view), unsafe.Alignof(*view) + }, 0, 16, 8}, + {"*_llcppg_anon_6.XGof_ref__pad", func() (uintptr, uintptr, uintptr) { + var value _llcppg_anon_6 + view := value.XGof_ref__pad() + return uintptr(unsafe.Pointer(view)) - uintptr(unsafe.Pointer(&value)), unsafe.Sizeof(*view), unsafe.Alignof(*view) + }, 0, 48, 4}, + {"*_llcppg_anon_6.XGof_ref__tid", func() (uintptr, uintptr, uintptr) { + var value _llcppg_anon_6 + view := value.XGof_ref__tid() + return uintptr(unsafe.Pointer(view)) - uintptr(unsafe.Pointer(&value)), unsafe.Sizeof(*view), unsafe.Alignof(*view) + }, 0, 4, 4}, + {"*_llcppg_anon_6.XGof_ref__sigev_thread", func() (uintptr, uintptr, uintptr) { + var value _llcppg_anon_6 + view := value.XGof_ref__sigev_thread() + return uintptr(unsafe.Pointer(view)) - uintptr(unsafe.Pointer(&value)), unsafe.Sizeof(*view), unsafe.Alignof(*view) + }, 0, 16, 8}, + } + + t.Run("function symbols", func(t *testing.T) { + for _, symbol := range signalFunctionSymbols { + t.Run(symbol.name, func(t *testing.T) { + if symbol.address == nil { + t.Fatal("C function address is nil") + } + t.Logf("C function address: %p", symbol.address) + }) + } + }) + t.Run("native prototypes", func(t *testing.T) { + check := func(name string, got reflect.Type, want signalABISlot) { + if got.Size() != want.size || uintptr(got.Align()) != want.align { + t.Errorf("%s size/alignment = %d/%d, C = %d/%d", name, got.Size(), got.Align(), want.size, want.align) + } + class := 0 + switch got.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + class = 1 + case reflect.Ptr, reflect.UnsafePointer, reflect.Func: + class = 5 + case reflect.Float32, reflect.Float64: + class = 8 + case reflect.Struct: + class = 12 + if got.NumField() == 1 && got.Field(0).Name == "_xgo_union" { + class = 13 + } + } + if class != want.class { + t.Errorf("%s ABI class = %d (%v), C = %d", name, class, got.Kind(), want.class) + } + } + for _, tc := range signalFunctionPrototypes { + t.Run(tc.name, func(t *testing.T) { + inputs := len(tc.inputs) + if tc.variadic { + inputs++ + } + if tc.signature.Kind() != reflect.Func || tc.signature.NumIn() != inputs || tc.signature.IsVariadic() != tc.variadic { + t.Fatalf("Go signature = %v, C fixed parameters = %d, variadic = %v", tc.signature, len(tc.inputs), tc.variadic) + } + for i, slot := range tc.inputs { + check(tc.name+" parameter", tc.signature.In(i), slot) + } + outputs := 0 + if tc.output != nil { + outputs = 1 + } + if tc.signature.NumOut() != outputs { + t.Fatalf("Go result count = %d, C = %d", tc.signature.NumOut(), outputs) + } + if tc.output != nil { + check(tc.name+" result", tc.signature.Out(0), *tc.output) + } + }) + } + for _, tc := range signalStaticFunctionPrototypes { + t.Run(tc.name, func(t *testing.T) { + for _, slot := range tc.slots { + if slot.goType != nil { + check(tc.name+" "+slot.label, slot.goType, slot.want) + } else if slot.got != slot.want { + t.Errorf("%s %s ABI = %+v, C = %+v", tc.name, slot.label, slot.got, slot.want) + } + } + }) + } + + }) + t.Run("native types and globals", func(t *testing.T) { + for _, tc := range signalTypeLayouts { + t.Run(tc.symbol+"/"+tc.property, func(t *testing.T) { + if tc.got != tc.want { + t.Fatalf("Go layout = %d, C headers = %d", tc.got, tc.want) + } + }) + } + for _, symbol := range signalVariableSymbols { + if symbol.address == nil { + t.Errorf("%s C variable address is nil", symbol.name) + } + t.Logf("%s C variable address: %p", symbol.name, symbol.address) + } + }) + t.Run("native constants", func(t *testing.T) { + for _, tc := range signalIntegerConstants { + t.Run(tc.name, func(t *testing.T) { + if tc.got != tc.want { + t.Fatalf("Go constant = %d, C headers = %d", tc.got, tc.want) + } + }) + } + }) + t.Run("union accessors", func(t *testing.T) { + for _, tc := range signalAccessorChecks { + t.Run(tc.name, func(t *testing.T) { + offset, size, align := tc.check() + if offset != tc.offset || size != tc.size || align != tc.align { + t.Fatalf("Go field offset/size/alignment = %d/%d/%d, C = %d/%d/%d", offset, size, align, tc.offset, tc.size, tc.align) + } + }) + } + }) + t.Run("symbol inventory", func(t *testing.T) { + functions, prototypes, types, constants, variables := map[string]bool{}, map[string]bool{}, map[string]bool{}, map[string]bool{}, map[string]bool{} + for _, tc := range signalFunctionPrototypes { + prototypes[tc.name] = true + } + for _, tc := range signalStaticFunctionPrototypes { + prototypes[tc.name] = true + } + + for _, symbol := range signalFunctionSymbols { + functions[symbol.name] = true + if !prototypes[symbol.name] { + t.Errorf("%s has no native prototype test", symbol.name) + } + } + for _, tc := range signalAccessorChecks { + functions[tc.name] = true + } + for _, tc := range signalTypeLayouts { + types[tc.symbol] = true + } + for _, tc := range signalIntegerConstants { + constants[tc.name] = true + } + for _, symbol := range signalVariableSymbols { + variables[symbol.name] = true + } + constants["LLGoPackage"] = true + functions["Signal"] = true + if LLGoPackage != "link" { + t.Errorf("LLGoPackage = %q, want link", LLGoPackage) + } + files := []string{"libc_" + runtime.GOOS + "_" + runtime.GOARCH + ".go"} + + for _, filename := range files { + source, err := parser.ParseFile(token.NewFileSet(), filename, nil, parser.ParseComments) + if err != nil { + t.Fatal(err) + } + for _, declaration := range source.Decls { + switch decl := declaration.(type) { + case *ast.FuncDecl: + name := decl.Name.Name + if !ast.IsExported(name) { + continue + } + if decl.Recv != nil { + receiver, prefix := decl.Recv.List[0].Type, "" + if pointer, ok := receiver.(*ast.StarExpr); ok { + receiver, prefix = pointer.X, "*" + } + name = prefix + receiver.(*ast.Ident).Name + "." + name + } + if !functions[name] { + t.Errorf("%s: function %s has no test", filename, name) + } + if strings.HasPrefix(decl.Name.Name, "Native") && decl.Name.Name != "NativeSignal" { + t.Errorf("%s retains duplicate %s", filename, name) + } + if decl.Doc != nil { + for _, comment := range decl.Doc.List { + for _, private := range []string{"C._llcppg_", "C.__sig", "C.__sysv_signal", "C.__libc_current_sigrt"} { + if strings.Contains(comment.Text, private) { + t.Errorf("%s still exposes private C entry point %s", filename, private) + } + } + } + } + case *ast.GenDecl: + for _, specification := range decl.Specs { + switch spec := specification.(type) { + case *ast.TypeSpec: + if ast.IsExported(spec.Name.Name) && !types[spec.Name.Name] { + t.Errorf("%s: type %s has no ABI test", filename, spec.Name.Name) + } + case *ast.ValueSpec: + for _, name := range spec.Names { + if !ast.IsExported(name.Name) { + continue + } + if decl.Tok == token.CONST && !constants[name.Name] { + t.Errorf("%s: constant %s has no test", filename, name.Name) + } + if decl.Tok == token.VAR && !variables[name.Name] { + t.Errorf("%s: variable %s has no test", filename, name.Name) + } + } + } + } + } + } + } + t.Logf("coverage: %d C functions, %d Go union accessors, %d types/global layouts, %d constants, %d globals", len(signalFunctionSymbols), len(signalAccessorChecks), len(signalTypeLayouts), len(constants), len(signalVariableSymbols)) + }) + + var set SigsetT + var info SiginfoT + var value Sigval + if unsafe.Sizeof(set) != nativeSigsetSize || unsafe.Alignof(set) != nativeSigsetAlign { + t.Fatalf("sigset_t = %d/%d, want %d/%d", unsafe.Sizeof(set), unsafe.Alignof(set), nativeSigsetSize, nativeSigsetAlign) + } + if unsafe.Sizeof(info) != nativeSiginfoSize || unsafe.Alignof(info) != 8 { + t.Fatalf("siginfo_t = %d/%d, want %d/8", unsafe.Sizeof(info), unsafe.Alignof(info), nativeSiginfoSize) + } + if unsafe.Offsetof(info.SiSigno) != 0 || unsafe.Offsetof(info.SiErrno) != 4 || unsafe.Offsetof(info.SiCode) != 8 { + t.Fatalf("siginfo_t header offsets = %d/%d/%d", unsafe.Offsetof(info.SiSigno), unsafe.Offsetof(info.SiErrno), unsafe.Offsetof(info.SiCode)) + } + if unsafe.Sizeof(value) != 8 || unsafe.Alignof(value) != 8 { + t.Fatalf("sigval = %d/%d, want 8/8", unsafe.Sizeof(value), unsafe.Alignof(value)) + } + *value.XGof_ref_sival_int() = -7 + if got := *(*c.Int)(unsafe.Pointer(&value)); got != -7 { + t.Fatalf("sigval integer storage = %d, want -7", got) + } + var marker uintptr + *value.XGof_ref_sival_ptr() = unsafe.Pointer(&marker) + if got := *(*unsafe.Pointer)(unsafe.Pointer(&value)); got != unsafe.Pointer(&marker) { + t.Fatalf("sigval pointer storage = %p, want %p", got, &marker) + } + +}