boot2

Playing with the boostrap
git clone https://git.ryansepassi.com/git/boot2.git
Log | Files | Refs | README

commit 6f4189daceee7ae5a24b181d1b83a1ce80e9d0fd
parent 6488cca37dcdc7e2b323bb6f3bd37c045ff41a19
Author: Ryan Sepassi <rsepassi@gmail.com>
Date:   Tue, 28 Apr 2026 18:43:09 -0700

stage1-flatten: vendor local simple-patches for libc stubs

Adds a scripts/simple-patches/tcc-0.9.26/ tree of small awk-style
literal-block replacements applied to the unpacked tcc-0.9.26 source
right after the live-bootstrap patches. They strip or guard call
sites whose libc symbols aren't provided by the mes-mini-libc layer
mes/include points at:

  tcc-is-native-stub   tcc.h           — drop the native-arch detection
                                          path (uses dl* / mprotect).
  tccrun-include       libtcc.c        — gate `#include "tccrun.c"`
                                          and the run hooks under
                                          CONFIG_TCC_RUN.
  tinyc-define         libtcc.c        — drop the tinyc malloc detector.
  longjmp-stub         libtcc.c        — replace longjmp on parse error
                                          with abort.
  set-environment-stub tcc.c           — gate getenv-driven env init.
  getclock-ms-stub     tcc.c           — drop gettimeofday timing.
  getcwd-stub          tccgen.c        — drop getcwd in error path.
  ldexp-stub           tccpp.c         — drop the ldexp-driven hex-float
                                          path (parser still parses
                                          them; codegen rejects fp).
  date-time-stub       tccpp.c         — replace __DATE__ / __TIME__
                                          predefines with fixed strings.
  elfinterp-stub       tccelf.c        — fix the dynamic-linker path
                                          rather than reading it via
                                          getenv.

Each patch follows live-bootstrap's pre/after literal-block format,
applied via the existing apply_simple_patch helper. The target file
list is checked at start so a missing patch fails the flatten loudly
instead of silently writing through.

Effect on the unresolved-symbol set produced by `make tcc-boot2`:
the libc functions stubbed here drop out, leaving only the small
forty-or-so libc subset tcc.c genuinely needs at runtime (see
docs/LIBC.txt).

Diffstat:
Ascripts/simple-patches/tcc-0.9.26/date-time-stub.after | 21+++++++++++++++++++++
Ascripts/simple-patches/tcc-0.9.26/date-time-stub.before | 14++++++++++++++
Ascripts/simple-patches/tcc-0.9.26/elfinterp-stub.after | 6++++++
Ascripts/simple-patches/tcc-0.9.26/elfinterp-stub.before | 2++
Ascripts/simple-patches/tcc-0.9.26/getclock-ms-stub.after | 12++++++++++++
Ascripts/simple-patches/tcc-0.9.26/getclock-ms-stub.before | 10++++++++++
Ascripts/simple-patches/tcc-0.9.26/getcwd-stub.after | 6++++++
Ascripts/simple-patches/tcc-0.9.26/getcwd-stub.before | 2++
Ascripts/simple-patches/tcc-0.9.26/ldexp-stub.after | 7+++++++
Ascripts/simple-patches/tcc-0.9.26/ldexp-stub.before | 3+++
Ascripts/simple-patches/tcc-0.9.26/longjmp-stub.after | 12++++++++++++
Ascripts/simple-patches/tcc-0.9.26/longjmp-stub.before | 8++++++++
Ascripts/simple-patches/tcc-0.9.26/set-environment-stub.after | 17+++++++++++++++++
Ascripts/simple-patches/tcc-0.9.26/set-environment-stub.before | 15+++++++++++++++
Ascripts/simple-patches/tcc-0.9.26/tcc-is-native-stub.after | 14++++++++++++++
Ascripts/simple-patches/tcc-0.9.26/tcc-is-native-stub.before | 14++++++++++++++
Ascripts/simple-patches/tcc-0.9.26/tccrun-include.after | 7+++++++
Ascripts/simple-patches/tcc-0.9.26/tccrun-include.before | 5+++++
Ascripts/simple-patches/tcc-0.9.26/tinyc-define.after | 9+++++++++
Ascripts/simple-patches/tcc-0.9.26/tinyc-define.before | 5+++++
Mscripts/stage1-flatten.sh | 24++++++++++++++++++++++++
21 files changed, 213 insertions(+), 0 deletions(-)

