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 | |