Make blink support conditionally linkable into APE

This commit is contained in:
Justine Tunney 2023-06-17 07:55:35 -07:00
parent 52d28966f7
commit 562a1384cd
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
21 changed files with 288 additions and 269 deletions

View file

@ -25,8 +25,7 @@
#include "libc/sysv/consts/termios.h"
#include "libc/sysv/errfuns.h"
extern const unsigned TIOCPTSNAME;
#define TIOCGPTN 0x80045430 // linux
#define TIOCPTYGNAME 0x40807453 // xnu
#define TIOCPTSNAME 0x48087448 // netbsd
#define FIODGNAME 0x80106678 // freebsd

View file

@ -25,7 +25,8 @@
#include "libc/sysv/consts/pty.h"
#include "libc/sysv/errfuns.h"
#define TIOCPTYUNLK 0x20007452
#define TIOCSPTLCK 0x40045431 // linux
#define TIOCPTYUNLK 0x20007452 // xnu
/**
* Unlocks pseudoteletypewriter pair.

View file

@ -17,8 +17,10 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/calls.h"
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/dce.h"
#include "libc/fmt/fmt.h"
#include "libc/intrin/kprintf.h"
#include "libc/fmt/itoa.h"
#include "libc/intrin/safemacros.internal.h"
#include "libc/log/color.internal.h"
#include "libc/log/gdb.h"
@ -31,9 +33,11 @@
#include "libc/runtime/symbols.internal.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/at.h"
#include "libc/sysv/consts/fileno.h"
#include "libc/sysv/consts/o.h"
#include "libc/sysv/consts/w.h"
#include "libc/sysv/errfuns.h"
/**
* Launches GDB debugger GUI for current process.
@ -54,14 +58,18 @@
relegated int(AttachDebugger)(intptr_t continuetoaddr) {
int pid, ttyfd;
struct StackFrame *bp;
char pidstr[11], breakcmd[40];
char pidstr[12], breakcmd[40];
const char *se, *elf, *gdb, *rewind, *layout;
__restore_tty();
if (IsGenuineBlink() || !(gdb = GetGdbPath()) || !isatty(0) || !isatty(1) ||
(ttyfd = open(_PATH_TTY, O_RDWR | O_CLOEXEC)) == -1) {
return -1;
if (!IsLinux() || //
IsGenuineBlink() || //
!(gdb = GetGdbPath()) || //
!isatty(0) || //
!isatty(1) || //
(ttyfd = sys_openat(AT_FDCWD, _PATH_TTY, O_RDWR | O_CLOEXEC, 0)) == -1) {
return enosys();
}
ksnprintf(pidstr, sizeof(pidstr), "%u", getpid());
FormatUint32(pidstr, getpid());
layout = "layout asm";
if ((elf = FindDebugBinary())) {
se = "-se";
@ -76,29 +84,31 @@ relegated int(AttachDebugger)(intptr_t continuetoaddr) {
continuetoaddr = bp->addr;
}
rewind = "-ex";
ksnprintf(breakcmd, sizeof(breakcmd), "%s *%#p", "break", continuetoaddr);
FormatHex64(stpcpy(breakcmd, "break *"), continuetoaddr, 1);
} else {
rewind = NULL;
breakcmd[0] = '\0';
}
if (!(pid = fork())) {
dup2(ttyfd, 0);
dup2(ttyfd, 1);
execv(gdb, (char *const[]){
"gdb", "--tui",
"-p", pidstr,
se, elf,
"-ex", "set osabi GNU/Linux",
"-ex", "set complaints 0",
"-ex", "set confirm off",
"-ex", layout,
"-ex", "layout reg",
"-ex", "set var g_gdbsync = 1",
"-q", rewind,
breakcmd, "-ex",
"c", NULL,
});
abort();
sys_dup2(ttyfd, 0, 0);
sys_dup2(ttyfd, 1, 0);
__sys_execve(gdb,
(char *const[]){
"gdb", "--tui",
"-p", pidstr,
se, elf,
"-ex", "set osabi GNU/Linux",
"-ex", "set complaints 0",
"-ex", "set confirm off",
"-ex", layout,
"-ex", "layout reg",
"-ex", "set var g_gdbsync = 1",
"-q", rewind,
breakcmd, "-ex",
"c", NULL,
},
environ);
__builtin_trap();
}
return pid;
}

View file

@ -0,0 +1,60 @@
/*-*- 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 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 "libc/macros.internal.h"
// Blink Virtual Machine for Linux Arm64
//
// If you want to support Raspberry Pi by embedding an emulator
// in your APE binary that runs automatically, then put this:
//
// STATIC_YOINK("blink_linux_aarch64");
//
// In your main.c file, to pull it into linkage from the static
// archive. Alternatively, you may simply add blink_linux_aarch64.o
// as an explicit linker argument.
.section .blink,"a",@progbits
.globl blink_linux_aarch64_size
blink_linux_aarch64:
.incbin "ape/blink-linux-aarch64.gz"
.endobj blink_linux_aarch64,globl
blink_linux_aarch64_size = . - blink_linux_aarch64
.section .emush,"a",@progbits
.ascii "if [ \"$s\" = Linux ]; then\n"
.ascii "if [ \"$m\" = aarch64 ] || [ \"$m\" = arm64 ]; then\n"
.ascii "if ! [ -x \"$e\" ]; then\n"
.ascii "echo \"extracting blink-linux-aarch64 to ${e}\" >&2\n"
.ascii "dd if=\"$o\" bs=1 skip=$(("
.weak blink_linux_aarch64_quad
.quad blink_linux_aarch64_quad
.weak blink_linux_aarch64_short
.short blink_linux_aarch64_short
.ascii ")) count=$(("
.weak blink_linux_aarch64_size_quad
.quad blink_linux_aarch64_size_quad
.weak blink_linux_aarch64_size_short
.short blink_linux_aarch64_size_short
.ascii ")) conv=notrunc 2>/dev/null | gunzip >\"$e.$$\"\n"
.ascii "mv -f \"$e.$$\" \"$e\"\n"
.ascii "chmod +x \"$e\"\n"
.ascii "fi\n"
.ascii "exec \"$e\" \"$o\" \"$@\"\n"
.ascii "fi\n"
.ascii "fi\n"

View file

@ -0,0 +1,58 @@
/*-*- 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 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 "libc/macros.internal.h"
// Blink Virtual Machine for Apple Silicon
//
// If you want to support Apple M1 by embedding an emulator in
// your APE binary that runs automatically, then put this:
//
// STATIC_YOINK("blink_xnu_aarch64");
//
// In your main.c file, to pull it into linkage from the static
// archive. Alternatively, you may simply add blink_xnu_aarch64.o
// as an explicit linker argument.
.section .blink,"a",@progbits
.globl blink_xnu_aarch64_size
blink_xnu_aarch64:
.incbin "ape/blink-xnu-aarch64.gz"
.endobj blink_xnu_aarch64,globl
blink_xnu_aarch64_size = . - blink_xnu_aarch64
.section .emush,"a",@progbits
.ascii "if [ \"$s\" = Darwin ] && [ \"$m\" = arm64 ]; then\n"
.ascii "if ! [ -x \"$e\" ]; then\n"
.ascii "echo \"extracting blink-darwin-aarch64 to ${e}\" >&2\n"
.ascii "dd if=\"$o\" bs=1 skip=$(("
.weak blink_xnu_aarch64_quad
.quad blink_xnu_aarch64_quad
.weak blink_xnu_aarch64_short
.short blink_xnu_aarch64_short
.ascii ")) count=$(("
.weak blink_xnu_aarch64_size_quad
.quad blink_xnu_aarch64_size_quad
.weak blink_xnu_aarch64_size_short
.short blink_xnu_aarch64_size_short
.ascii ")) conv=notrunc 2>/dev/null | gunzip >\"$e.$$\"\n"
.ascii "mv -f \"$e.$$\" \"$e\"\n"
.ascii "chmod +x \"$e\"\n"
.ascii "fi\n"
.ascii "exec \"$e\" \"$o\" \"$@\"\n"
.ascii "fi\n"

View file

@ -88,6 +88,10 @@ o/$(MODE)/libc/nexgen32e/gclongjmp.o: libc/nexgen32e/gclongjmp.S
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
o/$(MODE)/libc/nexgen32e/checkstackalign.o: libc/nexgen32e/checkstackalign.S
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
o/$(MODE)/libc/nexgen32e/blink_xnu_aarch64.o: libc/nexgen32e/blink_xnu_aarch64.S
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
o/$(MODE)/libc/nexgen32e/blink_linux_aarch64.o: libc/nexgen32e/blink_linux_aarch64.S
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
LIBC_NEXGEN32E_LIBS = $(foreach x,$(LIBC_NEXGEN32E_ARTIFACTS),$($(x)))
LIBC_NEXGEN32E_SRCS = $(foreach x,$(LIBC_NEXGEN32E_ARTIFACTS),$($(x)_SRCS))

View file

@ -1451,8 +1451,6 @@ syscon termios CSTOP 19 19 19 19 19 19 19 0 # unix consensus
# Pseudoteletypewriter Control
#
# group name GNU/Systemd GNU/Systemd (Aarch64) XNU's Not UNIX! MacOS (Arm64) FreeBSD OpenBSD NetBSD The New Technology Commentary
syscon pty TIOCGPTN 0x80045430 0x80045430 0 0 0x4004740f 0 0 0 # boop
syscon pty TIOCSPTLCK 0x40045431 0x40045431 0 0 0 0 0 0 # boop
syscon pty TIOCPKT 0x5420 0x5420 0x80047470 0x80047470 0x80047470 0x80047470 0x80047470 -1 # boop
syscon pty TIOCPKT_DATA 0 0 0 0 0 0 0 0 # consensus
syscon pty TIOCPKT_FLUSHREAD 1 1 1 1 1 1 1 1 # unix consensus

View file

@ -1,2 +0,0 @@
#include "libc/sysv/consts/syscon.internal.h"
.syscon pty,TIOCGPTN,0x80045430,0x80045430,0,0,0x4004740f,0,0,0

View file

@ -1,2 +0,0 @@
#include "libc/sysv/consts/syscon.internal.h"
.syscon pty,TIOCSPTLCK,0x40045431,0x40045431,0,0,0,0,0,0

View file

@ -12,7 +12,6 @@ extern const int TIOCPKT_IOCTL;
extern const int TIOCPKT_NOSTOP;
extern const int TIOCPKT_START;
extern const int TIOCPKT_STOP;
extern const int TIOCSPTLCK;
#define TIOCPKT_DATA 0x00
#define TIOCPKT_DOSTOP 0x01
@ -23,11 +22,9 @@ extern const int TIOCSPTLCK;
#define TIOCPKT_START 0x20
#define TIOCPKT_STOP 0x40
#define TIOCPKT TIOCPKT
#define TIOCSPTLCK TIOCSPTLCK
#define TIOCPKT TIOCPKT
#define __tmpcosmo_TIOCPKT -1036987649
#define __tmpcosmo_TIOCSPTLCK 372918192
#define __tmpcosmo_TIOCPKT -1036987649
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */

