Introduce cosmocc flags -mdbg -mtiny -moptlinux

The cosmocc.zip toolchain will now include four builds of the libcosmo.a
runtime libraries. You can pass the -mdbg flag if you want to debug your
cosmopolitan runtime. You can pass the -moptlinux flag if you don't want
windows code lurking in your binary. See tool/cosmocc/README.md for more
details on how these flags may be used and their important implications.
This commit is contained in:
Justine Tunney 2024-07-26 05:10:25 -07:00
parent 59692b0882
commit 642e9cb91a
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
22 changed files with 404 additions and 56 deletions

View file

@ -102,6 +102,19 @@ CONFIG_CCFLAGS += -O3 -fmerge-all-constants
CONFIG_COPTS += -mred-zone
TARGET_ARCH ?= -march=native
endif
ifeq ($(MODE), x86_64-optlinux)
CONFIG_OFLAGS ?= -g -ggdb
CONFIG_CPPFLAGS += -DNDEBUG -DSYSDEBUG -DSUPPORT_VECTOR=1
CONFIG_CCFLAGS += -O3 -fmerge-all-constants
CONFIG_COPTS += -mred-zone
TARGET_ARCH ?= -march=native
endif
ifeq ($(MODE), aarch64-optlinux)
CONFIG_OFLAGS ?= -g -ggdb
CONFIG_CPPFLAGS += -DNDEBUG -DSYSDEBUG -DSUPPORT_VECTOR=1
CONFIG_CCFLAGS += -O3 -fmerge-all-constants
CONFIG_COPTS += -mred-zone
endif
# Release Mode
#
@ -136,8 +149,21 @@ endif
ifeq ($(MODE), dbg)
ENABLE_FTRACE = 1
CONFIG_OFLAGS ?= -g -ggdb
CONFIG_CPPFLAGS += -DMODE_DBG -D__SANITIZE_UNDEFINED__
CONFIG_CCFLAGS += $(BACKTRACES) -DSYSDEBUG -O0 -fno-inline
OVERRIDE_CFLAGS += -O0
OVERRIDE_CXXFLAGS += -O0
CONFIG_CPPFLAGS += -DMODE_DBG -D__SANITIZE_UNDEFINED__ -Wno-unused-variable -Wno-unused-but-set-variable
CONFIG_CCFLAGS += $(BACKTRACES) -DSYSDEBUG
CONFIG_COPTS += -fsanitize=undefined
OVERRIDE_CCFLAGS += -fno-pie
QUOTA ?= -C64 -L300
endif
ifeq ($(MODE), x86_64-dbg)
ENABLE_FTRACE = 1
CONFIG_OFLAGS ?= -g -ggdb
OVERRIDE_CFLAGS += -O0
OVERRIDE_CXXFLAGS += -O0
CONFIG_CPPFLAGS += -DMODE_DBG -D__SANITIZE_UNDEFINED__ -Wno-unused-variable -Wno-unused-but-set-variable
CONFIG_CCFLAGS += $(BACKTRACES) -DSYSDEBUG
CONFIG_COPTS += -fsanitize=undefined
OVERRIDE_CCFLAGS += -fno-pie
QUOTA ?= -C64 -L300
@ -145,8 +171,10 @@ endif
ifeq ($(MODE), aarch64-dbg)
ENABLE_FTRACE = 1
CONFIG_OFLAGS ?= -g -ggdb
CONFIG_CPPFLAGS += -DMODE_DBG -D__SANITIZE_UNDEFINED__
CONFIG_CCFLAGS += $(BACKTRACES) -DSYSDEBUG -O0 -fno-inline -fdce
OVERRIDE_CFLAGS += -O0 -fdce
OVERRIDE_CXXFLAGS += -O0 -fdce
CONFIG_CPPFLAGS += -DMODE_DBG -D__SANITIZE_UNDEFINED__ -Wno-unused-variable -Wno-unused-but-set-variable
CONFIG_CCFLAGS += $(BACKTRACES) -DSYSDEBUG
CONFIG_COPTS += -fsanitize=undefined
QUOTA ?= -C64 -L300
endif

View file

@ -17,7 +17,6 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/internal.h"
#include "libc/intrin/fds.h"
#include "libc/calls/syscall-nt.internal.h"
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/calls/syscall_support-nt.internal.h"
@ -25,6 +24,7 @@
#include "libc/dce.h"
#include "libc/errno.h"
#include "libc/fmt/itoa.h"
#include "libc/intrin/fds.h"
#include "libc/intrin/strace.h"
#include "libc/mem/alloca.h"
#include "libc/nt/comms.h"
@ -52,6 +52,7 @@ static const char *DescribeFlush(char buf[12], int action) {
}
static dontinline textwindows int sys_tcflush_nt(int fd, int queue) {
#ifdef __x86_64__
if (!sys_isatty(fd)) {
return -1; // ebadf, enotty
}
@ -59,6 +60,9 @@ static dontinline textwindows int sys_tcflush_nt(int fd, int queue) {
return 0; // windows console output is never buffered
}
return FlushConsoleInputBytes();
#else
return enosys();
#endif
}
/**

View file

@ -557,7 +557,9 @@ static void *foreign_thunk_nt(void *func) {
// movabs $tramp,%r10
code[14] = 0x49;
code[15] = 0xba;
#ifdef __x86_64__
WRITE64LE(code + 16, (uintptr_t)__sysv2nt14);
#endif
// jmp *%r10
code[24] = 0x41;
code[25] = 0xff;

View file

@ -18,6 +18,9 @@
*/
#include "libc/calls/blockcancel.internal.h"
#include "libc/calls/cp.internal.h"
#include "libc/intrin/describebacktrace.h"
#include "libc/intrin/kprintf.h"
#include "libc/nexgen32e/stackframe.h"
#include "libc/runtime/internal.h"
#include "libc/runtime/runtime.h"
#include "libc/thread/posixthread.internal.h"
@ -46,7 +49,11 @@ void end_cancelation_point(int state) {
}
}
void report_cancelation_point(void) {
void report_cancelation_point(int sysv_ordinal, int xnu_ordinal) {
char bt[160];
struct StackFrame *bp = __builtin_frame_address(0);
kprintf("error: report_cancelation_point(%#x, %#x) %s\n", sysv_ordinal,
xnu_ordinal, (DescribeBacktrace)(bt, bp));
__builtin_trap();
}

View file

@ -266,7 +266,8 @@ static relegated void __oncrash_impl(int sig, siginfo_t *si, ucontext_t *ctx) {
if (j)
Append(b, " ");
Append(b, "%s%016lx%s x%d%s", ColorRegister(r),
ctx->uc_mcontext.regs[r], reset, r, r == 8 || r == 9 ? " " : "");
((uint64_t *)ctx->uc_mcontext.regs)[r], reset, r,
r == 8 || r == 9 ? " " : "");
}
Append(b, "\n");
}

