Support additional architectures in apelink (#1381)
Some checks failed
build / matrix_on_mode () (push) Has been cancelled
build / matrix_on_mode (optlinux) (push) Has been cancelled
build / matrix_on_mode (rel) (push) Has been cancelled
build / matrix_on_mode (tiny) (push) Has been cancelled
build / matrix_on_mode (tinylinux) (push) Has been cancelled

This updates apelink to support machine architectures not in the source
program input list by adding additional loaders, extracting the correct
one that matches the host uname machine. With this change, blink can be
supplied as the additional loader to run the program in x86_64 VMs. The
change has been verified against blink 1.0, powerpc64le and mips64el in
Docker using QEMU.
This commit is contained in:
Brett Jia 2025-03-06 13:26:31 -05:00 committed by GitHub
parent 38930de8e0
commit fc81fd8d16
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 41 additions and 0 deletions

View file

@ -68,6 +68,7 @@
#define EM_NONE 0
#define EM_M32 1
#define EM_386 3
#define EM_MIPS 8
#define EM_PPC64 21
#define EM_S390 22
#define EM_ARM 40

View file

@ -1630,6 +1630,20 @@ static char *GenerateScriptIfMachine(char *p, struct Input *in) {
}
}
static char *GenerateScriptIfLoaderMachine(char *p, struct Loader *loader) {
if (loader->machine == EM_NEXGEN32E) {
return stpcpy(p, "if [ \"$m\" = x86_64 ] || [ \"$m\" = amd64 ]; then\n");
} else if (loader->machine == EM_AARCH64) {
return stpcpy(p, "if [ \"$m\" = aarch64 ] || [ \"$m\" = arm64 ]; then\n");
} else if (loader->machine == EM_PPC64) {
return stpcpy(p, "if [ \"$m\" = ppc64le ]; then\n");
} else if (loader->machine == EM_MIPS) {
return stpcpy(p, "if [ \"$m\" = mips64 ]; then\n");
} else {
Die(loader->path, "unsupported cpu architecture");
}
}
static char *FinishGeneratingDosHeader(char *p) {
p = WRITE16LE(p, 0x1000); // 10: MZ: lowers upper bound load / 16
p = WRITE16LE(p, 0xf800); // 12: MZ: roll greed on bss
@ -2190,6 +2204,32 @@ int main(int argc, char *argv[]) {
gotsome = true;
}
}
// extract the ape loader for non-input architectures
for (i = 0; i < loaders.n; ++i) {
struct Loader *loader = loaders.p + i;
if (loader->used) {
continue;
}
loader->used = true;
p = GenerateScriptIfLoaderMachine(p, loader);
p = stpcpy(p, "mkdir -p \"${t%/*}\" ||exit\n"
"dd if=\"$o\"");
p = stpcpy(p, " skip=");
loader->ddarg_skip2 = p;
p = GenerateDecimalOffsetRelocation(p);
p = stpcpy(p, " count=");
loader->ddarg_size2 = p;
p = GenerateDecimalOffsetRelocation(p);
p = stpcpy(p, " bs=1 2>/dev/null | gzip -dc >\"$t.$$\" ||exit\n"
"chmod 755 \"$t.$$\" ||exit\n"
"mv -f \"$t.$$\" \"$t\" ||exit\n");
p = stpcpy(p, "exec \"$t\" \"$o\" \"$@\"\n"
"fi\n");
gotsome = true;
}
// close if-statements
if (inputs.n && (support_vector & _HOSTXNU)) {
if (!gotsome) {
p = stpcpy(p, "true\n");