Skip to content

Commit

Permalink
Get blink to build with modern Cosmopolitan
Browse files Browse the repository at this point in the history
Cosmopolitan Libc's new memory manager enables Blink to work *perfectly*
as an APE binary out of the box. It's truly delightful.
  • Loading branch information
jart committed Jun 22, 2024
1 parent ad801e6 commit 92fc4d0
Show file tree
Hide file tree
Showing 17 changed files with 167 additions and 104 deletions.
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,8 @@ include third_party/qemu/qemu.mk
include third_party/cosmo/cosmo.mk
include third_party/libc-test/libc-test.mk

BUILD_TOOLCHAIN := -DBUILD_TOOLCHAIN="\"$(shell $(CC) --version | head -n1)\""
BUILD_TIMESTAMP := -DBUILD_TIMESTAMP="\"$(shell LC_ALL=C TZ=UTC date +"%a %b %e %T %Z %Y")\""
BUILD_TOOLCHAIN := -DBUILD_TOOLCHAIN="\"$(shell $(CC) --version | head -n1 | sed s/\ / /g)\""
BUILD_TIMESTAMP := -DBUILD_TIMESTAMP="\"$(shell LC_ALL=C TZ=UTC date +"%a %b %e %T %Z %Y" | sed s/\ / /g)\""
BLINK_COMMITS := -DBLINK_COMMITS="\"$(shell git rev-list HEAD --count 2>/dev/null)\""
BLINK_GITSHA := -DBLINK_GITSHA="\"$(shell git rev-parse --verify HEAD 2>/dev/null)\""

