1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
/// Reusable configuration for relocating one raw image at a time.
///
/// A `Relocator` stores the stable relocation policy, currently the lazy PLT
/// binder. Attach a raw image with [`Relocator::run`] to create a
/// [`RelocatorRun`](crate::RelocatorRun); the run then owns per-image state such
/// as the raw object, observer, and symbol scope.
///
/// Use `Relocator` directly when the caller already knows which modules should
/// be visible. Use [`Linker`](crate::Linker) when dependencies should be
/// discovered from `DT_NEEDED` entries before relocation.
///
/// # Example
///
/// ```rust,no_run
/// use elf_loader::{
/// Loader, Relocator, Result,
/// image::{SyntheticModule, SyntheticSymbol},
/// };
///
/// extern "C" fn host_log(_value: i32) {}
///
/// fn main() -> Result<()> {
/// let host = SyntheticModule::new(
/// "__host",
/// [SyntheticSymbol::function("host_log", host_log as *const ())],
/// );
///
/// let raw = Loader::new().load_dylib("plugin.so")?;
/// let loaded = Relocator::new()
/// .run(raw)
/// .scope([host])
/// .relocate()?;
///
/// let run = unsafe {
/// loaded
/// .get::<extern "C" fn()>("run")
/// .expect("symbol `run` not found")
/// };
/// run();
/// Ok(())
/// }
/// ```