Compare commits

...
Author SHA1 Message Date
Stan Shebs 2431995fd0 As with gettimeofday, avoid vdso for clang-compiled time() 2019-04-30 18:24:46 -07:00
Stan Shebs d3f21e2615 Bypass gettimeofday ifunc if using clang 2019-04-30 18:23:43 -07:00
Stan Shebs 583e97d196 Make pointer in tst-realloc volatile also 2019-04-30 18:18:24 -07:00
Stan Shebs 2b89ce53dc Defeat a malloc optimization by declaring things volatile. 2019-04-30 18:17:39 -07:00
Stan Shebs c3f0d624e9 Make zero volatile to defeat constant-folding of 0.0/0.0 2019-04-30 17:34:38 -07:00
Stan Shebs 96ba247eed Comment out debugging hack that pollutes namespace 2019-04-30 15:45:23 -07:00
Stan Shebs 1ba2430890 Avoid the nonstandard .tls_common 2019-04-30 15:44:35 -07:00
Stan Shebs 98fa878ff0 Use clang integrated assembler except when asm is output and not required to be valid 2019-04-30 14:34:20 -07:00
Stan Shebs 47421c20fa For clang, add hidden proto of __libc_allocate_once_slow ahead of use 2019-04-30 14:18:35 -07:00
Stan Shebs 7f08540d90 Do not pass unhandled flag to clang 2019-04-30 13:53:45 -07:00
Stan Shebs 98bd74d428 Stub out execstack problem 2019-04-30 13:39:38 -07:00
Stan Shebs 84b5ab235e Stub out execstack, multidir, and ifunc problems 2019-04-30 13:38:28 -07:00
Stan Shebs 0d8743de85 Skip execstack test, depends on nested function 2019-04-30 13:29:13 -07:00
Stan Shebs 8603348fa3 De-nest test-ffs.c 2019-04-29 21:26:52 -07:00
Stan Shebs 240ea3c09c Work around a clang bug 2019-04-29 21:24:34 -07:00
Stan Shebs 411c5470ad clang requires -mno-see for 387 math 2019-04-29 20:33:36 -07:00
Stan Shebs e5da52d681 Suppress tgmath3 tests if clang 2019-04-29 20:05:48 -07:00
Stan Shebs 60c5087acb Put CMPLX* macros under ISO C11 2019-04-29 17:26:18 -07:00
Stan Shebs 7220c4d393 Add clang versions of CMPLX* macros 2019-04-29 14:07:00 -07:00
Stan Shebs e57ac229dc Reduce an error to warning if clang 2019-04-29 12:00:35 -07:00
Stan Shebs 367c8c0e97 Add a hidden_proto for __close_nocancel before its use 2019-04-26 13:43:38 -07:00
Stan Shebs e9ba4bf620 Add another workaround for clang problem with sizes in asm 2019-04-26 13:37:12 -07:00
Stan Shebs 181e58d747 Add hidden protos ahead of uses 2019-04-26 13:30:54 -07:00
Stan Shebs 40f3f5c1a5 De-nest makedb.c 2019-04-26 13:29:49 -07:00
Stan Shebs 7e3b1df6d4 Work around a weird clang link failure 2019-04-26 13:28:35 -07:00
Stan Shebs 964779a113 Remove debugging hack 2019-04-26 13:27:18 -07:00
Stan Shebs 9e10cf821f Work around clang assembler bug with expressions in .if 2019-04-26 13:26:46 -07:00
Stan Shebs 74b7dd6b5a Work around lack of .tfloat in clang assembler 2019-04-26 12:14:07 -07:00
Stan Shebs 4b957d975d Disallow extern inline if clang 2019-04-26 12:08:19 -07:00
Stan Shebs 73efc556ac Work around clang asm problem by changing types of two variables 2019-04-26 08:11:38 -07:00
Stan Shebs ace275b80b Update de-nested functions to match originals 2019-04-26 08:09:45 -07:00
Stan Shebs 52a7cb28f9 Add a --with-lld option to choose LLVMs lld linker 2019-04-24 11:04:33 -07:00
Stan Shebs 1cfcdae979 Work around clang assembler error with bnd by itself on a line 2019-04-24 09:47:33 -07:00
Stan Shebs 7c44a0bf9c Change de-nesting fix to use added argument instead of globals 2019-04-24 09:10:20 -07:00
Stan Shebs 868fc27ff4 Un-nest nested functions in dynamic linker 2019-04-24 09:06:59 -07:00
Stan Shebs fbf200117d Work around clang assembler problem with ifunc relocs 2019-04-24 08:14:19 -07:00
Stan Shebs 53eebacec0 De-nest regcomp.c 2019-04-24 08:09:37 -07:00
Stan Shebs f38fa7c980 Work around clang assembler error with movzx 2019-04-24 08:02:45 -07:00
Stan Shebs 64b3e177bc Work around a clang problem with asm constraints 2019-04-24 08:01:50 -07:00
Stan Shebs 1ba307084e Add workarounds for incomplete float128 support in clang 2019-04-24 07:53:02 -07:00
Stan Shebs 268ddcff50 Add clang version of __hidden_proto 2019-04-23 14:30:33 -07:00
Stan Shebs 54031961bf Skip undefined va_arg_pack 2019-04-23 14:28:39 -07:00
Stan Shebs 4bbfeb8e5b Add --with-clang and --disable-float128 options to toplevel configury 2019-04-23 14:25:52 -07:00
Carlos O'Donell dcd2b97dd1 malloc: Set and reset all hooks for tracing (Bug 16573)
If an error occurs during the tracing operation, particularly during a
call to lock_and_info() which calls _dl_addr, we may end up calling back
into the malloc-subsystem and relock the loader lock and deadlock. For
all intents and purposes the call to _dl_addr can call any of the malloc
family API functions and so we should disable all tracing before calling
such loader functions.  This is similar to the strategy that the new
malloc tracer takes when calling the real malloc, namely that all
tracing ceases at the boundary to the real function and any faults at
that point are the purvue of the library (though the new tracer does
this on a per-thread basis in an MT-safe fashion). Since the new tracer
and the hook deprecation are not yet complete we must fix these issues
where we can.

Tested on x86_64 with no regressions.

