Merge branch 'patch5' into 'master'
fix(ld.so): properly do copy relocations See merge request redox-os/relibc!604
This commit is contained in:
Generated
+27
-1
@@ -1,6 +1,6 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
@@ -243,6 +243,16 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.22"
|
||||
@@ -511,6 +521,7 @@ dependencies = [
|
||||
"scrypt",
|
||||
"sha-crypt",
|
||||
"sha2",
|
||||
"spin",
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
@@ -529,6 +540,12 @@ version = "0.2.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "010e18bd3bfd1d45a7e666b236c78720df0d9a7698ebaa9c1c559961eb60a38b"
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||
|
||||
[[package]]
|
||||
name = "scroll"
|
||||
version = "0.11.0"
|
||||
@@ -594,6 +611,15 @@ version = "0.3.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d"
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.9.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
|
||||
dependencies = [
|
||||
"lock_api",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "subtle"
|
||||
version = "2.6.1"
|
||||
|
||||
@@ -50,6 +50,7 @@ chrono-tz = {version = "0.10", default-features = false}
|
||||
chrono = {version = "0.4", default-features = false, features = ["alloc"]}
|
||||
libm = "0.2"
|
||||
object = { version = "0.36.7", git = "https://gitlab.redox-os.org/andypython/object", default-features = false, features = ["elf", "read_core"] }
|
||||
spin = "0.9.8"
|
||||
|
||||
[dependencies.dlmalloc]
|
||||
path = "dlmalloc-rs"
|
||||
|
||||
@@ -13,7 +13,7 @@ use core::{
|
||||
use crate::{
|
||||
c_str::CStr,
|
||||
ld_so::{
|
||||
linker::{DlError, ObjectHandle, ObjectScope, Resolve},
|
||||
linker::{DlError, ObjectHandle, Resolve, ScopeKind},
|
||||
tcb::Tcb,
|
||||
},
|
||||
platform::types::*,
|
||||
@@ -67,9 +67,9 @@ pub unsafe extern "C" fn dlopen(cfilename: *const c_char, flags: c_int) -> *mut
|
||||
};
|
||||
|
||||
let scope = if flags & RTLD_GLOBAL == RTLD_GLOBAL {
|
||||
ObjectScope::Global
|
||||
ScopeKind::Global
|
||||
} else {
|
||||
ObjectScope::Local
|
||||
ScopeKind::Local
|
||||
};
|
||||
|
||||
let noload = flags & RTLD_NOLOAD == RTLD_NOLOAD;
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
use super::linker::{Linker, ObjectHandle, ObjectScope, Resolve, Result};
|
||||
use super::linker::{Linker, ObjectHandle, Resolve, Result, ScopeKind};
|
||||
use crate::platform::types::c_void;
|
||||
use alloc::boxed::Box;
|
||||
|
||||
pub struct LinkerCallbacks {
|
||||
pub unload: Box<dyn Fn(&mut Linker, ObjectHandle)>,
|
||||
pub load_library:
|
||||
Box<dyn Fn(&mut Linker, Option<&str>, Resolve, ObjectScope, bool) -> Result<ObjectHandle>>,
|
||||
Box<dyn Fn(&mut Linker, Option<&str>, Resolve, ScopeKind, bool) -> Result<ObjectHandle>>,
|
||||
pub get_sym: Box<dyn Fn(&Linker, Option<ObjectHandle>, &str) -> Option<*mut c_void>>,
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ fn load_library(
|
||||
linker: &mut Linker,
|
||||
name: Option<&str>,
|
||||
resolve: Resolve,
|
||||
scope: ObjectScope,
|
||||
scope: ScopeKind,
|
||||
noload: bool,
|
||||
) -> Result<ObjectHandle> {
|
||||
linker.load_library(name, resolve, scope, noload)
|
||||
|
||||
+41
-19
@@ -21,7 +21,6 @@ use crate::{
|
||||
platform::{types::c_void, Pal, Sys},
|
||||
};
|
||||
use alloc::{
|
||||
collections::BTreeMap,
|
||||
string::{String, ToString},
|
||||
sync::Arc,
|
||||
vec::Vec,
|
||||
@@ -235,14 +234,12 @@ pub struct DSO {
|
||||
pub entry_point: usize,
|
||||
/// Loaded library in-memory data
|
||||
pub mmap: &'static [u8],
|
||||
pub global_syms: BTreeMap<String, Symbol>,
|
||||
pub weak_syms: BTreeMap<String, Symbol>,
|
||||
pub tls_module_id: usize,
|
||||
pub tls_offset: usize,
|
||||
|
||||
pub(super) dynamic: Dynamic<'static>,
|
||||
|
||||
pub scope: Scope,
|
||||
pub scope: spin::Once<Scope>,
|
||||
/// Position Independent Executable.
|
||||
pub pie: bool,
|
||||
}
|
||||
@@ -281,8 +278,6 @@ impl DSO {
|
||||
dlopened,
|
||||
entry_point,
|
||||
mmap,
|
||||
global_syms: BTreeMap::new(),
|
||||
weak_syms: BTreeMap::new(),
|
||||
tls_module_id: if tcb_master.is_some() {
|
||||
tls_module_id
|
||||
} else {
|
||||
@@ -292,12 +287,17 @@ impl DSO {
|
||||
|
||||
pie: is_pie_enabled(&elf),
|
||||
dynamic,
|
||||
scope: Scope::local(),
|
||||
scope: spin::Once::new(),
|
||||
};
|
||||
|
||||
Ok((dso, tcb_master, elf.elf_program_headers().to_vec()))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn scope(&self) -> &Scope {
|
||||
self.scope.get().expect("scope not initialized")
|
||||
}
|
||||
|
||||
/// Global Offset Table
|
||||
#[inline]
|
||||
pub fn got(&self) -> Option<NonNull<usize>> {
|
||||
@@ -314,7 +314,7 @@ impl DSO {
|
||||
&self.dynamic.needed
|
||||
}
|
||||
|
||||
pub fn get_sym(&self, name: &str) -> Option<(Symbol, SymbolBinding)> {
|
||||
pub fn get_sym<'a>(&self, name: &'a str) -> Option<(Symbol<'a>, SymbolBinding)> {
|
||||
let (_, sym) = self.dynamic.hash_table.find(
|
||||
name,
|
||||
None,
|
||||
@@ -329,6 +329,7 @@ impl DSO {
|
||||
|
||||
Some((
|
||||
Symbol {
|
||||
name,
|
||||
base: if self.pie {
|
||||
self.mmap.as_ptr() as usize
|
||||
} else {
|
||||
@@ -658,7 +659,7 @@ impl DSO {
|
||||
let dynstrtab = StringTable::new(
|
||||
&*mmap,
|
||||
strtab_offset as u64,
|
||||
strtab_offset as u64 + strtab_size as u64,
|
||||
strtab_offset as u64 + strtab_size,
|
||||
);
|
||||
|
||||
let get_str = |entry: &Dyn| {
|
||||
@@ -725,18 +726,27 @@ impl DSO {
|
||||
fn static_relocate(&self, global_scope: &Scope, reloc: Relocation) -> object::Result<()> {
|
||||
let b = self.mmap.as_ptr() as usize;
|
||||
|
||||
let sym = if reloc.sym.0 > 0 {
|
||||
let (sym, my_sym) = if reloc.sym.0 > 0 {
|
||||
let name = self.dynamic.symbol_name(reloc.sym).unwrap();
|
||||
|
||||
resolve_sym(name, &[global_scope, &self.scope])
|
||||
.map(|(sym, _, obj)| (sym, obj.tls_offset))
|
||||
let lookup_scopes = [global_scope, self.scope()];
|
||||
let sym = if reloc.kind == elf::R_X86_64_COPY {
|
||||
lookup_scopes
|
||||
.iter()
|
||||
.find_map(|scope| scope._get_sym(name, 1))
|
||||
} else {
|
||||
resolve_sym(name, &lookup_scopes)
|
||||
}
|
||||
.map(|(sym, _, obj)| (sym, obj));
|
||||
|
||||
(sym, self.dynamic.symbol(reloc.sym))
|
||||
} else {
|
||||
None
|
||||
(None, None)
|
||||
};
|
||||
|
||||
let (s, t) = sym
|
||||
.as_ref()
|
||||
.map(|(sym, t)| (sym.as_ptr() as usize, *t))
|
||||
.map(|(sym, obj)| (sym.as_ptr() as usize, obj.tls_offset))
|
||||
.unwrap_or((0, 0));
|
||||
|
||||
let a = reloc.addend;
|
||||
@@ -777,9 +787,18 @@ impl DSO {
|
||||
set_u64(f());
|
||||
},
|
||||
elf::R_X86_64_COPY => unsafe {
|
||||
let (sym, _) = sym
|
||||
let (sym, obj) = sym
|
||||
.as_ref()
|
||||
.expect("R_X86_64_COPY called without valid symbol");
|
||||
let my_sym = my_sym.expect("R_X86_64_COPY called without valid symbol");
|
||||
assert!(
|
||||
sym.size == my_sym.st_size(NativeEndian) as usize,
|
||||
"R_X86_64_COPY failed: I was trying to use the symbol {} from {} for {} but they had different sizes. Please consider relinking.",
|
||||
sym.name,
|
||||
obj.name,
|
||||
self.name
|
||||
);
|
||||
// SAFETY: Both the source and destination have the same size.
|
||||
ptr::copy_nonoverlapping(sym.as_ptr() as *const u8, ptr, sym.size);
|
||||
},
|
||||
_ => unimplemented!("relocation type {:#x}", reloc.kind),
|
||||
@@ -834,9 +853,9 @@ impl DSO {
|
||||
(elf::R_X86_64_JUMP_SLOT, Resolve::Now) => {
|
||||
let name = self.dynamic.symbol_name(reloc.sym).unwrap();
|
||||
|
||||
let resolved = resolve_sym(name, &[global_scope, &self.scope])
|
||||
let resolved = resolve_sym(name, &[global_scope, self.scope()])
|
||||
.map(|(sym, _, _)| sym.as_ptr() as usize)
|
||||
.expect("unresolved symbol");
|
||||
.unwrap_or_else(|| panic!("unresolved symbol: {name}"));
|
||||
|
||||
unsafe {
|
||||
*ptr = resolved + reloc.addend;
|
||||
@@ -862,7 +881,7 @@ impl DSO {
|
||||
if entry & 1 == 0 {
|
||||
// An even entry sets up `addr` for subsequent odd entries.
|
||||
unsafe {
|
||||
addr = base.add(entry as usize) as *mut usize;
|
||||
addr = base.add(entry) as *mut usize;
|
||||
*addr += base as usize;
|
||||
addr = addr.add(1);
|
||||
}
|
||||
@@ -950,6 +969,9 @@ fn dirname(path: &str) -> String {
|
||||
parts.join("/")
|
||||
}
|
||||
|
||||
pub fn resolve_sym(name: &str, scopes: &[&Scope]) -> Option<(Symbol, SymbolBinding, Arc<DSO>)> {
|
||||
pub fn resolve_sym<'a>(
|
||||
name: &'a str,
|
||||
scopes: &[&'a Scope],
|
||||
) -> Option<(Symbol<'a>, SymbolBinding, Arc<DSO>)> {
|
||||
scopes.iter().find_map(|scope| scope.get_sym(name))
|
||||
}
|
||||
|
||||
+111
-43
@@ -121,16 +121,17 @@ impl Drop for MmapFile {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct Symbol {
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Symbol<'a> {
|
||||
pub name: &'a str,
|
||||
pub value: usize,
|
||||
pub base: usize,
|
||||
pub size: usize,
|
||||
pub sym_type: u8,
|
||||
}
|
||||
|
||||
impl Symbol {
|
||||
pub fn as_ptr(self) -> *mut c_void {
|
||||
impl Symbol<'_> {
|
||||
pub fn as_ptr(&self) -> *mut c_void {
|
||||
(self.base + self.value) as *mut c_void
|
||||
}
|
||||
}
|
||||
@@ -147,15 +148,16 @@ pub enum Resolve {
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub enum ObjectScope {
|
||||
pub enum ScopeKind {
|
||||
Global,
|
||||
Local,
|
||||
}
|
||||
|
||||
pub enum Scope {
|
||||
Global {
|
||||
objs: Vec<Weak<DSO>>,
|
||||
},
|
||||
/// The global scope initially contains the main program and all of its
|
||||
/// dependencies. Additional objects will be added to this scope via
|
||||
/// `dlopen(2)` if the `RTLD_GLOBAL` flag is set.
|
||||
Global { objs: Vec<Weak<DSO>> },
|
||||
Local {
|
||||
owner: Option<Weak<DSO>>,
|
||||
objs: Vec<Arc<DSO>>,
|
||||
@@ -169,7 +171,7 @@ impl Scope {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(super) const fn local() -> Self {
|
||||
const fn local() -> Self {
|
||||
Self::Local {
|
||||
owner: None,
|
||||
objs: Vec::new(),
|
||||
@@ -211,7 +213,18 @@ impl Scope {
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn get_sym(&self, name: &str) -> Option<(Symbol, SymbolBinding, Arc<DSO>)> {
|
||||
pub(super) fn get_sym<'a>(
|
||||
&self,
|
||||
name: &'a str,
|
||||
) -> Option<(Symbol<'a>, SymbolBinding, Arc<DSO>)> {
|
||||
self._get_sym(name, 0)
|
||||
}
|
||||
|
||||
pub(super) fn _get_sym<'a>(
|
||||
&self,
|
||||
name: &'a str,
|
||||
skip: usize,
|
||||
) -> Option<(Symbol<'a>, SymbolBinding, Arc<DSO>)> {
|
||||
let mut res = None;
|
||||
|
||||
let get_sym = |obj: Arc<DSO>| {
|
||||
@@ -227,7 +240,11 @@ impl Scope {
|
||||
};
|
||||
|
||||
match self {
|
||||
Self::Global { objs } => objs.iter().map(|o| o.upgrade().unwrap()).find_map(get_sym),
|
||||
Self::Global { objs } => objs
|
||||
.iter()
|
||||
.skip(skip)
|
||||
.map(|o| o.upgrade().unwrap())
|
||||
.find_map(get_sym),
|
||||
Self::Local { owner, objs } => {
|
||||
let owner = owner
|
||||
.as_ref()
|
||||
@@ -237,16 +254,17 @@ impl Scope {
|
||||
|
||||
core::iter::once(owner)
|
||||
.chain(objs.iter().cloned())
|
||||
.skip(skip)
|
||||
.find_map(get_sym)
|
||||
}
|
||||
}
|
||||
.or(res)
|
||||
}
|
||||
|
||||
fn move_into(&self, other: &mut Self) {
|
||||
// FIXME: move not copy? as afiak u cannot downgrade from a global to a local scope.
|
||||
fn copy_into(&self, other: &mut Self) {
|
||||
match (self, other) {
|
||||
(Self::Local { owner, objs }, Self::Global { objs: other_objs }) => {
|
||||
// FIXME: may have duplicates
|
||||
let owner = owner.as_ref().expect("local scope without owner");
|
||||
other_objs.push(owner.clone());
|
||||
other_objs.extend(objs.iter().map(Arc::downgrade));
|
||||
@@ -255,6 +273,28 @@ impl Scope {
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn debug(&self) {
|
||||
match self {
|
||||
Self::Global { objs } => {
|
||||
println!(
|
||||
"[@global] {:?}",
|
||||
objs.iter()
|
||||
.map(|x| x.upgrade().unwrap().name.clone())
|
||||
.collect::<Vec<_>>()
|
||||
);
|
||||
}
|
||||
|
||||
Self::Local { owner, objs } => {
|
||||
let owner = owner.as_ref().unwrap().upgrade().unwrap();
|
||||
println!(
|
||||
"[{}] {:?}",
|
||||
owner.name,
|
||||
objs.iter().map(|x| x.name.clone()).collect::<Vec<_>>()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Used by dlfcn.h
|
||||
@@ -383,7 +423,7 @@ impl Linker {
|
||||
} else {
|
||||
Resolve::default()
|
||||
},
|
||||
ObjectScope::Global,
|
||||
ScopeKind::Global,
|
||||
)?;
|
||||
Ok(dso.entry_point)
|
||||
}
|
||||
@@ -392,7 +432,7 @@ impl Linker {
|
||||
&mut self,
|
||||
name: Option<&str>,
|
||||
resolve: Resolve,
|
||||
scope: ObjectScope,
|
||||
scope: ScopeKind,
|
||||
noload: bool,
|
||||
) -> Result<ObjectHandle> {
|
||||
trace!(
|
||||
@@ -413,17 +453,18 @@ impl Linker {
|
||||
match name {
|
||||
Some(name) => {
|
||||
if let Some(id) = self.name_to_object_id_map.get(name) {
|
||||
let obj = self.objects.get_mut(id).unwrap();
|
||||
let obj = self.objects.get(id).unwrap();
|
||||
|
||||
// We may be upgrading the object from a local scope to the
|
||||
// global scope.
|
||||
if scope == ObjectScope::Global {
|
||||
if scope == ScopeKind::Global {
|
||||
if self.config.debug_flags.contains(DebugFlags::SCOPES) {
|
||||
eprintln!("[ld.so]: moving {} into the global scope", obj.name);
|
||||
}
|
||||
|
||||
let mut global_scope = GLOBAL_SCOPE.write();
|
||||
obj.scope.move_into(&mut global_scope);
|
||||
obj.scope().copy_into(&mut global_scope);
|
||||
self.scope_debug();
|
||||
}
|
||||
|
||||
Ok(ObjectHandle::new(obj.clone()))
|
||||
@@ -466,7 +507,7 @@ impl Linker {
|
||||
let guard;
|
||||
|
||||
if let Some(handle) = handle.as_ref() {
|
||||
&handle.as_ref().scope
|
||||
handle.as_ref().scope()
|
||||
} else {
|
||||
guard = GLOBAL_SCOPE.read();
|
||||
&guard
|
||||
@@ -541,7 +582,7 @@ impl Linker {
|
||||
base_addr: Option<usize>,
|
||||
dlopened: bool,
|
||||
resolve: Resolve,
|
||||
scope: ObjectScope,
|
||||
scope: ScopeKind,
|
||||
) -> Result<Arc<DSO>> {
|
||||
let resolve = if cfg!(target_arch = "x86_64") {
|
||||
resolve
|
||||
@@ -666,9 +707,11 @@ impl Linker {
|
||||
}
|
||||
}
|
||||
|
||||
// new_objects is already reversed.
|
||||
for (i, obj) in new_objects.into_iter().enumerate() {
|
||||
for (i, obj) in new_objects.iter().enumerate() {
|
||||
obj.relocate(&objects_data[i], resolve).unwrap();
|
||||
}
|
||||
|
||||
for obj in new_objects.into_iter() {
|
||||
self.run_init(&obj);
|
||||
self.register_object(obj);
|
||||
}
|
||||
@@ -684,6 +727,19 @@ impl Linker {
|
||||
self.objects.insert(obj.id, obj);
|
||||
}
|
||||
|
||||
/// Loads the specified object and all of its dependencies.
|
||||
///
|
||||
/// `new_objects` contains any new objects that were loaded. Order is
|
||||
/// reverse of how the scope is populated.
|
||||
///
|
||||
/// The scope is populated such that the loaded objects are in breadth-first
|
||||
/// order. This means that first the requested object is added to the scope,
|
||||
/// and then its dependencies are added in the order of their respective
|
||||
/// `DT_NEEDED` entries in the requested object. This is done recursively
|
||||
/// until all dependencies have been loaded.
|
||||
///
|
||||
/// If a dependency has already been loaded, it is *not* added to the scope
|
||||
/// nor to `new_objects`.
|
||||
fn load_objects_recursive<'a>(
|
||||
&mut self,
|
||||
name: &str,
|
||||
@@ -693,9 +749,9 @@ impl Linker {
|
||||
new_objects: &mut Vec<Arc<DSO>>,
|
||||
objects_data: &mut Vec<Vec<ProgramHeader>>,
|
||||
tcb_masters: &mut Vec<Master>,
|
||||
// The object that caused this object to be loaded.
|
||||
dependent: Option<&mut DSO>,
|
||||
scope: ObjectScope,
|
||||
// Scope of the object that caused this object to be loaded.
|
||||
dependent_scope: Option<&mut Scope>,
|
||||
scope_kind: ScopeKind,
|
||||
) -> Result<Arc<DSO>> {
|
||||
// fixme: double lookup slow
|
||||
if let Some(id) = self.name_to_object_id_map.get(name) {
|
||||
@@ -711,7 +767,7 @@ impl Linker {
|
||||
let path = self.search_object(name, parent_runpath)?;
|
||||
let file = self.read_file(&path)?;
|
||||
let data = file.data();
|
||||
let (mut obj, tcb_master, elf) = DSO::new(
|
||||
let (obj, tcb_master, elf) = DSO::new(
|
||||
&path,
|
||||
data,
|
||||
base_addr,
|
||||
@@ -754,6 +810,18 @@ impl Linker {
|
||||
.map(|dep| dep.to_string())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let obj = Arc::new(obj);
|
||||
let mut scope = Scope::local();
|
||||
|
||||
if let Some(dependent_scope) = dependent_scope {
|
||||
match scope_kind {
|
||||
ScopeKind::Local => dependent_scope.add(&obj),
|
||||
ScopeKind::Global => GLOBAL_SCOPE.write().add(&obj),
|
||||
}
|
||||
} else if let ScopeKind::Global = scope_kind {
|
||||
GLOBAL_SCOPE.write().add(&obj);
|
||||
}
|
||||
|
||||
for dep_name in dependencies.iter() {
|
||||
self.load_objects_recursive(
|
||||
dep_name,
|
||||
@@ -763,28 +831,17 @@ impl Linker {
|
||||
new_objects,
|
||||
objects_data,
|
||||
tcb_masters,
|
||||
Some(&mut obj),
|
||||
scope,
|
||||
Some(&mut scope),
|
||||
scope_kind,
|
||||
)?;
|
||||
}
|
||||
|
||||
let obj = Arc::new_cyclic(|sref| {
|
||||
obj.scope.set_owner(sref.clone());
|
||||
obj
|
||||
});
|
||||
|
||||
if let Some(dependent) = dependent {
|
||||
match scope {
|
||||
ObjectScope::Local => dependent.scope.add(&obj),
|
||||
ObjectScope::Global => GLOBAL_SCOPE.write().add(&obj),
|
||||
}
|
||||
} else if let ObjectScope::Global = scope {
|
||||
GLOBAL_SCOPE.write().add(&obj);
|
||||
}
|
||||
|
||||
objects_data.push(elf);
|
||||
new_objects.push(obj.clone());
|
||||
|
||||
scope.set_owner(Arc::downgrade(&obj));
|
||||
obj.scope.call_once(|| scope);
|
||||
|
||||
Ok(obj)
|
||||
}
|
||||
|
||||
@@ -867,6 +924,17 @@ impl Linker {
|
||||
|
||||
obj.run_init();
|
||||
}
|
||||
|
||||
fn scope_debug(&self) {
|
||||
if self.config.debug_flags.contains(DebugFlags::SCOPES) {
|
||||
println!("[ld.so]: =========== SCOPES ==========");
|
||||
GLOBAL_SCOPE.read().debug();
|
||||
for obj in self.objects.values() {
|
||||
obj.scope().debug();
|
||||
}
|
||||
println!("[ld.so]: ==============================");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// GOT[1] = object_id
|
||||
@@ -901,7 +969,7 @@ extern "C" fn __plt_resolve_inner(obj: *const DSO, relocation_index: c_uint) ->
|
||||
)
|
||||
.expect("non utf8 symbol name");
|
||||
|
||||
let resolved = resolve_sym(name, &[&GLOBAL_SCOPE.read(), &obj.scope])
|
||||
let resolved = resolve_sym(name, &[&GLOBAL_SCOPE.read(), obj.scope()])
|
||||
.map(|(sym, _, _)| sym)
|
||||
.unwrap_or_else(|| panic!("symbol '{name}' not found"))
|
||||
.as_ptr();
|
||||
|
||||
Reference in New Issue
Block a user