diff --git a/src/platform/src/lib.rs b/src/platform/src/lib.rs
index 2a634a4eef497a329e36353b13eee6b84be19610..60331812eccf0c694628ce17a716de2953dac247 100644
--- a/src/platform/src/lib.rs
+++ b/src/platform/src/lib.rs
@@ -26,6 +26,10 @@ mod allocator;
 #[path = "allocator/ralloc.rs"]
 mod allocator;
 
+pub use pal::Pal;
+
+mod pal;
+
 pub use sys::*;
 
 #[cfg(all(not(feature = "no_std"), target_os = "linux"))]
diff --git a/src/platform/src/linux/mod.rs b/src/platform/src/linux/mod.rs
index 5446a52f1a47344903a3daa0acdc9ad2ebffe316..f1c941af36de7e3b9dc1dfbdb719dbb97975745b 100644
--- a/src/platform/src/linux/mod.rs
+++ b/src/platform/src/linux/mod.rs
@@ -1,5 +1,6 @@
 use core::{mem, ptr};
 
+use Pal;
 use errno;
 use types::*;
 
@@ -27,459 +28,463 @@ fn e(sys: usize) -> usize {
     }
 }
 
-pub unsafe fn accept(socket: c_int, address: *mut sockaddr, address_len: *mut socklen_t) -> c_int {
-    e(syscall!(ACCEPT, socket, address, address_len)) as c_int
-}
+pub struct Sys;
 