View file

@ -81,7 +81,6 @@ extern const int TCSAFLUSH;
extern const int TCSANOW;
extern const uint64_t TIOCCONS;
extern const uint64_t TIOCGETD;
extern const uint64_t TIOCGPTN;
extern const uint64_t TIOCGWINSZ;
extern const uint64_t TIOCNOTTY;
extern const uint64_t TIOCNXCL;
@ -211,7 +210,6 @@ extern const uint32_t CRTSCTS;
#define TCSANOW 0
#define TIOCCONS TIOCCONS
#define TIOCGETD TIOCGETD
#define TIOCGPTN TIOCGPTN
#define TIOCGWINSZ TIOCGWINSZ
#define TIOCNOTTY TIOCNOTTY
#define TIOCNXCL TIOCNXCL
@ -308,7 +306,6 @@ extern const uint32_t CRTSCTS;
#define __tmpcosmo_TCOFLUSH 659539281
#define __tmpcosmo_TIOCCONS 1455144588
#define __tmpcosmo_TIOCGETD 470897144
#define __tmpcosmo_TIOCGPTN 67701595
#define __tmpcosmo_TIOCGWINSZ 965491756
#define __tmpcosmo_TIOCNOTTY 1073131930
#define __tmpcosmo_TIOCNXCL 1210582499

