diff mbox

[libc/musl] (v0.1) Add support for musl-libc

Message ID 1405718252-2066-1-git-send-email-bryanhundven@gmail.com
State Superseded
Headers show

Commit Message

Bryan Hundven July 18, 2014, 9:17 p.m. UTC
This change is based on a patch by Timo Teräs:
    http://patchwork.ozlabs.org/patch/257187/

This patch, as the original, is an RFC. Currently a minimal armel- is
the only target tested. sh[34][a]- support is in crosstool-ng, but not
in the 020-musl-support.patch.

Please let me know if you have any comments, feedback, and/or
suggestions.

Signed-off-by: Bryan Hundven <bryanhundven@gmail.com>
---
 config/libc.in                                     |  11 +
 config/libc/musl.in                                |  47 +++
 config/libc/musl.in.2                              |   2 +
 patches/gcc/4.8.2/020-musl-support.patch           | 381 ++++++++++++++++++++
 patches/gcc/4.9.0/020-musl-support.patch           | 385 +++++++++++++++++++++
 patches/musl/1.0.3/001-fix_linker_regression.patch |  64 ++++
 .../1.0.3/002-fix_mips_linker_regression.patch     |  88 +++++
 patches/musl/1.1.3/001-fix_linker_regression.patch |  64 ++++
 .../1.1.3/002-fix_mips_linker_regression.patch     |  88 +++++
 .../arm-unknown-linux-muslgnueabi/crosstool.config |  10 +
 samples/arm-unknown-linux-muslgnueabi/reported.by  |   3 +
 scripts/build/arch/arm.sh                          |   1 +
 scripts/build/libc/musl.sh                         | 111 ++++++
 scripts/functions                                  |   1 +
 14 files changed, 1256 insertions(+)
 create mode 100644 config/libc/musl.in
 create mode 100644 config/libc/musl.in.2
 create mode 100644 patches/gcc/4.8.2/020-musl-support.patch
 create mode 100644 patches/gcc/4.9.0/020-musl-support.patch
 create mode 100644 patches/musl/1.0.3/001-fix_linker_regression.patch
 create mode 100644 patches/musl/1.0.3/002-fix_mips_linker_regression.patch
 create mode 100644 patches/musl/1.1.3/001-fix_linker_regression.patch
 create mode 100644 patches/musl/1.1.3/002-fix_mips_linker_regression.patch
 create mode 100644 samples/arm-unknown-linux-muslgnueabi/crosstool.config
 create mode 100644 samples/arm-unknown-linux-muslgnueabi/reported.by
 create mode 100644 scripts/build/libc/musl.sh

Comments

Bryan Hundven July 18, 2014, 9:53 p.m. UTC | #1
List,

