mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-08-02 07:50:31 +00:00
Add optional uname kernel check for non-ape loader
ELF executables of the same architecture lack mechanisms to specify the host operating system they are built for. As an example, SerenityOS and Linux both specify SYSV in the OSABI field, and while Linux specifies a .note.ABI-tag, SerenityOS lacks one altogether. Therefore, we do not do autodetection of the target kernel from provided loaders, and defer the matching of loaders to uname -s to the user.
This commit is contained in:
parent
b235492e71
commit
c90daf5296
1 changed files with 55 additions and 7 deletions
|
@ -85,6 +85,13 @@
|
|||
" executable will self-modify its header on\n" \
|
||||
" the first run, to use the platform format\n" \
|
||||
"\n" \
|
||||
" -k KERNEL test for maching kernel name [repeatable]\n" \
|
||||
" when set, the shell script for subsequent\n" \
|
||||
" loader executables will check if uname -s\n" \
|
||||
" output matches the kernel string, only if\n" \
|
||||
" the loader executable architecture is not\n" \
|
||||
" an architecture in the input binary list\n" \
|
||||
"\n" \
|
||||
" -M PATH bundle ape loader source code file for m1\n" \
|
||||
" processors running the xnu kernel so that\n" \
|
||||
" it can be compiled on the fly by xcode\n" \
|
||||
|
@ -213,6 +220,7 @@ struct Loader {
|
|||
char *ddarg_size1;
|
||||
char *ddarg_skip2;
|
||||
char *ddarg_size2;
|
||||
char kernel[64];
|
||||
};
|
||||
|
||||
struct Loaders {
|
||||
|
@ -244,6 +252,7 @@ static struct Inputs inputs;
|
|||
static char ape_heredoc[15];
|
||||
static enum Strategy strategy;
|
||||
static struct Loaders loaders;
|
||||
static char loader_kernel[64] = {'\0'};
|
||||
static const char *custom_sh_code;
|
||||
static bool force_bypass_binfmt_misc;
|
||||
static bool generate_debuggable_binary;
|
||||
|
@ -979,13 +988,24 @@ static void AddLoader(const char *path) {
|
|||
if (loaders.n == ARRAYLEN(loaders.p)) {
|
||||
Die(prog, "too many loaders");
|
||||
}
|
||||
loaders.p[loaders.n++].path = path;
|
||||
struct Loader *loader = &loaders.p[loaders.n++];
|
||||
loader->path = path;
|
||||
if (loader_kernel[0] != '\0') {
|
||||
strncpy(loader->kernel, loader_kernel, sizeof(loader->kernel));
|
||||
} else {
|
||||
loader->kernel[0] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
static void SetLoaderKernel(const char *kernel) {
|
||||
strncpy(loader_kernel, kernel, sizeof(loader_kernel));
|
||||
loader_kernel[sizeof(loader_kernel) - 1] = 0;
|
||||
}
|
||||
|
||||
static void GetOpts(int argc, char *argv[]) {
|
||||
int opt, bits;
|
||||
bool got_support_vector = false;
|
||||
while ((opt = getopt(argc, argv, "hvgsGBo:l:S:M:V:")) != -1) {
|
||||
while ((opt = getopt(argc, argv, "hvgsGBo:l:k:S:M:V:")) != -1) {
|
||||
switch (opt) {
|
||||
case 'o':
|
||||
outpath = optarg;
|
||||
|
@ -1009,6 +1029,10 @@ static void GetOpts(int argc, char *argv[]) {
|
|||
HashInputString("-l");
|
||||
AddLoader(optarg);
|
||||
break;
|
||||
case 'k':
|
||||
HashInputString("-k");
|
||||
SetLoaderKernel(optarg);
|
||||
break;
|
||||
case 'S':
|
||||
HashInputString("-S");
|
||||
HashInputString(optarg);
|
||||
|
@ -1632,16 +1656,24 @@ 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");
|
||||
p = stpcpy(p, "if [ \"$m\" = x86_64 ] || [ \"$m\" = amd64 ]");
|
||||
} else if (loader->machine == EM_AARCH64) {
|
||||
return stpcpy(p, "if [ \"$m\" = aarch64 ] || [ \"$m\" = arm64 ]; then\n");
|
||||
p = stpcpy(p, "if [ \"$m\" = aarch64 ] || [ \"$m\" = arm64 ]");
|
||||
} else if (loader->machine == EM_PPC64) {
|
||||
return stpcpy(p, "if [ \"$m\" = ppc64le ]; then\n");
|
||||
p = stpcpy(p, "if [ \"$m\" = ppc64le ]");
|
||||
} else if (loader->machine == EM_MIPS) {
|
||||
return stpcpy(p, "if [ \"$m\" = mips64 ]; then\n");
|
||||
p = stpcpy(p, "if [ \"$m\" = mips64 ]");
|
||||
} else {
|
||||
Die(loader->path, "unsupported cpu architecture");
|
||||
}
|
||||
|
||||
if (loader->kernel[0] != '\0') {
|
||||
p = stpcpy(p, " && [ \"$k\" = ");
|
||||
p = stpcpy(p, loader->kernel);
|
||||
p = stpcpy(p, " ]");
|
||||
}
|
||||
|
||||
return stpcpy(p, "; then\n");
|
||||
}
|
||||
|
||||
static char *FinishGeneratingDosHeader(char *p) {
|
||||
|
@ -1892,7 +1924,9 @@ int main(int argc, char *argv[]) {
|
|||
for (i = 0; i < loaders.n; ++i) {
|
||||
for (j = i + 1; j < loaders.n; ++j) {
|
||||
if (loaders.p[i].os == loaders.p[j].os &&
|
||||
loaders.p[i].machine == loaders.p[j].machine) {
|
||||
loaders.p[i].machine == loaders.p[j].machine &&
|
||||
strncmp(loaders.p[i].kernel, loaders.p[j].kernel,
|
||||
sizeof(loaders.p[i].kernel)) == 0) {
|
||||
Die(prog, "multiple ape loaders specified for the same platform");
|
||||
}
|
||||
}
|
||||
|
@ -2206,6 +2240,20 @@ int main(int argc, char *argv[]) {
|
|||
}
|
||||
|
||||
// extract the ape loader for non-input architectures
|
||||
// if the user requested a host kernel check, get the host kernel
|
||||
if (loader_kernel[0] != '\0') {
|
||||
bool hasunused = false;
|
||||
for (i = 0; i < loaders.n; ++i) {
|
||||
struct Loader *loader = loaders.p + i;
|
||||
if (!loader->used) {
|
||||
hasunused = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (hasunused) {
|
||||
p = stpcpy(p, "k=$(uname -s 2>/dev/null) || k=unknown\n");
|
||||
}
|
||||
}
|
||||
for (i = 0; i < loaders.n; ++i) {
|
||||
struct Loader *loader = loaders.p + i;
|
||||
if (loader->used) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue