feat: port gcc to MontaukOS

This commit is contained in:
2026-07-17 15:47:45 +02:00
parent 324b18edda
commit 8e6b619b02
14 changed files with 493 additions and 19 deletions
+96 -2
View File
@@ -1,17 +1,22 @@
/*
* 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.
* access/stat on the compiler backends, a direct posix_spawn of
* cc1plus, and BFD-style ar archive reads on /sdk/lib/libc.a
* (armap, member header at an armap offset, nested second fopen
* of the same file, member ELF magic). Prints one line per probe.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <spawn.h>
#include <sys/wait.h>
#define CC1PLUS "/sdk/libexec/gcc/x86_64-montauk/14.2.0/cc1plus"
#define LIBC_A_DOTS "/sdk/bin/../lib/gcc/x86_64-montauk/14.2.0/../../../libc.a"
static void probe(const char *p) {
struct stat st;
@@ -24,12 +29,101 @@ static void probe(const char *p) {
printf("\n");
}
/* Replay the sequence BFD/ld performs on an ar archive. Each step
prints ok/FAIL so the first broken layer is visible directly. */
static void ar_probe(const char *path) {
unsigned char buf[64];
char hdr[61];
long armap_size, member_off, member_size, i;
printf("ar_probe %s\n", path);
FILE *f = fopen(path, "rb");
if (f == NULL) { printf(" FAIL fopen\n"); return; }
/* Global magic */
if (fread(buf, 1, 8, f) != 8) { printf(" FAIL read magic\n"); fclose(f); return; }
printf(" magic %s: %.7s\n", memcmp(buf, "!<arch>\n", 8) == 0 ? "ok" : "FAIL", (char *)buf);
/* Armap ("/") member header at offset 8; size at header offset 48 */
if (fseek(f, 8, SEEK_SET) != 0 || fread(hdr, 1, 60, f) != 60) {
printf(" FAIL read armap header\n"); fclose(f); return;
}
hdr[60] = '\0';
armap_size = strtol(hdr + 48, NULL, 10);
printf(" armap hdr %s: name='%.4s' size=%ld fmag=%s\n",
hdr[0] == '/' ? "ok" : "FAIL", hdr, armap_size,
(hdr[58] == 0x60 && hdr[59] == '\n') ? "ok" : "FAIL");
/* First armap entry: 4-byte BE count, then BE member offsets */
if (fread(buf, 1, 8, f) != 8) { printf(" FAIL read armap data\n"); fclose(f); return; }
member_off = ((long)buf[4] << 24) | ((long)buf[5] << 16) | ((long)buf[6] << 8) | (long)buf[7];
printf(" armap syms=%ld first member offset=%ld\n",
((long)buf[0] << 24) | ((long)buf[1] << 16) | ((long)buf[2] << 8) | (long)buf[3],
member_off);
/* Member header at the armap offset, via the SAME stream */
if (fseek(f, member_off, SEEK_SET) != 0 || fread(hdr, 1, 60, f) != 60) {
printf(" FAIL read member header\n"); fclose(f); return;
}
hdr[60] = '\0';
member_size = strtol(hdr + 48, NULL, 10);
printf(" member hdr: name='%.16s' size=%ld fmag=%s\n",
hdr, member_size, (hdr[58] == 0x60 && hdr[59] == '\n') ? "ok" : "FAIL");
/* Nested second fopen of the same archive (ld does this per member),
ELF magic read at the member data offset while `f` stays open. */
FILE *g = fopen(path, "rb");
if (g == NULL) { printf(" FAIL nested fopen\n"); fclose(f); return; }
if (fseek(g, member_off + 60, SEEK_SET) != 0 || fread(buf, 1, 16, g) != 16) {
printf(" FAIL nested read\n"); fclose(g); fclose(f); return;
}
printf(" member ELF magic %s:", memcmp(buf, "\177ELF", 4) == 0 ? "ok" : "FAIL");
for (i = 0; i < 8; i++) printf(" %02x", buf[i]);
printf("\n");
/* Whole-member read through the nested stream + checksum */
{
unsigned long sum = 0;
long total = 0;
if (fseek(g, member_off + 60, SEEK_SET) != 0) { printf(" FAIL re-seek\n"); }
while (total < member_size) {
unsigned char chunk[4096];
long want = member_size - total;
size_t got;
if (want > (long)sizeof(chunk)) want = sizeof(chunk);
got = fread(chunk, 1, (size_t)want, g);
if (got == 0) break;
for (i = 0; i < (long)got; i++) sum = sum * 31 + chunk[i];
total += (long)got;
}
printf(" member read %ld/%ld bytes %s (sum=%08lx)\n",
total, member_size, total == member_size ? "ok" : "FAIL", sum);
}
/* Interleave: original stream must still read correctly after the
nested stream was used (independent positions). */
if (fseek(f, 0, SEEK_SET) == 0 && fread(buf, 1, 8, f) == 8) {
printf(" interleaved re-read %s\n", memcmp(buf, "!<arch>\n", 8) == 0 ? "ok" : "FAIL");
} else {
printf(" FAIL interleaved re-read\n");
}
fclose(g);
fclose(f);
}
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");
probe("/sdk/lib/libc.a");
probe(LIBC_A_DOTS);
ar_probe("/sdk/lib/libc.a");
ar_probe(LIBC_A_DOTS);
pid_t pid = -1;
char *argv[] = { (char *)"cc1plus", (char *)"--version", 0 };