summaryrefslogtreecommitdiff
path: root/system/musl
diff options
context:
space:
mode:
Diffstat (limited to 'system/musl')
-rw-r--r--system/musl/APKBUILD16
-rw-r--r--system/musl/amalgamation.patch244
-rw-r--r--system/musl/arm64-tls.patch116
-rw-r--r--system/musl/gettext-preserve-errno.patch28
-rw-r--r--system/musl/stdio.patch69
-rw-r--r--system/musl/strftime-add-l-support.patch25
6 files changed, 149 insertions, 349 deletions
diff --git a/system/musl/APKBUILD b/system/musl/APKBUILD
index dbb13a56f..1c30abdfb 100644
--- a/system/musl/APKBUILD
+++ b/system/musl/APKBUILD
@@ -1,7 +1,7 @@
# Maintainer: A. Wilcox <awilfox@adelielinux.org>
pkgname=musl
-pkgver=1.1.21
-pkgrel=4
+pkgver=1.1.22
+pkgrel=1
pkgdesc="System library (libc) implementation"
url="https://www.musl-libc.org/"
arch="all"
@@ -23,11 +23,11 @@ nolibc) ;;
esac
source="https://www.musl-libc.org/releases/musl-$pkgver.tar.gz
amalgamation.patch
+ arm64-tls.patch
3001-make-real-lastlog-h.patch
handle-aux-at_base.patch
fgetspent_r.patch
- gettext-preserve-errno.patch
- stdio.patch
+ strftime-add-l-support.patch
ldconfig
getent.c
@@ -120,13 +120,13 @@ utils() {
install -D -m755 "$srcdir"/ldconfig "$subpkgdir"/sbin
}
-sha512sums="fa6c4cc012626c5e517e0e10926fc845e3aa5f863ffaceeb38ac5b9ce0af631a37f6b94f470997db09aa0d5e03f4f28a2db83484b0f98481bea2239c1989d363 musl-1.1.21.tar.gz
-e2227bf201e13fc5a537bc47096dfa4d2ff45fc7ce5609a7c1d640e11215cf8a62d7652a4d17d25ab5c13406ef14fd4856397fc2056419fd1a83c8c37171fdc1 amalgamation.patch
+sha512sums="08a40d722672504427238e71c9e52a723c6a14735abe9581d6d4bb3f86662d5d51a3f32a6aed6420c1f9680e22a3a554a9b87ae342635be971e2db49cc9fdb87 musl-1.1.22.tar.gz
+8eadf9933e729e8a6d99f667257284eaf06cb0160b40e6307ed69159c03ba4ed3c67a2943c71b5abc258bbc6c9ff321a34aa55357ebb460be9363dd605e18144 amalgamation.patch
+a1127de160cbf820875d415f8fdda3c894e03748070070e282e1cf0604c883db3f8e1c311dd8c3f318ac8a158cb2183c757bcbbbd666b63676074bdec6a29983 arm64-tls.patch
88ae443dbb8e0a4368235bdc3a1c5c7b718495afa75e06deb8e01becc76cb1f0d6964589e2204fc749c9c1b3190b8b9ac1ae2c0099cab8e2ce3ec877103d4332 3001-make-real-lastlog-h.patch
6a7ff16d95b5d1be77e0a0fbb245491817db192176496a57b22ab037637d97a185ea0b0d19da687da66c2a2f5578e4343d230f399d49fe377d8f008410974238 handle-aux-at_base.patch
ded41235148930f8cf781538f7d63ecb0c65ea4e8ce792565f3649ee2523592a76b2a166785f0b145fc79f5852fd1fb1729a7a09110b3b8f85cba3912e790807 fgetspent_r.patch
-db180e437b8b7582e4d2baf06b592b88a9f6e5a8f18b7afa81d7a707240a774273778f8fec1c5cbea2a137e00cca49ff08fe762c871be20c70b50104b7e8e1e1 gettext-preserve-errno.patch
-14862273d0facbec042f444dfa477d1793b16b68e058bf7038f492cb6e3f3c278b1c3ea8bd89816e4e8b847ffd48ac7c3abd55504769fccd02356f6f80af2fd4 stdio.patch
+7ed6c620a5ea5585c323936b1ff01eb7f01a1192240706a0d0470b661a7a03ea10ed17507c59678aaedce51b7a5ea839c2f528f19f12de02119bf4e47f7c3998 strftime-add-l-support.patch
cce2f1eeb61e55674469c26871a573cce61d739c3defe9c8f56f2b774f6ba5435849ad542a6714120efddc98c297098e9c98a1a424ac593df2243d4aa479f9a9 ldconfig
378d70e65bcc65bb4e1415354cecfa54b0c1146dfb24474b69e418cdbf7ad730472cd09f6f103e1c99ba6c324c9560bccdf287f5889bbc3ef0bdf0e08da47413 getent.c
9d42d66fb1facce2b85dad919be5be819ee290bd26ca2db00982b2f8e055a0196290a008711cbe2b18ec9eee8d2270e3b3a4692c5a1b807013baa5c2b70a2bbf iconv.c"
diff --git a/system/musl/amalgamation.patch b/system/musl/amalgamation.patch
index fa118c910..bd8e6a141 100644
--- a/system/musl/amalgamation.patch
+++ b/system/musl/amalgamation.patch
@@ -280,27 +280,6 @@ index 03c5a77b..c423b825 100644
int ret = __clock_gettime(CLOCK_REALTIME, ts);
return ret < 0 ? 0 : base;
}
-diff --git a/src/stdio/setvbuf.c b/src/stdio/setvbuf.c
-index 06ea296c..523dddc8 100644
---- a/src/stdio/setvbuf.c
-+++ b/src/stdio/setvbuf.c
-@@ -12,13 +12,15 @@ int setvbuf(FILE *restrict f, char *restrict buf, int type, size_t size)
-
- if (type == _IONBF) {
- f->buf_size = 0;
-- } else {
-+ } else if (type == _IOLBF || type == _IOFBF) {
- if (buf && size >= UNGET) {
- f->buf = (void *)(buf + UNGET);
- f->buf_size = size - UNGET;
- }
- if (type == _IOLBF && f->buf_size)
- f->lbf = '\n';
-+ } else {
-+ return -1;
- }
-
- f->flags |= F_SVB;
diff --git a/src/unistd/getcwd.c b/src/unistd/getcwd.c
index f407ffe0..4fd3a60c 100644
--- a/src/unistd/getcwd.c
@@ -318,20 +297,6 @@ index f407ffe0..4fd3a60c 100644
if (ret == 0 || buf[0] != '/') {
errno = ENOENT;
return 0;
-diff --git a/include/tar.h b/include/tar.h
-index 2eba66ec..d15bd9b4 100644
---- a/include/tar.h
-+++ b/include/tar.h
-@@ -5,9 +5,7 @@
-
- #define TSUID 04000
- #define TSGID 02000
--#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) || defined(_XOPEN_SOURCE)
- #define TSVTX 01000
--#endif
- #define TUREAD 00400
- #define TUWRITE 00200
- #define TUEXEC 00100
diff --git a/src/conf/fpathconf.c b/src/conf/fpathconf.c
index b6a9d63e..83e47e87 100644
--- a/src/conf/fpathconf.c
@@ -437,212 +402,3 @@ index 4d91338b..04321887 100644
#define O_ACCMODE (03|O_SEARCH)
#define O_RDONLY 00
-diff --git a/src/dirent/fdopendir.c b/src/dirent/fdopendir.c
-index c377271d..d78fb87f 100644
---- a/src/dirent/fdopendir.c
-+++ b/src/dirent/fdopendir.c
-@@ -13,6 +13,10 @@ DIR *fdopendir(int fd)
- if (fstat(fd, &st) < 0) {
- return 0;
- }
-+ if (fcntl(fd, F_GETFL) & O_PATH) {
-+ errno = EBADF;
-+ return 0;
-+ }
- if (!S_ISDIR(st.st_mode)) {
- errno = ENOTDIR;
- return 0;
-diff --git a/src/unistd/renameat.c b/src/unistd/renameat.c
-index 12574822..07386407 100644
---- a/src/unistd/renameat.c
-+++ b/src/unistd/renameat.c
-@@ -1,7 +1,38 @@
-+#include <errno.h>
-+#include <libgen.h>
-+#include <limits.h>
- #include <stdio.h>
-+#include <string.h>
- #include "syscall.h"
-
- int renameat(int oldfd, const char *old, int newfd, const char *new)
- {
-+ char old_copy[PATH_MAX+1], new_copy[PATH_MAX+1];
-+ char *base;
-+
-+ if (strlen(old) > PATH_MAX || strlen(new) > PATH_MAX) {
-+ errno = ENAMETOOLONG;
-+ return -1;
-+ }
-+
-+ if (strlen(old) == 0 || strlen(new) == 0) {
-+ errno = ENOENT;
-+ return -1;
-+ }
-+
-+ strcpy(old_copy, old);
-+ strcpy(new_copy, new);
-+
-+ base = basename(old_copy);
-+ strncpy(old_copy, base, sizeof(old_copy));
-+ base = basename(new_copy);
-+ strncpy(new_copy, base, sizeof(new_copy));
-+
-+ if (strcmp(old_copy, ".") == 0 || strcmp(old_copy, "..") == 0 ||
-+ strcmp(new_copy, ".") == 0 || strcmp(new_copy, "..") == 0) {
-+ errno = EINVAL;
-+ return -1;
-+ }
-+
- return syscall(SYS_renameat, oldfd, old, newfd, new);
- }
-diff --git a/src/unistd/renameat.c b/src/unistd/renameat.c
-index 07386407..7e850401 100644
---- a/src/unistd/renameat.c
-+++ b/src/unistd/renameat.c
-@@ -1,16 +1,23 @@
- #include <errno.h>
-+#include <fcntl.h>
- #include <libgen.h>
- #include <limits.h>
- #include <stdio.h>
- #include <string.h>
-+#include <sys/stat.h>
-+#include <sys/types.h>
-+#include <unistd.h>
- #include "syscall.h"
-
- int renameat(int oldfd, const char *old, int newfd, const char *new)
- {
- char old_copy[PATH_MAX+1], new_copy[PATH_MAX+1];
- char *base;
-+ size_t old_size, new_size;
-+ struct stat statbuf;
-
-- if (strlen(old) > PATH_MAX || strlen(new) > PATH_MAX) {
-+ if ((old_size = strlen(old)) > PATH_MAX || \
-+ (new_size = strlen(new)) > PATH_MAX) {
- errno = ENAMETOOLONG;
- return -1;
- }
-@@ -34,5 +41,31 @@ int renameat(int oldfd, const char *old, int newfd, const char *new)
- return -1;
- }
-
-+ /* The Linux kernel will fail when attempting to rename a symlink of a
-+ directory with a trailing slash. We therefore have to handle this
-+ case ourselves. */
-+ if (old[old_size - 1] == '/') {
-+ /* Calling stat(2) on a symlink to a dir with the trailing
-+ slash causes stat(2) to return the actual directory instead
-+ of the symlink itself. */
-+ strcpy(old_copy, old);
-+ old_copy[old_size - 1] = '\0';
-+ if (fstatat(oldfd, old_copy, &statbuf, AT_SYMLINK_NOFOLLOW) == -1) {
-+ return -1;
-+ }
-+ if (S_ISLNK(statbuf.st_mode)) {
-+ if (fstatat(oldfd, old, &statbuf, 0) == -1) {
-+ return -1;
-+ }
-+ if (S_ISDIR(statbuf.st_mode)) {
-+ old = old_copy;
-+ } else {
-+ /* may as well not waste the syscall */
-+ errno = ENOTDIR;
-+ return -1;
-+ }
-+ }
-+ }
-+
- return syscall(SYS_renameat, oldfd, old, newfd, new);
- }
-diff --git a/src/unistd/renameat.c b/src/unistd/renameat.c
-index d0f31c21..e2f03d39 100644
---- a/src/unistd/renameat.c
-+++ b/src/unistd/renameat.c
-@@ -9,12 +9,31 @@
- #include <unistd.h>
- #include "syscall.h"
-
-+static inline int test_symlink_dirness(int fd, const char *pathname)
-+{
-+ struct stat statbuf;
-+ if (fstatat(fd, pathname, &statbuf, AT_SYMLINK_NOFOLLOW) == -1) {
-+ return 1;
-+ }
-+ if (S_ISLNK(statbuf.st_mode)) {
-+ if (fstatat(fd, pathname, &statbuf, 0) == -1) return 1;
-+
-+ if (S_ISDIR(statbuf.st_mode)) return 0;
-+ else {
-+ errno = ENOTDIR;
-+ return -1;
-+ }
-+ }
-+ return 1;
-+}
-+
- int renameat(int oldfd, const char *old, int newfd, const char *new)
- {
- char old_copy[PATH_MAX+1], new_copy[PATH_MAX+1];
- char *base;
- size_t old_size, new_size;
-- struct stat statbuf;
-+ struct stat oldstat, newstat;
-+ int r;
-
- if ((old_size = strlen(old)) > PATH_MAX || \
- (new_size = strlen(new)) > PATH_MAX) {
-@@ -22,11 +41,18 @@ int renameat(int oldfd, const char *old, int newfd, const char *new)
- return -1;
- }
-
-- if (strlen(old) == 0 || strlen(new) == 0) {
-+ if (old_size == 0 || new_size == 0) {
- errno = ENOENT;
- return -1;
- }
-
-+ /* Test equality of old and new.
-+ If they both resolve to the same dentry, we do nothing. */
-+ if (fstatat(oldfd, old, &oldstat, 0) == 0 && \
-+ fstatat(newfd, new, &newstat, 0) == 0 && \
-+ oldstat.st_dev == newstat.st_dev && \
-+ oldstat.st_ino == newstat.st_ino) return 0;
-+
- strcpy(old_copy, old);
- strcpy(new_copy, new);
-
-@@ -50,21 +76,17 @@ int renameat(int oldfd, const char *old, int newfd, const char *new)
- of the symlink itself. */
- strcpy(old_copy, old);
- old_copy[old_size - 1] = '\0';
-- if (fstatat(oldfd, old_copy, &statbuf, AT_SYMLINK_NOFOLLOW) == -1) {
-- return -1;
-- }
-- if (S_ISLNK(statbuf.st_mode)) {
-- if (fstatat(oldfd, old, &statbuf, 0) == -1) {
-- return -1;
-- }
-- if (S_ISDIR(statbuf.st_mode)) {
-- old = old_copy;
-- } else {
-- /* may as well not waste the syscall */
-- errno = ENOTDIR;
-- return -1;
-- }
-- }
-+ r = test_symlink_dirness(oldfd, old_copy);
-+ if (r == 0) old = old_copy;
-+ else if (r == -1) return -1;
-+ }
-+
-+ if (new[new_size - 1] == '/') {
-+ strcpy(new_copy, new);
-+ new_copy[new_size - 1] = '\0';
-+ r = test_symlink_dirness(newfd, new_copy);
-+ if (r == 0) new = new_copy;
-+ else if (r == -1) return -1;
- }
-
- return syscall(SYS_renameat, oldfd, old, newfd, new);
diff --git a/system/musl/arm64-tls.patch b/system/musl/arm64-tls.patch
new file mode 100644
index 000000000..4a6d7f7a4
--- /dev/null
+++ b/system/musl/arm64-tls.patch
@@ -0,0 +1,116 @@
+From 6104dae9088da7ffd9346671be867a43a4b03295 Mon Sep 17 00:00:00 2001
+From: Szabolcs Nagy <nsz@port70.net>
+Date: Thu, 16 May 2019 17:15:33 +0000
+Subject: fix static tls offsets of shared libs on TLS_ABOVE_TP targets
+
+tls_offset should always point to the end of the allocated static tls
+area, but this was not handled correctly on "tls variant 1" targets
+in the dynamic linker:
+
+after application tls was allocated, tls_offset was aligned up,
+potentially wasting tls space. (alignment may be needed at the
+begining of the tls area, not at the end, but that will be fixed
+separately as it is unlikely to affect real binaries.)
+
+when static tls was allocated for a shared library, tls_offset was
+only updated with the size of the tls segment which does not include
+alignment gaps, which can easily happen if the tls size update for
+one library leaves tls_offset misaligned for the next one. this can
+cause oob access in __copy_tls or arbitrary breakage at tls access.
+(the issue was observed on aarch64 with rust binaries)
+---
+ ldso/dynlink.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/ldso/dynlink.c b/ldso/dynlink.c
+index ad0cdba2..967f1fd9 100644
+--- a/ldso/dynlink.c
++++ b/ldso/dynlink.c
+@@ -1127,7 +1127,7 @@ static struct dso *load_library(const char *name, struct dso *needed_by)
+ #ifdef TLS_ABOVE_TP
+ p->tls.offset = tls_offset + ( (tls_align-1) &
+ -(tls_offset + (uintptr_t)p->tls.image) );
+- tls_offset += p->tls.size;
++ tls_offset = p->tls.offset + p->tls.size;
+ #else
+ tls_offset += p->tls.size + p->tls.align - 1;
+ tls_offset -= (tls_offset + (uintptr_t)p->tls.image)
+@@ -1797,9 +1797,7 @@ _Noreturn void __dls3(size_t *sp)
+ #ifdef TLS_ABOVE_TP
+ app.tls.offset = GAP_ABOVE_TP;
+ app.tls.offset += -GAP_ABOVE_TP & (app.tls.align-1);
+- tls_offset = app.tls.offset + app.tls.size
+- + ( -((uintptr_t)app.tls.image + app.tls.size)
+- & (app.tls.align-1) );
++ tls_offset = app.tls.offset + app.tls.size;
+ #else
+ tls_offset = app.tls.offset = app.tls.size
+ + ( -((uintptr_t)app.tls.image + app.tls.size)
+--
+cgit v1.2.1
+
+From a60b9e06861e56c0810bae0249b421e1758d281a Mon Sep 17 00:00:00 2001
+From: Szabolcs Nagy <nsz@port70.net>
+Date: Mon, 13 May 2019 18:47:11 +0000
+Subject: fix tls offsets when p_vaddr%p_align != 0 on TLS_ABOVE_TP targets
+
+currently the bfd linker does not seem to create tls segments where
+p_vaddr%p_align != 0, but this is valid in ELF and then the runtime
+computed tls offset must satisfy
+
+ offset%p_align == (base+p_vaddr)%p_align
+
+and in case of local exec tls (main executable) the smallest such
+offset must be used (otherwise it is incompatible with the offset
+computed by the static linker). the !TLS_ABOVE_TP case is handled
+correctly (the offset is negative then in the formula).
+
+the ldso code for TLS_ABOVE_TP is changed so the static tls offset
+of each module satisfies the formula.
+---
+ ldso/dynlink.c | 7 ++++---
+ src/env/__init_tls.c | 3 ++-
+ 2 files changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/ldso/dynlink.c b/ldso/dynlink.c
+index 967f1fd9..1398ff45 100644
+--- a/ldso/dynlink.c
++++ b/ldso/dynlink.c
+@@ -1125,8 +1125,8 @@ static struct dso *load_library(const char *name, struct dso *needed_by)
+ p->tls_id = ++tls_cnt;
+ tls_align = MAXP2(tls_align, p->tls.align);
+ #ifdef TLS_ABOVE_TP
+- p->tls.offset = tls_offset + ( (tls_align-1) &
+- -(tls_offset + (uintptr_t)p->tls.image) );
++ p->tls.offset = tls_offset + ( (p->tls.align-1) &
++ (-tls_offset + (uintptr_t)p->tls.image) );
+ tls_offset = p->tls.offset + p->tls.size;
+ #else
+ tls_offset += p->tls.size + p->tls.align - 1;
+@@ -1796,7 +1796,8 @@ _Noreturn void __dls3(size_t *sp)
+ app.tls_id = tls_cnt = 1;
+ #ifdef TLS_ABOVE_TP
+ app.tls.offset = GAP_ABOVE_TP;
+- app.tls.offset += -GAP_ABOVE_TP & (app.tls.align-1);
++ app.tls.offset += (-GAP_ABOVE_TP + (uintptr_t)app.tls.image)
++ & (app.tls.align-1);
+ tls_offset = app.tls.offset + app.tls.size;
+ #else
+ tls_offset = app.tls.offset = app.tls.size
+diff --git a/src/env/__init_tls.c b/src/env/__init_tls.c
+index 5f12500c..772baba3 100644
+--- a/src/env/__init_tls.c
++++ b/src/env/__init_tls.c
+@@ -115,7 +115,8 @@ static void static_init_tls(size_t *aux)
+ & (main_tls.align-1);
+ #ifdef TLS_ABOVE_TP
+ main_tls.offset = GAP_ABOVE_TP;
+- main_tls.offset += -GAP_ABOVE_TP & (main_tls.align-1);
++ main_tls.offset += (-GAP_ABOVE_TP + (uintptr_t)main_tls.image)
++ & (main_tls.align-1);
+ #else
+ main_tls.offset = main_tls.size;
+ #endif
+--
+cgit v1.2.1
+
diff --git a/system/musl/gettext-preserve-errno.patch b/system/musl/gettext-preserve-errno.patch
deleted file mode 100644
index c55df3e21..000000000
--- a/system/musl/gettext-preserve-errno.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-diff --git a/src/locale/dcngettext.c b/src/locale/dcngettext.c
-index 8b891d00..4c304393 100644
---- a/src/locale/dcngettext.c
-+++ b/src/locale/dcngettext.c
-@@ -122,6 +122,7 @@ char *dcngettext(const char *domainname, const char *msgid1, const char *msgid2,
- const struct __locale_map *lm;
- size_t domlen;
- struct binding *q;
-+ int old_errno = errno;
-
- if ((unsigned)category >= LC_ALL) goto notrans;
-
-@@ -138,6 +139,7 @@ char *dcngettext(const char *domainname, const char *msgid1, const char *msgid2,
- lm = loc->cat[category];
- if (!lm) {
- notrans:
-+ errno = old_errno;
- return (char *) ((n == 1) ? msgid1 : msgid2);
- }
-
-@@ -250,6 +252,7 @@ notrans:
- trans += l+1;
- }
- }
-+ errno = old_errno;
- return (char *)trans;
- }
-
diff --git a/system/musl/stdio.patch b/system/musl/stdio.patch
deleted file mode 100644
index 9ddfa5738..000000000
--- a/system/musl/stdio.patch
+++ /dev/null
@@ -1,69 +0,0 @@
-diff --git a/include/alltypes.h.in b/include/alltypes.h.in
-index 622ca01..4cc879b 100644
---- a/include/alltypes.h.in
-+++ b/include/alltypes.h.in
-@@ -57,6 +57,7 @@ TYPEDEF struct { unsigned __attr; } pthread_condattr_t;
- TYPEDEF struct { unsigned __attr; } pthread_barrierattr_t;
- TYPEDEF struct { unsigned __attr[2]; } pthread_rwlockattr_t;
-
-+STRUCT _IO_FILE { char __x; };
- TYPEDEF struct _IO_FILE FILE;
-
- TYPEDEF struct __mbstate_t { unsigned __opaque1, __opaque2; } mbstate_t;
-diff --git a/include/stdio.h b/include/stdio.h
-index afadd91..3604198 100644
---- a/include/stdio.h
-+++ b/include/stdio.h
-@@ -11,6 +11,10 @@ extern "C" {
- #define __NEED___isoc_va_list
- #define __NEED_size_t
-
-+#if __STDC_VERSION__ < 201112L
-+#define __NEED_struct__IO_FILE
-+#endif
-+
- #if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
- || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
- || defined(_BSD_SOURCE)
-diff --git a/include/wchar.h b/include/wchar.h
-index 369b1e9..88eb55b 100644
---- a/include/wchar.h
-+++ b/include/wchar.h
-@@ -14,6 +14,10 @@ extern "C" {
- #define __NEED_wint_t
- #define __NEED_mbstate_t
-
-+#if __STDC_VERSION__ < 201112L
-+#define __NEED_struct__IO_FILE
-+#endif
-+
- #if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
- || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
- #define __NEED_locale_t
-diff --git a/src/include/stdio.h b/src/include/stdio.h
-index 534c690..fae3755 100644
---- a/src/include/stdio.h
-+++ b/src/include/stdio.h
-@@ -1,6 +1,8 @@
- #ifndef STDIO_H
- #define STDIO_H
-
-+#define __DEFINED_struct__IO_FILE
-+
- #include "../../include/stdio.h"
-
- #undef stdin
-diff --git a/src/include/wchar.h b/src/include/wchar.h
-index e69de29..79f5d0e 100644
---- a/src/include/wchar.h
-+++ b/src/include/wchar.h
-@@ -0,0 +1,9 @@
-+#ifndef WCHAR_H
-+#define WCHAR_H
-+
-+#define __DEFINED_struct__IO_FILE
-+
-+#include "../../include/wchar.h"
-+
-+#endif
-+
diff --git a/system/musl/strftime-add-l-support.patch b/system/musl/strftime-add-l-support.patch
new file mode 100644
index 000000000..8305a9910
--- /dev/null
+++ b/system/musl/strftime-add-l-support.patch
@@ -0,0 +1,25 @@
+From 481def0e92ebfe81f40f416ddf345de15647e46b Mon Sep 17 00:00:00 2001
+From: "A. Wilcox" <AWilcox@Wilcox-Tech.com>
+Date: Fri, 31 May 2019 19:03:20 -0500
+Subject: [PATCH] strftime: add %l support
+
+---
+ src/time/strftime.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/src/time/strftime.c b/src/time/strftime.c
+index cc53d536..98caa1f6 100644
+--- a/src/time/strftime.c
++++ b/src/time/strftime.c
+@@ -95,6 +95,8 @@ const char *__strftime_fmt_1(char (*s)[100], size_t *l, int f, const struct tm *
+ case 'H':
+ val = tm->tm_hour;
+ goto number;
++ case 'l':
++ def_pad = ' ';
+ case 'I':
+ val = tm->tm_hour;
+ if (!val) val = 12;
+--
+2.21.0
+