View file

@ -7,6 +7,10 @@
*
* This macro should be used when specifying callbacks in the WIN32 API.
*/
#ifdef __x86_64__
#define NT2SYSV(FUNCTION) TRAMPOLINE(FUNCTION, __nt2sysv)
#else
#define NT2SYSV(FUNCTION) FUNCTION
#endif
#endif /* COSMOPOLITAN_LIBC_NEXGEN32E_NT2SYSV_H_ */

View file

@ -22,7 +22,6 @@
#include "libc/calls/calls.h"
#include "libc/calls/internal.h"
#include "libc/calls/state.internal.h"
#include "libc/intrin/fds.h"
#include "libc/calls/struct/rlimit.h"
#include "libc/calls/struct/rlimit.internal.h"
#include "libc/calls/struct/rusage.internal.h"
@ -39,6 +38,7 @@
#include "libc/intrin/bsf.h"
#include "libc/intrin/describeflags.h"
#include "libc/intrin/dll.h"
#include "libc/intrin/fds.h"
#include "libc/intrin/strace.h"
#include "libc/intrin/weaken.h"
#include "libc/mem/alloca.h"
@ -95,6 +95,10 @@
#define CLOSER_CONTAINER(e) DLL_CONTAINER(struct Closer, elem, e)
static atomic_bool has_vfork; // i.e. not qemu/wsl/xnu/openbsd
#ifdef __x86_64__
struct Closer {
int64_t handle;
struct Dll elem;
@ -106,8 +110,6 @@ struct SpawnFds {
struct Dll *closers;
};
static atomic_bool has_vfork; // i.e. not qemu/wsl/xnu/openbsd
static textwindows int64_t spawnfds_handle(struct SpawnFds *fds, int fd) {
if (__is_cloexec(fds->p + fd))
return -1;
@ -429,6 +431,8 @@ static textwindows dontinline errno_t posix_spawn_nt(
return err;
}
#endif // __x86_64__
/**
* Spawns process, the POSIX way, e.g.
*
@ -482,8 +486,10 @@ errno_t posix_spawn(int *pid, const char *path,
const posix_spawn_file_actions_t *file_actions,
const posix_spawnattr_t *attrp, char *const argv[],
char *const envp[]) {
#ifdef __x86_64__
if (IsWindows())
return posix_spawn_nt(pid, path, file_actions, attrp, argv, envp);
#endif
int pfds[2];
bool use_pipe;
volatile int status = 0;

View file

@ -589,7 +589,9 @@ int sys_clone_linux(int flags, // rdi
static int LinuxThreadEntry(void *arg, int tid) {
struct LinuxCloneArgs *wt = arg;
#if defined(__x86_64__)
sys_set_tls(ARCH_SET_GS, wt->tls);
#endif
return wt->func(wt->arg, tid);
}

View file

@ -6,7 +6,11 @@
/**
* Returns preferred size and alignment of thread stack.
*/
#ifndef MODE_DBG
#define GetStackSize() 81920
#else
#define GetStackSize() 163840
#endif
/**
* Returns preferred stack guard size.

View file

@ -88,7 +88,7 @@ o/$(MODE)/libc/sysv/sysret.o: private \
ifeq ($(ARCH),aarch64)
o/$(MODE)/libc/sysv/sysv.o: private \
CFLAGS += \
OVERRIDE_CFLAGS += \
-ffixed-x0 \
-ffixed-x1 \
-ffixed-x2 \

View file

@ -37,7 +37,7 @@ register long freebsd_ordinal asm("x9");
register long xnu_ordinal asm("x16");
register long cosmo_tls_register asm("x28");
void report_cancelation_point(void);
void report_cancelation_point(int, int);
dontinline long systemfive_cancel(void) {
return _weaken(_pthread_cancel_ack)();
@ -58,9 +58,9 @@ dontinline long systemfive_cancellable(void) {
return systemfive_cancel();
}
#if IsModeDbg()
if (!(pth->pt_flags & PT_INCANCEL)) {
if (!(pth->pt_flags & PT_INCANCEL) && !(pth->pt_flags & PT_NOCANCEL)) {
if (_weaken(report_cancelation_point)) {
_weaken(report_cancelation_point)();
_weaken(report_cancelation_point)(sysv_ordinal, xnu_ordinal);
}
__builtin_trap();
}

View file

@ -930,7 +930,7 @@ powl(long double x, long double y)
z = one - (r - z);
o.value = z;
j = o.parts32.mswhi;
j += (n << 16);
j += (int32_t)((uint32_t)n << 16); // TODO(jart): why ubsan
if ((j >> 16) <= 0)
z = scalbnl (z, n); /* subnormal output */
else

View file

@ -18,6 +18,7 @@
#include "ctl/string.h"
#include "ctl/utility.h"
#include "libc/dce.h"
#include "libc/mem/leaks.h"
#include "libc/calls/struct/timespec.h"
@ -43,103 +44,109 @@
const char* big_c = "aaaaaaaaaaaaaaaaaaaaaaaa";
const char* small_c = "aaaaaaaaaaaaaaaaaaaaaaa";
#if IsModeDbg()
#define ITERATIONS 1000 // because qemu in dbg mode is very slow
#else
#define ITERATIONS 1000000
#endif
int
main()
{
const ctl::string_view big(big_c), small(small_c);
BENCH(10000000, 1, {
BENCH(ITERATIONS * 10, 1, {
ctl::string s;
s.append("hello ");
s.append("world");
});
BENCH(1000000, 8, {
BENCH(ITERATIONS, 8, {
ctl::string s;
for (int i = 0; i < 8; ++i) {
s.append('a');
}
});
BENCH(1000000, 16, {
BENCH(ITERATIONS, 16, {
ctl::string s;
for (int i = 0; i < 16; ++i) {
s.append('a');
}
});
BENCH(1000000, 23, {
BENCH(ITERATIONS, 23, {
ctl::string s;
for (int i = 0; i < 23; ++i) {
s.append('a');
}
});
BENCH(1000000, 24, {
BENCH(ITERATIONS, 24, {
ctl::string s;
for (int i = 0; i < 24; ++i) {
s.append('a');
}
});
BENCH(1000000, 32, {
BENCH(ITERATIONS, 32, {
ctl::string s;
for (int i = 0; i < 32; ++i) {
s.append('a');
}
});
BENCH(1000000, 1, { ctl::string s(small_c); });
BENCH(ITERATIONS, 1, { ctl::string s(small_c); });
BENCH(1000000, 1, { ctl::string s(small); });
BENCH(ITERATIONS, 1, { ctl::string s(small); });
{
ctl::string small_copy("hello world");
BENCH(1000000, 1, { ctl::string s2(small_copy); });
BENCH(ITERATIONS, 1, { ctl::string s2(small_copy); });
}
BENCH(1000000, 1, {
BENCH(ITERATIONS, 1, {
ctl::string s(small);
ctl::string s2(ctl::move(s));
});
BENCH(1000000, 1, {
BENCH(ITERATIONS, 1, {
ctl::string s(small);
ctl::string s2(s);
});
BENCH(1000000, 1, { ctl::string s(big_c); });
BENCH(ITERATIONS, 1, { ctl::string s(big_c); });
BENCH(1000000, 1, { ctl::string s(big); });
BENCH(ITERATIONS, 1, { ctl::string s(big); });
{
ctl::string big_copy(big);
BENCH(1000000, 1, { ctl::string s2(big_copy); });
BENCH(ITERATIONS, 1, { ctl::string s2(big_copy); });
}
BENCH(1000000, 1, {
BENCH(ITERATIONS, 1, {
ctl::string s(big);
ctl::string s2(ctl::move(s));
});
BENCH(1000000, 1, {
BENCH(ITERATIONS, 1, {
ctl::string s(big);
ctl::string s2(s);
});
BENCH(1000000, 1, { ctl::string s(23, 'a'); });
BENCH(ITERATIONS, 1, { ctl::string s(23, 'a'); });
BENCH(1000000, 1, { ctl::string s(24, 'a'); });
BENCH(ITERATIONS, 1, { ctl::string s(24, 'a'); });
{
ctl::string s(5, 'a');
BENCH(1000000, 1, { ctl::string_view s2(s); });
BENCH(ITERATIONS, 1, { ctl::string_view s2(s); });
}
{
ctl::string big_trunc(48, 'a');
big_trunc.resize(4);
BENCH(1000000, 1, { ctl::string s(big_trunc); });
BENCH(ITERATIONS, 1, { ctl::string s(big_trunc); });
}
CheckForMemoryLeaks();

View file

@ -212,7 +212,7 @@ void ExpandLuminosityRange(unsigned n, unsigned char *Y) {
}
TEST(ExpandLuminosityRange, test) {
unsigned char Y[32];
_Alignas(16) unsigned char Y[32];
Y[0] = 0;
ExpandLuminosityRange(16, Y);
EXPECT_EQ(0, Y[0]);

View file

@ -152,6 +152,7 @@ static int nsync_futex_wait_win32_ (atomic_int *w, int expect, char pshare,
const struct timespec *timeout,
struct PosixThread *pt,
sigset_t waitmask) {
#ifdef __x86_64__
int sig;
bool32 ok;
struct timespec deadline, wait, now;
@ -203,6 +204,9 @@ static int nsync_futex_wait_win32_ (atomic_int *w, int expect, char pshare,
ASSERT (GetLastError () == ETIMEDOUT);
}
}
#else
return 0;
#endif /* __x86_64__ */
}
static struct timespec *nsync_futex_timeout_ (struct timespec *memory,

View file

@ -34,6 +34,7 @@ THIRD_PARTY_PYTHON_CHECKS = \
# TODO: Deal with aarch64 under qemu not making execve() easy.
ifneq ($(MODE), dbg)
ifneq ($(MODE), x86_64-dbg)
ifeq ($(ARCH), x86_64)
ifneq ($(UNAME_S), Windows)
THIRD_PARTY_PYTHON_CHECKS += \
@ -41,6 +42,7 @@ THIRD_PARTY_PYTHON_CHECKS += \
endif
endif
endif
endif
################################################################################
# STAGE ONE - BOOTSTRAPPING PYTHON

View file

@ -516,7 +516,11 @@ void AddArg(char *actual) {
}
static int GetBaseCpuFreqMhz(void) {
#ifdef __x86_64__
return KCPUIDS(16H, EAX) & 0x7fff;
#else
return 0;
#endif
}
void PlanResource(int resource, struct rlimit rlim) {

View file

@ -373,7 +373,11 @@ int SetLimit(int r, long lo, long hi) {
}
static int GetBaseCpuFreqMhz(void) {
#ifdef __x86_64__
return KCPUIDS(16H, EAX) & 0x7fff;
#else
return 0;
#endif
}
int SetCpuLimit(int secs) {

View file

@ -142,6 +142,116 @@ and AARCH64, which is K8 and ARMv8.0. You can pass architecture specific
flags to use newer ISAs by using the `-Xx86_64` and `-Xaarch64` prefixes
like `-Xx86_64-mssse3` and `-Xaarch64-march=armv8.2-a+dotprod`.
## Flags
The following supplemental flags are defined by cosmocc:
- `-mcosmo` causes `_COSMO_SOURCE` to be defined. This has a similar
effect to defining `_GNU_SOURCE`. When you use this flag, many
non-standard GNU, BSD, and Cosmo Libc APIs will become visible in
headers, e.g. `stdlib.h` will now define `ShowCrashReports()`.
Including `cosmo.h` has a similar effect, however it's recommended
that any program that uses cosmo-specific APIs pass this flag.
- `-mdbg` may be passed when linking programs. It has the same effect as
`export MODE=dbg` in that it will cause an alternative build of the
Cosmopolitan Libc runtime to be linked that was built with `-O0 -g`.
Under the normal build mode, `--ftrace` output is oftentimes missing
important pieces of the puzzle due to inlining. This mode makes it
more comprehensible. It's also the only way to make using GDB to
troubleshoot issues inside Cosmo Libc work reliably. Please be warned
that this flag may enable some heavyweight runtime checks. For
example, mmap() will become O(n) rather than O(logn) in an effort to
spot data structure corruption. Lastly, the linked Cosmo runtime was
compiled with `-fsanitize=undefined` (UBSAN) although you still need
to pass that flag too if you want it for your own code.
- `-mtiny` may be passed when linking programs. It has the same effect
as `export MODE=tiny` in that it will cause an alternative build of
the Cosmopolitan Libc runtime to be linked that's optimized for code
size. In the normal build mode, the smallest possible binary size will
be on the order of hundreds of kb, due to heavyweight features like
`--ftrace` and `--strace` being part of the mandatory runtime. Those
features don't exist in the tiny runtime, which should produce ~147kb
fat binaries and ~36kb x86-only binaries. You may also use this flag
when compiling objects. Since there's no function tracing, using this
will eliminate the NOPs that get inserted into the prologues of your
functions to make them hookable, which also greatly reduces code size.
Please note that this does not specify an `-O` flag, so you may want
to pass `-Os` too. Please note that this mode is granted leeway to
trade away performance whenever possible. Functions like memmove()
will stop using fancy vectorization which can dramatically decrease
the performance of certain use cases. malloc() will stop using cookies
which add bloat but are considered important by some people for both
security and reporting errors on corruption. APIs will also begin
refraining from detecting usage errors that are the fault of the
caller, so this mode isn't recommended for development.
- `-moptlinux` uses the optimized Linux-only version of Cosmopolitan
Libc runtime libraries. Your program will only be able to run on
Linux. The runtime is compiled at `-O3` although it still supports AMD
K8+ (c. 2003). Optimizations like red zone that wouldn't otherwise be
possible are enabled. Function call tracing and system call logging is
disabled. All the Windows polyfills go away and your binaries will be
significantly tinier. The `cosmocc` compiler will generate a shell
script with the magic `jartsr='` so you won't get unwanted attention
from Windows virus scanners. You're even allowed to use flags like
`-fomit-frame-pointer` when you use this mode. Users report optlinux
has helped them make the Python interpreter 5% faster, like distros,
optlinux will salt the earth if it gains a 1% advantage on benchmark
games. Therefore this mode gives you an apples-to-apples comparison
between cosmocc versus the gcc/clang configs used by linux distros.
## Raw Toolchains
The `cosmocc` and `cosmoar` programs use shell script magic to run both
toolchains under the hood. Sometimes this magic doesn't work when you're
building software that needs to do things like run the C preprocessor in
aarch64 mode. In such cases, cosmocc provides x86\_64 and aarch64 only
toolchains which give you more power and control over your builds.
- `x86_64-unknown-cosmo-cc`, `x86_64-unknown-cosmo-c++`, and
`x86_64-linux-cosmo-as` let you build multi-OS programs that only run
on x86\_64. You'll need this if you want to compile complex projects
like Emacs and OpenSSL. These are shell scripts that help you make
sure your software is compiled with the correct set of flags.
- `aarch64-unknown-cosmo-cc`, `aarch64-unknown-cosmo-c++`, and
`aarch64-linux-cosmo-as` let you build multi-OS programs that only run
on ARM64. You'll need this if you want to compile complex projects
like Emacs and OpenSSL. These are shell scripts that help you make
sure your software is compiled with the correct set of flags.
- `aarch64-linux-cosmo-cc`, `aarch64-linux-cosmo-c++`,
`aarch64-linux-cosmo-as`, and `aarch64-linux-cosmo-ld` are the actual
compiler executables. Using these grants full control over your
compiler and maximum performance. This is the approach favored for
instance by the Cosmopolitan Mono Repo's Makefile. If you use these,
then you should have zero expectation of support, because you'll be
assuming all responsibility for knowing about all the ABI-related
flags your Cosmopolitan runtime requires.
When you use the "unknown" OS compilers, they'll link ELF executables
which embed an APE program image. This is so it's possible to have DWARF
debugging data. If you say:
```
x86_64-unknown-cosmo-cc -Os -mtiny -o hello hello.c
./hello
x86_64-linux-cosmo-objcopy -SO binary hello hello.com
./hello.com
```
Then you can unwap the raw stripped APE executable and get a much
smaller file than you otherwise would using the `-s` flag.
If you compile your software twice, using both the x86\_64 and aarch64
compilers, then it's possible to link the two binaries into a single fat
binary yourself via the `apelink` program. To understand how this
process works, it works best if you use the `BUILDLOG` variable, to see
how the shell script wrappers are doing it. You can also consult the
build configs of the ahgamut/superconfigure project on GitHub.
## Troubleshooting
Your `cosmocc` compiler runs a number commands under the hood. If

View file

@ -156,6 +156,15 @@ for x; do
elif [ x"$x" = x"-mcosmo" ]; then
MCOSMO=1
continue
elif [ x"$x" = x"-mdbg" ]; then
MODE=dbg
continue
elif [ x"$x" = x"-mtiny" ]; then
MODE=tiny
continue
elif [ x"$x" = x"-moptlinux" ]; then
MODE=optlinux
continue
elif [ x"$x" = x"-fomit-frame-pointer" ]; then
# Quoth Apple: "The frame pointer register must always address a
# valid frame record. Some functions — such as leaf functions or
@ -243,10 +252,10 @@ LDFLAGS="-static -nostdlib -no-pie -fuse-ld=bfd -Wl,-z,noexecstack -Wl,-z,norelr
PRECIOUS="-fno-omit-frame-pointer"
# these features screw with backtraces so avoid them
if [ x"$OPT" != x"-Os" ] && [ x"$MODE" != x"tiny" ]; then
if [ x"$OPT" != x"-Os" ] && [ x"$MODE" != x"tiny" ] && [ x"$MODE" != x"optlinux" ]; then
CFLAGS="$CFLAGS -fno-optimize-sibling-calls -mno-omit-leaf-frame-pointer"
fi
if [ x"$OPT" != x"-O3" ]; then
if [ x"$OPT" != x"-O3" ] && [ x"$MODE" != x"optlinux" ]; then
CFLAGS="$CFLAGS -fno-schedule-insns2"
fi
@ -261,19 +270,39 @@ else
CFLAGS="$CFLAGS -Wno-implicit-int"
fi
CRT_X86_64="$BIN/../x86_64-linux-cosmo/lib/ape.o $BIN/../x86_64-linux-cosmo/lib/crt.o"
CPPFLAGS_X86_64="$CPPFLAGS -mno-red-zone"
if [ x"$MODE" = x"dbg" ]; then
LIB_X86_64="$BIN/../x86_64-linux-cosmo/lib/dbg"
LIB_AARCH64="$BIN/../aarch64-linux-cosmo/lib/dbg"
elif [ x"$MODE" = x"tiny" ]; then
LIB_X86_64="$BIN/../x86_64-linux-cosmo/lib/tiny"
LIB_AARCH64="$BIN/../aarch64-linux-cosmo/lib/tiny"
elif [ x"$MODE" = x"optlinux" ]; then
LIB_X86_64="$BIN/../x86_64-linux-cosmo/lib/optlinux"
LIB_AARCH64="$BIN/../aarch64-linux-cosmo/lib/optlinux"
else
LIB_X86_64="$BIN/../x86_64-linux-cosmo/lib"
LIB_AARCH64="$BIN/../aarch64-linux-cosmo/lib"
fi
CRT_X86_64="$LIB_X86_64/ape.o $LIB_X86_64/crt.o"
CPPFLAGS_X86_64="$CPPFLAGS"
CFLAGS_X86_64="$CFLAGS -mno-tls-direct-seg-refs"
LDFLAGS_X86_64="$LDFLAGS -L$BIN/../x86_64-linux-cosmo/lib -Wl,-T,$BIN/../x86_64-linux-cosmo/lib/ape.lds -Wl,-z,common-page-size=4096 -Wl,-z,max-page-size=16384"
LDFLAGS_X86_64="$LDFLAGS -L$LIB_X86_64 -L$BIN/../x86_64-linux-cosmo/lib -Wl,-T,$LIB_X86_64/ape.lds -Wl,-z,common-page-size=4096 -Wl,-z,max-page-size=16384"
LDLIBS_X86_64="-lcosmo"
CRT_AARCH64="$BIN/../aarch64-linux-cosmo/lib/crt.o"
CRT_AARCH64="$LIB_AARCH64/crt.o"
CPPFLAGS_AARCH64="$CPPFLAGS -fsigned-char"
CFLAGS_AARCH64="$CFLAGS -ffixed-x18 -ffixed-x28 -mno-outline-atomics"
LDFLAGS_AARCH64="$LDFLAGS -L$BIN/../aarch64-linux-cosmo/lib -Wl,-T,$BIN/../aarch64-linux-cosmo/lib/aarch64.lds -Wl,-z,common-page-size=16384 -Wl,-z,max-page-size=16384"
LDFLAGS_AARCH64="$LDFLAGS -L$LIB_AARCH64 -L$BIN/../aarch64-linux-cosmo/lib -Wl,-T,$LIB_AARCH64/aarch64.lds -Wl,-z,common-page-size=16384 -Wl,-z,max-page-size=16384"
LDLIBS_AARCH64="-lcosmo"
if [ x"$OPT" != x"-Os" ] && [ x"$MODE" != x"tiny" ]; then
SUPPORT_VECTOR=-1
if [ x"$MODE" = x"optlinux" ]; then
CPPFLAGS_X86_64="$CPPFLAGS_X86_64 -mno-red-zone"
SUPPORT_VECTOR=linux
fi
if [ x"$OPT" != x"-Os" ] && [ x"$MODE" != x"tiny" ] && [ x"$MODE" != x"optlinux" ]; then
CFLAGS_X86_64="${CFLAGS_X86_64} -fpatchable-function-entry=18,16 -fno-inline-functions-called-once -DFTRACE -DSYSDEBUG"
CFLAGS_AARCH64="${CFLAGS_AARCH64} -fpatchable-function-entry=7,6 -fno-inline-functions-called-once -DFTRACE -DSYSDEBUG"
fi
@ -526,6 +555,7 @@ fi
set -- \
"$BIN/apelink" \
-V "$SUPPORT_VECTOR" \
-l "$BIN/ape-x86_64.elf" \
-l "$BIN/ape-aarch64.elf" \
-M "$BIN/ape-m1.c" \
@ -536,10 +566,12 @@ set -- \
log_command "$@"
"$@" || Exit
set -- \
"$BIN/pecheck" "$OUTPUT"
log_command "$@"
"$@" || Exit
if [ x"$MODE" != "optlinux" ]; then
set -- \
"$BIN/pecheck" "$OUTPUT"
log_command "$@"
"$@" || Exit
fi
if [ $INTENT = ld ] && [ $SAVE_TEMPS -eq 0 ]; then
mv -f "$OUTPUT_X86_64" "${OUTPUT%.com}.com.dbg" || Exit

View file

@ -59,13 +59,33 @@ if [ x"$ARCH" = x"$PROG" ]; then
fatal_error "cosmocross must be run via cross compiler"
fi
for x; do
if [ x"$x" = x"-mtiny" ]; then
MODE=tiny
elif [ x"$x" = x"-mdbg" ]; then
MODE=dbg
elif [ x"$x" = x"-moptlinux" ]; then
MODE=optlinux
fi
done
if [ x"$MODE" = x"dbg" ]; then
LIB="$BIN/../$ARCH-linux-cosmo/lib/dbg"
elif [ x"$MODE" = x"tiny" ]; then
LIB="$BIN/../$ARCH-linux-cosmo/lib/tiny"
elif [ x"$MODE" = x"optlinux" ]; then
LIB="$BIN/../$ARCH-linux-cosmo/lib/optlinux"
else
LIB="$BIN/../$ARCH-linux-cosmo/lib"
fi
CC="$BIN/$ARCH-linux-cosmo-gcc"
CRT="$BIN/../$ARCH-linux-cosmo/lib/crt.o"
CRT="$LIB/crt.o"
LDLIBS="-lcosmo"
if [ -z "$COSMOS" ]; then
LDFLAGS="$LDFLAGS -L$BIN/../$ARCH-linux-cosmo/lib"
LDFLAGS="$LDFLAGS -L$LIB -L$BIN/../$ARCH-linux-cosmo/lib"
else
LDFLAGS="$LDFLAGS -L$COSMOS/lib -L$BIN/../$ARCH-linux-cosmo/lib"
LDFLAGS="$LDFLAGS -L$COSMOS/lib -L$LIB -L$BIN/../$ARCH-linux-cosmo/lib"
CPPFLAGS="$CPPFLAGS -I$COSMOS/include"
fi
if [ x"$PROG" != x"${PROG%++}" ]; then
@ -80,16 +100,20 @@ fi
PAGESZ=4096
if [ x"$ARCH" = x"x86_64" ]; then
OBJCOPYFLAGS="-S -O binary"
CRT="$BIN/../$ARCH-linux-cosmo/lib/ape-no-modify-self.o $CRT"
CPPFLAGS="$CPPFLAGS -mno-red-zone"
CRT="$LIB/ape-no-modify-self.o $CRT"
CFLAGS="$CFLAGS -mno-tls-direct-seg-refs"
LDFLAGS="$LDFLAGS -Wl,-T,$BIN/../$ARCH-linux-cosmo/lib/ape.lds"
LDFLAGS="$LDFLAGS -Wl,-T,$LIB/ape.lds"
if [ x"$MODE" = x"optlinux" ]; then
CPPFLAGS="$CPPFLAGS -mred-zone"
else
CPPFLAGS="$CPPFLAGS -mno-red-zone"
fi
elif [ x"$ARCH" = x"aarch64" ]; then
OBJCOPYFLAGS="-S"
PAGESZ=16384
CPPFLAGS="$CPPFLAGS -fsigned-char"
CFLAGS="$CFLAGS -ffixed-x18 -ffixed-x28 -mno-outline-atomics"
LDFLAGS="$LDFLAGS -Wl,-T,$BIN/../$ARCH-linux-cosmo/lib/aarch64.lds"
LDFLAGS="$LDFLAGS -Wl,-T,$LIB/aarch64.lds"
else
fatal_error "$ARCH: unsupported architecture"
fi
@ -142,6 +166,12 @@ for x; do
elif [ x"$x" = x"-mcosmo" ]; then
CPPFLAGS="$CPPFLAGS -D_COSMO_SOURCE"
continue
elif [ x"$x" = x"-mdbg" ]; then
continue
elif [ x"$x" = x"-mtiny" ]; then
continue
elif [ x"$x" = x"-moptlinux" ]; then
continue
elif [ x"$x" != x"${x#-o}" ]; then
OUTPUT=${x#-o}
elif [ x"$x" = x"-fpic" ]; then
@ -189,6 +219,7 @@ fi
# support --ftrace unless optimizing for size
if [ x"$OPT" != x"-Os" ] && # $OPT != -Os
[ x"$MODE" != x"optlinux" ] && # $MODE not optlinux
[ x"${MODE%tiny}" = x"${MODE}" ]; then # $MODE not in (tiny, aarch64-tiny)
if [ x"$ARCH" = x"x86_64" ]; then
CFLAGS="$CFLAGS -fpatchable-function-entry=18,16 -fno-inline-functions-called-once"
@ -199,10 +230,11 @@ fi
# maximize frame pointers unless optimizing for size
if [ x"$OPT" != x"-Os" ] && # $OPT != "-Os"
[ x"$MODE" != x"optlinux" ] && # $MODE not optlinux
[ x"$MODE" != x"${MODE%tiny}" ]; then # endswith($MODE, "tiny")
CFLAGS="$CFLAGS -fno-optimize-sibling-calls -mno-omit-leaf-frame-pointer"
fi
if [ x"$OPT" != x"-O3" ]; then
if [ x"$OPT" != x"-O3" ] && [ x"$MODE" != x"optlinux" ]; then
CFLAGS="$CFLAGS -fno-schedule-insns2"
fi

View file

@ -61,6 +61,42 @@ make -j64 m=$AMD64 \
o/$AMD64/third_party/make/make.dbg \
o/$AMD64/third_party/ctags/ctags.dbg
make -j64 m=$AMD64-tiny \
o/cosmocc.h.txt \
o/$AMD64-tiny/ape/ape.lds \
o/$AMD64-tiny/libc/crt/crt.o \
o/$AMD64-tiny/ape/ape.elf \
o/$AMD64-tiny/ape/ape.macho \
o/$AMD64-tiny/ape/ape.o \
o/$AMD64-tiny/ape/ape-copy-self.o \
o/$AMD64-tiny/ape/ape-no-modify-self.o \
o/$AMD64-tiny/cosmopolitan.a \
o/$AMD64-tiny/third_party/libcxx/libcxx.a \
make -j64 m=$AMD64-dbg \
o/cosmocc.h.txt \
o/$AMD64-dbg/ape/ape.lds \
o/$AMD64-dbg/libc/crt/crt.o \
o/$AMD64-dbg/ape/ape.elf \
o/$AMD64-dbg/ape/ape.macho \
o/$AMD64-dbg/ape/ape.o \
o/$AMD64-dbg/ape/ape-copy-self.o \
o/$AMD64-dbg/ape/ape-no-modify-self.o \
o/$AMD64-dbg/cosmopolitan.a \
o/$AMD64-dbg/third_party/libcxx/libcxx.a \
make TARGET_ARCH= -j64 m=$AMD64-optlinux \
o/cosmocc.h.txt \
o/$AMD64-optlinux/ape/ape.lds \
o/$AMD64-optlinux/libc/crt/crt.o \
o/$AMD64-optlinux/ape/ape.elf \
o/$AMD64-optlinux/ape/ape.macho \
o/$AMD64-optlinux/ape/ape.o \
o/$AMD64-optlinux/ape/ape-copy-self.o \
o/$AMD64-optlinux/ape/ape-no-modify-self.o \
o/$AMD64-optlinux/cosmopolitan.a \
o/$AMD64-optlinux/third_party/libcxx/libcxx.a \
make -j64 m=$ARM64 \
o/$ARM64/ape/ape.elf \
o/$ARM64/ape/aarch64.lds \
@ -95,6 +131,33 @@ make -j64 m=$ARM64 \
o/$ARM64/third_party/make/make.dbg \
o/$ARM64/third_party/ctags/ctags.dbg
make -j64 m=$ARM64-tiny \
o/$ARM64-tiny/ape/ape.elf \
o/$ARM64-tiny/ape/aarch64.lds \
o/$ARM64-tiny/libc/crt/crt.o \
o/$ARM64-tiny/ape/ape-copy-self.o \
o/$ARM64-tiny/ape/ape-no-modify-self.o \
o/$ARM64-tiny/cosmopolitan.a \
o/$ARM64-tiny/third_party/libcxx/libcxx.a \
make -j64 m=$ARM64-dbg \
o/$ARM64-dbg/ape/ape.elf \
o/$ARM64-dbg/ape/aarch64.lds \
o/$ARM64-dbg/libc/crt/crt.o \
o/$ARM64-dbg/ape/ape-copy-self.o \
o/$ARM64-dbg/ape/ape-no-modify-self.o \
o/$ARM64-dbg/cosmopolitan.a \
o/$ARM64-dbg/third_party/libcxx/libcxx.a \
make -j64 m=$ARM64-optlinux \
o/$ARM64-optlinux/ape/ape.elf \
o/$ARM64-optlinux/ape/aarch64.lds \
o/$ARM64-optlinux/libc/crt/crt.o \
o/$ARM64-optlinux/ape/ape-copy-self.o \
o/$ARM64-optlinux/ape/ape-no-modify-self.o \
o/$ARM64-optlinux/cosmopolitan.a \
o/$ARM64-optlinux/third_party/libcxx/libcxx.a \
mkdir -p "$OUTDIR/bin/"
cp tool/cosmocc/README.md "$OUTDIR/"
cp tool/cosmocc/LICENSE.* "$OUTDIR/"
@ -155,19 +218,51 @@ cd "$OLD"
for arch in $AMD64 $ARM64; do
mkdir -p "$OUTDIR/$arch-linux-cosmo/lib/"
mkdir -p "$OUTDIR/$arch-linux-cosmo/lib/dbg"
mkdir -p "$OUTDIR/$arch-linux-cosmo/lib/tiny"
mkdir -p "$OUTDIR/$arch-linux-cosmo/lib/optlinux"
cp -f o/$arch/libc/crt/crt.o "$OUTDIR/$arch-linux-cosmo/lib/"
cp -f o/$arch-dbg/libc/crt/crt.o "$OUTDIR/$arch-linux-cosmo/lib/dbg/"
cp -f o/$arch-tiny/libc/crt/crt.o "$OUTDIR/$arch-linux-cosmo/lib/tiny/"
cp -f o/$arch-optlinux/libc/crt/crt.o "$OUTDIR/$arch-linux-cosmo/lib/optlinux/"
cp -f o/$arch/cosmopolitan.a "$OUTDIR/$arch-linux-cosmo/lib/libcosmo.a"
cp -f o/$arch-dbg/cosmopolitan.a "$OUTDIR/$arch-linux-cosmo/lib/dbg/libcosmo.a"
cp -f o/$arch-tiny/cosmopolitan.a "$OUTDIR/$arch-linux-cosmo/lib/tiny/libcosmo.a"
cp -f o/$arch-optlinux/cosmopolitan.a "$OUTDIR/$arch-linux-cosmo/lib/optlinux/libcosmo.a"
cp -f o/$arch/third_party/libcxx/libcxx.a "$OUTDIR/$arch-linux-cosmo/lib/"
cp -f o/$arch-dbg/third_party/libcxx/libcxx.a "$OUTDIR/$arch-linux-cosmo/lib/dbg/"
cp -f o/$arch-tiny/third_party/libcxx/libcxx.a "$OUTDIR/$arch-linux-cosmo/lib/tiny/"
cp -f o/$arch-optlinux/third_party/libcxx/libcxx.a "$OUTDIR/$arch-linux-cosmo/lib/optlinux/"
for lib in c dl gcc_s m crypt pthread resolv rt dl unwind gomp stdc++; do
printf '\041\074\141\162\143\150\076\012' >"$OUTDIR/$arch-linux-cosmo/lib/lib$lib.a"
done
mkdir -p "$OUTDIR/lib/gcc/"
touch "$OUTDIR/lib/gcc/libgomp.spec" # needed if user passes -fopenmp but not -lgomp
done
cp -f o/$AMD64/ape/ape.o "$OUTDIR/x86_64-linux-cosmo/lib/"
cp -f o/$AMD64-dbg/ape/ape.o "$OUTDIR/x86_64-linux-cosmo/lib/dbg/"
cp -f o/$AMD64-tiny/ape/ape.o "$OUTDIR/x86_64-linux-cosmo/lib/tiny/"
cp -f o/$AMD64-optlinux/ape/ape.o "$OUTDIR/x86_64-linux-cosmo/lib/optlinux/"
cp -f o/$AMD64/ape/ape.lds "$OUTDIR/x86_64-linux-cosmo/lib/"
cp -f o/$AMD64-dbg/ape/ape.lds "$OUTDIR/x86_64-linux-cosmo/lib/dbg/"
cp -f o/$AMD64-tiny/ape/ape.lds "$OUTDIR/x86_64-linux-cosmo/lib/tiny/"
cp -f o/$AMD64-optlinux/ape/ape.lds "$OUTDIR/x86_64-linux-cosmo/lib/optlinux/"
cp -f o/$ARM64/ape/aarch64.lds "$OUTDIR/aarch64-linux-cosmo/lib/"
cp -f o/$ARM64-dbg/ape/aarch64.lds "$OUTDIR/aarch64-linux-cosmo/lib/dbg/"
cp -f o/$ARM64-tiny/ape/aarch64.lds "$OUTDIR/aarch64-linux-cosmo/lib/tiny/"
cp -f o/$ARM64-optlinux/ape/aarch64.lds "$OUTDIR/aarch64-linux-cosmo/lib/optlinux/"
cp -f o/$AMD64/ape/ape-no-modify-self.o "$OUTDIR/x86_64-linux-cosmo/lib/"
cp -f o/$AMD64-dbg/ape/ape-no-modify-self.o "$OUTDIR/x86_64-linux-cosmo/lib/dbg/"
cp -f o/$AMD64-tiny/ape/ape-no-modify-self.o "$OUTDIR/x86_64-linux-cosmo/lib/tiny/"
cp -f o/$AMD64-optlinux/ape/ape-no-modify-self.o "$OUTDIR/x86_64-linux-cosmo/lib/optlinux/"
cp -f ape/ape-m1.c "$OUTDIR/bin/"
cp -af tool/cosmocc/bin/* "$OUTDIR/bin/"