Coverage Report

Created: 2026-02-14 07:33

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/gimli-0.32.3/src/write/dwarf.rs
Line
Count
Source
1
use alloc::vec::Vec;
2
3
use crate::common::Encoding;
4
use crate::write::{
5
    AbbreviationTable, LineProgram, LineString, LineStringTable, Result, Sections, StringTable,
6
    Unit, UnitTable, Writer,
7
};
8
9
/// Writable DWARF information for more than one unit.
10
#[derive(Debug, Default)]
11
pub struct Dwarf {
12
    /// A table of units. These are primarily stored in the `.debug_info` section,
13
    /// but they also contain information that is stored in other sections.
14
    pub units: UnitTable,
15
16
    /// Extra line number programs that are not associated with a unit.
17
    ///
18
    /// These should only be used when generating DWARF5 line-only debug
19
    /// information.
20
    pub line_programs: Vec<LineProgram>,
21
22
    /// A table of strings that will be stored in the `.debug_line_str` section.
23
    pub line_strings: LineStringTable,
24
25
    /// A table of strings that will be stored in the `.debug_str` section.
26
    pub strings: StringTable,
27
}
28
29
impl Dwarf {
30
    /// Create a new `Dwarf` instance.
31
    #[inline]
32
0
    pub fn new() -> Self {
33
0
        Self::default()
34
0
    }
35
36
    /// Write the DWARF information to the given sections.
37
0
    pub fn write<W: Writer>(&mut self, sections: &mut Sections<W>) -> Result<()> {
38
0
        let line_strings = self.line_strings.write(&mut sections.debug_line_str)?;
39
0
        let strings = self.strings.write(&mut sections.debug_str)?;
40
0
        self.units.write(sections, &line_strings, &strings)?;
41
0
        for line_program in &self.line_programs {
42
0
            line_program.write(
43
0
                &mut sections.debug_line,
44
0
                line_program.encoding(),
45
0
                &line_strings,
46
0
                &strings,
47
0
            )?;
48
        }
49
0
        Ok(())
50
0
    }
51
52
    /// Get a reference to the data for a line string.
53
0
    pub fn get_line_string<'a>(&'a self, string: &'a LineString) -> &'a [u8] {
54
0
        string.get(&self.strings, &self.line_strings)
55
0
    }
56
}
57
58
/// Writable DWARF information for a single unit.
59
#[derive(Debug)]
60
pub struct DwarfUnit {
61
    /// A unit. This is primarily stored in the `.debug_info` section,
62
    /// but also contains information that is stored in other sections.
63
    pub unit: Unit,
64
65
    /// A table of strings that will be stored in the `.debug_line_str` section.
66
    pub line_strings: LineStringTable,
67
68
    /// A table of strings that will be stored in the `.debug_str` section.
69
    pub strings: StringTable,
70
}
71
72
impl DwarfUnit {
73
    /// Create a new `DwarfUnit`.
74
    ///
75
    /// Note: you should set `self.unit.line_program` after creation.
76
    /// This cannot be done earlier because it may need to reference
77
    /// `self.line_strings`.
78
0
    pub fn new(encoding: Encoding) -> Self {
79
0
        let unit = Unit::new(encoding, LineProgram::none());
80
0
        DwarfUnit {
81
0
            unit,
82
0
            line_strings: LineStringTable::default(),
83
0
            strings: StringTable::default(),
84
0
        }
85
0
    }
86
87
    /// Write the DWARf information to the given sections.
88
0
    pub fn write<W: Writer>(&mut self, sections: &mut Sections<W>) -> Result<()> {
89
0
        let line_strings = self.line_strings.write(&mut sections.debug_line_str)?;
90
0
        let strings = self.strings.write(&mut sections.debug_str)?;
91
92
0
        let abbrev_offset = sections.debug_abbrev.offset();
93
0
        let mut abbrevs = AbbreviationTable::default();
94
95
0
        self.unit.write(
96
0
            sections,
97
0
            abbrev_offset,
98
0
            &mut abbrevs,
99
0
            &line_strings,
100
0
            &strings,
101
0
        )?;
102
        // None should exist because we didn't give out any UnitId.
103
0
        assert!(sections.debug_info_refs.is_empty());
104
0
        assert!(sections.debug_loc_refs.is_empty());
105
0
        assert!(sections.debug_loclists_refs.is_empty());
106
107
0
        abbrevs.write(&mut sections.debug_abbrev)?;
108
0
        Ok(())
109
0
    }
110
111
    /// Get a reference to the data for a line string.
112
0
    pub fn get_line_string<'a>(&'a self, string: &'a LineString) -> &'a [u8] {
113
0
        string.get(&self.strings, &self.line_strings)
114
0
    }
115
}
116
117
#[cfg(feature = "read")]
118
pub(crate) mod convert {
119
    use super::*;
120
    use crate::read::{self, Reader};
121
    use crate::write::{Address, ConvertResult};
122
123
    impl Dwarf {
124
        /// Create a `write::Dwarf` by converting a `read::Dwarf`.
125
        ///
126
        /// `convert_address` is a function to convert read addresses into the `Address`
127
        /// type. For non-relocatable addresses, this function may simply return
128
        /// `Address::Constant(address)`. For relocatable addresses, it is the caller's
129
        /// responsibility to determine the symbol and addend corresponding to the address
130
        /// and return `Address::Symbol { symbol, addend }`.
131
0
        pub fn from<R: Reader<Offset = usize>>(
132
0
            dwarf: &read::Dwarf<R>,
133
0
            convert_address: &dyn Fn(u64) -> Option<Address>,
134
0
        ) -> ConvertResult<Dwarf> {
135
0
            let mut line_strings = LineStringTable::default();
136
0
            let mut strings = StringTable::default();
137
0
            let units = UnitTable::from(dwarf, &mut line_strings, &mut strings, convert_address)?;
138
            // TODO: convert the line programs that were not referenced by a unit.
139
0
            let line_programs = Vec::new();
140
0
            Ok(Dwarf {
141
0
                units,
142
0
                line_programs,
143
0
                line_strings,
144
0
                strings,
145
0
            })
146
0
        }
147
    }
148
}