فهرست منبع

Separate library specific data from main Linker struct

oddcoder 4 سال پیش
والد
کامیت
01b1738b3a
3فایلهای تغییر یافته به همراه83 افزوده شده و 75 حذف شده
  1. 52 0
      src/ld_so/library.rs
  2. 30 75
      src/ld_so/linker.rs
  3. 1 0
      src/ld_so/mod.rs

+ 52 - 0
src/ld_so/library.rs

@@ -0,0 +1,52 @@
+use alloc::{
+    boxed::Box,
+    collections::{BTreeMap, BTreeSet},
+    string::String,
+    vec::Vec,
+};
+
+#[derive(Default, Debug)]
+pub struct DepTree {
+    pub name: String,
+    pub deps: Vec<DepTree>,
+}
+
+impl DepTree {
+    pub fn new(name: String) -> DepTree {
+        DepTree {
+            name,
+            deps: Vec::new(),
+        }
+    }
+}
+
+/// Use to represnt a library as well as all th symbols that is loaded withen it.
+#[derive(Default)]
+pub struct Library {
+    /// Global symbols
+    pub globals: BTreeMap<String, usize>,
+    /// Weak symbols
+    pub weak_syms: BTreeMap<String, usize>,
+    /// Loaded library raw data
+    pub objects: BTreeMap<String, Box<[u8]>>,
+    /// Loaded library in-memory data
+    pub mmaps: BTreeMap<String, &'static mut [u8]>,
+    /// Each object will have its children called once with no repetition.
+    pub dep_tree: DepTree,
+    /// A set used to detect circular dependencies in the Linker::load function
+    pub cir_dep: BTreeSet<String>,
+}
+impl Library {
+    pub fn new() -> Library {
+        Default::default()
+    }
+    pub fn get_sym(&self, name: &str) -> Option<usize> {
+        if let Some(value) = self.globals.get(name) {
+            Some(*value)
+        } else if let Some(value) = self.weak_syms.get(name) {
+            Some(*value)
+        } else {
+            None
+        }
+    }
+}

+ 30 - 75
src/ld_so/linker.rs

@@ -1,6 +1,6 @@
 use alloc::{
     boxed::Box,
-    collections::{BTreeMap, BTreeSet},
+    collections::BTreeMap,
     string::{String, ToString},
     vec::Vec,
 };
