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