wasmtime_cranelift/debug/transform/
refs.rs1use gimli::write;
4use gimli::{DebugInfoOffset, Reader, UnitHeader, UnitOffset};
5use std::collections::HashMap;
6
7pub struct PendingUnitRefs {
10 refs: Vec<(write::UnitEntryId, gimli::DwAt, UnitOffset)>,
11}
12
13impl PendingUnitRefs {
14 pub fn new() -> Self {
15 Self { refs: Vec::new() }
16 }
17 pub fn insert(&mut self, entry_id: write::UnitEntryId, attr: gimli::DwAt, offset: UnitOffset) {
18 self.refs.push((entry_id, attr, offset));
19 }
20}
21
22pub struct PendingDebugInfoRefs {
25 refs: Vec<(write::UnitEntryId, gimli::DwAt, DebugInfoOffset)>,
26}
27
28impl PendingDebugInfoRefs {
29 pub fn new() -> Self {
30 Self { refs: Vec::new() }
31 }
32 pub fn insert(
33 &mut self,
34 entry_id: write::UnitEntryId,
35 attr: gimli::DwAt,
36 offset: DebugInfoOffset,
37 ) {
38 self.refs.push((entry_id, attr, offset));
39 }
40}
41
42pub struct UnitRefsMap {
45 map: HashMap<UnitOffset, write::UnitEntryId>,
46}
47
48impl UnitRefsMap {
49 pub fn new() -> Self {
50 Self {
51 map: HashMap::new(),
52 }
53 }
54 pub fn insert(&mut self, offset: UnitOffset, entry_id: write::UnitEntryId) {
55 self.map.insert(offset, entry_id);
56 }
57 pub fn patch(&self, refs: PendingUnitRefs, comp_unit: &mut write::Unit) {
58 for (die_id, attr_name, offset) in refs.refs {
59 let die = comp_unit.get_mut(die_id);
60 if let Some(unit_id) = self.map.get(&offset) {
61 die.set(attr_name, write::AttributeValue::UnitRef(*unit_id));
62 }
63 }
64 }
65}
66
67pub struct DebugInfoRefsMap {
70 map: HashMap<DebugInfoOffset, (write::UnitId, write::UnitEntryId)>,
71}
72
73impl DebugInfoRefsMap {
74 pub fn new() -> Self {
75 Self {
76 map: HashMap::new(),
77 }
78 }
79 pub fn insert<R>(&mut self, unit: &UnitHeader<R>, unit_id: write::UnitId, unit_map: UnitRefsMap)
80 where
81 R: Reader<Offset = usize>,
82 {
83 self.map
84 .extend(unit_map.map.into_iter().map(|(off, entry_id)| {
85 let off = off
86 .to_debug_info_offset(unit)
87 .expect("should be in debug_info section");
88 (off, (unit_id, entry_id))
89 }));
90 }
91 pub fn patch(
92 &self,
93 refs: impl Iterator<Item = (write::UnitId, PendingDebugInfoRefs)>,
94 units: &mut write::UnitTable,
95 ) {
96 for (id, refs) in refs {
97 let unit = units.get_mut(id);
98 for (die_id, attr_name, offset) in refs.refs {
99 let die = unit.get_mut(die_id);
100 if let Some((id, entry_id)) = self.map.get(&offset) {
101 die.set(
102 attr_name,
103 write::AttributeValue::DebugInfoRef(write::Reference::Entry(
104 *id, *entry_id,
105 )),
106 );
107 }
108 }
109 }
110 }
111}