Skip to content
Snippets Groups Projects
Commit 4860ab12 authored by Ahmed Abd El Mawgood's avatar Ahmed Abd El Mawgood
Browse files

Resolve Both strong and weak symbols

This patch keep 2 lists, one for strong symbols and one for weak
symbols. First it will check for the symbol to be resolved in the strong
symbols' list, if it is not there it will then check in the weak symbol
list.
parent c2488b50
No related branches found
No related tags found
No related merge requests found
...@@ -39,6 +39,8 @@ pub struct Linker { ...@@ -39,6 +39,8 @@ pub struct Linker {
// Used by link // Used by link
/// Global symbols /// Global symbols
globals: BTreeMap<String, usize>, globals: BTreeMap<String, usize>,
/// Weak symbols
weak_syms: BTreeMap<String, usize>,
/// Loaded library in-memory data /// Loaded library in-memory data
mmaps: BTreeMap<String, &'static mut [u8]>, mmaps: BTreeMap<String, &'static mut [u8]>,
verbose: bool, verbose: bool,
...@@ -51,6 +53,7 @@ impl Linker { ...@@ -51,6 +53,7 @@ impl Linker {
library_path: library_path.to_string(), library_path: library_path.to_string(),
objects: BTreeMap::new(), objects: BTreeMap::new(),
globals: BTreeMap::new(), globals: BTreeMap::new(),
weak_syms: BTreeMap::new(),
mmaps: BTreeMap::new(), mmaps: BTreeMap::new(),
verbose, verbose,
tls_index_offset: 0, tls_index_offset: 0,
...@@ -129,21 +132,43 @@ impl Linker { ...@@ -129,21 +132,43 @@ impl Linker {
} }
} }
fn collect_syms(elf: &Elf, mmap: &[u8], verbose: bool) -> Result<BTreeMap<String, usize>> { fn collect_syms(
elf: &Elf,
mmap: &[u8],
verbose: bool,
) -> Result<(BTreeMap<String, usize>, BTreeMap<String, usize>)> {
let mut globals = BTreeMap::new(); let mut globals = BTreeMap::new();
let mut weak_syms = BTreeMap::new();
for sym in elf.dynsyms.iter() { for sym in elf.dynsyms.iter() {
if sym.st_bind() == sym::STB_GLOBAL && sym.st_value != 0 { let bind = sym.st_bind();
if let Some(name_res) = elf.dynstrtab.get(sym.st_name) { if sym.st_value == 0 || ![sym::STB_GLOBAL, sym::STB_WEAK].contains(&bind) {
let name = name_res?; continue;
let value = mmap.as_ptr() as usize + sym.st_value as usize; }
let name: String;
let value: usize;
if let Some(name_res) = elf.dynstrtab.get(sym.st_name) {
name = name_res?.to_string();
value = mmap.as_ptr() as usize + sym.st_value as usize;
} else {
continue;
}
match sym.st_bind() {
sym::STB_GLOBAL => {
if verbose { if verbose {
println!(" global {}: {:x?} = {:#x}", &name, sym, value); println!(" global {}: {:x?} = {:#x}", &name, sym, value);
} }
globals.insert(name.to_string(), value); globals.insert(name, value);
}
sym::STB_WEAK => {
if verbose {
println!(" weak {}: {:x?} = {:#x}", &name, sym, value);
}
weak_syms.insert(name, value);
} }
_ => unreachable!(),
} }
} }
return Ok(globals); return Ok((globals, weak_syms));
} }
pub fn get_sym(&self, name: &str) -> Option<usize> { pub fn get_sym(&self, name: &str) -> Option<usize> {
...@@ -152,6 +177,11 @@ impl Linker { ...@@ -152,6 +177,11 @@ impl Linker {
println!(" sym {} = {:#x}", name, value); println!(" sym {} = {:#x}", name, value);
} }
Some(*value) Some(*value)
} else if let Some(value) = self.weak_syms.get(name) {
if self.verbose {
println!(" sym {} = {:#x}", name, value);
}
Some(*value)
} else { } else {
if self.verbose { if self.verbose {
println!(" sym {} = undefined", name); println!(" sym {} = undefined", name);
...@@ -252,8 +282,9 @@ impl Linker { ...@@ -252,8 +282,9 @@ impl Linker {
if self.verbose { if self.verbose {
println!(" mmap {:p}, {:#x}", mmap.as_mut_ptr(), mmap.len()); println!(" mmap {:p}, {:#x}", mmap.as_mut_ptr(), mmap.len());
} }
let globals = Linker::collect_syms(&elf, &mmap, self.verbose)?; let (globals, weak_syms) = Linker::collect_syms(&elf, &mmap, self.verbose)?;
self.globals.extend(globals.into_iter()); self.globals.extend(globals.into_iter());
self.weak_syms.extend(weak_syms.into_iter());
self.mmaps.insert(elf_name.to_string(), mmap); self.mmaps.insert(elf_name.to_string(), mmap);
} }
......
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