Merge branch 'weak-symbols' into 'master'

Weak symbols

See merge request redox-os/relibc!260
This commit is contained in:
Jeremy Soller
2020-03-19 17:56:22 +00:00
5 changed files with 96 additions and 43 deletions
+3 -3
View File
@@ -108,9 +108,9 @@ pub unsafe extern "C" fn dlsym(handle: *mut c_void, symbol: *const c_char) -> *m
eprintln!("dlsym: linker_ptr: {:p}", tcb.linker_ptr);
let linker = (&*tcb.linker_ptr).lock();
if let Some(global) = linker.globals.get(symbol_str) {
eprintln!("dlsym({:p}, {}) = 0x{:x}", handle, symbol_str, *global);
*global as *mut c_void
if let Some(global) = linker.get_sym(symbol_str) {
eprintln!("dlsym({:p}, {}) = 0x{:x}", handle, symbol_str, global);
global as *mut c_void
} else {
eprintln!("dlsym: symbol not found");
ERROR.store(ERROR_NOT_SUPPORTED.as_ptr() as usize, Ordering::SeqCst);
+2 -1
View File
@@ -5,7 +5,8 @@ use core::{convert::TryFrom, mem, ptr, slice};
use crate::{
c_str::CStr,
header::{
errno, fcntl, limits, stdlib::getenv, sys_ioctl, sys_time, sys_utsname, termios, time::timespec,
errno, fcntl, limits, stdlib::getenv, sys_ioctl, sys_time, sys_utsname, termios,
time::timespec,
},
platform::{self, types::*, Pal, Sys},
};
+89 -33
View File
@@ -38,7 +38,9 @@ pub struct Linker {
// Used by link
/// Global symbols
pub globals: BTreeMap<String, usize>,
globals: BTreeMap<String, usize>,
/// Weak symbols
weak_syms: BTreeMap<String, usize>,
/// Loaded library in-memory data
mmaps: BTreeMap<String, &'static mut [u8]>,
verbose: bool,
@@ -51,6 +53,7 @@ impl Linker {
library_path: library_path.to_string(),
objects: BTreeMap::new(),
globals: BTreeMap::new(),
weak_syms: BTreeMap::new(),
mmaps: BTreeMap::new(),
verbose,
tls_index_offset: 0,
@@ -129,6 +132,64 @@ impl Linker {
}
}
fn collect_syms(
elf: &Elf,
mmap: &[u8],
verbose: bool,
) -> Result<(BTreeMap<String, usize>, BTreeMap<String, usize>)> {
let mut globals = BTreeMap::new();
let mut weak_syms = BTreeMap::new();
for sym in elf.dynsyms.iter() {
let bind = sym.st_bind();
if sym.st_value == 0 || ![sym::STB_GLOBAL, sym::STB_WEAK].contains(&bind) {
continue;
}
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 {
println!(" global {}: {:x?} = {:#x}", &name, sym, 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, weak_syms));
}
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
}
}
pub fn link(&mut self, primary_opt: Option<&str>) -> Result<Option<usize>> {
let elfs = {
let mut elfs = BTreeMap::new();
@@ -179,7 +240,7 @@ impl Linker {
}
}
program_header::PT_TLS => {
if self.verbose{
if self.verbose {
println!(" load tls {:#x}: {:x?}", vsize, ph);
}
tls_size += vsize;
@@ -221,18 +282,9 @@ impl Linker {
if self.verbose {
println!(" mmap {:p}, {:#x}", mmap.as_mut_ptr(), mmap.len());
}
// Locate all globals
for sym in elf.dynsyms.iter() {
if sym.st_bind() == sym::STB_GLOBAL && sym.st_value != 0 {
if let Some(name_res) = elf.dynstrtab.get(sym.st_name) {
let name = name_res?;
let value = mmap.as_ptr() as usize + sym.st_value as usize;
// println!(" global {}: {:x?} = {:#x}", name, sym, value);
self.globals.insert(name.to_string(), value);
}
}
}
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);
}
@@ -242,7 +294,7 @@ impl Linker {
} else {
None
};
if self.verbose{
if self.verbose {
println!("tcb {:x?}", tcb_opt);
}
// Copy data
@@ -331,14 +383,20 @@ impl Linker {
);
}
if Some(*elf_name) == primary_opt {
tls_ranges.insert(elf_name.to_string(), (self.tls_index_offset, tcb_master.range()));
tls_ranges.insert(
elf_name.to_string(),
(self.tls_index_offset, tcb_master.range()),
);
tcb_masters[0] = tcb_master;
} else {
tcb_master.offset -= tls_offset;
tls_offset += vsize;
tls_ranges.insert(
elf_name.to_string(),
(self.tls_index_offset + tcb_masters.len(), tcb_master.range()),
(
self.tls_index_offset + tcb_masters.len(),
tcb_master.range(),
),
);
tcb_masters.push(tcb_master);
}
@@ -360,10 +418,6 @@ impl Linker {
// Perform relocations, and protect pages
for (elf_name, elf) in elfs.iter() {
let mmap = match self.mmaps.get_mut(*elf_name) {
Some(some) => some,
None => continue,
};
if self.verbose {
println!("link {}", elf_name);
}
@@ -379,10 +433,6 @@ impl Linker {
// rel
// );
let a = rel.r_addend.unwrap_or(0) as usize;
let b = mmap.as_mut_ptr() as usize;
let s = if rel.r_sym > 0 {
let sym = elf.dynsyms.get(rel.r_sym).ok_or(Error::Malformed(format!(
"missing symbol for relocation {:?}",
@@ -396,18 +446,20 @@ impl Linker {
"missing name for symbol {:?}",
sym
)))??;
if let Some(value) = self.globals.get(name) {
// println!(" sym {}: {:x?} = {:#x}", name, sym, value);
*value
} else {
// println!(" sym {}: {:x?} = undefined", name, sym);
0
}
self.get_sym(name).unwrap_or(0)
} else {
0
};
let a = rel.r_addend.unwrap_or(0) as usize;
let mmap = match self.mmaps.get_mut(*elf_name) {
Some(some) => some,
None => continue,
};
let b = mmap.as_mut_ptr() as usize;
let (tm, t) = if let Some((tls_index, tls_range)) = tls_ranges.get(*elf_name) {
(*tls_index, tls_range.start)
} else {
@@ -473,6 +525,10 @@ impl Linker {
prot |= sys_mman::PROT_WRITE;
}
let mmap = match self.mmaps.get_mut(*elf_name) {
Some(some) => some,
None => continue,
};
let res = unsafe {
let ptr = mmap.as_mut_ptr().add(vaddr);
if self.verbose {
+1 -5
View File
@@ -2,11 +2,7 @@ use alloc::boxed::Box;
use core::{mem, ops::Range, ptr, slice};
use goblin::error::{Error, Result};
use crate::{
header::sys_mman,
ld_so::linker::Linker,
sync::mutex::Mutex,
};
use crate::{header::sys_mman, ld_so::linker::Linker, sync::mutex::Mutex};
use super::PAGE_SIZE;
+1 -1
View File
@@ -215,7 +215,7 @@ impl PalSocket for Sys {
*error = 0;
return 0;
},
}
_ => (),
},
_ => (),