@@ -29,6 +29,7 @@ use crate::{
 use super::{
     access::access,
     debug::{RTLDDebug, RTLDState, _dl_debug_state, _r_debug},
+    library::{DepTree, Library},
     tcb::{Master, Tcb},
     PAGE_SIZE,
 };
@@ -43,61 +44,30 @@ pub struct DSO {
     pub base_addr: usize,
     pub entry_point: usize,
 }
-#[derive(Default, Debug)]
-pub struct DepTree {
-    pub name: String,
-    pub deps: Vec<DepTree>,
-}
 
-impl DepTree {
-    fn new(name: String) -> DepTree {
-        DepTree {
-            name,
-            deps: Vec::new(),
-        }
-    }
-}
 pub struct Linker {
     // Used by load
     /// Library path to search when loading library by name
     library_path: String,
-    /// Loaded library raw data
-    objects: BTreeMap<String, Box<[u8]>>,
-
-    // Used by link
-    /// Global symbols
-    globals: BTreeMap<String, usize>,
-    /// Weak symbols
-    weak_syms: BTreeMap<String, usize>,
-    /// Loaded library in-memory data
-    mmaps: BTreeMap<String, &'static mut [u8]>,
+    root: Library,
     verbose: bool,
     tls_index_offset: usize,
-    /// A set used to detect circular dependencies in the Linker::load function
-    cir_dep: BTreeSet<String>,
-    /// Each object will have its children callec once with no repetition.
-    dep_tree: DepTree,
 }
 
 impl Linker {
     pub fn new(library_path: &str, verbose: bool) -> Self {
         Self {
             library_path: library_path.to_string(),
-            objects: BTreeMap::new(),
-            globals: BTreeMap::new(),
-            weak_syms: BTreeMap::new(),
-            mmaps: BTreeMap::new(),
+            root: Library::new(),
             verbose,
             tls_index_offset: 0,
-            cir_dep: BTreeSet::new(),
-            dep_tree: Default::default(),
         }
     }
 
     pub fn load(&mut self, name: &str, path: &str) -> Result<()> {
-        self.dep_tree = self.load_recursive(name, path)?;
+        self.root.dep_tree = self.load_recursive(name, path)?;
         if self.verbose {
-            println!("Dep tree: {:#?}", self.dep_tree);
+            println!("Dep tree: {:#?}", self.root.dep_tree);
         }
         return Ok(());
     }
@@ -106,7 +76,7 @@ impl Linker {
         if self.verbose {
             println!("load {}: {}", name, path);
         }
-        if self.cir_dep.contains(name) {
+        if self.root.cir_dep.contains(name) {
             return Err(Error::Malformed(format!(
                 "Circular dependency: {} is a dependency of itself",
                 name
@@ -115,7 +85,7 @@ impl Linker {
 
         let mut deps = DepTree::new(name.to_string());
         let mut data = Vec::new();
-        self.cir_dep.insert(name.to_string());
+        self.root.cir_dep.insert(name.to_string());
         let path_c = CString::new(path)
             .map_err(|err| Error::Malformed(format!("invalid path '{}': {}", path, err)))?;
 
@@ -128,7 +98,7 @@ impl Linker {
                 .map_err(|err| Error::Malformed(format!("failed to read '{}': {}", path, err)))?;
         }
         deps.deps = self.load_data(name, data.into_boxed_slice())?;
-        self.cir_dep.remove(name);
+        self.root.cir_dep.remove(name);
         Ok(deps)
     }
 
@@ -142,13 +112,13 @@ impl Linker {
             }
         }
 
-        self.objects.insert(name.to_string(), data);
+        self.root.objects.insert(name.to_string(), data);
 
         return Ok(deps);
     }
 
     pub fn load_library(&mut self, name: &str) -> Result<Option<DepTree>> {
-        if self.objects.contains_key(name) {
+        if 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('/') {
@@ -228,25 +198,10 @@ impl Linker {
     }
 
     pub fn get_sym(&self, name: &str) -> Option<usize> {
-        if let Some(value) = self.globals.get(name) {
-            if self.verbose {
-                println!("    sym {} = {:#x}", name, value);
-            }
-            Some(*value)
-        } else if let Some(value) = self.weak_syms.get(name) {
-            if self.verbose {
-                println!("    sym {} = {:#x}", name, value);
-            }
-            Some(*value)
-        } else {
-            if self.verbose {
-                println!("    sym {} = undefined", name);
-            }
-            None
-        }
+        self.root.get_sym(name)
     }
     pub fn run_init(&self) -> Result<()> {
-        self.run_init_tree(&self.dep_tree)
+        self.run_init_tree(&self.root.dep_tree)
     }
 
     fn run_init_tree(&self, root: &DepTree) -> Result<()> {
@@ -256,11 +211,11 @@ impl Linker {
         if self.verbose {
             println!("init {}", &root.name);
         }
-        let mmap = match self.mmaps.get(&root.name) {
+        let mmap = match self.root.mmaps.get(&root.name) {
             Some(some) => some,
             None => return Ok(()),
         };
-        let elf = Elf::parse(self.objects.get(&root.name).unwrap())?;
+        let elf = Elf::parse(self.root.objects.get(&root.name).unwrap())?;
         for section in &elf.section_headers {
             let name = match elf.shdr_strtab.get(section.sh_name) {
                 Some(x) => match x {
@@ -284,18 +239,18 @@ impl Linker {
     }
 
     pub fn run_fini(&self) -> Result<()> {
-        self.run_fini_tree(&self.dep_tree)
+        self.run_fini_tree(&self.root.dep_tree)
     }
 
     fn run_fini_tree(&self, root: &DepTree) -> Result<()> {
         if self.verbose {
             println!("init {}", &root.name);
         }
-        let mmap = match self.mmaps.get(&root.name) {
+        let mmap = match self.root.mmaps.get(&root.name) {
             Some(some) => some,
             None => return Ok(()),
         };
-        let elf = Elf::parse(self.objects.get(&root.name).unwrap())?;
+        let elf = Elf::parse(self.root.objects.get(&root.name).unwrap())?;
         for section in &elf.section_headers {
             let name = match elf.shdr_strtab.get(section.sh_name) {
                 Some(x) => match x {
@@ -326,9 +281,9 @@ impl Linker {
         _dl_debug_state();
         let elfs = {
             let mut elfs = BTreeMap::new();
-            for (name, data) in self.objects.iter() {
+            for (name, data) in self.root.objects.iter() {
                 // Skip already linked libraries
-                if !self.mmaps.contains_key(&*name) {
+                if !self.root.mmaps.contains_key(&*name) {
                     elfs.insert(name.as_str(), Elf::parse(&data)?);
                 }
             }
@@ -342,7 +297,7 @@ impl Linker {
             if self.verbose {
                 println!("map {}", elf_name);
             }
-            let object = match self.objects.get(*elf_name) {
+            let object = match self.root.objects.get(*elf_name) {
                 Some(some) => some,
                 None => continue,
             };
@@ -478,9 +433,9 @@ impl Linker {
                 println!("  mmap {:p}, {:#x}", mmap.as_mut_ptr(), mmap.len());
             }
             let (globals, weak_syms) = Linker::collect_syms(&elf, &mmap, self.verbose)?;
-            self.globals.extend(globals.into_iter());
-            self.weak_syms.extend(weak_syms.into_iter());
-            self.mmaps.insert(elf_name.to_string(), mmap);
+            self.root.globals.extend(globals.into_iter());
+            self.root.weak_syms.extend(weak_syms.into_iter());
+            self.root.mmaps.insert(elf_name.to_string(), mmap);
         }
 
         // Allocate TLS
@@ -515,12 +470,12 @@ impl Linker {
             if same_elf {
                 continue;
             }
-            let object = match self.objects.get(*elf_name) {
+            let object = match self.root.objects.get(*elf_name) {
                 Some(some) => some,
                 None => continue,
             };
 
-            let mmap = match self.mmaps.get_mut(*elf_name) {
+            let mmap = match self.root.mmaps.get_mut(*elf_name) {
                 Some(some) => some,
                 None => continue,
             };
@@ -660,7 +615,7 @@ impl Linker {
 
                 let a = rel.r_addend.unwrap_or(0) as usize;
 
-                let mmap = match self.mmaps.get_mut(*elf_name) {
+                let mmap = match self.root.mmaps.get_mut(*elf_name) {
                     Some(some) => some,
                     None => continue,
                 };
@@ -741,7 +696,7 @@ impl Linker {
             }
             if let Some(dyn_start_addr) = dyn_start {
                 if let Some(i) = debug_start {
-                    let mmap = match self.mmaps.get_mut(*elf_name) {
+                    let mmap = match self.root.mmaps.get_mut(*elf_name) {
                         Some(some) => some,
                         None => continue,
                     };
@@ -778,7 +733,7 @@ impl Linker {
                         prot |= sys_mman::PROT_WRITE;
                     }
 
-                    let mmap = match self.mmaps.get_mut(*elf_name) {
+                    let mmap = match self.root.mmaps.get_mut(*elf_name) {
                         Some(some) => some,
                         None => continue,
                     };
@@ -811,7 +766,7 @@ impl Linker {
         // Perform indirect relocations (necessary evil), gather entry point
         let mut entry_opt = None;
         for (elf_name, elf) in elfs.iter() {
-            let mmap = match self.mmaps.get_mut(*elf_name) {
+            let mmap = match self.root.mmaps.get_mut(*elf_name) {
                 Some(some) => some,
                 None => continue,
             };

+ 1 - 0
src/ld_so/mod.rs

@@ -6,6 +6,7 @@ pub const PAGE_SIZE: usize = 4096;
 
 mod access;
 pub mod debug;
+mod library;
 pub mod linker;
 pub mod start;
 pub mod tcb;