-pub fn access(path: *const c_char, mode: c_int) -> c_int {
-    e(unsafe { syscall!(ACCESS, path, mode) }) as c_int
-}
+impl Pal for Sys {
+    unsafe fn accept(socket: c_int, address: *mut sockaddr, address_len: *mut socklen_t) -> c_int {
+        e(syscall!(ACCEPT, socket, address, address_len)) as c_int
+    }
 
-pub unsafe fn bind(socket: c_int, address: *const sockaddr, address_len: socklen_t) -> c_int {
-    e(syscall!(BIND, socket, address, address_len)) as c_int
-}
+    fn access(path: *const c_char, mode: c_int) -> c_int {
+        e(unsafe { syscall!(ACCESS, path, mode) }) as c_int
+    }
 
-pub fn brk(addr: *mut c_void) -> *mut c_void {
-    unsafe { syscall!(BRK, addr) as *mut c_void }
-}
+    unsafe fn bind(socket: c_int, address: *const sockaddr, address_len: socklen_t) -> c_int {
+        e(syscall!(BIND, socket, address, address_len)) as c_int
+    }
 
-pub fn chdir(path: *const c_char) -> c_int {
-    e(unsafe { syscall!(CHDIR, path) }) as c_int
-}
+    fn brk(addr: *mut c_void) -> *mut c_void {
+        unsafe { syscall!(BRK, addr) as *mut c_void }
+    }
 
-pub fn chmod(path: *const c_char, mode: mode_t) -> c_int {
-    e(unsafe { syscall!(FCHMODAT, AT_FDCWD, path, mode, 0) }) as c_int
-}
+    fn chdir(path: *const c_char) -> c_int {
+        e(unsafe { syscall!(CHDIR, path) }) as c_int
+    }
 
-pub fn chown(path: *const c_char, owner: uid_t, group: gid_t) -> c_int {
-    e(unsafe { syscall!(FCHOWNAT, AT_FDCWD, path, owner as u32, group as u32) }) as c_int
-}
+    fn chmod(path: *const c_char, mode: mode_t) -> c_int {
+        e(unsafe { syscall!(FCHMODAT, AT_FDCWD, path, mode, 0) }) as c_int
+    }
 
-pub fn close(fildes: c_int) -> c_int {
-    e(unsafe { syscall!(CLOSE, fildes) }) as c_int
-}
+    fn chown(path: *const c_char, owner: uid_t, group: gid_t) -> c_int {
+        e(unsafe { syscall!(FCHOWNAT, AT_FDCWD, path, owner as u32, group as u32) }) as c_int
+    }
 
-pub unsafe fn connect(socket: c_int, address: *const sockaddr, address_len: socklen_t) -> c_int {
-    e(syscall!(CONNECT, socket, address, address_len)) as c_int
-}
+    fn clock_gettime(clk_id: clockid_t, tp: *mut timespec) -> c_int {
+        e(unsafe { syscall!(CLOCK_GETTIME, clk_id, tp) }) as c_int
+    }
 
-pub fn dup(fildes: c_int) -> c_int {
-    e(unsafe { syscall!(DUP, fildes) }) as c_int
-}
+    fn close(fildes: c_int) -> c_int {
+        e(unsafe { syscall!(CLOSE, fildes) }) as c_int
+    }
 
-pub fn dup2(fildes: c_int, fildes2: c_int) -> c_int {
-    e(unsafe { syscall!(DUP3, fildes, fildes2, 0) }) as c_int
-}
+    unsafe fn connect(socket: c_int, address: *const sockaddr, address_len: socklen_t) -> c_int {
+        e(syscall!(CONNECT, socket, address, address_len)) as c_int
+    }
 
-pub fn execve(path: *const c_char, argv: *const *mut c_char, envp: *const *mut c_char) -> c_int {
-    e(unsafe { syscall!(EXECVE, path, argv, envp) }) as c_int
-}
+    fn dup(fildes: c_int) -> c_int {
+        e(unsafe { syscall!(DUP, fildes) }) as c_int
+    }
 
-pub fn exit(status: c_int) -> ! {
-    unsafe {
-        syscall!(EXIT, status);
+    fn dup2(fildes: c_int, fildes2: c_int) -> c_int {
+        e(unsafe { syscall!(DUP3, fildes, fildes2, 0) }) as c_int
     }
-    loop {}
-}
 
-pub fn fchdir(fildes: c_int) -> c_int {
-    e(unsafe { syscall!(FCHDIR, fildes) }) as c_int
-}
+    fn execve(path: *const c_char, argv: *const *mut c_char, envp: *const *mut c_char) -> c_int {
+        e(unsafe { syscall!(EXECVE, path, argv, envp) }) as c_int
+    }
 
-pub fn fchmod(fildes: c_int, mode: mode_t) -> c_int {
-    e(unsafe { syscall!(FCHMOD, fildes, mode) }) as c_int
-}
+    fn exit(status: c_int) -> ! {
+        unsafe {
+            syscall!(EXIT, status);
+        }
+        loop {}
+    }
 
-pub fn fchown(fildes: c_int, owner: uid_t, group: gid_t) -> c_int {
-    e(unsafe { syscall!(FCHOWN, fildes, owner, group) }) as c_int
-}
+    fn fchdir(fildes: c_int) -> c_int {
+        e(unsafe { syscall!(FCHDIR, fildes) }) as c_int
+    }
 
-pub fn flock(fd: c_int, operation: c_int) -> c_int {
-    e(unsafe { syscall!(FLOCK, fd, operation) }) as c_int
-}
+    fn fchmod(fildes: c_int, mode: mode_t) -> c_int {
+        e(unsafe { syscall!(FCHMOD, fildes, mode) }) as c_int
+    }
 
-pub fn fstat(fildes: c_int, buf: *mut stat) -> c_int {
-    let empty_cstr: *const c_char = unsafe { ::cstr_from_bytes_with_nul_unchecked(b"\0") };
-    e(unsafe { syscall!(NEWFSTATAT, fildes, empty_cstr, buf, AT_EMPTY_PATH) }) as c_int
-}
+    fn fchown(fildes: c_int, owner: uid_t, group: gid_t) -> c_int {
+        e(unsafe { syscall!(FCHOWN, fildes, owner, group) }) as c_int
+    }
 
-pub fn fcntl(fildes: c_int, cmd: c_int, arg: c_int) -> c_int {
-    e(unsafe { syscall!(FCNTL, fildes, cmd, arg) }) as c_int
-}
+    fn flock(fd: c_int, operation: c_int) -> c_int {
+        e(unsafe { syscall!(FLOCK, fd, operation) }) as c_int
+    }
 
-pub fn fork() -> pid_t {
-    e(unsafe { syscall!(CLONE, SIGCHLD, 0) }) as pid_t
-}
+    fn fstat(fildes: c_int, buf: *mut stat) -> c_int {
+        let empty_cstr: *const c_char = unsafe { ::cstr_from_bytes_with_nul_unchecked(b"\0") };
+        e(unsafe { syscall!(NEWFSTATAT, fildes, empty_cstr, buf, AT_EMPTY_PATH) }) as c_int
+    }
 
-pub fn fsync(fildes: c_int) -> c_int {
-    e(unsafe { syscall!(FSYNC, fildes) }) as c_int
-}
+    fn fcntl(fildes: c_int, cmd: c_int, arg: c_int) -> c_int {
+        e(unsafe { syscall!(FCNTL, fildes, cmd, arg) }) as c_int
+    }
 
-pub fn ftruncate(fildes: c_int, length: off_t) -> c_int {
-    e(unsafe { syscall!(FTRUNCATE, fildes, length) }) as c_int
-}
+    fn fork() -> pid_t {
+        e(unsafe { syscall!(CLONE, SIGCHLD, 0) }) as pid_t
+    }
 
-pub fn futimens(fd: c_int, times: *const timespec) -> c_int {
-    e(unsafe { syscall!(UTIMENSAT, fd, ptr::null::<c_char>(), times, 0) }) as c_int
-}
+    fn fsync(fildes: c_int) -> c_int {
+        e(unsafe { syscall!(FSYNC, fildes) }) as c_int
+    }
 
-pub fn utimens(path: *const c_char, times: *const timespec) -> c_int {
-    e(unsafe { syscall!(UTIMENSAT, AT_FDCWD, path, times, 0) }) as c_int
-}
+    fn ftruncate(fildes: c_int, length: off_t) -> c_int {
+        e(unsafe { syscall!(FTRUNCATE, fildes, length) }) as c_int
+    }
 
-pub fn getcwd(buf: *mut c_char, size: size_t) -> *mut c_char {
-    if e(unsafe { syscall!(GETCWD, buf, size) }) == !0 {
-        ptr::null_mut()
-    } else {
-        buf
+    fn futimens(fd: c_int, times: *const timespec) -> c_int {
+        e(unsafe { syscall!(UTIMENSAT, fd, ptr::null::<c_char>(), times, 0) }) as c_int
     }
-}
 
-pub fn getdents(fd: c_int, dirents: *mut dirent, bytes: usize) -> c_int {
-    unsafe { syscall!(GETDENTS64, fd, dirents, bytes) as c_int }
-}
+    fn utimens(path: *const c_char, times: *const timespec) -> c_int {
+        e(unsafe { syscall!(UTIMENSAT, AT_FDCWD, path, times, 0) }) as c_int
+    }
 
-pub fn getegid() -> gid_t {
-    e(unsafe { syscall!(GETEGID) }) as gid_t
-}
+    fn getcwd(buf: *mut c_char, size: size_t) -> *mut c_char {
+        if e(unsafe { syscall!(GETCWD, buf, size) }) == !0 {
+            ptr::null_mut()
+        } else {
+            buf
+        }
+    }
 
-pub fn geteuid() -> uid_t {
-    e(unsafe { syscall!(GETEUID) }) as uid_t
-}
+    fn getdents(fd: c_int, dirents: *mut dirent, bytes: usize) -> c_int {
+        unsafe { syscall!(GETDENTS64, fd, dirents, bytes) as c_int }
+    }
 
-pub fn getgid() -> gid_t {
-    e(unsafe { syscall!(GETGID) }) as gid_t
-}
+    fn getegid() -> gid_t {
+        e(unsafe { syscall!(GETEGID) }) as gid_t
+    }
 
-pub fn getrusage(who: c_int, r_usage: *mut rusage) -> c_int {
-    e(unsafe { syscall!(GETRUSAGE, who, r_usage) }) as c_int
-}
+    fn geteuid() -> uid_t {
+        e(unsafe { syscall!(GETEUID) }) as uid_t
+    }
 
-pub unsafe fn gethostname(mut name: *mut c_char, len: size_t) -> c_int {
-    // len only needs to be mutable on linux
-    let mut len = len;
+    fn getgid() -> gid_t {
+        e(unsafe { syscall!(GETGID) }) as gid_t
+    }
 
-    let mut uts = mem::uninitialized();
-    let err = uname(&mut uts);
-    if err < 0 {
-        mem::forget(uts);
-        return err;
+    fn getrusage(who: c_int, r_usage: *mut rusage) -> c_int {
+        e(unsafe { syscall!(GETRUSAGE, who, r_usage) }) as c_int
     }
-    for c in uts.nodename.iter() {
-        if len == 0 {
-            break;
-        }
-        len -= 1;
 
-        *name = *c;
+    unsafe fn gethostname(mut name: *mut c_char, len: size_t) -> c_int {
+        // len only needs to be mutable on linux
+        let mut len = len;
 
-        if *name == 0 {
-            // We do want to copy the zero also, so we check this after the copying.
-            break;
+        let mut uts = mem::uninitialized();
+        let err = uname(&mut uts);
+        if err < 0 {
+            mem::forget(uts);
+            return err;
         }
+        for c in uts.nodename.iter() {
+            if len == 0 {
+                break;
+            }
+            len -= 1;
+
+            *name = *c;
+
+            if *name == 0 {
+                // We do want to copy the zero also, so we check this after the copying.
+                break;
+            }
 
-        name = name.offset(1);
+            name = name.offset(1);
+        }
+        0
     }
-    0
-}
 
-pub fn getitimer(which: c_int, out: *mut itimerval) -> c_int {
-    e(unsafe { syscall!(GETITIMER, which, out) }) as c_int
-}
+    fn getitimer(which: c_int, out: *mut itimerval) -> c_int {
+        e(unsafe { syscall!(GETITIMER, which, out) }) as c_int
+    }
 
-pub unsafe fn getpeername(
-    socket: c_int,
-    address: *mut sockaddr,
-    address_len: *mut socklen_t,
-) -> c_int {
-    e(syscall!(GETPEERNAME, socket, address, address_len)) as c_int
-}
+    unsafe fn getpeername(
+        socket: c_int,
+        address: *mut sockaddr,
+        address_len: *mut socklen_t,
+    ) -> c_int {
+        e(syscall!(GETPEERNAME, socket, address, address_len)) as c_int
+    }
 
-pub fn getpgid(pid: pid_t) -> pid_t {
-    e(unsafe { syscall!(GETPGID, pid) }) as pid_t
-}
+    fn getpgid(pid: pid_t) -> pid_t {
+        e(unsafe { syscall!(GETPGID, pid) }) as pid_t
+    }
 
-pub fn getpid() -> pid_t {
-    e(unsafe { syscall!(GETPID) }) as pid_t
-}
+    fn getpid() -> pid_t {
+        e(unsafe { syscall!(GETPID) }) as pid_t
+    }
 
-pub fn getppid() -> pid_t {
-    e(unsafe { syscall!(GETPPID) }) as pid_t
-}
+    fn getppid() -> pid_t {
+        e(unsafe { syscall!(GETPPID) }) as pid_t
+    }
 
-pub unsafe fn getsockname(
-    socket: c_int,
-    address: *mut sockaddr,
-    address_len: *mut socklen_t,
-) -> c_int {
-    e(syscall!(GETSOCKNAME, socket, address, address_len)) as c_int
-}
+    unsafe fn getsockname(
+        socket: c_int,
+        address: *mut sockaddr,
+        address_len: *mut socklen_t,
+    ) -> c_int {
+        e(syscall!(GETSOCKNAME, socket, address, address_len)) as c_int
+    }
 
-pub fn getsockopt(
-    socket: c_int,
-    level: c_int,
-    option_name: c_int,
-    option_value: *mut c_void,
-    option_len: *mut socklen_t,
-) -> c_int {
-    e(unsafe {
-        syscall!(
-            GETSOCKOPT,
-            socket,
-            level,
-            option_name,
-            option_value,
-            option_len
-        )
-    }) as c_int
-}
+    fn getsockopt(
+        socket: c_int,
+        level: c_int,
+        option_name: c_int,
+        option_value: *mut c_void,
+        option_len: *mut socklen_t,
+    ) -> c_int {
+        e(unsafe {
+            syscall!(
+                GETSOCKOPT,
+                socket,
+                level,
+                option_name,
+                option_value,
+                option_len
+            )
+        }) as c_int
+    }
 
-pub fn gettimeofday(tp: *mut timeval, tzp: *mut timezone) -> c_int {
-    e(unsafe { syscall!(GETTIMEOFDAY, tp, tzp) }) as c_int
-}
+    fn gettimeofday(tp: *mut timeval, tzp: *mut timezone) -> c_int {
+        e(unsafe { syscall!(GETTIMEOFDAY, tp, tzp) }) as c_int
+    }
 
-pub fn getuid() -> uid_t {
-    e(unsafe { syscall!(GETUID) }) as uid_t
-}
+    fn getuid() -> uid_t {
+        e(unsafe { syscall!(GETUID) }) as uid_t
+    }
 
-pub fn ioctl(fd: c_int, request: c_ulong, out: *mut c_void) -> c_int {
-    // TODO: Somehow support varargs to syscall??
-    e(unsafe { syscall!(IOCTL, fd, request, out) }) as c_int
-}
+    fn ioctl(fd: c_int, request: c_ulong, out: *mut c_void) -> c_int {
+        // TODO: Somehow support varargs to syscall??
+        e(unsafe { syscall!(IOCTL, fd, request, out) }) as c_int
+    }
 
-pub fn isatty(fd: c_int) -> c_int {
-    let mut winsize = winsize::default();
-    (ioctl(fd, TIOCGWINSZ, &mut winsize as *mut _ as *mut c_void) == 0) as c_int
-}
+    fn isatty(fd: c_int) -> c_int {
+        let mut winsize = winsize::default();
+        (Self::ioctl(fd, TIOCGWINSZ, &mut winsize as *mut _ as *mut c_void) == 0) as c_int
+    }
 
-pub fn kill(pid: pid_t, sig: c_int) -> c_int {
-    e(unsafe { syscall!(KILL, pid, sig) }) as c_int
-}
+    fn kill(pid: pid_t, sig: c_int) -> c_int {
+        e(unsafe { syscall!(KILL, pid, sig) }) as c_int
+    }
 
-pub fn killpg(pgrp: pid_t, sig: c_int) -> c_int {
-    e(unsafe { syscall!(KILL, -(pgrp as isize) as pid_t, sig) }) as c_int
-}
+    fn killpg(pgrp: pid_t, sig: c_int) -> c_int {
+        e(unsafe { syscall!(KILL, -(pgrp as isize) as pid_t, sig) }) as c_int
+    }
 
-pub fn link(path1: *const c_char, path2: *const c_char) -> c_int {
-    e(unsafe { syscall!(LINKAT, AT_FDCWD, path1, AT_FDCWD, path2, 0) }) as c_int
-}
+    fn link(path1: *const c_char, path2: *const c_char) -> c_int {
+        e(unsafe { syscall!(LINKAT, AT_FDCWD, path1, AT_FDCWD, path2, 0) }) as c_int
+    }
 
-pub fn listen(socket: c_int, backlog: c_int) -> c_int {
-    e(unsafe { syscall!(LISTEN, socket, backlog) }) as c_int
-}
+    fn listen(socket: c_int, backlog: c_int) -> c_int {
+        e(unsafe { syscall!(LISTEN, socket, backlog) }) as c_int
+    }
 
-pub fn lseek(fildes: c_int, offset: off_t, whence: c_int) -> off_t {
-    e(unsafe { syscall!(LSEEK, fildes, offset, whence) }) as off_t
-}
+    fn lseek(fildes: c_int, offset: off_t, whence: c_int) -> off_t {
+        e(unsafe { syscall!(LSEEK, fildes, offset, whence) }) as off_t
+    }
 
-pub fn lstat(file: *const c_char, buf: *mut stat) -> c_int {
-    e(unsafe { syscall!(NEWFSTATAT, AT_FDCWD, file, buf, AT_SYMLINK_NOFOLLOW) }) as c_int
-}
+    fn lstat(file: *const c_char, buf: *mut stat) -> c_int {
+        e(unsafe { syscall!(NEWFSTATAT, AT_FDCWD, file, buf, AT_SYMLINK_NOFOLLOW) }) as c_int
+    }
 
-pub fn mkdir(path: *const c_char, mode: mode_t) -> c_int {
-    e(unsafe { syscall!(MKDIRAT, AT_FDCWD, path, mode) }) as c_int
-}
+    fn mkdir(path: *const c_char, mode: mode_t) -> c_int {
+        e(unsafe { syscall!(MKDIRAT, AT_FDCWD, path, mode) }) as c_int
+    }
 
-pub fn mkfifo(path: *const c_char, mode: mode_t) -> c_int {
-    e(unsafe { syscall!(MKNODAT, AT_FDCWD, path, mode, 0) }) as c_int
-}
+    fn mkfifo(path: *const c_char, mode: mode_t) -> c_int {
+        e(unsafe { syscall!(MKNODAT, AT_FDCWD, path, mode, 0) }) as c_int
+    }
 
-pub unsafe fn mmap(
-    addr: *mut c_void,
-    len: usize,
-    prot: c_int,
-    flags: c_int,
-    fildes: c_int,
-    off: off_t,
-) -> *mut c_void {
-    e(syscall!(MMAP, addr, len, prot, flags, fildes, off)) as *mut c_void
-}
+    unsafe fn mmap(
+        addr: *mut c_void,
+        len: usize,
+        prot: c_int,
+        flags: c_int,
+        fildes: c_int,
+        off: off_t,
+    ) -> *mut c_void {
+        e(syscall!(MMAP, addr, len, prot, flags, fildes, off)) as *mut c_void
+    }
 
-pub unsafe fn munmap(addr: *mut c_void, len: usize) -> c_int {
-    e(syscall!(MUNMAP, addr, len)) as c_int
-}
+    unsafe fn munmap(addr: *mut c_void, len: usize) -> c_int {
+        e(syscall!(MUNMAP, addr, len)) as c_int
+    }
 
-pub fn nanosleep(rqtp: *const timespec, rmtp: *mut timespec) -> c_int {
-    e(unsafe { syscall!(NANOSLEEP, rqtp, rmtp) }) as c_int
-}
+    fn nanosleep(rqtp: *const timespec, rmtp: *mut timespec) -> c_int {
+        e(unsafe { syscall!(NANOSLEEP, rqtp, rmtp) }) as c_int
+    }
 
-pub fn open(path: *const c_char, oflag: c_int, mode: mode_t) -> c_int {
-    e(unsafe { syscall!(OPENAT, AT_FDCWD, path, oflag, mode) }) as c_int
-}
+    fn open(path: *const c_char, oflag: c_int, mode: mode_t) -> c_int {
+        e(unsafe { syscall!(OPENAT, AT_FDCWD, path, oflag, mode) }) as c_int
+    }
 
-pub fn pipe(fildes: &mut [c_int]) -> c_int {
-    e(unsafe { syscall!(PIPE2, fildes.as_mut_ptr(), 0) }) as c_int
-}
+    fn pipe(fildes: &mut [c_int]) -> c_int {
+        e(unsafe { syscall!(PIPE2, fildes.as_mut_ptr(), 0) }) as c_int
+    }
 
-pub fn raise(sig: c_int) -> c_int {
-    let tid = e(unsafe { syscall!(GETTID) }) as pid_t;
-    let ret = if tid == !0 {
-        -1
-    } else {
-        e(unsafe { syscall!(TKILL, tid, sig) }) as c_int
-    };
+    fn raise(sig: c_int) -> c_int {
+        let tid = e(unsafe { syscall!(GETTID) }) as pid_t;
+        let ret = if tid == !0 {
+            -1
+        } else {
+            e(unsafe { syscall!(TKILL, tid, sig) }) as c_int
+        };
 
-    ret
-}
+        ret
+    }
 
-pub fn read(fildes: c_int, buf: &mut [u8]) -> ssize_t {
-    e(unsafe { syscall!(READ, fildes, buf.as_mut_ptr(), buf.len()) }) as ssize_t
-}
+    fn read(fildes: c_int, buf: &mut [u8]) -> ssize_t {
+        e(unsafe { syscall!(READ, fildes, buf.as_mut_ptr(), buf.len()) }) as ssize_t
+    }
 
-pub unsafe fn recvfrom(
-    socket: c_int,
-    buf: *mut c_void,
-    len: size_t,
-    flags: c_int,
-    address: *mut sockaddr,
-    address_len: *mut socklen_t,
-) -> ssize_t {
-    e(syscall!(
-        RECVFROM,
-        socket,
-        buf,
-        len,
-        flags,
-        address,
-        address_len
-    )) as ssize_t
-}
+    unsafe fn recvfrom(
+        socket: c_int,
+        buf: *mut c_void,
+        len: size_t,
+        flags: c_int,
+        address: *mut sockaddr,
+        address_len: *mut socklen_t,
+    ) -> ssize_t {
+        e(syscall!(
+            RECVFROM,
+            socket,
+            buf,
+            len,
+            flags,
+            address,
+            address_len
+        )) as ssize_t
+    }
 
-pub fn rename(old: *const c_char, new: *const c_char) -> c_int {
-    e(unsafe { syscall!(RENAMEAT, AT_FDCWD, old, AT_FDCWD, new) }) as c_int
-}
+    fn rename(old: *const c_char, new: *const c_char) -> c_int {
+        e(unsafe { syscall!(RENAMEAT, AT_FDCWD, old, AT_FDCWD, new) }) as c_int
+    }
 
-pub fn rmdir(path: *const c_char) -> c_int {
-    e(unsafe { syscall!(UNLINKAT, AT_FDCWD, path, AT_REMOVEDIR) }) as c_int
-}
+    fn rmdir(path: *const c_char) -> c_int {
+        e(unsafe { syscall!(UNLINKAT, AT_FDCWD, path, AT_REMOVEDIR) }) as c_int
+    }
 
-pub fn select(
-    nfds: c_int,
-    readfds: *mut fd_set,
-    writefds: *mut fd_set,
-    exceptfds: *mut fd_set,
-    timeout: *mut timeval,
-) -> c_int {
-    e(unsafe { syscall!(SELECT, nfds, readfds, writefds, exceptfds, timeout) }) as c_int
-}
+    fn select(
+        nfds: c_int,
+        readfds: *mut fd_set,
+        writefds: *mut fd_set,
+        exceptfds: *mut fd_set,
+        timeout: *mut timeval,
+    ) -> c_int {
+        e(unsafe { syscall!(SELECT, nfds, readfds, writefds, exceptfds, timeout) }) as c_int
+    }
 
-pub unsafe fn sendto(
-    socket: c_int,
-    buf: *const c_void,
-    len: size_t,
-    flags: c_int,
-    dest_addr: *const sockaddr,
-    dest_len: socklen_t,
-) -> ssize_t {
-    e(syscall!(
-        SENDTO, socket, buf, len, flags, dest_addr, dest_len
-    )) as ssize_t
-}
+    unsafe fn sendto(
+        socket: c_int,
+        buf: *const c_void,
+        len: size_t,
+        flags: c_int,
+        dest_addr: *const sockaddr,
+        dest_len: socklen_t,
+    ) -> ssize_t {
+        e(syscall!(
+            SENDTO, socket, buf, len, flags, dest_addr, dest_len
+        )) as ssize_t
+    }
 
-pub fn setitimer(which: c_int, new: *const itimerval, old: *mut itimerval) -> c_int {
-    e(unsafe { syscall!(SETITIMER, which, new, old) }) as c_int
-}
+    fn setitimer(which: c_int, new: *const itimerval, old: *mut itimerval) -> c_int {
+        e(unsafe { syscall!(SETITIMER, which, new, old) }) as c_int
+    }
 
-pub fn setpgid(pid: pid_t, pgid: pid_t) -> c_int {
-    e(unsafe { syscall!(SETPGID, pid, pgid) }) as c_int
-}
+    fn setpgid(pid: pid_t, pgid: pid_t) -> c_int {
+        e(unsafe { syscall!(SETPGID, pid, pgid) }) as c_int
+    }
 
-pub fn setregid(rgid: gid_t, egid: gid_t) -> c_int {
-    e(unsafe { syscall!(SETREGID, rgid, egid) }) as c_int
-}
+    fn setregid(rgid: gid_t, egid: gid_t) -> c_int {
+        e(unsafe { syscall!(SETREGID, rgid, egid) }) as c_int
+    }
 
-pub fn setreuid(ruid: uid_t, euid: uid_t) -> c_int {
-    e(unsafe { syscall!(SETREUID, ruid, euid) }) as c_int
-}
+    fn setreuid(ruid: uid_t, euid: uid_t) -> c_int {
+        e(unsafe { syscall!(SETREUID, ruid, euid) }) as c_int
+    }
 
-pub fn setsockopt(
-    socket: c_int,
-    level: c_int,
-    option_name: c_int,
-    option_value: *const c_void,
-    option_len: socklen_t,
-) -> c_int {
-    e(unsafe {
-        syscall!(
-            SETSOCKOPT,
-            socket,
-            level,
-            option_name,
-            option_value,
-            option_len
-        )
-    }) as c_int
-}
+    fn setsockopt(
+        socket: c_int,
+        level: c_int,
+        option_name: c_int,
+        option_value: *const c_void,
+        option_len: socklen_t,
+    ) -> c_int {
+        e(unsafe {
+            syscall!(
+                SETSOCKOPT,
+                socket,
+                level,
+                option_name,
+                option_value,
+                option_len
+            )
+        }) as c_int
+    }
 
-pub fn shutdown(socket: c_int, how: c_int) -> c_int {
-    e(unsafe { syscall!(SHUTDOWN, socket, how) }) as c_int
-}
+    fn shutdown(socket: c_int, how: c_int) -> c_int {
+        e(unsafe { syscall!(SHUTDOWN, socket, how) }) as c_int
+    }
 
-pub unsafe fn sigaction(sig: c_int, act: *const sigaction, oact: *mut sigaction) -> c_int {
-    e(syscall!(
-        RT_SIGACTION,
-        sig,
-        act,
-        oact,
-        mem::size_of::<sigset_t>()
-    )) as c_int
-}
+    unsafe fn sigaction(sig: c_int, act: *const sigaction, oact: *mut sigaction) -> c_int {
+        e(syscall!(
+            RT_SIGACTION,
+            sig,
+            act,
+            oact,
+            mem::size_of::<sigset_t>()
+        )) as c_int
+    }
 
-pub fn sigprocmask(how: c_int, set: *const sigset_t, oset: *mut sigset_t) -> c_int {
-    e(unsafe { syscall!(RT_SIGPROCMASK, how, set, oset, mem::size_of::<sigset_t>()) }) as c_int
-}
+    fn sigprocmask(how: c_int, set: *const sigset_t, oset: *mut sigset_t) -> c_int {
+        e(unsafe { syscall!(RT_SIGPROCMASK, how, set, oset, mem::size_of::<sigset_t>()) }) as c_int
+    }
 
-pub fn stat(file: *const c_char, buf: *mut stat) -> c_int {
-    e(unsafe { syscall!(NEWFSTATAT, AT_FDCWD, file, buf, 0) }) as c_int
-}
+    fn stat(file: *const c_char, buf: *mut stat) -> c_int {
+        e(unsafe { syscall!(NEWFSTATAT, AT_FDCWD, file, buf, 0) }) as c_int
+    }
 
-pub fn socket(domain: c_int, kind: c_int, protocol: c_int) -> c_int {
-    e(unsafe { syscall!(SOCKET, domain, kind, protocol) }) as c_int
-}
+    fn socket(domain: c_int, kind: c_int, protocol: c_int) -> c_int {
+        e(unsafe { syscall!(SOCKET, domain, kind, protocol) }) as c_int
+    }
 
-pub fn socketpair(domain: c_int, kind: c_int, protocol: c_int, socket_vector: *mut c_int) -> c_int {
-    e(unsafe { syscall!(SOCKETPAIR, domain, kind, protocol, socket_vector) }) as c_int
-}
+    fn socketpair(domain: c_int, kind: c_int, protocol: c_int, socket_vector: *mut c_int) -> c_int {
+        e(unsafe { syscall!(SOCKETPAIR, domain, kind, protocol, socket_vector) }) as c_int
+    }
 
-pub fn tcgetattr(fd: c_int, out: *mut termios) -> c_int {
-    ioctl(fd, TCGETS, out as *mut c_void)
-}
+    fn tcgetattr(fd: c_int, out: *mut termios) -> c_int {
+        Self::ioctl(fd, TCGETS, out as *mut c_void)
+    }
 
-pub fn tcsetattr(fd: c_int, act: c_int, value: *const termios) -> c_int {
-    if act < 0 || act > 2 {
-        unsafe {
-            errno = EINVAL;
+    fn tcsetattr(fd: c_int, act: c_int, value: *const termios) -> c_int {
+        if act < 0 || act > 2 {
+            unsafe {
+                errno = EINVAL;
+            }
+            return -1;
         }
-        return -1;
+        // This is safe because ioctl shouldn't modify the value
+        Self::ioctl(fd, TCSETS + act as c_ulong, value as *mut c_void)
     }
-    // This is safe because ioctl shouldn't modify the value
-    ioctl(fd, TCSETS + act as c_ulong, value as *mut c_void)
-}
 
-pub fn times(out: *mut tms) -> clock_t {
-    unsafe { syscall!(TIMES, out) as clock_t }
-}
-
-pub fn umask(mask: mode_t) -> mode_t {
-    unsafe { syscall!(UMASK, mask) as mode_t }
-}
+    fn times(out: *mut tms) -> clock_t {
+        unsafe { syscall!(TIMES, out) as clock_t }
+    }
 
-pub fn uname(utsname: *mut utsname) -> c_int {
-    e(unsafe { syscall!(UNAME, utsname, 0) }) as c_int
-}
+    fn umask(mask: mode_t) -> mode_t {
+        unsafe { syscall!(UMASK, mask) as mode_t }
+    }
 
-pub fn unlink(path: *const c_char) -> c_int {
-    e(unsafe { syscall!(UNLINKAT, AT_FDCWD, path, 0) }) as c_int
-}
+    fn uname(utsname: *mut utsname) -> c_int {
+        e(unsafe { syscall!(UNAME, utsname, 0) }) as c_int
+    }
 
-pub fn waitpid(pid: pid_t, stat_loc: *mut c_int, options: c_int) -> pid_t {
-    e(unsafe { syscall!(WAIT4, pid, stat_loc, options, 0) }) as pid_t
-}
+    fn unlink(path: *const c_char) -> c_int {
+        e(unsafe { syscall!(UNLINKAT, AT_FDCWD, path, 0) }) as c_int
+    }
 
-pub fn write(fildes: c_int, buf: &[u8]) -> ssize_t {
-    e(unsafe { syscall!(WRITE, fildes, buf.as_ptr(), buf.len()) }) as ssize_t
-}
+    fn waitpid(pid: pid_t, stat_loc: *mut c_int, options: c_int) -> pid_t {
+        e(unsafe { syscall!(WAIT4, pid, stat_loc, options, 0) }) as pid_t
+    }
 
-pub fn clock_gettime(clk_id: clockid_t, tp: *mut timespec) -> c_int {
-    e(unsafe { syscall!(CLOCK_GETTIME, clk_id, tp) }) as c_int
+    fn write(fildes: c_int, buf: &[u8]) -> ssize_t {
+        e(unsafe { syscall!(WRITE, fildes, buf.as_ptr(), buf.len()) }) as ssize_t
+    }
 }
diff --git a/src/platform/src/pal.rs b/src/platform/src/pal.rs
new file mode 100644
index 0000000000000000000000000000000000000000..67081b439e23db58887cad977258951f0e3b57b3
--- /dev/null
+++ b/src/platform/src/pal.rs
@@ -0,0 +1,370 @@
+use types::*;
+
+pub trait Pal {
+    fn no_pal<T>(name: &str) -> T;
+
+    unsafe fn accept(socket: c_int, address: *mut sockaddr, address_len: *mut socklen_t) -> c_int {
+        Self::no_pal("accept")
+    }
+
+    fn access(path: *const c_char, mode: c_int) -> c_int {
+        Self::no_pal("access")
+    }
+
+    unsafe fn bind(socket: c_int, address: *const sockaddr, address_len: socklen_t) -> c_int {
+        Self::no_pal("bind")
+    }
+
+    fn brk(addr: *mut c_void) -> *mut c_void {
+        Self::no_pal("brk")
+    }
+
+    fn chdir(path: *const c_char) -> c_int {
+        Self::no_pal("chdir")
+    }
+
+    fn chmod(path: *const c_char, mode: mode_t) -> c_int {
+        Self::no_pal("chmod")
+    }
+
+    fn chown(path: *const c_char, owner: uid_t, group: gid_t) -> c_int {
+        Self::no_pal("chown")
+    }
+
+    fn clock_gettime(clk_id: clockid_t, tp: *mut timespec) -> c_int {
+        Self::no_pal("clock_gettime")
+    }
+
+    fn close(fildes: c_int) -> c_int {
+        Self::no_pal("close")
+    }
+
+    unsafe fn connect(socket: c_int, address: *const sockaddr, address_len: socklen_t) -> c_int {
+        Self::no_pal("connect")
+    }
+
+    fn dup(fildes: c_int) -> c_int {
+        Self::no_pal("dup")
+    }
+
+    fn dup2(fildes: c_int, fildes2: c_int) -> c_int {
+        Self::no_pal("dup2")
+    }
+
+    fn execve(path: *const c_char, argv: *const *mut c_char, envp: *const *mut c_char) -> c_int {
+        Self::no_pal("execve")
+    }
+
+    fn exit(status: c_int) -> !;
+
+    fn fchdir(fildes: c_int) -> c_int {
+        Self::no_pal("fchdir")
+    }
+
+    fn fchmod(fildes: c_int, mode: mode_t) -> c_int {
+        Self::no_pal("fchmod")
+    }
+
+    fn fchown(fildes: c_int, owner: uid_t, group: gid_t) -> c_int {
+        Self::no_pal("fchown")
+    }
+
+    fn flock(fd: c_int, operation: c_int) -> c_int {
+        Self::no_pal("flock")
+    }
+
+    fn fstat(fildes: c_int, buf: *mut stat) -> c_int {
+        Self::no_pal("fstat")
+    }
+
+    fn fcntl(fildes: c_int, cmd: c_int, arg: c_int) -> c_int {
+        Self::no_pal("fcntl")
+    }
+
+    fn fork() -> pid_t {
+        Self::no_pal("fork")
+    }
+
+    fn fsync(fildes: c_int) -> c_int {
+        Self::no_pal("fsync")
+    }
+
+    fn ftruncate(fildes: c_int, length: off_t) -> c_int {
+        Self::no_pal("ftruncate")
+    }
+
+    fn futimens(fd: c_int, times: *const timespec) -> c_int {
+        Self::no_pal("futimens")
+    }
+
+    fn utimens(path: *const c_char, times: *const timespec) -> c_int {
+        Self::no_pal("utimens")
+    }
+
+    fn getcwd(buf: *mut c_char, size: size_t) -> *mut c_char {
+        Self::no_pal("getcwd")
+    }
+
+    fn getdents(fd: c_int, dirents: *mut dirent, bytes: usize) -> c_int {
+        Self::no_pal("getdents")
+    }
+
+    fn getegid() -> gid_t {
+        Self::no_pal("getegid")
+    }
+
+    fn geteuid() -> uid_t {
+        Self::no_pal("geteuid")
+    }
+
+    fn getgid() -> gid_t {
+        Self::no_pal("getgid")
+    }
+
+    fn getrusage(who: c_int, r_usage: *mut rusage) -> c_int {
+        Self::no_pal("getrusage")
+    }
+
+    unsafe fn gethostname(mut name: *mut c_char, len: size_t) -> c_int {
+        Self::no_pal("gethostname")
+    }
+
+    fn getitimer(which: c_int, out: *mut itimerval) -> c_int {
+        Self::no_pal("getitimer")
+    }
+
+    unsafe fn getpeername(socket: c_int, address: *mut sockaddr, address_len: *mut socklen_t) -> c_int {
+        Self::no_pal("getpeername")
+    }
+
+    fn getpgid(pid: pid_t) -> pid_t {
+        Self::no_pal("getpgid")
+    }
+
+    fn getpid() -> pid_t {
+        Self::no_pal("getpid")
+    }
+
+    fn getppid() -> pid_t {
+        Self::no_pal("getppid")
+    }
+
+    unsafe fn getsockname(socket: c_int, address: *mut sockaddr, address_len: *mut socklen_t) -> c_int {
+        Self::no_pal("getsockname")
+    }
+
+    fn getsockopt(
+        socket: c_int,
+        level: c_int,
+        option_name: c_int,
+        option_value: *mut c_void,
+        option_len: *mut socklen_t,
+    ) -> c_int {
+        Self::no_pal("getsockopt")
+    }
+
+    fn gettimeofday(tp: *mut timeval, tzp: *mut timezone) -> c_int {
+        Self::no_pal("gettimeofday")
+    }
+
+    fn getuid() -> uid_t {
+        Self::no_pal("getuid")
+    }
+
+    fn ioctl(fd: c_int, request: c_ulong, out: *mut c_void) -> c_int {
+        Self::no_pal("ioctl")
+    }
+
+    fn isatty(fd: c_int) -> c_int {
+        Self::no_pal("isatty")
+    }
+
+    fn kill(pid: pid_t, sig: c_int) -> c_int {
+        Self::no_pal("kill")
+    }
+
+    fn killpg(pgrp: pid_t, sig: c_int) -> c_int {
+        Self::no_pal("killpg")
+    }
+
+    fn link(path1: *const c_char, path2: *const c_char) -> c_int {
+        Self::no_pal("link")
+    }
+
+    fn listen(socket: c_int, backlog: c_int) -> c_int {
+        Self::no_pal("listen")
+    }
+
+    fn lseek(fildes: c_int, offset: off_t, whence: c_int) -> off_t {
+        Self::no_pal("lseek")
+    }
+
+    fn lstat(file: *const c_char, buf: *mut stat) -> c_int {
+        Self::no_pal("lstat")
+    }
+
+    fn mkdir(path: *const c_char, mode: mode_t) -> c_int {
+        Self::no_pal("mkdir")
+    }
+
+    fn mkfifo(path: *const c_char, mode: mode_t) -> c_int {
+        Self::no_pal("mkfifo")
+    }
+
+    unsafe fn mmap(
+        addr: *mut c_void,
+        len: usize,
+        prot: c_int,
+        flags: c_int,
+        fildes: c_int,
+        off: off_t,
+    ) -> *mut c_void {
+        Self::no_pal("mmap")
+    }
+
+    unsafe fn munmap(addr: *mut c_void, len: usize) -> c_int {
+        Self::no_pal("munmap")
+    }
+
+    fn nanosleep(rqtp: *const timespec, rmtp: *mut timespec) -> c_int {
+        Self::no_pal("nanosleep")
+    }
+
+    fn open(path: *const c_char, oflag: c_int, mode: mode_t) -> c_int {
+        Self::no_pal("open")
+    }
+
+    fn pipe(fildes: &mut [c_int]) -> c_int {
+        Self::no_pal("pipe")
+    }
+
+    fn raise(sig: c_int) -> c_int {
+        Self::no_pal("raise")
+    }
+
+    fn read(fildes: c_int, buf: &mut [u8]) -> ssize_t {
+        Self::no_pal("read")
+    }
+
+    unsafe fn recvfrom(
+        socket: c_int,
+        buf: *mut c_void,
+        len: size_t,
+        flags: c_int,
+        address: *mut sockaddr,
+        address_len: *mut socklen_t,
+    ) -> ssize_t {
+        Self::no_pal("recvfrom")
+    }
+
+    fn rename(old: *const c_char, new: *const c_char) -> c_int {
+        Self::no_pal("rename")
+    }
+
+    fn rmdir(path: *const c_char) -> c_int {
+        Self::no_pal("rmdir")
+    }
+
+    fn select(
+        nfds: c_int,
+        readfds: *mut fd_set,
+        writefds: *mut fd_set,
+        exceptfds: *mut fd_set,
+        timeout: *mut timeval,
+    ) -> c_int {
+        Self::no_pal("select")
+    }
+
+    unsafe fn sendto(
+        socket: c_int,
+        buf: *const c_void,
+        len: size_t,
+        flags: c_int,
+        dest_addr: *const sockaddr,
+        dest_len: socklen_t,
+    ) -> ssize_t {
+        Self::no_pal("sendto")
+    }
+
+    fn setitimer(which: c_int, new: *const itimerval, old: *mut itimerval) -> c_int {
+        Self::no_pal("setitimer")
+    }
+
+    fn setpgid(pid: pid_t, pgid: pid_t) -> c_int {
+        Self::no_pal("setpgid")
+    }
+
+    fn setregid(rgid: gid_t, egid: gid_t) -> c_int {
+        Self::no_pal("setregid")
+    }
+
+    fn setreuid(ruid: uid_t, euid: uid_t) -> c_int {
+        Self::no_pal("setreuid")
+    }
+
+    fn setsockopt(
+        socket: c_int,
+        level: c_int,
+        option_name: c_int,
+        option_value: *const c_void,
+        option_len: socklen_t,
+    ) -> c_int {
+        Self::no_pal("setsockopt")
+    }
+
+    fn shutdown(socket: c_int, how: c_int) -> c_int {
+        Self::no_pal("shutdown")
+    }
+
+    unsafe fn sigaction(sig: c_int, act: *const sigaction, oact: *mut sigaction) -> c_int {
+        Self::no_pal("sigaction")
+    }
+
+    fn sigprocmask(how: c_int, set: *const sigset_t, oset: *mut sigset_t) -> c_int {
+        Self::no_pal("sigprocmask")
+    }
+
+    fn stat(file: *const c_char, buf: *mut stat) -> c_int {
+        Self::no_pal("stat")
+    }
+
+    fn socket(domain: c_int, kind: c_int, protocol: c_int) -> c_int {
+        Self::no_pal("socket")
+    }
+
+    fn socketpair(domain: c_int, kind: c_int, protocol: c_int, socket_vector: *mut c_int) -> c_int {
+        Self::no_pal("socketpair")
+    }
+
+    fn tcgetattr(fd: c_int, out: *mut termios) -> c_int {
+        Self::no_pal("tcgetattr")
+    }
+
+    fn tcsetattr(fd: c_int, act: c_int, value: *const termios) -> c_int {
+        Self::no_pal("tcsetattr")
+    }
+
+    fn times(out: *mut tms) -> clock_t {
+        Self::no_pal("times")
+    }
+
+    fn umask(mask: mode_t) -> mode_t {
+        Self::no_pal("umask")
+    }
+
+    fn uname(utsname: *mut utsname) -> c_int {
+        Self::no_pal("uname")
+    }
+
+    fn unlink(path: *const c_char) -> c_int {
+        Self::no_pal("unlink")
+    }
+
+    fn waitpid(pid: pid_t, stat_loc: *mut c_int, options: c_int) -> pid_t {
+        Self::no_pal("waitpid")
+    }
+
+    fn write(fildes: c_int, buf: &[u8]) -> ssize_t {
+        Self::no_pal("write")
+    }
+}
diff --git a/src/sys_resource/src/lib.rs b/src/sys_resource/src/lib.rs
index 228f26fc7d1d09b0f00d77ae7cd1f3e28639c9d5..f919012588b5ed21ae1337da7b8ab5d109bf4d01 100644
--- a/src/sys_resource/src/lib.rs
+++ b/src/sys_resource/src/lib.rs
@@ -53,7 +53,7 @@ pub unsafe extern "C" fn getrlimit(resource: c_int, rlp: *mut rlimit) -> c_int {
     unimplemented!();
 }
 
-#[no_mangle]
+//#[no_mangle]
 pub unsafe extern "C" fn getrusage(who: c_int, r_usage: *mut rusage) -> c_int {
     platform::getrusage(who, r_usage as *mut platform::types::rusage)
 }
diff --git a/src/sys_times/src/lib.rs b/src/sys_times/src/lib.rs
index 3d8b7f89031bb4fb3ef16624d309533e09e6f285..965e75a33b0cdb8e3f11cad3922364b2e977a56b 100644
--- a/src/sys_times/src/lib.rs
+++ b/src/sys_times/src/lib.rs
@@ -14,7 +14,7 @@ pub struct tms {
     tms_cstime: clock_t,
 }
 
-#[no_mangle]
+//#[no_mangle]
 pub extern "C" fn times(out: *mut tms) -> clock_t {
     platform::times(out as *mut platform::types::tms)
 }