diff options
55 files changed, 1252 insertions, 192 deletions
@@ -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 ) \ + | x ) +#define F(x) ( ( x>=5 ? 0 : \ + x==0 ? R(0x90,0xc0) : \ + x==4 ? R(0x80,0xa0) : \ + R(0x80,0xc0) ) \ + | ( R(0x80,0xc0) >> 6 ) \ + | ( R(0x80,0xc0) >> 12 ) \ + | x ) + +const uint32_t bittab[] = { + C(0x2),C(0x3),C(0x4),C(0x5),C(0x6),C(0x7), + C(0x8),C(0x9),C(0xa),C(0xb),C(0xc),C(0xd),C(0xe),C(0xf), + D(0x0),D(0x1),D(0x2),D(0x3),D(0x4),D(0x5),D(0x6),D(0x7), + D(0x8),D(0x9),D(0xa),D(0xb),D(0xc),D(0xd),D(0xe),D(0xf), + E(0x0),E(0x1),E(0x2),E(0x3),E(0x4),E(0x5),E(0x6),E(0x7), + E(0x8),E(0x9),E(0xa),E(0xb),E(0xc),E(0xd),E(0xe),E(0xf), + F(0x0),F(0x1),F(0x2),F(0x3),F(0x4) +}; + +#ifdef BROKEN_VISIBILITY +__asm__(".hidden __fsmu8"); +#endif diff --git a/system/lib/libc/musl/src/multibyte/internal.h b/system/lib/libc/musl/src/multibyte/internal.h new file mode 100644 index 00000000..25ba240e --- /dev/null +++ b/system/lib/libc/musl/src/multibyte/internal.h @@ -0 |