Initial commit
This commit is contained in:
12
toolchain/musl/Config.in
Normal file
12
toolchain/musl/Config.in
Normal file
@@ -0,0 +1,12 @@
|
||||
# Password crypt stubbing
|
||||
|
||||
config MUSL_DISABLE_CRYPT_SIZE_HACK
|
||||
bool "Include crypt() support for SHA256, SHA512 and Blowfish ciphers"
|
||||
depends on TOOLCHAINOPTS && USE_MUSL && !EXTERNAL_TOOLCHAIN
|
||||
default n
|
||||
help
|
||||
Enable this option to re-include crypt() support for the SHA256, SHA512 and
|
||||
Blowfish ciphers. Without this option, attempting to hash a string with a salt
|
||||
requesting one of these ciphers will cause the crypt() function to call stub
|
||||
implementations which will always fail with errno ENOSYS. Including the ciphers
|
||||
will increase the library size by about 14KB after LZMA compression.
|
||||
31
toolchain/musl/Makefile
Normal file
31
toolchain/musl/Makefile
Normal file
@@ -0,0 +1,31 @@
|
||||
PATH_PREFIX=.
|
||||
|
||||
include ./common.mk
|
||||
|
||||
HOST_STAMP_BUILT:=$(HOST_BUILD_DIR)/.built
|
||||
HOST_STAMP_INSTALLED:=$(TOOLCHAIN_DIR)/stamp/.musl_installed
|
||||
|
||||
HOST_BUILD_PARALLEL:=1
|
||||
|
||||
MUSL_MAKEOPTS = -C $(HOST_BUILD_DIR) \
|
||||
DESTDIR="$(TOOLCHAIN_DIR)/" \
|
||||
LIBCC="$(subst libgcc.a,libgcc_initial.a,$(shell $(TARGET_CC) -print-libgcc-file-name))"
|
||||
|
||||
define Host/SetToolchainInfo
|
||||
$(SED) 's,^\(LIBC_TYPE\)=.*,\1=$(PKG_NAME),' $(TOOLCHAIN_DIR)/info.mk
|
||||
$(SED) 's,^\(LIBC_URL\)=.*,\1=http://www.musl-libc.org/,' $(TOOLCHAIN_DIR)/info.mk
|
||||
$(SED) 's,^\(LIBC_VERSION\)=.*,\1=$(PKG_VERSION),' $(TOOLCHAIN_DIR)/info.mk
|
||||
$(SED) 's,^\(LIBC_SO_VERSION\)=.*,\1=$(LIBC_SO_VERSION),' $(TOOLCHAIN_DIR)/info.mk
|
||||
endef
|
||||
|
||||
define Host/Compile
|
||||
+$(MAKE) $(HOST_JOBS) $(MUSL_MAKEOPTS) all
|
||||
endef
|
||||
|
||||
define Host/Install
|
||||
$(call Host/SetToolchainInfo)
|
||||
+$(MAKE) $(HOST_JOBS) $(MUSL_MAKEOPTS) DESTDIR="$(TOOLCHAIN_DIR)/" install
|
||||
$(CP) ./include $(TOOLCHAIN_DIR)/
|
||||
endef
|
||||
|
||||
$(eval $(call HostBuild))
|
||||
58
toolchain/musl/common.mk
Normal file
58
toolchain/musl/common.mk
Normal file
@@ -0,0 +1,58 @@
|
||||
#
|
||||
# Copyright (C) 2012-2013 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
include $(TOPDIR)/rules.mk
|
||||
include $(INCLUDE_DIR)/target.mk
|
||||
|
||||
PKG_NAME:=musl
|
||||
PKG_VERSION:=1.1.24
|
||||
PKG_RELEASE:=2
|
||||
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
|
||||
PKG_SOURCE_VERSION:=ea9525c8bcf6170df59364c4bcd616de1acf8703
|
||||
PKG_MIRROR_HASH:=6975c45b9bfe586ac00dbfcd1b1a13ab110af0528028ab3dee03e23e2c0763e5
|
||||
PKG_SOURCE_URL:=git://git.musl-libc.org/musl
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.xz
|
||||
|
||||
LIBC_SO_VERSION:=$(PKG_VERSION)
|
||||
PATCH_DIR:=$(PATH_PREFIX)/patches
|
||||
|
||||
BUILD_DIR_HOST:=$(BUILD_DIR_TOOLCHAIN)
|
||||
HOST_BUILD_PREFIX:=$(TOOLCHAIN_DIR)
|
||||
HOST_BUILD_DIR:=$(BUILD_DIR_TOOLCHAIN)/$(PKG_NAME)-$(PKG_VERSION)
|
||||
|
||||
include $(INCLUDE_DIR)/host-build.mk
|
||||
include $(INCLUDE_DIR)/hardening.mk
|
||||
|
||||
TARGET_CFLAGS:= $(filter-out -O%,$(TARGET_CFLAGS))
|
||||
TARGET_CFLAGS+= $(if $(CONFIG_MUSL_DISABLE_CRYPT_SIZE_HACK),,-DCRYPT_SIZE_HACK)
|
||||
|
||||
MUSL_CONFIGURE:= \
|
||||
$(TARGET_CONFIGURE_OPTS) \
|
||||
CFLAGS="$(TARGET_CFLAGS)" \
|
||||
CROSS_COMPILE="$(TARGET_CROSS)" \
|
||||
$(HOST_BUILD_DIR)/configure \
|
||||
--prefix=/ \
|
||||
--host=$(GNU_HOST_NAME) \
|
||||
--target=$(REAL_GNU_TARGET_NAME) \
|
||||
--disable-gcc-wrapper \
|
||||
--enable-debug \
|
||||
--enable-optimize
|
||||
|
||||
define Host/Configure
|
||||
ln -snf $(PKG_NAME)-$(PKG_VERSION) $(BUILD_DIR_TOOLCHAIN)/$(PKG_NAME)
|
||||
( cd $(HOST_BUILD_DIR); rm -f config.cache; \
|
||||
$(MUSL_CONFIGURE) \
|
||||
);
|
||||
endef
|
||||
|
||||
define Host/Clean
|
||||
rm -rf \
|
||||
$(HOST_BUILD_DIR) \
|
||||
$(BUILD_DIR_TOOLCHAIN)/$(PKG_NAME) \
|
||||
$(BUILD_DIR_TOOLCHAIN)/$(LIBC)-dev
|
||||
endef
|
||||
1
toolchain/musl/include/bits/wordsize.h
Normal file
1
toolchain/musl/include/bits/wordsize.h
Normal file
@@ -0,0 +1 @@
|
||||
#include <sys/user.h>
|
||||
48
toolchain/musl/include/features.h
Normal file
48
toolchain/musl/include/features.h
Normal file
@@ -0,0 +1,48 @@
|
||||
#ifndef _FEATURES_H
|
||||
#define _FEATURES_H
|
||||
|
||||
#ifdef _ALL_SOURCE
|
||||
#define _GNU_SOURCE 1
|
||||
#endif
|
||||
|
||||
#if !defined(_POSIX_SOURCE) && !defined(_POSIX_C_SOURCE) \
|
||||
&& !defined(_XOPEN_SOURCE) && !defined(_GNU_SOURCE) \
|
||||
&& !defined(_BSD_SOURCE) && !defined(__STRICT_ANSI__)
|
||||
#define _BSD_SOURCE 1
|
||||
#define _XOPEN_SOURCE 700
|
||||
#endif
|
||||
|
||||
#if __STDC_VERSION__ >= 199901L
|
||||
#define __restrict restrict
|
||||
#elif !defined(__GNUC__)
|
||||
#define __restrict
|
||||
#endif
|
||||
|
||||
#if __STDC_VERSION__ >= 199901L || defined(__cplusplus)
|
||||
#define __inline inline
|
||||
#endif
|
||||
|
||||
#if __STDC_VERSION__ >= 201112L
|
||||
#elif defined(__GNUC__)
|
||||
#define _Noreturn __attribute__((__noreturn__))
|
||||
#else
|
||||
#define _Noreturn
|
||||
#endif
|
||||
|
||||
/* Convenience macros to test the versions of glibc and gcc.
|
||||
Use them like this:
|
||||
#if __GNUC_PREREQ (2,8)
|
||||
... code requiring gcc 2.8 or later ...
|
||||
#endif
|
||||
Note - they won't work for gcc1 or glibc1, since the _MINOR macros
|
||||
were not defined then. */
|
||||
#if defined __GNUC__ && defined __GNUC_MINOR__
|
||||
# define __GNUC_PREREQ(maj, min) \
|
||||
((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
|
||||
#else
|
||||
# define __GNUC_PREREQ(maj, min) 0
|
||||
#endif
|
||||
|
||||
#include <sys/glibc-types.h>
|
||||
|
||||
#endif
|
||||
73
toolchain/musl/include/sgidefs.h
Normal file
73
toolchain/musl/include/sgidefs.h
Normal file
@@ -0,0 +1,73 @@
|
||||
/* Copyright (C) 1996, 1997, 1998, 2003, 2004 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ralf Baechle <ralf@gnu.org>.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#ifndef _SGIDEFS_H
|
||||
#define _SGIDEFS_H 1
|
||||
|
||||
/*
|
||||
* A crude hack to stop <asm/sgidefs.h>
|
||||
*/
|
||||
#undef __ASM_SGIDEFS_H
|
||||
#define __ASM_SGIDEFS_H
|
||||
|
||||
/*
|
||||
* And remove any damage it might have already done
|
||||
*/
|
||||
#undef _MIPS_ISA_MIPS1
|
||||
#undef _MIPS_ISA_MIPS2
|
||||
#undef _MIPS_ISA_MIPS3
|
||||
#undef _MIPS_ISA_MIPS4
|
||||
#undef _MIPS_ISA_MIPS5
|
||||
#undef _MIPS_ISA_MIPS32
|
||||
#undef _MIPS_ISA_MIPS64
|
||||
|
||||
#undef _MIPS_SIM_ABI32
|
||||
#undef _MIPS_SIM_NABI32
|
||||
#undef _MIPS_SIM_ABI64
|
||||
|
||||
/*
|
||||
* Definitions for the ISA level
|
||||
*/
|
||||
#define _MIPS_ISA_MIPS1 1
|
||||
#define _MIPS_ISA_MIPS2 2
|
||||
#define _MIPS_ISA_MIPS3 3
|
||||
#define _MIPS_ISA_MIPS4 4
|
||||
#define _MIPS_ISA_MIPS5 5
|
||||
#define _MIPS_ISA_MIPS32 6
|
||||
#define _MIPS_ISA_MIPS64 7
|
||||
|
||||
/*
|
||||
* Subprogram calling convention
|
||||
*/
|
||||
#ifndef _ABIO32
|
||||
# define _ABIO32 1
|
||||
#endif
|
||||
#define _MIPS_SIM_ABI32 _ABIO32
|
||||
|
||||
#ifndef _ABIN32
|
||||
# define _ABIN32 2
|
||||
#endif
|
||||
#define _MIPS_SIM_NABI32 _ABIN32
|
||||
|
||||
#ifndef _ABI64
|
||||
# define _ABI64 3
|
||||
#endif
|
||||
#define _MIPS_SIM_ABI64 _ABI64
|
||||
|
||||
#endif /* sgidefs.h */
|
||||
378
toolchain/musl/include/sys/cdefs.h
Normal file
378
toolchain/musl/include/sys/cdefs.h
Normal file
@@ -0,0 +1,378 @@
|
||||
/* Copyright (C) 1992-2002, 2004, 2005, 2006, 2007, 2009, 2011, 2012
|
||||
Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _SYS_CDEFS_H
|
||||
#define _SYS_CDEFS_H 1
|
||||
|
||||
/* We are almost always included from features.h. */
|
||||
#ifndef _FEATURES_H
|
||||
# include <features.h>
|
||||
#endif
|
||||
|
||||
/* The GNU libc does not support any K&R compilers or the traditional mode
|
||||
of ISO C compilers anymore. Check for some of the combinations not
|
||||
anymore supported. */
|
||||
#if defined __GNUC__ && !defined __STDC__
|
||||
# error "You need a ISO C conforming compiler to use the glibc headers"
|
||||
#endif
|
||||
|
||||
/* Some user header file might have defined this before. */
|
||||
#undef __P
|
||||
#undef __PMT
|
||||
|
||||
#ifdef __GNUC__
|
||||
|
||||
/* All functions, except those with callbacks or those that
|
||||
synchronize memory, are leaf functions. */
|
||||
# if __GNUC_PREREQ (4, 6) && !defined _LIBC
|
||||
# define __LEAF , __leaf__
|
||||
# define __LEAF_ATTR __attribute__ ((__leaf__))
|
||||
# else
|
||||
# define __LEAF
|
||||
# define __LEAF_ATTR
|
||||
# endif
|
||||
|
||||
/* GCC can always grok prototypes. For C++ programs we add throw()
|
||||
to help it optimize the function calls. But this works only with
|
||||
gcc 2.8.x and egcs. For gcc 3.2 and up we even mark C functions
|
||||
as non-throwing using a function attribute since programs can use
|
||||
the -fexceptions options for C code as well. */
|
||||
# if !defined __cplusplus && __GNUC_PREREQ (3, 3)
|
||||
# define __THROW __attribute__ ((__nothrow__ __LEAF))
|
||||
# define __THROWNL __attribute__ ((__nothrow__))
|
||||
# define __NTH(fct) __attribute__ ((__nothrow__ __LEAF)) fct
|
||||
# else
|
||||
# if defined __cplusplus && __GNUC_PREREQ (2,8)
|
||||
# define __THROW throw ()
|
||||
# define __THROWNL throw ()
|
||||
# define __NTH(fct) __LEAF_ATTR fct throw ()
|
||||
# else
|
||||
# define __THROW
|
||||
# define __THROWNL
|
||||
# define __NTH(fct) fct
|
||||
# endif
|
||||
# endif
|
||||
|
||||
#else /* Not GCC. */
|
||||
|
||||
# define __inline /* No inline functions. */
|
||||
|
||||
# define __THROW
|
||||
# define __THROWNL
|
||||
# define __NTH(fct) fct
|
||||
|
||||
#endif /* GCC. */
|
||||
|
||||
/* These two macros are not used in glibc anymore. They are kept here
|
||||
only because some other projects expect the macros to be defined. */
|
||||
#define __P(args) args
|
||||
#define __PMT(args) args
|
||||
|
||||
/* For these things, GCC behaves the ANSI way normally,
|
||||
and the non-ANSI way under -traditional. */
|
||||
|
||||
#define __CONCAT(x,y) x ## y
|
||||
#define __STRING(x) #x
|
||||
|
||||
/* This is not a typedef so `const __ptr_t' does the right thing. */
|
||||
#define __ptr_t void *
|
||||
#define __long_double_t long double
|
||||
|
||||
|
||||
/* C++ needs to know that types and declarations are C, not C++. */
|
||||
#ifdef __cplusplus
|
||||
# define __BEGIN_DECLS extern "C" {
|
||||
# define __END_DECLS }
|
||||
#else
|
||||
# define __BEGIN_DECLS
|
||||
# define __END_DECLS
|
||||
#endif
|
||||
|
||||
|
||||
/* The standard library needs the functions from the ISO C90 standard
|
||||
in the std namespace. At the same time we want to be safe for
|
||||
future changes and we include the ISO C99 code in the non-standard
|
||||
namespace __c99. The C++ wrapper header take case of adding the
|
||||
definitions to the global namespace. */
|
||||
#if defined __cplusplus && defined _GLIBCPP_USE_NAMESPACES
|
||||
# define __BEGIN_NAMESPACE_STD namespace std {
|
||||
# define __END_NAMESPACE_STD }
|
||||
# define __USING_NAMESPACE_STD(name) using std::name;
|
||||
# define __BEGIN_NAMESPACE_C99 namespace __c99 {
|
||||
# define __END_NAMESPACE_C99 }
|
||||
# define __USING_NAMESPACE_C99(name) using __c99::name;
|
||||
#else
|
||||
/* For compatibility we do not add the declarations into any
|
||||
namespace. They will end up in the global namespace which is what
|
||||
old code expects. */
|
||||
# define __BEGIN_NAMESPACE_STD
|
||||
# define __END_NAMESPACE_STD
|
||||
# define __USING_NAMESPACE_STD(name)
|
||||
# define __BEGIN_NAMESPACE_C99
|
||||
# define __END_NAMESPACE_C99
|
||||
# define __USING_NAMESPACE_C99(name)
|
||||
#endif
|
||||
|
||||
|
||||
/* Support for bounded pointers. */
|
||||
#ifndef __BOUNDED_POINTERS__
|
||||
# define __bounded /* nothing */
|
||||
# define __unbounded /* nothing */
|
||||
# define __ptrvalue /* nothing */
|
||||
#endif
|
||||
|
||||
|
||||
/* Fortify support. */
|
||||
#define __bos(ptr) __builtin_object_size (ptr, __USE_FORTIFY_LEVEL > 1)
|
||||
#define __bos0(ptr) __builtin_object_size (ptr, 0)
|
||||
#define __fortify_function __extern_always_inline __attribute_artificial__
|
||||
|
||||
#if __GNUC_PREREQ (4,3)
|
||||
# define __warndecl(name, msg) \
|
||||
extern void name (void) __attribute__((__warning__ (msg)))
|
||||
# define __warnattr(msg) __attribute__((__warning__ (msg)))
|
||||
# define __errordecl(name, msg) \
|
||||
extern void name (void) __attribute__((__error__ (msg)))
|
||||
#else
|
||||
# define __warndecl(name, msg) extern void name (void)
|
||||
# define __warnattr(msg)
|
||||
# define __errordecl(name, msg) extern void name (void)
|
||||
#endif
|
||||
|
||||
/* Support for flexible arrays. */
|
||||
#if __GNUC_PREREQ (2,97)
|
||||
/* GCC 2.97 supports C99 flexible array members. */
|
||||
# define __flexarr []
|
||||
#else
|
||||
# ifdef __GNUC__
|
||||
# define __flexarr [0]
|
||||
# else
|
||||
# if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
|
||||
# define __flexarr []
|
||||
# else
|
||||
/* Some other non-C99 compiler. Approximate with [1]. */
|
||||
# define __flexarr [1]
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
/* __asm__ ("xyz") is used throughout the headers to rename functions
|
||||
at the assembly language level. This is wrapped by the __REDIRECT
|
||||
macro, in order to support compilers that can do this some other
|
||||
way. When compilers don't support asm-names at all, we have to do
|
||||
preprocessor tricks instead (which don't have exactly the right
|
||||
semantics, but it's the best we can do).
|
||||
|
||||
Example:
|
||||
int __REDIRECT(setpgrp, (__pid_t pid, __pid_t pgrp), setpgid); */
|
||||
|
||||
#if defined __GNUC__ && __GNUC__ >= 2
|
||||
|
||||
# define __REDIRECT(name, proto, alias) name proto __asm__ (__ASMNAME (#alias))
|
||||
# ifdef __cplusplus
|
||||
# define __REDIRECT_NTH(name, proto, alias) \
|
||||
name proto __THROW __asm__ (__ASMNAME (#alias))
|
||||
# define __REDIRECT_NTHNL(name, proto, alias) \
|
||||
name proto __THROWNL __asm__ (__ASMNAME (#alias))
|
||||
# else
|
||||
# define __REDIRECT_NTH(name, proto, alias) \
|
||||
name proto __asm__ (__ASMNAME (#alias)) __THROW
|
||||
# define __REDIRECT_NTHNL(name, proto, alias) \
|
||||
name proto __asm__ (__ASMNAME (#alias)) __THROWNL
|
||||
# endif
|
||||
# define __ASMNAME(cname) __ASMNAME2 (__USER_LABEL_PREFIX__, cname)
|
||||
# define __ASMNAME2(prefix, cname) __STRING (prefix) cname
|
||||
|
||||
/*
|
||||
#elif __SOME_OTHER_COMPILER__
|
||||
|
||||
# define __REDIRECT(name, proto, alias) name proto; \
|
||||
_Pragma("let " #name " = " #alias)
|
||||
*/
|
||||
#endif
|
||||
|
||||
/* GCC has various useful declarations that can be made with the
|
||||
`__attribute__' syntax. All of the ways we use this do fine if
|
||||
they are omitted for compilers that don't understand it. */
|
||||
#if !defined __GNUC__ || __GNUC__ < 2
|
||||
# define __attribute__(xyz) /* Ignore */
|
||||
#endif
|
||||
|
||||
/* At some point during the gcc 2.96 development the `malloc' attribute
|
||||
for functions was introduced. We don't want to use it unconditionally
|
||||
(although this would be possible) since it generates warnings. */
|
||||
#if __GNUC_PREREQ (2,96)
|
||||
# define __attribute_malloc__ __attribute__ ((__malloc__))
|
||||
#else
|
||||
# define __attribute_malloc__ /* Ignore */
|
||||
#endif
|
||||
|
||||
/* At some point during the gcc 2.96 development the `pure' attribute
|
||||
for functions was introduced. We don't want to use it unconditionally
|
||||
(although this would be possible) since it generates warnings. */
|
||||
#if __GNUC_PREREQ (2,96)
|
||||
# define __attribute_pure__ __attribute__ ((__pure__))
|
||||
#else
|
||||
# define __attribute_pure__ /* Ignore */
|
||||
#endif
|
||||
|
||||
/* This declaration tells the compiler that the value is constant. */
|
||||
#if __GNUC_PREREQ (2,5)
|
||||
# define __attribute_const__ __attribute__ ((__const__))
|
||||
#else
|
||||
# define __attribute_const__ /* Ignore */
|
||||
#endif
|
||||
|
||||
/* At some point during the gcc 3.1 development the `used' attribute
|
||||
for functions was introduced. We don't want to use it unconditionally
|
||||
(although this would be possible) since it generates warnings. */
|
||||
#if __GNUC_PREREQ (3,1)
|
||||
# define __attribute_used__ __attribute__ ((__used__))
|
||||
# define __attribute_noinline__ __attribute__ ((__noinline__))
|
||||
#else
|
||||
# define __attribute_used__ __attribute__ ((__unused__))
|
||||
# define __attribute_noinline__ /* Ignore */
|
||||
#endif
|
||||
|
||||
/* gcc allows marking deprecated functions. */
|
||||
#if __GNUC_PREREQ (3,2)
|
||||
# define __attribute_deprecated__ __attribute__ ((__deprecated__))
|
||||
#else
|
||||
# define __attribute_deprecated__ /* Ignore */
|
||||
#endif
|
||||
|
||||
/* At some point during the gcc 2.8 development the `format_arg' attribute
|
||||
for functions was introduced. We don't want to use it unconditionally
|
||||
(although this would be possible) since it generates warnings.
|
||||
If several `format_arg' attributes are given for the same function, in
|
||||
gcc-3.0 and older, all but the last one are ignored. In newer gccs,
|
||||
all designated arguments are considered. */
|
||||
#if __GNUC_PREREQ (2,8)
|
||||
# define __attribute_format_arg__(x) __attribute__ ((__format_arg__ (x)))
|
||||
#else
|
||||
# define __attribute_format_arg__(x) /* Ignore */
|
||||
#endif
|
||||
|
||||
/* At some point during the gcc 2.97 development the `strfmon' format
|
||||
attribute for functions was introduced. We don't want to use it
|
||||
unconditionally (although this would be possible) since it
|
||||
generates warnings. */
|
||||
#if __GNUC_PREREQ (2,97)
|
||||
# define __attribute_format_strfmon__(a,b) \
|
||||
__attribute__ ((__format__ (__strfmon__, a, b)))
|
||||
#else
|
||||
# define __attribute_format_strfmon__(a,b) /* Ignore */
|
||||
#endif
|
||||
|
||||
/* The nonull function attribute allows to mark pointer parameters which
|
||||
must not be NULL. */
|
||||
#if __GNUC_PREREQ (3,3)
|
||||
# define __nonnull(params) __attribute__ ((__nonnull__ params))
|
||||
#else
|
||||
# define __nonnull(params)
|
||||
#endif
|
||||
|
||||
/* If fortification mode, we warn about unused results of certain
|
||||
function calls which can lead to problems. */
|
||||
#if __GNUC_PREREQ (3,4)
|
||||
# define __attribute_warn_unused_result__ \
|
||||
__attribute__ ((__warn_unused_result__))
|
||||
# if __USE_FORTIFY_LEVEL > 0
|
||||
# define __wur __attribute_warn_unused_result__
|
||||
# endif
|
||||
#else
|
||||
# define __attribute_warn_unused_result__ /* empty */
|
||||
#endif
|
||||
#ifndef __wur
|
||||
# define __wur /* Ignore */
|
||||
#endif
|
||||
|
||||
/* Forces a function to be always inlined. */
|
||||
#if __GNUC_PREREQ (3,2)
|
||||
# define __always_inline __inline __attribute__ ((__always_inline__))
|
||||
#else
|
||||
# define __always_inline __inline
|
||||
#endif
|
||||
|
||||
/* Associate error messages with the source location of the call site rather
|
||||
than with the source location inside the function. */
|
||||
#if __GNUC_PREREQ (4,3)
|
||||
# define __attribute_artificial__ __attribute__ ((__artificial__))
|
||||
#else
|
||||
# define __attribute_artificial__ /* Ignore */
|
||||
#endif
|
||||
|
||||
/* GCC 4.3 and above with -std=c99 or -std=gnu99 implements ISO C99
|
||||
inline semantics, unless -fgnu89-inline is used. */
|
||||
#if !defined __cplusplus || __GNUC_PREREQ (4,3)
|
||||
# if defined __GNUC_STDC_INLINE__ || defined __cplusplus
|
||||
# define __extern_inline extern __inline __attribute__ ((__gnu_inline__))
|
||||
# define __extern_always_inline \
|
||||
extern __always_inline __attribute__ ((__gnu_inline__))
|
||||
# else
|
||||
# define __extern_inline extern __inline
|
||||
# define __extern_always_inline extern __always_inline
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* GCC 4.3 and above allow passing all anonymous arguments of an
|
||||
__extern_always_inline function to some other vararg function. */
|
||||
#if __GNUC_PREREQ (4,3)
|
||||
# define __va_arg_pack() __builtin_va_arg_pack ()
|
||||
# define __va_arg_pack_len() __builtin_va_arg_pack_len ()
|
||||
#endif
|
||||
|
||||
/* It is possible to compile containing GCC extensions even if GCC is
|
||||
run in pedantic mode if the uses are carefully marked using the
|
||||
`__extension__' keyword. But this is not generally available before
|
||||
version 2.8. */
|
||||
#if !__GNUC_PREREQ (2,8)
|
||||
# define __extension__ /* Ignore */
|
||||
#endif
|
||||
|
||||
/* __restrict is known in EGCS 1.2 and above. */
|
||||
#if !__GNUC_PREREQ (2,92)
|
||||
# define __restrict /* Ignore */
|
||||
#endif
|
||||
|
||||
/* ISO C99 also allows to declare arrays as non-overlapping. The syntax is
|
||||
array_name[restrict]
|
||||
GCC 3.1 supports this. */
|
||||
#if __GNUC_PREREQ (3,1) && !defined __GNUG__
|
||||
# define __restrict_arr __restrict
|
||||
#else
|
||||
# ifdef __GNUC__
|
||||
# define __restrict_arr /* Not supported in old GCC. */
|
||||
# else
|
||||
# if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
|
||||
# define __restrict_arr restrict
|
||||
# else
|
||||
/* Some other non-C99 compiler. */
|
||||
# define __restrict_arr /* Not supported. */
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if __GNUC__ >= 3
|
||||
# define __glibc_unlikely(cond) __builtin_expect((cond), 0)
|
||||
#else
|
||||
# define __glibc_unlikely(cond) (cond)
|
||||
#endif
|
||||
|
||||
#endif /* sys/cdefs.h */
|
||||
35
toolchain/musl/include/sys/glibc-types.h
Normal file
35
toolchain/musl/include/sys/glibc-types.h
Normal file
@@ -0,0 +1,35 @@
|
||||
#ifndef __MUSL_GLIBC_TYPES_H
|
||||
#define __MUSL_GLIBC_TYPES_H
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
/* Convenience types. */
|
||||
typedef unsigned char __u_char;
|
||||
typedef unsigned short int __u_short;
|
||||
typedef unsigned int __u_int;
|
||||
typedef unsigned long int __u_long;
|
||||
|
||||
/* Fixed-size types, underlying types depend on word size and compiler. */
|
||||
typedef signed char __int8_t;
|
||||
typedef unsigned char __uint8_t;
|
||||
typedef signed short int __int16_t;
|
||||
typedef unsigned short int __uint16_t;
|
||||
typedef signed int __int32_t;
|
||||
typedef unsigned int __uint32_t;
|
||||
#if __WORDSIZE == 64
|
||||
typedef signed long int __int64_t;
|
||||
typedef unsigned long int __uint64_t;
|
||||
#else
|
||||
__extension__ typedef signed long long int __int64_t;
|
||||
__extension__ typedef unsigned long long int __uint64_t;
|
||||
#endif
|
||||
|
||||
#define __off64_t off_t
|
||||
#define __loff_t off_t
|
||||
typedef char *__caddr_t;
|
||||
#define __locale_t locale_t
|
||||
|
||||
#define __gid_t gid_t
|
||||
#define __uid_t uid_t
|
||||
|
||||
#endif
|
||||
574
toolchain/musl/include/sys/queue.h
Normal file
574
toolchain/musl/include/sys/queue.h
Normal file
@@ -0,0 +1,574 @@
|
||||
/*
|
||||
* Copyright (c) 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
|
||||
*
|
||||
* @(#)queue.h 8.5 (Berkeley) 8/20/94
|
||||
*/
|
||||
|
||||
#ifndef _SYS_QUEUE_H_
|
||||
#define _SYS_QUEUE_H_
|
||||
|
||||
/*
|
||||
* This file defines five types of data structures: singly-linked lists,
|
||||
* lists, simple queues, tail queues, and circular queues.
|
||||
*
|
||||
* A singly-linked list is headed by a single forward pointer. The
|
||||
* elements are singly linked for minimum space and pointer manipulation
|
||||
* overhead at the expense of O(n) removal for arbitrary elements. New
|
||||
* elements can be added to the list after an existing element or at the
|
||||
* head of the list. Elements being removed from the head of the list
|
||||
* should use the explicit macro for this purpose for optimum
|
||||
* efficiency. A singly-linked list may only be traversed in the forward
|
||||
* direction. Singly-linked lists are ideal for applications with large
|
||||
* datasets and few or no removals or for implementing a LIFO queue.
|
||||
*
|
||||
* A list is headed by a single forward pointer (or an array of forward
|
||||
* pointers for a hash table header). The elements are doubly linked
|
||||
* so that an arbitrary element can be removed without a need to
|
||||
* traverse the list. New elements can be added to the list before
|
||||
* or after an existing element or at the head of the list. A list
|
||||
* may only be traversed in the forward direction.
|
||||
*
|
||||
* A simple queue is headed by a pair of pointers, one the head of the
|
||||
* list and the other to the tail of the list. The elements are singly
|
||||
* linked to save space, so elements can only be removed from the
|
||||
* head of the list. New elements can be added to the list after
|
||||
* an existing element, at the head of the list, or at the end of the
|
||||
* list. A simple queue may only be traversed in the forward direction.
|
||||
*
|
||||
* A tail queue is headed by a pair of pointers, one to the head of the
|
||||
* list and the other to the tail of the list. The elements are doubly
|
||||
* linked so that an arbitrary element can be removed without a need to
|
||||
* traverse the list. New elements can be added to the list before or
|
||||
* after an existing element, at the head of the list, or at the end of
|
||||
* the list. A tail queue may be traversed in either direction.
|
||||
*
|
||||
* A circle queue is headed by a pair of pointers, one to the head of the
|
||||
* list and the other to the tail of the list. The elements are doubly
|
||||
* linked so that an arbitrary element can be removed without a need to
|
||||
* traverse the list. New elements can be added to the list before or after
|
||||
* an existing element, at the head of the list, or at the end of the list.
|
||||
* A circle queue may be traversed in either direction, but has a more
|
||||
* complex end of list detection.
|
||||
*
|
||||
* For details on the use of these macros, see the queue(3) manual page.
|
||||
*/
|
||||
|
||||
/*
|
||||
* List definitions.
|
||||
*/
|
||||
#define LIST_HEAD(name, type) \
|
||||
struct name { \
|
||||
struct type *lh_first; /* first element */ \
|
||||
}
|
||||
|
||||
#define LIST_HEAD_INITIALIZER(head) \
|
||||
{ NULL }
|
||||
|
||||
#define LIST_ENTRY(type) \
|
||||
struct { \
|
||||
struct type *le_next; /* next element */ \
|
||||
struct type **le_prev; /* address of previous next element */ \
|
||||
}
|
||||
|
||||
/*
|
||||
* List functions.
|
||||
*/
|
||||
#define LIST_INIT(head) do { \
|
||||
(head)->lh_first = NULL; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define LIST_INSERT_AFTER(listelm, elm, field) do { \
|
||||
if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
|
||||
(listelm)->field.le_next->field.le_prev = \
|
||||
&(elm)->field.le_next; \
|
||||
(listelm)->field.le_next = (elm); \
|
||||
(elm)->field.le_prev = &(listelm)->field.le_next; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
|
||||
(elm)->field.le_prev = (listelm)->field.le_prev; \
|
||||
(elm)->field.le_next = (listelm); \
|
||||
*(listelm)->field.le_prev = (elm); \
|
||||
(listelm)->field.le_prev = &(elm)->field.le_next; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define LIST_INSERT_HEAD(head, elm, field) do { \
|
||||
if (((elm)->field.le_next = (head)->lh_first) != NULL) \
|
||||
(head)->lh_first->field.le_prev = &(elm)->field.le_next;\
|
||||
(head)->lh_first = (elm); \
|
||||
(elm)->field.le_prev = &(head)->lh_first; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define LIST_REMOVE(elm, field) do { \
|
||||
if ((elm)->field.le_next != NULL) \
|
||||
(elm)->field.le_next->field.le_prev = \
|
||||
(elm)->field.le_prev; \
|
||||
*(elm)->field.le_prev = (elm)->field.le_next; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define LIST_FOREACH(var, head, field) \
|
||||
for ((var) = ((head)->lh_first); \
|
||||
(var); \
|
||||
(var) = ((var)->field.le_next))
|
||||
|
||||
/*
|
||||
* List access methods.
|
||||
*/
|
||||
#define LIST_EMPTY(head) ((head)->lh_first == NULL)
|
||||
#define LIST_FIRST(head) ((head)->lh_first)
|
||||
#define LIST_NEXT(elm, field) ((elm)->field.le_next)
|
||||
|
||||
|
||||
/*
|
||||
* Singly-linked List definitions.
|
||||
*/
|
||||
#define SLIST_HEAD(name, type) \
|
||||
struct name { \
|
||||
struct type *slh_first; /* first element */ \
|
||||
}
|
||||
|
||||
#define SLIST_HEAD_INITIALIZER(head) \
|
||||
{ NULL }
|
||||
|
||||
#define SLIST_ENTRY(type) \
|
||||
struct { \
|
||||
struct type *sle_next; /* next element */ \
|
||||
}
|
||||
|
||||
/*
|
||||
* Singly-linked List functions.
|
||||
*/
|
||||
#define SLIST_INIT(head) do { \
|
||||
(head)->slh_first = NULL; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
|
||||
(elm)->field.sle_next = (slistelm)->field.sle_next; \
|
||||
(slistelm)->field.sle_next = (elm); \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define SLIST_INSERT_HEAD(head, elm, field) do { \
|
||||
(elm)->field.sle_next = (head)->slh_first; \
|
||||
(head)->slh_first = (elm); \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define SLIST_REMOVE_HEAD(head, field) do { \
|
||||
(head)->slh_first = (head)->slh_first->field.sle_next; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define SLIST_REMOVE(head, elm, type, field) do { \
|
||||
if ((head)->slh_first == (elm)) { \
|
||||
SLIST_REMOVE_HEAD((head), field); \
|
||||
} \
|
||||
else { \
|
||||
struct type *curelm = (head)->slh_first; \
|
||||
while(curelm->field.sle_next != (elm)) \
|
||||
curelm = curelm->field.sle_next; \
|
||||
curelm->field.sle_next = \
|
||||
curelm->field.sle_next->field.sle_next; \
|
||||
} \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define SLIST_FOREACH(var, head, field) \
|
||||
for((var) = (head)->slh_first; (var); (var) = (var)->field.sle_next)
|
||||
|
||||
/*
|
||||
* Singly-linked List access methods.
|
||||
*/
|
||||
#define SLIST_EMPTY(head) ((head)->slh_first == NULL)
|
||||
#define SLIST_FIRST(head) ((head)->slh_first)
|
||||
#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
|
||||
|
||||
|
||||
/*
|
||||
* Singly-linked Tail queue declarations.
|
||||
*/
|
||||
#define STAILQ_HEAD(name, type) \
|
||||
struct name { \
|
||||
struct type *stqh_first; /* first element */ \
|
||||
struct type **stqh_last; /* addr of last next element */ \
|
||||
}
|
||||
|
||||
#define STAILQ_HEAD_INITIALIZER(head) \
|
||||
{ NULL, &(head).stqh_first }
|
||||
|
||||
#define STAILQ_ENTRY(type) \
|
||||
struct { \
|
||||
struct type *stqe_next; /* next element */ \
|
||||
}
|
||||
|
||||
/*
|
||||
* Singly-linked Tail queue functions.
|
||||
*/
|
||||
#define STAILQ_INIT(head) do { \
|
||||
(head)->stqh_first = NULL; \
|
||||
(head)->stqh_last = &(head)->stqh_first; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define STAILQ_INSERT_HEAD(head, elm, field) do { \
|
||||
if (((elm)->field.stqe_next = (head)->stqh_first) == NULL) \
|
||||
(head)->stqh_last = &(elm)->field.stqe_next; \
|
||||
(head)->stqh_first = (elm); \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define STAILQ_INSERT_TAIL(head, elm, field) do { \
|
||||
(elm)->field.stqe_next = NULL; \
|
||||
*(head)->stqh_last = (elm); \
|
||||
(head)->stqh_last = &(elm)->field.stqe_next; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define STAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
|
||||
if (((elm)->field.stqe_next = (listelm)->field.stqe_next) == NULL)\
|
||||
(head)->stqh_last = &(elm)->field.stqe_next; \
|
||||
(listelm)->field.stqe_next = (elm); \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define STAILQ_REMOVE_HEAD(head, field) do { \
|
||||
if (((head)->stqh_first = (head)->stqh_first->field.stqe_next) == NULL) \
|
||||
(head)->stqh_last = &(head)->stqh_first; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define STAILQ_REMOVE(head, elm, type, field) do { \
|
||||
if ((head)->stqh_first == (elm)) { \
|
||||
STAILQ_REMOVE_HEAD((head), field); \
|
||||
} else { \
|
||||
struct type *curelm = (head)->stqh_first; \
|
||||
while (curelm->field.stqe_next != (elm)) \
|
||||
curelm = curelm->field.stqe_next; \
|
||||
if ((curelm->field.stqe_next = \
|
||||
curelm->field.stqe_next->field.stqe_next) == NULL) \
|
||||
(head)->stqh_last = &(curelm)->field.stqe_next; \
|
||||
} \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define STAILQ_FOREACH(var, head, field) \
|
||||
for ((var) = ((head)->stqh_first); \
|
||||
(var); \
|
||||
(var) = ((var)->field.stqe_next))
|
||||
|
||||
#define STAILQ_CONCAT(head1, head2) do { \
|
||||
if (!STAILQ_EMPTY((head2))) { \
|
||||
*(head1)->stqh_last = (head2)->stqh_first; \
|
||||
(head1)->stqh_last = (head2)->stqh_last; \
|
||||
STAILQ_INIT((head2)); \
|
||||
} \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
/*
|
||||
* Singly-linked Tail queue access methods.
|
||||
*/
|
||||
#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL)
|
||||
#define STAILQ_FIRST(head) ((head)->stqh_first)
|
||||
#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
|
||||
|
||||
|
||||
/*
|
||||
* Simple queue definitions.
|
||||
*/
|
||||
#define SIMPLEQ_HEAD(name, type) \
|
||||
struct name { \
|
||||
struct type *sqh_first; /* first element */ \
|
||||
struct type **sqh_last; /* addr of last next element */ \
|
||||
}
|
||||
|
||||
#define SIMPLEQ_HEAD_INITIALIZER(head) \
|
||||
{ NULL, &(head).sqh_first }
|
||||
|
||||
#define SIMPLEQ_ENTRY(type) \
|
||||
struct { \
|
||||
struct type *sqe_next; /* next element */ \
|
||||
}
|
||||
|
||||
/*
|
||||
* Simple queue functions.
|
||||
*/
|
||||
#define SIMPLEQ_INIT(head) do { \
|
||||
(head)->sqh_first = NULL; \
|
||||
(head)->sqh_last = &(head)->sqh_first; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define SIMPLEQ_INSERT_HEAD(head, elm, field) do { \
|
||||
if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \
|
||||
(head)->sqh_last = &(elm)->field.sqe_next; \
|
||||
(head)->sqh_first = (elm); \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define SIMPLEQ_INSERT_TAIL(head, elm, field) do { \
|
||||
(elm)->field.sqe_next = NULL; \
|
||||
*(head)->sqh_last = (elm); \
|
||||
(head)->sqh_last = &(elm)->field.sqe_next; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
|
||||
if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\
|
||||
(head)->sqh_last = &(elm)->field.sqe_next; \
|
||||
(listelm)->field.sqe_next = (elm); \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define SIMPLEQ_REMOVE_HEAD(head, field) do { \
|
||||
if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \
|
||||
(head)->sqh_last = &(head)->sqh_first; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define SIMPLEQ_REMOVE(head, elm, type, field) do { \
|
||||
if ((head)->sqh_first == (elm)) { \
|
||||
SIMPLEQ_REMOVE_HEAD((head), field); \
|
||||
} else { \
|
||||
struct type *curelm = (head)->sqh_first; \
|
||||
while (curelm->field.sqe_next != (elm)) \
|
||||
curelm = curelm->field.sqe_next; \
|
||||
if ((curelm->field.sqe_next = \
|
||||
curelm->field.sqe_next->field.sqe_next) == NULL) \
|
||||
(head)->sqh_last = &(curelm)->field.sqe_next; \
|
||||
} \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define SIMPLEQ_FOREACH(var, head, field) \
|
||||
for ((var) = ((head)->sqh_first); \
|
||||
(var); \
|
||||
(var) = ((var)->field.sqe_next))
|
||||
|
||||
/*
|
||||
* Simple queue access methods.
|
||||
*/
|
||||
#define SIMPLEQ_EMPTY(head) ((head)->sqh_first == NULL)
|
||||
#define SIMPLEQ_FIRST(head) ((head)->sqh_first)
|
||||
#define SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next)
|
||||
|
||||
|
||||
/*
|
||||
* Tail queue definitions.
|
||||
*/
|
||||
#define _TAILQ_HEAD(name, type, qual) \
|
||||
struct name { \
|
||||
qual type *tqh_first; /* first element */ \
|
||||
qual type *qual *tqh_last; /* addr of last next element */ \
|
||||
}
|
||||
#define TAILQ_HEAD(name, type) _TAILQ_HEAD(name, struct type,)
|
||||
|
||||
#define TAILQ_HEAD_INITIALIZER(head) \
|
||||
{ NULL, &(head).tqh_first }
|
||||
|
||||
#define _TAILQ_ENTRY(type, qual) \
|
||||
struct { \
|
||||
qual type *tqe_next; /* next element */ \
|
||||
qual type *qual *tqe_prev; /* address of previous next element */\
|
||||
}
|
||||
#define TAILQ_ENTRY(type) _TAILQ_ENTRY(struct type,)
|
||||
|
||||
/*
|
||||
* Tail queue functions.
|
||||
*/
|
||||
#define TAILQ_INIT(head) do { \
|
||||
(head)->tqh_first = NULL; \
|
||||
(head)->tqh_last = &(head)->tqh_first; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define TAILQ_INSERT_HEAD(head, elm, field) do { \
|
||||
if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
|
||||
(head)->tqh_first->field.tqe_prev = \
|
||||
&(elm)->field.tqe_next; \
|
||||
else \
|
||||
(head)->tqh_last = &(elm)->field.tqe_next; \
|
||||
(head)->tqh_first = (elm); \
|
||||
(elm)->field.tqe_prev = &(head)->tqh_first; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define TAILQ_INSERT_TAIL(head, elm, field) do { \
|
||||
(elm)->field.tqe_next = NULL; \
|
||||
(elm)->field.tqe_prev = (head)->tqh_last; \
|
||||
*(head)->tqh_last = (elm); \
|
||||
(head)->tqh_last = &(elm)->field.tqe_next; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
|
||||
if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
|
||||
(elm)->field.tqe_next->field.tqe_prev = \
|
||||
&(elm)->field.tqe_next; \
|
||||
else \
|
||||
(head)->tqh_last = &(elm)->field.tqe_next; \
|
||||
(listelm)->field.tqe_next = (elm); \
|
||||
(elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
|
||||
(elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
|
||||
(elm)->field.tqe_next = (listelm); \
|
||||
*(listelm)->field.tqe_prev = (elm); \
|
||||
(listelm)->field.tqe_prev = &(elm)->field.tqe_next; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define TAILQ_REMOVE(head, elm, field) do { \
|
||||
if (((elm)->field.tqe_next) != NULL) \
|
||||
(elm)->field.tqe_next->field.tqe_prev = \
|
||||
(elm)->field.tqe_prev; \
|
||||
else \
|
||||
(head)->tqh_last = (elm)->field.tqe_prev; \
|
||||
*(elm)->field.tqe_prev = (elm)->field.tqe_next; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define TAILQ_FOREACH(var, head, field) \
|
||||
for ((var) = ((head)->tqh_first); \
|
||||
(var); \
|
||||
(var) = ((var)->field.tqe_next))
|
||||
|
||||
#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
|
||||
for ((var) = (*(((struct headname *)((head)->tqh_last))->tqh_last)); \
|
||||
(var); \
|
||||
(var) = (*(((struct headname *)((var)->field.tqe_prev))->tqh_last)))
|
||||
|
||||
#define TAILQ_CONCAT(head1, head2, field) do { \
|
||||
if (!TAILQ_EMPTY(head2)) { \
|
||||
*(head1)->tqh_last = (head2)->tqh_first; \
|
||||
(head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \
|
||||
(head1)->tqh_last = (head2)->tqh_last; \
|
||||
TAILQ_INIT((head2)); \
|
||||
} \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
/*
|
||||
* Tail queue access methods.
|
||||
*/
|
||||
#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL)
|
||||
#define TAILQ_FIRST(head) ((head)->tqh_first)
|
||||
#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
|
||||
|
||||
#define TAILQ_LAST(head, headname) \
|
||||
(*(((struct headname *)((head)->tqh_last))->tqh_last))
|
||||
#define TAILQ_PREV(elm, headname, field) \
|
||||
(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
|
||||
|
||||
|
||||
/*
|
||||
* Circular queue definitions.
|
||||
*/
|
||||
#define CIRCLEQ_HEAD(name, type) \
|
||||
struct name { \
|
||||
struct type *cqh_first; /* first element */ \
|
||||
struct type *cqh_last; /* last element */ \
|
||||
}
|
||||
|
||||
#define CIRCLEQ_HEAD_INITIALIZER(head) \
|
||||
{ (void *)&head, (void *)&head }
|
||||
|
||||
#define CIRCLEQ_ENTRY(type) \
|
||||
struct { \
|
||||
struct type *cqe_next; /* next element */ \
|
||||
struct type *cqe_prev; /* previous element */ \
|
||||
}
|
||||
|
||||
/*
|
||||
* Circular queue functions.
|
||||
*/
|
||||
#define CIRCLEQ_INIT(head) do { \
|
||||
(head)->cqh_first = (void *)(head); \
|
||||
(head)->cqh_last = (void *)(head); \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
|
||||
(elm)->field.cqe_next = (listelm)->field.cqe_next; \
|
||||
(elm)->field.cqe_prev = (listelm); \
|
||||
if ((listelm)->field.cqe_next == (void *)(head)) \
|
||||
(head)->cqh_last = (elm); \
|
||||
else \
|
||||
(listelm)->field.cqe_next->field.cqe_prev = (elm); \
|
||||
(listelm)->field.cqe_next = (elm); \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \
|
||||
(elm)->field.cqe_next = (listelm); \
|
||||
(elm)->field.cqe_prev = (listelm)->field.cqe_prev; \
|
||||
if ((listelm)->field.cqe_prev == (void *)(head)) \
|
||||
(head)->cqh_first = (elm); \
|
||||
else \
|
||||
(listelm)->field.cqe_prev->field.cqe_next = (elm); \
|
||||
(listelm)->field.cqe_prev = (elm); \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \
|
||||
(elm)->field.cqe_next = (head)->cqh_first; \
|
||||
(elm)->field.cqe_prev = (void *)(head); \
|
||||
if ((head)->cqh_last == (void *)(head)) \
|
||||
(head)->cqh_last = (elm); \
|
||||
else \
|
||||
(head)->cqh_first->field.cqe_prev = (elm); \
|
||||
(head)->cqh_first = (elm); \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \
|
||||
(elm)->field.cqe_next = (void *)(head); \
|
||||
(elm)->field.cqe_prev = (head)->cqh_last; \
|
||||
if ((head)->cqh_first == (void *)(head)) \
|
||||
(head)->cqh_first = (elm); \
|
||||
else \
|
||||
(head)->cqh_last->field.cqe_next = (elm); \
|
||||
(head)->cqh_last = (elm); \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define CIRCLEQ_REMOVE(head, elm, field) do { \
|
||||
if ((elm)->field.cqe_next == (void *)(head)) \
|
||||
(head)->cqh_last = (elm)->field.cqe_prev; \
|
||||
else \
|
||||
(elm)->field.cqe_next->field.cqe_prev = \
|
||||
(elm)->field.cqe_prev; \
|
||||
if ((elm)->field.cqe_prev == (void *)(head)) \
|
||||
(head)->cqh_first = (elm)->field.cqe_next; \
|
||||
else \
|
||||
(elm)->field.cqe_prev->field.cqe_next = \
|
||||
(elm)->field.cqe_next; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define CIRCLEQ_FOREACH(var, head, field) \
|
||||
for ((var) = ((head)->cqh_first); \
|
||||
(var) != (const void *)(head); \
|
||||
(var) = ((var)->field.cqe_next))
|
||||
|
||||
#define CIRCLEQ_FOREACH_REVERSE(var, head, field) \
|
||||
for ((var) = ((head)->cqh_last); \
|
||||
(var) != (const void *)(head); \
|
||||
(var) = ((var)->field.cqe_prev))
|
||||
|
||||
/*
|
||||
* Circular queue access methods.
|
||||
*/
|
||||
#define CIRCLEQ_EMPTY(head) ((head)->cqh_first == (void *)(head))
|
||||
#define CIRCLEQ_FIRST(head) ((head)->cqh_first)
|
||||
#define CIRCLEQ_LAST(head) ((head)->cqh_last)
|
||||
#define CIRCLEQ_NEXT(elm, field) ((elm)->field.cqe_next)
|
||||
#define CIRCLEQ_PREV(elm, field) ((elm)->field.cqe_prev)
|
||||
|
||||
#define CIRCLEQ_LOOP_NEXT(head, elm, field) \
|
||||
(((elm)->field.cqe_next == (void *)(head)) \
|
||||
? ((head)->cqh_first) \
|
||||
: (elm->field.cqe_next))
|
||||
#define CIRCLEQ_LOOP_PREV(head, elm, field) \
|
||||
(((elm)->field.cqe_prev == (void *)(head)) \
|
||||
? ((head)->cqh_last) \
|
||||
: (elm->field.cqe_prev))
|
||||
|
||||
#endif /* sys/queue.h */
|
||||
11
toolchain/musl/patches/100-add_glob_onlydir.patch
Normal file
11
toolchain/musl/patches/100-add_glob_onlydir.patch
Normal file
@@ -0,0 +1,11 @@
|
||||
--- a/include/glob.h
|
||||
+++ b/include/glob.h
|
||||
@@ -34,6 +34,8 @@ void globfree(glob_t *);
|
||||
#define GLOB_TILDE 0x1000
|
||||
#define GLOB_TILDE_CHECK 0x4000
|
||||
|
||||
+#define GLOB_ONLYDIR 0x100
|
||||
+
|
||||
#define GLOB_NOSPACE 1
|
||||
#define GLOB_ABORTED 2
|
||||
#define GLOB_NOMATCH 3
|
||||
28
toolchain/musl/patches/110-read_timezone_from_fs.patch
Normal file
28
toolchain/musl/patches/110-read_timezone_from_fs.patch
Normal file
@@ -0,0 +1,28 @@
|
||||
--- a/src/time/__tz.c
|
||||
+++ b/src/time/__tz.c
|
||||
@@ -25,6 +25,9 @@ static int r0[5], r1[5];
|
||||
static const unsigned char *zi, *trans, *index, *types, *abbrevs, *abbrevs_end;
|
||||
static size_t map_size;
|
||||
|
||||
+static const char *tzfile;
|
||||
+static size_t tzfile_size;
|
||||
+
|
||||
static char old_tz_buf[32];
|
||||
static char *old_tz = old_tz_buf;
|
||||
static size_t old_tz_size = sizeof old_tz_buf;
|
||||
@@ -125,6 +128,15 @@ static void do_tzset()
|
||||
"/usr/share/zoneinfo/\0/share/zoneinfo/\0/etc/zoneinfo/\0";
|
||||
|
||||
s = getenv("TZ");
|
||||
+
|
||||
+ /* if TZ is empty try to read it from /etc/TZ */
|
||||
+ if (!s || !*s) {
|
||||
+ if (tzfile)
|
||||
+ __munmap((void*)tzfile, tzfile_size);
|
||||
+
|
||||
+ s = tzfile = (void *)__map_file("/etc/TZ", &tzfile_size);
|
||||
+ }
|
||||
+
|
||||
if (!s) s = "/etc/localtime";
|
||||
if (!*s) s = __utc;
|
||||
|
||||
53
toolchain/musl/patches/200-add_libssp_nonshared.patch
Normal file
53
toolchain/musl/patches/200-add_libssp_nonshared.patch
Normal file
@@ -0,0 +1,53 @@
|
||||
From 7ec87fbbc3cac99b4173d082dd6195f47c9a32e7 Mon Sep 17 00:00:00 2001
|
||||
From: Steven Barth <steven@midlink.org>
|
||||
Date: Mon, 22 Jun 2015 11:01:56 +0200
|
||||
Subject: [PATCH] Add libssp_nonshared.a so GCC's is not needed
|
||||
|
||||
Signed-off-by: Steven Barth <steven@midlink.org>
|
||||
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -66,7 +66,7 @@ CRT_LIBS = $(addprefix lib/,$(notdir $(C
|
||||
STATIC_LIBS = lib/libc.a
|
||||
SHARED_LIBS = lib/libc.so
|
||||
TOOL_LIBS = lib/musl-gcc.specs
|
||||
-ALL_LIBS = $(CRT_LIBS) $(STATIC_LIBS) $(SHARED_LIBS) $(EMPTY_LIBS) $(TOOL_LIBS)
|
||||
+ALL_LIBS = $(CRT_LIBS) $(STATIC_LIBS) $(SHARED_LIBS) $(EMPTY_LIBS) $(TOOL_LIBS) lib/libssp_nonshared.a
|
||||
ALL_TOOLS = obj/musl-gcc
|
||||
|
||||
WRAPCC_GCC = gcc
|
||||
@@ -86,7 +86,7 @@ else
|
||||
|
||||
all: $(ALL_LIBS) $(ALL_TOOLS)
|
||||
|
||||
-OBJ_DIRS = $(sort $(patsubst %/,%,$(dir $(ALL_LIBS) $(ALL_TOOLS) $(ALL_OBJS) $(GENH) $(GENH_INT))) obj/include)
|
||||
+OBJ_DIRS = $(sort $(patsubst %/,%,$(dir $(ALL_LIBS) $(ALL_TOOLS) $(ALL_OBJS) $(GENH) $(GENH_INT))) obj/include obj/libssp_nonshared)
|
||||
|
||||
$(ALL_LIBS) $(ALL_TOOLS) $(ALL_OBJS) $(ALL_OBJS:%.o=%.lo) $(GENH) $(GENH_INT): | $(OBJ_DIRS)
|
||||
|
||||
@@ -113,6 +113,8 @@ obj/crt/rcrt1.o: $(srcdir)/ldso/dlstart.
|
||||
|
||||
obj/crt/Scrt1.o obj/crt/rcrt1.o: CFLAGS_ALL += -fPIC
|
||||
|
||||
+obj/libssp_nonshared/__stack_chk_fail_local.o: CFLAGS_ALL += $(CFLAGS_NOSSP)
|
||||
+
|
||||
OPTIMIZE_SRCS = $(wildcard $(OPTIMIZE_GLOBS:%=$(srcdir)/src/%))
|
||||
$(OPTIMIZE_SRCS:$(srcdir)/%.c=obj/%.o) $(OPTIMIZE_SRCS:$(srcdir)/%.c=obj/%.lo): CFLAGS += -O3
|
||||
|
||||
@@ -165,6 +167,11 @@ lib/libc.a: $(AOBJS)
|
||||
$(AR) rc $@ $(AOBJS)
|
||||
$(RANLIB) $@
|
||||
|
||||
+lib/libssp_nonshared.a: obj/libssp_nonshared/__stack_chk_fail_local.o
|
||||
+ rm -f $@
|
||||
+ $(AR) rc $@ $<
|
||||
+ $(RANLIB) $@
|
||||
+
|
||||
$(EMPTY_LIBS):
|
||||
rm -f $@
|
||||
$(AR) rc $@
|
||||
--- /dev/null
|
||||
+++ b/libssp_nonshared/__stack_chk_fail_local.c
|
||||
@@ -0,0 +1,2 @@
|
||||
+#include "atomic.h"
|
||||
+void __attribute__((visibility ("hidden"))) __stack_chk_fail_local(void) { a_crash(); }
|
||||
11
toolchain/musl/patches/300-relative.patch
Normal file
11
toolchain/musl/patches/300-relative.patch
Normal file
@@ -0,0 +1,11 @@
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -215,7 +215,7 @@ $(DESTDIR)$(includedir)/%: $(srcdir)/inc
|
||||
$(INSTALL) -D -m 644 $< $@
|
||||
|
||||
$(DESTDIR)$(LDSO_PATHNAME): $(DESTDIR)$(libdir)/libc.so
|
||||
- $(INSTALL) -D -l $(libdir)/libc.so $@ || true
|
||||
+ $(INSTALL) -D -l libc.so $@ || true
|
||||
|
||||
install-libs: $(ALL_LIBS:lib/%=$(DESTDIR)$(libdir)/%) $(if $(SHARED_LIBS),$(DESTDIR)$(LDSO_PATHNAME),)
|
||||
|
||||
@@ -0,0 +1,197 @@
|
||||
From e6683d001a95d7c3d4d992496f00f77e01fcd268 Mon Sep 17 00:00:00 2001
|
||||
From: Hauke Mehrtens <hauke@hauke-m.de>
|
||||
Date: Sun, 22 Nov 2015 15:04:23 +0100
|
||||
Subject: [PATCH v2] Add format attribute to some function declarations
|
||||
|
||||
GCC and Clang are able to check the format arguments given to a
|
||||
function and warn the user if there is a error in the format arguments
|
||||
or if there is a potential uncontrolled format string security problem
|
||||
in the code. GCC does this automatically for some functions like
|
||||
printf(), but it is also possible to annotate other functions in a way
|
||||
that it will check them too. This feature is used by glibc for many
|
||||
functions. This patch adds the attribute to the some functions of musl
|
||||
expect for these functions where gcc automatically adds it.
|
||||
|
||||
GCC automatically adds checks for these functions: printf, fprintf,
|
||||
sprintf, scanf, fscanf, sscanf, strftime, vprintf, vfprintf and
|
||||
vsprintf.
|
||||
|
||||
The documentation from gcc is here:
|
||||
https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html
|
||||
|
||||
The documentation from Clang is here:
|
||||
http://clang.llvm.org/docs/AttributeReference.html#format-gnu-format
|
||||
|
||||
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
|
||||
---
|
||||
include/err.h | 26 +++++++++++++++++---------
|
||||
include/monetary.h | 12 ++++++++++--
|
||||
include/stdio.h | 29 ++++++++++++++++++++---------
|
||||
include/syslog.h | 12 ++++++++++--
|
||||
4 files changed, 57 insertions(+), 22 deletions(-)
|
||||
|
||||
--- a/include/err.h
|
||||
+++ b/include/err.h
|
||||
@@ -8,15 +8,23 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
-void warn(const char *, ...);
|
||||
-void vwarn(const char *, va_list);
|
||||
-void warnx(const char *, ...);
|
||||
-void vwarnx(const char *, va_list);
|
||||
+#if __GNUC__ >= 3
|
||||
+#define __fp(x, y) __attribute__ ((__format__ (__printf__, x, y)))
|
||||
+#else
|
||||
+#define __fp(x, y)
|
||||
+#endif
|
||||
+
|
||||
+void warn(const char *, ...) __fp(1, 2);
|
||||
+void vwarn(const char *, va_list) __fp(1, 0);
|
||||
+void warnx(const char *, ...) __fp(1, 2);
|
||||
+void vwarnx(const char *, va_list) __fp(1, 0);
|
||||
+
|
||||
+_Noreturn void err(int, const char *, ...) __fp(2, 3);
|
||||
+_Noreturn void verr(int, const char *, va_list) __fp(2, 0);
|
||||
+_Noreturn void errx(int, const char *, ...) __fp(2, 3);
|
||||
+_Noreturn void verrx(int, const char *, va_list) __fp(2, 0);
|
||||
|
||||
-_Noreturn void err(int, const char *, ...);
|
||||
-_Noreturn void verr(int, const char *, va_list);
|
||||
-_Noreturn void errx(int, const char *, ...);
|
||||
-_Noreturn void verrx(int, const char *, va_list);
|
||||
+#undef __fp
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
--- a/include/monetary.h
|
||||
+++ b/include/monetary.h
|
||||
@@ -13,8 +13,16 @@ extern "C" {
|
||||
|
||||
#include <bits/alltypes.h>
|
||||
|
||||
-ssize_t strfmon(char *__restrict, size_t, const char *__restrict, ...);
|
||||
-ssize_t strfmon_l(char *__restrict, size_t, locale_t, const char *__restrict, ...);
|
||||
+#if __GNUC__ >= 3
|
||||
+#define __fsfm(x, y) __attribute__ ((__format__ (__strfmon__, x, y)))
|
||||
+#else
|
||||
+#define __fsfm(x, y)
|
||||
+#endif
|
||||
+
|
||||
+ssize_t strfmon(char *__restrict, size_t, const char *__restrict, ...) __fsfm(3, 4);
|
||||
+ssize_t strfmon_l(char *__restrict, size_t, locale_t, const char *__restrict, ...) __fsfm(4, 5);
|
||||
+
|
||||
+#undef __fsfm
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
--- a/include/stdio.h
|
||||
+++ b/include/stdio.h
|
||||
@@ -25,6 +25,14 @@ extern "C" {
|
||||
|
||||
#include <bits/alltypes.h>
|
||||
|
||||
+#if __GNUC__ >= 3
|
||||
+#define __fp(x, y) __attribute__ ((__format__ (__printf__, x, y)))
|
||||
+#define __fs(x, y) __attribute__ ((__format__ (__scanf__, x, y)))
|
||||
+#else
|
||||
+#define __fp(x, y)
|
||||
+#define __fs(x, y)
|
||||
+#endif
|
||||
+
|
||||
#ifdef __cplusplus
|
||||
#define NULL 0L
|
||||
#else
|
||||
@@ -107,19 +115,19 @@ int puts(const char *);
|
||||
int printf(const char *__restrict, ...);
|
||||
int fprintf(FILE *__restrict, const char *__restrict, ...);
|
||||
int sprintf(char *__restrict, const char *__restrict, ...);
|
||||
-int snprintf(char *__restrict, size_t, const char *__restrict, ...);
|
||||
+int snprintf(char *__restrict, size_t, const char *__restrict, ...) __fp(3, 4);
|
||||
|
||||
int vprintf(const char *__restrict, __isoc_va_list);
|
||||
int vfprintf(FILE *__restrict, const char *__restrict, __isoc_va_list);
|
||||
int vsprintf(char *__restrict, const char *__restrict, __isoc_va_list);
|
||||
-int vsnprintf(char *__restrict, size_t, const char *__restrict, __isoc_va_list);
|
||||
+int vsnprintf(char *__restrict, size_t, const char *__restrict, __isoc_va_list) __fp(3, 0);
|
||||
|
||||
int scanf(const char *__restrict, ...);
|
||||
int fscanf(FILE *__restrict, const char *__restrict, ...);
|
||||
int sscanf(const char *__restrict, const char *__restrict, ...);
|
||||
-int vscanf(const char *__restrict, __isoc_va_list);
|
||||
-int vfscanf(FILE *__restrict, const char *__restrict, __isoc_va_list);
|
||||
-int vsscanf(const char *__restrict, const char *__restrict, __isoc_va_list);
|
||||
+int vscanf(const char *__restrict, __isoc_va_list) __fs(1, 0);
|
||||
+int vfscanf(FILE *__restrict, const char *__restrict, __isoc_va_list) __fs(2, 0);
|
||||
+int vsscanf(const char *__restrict, const char *__restrict, __isoc_va_list) __fs(2, 0);
|
||||
|
||||
void perror(const char *);
|
||||
|
||||
@@ -140,8 +148,8 @@ int pclose(FILE *);
|
||||
int fileno(FILE *);
|
||||
int fseeko(FILE *, off_t, int);
|
||||
off_t ftello(FILE *);
|
||||
-int dprintf(int, const char *__restrict, ...);
|
||||
-int vdprintf(int, const char *__restrict, __isoc_va_list);
|
||||
+int dprintf(int, const char *__restrict, ...) __fp(2, 3);
|
||||
+int vdprintf(int, const char *__restrict, __isoc_va_list) __fp(2, 0);
|
||||
void flockfile(FILE *);
|
||||
int ftrylockfile(FILE *);
|
||||
void funlockfile(FILE *);
|
||||
@@ -180,8 +188,8 @@ int fileno_unlocked(FILE *);
|
||||
int getw(FILE *);
|
||||
int putw(int, FILE *);
|
||||
char *fgetln(FILE *, size_t *);
|
||||
-int asprintf(char **, const char *, ...);
|
||||
-int vasprintf(char **, const char *, __isoc_va_list);
|
||||
+int asprintf(char **, const char *, ...) __fp(2, 3);
|
||||
+int vasprintf(char **, const char *, __isoc_va_list) __fp(2, 0);
|
||||
#endif
|
||||
|
||||
#ifdef _GNU_SOURCE
|
||||
@@ -203,6 +211,9 @@ typedef struct _IO_cookie_io_functions_t
|
||||
FILE *fopencookie(void *, const char *, cookie_io_functions_t);
|
||||
#endif
|
||||
|
||||
+#undef __fp
|
||||
+#undef __fs
|
||||
+
|
||||
#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
|
||||
#define tmpfile64 tmpfile
|
||||
#define fopen64 fopen
|
||||
--- a/include/syslog.h
|
||||
+++ b/include/syslog.h
|
||||
@@ -56,16 +56,22 @@ extern "C" {
|
||||
#define LOG_NOWAIT 0x10
|
||||
#define LOG_PERROR 0x20
|
||||
|
||||
+#if __GNUC__ >= 3
|
||||
+#define __fp(x, y) __attribute__ ((__format__ (__printf__, x, y)))
|
||||
+#else
|
||||
+#define __fp(x, y)
|
||||
+#endif
|
||||
+
|
||||
void closelog (void);
|
||||
void openlog (const char *, int, int);
|
||||
int setlogmask (int);
|
||||
-void syslog (int, const char *, ...);
|
||||
+void syslog (int, const char *, ...) __fp(2, 3);
|
||||
|
||||
#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
|
||||
#define _PATH_LOG "/dev/log"
|
||||
#define __NEED_va_list
|
||||
#include <bits/alltypes.h>
|
||||
-void vsyslog (int, const char *, va_list);
|
||||
+void vsyslog (int, const char *, va_list) __fp(2, 0);
|
||||
#if defined(SYSLOG_NAMES)
|
||||
#define INTERNAL_NOPRI 0x10
|
||||
#define INTERNAL_MARK (LOG_NFACILITIES<<3)
|
||||
@@ -93,6 +99,8 @@ typedef struct {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
+#undef __fp
|
||||
+
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,69 @@
|
||||
From e01b5939b38aea5ecbe41670643199825874b26c Mon Sep 17 00:00:00 2001
|
||||
From: Rich Felker <dalias@aerifal.cx>
|
||||
Date: Thu, 21 May 2020 23:32:45 -0400
|
||||
Subject: [PATCH 2/4] don't use libc.threads_minus_1 as relaxed atomic for
|
||||
skipping locks
|
||||
|
||||
after all but the last thread exits, the next thread to observe
|
||||
libc.threads_minus_1==0 and conclude that it can skip locking fails to
|
||||
synchronize with any changes to memory that were made by the
|
||||
last-exiting thread. this can produce data races.
|
||||
|
||||
on some archs, at least x86, memory synchronization is unlikely to be
|
||||
a problem; however, with the inline locks in malloc, skipping the lock
|
||||
also eliminated the compiler barrier, and caused code that needed to
|
||||
re-check chunk in-use bits after obtaining the lock to reuse a stale
|
||||
value, possibly from before the process became single-threaded. this
|
||||
in turn produced corruption of the heap state.
|
||||
|
||||
some uses of libc.threads_minus_1 remain, especially for allocation of
|
||||
new TLS in the dynamic linker; otherwise, it could be removed
|
||||
entirely. it's made non-volatile to reflect that the remaining
|
||||
accesses are only made under lock on the thread list.
|
||||
|
||||
instead of libc.threads_minus_1, libc.threaded is now used for
|
||||
skipping locks. the difference is that libc.threaded is permanently
|
||||
true once an additional thread has been created. this will produce
|
||||
some performance regression in processes that are mostly
|
||||
single-threaded but occasionally creating threads. in the future it
|
||||
may be possible to bring back the full lock-skipping, but more care
|
||||
needs to be taken to produce a safe design.
|
||||
---
|
||||
src/internal/libc.h | 2 +-
|
||||
src/malloc/malloc.c | 2 +-
|
||||
src/thread/__lock.c | 2 +-
|
||||
3 files changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/src/internal/libc.h
|
||||
+++ b/src/internal/libc.h
|
||||
@@ -21,7 +21,7 @@ struct __libc {
|
||||
int can_do_threads;
|
||||
int threaded;
|
||||
int secure;
|
||||
- volatile int threads_minus_1;
|
||||
+ int threads_minus_1;
|
||||
size_t *auxv;
|
||||
struct tls_module *tls_head;
|
||||
size_t tls_size, tls_align, tls_cnt;
|
||||
--- a/src/malloc/malloc.c
|
||||
+++ b/src/malloc/malloc.c
|
||||
@@ -26,7 +26,7 @@ int __malloc_replaced;
|
||||
|
||||
static inline void lock(volatile int *lk)
|
||||
{
|
||||
- if (libc.threads_minus_1)
|
||||
+ if (libc.threaded)
|
||||
while(a_swap(lk, 1)) __wait(lk, lk+1, 1, 1);
|
||||
}
|
||||
|
||||
--- a/src/thread/__lock.c
|
||||
+++ b/src/thread/__lock.c
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
void __lock(volatile int *l)
|
||||
{
|
||||
- if (!libc.threads_minus_1) return;
|
||||
+ if (!libc.threaded) return;
|
||||
/* fast path: INT_MIN for the lock, +1 for the congestion */
|
||||
int current = a_cas(l, 0, INT_MIN + 1);
|
||||
if (!current) return;
|
||||
65
toolchain/musl/patches/700-wcsnrtombs-cve-2020-28928.diff
Normal file
65
toolchain/musl/patches/700-wcsnrtombs-cve-2020-28928.diff
Normal file
@@ -0,0 +1,65 @@
|
||||
diff --git a/src/multibyte/wcsnrtombs.c b/src/multibyte/wcsnrtombs.c
|
||||
index 676932b5..95e25e70 100644
|
||||
--- a/src/multibyte/wcsnrtombs.c
|
||||
+++ b/src/multibyte/wcsnrtombs.c
|
||||
@@ -1,41 +1,33 @@
|
||||
#include <wchar.h>
|
||||
+#include <limits.h>
|
||||
+#include <string.h>
|
||||
|
||||
size_t wcsnrtombs(char *restrict dst, const wchar_t **restrict wcs, size_t wn, size_t n, mbstate_t *restrict st)
|
||||
{
|
||||
- size_t l, cnt=0, n2;
|
||||
- char *s, buf[256];
|
||||
const wchar_t *ws = *wcs;
|
||||
- const wchar_t *tmp_ws;
|
||||
-
|
||||
- if (!dst) s = buf, n = sizeof buf;
|
||||
- else s = dst;
|
||||
-
|
||||
- while ( ws && n && ( (n2=wn)>=n || n2>32 ) ) {
|
||||
- if (n2>=n) n2=n;
|
||||
- tmp_ws = ws;
|
||||
- l = wcsrtombs(s, &ws, n2, 0);
|
||||
- if (!(l+1)) {
|
||||
- cnt = l;
|
||||
- n = 0;
|
||||
+ size_t cnt = 0;
|
||||
+ if (!dst) n=0;
|
||||
+ while (ws && wn) {
|
||||
+ char tmp[MB_LEN_MAX];
|
||||
+ size_t l = wcrtomb(n<MB_LEN_MAX ? tmp : dst, *ws, 0);
|
||||
+ if (l==-1) {
|
||||
+ cnt = -1;
|
||||
break;
|
||||
}
|
||||
- if (s != buf) {
|
||||
- s += l;
|
||||
+ if (dst) {
|
||||
+ if (n<MB_LEN_MAX) {
|
||||
+ if (l>n) break;
|
||||
+ memcpy(dst, tmp, l);
|
||||
+ }
|
||||
+ dst += l;
|
||||
n -= l;
|
||||
}
|
||||
- wn = ws ? wn - (ws - tmp_ws) : 0;
|
||||
- cnt += l;
|
||||
- }
|
||||
- if (ws) while (n && wn) {
|
||||
- l = wcrtomb(s, *ws, 0);
|
||||
- if ((l+1)<=1) {
|
||||
- if (!l) ws = 0;
|
||||
- else cnt = l;
|
||||
+ if (!*ws) {
|
||||
+ ws = 0;
|
||||
break;
|
||||
}
|
||||
- ws++; wn--;
|
||||
- /* safe - this loop runs fewer than sizeof(buf) times */
|
||||
- s+=l; n-=l;
|
||||
+ ws++;
|
||||
+ wn--;
|
||||
cnt += l;
|
||||
}
|
||||
if (dst) *wcs = ws;
|
||||
100
toolchain/musl/patches/900-iconv_size_hack.patch
Normal file
100
toolchain/musl/patches/900-iconv_size_hack.patch
Normal file
@@ -0,0 +1,100 @@
|
||||
--- a/src/locale/iconv.c
|
||||
+++ b/src/locale/iconv.c
|
||||
@@ -48,6 +48,7 @@ static const unsigned char charmaps[] =
|
||||
"utf16\0\0\312"
|
||||
"ucs4\0utf32\0\0\313"
|
||||
"ucs2\0\0\314"
|
||||
+#ifdef FULL_ICONV
|
||||
"eucjp\0\0\320"
|
||||
"shiftjis\0sjis\0\0\321"
|
||||
"iso2022jp\0\0\322"
|
||||
@@ -56,6 +57,7 @@ static const unsigned char charmaps[] =
|
||||
"gb2312\0\0\332"
|
||||
"big5\0bigfive\0cp950\0big5hkscs\0\0\340"
|
||||
"euckr\0ksc5601\0ksx1001\0cp949\0\0\350"
|
||||
+#endif
|
||||
#include "codepages.h"
|
||||
;
|
||||
|
||||
@@ -66,6 +68,7 @@ static const unsigned short legacy_chars
|
||||
#include "legacychars.h"
|
||||
};
|
||||
|
||||
+#ifdef FULL_ICONV
|
||||
static const unsigned short jis0208[84][94] = {
|
||||
#include "jis0208.h"
|
||||
};
|
||||
@@ -85,6 +88,7 @@ static const unsigned short hkscs[] = {
|
||||
static const unsigned short ksc[93][94] = {
|
||||
#include "ksc.h"
|
||||
};
|
||||
+#endif
|
||||
|
||||
static const unsigned short rev_jis[] = {
|
||||
#include "revjis.h"
|
||||
@@ -205,6 +209,7 @@ static unsigned legacy_map(const unsigne
|
||||
return x < 256 ? x : legacy_chars[x-256];
|
||||
}
|
||||
|
||||
+#ifdef FULL_ICONV
|
||||
static unsigned uni_to_jis(unsigned c)
|
||||
{
|
||||
unsigned nel = sizeof rev_jis / sizeof *rev_jis;
|
||||
@@ -223,6 +228,7 @@ static unsigned uni_to_jis(unsigned c)
|
||||
}
|
||||
}
|
||||
}
|
||||
+#endif
|
||||
|
||||
size_t iconv(iconv_t cd, char **restrict in, size_t *restrict inb, char **restrict out, size_t *restrict outb)
|
||||
{
|
||||
@@ -319,6 +325,7 @@ size_t iconv(iconv_t cd, char **restrict
|
||||
}
|
||||
type = scd->state;
|
||||
continue;
|
||||
+#ifdef FULL_ICONV
|
||||
case SHIFT_JIS:
|
||||
if (c < 128) break;
|
||||
if (c-0xa1 <= 0xdf-0xa1) {
|
||||
@@ -518,6 +525,7 @@ size_t iconv(iconv_t cd, char **restrict
|
||||
c = ksc[c][d];
|
||||
if (!c) goto ilseq;
|
||||
break;
|
||||
+#endif
|
||||
default:
|
||||
if (!c) break;
|
||||
c = legacy_map(map, c);
|
||||
@@ -559,6 +567,7 @@ size_t iconv(iconv_t cd, char **restrict
|
||||
}
|
||||
}
|
||||
goto subst;
|
||||
+#ifdef FULL_ICONV
|
||||
case SHIFT_JIS:
|
||||
if (c < 128) goto revout;
|
||||
if (c == 0xa5) {
|
||||
@@ -632,6 +641,7 @@ size_t iconv(iconv_t cd, char **restrict
|
||||
*(*out)++ = 'B';
|
||||
*outb -= 8;
|
||||
break;
|
||||
+#endif
|
||||
case UCS2:
|
||||
totype = UCS2BE;
|
||||
case UCS2BE:
|
||||
--- a/src/locale/codepages.h
|
||||
+++ b/src/locale/codepages.h
|
||||
@@ -129,6 +129,7 @@
|
||||
"\340\204\43\316\100\344\34\144\316\71\350\244\243\316\72\354\264\343\316\73"
|
||||
"\21\361\44\317\74\364\30\145\17\124\146\345\243\317\76\374\134\304\327\77"
|
||||
|
||||
+#ifdef FULL_ICONV
|
||||
"cp1250\0"
|
||||
"windows1250\0"
|
||||
"\0\40"
|
||||
@@ -239,6 +240,7 @@
|
||||
"\20\105\163\330\64\324\324\145\315\65\330\144\243\315\66\334\334\145\330\67"
|
||||
"\340\204\43\316\100\344\224\143\316\71\350\244\243\316\72\205\265\343\316\73"
|
||||
"\21\305\203\330\74\364\330\145\317\75\370\344\243\317\76\374\340\65\362\77"
|
||||
+#endif
|
||||
|
||||
"koi8r\0"
|
||||
"\0\40"
|
||||
75
toolchain/musl/patches/901-crypt_size_hack.patch
Normal file
75
toolchain/musl/patches/901-crypt_size_hack.patch
Normal file
@@ -0,0 +1,75 @@
|
||||
--- a/src/crypt/crypt_sha512.c
|
||||
+++ b/src/crypt/crypt_sha512.c
|
||||
@@ -13,6 +13,17 @@
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
+#ifdef CRYPT_SIZE_HACK
|
||||
+#include <errno.h>
|
||||
+
|
||||
+char *__crypt_sha512(const char *key, const char *setting, char *output)
|
||||
+{
|
||||
+ errno = ENOSYS;
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+#else
|
||||
+
|
||||
/* public domain sha512 implementation based on fips180-3 */
|
||||
/* >=2^64 bits messages are not supported (about 2000 peta bytes) */
|
||||
|
||||
@@ -369,3 +380,4 @@ char *__crypt_sha512(const char *key, co
|
||||
return "*";
|
||||
return p;
|
||||
}
|
||||
+#endif
|
||||
--- a/src/crypt/crypt_blowfish.c
|
||||
+++ b/src/crypt/crypt_blowfish.c
|
||||
@@ -50,6 +50,17 @@
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
+#ifdef CRYPT_SIZE_HACK
|
||||
+#include <errno.h>
|
||||
+
|
||||
+char *__crypt_blowfish(const char *key, const char *setting, char *output)
|
||||
+{
|
||||
+ errno = ENOSYS;
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+#else
|
||||
+
|
||||
typedef uint32_t BF_word;
|
||||
typedef int32_t BF_word_signed;
|
||||
|
||||
@@ -796,3 +807,4 @@ char *__crypt_blowfish(const char *key,
|
||||
|
||||
return "*";
|
||||
}
|
||||
+#endif
|
||||
--- a/src/crypt/crypt_sha256.c
|
||||
+++ b/src/crypt/crypt_sha256.c
|
||||
@@ -13,6 +13,17 @@
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
+#ifdef CRYPT_SIZE_HACK
|
||||
+#include <errno.h>
|
||||
+
|
||||
+char *__crypt_sha256(const char *key, const char *setting, char *output)
|
||||
+{
|
||||
+ errno = ENOSYS;
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+#else
|
||||
+
|
||||
/* public domain sha256 implementation based on fips180-3 */
|
||||
|
||||
struct sha256 {
|
||||
@@ -320,3 +331,4 @@ char *__crypt_sha256(const char *key, co
|
||||
return "*";
|
||||
return p;
|
||||
}
|
||||
+#endif
|
||||
Reference in New Issue
Block a user