mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-02-24 06:49:02 +00:00
Do better job documenting platform issues
This commit is contained in:
parent
eea601f346
commit
9f9aec013a
5 changed files with 97 additions and 25 deletions
35
README.md
35
README.md
|
@ -200,23 +200,42 @@ gdb foo.com -ex 'add-symbol-file foo.com.dbg 0x401000'
|
||||||
|
|
||||||
### Linux
|
### Linux
|
||||||
|
|
||||||
Linux systems with WINE installed might have issues running APE programs
|
Some Linux systems are configured to launch MZ executables under WINE.
|
||||||
if WINE is registered with `binnfmt_misc`. To work around this, you need
|
Other distros configure their stock installs so that APE programs will
|
||||||
to remove WINE from `binfmt_misc`. You could also disable `binfmt_misc`
|
print "run-detectors: unable to find an interpreter". For example:
|
||||||
entirely.
|
|
||||||
|
|
||||||
|
```sh
|
||||||
|
jart@ubuntu:~$ wget https://cosmo.zip/pub/cosmos/bin/dash
|
||||||
|
jart@ubuntu:~$ chmod +x dash
|
||||||
|
jart@ubuntu:~$ ./dash
|
||||||
|
run-detectors: unable to find an interpreter for ./dash
|
||||||
```
|
```
|
||||||
sudo sh -c 'echo 0 > /proc/sys/fs/binfmt_misc/status'
|
|
||||||
|
You can fix that by registering APE with `binfmt_misc`:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sudo wget -O /usr/bin/ape https://cosmo.zip/pub/cosmos/bin/ape-$(uname -m).elf
|
||||||
|
sudo sh -c "echo ':APE:M::MZqFpD::/usr/bin/ape:' >/proc/sys/fs/binfmt_misc/register"
|
||||||
|
sudo sh -c "echo ':APE-jart:M::jartsr::/usr/bin/ape:' >/proc/sys/fs/binfmt_misc/register"
|
||||||
|
```
|
||||||
|
|
||||||
|
You should be good now. APE will not only work, it'll launch executables
|
||||||
|
400µs faster now too. However if things still didn't work out, it's also
|
||||||
|
possible to disable `binfmt_misc` as follows:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sudo sh -c 'echo -1 > /proc/sys/fs/binfmt_misc/cli' # remove Ubuntu's MZ interpreter
|
||||||
|
sudo sh -c 'echo -1 > /proc/sys/fs/binfmt_misc/status' # remove ALL binfmt_misc entries
|
||||||
```
|
```
|
||||||
|
|
||||||
### WSL
|
### WSL
|
||||||
|
|
||||||
It's normally unsafe to use APE in a WSL environment, because it tries
|
It's normally unsafe to use APE in a WSL environment, because it tries
|
||||||
to run them as WIN32 binaries within the WSL environment. In order to
|
to run MZ executables as WIN32 binaries within the WSL environment. In
|
||||||
make it safe to use Cosmopolitan software on WSL, you have to run:
|
order to make it safe to use Cosmopolitan software on WSL, run this:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
sh -c "echo -1 > /proc/sys/fs/binfmt_misc/WSLInterop"
|
sudo sh -c "echo -1 > /proc/sys/fs/binfmt_misc/WSLInterop"
|
||||||
```
|
```
|
||||||
|
|
||||||
## Discord Chatroom
|
## Discord Chatroom
|
||||||
|
|
|
@ -32,6 +32,15 @@ _apple: mov $_HOSTXNU,%cl
|
||||||
.endfn _apple,weak,hidden
|
.endfn _apple,weak,hidden
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if SupportsWindows() && defined(__x86_64__) && !IsTiny()
|
||||||
|
// implements all win32 apis on non-windows hosts
|
||||||
|
// it is just enough code to get a good backtrace
|
||||||
|
__oops_win32:
|
||||||
|
ud2
|
||||||
|
nop
|
||||||
|
.endfn __oops_win32
|
||||||
|
#endif
|
||||||
|
|
||||||
// System Five userspace program entrypoint.
|
// System Five userspace program entrypoint.
|
||||||
//
|
//
|
||||||
// @param rsp is [n,argv₀..argvₙ₋₁,0,envp₀..,0,auxv₀..,0,..]
|
// @param rsp is [n,argv₀..argvₙ₋₁,0,envp₀..,0,auxv₀..,0,..]
|
||||||
|
@ -76,7 +85,6 @@ _start:
|
||||||
// make win32 imps crash
|
// make win32 imps crash
|
||||||
.weak ape_idata_iat
|
.weak ape_idata_iat
|
||||||
.weak ape_idata_iatend
|
.weak ape_idata_iatend
|
||||||
.weak __oops_win32
|
|
||||||
ezlea __oops_win32,ax
|
ezlea __oops_win32,ax
|
||||||
ezlea ape_idata_iat,di
|
ezlea ape_idata_iat,di
|
||||||
ezlea ape_idata_iatend,cx
|
ezlea ape_idata_iatend,cx
|
||||||
|
|
|
@ -23,7 +23,6 @@
|
||||||
#include "libc/intrin/nomultics.internal.h"
|
#include "libc/intrin/nomultics.internal.h"
|
||||||
#include "libc/intrin/weaken.h"
|
#include "libc/intrin/weaken.h"
|
||||||
#include "libc/limits.h"
|
#include "libc/limits.h"
|
||||||
#include "libc/log/libfatal.internal.h"
|
|
||||||
#include "libc/macros.internal.h"
|
#include "libc/macros.internal.h"
|
||||||
#include "libc/nexgen32e/rdtsc.h"
|
#include "libc/nexgen32e/rdtsc.h"
|
||||||
#include "libc/nt/console.h"
|
#include "libc/nt/console.h"
|
||||||
|
@ -45,7 +44,6 @@
|
||||||
#include "libc/sock/internal.h"
|
#include "libc/sock/internal.h"
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
#include "libc/sysv/consts/prot.h"
|
#include "libc/sysv/consts/prot.h"
|
||||||
|
|
||||||
#ifdef __x86_64__
|
#ifdef __x86_64__
|
||||||
|
|
||||||
#define abi __msabi textwindows dontinstrument
|
#define abi __msabi textwindows dontinstrument
|
||||||
|
@ -55,6 +53,7 @@ __msabi extern typeof(CreateFileMapping) *const __imp_CreateFileMappingW;
|
||||||
__msabi extern typeof(DuplicateHandle) *const __imp_DuplicateHandle;
|
__msabi extern typeof(DuplicateHandle) *const __imp_DuplicateHandle;
|
||||||
__msabi extern typeof(FreeEnvironmentStrings) *const __imp_FreeEnvironmentStringsW;
|
__msabi extern typeof(FreeEnvironmentStrings) *const __imp_FreeEnvironmentStringsW;
|
||||||
__msabi extern typeof(GetConsoleMode) *const __imp_GetConsoleMode;
|
__msabi extern typeof(GetConsoleMode) *const __imp_GetConsoleMode;
|
||||||
|
__msabi extern typeof(GetCurrentDirectory) *const __imp_GetCurrentDirectoryW;
|
||||||
__msabi extern typeof(GetCurrentProcessId) *const __imp_GetCurrentProcessId;
|
__msabi extern typeof(GetCurrentProcessId) *const __imp_GetCurrentProcessId;
|
||||||
__msabi extern typeof(GetEnvironmentStrings) *const __imp_GetEnvironmentStringsW;
|
__msabi extern typeof(GetEnvironmentStrings) *const __imp_GetEnvironmentStringsW;
|
||||||
__msabi extern typeof(GetEnvironmentVariable) *const __imp_GetEnvironmentVariableW;
|
__msabi extern typeof(GetEnvironmentVariable) *const __imp_GetEnvironmentVariableW;
|
||||||
|
@ -67,6 +66,7 @@ __msabi extern typeof(SetConsoleOutputCP) *const __imp_SetConsoleOutputCP;
|
||||||
__msabi extern typeof(SetEnvironmentVariable) *const __imp_SetEnvironmentVariableW;
|
__msabi extern typeof(SetEnvironmentVariable) *const __imp_SetEnvironmentVariableW;
|
||||||
__msabi extern typeof(SetStdHandle) *const __imp_SetStdHandle;
|
__msabi extern typeof(SetStdHandle) *const __imp_SetStdHandle;
|
||||||
__msabi extern typeof(VirtualProtect) *const __imp_VirtualProtect;
|
__msabi extern typeof(VirtualProtect) *const __imp_VirtualProtect;
|
||||||
|
__msabi extern typeof(WriteFile) *const __imp_WriteFile;
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
void cosmo(int, char **, char **, long (*)[2]) wontreturn;
|
void cosmo(int, char **, char **, long (*)[2]) wontreturn;
|
||||||
|
@ -88,9 +88,33 @@ __funline char16_t *MyCommandLine(void) {
|
||||||
return cmd;
|
return cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
// implements all win32 apis on non-windows hosts
|
static abi char16_t *StrStr(const char16_t *haystack, const char16_t *needle) {
|
||||||
static abi long __oops_win32(void) {
|
size_t i;
|
||||||
notpossible;
|
for (;;) {
|
||||||
|
for (i = 0;; ++i) {
|
||||||
|
if (!needle[i]) return (/*unconst*/ char16_t *)haystack;
|
||||||
|
if (!haystack[i]) break;
|
||||||
|
if (needle[i] != haystack[i]) break;
|
||||||
|
}
|
||||||
|
if (!*haystack++) break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static abi void PrintError(const char *s, size_t n) {
|
||||||
|
#define PrintError(s) PrintError(s, sizeof(s) - 1)
|
||||||
|
__imp_WriteFile(__imp_GetStdHandle(kNtStdErrorHandle), s, n, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// detect the unholiest of environments
|
||||||
|
static abi bool32 IsWslChimera(void) {
|
||||||
|
char16_t path[PATH_MAX];
|
||||||
|
return __imp_GetCurrentDirectoryW(PATH_MAX, path) && //
|
||||||
|
path[0] == '\\' && //
|
||||||
|
path[1] == '\\' && //
|
||||||
|
path[2] == 'w' && //
|
||||||
|
path[3] == 's' && //
|
||||||
|
path[4] == 'l';
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns true if utf-8 path is a win32-style path that exists
|
// returns true if utf-8 path is a win32-style path that exists
|
||||||
|
@ -239,12 +263,17 @@ abi int64_t WinMain(int64_t hInstance, int64_t hPrevInstance,
|
||||||
extern char os asm("__hostos");
|
extern char os asm("__hostos");
|
||||||
os = _HOSTWINDOWS; // madness https://news.ycombinator.com/item?id=21019722
|
os = _HOSTWINDOWS; // madness https://news.ycombinator.com/item?id=21019722
|
||||||
kStartTsc = rdtsc();
|
kStartTsc = rdtsc();
|
||||||
|
if (!IsTiny() && IsWslChimera()) {
|
||||||
|
PrintError("error: APE is running on WIN32 inside WSL. You need to run: "
|
||||||
|
"sudo sh -c 'echo -1 > /proc/sys/fs/binfmt_misc/WSLInterop'\n");
|
||||||
|
return 77 << 8; // exit(77)
|
||||||
|
}
|
||||||
__umask = 077;
|
__umask = 077;
|
||||||
__pid = __imp_GetCurrentProcessId();
|
__pid = __imp_GetCurrentProcessId();
|
||||||
cmdline = MyCommandLine();
|
cmdline = MyCommandLine();
|
||||||
#ifdef SYSDEBUG
|
#ifdef SYSDEBUG
|
||||||
// sloppy flag-only check for early initialization
|
// sloppy flag-only check for early initialization
|
||||||
if (__strstr16(cmdline, u"--strace")) ++__strace;
|
if (StrStr(cmdline, u"--strace")) ++__strace;
|
||||||
#endif
|
#endif
|
||||||
if (_weaken(WinSockInit)) {
|
if (_weaken(WinSockInit)) {
|
||||||
_weaken(WinSockInit)();
|
_weaken(WinSockInit)();
|
||||||
|
|
|
@ -93,14 +93,30 @@ If you use zsh and have trouble running APE programs try `sh -c ./prog`
|
||||||
or simply upgrade to zsh 5.9+ (since we patched it two years ago). The
|
or simply upgrade to zsh 5.9+ (since we patched it two years ago). The
|
||||||
same is the case for Python `subprocess`, old versions of fish, etc.
|
same is the case for Python `subprocess`, old versions of fish, etc.
|
||||||
|
|
||||||
|
If you're on Linux, then `binfmt_misc` might try to run APE programs
|
||||||
|
under WINE, or say "run-detectors: unable to find an interpreter". You
|
||||||
|
can fix that by running these commands:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sudo wget -O /usr/bin/ape https://cosmo.zip/pub/cosmos/bin/ape-$(uname -m).elf
|
||||||
|
sudo sh -c "echo ':APE:M::MZqFpD::/usr/bin/ape:' >/proc/sys/fs/binfmt_misc/register"
|
||||||
|
sudo sh -c "echo ':APE-jart:M::jartsr::/usr/bin/ape:' >/proc/sys/fs/binfmt_misc/register"
|
||||||
|
```
|
||||||
|
|
||||||
On Apple Silicon, `aarch64-unknown-cosmo-cc` produces ELF binaries. If
|
On Apple Silicon, `aarch64-unknown-cosmo-cc` produces ELF binaries. If
|
||||||
you build a hello world program, then you need to say `ape ./hello` to
|
you build a hello world program, then you need to say `ape ./hello`. If
|
||||||
run it. Note this isn't an issue for `cosmocc` which will wrap the ELF
|
you don't have an `ape` command then run `cc -o ape bin/ape-m1.c` which
|
||||||
program in a shell script that'll compile your APE loader automatically
|
should be moved to `/usr/local/bin/ape`. Your APE interpreter might
|
||||||
as needed. This also isn't an issue if your login shell was built using
|
already exist under a path like `$TMPDIR/.ape-1.9`. It's important to
|
||||||
Cosmopolitan Libc, e.g. <https://cosmo.zip/pub/cosmos/bin/bash> because
|
note this is only a gotcha for the cross compiler. Your `cosmocc`
|
||||||
Cosmo's `execve()` implementation will seamlessly launch ELF files via
|
compiler wraps the actual ELF binaries with a shell script that'll
|
||||||
your APE Loader.
|
extract and compile an APE loader automatically, as needed. This also
|
||||||
|
isn't an issue if your login shell was built using Cosmopolitan Libc,
|
||||||
|
e.g. <https://cosmo.zip/pub/cosmos/bin/bash>. That's because Cosmo's
|
||||||
|
`execve()` implementation will automatically react to `ENOEXEC` from the
|
||||||
|
kernel by re-launching the program under `/usr/local/bin/ape`. Lastly
|
||||||
|
note that all other platforms that aren't Apple Arm64 use `/usr/bin/ape`
|
||||||
|
as the hard-coded canonical interpreter path.
|
||||||
|
|
||||||
On Windows, you need a shell in order to run the shell script wrappers
|
On Windows, you need a shell in order to run the shell script wrappers
|
||||||
from this toolchain. It's recommended that you download Cosmos binaries
|
from this toolchain. It's recommended that you download Cosmos binaries
|
||||||
|
|
|
@ -122,9 +122,9 @@ cp -f o/x86_64/ape/ape-no-modify-self.o "$OUTDIR/x86_64-linux-cosmo/lib/"
|
||||||
|
|
||||||
cp -f ape/ape-m1.c "$OUTDIR/bin/"
|
cp -f ape/ape-m1.c "$OUTDIR/bin/"
|
||||||
cp -af tool/cosmocc/bin/* "$OUTDIR/bin/"
|
cp -af tool/cosmocc/bin/* "$OUTDIR/bin/"
|
||||||
cp -f o/x86_64/ape/ape.elf "$OUTDIR/bin/"
|
cp -f o/x86_64/ape/ape.elf "$OUTDIR/bin/ape-x86_64.elf"
|
||||||
cp -f o/x86_64/ape/ape.macho "$OUTDIR/bin/"
|
cp -f o/x86_64/ape/ape.macho "$OUTDIR/bin/ape-x86_64.macho"
|
||||||
cp -f o/aarch64/ape/ape.elf "$OUTDIR/bin/ape.aarch64"
|
cp -f o/aarch64/ape/ape.elf "$OUTDIR/bin/ape-aarch64.elf"
|
||||||
for x in assimilate march-native mktemper fixupobj zipcopy apelink pecheck mkdeps zipobj; do
|
for x in assimilate march-native mktemper fixupobj zipcopy apelink pecheck mkdeps zipobj; do
|
||||||
o//tool/build/apelink.com \
|
o//tool/build/apelink.com \
|
||||||
-l o/x86_64/ape/ape.elf \
|
-l o/x86_64/ape/ape.elf \
|
||||||
|
|
Loading…
Add table
Reference in a new issue