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:
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"