POSIX requires that we make a copy, so we allocate a new string
and free it in posix_spawn_file_actions_destroy.
Reported by David Reid, Alex Gaynor, and Glyph Lefkowitz. This bug
may have security implications.
As with other issues of this kind, bug 17042 is log2 (1) wrongly
returning -0 instead of +0 in round-downward mode because of
implementations effectively in terms of log1p (x - 1). This patch
fixes the issue in the same way used for log and log10.
Tested x86_64 and x86 and ulps updated accordingly. Also tested for
mips64 to confirm a fix was needed for ldbl-128 and to validate that
fix (also applied to ldbl-128ibm since that version of log2l is
essentially the same as the ldbl-128 one).
[BZ #17042]
* sysdeps/i386/fpu/e_log2.S (__ieee754_log2): Take absolete value
when x - 1 is zero.
* sysdeps/i386/fpu/e_log2f.S (__ieee754_log2f): Likewise.
* sysdeps/i386/fpu/e_log2l.S (__ieee754_log2l): Likewise.
* sysdeps/ieee754/ldbl-128/e_log2l.c (__ieee754_log2l): Return
0.0L for an argument of 1.0L.
* sysdeps/ieee754/ldbl-128ibm/e_log2l.c (__ieee754_log2l):
Likewise.
* sysdeps/x86_64/fpu/e_log2l.S (__ieee754_log2l): Take absolute
value when x - 1 is zero.
* math/libm-test.inc (log2_test): Use ALL_RM_TEST.
* sysdeps/i386/fpu/libm-test-ulps: Update.
* sysdeps/x86_64/fpu/libm-test-ulps: Likewise.
The current code for handling concurrent resolution says that the
ABI for _dl_tlsdesc_resolve_hold is the same as that of
_dl_tlsdesc_lazy_resolver. However _dl_tlsdesc_resolve_hold is
called from the trampoline directly rather than the lazy resolver
stub so, for example, r2 has not been pushed so does not needed
to be restored.
This fixes an intermittent failure in nptl/tst-tls3 when building
glibc for arm-linux-gnueabihf with -mtls-dialect=gnu2.
ChangeLog:
2014-05-27 Will Newton <will.newton@linaro.org>
[BZ #16990]
* sysdeps/arm/dl-tlsdesc.S (_dl_tlsdesc_resolve_hold): Save
and restore r2 rather than just restoring.
The offset computation in write mode uses the fact that _IO_read_end
is kept in sync with the external file offset. This however is not
true when O_APPEND is in effect since switching to write mode ought to
send the external file offset to the end of file without making the
necessary adjustment to _IO_read_end.
Hence in append mode, offset computation when writing should only
consider the effect of unflushed writes, i.e. from _IO_write_base to
_IO_write_ptr.
The wiki has a detailed document that describes the rationale for
offsets returned by ftell in various conditions:
https://sourceware.org/glibc/wiki/File%20offsets%20in%20a%20stdio%20stream%20and%20ftell
This fixes a variety of testsuite failures for me:
tststatic.out Error 1
tststatic2.out Error 1
tst-tls9-static.out Error 1
tst-audit8.out Error 127
tst-audit9.out Error 127
tst-audit1.out Error 127
and also has the added benefit of making LD_AUDIT/sotruss work on
AArch64.
Otherwise, we bail out early in _dl_try_allocate_static_tls as the
alignment requirement of the PT_TLS section in libc is 16.
The netgroups nss modules in the glibc tree use NSS_STATUS_UNAVAIL
(with errno as ERANGE) when the supplied buffer does not have
sufficient space for the result. This is wrong, because the canonical
way to indicate insufficient buffer is to set the errno to ERANGE and
the status to NSS_STATUS_TRYAGAIN, as is used by all other modules.
This fixes nscd behaviour when the nss_ldap module returns
NSS_STATUS_TRYAGAIN to indicate that a netgroup entry is too long to
fit into the supplied buffer.
As noted in bug 16978, older POSIX versions include
in the specified contents of <tar.h>, with only the 2001 edition
introducing the notion of XSI-conditional definitions and conditioning
that definition. Thus, this macro should be defined for
!__USE_XOPEN2K as well as for __USE_XOPEN, and this patch duly defines
it in that case. Tested x86_64.
[BZ #16978]
* posix/tar.h [!__USE_XOPEN2K] (TSVTX): Define macro.
* conform/Makefile (test-xfail-POSIX/tar.h/conform): Remove
variable.
As with various other issues of this kind, bug 16977 is log10 (1)
wrongly returning -0 rather than +0 in round-downward mode because of
an implementation effectively in terms of log1p (x - 1). This patch
fixes the issue in the same way used for log.
Tested x86_64 and x86 and ulps updated accordingly. Also tested for
mips64 to confirm a fix was needed for ldbl-128 and to validate that
fix (also applied to ldbl-128ibm since that version of logl is
essentially the same as the ldbl-128 one).
[BZ #16977]
* sysdeps/i386/fpu/e_log10.S (__ieee754_log10): Take absolute
value when x - 1 is zero.
* sysdeps/i386/fpu/e_log10f.S (__ieee754_log10f): Likewise.
* sysdeps/i386/fpu/e_log10l.S (__ieee754_log10l): Likewise.
* sysdeps/ieee754/ldbl-128/e_log10l.c (__ieee754_log10l): Return
0.0L for an argument of 1.0L.
* sysdeps/ieee754/ldbl-128ibm/e_log10l.c (__ieee754_log10l):
Likewise.
* sysdeps/x86_64/fpu/e_log10l.S (__ieee754_log10l): Take absolute
value when x - 1 is zero.
* math/libm-test.inc (log10_test): Use ALL_RM_TEST.
* sysdeps/i386/fpu/libm-test-ulps: Update.
* sysdeps/x86_64/fpu/libm-test-ulps: Likewise.
This patch fixes an issue observed running the tst-strtod-round test on
32 bit sparc. In some conditions, strtold calls round_and_return, which in
turn calls __mpn_rshift with cnt = 0, while stdlib/rshift.c explicitly says
that cnts should satisfy 0 < CNT < BITS_PER_MP_LIMB. In this case, the code
end up doing a logical shift right of the same amount than the register,
which is undefined in the C standard.
Due to this bug, 32-bit sparc does not correctly convert the value
"0x1p-16446", but it is likely that other architectures are also
affected for other input values.
For static linking the locale code avoids linking code and data for
unused categories. However for nl_langinfo we know only at runtime which
categories are used, so direct reference to every nl_current_CATEGORY
symbol should be done.
This was broken by commit bc3e1c1273 where
nl_langinfo_l and nl_langinfo have been merged and some code has been
lost in the process.
In order to detect locales issues with static linking, compile a version
of tst-langinfo with static linking.
Note: this is Debian bug#747103 reported by Raphael <raphael.astier@eliot-sa.com>
Using the default header instead. This matches the kernel, which also
uses the generic header. Fixes the sys/wait.h conform issue, where
si_band had the wrong type.
prlimit and prlimit64 have been added in the main <bits/resource.h>, but
not in the SPARC specific version. Fix that.
Note: this is Debian bug#703559, reported by Emilio Pozuelo Monfort
<pochu@debian.org>
If the fd refers to a terminal device, but not a pty master, the
TIOCGPTN ioctl returns with ENOTTY. This error is not caught, and the
possibly undefined buffer passed to ptsname_r is sent directly to the
stat64 syscall.
Fix this by using a fallback to the old method only if the TIOCGPTN
ioctl fails with EINVAL. This also fix the return value in that specific
case (it return ENOENT without this patch).
Also add tests to the ptsname_r function (and ptsname at the same time).
Note: this is Debian bug#741482, reported by Jakub Wilk <jwilk@debian.org>
getaddrinfo correctly returns EAI_AGAIN for AF_INET and AF_INET6
queries. For AF_UNSPEC however, an older change
(a682a1bf55) broke the check and due to
that the returned error was EAI_NONAME.
This patch fixes the check so that a non-authoritative not-found is
returned as EAI_AGAIN to the user instead of EAI_NONAME.
Bug 16564 is spurious overflow of log1pl (LDBL_MAX) in FE_UPWARD mode,
resulting from log1pl adding 1 to its argument (for arguments not
close to 0), which overflows in that mode. This patch fixes this by
avoiding adding 1 to large arguments (precisely what counts as large
depends on the floating-point format).
Tested x86_64 and x86, and spot-checked log1pl tests on mips64 and
powerpc64.
[BZ #16564]
* sysdeps/i386/fpu/s_log1pl.S (__log1pl): Do not add 1 to positive
arguments with exponent 65 or above.
* sysdeps/ieee754/ldbl-128/s_log1pl.c (__log1pl): Do not add 1 to
arguments 0x1p113L or above.
* sysdeps/ieee754/ldbl-128ibm/s_log1pl.c (__log1pl): Do not add 1
to arguments 0x1p107L or above.
* sysdeps/x86_64/fpu/s_log1pl.S (__log1pl): Do not add 1 to
positive arguments with exponent 65 or above.
* math/auto-libm-test-in: Add more tests of log1p.
* math/auto-libm-test-out: Regenerated.
According to C99/C11 Annex G, cacos applied to a value with real part
+Inf and finite imaginary part should produce a result with real part
+0. glibc wrongly produces a result with real part -0 in FE_DOWNWARD
mode. This patch fixes this by checking for zero results in the
relevant case of non-finite arguments (where there should never be a
result with -0 real part), and converts the tests of cacos to
ALL_RM_TEST.
Tested x86_64 and x86 and ulps updated accordingly.
[BZ #16928]
* math/s_cacos.c (__cacos): Ensure zero real part of result from
non-finite arguments is +0.
* math/s_cacosf.c (__cacosf): Likewise.
* math/s_cacosl.c (__cacosl): Likewise.
* math/libm-test.inc (cacos_test): Use ALL_RM_TEST.
* sysdeps/i386/fpu/libm-test-ulps: Update.
* sysdeps/x86_64/fpu/libm-test-ulps: Likewise.
According to C99 and C11 Annex F, acosh (1) should be +0 in all
rounding modes. However, some implementations in glibc wrongly return
-0 in round-downward mode (which is what you get if you end up
computing log1p (-0), via 1 - 1 being -0 in round-downward mode).
This patch fixes the problem implementations, by correcting the test
for an exact 1 value in the ldbl-96 implementation to allow for the
explicit high bit of the mantissa, and by inserting fabs instructions
in the i386 implementations; tests of acosh are duly converted to
ALL_RM_TEST. I believe all the other sysdeps/ieee754 implementations
are already OK (I haven't checked the ia64 versions, but if buggy then
that will be obvious from the results of test runs after this patch is
in).
Tested x86_64 and x86 and ulps updated accordingly.
[BZ #16927]
* sysdeps/i386/fpu/e_acosh.S (__ieee754_acosh): Use fabs on x-1
value.
* sysdeps/i386/fpu/e_acoshf.S (__ieee754_acoshf): Likewise.
* sysdeps/i386/fpu/e_acoshl.S (__ieee754_acoshl): Likewise.
* sysdeps/ieee754/ldbl-96/e_acoshl.c (__ieee754_acoshl): Correct
for explicit high bit of mantissa when testing for argument equal
to 1.
* math/libm-test.inc (acosh_test): Use ALL_RM_TEST.
* sysdeps/i386/fpu/libm-test-ulps: Update.
* sysdeps/x86_64/fpu/libm-test-ulps: Likewise.
Bug 16516 reports spurious underflows from erf (for all floating-point
types), when the result is close to underflowing but does not actually
underflow.
erf (x) is about (2/sqrt(pi))*x for x close to 0, so there are
subnormal arguments for which it does not underflow. The various
implementations do (x + efx*x) (for efx = 2/sqrt(pi) - 1), for greater
accuracy than if just using a single multiplication by an
approximation to 2/sqrt(pi) (effectively, this way there are a few
more bits in the approximation to 2/sqrt(pi)). This can introduce
underflows when efx*x underflows even though the final result does
not, so a scaled calculation with 8*efx is done in these cases - but 8
is not a big enough scale factor to avoid all such underflows. 16 is
(any underflows with a scale factor of 16 would only occur when the
final result underflows), so this patch changes the code to use that
factor. Rather than recomputing all the values of the efx8 variable,
it is removed, leaving it to the compiler's constant folding to
compute 16*efx. As such scaling can also lose underflows when the
final scaling down happens to be exact, appropriate checks are added
to ensure underflow exceptions occur when required in such cases.
Tested x86_64 and x86; no ulps updates needed. Also spot-checked for
powerpc32 and mips64 to verify the changes to the ldbl-128ibm and
ldbl-128 implementations.
[BZ #16516]
* sysdeps/ieee754/dbl-64/s_erf.c (efx8): Remove variable.
(__erf): Scale by 16 instead of 8 in potentially underflowing
case. Ensure exception if result actually underflows.
* sysdeps/ieee754/flt-32/s_erff.c (efx8): Remove variable.
(__erff): Scale by 16 instead of 8 in potentially underflowing
case. Ensure exception if result actually underflows.
* sysdeps/ieee754/ldbl-128/s_erfl.c: Include <float.h>.
(efx8): Remove variable.
(__erfl): Scale by 16 instead of 8 in potentially underflowing
case. Ensure exception if result actually underflows.
* sysdeps/ieee754/ldbl-128ibm/s_erfl.c: Include <float.h>.
(efx8): Remove variable.
(__erfl): Scale by 16 instead of 8 in potentially underflowing
case. Ensure exception if result actually underflows.
* sysdeps/ieee754/ldbl-96/s_erfl.c: Include <float.h>.
(efx8): Remove variable.
(__erfl): Scale by 16 instead of 8 in potentially underflowing
case. Ensure exception if result actually underflows.
* math/auto-libm-test-in: Add more tests of erf.
* math/auto-libm-test-out: Regenerated.
This patch fixes bug 16064, i386 fenv_t not including SSE state, using
the technique suggested there of storing the state in the existing
__eip field of fenv_t to avoid needing to increase the size of fenv_t
and add new symbol versions. The included testcase, which previously
failed for i386 (but passed for x86_64), illustrates how the previous
state was buggy.
This patch causes the SSE state to be included *to the extent it is on
x86_64*. Where some state should logically be included but isn't for
x86_64 (see bug 16068), this patch does not cause it to be included
for i386 either. The idea is that any patch fixing that bug should
fix it for both x86_64 and i386 at once.
Tested i386 and x86_64. (I haven't tested the case of a CPU without
SSE2 disabling the test.)
[BZ #16064]
* sysdeps/i386/fpu/fegetenv.c: Include <unistd.h>, <ldsodefs.h>
and <dl-procinfo.h>.
(__fegetenv): Save SSE state in envp->__eip if supported.
* sysdeps/i386/fpu/feholdexcpt.c (feholdexcept): Save SSE state in
envp->__eip if supported.
* sysdeps/i386/fpu/fesetenv.c: Include <unistd.h>, <ldsodefs.h>
and <dl-procinfo.h>.
(__fesetenv): Always set __eip, __cs_selector, __opcode,
__data_offset and __data_selector in environment to 0. Set SSE
state if supported.
* sysdeps/x86/fpu/Makefile [$(subdir) = math] (tests): Add
test-fenv-sse.
[$(subdir) = math] (CFLAGS-test-fenv-sse.c): Add -msse2
-mfpmath=sse.
* sysdeps/x86/fpu/test-fenv-sse.c: New file.
Added support for TX lock elision of pthread mutexes on s390 and
s390x. This may improve lock scaling of existing programs on TX
capable systems. The lock elision code is only built with
--enable-lock-elision=yes and then requires a GCC version supporting
the TX builtins. With lock elision default mutexes are elided via
__builtin_tbegin, if the cpu supports transactions. By default lock
elision is not enabled and the elision code is not built.
Add an optimized implementation of strcmp for ARMv7-A cores. This
implementation is significantly faster than the current generic C
implementation, particularly for strings of 16 bytes and longer.
Tested with the glibc string tests for arm-linux-gnueabihf and
armeb-linux-gnueabihf.
The code was written by ARM, who have agreed to assign the copyright
to the FSF for integration into glibc.
ChangeLog:
2014-05-09 Will Newton <will.newton@linaro.org>
* sysdeps/arm/armv7/strcmp.S: New file.
* NEWS: Mention addition of ARMv7 optimized strcmp.
This patch fixes what I believe to be a bug in the handling of
R_ARM_IRELATIVE RELA relocations. At present, these are handled the
same as REL relocations: i.e. the addend is loaded from the relocation
address. Most of the time this isn't a problem because RELA relocations
aren't used on ARM (GNU/Linux at least) anyway, but it causes problems
with prelink, which uses RELA on all targets for its conflict table.
(Support for ifunc prelinking requires a prelink patch, not yet posted.)
Anyway, this patch works, though I'm not 100% sure if it is correct: I
notice that this code path received attention last year:
https://sourceware.org/ml/libc-ports/2013-07/msg00000.html
I'm not sure under what circumstances that patch would have had an
effect, nor if my patch conflicts with that case.
No regressions using Mentor's usual glibc cross-testing infrastructure.
[BZ #16888]
* sysdeps/arm/dl-machine.h (elf_machine_rela): Fix R_ARM_IRELATIVE
handling.
This patch increases the minimum Linux kernel version for glibc to
2.6.32, as discussed in the thread starting at
<https://sourceware.org/ml/libc-alpha/2014-01/msg00511.html>.
This patch just does the minimal change to arch_minimum_kernel
settings (and LIBC_LINUX_VERSION, which determines the minimum kernel
headers version, as it doesn't make sense for that to be older than
the minimum kernel that can be used at runtime). Followups would be
expected to do, roughly and not necessarily precisely in this order:
* Remove __LINUX_KERNEL_VERSION checks in kernel-features.h files
where those checks are always true / always false for kernels 2.6.32
and above.
* Otherwise simplify/improve conditionals in those files (for example,
where defining once in the main file then undefining in
architecture-specific files makes things clearer than having lots of
separate definitions of the same macro), possibly fixing in the
process cases where a macro should optimally have been defined for a
given architecture but wasn't. (In the review in preparation for
this version increase I checked what the right conditions should be
for all macros in the main kernel-features.h whose definitions there
would have been affected by the increase - but I only fixed that
subset of the issues found where --enable-kernel=2.6.32 would have
caused a kernel feature to be wrongly assumed to be present, not any
cases where a feature is not assumed but could be assumed.)
* Remove conditionals on __ASSUME_* where they can now be taken to be
always-true, and the definitions when the macros are only used in
Linux-specific files.
* Split more architectures out of the main kernel-features.h (like
ex-ports architectures), once various of the architecture
conditionals there have been eliminated so the new
architecture-specific files are no larger than actually necessary.
Tested x86_64.
2014-03-27 Joseph Myers <joseph@codesourcery.com>
[BZ #9894]
* sysdeps/unix/sysv/linux/configure.ac (LIBC_LINUX_VERSION):
Change to 2.6.32.
(arch_minimum_kernel): Change all 2.6.16 settings to 2.6.32.
* sysdeps/unix/sysv/linux/configure: Regenerated.
* sysdeps/unix/sysv/linux/microblaze/configure.ac: Remove file.
* sysdeps/unix/sysv/linux/microblaze/configure: Likewise.
* sysdeps/unix/sysv/linux/tile/configure.ac: Likewise.
* sysdeps/unix/sysv/linux/tile/configure: Likewise.
* README: Update reference to required Linux kernel version.
* manual/install.texi (Linux): Update reference to required Linux
kernel headers version.
* INSTALL: Regenerated.
The datahead structure has an unused padding field that remains
uninitialized. Valgrind prints out a warning for it on querying a
netgroups entry. This is harmless, but is a potential data leak since
it would result in writing out an uninitialized byte to the cache
file. Besides, this happens only when there is a cache miss, so we're
not adding computation to any fast path.
[Fixes BZ #14308, #12994, #13651]
AF_UNSPEC results in sending two queries in parallel, one for the A
record and the other for the AAAA record. If one of these is a
referral, then the query fails, which is wrong. It should return at
least the one successful response.
The fix has two parts. The first part makes the referral fall back to
the SERVFAIL path, which results in using the successful response.
There is a bug in that path however, due to which the second part is
necessary. The bug here is that if the first response is a failure
and the second succeeds, __libc_res_nsearch does not detect that and
assumes a failure. The case where the first response is a success and
the second fails, works correctly.
This condition is produced by buggy routers, so here's a crude
interposable library that can simulate such a condition. The library
overrides the recvfrom syscall and modifies the header of the packet
received to reproduce this scenario. It has two key variables:
mod_packet and first_error.
The mod_packet variable when set to 0, results in odd packets being
modified to be a referral. When set to 1, even packets are modified
to be a referral.
The first_error causes the first response to be a failure so that a
domain-appended search is performed to test the second part of the
__libc_nsearch fix.
The driver for this fix is a simple getaddrinfo program that does an
AF_UNSPEC query. I have omitted this since it should be easy to
implement.
I have tested this on x86_64.
The interceptor library source:
/* Override recvfrom and modify the header of the first DNS response to make it
a referral and reproduce bz #845218. We have to resort to this ugly hack
because we cannot make bind return the buggy response of a referral for the
AAAA record and an authoritative response for the A record. */
#define _GNU_SOURCE
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdbool.h>
#include <endian.h>
#include <dlfcn.h>
#include <stdlib.h>
/* Lifted from resolv/arpa/nameser_compat.h. */
typedef struct {
unsigned id :16; /*%< query identification number */
#if BYTE_ORDER == BIG_ENDIAN
/* fields in third byte */
unsigned qr: 1; /*%< response flag */
unsigned opcode: 4; /*%< purpose of message */
unsigned aa: 1; /*%< authoritive answer */
unsigned tc: 1; /*%< truncated message */
unsigned rd: 1; /*%< recursion desired */
/* fields
* in
* fourth
* byte
* */
unsigned ra: 1; /*%< recursion available */
unsigned unused :1; /*%< unused bits (MBZ as of 4.9.3a3) */
unsigned ad: 1; /*%< authentic data from named */
unsigned cd: 1; /*%< checking disabled by resolver */
unsigned rcode :4; /*%< response code */
#endif
#if BYTE_ORDER == LITTLE_ENDIAN || BYTE_ORDER == PDP_ENDIAN
/* fields
* in
* third
* byte
* */
unsigned rd :1; /*%< recursion desired */
unsigned tc :1; /*%< truncated message */
unsigned aa :1; /*%< authoritive answer */
unsigned opcode :4; /*%< purpose of message */
unsigned qr :1; /*%< response flag */
/* fields
* in
* fourth
* byte
* */
unsigned rcode :4; /*%< response code */
unsigned cd: 1; /*%< checking disabled by resolver */
unsigned ad: 1; /*%< authentic data from named */
unsigned unused :1; /*%< unused bits (MBZ as of 4.9.3a3) */
unsigned ra :1; /*%< recursion available */
#endif
/* remaining
* bytes
* */
unsigned qdcount :16; /*%< number of question entries */
unsigned ancount :16; /*%< number of answer entries */
unsigned nscount :16; /*%< number of authority entries */
unsigned arcount :16; /*%< number of resource entries */
} HEADER;
static int done = 0;
/* Packets to modify. 0 for the odd packets and 1 for even packets. */
static const int mod_packet = 0;
/* Set to true if the first request should result in an error, resulting in a
search query. */
static bool first_error = true;
static ssize_t (*real_recvfrom) (int sockfd, void *buf, size_t len, int flags,
struct sockaddr *src_addr, socklen_t *addrlen);
void
__attribute__ ((constructor))
init (void)
{
real_recvfrom = dlsym (RTLD_NEXT, "recvfrom");
if (real_recvfrom == NULL)
{
printf ("Failed to get reference to recvfrom: %s\n", dlerror ());
printf ("Cannot simulate test\n");
abort ();
}
}
/* Modify the second packet that we receive to set the header in a manner as to
reproduce BZ #845218. */
static void
mod_buf (HEADER *h, int port)
{
if (done % 2 == mod_packet || (first_error && done == 1))
{
printf ("(Modifying header)");
if (first_error && done == 1)
h->rcode = 3;
else
h->rcode = 0; /* NOERROR == 0. */
h->ancount = 0;
h->aa = 0;
h->ra = 0;
h->arcount = 0;
}
done++;
}
ssize_t
recvfrom (int sockfd, void *buf, size_t len, int flags,
struct sockaddr *src_addr, socklen_t *addrlen)
{
ssize_t ret = real_recvfrom (sockfd, buf, len, flags, src_addr, addrlen);
int port = htons (((struct sockaddr_in *) src_addr)->sin_port);
struct in_addr addr = ((struct sockaddr_in *) src_addr)->sin_addr;
const char *host = inet_ntoa (addr);
printf ("\n*** From %s:%d: ", host, port);
mod_buf (buf, port);
printf ("returned %zd\n", ret);
return ret;
}
The current implementation of setcontext uses rt_sigreturn to restore
the contents of registers. This contrasts with the way most other
architectures implement setcontext:
powerpc64, mips, tile:
Call rt_sigreturn if context was created by a call to a signal handler,
otherwise restore in user code.
powerpc32:
Call swapcontext system call and don't call sigreturn or rt_sigreturn.
x86_64, sparc, hppa, sh, ia64, m68k, s390, arm:
Only support restoring "synchronous" contexts, that is contexts
created by getcontext, and restoring in user code and don't call
sigreturn or rt_sigreturn.
alpha:
Call sigreturn (but not rt_sigreturn) in all cases to do the restore.
The text of the setcontext manpage suggests that the requirement to be
able to restore a signal handler created context has been dropped from
SUSv2:
If the context was obtained by a call to a signal handler, then old
standard text says that "program execution continues with the program
instruction following the instruction interrupted by the signal".
However, this sentence was removed in SUSv2, and the present verdict
is "the result is unspecified".
Implementing setcontext by calling rt_sigreturn unconditionally causes
problems when used with sigaltstack as in BZ #16629. On this basis it
seems that aarch64 is broken and that new ports should only support
restoring contexts created with getcontext and do not need to call
rt_sigreturn at all.
This patch re-implements the aarch64 setcontext function to restore
the context in user code in a similar manner to x86_64 and other ports.
ChangeLog:
2014-04-17 Will Newton <will.newton@linaro.org>
[BZ #16629]
* sysdeps/unix/sysv/linux/aarch64/setcontext.S (__setcontext):
Re-implement to restore registers in user code and avoid
rt_sigreturn system call.