Starting with commit
glibc-2.18.90-470-g2a939a7e6d81f109d49306bc2e10b4ac9ceed8f9 that
introduced substitution of dynamic string tokens in fillin_rpath,
_dl_init_paths invokes _dl_dst_substitute for $LD_LIBRARY_PATH twice:
the first time it's called directly, the second time the result
is passed on to fillin_rpath which calls expand_dynamic_string_token
which in turn calls _dl_dst_substitute, leading to the following
behaviour:
$ mkdir -p /tmp/'$ORIGIN' && cd /tmp/'$ORIGIN' &&
echo 'int main(){}' |gcc -xc - &&
strace -qq -E LD_LIBRARY_PATH='$ORIGIN' -e /open ./a.out
open("/tmp//tmp/$ORIGIN/tls/x86_64/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/tmp//tmp/$ORIGIN/tls/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/tmp//tmp/$ORIGIN/x86_64/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/tmp//tmp/$ORIGIN/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
Fix this by removing the direct _dl_dst_substitute invocation.
* elf/dl-load.c (_dl_init_paths): Remove _dl_dst_substitute preparatory
code and invocation.
There are three flavors of the crt startup code:
1) crt1.o used for non-pie,
2) Scrt1.o used for dynamic linked pie (dynamic linker relocates),
3) rcrt1.o used for static linked pie (self relocation is needed)
In the --enable-static-pie case crt1.o is built with -DPIC and in case
of static linking it interposes _dl_relocate_static_pie in libc to
avoid self relocation.
Scrt1.o is built with -DPIC -DSHARED and it relies on GOT entries that
the static linker cannot relax and thus need relocation before the
start code is executed, so rcrt1.o needs separate implementation.
This implementation does not work for .text > 4G position independent
executables, which is fine since the toolchain does not support
-mcmodel=large with -fPIE.
Tests pass with ld/22269 and ld/22263 binutils bugs fixed.
* sysdeps/aarch64/start.S (_start): Handle PIC && !SHARED case.
ldconfig supports `include' directives and use the glob function to
process them. The glob function sort entries according to the LC_COLLATE
category. When using a standard "include /etc/ld.so.conf.d/*.conf" entry
in /etc/ld.so.conf, the order therefore depends on the locale used to
run ldconfig. A few examples of locale specific order that might be
disturbing in that context compared to the C locale:
- The cs_CZ and sk_SK locales sort the digits after the letters.
- The et_EE locale sorts the 'z' between 's' and 't'.
This patch fixes that by setting LC_COLLATE to C in order to process
files in deterministic order, independently of the locale used to launch
ldconfig.
NOTE: This should NOT be backported to older release branches.
Changelog:
[BZ #22505]
* elf/ldconfig.c (main): Call setlocale to force LC_COLLATE to C.
The test tst-leaks1 exercises calling dlopen with a $ORIGIN DST.
This results in a theoretical leak e.g.
Memory not freed:
-----------------
Address Size Caller
0x0000000001d766c0 0x21 at 0x7fb1bd8bf4ab
Or as seen via valgrind:
==27582== 33 bytes in 1 blocks are still reachable in loss record 1 of 1
==27582== at 0x4C2CB6B: malloc (vg_replace_malloc.c:299)
==27582== by 0x40124AA: _dl_get_origin (dl-origin.c:50)
==27582== by 0x4007DB9: expand_dynamic_string_token (dl-load.c:382)
==27582== by 0x400899C: _dl_map_object (dl-load.c:2160)
==27582== by 0x4013020: dl_open_worker (dl-open.c:224)
==27582== by 0x5166F9B: _dl_catch_exception (dl-error-skeleton.c:198)
==27582== by 0x4012BD9: _dl_open (dl-open.c:594)
==27582== by 0x4E39EF5: dlopen_doit (dlopen.c:66)
==27582== by 0x5166F9B: _dl_catch_exception (dl-error-skeleton.c:198)
==27582== by 0x516700E: _dl_catch_error (dl-error-skeleton.c:217)
==27582== by 0x4E3A514: _dlerror_run (dlerror.c:162)
==27582== by 0x4E39F70: dlopen@@GLIBC_2.2.5 (dlopen.c:87)
There is no real leak.
The calling link map (the executable's link map) has it's l_origin
expanded for future use as part of _dl_get_origin, and that results
in the main executable link map having a N-byte allocation for
l->l_origin that is never freed since the executable's link map is
just a part of the process.
To take this into account we do one dlopen with $ORIGIN before
calling mtrace to force the initialization of the executable link
map.
Signed-off-by: Carlos O'Donell <carlos@redhat.com>
Static PIE extends address space layout randomization to static
executables. It provides additional security hardening benefits at
the cost of some memory and performance.
Dynamic linker, ld.so, is a standalone program which can be loaded at
any address. This patch adds a configure option, --enable-static-pie,
to embed the part of ld.so in static executable to create static position
independent executable (static PIE). A static PIE is similar to static
executable, but can be loaded at any address without help from a dynamic
linker. When --enable-static-pie is used to configure glibc, libc.a is
built as PIE and all static executables, including tests, are built as
static PIE. The resulting libc.a can be used together with GCC 8 or
above to build static PIE with the compiler option, -static-pie. But
GCC 8 isn't required to build glibc with --enable-static-pie. Only GCC
with PIE support is needed. When an older GCC is used to build glibc
with --enable-static-pie, proper input files are passed to linker to
create static executables as static PIE, together with "-z text" to
prevent dynamic relocations in read-only segments, which are not allowed
in static PIE.
The following changes are made for static PIE:
1. Add a new function, _dl_relocate_static_pie, to:
a. Get the run-time load address.
b. Read the dynamic section.
c. Perform dynamic relocations.
Dynamic linker also performs these steps. But static PIE doesn't load
any shared objects.
2. Call _dl_relocate_static_pie at entrance of LIBC_START_MAIN in
libc.a. crt1.o, which is used to create dynamic and non-PIE static
executables, is updated to include a dummy _dl_relocate_static_pie.
rcrt1.o is added to create static PIE, which will link in the real
_dl_relocate_static_pie. grcrt1.o is also added to create static PIE
with -pg. GCC 8 has been updated to support rcrt1.o and grcrt1.o for
static PIE.
Static PIE can work on all architectures which support PIE, provided:
1. Target must support accessing of local functions without dynamic
relocations, which is needed in start.S to call __libc_start_main with
function addresses of __libc_csu_init, __libc_csu_fini and main. All
functions in static PIE are local functions. If PIE start.S can't reach
main () defined in a shared object, the code sequence:
pass address of local_main to __libc_start_main
...
local_main:
tail call to main via PLT
can be used.
2. start.S is updated to check PIC instead SHARED for PIC code path and
avoid dynamic relocation, when PIC is defined and SHARED isn't defined,
to support static PIE.
3. All assembly codes are updated check PIC instead SHARED for PIC code
path to avoid dynamic relocations in read-only sections.
4. All assembly codes are updated check SHARED instead PIC for static
symbol name.
5. elf_machine_load_address in dl-machine.h are updated to support static
PIE.
6. __brk works without TLS nor dynamic relocations in read-only section
so that it can be used by __libc_setup_tls to initializes TLS in static
PIE.
NB: When glibc is built with GCC defaulted to PIE, libc.a is compiled
with -fPIE, regardless if --enable-static-pie is used to configure glibc.
When glibc is configured with --enable-static-pie, libc.a is compiled
with -fPIE, regardless whether GCC defaults to PIE or not. The same
libc.a can be used to build both static executable and static PIE.
There is no need for separate PIE copy of libc.a.
On x86-64, the normal static sln:
text data bss dec hex filename
625425 8284 5456 639165 9c0bd elf/sln
the static PIE sln:
text data bss dec hex filename
657626 20636 5392 683654 a6e86 elf/sln
The code size is increased by 5% and the binary size is increased by 7%.
Linker requirements to build glibc with --enable-static-pie:
1. Linker supports --no-dynamic-linker to remove PT_INTERP segment from
static PIE.
2. Linker can create working static PIE. The x86-64 linker needs the
fix for
https://sourceware.org/bugzilla/show_bug.cgi?id=21782
The i386 linker needs to be able to convert "movl main@GOT(%ebx), %eax"
to "leal main@GOTOFF(%ebx), %eax" if main is defined locally.
Binutils 2.29 or above are OK for i686 and x86-64. But linker status for
other targets need to be verified.
3. Linker should resolve undefined weak symbols to 0 in static PIE:
https://sourceware.org/bugzilla/show_bug.cgi?id=22269
4. Many ELF backend linkers incorrectly check bfd_link_pic for TLS
relocations, which should check bfd_link_executable instead:
https://sourceware.org/bugzilla/show_bug.cgi?id=22263
Tested on aarch64, i686 and x86-64.
Using GCC 7 and binutils master branch, build-many-glibcs.py with
--enable-static-pie with all patches for static PIE applied have the
following build successes:
PASS: glibcs-aarch64_be-linux-gnu build
PASS: glibcs-aarch64-linux-gnu build
PASS: glibcs-armeb-linux-gnueabi-be8 build
PASS: glibcs-armeb-linux-gnueabi build
PASS: glibcs-armeb-linux-gnueabihf-be8 build
PASS: glibcs-armeb-linux-gnueabihf build
PASS: glibcs-arm-linux-gnueabi build
PASS: glibcs-arm-linux-gnueabihf build
PASS: glibcs-arm-linux-gnueabihf-v7a build
PASS: glibcs-arm-linux-gnueabihf-v7a-disable-multi-arch build
PASS: glibcs-m68k-linux-gnu build
PASS: glibcs-microblazeel-linux-gnu build
PASS: glibcs-microblaze-linux-gnu build
PASS: glibcs-mips64el-linux-gnu-n32 build
PASS: glibcs-mips64el-linux-gnu-n32-nan2008 build
PASS: glibcs-mips64el-linux-gnu-n32-nan2008-soft build
PASS: glibcs-mips64el-linux-gnu-n32-soft build
PASS: glibcs-mips64el-linux-gnu-n64 build
PASS: glibcs-mips64el-linux-gnu-n64-nan2008 build
PASS: glibcs-mips64el-linux-gnu-n64-nan2008-soft build
PASS: glibcs-mips64el-linux-gnu-n64-soft build
PASS: glibcs-mips64-linux-gnu-n32 build
PASS: glibcs-mips64-linux-gnu-n32-nan2008 build
PASS: glibcs-mips64-linux-gnu-n32-nan2008-soft build
PASS: glibcs-mips64-linux-gnu-n32-soft build
PASS: glibcs-mips64-linux-gnu-n64 build
PASS: glibcs-mips64-linux-gnu-n64-nan2008 build
PASS: glibcs-mips64-linux-gnu-n64-nan2008-soft build
PASS: glibcs-mips64-linux-gnu-n64-soft build
PASS: glibcs-mipsel-linux-gnu build
PASS: glibcs-mipsel-linux-gnu-nan2008 build
PASS: glibcs-mipsel-linux-gnu-nan2008-soft build
PASS: glibcs-mipsel-linux-gnu-soft build
PASS: glibcs-mips-linux-gnu build
PASS: glibcs-mips-linux-gnu-nan2008 build
PASS: glibcs-mips-linux-gnu-nan2008-soft build
PASS: glibcs-mips-linux-gnu-soft build
PASS: glibcs-nios2-linux-gnu build
PASS: glibcs-powerpc64le-linux-gnu build
PASS: glibcs-powerpc64-linux-gnu build
PASS: glibcs-tilegxbe-linux-gnu-32 build
PASS: glibcs-tilegxbe-linux-gnu build
PASS: glibcs-tilegx-linux-gnu-32 build
PASS: glibcs-tilegx-linux-gnu build
PASS: glibcs-tilepro-linux-gnu build
and the following build failures:
FAIL: glibcs-alpha-linux-gnu build
elf/sln is failed to link due to:
assertion fail bfd/elf64-alpha.c:4125
This is caused by linker bug and/or non-PIC code in PIE libc.a.
FAIL: glibcs-hppa-linux-gnu build
elf/sln is failed to link due to:
collect2: fatal error: ld terminated with signal 11 [Segmentation fault]
https://sourceware.org/bugzilla/show_bug.cgi?id=22537
FAIL: glibcs-ia64-linux-gnu build
elf/sln is failed to link due to:
collect2: fatal error: ld terminated with signal 11 [Segmentation fault]
FAIL: glibcs-powerpc-linux-gnu build
FAIL: glibcs-powerpc-linux-gnu-soft build
FAIL: glibcs-powerpc-linux-gnuspe build
FAIL: glibcs-powerpc-linux-gnuspe-e500v1 build
elf/sln is failed to link due to:
ld: read-only segment has dynamic relocations.
This is caused by linker bug and/or non-PIC code in PIE libc.a. See:
https://sourceware.org/bugzilla/show_bug.cgi?id=22264
FAIL: glibcs-powerpc-linux-gnu-power4 build
elf/sln is failed to link due to:
findlocale.c:96:(.text+0x22c): @local call to ifunc memchr
This is caused by linker bug and/or non-PIC code in PIE libc.a.
FAIL: glibcs-s390-linux-gnu build
elf/sln is failed to link due to:
collect2: fatal error: ld terminated with signal 11 [Segmentation fault], core dumped
assertion fail bfd/elflink.c:14299
This is caused by linker bug and/or non-PIC code in PIE libc.a.
FAIL: glibcs-sh3eb-linux-gnu build
FAIL: glibcs-sh3-linux-gnu build
FAIL: glibcs-sh4eb-linux-gnu build
FAIL: glibcs-sh4eb-linux-gnu-soft build
FAIL: glibcs-sh4-linux-gnu build
FAIL: glibcs-sh4-linux-gnu-soft build
elf/sln is failed to link due to:
ld: read-only segment has dynamic relocations.
This is caused by linker bug and/or non-PIC code in PIE libc.a. See:
https://sourceware.org/bugzilla/show_bug.cgi?id=22263
Also TLS code sequence in SH assembly syscalls in glibc doesn't match TLS
code sequence expected by ld:
https://sourceware.org/bugzilla/show_bug.cgi?id=22270
FAIL: glibcs-sparc64-linux-gnu build
FAIL: glibcs-sparcv9-linux-gnu build
FAIL: glibcs-tilegxbe-linux-gnu build
FAIL: glibcs-tilegxbe-linux-gnu-32 build
FAIL: glibcs-tilegx-linux-gnu build
FAIL: glibcs-tilegx-linux-gnu-32 build
FAIL: glibcs-tilepro-linux-gnu build
elf/sln is failed to link due to:
ld: read-only segment has dynamic relocations.
This is caused by linker bug and/or non-PIC code in PIE libc.a. See:
https://sourceware.org/bugzilla/show_bug.cgi?id=22263
[BZ #19574]
* INSTALL: Regenerated.
* Makeconfig (real-static-start-installed-name): New.
(pic-default): Updated for --enable-static-pie.
(pie-default): New for --enable-static-pie.
(default-pie-ldflag): Likewise.
(+link-static-before-libc): Replace $(DEFAULT-LDFLAGS-$(@F))
with $(if $($(@F)-no-pie),$(no-pie-ldflag),$(default-pie-ldflag)).
Replace $(static-start-installed-name) with
$(real-static-start-installed-name).
(+prectorT): Updated for --enable-static-pie.
(+postctorT): Likewise.
(CFLAGS-.o): Add $(pie-default).
(CFLAGS-.op): Likewise.
* NEWS: Mention --enable-static-pie.
* config.h.in (ENABLE_STATIC_PIE): New.
* configure.ac (--enable-static-pie): New configure option.
(have-no-dynamic-linker): New LIBC_CONFIG_VAR.
(have-static-pie): Likewise.
Enable static PIE if linker supports --no-dynamic-linker.
(ENABLE_STATIC_PIE): New AC_DEFINE.
(enable-static-pie): New LIBC_CONFIG_VAR.
* configure: Regenerated.
* csu/Makefile (omit-deps): Add r$(start-installed-name) and
gr$(start-installed-name) for --enable-static-pie.
(extra-objs): Likewise.
(install-lib): Likewise.
(extra-objs): Add static-reloc.o and static-reloc.os
($(objpfx)$(start-installed-name)): Also depend on
$(objpfx)static-reloc.o.
($(objpfx)r$(start-installed-name)): New.
($(objpfx)g$(start-installed-name)): Also depend on
$(objpfx)static-reloc.os.
($(objpfx)gr$(start-installed-name)): New.
* csu/libc-start.c (LIBC_START_MAIN): Call _dl_relocate_static_pie
in libc.a.
* csu/libc-tls.c (__libc_setup_tls): Add main_map->l_addr to
initimage.
* csu/static-reloc.c: New file.
* elf/Makefile (routines): Add dl-reloc-static-pie.
(elide-routines.os): Likewise.
(DEFAULT-LDFLAGS-tst-tls1-static-non-pie): Removed.
(tst-tls1-static-non-pie-no-pie): New.
* elf/dl-reloc-static-pie.c: New file.
* elf/dl-support.c (_dl_get_dl_main_map): New function.
* elf/dynamic-link.h (ELF_DURING_STARTUP): Also check
STATIC_PIE_BOOTSTRAP.
* elf/get-dynamic-info.h (elf_get_dynamic_info): Likewise.
* gmon/Makefile (tests): Add tst-gmon-static-pie.
(tests-static): Likewise.
(DEFAULT-LDFLAGS-tst-gmon-static): Removed.
(tst-gmon-static-no-pie): New.
(CFLAGS-tst-gmon-static-pie.c): Likewise.
(CRT-tst-gmon-static-pie): Likewise.
(tst-gmon-static-pie-ENV): Likewise.
(tests-special): Likewise.
($(objpfx)tst-gmon-static-pie.out): Likewise.
(clean-tst-gmon-static-pie-data): Likewise.
($(objpfx)tst-gmon-static-pie-gprof.out): Likewise.
* gmon/tst-gmon-static-pie.c: New file.
* manual/install.texi: Document --enable-static-pie.
* sysdeps/generic/ldsodefs.h (_dl_relocate_static_pie): New.
(_dl_get_dl_main_map): Likewise.
* sysdeps/i386/configure.ac: Check if linker supports static PIE.
* sysdeps/x86_64/configure.ac: Likewise.
* sysdeps/i386/configure: Regenerated.
* sysdeps/x86_64/configure: Likewise.
* sysdeps/mips/Makefile (ASFLAGS-.o): Add $(pie-default).
(ASFLAGS-.op): Likewise.
Three tests fail with a read-only source directory because they try to
write into the source directory. None of these write into it in a way
that should actually be problematic for concurrent builds sharing the
same writable source directory, but avoiding any writing into the
source directory (from testing, or from building glibc if the source
timestamps are properly ordered) is still a good idea, as being able
to build with read-only sources helps make sure there isn't anything
that could cause problems for concurrent builds.
This patch changes the tests in question to use either /tmp or the
build directory to write their temporary files (or to test O_TMPFILE,
as applicable).
Tested for x86_64.
* io/Makefile (tst-open-tmpfile-ARGS): New variable.
* posix/tst-mmap-offset.c (fname): Use /tmp.
* stdlib/tst-setcontext3.sh (tempfile): Use ${objpfx}.
The conventional configure triplet for ARM GNU/Linux with hard-float
ABI is arm-*-linux-gnueabihf. However, GCC does not automatically use
the hard-float ABI based on that triplet. This patch fixes
build-many-glibcs.py to pass --with-float=hard so that the
arm-linux-gnueabihf configurations actually build with the intended
ABI.
Tested building the affected configurations with build-many-glibcs.py.
* scripts/build-many-glibcs.py (Context.add_all_configs): Use
--with-float=hard for arm-linux-gnueabihf configurations.
Building and installing glibc leaves .mo files (compiled message
translations) behind in the source directory. Building those files in
the source directory may once have made sense, if they were included
in release tarballs; now that release tarballs are just the output of
"git archive", building any non-checked-in files in the source
directory does not make sense. This patch changes these files to be
built in the build directory instead. The realclean rule is changed
to simply adding the .mo files to the "generated" variable, since once
the files are in the build directory it make no sense to exclude them
from normal cleanup rules.
This is necessary but not sufficient to avoid build-many-glibcs.py
needing to copy the glibc source directory. Its list of files to
touch on checkout to avoid subsequent regeneration (configure,
preconfigure, *-kw.h) is incomplete (missing at least INSTALL,
sysdeps/gnu/errlist.c, posix/testcases.h, posix/ptestcases.h,
locale/C-translit.h, (only regenerated for Hurd builds)
sysdeps/mach/hurd/bits/errno.h, (only regenerated for 32-bit SPARC
builds) sysdeps/sparc/sparc32/{sdiv,udiv,rem,urem}.S) - the existing
list may be sufficient to prevent regeneration that actually changes
the file contents depending on the installed build tools, but not to
ensure there is no regeneration at all - and there might well be other
things writing into the source directory in the course of building and
testing (so needing appropriate testing with read-only source
directories with different timestamp orderings to find and eliminate
all such cases).
Tested for x86_64.
[BZ #14121]
* po/Makefile (generated): Add $(ALL_LINGUAS:%=%.mo).
(%.mo): Change to $(objpfx)%.mo. Use $(make-target-directory).
($(mo-installed)): Use $(objpfx)%.mo.
(realclean): Remove rule.
po/Makefile has both old code for copying .po files from a shared
directory /com/share/ftp/gnu/po/maint/glibc (presumably once present
on some GNU server), and new code for downloading them from the
Translation Project. This patch removes the old code, leading only
the new code.
Tested for x86_64.
* po/Makefile (linguas): Remove rule and dependencies.
(linguas.mo): Likewise.
(.PHONY): Do not depend on linguas and linguas.mo.
(podir): Remove variable.
(pofiles): Likewise.
[$(pofiles)] (%.po): Remove rule.
While working on another patch I noticed that (a)
sysdeps/sparc/sparc32/Makefile is the only place with special
realclean settings, apart from po/, and (b) the generated files with a
rule in that Makefile to generate them (using m4) had been patched
manually so no longer corresponded with the output of the generator -
so if the timestamps were wrong, a build would result in changes to
the files in the source directory. (They also didn't correspond
because of changes in make 3.81 to how make handles whitespace at the
start of a line in a sequence of backslash-newline continuation lines
within a recipe.)
This patch fixes the generation and output files to match. The issue
with make and whitespace at start of continuation lines is fixed by
putting those newlines outside of arguments to echo, so the number of
spaces in the argument matches the number in the existing generated
files. Then divrem.m4 is changed to avoid generating whitespace-only
lines (my fix to the outputs from 2013; this fix to the generator also
changes the indentation of a label in the output files) and to
generate an alias in udiv.S (Adhemerval's fix from March).
build-many-glibcs.py doesn't have a non-v9 SPARC configuration,
because non-v9 32-bit SPARC didn't build when I set up
build-many-glibcs.py but sparcv9 did build. Whether or not non-v9
32-bit SPARC now builds (or indeed whether or not support for it is
obsolete), I tested by removing the sparcv8 and sparcv9 versions of
the four files in question, so forcing the generated files to be built
and used, and the compilation parts of the glibc testsuite passed.
* sysdeps/sparc/sparc32/Makefile
($(divrem:%=$(sysdep_dir)/sparc/sparc32/%.S)): Do not include
start-of-line whitespace in argument of echo.
* sysdeps/sparc/sparc32/divrem.m4: Avoid generating lines starting
with whitespace. Generate __wrap_.udiv alias.
* sysdeps/sparc/sparc32/rem.S: Regenerated.
* sysdeps/sparc/sparc32/sdiv.S: Likewise.
* sysdeps/sparc/sparc32/udiv.S: Likewise.
* sysdeps/sparc/sparc32/urem.S: Likewise.
This patch makes use of vectors for aligned inputs. Improvements
upto 30% seen for larger aligned inputs.
Reviewed-by: Tulio Magno Quites Machado Filho <tuliom@linux.vnet.ibm.com>
SXID_ERASE is implicit for all environment variables. Avoid
mentioning it in the tunables list; that way only the ones with
SXID_IGNORE remain prominent and mentioned. TODO: we need to audit
each of those cases and drop them to SXID_ERASE wherever possible.
Support added to identify Sparc M7/T7/S7/M8/T8 processor capability.
Performance tests run on Sparc S7 using new code and old niagara4 code.
Optimizations for memset also apply to bzero as they share code.
For memset/bzero, performance comparison with niagara4 code:
For memset nonzero data,
256-1023 bytes - 60-90% gain (in cache); 5% gain (out of cache)
1K+ bytes - 80-260% gain (in cache); 40-80% gain (out of cache)
For memset zero data (and bzero),
256-1023 bytes - 80-120% gain (in cache), 0% gain (out of cache)
1024+ bytes - 2-4x gain (in cache), 10-35% gain (out of cache)
Tested in sparcv9-*-* and sparc64-*-* targets in both multi and
non-multi arch configurations.
Patrick McGehearty <patrick.mcgehearty@oracle.com>
Adhemerval Zanella <adhemerval.zanella@linaro.org>
* sysdeps/sparc/sparc32/sparcv9/multiarch/Makefile
(sysdeps_routines): Add memset-niagara7.
* sysdeps/sparc/sparc64/multiarch/Makefile (sysdes_rotuines):
Likewise.
* sysdeps/sparc/sparc32/sparcv9/multiarch/memset-niagara7.S: New
file.
* sysdeps/sparc/sparc64/multiarch/memset-niagara7.S: Likewise.
* sysdeps/sparc/sparc64/multiarch/ifunc-impl-list.c
(__libc_ifunc_impl_list): Add __bzero_niagara7 and __memset_niagara7.
* sysdeps/sparc/sparc64/multiarch/ifunc-memset.h (IFUNC_SELECTOR):
Add niagara7 option.
* NEWS: Mention sparc m7 optimized memcpy, mempcpy, memmove, and
memset.
Support added to identify Sparc M7/T7/S7/M8/T8 processor capability.
Performance tests run on Sparc S7 using new code and old niagara4 code.
Optimizations for memcpy also apply to mempcpy and memmove
where they share code. Optimizations for memset also apply
to bzero as they share code.
For memcpy/mempcpy/memmove, performance comparison with niagara4 code:
Long word aligned data
0-127 bytes - minimal changes
128-1023 bytes - 7-30% gain
1024+ bytes - 1-7% gain (in cache); 30-100% gain (out of cache)
Word aligned data
0-127 bytes - 50%+ gain
128-1023 bytes - 10-200% gain
1024+ bytes - 0-15% gain (in cache); 5-50% gain (out of cache)
Unaligned data
0-127 bytes - 0-70%+ gain
128-447 bytes - 40-80%+ gain
448-511 bytes - 1-3% loss
512-4096 bytes - 2-3% gain (in cache); 0-20% gain (out of cache)
4096+ bytes - ± 3% (in cache); 20-50% gain (out of cache)
Tested in sparcv9-*-* and sparc64-*-* targets in both multi and
non-multi arch configurations.
Patrick McGehearty <patrick.mcgehearty@oracle.com>
Adhemerval Zanella <adhemerval.zanella@linaro.org>
* sysdeps/sparc/sparc32/sparcv9/multiarch/Makefile
(sysdeps_routines): Add memcpy-memmove-niagara7 and memmove-ultra1.
* sysdeps/sparc/sparc64/multiarch/Makefile (sysdeps_routines):
Likewise.
* sysdeps/sparc/sparc32/sparcv9/multiarch/memcpy-memmove-niagara7.S:
New file.
* sysdeps/sparc/sparc32/sparcv9/multiarch/memmove-ultra1.S: Likewise.
* sysdeps/sparc/sparc32/sparcv9/multiarch/rtld-memmove.c: Likewise.
* sysdeps/sparc/sparc64/multiarch/ifunc-impl-list.c
(__libc_ifunc_impl_list): Add __memcpy_niagara7, __mempcpy_niagara7,
and __memmove_niagara7.
* sysdeps/sparc/sparc64/multiarch/ifunc-memcpy.h (IFUNC_SELECTOR):
Add niagara7 option.
* sysdeps/sparc/sparc64/multiarch/memmove.c: New file.
* sysdeps/sparc/sparc64/multiarch/ifunc-memmove.h: Likewise.
* sysdeps/sparc/sparc64/multiarch/memcpy-memmove-niagara7.S: Likewise.
* sysdeps/sparc/sparc64/multiarch/memmove-ultra1.S: Likewise.
* sysdeps/sparc/sparc64/multiarch/rtld-memmove.c: Likewise.
Tested in sparcv9-*-* and sparc64-*-* targets in both non-multi-arch and
multi-arch configurations.
* sysdeps/sparc/sparc32/sparcv9/memmove.S: New file.
* sysdeps/sparc/sparc32/sparcv9/rtld-memmove.c: Likewise.
* sysdeps/sparc/sparc64/memmove.S: Likewise.
* sysdeps/sparc/sparc64/rtld-memmove.c: Likewise.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
This patch adds support for the ADP (also known as adi) hardware
capability, as reported by the kernel sparc port when running on M7
machines.
Tested in both sparcv9-*-* and sparc64-*-* targets.
* sysdeps/sparc/bits/hwcap.h (HWCAP_SPARC_ADP): Defined.
* sysdeps/sparc/dl-procinfo.c: Added "adp" to the
_dl_sparc_cap_flags array.
* sysdeps/sparc/dl-procinfo.h (_DL_HWCAP_COUNT): Increment.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Replace the simple byte-wise compare in the misaligned case with a
dword compare with page boundary checks in place. For simplicity I've
chosen a 4K page boundary so that we don't have to query the actual
page size on the system.
This results in up to 3x improvement in performance in the unaligned
case on falkor and about 2.5x improvement on mustang as measured using
bench-strcmp.
* sysdeps/aarch64/strcmp.S (misaligned8): Compare dword at a
time whenever possible.
A glibc master build with --enable-nss-crypt using the NSS
crypto libraries fails during make check with the following error:
<command-line>:0:0: error: "USE_CRYPT" redefined [-Werror]
<command-line>:0:0: note: this is the location of the previous
definition
This is caused by commit 36975e8e7e
by H.J. Lu which replaces all = with +=. The fix is to undefine
USE_CRYPT before defining it to zero.
Committed as an obvious fix. Fixes the build issue on x86_64 with
no regressions.
Signed-off-by: Carlos O'Donell <carlos@redhat.com>
The default sysdeps/ieee754 fma implementations rely on exceptions and
rounding modes to achieve correct results through internal use of
round-to-odd. Thus, glibc configurations without support for
exceptions and rounding modes instead need to use implementations of
fma based on soft-fp.
At present, this is achieved via having implementation files in
soft-fp/ that are #included by sysdeps files for each glibc
configuration that needs them. In general this means such a
configuration has its own s_fma.c and s_fmaf.c.
TS 18661-1 adds functions that do an operation (+ - * / sqrt fma) on
arguments wider than the return type, with a single rounding of the
infinite-precision result to that return type. These are also
naturally implemented using round-to-odd on platforms with hardware
support for rounding modes and exceptions but lacking hardware support
for these narrowing operations themselves. (Platforms that have
direct hardware support for such narrowing operations include at least
ia64, and Power ISA 2.07 or later, which I think means POWER8 or
later.)
So adding the remaining TS 18661-1 functions would mean at least six
narrowing function implementations (fadd fsub fmul fdiv ffma fsqrt),
with aliases for other types and further implementations in some
configurations, that need to be overridden for configurations lacking
hardware exceptions and rounding modes. Requiring all such
configurations (currently seven of them) to have their own source
files for all those functions seems undesirable.
Thus, this patch adds a directory sysdeps/ieee754/soft-fp to contain
libm function implementations based on soft-fp. This directory is
then used via Implies from all the configurations that need it, so no
more files need adding to every such configuration when adding more
functions with soft-fp implementations. A configuration can still
selectively #include a particular file from this directory if desired;
thus, the MIPS #include of the fmal implementation is retained, since
that's appropriate even for hard float (because long double is always
implementated in software for MIPS64, so the soft-fp implementation of
fmal is better than the ldbl-128 one).
This also provides additional motivation for my recent patch removing
--with-fp / --without-fp: previously there was no need for correct use
of --without-fp for no-FPU ARM or SH3, and now we have autodetection
nofpu/ sysdeps directories can be used by this patch for those
configurations without imposing any new requirements on how glibc is
configured.
(The mips64/*/fpu/s_fma.c files added by this patch are needed to keep
the dbl-64 version of fma for double, rather than the ldbl-128 one,
used in that case.)
Tested with build-many-glibcs.py that installed stripped shared
libraries are unchanged by this patch.
* soft-fp/fmadf4.c: Move to ....
* sysdeps/ieee754/soft-fp/s_fma.c: ... here.
* soft-fp/fmasf4.c: Move to ....
* sysdeps/ieee754/soft-fp/s_fmaf.c: ... here.
* soft-fp/fmatf4.c: Move to ....
* sysdeps/ieee754/soft-fp/s_fmal.c: ... here.
* sysdeps/ieee754/soft-fp/Makefile: New file.
* sysdeps/arm/preconfigure.ac: Define with_fp_cond.
* sysdeps/arm/preconfigure: Regenerated.
* sysdeps/arm/nofpu/Implies: New file.
* sysdeps/arm/s_fma.c: Remove file.
* sysdeps/arm/s_fmaf.c: Likewise.
* sysdeps/m68k/coldfire/nofpu/Implies: New file.
* sysdeps/m68k/coldfire/nofpu/s_fma.c: Remove file.
* sysdeps/m68k/coldfire/nofpu/s_fmaf.c: Likewise.
* sysdeps/microblaze/Implies: Add ieee754/soft-fp.
* sysdeps/microblaze/s_fma.c: Remove file.
* sysdeps/microblaze/s_fmaf.c: Likewise.
* sysdeps/mips/mips32/nofpu/Implies: New file.
* sysdeps/mips/mips64/n32/fpu/s_fma.c: Likewise.
* sysdeps/mips/mips64/n32/nofpu/Implies: Likewise.
* sysdeps/mips/mips64/n64/fpu/s_fma.c: Likewise.
* sysdeps/mips/mips64/n64/nofpu/Implies: Likewise.
* sysdeps/mips/ieee754/s_fma.c: Remove file.
* sysdeps/mips/ieee754/s_fmaf.c: Likewise.
* sysdeps/mips/ieee754/s_fmal.c: Update include for move of fmal
implementation.
* sysdeps/nios2/Implies: Add ieee754/soft-fp.
* sysdeps/nios2/s_fma.c: Remove file.
* sysdeps/nios2/s_fmaf.c: Likewise.
* sysdeps/sh/nofpu/Implies: New file.
* sysdeps/sh/s_fma.c: Remove file.
* sysdeps/sh/s_fmaf.c: Likewise.
* sysdeps/tile/Implies: Add ieee754/soft-fp.
* sysdeps/tile/s_fma.c: Remove file.
* sysdeps/tile/s_fmaf.c: Likewise.
Some libio operations fail to correctly free the backup area (created
by _IO_{w}default_pbackfail on unget{w}c) resulting in either invalid
buffer free operations or memory leaks.
For instance, on the example provided by BZ#22415 a following
fputc after a fseek to rewind the stream issues an invalid free on
the buffer. It is because although _IO_file_overflow correctly
(from fputc) correctly calls _IO_free_backup_area, the
_IO_new_file_seekoff (called by fseek) updates the FILE internal
pointers without first free the backup area (resulting in invalid
values in the internal pointers).
The wide version also shows an issue, but instead of accessing invalid
pointers it leaks the backup memory on fseek/fputwc operation.
Checked on x86_64-linux-gnu and i686-linux-gnu.
* libio/Makefile (tests): Add tst-bz22415.
(tst-bz22415-ENV): New rule.
(generated): Add tst-bz22415.mtrace and tst-bz22415.check.
(tests-special): Add tst-bz22415-mem.out.
($(objpfx)tst-bz22415-mem.out): New rule.
* libio/fileops.c (_IO_new_file_seekoff): Call _IO_free_backup_area
in case of a successful seek operation.
* libio/wfileops.c (_IO_wfile_seekoff): Likewise.
(_IO_wfile_overflow): Call _IO_free_wbackup_area in case a write
buffer is required.
* libio/tst-bz22415.c: New test.
When running strace, IPC_64 was set in the command, but ia64 is
an architecture where CONFIG_ARCH_WANT_IPC_PARSE_VERSION *isn't* set
in the kernel, so ipc_parse_version just returns IPC_64 without
clearing the IPC_64 bit in the command.
* sysdeps/unix/sysv/linux/ia64/ipc_priv.h: New file defining
__IPC_64 to 0 to avoid IPC_64 being set.
Signed-off-by: James Clarke <jrtc27@jrtc27.com>
These functions set errno and thus the const attribute was wrong.
[BZ #22593]
* math/bits/mathcalls.h (nextafter): Remove const.
(nexttoward): Likewise.
There is a configure option --without-fp that specifies that nofpu
sysdeps directories should be used instead of fpu directories.
For most glibc configurations, this option is of no use: either there
is no valid nofpu variant of that configuration, or there are no fpu
or nofpu sysdeps directories for that processor and so the option does
nothing. For a few configurations, if you are using a soft-float
compiler this option is required, and failing to use it generally
results in compilation errors from inline asm using unavailable
floating-point instructions.
We're moving away from --with-cpu to configuring glibc based on how
the compiler generates code, and it is natural to do so for
--without-fp as well; in most cases the soft-float and hard-float ABIs
are incompatible so you have no hope of building a working glibc with
an inappropriately configured compiler or libgcc.
This patch eliminates --without-fp, replacing it entirely by automatic
configuration based on the compiler. Configurations for which this is
relevant (coldfire / mips / powerpc32 / sh) define a variable
with_fp_cond in their preconfigure fragments (under the same
conditions under which those fragments do anything); this is a
preprocessor conditional which the toplevel configure script then uses
in a test to determine which sysdeps directories to use.
The config.make with-fp variable remains. It's used only by powerpc
(sysdeps/powerpc/powerpc32/Makefile) to add -mhard-float to various
flags variables. For powerpc, -mcpu= options can imply use of
soft-float. That could be an issue if you want to build for
e.g. 476fp, but are using --with-cpu=476 because there isn't a 476fp
sysdeps directory. If in future we eliminate --with-cpu and replace
it entirely by testing the compiler, it would be natural at that point
to eliminate that code as well (as the user should then just use a
compiler defaulting to 476fp and the 476 sysdeps directory would be
used automatically).
Tested for x86_64, and tested with build-many-glibcs.py that installed
shared libraries are unchanged by this patch.
* configure.ac (--with-fp): Remove configure option.
(with_fp_cond): New variable.
(libc_cv_with_fp): New configure test. Use this variable instead
of with_fp.
* configure: Regenerated.
* config.make.in (with-fp): Use @libc_cv_with_fp@.
* manual/install.texi (Configuring and compiling): Remove
--without-fp.
* INSTALL: Regenerated.
* sysdeps/m68k/preconfigure (with_fp_cond): Define for ColdFire.
* sysdeps/mips/preconfigure (with_fp_cond): Define.
* sysdeps/powerpc/preconfigure (with_fp_cond): Define for 32-bit.
* sysdeps/sh/preconfigure (with_fp_cond): Define.
* scripts/build-many-glibcs.py (Context.add_all_configs): Do not
use --without-fp to configure glibc.
The same logic used in s_cosf.S version for x86 and powerpc
is used to create a generic s_cosf.c, so there is no performance
improvement in x86_64 and powerpc64.
* sysdeps/ieee754/flt-32/s_cosf.c: New implementation.
On POWER8, unaligned memory accesses to cached memory has little impact
on performance as opposed to its ancestors.
It is disabled by default and will only be available when the tunable
glibc.tune.cached_memopt is set to 1.
__memcpy_power8_cached __memcpy_power7
============================================================
max-size=4096: 33325.70 ( 12.65%) 38153.00
max-size=8192: 32878.20 ( 11.17%) 37012.30
max-size=16384: 33782.20 ( 11.61%) 38219.20
max-size=32768: 33296.20 ( 11.30%) 37538.30
max-size=65536: 33765.60 ( 10.53%) 37738.40
* manual/tunables.texi (Hardware Capability Tunables): Document
glibc.tune.cached_memopt.
* sysdeps/powerpc/cpu-features.c: New file.
* sysdeps/powerpc/cpu-features.h: New file.
* sysdeps/powerpc/dl-procinfo.c [!IS_IN(ldconfig)]: Add
_dl_powerpc_cpu_features.
* sysdeps/powerpc/dl-tunables.list: New file.
* sysdeps/powerpc/ldsodefs.h: Include cpu-features.h.
* sysdeps/powerpc/powerpc32/power4/multiarch/init-arch.h
(INIT_ARCH): Initialize use_aligned_memopt.
* sysdeps/powerpc/powerpc64/dl-machine.h [defined(SHARED &&
IS_IN(rtld))]: Restrict dl_platform_init availability and
initialize CPU features used by tunables.
* sysdeps/powerpc/powerpc64/multiarch/Makefile (sysdep_routines):
Add memcpy-power8-cached.
* sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c: Add
__memcpy_power8_cached.
* sysdeps/powerpc/powerpc64/multiarch/memcpy.c: Likewise.
* sysdeps/powerpc/powerpc64/multiarch/memcpy-power8-cached.S:
New file.
Reviewed-by: Rajalakshmi Srinivasaraghavan <raji@linux.vnet.ibm.com>
In _dl_runtime_resolve[_vx], unwinding fails after the new stack frame
is created as there is no CFI rule for r15. This is also observeable in
GDB: Backtrace stopped: previous frame inner to this frame (corrupt stack?)
Therefore this patch is now storing r15 on stack and is using cfi_offset rule.
The stmg/lmg instruction is used to store/load r14 and r15 with one instruction.
On 64bit, the offsets of the fprs have moved to store r15 directly after r14.
On 31bit, the r14/r15 is now stored between the other gprs and fprs as the space
wasn't used.
ChangeLog:
* sysdeps/s390/s390-64/dl-trampoline.h (_dl_runtime_resolve):
Store r15 on stack and add cfi rule.
* sysdeps/s390/s390-32/dl-trampoline.h (_dl_runtime_resolve):
Likewise.
On Skylake, bench-sinf reports performance improvement:
Before After Improvement
max 153.996 100.094 54%
min 8.546 6.852 25%
mean 18.1223 11.802 54%
* sysdeps/x86_64/fpu/multiarch/Makefile (libm-sysdep_routines):
Add s_sinf-sse2 and s_sinf-fma.
(CFLAGS-s_sinf-fma.c): New.
* sysdeps/x86_64/fpu/multiarch/s_sinf-fma.c: New file.
* sysdeps/x86_64/fpu/multiarch/s_sinf-sse2.c: Likewise.
* sysdeps/x86_64/fpu/multiarch/s_sinf.c: Likewise.
As per C11 DR#471, ctanh (0 + i NaN) and ctanh (0 + i Inf) should
return 0 + i NaN (with "invalid" exception in the second case but not
the first), not NaN + i NaN. This has corresponding implications for
ctan since its special cases are defined by ctan (z) = -i ctanh (iz).
This patch implements these cases for ctanh and ctan, updating
tests accordingly.
Tested for x86_64.
[BZ #22568]
* math/s_ctan_template.c (M_DECL_FUNC (__ctan)): Set imaginary
part of result to imaginary part of argument if it is zero and the
real part of the argument is not finite.
* math/s_ctanh_template.c (M_DECL_FUNC (__ctanh)): Set real part
of result to real part of argument if it is zero and the imaginary
part of the argument is not finite.
[BZ #22524]
* localedata/Makefile: Add lt_LT.UTF-8 to test-input
and to the list of locales to be built for testing.
* localedata/lt_LT.UTF-8.in: New file for testing the collation.
* localedata/locales/lt_LT (LC_COLLATE): Use “copy "iso14651_t1"”
and build the collation rules upon that.
This patch adds support for defining strtof32, wcstof32, strtof32_l
and wcstof32_l functions as aliases of the corresponding float
functions when _Float32 support is enabled.
Tested for x86_64; also tested with build-many-glibcs.py in
conjunction with other _Float32 changes.
* stdlib/strtof.c: Include <bits/floatn.h>
[__HAVE_FLOAT32 && !__HAVE_DISTINCT_FLOAT32] (strtof32): Define
and later undefine as macro. Define as weak alias if
[!USE_WIDE_CHAR].
[__HAVE_FLOAT32 && !__HAVE_DISTINCT_FLOAT32] (wcstof32): Define
and later undefine as macro. Define as weak alias if
[USE_WIDE_CHAR].
* stdlib/strtof_l.c: Include <bits/floatn.h>
[__HAVE_FLOAT32 && !__HAVE_DISTINCT_FLOAT32] (strtof32_l): Define
and later undefine as macro. Define as weak alias if
[!USE_WIDE_CHAR].
[__HAVE_FLOAT32 && !__HAVE_DISTINCT_FLOAT32] (wcstof32_l): Define
and later undefine as macro. Define as weak alias if
[USE_WIDE_CHAR].