On Fri, Jul 18, 2014 at 2:17 PM, Bryan Hundven <bryanhundven@gmail.com> wrote:
> This change is based on a patch by Timo Teräs:
>     http://patchwork.ozlabs.org/patch/257187/
>
> This patch, as the original, is an RFC. Currently a minimal armel- is
> the only target tested. sh[34][a]- support is in crosstool-ng, but not
> in the 020-musl-support.patch.
>
> Please let me know if you have any comments, feedback, and/or
> suggestions.
>
> Signed-off-by: Bryan Hundven <bryanhundven@gmail.com>
> ---
>  config/libc.in                                     |  11 +
>  config/libc/musl.in                                |  47 +++
>  config/libc/musl.in.2                              |   2 +
>  patches/gcc/4.8.2/020-musl-support.patch           | 381 ++++++++++++++++++++
>  patches/gcc/4.9.0/020-musl-support.patch           | 385 +++++++++++++++++++++
>  patches/musl/1.0.3/001-fix_linker_regression.patch |  64 ++++
>  .../1.0.3/002-fix_mips_linker_regression.patch     |  88 +++++
>  patches/musl/1.1.3/001-fix_linker_regression.patch |  64 ++++
>  .../1.1.3/002-fix_mips_linker_regression.patch     |  88 +++++
>  .../arm-unknown-linux-muslgnueabi/crosstool.config |  10 +
>  samples/arm-unknown-linux-muslgnueabi/reported.by  |   3 +
>  scripts/build/arch/arm.sh                          |   1 +
>  scripts/build/libc/musl.sh                         | 111 ++++++
>  scripts/functions                                  |   1 +
>  14 files changed, 1256 insertions(+)
>  create mode 100644 config/libc/musl.in
>  create mode 100644 config/libc/musl.in.2
>  create mode 100644 patches/gcc/4.8.2/020-musl-support.patch
>  create mode 100644 patches/gcc/4.9.0/020-musl-support.patch
>  create mode 100644 patches/musl/1.0.3/001-fix_linker_regression.patch
>  create mode 100644 patches/musl/1.0.3/002-fix_mips_linker_regression.patch
>  create mode 100644 patches/musl/1.1.3/001-fix_linker_regression.patch
>  create mode 100644 patches/musl/1.1.3/002-fix_mips_linker_regression.patch
>  create mode 100644 samples/arm-unknown-linux-muslgnueabi/crosstool.config
>  create mode 100644 samples/arm-unknown-linux-muslgnueabi/reported.by
>  create mode 100644 scripts/build/libc/musl.sh
>
> diff --git a/config/libc.in b/config/libc.in
> index 03f5db2..ff9ce9e 100644
> --- a/config/libc.in
> +++ b/config/libc.in
> @@ -28,6 +28,10 @@ config LIBC_SUPPORT_NPTL
>      bool
>      select LIBC_SUPPORT_THREADS_ANY
>
> +config LIBC_SUPPORT_MUSL
> +    bool
> +    select LIBC_SUPPORT_THREADS_ANY
> +
>  config LIBC_SUPPORT_LINUXTHREADS
>      bool
>      select LIBC_SUPPORT_THREADS_ANY
> @@ -42,6 +46,7 @@ config LIBC_SUPPORT_THREADS_NONE
>  config THREADS
>      string
>      default "nptl"          if THREADS_NPTL
> +    default "musl"          if THREADS_MUSL
>      default "linuxthreads"  if THREADS_LINUXTHREADS
>      default "win32"         if THREADS_WIN32THREADS
>      default "none"          if THREADS_NONE || LIBC_none
> @@ -55,6 +60,7 @@ choice
>      bool
>      prompt "Threading implementation to use:"
>      default THREADS_NPTL           if LIBC_SUPPORT_NPTL
> +    default THREADS_MUSL           if LIBC_SUPPORT_MUSL
>      default THREADS_LINUXTHREADS   if LIBC_SUPPORT_LINUXTHREADS && ! LIBC_SUPPORT_NPTL
>      default THREADS_WIN32          if LIBC_SUPPORT_WIN32THREADS
>      default THREADS_NONE           if ! LIBC_SUPPORT_THREADS_ANY
> @@ -64,6 +70,11 @@ config THREADS_NPTL
>      prompt "nptl"
>      depends on LIBC_SUPPORT_NPTL
>
> +config THREADS_MUSL
> +    bool
> +    prompt "musl"
> +    depends on LIBC_SUPPORT_MUSL
> +
>  config THREADS_LINUXTHREADS
>      bool
>      prompt "linuxthreads"
> diff --git a/config/libc/musl.in b/config/libc/musl.in
> new file mode 100644
> index 0000000..69f465c
> --- /dev/null
> +++ b/config/libc/musl.in
> @@ -0,0 +1,47 @@
> +# musl options
> +
> +## depends on ! WINDOWS && ! BARE_METAL
> +##
> +## select LIBC_SUPPORT_MUSL
> +## select CC_CORE_PASSES_NEEDED
> +##
> +## help Musl is a new standard library to power a new generation of Linux-based
> +## help devices. musl is lightweight, fast, simple, free, and strives to be
> +## help correct in the sense of standards-conformance and safety.
> +
> +choice
> +    bool
> +    prompt "musl version"
> +# Don't remove next line
> +# CT_INSERT_VERSION_BELOW
> +
> +config LIBC_MUSL_V_1_1_3
> +    bool
> +    prompt "1.1.3 (Mainline)"
> +    select LIBC_MUSL_DEFAULTS
> +    depends on EXPERIMENTAL
> +
> +config LIBC_MUSL_V_1_0_3
> +    bool
> +    prompt "1.0.3 (Stable)"
> +    select LIBC_MUSL_DEFAULTS
> +
> +config LIBC_MUSL_V_CUSTOM
> +    bool
> +    prompt "Custom musl"
> +    select LIBC_MUSL_DEFAULTS
> +    depends on EXPERIMENTAL
> +
> +endchoice
> +
> +config LIBC_MUSL_DEFAULTS
> +    bool
> +    select LIBC_SUPPORT_MUSL
> +
> +config LIBC_VERSION
> +    string
> +# Don't remove next line
> +# CT_INSERT_VERSION_STRING_BELOW
> +    default "1.1.3" if LIBC_MUSL_V_1_1_3
> +    default "1.0.3" if LIBC_MUSL_V_1_0_3
> +    default "custom" if LIBC_MUSL_V_CUSTOM
> diff --git a/config/libc/musl.in.2 b/config/libc/musl.in.2
> new file mode 100644
> index 0000000..6fd954c
> --- /dev/null
> +++ b/config/libc/musl.in.2
> @@ -0,0 +1,2 @@
> +# musl second-part options\n
> +
> diff --git a/patches/gcc/4.8.2/020-musl-support.patch b/patches/gcc/4.8.2/020-musl-support.patch
> new file mode 100644
> index 0000000..a4e4987
> --- /dev/null
> +++ b/patches/gcc/4.8.2/020-musl-support.patch
> @@ -0,0 +1,381 @@
> +diff --git a/gcc/config.gcc b/gcc/config.gcc
> +index 92d57dd..9ed4828 100644
> +--- a/gcc/config.gcc
> ++++ b/gcc/config.gcc
> +@@ -550,7 +550,7 @@ case ${target} in
> + esac
> +
> + # Common C libraries.
> +-tm_defines="$tm_defines LIBC_GLIBC=1 LIBC_UCLIBC=2 LIBC_BIONIC=3"
> ++tm_defines="$tm_defines LIBC_GLIBC=1 LIBC_UCLIBC=2 LIBC_BIONIC=3 LIBC_MUSL=4"
> +
> + # Common parts for widely ported systems.
> + case ${target} in
> +@@ -653,6 +653,9 @@ case ${target} in
> +     *-*-*uclibc*)
> +       tm_defines="$tm_defines DEFAULT_LIBC=LIBC_UCLIBC"
> +       ;;
> ++    *-*-*musl*)
> ++      tm_defines="$tm_defines DEFAULT_LIBC=LIBC_MUSL"
> ++      ;;
> +     *)
> +       tm_defines="$tm_defines DEFAULT_LIBC=LIBC_GLIBC"
> +       ;;
> +@@ -2114,6 +2117,10 @@ powerpc*-*-linux*)
> +           powerpc*-*-linux*paired*)
> +               tm_file="${tm_file} rs6000/750cl.h" ;;
> +       esac
> ++        case ${target} in
> ++            *-linux*-musl*)
> ++                enable_secureplt=yes ;;
> ++        esac
> +       if test x${enable_secureplt} = xyes; then
> +               tm_file="rs6000/secureplt.h ${tm_file}"
> +       fi
> +diff --git a/gcc/config/arm/linux-eabi.h b/gcc/config/arm/linux-eabi.h
> +index 4a425c8..6fa88b9 100644
> +--- a/gcc/config/arm/linux-eabi.h
> ++++ b/gcc/config/arm/linux-eabi.h
> +@@ -77,6 +77,10 @@
> +     %{mfloat-abi=soft*:" GLIBC_DYNAMIC_LINKER_SOFT_FLOAT "} \
> +     %{!mfloat-abi=*:" GLIBC_DYNAMIC_LINKER_DEFAULT "}"
> +
> ++/* musl has no "classic" (i.e. broken) mode */
> ++#undef  MUSL_DYNAMIC_LINKER
> ++#define MUSL_DYNAMIC_LINKER "/lib/ld-musl-arm.so.1"
> ++
> + /* At this point, bpabi.h will have clobbered LINK_SPEC.  We want to
> +    use the GNU/Linux version, not the generic BPABI version.  */
> + #undef  LINK_SPEC
> +diff --git a/gcc/config/i386/linux.h b/gcc/config/i386/linux.h
> +index 3c95ee0..93725fa 100644
> +--- a/gcc/config/i386/linux.h
> ++++ b/gcc/config/i386/linux.h
> +@@ -21,3 +21,4 @@ along with GCC; see the file COPYING3.  If not see
> +
> + #define GNU_USER_LINK_EMULATION "elf_i386"
> + #define GLIBC_DYNAMIC_LINKER "/lib/ld-linux.so.2"
> ++#define MUSL_DYNAMIC_LINKER "/lib/ld-musl-i386.so.1"
> +diff --git a/gcc/config/i386/linux64.h b/gcc/config/i386/linux64.h
> +index b793e08..d6e2bf9 100644
> +--- a/gcc/config/i386/linux64.h
> ++++ b/gcc/config/i386/linux64.h
> +@@ -30,3 +30,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
> + #define GLIBC_DYNAMIC_LINKER32 "/lib/ld-linux.so.2"
> + #define GLIBC_DYNAMIC_LINKER64 "/lib64/ld-linux-x86-64.so.2"
> + #define GLIBC_DYNAMIC_LINKERX32 "/libx32/ld-linux-x32.so.2"
> ++
> ++#define MUSL_DYNAMIC_LINKER32 "/lib/ld-musl-i386.so.1"
> ++#define MUSL_DYNAMIC_LINKER64 "/lib/ld-musl-x86_64.so.1"
> ++#define MUSL_DYNAMIC_LINKERX32 "/lib/ld-musl-x32.so.1"
> +diff --git a/gcc/config/linux.h b/gcc/config/linux.h
> +index 2be1079..dc88df9 100644
> +--- a/gcc/config/linux.h
> ++++ b/gcc/config/linux.h
> +@@ -32,10 +32,12 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
> + #define OPTION_GLIBC  (DEFAULT_LIBC == LIBC_GLIBC)
> + #define OPTION_UCLIBC (DEFAULT_LIBC == LIBC_UCLIBC)
> + #define OPTION_BIONIC (DEFAULT_LIBC == LIBC_BIONIC)
> ++#define OPTION_MUSL   (DEFAULT_LIBC == LIBC_MUSL)
> + #else
> + #define OPTION_GLIBC  (linux_libc == LIBC_GLIBC)
> + #define OPTION_UCLIBC (linux_libc == LIBC_UCLIBC)
> + #define OPTION_BIONIC (linux_libc == LIBC_BIONIC)
> ++#define OPTION_MUSL   (linux_libc == LIBC_MUSL)
> + #endif
> +
> + #define GNU_USER_TARGET_OS_CPP_BUILTINS()                     \
> +@@ -53,18 +55,21 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
> +    uClibc or Bionic is the default C library and whether
> +    -muclibc or -mglibc or -mbionic has been passed to change the default.  */
> +
> +-#define CHOOSE_DYNAMIC_LINKER1(LIBC1, LIBC2, LIBC3, LD1, LD2, LD3)    \
> +-  "%{" LIBC2 ":" LD2 ";:%{" LIBC3 ":" LD3 ";:" LD1 "}}"
> ++#define CHOOSE_DYNAMIC_LINKER1(LIBC1, LIBC2, LIBC3, LIBC4, LD1, LD2, LD3, LD4)        \
> ++  "%{" LIBC2 ":" LD2 ";:%{" LIBC3 ":" LD3 ";:%{" LIBC4 ":" LD4 ";:" LD1 "}}}"
> +
> + #if DEFAULT_LIBC == LIBC_GLIBC
> +-#define CHOOSE_DYNAMIC_LINKER(G, U, B) \
> +-  CHOOSE_DYNAMIC_LINKER1 ("mglibc", "muclibc", "mbionic", G, U, B)
> ++#define CHOOSE_DYNAMIC_LINKER(G, U, B, M) \
> ++  CHOOSE_DYNAMIC_LINKER1 ("mglibc", "muclibc", "mbionic", "mmusl", G, U, B, M)
> + #elif DEFAULT_LIBC == LIBC_UCLIBC
> +-#define CHOOSE_DYNAMIC_LINKER(G, U, B) \
> +-  CHOOSE_DYNAMIC_LINKER1 ("muclibc", "mglibc", "mbionic", U, G, B)
> ++#define CHOOSE_DYNAMIC_LINKER(G, U, B, M) \
> ++  CHOOSE_DYNAMIC_LINKER1 ("muclibc", "mglibc", "mbionic", "mmusl", U, G, B, M)
> + #elif DEFAULT_LIBC == LIBC_BIONIC
> +-#define CHOOSE_DYNAMIC_LINKER(G, U, B) \
> +-  CHOOSE_DYNAMIC_LINKER1 ("mbionic", "mglibc", "muclibc", B, G, U)
> ++#define CHOOSE_DYNAMIC_LINKER(G, U, B, M) \
> ++  CHOOSE_DYNAMIC_LINKER1 ("mbionic", "mglibc", "muclibc", "mmusl", B, G, U, M)
> ++#elif DEFAULT_LIBC == LIBC_MUSL
> ++#define CHOOSE_DYNAMIC_LINKER(G, U, B, M) \
> ++  CHOOSE_DYNAMIC_LINKER1 ("mmusl", "mglibc", "muclibc", "mbionic", M, G, U, B)
> + #else
> + #error "Unsupported DEFAULT_LIBC"
> + #endif /* DEFAULT_LIBC */
> +@@ -84,16 +89,16 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
> +
> + #define GNU_USER_DYNAMIC_LINKER                                               \
> +   CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKER, UCLIBC_DYNAMIC_LINKER, \
> +-                       BIONIC_DYNAMIC_LINKER)
> ++                       BIONIC_DYNAMIC_LINKER, MUSL_DYNAMIC_LINKER)
> + #define GNU_USER_DYNAMIC_LINKER32                                     \
> +   CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKER32, UCLIBC_DYNAMIC_LINKER32, \
> +-                       BIONIC_DYNAMIC_LINKER32)
> ++                       BIONIC_DYNAMIC_LINKER32, MUSL_DYNAMIC_LINKER32)
> + #define GNU_USER_DYNAMIC_LINKER64                                     \
> +   CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKER64, UCLIBC_DYNAMIC_LINKER64, \
> +-                       BIONIC_DYNAMIC_LINKER64)
> ++                       BIONIC_DYNAMIC_LINKER64, MUSL_DYNAMIC_LINKER64)
> + #define GNU_USER_DYNAMIC_LINKERX32                                    \
> +   CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKERX32, UCLIBC_DYNAMIC_LINKERX32, \
> +-                       BIONIC_DYNAMIC_LINKERX32)
> ++                       BIONIC_DYNAMIC_LINKERX32, MUSL_DYNAMIC_LINKERX32)
> +
> + /* Determine whether the entire c99 runtime
> +    is present in the runtime library.  */
> +diff --git a/gcc/config/linux.opt b/gcc/config/linux.opt
> +index 27991be..24f9f68 100644
> +--- a/gcc/config/linux.opt
> ++++ b/gcc/config/linux.opt
> +@@ -30,3 +30,7 @@ Use GNU C library
> + muclibc
> + Target Report RejectNegative Var(linux_libc,LIBC_UCLIBC) Negative(mbionic)
> + Use uClibc C library
> ++
> ++mmusl
> ++Target Report RejectNegative Var(linux_libc,LIBC_MUSL) Negative(mglibc)
> ++Use musl C library
> +diff --git a/gcc/config/mips/linux.h b/gcc/config/mips/linux.h
> +index 9b4c68d..47994b7 100644
> +--- a/gcc/config/mips/linux.h
> ++++ b/gcc/config/mips/linux.h
> +@@ -18,3 +18,5 @@ along with GCC; see the file COPYING3.  If not see
> + <http://www.gnu.org/licenses/>.  */
> +
> + #define GLIBC_DYNAMIC_LINKER "/lib/ld.so.1"
> ++
> ++#define MUSL_DYNAMIC_LINKER "/lib/ld-musl-mips.so.1"
> +diff --git a/gcc/config/rs6000/linux64.h b/gcc/config/rs6000/linux64.h
> +index 3f28058..35c691b 100644
> +--- a/gcc/config/rs6000/linux64.h
> ++++ b/gcc/config/rs6000/linux64.h
> +@@ -354,17 +354,21 @@ extern int dot_symbols;
> + #define GLIBC_DYNAMIC_LINKER64 "/lib64/ld64.so.1"
> + #define UCLIBC_DYNAMIC_LINKER32 "/lib/ld-uClibc.so.0"
> + #define UCLIBC_DYNAMIC_LINKER64 "/lib/ld64-uClibc.so.0"
> ++#define MUSL_DYNAMIC_LINKER32 "/lib/ld-musl-powerpc.so.1"
> ++#define MUSL_DYNAMIC_LINKER64 "/lib/ld-musl-powerpc64.so.1"
> + #if DEFAULT_LIBC == LIBC_UCLIBC
> +-#define CHOOSE_DYNAMIC_LINKER(G, U) "%{mglibc:" G ";:" U "}"
> ++#define CHOOSE_DYNAMIC_LINKER(G, U, M) "%{mglibc:" G ";:%{mmusl:" M ";:" U "}}"
> + #elif DEFAULT_LIBC == LIBC_GLIBC
> +-#define CHOOSE_DYNAMIC_LINKER(G, U) "%{muclibc:" U ";:" G "}"
> ++#define CHOOSE_DYNAMIC_LINKER(G, U, M) "%{muclibc:" U ";:%{mmusl:" M ";:" G "}}"
> ++#elif DEFAULT_LIBC == LIBC_MUSL
> ++#define CHOOSE_DYNAMIC_LINKER(G, U, M) "%{mglibc:" G ";:%{muclibc:" U ";:" M "}}"
> + #else
> + #error "Unsupported DEFAULT_LIBC"
> + #endif
> + #define GNU_USER_DYNAMIC_LINKER32 \
> +-  CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKER32, UCLIBC_DYNAMIC_LINKER32)
> ++  CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKER32, UCLIBC_DYNAMIC_LINKER32, MUSL_DYNAMIC_LINKER32)
> + #define GNU_USER_DYNAMIC_LINKER64 \
> +-  CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKER64, UCLIBC_DYNAMIC_LINKER64)
> ++  CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKER64, UCLIBC_DYNAMIC_LINKER64, MUSL_DYNAMIC_LINKER64)
> +
> + #undef  DEFAULT_ASM_ENDIAN
> + #if (TARGET_DEFAULT & MASK_LITTLE_ENDIAN)
> +diff --git a/gcc/config/rs6000/secureplt.h b/gcc/config/rs6000/secureplt.h
> +index 39ffb88..5d3817f 100644
> +--- a/gcc/config/rs6000/secureplt.h
> ++++ b/gcc/config/rs6000/secureplt.h
> +@@ -18,3 +18,4 @@ along with GCC; see the file COPYING3.  If not see
> + <http://www.gnu.org/licenses/>.  */
> +
> + #define CC1_SECURE_PLT_DEFAULT_SPEC "-msecure-plt"
> ++#define LINK_SECURE_PLT_DEFAULT_SPEC "--secure-plt"
> +diff --git a/gcc/config/rs6000/sysv4.h b/gcc/config/rs6000/sysv4.h
> +index 0cc8ffb..766d1d9 100644
> +--- a/gcc/config/rs6000/sysv4.h
> ++++ b/gcc/config/rs6000/sysv4.h
> +@@ -550,6 +550,9 @@ ENDIAN_SELECT(" -mbig", " -mlittle", DEFAULT_ASM_ENDIAN)
> + #ifndef CC1_SECURE_PLT_DEFAULT_SPEC
> + #define CC1_SECURE_PLT_DEFAULT_SPEC ""
> + #endif
> ++#ifndef LINK_SECURE_PLT_DEFAULT_SPEC
> ++#define LINK_SECURE_PLT_DEFAULT_SPEC ""
> ++#endif
> +
> + /* Pass -G xxx to the compiler and set correct endian mode.  */
> + #define       CC1_SPEC "%{G*} %(cc1_cpu)" \
> +@@ -566,6 +569,7 @@ ENDIAN_SELECT(" -mbig", " -mlittle", DEFAULT_ASM_ENDIAN)
> + %{msdata: -msdata=default} \
> + %{mno-sdata: -msdata=none} \
> + %{!mbss-plt: %{!msecure-plt: %(cc1_secure_plt_default)}} \
> ++%{!mbss-plt: %{!msecure-plt: %(link_secure_plt_default)}} \
> + %{profile: -p}"
> +
> + /* Default starting address if specified.  */
> +@@ -778,15 +782,18 @@ ENDIAN_SELECT(" -mbig", " -mlittle", DEFAULT_ASM_ENDIAN)
> +
> + #define GLIBC_DYNAMIC_LINKER "/lib/ld.so.1"
> + #define UCLIBC_DYNAMIC_LINKER "/lib/ld-uClibc.so.0"
> ++#define MUSL_DYNAMIC_LINKER "/lib/ld-musl-powerpc.so.1"
> + #if DEFAULT_LIBC == LIBC_UCLIBC
> +-#define CHOOSE_DYNAMIC_LINKER(G, U) "%{mglibc:" G ";:" U "}"
> ++#define CHOOSE_DYNAMIC_LINKER(G, U, M) "%{mglibc:" G ";:%{mmusl:" M ";:" U "}}"
> ++#elif DEFAULT_LIBC == LIBC_MUSL
> ++#define CHOOSE_DYNAMIC_LINKER(G, U, M) "%{mglibc:" G ";:%{muclibc:" U ";:" M "}}"
> + #elif !defined (DEFAULT_LIBC) || DEFAULT_LIBC == LIBC_GLIBC
> +-#define CHOOSE_DYNAMIC_LINKER(G, U) "%{muclibc:" U ";:" G "}"
> ++#define CHOOSE_DYNAMIC_LINKER(G, U, M) "%{muclibc:" U ";:%{mmusl:" M ";:" G "}}"
> + #else
> + #error "Unsupported DEFAULT_LIBC"
> + #endif
> + #define GNU_USER_DYNAMIC_LINKER \
> +-  CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKER, UCLIBC_DYNAMIC_LINKER)
> ++  CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKER, UCLIBC_DYNAMIC_LINKER, MUSL_DYNAMIC_LINKER)
> +
> + #define LINK_OS_LINUX_SPEC "-m elf32ppclinux %{!shared: %{!static: \
> +   %{rdynamic:-export-dynamic} \
> +@@ -912,6 +919,7 @@ ncrtn.o%s"
> +   { "cc1_endian_little",      CC1_ENDIAN_LITTLE_SPEC },               \
> +   { "cc1_endian_default",     CC1_ENDIAN_DEFAULT_SPEC },              \
> +   { "cc1_secure_plt_default", CC1_SECURE_PLT_DEFAULT_SPEC },          \
> ++  { "link_secure_plt_default",        LINK_SECURE_PLT_DEFAULT_SPEC },         \
> +   { "cpp_os_ads",             CPP_OS_ADS_SPEC },                      \
> +   { "cpp_os_yellowknife",     CPP_OS_YELLOWKNIFE_SPEC },              \
> +   { "cpp_os_mvme",            CPP_OS_MVME_SPEC },                     \
> +diff --git a/gcc/ginclude/stddef.h b/gcc/ginclude/stddef.h
> +index b04dd65..9a4d58b 100644
> +--- a/gcc/ginclude/stddef.h
> ++++ b/gcc/ginclude/stddef.h
> +@@ -181,6 +181,7 @@ typedef __PTRDIFF_TYPE__ ptrdiff_t;
> + #ifndef _GCC_SIZE_T
> + #ifndef _SIZET_
> + #ifndef __size_t
> ++#ifndef __DEFINED_size_t /* musl */
> + #define __size_t__    /* BeOS */
> + #define __SIZE_T__    /* Cray Unicos/Mk */
> + #define _SIZE_T
> +@@ -197,6 +198,7 @@ typedef __PTRDIFF_TYPE__ ptrdiff_t;
> + #define ___int_size_t_h
> + #define _GCC_SIZE_T
> + #define _SIZET_
> ++#define __DEFINED_size_t /* musl */
> + #if (defined (__FreeBSD__) && (__FreeBSD__ >= 5)) \
> +   || defined(__FreeBSD_kernel__)
> + /* __size_t is a typedef on FreeBSD 5, must not trash it. */
> +@@ -214,6 +216,7 @@ typedef __SIZE_TYPE__ size_t;
> + typedef long ssize_t;
> + #endif /* __BEOS__ */
> + #endif /* !(defined (__GNUG__) && defined (size_t)) */
> ++#endif /* __DEFINED_size_t */
> + #endif /* __size_t */
> + #endif /* _SIZET_ */
> + #endif /* _GCC_SIZE_T */
> +diff --git a/libgcc/config/rs6000/linux-unwind.h b/libgcc/config/rs6000/linux-unwind.h
> +index c9273c4..6118a95 100644
> +--- a/libgcc/config/rs6000/linux-unwind.h
> ++++ b/libgcc/config/rs6000/linux-unwind.h
> +@@ -258,6 +258,7 @@ ppc_fallback_frame_state (struct _Unwind_Context *context,
> +
> +   return _URC_NO_REASON;
> + }
> ++#endif
> +
> + #define MD_FROB_UPDATE_CONTEXT frob_update_context
> +
> +diff --git a/libgomp/config/posix/time.c b/libgomp/config/posix/time.c
> +index 37898ec..67cf25f 100644
> +--- a/libgomp/config/posix/time.c
> ++++ b/libgomp/config/posix/time.c
> +@@ -28,6 +28,8 @@
> +    The following implementation uses the most simple POSIX routines.
> +    If present, POSIX 4 clocks should be used instead.  */
> +
> ++#define _POSIX_C_SOURCE 199309L /* for clocks */
> ++
> + #include "libgomp.h"
> + #include <unistd.h>
> + #if TIME_WITH_SYS_TIME
> +diff --git a/libitm/config/arm/hwcap.cc b/libitm/config/arm/hwcap.cc
> +index d064917..e5278c9 100644
> +--- a/libitm/config/arm/hwcap.cc
> ++++ b/libitm/config/arm/hwcap.cc
> +@@ -40,7 +40,11 @@ int GTM_hwcap HIDDEN = 0
> +
> + #ifdef __linux__
> + #include <unistd.h>
> ++#ifdef __GLIBC__
> + #include <sys/fcntl.h>
> ++#else
> ++#include <fcntl.h>
> ++#endif
> + #include <elf.h>
> +
> + static void __attribute__((constructor))
> +diff --git a/libitm/config/linux/x86/tls.h b/libitm/config/linux/x86/tls.h
> +index 4e0115f..ba03047 100644
> +--- a/libitm/config/linux/x86/tls.h
> ++++ b/libitm/config/linux/x86/tls.h
> +@@ -25,16 +25,19 @@
> + #ifndef LIBITM_X86_TLS_H
> + #define LIBITM_X86_TLS_H 1
> +
> +-#if defined(__GLIBC_PREREQ) && __GLIBC_PREREQ(2, 10)
> ++#if defined(__GLIBC_PREREQ)
> ++#if __GLIBC_PREREQ(2, 10)
> + /* Use slots in the TCB head rather than __thread lookups.
> +    GLIBC has reserved words 10 through 13 for TM.  */
> + #define HAVE_ARCH_GTM_THREAD 1
> + #define HAVE_ARCH_GTM_THREAD_DISP 1
> + #endif
> ++#endif
> +
> + #include "config/generic/tls.h"
> +
> +-#if defined(__GLIBC_PREREQ) && __GLIBC_PREREQ(2, 10)
> ++#if defined(__GLIBC_PREREQ)
> ++#if __GLIBC_PREREQ(2, 10)
> + namespace GTM HIDDEN {
> +
> + #ifdef __x86_64__
> +@@ -101,5 +104,6 @@ static inline void set_abi_disp(struct abi_dispatch *x)
> +
> + } // namespace GTM
> + #endif /* >= GLIBC 2.10 */
> ++#endif
> +
> + #endif // LIBITM_X86_TLS_H
> +diff --git a/libstdc++-v3/configure.host b/libstdc++-v3/configure.host
> +index 23b3f52..75e9a55 100644
> +--- a/libstdc++-v3/configure.host
> ++++ b/libstdc++-v3/configure.host
> +@@ -264,6 +264,13 @@ case "${host_os}" in
> +     os_include_dir="os/bsd/freebsd"
> +     ;;
> +   gnu* | linux* | kfreebsd*-gnu | knetbsd*-gnu)
> ++    # check for musl by target
> ++    case "${host_os}" in
> ++      *-musl*)
> ++        os_include_dir="os/generic"
> ++        ;;
> ++      *)
> ++
> +     if [ "$uclibc" = "yes" ]; then
> +       os_include_dir="os/uclibc"
> +     elif [ "$bionic" = "yes" ]; then
> +@@ -272,6 +279,9 @@ case "${host_os}" in
> +       os_include_dir="os/gnu-linux"
> +     fi
> +     ;;
> ++
> ++    esac
> ++    ;;
> +   hpux*)
> +     os_include_dir="os/hpux"
> +     ;;
> diff --git a/patches/gcc/4.9.0/020-musl-support.patch b/patches/gcc/4.9.0/020-musl-support.patch
> new file mode 100644
> index 0000000..a93ff73
> --- /dev/null
> +++ b/patches/gcc/4.9.0/020-musl-support.patch
> @@ -0,0 +1,385 @@
> +diff --git a/gcc/config.gcc b/gcc/config.gcc
> +index 3c55c88..e526ef3 100644
> +--- a/gcc/config.gcc
> ++++ b/gcc/config.gcc
> +@@ -594,7 +594,7 @@ case ${target} in
> + esac
> +
> + # Common C libraries.
> +-tm_defines="$tm_defines LIBC_GLIBC=1 LIBC_UCLIBC=2 LIBC_BIONIC=3"
> ++tm_defines="$tm_defines LIBC_GLIBC=1 LIBC_UCLIBC=2 LIBC_BIONIC=3 LIBC_MUSL=4"
> +
> + # 32-bit x86 processors supported by --with-arch=.  Each processor
> + # MUST be separated by exactly one space.
> +@@ -719,6 +719,9 @@ case ${target} in
> +     *-*-*uclibc*)
> +       tm_defines="$tm_defines DEFAULT_LIBC=LIBC_UCLIBC"
> +       ;;
> ++    *-*-*musl*)
> ++      tm_defines="$tm_defines DEFAULT_LIBC=LIBC_MUSL"
> ++      ;;
> +     *)
> +       tm_defines="$tm_defines DEFAULT_LIBC=LIBC_GLIBC"
> +       ;;
> +@@ -2323,6 +2326,10 @@ powerpc*-*-linux*)
> +           powerpc*-*-linux*paired*)
> +               tm_file="${tm_file} rs6000/750cl.h" ;;
> +       esac
> ++        case ${target} in
> ++            *-linux*-musl*)
> ++                enable_secureplt=yes ;;
> ++        esac
> +       if test x${enable_secureplt} = xyes; then
> +               tm_file="rs6000/secureplt.h ${tm_file}"
> +       fi
> +diff --git a/gcc/config/arm/linux-eabi.h b/gcc/config/arm/linux-eabi.h
> +index f1f3448..8c297b9 100644
> +--- a/gcc/config/arm/linux-eabi.h
> ++++ b/gcc/config/arm/linux-eabi.h
> +@@ -77,6 +77,10 @@
> +     %{mfloat-abi=soft*:" GLIBC_DYNAMIC_LINKER_SOFT_FLOAT "} \
> +     %{!mfloat-abi=*:" GLIBC_DYNAMIC_LINKER_DEFAULT "}"
> +
> ++/* musl has no "classic" (i.e. broken) mode */
> ++#undef  MUSL_DYNAMIC_LINKER
> ++#define MUSL_DYNAMIC_LINKER "/lib/ld-musl-arm.so.1"
> ++
> + /* At this point, bpabi.h will have clobbered LINK_SPEC.  We want to
> +    use the GNU/Linux version, not the generic BPABI version.  */
> + #undef  LINK_SPEC
> +diff --git a/gcc/config/i386/linux.h b/gcc/config/i386/linux.h
> +index 1fb1e03..22144f6 100644
> +--- a/gcc/config/i386/linux.h
> ++++ b/gcc/config/i386/linux.h
> +@@ -21,3 +21,4 @@ along with GCC; see the file COPYING3.  If not see
> +
> + #define GNU_USER_LINK_EMULATION "elf_i386"
> + #define GLIBC_DYNAMIC_LINKER "/lib/ld-linux.so.2"
> ++#define MUSL_DYNAMIC_LINKER "/lib/ld-musl-i386.so.1"
> +diff --git a/gcc/config/i386/linux64.h b/gcc/config/i386/linux64.h
> +index a90171e..8d4bf5f 100644
> +--- a/gcc/config/i386/linux64.h
> ++++ b/gcc/config/i386/linux64.h
> +@@ -30,3 +30,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
> + #define GLIBC_DYNAMIC_LINKER32 "/lib/ld-linux.so.2"
> + #define GLIBC_DYNAMIC_LINKER64 "/lib64/ld-linux-x86-64.so.2"
> + #define GLIBC_DYNAMIC_LINKERX32 "/libx32/ld-linux-x32.so.2"
> ++
> ++#define MUSL_DYNAMIC_LINKER32 "/lib/ld-musl-i386.so.1"
> ++#define MUSL_DYNAMIC_LINKER64 "/lib/ld-musl-x86_64.so.1"
> ++#define MUSL_DYNAMIC_LINKERX32 "/lib/ld-musl-x32.so.1"
> +diff --git a/gcc/config/linux.h b/gcc/config/linux.h
> +index d38ef81..1a1a684 100644
> +--- a/gcc/config/linux.h
> ++++ b/gcc/config/linux.h
> +@@ -32,10 +32,12 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
> + #define OPTION_GLIBC  (DEFAULT_LIBC == LIBC_GLIBC)
> + #define OPTION_UCLIBC (DEFAULT_LIBC == LIBC_UCLIBC)
> + #define OPTION_BIONIC (DEFAULT_LIBC == LIBC_BIONIC)
> ++#define OPTION_MUSL   (DEFAULT_LIBC == LIBC_MUSL)
> + #else
> + #define OPTION_GLIBC  (linux_libc == LIBC_GLIBC)
> + #define OPTION_UCLIBC (linux_libc == LIBC_UCLIBC)
> + #define OPTION_BIONIC (linux_libc == LIBC_BIONIC)
> ++#define OPTION_MUSL   (linux_libc == LIBC_MUSL)
> + #endif
> +
> + #define GNU_USER_TARGET_OS_CPP_BUILTINS()                     \
> +@@ -53,18 +55,21 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
> +    uClibc or Bionic is the default C library and whether
> +    -muclibc or -mglibc or -mbionic has been passed to change the default.  */
> +
> +-#define CHOOSE_DYNAMIC_LINKER1(LIBC1, LIBC2, LIBC3, LD1, LD2, LD3)    \
> +-  "%{" LIBC2 ":" LD2 ";:%{" LIBC3 ":" LD3 ";:" LD1 "}}"
> ++#define CHOOSE_DYNAMIC_LINKER1(LIBC1, LIBC2, LIBC3, LIBC4, LD1, LD2, LD3, LD4)        \
> ++  "%{" LIBC2 ":" LD2 ";:%{" LIBC3 ":" LD3 ";:%{" LIBC4 ":" LD4 ";:" LD1 "}}}"
> +
> + #if DEFAULT_LIBC == LIBC_GLIBC
> +-#define CHOOSE_DYNAMIC_LINKER(G, U, B) \
> +-  CHOOSE_DYNAMIC_LINKER1 ("mglibc", "muclibc", "mbionic", G, U, B)
> ++#define CHOOSE_DYNAMIC_LINKER(G, U, B, M) \
> ++  CHOOSE_DYNAMIC_LINKER1 ("mglibc", "muclibc", "mbionic", "mmusl", G, U, B, M)
> + #elif DEFAULT_LIBC == LIBC_UCLIBC
> +-#define CHOOSE_DYNAMIC_LINKER(G, U, B) \
> +-  CHOOSE_DYNAMIC_LINKER1 ("muclibc", "mglibc", "mbionic", U, G, B)
> ++#define CHOOSE_DYNAMIC_LINKER(G, U, B, M) \
> ++  CHOOSE_DYNAMIC_LINKER1 ("muclibc", "mglibc", "mbionic", "mmusl", U, G, B, M)
> + #elif DEFAULT_LIBC == LIBC_BIONIC
> +-#define CHOOSE_DYNAMIC_LINKER(G, U, B) \
> +-  CHOOSE_DYNAMIC_LINKER1 ("mbionic", "mglibc", "muclibc", B, G, U)
> ++#define CHOOSE_DYNAMIC_LINKER(G, U, B, M) \
> ++  CHOOSE_DYNAMIC_LINKER1 ("mbionic", "mglibc", "muclibc", "mmusl", B, G, U, M)
> ++#elif DEFAULT_LIBC == LIBC_MUSL
> ++#define CHOOSE_DYNAMIC_LINKER(G, U, B, M) \
> ++  CHOOSE_DYNAMIC_LINKER1 ("mmusl", "mglibc", "muclibc", "mbionic", M, G, U, B)
> + #else
> + #error "Unsupported DEFAULT_LIBC"
> + #endif /* DEFAULT_LIBC */
> +@@ -84,16 +89,16 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
> +
> + #define GNU_USER_DYNAMIC_LINKER                                               \
> +   CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKER, UCLIBC_DYNAMIC_LINKER, \
> +-                       BIONIC_DYNAMIC_LINKER)
> ++                       BIONIC_DYNAMIC_LINKER, MUSL_DYNAMIC_LINKER)
> + #define GNU_USER_DYNAMIC_LINKER32                                     \
> +   CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKER32, UCLIBC_DYNAMIC_LINKER32, \
> +-                       BIONIC_DYNAMIC_LINKER32)
> ++                       BIONIC_DYNAMIC_LINKER32, MUSL_DYNAMIC_LINKER32)
> + #define GNU_USER_DYNAMIC_LINKER64                                     \
> +   CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKER64, UCLIBC_DYNAMIC_LINKER64, \
> +-                       BIONIC_DYNAMIC_LINKER64)
> ++                       BIONIC_DYNAMIC_LINKER64, MUSL_DYNAMIC_LINKER64)
> + #define GNU_USER_DYNAMIC_LINKERX32                                    \
> +   CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKERX32, UCLIBC_DYNAMIC_LINKERX32, \
> +-                       BIONIC_DYNAMIC_LINKERX32)
> ++                       BIONIC_DYNAMIC_LINKERX32, MUSL_DYNAMIC_LINKERX32)
> +
> + /* Whether we have Bionic libc runtime */
> + #undef TARGET_HAS_BIONIC
> +diff --git a/gcc/config/linux.opt b/gcc/config/linux.opt
> +index 435bd87..0c94f14 100644
> +--- a/gcc/config/linux.opt
> ++++ b/gcc/config/linux.opt
> +@@ -30,3 +30,7 @@ Use GNU C library
> + muclibc
> + Target Report RejectNegative Var(linux_libc,LIBC_UCLIBC) Negative(mbionic)
> + Use uClibc C library
> ++
> ++mmusl
> ++Target Report RejectNegative Var(linux_libc,LIBC_MUSL) Negative(mglibc)
> ++Use musl C library
> +diff --git a/gcc/config/mips/linux.h b/gcc/config/mips/linux.h
> +index e539422..7141ad9 100644
> +--- a/gcc/config/mips/linux.h
> ++++ b/gcc/config/mips/linux.h
> +@@ -20,6 +20,9 @@ along with GCC; see the file COPYING3.  If not see
> + #define GLIBC_DYNAMIC_LINKER \
> +   "%{mnan=2008:/lib/ld-linux-mipsn8.so.1;:/lib/ld.so.1}"
> +
> ++#define MUSL_DYNAMIC_LINKER \
> ++      "/lib/ld-musl-mips.so.1"
> ++
> + #undef UCLIBC_DYNAMIC_LINKER
> + #define UCLIBC_DYNAMIC_LINKER \
> +   "%{mnan=2008:/lib/ld-uClibc-mipsn8.so.0;:/lib/ld-uClibc.so.0}"
> +diff --git a/gcc/config/rs6000/linux64.h b/gcc/config/rs6000/linux64.h
> +index dbc9a52..c66f4d0 100644
> +--- a/gcc/config/rs6000/linux64.h
> ++++ b/gcc/config/rs6000/linux64.h
> +@@ -375,17 +375,21 @@ extern int dot_symbols;
> + #endif
> + #define UCLIBC_DYNAMIC_LINKER32 "/lib/ld-uClibc.so.0"
> + #define UCLIBC_DYNAMIC_LINKER64 "/lib/ld64-uClibc.so.0"
> ++#define MUSL_DYNAMIC_LINKER32 "/lib/ld-musl-powerpc.so.1"
> ++#define MUSL_DYNAMIC_LINKER64 "/lib/ld-musl-powerpc64.so.1"
> + #if DEFAULT_LIBC == LIBC_UCLIBC
> +-#define CHOOSE_DYNAMIC_LINKER(G, U) "%{mglibc:" G ";:" U "}"
> ++#define CHOOSE_DYNAMIC_LINKER(G, U, M) "%{mglibc:" G ";:%{mmusl:" M ";:" U "}}"
> + #elif DEFAULT_LIBC == LIBC_GLIBC
> +-#define CHOOSE_DYNAMIC_LINKER(G, U) "%{muclibc:" U ";:" G "}"
> ++#define CHOOSE_DYNAMIC_LINKER(G, U, M) "%{muclibc:" U ";:%{mmusl:" M ";:" G "}}"
> ++#elif DEFAULT_LIBC == LIBC_MUSL
> ++#define CHOOSE_DYNAMIC_LINKER(G, U, M) "%{mglibc:" G ";:%{muclibc:" U ";:" M "}}"
> + #else
> + #error "Unsupported DEFAULT_LIBC"
> + #endif
> + #define GNU_USER_DYNAMIC_LINKER32 \
> +-  CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKER32, UCLIBC_DYNAMIC_LINKER32)
> ++  CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKER32, UCLIBC_DYNAMIC_LINKER32, MUSL_DYNAMIC_LINKER32)
> + #define GNU_USER_DYNAMIC_LINKER64 \
> +-  CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKER64, UCLIBC_DYNAMIC_LINKER64)
> ++  CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKER64, UCLIBC_DYNAMIC_LINKER64, MUSL_DYNAMIC_LINKER64)
> +
> + #undef  DEFAULT_ASM_ENDIAN
> + #if (TARGET_DEFAULT & MASK_LITTLE_ENDIAN)
> +diff --git a/gcc/config/rs6000/secureplt.h b/gcc/config/rs6000/secureplt.h
> +index 01959e3..ea3f62f 100644
> +--- a/gcc/config/rs6000/secureplt.h
> ++++ b/gcc/config/rs6000/secureplt.h
> +@@ -18,3 +18,4 @@ along with GCC; see the file COPYING3.  If not see
> + <http://www.gnu.org/licenses/>.  */
> +
> + #define CC1_SECURE_PLT_DEFAULT_SPEC "-msecure-plt"
> ++#define LINK_SECURE_PLT_DEFAULT_SPEC "--secure-plt"
> +diff --git a/gcc/config/rs6000/sysv4.h b/gcc/config/rs6000/sysv4.h
> +index d04e6e4..43ced03 100644
> +--- a/gcc/config/rs6000/sysv4.h
> ++++ b/gcc/config/rs6000/sysv4.h
> +@@ -537,6 +537,9 @@ ENDIAN_SELECT(" -mbig", " -mlittle", DEFAULT_ASM_ENDIAN)
> + #ifndef CC1_SECURE_PLT_DEFAULT_SPEC
> + #define CC1_SECURE_PLT_DEFAULT_SPEC ""
> + #endif
> ++#ifndef LINK_SECURE_PLT_DEFAULT_SPEC
> ++#define LINK_SECURE_PLT_DEFAULT_SPEC ""
> ++#endif
> +
> + /* Pass -G xxx to the compiler.  */
> + #define       CC1_SPEC "%{G*} %(cc1_cpu)" \
> +@@ -551,6 +554,7 @@ ENDIAN_SELECT(" -mbig", " -mlittle", DEFAULT_ASM_ENDIAN)
> + %{msdata: -msdata=default} \
> + %{mno-sdata: -msdata=none} \
> + %{!mbss-plt: %{!msecure-plt: %(cc1_secure_plt_default)}} \
> ++%{!mbss-plt: %{!msecure-plt: %(link_secure_plt_default)}} \
> + %{profile: -p}"
> +
> + /* Default starting address if specified.  */
> +@@ -763,15 +767,18 @@ ENDIAN_SELECT(" -mbig", " -mlittle", DEFAULT_ASM_ENDIAN)
> +
> + #define GLIBC_DYNAMIC_LINKER "/lib/ld.so.1"
> + #define UCLIBC_DYNAMIC_LINKER "/lib/ld-uClibc.so.0"
> ++#define MUSL_DYNAMIC_LINKER "/lib/ld-musl-powerpc.so.1"
> + #if DEFAULT_LIBC == LIBC_UCLIBC
> +-#define CHOOSE_DYNAMIC_LINKER(G, U) "%{mglibc:" G ";:" U "}"
> ++#define CHOOSE_DYNAMIC_LINKER(G, U, M) "%{mglibc:" G ";:%{mmusl:" M ";:" U "}}"
> ++#elif DEFAULT_LIBC == LIBC_MUSL
> ++#define CHOOSE_DYNAMIC_LINKER(G, U, M) "%{mglibc:" G ";:%{muclibc:" U ";:" M "}}"
> + #elif !defined (DEFAULT_LIBC) || DEFAULT_LIBC == LIBC_GLIBC
> +-#define CHOOSE_DYNAMIC_LINKER(G, U) "%{muclibc:" U ";:" G "}"
> ++#define CHOOSE_DYNAMIC_LINKER(G, U, M) "%{muclibc:" U ";:%{mmusl:" M ";:" G "}}"
> + #else
> + #error "Unsupported DEFAULT_LIBC"
> + #endif
> + #define GNU_USER_DYNAMIC_LINKER \
> +-  CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKER, UCLIBC_DYNAMIC_LINKER)
> ++  CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKER, UCLIBC_DYNAMIC_LINKER, MUSL_DYNAMIC_LINKER)
> +
> + #define LINK_OS_LINUX_SPEC "-m elf32ppclinux %{!shared: %{!static: \
> +   %{rdynamic:-export-dynamic} \
> +@@ -894,6 +901,7 @@ ncrtn.o%s"
> +   { "link_os_openbsd",                LINK_OS_OPENBSD_SPEC },                 \
> +   { "link_os_default",                LINK_OS_DEFAULT_SPEC },                 \
> +   { "cc1_secure_plt_default", CC1_SECURE_PLT_DEFAULT_SPEC },          \
> ++  { "link_secure_plt_default",        LINK_SECURE_PLT_DEFAULT_SPEC },         \
> +   { "cpp_os_ads",             CPP_OS_ADS_SPEC },                      \
> +   { "cpp_os_yellowknife",     CPP_OS_YELLOWKNIFE_SPEC },              \
> +   { "cpp_os_mvme",            CPP_OS_MVME_SPEC },                     \
> +diff --git a/gcc/ginclude/stddef.h b/gcc/ginclude/stddef.h
> +index cfa8df3..5212a27 100644
> +--- a/gcc/ginclude/stddef.h
> ++++ b/gcc/ginclude/stddef.h
> +@@ -181,6 +181,7 @@ typedef __PTRDIFF_TYPE__ ptrdiff_t;
> + #ifndef _GCC_SIZE_T
> + #ifndef _SIZET_
> + #ifndef __size_t
> ++#ifndef __DEFINED_size_t /* musl */
> + #define __size_t__    /* BeOS */
> + #define __SIZE_T__    /* Cray Unicos/Mk */
> + #define _SIZE_T
> +@@ -197,6 +198,7 @@ typedef __PTRDIFF_TYPE__ ptrdiff_t;
> + #define ___int_size_t_h
> + #define _GCC_SIZE_T
> + #define _SIZET_
> ++#define __DEFINED_size_t /* musl */
> + #if (defined (__FreeBSD__) && (__FreeBSD__ >= 5)) \
> +   || defined(__FreeBSD_kernel__)
> + /* __size_t is a typedef on FreeBSD 5, must not trash it. */
> +@@ -214,6 +216,7 @@ typedef __SIZE_TYPE__ size_t;
> + typedef long ssize_t;
> + #endif /* __BEOS__ */
> + #endif /* !(defined (__GNUG__) && defined (size_t)) */
> ++#endif /* __DEFINED_size_t */
> + #endif /* __size_t */
> + #endif /* _SIZET_ */
> + #endif /* _GCC_SIZE_T */
> +diff --git a/libgcc/config/rs6000/linux-unwind.h b/libgcc/config/rs6000/linux-unwind.h
> +index c5b006e..0eadc7a 100644
> +--- a/libgcc/config/rs6000/linux-unwind.h
> ++++ b/libgcc/config/rs6000/linux-unwind.h
> +@@ -282,6 +282,7 @@ ppc_fallback_frame_state (struct _Unwind_Context *context,
> +
> +   return _URC_NO_REASON;
> + }
> ++#endif
> +
> + #define MD_FROB_UPDATE_CONTEXT frob_update_context
> +
> +diff --git a/libgomp/config/posix/time.c b/libgomp/config/posix/time.c
> +index 6000aa3..be926df 100644
> +--- a/libgomp/config/posix/time.c
> ++++ b/libgomp/config/posix/time.c
> +@@ -28,6 +28,8 @@
> +    The following implementation uses the most simple POSIX routines.
> +    If present, POSIX 4 clocks should be used instead.  */
> +
> ++#define _POSIX_C_SOURCE 199309L /* for clocks */
> ++
> + #include "libgomp.h"
> + #include <unistd.h>
> + #if TIME_WITH_SYS_TIME
> +diff --git a/libitm/config/arm/hwcap.cc b/libitm/config/arm/hwcap.cc
> +index 11ef0f6..07a9e41 100644
> +--- a/libitm/config/arm/hwcap.cc
> ++++ b/libitm/config/arm/hwcap.cc
> +@@ -40,7 +40,11 @@ int GTM_hwcap HIDDEN = 0
> +
> + #ifdef __linux__
> + #include <unistd.h>
> ++#ifdef __GLIBC__
> + #include <sys/fcntl.h>
> ++#else
> ++#include <fcntl.h>
> ++#endif
> + #include <elf.h>
> +
> + static void __attribute__((constructor))
> +diff --git a/libitm/config/linux/x86/tls.h b/libitm/config/linux/x86/tls.h
> +index 760e6e9..0407883 100644
> +--- a/libitm/config/linux/x86/tls.h
> ++++ b/libitm/config/linux/x86/tls.h
> +@@ -25,16 +25,19 @@
> + #ifndef LIBITM_X86_TLS_H
> + #define LIBITM_X86_TLS_H 1
> +
> +-#if defined(__GLIBC_PREREQ) && __GLIBC_PREREQ(2, 10)
> ++#if defined(__GLIBC_PREREQ)
> ++#if __GLIBC_PREREQ(2, 10)
> + /* Use slots in the TCB head rather than __thread lookups.
> +    GLIBC has reserved words 10 through 13 for TM.  */
> + #define HAVE_ARCH_GTM_THREAD 1
> + #define HAVE_ARCH_GTM_THREAD_DISP 1
> + #endif
> ++#endif
> +
> + #include "config/generic/tls.h"
> +
> +-#if defined(__GLIBC_PREREQ) && __GLIBC_PREREQ(2, 10)
> ++#if defined(__GLIBC_PREREQ)
> ++#if __GLIBC_PREREQ(2, 10)
> + namespace GTM HIDDEN {
> +
> + #ifdef __x86_64__
> +@@ -101,5 +104,6 @@ static inline void set_abi_disp(struct abi_dispatch *x)
> +
> + } // namespace GTM
> + #endif /* >= GLIBC 2.10 */
> ++#endif
> +
> + #endif // LIBITM_X86_TLS_H
> +diff --git a/libstdc++-v3/configure.host b/libstdc++-v3/configure.host
> +index c168454..0e6aee5 100644
> +--- a/libstdc++-v3/configure.host
> ++++ b/libstdc++-v3/configure.host
> +@@ -264,6 +264,13 @@ case "${host_os}" in
> +     os_include_dir="os/bsd/freebsd"
> +     ;;
> +   gnu* | linux* | kfreebsd*-gnu | knetbsd*-gnu)
> ++    # check for musl by target
> ++    case "${host_os}" in
> ++      *-musl*)
> ++        os_include_dir="os/generic"
> ++        ;;
> ++      *)
> ++
> +     if [ "$uclibc" = "yes" ]; then
> +       os_include_dir="os/uclibc"
> +     elif [ "$bionic" = "yes" ]; then
> +@@ -272,6 +279,9 @@ case "${host_os}" in
> +       os_include_dir="os/gnu-linux"
> +     fi
> +     ;;
> ++
> ++    esac
> ++    ;;
> +   hpux*)
> +     os_include_dir="os/hpux"
> +     ;;
> diff --git a/patches/musl/1.0.3/001-fix_linker_regression.patch b/patches/musl/1.0.3/001-fix_linker_regression.patch
> new file mode 100644
> index 0000000..801cb00
> --- /dev/null
> +++ b/patches/musl/1.0.3/001-fix_linker_regression.patch
> @@ -0,0 +1,64 @@
> +From 9a4ad02214a859e93d2c980e4535378a6a74e3a6 Mon Sep 17 00:00:00 2001
> +From: Rich Felker <dalias@aerifal.cx>
> +Date: Mon, 30 Jun 2014 01:52:54 +0000
> +Subject: fix regression in dynamic linker error reporting
> +
> +due to a mistake when refactoring the error printing for the dynamic
> +linker (commit 7c73cacd09a51a87484db5689864743e4984a84d), all messages
> +were suppressed and replaced by blank lines.
> +---
> +diff --git a/src/ldso/dynlink.c b/src/ldso/dynlink.c
> +index bc4f2f6..a08300d 100644
> +--- a/src/ldso/dynlink.c
> ++++ b/src/ldso/dynlink.c
> +@@ -290,8 +290,7 @@ static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stri
> +               if (!astype) continue;
> +               type = remap_rel(astype);
> +               if (!type) {
> +-                      error(errbuf, sizeof errbuf,
> +-                              "Error relocating %s: unsupported relocation type %d",
> ++                      error("Error relocating %s: unsupported relocation type %d",
> +                               dso->name, astype);
> +                       continue;
> +               }
> +@@ -304,8 +303,7 @@ static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stri
> +                       def = find_sym(ctx, name, type==REL_PLT);
> +                       if (!def.sym && (sym->st_shndx != SHN_UNDEF
> +                           || sym->st_info>>4 != STB_WEAK)) {
> +-                              error(errbuf, sizeof errbuf,
> +-                                      "Error relocating %s: %s: symbol not found",
> ++                              error("Error relocating %s: %s: symbol not found",
> +                                       dso->name, name);
> +                               continue;
> +                       }
> +@@ -366,7 +364,7 @@ static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stri
> +                       if (stride<3) addend = reloc_addr[1];
> +                       if (runtime && def.dso->tls_id >= static_tls_cnt) {
> +                               struct td_index *new = malloc(sizeof *new);
> +-                              if (!new) error(errbuf, sizeof errbuf,
> ++                              if (!new) error(
> +                                       "Error relocating %s: cannot allocate TLSDESC for %s",
> +                                       dso->name, sym ? name : "(local)" );
> +                               new->next = dso->td_index;
> +@@ -839,8 +837,7 @@ static void load_deps(struct dso *p)
> +                       if (p->dynv[i] != DT_NEEDED) continue;
> +                       dep = load_library(p->strings + p->dynv[i+1], p);
> +                       if (!dep) {
> +-                              error(errbuf, sizeof errbuf,
> +-                                      "Error loading shared library %s: %m (needed by %s)",
> ++                              error("Error loading shared library %s: %m (needed by %s)",
> +                                       p->strings + p->dynv[i+1], p->name);
> +                               continue;
> +                       }
> +@@ -890,8 +887,7 @@ static void reloc_all(struct dso *p)
> +
> +               if (p->relro_start != p->relro_end &&
> +                   mprotect(p->base+p->relro_start, p->relro_end-p->relro_start, PROT_READ) < 0) {
> +-                      error(errbuf, sizeof errbuf,
> +-                              "Error relocating %s: RELRO protection failed: %m",
> ++                      error("Error relocating %s: RELRO protection failed: %m",
> +                               p->name);
> +               }
> +
> +--
> +cgit v0.9.0.3-65-g4555
> diff --git a/patches/musl/1.0.3/002-fix_mips_linker_regression.patch b/patches/musl/1.0.3/002-fix_mips_linker_regression.patch
> new file mode 100644
> index 0000000..4891b4f
> --- /dev/null
> +++ b/patches/musl/1.0.3/002-fix_mips_linker_regression.patch
> @@ -0,0 +1,88 @@
> +From 2d8cc92a7cb4a3256ed07d86843388ffd8a882b1 Mon Sep 17 00:00:00 2001
> +From: Rich Felker <dalias@aerifal.cx>
> +Date: Mon, 30 Jun 2014 05:18:14 +0000
> +Subject: fix regression in mips dynamic linker
> +
> +this issue caused the address of functions in shared libraries to
> +resolve to their PLT thunks in the main program rather than their
> +correct addresses. it was observed causing crashes, though the
> +mechanism of the crash was not thoroughly investigated. since the
> +issue is very subtle, it calls for some explanation:
> +
> +on all well-behaved archs, GOT entries that belong to the PLT use a
> +special relocation type, typically called JMP_SLOT, so that the
> +dynamic linker can avoid having the jump destinations for the PLT
> +resolve to PLT thunks themselves (they also provide a definition for
> +the symbol, which must be used whenever the address of the function is
> +taken so that all DSOs see the same address).
> +
> +however, the traditional mips PIC ABI lacked such a JMP_SLOT
> +relocation type, presumably because, due to the way PIC works, the
> +address of the PLT thunk was never needed and could always be ignored.
> +
> +prior to commit adf94c19666e687a728bbf398f9a88ea4ea19996, the mips
> +version of reloc.h contained a hack that caused all symbol lookups to
> +be treated like JMP_SLOT, inhibiting undefined symbols from ever being
> +used to resolve symbolic relocations. this hack goes all the way back
> +to commit babf820180368f00742ec65b2050a82380d7c542, when the mips
> +dynamic linker was first made usable.
> +
> +during the recent refactoring to eliminate arch-specific relocation
> +processing (commit adf94c19666e687a728bbf398f9a88ea4ea19996), this
> +hack was overlooked and no equivalent functionality was provided in
> +the new code.
> +
> +fixing the problem is not as simple as adding back an equivalent hack,
> +since there is now also a "non-PIC ABI" that can be used for the main
> +executable, which actually does use a PLT. the closest thing to
> +official documentation I could find for this ABI is nonpic.txt,
> +attached to Message-ID: 20080701202236.GA1534@caradoc.them.org, which
> +can be found in the gcc mailing list archives and elsewhere. per this
> +document, undefined symbols corresponding to PLT thunks have the
> +STO_MIPS_PLT bit set in the symbol's st_other field. thus, I have
> +added an arch-specific rule for mips, applied at the find_sym level
> +rather than the relocation level, to reject undefined symbols with the
> +STO_MIPS_PLT bit clear.
> +
> +the previous hack of treating all mips relocations as JMP_SLOT-like,
> +rather than rejecting the unwanted symbols in find_sym, probably also
> +caused dlsym to wrongly return PLT thunks in place of the correct
> +address of a function under at least some conditions. this should now
> +be fixed, at least for global-scope symbol lookups.
> +---
> +diff --git a/arch/mips/reloc.h b/arch/mips/reloc.h
> +index 91fa097..4b81d32 100644
> +--- a/arch/mips/reloc.h
> ++++ b/arch/mips/reloc.h
> +@@ -86,3 +86,4 @@ static void do_arch_relocs(struct dso *this, struct dso *head)
> +
> + #define NEED_ARCH_RELOCS 1
> + #define DYNAMIC_IS_RO 1
> ++#define ARCH_SYM_REJECT_UND(s) (!((s)->st_other & STO_MIPS_PLT))
> +diff --git a/src/ldso/dynlink.c b/src/ldso/dynlink.c
> +index a08300d..55124ff 100644
> +--- a/src/ldso/dynlink.c
> ++++ b/src/ldso/dynlink.c
> +@@ -233,6 +233,10 @@ static Sym *gnu_lookup(const char *s, uint32_t h1, struct dso *dso)
> + #define OK_TYPES (1<<STT_NOTYPE | 1<<STT_OBJECT | 1<<STT_FUNC | 1<<STT_COMMON | 1<<STT_TLS)
> + #define OK_BINDS (1<<STB_GLOBAL | 1<<STB_WEAK | 1<<STB_GNU_UNIQUE)
> +
> ++#ifndef ARCH_SYM_REJECT_UND
> ++#define ARCH_SYM_REJECT_UND(s) 0
> ++#endif
> ++
> + static struct symdef find_sym(struct dso *dso, const char *s, int need_def)
> + {
> +       uint32_t h = 0, gh = 0;
> +@@ -249,7 +253,8 @@ static struct symdef find_sym(struct dso *dso, const char *s, int need_def)
> +               }
> +               if (!sym) continue;
> +               if (!sym->st_shndx)
> +-                      if (need_def || (sym->st_info&0xf) == STT_TLS)
> ++                      if (need_def || (sym->st_info&0xf) == STT_TLS
> ++                          || ARCH_SYM_REJECT_UND(sym))
> +                               continue;
> +               if (!sym->st_value)
> +                       if ((sym->st_info&0xf) != STT_TLS)
> +--
> +cgit v0.9.0.3-65-g4555
> diff --git a/patches/musl/1.1.3/001-fix_linker_regression.patch b/patches/musl/1.1.3/001-fix_linker_regression.patch
> new file mode 100644
> index 0000000..801cb00
> --- /dev/null
> +++ b/patches/musl/1.1.3/001-fix_linker_regression.patch
> @@ -0,0 +1,64 @@
> +From 9a4ad02214a859e93d2c980e4535378a6a74e3a6 Mon Sep 17 00:00:00 2001
> +From: Rich Felker <dalias@aerifal.cx>
> +Date: Mon, 30 Jun 2014 01:52:54 +0000
> +Subject: fix regression in dynamic linker error reporting
> +
> +due to a mistake when refactoring the error printing for the dynamic
> +linker (commit 7c73cacd09a51a87484db5689864743e4984a84d), all messages
> +were suppressed and replaced by blank lines.
> +---
> +diff --git a/src/ldso/dynlink.c b/src/ldso/dynlink.c
> +index bc4f2f6..a08300d 100644
> +--- a/src/ldso/dynlink.c
> ++++ b/src/ldso/dynlink.c
> +@@ -290,8 +290,7 @@ static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stri
> +               if (!astype) continue;
> +               type = remap_rel(astype);
> +               if (!type) {
> +-                      error(errbuf, sizeof errbuf,
> +-                              "Error relocating %s: unsupported relocation type %d",
> ++                      error("Error relocating %s: unsupported relocation type %d",
> +                               dso->name, astype);
> +                       continue;
> +               }
> +@@ -304,8 +303,7 @@ static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stri
> +                       def = find_sym(ctx, name, type==REL_PLT);
> +                       if (!def.sym && (sym->st_shndx != SHN_UNDEF
> +                           || sym->st_info>>4 != STB_WEAK)) {
> +-                              error(errbuf, sizeof errbuf,
> +-                                      "Error relocating %s: %s: symbol not found",
> ++                              error("Error relocating %s: %s: symbol not found",
> +                                       dso->name, name);
> +                               continue;
> +                       }
> +@@ -366,7 +364,7 @@ static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stri
> +                       if (stride<3) addend = reloc_addr[1];
> +                       if (runtime && def.dso->tls_id >= static_tls_cnt) {
> +                               struct td_index *new = malloc(sizeof *new);
> +-                              if (!new) error(errbuf, sizeof errbuf,
> ++                              if (!new) error(
> +                                       "Error relocating %s: cannot allocate TLSDESC for %s",
> +                                       dso->name, sym ? name : "(local)" );
> +                               new->next = dso->td_index;
> +@@ -839,8 +837,7 @@ static void load_deps(struct dso *p)
> +                       if (p->dynv[i] != DT_NEEDED) continue;
> +                       dep = load_library(p->strings + p->dynv[i+1], p);
> +                       if (!dep) {
> +-                              error(errbuf, sizeof errbuf,
> +-                                      "Error loading shared library %s: %m (needed by %s)",
> ++                              error("Error loading shared library %s: %m (needed by %s)",
> +                                       p->strings + p->dynv[i+1], p->name);
> +                               continue;
> +                       }
> +@@ -890,8 +887,7 @@ static void reloc_all(struct dso *p)
> +
> +               if (p->relro_start != p->relro_end &&
> +                   mprotect(p->base+p->relro_start, p->relro_end-p->relro_start, PROT_READ) < 0) {
> +-                      error(errbuf, sizeof errbuf,
> +-                              "Error relocating %s: RELRO protection failed: %m",
> ++                      error("Error relocating %s: RELRO protection failed: %m",
> +                               p->name);
> +               }
> +
> +--
> +cgit v0.9.0.3-65-g4555
> diff --git a/patches/musl/1.1.3/002-fix_mips_linker_regression.patch b/patches/musl/1.1.3/002-fix_mips_linker_regression.patch
> new file mode 100644
> index 0000000..4891b4f
> --- /dev/null
> +++ b/patches/musl/1.1.3/002-fix_mips_linker_regression.patch
> @@ -0,0 +1,88 @@
> +From 2d8cc92a7cb4a3256ed07d86843388ffd8a882b1 Mon Sep 17 00:00:00 2001
> +From: Rich Felker <dalias@aerifal.cx>
> +Date: Mon, 30 Jun 2014 05:18:14 +0000
> +Subject: fix regression in mips dynamic linker
> +
> +this issue caused the address of functions in shared libraries to
> +resolve to their PLT thunks in the main program rather than their
> +correct addresses. it was observed causing crashes, though the
> +mechanism of the crash was not thoroughly investigated. since the
> +issue is very subtle, it calls for some explanation:
> +
> +on all well-behaved archs, GOT entries that belong to the PLT use a
> +special relocation type, typically called JMP_SLOT, so that the
> +dynamic linker can avoid having the jump destinations for the PLT
> +resolve to PLT thunks themselves (they also provide a definition for
> +the symbol, which must be used whenever the address of the function is
> +taken so that all DSOs see the same address).
> +
> +however, the traditional mips PIC ABI lacked such a JMP_SLOT
> +relocation type, presumably because, due to the way PIC works, the
> +address of the PLT thunk was never needed and could always be ignored.
> +
> +prior to commit adf94c19666e687a728bbf398f9a88ea4ea19996, the mips
> +version of reloc.h contained a hack that caused all symbol lookups to
> +be treated like JMP_SLOT, inhibiting undefined symbols from ever being
> +used to resolve symbolic relocations. this hack goes all the way back
> +to commit babf820180368f00742ec65b2050a82380d7c542, when the mips
> +dynamic linker was first made usable.
> +
> +during the recent refactoring to eliminate arch-specific relocation
> +processing (commit adf94c19666e687a728bbf398f9a88ea4ea19996), this
> +hack was overlooked and no equivalent functionality was provided in
> +the new code.
> +
> +fixing the problem is not as simple as adding back an equivalent hack,
> +since there is now also a "non-PIC ABI" that can be used for the main
> +executable, which actually does use a PLT. the closest thing to
> +official documentation I could find for this ABI is nonpic.txt,
> +attached to Message-ID: 20080701202236.GA1534@caradoc.them.org, which
> +can be found in the gcc mailing list archives and elsewhere. per this
> +document, undefined symbols corresponding to PLT thunks have the
> +STO_MIPS_PLT bit set in the symbol's st_other field. thus, I have
> +added an arch-specific rule for mips, applied at the find_sym level
> +rather than the relocation level, to reject undefined symbols with the
> +STO_MIPS_PLT bit clear.
> +
> +the previous hack of treating all mips relocations as JMP_SLOT-like,
> +rather than rejecting the unwanted symbols in find_sym, probably also
> +caused dlsym to wrongly return PLT thunks in place of the correct
> +address of a function under at least some conditions. this should now
> +be fixed, at least for global-scope symbol lookups.
> +---
> +diff --git a/arch/mips/reloc.h b/arch/mips/reloc.h
> +index 91fa097..4b81d32 100644
> +--- a/arch/mips/reloc.h
> ++++ b/arch/mips/reloc.h
> +@@ -86,3 +86,4 @@ static void do_arch_relocs(struct dso *this, struct dso *head)
> +
> + #define NEED_ARCH_RELOCS 1
> + #define DYNAMIC_IS_RO 1
> ++#define ARCH_SYM_REJECT_UND(s) (!((s)->st_other & STO_MIPS_PLT))
> +diff --git a/src/ldso/dynlink.c b/src/ldso/dynlink.c
> +index a08300d..55124ff 100644
> +--- a/src/ldso/dynlink.c
> ++++ b/src/ldso/dynlink.c
> +@@ -233,6 +233,10 @@ static Sym *gnu_lookup(const char *s, uint32_t h1, struct dso *dso)
> + #define OK_TYPES (1<<STT_NOTYPE | 1<<STT_OBJECT | 1<<STT_FUNC | 1<<STT_COMMON | 1<<STT_TLS)
> + #define OK_BINDS (1<<STB_GLOBAL | 1<<STB_WEAK | 1<<STB_GNU_UNIQUE)
> +
> ++#ifndef ARCH_SYM_REJECT_UND
> ++#define ARCH_SYM_REJECT_UND(s) 0
> ++#endif
> ++
> + static struct symdef find_sym(struct dso *dso, const char *s, int need_def)
> + {
> +       uint32_t h = 0, gh = 0;
> +@@ -249,7 +253,8 @@ static struct symdef find_sym(struct dso *dso, const char *s, int need_def)
> +               }
> +               if (!sym) continue;
> +               if (!sym->st_shndx)
> +-                      if (need_def || (sym->st_info&0xf) == STT_TLS)
> ++                      if (need_def || (sym->st_info&0xf) == STT_TLS
> ++                          || ARCH_SYM_REJECT_UND(sym))
> +                               continue;
> +               if (!sym->st_value)
> +                       if ((sym->st_info&0xf) != STT_TLS)
> +--
> +cgit v0.9.0.3-65-g4555
> diff --git a/samples/arm-unknown-linux-muslgnueabi/crosstool.config b/samples/arm-unknown-linux-muslgnueabi/crosstool.config
> new file mode 100644
> index 0000000..8b96eb1
> --- /dev/null
> +++ b/samples/arm-unknown-linux-muslgnueabi/crosstool.config
> @@ -0,0 +1,10 @@
> +CT_EXPERIMENTAL=y
> +CT_ARCH_ARCH="armv5te"
> +CT_ARCH_FLOAT_SW=y
> +CT_ARCH_arm=y
> +CT_KERNEL_linux=y
> +CT_BINUTILS_FOR_TARGET=y
> +CT_LIBC_musl=y
> +CT_CC_V_4_9_0=y
> +CT_CC_LANG_CXX=y
> +# CT_CC_GCC_SJLJ_EXCEPTIONS is not set
> diff --git a/samples/arm-unknown-linux-muslgnueabi/reported.by b/samples/arm-unknown-linux-muslgnueabi/reported.by
> new file mode 100644
> index 0000000..7ba54a4
> --- /dev/null
> +++ b/samples/arm-unknown-linux-muslgnueabi/reported.by
> @@ -0,0 +1,3 @@
> +reporter_name="Bryan Hundven"
> +reporter_url="http://bhundven.github.io"
> +reporter_comment=""
> diff --git a/scripts/build/arch/arm.sh b/scripts/build/arch/arm.sh
> index 430bdde..ba87e0c 100644
> --- a/scripts/build/arch/arm.sh
> +++ b/scripts/build/arch/arm.sh
> @@ -17,6 +17,7 @@ CT_DoArchTupleValues() {
>      case "${CT_LIBC},${CT_ARCH_ARM_EABI}" in
>          *glibc,y)   CT_TARGET_SYS=gnueabi;;
>          uClibc,y)   CT_TARGET_SYS=uclibcgnueabi;;
> +        musl,y)     CT_TARGET_SYS=muslgnueabi;;
>          *,y)        CT_TARGET_SYS=eabi;;
>      esac
>
> diff --git a/scripts/build/libc/musl.sh b/scripts/build/libc/musl.sh
> new file mode 100644
> index 0000000..af2dba7
> --- /dev/null
> +++ b/scripts/build/libc/musl.sh
> @@ -0,0 +1,111 @@
> +# This file adds functions to build the musl C library
> +# Copyright 2013 Timo Teräs
> +# Licensed under the GPL v2. See COPYING in the root of this package
> +
> +do_libc_get() {
> +    local libc_src
> +
> +    libc_src="http://www.musl-libc.org/releases"
> +
> +    if [ "${CT_LIBC_MUSL_CUSTOM}" = "y" ]; then
> +        CT_GetCustom "musl" "${CT_LIBC_VERSION}"      \
> +                     "${CT_LIBC_MUSL_CUSTOM_LOCATION}"
> +    else # ! custom location
> +        CT_GetFile "musl-${CT_LIBC_VERSION}" "${libc_src}"
> +    fi # ! custom location
> +}
> +
> +do_libc_extract() {
> +    # If using custom directory location, nothing to do.
> +    if [ "${CT_LIBC_MUSL_CUSTOM}" = "y" ]; then
> +        # Abort if the custom directory is not found.
> +        if ! [ -d "${CT_SRC_DIR}/musl-${CT_LIBC_VERSION}" ]; then
> +            CT_Abort "Directory not found: ${CT_SRC_DIR}/musl-${CT_LIBC_VERSION}"
> +        fi
> +
> +        return 0
> +    fi
> +
> +    CT_Extract "musl-${CT_LIBC_VERSION}"
> +    CT_Patch "musl" "${CT_LIBC_VERSION}"
> +}
> +
> +do_libc_check_config() {
> +    :
> +}
> +
> +do_libc_configure() {
> +    CT_DoLog EXTRA "Configuring C library"
> +    local -a extra_cflags
> +
> +    # From buildroot:
> +    # gcc constant folding bug with weak aliases workaround
> +    # See http://www.openwall.com/lists/musl/2014/05/15/1
> +    if [ "${CT_CC_GCC_4_9_or_later}" = "y" ]; then
> +        extra_cflags+=("-fno-toplevel-reorder")
> +    fi
> +
> +    # NOTE: musl handles the build/host/target a little bit differently
> +    # then one would expect:
> +    #   build   : not used
> +    #   host    : the machine building musl
> +    #   target  : the machine musl runs on
> +    CT_DoExecLog CFG                \
> +    CFLAGS="${extra_cflags[@]}"     \
> +    CROSS_COMPILE="${CT_TARGET}-"   \
> +    ./configure                     \
> +        --host="${CT_BUILD}"        \
> +        --target="${CT_TARGET}"     \
> +        --prefix="/usr"             \
> +        --disable-gcc-wrapper
> +}
> +
> +do_libc_start_files() {
> +    local ARCH
> +
> +    CT_DoStep INFO "Installing C library headers"
> +
> +    # Simply copy files until musl has the ability to build out-of-tree
> +    CT_DoLog EXTRA "Copying sources to build directory"
> +    CT_DoExecLog ALL cp -av "${CT_SRC_DIR}/musl-${CT_LIBC_VERSION}" \
> +                            "${CT_BUILD_DIR}/build-libc-headers"
> +    cd "${CT_BUILD_DIR}/build-libc-headers"
> +
> +    # musl can be installed without gcc if arch is known
> +    case "${CT_TARGET}" in
> +        arm*) ARCH=arm ;;
> +        i?86*) ARCH=i386 ;;
> +        x86_64*) ARCH=x86_64 ;;
> +        mips-*|mipsel-*) ARCH=mips ;;
> +        microblaze-*) ARCH=microblaze ;;
> +        powerpc-*) ARCH=powerpc ;;
> +        sh-*|sh[34]-*) ARCH=sh ;;
> +        x32-*) ARCH=x32 ;;
> +        *) return 1 ;;
> +    esac
> +
> +    CT_DoLog EXTRA "Installing headers"
> +    CT_DoExecLog ALL make ARCH="${ARCH}" install-headers DESTDIR="${CT_SYSROOT_DIR}/"
> +
> +    CT_EndStep
> +}
> +
> +do_libc() {
> +    CT_DoStep INFO "Installing C library"
> +
> +    # Simply copy files until musl has the ability to build out-of-tree
> +    CT_DoLog EXTRA "Copying sources to build directory"
> +    CT_DoExecLog ALL cp -av "${CT_SRC_DIR}/musl-${CT_LIBC_VERSION}" \
> +                            "${CT_BUILD_DIR}/build-libc"
> +    cd "${CT_BUILD_DIR}/build-libc"
> +
> +    do_libc_configure
> +
> +    CT_DoLog EXTRA "Building C library"
> +    CT_DoExecLog ALL make ${JOBSFLAGS}
> +
> +    CT_DoLog EXTRA "Installing C library"
> +    CT_DoExecLog ALL make install DESTDIR="${CT_SYSROOT_DIR}/"
> +
> +    CT_EndStep
> +}
> diff --git a/scripts/functions b/scripts/functions
> index b15601a..2cad8f1 100644
> --- a/scripts/functions
> +++ b/scripts/functions
> @@ -1174,6 +1174,7 @@ CT_DoBuildTargetTuple() {
>      case "${CT_LIBC}" in
>          *glibc) CT_TARGET_SYS=gnu;;
>          uClibc) CT_TARGET_SYS=uclibc;;
> +        musl)   CT_TARGET_SYS=musl;;
>          *)      CT_TARGET_SYS=elf;;
>      esac
>
> --
> 2.0.1
>

