Rust · 1380 bytes Raw Blame History
1 use std::collections::HashMap;
2
3 use crate::resolve::SymbolId;
4
5 #[derive(Debug, Clone, PartialEq, Eq, Default)]
6 pub struct GotSection {
7 pub entries: Vec<GotEntry>,
8 pub index: HashMap<SymbolId, usize>,
9 }
10
11 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
12 pub struct GotEntry {
13 pub symbol: SymbolId,
14 pub weak_import: bool,
15 }
16
17 impl GotSection {
18 pub fn intern(&mut self, symbol: SymbolId, weak_import: bool) -> usize {
19 if let Some(&idx) = self.index.get(&symbol) {
20 return idx;
21 }
22 let idx = self.entries.len();
23 self.entries.push(GotEntry {
24 symbol,
25 weak_import,
26 });
27 self.index.insert(symbol, idx);
28 idx
29 }
30
31 pub fn get(&self, symbol: SymbolId) -> Option<(usize, &GotEntry)> {
32 let idx = *self.index.get(&symbol)?;
33 Some((idx, &self.entries[idx]))
34 }
35 }
36
37 #[cfg(test)]
38 mod tests {
39 use super::*;
40
41 #[test]
42 fn intern_deduplicates_symbol_slots() {
43 let mut got = GotSection::default();
44 let a = got.intern(SymbolId(7), false);
45 let b = got.intern(SymbolId(7), true);
46 let c = got.intern(SymbolId(9), true);
47 assert_eq!(a, 0);
48 assert_eq!(b, 0);
49 assert_eq!(c, 1);
50 assert_eq!(got.entries.len(), 2);
51 assert!(!got.entries[0].weak_import);
52 assert!(got.entries[1].weak_import);
53 }
54 }
55