Co-authored-by: Kwok Cheung Yeung <kcy@codesourcery.com>
Reviewed-by: DJ Delorie <dj@redhat.com>
(cherry picked from commit e621246ec6)
2019-04-15 20:49:32 +02:00
TAMUKI Shoichi 0941350c20 ja_JP locale: Add entry for the new Japanese era [BZ #22964]
The Japanese era name will be changed on May 1, 2019.  The Japanese
government made a preliminary announcement on April 1, 2019.

The glibc ja_JP locale must be updated to include the new era name for
strftime's alternative year format support.

This is a minimal cherry pick of just the required locale changes.

(cherry picked from commit 466afec308)
2019-04-03 19:42:20 +02:00
TAMUKI Shoichi e28ad442e7 ja_JP: Change the offset for Taisho gan-nen from 2 to 1 [BZ #24162]
The offset in era-string format for Taisho gan-nen (1912) is currently
defined as 2, but it should be 1.  So fix it.  "Gan-nen" means the 1st
(origin) year, Taisho started on July 30, 1912.

Reported-by: Morimitsu, Junji <junji.morimitsu@hpe.com>
Reviewed-by: Rafal Luzynski <digitalfreak@lingonborough.com>

ChangeLog:

	[BZ #24162]
	* localedata/locales/ja_JP (LC_TIME): Change the offset for Taisho
	gan-nen from 2 to 1.  Problem reported by Morimitsu, Junji.

(cherry picked from commit 31effacee2)
2019-03-22 10:59:06 +09:00
Stefan Liebler 6eb48fe80c S390: Mark vx and vxe as important hwcap.
This patch adds vx and vxe as important hwcaps
which allows one to provide shared libraries
tuned for platforms with non-vx/-vxe, vx or vxe.

ChangeLog:

	* sysdeps/s390/dl-procinfo.h (HWCAP_IMPORTANT):
	Add HWCAP_S390_VX and HWCAP_S390_VXE.

(cherry picked from commit 61f5e9470f)

Conflicts:
	ChangeLog
2019-03-21 09:27:37 +01:00
Aurelien Jarno 10dd17da71 Record CVE-2019-9169 in NEWS and ChangeLog [BZ #24114]
(cherry picked from commit b626c5aa5d)
2019-03-16 23:27:47 +01:00
Paul Eggert 4d0b1b0f61 regex: fix read overrun [BZ #24114]
Problem found by AddressSanitizer, reported by Hongxu Chen in:
https://debbugs.gnu.org/34140
* posix/regexec.c (proceed_next_node):
Do not read past end of input buffer.

(cherry picked from commit 583dd860d5)
2019-03-16 23:26:14 +01:00
Stefan Liebler bc6f839fb4 Fix output of LD_SHOW_AUXV=1.
Starting with commit 1616d034b6
the output was corrupted on some platforms as _dl_procinfo
was called for every auxv entry and on some architectures like s390
all entries were represented as "AT_HWCAP".

This patch is removing the condition and let _dl_procinfo decide if
an entry is printed in a platform specific or generic way.
This patch also adjusts all _dl_procinfo implementations which assumed
that they are only called for AT_HWCAP or AT_HWCAP2. They are now just
returning a non-zero-value for entries which are not handled platform
specifc.

ChangeLog:

	* elf/dl-sysdep.c (_dl_show_auxv): Remove condition and always
	call _dl_procinfo.
	* sysdeps/unix/sysv/linux/s390/dl-procinfo.h (_dl_procinfo):
	Ignore types other than AT_HWCAP.
	* sysdeps/sparc/dl-procinfo.h (_dl_procinfo): Likewise.
	* sysdeps/unix/sysv/linux/i386/dl-procinfo.h (_dl_procinfo):
	Likewise.
	* sysdeps/powerpc/dl-procinfo.h (_dl_procinfo): Adjust comment
	in the case of falling back to generic output mechanism.
	* sysdeps/unix/sysv/linux/arm/dl-procinfo.h (_dl_procinfo):
	Likewise.

(cherry picked from commit 7c6513082b)

Conflicts:
	ChangeLog
2019-03-13 10:51:23 +01:00
Florian Weimer 067fc32968 nptl: Fix invalid Systemtap probe in pthread_join [BZ #24211]
After commit f1ac745583 ("arm: Use "nr"
constraint for Systemtap probes [BZ #24164]"), we load pd->result into
a register in the probe below:

      /* Free the TCB.  */
      __free_tcb (pd);
    }
  else
    pd->joinid = NULL;

  LIBC_PROBE (pthread_join_ret, 3, threadid, result, pd->result);

However, at this point, the thread descriptor has been freed.  If the
thread stack does not fit into the thread stack cache, the memory will
have been unmapped, and the program will crash in the probe.

(cherry picked from commit bc10e22c90)
2019-02-15 21:27:01 +01:00
Florian Weimer c096b008d2 nptl: Avoid fork handler lock for async-signal-safe fork [BZ #24161]
Commit 27761a1042 ("Refactor atfork
handlers") introduced a lock, atfork_lock, around fork handler list
accesses.  It turns out that this lock occasionally results in
self-deadlocks in malloc/tst-mallocfork2:

(gdb) bt
#0  __lll_lock_wait_private ()
    at ../sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:63
#1  0x00007f160c6f927a in __run_fork_handlers (who=(unknown: 209394016),
    who@entry=atfork_run_prepare) at register-atfork.c:116
#2  0x00007f160c6b7897 in __libc_fork () at ../sysdeps/nptl/fork.c:58
#3  0x00000000004027d6 in sigusr1_handler (signo=<optimized out>)
    at tst-mallocfork2.c:80
#4  sigusr1_handler (signo=<optimized out>) at tst-mallocfork2.c:64
#5  <signal handler called>
#6  0x00007f160c6f92e4 in __run_fork_handlers (who=who@entry=atfork_run_parent)
    at register-atfork.c:136
#7  0x00007f160c6b79a2 in __libc_fork () at ../sysdeps/nptl/fork.c:152
#8  0x0000000000402567 in do_test () at tst-mallocfork2.c:156
#9  0x0000000000402dd2 in support_test_main (argc=1, argv=0x7ffc81ef1ab0,
    config=config@entry=0x7ffc81ef1970) at support_test_main.c:350
#10 0x0000000000402362 in main (argc=<optimized out>, argv=<optimized out>)
    at ../support/test-driver.c:168

If no locking happens in the single-threaded case (where fork is
expected to be async-signal-safe), this deadlock is avoided.
(pthread_atfork is not required to be async-signal-safe, so a fork
call from a signal handler interrupting pthread_atfork is not
a problem.)

(cherry picked from commit 669ff911e2)
2019-02-08 12:54:41 +01:00
Stefan Liebler 44113a8ba2 Add compiler barriers around modifications of the robust mutex list for pthread_mutex_trylock. [BZ #24180]
While debugging a kernel warning, Thomas Gleixner, Sebastian Sewior and
Heiko Carstens found a bug in pthread_mutex_trylock due to misordered
instructions:
140:   a5 1b 00 01             oill    %r1,1
144:   e5 48 a0 f0 00 00       mvghi   240(%r10),0   <--- THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
14a:   e3 10 a0 e0 00 24       stg     %r1,224(%r10) <--- last THREAD_SETMEM of ENQUEUE_MUTEX_PI

vs (with compiler barriers):
140:   a5 1b 00 01             oill    %r1,1
144:   e3 10 a0 e0 00 24       stg     %r1,224(%r10)
14a:   e5 48 a0 f0 00 00       mvghi   240(%r10),0

Please have a look at the discussion:
"Re: WARN_ON_ONCE(!new_owner) within wake_futex_pi() triggerede"
(https://lore.kernel.org/lkml/20190202112006.GB3381@osiris/)

This patch is introducing the same compiler barriers and comments
for pthread_mutex_trylock as introduced for pthread_mutex_lock and
pthread_mutex_timedlock by commit 8f9450a0b7
"Add compiler barriers around modifications of the robust mutex list."

ChangeLog:

	[BZ #24180]
	* nptl/pthread_mutex_trylock.c (__pthread_mutex_trylock):
	Add compiler barriers and comments.

(cherry picked from commit 823624bdc4)
2019-02-07 15:33:23 +01:00
Florian Weimer 2de15ac957 arm: Use "nr" constraint for Systemtap probes [BZ #24164]
With the default "nor" constraint, current GCC will use the "o"
constraint for constants, after emitting the constant to memory.  That
results in unparseable Systemtap probe notes such as "-4@.L1052".
Removing the "o" alternative and using "nr" instead avoids this.

(cherry picked from commit f1ac745583)
2019-02-05 13:49:03 +01:00
H.J. Lu 726a78867b x86-64 memcmp: Use unsigned Jcc instructions on size [BZ #24155]
Since the size argument is unsigned. we should use unsigned Jcc
instructions, instead of signed, to check size.

Tested on x86-64 and x32, with and without --disable-multi-arch.

	[BZ #24155]
	CVE-2019-7309
	* NEWS: Updated for CVE-2019-7309.
	* sysdeps/x86_64/memcmp.S: Use RDX_LP for size.  Clear the
	upper 32 bits of RDX register for x32.  Use unsigned Jcc
	instructions, instead of signed.
	* sysdeps/x86_64/x32/Makefile (tests): Add tst-size_t-memcmp-2.
	* sysdeps/x86_64/x32/tst-size_t-memcmp-2.c: New test.

(cherry picked from commit 3f635fb433)
2019-02-04 12:27:04 -08:00
Carlos O'Donell 86013ef5ce nptl: Fix pthread_rwlock_try*lock stalls (Bug 23844)
For a full analysis of both the pthread_rwlock_tryrdlock() stall
and the pthread_rwlock_trywrlock() stall see:
https://sourceware.org/bugzilla/show_bug.cgi?id=23844#c14

In the pthread_rwlock_trydlock() function we fail to inspect for
PTHREAD_RWLOCK_FUTEX_USED in __wrphase_futex and wake the waiting
readers.

In the pthread_rwlock_trywrlock() function we write 1 to
__wrphase_futex and loose the setting of the PTHREAD_RWLOCK_FUTEX_USED
bit, again failing to wake waiting readers during unlock.

The fix in the case of pthread_rwlock_trydlock() is to check for
PTHREAD_RWLOCK_FUTEX_USED and wake the readers.

The fix in the case of pthread_rwlock_trywrlock() is to only write
1 to __wrphase_futex if we installed the write phase, since all other
readers would be spinning waiting for this step.

We add two new tests, one exercises the stall for
pthread_rwlock_trywrlock() which is easy to exercise, and one exercises
the stall for pthread_rwlock_trydlock() which is harder to exercise.

The pthread_rwlock_trywrlock() test fails consistently without the fix,
and passes after. The pthread_rwlock_tryrdlock() test fails roughly
5-10% of the time without the fix, and passes all the time after.

Signed-off-by: Carlos O'Donell <carlos@redhat.com>
Signed-off-by: Torvald Riegel <triegel@redhat.com>
Signed-off-by: Rik Prohaska <prohaska7@gmail.com>
Co-authored-by: Torvald Riegel <triegel@redhat.com>
Co-authored-by: Rik Prohaska <prohaska7@gmail.com>
(cherry picked from commit 5fc9ed4c40)
2019-01-31 21:37:53 -05:00
97 changed files with 1980 additions and 159 deletions
+116
View File
@@ -1,3 +1,119 @@
2019-04-09 Carlos O'Donell <carlos@redhat.com>
Kwok Cheung Yeung <kcy@codesourcery.com>
[BZ #16573]
* malloc/mtrace.c: Define prototypes for all hooks.
(set_default_hooks): New function.
(set_trace_hooks): Likewise.
(save_default_hooks): Likewise.
(tr_freehook): Use new s*_hooks functions.
(tr_mallochook): Likewise.
(tr_reallochook): Likewise.
(tr_memalignhook): Likewise.
(mtrace): Likewise.
(muntrace): Likewise.
2019-04-02 TAMUKI Shoichi <tamuki@linet.gr.jp>
[BZ #22964]
* localedata/locales/ja_JP (LC_TIME): Add entry for the new Japanese
era.
2019-03-02 TAMUKI Shoichi <tamuki@linet.gr.jp>
[BZ #24162]
* localedata/locales/ja_JP (LC_TIME): Change the offset for Taisho
gan-nen from 2 to 1. Problem reported by Morimitsu, Junji.
2019-03-21 Stefan Liebler <stli@linux.ibm.com>
* sysdeps/s390/dl-procinfo.h (HWCAP_IMPORTANT):
Add HWCAP_S390_VX and HWCAP_S390_VXE.
2019-01-31 Paul Eggert <eggert@cs.ucla.edu>
CVE-2019-9169
regex: fix read overrun [BZ #24114]
Problem found by AddressSanitizer, reported by Hongxu Chen in:
https://debbugs.gnu.org/34140
* posix/regexec.c (proceed_next_node):
Do not read past end of input buffer.
2019-03-13 Stefan Liebler <stli@linux.ibm.com>
* elf/dl-sysdep.c (_dl_show_auxv): Remove condition and always
call _dl_procinfo.
* sysdeps/unix/sysv/linux/s390/dl-procinfo.h (_dl_procinfo):
Ignore types other than AT_HWCAP.
* sysdeps/sparc/dl-procinfo.h (_dl_procinfo): Likewise.
* sysdeps/unix/sysv/linux/i386/dl-procinfo.h (_dl_procinfo):
Likewise.
* sysdeps/powerpc/dl-procinfo.h (_dl_procinfo): Adjust comment
in the case of falling back to generic output mechanism.
* sysdeps/unix/sysv/linux/arm/dl-procinfo.h (_dl_procinfo):
Likewise.
2019-02-15 Florian Weimer <fweimer@redhat.com>
[BZ #24211]
* nptl/pthread_join_common.c (__pthread_timedjoin_ex): Do not read
pd->result after the thread descriptor has been freed.
2019-02-08 Florian Weimer <fweimer@redhat.com>
[BZ #24161]
* sysdeps/nptl/fork.h (__run_fork_handlers): Add multiple_threads
argument.
* nptl/register-atfork.c (__run_fork_handlers): Only perform
locking if the new do_locking argument is true.
* sysdeps/nptl/fork.c (__libc_fork): Pass multiple_threads to
__run_fork_handlers.
2019-02-07 Stefan Liebler <stli@linux.ibm.com>
[BZ #24180]
* nptl/pthread_mutex_trylock.c (__pthread_mutex_trylock):
Add compiler barriers and comments.
2019-02-05 Florian Weimer <fweimer@redhat.com>
[BZ #24164]
arm: Use "nr" constraint for Systemtap probes, to avoid the
compiler using memory operands for constants, due to the "o"
alternative in the default "nor" constraint.
* include/stap-probe.h [USE_STAP_PROBE]: Include
<stap-probe-machine.h>
* sysdeps/generic/stap-probe-machine.h: New file.
* sysdeps/arm/stap-probe-machine.h: Likewise.
2019-02-04 H.J. Lu <hongjiu.lu@intel.com>
[BZ #24155]
CVE-2019-7309
* NEWS: Updated for CVE-2019-7309.
* sysdeps/x86_64/memcmp.S: Use RDX_LP for size. Clear the
upper 32 bits of RDX register for x32. Use unsigned Jcc
instructions, instead of signed.
* sysdeps/x86_64/x32/Makefile (tests): Add tst-size_t-memcmp-2.
* sysdeps/x86_64/x32/tst-size_t-memcmp-2.c: New test.
2019-01-31 Carlos O'Donell <carlos@redhat.com>
Torvald Riegel <triegel@redhat.com>
Rik Prohaska <prohaska7@gmail.com>
[BZ# 23844]
* nptl/Makefile (tests): Add tst-rwlock-tryrdlock-stall, and
tst-rwlock-trywrlock-stall.
* nptl/pthread_rwlock_tryrdlock.c (__pthread_rwlock_tryrdlock):
Wake waiters if PTHREAD_RWLOCK_FUTEX_USED is set.
* nptl/pthread_rwlock_trywrlock.c (__pthread_rwlock_trywrlock):
Set __wrphase_fute to 1 only if we started the write phase.
* nptl/tst-rwlock-tryrdlock-stall.c: New file.
* nptl/tst-rwlock-trywrlock-stall.c: New file.
* support/Makefile (libsupport-routines): Add xpthread_rwlock_destroy.
* support/xpthread_rwlock_destroy.c: New file.
* support/xthread.h: Declare xpthread_rwlock_destroy.
2019-01-31 Siddhesh Poyarekar <siddhesh@sourceware.org>
* version.h (RELEASE): Set to "stable".
+25
View File
@@ -521,8 +521,13 @@ CFLAGS-printers-tests := -O0 -ggdb3 -DIS_IN_build
ifeq (yes,$(build-shared))
# These indicate whether to link using the built ld.so or the installed one.
ifeq ($(with-lld),no)
installed-rtld-LDFLAGS = -Wl,-dynamic-linker=$(rtlddir)/$(rtld-installed-name)
built-rtld-LDFLAGS = -Wl,-dynamic-linker=$(elf-objpfx)ld.so
else
installed-rtld-LDFLAGS = -Wl,-dynamic-linker,$(rtlddir)/$(rtld-installed-name)
built-rtld-LDFLAGS = -Wl,-dynamic-linker,$(elf-objpfx)ld.so
endif
ifndef rtld-LDFLAGS
rtld-LDFLAGS = $(installed-rtld-LDFLAGS)
@@ -829,7 +834,9 @@ endif
# We have to assume that glibc functions are called in any rounding
# mode and also change the rounding mode in a few functions. So,
# disable any optimization that assume default rounding mode.
ifeq ($(with-clang),no)
+math-flags = -frounding-math
endif
# Logically only "libnldbl", "nonlib" and "testsuite" should be using
# -fno-math-errno. However due to GCC bug #88576, only "libm" can use
@@ -900,6 +907,24 @@ ifeq "$(strip $(+cflags))" ""
+cflags := $(default_cflags)
endif # $(+cflags) == ""
# For now, manually add known-needed clang flags here.
ifeq ($(with-clang),yes)
+cflags += -fheinous-gnu-extensions
# Don't complain about __sigsetjmp.
+cflags += -Wno-builtin-requires-header
# clang takes gnu89 as requiring a warning about duplicates, gcc does not
+cflags += -Wno-duplicate-decl-specifier
# Non-string format arguments come from debugging prints in ld.so.
+cflags += -Wno-format-security
ifeq ($(with-lld),yes)
LDFLAGS.so += -fuse-ld=lld
LDFLAGS-rtld += -fuse-ld=lld
LDFLAGS += -fuse-ld=lld
endif
endif # with-clang == yes
+cflags += $(cflags-cpu) $(+gccwarn) $(+merge-constants) $(+math-flags) \
$(+stack-protector)
+gcc-nowarn := -w
+9 -4
View File
@@ -225,6 +225,11 @@ sed-remove-dotdot := -e 's@ *\([^ \/$$][^ \]*\)@ $$(..)\1@g' \
-e 's@^\([^ \/$$][^ \]*\)@$$(..)\1@g'
endif
MOARFLAGS =
ifeq ($(with-clang),yes)
MOARFLAGS = -no-integrated-as
endif
ifdef gen-py-const-headers
# We'll use a static pattern rule to match .pysym files with their
# corresponding generated .py files.
@@ -249,7 +254,7 @@ $(py-const): $(py-const-dir)%.py: %.pysym $(py-const-script) \
$(common-before-compile)
$(make-target-directory)
$(PYTHON) $(py-const-script) --python \
--cc="$(CC) $(CFLAGS) $(CPPFLAGS)" $< \
--cc="$(CC) $(MOARFLAGS) $(CFLAGS) $(CPPFLAGS)" $< \
> $@.tmp
mv -f $@.tmp $@
@@ -268,7 +273,7 @@ ifdef gen-as-const-headers
# may lead to build hang on a many-core machine.
$(common-objpfx)%.h $(common-objpfx)%.h.d: $(..)scripts/gen-as-const.py \
%.sym $(common-before-compile)
$(PYTHON) $< --cc="$(CC) $(CFLAGS) $(CPPFLAGS) -DGEN_AS_CONST_HEADERS \
$(PYTHON) $< --cc="$(CC) $(MOARFLAGS) $(CFLAGS) $(CPPFLAGS) -DGEN_AS_CONST_HEADERS \
-MD -MP -MF $(@:.h=.h.d)T \
-MT '$(@:.h=.h.d) $(@:.h.d=.h)'" \
$(filter %.sym,$^) > $(@:.h.d=.h)T
@@ -587,7 +592,7 @@ $(common-objpfx)shlib.lds: $(common-objpfx)config.make $(..)Makerules
common-generated += shlib.lds
shlib-lds = $(common-objpfx)shlib.lds
shlib-lds-flags = -T $(shlib-lds)
shlib-lds-flags = -Wl,-T,$(shlib-lds)
endif
define build-shlib
@@ -639,7 +644,7 @@ LDFLAGS-c.so = -nostdlib -nostartfiles
# But we still want to link libc.so against $(libc.so-gnulib).
LDLIBS-c.so += $(libc.so-gnulib)
# Give libc.so an entry point and make it directly runnable itself.
LDFLAGS-c.so += -e __libc_main
LDFLAGS-c.so += -Wl,-e,__libc_main
# Pre-link the objects of libc_pic.a so that we can locally resolve
# COMMON symbols before we link against ld.so. This is because ld.so
# contains some of libc_pic.a already, which will prevent the COMMONs
+29
View File
@@ -4,6 +4,35 @@ See the end for copying conditions.
Please send GNU C library bug reports via <https://sourceware.org/bugzilla/>
using `glibc' in the "product" field.
Version 2.29.1
Major new features:
* The entry for the new Japanese era has been added for ja_JP locale.
The following bugs are resolved with this release:
[16573] malloc: Set and reset all hooks for tracing
[24155] x32 memcmp can treat positive length as 0 (if sign bit in RDX is set) (CVE-2019-7309)
[24164] Systemtap probes need to use "nr" constraint on 32-bit Arm
[24161] __run_fork_handlers self-deadlocks in malloc/tst-mallocfork2
[24211] Use-after-free in Systemtap probe in pthread_join
Security related changes:
CVE-2019-7309: x86-64 memcmp used signed Jcc instructions to check
size. For x86-64, memcmp on an object size larger than SSIZE_MAX
has undefined behavior. On x32, the size_t argument may be passed
in the lower 32 bits of the 64-bit RDX register with non-zero upper
32 bits. When it happened with the sign bit of RDX register set,
memcmp gave the wrong result since it treated the size argument as
zero. Reported by H.J. Lu.
CVE-2019-9169: Attempted case-insensitive regular-expression match
via proceed_next_node in posix/regexec.c leads to heap-based buffer
over-read. Reported by Hongxu Chen.
Version 2.29
+2
View File
@@ -183,6 +183,8 @@
/* Define if the linker defines __ehdr_start. */
#undef HAVE_EHDR_START
#define WANT_FLOAT128 0
/*
*/
+1
View File
@@ -103,6 +103,7 @@ use-nscd = @use_nscd@
build-hardcoded-path-in-tests= @hardcoded_path_in_tests@
build-pt-chown = @build_pt_chown@
have-tunables = @have_tunables@
enable-float128 = @enable_float128@
# Build tools.
CC = @CC@
Vendored
+72 -4
View File
@@ -670,6 +670,7 @@ stack_protector
libc_cv_ssp
libc_cv_with_fp
base_machine
enable_float128
have_tunables
build_pt_chown
build_nscd
@@ -733,6 +734,7 @@ infodir
docdir
oldincludedir
includedir
runstatedir
localstatedir
sharedstatedir
sysconfdir
@@ -762,6 +764,8 @@ with_gd_include
with_gd_lib
with_binutils
with_selinux
with_clang
with_lld
with_headers
with_default_link
with_nonshared_cflags
@@ -792,6 +796,7 @@ enable_build_nscd
enable_nscd
enable_pt_chown
enable_tunables
enable_float128
enable_mathvec
enable_cet
with_cpu
@@ -846,6 +851,7 @@ datadir='${datarootdir}'
sysconfdir='${prefix}/etc'
sharedstatedir='${prefix}/com'
localstatedir='${prefix}/var'
runstatedir='${localstatedir}/run'
includedir='${prefix}/include'
oldincludedir='/usr/include'
docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
@@ -1098,6 +1104,15 @@ do
| -silent | --silent | --silen | --sile | --sil)
silent=yes ;;
-runstatedir | --runstatedir | --runstatedi | --runstated \
| --runstate | --runstat | --runsta | --runst | --runs \
| --run | --ru | --r)
ac_prev=runstatedir ;;
-runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
| --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
| --run=* | --ru=* | --r=*)
runstatedir=$ac_optarg ;;
-sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
ac_prev=sbindir ;;
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
@@ -1235,7 +1250,7 @@ fi
for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
datadir sysconfdir sharedstatedir localstatedir includedir \
oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
libdir localedir mandir
libdir localedir mandir runstatedir
do
eval ac_val=\$$ac_var
# Remove trailing slashes.
@@ -1388,6 +1403,7 @@ Fine tuning of the installation directories:
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
--runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run]
--libdir=DIR object code libraries [EPREFIX/lib]
--includedir=DIR C header files [PREFIX/include]
--oldincludedir=DIR C header files for non-gcc [/usr/include]
@@ -1467,6 +1483,7 @@ Optional Features:
--enable-pt_chown Enable building and installing pt_chown
--enable-tunables Enable tunables support. Known values are 'yes',
'no' and 'valstring'
--disable-float128 disable float128 support
--enable-mathvec Enable building and installing mathvec [default
depends on architecture]
--enable-cet enable Intel Control-flow Enforcement Technology
@@ -1482,6 +1499,8 @@ Optional Packages:
--with-gd-lib=DIR find libgd library files in DIR
--with-binutils=PATH specify location of binutils (as and ld)
--with-selinux if building with SELinux support
--with-clang if building with clang (temporary)
--with-lld if building/linking with lld (temporary)
--with-headers=PATH location of system headers to use (for example
/usr/src/linux/include) [default=compiler default]
--with-default-link do not use explicit linker scripts
@@ -3324,6 +3343,26 @@ else
fi
# Check whether --with-clang was given.
if test "${with_clang+set}" = set; then :
withval=$with_clang; with_clang=$withval
else
with_clang=no
fi
config_vars="$config_vars
with-clang = $with_clang"
# Check whether --with-lld was given.
if test "${with_lld+set}" = set; then :
withval=$with_lld; with_lld=$withval
else
with_lld=no
fi
config_vars="$config_vars
with-lld = $with_lld"
# Check whether --with-headers was given.
if test "${with_headers+set}" = set; then :
@@ -3757,6 +3796,19 @@ if test "$have_tunables" = yes; then
fi
# Check whether --enable-float128 was given.
if test "${enable_float128+set}" = set; then :
enableval=$enable_float128; enable_float128=$enableval
else
enable_float128=yes
fi
if test "$enable_float128" = yes; then
$as_echo "#define WANT_FLOAT128 1" >>confdefs.h
fi
# The abi-tags file uses a fairly simplistic model for name recognition that
# can't distinguish i486-pc-linux-gnu fully from i486-pc-gnu. So we mutate a
# $host_os of `gnu*' here to be `gnu-gnu*' just so that it can tell.
@@ -3988,6 +4040,13 @@ else
fi
fi
# Workaround for clang assembler problem with ifunc relocs, b/119574415
if test "$with_clang" = no; then
no_integrated_as=
else
no_integrated_as=-no-integrated-as
fi
# For the multi-arch option we need support in the assembler & linker.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for assembler and linker STT_GNU_IFUNC support" >&5
$as_echo_n "checking for assembler and linker STT_GNU_IFUNC support... " >&6; }
@@ -4010,7 +4069,7 @@ __start:
EOF
libc_cv_ld_gnu_indirect_function=no
if ${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS \
-nostartfiles -nostdlib $no_ssp \
-nostartfiles -nostdlib $no_ssp $no_integrated_as \
-o conftest conftest.S 1>&5 2>&5; then
# Do a link to see if the backend supports IFUNC relocs.
$READELF -r conftest 1>&5
@@ -4528,6 +4587,7 @@ $as_echo "$libc_cv_prog_ld_gnu" >&6; }
gnu_ld=$libc_cv_prog_ld_gnu
if test "$with_clang" = no; then
# Accept binutils 2.25 or newer.
for ac_prog in $AS
do
@@ -4592,7 +4652,9 @@ if test $ac_verc_fail = yes; then
AS=: critic_missing="$critic_missing as"
fi
fi
if test "$with_lld" = no; then
if test -n "`$LD --version | sed -n 's/^GNU \(gold\).*$/\1/p'`"; then
# Accept gold 1.14 or higher
for ac_prog in $LD
@@ -4722,6 +4784,7 @@ if test $ac_verc_fail = yes; then
LD=: critic_missing="$critic_missing GNU ld"
fi
fi
fi
# These programs are version sensitive.
@@ -5120,7 +5183,9 @@ main ()
{
#if !defined __GNUC__ || __GNUC__ < 5
#if !defined __clang__
#error insufficient compiler
#endif
#endif
;
return 0;
@@ -6271,7 +6336,7 @@ char *foo (const char *a, const char *b)
return __builtin_strstr (a, b);
}
EOF
if { ac_try='${CC-cc} -O3 -S conftest.c -o - | grep -F "my_strstr" > /dev/null'
if { ac_try='${CC-cc} -O3 -S conftest.c -o - | grep -F "strstr" > /dev/null'
{ { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -6352,7 +6417,7 @@ __attribute__ ((__optimize__ ("-fno-tree-loop-distribute-patterns")))
foo (void) {}
EOF
libc_cv_cc_loop_to_function=no
if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -c conftest.c'
if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -Werror -c conftest.c'
{ { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -6872,7 +6937,10 @@ libc_cv_pie_default=$libc_cv_cc_pie_default
# Set the `multidir' variable by grabbing the variable from the compiler.
# We do it once and save the result in a generated makefile.
libc_cv_multidir=.
if test "$with_clang" = no; then
libc_cv_multidir=`${CC-cc} $CFLAGS $CPPFLAGS -print-multi-directory`
fi
if test "$static_pie" = yes; then
+43 -3
View File
@@ -137,6 +137,20 @@ AC_ARG_WITH([selinux],
[if building with SELinux support]),
[with_selinux=$withval],
[with_selinux=auto])
dnl This is a temporary hack, to help sort out wired-in GCC assumptions.
AC_ARG_WITH([clang],
AC_HELP_STRING([--with-clang],
[if building with clang (temporary)]),
[with_clang=$withval],
[with_clang=no])
LIBC_CONFIG_VAR([with-clang], [$with_clang])
dnl This is a temporary hack, to help with BFD LD vs LLD debugging.
AC_ARG_WITH([lld],
AC_HELP_STRING([--with-lld],
[if building/linking with lld (temporary)]),
[with_lld=$withval],
[with_lld=no])
LIBC_CONFIG_VAR([with-lld], [$with_lld])
AC_ARG_WITH([headers],
AC_HELP_STRING([--with-headers=PATH],
@@ -454,6 +468,16 @@ if test "$have_tunables" = yes; then
AC_DEFINE(HAVE_TUNABLES)
fi
AC_ARG_ENABLE([float128],
AC_HELP_STRING([--disable-float128],
[disable float128 support]),
[enable_float128=$enableval],
[enable_float128=yes])
AC_SUBST(enable_float128)
if test "$enable_float128" = yes; then
AC_DEFINE(WANT_FLOAT128)
fi
# The abi-tags file uses a fairly simplistic model for name recognition that
# can't distinguish i486-pc-linux-gnu fully from i486-pc-gnu. So we mutate a
# $host_os of `gnu*' here to be `gnu-gnu*' just so that it can tell.
@@ -618,6 +642,13 @@ else
fi
fi
# Workaround for clang assembler problem with ifunc relocs, b/119574415
if test "$with_clang" = no; then
no_integrated_as=
else
no_integrated_as=-no-integrated-as
fi
# For the multi-arch option we need support in the assembler & linker.
AC_CACHE_CHECK([for assembler and linker STT_GNU_IFUNC support],
libc_cv_ld_gnu_indirect_function, [dnl
@@ -637,7 +668,7 @@ __start:
EOF
libc_cv_ld_gnu_indirect_function=no
if ${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS \
-nostartfiles -nostdlib $no_ssp \
-nostartfiles -nostdlib $no_ssp $no_integrated_as \
-o conftest conftest.S 1>&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD; then
# Do a link to see if the backend supports IFUNC relocs.
$READELF -r conftest 1>&AS_MESSAGE_LOG_FD
@@ -971,12 +1002,15 @@ AC_PROG_LN_S
LIBC_PROG_BINUTILS
if test "$with_clang" = no; then
# Accept binutils 2.25 or newer.
AC_CHECK_PROG_VER(AS, $AS, --version,
[GNU assembler.* \([0-9]*\.[0-9.]*\)],
[2.1[0-9][0-9]*|2.2[5-9]*|2.[3-9][0-9]*|[3-9].*|[1-9][0-9]*],
AS=: critic_missing="$critic_missing as")
fi
if test "$with_lld" = no; then
if test -n "`$LD --version | sed -n 's/^GNU \(gold\).*$/\1/p'`"; then
# Accept gold 1.14 or higher
AC_CHECK_PROG_VER(LD, $LD, --version,
@@ -989,6 +1023,7 @@ else
[2.1[0-9][0-9]*|2.2[5-9]*|2.[3-9][0-9]*|[3-9].*|[1-9][0-9]*],
LD=: critic_missing="$critic_missing GNU ld")
fi
fi
# These programs are version sensitive.
AC_CHECK_TOOL_PREFIX
@@ -1018,7 +1053,9 @@ AC_CHECK_PROG_VER(BISON, bison, --version,
AC_CACHE_CHECK([if $CC is sufficient to build libc], libc_cv_compiler_ok, [
AC_TRY_COMPILE([], [
#if !defined __GNUC__ || __GNUC__ < 5
#if !defined __clang__
#error insufficient compiler
#endif
#endif],
[libc_cv_compiler_ok=yes],
[libc_cv_compiler_ok=no])])
@@ -1556,7 +1593,7 @@ char *foo (const char *a, const char *b)
}
EOF
dnl
if AC_TRY_COMMAND([${CC-cc} -O3 -S conftest.c -o - | grep -F "my_strstr" > /dev/null]);
if AC_TRY_COMMAND([${CC-cc} -O3 -S conftest.c -o - | grep -F "strstr" > /dev/null]);
then
libc_cv_gcc_builtin_redirection=yes
else
@@ -1599,7 +1636,7 @@ __attribute__ ((__optimize__ ("-fno-tree-loop-distribute-patterns")))
foo (void) {}
EOF
libc_cv_cc_loop_to_function=no
if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS -c conftest.c])
if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS -Werror -c conftest.c])
then
libc_cv_cc_loop_to_function=yes
fi
@@ -1865,7 +1902,10 @@ AC_SUBST(libc_cv_pie_default)
# Set the `multidir' variable by grabbing the variable from the compiler.
# We do it once and save the result in a generated makefile.
libc_cv_multidir=.
if test "$with_clang" = no; then
libc_cv_multidir=`${CC-cc} $CFLAGS $CPPFLAGS -print-multi-directory`
fi
AC_SUBST(libc_cv_multidir)
if test "$static_pie" = yes; then
+6 -1
View File
@@ -201,9 +201,11 @@ endif
test-srcs = tst-pathopt
selinux-enabled := $(shell cat /selinux/enforce 2> /dev/null)
ifneq ($(selinux-enabled),1)
ifneq ($(with-clang),yes)
tests-execstack-yes = tst-execstack tst-execstack-needed tst-execstack-prog
endif
endif
endif
tests += $(tests-execstack-$(have-z-execstack))
ifeq ($(run-built-tests),yes)
tests-special += $(objpfx)tst-leaks1-mem.out \
@@ -312,7 +314,9 @@ tests-pie += vismain
CFLAGS-vismain.c += $(PIE-ccflag)
endif
endif
ifneq ($(with-clang),yes)
modules-execstack-yes = tst-execstack-mod
endif
extra-test-objs += $(addsuffix .os,$(strip $(modules-names)))
# filtmod1.so has a special rule
@@ -458,9 +462,10 @@ $(objpfx)librtld.map: $(objpfx)dl-allobjs.os $(common-objpfx)libc_pic.a
rm -f $@.o
mv -f $@T $@
# For lld, add to regexp below for optional address and size to be at front of line.
$(objpfx)librtld.mk: $(objpfx)librtld.map Makefile
LC_ALL=C \
sed -n 's@^$(common-objpfx)\([^(]*\)(\([^)]*\.os\)) *.*$$@\1 \2@p' \
sed -n 's@^[0-9a-f ]*$(common-objpfx)\([^(]*\)(\([^)]*\.os\)) *.*$$@\1 \2@p' \
$< | \
while read lib file; do \
case $$lib in \
+42 -11
View File
@@ -27,17 +27,8 @@
#include <sys/types.h>
#include "dynamic-link.h"
void
_dl_resolve_conflicts (struct link_map *l, ElfW(Rela) *conflict,
ElfW(Rela) *conflictend)
{
#if ! ELF_MACHINE_NO_RELA
if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_RELOC))
_dl_debug_printf ("\nconflict processing: %s\n", DSO_FILENAME (l->l_name));
#ifndef NESTING
{
/* Do the conflict relocation of the object and library GOT and other
data. */
/* This macro is used as a callback from the ELF_DYNAMIC_RELOCATE code. */
#define RESOLVE_MAP(ref, version, flags) (*ref = NULL, NULL)
@@ -51,13 +42,49 @@ _dl_resolve_conflicts (struct link_map *l, ElfW(Rela) *conflict,
(map) = resolve_conflict_map; \
} while (0)
#include "dynamic-link.h"
#endif /* n NESTING */
void
_dl_resolve_conflicts (struct link_map *l, ElfW(Rela) *conflict,
ElfW(Rela) *conflictend)
{
#if ! ELF_MACHINE_NO_RELA
if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_RELOC))
_dl_debug_printf ("\nconflict processing: %s\n", DSO_FILENAME (l->l_name));
{
/* Do the conflict relocation of the object and library GOT and other
data. */
#ifdef NESTING
/* This macro is used as a callback from the ELF_DYNAMIC_RELOCATE code. */
#define RESOLVE_MAP(ref, version, flags) (*ref = NULL, NULL)
#define RESOLVE(ref, version, flags) (*ref = NULL, 0)
#define RESOLVE_CONFLICT_FIND_MAP(map, r_offset) \
do { \
while ((resolve_conflict_map->l_map_end < (ElfW(Addr)) (r_offset)) \
|| (resolve_conflict_map->l_map_start > (ElfW(Addr)) (r_offset))) \
resolve_conflict_map = resolve_conflict_map->l_next; \
\
(map) = resolve_conflict_map; \
} while (0)
#endif /* NESTING */
/* Prelinking makes no sense for anything but the main namespace. */
assert (l->l_ns == LM_ID_BASE);
struct link_map *resolve_conflict_map __attribute__ ((__unused__))
= GL(dl_ns)[LM_ID_BASE]._ns_loaded;
#ifdef NESTING
#include "dynamic-link.h"
#endif /* NESTING */
/* Override these, defined in dynamic-link.h. */
#undef CHECK_STATIC_TLS
#define CHECK_STATIC_TLS(ref_map, sym_map) ((void) 0)
@@ -68,7 +95,11 @@ _dl_resolve_conflicts (struct link_map *l, ElfW(Rela) *conflict,
for (; conflict < conflictend; ++conflict)
elf_machine_rela (l, conflict, NULL, NULL, (void *) conflict->r_offset,
0);
0
#ifndef NESTING
, NULL
#endif
);
}
#endif
}
+8 -1
View File
@@ -157,8 +157,11 @@ static uint32_t narcs;
currently in the mmaped file. At no point of time this has to be the
same as NARCS. If it is equal all entries from the file are in our
lists. */
#ifdef __clang__
static volatile unsigned long *narcsp;
#else
static volatile uint32_t *narcsp;
#endif
struct here_fromstruct
{
@@ -170,7 +173,11 @@ static volatile uint16_t *tos;
static struct here_fromstruct *froms;
static uint32_t fromlimit;
#ifdef __clang__
static volatile unsigned long fromidx;
#else
static volatile uint32_t fromidx;
#endif
static uintptr_t lowpc;
static size_t textsize;
+49 -1
View File
@@ -141,6 +141,40 @@ _dl_nothread_init_static_tls (struct link_map *map)
'\0', map->l_tls_blocksize - map->l_tls_initimage_size);
}
#ifndef NESTING
/* String table object symbols. */
static struct link_map *glob_l;
static struct r_scope_elem **glob_scope;
static const char *glob_strtab;
/* This macro is used as a callback from the ELF_DYNAMIC_RELOCATE code. */
#define RESOLVE_MAP(ref, version, r_type) \
((ELFW(ST_BIND) ((*ref)->st_info) != STB_LOCAL \
&& __glibc_likely (!dl_symbol_visibility_binds_local_p (*ref))) \
? ((__builtin_expect ((*ref) == glob_l->l_lookup_cache.sym, 0) \
&& elf_machine_type_class (r_type) == glob_l->l_lookup_cache.type_class) \
? (bump_num_cache_relocations (), \
(*ref) = glob_l->l_lookup_cache.ret, \
glob_l->l_lookup_cache.value) \
: ({ lookup_t _lr; \
int _tc = elf_machine_type_class (r_type); \
glob_l->l_lookup_cache.type_class = _tc; \
glob_l->l_lookup_cache.sym = (*ref); \
const struct r_found_version *v = NULL; \
if ((version) != NULL && (version)->hash != 0) \
v = (version); \
_lr = _dl_lookup_symbol_x (glob_strtab + (*ref)->st_name, glob_l, (ref), \
glob_scope, v, _tc, \
DL_LOOKUP_ADD_DEPENDENCY, NULL); \
glob_l->l_lookup_cache.ret = (*ref); \
glob_l->l_lookup_cache.value = _lr; })) \
: glob_l)
#include "dynamic-link.h"
#endif /* n NESTING */
void
_dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
@@ -223,6 +257,8 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
{
/* Do the actual relocation of the object's GOT and other data. */
#ifdef NESTING
/* String table object symbols. */
const char *strtab = (const void *) D_PTR (l, l_info[DT_STRTAB]);
@@ -251,7 +287,19 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
#include "dynamic-link.h"
ELF_DYNAMIC_RELOCATE (l, lazy, consider_profiling, skip_ifunc);
#else
glob_l = l;
glob_scope = scope;
glob_strtab = (const void *) D_PTR (glob_l, l_info[DT_STRTAB]);
#endif /* NESTING */
ELF_DYNAMIC_RELOCATE (l, lazy, consider_profiling, skip_ifunc
#ifndef NESTING
, NULL
#endif
);
#ifndef PROF
if (__glibc_unlikely (consider_profiling)
+3 -8
View File
@@ -328,14 +328,9 @@ _dl_show_auxv (void)
assert (AT_NULL == 0);
assert (AT_IGNORE == 1);
if (av->a_type == AT_HWCAP || av->a_type == AT_HWCAP2
|| AT_L1I_CACHEGEOMETRY || AT_L1D_CACHEGEOMETRY
|| AT_L2_CACHEGEOMETRY || AT_L3_CACHEGEOMETRY)
{
/* These are handled in a special way per platform. */
if (_dl_procinfo (av->a_type, av->a_un.a_val) == 0)
continue;
}
/* Some entries are handled in a special way per platform. */
if (_dl_procinfo (av->a_type, av->a_un.a_val) == 0)
continue;
if (idx < sizeof (auxvars) / sizeof (auxvars[0])
&& auxvars[idx].form != unknown)
+25 -5
View File
@@ -41,7 +41,11 @@ auto inline void __attribute__ ((always_inline))
elf_dynamic_do_Rel (struct link_map *map,
ElfW(Addr) reladdr, ElfW(Addr) relsize,
__typeof (((ElfW(Dyn) *) 0)->d_un.d_val) nrelative,
int lazy, int skip_ifunc)
int lazy, int skip_ifunc
#ifndef NESTING
, struct link_map *boot_map
#endif
)
{
const ElfW(Rel) *r = (const void *) reladdr;
const ElfW(Rel) *end = (const void *) (reladdr + relsize);
@@ -136,7 +140,11 @@ elf_dynamic_do_Rel (struct link_map *map,
ElfW(Half) ndx = version[ELFW(R_SYM) (r->r_info)] & 0x7fff;
elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)],
&map->l_versions[ndx],
(void *) (l_addr + r->r_offset), skip_ifunc);
(void *) (l_addr + r->r_offset), skip_ifunc
#ifndef NESTING
, boot_map
#endif
);
}
#if defined ELF_MACHINE_IRELATIVE && !defined RTLD_BOOTSTRAP
@@ -150,7 +158,11 @@ elf_dynamic_do_Rel (struct link_map *map,
&symtab[ELFW(R_SYM) (r2->r_info)],
&map->l_versions[ndx],
(void *) (l_addr + r2->r_offset),
skip_ifunc);
skip_ifunc
#ifndef NESTING
, boot_map
#endif
);
}
#endif
}
@@ -168,7 +180,11 @@ elf_dynamic_do_Rel (struct link_map *map,
else
# endif
elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)], NULL,
(void *) (l_addr + r->r_offset), skip_ifunc);
(void *) (l_addr + r->r_offset), skip_ifunc
#ifndef NESTING
, boot_map
#endif
);
# ifdef ELF_MACHINE_IRELATIVE
if (r2 != NULL)
@@ -176,7 +192,11 @@ elf_dynamic_do_Rel (struct link_map *map,
if (ELFW(R_TYPE) (r2->r_info) == ELF_MACHINE_IRELATIVE)
elf_machine_rel (map, r2, &symtab[ELFW(R_SYM) (r2->r_info)],
NULL, (void *) (l_addr + r2->r_offset),
skip_ifunc);
skip_ifunc
#ifndef NESTING
, boot_map
#endif
);
# endif
}
#endif
+93 -1
View File
@@ -16,6 +16,10 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#ifndef NESTING
#define auto static
#endif
/* This macro is used as a callback from elf_machine_rel{a,} when a
static TLS reloc is about to be performed. Since (in dl-load.c) we
permit dynamic loading of objects that might use such relocs, we
@@ -70,7 +74,11 @@ elf_machine_rel_relative (ElfW(Addr) l_addr, const ElfW(Rel) *reloc,
auto inline void __attribute__((always_inline))
elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
const ElfW(Sym) *sym, const struct r_found_version *version,
void *const reloc_addr, int skip_ifunc);
void *const reloc_addr, int skip_ifunc
#ifndef NESTING
, struct link_map *boot_map
#endif
);
auto inline void __attribute__((always_inline))
elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
void *const reloc_addr);
@@ -113,6 +121,60 @@ elf_machine_lazy_rel (struct link_map *map,
consumes precisely the very end of the DT_REL*, or DT_JMPREL and DT_REL*
are completely separate and there is a gap between them. */
#ifndef NESTING
# define _ELF_DYNAMIC_DO_RELOC(RELOC, reloc, map, do_lazy, skip_ifunc, test_rel, boot_map) \
do { \
struct { ElfW(Addr) start, size; \
__typeof (((ElfW(Dyn) *) 0)->d_un.d_val) nrelative; int lazy; } \
ranges[2] = { { 0, 0, 0, 0 }, { 0, 0, 0, 0 } }; \
\
if ((map)->l_info[DT_##RELOC]) \
{ \
ranges[0].start = D_PTR ((map), l_info[DT_##RELOC]); \
ranges[0].size = (map)->l_info[DT_##RELOC##SZ]->d_un.d_val; \
if (map->l_info[VERSYMIDX (DT_##RELOC##COUNT)] != NULL) \
ranges[0].nrelative \
= map->l_info[VERSYMIDX (DT_##RELOC##COUNT)]->d_un.d_val; \
} \
if ((map)->l_info[DT_PLTREL] \
&& (!test_rel || (map)->l_info[DT_PLTREL]->d_un.d_val == DT_##RELOC)) \
{ \
ElfW(Addr) start = D_PTR ((map), l_info[DT_JMPREL]); \
ElfW(Addr) size = (map)->l_info[DT_PLTRELSZ]->d_un.d_val; \
\
if (ranges[0].start + ranges[0].size == (start + size)) \
ranges[0].size -= size; \
if (ELF_DURING_STARTUP \
|| (!(do_lazy) \
&& (ranges[0].start + ranges[0].size) == start)) \
{ \
/* Combine processing the sections. */ \
ranges[0].size += size; \
} \
else \
{ \
ranges[1].start = start; \
ranges[1].size = size; \
ranges[1].lazy = (do_lazy); \
} \
} \
\
if (ELF_DURING_STARTUP) \
elf_dynamic_do_##reloc ((map), ranges[0].start, ranges[0].size, \
ranges[0].nrelative, 0, skip_ifunc, boot_map); \
else \
{ \
int ranges_index; \
for (ranges_index = 0; ranges_index < 2; ++ranges_index) \
elf_dynamic_do_##reloc ((map), \
ranges[ranges_index].start, \
ranges[ranges_index].size, \
ranges[ranges_index].nrelative, \
ranges[ranges_index].lazy, \
skip_ifunc, boot_map); \
} \
} while (0)
#else /* NESTING */
# define _ELF_DYNAMIC_DO_RELOC(RELOC, reloc, map, do_lazy, skip_ifunc, test_rel) \
do { \
struct { ElfW(Addr) start, size; \
@@ -165,6 +227,7 @@ elf_machine_lazy_rel (struct link_map *map,
skip_ifunc); \
} \
} while (0)
#endif /* NESTING */
# if ELF_MACHINE_NO_REL || ELF_MACHINE_NO_RELA
# define _ELF_CHECK_REL 0
@@ -172,6 +235,34 @@ elf_machine_lazy_rel (struct link_map *map,
# define _ELF_CHECK_REL 1
# endif
#ifndef NESTING
# if ! ELF_MACHINE_NO_REL
# include "do-rel.h"
# define ELF_DYNAMIC_DO_REL(map, lazy, skip_ifunc, boot_map) \
_ELF_DYNAMIC_DO_RELOC (REL, Rel, map, lazy, skip_ifunc, _ELF_CHECK_REL, boot_map)
# else
# define ELF_DYNAMIC_DO_REL(map, lazy, skip_ifunc, boot_map) /* Nothing to do. */
# endif
# if ! ELF_MACHINE_NO_RELA
# define DO_RELA
# include "do-rel.h"
# define ELF_DYNAMIC_DO_RELA(map, lazy, skip_ifunc, boot_map) \
_ELF_DYNAMIC_DO_RELOC (RELA, Rela, map, lazy, skip_ifunc, _ELF_CHECK_REL, boot_map)
# else
# define ELF_DYNAMIC_DO_RELA(map, lazy, skip_ifunc, boot_map) /* Nothing to do. */
# endif
/* This can't just be an inline function because GCC is too dumb
to inline functions containing inlines themselves. */
# define ELF_DYNAMIC_RELOCATE(map, lazy, consider_profile, skip_ifunc, boot_map) \
do { \
int edr_lazy = elf_machine_runtime_setup ((map), (lazy), \
(consider_profile)); \
ELF_DYNAMIC_DO_REL ((map), edr_lazy, skip_ifunc, boot_map); \
ELF_DYNAMIC_DO_RELA ((map), edr_lazy, skip_ifunc, boot_map); \
} while (0)
#else /* NESTING */
# if ! ELF_MACHINE_NO_REL
# include "do-rel.h"
# define ELF_DYNAMIC_DO_REL(map, lazy, skip_ifunc) \
@@ -198,5 +289,6 @@ elf_machine_lazy_rel (struct link_map *map,
ELF_DYNAMIC_DO_REL ((map), edr_lazy, skip_ifunc); \
ELF_DYNAMIC_DO_RELA ((map), edr_lazy, skip_ifunc); \
} while (0)
#endif /* NESTING */
#endif
+10
View File
@@ -22,6 +22,8 @@
#include <assert.h>
#include <libc-diag.h>
#if defined NESTING || !defined SAW_EGDI
#ifndef RESOLVE_MAP
static
#else
@@ -183,3 +185,11 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
info[DT_RPATH] = NULL;
#endif
}
#endif
#ifndef NESTING
#ifndef SAW_EGDI
#define SAW_EGDI
#endif
#endif /* n NESTING */
+49 -2
View File
@@ -325,7 +325,7 @@ DL_SYSINFO_IMPLEMENTATION
is fine, too. The latter is important here. We can avoid setting
up a temporary link map for ld.so if we can mark _rtld_global as
hidden. */
#ifdef PI_STATIC_AND_HIDDEN
#if 0 //def PI_STATIC_AND_HIDDEN
# define DONT_USE_BOOTSTRAP_MAP 1
#endif
@@ -393,7 +393,13 @@ _dl_start_final (void *arg, struct dl_start_final_info *info)
#endif
_dl_setup_hash (&GL(dl_rtld_map));
GL(dl_rtld_map).l_real = &GL(dl_rtld_map);
#if defined(__clang__)
/* Work around an lld complaint that _begin cannot have a reloc and
also be absolute because of _begin=0 on linker line. */
GL(dl_rtld_map).l_map_start = (ElfW(Addr)) 0;
#else
GL(dl_rtld_map).l_map_start = (ElfW(Addr)) _begin;
#endif
GL(dl_rtld_map).l_map_end = (ElfW(Addr)) _end;
GL(dl_rtld_map).l_text_end = (ElfW(Addr)) _etext;
/* Copy the TLS related data if necessary. */
@@ -440,9 +446,30 @@ _dl_start_final (void *arg, struct dl_start_final_info *info)
return start_addr;
}
#ifndef NESTING
#ifdef DONT_USE_BOOTSTRAP_MAP
# define bootstrap_map GL(dl_rtld_map)
#else
# define bootstrap_map info.l
#endif
/* This #define produces dynamic linking inline functions for
bootstrap relocation instead of general-purpose relocation.
Since ld.so must not have any undefined symbols the result
is trivial: always the map of ld.so itself. */
#define RTLD_BOOTSTRAP
#define RESOLVE_MAP(sym, version, flags) (&bootstrap_map)
#include "dynamic-link.h"
#endif /* n NESTING */
static ElfW(Addr) __attribute_used__
_dl_start (void *arg)
{
#ifndef NESTING
#ifndef DONT_USE_BOOTSTRAP_MAP
struct dl_start_final_info info;
#endif /* DUBM */
#else /* NESTING */
#ifdef DONT_USE_BOOTSTRAP_MAP
# define bootstrap_map GL(dl_rtld_map)
#else
@@ -458,6 +485,7 @@ _dl_start (void *arg)
#define BOOTSTRAP_MAP (&bootstrap_map)
#define RESOLVE_MAP(sym, version, flags) BOOTSTRAP_MAP
#include "dynamic-link.h"
#endif /* NESTING */
if (HP_TIMING_INLINE && HP_SMALL_TIMING_AVAIL)
#ifdef DONT_USE_BOOTSTRAP_MAP
@@ -503,7 +531,11 @@ _dl_start (void *arg)
/* Relocate ourselves so we can do normal function calls and
data access using the global offset table. */
ELF_DYNAMIC_RELOCATE (&bootstrap_map, 0, 0, 0);
ELF_DYNAMIC_RELOCATE (&bootstrap_map, 0, 0, 0
#ifndef NESTING
, &bootstrap_map
#endif
);
}
bootstrap_map.l_relocated = 1;
@@ -2794,3 +2826,18 @@ print_statistics (hp_timing_t *rtld_total_timep)
}
#endif
}
#ifndef NESTING
char *dummy1 = (char *)elf_get_dynamic_info;
# if ! ELF_MACHINE_NO_REL
char *dummy2 = (char *)elf_machine_rel;
char *dummy3 = (char *)elf_machine_rel_relative;
#endif
# if ! ELF_MACHINE_NO_RELA
char *dummy4 = (char *)elf_machine_rela;
char *dummy5 = (char *)elf_machine_rela_relative;
#endif
# if ELF_MACHINE_NO_RELA || defined ELF_MACHINE_PLT_REL
char *dummy6 = (char *)elf_machine_lazy_rel;
#endif
#endif
+1 -1
View File
@@ -1,7 +1,7 @@
/* Macros to support TLS testing in times of missing compiler support. */
#define COMMON_INT_DEF(x) \
asm (".tls_common " #x ",4,4")
__thread int x;
/* XXX Until we get compiler support we don't need declarations. */
#define COMMON_INT_DECL(x)
+12
View File
@@ -114,6 +114,10 @@ enum
/* Internal function. Terminate the process using __libc_fatal. */
void __libc_alloc_buffer_create_failure (void *start, size_t size);
/* clang wants a hidden proto ahead of use. */
#ifndef _ISOMAC
libc_hidden_proto (__libc_alloc_buffer_create_failure)
#endif
/* Create a new allocation buffer. The byte range from START to START
+ SIZE - 1 must be valid, and the allocation buffer allocates
@@ -132,6 +136,10 @@ alloc_buffer_create (void *start, size_t size)
/* Internal function. See alloc_buffer_allocate below. */
struct alloc_buffer __libc_alloc_buffer_allocate (size_t size, void **pptr)
__attribute__ ((nonnull (2)));
/* clang wants a hidden proto ahead of use. */
#ifndef _ISOMAC
libc_hidden_proto (__libc_alloc_buffer_allocate)
#endif
/* Allocate a buffer of SIZE bytes using malloc. The returned buffer
is in a failed state if malloc fails. *PPTR points to the start of
@@ -342,6 +350,10 @@ alloc_buffer_copy_bytes (struct alloc_buffer *buf, const void *src, size_t size)
struct alloc_buffer __libc_alloc_buffer_copy_string (struct alloc_buffer,
const char *)
__attribute__ ((nonnull (2)));
/* clang wants a hidden proto ahead of use. */
#ifndef _ISOMAC
libc_hidden_proto (__libc_alloc_buffer_copy_string)
#endif
/* Copy the string at SRC into the buffer, including its null
terminator. If there is not enough room in the buffer, the buffer
+5
View File
@@ -28,6 +28,11 @@ void *__libc_allocate_once_slow (void **__place,
void *__ptr),
void *__closure);
#ifdef __clang__
/* clang needs the hidden proto to be specified ahead of its use. */
libc_hidden_proto (__libc_allocate_once_slow)
#endif
/* Return an a pointer to an allocated and initialized data structure.
If this function returns a non-NULL value, the caller can assume
that pointed-to data has been initialized according to the ALLOCATE
+1 -2
View File
@@ -462,11 +462,10 @@
/* Decide whether we can define 'extern inline' functions in headers. */
#if __GNUC_PREREQ (2, 7) && defined __OPTIMIZE__ \
&& !defined __OPTIMIZE_SIZE__ && !defined __NO_INLINE__ \
&& defined __extern_inline
&& defined __extern_inline && !defined __clang__
# define __USE_EXTERN_INLINES 1
#endif
/* This is here only because every header file already includes this one.
Get the definitions of all the appropriate `__stub_FUNCTION' symbols.
<gnu/stubs.h> contains `#define __stub_FUNCTION' when FUNCTION is a stub
+10
View File
@@ -530,9 +530,19 @@ for linking")
__hidden_proto (name, , __GI_##name, ##attrs)
# define hidden_tls_proto(name, attrs...) \
__hidden_proto (name, __thread, __GI_##name, ##attrs)
#ifndef __clang__
# define __hidden_proto(name, thread, internal, attrs...) \
extern thread __typeof (name) name __asm__ (__hidden_asmname (#internal)) \
__hidden_proto_hiddenattr (attrs);
#else
# define __hidden_proto(name, thread, internal, attrs...) \
extern thread __typeof (name) name \
__hidden_proto_hiddenattr (attrs); \
_Pragma (__redefine(name, internal))
/* Note that this macro does not use __hidden_asmname, since it produces a string. */
# define __redefine(name, internal) __stringize(redefine_extname name internal)
# define __stringize(X) #X
#endif
# define __hidden_asmname(name) \
__hidden_asmname1 (__USER_LABEL_PREFIX__, name)
# define __hidden_asmname1(prefix, name) __hidden_asmname2(prefix, name)
+1
View File
@@ -21,6 +21,7 @@
#ifdef USE_STAP_PROBE
# include <stap-probe-machine.h>
# include <sys/sdt.h>
/* Our code uses one macro LIBC_PROBE (name, n, arg1, ..., argn).
+4 -2
View File
@@ -14946,12 +14946,14 @@ am_pm "<U5348><U524D>";"<U5348><U5F8C>"
t_fmt_ampm "%p%I<U6642>%M<U5206>%S<U79D2>"
era "+:2:1990//01//01:+*:<U5E73><U6210>:%EC%Ey<U5E74>";/
era "+:2:2020//01//01:+*:<U4EE4><U548C>:%EC%Ey<U5E74>";/
"+:1:2019//05//01:2019//12//31:<U4EE4><U548C>:%EC<U5143><U5E74>";/
"+:2:1990//01//01:2019//04//30:<U5E73><U6210>:%EC%Ey<U5E74>";/
"+:1:1989//01//08:1989//12//31:<U5E73><U6210>:%EC<U5143><U5E74>";/
"+:2:1927//01//01:1989//01//07:<U662D><U548C>:%EC%Ey<U5E74>";/
"+:1:1926//12//25:1926//12//31:<U662D><U548C>:%EC<U5143><U5E74>";/
"+:2:1913//01//01:1926//12//24:<U5927><U6B63>:%EC%Ey<U5E74>";/
"+:2:1912//07//30:1912//12//31:<U5927><U6B63>:%EC<U5143><U5E74>";/
"+:1:1912//07//30:1912//12//31:<U5927><U6B63>:%EC<U5143><U5E74>";/
"+:6:1873//01//01:1912//07//29:<U660E><U6CBB>:%EC%Ey<U5E74>";/
"+:1:0001//01//01:1872//12//31:<U897F><U66A6>:%EC%Ey<U5E74>";/
"+:1:-0001//12//31:-*:<U7D00><U5143><U524D>:%EC%Ey<U5E74>"
+4
View File
@@ -112,7 +112,11 @@ struct entry
};
static struct entry buffer[2 * DEFAULT_BUFFER_SIZE];
#ifdef __clang__
static long buffer_cnt;
#else
static uatomic32_t buffer_cnt;
#endif
static struct entry first;
+46 -26
View File
@@ -121,6 +121,41 @@ lock_and_info (const void *caller, Dl_info *mem)
return res;
}
static void tr_freehook (void *, const void *);
static void * tr_mallochook (size_t, const void *);
static void * tr_reallochook (void *, size_t, const void *);
static void * tr_memalignhook (size_t, size_t, const void *);
/* Set all the default non-trace hooks. */
static __always_inline void
set_default_hooks (void)
{
__free_hook = tr_old_free_hook;
__malloc_hook = tr_old_malloc_hook;
__realloc_hook = tr_old_realloc_hook;
__memalign_hook = tr_old_memalign_hook;
}
/* Set all of the tracing hooks used for mtrace. */
static __always_inline void
set_trace_hooks (void)
{
__free_hook = tr_freehook;
__malloc_hook = tr_mallochook;
__realloc_hook = tr_reallochook;
__memalign_hook = tr_memalignhook;
}
/* Save the current set of hooks as the default hooks. */
static __always_inline void
save_default_hooks (void)
{
tr_old_free_hook = __free_hook;
tr_old_malloc_hook = __malloc_hook;
tr_old_realloc_hook = __realloc_hook;
tr_old_memalign_hook = __memalign_hook;
}
static void
tr_freehook (void *ptr, const void *caller)
{
@@ -138,12 +173,12 @@ tr_freehook (void *ptr, const void *caller)
tr_break ();
__libc_lock_lock (lock);
}
__free_hook = tr_old_free_hook;
set_default_hooks ();
if (tr_old_free_hook != NULL)
(*tr_old_free_hook)(ptr, caller);
else
free (ptr);
__free_hook = tr_freehook;
set_trace_hooks ();
__libc_lock_unlock (lock);
}
@@ -155,12 +190,12 @@ tr_mallochook (size_t size, const void *caller)
Dl_info mem;
Dl_info *info = lock_and_info (caller, &mem);
__malloc_hook = tr_old_malloc_hook;
set_default_hooks ();
if (tr_old_malloc_hook != NULL)
hdr = (void *) (*tr_old_malloc_hook)(size, caller);
else
hdr = (void *) malloc (size);
__malloc_hook = tr_mallochook;
set_trace_hooks ();
tr_where (caller, info);
/* We could be printing a NULL here; that's OK. */
@@ -185,16 +220,12 @@ tr_reallochook (void *ptr, size_t size, const void *caller)
Dl_info mem;
Dl_info *info = lock_and_info (caller, &mem);
__free_hook = tr_old_free_hook;
__malloc_hook = tr_old_malloc_hook;
__realloc_hook = tr_old_realloc_hook;
set_default_hooks ();
if (tr_old_realloc_hook != NULL)
hdr = (void *) (*tr_old_realloc_hook)(ptr, size, caller);
else
hdr = (void *) realloc (ptr, size);
__free_hook = tr_freehook;
__malloc_hook = tr_mallochook;
__realloc_hook = tr_reallochook;
set_trace_hooks ();
tr_where (caller, info);
if (hdr == NULL)
@@ -230,14 +261,12 @@ tr_memalignhook (size_t alignment, size_t size, const void *caller)
Dl_info mem;
Dl_info *info = lock_and_info (caller, &mem);
__memalign_hook = tr_old_memalign_hook;
__malloc_hook = tr_old_malloc_hook;
set_default_hooks ();
if (tr_old_memalign_hook != NULL)
hdr = (void *) (*tr_old_memalign_hook)(alignment, size, caller);
else
hdr = (void *) memalign (alignment, size);
__memalign_hook = tr_memalignhook;
__malloc_hook = tr_mallochook;
set_trace_hooks ();
tr_where (caller, info);
/* We could be printing a NULL here; that's OK. */
@@ -305,14 +334,8 @@ mtrace (void)
malloc_trace_buffer = mtb;
setvbuf (mallstream, malloc_trace_buffer, _IOFBF, TRACE_BUFFER_SIZE);
fprintf (mallstream, "= Start\n");
tr_old_free_hook = __free_hook;
__free_hook = tr_freehook;
tr_old_malloc_hook = __malloc_hook;
__malloc_hook = tr_mallochook;
tr_old_realloc_hook = __realloc_hook;
__realloc_hook = tr_reallochook;
tr_old_memalign_hook = __memalign_hook;
__memalign_hook = tr_memalignhook;
save_default_hooks ();
set_trace_hooks ();
#ifdef _LIBC
if (!added_atexit_handler)
{
@@ -338,10 +361,7 @@ muntrace (void)
file. */
FILE *f = mallstream;
mallstream = NULL;
__free_hook = tr_old_free_hook;
__malloc_hook = tr_old_malloc_hook;
__realloc_hook = tr_old_realloc_hook;
__memalign_hook = tr_old_memalign_hook;
set_default_hooks ();
fprintf (f, "= End\n");
fclose (f);
+2 -2
View File
@@ -35,8 +35,8 @@ call_free (void *ptr)
int
do_test (void)
{
void *ptr1 = malloc (SIZE);
void *ptr2 = malloc (SIZE);
void *volatile ptr1 = malloc (SIZE);
void *volatile ptr2 = malloc (SIZE);
/* Avoid unwanted output to TTY after an expected memory corruption. */
ignore_stderr();
+1 -1
View File
@@ -69,7 +69,7 @@ test_setup (void)
static void
test_large_allocations (size_t size)
{
void * ptr_to_realloc;
void *volatile ptr_to_realloc;
test_setup ();
TEST_VERIFY (malloc (size) == NULL);
+1 -1
View File
@@ -33,7 +33,7 @@ merror (const char *msg)
static int
do_test (void)
{
void *p, *q;
void *volatile p, *volatile q;
int save;
errno = 0;
+1 -1
View File
@@ -33,7 +33,7 @@ merror (const char *msg)
static int
do_test (void)
{
void *p, *q;
void *volatile p, *volatile q;
errno = 0;
+1 -1
View File
@@ -33,7 +33,7 @@ merror (const char *msg)
static int
do_test (void)
{
void *p;
void *volatile p;
unsigned char *c;
int save, i, ok;
+1 -1
View File
@@ -34,7 +34,7 @@ merror (const char *msg)
static int
do_test (void)
{
void *p;
void *volatile p;
unsigned long pagesize = getpagesize ();
unsigned long ptrval;
int save;
+3 -1
View File
@@ -361,9 +361,11 @@ tgmath3-macros = atan2 cbrt ceil copysign erf erfc exp2 expm1 fdim floor \
fromfp fromfpx ufromfp ufromfpx totalorder totalordermag \
scalb
tgmath3-macro-tests = $(addprefix test-tgmath3-,$(tgmath3-macros))
# Suppress these tests with clang for now, multiple issues
ifneq ($(with-clang),yes)
tests += $(tgmath3-macro-tests)
generated += $(addsuffix .c,$(tgmath3-macro-tests))
endif
$(tgmath3-macro-tests:%=$(objpfx)%.o): CFLAGS += -fno-builtin
$(foreach m,$(tgmath3-macros),\
+25
View File
@@ -52,23 +52,40 @@ __BEGIN_DECLS
#undef I
#define I _Complex_I
#if defined __USE_ISOC11 && defined __clang__
/* Clang casts types to _Complex instead of using __builtin_complex. */
#define __CMPLX(x, y, t) (+(_Complex t){(t)(x), (t)(y)})
#define CMPLX(x, y) __CMPLX(x, y, double)
#define CMPLXF(x, y) __CMPLX(x, y, float)
#define CMPLXL(x, y) __CMPLX(x, y, long double)
#else
#if defined __USE_ISOC11 && __GNUC_PREREQ (4, 7)
/* Macros to expand into expression of specified complex type. */
# define CMPLX(x, y) __builtin_complex ((double) (x), (double) (y))
# define CMPLXF(x, y) __builtin_complex ((float) (x), (float) (y))
# define CMPLXL(x, y) __builtin_complex ((long double) (x), (long double) (y))
#endif
#endif /* __clang __ */
#if __HAVE_FLOAT16 && __GLIBC_USE (IEC_60559_TYPES_EXT)
# define CMPLXF16(x, y) __builtin_complex ((_Float16) (x), (_Float16) (y))
#endif
#if __HAVE_FLOAT32 && __GLIBC_USE (IEC_60559_TYPES_EXT)
#if defined(__clang__)
/* The typedef _Float32 does not seem to work here. */
# define CMPLXF32(x, y) __CMPLX(x, y, float)
#else
# define CMPLXF32(x, y) __builtin_complex ((_Float32) (x), (_Float32) (y))
#endif /* __clang __ */
#endif
#if __HAVE_FLOAT64 && __GLIBC_USE (IEC_60559_TYPES_EXT)
#if defined(__clang__)
# define CMPLXF64(x, y) __CMPLX(x, y, double)
#else
# define CMPLXF64(x, y) __builtin_complex ((_Float64) (x), (_Float64) (y))
#endif /* __clang __ */
#endif
#if __HAVE_FLOAT128 && __GLIBC_USE (IEC_60559_TYPES_EXT)
@@ -76,11 +93,19 @@ __BEGIN_DECLS
#endif
#if __HAVE_FLOAT32X && __GLIBC_USE (IEC_60559_TYPES_EXT)
#if defined(__clang__)
# define CMPLXF32X(x, y) __CMPLX(x, y, double)
#else
# define CMPLXF32X(x, y) __builtin_complex ((_Float32x) (x), (_Float32x) (y))
#endif
#endif /* __clang __ */
#if __HAVE_FLOAT64X && __GLIBC_USE (IEC_60559_TYPES_EXT)
#if defined(__clang__)
# define CMPLXF64X(x, y) __CMPLX(x, y, long double)
#else
# define CMPLXF64X(x, y) __builtin_complex ((_Float64x) (x), (_Float64x) (y))
#endif /* __clang __ */
#endif
#if __HAVE_FLOAT128X && __GLIBC_USE (IEC_60559_TYPES_EXT)
+4
View File
@@ -20,7 +20,11 @@
#ifdef FE_INVALID
# ifndef FE_SNANS_ALWAYS_SIGNAL
# ifdef __clang__
# warning "FE_SNANS_ALWAYS_SIGNAL not defined, fix clang please"
# else
# error "FE_SNANS_ALWAYS_SIGNAL not defined"
# endif
# endif
#else
# ifdef FE_SNANS_ALWAYS_SIGNAL
+4
View File
@@ -21,8 +21,12 @@
#include <atomic.h>
#ifndef atomic_t
#ifdef __clang__
# define atomic_t long
#else
# define atomic_t int
#endif
#endif
/* Test various atomic.h macros. */
static int
+16 -3
View File
@@ -231,6 +231,11 @@ CFLAGS-fsync.c += -fexceptions -fasynchronous-unwind-tables
CFLAGS-pt-system.c += -fexceptions
# Workaround for clang assembler problem with ifunc relocs, b/119574415
ifeq ($(with-clang),yes)
CFLAGS-pt-vfork.c += -no-integrated-as
endif
LDLIBS-tst-once5 = -lstdc++
CFLAGS-tst-thread_local1.o = -std=gnu++11
LDLIBS-tst-thread_local1 = -lstdc++
@@ -319,7 +324,8 @@ tests = tst-attr1 tst-attr2 tst-attr3 tst-default-attr \
tst-cnd-basic tst-mtx-trylock tst-cnd-broadcast \
tst-cnd-timedwait tst-thrd-detach tst-mtx-basic tst-thrd-sleep \
tst-mtx-recursive tst-tss-basic tst-call-once tst-mtx-timedlock \
tst-rwlock-pwn
tst-rwlock-pwn \
tst-rwlock-tryrdlock-stall tst-rwlock-trywrlock-stall
tests-internal := tst-rwlock19 tst-rwlock20 \
tst-sem11 tst-sem12 tst-sem13 \
@@ -388,16 +394,22 @@ tests += tst-atfork2 tst-tls4 tst-_res1 tst-fini1 tst-compat-forwarder \
tests-internal += tst-tls3 tst-tls3-malloc tst-tls5 tst-stackguard1
tests-nolibpthread += tst-fini1
ifeq ($(have-z-execstack),yes)
# Test depends on a nested function, can't compile without rewrite
ifneq ($(with-clang),yes)
tests += tst-execstack
endif
endif
endif
modules-names = tst-atfork2mod tst-tls3mod tst-tls4moda tst-tls4modb \
tst-tls5mod tst-tls5moda tst-tls5modb tst-tls5modc \
tst-tls5modd tst-tls5mode tst-tls5modf tst-stack4mod \
tst-_res1mod1 tst-_res1mod2 tst-execstack-mod tst-fini1mod \
tst-_res1mod1 tst-_res1mod2 tst-fini1mod \
tst-join7mod tst-compat-forwarder-mod tst-audit-threads-mod1 \
tst-audit-threads-mod2
ifneq ($(with-clang),yes)
modules-names += tst-execstack-mod
endif
extra-test-objs += $(addsuffix .os,$(strip $(modules-names))) \
tst-cleanup4aux.o tst-cleanupx4aux.o
test-extras += tst-cleanup4aux tst-cleanupx4aux
@@ -422,10 +434,11 @@ ifeq ($(build-shared),yes)
# Set the `multidir' variable by grabbing the variable from the compiler.
# We do it once and save the result in a generated makefile.
# Suppress not-working clang attempt to include 32 and x32 multidirs.
-include $(objpfx)multidir.mk
$(objpfx)multidir.mk: $(common-objpfx)config.make
$(make-target-directory)
dir=`$(CC) $(CFLAGS) $(CPPFLAGS) -print-multi-directory`; \
dir="."; \
echo "multidir := $$dir" > $@T
mv -f $@T $@
+3 -2
View File
@@ -86,6 +86,7 @@ __pthread_timedjoin_ex (pthread_t threadid, void **thread_return,
pthread_cleanup_pop (0);
}
void *pd_result = pd->result;
if (__glibc_likely (result == 0))
{
/* We mark the thread as terminated and as joined. */
@@ -93,7 +94,7 @@ __pthread_timedjoin_ex (pthread_t threadid, void **thread_return,
/* Store the return value if the caller is interested. */
if (thread_return != NULL)
*thread_return = pd->result;
*thread_return = pd_result;
/* Free the TCB. */
__free_tcb (pd);
@@ -101,7 +102,7 @@ __pthread_timedjoin_ex (pthread_t threadid, void **thread_return,
else
pd->joinid = NULL;
LIBC_PROBE (pthread_join_ret, 3, threadid, result, pd->result);
LIBC_PROBE (pthread_join_ret, 3, threadid, result, pd_result);
return result;
}
+53 -4
View File
@@ -94,6 +94,9 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex)
case PTHREAD_MUTEX_ROBUST_ADAPTIVE_NP:
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
&mutex->__data.__list.__next);
/* We need to set op_pending before starting the operation. Also
see comments at ENQUEUE_MUTEX. */
__asm ("" ::: "memory");
oldval = mutex->__data.__lock;
do
@@ -119,7 +122,12 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex)
/* But it is inconsistent unless marked otherwise. */
mutex->__data.__owner = PTHREAD_MUTEX_INCONSISTENT;
/* We must not enqueue the mutex before we have acquired it.
Also see comments at ENQUEUE_MUTEX. */
__asm ("" ::: "memory");
ENQUEUE_MUTEX (mutex);
/* We need to clear op_pending after we enqueue the mutex. */
__asm ("" ::: "memory");
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
/* Note that we deliberately exist here. If we fall
@@ -135,6 +143,8 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex)
int kind = PTHREAD_MUTEX_TYPE (mutex);
if (kind == PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP)
{
/* We do not need to ensure ordering wrt another memory
access. Also see comments at ENQUEUE_MUTEX. */
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
NULL);
return EDEADLK;
@@ -142,6 +152,8 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex)
if (kind == PTHREAD_MUTEX_ROBUST_RECURSIVE_NP)
{
/* We do not need to ensure ordering wrt another memory
access. */
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
NULL);
@@ -160,6 +172,9 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex)
id, 0);
if (oldval != 0 && (oldval & FUTEX_OWNER_DIED) == 0)
{
/* We haven't acquired the lock as it is already acquired by
another owner. We do not need to ensure ordering wrt another
memory access. */
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
return EBUSY;
@@ -173,13 +188,20 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex)
if (oldval == id)
lll_unlock (mutex->__data.__lock,
PTHREAD_ROBUST_MUTEX_PSHARED (mutex));
/* FIXME This violates the mutex destruction requirements. See
__pthread_mutex_unlock_full. */
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
return ENOTRECOVERABLE;
}
}
while ((oldval & FUTEX_OWNER_DIED) != 0);
/* We must not enqueue the mutex before we have acquired it.
Also see comments at ENQUEUE_MUTEX. */
__asm ("" ::: "memory");
ENQUEUE_MUTEX (mutex);
/* We need to clear op_pending after we enqueue the mutex. */
__asm ("" ::: "memory");
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
mutex->__data.__owner = id;
@@ -211,10 +233,15 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex)
}
if (robust)
/* Note: robust PI futexes are signaled by setting bit 0. */
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
(void *) (((uintptr_t) &mutex->__data.__list.__next)
| 1));
{
/* Note: robust PI futexes are signaled by setting bit 0. */
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
(void *) (((uintptr_t) &mutex->__data.__list.__next)
| 1));
/* We need to set op_pending before starting the operation. Also
see comments at ENQUEUE_MUTEX. */
__asm ("" ::: "memory");
}
oldval = mutex->__data.__lock;
@@ -223,12 +250,16 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex)
{
if (kind == PTHREAD_MUTEX_ERRORCHECK_NP)
{
/* We do not need to ensure ordering wrt another memory
access. */
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
return EDEADLK;
}
if (kind == PTHREAD_MUTEX_RECURSIVE_NP)
{
/* We do not need to ensure ordering wrt another memory
access. */
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
/* Just bump the counter. */
@@ -250,6 +281,9 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex)
{
if ((oldval & FUTEX_OWNER_DIED) == 0)
{
/* We haven't acquired the lock as it is already acquired by
another owner. We do not need to ensure ordering wrt another
memory access. */
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
return EBUSY;
@@ -270,6 +304,9 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex)
if (INTERNAL_SYSCALL_ERROR_P (e, __err)
&& INTERNAL_SYSCALL_ERRNO (e, __err) == EWOULDBLOCK)
{
/* The kernel has not yet finished the mutex owner death.
We do not need to ensure ordering wrt another memory
access. */
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
return EBUSY;
@@ -287,7 +324,12 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex)
/* But it is inconsistent unless marked otherwise. */
mutex->__data.__owner = PTHREAD_MUTEX_INCONSISTENT;
/* We must not enqueue the mutex before we have acquired it.
Also see comments at ENQUEUE_MUTEX. */
__asm ("" ::: "memory");
ENQUEUE_MUTEX (mutex);
/* We need to clear op_pending after we enqueue the mutex. */
__asm ("" ::: "memory");
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
/* Note that we deliberately exit here. If we fall
@@ -310,13 +352,20 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex)
PTHREAD_ROBUST_MUTEX_PSHARED (mutex)),
0, 0);
/* To the kernel, this will be visible after the kernel has
acquired the mutex in the syscall. */
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
return ENOTRECOVERABLE;
}
if (robust)
{
/* We must not enqueue the mutex before we have acquired it.
Also see comments at ENQUEUE_MUTEX. */
__asm ("" ::: "memory");
ENQUEUE_MUTEX_PI (mutex);
/* We need to clear op_pending after we enqueue the mutex. */
__asm ("" ::: "memory");
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
}
+16 -9
View File
@@ -94,15 +94,22 @@ __pthread_rwlock_tryrdlock (pthread_rwlock_t *rwlock)
/* Same as in __pthread_rwlock_rdlock_full:
We started the read phase, so we are also responsible for
updating the write-phase futex. Relaxed MO is sufficient.
Note that there can be no other reader that we have to wake
because all other readers will see the read phase started by us
(or they will try to start it themselves); if a writer started
the read phase, we cannot have started it. Furthermore, we
cannot discard a PTHREAD_RWLOCK_FUTEX_USED flag because we will
overwrite the value set by the most recent writer (or the readers
before it in case of explicit hand-over) and we know that there
are no waiting readers. */
atomic_store_relaxed (&rwlock->__data.__wrphase_futex, 0);
We have to do the same steps as a writer would when handing over the
read phase to use because other readers cannot distinguish between
us and the writer.
Note that __pthread_rwlock_tryrdlock callers will not have to be
woken up because they will either see the read phase started by us
or they will try to start it themselves; however, callers of
__pthread_rwlock_rdlock_full just increase the reader count and then
check what state the lock is in, so they cannot distinguish between
us and a writer that acquired and released the lock in the
meantime. */
if ((atomic_exchange_relaxed (&rwlock->__data.__wrphase_futex, 0)
& PTHREAD_RWLOCK_FUTEX_USED) != 0)
{
int private = __pthread_rwlock_get_private (rwlock);
futex_wake (&rwlock->__data.__wrphase_futex, INT_MAX, private);
}
}
return 0;
+8 -1
View File
@@ -46,8 +46,15 @@ __pthread_rwlock_trywrlock (pthread_rwlock_t *rwlock)
&rwlock->__data.__readers, &r,
r | PTHREAD_RWLOCK_WRPHASE | PTHREAD_RWLOCK_WRLOCKED))
{
/* We have become the primary writer and we cannot have shared
the PTHREAD_RWLOCK_FUTEX_USED flag with someone else, so we
can simply enable blocking (see full wrlock code). */
atomic_store_relaxed (&rwlock->__data.__writers_futex, 1);
atomic_store_relaxed (&rwlock->__data.__wrphase_futex, 1);
/* If we started a write phase, we need to enable readers to
wait. If we did not, we must not change it because other threads
may have set the PTHREAD_RWLOCK_FUTEX_USED in the meantime. */
if ((r & PTHREAD_RWLOCK_WRPHASE) == 0)
atomic_store_relaxed (&rwlock->__data.__wrphase_futex, 1);
atomic_store_relaxed (&rwlock->__data.__cur_writer,
THREAD_GETMEM (THREAD_SELF, tid));
return 0;
+5 -3
View File
@@ -107,13 +107,14 @@ __unregister_atfork (void *dso_handle)
}
void
__run_fork_handlers (enum __run_fork_handler_type who)
__run_fork_handlers (enum __run_fork_handler_type who, _Bool do_locking)
{
struct fork_handler *runp;
if (who == atfork_run_prepare)
{
lll_lock (atfork_lock, LLL_PRIVATE);
if (do_locking)
lll_lock (atfork_lock, LLL_PRIVATE);
size_t sl = fork_handler_list_size (&fork_handlers);
for (size_t i = sl; i > 0; i--)
{
@@ -133,7 +134,8 @@ __run_fork_handlers (enum __run_fork_handler_type who)
else if (who == atfork_run_parent && runp->parent_handler)
runp->parent_handler ();
}
lll_unlock (atfork_lock, LLL_PRIVATE);
if (do_locking)
lll_unlock (atfork_lock, LLL_PRIVATE);
}
}
+355
View File
@@ -0,0 +1,355 @@
/* Bug 23844: Test for pthread_rwlock_tryrdlock stalls.
Copyright (C) 2019 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
<http://www.gnu.org/licenses/>. */
/* For a full analysis see comment:
https://sourceware.org/bugzilla/show_bug.cgi?id=23844#c14
Provided here for reference:
--- Analysis of pthread_rwlock_tryrdlock() stall ---
A read lock begins to execute.
In __pthread_rwlock_rdlock_full:
We can attempt a read lock, but find that the lock is
in a write phase (PTHREAD_RWLOCK_WRPHASE, or WP-bit
is set), and the lock is held by a primary writer
(PTHREAD_RWLOCK_WRLOCKED is set). In this case we must
wait for explicit hand over from the writer to us or
one of the other waiters. The read lock threads are
about to execute:
341 r = (atomic_fetch_add_acquire (&rwlock->__data.__readers,
342 (1 << PTHREAD_RWLOCK_READER_SHIFT))
343 + (1 << PTHREAD_RWLOCK_READER_SHIFT));
An unlock beings to execute.
Then in __pthread_rwlock_wrunlock:
547 unsigned int r = atomic_load_relaxed (&rwlock->__data.__readers);
...
549 while (!atomic_compare_exchange_weak_release
550 (&rwlock->__data.__readers, &r,
551 ((r ^ PTHREAD_RWLOCK_WRLOCKED)
552 ^ ((r >> PTHREAD_RWLOCK_READER_SHIFT) == 0 ? 0
553 : PTHREAD_RWLOCK_WRPHASE))))
554 {
...
556 }
We clear PTHREAD_RWLOCK_WRLOCKED, and if there are
no readers so we leave the lock in PTHRAD_RWLOCK_WRPHASE.
Back in the read lock.
The read lock adjusts __readres as above.
383 while ((r & PTHREAD_RWLOCK_WRPHASE) != 0
384 && (r & PTHREAD_RWLOCK_WRLOCKED) == 0)
385 {
...
390 if (atomic_compare_exchange_weak_acquire (&rwlock->__data.__readers, &r,
391 r ^ PTHREAD_RWLOCK_WRPHASE))
392 {
And then attemps to start the read phase.
Assume there happens to be a tryrdlock at this point, noting
that PTHREAD_RWLOCK_WRLOCKED is clear, and PTHREAD_RWLOCK_WRPHASE
is 1. So the try lock attemps to start the read phase.
In __pthread_rwlock_tryrdlock:
44 if ((r & PTHREAD_RWLOCK_WRPHASE) == 0)
45 {
...
49 if (((r & PTHREAD_RWLOCK_WRLOCKED) != 0)
50 && (rwlock->__data.__flags
51 == PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP))
52 return EBUSY;
53 rnew = r + (1 << PTHREAD_RWLOCK_READER_SHIFT);
54 }
...
89 while (!atomic_compare_exchange_weak_acquire (&rwlock->__data.__readers,
90 &r, rnew));
And succeeds.
Back in the write unlock:
557 if ((r >> PTHREAD_RWLOCK_READER_SHIFT) != 0)
558 {
...
563 if ((atomic_exchange_relaxed (&rwlock->__data.__wrphase_futex, 0)
564 & PTHREAD_RWLOCK_FUTEX_USED) != 0)
565 futex_wake (&rwlock->__data.__wrphase_futex, INT_MAX, private);
566 }
We note that PTHREAD_RWLOCK_FUTEX_USED is non-zero
and don't wake anyone. This is OK because we handed
over to the trylock. It will be the trylock's responsibility
to wake any waiters.
Back in the read lock:
The read lock fails to install PTHRAD_REWLOCK_WRPHASE as 0 because
the __readers value was adjusted by the trylock, and so it falls through
to waiting on the lock for explicit handover from either a new writer
or a new reader.
448 int err = futex_abstimed_wait (&rwlock->__data.__wrphase_futex,
449 1 | PTHREAD_RWLOCK_FUTEX_USED,
450 abstime, private);
We use PTHREAD_RWLOCK_FUTEX_USED to indicate the futex
is in use.
At this point we have readers waiting on the read lock
to unlock. The wrlock is done. The trylock is finishing
the installation of the read phase.
92 if ((r & PTHREAD_RWLOCK_WRPHASE) != 0)
93 {
...
105 atomic_store_relaxed (&rwlock->__data.__wrphase_futex, 0);
106 }
The trylock does note that we were the one that
installed the read phase, but the comments are not
correct, the execution ordering above shows that
readers might indeed be waiting, and they are.
The atomic_store_relaxed throws away PTHREAD_RWLOCK_FUTEX_USED,
and the waiting reader is never worken becuase as noted
above it is conditional on the futex being used.
The solution is for the trylock thread to inspect
PTHREAD_RWLOCK_FUTEX_USED and wake the waiting readers.
--- Analysis of pthread_rwlock_trywrlock() stall ---
A write lock begins to execute, takes the write lock,
and then releases the lock...
In pthread_rwlock_wrunlock():
547 unsigned int r = atomic_load_relaxed (&rwlock->__data.__readers);
...
549 while (!atomic_compare_exchange_weak_release
550 (&rwlock->__data.__readers, &r,
551 ((r ^ PTHREAD_RWLOCK_WRLOCKED)
552 ^ ((r >> PTHREAD_RWLOCK_READER_SHIFT) == 0 ? 0
553 : PTHREAD_RWLOCK_WRPHASE))))
554 {
...
556 }
... leaving it in the write phase with zero readers
(the case where we leave the write phase in place
during a write unlock).
A write trylock begins to execute.
In __pthread_rwlock_trywrlock:
40 while (((r & PTHREAD_RWLOCK_WRLOCKED) == 0)
41 && (((r >> PTHREAD_RWLOCK_READER_SHIFT) == 0)
42 || (prefer_writer && ((r & PTHREAD_RWLOCK_WRPHASE) != 0))))
43 {
The lock is not locked.
There are no readers.
45 if (atomic_compare_exchange_weak_acquire (
46 &rwlock->__data.__readers, &r,
47 r | PTHREAD_RWLOCK_WRPHASE | PTHREAD_RWLOCK_WRLOCKED))
We atomically install the write phase and we take the
exclusive write lock.
48 {
49 atomic_store_relaxed (&rwlock->__data.__writers_futex, 1);
We get this far.
A reader lock begins to execute.
In pthread_rwlock_rdlock:
437 for (;;)
438 {
439 while (((wpf = atomic_load_relaxed (&rwlock->__data.__wrphase_futex))
440 | PTHREAD_RWLOCK_FUTEX_USED) == (1 | PTHREAD_RWLOCK_FUTEX_USED))
441 {
442 int private = __pthread_rwlock_get_private (rwlock);
443 if (((wpf & PTHREAD_RWLOCK_FUTEX_USED) == 0)
444 && (!atomic_compare_exchange_weak_relaxed
445 (&rwlock->__data.__wrphase_futex,
446 &wpf, wpf | PTHREAD_RWLOCK_FUTEX_USED)))
447 continue;
448 int err = futex_abstimed_wait (&rwlock->__data.__wrphase_futex,
449 1 | PTHREAD_RWLOCK_FUTEX_USED,
450 abstime, private);
We are in a write phase, so the while() on line 439 is true.
The value of wpf does not have PTHREAD_RWLOCK_FUTEX_USED set
since this is the first reader to lock.
The atomic operation sets wpf with PTHREAD_RELOCK_FUTEX_USED
on the expectation that this reader will be woken during
the handoff.
Back in pthread_rwlock_trywrlock:
50 atomic_store_relaxed (&rwlock->__data.__wrphase_futex, 1);
51 atomic_store_relaxed (&rwlock->__data.__cur_writer,
52 THREAD_GETMEM (THREAD_SELF, tid));
53 return 0;
54 }
...
57 }
We write 1 to __wrphase_futex discarding PTHREAD_RWLOCK_FUTEX_USED,
and so in the unlock we will not awaken the waiting reader.
The solution to this is to realize that if we did not start the write
phase we need not write 1 or any other value to __wrphase_futex.
This ensures that any readers (which saw __wrphase_futex != 0) can
set PTHREAD_RWLOCK_FUTEX_USED and this can be used at unlock to
wake them.
If we installed the write phase then all other readers are looping
here:
In __pthread_rwlock_rdlock_full:
437 for (;;)
438 {
439 while (((wpf = atomic_load_relaxed (&rwlock->__data.__wrphase_futex))
440 | PTHREAD_RWLOCK_FUTEX_USED) == (1 | PTHREAD_RWLOCK_FUTEX_USED))
441 {
...
508 }
waiting for the write phase to be installed or removed before they
can begin waiting on __wrphase_futex (part of the algorithm), or
taking a concurrent read lock, and thus we can safely write 1 to
__wrphase_futex.
If we did not install the write phase then the readers may already
be waiting on the futex, the original writer wrote 1 to __wrphase_futex
as part of starting the write phase, and we cannot also write 1
without loosing the PTHREAD_RWLOCK_FUTEX_USED bit.
---
Summary for the pthread_rwlock_tryrdlock() stall:
The stall is caused by pthread_rwlock_tryrdlock failing to check
that PTHREAD_RWLOCK_FUTEX_USED is set in the __wrphase_futex futex
and then waking the futex.
The fix for bug 23844 ensures that waiters on __wrphase_futex are
correctly woken. Before the fix the test stalls as readers can
wait forever on __wrphase_futex. */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <support/xthread.h>
#include <errno.h>
/* We need only one lock to reproduce the issue. We will need multiple
threads to get the exact case where we have a read, try, and unlock
all interleaving to produce the case where the readers are waiting
and the try fails to wake them. */
pthread_rwlock_t onelock;
/* The number of threads is arbitrary but empirically chosen to have
enough threads that we see the condition where waiting readers are
not woken by a successful tryrdlock. */
#define NTHREADS 32
_Atomic int do_exit;
void *
run_loop (void *arg)
{
int i = 0, ret;
while (!do_exit)
{
/* Arbitrarily choose if we are the writer or reader. Choose a
high enough ratio of readers to writers to make it likely
that readers block (and eventually are susceptable to
stalling).
If we are a writer, take the write lock, and then unlock.
If we are a reader, try the lock, then lock, then unlock. */
if ((i % 8) != 0)
xpthread_rwlock_wrlock (&onelock);
else
{
if ((ret = pthread_rwlock_tryrdlock (&onelock)) != 0)
{
if (ret == EBUSY)
xpthread_rwlock_rdlock (&onelock);
else
exit (EXIT_FAILURE);
}
}
/* Thread does some work and then unlocks. */
xpthread_rwlock_unlock (&onelock);
i++;
}
return NULL;
}
int
do_test (void)
{
int i;
pthread_t tids[NTHREADS];
xpthread_rwlock_init (&onelock, NULL);
for (i = 0; i < NTHREADS; i++)
tids[i] = xpthread_create (NULL, run_loop, NULL);
/* Run for some amount of time. Empirically speaking exercising
the stall via pthread_rwlock_tryrdlock is much harder, and on
a 3.5GHz 4 core x86_64 VM system it takes somewhere around
20-200s to stall, approaching 100% stall past 200s. We can't
wait that long for a regression test so we just test for 20s,
and expect the stall to happen with a 5-10% chance (enough for
developers to see). */
sleep (20);
/* Then exit. */
printf ("INFO: Exiting...\n");
do_exit = 1;
/* If any readers stalled then we will timeout waiting for them. */
for (i = 0; i < NTHREADS; i++)
xpthread_join (tids[i]);
printf ("INFO: Done.\n");
xpthread_rwlock_destroy (&onelock);
printf ("PASS: No pthread_rwlock_tryrdlock stalls detected.\n");
return 0;
}
#define TIMEOUT 30
#include <support/test-driver.c>
+108
View File
@@ -0,0 +1,108 @@
/* Bug 23844: Test for pthread_rwlock_trywrlock stalls.
Copyright (C) 2019 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
<http://www.gnu.org/licenses/>. */
/* For a full analysis see comments in tst-rwlock-tryrdlock-stall.c.
Summary for the pthread_rwlock_trywrlock() stall:
The stall is caused by pthread_rwlock_trywrlock setting
__wrphase_futex futex to 1 and loosing the
PTHREAD_RWLOCK_FUTEX_USED bit.
The fix for bug 23844 ensures that waiters on __wrphase_futex are
correctly woken. Before the fix the test stalls as readers can
wait forever on __wrphase_futex. */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <support/xthread.h>
#include <errno.h>
/* We need only one lock to reproduce the issue. We will need multiple
threads to get the exact case where we have a read, try, and unlock
all interleaving to produce the case where the readers are waiting
and the try clears the PTHREAD_RWLOCK_FUTEX_USED bit and a
subsequent unlock fails to wake them. */
pthread_rwlock_t onelock;
/* The number of threads is arbitrary but empirically chosen to have
enough threads that we see the condition where waiting readers are
not woken by a successful unlock. */
#define NTHREADS 32
_Atomic int do_exit;
void *
run_loop (void *arg)
{
int i = 0, ret;
while (!do_exit)
{
/* Arbitrarily choose if we are the writer or reader. Choose a
high enough ratio of readers to writers to make it likely
that readers block (and eventually are susceptable to
stalling).
If we are a writer, take the write lock, and then unlock.
If we are a reader, try the lock, then lock, then unlock. */
if ((i % 8) != 0)
{
if ((ret = pthread_rwlock_trywrlock (&onelock)) != 0)
{
if (ret == EBUSY)
xpthread_rwlock_wrlock (&onelock);
else
exit (EXIT_FAILURE);
}
}
else
xpthread_rwlock_rdlock (&onelock);
/* Thread does some work and then unlocks. */
xpthread_rwlock_unlock (&onelock);
i++;
}
return NULL;
}
int
do_test (void)
{
int i;
pthread_t tids[NTHREADS];
xpthread_rwlock_init (&onelock, NULL);
for (i = 0; i < NTHREADS; i++)
tids[i] = xpthread_create (NULL, run_loop, NULL);
/* Run for some amount of time. The pthread_rwlock_tryrwlock stall
is very easy to trigger and happens in seconds under the test
conditions. */
sleep (10);
/* Then exit. */
printf ("INFO: Exiting...\n");
do_exit = 1;
/* If any readers stalled then we will timeout waiting for them. */
for (i = 0; i < NTHREADS; i++)
xpthread_join (tids[i]);
printf ("INFO: Done.\n");
xpthread_rwlock_destroy (&onelock);
printf ("PASS: No pthread_rwlock_tryrwlock stalls detected.\n");
return 0;
}
#include <support/test-driver.c>
+45
View File
@@ -618,6 +618,47 @@ next_prime (size_t seed)
return seed;
}
#ifndef NESTING
static struct database *globdb;
static size_t max_chainlength;
static char *wp;
static size_t nhashentries;
static bool copy_string;
void add_key(const void *nodep, const VISIT which, const int depth)
{
if (which != leaf && which != postorder)
return;
const struct dbentry *dbe = *(const struct dbentry **) nodep;
ptrdiff_t stridx;
if (copy_string)
{
stridx = wp - globdb->keystrtab;
wp = stpcpy (wp, dbe->str) + 1;
}
else
stridx = 0;
size_t hidx = dbe->hashval % nhashentries;
size_t hval2 = 1 + dbe->hashval % (nhashentries - 2);
size_t chainlength = 0;
while (globdb->hashtable[hidx] != ~((stridx_t) 0))
{
++chainlength;
if ((hidx += hval2) >= nhashentries)
hidx -= nhashentries;
}
globdb->hashtable[hidx] = ((globdb->extra_string ? valstrlen : 0)
+ dbe->validx);
globdb->keyidxtab[hidx] = stridx;
max_chainlength = MAX (max_chainlength, chainlength);
}
#endif
static void
compute_tables (void)
@@ -649,6 +690,7 @@ compute_tables (void)
db->keyidxtab = db->hashtable + nhashentries_max;
db->keystrtab = (char *) (db->keyidxtab + nhashentries_max);
#ifdef NESTING
static size_t max_chainlength;
static char *wp;
static size_t nhashentries;
@@ -687,6 +729,9 @@ compute_tables (void)
max_chainlength = MAX (max_chainlength, chainlength);
}
#else
globdb = db;
#endif
copy_string = false;
nhashentries = nhashentries_min;
+2
View File
@@ -117,6 +117,8 @@ install-others-programs := $(inst_libexecdir)/getconf
before-compile += $(objpfx)posix-conf-vars-def.h
CFLAGS-regex.c += -Wno-error
# So they get cleaned up.
generated += $(addprefix wordexp-test-result, 1 2 3 4 5 6 7 8 9 10) \
annexc annexc.out wordexp-tst.out bug-regex2-mem.out \
+270 -1
View File
@@ -2839,6 +2839,261 @@ build_collating_symbol (bitset_t sbcset, const unsigned char *name)
}
#endif /* not _LIBC */
#ifndef NESTING
/* Local function for parse_bracket_exp used in _LIBC environment.
Seek the collating symbol entry corresponding to NAME.
Return the index of the symbol in the SYMB_TABLE,
or -1 if not found. */
static int32_t
__attribute__ ((always_inline))
seek_collating_symbol_entry (const unsigned char *name, size_t name_len,
int32_t *symb_table, int32_t table_size,
unsigned char *extra)
{
int32_t elem;
for (elem = 0; elem < table_size; elem++)
if (symb_table[2 * elem] != 0)
{
int32_t idx = symb_table[2 * elem + 1];
/* Skip the name of collating element name. */
idx += 1 + extra[idx];
if (/* Compare the length of the name. */
name_len == extra[idx]
/* Compare the name. */
&& memcmp (name, &extra[idx + 1], name_len) == 0)
/* Yep, this is the entry. */
return elem;
}
return -1;
}
/* Local function for parse_bracket_exp used in _LIBC environment.
Look up the collation sequence value of BR_ELEM.
Return the value if succeeded, UINT_MAX otherwise. */
static unsigned int
__attribute__ ((always_inline))
lookup_collation_sequence_value (bracket_elem_t *br_elem, uint32_t nrules,
unsigned char *collseqmb, char *collseqwc,
int32_t *symb_table, int32_t table_size,
unsigned char *extra)
{
if (br_elem->type == SB_CHAR)
{
/*
if (MB_CUR_MAX == 1)
*/
if (nrules == 0)
return collseqmb[br_elem->opr.ch];
else
{
wint_t wc = __btowc (br_elem->opr.ch);
return __collseq_table_lookup (collseqwc, wc);
}
}
else if (br_elem->type == MB_CHAR)
{
if (nrules != 0)
return __collseq_table_lookup (collseqwc, br_elem->opr.wch);
}
else if (br_elem->type == COLL_SYM)
{
size_t sym_name_len = strlen ((char *) br_elem->opr.name);
if (nrules != 0)
{
int32_t elem, idx;
elem = seek_collating_symbol_entry (br_elem->opr.name,
sym_name_len,
symb_table, table_size,
extra);
if (elem != -1)
{
/* We found the entry. */
idx = symb_table[2 * elem + 1];
/* Skip the name of collating element name. */
idx += 1 + extra[idx];
/* Skip the byte sequence of the collating element. */
idx += 1 + extra[idx];
/* Adjust for the alignment. */
idx = (idx + 3) & ~3;
/* Skip the multibyte collation sequence value. */
idx += sizeof (unsigned int);
/* Skip the wide char sequence of the collating element. */
idx += sizeof (unsigned int) *
(1 + *(unsigned int *) (extra + idx));
/* Return the collation sequence value. */
return *(unsigned int *) (extra + idx);
}
else if (sym_name_len == 1)
{
/* No valid character. Match it as a single byte
character. */
return collseqmb[br_elem->opr.name[0]];
}
}
else if (sym_name_len == 1)
return collseqmb[br_elem->opr.name[0]];
}
return UINT_MAX;
}
/* Local function for parse_bracket_exp used in _LIBC environment.
Build the range expression which starts from START_ELEM, and ends
at END_ELEM. The result are written to MBCSET and SBCSET.
RANGE_ALLOC is the allocated size of mbcset->range_starts, and
mbcset->range_ends, is a pointer argument since we may
update it. */
static reg_errcode_t
__attribute__ ((always_inline))
build_range_exp (bitset_t sbcset, re_charset_t *mbcset, int *range_alloc,
bracket_elem_t *start_elem, bracket_elem_t *end_elem,
re_dfa_t *dfa, reg_syntax_t syntax, uint32_t nrules,
unsigned char *collseqmb, char *collseqwc,
int32_t *symb_table, int32_t table_size,
unsigned char *extra)
{
unsigned int ch;
uint32_t start_collseq;
uint32_t end_collseq;
/* Equivalence Classes and Character Classes can't be a range
start/end. */
if (__glibc_unlikely (start_elem->type == EQUIV_CLASS || start_elem->type == CHAR_CLASS
|| end_elem->type == EQUIV_CLASS || end_elem->type == CHAR_CLASS))
return REG_ERANGE;
start_collseq = lookup_collation_sequence_value (start_elem, nrules, collseqmb, collseqwc,
symb_table, table_size, extra);
end_collseq = lookup_collation_sequence_value (end_elem, nrules, collseqmb, collseqwc,
symb_table, table_size, extra);
/* Check start/end collation sequence values. */
if (__glibc_unlikely (start_collseq == UINT_MAX || end_collseq == UINT_MAX))
return REG_ECOLLATE;
if (__glibc_unlikely ((syntax & RE_NO_EMPTY_RANGES) && start_collseq > end_collseq))
return REG_ERANGE;
/* Got valid collation sequence values, add them as a new entry.
However, if we have no collation elements, and the character set
is single byte, the single byte character set that we
build below suffices. */
if (nrules > 0 || dfa->mb_cur_max > 1)
{
/* Check the space of the arrays. */
if (__glibc_unlikely (*range_alloc == mbcset->nranges))
{
/* There is not enough space, need realloc. */
uint32_t *new_array_start;
uint32_t *new_array_end;
int new_nranges;
/* +1 in case of mbcset->nranges is 0. */
new_nranges = 2 * mbcset->nranges + 1;
new_array_start = re_realloc (mbcset->range_starts, uint32_t,
new_nranges);
new_array_end = re_realloc (mbcset->range_ends, uint32_t,
new_nranges);
if (__glibc_unlikely (new_array_start == NULL || new_array_end == NULL))
return REG_ESPACE;
mbcset->range_starts = new_array_start;
mbcset->range_ends = new_array_end;
*range_alloc = new_nranges;
}
mbcset->range_starts[mbcset->nranges] = start_collseq;
mbcset->range_ends[mbcset->nranges++] = end_collseq;
}
/* Build the table for single byte characters. */
for (ch = 0; ch < SBC_MAX; ch++)
{
uint32_t ch_collseq;
/*
if (MB_CUR_MAX == 1)
*/
if (nrules == 0)
ch_collseq = collseqmb[ch];
else
ch_collseq = __collseq_table_lookup (collseqwc, __btowc (ch));
if (start_collseq <= ch_collseq && ch_collseq <= end_collseq)
bitset_set (sbcset, ch);
}
return REG_NOERROR;
}
/* Local function for parse_bracket_exp used in _LIBC environment.
Build the collating element which is represented by NAME.
The result are written to MBCSET and SBCSET.
COLL_SYM_ALLOC is the allocated size of mbcset->coll_sym, is a
pointer argument since we may update it. */
static reg_errcode_t
__attribute__ ((always_inline))
build_collating_symbol (bitset_t sbcset, re_charset_t *mbcset,
int *coll_sym_alloc, const unsigned char *name,
uint32_t nrules, int32_t *symb_table, int32_t table_size,
unsigned char *extra)
{
int32_t elem, idx;
size_t name_len = strlen ((const char *) name);
if (nrules != 0)
{
elem = seek_collating_symbol_entry (name, name_len, symb_table,
table_size, extra);
if (elem != -1)
{
/* We found the entry. */
idx = symb_table[2 * elem + 1];
/* Skip the name of collating element name. */
idx += 1 + extra[idx];
}
else if (name_len == 1)
{
/* No valid character, treat it as a normal
character. */
bitset_set (sbcset, name[0]);
return REG_NOERROR;
}
else
return REG_ECOLLATE;
/* Got valid collation sequence, add it as a new entry. */
/* Check the space of the arrays. */
if (__glibc_unlikely (*coll_sym_alloc == mbcset->ncoll_syms))
{
/* Not enough, realloc it. */
/* +1 in case of mbcset->ncoll_syms is 0. */
int new_coll_sym_alloc = 2 * mbcset->ncoll_syms + 1;
/* Use realloc since mbcset->coll_syms is NULL
if *alloc == 0. */
int32_t *new_coll_syms = re_realloc (mbcset->coll_syms, int32_t,
new_coll_sym_alloc);
if (__glibc_unlikely (new_coll_syms == NULL))
return REG_ESPACE;
mbcset->coll_syms = new_coll_syms;
*coll_sym_alloc = new_coll_sym_alloc;
}
mbcset->coll_syms[mbcset->ncoll_syms++] = idx;
return REG_NOERROR;
}
else
{
if (__glibc_unlikely (name_len != 1))
return REG_ECOLLATE;
else
{
bitset_set (sbcset, name[0]);
return REG_NOERROR;
}
}
}
#endif /* n NESTING */
/* This function parse bracket expression like "[abc]", "[a-c]",
"[[.a-a.]]" etc. */
@@ -2854,6 +3109,8 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
const int32_t *symb_table;
const unsigned char *extra;
# ifdef NESTING
/* Local function for parse_bracket_exp used in _LIBC environment.
Seek the collating symbol entry corresponding to NAME.
Return the index of the symbol in the SYMB_TABLE,
@@ -3095,6 +3352,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
}
}
}
# endif /* NESTING */
#endif
re_token_t br_token;
@@ -3237,8 +3495,15 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
token_len = peek_token_bracket (token, regexp, syntax);
#ifdef _LIBC
# ifdef NESTING
*err = build_range_exp (sbcset, mbcset, &range_alloc,
&start_elem, &end_elem);
# else /* n NESTING */
*err = build_range_exp (sbcset, mbcset, &range_alloc,
&start_elem, &end_elem,
dfa, syntax, nrules, collseqmb, collseqwc,
symb_table, table_size, extra);
# endif /* NESTING */
#else
# ifdef RE_ENABLE_I18N
*err = build_range_exp (syntax, sbcset,
@@ -3291,7 +3556,11 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
#ifdef RE_ENABLE_I18N
mbcset, &coll_sym_alloc,
#endif /* RE_ENABLE_I18N */
start_elem.opr.name);
start_elem.opr.name
#ifndef NESTING
, nrules, symb_table, table_size, extra
#endif /* NESTING */
);
if (__glibc_unlikely (*err != REG_NOERROR))
goto parse_bracket_exp_free_return;
break;
+4 -2
View File
@@ -1293,8 +1293,10 @@ proceed_next_node (const re_match_context_t *mctx, Idx nregs, regmatch_t *regs,
else if (naccepted)
{
char *buf = (char *) re_string_get_buffer (&mctx->input);
if (memcmp (buf + regs[subexp_idx].rm_so, buf + *pidx,
naccepted) != 0)
if (mctx->input.valid_len - *pidx < naccepted
|| (memcmp (buf + regs[subexp_idx].rm_so, buf + *pidx,
naccepted)
!= 0))
return -1;
}
}
+3 -3
View File
@@ -61,9 +61,9 @@ def gen_test(sym_data):
continue
name = arg[0]
value = arg[1]
out_lines.append('_Static_assert (U (asconst_%s) == (c_t) (%s), '
'"value of %s");'
% (name, value, name))
# out_lines.append('_Static_assert (U (asconst_%s) == (c_t) (%s), '
# '"value of %s");'
# % (name, value, name))
return '\n'.join(out_lines)
+2
View File
@@ -5,6 +5,7 @@
int
do_test (void)
{
#ifndef __clang__ /* clang never finishes */
size_t instances = 16384;
#define X0 "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
const char *item = "\na\nabbcd55";
@@ -44,6 +45,7 @@ do_test (void)
return 1;
}
free (buf);
#endif /* __clang__ */
return 0;
}
#define TEST_FUNCTION do_test ()
+15 -16
View File
@@ -21,27 +21,26 @@
#include <stdio.h>
#include <string.h>
int failures = 0;
void
try (const char *name, long long int param, int value, int expected)
{
if (value != expected)
{
printf ("%s(%#llx) expected %d got %d\n",
name, param, expected, value);
++failures;
}
else
printf ("%s(%#llx) as expected %d\n", name, param, value);
}
int
do_test (void)
{
int failures = 0;
int i;
auto void try (const char *name, long long int param, int value,
int expected);
void try (const char *name, long long int param, int value, int expected)
{
if (value != expected)
{
printf ("%s(%#llx) expected %d got %d\n",
name, param, expected, value);
++failures;
}
else
printf ("%s(%#llx) as expected %d\n", name, param, value);
}
#define TEST(fct, type) \
try (#fct, 0, fct ((type) 0), 0); \
for (i=0 ; i < 8 * sizeof (type); i++) \
+1
View File
@@ -129,6 +129,7 @@ libsupport-routines = \
xpthread_mutexattr_settype \
xpthread_once \
xpthread_rwlock_init \
xpthread_rwlock_destroy \
xpthread_rwlock_rdlock \
xpthread_rwlock_unlock \
xpthread_rwlock_wrlock \
+26
View File
@@ -0,0 +1,26 @@
/* pthread_rwlock_destroy with error checking.
Copyright (C) 2019 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
<http://www.gnu.org/licenses/>. */
#include <support/xthread.h>
void
xpthread_rwlock_destroy (pthread_rwlock_t *rwlock)
{
xpthread_check_return ("pthread_rwlock_destroy",
pthread_rwlock_destroy (rwlock));
}
+1
View File
@@ -84,6 +84,7 @@ void xpthread_rwlockattr_setkind_np (pthread_rwlockattr_t *attr, int pref);
void xpthread_rwlock_wrlock (pthread_rwlock_t *rwlock);
void xpthread_rwlock_rdlock (pthread_rwlock_t *rwlock);
void xpthread_rwlock_unlock (pthread_rwlock_t *rwlock);
void xpthread_rwlock_destroy (pthread_rwlock_t *rwlock);
__END_DECLS
+22
View File
@@ -0,0 +1,22 @@
/* Macros for customizing Systemtap <sys/sdt.h>. Arm version.
Copyright (C) 2019 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
<http://www.gnu.org/licenses/>. */
/* The default "nor" constraint produces unparseable memory references
for constants. Omit the problematic "o" constraint. See bug 24164
and GCC PR 89146. */
#define STAP_SDT_ARG_CONSTRAINT nr
+4
View File
@@ -719,7 +719,11 @@ _dl_dprintf (int fd, const char *fmt, ...)
{
/* Use local declaration to avoid includign <stdio.h>. */
extern int __dprintf(int fd, const char *format, ...) attribute_hidden;
#if defined(__clang__)
__dprintf (fd, fmt);
#else
__dprintf (fd, fmt, __builtin_va_arg_pack ());
#endif
}
#endif
+19
View File
@@ -0,0 +1,19 @@
/* Macros for customizing Systemtap <sys/sdt.h>. Generic version.
Copyright (C) 2019 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
<http://www.gnu.org/licenses/>. */
/* By default, there are no customizations. */
+1 -1
View File
@@ -1,4 +1,4 @@
# Include this earlier so it can be used earlier in Makefiles,
# and sysdep/ makefiles.
float128-fcts = yes
float128-fcts = $(enable-float128)
float64x-alias-fcts = yes
+2
View File
@@ -1,3 +1,4 @@
ifeq ($(enable-float128),yes)
ifeq ($(subdir),stdlib)
routines += float1282mpn strfromf128
routines += strtof128 strtof128_l strtof128_nan mpn2float128
@@ -10,3 +11,4 @@ endif
ifeq ($(subdir),wcsmbs)
routines += wcstof128_l wcstof128 wcstof128_nan
endif
endif # enable-float128
+1 -1
View File
@@ -38,7 +38,7 @@ static char rcsid[] = "$NetBSD: k_standard.c,v 1.6 1995/05/10 20:46:35 jtc Exp $
# if 0
static const double zero = 0.0; /* used as const */
# else
static double zero = 0.0; /* used as const */
volatile static double zero = 0.0; /* used as const */
# endif
/*
+3 -3
View File
@@ -55,7 +55,7 @@ __libc_fork (void)
but our current fork implementation is not. */
bool multiple_threads = THREAD_GETMEM (THREAD_SELF, header.multiple_threads);
__run_fork_handlers (atfork_run_prepare);
__run_fork_handlers (atfork_run_prepare, multiple_threads);
/* If we are not running multiple threads, we do not have to
preserve lock state. If fork runs from a signal handler, only
@@ -134,7 +134,7 @@ __libc_fork (void)
__rtld_lock_initialize (GL(dl_load_lock));
/* Run the handlers registered for the child. */
__run_fork_handlers (atfork_run_child);
__run_fork_handlers (atfork_run_child, multiple_threads);
}
else
{
@@ -149,7 +149,7 @@ __libc_fork (void)
}
/* Run the handlers registered for the parent. */
__run_fork_handlers (atfork_run_parent);
__run_fork_handlers (atfork_run_parent, multiple_threads);
}
return pid;
+5 -3
View File
@@ -52,9 +52,11 @@ enum __run_fork_handler_type
- atfork_run_child: run all the CHILD_HANDLER and unlocks the internal
lock.
- atfork_run_parent: run all the PARENT_HANDLER and unlocks the internal
lock. */
extern void __run_fork_handlers (enum __run_fork_handler_type who)
attribute_hidden;
lock.
Perform locking only if DO_LOCKING. */
extern void __run_fork_handlers (enum __run_fork_handler_type who,
_Bool do_locking) attribute_hidden;
/* C library side function to register new fork handlers. */
extern int __register_atfork (void (*__prepare) (void),
+4
View File
@@ -71,7 +71,11 @@
#define gai_start_notify_thread __gai_start_notify_thread
/* For some reason, with clang this define causes a linktime failure
building libanl.so. */
#ifndef __clang__
#define gai_create_helper_thread __gai_create_helper_thread
#endif
extern inline void
__gai_start_notify_thread (void)
+1 -1
View File
@@ -225,7 +225,7 @@ _dl_procinfo (unsigned int type, unsigned long int word)
break;
}
default:
/* This should not happen. */
/* Fallback to generic output mechanism. */
return -1;
}
_dl_printf ("\n");
+9 -1
View File
@@ -684,7 +684,11 @@ elf_machine_rela (struct link_map *map,
const Elf64_Sym *sym,
const struct r_found_version *version,
void *const reloc_addr_arg,
int skip_ifunc)
int skip_ifunc
#ifndef NESTING
, struct link_map *boot_map
#endif
)
{
Elf64_Addr *const reloc_addr = reloc_addr_arg;
const int r_type = ELF64_R_TYPE (reloc->r_info);
@@ -707,7 +711,11 @@ elf_machine_rela (struct link_map *map,
/* We need SYM_MAP even in the absence of TLS, for elf_machine_fixup_plt
and STT_GNU_IFUNC. */
#if !defined NESTING && defined RTLD_BOOTSTRAP
struct link_map *sym_map = boot_map;
#else
struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
#endif
Elf64_Addr value = SYMBOL_ADDRESS (sym_map, sym, true) + reloc->r_addend;
if (sym != NULL
+2 -1
View File
@@ -57,7 +57,8 @@ enum
};
#define HWCAP_IMPORTANT (HWCAP_S390_ZARCH | HWCAP_S390_LDISP \
| HWCAP_S390_EIMM | HWCAP_S390_DFP)
| HWCAP_S390_EIMM | HWCAP_S390_DFP \
| HWCAP_S390_VX | HWCAP_S390_VXE)
/* We cannot provide a general printing function. */
#define _dl_procinfo(type, word) -1
+2 -2
View File
@@ -31,8 +31,8 @@ _dl_procinfo (unsigned int type, unsigned long int word)
{
int i;
/* Fallback to unknown output mechanism. */
if (type == AT_HWCAP2)
/* Fallback to generic output mechanism. */
if (type != AT_HWCAP)
return -1;
_dl_printf ("AT_HWCAP: ");
+1 -1
View File
@@ -67,7 +67,7 @@ _dl_procinfo (unsigned int type, unsigned long int word)
break;
}
default:
/* This should not happen. */
/* Fallback to generic output mechanism. */
return -1;
}
_dl_printf ("\n");
+2 -2
View File
@@ -30,8 +30,8 @@ _dl_procinfo (unsigned int type, unsigned long int word)
in the kernel sources. */
int i;
/* Fallback to unknown output mechanism. */
if (type == AT_HWCAP2)
/* Fallback to generic output mechanism. */
if (type != AT_HWCAP)
return -1;
_dl_printf ("AT_HWCAP: ");
+7
View File
@@ -49,6 +49,13 @@ __typeof (__write) __write_nocancel;
/* Uncancelable close. */
__typeof (__close) __close_nocancel;
#ifdef __clang__
/* We need the hidden proto to be ahead of its use. */
#if IS_IN (libc) || IS_IN (rtld)
hidden_proto (__close_nocancel)
#endif
#endif
/* Non cancellable close syscall that does not also set errno in case of
failure. */
static inline void
+2 -2
View File
@@ -32,8 +32,8 @@ _dl_procinfo (unsigned int type, unsigned long int word)
in the kernel sources. */
int i;
/* Fallback to unknown output mechanism. */
if (type == AT_HWCAP2)
/* Fallback to generic output mechanism. */
if (type != AT_HWCAP)
return -1;
_dl_printf ("AT_HWCAP: ");
+2 -1
View File
@@ -18,7 +18,8 @@
#include <sys/time.h>
#ifdef SHARED
/* Clang ifunc support works, but differently enough that this code breaks. */
#if defined(SHARED) && !defined(__clang__)
# include <dl-vdso.h>
# include <errno.h>
+4 -1
View File
@@ -18,7 +18,8 @@
#include <time.h>
#ifdef SHARED
/* Clang ifunc support works, but differently enough that this code breaks. */
#if defined(SHARED) && !defined(__clang__)
#include <dl-vdso.h>
#include <errno.h>
@@ -57,3 +58,5 @@ time (time_t *t)
}
#endif
libc_hidden_weak (time)
+31
View File
@@ -21,6 +21,10 @@
#include <features.h>
#if 0 /* for macro expansion debugging */
#define capture(sym, val) extern int sym[val]
#endif
/* Defined to 1 if the current compiler invocation provides a
floating-point type with the IEEE 754 binary128 format, and this
glibc includes corresponding *f128 interfaces for it. The required
@@ -55,6 +59,11 @@
#ifndef __ASSEMBLER__
#if 0 /* for macro expansion debugging */
capture(i_have_float128, __HAVE_FLOAT128);
capture(i_have_distinct_float128, __HAVE_DISTINCT_FLOAT128);
#endif
/* Defined to concatenate the literal suffix to be used with _Float128
types, if __HAVE_FLOAT128 is 1. */
# if __HAVE_FLOAT128
@@ -83,9 +92,25 @@ typedef _Complex float __cfloat128 __attribute__ ((__mode__ (__TC__)));
/* The type _Float128 exists only since GCC 7.0. */
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
/* need a clang 5.0 case here? */
typedef __float128 _Float128;
# endif
#if defined __clang__
#if 0 /* clang 5.0 or less */
#define __builtin_huge_valf128() ((_Float128) __builtin_huge_val ())
#define __builtin_inff128() ((_Float128) __builtin_inf ())
#define __builtin_nanf128(x) ((_Float128) __builtin_nan (x))
#define __builtin_nansf128(x) ((_Float128) __builtin_nans (x))
#define __builtin_copysignf128(x,y) ((_Float128) __builtin_copysign ((double)(x),(double)(y)))
#define __builtin_fabsf128(x) ((_Float128) __builtin_fabs ((double)(x)))
#endif
#define __builtin_signbitf128(x) (__builtin_signbit (x))
#else /* GCC */
/* __builtin_huge_valf128 doesn't exist before GCC 7.0. */
# if !__GNUC_PREREQ (7, 0)
# define __builtin_huge_valf128() ((_Float128) __builtin_huge_val ())
@@ -112,8 +137,14 @@ typedef __float128 _Float128;
# define __builtin_signbitf128 __signbitf128
# endif
#endif /* clang or GCC */
# endif
#if !__HAVE_FLOAT128 && defined __clang__
typedef long double _Float128;
#endif
#endif /* !__ASSEMBLER__. */
#include <bits/floatn-common.h>
+3
View File
@@ -9,6 +9,9 @@ CFLAGS-test-fenv-sse.c += -msse2 -mfpmath=sse
CFLAGS-test-fenv-clear-sse.c += -msse2 -mfpmath=sse
CFLAGS-test-fenv-sse-2.c += -msse2 -mfpmath=sse
CFLAGS-test-flt-eval-method-387.c += -fexcess-precision=standard -mfpmath=387
ifeq ($(with-clang),yes)
CFLAGS-test-flt-eval-method-387.c += -mno-sse
endif
CFLAGS-test-flt-eval-method-sse.c += -fexcess-precision=standard -msse2 \
-mfpmath=sse
endif
+1 -1
View File
@@ -19,7 +19,7 @@
#ifndef X86_MATH_BARRIERS_H
#define X86_MATH_BARRIERS_H 1
#ifdef __SSE2_MATH__
#if defined(__SSE2_MATH__) && !defined(__clang__)
# define math_opt_barrier(x) \
({ __typeof(x) __x; \
if (sizeof (x) <= sizeof (double) \
+4 -1
View File
@@ -127,7 +127,10 @@ $(objpfx)tst-sse: $(objpfx)tst-ssemod.so
$(objpfx)tst-avx: $(objpfx)tst-avx-aux.o $(objpfx)tst-avxmod.so
$(objpfx)tst-avx512: $(objpfx)tst-avx512-aux.o $(objpfx)tst-avx512mod.so
AVX-CFLAGS=-mavx -mno-vzeroupper
AVX-CFLAGS = -mavx
ifneq ($(with-clang),yes)
AVX-CFLAGS += -mno-vzeroupper
endif
CFLAGS-tst-audit4-aux.c += $(AVX-CFLAGS)
CFLAGS-tst-auditmod4a.c += $(AVX-CFLAGS)
CFLAGS-tst-auditmod4b.c += $(AVX-CFLAGS)
+9 -1
View File
@@ -267,7 +267,11 @@ auto inline void
__attribute__ ((always_inline))
elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
const ElfW(Sym) *sym, const struct r_found_version *version,
void *const reloc_addr_arg, int skip_ifunc)
void *const reloc_addr_arg, int skip_ifunc
#ifndef NESTING
, struct link_map *boot_map
#endif
)
{
ElfW(Addr) *const reloc_addr = reloc_addr_arg;
const unsigned long int r_type = ELFW(R_TYPE) (reloc->r_info);
@@ -305,7 +309,11 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
# ifndef RTLD_BOOTSTRAP
const ElfW(Sym) *const refsym = sym;
# endif
#if !defined NESTING && defined RTLD_BOOTSTRAP
struct link_map *sym_map = boot_map;
#else
struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
#endif
ElfW(Addr) value = SYMBOL_ADDRESS (sym_map, sym, true);
if (sym != NULL
+2 -1
View File
@@ -45,7 +45,8 @@
#ifdef __ILP32__
# define PRESERVE_BND_REGS_PREFIX
#else
# ifdef HAVE_MPX_SUPPORT
/* clang integrated assembler does not like "bnd" by itself on a line. */
# if defined(HAVE_MPX_SUPPORT) && !defined(__clang__)
# define PRESERVE_BND_REGS_PREFIX bnd
# else
# define PRESERVE_BND_REGS_PREFIX .byte 0xf2
+6
View File
@@ -17,7 +17,13 @@ RCSID("$NetBSD: s_log1p.S,v 1.7 1995/05/09 00:10:58 jtc Exp $")
-1 + sqrt(2) / 2 <= x <= 1 - sqrt(2) / 2
0.29 is a safe value.
*/
#if defined(__clang__)
/* Necessary in the absence of a .tfloat directive in the assembler. */
limit:
.byte 0xe1, 0x7a, 0x14, 0xae, 0x47, 0xe1, 0x7a, 0x94, 0xfd, 0x3f
#else
limit: .tfloat 0.29
#endif
/* Please note: we use a double value here. Since 1.0 has
an exact representation this does not effect the accuracy
but it helps to optimize the code. */
+3
View File
@@ -29,9 +29,12 @@
__svml_dexp_data:
/* Lookup table of 2^(j/2^K): */
/* clang integrated assembler doesn't think subtract yields an absolute, skip. */
#if !defined(__clang__)
.if .-__svml_dexp_data != __dbT
.err
.endif
#endif
.quad 0x3ff0000000000000
.quad 0x3ff002c605e2e8cf
.quad 0x3ff0058c86da1c0a
+6
View File
@@ -32,18 +32,24 @@
#define __iDomainRange 8768
.macro double_vector offset value
/* clang integrated assembler doesn't think subtract yields an absolute, skip. */
#if !defined(__clang__)
.if .-__svml_dexp_data != \offset
.err
.endif
#endif
.rept 8
.quad \value
.endr
.endm
.macro float_vector offset value
/* clang integrated assembler doesn't think subtract yields an absolute, skip. */
#if !defined(__clang__)
.if .-__svml_dexp_data != \offset
.err
.endif
#endif
.rept 16
.long \value
.endr
+15
View File
@@ -30,9 +30,12 @@ __svml_dlog_data:
/* Lookup table in high+low parts and 9-bit index for
-log(mRcp), where mRcp is mantissa of 1/x 9-bit accurate reciprocal: */
/* clang integrated assembler doesn't think subtract yields an absolute, skip. */
#if !defined(__clang__)
.if .-__svml_dlog_data != _Log_HA_table
.err
.endif
#endif
.quad 0xc086232bdd7a8300
.quad 0xbe1ce91eef3fb100
.quad 0xc086232fdc7ad828
@@ -1066,9 +1069,12 @@ __svml_dlog_data:
/* Lookup table with 9-bit index for
-log(mRcp), where mRcp is mantissa of 1/x 9-bit accurate reciprocal:
*/
/* clang integrated assembler doesn't think subtract yields an absolute, skip. */
#if !defined(__clang__)
.if .-__svml_dlog_data != _Log_LA_table
.err
.endif
#endif
.quad 0x8000000000000000
.quad 0xbf5ff802a9ab10e6
.quad 0xbf6ff00aa2b10bc0
@@ -1630,9 +1636,12 @@ double_vector _L2 0x3fe62e42fefa39ef
/* General purpose constants:
DP infinities, +/- */
/* clang integrated assembler doesn't think subtract yields an absolute, skip. */
#if !defined(__clang__)
.if .-__svml_dlog_data != _dInfs
.err
.endif
#endif
.quad 0x7ff0000000000000
.quad 0xfff0000000000000
.rept 48
@@ -1640,9 +1649,12 @@ double_vector _L2 0x3fe62e42fefa39ef
.endr
/* DP 1.0, +/- */
/* clang integrated assembler doesn't think subtract yields an absolute, skip. */
#if !defined(__clang__)
.if .-__svml_dlog_data != _dOnes
.err
.endif
#endif
.quad 0x3ff0000000000000
.quad 0xbff0000000000000
.rept 48
@@ -1650,9 +1662,12 @@ double_vector _L2 0x3fe62e42fefa39ef
.endr
/* DP 0.0, +/- */
/* clang integrated assembler doesn't think subtract yields an absolute, skip. */
#if !defined(__clang__)
.if .-__svml_dlog_data != _dZeros
.err
.endif
#endif
.quad 0x0000000000000000
.quad 0x8000000000000000
.rept 48
+3
View File
@@ -43,9 +43,12 @@
#define _dZeros 13568
.macro double_vector offset value
/* clang integrated assembler doesn't think subtract yields an absolute, skip. */
#if !defined(__clang__)
.if .-__svml_dlog_data != \offset
.err
.endif
#endif
.rept 8
.quad \value
.endr
+15
View File
@@ -30,9 +30,12 @@
__svml_dpow_data:
/* Lookup log(2) table (for HSW): */
/* clang integrated assembler doesn't think subtract yields an absolute, skip. */
#if !defined(__clang__)
.if .-__svml_dpow_data != _hsw_log2_table
.err
.endif
#endif
.quad 0xc08ff00000000000
.quad 0x0000000000000000
.quad 0xc08ff005c3e0ffc2
@@ -1064,9 +1067,12 @@ __svml_dpow_data:
.endr
/* Lookup exp(2) table (for HSW): */
/* clang integrated assembler doesn't think subtract yields an absolute, skip. */
#if !defined(__clang__)
.if .-__svml_dpow_data != _hsw_dTe
.err
.endif
#endif
.quad 0x3ff0000000000000
.quad 0x3ff00b1afa5abcbf
.quad 0x3ff0163da9fb3335
@@ -1395,9 +1401,12 @@ double_vector _hsw_dce2 0x3fcebfbdff82c54d
double_vector _hsw_dce1 0x3fe62e42fefa39b9
/* Reciprocal lookup table for log part (non HSW): */
/* clang integrated assembler doesn't think subtract yields an absolute, skip. */
#if !defined(__clang__)
.if .-__svml_dpow_data != _rcp_t1
.err
.endif
#endif
.quad 0x3ff7154740000000
.quad 0x3ff70f8340000000
.quad 0x3ff709c240000000
@@ -2429,9 +2438,12 @@ double_vector _hsw_dce1 0x3fe62e42fefa39b9
.endr
/* Log(2) lookup table for log part (non HSW): */
/* clang integrated assembler doesn't think subtract yields an absolute, skip. */
#if !defined(__clang__)
.if .-__svml_dpow_data != _log2_t1
.err
.endif
#endif
.rept 2
.quad 0x0000000000000000
.endr
@@ -4489,9 +4501,12 @@ double_vector _hsw_dce1 0x3fe62e42fefa39b9
.endr
/* Exp(2) lookup table for exp part (non HSW) */
/* clang integrated assembler doesn't think subtract yields an absolute, skip. */
#if !defined(__clang__)
.if .-__svml_dpow_data != _exp2_tbl
.err
.endif
#endif
.quad 0x3ff0000000000000
.quad 0x0000000000000000
.quad 0x3ff0163da9fb3335
+6
View File
@@ -84,18 +84,24 @@
#define _jIndexMask 40704
.macro double_vector offset value
/* clang integrated assembler doesn't think subtract yields an absolute, skip. */
#if !defined(__clang__)
.if .-__svml_dpow_data != \offset
.err
.endif
#endif
.rept 8
.quad \value
.endr
.endm
.macro float_vector offset value
/* clang integrated assembler doesn't think subtract yields an absolute, skip. */
#if !defined(__clang__)
.if .-__svml_dpow_data != \offset
.err
.endif
#endif
.rept 16
.long \value
.endr
+3
View File
@@ -61,9 +61,12 @@
#define __dSignMask __lNZero
.macro double_vector offset value
/* clang integrated assembler doesn't think subtract yields an absolute, skip. */
#if !defined(__clang__)
.if .-__svml_d_trig_data != \offset
.err
.endif
#endif
.rept 8
.quad \value
.endr
+3
View File
@@ -34,9 +34,12 @@
#define __iDomainRange 768
.macro float_vector offset value
/* clang integrated assembler doesn't think subtract yields an absolute, skip. */
#if !defined(__clang__)
.if .-__svml_sexp_data != \offset
.err
.endif
#endif
.rept 16
.long \value
.endr
+9
View File
@@ -70,9 +70,12 @@ float_vector _sOne 0x3f800000
float_vector _sLn2 0x3f317218
/* SP infinity, +/- */
/* clang integrated assembler doesn't think subtract yields an absolute, skip. */
#if !defined(__clang__)
.if .-__svml_slog_data != _sInfs
.err
.endif
#endif
.long 0x7f800000
.long 0xff800000
.rept 56
@@ -80,9 +83,12 @@ float_vector _sLn2 0x3f317218
.endr
/* SP one, +/- */
/* clang integrated assembler doesn't think subtract yields an absolute, skip. */
#if !defined(__clang__)
.if .-__svml_slog_data != _sOnes
.err
.endif
#endif
.long 0x3f800000
.long 0xbf800000
.rept 56
@@ -90,9 +96,12 @@ float_vector _sLn2 0x3f317218
.endr
/* SP zero +/- */
/* clang integrated assembler doesn't think subtract yields an absolute, skip. */
#if !defined(__clang__)
.if .-__svml_slog_data != _sZeros
.err
.endif
#endif
.long 0x00000000
.long 0x80000000
.rept 56
+3
View File
@@ -37,9 +37,12 @@
#define _sZeros 960
.macro float_vector offset value
/* clang integrated assembler doesn't think subtract yields an absolute, skip. */
#if !defined(__clang__)
.if .-__svml_slog_data != \offset
.err
.endif
#endif
.rept 16
.long \value
.endr
+18
View File
@@ -46,9 +46,12 @@ float_vector _ABSMASK 0x7fffffff
float_vector _DOMAINRANGE 0x42ae9a00
/* Log(2) lookup High+Low table for logarithmic part */
/* clang integrated assembler doesn't think subtract yields an absolute, skip. */
#if !defined(__clang__)
.if .-__svml_spow_data != _Log_HA_table
.err
.endif
#endif
.quad 0xc086232bdd7a8300
.quad 0xbe1ce91eef3fb100
.quad 0xc086232fdc7ad828
@@ -1080,9 +1083,12 @@ float_vector _DOMAINRANGE 0x42ae9a00
.endr
/* Log(2) lookup table for logarithmic part */
/* clang integrated assembler doesn't think subtract yields an absolute, skip. */
#if !defined(__clang__)
.if .-__svml_spow_data != _Log_LA_table
.err
.endif
#endif
.quad 0x8000000000000000
.quad 0xbf5ff802a9ab10e6
.quad 0xbf6ff00aa2b10bc0
@@ -1650,9 +1656,12 @@ double_vector _Bias1 0x408ff00000000000
double_vector _L2 0x3fe62e42fefa39ef
/* dInfs = DP infinity, +/- == */
/* clang integrated assembler doesn't think subtract yields an absolute, skip. */
#if !defined(__clang__)
.if .-__svml_spow_data != _dInfs
.err
.endif
#endif
.quad 0x7ff0000000000000
.quad 0xfff0000000000000
.rept 48
@@ -1660,9 +1669,12 @@ double_vector _L2 0x3fe62e42fefa39ef
.endr
/* dOnes = DP one, +/- == */
/* clang integrated assembler doesn't think subtract yields an absolute, skip. */
#if !defined(__clang__)
.if .-__svml_spow_data != _dOnes
.err
.endif
#endif
.quad 0x3ff0000000000000
.quad 0xbff0000000000000
.rept 48
@@ -1670,17 +1682,23 @@ double_vector _L2 0x3fe62e42fefa39ef
.endr
/* dZeros = DP zero +/- == */
/* clang integrated assembler doesn't think subtract yields an absolute, skip. */
#if !defined(__clang__)
.if .-__svml_spow_data != _dZeros
.err
.endif
#endif
.quad 0x0000000000000000
.quad 0x8000000000000000
.rept 48
.byte 0
.endr
/* clang integrated assembler doesn't think subtract yields an absolute, skip. */
#if !defined(__clang__)
.if .-__svml_spow_data != __dbT
.err
.endif
#endif
.quad 0x3feffffffc27dd9e
.quad 0x3ff00162f1a4047d
.quad 0x3ff002c603f68252
+6
View File
@@ -56,18 +56,24 @@
#define __iDomainRange 30784
.macro double_vector offset value
/* clang integrated assembler doesn't think subtract yields an absolute, skip. */
#if !defined(__clang__)
.if .-__svml_spow_data != \offset
.err
.endif
#endif
.rept 8
.quad \value
.endr
.endm
.macro float_vector offset value
/* clang integrated assembler doesn't think subtract yields an absolute, skip. */
#if !defined(__clang__)
.if .-__svml_spow_data != \offset
.err
.endif
#endif
.rept 16
.long \value
.endr
+3
View File
@@ -20,9 +20,12 @@
#define S_TRIG_DATA_H
.macro float_vector offset value
/* clang integrated assembler doesn't think subtract yields an absolute, skip. */
#if !defined(__clang__)
.if .-__svml_s_trig_data != \offset
.err
.endif
#endif
.rept 16
.long \value
.endr
+12 -8
View File
@@ -21,14 +21,18 @@
.text
ENTRY (memcmp)
test %rdx, %rdx
#ifdef __ILP32__
/* Clear the upper 32 bits. */
movl %edx, %edx
#endif
test %RDX_LP, %RDX_LP
jz L(finz)
cmpq $1, %rdx
jle L(finr1b)
jbe L(finr1b)
subq %rdi, %rsi
movq %rdx, %r10
cmpq $32, %r10
jge L(gt32)
jae L(gt32)
/* Handle small chunks and last block of less than 32 bytes. */
L(small):
testq $1, %r10
@@ -156,7 +160,7 @@ L(A32):
movq %r11, %r10
andq $-32, %r10
cmpq %r10, %rdi
jge L(mt16)
jae L(mt16)
/* Pre-unroll to be ready for unrolled 64B loop. */
testq $32, %rdi
jz L(A64)
@@ -178,7 +182,7 @@ L(A64):
movq %r11, %r10
andq $-64, %r10
cmpq %r10, %rdi
jge L(mt32)
jae L(mt32)
L(A64main):
movdqu (%rdi,%rsi), %xmm0
@@ -216,7 +220,7 @@ L(mt32):
movq %r11, %r10
andq $-32, %r10
cmpq %r10, %rdi
jge L(mt16)
jae L(mt16)
L(A32main):
movdqu (%rdi,%rsi), %xmm0
@@ -254,7 +258,7 @@ L(ATR):
movq %r11, %r10
andq $-32, %r10
cmpq %r10, %rdi
jge L(mt16)
jae L(mt16)
testq $16, %rdi
jz L(ATR32)
@@ -325,7 +329,7 @@ L(ATR64main):
movq %r11, %r10
andq $-32, %r10
cmpq %r10, %rdi
jge L(mt16)
jae L(mt16)
L(ATR32res):
movdqa (%rdi,%rsi), %xmm0
+3 -2
View File
@@ -2232,8 +2232,9 @@ LABEL(strcmp_exitz):
.p2align 4
LABEL(Byte0):
movzx (%rsi), %ecx
movzx (%rdi), %eax
# Clang assembler objects to movzx here.
movzbl (%rsi), %ecx
movzbl (%rdi), %eax
#if defined USE_AS_STRCASECMP_L || defined USE_AS_STRNCASECMP_L
leaq _nl_C_LC_CTYPE_tolower+128*4(%rip), %rdx
+2 -1
View File
@@ -8,7 +8,8 @@ endif
ifeq ($(subdir),string)
tests += tst-size_t-memchr tst-size_t-memcmp tst-size_t-memcpy \
tst-size_t-memrchr tst-size_t-memset tst-size_t-strncasecmp \
tst-size_t-strncmp tst-size_t-strncpy tst-size_t-strnlen
tst-size_t-strncmp tst-size_t-strncpy tst-size_t-strnlen \
tst-size_t-memcmp-2
endif
ifeq ($(subdir),wcsmbs)
+79
View File
@@ -0,0 +1,79 @@
/* Test memcmp with size_t in the lower 32 bits of 64-bit register.
Copyright (C) 2019 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
<http://www.gnu.org/licenses/>. */
#define TEST_MAIN
#ifdef WIDE
# define TEST_NAME "wmemcmp"
#else
# define TEST_NAME "memcmp"
#endif
#include "test-size_t.h"
#ifdef WIDE
# include <inttypes.h>
# include <wchar.h>
# define MEMCMP wmemcmp
# define CHAR wchar_t
#else
# define MEMCMP memcmp
# define CHAR char
#endif
IMPL (MEMCMP, 1)
typedef int (*proto_t) (const CHAR *, const CHAR *, size_t);
static int
__attribute__ ((noinline, noclone))
do_memcmp (parameter_t a, parameter_t b)
{
return CALL (&b, a.p, b.p, a.len);
}
static int
test_main (void)
{
test_init ();
parameter_t dest = { { page_size / sizeof (CHAR) }, buf1 };
parameter_t src = { { 0 }, buf2 };
memcpy (buf1, buf2, page_size);
CHAR *p = (CHAR *) buf1;
p[page_size / sizeof (CHAR) - 1] = (CHAR) 1;
int ret = 0;
FOR_EACH_IMPL (impl, 0)
{
src.fn = impl->fn;
int res = do_memcmp (dest, src);
if (res >= 0)
{
error (0, 0, "Wrong result in function %s: %i >= 0",
impl->name, res);
ret = 1;
}
}
return ret ? EXIT_FAILURE : EXIT_SUCCESS;
}
#include <support/test-driver.c>