If a signal arrived during a symbol lookup and the signal handler also
required a symbol lookup, the end of the lookup in the signal handler reset
the flag whether restoring AVX/SSE registers is needed. Resetting means
in this case that the tail part of the outer lookup code will try to
restore the registers and this can fail miserably. We now restore to the
previous value which makes nesting calls possible.
The syscall wrappers had to save and restore the syscall parameter
values and return value when calling the functions to enable/disable
cancellation were called. Not anymore. The called functions are
special and don't modify any unexpected registers.
SSE registers are used for passing parameters and must be preserved
in runtime relocations. This is inside ld.so enforced through the
tests in tst-xmmymm.sh. But the malloc routines used after startup
come from libc.so and can be arbitrarily complex. It's overkill
to save the SSE registers all the time because of that. These calls
are rare. Instead we save them on demand. The new infrastructure
put in place in this patch makes this possible and efficient.
It just happens that __pthread_enable_asynccancel doesn't modify the $rdi
register. But this isn't guaranteed. Hence we reload the register after
the calls.
The kernel from 2.3.31 on supports the rt_tgsigqueueinfo syscall.
Use it to implement the non-standard extension which, like
sigqueue, can pass additional data to the receiving thread.
Due to a pasto the fallocate64 interface, introduced in glibc 2.10,
isn't exported for 32-bit Linux platforms. It is too late for this
now so exported them for glibc 2.11.
Because we are not shutting down the other threads first another
thread might work on a query before the process shuts down. In this
case the now uninitialized libselinux and libaudit might be used.
Just don't free the resources. It's not necessary anyway because
the process is about to terminate.
The bits tested to decide when to delay the return when switching
off async cancel mode were wrong. Fix that. Also close a race
condition in pthread_cancel where the bit indicating the cancellation
is unconditionally set even if the cancel type might have changed.
When disabling async cancellation we cannot return from the function
call if the thread is canceled. This happens when the cancel bits
have been set before async cancel is disabled but the signal hasn't
been sent/received yet. Delay for as long as necessary since
otherwise the signal might be received in an unsafe context.