Store globals and mappings on Linker struct
This commit is contained in:
+23
-13
@@ -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,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user