Skip to content

Commit

Permalink
Support baseline POSIX standard
Browse files Browse the repository at this point in the history
Many more configuration checks have been added in order to in theory
support baseline POSIX systems, without XSI extensions. Bugs are now
fixed in interfaces like SIOCGIFCONF, getrandom(), getresuid(), etc.
Executable loading is greatly improved. Blink will now handle script
shebang lines. Detection of non-Linux binaries has improved too.
  • Loading branch information
jart committed Feb 13, 2023
1 parent b7c93c1 commit 3807eb8
Show file tree
Hide file tree
Showing 91 changed files with 2,115 additions and 710 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ blink.log
/TAGS
/HTAGS
/config.h
/config.mk
/config.log
/*.dump
/gmon.out
Expand Down
9 changes: 3 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

SHELL = /bin/sh
MAKEFLAGS += --no-builtin-rules
ARCHITECTURES = x86_64 x86_64-gcc49 i486 aarch64 riscv64 arm mips s390x mipsel mips64 mips64el powerpc powerpc64le
ARCHITECTURES = x86_64 x86_64-gcc49 i486 aarch64 arm mips s390x mipsel mips64 mips64el powerpc powerpc64le

.SUFFIXES:
.DELETE_ON_ERROR:
Expand All @@ -20,10 +20,7 @@ MODE := $(m)
endif
endif

HOST_SYSTEM := $(shell uname -s)
HOST_ARCH := $(shell uname -m)
HOST_OS := $(shell uname -o 2>/dev/null)
TMPDIR := $(shell mkdir -p o/tmp; echo $(shell pwd)/o/tmp)
include config.mk

ifneq ($(HOST_SYSTEM), Linux)
VM = o/$(MODE)/blink/blink
Expand Down Expand Up @@ -167,7 +164,7 @@ HTAGS: o/$(MODE)/hdrs.txt $(HDRS)
build/htags -L $< -o $@

clean:
rm -f $(OBJS) o/$(MODE)/blink/blink o/$(MODE)/blink/blinkenlights o/$(MODE)/blink/blink.a
rm -f $(OBJS) o/$(MODE)/blink/blink o/$(MODE)/blink/blinkenlights o/$(MODE)/blink/blink.a o/$(MODE)/third_party/zlib/zlib.a

distclean:
rm -rf o
Expand Down
14 changes: 11 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ do the same thing as the `qemu-x86_64` command, except that
1. Blink is 196kb in size (or 126kb if optional features are disabled),
whereas the qemu-x86_64 executable is 4mb in size.

2. Blink will run your Linux binaries on any POSIX platform, whereas
2. Blink will run your Linux binaries on any POSIX system, whereas
qemu-x86_64 only supports Linux.

3. Blink goes 2x faster than qemu-x86_64 on some benchmarks, such as SSE
Expand Down Expand Up @@ -44,11 +44,11 @@ following platforms:

Blink depends on the following libraries:

- libc (POSIX.1-2017)
- libc (POSIX.1-2017 baseline, XSI not required)

Blink can be compiled on UNIX systems that have:

- A C11 compiler (e.g. GCC 4.9.4+)
- A C11 compiler with atomics (e.g. GCC 4.9.4+)
- Modern GNU Make (i.e. not the one that comes with XCode)

The instructions for compiling Blink are as follows:
Expand Down Expand Up @@ -129,6 +129,14 @@ You can hunt down bugs in Blink using the following build modes:
- `MODE=ubsan` to find violations of the C standard
- `MODE=msan` helps find uninitialized memory errors

You can check Blink's compliance with the POSIX standard using the
following configuration flags:

```sh
./configure --posix # only use c11 with baseline posix standard
./configure --xopen # same but also allow use of xsi extensions
```

### Testing

Blink is tested primarily using precompiled binaries downloaded
Expand Down
10 changes: 5 additions & 5 deletions blink/ancillary.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ static int AppendCmsg(struct Machine *m, struct msghdr *msg, int level,
return 0;
}

#ifdef SCM_CREDENTIALS
#ifdef HAVE_SCM_CREDENTIALS
static int SendScmCredentials(struct Machine *m, struct msghdr *msg,
const struct ucred_linux *payload,
size_t elements) {
Expand Down Expand Up @@ -103,7 +103,7 @@ static ssize_t GetAncillaryElementLength(const struct cmsghdr_linux *gcmsg) {
case SCM_RIGHTS_LINUX:
return 4;
#endif
#ifdef SCM_CREDENTIALS
#ifdef HAVE_SCM_CREDENTIALS
case SCM_CREDENTIALS_LINUX:
return sizeof(struct ucred_linux);
#endif
Expand Down Expand Up @@ -179,7 +179,7 @@ int SendAncillary(struct Machine *m, struct msghdr *msg,
return -1;
break;
#endif
#ifdef SCM_CREDENTIALS
#ifdef HAVE_SCM_CREDENTIALS
case SCM_CREDENTIALS_LINUX:
if (SendScmCredentials(m, msg, (const struct ucred_linux *)payload,
elements) == -1)
Expand Down Expand Up @@ -271,7 +271,7 @@ static i64 ReceiveScmRights(struct Machine *m, struct msghdr_linux *gm,
}
#endif

#ifdef SCM_CREDENTIALS
#ifdef HAVE_SCM_CREDENTIALS
static i64 ReceiveScmCredentials(struct Machine *m, struct msghdr_linux *gm,
struct cmsghdr *cmsg, u64 offset) {
struct ucred_linux gucred;
Expand Down Expand Up @@ -301,7 +301,7 @@ static i64 ReceiveControlMessage(struct Machine *m, struct msghdr_linux *gm,
return ReceiveScmRights(m, gm, cmsg, offset, flags);
}
#endif
#ifdef SCM_CREDENTIALS
#ifdef HAVE_SCM_CREDENTIALS
if (cmsg->cmsg_type == SCM_CREDENTIALS) {
return ReceiveScmCredentials(m, gm, cmsg, offset);
}
Expand Down
7 changes: 4 additions & 3 deletions blink/argv.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,14 @@ static long GetGuestPageSize(struct Machine *m) {
}
}

void LoadArgv(struct Machine *m, char *prog, char **args, char **vars) {
void LoadArgv(struct Machine *m, char *execfn, char *prog, char **args,
char **vars) {
u8 *bytes;
char rng[16];
struct Elf *elf;
i64 sp, *p, *bloc;
size_t i, narg, nenv, naux, nall;
GetRandom(rng, 16);
unassert(GetRandom(rng, 16, 0) == 16);
elf = &m->system->elf;
naux = 10;
if (elf->at_entry) {
Expand All @@ -95,7 +96,7 @@ void LoadArgv(struct Machine *m, char *prog, char **args, char **vars) {
PUSH_AUXV(AT_PAGESZ_LINUX, GetGuestPageSize(m));
PUSH_AUXV(AT_CLKTCK_LINUX, sysconf(_SC_CLK_TCK));
PUSH_AUXV(AT_RANDOM_LINUX, PushBuffer(m, rng, 16));
PUSH_AUXV(AT_EXECFN_LINUX, PushString(m, g_blink_path));
PUSH_AUXV(AT_EXECFN_LINUX, PushString(m, execfn));
if (elf->at_entry) {
PUSH_AUXV(AT_PHDR_LINUX, elf->at_phdr);
PUSH_AUXV(AT_PHENT_LINUX, elf->at_phent);
Expand Down
9 changes: 5 additions & 4 deletions blink/blink.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ static void OnSigSegv(int sig, siginfo_t *si, void *ptr) {
siglongjmp(g_machine->onhalt, kMachineSegmentationFault);
}

static int Exec(char *prog, char **argv, char **envp) {
static int Exec(char *execfn, char *prog, char **argv, char **envp) {
int i;
sigset_t oldmask;
struct Machine *old;
Expand All @@ -123,7 +123,7 @@ static int Exec(char *prog, char **argv, char **envp) {
g_machine->system->exec = Exec;
if (!old) {
// this is the first time a program is being loaded
LoadProgram(g_machine, prog, argv, envp);
LoadProgram(g_machine, execfn, prog, argv, envp);
SetupCod(g_machine);
for (i = 0; i < 10; ++i) {
AddStdFd(&g_machine->system->fds, i);
Expand All @@ -137,7 +137,7 @@ static int Exec(char *prog, char **argv, char **envp) {
}
memcpy(g_machine->system->rlim, old->system->rlim,
sizeof(old->system->rlim));
LoadProgram(g_machine, prog, argv, envp);
LoadProgram(g_machine, execfn, prog, argv, envp);
g_machine->system->fds.list = old->system->fds.list;
old->system->fds.list = 0;
// releasing the execve() lock must come after unlocking fds
Expand Down Expand Up @@ -286,5 +286,6 @@ int main(int argc, char *argv[]) {
WriteErrorString("\n");
exit(127);
}
return Exec(g_pathbuf, argv + optind_ + FLAG_zero, environ);
argv[optind_] = g_pathbuf;
return Exec(g_pathbuf, g_pathbuf, argv + optind_ + FLAG_zero, environ);
}
Loading

0 comments on commit 3807eb8

Please sign in to comment.