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.
id(&self) -> SectionId59     fn id(&self) -> SectionId;
60 
61     /// Returns the ELF section name for this type.
name(&self) -> &'static str62     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`.
new(section: W) -> Self102     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.clone()),
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     /// For each section, call `f` once with a shared reference.
for_each<F, E>(&self, mut f: F) -> result::Result<(), E> where F: FnMut(SectionId, &W) -> result::Result<(), E>,124     pub fn for_each<F, E>(&self, mut f: F) -> result::Result<(), E>
125     where
126         F: FnMut(SectionId, &W) -> result::Result<(), E>,
127     {
128         macro_rules! f {
129             ($s:expr) => {
130                 f($s.id(), &$s)
131             };
132         }
133         // Ordered so that earlier sections do not reference later sections.
134         f!(self.debug_abbrev)?;
135         f!(self.debug_str)?;
136         f!(self.debug_line_str)?;
137         f!(self.debug_line)?;
138         f!(self.debug_ranges)?;
139         f!(self.debug_rnglists)?;
140         f!(self.debug_loc)?;
141         f!(self.debug_loclists)?;
142         f!(self.debug_info)?;
143         f!(self.debug_frame)?;
144         f!(self.eh_frame)?;
145         Ok(())
146     }
147 
148     /// For each section, call `f` once with a mutable reference.
for_each_mut<F, E>(&mut self, mut f: F) -> result::Result<(), E> where F: FnMut(SectionId, &mut W) -> result::Result<(), E>,149     pub fn for_each_mut<F, E>(&mut self, mut f: F) -> result::Result<(), E>
150     where
151         F: FnMut(SectionId, &mut W) -> result::Result<(), E>,
152     {
153         macro_rules! f {
154             ($s:expr) => {
155                 f($s.id(), &mut $s)
156             };
157         }
158         // Ordered so that earlier sections do not reference later sections.
159         f!(self.debug_abbrev)?;
160         f!(self.debug_str)?;
161         f!(self.debug_line_str)?;
162         f!(self.debug_line)?;
163         f!(self.debug_ranges)?;
164         f!(self.debug_rnglists)?;
165         f!(self.debug_loc)?;
166         f!(self.debug_loclists)?;
167         f!(self.debug_info)?;
168         f!(self.debug_frame)?;
169         f!(self.eh_frame)?;
170         Ok(())
171     }
172 }
173