]> git.proxmox.com Git - rustc.git/blob - vendor/gimli-0.23.0/src/write/dwarf.rs
New upstream version 1.54.0+dfsg1
[rustc.git] / vendor / gimli-0.23.0 / src / write / dwarf.rs
1 use alloc::vec::Vec;
2
3 use crate::common::Encoding;
4 use crate::write::{
5 AbbreviationTable, LineProgram, LineStringTable, Result, Sections, StringTable, Unit,
6 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 pub fn new() -> Self {
33 Self::default()
34 }
35
36 /// Write the DWARF information to the given sections.
37 pub fn write<W: Writer>(&mut self, sections: &mut Sections<W>) -> Result<()> {
38 let line_strings = self.line_strings.write(&mut sections.debug_line_str)?;
39 let strings = self.strings.write(&mut sections.debug_str)?;
40 self.units.write(sections, &line_strings, &strings)?;
41 for line_program in &self.line_programs {
42 line_program.write(
43 &mut sections.debug_line,
44 line_program.encoding(),
45 &line_strings,
46 &strings,
47 )?;
48 }
49 Ok(())
50 }
51 }
52
53 /// Writable DWARF information for a single unit.
54 #[derive(Debug)]
55 pub struct DwarfUnit {
56 /// A unit. This is primarily stored in the `.debug_info` section,
57 /// but also contains information that is stored in other sections.
58 pub unit: Unit,
59
60 /// A table of strings that will be stored in the `.debug_line_str` section.
61 pub line_strings: LineStringTable,
62
63 /// A table of strings that will be stored in the `.debug_str` section.
64 pub strings: StringTable,
65 }
66
67 impl DwarfUnit {
68 /// Create a new `DwarfUnit`.
69 ///
70 /// Note: you should set `self.unit.line_program` after creation.
71 /// This cannot be done earlier because it may need to reference
72 /// `self.line_strings`.
73 pub fn new(encoding: Encoding) -> Self {
74 let unit = Unit::new(encoding, LineProgram::none());
75 DwarfUnit {
76 unit,
77 line_strings: LineStringTable::default(),
78 strings: StringTable::default(),
79 }
80 }
81
82 /// Write the DWARf information to the given sections.
83 pub fn write<W: Writer>(&mut self, sections: &mut Sections<W>) -> Result<()> {
84 let line_strings = self.line_strings.write(&mut sections.debug_line_str)?;
85 let strings = self.strings.write(&mut sections.debug_str)?;
86
87 let abbrev_offset = sections.debug_abbrev.offset();
88 let mut abbrevs = AbbreviationTable::default();
89
90 self.unit.write(
91 sections,
92 abbrev_offset,
93 &mut abbrevs,
94 &line_strings,
95 &strings,
96 )?;
97 // None should exist because we didn't give out any UnitId.
98 assert!(sections.debug_info_refs.is_empty());
99 assert!(sections.debug_loc_refs.is_empty());
100 assert!(sections.debug_loclists_refs.is_empty());
101
102 abbrevs.write(&mut sections.debug_abbrev)?;
103 Ok(())
104 }
105 }
106
107 #[cfg(feature = "read")]
108 pub(crate) mod convert {
109 use super::*;
110 use crate::read::{self, Reader};
111 use crate::write::{Address, ConvertResult};
112
113 impl Dwarf {
114 /// Create a `write::Dwarf` by converting a `read::Dwarf`.
115 ///
116 /// `convert_address` is a function to convert read addresses into the `Address`
117 /// type. For non-relocatable addresses, this function may simply return
118 /// `Address::Constant(address)`. For relocatable addresses, it is the caller's
119 /// responsibility to determine the symbol and addend corresponding to the address
120 /// and return `Address::Symbol { symbol, addend }`.
121 pub fn from<R: Reader<Offset = usize>>(
122 dwarf: &read::Dwarf<R>,
123 convert_address: &dyn Fn(u64) -> Option<Address>,
124 ) -> ConvertResult<Dwarf> {
125 let mut line_strings = LineStringTable::default();
126 let mut strings = StringTable::default();
127 let units = UnitTable::from(dwarf, &mut line_strings, &mut strings, convert_address)?;
128 // TODO: convert the line programs that were not referenced by a unit.
129 let line_programs = Vec::new();
130 Ok(Dwarf {
131 units,
132 line_programs,
133 line_strings,
134 strings,
135 })
136 }
137 }
138 }