View file

@ -16,6 +16,7 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/intrin/kprintf.h"
#include "libc/stdio/stdio.h"
#include "libc/testlib/ezbench.h"
#include "libc/testlib/testlib.h"
@ -38,7 +39,7 @@ double __testlib_ezbenchcontrol(void) {
if (Tries == 10) {
fputs("warning: failed to accurately benchmark control\n", stderr);
}
fprintf(stderr, "will subtract benchmark overhead of %g cycles\n\n",
kprintf("will subtract benchmark overhead of %g cycles\n\n",
g_ezbenchcontrol);
once = true;
}

View file

@ -16,12 +16,13 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/intrin/kprintf.h"
#include "libc/stdio/stdio.h"
#include "libc/testlib/testlib.h"
void testlib_incrementfailed(void) {
if (++g_testlib_failed > 23) {
fprintf(stderr, "too many failures, aborting\n");
kprintf("too many failures, aborting\n");
testlib_abort();
}
}

View file

@ -27,6 +27,7 @@
#include "libc/fmt/fmt.h"
#include "libc/fmt/itoa.h"
#include "libc/intrin/atomic.h"
#include "libc/intrin/kprintf.h"
#include "libc/intrin/strace.internal.h"
#include "libc/intrin/weaken.h"
#include "libc/log/check.h"
@ -55,8 +56,7 @@ static pthread_mutex_t testlib_error_lock;
void testlib_finish(void) {
if (g_testlib_failed) {
fprintf(stderr, "%u / %u %s\n", g_testlib_failed, g_testlib_ran,
"tests failed");
kprintf("%u / %u %s\n", g_testlib_failed, g_testlib_ran, "tests failed");
}
}
@ -163,7 +163,7 @@ static void CheckForFileDescriptors(void) {
for (i = 0; i < ARRAYLEN(pfds); ++i) {
if (pfds[i].revents & POLLNVAL) continue;
++g_testlib_failed;
fprintf(stderr, "error: test failed to close() fd %d\n", pfds[i].fd);
kprintf("error: test failed to close() fd %d\n", pfds[i].fd);
}
}
#endif
@ -182,7 +182,7 @@ static void CheckForZombies(void) {
break;
} else {
++g_testlib_failed;
fprintf(stderr, "error: test failed to reap zombies %d\n", pid);
kprintf("error: test failed to reap zombies %d\n", pid);
}
}
#endif