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 | /// For each section, call `f` once with a shared reference. |
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. |
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 | |