Skip to content
Snippets Groups Projects
Commit 69fc6227 authored by Jeremy Soller's avatar Jeremy Soller
Browse files

Merge branch 'use_kernel_loaded_elf' into 'master'

Use Kernel mapped binaries when available.

See merge request !262
parents 701e64b3 cc305fc5
No related branches found
No related tags found
1 merge request!262Use Kernel mapped binaries when available.
Pipeline #7272 failed
......@@ -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);
......
......@@ -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,
......
......@@ -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 => {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment