Commit 8f2469e4 authored by Timo Teräs's avatar Timo Teräs

main/musl: cherry-pick fixes and compatibility improvements from upstream

parent 7086cc9b
From dc95322e18615392eea69de355edd735a15a8f36 Mon Sep 17 00:00:00 2001
From: Rich Felker <dalias@aerifal.cx>
Date: Mon, 20 Oct 2014 00:22:51 -0400
Subject: [PATCH] manually "shrink wrap" fast path in pthread_once
this change is a workaround for the inability of current compilers to
perform "shrink wrapping" optimizations. in casual testing, it roughly
doubled the performance of pthread_once when called on an
already-finished once control object.
---
src/thread/pthread_once.c | 20 ++++++++++++--------
1 file changed, 12 insertions(+), 8 deletions(-)
diff --git a/src/thread/pthread_once.c b/src/thread/pthread_once.c
index 7c47385..df655ef 100644
--- a/src/thread/pthread_once.c
+++ b/src/thread/pthread_once.c
@@ -8,15 +8,8 @@ static void undo(void *control)
__wake(control, -1, 1);
}
-int __pthread_once(pthread_once_t *control, void (*init)(void))
+int __pthread_once_full(pthread_once_t *control, void (*init)(void))
{
- /* Return immediately if init finished before, but ensure that
- * effects of the init routine are visible to the caller. */
- if (*control == 2) {
- a_barrier();
- return 0;
- }
-
/* Try to enter initializing state. Four possibilities:
* 0 - we're the first or the other cancelled; run init
* 1 - another thread is running init; wait
@@ -43,4 +36,15 @@ int __pthread_once(pthread_once_t *control, void (*init)(void))
}
}
+int __pthread_once(pthread_once_t *control, void (*init)(void))
+{
+ /* Return immediately if init finished before, but ensure that
+ * effects of the init routine are visible to the caller. */
+ if (*control == 2) {
+ a_barrier();
+ return 0;
+ }
+ return __pthread_once_full(control, init);
+}
+
weak_alias(__pthread_once, pthread_once);
--
2.2.0
From 9d836ea7a69a6441fcdca815328d274e4ed6b707 Mon Sep 17 00:00:00 2001
From: Rich Felker <dalias@aerifal.cx>
Date: Thu, 30 Oct 2014 20:03:56 -0400
Subject: [PATCH] fix failure of open to read variadic mode argument for
O_TMPFILE
---
src/fcntl/open.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/fcntl/open.c b/src/fcntl/open.c
index 5e5be1d..3928a6e 100644
--- a/src/fcntl/open.c
+++ b/src/fcntl/open.c
@@ -7,7 +7,7 @@ int open(const char *filename, int flags, ...)
{
mode_t mode = 0;
- if (flags & O_CREAT) {
+ if ((flags & O_CREAT) || (flags & O_TMPFILE) == O_TMPFILE) {
va_list ap;
va_start(ap, flags);
mode = va_arg(ap, mode_t);
--
2.2.0
From 2da3ab1382ca8e39eb1e4428103764a81fba73d3 Mon Sep 17 00:00:00 2001
From: Rich Felker <dalias@aerifal.cx>
Date: Thu, 30 Oct 2014 20:08:40 -0400
Subject: [PATCH] fix invalid access by openat to possibly-missing variadic
mode argument
the mode argument is only required to be present when the O_CREAT or
O_TMPFILE flag is used.
---
src/fcntl/openat.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/src/fcntl/openat.c b/src/fcntl/openat.c
index 634c4bf..4faeb29 100644
--- a/src/fcntl/openat.c
+++ b/src/fcntl/openat.c
@@ -6,10 +6,14 @@
int openat(int fd, const char *filename, int flags, ...)
{
mode_t mode;
- va_list ap;
- va_start(ap, flags);
- mode = va_arg(ap, mode_t);
- va_end(ap);
+
+ if ((flags & O_CREAT) || (flags & O_TMPFILE) == O_TMPFILE) {
+ va_list ap;
+ va_start(ap, flags);
+ mode = va_arg(ap, mode_t);
+ va_end(ap);
+ }
+
return syscall_cp(SYS_openat, fd, filename, flags|O_LARGEFILE, mode);
}
--
2.2.0
From e146e6035fecea080fb17450db3c8bb44d36e07d Mon Sep 17 00:00:00 2001
From: Rich Felker <dalias@aerifal.cx>
Date: Fri, 31 Oct 2014 15:35:24 -0400
Subject: [PATCH] fix uninitialized mode variable in openat function
this was introduced in commit 2da3ab1382ca8e39eb1e4428103764a81fba73d3
as an oversight while making the variadic argument access conditional.
---
src/fcntl/openat.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/fcntl/openat.c b/src/fcntl/openat.c
index 4faeb29..e741336 100644
--- a/src/fcntl/openat.c
+++ b/src/fcntl/openat.c
@@ -5,7 +5,7 @@
int openat(int fd, const char *filename, int flags, ...)
{
- mode_t mode;
+ mode_t mode = 0;
if ((flags & O_CREAT) || (flags & O_TMPFILE) == O_TMPFILE) {
va_list ap;
--
2.2.0
From a732e80d33b4fd6f510f7cec4f5573ef5d89bc4e Mon Sep 17 00:00:00 2001
From: Szabolcs Nagy <nsz@port70.net>
Date: Wed, 5 Nov 2014 21:40:29 +0100
Subject: [PATCH] math: fix x86_64 and x32 asm not to use sahf instruction
Some early x86_64 cpus (released before 2006) did not support sahf/lahf
instructions so they should be avoided (intel manual says they are only
supported if CPUID.80000001H:ECX.LAHF-SAHF[bit 0] = 1).
The workaround simplifies exp2l and expm1l because fucomip can be
used instead of the fucomp;fnstsw;sahf sequence copied from i386.
In fmodl and remainderl sahf is replaced by a simple bit test.
---
src/math/x32/exp2l.s | 13 +++----------
src/math/x32/fmodl.s | 4 ++--
src/math/x32/remainderl.s | 4 ++--
src/math/x86_64/exp2l.s | 13 +++----------
src/math/x86_64/fmodl.s | 4 ++--
src/math/x86_64/remainderl.s | 4 ++--
6 files changed, 14 insertions(+), 28 deletions(-)
diff --git a/src/math/x32/exp2l.s b/src/math/x32/exp2l.s
index d9f4d6e..dfb2bc7 100644
--- a/src/math/x32/exp2l.s
+++ b/src/math/x32/exp2l.s
@@ -6,9 +6,7 @@ expm1l:
fmulp
movl $0xc2820000,-4(%esp)
flds -4(%esp)
- fucomp %st(1)
- fnstsw %ax
- sahf
+ fucomip %st(1)
fld1
jb 1f
# x*log2e <= -65, return -1 without underflow
@@ -17,11 +15,8 @@ expm1l:
ret
1: fld %st(1)
fabs
- fucom %st(1)
- fnstsw %ax
+ fucomip %st(1)
fstp %st(0)
- fstp %st(0)
- sahf
ja 1f
f2xm1
ret
@@ -53,9 +48,7 @@ exp2l:
fld %st(1)
fsub %st(1)
faddp
- fucomp %st(1)
- fnstsw
- sahf
+ fucomip %st(1)
je 2f # x - 0x1p63 + 0x1p63 == x
movl $1,(%esp)
flds (%esp) # 0x1p-149
diff --git a/src/math/x32/fmodl.s b/src/math/x32/fmodl.s
index 9e4378a..b951320 100644
--- a/src/math/x32/fmodl.s
+++ b/src/math/x32/fmodl.s
@@ -5,7 +5,7 @@ fmodl:
fldt 8(%esp)
1: fprem
fstsw %ax
- sahf
- jp 1b
+ testb $4,%ah
+ jnz 1b
fstp %st(1)
ret
diff --git a/src/math/x32/remainderl.s b/src/math/x32/remainderl.s
index c97f68a..79bf4fe 100644
--- a/src/math/x32/remainderl.s
+++ b/src/math/x32/remainderl.s
@@ -5,7 +5,7 @@ remainderl:
fldt 8(%esp)
1: fprem1
fstsw %ax
- sahf
- jp 1b
+ testb $4,%ah
+ jnz 1b
fstp %st(1)
ret
diff --git a/src/math/x86_64/exp2l.s b/src/math/x86_64/exp2l.s
index 0d6cd56..0e9bdf9 100644
--- a/src/math/x86_64/exp2l.s
+++ b/src/math/x86_64/exp2l.s
@@ -6,9 +6,7 @@ expm1l:
fmulp
movl $0xc2820000,-4(%rsp)
flds -4(%rsp)
- fucomp %st(1)
- fnstsw %ax
- sahf
+ fucomip %st(1)
fld1
jb 1f
# x*log2e <= -65, return -1 without underflow
@@ -17,11 +15,8 @@ expm1l:
ret
1: fld %st(1)
fabs
- fucom %st(1)
- fnstsw %ax
+ fucomip %st(1)
fstp %st(0)
- fstp %st(0)
- sahf
ja 1f
f2xm1
ret
@@ -53,9 +48,7 @@ exp2l:
fld %st(1)
fsub %st(1)
faddp
- fucomp %st(1)
- fnstsw
- sahf
+ fucomip %st(1)
je 2f # x - 0x1p63 + 0x1p63 == x
movl $1,(%rsp)
flds (%rsp) # 0x1p-149
diff --git a/src/math/x86_64/fmodl.s b/src/math/x86_64/fmodl.s
index ca81e60..cd8d2b7 100644
--- a/src/math/x86_64/fmodl.s
+++ b/src/math/x86_64/fmodl.s
@@ -5,7 +5,7 @@ fmodl:
fldt 8(%rsp)
1: fprem
fstsw %ax
- sahf
- jp 1b
+ testb $4,%ah
+ jnz 1b
fstp %st(1)
ret
diff --git a/src/math/x86_64/remainderl.s b/src/math/x86_64/remainderl.s
index 75c1237..2c337cf 100644
--- a/src/math/x86_64/remainderl.s
+++ b/src/math/x86_64/remainderl.s
@@ -5,7 +5,7 @@ remainderl:
fldt 8(%rsp)
1: fprem1
fstsw %ax
- sahf
- jp 1b
+ testb $4,%ah
+ jnz 1b
fstp %st(1)
ret
--
2.2.0
From ec4318943a26d4bd4050481d11709853184f2794 Mon Sep 17 00:00:00 2001
From: Szabolcs Nagy <nsz@port70.net>
Date: Wed, 5 Nov 2014 22:13:58 +0100
Subject: [PATCH] math: use fnstsw consistently instead of fstsw in x87 asm
fnstsw does not wait for pending unmasked x87 floating-point exceptions
and it is the same as fstsw when all exceptions are masked which is the
only environment libc supports.
---
src/math/i386/fmod.s | 2 +-
src/math/i386/fmodf.s | 2 +-
src/math/i386/fmodl.s | 2 +-
src/math/i386/remainder.s | 2 +-
src/math/i386/remainderf.s | 2 +-
src/math/i386/remainderl.s | 2 +-
src/math/i386/sqrt.s | 2 +-
src/math/x32/fmodl.s | 2 +-
src/math/x32/remainderl.s | 2 +-
src/math/x86_64/fmodl.s | 2 +-
src/math/x86_64/remainderl.s | 2 +-
11 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/src/math/i386/fmod.s b/src/math/i386/fmod.s
index 069fbfe..2113b3c 100644
--- a/src/math/i386/fmod.s
+++ b/src/math/i386/fmod.s
@@ -4,7 +4,7 @@ fmod:
fldl 12(%esp)
fldl 4(%esp)
1: fprem
- fstsw %ax
+ fnstsw %ax
sahf
jp 1b
fstp %st(1)
diff --git a/src/math/i386/fmodf.s b/src/math/i386/fmodf.s
index d99c80f..e04e2a5 100644
--- a/src/math/i386/fmodf.s
+++ b/src/math/i386/fmodf.s
@@ -4,7 +4,7 @@ fmodf:
flds 8(%esp)
flds 4(%esp)
1: fprem
- fstsw %ax
+ fnstsw %ax
sahf
jp 1b
fstp %st(1)
diff --git a/src/math/i386/fmodl.s b/src/math/i386/fmodl.s
index 7e07e7b..0cb3fe9 100644
--- a/src/math/i386/fmodl.s
+++ b/src/math/i386/fmodl.s
@@ -4,7 +4,7 @@ fmodl:
fldt 16(%esp)
fldt 4(%esp)
1: fprem
- fstsw %ax
+ fnstsw %ax
sahf
jp 1b
fstp %st(1)
diff --git a/src/math/i386/remainder.s b/src/math/i386/remainder.s
index 7f4be05..ab1da95 100644
--- a/src/math/i386/remainder.s
+++ b/src/math/i386/remainder.s
@@ -7,7 +7,7 @@ drem:
fldl 12(%esp)
fldl 4(%esp)
1: fprem1
- fstsw %ax
+ fnstsw %ax
sahf
jp 1b
fstp %st(1)
diff --git a/src/math/i386/remainderf.s b/src/math/i386/remainderf.s
index ac6e367..6a7378a 100644
--- a/src/math/i386/remainderf.s
+++ b/src/math/i386/remainderf.s
@@ -7,7 +7,7 @@ dremf:
flds 8(%esp)
flds 4(%esp)
1: fprem1
- fstsw %ax
+ fnstsw %ax
sahf
jp 1b
fstp %st(1)
diff --git a/src/math/i386/remainderl.s b/src/math/i386/remainderl.s
index 0097872..b41518e 100644
--- a/src/math/i386/remainderl.s
+++ b/src/math/i386/remainderl.s
@@ -4,7 +4,7 @@ remainderl:
fldt 16(%esp)
fldt 4(%esp)
1: fprem1
- fstsw %ax
+ fnstsw %ax
sahf
jp 1b
fstp %st(1)
diff --git a/src/math/i386/sqrt.s b/src/math/i386/sqrt.s
index 8289d09..57837e2 100644
--- a/src/math/i386/sqrt.s
+++ b/src/math/i386/sqrt.s
@@ -2,7 +2,7 @@
.type sqrt,@function
sqrt: fldl 4(%esp)
fsqrt
- fstsw %ax
+ fnstsw %ax
sub $12,%esp
fld %st(0)
fstpt (%esp)
diff --git a/src/math/x32/fmodl.s b/src/math/x32/fmodl.s
index b951320..c3f790c 100644
--- a/src/math/x32/fmodl.s
+++ b/src/math/x32/fmodl.s
@@ -4,7 +4,7 @@ fmodl:
fldt 24(%esp)
fldt 8(%esp)
1: fprem
- fstsw %ax
+ fnstsw %ax
testb $4,%ah
jnz 1b
fstp %st(1)
diff --git a/src/math/x32/remainderl.s b/src/math/x32/remainderl.s
index 79bf4fe..376ba0e 100644
--- a/src/math/x32/remainderl.s
+++ b/src/math/x32/remainderl.s
@@ -4,7 +4,7 @@ remainderl:
fldt 24(%esp)
fldt 8(%esp)
1: fprem1
- fstsw %ax
+ fnstsw %ax
testb $4,%ah
jnz 1b
fstp %st(1)
diff --git a/src/math/x86_64/fmodl.s b/src/math/x86_64/fmodl.s
index cd8d2b7..ea07b40 100644
--- a/src/math/x86_64/fmodl.s
+++ b/src/math/x86_64/fmodl.s
@@ -4,7 +4,7 @@ fmodl:
fldt 24(%rsp)
fldt 8(%rsp)
1: fprem
- fstsw %ax
+ fnstsw %ax
testb $4,%ah
jnz 1b
fstp %st(1)
diff --git a/src/math/x86_64/remainderl.s b/src/math/x86_64/remainderl.s
index 2c337cf..cb3857b 100644
--- a/src/math/x86_64/remainderl.s
+++ b/src/math/x86_64/remainderl.s
@@ -4,7 +4,7 @@ remainderl:
fldt 24(%rsp)
fldt 8(%rsp)
1: fprem1
- fstsw %ax
+ fnstsw %ax
testb $4,%ah
jnz 1b
fstp %st(1)
--
2.2.0
From b91cdbe2bc8b626aa04dc6e3e84345accf34e4b1 Mon Sep 17 00:00:00 2001
From: Rich Felker <dalias@aerifal.cx>
Date: Sat, 15 Nov 2014 12:16:19 -0500
Subject: [PATCH] fix behavior of printf with alt-form octal, zero precision,
zero value
in this case there are two conflicting rules in play: that an explicit
precision of zero with the value zero produces no output, and that the
'#' modifier for octal increases the precision sufficiently to yield a
leading zero. ISO C (7.19.6.1 paragraph 6 in C99+TC3) includes a
parenthetical remark to clarify that the precision-increasing behavior
takes precedence, but the corresponding text in POSIX off of which I
based the implementation is missing this remark.
this issue was covered in WG14 DR#151.
---
src/stdio/vfprintf.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/stdio/vfprintf.c b/src/stdio/vfprintf.c
index ea25772..39c1e86 100644
--- a/src/stdio/vfprintf.c
+++ b/src/stdio/vfprintf.c
@@ -570,7 +570,7 @@ static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg,
if (0) {
case 'o':
a = fmt_o(arg.i, z);
- if ((fl&ALT_FORM) && arg.i) prefix+=5, pl=1;
+ if ((fl&ALT_FORM) && p<z-a+1) p=z-a+1;
} if (0) {
case 'd': case 'i':
pl=1;
--
2.2.0
From 941644e98c3d05761b4639a8ae5afacd8586d1b9 Mon Sep 17 00:00:00 2001
From: Jens Gustedt <Jens.Gustedt@inria.fr>
Date: Sun, 9 Nov 2014 11:18:08 +0100
Subject: [PATCH] implement a private state for the uchar.h functions
The C standard is imperative on that:
7.28.1 ... If ps is a null pointer, each function uses its own internal
mbstate_t object instead, which is initialized at program startup to
the initial conversion state;
and these functions are also not supposed to implicitly use the state of
the wchar.h functions:
7.29.6.3 ... The implementation behaves as if no library function calls
these functions with a null pointer for ps.
Previously this resulted in two bugs.
- The functions c16rtomb and mbrtoc16 would crash when called with ps
set to null.
- The function mbrtoc32 used the private state of mbrtowc, which it
is not allowed to do.
---
src/multibyte/c16rtomb.c | 2 ++
src/multibyte/mbrtoc16.c | 2 ++
src/multibyte/mbrtoc32.c | 2 ++
3 files changed, 6 insertions(+)
diff --git a/src/multibyte/c16rtomb.c b/src/multibyte/c16rtomb.c
index 2e8ec97..39ca375 100644
--- a/src/multibyte/c16rtomb.c
+++ b/src/multibyte/c16rtomb.c
@@ -4,6 +4,8 @@
size_t c16rtomb(char *restrict s, char16_t c16, mbstate_t *restrict ps)
{
+ static unsigned internal_state;
+ if (!ps) ps = (void *)&internal_state;
unsigned *x = (unsigned *)ps;
wchar_t wc;
diff --git a/src/multibyte/mbrtoc16.c b/src/multibyte/mbrtoc16.c
index 74b7d77..765ff90 100644
--- a/src/multibyte/mbrtoc16.c
+++ b/src/multibyte/mbrtoc16.c
@@ -3,6 +3,8 @@
size_t mbrtoc16(char16_t *restrict pc16, const char *restrict s, size_t n, mbstate_t *restrict ps)
{
+ static unsigned internal_state;
+ if (!ps) ps = (void *)&internal_state;
unsigned *pending = (unsigned *)ps;
if (!s) return mbrtoc16(0, "", 1, ps);
diff --git a/src/multibyte/mbrtoc32.c b/src/multibyte/mbrtoc32.c
index c6d2082..9b6b236 100644
--- a/src/multibyte/mbrtoc32.c
+++ b/src/multibyte/mbrtoc32.c
@@ -3,6 +3,8 @@
size_t mbrtoc32(char32_t *restrict pc32, const char *restrict s, size_t n, mbstate_t *restrict ps)
{
+ static unsigned internal_state;
+ if (!ps) ps = (void *)&internal_state;
if (!s) return mbrtoc32(0, "", 1, ps);
wchar_t wc;
size_t ret = mbrtowc(&wc, s, n, ps);
--
2.2.0
From acccc93e084641861ca553317edb7da7791833b5 Mon Sep 17 00:00:00 2001
From: Felix Fietkau <nbd@openwrt.org>
Date: Tue, 21 Oct 2014 22:24:50 +0200
Subject: [PATCH] getopt: fix optional argument processing
Processing an option character with optional argument fails if the
option is last on the command line. This happens because the
if (optind >= argc) check runs first before testing for optional
argument.
---
src/misc/getopt.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/misc/getopt.c b/src/misc/getopt.c
index 8a2e4d5..f94c4f7 100644
--- a/src/misc/getopt.c
+++ b/src/misc/getopt.c
@@ -55,7 +55,8 @@ int getopt(int argc, char * const argv[], const char *optstring)
return '?';
}
if (optstring[i+1] == ':') {
- if (optind >= argc) {
+ if (optstring[i+2] == ':') optarg = 0;
+ else if (optind >= argc) {
if (optstring[0] == ':') return ':';
if (opterr) {
write(2, argv[0], strlen(argv[0]));
@@ -65,7 +66,6 @@ int getopt(int argc, char * const argv[], const char *optstring)
}
return '?';
}
- if (optstring[i+2] == ':') optarg = 0;
if (optstring[i+2] != ':' || optpos) {
optarg = argv[optind++] + optpos;
optpos = 0;
--
2.2.0
From d8dc2b7c0289b12eeef4feff65e3c918111b0f55 Mon Sep 17 00:00:00 2001
From: Rich Felker <dalias@aerifal.cx>
Date: Sun, 23 Nov 2014 16:17:57 -0500
Subject: [PATCH] adapt dynamic linker for new binutils versions that omit
DT_RPATH
the new DT_RUNPATH semantics for search order are always used, and
since binutils had always set both DT_RPATH and DT_RUNPATH when the
latter was used, processing only DT_RPATH worked fine. however, recent
binutils has stopped generating DT_RPATH when DT_RUNPATH is used,
which broke support for this feature completely.
---
src/ldso/dynlink.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/ldso/dynlink.c b/src/ldso/dynlink.c
index 1de430c..00af886 100644
--- a/src/ldso/dynlink.c
+++ b/src/ldso/dynlink.c
@@ -645,6 +645,8 @@ static void decode_dyn(struct dso *p)
p->hashtab = (void *)(p->base + dyn[DT_HASH]);
if (dyn[0]&(1<<DT_RPATH))
p->rpath_orig = (void *)(p->strings + dyn[DT_RPATH]);
+ if (dyn[0]&(1<<DT_RUNPATH))
+ p->rpath_orig = (void *)(p->strings + dyn[DT_RUNPATH]);
if (search_vec(p->dynv, dyn, DT_GNU_HASH))
p->ghashtab = (void *)(p->base + *dyn);
if (search_vec(p->dynv, dyn, DT_VERSYM))
--
2.2.0
From b72cd07f176b876aa51864d93aa8101477b1d732 Mon Sep 17 00:00:00 2001
From: Gianluca Anzolin <gianluca@sottospazio.it>
Date: Tue, 25 Nov 2014 08:56:03 +0100
Subject: [PATCH] add support for non-option arguments extension to getopt
this is a GNU extension, activated by including '-' as the first
character of the options string, whereby non-option arguments are
processed as if they were arguments to an option character '\1' rather
than ending option processing.
---
src/misc/getopt.c | 17 ++++++++++++++++-
src/misc/getopt_long.c | 7 ++++---
2 files changed, 20 insertions(+), 4 deletions(-)
diff --git a/src/misc/getopt.c b/src/misc/getopt.c
index f94c4f7..a698c8d 100644
--- a/src/misc/getopt.c
+++ b/src/misc/getopt.c