the userspace ucontext API has this as an array rather than a
structure.
commit 3c59a86895 fixed the
corresponding mistake for vrregset_t, namely that the original
powerpc64 port used a mix of types from 32-bit powerpc and powerpc64
rather than matching the 64-bit types.
between v2 and v3 of the powerpc64 port patch, the change was made
from a 32x4 array of 32-bit unsigned ints for vrregs[] to a 32-element
array of __int128. this mismatches the API applications working with
mcontext_t expect from glibc, and seems to have been motivated by a
misinterpretation of a comment on how aarch64 did things as a
suggestion to do the same on powerpc64.
the mistaken layout seems to have been adapted from 32-bit powerpc,
where vscr and vrsave are packed into the same 128-bit slot in a way
that looks like it relies on non-overlapping-ness of the value bits in
big endian.
the powerpc64 port accounted for the fact that the 64-bit ABI puts
each in its own 128-bit slot, but ordered them incorrectly (matching
the bit order used on the 32-bit ABI), and failed to account for vscr
being padded according to endianness so that it can be accessed via
vector moves.
in addition to ABI layout, our definition used different logical
member layout/naming from glibc, where vscr is a structure to
facilitate access as a 32-bit word or a 128-bit vector. the
inconsistency here was unintentional, so fix it.
the previous values (2k min and 8k default) were too small for some
archs. aarch64 reserves 4k in the signal context for future extensions
and requires about 4.5k total, and powerpc reportedly uses over 2k.
the new minimums are chosen to fit the saved context and also allow a
minimal signal handler to run.
since the default (SIGSTKSZ) has always been 6k larger than the
minimum, it is also increased to maintain the 6k usable by the signal
handler. this happens to be able to store one pathname buffer and
should be sufficient for calling any function in libc that doesn't
involve conversion between floating point and decimal representations.
x86 (both 32-bit and 64-bit variants) may also need a larger minimum
(around 2.5k) in the future to support avx-512, but the values on
these archs are left alone for now pending further analysis.
the value for PTHREAD_STACK_MIN is not increased to match MINSIGSTKSZ
at this time. this is so as not to preclude applications from using
extremely small thread stacks when they know they will not be handling
signals. unfortunately cancellation and multi-threaded set*id() use
signals as an implementation detail and therefore require a stack
large enough for a signal context, so applications which use extremely
small thread stacks may still need to avoid using these features.
it should now really match the kernel. some of the removed padding
corresponded to the difference between user and kernel sigset_t. the
space at the end was redundant with the uc_mcontext member and seems
to have been added as a result of misunderstanding glibc's definition
versus the kernel's.
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.
also handle the non-GNUC case where alignment attribute is not available
by simply omitting it. this will not cause problems except for
inclusion of mcontex_t/ucontext_t in application-defined structures,
since the natural alignment of the uc_mcontext member relative to the
start of ucontext_t is already correct. and shame on whoever designed
this for making it impossible to satisfy the ABI requirements without
GNUC extensions.
based on initial work by rdp, with heavy modifications. some features
including threads are untested because qemu app-level emulation seems
to be broken and I do not have a proper system image for testing.
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...