diff --git a/README.md b/README.md index a98136e..f34af0f 100644 --- a/README.md +++ b/README.md @@ -208,7 +208,12 @@ is required later for autotools. more complex edits, including just changes to lines. Luckily, we are able to patch patch using sed only. -#### Part 13: patched tinycc +#### Part 13: patched mes-libc + +Since patch is available at this point, we can apply additional fixes to +mes-libc that are not included in the wip-m2 branch and recompile libc. + +#### Part 14: patched tinycc In Guix, tinycc is patched to force static linking. Prior to this step, we have been forced to manually specify static linking for each tool. Now that we have @@ -217,11 +222,6 @@ patch, we can patch tinycc to force static linking and then recompile it. Note that we have to do this using tinycc 0.9.26, as tinycc 0.9.27 cannot recompile itself for unknown reasons. -#### Part 14: patched mes-libc - -Since patch is available at this point, we can apply additional fixes to -mes-libc that are not included in the wip-m2 branch and recompile libc. - #### Part 15: make 3.80 GNU `make` is now built so we have a more robust building system. `make` allows @@ -266,6 +266,7 @@ cope here. macros to be defined and files to be generated from those macros. #### Part 22: flex 2.5.11 + `flex` is a tool for generating lexers or scanners: programs that recognize lexical patters. Unfortunately `flex` also depends on itself for compiling its own scanner, so @@ -273,5 +274,23 @@ first flex 2.5.11 is compiled, with its scanner definition manually modified so it can be processed by lex for the Heirloom project (the required modifications are mostly syntactical, plus a few workarounds to avoid some flex advanced features). -### Part 23 flex 2.5.14 +#### Part 23 flex 2.5.14 + Then we recompile unpatched `flex` using its own lexer. + +#### Part 24 musl 1.1.24 + +`musl` is a C standard library that is lightweight, fast, simple, free, and strives to be correct +in the sense of standards-conformance and safety. `musl` is used by some distributions of GNU/Linux +as their C library. Our previous Mes C library was incomplete which prevented us from building many +newer or more complex programs. + +`tcc` has slight problems when building and linking `musl`, so we apply a few patches. In particular, +we replace all weak symbols with strong symbols and will patch `tcc` in the next step to ignore duplicate +symbols. + +#### Part 25 tcc 0.9.27 (musl) + +We recompile `tcc` against musl. This is a two stage process. First we build tcc-0.9.27 that itself +links to Mes C library but produces binaries linked to musl. Then we recompile newly produced tcc +with itself. Interestingly, tcc-0.9.27 linked against musl is self hosting. diff --git a/rootfs.sh b/rootfs.sh index 6f62318..2d2cc45 100755 --- a/rootfs.sh +++ b/rootfs.sh @@ -139,6 +139,9 @@ get_file http://download.nust.na/pub2/openpkg1/sources/DST/flex/flex-2.5.11.tar. # flex 2.5.14 get_file http://download.nust.na/pub2/openpkg1/sources/DST/flex/flex-2.5.14.tar.gz +# musl 1.1.24 +get_file https://musl.libc.org/releases/musl-1.1.24.tar.gz + # General cleanup find tmp -name .git -exec rm -rf \; diff --git a/sysa/after.kaem.run b/sysa/after.kaem.run index 29d646e..f2a0ab1 100755 --- a/sysa/after.kaem.run +++ b/sysa/after.kaem.run @@ -101,16 +101,16 @@ cd ${pkg} kaem --file ${pkg}.kaem cd .. -# Part 13: tcc-patched -cd tcc-0.9.27 -kaem --file tcc-patched.kaem -cd .. - -# Part 14: mes-libc-patched +# Part 13: mes-libc-patched cd tcc-0.9.27 kaem --file mes-libc-patched.kaem cd .. +# Part 14: tcc-patched +cd tcc-0.9.27 +kaem --file tcc-patched.kaem +cd .. + # Part 15: make pkg="make-3.80" cd ${pkg} diff --git a/sysa/flex-2.5.11/src/.placeholder b/sysa/flex-2.5.11/src/.placeholder deleted file mode 100644 index e69de29..0000000 diff --git a/sysa/helpers.sh b/sysa/helpers.sh index e9d160d..7e0ed68 100755 --- a/sysa/helpers.sh +++ b/sysa/helpers.sh @@ -27,14 +27,15 @@ build () { cd "build" - echo "${pkg}: unpacking source." - call src_unpack - build_script="${base_dir}/${script_name}" if test -e "${build_script}"; then # shellcheck source=/dev/null . "${build_script}" fi + + echo "${pkg}: unpacking source." + call src_unpack + cd "${pkg}" || (echo "Cannot cd into build/${pkg}!"; kill $$) echo "${pkg}: preparing source." @@ -53,6 +54,8 @@ build () { echo "${pkg}: build successful" cd .. + + unset -f src_unpack src_prepare src_configure src_compile src_install } # Default unpacking function that unpacks a single source tarball. diff --git a/sysa/musl-1.1.24/musl-1.1.24.sh b/sysa/musl-1.1.24/musl-1.1.24.sh new file mode 100755 index 0000000..5682981 --- /dev/null +++ b/sysa/musl-1.1.24/musl-1.1.24.sh @@ -0,0 +1,22 @@ +src_prepare() { + default_src_prepare + + # tcc does not support complex types + rm -rf src/complex + + # Configure fails without this + mkdir -p /dev +} + +src_configure() { + CC=tcc ./configure \ + --host=i386 \ + --disable-shared \ + --prefix=/after \ + --libdir=/after/lib/musl/ \ + --includedir=/after/include/musl +} + +src_compile() { + make CROSS_COMPILE= AR="tcc -ar" RANLIB=true CFLAGS="-DSYSCALL_NO_TLS" +} diff --git a/sysa/musl-1.1.24/patches/fenv.patch b/sysa/musl-1.1.24/patches/fenv.patch new file mode 100644 index 0000000..707ed53 --- /dev/null +++ b/sysa/musl-1.1.24/patches/fenv.patch @@ -0,0 +1,58 @@ +tcc does not seem to support stmxcsr and ldmxcsr. +Remove those. This migt break float exception handling but we +are unlikely to need it. +diff -U3 -r src/fenv/i386/fenv.s src/fenv/i386/fenv.s +--- src/fenv/i386/fenv.s 2019-10-13 22:58:27.000000000 +0100 ++++ src/fenv/i386/fenv.s 2021-02-01 00:27:04.924135707 +0000 +@@ -17,7 +17,6 @@ + jz 1f + fnclex + 1: push %edx +- stmxcsr (%esp) + pop %edx + and $0x3f,%eax + or %eax,%edx +@@ -26,7 +25,6 @@ + not %ecx + and %ecx,%edx + push %edx +- ldmxcsr (%esp) + pop %edx + 1: xor %eax,%eax + ret +@@ -77,11 +75,9 @@ + pop %edx + testl $0x02000000,(%edx) + jz 1f +- stmxcsr (%esp) + shl $3,%ch + andb $0x9f,1(%esp) + or %ch,1(%esp) +- ldmxcsr (%esp) + 1: pop %ecx + ret + +@@ -107,7 +103,6 @@ + testl $0x02000000,(%edx) + jz 1f + push %eax +- stmxcsr (%esp) + pop %edx + and $0x3f,%edx + or %edx,4(%ecx) +@@ -143,7 +138,6 @@ + shl $3,%ecx + or $0x1f80,%ecx + mov %ecx,4(%esp) +- ldmxcsr 4(%esp) + 1: ret + + .global fetestexcept +@@ -158,7 +152,6 @@ + pop %edx + testl $0x02000000,(%edx) + jz 1f +- stmxcsr 4(%esp) + or 4(%esp),%eax + 1: and %ecx,%eax + ret diff --git a/sysa/musl-1.1.24/patches/makefile.patch b/sysa/musl-1.1.24/patches/makefile.patch new file mode 100644 index 0000000..d6f965c --- /dev/null +++ b/sysa/musl-1.1.24/patches/makefile.patch @@ -0,0 +1,12 @@ +tcc -ar does not support creating empty archives +--- Makefile 2019-10-13 22:58:27.000000000 +0100 ++++ Makefile 2021-02-01 00:21:14.974687663 +0000 +@@ -167,7 +167,7 @@ + + $(EMPTY_LIBS): + rm -f $@ +- $(AR) rc $@ ++ touch $@ + + lib/%.o: obj/crt/$(ARCH)/%.o + cp $< $@ diff --git a/sysa/musl-1.1.24/patches/musl_weak_symbols.patch b/sysa/musl-1.1.24/patches/musl_weak_symbols.patch new file mode 100644 index 0000000..30c3845 --- /dev/null +++ b/sysa/musl-1.1.24/patches/musl_weak_symbols.patch @@ -0,0 +1,12 @@ +Replace weak symbols with strong to workaround an issue with tcc -ar +This won't be necessary once we can rebuild with ar from binutils. +--- src/include/features.h 2021-02-02 23:15:42.791932948 +0000 ++++ src/include/features.h 2021-02-02 23:17:21.394647015 +0000 +@@ -6,6 +6,6 @@ + #define weak __attribute__((__weak__)) + #define hidden __attribute__((__visibility__("hidden"))) + #define weak_alias(old, new) \ +- extern __typeof(old) new __attribute__((__weak__, __alias__(#old))) ++ extern __typeof(old) new __attribute__((/*__weak__, */__alias__(#old))) + + #endif diff --git a/sysa/musl-1.1.24/patches/set_thread_area.patch b/sysa/musl-1.1.24/patches/set_thread_area.patch new file mode 100644 index 0000000..2468b9f --- /dev/null +++ b/sysa/musl-1.1.24/patches/set_thread_area.patch @@ -0,0 +1,31 @@ +From 0b0640219338b80cf47026d1970b5503414ed7f3 Mon Sep 17 00:00:00 2001 +From: Rich Felker +Date: Sun, 30 Aug 2020 21:37:12 -0400 +Subject: fix i386 __set_thread_area fallback + +this code is only needed for pre-2.6 kernels, which are not actually +supported anyway, and was never tested. the fallback path using +SYS_modify_ldt failed to clear the upper bits of %eax (all ones due to +SYS_set_thread_area's return value being an error) before modifying +%al to attempt a new syscall. +--- + src/thread/i386/__set_thread_area.s | 1 + + 1 file changed, 1 insertion(+) + +(limited to 'src/thread/i386/__set_thread_area.s') + +diff --git src/thread/i386/__set_thread_area.s src/thread/i386/__set_thread_area.s +index c2c21dd5..aa6852be 100644 +--- src/thread/i386/__set_thread_area.s ++++ src/thread/i386/__set_thread_area.s +@@ -28,6 +28,7 @@ __set_thread_area: + ret + 2: + mov %ebx,%ecx ++ xor %eax,%eax + xor %ebx,%ebx + xor %edx,%edx + mov %ebx,(%esp) +-- +cgit v1.2.1 + diff --git a/sysa/musl-1.1.24/patches/sigsetjmp.patch b/sysa/musl-1.1.24/patches/sigsetjmp.patch new file mode 100644 index 0000000..036fc73 --- /dev/null +++ b/sysa/musl-1.1.24/patches/sigsetjmp.patch @@ -0,0 +1,13 @@ +tcc does not like jecxz instruction. +--- src/signal/i386/sigsetjmp.s 2019-10-13 22:58:27.000000000 +0100 ++++ src/signal/i386/sigsetjmp.s 2021-02-01 00:19:25.671735415 +0000 +@@ -5,7 +5,8 @@ + sigsetjmp: + __sigsetjmp: + mov 8(%esp),%ecx +- jecxz 1f ++ cmp %ecx,0 ++ je 1f + + mov 4(%esp),%eax + popl 24(%eax) diff --git a/sysa/musl-1.1.24/patches/tcc_static.patch b/sysa/musl-1.1.24/patches/tcc_static.patch new file mode 100644 index 0000000..19dc2e9 --- /dev/null +++ b/sysa/musl-1.1.24/patches/tcc_static.patch @@ -0,0 +1,107 @@ +tinycc-0.9.27 does not support the use of the static keyword within an array length or index. +diff -U3 -r src/internal/syscall.h src/internal/syscall.h +--- src/internal/syscall.h 2019-10-13 22:58:27.000000000 +0100 ++++ src/internal/syscall.h 2021-02-01 00:24:02.099200492 +0000 +@@ -331,7 +331,7 @@ + #define __sys_open_cp(...) __SYSCALL_DISP(__sys_open_cp,,__VA_ARGS__) + #define sys_open_cp(...) __syscall_ret(__sys_open_cp(__VA_ARGS__)) + +-hidden void __procfdname(char __buf[static 15+3*sizeof(int)], unsigned); ++hidden void __procfdname(char __buf[15+3*sizeof(int)], unsigned); + + hidden void *__vdsosym(const char *, const char *); + +diff -U3 -r src/network/lookup.h src/network/lookup.h +--- src/network/lookup.h 2019-10-13 22:58:27.000000000 +0100 ++++ src/network/lookup.h 2021-02-01 00:27:42.695155110 +0000 +@@ -43,9 +43,9 @@ + #define MAXADDRS 48 + #define MAXSERVS 2 + +-hidden int __lookup_serv(struct service buf[static MAXSERVS], const char *name, int proto, int socktype, int flags); +-hidden int __lookup_name(struct address buf[static MAXADDRS], char canon[static 256], const char *name, int family, int flags); +-hidden int __lookup_ipliteral(struct address buf[static 1], const char *name, int family); ++hidden int __lookup_serv(struct service buf[MAXSERVS], const char *name, int proto, int socktype, int flags); ++hidden int __lookup_name(struct address buf[MAXADDRS], char canon[256], const char *name, int family, int flags); ++hidden int __lookup_ipliteral(struct address buf[1], const char *name, int family); + + hidden int __get_resolv_conf(struct resolvconf *, char *, size_t); + hidden int __res_msend_rc(int, const unsigned char *const *, const int *, unsigned char *const *, int *, int, const struct resolvconf *); +diff -U3 -r src/network/lookup_ipliteral.c src/network/lookup_ipliteral.c +--- src/network/lookup_ipliteral.c 2019-10-13 22:58:27.000000000 +0100 ++++ src/network/lookup_ipliteral.c 2021-02-01 00:27:59.955620933 +0000 +@@ -9,7 +9,7 @@ + #include + #include "lookup.h" + +-int __lookup_ipliteral(struct address buf[static 1], const char *name, int family) ++int __lookup_ipliteral(struct address buf[1], const char *name, int family) + { + struct in_addr a4; + struct in6_addr a6; +diff -U3 -r src/network/lookup_name.c src/network/lookup_name.c +--- src/network/lookup_name.c 2019-10-13 22:58:27.000000000 +0100 ++++ src/network/lookup_name.c 2021-02-01 00:28:56.117136509 +0000 +@@ -23,7 +23,7 @@ + return !*s; + } + +-static int name_from_null(struct address buf[static 2], const char *name, int family, int flags) ++static int name_from_null(struct address buf[2], const char *name, int family, int flags) + { + int cnt = 0; + if (name) return 0; +@@ -41,12 +41,12 @@ + return cnt; + } + +-static int name_from_numeric(struct address buf[static 1], const char *name, int family) ++static int name_from_numeric(struct address buf[1], const char *name, int family) + { + return __lookup_ipliteral(buf, name, family); + } + +-static int name_from_hosts(struct address buf[static MAXADDRS], char canon[static 256], const char *name, int family) ++static int name_from_hosts(struct address buf[MAXADDRS], char canon[256], const char *name, int family) + { + char line[512]; + size_t l = strlen(name); +@@ -130,7 +130,7 @@ + return 0; + } + +-static int name_from_dns(struct address buf[static MAXADDRS], char canon[static 256], const char *name, int family, const struct resolvconf *conf) ++static int name_from_dns(struct address buf[MAXADDRS], char canon[256], const char *name, int family, const struct resolvconf *conf) + { + unsigned char qbuf[2][280], abuf[2][512]; + const unsigned char *qp[2] = { qbuf[0], qbuf[1] }; +@@ -166,7 +166,7 @@ + return EAI_FAIL; + } + +-static int name_from_dns_search(struct address buf[static MAXADDRS], char canon[static 256], const char *name, int family) ++static int name_from_dns_search(struct address buf[MAXADDRS], char canon[256], const char *name, int family) + { + char search[256]; + struct resolvconf conf; +@@ -284,7 +284,7 @@ + return b->sortkey - a->sortkey; + } + +-int __lookup_name(struct address buf[static MAXADDRS], char canon[static 256], const char *name, int family, int flags) ++int __lookup_name(struct address buf[MAXADDRS], char canon[256], const char *name, int family, int flags) + { + int cnt = 0, i, j; + +diff -U3 -r src/network/lookup_serv.c src/network/lookup_serv.c +--- src/network/lookup_serv.c 2019-10-13 22:58:27.000000000 +0100 ++++ src/network/lookup_serv.c 2021-02-01 00:29:10.357520778 +0000 +@@ -9,7 +9,7 @@ + #include "lookup.h" + #include "stdio_impl.h" + +-int __lookup_serv(struct service buf[static MAXSERVS], const char *name, int proto, int socktype, int flags) ++int __lookup_serv(struct service buf[MAXSERVS], const char *name, int proto, int socktype, int flags) + { + char line[128]; + int cnt = 0; diff --git a/sysa/musl-1.1.24/patches/va_list.patch b/sysa/musl-1.1.24/patches/va_list.patch new file mode 100644 index 0000000..5aae04d --- /dev/null +++ b/sysa/musl-1.1.24/patches/va_list.patch @@ -0,0 +1,37 @@ +From 1642f5982009e110615a29745f9cafd51a5c1597 Mon Sep 17 00:00:00 2001 +From: Giovanni Mascellani +Date: Tue, 11 Jun 2019 11:20:07 +0200 +Subject: [PATCH] stdarg.h: add support for tcc. + +--- + arch/i386/bits/alltypes.h.in | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) + +diff --git a/arch/i386/bits/alltypes.h.in b/arch/i386/bits/alltypes.h.in +index 1a8432d3..44cb5987 100644 +--- arch/i386/bits/alltypes.h.in ++++ arch/i386/bits/alltypes.h.in +@@ -2,7 +2,19 @@ + #define _Int64 long long + #define _Reg int + +-#if __GNUC__ >= 3 ++#ifdef __TINYC__ ++typedef char *__builtin_va_list; ++#define __builtin_va_start(ap,last) ap = ((char *)&(last)) + ((sizeof(last)+3)&~3) ++#define __builtin_va_arg(ap,type) (ap += (sizeof(type)+3)&~3, *(type *)(ap - ((sizeof(type)+3)&~3))) ++#define __builtin_va_copy(dest, src) (dest) = (src) ++#define __builtin_va_end(ap) ++#ifndef __TINYC_redefine_va_list ++#define __TINYC_redefine_va_list ++#undef __DEFINED_va_list ++#endif ++#endif ++ ++#if __GNUC__ >= 3 || defined(__TINYC__) + TYPEDEF __builtin_va_list va_list; + TYPEDEF __builtin_va_list __isoc_va_list; + #else +-- +GitLab + diff --git a/sysa/run.sh b/sysa/run.sh index 579ab88..f557e75 100755 --- a/sysa/run.sh +++ b/sysa/run.sh @@ -18,4 +18,10 @@ build flex-2.5.11 # Part 23 build flex-2.5.14 +# Part 24 +build musl-1.1.24 + +# Part 25 +build tcc-0.9.27 tcc-musl.sh + echo "Bootstrapping completed." diff --git a/sysa/tcc-0.9.27/mes-libc-patched.kaem b/sysa/tcc-0.9.27/mes-libc-patched.kaem index 39da1ab..1944b66 100755 --- a/sysa/tcc-0.9.27/mes-libc-patched.kaem +++ b/sysa/tcc-0.9.27/mes-libc-patched.kaem @@ -6,6 +6,7 @@ cd src/mes-libc # Patch patch -Np0 -i ../../patches/mes-libc-qsort.patch +patch -Np0 -i ../../patches/mes-libc-crt1.patch # Recompile libc cd ../tcc-0.9.27 diff --git a/sysa/tcc-0.9.27/patches/ignore-duplicate-symbols.patch b/sysa/tcc-0.9.27/patches/ignore-duplicate-symbols.patch new file mode 100644 index 0000000..79313ea --- /dev/null +++ b/sysa/tcc-0.9.27/patches/ignore-duplicate-symbols.patch @@ -0,0 +1,15 @@ +Ignore duplicate symbols. Due to poor support for weak symbols in tcc-ar +we had to patch musl to replace weak symbols with strong symbols +--- tccelf.c 2021-02-02 17:41:08.662247892 +0000 ++++ tccelf.c 2021-02-02 23:21:49.652080201 +0000 +@@ -552,8 +552,9 @@ + #if 0 + printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n", + sym_bind, shndx, new_vis, esym_bind, esym->st_shndx, esym_vis); +-#endif + tcc_error_noabort("'%s' defined twice", name); ++#endif ++ goto do_patch; + } + } else { + do_patch: diff --git a/sysa/tcc-0.9.27/patches/mes-libc-crt1.patch b/sysa/tcc-0.9.27/patches/mes-libc-crt1.patch new file mode 100644 index 0000000..fd1b954 --- /dev/null +++ b/sysa/tcc-0.9.27/patches/mes-libc-crt1.patch @@ -0,0 +1,23 @@ +Fix issue in mes-libc crt where argc was getting truncated to lower byte and +prevented programs with more than 255 arguments from working correctly. + +--- lib/linux/x86-mes-gcc/crt1.c ++++ lib/linux/x86-mes-gcc/crt1.c +@@ -48,7 +48,7 @@ _start () + asm ( + "mov %%ebp,%%eax\n\t" + "add $4,%%eax\n\t" +- "movzbl (%%eax),%%eax\n\t" ++ "mov (%%eax),%%eax\n\t" + "add $3,%%eax\n\t" + "shl $2,%%eax\n\t" + "add %%ebp,%%eax\n\t" +@@ -64,7 +64,7 @@ _start () + + "mov %ebp,%eax\n\t" + "add $4,%eax\n\t" +- "movzbl (%eax),%eax\n\t" ++ "mov (%eax),%eax\n\t" + "push %eax\n\t" + + "call main\n\t" diff --git a/sysa/tcc-0.9.27/tcc-musl.sh b/sysa/tcc-0.9.27/tcc-musl.sh new file mode 100755 index 0000000..17e6eff --- /dev/null +++ b/sysa/tcc-0.9.27/tcc-musl.sh @@ -0,0 +1,50 @@ +src_unpack() { + # Our cp does not support recursive copying + tar -c -C ../src/ -f tcc-0.9.27.tar tcc-0.9.27/ + tar -xf tcc-0.9.27.tar +} + +src_prepare() { + patch -Np0 -i ../../patches/ignore-duplicate-symbols.patch +} + +src_compile() { + export prefix=/after + export libdir=${prefix}/lib/musl + export incdir=${prefix}/include/musl + export bindir=${prefix}/bin + + mkdir -p ${libdir}/tcc + + # We first have to recompile using tcc-0.9.26 as tcc-0.9.27 is not self-hosting, + # but when linked with musl it is. + for TCC in tcc-0.9.26 tcc-musl; do + ${TCC} \ + -v \ + -static \ + -o ${bindir}/tcc-musl \ + -D TCC_TARGET_I386=1 \ + -D CONFIG_TCCDIR=\"${libdir}/tcc\" \ + -D CONFIG_TCC_CRTPREFIX=\"${libdir}\" \ + -D CONFIG_TCC_ELFINTERP=\"/musl/loader\" \ + -D CONFIG_TCC_LIBPATHS=\"${libdir}:${libdir}/tcc\" \ + -D CONFIG_TCC_SYSINCLUDEPATHS=\"${incdir}\" \ + -D TCC_LIBGCC=\"${libdir}/libc.a\" \ + -D CONFIG_TCC_STATIC=1 \ + -D CONFIG_USE_LIBGCC=1 \ + -D TCC_VERSION=\"0.9.27\" \ + -D ONE_SOURCE=1 \ + tcc.c + + # libtcc1.a + ${TCC} -c -D HAVE_CONFIG_H=1 lib/libtcc1.c + ${TCC} -ar cr ${libdir}/tcc/libtcc1.a libtcc1.o + done +} + +src_install() { + # Remove old tcc binaries, keep one for tcc-0.9.27 with mes C library + mv ${bindir}/tcc ${bindir}/tcc-mes + rm ${bindir}/boot*-tcc ${bindir}/tcc-0.9.26 ${bindir}/mes-tcc + ln -s ${bindir}/tcc-musl ${bindir}/tcc +}