]>
Commit | Line | Data |
---|---|---|
f035d41b XL |
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.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. | |
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 | } |