diff --git a/scripts/simple-patches/tcc-0.9.26/date-time-stub.after b/scripts/simple-patches/tcc-0.9.26/date-time-stub.after @@ -0,0 +1,21 @@ + } else if (tok == TOK___DATE__ || tok == TOK___TIME__) { +#if BOOTSTRAP + if (tok == TOK___DATE__) + cstrval = "Jan 1 1970"; + else + cstrval = "00:00:00"; +#else + time_t ti; + struct tm *tm; + + time(&ti); + tm = localtime(&ti); + if (tok == TOK___DATE__) { + snprintf(buf, sizeof(buf), "%s %2d %d", + ab_month_name[tm->tm_mon], tm->tm_mday, tm->tm_year + 1900); + } else { + snprintf(buf, sizeof(buf), "%02d:%02d:%02d", + tm->tm_hour, tm->tm_min, tm->tm_sec); + } + cstrval = buf; +#endif diff --git a/scripts/simple-patches/tcc-0.9.26/date-time-stub.before b/scripts/simple-patches/tcc-0.9.26/date-time-stub.before @@ -0,0 +1,14 @@ + } else if (tok == TOK___DATE__ || tok == TOK___TIME__) { + time_t ti; + struct tm *tm; + + time(&ti); + tm = localtime(&ti); + if (tok == TOK___DATE__) { + snprintf(buf, sizeof(buf), "%s %2d %d", + ab_month_name[tm->tm_mon], tm->tm_mday, tm->tm_year + 1900); + } else { + snprintf(buf, sizeof(buf), "%02d:%02d:%02d", + tm->tm_hour, tm->tm_min, tm->tm_sec); + } + cstrval = buf; diff --git a/scripts/simple-patches/tcc-0.9.26/elfinterp-stub.after b/scripts/simple-patches/tcc-0.9.26/elfinterp-stub.after @@ -0,0 +1,6 @@ + /* allow override the dynamic loader */ +#if BOOTSTRAP + const char *elfint = NULL; +#else + const char *elfint = getenv("LD_SO"); +#endif diff --git a/scripts/simple-patches/tcc-0.9.26/elfinterp-stub.before b/scripts/simple-patches/tcc-0.9.26/elfinterp-stub.before @@ -0,0 +1,2 @@ + /* allow override the dynamic loader */ + const char *elfint = getenv("LD_SO"); diff --git a/scripts/simple-patches/tcc-0.9.26/getclock-ms-stub.after b/scripts/simple-patches/tcc-0.9.26/getclock-ms-stub.after @@ -0,0 +1,12 @@ +static unsigned getclock_ms(void) +{ +#if BOOTSTRAP + return 0; +#elif defined(_WIN32) + return GetTickCount(); +#else + struct timeval tv; + gettimeofday(&tv, NULL); + return tv.tv_sec*1000 + (tv.tv_usec+500)/1000; +#endif +} diff --git a/scripts/simple-patches/tcc-0.9.26/getclock-ms-stub.before b/scripts/simple-patches/tcc-0.9.26/getclock-ms-stub.before @@ -0,0 +1,10 @@ +static unsigned getclock_ms(void) +{ +#ifdef _WIN32 + return GetTickCount(); +#else + struct timeval tv; + gettimeofday(&tv, NULL); + return tv.tv_sec*1000 + (tv.tv_usec+500)/1000; +#endif +} diff --git a/scripts/simple-patches/tcc-0.9.26/getcwd-stub.after b/scripts/simple-patches/tcc-0.9.26/getcwd-stub.after @@ -0,0 +1,6 @@ + text_section->sh_num, NULL); +#if BOOTSTRAP + buf[0] = '.'; buf[1] = 0; +#else + getcwd(buf, sizeof(buf)); +#endif diff --git a/scripts/simple-patches/tcc-0.9.26/getcwd-stub.before b/scripts/simple-patches/tcc-0.9.26/getcwd-stub.before @@ -0,0 +1,2 @@ + text_section->sh_num, NULL); + getcwd(buf, sizeof(buf)); diff --git a/scripts/simple-patches/tcc-0.9.26/ldexp-stub.after b/scripts/simple-patches/tcc-0.9.26/ldexp-stub.after @@ -0,0 +1,7 @@ + d = (double)bn[1] * 4294967296.0 + (double)bn[0]; +#endif +#if BOOTSTRAP + d = 0; +#else + d = ldexp(d, exp_val - frac_bits); +#endif diff --git a/scripts/simple-patches/tcc-0.9.26/ldexp-stub.before b/scripts/simple-patches/tcc-0.9.26/ldexp-stub.before @@ -0,0 +1,3 @@ + d = (double)bn[1] * 4294967296.0 + (double)bn[0]; +#endif + d = ldexp(d, exp_val - frac_bits); diff --git a/scripts/simple-patches/tcc-0.9.26/longjmp-stub.after b/scripts/simple-patches/tcc-0.9.26/longjmp-stub.after @@ -0,0 +1,12 @@ + /* better than nothing: in some cases, we accept to handle errors */ +#if HAVE_SETJMP + if (s1->error_set_jmp_enabled) { + longjmp(s1->error_jmp_buf, 1); + } else { + /* XXX: eliminate this someday */ + exit(1); + } +#else + exit(1); +#endif +} diff --git a/scripts/simple-patches/tcc-0.9.26/longjmp-stub.before b/scripts/simple-patches/tcc-0.9.26/longjmp-stub.before @@ -0,0 +1,8 @@ + /* better than nothing: in some cases, we accept to handle errors */ + if (s1->error_set_jmp_enabled) { + longjmp(s1->error_jmp_buf, 1); + } else { + /* XXX: eliminate this someday */ + exit(1); + } +} diff --git a/scripts/simple-patches/tcc-0.9.26/set-environment-stub.after b/scripts/simple-patches/tcc-0.9.26/set-environment-stub.after @@ -0,0 +1,17 @@ +#if !BOOTSTRAP + char * path; + + path = getenv("C_INCLUDE_PATH"); + if(path != NULL) { + tcc_add_include_path(s, path); + } + path = getenv("CPATH"); + if(path != NULL) { + tcc_add_include_path(s, path); + } + path = getenv("LIBRARY_PATH"); + if(path != NULL) { + tcc_add_library_path(s, path); + } +#endif +} diff --git a/scripts/simple-patches/tcc-0.9.26/set-environment-stub.before b/scripts/simple-patches/tcc-0.9.26/set-environment-stub.before @@ -0,0 +1,15 @@ + char * path; + + path = getenv("C_INCLUDE_PATH"); + if(path != NULL) { + tcc_add_include_path(s, path); + } + path = getenv("CPATH"); + if(path != NULL) { + tcc_add_include_path(s, path); + } + path = getenv("LIBRARY_PATH"); + if(path != NULL) { + tcc_add_library_path(s, path); + } +} diff --git a/scripts/simple-patches/tcc-0.9.26/tcc-is-native-stub.after b/scripts/simple-patches/tcc-0.9.26/tcc-is-native-stub.after @@ -0,0 +1,14 @@ +/* only native compiler supports -run */ +#if !BOOTSTRAP && defined _WIN32 == defined TCC_TARGET_PE +# if (defined __i386__ || defined _X86_) && defined TCC_TARGET_I386 +# define TCC_IS_NATIVE +# elif (defined __x86_64__ || defined _AMD64_) && defined TCC_TARGET_X86_64 +# define TCC_IS_NATIVE +# elif defined __arm__ && defined TCC_TARGET_ARM +# define TCC_IS_NATIVE +# elif defined __aarch64__ && defined TCC_TARGET_ARM64 +# define TCC_IS_NATIVE +# elif defined __riscv && defined __LP64__ && defined TCC_TARGET_RISCV64 +# define TCC_IS_NATIVE +# endif +#endif diff --git a/scripts/simple-patches/tcc-0.9.26/tcc-is-native-stub.before b/scripts/simple-patches/tcc-0.9.26/tcc-is-native-stub.before @@ -0,0 +1,14 @@ +/* only native compiler supports -run */ +#if defined _WIN32 == defined TCC_TARGET_PE +# if (defined __i386__ || defined _X86_) && defined TCC_TARGET_I386 +# define TCC_IS_NATIVE +# elif (defined __x86_64__ || defined _AMD64_) && defined TCC_TARGET_X86_64 +# define TCC_IS_NATIVE +# elif defined __arm__ && defined TCC_TARGET_ARM +# define TCC_IS_NATIVE +# elif defined __aarch64__ && defined TCC_TARGET_ARM64 +# define TCC_IS_NATIVE +# elif defined __riscv && defined __LP64__ && defined TCC_TARGET_RISCV64 +# define TCC_IS_NATIVE +# endif +#endif diff --git a/scripts/simple-patches/tcc-0.9.26/tccrun-include.after b/scripts/simple-patches/tcc-0.9.26/tccrun-include.after @@ -0,0 +1,7 @@ +#ifdef ONE_SOURCE +#include "tccpp.c" +#include "tccgen.c" +#include "tccelf.c" +#if !BOOTSTRAP +#include "tccrun.c" +#endif diff --git a/scripts/simple-patches/tcc-0.9.26/tccrun-include.before b/scripts/simple-patches/tcc-0.9.26/tccrun-include.before @@ -0,0 +1,5 @@ +#ifdef ONE_SOURCE +#include "tccpp.c" +#include "tccgen.c" +#include "tccelf.c" +#include "tccrun.c" diff --git a/scripts/simple-patches/tcc-0.9.26/tinyc-define.after b/scripts/simple-patches/tcc-0.9.26/tinyc-define.after @@ -0,0 +1,9 @@ + /* define __TINYC__ 92X */ +#if BOOTSTRAP + tcc_define_symbol(s, "__TINYC__", "926"); +#else + char buffer[32]; int a,b,c; + sscanf(TCC_VERSION, "%d.%d.%d", &a, &b, &c); + sprintf(buffer, "%d", a*10000 + b*100 + c); + tcc_define_symbol(s, "__TINYC__", buffer); +#endif diff --git a/scripts/simple-patches/tcc-0.9.26/tinyc-define.before b/scripts/simple-patches/tcc-0.9.26/tinyc-define.before @@ -0,0 +1,5 @@ + /* define __TINYC__ 92X */ + char buffer[32]; int a,b,c; + sscanf(TCC_VERSION, "%d.%d.%d", &a, &b, &c); + sprintf(buffer, "%d", a*10000 + b*100 + c); + tcc_define_symbol(s, "__TINYC__", buffer); diff --git a/scripts/stage1-flatten.sh b/scripts/stage1-flatten.sh @@ -46,6 +46,7 @@ ROOT=$(cd "$(dirname "$0")/.." && pwd) WORK=$ROOT/build/cc-bootstrap/$ARCH DISTFILES=$ROOT/../lb-work/distfiles LB_PATCHES=$ROOT/../live-bootstrap/steps/tcc-0.9.26/simple-patches +OUR_PATCHES=$ROOT/scripts/simple-patches/tcc-0.9.26 MES_INCLUDE=$ROOT/../mes/include MES_INCLUDE_LINUX=$MES_INCLUDE/linux/$MES_ARCH @@ -54,6 +55,7 @@ TCC_PKG=tcc-0.9.26-1147-gee75a10c [ -r "$TCC_TAR" ] || { echo "missing $TCC_TAR" >&2; exit 1; } [ -d "$LB_PATCHES" ] || { echo "missing $LB_PATCHES" >&2; exit 1; } +[ -d "$OUR_PATCHES" ] || { echo "missing $OUR_PATCHES" >&2; exit 1; } [ -d "$MES_INCLUDE" ] || { echo "missing $MES_INCLUDE" >&2; exit 1; } [ -d "$MES_INCLUDE_LINUX" ] || { echo "missing $MES_INCLUDE_LINUX" >&2; exit 1; } @@ -103,6 +105,28 @@ apply_simple_patch \ "$LB_PATCHES/addback-fileopen.before" \ "$LB_PATCHES/addback-fileopen.after" +# Bootstrap stub patches — eliminate libc symbols not provided by mes-mini-libc +# (mprotect, getcwd, getenv, gettimeofday, ldexp, time, localtime, sscanf) by +# gating call sites on the existing BOOTSTRAP CPP define. +apply_our_patch() { + name=$1; target=$2 + apply_simple_patch \ + "$target" \ + "$OUR_PATCHES/$name.before" \ + "$OUR_PATCHES/$name.after" +} + +apply_our_patch tcc-is-native-stub "$SRC/tcc.h" +apply_our_patch tccrun-include "$SRC/libtcc.c" +apply_our_patch tinyc-define "$SRC/libtcc.c" +apply_our_patch longjmp-stub "$SRC/libtcc.c" +apply_our_patch set-environment-stub "$SRC/tcc.c" +apply_our_patch getclock-ms-stub "$SRC/tcc.c" +apply_our_patch getcwd-stub "$SRC/tccgen.c" +apply_our_patch ldexp-stub "$SRC/tccpp.c" +apply_our_patch date-time-stub "$SRC/tccpp.c" +apply_our_patch elfinterp-stub "$SRC/tccelf.c" + # Empty config.h shims — pass1.kaem creates these via `catm <out>` (line 27-28). : > "$SRC/config.h" mkdir -p "$WORK/mes-overlay/mes"