diff --git a/src/header/dlfcn/mod.rs b/src/header/dlfcn/mod.rs
index cc10390c07e12800b2f2ce7a7a31d8fe969e7fee..f9c3bc8149c59b02b4b95aa2fadc1b97921e3100 100644
--- a/src/header/dlfcn/mod.rs
+++ b/src/header/dlfcn/mod.rs
@@ -66,7 +66,7 @@ pub unsafe extern "C" fn dlopen(filename: *const c_char, flags: c_int) -> *mut c
                 }
             }
 
-            match linker.link(None) {
+            match linker.link(None, None) {
                 Ok(ok) => (),
                 Err(err) => {
                     eprintln!("dlopen: failed to link '{}': {}", filename, err);
diff --git a/src/ld_so/linker.rs b/src/ld_so/linker.rs
index 848645146058b9695a7493b6902ce18656904226..15c666711c436468b224c25e2754a6f9e8418665 100644
--- a/src/ld_so/linker.rs
+++ b/src/ld_so/linker.rs
@@ -29,6 +29,12 @@ const PATH_SEP: char = ';';
 #[cfg(target_os = "linux")]
 const PATH_SEP: char = ':';
 
+pub struct DSO {
+    pub name: String,
+    pub base_addr: usize,
+    pub entry_point: usize,
+}
+
 pub struct Linker {
     // Used by load
     /// Library path to search when loading library by name
@@ -190,7 +196,7 @@ impl Linker {
         }
     }
 
-    pub fn link(&mut self, primary_opt: Option<&str>) -> Result<Option<usize>> {
+    pub fn link(&mut self, primary_opt: Option<&str>, dso: Option<DSO>) -> Result<Option<usize>> {
         let elfs = {
             let mut elfs = BTreeMap::new();
             for (name, data) in self.objects.iter() {
@@ -262,22 +268,41 @@ impl Linker {
             // Allocate memory
             let mmap = unsafe {
                 let size = bounds.1 /* - bounds.0 */;
-                let ptr = sys_mman::mmap(
-                    ptr::null_mut(),
-                    size,
-                    //TODO: Make it possible to not specify PROT_EXEC on Redox
-                    sys_mman::PROT_READ | sys_mman::PROT_WRITE,
-                    sys_mman::MAP_ANONYMOUS | sys_mman::MAP_PRIVATE,
-                    -1,
-                    0,
-                );
-                if ptr as usize == !0
-                /* MAP_FAILED */
-                {
-                    return Err(Error::Malformed(format!("failed to map {}", elf_name)));
+                let same_elf = if let Some(prog) = dso.as_ref() {
+                    if prog.name == *elf_name {
+                        true
+                    } else {
+                        false
+                    }
+                } else {
+                    false
+                };
+                if same_elf {
+                    let addr = dso.as_ref().unwrap().base_addr;
+                    sys_mman::mprotect(
+                        addr as *mut c_void,
+                        size,
+                        sys_mman::PROT_READ | sys_mman::PROT_WRITE,
+                    );
+                    slice::from_raw_parts_mut(addr as *mut u8, size)
+                } else {
+                    let ptr = sys_mman::mmap(
+                        ptr::null_mut(),
+                        size,
+                        //TODO: Make it possible to not specify PROT_EXEC on Redox
+                        sys_mman::PROT_READ | sys_mman::PROT_WRITE,
+                        sys_mman::MAP_ANONYMOUS | sys_mman::MAP_PRIVATE,
+                        -1,
+                        0,
+                    );
+                    if ptr as usize == !0
+                    /* MAP_FAILED */
+                    {
+                        return Err(Error::Malformed(format!("failed to map {}", elf_name)));
+                    }
+                    ptr::write_bytes(ptr as *mut u8, 0, size);
+                    slice::from_raw_parts_mut(ptr as *mut u8, size)
                 }
-                ptr::write_bytes(ptr as *mut u8, 0, size);
-                slice::from_raw_parts_mut(ptr as *mut u8, size)
             };
             if self.verbose {
                 println!("  mmap {:p}, {:#x}", mmap.as_mut_ptr(), mmap.len());
@@ -308,6 +333,18 @@ impl Linker {
         });
         let mut tls_ranges = BTreeMap::new();
         for (elf_name, elf) in elfs.iter() {
+            let same_elf = if let Some(prog) = dso.as_ref() {
+                if prog.name == *elf_name {
+                    true
+                } else {
+                    false
+                }
+            } else {
+                false
+            };
+            if same_elf {
+                continue;
+            }
             let object = match self.objects.get(*elf_name) {
                 Some(some) => some,
                 None => continue,
diff --git a/src/ld_so/start.rs b/src/ld_so/start.rs
index 28856a46fef6ab87b96f9b793ccd1c445c363041..16075479925ddb0a794f37adf2968137953dc89d 100644
--- a/src/ld_so/start.rs
+++ b/src/ld_so/start.rs
@@ -6,8 +6,11 @@ use crate::{
     c_str::CStr, header::unistd, platform::types::c_char, start::Stack, sync::mutex::Mutex,
 };
 
-use super::{linker::Linker, tcb::Tcb};
-use crate::header::sys_auxv::AT_ENTRY;
+use super::{
+    linker::{Linker, DSO},
+    tcb::Tcb,
+};
+use crate::header::sys_auxv::{AT_ENTRY, AT_PHDR};
 
 unsafe fn get_argv(mut ptr: *const usize) -> (Vec<String>, *const usize) {
     //traverse the stack and collect argument vector
@@ -149,7 +152,26 @@ pub extern "C" fn relibc_ld_so_start(sp: &'static mut Stack, ld_entry: usize) ->
     } else {
         &argv[0]
     };
-
+    // if we are not running in manual mode, then the main
+    // program is already loaded by the kernel and we want
+    // to use it.
+    let program = {
+        let mut pr = None;
+        if !is_manual {
+            let phdr = *auxv.get(&AT_PHDR).unwrap();
+            if phdr != 0 {
+                let p = DSO {
+                    name: path.to_owned(),
+                    entry_point: *auxv.get(&AT_ENTRY).unwrap(),
+                    // The 0x40 is the size of Elf header not a good idea for different bit size
+                    // compatiablility but it will always work on 64 bit systems,
+                    base_addr: phdr - 0x40,
+                };
+                pr = Some(p);
+            }
+        }
+        pr
+    };
     let mut linker = Linker::new(library_path, false);
     match linker.load(&path, &path) {
         Ok(()) => (),
@@ -160,7 +182,7 @@ pub extern "C" fn relibc_ld_so_start(sp: &'static mut Stack, ld_entry: usize) ->
         }
     }
 
-    let entry = match linker.link(Some(&path)) {
+    let entry = match linker.link(Some(&path), program) {
         Ok(ok) => match ok {
             Some(some) => some,
             None => {