This patch has been declined, as Yann does not want to add an
out-of-tree gcc feature to support musl. When musl is supported
upstream in gcc, we can continue this work.

For now the branch is located here:

https://bitbucket.org/bhundven/crosstool-ng/branch/musl

-Bryan

--
For unsubscribe information see http://sourceware.org/lists.html#faq
Yann E. MORIN July 26, 2014, 11:12 p.m. UTC | #2
Bryan, All,

On 2014-07-18 14:17 -0700, Bryan Hundven spake thusly:
> This change is based on a patch by Timo Teräs:
>     http://patchwork.ozlabs.org/patch/257187/
> 
> This patch, as the original, is an RFC. Currently a minimal armel- is
> the only target tested. sh[34][a]- support is in crosstool-ng, but not
> in the 020-musl-support.patch.
> 
> Please let me know if you have any comments, feedback, and/or
> suggestions.

So, this patch has stirred a bit of discussions on IRC.

My position is to not have feature-patches against the components,
especially if they have not been blessed by the corresponding upstream.

Having feature-patches to components is globally a problem, because they
might have unexpected and hard-to-find impacts on the compoent. For
example, we have such a situation with (another) musl patch in
Buildroot, that breaks C++ applications that throw exceptions.

I do not want such issues to pop up in crosstool-NG.


