diff --git a/libc/musl/0001-riscv64-define-ELF_NFPREG.patch b/libc/musl/0001-riscv64-define-ELF_NFPREG.patch new file mode 100644 index 0000000..b2f0a0f --- /dev/null +++ b/libc/musl/0001-riscv64-define-ELF_NFPREG.patch @@ -0,0 +1,24 @@ +From e5d2823631bbfebacf48e1a34ed28f28d7cb2570 Mon Sep 17 00:00:00 2001 +From: Khem Raj +Date: Mon, 11 Jan 2021 09:40:33 -0800 +Subject: [PATCH] riscv64: define ELF_NFPREG + +ELF_NFPREG is used by some userspace applications like gdb +--- + arch/riscv64/bits/user.h | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/riscv64/bits/user.h b/arch/riscv64/bits/user.h +index 2da743ea..0d37de0b 100644 +--- a/arch/riscv64/bits/user.h ++++ b/arch/riscv64/bits/user.h +@@ -1,5 +1,6 @@ + #include + + #define ELF_NGREG 32 ++#define ELF_NFPREG 33 + typedef unsigned long elf_greg_t, elf_gregset_t[ELF_NGREG]; + typedef union __riscv_mc_fp_state elf_fpregset_t; +-- +2.30.1 + diff --git a/libc/musl/APKBUILD b/libc/musl/APKBUILD new file mode 100644 index 0000000..46f11a2 --- /dev/null +++ b/libc/musl/APKBUILD @@ -0,0 +1,55 @@ +# Contributor: Ariadne Conill +# Contributor: Timo Teräs +# Maintainer: Alex Denes +pkgname=musl +pkgver=1.2.2 +pkgrel=6 +pkgdesc="the musl c library (libc) implementation" +url="https://musl.libc.org/" +arch="all" +license="MIT" +options="!check" +source=" + musl-$pkgver.tar.gz::https://git.musl-libc.org/cgit/musl/snapshot/v$pkgver.tar.gz + 0001-riscv64-define-ELF_NFPREG.patch + handle-aux-at_base.patch + syscall-cp-epoll.patch +" + +# secfixes: +# 1.2.2_pre2-r0: +# - CVE-2020-28928 +# 1.1.23-r2: +# - CVE-2019-14697 +# 1.1.15-r4: +# - CVE-2016-8859 + +builddir="$srcdir"/"v$pkgver" + +build() { + # note: not autotools + ./configure \ + --build=$CBUILD \ + --host=$CHOST \ + --prefix=/usr \ + --sysconfdir=/etc \ + --mandir=/usr/share/man \ + --infodir=/usr/share/info \ + --localstatedir=/var \ + --enable-debug \ + --disable-eh-frame \ + --disable-shared + make +} + +package() { + cd "$builddir" + make DESTDIR="$pkgdir" install +} + +sha512sums=" +7240550ab45cb6b410d65013c92f1f1de0f274322e7ba10e3cf9ce0464a1a833337c2fde39d2fc8c25af1d60599a5bb0ec0d9fb3723c098df3a72e82251bb3eb musl-1.2.2.tar.gz +f036317426d54efb4df41c08664c8513d3991408b20f4c74220c8b0324d2e96a97094851ea225e363dd593828c2280e77422b0f4b924dbd106df45504723a00e 0001-riscv64-define-ELF_NFPREG.patch +a76f79b801497ad994746cf82bb6eaf86f9e1ae646e6819fbae8532a7f4eee53a96ac1d4e789ec8f66aea2a68027b0597f7a579b3369e01258da8accfce41370 handle-aux-at_base.patch +d256ba7857c98d39b86aa73674eda5d45ab8134dde3fac2bc48ebb6ba9a824c20c43f2cdc6af54d2a45c162d1e4ec6517c36400992bba10496bcc51b374cbcd0 syscall-cp-epoll.patch +" diff --git a/libc/musl/__stack_chk_fail_local.c b/libc/musl/__stack_chk_fail_local.c new file mode 100644 index 0000000..2b403a6 --- /dev/null +++ b/libc/musl/__stack_chk_fail_local.c @@ -0,0 +1,2 @@ +extern void __stack_chk_fail(void); +void __attribute__((visibility ("hidden"))) __stack_chk_fail_local(void) { __stack_chk_fail(); } diff --git a/libc/musl/eh-frame.patch b/libc/musl/eh-frame.patch new file mode 100644 index 0000000..af7ba3e --- /dev/null +++ b/libc/musl/eh-frame.patch @@ -0,0 +1,140 @@ +From b2d24e3cc6015aa6a4b01b1fdbad1e68b6fccb96 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Timo=20Ter=C3=A4s?= +Date: Fri, 9 Jul 2021 10:57:20 +0300 +Subject: add configure option to enable .eh_frame generation + +Add --enable-eh-frame to enable .eh_frame generation. This adds +about 80kB to ELF size on x86_64. + +This is useful to run continuous profilers, gdb, valgrind and other +debugging utilities to generate backtrace information without having +to install the full musl-dbg package. + +As side effect, this might seem to make exception handling work +through C-library fuctions when they are calling a callback (e.g. qsort), +but this continues to be UB and is not supported. This actually is the +case on ARM where .ARM.exidx is used for unwind info which is present +always on the musl DSO. + +--- + Makefile | 4 ++-- + configure | 30 ++++++++++++++++++++++-------- + tools/add-cfi.i386.awk | 2 +- + tools/add-cfi.x86_64.awk | 2 +- + 4 files changed, 26 insertions(+), 12 deletions(-) + +diff --git a/Makefile b/Makefile +index e8cc4436..2b501c25 100644 +--- a/Makefile ++++ b/Makefile +@@ -134,8 +134,8 @@ $(LOBJS) $(LDSO_OBJS): CFLAGS_ALL += -fPIC + CC_CMD = $(CC) $(CFLAGS_ALL) -c -o $@ $< + + # Choose invocation of assembler to be used +-ifeq ($(ADD_CFI),yes) +- AS_CMD = LC_ALL=C awk -f $(srcdir)/tools/add-cfi.common.awk -f $(srcdir)/tools/add-cfi.$(ARCH).awk $< | $(CC) $(CFLAGS_ALL) -x assembler -c -o $@ - ++ifneq ($(ADD_CFI),no) ++ AS_CMD = LC_ALL=C awk -v CFI_SECTIONS="$(ADD_CFI)" -f $(srcdir)/tools/add-cfi.common.awk -f $(srcdir)/tools/add-cfi.$(ARCH).awk $< | $(CC) $(CFLAGS_ALL) -x assembler -c -o $@ - + else + AS_CMD = $(CC_CMD) + endif +diff --git a/configure b/configure +index a5231a0e..eea16e6c 100755 +--- a/configure ++++ b/configure +@@ -30,6 +30,7 @@ System types: + Optional features: + --enable-optimize=... optimize listed components for speed over size [auto] + --enable-debug build with debugging information [disabled] ++ --enable-eh-frame keep .eh_frame on main binary [disabled] + --disable-warnings build with recommended warnings flags [enabled] + --enable-wrapper=... build given musl toolchain wrapper [auto] + --disable-shared inhibit building shared library [enabled] +@@ -142,6 +143,7 @@ static=yes + wrapper=auto + gcc_wrapper=no + clang_wrapper=no ++eh_frame=no + malloc_dir=mallocng + + for arg ; do +@@ -172,6 +174,8 @@ case "$arg" in + --disable-wrapper|--enable-wrapper=no) wrapper=no ;; + --enable-gcc-wrapper|--enable-gcc-wrapper=yes) wrapper=yes ; gcc_wrapper=yes ;; + --disable-gcc-wrapper|--enable-gcc-wrapper=no) wrapper=no ;; ++--enable-eh-frame|--enable-eh-frame=yes) eh_frame=yes ;; ++--disable-eh-frame|--enable-eh-frame=no) eh_frame=no ;; + --with-malloc=*) malloc_dir=${arg#*=} ;; + --enable-*|--disable-*|--with-*|--without-*|--*dir=*) ;; + --host=*|--target=*) target=${arg#*=} ;; +@@ -407,14 +411,22 @@ test "$debug" = yes && CFLAGS_AUTO=-g + # enabled, our assembler supports the needed directives, and the + # preprocessing script has been written for our architecture. + # +-printf "checking whether we should preprocess assembly to add debugging information... " +-if fnmatch '-g*|*\ -g*' "$CFLAGS_AUTO $CFLAGS" && +- test -f "tools/add-cfi.$ARCH.awk" && ++printf "checking whether we should preprocess assembly to add unwind information... " ++ ++ADD_CFI="no" ++if test -f "tools/add-cfi.$ARCH.awk" && + printf ".file 1 \"srcfile.s\"\n.line 1\n.cfi_startproc\n.cfi_endproc" | $CC -g -x assembler -c -o /dev/null 2>/dev/null - + then +- ADD_CFI=yes +-else +- ADD_CFI=no ++ if test "$eh_frame" = "yes" && fnmatch '-g*|*\ -g*' "$CFLAGS_AUTO $CFLAGS" ++ then ++ ADD_CFI=".eh_frame, .debug_frame" ++ elif test "$eh_frame" = "yes" ++ then ++ ADD_CFI=".eh_frame" ++ elif fnmatch '-g*|*\ -g*' "$CFLAGS_AUTO $CFLAGS" ++ then ++ ADD_CFI=".debug_frame" ++ fi + fi + printf "%s\n" "$ADD_CFI" + +@@ -478,8 +490,10 @@ fi + # unstrippable. These options force them back to debug sections (and + # cause them not to get generated at all if debugging is off). + # +-tryflag CFLAGS_AUTO -fno-unwind-tables +-tryflag CFLAGS_AUTO -fno-asynchronous-unwind-tables ++if test "$eh_frame" = "no"; then ++ tryflag CFLAGS_AUTO -fno-unwind-tables ++ tryflag CFLAGS_AUTO -fno-asynchronous-unwind-tables ++fi + + # + # Attempt to put each function and each data object in its own +diff --git a/tools/add-cfi.i386.awk b/tools/add-cfi.i386.awk +index d05037de..f758acec 100644 +--- a/tools/add-cfi.i386.awk ++++ b/tools/add-cfi.i386.awk +@@ -9,7 +9,7 @@ + + BEGIN { + # don't put CFI data in the .eh_frame ELF section (which we don't keep) +- print ".cfi_sections .debug_frame" ++ print ".cfi_sections " CFI_SECTIONS + + # only emit CFI directives inside a function + in_function = 0 +diff --git a/tools/add-cfi.x86_64.awk b/tools/add-cfi.x86_64.awk +index 7e1513d6..4a2ae029 100644 +--- a/tools/add-cfi.x86_64.awk ++++ b/tools/add-cfi.x86_64.awk +@@ -2,7 +2,7 @@ + + BEGIN { + # don't put CFI data in the .eh_frame ELF section (which we don't keep) +- print ".cfi_sections .debug_frame" ++ print ".cfi_sections " CFI_SECTIONS + + # only emit CFI directives inside a function + in_function = 0 +-- +2.32.0 + diff --git a/libc/musl/getconf.c b/libc/musl/getconf.c new file mode 100644 index 0000000..c423524 --- /dev/null +++ b/libc/musl/getconf.c @@ -0,0 +1,338 @@ +/*- + * Copyright (c) 1996, 1998 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by J.T. Conklin. + * + * Mostly rewritten to be used in Alpine Linux (with musl c-library) + * by Timo Teräs. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct conf_variable { + const char *name; + enum { SYSCONF, CONFSTR, PATHCONF, CONSTANT, UCONSTANT, NUM_TYPES } type; + long value; +}; + +static const struct conf_variable conf_table[] = { +{ "PATH", CONFSTR, _CS_PATH }, + +/* Utility Limit Minimum Values */ +{ "POSIX2_BC_BASE_MAX", CONSTANT, _POSIX2_BC_BASE_MAX }, +{ "POSIX2_BC_DIM_MAX", CONSTANT, _POSIX2_BC_DIM_MAX }, +{ "POSIX2_BC_SCALE_MAX", CONSTANT, _POSIX2_BC_SCALE_MAX }, +{ "POSIX2_BC_STRING_MAX", CONSTANT, _POSIX2_BC_STRING_MAX }, +{ "POSIX2_COLL_WEIGHTS_MAX", CONSTANT, _POSIX2_COLL_WEIGHTS_MAX }, +{ "POSIX2_EXPR_NEST_MAX", CONSTANT, _POSIX2_EXPR_NEST_MAX }, +{ "POSIX2_LINE_MAX", CONSTANT, _POSIX2_LINE_MAX }, +{ "POSIX2_RE_DUP_MAX", CONSTANT, _POSIX2_RE_DUP_MAX }, +{ "POSIX2_VERSION", CONSTANT, _POSIX2_VERSION }, + +/* POSIX.1 Minimum Values */ +{ "_POSIX_AIO_LISTIO_MAX", CONSTANT, _POSIX_AIO_LISTIO_MAX }, +{ "_POSIX_AIO_MAX", CONSTANT, _POSIX_AIO_MAX }, +{ "_POSIX_ARG_MAX", CONSTANT, _POSIX_ARG_MAX }, +{ "_POSIX_CHILD_MAX", CONSTANT, _POSIX_CHILD_MAX }, +{ "_POSIX_LINK_MAX", CONSTANT, _POSIX_LINK_MAX }, +{ "_POSIX_MAX_CANON", CONSTANT, _POSIX_MAX_CANON }, +{ "_POSIX_MAX_INPUT", CONSTANT, _POSIX_MAX_INPUT }, +{ "_POSIX_MQ_OPEN_MAX", CONSTANT, _POSIX_MQ_OPEN_MAX }, +{ "_POSIX_MQ_PRIO_MAX", CONSTANT, _POSIX_MQ_PRIO_MAX }, +{ "_POSIX_NAME_MAX", CONSTANT, _POSIX_NAME_MAX }, +{ "_POSIX_NGROUPS_MAX", CONSTANT, _POSIX_NGROUPS_MAX }, +{ "_POSIX_OPEN_MAX", CONSTANT, _POSIX_OPEN_MAX }, +{ "_POSIX_PATH_MAX", CONSTANT, _POSIX_PATH_MAX }, +{ "_POSIX_PIPE_BUF", CONSTANT, _POSIX_PIPE_BUF }, +{ "_POSIX_SSIZE_MAX", CONSTANT, _POSIX_SSIZE_MAX }, +{ "_POSIX_STREAM_MAX", CONSTANT, _POSIX_STREAM_MAX }, +{ "_POSIX_TZNAME_MAX", CONSTANT, _POSIX_TZNAME_MAX }, + +/* Symbolic Utility Limits */ +{ "BC_BASE_MAX", SYSCONF, _SC_BC_BASE_MAX }, +{ "BC_DIM_MAX", SYSCONF, _SC_BC_DIM_MAX }, +{ "BC_SCALE_MAX", SYSCONF, _SC_BC_SCALE_MAX }, +{ "BC_STRING_MAX", SYSCONF, _SC_BC_STRING_MAX }, +{ "COLL_WEIGHTS_MAX", SYSCONF, _SC_COLL_WEIGHTS_MAX }, +{ "EXPR_NEST_MAX", SYSCONF, _SC_EXPR_NEST_MAX }, +{ "LINE_MAX", SYSCONF, _SC_LINE_MAX }, +{ "RE_DUP_MAX", SYSCONF, _SC_RE_DUP_MAX }, + +/* Optional Facility Configuration Values */ +{ "_POSIX2_C_BIND", SYSCONF, _SC_2_C_BIND }, +{ "POSIX2_C_DEV", SYSCONF, _SC_2_C_DEV }, +{ "POSIX2_CHAR_TERM", SYSCONF, _SC_2_CHAR_TERM }, +{ "POSIX2_FORT_DEV", SYSCONF, _SC_2_FORT_DEV }, +{ "POSIX2_FORT_RUN", SYSCONF, _SC_2_FORT_RUN }, +{ "POSIX2_LOCALEDEF", SYSCONF, _SC_2_LOCALEDEF }, +{ "POSIX2_SW_DEV", SYSCONF, _SC_2_SW_DEV }, +{ "POSIX2_UPE", SYSCONF, _SC_2_UPE }, + +/* POSIX.1 Configurable System Variables */ +{ "AIO_LISTIO_MAX", SYSCONF, _SC_AIO_LISTIO_MAX }, +{ "AIO_MAX", SYSCONF, _SC_AIO_MAX }, +{ "ARG_MAX", SYSCONF, _SC_ARG_MAX }, +{ "CHILD_MAX", SYSCONF, _SC_CHILD_MAX }, +{ "CLK_TCK", SYSCONF, _SC_CLK_TCK }, +{ "MQ_OPEN_MAX", SYSCONF, _SC_MQ_OPEN_MAX }, +{ "MQ_PRIO_MAX", SYSCONF, _SC_MQ_PRIO_MAX }, +{ "NGROUPS_MAX", SYSCONF, _SC_NGROUPS_MAX }, +{ "OPEN_MAX", SYSCONF, _SC_OPEN_MAX }, +{ "STREAM_MAX", SYSCONF, _SC_STREAM_MAX }, +{ "TZNAME_MAX", SYSCONF, _SC_TZNAME_MAX }, +{ "_POSIX_JOB_CONTROL", SYSCONF, _SC_JOB_CONTROL }, +{ "_POSIX_SAVED_IDS", SYSCONF, _SC_SAVED_IDS }, +{ "_POSIX_VERSION", SYSCONF, _SC_VERSION }, + +{ "LINK_MAX", PATHCONF, _PC_LINK_MAX }, +{ "MAX_CANON", PATHCONF, _PC_MAX_CANON }, +{ "MAX_INPUT", PATHCONF, _PC_MAX_INPUT }, +{ "NAME_MAX", PATHCONF, _PC_NAME_MAX }, +{ "PATH_MAX", PATHCONF, _PC_PATH_MAX }, +{ "PIPE_BUF", PATHCONF, _PC_PIPE_BUF }, +{ "_POSIX_CHOWN_RESTRICTED", PATHCONF, _PC_CHOWN_RESTRICTED }, +{ "_POSIX_NO_TRUNC", PATHCONF, _PC_NO_TRUNC }, +{ "_POSIX_VDISABLE", PATHCONF, _PC_VDISABLE }, + +/* POSIX.1b Configurable System Variables */ +{ "PAGESIZE", SYSCONF, _SC_PAGESIZE }, +{ "_POSIX_ASYNCHRONOUS_IO", SYSCONF, _SC_ASYNCHRONOUS_IO }, +{ "_POSIX_FSYNC", SYSCONF, _SC_FSYNC }, +{ "_POSIX_MAPPED_FILES", SYSCONF, _SC_MAPPED_FILES }, +{ "_POSIX_MEMLOCK", SYSCONF, _SC_MEMLOCK }, +{ "_POSIX_MEMLOCK_RANGE", SYSCONF, _SC_MEMLOCK_RANGE }, +{ "_POSIX_MEMORY_PROTECTION", SYSCONF, _SC_MEMORY_PROTECTION }, +{ "_POSIX_MESSAGE_PASSING", SYSCONF, _SC_MESSAGE_PASSING }, +{ "_POSIX_MONOTONIC_CLOCK", SYSCONF, _SC_MONOTONIC_CLOCK }, +{ "_POSIX_PRIORITY_SCHEDULING", SYSCONF, _SC_PRIORITY_SCHEDULING }, +{ "_POSIX_SEMAPHORES", SYSCONF, _SC_SEMAPHORES }, +{ "_POSIX_SHARED_MEMORY_OBJECTS", SYSCONF, _SC_SHARED_MEMORY_OBJECTS }, +{ "_POSIX_SYNCHRONIZED_IO", SYSCONF, _SC_SYNCHRONIZED_IO }, +{ "_POSIX_TIMERS", SYSCONF, _SC_TIMERS }, + +{ "_POSIX_SYNC_IO", PATHCONF, _PC_SYNC_IO }, + +/* POSIX.1c Configurable System Variables */ +{ "LOGIN_NAME_MAX", SYSCONF, _SC_LOGIN_NAME_MAX }, +{ "_POSIX_THREADS", SYSCONF, _SC_THREADS }, + +/* POSIX.1j Configurable System Variables */ +{ "_POSIX_BARRIERS", SYSCONF, _SC_BARRIERS }, +{ "_POSIX_READER_WRITER_LOCKS", SYSCONF, _SC_READER_WRITER_LOCKS }, +{ "_POSIX_SPIN_LOCKS", SYSCONF, _SC_SPIN_LOCKS }, + +/* XPG4.2 Configurable System Variables */ +{ "IOV_MAX", SYSCONF, _SC_IOV_MAX }, +{ "PAGE_SIZE", SYSCONF, _SC_PAGE_SIZE }, +{ "_XOPEN_SHM", SYSCONF, _SC_XOPEN_SHM }, + +/* X/Open CAE Spec. Issue 5 Version 2 Configurable System Variables */ +{ "FILESIZEBITS", PATHCONF, _PC_FILESIZEBITS }, + +/* POSIX.1-2001 XSI Option Group Configurable System Variables */ +{ "ATEXIT_MAX", SYSCONF, _SC_ATEXIT_MAX }, + +/* POSIX.1-2001 TSF Configurable System Variables */ +{ "GETGR_R_SIZE_MAX", SYSCONF, _SC_GETGR_R_SIZE_MAX }, +{ "GETPW_R_SIZE_MAX", SYSCONF, _SC_GETPW_R_SIZE_MAX }, + +/* Commonly provided extensions */ +{ "_PHYS_PAGES", SYSCONF, _SC_PHYS_PAGES }, +{ "_AVPHYS_PAGES", SYSCONF, _SC_AVPHYS_PAGES }, +{ "_NPROCESSORS_CONF", SYSCONF, _SC_NPROCESSORS_CONF }, +{ "_NPROCESSORS_ONLN", SYSCONF, _SC_NPROCESSORS_ONLN }, + +/* Data type related extensions */ +{ "CHAR_BIT", CONSTANT, CHAR_BIT }, +{ "CHAR_MAX", CONSTANT, CHAR_MAX }, +{ "CHAR_MIN", CONSTANT, CHAR_MIN }, +{ "INT_MAX", CONSTANT, INT_MAX }, +{ "INT_MIN", CONSTANT, INT_MIN }, +{ "LONG_BIT", CONSTANT, LONG_BIT }, +{ "LONG_MAX", CONSTANT, LONG_MAX }, +{ "LONG_MIN", CONSTANT, LONG_MIN }, +{ "SCHAR_MAX", CONSTANT, SCHAR_MAX }, +{ "SCHAR_MIN", CONSTANT, SCHAR_MIN }, +{ "SHRT_MAX", CONSTANT, SHRT_MAX }, +{ "SHRT_MIN", CONSTANT, SHRT_MIN }, +{ "SSIZE_MAX", CONSTANT, SSIZE_MAX }, +{ "UCHAR_MAX", UCONSTANT, (long) UCHAR_MAX }, +{ "UINT_MAX", UCONSTANT, (long) UINT_MAX }, +{ "ULONG_MAX", UCONSTANT, (long) ULONG_MAX }, +{ "USHRT_MAX", UCONSTANT, (long) USHRT_MAX }, +{ "WORD_BIT", CONSTANT, WORD_BIT }, + +{ NULL, CONSTANT, 0L } +}; + +static int all = 0; + +static void usage(const char *p) +{ + (void)fprintf(stderr, "Usage: %s system_var\n\t%s -a\n" + "\t%s path_var pathname\n\t%s -a pathname\n", p, p, p, p); + exit(EXIT_FAILURE); +} + +static void print_long(const char *name, long val) +{ + if (all) printf("%s = %ld\n", name, val); + else printf("%ld\n", val); +} + +static void print_ulong(const char *name, unsigned long val) +{ + if (all) printf("%s = %lu\n", name, val); + else printf("%lu\n", val); +} + +static void print_string(const char *name, const char *val) +{ + if (all) printf("%s = %s\n", name, val); + else printf("%s\n", val); +} + +static int print_constant(const struct conf_variable *cp, const char *pathname) +{ + print_long(cp->name, cp->value); + return 0; +} + +static int print_uconstant(const struct conf_variable *cp, const char *pathname) +{ + print_ulong(cp->name, (unsigned long) cp->value); + return 0; +} + +static int print_sysconf(const struct conf_variable *cp, const char *pathname) +{ + long val; + + errno = 0; + if ((val = sysconf((int)cp->value)) == -1) { + if (errno != 0) err(EXIT_FAILURE, "sysconf(%ld)", cp->value); + return -1; + } + print_long(cp->name, val); + return 0; +} + +static int print_confstr(const struct conf_variable *cp, const char *pathname) +{ + size_t len; + char *val; + + errno = 0; + if ((len = confstr((int)cp->value, NULL, 0)) == 0) goto error; + if ((val = malloc(len)) == NULL) err(EXIT_FAILURE, "Can't allocate %zu bytes", len); + errno = 0; + if (confstr((int)cp->value, val, len) == 0) goto error; + print_string(cp->name, val); + free(val); + return 0; +error: + if (errno != EINVAL) err(EXIT_FAILURE, "confstr(%ld)", cp->value); + return -1; +} + +static int print_pathconf(const struct conf_variable *cp, const char *pathname) +{ + long val; + + errno = 0; + if ((val = pathconf(pathname, (int)cp->value)) == -1) { + if (all && errno == EINVAL) return 0; + if (errno != 0) err(EXIT_FAILURE, "pathconf(%s, %ld)", pathname, cp->value); + return -1; + } + print_long(cp->name, val); + return 0; +} + +typedef int (*handler_t)(const struct conf_variable *cp, const char *pathname); +static const handler_t type_handlers[NUM_TYPES] = { + [SYSCONF] = print_sysconf, + [CONFSTR] = print_confstr, + [PATHCONF] = print_pathconf, + [CONSTANT] = print_constant, + [UCONSTANT] = print_uconstant, +}; + +int main(int argc, char **argv) +{ + const char *progname = argv[0]; + const struct conf_variable *cp; + const char *varname, *pathname; + int ch, found = 0; + + (void)setlocale(LC_ALL, ""); + while ((ch = getopt(argc, argv, "a")) != -1) { + switch (ch) { + case 'a': + all = 1; + break; + case '?': + default: + usage(progname); + } + } + argc -= optind; + argv += optind; + + if (!all) { + if (argc == 0) + usage(progname); + varname = argv[0]; + argc--; + argv++; + } else + varname = NULL; + + if (argc > 1) + usage(progname); + pathname = argv[0]; /* may be NULL */ + + for (cp = conf_table; cp->name != NULL; cp++) { + if (!all && strcmp(varname, cp->name) != 0) continue; + if ((cp->type == PATHCONF) == (pathname != NULL)) { + if (type_handlers[cp->type](cp, pathname) < 0) + print_string(cp->name, "undefined"); + found = 1; + } else if (!all) + errx(EXIT_FAILURE, "%s: invalid variable type", cp->name); + } + if (!all && !found) errx(EXIT_FAILURE, "%s: unknown variable", varname); + (void)fflush(stdout); + return ferror(stdout) ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/libc/musl/getent.c b/libc/musl/getent.c new file mode 100644 index 0000000..4a6aa6f --- /dev/null +++ b/libc/musl/getent.c @@ -0,0 +1,536 @@ +/*- + * Copyright (c) 2004-2006 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Luke Mewburn. + * Timo Teräs cleaned up the code for use in Alpine Linux with musl libc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +enum { + RV_OK = 0, + RV_USAGE = 1, + RV_NOTFOUND = 2, + RV_NOENUM = 3 +}; + +static int usage(const char *); + +static int parsenum(const char *word, unsigned long *result) +{ + unsigned long num; + char *ep; + + if (!isdigit((unsigned char)word[0])) + return 0; + errno = 0; + num = strtoul(word, &ep, 10); + if (num == ULONG_MAX && errno == ERANGE) + return 0; + if (*ep != '\0') + return 0; + *result = num; + return 1; +} + +/* + * printfmtstrings -- + * vprintf(format, ...), + * then the aliases (beginning with prefix, separated by sep), + * then a newline + */ +__attribute__ ((format (printf, 4, 5))) +static void printfmtstrings(char *strings[], const char *prefix, const char *sep, + const char *fmt, ...) +{ + va_list ap; + const char *curpref; + size_t i; + + va_start(ap, fmt); + (void)vprintf(fmt, ap); + va_end(ap); + + curpref = prefix; + for (i = 0; strings[i] != NULL; i++) { + (void)printf("%s%s", curpref, strings[i]); + curpref = sep; + } + (void)printf("\n"); +} + +static int ethers(int argc, char *argv[]) +{ + char hostname[MAXHOSTNAMELEN + 1], *hp; + struct ether_addr ea, *eap; + int i, rv; + + if (argc == 2) { + warnx("Enumeration not supported on ethers"); + return RV_NOENUM; + } + + rv = RV_OK; + for (i = 2; i < argc; i++) { + if ((eap = ether_aton(argv[i])) == NULL) { + eap = &ea; + hp = argv[i]; + if (ether_hostton(hp, eap) != 0) { + rv = RV_NOTFOUND; + break; + } + } else { + hp = hostname; + if (ether_ntohost(hp, eap) != 0) { + rv = RV_NOTFOUND; + break; + } + } + (void)printf("%-17s %s\n", ether_ntoa(eap), hp); + } + return rv; +} + +static void groupprint(const struct group *gr) +{ + printfmtstrings(gr->gr_mem, ":", ",", "%s:%s:%u", + gr->gr_name, gr->gr_passwd, gr->gr_gid); +} + +static int group(int argc, char *argv[]) +{ + struct group *gr; + unsigned long id; + int i, rv; + + rv = RV_OK; + if (argc == 2) { + while ((gr = getgrent()) != NULL) + groupprint(gr); + } else { + for (i = 2; i < argc; i++) { + if (parsenum(argv[i], &id)) + gr = getgrgid((gid_t)id); + else + gr = getgrnam(argv[i]); + if (gr == NULL) { + rv = RV_NOTFOUND; + break; + } + groupprint(gr); + } + } + endgrent(); + return rv; +} + +static void hostsprint(const struct hostent *he) +{ + char buf[INET6_ADDRSTRLEN]; + + if (inet_ntop(he->h_addrtype, he->h_addr, buf, sizeof(buf)) == NULL) + (void)strlcpy(buf, "# unknown", sizeof(buf)); + printfmtstrings(he->h_aliases, " ", " ", "%-16s %s", buf, he->h_name); +} + +static int hosts(int argc, char *argv[]) +{ + struct hostent *he; + char addr[IN6ADDRSZ]; + int i, rv; + + sethostent(1); + rv = RV_OK; + if (argc == 2) { + while ((he = gethostent()) != NULL) + hostsprint(he); + } else { + for (i = 2; i < argc; i++) { + if (inet_pton(AF_INET6, argv[i], (void *)addr) > 0) + he = gethostbyaddr(addr, IN6ADDRSZ, AF_INET6); + else if (inet_pton(AF_INET, argv[i], (void *)addr) > 0) + he = gethostbyaddr(addr, INADDRSZ, AF_INET); + else if ((he = gethostbyname2(argv[i], AF_INET6)) == NULL) + he = gethostbyname2(argv[i], AF_INET); + if (he == NULL) { + rv = RV_NOTFOUND; + break; + } + hostsprint(he); + } + } + endhostent(); + return rv; +} + +static int ahosts_ex(int family, int flags, int argc, char *argv[]) +{ + static const char *socktypes[] = { + [SOCK_STREAM] = "STREAM", + [SOCK_DGRAM] = "DGRAM", + [SOCK_RAW] = "RAW", + [SOCK_RDM] = "RDM", + [SOCK_SEQPACKET] = "SEQPACKET", + [SOCK_DCCP] = "DCCP", + [SOCK_PACKET] = "PACKET", + }; + const char *sockstr; + char sockbuf[16], buf[INET6_ADDRSTRLEN]; + struct addrinfo *res, *r, hint; + void *addr; + int i; + + if (argc == 2) + return hosts(argc, argv); + + hint = (struct addrinfo) { + .ai_family = family, + .ai_flags = AI_ADDRCONFIG | AI_CANONNAME | flags, + }; + + for (i = 2; i < argc; i++) { + if (getaddrinfo(argv[i], 0, &hint, &res) != 0) + return RV_NOTFOUND; + + for (r = res; r; r = r->ai_next) { + sockstr = NULL; + if (r->ai_socktype >= 0 && r->ai_socktype < sizeof(socktypes)/sizeof(socktypes[0])) + sockstr = socktypes[r->ai_socktype]; + if (!sockstr) { + sprintf(buf, "%d", r->ai_socktype); + sockstr = sockbuf; + } + switch (r->ai_family) { + case AF_INET: + addr = &((struct sockaddr_in*) r->ai_addr)->sin_addr; + break; + case AF_INET6: + addr = &((struct sockaddr_in6*) r->ai_addr)->sin6_addr; + break; + default: + continue; + } + if (inet_ntop(r->ai_family, addr, buf, sizeof(buf)) == NULL) + (void)strlcpy(buf, "# unknown", sizeof(buf)); + printf("%-15s %-6s %s\n", buf, sockstr, r->ai_canonname ?: ""); + } + } + + return RV_OK; +} + +static int ahosts(int argc, char *argv[]) +{ + return ahosts_ex(AF_UNSPEC, 0, argc, argv); +} + +static int ahostsv4(int argc, char *argv[]) +{ + return ahosts_ex(AF_INET, 0, argc, argv); +} + +static int ahostsv6(int argc, char *argv[]) +{ + return ahosts_ex(AF_INET6, AI_V4MAPPED, argc, argv); +} + +static void networksprint(const struct netent *ne) +{ + char buf[INET6_ADDRSTRLEN]; + struct in_addr ianet; + + ianet = inet_makeaddr(ne->n_net, 0); + if (inet_ntop(ne->n_addrtype, &ianet, buf, sizeof(buf)) == NULL) + (void)strlcpy(buf, "# unknown", sizeof(buf)); + printfmtstrings(ne->n_aliases, " ", " ", "%-16s %s", ne->n_name, buf); +} + +static int networks(int argc, char *argv[]) +{ + struct netent *ne; + in_addr_t net; + int i, rv; + + setnetent(1); + rv = RV_OK; + if (argc == 2) { + while ((ne = getnetent()) != NULL) + networksprint(ne); + } else { + for (i = 2; i < argc; i++) { + net = inet_network(argv[i]); + if (net != INADDR_NONE) + ne = getnetbyaddr(net, AF_INET); + else + ne = getnetbyname(argv[i]); + if (ne != NULL) { + rv = RV_NOTFOUND; + break; + } + networksprint(ne); + } + } + endnetent(); + return rv; +} + +static void passwdprint(struct passwd *pw) +{ + (void)printf("%s:%s:%u:%u:%s:%s:%s\n", + pw->pw_name, pw->pw_passwd, pw->pw_uid, + pw->pw_gid, pw->pw_gecos, pw->pw_dir, pw->pw_shell); +} + +static int passwd(int argc, char *argv[]) +{ + struct passwd *pw; + unsigned long id; + int i, rv; + + rv = RV_OK; + if (argc == 2) { + while ((pw = getpwent()) != NULL) + passwdprint(pw); + } else { + for (i = 2; i < argc; i++) { + if (parsenum(argv[i], &id)) + pw = getpwuid((uid_t)id); + else + pw = getpwnam(argv[i]); + if (pw == NULL) { + rv = RV_NOTFOUND; + break; + } + passwdprint(pw); + } + } + endpwent(); + return rv; +} + +static void protocolsprint(struct protoent *pe) +{ + printfmtstrings(pe->p_aliases, " ", " ", + "%-16s %5d", pe->p_name, pe->p_proto); +} + +static int protocols(int argc, char *argv[]) +{ + struct protoent *pe; + unsigned long id; + int i, rv; + + setprotoent(1); + rv = RV_OK; + if (argc == 2) { + while ((pe = getprotoent()) != NULL) + protocolsprint(pe); + } else { + for (i = 2; i < argc; i++) { + if (parsenum(argv[i], &id)) + pe = getprotobynumber((int)id); + else + pe = getprotobyname(argv[i]); + if (pe == NULL) { + rv = RV_NOTFOUND; + break; + } + protocolsprint(pe); + } + } + endprotoent(); + return rv; +} + +static void servicesprint(struct servent *se) +{ + printfmtstrings(se->s_aliases, " ", " ", + "%-16s %5d/%s", + se->s_name, ntohs(se->s_port), se->s_proto); + +} + +static int services(int argc, char *argv[]) +{ + struct servent *se; + unsigned long id; + char *proto; + int i, rv; + + setservent(1); + rv = RV_OK; + if (argc == 2) { + while ((se = getservent()) != NULL) + servicesprint(se); + } else { + for (i = 2; i < argc; i++) { + proto = strchr(argv[i], '/'); + if (proto != NULL) + *proto++ = '\0'; + if (parsenum(argv[i], &id)) + se = getservbyport(htons(id), proto); + else + se = getservbyname(argv[i], proto); + if (se == NULL) { + rv = RV_NOTFOUND; + break; + } + servicesprint(se); + } + } + endservent(); + return rv; +} + +static int shadow(int argc, char *argv[]) +{ + struct spwd *sp; + int i, rv; + + rv = RV_OK; + if (argc == 2) { + while ((sp = getspent()) != NULL) + putspent(sp, stdout); + } else { + for (i = 2; i < argc; i++) { + sp = getspnam(argv[i]); + if (sp == NULL) { + rv = RV_NOTFOUND; + break; + } + putspent(sp, stdout); + } + } + endspent(); + return rv; +} + +static int shells(int argc, char *argv[]) +{ + const char *sh; + int i, rv; + + setusershell(); + rv = RV_OK; + if (argc == 2) { + while ((sh = getusershell()) != NULL) + (void)printf("%s\n", sh); + } else { + for (i = 2; i < argc; i++) { + setusershell(); + while ((sh = getusershell()) != NULL) { + if (strcmp(sh, argv[i]) == 0) { + (void)printf("%s\n", sh); + break; + } + } + if (sh == NULL) { + rv = RV_NOTFOUND; + break; + } + } + } + endusershell(); + return rv; +} + +static struct getentdb { + const char *name; + int (*callback)(int, char *[]); +} databases[] = { + { "ethers", ethers, }, + { "group", group, }, + { "hosts", hosts, }, + { "ahosts", ahosts, }, + { "ahostsv4", ahostsv4, }, + { "ahostsv6", ahostsv6, }, + { "networks", networks, }, + { "passwd", passwd, }, + { "protocols", protocols, }, + { "services", services, }, + { "shadow", shadow, }, + { "shells", shells, }, + + { NULL, NULL, }, +}; + +static int usage(const char *arg0) +{ + struct getentdb *curdb; + size_t i; + + (void)fprintf(stderr, "Usage: %s database [key ...]\n", arg0); + (void)fprintf(stderr, "\tdatabase may be one of:"); + for (i = 0, curdb = databases; curdb->name != NULL; curdb++, i++) { + if (i % 7 == 0) + (void)fputs("\n\t\t", stderr); + (void)fprintf(stderr, "%s%s", i % 7 == 0 ? "" : " ", + curdb->name); + } + (void)fprintf(stderr, "\n"); + exit(RV_USAGE); + /* NOTREACHED */ +} + +int +main(int argc, char *argv[]) +{ + struct getentdb *curdb; + + if (argc < 2) + usage(argv[0]); + for (curdb = databases; curdb->name != NULL; curdb++) + if (strcmp(curdb->name, argv[1]) == 0) + return (*curdb->callback)(argc, argv); + + warn("Unknown database `%s'", argv[1]); + usage(argv[0]); + /* NOTREACHED */ +} diff --git a/libc/musl/handle-aux-at_base.patch b/libc/musl/handle-aux-at_base.patch new file mode 100644 index 0000000..7c9f2dc --- /dev/null +++ b/libc/musl/handle-aux-at_base.patch @@ -0,0 +1,46 @@ +This is required to make the gcompat ELF interpreter stub work with some +packed binaries. + +diff --git a/src/env/__init_tls.c b/src/env/__init_tls.c +index b125eb1..616c6a6 100644 +--- a/src/env/__init_tls.c ++++ b/src/env/__init_tls.c +@@ -66,8 +66,10 @@ void *__copy_tls(unsigned char *mem) + } + + #if ULONG_MAX == 0xffffffff ++typedef Elf32_Ehdr Ehdr; + typedef Elf32_Phdr Phdr; + #else ++typedef Elf64_Ehdr Ehdr; + typedef Elf64_Phdr Phdr; + #endif + +@@ -77,15 +79,23 @@ extern const size_t _DYNAMIC[]; + static void static_init_tls(size_t *aux) + { + unsigned char *p; +- size_t n; ++ size_t n, e; + Phdr *phdr, *tls_phdr=0; + size_t base = 0; + void *mem; + +- for (p=(void *)aux[AT_PHDR],n=aux[AT_PHNUM]; n; n--,p+=aux[AT_PHENT]) { ++ if (aux[AT_BASE]) { ++ Ehdr *ehdr = (void *)aux[AT_BASE]; ++ p = (unsigned char *)aux[AT_BASE] + ehdr->e_phoff; ++ n = ehdr->e_phnum; ++ e = ehdr->e_phentsize; ++ } else { ++ p = (void *)aux[AT_PHDR]; ++ n = aux[AT_PHNUM]; ++ e = aux[AT_PHENT]; ++ } ++ for (; n; n--, p+=e) { + phdr = (void *)p; +- if (phdr->p_type == PT_PHDR) +- base = aux[AT_PHDR] - phdr->p_vaddr; + if (phdr->p_type == PT_DYNAMIC && _DYNAMIC) + base = (size_t)_DYNAMIC - phdr->p_vaddr; + if (phdr->p_type == PT_TLS) diff --git a/libc/musl/iconv.c b/libc/musl/iconv.c new file mode 100644 index 0000000..f5d5ce2 --- /dev/null +++ b/libc/musl/iconv.c @@ -0,0 +1,110 @@ +/* + * iconv.c + * Implementation of SUSv4 XCU iconv utility + * Copyright © 2011 Rich Felker + * Licensed under the terms of the GNU General Public License, v2 or later + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char **argv) +{ + const char *from=0, *to=0; + int b; + iconv_t cd; + char buf[BUFSIZ]; + char outbuf[BUFSIZ*4]; + char *in, *out; + size_t inb; + size_t l; + size_t unitsize=0; + int err=0; + FILE *f; + + while ((b = getopt(argc, argv, "f:t:csl")) != EOF) switch(b) { + case 'l': + puts("UTF-8, UTF-16BE, UTF-16LE, UTF-32BE, UTF32-LE, UCS-2BE, UCS-2LE, WCHAR_T,\n" + "US_ASCII, ISO8859-1, ISO8859-2, ISO8859-3, ISO8859-4, ISO8859-5,\n" + "ISO8859-6, ISO8859-7, ..."); + exit(0); + case 'c': case 's': break; + case 'f': from=optarg; break; + case 't': to=optarg; break; + default: exit(1); + } + + if (!from || !to) { + setlocale(LC_CTYPE, ""); + if (!to) to = nl_langinfo(CODESET); + if (!from) from = nl_langinfo(CODESET); + } + cd = iconv_open(to, from); + if (cd == (iconv_t)-1) { + if (iconv_open(to, "WCHAR_T") == (iconv_t)-1) + fprintf(stderr, "iconv: destination charset %s: ", to); + else + fprintf(stderr, "iconv: source charset %s: ", from); + perror(""); + exit(1); + } + if (optind == argc) argv[argc++] = "-"; + + for (; optind < argc; optind++) { + if (argv[optind][0]=='-' && !argv[optind][1]) { + f = stdin; + argv[optind] = "(stdin)"; + } else if (!(f = fopen(argv[optind], "rb"))) { + fprintf(stderr, "iconv: %s: ", argv[optind]); + perror(""); + err = 1; + continue; + } + inb = 0; + for (;;) { + in = buf; + out = outbuf; + l = fread(buf+inb, 1, sizeof(buf)-inb, f); + inb += l; + if (!inb) break; + if (iconv(cd, &in, &inb, &out, (size_t [1]){sizeof outbuf})==-1 + && errno == EILSEQ) { + if (!unitsize) { + wchar_t wc='0'; + char dummy[4], *dummyp=dummy; + iconv_t cd2 = iconv_open(from, "WCHAR_T"); + if (cd == (iconv_t)-1) { + unitsize = 1; + } else { + iconv(cd2, + (char *[1]){(char *)&wc}, + (size_t[1]){1}, + &dummyp, (size_t[1]){4}); + unitsize = dummyp-dummy; + if (!unitsize) unitsize=1; + } + } + inb-=unitsize; + in+=unitsize; + } + if (inb && !l && errno==EINVAL) break; + if (out>outbuf && !fwrite(outbuf, out-outbuf, 1, stdout)) { + perror("iconv: write error"); + exit(1); + } + if (inb) memmove(buf, in, inb); + } + if (ferror(f)) { + fprintf(stderr, "iconv: %s: ", argv[optind]); + perror(""); + err = 1; + } + } + return err; +} diff --git a/libc/musl/ldconfig b/libc/musl/ldconfig new file mode 100644 index 0000000..ccf7c2a --- /dev/null +++ b/libc/musl/ldconfig @@ -0,0 +1,18 @@ +#!/bin/sh +scan_dirs() { + scanelf -qS "$@" | while read SONAME FILE; do + TARGET="${FILE##*/}" + LINK="${FILE%/*}/$SONAME" + case "$FILE" in + /lib/*|/usr/lib/*|/usr/local/lib/*) ;; + *) [ -h "$LINK" -o ! -e "$LINK" ] && ln -sf "$TARGET" "$LINK" + esac + done + return 0 +} +# eat ldconfig options +while getopts "nNvXvf:C:r:" opt; do + : +done +shift $(( $OPTIND - 1 )) +[ $# -gt 0 ] && scan_dirs "$@" diff --git a/libc/musl/syscall-cp-epoll.patch b/libc/musl/syscall-cp-epoll.patch new file mode 100644 index 0000000..338620a --- /dev/null +++ b/libc/musl/syscall-cp-epoll.patch @@ -0,0 +1,16 @@ +diff --git a/src/linux/epoll.c b/src/linux/epoll.c +index deff5b10..93baa814 100644 +--- a/src/linux/epoll.c ++++ b/src/linux/epoll.c +@@ -24,9 +24,9 @@ int epoll_ctl(int fd, int op, int fd2, struct epoll_event *ev) + + int epoll_pwait(int fd, struct epoll_event *ev, int cnt, int to, const sigset_t *sigs) + { +- int r = __syscall(SYS_epoll_pwait, fd, ev, cnt, to, sigs, _NSIG/8); ++ int r = __syscall_cp(SYS_epoll_pwait, fd, ev, cnt, to, sigs, _NSIG/8); + #ifdef SYS_epoll_wait +- if (r==-ENOSYS && !sigs) r = __syscall(SYS_epoll_wait, fd, ev, cnt, to); ++ if (r==-ENOSYS && !sigs) r = __syscall_cp(SYS_epoll_wait, fd, ev, cnt, to); + #endif + return __syscall_ret(r); + }