diff --git a/Makefile b/Makefile
index 4dfeca3e4ea0edaa95f2745eeaf4ecd679682059..8f19b4737e332089607399408e947e8fe7e4ec1a 100644
--- a/Makefile
+++ b/Makefile
@@ -27,10 +27,7 @@ endif
 
 SRC=\
 	Cargo.* \
-	src/* \
-	src/*/* \
-	src/*/*/* \
-	src/*/*/*/*
+	$(shell find src -type f)
 
 .PHONY: all clean fmt headers install install-headers libs test
 
diff --git a/build.rs b/build.rs
index 5d4005b21feb3201d6ffbb4a21e06c4dd22653b4..1b7656f39f8ab40d6bcd300775662d4c07134dab 100644
--- a/build.rs
+++ b/build.rs
@@ -1,6 +1,6 @@
 extern crate cc;
 
-use std::env;
+use std::{env, fs};
 
 fn main() {
     let crate_dir = env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR not set");
@@ -8,16 +8,12 @@ fn main() {
     cc::Build::new()
         .flag("-nostdinc")
         .flag("-nostdlib")
-        .flag("-I")
-        .flag(&format!("{}/include", crate_dir))
+        .include(&format!("{}/include", crate_dir))
         .flag("-fno-stack-protector")
         .flag("-Wno-expansion-to-defined")
-        .file("src/c/dlmalloc.c")
-        .file("src/c/fcntl.c")
-        .file("src/c/stack_chk.c")
-        .file("src/c/stdio.c")
-        .file("src/c/stdlib.c")
-        .file("src/c/unistd.c")
+        .files(fs::read_dir("src/c")
+               .expect("src/c directory missing")
+               .map(|res| res.expect("read_dir error").path()))
         .compile("relibc_c");
 
     println!("cargo:rustc-link-lib=static=relibc_c");
diff --git a/include/bits/sys/ptrace.h b/include/bits/sys/ptrace.h
new file mode 100644
index 0000000000000000000000000000000000000000..568341c68fd9baceace56405eb9c11426c5b2895
--- /dev/null
+++ b/include/bits/sys/ptrace.h
@@ -0,0 +1,6 @@
+#ifndef _BITS_SYS_PTRACE_H
+#define _BITS_SYS_PTRACE_H
+
+int ptrace(int request, ...);
+
+#endif
diff --git a/src/c/fcntl.c b/src/c/fcntl.c
index 9aea06f0277893283c89808e5e83635ea8cd9a9d..76b92022e1017a55f3a52a185f14f26a1eb47e7d 100644
--- a/src/c/fcntl.c
+++ b/src/c/fcntl.c
@@ -1,6 +1,8 @@
 #include <stdarg.h>
 #include <sys/types.h>
 
+// TODO: Can be implemented in rust when cbindgen supports "..." syntax
+
 int sys_open(const char* filename, int flags, mode_t mode);
 
 int open(const char* filename, int flags, ...) {
diff --git a/src/c/ptrace.c b/src/c/ptrace.c
new file mode 100644
index 0000000000000000000000000000000000000000..513cb5d48091be8fa3eefe6e4d89c4d64234c6ae
--- /dev/null
+++ b/src/c/ptrace.c
@@ -0,0 +1,13 @@
+// TODO: Can be implemented in rust when cbindgen supports "..." syntax
+
+#include <stdarg.h>
+
+int sys_ptrace(int request, va_list ap);
+
+int ptrace(int request, ...) {
+    va_list ap;
+    va_start(ap, request);
+    int ret = sys_ptrace(request, ap);
+    va_end(ap);
+    return ret;
+}
diff --git a/src/c/stdio.c b/src/c/stdio.c
index fe4ab46b4b97703f5091bf82bebf10dfc62c9235..196ec6aca9be18f0c78602301a3072842963e22e 100644
--- a/src/c/stdio.c
+++ b/src/c/stdio.c
@@ -3,6 +3,8 @@
 
 typedef struct FILE FILE;
 
+// TODO: Can be implemented in rust when cbindgen supports "..." syntax
+
 int vasprintf(char ** strp, const char * fmt, va_list ap);
 
 int asprintf(char ** strp, const char * fmt, ...) {
diff --git a/src/c/unistd.c b/src/c/unistd.c
index 971cab32b3e9cb69513bd7919dff2001b0b0698d..ac2629e1dad49bb46cc1fdef8634a6bf5401b861 100644
--- a/src/c/unistd.c
+++ b/src/c/unistd.c
@@ -1,6 +1,8 @@
 #include <stdarg.h>
 #include <stddef.h>
 
+// TODO: Can be implemented in rust when cbindgen supports "..." syntax
+
 int execv(const char *path, char *const *argv);
 
 int execl(const char *path, const char* argv0, ...)
diff --git a/src/header/sys_ptrace/cbindgen.toml b/src/header/sys_ptrace/cbindgen.toml
index 3ecacd053429f1e8ded5635cada8ba39c08e1089..11bd11f6704acf53b22aedcd5f6edf62513713cf 100644
--- a/src/header/sys_ptrace/cbindgen.toml
+++ b/src/header/sys_ptrace/cbindgen.toml
@@ -2,6 +2,7 @@ sys_includes = []
 include_guard = "_SYS_PTRACE_H"
 language = "C"
 style = "Tag"
+trailer = "#include <bits/sys/ptrace.h>"
 
 [enum]
 prefix_with_name = true
diff --git a/src/header/sys_ptrace/mod.rs b/src/header/sys_ptrace/mod.rs
index 230c25ede07e8f33f17e2afb0ed520de233ec259..8b40fa8b4e2ed980216f982fec7bb4f4493b7d8b 100644
--- a/src/header/sys_ptrace/mod.rs
+++ b/src/header/sys_ptrace/mod.rs
@@ -1,8 +1,10 @@
 //! ptrace compatibility layer for Redox OS
 
+use core::ffi::VaList;
 use platform::types::*;
 use platform::{PalPtrace, Sys};
 
+pub const PTRACE_TRACEME: c_int = 0;
 pub const PTRACE_PEEKTEXT: c_int = 1;
 pub const PTRACE_PEEKDATA: c_int = 2;
 pub const PTRACE_POKETEXT: c_int = 4;
@@ -16,9 +18,11 @@ pub const PTRACE_GETFPREGS: c_int = 14;
 pub const PTRACE_SETFPREGS: c_int = 15;
 pub const PTRACE_ATTACH: c_int = 16;
 pub const PTRACE_DETACH: c_int = 17;
+pub const PTRACE_SYSCALL: c_int = 24;
 
+// Can't use "params: ..." syntax, because... guess what? Cbingen again :(
 #[no_mangle]
-pub unsafe extern "C" fn ptrace(request: c_int, mut params: ...) -> c_int {
+pub unsafe extern "C" fn sys_ptrace(request: c_int, mut params: VaList) -> c_int {
     // Musl also just grabs the arguments from the varargs...
     Sys::ptrace(request, params.arg(), params.arg(), params.arg())
 }