a mips signal mask contains 128 bits, enough for signals 1 through
128. however, the exit status obtained from the wait-family functions
only has room for values up to 127. reportedly signal 128 was causing
kernelspace bugs, so it was removed from the kernel recently; even
without that issue, however, it was impossible to support it correctly
in userspace.
at the same time, the bug was masked on musl by SIGRTMAX incorrectly
yielding 64 on mips, rather than the "correct" value of 128. now that
the _NSIG issue is fixed, SIGRTMAX can be fixed at the same time,
exposing the full range of signals for application use.
note that the (nonstandardized) libc _NSIG value is actually one
greater than the max signal number, and also one greater than the
kernel headers' idea of _NSIG. this is the reason for the discrepency
with the recent kernel changes. since reducing _NSIG by one brought it
down from 129 to 128, rather than from 128 to 127, _NSIG/8, used
widely in the musl sources, is unchanged.
with these changes, the members/types of mcontext_t and related stuff
should closely match the glibc definitions. unlike glibc, however, the
definitions here avoid using typedefs as much as possible and work
directly with the underlying types, to minimize namespace pollution
from signal.h in the default (_BSD_SOURCE) profile.
this is a first step in improving compatibility with applications
which poke at context/register information -- mainly debuggers, trace
utilities, etc. additional definitions in ucontext.h and other headers
may be needed later.
if feature test macros are used to request a conforming namespace,
mcontext_t is replaced with an opaque structure of the equivalent size
and alignment; conforming programs cannot examine its contents anyway.
unlike the previous definition, NSIG/_NSIG is supposed to be one more
than the highest signal number. adding this will allow simplifying
libc-internal code that makes signal-related syscalls, which can be
done as a later step. some apps might use it too; while this usage is
questionable, it's at least not insane.
basically, this version of the code was obtained by starting with
rdp's work from his ellcc source tree, adapting it to musl's build
system and coding style, auditing the bits headers for discrepencies
with kernel definitions or glibc/LSB ABI or large file issues, fixing
up incompatibility with the old binutils from aboriginal linux, and
adding some new special cases to deal with the oddities of sigaction
and pipe syscall interfaces on mips.
at present, minimal test programs work, but some interfaces are broken
or missing. threaded programs probably will not link.
this is actually rather ugly, and would get even uglier if we ever
want to support further feature test macros. at some point i may
factor the bits headers into separate files for C base, POSIX base,
and nonstandard extensions (the only distinctions that seem to matter
now) and then the logic for which to include can go in the main header
rather than being duplicated for each arch. the downside of this is
that it would result in more files having to be opened during
compilation, so as long as the ugliness does not grow, i'm inclined to
leave it alone for now.
this port assumes eabi calling conventions, eabi linux syscall
convention, and presence of the kernel helpers at 0xffff0f?0 needed
for threads support. otherwise it makes very few assumptions, and the
code should work even on armv4 without thumb support, as well as on
systems with thumb interworking. the bits headers declare this a
little endian system, but as far as i can tell the code should work
equally well on big endian.
some small details are probably broken; so far, testing has been
limited to qemu/aboriginal linux.
only the structures, not the functions from ucontext.h, are supported
at this point. the main goal of this commit is to make modern gcc with
dwarf2 unwinding build without errors.
honestly, it probably doesn't matter how we define these as long as
they have members with the right names to prevent errors while
compiling libgcc. the only time they will be used is for propagating
exceptions across signal-handler boundaries, which invokes undefined
behavior anyway. but as-is, they're probably correct and may be useful
to various low-level applications dealing with virtualization, jit
code generation, and so on...