summaryrefslogtreecommitdiff
path: root/vendor/gimli/src/write/dwarf.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/gimli/src/write/dwarf.rs')
-rw-r--r--vendor/gimli/src/write/dwarf.rs138
1 files changed, 138 insertions, 0 deletions
diff --git a/vendor/gimli/src/write/dwarf.rs b/vendor/gimli/src/write/dwarf.rs
new file mode 100644
index 0000000..ea50712
--- /dev/null
+++ b/vendor/gimli/src/write/dwarf.rs
@@ -0,0 +1,138 @@
+use alloc::vec::Vec;
+
+use crate::common::Encoding;
+use crate::write::{
+ AbbreviationTable, LineProgram, LineStringTable, Result, Sections, StringTable, Unit,
+ UnitTable, Writer,
+};
+
+/// Writable DWARF information for more than one unit.
+#[derive(Debug, Default)]
+pub struct Dwarf {
+ /// A table of units. These are primarily stored in the `.debug_info` section,
+ /// but they also contain information that is stored in other sections.
+ pub units: UnitTable,
+
+ /// Extra line number programs that are not associated with a unit.
+ ///
+ /// These should only be used when generating DWARF5 line-only debug
+ /// information.
+ pub line_programs: Vec<LineProgram>,
+
+ /// A table of strings that will be stored in the `.debug_line_str` section.
+ pub line_strings: LineStringTable,
+
+ /// A table of strings that will be stored in the `.debug_str` section.
+ pub strings: StringTable,
+}
+
+impl Dwarf {
+ /// Create a new `Dwarf` instance.
+ #[inline]
+ pub fn new() -> Self {
+ Self::default()
+ }
+
+ /// Write the DWARF information to the given sections.
+ pub fn write<W: Writer>(&mut self, sections: &mut Sections<W>) -> Result<()> {
+ let line_strings = self.line_strings.write(&mut sections.debug_line_str)?;
+ let strings = self.strings.write(&mut sections.debug_str)?;
+ self.units.write(sections, &line_strings, &strings)?;
+ for line_program in &self.line_programs {
+ line_program.write(
+ &mut sections.debug_line,
+ line_program.encoding(),
+ &line_strings,
+ &strings,
+ )?;
+ }
+ Ok(())
+ }
+}
+
+/// Writable DWARF information for a single unit.
+#[derive(Debug)]
+pub struct DwarfUnit {
+ /// A unit. This is primarily stored in the `.debug_info` section,
+ /// but also contains information that is stored in other sections.
+ pub unit: Unit,
+
+ /// A table of strings that will be stored in the `.debug_line_str` section.
+ pub line_strings: LineStringTable,
+
+ /// A table of strings that will be stored in the `.debug_str` section.
+ pub strings: StringTable,
+}
+
+impl DwarfUnit {
+ /// Create a new `DwarfUnit`.
+ ///
+ /// Note: you should set `self.unit.line_program` after creation.
+ /// This cannot be done earlier because it may need to reference
+ /// `self.line_strings`.
+ pub fn new(encoding: Encoding) -> Self {
+ let unit = Unit::new(encoding, LineProgram::none());
+ DwarfUnit {
+ unit,
+ line_strings: LineStringTable::default(),
+ strings: StringTable::default(),
+ }
+ }
+
+ /// Write the DWARf information to the given sections.
+ pub fn write<W: Writer>(&mut self, sections: &mut Sections<W>) -> Result<()> {
+ let line_strings = self.line_strings.write(&mut sections.debug_line_str)?;
+ let strings = self.strings.write(&mut sections.debug_str)?;
+
+ let abbrev_offset = sections.debug_abbrev.offset();
+ let mut abbrevs = AbbreviationTable::default();
+
+ self.unit.write(
+ sections,
+ abbrev_offset,
+ &mut abbrevs,
+ &line_strings,
+ &strings,
+ )?;
+ // None should exist because we didn't give out any UnitId.
+ assert!(sections.debug_info_refs.is_empty());
+ assert!(sections.debug_loc_refs.is_empty());
+ assert!(sections.debug_loclists_refs.is_empty());
+
+ abbrevs.write(&mut sections.debug_abbrev)?;
+ Ok(())
+ }
+}
+
+#[cfg(feature = "read")]
+pub(crate) mod convert {
+ use super::*;
+ use crate::read::{self, Reader};
+ use crate::write::{Address, ConvertResult};
+
+ impl Dwarf {
+ /// Create a `write::Dwarf` by converting a `read::Dwarf`.
+ ///
+ /// `convert_address` is a function to convert read addresses into the `Address`
+ /// type. For non-relocatable addresses, this function may simply return
+ /// `Address::Constant(address)`. For relocatable addresses, it is the caller's
+ /// responsibility to determine the symbol and addend corresponding to the address
+ /// and return `Address::Symbol { symbol, addend }`.
+ pub fn from<R: Reader<Offset = usize>>(
+ dwarf: &read::Dwarf<R>,
+ convert_address: &dyn Fn(u64) -> Option<Address>,
+ ) -> ConvertResult<Dwarf> {
+ let mut line_strings = LineStringTable::default();
+ let mut strings = StringTable::default();
+ let units = UnitTable::from(dwarf, &mut line_strings, &mut strings, convert_address)?;
+ // TODO: convert the line programs that were not referenced by a unit.
+ let line_programs = Vec::new();
+ Ok(Dwarf {
+ units,
+ line_programs,
+ line_strings,
+ strings,
+ })
+ }
+ }
+}