ASR_BASE
Change-Id: Icf3719cc0afe3eeb3edc7fa80a2eb5199ca9dda1
diff --git a/toolchain/glibc/Makefile b/toolchain/glibc/Makefile
new file mode 100644
index 0000000..bfb5598
--- /dev/null
+++ b/toolchain/glibc/Makefile
@@ -0,0 +1,32 @@
+PATH_PREFIX := .
+VARIANT:=final
+HOST_BUILD_PARALLEL:=1
+
+include ./common.mk
+
+define Host/Compile
+ +$(MAKE) -C $(CUR_BUILD_DIR) \
+ PARALLELMFLAGS="$(HOST_JOBS)" \
+ BUILD_CFLAGS="$(HOST_CFLAGS)" \
+ default-rpath="/lib:/usr/lib" \
+ all
+endef
+
+define Host/Install
+ $(call Host/SetToolchainInfo)
+ $(MAKE) -C $(CUR_BUILD_DIR) \
+ BUILD_CFLAGS="$(HOST_CFLAGS)" \
+ install_root="$(TOOLCHAIN_DIR)" \
+ install
+ ( cd $(TOOLCHAIN_DIR) ; \
+ for d in lib usr/lib ; do \
+ for f in libc.so libm.so libpthread.so libgcc_s.so ; do \
+ if [ -f $$$$d/$$$$f -a ! -L $$$$d/$$$$f ] ; then \
+ $(SED) 's,/usr/lib/,,g;s,/lib/,,g' $$$$d/$$$$f ; \
+ fi \
+ done \
+ done \
+ )
+endef
+
+$(eval $(call HostBuild))
diff --git a/toolchain/glibc/common.mk b/toolchain/glibc/common.mk
new file mode 100644
index 0000000..f4c0c66
--- /dev/null
+++ b/toolchain/glibc/common.mk
@@ -0,0 +1,104 @@
+#
+# Copyright (C) 2006-2020 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=glibc
+PKG_VERSION:=2.38
+PKG_RELEASE:=1
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE_VERSION:=e9f05fa1c62c8044ff025963498063f73eb51c5f
+PKG_MIRROR_HASH:=fd61eb2caea0d4100638b8aa8285b0f1bc23af921c376516307c9ab8ac307739
+PKG_SOURCE_URL:=https://sourceware.org/git/glibc.git
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.zst
+PKG_CPE_ID:=cpe:/a:gnu:glibc
+
+HOST_BUILD_DIR:=$(BUILD_DIR_TOOLCHAIN)/$(PKG_SOURCE_SUBDIR)
+CUR_BUILD_DIR:=$(HOST_BUILD_DIR)-$(VARIANT)
+PATCH_DIR:=$(PATH_PREFIX)/patches
+
+include $(INCLUDE_DIR)/toolchain-build.mk
+
+HOST_STAMP_PREPARED:=$(HOST_BUILD_DIR)/.prepared
+HOST_STAMP_CONFIGURED:=$(CUR_BUILD_DIR)/.configured
+HOST_STAMP_BUILT:=$(CUR_BUILD_DIR)/.built
+HOST_STAMP_INSTALLED:=$(TOOLCHAIN_DIR)/stamp/.glibc_$(VARIANT)_installed
+
+ifeq ($(ARCH),mips64)
+ ifdef CONFIG_MIPS64_ABI_N64
+ TARGET_CFLAGS += -mabi=64
+ endif
+ ifdef CONFIG_MIPS64_ABI_N32
+ TARGET_CFLAGS += -mabi=n32
+ endif
+ ifdef CONFIG_MIPS64_ABI_O32
+ TARGET_CFLAGS += -mabi=32
+ endif
+endif
+
+TARGET_CFLAGS := $(filter-out -D_TIME_BITS=64 -D_FILE_OFFSET_BITS=64,$(TARGET_CFLAGS))
+
+# -Os miscompiles w. 2.24 gcc5/gcc6
+# only -O2 tested by upstream changeset
+# "Optimize i386 syscall inlining for GCC 5"
+GLIBC_CONFIGURE:= \
+ unset LD_LIBRARY_PATH; \
+ BUILD_CC="$(HOSTCC)" \
+ $(TARGET_CONFIGURE_OPTS) \
+ CFLAGS="-O2 $(filter-out -Os,$(call qstrip,$(TARGET_CFLAGS)))" \
+ libc_cv_slibdir="/lib" \
+ use_ldconfig=no \
+ $(HOST_BUILD_DIR)/$(GLIBC_PATH)configure \
+ --prefix= \
+ --build=$(GNU_HOST_NAME) \
+ --host=$(REAL_GNU_TARGET_NAME) \
+ --with-headers=$(TOOLCHAIN_DIR)/include \
+ --disable-profile \
+ --disable-werror \
+ --without-gd \
+ --without-cvs \
+ --enable-add-ons \
+ --enable-crypt \
+ --$(if $(CONFIG_SOFT_FLOAT),without,with)-fp \
+ $(if $(CONFIG_PKG_CC_STACKPROTECTOR_REGULAR),--enable-stack-protector=yes) \
+ $(if $(CONFIG_PKG_CC_STACKPROTECTOR_STRONG),--enable-stack-protector=strong) \
+ $(if $(CONFIG_PKG_CC_STACKPROTECTOR_ALL),--enable-stack-protector=all) \
+ $(if $(CONFIG_PKG_RELRO_FULL),--enable-bind-now) \
+ $(if $(CONFIG_PKG_FORTIFY_SOURCE_1),--enable-fortify-source=1) \
+ $(if $(CONFIG_PKG_FORTIFY_SOURCE_2),--enable-fortify-source=2) \
+ --enable-kernel=4.14.0
+
+export libc_cv_ssp=no
+export libc_cv_ssp_strong=no
+export ac_cv_header_cpuid_h=yes
+export HOST_CFLAGS := $(HOST_CFLAGS) -idirafter $(CURDIR)/$(PATH_PREFIX)/include
+
+define Host/SetToolchainInfo
+ $(SED) 's,^\(LIBC_TYPE\)=.*,\1=$(PKG_NAME),' $(TOOLCHAIN_DIR)/info.mk
+ $(SED) 's,^\(LIBC_URL\)=.*,\1=http://www.gnu.org/software/libc/,' $(TOOLCHAIN_DIR)/info.mk
+ $(SED) 's,^\(LIBC_VERSION\)=.*,\1=$(PKG_VERSION),' $(TOOLCHAIN_DIR)/info.mk
+ $(SED) 's,^\(LIBC_SO_VERSION\)=.*,\1=$(PKG_VERSION),' $(TOOLCHAIN_DIR)/info.mk
+endef
+
+define Host/Configure
+ mkdir -p $(CUR_BUILD_DIR)
+ ( cd $(CUR_BUILD_DIR); rm -f config.cache; \
+ $(GLIBC_CONFIGURE) \
+ );
+endef
+
+define Host/Prepare
+ $(call Host/Prepare/Default)
+ ln -snf $(PKG_SOURCE_SUBDIR) $(BUILD_DIR_TOOLCHAIN)/$(PKG_NAME)
+endef
+
+define Host/Clean
+ rm -rf $(CUR_BUILD_DIR)* \
+ $(BUILD_DIR_TOOLCHAIN)/$(LIBC)-dev \
+ $(BUILD_DIR_TOOLCHAIN)/$(PKG_NAME)
+endef
diff --git a/toolchain/glibc/headers/Makefile b/toolchain/glibc/headers/Makefile
new file mode 100644
index 0000000..f1d8a8b
--- /dev/null
+++ b/toolchain/glibc/headers/Makefile
@@ -0,0 +1,28 @@
+PATH_PREFIX:=..
+VARIANT:=headers
+
+include ../common.mk
+
+define Host/Compile
+
+endef
+
+define Host/Install
+ $(call Host/SetToolchainInfo)
+ mkdir -p $(BUILD_DIR_TOOLCHAIN)/$(LIBC)-dev/{include,lib}
+ $(MAKE) -C $(CUR_BUILD_DIR) \
+ BUILD_CFLAGS="$(HOST_CFLAGS)" \
+ install_root="$(BUILD_DIR_TOOLCHAIN)/$(LIBC)-dev" \
+ install-bootstrap-headers=yes \
+ install-headers
+ $(CP) $(BUILD_DIR_TOOLCHAIN)/linux-dev/* $(BUILD_DIR_TOOLCHAIN)/$(LIBC)-dev/
+ $(MAKE) -C $(CUR_BUILD_DIR) \
+ csu/subdir_lib
+ ( cd $(CUR_BUILD_DIR); \
+ $(CP) csu/crt1.o csu/crti.o csu/crtn.o $(BUILD_DIR_TOOLCHAIN)/$(LIBC)-dev/lib/ \
+ )
+ $(TARGET_CC) -nostdlib -nostartfiles -shared -x c /dev/null \
+ -o $(BUILD_DIR_TOOLCHAIN)/$(LIBC)-dev/lib/libc.so
+endef
+
+$(eval $(call HostBuild))
diff --git a/toolchain/glibc/include/libintl.h b/toolchain/glibc/include/libintl.h
new file mode 100644
index 0000000..69cb887
--- /dev/null
+++ b/toolchain/glibc/include/libintl.h
@@ -0,0 +1,6 @@
+#ifndef __FAKE_LIBINTL_H
+#define __FAKE_LIBINTL_H
+
+#define _(X) (X)
+
+#endif
diff --git a/toolchain/glibc/patches/050-Revert-Disallow-use-of-DES-encryption-functions-in-n.patch b/toolchain/glibc/patches/050-Revert-Disallow-use-of-DES-encryption-functions-in-n.patch
new file mode 100644
index 0000000..771cb4c
--- /dev/null
+++ b/toolchain/glibc/patches/050-Revert-Disallow-use-of-DES-encryption-functions-in-n.patch
@@ -0,0 +1,677 @@
+From 08f5e0df46ce1ad617bcde1fd5542545397630b9 Mon Sep 17 00:00:00 2001
+From: Hans Dedecker <dedeckeh@gmail.com>
+Date: Sat, 24 Oct 2020 21:13:30 +0200
+Subject: Revert "Disallow use of DES encryption functions in new programs."
+
+This reverts commit b10a0accee709a5efff2fadf0b0bbb79ff0ad759.
+
+ppp still uses the encrypt functions from the libc while musl libc also
+provides them.
+---
+ conform/data/stdlib.h-data | 3 +
+ conform/data/unistd.h-data | 6 ++
+ crypt/cert.c | 26 -----
+ crypt/crypt-entry.c | 15 ++-
+ crypt/crypt.h | 16 +++
+ crypt/crypt_util.c | 9 --
+ manual/conf.texi | 2 -
+ manual/crypt.texi | 204 +++++++++++++++++++++++++++++++++++++
+ manual/string.texi | 82 +++++++--------
+ posix/unistd.h | 17 +++-
+ stdlib/stdlib.h | 6 ++
+ sunrpc/des_crypt.c | 7 +-
+ sunrpc/des_soft.c | 2 +-
+ 13 files changed, 305 insertions(+), 90 deletions(-)
+
+--- a/conform/data/stdlib.h-data
++++ b/conform/data/stdlib.h-data
+@@ -149,6 +149,9 @@ function {unsigned short int*} seed48 (u
+ #if !defined ISO && !defined ISO99 && !defined ISO11 && !defined POSIX && !defined XPG4 && !defined XPG42 && !defined UNIX98
+ function int setenv (const char*, const char*, int)
+ #endif
++#if !defined ISO && !defined ISO99 && !defined ISO11 && !defined POSIX && !defined POSIX2008
++function void setkey (const char*)
++#endif
+ #if !defined ISO && !defined ISO99 && !defined ISO11 && !defined XPG4 && !defined POSIX && !defined POSIX2008
+ function {char*} setstate (char*)
+ #endif
+--- a/conform/data/unistd.h-data
++++ b/conform/data/unistd.h-data
+@@ -437,6 +437,9 @@ function int chroot (const char*)
+ function int chown (const char*, uid_t, gid_t)
+ function int close (int)
+ function size_t confstr (int, char*, size_t)
++#if !defined POSIX && !defined POSIX2008
++function {char*} crypt (const char*, const char*)
++#endif
+ #if defined XPG4 || defined XPG42 || defined UNIX98
+ function {char*} ctermid (char*)
+ function {char*} cuserid (char*)
+@@ -446,6 +449,9 @@ allow cuserid
+ #endif
+ function int dup (int)
+ function int dup2 (int, int)
++#if !defined POSIX && !defined POSIX2008
++function void encrypt (char[64], int)
++#endif
+ function int execl (const char*, const char*, ...)
+ function int execle (const char*, const char*, ...)
+ function int execlp (const char*, const char*, ...)
+--- a/crypt/cert.c
++++ b/crypt/cert.c
+@@ -10,22 +10,6 @@
+ #include <stdlib.h>
+ #include "crypt.h"
+
+-/* This file tests the deprecated setkey/encrypt interface. */
+-#include <shlib-compat.h>
+-#if TEST_COMPAT (libcrypt, GLIBC_2_0, GLIBC_2_28)
+-
+-#define libcrypt_version_reference(symbol, version) \
+- _libcrypt_version_reference (symbol, VERSION_libcrypt_##version)
+-#define _libcrypt_version_reference(symbol, version) \
+- __libcrypt_version_reference (symbol, version)
+-#define __libcrypt_version_reference(symbol, version) \
+- __asm__ (".symver " #symbol ", " #symbol "@" #version)
+-
+-extern void setkey (const char *);
+-extern void encrypt (const char *, int);
+-libcrypt_version_reference (setkey, GLIBC_2_0);
+-libcrypt_version_reference (encrypt, GLIBC_2_0);
+-
+ int totfails = 0;
+
+ int main (int argc, char *argv[]);
+@@ -123,13 +107,3 @@ put8 (char *cp)
+ printf("%02x", t);
+ }
+ }
+-
+-#else /* encrypt and setkey are not available. */
+-
+-int
+-main (void)
+-{
+- return 77; /* UNSUPPORTED */
+-}
+-
+-#endif
+--- a/crypt/crypt-entry.c
++++ b/crypt/crypt-entry.c
+@@ -35,7 +35,6 @@
+ #endif
+
+ #include "crypt-private.h"
+-#include <shlib-compat.h>
+
+ /* Prototypes for local functions. */
+ #ifndef __GNU_LIBRARY__
+@@ -177,7 +176,17 @@ crypt (const char *key, const char *salt
+ return __crypt_r (key, salt, &_ufc_foobar);
+ }
+
+-#if SHLIB_COMPAT (libcrypt, GLIBC_2_0, GLIBC_2_28)
++
++/*
++ * To make fcrypt users happy.
++ * They don't need to call init_des.
++ */
++#ifdef _LIBC
+ weak_alias (crypt, fcrypt)
+-compat_symbol (libcrypt, fcrypt, fcrypt, GLIBC_2_0);
++#else
++char *
++__fcrypt (const char *key, const char *salt)
++{
++ return crypt (key, salt);
++}
+ #endif
+--- a/crypt/crypt.h
++++ b/crypt/crypt.h
+@@ -36,6 +36,14 @@ __BEGIN_DECLS
+ extern char *crypt (const char *__phrase, const char *__salt)
+ __THROW __nonnull ((1, 2));
+
++/* Setup DES tables according KEY. */
++extern void setkey (const char *__key) __THROW __nonnull ((1));
++
++/* Encrypt data in BLOCK in place if EDFLAG is zero; otherwise decrypt
++ block in place. */
++extern void encrypt (char *__glibc_block, int __edflag)
++ __THROW __nonnull ((1));
++
+ #ifdef __USE_GNU
+
+ /* This structure provides scratch and output buffers for 'crypt_r'.
+@@ -63,6 +71,14 @@ struct crypt_data
+ extern char *crypt_r (const char *__phrase, const char *__salt,
+ struct crypt_data * __restrict __data)
+ __THROW __nonnull ((1, 2, 3));
++
++extern void setkey_r (const char *__key,
++ struct crypt_data * __restrict __data)
++ __THROW __nonnull ((1, 2));
++
++extern void encrypt_r (char *__glibc_block, int __edflag,
++ struct crypt_data * __restrict __data)
++ __THROW __nonnull ((1, 3));
+ #endif
+
+ __END_DECLS
+--- a/crypt/crypt_util.c
++++ b/crypt/crypt_util.c
+@@ -34,7 +34,6 @@
+ #endif
+
+ #include "crypt-private.h"
+-#include <shlib-compat.h>
+
+ /* Prototypes for local functions. */
+ #ifndef __GNU_LIBRARY__
+@@ -151,7 +150,6 @@ static const int sbox[8][4][16]= {
+ }
+ };
+
+-#if SHLIB_COMPAT (libcrypt, GLIBC_2_0, GLIBC_2_28)
+ /*
+ * This is the initial
+ * permutation matrix
+@@ -162,7 +160,6 @@ static const int initial_perm[64] = {
+ 57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3,
+ 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7
+ };
+-#endif
+
+ /*
+ * This is the final
+@@ -788,7 +785,6 @@ _ufc_output_conversion_r (ufc_long v1, u
+ __data->crypt_3_buf[13] = 0;
+ }
+
+-#if SHLIB_COMPAT (libcrypt, GLIBC_2_0, GLIBC_2_28)
+
+ /*
+ * UNIX encrypt function. Takes a bitvector
+@@ -889,14 +885,12 @@ __encrypt_r (char *__block, int __edflag
+ }
+ }
+ weak_alias (__encrypt_r, encrypt_r)
+-compat_symbol (libcrypt, encrypt_r, encrypt_r, GLIBC_2_0);
+
+ void
+ encrypt (char *__block, int __edflag)
+ {
+ __encrypt_r(__block, __edflag, &_ufc_foobar);
+ }
+-compat_symbol (libcrypt, encrypt, encrypt, GLIBC_2_0);
+
+
+ /*
+@@ -921,15 +915,12 @@ __setkey_r (const char *__key, struct cr
+ _ufc_mk_keytab_r((char *) ktab, __data);
+ }
+ weak_alias (__setkey_r, setkey_r)
+-compat_symbol (libcrypt, setkey_r, setkey_r, GLIBC_2_0);
+
+ void
+ setkey (const char *__key)
+ {
+ __setkey_r(__key, &_ufc_foobar);
+ }
+-compat_symbol (libcrypt, setkey, setkey, GLIBC_2_0);
+-#endif /* SHLIB_COMPAT (libcrypt, GLIBC_2_0, GLIBC_2_28) */
+
+ void
+ __b64_from_24bit (char **cp, int *buflen,
+--- a/manual/conf.texi
++++ b/manual/conf.texi
+@@ -780,8 +780,6 @@ Inquire about the parameter correspondin
+ @item _SC_XOPEN_CRYPT
+ @standards{X/Open, unistd.h}
+ Inquire about the parameter corresponding to @code{_XOPEN_CRYPT}.
+-@Theglibc no longer implements the @code{_XOPEN_CRYPT} extensions,
+-so @samp{sysconf (_SC_XOPEN_CRYPT)} always returns @code{-1}.
+
+ @item _SC_XOPEN_ENH_I18N
+ @standards{X/Open, unistd.h}
+--- a/manual/crypt.texi
++++ b/manual/crypt.texi
+@@ -16,8 +16,19 @@ subject to them, even if you do not use
+ yourself. The restrictions vary from place to place and are changed
+ often, so we cannot give any more specific advice than this warning.
+
++@vindex AUTH_DES
++@cindex FIPS 140-2
++It also provides support for Secure RPC, and some library functions that
++can be used to perform normal DES encryption. The @code{AUTH_DES}
++authentication flavor in Secure RPC, as provided by @theglibc{},
++uses DES and does not comply with FIPS 140-2 nor does any other use of DES
++within @theglibc{}. It is recommended that Secure RPC should not be used
++for systems that need to comply with FIPS 140-2 since all flavors of
++encrypted authentication use normal DES.
++
+ @menu
+ * Passphrase Storage:: One-way hashing for passphrases.
++* crypt:: A one-way function for passwords.
+ * Unpredictable Bytes:: Randomness for cryptographic purposes.
+ @end menu
+
+@@ -190,6 +201,199 @@ unpredictable as possible; @pxref{Unpred
+ @include genpass.c.texi
+ @end smallexample
+
++@node DES Encryption
++@section DES Encryption
++
++@cindex FIPS 46-3
++The Data Encryption Standard is described in the US Government Federal
++Information Processing Standards (FIPS) 46-3 published by the National
++Institute of Standards and Technology. The DES has been very thoroughly
++analyzed since it was developed in the late 1970s, and no new
++significant flaws have been found.
++
++However, the DES uses only a 56-bit key (plus 8 parity bits), and a
++machine has been built in 1998 which can search through all possible
++keys in about 6 days, which cost about US$200000; faster searches would
++be possible with more money. This makes simple DES insecure for most
++purposes, and NIST no longer permits new US government systems
++to use simple DES.
++
++For serious encryption functionality, it is recommended that one of the
++many free encryption libraries be used instead of these routines.
++
++The DES is a reversible operation which takes a 64-bit block and a
++64-bit key, and produces another 64-bit block. Usually the bits are
++numbered so that the most-significant bit, the first bit, of each block
++is numbered 1.
++
++Under that numbering, every 8th bit of the key (the 8th, 16th, and so
++on) is not used by the encryption algorithm itself. But the key must
++have odd parity; that is, out of bits 1 through 8, and 9 through 16, and
++so on, there must be an odd number of `1' bits, and this completely
++specifies the unused bits.
++
++@deftypefun void setkey (const char *@var{key})
++@standards{BSD, crypt.h}
++@standards{SVID, crypt.h}
++@safety{@prelim{}@mtunsafe{@mtasurace{:crypt}}@asunsafe{@asucorrupt{} @asulock{}}@acunsafe{@aculock{}}}
++@c The static buffer stores the key, making it fundamentally
++@c thread-unsafe. The locking issues are only in the initialization
++@c path; cancelling the initialization will leave the lock held, it
++@c would otherwise repeat the initialization on the next call.
++
++The @code{setkey} function sets an internal data structure to be an
++expanded form of @var{key}. @var{key} is specified as an array of 64
++bits each stored in a @code{char}, the first bit is @code{key[0]} and
++the 64th bit is @code{key[63]}. The @var{key} should have the correct
++parity.
++@end deftypefun
++
++@deftypefun void encrypt (char *@var{block}, int @var{edflag})
++@standards{BSD, crypt.h}
++@standards{SVID, crypt.h}
++@safety{@prelim{}@mtunsafe{@mtasurace{:crypt}}@asunsafe{@asucorrupt{} @asulock{}}@acunsafe{@aculock{}}}
++@c Same issues as setkey.
++
++The @code{encrypt} function encrypts @var{block} if
++@var{edflag} is 0, otherwise it decrypts @var{block}, using a key
++previously set by @code{setkey}. The result is
++placed in @var{block}.
++
++Like @code{setkey}, @var{block} is specified as an array of 64 bits each
++stored in a @code{char}, but there are no parity bits in @var{block}.
++@end deftypefun
++
++@deftypefun void setkey_r (const char *@var{key}, {struct crypt_data *} @var{data})
++@deftypefunx void encrypt_r (char *@var{block}, int @var{edflag}, {struct crypt_data *} @var{data})
++@standards{GNU, crypt.h}
++@c setkey_r: @safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{} @asulock{}}@acunsafe{@aculock{}}}
++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{} @asulock{}}@acunsafe{@aculock{}}}
++
++These are reentrant versions of @code{setkey} and @code{encrypt}. The
++only difference is the extra parameter, which stores the expanded
++version of @var{key}. Before calling @code{setkey_r} the first time,
++@code{data->initialized} must be cleared to zero.
++@end deftypefun
++
++The @code{setkey_r} and @code{encrypt_r} functions are GNU extensions.
++@code{setkey}, @code{encrypt}, @code{setkey_r}, and @code{encrypt_r} are
++defined in @file{crypt.h}.
++
++@deftypefun int ecb_crypt (char *@var{key}, char *@var{blocks}, unsigned int @var{len}, unsigned int @var{mode})
++@standards{SUNRPC, rpc/des_crypt.h}
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++
++The function @code{ecb_crypt} encrypts or decrypts one or more blocks
++using DES. Each block is encrypted independently.
++
++The @var{blocks} and the @var{key} are stored packed in 8-bit bytes, so
++that the first bit of the key is the most-significant bit of
++@code{key[0]} and the 63rd bit of the key is stored as the
++least-significant bit of @code{key[7]}. The @var{key} should have the
++correct parity.
++
++@var{len} is the number of bytes in @var{blocks}. It should be a
++multiple of 8 (so that there are a whole number of blocks to encrypt).
++@var{len} is limited to a maximum of @code{DES_MAXDATA} bytes.
++
++The result of the encryption replaces the input in @var{blocks}.
++
++The @var{mode} parameter is the bitwise OR of two of the following:
++
++@vtable @code
++@item DES_ENCRYPT
++@standards{SUNRPC, rpc/des_crypt.h}
++This constant, used in the @var{mode} parameter, specifies that
++@var{blocks} is to be encrypted.
++
++@item DES_DECRYPT
++@standards{SUNRPC, rpc/des_crypt.h}
++This constant, used in the @var{mode} parameter, specifies that
++@var{blocks} is to be decrypted.
++
++@item DES_HW
++@standards{SUNRPC, rpc/des_crypt.h}
++This constant, used in the @var{mode} parameter, asks to use a hardware
++device. If no hardware device is available, encryption happens anyway,
++but in software.
++
++@item DES_SW
++@standards{SUNRPC, rpc/des_crypt.h}
++This constant, used in the @var{mode} parameter, specifies that no
++hardware device is to be used.
++@end vtable
++
++The result of the function will be one of these values:
++
++@vtable @code
++@item DESERR_NONE
++@standards{SUNRPC, rpc/des_crypt.h}
++The encryption succeeded.
++
++@item DESERR_NOHWDEVICE
++@standards{SUNRPC, rpc/des_crypt.h}
++The encryption succeeded, but there was no hardware device available.
++
++@item DESERR_HWERROR
++@standards{SUNRPC, rpc/des_crypt.h}
++The encryption failed because of a hardware problem.
++
++@item DESERR_BADPARAM
++@standards{SUNRPC, rpc/des_crypt.h}
++The encryption failed because of a bad parameter, for instance @var{len}
++is not a multiple of 8 or @var{len} is larger than @code{DES_MAXDATA}.
++@end vtable
++@end deftypefun
++
++@deftypefun int DES_FAILED (int @var{err})
++@standards{SUNRPC, rpc/des_crypt.h}
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++This macro returns 1 if @var{err} is a `success' result code from
++@code{ecb_crypt} or @code{cbc_crypt}, and 0 otherwise.
++@end deftypefun
++
++@deftypefun int cbc_crypt (char *@var{key}, char *@var{blocks}, unsigned int @var{len}, unsigned int @var{mode}, char *@var{ivec})
++@standards{SUNRPC, rpc/des_crypt.h}
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++
++The function @code{cbc_crypt} encrypts or decrypts one or more blocks
++using DES in Cipher Block Chaining mode.
++
++For encryption in CBC mode, each block is exclusive-ored with @var{ivec}
++before being encrypted, then @var{ivec} is replaced with the result of
++the encryption, then the next block is processed. Decryption is the
++reverse of this process.
++
++This has the advantage that blocks which are the same before being
++encrypted are very unlikely to be the same after being encrypted, making
++it much harder to detect patterns in the data.
++
++Usually, @var{ivec} is set to 8 random bytes before encryption starts.
++Then the 8 random bytes are transmitted along with the encrypted data
++(without themselves being encrypted), and passed back in as @var{ivec}
++for decryption. Another possibility is to set @var{ivec} to 8 zeroes
++initially, and have the first block encrypted consist of 8 random
++bytes.
++
++Otherwise, all the parameters are similar to those for @code{ecb_crypt}.
++@end deftypefun
++
++@deftypefun void des_setparity (char *@var{key})
++@standards{SUNRPC, rpc/des_crypt.h}
++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
++
++The function @code{des_setparity} changes the 64-bit @var{key}, stored
++packed in 8-bit bytes, to have odd parity by altering the low bits of
++each byte.
++@end deftypefun
++
++The @code{ecb_crypt}, @code{cbc_crypt}, and @code{des_setparity}
++functions and their accompanying macros are all defined in the header
++@file{rpc/des_crypt.h}.
++
++@node Unpredictable Bytes
++@section Generating Unpredictable Bytes
++
+ The next program demonstrates how to verify a passphrase. It checks a
+ hash hardcoded into the program, because looking up real users' hashed
+ passphrases may require special privileges (@pxref{User Database}).
+--- a/manual/string.texi
++++ b/manual/string.texi
+@@ -36,8 +36,8 @@ too.
+ for delimiters.
+ * Erasing Sensitive Data:: Clearing memory which contains sensitive
+ data, after it's no longer needed.
+-* Shuffling Bytes:: Or how to flash-cook a string.
+-* Obfuscating Data:: Reversibly obscuring data from casual view.
++* strfry:: Function for flash-cooking a string.
++* Trivial Encryption:: Obscuring data.
+ * Encode Binary Data:: Encoding and Decoding of Binary Data.
+ * Argz and Envz Vectors:: Null-separated string vectors.
+ @end menu
+@@ -2512,73 +2512,73 @@ functionality under a different name, su
+ systems it may be in @file{strings.h} instead.
+ @end deftypefun
+
+-
+-@node Shuffling Bytes
+-@section Shuffling Bytes
++@node strfry
++@section strfry
+
+ The function below addresses the perennial programming quandary: ``How do
+ I take good data in string form and painlessly turn it into garbage?''
+-This is not a difficult thing to code for oneself, but the authors of
+-@theglibc{} wish to make it as convenient as possible.
++This is actually a fairly simple task for C programmers who do not use
++@theglibc{} string functions, but for programs based on @theglibc{},
++the @code{strfry} function is the preferred method for
++destroying string data.
+
+-To @emph{erase} data, use @code{explicit_bzero} (@pxref{Erasing
+-Sensitive Data}); to obfuscate it reversibly, use @code{memfrob}
+-(@pxref{Obfuscating Data}).
++The prototype for this function is in @file{string.h}.
+
+ @deftypefun {char *} strfry (char *@var{string})
+ @standards{GNU, string.h}
+ @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+ @c Calls initstate_r, time, getpid, strlen, and random_r.
+
+-@code{strfry} performs an in-place shuffle on @var{string}. Each
+-character is swapped to a position selected at random, within the
+-portion of the string starting with the character's original position.
+-(This is the Fisher-Yates algorithm for unbiased shuffling.)
+-
+-Calling @code{strfry} will not disturb any of the random number
+-generators that have global state (@pxref{Pseudo-Random Numbers}).
++@code{strfry} creates a pseudorandom anagram of a string, replacing the
++input with the anagram in place. For each position in the string,
++@code{strfry} swaps it with a position in the string selected at random
++(from a uniform distribution). The two positions may be the same.
+
+ The return value of @code{strfry} is always @var{string}.
+
+ @strong{Portability Note:} This function is unique to @theglibc{}.
+-It is declared in @file{string.h}.
++
+ @end deftypefun
+
+
+-@node Obfuscating Data
+-@section Obfuscating Data
++@node Trivial Encryption
++@section Trivial Encryption
++@cindex encryption
++
++
++The @code{memfrob} function converts an array of data to something
++unrecognizable and back again. It is not encryption in its usual sense
++since it is easy for someone to convert the encrypted data back to clear
++text. The transformation is analogous to Usenet's ``Rot13'' encryption
++method for obscuring offensive jokes from sensitive eyes and such.
++Unlike Rot13, @code{memfrob} works on arbitrary binary data, not just
++text.
+ @cindex Rot13
+
+-The @code{memfrob} function reversibly obfuscates an array of binary
+-data. This is not true encryption; the obfuscated data still bears a
+-clear relationship to the original, and no secret key is required to
+-undo the obfuscation. It is analogous to the ``Rot13'' cipher used on
+-Usenet for obscuring offensive jokes, spoilers for works of fiction,
+-and so on, but it can be applied to arbitrary binary data.
+-
+-Programs that need true encryption---a transformation that completely
+-obscures the original and cannot be reversed without knowledge of a
+-secret key---should use a dedicated cryptography library, such as
+-@uref{https://www.gnu.org/software/libgcrypt/,,libgcrypt}.
+-
+-Programs that need to @emph{destroy} data should use
+-@code{explicit_bzero} (@pxref{Erasing Sensitive Data}), or possibly
+-@code{strfry} (@pxref{Shuffling Bytes}).
++For true encryption, @xref{Cryptographic Functions}.
++
++This function is declared in @file{string.h}.
++@pindex string.h
+
+ @deftypefun {void *} memfrob (void *@var{mem}, size_t @var{length})
+ @standards{GNU, string.h}
+ @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+
+-The function @code{memfrob} obfuscates @var{length} bytes of data
+-beginning at @var{mem}, in place. Each byte is bitwise xor-ed with
+-the binary pattern 00101010 (hexadecimal 0x2A). The return value is
+-always @var{mem}.
+-
+-@code{memfrob} a second time on the same data returns it to
+-its original state.
++@code{memfrob} transforms (frobnicates) each byte of the data structure
++at @var{mem}, which is @var{length} bytes long, by bitwise exclusive
++oring it with binary 00101010. It does the transformation in place and
++its return value is always @var{mem}.
++
++Note that @code{memfrob} a second time on the same data structure
++returns it to its original state.
++
++This is a good function for hiding information from someone who doesn't
++want to see it or doesn't want to see it very much. To really prevent
++people from retrieving the information, use stronger encryption such as
++that described in @xref{Cryptographic Functions}.
+
+ @strong{Portability Note:} This function is unique to @theglibc{}.
+-It is declared in @file{string.h}.
++
+ @end deftypefun
+
+ @node Encode Binary Data
+--- a/posix/unistd.h
++++ b/posix/unistd.h
+@@ -107,6 +107,9 @@ __BEGIN_DECLS
+ /* The X/Open Unix extensions are available. */
+ #define _XOPEN_UNIX 1
+
++/* Encryption is present. */
++#define _XOPEN_CRYPT 1
++
+ /* The enhanced internationalization capabilities according to XPG4.2
+ are present. */
+ #define _XOPEN_ENH_I18N 1
+@@ -1150,17 +1153,25 @@ ssize_t copy_file_range (int __infd, __o
+ extern int fdatasync (int __fildes);
+ #endif /* Use POSIX199309 */
+
+-#ifdef __USE_MISC
++/* XPG4.2 specifies that prototypes for the encryption functions must
++ be defined here. */
++#ifdef __USE_XOPEN
+ /* One-way hash PHRASE, returning a string suitable for storage in the
+ user database. SALT selects the one-way function to use, and
+ ensures that no two users' hashes are the same, even if they use
+ the same passphrase. The return value points to static storage
+ which will be overwritten by the next call to crypt. */
++
++/* Encrypt at most 8 characters from KEY using salt to perturb DES. */
+ extern char *crypt (const char *__key, const char *__salt)
+ __THROW __nonnull ((1, 2));
+-#endif
+
+-#ifdef __USE_XOPEN
++/* Encrypt data in BLOCK in place if EDFLAG is zero; otherwise decrypt
++ block in place. */
++extern void encrypt (char *__glibc_block, int __edflag)
++ __THROW __nonnull ((1));
++
++
+ /* Swab pairs bytes in the first N bytes of the area pointed to by
+ FROM and copy the result to TO. The value of TO must not be in the
+ range [FROM - N + 1, FROM - 1]. If N is odd the first byte in FROM
+--- a/stdlib/stdlib.h
++++ b/stdlib/stdlib.h
+@@ -1103,6 +1103,12 @@ extern int getsubopt (char **__restrict
+ #endif
+
+
++#ifdef __USE_XOPEN
++/* Setup DES tables according KEY. */
++extern void setkey (const char *__key) __THROW __nonnull ((1));
++#endif
++
++
+ /* X/Open pseudo terminal handling. */
+
+ #ifdef __USE_XOPEN2KXSI
+--- a/sunrpc/des_crypt.c
++++ b/sunrpc/des_crypt.c
+@@ -86,9 +86,6 @@ common_crypt (char *key, char *buf, regi
+ return desdev == DES_SW ? DESERR_NONE : DESERR_NOHWDEVICE;
+ }
+
+-/* Note: these cannot be excluded from the build yet, because they are
+- still used internally. */
+-
+ /*
+ * CBC mode encryption
+ */
+@@ -105,7 +102,7 @@ cbc_crypt (char *key, char *buf, unsigne
+ COPY8 (dp.des_ivec, ivec);
+ return err;
+ }
+-hidden_nolink (cbc_crypt, libc, GLIBC_2_1)
++libc_hidden_nolink_sunrpc (cbc_crypt, GLIBC_2_1)
+
+ /*
+ * ECB mode encryption
+@@ -118,4 +115,4 @@ ecb_crypt (char *key, char *buf, unsigne
+ dp.des_mode = ECB;
+ return common_crypt (key, buf, len, mode, &dp);
+ }
+-hidden_nolink (ecb_crypt, libc, GLIBC_2_1)
++libc_hidden_nolink_sunrpc (ecb_crypt, GLIBC_2_1)
+--- a/sunrpc/des_soft.c
++++ b/sunrpc/des_soft.c
+@@ -71,4 +71,4 @@ des_setparity (char *p)
+ p++;
+ }
+ }
+-hidden_nolink (des_setparity, libc, GLIBC_2_1)
++libc_hidden_nolink_sunrpc (des_setparity, GLIBC_2_1)
diff --git a/toolchain/glibc/patches/100-fix_cross_rpcgen.patch b/toolchain/glibc/patches/100-fix_cross_rpcgen.patch
new file mode 100644
index 0000000..9baed08
--- /dev/null
+++ b/toolchain/glibc/patches/100-fix_cross_rpcgen.patch
@@ -0,0 +1,36 @@
+--- a/sunrpc/rpc/types.h
++++ b/sunrpc/rpc/types.h
+@@ -75,18 +75,23 @@ typedef unsigned long rpcport_t;
+ #endif
+
+ #ifndef __u_char_defined
+-typedef __u_char u_char;
+-typedef __u_short u_short;
+-typedef __u_int u_int;
+-typedef __u_long u_long;
+-typedef __quad_t quad_t;
+-typedef __u_quad_t u_quad_t;
+-typedef __fsid_t fsid_t;
++typedef unsigned char u_char;
++typedef unsigned short u_short;
++typedef unsigned int u_int;
++typedef unsigned long u_long;
++#if __WORDSIZE == 64
++typedef long int quad_t;
++typedef unsigned long int u_quad_t;
++#elif defined __GLIBC_HAVE_LONG_LONG
++typedef long long int quad_t;
++typedef unsigned long long int u_quad_t;
++#endif
++typedef u_quad_t fsid_t;
+ # define __u_char_defined
+ #endif
+-#ifndef __daddr_t_defined
+-typedef __daddr_t daddr_t;
+-typedef __caddr_t caddr_t;
++#if !defined(__daddr_t_defined) && defined(linux)
++typedef long int daddr_t;
++typedef char *caddr_t;
+ # define __daddr_t_defined
+ #endif
+
diff --git a/toolchain/glibc/patches/200-add-dl-search-paths.patch b/toolchain/glibc/patches/200-add-dl-search-paths.patch
new file mode 100644
index 0000000..1510654
--- /dev/null
+++ b/toolchain/glibc/patches/200-add-dl-search-paths.patch
@@ -0,0 +1,14 @@
+add /usr/lib to default search path for the dynamic linker
+
+--- a/Makeconfig
++++ b/Makeconfig
+@@ -632,6 +632,9 @@ else
+ default-rpath = $(libdir)
+ endif
+
++# Add /usr/lib to default search path for the dynamic linker
++user-defined-trusted-dirs := /usr/lib
++
+ ifndef link-extra-libs
+ link-extra-libs = $(LDLIBS-$(@F))
+ link-extra-libs-static = $(link-extra-libs)
diff --git a/toolchain/glibc/patches/500-fix-building-arm-thumb.patch b/toolchain/glibc/patches/500-fix-building-arm-thumb.patch
new file mode 100644
index 0000000..05d56f0
--- /dev/null
+++ b/toolchain/glibc/patches/500-fix-building-arm-thumb.patch
@@ -0,0 +1,11 @@
+--- a/configure
++++ b/configure
+@@ -6882,7 +6882,7 @@ fi
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libc_cv_as_noexecstack" >&5
+ printf "%s\n" "$libc_cv_as_noexecstack" >&6; }
+ if test $libc_cv_as_noexecstack = yes; then
+- ASFLAGS_config="$ASFLAGS_config -Wa,--noexecstack"
++ ASFLAGS_config="$ASFLAGS_config -Wa,--noexecstack $CFLAGS"
+ fi
+
+