Compare commits

...
11 Commits
Author SHA1 Message Date
Justine Tunney c60b150fcf Release Cosmopolitan v3.2.1 2024-01-05 15:36:57 -08:00
Jōshin 80ec6c9283 Try to detect kernel version for P flag (#1059) 2024-01-05 15:19:46 -08:00
Justine Tunney 2d93788ce3 Fix --ftrace with cosmo_dlopen()
This change ensures function call logging won't crash the process when
cosmo_dlopen() is called.
2024-01-05 15:13:07 -08:00
Jōshin 15548b523c Cleanup apeinstall.sh (#1057) 2024-01-05 13:45:14 -08:00
Jōshin 412a200ae4 Support binfmt_misc P flag in APE loader (#1058)
This allows ape to automatically preserve `argv[0]` [as of Linux kernel
5.12][0] if the [binfmt_misc][1] registration contains the P flag.

This also removes may_path_search, which was identical to the literally
flag in usage. As a result, FindCommand is subsumed into Commandv.

[0]: https://patchew.org/QEMU/[email protected]/
[1]: https://www.kernel.org/doc/html/latest/admin-guide/binfmt-misc.html
2024-01-05 12:35:01 -08:00
Justine Tunney 44a463e4d2 Invent *cosmo_dltramp() function 2024-01-05 09:11:51 -08:00
Justine Tunney 0de6a08988 Upgrade mono repo to cosmocc 3.2
The toolchain will now be downloaded going forward from multiple pinned
URLs which have shasums. Either wget or curl must be installed.

This change unblocks #1053
2024-01-05 08:02:04 -08:00
Paul Kulchenko a334f9cc33 Update redbean ProgramDirectory to return a list of previously set directories (#1021) 2024-01-05 02:17:55 -08:00
Jōshin 3315b6ef11 Store StrlenDevFd in n (#1056) 2024-01-04 23:17:37 -05:00
Justine Tunney e93c8c4f8f Fix typo 2024-01-04 13:59:36 -08:00
Justine Tunney 0e49bed660 Support 40 cosmo_dlopen() function parameters
Our dynamic linking implementation is now able to support functions with
dozens of parameters. In addition to having extra integral arguments you
can now pass vector registers using intrinsic types. Lastly, you can now
return multiple values, which is useful for functions returning structs.
2024-01-04 13:41:26 -08:00
98 changed files with 892 additions and 19715 deletions

No files matched your search

+1
View File
@@ -1,6 +1,7 @@
# -*- conf -*-
/o
/cosmocc
/.prompt.jtlp
# TODO: Find some way to have Python write to o/
+69 -9
View File
@@ -73,10 +73,13 @@ MODE := $(m)
endif
endif
COMMA := ,
PWD := $(shell pwd)
# detect wsl2 running cosmopolitan binaries on the host by checking whether:
# - user ran build/bootstrap/make.com, in which case make's working directory is in wsl
# - user ran make, in which case cocmd.com's working directory is in wsl
ifneq ($(findstring //wsl.localhost/,$(CURDIR) $(shell pwd)),)
ifneq ($(findstring //wsl.localhost/,$(CURDIR) $(PWD)),)
$(warning wsl2 interop is enabled)
$(error you need to run sudo sh -c 'echo -1 > /proc/sys/fs/binfmt_misc/WSLInterop')
endif
@@ -89,13 +92,70 @@ ifeq ($(MAKE_VERSION), 3.81)
$(error please use build/bootstrap/make.com)
endif
# provide instructions to non-linux users on unbundling gcc
ifeq ($(TOOLCHAIN),) # if TOOLCHAIN isn't defined
ifeq ("$(wildcard o/third_party/gcc/bin/x86_64-linux-cosmo-*)","") # if our gcc isn't unbundled
ifneq ($(UNAME_M)-$(UNAME_S), x86_64-Linux) # if this is not amd64 linux
$(error please run tool/cosmocc/fetch.sh)
endif
LC_ALL = C
SOURCE_DATE_EPOCH = 0
ARFLAGS = rcsD
ZFLAGS ?=
XARGS ?= xargs -P4 -rs8000
DOT ?= dot
CLANG = clang
TMPDIR = o/tmp
AR = build/bootstrap/ar.com
CP = build/bootstrap/cp.com
RM = build/bootstrap/rm.com -f
GZIP = build/bootstrap/gzip.com
ECHO = build/bootstrap/echo.com
CHMOD = build/bootstrap/chmod.com
TOUCH = build/bootstrap/touch.com
PKG = build/bootstrap/package.com
MKDEPS = build/bootstrap/mkdeps.com
ZIPOBJ = build/bootstrap/zipobj.com
ZIPCOPY = build/bootstrap/zipcopy.com
PECHECK = build/bootstrap/pecheck.com
FIXUPOBJ = build/bootstrap/fixupobj.com
MKDIR = build/bootstrap/mkdir.com -p
COMPILE = build/bootstrap/compile.com -V9 -P4096 $(QUOTA)
IGNORE := $(shell $(MKDIR) $(TMPDIR))
ifneq ($(findstring aarch64,$(MODE)),)
ARCH = aarch64
HOSTS ?= pi studio freebsdarm
else
ARCH = x86_64
HOSTS ?= freebsd rhel7 xnu win10 openbsd netbsd
endif
ZIPOBJ_FLAGS += -a$(ARCH)
IGNORE := $(shell $(MKDIR) $(TMPDIR))
export ADDR2LINE
export LC_ALL
export MKDIR
export MODE
export SOURCE_DATE_EPOCH
export TMPDIR
COSMOCC = cosmocc/3.2
TOOLCHAIN = $(COSMOCC)/bin/$(ARCH)-linux-cosmo-
DOWNLOAD := $(shell build/download-cosmocc.sh $(COSMOCC) 3.2 28b48682595f0f46b45ab381118cdffdabc8fcfa29aa54e301fe6ffe35269f5e)
AS = $(TOOLCHAIN)as
CC = $(TOOLCHAIN)gcc
CXX = $(TOOLCHAIN)g++
CXXFILT = $(TOOLCHAIN)c++filt
LD = $(TOOLCHAIN)ld.bfd
NM = $(TOOLCHAIN)nm
GCC = $(TOOLCHAIN)gcc
STRIP = $(TOOLCHAIN)strip
OBJCOPY = $(TOOLCHAIN)objcopy
OBJDUMP = $(TOOLCHAIN)objdump
ifneq ($(wildcard $(PWD)/$(TOOLCHAIN)addr2line),)
ADDR2LINE = $(PWD)/$(TOOLCHAIN)addr2line
else
ADDR2LINE = $(TOOLCHAIN)addr2line
endif
# the default build modes is empty string
@@ -138,7 +198,7 @@ $(warning please run ape/apeinstall.sh if you intend to use landlock make)
$(shell sleep .5)
endif
endif
ifeq ($(USE_SYSTEM_TOOLCHAIN),)
ifneq ($(TOOLCHAIN),)
.STRICT = 1
endif
endif
@@ -149,8 +209,8 @@ endif
libc/stdbool.h \
libc/disclaimer.inc \
rwc:/dev/shm \
rx:cosmocc \
rx:build/bootstrap \
rx:o/third_party/gcc \
r:build/portcosmo.h \
/proc/stat \
rw:/dev/null \
+6 -17
View File
@@ -76,18 +76,7 @@ make install
## Cosmopolitan Source Builds
Cosmopolitan can be compiled from source on any of our supported
platforms. First, you need to download or clone the repository. If
you're not using x86-64 Linux then you'll need cosmocc too.
```sh
git clone https://github.com/jart/cosmopolitan cosmo
cd cosmo
mkdir -p o/third_party/gcc
pushd o/third_party/gcc
wget https://cosmo.zip/pub/cosmocc/cosmocc.zip
unzip cosmocc.zip
popd
```
platforms. The Makefile will download cosmocc automatically.
It's recommended that you install a systemwide APE Loader. This command
requires `sudo` access to copy the `ape` command to a system folder and
@@ -103,7 +92,7 @@ guaranteed to be compatible and furthermore includes our extensions for
doing build system sandboxing.
```sh
o//third_party/gcc/bin/make -j8
build/bootstrap/make.com -j8
o//examples/hello.com
```
@@ -114,7 +103,7 @@ depends on core LIBC packages.
```sh
rm -rf o//libc o//test
o//third_party/gcc/bin/make o//test/posix/signal_test.com
build/bootstrap/make.com o//test/posix/signal_test.com
o//test/posix/signal_test.com
```
@@ -123,21 +112,21 @@ list out each individual one. For example if you wanted to build and run
all the unit tests in the `TEST_POSIX` package, you could say:
```sh
o//third_party/gcc/bin/make o//test/posix
build/bootstrap/make.com o//test/posix
```
Cosmopolitan provides a variety of build modes. For example, if you want
really tiny binaries (as small as 12kb in size) then you'd say:
```sh
o//third_party/gcc/bin/make m=tiny
build/bootstrap/make.com m=tiny
```
You can furthermore cut out the bloat of other operating systems, and
have Cosmopolitan become much more similar to Musl Libc.
```sh
o//third_party/gcc/bin/make m=tinylinux
build/bootstrap/make.com m=tinylinux
```
For further details, see [//build/config.mk](build/config.mk).
+63 -36
View File
@@ -10,73 +10,93 @@ if [ ! -f ape/loader.c ]; then
cd "$COSMO" || exit
fi
if [ -x build/bootstrap/make.com ]; then
MAKE=build/bootstrap/make.com
else
MAKE=make
fi
if [ "$(id -u)" -eq 0 ]; then
SUDO=
else
SUDO=sudo
fi
if command -v install >/dev/null 2>&1; then
if [ x"$(uname -s)" = xLinux ]; then
INSTALL="install -o root -g root -m 755"
else
INSTALL="install -o root -g wheel -m 755"
fi
else
INSTALL="cp -f"
fi
echo "Actually Portable Executable (APE) Installer" >&2
echo "Author: Justine Tunney <[email protected]>" >&2
# special installation process for apple silicon
if [ "$(uname -s)" = "Darwin" ] && [ "$(uname -m)" = "arm64" ]; then
if [ x"$(uname -s)" = xDarwin ] && [ x"$(uname -m)" = xarm64 ]; then
echo "cc -O -o $TMPDIR/ape.$$ ape/ape-m1.c" >&2
cc -O -o "$TMPDIR/ape.$$" ape/ape-m1.c || exit
trap 'rm "$TMPDIR/ape.$$"' EXIT
if [ ! -d /usr/local/bin ]; then
echo "$SUDO mkdir -p /usr/local/bin" >&2
$SUDO mkdir -p /usr/local/bin || exit
fi
echo "$SUDO mv -f $TMPDIR/ape.$$ /usr/local/bin/ape" >&2
$SUDO mv -f "$TMPDIR/ape.$$" /usr/local/bin/ape || exit
echo "$SUDO $INSTALL $TMPDIR/ape.$$ /usr/local/bin/ape" >&2
$SUDO $INSTALL "$TMPDIR/ape.$$" /usr/local/bin/ape || exit
exit
fi
if [ x"$(uname -m)" = xarm64 ] || [ x"$(uname -m)" = xaarch64 ]; then
MODE=aarch64
EXT=elf
BEXT=aarch64
elif [ x"$(uname -m)" = xx86_64 ]; then
MODE=
if [ x"$(uname -s)" = xDarwin ]; then
EXT=macho
else
EXT=elf
fi
BEXT=$EXT
else
echo "unsupported architecture $(uname -m)" >&2
exit
fi
################################################################################
# INSTALL APE LOADER SYSTEMWIDE
if [ -f o/depend ] && make -j8 o//ape; then
if [ -f o/$MODE/depend ] && $MAKE -j8 o/$MODE/ape; then
echo "successfully recompiled ape loader" >&2
elif [ -x o//ape/ape.elf ] && [ -x o//ape/ape.macho ]; then
elif [ -x o/$MODE/ape/ape.$EXT ]; then
echo "using ape loader you compiled earlier" >&2
elif [ -d build/bootstrap ]; then
# if make isn't being used then it's unlikely the user changed the sources
# in that case the prebuilt binaries should be completely up-to-date
echo "using prebuilt ape loader from cosmo repo" >&2
mkdir -p o//ape || exit
cp -af build/bootstrap/ape.elf o//ape/ape.elf || exit
cp -af build/bootstrap/ape.macho o//ape/ape.macho || exit
mkdir -p o/$MODE/ape || exit
cp -af build/bootstrap/ape.$BEXT o/$MODE/ape/ape.$EXT || exit
else
echo "no cosmopolitan libc repository here" >&2
echo "fetching ape loader from justine.lol" >&2
mkdir -p o//ape || exit
echo "fetching ape loader from justine.lol" >&2
mkdir -p o/$MODE/ape || exit
if command -v wget >/dev/null 2>&1; then
wget -qO o//ape/ape.elf https://justine.lol/ape.elf || exit
wget -qO o//ape/ape.macho https://justine.lol/ape.macho || exit
wget -qO o/$MODE/ape/ape.$EXT https://justine.lol/ape.$BEXT || exit
else
curl -Rso o//ape/ape.elf https://justine.lol/ape.elf || exit
curl -Rso o//ape/ape.macho https://justine.lol/ape.macho || exit
curl -Rso o/$MODE/ape/ape.$EXT https://justine.lol/ape.$BEXT || exit
fi
chmod +x o//ape/ape.elf || exit
chmod +x o//ape/ape.macho || exit
chmod +x o/$MODE/ape/ape.$EXT || exit
fi
if [ "$(uname -s)" = "Darwin" ]; then
if ! [ /usr/bin/ape -nt o//ape/ape.macho ]; then
echo >&2
echo "installing o//ape/ape.macho to /usr/bin/ape" >&2
echo "$SUDO cp -f o//ape/ape.macho /usr/bin/ape" >&2
$SUDO cp -f o//ape/ape.macho /usr/bin/ape || exit
echo "done" >&2
fi
else
if ! [ /usr/bin/ape -nt o//ape/ape.elf ]; then
echo >&2
echo "installing o//ape/ape.elf to /usr/bin/ape" >&2
echo "$SUDO mv -f o//ape/ape.elf /usr/bin/ape" >&2
$SUDO cp -f o//ape/ape.elf /usr/bin/ape || exit
echo "done" >&2
fi
if ! [ /usr/bin/ape -nt o/$MODE/ape/ape.$EXT ]; then
echo >&2
echo "installing o/$MODE/ape/ape.$EXT to /usr/bin/ape" >&2
echo "$SUDO $INSTALL o/$MODE/ape/ape.$EXT /usr/bin/ape" >&2
$SUDO $INSTALL o/$MODE/ape/ape.$EXT /usr/bin/ape || exit
echo "done" >&2
fi
################################################################################
@@ -112,13 +132,20 @@ if [ x"$(uname -s)" = xLinux ]; then
echo done >&2
fi
uname_r="$(uname -r)"
if printf '%s\n%s\n' 5.12 "$uname_r" | sort -CV; then
FLAGS=FP
else
FLAGS=F
fi
echo >&2
echo registering APE with binfmt_misc >&2
echo you may need to edit configs to persist across reboot >&2
echo '$SUDO sh -c "echo '"'"':APE:M::MZqFpD::/usr/bin/ape:'"'"' >/proc/sys/fs/binfmt_misc/register"' >&2
$SUDO sh -c "echo ':APE:M::MZqFpD::/usr/bin/ape:' >/proc/sys/fs/binfmt_misc/register" || exit
echo '$SUDO sh -c "echo '"'"':APE-jart:M::jartsr::/usr/bin/ape:'"'"' >/proc/sys/fs/binfmt_misc/register"' >&2
$SUDO sh -c "echo ':APE-jart:M::jartsr::/usr/bin/ape:' >/proc/sys/fs/binfmt_misc/register" || exit
echo '$SUDO sh -c "echo '"'"':APE:M::MZqFpD::/usr/bin/ape:'"$FLAGS'"' >/proc/sys/fs/binfmt_misc/register"' >&2
$SUDO sh -c "echo ':APE:M::MZqFpD::/usr/bin/ape:$FLAGS' >/proc/sys/fs/binfmt_misc/register" || exit
echo '$SUDO sh -c "echo '"'"':APE-jart:M::jartsr::/usr/bin/ape:'"$FLAGS'"' >/proc/sys/fs/binfmt_misc/register"' >&2
$SUDO sh -c "echo ':APE-jart:M::jartsr::/usr/bin/ape:$FLAGS' >/proc/sys/fs/binfmt_misc/register" || exit
echo done >&2
if [ x"$(cat /proc/sys/fs/binfmt_misc/status)" = xdisabled ]; then
+54 -70
View File
@@ -113,41 +113,44 @@
#define EXTERN_C
#endif
#define O_RDONLY 0
#define PROT_NONE 0
#define PROT_READ 1
#define PROT_WRITE 2
#define PROT_EXEC 4
#define MAP_SHARED 1
#define MAP_PRIVATE 2
#define MAP_FIXED 16
#define MAP_ANONYMOUS (IsLinux() ? 32 : 4096)
#define MAP_NORESERVE (IsLinux() ? 16384 : 0)
#define ELFCLASS32 1
#define ELFDATA2LSB 1
#define EM_NEXGEN32E 62
#define EM_AARCH64 183
#define ET_EXEC 2
#define ET_DYN 3
#define PT_LOAD 1
#define PT_DYNAMIC 2
#define PT_INTERP 3
#define EI_CLASS 4
#define EI_DATA 5
#define PF_X 1
#define PF_W 2
#define PF_R 4
#define AT_PHDR 3
#define AT_PHENT 4
#define AT_PHNUM 5
#define AT_PAGESZ 6
#define AT_EXECFN_LINUX 31
#define AT_EXECFN_NETBSD 2014
#define X_OK 1
#define XCR0_SSE 2
#define XCR0_AVX 4
#define PR_SET_MM 35
#define PR_SET_MM_EXE_FILE 13
#define O_RDONLY 0
#define PROT_NONE 0
#define PROT_READ 1
#define PROT_WRITE 2
#define PROT_EXEC 4
#define MAP_SHARED 1
#define MAP_PRIVATE 2
#define MAP_FIXED 16
#define MAP_ANONYMOUS (IsLinux() ? 32 : 4096)
#define MAP_NORESERVE (IsLinux() ? 16384 : 0)
#define ELFCLASS32 1
#define ELFDATA2LSB 1
#define EM_NEXGEN32E 62
#define EM_AARCH64 183
#define ET_EXEC 2
#define ET_DYN 3
#define PT_LOAD 1
#define PT_DYNAMIC 2
#define PT_INTERP 3
#define EI_CLASS 4
#define EI_DATA 5
#define PF_X 1
#define PF_W 2
#define PF_R 4
#define AT_PHDR 3
#define AT_PHENT 4
#define AT_PHNUM 5
#define AT_PAGESZ 6
#define AT_FLAGS 8
#define AT_FLAGS_PRESERVE_ARGV0_BIT 0
#define AT_FLAGS_PRESERVE_ARGV0 (1 << AT_FLAGS_PRESERVE_ARGV0_BIT)
#define AT_EXECFN_LINUX 31
#define AT_EXECFN_NETBSD 2014
#define X_OK 1
#define XCR0_SSE 2
#define XCR0_AVX 4
#define PR_SET_MM 35
#define PR_SET_MM_EXE_FILE 13
#define READ32(S) \
((unsigned)(255 & (S)[3]) << 030 | (unsigned)(255 & (S)[2]) << 020 | \
@@ -572,39 +575,15 @@ static char SearchPath(struct PathSearcher *ps) {
}
}
static char FindCommand(struct PathSearcher *ps) {
ps->path[0] = 0;
/* paths are always 100% taken literally when a slash exists
$ ape foo/bar.com arg1 arg2 */
if (MemChr(ps->name, '/', ps->namelen)) {
return AccessCommand(ps, 0);
}
/* we don't run files in the current directory
$ ape foo.com arg1 arg2
unless $PATH has an empty string entry, e.g.
$ expert PATH=":/bin"
$ ape foo.com arg1 arg2
however we will execute this
$ ape - foo.com foo.com arg1 arg2
because cosmo's execve needs it */
if (ps->literally && AccessCommand(ps, 0)) {
return 1;
}
/* otherwise search for name on $PATH */
return SearchPath(ps);
}
static char *Commandv(struct PathSearcher *ps, int os, char *name,
const char *syspath, int may_path_search) {
if (!may_path_search) return name;
const char *syspath) {
if (!(ps->namelen = StrLen((ps->name = name)))) return 0;
if (ps->literally || MemChr(ps->name, '/', ps->namelen)) return name;
ps->os = os;
ps->syspath = syspath ? syspath : "/bin:/usr/local/bin:/usr/bin";
if (!(ps->namelen = StrLen((ps->name = name)))) return 0;
if (ps->namelen + 1 > sizeof(ps->path)) return 0;
if (FindCommand(ps)) {
ps->path[0] = 0;
if (SearchPath(ps)) {
return ps->path;
} else {
return 0;
@@ -913,10 +892,10 @@ EXTERN_C __attribute__((__noreturn__)) void ApeLoader(long di, long *sp,
char dl) {
int rc, n;
unsigned i;
char literally;
const char *ape;
int c, fd, os, argc;
struct ApeLoader *M;
char arg0, literally;
unsigned long pagesz;
union ElfEhdrBuf *ebuf;
long *auxv, *ap, *endp, *sp2;
@@ -961,11 +940,14 @@ EXTERN_C __attribute__((__noreturn__)) void ApeLoader(long di, long *sp,
/* detect netbsd and find end of words */
pagesz = 0;
arg0 = 0;
for (ap = auxv; ap[0]; ap += 2) {
if (ap[0] == AT_PAGESZ) {
pagesz = ap[1];
} else if (SupportsNetbsd() && !os && ap[0] == AT_EXECFN_NETBSD) {
os = NETBSD;
} else if (SupportsLinux() && ap[0] == AT_FLAGS) {
arg0 = !!(ap[1] & AT_FLAGS_PRESERVE_ARGV0);
}
}
if (!pagesz) {
@@ -979,8 +961,12 @@ EXTERN_C __attribute__((__noreturn__)) void ApeLoader(long di, long *sp,
}
/* we can load via shell, shebang, or binfmt_misc */
int may_path_search = 1;
if ((literally = argc >= 3 && !StrCmp(argv[1], "-"))) {
if (arg0) {
literally = 1;
prog = (char *)sp[2];
argc = sp[2] = sp[0] - 2;
argv = (char **)((sp += 2) + 1);
} else if ((literally = argc >= 3 && !StrCmp(argv[1], "-"))) {
/* if the first argument is a hyphen then we give the user the
power to change argv[0] or omit it entirely. most operating
systems don't permit the omission of argv[0] but we do, b/c
@@ -988,7 +974,6 @@ EXTERN_C __attribute__((__noreturn__)) void ApeLoader(long di, long *sp,
prog = (char *)sp[3];
argc = sp[3] = sp[0] - 3;
argv = (char **)((sp += 3) + 1);
may_path_search = 0;
} else if (argc < 2) {
ShowUsage(os, 2, 1);
} else {
@@ -1029,8 +1014,7 @@ EXTERN_C __attribute__((__noreturn__)) void ApeLoader(long di, long *sp,
}
/* resolve path of executable and read its first page */
if (!(exe = Commandv(&M->ps, os, prog, GetEnv(envp, "PATH"),
may_path_search))) {
if (!(exe = Commandv(&M->ps, os, prog, GetEnv(envp, "PATH")))) {
Pexit(os, prog, 0, "not found (maybe chmod +x or ./ needed)");
} else if ((fd = Open(exe, O_RDONLY, 0, os)) < 0) {
Pexit(os, exe, fd, "open");
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
-85
View File
@@ -53,91 +53,6 @@
# OVERRIDE_FOO set ~/.cosmo.mk and target-specific (use rarely)
#
LC_ALL = C
SOURCE_DATE_EPOCH = 0
ARFLAGS = rcsD
ZFLAGS ?=
XARGS ?= xargs -P4 -rs8000
DOT ?= dot
CLANG = clang
TMPDIR = o/tmp
AR = build/bootstrap/ar.com
CP = build/bootstrap/cp.com
RM = build/bootstrap/rm.com -f
GZIP = build/bootstrap/gzip.com
ECHO = build/bootstrap/echo.com
CHMOD = build/bootstrap/chmod.com
TOUCH = build/bootstrap/touch.com
PKG = build/bootstrap/package.com
MKDEPS = build/bootstrap/mkdeps.com
ZIPOBJ = build/bootstrap/zipobj.com
ZIPCOPY = build/bootstrap/zipcopy.com
PECHECK = build/bootstrap/pecheck.com
FIXUPOBJ = build/bootstrap/fixupobj.com
MKDIR = build/bootstrap/mkdir.com -p
COMPILE = build/bootstrap/compile.com -V9 -P4096 $(QUOTA)
COMMA := ,
PWD := $(shell build/bootstrap/pwd.com)
IGNORE := $(shell $(MKDIR) $(TMPDIR))
ifneq ($(findstring aarch64,$(MODE)),)
ARCH = aarch64
HOSTS ?= pi studio freebsdarm
else
ARCH = x86_64
HOSTS ?= freebsd rhel7 xnu win10 openbsd netbsd
endif
ZIPOBJ_FLAGS += -a$(ARCH)
ifeq ($(PREFIX),)
ifeq ($(USE_SYSTEM_TOOLCHAIN),)
ifeq ($(ARCH),x86_64)
ifneq ("$(wildcard o/third_party/gcc/bin/x86_64-linux-cosmo-*)","")
PREFIX = o/third_party/gcc/bin/x86_64-linux-cosmo-
else
IGNORE := $(shell build/bootstrap/unbundle.com)
PREFIX = o/third_party/gcc/bin/x86_64-linux-musl-
endif
endif # ($(ARCH),x86_64))
ifeq ($(ARCH),aarch64)
ifneq ("$(wildcard o/third_party/gcc/bin/aarch64-linux-cosmo-*)","")
PREFIX = o/third_party/gcc/bin/aarch64-linux-cosmo-
else
IGNORE := $(shell build/bootstrap/unbundle.com)
PREFIX = o/third_party/gcc/bin/aarch64-linux-musl-
endif
endif # ($(ARCH),aarch64)
endif # ($(USE_SYSTEM_TOOLCHAIN),)
endif # ($(PREFIX),)
AS = $(PREFIX)as
CC = $(PREFIX)gcc
CXX = $(PREFIX)g++
CXXFILT = $(PREFIX)c++filt
LD = $(PREFIX)ld.bfd
NM = $(PREFIX)nm
GCC = $(PREFIX)gcc
STRIP = $(PREFIX)strip
OBJCOPY = $(PREFIX)objcopy
OBJDUMP = $(PREFIX)objdump
ifneq ($(wildcard $(PWD)/$(PREFIX)addr2line),)
ADDR2LINE = $(PWD)/$(PREFIX)addr2line
else
ADDR2LINE = $(PREFIX)addr2line
endif
export ADDR2LINE
export LC_ALL
export MKDIR
export MODE
export SOURCE_DATE_EPOCH
export TMPDIR
ifeq ($(LANDLOCKMAKE_VERSION),)
TMPSAFE = $(join $(TMPDIR),$(subst /,_,$@)).tmp
else
+91
View File
@@ -0,0 +1,91 @@
#!/bin/sh
# cosmocc downloader script
# https://justine.lol/cosmo3/#install
# https://github.com/jart/cosmopolitan/blob/master/tool/cosmocc/README.md
# collect arguments
OUTPUT_DIR=${1:?OUTPUT_DIR}
COSMOCC_VERSION=${2:?COSMOCC_VERSION}
COSMOCC_SHA256SUM=${3:?COSMOCC_SHA256SUM}
URL1="https://github.com/jart/cosmopolitan/releases/download/${COSMOCC_VERSION}/cosmocc-${COSMOCC_VERSION}.zip"
URL2="https://cosmo.zip/pub/cosmocc/cosmocc-${COSMOCC_VERSION}.zip"
# helper function
abort() {
printf '%s\n' "download terminated." >&2
exit 1
}
# exit if already downloaded
# we need it because directory timestamps work wierdly
OUTPUT_DIR=${OUTPUT_DIR%/}
if [ -d "${OUTPUT_DIR}" ]; then
exit 0
fi
# find commands we need to securely download cosmocc
if ! UNZIP=$(command -v unzip 2>/dev/null); then
printf '%s\n' "$0: fatal error: you need the unzip command" >&2
printf '%s\n' "please download https://cosmo.zip/pub/cosmos/bin/unzip and put it on the system path" >&2
abort
fi
if ! SHA256SUM=$(command -v sha256sum 2>/dev/null); then
if [ ! -f build/sha256sum.c ]; then
printf '%s\n' "$0: fatal error: you need to install sha256sum" >&2
printf '%s\n' "please download https://cosmo.zip/pub/cosmos/bin/sha256sum and put it on the system path" >&2
abort
fi
if ! SHA256SUM=$(command -v "$PWD/o/build/sha256sum" 2>/dev/null); then
if ! CC=$(command -v "$CC" 2>/dev/null); then
if ! CC=$(command -v cc 2>/dev/null); then
if ! CC=$(command -v cosmocc 2>/dev/null); then
printf '%s\n' "$0: fatal error: you need to install either sha256sum, cc, or cosmocc" >&2
printf '%s\n' "please download https://cosmo.zip/pub/cosmos/bin/sha256sum and put it on the system path" >&2
abort
fi
fi
fi
mkdir -p o/build || abort
SHA256SUM="$PWD/o/build/sha256sum"
printf '%s\n' "${CC} -w -O2 -o ${SHA256SUM} build/sha256sum.c" >&2
"${CC}" -w -O2 -o "${SHA256SUM}.$$" build/sha256sum.c || abort
mv -f "${SHA256SUM}.$$" "${SHA256SUM}" || abort
fi
fi
if WGET=$(command -v wget 2>/dev/null); then
DOWNLOAD=$WGET
DOWNLOAD_ARGS=-O
elif CURL=$(command -v curl 2>/dev/null); then
DOWNLOAD=$CURL
DOWNLOAD_ARGS=-fLo
else
printf '%s\n' "$0: fatal error: you need to install either wget or curl" >&2
printf '%s\n' "please download https://cosmo.zip/pub/cosmos/bin/wget and put it on the system path" >&2
abort
fi
# create temporary output directory
OLDPWD=$PWD
OUTPUT_TMP="${OUTPUT_DIR}.tmp.$$/"
mkdir -p "${OUTPUT_TMP}" || abort
cd "${OUTPUT_TMP}"
die() {
cd "${OLDPWD}"
rm -rf "${OUTPUT_TMP}"
abort
}
# download cosmocc toolchain
# multiple urls avoids outages and national firewalls
if ! "${DOWNLOAD}" ${DOWNLOAD_ARGS} cosmocc.zip "${URL1}"; then
rm -f cosmocc.zip
"${DOWNLOAD}" ${DOWNLOAD_ARGS} cosmocc.zip "${URL2}" || die
fi
printf '%s\n' "${COSMOCC_SHA256SUM} *cosmocc.zip" >cosmocc.zip.sha256sum
"${SHA256SUM}" -c cosmocc.zip.sha256sum || die
"${UNZIP}" cosmocc.zip || die
rm -f cosmocc.zip cosmocc.zip.sha256sum
# commit output directory
cd "${OLDPWD}" || die
mv "${OUTPUT_TMP}" "${OUTPUT_DIR}" || die
+8 -8
View File
@@ -6,14 +6,14 @@ if [ -n "$OBJDUMP" ]; then
fi
find_objdump() {
if [ -x o/third_party/gcc/bin/$1-linux-cosmo-objdump ]; then
OBJDUMP=o/third_party/gcc/bin/$1-linux-cosmo-objdump
elif [ -x o/third_party/gcc/bin/$1-linux-musl-objdump ]; then
OBJDUMP=o/third_party/gcc/bin/$1-linux-musl-objdump
elif [ -x "$COSMO/o/third_party/gcc/bin/$1-linux-cosmo-objdump" ]; then
OBJDUMP="$COSMO/o/third_party/gcc/bin/$1-linux-cosmo-objdump"
elif [ -x "$COSMO/o/third_party/gcc/bin/$1-linux-musl-objdump" ]; then
OBJDUMP="$COSMO/o/third_party/gcc/bin/$1-linux-musl-objdump"
if [ -x cosmocc/3.2/bin/$1-linux-cosmo-objdump ]; then
OBJDUMP=cosmocc/3.2/bin/$1-linux-cosmo-objdump
elif [ -x cosmocc/3.2/bin/$1-linux-musl-objdump ]; then
OBJDUMP=cosmocc/3.2/bin/$1-linux-musl-objdump
elif [ -x "$COSMO/cosmocc/3.2/bin/$1-linux-cosmo-objdump" ]; then
OBJDUMP="$COSMO/cosmocc/3.2/bin/$1-linux-cosmo-objdump"
elif [ -x "$COSMO/cosmocc/3.2/bin/$1-linux-musl-objdump" ]; then
OBJDUMP="$COSMO/cosmocc/3.2/bin/$1-linux-musl-objdump"
else
echo "error: toolchain not found (try running 'cosmocc --update' or 'make' in the cosmo monorepo)" >&2
exit 1
+4 -4
View File
@@ -180,10 +180,10 @@ static inline void InitProgramExecutableNameImpl(void) {
empty string to obviate the TOCTOU problem between loader and binary.
*/
if (!(b = DevFd()) ||
0 != strncmp(b, __program_executable_name, StrlenDevFd()) ||
!__program_executable_name[StrlenDevFd()] ||
__program_executable_name[StrlenDevFd()] == '.' ||
strchr(__program_executable_name + StrlenDevFd(), '/')) {
0 != strncmp(b, __program_executable_name, (n = StrlenDevFd())) ||
!__program_executable_name[n] ||
__program_executable_name[n] == '.' ||
strchr(__program_executable_name + n, '/')) {
goto UseEmpty;
}
}
+1 -1
View File
@@ -22,7 +22,7 @@
#include "libc/errno.h"
/**
* Returns true if process is running under qemu-x86_64 or qemu-x86_64.
* Returns true if process is running under qemu-x86_64 or qemu-aarch64.
*/
int IsQemu(void) {
// qemu doesn't validate the advice argument
+11 -2
View File
@@ -8,8 +8,13 @@ LIBC_DLOPEN = $(LIBC_DLOPEN_A_DEPS) $(LIBC_DLOPEN_A)
LIBC_DLOPEN_A = o/$(MODE)/libc/dlopen/dlopen.a
LIBC_DLOPEN_A_FILES := $(wildcard libc/dlopen/*)
LIBC_DLOPEN_A_HDRS = $(filter %.h,$(LIBC_DLOPEN_A_FILES))
LIBC_DLOPEN_A_SRCS = $(filter %.c,$(LIBC_DLOPEN_A_FILES))
LIBC_DLOPEN_A_OBJS = $(LIBC_DLOPEN_A_SRCS:%.c=o/$(MODE)/%.o)
LIBC_DLOPEN_A_SRCS_C = $(filter %.c,$(LIBC_DLOPEN_A_FILES))
LIBC_DLOPEN_A_SRCS_S = $(filter %.S,$(LIBC_DLOPEN_A_FILES))
LIBC_DLOPEN_A_SRCS = $(LIBC_DLOPEN_A_SRCS_C) $(LIBC_DLOPEN_A_SRCS_S)
LIBC_DLOPEN_A_OBJS = \
$(LIBC_DLOPEN_A_SRCS_C:%.c=o/$(MODE)/%.o) \
$(LIBC_DLOPEN_A_SRCS_S:%.S=o/$(MODE)/%.o)
LIBC_DLOPEN_A_CHECKS = \
$(LIBC_DLOPEN_A).pkg \
@@ -45,6 +50,10 @@ $(LIBC_DLOPEN_A_OBJS): private \
-Wframe-larger-than=4096 \
-Walloca-larger-than=4096
# these assembly files are safe to build on aarch64
o/$(MODE)/libc/dlopen/foreign_tramp.o: libc/dlopen/foreign_tramp.S
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
LIBC_DLOPEN_LIBS = $(foreach x,$(LIBC_DLOPEN_ARTIFACTS),$($(x)))
LIBC_DLOPEN_SRCS = $(foreach x,$(LIBC_DLOPEN_ARTIFACTS),$($(x)_SRCS))
LIBC_DLOPEN_HDRS = $(foreach x,$(LIBC_DLOPEN_ARTIFACTS),$($(x)_HDRS))
+1
View File
@@ -20,6 +20,7 @@ int dlclose(void *);
char *cosmo_dlerror(void);
void *cosmo_dlopen(const char *, int);
void *cosmo_dlsym(void *, const char *);
void *cosmo_dltramp(void *);
int cosmo_dlclose(void *);
#endif
+35 -45
View File
@@ -116,7 +116,7 @@ struct Loaded {
Elf64_Phdr ph[25];
};
static struct {
struct {
atomic_uint once;
bool is_supported;
struct CosmoTib *tib;
@@ -125,9 +125,10 @@ static struct {
int (*dlclose)(void *);
char *(*dlerror)(void);
jmp_buf jb;
} foreign;
} __foreign;
long __sysv2nt14();
long foreign_tramp();
static _Thread_local char dlerror_buf[128];
@@ -156,28 +157,6 @@ static int is_file_newer_than(const char *path, const char *other) {
return timespec_cmp(st1.st_mtim, st2.st_mtim) > 0;
}
// on system five we sadly need this brutal trampoline
// todo(jart): add tls trampoline to sigaction() handlers
// todo(jart): morph binary to get tls from host c library
static long foreign_tramp(long a, long b, long c, long d, long e,
long func(long, long, long, long, long, double,
double, double, double, double, double),
double A, double B, double C, double D, double E,
double F) {
long res;
BLOCK_SIGNALS;
#ifdef __x86_64__
struct CosmoTib *tib = __get_tls();
__set_tls(foreign.tib);
#endif
res = func(a, b, c, d, e, A, B, C, D, E, F);
#ifdef __x86_64__
__set_tls(tib);
#endif
ALLOW_SIGNALS;
return res;
}
static unsigned elf2prot(unsigned x) {
unsigned r = 0;
if (x & PF_R) r += PROT_READ;
@@ -308,11 +287,11 @@ static long *push_strs(long *sp, char **list, int count) {
}
static wontreturn dontinstrument void foreign_helper(void **p) {
foreign.dlopen = p[0];
foreign.dlsym = p[1];
foreign.dlclose = p[2];
foreign.dlerror = p[3];
longjmp(foreign.jb, 1);
__foreign.dlopen = p[0];
__foreign.dlsym = p[1];
__foreign.dlclose = p[2];
__foreign.dlerror = p[3];
_longjmp(__foreign.jb, 1);
}
static dontinline void elf_exec(const char *file, char **envp) {
@@ -515,11 +494,11 @@ static uint8_t *movimm(uint8_t p[static 16], int reg, uint64_t val) {
static void *foreign_thunk_sysv(void *func) {
uint8_t *code, *p;
#ifdef __x86_64__
// movabs $func,%r9
// movabs $func,%rax
// movabs $foreign_tramp,%r10
// jmp *%r10
if (!(p = code = foreign_alloc(23))) return 0; // 10 + 10 + 3 = 23
p = movimm(p, 9, (uintptr_t)func);
p = movimm(p, 0, (uintptr_t)func);
p = movimm(p, 10, (uintptr_t)foreign_tramp);
*p++ = 0x41;
*p++ = 0xff;
@@ -527,7 +506,7 @@ static void *foreign_thunk_sysv(void *func) {
#elif defined(__aarch64__)
__jit_begin();
if ((p = code = foreign_alloc(36))) {
p = movimm(p, 5, (uintptr_t)func);
p = movimm(p, 8, (uintptr_t)func);
p = movimm(p, 10, (uintptr_t)foreign_tramp);
*(uint32_t *)p = 0xd61f0140; // br x10
__clear_cache(code, p + 4);
@@ -671,19 +650,19 @@ static bool foreign_setup(void) {
#ifdef __x86_64__
struct CosmoTib *cosmo_tib = __get_tls();
#endif
if (!setjmp(foreign.jb)) {
if (!setjmp(__foreign.jb)) {
elf_exec(exe, environ);
return false; // if elf_exec() returns, it failed
}
#ifdef __x86_64__
foreign.tib = __get_tls();
__foreign.tib = __get_tls();
__set_tls(cosmo_tib);
#endif
foreign.dlopen = foreign_thunk_sysv(foreign.dlopen);
foreign.dlsym = foreign_thunk_sysv(foreign.dlsym);
foreign.dlclose = foreign_thunk_sysv(foreign.dlclose);
foreign.dlerror = foreign_thunk_sysv(foreign.dlerror);
foreign.is_supported = true;
__foreign.dlopen = foreign_thunk_sysv(__foreign.dlopen);
__foreign.dlsym = foreign_thunk_sysv(__foreign.dlsym);
__foreign.dlclose = foreign_thunk_sysv(__foreign.dlclose);
__foreign.dlerror = foreign_thunk_sysv(__foreign.dlerror);
__foreign.is_supported = true;
return true;
}
@@ -693,8 +672,8 @@ static void foreign_once(void) {
static bool foreign_init(void) {
bool res;
cosmo_once(&foreign.once, foreign_once);
if (!(res = foreign.is_supported)) {
cosmo_once(&__foreign.once, foreign_once);
if (!(res = __foreign.is_supported)) {
dlerror_set("dlopen() isn't supported on this platform");
}
return res;
@@ -824,7 +803,7 @@ void *cosmo_dlopen(const char *path, int mode) {
dlerror_set("dlopen() isn't supported on OpenBSD yet");
res = 0;
} else if (foreign_init()) {
res = foreign.dlopen(path, mode);
res = __foreign.dlopen(path, mode);
} else {
res = 0;
}
@@ -854,7 +833,7 @@ void *cosmo_dlsym(void *handle, const char *name) {
dlerror_set("dlopen() isn't supported on x86-64 MacOS");
func = 0;
} else if (foreign_init()) {
if ((func = foreign.dlsym(handle, name))) {
if ((func = __foreign.dlsym(handle, name))) {
func = foreign_thunk_sysv(func);
}
} else {
@@ -864,6 +843,17 @@ void *cosmo_dlsym(void *handle, const char *name) {
return func;
}
/**
* Trampolines foreign function pointer so it can be called safely.
*/
void *cosmo_dltramp(void *foreign_func) {
if (!IsWindows()) {
return foreign_thunk_sysv(foreign_func);
} else {
return foreign_thunk_nt(foreign_func);
}
}
/**
* Closes dynamic shared object.
*
@@ -880,7 +870,7 @@ int cosmo_dlclose(void *handle) {
dlerror_set("dlopen() isn't supported on x86-64 MacOS");
res = -1;
} else if (foreign_init()) {
res = foreign.dlclose(handle);
res = __foreign.dlclose(handle);
} else {
res = -1;
}
@@ -898,7 +888,7 @@ char *cosmo_dlerror(void) {
} else if (IsWindows() || IsXnu()) {
res = dlerror_buf;
} else if (foreign_init()) {
res = foreign.dlerror();
res = __foreign.dlerror();
res = dlerror_set(res);
} else {
res = dlerror_buf;
+236
View File
@@ -0,0 +1,236 @@
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
│ vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi │
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2024 Justine Alexandra Roberts Tunney │
│ │
│ Permission to use, copy, modify, and/or distribute this software for │
│ any purpose with or without fee is hereby granted, provided that the │
│ above copyright notice and this permission notice appear in all copies. │
│ │
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/macros.internal.h"
#define SIZE 0x0200
#define SKEW 0x10
foreign_tramp:
#ifdef __x86_64__
push %rbp
mov %rsp,%rbp
sub $SIZE,%rsp
// save vector arguments
movdqu %xmm0,-0x10(%rbp)
movdqu %xmm1,-0x20(%rbp)
movdqu %xmm2,-0x30(%rbp)
movdqu %xmm3,-0x40(%rbp)
movdqu %xmm4,-0x50(%rbp)
movdqu %xmm5,-0x60(%rbp)
movdqu %xmm6,-0x70(%rbp)
movdqu %xmm7,-0x80(%rbp)
// save register arguments
mov %rdi,-0x88(%rbp)
mov %rsi,-0x90(%rbp)
mov %rdx,-0x98(%rbp)
mov %rcx,-0xa0(%rbp)
mov %r8,-0xa8(%rbp)
mov %r9,-0xb0(%rbp)
// save function pointer
mov %rax,-0xb8(%rbp)
// block signals
call __sig_block
mov %rax,-0xc0(%rbp)
// switch to foreign tls
mov %fs:0,%rax
mov %rax,-0xc8(%rbp)
mov __foreign+8(%rip),%rdi
call __set_tls
// move stack arguments
movdqu SKEW+0x00(%rbp),%xmm0
movdqu SKEW+0x10(%rbp),%xmm1
movdqu SKEW+0x20(%rbp),%xmm2
movdqu SKEW+0x30(%rbp),%xmm3
movdqu SKEW+0x40(%rbp),%xmm4
movdqu SKEW+0x50(%rbp),%xmm5
movdqu SKEW+0x60(%rbp),%xmm6
movdqu SKEW+0x70(%rbp),%xmm7
movdqu %xmm0,-SIZE+0x00(%rbp)
movdqu %xmm1,-SIZE+0x10(%rbp)
movdqu %xmm2,-SIZE+0x20(%rbp)
movdqu %xmm3,-SIZE+0x30(%rbp)
movdqu %xmm4,-SIZE+0x40(%rbp)
movdqu %xmm5,-SIZE+0x50(%rbp)
movdqu %xmm6,-SIZE+0x60(%rbp)
movdqu %xmm7,-SIZE+0x70(%rbp)
movdqu SKEW+0x80(%rbp),%xmm0
movdqu SKEW+0x90(%rbp),%xmm1
movdqu SKEW+0xa0(%rbp),%xmm2
movdqu SKEW+0xb0(%rbp),%xmm3
movdqu SKEW+0xc0(%rbp),%xmm4
movdqu SKEW+0xd0(%rbp),%xmm5
movdqu SKEW+0xe0(%rbp),%xmm6
movdqu SKEW+0xf0(%rbp),%xmm7
movdqu %xmm0,-SIZE+0x80(%rbp)
movdqu %xmm1,-SIZE+0x90(%rbp)
movdqu %xmm2,-SIZE+0xa0(%rbp)
movdqu %xmm3,-SIZE+0xb0(%rbp)
movdqu %xmm4,-SIZE+0xc0(%rbp)
movdqu %xmm5,-SIZE+0xd0(%rbp)
movdqu %xmm6,-SIZE+0xe0(%rbp)
movdqu %xmm7,-SIZE+0xf0(%rbp)
// restore vector arguments
movdqu -0x10(%rbp),%xmm0
movdqu -0x20(%rbp),%xmm1
movdqu -0x30(%rbp),%xmm2
movdqu -0x40(%rbp),%xmm3
movdqu -0x50(%rbp),%xmm4
movdqu -0x60(%rbp),%xmm5
movdqu -0x70(%rbp),%xmm6
movdqu -0x80(%rbp),%xmm7
// restore register arguments
mov -0x88(%rbp),%rdi
mov -0x90(%rbp),%rsi
mov -0x98(%rbp),%rdx
mov -0xa0(%rbp),%rcx
mov -0xa8(%rbp),%r8
mov -0xb0(%rbp),%r9
// call function
mov -0xb8(%rbp),%rax
call *%rax
// save function result
movdqu %xmm0,-0x10(%rbp)
movdqu %xmm1,-0x20(%rbp)
mov %rax,-0x28(%rbp)
mov %rdx,-0x30(%rbp)
// restore tls
mov -0xc8(%rbp),%rdi
call __set_tls
// unblock signals
mov -0xc0(%rbp),%rdi
call __sig_unblock
// restore function result
mov -0x28(%rbp),%rax
mov -0x30(%rbp),%rdx
movdqu -0x10(%rbp),%xmm0
movdqu -0x20(%rbp),%xmm1
add $SIZE,%rsp
pop %rbp
ret
#elif defined(__aarch64__)
stp x29,x30,[sp,-0x100]!
mov x29,sp
// save vector arguments
stp q0,q1,[sp,0x10]
stp q2,q3,[sp,0x30]
stp q4,q5,[sp,0x50]
stp q6,q7,[sp,0x70]
// save register arguments
stp x0,x1,[sp,0x90]
stp x2,x3,[sp,0xa0]
stp x4,x5,[sp,0xb0]
stp x6,x7,[sp,0xc0]
// save function pointer
str x8,[sp,0xd0]
// block signals
bl __sig_block
str x0,[sp,0xd8]
// move stack arguments
sub sp,sp,#0x100
ldp q0,q1,[sp,SIZE+0x00]
ldp q2,q3,[sp,SIZE+0x20]
ldp q4,q5,[sp,SIZE+0x40]
ldp q6,q7,[sp,SIZE+0x60]
stp q0,q1,[sp,0x00]
stp q2,q3,[sp,0x20]
stp q4,q5,[sp,0x40]
stp q6,q7,[sp,0x60]
ldp q0,q1,[sp,SIZE+0x80]
ldp q2,q3,[sp,SIZE+0xa0]
ldp q4,q5,[sp,SIZE+0xc0]
ldp q6,q7,[sp,SIZE+0xe0]
stp q0,q1,[sp,0x80]
stp q2,q3,[sp,0xa0]
stp q4,q5,[sp,0xc0]
stp q6,q7,[sp,0xe0]
// restore vector arguments
ldp q0,q1,[sp,0x100+0x10]
ldp q2,q3,[sp,0x100+0x30]
ldp q4,q5,[sp,0x100+0x50]
ldp q6,q7,[sp,0x100+0x70]
// restore register arguments
ldp x0,x1,[sp,0x100+0x90]
ldp x2,x3,[sp,0x100+0xa0]
ldp x4,x5,[sp,0x100+0xb0]
ldp x6,x7,[sp,0x100+0xc0]
// call function
ldr x8,[sp,0x100+0xd0]
blr x8
add sp,sp,#0x100
// save vector results
stp q0,q1,[sp,0x10]
stp q2,q3,[sp,0x30]
stp q4,q5,[sp,0x50]
stp q6,q7,[sp,0x70]
// save register results
stp x0,x1,[sp,0x90]
stp x2,x3,[sp,0xa0]
stp x4,x5,[sp,0xb0]
stp x6,x7,[sp,0xc0]
// unblock signals
ldr x0,[sp,0xd8]
bl __sig_unblock
// restore vector results
ldp q0,q1,[sp,0x10]
ldp q2,q3,[sp,0x30]
ldp q4,q5,[sp,0x50]
ldp q6,q7,[sp,0x70]
// restore register results
ldp x0,x1,[sp,0x90]
ldp x2,x3,[sp,0xa0]
ldp x4,x5,[sp,0xb0]
ldp x6,x7,[sp,0xc0]
ldp x29,x30,[sp],0x100
ret
#endif // __x86_64__
.endfn foreign_tramp,globl
+1 -1
View File
@@ -4,7 +4,7 @@
#define __COSMOPOLITAN_MAJOR__ 3
#define __COSMOPOLITAN_MINOR__ 2
#define __COSMOPOLITAN_PATCH__ 0
#define __COSMOPOLITAN_PATCH__ 1
#define __COSMOPOLITAN__ \
(100000000 * __COSMOPOLITAN_MAJOR__ + 1000000 * __COSMOPOLITAN_MINOR__ + \
__COSMOPOLITAN_PATCH__)
+2 -2
View File
@@ -25,9 +25,9 @@
#include "libc/str/str.h"
#ifdef __x86_64__
#define ADDR2LINE "o/third_party/gcc/bin/x86_64-linux-musl-addr2line"
#define ADDR2LINE "cosmocc/3.2/bin/x86_64-linux-musl-addr2line"
#elif defined(__aarch64__)
#define ADDR2LINE "o/third_party/gcc/bin/aarch64-linux-musl-addr2line"
#define ADDR2LINE "cosmocc/3.2/bin/aarch64-linux-musl-addr2line"
#endif
static struct {
+2 -1
View File
@@ -28,6 +28,7 @@
.ftrace1
longjmp:
.ftrace2
_longjmp:
#ifdef __x86_64__
mov %esi,%eax
test %eax,%eax
@@ -61,5 +62,5 @@ longjmp:
#error "unsupported architecture"
#endif
.endfn longjmp,globl
.alias longjmp,_longjmp
.endfn _longjmp,globl
.alias longjmp,siglongjmp
+26
View File
@@ -0,0 +1,26 @@
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
│ vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi │
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2024 Justine Alexandra Roberts Tunney │
│ │
│ Permission to use, copy, modify, and/or distribute this software for │
│ any purpose with or without fee is hereby granted, provided that the │
│ above copyright notice and this permission notice appear in all copies. │
│ │
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/macros.internal.h"
// we can't allow ftrace here since ftrace needs tls
sys_set_tls:
mov __NR_set_tls(%rip),%eax
syscall
ret
.endfn sys_set_tls,globl
+3 -2
View File
@@ -28,12 +28,13 @@
int sys_set_tls();
textstartup void __set_tls(struct CosmoTib *tib) {
// we can't allow --ftrace here because cosmo_dlopen() calls this
// function to fix the tls register, and ftrace needs it unbroken
dontinstrument textstartup void __set_tls(struct CosmoTib *tib) {
tib = __adj_tls(tib);
#ifdef __x86_64__
// ask the operating system to change the x86 segment register
if (IsWindows()) {
npassert(0 <= __tls_index && __tls_index < 64);
asm("mov\t%1,%%gs:%0" : "=m"(*((long *)0x1480 + __tls_index)) : "r"(tib));
} else if (IsFreebsd()) {
sys_set_tls(129 /*AMD64_SET_FSBASE*/, tib);
-2
View File
@@ -1,2 +0,0 @@
#include "libc/sysv/macros.internal.h"
.scall sys_set_tls,0x13d1490a5300309e,4095,3,165,globl,hidden
+1
View File
@@ -1725,6 +1725,7 @@ syscon nr __NR_ioperm 0x00ad 0x0fff 0xfff 0xfff 0xfff 0xfff 0xfff
syscon nr __NR_init_module 0x00af 0x0069 0xfff 0xfff 0xfff 0xfff 0xfff 0xfff
syscon nr __NR_delete_module 0x00b0 0x006a 0xfff 0xfff 0xfff 0xfff 0xfff 0xfff
syscon nr __NR_gettid 0x00ba 0x00b2 0x100001b 0xfff 432 299 311 0xfff # TODO(jart): thread_self_trap vs. gettid?
syscon nr __NR_set_tls 0x009e 0xfff 0x3000003 0xfff 0x00a5 0x0149 0x13d 0xfff
syscon nr __NR_readahead 0x00bb 0x00d5 0xfff 0xfff 0xfff 0xfff 0xfff 0xfff
syscon nr __NR_setxattr 0x00bc 0x0005 0x20000ec 0x00ec 0xfff 0xfff 0x177 0xfff
syscon nr __NR_fsetxattr 0x00be 0x0007 0x20000ed 0x00ed 0xfff 0xfff 0x179 0xfff
+2
View File
@@ -0,0 +1,2 @@
#include "libc/sysv/consts/syscon.internal.h"
.syscon nr,__NR_set_tls,0x009e,0xfff,0x3000003,0xfff,0x00a5,0x0149,0x13d,0xfff
-1
View File
@@ -201,7 +201,6 @@ scall sys_modify_ldt 0xfffffffffffff09a 0xfff globl # no wrapper
scall sys_pivot_root 0xfffffffffffff09b 0x029 globl hidden
#scall prctl 0xfffffffffffff09d 0x0a7 globl # wrapped manually
scall sys_arch_prctl 0x0a50a50a5ffff09e 0xfff globl hidden # sysarch() on bsd
scall sys_set_tls 0x13d1490a5300309e 0xfff globl hidden # arch_prctl on linux, sysarch on freebsd, _lwp_setprivate on netbsd, __set_tcb on openbsd, _lwp_setprivate on netbsd, thread_fast_set_cthread_self on xnu
scall sys_adjtimex 0xfffffffffffff09f 0x0ab globl # no wrapper
scall sys_swapon 0xffffff05520550a7 0x0e0 globl # no wrapper
scall sys_swapoff 0xffffff1a8ffff0a8 0x0e1 globl # no wrapper
-17107
View File
File diff suppressed because it is too large. Load diff
-27
View File
@@ -1,27 +0,0 @@
DESCRIPTION
Cosmopolitan GCC
Prebuilt x86_64-linux binaries
An APE-friendly C/C++ compiler
LICENSE
GPLv3 and other licenses (see LICENSE.txt)
ORIGIN
@ahgamut's musl-cross-make fork
https://github.com/ahgamut/musl-cross-make/
e58abc1110b335a3341e8ad5821ad8e3880d9bb2
MODIFICATIONS
ahgamut's musl-cross-make fork includes a 2kLOC patch that modifies
GCC so it'll compile C code like `switch(errno){case EINVAL: etc.}`
see third_party/gcc/portcosmo.patch for GCC 11.2.0 for our changes
NOTES
These binaries were compiled by Justine Tunney. You have the freedom
to obtain the original source source code, apply our patch, and enjoy
all the freedoms promised to you by the GNU General Public License.
-1
View File
@@ -1 +0,0 @@
../../bin/aarch64-linux-musl-ar
-1
View File
@@ -1 +0,0 @@
../../bin/aarch64-linux-musl-as
Binary file not shown.
-1
View File
@@ -1 +0,0 @@
ld.bfd
-1
View File
@@ -1 +0,0 @@
../../bin/aarch64-linux-musl-nm
-1
View File
@@ -1 +0,0 @@
../../bin/aarch64-linux-musl-objcopy
-1
View File
@@ -1 +0,0 @@
../../bin/aarch64-linux-musl-objdump
-1
View File
@@ -1 +0,0 @@
../../bin/aarch64-linux-musl-strip
Binary file not shown.
Binary file not shown.
Binary file not shown.
-1
View File
@@ -1 +0,0 @@
aarch64-linux-musl-g++
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
-1
View File
@@ -1 +0,0 @@
../aarch64-linux-musl/bin/ld.bfd
-1
View File
@@ -1 +0,0 @@
../aarch64-linux-musl/bin/ld.bfd
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
-1
View File
@@ -1 +0,0 @@
x86_64-linux-musl-g++
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
-1
View File
@@ -1 +0,0 @@
../x86_64-linux-musl/bin/ld.bfd
-1
View File
@@ -1 +0,0 @@
../x86_64-linux-musl/bin/ld.bfd
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
-97
View File
@@ -1,97 +0,0 @@
#
# config.mak.dist - sample musl-cross-make configuration
#
# Copy to config.mak and edit as desired.
#
# There is no default TARGET; you must select one here or on the make
# command line. Some examples:
# TARGET = i486-linux-musl
TARGET = aarch64-linux-musl
# TARGET = arm-linux-musleabi
# TARGET = arm-linux-musleabihf
# TARGET = sh2eb-linux-muslfdpic
# TARGET = powerpc64le-linux-musl
# TARGET = aarch64-linux-musl
# By default, cross compilers are installed to ./output under the top-level
# musl-cross-make directory and can later be moved wherever you want them.
# To install directly to a specific location, set it here. Multiple targets
# can safely be installed in the same location. Some examples:
OUTPUT = /opt/cross11portcosmo
# OUTPUT = /usr/local
# By default, latest supported release versions of musl and the toolchain
# components are used. You can override those here, but the version selected
# must be supported (under hashes/ and patches/) to work. For musl, you
# can use "git-refname" (e.g. git-master) instead of a release. Setting a
# blank version for gmp, mpc, mpfr and isl will suppress download and
# in-tree build of these libraries and instead depend on pre-installed
# libraries when available (isl is optional and not set by default).
# Setting a blank version for linux will suppress installation of kernel
# headers, which are not needed unless compiling programs that use them.
BINUTILS_VER = 2.35.2
GCC_VER = 11.2.0
# MUSL_VER = git-master
# GMP_VER =
# MPC_VER =
# MPFR_VER =
# ISL_VER =
# LINUX_VER =
# By default source archives are downloaded with wget. curl is also an option.
# DL_CMD = wget -c -O
# DL_CMD = curl -C - -L -o
# Check sha-1 hashes of downloaded source archives. On gnu systems this is
# usually done with sha1sum.
# SHA1_CMD = sha1sum -c
# SHA1_CMD = sha1 -c
# SHA1_CMD = shasum -a 1 -c
# Something like the following can be used to produce a static-linked
# toolchain that's deployable to any system with matching arch, using
# an existing musl-targeted cross compiler. This only works if the
# system you build on can natively (or via binfmt_misc and qemu) run
# binaries produced by the existing toolchain (in this example, i486).
# MUSL_CONFIG += --enable-debug
# MUSL_CONFIG += CFLAGS="-Os -fno-omit-frame-pointer -fno-optimize-sibling-calls -mno-omit-leaf-frame-pointer"
MUSL_CONFIG += CFLAGS="-Os"
COMMON_CONFIG += CC="/opt/cross/bin/x86_64-linux-musl-gcc -static --static"
COMMON_CONFIG += CXX="/opt/cross/bin/x86_64-linux-musl-g++ -static --static"
# COMMON_CONFIG += CC="gcc -static --static"
# COMMON_CONFIG += CXX="g++ -static --static"
# Recommended options for smaller build for deploying binaries:
COMMON_CONFIG += CFLAGS="-Os -g0"
COMMON_CONFIG += CXXFLAGS="-Os -g0"
COMMON_CONFIG += LDFLAGS="-s"
# Options you can add for faster/simpler build at the expense of features:
COMMON_CONFIG += --disable-nls
GCC_CONFIG += --disable-libquadmath --disable-decimal-float
GCC_CONFIG += --disable-libitm
GCC_CONFIG += --disable-fixed-point
GCC_CONFIG += --disable-lto
# By default C and C++ are the only languages enabled, and these are
# the only ones tested and known to be supported. You can uncomment the
# following and add other languages if you want to try getting them to
# work too.
GCC_CONFIG += --enable-languages=c,c++ #--enable-plugin
# You can keep the local build path out of your toolchain binaries and
# target libraries with the following, but then gdb needs to be told
# where to look for source files.
# COMMON_CONFIG += --with-debug-prefix-map=$(CURDIR)=
Whitespace-only changes.
@@ -1 +0,0 @@
../../../../bin/aarch64-linux-musl-as
Binary file not shown.
Binary file not shown.
@@ -1 +0,0 @@
../../../../x86_64-linux-musl/bin/ld.bfd
Binary file not shown.
@@ -1 +0,0 @@
../../../../bin/aarch64-linux-musl-ld.bfd
@@ -1 +0,0 @@
../../../../bin/aarch64-linux-musl-ld.bfd
@@ -1 +0,0 @@
../../../../bin/x86_64-linux-musl-as
Binary file not shown.
Binary file not shown.
Binary file not shown.
-1910
View File
File diff suppressed because it is too large. Load diff
-37
View File
@@ -1,37 +0,0 @@
#!/bin/sh
ARCH=${1:-x86_64}
IMPORT=${2:-/opt/cross11portcosmo}
PREFIX=third_party/gcc
OLDVERSION=11.2.0
NEWVERSION=11.2.0
rm -rf o/third_party/gcc
if [ $OLDVERSION != $NEWVERSION ]; then
mv $PREFIX/libexec/gcc/$ARCH-linux-musl/$OLDVERSION $PREFIX/libexec/gcc/$ARCH-linux-musl/$NEWVERSION
mv $PREFIX/lib/gcc/$ARCH-linux-musl/$OLDVERSION $PREFIX/lib/gcc/$ARCH-linux-musl/$NEWVERSION
sed -i -e "s/$OLDVERSION/$NEWVERSION/g" $(find $PREFIX -name \*.sym | grep $ARCH)
fi
FILES="
$ARCH-linux-musl/bin/ld.bfd
libexec/gcc/$ARCH-linux-musl/$NEWVERSION/collect2
libexec/gcc/$ARCH-linux-musl/$NEWVERSION/cc1
libexec/gcc/$ARCH-linux-musl/$NEWVERSION/cc1plus
bin/$ARCH-linux-musl-as
bin/$ARCH-linux-musl-ar
bin/$ARCH-linux-musl-gcc
bin/$ARCH-linux-musl-g++
bin/$ARCH-linux-musl-nm
bin/$ARCH-linux-musl-objcopy
bin/$ARCH-linux-musl-c++filt
bin/$ARCH-linux-musl-addr2line
bin/$ARCH-linux-musl-objdump
bin/$ARCH-linux-musl-gcc-nm
bin/$ARCH-linux-musl-strip
"
for f in $FILES; do
cp -f $IMPORT/$f $PREFIX/$f || exit
gzip -f9 $PREFIX/$f || exit
done
-1
View File
@@ -1 +0,0 @@
../../bin/x86_64-linux-musl-ar
-1
View File
@@ -1 +0,0 @@
../../bin/x86_64-linux-musl-as
Binary file not shown.
-1
View File
@@ -1 +0,0 @@
ld.bfd
-1
View File
@@ -1 +0,0 @@
../../bin/x86_64-linux-musl-nm
-1
View File
@@ -1 +0,0 @@
../../bin/x86_64-linux-musl-objcopy
-1
View File
@@ -1 +0,0 @@
../../bin/x86_64-linux-musl-objdump
-1
View File
@@ -1 +0,0 @@
../../bin/x86_64-linux-musl-strip
+105 -88
View File
@@ -7,124 +7,141 @@ TOOL_BUILD_FILES := $(wildcard tool/build/*)
TOOL_BUILD_SRCS = $(filter %.c,$(TOOL_BUILD_FILES))
TOOL_BUILD_HDRS = $(filter %.h,$(TOOL_BUILD_FILES))
TOOL_BUILD_BINS = \
$(TOOL_BUILD_COMS) \
TOOL_BUILD_BINS = \
$(TOOL_BUILD_COMS) \
$(TOOL_BUILD_COMS:%=%.dbg)
TOOL_BUILD_OBJS = \
TOOL_BUILD_OBJS = \
$(TOOL_BUILD_SRCS:%.c=o/$(MODE)/%.o)
TOOL_BUILD_COMS = \
TOOL_BUILD_COMS = \
$(TOOL_BUILD_SRCS:%.c=o/$(MODE)/%.com)
TOOL_BUILD_CHECKS = \
$(TOOL_BUILD).pkg \
TOOL_BUILD_CHECKS = \
$(TOOL_BUILD).pkg \
$(TOOL_BUILD_HDRS:%=o/$(MODE)/%.ok)
TOOL_BUILD_DIRECTDEPS = \
DSP_CORE \
DSP_SCALE \
DSP_TTY \
LIBC_CALLS \
LIBC_ELF \
LIBC_FMT \
LIBC_INTRIN \
LIBC_LOG \
LIBC_MEM \
LIBC_NEXGEN32E \
LIBC_NT_KERNEL32 \
LIBC_NT_PSAPI \
LIBC_NT_USER32 \
LIBC_NT_WS2_32 \
LIBC_PROC \
LIBC_RUNTIME \
LIBC_SOCK \
LIBC_STDIO \
LIBC_STR \
LIBC_SYSV \
LIBC_SYSV_CALLS \
LIBC_THREAD \
LIBC_TIME \
LIBC_TINYMATH \
LIBC_X \
NET_HTTP \
NET_HTTPS \
THIRD_PARTY_COMPILER_RT \
THIRD_PARTY_GDTOA \
THIRD_PARTY_GETOPT \
THIRD_PARTY_MBEDTLS \
THIRD_PARTY_MUSL \
THIRD_PARTY_REGEX \
THIRD_PARTY_STB \
THIRD_PARTY_XED \
THIRD_PARTY_ZLIB \
THIRD_PARTY_ZLIB_GZ \
TOOL_BUILD_DIRECTDEPS = \
DSP_CORE \
DSP_SCALE \
DSP_TTY \
LIBC_CALLS \
LIBC_DLOPEN \
LIBC_ELF \
LIBC_FMT \
LIBC_INTRIN \
LIBC_LOG \
LIBC_MEM \
LIBC_NEXGEN32E \
LIBC_NT_KERNEL32 \
LIBC_NT_PSAPI \
LIBC_NT_USER32 \
LIBC_NT_WS2_32 \
LIBC_PROC \
LIBC_RUNTIME \
LIBC_SOCK \
LIBC_STDIO \
LIBC_STR \
LIBC_SYSV \
LIBC_SYSV_CALLS \
LIBC_THREAD \
LIBC_TIME \
LIBC_TINYMATH \
LIBC_X \
NET_HTTP \
NET_HTTPS \
THIRD_PARTY_COMPILER_RT \
THIRD_PARTY_GDTOA \
THIRD_PARTY_GETOPT \
THIRD_PARTY_MBEDTLS \
THIRD_PARTY_MUSL \
THIRD_PARTY_REGEX \
THIRD_PARTY_STB \
THIRD_PARTY_XED \
THIRD_PARTY_ZLIB \
THIRD_PARTY_ZLIB_GZ \
TOOL_BUILD_LIB
TOOL_BUILD_DEPS := \
TOOL_BUILD_DEPS := \
$(call uniq,$(foreach x,$(TOOL_BUILD_DIRECTDEPS),$($(x))))
o/$(MODE)/tool/build/build.pkg: \
$(TOOL_BUILD_OBJS) \
o/$(MODE)/tool/build/build.pkg: \
$(TOOL_BUILD_OBJS) \
$(foreach x,$(TOOL_BUILD_DIRECTDEPS),$($(x)_A).pkg)
o/$(MODE)/tool/build/%.com.dbg: \
$(TOOL_BUILD_DEPS) \
o/$(MODE)/tool/build/build.pkg \
o/$(MODE)/tool/build/%.o \
$(CRT) \
o/$(MODE)/tool/build/%.com.dbg: \
$(TOOL_BUILD_DEPS) \
o/$(MODE)/tool/build/build.pkg \
o/$(MODE)/tool/build/%.o \
$(CRT) \
$(APE_NO_MODIFY_SELF)
@$(APELINK)
o/$(MODE)/tool/build/dso/sandbox-$(ARCH).so.zip.o \
o/$(MODE)/tool/build/false.com.zip.o \
o/$(MODE)/tool/build/echo.com.zip.o \
o/$(MODE)/tool/build/cocmd.com.zip.o: private \
ZIPOBJ_FLAGS += \
o/$(MODE)/tool/build/dso/sandbox-$(ARCH).so.zip.o \
o/$(MODE)/tool/build/false.com.zip.o \
o/$(MODE)/tool/build/echo.com.zip.o \
o/$(MODE)/tool/build/cocmd.com.zip.o: private \
ZIPOBJ_FLAGS += \
-B
# we need pic because:
# so it can be an LD_PRELOAD payload
o/$(MODE)/tool/build/dso/sandbox.o: private \
CFLAGS += \
o/$(MODE)/tool/build/dso/sandbox.o: private \
CFLAGS += \
-fPIC
o/$(MODE)/tool/build/dso/sandbox.o: \
libc/calls/calls.h \
tool/build/dso/sandbox.c \
libc/calls/pledge.h \
libc/runtime/runtime.h \
libc/calls/pledge.internal.h \
libc/intrin/promises.internal.h \
o/$(MODE)/tool/build/dso/sandbox.o: \
libc/calls/calls.h \
tool/build/dso/sandbox.c \
libc/calls/pledge.h \
libc/runtime/runtime.h \
libc/calls/pledge.internal.h \
libc/intrin/promises.internal.h \
tool/build/BUILD.mk
o/$(MODE)/tool/build/dso/sandbox-$(ARCH).so: \
o/$(MODE)/tool/build/dso/sandbox.o \
o/$(MODE)/libc/calls/pledge-linux.o \
o/$(MODE)/tool/build/dso/sandbox-$(ARCH).so: \
o/$(MODE)/tool/build/dso/sandbox.o \
o/$(MODE)/libc/calls/pledge-linux.o \
o/$(MODE)/libc/sysv/restorert.o
@$(COMPILE) -ALINK.so \
$(CC) \
-s \
-shared \
-nostdlib \
-fuse-ld=bfd \
-Wl,--gc-sections \
o/$(MODE)/tool/build/dso/sandbox.o \
o/$(MODE)/libc/calls/pledge-linux.o \
o/$(MODE)/libc/sysv/restorert.o \
@$(COMPILE) -ALINK.so \
$(CC) \
-s \
-shared \
-nostdlib \
-fuse-ld=bfd \
-Wl,--gc-sections \
o/$(MODE)/tool/build/dso/sandbox.o \
o/$(MODE)/libc/calls/pledge-linux.o \
o/$(MODE)/libc/sysv/restorert.o \
$(OUTPUT_OPTION)
o/$(MODE)/tool/build/pledge.com.dbg: \
$(TOOL_BUILD_DEPS) \
o/$(MODE)/tool/build/build.pkg \
o/$(MODE)/tool/build/dso/sandbox-$(ARCH).so.zip.o \
o/$(MODE)/tool/build/pledge.o \
$(CRT) \
o/$(MODE)/tool/build/pledge.com.dbg: \
$(TOOL_BUILD_DEPS) \
o/$(MODE)/tool/build/build.pkg \
o/$(MODE)/tool/build/dso/sandbox-$(ARCH).so.zip.o \
o/$(MODE)/tool/build/pledge.o \
$(CRT) \
$(APE_NO_MODIFY_SELF)
@$(APELINK)
o/$(MODE)/tool/build/dso/dlopen_helper.so: \
o/$(MODE)/tool/build/dso/dlopen_helper.o
@$(COMPILE) -ALINK.so \
$(CC) \
-s \
-shared \
-nostdlib \
-fuse-ld=bfd \
o/$(MODE)/tool/build/dso/dlopen_helper.o \
$(OUTPUT_OPTION)
o/$(MODE)/tool/build/dlopen_test.com.runs: \
o/$(MODE)/tool/build/dlopen_test.com \
o/$(MODE)/tool/build/dso/dlopen_helper.so
$< o/$(MODE)/tool/build/dso/dlopen_helper.so
.PHONY: o/$(MODE)/tool/build
o/$(MODE)/tool/build: \
o/$(MODE)/tool/build/lib \
$(TOOL_BUILD_BINS) \
o/$(MODE)/tool/build: \
o/$(MODE)/tool/build/lib \
$(TOOL_BUILD_BINS) \
$(TOOL_BUILD_CHECKS)
@@ -1,7 +1,7 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│ vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi │
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2022 Justine Alexandra Roberts Tunney │
│ Copyright 2024 Justine Alexandra Roberts Tunney │
│ │
│ Permission to use, copy, modify, and/or distribute this software for │
│ any purpose with or without fee is hereby granted, provided that the │
@@ -17,77 +17,110 @@
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/calls.h"
#include "libc/calls/struct/stat.h"
#include "libc/dce.h"
#include "libc/errno.h"
#include "libc/fmt/itoa.h"
#include "libc/fmt/magnumstrs.internal.h"
#include "libc/dlopen/dlfcn.h"
#include "libc/limits.h"
#include "libc/runtime/runtime.h"
#include "libc/stdio/ftw.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/s.h"
#include "libc/x/x.h"
const char *prog;
char tmpdir[PATH_MAX];
char binpath[PATH_MAX];
bool IsDirectory(const char *path) {
int e;
bool res;
struct stat st;
e = errno;
res = stat(path, &st) != -1 && S_ISDIR(st.st_mode);
errno = e;
return res;
}
void Execute(char *argv[]) {
int ws;
if (!vfork()) {
execv(argv[0], argv);
_Exit(127);
}
wait(&ws);
if (!WIFEXITED(ws) || WEXITSTATUS(ws)) {
fputs(argv[0], stderr);
fputs(": command failed\n", stderr);
exit(1);
}
}
int Visit(const char *fpath, const struct stat *sb, int tflag,
struct FTW *ftwbuf) {
if (tflag == FTW_F && endswith(fpath, ".gz")) {
Execute((char *[]){"build/bootstrap/gzip.com", "-d", (char *)fpath, 0});
strcpy(binpath, fpath);
binpath[strlen(binpath) - 3] = 0;
chmod(binpath, 0755);
} else if (tflag == FTW_F && endswith(fpath, ".sym")) {
strcpy(binpath, fpath);
binpath[strlen(binpath) - 4] = 0;
symlink(xslurp(fpath, 0), binpath);
}
return 0;
}
struct big {
long x1;
long x2;
long x3;
long x4;
long x5;
long x6;
long x7;
long x8;
long x9;
double f0;
double f1;
};
int main(int argc, char *argv[]) {
if (!IsLinux()) return 0;
prog = argv[0];
if (!prog) prog = "unbundle";
if (IsDirectory("o/third_party/gcc")) return 0;
makedirs("o/third_party", 0755);
FormatInt32(stpcpy(tmpdir, "o/third_party/gcc."), getpid());
Execute(
(char *[]){"build/bootstrap/cp.com", "-r", "third_party/gcc", tmpdir, 0});
if (nftw(tmpdir, Visit, 20, 0) == -1) {
fputs(prog, stderr);
fputs(": nftw failed: ", stderr);
fputs(_strerdoc(errno), stderr);
fputs("\n", stderr);
void *lib = cosmo_dlopen(argv[1], RTLD_LAZY);
if (!lib) {
tinyprint(2, "cosmo_dlopen() failed: ", cosmo_dlerror(), "\n", NULL);
exit(1);
}
rename(tmpdir, "o/third_party/gcc");
fprintf(stderr, "opened library!\n");
long (*big)(struct big *, long, long, long, long, long, long, long, long,
long, double, double) = cosmo_dlsym(lib, "big");
if (!big) {
tinyprint(2, "cosmo_dlsym() failed: ", cosmo_dlerror(), "\n", NULL);
exit(1);
}
fprintf(stderr, "imported symbol!\n");
struct big args = {0};
long res = big(&args, 1, 2, 3, 4, 5, 6, 7, 8, 9, 3.14, 2.3);
int fails = 0;
if (res != 31337) {
fprintf(stderr, "error: bad result: %016lx\n", res);
++fails;
}
if (args.x1 != 1) {
fprintf(stderr, "error: bad x1: %016lx\n", args.x1);
++fails;
}
if (args.x2 != 2) {
fprintf(stderr, "error: bad x2: %016lx\n", args.x2);
++fails;
}
if (args.x3 != 3) {
fprintf(stderr, "error: bad x3: %016lx\n", args.x3);
++fails;
}
if (args.x4 != 4) {
fprintf(stderr, "error: bad x4: %016lx\n", args.x4);
++fails;
}
if (args.x5 != 5) {
fprintf(stderr, "error: bad x5: %016lx\n", args.x5);
++fails;
}
if (args.x6 != 6) {
fprintf(stderr, "error: bad x6: %016lx\n", args.x6);
++fails;
}
if (args.x7 != 7) {
fprintf(stderr, "error: bad x7: %016lx\n", args.x7);
++fails;
}
if (args.x8 != 8) {
fprintf(stderr, "error: bad x8: %016lx\n", args.x8);
++fails;
}
if (args.x9 != 9) {
fprintf(stderr, "error: bad x9: %016lx\n", args.x9);
++fails;
}
if (args.f0 != 3.14) {
fprintf(stderr, "error: bad f0: %g\n", args.f0);
++fails;
}
if (args.f1 != 2.3) {
fprintf(stderr, "error: bad f1: %g\n", args.f1);
++fails;
}
cosmo_dlclose(lib);
return fails;
}
+48
View File
@@ -0,0 +1,48 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│ vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi │
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2024 Justine Alexandra Roberts Tunney │
│ │
│ Permission to use, copy, modify, and/or distribute this software for │
│ any purpose with or without fee is hereby granted, provided that the │
│ above copyright notice and this permission notice appear in all copies. │
│ │
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
struct big {
long x1;
long x2;
long x3;
long x4;
long x5;
long x6;
long x7;
long x8;
long x9;
double f0;
double f1;
};
long big(struct big *x0, long x1, long x2, long x3, long x4, long x5, long x6,
long x7, long x8, long x9, double f0, double f1) {
x0->x1 = x1;
x0->x2 = x2;
x0->x3 = x3;
x0->x4 = x4;
x0->x5 = x5;
x0->x6 = x6;
x0->x7 = x7;
x0->x8 = x8;
x0->x9 = x9;
x0->f0 = f0;
x0->f1 = f1;
return 31337;
}
+2 -3
View File
@@ -20,9 +20,8 @@ Cosmopolitan comes with absolutely NO WARRANTY of any kind.
For more information, see the Cosmopolitan LICENSE files.
Copyright (C) 2019 Free Software Foundation, Inc.
This launches GNU GCC/Binutils subprocesses, which is free software; see
Cosmopolitan's third_party/gcc/ for source code and copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
cosmocc's LICENSE files for source code and copying conditions. There is
NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
EOF
exit
fi
+2 -3
View File
@@ -18,9 +18,8 @@ Cosmopolitan comes with absolutely NO WARRANTY of any kind.
For more information, see the Cosmopolitan LICENSE files.
Copyright (C) 2019 Free Software Foundation, Inc.
This launches GNU GCC/Binutils subprocesses, which is free software; see
Cosmopolitan's third_party/gcc/ for source code and copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
cosmocc's LICENSE files for source code and copying conditions. There is
NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
EOF
exit
fi
-64
View File
@@ -1,64 +0,0 @@
#!/bin/sh
# tool/cosmocc/fetch.sh
# sets up mono repo to use latest cosmocc toolchain
URL=https://cosmo.zip/pub/cosmocc/cosmocc.zip
echo creating o/third_party/gcc... >&2
rm -rf o/third_party/gcc || exit
mkdir -p o/third_party/gcc || exit
cd o/third_party/gcc
echo downloading $URL... >&2
if command -v wget >/dev/null; then
wget $URL || exit
else
curl -Lo cosmocc.zip $URL || exit
fi
echo extracting cosmocc.zip... >&2
unzip cosmocc.zip || exit
rm -f cosmocc.zip
# report success and give tips
cat <<'EOF' >&2
SUCCESS
the cosmo mono repo will now build using cosmocc
WARNING
if you run `make clean` then you'll have to download it again
CONSIDER
you can install the cosmocc toolchain you just downloaded as follows
sudo chmod 01777 /opt
rm -rf /opt/cosmocc
mv o/third_party/gcc /opt/cosmocc
ln -sf /opt/cosmocc o/third_party/gcc
echo 'export PATH="/opt/cosmocc/bin:$PATH"' >>~/.profile
then just recreate the symlink after cleaning. please note that you
should NEVER need to use make clean with the cosmo mono repo, since
our Makefile is flawless. if make clean actually helps, file a bug.
EOF
# give tip to linux users
if [ x"$(uname -s)" = x"Linux" ]; then
cat <<'EOF' >&2
PROTIP
running these commands
rm -rf o
sudo mount -t tmpfs -o size=10G,noatime,nodiratime /dev/shm o
ln -sf /opt/cosmocc o/third_party/gcc
makes the mono repo build faster
EOF
fi
+2 -2
View File
@@ -2,7 +2,7 @@
# cosmopolitan toolchain packager
#
# tool/cosmocc/package.sh
# cd cosmocc
# cd cosmocc/latest
# zip -ry9 ../cosmocc.zip .
#
@@ -15,7 +15,7 @@ mode() {
esac
}
OUTDIR=${1:-cosmocc}
OUTDIR=${1:-cosmocc/latest}
APELINK=o/$(mode)/tool/build/apelink.com
AMD64=${2:-x86_64}
ARM64=${3:-aarch64}
+6 -1
View File
@@ -1603,11 +1603,16 @@ FUNCTIONS
ProgramGid(int)
Same as the -G flag if called from .init.lua for setgid()
ProgramDirectory(str)
ProgramDirectory([directory:str]) → {directory, ...}
Same as the -D flag if called from .init.lua for overlaying local
file system directories. This may be called multiple times. The
first directory programmed is preferred. These currently do not
show up in the index page listing.
This call also modifies `package.path` value to either prepend
the added directory in front of the default path (if found) or
to append it (in all other cases).
If no directory is provided, then a table with previously set
directories is returned.
ProgramLogMessages(bool)
Same as the -m flag if called from .init.lua for logging message
+12
View File
@@ -4580,6 +4580,18 @@ static int LuaProgramBrand(lua_State *L) {
}
static int LuaProgramDirectory(lua_State *L) {
size_t i;
// if no parameter is provided, then return current directories
if (lua_isnoneornil(L, 1)) {
lua_newtable(L);
if (stagedirs.n) {
for (i = 0; i < stagedirs.n; ++i) {
lua_pushlstring(L, stagedirs.p[i].s, stagedirs.p[i].n);
lua_seti(L, -2, i + 1);
}
}
return 1;
}
struct stat st;
const char *path = luaL_checkstring(L, 1);
// check to raise a Lua error, to allow it to be handled