diff --git a/src/ld_so/linker.rs b/src/ld_so/linker.rs index 75741c1c7f4a1c0a206a287334818851d0aca036..86f65225e6d51f6a68fc0008743979998bd666be 100644 --- a/src/ld_so/linker.rs +++ b/src/ld_so/linker.rs @@ -4,7 +4,12 @@ use alloc::{ string::{String, ToString}, vec::Vec, }; -use core::{mem, ptr, slice}; +use core::{ + mem, + ops::Range, + ptr, + slice +}; use goblin::{ elf::{program_header, reloc, sym, Elf}, error::{Error, Result}, @@ -30,8 +35,13 @@ const PATH_SEP: char = ';'; const PATH_SEP: char = ':'; pub struct Linker { + // Used by load library_path: String, objects: BTreeMap<String, Box<[u8]>>, + // Used by link + mmaps: BTreeMap<String, &'static mut [u8]>, + globals: BTreeMap<String, usize>, + tls_ranges: BTreeMap<String, (usize, Range<usize>)>, } impl Linker { @@ -39,6 +49,9 @@ impl Linker { Self { library_path: library_path.to_string(), objects: BTreeMap::new(), + mmaps: BTreeMap::new(), + globals: BTreeMap::new(), + tls_ranges: BTreeMap::new(), } } @@ -125,8 +138,6 @@ impl Linker { // Load all ELF files into memory and find all globals let mut tls_primary = 0; let mut tls_size = 0; - let mut mmaps = BTreeMap::new(); - let mut globals = BTreeMap::new(); for (elf_name, elf) in elfs.iter() { println!("map {}", elf_name); @@ -205,12 +216,12 @@ impl Linker { let name = name_res?; let value = mmap.as_ptr() as usize + sym.st_value as usize; // println!(" global {}: {:x?} = {:#x}", name, sym, value); - globals.insert(name, value); + self.globals.insert(name.to_string(), value); } } } - mmaps.insert(elf_name, mmap); + self.mmaps.insert(elf_name.to_string(), mmap); } // Allocate TLS @@ -226,14 +237,13 @@ impl Linker { len: 0, offset: 0, }); - let mut tls_ranges = BTreeMap::new(); for (elf_name, elf) in elfs.iter() { let object = match self.objects.get(*elf_name) { Some(some) => some, None => continue, }; - let mmap = match mmaps.get_mut(elf_name) { + let mmap = match self.mmaps.get_mut(*elf_name) { Some(some) => some, None => continue, }; @@ -303,12 +313,12 @@ impl Linker { ); if *elf_name == primary { - tls_ranges.insert(elf_name, (0, tcb_master.range())); + self.tls_ranges.insert(elf_name.to_string(), (0, tcb_master.range())); tcb_masters[0] = tcb_master; } else { tcb_master.offset -= tls_offset; tls_offset += vsize; - tls_ranges.insert(elf_name, (tcb_masters.len(), tcb_master.range())); + self.tls_ranges.insert(elf_name.to_string(), (tcb_masters.len(), tcb_master.range())); tcb_masters.push(tcb_master); } } @@ -325,7 +335,7 @@ impl Linker { // Perform relocations, and protect pages for (elf_name, elf) in elfs.iter() { - let mmap = match mmaps.get_mut(elf_name) { + let mmap = match self.mmaps.get_mut(*elf_name) { Some(some) => some, None => continue, }; @@ -362,7 +372,7 @@ impl Linker { sym )))??; - if let Some(value) = globals.get(name) { + if let Some(value) = self.globals.get(name) { // println!(" sym {}: {:x?} = {:#x}", name, sym, value); *value } else { @@ -373,7 +383,7 @@ impl Linker { 0 }; - let (tm, t) = if let Some((tls_index, tls_range)) = tls_ranges.get(elf_name) { + let (tm, t) = if let Some((tls_index, tls_range)) = self.tls_ranges.get(*elf_name) { (*tls_index, tls_range.start) } else { (0, 0) @@ -460,7 +470,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 mmaps.get_mut(elf_name) { + let mmap = match self.mmaps.get_mut(*elf_name) { Some(some) => some, None => continue, };