Expand Down
2 changes: 1 addition & 1 deletion blink/demangle.c
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ char *Demangle(char *p, const char *symbol, size_t n) {
size_t sn;
sigset_t ss, oldss;
sn = strlen(symbol);
if (startswith(symbol, "_Z")) {
if (StartsWith(symbol, "_Z")) {
#ifdef HAVE_PTHREAD_SETCANCELSTATE
unassert(!pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs));
#endif
Expand Down
2 changes: 1 addition & 1 deletion blink/diself.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ static void DisLoadElfSyms(struct Dis *d, Elf64_Ehdr_ *ehdr, size_t esize,
for (i = 0; i < n; ++i) {
if (ELF64_ST_TYPE_(st[i].info) == STT_SECTION_ ||
ELF64_ST_TYPE_(st[i].info) == STT_FILE_ || !Read32(st[i].name) ||
startswith(stab + Read32(st[i].name), "v_") ||
StartsWith(stab + Read32(st[i].name), "v_") ||
!(0 <= Read32(st[i].name) && Read32(st[i].name) < stablen) ||
!Read64(st[i].value) ||
!(-0x800000000000 <= (i64)Read64(st[i].value) &&
Expand Down
4 changes: 2 additions & 2 deletions blink/disinst.c
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,8 @@ static char *DisName(struct Dis *d, char *bp, const char *name,
} else {
*p++ = 's';
}
} else if (wantsuffix || (ambiguous && !startswith(name, "f") &&
!startswith(name, "set"))) {
} else if (wantsuffix || (ambiguous && !StartsWith(name, "f") &&
!StartsWith(name, "set"))) {
if (Osz(rde)) {
if (ambiguous || Mode(rde) != XED_MODE_REAL) {
*p++ = 'w';
Expand Down
2 changes: 1 addition & 1 deletion blink/endswith.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

#include "blink/util.h"

bool endswith(const char *s, const char *suffix) {
bool EndsWith(const char *s, const char *suffix) {
size_t n, m;
n = strlen(s);
m = strlen(suffix);
Expand Down
16 changes: 8 additions & 8 deletions blink/loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -298,12 +298,12 @@ static void ExplainWhyItCantBeEmulated(const char *path, const char *reason) {
}

static bool IsBinFile(const char *prog) {
return endswith(prog, ".bin") || //
endswith(prog, ".BIN") || //
endswith(prog, ".img") || //
endswith(prog, ".IMG") || //
endswith(prog, ".raw") || //
endswith(prog, ".RAW");
return EndsWith(prog, ".bin") || //
EndsWith(prog, ".BIN") || //
EndsWith(prog, ".img") || //
EndsWith(prog, ".IMG") || //
EndsWith(prog, ".raw") || //
EndsWith(prog, ".RAW");
}

bool IsSupportedExecutable(const char *path, void *image, size_t size) {
Expand Down Expand Up @@ -752,8 +752,8 @@ error: unsupported executable; we need:\n\
}
if (m->mode.genmode == XED_GEN_MODE_REAL) {
LoadBios(m, biosprog);
if (endswith(prog, ".com") || //
endswith(prog, ".COM")) {
if (EndsWith(prog, ".com") || //
EndsWith(prog, ".COM")) {
// cosmo convention (see also binbase)
AddFileMap(m->system, 4 * 1024 * 1024, 512, prog, 0);
} else {
Expand Down
13 changes: 7 additions & 6 deletions blink/log.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@

#define DEFAULT_LOG_PATH "blink.log"

#define APPEND(F, ...) n += F(b + n, n > PIPE_BUF ? 0 : PIPE_BUF - n, __VA_ARGS__)
#define APPEND(F, ...) \
n += F(b + n, n > PIPE_BUF ? 0 : PIPE_BUF - n, __VA_ARGS__)

static struct Log {
pthread_once_t_ once;
Expand Down Expand Up @@ -126,8 +127,8 @@ static void OpenLog(void) {

static void Log(const char *file, int line, const char *fmt, va_list va,
int level) {
char b[4096];
int err, n = 0;
char b[PIPE_BUF];
err = errno;
unassert(!pthread_once_(&g_log.once, OpenLog));
APPEND(snprintf, "%c%s:%s:%d:%d ", "EI"[level], GetTimestamp(), file, line,
Expand All @@ -136,10 +137,10 @@ static void Log(const char *file, int line, const char *fmt, va_list va,
APPEND(snprintf, "\n");
if (n > PIPE_BUF - 1) {
n = PIPE_BUF - 1;
b[n-1] = '\n';
b[n-2] = '.';
b[n-3] = '.';
b[n-4] = '.';
b[n - 1] = '\n';
b[n - 2] = '.';
b[n - 3] = '.';
b[n - 4] = '.';
}
if (g_log.fd != -1) {
WriteError(g_log.fd, b, n);
Expand Down
151 changes: 78 additions & 73 deletions blink/machine.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@
#include <signal.h>
#include <stdbool.h>

#ifdef __COSMOPOLITAN__
#define _COSMO_SOURCE
#include <libc/dce.h>
#endif

#include "blink/atomic.h"
#include "blink/builtin.h"
#include "blink/dll.h"
Expand Down Expand Up @@ -324,78 +329,78 @@ struct MachineTlb {
u64 entry;
};

struct Machine { //
u64 ip; // instruction pointer
u8 oplen; // length of operation
struct XedMachineMode mode; // [dup] XED_MACHINE_MODE_REAL etc.
bool threaded; // must use synchronization
_Atomic(bool) attention; // signals main interpreter loop
u32 flags; // x86 eflags register
i64 stashaddr; // it's our page overlap buffer
union { // GENERAL REGISTER FILE
u64 align8_; //
u8 beg[128]; //
u8 weg[16][8]; //
struct { //
union { //
u8 ax[8]; // [vol] accumulator, result:1/2
struct { //
u8 al; // lo byte of ax
u8 ah; // hi byte of ax
}; //
}; //
union { //
u8 cx[8]; // [vol] param:4/6
struct { //
u8 cl; // lo byte of cx
u8 ch; // hi byte of cx
}; //
}; //
union { //
u8 dx[8]; // [vol] param:3/6, result:2/2
struct { //
u8 dl; // lo byte of dx
u8 dh; // hi byte of dx
}; //
}; //
union { //
u8 bx[8]; // [sav] base index
struct { //
u8 bl; // lo byte of bx
u8 bh; // hi byte of bx
}; //
}; //
u8 sp[8]; // [sav] stack pointer
u8 bp[8]; // [sav] backtrace pointer
u8 si[8]; // [vol] param:2/6
u8 di[8]; // [vol] param:1/6
u8 r8[8]; // [vol] param:5/6
u8 r9[8]; // [vol] param:6/6
u8 r10[8]; // [vol]
u8 r11[8]; // [vol]
u8 r12[8]; // [sav]
u8 r13[8]; // [sav]
u8 r14[8]; // [sav]
u8 r15[8]; // [sav]
}; //
}; //
_Alignas(16) u8 xmm[16][16]; // 128-BIT VECTOR REGISTER FILE
struct XedDecodedInst *xedd; // ->opcache->icache if non-jit
i64 readaddr; // so tui can show memory reads
i64 writeaddr; // so tui can show memory write
i64 readsize; // bytes length of last read op
i64 writesize; // byte length of last write op
union { //
struct DescriptorCache seg[8]; //
struct { //
struct DescriptorCache es; // xtra segment (legacy / real)
struct DescriptorCache cs; // code segment (legacy / real)
struct DescriptorCache ss; // stak segment (legacy / real)
struct DescriptorCache ds; // data segment (legacy / real)
struct DescriptorCache fs; // thred-local segment register
struct DescriptorCache gs; // winple thread-local register
}; //
}; //
struct Machine { //
u64 ip; // instruction pointer
u8 oplen; // length of operation
struct XedMachineMode mode; // [dup] XED_MACHINE_MODE_REAL etc.
bool threaded; // must use synchronization
_Atomic(bool) attention; // signals main interpreter loop
u32 flags; // x86 eflags register
i64 stashaddr; // it's our page overlap buffer
union { // GENERAL REGISTER FILE
u64 align8_; //
u8 beg[128]; //
u8 weg[16][8]; //
struct { //
union { //
u8 ax[8]; // [vol] accumulator, result:1/2
struct { //
u8 al; // lo byte of ax
u8 ah; // hi byte of ax
}; //
}; //
union { //
u8 cx[8]; // [vol] param:4/6
struct { //
u8 cl; // lo byte of cx
u8 ch; // hi byte of cx
}; //
}; //
union { //
u8 dx[8]; // [vol] param:3/6, result:2/2
struct { //
u8 dl; // lo byte of dx
u8 dh; // hi byte of dx
}; //
}; //
union { //
u8 bx[8]; // [sav] base index
struct { //
u8 bl; // lo byte of bx
u8 bh; // hi byte of bx
}; //
}; //
u8 sp[8]; // [sav] stack pointer
u8 bp[8]; // [sav] backtrace pointer
u8 si[8]; // [vol] param:2/6
u8 di[8]; // [vol] param:1/6
u8 r8[8]; // [vol] param:5/6
u8 r9[8]; // [vol] param:6/6
u8 r10[8]; // [vol]
u8 r11[8]; // [vol]
u8 r12[8]; // [sav]
u8 r13[8]; // [sav]
u8 r14[8]; // [sav]
u8 r15[8]; // [sav]
}; //
}; //
_Alignas(16) u8 xmm[16][16]; // 128-BIT VECTOR REGISTER FILE
struct XedDecodedInst *xedd; // ->opcache->icache if non-jit
i64 readaddr; // so tui can show memory reads
i64 writeaddr; // so tui can show memory write
i64 readsize; // bytes length of last read op
i64 writesize; // byte length of last write op
union { //
struct DescriptorCache seg[8]; //
struct { //
struct DescriptorCache es; // xtra segment (legacy / real)
struct DescriptorCache cs; // code segment (legacy / real)
struct DescriptorCache ss; // stak segment (legacy / real)
struct DescriptorCache ds; // data segment (legacy / real)
struct DescriptorCache fs; // thred-local segment register
struct DescriptorCache gs; // winple thread-local register
}; //
}; //
struct MachineFpu fpu; // FLOATING-POINT REGISTER FILE
u32 mxcsr; // SIMD status control register
pthread_t thread; // POSIX thread of this machine
Expand Down Expand Up @@ -435,7 +440,7 @@ struct Machine { //
struct Dll elem; //
struct SmcQueue smcqueue; //
struct OpCache opcache[1]; //
}; //
}; //

extern _Thread_local siginfo_t g_siginfo;
extern _Thread_local struct Machine *g_machine;
Expand Down
31 changes: 31 additions & 0 deletions blink/mkfifo.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*-*- 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 2023 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 <fcntl.h>
#include <sys/stat.h>

#include "blink/errno.h"
#include "blink/log.h"

int mkfifo_(const char *ph, mode_t mode) {
#ifdef HAVE_MKFIFO
return mkfifo(ph, mode);
#else
return enosys();
#endif
}
4 changes: 3 additions & 1 deletion blink/ssemov.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,9 @@ static void MovdqaWdqVdq(P) {
u8 *dst;
IGNORE_RACES_START();
dst = GetXmmAddress(A);
if (!IsRomAddress(m, dst)) memcpy(dst, XmmRexrReg(m, rde), 16);
if (!IsRomAddress(m, dst)) {
memcpy(dst, XmmRexrReg(m, rde), 16);
}
IGNORE_RACES_END();
if (IsMakingPath(m)) {
Jitter(A, "z4A" // 128-bit GetReg
Expand Down
2 changes: 1 addition & 1 deletion blink/startswith.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
╚─────────────────────────────────────────────────────────────────────────────*/
#include "blink/util.h"

bool startswith(const char *s, const char *p) {
bool StartsWith(const char *s, const char *p) {
for (;;) {
if (!*p) return true;
if (!*s) return false;
Expand Down
8 changes: 8 additions & 0 deletions blink/syscall.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ bool CheckInterrupt(struct Machine *, bool);
int SysStatfs(struct Machine *, i64, i64);
int SysFstatfs(struct Machine *, i32, i64);
int mkfifoat_(int, const char *, mode_t);
int mkfifo_(const char *, mode_t);

void Strace(struct Machine *, const char *, bool, const char *, ...);

Expand All @@ -86,4 +87,11 @@ void Strace(struct Machine *, const char *, bool, const char *, ...);
#define mkfifoat mkfifoat_
#endif

#ifndef HAVE_MKFIFO
#ifdef mkfifo
#undef mkfifo
#endif
#define mkfifo mkfifo_
#endif

#endif /* BLINK_SYSCALL_H_ */
4 changes: 2 additions & 2 deletions blink/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ int GetOpt(int, char *const[], const char *);
u64 tpenc(uint32_t);
const char *DescribeSignal(int);
const char *DescribeHostErrno(int);
bool endswith(const char *, const char *);
bool startswith(const char *, const char *);
bool EndsWith(const char *, const char *);
bool StartsWith(const char *, const char *);
const char *doublenul(const char *, unsigned);
ssize_t readansi(int, char *, size_t);
char *FormatInt64(char *, int64_t);
Expand Down
8 changes: 3 additions & 5 deletions blink/x86.c
Original file line number Diff line number Diff line change
Expand Up @@ -770,16 +770,14 @@ int DecodeInstruction(struct XedDecodedInst *x, const void *itext, size_t bytes,
}
rc = xed_decode_instruction_length(x);
rde = x->op.rde;
rde |= (Opcode(rde) & 7) << 12; // srm
rde |= (Opcode(rde) & 7) << 12; // srm
if (Mode(rde) == XED_MODE_REAL) {
// in 16-bit mode, flip osz, except for SIMD instructions & cmpxchg8b;
// for SIMD instructions, 0x66 always refers to instructions with larger
// operands, & lack of 0x66 to instructions with smaller operands
u16 mop = Mopcode(rde);
if ((mop >= 0x150 && mop <= 0x176) ||
(mop >= 0x17C && mop <= 0x17F) ||
mop == 0x1C2 ||
(mop >= 0x1C4 && mop <= 0x1C7) ||
if ((mop >= 0x150 && mop <= 0x176) || (mop >= 0x17C && mop <= 0x17F) ||
mop == 0x1C2 || (mop >= 0x1C4 && mop <= 0x1C7) ||
(mop >= 0x1D0 && mop <= 0x1FE)) {
(void)rde;
} else {
Expand Down
1 change: 1 addition & 0 deletions config.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
// #define HAVE_INT128
// #define HAVE_SA_LEN
// #define HAVE_PREADV
// #define HAVE_MKFIFO
// #define HAVE_WCWIDTH
// #define HAVE_SYSINFO
// #define HAVE_FEXECVE
Expand Down
Loading

0 comments on commit 92fc4d0

Please sign in to comment.