feat: port gcc to MontaukOS
This commit is contained in:
@@ -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 };
|
||||
|
||||
Reference in New Issue
Block a user