From ea3265766c4ede0b363b09fe1388a7a2f0f153c2 Mon Sep 17 00:00:00 2001 From: oddcoder <ahmedsoliman@oddcoder.com> Date: Sat, 4 Jul 2020 14:05:40 +0200 Subject: [PATCH] Allow struct Linker to specify which library space to use --- src/ld_so/linker.rs | 60 +++++++++++++++++++++++++++------------------ 1 file changed, 36 insertions(+), 24 deletions(-) diff --git a/src/ld_so/linker.rs b/src/ld_so/linker.rs index bfddca203..201e14344 100644 --- a/src/ld_so/linker.rs +++ b/src/ld_so/linker.rs @@ -1,10 +1,12 @@ use alloc::{ boxed::Box, collections::BTreeMap, + rc::Rc, string::{String, ToString}, vec::Vec, }; use core::{ + cell::RefCell, mem::{size_of, swap, transmute}, ptr, slice, }; @@ -28,6 +30,7 @@ use crate::{ use super::{ access::access, + callbacks::LinkerCallbacks, debug::{RTLDDebug, RTLDState, _dl_debug_state, _r_debug}, library::{DepTree, Library}, tcb::{Master, Tcb}, @@ -52,6 +55,9 @@ pub struct Linker { root: Library, verbose: bool, tls_index_offset: usize, + lib_spaces: BTreeMap<usize, Library>, + counter: usize, + pub cbs: Rc<RefCell<LinkerCallbacks>>, } impl Linker { @@ -61,9 +67,11 @@ impl Linker { root: Library::new(), verbose, tls_index_offset: 0, + lib_spaces: BTreeMap::new(), + counter: 1, + cbs: Rc::new(RefCell::new(LinkerCallbacks::new())), } } - pub fn load(&mut self, name: &str, path: &str) -> Result<()> { let mut lib: Library = Library::new(); swap(&mut lib, &mut self.root); @@ -74,7 +82,13 @@ impl Linker { } return Ok(()); } - + pub fn unload(&mut self, libspace: usize) { + if let Some(lib) = self.lib_spaces.remove(&libspace) { + for (_, mmap) in lib.mmaps { + unsafe { sys_mman::munmap(mmap.as_mut_ptr() as *mut c_void, mmap.len()) }; + } + } + } fn load_recursive(&mut self, name: &str, path: &str, lib: &mut Library) -> Result<DepTree> { if self.verbose { println!("load {}: {}", name, path); @@ -125,13 +139,16 @@ impl Linker { return Ok(deps); } - pub fn load_library(&mut self, name: &str) -> Result<Option<DepTree>> { - // TODO this is wrong + pub fn load_library(&mut self, name: &str) -> Result<usize> { let mut lib = Library::new(); - self._load_library(name, &mut lib) + self._load_library(name, &mut lib)?; + let ret = self.counter; + self.lib_spaces.insert(ret, lib); + self.counter += 1; + return Ok(ret); } fn _load_library(&mut self, name: &str, lib: &mut Library) -> Result<Option<DepTree>> { - if lib.objects.contains_key(name) { + if lib.objects.contains_key(name) || self.root.objects.contains_key(name) { // It should be previously resolved so we don't need to worry about it Ok(None) } else if name.contains('/') { @@ -212,9 +229,8 @@ impl Linker { pub fn get_sym(&self, name: &str, libspace: Option<usize>) -> Option<usize> { match libspace { - Some(lib) => { - //TODO this is the same kind of wrong - let lib = Library::new(); + Some(id) => { + let lib = self.lib_spaces.get(&id)?; lib.get_sym(name) } None => self.root.get_sym(name), @@ -223,23 +239,18 @@ impl Linker { pub fn run_init(&self, libspace: Option<usize>) -> Result<()> { match libspace { - Some(lib) => { - //TODO this is the same kind of wrong - let lib = Library::new(); + Some(id) => { + let lib = self.lib_spaces.get(&id).unwrap(); self.run_tree(&lib, &lib.dep_tree, ".init_array") } - None => { - //TODO we first need to deinitialize all the loaded libraries first! - self.run_tree(&self.root, &self.root.dep_tree, ".init_array") - } + None => self.run_tree(&self.root, &self.root.dep_tree, ".init_array"), } } pub fn run_fini(&self, libspace: Option<usize>) -> Result<()> { match libspace { - Some(lib) => { - //TODO this is the same kind of wrong - let lib = Library::new(); + Some(id) => { + let lib = self.lib_spaces.get(&id).unwrap().unwrap(); self.run_tree(&lib, &lib.dep_tree, ".fini_array") } None => { @@ -290,10 +301,11 @@ impl Linker { libspace: Option<usize>, ) -> Result<Option<usize>> { match libspace { - Some(lib) => { - //TODO this is the same kind of wrong - let mut lib = Library::new(); - self._link(primary_opt, dso, &mut lib) + Some(id) => { + let mut lib = self.lib_spaces.remove(&id).unwrap(); + let res = self._link(primary_opt, dso, &mut lib); + self.lib_spaces.insert(id, lib); + res } None => { let mut lib = Library::new(); @@ -317,7 +329,7 @@ impl Linker { let mut elfs = BTreeMap::new(); for (name, data) in lib.objects.iter() { // Skip already linked libraries - if !lib.mmaps.contains_key(&*name) { + if !lib.mmaps.contains_key(&*name) && !self.root.mmaps.contains_key(&*name) { elfs.insert(name.as_str(), Elf::parse(&data)?); } } -- GitLab