diff --git a/src/header/stdlib/mod.rs b/src/header/stdlib/mod.rs
index 709bfc741efb442d6b0378ab75cf7f6221726a7f..02750d14422e4778776340fe52fc0c56f34acaa1 100644
--- a/src/header/stdlib/mod.rs
+++ b/src/header/stdlib/mod.rs
@@ -218,12 +218,18 @@ pub extern "C" fn erand(xsubi: [c_ushort; 3]) -> c_double {
 
 #[no_mangle]
 pub unsafe extern "C" fn exit(status: c_int) {
+    extern "C" {
+        fn _fini();
+    }
+
     for i in (0..ATEXIT_FUNCS.len()).rev() {
         if let Some(func) = ATEXIT_FUNCS[i] {
             (func)();
         }
     }
 
+    _fini();
+
     Sys::exit(status);
 }
 
diff --git a/src/start.rs b/src/start.rs
index 02e739f82890fc25b97702b4bd86b1c6dcc38f74..006b722d9cd5028069f4386a8e6947a1a89a0a35 100644
--- a/src/start.rs
+++ b/src/start.rs
@@ -1,7 +1,7 @@
 use alloc::Vec;
 use core::ptr;
 
-use header::stdio;
+use header::{stdio, stdlib};
 use platform;
 use platform::types::*;
 use platform::{Pal, Sys};
@@ -30,6 +30,7 @@ impl Stack {
 #[no_mangle]
 pub unsafe extern "C" fn relibc_start(sp: &'static Stack) -> ! {
     extern "C" {
+        fn _init();
         fn main(argc: isize, argv: *const *const c_char, envp: *const *const c_char) -> c_int;
     }
 
@@ -63,11 +64,15 @@ pub unsafe extern "C" fn relibc_start(sp: &'static Stack) -> ! {
     stdio::stdout = stdio::default_stdout.get();
     stdio::stderr = stdio::default_stderr.get();
 
-    Sys::exit(main(
+    _init();
+
+    stdlib::exit(main(
         argc,
         argv,
         // not envp, because programs like bash try to modify this *const*
         // pointer :|
         platform::environ as *const *const c_char,
     ));
+
+    unreachable!();
 }