However, we've had a very constructive discussion with Bryan on IRC,
about adding musl to crosstool-NG. Here is the plan:

1- add a new config knob that enables using experimental patches. Such
   patches are not located in the same area as other patches, so do not
   get applied by default, unless that new config knob is enabled.

2- for each experimental patch added, a corresponding config knob is
   automatically generated, so the user can seelct whatever experimental
   patches he wishes to.

3- add musl as a new C library, but without the biggish gcc patch

4- add the musl patches as experimental patches, with a big README
   stating the experimental status


Note that the experimental patches will be a severly restricted feature.
We'll only add select patches. For now, only the musl patch is
identified as going in. Later, we might add a few others, especially for
llvm. But the list will *not* grow out of proportions.


Thanks for watching the show. You can now resume your normal activities.
;-)

Regards,
Yann E. MORIN.
diff mbox

Patch

diff --git a/config/libc.in b/config/libc.in
index 03f5db2..ff9ce9e 100644
--- a/config/libc.in
+++ b/config/libc.in
@@ -28,6 +28,10 @@  config LIBC_SUPPORT_NPTL
     bool
     select LIBC_SUPPORT_THREADS_ANY
 
+config LIBC_SUPPORT_MUSL
+    bool
+    select LIBC_SUPPORT_THREADS_ANY
+
 config LIBC_SUPPORT_LINUXTHREADS
     bool
     select LIBC_SUPPORT_THREADS_ANY
