Rust · 2725 bytes Raw Blame History
1 use std::collections::HashMap;
2
3 use crate::resolve::{DylibId, SymbolId};
4
5 pub const STUB_SIZE: u32 = 12;
6 pub const LAZY_POINTER_SIZE: u32 = 8;
7 pub const STUB_HELPER_HEADER_SIZE: u32 = 24;
8 pub const STUB_HELPER_ENTRY_SIZE: u32 = 12;
9 pub const DYLD_PRIVATE_SIZE: u32 = 8;
10
11 #[derive(Debug, Clone, PartialEq, Eq, Default)]
12 pub struct StubsSection {
13 pub entries: Vec<StubEntry>,
14 pub index: HashMap<SymbolId, usize>,
15 }
16
17 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
18 pub struct StubEntry {
19 pub symbol: SymbolId,
20 pub dylib: DylibId,
21 pub weak_import: bool,
22 }
23
24 impl StubsSection {
25 pub fn intern(&mut self, symbol: SymbolId, dylib: DylibId, weak_import: bool) -> usize {
26 if let Some(&idx) = self.index.get(&symbol) {
27 return idx;
28 }
29 let idx = self.entries.len();
30 self.entries.push(StubEntry {
31 symbol,
32 dylib,
33 weak_import,
34 });
35 self.index.insert(symbol, idx);
36 idx
37 }
38
39 pub fn get(&self, symbol: SymbolId) -> Option<(usize, &StubEntry)> {
40 let idx = *self.index.get(&symbol)?;
41 Some((idx, &self.entries[idx]))
42 }
43 }
44
45 #[derive(Debug, Clone, PartialEq, Eq, Default)]
46 pub struct LazyPointerSection {
47 pub entries: Vec<LazyPointerEntry>,
48 pub index: HashMap<SymbolId, usize>,
49 }
50
51 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
52 pub struct LazyPointerEntry {
53 pub symbol: SymbolId,
54 pub dylib: DylibId,
55 pub weak_import: bool,
56 }
57
58 impl LazyPointerSection {
59 pub fn intern(&mut self, symbol: SymbolId, dylib: DylibId, weak_import: bool) -> usize {
60 if let Some(&idx) = self.index.get(&symbol) {
61 return idx;
62 }
63 let idx = self.entries.len();
64 self.entries.push(LazyPointerEntry {
65 symbol,
66 dylib,
67 weak_import,
68 });
69 self.index.insert(symbol, idx);
70 idx
71 }
72
73 pub fn get(&self, symbol: SymbolId) -> Option<(usize, &LazyPointerEntry)> {
74 let idx = *self.index.get(&symbol)?;
75 Some((idx, &self.entries[idx]))
76 }
77 }
78
79 #[cfg(test)]
80 mod tests {
81 use super::*;
82
83 #[test]
84 fn stubs_and_lazy_pointers_share_symbol_dedup() {
85 let mut stubs = StubsSection::default();
86 let mut lazy = LazyPointerSection::default();
87
88 let a = stubs.intern(SymbolId(3), DylibId(1), false);
89 let b = stubs.intern(SymbolId(3), DylibId(1), true);
90 let c = lazy.intern(SymbolId(3), DylibId(1), false);
91 let d = lazy.intern(SymbolId(4), DylibId(2), true);
92
93 assert_eq!(a, 0);
94 assert_eq!(b, 0);
95 assert_eq!(c, 0);
96 assert_eq!(d, 1);
97 assert_eq!(stubs.entries.len(), 1);
98 assert_eq!(lazy.entries.len(), 2);
99 }
100 }
101