Compare commits

...
Author SHA1 Message Date
Florian Weimer e51a6bf18e malloc: Increase tcache fill count from 16 to 32
This avoids a regression in the omnetpp and xalancbmk benchmarks
of SPEC.  Apparently, these benchmarks are very sensitive to the
fill rate in malloc.

Suggested-by: Wilco Dijkstra <wilco.dijkstra@arm.com>
Tested-by: Wilco Dijkstra <wilco.dijkstra@arm.com>
2026-06-30 09:07:19 +02:00
Florian Weimer b50e24aea3 malloc: Only fill half of the tcache during batch allocation
This leaves room for subsequent frees.
2026-06-30 09:07:19 +02:00
Florian Weimer c0a1c6e06d malloc: Perform batched frees if tcache is full
Batched frees amortize the locking overhead once the tcache is full.
Previously, once the tcache slot was full, each free acquired the
arena lock.  With this change, neighboring tcache allocations in the
same arena re-use an arena lock that already exists.

Pass the tcache pointer to __libc_free_batch so that it is not
necessary to reload the tcache pointer after the _int_free_chunk
calls.
2026-06-30 09:07:19 +02:00
H.J. Lu ccd4cd5324 malloc: Don't call __get_thp_mode/__get_thp_size twice
Both ld.so and malloc track kernel THP mode and THP page size when THP
in ld.so is enabled by

GLIBC_TUNABLES=glibc.elf.thp=1

and THP in malloc is enabled by

GLIBC_TUNABLES=glibc.malloc.hugetlb=1

But DL_MAP_DEFAULT_THP_PAGESIZE and MALLOC_DEFAULT_THP_PAGESIZE may be
different when they are defined in <hugepages.h>.

If THP in ld.so is enabled, change malloc to use kernel THP mode from
ld.so, instead of calling __get_thp_mode, and use THP page size from
ld.so if it came from __get_thp_size.  This avoids calling __get_thp_mode
and __get_thp_size again, which are quite expensive:

1. Initialize mp_.thp_mode and GL(dl_thp_mode) to thp_mode_unknown.
2. Set mp_.thp_mode to GL(dl_thp_mode) if GL(dl_thp_mode) isn't
thp_mode_unknown.  Otherwise call __get_thp_mode to set mp_.thp_mode.
3. GL(dl_elf_thp_pagesize) is set to DL_MAP_DEFAULT_THP_PAGESIZE without
calling __get_thp_size and THP page size for malloc may be different from
THP page size for ld.so.  Set mp_.thp_pagesize to GL(dl_elf_thp_pagesize)
if DL_MAP_DEFAULT_THP_PAGESIZE is defined.  Otherwise call __get_thp_size
to set mp_.thp_pagesize.
4. THP page size in malloc is capped to MAX_THP_PAGESIZE.  If THP page
size is above MAX_THP_PAGESIZE, THP in malloc is disabled.

These result in when glibc.elf.thp is set to 1, malloc uses the actual
kernel THP mode instead of defaulting to madvise mode and madvise_thp
will stop issuing MADV_HUGEPAGE if kernel THP mode is always.

This fixes BZ #34083.

Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
2026-06-26 10:18:36 +08:00
Jiri Stransky 96773cc77b nis: Fix a memory leak in nis_creategroup when malloc fails
The zo_domain field was missing from the list of fields to be freed.

Reviewed-by: DJ Delorie <dj@redhat.com>
2026-06-25 11:21:14 -03:00
Xiang Gao 21103aef12 stdio-common: Fix scanf nan/inf pushback [BZ #34208]
When scanf parses special floating-point inputs like "nan", "inf", it
may read one extra character to check whether the input still matches
the expected word.

If that extra character does not match, the conversion should fail, but
the character has already been read from the stream.  Some error paths
did not push it back before reporting the conversion error, so later input
started at the wrong position.

Fix this by keeping EOF and width errors separate from character mismatch
errors.  Push the character back before calling conv_error for mismatch
errors.

Add narrow and wide scanf tests using the same test body.  The test cases
focus on the paths changed by this patch: mismatches while matching "nan",
"nan(...)", "inf", and "infinity".

Tested on x86_64 Fedora 42.

The following tests passed without regressions:
  make test t=stdio-common/tst-scanf-bz34208
  make test t=stdio-common/tst-wscanf-bz34208
  make subdirs="stdio-common libio" check

Signed-off-by: Xiang Gao <gaoxiang@kylinos.cn>
Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
2026-06-25 10:20:24 -03:00
Michael Ford ead80441e6 nss: Remove --enable-static-nss configure option
Since the NSS reorganization in glibc 2.33 the --enable-static-nss
option no longer changes the build: the files and dns services are built
into libc unconditionally, and there is no longer any mechanism to bake
the remaining services into libc.a.  After removing the dead
-DSTATIC_NSS define and the <gnu/lib-names.h> include (commits
82b710c190 and
2169401438), the option's only remaining
effect was to define DO_STATIC_NSS, which suppresses the static link
warnings on the NSS interface functions in libc.a.

With DO_STATIC_NSS gone, nss_interface_function emits the static link
warning unconditionally; static_nss and build-static-nss are removed
along with the configure option.

tst-nss-static, previously built only when build-static-nss was set, is
now added to tests-static unconditionally so the static NSS path retains
test coverage.

Signed-off-by: Michael Ford <fanquake@gmail.com>
Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
2026-06-25 10:20:24 -03:00
Adhemerval Zanella 657fe73fb1 manual: Document indirect functions (IFUNC)
Add a new section to the Dynamic Linker chapter describing the
STT_GNU_IFUNC mechanism: the resolver calling convention for each
supported architecture, when resolvers run, and the functionality
supported in resolvers (TLS access, stack protector, cross-object
references) along with the remaining restrictions, reflecting the
recent ordering fixes (BZ 20680, BZ 23240, BZ 28817, BZ 34164,
BZ 34170).  Also cross-reference it from the hardening section.

Reviewed-by: Yury Khrustalev <yury.khrustalev@arm.com>
2026-06-25 09:50:38 -03:00
Sachin Monga c9b5a4a593 ppc64le: Restore optimized memchr for power10 [BZ #34300]
Restore the POWER10 memchr implementation reverted in commit
a7877bb668 [BZ #33059], addressing the
actual cause:
The non-volatile vector register v20 used as the
zero vector (M_VREG_ZERO) is replaced with the volatile register v17.

Additionally, the assembler workaround used earlier for the
instructions lxvp and vextractbm is replaced with actual
instructions.
2026-06-25 00:21:08 -05:00
Shengwen Cheng a014af39fd riscv: Fix RV32 libthread_db THREAD_SELF register layout
The RISC-V libthread_db THREAD_SELF descriptor currently assumes 64-bit
general-register slots:

  REGISTER (64, 64, 4 * 8, ...)

That is correct for RV64, where tp/x4 is at byte offset 4 * 8 in the
general register set.  On RV32, general-register slots are 32-bit wide,
so tp/x4 is at byte offset 4 * 4.

Using the RV64 layout on RV32 makes libthread_db read the wrong thread
pointer value and prevents GDB from enabling pthread-aware thread
debugging.

Use a helper macro to pass the RISC-V register size into the
DB_THREAD_SELF definition.

Signed-off-by: Shengwen Cheng <shengwen1997.tw@gmail.com>
Reviewed-by: Peter Bergner <bergner@tenstorrent.com>
2026-06-24 17:54:00 +00:00
Adhemerval Zanella 16c74b94b9 elf: Fix clang-18 build of ifunc resolver tests
clang-18 errors on the static ifunc resolvers seen as unused.
2026-06-24 13:41:26 -03:00
H.J. Lu 8e5c299980 arm: Xfail 2 static THP tests
Since 2 static THP tests fail on arm:

FAIL: elf/tst-thp-1-no-s-code-static
FAIL: elf/tst-thp-1-static

due to limitations of arm32 kABI:

https://sourceware.org/bugzilla/show_bug.cgi?id=34096

xfail them.

Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
2026-06-24 06:18:21 +08:00
H.J. Lu d00085d6d0 thp: Limit THP code padding to 2 * THP page size
Since R_ARC_S25W_PCREL range is limited, 32MB THP code padding leads to
relocation overflow:

.../support/libsupport_nonshared.a(support_test_main.oS):
in function `support_test_main':
.../support/support_test_main.c:396:(.text+0x650): relocation truncated to fit: R_ARC_S25W_PCREL_PLT against symbol `atexit' defined in .text section in
../glibc/libc_nonshared.a(atexit.oS)
.../install/compilers/arc-linux-gnu/arc-glibc-linux-gnu/bin/ld: final link failed
collect2: error: ld returned 1 exit status

Limit THP code padding to 2 * THP page size to avoid R_ARC_S25W_PCREL
relocation overflow.

Tested natively for Linux/x86-64 and Linux/i686 as well as with
build-many-glibcs.py for arc-linux-gnu.

This fixes BZ #34311

Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
2026-06-24 06:17:20 +08:00
Mike FABIAN 98e1e467a8 Update documentation of iconv [BZ #30136]
Reviewed-by: Florian Weimer <fweimer@redhat.com>
2026-06-23 14:50:30 -03:00
Pierre Blanchard 2cce7ec3c8 AArch64: additional mathvec build system cleanups.
Rely on a single list of ISAs and precisions for
source, tests and benchmarks.

Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
2026-06-23 14:50:30 -03:00
Pierre Blanchard c5a4d7ccb2 AArch64: Update SHARED-FILES with files from Arm Optimized-Routines
Adds lists for math.h and string.h and track file revisions.

Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
2026-06-23 14:50:30 -03:00
Pierre Blanchard 5a60281b88 AArch64: Update mathvec directory structure.
The new structure matches that of Arm Optimized-routines,
to facilitate files traceability.

Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
2026-06-23 14:50:30 -03:00
John David Anglin f9deb2f50b hppa: Fix missing call to __feraiseexcept (BZ 34306)
The feupdateenv function is supposed to raise exceptions after
installing the environment represented by its envp argument.
This was accidentally missed on hppa.

The failure to raise exceptions was noticed by the failure of
the math/test-narrowing-trap test.

Signed-off-by: John David Anglin <dave.anglin@bell.net>
2026-06-23 13:41:10 -04:00
Sergey Kolosov b61b98e3d0 resolv: Add test for gethostbyname_r unaligned buffer [BZ #18287]
Add a test for the buffer overflow in gethostbyname_r (Bug 18287), which
occurs when alignment padding is not subtracted from the remaining buffer
length.

The test uses binary search to find the exact required buffer size
for a mocked DNS response. It then tests all pointer misalignments
(1-7 bytes) using a custom 0xAA guard region. This guarantees
deterministic detection of out-of-bounds writes, avoiding false
negatives caused by malloc chunk rounding.

Reviewed-by: Florian Weimer <fweimer@redhat.com>
2026-06-23 08:40:41 +02:00
Justus Winter 91eb5057b9 Define _PATH_MOUNTED as "/etc/mtab"
Change the definition of _PATH_MOUNTED to "/etc/mtab". This is the
value used on Linux, and BSD also uses /etc/mtab.

The change is motivated by the fact that on Debian /etc/mtab is a
symbolic link to /proc/mounts. This patch adjusts the macro for
non-linux systems such as Hurd. Changing this using
sysdeps/mach/hurd/paths.h causes build problems because
/usr/include/hurd/paths.h is shadowed by this file. This change is
proposed in the hope that aligning the non-linux targets with the
glibc for Linux is perceived as a good thing while fixing this problem
on Debian/Hurd along the way.
2026-06-22 22:25:38 +02:00
Adhemerval Zanella bc76aa1658 Add advisory text for CVE-2026-6791
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Reviewed-by: Siddhesh Poyarekar <siddhesh@gotplt.org>
2026-06-22 14:16:35 -03:00
Adhemerval Zanella 07c24f3539 posix: Fix stack overflow in wordexp tilde expansion (BZ 34091, CVE-2026-6791)
The parse_tilde function previously used strndupa to allocate memory
for the parsed username on the stack, and since the input is
user-defined, this can lead to a stack overflow.

This patch fixes the issue by replacing strndupa with scratch_buffer,
by reusing the buffer used in the __getpwnam_r call.

The new “tst-wordexp-tilde.c” test is a test-container to avoid using
system-defined NSS modules.

Checked on x86_64-linux-gnu and i686-linux-gnu.
2026-06-22 11:11:24 -03:00
60f7247847 riscv: Add RVV memmove for both multiarch and non-multiarch builds
This patch adds an RVV-optimized implementation of memmove for RISC-V and
enables it for both multiarch (IFUNC) and non-multiarch builds.

The implementation integrates Hau Hsu's 2023 RVV work under a unified
ifunc-based framework. A vectorized version (__memmove_vector) is added
alongside the generic fallback (__memmove_generic). The runtime resolver
selects the RVV variant when RISCV_HWPROBE_KEY_IMA_EXT_0 reports vector
support (RVV).

Currently, the resolver still selects the RVV variant even when the RVV
extension is disabled via prctl(). As a consequence, any process that
has RVV disabled via prctl() will receive SIGILL when calling memmove().

Co-authored-by: Hau Hsu <hau.hsu@sifive.com>
Co-authored-by: Jerry Shih <jerry.shih@sifive.com>
Signed-off-by: Yao Zihong <zihong.plct@isrc.iscas.ac.cn>
Reviewed-by: Peter Bergner <bergner@tenstorrent.com>
2026-06-20 22:56:09 -05:00
H.J. Lu 53d909a283 elf: Support THP segment load with madvise enabled THP
The current THP segment load approach works only when THP is enabled
with always in the kernel.  If THP is enabled with madvise in the
kernel, to enable THP segment load in an application, madvise should
be called with MADV_HUGEPAGE on all THP eligible PT_LOAD segments:

1. Define DL_MAP_DEFAULT_THP_PAGESIZE in hugepages.h and default it to 0.
If DL_MAP_DEFAULT_THP_PAGESIZE is defined, assume kernel THP madvise mode.
If kernel THP mode is always or never, there is an extra madvise call
which has no impact.  DL_MAP_DEFAULT_THP_PAGESIZE is defined for x86-64
and 64-bit loongarch.
2. Update _dl_map_segment_align to support madvise THP mode.  This fixes
BZ #34079.
3. Call _dl_executable_postprocess in rtld_setup_main_map for dynamic
executables and in LIBC_START_MAIN for static executables, which calls
madvise with MADV_HUGEPAGE on all THP eligible PT_LOAD segments in
executable.  This fixes BZ #34080 for both dynamic and static executables.
4. Call _dl_postprocess_loadcmd_extra in _dl_postprocess_loadcmd, which
calls madvise with MADV_HUGEPAGE on all THP eligible PT_LOAD segments
when loading an object after they have been mapped in.  This fixes
BZ #34080 for shared objects.
5. Set the maximum page alignment on THP tests to THP page size as the
default maximum page alignment may be smaller than THP page size.
6. Add tests to verify that large executable PT_LOAD segments in
executables are mapped at addresses aligned to THP page size when the
kernel is configured to use THP in "always" mode or "madvise" mode by
inspecting /proc/self/maps to check that the mapping address is aligned
to THP page size reported by the kernel.  Also verify that madvise is
called with MADV_HUGEPAGE when the glibc tunable glibc.elf.thp=1 is used
and madvise isn't called with MADV_HUGEPAGE when the glibc tunable
glibc.elf.thp=0 is used.

Skip these tests if THP page size cannot be determined or if THP is not
enabled in "always" mode nor "madvise" mode.

Quote WANG Rui <wangrui@loongson.cn>:

From benchmarking a clang build of the Linux kernel on x86_64 with
your patch in THP madvise mode, I observed that iTLB misses were
reduced, similar to what we see in THP always mode.

NB: Some THP tests fail on arm due to limitations of arm32 kABI:

https://sourceware.org/bugzilla/show_bug.cgi?id=34096

Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
2026-06-20 05:35:24 +08:00
Carlos O'Donell 9310db5a08 advisories: Update GLIBC-SA-2026-0012 metadata
Update vulnerable versions in descriptive text.
2026-06-19 16:30:41 -04:00
Adhemerval Zanella da11a7d92c Remove unused THREAD_SET_POINTER_GUARD and THREAD_COPY_POINTER_GUARD
Commit a5ec880f80 ("Consolidate pointer
guard to use a relro variable instead of the TCB") moved the pointer
guard to the module-local relro variable __pointer_chk_guard_local and
dropped the THREAD_{SET,COPY}_POINTER_GUARD macros, which are no longer
defined by any target.

Checked on a build for all afftected targets.
2026-06-19 14:23:05 -03:00
Florian Weimer 4ba0b79b95 resolv: Add test case tst-ns_sprintrr (bug 34033, bug 34069)
This test case covers both input buffer overreads and output buffer
overflows.  It should systematically cover these issues.

I used code auto-generation for updating the test expectations for
truncated RDATA in TXT, ISDN records, after writing the rest
of the test by hand.

Assisted-by: LLM
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
2026-06-19 18:22:20 +02:00
Florian Weimer a7b60d23bb resolv: Fix buffer overreads in ns_sprintrrf (CVE-2026-6238)
Check that the RDATA payload does not require more than RDATALEN
bytes while processing it.  The fixes cover A6, LOC records.
(CERT, TKEY, TSIG were fixed before, by switching to the generic
formatter.)

The vulnerable LOC record handling was first introduced before
glibc 2.0, in commit ee188d555b.

CERT, TSIG, TKEY handling came with commit
b43b13ac25, released with glibc 2.2.

A6 record handling was introduced in commit
9163381643 ("* resolv/ns_print.c
(ns_sprintrrf): Handle ns_t_a6 and ns_t_opt."), which went into glibc
2.7.

This fixes bug 34069.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
2026-06-19 18:22:20 +02:00
Florian Weimer ca44a6609c resolv: More types as unknown in ns_sprintrrf (CVE-2026-5435)
Specifically, CERT, TKEY, TSIG, OPT.  This removes the buggy
implementations of TSIG, fixing bug 34033, and partially
fixing bug 34069.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
2026-06-19 18:22:20 +02:00
Florian Weimer cd0db208d5 resolv: Check for inet_ntop failure in ns_sprintrrf
This makes the output more consistent (either failure or complete
output) and helps with systematic testing with varying buffer
sizes.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
2026-06-19 18:22:20 +02:00
Florian Weimer d58415eb17 resolv: Improve formatting of unknown records in ns_sprintrrf
Do not add the "unknown RR type" comment.  After adding the TYPE
prefix, the number is largely redundant.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
2026-06-19 18:22:20 +02:00
Florian Weimer f69b7f95e3 resolv: Fix ns_sprintrrf formatting of class, type values (bug 34289)
The p_class and p_type results could overwrite each other if both
were unknown.  Format unknown values with CLASS and TYPE prefixes,
as in RFC 3597.  Handle A6 separately because it cannot be added
to __p_type_syms for ABI reasons.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
2026-06-19 18:22:20 +02:00
Florian Weimer 360f352c9a resolv: Declare __p_class_syms, __p_type_syms for internal use
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
2026-06-19 18:22:20 +02:00
Florian Weimer 1607beb5f4 Update GLIBC-SA-2026-0012 to mention A6 records
It turns out there is a missing inner length check in it, too.

Also fix the vulnerable commit.  It predates the glibc 2.0 release
because the old stream-based formatting code in resolv/res_debug.c had
the same bug in its LOC handling.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
2026-06-19 18:22:20 +02:00
Wilco Dijkstra cdbefe2f94 string: Improve memchr random test
Add matches before the start to ensure the memchr test checks they do not
result in false matches or missed matches.

Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
2026-06-18 19:44:31 +00:00
Dylan Fleming 4e105d9855 AArch64: Vectorise SVE fp64 sin/cos special case
Implemented double precision vector fallback for SVE sin/cos.

Includes rewrite of sin to use trig instructions.

Reviewed-by: Wilco Dijkstra  <Wilco.Dijkstra@arm.com>
2026-06-18 14:56:22 +00:00
Dylan Fleming 708185c829 AArch64: Vectorise AdvSIMD fp64 sin/cos special case
Implemented double precision vector fallback for AdvSIMD sin/cos.

Reviewed-by: Wilco Dijkstra  <Wilco.Dijkstra@arm.com>
2026-06-18 14:56:22 +00:00
Dylan Fleming e585d88982 AArch64: Vectorise SVE fp32 sin/cos special case
Implemented single precision vector fallback for SVE sinf/cosf.

Includes a rewrite of SVE sinf to use the trig instructions.

Reviewed-by: Wilco Dijkstra  <Wilco.Dijkstra@arm.com>
2026-06-18 14:56:22 +00:00
Dylan Fleming faa9ea921a AArch64: Vectorise AdvSIMD fp32 sin/cos special case
Implemented single precision vector fallback for AdvSIMD sinf/cosf.

Includes cleanup of the fast pass to remove old styling and conventions.

Reviewed-by: Wilco Dijkstra  <Wilco.Dijkstra@arm.com>
2026-06-18 14:56:22 +00:00
Yury Khrustalev a3b1faddaf news: Describe AArch64-specific changes for 2.44
Reviewed-by: Wilco Dijkstra <Wilco.Dijkstra@arm.com>
2026-06-18 14:46:42 +01:00
Adhemerval Zanella 242a1f4b0f elf: Do not scrub AT_RANDOM to a constant when reseeding fails (BZ 34197)
_dl_reseed_random zeroed the AT_RANDOM bytes before refilling them with
getrandom (GRND_NONBLOCK).  That call is best-effort and can write nothing
(e.g. before the kernel entropy pool is initialized early at boot), leaving
the 16 bytes as a constant zero.

Since the value is exposed through getauxval (AT_RANDOM), this traded a
potential guard leak for a guaranteed predictable value.

Drop the memset and overwrite the bytes in place instead.  The generic
version now just drops the pointer (it is not used anywhere).

Checked on x86_64-linux-gnu and i686-linux-gnu.

Reviewed-by: Florian Weimer <fweimer@redhat.com>
2026-06-17 09:52:32 -03:00
Wilco Dijkstra 368438d8b6 manual: Update memchr description [BZ #19406]
Update memchr description to indicate it cannot overread and the size
may be larger than the object passed.  This is required since C11.

Suggested-by: Paul Eggert <eggert@cs.ucla.edu>
Reviewed-by: Paul Eggert <eggert@cs.ucla.edu>
2026-06-17 11:48:50 +00:00
Samuel Thibault 89b4605be8 hurd: Add ETH_TLEN and ETH_FCS_LEN 2026-06-17 01:26:54 +02:00
Samuel Thibault 145b53b22a hurd: Fix ETH_P_PUP
According to IANA, PUP is 0200
2026-06-17 01:26:45 +02:00
Samuel Thibault 8d184c42cc Factorize if_arp.h
They were essentially identical between linux and hurd, and are
OS-independent.
2026-06-17 01:17:21 +02:00
Adhemerval Zanella 337e18d661 elf: Scrub and reseed the AT_RANDOM bytes after deriving the guards (BZ 34197)
Once the pointer and stack guards have been derived from AT_RANDOM, scrub
the bytes and refill them with new random data unrelated to the guards.
On Linux, it uses getrandom syscall (as for tcache_key_initialize), and
fallback to zero the memory if the syscall is not avaiable.

This keeps AT_RANDOM useful to applications while ensuring those bytes no
longer reveal the guards.

The work is done by _dl_reseed_random, called once the guards are in place
and before any ELF constructor can observe AT_RANDOM: in security_init for
the dynamic loader and in __libc_start_main for statically linked programs.

Checked on aarch64-linux-gnu, x86_64-linux-gnu, and i686-linux-gnu.

Reviewed-by: DJ Delorie <dj@redhat.com>
2026-06-16 14:53:48 -03:00
Adhemerval Zanella 604fe0b87b Consolidate dl-osinfo.h into the generic implementation
The generic and the Linux _dl_setup_stack_chk_guard and
_dl_setup_pointer_guard are identical when the kernel provides the
AT_RANDOM auxiliary vector, which is always the case on the supported
Linux kernels; the generic version only adds a fallback for a missing
AT_RANDOM.  Remove the Linux-specific dl-osinfo.h and use the generic
one for all targets.

The removed header pulled in <dl-sysdep.h>, which is what transitively
declared __libc_enable_secure for dl-parse_auxv.h; include <unistd.h>
there directly so it no longer relies on that.  Include <string.h> in
the generic header so it is self-contained.

Reviewed-by: DJ Delorie <dj@redhat.com>
2026-06-16 14:53:48 -03:00
Adhemerval Zanella 78f1f0e39c Consolidate the C pointer guard and align the assembly implementations
The per-architecture pointer_guard.h files all implemented some variant
of C PTR_MANGLE/PTR_DEMANGLE: the i386 and x86_64 versions did an
exclusive-or by the guard followed by a rotate left by
2 * sizeof (uintptr_t) + 1 bits (9 on 32-bit, 17 on 64-bit), while the
other targets did the exclusive-or only.  The assembly macros likewise
rotated on i386 and x86_64 but not on the other targets.

Consolidate everything to use XOR + rotate uniformly: collapse the
per-architecture C headers into a single generic implementation, and
add the matching rotate to the assembly implementations that lacked it.

Targets with an assembly rotate instruction (aarch64, arm, loongarch,
powerpc, s390, csky) just add it.  Those without one (alpha, sparc, sh)
synthesize the rotation: alpha and sparc with a shift/shift/or sequence,
which needs an extra scratch register added to the PTR_MANGLE/PTR_DEMANGLE
macros, sh with single-bit rotates, which needs no scratch.  The s390
__longjmp and ____longjmp_chk demangle the return address and stack
pointer in C, so update those too.

Checked with setjmp, ptrguard and longjmp_chk tests for all supported
ABIs that can run under qemu (all but csky), and with builds for all
supported ABIs.

Reviewed-by: DJ Delorie <dj@redhat.com>
2026-06-16 14:53:47 -03:00
Adhemerval Zanella c626d764d7 Remove the jmp_buf stack pointer demangle on ABIs that do not mangle it
arc, m68k, microblaze, mips, and riscv store the raw stack pointer in
setjmp, while their jmpbuf-unwind.h applies PTR_DEMANGLE to it in
_jmpbuf_sp.  This is currently harmless because these ABIs use the
generic pointer_guard.h, where the C PTR_DEMANGLE is a no-op.

No functional change.

Reviewed-by: DJ Delorie <dj@redhat.com>
2026-06-16 14:53:29 -03:00
Adhemerval Zanella afc90416e9 Split pointer_guard.h into C and assembly headers
Move the assembly PTR_MANGLE/PTR_DEMANGLE definitions out of each
pointer_guard.h into a new sibling pointer_guard-asm.h, guarded by
__ASSEMBLER__.  pointer_guard.h now includes pointer_guard-asm.h and
keeps only the C definitions.

No functional change: the .S and .c files still include pointer_guard.h
and get the same macros, and <pointer_guard-asm.h> resolves per-arch
through the usual sysdeps include path.

Checked with a build for all affected ABIs.

Reviewed-by: DJ Delorie <dj@redhat.com>
2026-06-16 14:53:29 -03:00
Adhemerval Zanella d50ae543a4 Enable the pointer guard in the dynamic loader
i386, powerpc, s390, sh and sparc fell back to the generic no-op
pointer_guard.h in ld.so, so the loader's own setjmp/longjmp and mangled
function pointers were left unprotected (the other targets already
mangle in rtld).  ld.so is position-independent and sets up
__pointer_chk_guard_local early in dl_main, so the loader can reach it
the same way a statically linked program does:

  - powerpc, s390, sh, sparc: select __pointer_chk_guard_local for
    IS_IN (rtld) and reuse the existing PIC guard load.
  - i386: load it via @GOTOFF off a GOT pointer set up with LOAD_PIC_REG
    in the caller-provided scratch register
    (ld.so does not keep the GOT in %ebx at the setjmp/longjmp entry).
  - s390: drop the IS_IN (rtld) "#undef PTR_DEMANGLE" in __longjmp.c so
    the loader's longjmp demangles to match its setjmp.

Checked on x86_64-linux-gnu, aarch64-linux-gnu, i686-linux-gnu, and
armv7a-linux-gnueabihf.  I also run elf and setjmp checks on qemu
loongarch64, powerpc64, powerpc64le, and s390x systems.

Reviewed-by: DJ Delorie <dj@redhat.com>
2026-06-16 14:53:28 -03:00
Adhemerval Zanella a5ec880f80 Consolidate pointer guard to use a relro variable instead of the TCB
For the targets that still read the pointer guard from the thread
descriptor (i386, x86_64, powerpc, s390, sparc, and sh), mangle and
demangle pointers using the module-local __pointer_chk_guard_local (in
ld.so and static binaries) or the global __pointer_chk_guard provided by
the dynamic loader (in shared objects), matching the scheme already used
by aarch64, alpha, arm, csky and loongarch.

On i386 the guard is no longer reachable as a single %gs-relative memory
operand, so the assembly PTR_MANGLE/PTR_DEMANGLE PIC variants need a
register to hold the GOT pointer and the guard address.

This removes the dependency on the TCB pointer_guard slot: drop
THREAD_{GET,SET,COPY}_POINTER_GUARD and the POINTER_GUARD tcb-offset,
and point the POINTER_CHK_GUARD test macro at the relro variable.  The
tcbhead_t slot is kept (renamed to an unused reserved field, except on
s390 which reused the stack guard) to preserve the ABI.  s390 gains a
distinct pointer guard rather than aliasing the stack guard.

Checked on x86_64-linux-gnu, aarch64-linux-gnu, i686-linux-gnu, and
armv7a-linux-gnueabihf.  I also run elf and setjmp checks on qemu
loongarch64, powerpc64, powerpc64le, and s390x systems.

Reviewed-by: DJ Delorie <dj@redhat.com>
2026-06-16 11:35:06 -03:00
Adhemerval Zanella 3785d4c0d0 elf: Propagate the pointer guard to ld.so loaded via static dlopen (BZ 34196)
The static-dlopen does not initialize the pointer guard for ABIs that
define THREAD_SET_POINTER_GUARD.  Besides not properly guard the
pointer if a libc.so symbol is called, this can lead to setjmp
failures (a jmp_buf set up by the loaded libc.so.6 cannot be restored
by the static program's __longjmp, and vice versa).

Seed the just-mapped loader's __pointer_chk_guard from the program's
__pointer_chk_guard_local in __rtld_static_init, next to the other
runtime values copied there.

Checked on aarch64-linux-gnu, x86_64-linux-gnu, and i686-linux-gnu.

Reviewed-by: DJ Delorie <dj@redhat.com>
2026-06-16 08:29:57 -03:00
Adhemerval Zanella a767fbcff0 math: Sync acosh with CORE-MATH 887cab6f
It syncs with CORE-MATH commit 887cab6f.  The new tests are from
the CORE-MATH acosh worst-cases inputs that trigger the FE_TOWARDZERO
issue with the previous implementation, along with the hard-to-round
cases from CORE-MATH commits 72febed6 and ce9e99f6.

Checked on x86_64-linux-gnu, x86_64-linux-gnu with --disable-multi-arch
(so soft FMA implementation is used), i686-linux-gnu (which uses its
own acosh implementation), aarch64-linux-gnu, and
armv7a-linux-gnueabihf.

Reviewed-by: Paul Zimmermann <Paul.Zimmermann@inria.fr>
2026-06-15 17:41:15 +00:00
Michael Ford 82b710c190 inet: Remove unused STATIC_NSS define
The --enable-static-nss configuration adds -DSTATIC_NSS to CFLAGS for
the inet subdirectory, but no source file has referenced the STATIC_NSS
macro for quite some time. So remove the dead define.

Signed-off-by: Michael Ford <fanquake@gmail.com>
Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
2026-06-15 15:00:03 +00:00
Michael Ford 2169401438 nss: Remove <gnu/lib-names.h> include from nsswitch.c
nsswitch.c no longer references any of the *_SO macros provided by
<gnu/lib-names.h>. The only consumer, __nss_shlib_revision, moved to
nss_module.c as part of the NSS reorganization in glibc 2.33 (and
nss_module.c includes the header unconditionally), but the guarded
include was left behind.

Signed-off-by: Michael Ford <fanquake@gmail.com>
Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
2026-06-15 14:59:41 +00:00
Adhemerval Zanella 1111fbdd3e arm: Save/restore VFP registers in PLT trampolines (BZ 34144, BZ 15792)
_dl_runtime_resolve and _dl_runtime_profile only preserved the integer
argument registers (r0-r3) across the inner call to _dl_fixup /
_dl_profile_fixup.  Two related ABI requirements demand more:

  * Under AAPCS-VFP, d0-d7 hold the caller's double arguments to the
    function being resolved.  Recent GCC emits VFP instructions inside
    the fixup routines, clobbering them, so the resolved function sees
    corrupted arguments (BZ 34144).

  * Per RTABI32, the __aeabi_mem* helpers (and similar runtime helpers
    reachable through the dynamic linker) must only corrupt integer
    core registers.  IFUNC resolvers, audit modules, and interposed
    malloc invoked during symbol resolution may also use VFP, even on
    softfp ABI builds (BZ 15792).

Save all call-clobbered VFP state -- d0-d15 unconditionally, d16-d31
when HWCAP_ARM_VFPD32 is set, and fpscr -- around the inner fixup
call.  Whether VFP is usable is a property of the hardware, not of
the ABI glibc was built with, so the decision is gated on AT_HWCAP at
runtime in both hardfp and softfp builds; hardfp builds will always
find HWCAP_ARM_VFP set, while softfp builds running on a non-VFP CPU
correctly skip the save.

For _dl_runtime_profile the save area is slipped in just before the
bl to _dl_profile_fixup; the outgoing framesizep argument is
recomputed to account for the extra frame, and both the fast path
(no audit framesize) and the slow path (audit wraps with
pltenter/pltexit) traverse the restore before splitting.

Checked on arm-linux-gnueabihf.

Tested-by: Aurelien Jarno <aurelien@aurel32.net>
Reviewed-by: Wilco Dijkstra  <Wilco.Dijkstra@arm.com>
2026-06-15 14:59:10 +00:00
Adhemerval Zanella 6adb7400fd aarch64: Fix static PIE CPU feature detection (BZ 34205)
ARCH_INIT_CPU_FEATURES is called from __libc_start_main before
_dl_relocate_static_pie, so any code it runs must not rely on
relocations being applied yet.  Two issues break this under static PIE:

  1. The cpu_list table held 'const char *name' members, whose
     addresses are not link-time constants under PIE and thus require
     base-relative relocations that are not yet in place.  Replace the
     array of structs with a flat NUL-separated name string and a
     parallel midr array, removing the pointer relocations.

  2. tunable_strcmp pulls in memcmp, which is an IFUNC and is likewise
     unresolved at this point.  Redirect memcmp to __memcmp_generic in
     the aarch64 dl-symbol-redir-ifunc.h and include it from
     csu/libc-start.c.

Checked on aarch64-linux-gnu.

Reviewed-by: Wilco Dijkstra  <Wilco.Dijkstra@arm.com>
2026-06-15 14:58:11 +00:00
Sana Kazi 1cba6073e5 nptl: open threads comm with O_WRONLY|O_CLOEXEC
pthread_setname_np opens the thread's comm file using O_RDWR, but the
function only ever writes to it.  This causes two distinct problems:

1. Missing O_CLOEXEC: the file descriptor is not marked close-on-exec,
   so it remains open across fork+exec.  A child process that audits
   its inherited file-descriptor set will encounter an unexpected /proc
   fd it did not open and may treat this as a security violation and
   abort.

2. Unnecessary O_RDWR: requesting read+write access when only write
   access is needed can cause open() to fail under security policies
   that permit writing to /proc/<tid>/comm but deny reading it.

Fix both issues by replacing O_RDWR with O_WRONLY|O_CLOEXEC

Similarly, updated pthread_getname_np to use O_CLOEXEC.

Bug-Id: 34192[https://sourceware.org/bugzilla/show_bug.cgi?id=34192]

Signed-off-by: Sana Kazi <Sana.Kazi@bmwtechworks.in>
Reviewed-by: Florian Weimer <fweimer@redhat.com>
2026-06-15 16:37:59 +02:00
Yury Khrustalev 9ed3576e61 malloc: aarch64: Add ifuncs for malloc functions
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 moment they
return core implementations but in the future they can be changed
to support for features, e.g. to handle memory tagging.
2026-06-15 13:40:22 +01:00
Fabian Rast df83fa8813 rtld: cache cpuid results on the stack for intel
dl_init_cacheinfo retrieves various information about cache
sizes, using the cpuid instruction on x86.
Previously, the same cpuid leaves were queried multiple times.
This behavior caused intel_check_word to prominently show up in
profiles of dynamic loader startup on the Intel(R) Xeon(R) Gold 6430.
The big performance impact could not be reproduced on other Intel cpus.

This patch reduces the number of cpuid queries on startup
by caching their results on the stack for reuse when searching for a
different cache size value.
This approach does not change the overall design of
the cache enumeration code (repeated calls to handle_* functions).
The values are cached on the stack instead of globally (e.g.
in the cpu_features global) because they are never needed after
early initialization.

The cache is only active for Intel cpus, because it has not yet
been shown through benchmarks that it meaningfully improves performance
for other processors.

Signed-off-by: Fabian Rast <fabian.rast@tum.de>
Reviewed-by: Sunil K Pandey <skpgkp2@gmail.com>
2026-06-11 10:10:38 -07:00
Joseph Myers 8ae37adb21 Fix -Wconstant-logical-operand error for Hurd
Building for Hurd with GCC mainline produces an error in pt-block.c
(here MSG_OPTIONS is a macro that may be defined before pt-block.c is
included by another source file):

In file included from ../sysdeps/mach/htl/pt-block-intr.c:6:
../sysdeps/mach/htl/pt-block.c: In function '__pthread_block_intr':
../sysdeps/mach/htl/pt-block.c:49:42: error: use of logical '&&' with constant operand '1024' [-Werror=constant-logical-operand]
   49 |   if ((MSG_OPTIONS & MACH_RCV_INTERRUPT) && err == MACH_RCV_INTERRUPTED)
      |                                          ^~
../sysdeps/mach/htl/pt-block.c:49:42: note: use '&' for bitwise operation
   49 |   if ((MSG_OPTIONS & MACH_RCV_INTERRUPT) && err == MACH_RCV_INTERRUPTED)
      |                                          ^~
      |                                          &

Fix this, and a similar error in pt-timedblock.c, with an explicit != 0.

Tested with build-many-glibcs.py (compilers and glibcs builds) for
i686-gnu and x86_64-gnu.
2026-06-10 18:49:53 +00:00
Joseph Myers d8fa402f5e Fix -Werror=constant-logical-operand errors in soft-fp
Building for sparc64-linux-gnu with GCC mainline produces a series of
-Werror=constant-logical-operand errors in soft-fp code, relating to
calls to _FP_TO_INT where rsigned is -1 not 0 or 1.  Use explicit != 0
in the soft-fp code to avoid these errors.

Tested with build-many-glibcs.py (compilers and glibcs builds) for
sparc64-linux-gnu with GCC mainline.
2026-06-10 16:33:27 +00:00
Joseph Myers 690472e2a5 Fix -Wconstant-logical-operand error in tst-printf-format-skeleton.c
Building the glibc testsuite with GCC mainline fails with:

In file included from tst-printf-format-skeleton-double.c:33,
                 from tst-printf-format-p-double.c:20:
tst-printf-format-skeleton.c: In function 'do_test':
tst-printf-format-skeleton.c:308:12: error: use of logical '&&' with constant operand '53' [-Werror=constant-logical-operand]
  308 |   if (PREC && printf ("prec:%i\n", PREC) < 0)
      |            ^~
tst-printf-format-skeleton.c:308:12: note: use '&' for bitwise operation
  308 |   if (PREC && printf ("prec:%i\n", PREC) < 0)
      |            ^~
      |            &
cc1: all warnings being treated as errors

Fix this using an explicit "!= 0".  Tested with build-many-glibcs.py
for aarch64-linux-gnu.
2026-06-10 14:01:34 +00:00
Zihong Yao 9cf4dd03bd riscv: Keep __memcmpeq alias with RVV memcmp
Commit 2efc702628 replaces the generic RISC-V memcmp, which also exports
__memcmpeq.

A dedicated RISC-V __memcmpeq implementation is expected in a later patch,
which is still under review. Keep the alias here so this patch does not
temporarily drop the existing __memcmpeq ABI.

Tested on a Muse-Pi board with GCC 15.2.0 using `--with-arch=rv64g_zca_zcd --with-abi=lp64d`
and `CFLAGS="-march=rv64g_zca_zcd -mabi=lp64d -O2"`. Full make check was
run for both multiarch and non-multiarch builds.
This also fixes the string/inl-tester link failure caused by the missing
__memcmpeq symbol.

In both runs, the only FAILs are the unchanged cospi/sinpi/tanpi math test
failures.

Signed-off-by: Zihong Yao <zihong.plct@isrc.iscas.ac.cn>
Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
2026-06-09 09:06:07 -03:00
Brian Jorgensen 6f072238e9 fcntl-linux.h : Fix typo in comments. (bug 17119)
This commit fixes incorrect comments in set / get macros.

Signed-off-by: Brian Jorgensen <brjorgen98@gmail.com>
Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
2026-06-09 09:05:59 -03:00
Florian Weimer e9325bd7d0 iconv: Suppress intermediate errors with //TRANSLIT (bug 34236)
When tentatively converting characters on behalf of
__gconv_transliterate, do not create a persistent error.  Just
produce a local error, and rely on __gconv_transliterate to
produce the error if all transliteration options are exhausted.

This fixes transliteration of “½” to ASCII, which cannot use the
“ 1⁄2 ” alternative.  Eventually, the “ 1/2 ” alternative is chosen,
but the error sticks.  Therefore, iconv exited with status 1 before
this change.

Adjust iconv/tst-iconv_prog.sh to test both C and en_US.UTF-8 locales.
This requires changing the way the ICONV template is defined, so that
run_program_env is evaluated multiple times.

Fixes commit 9a4b0eaf72 ("iconv: do not
report error exit with transliteration [BZ #32448]"),
commit 6cbf845fcd ("iconv: Preserve
iconv -c error exit on invalid inputs (bug 32046)"), and bug 34236.

Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
2026-06-09 07:28:02 +02:00
Josef Johansson 88099e289d nscd: Typo in comment
Fixes: https://sourceware.org/bugzilla/show_bug.cgi?id=34240

Signed-off-by: Josef Johansson <josef@oderland.se>
Reviewed-by: Florian Weimer <fweimer@redhat.com>
2026-06-08 17:32:27 +02:00
Andreas Schwab 4e22f95057 libio: use _IO_have_wbackup for wide streams
Fix two wrong uses of _IO_have_backup on a wide stream.
2026-06-08 17:01:15 +02:00
Sam James d0cc9bf859 elf: don't clobber ld.so.conf in tst-glibc-hwcaps-prepend-cache [BZ #34210]
dbe5065f21 and ae589cb84d
cater for setups where ld.so.conf{,.d} is required to find runtime support
libraries, but tst-glibc-hwcaps-prepend-cache clobbers the created ld.so.conf
with its own entry.

Fix it to instead use the ld.so.conf.d created in ae589cb84d
to co-exist with existing entries.

Bug: https://bugs.gentoo.org/976773
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31901
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=34210
Tested-by: Andreas K. Hüttel <dilfridge@gentoo.org>
Reported-by: Eli Schwartz <eschwartz@gentoo.org>
Reviewed-by: Andreas K. Hüttel <dilfridge@gentoo.org>
2026-06-06 21:22:46 +01:00
Adhemerval Zanella 2b6f6710a1 elf: Remove inhibit_stack_protector from __ifunc_resolver
With 01964c3ec8e fix ifunc resolvers can be fully instrumented with
stack protector.

Checked on aarch64-linux-gnu, x86_64-linux-gnu, and i686-linux-gnu
built with --enable-stack-protector=all.

Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
2026-06-05 16:20:20 -03:00
Adhemerval Zanella f9a11a380d elf: Set up TLS slotinfo for dlopen'd modules before relocation (BZ 34170)
An IFUNC resolver in a DSO that is being loaded by dlopen is allowed
to read its own TLS storage during the resolver call.  After
af34b1376a ("elf: Initialize static TLS before relocation processing
(BZ 34164)") that works for the initial-exec model on every supported
architecture.

However, it does not work for the dynamic-TLS path (on both -mtls-dialect mode,
if the ABI supports both).  Both lookup paths index the calling thread's
DTV by the new module's l_tls_modid and, on miss, walk
GL(dl_tls_dtv_slotinfo_list) to discover the module and lazily allocate
its TLS block.  The just-loaded DSO is however not yet in that list when
its resolver fires, so the lookup faults inside dlopen.  This is the
direct dlopen analog of BZ 34164.

The solution is to reorder dl_open_worker_begin so the slotinfo install
happens before the relocation pass.  The new order is:

  1. resize_scopes, resize_tls_slotinfo, add_to_global_resize
     (unchanged, still recoverable).
  2. update_tls_slotinfo: register the new modules in slotinfo, bump
     dl_tls_generation, initialise their static TLS images.
  3. Relocate the new objects.  IFUNC resolvers can now read their
     own DSO's __thread storage via any TLS model.
  4. Demarcation point.
  5. update_scopes, _dl_find_object_update.

Checked on aarch64-linux-gnu and x86_64-linux-gnu.

Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
2026-06-05 16:20:20 -03:00
Wilco Dijkstra 49244da110 malloc: Simplify _int_free_chunk
Simplify _int_free_chunk() and always lock if needed.  Use
_int_free_merge_chunk() for cases that assume the arena has been locked
instead.  Move the errno save/restore to _int_free_maybe_trim().

Reviewed-by: Yury Khrustalev <yury.khrustalev@arm.com>
2026-06-05 13:56:37 +00:00
c275c424b3 riscv: Add RVV strrchr for both multiarch and non-multiarch builds
This patch adds an RVV-optimized implementation of strrchr for RISC-V and
enables it for both multiarch (IFUNC) and non-multiarch builds.

The implementation integrates Hau Hsu's 2023 RVV work under a unified
ifunc-based framework. A vectorized version (__strrchr_vector) is added
alongside the generic fallback (__strrchr_generic). The runtime resolver
selects the RVV variant when RISCV_HWPROBE_KEY_IMA_EXT_0 reports vector
support (RVV).

Currently, the resolver still selects the RVV variant even when the RVV
extension is disabled via prctl(). As a consequence, any process that
has RVV disabled via prctl() will receive SIGILL when calling strrchr().

Co-authored-by: Hau Hsu <hau.hsu@sifive.com>
Co-authored-by: Jerry Shih <jerry.shih@sifive.com>
Signed-off-by: Yao Zihong <zihong.plct@isrc.iscas.ac.cn>
Reviewed-by: Peter Bergner <bergner@tenstorrent.com>
2026-06-05 00:48:14 +00:00
bbc3867f8d riscv: Add RVV strchr for both multiarch and non-multiarch builds
This patch adds an RVV-optimized implementation of strchr for RISC-V and
enables it for both multiarch (IFUNC) and non-multiarch builds.

The implementation integrates Hau Hsu's 2023 RVV work under a unified
ifunc-based framework. A vectorized version (__strchr_vector) is added
alongside the generic fallback (__strchr_generic). The runtime resolver
selects the RVV variant when RISCV_HWPROBE_KEY_IMA_EXT_0 reports vector
support (RVV).

Currently, the resolver still selects the RVV variant even when the RVV
extension is disabled via prctl(). As a consequence, any process that
has RVV disabled via prctl() will receive SIGILL when calling strchr().

Co-authored-by: Hau Hsu <hau.hsu@sifive.com>
Co-authored-by: Jerry Shih <jerry.shih@sifive.com>
Signed-off-by: Yao Zihong <zihong.plct@isrc.iscas.ac.cn>
Reviewed-by: Peter Bergner <bergner@tenstorrent.com>
2026-06-05 00:48:09 +00:00
512f99e71d riscv: Add RVV memchr for both multiarch and non-multiarch builds
This patch adds an RVV-optimized implementation of memchr for RISC-V and
enables it for both multiarch (IFUNC) and non-multiarch builds.

The implementation integrates Hau Hsu's 2023 RVV work under a unified
ifunc-based framework. A vectorized version (__memchr_vector) is added
alongside the generic fallback (__memchr_generic). The runtime resolver
selects the RVV variant when RISCV_HWPROBE_KEY_IMA_EXT_0 reports vector
support (RVV).

Currently, the resolver still selects the RVV variant even when the RVV
extension is disabled via prctl(). As a consequence, any process that
has RVV disabled via prctl() will receive SIGILL when calling memchr().

Co-authored-by: Hau Hsu <hau.hsu@sifive.com>
Co-authored-by: Jerry Shih <jerry.shih@sifive.com>
Signed-off-by: Yao Zihong <zihong.plct@isrc.iscas.ac.cn>
Reviewed-by: Peter Bergner <bergner@tenstorrent.com>
2026-06-05 00:48:01 +00:00
496ccfe312 riscv: Add RVV memccpy for both multiarch and non-multiarch builds
This patch adds an RVV-optimized implementation of memccpy for RISC-V and
enables it for both multiarch (IFUNC) and non-multiarch builds.

The implementation integrates Hau Hsu's 2023 RVV work under a unified
ifunc-based framework. A vectorized version (__memccpy_vector) is added
alongside the generic fallback (__memccpy_generic). The runtime resolver
selects the RVV variant when RISCV_HWPROBE_KEY_IMA_EXT_0 reports vector
support (RVV).

Currently, the resolver still selects the RVV variant even when the RVV
extension is disabled via prctl(). As a consequence, any process that
has RVV disabled via prctl() will receive SIGILL when calling memccpy().

Co-authored-by: Hau Hsu <hau.hsu@sifive.com>
Co-authored-by: Jerry Shih <jerry.shih@sifive.com>
Signed-off-by: Yao Zihong <zihong.plct@isrc.iscas.ac.cn>
Reviewed-by: Peter Bergner <bergner@tenstorrent.com>
2026-06-05 00:47:51 +00:00
2efc702628 riscv: Add RVV memcmp for both multiarch and non-multiarch builds
This patch adds an RVV-optimized implementation of memcmp for RISC-V and
enables it for both multiarch (IFUNC) and non-multiarch builds.

The implementation integrates Hau Hsu's 2023 RVV work under a unified
ifunc-based framework. A vectorized version (__memcmp_vector) is added
alongside the generic fallback (__memcmp_generic). The runtime resolver
selects the RVV variant when RISCV_HWPROBE_KEY_IMA_EXT_0 reports vector
support (RVV).

Currently, the resolver still selects the RVV variant even when the RVV
extension is disabled via prctl(). As a consequence, any process that
has RVV disabled via prctl() will receive SIGILL when calling memcmp().

Co-authored-by: Hau Hsu <hau.hsu@sifive.com>
Co-authored-by: Jerry Shih <jerry.shih@sifive.com>
Signed-off-by: Yao Zihong <zihong.plct@isrc.iscas.ac.cn>
Reviewed-by: Peter Bergner <bergner@tenstorrent.com>
2026-06-04 19:02:07 -05:00
Wilco Dijkstra 93e6135904 malloc: Reduce maximum arenas
The default maximum arenas is 8 times the number of cores in a 64-bit system.
Since modern CPUs have many cores and big servers have 256 cores, this results
in excessive number of arenas, which wastes memory.  Limit the number of arenas
to max (8, ncores) which is less extreme.  In the future the limit should be
lowered further for large systems.

Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
2026-06-04 14:25:37 +00:00
Adam Yi 13dc1040af resolv: reset _u._ext.nscount in __res_iclose [BZ #34154]
__res_iclose, when called with FREE_ADDR=true, frees and NULLs every
statp->_u._ext.nsaddrs[ns] but does not reset statp->_u._ext.nscount.
This breaks the invariant relied on by __res_context_send's cache
validation loop in resolv/res_send.c:293-312: when _u._ext.nscount
is non-zero, every _u._ext.nsaddrs[ns] corresponding to
statp->nsaddr_list[ns].sin_family != 0 is expected to be non-NULL.

res_init unconditionally calls __res_iclose(&_res, true) before
__res_vinit, so any __res_vinit failure (for example,
fopen("/etc/resolv.conf") returning EMFILE under file-descriptor
exhaustion, or any allocation failure in __resolv_conf_load,
__resolv_conf_allocate, or __resolv_conf_attach before
update_from_conf runs) leaves _u._ext.nscount non-zero with all
_u._ext.nsaddrs[] NULL.  The next name lookup walks the validation
loop and dereferences NULL in sock_eq.  A DNS lookup may fail after
a failed res_init, but it should not segfault.

Reset _u._ext.nscount = 0 alongside the existing __resolv_conf_detach
call.  The next __res_context_send call then re-enters its init
block (res_send.c:316-335) and repopulates _u._ext.nsaddrs[] from
statp->nsaddr_list[], which __res_iclose leaves untouched.  This
also lets support/resolv_test.c drop its now-redundant manual reset
after __res_iclose(&_res, true).

Add a regression test that drops RLIMIT_NOFILE so fopen of
/etc/resolv.conf fails with EMFILE inside __res_vinit, then verifies
the subsequent gethostbyname does not crash.

Signed-off-by: Adam Yi <ayi@janestreet.com>
Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
2026-06-03 11:11:09 -03:00
Alejandro Colomar 20fffa2c39 sysdeps/ieee754/ldbl-128ibm-compat/test-printf-chk-ldbl-compat.c: Fix typo
Signed-off-by: Alejandro Colomar <alx@kernel.org>
Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
2026-06-03 11:11:06 -03:00
Wilco Dijkstra b7e256c32c malloc: Improve documentation of malloc tunables
Update default for tcache_count tunable.  Remove existing documentation and
mention removal of fastbins in mxfast tunable.  Improve wording of hugetlb
tunable, including default for AArch64.

Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
2026-06-03 13:10:58 +00:00
Wilco Dijkstra 4a7805d05c malloc: Minor cleanups
Merge request2size into checked_request2size.  Improve interface of
clear_memory.  Fix incorrect use of __glibc_unlikely in __libc_calloc.
Fix missing tabs.

Reviewed-by: Yury Khrustalev <yury.khrustalev@arm.com>
2026-06-03 13:10:06 +00:00
Adhemerval Zanella 0b27186151 support: Also run malloc hugetlb=1 tests when transparent hugepage is 'always'
The glibc.malloc.hugetlb=1 is redundant with kernel is n 'always'
mode, but the madvise does work, and the tunable should not fail.

Suggested-by: Yury Khrustalev <yury.khrustalev@arm.com>
Reviewed-by: Yury Khrustalev <yury.khrustalev@arm.com>
2026-06-03 09:09:27 -03:00
Adhemerval Zanella e951752cd0 arm: Fix main-in-dso with non-BFD linkers (BZ 34098)
Commit c2d6afb4a0 changed the PIC && !SHARED path of start.S (used by
crt1.o and rcrt1.o) to load main via a R_ARM_REL32 data relocation.  When
main is provided by a shared object, BFD ld synthesizes a canonical PLT
entry for it, but other linkers (e.g. mold) do not, producing a broken
binary that crashes at startup.

Follow the aarch64 approach and reference main through a local __wrap_main
that tail-calls it with a branch relocation, which every linker turns into
a PLT entry.

Checked on armv7a-linux-gnueabihf with and without --enable-default-pie.
2026-06-03 09:09:12 -03:00
Adhemerval Zanella 5879990337 elf: Fix tst-ifunc-tls-init with --disable-default-pie
The test failed with --disable-default-pie because its primary check read
the resolver's diagnostic side effect before the resolver had run.

In a non-PIE executable the references to the IFUNC (fptr and ifunc_tls)
are satisfied through a canonical IPLT entry in the executable itself.
Under the default lazy binding that IPLT is resolved on first use, not
during startup relocation, so the resolver had not yet run when
'check_sentinel' inspected that value.  With a PIE executable
(or LD_BIND_NOW=1) the resolver runs eagerly at startup and the check
passed.  The dlopen path was unaffected because dlopen resolves the
data relocation eagerly.

This is a test ordering issue: the resolver always reads the initial-exec
TLS correctly whenever it runs, so the BZ 34164 fix is not involved.
Reorder test_tls_ifunc so that fptr/ifunc_tls force the IFUNC to be
resolved before the last_seen_sentinel value is inspected.

Checked on x86_64-linux-gnu and i686-linux-gnu with --disable-default-pie.

Reported-by: Yury Khrustalev <yury.khrustalev@arm.com>
Reviewed-by: Yury Khrustalev <yury.khrustalev@arm.com>
2026-06-02 15:10:02 -03:00
Sachin Monga 7193069543 powerpc64le: Add optimized __memcmpeq for POWER10
__memcmpeq (added in glibc 2.35) was previously an alias to memcmp on
POWER10 via strong_alias. However, in the multiarch IFUNC path, this
caused __memcmpeq to resolve to the generic C memcmp.c implementation
rather than the optimized POWER10 memcmp.S, leaving a significant
performance gap.

Unlike memcmp, __memcmpeq only needs to return zero or nonzero with
no requirement on the sign or magnitude for unequal inputs, allowing
a simpler and faster implementation.

Performance on POWER10 :

  1) __memcmpeq (generic) -> __memcmpeq_power10
     The primary motivation - __memcmpeq was resolving to generic C
     in the multiarch path.

  - Small data (< 8B to < 512B) : ~52% - 82% improvement.
  - Bulk  (< 16MB to < 256MB)   : ~25% - 32% improvement.
  - Large (1GB)			: ~33% improvement

  2) memcmp_power10 (optimized .S) -> __memcmpeq_power10:
     Comparing dedicated __memcmpeq against the optimized memcmp
     it previously aliased to.

  - Small data (< 8B to < 256B) : No improvement observed.
    Real-world workloads predominantly operate on larger buffers
  - >= 512B			: ~9%  improvement.
  - 16MB - 128MB		: ~25% - 32% improvement.
  - 256MB			: ~3%  improvement.
  - Large (1GB)			: On par.

Reviewed-by: Wilco Dijkstra  <Wilco.Dijkstra@arm.com>
2026-06-02 00:51:36 -05:00
Adhemerval Zanella c5278a6428 arm: Redirect memcpy to __memcpy_arm for loader/static init code
After "elf: Initialize TCB and stack-protector before static IFUNC
resolvers (BZ 20680, BZ 27582, BZ 28817)", early loader and static
initialization code may run before the IFUNC resolvers are processed.

The armv7-a supports memcpy, so add a dl-symbol-redir-ifunc.h to
redirect the memcpy to to __memcpy_arm implementation.

Checked on armv7a-linux-gnueabihf.
2026-06-01 13:16:26 -03:00
Yury Khrustalev 0458560b5d misc: Fix typos in comments 2026-06-01 13:29:53 +01:00
463 changed files with 10687 additions and 2719 deletions
-6
View File
@@ -158,12 +158,6 @@ passed to 'configure'. For example:
Don't build libraries with profiling information. You may want to
use this option if you don't plan to do profiling.
'--enable-static-nss'
Compile static versions of the NSS (Name Service Switch) libraries.
This is not recommended because it defeats the purpose of NSS; a
program linked statically with the NSS libraries cannot be
dynamically reconfigured to use a different name database.
'--enable-hardcoded-path-in-tests'
By default, dynamic tests are linked to run with the installed C
library. This option hardcodes the newly built C library path in
+25
View File
@@ -9,6 +9,15 @@ Version 2.44
Major new features:
* A new tunable, glibc.elf.thp, is added to map read-only segments with
Transparent Huge Pages (THP) if THP isn't disable in kernel. When
glibc.elf.thp is set to 1, malloc uses the actual kernel THP mode
instead of defaulting to madvise mode and madvise_thp will stop issuing
MADV_HUGEPAGE if kernel THP mode is always.
* THP page size in malloc is capped to MAX_THP_PAGESIZE. If THP page
size is above MAX_THP_PAGESIZE, THP in malloc is disabled.
* Additional optimized and correctly rounded mathematical functions have
been imported from the CORE-MATH project, in particular cosh, sinh, and
tanh.
@@ -21,6 +30,13 @@ Major new features:
* Static PIE is now supported for arm-*-linux-gnueabi. It requires toolchain
support to correctly set the expected linker options.
* On AArch64 targets that support Guarded Control Stack extension all GCS
operations (including status, write on shadow stack, and push to shadow
stack) are locked after enabling GCS with ENFORCED or OVERRIDE GCS policy.
When a GCS operation is locked, a program cannot change this operation
status via prctl syscall. This prevents disabling or corrupting GCS
shadow stack during runtime.
Deprecated and removed features, and other changes affecting compatibility:
* Although malloc and related functions currently return pointers
@@ -32,6 +48,15 @@ Deprecated and removed features, and other changes affecting compatibility:
* The s390-linux-gnu (31bit) configuration is no longer supported.
* The --enable-memory-tagging configure option has been removed.
The corresponding AArch64-specific functionality that was previously
activated by this flag has been removed as well.
* The --enable-static-nss configure option has been removed. It had no
effect on the build since the NSS reorganization in glibc 2.33; its only
remaining behavior was to suppress the link-time warnings on the NSS
interface functions in libc.a, which are now emitted unconditionally.
Changes to build and runtime requirements:
[Add changes to build and runtime requirements here]
+522 -1
View File
@@ -262,7 +262,7 @@ tzdata:
# The project is distribute here:
# https://gitlab.inria.fr/core-math/core-math/
core-math:
# src/binary64/acosh/acosh.c, revision 1bd85b89
# src/binary64/acosh/acosh.c, revision 887cab6f
sysdeps/ieee754/dbl-64/e_acosh.c
# src/binary64/atanh/atanh.c, revision 532e37dc
sysdeps/ieee754/dbl-64/e_atanh.c
@@ -332,3 +332,524 @@ core-math:
sysdeps/ieee754/flt-32/s_tanhf.c
# src/binary32/tanpi/tanpif.c, revision 3bbf907
sysdeps/ieee754/flt-32/s_tanpif.c
# The following files are imported from the Arm Optimized-Routines project,
# with adjustments made to follow glibc code style and integrate with
# glibc-specific infrastructure where needed.
#
# The project is distributed here:
# https://github.com/ARM-software/optimized-routines/
arm-optimized-routines:
# Math routines
# math/math_config.h, revision 712aa21
sysdeps/ieee754/flt-32/math_config.h
# math/math_config.h, revision 712aa21
sysdeps/ieee754/dbl-64/math_config.h
# math/math_err.c, revision 189dfef
sysdeps/ieee754/dbl-64/math_err.c
# math/math_errf.c, revision 189dfef
sysdeps/ieee754/flt-32/math_errf.c
# math/cosf.c, revision aec783d
sysdeps/ieee754/flt-32/s_cosf.c
# math/exp2f.c, revision 712aa21
sysdeps/ieee754/flt-32/e_exp2f.c
# math/exp2f_data.c, revision 189dfef
sysdeps/ieee754/flt-32/e_exp2f_data.c
# math/expf.c, revision 712aa21
sysdeps/ieee754/flt-32/e_expf.c
# math/log2f.c, revision 712aa21
sysdeps/ieee754/flt-32/e_log2f.c
# math/log2f_data.c, revision 189dfef
sysdeps/ieee754/flt-32/e_log2f_data.c
# math/logf.c, revision 712aa21
sysdeps/ieee754/flt-32/e_logf.c
# math/logf_data.c, revision c0136f1
sysdeps/ieee754/flt-32/e_logf_data.c
# math/powf.c, revision 712aa21
sysdeps/ieee754/flt-32/e_powf.c
# math/powf_log2_data.c, revision 189dfef
sysdeps/ieee754/flt-32/e_powf_log2_data.c
# math/sincosf.c, revision af29d39
sysdeps/ieee754/flt-32/s_sincosf.c
# math/sincosf.h, revision aed553c
sysdeps/ieee754/flt-32/s_sincosf.h
# math/sincosf_data.c, revision 189dfef
sysdeps/ieee754/flt-32/s_sincosf_data.c
# math/sinf.c, revision aec783d
sysdeps/ieee754/flt-32/s_sinf.c
# math/exp.c, revision 712aa21
sysdeps/ieee754/dbl-64/e_exp.c
# math/exp10.c, revision 712aa21
sysdeps/ieee754/dbl-64/e_exp10.c
# math/exp2.c, revision 712aa21
sysdeps/ieee754/dbl-64/e_exp2.c
# math/exp_data.c, revision c013701
sysdeps/ieee754/dbl-64/e_exp_data.c
# math/log.c, revision 712aa21
sysdeps/ieee754/dbl-64/e_log.c
# math/log2.c, revision 712aa21
sysdeps/ieee754/dbl-64/e_log2.c
# math/log2_data.c, revision 189dfef
sysdeps/ieee754/dbl-64/e_log2_data.c
# math/log_data.c, revision 189dfef
sysdeps/ieee754/dbl-64/e_log_data.c
# math/pow.c, revision 712aa21
sysdeps/ieee754/dbl-64/e_pow.c
# math/pow_log_data.c, revision 189dfef
sysdeps/ieee754/dbl-64/e_pow_log_data.c
# Mathvec routines
# math/math_config.h, revision 712aa21
sysdeps/aarch64/fpu/vecmath_config.h
# math/aarch64/v_erf_data.c, revision 0a6ab6d
sysdeps/aarch64/fpu/erf_data.c
# math/aarch64/v_erfc_data.c, revision 0a6ab6d
sysdeps/aarch64/fpu/erfc_data.c
# math/aarch64/v_erfcf_data.c, revision 0a6ab6d
sysdeps/aarch64/fpu/erfcf_data.c
# math/aarch64/v_erff_data.c, revision 0a6ab6d
sysdeps/aarch64/fpu/erff_data.c
# math/aarch64/v_exp_data.c, revision 0a6ab6d
sysdeps/aarch64/fpu/v_exp_data.c
# math/aarch64/v_exp_tail_data.c, revision 0a6ab6d
sysdeps/aarch64/fpu/v_exp_tail_data.c
# math/aarch64/v_log10_data.c, revision 0a6ab6d
sysdeps/aarch64/fpu/v_log10_data.c
# math/aarch64/v_log2_data.c, revision 0a6ab6d
sysdeps/aarch64/fpu/v_log2_data.c
# math/aarch64/v_log_data.c, revision 0a6ab6d
sysdeps/aarch64/fpu/v_log_data.c
# math/aarch64/v_pow_exp_data.c, revision 0a6ab6d
sysdeps/aarch64/fpu/v_pow_exp_data.c
# math/aarch64/v_pow_log_data.c, revision 0a6ab6d
sysdeps/aarch64/fpu/v_pow_log_data.c
# math/aarch64/v_powf_data.c, revision 0a6ab6d
sysdeps/aarch64/fpu/v_powf_data.c
# math/aarch64/sve/acos.c, revision 1aad38d
sysdeps/aarch64/fpu/sve/acos.c
# math/aarch64/sve/acosf.c, revision 1aad38d
sysdeps/aarch64/fpu/sve/acosf.c
# math/aarch64/sve/acosh.c, revision 8b665af
sysdeps/aarch64/fpu/sve/acosh.c
# math/aarch64/sve/acoshf.c, revision 1aad38d
sysdeps/aarch64/fpu/sve/acoshf.c
# math/aarch64/sve/acospi.c, revision 1aad38d
sysdeps/aarch64/fpu/sve/acospi.c
# math/aarch64/sve/acospif.c, revision 1aad38d
sysdeps/aarch64/fpu/sve/acospif.c
# math/aarch64/sve/asin.c, revision 1aad38d
sysdeps/aarch64/fpu/sve/asin.c
# math/aarch64/sve/asinf.c, revision 1aad38d
sysdeps/aarch64/fpu/sve/asinf.c
# math/aarch64/sve/asinh.c, revision 9bf4cfc
sysdeps/aarch64/fpu/sve/asinh.c
# math/aarch64/sve/asinhf.c, revision 1aad38d
sysdeps/aarch64/fpu/sve/asinhf.c
# math/aarch64/sve/asinpi.c, revision 1aad38d
sysdeps/aarch64/fpu/sve/asinpi.c
# math/aarch64/sve/asinpif.c, revision 1aad38d
sysdeps/aarch64/fpu/sve/asinpif.c
# math/aarch64/sve/atan.c, revision 1aad38d
sysdeps/aarch64/fpu/sve/atan.c
# math/aarch64/sve/atan2.c, revision 1aad38d
sysdeps/aarch64/fpu/sve/atan2.c
# math/aarch64/sve/atan2f.c, revision 1aad38d
sysdeps/aarch64/fpu/sve/atan2f.c
# math/aarch64/sve/atan2pi.c, revision 1aad38d
sysdeps/aarch64/fpu/sve/atan2pi.c
# math/aarch64/sve/atan2pif.c, revision 1aad38d
sysdeps/aarch64/fpu/sve/atan2pif.c
# math/aarch64/sve/atanf.c, revision 1aad38d
sysdeps/aarch64/fpu/sve/atanf.c
# math/aarch64/sve/atanh.c, revision 29c7342
sysdeps/aarch64/fpu/sve/atanh.c
# math/aarch64/sve/atanhf.c, revision 1aad38d
sysdeps/aarch64/fpu/sve/atanhf.c
# math/aarch64/sve/atanpi.c, revision 1aad38d
sysdeps/aarch64/fpu/sve/atanpi.c
# math/aarch64/sve/atanpif.c, revision 1aad38d
sysdeps/aarch64/fpu/sve/atanpif.c
# math/aarch64/sve/cbrt.c, revision 1aad38d
sysdeps/aarch64/fpu/sve/cbrt.c
# math/aarch64/sve/cbrtf.c, revision 1aad38d
sysdeps/aarch64/fpu/sve/cbrtf.c
# math/aarch64/sve/cos.c, revision 99cbbad
sysdeps/aarch64/fpu/sve/cos.c
# math/aarch64/sve/cosf.c, revision 25aa012
sysdeps/aarch64/fpu/sve/cosf.c
# math/aarch64/sve/cosh.c, revision 242a017
sysdeps/aarch64/fpu/sve/cosh.c
# math/aarch64/sve/coshf.c, revision 2fff60c
sysdeps/aarch64/fpu/sve/coshf.c
# math/aarch64/sve/cospi.c, revision 1aad38d
sysdeps/aarch64/fpu/sve/cospi.c
# math/aarch64/sve/cospif.c, revision 1aad38d
sysdeps/aarch64/fpu/sve/cospif.c
# math/aarch64/sve/erf.c, revision 1aad38d
sysdeps/aarch64/fpu/sve/erf.c
# math/aarch64/sve/erfc.c, revision 1aad38d
sysdeps/aarch64/fpu/sve/erfc.c
# math/aarch64/sve/erfcf.c, revision 1aad38d
sysdeps/aarch64/fpu/sve/erfcf.c
# math/aarch64/sve/erff.c, revision 1aad38d
sysdeps/aarch64/fpu/sve/erff.c
# math/aarch64/sve/exp.c, revision d664b69
sysdeps/aarch64/fpu/sve/exp.c
# math/aarch64/sve/exp10.c, revision d664b69
sysdeps/aarch64/fpu/sve/exp10.c
# math/aarch64/sve/exp10f.c, revision d664b69
sysdeps/aarch64/fpu/sve/exp10f.c
# math/aarch64/sve/exp10m1.c, revision d664b69
sysdeps/aarch64/fpu/sve/exp10m1.c
# math/aarch64/sve/exp10m1f.c, revision d664b69
sysdeps/aarch64/fpu/sve/exp10m1f.c
# math/aarch64/sve/exp2.c, revision d664b69
sysdeps/aarch64/fpu/sve/exp2.c
# math/aarch64/sve/exp2f.c, revision d664b69
sysdeps/aarch64/fpu/sve/exp2f.c
# math/aarch64/sve/exp2m1.c, revision d664b69
sysdeps/aarch64/fpu/sve/exp2m1.c
# math/aarch64/sve/exp2m1f.c, revision d664b69
sysdeps/aarch64/fpu/sve/exp2m1f.c
# math/aarch64/sve/expf.c, revision 47044a5
sysdeps/aarch64/fpu/sve/expf.c
# math/aarch64/sve/expm1.c, revision d664b69
sysdeps/aarch64/fpu/sve/expm1.c
# math/aarch64/sve/expm1f.c, revision d664b69
sysdeps/aarch64/fpu/sve/expm1f.c
# math/aarch64/sve/hypot.c, revision 74d699d
sysdeps/aarch64/fpu/sve/hypot.c
# math/aarch64/sve/hypotf.c, revision 74d699d
sysdeps/aarch64/fpu/sve/hypotf.c
# math/aarch64/sve/log.c, revision 91b052e
sysdeps/aarch64/fpu/sve/log.c
# math/aarch64/sve/log10.c, revision 91b052e
sysdeps/aarch64/fpu/sve/log10.c
# math/aarch64/sve/log10f.c, revision 8ca4cc0
sysdeps/aarch64/fpu/sve/log10f.c
# math/aarch64/sve/log10p1.c, revision 166744d
sysdeps/aarch64/fpu/sve/log10p1.c
# math/aarch64/sve/log10p1f.c, revision 8124d30
sysdeps/aarch64/fpu/sve/log10p1f.c
# math/aarch64/sve/log1p.c, revision 1aad38d
sysdeps/aarch64/fpu/sve/log1p.c
# math/aarch64/sve/log1pf.c, revision 1aad38d
sysdeps/aarch64/fpu/sve/log1pf.c
# math/aarch64/sve/log2.c, revision 91b052e
sysdeps/aarch64/fpu/sve/log2.c
# math/aarch64/sve/log2f.c, revision 8ca4cc0
sysdeps/aarch64/fpu/sve/log2f.c
# math/aarch64/sve/log2p1.c, revision 1aad38d
sysdeps/aarch64/fpu/sve/log2p1.c
# math/aarch64/sve/log2p1f.c, revision 1aad38d
sysdeps/aarch64/fpu/sve/log2p1f.c
# math/aarch64/sve/logf.c, revision 8ca4cc0
sysdeps/aarch64/fpu/sve/logf.c
# math/aarch64/sve/pow.c, revision 2c38e83
sysdeps/aarch64/fpu/sve/pow.c
# math/aarch64/sve/powf.c, revision 2c38e83
sysdeps/aarch64/fpu/sve/powf.c
# math/aarch64/sve/powr.c, revision 30da949
sysdeps/aarch64/fpu/sve/powr.c
# math/aarch64/sve/powrf.c, revision e2bca42
sysdeps/aarch64/fpu/sve/powrf.c
# math/aarch64/sve/rsqrt.c, revision 4fc7374
sysdeps/aarch64/fpu/sve/rsqrt.c
# math/aarch64/sve/rsqrtf.c, revision b1bc8ba
sysdeps/aarch64/fpu/sve/rsqrtf.c
# math/aarch64/sve/sin.c, revision 99cbbad
sysdeps/aarch64/fpu/sve/sin.c
# math/aarch64/sve/sinf.c, revision 25aa012
sysdeps/aarch64/fpu/sve/sinf.c
# math/aarch64/sve/sinh.c, revision 242a017
sysdeps/aarch64/fpu/sve/sinh.c
# math/aarch64/sve/sinhf.c, revision 2fff60c
sysdeps/aarch64/fpu/sve/sinhf.c
# math/aarch64/sve/sinpi.c, revision 1aad38d
sysdeps/aarch64/fpu/sve/sinpi.c
# math/aarch64/sve/sinpif.c, revision 1aad38d
sysdeps/aarch64/fpu/sve/sinpif.c
# math/aarch64/sve/tan.c, revision 1aad38d
sysdeps/aarch64/fpu/sve/tan.c
# math/aarch64/sve/tanf.c, revision 1aad38d
sysdeps/aarch64/fpu/sve/tanf.c
# math/aarch64/sve/tanh.c, revision 1aad38d
sysdeps/aarch64/fpu/sve/tanh.c
# math/aarch64/sve/tanhf.c, revision 2fff60c
sysdeps/aarch64/fpu/sve/tanhf.c
# math/aarch64/sve/tanpi.c, revision 1aad38d
sysdeps/aarch64/fpu/sve/tanpi.c
# math/aarch64/sve/tanpif.c, revision 1aad38d
sysdeps/aarch64/fpu/sve/tanpif.c
# math/aarch64/sve/sv_exp_special_inline.h, revision d664b69
sysdeps/aarch64/fpu/sve/sv_exp_special_inline.h
# math/aarch64/sve/sv_expf_inline.h, revision ba35b32
sysdeps/aarch64/fpu/sve/sv_expf_inline.h
# math/aarch64/sve/sv_expf_special_inline.h, revision d664b69
sysdeps/aarch64/fpu/sve/sv_expf_special_inline.h
# math/aarch64/sve/sv_expm1f_inline.h, revision 78cd003
sysdeps/aarch64/fpu/sve/sv_expm1f_inline.h
# math/aarch64/sve/sv_log1p_inline.h, revision 7d08237
sysdeps/aarch64/fpu/sve/sv_log1p_inline.h
# math/aarch64/sve/sv_log1pf_inline.h, revision a386525
sysdeps/aarch64/fpu/sve/sv_log1pf_inline.h
# math/aarch64/sve/sv_pow_inline.h, revision 30da949
sysdeps/aarch64/fpu/sve/sv_pow_inline.h
# math/aarch64/sve/sv_powf_inline.h, revision 30da949
sysdeps/aarch64/fpu/sve/sv_powf_inline.h
# math/aarch64/sve/sv_poly_f32.h, revision 5d5e6e6
sysdeps/aarch64/fpu/sve/poly_sve_f32.h
# math/aarch64/sve/sv_poly_f64.h, revision 5d5e6e6
sysdeps/aarch64/fpu/sve/poly_sve_f64.h
# math/aarch64/sve/sv_poly_generic.h, revision 5d5e6e6
sysdeps/aarch64/fpu/sve/poly_sve_generic.h
# math/aarch64/sve/sv_math.h, revision 7361ef6
sysdeps/aarch64/fpu/sve/sv_math.h
# math/aarch64/sve/sv_trig_fallback.h, revision 99cbbad
sysdeps/aarch64/fpu/sve/sv_trig_fallback.h
# math/aarch64/sve/sv_trigf_fallback.h, revision 25aa012
sysdeps/aarch64/fpu/sve/sv_trigf_fallback.h
# math/aarch64/advsimd/acos.c, revision 1aad38d
sysdeps/aarch64/fpu/advsimd/acos.c
# math/aarch64/advsimd/acosf.c, revision 1aad38d
sysdeps/aarch64/fpu/advsimd/acosf.c
# math/aarch64/advsimd/acosh.c, revision 188e75a
sysdeps/aarch64/fpu/advsimd/acosh.c
# math/aarch64/advsimd/acoshf.c, revision af3851e
sysdeps/aarch64/fpu/advsimd/acoshf.c
# math/aarch64/advsimd/acospi.c, revision 1aad38d
sysdeps/aarch64/fpu/advsimd/acospi.c
# math/aarch64/advsimd/acospif.c, revision 1aad38d
sysdeps/aarch64/fpu/advsimd/acospif.c
# math/aarch64/advsimd/asin.c, revision 1aad38d
sysdeps/aarch64/fpu/advsimd/asin.c
# math/aarch64/advsimd/asinf.c, revision 1aad38d
sysdeps/aarch64/fpu/advsimd/asinf.c
# math/aarch64/advsimd/asinh.c, revision bac1b4f
sysdeps/aarch64/fpu/advsimd/asinh.c
# math/aarch64/advsimd/asinhf.c, revision af3851e
sysdeps/aarch64/fpu/advsimd/asinhf.c
# math/aarch64/advsimd/asinpi.c, revision 1aad38d
sysdeps/aarch64/fpu/advsimd/asinpi.c
# math/aarch64/advsimd/asinpif.c, revision 1aad38d
sysdeps/aarch64/fpu/advsimd/asinpif.c
# math/aarch64/advsimd/atan.c, revision 1aad38d
sysdeps/aarch64/fpu/advsimd/atan.c
# math/aarch64/advsimd/atan2.c, revision 1aad38d
sysdeps/aarch64/fpu/advsimd/atan2.c
# math/aarch64/advsimd/atan2f.c, revision 1aad38d
sysdeps/aarch64/fpu/advsimd/atan2f.c
# math/aarch64/advsimd/atan2pi.c, revision 1aad38d
sysdeps/aarch64/fpu/advsimd/atan2pi.c
# math/aarch64/advsimd/atan2pif.c, revision 1aad38d
sysdeps/aarch64/fpu/advsimd/atan2pif.c
# math/aarch64/advsimd/atanf.c, revision 1aad38d
sysdeps/aarch64/fpu/advsimd/atanf.c
# math/aarch64/advsimd/atanh.c, revision 281cb3a
sysdeps/aarch64/fpu/advsimd/atanh.c
# math/aarch64/advsimd/atanhf.c, revision d852158
sysdeps/aarch64/fpu/advsimd/atanhf.c
# math/aarch64/advsimd/atanpi.c, revision 1aad38d
sysdeps/aarch64/fpu/advsimd/atanpi.c
# math/aarch64/advsimd/atanpif.c, revision 1aad38d
sysdeps/aarch64/fpu/advsimd/atanpif.c
# math/aarch64/advsimd/cbrt.c, revision 0a6ab6d
sysdeps/aarch64/fpu/advsimd/cbrt.c
# math/aarch64/advsimd/cbrtf.c, revision 6c74650
sysdeps/aarch64/fpu/advsimd/cbrtf.c
# math/aarch64/advsimd/cos.c, revision 677a12b
sysdeps/aarch64/fpu/advsimd/cos.c
# math/aarch64/advsimd/cosf.c, revision 15c35d9
sysdeps/aarch64/fpu/advsimd/cosf.c
# math/aarch64/advsimd/cosh.c, revision 447bbaa
sysdeps/aarch64/fpu/advsimd/cosh.c
# math/aarch64/advsimd/coshf.c, revision 45237ba
sysdeps/aarch64/fpu/advsimd/coshf.c
# math/aarch64/advsimd/cospi.c, revision 1aad38d
sysdeps/aarch64/fpu/advsimd/cospi.c
# math/aarch64/advsimd/cospif.c, revision 1aad38d
sysdeps/aarch64/fpu/advsimd/cospif.c
# math/aarch64/advsimd/erf.c, revision 1aad38d
sysdeps/aarch64/fpu/advsimd/erf.c
# math/aarch64/advsimd/erfc.c, revision 1aad38d
sysdeps/aarch64/fpu/advsimd/erfc.c
# math/aarch64/advsimd/erfcf.c, revision 1aad38d
sysdeps/aarch64/fpu/advsimd/erfcf.c
# math/aarch64/advsimd/erff.c, revision 1aad38d
sysdeps/aarch64/fpu/advsimd/erff.c
# math/aarch64/advsimd/exp.c, revision dce5dab
sysdeps/aarch64/fpu/advsimd/exp.c
# math/aarch64/advsimd/exp10.c, revision dce5dab
sysdeps/aarch64/fpu/advsimd/exp10.c
# math/aarch64/advsimd/exp10f.c, revision 69d38dd
sysdeps/aarch64/fpu/advsimd/exp10f.c
# math/aarch64/advsimd/exp10m1.c, revision dce5dab
sysdeps/aarch64/fpu/advsimd/exp10m1.c
# math/aarch64/advsimd/exp10m1f.c, revision a5092e8
sysdeps/aarch64/fpu/advsimd/exp10m1f.c
# math/aarch64/advsimd/exp2.c, revision dce5dab
sysdeps/aarch64/fpu/advsimd/exp2.c
# math/aarch64/advsimd/exp2f.c, revision 69d38dd
sysdeps/aarch64/fpu/advsimd/exp2f.c
# math/aarch64/advsimd/exp2m1.c, revision dce5dab
sysdeps/aarch64/fpu/advsimd/exp2m1.c
# math/aarch64/advsimd/exp2m1f.c, revision a5092e8
sysdeps/aarch64/fpu/advsimd/exp2m1f.c
# math/aarch64/advsimd/expf.c, revision 69d38dd
sysdeps/aarch64/fpu/advsimd/expf.c
# math/aarch64/advsimd/expm1.c, revision dce5dab
sysdeps/aarch64/fpu/advsimd/expm1.c
# math/aarch64/advsimd/expm1f.c, revision a5092e8
sysdeps/aarch64/fpu/advsimd/expm1f.c
# math/aarch64/advsimd/hypot.c, revision 09f8d05
sysdeps/aarch64/fpu/advsimd/hypot.c
# math/aarch64/advsimd/hypotf.c, revision 99dff4f
sysdeps/aarch64/fpu/advsimd/hypotf.c
# math/aarch64/advsimd/log.c, revision 0345857
sysdeps/aarch64/fpu/advsimd/log.c
# math/aarch64/advsimd/log10.c, revision 77aff35
sysdeps/aarch64/fpu/advsimd/log10.c
# math/aarch64/advsimd/log10f.c, revision ff1596f
sysdeps/aarch64/fpu/advsimd/log10f.c
# math/aarch64/advsimd/log10p1.c, revision 7fc8510
sysdeps/aarch64/fpu/advsimd/log10p1.c
# math/aarch64/advsimd/log10p1f.c, revision 58cd796
sysdeps/aarch64/fpu/advsimd/log10p1f.c
# math/aarch64/advsimd/log1p.c, revision 355a985
sysdeps/aarch64/fpu/advsimd/log1p.c
# math/aarch64/advsimd/log1pf.c, revision 5cf8408
sysdeps/aarch64/fpu/advsimd/log1pf.c
# math/aarch64/advsimd/log2.c, revision b8deb33
sysdeps/aarch64/fpu/advsimd/log2.c
# math/aarch64/advsimd/log2f.c, revision b98f80d
sysdeps/aarch64/fpu/advsimd/log2f.c
# math/aarch64/advsimd/log2p1.c, revision 1aad38d
sysdeps/aarch64/fpu/advsimd/log2p1.c
# math/aarch64/advsimd/log2p1f.c, revision 58cd796
sysdeps/aarch64/fpu/advsimd/log2p1f.c
# math/aarch64/advsimd/logf.c, revision 1b15b12
sysdeps/aarch64/fpu/advsimd/logf.c
# math/aarch64/advsimd/finite_pow.h, revision 30da949
sysdeps/aarch64/fpu/advsimd/finite_pow.h
# math/pow_common.h, revision 30da949
sysdeps/aarch64/fpu/pow_common.h
# math/powf_common.h, revision 30da949
sysdeps/aarch64/fpu/powf_common.h
# math/aarch64/advsimd/pow.c, revision 30da949
sysdeps/aarch64/fpu/advsimd/pow.c
# math/aarch64/advsimd/powf.c, revision 30da949
sysdeps/aarch64/fpu/advsimd/powf.c
# math/aarch64/advsimd/powr.c, revision 30da949
sysdeps/aarch64/fpu/advsimd/powr.c
# math/aarch64/advsimd/powrf.c, revision e2bca42
sysdeps/aarch64/fpu/advsimd/powrf.c
# math/aarch64/advsimd/rsqrt.c, revision 0945eab
sysdeps/aarch64/fpu/advsimd/rsqrt.c
# math/aarch64/advsimd/rsqrtf.c, revision 88e9cc9
sysdeps/aarch64/fpu/advsimd/rsqrtf.c
# math/aarch64/advsimd/sin.c, revision 677a12b
sysdeps/aarch64/fpu/advsimd/sin.c
# math/aarch64/advsimd/sinf.c, revision 15c35d9
sysdeps/aarch64/fpu/advsimd/sinf.c
# math/aarch64/advsimd/sinh.c, revision 447bbaa
sysdeps/aarch64/fpu/advsimd/sinh.c
# math/aarch64/advsimd/sinhf.c, revision 45237ba
sysdeps/aarch64/fpu/advsimd/sinhf.c
# math/aarch64/advsimd/sinpi.c, revision 1aad38d
sysdeps/aarch64/fpu/advsimd/sinpi.c
# math/aarch64/advsimd/sinpif.c, revision 1aad38d
sysdeps/aarch64/fpu/advsimd/sinpif.c
# math/aarch64/advsimd/tan.c, revision a8bbb87
sysdeps/aarch64/fpu/advsimd/tan.c
# math/aarch64/advsimd/tanf.c, revision 1aad38d
sysdeps/aarch64/fpu/advsimd/tanf.c
# math/aarch64/advsimd/tanh.c, revision 447bbaa
sysdeps/aarch64/fpu/advsimd/tanh.c
# math/aarch64/advsimd/tanhf.c, revision 45237ba
sysdeps/aarch64/fpu/advsimd/tanhf.c
# math/aarch64/advsimd/tanpi.c, revision 1aad38d
sysdeps/aarch64/fpu/advsimd/tanpi.c
# math/aarch64/advsimd/tanpif.c, revision 1aad38d
sysdeps/aarch64/fpu/advsimd/tanpif.c
# math/aarch64/advsimd/v_exp_special_case_inline.h, revision dce5dab
sysdeps/aarch64/fpu/advsimd/v_exp_special_case_inline.h
# math/aarch64/advsimd/v_expf_inline.h, revision 747e0e1
sysdeps/aarch64/fpu/advsimd/v_expf_inline.h
# math/aarch64/advsimd/v_expf_special_inline.h, revision a5092e8
sysdeps/aarch64/fpu/advsimd/v_expf_special_inline.h
# math/aarch64/advsimd/v_expm1_inline.h, revision 0a6ab6d
sysdeps/aarch64/fpu/advsimd/v_expm1_inline.h
# math/aarch64/advsimd/v_expm1f_inline.h, revision 0a6ab6d
sysdeps/aarch64/fpu/advsimd/v_expm1f_inline.h
# math/aarch64/advsimd/v_log1p_inline.h, revision 1aad38d
sysdeps/aarch64/fpu/advsimd/v_log1p_inline.h
# math/aarch64/advsimd/v_log1pf_inline.h, revision 0a6ab6d
sysdeps/aarch64/fpu/advsimd/v_log1pf_inline.h
# math/aarch64/advsimd/v_pow_inline.h, revision efde0c7
sysdeps/aarch64/fpu/advsimd/v_pow_inline.h
# math/aarch64/advsimd/v_powf_inline.h, revision 5b06a16
sysdeps/aarch64/fpu/advsimd/v_powf_inline.h
# math/aarch64/advsimd/v_powrf_inline.h, revision 30da949
sysdeps/aarch64/fpu/advsimd/v_powrf_inline.h
# math/aarch64/advsimd/v_poly_f32.h, revision 0a6ab6d
sysdeps/aarch64/fpu/advsimd/poly_advsimd_f32.h
# math/aarch64/advsimd/v_poly_f64.h, revision 0a6ab6d
sysdeps/aarch64/fpu/advsimd/poly_advsimd_f64.h
# math/poly_generic.h, revision 0a6ab6d
sysdeps/aarch64/fpu/advsimd/poly_generic.h
# math/aarch64/advsimd/v_math.h, revision 1829557
sysdeps/aarch64/fpu/advsimd/v_math.h
# math/aarch64/advsimd/v_trig_fallback.h, revision 677a12b
sysdeps/aarch64/fpu/advsimd/v_trig_fallback.h
# math/aarch64/advsimd/v_trigf_fallback.h, revision 15c35d9
sysdeps/aarch64/fpu/advsimd/v_trigf_fallback.h
# String routines
# string/aarch64/__mtag_tag_region.S, revision 41e5ae5
sysdeps/aarch64/__mtag_tag_region.S
# string/aarch64/__mtag_tag_zero_region.S, revision 41e5ae5
sysdeps/aarch64/__mtag_tag_zero_region.S
# string/aarch64/memchr-mte.S, revision 41e5ae5
sysdeps/aarch64/memchr.S
# string/aarch64/memcmp.S, revision 41e5ae5
sysdeps/aarch64/memcmp.S
# string/aarch64/memcpy-advsimd.S, revision 41e5ae5
sysdeps/aarch64/memcpy.S
# string/aarch64/memcpy-mops.S, revision 41e5ae5
sysdeps/aarch64/multiarch/memcpy_mops.S
# string/aarch64/memcpy-sve.S, revision 71e3640
sysdeps/aarch64/multiarch/memcpy_sve.S
# string/aarch64/memmove-mops.S, revision 41e5ae5
sysdeps/aarch64/multiarch/memmove_mops.S
# string/aarch64/memrchr.S, revision 41e5ae5
sysdeps/aarch64/memrchr.S
# string/aarch64/memset-mops.S, revision 41e5ae5
sysdeps/aarch64/multiarch/memset_mops.S
# string/aarch64/memset-sve.S, revision 0f71101
sysdeps/aarch64/multiarch/memset_sve_zva64.S
# string/aarch64/memset.S, revision 098df8c
sysdeps/aarch64/memset.S
# string/aarch64/stpcpy.S, revision 189dfef
sysdeps/aarch64/stpcpy.S
# string/aarch64/strchr-mte.S, revision 41e5ae5
sysdeps/aarch64/strchr.S
# string/aarch64/strchrnul-mte.S, revision 41e5ae5
sysdeps/aarch64/strchrnul.S
# string/aarch64/strcmp.S, revision 41e5ae5
sysdeps/aarch64/strcmp.S
# string/aarch64/strcpy.S, revision 41e5ae5
sysdeps/aarch64/strcpy.S
# string/aarch64/strlen-mte.S, revision 41e5ae5
sysdeps/aarch64/strlen.S
# string/aarch64/strncmp.S, revision 41e5ae5
sysdeps/aarch64/strncmp.S
# string/aarch64/strnlen.S, revision 41e5ae5
sysdeps/aarch64/strnlen.S
# string/aarch64/strrchr-mte.S, revision 41e5ae5
sysdeps/aarch64/strrchr.S
# string/arm/memchr.S, revision 1eb5d7c
sysdeps/arm/armv6t2/memchr.S
# string/arm/memcpy.S, revision 1eb5d7c
sysdeps/arm/armv7/multiarch/memcpy_impl.S
# string/arm/strcmp.S, revision 1eb5d7c
sysdeps/arm/armv7/strcmp.S
# string/arm/strlen-armv6t2.S, revision 1eb5d7c
sysdeps/arm/armv6t2/strlen.S
+6 -6
View File
@@ -1,11 +1,11 @@
Buffer overread in ns_printrrf with corrupted RDATA field
The deprecated functions ns_printrrf, ns_printrr and fp_nquery in the
GNU C Library version 2.2 and newer fail to validate the RDATA content
against the RDATA length in a DNS response when processing LOC, CERT,
TKEY or TSIG records, which may allow an attacker to craft a DNS
response, causing a target application to crash or read uninitialized
memory.
GNU C Library version 2.0.1 to version 2.43 fail to validate the RDATA
content against the RDATA length in a DNS response when processing A6,
CERT, LOC, TKEY or TSIG records, which may allow an attacker to craft a
DNS response, causing a target application to crash or read
uninitialized memory.
These functions are for application debugging only and hence not in the
path of code executed by the DNS resolver. Further, they have been
@@ -15,4 +15,4 @@ interfaces since they may be removed in future versions.
CVE-Id: CVE-2026-6238
Public-Date: 2026-04-11
Vulnerable-Commit: b43b13ac2544b11f35be301d1589b51a8473e32b (2.2)
Vulnerable-Commit: ee188d555b8c32ad9704a7440cab400af967292f (1.90)
+20
View File
@@ -0,0 +1,20 @@
Potential stack-based buffer clash during tilde expansion in wordexp
Calling wordexp with a tilde (~) followed by an overly long username
in the GNU C Library version 2.2.3 to 2.43 may lead to a stack buffer
clash.
When expanding paths that begin with a tilde (~) followed by a username, the
internal parse_tilde function extracts the username to determine the user's
home directory. The implementation allocates memory for this username directly
on the stack using the strndupa macro. Because the size of this allocation
was determined by the length of the user-supplied input without any bounds
checks, passing an excessively long username e.g. thousands of characters,
forces the thread to exhaust its stack space. Thus if an application passes
untrusted, attacker-controlled input to the wordexp function, an attacker
can trigger a stack clash.
CVE-Id: CVE-2026-6791
Public-Date: 2026-06-22
Vulnerable-Commit: 344af000e1d6e9c7882b9bc48e71cb3f1b5fc03c (2.2.3-114)
Reported-by: storm
-3
View File
@@ -32,9 +32,6 @@
/* Define if _Unwind_Find_FDE should be exported from glibc. */
#undef EXPORT_UNWIND_FIND_FDE
/* Define if static NSS modules are wanted. */
#undef DO_STATIC_NSS
/* Assume that the compiler supports __builtin_expect.
This macro is necessary for proper compilation of code
shared between GNU libc and GNU gettext projects. */
-1
View File
@@ -81,7 +81,6 @@ mach-interface-list = @mach_interface_list@
# Configuration options.
build-shared = @shared@
build-profile = @profile@
build-static-nss = @static_nss@
cross-compiling = @cross_compiling@
force-install = @force_install@
build-nscd = @build_nscd@
Vendored
-19
View File
@@ -616,7 +616,6 @@ RELEASE
VERSION
mach_interface_list
DEFINES
static_nss
profile
libc_cv_multidir
test_enable_cet
@@ -804,7 +803,6 @@ enable_hardcoded_path_in_tests
enable_hidden_plt
enable_bind_now
enable_stack_protector
enable_static_nss
enable_force_install
enable_maintainer_mode
enable_kernel
@@ -1477,7 +1475,6 @@ Optional Features:
--enable-stack-protector=[yes|no|all|strong]
Use -fstack-protector[-all|-strong] to detect glibc
buffer overflows
--enable-static-nss build static NSS modules [default=no]
--disable-force-install don't force installation of files from this package,
even if they are older than the installed files
--enable-maintainer-mode
@@ -4614,21 +4611,6 @@ all|yes|no|strong) ;;
*) as_fn_error $? "Not a valid argument for --enable-stack-protector: \"$enable_stack_protector\"" "$LINENO" 5;;
esac
# Check whether --enable-static-nss was given.
if test ${enable_static_nss+y}
then :
enableval=$enable_static_nss; static_nss=$enableval
else case e in #(
e) static_nss=no ;;
esac
fi
if test x"$static_nss" = xyes || test x"$shared" = xno; then
static_nss=yes
printf "%s\n" "#define DO_STATIC_NSS 1" >>confdefs.h
fi
# Check whether --enable-force-install was given.
if test ${enable_force_install+y}
then :
@@ -9595,7 +9577,6 @@ libc_cv_multidir=`${CC-cc} $CFLAGS $CPPFLAGS -print-multi-directory`
VERSION=`sed -n -e 's/^#define VERSION "\([^"]*\)"/\1/p' < $srcdir/version.h`
RELEASE=`sed -n -e 's/^#define RELEASE "\([^"]*\)"/\1/p' < $srcdir/version.h`
-14
View File
@@ -272,19 +272,6 @@ all|yes|no|strong) ;;
*) AC_MSG_ERROR([Not a valid argument for --enable-stack-protector: "$enable_stack_protector"]);;
esac
dnl On some platforms we cannot use dynamic loading. We must provide
dnl static NSS modules.
AC_ARG_ENABLE([static-nss],
AS_HELP_STRING([--enable-static-nss],
[build static NSS modules @<:@default=no@:>@]),
[static_nss=$enableval],
[static_nss=no])
dnl Enable static NSS also if we build no shared objects.
if test x"$static_nss" = xyes || test x"$shared" = xno; then
static_nss=yes
AC_DEFINE(DO_STATIC_NSS)
fi
AC_ARG_ENABLE([force-install],
AS_HELP_STRING([--disable-force-install],
[don't force installation of files from this package, even if they are older than the installed files]),
@@ -2200,7 +2187,6 @@ libc_cv_multidir=`${CC-cc} $CFLAGS $CPPFLAGS -print-multi-directory`
AC_SUBST(libc_cv_multidir)
AC_SUBST(profile)
AC_SUBST(static_nss)
AC_SUBST(DEFINES)
+14 -8
View File
@@ -44,21 +44,20 @@ extern void __libc_init_first (int argc, char **argv, char **envp);
#include <tls.h>
#ifndef SHARED
# include <dl-osinfo.h>
# include <dl-reseed-random.h>
# include <dl-symbol-redir-ifunc.h>
# ifndef THREAD_SET_STACK_GUARD
/* Only exported for architectures that don't store the stack guard canary
in thread local area. */
uintptr_t __stack_chk_guard attribute_relro;
# endif
# ifndef THREAD_SET_POINTER_GUARD
/* Only exported for architectures that don't store the pointer guard
value in thread local area. */
uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden;
# endif
#endif
#ifndef SHARED
# include <link.h>
# include <dl-irel.h>
# include <dl-symbol-redir-ifunc.h>
# ifdef ELF_MACHINE_IRELA
# define IREL_T ElfW(Rela)
@@ -205,6 +204,7 @@ call_fini (void *unused)
#endif /* !SHARED */
#include <libc-start.h>
#include <dl-exec-post.h>
STATIC int LIBC_START_MAIN (int (*main) (int, char **, char **
MAIN_AUXVEC_DECL),
@@ -294,11 +294,12 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL),
/* Set up the pointer guard value. */
uintptr_t pointer_chk_guard = _dl_setup_pointer_guard (_dl_random,
stack_chk_guard);
# ifdef THREAD_SET_POINTER_GUARD
THREAD_SET_POINTER_GUARD (pointer_chk_guard);
# else
__pointer_chk_guard_local = pointer_chk_guard;
# endif
/* We do not need the _dl_random value anymore. Scrub the AT_RANDOM
bytes and clear the pointer; on targets with an entropy source, refill
the bytes with fresh random data. */
_dl_reseed_random (&_dl_random);
/* Now that the TCB, canary, and pointer guard are in place, run the
deferred IFUNC relocations. For non-PIE static binaries this is
@@ -307,6 +308,11 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL),
_dl_relocate_static_pie_ifunc ();
ARCH_SETUP_IREL ();
/* This must run after the IFUNC relocations: _dl_executable_postprocess
may call IFUNC-resolved routines. */
struct link_map *main_map = _dl_get_dl_main_map ();
_dl_executable_postprocess (main_map, GL(dl_phdr), GL(dl_phnum));
/* Initialize libpthread if linked in. */
if (__pthread_initialize_minimal != NULL)
__pthread_initialize_minimal ();
+36 -1
View File
@@ -270,6 +270,7 @@ tests-static-normal := \
tst-env-setuid-static \
tst-getauxval-static \
tst-linkall-static \
tst-ptrguard-static-dlopen \
tst-single_threaded-pthread-static \
tst-single_threaded-static \
tst-tls-allocation-failure-static \
@@ -278,6 +279,7 @@ tests-static-normal := \
# tests-static-normal
tests-static-internal := \
tst-atrandom-scrub-static \
tst-dl-printf-static \
tst-dl_find_object-static \
tst-env-setuid-tunables \
@@ -547,6 +549,7 @@ tests-internal += \
neededtest2 \
neededtest3 \
neededtest4 \
tst-atrandom-scrub \
tst-audit19a \
tst-create_format1 \
tst-dl-hwcaps_split \
@@ -576,6 +579,7 @@ tests-container += \
tst-dlopen-tlsmodid-container \
tst-pldd \
tst-preload-pthread-libc \
tst-ptrguard-static-dlopen \
tst-rootdir \
# tests-container
@@ -1013,6 +1017,7 @@ modules-names += \
tst-null-argv-lib \
tst-p_alignmod-base \
tst-p_alignmod3 \
tst-ptrguard-static-dlopen-mod \
tst-recursive-tlsmallocmod \
tst-recursive-tlsmod0 \
tst-recursive-tlsmod1 \
@@ -1296,6 +1301,7 @@ tests += \
tst-ifunc-plt-dlopen-bindnow \
tst-ifunc-resolver-protector \
tst-ifunc-tls-init \
tst-ifunc-tls-init-gd-ld \
tst-ifunc-tls-write \
tst-tls-tdata-reloc \
# tests
@@ -1363,11 +1369,20 @@ modules-names += \
tst-ifunc-plt-dep \
tst-ifunc-plt-lib \
tst-ifunc-resolver-protector-mod \
tst-ifunc-tls-init-gd-global-lib \
tst-ifunc-tls-init-gd-lib \
tst-ifunc-tls-init-ld-lib \
tst-ifunc-tls-init-lib1 \
tst-ifunc-tls-init-lib2 \
tst-ifunc-tls-write-lib \
tst-tls-tdata-reloc-lib \
# modules-names
ifneq (no,$(have-test-mtls-descriptor))
tests += tst-ifunc-tls-init-tlsdesc
modules-names += tst-ifunc-tls-init-tlsdesc-lib
CFLAGS-tst-ifunc-tls-init-tlsdesc-lib.c += \
-mtls-dialect=$(have-test-mtls-descriptor)
endif
ifeq (no,$(with-lld))
modules-names += ifuncmod5
endif
@@ -2407,6 +2422,9 @@ tst-ptrguard1-ARGS = --command "$(host-test-program-cmd) --child"
CFLAGS-tst-ptrguard1-static.c += -DPTRGUARD_LOCAL
tst-ptrguard1-static-ARGS = --command "$(objpfx)tst-ptrguard1-static --child"
# Likewise, the static pointer guard lives in __pointer_chk_guard_local.
CFLAGS-tst-atrandom-scrub-static.c += -DPTRGUARD_LOCAL
$(objpfx)tst-leaks1-mem.out: $(objpfx)tst-leaks1.out
$(common-objpfx)malloc/mtrace $(objpfx)tst-leaks1.mtrace > $@; \
$(evaluate-test)
@@ -2522,6 +2540,20 @@ $(objpfx)tst-ifunc-tls-init.out: \
$(objpfx)tst-ifunc-tls-write: $(objpfx)tst-ifunc-tls-write-lib.so
$(objpfx)tst-tls-tdata-reloc: $(objpfx)tst-tls-tdata-reloc-lib.so
$(objpfx)tst-ifunc-tls-init-gd-ld: $(shared-thread-library)
$(objpfx)tst-ifunc-tls-init-gd-ld.out: \
$(objpfx)tst-ifunc-tls-init-gd-lib.so \
$(objpfx)tst-ifunc-tls-init-gd-global-lib.so \
$(objpfx)tst-ifunc-tls-init-ld-lib.so
tst-ifunc-tls-init-gd-ld-TUNABLES = glibc.rtld.optional_static_tls=0
ifneq (no,$(have-test-mtls-descriptor))
$(objpfx)tst-ifunc-tls-init-tlsdesc: $(shared-thread-library)
$(objpfx)tst-ifunc-tls-init-tlsdesc.out: \
$(objpfx)tst-ifunc-tls-init-tlsdesc-lib.so
tst-ifunc-tls-init-tlsdesc-TUNABLES = glibc.rtld.optional_static_tls=0
endif # $(have-test-mtls-descriptor)
$(objpfx)tst-unique1.out: $(objpfx)tst-unique1mod1.so \
$(objpfx)tst-unique1mod2.so
@@ -2810,7 +2842,7 @@ $(objpfx)tst-ldconfig-soname.out : tst-ldconfig-soname.sh \
# Test static linking of all the libraries we can possibly link
# together. Note that in some configurations this may be less than the
# complete list of libraries we build but we try to maxmimize this list.
# complete list of libraries we build but we try to maximize this list.
$(objpfx)tst-linkall-static: \
$(common-objpfx)math/libm.a \
$(common-objpfx)resolv/libresolv.a \
@@ -3177,6 +3209,9 @@ $(objpfx)tst-tls21mod.so: $(tst-tls-many-dynamic-modules:%=$(objpfx)%.so)
$(objpfx)tst-getauxval-static.out: $(objpfx)tst-auxvalmod.so
tst-getauxval-static-ENV = LD_LIBRARY_PATH=$(objpfx):$(common-objpfx)
$(objpfx)tst-ptrguard-static-dlopen.out: \
$(objpfx)tst-ptrguard-static-dlopen-mod.so
$(objpfx)tst-dlmopen-gethostbyname.out: $(objpfx)tst-dlmopen-gethostbyname-mod.so
$(objpfx)tst-ro-dynamic: $(objpfx)tst-ro-dynamic-mod.so
+1 -1
View File
@@ -485,7 +485,7 @@ _dl_close_worker (struct link_map *map, bool force)
size_t tls_free_end;
tls_free_start = tls_free_end = NO_TLS_OFFSET;
/* Protects global and module specitic TLS state. */
/* Protects global and module specific TLS state. */
__rtld_lock_lock_recursive (GL(dl_load_tls_lock));
/* We modify the list of loaded objects. */
+1 -1
View File
@@ -557,7 +557,7 @@ cannot load auxiliary `%s' because of empty dynamic string token "
/* Copy the binary into position 0. */
l_initfini[0] = map->l_searchlist.r_list[map_index];
/* Copy the filtees. */
/* Copy the filters. */
for (i = 0; i < map_index; ++i)
l_initfini[i+1] = map->l_searchlist.r_list[i];
+2 -2
View File
@@ -465,7 +465,7 @@ _dl_find_object (void *pc1, struct dl_find_object *result)
}
rtld_hidden_def (_dl_find_object)
/* Subroutine of _dlfo_process_initial to split out noncontigous link
/* Subroutine of _dlfo_process_initial to split out noncontiguous link
maps. NODELETE is the number of used _dlfo_nodelete_mappings
elements. It is incremented as needed, and the new NODELETE value
is returned. */
@@ -586,7 +586,7 @@ _dl_find_object_init (void)
{
/* Non-contiguous main maps are handled in
_dlfo_process_initial. Mark as initialized, but not
coverying any valid PC. */
covering any valid PC. */
_dlfo_main.map_start = -1;
_dlfo_main.map_end = -1;
}
+3
View File
@@ -112,6 +112,7 @@ struct loadcmd
int prot; /* PROT_* bits. */
};
#include <dl-load-post.h>
/* Iterator for program header segments. Initialize with
_dl_pt_load_iterator_init, then either walk PT_LOAD segments via
@@ -215,6 +216,8 @@ _dl_postprocess_loadcmd (struct link_map *l, const ElfW(Ehdr) *header,
/* Found the program header in this segment. */
l->l_phdr = (void *) (uintptr_t) (c->mapstart + header->e_phoff
- c->mapoff);
_dl_postprocess_loadcmd_extra (l, c);
}
+26 -27
View File
@@ -658,6 +658,31 @@ dl_open_worker_begin (void *a)
bool relocation_in_progress = false;
/* This only performs the memory allocations. The actual update of
the scopes happens below, after failure is impossible. */
resize_scopes (new);
/* Increase the size of the GL (dl_tls_dtv_slotinfo_list) data
structure. */
bool any_tls = resize_tls_slotinfo (new);
/* Perform the necessary allocations for adding new global objects
to the global scope below. */
if (mode & RTLD_GLOBAL)
add_to_global_resize (new);
/* Install the new modules in the DTV slotinfo and initialise their
static TLS *before* relocation, so an IFUNC resolver firing during
the relocation loop below can reach its DSO's __thread storage via
__tls_get_addr / TLSDESC. Without this, the resolver's TLS access
for a just-loaded module would index into an unallocated DTV slot
and crash. If relocation later fails, the subsequent _dl_close_worker
cleans up these slotinfo entries via remove_slotinfo. */
if (any_tls)
/* FIXME: This calls _dl_update_slotinfo, which aborts the process
on memory allocation failure. See bug 16134. */
update_tls_slotinfo (new);
/* Perform relocation. This can trigger lazy binding in IFUNC
resolvers. For NODELETE mappings, these dependencies are not
recorded because the flag has not been applied to the newly
@@ -682,19 +707,6 @@ dl_open_worker_begin (void *a)
_dl_open_relocate_one_object (args, r, new->l_initfini[i], reloc_mode,
&relocation_in_progress);
/* This only performs the memory allocations. The actual update of
the scopes happens below, after failure is impossible. */
resize_scopes (new);
/* Increase the size of the GL (dl_tls_dtv_slotinfo_list) data
structure. */
bool any_tls = resize_tls_slotinfo (new);
/* Perform the necessary allocations for adding new global objects
to the global scope below. */
if (mode & RTLD_GLOBAL)
add_to_global_resize (new);
/* Demarcation point: After this, no recoverable errors are allowed.
All memory allocations for new objects must have happened
before. */
@@ -716,19 +728,6 @@ dl_open_worker_begin (void *a)
_dl_signal_error (ENOMEM, new->l_libname->name, NULL,
N_ ("cannot allocate address lookup data"));
/* FIXME: It is unclear whether the order here is correct.
Shouldn't new objects be made available for binding (and thus
execution) only after there TLS data has been set up fully?
Fixing bug 16134 will likely make this distinction less
important. */
/* Second stage after resize_tls_slotinfo: Update the slotinfo data
structures. */
if (any_tls)
/* FIXME: This calls _dl_update_slotinfo, which aborts the process
on memory allocation failure. See bug 16134. */
update_tls_slotinfo (new);
/* Notify the debugger all new objects have been relocated. */
if (relocation_in_progress)
LIBC_PROBE (reloc_complete, 3, args->nsid, r, new);
@@ -777,7 +776,7 @@ dl_open_worker (void *a)
#ifdef SHARED
if (was_not_consistent)
/* Avoid redudant/recursive signalling. */
/* Avoid redundant/recursive signalling. */
_dl_audit_activity_nsid (nsid, LA_ACT_CONSISTENT);
#endif
}
+6
View File
@@ -179,6 +179,12 @@ int _dl_stack_cache_lock;
#endif
struct dl_scope_free_list *_dl_scope_free_list;
#ifdef HAVE_THP
enum dl_elf_thp_control_t _dl_elf_thp_control;
enum thp_mode_t _dl_thp_mode;
size_t _dl_elf_thp_pagesize;
#endif
#ifdef NEED_DL_SYSINFO
/* Needed for improved syscall handling on at least x86/Linux. NB: Don't
initialize it here to avoid RELATIVE relocation in static PIE. */
+3 -3
View File
@@ -339,7 +339,7 @@ _dl_determine_tlsoffset (void)
/* Extra TLS block for internal usage to append at the end of the TLS blocks
(in allocation order). The address at which the block is allocated must
be aligned to 'extra_tls_align'. The size of the block as returned by
'_dl_extra_tls_get_size ()' is always a multiple of the aligment.
'_dl_extra_tls_get_size ()' is always a multiple of the alignment.
On Linux systems this is where the rseq area will be allocated. On other
systems it is currently unused and both values will be '0'. */
@@ -419,7 +419,7 @@ _dl_determine_tlsoffset (void)
/* Extra TLS block for internal usage to append at the end of the TLS blocks
(in allocation order). The address at which the block is allocated must
be aligned to 'extra_tls_align'. The size of the block as returned by
'_dl_extra_tls_get_size ()' is always a multiple of the aligment.
'_dl_extra_tls_get_size ()' is always a multiple of the alignment.
On Linux systems this is where the rseq area will be allocated. On other
systems it is currently unused and both values will be '0'. */
@@ -699,7 +699,7 @@ _dl_allocate_tls_init (void *result, bool main_thread)
initialization because it would already be set by the
audit setup, which uses the dlopen code and already
clears l_need_tls_init. Calls with !main_thread from
pthread_create need to initialze TLS for the current
pthread_create need to initialize TLS for the current
thread regardless of namespace. */
if (map->l_ns != LM_ID_BASE && main_thread)
continue;
+11 -19
View File
@@ -35,6 +35,7 @@
#include <unsecvars.h>
#include <dl-cache.h>
#include <dl-osinfo.h>
#include <dl-reseed-random.h>
#include <dl-prop.h>
#include <dl-vdso.h>
#include <dl-vdso-setup.h>
@@ -52,6 +53,7 @@
#include <dl-find_object.h>
#include <dl-audit-check.h>
#include <dl-call_tls_init_tp.h>
#include <dl-exec-post.h>
#include <assert.h>
@@ -166,12 +168,8 @@ rtld_hidden_data_def (_dl_argv)
uintptr_t __stack_chk_guard attribute_relro;
#endif
/* Only exported for architectures that don't store the pointer guard
value in thread local area. */
uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden;
#ifndef THREAD_SET_POINTER_GUARD
strong_alias (__pointer_chk_guard_local, __pointer_chk_guard)
#endif
/* Check that AT_SECURE=0, or that the passed name does not contain
directories and is not overly long. Reject empty names
@@ -827,15 +825,12 @@ security_init (void)
/* Set up the pointer guard as well, if necessary. */
uintptr_t pointer_chk_guard
= _dl_setup_pointer_guard (_dl_random, stack_chk_guard);
#ifdef THREAD_SET_POINTER_GUARD
THREAD_SET_POINTER_GUARD (pointer_chk_guard);
#endif
__pointer_chk_guard_local = pointer_chk_guard;
/* We do not need the _dl_random value anymore. The less
information we leave behind, the better, so clear the
variable. */
_dl_random = NULL;
/* We do not need the _dl_random value anymore. Scrub the AT_RANDOM
bytes and clear the pointer; on targets with an entropy source, refill
the bytes with fresh random data. */
_dl_reseed_random (&_dl_random);
}
#include <setup-vdso.h>
@@ -1209,14 +1204,8 @@ rtld_setup_main_map (struct link_map *main_map)
main_map->l_relro_size = ph->p_memsz;
break;
}
/* Process program headers again, but scan them backwards since
PT_GNU_PROPERTY is close to the end of program headers. */
for (const ElfW(Phdr) *ph = &phdr[phnum]; ph != phdr; --ph)
if (ph[-1].p_type == PT_GNU_PROPERTY)
{
_dl_process_pt_gnu_property (main_map, -1, &ph[-1]);
break;
}
_dl_executable_postprocess (main_map, phdr, phnum);
/* Adjust the address of the TLS initialization image in case
the executable is actually an ET_DYN object. */
@@ -1589,6 +1578,9 @@ dl_main (const ElfW(Phdr) *phdr,
{
RTLD_TIMING_VAR (start);
rtld_timer_start (&start);
#ifdef HAVE_THP
_dl_get_thp_config ();
#endif
_dl_map_object (NULL, rtld_progname, lt_executable, 0,
__RTLD_OPENEXEC, LM_ID_BASE);
rtld_timer_stop (&load_time, start);
+10
View File
@@ -81,5 +81,15 @@ __rtld_static_init (struct link_map *map)
dl->_dl_find_object = _dl_find_object;
dl->_dl_readonly_area = _dl_readonly_area;
extern uintptr_t __pointer_chk_guard_local attribute_hidden;
const ElfW(Sym) *guard_sym
= _dl_lookup_direct (map, "__pointer_chk_guard",
0x69f99cab, /* _dl_new_hash output. */
"GLIBC_PRIVATE",
0x0963cf85); /* _dl_elf_hash output. */
assert (guard_sym != NULL);
*(uintptr_t *) DL_SYMBOL_ADDRESS (map, guard_sym)
= __pointer_chk_guard_local;
__rtld_static_init_arch (map, dl);
}
+1
View File
@@ -0,0 +1 @@
#include "tst-atrandom-scrub.c"
+89
View File
@@ -0,0 +1,89 @@
/* Verify the AT_RANDOM bytes do not reveal the guards after startup.
Copyright (C) 2026 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
/* The loader (security_init) and the static startup code (__libc_start_main)
derive the stack and pointer guards from the AT_RANDOM bytes, scrub those
bytes, and refill them with fresh entropy unrelated to the guards. The
AT_RANDOM entry is kept, so getauxval (AT_RANDOM) keeps returning 16 random
bytes, but they no longer reveal the guards. Check that neither guard can
be reconstructed from AT_RANDOM and that no auxiliary vector entry holds a
guard value. */
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <sys/auxv.h>
#include <stackguard-macros.h>
#include <tls.h>
#include <support/check.h>
static int
do_test (void)
{
uintptr_t stack_guard = STACK_CHK_GUARD;
uintptr_t pointer_guard = POINTER_CHK_GUARD;
unsigned char *random = (unsigned char *) getauxval (AT_RANDOM);
if (random == NULL)
FAIL_UNSUPPORTED ("the kernel did not provide AT_RANDOM");
printf ("debug: stack guard = %0*jx\n",
(int) (2 * sizeof (uintptr_t)), (uintmax_t) stack_guard);
printf ("debug: pointer guard = %0*jx\n",
(int) (2 * sizeof (uintptr_t)), (uintmax_t) pointer_guard);
printf ("debug: AT_RANDOM = ");
for (int i = 0; i < 16; i++)
printf ("%02x", random[i]);
printf ("\n");
/* Sanity check: the guards and AT_RANDOM must all have been populated
(not all-zero), otherwise we cannot tell scrub-and-reseed apart from
"never set up". */
TEST_VERIFY (stack_guard != 0);
TEST_VERIFY (pointer_guard != 0);
bool random_all_zero = true;
for (int i = 0; i < 16; i++)
if (random[i] != 0)
{
random_all_zero = false;
break;
}
TEST_VERIFY (!random_all_zero);
/* Reconstruct the guards from the (reseeded) AT_RANDOM bytes the way the
loader does and check that they no longer match the live guards. */
uintptr_t recovered_stack;
memcpy (&recovered_stack, random, sizeof (recovered_stack));
#if __BYTE_ORDER == __LITTLE_ENDIAN
recovered_stack &= ~(uintptr_t) 0xff;
#else
recovered_stack &= ~((uintptr_t) 0xff << (8 * (sizeof (recovered_stack) - 1)));
#endif
TEST_VERIFY (recovered_stack != stack_guard);
uintptr_t recovered_pointer;
memcpy (&recovered_pointer, random + sizeof (uintptr_t),
sizeof (recovered_pointer));
TEST_VERIFY (recovered_pointer != pointer_guard);
return 0;
}
#include <support/test-driver.c>
+1 -1
View File
@@ -46,7 +46,7 @@ do_test (void)
{
/* Install the default implementation of libmarkermod1.so. */
char *conf_path = xasprintf ("%s/ld.so.conf", support_sysconfdir_prefix);
char *conf_path = xasprintf ("%s/ld.so.conf.d/hwcaps.conf", support_sysconfdir_prefix);
xmkdirp (support_sysconfdir_prefix, 0777);
support_write_file_string (conf_path, "/glibc-test/lib\n");
free (conf_path);
+1
View File
@@ -41,6 +41,7 @@ my_foo (void)
static __typeof (foo) *
inhibit_stack_protector
__attribute_used__
foo_ifunc (void)
{
init_foo ();
+7 -4
View File
@@ -22,6 +22,7 @@
.rel{a}.plt). This verifies that every IRELATIVE entry is deferred
until after .rela.plt has been processed, not just the first one. */
#include <sys/cdefs.h>
#include <stddef.h>
extern int get_value (void);
@@ -38,14 +39,16 @@ impl_b (void)
return 2;
}
static int (*
resolve_a (void)) (void)
static typeof (impl_a) *
__attribute_used__
resolve_a (void)
{
return get_value () == 42 ? impl_a : NULL;
}
static int (*
resolve_b (void)) (void)
static typeof (impl_b) *
__attribute_used__
resolve_b (void)
{
return get_value () == 42 ? impl_b : NULL;
}
+3
View File
@@ -25,6 +25,8 @@
always observe an initialised canary; this test guards against any future
reordering that would break that invariant. */
#include <sys/cdefs.h>
#define SENTINEL 0x5A5A1234
static volatile int resolver_ran;
@@ -44,6 +46,7 @@ impl_ok (int x)
typedef int (*fn_t) (int);
static fn_t
__attribute_used__
resolver (void)
{
/* Buffer + zero-fill force -fstack-protector-all canary code. */
@@ -50,6 +50,7 @@ impl_ok (int x)
typedef int (*fn_t) (int);
static fn_t
__attribute_used__
resolver (void)
{
/* Buffer forces -fstack-protector-all to emit canary code even with
+3
View File
@@ -0,0 +1,3 @@
#define TLS_MODEL "global-dynamic"
#define SENTINEL_STORAGE /* empty */
#include "tst-ifunc-tls-init-gd-ld-lib-skeleton.c"
@@ -0,0 +1,73 @@
/* Shared-library skeleton for tst-ifunc-tls-init-gd-ld.
Copyright (C) 2026 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
/* Unlike tst-ifunc-tls-init-lib-skeleton.c, which uses initial-exec and
resolves via a single TP-relative load, this skeleton's TLS_MODEL is
either "global-dynamic" or "local-dynamic" so the resolver's read of
'sentinel' must traverse __tls_get_addr (or the architecture's
TLSDESC equivalent). That dynamic-TLS access can lazily allocate a
per-module TLS block, which is the path being exercised. */
#include <sys/cdefs.h>
#ifndef TLS_MODEL
# error "tst-ifunc-tls-init-gd-ld-lib-skeleton.c needs TLS_MODEL defined"
#endif
/* Without static the relocation against the SENTINEL goes through the regular
global-symbol lookup path; combined with TLS_MODEL="global-dynamic" this
exercises the "global GD" variant rather than the file-local one. */
#ifndef SENTINEL_STORAGE
# define SENTINEL_STORAGE static
#endif
#define SENTINEL 0x5A5A1234
SENTINEL_STORAGE volatile __thread int sentinel
__attribute__ ((tls_model (TLS_MODEL))) = SENTINEL;
static volatile int last_seen_sentinel;
static int
impl_ok (void)
{
return SENTINEL;
}
static int
impl_bad (void)
{
return 0;
}
int
get_last_seen_sentinel (void)
{
return last_seen_sentinel;
}
static typeof (impl_ok) *
__attribute_used__
resolver (void)
{
int s = sentinel;
last_seen_sentinel = s;
return s == SENTINEL ? impl_ok : impl_bad;
}
int ifunc_tls (void) __attribute__ ((ifunc ("resolver")));
int (*fptr) (void) = ifunc_tls;
+89
View File
@@ -0,0 +1,89 @@
/* Check if dynamic-TLS variables (global-dynamic, local-dynamic) are
correctly initialised in IFUNC resolvers reached via dlopen.
Copyright (C) 2026 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
/* This test dlopens three modules covering the dynamic-TLS access variants:
gd-lib file-local 'sentinel' + tls_model("global-dynamic")
ld-lib file-local 'sentinel' + tls_model("local-dynamic")
gd-global-lib external 'sentinel' + tls_model("global-dynamic")
In each case the IFUNC resolver's read of 'sentinel' must traverse the
dynamic-TLS resolution path at the moment the resolver fires during
dlopen-time relocation.
Each variant additionally calls the resolved IFUNC from a thread spawned
after dlopen, to verify per-thread DTV propagation for the newly-loaded
module. */
#include <support/check.h>
#include <support/xdlfcn.h>
#include <support/xthread.h>
#define SENTINEL 0x5A5A1234
struct ifunc_handles
{
int (*get_last_seen_sentinel) (void);
int (**fptr) (void);
int (*ifunc_tls) (void);
};
static void *
ifunc_caller (void *arg)
{
struct ifunc_handles *h = arg;
TEST_COMPARE ((*h->fptr) (), SENTINEL);
TEST_COMPARE (h->ifunc_tls (), SENTINEL);
return NULL;
}
static void
test_lib (const char *soname)
{
void *handle = xdlopen (soname, RTLD_LAZY | RTLD_LOCAL);
struct ifunc_handles h;
h.get_last_seen_sentinel = xdlsym (handle, "get_last_seen_sentinel");
h.fptr = xdlsym (handle, "fptr");
h.ifunc_tls = xdlsym (handle, "ifunc_tls");
TEST_COMPARE (h.get_last_seen_sentinel (), SENTINEL);
TEST_VERIFY (*h.fptr != NULL);
TEST_COMPARE ((*h.fptr) (), SENTINEL);
TEST_COMPARE (h.ifunc_tls (), SENTINEL);
/* From a thread spawned *after* the dlopen, which exercises DTV propagation
for the new module into a fresh TCB. */
pthread_t consumer = xpthread_create (NULL, ifunc_caller, &h);
xpthread_join (consumer);
xdlclose (handle);
}
static int
do_test (void)
{
test_lib ("tst-ifunc-tls-init-gd-lib.so");
test_lib ("tst-ifunc-tls-init-ld-lib.so");
test_lib ("tst-ifunc-tls-init-gd-global-lib.so");
return 0;
}
#include <support/test-driver.c>
+2
View File
@@ -0,0 +1,2 @@
#define TLS_MODEL "global-dynamic"
#include "tst-ifunc-tls-init-gd-ld-lib-skeleton.c"
+2
View File
@@ -0,0 +1,2 @@
#define TLS_MODEL "local-dynamic"
#include "tst-ifunc-tls-init-gd-ld-lib-skeleton.c"
+5 -1
View File
@@ -20,6 +20,8 @@
load, so the test is sensitive to whether the static TLS block has been
populated rather than to any __tls_get_addr / DTV-update timing. */
#include <sys/cdefs.h>
#define SENTINEL 0x5A5A1234
/* The 'volatile' avoids constant fold optimization in impl_ok. */
@@ -45,7 +47,9 @@ get_last_seen_sentinel (void)
return last_seen_sentinel;
}
static int (*resolver (void)) (void)
static typeof (impl_ok) *
__attribute_used__
resolver (void)
{
int s = sentinel;
last_seen_sentinel = s;
+3
View File
@@ -0,0 +1,3 @@
#define TLS_MODEL "global-dynamic"
#define SENTINEL_STORAGE /* empty */
#include "tst-ifunc-tls-init-gd-ld-lib-skeleton.c"
+69
View File
@@ -0,0 +1,69 @@
/* Check that an IFUNC resolver in a dlopen'd DSO can read .tdata-initialised
__thread storage when the TLS access is compiled as a TLSDESC sequence.
Copyright (C) 2026 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
/* Sibling of tst-ifunc-tls-init-gd-ld, but the TLS access in the loaded
DSO is compiled with the TLSDESC dialect (x86 gnu2, aarch64 desc). */
#include <support/check.h>
#include <support/xdlfcn.h>
#include <support/xthread.h>
#define SENTINEL 0x5A5A1234
struct ifunc_handles
{
int (*get_last_seen_sentinel) (void);
int (**fptr) (void);
int (*ifunc_tls) (void);
};
static void *
ifunc_caller (void *arg)
{
struct ifunc_handles *h = arg;
TEST_COMPARE ((*h->fptr) (), SENTINEL);
TEST_COMPARE (h->ifunc_tls (), SENTINEL);
return NULL;
}
static int
do_test (void)
{
void *handle = xdlopen ("tst-ifunc-tls-init-tlsdesc-lib.so",
RTLD_LAZY | RTLD_LOCAL);
struct ifunc_handles h;
h.get_last_seen_sentinel = xdlsym (handle, "get_last_seen_sentinel");
h.fptr = xdlsym (handle, "fptr");
h.ifunc_tls = xdlsym (handle, "ifunc_tls");
TEST_COMPARE (h.get_last_seen_sentinel (), SENTINEL);
TEST_VERIFY (*h.fptr != NULL);
TEST_COMPARE ((*h.fptr) (), SENTINEL);
TEST_COMPARE (h.ifunc_tls (), SENTINEL);
pthread_t consumer = xpthread_create (NULL, ifunc_caller, &h);
xpthread_join (consumer);
xdlclose (handle);
return 0;
}
#include <support/test-driver.c>
+12 -8
View File
@@ -39,6 +39,18 @@ test_tls_ifunc (int (*check_sentinel)(void),
int (*check_fptr)(void),
int (*check_ifunc_tls)(void))
{
/* Force the IFUNC to be resolved before inspecting what the resolver
observed. In a non-PIE executable the references to the IFUNC are
satisfied through a canonical IPLT entry in the executable, which under
lazy binding is resolved on first use rather than during startup
relocation. Calling fptr/ifunc_tls here guarantees the resolver has run
regardless of PIE-ness or binding mode. */
TEST_VERIFY (check_fptr != NULL);
TEST_COMPARE (check_fptr (), SENTINEL);
/* Issue the ifunc directly as well. */
TEST_COMPARE (check_ifunc_tls (), SENTINEL);
/* Primary check: 'get_last_seen_sentinel' returns the value of the DSO's
thread-local 'sentinel' as observed by the resolver at the moment it ran
for the IFUNC reloc that initialised fptr. The getter is a regular
@@ -46,14 +58,6 @@ test_tls_ifunc (int (*check_sentinel)(void),
does NOT go through a COPY relocation that could overwrite the resolver's
write. */
TEST_COMPARE (check_sentinel (), SENTINEL);
/* Secondary check: fptr is set during IFUNC resolver call, then copied into
the exe's. Returns SENTINEL only if the resolver picked impl_ok. */
TEST_VERIFY (check_fptr != NULL);
TEST_COMPARE (check_fptr (), SENTINEL);
/* Sanity check: issue the ifunc. */
TEST_COMPARE (check_ifunc_tls (), SENTINEL);
}
static int
+5 -1
View File
@@ -21,6 +21,8 @@
overwrites counter with MARKER, and the test then reads counter back
through a getter. */
#include <sys/cdefs.h>
#define SENTINEL 0x5A5A1234u
#define MARKER 0x32125A5Au
@@ -34,7 +36,9 @@ impl (void)
return 0;
}
static unsigned int (*resolver (void)) (void)
static typeof (impl) *
__attribute_used__
resolver (void)
{
counter = MARKER;
return impl;
+29
View File
@@ -0,0 +1,29 @@
/* Shared object for the static-dlopen pointer guard test.
Copyright (C) 2026 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
#include <setjmp.h>
static jmp_buf jb;
void (*do_longjmp) (jmp_buf);
void
foo (void)
{
if (setjmp (jb) == 0)
do_longjmp (jb);
}
+51
View File
@@ -0,0 +1,51 @@
/* Test that the pointer guard is propagated to ld.so via static dlopen.
Copyright (C) 2026 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
/* A statically linked program dlopens a shared object; the object's setjmp
uses the just-mapped libc.so's pointer guard while the longjmp below uses
the program's guard. Unless __rtld_static_init propagates the guard to
the loaded loader the two differ, and the setjmp/longjmp round-trip jumps
to a corrupt address and crashes. */
#include <setjmp.h>
#include <support/check.h>
#include <support/xdlfcn.h>
static void
call_longjmp (jmp_buf jb)
{
longjmp (jb, 1);
}
static int
do_test (void)
{
void *h = xdlopen ("tst-ptrguard-static-dlopen-mod.so", RTLD_NOW);
void (*foo) (void) = xdlsym (h, "foo");
void (**do_longjmp) (jmp_buf) = xdlsym (h, "do_longjmp");
*do_longjmp = call_longjmp;
/* foo () sets the jump buffer and calls back into call_longjmp; a
mismatched guard makes the return jump fault. */
foo ();
xdlclose (h);
return 0;
}
#include <support/test-driver.c>
@@ -0,0 +1 @@
cp $B/elf/tst-ptrguard-static-dlopen-mod.so $L/tst-ptrguard-static-dlopen-mod.so
+2 -1
View File
@@ -139,7 +139,8 @@ $(objpfx)test-iconvconfig.out: $(objpfx)iconvconfig
rm -f $$tmp) > $@; \
$(evaluate-test)
$(objpfx)tst-iconv_prog.out: tst-iconv_prog.sh $(objpfx)iconv_prog
$(objpfx)tst-iconv_prog.out: tst-iconv_prog.sh $(objpfx)iconv_prog \
$(gen-locales)
$(BASH) $< $(common-objdir) '$(test-wrapper-env)' \
'$(run-program-env)' '$(rpath-link)' > $@; \
$(evaluate-test)
+4 -2
View File
@@ -144,8 +144,10 @@
if (irreversible == NULL) \
{ \
/* This means we are in call from __gconv_transliterate. In this \
case we are not doing any error recovery ourselves. */ \
result = __gconv_mark_illegal_input (step_data); \
case we are not doing any error recovery ourselves. Do not create \
a persistent error state. If __gconv_transliterate exhausts all \
alternatives, it will call __gconv_mark_illegal_input itself. */ \
result = __GCONV_ILLEGAL_INPUT; \
break; \
} \
\
+20 -10
View File
@@ -29,10 +29,10 @@ LIBPATH=$codir:$codir/iconvdata
# How the start the iconv(1) program. $from is not defined/expanded yet.
ICONV='
$test_wrapper_env $run_program_env
$codir/elf/ld.so --library-path $library_path:$LIBPATH --inhibit-rpath ${from}.so
$codir/iconv/iconv_prog
'
ICONV="$test_wrapper_env $run_program_env $ICONV"
TIMEOUTFACTOR=${TIMEOUTFACTOR:-1}
@@ -220,6 +220,7 @@ testarray=(
"\x00\x00;;INVALID;UTF-8;1"
"\x00\x00;;UTF-8;INVALID;1"
"\xc3\xa9;;UTF-8;ASCII//TRANSLIT;0"
"X\xc2\xbdY;;UTF-8;ASCII//TRANSLIT;0"
)
# Requires $twobyte input, $c flag, $from, and $to to be set; sets $ret
@@ -280,12 +281,21 @@ check_errtest_result ()
fi
}
for testcommand in "${testarray[@]}"; do
twobyte="$(echo "$testcommand" | cut -d";" -f 1)"
c="$(echo "$testcommand" | cut -d";" -f 2)"
from="$(echo "$testcommand" | cut -d";" -f 3)"
to="$(echo "$testcommand" | cut -d";" -f 4)"
eret="$(echo "$testcommand" | cut -d";" -f 5)"
execute_test
check_errtest_result
done
run_test_array ()
{
for testcommand in "${testarray[@]}"; do
twobyte="$(echo "$testcommand" | cut -d";" -f 1)"
c="$(echo "$testcommand" | cut -d";" -f 2)"
from="$(echo "$testcommand" | cut -d";" -f 3)"
to="$(echo "$testcommand" | cut -d";" -f 4)"
eret="$(echo "$testcommand" | cut -d";" -f 5)"
execute_test
check_errtest_result
done
}
echo "info: testing C locale"
run_test_array
echo "info: testing en_US.UTF-8 locale"
run_program_env="$run_program_env LC_ALL=en_US.UTF-8"
run_test_array
+1 -1
View File
@@ -671,7 +671,7 @@ for linking")
/* Helper / base macros for indirect function symbols. */
#define __ifunc_resolver(type_name, name, expr, init, classifier, ...) \
classifier inhibit_stack_protector \
classifier \
__typeof (type_name) *name##_ifunc (__VA_ARGS__) \
{ \
init (); \
+5
View File
@@ -70,6 +70,11 @@ libc_hidden_proto (__libc_res_nameinquery)
extern __typeof (__res_queriesmatch) __libc_res_queriesmatch;
libc_hidden_proto (__libc_res_queriesmatch)
extern const struct res_sym __p_class_syms[];
libresolv_hidden_proto (__p_class_syms)
extern const struct res_sym __p_type_syms[];
libresolv_hidden_proto (__p_type_syms)
/* Variant of res_hnok which operates on binary (but uncompressed) names. */
bool __res_binary_hnok (const unsigned char *dn) attribute_hidden;
-4
View File
@@ -134,10 +134,6 @@ endif
$(inst_sysconfdir)/rpc: etc.rpc $(+force)
$(do-install)
ifeq ($(build-static-nss),yes)
CFLAGS += -DSTATIC_NSS
endif
ifeq ($(have-test-clang),yes)
CFLAGS-tst-deadline.c += -Wno-ignored-attributes
endif
+2 -2
View File
@@ -270,7 +270,7 @@ __wunderflow (FILE *fp)
if (save_for_wbackup (fp, fp->_wide_data->_IO_read_end))
return WEOF;
}
else if (_IO_have_backup (fp))
else if (_IO_have_wbackup (fp))
_IO_free_wbackup_area (fp);
return _IO_UNDERFLOW (fp);
}
@@ -603,6 +603,6 @@ _IO_unsave_wmarkers (FILE *fp)
fp->_markers = NULL;
}
if (_IO_have_backup (fp))
if (_IO_have_wbackup (fp))
_IO_free_wbackup_area (fp);
}
+4 -9
View File
@@ -799,16 +799,11 @@ arena_get2 (size_t size, mstate avoid_arena)
{
if (mp_.arena_max != 0)
narenas_limit = mp_.arena_max;
else if (narenas > mp_.arena_test)
else if (narenas >= mp_.arena_test)
{
int n = __get_nprocs ();
if (n >= 1)
narenas_limit = NARENAS_FROM_NCORES (n);
else
/* We have no information about the system. Assume two
cores. */
narenas_limit = NARENAS_FROM_NCORES (2);
narenas_limit = __get_nprocs ();
if (narenas_limit < mp_.arena_test)
narenas_limit = mp_.arena_test;
}
}
repeat:;
+1 -1
View File
@@ -224,7 +224,7 @@ free_check (void *mem)
}
else
{
_int_free_chunk (&main_arena, p, chunksize (p), 1);
_int_free_merge_chunk (&main_arena, p, chunksize (p));
__libc_lock_unlock (main_arena.mutex);
}
__set_errno (err);
+2
View File
@@ -24,6 +24,8 @@
#include <malloc-size.h>
#include <hugepages.h>
#include <calloc-clear-memory.h>
#include <malloc-api.h>
#include <malloc-ifuncs.h>
/* Called in the parent process before a fork. */
void __malloc_fork_lock_parent (void) attribute_hidden;
+190 -204
View File
@@ -306,7 +306,7 @@ verify (PTRDIFF_MAX <= SIZE_MAX / 2);
/* This is another arbitrary limit, which tunables can change. Each
tcache bin will hold at most this number of chunks. */
# define TCACHE_FILL_COUNT 16
# define TCACHE_FILL_COUNT 32
/* Maximum chunks in tcache bins for tunables. This value must fit the range
of tcache->num_slots[] entries, else they may overflow. */
@@ -459,101 +459,10 @@ static int extra_mmap_prot = 0;
/* ---------- description of public routines ------------ */
#if IS_IN (libc)
/*
malloc(size_t n)
Returns a pointer to a newly allocated chunk of at least n bytes, or null
if no space is available. Additionally, on failure, errno is
set to ENOMEM on ANSI C systems.
If n is zero, malloc returns a minimum-sized chunk. (The minimum
size is 16 bytes on most 32bit systems, and 24 or 32 bytes on 64bit
systems.) On most systems, size_t is an unsigned type, so calls
with negative arguments are interpreted as requests for huge amounts
of space, which will often fail. The maximum supported value of n
differs across systems, but is in all cases less than the maximum
representable value of a size_t.
*/
void *__libc_malloc (size_t);
libc_hidden_proto (__libc_malloc)
static void *__libc_calloc2 (size_t);
static void *__libc_malloc2 (size_t);
/*
free(void* p)
Releases the chunk of memory pointed to by p, that had been previously
allocated using malloc or a related routine such as realloc.
It has no effect if p is null. It can have arbitrary (i.e., bad!)
effects if p has already been freed.
Unless disabled (using mallopt), freeing very large spaces will
when possible, automatically trigger operations that give
back unused memory to the system, thus reducing program footprint.
*/
void __libc_free(void*);
libc_hidden_proto (__libc_free)
/*
calloc(size_t n_elements, size_t element_size);
Returns a pointer to n_elements * element_size bytes, with all locations
set to zero.
*/
void* __libc_calloc(size_t, size_t);
/*
realloc(void* p, size_t n)
Returns a pointer to a chunk of size n that contains the same data
as does chunk p up to the minimum of (n, p's size) bytes, or null
if no space is available.
The returned pointer may or may not be the same as p. The algorithm
prefers extending p when possible, otherwise it employs the
equivalent of a malloc-copy-free sequence.
If p is null, realloc is equivalent to malloc.
If space is not available, realloc returns null, errno is set (if on
ANSI) and p is NOT freed.
if n is for fewer bytes than already held by p, the newly unused
space is lopped off and freed if possible. Unless the #define
REALLOC_ZERO_BYTES_FREES is set, realloc with a size argument of
zero (re)allocates a minimum-sized chunk.
Large chunks that were internally obtained via mmap will always be
grown using malloc-copy-free sequences unless the system supports
MREMAP (currently only linux).
The old unix realloc convention of allowing the last-free'd chunk
to be used as an argument to realloc is not supported.
*/
void* __libc_realloc(void*, size_t);
libc_hidden_proto (__libc_realloc)
/*
memalign(size_t alignment, size_t n);
Returns a pointer to a newly allocated chunk of n bytes, aligned
in accord with the alignment argument.
The alignment argument should be a power of two. If the argument is
not a power of two, the nearest greater power is used.
8-byte alignment is guaranteed by normal malloc calls, so don't
bother calling memalign with an argument of 8 or less.
Overreliance on memalign is a sure way to fragment space.
*/
void* __libc_memalign(size_t, size_t);
libc_hidden_proto (__libc_memalign)
/*
valloc(size_t n);
Equivalent to memalign(pagesize, n), where pagesize is the page
size of the system. If the pagesize is unknown, 4096 is used.
*/
void* __libc_valloc(size_t);
/*
mallinfo()
Returns (by copy) a struct containing various summary statistics:
@@ -578,14 +487,6 @@ libc_hidden_proto (__libc_mallinfo2)
struct mallinfo __libc_mallinfo(void);
/*
pvalloc(size_t n);
Equivalent to valloc(minimum-page-that-holds(n)), that is,
round up n to nearest pagesize.
*/
void* __libc_pvalloc(size_t);
/*
malloc_trim(size_t pad);
@@ -612,23 +513,6 @@ void* __libc_pvalloc(size_t);
*/
int __malloc_trim(size_t);
/*
malloc_usable_size(void* p);
Returns the number of bytes you can actually use in
an allocated chunk, which may be more than you requested (although
often not) due to alignment and minimum size constraints.
You can use this many bytes without worrying about
overwriting other allocated objects. This is not a particularly great
programming practice. malloc_usable_size can be more useful in
debugging and assertions, for example:
p = malloc(n);
assert(malloc_usable_size(p) >= 256);
*/
size_t __malloc_usable_size(void*);
/*
malloc_stats();
Prints on stderr the amount of space obtained from the system (both
@@ -651,12 +535,6 @@ size_t __malloc_usable_size(void*);
*/
void __malloc_stats(void);
/*
posix_memalign(void **memptr, size_t alignment, size_t size);
POSIX wrapper like memalign(), checking for validity of size.
*/
int __posix_memalign(void **, size_t, size_t);
#endif /* IS_IN (libc) */
/*
@@ -931,7 +809,7 @@ typedef struct malloc_chunk* mchunkptr;
/* Internal routines. */
static void* _int_malloc(mstate, size_t);
static void _int_free_chunk (mstate, mchunkptr, INTERNAL_SIZE_T, int);
static void _int_free_chunk (mstate, mchunkptr, INTERNAL_SIZE_T);
static void _int_free_merge_chunk (mstate, mchunkptr, INTERNAL_SIZE_T);
static INTERNAL_SIZE_T _int_free_create_chunk (mstate,
mchunkptr, INTERNAL_SIZE_T,
@@ -1126,24 +1004,19 @@ nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
#define misaligned_chunk(p) (misaligned_mem( chunk2mem (p)))
/* pad request bytes into a usable size -- internal version */
/* Note: This must be a macro that evaluates to a compile time constant
if passed a literal constant. */
#define request2size(req) \
(((req) + SIZE_SZ + MALLOC_ALIGN_MASK < MINSIZE) ? \
MINSIZE : \
((req) + SIZE_SZ + MALLOC_ALIGN_MASK) & ~MALLOC_ALIGN_MASK)
/* Check if REQ overflows when padded and aligned and if the resulting
value is less than PTRDIFF_T. Returns the requested size or
MINSIZE in case the value is less than MINSIZE, or SIZE_MAX if any
of the previous checks fail. */
static __always_inline size_t
checked_request2size (size_t req) __nonnull (1)
checked_request2size (size_t req)
{
if (__glibc_unlikely (req > PTRDIFF_MAX))
return SIZE_MAX;
return request2size (req);
return (req + SIZE_SZ + MALLOC_ALIGN_MASK < MINSIZE
? MINSIZE
: (req + SIZE_SZ + MALLOC_ALIGN_MASK) & ~MALLOC_ALIGN_MASK);
}
/*
@@ -1655,9 +1528,8 @@ static struct malloc_par mp_ =
.n_mmaps_max = DEFAULT_MMAP_MAX,
.mmap_threshold = DEFAULT_MMAP_THRESHOLD,
.trim_threshold = DEFAULT_TRIM_THRESHOLD,
#define NARENAS_FROM_NCORES(n) ((n) * (sizeof (long) == 4 ? 2 : 8))
.arena_test = NARENAS_FROM_NCORES (1),
.thp_mode = thp_mode_not_supported
.arena_test = sizeof (long) == 4 ? 2 : 8,
.thp_mode = thp_mode_unknown
#if USE_TCACHE
,
.tcache_count = TCACHE_FILL_COUNT,
@@ -2246,7 +2118,7 @@ sysmalloc (INTERNAL_SIZE_T nb, mstate av)
CHUNK_HDR_SZ | PREV_INUSE);
set_foot (chunk_at_offset (old_top, old_size), CHUNK_HDR_SZ);
set_head (old_top, old_size | PREV_INUSE | NON_MAIN_ARENA);
_int_free_chunk (av, old_top, chunksize (old_top), 1);
_int_free_merge_chunk (av, old_top, chunksize (old_top));
}
else
{
@@ -2517,7 +2389,7 @@ sysmalloc (INTERNAL_SIZE_T nb, mstate av)
/* If possible, release the rest. */
if (old_size >= MINSIZE)
{
_int_free_chunk (av, old_top, chunksize (old_top), 1);
_int_free_merge_chunk (av, old_top, chunksize (old_top));
}
}
}
@@ -2847,7 +2719,8 @@ tcache_put_n (mchunkptr chunk, size_t tc_idx, tcache_entry **ep, bool mangled)
available chunks to remove. Removes chunk from the middle of the
list. */
static __always_inline void *
tcache_get_n (size_t tc_idx, tcache_entry **ep, bool mangled)
tcache_get_n (tcache_perthread_struct *tc, size_t tc_idx, tcache_entry **ep,
bool mangled)
{
tcache_entry *e;
if (!mangled)
@@ -2863,7 +2736,7 @@ tcache_get_n (size_t tc_idx, tcache_entry **ep, bool mangled)
else
*ep = PROTECT_PTR (ep, REVEAL_PTR (e->next));
++(tcache->num_slots[tc_idx]);
++(tc->num_slots[tc_idx]);
e->key = 0;
return (void *) e;
}
@@ -2878,7 +2751,7 @@ tcache_put (mchunkptr chunk, size_t tc_idx)
static __always_inline void *
tcache_get (size_t tc_idx)
{
return tcache_get_n (tc_idx, &tcache->entries[tc_idx], false);
return tcache_get_n (tcache, tc_idx, &tcache->entries[tc_idx], false);
}
static __always_inline tcache_entry **
@@ -2921,7 +2794,7 @@ tcache_get_large (size_t tc_idx, size_t nb)
if (te == NULL || nb != chunksize (mem2chunk (te)))
return NULL;
return tcache_get_n (tc_idx, entry, mangled);
return tcache_get_n (tcache, tc_idx, entry, mangled);
}
static void tcache_init (mstate av);
@@ -2954,7 +2827,7 @@ tcache_get_align (size_t nb, size_t alignment)
if (te != NULL
&& csize == nb
&& PTR_IS_ALIGNED (te, alignment))
return tcache_get_n (tc_idx, tep, mangled);
return tcache_get_n (tcache, tc_idx, tep, mangled);
}
return NULL;
}
@@ -3014,12 +2887,12 @@ tcache_thread_shutdown (void)
tcache_tmp->entries[i] = REVEAL_PTR (e->next);
e->key = 0;
p = mem2chunk (e);
_int_free_chunk (arena_for_chunk (p), p, chunksize (p), 0);
_int_free_chunk (arena_for_chunk (p), p, chunksize (p));
}
}
p = mem2chunk (tcache_tmp);
_int_free_chunk (arena_for_chunk (p), p, chunksize (p), 0);
_int_free_chunk (arena_for_chunk (p), p, chunksize (p));
}
/* Initialize tcache. In the rare case there isn't any memory available,
@@ -3035,7 +2908,7 @@ tcache_init (mstate av)
size_t bytes = sizeof (tcache_perthread_struct);
if (av)
tcache =
(tcache_perthread_struct *) _int_malloc (av, request2size (bytes));
(tcache_perthread_struct *) _int_malloc (av, bytes);
else
tcache = (tcache_perthread_struct *) __libc_malloc2 (bytes);
@@ -3134,6 +3007,62 @@ tcache_free_init (void *mem)
__libc_free (mem);
}
/* If the arena does not change between chunks, keep the lock. */
static inline void
__libc_free_batched_loop (bool do_lock, mstate av, mchunkptr p, INTERNAL_SIZE_T size,
tcache_perthread_struct *tc, size_t tc_idx)
{
/* Empty half of the tcache, for a hysteresis effect. */
unsigned int to_free = mp_.tcache_count / 2;
if (do_lock)
__libc_lock_lock (av->mutex);
_int_free_merge_chunk (av, p, size);
while (tc->entries[tc_idx] != NULL && to_free > 0)
{
void *mem = tcache_get_n (tc, tc_idx, &tc->entries[tc_idx], false);
p = mem2chunk (mem);
size = chunksize (p);
/* Lock a different arena if necessary. */
if (do_lock)
{
mstate chunk_av = arena_for_chunk (p);
if (chunk_av != av)
{
__libc_lock_unlock (av->mutex);
av = chunk_av;
__libc_lock_lock (av->mutex);
}
}
_int_free_merge_chunk (av, p, size);
to_free--;
}
if (do_lock)
__libc_lock_unlock (av->mutex);
}
/* Deallocate half of the tcache entries into arenas, to amortize the
locking overhead. */
static __attribute_noinline__ void
__libc_free_batched (mchunkptr p, INTERNAL_SIZE_T size,
tcache_perthread_struct *tc, size_t tc_idx)
{
/* Check size >= MINSIZE and p + size does not overflow. */
if (__glibc_unlikely (INT_ADD_OVERFLOW ((uintptr_t) p,
size - MINSIZE)))
return malloc_printerr_tail ("free(): invalid size (batch)");
if (SINGLE_THREAD_P)
__libc_free_batched_loop (false, &main_arena, p, size, tc, tc_idx);
else
__libc_free_batched_loop (true, arena_for_chunk (p), p, size, tc, tc_idx);
}
void
__libc_free (void *mem)
{
@@ -3164,6 +3093,13 @@ __libc_free (void *mem)
{
if (__glibc_likely (tcache->num_slots[tc_idx] != 0))
return tcache_put (p, tc_idx);
else
{
/* Perform batched freeing of tcache entries. */
if (__glibc_unlikely (tcache_inactive ()))
return tcache_free_init (mem);
return __libc_free_batched (p, size, tcache, tc_idx);
}
}
else
{
@@ -3171,10 +3107,9 @@ __libc_free (void *mem)
if (size >= MINSIZE
&& __glibc_likely (tcache->num_slots[tc_idx] != 0))
return tcache_put_large (p, tc_idx);
if (__glibc_unlikely (tcache_inactive ()))
return tcache_free_init (mem);
}
if (__glibc_unlikely (tcache_inactive ()))
return tcache_free_init (mem);
}
#endif
@@ -3183,7 +3118,7 @@ __libc_free (void *mem)
size - MINSIZE)))
return malloc_printerr_tail ("free(): invalid size");
_int_free_chunk (arena_for_chunk (p), p, size, 0);
_int_free_chunk (arena_for_chunk (p), p, size);
}
libc_hidden_def (__libc_free)
@@ -3290,7 +3225,7 @@ __libc_realloc (void *oldmem, size_t bytes)
if (newp != NULL)
{
memcpy (newp, oldmem, memsize (oldp));
_int_free_chunk (ar_ptr, oldp, chunksize (oldp), 0);
_int_free_chunk (ar_ptr, oldp, chunksize (oldp));
}
}
@@ -3318,10 +3253,8 @@ __libc_memalign (size_t alignment, size_t bytes)
}
libc_hidden_def (__libc_memalign)
/* For ISO C17. */
void *
weak_function
aligned_alloc (size_t alignment, size_t bytes)
__aligned_alloc (size_t alignment, size_t bytes)
{
/* Starting with ISO C17 the standard requires an error for alignments
that are not supported. Only integral powers of 2 are valid. */
@@ -3333,11 +3266,10 @@ aligned_alloc (size_t alignment, size_t bytes)
return _mid_memalign (alignment, bytes);
}
libc_hidden_def (__aligned_alloc)
/* For ISO C23. */
void
weak_function
free_sized (void *ptr, __attribute_maybe_unused__ size_t size)
__free_sized (void *ptr, __attribute_maybe_unused__ size_t size)
{
/* We do not perform validation that size is the same as the original
requested size at this time. We leave that to the sanitizers. We
@@ -3346,11 +3278,10 @@ free_sized (void *ptr, __attribute_maybe_unused__ size_t size)
free (ptr);
}
libc_hidden_def (__free_sized)
/* For ISO C23. */
void
weak_function
free_aligned_sized (void *ptr, __attribute_maybe_unused__ size_t alignment,
__free_aligned_sized (void *ptr, __attribute_maybe_unused__ size_t alignment,
__attribute_maybe_unused__ size_t size)
{
/* We do not perform validation that size and alignment is the same as
@@ -3360,6 +3291,7 @@ free_aligned_sized (void *ptr, __attribute_maybe_unused__ size_t alignment,
free (ptr);
}
libc_hidden_def (__free_aligned_sized)
static void *
_mid_memalign (size_t alignment, size_t bytes)
@@ -3408,6 +3340,7 @@ __libc_valloc (size_t bytes)
{
return _mid_memalign (GLRO (dl_pagesize), bytes);
}
libc_hidden_def (__libc_valloc)
void *
__libc_pvalloc (size_t bytes)
@@ -3425,6 +3358,7 @@ __libc_pvalloc (size_t bytes)
return _mid_memalign (pagesize, rounded_bytes & -pagesize);
}
libc_hidden_def (__libc_pvalloc)
static void * __attribute_noinline__
__libc_calloc2 (size_t sz)
@@ -3433,7 +3367,6 @@ __libc_calloc2 (size_t sz)
mchunkptr oldtop, p;
INTERNAL_SIZE_T oldtopsize, csz;
void *mem;
unsigned long clearsize;
if (SINGLE_THREAD_P)
av = &main_arena;
@@ -3510,8 +3443,7 @@ __libc_calloc2 (size_t sz)
}
#endif
clearsize = csz - SIZE_SZ;
return clear_memory ((INTERNAL_SIZE_T *) mem, clearsize);
return clear_memory (mem, csz - SIZE_SZ);
}
void *
@@ -3532,16 +3464,13 @@ __libc_calloc (size_t n, size_t elem_size)
{
size_t tc_idx = csize2tidx (nb);
if (__glibc_unlikely (tc_idx < TCACHE_SMALL_BINS))
{
if (__glibc_likely (tc_idx < TCACHE_SMALL_BINS))
{
if (tcache->entries[tc_idx] != NULL)
{
void *mem = tcache_get (tc_idx);
return clear_memory ((INTERNAL_SIZE_T *) mem, tidx2usize (tc_idx));
}
return clear_memory (tcache_get (tc_idx), tidx2usize (tc_idx));
}
else
{
{
tc_idx = large_csize2tidx (nb);
void *mem = tcache_get_large (tc_idx, nb);
if (mem != NULL)
@@ -3551,6 +3480,7 @@ __libc_calloc (size_t n, size_t elem_size)
#endif
return __libc_calloc2 (bytes);
}
libc_hidden_def (__libc_calloc)
#endif /* IS_IN (libc) */
/*
@@ -3640,8 +3570,11 @@ _int_malloc (mstate av, size_t bytes)
if (__glibc_unlikely (tcache_inactive ()))
tcache_init (av);
/* While bin not empty and tcache not full, copy chunks over. */
while (tcache->num_slots[tc_idx] != 0
/* While bin not empty and tcache not full, copy chunks over.
Only fill half of the tcache, so that subsequent frees
do not immediately flush the tcache. */
unsigned int tcache_target_count = mp_.tcache_count / 2;
while (tcache->num_slots[tc_idx] > tcache_target_count
&& (tc_victim = last (bin)) != bin)
{
if (tc_victim != NULL)
@@ -4057,11 +3990,10 @@ _int_malloc (mstate av, size_t bytes)
------------------------------ free ------------------------------
*/
/* Free chunk P of SIZE bytes to the arena. HAVE_LOCK indicates where
the arena for P has already been locked. Caller must ensure chunk
and size are valid. */
static void
_int_free_chunk (mstate av, mchunkptr p, INTERNAL_SIZE_T size, int have_lock)
/* Free chunk P of SIZE bytes to the arena AV (which is not locked).
Caller must ensure chunk and size are valid. */
static __attribute_maybe_unused__ void
_int_free_chunk (mstate av, mchunkptr p, INTERNAL_SIZE_T size)
{
/*
Consolidate other non-mmapped chunks as they arrive.
@@ -4069,22 +4001,14 @@ _int_free_chunk (mstate av, mchunkptr p, INTERNAL_SIZE_T size, int have_lock)
if (!chunk_is_mmapped(p)) {
/* Preserve errno in case block merging results in munmap. */
int err = errno;
/* If we're single-threaded, don't lock the arena. */
if (SINGLE_THREAD_P)
have_lock = true;
if (!have_lock)
__libc_lock_lock (av->mutex);
_int_free_merge_chunk (av, p, size);
if (!have_lock)
__libc_lock_unlock (av->mutex);
__set_errno (err);
_int_free_merge_chunk (av, p, size);
else
{
__libc_lock_lock (av->mutex);
_int_free_merge_chunk (av, p, size);
__libc_lock_unlock (av->mutex);
}
}
/*
If the chunk was allocated via mmap, release via munmap().
@@ -4101,8 +4025,8 @@ _int_free_chunk (mstate av, mchunkptr p, INTERNAL_SIZE_T size, int have_lock)
}
}
/* Try to merge chunk P of SIZE bytes with its neighbors. Put the
resulting chunk on the appropriate bin list. P must not be on a
/* Try to merge chunk P of SIZE bytes from locked arena AV with its neighbors.
Put the resulting chunk on the appropriate bin list. P must not be on a
bin list yet, and it can be in use. */
static void
_int_free_merge_chunk (mstate av, mchunkptr p, INTERNAL_SIZE_T size)
@@ -4232,6 +4156,9 @@ _int_free_maybe_trim (mstate av, INTERNAL_SIZE_T size)
if ATTEMPT_TRIMMING_THRESHOLD is reached. */
if (size >= ATTEMPT_TRIMMING_THRESHOLD)
{
/* Preserve errno. */
int err = errno;
if (av == &main_arena)
{
#ifndef MORECORE_CANNOT_TRIM
@@ -4248,6 +4175,8 @@ _int_free_maybe_trim (mstate av, INTERNAL_SIZE_T size)
assert (heap->ar_ptr == av);
heap_trim (heap, mp_.top_pad);
}
__set_errno (err);
}
}
@@ -4338,7 +4267,7 @@ _int_realloc (mstate av, mchunkptr oldp, INTERNAL_SIZE_T oldsize,
{
void *oldmem = chunk2mem (oldp);
memcpy (newmem, oldmem, memsize (oldp));
_int_free_chunk (av, oldp, chunksize (oldp), 1);
_int_free_merge_chunk (av, oldp, chunksize (oldp));
check_inuse_chunk (av, newp);
return newmem;
}
@@ -4364,7 +4293,7 @@ _int_realloc (mstate av, mchunkptr oldp, INTERNAL_SIZE_T oldsize,
(av != &main_arena ? NON_MAIN_ARENA : 0));
/* Mark remainder as inuse so free() won't complain */
set_inuse_bit_at_offset (remainder, remainder_size);
_int_free_chunk (av, remainder, chunksize (remainder), 1);
_int_free_merge_chunk (av, remainder, chunksize (remainder));
}
check_inuse_chunk (av, newp);
@@ -4547,6 +4476,7 @@ __malloc_usable_size (void *m)
return 0;
return musable (m);
}
libc_hidden_def (__malloc_usable_size)
#endif /* IS_IN (libc) */
/*
@@ -4754,7 +4684,7 @@ do_set_tcache_max (size_t value)
if (value > PTRDIFF_MAX)
return 0;
size_t nb = request2size (value);
size_t nb = checked_request2size (value);
size_t tc_idx = csize2tidx (nb);
if (tc_idx >= TCACHE_SMALL_BINS)
@@ -4793,13 +4723,41 @@ do_set_mxfast (size_t value)
return 1;
}
#ifdef HAVE_THP
static __always_inline enum thp_mode_t
get_dl_thp_mode (void)
{
return GL(dl_thp_mode);
}
static __always_inline unsigned long int
get_dl_elf_thp_pagesize (void)
{
return GL(dl_elf_thp_pagesize);
}
#else
# define get_dl_thp_mode() __get_thp_mode ()
# define get_dl_elf_thp_pagesize() __get_thp_size ()
#endif
static __always_inline int
do_set_hugetlb (size_t value)
{
/* If __get_thp_mode and __get_thp_size have been called during
startup, don't call them again here. */
enum thp_mode_t thp_mode = get_dl_thp_mode ();
/* Enable THP if MALLOC_DEFAULT_THP_PAGESIZE is non-zero. */
if (MALLOC_DEFAULT_THP_PAGESIZE > 0)
{
mp_.thp_mode = thp_mode_madvise;
/* If thp_mode is unknown, THP segment load is disabled by
GLIBC_TUNABLES=glibc.elf.thp=0. In this case, set
mp_.thp_mode to madvise. Otherwise, set it to thp_mode to
keep mp_.thp_mode in sync with GL(dl_thp_mode). */
if (thp_mode == thp_mode_unknown)
mp_.thp_mode = thp_mode_madvise;
else
mp_.thp_mode = thp_mode;
mp_.thp_pagesize = MALLOC_DEFAULT_THP_PAGESIZE;
}
@@ -4816,9 +4774,27 @@ do_set_hugetlb (size_t value)
if (MALLOC_DEFAULT_THP_PAGESIZE > 0)
return 0;
mp_.thp_mode = __get_thp_mode ();
if (mp_.thp_mode == thp_mode_madvise || mp_.thp_mode == thp_mode_always)
mp_.thp_pagesize = __get_thp_size ();
if (thp_mode == thp_mode_unknown)
{
/* Call __get_thp_mode and __get_thp_size when THP segment load
is disabled. */
mp_.thp_mode = __get_thp_mode ();
if (mp_.thp_mode == thp_mode_madvise
|| mp_.thp_mode == thp_mode_always)
mp_.thp_pagesize = __get_thp_size ();
}
else
{
/* THP segment load is enabled. GL(dl_elf_thp_pagesize) is
set to DL_MAP_DEFAULT_THP_PAGESIZE if it isn't zero. In
this case, call get_capped_thp_size () instead of using
DL_MAP_DEFAULT_THP_PAGESIZE for malloc. */
mp_.thp_mode = thp_mode;
if (DL_MAP_DEFAULT_THP_PAGESIZE != 0)
mp_.thp_pagesize = get_capped_thp_size ();
else
mp_.thp_pagesize = get_dl_elf_thp_pagesize ();
}
}
else if (value >= 2)
__get_hugepage_config (value == 2 ? 0 : value, &mp_.hp_pagesize,
@@ -5074,6 +5050,7 @@ __posix_memalign (void **memptr, size_t alignment, size_t size)
*memptr = mem;
return 0;
}
libc_hidden_def (__posix_memalign)
#endif /* IS_IN (libc) */
@@ -5236,6 +5213,9 @@ __malloc_info (int options, FILE *fp)
}
#if IS_IN (libc)
/* See sysdeps/generic/malloc-ifuncs.h for details. */
# if !USE_MULTIARCH_MALLOC
strong_alias (__libc_malloc, malloc)
strong_alias (__libc_realloc, realloc)
strong_alias (__libc_free, free)
@@ -5245,6 +5225,10 @@ weak_alias (__posix_memalign, posix_memalign)
weak_alias (__libc_valloc, valloc)
weak_alias (__libc_pvalloc, pvalloc)
weak_alias (__malloc_usable_size, malloc_usable_size)
weak_alias (__aligned_alloc, aligned_alloc)
weak_alias (__free_sized, free_sized)
weak_alias (__free_aligned_sized, free_aligned_sized)
#endif /* !USE_MULTIARCH_MALLOC */
weak_alias (__malloc_info, malloc_info)
weak_alias (__libc_mallinfo, mallinfo)
@@ -5254,9 +5238,11 @@ weak_alias (__malloc_stats, malloc_stats)
weak_alias (__malloc_trim, malloc_trim)
#endif /* IS_IN (libc) */
#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_26)
#if !USE_MULTIARCH_MALLOC
# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_26)
compat_symbol (libc, __libc_free, cfree, GLIBC_2_0);
#endif
# endif
#endif /* !USE_MULTIARCH_MALLOC */
/* ------------------------------------------------------------
History:
+1 -1
View File
@@ -310,7 +310,7 @@ int
do_test (void)
{
/* Limit the number of malloc arenas. We use a very low number so
that despute the address space limit configured below, all
that despite the address space limit configured below, all
requested arenas a can be created. */
if (mallopt (M_ARENA_MAX, 2) == 0)
{
+6 -3
View File
@@ -1842,7 +1842,8 @@ two things: either all bytes from the input buffer are consumed or
there are some bytes at the end of the buffer that possibly can form a
complete character but the input is incomplete. The second reason for a
stop is that the output buffer is full. And the third reason is that
the input contains invalid characters.
the input contains invalid characters or translation to the character
encoding of the output is not possible.
In all of these cases the buffer pointers after the last successful
conversion, for the input and output buffers, are stored in @var{inbuf} and
@@ -1866,9 +1867,11 @@ the value pointed to by @var{inbytesleft} is nonzero.
@table @code
@item EILSEQ
The conversion stopped because of an invalid byte sequence in the input.
The conversion stopped because of an invalid byte sequence in the
input or because translation of the byte sequence to the character
encoding of the output is not possible.
After the call, @code{*@var{inbuf}} points at the first byte of the
invalid byte sequence.
byte sequence which caused the error.
@item E2BIG
The conversion stopped because it ran out of space in the output buffer.
+300 -3
View File
@@ -17,6 +17,7 @@ Dynamic linkers are sometimes called @dfn{dynamic loaders}.
* Dynamic Linker Environment Variables:: Environment variables that control the
dynamic linker.
* Dynamic Linker Introspection:: Interfaces for querying mapping information.
* Indirect Functions:: Selecting function implementations at load time.
* Dynamic Linker Hardening:: Avoiding unexpected issues with dynamic linking.
@end menu
@@ -735,6 +736,299 @@ A bit mask used to signal that the object contains SFrame data. See
@end table
@node Indirect Functions
@section Indirect Functions
@cindex indirect function
@cindex IFUNC
@cindex @code{STT_GNU_IFUNC}
@cindex resolver function (IFUNC)
@dfn{Indirect functions} (often called @dfn{IFUNCs}) are a GNU
extension to ELF that defers the selection of a function
implementation until load time. A symbol of type
@code{STT_GNU_IFUNC} does not designate the implementation of a
function. Instead, it designates a @dfn{resolver function}.
@Theglibc{} invokes the resolver while processing relocations that
reference the symbol, and the address returned by the resolver becomes
the target of those references. The typical use of indirect functions
is to select the variant of a function best suited to the system the
program is running on, for example based on the available instruction
set extensions.
Indirect functions are usually defined using the @code{ifunc} function
attribute provided by GCC and compatible compilers:
@smallexample
static int
my_func_generic (int a)
@{
/* @r{@dots{}} */
@}
static int
my_func_vectorized (int a)
@{
/* @r{@dots{}} */
@}
/* @r{The resolver returns the address of the selected
implementation.} */
static typeof (my_func_generic) *
my_func_resolver (void)
@{
if (vector_extension_available ())
return my_func_vectorized;
return my_func_generic;
@}
int my_func (int a) __attribute__ ((ifunc ("my_func_resolver")));
@end smallexample
@subsection IFUNC Resolver Calling Conventions
The return value is the address of the selected implementation.
On many architectures, the resolver receives arguments that describe
the capabilities of the system, typically derived from the @code{AT_HWCAP}
value in the auxiliary vector (@pxref{Auxiliary Vector}). These arguments
exist because of the restricted environment resolvers run in (see below):
they allow a resolver to select an implementation without having to obtain
the information through other means. Where such arguments are available,
resolvers should use them instead of querying the system through
function calls.
The architecture-specific conventions are:
@table @asis
@item AArch64
@smallexample
#include <sys/ifunc.h>
void *resolver (uint64_t hwcap, const __ifunc_arg_t *arg);
@end smallexample
The first argument contains the @code{AT_HWCAP} value. If the
@code{_IFUNC_ARG_HWCAP} bit is set, the second argument is valid and
points to a @code{__ifunc_arg_t} structure that provides access to all
hardware capability values: the @code{_size} member contains the size of
the structure in bytes, and the @code{_hwcap}, @code{_hwcap2},
@code{_hwcap3}, and @code{_hwcap4} members contain the
@code{AT_HWCAP}, @code{AT_HWCAP2}, @code{AT_HWCAP3}, and
@code{AT_HWCAP4} values, respectively. Resolvers must check
@code{_size} before accessing a member, because @theglibc{} may pass
a structure that ends before that member. The @code{__ifunc_hwcap}
inline function in @file{sys/ifunc.h} performs the required checks
when obtaining a hardware capability value by index.
The canonical documentation for this interface is the
@cite{GNU C Library ifunc interface} section of the @cite{ELF for the
Arm 64-bit Architecture (AArch64)} ABI, available at
@uref{https://github.com/ARM-software/abi-aa/blob/main/sysvabi64/sysvabi64.rst}.
@item Arm
@smallexample
void *resolver (unsigned long int hwcap);
@end smallexample
The argument contains the @code{AT_HWCAP} value.
@item LoongArch
@smallexample
#include <sys/ifunc.h>
void *resolver (const __ifunc_arg_t *arg);
@end smallexample
The argument points to a @code{__ifunc_arg_t} structure whose
@code{_size} member contains the size of the structure in bytes and
whose @code{_hwcap} member contains the @code{AT_HWCAP} value. Resolvers
must check @code{_size} before accessing members added by later versions
of the structure.
@item PowerPC (32-bit and 64-bit)
@smallexample
void *resolver (unsigned long int hwcap);
@end smallexample
The argument contains the @code{AT_HWCAP} value. The
@code{AT_HWCAP2} value is not passed as an argument.
@item RISC-V
@smallexample
#include <sys/hwprobe.h>
void *resolver (uint64_t hwcap, __riscv_hwprobe_t hwprobe,
void *reserved);
@end smallexample
The first argument contains the @code{AT_HWCAP} value. The second
argument is a pointer to the @code{__riscv_hwprobe} function
(@pxref{RISC-V}), passed so that the resolver can probe for extensions
without referencing a symbol in another object. Versions of
@theglibc{} before 2.40 pass a null pointer here, so resolvers must
check the argument before calling it; the @code{__riscv_hwprobe_one}
inline function in @file{sys/hwprobe.h} performs this check. The
third argument is reserved for future extension.
@item s390 (64-bit)
@smallexample
void *resolver (unsigned long int hwcap);
@end smallexample
The argument contains the @code{AT_HWCAP} value.
@item SPARC (32-bit and 64-bit)
@smallexample
void *resolver (int hwcap);
@end smallexample
The argument contains the @code{AT_HWCAP} value.
@item x86 (i386 and x86-64)
@smallexample
void *resolver (void);
@end smallexample
No arguments are passed: on x86 the @code{CPUID} instruction can be
executed directly from the resolver instead. Resolvers can use the
@code{__cpuid} and @code{__cpuid_count} macros from the GCC
@file{cpuid.h} header.
Alternatively, the @code{CPU_FEATURE_PRESENT} and
@code{CPU_FEATURE_ACTIVE} macros from @file{sys/platform/x86.h}
(@pxref{X86}) can be used; the data they consult is initialized by
@theglibc{} before any resolver runs.
@end table
@subsection When IFUNC Resolvers Run
Resolver functions run early, before the process or the newly loaded
objects are fully initialized. The exact point at which a resolver
runs depends on how the indirect function is referenced and how the
program is linked:
@itemize @bullet
@item
In dynamically linked programs, resolvers for non-lazy references run
during relocation processing at program startup, before ELF
constructors and before @code{main}. Non-lazy references include data
relocations against the function address (for example, initialized
function pointer variables), and all references if lazy binding is
disabled (for example, with the @option{-z now} link-time option or
the @env{LD_BIND_NOW} environment variable).
@item
With lazy binding, the resolver for a function call through the PLT
may not run until the function is called for the first time. Programs
should not depend on whether a resolver runs at load time or at the
time of the first call.
@item
For objects loaded with @code{dlopen}, resolvers run during the
relocation of the newly loaded objects, before their ELF constructors
run.
@item
In statically linked programs (including static PIE), resolvers are
invoked by the startup code in @theglibc{}, before ELF constructors
and before @code{main}.
@end itemize
A resolver can be invoked more than once: in general, it runs once for
every relocation that references the indirect function symbol, and
distinct objects referencing the same symbol cause separate resolver
invocations. Under lazy binding, resolver invocations can also happen
concurrently on multiple threads. Resolvers must therefore be
idempotent: they should return the same implementation on every
invocation and avoid side effects.
@subsection Supported Functionality in IFUNC Resolvers
Because resolvers run during relocation processing, only a restricted
execution environment is available to them. @Theglibc{} provides the
guarantees listed below, each annotated with the version of @theglibc{}
from which it applies. Versions before 2.44 provided none of them:
resolvers could run before thread-local storage, the TCB, and the stack
protector were initialized, and before the relocations of other objects
had been processed. A resolver that must remain compatible with those
versions should not rely on any of these guarantees, and should restrict
itself to the architecture-provided resolver arguments and to data
defined in the same translation unit.
@itemize @bullet
@item
The thread control block (TCB) of the initial thread is set up before
any resolver runs. This applies to dynamically linked programs and to
statically linked programs (including static PIE). Consequently,
resolvers may be compiled with stack protector instrumentation
(@option{-fstack-protector} and its variants): the stack canary is
initialized before the first resolver runs. (Since @theglibc{} 2.44.)
@item
Tunables (@pxref{Tunables}) and the architecture-specific CPU feature
detection used by @theglibc{} are processed before any resolver runs.
A resolver that selects an implementation based on @theglibc{}'s CPU
feature data therefore observes values that already reflect any tunable
that masks hardware capabilities, such as @code{glibc.cpu.hwcaps}
(@pxref{Hardware Capability Tunables}). (Since @theglibc{} 2.44.)
@item
A resolver may read from and write to thread-local variables
(@code{__thread}, @code{_Thread_local}) defined by the same object
that defines the resolver, using any TLS access model. The initial
values of such variables are visible to the resolver, and stores
performed by the resolver persist after it returns. This applies to
objects loaded at process startup, to objects loaded with
@code{dlopen}, and to statically linked programs. (Since @theglibc{}
2.44.)
@item
At program startup, the regular (non-IFUNC) relocations of all
initially loaded objects are processed before any resolver runs. A
resolver may therefore reference data and call functions defined in
other initially loaded objects. (Since @theglibc{} 2.44.)
@item
During @code{dlopen}, newly loaded objects are relocated after their
dependencies. A resolver in a newly loaded object may reference data
and call functions defined by the object itself, by its dependencies
(direct and indirect), and by objects that were already loaded before
the @code{dlopen} call. (Since @theglibc{} 2.44.)
@end itemize
@Theglibc{} itself defines indirect functions and the guarantees above
apply to these internal resolvers as well.
Everything not listed above should be considered unsupported. In
particular, the following restrictions apply:
@itemize @bullet
@item
ELF constructors of the objects being loaded have not run when their
resolvers are invoked. Resolvers must not depend on any initialization
performed by constructors, such as the construction of C++ global objects,
even in other objects whose relocations have already been processed.
@item
Accessing thread-local variables defined by other objects is not
supported.
@item
Functions that depend on a fully initialized @theglibc{}, or that may
call back into the dynamic linker, are not supported in resolvers.
This includes (but is not limited to) @code{malloc}, @code{dlopen},
@code{dlsym}, and creating threads.
@item
Because a resolved address is bound permanently, resolvers must not
base their decision on state that can change during the lifetime of
the process (@pxref{Single-Threaded, , Detecting Single-Threaded
Execution}, for an example involving
@code{__libc_single_threaded}).
@end itemize
For recommendations on the use of indirect functions in hardened or
security-sensitive applications, @pxref{Dynamic Linker Hardening}.
@node Dynamic Linker Hardening
@section Avoiding Unexpected Issues With Dynamic Linking
@@ -828,9 +1122,12 @@ Underlinking (see above) can hide the presence of cycles.
@item
Limit the creation of indirect function (IFUNC) resolvers. These
resolvers run during relocation processing, when @theglibc{} is not in
a fully consistent state. If you write your own IFUNC resolvers, do
not depend on external data or function references in those resolvers.
resolvers run during relocation processing, before the process or the
newly loaded objects are fully initialized
(@pxref{Indirect Functions}). If you write your own IFUNC resolvers,
keep them self-contained: do not depend on external data or function
references in those resolvers, even where current versions of
@theglibc{} support such references.
@item
Do not use the audit functionality (@code{LD_AUDIT}, @code{DT_AUDIT},
-6
View File
@@ -189,12 +189,6 @@ NOTE: @option{--enable-cet} is only supported on x86_64 and x32.
Don't build libraries with profiling information. You may want to use
this option if you don't plan to do profiling.
@item --enable-static-nss
Compile static versions of the NSS (Name Service Switch) libraries.
This is not recommended because it defeats the purpose of NSS; a program
linked statically with the NSS libraries cannot be dynamically
reconfigured to use a different name database.
@item --enable-hardcoded-path-in-tests
By default, dynamic tests are linked to run with the installed C library.
This option hardcodes the newly built C library path in dynamic tests
-1
View File
@@ -2863,7 +2863,6 @@ aiocb64}, since the LFS transparently replaces the old interface.
@c _dl_deallocate_tls dup
@c munmap ok
@c THREAD_COPY_STACK_GUARD ok
@c THREAD_COPY_POINTER_GUARD ok
@c atomic_exchange_acquire ok
@c lll_futex_wake ok
@c deallocate_stack @asulock @ascuheap @aculock @acsmem
+2 -5
View File
@@ -1388,11 +1388,8 @@ environment variable @env{MALLOC_ARENA_TEST} to the desired value.
This parameter sets the number of arenas to use regardless of the number of
cores in the system.
The default value of this tunable is @code{0}, meaning that the limit on the
number of arenas is determined by the number of CPU cores online. For 32-bit
systems the limit is twice the number of cores online and on 64-bit systems, it
is eight times the number of cores online. Note that the default value is not
derived from the default value of M_ARENA_TEST and is computed independently.
The default value of this tunable is @code{0}, meaning that the limit is the
number of CPU cores online reported by get_nprocs().
This parameter can also be set for the process at startup by setting the
environment variable @env{MALLOC_ARENA_MAX} to the desired value.
+6
View File
@@ -1803,6 +1803,12 @@ to an @code{unsigned char}) in the initial @var{size} bytes of the
object beginning at @var{block}. The return value is a pointer to the
located byte, or a null pointer if no match was found.
This function behaves as if it reads the bytes sequentially and stops at
the first match, which means that if the object contains a match the
behavior is defined even when the object size is less than @var{size}.
This behavior guarantee is unusual, and is not shared by related
functions like @code{memcmp} and @code{wmemchr}.
In ISO C23 and later, this function is qualifier-generic:
that is, it is also implemented as a function-like macro,
and when the macro is used and @var{block} has a type
+12 -18
View File
@@ -220,10 +220,8 @@ identical in features.
This tunable sets the number of arenas to use in a process regardless of the
number of cores in the system.
The default value of this tunable is @code{0}, meaning that the limit on the
number of arenas is determined by the number of CPU cores online. For 32-bit
systems the limit is twice the number of cores online and on 64-bit systems, it
is 8 times the number of cores online.
The default value of this tunable is @code{0}, meaning that the limit is the
number of CPU cores online reported by get_nprocs().
@end deftp
@deftp Tunable glibc.malloc.tcache_max
@@ -239,31 +237,27 @@ disabled.
The approximate maximum overhead of the per-thread cache is thus equal
to the number of bins times the chunk count in each bin times the size
of each chunk. With defaults, the approximate maximum overhead of the
per-thread cache is approximately 236 KB on 64-bit systems and 118 KB
on 32-bit systems.
of each chunk.
@end deftp
@deftp Tunable glibc.malloc.mxfast
One of the optimizations @code{malloc} uses is to maintain a series of ``fast
bins'' that hold chunks up to a specific size. The default and
maximum size which may be held this way is 80 bytes on 32-bit systems
or 160 bytes on 64-bit systems. Applications which value size over
speed may choose to reduce the size of requests which are serviced
from fast bins with this tunable. Note that the value specified
includes @code{malloc}'s internal overhead, which is normally the size of one
pointer, so add 4 on 32-bit systems or 8 on 64-bit systems to the size
passed to @code{malloc} for the largest bin size to enable.
This tunable has no effect since the ``fastbins'' have been removed.
@end deftp
@deftp Tunable glibc.malloc.hugetlb
This tunable controls the usage of Huge Pages on @code{malloc} calls. The
default value is @code{0}, which disables any additional support on
@code{malloc}.
default value is @code{0} on most targets. Using @code{0} disables support
that improves use of huge pages in @code{malloc}. However huge pages may
still be created depending on the OS settings.
Setting its value to @code{1} enables the use of @code{madvise} with
@code{MADV_HUGEPAGE} after memory allocation with @code{mmap}. It is enabled
only if the system supports Transparent Huge Page (currently only on Linux).
This is the default used for AArch64.
When @code{glibc.elf.thp} set to 1, malloc uses the actual kernel THP mode
instead of defaulting to madvise mode and madvise_thp will stop issuing
MADV_HUGEPAGE if kernel THP mode is always.
Setting its value to @code{2} enables the use of Huge Page directly with
@code{mmap} with the use of @code{MAP_HUGETLB} flag. The huge page size
+13
View File
@@ -236,6 +236,19 @@ acosh 0x1.00b3140f6b582p+0
acosh 0x1.00b31560e5422p+0
acosh 0x1.00b3156dfbb59p+0
acosh 0x1.00b319a514ad9p+0
acosh 0x1.004292b93a05ep+0
acosh 0x1.0042d6fc11ef6p+0
acosh 0x1.00a7deb3381abp+0
acosh 0x1.00a7ff291046ap+0
acosh 0x1.00a800422847ap+0
acosh 0x1.00a8178044ea8p+0
acosh 0x1.00a83624f0d22p+0
acosh 0x1.00a851f655836p+0
acosh 0x1.00a86ce6bcfb9p+0
acosh 0x1.00a888136de79p+0
acosh 0x1.00a8abbf7ef1ap+0
acosh 0x1.1p+1
acosh 0x1.3bf8009648dcp+16
acosh max
add 0 0
+853
View File
@@ -3041,6 +3041,859 @@ acosh 0x1.00b319a514ad9p+0
= acosh tonearest ibm128 0x1.00b319a514ad9p+0 : 0x1.2ebfff0249e40ffff0d22dedd18p-4 : inexact-ok
= acosh towardzero ibm128 0x1.00b319a514ad9p+0 : 0x1.2ebfff0249e40ffff0d22dedd18p-4 : inexact-ok
= acosh upward ibm128 0x1.00b319a514ad9p+0 : 0x1.2ebfff0249e40ffff0d22dedd2p-4 : inexact-ok
acosh 0x1.004292b93a05ep+0
= acosh downward binary32 0x1.004294p+0 : 0xb.89d1dp-8 : inexact-ok
= acosh tonearest binary32 0x1.004294p+0 : 0xb.89d1ep-8 : inexact-ok
= acosh towardzero binary32 0x1.004294p+0 : 0xb.89d1dp-8 : inexact-ok
= acosh upward binary32 0x1.004294p+0 : 0xb.89d1ep-8 : inexact-ok
= acosh downward binary64 0x1.004294p+0 : 0xb.89d1d8345ccbp-8 : inexact-ok
= acosh tonearest binary64 0x1.004294p+0 : 0xb.89d1d8345ccbp-8 : inexact-ok
= acosh towardzero binary64 0x1.004294p+0 : 0xb.89d1d8345ccbp-8 : inexact-ok
= acosh upward binary64 0x1.004294p+0 : 0xb.89d1d8345ccb8p-8 : inexact-ok
= acosh downward intel96 0x1.004294p+0 : 0xb.89d1d8345ccb064p-8 : inexact-ok
= acosh tonearest intel96 0x1.004294p+0 : 0xb.89d1d8345ccb065p-8 : inexact-ok
= acosh towardzero intel96 0x1.004294p+0 : 0xb.89d1d8345ccb064p-8 : inexact-ok
= acosh upward intel96 0x1.004294p+0 : 0xb.89d1d8345ccb065p-8 : inexact-ok
= acosh downward m68k96 0x1.004294p+0 : 0xb.89d1d8345ccb064p-8 : inexact-ok
= acosh tonearest m68k96 0x1.004294p+0 : 0xb.89d1d8345ccb065p-8 : inexact-ok
= acosh towardzero m68k96 0x1.004294p+0 : 0xb.89d1d8345ccb064p-8 : inexact-ok
= acosh upward m68k96 0x1.004294p+0 : 0xb.89d1d8345ccb065p-8 : inexact-ok
= acosh downward binary128 0x1.004294p+0 : 0xb.89d1d8345ccb064c07e40bcfaef8p-8 : inexact-ok
= acosh tonearest binary128 0x1.004294p+0 : 0xb.89d1d8345ccb064c07e40bcfaef8p-8 : inexact-ok
= acosh towardzero binary128 0x1.004294p+0 : 0xb.89d1d8345ccb064c07e40bcfaef8p-8 : inexact-ok
= acosh upward binary128 0x1.004294p+0 : 0xb.89d1d8345ccb064c07e40bcfafp-8 : inexact-ok
= acosh downward ibm128 0x1.004294p+0 : 0xb.89d1d8345ccb064c07e40bcfacp-8 : inexact-ok
= acosh tonearest ibm128 0x1.004294p+0 : 0xb.89d1d8345ccb064c07e40bcfbp-8 : inexact-ok
= acosh towardzero ibm128 0x1.004294p+0 : 0xb.89d1d8345ccb064c07e40bcfacp-8 : inexact-ok
= acosh upward ibm128 0x1.004294p+0 : 0xb.89d1d8345ccb064c07e40bcfbp-8 : inexact-ok
= acosh downward binary32 0x1.004292p+0 : 0xb.89a57p-8 : inexact-ok
= acosh tonearest binary32 0x1.004292p+0 : 0xb.89a58p-8 : inexact-ok
= acosh towardzero binary32 0x1.004292p+0 : 0xb.89a57p-8 : inexact-ok
= acosh upward binary32 0x1.004292p+0 : 0xb.89a58p-8 : inexact-ok
= acosh downward binary64 0x1.004292p+0 : 0xb.89a57c0a97e58p-8 : inexact-ok
= acosh tonearest binary64 0x1.004292p+0 : 0xb.89a57c0a97e6p-8 : inexact-ok
= acosh towardzero binary64 0x1.004292p+0 : 0xb.89a57c0a97e58p-8 : inexact-ok
= acosh upward binary64 0x1.004292p+0 : 0xb.89a57c0a97e6p-8 : inexact-ok
= acosh downward intel96 0x1.004292p+0 : 0xb.89a57c0a97e5d1bp-8 : inexact-ok
= acosh tonearest intel96 0x1.004292p+0 : 0xb.89a57c0a97e5d1cp-8 : inexact-ok
= acosh towardzero intel96 0x1.004292p+0 : 0xb.89a57c0a97e5d1bp-8 : inexact-ok
= acosh upward intel96 0x1.004292p+0 : 0xb.89a57c0a97e5d1cp-8 : inexact-ok
= acosh downward m68k96 0x1.004292p+0 : 0xb.89a57c0a97e5d1bp-8 : inexact-ok
= acosh tonearest m68k96 0x1.004292p+0 : 0xb.89a57c0a97e5d1cp-8 : inexact-ok
= acosh towardzero m68k96 0x1.004292p+0 : 0xb.89a57c0a97e5d1bp-8 : inexact-ok
= acosh upward m68k96 0x1.004292p+0 : 0xb.89a57c0a97e5d1cp-8 : inexact-ok
= acosh downward binary128 0x1.004292p+0 : 0xb.89a57c0a97e5d1b89afd02571ee8p-8 : inexact-ok
= acosh tonearest binary128 0x1.004292p+0 : 0xb.89a57c0a97e5d1b89afd02571efp-8 : inexact-ok
= acosh towardzero binary128 0x1.004292p+0 : 0xb.89a57c0a97e5d1b89afd02571ee8p-8 : inexact-ok
= acosh upward binary128 0x1.004292p+0 : 0xb.89a57c0a97e5d1b89afd02571efp-8 : inexact-ok
= acosh downward ibm128 0x1.004292p+0 : 0xb.89a57c0a97e5d1b89afd02571cp-8 : inexact-ok
= acosh tonearest ibm128 0x1.004292p+0 : 0xb.89a57c0a97e5d1b89afd02572p-8 : inexact-ok
= acosh towardzero ibm128 0x1.004292p+0 : 0xb.89a57c0a97e5d1b89afd02571cp-8 : inexact-ok
= acosh upward ibm128 0x1.004292p+0 : 0xb.89a57c0a97e5d1b89afd02572p-8 : inexact-ok
= acosh downward binary64 0x1.004292b93a05ep+0 : 0xb.89b588725684p-8 : inexact-ok
= acosh tonearest binary64 0x1.004292b93a05ep+0 : 0xb.89b5887256848p-8 : inexact-ok
= acosh towardzero binary64 0x1.004292b93a05ep+0 : 0xb.89b588725684p-8 : inexact-ok
= acosh upward binary64 0x1.004292b93a05ep+0 : 0xb.89b5887256848p-8 : inexact-ok
= acosh downward intel96 0x1.004292b93a05ep+0 : 0xb.89b5887256847ffp-8 : inexact-ok
= acosh tonearest intel96 0x1.004292b93a05ep+0 : 0xb.89b5887256848p-8 : inexact-ok
= acosh towardzero intel96 0x1.004292b93a05ep+0 : 0xb.89b5887256847ffp-8 : inexact-ok
= acosh upward intel96 0x1.004292b93a05ep+0 : 0xb.89b5887256848p-8 : inexact-ok
= acosh downward m68k96 0x1.004292b93a05ep+0 : 0xb.89b5887256847ffp-8 : inexact-ok
= acosh tonearest m68k96 0x1.004292b93a05ep+0 : 0xb.89b5887256848p-8 : inexact-ok
= acosh towardzero m68k96 0x1.004292b93a05ep+0 : 0xb.89b5887256847ffp-8 : inexact-ok
= acosh upward m68k96 0x1.004292b93a05ep+0 : 0xb.89b5887256848p-8 : inexact-ok
= acosh downward binary128 0x1.004292b93a05ep+0 : 0xb.89b5887256847fffd4cea3586058p-8 : inexact-ok
= acosh tonearest binary128 0x1.004292b93a05ep+0 : 0xb.89b5887256847fffd4cea3586058p-8 : inexact-ok
= acosh towardzero binary128 0x1.004292b93a05ep+0 : 0xb.89b5887256847fffd4cea3586058p-8 : inexact-ok
= acosh upward binary128 0x1.004292b93a05ep+0 : 0xb.89b5887256847fffd4cea358606p-8 : inexact-ok
= acosh downward ibm128 0x1.004292b93a05ep+0 : 0xb.89b5887256847fffd4cea3586p-8 : inexact-ok
= acosh tonearest ibm128 0x1.004292b93a05ep+0 : 0xb.89b5887256847fffd4cea3586p-8 : inexact-ok
= acosh towardzero ibm128 0x1.004292b93a05ep+0 : 0xb.89b5887256847fffd4cea3586p-8 : inexact-ok
= acosh upward ibm128 0x1.004292b93a05ep+0 : 0xb.89b5887256847fffd4cea35864p-8 : inexact-ok
acosh 0x1.0042d6fc11ef6p+0
= acosh downward binary32 0x1.0042d8p+0 : 0xb.8fb48p-8 : inexact-ok
= acosh tonearest binary32 0x1.0042d8p+0 : 0xb.8fb49p-8 : inexact-ok
= acosh towardzero binary32 0x1.0042d8p+0 : 0xb.8fb48p-8 : inexact-ok
= acosh upward binary32 0x1.0042d8p+0 : 0xb.8fb49p-8 : inexact-ok
= acosh downward binary64 0x1.0042d8p+0 : 0xb.8fb489e37e14p-8 : inexact-ok
= acosh tonearest binary64 0x1.0042d8p+0 : 0xb.8fb489e37e14p-8 : inexact-ok
= acosh towardzero binary64 0x1.0042d8p+0 : 0xb.8fb489e37e14p-8 : inexact-ok
= acosh upward binary64 0x1.0042d8p+0 : 0xb.8fb489e37e148p-8 : inexact-ok
= acosh downward intel96 0x1.0042d8p+0 : 0xb.8fb489e37e1439p-8 : inexact-ok
= acosh tonearest intel96 0x1.0042d8p+0 : 0xb.8fb489e37e1439p-8 : inexact-ok
= acosh towardzero intel96 0x1.0042d8p+0 : 0xb.8fb489e37e1439p-8 : inexact-ok
= acosh upward intel96 0x1.0042d8p+0 : 0xb.8fb489e37e14391p-8 : inexact-ok
= acosh downward m68k96 0x1.0042d8p+0 : 0xb.8fb489e37e1439p-8 : inexact-ok
= acosh tonearest m68k96 0x1.0042d8p+0 : 0xb.8fb489e37e1439p-8 : inexact-ok
= acosh towardzero m68k96 0x1.0042d8p+0 : 0xb.8fb489e37e1439p-8 : inexact-ok
= acosh upward m68k96 0x1.0042d8p+0 : 0xb.8fb489e37e14391p-8 : inexact-ok
= acosh downward binary128 0x1.0042d8p+0 : 0xb.8fb489e37e143904f6dce9a51828p-8 : inexact-ok
= acosh tonearest binary128 0x1.0042d8p+0 : 0xb.8fb489e37e143904f6dce9a5183p-8 : inexact-ok
= acosh towardzero binary128 0x1.0042d8p+0 : 0xb.8fb489e37e143904f6dce9a51828p-8 : inexact-ok
= acosh upward binary128 0x1.0042d8p+0 : 0xb.8fb489e37e143904f6dce9a5183p-8 : inexact-ok
= acosh downward ibm128 0x1.0042d8p+0 : 0xb.8fb489e37e143904f6dce9a518p-8 : inexact-ok
= acosh tonearest ibm128 0x1.0042d8p+0 : 0xb.8fb489e37e143904f6dce9a518p-8 : inexact-ok
= acosh towardzero ibm128 0x1.0042d8p+0 : 0xb.8fb489e37e143904f6dce9a518p-8 : inexact-ok
= acosh upward ibm128 0x1.0042d8p+0 : 0xb.8fb489e37e143904f6dce9a51cp-8 : inexact-ok
= acosh downward binary32 0x1.0042d6p+0 : 0xb.8f884p-8 : inexact-ok
= acosh tonearest binary32 0x1.0042d6p+0 : 0xb.8f884p-8 : inexact-ok
= acosh towardzero binary32 0x1.0042d6p+0 : 0xb.8f884p-8 : inexact-ok
= acosh upward binary32 0x1.0042d6p+0 : 0xb.8f885p-8 : inexact-ok
= acosh downward binary64 0x1.0042d6p+0 : 0xb.8f8844530cc6p-8 : inexact-ok
= acosh tonearest binary64 0x1.0042d6p+0 : 0xb.8f8844530cc6p-8 : inexact-ok
= acosh towardzero binary64 0x1.0042d6p+0 : 0xb.8f8844530cc6p-8 : inexact-ok
= acosh upward binary64 0x1.0042d6p+0 : 0xb.8f8844530cc68p-8 : inexact-ok
= acosh downward intel96 0x1.0042d6p+0 : 0xb.8f8844530cc6345p-8 : inexact-ok
= acosh tonearest intel96 0x1.0042d6p+0 : 0xb.8f8844530cc6346p-8 : inexact-ok
= acosh towardzero intel96 0x1.0042d6p+0 : 0xb.8f8844530cc6345p-8 : inexact-ok
= acosh upward intel96 0x1.0042d6p+0 : 0xb.8f8844530cc6346p-8 : inexact-ok
= acosh downward m68k96 0x1.0042d6p+0 : 0xb.8f8844530cc6345p-8 : inexact-ok
= acosh tonearest m68k96 0x1.0042d6p+0 : 0xb.8f8844530cc6346p-8 : inexact-ok
= acosh towardzero m68k96 0x1.0042d6p+0 : 0xb.8f8844530cc6345p-8 : inexact-ok
= acosh upward m68k96 0x1.0042d6p+0 : 0xb.8f8844530cc6346p-8 : inexact-ok
= acosh downward binary128 0x1.0042d6p+0 : 0xb.8f8844530cc6345bf51805407d2p-8 : inexact-ok
= acosh tonearest binary128 0x1.0042d6p+0 : 0xb.8f8844530cc6345bf51805407d28p-8 : inexact-ok
= acosh towardzero binary128 0x1.0042d6p+0 : 0xb.8f8844530cc6345bf51805407d2p-8 : inexact-ok
= acosh upward binary128 0x1.0042d6p+0 : 0xb.8f8844530cc6345bf51805407d28p-8 : inexact-ok
= acosh downward ibm128 0x1.0042d6p+0 : 0xb.8f8844530cc6345bf51805407cp-8 : inexact-ok
= acosh tonearest ibm128 0x1.0042d6p+0 : 0xb.8f8844530cc6345bf51805407cp-8 : inexact-ok
= acosh towardzero ibm128 0x1.0042d6p+0 : 0xb.8f8844530cc6345bf51805407cp-8 : inexact-ok
= acosh upward ibm128 0x1.0042d6p+0 : 0xb.8f8844530cc6345bf51805408p-8 : inexact-ok
= acosh downward binary64 0x1.0042d6fc11ef6p+0 : 0xb.8f9e10325a1dp-8 : inexact-ok
= acosh tonearest binary64 0x1.0042d6fc11ef6p+0 : 0xb.8f9e10325a1d8p-8 : inexact-ok
= acosh towardzero binary64 0x1.0042d6fc11ef6p+0 : 0xb.8f9e10325a1dp-8 : inexact-ok
= acosh upward binary64 0x1.0042d6fc11ef6p+0 : 0xb.8f9e10325a1d8p-8 : inexact-ok
= acosh downward intel96 0x1.0042d6fc11ef6p+0 : 0xb.8f9e10325a1d7ffp-8 : inexact-ok
= acosh tonearest intel96 0x1.0042d6fc11ef6p+0 : 0xb.8f9e10325a1d8p-8 : inexact-ok
= acosh towardzero intel96 0x1.0042d6fc11ef6p+0 : 0xb.8f9e10325a1d7ffp-8 : inexact-ok
= acosh upward intel96 0x1.0042d6fc11ef6p+0 : 0xb.8f9e10325a1d8p-8 : inexact-ok
= acosh downward m68k96 0x1.0042d6fc11ef6p+0 : 0xb.8f9e10325a1d7ffp-8 : inexact-ok
= acosh tonearest m68k96 0x1.0042d6fc11ef6p+0 : 0xb.8f9e10325a1d8p-8 : inexact-ok
= acosh towardzero m68k96 0x1.0042d6fc11ef6p+0 : 0xb.8f9e10325a1d7ffp-8 : inexact-ok
= acosh upward m68k96 0x1.0042d6fc11ef6p+0 : 0xb.8f9e10325a1d8p-8 : inexact-ok
= acosh downward binary128 0x1.0042d6fc11ef6p+0 : 0xb.8f9e10325a1d7ffff8b8abf45098p-8 : inexact-ok
= acosh tonearest binary128 0x1.0042d6fc11ef6p+0 : 0xb.8f9e10325a1d7ffff8b8abf450ap-8 : inexact-ok
= acosh towardzero binary128 0x1.0042d6fc11ef6p+0 : 0xb.8f9e10325a1d7ffff8b8abf45098p-8 : inexact-ok
= acosh upward binary128 0x1.0042d6fc11ef6p+0 : 0xb.8f9e10325a1d7ffff8b8abf450ap-8 : inexact-ok
= acosh downward ibm128 0x1.0042d6fc11ef6p+0 : 0xb.8f9e10325a1d7ffff8b8abf45p-8 : inexact-ok
= acosh tonearest ibm128 0x1.0042d6fc11ef6p+0 : 0xb.8f9e10325a1d7ffff8b8abf45p-8 : inexact-ok
= acosh towardzero ibm128 0x1.0042d6fc11ef6p+0 : 0xb.8f9e10325a1d7ffff8b8abf45p-8 : inexact-ok
= acosh upward ibm128 0x1.0042d6fc11ef6p+0 : 0xb.8f9e10325a1d7ffff8b8abf454p-8 : inexact-ok
acosh 0x1.00a7deb3381abp+0
= acosh downward binary32 0x1.00a7ep+0 : 0x1.251cf8p-4 : inexact-ok
= acosh tonearest binary32 0x1.00a7ep+0 : 0x1.251cf8p-4 : inexact-ok
= acosh towardzero binary32 0x1.00a7ep+0 : 0x1.251cf8p-4 : inexact-ok
= acosh upward binary32 0x1.00a7ep+0 : 0x1.251cfap-4 : inexact-ok
= acosh downward binary64 0x1.00a7ep+0 : 0x1.251cf8a1135cap-4 : inexact-ok
= acosh tonearest binary64 0x1.00a7ep+0 : 0x1.251cf8a1135cap-4 : inexact-ok
= acosh towardzero binary64 0x1.00a7ep+0 : 0x1.251cf8a1135cap-4 : inexact-ok
= acosh upward binary64 0x1.00a7ep+0 : 0x1.251cf8a1135cbp-4 : inexact-ok
= acosh downward intel96 0x1.00a7ep+0 : 0x1.251cf8a1135ca4acp-4 : inexact-ok
= acosh tonearest intel96 0x1.00a7ep+0 : 0x1.251cf8a1135ca4acp-4 : inexact-ok
= acosh towardzero intel96 0x1.00a7ep+0 : 0x1.251cf8a1135ca4acp-4 : inexact-ok
= acosh upward intel96 0x1.00a7ep+0 : 0x1.251cf8a1135ca4aep-4 : inexact-ok
= acosh downward m68k96 0x1.00a7ep+0 : 0x1.251cf8a1135ca4acp-4 : inexact-ok
= acosh tonearest m68k96 0x1.00a7ep+0 : 0x1.251cf8a1135ca4acp-4 : inexact-ok
= acosh towardzero m68k96 0x1.00a7ep+0 : 0x1.251cf8a1135ca4acp-4 : inexact-ok
= acosh upward m68k96 0x1.00a7ep+0 : 0x1.251cf8a1135ca4aep-4 : inexact-ok
= acosh downward binary128 0x1.00a7ep+0 : 0x1.251cf8a1135ca4ac066bcd698df6p-4 : inexact-ok
= acosh tonearest binary128 0x1.00a7ep+0 : 0x1.251cf8a1135ca4ac066bcd698df6p-4 : inexact-ok
= acosh towardzero binary128 0x1.00a7ep+0 : 0x1.251cf8a1135ca4ac066bcd698df6p-4 : inexact-ok
= acosh upward binary128 0x1.00a7ep+0 : 0x1.251cf8a1135ca4ac066bcd698df7p-4 : inexact-ok
= acosh downward ibm128 0x1.00a7ep+0 : 0x1.251cf8a1135ca4ac066bcd698d8p-4 : inexact-ok
= acosh tonearest ibm128 0x1.00a7ep+0 : 0x1.251cf8a1135ca4ac066bcd698ep-4 : inexact-ok
= acosh towardzero ibm128 0x1.00a7ep+0 : 0x1.251cf8a1135ca4ac066bcd698d8p-4 : inexact-ok
= acosh upward ibm128 0x1.00a7ep+0 : 0x1.251cf8a1135ca4ac066bcd698ep-4 : inexact-ok
= acosh downward binary32 0x1.00a7dep+0 : 0x1.251b38p-4 : inexact-ok
= acosh tonearest binary32 0x1.00a7dep+0 : 0x1.251b3ap-4 : inexact-ok
= acosh towardzero binary32 0x1.00a7dep+0 : 0x1.251b38p-4 : inexact-ok
= acosh upward binary32 0x1.00a7dep+0 : 0x1.251b3ap-4 : inexact-ok
= acosh downward binary64 0x1.00a7dep+0 : 0x1.251b39d55be05p-4 : inexact-ok
= acosh tonearest binary64 0x1.00a7dep+0 : 0x1.251b39d55be05p-4 : inexact-ok
= acosh towardzero binary64 0x1.00a7dep+0 : 0x1.251b39d55be05p-4 : inexact-ok
= acosh upward binary64 0x1.00a7dep+0 : 0x1.251b39d55be06p-4 : inexact-ok
= acosh downward intel96 0x1.00a7dep+0 : 0x1.251b39d55be05036p-4 : inexact-ok
= acosh tonearest intel96 0x1.00a7dep+0 : 0x1.251b39d55be05036p-4 : inexact-ok
= acosh towardzero intel96 0x1.00a7dep+0 : 0x1.251b39d55be05036p-4 : inexact-ok
= acosh upward intel96 0x1.00a7dep+0 : 0x1.251b39d55be05038p-4 : inexact-ok
= acosh downward m68k96 0x1.00a7dep+0 : 0x1.251b39d55be05036p-4 : inexact-ok
= acosh tonearest m68k96 0x1.00a7dep+0 : 0x1.251b39d55be05036p-4 : inexact-ok
= acosh towardzero m68k96 0x1.00a7dep+0 : 0x1.251b39d55be05036p-4 : inexact-ok
= acosh upward m68k96 0x1.00a7dep+0 : 0x1.251b39d55be05038p-4 : inexact-ok
= acosh downward binary128 0x1.00a7dep+0 : 0x1.251b39d55be0503683142b3bb4cep-4 : inexact-ok
= acosh tonearest binary128 0x1.00a7dep+0 : 0x1.251b39d55be0503683142b3bb4cep-4 : inexact-ok
= acosh towardzero binary128 0x1.00a7dep+0 : 0x1.251b39d55be0503683142b3bb4cep-4 : inexact-ok
= acosh upward binary128 0x1.00a7dep+0 : 0x1.251b39d55be0503683142b3bb4cfp-4 : inexact-ok
= acosh downward ibm128 0x1.00a7dep+0 : 0x1.251b39d55be0503683142b3bb48p-4 : inexact-ok
= acosh tonearest ibm128 0x1.00a7dep+0 : 0x1.251b39d55be0503683142b3bb5p-4 : inexact-ok
= acosh towardzero ibm128 0x1.00a7dep+0 : 0x1.251b39d55be0503683142b3bb48p-4 : inexact-ok
= acosh upward ibm128 0x1.00a7dep+0 : 0x1.251b39d55be0503683142b3bb5p-4 : inexact-ok
= acosh downward binary64 0x1.00a7deb3381abp+0 : 0x1.251bd63ad7b3bp-4 : inexact-ok
= acosh tonearest binary64 0x1.00a7deb3381abp+0 : 0x1.251bd63ad7b3cp-4 : inexact-ok
= acosh towardzero binary64 0x1.00a7deb3381abp+0 : 0x1.251bd63ad7b3bp-4 : inexact-ok
= acosh upward binary64 0x1.00a7deb3381abp+0 : 0x1.251bd63ad7b3cp-4 : inexact-ok
= acosh downward intel96 0x1.00a7deb3381abp+0 : 0x1.251bd63ad7b3bffep-4 : inexact-ok
= acosh tonearest intel96 0x1.00a7deb3381abp+0 : 0x1.251bd63ad7b3cp-4 : inexact-ok
= acosh towardzero intel96 0x1.00a7deb3381abp+0 : 0x1.251bd63ad7b3bffep-4 : inexact-ok
= acosh upward intel96 0x1.00a7deb3381abp+0 : 0x1.251bd63ad7b3cp-4 : inexact-ok
= acosh downward m68k96 0x1.00a7deb3381abp+0 : 0x1.251bd63ad7b3bffep-4 : inexact-ok
= acosh tonearest m68k96 0x1.00a7deb3381abp+0 : 0x1.251bd63ad7b3cp-4 : inexact-ok
= acosh towardzero m68k96 0x1.00a7deb3381abp+0 : 0x1.251bd63ad7b3bffep-4 : inexact-ok
= acosh upward m68k96 0x1.00a7deb3381abp+0 : 0x1.251bd63ad7b3cp-4 : inexact-ok
= acosh downward binary128 0x1.00a7deb3381abp+0 : 0x1.251bd63ad7b3bffff52f66ff4641p-4 : inexact-ok
= acosh tonearest binary128 0x1.00a7deb3381abp+0 : 0x1.251bd63ad7b3bffff52f66ff4641p-4 : inexact-ok
= acosh towardzero binary128 0x1.00a7deb3381abp+0 : 0x1.251bd63ad7b3bffff52f66ff4641p-4 : inexact-ok
= acosh upward binary128 0x1.00a7deb3381abp+0 : 0x1.251bd63ad7b3bffff52f66ff4642p-4 : inexact-ok
= acosh downward ibm128 0x1.00a7deb3381abp+0 : 0x1.251bd63ad7b3bffff52f66ff46p-4 : inexact-ok
= acosh tonearest ibm128 0x1.00a7deb3381abp+0 : 0x1.251bd63ad7b3bffff52f66ff468p-4 : inexact-ok
= acosh towardzero ibm128 0x1.00a7deb3381abp+0 : 0x1.251bd63ad7b3bffff52f66ff46p-4 : inexact-ok
= acosh upward ibm128 0x1.00a7deb3381abp+0 : 0x1.251bd63ad7b3bffff52f66ff468p-4 : inexact-ok
acosh 0x1.00a7ff291046ap+0
= acosh downward binary32 0x1.00a8p+0 : 0x1.2538e2p-4 : inexact-ok
= acosh tonearest binary32 0x1.00a8p+0 : 0x1.2538e4p-4 : inexact-ok
= acosh towardzero binary32 0x1.00a8p+0 : 0x1.2538e2p-4 : inexact-ok
= acosh upward binary32 0x1.00a8p+0 : 0x1.2538e4p-4 : inexact-ok
= acosh downward binary64 0x1.00a8p+0 : 0x1.2538e3f23ffd7p-4 : inexact-ok
= acosh tonearest binary64 0x1.00a8p+0 : 0x1.2538e3f23ffd8p-4 : inexact-ok
= acosh towardzero binary64 0x1.00a8p+0 : 0x1.2538e3f23ffd7p-4 : inexact-ok
= acosh upward binary64 0x1.00a8p+0 : 0x1.2538e3f23ffd8p-4 : inexact-ok
= acosh downward intel96 0x1.00a8p+0 : 0x1.2538e3f23ffd7ccep-4 : inexact-ok
= acosh tonearest intel96 0x1.00a8p+0 : 0x1.2538e3f23ffd7cdp-4 : inexact-ok
= acosh towardzero intel96 0x1.00a8p+0 : 0x1.2538e3f23ffd7ccep-4 : inexact-ok
= acosh upward intel96 0x1.00a8p+0 : 0x1.2538e3f23ffd7cdp-4 : inexact-ok
= acosh downward m68k96 0x1.00a8p+0 : 0x1.2538e3f23ffd7ccep-4 : inexact-ok
= acosh tonearest m68k96 0x1.00a8p+0 : 0x1.2538e3f23ffd7cdp-4 : inexact-ok
= acosh towardzero m68k96 0x1.00a8p+0 : 0x1.2538e3f23ffd7ccep-4 : inexact-ok
= acosh upward m68k96 0x1.00a8p+0 : 0x1.2538e3f23ffd7cdp-4 : inexact-ok
= acosh downward binary128 0x1.00a8p+0 : 0x1.2538e3f23ffd7ccf0ff985097484p-4 : inexact-ok
= acosh tonearest binary128 0x1.00a8p+0 : 0x1.2538e3f23ffd7ccf0ff985097485p-4 : inexact-ok
= acosh towardzero binary128 0x1.00a8p+0 : 0x1.2538e3f23ffd7ccf0ff985097484p-4 : inexact-ok
= acosh upward binary128 0x1.00a8p+0 : 0x1.2538e3f23ffd7ccf0ff985097485p-4 : inexact-ok
= acosh downward ibm128 0x1.00a8p+0 : 0x1.2538e3f23ffd7ccf0ff98509748p-4 : inexact-ok
= acosh tonearest ibm128 0x1.00a8p+0 : 0x1.2538e3f23ffd7ccf0ff98509748p-4 : inexact-ok
= acosh towardzero ibm128 0x1.00a8p+0 : 0x1.2538e3f23ffd7ccf0ff98509748p-4 : inexact-ok
= acosh upward ibm128 0x1.00a8p+0 : 0x1.2538e3f23ffd7ccf0ff9850975p-4 : inexact-ok
= acosh downward binary32 0x1.00a7fep+0 : 0x1.253724p-4 : inexact-ok
= acosh tonearest binary32 0x1.00a7fep+0 : 0x1.253726p-4 : inexact-ok
= acosh towardzero binary32 0x1.00a7fep+0 : 0x1.253724p-4 : inexact-ok
= acosh upward binary32 0x1.00a7fep+0 : 0x1.253726p-4 : inexact-ok
= acosh downward binary64 0x1.00a7fep+0 : 0x1.253725512607dp-4 : inexact-ok
= acosh tonearest binary64 0x1.00a7fep+0 : 0x1.253725512607dp-4 : inexact-ok
= acosh towardzero binary64 0x1.00a7fep+0 : 0x1.253725512607dp-4 : inexact-ok
= acosh upward binary64 0x1.00a7fep+0 : 0x1.253725512607ep-4 : inexact-ok
= acosh downward intel96 0x1.00a7fep+0 : 0x1.253725512607d666p-4 : inexact-ok
= acosh tonearest intel96 0x1.00a7fep+0 : 0x1.253725512607d668p-4 : inexact-ok
= acosh towardzero intel96 0x1.00a7fep+0 : 0x1.253725512607d666p-4 : inexact-ok
= acosh upward intel96 0x1.00a7fep+0 : 0x1.253725512607d668p-4 : inexact-ok
= acosh downward m68k96 0x1.00a7fep+0 : 0x1.253725512607d666p-4 : inexact-ok
= acosh tonearest m68k96 0x1.00a7fep+0 : 0x1.253725512607d668p-4 : inexact-ok
= acosh towardzero m68k96 0x1.00a7fep+0 : 0x1.253725512607d666p-4 : inexact-ok
= acosh upward m68k96 0x1.00a7fep+0 : 0x1.253725512607d668p-4 : inexact-ok
= acosh downward binary128 0x1.00a7fep+0 : 0x1.253725512607d66772cccf1eb375p-4 : inexact-ok
= acosh tonearest binary128 0x1.00a7fep+0 : 0x1.253725512607d66772cccf1eb376p-4 : inexact-ok
= acosh towardzero binary128 0x1.00a7fep+0 : 0x1.253725512607d66772cccf1eb375p-4 : inexact-ok
= acosh upward binary128 0x1.00a7fep+0 : 0x1.253725512607d66772cccf1eb376p-4 : inexact-ok
= acosh downward ibm128 0x1.00a7fep+0 : 0x1.253725512607d66772cccf1eb3p-4 : inexact-ok
= acosh tonearest ibm128 0x1.00a7fep+0 : 0x1.253725512607d66772cccf1eb38p-4 : inexact-ok
= acosh towardzero ibm128 0x1.00a7fep+0 : 0x1.253725512607d66772cccf1eb3p-4 : inexact-ok
= acosh upward ibm128 0x1.00a7fep+0 : 0x1.253725512607d66772cccf1eb38p-4 : inexact-ok
= acosh downward binary64 0x1.00a7ff291046ap+0 : 0x1.253828741f38fp-4 : inexact-ok
= acosh tonearest binary64 0x1.00a7ff291046ap+0 : 0x1.253828741f39p-4 : inexact-ok
= acosh towardzero binary64 0x1.00a7ff291046ap+0 : 0x1.253828741f38fp-4 : inexact-ok
= acosh upward binary64 0x1.00a7ff291046ap+0 : 0x1.253828741f39p-4 : inexact-ok
= acosh downward intel96 0x1.00a7ff291046ap+0 : 0x1.253828741f38fffep-4 : inexact-ok
= acosh tonearest intel96 0x1.00a7ff291046ap+0 : 0x1.253828741f39p-4 : inexact-ok
= acosh towardzero intel96 0x1.00a7ff291046ap+0 : 0x1.253828741f38fffep-4 : inexact-ok
= acosh upward intel96 0x1.00a7ff291046ap+0 : 0x1.253828741f39p-4 : inexact-ok
= acosh downward m68k96 0x1.00a7ff291046ap+0 : 0x1.253828741f38fffep-4 : inexact-ok
= acosh tonearest m68k96 0x1.00a7ff291046ap+0 : 0x1.253828741f39p-4 : inexact-ok
= acosh towardzero m68k96 0x1.00a7ff291046ap+0 : 0x1.253828741f38fffep-4 : inexact-ok
= acosh upward m68k96 0x1.00a7ff291046ap+0 : 0x1.253828741f39p-4 : inexact-ok
= acosh downward binary128 0x1.00a7ff291046ap+0 : 0x1.253828741f38fffff64335b544a2p-4 : inexact-ok
= acosh tonearest binary128 0x1.00a7ff291046ap+0 : 0x1.253828741f38fffff64335b544a2p-4 : inexact-ok
= acosh towardzero binary128 0x1.00a7ff291046ap+0 : 0x1.253828741f38fffff64335b544a2p-4 : inexact-ok
= acosh upward binary128 0x1.00a7ff291046ap+0 : 0x1.253828741f38fffff64335b544a3p-4 : inexact-ok
= acosh downward ibm128 0x1.00a7ff291046ap+0 : 0x1.253828741f38fffff64335b5448p-4 : inexact-ok
= acosh tonearest ibm128 0x1.00a7ff291046ap+0 : 0x1.253828741f38fffff64335b5448p-4 : inexact-ok
= acosh towardzero ibm128 0x1.00a7ff291046ap+0 : 0x1.253828741f38fffff64335b5448p-4 : inexact-ok
= acosh upward ibm128 0x1.00a7ff291046ap+0 : 0x1.253828741f38fffff64335b545p-4 : inexact-ok
acosh 0x1.00a800422847ap+0
= acosh downward binary32 0x1.00a802p+0 : 0x1.253aa2p-4 : inexact-ok
= acosh tonearest binary32 0x1.00a802p+0 : 0x1.253aa2p-4 : inexact-ok
= acosh towardzero binary32 0x1.00a802p+0 : 0x1.253aa2p-4 : inexact-ok
= acosh upward binary32 0x1.00a802p+0 : 0x1.253aa4p-4 : inexact-ok
= acosh downward binary64 0x1.00a802p+0 : 0x1.253aa290b0822p-4 : inexact-ok
= acosh tonearest binary64 0x1.00a802p+0 : 0x1.253aa290b0823p-4 : inexact-ok
= acosh towardzero binary64 0x1.00a802p+0 : 0x1.253aa290b0822p-4 : inexact-ok
= acosh upward binary64 0x1.00a802p+0 : 0x1.253aa290b0823p-4 : inexact-ok
= acosh downward intel96 0x1.00a802p+0 : 0x1.253aa290b0822ce2p-4 : inexact-ok
= acosh tonearest intel96 0x1.00a802p+0 : 0x1.253aa290b0822ce4p-4 : inexact-ok
= acosh towardzero intel96 0x1.00a802p+0 : 0x1.253aa290b0822ce2p-4 : inexact-ok
= acosh upward intel96 0x1.00a802p+0 : 0x1.253aa290b0822ce4p-4 : inexact-ok
= acosh downward m68k96 0x1.00a802p+0 : 0x1.253aa290b0822ce2p-4 : inexact-ok
= acosh tonearest m68k96 0x1.00a802p+0 : 0x1.253aa290b0822ce4p-4 : inexact-ok
= acosh towardzero m68k96 0x1.00a802p+0 : 0x1.253aa290b0822ce2p-4 : inexact-ok
= acosh upward m68k96 0x1.00a802p+0 : 0x1.253aa290b0822ce4p-4 : inexact-ok
= acosh downward binary128 0x1.00a802p+0 : 0x1.253aa290b0822ce377361e6d4092p-4 : inexact-ok
= acosh tonearest binary128 0x1.00a802p+0 : 0x1.253aa290b0822ce377361e6d4093p-4 : inexact-ok
= acosh towardzero binary128 0x1.00a802p+0 : 0x1.253aa290b0822ce377361e6d4092p-4 : inexact-ok
= acosh upward binary128 0x1.00a802p+0 : 0x1.253aa290b0822ce377361e6d4093p-4 : inexact-ok
= acosh downward ibm128 0x1.00a802p+0 : 0x1.253aa290b0822ce377361e6d408p-4 : inexact-ok
= acosh tonearest ibm128 0x1.00a802p+0 : 0x1.253aa290b0822ce377361e6d408p-4 : inexact-ok
= acosh towardzero ibm128 0x1.00a802p+0 : 0x1.253aa290b0822ce377361e6d408p-4 : inexact-ok
= acosh upward ibm128 0x1.00a802p+0 : 0x1.253aa290b0822ce377361e6d41p-4 : inexact-ok
= acosh downward binary32 0x1.00a8p+0 : 0x1.2538e2p-4 : inexact-ok
= acosh tonearest binary32 0x1.00a8p+0 : 0x1.2538e4p-4 : inexact-ok
= acosh towardzero binary32 0x1.00a8p+0 : 0x1.2538e2p-4 : inexact-ok
= acosh upward binary32 0x1.00a8p+0 : 0x1.2538e4p-4 : inexact-ok
= acosh downward binary64 0x1.00a8p+0 : 0x1.2538e3f23ffd7p-4 : inexact-ok
= acosh tonearest binary64 0x1.00a8p+0 : 0x1.2538e3f23ffd8p-4 : inexact-ok
= acosh towardzero binary64 0x1.00a8p+0 : 0x1.2538e3f23ffd7p-4 : inexact-ok
= acosh upward binary64 0x1.00a8p+0 : 0x1.2538e3f23ffd8p-4 : inexact-ok
= acosh downward intel96 0x1.00a8p+0 : 0x1.2538e3f23ffd7ccep-4 : inexact-ok
= acosh tonearest intel96 0x1.00a8p+0 : 0x1.2538e3f23ffd7cdp-4 : inexact-ok
= acosh towardzero intel96 0x1.00a8p+0 : 0x1.2538e3f23ffd7ccep-4 : inexact-ok
= acosh upward intel96 0x1.00a8p+0 : 0x1.2538e3f23ffd7cdp-4 : inexact-ok
= acosh downward m68k96 0x1.00a8p+0 : 0x1.2538e3f23ffd7ccep-4 : inexact-ok
= acosh tonearest m68k96 0x1.00a8p+0 : 0x1.2538e3f23ffd7cdp-4 : inexact-ok
= acosh towardzero m68k96 0x1.00a8p+0 : 0x1.2538e3f23ffd7ccep-4 : inexact-ok
= acosh upward m68k96 0x1.00a8p+0 : 0x1.2538e3f23ffd7cdp-4 : inexact-ok
= acosh downward binary128 0x1.00a8p+0 : 0x1.2538e3f23ffd7ccf0ff985097484p-4 : inexact-ok
= acosh tonearest binary128 0x1.00a8p+0 : 0x1.2538e3f23ffd7ccf0ff985097485p-4 : inexact-ok
= acosh towardzero binary128 0x1.00a8p+0 : 0x1.2538e3f23ffd7ccf0ff985097484p-4 : inexact-ok
= acosh upward binary128 0x1.00a8p+0 : 0x1.2538e3f23ffd7ccf0ff985097485p-4 : inexact-ok
= acosh downward ibm128 0x1.00a8p+0 : 0x1.2538e3f23ffd7ccf0ff98509748p-4 : inexact-ok
= acosh tonearest ibm128 0x1.00a8p+0 : 0x1.2538e3f23ffd7ccf0ff98509748p-4 : inexact-ok
= acosh towardzero ibm128 0x1.00a8p+0 : 0x1.2538e3f23ffd7ccf0ff98509748p-4 : inexact-ok
= acosh upward ibm128 0x1.00a8p+0 : 0x1.2538e3f23ffd7ccf0ff9850975p-4 : inexact-ok
= acosh downward binary64 0x1.00a800422847ap+0 : 0x1.25391da7f5afep-4 : inexact-ok
= acosh tonearest binary64 0x1.00a800422847ap+0 : 0x1.25391da7f5affp-4 : inexact-ok
= acosh towardzero binary64 0x1.00a800422847ap+0 : 0x1.25391da7f5afep-4 : inexact-ok
= acosh upward binary64 0x1.00a800422847ap+0 : 0x1.25391da7f5affp-4 : inexact-ok
= acosh downward intel96 0x1.00a800422847ap+0 : 0x1.25391da7f5afeffep-4 : inexact-ok
= acosh tonearest intel96 0x1.00a800422847ap+0 : 0x1.25391da7f5affp-4 : inexact-ok
= acosh towardzero intel96 0x1.00a800422847ap+0 : 0x1.25391da7f5afeffep-4 : inexact-ok
= acosh upward intel96 0x1.00a800422847ap+0 : 0x1.25391da7f5affp-4 : inexact-ok
= acosh downward m68k96 0x1.00a800422847ap+0 : 0x1.25391da7f5afeffep-4 : inexact-ok
= acosh tonearest m68k96 0x1.00a800422847ap+0 : 0x1.25391da7f5affp-4 : inexact-ok
= acosh towardzero m68k96 0x1.00a800422847ap+0 : 0x1.25391da7f5afeffep-4 : inexact-ok
= acosh upward m68k96 0x1.00a800422847ap+0 : 0x1.25391da7f5affp-4 : inexact-ok
= acosh downward binary128 0x1.00a800422847ap+0 : 0x1.25391da7f5afeffff5588ec04ec3p-4 : inexact-ok
= acosh tonearest binary128 0x1.00a800422847ap+0 : 0x1.25391da7f5afeffff5588ec04ec3p-4 : inexact-ok
= acosh towardzero binary128 0x1.00a800422847ap+0 : 0x1.25391da7f5afeffff5588ec04ec3p-4 : inexact-ok
= acosh upward binary128 0x1.00a800422847ap+0 : 0x1.25391da7f5afeffff5588ec04ec4p-4 : inexact-ok
= acosh downward ibm128 0x1.00a800422847ap+0 : 0x1.25391da7f5afeffff5588ec04e8p-4 : inexact-ok
= acosh tonearest ibm128 0x1.00a800422847ap+0 : 0x1.25391da7f5afeffff5588ec04fp-4 : inexact-ok
= acosh towardzero ibm128 0x1.00a800422847ap+0 : 0x1.25391da7f5afeffff5588ec04e8p-4 : inexact-ok
= acosh upward ibm128 0x1.00a800422847ap+0 : 0x1.25391da7f5afeffff5588ec04fp-4 : inexact-ok
acosh 0x1.00a8178044ea8p+0
= acosh downward binary32 0x1.00a818p+0 : 0x1.254dd2p-4 : inexact-ok
= acosh tonearest binary32 0x1.00a818p+0 : 0x1.254dd2p-4 : inexact-ok
= acosh towardzero binary32 0x1.00a818p+0 : 0x1.254dd2p-4 : inexact-ok
= acosh upward binary32 0x1.00a818p+0 : 0x1.254dd4p-4 : inexact-ok
= acosh downward binary64 0x1.00a818p+0 : 0x1.254dd2afe4abcp-4 : inexact-ok
= acosh tonearest binary64 0x1.00a818p+0 : 0x1.254dd2afe4abcp-4 : inexact-ok
= acosh towardzero binary64 0x1.00a818p+0 : 0x1.254dd2afe4abcp-4 : inexact-ok
= acosh upward binary64 0x1.00a818p+0 : 0x1.254dd2afe4abdp-4 : inexact-ok
= acosh downward intel96 0x1.00a818p+0 : 0x1.254dd2afe4abc368p-4 : inexact-ok
= acosh tonearest intel96 0x1.00a818p+0 : 0x1.254dd2afe4abc36ap-4 : inexact-ok
= acosh towardzero intel96 0x1.00a818p+0 : 0x1.254dd2afe4abc368p-4 : inexact-ok
= acosh upward intel96 0x1.00a818p+0 : 0x1.254dd2afe4abc36ap-4 : inexact-ok
= acosh downward m68k96 0x1.00a818p+0 : 0x1.254dd2afe4abc368p-4 : inexact-ok
= acosh tonearest m68k96 0x1.00a818p+0 : 0x1.254dd2afe4abc36ap-4 : inexact-ok
= acosh towardzero m68k96 0x1.00a818p+0 : 0x1.254dd2afe4abc368p-4 : inexact-ok
= acosh upward m68k96 0x1.00a818p+0 : 0x1.254dd2afe4abc36ap-4 : inexact-ok
= acosh downward binary128 0x1.00a818p+0 : 0x1.254dd2afe4abc369a347f79ec4aep-4 : inexact-ok
= acosh tonearest binary128 0x1.00a818p+0 : 0x1.254dd2afe4abc369a347f79ec4aep-4 : inexact-ok
= acosh towardzero binary128 0x1.00a818p+0 : 0x1.254dd2afe4abc369a347f79ec4aep-4 : inexact-ok
= acosh upward binary128 0x1.00a818p+0 : 0x1.254dd2afe4abc369a347f79ec4afp-4 : inexact-ok
= acosh downward ibm128 0x1.00a818p+0 : 0x1.254dd2afe4abc369a347f79ec48p-4 : inexact-ok
= acosh tonearest ibm128 0x1.00a818p+0 : 0x1.254dd2afe4abc369a347f79ec48p-4 : inexact-ok
= acosh towardzero ibm128 0x1.00a818p+0 : 0x1.254dd2afe4abc369a347f79ec48p-4 : inexact-ok
= acosh upward ibm128 0x1.00a818p+0 : 0x1.254dd2afe4abc369a347f79ec5p-4 : inexact-ok
= acosh downward binary32 0x1.00a816p+0 : 0x1.254c14p-4 : inexact-ok
= acosh tonearest binary32 0x1.00a816p+0 : 0x1.254c14p-4 : inexact-ok
= acosh towardzero binary32 0x1.00a816p+0 : 0x1.254c14p-4 : inexact-ok
= acosh upward binary32 0x1.00a816p+0 : 0x1.254c16p-4 : inexact-ok
= acosh downward binary64 0x1.00a816p+0 : 0x1.254c142eb8df3p-4 : inexact-ok
= acosh tonearest binary64 0x1.00a816p+0 : 0x1.254c142eb8df4p-4 : inexact-ok
= acosh towardzero binary64 0x1.00a816p+0 : 0x1.254c142eb8df3p-4 : inexact-ok
= acosh upward binary64 0x1.00a816p+0 : 0x1.254c142eb8df4p-4 : inexact-ok
= acosh downward intel96 0x1.00a816p+0 : 0x1.254c142eb8df3b28p-4 : inexact-ok
= acosh tonearest intel96 0x1.00a816p+0 : 0x1.254c142eb8df3b2ap-4 : inexact-ok
= acosh towardzero intel96 0x1.00a816p+0 : 0x1.254c142eb8df3b28p-4 : inexact-ok
= acosh upward intel96 0x1.00a816p+0 : 0x1.254c142eb8df3b2ap-4 : inexact-ok
= acosh downward m68k96 0x1.00a816p+0 : 0x1.254c142eb8df3b28p-4 : inexact-ok
= acosh tonearest m68k96 0x1.00a816p+0 : 0x1.254c142eb8df3b2ap-4 : inexact-ok
= acosh towardzero m68k96 0x1.00a816p+0 : 0x1.254c142eb8df3b28p-4 : inexact-ok
= acosh upward m68k96 0x1.00a816p+0 : 0x1.254c142eb8df3b2ap-4 : inexact-ok
= acosh downward binary128 0x1.00a816p+0 : 0x1.254c142eb8df3b29e68dd8a9c964p-4 : inexact-ok
= acosh tonearest binary128 0x1.00a816p+0 : 0x1.254c142eb8df3b29e68dd8a9c965p-4 : inexact-ok
= acosh towardzero binary128 0x1.00a816p+0 : 0x1.254c142eb8df3b29e68dd8a9c964p-4 : inexact-ok
= acosh upward binary128 0x1.00a816p+0 : 0x1.254c142eb8df3b29e68dd8a9c965p-4 : inexact-ok
= acosh downward ibm128 0x1.00a816p+0 : 0x1.254c142eb8df3b29e68dd8a9c9p-4 : inexact-ok
= acosh tonearest ibm128 0x1.00a816p+0 : 0x1.254c142eb8df3b29e68dd8a9c98p-4 : inexact-ok
= acosh towardzero ibm128 0x1.00a816p+0 : 0x1.254c142eb8df3b29e68dd8a9c9p-4 : inexact-ok
= acosh upward ibm128 0x1.00a816p+0 : 0x1.254c142eb8df3b29e68dd8a9c98p-4 : inexact-ok
= acosh downward binary64 0x1.00a8178044ea8p+0 : 0x1.254d634bf31f8p-4 : inexact-ok
= acosh tonearest binary64 0x1.00a8178044ea8p+0 : 0x1.254d634bf31f9p-4 : inexact-ok
= acosh towardzero binary64 0x1.00a8178044ea8p+0 : 0x1.254d634bf31f8p-4 : inexact-ok
= acosh upward binary64 0x1.00a8178044ea8p+0 : 0x1.254d634bf31f9p-4 : inexact-ok
= acosh downward intel96 0x1.00a8178044ea8p+0 : 0x1.254d634bf31f8ffep-4 : inexact-ok
= acosh tonearest intel96 0x1.00a8178044ea8p+0 : 0x1.254d634bf31f9p-4 : inexact-ok
= acosh towardzero intel96 0x1.00a8178044ea8p+0 : 0x1.254d634bf31f8ffep-4 : inexact-ok
= acosh upward intel96 0x1.00a8178044ea8p+0 : 0x1.254d634bf31f9p-4 : inexact-ok
= acosh downward m68k96 0x1.00a8178044ea8p+0 : 0x1.254d634bf31f8ffep-4 : inexact-ok
= acosh tonearest m68k96 0x1.00a8178044ea8p+0 : 0x1.254d634bf31f9p-4 : inexact-ok
= acosh towardzero m68k96 0x1.00a8178044ea8p+0 : 0x1.254d634bf31f8ffep-4 : inexact-ok
= acosh upward m68k96 0x1.00a8178044ea8p+0 : 0x1.254d634bf31f9p-4 : inexact-ok
= acosh downward binary128 0x1.00a8178044ea8p+0 : 0x1.254d634bf31f8ffffd7678c63336p-4 : inexact-ok
= acosh tonearest binary128 0x1.00a8178044ea8p+0 : 0x1.254d634bf31f8ffffd7678c63337p-4 : inexact-ok
= acosh towardzero binary128 0x1.00a8178044ea8p+0 : 0x1.254d634bf31f8ffffd7678c63336p-4 : inexact-ok
= acosh upward binary128 0x1.00a8178044ea8p+0 : 0x1.254d634bf31f8ffffd7678c63337p-4 : inexact-ok
= acosh downward ibm128 0x1.00a8178044ea8p+0 : 0x1.254d634bf31f8ffffd7678c633p-4 : inexact-ok
= acosh tonearest ibm128 0x1.00a8178044ea8p+0 : 0x1.254d634bf31f8ffffd7678c633p-4 : inexact-ok
= acosh towardzero ibm128 0x1.00a8178044ea8p+0 : 0x1.254d634bf31f8ffffd7678c633p-4 : inexact-ok
= acosh upward ibm128 0x1.00a8178044ea8p+0 : 0x1.254d634bf31f8ffffd7678c6338p-4 : inexact-ok
acosh 0x1.00a83624f0d22p+0
= acosh downward binary32 0x1.00a838p+0 : 0x1.2569b8p-4 : inexact-ok
= acosh tonearest binary32 0x1.00a838p+0 : 0x1.2569bap-4 : inexact-ok
= acosh towardzero binary32 0x1.00a838p+0 : 0x1.2569b8p-4 : inexact-ok
= acosh upward binary32 0x1.00a838p+0 : 0x1.2569bap-4 : inexact-ok
= acosh downward binary64 0x1.00a838p+0 : 0x1.2569b9590b2e1p-4 : inexact-ok
= acosh tonearest binary64 0x1.00a838p+0 : 0x1.2569b9590b2e1p-4 : inexact-ok
= acosh towardzero binary64 0x1.00a838p+0 : 0x1.2569b9590b2e1p-4 : inexact-ok
= acosh upward binary64 0x1.00a838p+0 : 0x1.2569b9590b2e2p-4 : inexact-ok
= acosh downward intel96 0x1.00a838p+0 : 0x1.2569b9590b2e1096p-4 : inexact-ok
= acosh tonearest intel96 0x1.00a838p+0 : 0x1.2569b9590b2e1096p-4 : inexact-ok
= acosh towardzero intel96 0x1.00a838p+0 : 0x1.2569b9590b2e1096p-4 : inexact-ok
= acosh upward intel96 0x1.00a838p+0 : 0x1.2569b9590b2e1098p-4 : inexact-ok
= acosh downward m68k96 0x1.00a838p+0 : 0x1.2569b9590b2e1096p-4 : inexact-ok
= acosh tonearest m68k96 0x1.00a838p+0 : 0x1.2569b9590b2e1096p-4 : inexact-ok
= acosh towardzero m68k96 0x1.00a838p+0 : 0x1.2569b9590b2e1096p-4 : inexact-ok
= acosh upward m68k96 0x1.00a838p+0 : 0x1.2569b9590b2e1098p-4 : inexact-ok
= acosh downward binary128 0x1.00a838p+0 : 0x1.2569b9590b2e10963d32504660d8p-4 : inexact-ok
= acosh tonearest binary128 0x1.00a838p+0 : 0x1.2569b9590b2e10963d32504660d8p-4 : inexact-ok
= acosh towardzero binary128 0x1.00a838p+0 : 0x1.2569b9590b2e10963d32504660d8p-4 : inexact-ok
= acosh upward binary128 0x1.00a838p+0 : 0x1.2569b9590b2e10963d32504660d9p-4 : inexact-ok
= acosh downward ibm128 0x1.00a838p+0 : 0x1.2569b9590b2e10963d325046608p-4 : inexact-ok
= acosh tonearest ibm128 0x1.00a838p+0 : 0x1.2569b9590b2e10963d32504661p-4 : inexact-ok
= acosh towardzero ibm128 0x1.00a838p+0 : 0x1.2569b9590b2e10963d325046608p-4 : inexact-ok
= acosh upward ibm128 0x1.00a838p+0 : 0x1.2569b9590b2e10963d32504661p-4 : inexact-ok
= acosh downward binary32 0x1.00a836p+0 : 0x1.2567fap-4 : inexact-ok
= acosh tonearest binary32 0x1.00a836p+0 : 0x1.2567fcp-4 : inexact-ok
= acosh towardzero binary32 0x1.00a836p+0 : 0x1.2567fap-4 : inexact-ok
= acosh upward binary32 0x1.00a836p+0 : 0x1.2567fcp-4 : inexact-ok
= acosh downward binary64 0x1.00a836p+0 : 0x1.2567fb0267a27p-4 : inexact-ok
= acosh tonearest binary64 0x1.00a836p+0 : 0x1.2567fb0267a28p-4 : inexact-ok
= acosh towardzero binary64 0x1.00a836p+0 : 0x1.2567fb0267a27p-4 : inexact-ok
= acosh upward binary64 0x1.00a836p+0 : 0x1.2567fb0267a28p-4 : inexact-ok
= acosh downward intel96 0x1.00a836p+0 : 0x1.2567fb0267a27982p-4 : inexact-ok
= acosh tonearest intel96 0x1.00a836p+0 : 0x1.2567fb0267a27984p-4 : inexact-ok
= acosh towardzero intel96 0x1.00a836p+0 : 0x1.2567fb0267a27982p-4 : inexact-ok
= acosh upward intel96 0x1.00a836p+0 : 0x1.2567fb0267a27984p-4 : inexact-ok
= acosh downward m68k96 0x1.00a836p+0 : 0x1.2567fb0267a27982p-4 : inexact-ok
= acosh tonearest m68k96 0x1.00a836p+0 : 0x1.2567fb0267a27984p-4 : inexact-ok
= acosh towardzero m68k96 0x1.00a836p+0 : 0x1.2567fb0267a27982p-4 : inexact-ok
= acosh upward m68k96 0x1.00a836p+0 : 0x1.2567fb0267a27984p-4 : inexact-ok
= acosh downward binary128 0x1.00a836p+0 : 0x1.2567fb0267a279837a43548c4aep-4 : inexact-ok
= acosh tonearest binary128 0x1.00a836p+0 : 0x1.2567fb0267a279837a43548c4aep-4 : inexact-ok
= acosh towardzero binary128 0x1.00a836p+0 : 0x1.2567fb0267a279837a43548c4aep-4 : inexact-ok
= acosh upward binary128 0x1.00a836p+0 : 0x1.2567fb0267a279837a43548c4ae1p-4 : inexact-ok
= acosh downward ibm128 0x1.00a836p+0 : 0x1.2567fb0267a279837a43548c4a8p-4 : inexact-ok
= acosh tonearest ibm128 0x1.00a836p+0 : 0x1.2567fb0267a279837a43548c4bp-4 : inexact-ok
= acosh towardzero ibm128 0x1.00a836p+0 : 0x1.2567fb0267a279837a43548c4a8p-4 : inexact-ok
= acosh upward ibm128 0x1.00a836p+0 : 0x1.2567fb0267a279837a43548c4bp-4 : inexact-ok
= acosh downward binary64 0x1.00a83624f0d22p+0 : 0x1.25681b3685b06p-4 : inexact-ok
= acosh tonearest binary64 0x1.00a83624f0d22p+0 : 0x1.25681b3685b07p-4 : inexact-ok
= acosh towardzero binary64 0x1.00a83624f0d22p+0 : 0x1.25681b3685b06p-4 : inexact-ok
= acosh upward binary64 0x1.00a83624f0d22p+0 : 0x1.25681b3685b07p-4 : inexact-ok
= acosh downward intel96 0x1.00a83624f0d22p+0 : 0x1.25681b3685b06ffep-4 : inexact-ok
= acosh tonearest intel96 0x1.00a83624f0d22p+0 : 0x1.25681b3685b07p-4 : inexact-ok
= acosh towardzero intel96 0x1.00a83624f0d22p+0 : 0x1.25681b3685b06ffep-4 : inexact-ok
= acosh upward intel96 0x1.00a83624f0d22p+0 : 0x1.25681b3685b07p-4 : inexact-ok
= acosh downward m68k96 0x1.00a83624f0d22p+0 : 0x1.25681b3685b06ffep-4 : inexact-ok
= acosh tonearest m68k96 0x1.00a83624f0d22p+0 : 0x1.25681b3685b07p-4 : inexact-ok
= acosh towardzero m68k96 0x1.00a83624f0d22p+0 : 0x1.25681b3685b06ffep-4 : inexact-ok
= acosh upward m68k96 0x1.00a83624f0d22p+0 : 0x1.25681b3685b07p-4 : inexact-ok
= acosh downward binary128 0x1.00a83624f0d22p+0 : 0x1.25681b3685b06ffff10bb87a98f9p-4 : inexact-ok
= acosh tonearest binary128 0x1.00a83624f0d22p+0 : 0x1.25681b3685b06ffff10bb87a98f9p-4 : inexact-ok
= acosh towardzero binary128 0x1.00a83624f0d22p+0 : 0x1.25681b3685b06ffff10bb87a98f9p-4 : inexact-ok
= acosh upward binary128 0x1.00a83624f0d22p+0 : 0x1.25681b3685b06ffff10bb87a98fap-4 : inexact-ok
= acosh downward ibm128 0x1.00a83624f0d22p+0 : 0x1.25681b3685b06ffff10bb87a988p-4 : inexact-ok
= acosh tonearest ibm128 0x1.00a83624f0d22p+0 : 0x1.25681b3685b06ffff10bb87a99p-4 : inexact-ok
= acosh towardzero ibm128 0x1.00a83624f0d22p+0 : 0x1.25681b3685b06ffff10bb87a988p-4 : inexact-ok
= acosh upward ibm128 0x1.00a83624f0d22p+0 : 0x1.25681b3685b06ffff10bb87a99p-4 : inexact-ok
acosh 0x1.00a851f655836p+0
= acosh downward binary32 0x1.00a852p+0 : 0x1.258062p-4 : inexact-ok
= acosh tonearest binary32 0x1.00a852p+0 : 0x1.258062p-4 : inexact-ok
= acosh towardzero binary32 0x1.00a852p+0 : 0x1.258062p-4 : inexact-ok
= acosh upward binary32 0x1.00a852p+0 : 0x1.258064p-4 : inexact-ok
= acosh downward binary64 0x1.00a852p+0 : 0x1.258062cda836ap-4 : inexact-ok
= acosh tonearest binary64 0x1.00a852p+0 : 0x1.258062cda836bp-4 : inexact-ok
= acosh towardzero binary64 0x1.00a852p+0 : 0x1.258062cda836ap-4 : inexact-ok
= acosh upward binary64 0x1.00a852p+0 : 0x1.258062cda836bp-4 : inexact-ok
= acosh downward intel96 0x1.00a852p+0 : 0x1.258062cda836ac4ap-4 : inexact-ok
= acosh tonearest intel96 0x1.00a852p+0 : 0x1.258062cda836ac4ap-4 : inexact-ok
= acosh towardzero intel96 0x1.00a852p+0 : 0x1.258062cda836ac4ap-4 : inexact-ok
= acosh upward intel96 0x1.00a852p+0 : 0x1.258062cda836ac4cp-4 : inexact-ok
= acosh downward m68k96 0x1.00a852p+0 : 0x1.258062cda836ac4ap-4 : inexact-ok
= acosh tonearest m68k96 0x1.00a852p+0 : 0x1.258062cda836ac4ap-4 : inexact-ok
= acosh towardzero m68k96 0x1.00a852p+0 : 0x1.258062cda836ac4ap-4 : inexact-ok
= acosh upward m68k96 0x1.00a852p+0 : 0x1.258062cda836ac4cp-4 : inexact-ok
= acosh downward binary128 0x1.00a852p+0 : 0x1.258062cda836ac4af0ffef2d90ecp-4 : inexact-ok
= acosh tonearest binary128 0x1.00a852p+0 : 0x1.258062cda836ac4af0ffef2d90ecp-4 : inexact-ok
= acosh towardzero binary128 0x1.00a852p+0 : 0x1.258062cda836ac4af0ffef2d90ecp-4 : inexact-ok
= acosh upward binary128 0x1.00a852p+0 : 0x1.258062cda836ac4af0ffef2d90edp-4 : inexact-ok
= acosh downward ibm128 0x1.00a852p+0 : 0x1.258062cda836ac4af0ffef2d908p-4 : inexact-ok
= acosh tonearest ibm128 0x1.00a852p+0 : 0x1.258062cda836ac4af0ffef2d91p-4 : inexact-ok
= acosh towardzero ibm128 0x1.00a852p+0 : 0x1.258062cda836ac4af0ffef2d908p-4 : inexact-ok
= acosh upward ibm128 0x1.00a852p+0 : 0x1.258062cda836ac4af0ffef2d91p-4 : inexact-ok
= acosh downward binary32 0x1.00a85p+0 : 0x1.257ea4p-4 : inexact-ok
= acosh tonearest binary32 0x1.00a85p+0 : 0x1.257ea4p-4 : inexact-ok
= acosh towardzero binary32 0x1.00a85p+0 : 0x1.257ea4p-4 : inexact-ok
= acosh upward binary32 0x1.00a85p+0 : 0x1.257ea6p-4 : inexact-ok
= acosh downward binary64 0x1.00a85p+0 : 0x1.257ea4998a721p-4 : inexact-ok
= acosh tonearest binary64 0x1.00a85p+0 : 0x1.257ea4998a721p-4 : inexact-ok
= acosh towardzero binary64 0x1.00a85p+0 : 0x1.257ea4998a721p-4 : inexact-ok
= acosh upward binary64 0x1.00a85p+0 : 0x1.257ea4998a722p-4 : inexact-ok
= acosh downward intel96 0x1.00a85p+0 : 0x1.257ea4998a7216dcp-4 : inexact-ok
= acosh tonearest intel96 0x1.00a85p+0 : 0x1.257ea4998a7216dcp-4 : inexact-ok
= acosh towardzero intel96 0x1.00a85p+0 : 0x1.257ea4998a7216dcp-4 : inexact-ok
= acosh upward intel96 0x1.00a85p+0 : 0x1.257ea4998a7216dep-4 : inexact-ok
= acosh downward m68k96 0x1.00a85p+0 : 0x1.257ea4998a7216dcp-4 : inexact-ok
= acosh tonearest m68k96 0x1.00a85p+0 : 0x1.257ea4998a7216dcp-4 : inexact-ok
= acosh towardzero m68k96 0x1.00a85p+0 : 0x1.257ea4998a7216dcp-4 : inexact-ok
= acosh upward m68k96 0x1.00a85p+0 : 0x1.257ea4998a7216dep-4 : inexact-ok
= acosh downward binary128 0x1.00a85p+0 : 0x1.257ea4998a7216dc12b55701ecccp-4 : inexact-ok
= acosh tonearest binary128 0x1.00a85p+0 : 0x1.257ea4998a7216dc12b55701eccdp-4 : inexact-ok
= acosh towardzero binary128 0x1.00a85p+0 : 0x1.257ea4998a7216dc12b55701ecccp-4 : inexact-ok
= acosh upward binary128 0x1.00a85p+0 : 0x1.257ea4998a7216dc12b55701eccdp-4 : inexact-ok
= acosh downward ibm128 0x1.00a85p+0 : 0x1.257ea4998a7216dc12b55701ec8p-4 : inexact-ok
= acosh tonearest ibm128 0x1.00a85p+0 : 0x1.257ea4998a7216dc12b55701edp-4 : inexact-ok
= acosh towardzero ibm128 0x1.00a85p+0 : 0x1.257ea4998a7216dc12b55701ec8p-4 : inexact-ok
= acosh upward ibm128 0x1.00a85p+0 : 0x1.257ea4998a7216dc12b55701edp-4 : inexact-ok
= acosh downward binary64 0x1.00a851f655836p+0 : 0x1.25805a613011cp-4 : inexact-ok
= acosh tonearest binary64 0x1.00a851f655836p+0 : 0x1.25805a613011dp-4 : inexact-ok
= acosh towardzero binary64 0x1.00a851f655836p+0 : 0x1.25805a613011cp-4 : inexact-ok
= acosh upward binary64 0x1.00a851f655836p+0 : 0x1.25805a613011dp-4 : inexact-ok
= acosh downward intel96 0x1.00a851f655836p+0 : 0x1.25805a613011cffep-4 : inexact-ok
= acosh tonearest intel96 0x1.00a851f655836p+0 : 0x1.25805a613011dp-4 : inexact-ok
= acosh towardzero intel96 0x1.00a851f655836p+0 : 0x1.25805a613011cffep-4 : inexact-ok
= acosh upward intel96 0x1.00a851f655836p+0 : 0x1.25805a613011dp-4 : inexact-ok
= acosh downward m68k96 0x1.00a851f655836p+0 : 0x1.25805a613011cffep-4 : inexact-ok
= acosh tonearest m68k96 0x1.00a851f655836p+0 : 0x1.25805a613011dp-4 : inexact-ok
= acosh towardzero m68k96 0x1.00a851f655836p+0 : 0x1.25805a613011cffep-4 : inexact-ok
= acosh upward m68k96 0x1.00a851f655836p+0 : 0x1.25805a613011dp-4 : inexact-ok
= acosh downward binary128 0x1.00a851f655836p+0 : 0x1.25805a613011cffffb720f641d22p-4 : inexact-ok
= acosh tonearest binary128 0x1.00a851f655836p+0 : 0x1.25805a613011cffffb720f641d22p-4 : inexact-ok
= acosh towardzero binary128 0x1.00a851f655836p+0 : 0x1.25805a613011cffffb720f641d22p-4 : inexact-ok
= acosh upward binary128 0x1.00a851f655836p+0 : 0x1.25805a613011cffffb720f641d23p-4 : inexact-ok
= acosh downward ibm128 0x1.00a851f655836p+0 : 0x1.25805a613011cffffb720f641dp-4 : inexact-ok
= acosh tonearest ibm128 0x1.00a851f655836p+0 : 0x1.25805a613011cffffb720f641dp-4 : inexact-ok
= acosh towardzero ibm128 0x1.00a851f655836p+0 : 0x1.25805a613011cffffb720f641dp-4 : inexact-ok
= acosh upward ibm128 0x1.00a851f655836p+0 : 0x1.25805a613011cffffb720f641d8p-4 : inexact-ok
acosh 0x1.00a86ce6bcfb9p+0
= acosh downward binary32 0x1.00a86ep+0 : 0x1.2598c8p-4 : inexact-ok
= acosh tonearest binary32 0x1.00a86ep+0 : 0x1.2598c8p-4 : inexact-ok
= acosh towardzero binary32 0x1.00a86ep+0 : 0x1.2598c8p-4 : inexact-ok
= acosh upward binary32 0x1.00a86ep+0 : 0x1.2598cap-4 : inexact-ok
= acosh downward binary64 0x1.00a86ep+0 : 0x1.2598c890ab32bp-4 : inexact-ok
= acosh tonearest binary64 0x1.00a86ep+0 : 0x1.2598c890ab32bp-4 : inexact-ok
= acosh towardzero binary64 0x1.00a86ep+0 : 0x1.2598c890ab32bp-4 : inexact-ok
= acosh upward binary64 0x1.00a86ep+0 : 0x1.2598c890ab32cp-4 : inexact-ok
= acosh downward intel96 0x1.00a86ep+0 : 0x1.2598c890ab32b25p-4 : inexact-ok
= acosh tonearest intel96 0x1.00a86ep+0 : 0x1.2598c890ab32b252p-4 : inexact-ok
= acosh towardzero intel96 0x1.00a86ep+0 : 0x1.2598c890ab32b25p-4 : inexact-ok
= acosh upward intel96 0x1.00a86ep+0 : 0x1.2598c890ab32b252p-4 : inexact-ok
= acosh downward m68k96 0x1.00a86ep+0 : 0x1.2598c890ab32b25p-4 : inexact-ok
= acosh tonearest m68k96 0x1.00a86ep+0 : 0x1.2598c890ab32b252p-4 : inexact-ok
= acosh towardzero m68k96 0x1.00a86ep+0 : 0x1.2598c890ab32b25p-4 : inexact-ok
= acosh upward m68k96 0x1.00a86ep+0 : 0x1.2598c890ab32b252p-4 : inexact-ok
= acosh downward binary128 0x1.00a86ep+0 : 0x1.2598c890ab32b25108ca3547d702p-4 : inexact-ok
= acosh tonearest binary128 0x1.00a86ep+0 : 0x1.2598c890ab32b25108ca3547d703p-4 : inexact-ok
= acosh towardzero binary128 0x1.00a86ep+0 : 0x1.2598c890ab32b25108ca3547d702p-4 : inexact-ok
= acosh upward binary128 0x1.00a86ep+0 : 0x1.2598c890ab32b25108ca3547d703p-4 : inexact-ok
= acosh downward ibm128 0x1.00a86ep+0 : 0x1.2598c890ab32b25108ca3547d7p-4 : inexact-ok
= acosh tonearest ibm128 0x1.00a86ep+0 : 0x1.2598c890ab32b25108ca3547d7p-4 : inexact-ok
= acosh towardzero ibm128 0x1.00a86ep+0 : 0x1.2598c890ab32b25108ca3547d7p-4 : inexact-ok
= acosh upward ibm128 0x1.00a86ep+0 : 0x1.2598c890ab32b25108ca3547d78p-4 : inexact-ok
= acosh downward binary32 0x1.00a86cp+0 : 0x1.25970ap-4 : inexact-ok
= acosh tonearest binary32 0x1.00a86cp+0 : 0x1.25970ap-4 : inexact-ok
= acosh towardzero binary32 0x1.00a86cp+0 : 0x1.25970ap-4 : inexact-ok
= acosh upward binary32 0x1.00a86cp+0 : 0x1.25970cp-4 : inexact-ok
= acosh downward binary64 0x1.00a86cp+0 : 0x1.25970a81b2195p-4 : inexact-ok
= acosh tonearest binary64 0x1.00a86cp+0 : 0x1.25970a81b2195p-4 : inexact-ok
= acosh towardzero binary64 0x1.00a86cp+0 : 0x1.25970a81b2195p-4 : inexact-ok
= acosh upward binary64 0x1.00a86cp+0 : 0x1.25970a81b2196p-4 : inexact-ok
= acosh downward intel96 0x1.00a86cp+0 : 0x1.25970a81b219568ap-4 : inexact-ok
= acosh tonearest intel96 0x1.00a86cp+0 : 0x1.25970a81b219568cp-4 : inexact-ok
= acosh towardzero intel96 0x1.00a86cp+0 : 0x1.25970a81b219568ap-4 : inexact-ok
= acosh upward intel96 0x1.00a86cp+0 : 0x1.25970a81b219568cp-4 : inexact-ok
= acosh downward m68k96 0x1.00a86cp+0 : 0x1.25970a81b219568ap-4 : inexact-ok
= acosh tonearest m68k96 0x1.00a86cp+0 : 0x1.25970a81b219568cp-4 : inexact-ok
= acosh towardzero m68k96 0x1.00a86cp+0 : 0x1.25970a81b219568ap-4 : inexact-ok
= acosh upward m68k96 0x1.00a86cp+0 : 0x1.25970a81b219568cp-4 : inexact-ok
= acosh downward binary128 0x1.00a86cp+0 : 0x1.25970a81b219568b204e54ff9b22p-4 : inexact-ok
= acosh tonearest binary128 0x1.00a86cp+0 : 0x1.25970a81b219568b204e54ff9b23p-4 : inexact-ok
= acosh towardzero binary128 0x1.00a86cp+0 : 0x1.25970a81b219568b204e54ff9b22p-4 : inexact-ok
= acosh upward binary128 0x1.00a86cp+0 : 0x1.25970a81b219568b204e54ff9b23p-4 : inexact-ok
= acosh downward ibm128 0x1.00a86cp+0 : 0x1.25970a81b219568b204e54ff9bp-4 : inexact-ok
= acosh tonearest ibm128 0x1.00a86cp+0 : 0x1.25970a81b219568b204e54ff9bp-4 : inexact-ok
= acosh towardzero ibm128 0x1.00a86cp+0 : 0x1.25970a81b219568b204e54ff9bp-4 : inexact-ok
= acosh upward ibm128 0x1.00a86cp+0 : 0x1.25970a81b219568b204e54ff9b8p-4 : inexact-ok
= acosh downward binary64 0x1.00a86ce6bcfb9p+0 : 0x1.2597d38764b0fp-4 : inexact-ok
= acosh tonearest binary64 0x1.00a86ce6bcfb9p+0 : 0x1.2597d38764b1p-4 : inexact-ok
= acosh towardzero binary64 0x1.00a86ce6bcfb9p+0 : 0x1.2597d38764b0fp-4 : inexact-ok
= acosh upward binary64 0x1.00a86ce6bcfb9p+0 : 0x1.2597d38764b1p-4 : inexact-ok
= acosh downward intel96 0x1.00a86ce6bcfb9p+0 : 0x1.2597d38764b0fffep-4 : inexact-ok
= acosh tonearest intel96 0x1.00a86ce6bcfb9p+0 : 0x1.2597d38764b1p-4 : inexact-ok
= acosh towardzero intel96 0x1.00a86ce6bcfb9p+0 : 0x1.2597d38764b0fffep-4 : inexact-ok
= acosh upward intel96 0x1.00a86ce6bcfb9p+0 : 0x1.2597d38764b1p-4 : inexact-ok
= acosh downward m68k96 0x1.00a86ce6bcfb9p+0 : 0x1.2597d38764b0fffep-4 : inexact-ok
= acosh tonearest m68k96 0x1.00a86ce6bcfb9p+0 : 0x1.2597d38764b1p-4 : inexact-ok
= acosh towardzero m68k96 0x1.00a86ce6bcfb9p+0 : 0x1.2597d38764b0fffep-4 : inexact-ok
= acosh upward m68k96 0x1.00a86ce6bcfb9p+0 : 0x1.2597d38764b1p-4 : inexact-ok
= acosh downward binary128 0x1.00a86ce6bcfb9p+0 : 0x1.2597d38764b0fffff6d235cd9cb6p-4 : inexact-ok
= acosh tonearest binary128 0x1.00a86ce6bcfb9p+0 : 0x1.2597d38764b0fffff6d235cd9cb6p-4 : inexact-ok
= acosh towardzero binary128 0x1.00a86ce6bcfb9p+0 : 0x1.2597d38764b0fffff6d235cd9cb6p-4 : inexact-ok
= acosh upward binary128 0x1.00a86ce6bcfb9p+0 : 0x1.2597d38764b0fffff6d235cd9cb7p-4 : inexact-ok
= acosh downward ibm128 0x1.00a86ce6bcfb9p+0 : 0x1.2597d38764b0fffff6d235cd9c8p-4 : inexact-ok
= acosh tonearest ibm128 0x1.00a86ce6bcfb9p+0 : 0x1.2597d38764b0fffff6d235cd9c8p-4 : inexact-ok
= acosh towardzero ibm128 0x1.00a86ce6bcfb9p+0 : 0x1.2597d38764b0fffff6d235cd9c8p-4 : inexact-ok
= acosh upward ibm128 0x1.00a86ce6bcfb9p+0 : 0x1.2597d38764b0fffff6d235cd9dp-4 : inexact-ok
acosh 0x1.00a888136de79p+0
= acosh downward binary32 0x1.00a88ap+0 : 0x1.25b12cp-4 : inexact-ok
= acosh tonearest binary32 0x1.00a88ap+0 : 0x1.25b12cp-4 : inexact-ok
= acosh towardzero binary32 0x1.00a88ap+0 : 0x1.25b12cp-4 : inexact-ok
= acosh upward binary32 0x1.00a88ap+0 : 0x1.25b12ep-4 : inexact-ok
= acosh downward binary64 0x1.00a88ap+0 : 0x1.25b12c4bf23d7p-4 : inexact-ok
= acosh tonearest binary64 0x1.00a88ap+0 : 0x1.25b12c4bf23d8p-4 : inexact-ok
= acosh towardzero binary64 0x1.00a88ap+0 : 0x1.25b12c4bf23d7p-4 : inexact-ok
= acosh upward binary64 0x1.00a88ap+0 : 0x1.25b12c4bf23d8p-4 : inexact-ok
= acosh downward intel96 0x1.00a88ap+0 : 0x1.25b12c4bf23d7efp-4 : inexact-ok
= acosh tonearest intel96 0x1.00a88ap+0 : 0x1.25b12c4bf23d7ef2p-4 : inexact-ok
= acosh towardzero intel96 0x1.00a88ap+0 : 0x1.25b12c4bf23d7efp-4 : inexact-ok
= acosh upward intel96 0x1.00a88ap+0 : 0x1.25b12c4bf23d7ef2p-4 : inexact-ok
= acosh downward m68k96 0x1.00a88ap+0 : 0x1.25b12c4bf23d7efp-4 : inexact-ok
= acosh tonearest m68k96 0x1.00a88ap+0 : 0x1.25b12c4bf23d7ef2p-4 : inexact-ok
= acosh towardzero m68k96 0x1.00a88ap+0 : 0x1.25b12c4bf23d7efp-4 : inexact-ok
= acosh upward m68k96 0x1.00a88ap+0 : 0x1.25b12c4bf23d7ef2p-4 : inexact-ok
= acosh downward binary128 0x1.00a88ap+0 : 0x1.25b12c4bf23d7ef17059706ff48ep-4 : inexact-ok
= acosh tonearest binary128 0x1.00a88ap+0 : 0x1.25b12c4bf23d7ef17059706ff48fp-4 : inexact-ok
= acosh towardzero binary128 0x1.00a88ap+0 : 0x1.25b12c4bf23d7ef17059706ff48ep-4 : inexact-ok
= acosh upward binary128 0x1.00a88ap+0 : 0x1.25b12c4bf23d7ef17059706ff48fp-4 : inexact-ok
= acosh downward ibm128 0x1.00a88ap+0 : 0x1.25b12c4bf23d7ef17059706ff48p-4 : inexact-ok
= acosh tonearest ibm128 0x1.00a88ap+0 : 0x1.25b12c4bf23d7ef17059706ff48p-4 : inexact-ok
= acosh towardzero ibm128 0x1.00a88ap+0 : 0x1.25b12c4bf23d7ef17059706ff48p-4 : inexact-ok
= acosh upward ibm128 0x1.00a88ap+0 : 0x1.25b12c4bf23d7ef17059706ff5p-4 : inexact-ok
= acosh downward binary32 0x1.00a888p+0 : 0x1.25af6ep-4 : inexact-ok
= acosh tonearest binary32 0x1.00a888p+0 : 0x1.25af6ep-4 : inexact-ok
= acosh towardzero binary32 0x1.00a888p+0 : 0x1.25af6ep-4 : inexact-ok
= acosh upward binary32 0x1.00a888p+0 : 0x1.25af7p-4 : inexact-ok
= acosh downward binary64 0x1.00a888p+0 : 0x1.25af6e62148e5p-4 : inexact-ok
= acosh tonearest binary64 0x1.00a888p+0 : 0x1.25af6e62148e6p-4 : inexact-ok
= acosh towardzero binary64 0x1.00a888p+0 : 0x1.25af6e62148e5p-4 : inexact-ok
= acosh upward binary64 0x1.00a888p+0 : 0x1.25af6e62148e6p-4 : inexact-ok
= acosh downward intel96 0x1.00a888p+0 : 0x1.25af6e62148e5e02p-4 : inexact-ok
= acosh tonearest intel96 0x1.00a888p+0 : 0x1.25af6e62148e5e04p-4 : inexact-ok
= acosh towardzero intel96 0x1.00a888p+0 : 0x1.25af6e62148e5e02p-4 : inexact-ok
= acosh upward intel96 0x1.00a888p+0 : 0x1.25af6e62148e5e04p-4 : inexact-ok
= acosh downward m68k96 0x1.00a888p+0 : 0x1.25af6e62148e5e02p-4 : inexact-ok
= acosh tonearest m68k96 0x1.00a888p+0 : 0x1.25af6e62148e5e04p-4 : inexact-ok
= acosh towardzero m68k96 0x1.00a888p+0 : 0x1.25af6e62148e5e02p-4 : inexact-ok
= acosh upward m68k96 0x1.00a888p+0 : 0x1.25af6e62148e5e04p-4 : inexact-ok
= acosh downward binary128 0x1.00a888p+0 : 0x1.25af6e62148e5e03aa03d6ce9167p-4 : inexact-ok
= acosh tonearest binary128 0x1.00a888p+0 : 0x1.25af6e62148e5e03aa03d6ce9168p-4 : inexact-ok
= acosh towardzero binary128 0x1.00a888p+0 : 0x1.25af6e62148e5e03aa03d6ce9167p-4 : inexact-ok
= acosh upward binary128 0x1.00a888p+0 : 0x1.25af6e62148e5e03aa03d6ce9168p-4 : inexact-ok
= acosh downward ibm128 0x1.00a888p+0 : 0x1.25af6e62148e5e03aa03d6ce91p-4 : inexact-ok
= acosh tonearest ibm128 0x1.00a888p+0 : 0x1.25af6e62148e5e03aa03d6ce918p-4 : inexact-ok
= acosh towardzero ibm128 0x1.00a888p+0 : 0x1.25af6e62148e5e03aa03d6ce91p-4 : inexact-ok
= acosh upward ibm128 0x1.00a888p+0 : 0x1.25af6e62148e5e03aa03d6ce918p-4 : inexact-ok
= acosh downward binary64 0x1.00a888136de79p+0 : 0x1.25af7f4e069fbp-4 : inexact-ok
= acosh tonearest binary64 0x1.00a888136de79p+0 : 0x1.25af7f4e069fcp-4 : inexact-ok
= acosh towardzero binary64 0x1.00a888136de79p+0 : 0x1.25af7f4e069fbp-4 : inexact-ok
= acosh upward binary64 0x1.00a888136de79p+0 : 0x1.25af7f4e069fcp-4 : inexact-ok
= acosh downward intel96 0x1.00a888136de79p+0 : 0x1.25af7f4e069fbffep-4 : inexact-ok
= acosh tonearest intel96 0x1.00a888136de79p+0 : 0x1.25af7f4e069fcp-4 : inexact-ok
= acosh towardzero intel96 0x1.00a888136de79p+0 : 0x1.25af7f4e069fbffep-4 : inexact-ok
= acosh upward intel96 0x1.00a888136de79p+0 : 0x1.25af7f4e069fcp-4 : inexact-ok
= acosh downward m68k96 0x1.00a888136de79p+0 : 0x1.25af7f4e069fbffep-4 : inexact-ok
= acosh tonearest m68k96 0x1.00a888136de79p+0 : 0x1.25af7f4e069fcp-4 : inexact-ok
= acosh towardzero m68k96 0x1.00a888136de79p+0 : 0x1.25af7f4e069fbffep-4 : inexact-ok
= acosh upward m68k96 0x1.00a888136de79p+0 : 0x1.25af7f4e069fcp-4 : inexact-ok
= acosh downward binary128 0x1.00a888136de79p+0 : 0x1.25af7f4e069fbffffd3099b29fe1p-4 : inexact-ok
= acosh tonearest binary128 0x1.00a888136de79p+0 : 0x1.25af7f4e069fbffffd3099b29fe2p-4 : inexact-ok
= acosh towardzero binary128 0x1.00a888136de79p+0 : 0x1.25af7f4e069fbffffd3099b29fe1p-4 : inexact-ok
= acosh upward binary128 0x1.00a888136de79p+0 : 0x1.25af7f4e069fbffffd3099b29fe2p-4 : inexact-ok
= acosh downward ibm128 0x1.00a888136de79p+0 : 0x1.25af7f4e069fbffffd3099b29f8p-4 : inexact-ok
= acosh tonearest ibm128 0x1.00a888136de79p+0 : 0x1.25af7f4e069fbffffd3099b2ap-4 : inexact-ok
= acosh towardzero ibm128 0x1.00a888136de79p+0 : 0x1.25af7f4e069fbffffd3099b29f8p-4 : inexact-ok
= acosh upward ibm128 0x1.00a888136de79p+0 : 0x1.25af7f4e069fbffffd3099b2ap-4 : inexact-ok
acosh 0x1.00a8abbf7ef1ap+0
= acosh downward binary32 0x1.00a8acp+0 : 0x1.25cec6p-4 : inexact-ok
= acosh tonearest binary32 0x1.00a8acp+0 : 0x1.25cec8p-4 : inexact-ok
= acosh towardzero binary32 0x1.00a8acp+0 : 0x1.25cec6p-4 : inexact-ok
= acosh upward binary32 0x1.00a8acp+0 : 0x1.25cec8p-4 : inexact-ok
= acosh downward binary64 0x1.00a8acp+0 : 0x1.25cec73e8065p-4 : inexact-ok
= acosh tonearest binary64 0x1.00a8acp+0 : 0x1.25cec73e80651p-4 : inexact-ok
= acosh towardzero binary64 0x1.00a8acp+0 : 0x1.25cec73e8065p-4 : inexact-ok
= acosh upward binary64 0x1.00a8acp+0 : 0x1.25cec73e80651p-4 : inexact-ok
= acosh downward intel96 0x1.00a8acp+0 : 0x1.25cec73e80650cd8p-4 : inexact-ok
= acosh tonearest intel96 0x1.00a8acp+0 : 0x1.25cec73e80650cd8p-4 : inexact-ok
= acosh towardzero intel96 0x1.00a8acp+0 : 0x1.25cec73e80650cd8p-4 : inexact-ok
= acosh upward intel96 0x1.00a8acp+0 : 0x1.25cec73e80650cdap-4 : inexact-ok
= acosh downward m68k96 0x1.00a8acp+0 : 0x1.25cec73e80650cd8p-4 : inexact-ok
= acosh tonearest m68k96 0x1.00a8acp+0 : 0x1.25cec73e80650cd8p-4 : inexact-ok
= acosh towardzero m68k96 0x1.00a8acp+0 : 0x1.25cec73e80650cd8p-4 : inexact-ok
= acosh upward m68k96 0x1.00a8acp+0 : 0x1.25cec73e80650cdap-4 : inexact-ok
= acosh downward binary128 0x1.00a8acp+0 : 0x1.25cec73e80650cd86d8df15d29efp-4 : inexact-ok
= acosh tonearest binary128 0x1.00a8acp+0 : 0x1.25cec73e80650cd86d8df15d29fp-4 : inexact-ok
= acosh towardzero binary128 0x1.00a8acp+0 : 0x1.25cec73e80650cd86d8df15d29efp-4 : inexact-ok
= acosh upward binary128 0x1.00a8acp+0 : 0x1.25cec73e80650cd86d8df15d29fp-4 : inexact-ok
= acosh downward ibm128 0x1.00a8acp+0 : 0x1.25cec73e80650cd86d8df15d298p-4 : inexact-ok
= acosh tonearest ibm128 0x1.00a8acp+0 : 0x1.25cec73e80650cd86d8df15d2ap-4 : inexact-ok
= acosh towardzero ibm128 0x1.00a8acp+0 : 0x1.25cec73e80650cd86d8df15d298p-4 : inexact-ok
= acosh upward ibm128 0x1.00a8acp+0 : 0x1.25cec73e80650cd86d8df15d2ap-4 : inexact-ok
= acosh downward binary32 0x1.00a8aap+0 : 0x1.25cd08p-4 : inexact-ok
= acosh tonearest binary32 0x1.00a8aap+0 : 0x1.25cd0ap-4 : inexact-ok
= acosh towardzero binary32 0x1.00a8aap+0 : 0x1.25cd08p-4 : inexact-ok
= acosh upward binary32 0x1.00a8aap+0 : 0x1.25cd0ap-4 : inexact-ok
= acosh downward binary64 0x1.00a8aap+0 : 0x1.25cd0981a54b9p-4 : inexact-ok
= acosh tonearest binary64 0x1.00a8aap+0 : 0x1.25cd0981a54bap-4 : inexact-ok
= acosh towardzero binary64 0x1.00a8aap+0 : 0x1.25cd0981a54b9p-4 : inexact-ok
= acosh upward binary64 0x1.00a8aap+0 : 0x1.25cd0981a54bap-4 : inexact-ok
= acosh downward intel96 0x1.00a8aap+0 : 0x1.25cd0981a54b995ap-4 : inexact-ok
= acosh tonearest intel96 0x1.00a8aap+0 : 0x1.25cd0981a54b995ap-4 : inexact-ok
= acosh towardzero intel96 0x1.00a8aap+0 : 0x1.25cd0981a54b995ap-4 : inexact-ok
= acosh upward intel96 0x1.00a8aap+0 : 0x1.25cd0981a54b995cp-4 : inexact-ok
= acosh downward m68k96 0x1.00a8aap+0 : 0x1.25cd0981a54b995ap-4 : inexact-ok
= acosh tonearest m68k96 0x1.00a8aap+0 : 0x1.25cd0981a54b995ap-4 : inexact-ok
= acosh towardzero m68k96 0x1.00a8aap+0 : 0x1.25cd0981a54b995ap-4 : inexact-ok
= acosh upward m68k96 0x1.00a8aap+0 : 0x1.25cd0981a54b995cp-4 : inexact-ok
= acosh downward binary128 0x1.00a8aap+0 : 0x1.25cd0981a54b995a643f0e3f242ap-4 : inexact-ok
= acosh tonearest binary128 0x1.00a8aap+0 : 0x1.25cd0981a54b995a643f0e3f242bp-4 : inexact-ok
= acosh towardzero binary128 0x1.00a8aap+0 : 0x1.25cd0981a54b995a643f0e3f242ap-4 : inexact-ok
= acosh upward binary128 0x1.00a8aap+0 : 0x1.25cd0981a54b995a643f0e3f242bp-4 : inexact-ok
= acosh downward ibm128 0x1.00a8aap+0 : 0x1.25cd0981a54b995a643f0e3f24p-4 : inexact-ok
= acosh tonearest ibm128 0x1.00a8aap+0 : 0x1.25cd0981a54b995a643f0e3f24p-4 : inexact-ok
= acosh towardzero ibm128 0x1.00a8aap+0 : 0x1.25cd0981a54b995a643f0e3f24p-4 : inexact-ok
= acosh upward ibm128 0x1.00a8aap+0 : 0x1.25cd0981a54b995a643f0e3f248p-4 : inexact-ok
= acosh downward binary64 0x1.00a8abbf7ef1ap+0 : 0x1.25ce8f16afb45p-4 : inexact-ok
= acosh tonearest binary64 0x1.00a8abbf7ef1ap+0 : 0x1.25ce8f16afb46p-4 : inexact-ok
= acosh towardzero binary64 0x1.00a8abbf7ef1ap+0 : 0x1.25ce8f16afb45p-4 : inexact-ok
= acosh upward binary64 0x1.00a8abbf7ef1ap+0 : 0x1.25ce8f16afb46p-4 : inexact-ok
= acosh downward intel96 0x1.00a8abbf7ef1ap+0 : 0x1.25ce8f16afb45ffep-4 : inexact-ok
= acosh tonearest intel96 0x1.00a8abbf7ef1ap+0 : 0x1.25ce8f16afb46p-4 : inexact-ok
= acosh towardzero intel96 0x1.00a8abbf7ef1ap+0 : 0x1.25ce8f16afb45ffep-4 : inexact-ok
= acosh upward intel96 0x1.00a8abbf7ef1ap+0 : 0x1.25ce8f16afb46p-4 : inexact-ok
= acosh downward m68k96 0x1.00a8abbf7ef1ap+0 : 0x1.25ce8f16afb45ffep-4 : inexact-ok
= acosh tonearest m68k96 0x1.00a8abbf7ef1ap+0 : 0x1.25ce8f16afb46p-4 : inexact-ok
= acosh towardzero m68k96 0x1.00a8abbf7ef1ap+0 : 0x1.25ce8f16afb45ffep-4 : inexact-ok
= acosh upward m68k96 0x1.00a8abbf7ef1ap+0 : 0x1.25ce8f16afb46p-4 : inexact-ok
= acosh downward binary128 0x1.00a8abbf7ef1ap+0 : 0x1.25ce8f16afb45ffffdb93830c917p-4 : inexact-ok
= acosh tonearest binary128 0x1.00a8abbf7ef1ap+0 : 0x1.25ce8f16afb45ffffdb93830c918p-4 : inexact-ok
= acosh towardzero binary128 0x1.00a8abbf7ef1ap+0 : 0x1.25ce8f16afb45ffffdb93830c917p-4 : inexact-ok
= acosh upward binary128 0x1.00a8abbf7ef1ap+0 : 0x1.25ce8f16afb45ffffdb93830c918p-4 : inexact-ok
= acosh downward ibm128 0x1.00a8abbf7ef1ap+0 : 0x1.25ce8f16afb45ffffdb93830c9p-4 : inexact-ok
= acosh tonearest ibm128 0x1.00a8abbf7ef1ap+0 : 0x1.25ce8f16afb45ffffdb93830c9p-4 : inexact-ok
= acosh towardzero ibm128 0x1.00a8abbf7ef1ap+0 : 0x1.25ce8f16afb45ffffdb93830c9p-4 : inexact-ok
= acosh upward ibm128 0x1.00a8abbf7ef1ap+0 : 0x1.25ce8f16afb45ffffdb93830c98p-4 : inexact-ok
acosh 0x1.1p+1
= acosh downward binary32 0x2.2p+0 : 0x1.62e42ep+0 : inexact-ok
= acosh tonearest binary32 0x2.2p+0 : 0x1.62e43p+0 : inexact-ok
= acosh towardzero binary32 0x2.2p+0 : 0x1.62e42ep+0 : inexact-ok
= acosh upward binary32 0x2.2p+0 : 0x1.62e43p+0 : inexact-ok
= acosh downward binary64 0x2.2p+0 : 0x1.62e42fefa39efp+0 : inexact-ok
= acosh tonearest binary64 0x2.2p+0 : 0x1.62e42fefa39efp+0 : inexact-ok
= acosh towardzero binary64 0x2.2p+0 : 0x1.62e42fefa39efp+0 : inexact-ok
= acosh upward binary64 0x2.2p+0 : 0x1.62e42fefa39fp+0 : inexact-ok
= acosh downward intel96 0x2.2p+0 : 0x1.62e42fefa39ef356p+0 : inexact-ok
= acosh tonearest intel96 0x2.2p+0 : 0x1.62e42fefa39ef358p+0 : inexact-ok
= acosh towardzero intel96 0x2.2p+0 : 0x1.62e42fefa39ef356p+0 : inexact-ok
= acosh upward intel96 0x2.2p+0 : 0x1.62e42fefa39ef358p+0 : inexact-ok
= acosh downward m68k96 0x2.2p+0 : 0x1.62e42fefa39ef356p+0 : inexact-ok
= acosh tonearest m68k96 0x2.2p+0 : 0x1.62e42fefa39ef358p+0 : inexact-ok
= acosh towardzero m68k96 0x2.2p+0 : 0x1.62e42fefa39ef356p+0 : inexact-ok
= acosh upward m68k96 0x2.2p+0 : 0x1.62e42fefa39ef358p+0 : inexact-ok
= acosh downward binary128 0x2.2p+0 : 0x1.62e42fefa39ef35793c7673007e5p+0 : inexact-ok
= acosh tonearest binary128 0x2.2p+0 : 0x1.62e42fefa39ef35793c7673007e6p+0 : inexact-ok
= acosh towardzero binary128 0x2.2p+0 : 0x1.62e42fefa39ef35793c7673007e5p+0 : inexact-ok
= acosh upward binary128 0x2.2p+0 : 0x1.62e42fefa39ef35793c7673007e6p+0 : inexact-ok
= acosh downward ibm128 0x2.2p+0 : 0x1.62e42fefa39ef35793c76730078p+0 : inexact-ok
= acosh tonearest ibm128 0x2.2p+0 : 0x1.62e42fefa39ef35793c7673008p+0 : inexact-ok
= acosh towardzero ibm128 0x2.2p+0 : 0x1.62e42fefa39ef35793c76730078p+0 : inexact-ok
= acosh upward ibm128 0x2.2p+0 : 0x1.62e42fefa39ef35793c7673008p+0 : inexact-ok
acosh 0x1.3bf8009648dcp+16
= acosh downward binary32 0x1.3bf802p+16 : 0xb.fe74bp+0 : inexact-ok
= acosh tonearest binary32 0x1.3bf802p+16 : 0xb.fe74bp+0 : inexact-ok
= acosh towardzero binary32 0x1.3bf802p+16 : 0xb.fe74bp+0 : inexact-ok
= acosh upward binary32 0x1.3bf802p+16 : 0xb.fe74cp+0 : inexact-ok
= acosh downward binary64 0x1.3bf802p+16 : 0xb.fe74b077f39ap+0 : inexact-ok
= acosh tonearest binary64 0x1.3bf802p+16 : 0xb.fe74b077f39ap+0 : inexact-ok
= acosh towardzero binary64 0x1.3bf802p+16 : 0xb.fe74b077f39ap+0 : inexact-ok
= acosh upward binary64 0x1.3bf802p+16 : 0xb.fe74b077f39a8p+0 : inexact-ok
= acosh downward intel96 0x1.3bf802p+16 : 0xb.fe74b077f39a22cp+0 : inexact-ok
= acosh tonearest intel96 0x1.3bf802p+16 : 0xb.fe74b077f39a22cp+0 : inexact-ok
= acosh towardzero intel96 0x1.3bf802p+16 : 0xb.fe74b077f39a22cp+0 : inexact-ok
= acosh upward intel96 0x1.3bf802p+16 : 0xb.fe74b077f39a22dp+0 : inexact-ok
= acosh downward m68k96 0x1.3bf802p+16 : 0xb.fe74b077f39a22cp+0 : inexact-ok
= acosh tonearest m68k96 0x1.3bf802p+16 : 0xb.fe74b077f39a22cp+0 : inexact-ok
= acosh towardzero m68k96 0x1.3bf802p+16 : 0xb.fe74b077f39a22cp+0 : inexact-ok
= acosh upward m68k96 0x1.3bf802p+16 : 0xb.fe74b077f39a22dp+0 : inexact-ok
= acosh downward binary128 0x1.3bf802p+16 : 0xb.fe74b077f39a22c0afc2891cc05p+0 : inexact-ok
= acosh tonearest binary128 0x1.3bf802p+16 : 0xb.fe74b077f39a22c0afc2891cc058p+0 : inexact-ok
= acosh towardzero binary128 0x1.3bf802p+16 : 0xb.fe74b077f39a22c0afc2891cc05p+0 : inexact-ok
= acosh upward binary128 0x1.3bf802p+16 : 0xb.fe74b077f39a22c0afc2891cc058p+0 : inexact-ok
= acosh downward ibm128 0x1.3bf802p+16 : 0xb.fe74b077f39a22c0afc2891ccp+0 : inexact-ok
= acosh tonearest ibm128 0x1.3bf802p+16 : 0xb.fe74b077f39a22c0afc2891ccp+0 : inexact-ok
= acosh towardzero ibm128 0x1.3bf802p+16 : 0xb.fe74b077f39a22c0afc2891ccp+0 : inexact-ok
= acosh upward ibm128 0x1.3bf802p+16 : 0xb.fe74b077f39a22c0afc2891cc4p+0 : inexact-ok
= acosh downward binary32 0x1.3bf8p+16 : 0xb.fe74ap+0 : inexact-ok
= acosh tonearest binary32 0x1.3bf8p+16 : 0xb.fe74bp+0 : inexact-ok
= acosh towardzero binary32 0x1.3bf8p+16 : 0xb.fe74ap+0 : inexact-ok
= acosh upward binary32 0x1.3bf8p+16 : 0xb.fe74bp+0 : inexact-ok
= acosh downward binary64 0x1.3bf8p+16 : 0xb.fe74aed920318p+0 : inexact-ok
= acosh tonearest binary64 0x1.3bf8p+16 : 0xb.fe74aed920318p+0 : inexact-ok
= acosh towardzero binary64 0x1.3bf8p+16 : 0xb.fe74aed920318p+0 : inexact-ok
= acosh upward binary64 0x1.3bf8p+16 : 0xb.fe74aed92032p+0 : inexact-ok
= acosh downward intel96 0x1.3bf8p+16 : 0xb.fe74aed92031a37p+0 : inexact-ok
= acosh tonearest intel96 0x1.3bf8p+16 : 0xb.fe74aed92031a38p+0 : inexact-ok
= acosh towardzero intel96 0x1.3bf8p+16 : 0xb.fe74aed92031a37p+0 : inexact-ok
= acosh upward intel96 0x1.3bf8p+16 : 0xb.fe74aed92031a38p+0 : inexact-ok
= acosh downward m68k96 0x1.3bf8p+16 : 0xb.fe74aed92031a37p+0 : inexact-ok
= acosh tonearest m68k96 0x1.3bf8p+16 : 0xb.fe74aed92031a38p+0 : inexact-ok
= acosh towardzero m68k96 0x1.3bf8p+16 : 0xb.fe74aed92031a37p+0 : inexact-ok
= acosh upward m68k96 0x1.3bf8p+16 : 0xb.fe74aed92031a38p+0 : inexact-ok
= acosh downward binary128 0x1.3bf8p+16 : 0xb.fe74aed92031a37c22a37edd14fp+0 : inexact-ok
= acosh tonearest binary128 0x1.3bf8p+16 : 0xb.fe74aed92031a37c22a37edd14f8p+0 : inexact-ok
= acosh towardzero binary128 0x1.3bf8p+16 : 0xb.fe74aed92031a37c22a37edd14fp+0 : inexact-ok
= acosh upward binary128 0x1.3bf8p+16 : 0xb.fe74aed92031a37c22a37edd14f8p+0 : inexact-ok
= acosh downward ibm128 0x1.3bf8p+16 : 0xb.fe74aed92031a37c22a37edd14p+0 : inexact-ok
= acosh tonearest ibm128 0x1.3bf8p+16 : 0xb.fe74aed92031a37c22a37edd14p+0 : inexact-ok
= acosh towardzero ibm128 0x1.3bf8p+16 : 0xb.fe74aed92031a37c22a37edd14p+0 : inexact-ok
= acosh upward ibm128 0x1.3bf8p+16 : 0xb.fe74aed92031a37c22a37edd18p+0 : inexact-ok
= acosh downward binary64 0x1.3bf8009648dcp+16 : 0xb.fe74af52e329p+0 : inexact-ok
= acosh tonearest binary64 0x1.3bf8009648dcp+16 : 0xb.fe74af52e3298p+0 : inexact-ok
= acosh towardzero binary64 0x1.3bf8009648dcp+16 : 0xb.fe74af52e329p+0 : inexact-ok
= acosh upward binary64 0x1.3bf8009648dcp+16 : 0xb.fe74af52e3298p+0 : inexact-ok
= acosh downward intel96 0x1.3bf8009648dcp+16 : 0xb.fe74af52e3297ffp+0 : inexact-ok
= acosh tonearest intel96 0x1.3bf8009648dcp+16 : 0xb.fe74af52e3298p+0 : inexact-ok
= acosh towardzero intel96 0x1.3bf8009648dcp+16 : 0xb.fe74af52e3297ffp+0 : inexact-ok
= acosh upward intel96 0x1.3bf8009648dcp+16 : 0xb.fe74af52e3298p+0 : inexact-ok
= acosh downward m68k96 0x1.3bf8009648dcp+16 : 0xb.fe74af52e3297ffp+0 : inexact-ok
= acosh tonearest m68k96 0x1.3bf8009648dcp+16 : 0xb.fe74af52e3298p+0 : inexact-ok
= acosh towardzero m68k96 0x1.3bf8009648dcp+16 : 0xb.fe74af52e3297ffp+0 : inexact-ok
= acosh upward m68k96 0x1.3bf8009648dcp+16 : 0xb.fe74af52e3298p+0 : inexact-ok
= acosh downward binary128 0x1.3bf8009648dcp+16 : 0xb.fe74af52e3297fffffffffffff5p+0 : inexact-ok
= acosh tonearest binary128 0x1.3bf8009648dcp+16 : 0xb.fe74af52e3297fffffffffffff58p+0 : inexact-ok
= acosh towardzero binary128 0x1.3bf8009648dcp+16 : 0xb.fe74af52e3297fffffffffffff5p+0 : inexact-ok
= acosh upward binary128 0x1.3bf8009648dcp+16 : 0xb.fe74af52e3297fffffffffffff58p+0 : inexact-ok
= acosh downward ibm128 0x1.3bf8009648dcp+16 : 0xb.fe74af52e3297ffffffffffffcp+0 : inexact-ok
= acosh tonearest ibm128 0x1.3bf8009648dcp+16 : 0xb.fe74af52e3298p+0 : inexact-ok
= acosh towardzero ibm128 0x1.3bf8009648dcp+16 : 0xb.fe74af52e3297ffffffffffffcp+0 : inexact-ok
= acosh upward ibm128 0x1.3bf8009648dcp+16 : 0xb.fe74af52e3298p+0 : inexact-ok
acosh max
= acosh downward binary32 0xf.fffffp+124 : 0x5.96a7ep+4 : inexact-ok
= acosh tonearest binary32 0xf.fffffp+124 : 0x5.96a7ep+4 : inexact-ok
+1
View File
@@ -60,6 +60,7 @@ nis_creategroup (const_nis_name group, unsigned int flags)
free (obj->zo_group);
free (obj->zo_owner);
free (obj->zo_name);
free (obj->zo_domain);
free (obj);
return NIS_NOMEMORY;
}
-5
View File
@@ -740,11 +740,6 @@ __pthread_create_2_1 (pthread_t *newthread, const pthread_attr_t *attr,
THREAD_COPY_STACK_GUARD (pd);
#endif
/* Copy the pointer guard value. */
#ifdef THREAD_COPY_POINTER_GUARD
THREAD_COPY_POINTER_GUARD (pd);
#endif
/* Setup tcbhead. */
tls_setup_tcbhead (pd);
+1 -1
View File
@@ -44,7 +44,7 @@ __pthread_getname_np (pthread_t th, char *buf, size_t len)
char fname[sizeof (FMT) + 8];
sprintf (fname, FMT, (unsigned int) pd->tid);
int fd = __open64_nocancel (fname, O_RDONLY);
int fd = __open64_nocancel (fname, O_RDONLY | O_CLOEXEC);
if (fd == -1)
return errno;
+1 -1
View File
@@ -46,7 +46,7 @@ __pthread_setname_np (pthread_t th, const char *name)
char fname[sizeof (FMT) + 8];
sprintf (fname, FMT, (unsigned int) pd->tid);
int fd = __open64_nocancel (fname, O_RDWR);
int fd = __open64_nocancel (fname, O_WRONLY | O_CLOEXEC);
if (fd == -1)
return errno;
+1 -1
View File
@@ -192,7 +192,7 @@ cache_addgr (struct database_dyn *db, int fd, request_header *req,
+ gr_mem_cnt * sizeof (uint32_t)
+ gr_name_len + gr_passwd_len + gr_mem_len_total);
/* If we refill the cache, first assume the reconrd did not
/* If we refill the cache, first assume the record did not
change. Allocate memory on the cache since it is likely
discarded anyway. If it turns out to be necessary to have a
new record we can still allocate real memory. */
+1 -1
View File
@@ -224,7 +224,7 @@ cache_addhst (struct database_dyn *db, int fd, request_header *req,
+ h_aliases_cnt * sizeof (uint32_t)
+ h_addr_list_cnt * hst->h_length);
/* If we refill the cache, first assume the reconrd did not
/* If we refill the cache, first assume the record did not
change. Allocate memory on the cache since it is likely
discarded anyway. If it turns out to be necessary to have a
new record we can still allocate real memory. */
+1 -1
View File
@@ -245,7 +245,7 @@ addinitgroupsX (struct database_dyn *db, int fd, request_header *req,
total = offsetof (struct dataset, strdata) + start * sizeof (int32_t);
/* If we refill the cache, first assume the reconrd did not
/* If we refill the cache, first assume the record did not
change. Allocate memory on the cache since it is likely
discarded anyway. If it turns out to be necessary to have a
new record we can still allocate real memory. */
+1 -1
View File
@@ -186,7 +186,7 @@ cache_addpw (struct database_dyn *db, int fd, request_header *req,
+ pw_name_len + pw_passwd_len
+ pw_gecos_len + pw_dir_len + pw_shell_len);
/* If we refill the cache, first assume the reconrd did not
/* If we refill the cache, first assume the record did not
change. Allocate memory on the cache since it is likely
discarded anyway. If it turns out to be necessary to have a
new record we can still allocate real memory. */
+1 -1
View File
@@ -180,7 +180,7 @@ cache_addserv (struct database_dyn *db, int fd, request_header *req,
+ s_proto_len
+ s_aliases_cnt * sizeof (uint32_t));
/* If we refill the cache, first assume the reconrd did not
/* If we refill the cache, first assume the record did not
change. Allocate memory on the cache since it is likely
discarded anyway. If it turns out to be necessary to have a
new record we can still allocate real memory. */
-3
View File
@@ -427,12 +427,9 @@ libnss_compat-routines := $(addprefix compat-,grp pwd spwd initgroups) \
install-others += $(inst_vardbdir)/Makefile
# Build static module into libc if requested
libnss_db-inhibit-o = $(filter-out .os,$(object-suffixes))
libnss_compat-inhibit-o = $(filter-out .os,$(object-suffixes))
ifeq ($(build-static-nss),yes)
tests-static += tst-nss-static
endif
extra-test-objs += nss_test1.os nss_test2.os nss_test_errno.os \
nss_test_gai_hv2_canonname.os
-4
View File
@@ -33,10 +33,6 @@
#include <shadow.h>
#include <unistd.h>
#if !defined DO_STATIC_NSS || defined SHARED
# include <gnu/lib-names.h>
#endif
#include "nsswitch.h"
#include "../nscd/nscd_proto.h"
#include <sysdep.h>
+5 -7
View File
@@ -77,13 +77,11 @@ enum
extern bool __nss_database_custom[NSS_DBSIDX_max] attribute_hidden;
#endif
/* Warning for NSS functions, which don't require dlopen if glibc
was built with --enable-static-nss. */
#ifdef DO_STATIC_NSS
# define nss_interface_function(name)
#else
# define nss_interface_function(name) static_link_warning (name)
#endif
/* NSS lookups can load service modules via dlopen at runtime, so a
statically linked program still depends on the shared NSS modules
matching the libc it was built against. Emit the static link
warning on the NSS interface functions accordingly. */
#define nss_interface_function(name) static_link_warning (name)
/* Interface functions for NSS. */
+1
View File
@@ -360,6 +360,7 @@ tests-internal := \
tests-container := \
bug-ga2 \
tst-vfork3 \
tst-wordexp-tilde \
# tests-container
tests-time64 := \
+244
View File
@@ -0,0 +1,244 @@
/* Test wordexp tilde expansion with large usernames (BZ 34091).
Copyright (C) 2026 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
#include <pwd.h>
#include <stdio.h>
#include <string.h>
#include <wordexp.h>
#include <stdlib.h>
#include <sys/resource.h>
#include <support/check.h>
#include <support/support.h>
#include <support/xunistd.h>
#include <support/namespace.h>
typedef void (*func_callback_t)(void);
static void
subprocess_small_stack (void *closure)
{
struct rlimit rl;
TEST_COMPARE (getrlimit (RLIMIT_STACK, &rl), 0);
rl.rlim_cur = 512 * 1024;
TEST_COMPARE (setrlimit (RLIMIT_STACK, &rl), 0);
func_callback_t func_test = closure;
func_test ();
}
/* Build a string "~<padding>/tail" where <padding> is LEN bytes of the
character CH. The caller must free the result. */
static char *
make_tilde_input (char ch, size_t len, const char *tail)
{
/* ~ + len + / + tail + \0 */
size_t taillen = tail != NULL ? strlen (tail) : 0;
size_t total = 1 + len + 1 + taillen + 1;
char *buf = xmalloc (total);
buf[0] = '~';
memset (buf + 1, ch, len);
buf[1 + len] = '/';
if (tail != NULL)
memcpy (buf + 1 + len + 1, tail, taillen);
buf[total - 1] = '\0';
return buf;
}
/* Test 1: A very long username must not crash. The username will not match
any real user, so wordexp returns ~<long>/rest. */
static void
test_long_username (void)
{
printf ("info: test_long_username_no_crash\n");
static const char REST[] = "rest";
/* 1 MiB username — well beyond any reasonable stack frame. */
const size_t long_len = 1024 * 1024;
char *input = make_tilde_input ('A', long_len, REST);
wordexp_t we = { 0 };
int ret = wordexp (input, &we, 0);
/* The (non-existent) username is invalid, so wordexp falls back to
literal output: ~AAA/rest. */
TEST_COMPARE (ret, 0);
TEST_COMPARE (we.we_wordc, 1);
/* Verify prefix: '~' followed by long_len 'A's. */
const char *result = we.we_wordv[0];
TEST_COMPARE (result[0], '~');
TEST_COMPARE (strlen (result),
1 /* ~ */ + long_len + sizeof (REST));
for (size_t j = 1; j <= long_len; j++)
if (result[j] != 'A')
{
printf (" mismatch at position %zu: expected 'A', got '%c'\n",
j, result[j]);
support_record_failure ();
break;
}
/* Verify the tail after the username. */
TEST_COMPARE_STRING (result + 1 + long_len, "/rest");
wordfree (&we);
free (input);
}
/* Test 2: A username that just exceeds the default scratch_buffer inline
size (1024 bytes) exercises the scratch_buffer_set_array_size growth path
without being excessively large. */
static void
test_scratch_buffer_growth (void)
{
printf ("info: test_scratch_buffer_growth\n");
const size_t len = 2048;
char *input = make_tilde_input ('x', len, NULL);
wordexp_t we = { 0 };
int ret = wordexp (input, &we, 0);
TEST_COMPARE (ret, 0);
TEST_COMPARE (we.we_wordc, 1);
/* ~xxx…/ — the trailing slash makes a separate empty component, but
wordexp merges it into the single token ~xxx/. */
const char *result = we.we_wordv[0];
TEST_COMPARE (result[0], '~');
for (size_t j = 1; j <= len; j++)
if (result[j] != 'x')
{
printf (" mismatch at position %zu\n", j);
support_record_failure ();
break;
}
TEST_COMPARE (result[1 + len], '/');
wordfree (&we);
free (input);
}
/* Test 3: ~root still resolves to the correct home directory through the
__getpwnam_r path. */
static void
test_known_user (void)
{
printf ("info: test_known_user\n");
/* Look up root's home directory for comparison. */
struct passwd *pw = getpwnam ("root");
if (pw == NULL || pw->pw_dir == NULL)
{
printf (" SKIP: cannot look up root\n");
return;
}
char *expected = xasprintf ("%s/file", pw->pw_dir);
wordexp_t we = { 0 };
TEST_COMPARE (wordexp ("~root/file", &we, 0), 0);
TEST_COMPARE (we.we_wordc, 1);
TEST_COMPARE_STRING (we.we_wordv[0], expected);
wordfree (&we);
free (expected);
}
/* Test 4: Bare tilde expands to $HOME. */
static void
test_bare_tilde (void)
{
printf ("info: test_bare_tilde\n");
const char *home = getenv ("HOME");
if (home == NULL)
{
printf (" SKIP: HOME is not set\n");
return;
}
wordexp_t we = { 0 };
TEST_COMPARE (wordexp ("~", &we, 0), 0);
TEST_COMPARE (we.we_wordc, 1);
TEST_COMPARE_STRING (we.we_wordv[0], home);
wordfree (&we);
}
/* Test 5: Short non-existent username falls back to literal ~username output,
exercising the invalid-login-name path. */
static void
test_unknown_user (void)
{
printf ("info: test_unknown_user\n");
/* Pick a username that is extremely unlikely to exist. */
wordexp_t we = { 0 };
TEST_COMPARE (wordexp ("~no_such_user_xyzzy42", &we, 0), 0);
TEST_COMPARE (we.we_wordc, 1);
TEST_COMPARE_STRING (we.we_wordv[0], "~no_such_user_xyzzy42");
wordfree (&we);
}
/* Test 6: Tilde with username and WRDE_APPEND — exercises parse_tilde's
interaction with the WRDE_APPEND word list. */
static void
test_tilde_with_append (void)
{
printf ("info: test_tilde_with_append\n");
const char *home = getenv ("HOME");
if (home == NULL)
{
printf (" SKIP: HOME is not set\n");
return;
}
wordexp_t we = { 0 };
TEST_COMPARE (wordexp ("first", &we, 0), 0);
TEST_COMPARE (wordexp ("~/path", &we, WRDE_APPEND), 0);
TEST_COMPARE (we.we_wordc, 2);
TEST_COMPARE_STRING (we.we_wordv[0], "first");
char *expected = xasprintf ("%s/path", home);
TEST_COMPARE_STRING (we.we_wordv[1], expected);
wordfree (&we);
free (expected);
}
static int
do_test (void)
{
test_known_user ();
test_bare_tilde ();
test_unknown_user ();
test_tilde_with_append ();
support_isolate_in_subprocess (subprocess_small_stack,
test_long_username);
support_isolate_in_subprocess (subprocess_small_stack,
test_scratch_buffer_growth);
return 0;
}
#include <support/test-driver.c>
+1
View File
@@ -0,0 +1 @@
root:x:0:
@@ -0,0 +1,3 @@
passwd: files
group: files
shadow: files
+1
View File
@@ -0,0 +1 @@
root:x:0:0:root:/root:/bin/sh
+18 -6
View File
@@ -335,17 +335,29 @@ parse_tilde (char **word, size_t *word_length, size_t *max_length,
else
{
/* Look up user name in database to get home directory */
char *user = strndupa (&words[1 + *offset], i - (1 + *offset));
struct passwd pwd, *tpwd;
int result;
size_t userlen = i - (1 + *offset);
/* tmpbuf contains both the user and the __getpwnam_r working area. */
struct scratch_buffer tmpbuf;
scratch_buffer_init (&tmpbuf);
if (!scratch_buffer_set_array_size (&tmpbuf, userlen + 1, 1))
return WRDE_NOSPACE;
char *user = tmpbuf.data;
memcpy (user, &words[1 + *offset], userlen);
user[userlen] = '\0';
while ((result = __getpwnam_r (user, &pwd, tmpbuf.data, tmpbuf.length,
struct passwd pwd, *tpwd;
int result;
while ((result = __getpwnam_r (user,
&pwd,
tmpbuf.data + userlen + 1,
tmpbuf.length - userlen - 1,
&tpwd)) != 0
&& errno == ERANGE)
if (!scratch_buffer_grow (&tmpbuf))
return WRDE_NOSPACE;
{
if (!scratch_buffer_grow_preserve (&tmpbuf))
return WRDE_NOSPACE;
user = tmpbuf.data;
}
if (result == 0 && tpwd != NULL && pwd.pw_dir)
*word = w_addstr (*word, word_length, max_length, pwd.pw_dir);
+8
View File
@@ -108,6 +108,7 @@ tests += \
tst-ns_name \
tst-ns_name_compress \
tst-ns_name_pton \
tst-ns_sprintrr \
tst-res_hconf_reorder \
tst-res_hnok \
tst-resolv-aliases \
@@ -122,6 +123,7 @@ tests += \
tst-resolv-noaaaa \
tst-resolv-noaaaa-vc \
tst-resolv-nondecimal \
tst-resolv-res_init-failure \
tst-resolv-res_init-multi \
tst-resolv-search \
tst-resolv-semi-failure \
@@ -156,6 +158,7 @@ tests += \
tst-resolv-ai_idn-nolibidn2 \
tst-resolv-canonname \
tst-resolv-getaddrinfo-fqdn \
tst-resolv-gethostbyname_r-unaligned \
tst-resolv-trustad \
# Needs resolv_context.
@@ -305,8 +308,12 @@ $(objpfx)tst-resolv-byaddr: $(objpfx)libresolv.so $(shared-thread-library)
$(objpfx)tst-resolv-dns-section: $(objpfx)libresolv.so \
$(shared-thread-library)
$(objpfx)tst-resolv-edns: $(objpfx)libresolv.so $(shared-thread-library)
$(objpfx)tst-resolv-gethostbyname_r-unaligned: \
$(objpfx)libresolv.so $(shared-thread-library)
$(objpfx)tst-resolv-network: $(objpfx)libresolv.so $(shared-thread-library)
$(objpfx)tst-resolv-res_init: $(objpfx)libresolv.so
$(objpfx)tst-resolv-res_init-failure: $(objpfx)libresolv.so \
$(shared-thread-library)
$(objpfx)tst-resolv-res_init-multi: $(objpfx)libresolv.so \
$(shared-thread-library)
$(objpfx)tst-resolv-res_init-thread: $(objpfx)libresolv.so \
@@ -338,5 +345,6 @@ $(objpfx)tst-ns_name: $(objpfx)libresolv.so
$(objpfx)tst-ns_name.out: tst-ns_name.data
$(objpfx)tst-ns_name_compress: $(objpfx)libresolv.so
$(objpfx)tst-ns_name_pton: $(objpfx)libresolv.so
$(objpfx)tst-ns_sprintrr: $(objpfx)libresolv.so
$(objpfx)tst-res_hnok: $(objpfx)libresolv.so
$(objpfx)tst-p_secstodate: $(objpfx)libresolv.so
+53 -117
View File
@@ -78,6 +78,24 @@ ns_sprintrr(const ns_msg *handle, const ns_rr *rr,
}
libresolv_hidden_def (ns_sprintrr)
/* Writes the class/type symbol NUMBER to *BUF, using the name from
*SYMS if possible. If NUMBER is not found in *SYMS, print the
number with PREFIX. */
static int
addsym (const struct res_sym *syms, int number, const char *prefix,
char **buf, size_t *buflen)
{
for (; syms->name != NULL; syms++)
if (number == syms->number)
{
T (addstr (" ", 1, buf, buflen));
return addstr (syms->name, strlen (syms->name), buf, buflen);
}
char tmp[20];
int len = snprintf (tmp, sizeof (tmp), " %s%d", prefix, number);
return addstr (tmp, len, buf, buflen);
}
/*%
* Convert the fields of an RR into presentation format.
*
@@ -97,7 +115,6 @@ ns_sprintrrf(const u_char *msg, size_t msglen,
const char *comment;
char tmp[100];
char errbuf[40];
int len, x;
/*
@@ -128,11 +145,21 @@ ns_sprintrrf(const u_char *msg, size_t msglen,
/*
* TTL, Class, Type.
*/
T(x = ns_format_ttl(ttl, buf, buflen));
addlen(x, &buf, &buflen);
len = SPRINTF((tmp, " %s %s", p_class(class), p_type(type)));
T(addstr(tmp, len, &buf, &buflen));
T(spaced = addtab(x + len, 16, spaced, &buf, &buflen));
{
char *start = buf;
T (x = ns_format_ttl (ttl, buf, buflen));
addlen (x, &buf, &buflen);
T (addsym (__p_class_syms, class, "CLASS", &buf, &buflen));
if (type == ns_t_a6)
/* A6 is not part of __p_type_syms, which is exported.
Adding A6 there would change its size. Handle it here. */
T (addstr (" A6", 3, &buf, &buflen));
else
T (addsym (__p_type_syms, type, "TYPE", &buf, &buflen));
T (spaced = addtab(buf - start, 16, spaced, &buf, &buflen));
}
/*
* RData.
@@ -140,8 +167,9 @@ ns_sprintrrf(const u_char *msg, size_t msglen,
switch (type) {
case ns_t_a:
if (rdlen != (size_t)NS_INADDRSZ)
goto formerr;
(void) inet_ntop(AF_INET, rdata, buf, buflen);
goto formerr;
if (inet_ntop (AF_INET, rdata, buf, buflen) == NULL)
return -1;
addlen(strlen(buf), &buf, &buflen);
break;
@@ -307,16 +335,18 @@ ns_sprintrrf(const u_char *msg, size_t msglen,
}
case ns_t_aaaa:
if (rdlen != (size_t)NS_IN6ADDRSZ)
goto formerr;
(void) inet_ntop(AF_INET6, rdata, buf, buflen);
if (rdlen != (size_t)NS_IN6ADDRSZ)
goto formerr;
if (inet_ntop (AF_INET6, rdata, buf, buflen) == NULL)
return -1;
addlen(strlen(buf), &buf, &buflen);
break;
case ns_t_loc: {
char t[255];
/* XXX protocol format checking? */
if (rdlen != 16)
goto formerr;
(void) loc_ntoa(rdata, t);
T(addstr(t, strlen(t), &buf, &buflen));
break;
@@ -400,7 +430,8 @@ ns_sprintrrf(const u_char *msg, size_t msglen,
goto formerr;
/* Address. */
(void) inet_ntop(AF_INET, rdata, buf, buflen);
if (inet_ntop (AF_INET, rdata, buf, buflen) == NULL)
return -1;
addlen(strlen(buf), &buf, &buflen);
rdata += NS_INADDRSZ;
@@ -434,96 +465,6 @@ ns_sprintrrf(const u_char *msg, size_t msglen,
break;
}
case ns_t_cert: {
u_int c_type, key_tag, alg;
int n;
unsigned int siz;
char base64_cert[8192], tmp[40];
const char *leader;
c_type = ns_get16(rdata); rdata += NS_INT16SZ;
key_tag = ns_get16(rdata); rdata += NS_INT16SZ;
alg = (u_int) *rdata++;
len = SPRINTF((tmp, "%d %d %d ", c_type, key_tag, alg));
T(addstr(tmp, len, &buf, &buflen));
siz = (edata-rdata)*4/3 + 4; /* "+4" accounts for trailing \0 */
if (siz > sizeof(base64_cert) * 3/4) {
const char *str = "record too long to print";
T(addstr(str, strlen(str), &buf, &buflen));
}
else {
len = b64_ntop(rdata, edata-rdata, base64_cert, siz);
if (len < 0)
goto formerr;
else if (len > 15) {
T(addstr(" (", 2, &buf, &buflen));
leader = "\n\t\t";
spaced = 0;
}
else
leader = " ";
for (n = 0; n < len; n += 48) {
T(addstr(leader, strlen(leader),
&buf, &buflen));
T(addstr(base64_cert + n, MIN(len - n, 48),
&buf, &buflen));
}
if (len > 15)
T(addstr(" )", 2, &buf, &buflen));
}
break;
}
case ns_t_tkey: {
/* KJD - need to complete this */
u_long t;
int mode, err, keysize;
/* Algorithm name. */
T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
T(addstr(" ", 1, &buf, &buflen));
/* Inception. */
t = ns_get32(rdata); rdata += NS_INT32SZ;
len = SPRINTF((tmp, "%lu ", t));
T(addstr(tmp, len, &buf, &buflen));
/* Expiration. */
t = ns_get32(rdata); rdata += NS_INT32SZ;
len = SPRINTF((tmp, "%lu ", t));
T(addstr(tmp, len, &buf, &buflen));
/* Mode , Error, Key Size. */
/* Priority, Weight, Port. */
mode = ns_get16(rdata); rdata += NS_INT16SZ;
err = ns_get16(rdata); rdata += NS_INT16SZ;
keysize = ns_get16(rdata); rdata += NS_INT16SZ;
len = SPRINTF((tmp, "%u %u %u ", mode, err, keysize));
T(addstr(tmp, len, &buf, &buflen));
/* XXX need to dump key, print otherdata length & other data */
break;
}
case ns_t_tsig: {
/* BEW - need to complete this */
int n;
T(len = addname(msg, msglen, &rdata, origin, &buf, &buflen));
T(addstr(" ", 1, &buf, &buflen));
rdata += 8; /*%< time */
n = ns_get16(rdata); rdata += INT16SZ;
rdata += n; /*%< sig */
n = ns_get16(rdata); rdata += INT16SZ; /*%< original id */
sprintf(buf, "%d", ns_get16(rdata));
rdata += INT16SZ;
addlen(strlen(buf), &buf, &buflen);
break;
}
case ns_t_a6: {
struct in6_addr a;
int pbyte, pbit;
@@ -539,12 +480,14 @@ ns_sprintrrf(const u_char *msg, size_t msglen,
/* address suffix: provided only when prefix len != 128 */
if (pbit < 128) {
if (rdata + pbyte >= edata) goto formerr;
unsigned int bytelen = sizeof(a) - pbyte;
if (edata - rdata < bytelen) goto formerr;
memset(&a, 0, sizeof(a));
memcpy(&a.s6_addr[pbyte], rdata, sizeof(a) - pbyte);
(void) inet_ntop(AF_INET6, &a, buf, buflen);
memcpy(&a.s6_addr[pbyte], rdata, bytelen);
if (inet_ntop (AF_INET6, &a, buf, buflen) == NULL)
return -1;
addlen(strlen(buf), &buf, &buflen);
rdata += sizeof(a) - pbyte;
rdata += bytelen;
}
/* prefix name: provided only when prefix len > 0 */
@@ -557,25 +500,18 @@ ns_sprintrrf(const u_char *msg, size_t msglen,
break;
}
case ns_t_opt: {
len = SPRINTF((tmp, "%u bytes", class));
T(addstr(tmp, len, &buf, &buflen));
break;
}
default:
snprintf (errbuf, sizeof (errbuf), "unknown RR type %d", type);
comment = errbuf;
comment = "";
goto hexify;
}
return (buf - obuf);
formerr:
comment = "RR format error";
comment = " ; RR format error";
hexify: {
int n, m;
char *p;
len = SPRINTF((tmp, "\\# %u%s\t; %s", (unsigned)(edata - rdata),
len = SPRINTF((tmp, "\\# %u%s%s", (unsigned)(edata - rdata),
rdlen != 0U ? " (" : "", comment));
T(addstr(tmp, len, &buf, &buflen));
while (rdata < edata) {
+7 -2
View File
@@ -89,7 +89,9 @@
#include <stdlib.h>
/* Close all open sockets. If FREE_ADDR is true, deallocate any
separately allocated name server addresses. */
separately allocated name server addresses, detach the extended
resolver configuration, and reset the cached extended-state count
so subsequent name lookups reinitialize the extended state. */
void
__res_iclose (res_state statp, bool free_addr)
{
@@ -114,7 +116,10 @@ __res_iclose (res_state statp, bool free_addr)
}
}
if (free_addr)
__resolv_conf_detach (statp);
{
__resolv_conf_detach (statp);
statp->_u._ext.nscount = 0;
}
}
libc_hidden_def (__res_iclose)
-4
View File
@@ -390,8 +390,6 @@ p_fqname(const u_char *cp, const u_char *msg, FILE *file) {
* that C_ANY is a qclass but not a class. (You can ask for records of class
* C_ANY, but you can't have any records of that class in the database.)
*/
extern const struct res_sym __p_class_syms[];
libresolv_hidden_proto (__p_class_syms)
const struct res_sym __p_class_syms[] = {
{C_IN, (char *) "IN"},
{C_CHAOS, (char *) "CHAOS"},
@@ -426,8 +424,6 @@ const struct res_sym __p_update_section_syms[] attribute_hidden = {
* Names of RR types and qtypes. The list is incomplete because its
* size is part of the ABI.
*/
extern const struct res_sym __p_type_syms[];
libresolv_hidden_proto (__p_type_syms)
const struct res_sym __p_type_syms[] = {
{ns_t_a, (char *) "A", (char *) "address"},
{ns_t_ns, (char *) "NS", (char *) "name server"},
+329
View File
@@ -0,0 +1,329 @@
/* Tests for the ns_sprintrr function.
Copyright (C) 2026 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
#include <arpa/nameser.h>
#include <alloc_buffer.h>
#include <arpa/inet.h>
#include <libc-diag.h>
#include <stdbool.h>
#include <string.h>
#include <support/check.h>
#include <support/next_to_fault.h>
#include <stdio.h>
/* Regions that test_one_record uses for input and output. */
static struct support_next_to_fault ntf_in;
static struct support_next_to_fault ntf_out;
/* This is used by test_one_record to construct the packet. */
static const char packet_prefix[] =
/* DNS response with one question, one answer record. */
"AA\x81\x80\0\1\0\1\0\0\0\0"
/* Question: www.example.org/IN/ANY. */
"\3www\7example\3org\0\0\xff\0\1"
/* Response: compression reference. */
"\xc0\x0c";
/* Use ns_sprintrr to format a DNS record (starting with
packet_prefix) of type RTYPE, with a record payload of RDATALEN
bytes starting at RDATA. Check successful formatting against
EXPECTED. Try various truncated input and output buffers to catch
overreads and buffer overflows, using ntf_in and ntf_out above. */
static void
test_one_record (uint16_t rtype, const char *rdata, size_t rdatalen,
const char *expected)
{
struct rr_header
{
uint16_t typ;
uint16_t cls;
uint32_t ttl;
uint16_t rdatalen;
uint16_t pad;
} hdr =
{
.typ = htons (rtype),
.cls = htons (ns_c_in),
.ttl = htonl (86400), /* One day. */
.rdatalen = htons (rdatalen),
};
enum { hdrlen = offsetof (struct rr_header, pad) };
TEST_COMPARE (hdrlen, 10);
/* Construct the packet from packet_prefix, hdr, and rdata. */
unsigned char packet[512];
size_t packetlen;
{
struct alloc_buffer buf = alloc_buffer_create (packet, sizeof (packet));
alloc_buffer_copy_bytes (&buf, packet_prefix, sizeof (packet_prefix) - 1);
alloc_buffer_copy_bytes (&buf, &hdr, hdrlen);
alloc_buffer_copy_bytes (&buf, rdata, rdatalen);
packetlen = sizeof (packet) - alloc_buffer_size (&buf);
}
/* Parse the record. */
ns_msg msg;
TEST_COMPARE (ns_initparse (packet, packetlen, &msg), 0);
ns_rr rr;
TEST_COMPARE (ns_parserr (&msg, ns_s_an, 0, &rr), 0);
/* Try sizes up to this limit. Go a bit beyond the expected size to
check for errors. */
size_t max_result_size = strlen (expected) + 16;
bool success = false;
for (size_t result_size = 1; result_size <= max_result_size; ++result_size)
{
char *result_start = ntf_out.buffer + ntf_out.length - result_size;
memset (result_start, 'X', result_size);
/* ns_sprintrr was deprecated in 2.34. */
DIAG_PUSH_NEEDS_COMMENT;
DIAG_IGNORE_NEEDS_COMMENT (4.9, "-Wdeprecated-declarations");
int ret = ns_sprintrr (&msg, &rr, NULL, NULL, result_start, result_size);
DIAG_POP_NEEDS_COMMENT;
if (ret > 0)
{
TEST_COMPARE_STRING (result_start, expected);
TEST_COMPARE (ret, strlen (expected));
success = true;
}
else
{
TEST_VERIFY (!success);
TEST_COMPARE (ret, -1);
}
}
TEST_VERIFY (success);
/* Test with truncated RDATA. */
for (size_t rdata_size = 0; rdata_size <= rdatalen; ++rdata_size)
{
size_t truncated_packet_size = packetlen - rdatalen + rdata_size;
unsigned char *packet_start
= ((unsigned char *) ntf_in.buffer + ntf_in.length
- truncated_packet_size);
memcpy (packet_start, packet, truncated_packet_size);
/* Patch in the updated RDATA length field. */
uint16_t new_rdatalen = htons (rdata_size);
memcpy (packet_start + truncated_packet_size - rdata_size - 2,
&new_rdatalen, 2);
ns_msg msg;
TEST_COMPARE (ns_initparse (packet_start, truncated_packet_size, &msg),
0);
ns_rr rr;
TEST_COMPARE (ns_parserr (&msg, ns_s_an, 0, &rr), 0);
size_t result_size = strlen (expected) + 1;
char *result_start = ntf_out.buffer + ntf_out.length - result_size;
memset (result_start, 'X', result_size);
/* ns_sprintrr was deprecated in 2.34. */
DIAG_PUSH_NEEDS_COMMENT;
DIAG_IGNORE_NEEDS_COMMENT (4.9, "-Wdeprecated-declarations");
int ret = ns_sprintrr (&msg, &rr, NULL, NULL, result_start, result_size);
DIAG_POP_NEEDS_COMMENT;
/* This flag indicates whether the output is syntactically
correct. In some cases, truncation may still yield a valid
payload. */
bool broken = rdata_size < rdatalen;
switch (rtype)
{
case ns_t_wks:
/* WKS records use all trailing bytes for the port bitmap. */
broken = rdata_size < 5;
break;
case ns_t_nsap:
/* Uses all bytes that are available. */
broken = false;
break;
case ns_t_txt:
/* Truncation produces a valid payload if it occurs right
after a complete string in the TXT payload. */
broken = false;
for (size_t pos = 0; pos < rdata_size; )
{
unsigned int slen = rdata[pos] & 0xff;
if (pos + 1 + slen > rdata_size)
{
broken = true;
break;
}
pos += 1 + slen;
}
break;
case ns_t_isdn:
/* The second field is optional. If it is present, it must
not be truncated. */
broken = rdata_size < 6 || (rdata_size > 6 && rdata_size < rdatalen);
break;
case ns_t_a6:
/* The first A6 subtest contains a trailing domain name,
which is ignored and not formatted. */
if (rdata_size > 0 && rdata[0] == 0)
broken = rdata_size < 17;
break;
case ns_t_cert:
case ns_t_tkey:
case ns_t_tsig:
/* Only generic printing, which does not validate anything. */
broken = false;
break;
}
if (broken)
{
if (strstr (result_start, "RR format error") != NULL)
/* No further checks if an error indicator has been added
to the output. */
;
else
TEST_COMPARE (ret, -1);
}
else
TEST_VERIFY (ret > 0);
}
}
static int
do_test (void)
{
ntf_in = support_next_to_fault_allocate (512);
ntf_out = support_next_to_fault_allocate (256);
#define T(rtype, rdata, expected) \
test_one_record (rtype, rdata, sizeof (rdata) - 1, expected)
T (ns_t_a, "\xc0\0\2\1", "www.example.org.\t1D IN A\t\t192.0.2.1");
T (ns_t_cname, "\4www1\4prod\xc0\x10",
"www.example.org.\t1D IN CNAME\twww1.prod.example.org.");
T (ns_t_hinfo, "\5first\6second",
"www.example.org.\t1D IN HINFO\t\"first\" \"second\"");
T (ns_t_isdn, "\5first\6second",
"www.example.org.\t1D IN ISDN\t\"first\" \"second\"");
/* Bug: Extra space at the end in the text representation of ISDN RRs. */
T (ns_t_isdn, "\5first", "www.example.org.\t1D IN ISDN\t\"first\" ");
T (ns_t_soa,
"\2ns\xc0\x10\12hostmaster\xc0\x10"
"\0\0\0\1\0\0\0\2\0\0\0\3\0\0\0\4\0\0\0\5",
"www.example.org.\t1D IN SOA\tns.example.org. hostmaster.example.org. (\n"
"\t\t\t\t\t1\t\t; serial\n"
"\t\t\t\t\t2S\t\t; refresh\n"
"\t\t\t\t\t3S\t\t; retry\n"
"\t\t\t\t\t4S\t\t; expiry\n"
"\t\t\t\t\t5S )\t\t; minimum\n");
T (ns_t_mx, "\0\xa\2mx\xc0\x10",
"www.example.org.\t1D IN MX\t10 mx.example.org.");
T (ns_t_px, "\0\xa\3px1\xc0\x10\3px2\xc0\x10",
"www.example.org.\t1D IN PX\t10 px1.example.org. px2.example.org.");
T (ns_t_x25, "\4X.25",
"www.example.org.\t1D IN X25\t\"X.25\"");
T (ns_t_txt, "\1A\2BC\3DEF",
"www.example.org.\t1D IN TXT\t\"A\" \"BC\" \"DEF\"");
T (ns_t_nsap, "",
"www.example.org.\t1D IN NSAP\t");
T (ns_t_nsap, "\1",
"www.example.org.\t1D IN NSAP\t01");
T (ns_t_nsap, "\1\2",
"www.example.org.\t1D IN NSAP\t01.02");
T (ns_t_nsap, "\1\2\3",
"www.example.org.\t1D IN NSAP\t01.0203");
T (ns_t_nsap, "\1\2\3\4",
"www.example.org.\t1D IN NSAP\t01.0203.04");
T (ns_t_nsap,
"\1\2\3\4\5\6\7\10\11\12\13\14\15\16\17\20\21\22\23\24\25\26\27\30\31\32"
"\33\34\35\36\37\40\41\42\43\44\45\46\47\50\51\52\53\54\55\56\57\60\61"
"\62\63\64\65\66\67\70\71\72\73\74\75\76\77\100\101\102\103\104\105\106"
"\107\110\111\112\113\114\115\116\117\120\121\122\123\124\125\126\127"
"\130\131\132\133\134\135\136\137\140\141\142\143\144\145\146\147\150"
"\151\152\153\154\155\156\157\160\161\162\163\164\165\166\167\170\171"
"\172\173\174\175\176\177\200\201\202\203\204\205\206\207\210\211\212"
"\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233"
"\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254"
"\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275"
"\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316"
"\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337"
"\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360"
"\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377",
"www.example.org.\t1D IN NSAP\t"
"01.0203.0405.0607.0809.0A0B.0C0D.0E0F.1011.1213.1415.1617.1819.1A1B"
".1C1D.1E1F.2021.2223.2425.2627.2829.2A2B.2C2D.2E2F.3031.3233.3435.3637"
".3839.3A3B.3C3D.3E3F.4041.4243.4445.4647.4849.4A4B.4C4D.4E4F.5051.5253"
".5455.5657.5859.5A5B.5C5D.5E5F.6061.6263.6465.6667.6869.6A6B.6C6D.6E6F"
".7071.7273.7475.7677.7879.7A7B.7C7D.7E7F.8081.8283.8485.8687.8889.8A8B"
".8C8D.8E8F.9091.9293.9495.9697.9899.9A9B.9C9D.9E9F.A0A1.A2A3.A4A5.A6A7"
".A8A9.AAAB.ACAD.AEAF.B0B1.B2B3.B4B5.B6B7.B8B9.BABB.BCBD.BEBF.C0C1.C2C3"
".C4C5.C6C7.C8C9.CACB.CCCD.CECF.D0D1.D2D3.D4D5.D6D7.D8D9.DADB.DCDD.DEDF"
".E0E1.E2E3.E4E5.E6E7.E8E9.EAEB.ECED.EEEF.F0F1.F2F3.F4F5.F6F7.F8F9.FAFB"
".FCFD.FEFF");
T (ns_t_aaaa, "\x20\x01\x0d\xb8\0\0\0\0\0\0\0\0\0\0\x12\x34",
"www.example.org.\t1D IN AAAA\t2001:db8::1234");
/* Example from RFC 1876. The loc_ntoa format is different from the
official text representation. */
T (ns_t_loc,
"\000\063\026\023\211\027\055\320\160\276\025\360\000\230\215\040",
"www.example.org.\t1D IN LOC"
"\t42 21 54.000 N 71 06 18.000 W -24.00m 30.00m 10000.00m 10.00m");
T (ns_t_naptr,
"\0\1\0\2\5flags\7service\2.*\5naptr\xc0\x10",
"www.example.org.\t1D IN NAPTR\t1 2 \"flags\" \"service\" \".*\""
" naptr.example.org.");
T (ns_t_srv,
"\0\1\0\2\0\x50\4www1\xc0\x10",
"www.example.org.\t1D IN SRV\t1 2 80 www1.example.org.");
T (ns_t_rp, "\3rp1\xc0\x10\3rp2\xc0\x10",
"www.example.org.\t1D IN RP\trp1.example.org. rp2.example.org.");
T (ns_t_wks, "\xc0\0\2\1\6\0\0\0\0\0\0\0\0\0\0\200",
"www.example.org.\t1D IN WKS\t192.0.2.1 6 ( \n\t\t\t\t80 )");
T (ns_t_cert, "\0\1\x04\xd2\0blob",
"www.example.org.\t1D IN CERT\t\\# 9 (\n"
"\t00 01 04 d2 00 62 6c 6f 62 )\t\t\t; .....blob");
T (ns_t_tkey, "\4algo\0\0\0\0\1\0\0\0\2\0\3\0\4"
"\0\5\xa1\xa2\xa3\xa4\xa5\0\3\xb1\xb2\xb3",
"www.example.org.\t1D IN TYPE249\t\\# 30 (\n"
"\t04 61 6c 67 6f 00 00 00 00 01 00 00 00 02 00 03 ; .algo...........\n"
"\t00 04 00 05 a1 a2 a3 a4 a5 00 03 b1 b2 b3 )\t; ..............");
T (ns_t_tsig, "\4algo\0"
"\0\20\xdd\xcd\x64\x10\xe9\x21\x34\x1a\x8e\xe0\xa1\x9a\x30\xfc\x3b\xd1"
"\0\2\0\3\0\5other",
"www.example.org.\t1D IN TSIG\t\\# 35 (\n"
"\t04 61 6c 67 6f 00 00 10 dd cd 64 10 e9 21 34 1a ; .algo.....d..!4.\n"
"\t8e e0 a1 9a 30 fc 3b d1 00 02 00 03 00 05 6f 74 ; ....0.;.......ot\n"
"\t68 65 72 )\t\t\t\t\t; her");
T (ns_t_a6,
"\0\x20\x01\x0d\xb8\0\0\0\0\0\0\0\0\0\0\x12\x34\6prefix\xc0\x10",
"www.example.org.\t1D IN A6\t0 2001:db8::1234");
T (ns_t_a6,
"\0\x20\x01\x0d\xb8\0\0\0\0\0\0\0\0\0\0\x12\x35",
"www.example.org.\t1D IN A6\t0 2001:db8::1235");
T (ns_t_a6, "\200\6prefix\xc0\x10",
"www.example.org.\t1D IN A6\t128 prefix.example.org.");
T (ns_t_a6, "\x20\0\0\0\0\0\0\0\0\0\0\x12\x36\6prefix\xc0\x10",
"www.example.org.\t1D IN A6\t32 ::1236 prefix.example.org.");
#undef T
support_next_to_fault_free (&ntf_in);
support_next_to_fault_free (&ntf_out);
return 0;
}
#include <support/test-driver.c>
@@ -0,0 +1,161 @@
/* Test for BZ #18287.
This test verifies that gethostbyname_r correctly accounts for pointer
alignment padding when calculating the remaining buffer size.
Copyright (C) 2026 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
#include <errno.h>
#include <netdb.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <support/check.h>
#include <support/check_nss.h>
#include <support/resolv_test.h>
#include <support/support.h>
#include <support/xmemstream.h>
static const char host_name[] = "foo.site.example";
/* Prepare big enough answer to trigger buffer overflow. */
static void
response (const struct resolv_response_context *ctx,
struct resolv_response_builder *b,
const char *qname, uint16_t qclass, uint16_t qtype)
{
if (strcmp (qname, host_name) == 0 && qtype == T_A)
{
struct resolv_response_flags flags = { };
resolv_response_init (b, flags);
resolv_response_add_question (b, qname, qclass, qtype);
resolv_response_section (b, ns_s_an);
for (int i = 0; i <= 60; i++)
{
char last_ch = (char) i;
char addr_ipv4[4] = { 127, 126, 125, last_ch };
resolv_response_open_record (b, qname, qclass, T_A, 0x12345678);
resolv_response_add_data (b, addr_ipv4, sizeof (addr_ipv4));
resolv_response_close_record (b);
}
}
}
/* Test gethostbyname_r with a specified buffer size and alignment.
Returns true if the buffer is sufficient, false if it's too small. */
static bool
query_host (size_t size, size_t align)
{
struct hostent ret;
struct hostent *result = NULL;
int err;
/* Allocate memory for buffer, alignment padding, and a 64-byte checking
area. */
size_t total_alloc = size + align + 64;
unsigned char *raw_buf = xmalloc (total_alloc);
/* Fill the tail of the buffer with 0xAA to detect overflows below. */
memset (raw_buf, 0, size + align);
memset (raw_buf + size + align, 0xAA, 64);
char *ptr = (char *) raw_buf + align;
int res = gethostbyname_r (host_name, &ret, ptr, size, &result, &err);
/* Verify that the overflow guard region remains unchanged. */
for (int i = 0; i < 64; i++)
if (raw_buf[size + align + i] != 0xAA)
FAIL_EXIT1 ("Buffer overflow was detected! (align=%zu, size=%zu)",
align, size);
bool is_sufficient = false;
if (res == 0 && result != NULL)
{
/* Generate the expected response to satisfy check_hostent. */
struct xmemstream expected;
xopen_memstream (&expected);
fprintf (expected.out, "name: %s\n", host_name);
for (int i = 0; i <= 60; i++)
fprintf (expected.out, "address: 127.126.125.%d\n", i);
xfclose_memstream (&expected);
check_hostent (host_name, &ret, expected.buffer);
free (expected.buffer);
is_sufficient = true; /* Buffer is sufficient. */
}
else if (res == ERANGE && err == NETDB_INTERNAL)
is_sufficient = false; /* Buffer is too small. */
else
FAIL_EXIT1 ("gethostbyname_r failed unexpectedly: res=%d, err=%d",
res, err);
free (raw_buf);
return is_sufficient;
}
static int
do_test (void)
{
struct resolv_test *aux = resolv_test_start
((struct resolv_redirect_config)
{
.response_callback = response,
});
int lower_bound = 512;
int upper_bound = 2048;
TEST_COMPARE (query_host (lower_bound, 0), false);
TEST_COMPARE (query_host (upper_bound, 0), true);
/* Finding the smallest hostent buffer size. */
while (upper_bound != lower_bound + 1)
{
int size = (lower_bound + upper_bound) / 2;
if (query_host (size, 0))
upper_bound = size;
else
lower_bound = size;
}
printf ("info: Boundary found. lower_bound=%d, upper_bound=%d\n",
lower_bound, upper_bound);
TEST_COMPARE (query_host (lower_bound, 0), false);
TEST_COMPARE (query_host (upper_bound, 0), true);
/* Trigger the vulnerability.
Test all misalignments (1-7 bytes). Note that it is expected that
for certain alignments, the required buffer size increases. This
happens because gethostbyname_r applies internal padding to align
pointers, which consumes available space. Therefore, a patched glibc
safely returns true (success) or false (ERANGE) depending on this
padding. A vulnerable glibc will fail to account for alignment
padding, overflow the buffer, and cause a test failure. */
for (size_t align = 1; align < 8; align++)
query_host (upper_bound, align);
resolv_test_end (aux);
return 0;
}
#include <support/test-driver.c>
+109
View File
@@ -0,0 +1,109 @@
/* Test that name lookups do not crash after a failing res_init call.
Copyright The GNU Toolchain Authors.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
/* When res_init is called on a thread whose resolver state has
already been initialized, it unconditionally invokes
__res_iclose(&_res, true) before __res_vinit. __res_iclose used
to NULL every _u._ext.nsaddrs[ns] without resetting
_u._ext.nscount, breaking the invariant that
__res_context_send's validation loop relies on. If __res_vinit
then failed (for example, because fopen("/etc/resolv.conf")
returned EMFILE), the resolver state was left with
_u._ext.nscount > 0 and _u._ext.nsaddrs[*] == NULL. The next
name lookup walked the validation loop and dereferenced NULL in
sock_eq.
This test reproduces the crash:
1. perform a name lookup so __res_context_send populates
_u._ext.nsaddrs[] and sets _u._ext.nscount;
2. drop RLIMIT_NOFILE so fopen("/etc/resolv.conf") fails with
EMFILE on the next call;
3. call res_init, which must report failure;
4. perform another name lookup, which must not crash. */
#include <arpa/nameser.h>
#include <netdb.h>
#include <resolv.h>
#include <sys/resource.h>
#include <support/check.h>
#include <support/resolv_test.h>
#include <support/xunistd.h>
static void
response (const struct resolv_response_context *ctx,
struct resolv_response_builder *b,
const char *qname, uint16_t qclass, uint16_t qtype)
{
resolv_response_init (b, (struct resolv_response_flags) { 0 });
resolv_response_add_question (b, qname, qclass, qtype);
resolv_response_section (b, ns_s_an);
resolv_response_open_record (b, qname, qclass, qtype, 0);
if (qtype == T_A)
{
const char ipv4[4] = { 192, 0, 2, 1 };
resolv_response_add_data (b, ipv4, sizeof (ipv4));
}
resolv_response_close_record (b);
}
static int
do_test (void)
{
struct resolv_test *aux = resolv_test_start
((struct resolv_redirect_config) { .response_callback = response });
/* Initial lookup. This drives __res_context_send through its init
block, which allocates _u._ext.nsaddrs[] and sets
_u._ext.nscount to _res.nscount. */
struct hostent *h = gethostbyname ("primer.example");
TEST_VERIFY_EXIT (h != NULL);
/* Drop RLIMIT_NOFILE so that the next fopen of /etc/resolv.conf
inside __resolv_conf_load fails with EMFILE. Already-open
descriptors (including those held by the resolv test harness)
remain valid; only new descriptor allocations are blocked. */
struct rlimit rl;
TEST_COMPARE (getrlimit (RLIMIT_NOFILE, &rl), 0);
rlim_t saved_cur = rl.rlim_cur;
rl.rlim_cur = 3;
TEST_COMPARE (setrlimit (RLIMIT_NOFILE, &rl), 0);
/* res_init must report failure: __res_iclose has already cleared
the extended state, __res_vinit then fails to reload
/etc/resolv.conf. */
TEST_COMPARE (res_init (), -1);
/* The repro: without the fix in __res_iclose, this call would
enter __res_context_send's validation loop with stale
_u._ext.nscount and NULL _u._ext.nsaddrs[0], dereference NULL
in sock_eq, and SIGSEGV. We do not care whether the lookup
succeeds (it will likely fail because socket() also returns
EMFILE), only that it returns without crashing. */
(void) gethostbyname ("after.example");
/* Restore the descriptor limit before resolv_test_end so its
cleanup work is not constrained. */
rl.rlim_cur = saved_cur;
TEST_COMPARE (setrlimit (RLIMIT_NOFILE, &rl), 0);
resolv_test_end (aux);
return 0;
}
#include <support/test-driver.c>
+2 -2
View File
@@ -1510,7 +1510,7 @@
} \
\
if (_FP_EXPBIAS_##fs + (rsize) - 1 < _FP_EXPMAX_##fs \
&& (rsigned) \
&& (rsigned) != 0 \
&& X##_s \
&& X##_e == _FP_EXPBIAS_##fs + (rsize) - 1) \
{ \
@@ -1555,7 +1555,7 @@
_FP_FRACBITS_##fs); \
_FP_FRAC_ASSEMBLE_##wc ((r), X, (rsize)); \
} \
if ((rsigned) && X##_s) \
if ((rsigned) != 0 && X##_s) \
(r) = -(r); \
if ((rsigned) == 2 && X##_e >= _FP_EXPBIAS_##fs + (rsize) - 1) \
{ \
+2
View File
@@ -327,6 +327,7 @@ tests := \
tst-scanf-binary-gnu11 \
tst-scanf-binary-gnu89 \
tst-scanf-bz27650 \
tst-scanf-bz34208 \
tst-scanf-intn \
tst-scanf-nan \
tst-scanf-round \
@@ -351,6 +352,7 @@ tests := \
tst-vfprintf-width-prec-alloc \
tst-vfscanf-bz34008 \
tst-wc-printf \
tst-wscanf-bz34208 \
tstdiomisc \
tstgetln \
tstscanf \
+1 -1
View File
@@ -305,7 +305,7 @@ do_test (int argc, char *argv[])
mtrace ();
if (PREC && printf ("prec:%i\n", PREC) < 0)
if (PREC != 0 && printf ("prec:%i\n", PREC) < 0)
{
perror ("printf");
return EXIT_FAILURE;
+103
View File
@@ -0,0 +1,103 @@
/* Test scanf pushback for incomplete nan/inf inputs (BZ #34208).
Copyright (C) 2026 The GNU Toolchain Authors.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
#include <array_length.h>
#include <stdio.h>
#include <support/check.h>
#include <wchar.h>
#ifdef TEST_WCHAR
# define CHAR_T wchar_t
# define WINT_T wint_t
# define FSCANF fwscanf
# define FPUTC fputwc
# define FGETC fgetwc
# define EOF_VALUE WEOF
# define L_(Str) L ## Str
#else
# define CHAR_T char
# define WINT_T int
# define FSCANF fscanf
# define FPUTC fputc
# define FGETC fgetc
# define EOF_VALUE EOF
# define L_(Str) Str
#endif
#define SCAN_FORMAT L_("%e")
static const float sentinel = -123.0f;
struct test
{
const CHAR_T *input;
long int expected_offset;
const CHAR_T *expected_rest;
};
static const struct test tests[] =
{
/* Original reproducer. The "[" is read while looking for the
second "n" in "nan", so it must be pushed back. */
{ L_("+NA[..z"), 3, L_("[..z") },
/* Mismatch while matching "nan(...)", "inf" and "infinity" must be
pushed back. */
{ L_("nan(@X"), 4, L_("@X") },
{ L_("iX"), 1, L_("X") },
{ L_("infiX"), 4, L_("X") },
};
static void
do_one_test (const struct test *test)
{
FILE *fp = tmpfile ();
TEST_VERIFY_EXIT (fp != NULL);
for (const CHAR_T *p = test->input; *p != '\0'; p++)
TEST_COMPARE (FPUTC (*p, fp), (WINT_T) *p);
TEST_COMPARE (fseek (fp, 0, SEEK_SET), 0);
float value = sentinel;
TEST_COMPARE (FSCANF (fp, SCAN_FORMAT, &value), 0);
TEST_COMPARE (ftell (fp), test->expected_offset);
TEST_VERIFY (value == sentinel);
for (const CHAR_T *p = test->expected_rest; *p != '\0'; p++)
TEST_COMPARE (FGETC (fp), (WINT_T) *p);
TEST_COMPARE (FGETC (fp), EOF_VALUE);
TEST_VERIFY (feof (fp));
TEST_VERIFY (! ferror (fp));
TEST_COMPARE (fclose (fp), 0);
}
static int
do_test (void)
{
for (size_t i = 0; i < array_length (tests); i++)
{
printf ("info: case %zu\n", i);
do_one_test (&tests[i]);
}
return 0;
}
#include <support/test-driver.c>
+20
View File
@@ -0,0 +1,20 @@
/* Test wscanf pushback for incomplete nan/inf inputs (BZ #34208).
Copyright (C) 2026 The GNU Toolchain Authors.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
#define TEST_WCHAR
#include "tst-scanf-bz34208.c"
+49 -24
View File
@@ -2048,17 +2048,23 @@ digits_extended_fail:
{
/* Maybe "nan". */
char_buffer_add (&charbuf, c);
if (__builtin_expect (width == 0
|| inchar () == EOF
|| TOLOWER (c) != L_('a'), 0))
if (__glibc_unlikely (width == 0 || inchar () == EOF))
conv_error ();
if (__glibc_unlikely (TOLOWER (c) != L_('a')))
{
ungetc (c, s);
conv_error ();
}
if (width > 0)
--width;
char_buffer_add (&charbuf, c);
if (__builtin_expect (width == 0
|| inchar () == EOF
|| TOLOWER (c) != L_('n'), 0))
if (__glibc_unlikely (width == 0 || inchar () == EOF))
conv_error ();
if (__glibc_unlikely (TOLOWER (c) != L_('n')))
{
ungetc (c, s);
conv_error ();
}
if (width > 0)
--width;
char_buffer_add (&charbuf, c);
@@ -2092,6 +2098,7 @@ digits_extended_fail:
{
/* Invalid character was observed. Only valid
characters are [a-zA-Z0-9_] and ')'. */
ungetc (c, s);
conv_error ();
break;
}
@@ -2113,17 +2120,23 @@ digits_extended_fail:
{
/* Maybe "inf" or "infinity". */
char_buffer_add (&charbuf, c);
if (__builtin_expect (width == 0
|| inchar () == EOF
|| TOLOWER (c) != L_('n'), 0))
if (__glibc_unlikely (width == 0 || inchar () == EOF))
conv_error ();
if (__glibc_unlikely (TOLOWER (c) != L_('n')))
{
ungetc (c, s);
conv_error ();
}
if (width > 0)
--width;
char_buffer_add (&charbuf, c);
if (__builtin_expect (width == 0
|| inchar () == EOF
|| TOLOWER (c) != L_('f'), 0))
if (__glibc_unlikely (width == 0 || inchar () == EOF))
conv_error ();
if (__glibc_unlikely (TOLOWER (c) != L_('f')))
{
ungetc (c, s);
conv_error ();
}
if (width > 0)
--width;
char_buffer_add (&charbuf, c);
@@ -2136,31 +2149,43 @@ digits_extended_fail:
--width;
/* Now we have to read the rest as well. */
char_buffer_add (&charbuf, c);
if (__builtin_expect (width == 0
|| inchar () == EOF
|| TOLOWER (c) != L_('n'), 0))
if (__glibc_unlikely (width == 0 || inchar () == EOF))
conv_error ();
if (__glibc_unlikely (TOLOWER (c) != L_('n')))
{
ungetc (c, s);
conv_error ();
}
if (width > 0)
--width;
char_buffer_add (&charbuf, c);
if (__builtin_expect (width == 0
|| inchar () == EOF
|| TOLOWER (c) != L_('i'), 0))
if (__glibc_unlikely (width == 0 || inchar () == EOF))
conv_error ();
if (__glibc_unlikely (TOLOWER (c) != L_('i')))
{
ungetc (c, s);
conv_error ();
}
if (width > 0)
--width;
char_buffer_add (&charbuf, c);
if (__builtin_expect (width == 0
|| inchar () == EOF
|| TOLOWER (c) != L_('t'), 0))
if (__glibc_unlikely (width == 0 || inchar () == EOF))
conv_error ();
if (__glibc_unlikely (TOLOWER (c) != L_('t')))
{
ungetc (c, s);
conv_error ();
}
if (width > 0)
--width;
char_buffer_add (&charbuf, c);
if (__builtin_expect (width == 0
|| inchar () == EOF
|| TOLOWER (c) != L_('y'), 0))
if (__glibc_unlikely (width == 0 || inchar () == EOF))
conv_error ();
if (__glibc_unlikely (TOLOWER (c) != L_('y')))
{
ungetc (c, s);
conv_error ();
}
if (width > 0)
--width;
char_buffer_add (&charbuf, c);
+5
View File
@@ -177,6 +177,11 @@ do_random_tests (void)
}
}
/* Add matching chars before the start to improve test coverage. */
i = random () & 31;
if (i < align)
p[i] = seek_char;
if (pos < len)
{
size_t r = random ();
-1
View File
@@ -1183,7 +1183,6 @@ resolv_test_start (struct resolv_redirect_config config)
/* Disable IPv6 name server addresses. The code below only
overrides the IPv4 addresses. */
__res_iclose (&_res, true);
_res._u._ext.nscount = 0;
/* Redirect queries to the server socket. */
if (test_verbose)
+57 -12
View File
@@ -27,22 +27,67 @@
#include <support/support_check_hugetlb.h>
#include <support/check.h>
bool
support_thp_is_madvise (void)
enum thp_mode_t
support_get_thp_mode (void)
{
int fd = open ("/sys/kernel/mm/transparent_hugepage/enabled", O_RDONLY);
int fd = open ("/sys/kernel/mm/transparent_hugepage/enabled",
O_RDONLY, 0);
if (fd == -1)
return false;
return thp_mode_not_supported;
#define MODE_MADVISE "always [madvise] never\n"
static const char mode_always[] = "[always] madvise never\n";
static const char mode_madvise[] = "always [madvise] never\n";
static const char mode_never[] = "always madvise [never]\n";
char str[sizeof(MODE_MADVISE)];
char str[sizeof(mode_always)];
ssize_t s = read (fd, str, sizeof (str));
close (fd);
if (s != sizeof (str) - 1)
return false;
if (s < 0 || s >= sizeof str)
return thp_mode_not_supported;
str[s] = '\0';
return strcmp (str, MODE_MADVISE) == 0;
if (s == sizeof (mode_always) - 1)
{
if (strcmp (str, mode_always) == 0)
return thp_mode_always;
else if (strcmp (str, mode_madvise) == 0)
return thp_mode_madvise;
else if (strcmp (str, mode_never) == 0)
return thp_mode_never;
}
return thp_mode_not_supported;
}
unsigned long int
support_get_thp_size (void)
{
int fd = open ("/sys/kernel/mm/transparent_hugepage/hpage_pmd_size",
O_RDONLY, 0);
if (fd == -1)
return 0;
char str[INT_BUFSIZE_BOUND (unsigned long int)];
ssize_t s = read (fd, str, sizeof (str));
close (fd);
if (s < 0)
return 0;
unsigned long int r = 0;
for (ssize_t i = 0; i < s; i++)
{
if (str[i] == '\n')
break;
r *= 10;
r += str[i] - '0';
}
return r;
}
bool
support_thp_work_madvise (void)
{
enum thp_mode_t mode = support_get_thp_mode ();
return mode == thp_mode_always || mode == thp_mode_madvise;
}
bool
@@ -55,7 +100,7 @@ support_hugepages_reserved (void)
char str[INT_BUFSIZE_BOUND(unsigned long int)];
ssize_t s = read (fd, str, sizeof (str));
close (fd);
if (s >= sizeof str || s < 0)
if (s < 0 || s >= sizeof str)
return false;
str[s] = '\0';
unsigned long int n = 0;
@@ -69,10 +114,10 @@ support_check_malloc_hugetlb (void)
return;
size_t hugetlb = TUNABLE_GET_FULL (glibc, malloc, hugetlb, size_t, NULL);
if (hugetlb == 1 && !support_thp_is_madvise ())
if (hugetlb == 1 && !support_thp_work_madvise ())
FAIL_UNSUPPORTED ("glibc.malloc.hugetlb=1 requires"
" /sys/kernel/mm/transparent_hugepage/enabled"
" = madvise");
" either always or madvise");
if (hugetlb == 2 && !support_hugepages_reserved ())
FAIL_UNSUPPORTED ("glibc.malloc.hugetlb=2 requires"
" /proc/sys/vm/nr_hugepages > 0");
+12
View File
@@ -21,6 +21,10 @@
#include <stdbool.h>
#include <sys/cdefs.h>
#undef attribute_hidden
#define attribute_hidden
#include <hugepages.h> /* For enum thp_mode_t. */
#undef attribute_hidden
__BEGIN_DECLS
@@ -43,6 +47,14 @@ bool support_hugepages_reserved (void);
so it is safe to call unconditionally. */
void support_check_malloc_hugetlb (void);
/* Returns Transparent Huge Pages (THP) mode from
/sys/kernel/mm/transparent_hugepage/enabled. */
extern enum thp_mode_t support_get_thp_mode (void);
/* Returns Transparent Huge Pages (THP) page size from
/sys/kernel/mm/transparent_hugepage/hpage_pmd_size. */
extern unsigned long int support_get_thp_size (void);
__END_DECLS
#endif /* SUPPORT_SUPPORT_CHECK_HUGETLB_H */
+62 -37
View File
@@ -42,24 +42,40 @@ float-advsimd-funcs = $(libmvec-supported-funcs)
double-advsimd-funcs = $(libmvec-supported-funcs)
float-sve-funcs = $(libmvec-supported-funcs)
double-sve-funcs = $(libmvec-supported-funcs)
mathvec-types = float double
mathvec-subdirs = advsimd sve
ifeq ($(subdir),mathvec)
libmvec-support = $(addsuffix f_advsimd,$(float-advsimd-funcs)) \
$(addsuffix _advsimd,$(double-advsimd-funcs)) \
$(addsuffix f_sve,$(float-sve-funcs)) \
$(addsuffix _sve,$(double-sve-funcs)) \
v_log_data \
v_exp_data \
v_log2_data \
v_log10_data \
erf_data \
erff_data \
v_exp_tail_data \
erfc_data \
erfcf_data \
v_pow_exp_data \
v_pow_log_data \
v_powf_data
generated-dirs += $(mathvec-subdirs)
generated += $(addsuffix /stamp,$(mathvec-subdirs))
before-compile += $(addprefix $(objpfx),$(addsuffix /stamp,$(mathvec-subdirs)))
$(addprefix $(objpfx),$(addsuffix /stamp,$(mathvec-subdirs))):
$(make-target-directory)
touch $@
sysd-rules-patterns += $(foreach dir,$(mathvec-subdirs),$(dir)/%:$(dir)/%)
define libmvec-routines-for
$(addprefix $(1)/,$(addsuffix f,$(float-$(1)-funcs))) \
$(addprefix $(1)/,$(double-$(1)-funcs))
endef
libmvec-vector-routines = $(foreach dir,$(mathvec-subdirs),\
$(call libmvec-routines-for,$(dir)))
libmvec-data-routines = v_log_data \
v_exp_data \
v_log2_data \
v_log10_data \
erf_data \
erff_data \
v_exp_tail_data \
erfc_data \
erfcf_data \
v_pow_exp_data \
v_pow_log_data \
v_powf_data
libmvec-support = $(libmvec-vector-routines) $(libmvec-data-routines)
endif
# Enable SVE for building libmvec. Since CFLAGS may contain a -mcpu or -march,
@@ -68,21 +84,27 @@ endif
sve-cflags = -mcpu=generic+sve -march=armv8-a+sve -mtune=neoverse-v1
bench-script-advsimd = bench_libmvec_advsimd.py
bench-script-sve = bench_libmvec_sve.py
define bench-libmvec-for
$(addprefix $(1)-$(2)-,$($(1)-$(2)-funcs))
endef
ifeq ($(build-mathvec),yes)
bench-libmvec = $(addprefix float-advsimd-,$(float-advsimd-funcs)) \
$(addprefix double-advsimd-,$(double-advsimd-funcs)) \
$(addprefix float-sve-,$(float-sve-funcs)) \
$(addprefix double-sve-,$(double-sve-funcs))
bench-libmvec = $(foreach type,$(mathvec-types),\
$(foreach dir,$(mathvec-subdirs),\
$(call bench-libmvec-for,$(type),$(dir))))
endif
$(objpfx)bench-float-advsimd-%.c:
$(PYTHON) $(..)sysdeps/aarch64/fpu/scripts/bench_libmvec_advsimd.py $(basename $(@F)) > $@
$(objpfx)bench-double-advsimd-%.c:
$(PYTHON) $(..)sysdeps/aarch64/fpu/scripts/bench_libmvec_advsimd.py $(basename $(@F)) > $@
$(objpfx)bench-float-sve-%.c:
$(PYTHON) $(..)sysdeps/aarch64/fpu/scripts/bench_libmvec_sve.py $(basename $(@F)) > $@
$(objpfx)bench-double-sve-%.c:
$(PYTHON) $(..)sysdeps/aarch64/fpu/scripts/bench_libmvec_sve.py $(basename $(@F)) > $@
define bench-libmvec-rule
$(objpfx)bench-$(1)-$(2)-%.c:
$$(PYTHON) $$(..)sysdeps/aarch64/fpu/scripts/$$(bench-script-$(2)) $$(basename $$(@F)) > $$@
endef
$(foreach type,$(mathvec-types),\
$(foreach dir,$(mathvec-subdirs),\
$(eval $(call bench-libmvec-rule,$(type),$(dir)))))
ifeq (${STATIC-BENCHTESTS},yes)
libmvec-benchtests = $(common-objpfx)mathvec/libmvec.a $(common-objpfx)math/libm.a
@@ -93,21 +115,24 @@ endif
$(addprefix $(objpfx)bench-,$(bench-libmvec)): $(libmvec-benchtests)
ifeq ($(build-mathvec),yes)
libmvec-tests += float-advsimd double-advsimd float-sve double-sve
libmvec-tests += $(foreach type,$(mathvec-types),\
$(foreach dir,$(mathvec-subdirs),$(type)-$(dir)))
endif
define sve-float-cflags-template
CFLAGS-$(1)f_sve.c += $(sve-cflags)
CFLAGS-bench-float-sve-$(1).c += $(sve-cflags)
define sve-bench-cflags-template
CFLAGS-bench-$(1)-sve-$(2).c += $(sve-cflags)
endef
define sve-double-cflags-template
CFLAGS-$(1)_sve.c += $(sve-cflags)
CFLAGS-bench-double-sve-$(1).c += $(sve-cflags)
$(foreach type,$(mathvec-types),\
$(foreach f,$($(type)-sve-funcs),\
$(eval $(call sve-bench-cflags-template,$(type),$(f)))))
# Specialize CFLAGS used for building SVE sources.
define sve-object-cflags-template
$(objpfx)sve/%$(1): CFLAGS += $(sve-cflags)
endef
$(foreach f,$(float-sve-funcs), $(eval $(call sve-float-cflags-template,$(f))))
$(foreach f,$(double-sve-funcs), $(eval $(call sve-double-cflags-template,$(f))))
$(foreach o,$(all-object-suffixes),$(eval $(call sve-object-cflags-template,$(o))))
CFLAGS-test-float-sve-wrappers.c = $(sve-cflags)
CFLAGS-test-double-sve-wrappers.c = $(sve-cflags)

Some files were not shown because too many files have changed in this diff Show More