1use std::ops::DerefMut;
2use std::result;
3use std::vec::Vec;
4
5use crate::common::SectionId;
6use crate::write::{
7 DebugAbbrev, DebugFrame, DebugInfo, DebugInfoReference, DebugLine, DebugLineStr, DebugLoc,
8 DebugLocLists, DebugRanges, DebugRngLists, DebugStr, EhFrame, Writer,
9};
10
11macro_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.
57pub 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)]
69pub 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
100impl<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
122impl<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")]
212mod 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