@@ -42,6 +46,7 @@  config LIBC_SUPPORT_THREADS_NONE
 config THREADS
     string
     default "nptl"          if THREADS_NPTL
+    default "musl"          if THREADS_MUSL
     default "linuxthreads"  if THREADS_LINUXTHREADS
     default "win32"         if THREADS_WIN32THREADS
     default "none"          if THREADS_NONE || LIBC_none
@@ -55,6 +60,7 @@  choice
     bool
     prompt "Threading implementation to use:"
     default THREADS_NPTL           if LIBC_SUPPORT_NPTL
+    default THREADS_MUSL           if LIBC_SUPPORT_MUSL
     default THREADS_LINUXTHREADS   if LIBC_SUPPORT_LINUXTHREADS && ! LIBC_SUPPORT_NPTL
     default THREADS_WIN32          if LIBC_SUPPORT_WIN32THREADS
     default THREADS_NONE           if ! LIBC_SUPPORT_THREADS_ANY
@@ -64,6 +70,11 @@  config THREADS_NPTL
     prompt "nptl"
     depends on LIBC_SUPPORT_NPTL
 
+config THREADS_MUSL
+    bool
+    prompt "musl"
+    depends on LIBC_SUPPORT_MUSL
+
 config THREADS_LINUXTHREADS
     bool
     prompt "linuxthreads"
