diff --git a/third_party/chibicc/as.c b/third_party/chibicc/as.c index e05283875..4fe77a26f 100644 --- a/third_party/chibicc/as.c +++ b/third_party/chibicc/as.c @@ -3944,7 +3944,7 @@ static void Objectify(struct As *a, int path) { char *p; int i, j, s, e; struct ElfWriter *elf; - elf = elfwriter_open(a->strings.p[path], 0644); + elf = elfwriter_open(a->strings.p[path], 0644, EM_NEXGEN32E); for (i = 0; i < a->symbols.n; ++i) { if (!IsLiveSymbol(a, i)) continue; p = strndup(a->slices.p[a->symbols.p[i].name].p, diff --git a/third_party/python/pyobj.c b/third_party/python/pyobj.c index 26aca6d11..4367b22a0 100644 --- a/third_party/python/pyobj.c +++ b/third_party/python/pyobj.c @@ -646,7 +646,7 @@ Objectify(void) memcpy(pycdata + sizeof(header), mardata, marsize); yoinked = newinterner(); forcepulls = newinterner(); - elf = elfwriter_open(outpath, 0644); + elf = elfwriter_open(outpath, 0644, 0); elfwriter_cargoculting(elf); if (ispkg) { elfwriter_zip(elf, zipdir, zipdir, strlen(zipdir), diff --git a/tool/build/lib/elfwriter.c b/tool/build/lib/elfwriter.c index 6af6d849c..20b4a7748 100644 --- a/tool/build/lib/elfwriter.c +++ b/tool/build/lib/elfwriter.c @@ -156,7 +156,7 @@ static void FlushTables(struct ElfWriter *elf) { elfwriter_commit(elf, size); } -struct ElfWriter *elfwriter_open(const char *path, int mode) { +struct ElfWriter *elfwriter_open(const char *path, int mode, int arch) { struct ElfWriter *elf; CHECK_NOTNULL((elf = calloc(1, sizeof(struct ElfWriter)))); CHECK_NOTNULL((elf->path = strdup(path))); @@ -166,15 +166,22 @@ struct ElfWriter *elfwriter_open(const char *path, int mode) { elf->mapsize, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, elf->fd, 0))); elf->ehdr = memcpy(elf->map, &kObjHeader, (elf->wrote = sizeof(kObjHeader))); - if (strstr(path, "/aarch64")) { - elf->ehdr->e_machine = EM_AARCH64; - } else if (strstr(path, "/powerpc64")) { - elf->ehdr->e_machine = EM_PPC64; - } else if (strstr(path, "/riscv")) { - elf->ehdr->e_machine = EM_RISCV; - } else if (strstr(path, "/s390")) { + if (!arch) { +#ifdef __x86_64__ + arch = EM_NEXGEN32E; +#elif defined(__aarch64__) + arch = EM_AARCH64; +#elif defined(__powerpc64__) + arch = EM_PPC64; +#elif defined(__riscv) + arch = EM_RISCV; +#elif defined(__s390x__) elf->ehdr->e_machine = EM_S390; +#else +#error "unsupported architecture" +#endif } + elf->ehdr->e_machine = arch; elf->strtab = newinterner(); elf->shstrtab = newinterner(); intern(elf->strtab, ""); diff --git a/tool/build/lib/elfwriter.h b/tool/build/lib/elfwriter.h index 4a9c8439c..5bed297be 100644 --- a/tool/build/lib/elfwriter.h +++ b/tool/build/lib/elfwriter.h @@ -54,7 +54,7 @@ struct ElfWriter { struct Interner *shstrtab; }; -struct ElfWriter *elfwriter_open(const char *, int) __wur; +struct ElfWriter *elfwriter_open(const char *, int, int) __wur; void elfwriter_cargoculting(struct ElfWriter *); void elfwriter_close(struct ElfWriter *); void elfwriter_align(struct ElfWriter *, size_t, size_t); diff --git a/tool/build/zipobj.c b/tool/build/zipobj.c index b9cac3fc9..7d09a9300 100644 --- a/tool/build/zipobj.c +++ b/tool/build/zipobj.c @@ -43,6 +43,7 @@ #include "tool/build/lib/elfwriter.h" #include "tool/build/lib/stripcomponents.h" +int arch_; char *name_; char *yoink_; char *symbol_; @@ -76,6 +77,7 @@ FLAGS\n\ -o PATH output path\n\ -0 disable compression\n\ -B basename-ify zip filename\n\ + -a ARCH microprocessor architecture\n\ -N ZIPPATH zip filename (defaults to input arg)\n\ -P ZIPPATH prepend path zip filename using join\n\ -C INTEGER strips leading path components from zip filename\n\ @@ -86,14 +88,34 @@ FLAGS\n\ exit(rc); } +static int ParseArch(const char *s) { + if (startswith(s, "x86")) { + return EM_NEXGEN32E; + } else if (startswith(s, "arm") || !strcmp(s, "aarch64")) { + return EM_AARCH64; + } else if (startswith(s, "ppc") || startswith(s, "powerpc")) { + return EM_PPC64; + } else if (startswith(s, "riscv")) { + return EM_RISCV; + } else if (startswith(s, "s390")) { + return EM_S390; + } else { + tinyprint(2, "error: unrecognized microprocessor architecture\n", NULL); + exit(1); + } +} + void GetOpts(int *argc, char ***argv) { int opt; yoink_ = "__zip_eocd"; - while ((opt = getopt(*argc, *argv, "?0nhBN:C:P:o:s:y:")) != -1) { + while ((opt = getopt(*argc, *argv, "?0nhBN:C:P:o:s:y:a:")) != -1) { switch (opt) { case 'o': outpath_ = optarg; break; + case 'a': + arch_ = ParseArch(optarg); + break; case 'n': exit(0); case 's': @@ -192,18 +214,18 @@ void PullEndOfCentralDirectoryIntoLinkage(struct ElfWriter *elf) { } void CheckFilenameKosher(const char *path) { - CHECK_LE(kZipCfileHdrMinSize + strlen(path), 65535); - CHECK(!startswith(path, "/")); - CHECK(!strstr(path, "..")); + unassert(kZipCfileHdrMinSize + strlen(path) <= 65535); + unassert(!startswith(path, "/")); + unassert(!strstr(path, "..")); } void zipobj(int argc, char **argv) { size_t i; struct ElfWriter *elf; - CHECK_LT(argc, UINT16_MAX / 3 - 64); /* ELF 64k section limit */ + unassert(argc < UINT16_MAX / 3 - 64); /* ELF 64k section limit */ GetOpts(&argc, &argv); for (i = 0; i < argc; ++i) CheckFilenameKosher(argv[i]); - elf = elfwriter_open(outpath_, 0644); + elf = elfwriter_open(outpath_, 0644, arch_); elfwriter_cargoculting(elf); for (i = 0; i < argc; ++i) ProcessFile(elf, argv[i]); PullEndOfCentralDirectoryIntoLinkage(elf); @@ -211,7 +233,6 @@ void zipobj(int argc, char **argv) { } int main(int argc, char **argv) { - ShowCrashReports(); timestamp.tv_sec = 1647414000; /* determinism */ /* clock_gettime(CLOCK_REALTIME, ×tamp); */ zipobj(argc, argv);