From b846a7a0ea77de85c0d84d3653d8db8d3c81b4c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C5=99emysl=20Janouch?= Date: Sat, 24 Dec 2016 22:27:38 +0100 Subject: [PATCH] Add support for OpenBSD It just rejects the generic System V ABI and has other syscall numbers. --- Makefile | 8 +++++--- README.adoc | 6 +++--- bfc-amd64-linux.c => bfc-amd64.c | 15 +++++++++++++-- 3 files changed, 21 insertions(+), 8 deletions(-) rename bfc-amd64-linux.c => bfc-amd64.c (97%) diff --git a/Makefile b/Makefile index 5bb5db1..d25311c 100644 --- a/Makefile +++ b/Makefile @@ -1,11 +1,13 @@ # All we need is C99 and POSIX, which this should make available CFLAGS = -std=gnu99 -NAMES = bfc-amd64-linux +NAMES = bfc-amd64-linux bfc-amd64-openbsd all: $(NAMES) -%: %.c - $(CC) $(CPPFLAGS) $(CFLAGS) $< -o $@ +%-linux: %.c + $(CC) $(CPPFLAGS) $(CFLAGS) $< -o $@ -DTARGET_LINUX +%-openbsd: %.c + $(CC) $(CPPFLAGS) $(CFLAGS) $< -o $@ -DTARGET_OPENBSD clean: rm -f $(NAMES) diff --git a/README.adoc b/README.adoc index e04e8bd..69ebd7e 100644 --- a/README.adoc +++ b/README.adoc @@ -1,8 +1,8 @@ bfc === -'bfc' is a small, fast, self-contained, optimizing Brainfuck compiler for Linux -on Intel x86-64. +'bfc' is a small, fast, self-contained, optimizing Brainfuck compiler for *nix +on Intel x86-64. Currently supported targets are Linux and OpenBSD. Also included are several interpreters in various states of sophistication that document my progress as I was writing this, from the simplest approach to an @@ -14,7 +14,7 @@ The compiler itself is platform agnostic. Building -------- Build dependencies: a C99 compiler + -Runtime dependencies: Linux +Runtime dependencies: Linux or OpenBSD $ git clone https://github.com/pjanouch/bfc.git $ cd bfc diff --git a/bfc-amd64-linux.c b/bfc-amd64.c similarity index 97% rename from bfc-amd64-linux.c rename to bfc-amd64.c index 1579681..9681ca1 100644 --- a/bfc-amd64-linux.c +++ b/bfc-amd64.c @@ -580,7 +580,13 @@ main (int argc, char *argv[]) // args -> rdi, rsi, rdx, r10, r8, r9 // trashed <- rcx, r11 +#ifdef TARGET_OPENBSD + enum { SYS_READ = 3, SYS_WRITE = 4, SYS_EXIT = 1 }; +#elif defined TARGET_LINUX enum { SYS_READ = 0, SYS_WRITE = 1, SYS_EXIT = 60 }; +#else +#error Target not supported +#endif CODE ("\xB8") DD (SYS_EXIT) // mov eax, 0x3c CODE ("\x48\x31\xFF") // xor rdi, rdi @@ -605,7 +611,7 @@ main (int argc, char *argv[]) size_t read_offset = buffer.len; CODE ("\x50") // push rax -- save tape position CODE ("\xB8") DD (SYS_READ) // mov eax, "SYS_READ" - CODE ("\x48\x89\xC7") // mov rdi, rax -- STDIN_FILENO + CODE ("\xBF") DD (0) // mov edi, "STDIN_FILENO" CODE ("\x66\x6A\x00") // push word 0 -- the default value for EOF CODE ("\x48\x89\xE6") // mov rsi, rsp -- the char starts at rsp CODE ("\xBA") DD (1) // mov edx, 1 -- count @@ -623,7 +629,7 @@ main (int argc, char *argv[]) size_t write_offset = buffer.len; CODE ("\x50") // push rax -- save tape position CODE ("\xB8") DD (SYS_WRITE) // mov eax, "SYS_WRITE" - CODE ("\x48\x89\xC7") // mov rdi, rax -- STDOUT_FILENO + CODE ("\xBF") DD (1) // mov edi, "STDOUT_FILENO" CODE ("\x66\x53") // push bx CODE ("\x48\x89\xE6") // mov rsi, rsp -- the char starts at rsp CODE ("\xBA") DD (1) // mov edx, 1 -- count @@ -683,7 +689,12 @@ main (int argc, char *argv[]) // ELF header CODE ("\x7F" "ELF\x02\x01\x01") // ELF, 64-bit, little endian, v1 +#ifdef TARGET_OPENBSD + // OpenBSD either requires its ABI or a PT_NOTE with "OpenBSD" in it + CODE ("\x0C\x00" "\0\0\0\0\0\0\0") // OpenBSD ABI, v0, padding +#else CODE ("\x00\x00" "\0\0\0\0\0\0\0") // Unix System V ABI, v0, padding +#endif DW (2) DW (62) DD (1) // executable, x86-64, v1 DQ (ELF_LOAD_CODE + ELF_META_SIZE) // entry point address DQ (ELF_HEADER_SIZE) DQ (0) // program, section header offset