diff --git a/config/libc/musl.in b/config/libc/musl.in
new file mode 100644
index 0000000..69f465c
--- /dev/null
+++ b/config/libc/musl.in
@@ -0,0 +1,47 @@ 
+# musl options
+
+## depends on ! WINDOWS && ! BARE_METAL
+##
+## select LIBC_SUPPORT_MUSL
+## select CC_CORE_PASSES_NEEDED
+##
+## help Musl is a new standard library to power a new generation of Linux-based
+## help devices. musl is lightweight, fast, simple, free, and strives to be
+## help correct in the sense of standards-conformance and safety.
+
+choice
+    bool
+    prompt "musl version"
+# Don't remove next line
+# CT_INSERT_VERSION_BELOW
+
+config LIBC_MUSL_V_1_1_3
+    bool
+    prompt "1.1.3 (Mainline)"
+    select LIBC_MUSL_DEFAULTS
+    depends on EXPERIMENTAL
+
+config LIBC_MUSL_V_1_0_3
+    bool
+    prompt "1.0.3 (Stable)"
+    select LIBC_MUSL_DEFAULTS
+
+config LIBC_MUSL_V_CUSTOM
+    bool
+    prompt "Custom musl"
+    select LIBC_MUSL_DEFAULTS
+    depends on EXPERIMENTAL
+
+endchoice
+
+config LIBC_MUSL_DEFAULTS
+    bool
+    select LIBC_SUPPORT_MUSL
+
+config LIBC_VERSION
+    string
+# Don't remove next line
+# CT_INSERT_VERSION_STRING_BELOW
+    default "1.1.3" if LIBC_MUSL_V_1_1_3
+    default "1.0.3" if LIBC_MUSL_V_1_0_3
+    default "custom" if LIBC_MUSL_V_CUSTOM
diff --git a/config/libc/musl.in.2 b/config/libc/musl.in.2
new file mode 100644
index 0000000..6fd954c
--- /dev/null
+++ b/config/libc/musl.in.2
@@ -0,0 +1,2 @@ 
+# musl second-part options\n
+
diff --git a/patches/gcc/4.8.2/020-musl-support.patch b/patches/gcc/4.8.2/020-musl-support.patch
new file mode 100644
index 0000000..a4e4987
--- /dev/null
+++ b/patches/gcc/4.8.2/020-musl-support.patch
@@ -0,0 +1,381 @@ 
+diff --git a/gcc/config.gcc b/gcc/config.gcc
+index 92d57dd..9ed4828 100644
+--- a/gcc/config.gcc
++++ b/gcc/config.gcc
+@@ -550,7 +550,7 @@ case ${target} in
+ esac
+ 
+ # Common C libraries.
+-tm_defines="$tm_defines LIBC_GLIBC=1 LIBC_UCLIBC=2 LIBC_BIONIC=3"
++tm_defines="$tm_defines LIBC_GLIBC=1 LIBC_UCLIBC=2 LIBC_BIONIC=3 LIBC_MUSL=4"
+ 
+ # Common parts for widely ported systems.
+ case ${target} in
+@@ -653,6 +653,9 @@ case ${target} in
+     *-*-*uclibc*)
+       tm_defines="$tm_defines DEFAULT_LIBC=LIBC_UCLIBC"
+       ;;
++    *-*-*musl*)
++      tm_defines="$tm_defines DEFAULT_LIBC=LIBC_MUSL"
++      ;;
+     *)
+       tm_defines="$tm_defines DEFAULT_LIBC=LIBC_GLIBC"
+       ;;
+@@ -2114,6 +2117,10 @@ powerpc*-*-linux*)
+ 	    powerpc*-*-linux*paired*)
+ 		tm_file="${tm_file} rs6000/750cl.h" ;;
+ 	esac
++        case ${target} in
++            *-linux*-musl*)
++                enable_secureplt=yes ;;
++        esac
+ 	if test x${enable_secureplt} = xyes; then
+ 		tm_file="rs6000/secureplt.h ${tm_file}"
+ 	fi
+diff --git a/gcc/config/arm/linux-eabi.h b/gcc/config/arm/linux-eabi.h
+index 4a425c8..6fa88b9 100644
+--- a/gcc/config/arm/linux-eabi.h
++++ b/gcc/config/arm/linux-eabi.h
+@@ -77,6 +77,10 @@
+     %{mfloat-abi=soft*:" GLIBC_DYNAMIC_LINKER_SOFT_FLOAT "} \
+     %{!mfloat-abi=*:" GLIBC_DYNAMIC_LINKER_DEFAULT "}"
+ 
++/* musl has no "classic" (i.e. broken) mode */
++#undef  MUSL_DYNAMIC_LINKER
++#define MUSL_DYNAMIC_LINKER "/lib/ld-musl-arm.so.1"
++
+ /* At this point, bpabi.h will have clobbered LINK_SPEC.  We want to
+    use the GNU/Linux version, not the generic BPABI version.  */
+ #undef  LINK_SPEC
+diff --git a/gcc/config/i386/linux.h b/gcc/config/i386/linux.h
+index 3c95ee0..93725fa 100644
+--- a/gcc/config/i386/linux.h
++++ b/gcc/config/i386/linux.h
+@@ -21,3 +21,4 @@ along with GCC; see the file COPYING3.  If not see
+ 
+ #define GNU_USER_LINK_EMULATION "elf_i386"
+ #define GLIBC_DYNAMIC_LINKER "/lib/ld-linux.so.2"
++#define MUSL_DYNAMIC_LINKER "/lib/ld-musl-i386.so.1"
+diff --git a/gcc/config/i386/linux64.h b/gcc/config/i386/linux64.h
+index b793e08..d6e2bf9 100644
+--- a/gcc/config/i386/linux64.h
++++ b/gcc/config/i386/linux64.h
+@@ -30,3 +30,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+ #define GLIBC_DYNAMIC_LINKER32 "/lib/ld-linux.so.2"
+ #define GLIBC_DYNAMIC_LINKER64 "/lib64/ld-linux-x86-64.so.2"
+ #define GLIBC_DYNAMIC_LINKERX32 "/libx32/ld-linux-x32.so.2"
++
++#define MUSL_DYNAMIC_LINKER32 "/lib/ld-musl-i386.so.1"
++#define MUSL_DYNAMIC_LINKER64 "/lib/ld-musl-x86_64.so.1"
++#define MUSL_DYNAMIC_LINKERX32 "/lib/ld-musl-x32.so.1"
+diff --git a/gcc/config/linux.h b/gcc/config/linux.h
+index 2be1079..dc88df9 100644
+--- a/gcc/config/linux.h
++++ b/gcc/config/linux.h
+@@ -32,10 +32,12 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+ #define OPTION_GLIBC  (DEFAULT_LIBC == LIBC_GLIBC)
+ #define OPTION_UCLIBC (DEFAULT_LIBC == LIBC_UCLIBC)
+ #define OPTION_BIONIC (DEFAULT_LIBC == LIBC_BIONIC)
++#define OPTION_MUSL   (DEFAULT_LIBC == LIBC_MUSL)
+ #else
+ #define OPTION_GLIBC  (linux_libc == LIBC_GLIBC)
+ #define OPTION_UCLIBC (linux_libc == LIBC_UCLIBC)
+ #define OPTION_BIONIC (linux_libc == LIBC_BIONIC)
++#define OPTION_MUSL   (linux_libc == LIBC_MUSL)
+ #endif
+ 
+ #define GNU_USER_TARGET_OS_CPP_BUILTINS()			\
+@@ -53,18 +55,21 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+    uClibc or Bionic is the default C library and whether
+    -muclibc or -mglibc or -mbionic has been passed to change the default.  */
+ 
+-#define CHOOSE_DYNAMIC_LINKER1(LIBC1, LIBC2, LIBC3, LD1, LD2, LD3)	\
+-  "%{" LIBC2 ":" LD2 ";:%{" LIBC3 ":" LD3 ";:" LD1 "}}"
++#define CHOOSE_DYNAMIC_LINKER1(LIBC1, LIBC2, LIBC3, LIBC4, LD1, LD2, LD3, LD4)	\
++  "%{" LIBC2 ":" LD2 ";:%{" LIBC3 ":" LD3 ";:%{" LIBC4 ":" LD4 ";:" LD1 "}}}"
+ 
+ #if DEFAULT_LIBC == LIBC_GLIBC
+-#define CHOOSE_DYNAMIC_LINKER(G, U, B) \
+-  CHOOSE_DYNAMIC_LINKER1 ("mglibc", "muclibc", "mbionic", G, U, B)
++#define CHOOSE_DYNAMIC_LINKER(G, U, B, M) \
++  CHOOSE_DYNAMIC_LINKER1 ("mglibc", "muclibc", "mbionic", "mmusl", G, U, B, M)
+ #elif DEFAULT_LIBC == LIBC_UCLIBC
+-#define CHOOSE_DYNAMIC_LINKER(G, U, B) \
+-  CHOOSE_DYNAMIC_LINKER1 ("muclibc", "mglibc", "mbionic", U, G, B)
++#define CHOOSE_DYNAMIC_LINKER(G, U, B, M) \
++  CHOOSE_DYNAMIC_LINKER1 ("muclibc", "mglibc", "mbionic", "mmusl", U, G, B, M)
+ #elif DEFAULT_LIBC == LIBC_BIONIC
+-#define CHOOSE_DYNAMIC_LINKER(G, U, B) \
+-  CHOOSE_DYNAMIC_LINKER1 ("mbionic", "mglibc", "muclibc", B, G, U)
++#define CHOOSE_DYNAMIC_LINKER(G, U, B, M) \
++  CHOOSE_DYNAMIC_LINKER1 ("mbionic", "mglibc", "muclibc", "mmusl", B, G, U, M)
++#elif DEFAULT_LIBC == LIBC_MUSL
++#define CHOOSE_DYNAMIC_LINKER(G, U, B, M) \
++  CHOOSE_DYNAMIC_LINKER1 ("mmusl", "mglibc", "muclibc", "mbionic", M, G, U, B)
+ #else
+ #error "Unsupported DEFAULT_LIBC"
+ #endif /* DEFAULT_LIBC */
+@@ -84,16 +89,16 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+ 
+ #define GNU_USER_DYNAMIC_LINKER						\
+   CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKER, UCLIBC_DYNAMIC_LINKER,	\
+-			 BIONIC_DYNAMIC_LINKER)
++			 BIONIC_DYNAMIC_LINKER, MUSL_DYNAMIC_LINKER)
+ #define GNU_USER_DYNAMIC_LINKER32					\
+   CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKER32, UCLIBC_DYNAMIC_LINKER32, \
+-			 BIONIC_DYNAMIC_LINKER32)
++			 BIONIC_DYNAMIC_LINKER32, MUSL_DYNAMIC_LINKER32)
+ #define GNU_USER_DYNAMIC_LINKER64					\
+   CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKER64, UCLIBC_DYNAMIC_LINKER64, \
+-			 BIONIC_DYNAMIC_LINKER64)
++			 BIONIC_DYNAMIC_LINKER64, MUSL_DYNAMIC_LINKER64)
+ #define GNU_USER_DYNAMIC_LINKERX32					\
+   CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKERX32, UCLIBC_DYNAMIC_LINKERX32, \
+-			 BIONIC_DYNAMIC_LINKERX32)
++			 BIONIC_DYNAMIC_LINKERX32, MUSL_DYNAMIC_LINKERX32)
+ 
+ /* Determine whether the entire c99 runtime
+    is present in the runtime library.  */
+diff --git a/gcc/config/linux.opt b/gcc/config/linux.opt
+index 27991be..24f9f68 100644
+--- a/gcc/config/linux.opt
++++ b/gcc/config/linux.opt
+@@ -30,3 +30,7 @@ Use GNU C library
+ muclibc
+ Target Report RejectNegative Var(linux_libc,LIBC_UCLIBC) Negative(mbionic)
+ Use uClibc C library
++
++mmusl
++Target Report RejectNegative Var(linux_libc,LIBC_MUSL) Negative(mglibc)
++Use musl C library
+diff --git a/gcc/config/mips/linux.h b/gcc/config/mips/linux.h
+index 9b4c68d..47994b7 100644
+--- a/gcc/config/mips/linux.h
++++ b/gcc/config/mips/linux.h
+@@ -18,3 +18,5 @@ along with GCC; see the file COPYING3.  If not see
+ <http://www.gnu.org/licenses/>.  */
+ 
+ #define GLIBC_DYNAMIC_LINKER "/lib/ld.so.1"
++
++#define MUSL_DYNAMIC_LINKER "/lib/ld-musl-mips.so.1"
+diff --git a/gcc/config/rs6000/linux64.h b/gcc/config/rs6000/linux64.h
+index 3f28058..35c691b 100644
+--- a/gcc/config/rs6000/linux64.h
++++ b/gcc/config/rs6000/linux64.h
+@@ -354,17 +354,21 @@ extern int dot_symbols;
+ #define GLIBC_DYNAMIC_LINKER64 "/lib64/ld64.so.1"
+ #define UCLIBC_DYNAMIC_LINKER32 "/lib/ld-uClibc.so.0"
+ #define UCLIBC_DYNAMIC_LINKER64 "/lib/ld64-uClibc.so.0"
++#define MUSL_DYNAMIC_LINKER32 "/lib/ld-musl-powerpc.so.1"
++#define MUSL_DYNAMIC_LINKER64 "/lib/ld-musl-powerpc64.so.1"
+ #if DEFAULT_LIBC == LIBC_UCLIBC
+-#define CHOOSE_DYNAMIC_LINKER(G, U) "%{mglibc:" G ";:" U "}"
++#define CHOOSE_DYNAMIC_LINKER(G, U, M) "%{mglibc:" G ";:%{mmusl:" M ";:" U "}}"
+ #elif DEFAULT_LIBC == LIBC_GLIBC
+-#define CHOOSE_DYNAMIC_LINKER(G, U) "%{muclibc:" U ";:" G "}"
++#define CHOOSE_DYNAMIC_LINKER(G, U, M) "%{muclibc:" U ";:%{mmusl:" M ";:" G "}}"
++#elif DEFAULT_LIBC == LIBC_MUSL
++#define CHOOSE_DYNAMIC_LINKER(G, U, M) "%{mglibc:" G ";:%{muclibc:" U ";:" M "}}"
+ #else
+ #error "Unsupported DEFAULT_LIBC"
+ #endif
+ #define GNU_USER_DYNAMIC_LINKER32 \
+-  CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKER32, UCLIBC_DYNAMIC_LINKER32)
++  CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKER32, UCLIBC_DYNAMIC_LINKER32, MUSL_DYNAMIC_LINKER32)
+ #define GNU_USER_DYNAMIC_LINKER64 \
+-  CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKER64, UCLIBC_DYNAMIC_LINKER64)
++  CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKER64, UCLIBC_DYNAMIC_LINKER64, MUSL_DYNAMIC_LINKER64)
+ 
+ #undef  DEFAULT_ASM_ENDIAN
+ #if (TARGET_DEFAULT & MASK_LITTLE_ENDIAN)
+diff --git a/gcc/config/rs6000/secureplt.h b/gcc/config/rs6000/secureplt.h
+index 39ffb88..5d3817f 100644
+--- a/gcc/config/rs6000/secureplt.h
++++ b/gcc/config/rs6000/secureplt.h
+@@ -18,3 +18,4 @@ along with GCC; see the file COPYING3.  If not see
+ <http://www.gnu.org/licenses/>.  */
+ 
+ #define CC1_SECURE_PLT_DEFAULT_SPEC "-msecure-plt"
++#define LINK_SECURE_PLT_DEFAULT_SPEC "--secure-plt"
+diff --git a/gcc/config/rs6000/sysv4.h b/gcc/config/rs6000/sysv4.h
+index 0cc8ffb..766d1d9 100644
+--- a/gcc/config/rs6000/sysv4.h
++++ b/gcc/config/rs6000/sysv4.h
+@@ -550,6 +550,9 @@ ENDIAN_SELECT(" -mbig", " -mlittle", DEFAULT_ASM_ENDIAN)
+ #ifndef CC1_SECURE_PLT_DEFAULT_SPEC
+ #define CC1_SECURE_PLT_DEFAULT_SPEC ""
+ #endif
++#ifndef LINK_SECURE_PLT_DEFAULT_SPEC
++#define LINK_SECURE_PLT_DEFAULT_SPEC ""
++#endif
+ 
+ /* Pass -G xxx to the compiler and set correct endian mode.  */
+ #define	CC1_SPEC "%{G*} %(cc1_cpu)" \
+@@ -566,6 +569,7 @@ ENDIAN_SELECT(" -mbig", " -mlittle", DEFAULT_ASM_ENDIAN)
+ %{msdata: -msdata=default} \
+ %{mno-sdata: -msdata=none} \
+ %{!mbss-plt: %{!msecure-plt: %(cc1_secure_plt_default)}} \
++%{!mbss-plt: %{!msecure-plt: %(link_secure_plt_default)}} \
+ %{profile: -p}"
+ 
+ /* Default starting address if specified.  */
+@@ -778,15 +782,18 @@ ENDIAN_SELECT(" -mbig", " -mlittle", DEFAULT_ASM_ENDIAN)
+ 
+ #define GLIBC_DYNAMIC_LINKER "/lib/ld.so.1"
+ #define UCLIBC_DYNAMIC_LINKER "/lib/ld-uClibc.so.0"
++#define MUSL_DYNAMIC_LINKER "/lib/ld-musl-powerpc.so.1"
+ #if DEFAULT_LIBC == LIBC_UCLIBC
+-#define CHOOSE_DYNAMIC_LINKER(G, U) "%{mglibc:" G ";:" U "}"
++#define CHOOSE_DYNAMIC_LINKER(G, U, M) "%{mglibc:" G ";:%{mmusl:" M ";:" U "}}"
++#elif DEFAULT_LIBC == LIBC_MUSL
++#define CHOOSE_DYNAMIC_LINKER(G, U, M) "%{mglibc:" G ";:%{muclibc:" U ";:" M "}}"
+ #elif !defined (DEFAULT_LIBC) || DEFAULT_LIBC == LIBC_GLIBC
+-#define CHOOSE_DYNAMIC_LINKER(G, U) "%{muclibc:" U ";:" G "}"
++#define CHOOSE_DYNAMIC_LINKER(G, U, M) "%{muclibc:" U ";:%{mmusl:" M ";:" G "}}"
+ #else
+ #error "Unsupported DEFAULT_LIBC"
+ #endif
+ #define GNU_USER_DYNAMIC_LINKER \
+-  CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKER, UCLIBC_DYNAMIC_LINKER)
++  CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKER, UCLIBC_DYNAMIC_LINKER, MUSL_DYNAMIC_LINKER)
+ 
+ #define LINK_OS_LINUX_SPEC "-m elf32ppclinux %{!shared: %{!static: \
+   %{rdynamic:-export-dynamic} \
+@@ -912,6 +919,7 @@ ncrtn.o%s"
+   { "cc1_endian_little",	CC1_ENDIAN_LITTLE_SPEC },		\
+   { "cc1_endian_default",	CC1_ENDIAN_DEFAULT_SPEC },		\
+   { "cc1_secure_plt_default",	CC1_SECURE_PLT_DEFAULT_SPEC },		\
++  { "link_secure_plt_default",	LINK_SECURE_PLT_DEFAULT_SPEC },		\
+   { "cpp_os_ads",		CPP_OS_ADS_SPEC },			\
+   { "cpp_os_yellowknife",	CPP_OS_YELLOWKNIFE_SPEC },		\
+   { "cpp_os_mvme",		CPP_OS_MVME_SPEC },			\
+diff --git a/gcc/ginclude/stddef.h b/gcc/ginclude/stddef.h
+index b04dd65..9a4d58b 100644
+--- a/gcc/ginclude/stddef.h
++++ b/gcc/ginclude/stddef.h
+@@ -181,6 +181,7 @@ typedef __PTRDIFF_TYPE__ ptrdiff_t;
+ #ifndef _GCC_SIZE_T
+ #ifndef _SIZET_
+ #ifndef __size_t
++#ifndef __DEFINED_size_t /* musl */
+ #define __size_t__	/* BeOS */
+ #define __SIZE_T__	/* Cray Unicos/Mk */
+ #define _SIZE_T
+@@ -197,6 +198,7 @@ typedef __PTRDIFF_TYPE__ ptrdiff_t;
+ #define ___int_size_t_h
+ #define _GCC_SIZE_T
+ #define _SIZET_
++#define __DEFINED_size_t /* musl */
+ #if (defined (__FreeBSD__) && (__FreeBSD__ >= 5)) \
+   || defined(__FreeBSD_kernel__)
+ /* __size_t is a typedef on FreeBSD 5, must not trash it. */
+@@ -214,6 +216,7 @@ typedef __SIZE_TYPE__ size_t;
+ typedef long ssize_t;
+ #endif /* __BEOS__ */
+ #endif /* !(defined (__GNUG__) && defined (size_t)) */
++#endif /* __DEFINED_size_t */
+ #endif /* __size_t */
+ #endif /* _SIZET_ */
+ #endif /* _GCC_SIZE_T */
+diff --git a/libgcc/config/rs6000/linux-unwind.h b/libgcc/config/rs6000/linux-unwind.h
+index c9273c4..6118a95 100644
+--- a/libgcc/config/rs6000/linux-unwind.h
++++ b/libgcc/config/rs6000/linux-unwind.h
+@@ -258,6 +258,7 @@ ppc_fallback_frame_state (struct _Unwind_Context *context,
+ 
+   return _URC_NO_REASON;
+ }
++#endif
+ 
+ #define MD_FROB_UPDATE_CONTEXT frob_update_context
+ 
+diff --git a/libgomp/config/posix/time.c b/libgomp/config/posix/time.c
+index 37898ec..67cf25f 100644
+--- a/libgomp/config/posix/time.c
++++ b/libgomp/config/posix/time.c
+@@ -28,6 +28,8 @@
+    The following implementation uses the most simple POSIX routines.
+    If present, POSIX 4 clocks should be used instead.  */
+ 
++#define _POSIX_C_SOURCE 199309L /* for clocks */
++
+ #include "libgomp.h"
+ #include <unistd.h>
+ #if TIME_WITH_SYS_TIME
+diff --git a/libitm/config/arm/hwcap.cc b/libitm/config/arm/hwcap.cc
+index d064917..e5278c9 100644
+--- a/libitm/config/arm/hwcap.cc
++++ b/libitm/config/arm/hwcap.cc
+@@ -40,7 +40,11 @@ int GTM_hwcap HIDDEN = 0
+ 
+ #ifdef __linux__
+ #include <unistd.h>
++#ifdef __GLIBC__
+ #include <sys/fcntl.h>
++#else
++#include <fcntl.h>
++#endif
+ #include <elf.h>
+ 
+ static void __attribute__((constructor))
+diff --git a/libitm/config/linux/x86/tls.h b/libitm/config/linux/x86/tls.h
+index 4e0115f..ba03047 100644
+--- a/libitm/config/linux/x86/tls.h
++++ b/libitm/config/linux/x86/tls.h
+@@ -25,16 +25,19 @@
+ #ifndef LIBITM_X86_TLS_H
+ #define LIBITM_X86_TLS_H 1
+ 
+-#if defined(__GLIBC_PREREQ) && __GLIBC_PREREQ(2, 10)
++#if defined(__GLIBC_PREREQ)
++#if __GLIBC_PREREQ(2, 10)
+ /* Use slots in the TCB head rather than __thread lookups.
+    GLIBC has reserved words 10 through 13 for TM.  */
+ #define HAVE_ARCH_GTM_THREAD 1
+ #define HAVE_ARCH_GTM_THREAD_DISP 1
+ #endif
++#endif
+ 
+ #include "config/generic/tls.h"
+ 
+-#if defined(__GLIBC_PREREQ) && __GLIBC_PREREQ(2, 10)
++#if defined(__GLIBC_PREREQ)
++#if __GLIBC_PREREQ(2, 10)
+ namespace GTM HIDDEN {
+ 
+ #ifdef __x86_64__
+@@ -101,5 +104,6 @@ static inline void set_abi_disp(struct abi_dispatch *x)
+ 
+ } // namespace GTM
+ #endif /* >= GLIBC 2.10 */
++#endif
+ 
+ #endif // LIBITM_X86_TLS_H
+diff --git a/libstdc++-v3/configure.host b/libstdc++-v3/configure.host
+index 23b3f52..75e9a55 100644
+--- a/libstdc++-v3/configure.host
++++ b/libstdc++-v3/configure.host
+@@ -264,6 +264,13 @@ case "${host_os}" in
+     os_include_dir="os/bsd/freebsd"
+     ;;
+   gnu* | linux* | kfreebsd*-gnu | knetbsd*-gnu)
++    # check for musl by target
++    case "${host_os}" in
++      *-musl*)
++        os_include_dir="os/generic"
++        ;;
++      *)
++
+     if [ "$uclibc" = "yes" ]; then
+       os_include_dir="os/uclibc"
+     elif [ "$bionic" = "yes" ]; then
+@@ -272,6 +279,9 @@ case "${host_os}" in
+       os_include_dir="os/gnu-linux"
+     fi
+     ;;
++
++    esac
++    ;;
+   hpux*)
+     os_include_dir="os/hpux"
+     ;;
diff --git a/patches/gcc/4.9.0/020-musl-support.patch b/patches/gcc/4.9.0/020-musl-support.patch
new file mode 100644
index 0000000..a93ff73
--- /dev/null
+++ b/patches/gcc/4.9.0/020-musl-support.patch
@@ -0,0 +1,385 @@ 
+diff --git a/gcc/config.gcc b/gcc/config.gcc
+index 3c55c88..e526ef3 100644
+--- a/gcc/config.gcc
++++ b/gcc/config.gcc
+@@ -594,7 +594,7 @@ case ${target} in
+ esac
+ 
+ # Common C libraries.
+-tm_defines="$tm_defines LIBC_GLIBC=1 LIBC_UCLIBC=2 LIBC_BIONIC=3"
++tm_defines="$tm_defines LIBC_GLIBC=1 LIBC_UCLIBC=2 LIBC_BIONIC=3 LIBC_MUSL=4"
+ 
+ # 32-bit x86 processors supported by --with-arch=.  Each processor
+ # MUST be separated by exactly one space.
+@@ -719,6 +719,9 @@ case ${target} in
+     *-*-*uclibc*)
+       tm_defines="$tm_defines DEFAULT_LIBC=LIBC_UCLIBC"
+       ;;
++    *-*-*musl*)
++      tm_defines="$tm_defines DEFAULT_LIBC=LIBC_MUSL"
++      ;;
+     *)
+       tm_defines="$tm_defines DEFAULT_LIBC=LIBC_GLIBC"
+       ;;
+@@ -2323,6 +2326,10 @@ powerpc*-*-linux*)
+ 	    powerpc*-*-linux*paired*)
+ 		tm_file="${tm_file} rs6000/750cl.h" ;;
+ 	esac
++        case ${target} in
++            *-linux*-musl*)
++                enable_secureplt=yes ;;
++        esac
+ 	if test x${enable_secureplt} = xyes; then
+ 		tm_file="rs6000/secureplt.h ${tm_file}"
+ 	fi
+diff --git a/gcc/config/arm/linux-eabi.h b/gcc/config/arm/linux-eabi.h
+index f1f3448..8c297b9 100644
+--- a/gcc/config/arm/linux-eabi.h
++++ b/gcc/config/arm/linux-eabi.h
+@@ -77,6 +77,10 @@
+     %{mfloat-abi=soft*:" GLIBC_DYNAMIC_LINKER_SOFT_FLOAT "} \
+     %{!mfloat-abi=*:" GLIBC_DYNAMIC_LINKER_DEFAULT "}"
+ 
++/* musl has no "classic" (i.e. broken) mode */
++#undef  MUSL_DYNAMIC_LINKER
++#define MUSL_DYNAMIC_LINKER "/lib/ld-musl-arm.so.1"
++
+ /* At this point, bpabi.h will have clobbered LINK_SPEC.  We want to
+    use the GNU/Linux version, not the generic BPABI version.  */
+ #undef  LINK_SPEC
+diff --git a/gcc/config/i386/linux.h b/gcc/config/i386/linux.h
+index 1fb1e03..22144f6 100644
+--- a/gcc/config/i386/linux.h
++++ b/gcc/config/i386/linux.h
+@@ -21,3 +21,4 @@ along with GCC; see the file COPYING3.  If not see
+ 
+ #define GNU_USER_LINK_EMULATION "elf_i386"
+ #define GLIBC_DYNAMIC_LINKER "/lib/ld-linux.so.2"
++#define MUSL_DYNAMIC_LINKER "/lib/ld-musl-i386.so.1"
+diff --git a/gcc/config/i386/linux64.h b/gcc/config/i386/linux64.h
+index a90171e..8d4bf5f 100644
+--- a/gcc/config/i386/linux64.h
++++ b/gcc/config/i386/linux64.h
+@@ -30,3 +30,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+ #define GLIBC_DYNAMIC_LINKER32 "/lib/ld-linux.so.2"
+ #define GLIBC_DYNAMIC_LINKER64 "/lib64/ld-linux-x86-64.so.2"
+ #define GLIBC_DYNAMIC_LINKERX32 "/libx32/ld-linux-x32.so.2"
++
++#define MUSL_DYNAMIC_LINKER32 "/lib/ld-musl-i386.so.1"
++#define MUSL_DYNAMIC_LINKER64 "/lib/ld-musl-x86_64.so.1"
++#define MUSL_DYNAMIC_LINKERX32 "/lib/ld-musl-x32.so.1"
+diff --git a/gcc/config/linux.h b/gcc/config/linux.h
+index d38ef81..1a1a684 100644
+--- a/gcc/config/linux.h
++++ b/gcc/config/linux.h
+@@ -32,10 +32,12 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+ #define OPTION_GLIBC  (DEFAULT_LIBC == LIBC_GLIBC)
+ #define OPTION_UCLIBC (DEFAULT_LIBC == LIBC_UCLIBC)
+ #define OPTION_BIONIC (DEFAULT_LIBC == LIBC_BIONIC)
++#define OPTION_MUSL   (DEFAULT_LIBC == LIBC_MUSL)
+ #else
+ #define OPTION_GLIBC  (linux_libc == LIBC_GLIBC)
+ #define OPTION_UCLIBC (linux_libc == LIBC_UCLIBC)
+ #define OPTION_BIONIC (linux_libc == LIBC_BIONIC)
++#define OPTION_MUSL   (linux_libc == LIBC_MUSL)
+ #endif
+ 
+ #define GNU_USER_TARGET_OS_CPP_BUILTINS()			\
+@@ -53,18 +55,21 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+    uClibc or Bionic is the default C library and whether
+    -muclibc or -mglibc or -mbionic has been passed to change the default.  */
+ 
+-#define CHOOSE_DYNAMIC_LINKER1(LIBC1, LIBC2, LIBC3, LD1, LD2, LD3)	\
+-  "%{" LIBC2 ":" LD2 ";:%{" LIBC3 ":" LD3 ";:" LD1 "}}"
++#define CHOOSE_DYNAMIC_LINKER1(LIBC1, LIBC2, LIBC3, LIBC4, LD1, LD2, LD3, LD4)	\
++  "%{" LIBC2 ":" LD2 ";:%{" LIBC3 ":" LD3 ";:%{" LIBC4 ":" LD4 ";:" LD1 "}}}"
+ 
+ #if DEFAULT_LIBC == LIBC_GLIBC
+-#define CHOOSE_DYNAMIC_LINKER(G, U, B) \
+-  CHOOSE_DYNAMIC_LINKER1 ("mglibc", "muclibc", "mbionic", G, U, B)
++#define CHOOSE_DYNAMIC_LINKER(G, U, B, M) \
++  CHOOSE_DYNAMIC_LINKER1 ("mglibc", "muclibc", "mbionic", "mmusl", G, U, B, M)
+ #elif DEFAULT_LIBC == LIBC_UCLIBC
+-#define CHOOSE_DYNAMIC_LINKER(G, U, B) \
+-  CHOOSE_DYNAMIC_LINKER1 ("muclibc", "mglibc", "mbionic", U, G, B)
++#define CHOOSE_DYNAMIC_LINKER(G, U, B, M) \
++  CHOOSE_DYNAMIC_LINKER1 ("muclibc", "mglibc", "mbionic", "mmusl", U, G, B, M)
+ #elif DEFAULT_LIBC == LIBC_BIONIC
+-#define CHOOSE_DYNAMIC_LINKER(G, U, B) \
+-  CHOOSE_DYNAMIC_LINKER1 ("mbionic", "mglibc", "muclibc", B, G, U)
++#define CHOOSE_DYNAMIC_LINKER(G, U, B, M) \
++  CHOOSE_DYNAMIC_LINKER1 ("mbionic", "mglibc", "muclibc", "mmusl", B, G, U, M)
++#elif DEFAULT_LIBC == LIBC_MUSL
++#define CHOOSE_DYNAMIC_LINKER(G, U, B, M) \
++  CHOOSE_DYNAMIC_LINKER1 ("mmusl", "mglibc", "muclibc", "mbionic", M, G, U, B)
+ #else
+ #error "Unsupported DEFAULT_LIBC"
+ #endif /* DEFAULT_LIBC */
+@@ -84,16 +89,16 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+ 
+ #define GNU_USER_DYNAMIC_LINKER						\
+   CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKER, UCLIBC_DYNAMIC_LINKER,	\
+-			 BIONIC_DYNAMIC_LINKER)
++			 BIONIC_DYNAMIC_LINKER, MUSL_DYNAMIC_LINKER)
+ #define GNU_USER_DYNAMIC_LINKER32					\
+   CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKER32, UCLIBC_DYNAMIC_LINKER32, \
+-			 BIONIC_DYNAMIC_LINKER32)
++			 BIONIC_DYNAMIC_LINKER32, MUSL_DYNAMIC_LINKER32)
+ #define GNU_USER_DYNAMIC_LINKER64					\
+   CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKER64, UCLIBC_DYNAMIC_LINKER64, \
+-			 BIONIC_DYNAMIC_LINKER64)
++			 BIONIC_DYNAMIC_LINKER64, MUSL_DYNAMIC_LINKER64)
+ #define GNU_USER_DYNAMIC_LINKERX32					\
+   CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKERX32, UCLIBC_DYNAMIC_LINKERX32, \
+-			 BIONIC_DYNAMIC_LINKERX32)
++			 BIONIC_DYNAMIC_LINKERX32, MUSL_DYNAMIC_LINKERX32)
+ 
+ /* Whether we have Bionic libc runtime */
+ #undef TARGET_HAS_BIONIC
+diff --git a/gcc/config/linux.opt b/gcc/config/linux.opt
+index 435bd87..0c94f14 100644
+--- a/gcc/config/linux.opt
++++ b/gcc/config/linux.opt
+@@ -30,3 +30,7 @@ Use GNU C library
+ muclibc
+ Target Report RejectNegative Var(linux_libc,LIBC_UCLIBC) Negative(mbionic)
+ Use uClibc C library
++
++mmusl
++Target Report RejectNegative Var(linux_libc,LIBC_MUSL) Negative(mglibc)
++Use musl C library
+diff --git a/gcc/config/mips/linux.h b/gcc/config/mips/linux.h
+index e539422..7141ad9 100644
+--- a/gcc/config/mips/linux.h
++++ b/gcc/config/mips/linux.h
+@@ -20,6 +20,9 @@ along with GCC; see the file COPYING3.  If not see
+ #define GLIBC_DYNAMIC_LINKER \
+   "%{mnan=2008:/lib/ld-linux-mipsn8.so.1;:/lib/ld.so.1}"
+ 
++#define MUSL_DYNAMIC_LINKER \
++	"/lib/ld-musl-mips.so.1"
++
+ #undef UCLIBC_DYNAMIC_LINKER
+ #define UCLIBC_DYNAMIC_LINKER \
+   "%{mnan=2008:/lib/ld-uClibc-mipsn8.so.0;:/lib/ld-uClibc.so.0}"
+diff --git a/gcc/config/rs6000/linux64.h b/gcc/config/rs6000/linux64.h
+index dbc9a52..c66f4d0 100644
+--- a/gcc/config/rs6000/linux64.h
++++ b/gcc/config/rs6000/linux64.h
+@@ -375,17 +375,21 @@ extern int dot_symbols;
+ #endif
+ #define UCLIBC_DYNAMIC_LINKER32 "/lib/ld-uClibc.so.0"
+ #define UCLIBC_DYNAMIC_LINKER64 "/lib/ld64-uClibc.so.0"
++#define MUSL_DYNAMIC_LINKER32 "/lib/ld-musl-powerpc.so.1"
++#define MUSL_DYNAMIC_LINKER64 "/lib/ld-musl-powerpc64.so.1"
+ #if DEFAULT_LIBC == LIBC_UCLIBC
+-#define CHOOSE_DYNAMIC_LINKER(G, U) "%{mglibc:" G ";:" U "}"
++#define CHOOSE_DYNAMIC_LINKER(G, U, M) "%{mglibc:" G ";:%{mmusl:" M ";:" U "}}"
+ #elif DEFAULT_LIBC == LIBC_GLIBC
+-#define CHOOSE_DYNAMIC_LINKER(G, U) "%{muclibc:" U ";:" G "}"
++#define CHOOSE_DYNAMIC_LINKER(G, U, M) "%{muclibc:" U ";:%{mmusl:" M ";:" G "}}"
++#elif DEFAULT_LIBC == LIBC_MUSL
++#define CHOOSE_DYNAMIC_LINKER(G, U, M) "%{mglibc:" G ";:%{muclibc:" U ";:" M "}}"
+ #else
+ #error "Unsupported DEFAULT_LIBC"
+ #endif
+ #define GNU_USER_DYNAMIC_LINKER32 \
+-  CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKER32, UCLIBC_DYNAMIC_LINKER32)
++  CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKER32, UCLIBC_DYNAMIC_LINKER32, MUSL_DYNAMIC_LINKER32)
+ #define GNU_USER_DYNAMIC_LINKER64 \
+-  CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKER64, UCLIBC_DYNAMIC_LINKER64)
++  CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKER64, UCLIBC_DYNAMIC_LINKER64, MUSL_DYNAMIC_LINKER64)
+ 
+ #undef  DEFAULT_ASM_ENDIAN
+ #if (TARGET_DEFAULT & MASK_LITTLE_ENDIAN)
+diff --git a/gcc/config/rs6000/secureplt.h b/gcc/config/rs6000/secureplt.h
+index 01959e3..ea3f62f 100644
+--- a/gcc/config/rs6000/secureplt.h
++++ b/gcc/config/rs6000/secureplt.h
+@@ -18,3 +18,4 @@ along with GCC; see the file COPYING3.  If not see
+ <http://www.gnu.org/licenses/>.  */
+ 
+ #define CC1_SECURE_PLT_DEFAULT_SPEC "-msecure-plt"
++#define LINK_SECURE_PLT_DEFAULT_SPEC "--secure-plt"
+diff --git a/gcc/config/rs6000/sysv4.h b/gcc/config/rs6000/sysv4.h
+index d04e6e4..43ced03 100644
+--- a/gcc/config/rs6000/sysv4.h
++++ b/gcc/config/rs6000/sysv4.h
+@@ -537,6 +537,9 @@ ENDIAN_SELECT(" -mbig", " -mlittle", DEFAULT_ASM_ENDIAN)
+ #ifndef CC1_SECURE_PLT_DEFAULT_SPEC
+ #define CC1_SECURE_PLT_DEFAULT_SPEC ""
+ #endif
++#ifndef LINK_SECURE_PLT_DEFAULT_SPEC
++#define LINK_SECURE_PLT_DEFAULT_SPEC ""
++#endif
+ 
+ /* Pass -G xxx to the compiler.  */
+ #define	CC1_SPEC "%{G*} %(cc1_cpu)" \
+@@ -551,6 +554,7 @@ ENDIAN_SELECT(" -mbig", " -mlittle", DEFAULT_ASM_ENDIAN)
+ %{msdata: -msdata=default} \
+ %{mno-sdata: -msdata=none} \
+ %{!mbss-plt: %{!msecure-plt: %(cc1_secure_plt_default)}} \
++%{!mbss-plt: %{!msecure-plt: %(link_secure_plt_default)}} \
+ %{profile: -p}"
+ 
+ /* Default starting address if specified.  */
+@@ -763,15 +767,18 @@ ENDIAN_SELECT(" -mbig", " -mlittle", DEFAULT_ASM_ENDIAN)
+ 
+ #define GLIBC_DYNAMIC_LINKER "/lib/ld.so.1"
+ #define UCLIBC_DYNAMIC_LINKER "/lib/ld-uClibc.so.0"
++#define MUSL_DYNAMIC_LINKER "/lib/ld-musl-powerpc.so.1"
+ #if DEFAULT_LIBC == LIBC_UCLIBC
+-#define CHOOSE_DYNAMIC_LINKER(G, U) "%{mglibc:" G ";:" U "}"
++#define CHOOSE_DYNAMIC_LINKER(G, U, M) "%{mglibc:" G ";:%{mmusl:" M ";:" U "}}"
++#elif DEFAULT_LIBC == LIBC_MUSL
++#define CHOOSE_DYNAMIC_LINKER(G, U, M) "%{mglibc:" G ";:%{muclibc:" U ";:" M "}}"
+ #elif !defined (DEFAULT_LIBC) || DEFAULT_LIBC == LIBC_GLIBC
+-#define CHOOSE_DYNAMIC_LINKER(G, U) "%{muclibc:" U ";:" G "}"
++#define CHOOSE_DYNAMIC_LINKER(G, U, M) "%{muclibc:" U ";:%{mmusl:" M ";:" G "}}"
+ #else
+ #error "Unsupported DEFAULT_LIBC"
+ #endif
+ #define GNU_USER_DYNAMIC_LINKER \
+-  CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKER, UCLIBC_DYNAMIC_LINKER)
++  CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKER, UCLIBC_DYNAMIC_LINKER, MUSL_DYNAMIC_LINKER)
+ 
+ #define LINK_OS_LINUX_SPEC "-m elf32ppclinux %{!shared: %{!static: \
+   %{rdynamic:-export-dynamic} \
+@@ -894,6 +901,7 @@ ncrtn.o%s"
+   { "link_os_openbsd",		LINK_OS_OPENBSD_SPEC },			\
+   { "link_os_default",		LINK_OS_DEFAULT_SPEC },			\
+   { "cc1_secure_plt_default",	CC1_SECURE_PLT_DEFAULT_SPEC },		\
++  { "link_secure_plt_default",	LINK_SECURE_PLT_DEFAULT_SPEC },		\
+   { "cpp_os_ads",		CPP_OS_ADS_SPEC },			\
+   { "cpp_os_yellowknife",	CPP_OS_YELLOWKNIFE_SPEC },		\
+   { "cpp_os_mvme",		CPP_OS_MVME_SPEC },			\
+diff --git a/gcc/ginclude/stddef.h b/gcc/ginclude/stddef.h
+index cfa8df3..5212a27 100644
+--- a/gcc/ginclude/stddef.h
++++ b/gcc/ginclude/stddef.h
+@@ -181,6 +181,7 @@ typedef __PTRDIFF_TYPE__ ptrdiff_t;
+ #ifndef _GCC_SIZE_T
+ #ifndef _SIZET_
+ #ifndef __size_t
++#ifndef __DEFINED_size_t /* musl */
+ #define __size_t__	/* BeOS */
+ #define __SIZE_T__	/* Cray Unicos/Mk */
+ #define _SIZE_T
+@@ -197,6 +198,7 @@ typedef __PTRDIFF_TYPE__ ptrdiff_t;
+ #define ___int_size_t_h
+ #define _GCC_SIZE_T
+ #define _SIZET_
++#define __DEFINED_size_t /* musl */
+ #if (defined (__FreeBSD__) && (__FreeBSD__ >= 5)) \
+   || defined(__FreeBSD_kernel__)
+ /* __size_t is a typedef on FreeBSD 5, must not trash it. */
+@@ -214,6 +216,7 @@ typedef __SIZE_TYPE__ size_t;
+ typedef long ssize_t;
+ #endif /* __BEOS__ */
+ #endif /* !(defined (__GNUG__) && defined (size_t)) */
++#endif /* __DEFINED_size_t */
+ #endif /* __size_t */
+ #endif /* _SIZET_ */
+ #endif /* _GCC_SIZE_T */
+diff --git a/libgcc/config/rs6000/linux-unwind.h b/libgcc/config/rs6000/linux-unwind.h
+index c5b006e..0eadc7a 100644
+--- a/libgcc/config/rs6000/linux-unwind.h
++++ b/libgcc/config/rs6000/linux-unwind.h
+@@ -282,6 +282,7 @@ ppc_fallback_frame_state (struct _Unwind_Context *context,
+ 
+   return _URC_NO_REASON;
+ }
++#endif
+ 
+ #define MD_FROB_UPDATE_CONTEXT frob_update_context
+ 
+diff --git a/libgomp/config/posix/time.c b/libgomp/config/posix/time.c
+index 6000aa3..be926df 100644
+--- a/libgomp/config/posix/time.c
++++ b/libgomp/config/posix/time.c
+@@ -28,6 +28,8 @@
+    The following implementation uses the most simple POSIX routines.
+    If present, POSIX 4 clocks should be used instead.  */
+ 
++#define _POSIX_C_SOURCE 199309L /* for clocks */
++
+ #include "libgomp.h"
+ #include <unistd.h>
+ #if TIME_WITH_SYS_TIME
+diff --git a/libitm/config/arm/hwcap.cc b/libitm/config/arm/hwcap.cc
+index 11ef0f6..07a9e41 100644
+--- a/libitm/config/arm/hwcap.cc
++++ b/libitm/config/arm/hwcap.cc
+@@ -40,7 +40,11 @@ int GTM_hwcap HIDDEN = 0
+ 
+ #ifdef __linux__
+ #include <unistd.h>
++#ifdef __GLIBC__
+ #include <sys/fcntl.h>
++#else
++#include <fcntl.h>
++#endif
+ #include <elf.h>
+ 
+ static void __attribute__((constructor))
+diff --git a/libitm/config/linux/x86/tls.h b/libitm/config/linux/x86/tls.h
+index 760e6e9..0407883 100644
+--- a/libitm/config/linux/x86/tls.h
++++ b/libitm/config/linux/x86/tls.h
+@@ -25,16 +25,19 @@
+ #ifndef LIBITM_X86_TLS_H
+ #define LIBITM_X86_TLS_H 1
+ 
+-#if defined(__GLIBC_PREREQ) && __GLIBC_PREREQ(2, 10)
++#if defined(__GLIBC_PREREQ)
++#if __GLIBC_PREREQ(2, 10)
+ /* Use slots in the TCB head rather than __thread lookups.
+    GLIBC has reserved words 10 through 13 for TM.  */
+ #define HAVE_ARCH_GTM_THREAD 1
+ #define HAVE_ARCH_GTM_THREAD_DISP 1
+ #endif
++#endif
+ 
+ #include "config/generic/tls.h"
+ 
+-#if defined(__GLIBC_PREREQ) && __GLIBC_PREREQ(2, 10)
++#if defined(__GLIBC_PREREQ)
++#if __GLIBC_PREREQ(2, 10)
+ namespace GTM HIDDEN {
+ 
+ #ifdef __x86_64__
+@@ -101,5 +104,6 @@ static inline void set_abi_disp(struct abi_dispatch *x)
+ 
+ } // namespace GTM
+ #endif /* >= GLIBC 2.10 */
++#endif
+ 
+ #endif // LIBITM_X86_TLS_H
+diff --git a/libstdc++-v3/configure.host b/libstdc++-v3/configure.host
+index c168454..0e6aee5 100644
+--- a/libstdc++-v3/configure.host
++++ b/libstdc++-v3/configure.host
+@@ -264,6 +264,13 @@ case "${host_os}" in
+     os_include_dir="os/bsd/freebsd"
+     ;;
+   gnu* | linux* | kfreebsd*-gnu | knetbsd*-gnu)
++    # check for musl by target
++    case "${host_os}" in
++      *-musl*)
++        os_include_dir="os/generic"
++        ;;
++      *)
++
+     if [ "$uclibc" = "yes" ]; then
+       os_include_dir="os/uclibc"
+     elif [ "$bionic" = "yes" ]; then
+@@ -272,6 +279,9 @@ case "${host_os}" in
+       os_include_dir="os/gnu-linux"
+     fi
+     ;;
++
++    esac
++    ;;
+   hpux*)
+     os_include_dir="os/hpux"
+     ;;
diff --git a/patches/musl/1.0.3/001-fix_linker_regression.patch b/patches/musl/1.0.3/001-fix_linker_regression.patch
new file mode 100644
index 0000000..801cb00
--- /dev/null
+++ b/patches/musl/1.0.3/001-fix_linker_regression.patch
@@ -0,0 +1,64 @@ 
+From 9a4ad02214a859e93d2c980e4535378a6a74e3a6 Mon Sep 17 00:00:00 2001
+From: Rich Felker <dalias@aerifal.cx>
+Date: Mon, 30 Jun 2014 01:52:54 +0000
+Subject: fix regression in dynamic linker error reporting
+
+due to a mistake when refactoring the error printing for the dynamic
+linker (commit 7c73cacd09a51a87484db5689864743e4984a84d), all messages
+were suppressed and replaced by blank lines.
+---
+diff --git a/src/ldso/dynlink.c b/src/ldso/dynlink.c
+index bc4f2f6..a08300d 100644
+--- a/src/ldso/dynlink.c
++++ b/src/ldso/dynlink.c
+@@ -290,8 +290,7 @@ static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stri
+ 		if (!astype) continue;
+ 		type = remap_rel(astype);
+ 		if (!type) {
+-			error(errbuf, sizeof errbuf,
+-				"Error relocating %s: unsupported relocation type %d",
++			error("Error relocating %s: unsupported relocation type %d",
+ 				dso->name, astype);
+ 			continue;
+ 		}
+@@ -304,8 +303,7 @@ static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stri
+ 			def = find_sym(ctx, name, type==REL_PLT);
+ 			if (!def.sym && (sym->st_shndx != SHN_UNDEF
+ 			    || sym->st_info>>4 != STB_WEAK)) {
+-				error(errbuf, sizeof errbuf,
+-					"Error relocating %s: %s: symbol not found",
++				error("Error relocating %s: %s: symbol not found",
+ 					dso->name, name);
+ 				continue;
+ 			}
+@@ -366,7 +364,7 @@ static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stri
+ 			if (stride<3) addend = reloc_addr[1];
+ 			if (runtime && def.dso->tls_id >= static_tls_cnt) {
+ 				struct td_index *new = malloc(sizeof *new);
+-				if (!new) error(errbuf, sizeof errbuf,
++				if (!new) error(
+ 					"Error relocating %s: cannot allocate TLSDESC for %s",
+ 					dso->name, sym ? name : "(local)" );
+ 				new->next = dso->td_index;
+@@ -839,8 +837,7 @@ static void load_deps(struct dso *p)
+ 			if (p->dynv[i] != DT_NEEDED) continue;
+ 			dep = load_library(p->strings + p->dynv[i+1], p);
+ 			if (!dep) {
+-				error(errbuf, sizeof errbuf,
+-					"Error loading shared library %s: %m (needed by %s)",
++				error("Error loading shared library %s: %m (needed by %s)",
+ 					p->strings + p->dynv[i+1], p->name);
+ 				continue;
+ 			}
+@@ -890,8 +887,7 @@ static void reloc_all(struct dso *p)
+ 
+ 		if (p->relro_start != p->relro_end &&
+ 		    mprotect(p->base+p->relro_start, p->relro_end-p->relro_start, PROT_READ) < 0) {
+-			error(errbuf, sizeof errbuf,
+-				"Error relocating %s: RELRO protection failed: %m",
++			error("Error relocating %s: RELRO protection failed: %m",
+ 				p->name);
+ 		}
+ 
+--
+cgit v0.9.0.3-65-g4555
diff --git a/patches/musl/1.0.3/002-fix_mips_linker_regression.patch b/patches/musl/1.0.3/002-fix_mips_linker_regression.patch
new file mode 100644
index 0000000..4891b4f
--- /dev/null
+++ b/patches/musl/1.0.3/002-fix_mips_linker_regression.patch
@@ -0,0 +1,88 @@ 
+From 2d8cc92a7cb4a3256ed07d86843388ffd8a882b1 Mon Sep 17 00:00:00 2001
+From: Rich Felker <dalias@aerifal.cx>
+Date: Mon, 30 Jun 2014 05:18:14 +0000
+Subject: fix regression in mips dynamic linker
+
+this issue caused the address of functions in shared libraries to
+resolve to their PLT thunks in the main program rather than their
+correct addresses. it was observed causing crashes, though the
+mechanism of the crash was not thoroughly investigated. since the
+issue is very subtle, it calls for some explanation:
+
+on all well-behaved archs, GOT entries that belong to the PLT use a
+special relocation type, typically called JMP_SLOT, so that the
+dynamic linker can avoid having the jump destinations for the PLT
+resolve to PLT thunks themselves (they also provide a definition for
+the symbol, which must be used whenever the address of the function is
+taken so that all DSOs see the same address).
+
+however, the traditional mips PIC ABI lacked such a JMP_SLOT
+relocation type, presumably because, due to the way PIC works, the
+address of the PLT thunk was never needed and could always be ignored.
+
+prior to commit adf94c19666e687a728bbf398f9a88ea4ea19996, the mips
+version of reloc.h contained a hack that caused all symbol lookups to
+be treated like JMP_SLOT, inhibiting undefined symbols from ever being
+used to resolve symbolic relocations. this hack goes all the way back
+to commit babf820180368f00742ec65b2050a82380d7c542, when the mips
+dynamic linker was first made usable.
+
+during the recent refactoring to eliminate arch-specific relocation
+processing (commit adf94c19666e687a728bbf398f9a88ea4ea19996), this
+hack was overlooked and no equivalent functionality was provided in
+the new code.
+
+fixing the problem is not as simple as adding back an equivalent hack,
+since there is now also a "non-PIC ABI" that can be used for the main
+executable, which actually does use a PLT. the closest thing to
+official documentation I could find for this ABI is nonpic.txt,
+attached to Message-ID: 20080701202236.GA1534@caradoc.them.org, which
+can be found in the gcc mailing list archives and elsewhere. per this
+document, undefined symbols corresponding to PLT thunks have the
+STO_MIPS_PLT bit set in the symbol's st_other field. thus, I have
+added an arch-specific rule for mips, applied at the find_sym level
+rather than the relocation level, to reject undefined symbols with the
+STO_MIPS_PLT bit clear.
+
+the previous hack of treating all mips relocations as JMP_SLOT-like,
+rather than rejecting the unwanted symbols in find_sym, probably also
+caused dlsym to wrongly return PLT thunks in place of the correct
+address of a function under at least some conditions. this should now
+be fixed, at least for global-scope symbol lookups.
+---
+diff --git a/arch/mips/reloc.h b/arch/mips/reloc.h
+index 91fa097..4b81d32 100644
+--- a/arch/mips/reloc.h
++++ b/arch/mips/reloc.h
+@@ -86,3 +86,4 @@ static void do_arch_relocs(struct dso *this, struct dso *head)
+ 
+ #define NEED_ARCH_RELOCS 1
+ #define DYNAMIC_IS_RO 1
++#define ARCH_SYM_REJECT_UND(s) (!((s)->st_other & STO_MIPS_PLT))
+diff --git a/src/ldso/dynlink.c b/src/ldso/dynlink.c
+index a08300d..55124ff 100644
+--- a/src/ldso/dynlink.c
++++ b/src/ldso/dynlink.c
+@@ -233,6 +233,10 @@ static Sym *gnu_lookup(const char *s, uint32_t h1, struct dso *dso)
+ #define OK_TYPES (1<<STT_NOTYPE | 1<<STT_OBJECT | 1<<STT_FUNC | 1<<STT_COMMON | 1<<STT_TLS)
+ #define OK_BINDS (1<<STB_GLOBAL | 1<<STB_WEAK | 1<<STB_GNU_UNIQUE)
+ 
++#ifndef ARCH_SYM_REJECT_UND
++#define ARCH_SYM_REJECT_UND(s) 0
++#endif
++
+ static struct symdef find_sym(struct dso *dso, const char *s, int need_def)
+ {
+ 	uint32_t h = 0, gh = 0;
+@@ -249,7 +253,8 @@ static struct symdef find_sym(struct dso *dso, const char *s, int need_def)
+ 		}
+ 		if (!sym) continue;
+ 		if (!sym->st_shndx)
+-			if (need_def || (sym->st_info&0xf) == STT_TLS)
++			if (need_def || (sym->st_info&0xf) == STT_TLS
++			    || ARCH_SYM_REJECT_UND(sym))
+ 				continue;
+ 		if (!sym->st_value)
+ 			if ((sym->st_info&0xf) != STT_TLS)
+--
+cgit v0.9.0.3-65-g4555
diff --git a/patches/musl/1.1.3/001-fix_linker_regression.patch b/patches/musl/1.1.3/001-fix_linker_regression.patch
new file mode 100644
index 0000000..801cb00
--- /dev/null
+++ b/patches/musl/1.1.3/001-fix_linker_regression.patch
@@ -0,0 +1,64 @@ 
+From 9a4ad02214a859e93d2c980e4535378a6a74e3a6 Mon Sep 17 00:00:00 2001
+From: Rich Felker <dalias@aerifal.cx>
+Date: Mon, 30 Jun 2014 01:52:54 +0000
+Subject: fix regression in dynamic linker error reporting
+
+due to a mistake when refactoring the error printing for the dynamic
+linker (commit 7c73cacd09a51a87484db5689864743e4984a84d), all messages
+were suppressed and replaced by blank lines.
+---
+diff --git a/src/ldso/dynlink.c b/src/ldso/dynlink.c
+index bc4f2f6..a08300d 100644
+--- a/src/ldso/dynlink.c
++++ b/src/ldso/dynlink.c
+@@ -290,8 +290,7 @@ static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stri
+ 		if (!astype) continue;
+ 		type = remap_rel(astype);
+ 		if (!type) {
+-			error(errbuf, sizeof errbuf,
+-				"Error relocating %s: unsupported relocation type %d",
++			error("Error relocating %s: unsupported relocation type %d",
+ 				dso->name, astype);
+ 			continue;
+ 		}
+@@ -304,8 +303,7 @@ static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stri
+ 			def = find_sym(ctx, name, type==REL_PLT);
+ 			if (!def.sym && (sym->st_shndx != SHN_UNDEF
+ 			    || sym->st_info>>4 != STB_WEAK)) {
+-				error(errbuf, sizeof errbuf,
+-					"Error relocating %s: %s: symbol not found",
++				error("Error relocating %s: %s: symbol not found",
+ 					dso->name, name);
+ 				continue;
+ 			}
+@@ -366,7 +364,7 @@ static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stri
+ 			if (stride<3) addend = reloc_addr[1];
+ 			if (runtime && def.dso->tls_id >= static_tls_cnt) {
+ 				struct td_index *new = malloc(sizeof *new);
+-				if (!new) error(errbuf, sizeof errbuf,
++				if (!new) error(
+ 					"Error relocating %s: cannot allocate TLSDESC for %s",
+ 					dso->name, sym ? name : "(local)" );
+ 				new->next = dso->td_index;
+@@ -839,8 +837,7 @@ static void load_deps(struct dso *p)
+ 			if (p->dynv[i] != DT_NEEDED) continue;
+ 			dep = load_library(p->strings + p->dynv[i+1], p);
+ 			if (!dep) {
+-				error(errbuf, sizeof errbuf,
+-					"Error loading shared library %s: %m (needed by %s)",
++				error("Error loading shared library %s: %m (needed by %s)",
+ 					p->strings + p->dynv[i+1], p->name);
+ 				continue;
+ 			}
+@@ -890,8 +887,7 @@ static void reloc_all(struct dso *p)
+ 
+ 		if (p->relro_start != p->relro_end &&
+ 		    mprotect(p->base+p->relro_start, p->relro_end-p->relro_start, PROT_READ) < 0) {
+-			error(errbuf, sizeof errbuf,
+-				"Error relocating %s: RELRO protection failed: %m",
++			error("Error relocating %s: RELRO protection failed: %m",
+ 				p->name);
+ 		}
+ 
+--
+cgit v0.9.0.3-65-g4555
diff --git a/patches/musl/1.1.3/002-fix_mips_linker_regression.patch b/patches/musl/1.1.3/002-fix_mips_linker_regression.patch
new file mode 100644
index 0000000..4891b4f
--- /dev/null
+++ b/patches/musl/1.1.3/002-fix_mips_linker_regression.patch
@@ -0,0 +1,88 @@ 
+From 2d8cc92a7cb4a3256ed07d86843388ffd8a882b1 Mon Sep 17 00:00:00 2001
+From: Rich Felker <dalias@aerifal.cx>
+Date: Mon, 30 Jun 2014 05:18:14 +0000
+Subject: fix regression in mips dynamic linker
+
+this issue caused the address of functions in shared libraries to
+resolve to their PLT thunks in the main program rather than their
+correct addresses. it was observed causing crashes, though the
+mechanism of the crash was not thoroughly investigated. since the
+issue is very subtle, it calls for some explanation:
+
+on all well-behaved archs, GOT entries that belong to the PLT use a
+special relocation type, typically called JMP_SLOT, so that the
+dynamic linker can avoid having the jump destinations for the PLT
+resolve to PLT thunks themselves (they also provide a definition for
+the symbol, which must be used whenever the address of the function is
+taken so that all DSOs see the same address).
+
+however, the traditional mips PIC ABI lacked such a JMP_SLOT
+relocation type, presumably because, due to the way PIC works, the
+address of the PLT thunk was never needed and could always be ignored.
+
+prior to commit adf94c19666e687a728bbf398f9a88ea4ea19996, the mips
+version of reloc.h contained a hack that caused all symbol lookups to
+be treated like JMP_SLOT, inhibiting undefined symbols from ever being
+used to resolve symbolic relocations. this hack goes all the way back
+to commit babf820180368f00742ec65b2050a82380d7c542, when the mips
+dynamic linker was first made usable.
+
+during the recent refactoring to eliminate arch-specific relocation
+processing (commit adf94c19666e687a728bbf398f9a88ea4ea19996), this
+hack was overlooked and no equivalent functionality was provided in
+the new code.
+
+fixing the problem is not as simple as adding back an equivalent hack,
+since there is now also a "non-PIC ABI" that can be used for the main
+executable, which actually does use a PLT. the closest thing to
+official documentation I could find for this ABI is nonpic.txt,
+attached to Message-ID: 20080701202236.GA1534@caradoc.them.org, which
+can be found in the gcc mailing list archives and elsewhere. per this
+document, undefined symbols corresponding to PLT thunks have the
+STO_MIPS_PLT bit set in the symbol's st_other field. thus, I have
+added an arch-specific rule for mips, applied at the find_sym level
+rather than the relocation level, to reject undefined symbols with the
+STO_MIPS_PLT bit clear.
+
+the previous hack of treating all mips relocations as JMP_SLOT-like,
+rather than rejecting the unwanted symbols in find_sym, probably also
+caused dlsym to wrongly return PLT thunks in place of the correct
+address of a function under at least some conditions. this should now
+be fixed, at least for global-scope symbol lookups.
+---
+diff --git a/arch/mips/reloc.h b/arch/mips/reloc.h
+index 91fa097..4b81d32 100644
+--- a/arch/mips/reloc.h
++++ b/arch/mips/reloc.h
+@@ -86,3 +86,4 @@ static void do_arch_relocs(struct dso *this, struct dso *head)
+ 
+ #define NEED_ARCH_RELOCS 1
+ #define DYNAMIC_IS_RO 1
++#define ARCH_SYM_REJECT_UND(s) (!((s)->st_other & STO_MIPS_PLT))
+diff --git a/src/ldso/dynlink.c b/src/ldso/dynlink.c
+index a08300d..55124ff 100644
+--- a/src/ldso/dynlink.c
++++ b/src/ldso/dynlink.c
+@@ -233,6 +233,10 @@ static Sym *gnu_lookup(const char *s, uint32_t h1, struct dso *dso)
+ #define OK_TYPES (1<<STT_NOTYPE | 1<<STT_OBJECT | 1<<STT_FUNC | 1<<STT_COMMON | 1<<STT_TLS)
+ #define OK_BINDS (1<<STB_GLOBAL | 1<<STB_WEAK | 1<<STB_GNU_UNIQUE)
+ 
++#ifndef ARCH_SYM_REJECT_UND
++#define ARCH_SYM_REJECT_UND(s) 0
++#endif
++
+ static struct symdef find_sym(struct dso *dso, const char *s, int need_def)
+ {
+ 	uint32_t h = 0, gh = 0;
+@@ -249,7 +253,8 @@ static struct symdef find_sym(struct dso *dso, const char *s, int need_def)
+ 		}
+ 		if (!sym) continue;
+ 		if (!sym->st_shndx)
+-			if (need_def || (sym->st_info&0xf) == STT_TLS)
++			if (need_def || (sym->st_info&0xf) == STT_TLS
++			    || ARCH_SYM_REJECT_UND(sym))
+ 				continue;
+ 		if (!sym->st_value)
+ 			if ((sym->st_info&0xf) != STT_TLS)
+--
+cgit v0.9.0.3-65-g4555
diff --git a/samples/arm-unknown-linux-muslgnueabi/crosstool.config b/samples/arm-unknown-linux-muslgnueabi/crosstool.config
new file mode 100644
index 0000000..8b96eb1
--- /dev/null
+++ b/samples/arm-unknown-linux-muslgnueabi/crosstool.config
@@ -0,0 +1,10 @@ 
+CT_EXPERIMENTAL=y
+CT_ARCH_ARCH="armv5te"
+CT_ARCH_FLOAT_SW=y
+CT_ARCH_arm=y
+CT_KERNEL_linux=y
+CT_BINUTILS_FOR_TARGET=y
+CT_LIBC_musl=y
+CT_CC_V_4_9_0=y
+CT_CC_LANG_CXX=y
+# CT_CC_GCC_SJLJ_EXCEPTIONS is not set
diff --git a/samples/arm-unknown-linux-muslgnueabi/reported.by b/samples/arm-unknown-linux-muslgnueabi/reported.by
new file mode 100644
index 0000000..7ba54a4
--- /dev/null
+++ b/samples/arm-unknown-linux-muslgnueabi/reported.by
@@ -0,0 +1,3 @@ 
+reporter_name="Bryan Hundven"
+reporter_url="http://bhundven.github.io"
+reporter_comment=""
diff --git a/scripts/build/arch/arm.sh b/scripts/build/arch/arm.sh
index 430bdde..ba87e0c 100644
--- a/scripts/build/arch/arm.sh
+++ b/scripts/build/arch/arm.sh
@@ -17,6 +17,7 @@  CT_DoArchTupleValues() {
     case "${CT_LIBC},${CT_ARCH_ARM_EABI}" in
         *glibc,y)   CT_TARGET_SYS=gnueabi;;
         uClibc,y)   CT_TARGET_SYS=uclibcgnueabi;;
+        musl,y)     CT_TARGET_SYS=muslgnueabi;;
         *,y)        CT_TARGET_SYS=eabi;;
     esac
 
diff --git a/scripts/build/libc/musl.sh b/scripts/build/libc/musl.sh
new file mode 100644
index 0000000..af2dba7
--- /dev/null
+++ b/scripts/build/libc/musl.sh
@@ -0,0 +1,111 @@ 
+# This file adds functions to build the musl C library
+# Copyright 2013 Timo Teräs
+# Licensed under the GPL v2. See COPYING in the root of this package
+
+do_libc_get() {
+    local libc_src
+
+    libc_src="http://www.musl-libc.org/releases"
+
+    if [ "${CT_LIBC_MUSL_CUSTOM}" = "y" ]; then
+        CT_GetCustom "musl" "${CT_LIBC_VERSION}"      \
+                     "${CT_LIBC_MUSL_CUSTOM_LOCATION}"
+    else # ! custom location
+        CT_GetFile "musl-${CT_LIBC_VERSION}" "${libc_src}"
+    fi # ! custom location
+}
+
+do_libc_extract() {
+    # If using custom directory location, nothing to do.
+    if [ "${CT_LIBC_MUSL_CUSTOM}" = "y" ]; then
+        # Abort if the custom directory is not found.
+        if ! [ -d "${CT_SRC_DIR}/musl-${CT_LIBC_VERSION}" ]; then
+            CT_Abort "Directory not found: ${CT_SRC_DIR}/musl-${CT_LIBC_VERSION}"
+        fi
+
+        return 0
+    fi
+
+    CT_Extract "musl-${CT_LIBC_VERSION}"
+    CT_Patch "musl" "${CT_LIBC_VERSION}"
+}
+
+do_libc_check_config() {
+    :
+}
+
+do_libc_configure() {
+    CT_DoLog EXTRA "Configuring C library"
+    local -a extra_cflags
+
+    # From buildroot:
+    # gcc constant folding bug with weak aliases workaround
+    # See http://www.openwall.com/lists/musl/2014/05/15/1
+    if [ "${CT_CC_GCC_4_9_or_later}" = "y" ]; then
+        extra_cflags+=("-fno-toplevel-reorder")
+    fi
+
+    # NOTE: musl handles the build/host/target a little bit differently
+    # then one would expect:
+    #   build   : not used
+    #   host    : the machine building musl
+    #   target  : the machine musl runs on
+    CT_DoExecLog CFG                \
+    CFLAGS="${extra_cflags[@]}"     \
+    CROSS_COMPILE="${CT_TARGET}-"   \
+    ./configure                     \
+        --host="${CT_BUILD}"        \
+        --target="${CT_TARGET}"     \
+        --prefix="/usr"             \
+        --disable-gcc-wrapper
+}
+
+do_libc_start_files() {
+    local ARCH
+
+    CT_DoStep INFO "Installing C library headers"
+
+    # Simply copy files until musl has the ability to build out-of-tree
+    CT_DoLog EXTRA "Copying sources to build directory"
+    CT_DoExecLog ALL cp -av "${CT_SRC_DIR}/musl-${CT_LIBC_VERSION}" \
+                            "${CT_BUILD_DIR}/build-libc-headers"
+    cd "${CT_BUILD_DIR}/build-libc-headers"
+
+    # musl can be installed without gcc if arch is known
+    case "${CT_TARGET}" in
+        arm*) ARCH=arm ;;
+        i?86*) ARCH=i386 ;;
+        x86_64*) ARCH=x86_64 ;;
+        mips-*|mipsel-*) ARCH=mips ;;
+        microblaze-*) ARCH=microblaze ;;
+        powerpc-*) ARCH=powerpc ;;
+        sh-*|sh[34]-*) ARCH=sh ;;
+        x32-*) ARCH=x32 ;;
+        *) return 1 ;;
+    esac
+
+    CT_DoLog EXTRA "Installing headers"
+    CT_DoExecLog ALL make ARCH="${ARCH}" install-headers DESTDIR="${CT_SYSROOT_DIR}/"
+
+    CT_EndStep
+}
+
+do_libc() {
+    CT_DoStep INFO "Installing C library"
+
+    # Simply copy files until musl has the ability to build out-of-tree
+    CT_DoLog EXTRA "Copying sources to build directory"
+    CT_DoExecLog ALL cp -av "${CT_SRC_DIR}/musl-${CT_LIBC_VERSION}" \
+                            "${CT_BUILD_DIR}/build-libc"
+    cd "${CT_BUILD_DIR}/build-libc"
+
+    do_libc_configure
+
+    CT_DoLog EXTRA "Building C library"
+    CT_DoExecLog ALL make ${JOBSFLAGS}
+
+    CT_DoLog EXTRA "Installing C library"
+    CT_DoExecLog ALL make install DESTDIR="${CT_SYSROOT_DIR}/"
+
+    CT_EndStep
+}
diff --git a/scripts/functions b/scripts/functions
index b15601a..2cad8f1 100644
--- a/scripts/functions
+++ b/scripts/functions
@@ -1174,6 +1174,7 @@  CT_DoBuildTargetTuple() {
     case "${CT_LIBC}" in
         *glibc) CT_TARGET_SYS=gnu;;
         uClibc) CT_TARGET_SYS=uclibc;;
+        musl)   CT_TARGET_SYS=musl;;
         *)      CT_TARGET_SYS=elf;;
     esac