diff --git a/kernel/src/Api/BuildNo.hpp b/kernel/src/Api/BuildNo.hpp index 8b446bd..39cdee0 100644 --- a/kernel/src/Api/BuildNo.hpp +++ b/kernel/src/Api/BuildNo.hpp @@ -12,4 +12,4 @@ #pragma once -#define MONTAUK_BUILD_NUMBER 23 +#define MONTAUK_BUILD_NUMBER 25 diff --git a/kernel/src/Api/Process.hpp b/kernel/src/Api/Process.hpp index b06eec9..f8de325 100644 --- a/kernel/src/Api/Process.hpp +++ b/kernel/src/Api/Process.hpp @@ -84,6 +84,18 @@ namespace montauk::abi { return childPid; } + // Copy the absolute path this process was spawned from (argv[0]). + static int Sys_GetExecPath(char* buf, uint64_t maxLen) { + auto* proc = Sched::GetCurrentProcessPtr(); + if (proc == nullptr || buf == nullptr || maxLen == 0) return -1; + int i = 0; + for (; i < (int)maxLen - 1 && proc->name[i]; i++) { + buf[i] = proc->name[i]; + } + buf[i] = '\0'; + return i; + } + static int Sys_GetArgs(char* buf, uint64_t maxLen) { auto* proc = Sched::GetCurrentProcessPtr(); if (proc == nullptr || buf == nullptr || maxLen == 0) return -1; diff --git a/kernel/src/Api/Syscall.cpp b/kernel/src/Api/Syscall.cpp index c8614d3..70410fb 100644 --- a/kernel/src/Api/Syscall.cpp +++ b/kernel/src/Api/Syscall.cpp @@ -150,6 +150,9 @@ namespace montauk::abi { return (int64_t)Sys_FbMap(); case SYS_FBFLIP: return Sys_FbFlip(frame->arg1, frame->arg2); + case SYS_GETEXECPATH: + if (!UserMemory::Range(frame->arg2 ? frame->arg1 : frame->arg1, frame->arg2, true)) return -1; + return Sys_GetExecPath((char*)frame->arg1, frame->arg2); case SYS_TERMSIZE: return (int64_t)Sys_TermSize(); case SYS_GETARGS: diff --git a/kernel/src/Api/Syscall.hpp b/kernel/src/Api/Syscall.hpp index 670ae28..a74f877 100644 --- a/kernel/src/Api/Syscall.hpp +++ b/kernel/src/Api/Syscall.hpp @@ -280,7 +280,10 @@ namespace montauk::abi { static constexpr uint64_t SYS_POWERINFO = 149; // (PowerInfo*) -> 0, -1 unsupported /* Graphics.hpp -- framebuffer page flip (double-buffered scanout) */ - static constexpr uint64_t SYS_FBFLIP = 150; // (index, flags) -> new front index; index=-1 queries support (1/0); flags bit0 = wait vsync + static constexpr uint64_t SYS_FBFLIP = 150; + + // Absolute path of the running executable (for argv[0]). + static constexpr uint64_t SYS_GETEXECPATH = 151; // (index, flags) -> new front index; index=-1 queries support (1/0); flags bit0 = wait vsync // Tunable parameters (for SYS_SDR_SETPARAM / SYS_SDR_GETPARAM). static constexpr int SDR_PARAM_FREQ = 0; // center frequency, Hz diff --git a/programs/GNUmakefile b/programs/GNUmakefile index d12b293..5cc1ade 100644 --- a/programs/GNUmakefile +++ b/programs/GNUmakefile @@ -405,6 +405,7 @@ ifneq ($(wildcard $(NATIVE_BIN)/as),) cp -r ../toolchain/local/x86_64-montauk/include/c++ $(BINDIR)/sdk/include/c++ ../toolchain/local/bin/x86_64-montauk-gcc -O2 ../toolchain/files/tls-test.c -o $(BINDIR)/sdk/bin/tls-test.elf ../toolchain/local/bin/x86_64-montauk-g++ -O2 ../toolchain/files/cxx-test.cpp -o $(BINDIR)/sdk/bin/cxx-test.elf + ../toolchain/local/bin/x86_64-montauk-gcc -O2 ../toolchain/files/sdk-diag.c -o $(BINDIR)/sdk/bin/sdk-diag.elf ifneq ($(wildcard ../toolchain/native-gcc/sdk/bin/gcc),) cp ../toolchain/native-gcc/sdk/bin/gcc $(BINDIR)/sdk/bin/gcc.elf cp ../toolchain/native-gcc/sdk/bin/g++ $(BINDIR)/sdk/bin/g++.elf diff --git a/programs/include/Api/Syscall.hpp b/programs/include/Api/Syscall.hpp index 69eebb6..ed6c29a 100644 --- a/programs/include/Api/Syscall.hpp +++ b/programs/include/Api/Syscall.hpp @@ -204,7 +204,10 @@ namespace montauk::abi { static constexpr uint64_t SYS_POWERINFO = 149; // (PowerInfo*) -> 0, -1 unsupported // Framebuffer page flip (double-buffered scanout) - static constexpr uint64_t SYS_FBFLIP = 150; // (index, flags) -> new front index; index=-1 queries support (1/0); flags bit0 = wait vsync + static constexpr uint64_t SYS_FBFLIP = 150; + + // Absolute path of the running executable (for argv[0]). + static constexpr uint64_t SYS_GETEXECPATH = 151; // (index, flags) -> new front index; index=-1 queries support (1/0); flags bit0 = wait vsync // Tunable parameters (for SYS_SDR_SETPARAM / SYS_SDR_GETPARAM). static constexpr int SDR_PARAM_FREQ = 0; // center frequency, Hz diff --git a/programs/include/libc/montauk.h b/programs/include/libc/montauk.h index ace118d..1ac8066 100644 --- a/programs/include/libc/montauk.h +++ b/programs/include/libc/montauk.h @@ -174,6 +174,7 @@ extern "C" { #define MTK_SYS_SDR_GETPARAM 148 #define MTK_SYS_POWERINFO 149 #define MTK_SYS_FBFLIP 150 +#define MTK_SYS_GETEXECPATH 151 /* @SYSCALLS-END */ #define MTK_SOCK_TCP 1 @@ -410,6 +411,10 @@ static inline int mtk_getargs(char *buf, unsigned long max_len) { return (int)_mtk_syscall2(MTK_SYS_GETARGS, (long)buf, (long)max_len); } +static inline int mtk_getexecpath(char *buf, unsigned long maxLen) { + return (int)mtk_syscall2(MTK_SYS_GETEXECPATH, (long)buf, (long)maxLen); +} + static inline int mtk_chdir(const char *path) { return (int)_mtk_syscall1(MTK_SYS_CHDIR, (long)path); } diff --git a/programs/lib/libc/crt/crt1.c b/programs/lib/libc/crt/crt1.c index a84d705..0a87d62 100644 --- a/programs/lib/libc/crt/crt1.c +++ b/programs/lib/libc/crt/crt1.c @@ -31,8 +31,9 @@ static inline long _sys2(long nr, long a1, long a2) { return ret; } -#define SYS_EXIT 0 -#define SYS_GETARGS 25 +#define SYS_EXIT 0 +#define SYS_GETARGS 25 +#define SYS_GETEXECPATH 151 extern int main(int argc, char** argv); @@ -71,12 +72,17 @@ static void _run_fini_array(void) { void _start(void) { /* Static: 4 KiB args + 256 argv slots would crowd a 32 KiB stack. */ static char argbuf[4096]; + static char pathbuf[256]; static char* argv[256]; int len = (int)_sys2(SYS_GETARGS, (long)argbuf, (long)sizeof(argbuf)); int argc = 0; - argv[argc++] = (char*)"prog"; + /* Real argv[0]: tools like the GCC driver relocate their install + prefix from it, so "prog" placeholders send them to garbage + paths. Fall back to "prog" on kernels without the syscall. */ + int plen = (int)_sys2(SYS_GETEXECPATH, (long)pathbuf, (long)sizeof(pathbuf)); + argv[argc++] = (plen > 0) ? pathbuf : (char*)"prog"; if (len > 0) { if (len > (int)sizeof(argbuf) - 1) { diff --git a/programs/lib/libc/crt1.o b/programs/lib/libc/crt1.o index 4b057b8..ef5b27c 100644 Binary files a/programs/lib/libc/crt1.o and b/programs/lib/libc/crt1.o differ diff --git a/programs/libs/libprintersapplet/obj/src/libprintersapplet.o b/programs/libs/libprintersapplet/obj/src/libprintersapplet.o index 8b60005..3b3f633 100644 Binary files a/programs/libs/libprintersapplet/obj/src/libprintersapplet.o and b/programs/libs/libprintersapplet/obj/src/libprintersapplet.o differ diff --git a/programs/libs/libtimezonesapplet/obj/src/libtimezonesapplet.o b/programs/libs/libtimezonesapplet/obj/src/libtimezonesapplet.o index 4f10ca1..fdd6dd9 100644 Binary files a/programs/libs/libtimezonesapplet/obj/src/libtimezonesapplet.o and b/programs/libs/libtimezonesapplet/obj/src/libtimezonesapplet.o differ diff --git a/toolchain/files/sdk-diag.c b/toolchain/files/sdk-diag.c new file mode 100644 index 0000000..8298c48 --- /dev/null +++ b/toolchain/files/sdk-diag.c @@ -0,0 +1,44 @@ +/* + * sdk-diag.c + * Probes the exact libc/kernel layers the GCC driver depends on: + * access/stat on the compiler backends, and a direct posix_spawn + * of cc1plus. Prints one line per probe. +*/ + +#include +#include +#include +#include +#include + +#define CC1PLUS "/sdk/libexec/gcc/x86_64-montauk/14.2.0/cc1plus" + +static void probe(const char *p) { + struct stat st; + int a = access(p, X_OK); + int s = stat(p, &st); + printf("%-52s access=%d stat=%d", p, a, s); + if (s == 0) { + printf(" mode=%o size=%ld", (unsigned)st.st_mode, (long)st.st_size); + } + printf("\n"); +} + +int main(void) { + probe(CC1PLUS); + probe("/sdk/libexec/gcc/x86_64-montauk/14.2.0"); + probe("/sdk/libexec/gcc"); + probe("/sdk/bin/as.elf"); + probe("/tmp"); + + pid_t pid = -1; + char *argv[] = { (char *)"cc1plus", (char *)"--version", 0 }; + int r = posix_spawn(&pid, CC1PLUS, 0, 0, argv, 0); + printf("posix_spawn(cc1plus --version) = %d pid=%d\n", r, (int)pid); + if (r == 0) { + int st = -1; + waitpid(pid, &st, 0); + printf("cc1plus wait status = %d (exit %d)\n", st, (st >> 8) & 0xFF); + } + return 0; +}