logb (+-0) is a pole error: it returns -Inf and raises the
divide-by-zero exception, but it never set errno, even though glibc
defines math_errhandling to include MATH_ERRNO.
Set errno in the zero branch that already exists in every logb
implementation, instead of adding a w_logb wrapper; the
USE_LOGB*_BUILTIN paths have no such branch, so add one there. The
double and float versions use __math_divzero and __math_divzerof.
There is no long double equivalent, so those keep the explicit
division and use math_opt_barrier to stop the compiler from folding
it away.
The i386 fxtract implementations of logb and logbf cannot set errno,
and adding the error handling to the assembly is not worthwhile, so
they are removed in favour of the generic C ones. s_logbl.c moves to
sysdeps/x86/fpu, replacing the x86_64 copy that only included it.
The manual described logb (0) as returning +Inf without signalling,
which was wrong in both respects.
Tested on x86_64-linux-gnu.
Signed-off-by: Shamil Abdulaev <ashamil435@gmail.com>
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
DO_DIVBYZERO placed __divbyzero in .gnu.linkonce.t.divbyzero so that,
when building the PIC libc.so, every divide routine's copy collapses to
one. .gnu.linkonce is a pre-comdat-group GNU convention that no current
toolchain emits and that upstream lld has declined to support in full
generality, since a linked-to section from outside a group is not valid
ELF and every non-GNU-as producer has used SHT_GROUP comdat groups
instead for 25+ years.
BZ #20543 tracked this migration across glibc; i386's PIC-thunk section
was converted, but alpha's divide-by-zero handler was missed. Switch it
to the same "axG",@progbits,<sym>,comdat idiom already used by the i386
and sparc PIC-thunk sections, so it is deduplicated via a real ELF group
rather than section-name matching.
Divide routines reach the handler via `beq Y, DIVBYZERO`, a 21-bit
word-displacement branch (+-4MB range). The old .gnu.linkonce.t.* name
put the section in the default linker script's last .text bucket,
guaranteeing it trailed all other code; .text.__divbyzero lands one
bucket earlier alongside other .text.* input sections, so "last in
.text" is no longer guaranteed (PIC libc.so only; libc.a keeps per-file
copies). Measured on an alpha-unknown-linux-gnu build, __divbyzero
landed a few hundred bytes from the end of a ~1.6MB .text. An
out-of-range branch would fail the link with "relocation truncated to
fit" rather than produce a silently broken libc.
Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
Commit 21841f0d56 ("PowerPC: Influence cpu/arch hwcap features via
GLIBC_TUNABLES") changed the INIT_ARCH() macro used by powerpc32/power4
and (via a one-line include) powerpc64 multiarch IFUNC resolvers to
read hwcap and hwcap2 through a direct
&GLRO(dl_powerpc_cpu_features)
reference, instead of the previous __GLRO() wrapper. The __GLRO() macro
performs a volatile NULL check on _rtld_global_ro, which matters because
IFUNC resolvers can run before _rtld_global_ro has been relocated for the
current library.
This regression triggers when a shared library's IFUNC symbol from libm
is resolved via BIND_NOW (full RELRO) before libm's own GOT is relocated:
the resolver's INIT_ARCH() then dereferences a NULL _rtld_global_ro and
segfaults at the hwcap load. The concrete failure seen was rsyslogd
crashing on startup on powerpc64 (e5500, BE) with
rsyslogd -> librsyslog -> libfastjson -> modf() IFUNC in libm
when libfastjson lacked a DT_NEEDED on libm, so libm was relocated after
libfastjson's IFUNC resolvers ran.
Restore the __GLRO()-based access for both hwcap and hwcap2, matching
the pre-2.41 behaviour and how use_cached_memopt is already read in the
same macro. This is a no-op once _rtld_global_ro is fully initialised
and simply reinstates the early-startup NULL guard.
Add a regression test (ppc64 only; ppc32 has additional early-startup
constraints that make the same test infeasible there). The module is
linked with -z,now and intentionally has no DT_NEEDED on libm, so the
IFUNC resolver for modf() runs before libm is fully relocated.
Signed-off-by: Michael Pfeifroth <micpf@westermo.com>
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
As documented by posix & linux, if the real ID is set or the effective ID is
set to a value not equal to the previous real ID, the saved ID shall be set
to the new effective ID.
Also fix __pthread_tpp_change_priority to undo changes to the priomap
array if any of the scheduler system calls fail.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
The BZ#33326 testcase triggers an assertion during process startup,
which results in a segmentation fault instead of an error message
and process termination with a SIGABRT. The assert issues
__libc_message_impl, which in turn might call string functions
depending on the ABI (strchrnul, strlen, memcpy/mempcpy), system
calls (writev and mmap), and finally the abort call.
The dl-symbol-redir-ifunc.h is also expanded to cover strchrnul on
x86_64, s390, powerpc64 (both endianness) and loongarch, mempcpy on
powerpc64be, and memcpy on aarch64. On s390 the redirection is only
issued if the ifunc variant is built, since strchrnul-c.c only renames
the C implementation to STRCHRNUL_DEFAULT when HAVE_STRCHRNUL_IFUNC is
set.
The buffer that backs up the assert message is now allocated through
_dl_mmap, which issues the syscall directly instead of calling __mmap
(setting errno on failure requires the thread pointer).
The abort call now issues __raise_direct instead of raise (the Hurd
port aliases __raise_direct to raise).
On i386, syscalls should not use the vDSO during program startup because
the thread pointer is not yet initialized. This requires __raise_direct,
_dl_writev, and _dl_mmap to be built with I386_USE_SYSENTER set to 0.
Creating a test case is challenging. For static-pie, the assert is only
called for ill-formed ELF files on elf_get_dynamic_info and by some targets
on ELF_DYNAMIC_RELOCATE (although not all targets use assert in their
dl-machine.h). Some targets also issue __libc_fatal on ARCH_SETUP_IREL,
but also only for ill-formatted ELF files.
The test employs a different strategy and overrides the __tunables_init
symbol, which is invoked immediately before self-relocation and TLS setup.
The test is built with -Wl,-z,muldefs to avoid linker issues.
I checked on aarch64, x86_64, i686, s390x (qemu), sparc (qemu),
mips64el (qemu), armhf, riscv, and powerpc.
Reviewed-by: Florian Weimer <fweimer@redhat.com>
And change _dl_writev to return a negative errno in case of failure.
This keeps the required semantics for not setting errno on failure
and allows removing the Linux libc_fatal.c implementation.
It also makes it simple to use the writev syscall during process
startup, especially on i386, where it requires disabling vDSO.
Checked on x86_64-linux-gnu and i686-linux-gnu.
Reviewed-by: Florian Weimer <fweimer@redhat.com>
.. and openat64.
Linux 7.2 (31cf44efa6df72a524b40adefb80539f3a4e13ba) allows openat, openat2
to take a NULL path with the new O_EMPTYPATH flag, so the nonnull attribute
is no longer sound. Drop it.
Bug: https://sourceware.org/PR34313
Reviewed-by: Paul Eggert <eggert@cs.ucla.edu>
Commit a2b0ff98a0 added __attribute_optimization_barrier__ and converted the
users of __attribute__ ((noinline, noclone)) to it, so that Clang, which does
not implement noclone, gets optnone instead of an unknown-attribute warning
that is an error under -Werror.
Twelve users were missed, all of them in code that a plain x86_64 build never
preprocesses, which is why they survived the sweep:
- libio/tst-stderr-compat.c is inside
#if TEST_COMPAT (libc, GLIBC_2_0, GLIBC_2_1), so it is compiled only on
ports that still have GLIBC_2.0 compat symbols -- i686 and alpha among
them, but not x86_64. Building it with Clang fails.
- The eleven sysdeps/x86_64/x32/tst-size_t-*.c tests are built only for the
x32 ABI.
No functional change for GCC, which still gets noinline and noclone.
Checked that both shapes -- the weak function in libio and the static function
in the x32 tests -- compile with GCC and with Clang after the change, and that
the pre-change shape is an error under Clang with -Werror.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
In a few places, we weren't exiting w/ 77 when skipping. Fix that by using
our standard macro for it.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Add memory clobber for writing to the POR_EL0 register since a change
to this register affects subsequent memory accesses.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Previously, add_system_dir added different paths depending on the ABI:
ilp32d: /lib32
ilp32s: /lib32/sf
Now, add_sysmtem_dir adds all of the following directories to standard
search path for both ilp32d ABI and ilp32s ABI:
/lib
/lib32
/lib32/sf
/lib64
/lib64/sf
This change fixes elf/tst-ptrguard-static-dlopen on ilp32s ABI.
The test is a statically linked executable with dlopen
tst-ptrguard-static-dlopen-mod.so. Without this patch, the test fails
because it looks for ld.so in /lib32/sf, but the file is actually
in /lib32.
LoongArch32 Reduced has no rotri.d/rotri.w instructions.
Use slli.w/srli.w/or to synthesize the rotation on LoongArch32
and LoongArch32 Reduced.
Reported-by: Haiyong Sun <sunhaiyong@loongson.cn>
The bug only exists in the non-FMA-contracted compilation of that
branch. On x86_64 it can be triggered with:
GLIBC_TUNABLES=glibc.cpu.hwcaps=-AVX2 math/test-double-tanh
Or by building without ifunc support.
Checked on aarch64-linux-gnu and x86_64-linux-gnu with
--disable-multi-arch.
Several tests rely on a madvise syscall to appear in strace output
(or not appear in case of 'disable' tests). This syscall may occur
in malloc. To avoid this from happening, we use malloc tunable to
disable hugetlb for these tests.
Suggested-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
A string tunable value usually references the GLIBC_TUNABLES (or alias)
environment string, which lives in the environment block the kernel places
on the initial stack. That memory is owned by the application, which may
overwrite it (e.g. setproctitle), so the reference is only safe while no
application code has run (a value coming from the system-wide tunables
cache is a copy instead, but the rule is applied uniformly).
This patch make the lifetime explicit and enforced without copying the value
or allocating any memory by adding __tunable_seal_strings, which drops every
string tunable reference once early startup is complete.
The seal is applied after the only string tunable consumer and before any
code outside of the startup sequence runs.
Checked on aarch64-linux-gnu and x86_64-linux-gnu. I also run the elf
tests on powerpc64le-linux-gnu, loongarch64-linux-gnuf64, and
s390x-linux-gnu.
Commit 24d188a2a1 left a stray #endif in
the powerpc32 soft-float __longjmp-common.S. Remove it, matching the
fpu variant.
Checked with a build for powerpc32-linux-gnu-soft.
On MIPS64 and AArch64 systems with 16-KiB pages, the PMD size is 32MB.
As we already have multiple platforms requiring such a large size and
it's the maximum THP size we support to align the load segments, it's
easier to raise the default instead of adding more special cases.
Link: https://sourceware.org/glibc/wiki/Testing/Tests/elf/tst-thp-1
Signed-off-by: Xi Ruoyao <xry111@xry111.site>
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Build the mask from the raw difference, as find_ne_all () now does.
index_first () and index_last () only need to know which byte holds the
first or the last set bit, and find_zero_all () marks only the bytes that
were zero, so each term of the or marks only its own bytes.
That drops one of the two carry chains from strcmp () and strncmp () on
targets using the generic string-fza.h, and one of the two uqsub8 on
armv6t2. As in find_ne_all (), only the generic implementation tests
HAVE_BITOPTS_WORKING.
powerpc keeps its existing form, where orc folds the complement of cmpb
into the or and the raw difference saves nothing. alpha and riscv do not
reach this code with the generic index_first ().
Reviewed-by: Wilco Dijkstra <Wilco.Dijkstra@arm.com>
find_zero_ne_all () searches for a zero byte in X1 or a byte that differs
between X1 and X2. A caller that knows X2 contains no NUL byte does not
need the zero test, since a NUL byte in X1 already differs from every
byte of X2.
Add find_ne_all (), which searches for inequality alone, to the generic
implementation and to each target that provides its own string-fza.h.
Dropping the zero test makes it cheaper than find_zero_ne_all () on every
target.
Return the difference unreduced wherever index_first () and index_last ()
come from the generic string-fzi.h, which uses stdc_trailing_zeros () and
stdc_leading_zeros () and so only needs to know which byte holds the first
or the last set bit. That covers armv6t2, powerpc and riscv with the
bitmap extensions, as well as the generic implementation. Only the
generic one tests HAVE_BITOPTS_WORKING, since its fallback ctzb () and
clzb () isolate a single bit and expect it at 0x80; the target masks are
already incompatible with that fallback and cannot use it either way.
riscv without the bitmap extensions takes its string-fza.h from the
generic implementation while defining its own index_first () and
index_last (), which tested bit 7 of each byte. Test the whole byte
instead, so that they accept the unreduced difference.
alpha keeps a reduced form, its find_t being a cmpbge mask of one bit per
byte throughout.
Reviewed-by: Wilco Dijkstra <Wilco.Dijkstra@arm.com>
Introduce ifuncs and resolvers for functions pertinent to the
malloc interface on the AArch64 target: malloc, calloc, free,
realloc, memalign, valloc, pvalloc, posix_memalign, aligned_alloc,
free_sized, free_aligned_sized, malloc_usable_size.
A target can define the USE_MULTIARCH_MALLOC macro. In this case
it must provide alternative aliases for the malloc functions that
point to the ifuncs.
This implementation respects the --disable-multi-arch configure
flag. If multi-arch support is disabled, the generic aliases
are used on aarch64.
This patch contains aarch64-specific resolvers. At this point they
return core implementations but in the future they can be changed
to support for features, e.g. to handle memory tagging.
Reviewed-by: Wilco Dijkstra <Wilco.Dijkstra@arm.com>
This commit moves declarations for various malloc functions from
the malloc.c file to a separate header that can be used to include
these declarations in other source files.
No functional change intended.
Reviewed-by: Wilco Dijkstra <Wilco.Dijkstra@arm.com>
After commit 78f1f0e39c ("Consolidate
the C pointer guard and align the assembly implementations"),
PTR_DEMANGLE3 on POWER no longer atomically updates the destination
register. The fortified longjmp relies on atomic update of the
stack pointer (r1) in sysdeps/powerpc/powerpc64/__longjmp-common.S
and parallel files:
#ifdef PTR_DEMANGLE
# ifdef CHECK_SP
PTR_DEMANGLE3 (r22, r22, r25)
# else
PTR_DEMANGLE3 (r1, r22, r25)
# endif
#endif
Fix this by using PTR_DEMANGLE instead of PTR_DEMANGLE3. Remove
PTR_MANGLE3 and PTR_DEMANGLE3 as unused.
An alternate fix would store the pointer guard cookie rotated,
but this would go against the unification in the commit that
introduced the regression.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Commits 6deadd4eb6 and ade9f30ce2 changed m68k fmod to call
__m81_u(fmod), instead of the mathimpl.h inline
__m81_u(__ieee754_fmod) (that wraps the m68k fmod instruction).
This leads to infinite recursion.
Tested-by: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
alpha was the only target that overrode sysdeps/generic/nscd-types.h,
defining nscd_ssize_t as int64_t rather than int32_t. The file dated back
to the initial import and had only ever received licence and copyright
updates.
nscd's response headers are a wire format, shared between the daemon and
its clients through a socket and through the persistent cache. A 64-bit
nscd_ssize_t gives four of them 8-byte alignment while their last member is
32 bits, so they acquire four bytes of tail padding: hst_response_header,
ai_response_header, serv_response_header and innetgroup_response_header.
For the hosts cache that is fatal. cache_addhst() asserts that the string
data follows the header with no gap, and on alpha it does not:
nscd: hstcache.c:269: cache_addhst: Assertion
`(char *) (&dataset->resp.error + 1) == dataset->strdata' failed.
The daemon aborts, and nscd/tst-nscd-basic fails with 58 errors. With the
override removed it passes.
The padding is also never initialised. cache_addhst() assigns the header
fields individually and nothing clears the record, yet the response is sent
with writeall (fd, &dataset->resp, ...) covering the full
sizeof (hst_response_header), so four uninitialised bytes reach every
client.
With alpha gone there is no target left overriding the type, so the sysdeps
indirection has no purpose. Delete both headers and define nscd_ssize_t
directly in nscd/nscd-client.h alongside the wire format it describes.
This changes nscd's protocol and persistent cache layout on alpha; the
daemon and its clients always come from the same build, so the exposure is
a daemon left running or a cache file left behind across the upgrade.
Signed-off-by: Magnus Lindholm <linmag7@gmail.com>
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
The test places the ancillary buffer so that it ends against a PROT_NONE
page, at cmsg - (CMSG_SPACE (tsize) + slack). CMSG_SPACE (sizeof (struct
timeval)) is a multiple of the alignment of struct cmsghdr, so the start of
the buffer inherits the alignment of the slack, and one of the slack sizes
the test uses is 4.
msg_control has to be suitably aligned for struct cmsghdr: recvmsg and the
CMSG_* macros both read cmsg_len from the start of the buffer, and it is a
size_t. On a target that does not fix up unaligned accesses in hardware,
reading it from a misaligned address traps into the kernel. On alpha each
one is reported:
ld-linux.so.2(48878): unaligned trap at 0000000120001e3c: ... 29 2
five per run, all from the loop over the control messages in
do_recvmsg_slack_ancillary. The test still passes, since the kernel
completes the access and returns.
Round the start of the buffer down to the alignment, and add the alignment
minus one to the requested allocation so the rounding cannot move the start
outside it. A slack that is not a multiple of the alignment then leaves the
buffer ending a few bytes short of the guard page rather than against it; the
overruns the guard page is there to catch are a whole timestamp rather than a
few bytes, so they are still caught.
Reviewed-by: Florian Weimer <fweimer@redhat.com>
Change strace-tst-thp.sh to check the command exit status so that
unsupported THP tests exit with status 77.
Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
alpha was the only target implementing gethostname with the syscall
rather than through uname. Its only behavioural difference was the errno
for a too-small buffer: it reported EOVERFLOW where the generic
implementation, gethostname(2) and misc/tst-gethostname expect
ENAMETOOLONG, so alpha failed that test:
tst-gethostname.c:96: numeric comparison failure
left: 112 (0x70, EOVERFLOW); from: errno
right: 63 (0x3f); from: ENAMETOOLONG
The file contains nothing but that function, so removing it lets the
sysdeps search fall through to sysdeps/posix/gethostname.c, which
produces the same buffer contents and the expected errno.
misc/tst-gethostname passes on alpha with it.
Suggested-by: Florian Weimer <fw@deneb.enyo.de>
Signed-off-by: Magnus Lindholm <linmag7@gmail.com>
Reviewed-by: Florian Weimer <fweimer@redhat.com>
The nptl/tst-cancel32 test fails intermittently on LoongArch
with SIGSEGV at __longjmp:
0x7ffff7de7f6c <__longjmp+28> rotri.d $sp, $t0, 0x11
0x7ffff7de7f70 <__longjmp+32> xor $sp, $sp, $t1
rotri.d and xor are expanded from PTR_DEMANGLE2.
If the thread is cancelled between the rotri.d and xor,
an incomplete sp register causes the SIGSEGV.
Change the destination register of rotri.d to avoid an incomplete sp.
Commit 89b53077d2 ("nptl: Fix Race conditions in pthread cancellation
[BZ#12683]") added a second copy of the __INTERNAL_SYSCALL_NCS{0-7}
and INTERNAL_SYSCALL_NCS_CALL macros, which had already been defined
earlier in the same file by commit 00baddbb93 ("linux: Add generic
syscall implementation"). Remove the second copy.
Signed-off-by: Ryota Saito <saito.ryota.23@shizuoka.ac.jp>
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
The librtld.map and librtld.os link recipes use $(gnulib), which on arm
contains libgcc-stubs.a through gnulib-arch. But the archive is only a
prerequisite of lib-noranlib so the rtld link can run before the archive
exists:
ld.bfd: cannot find .../elf/libgcc-stubs.a: No such file or directory
The race seems to predates the parallel subdirectory recursion, which
only made it observable.
Add the order-only dependency in sysdeps/arm/Makefile rather than in
elf/Makefile. Theprerequisite lists expand when the rule is parsed,
and gnulib-arch is only defined once Makerules includes the sysdeps
makefiles.
Verified with a build for arm-linux-gnueabihf.
Reviewed-by: Sam James <sam@gentoo.org>
The parallel subdirectory recursion (commit 7cac99621e) only orders
csu (and mach/hurd on Hurd) before the parallel fan-out plus the edges
the Depend files request. A header generated from gen-as-const-headers
is only ordered before the compilations of the subdirectory that
adds the .sym (through before-compile), so a header consumed by a
different subdirectory may not exist yet when its consumer is
compiled.
That is the case for <sigaltstack-offsets.h>: it is generated when
building misc, while its only consumer, ____longjmp_chk.S (x86_64 and
sh), is built in debug. The serial recursion always ran misc before
debug in the sorted order, hiding the missing dependency.
Move the generate the header to 'debug' instead.
The same class of problem exists on Hurd: jmp_buf-ssp.h that is used
by ____longjmp_chk.S in debug, and signal-defines.h that is sued
by debug and setjmp.
Deterministically reproduced with 'make debug/subdir_lib' from a clean
build tree (which orders only csu before debug), and verified with
builds for x86_64-linux-gnu, sh4-linux-gnu, i686-gnu, and x86_64-gnu.
Reviewed-by: Sam James <sam@gentoo.org>
_Float32x and _Float64 are both binary64 on Alpha, so this narrowing
divide is a plain divide and the hardware alone decides whether to signal
underflow.
IEEE 754 determines tininess after rounding from the result rounded as if
the exponent range were unbounded, while Alpha determines it from the
delivered result. The two differ for a quotient that is tiny but rounds
up to the smallest normal, as in DBL_MIN / (1 + 2^-52) under a rounding
mode that rounds away from zero: the binade below DBL_MIN has a finer
spacing than the subnormals, so the unbounded rounding stays below
DBL_MIN and the result is tiny, but the delivered result is DBL_MIN and
looks normal. Alpha signals no underflow for it.
Nothing in software can correct this. The hardware detects no underflow,
so no software completion trap is taken and the kernel emulation never
runs, and as the operation is not really narrowing there is no wider
intermediate for libm to examine.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
FE_NOMASK_ENV is the floating-point environment in which no exception is
masked, so it must enable every exception that FE_ALL_EXCEPT covers. On
Alpha that includes the GNU extension FE_DENORMAL, whose SWCR trap enable
bit is IEEE_TRAP_ENABLE_DNO (bit 6).
The constant only set bits 1 through 5 (INV, DZE, OVF, UNF and INE), so
after fesetenv (FE_NOMASK_ENV) a subsequent fegetexcept () returned
0x3e0000 rather than FE_ALL_EXCEPT (0x7e0000), and denormal exceptions
stayed masked. Set bit 6 as well.
Fixes math/test-fenv-return on alpha.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
The cancellable syscall wrappers end with a tail call to __syscall_cancel,
the wrapper frame is then elided, so when the syscall executes the wrapper
is no longer present on the stack. Tools that unwind from CFI alone, such
as valgrind, perf and sampling profilers, cannot observe it. On gdb, it
only recovers it from DWARF call site information, which reduced-debuginfo
libc builds usually omit.
The behaviour is target dependent: for a shared (PIC) the tail call is
emitted on aarch64, arc, loongarch and riscv. It is not emitted on i386,
x86_64, arm, s390x, sparc and alpha, where the seventh argument is passed
on the stack or fewer argument registers are available, nor on powerpc
and mips, where the TOC/GOT pointer must be restored after the call.
This is why the problem was originally reported as aarch64 specific while
x86_64 was unaffected.
Rather than only inhibiting the tail call [1] (which keeps the wrapper frame
but still leaves the __syscall_cancel and __internal_syscall_cancel
frames), move the cancellation logic back into the wrappers. In the
single-threaded case the syscall is now issued directly from the wrapper;
only the multi-threaded path still calls the out-of-line __syscall_cancel_arch.
This keeps the wrapper observable and removes the extra frames, mimicking
how cancellation was handled before 89b53077d2.
The result is a small libc.so .text increase (size, first column):
ABI master patched diff increase
aarch64 1635880 1647424 11544 0.71%
x86_64 1981081 1992257 11176 0.56%
powerpc64le 2364336 2376964 12628 0.53%
riscv64 1368386 1376704 8318 0.61%
loongarch64 1741385 1755601 14216 0.82%
The tst-backtrace5 was suppose to track this issue, but due wrong
loop variable check it does not take this in account. This patch also fixes
it.
Checked on aarch64-linux-gnu, x86_64-linux-gnu, i686-linux-gnu,
arm-linux-gnueabihf, and powerpc64le-linux-gnu.
[1] https://sourceware.org/pipermail/libc-alpha/2025-March/165395.html
The check for -mlong-double-128 IBM extended format support wrapped its
test code in AC_LANG_PROGRAM, which places the body inside main(). The
body defines a function, so it became a nested function definition -- a
GCC extension that Clang does not implement, making the test fail with
Clang.
Use AC_LANG_SOURCE so the function is defined at file scope, and
regenerate configure.
Reviewed-by: Sam James <sam@gentoo.org>