From 52260ccebb73465eacbc292bdc343bdd75e14801 Mon Sep 17 00:00:00 2001 From: Bryan Hundven Date: Thu, 31 Jul 2014 19:01:46 -0700 Subject: libc/musl: add musl-libc support This patch adds initial support for musl-libc. Musl-libc versions currently supported: * 1.0.3 (Stable) * 1.1.3 (Previous Mainline) * 1.1.4 (Mainline) Futher improvements are needed. * gcc-4.9.x has issues (Might be fixed in musl-1.1.4). * Multilib support is needed. * Checks to make sure paths are correct. * Move to 2-step gcc build. 3-step build is not necessary. Signed-off-by: Bryan Hundven [yann.morin.1998@free.fr: removed the gcc musl patch, to be added later; removed dead code do_get_arch()] Signed-off-by: "Yann E. MORIN" diff --git a/config/libc/musl.in b/config/libc/musl.in new file mode 100644 index 0000000..7bab480 --- /dev/null +++ b/config/libc/musl.in @@ -0,0 +1,49 @@ +# musl options + +## depends on ! WINDOWS && ! BARE_METAL +## +## select LIBC_SUPPORT_THREADS_NATIVE +## 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. + +config THREADS + default "musl" + +choice + bool + prompt "musl version" +# Don't remove next line +# CT_INSERT_VERSION_BELOW + +config LIBC_MUSL_V_1_1_4 + bool + prompt "1.1.4 (Mainline)" + depends on EXPERIMENTAL + +config LIBC_MUSL_V_1_1_3 + bool + prompt "1.1.3" + depends on EXPERIMENTAL + +config LIBC_MUSL_V_1_0_3 + bool + prompt "1.0.3 (Stable)" + +config LIBC_MUSL_V_CUSTOM + bool + prompt "Custom musl" + depends on EXPERIMENTAL + +endchoice + +config LIBC_VERSION + string +# Don't remove next line +# CT_INSERT_VERSION_STRING_BELOW + default "1.1.4" if LIBC_MUSL_V_1_1_4 + 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/patches/musl/1.0.3/0001-fix_linker_regression.patch b/patches/musl/1.0.3/0001-fix_linker_regression.patch new file mode 100644 index 0000000..801cb00 --- /dev/null +++ b/patches/musl/1.0.3/0001-fix_linker_regression.patch @@ -0,0 +1,64 @@ +From 9a4ad02214a859e93d2c980e4535378a6a74e3a6 Mon Sep 17 00:00:00 2001 +From: Rich Felker +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/0002-fix_mips_linker_regression.patch b/patches/musl/1.0.3/0002-fix_mips_linker_regression.patch new file mode 100644 index 0000000..4891b4f --- /dev/null +++ b/patches/musl/1.0.3/0002-fix_mips_linker_regression.patch @@ -0,0 +1,88 @@ +From 2d8cc92a7cb4a3256ed07d86843388ffd8a882b1 Mon Sep 17 00:00:00 2001 +From: Rich Felker +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<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/0001-fix_linker_regression.patch b/patches/musl/1.1.3/0001-fix_linker_regression.patch new file mode 100644 index 0000000..801cb00 --- /dev/null +++ b/patches/musl/1.1.3/0001-fix_linker_regression.patch @@ -0,0 +1,64 @@ +From 9a4ad02214a859e93d2c980e4535378a6a74e3a6 Mon Sep 17 00:00:00 2001 +From: Rich Felker +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/0002-fix_mips_linker_regression.patch b/patches/musl/1.1.3/0002-fix_mips_linker_regression.patch new file mode 100644 index 0000000..4891b4f --- /dev/null +++ b/patches/musl/1.1.3/0002-fix_mips_linker_regression.patch @@ -0,0 +1,88 @@ +From 2d8cc92a7cb4a3256ed07d86843388ffd8a882b1 Mon Sep 17 00:00:00 2001 +From: Rich Felker +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<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/scripts/build/arch/arm.sh b/scripts/build/arch/arm.sh index 430bdde..5f6ce2f 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=musleabi;; *,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..7172cf2 --- /dev/null +++ b/scripts/build/libc/musl.sh @@ -0,0 +1,103 @@ +# 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_TARGET}" \ + --target="${CT_TARGET}" \ + --prefix="/usr" \ + --disable-gcc-wrapper +} + +do_libc_start_files() { + 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" + + do_libc_configure + + CT_DoLog EXTRA "Installing headers" + CT_DoExecLog ALL make DESTDIR="${CT_SYSROOT_DIR}" install-headers + + CT_DoExecLog ALL make DESTDIR="${CT_SYSROOT_DIR}" \ + crt/crt1.o crt/crti.o crt/crtn.o + CT_DoExecLog ALL cp -av crt/crt*.o "${CT_SYSROOT_DIR}/usr/lib" + CT_DoExecLog ALL ${CT_TARGET}-gcc -nostdlib \ + -nostartfiles -shared -x c /dev/null -o "${CT_SYSROOT_DIR}/usr/lib/libc.so" + 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 DESTDIR="${CT_SYSROOT_DIR}" install + + CT_EndStep +} diff --git a/scripts/functions b/scripts/functions index 2e4d4fa..eae3b95 100644 --- a/scripts/functions +++ b/scripts/functions @@ -1182,6 +1182,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 -- cgit v0.10.2-6-g49f6