aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2013-04-23 18:50:47 -0700
committerAlon Zakai <alonzakai@gmail.com>2013-04-23 18:50:47 -0700
commitf6fa219f1275b8a98c768d1f8593613ed85d5cfe (patch)
tree89b4848d4bd5a1fbdf9100f346c1583c657b341d
parent430dcb4c1533a7c2e9486a2bcbb4e0bda3025c0c (diff)
parent029c076151fb9cb47c54af53c52870ef0b620c5c (diff)
Merge pull request #1063 from waywardmonkeys/musl-libc1.3.7
Add wchar and multibyte libc functions
-rwxr-xr-xemcc139
-rw-r--r--src/library.js44
-rw-r--r--system/lib/libc.symbols162
-rw-r--r--system/lib/libc/musl/memcpy.c29
-rw-r--r--system/lib/libc/musl/readme.txt1
-rw-r--r--system/lib/libc/musl/src/internal/libc.c22
-rw-r--r--system/lib/libc/musl/src/internal/libc.h71
-rw-r--r--system/lib/libc/musl/src/multibyte/btowc.c7
-rw-r--r--system/lib/libc/musl/src/multibyte/internal.c38
-rw-r--r--system/lib/libc/musl/src/multibyte/internal.h22
-rw-r--r--system/lib/libc/musl/src/multibyte/mblen.c17
-rw-r--r--system/lib/libc/musl/src/multibyte/mbrlen.c18
-rw-r--r--system/lib/libc/musl/src/multibyte/mbrtowc.c57
-rw-r--r--system/lib/libc/musl/src/multibyte/mbsinit.c17
-rw-r--r--system/lib/libc/musl/src/multibyte/mbsnrtowcs.c65
-rw-r--r--system/lib/libc/musl/src/multibyte/mbsrtowcs.c100
-rw-r--r--system/lib/libc/musl/src/multibyte/mbstowcs.c7
-rw-r--r--system/lib/libc/musl/src/multibyte/mbtowc.c53
-rw-r--r--system/lib/libc/musl/src/multibyte/wcrtomb.c38
-rw-r--r--system/lib/libc/musl/src/multibyte/wcsnrtombs.c52
-rw-r--r--system/lib/libc/musl/src/multibyte/wcsrtombs.c58
-rw-r--r--system/lib/libc/musl/src/multibyte/wcstombs.c7
-rw-r--r--system/lib/libc/musl/src/multibyte/wctob.c8
-rw-r--r--system/lib/libc/musl/src/multibyte/wctomb.c18
-rw-r--r--system/lib/libc/musl/src/string/wcpcpy.c6
-rw-r--r--system/lib/libc/musl/src/string/wcpncpy.c6
-rw-r--r--system/lib/libc/musl/src/string/wcscasecmp.c7
-rw-r--r--system/lib/libc/musl/src/string/wcscasecmp_l.c6
-rw-r--r--system/lib/libc/musl/src/string/wcscat.c7
-rw-r--r--system/lib/libc/musl/src/string/wcschr.c8
-rw-r--r--system/lib/libc/musl/src/string/wcscmp.c7
-rw-r--r--system/lib/libc/musl/src/string/wcscpy.c8
-rw-r--r--system/lib/libc/musl/src/string/wcscspn.c10
-rw-r--r--system/lib/libc/musl/src/string/wcsdup.c11
-rw-r--r--system/lib/libc/musl/src/string/wcslen.c8
-rw-r--r--system/lib/libc/musl/src/string/wcsncasecmp.c9
-rw-r--r--system/lib/libc/musl/src/string/wcsncasecmp_l.c6
-rw-r--r--system/lib/libc/musl/src/string/wcsncat.c10
-rw-r--r--system/lib/libc/musl/src/string/wcsncmp.c7
-rw-r--r--system/lib/libc/musl/src/string/wcsncpy.c9
-rw-r--r--system/lib/libc/musl/src/string/wcsnlen.c8
-rw-r--r--system/lib/libc/musl/src/string/wcspbrk.c7
-rw-r--r--system/lib/libc/musl/src/string/wcsrchr.c8
-rw-r--r--system/lib/libc/musl/src/string/wcsspn.c8
-rw-r--r--system/lib/libc/musl/src/string/wcsstr.c108
-rw-r--r--system/lib/libc/musl/src/string/wcstok.c12
-rw-r--r--system/lib/libc/musl/src/string/wcswcs.c6
-rw-r--r--system/lib/libc/musl/src/string/wmemchr.c8
-rw-r--r--system/lib/libc/musl/src/string/wmemcmp.c8
-rw-r--r--system/lib/libc/musl/src/string/wmemcpy.c9
-rw-r--r--system/lib/libc/musl/src/string/wmemmove.c12
-rw-r--r--system/lib/libc/musl/src/string/wmemset.c9
-rw-r--r--system/lib/libcextra.symbols48
-rwxr-xr-xtests/runner.py16
-rw-r--r--tools/shared.py2
55 files changed, 1252 insertions, 192 deletions
diff --git a/emcc b/emcc
index 5d22129a..fed7e997 100755
--- a/emcc
+++ b/emcc
@@ -1108,10 +1108,45 @@ try:
# Note that we assume a single symbol is enough to know if we have/do not have dlmalloc etc. If you
# include just a few symbols but want the rest, this will not work.
+ def read_symbols(path, exclude=None):
+ symbols = map(lambda line: line.strip().split(' ')[1], open(path).readlines())
+ if exclude:
+ symbols = filter(lambda symbol: symbol not in exclude, symbols)
+ return set(symbols)
+
+ # XXX We also need to add libc symbols that use malloc, for example strdup. It's very rare to use just them and not
+ # a normal malloc symbol (like free, after calling strdup), so we haven't hit this yet, but it is possible.
+ libc_symbols = read_symbols(shared.path_from_root('system', 'lib', 'libc.symbols'))
+ libcextra_symbols = read_symbols(shared.path_from_root('system', 'lib', 'libcextra.symbols'))
+ libcxx_symbols = read_symbols(shared.path_from_root('system', 'lib', 'libcxx', 'symbols'), exclude=libc_symbols)
+ libcxxabi_symbols = read_symbols(shared.path_from_root('system', 'lib', 'libcxxabi', 'symbols'), exclude=libc_symbols)
+
+ def build_libc(lib_filename, files):
+ o_s = []
+ prev_cxx = os.environ.get('EMMAKEN_CXX')
+ if prev_cxx: os.environ['EMMAKEN_CXX'] = ''
+ musl_internal_includes = shared.path_from_root('system', 'lib', 'libc', 'musl', 'src', 'internal')
+ for src in files:
+ o = in_temp(os.path.basename(src) + '.o')
+ execute([shared.PYTHON, shared.EMCC, shared.path_from_root('system', 'lib', src), '-o', o, '-I', musl_internal_includes], stdout=stdout, stderr=stderr)
+ o_s.append(o)
+ if prev_cxx: os.environ['EMMAKEN_CXX'] = prev_cxx
+ shared.Building.link(o_s, in_temp(lib_filename))
+ return in_temp(lib_filename)
+
+ def build_libcxx(src_dirname, lib_filename, files):
+ o_s = []
+ for src in files:
+ o = in_temp(src + '.o')
+ srcfile = shared.path_from_root(src_dirname, src)
+ execute([shared.PYTHON, shared.EMXX, srcfile, '-o', o, '-std=c++11'], stdout=stdout, stderr=stderr)
+ o_s.append(o)
+ shared.Building.link(o_s, in_temp(lib_filename))
+ return in_temp(lib_filename)
+
# libc
def create_libc():
if DEBUG: print >> sys.stderr, 'emcc: building libc for cache'
- o_s = []
libc_files = [
'dlmalloc.c',
os.path.join('libcxx', 'new.cpp'),
@@ -1126,17 +1161,7 @@ try:
os.path.join('libc', 'gen', 'vwarnx.c'),
os.path.join('libc', 'stdlib', 'strtod.c'),
];
-
- prev_cxx = os.environ.get('EMMAKEN_CXX')
- if prev_cxx: os.environ['EMMAKEN_CXX'] = ''
- for src in libc_files:
- o = in_temp(os.path.basename(src) + '.o')
- execute([shared.PYTHON, shared.EMCC, shared.path_from_root('system', 'lib', src), '-o', o], stdout=stdout, stderr=stderr)
- o_s.append(o)
- if prev_cxx: os.environ['EMMAKEN_CXX'] = prev_cxx
-
- shared.Building.link(o_s, in_temp('libc.bc'))
- return in_temp('libc.bc')
+ return build_libc('libc.bc', libc_files)
def fix_libc(need):
# libc needs some sign correction. # If we are in mode 0, switch to 2. We will add our lines
@@ -1148,14 +1173,70 @@ try:
shared.Settings.CORRECT_SIGNS_LINES = [shared.path_from_root('src', 'dlmalloc.c') + ':' + str(i+4) for i in [4816, 4191, 4246, 4199, 4205, 4235, 4227]]
# If we are in mode 1, we are correcting everything anyhow. If we are in mode 3, we will be corrected
# so all is well anyhow too.
- # XXX We also need to add libc symbols that use malloc, for example strdup. It's very rare to use just them and not
- # a normal malloc symbol (like free, after calling strdup), so we haven't hit this yet, but it is possible.
- libc_symbols = open(shared.path_from_root('system', 'lib', 'libc.symbols')).read().split('\n')
+
+ # libcextra
+ def create_libcextra():
+ if DEBUG: print >> sys.stderr, 'emcc: building libcextra for cache'
+ musl_files = [
+ ['multibyte', [
+ 'btowc.c',
+ 'mblen.c',
+ 'mbrlen.c',
+ 'mbrtowc.c',
+ 'mbsinit.c',
+ 'mbsnrtowcs.c',
+ 'mbsrtowcs.c',
+ 'mbstowcs.c',
+ 'mbtowc.c',
+ 'wcrtomb.c',
+ 'wcsnrtombs.c',
+ 'wcsrtombs.c',
+ 'wcstombs.c',
+ 'wctob.c',
+ 'wctomb.c',
+ ]],
+ ['string', [
+ 'wcpcpy.c',
+ 'wcpncpy.c',
+ 'wcscasecmp.c',
+ # 'wcscasecmp_l.c', # XXX: alltypes.h issue
+ 'wcscat.c',
+ 'wcschr.c',
+ 'wcscmp.c',
+ 'wcscpy.c',
+ 'wcscspn.c',
+ 'wcsdup.c',
+ 'wcslen.c',
+ 'wcsncasecmp.c',
+ # 'wcsncasecmp_l.c', # XXX: alltypes.h issue
+ 'wcsncat.c',
+ 'wcsncmp.c',
+ 'wcsncpy.c',
+ 'wcsnlen.c',
+ 'wcspbrk.c',
+ 'wcsrchr.c',
+ 'wcsspn.c',
+ 'wcsstr.c',
+ 'wcstok.c',
+ 'wcswcs.c',
+ 'wmemchr.c',
+ 'wmemcmp.c',
+ 'wmemcpy.c',
+ 'wmemmove.c',
+ 'wmemset.c',
+ ]]
+ ]
+ libcextra_files = []
+ for directory, sources in musl_files:
+ libcextra_files += [os.path.join('libc', 'musl', 'src', directory, source) for source in sources]
+ return build_libc('libcextra.bc', libcextra_files)
+
+ def fix_libcextra(need):
+ pass
# libcxx
def create_libcxx():
if DEBUG: print >> sys.stderr, 'emcc: building libcxx for cache'
- os = []
libcxx_files = [
'algorithm.cpp',
'condition_variable.cpp',
@@ -1180,50 +1261,34 @@ try:
'regex.cpp',
'strstream.cpp'
]
- for src in libcxx_files:
- o = in_temp(src + '.o')
- srcfile = shared.path_from_root('system', 'lib', 'libcxx', src)
- execute([shared.PYTHON, shared.EMXX, srcfile, '-o', o, '-std=c++11'], stdout=stdout, stderr=stderr)
- os.append(o)
- shared.Building.link(os, in_temp('libcxx.bc'))
- return in_temp('libcxx.bc')
+ return build_libcxx(os.path.join('system', 'lib', 'libcxx'), 'libcxx.bc', libcxx_files)
+
def fix_libcxx(need):
assert shared.Settings.QUANTUM_SIZE == 4, 'We do not support libc++ with QUANTUM_SIZE == 1'
# libcxx might need corrections, so turn them all on. TODO: check which are actually needed
shared.Settings.CORRECT_SIGNS = shared.Settings.CORRECT_OVERFLOWS = shared.Settings.CORRECT_ROUNDINGS = 1
#print >> sys.stderr, 'emcc: info: using libcxx turns on CORRECT_* options'
- libcxx_symbols = map(lambda line: line.strip().split(' ')[1], open(shared.path_from_root('system', 'lib', 'libcxx', 'symbols')).readlines())
- libcxx_symbols = filter(lambda symbol: symbol not in libc_symbols, libcxx_symbols)
- libcxx_symbols = set(libcxx_symbols)
# libcxxabi - just for dynamic_cast for now
def create_libcxxabi():
if DEBUG: print >> sys.stderr, 'emcc: building libcxxabi for cache'
- os = []
libcxxabi_files = [
'typeinfo.cpp',
'private_typeinfo.cpp'
]
- for src in libcxxabi_files:
- o = in_temp(src + '.o')
- srcfile = shared.path_from_root('system', 'lib', 'libcxxabi', 'src', src)
- execute([shared.PYTHON, shared.EMXX, srcfile, '-o', o, '-std=c++11'], stdout=stdout, stderr=stderr)
- os.append(o)
- shared.Building.link(os, in_temp('libcxxabi.bc'))
- return in_temp('libcxxabi.bc')
+ return build_libcxx(os.path.join('system', 'lib', 'libcxxabi', 'src'), 'libcxxabi.bc', libcxxabi_files)
+
def fix_libcxxabi(need):
assert shared.Settings.QUANTUM_SIZE == 4, 'We do not support libc++abi with QUANTUM_SIZE == 1'
#print >> sys.stderr, 'emcc: info: using libcxxabi, this may need CORRECT_* options'
#shared.Settings.CORRECT_SIGNS = shared.Settings.CORRECT_OVERFLOWS = shared.Settings.CORRECT_ROUNDINGS = 1
- libcxxabi_symbols = map(lambda line: line.strip().split(' ')[1], open(shared.path_from_root('system', 'lib', 'libcxxabi', 'symbols')).readlines())
- libcxxabi_symbols = filter(lambda symbol: symbol not in libc_symbols, libcxxabi_symbols)
- libcxxabi_symbols = set(libcxxabi_symbols)
# If we have libcxx, we must force inclusion of libc, since libcxx uses new internally. Note: this is kind of hacky
# Settings this in the environment will avoid checking dependencies and make building big projects a little faster
force = os.environ.get('EMCC_FORCE_STDLIBS')
has = need = None
for name, create, fix, library_symbols in [('libcxx', create_libcxx, fix_libcxx, libcxx_symbols),
+ ('libcextra', create_libcextra, fix_libcextra, libcextra_symbols),
('libcxxabi', create_libcxxabi, fix_libcxxabi, libcxxabi_symbols),
('libc', create_libc, fix_libc, libc_symbols)]:
if not force:
diff --git a/src/library.js b/src/library.js
index 04878ffc..29c3386f 100644
--- a/src/library.js
+++ b/src/library.js
@@ -4168,32 +4168,6 @@ LibraryManager.library = {
}
},
- mbtowc: function(pwc, pmb, maxx) {
- // XXX doesn't really handle multibyte at all
- if (!pmb) return 0;
- maxx = Math.min({{{ cDefine('_NL_CTYPE_MB_CUR_MAX') }}}, maxx);
- var i;
- for (i = 0; i < maxx; i++) {
- var curr = {{{ makeGetValue('pmb', 0, 'i8') }}};
- if (pwc) {
- {{{ makeSetValue('pwc', '0', 'curr', 'i8') }}};
- {{{ makeSetValue('pwc', '1', '0', 'i8') }}};
- pwc += 2;
- }
- pmb++;
- if (!curr) break;
- }
- return i;
- },
-
- wcrtomb: function(s, wc, ps) {
- // XXX doesn't really handle multibyte at all
- if (s) {
- {{{ makeSetValue('s', '0', 'wc', 'i8') }}};
- }
- return 1;
- },
-
arc4random: 'rand',
// ==========================================================================
@@ -4243,8 +4217,6 @@ LibraryManager.library = {
return ret|0;
},
- wmemcpy: function() { throw 'wmemcpy not implemented' },
-
llvm_memcpy_i32: 'memcpy',
llvm_memcpy_i64: 'memcpy',
llvm_memcpy_p0i8_p0i8_i32: 'memcpy',
@@ -4274,8 +4246,6 @@ LibraryManager.library = {
llvm_memmove_p0i8_p0i8_i32: 'memmove',
llvm_memmove_p0i8_p0i8_i64: 'memmove',
- wmemmove: function() { throw 'wmemmove not implemented' },
-
memset__inline: function(ptr, value, num, align) {
return makeSetValues(ptr, 0, value, 'null', num, align);
},
@@ -4316,8 +4286,6 @@ LibraryManager.library = {
llvm_memset_p0i8_i32: 'memset',
llvm_memset_p0i8_i64: 'memset',
- wmemset: function() { throw 'wmemset not implemented' },
-
strlen__sig: 'ii',
strlen__asm: true,
strlen: function(ptr) {
@@ -4330,18 +4298,6 @@ LibraryManager.library = {
return (curr - ptr)|0;
},
- // TODO: Implement when we have real unicode support.
- mblen: function() {
- return 1;
- },
-
- wcslen: function() { throw 'wcslen not implemented' },
- mbrlen: function() { throw 'mbrlen not implemented' },
- mbsrtowcs: function() { throw 'mbsrtowcs not implemented' },
- wcsnrtombs: function() { throw 'wcsnrtombs not implemented' },
- mbsnrtowcs: function() { throw 'mbsnrtowcs not implemented' },
- mbrtowc: function() { throw 'mbrtowc not implemented' },
-
strspn: function(pstr, pset) {
var str = pstr, set, strcurr, setcurr;
while (1) {
diff --git a/system/lib/libc.symbols b/system/lib/libc.symbols
index 96e995cf..1b126abf 100644
--- a/system/lib/libc.symbols
+++ b/system/lib/libc.symbols
@@ -1,81 +1,81 @@
-_ZNKSt20bad_array_new_length4whatEv
-_ZNKSt9bad_alloc4whatEv
-_ZNSt20bad_array_new_lengthC1Ev
-_ZNSt20bad_array_new_lengthC2Ev
-_ZNSt20bad_array_new_lengthD0Ev
-_ZNSt20bad_array_new_lengthD1Ev
-_ZNSt20bad_array_new_lengthD2Ev
-_ZNSt9bad_allocC1Ev
-_ZNSt9bad_allocC2Ev
-_ZNSt9bad_allocD0Ev
-_ZNSt9bad_allocD1Ev
-_ZNSt9bad_allocD2Ev
-_ZSt15get_new_handlerv
-_ZSt15set_new_handlerPFvvE
-_ZSt17__throw_bad_allocv
-_ZSt7nothrow
-_ZTISt20bad_array_new_length
-_ZTISt9bad_alloc
-_ZTSSt20bad_array_new_length
-_ZTSSt9bad_alloc
-_ZTVSt20bad_array_new_length
-_ZTVSt9bad_alloc
-_ZdaPv
-_ZdaPvRKSt9nothrow_t
-_ZdlPv
-_ZdlPvRKSt9nothrow_t
-_Znaj
-_ZnajRKSt9nothrow_t
-_Znwj
-_ZnwjRKSt9nothrow_t
-_err
-_errx
-_verr
-_verrx
-_vwarn
-_vwarnx
-_warn
-_warnx
-atof
-bulk_free
-calloc
-err
-errx
-free
-getopt
-getopt_long
-getopt_long_only
-independent_calloc
-independent_comalloc
-mallinfo
-malloc
-malloc_footprint
-malloc_footprint_limit
-malloc_max_footprint
-malloc_set_footprint_limit
-malloc_stats
-malloc_trim
-malloc_usable_size
-mallopt
-memalign
-optarg
-opterr
-optind
-optopt
-optreset
-posix_memalign
-pvalloc
-realloc
-realloc_in_place
-strtod
-strtod_l
-strtof
-strtold
-strtold_l
-valloc
-verr
-verrx
-vwarn
-vwarnx
-warn1
-warnx
+ T _ZNKSt20bad_array_new_length4whatEv
+ T _ZNKSt9bad_alloc4whatEv
+ T _ZNSt20bad_array_new_lengthC1Ev
+ T _ZNSt20bad_array_new_lengthC2Ev
+ T _ZNSt20bad_array_new_lengthD0Ev
+ ? _ZNSt20bad_array_new_lengthD1Ev
+ T _ZNSt20bad_array_new_lengthD2Ev
+ T _ZNSt9bad_allocC1Ev
+ T _ZNSt9bad_allocC2Ev
+ T _ZNSt9bad_allocD0Ev
+ T _ZNSt9bad_allocD1Ev
+ T _ZNSt9bad_allocD2Ev
+ T _ZSt15get_new_handlerv
+ T _ZSt15set_new_handlerPFvvE
+ T _ZSt17__throw_bad_allocv
+ D _ZSt7nothrow
+ D _ZTISt20bad_array_new_length
+ D _ZTISt9bad_alloc
+ D _ZTSSt20bad_array_new_length
+ D _ZTSSt9bad_alloc
+ D _ZTVSt20bad_array_new_length
+ D _ZTVSt9bad_alloc
+ W _ZdaPv
+ W _ZdaPvRKSt9nothrow_t
+ W _ZdlPv
+ W _ZdlPvRKSt9nothrow_t
+ W _Znaj
+ W _ZnajRKSt9nothrow_t
+ W _Znwj
+ W _ZnwjRKSt9nothrow_t
+ T _err
+ T _errx
+ T _verr
+ T _verrx
+ T _vwarn
+ T _vwarnx
+ T _warn
+ T _warnx
+ T atof
+ W bulk_free
+ W calloc
+ W err
+ W errx
+ W free
+ T getopt
+ T getopt_long
+ T getopt_long_only
+ W independent_calloc
+ W independent_comalloc
+ W mallinfo
+ W malloc
+ W malloc_footprint
+ W malloc_footprint_limit
+ W malloc_max_footprint
+ W malloc_set_footprint_limit
+ W malloc_stats
+ W malloc_trim
+ T malloc_usable_size
+ W mallopt
+ W memalign
+ C optarg
+ D opterr
+ D optind
+ D optopt
+ C optreset
+ W posix_memalign
+ W pvalloc
+ W realloc
+ W realloc_in_place
+ T strtod
+ T strtod_l
+ T strtof
+ T strtold
+ T strtold_l
+ W valloc
+ W verr
+ W verrx
+ W vwarn
+ W vwarnx
+ W warn1
+ W warnx
diff --git a/system/lib/libc/musl/memcpy.c b/system/lib/libc/musl/memcpy.c
deleted file mode 100644
index 8e98302f..00000000
--- a/system/lib/libc/musl/memcpy.c
+++ /dev/null
@@ -1,29 +0,0 @@
-#include <string.h>
-#include <stdlib.h>
-#include <stdint.h>
-
-#define SS (sizeof(size_t))
-#define ALIGN (sizeof(size_t)-1)
-#define ONES ((size_t)-1/UCHAR_MAX)
-
-void *memcpy(void *restrict dest, const void *restrict src, size_t n)
-{
- unsigned char *d = dest;
- const unsigned char *s = src;
-
- if (((uintptr_t)d & ALIGN) != ((uintptr_t)s & ALIGN))
- goto misaligned;
-
- for (; ((uintptr_t)d & ALIGN) && n; n--) *d++ = *s++;
- if (n) {
- size_t *wd = (void *)d;
- const size_t *ws = (const void *)s;
-
- for (; n>=SS; n-=SS) *wd++ = *ws++;
- d = (void *)wd;
- s = (const void *)ws;
-misaligned:
- for (; n; n--) *d++ = *s++;
- }
- return dest;
-}
diff --git a/system/lib/libc/musl/readme.txt b/system/lib/libc/musl/readme.txt
new file mode 100644
index 00000000..0df3429d
--- /dev/null
+++ b/system/lib/libc/musl/readme.txt
@@ -0,0 +1 @@
+These sources were downloaded from the musl-0.9.10 release on April 14, 2003.
diff --git a/system/lib/libc/musl/src/internal/libc.c b/system/lib/libc/musl/src/internal/libc.c
new file mode 100644
index 00000000..942f6b44
--- /dev/null
+++ b/system/lib/libc/musl/src/internal/libc.c
@@ -0,0 +1,22 @@
+#include "libc.h"
+
+#ifdef USE_LIBC_ACCESSOR
+struct __libc *__libc_loc()
+{
+ static struct __libc __libc;
+ return &__libc;
+}
+#else
+struct __libc __libc;
+#endif
+
+#ifdef BROKEN_VISIBILITY
+__asm__(".hidden __libc");
+#endif
+
+size_t __hwcap;
+size_t __sysinfo;
+char *__progname=0, *__progname_full=0;
+
+weak_alias(__progname, program_invocation_short_name);
+weak_alias(__progname_full, program_invocation_name);
diff --git a/system/lib/libc/musl/src/internal/libc.h b/system/lib/libc/musl/src/internal/libc.h
new file mode 100644
index 00000000..c9416f07
--- /dev/null
+++ b/system/lib/libc/musl/src/internal/libc.h
@@ -0,0 +1,71 @@
+#ifndef LIBC_H
+#define LIBC_H
+
+#include <stdlib.h>
+#include <stdio.h>
+
+struct __libc {
+ void *main_thread;
+ int threaded;
+ int secure;
+ size_t *auxv;
+ int (*atexit)(void (*)(void));
+ void (*fini)(void);
+ void (*ldso_fini)(void);
+ volatile int threads_minus_1;
+ int canceldisable;
+ FILE *ofl_head;
+ int ofl_lock[2];
+ size_t tls_size;
+};
+
+extern size_t __hwcap;
+
+#if !defined(__PIC__) || (100*__GNUC__+__GNUC_MINOR__ >= 303 && !defined(__PCC__))
+
+#ifdef __PIC__
+#if __GNUC__ < 4
+#define BROKEN_VISIBILITY 1
+#endif
+#define ATTR_LIBC_VISIBILITY __attribute__((visibility("hidden")))
+#else
+#define ATTR_LIBC_VISIBILITY
+#endif
+
+extern struct __libc __libc ATTR_LIBC_VISIBILITY;
+#define libc __libc
+
+#else
+
+#define USE_LIBC_ACCESSOR
+#define ATTR_LIBC_VISIBILITY
+extern struct __libc *__libc_loc(void) __attribute__((const));
+#define libc (*__libc_loc())
+
+#endif
+
+
+/* Designed to avoid any overhead in non-threaded processes */
+void __lock(volatile int *) ATTR_LIBC_VISIBILITY;
+void __unlock(volatile int *) ATTR_LIBC_VISIBILITY;
+int __lockfile(FILE *) ATTR_LIBC_VISIBILITY;
+void __unlockfile(FILE *) ATTR_LIBC_VISIBILITY;
+#define LOCK(x) (libc.threads_minus_1 ? (__lock(x),1) : ((void)(x),1))
+#define UNLOCK(x) (libc.threads_minus_1 ? (__unlock(x),1) : ((void)(x),1))
+
+void __synccall(void (*)(void *), void *);
+int __setxid(int, int, int, int);
+
+extern char **__environ;
+
+#undef weak_alias
+#define weak_alias(old, new) \
+ extern __typeof(old) new __attribute__((weak, alias(#old)))
+
+#undef LFS64_2
+#define LFS64_2(x, y) weak_alias(x, y)
+
+#undef LFS64
+#define LFS64(x) LFS64_2(x, x##64)
+
+#endif
diff --git a/system/lib/libc/musl/src/multibyte/btowc.c b/system/lib/libc/musl/src/multibyte/btowc.c
new file mode 100644
index 00000000..9d2c3b16
--- /dev/null
+++ b/system/lib/libc/musl/src/multibyte/btowc.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+#include <wchar.h>
+
+wint_t btowc(int c)
+{
+ return c<128U ? c : EOF;
+}
diff --git a/system/lib/libc/musl/src/multibyte/internal.c b/system/lib/libc/musl/src/multibyte/internal.c
new file mode 100644
index 00000000..ab22806e
--- /dev/null
+++ b/system/lib/libc/musl/src/multibyte/internal.c
@@ -0,0 +1,38 @@
+/*
+ * This code was written by Rich Felker in 2010; no copyright is claimed.
+ * This code is in the public domain. Attribution is appreciated but
+ * unnecessary.
+ */
+
+#include <inttypes.h>
+
+#include "internal.h"
+
+#define C(x) ( x<2 ? -1 : ( R(0x80,0xc0) | x ) )
+#define D(x) C((x+16))
+#define E(x) ( ( x==0 ? R(0xa0,0xc0) : \
+ x==0xd ? R(0x80,0xa0) : \
+ R(0x80,0xc0) ) \
+ | ( R(0x80,0xc0) >> 6 ) \