| 1 | use std::ops::DerefMut; |
| 2 | use std::result; |
| 3 | use std::vec::Vec; |
| 4 | |
| 5 | use crate::common::SectionId; |
| 6 | use crate::write::{ |
| 7 | DebugAbbrev, DebugFrame, DebugInfo, DebugInfoReference, DebugLine, DebugLineStr, DebugLoc, |
| 8 | DebugLocLists, DebugRanges, DebugRngLists, DebugStr, EhFrame, Writer, |
| 9 | }; |
| 10 | |
| 11 | macro_rules! define_section { |
| 12 | ($name:ident, $offset:ident, $docs:expr) => { |
| 13 | #[doc=$docs] |
| 14 | #[derive(Debug, Default)] |
| 15 | pub struct $name<W: Writer>(pub W); |
| 16 | |
| 17 | impl<W: Writer> $name<W> { |
| 18 | /// Return the offset of the next write. |
| 19 | pub fn offset(&self) -> $offset { |
| 20 | $offset(self.len()) |
| 21 | } |
| 22 | } |
| 23 | |
| 24 | impl<W: Writer> From<W> for $name<W> { |
| 25 | #[inline] |
| 26 | fn from(w: W) -> Self { |
| 27 | $name(w) |
| 28 | } |
| 29 | } |
| 30 | |
| 31 | impl<W: Writer> Deref for $name<W> { |
| 32 | type Target = W; |
| 33 | |
| 34 | #[inline] |
| 35 | fn deref(&self) -> &W { |
| 36 | &self.0 |
| 37 | } |
| 38 | } |
| 39 | |
| 40 | impl<W: Writer> DerefMut for $name<W> { |
| 41 | #[inline] |
| 42 | fn deref_mut(&mut self) -> &mut W { |
| 43 | &mut self.0 |
| 44 | } |
| 45 | } |
| 46 | |
| 47 | impl<W: Writer> Section<W> for $name<W> { |
| 48 | #[inline] |
| 49 | fn id(&self) -> SectionId { |
| 50 | SectionId::$name |
| 51 | } |
| 52 | } |
| 53 | }; |
| 54 | } |
| 55 | |
| 56 | /// Functionality common to all writable DWARF sections. |
| 57 | pub trait Section<W: Writer>: DerefMut<Target = W> { |
| 58 | /// Returns the DWARF section kind for this type. |
| 59 | fn id(&self) -> SectionId; |
| 60 | |
| 61 | /// Returns the ELF section name for this type. |
| 62 | fn name(&self) -> &'static str { |
| 63 | self.id().name() |
| 64 | } |
| 65 | } |
| 66 | |
| 67 | /// All of the writable DWARF sections. |
| 68 | #[derive (Debug, Default)] |
| 69 | pub struct Sections<W: Writer> { |
| 70 | /// The `.debug_abbrev` section. |
| 71 | pub debug_abbrev: DebugAbbrev<W>, |
| 72 | /// The `.debug_info` section. |
| 73 | pub debug_info: DebugInfo<W>, |
| 74 | /// The `.debug_line` section. |
| 75 | pub debug_line: DebugLine<W>, |
| 76 | /// The `.debug_line_str` section. |
| 77 | pub debug_line_str: DebugLineStr<W>, |
| 78 | /// The `.debug_ranges` section. |
| 79 | pub debug_ranges: DebugRanges<W>, |
| 80 | /// The `.debug_rnglists` section. |
| 81 | pub debug_rnglists: DebugRngLists<W>, |
| 82 | /// The `.debug_loc` section. |
| 83 | pub debug_loc: DebugLoc<W>, |
| 84 | /// The `.debug_loclists` section. |
| 85 | pub debug_loclists: DebugLocLists<W>, |
| 86 | /// The `.debug_str` section. |
| 87 | pub debug_str: DebugStr<W>, |
| 88 | /// The `.debug_frame` section. |
| 89 | pub debug_frame: DebugFrame<W>, |
| 90 | /// The `.eh_frame` section. |
| 91 | pub eh_frame: EhFrame<W>, |
| 92 | /// Unresolved references in the `.debug_info` section. |
| 93 | pub(crate) debug_info_refs: Vec<DebugInfoReference>, |
| 94 | /// Unresolved references in the `.debug_loc` section. |
| 95 | pub(crate) debug_loc_refs: Vec<DebugInfoReference>, |
| 96 | /// Unresolved references in the `.debug_loclists` section. |
| 97 | pub(crate) debug_loclists_refs: Vec<DebugInfoReference>, |
| 98 | } |
| 99 | |
| 100 | impl<W: Writer + Clone> Sections<W> { |
| 101 | /// Create a new `Sections` using clones of the given `section`. |
| 102 | pub fn new(section: W) -> Self { |
| 103 | Sections { |
| 104 | debug_abbrev: DebugAbbrev(section.clone()), |
| 105 | debug_info: DebugInfo(section.clone()), |
| 106 | debug_line: DebugLine(section.clone()), |
| 107 | debug_line_str: DebugLineStr(section.clone()), |
| 108 | debug_ranges: DebugRanges(section.clone()), |
| 109 | debug_rnglists: DebugRngLists(section.clone()), |
| 110 | debug_loc: DebugLoc(section.clone()), |
| 111 | debug_loclists: DebugLocLists(section.clone()), |
| 112 | debug_str: DebugStr(section.clone()), |
| 113 | debug_frame: DebugFrame(section.clone()), |
| 114 | eh_frame: EhFrame(section), |
| 115 | debug_info_refs: Vec::new(), |
| 116 | debug_loc_refs: Vec::new(), |
| 117 | debug_loclists_refs: Vec::new(), |
| 118 | } |
| 119 | } |
| 120 | } |
| 121 | |
| 122 | impl<W: Writer> Sections<W> { |
| 123 | /// Get the section with the given `id`. |
| 124 | pub fn get(&self, id: SectionId) -> Option<&W> { |
| 125 | match id { |
| 126 | SectionId::DebugAbbrev => Some(&self.debug_abbrev.0), |
| 127 | SectionId::DebugInfo => Some(&self.debug_info.0), |
| 128 | SectionId::DebugLine => Some(&self.debug_line.0), |
| 129 | SectionId::DebugLineStr => Some(&self.debug_line_str.0), |
| 130 | SectionId::DebugRanges => Some(&self.debug_ranges.0), |
| 131 | SectionId::DebugRngLists => Some(&self.debug_rnglists.0), |
| 132 | SectionId::DebugLoc => Some(&self.debug_loc.0), |
| 133 | SectionId::DebugLocLists => Some(&self.debug_loclists.0), |
| 134 | SectionId::DebugStr => Some(&self.debug_str.0), |
| 135 | SectionId::DebugFrame => Some(&self.debug_frame.0), |
| 136 | SectionId::EhFrame => Some(&self.eh_frame.0), |
| 137 | _ => None, |
| 138 | } |
| 139 | } |
| 140 | |
| 141 | /// Get the section with the given `id`. |
| 142 | pub fn get_mut(&mut self, id: SectionId) -> Option<&mut W> { |
| 143 | match id { |
| 144 | SectionId::DebugAbbrev => Some(&mut self.debug_abbrev.0), |
| 145 | SectionId::DebugInfo => Some(&mut self.debug_info.0), |
| 146 | SectionId::DebugLine => Some(&mut self.debug_line.0), |
| 147 | SectionId::DebugLineStr => Some(&mut self.debug_line_str.0), |
| 148 | SectionId::DebugRanges => Some(&mut self.debug_ranges.0), |
| 149 | SectionId::DebugRngLists => Some(&mut self.debug_rnglists.0), |
| 150 | SectionId::DebugLoc => Some(&mut self.debug_loc.0), |
| 151 | SectionId::DebugLocLists => Some(&mut self.debug_loclists.0), |
| 152 | SectionId::DebugStr => Some(&mut self.debug_str.0), |
| 153 | SectionId::DebugFrame => Some(&mut self.debug_frame.0), |
| 154 | SectionId::EhFrame => Some(&mut self.eh_frame.0), |
| 155 | _ => None, |
| 156 | } |
| 157 | } |
| 158 | |
| 159 | /// For each section, call `f` once with a shared reference. |
| 160 | pub fn for_each<'a, F, E>(&'a self, mut f: F) -> result::Result<(), E> |
| 161 | where |
| 162 | F: FnMut(SectionId, &'a W) -> result::Result<(), E>, |
| 163 | { |
| 164 | macro_rules! f { |
| 165 | ($s:expr) => { |
| 166 | f($s.id(), &$s) |
| 167 | }; |
| 168 | } |
| 169 | // Ordered so that earlier sections do not reference later sections. |
| 170 | f!(self.debug_abbrev)?; |
| 171 | f!(self.debug_str)?; |
| 172 | f!(self.debug_line_str)?; |
| 173 | f!(self.debug_line)?; |
| 174 | f!(self.debug_ranges)?; |
| 175 | f!(self.debug_rnglists)?; |
| 176 | f!(self.debug_loc)?; |
| 177 | f!(self.debug_loclists)?; |
| 178 | f!(self.debug_info)?; |
| 179 | f!(self.debug_frame)?; |
| 180 | f!(self.eh_frame)?; |
| 181 | Ok(()) |
| 182 | } |
| 183 | |
| 184 | /// For each section, call `f` once with a mutable reference. |
| 185 | pub fn for_each_mut<'a, F, E>(&'a mut self, mut f: F) -> result::Result<(), E> |
| 186 | where |
| 187 | F: FnMut(SectionId, &'a mut W) -> result::Result<(), E>, |
| 188 | { |
| 189 | macro_rules! f { |
| 190 | ($s:expr) => { |
| 191 | f($s.id(), &mut $s) |
| 192 | }; |
| 193 | } |
| 194 | // Ordered so that earlier sections do not reference later sections. |
| 195 | f!(self.debug_abbrev)?; |
| 196 | f!(self.debug_str)?; |
| 197 | f!(self.debug_line_str)?; |
| 198 | f!(self.debug_line)?; |
| 199 | f!(self.debug_ranges)?; |
| 200 | f!(self.debug_rnglists)?; |
| 201 | f!(self.debug_loc)?; |
| 202 | f!(self.debug_loclists)?; |
| 203 | f!(self.debug_info)?; |
| 204 | f!(self.debug_frame)?; |
| 205 | f!(self.eh_frame)?; |
| 206 | Ok(()) |
| 207 | } |
| 208 | } |
| 209 | |
| 210 | #[cfg (test)] |
| 211 | #[cfg (feature = "read" )] |
| 212 | mod tests { |
| 213 | use super::*; |
| 214 | use crate::{read, write::EndianVec, Endianity}; |
| 215 | |
| 216 | impl<E: Endianity> Sections<EndianVec<E>> { |
| 217 | pub(crate) fn read(&self, endian: E) -> read::Dwarf<read::EndianSlice<'_, E>> { |
| 218 | read::Dwarf::load(|section_id| -> read::Result<_> { |
| 219 | Ok(read::EndianSlice::new( |
| 220 | self.get(section_id).map(|w| w.slice()).unwrap_or_default(), |
| 221 | endian, |
| 222 | )) |
| 223 | }) |
| 224 | .unwrap() |
| 225 | } |
| 226 | } |
| 227 | } |
| 228 | |