1 | /// Whether the format of a compilation unit is 32- or 64-bit. |
2 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
3 | pub enum Format { |
4 | /// 64-bit DWARF |
5 | Dwarf64 = 8, |
6 | /// 32-bit DWARF |
7 | Dwarf32 = 4, |
8 | } |
9 | |
10 | impl Format { |
11 | /// Return the serialized size of an initial length field for the format. |
12 | #[inline ] |
13 | pub fn initial_length_size(self) -> u8 { |
14 | match self { |
15 | Format::Dwarf32 => 4, |
16 | Format::Dwarf64 => 12, |
17 | } |
18 | } |
19 | |
20 | /// Return the natural word size for the format |
21 | #[inline ] |
22 | pub fn word_size(self) -> u8 { |
23 | match self { |
24 | Format::Dwarf32 => 4, |
25 | Format::Dwarf64 => 8, |
26 | } |
27 | } |
28 | } |
29 | |
30 | /// Which vendor extensions to support. |
31 | #[derive(Clone, Copy, Debug, PartialEq, Eq)] |
32 | #[non_exhaustive ] |
33 | pub enum Vendor { |
34 | /// A default set of extensions, including some common GNU extensions. |
35 | Default, |
36 | /// AAarch64 extensions. |
37 | AArch64, |
38 | } |
39 | |
40 | /// Encoding parameters that are commonly used for multiple DWARF sections. |
41 | /// |
42 | /// This is intended to be small enough to pass by value. |
43 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
44 | // `address_size` and `format` are used more often than `version`, so keep |
45 | // them first. |
46 | #[repr (C)] |
47 | pub struct Encoding { |
48 | /// The size of an address. |
49 | pub address_size: u8, |
50 | |
51 | // The size of a segment selector. |
52 | // TODO: pub segment_size: u8, |
53 | /// Whether the DWARF format is 32- or 64-bit. |
54 | pub format: Format, |
55 | |
56 | /// The DWARF version of the header. |
57 | pub version: u16, |
58 | } |
59 | |
60 | /// Encoding parameters for a line number program. |
61 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
62 | pub struct LineEncoding { |
63 | /// The size in bytes of the smallest target machine instruction. |
64 | pub minimum_instruction_length: u8, |
65 | |
66 | /// The maximum number of individual operations that may be encoded in an |
67 | /// instruction. |
68 | pub maximum_operations_per_instruction: u8, |
69 | |
70 | /// The initial value of the `is_stmt` register. |
71 | pub default_is_stmt: bool, |
72 | |
73 | /// The minimum value which a special opcode can add to the line register. |
74 | pub line_base: i8, |
75 | |
76 | /// The range of values which a special opcode can add to the line register. |
77 | pub line_range: u8, |
78 | } |
79 | |
80 | impl Default for LineEncoding { |
81 | fn default() -> Self { |
82 | // Values from LLVM. |
83 | LineEncoding { |
84 | minimum_instruction_length: 1, |
85 | maximum_operations_per_instruction: 1, |
86 | default_is_stmt: true, |
87 | line_base: -5, |
88 | line_range: 14, |
89 | } |
90 | } |
91 | } |
92 | |
93 | /// A DWARF register number. |
94 | /// |
95 | /// The meaning of this value is ABI dependent. This is generally encoded as |
96 | /// a ULEB128, but supported architectures need 16 bits at most. |
97 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] |
98 | pub struct Register(pub u16); |
99 | |
100 | /// An offset into the `.debug_abbrev` section. |
101 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
102 | pub struct DebugAbbrevOffset<T = usize>(pub T); |
103 | |
104 | /// An offset to a set of entries in the `.debug_addr` section. |
105 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
106 | pub struct DebugAddrBase<T = usize>(pub T); |
107 | |
108 | /// An index into a set of addresses in the `.debug_addr` section. |
109 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
110 | pub struct DebugAddrIndex<T = usize>(pub T); |
111 | |
112 | /// An offset into the `.debug_aranges` section. |
113 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
114 | pub struct DebugArangesOffset<T = usize>(pub T); |
115 | |
116 | /// An offset into the `.debug_info` section. |
117 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Hash)] |
118 | pub struct DebugInfoOffset<T = usize>(pub T); |
119 | |
120 | /// An offset into the `.debug_line` section. |
121 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
122 | pub struct DebugLineOffset<T = usize>(pub T); |
123 | |
124 | /// An offset into the `.debug_line_str` section. |
125 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
126 | pub struct DebugLineStrOffset<T = usize>(pub T); |
127 | |
128 | /// An offset into either the `.debug_loc` section or the `.debug_loclists` section, |
129 | /// depending on the version of the unit the offset was contained in. |
130 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
131 | pub struct LocationListsOffset<T = usize>(pub T); |
132 | |
133 | /// An offset to a set of location list offsets in the `.debug_loclists` section. |
134 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
135 | pub struct DebugLocListsBase<T = usize>(pub T); |
136 | |
137 | /// An index into a set of location list offsets in the `.debug_loclists` section. |
138 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
139 | pub struct DebugLocListsIndex<T = usize>(pub T); |
140 | |
141 | /// An offset into the `.debug_macinfo` section. |
142 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
143 | pub struct DebugMacinfoOffset<T = usize>(pub T); |
144 | |
145 | /// An offset into the `.debug_macro` section. |
146 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
147 | pub struct DebugMacroOffset<T = usize>(pub T); |
148 | |
149 | /// An offset into either the `.debug_ranges` section or the `.debug_rnglists` section, |
150 | /// depending on the version of the unit the offset was contained in. |
151 | /// |
152 | /// If this is from a DWARF 4 DWO file, then it must additionally be offset by the |
153 | /// value of `DW_AT_GNU_ranges_base`. You can use `Dwarf::ranges_offset_from_raw` to do this. |
154 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
155 | pub struct RawRangeListsOffset<T = usize>(pub T); |
156 | |
157 | /// An offset into either the `.debug_ranges` section or the `.debug_rnglists` section, |
158 | /// depending on the version of the unit the offset was contained in. |
159 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
160 | pub struct RangeListsOffset<T = usize>(pub T); |
161 | |
162 | /// An offset to a set of range list offsets in the `.debug_rnglists` section. |
163 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
164 | pub struct DebugRngListsBase<T = usize>(pub T); |
165 | |
166 | /// An index into a set of range list offsets in the `.debug_rnglists` section. |
167 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
168 | pub struct DebugRngListsIndex<T = usize>(pub T); |
169 | |
170 | /// An offset into the `.debug_str` section. |
171 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
172 | pub struct DebugStrOffset<T = usize>(pub T); |
173 | |
174 | /// An offset to a set of entries in the `.debug_str_offsets` section. |
175 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
176 | pub struct DebugStrOffsetsBase<T = usize>(pub T); |
177 | |
178 | /// An index into a set of entries in the `.debug_str_offsets` section. |
179 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
180 | pub struct DebugStrOffsetsIndex<T = usize>(pub T); |
181 | |
182 | /// An offset into the `.debug_types` section. |
183 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Hash)] |
184 | pub struct DebugTypesOffset<T = usize>(pub T); |
185 | |
186 | /// A type signature as used in the `.debug_types` section. |
187 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
188 | pub struct DebugTypeSignature(pub u64); |
189 | |
190 | /// An offset into the `.debug_frame` section. |
191 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
192 | pub struct DebugFrameOffset<T = usize>(pub T); |
193 | |
194 | impl<T> From<T> for DebugFrameOffset<T> { |
195 | #[inline ] |
196 | fn from(o: T) -> Self { |
197 | DebugFrameOffset(o) |
198 | } |
199 | } |
200 | |
201 | /// An offset into the `.eh_frame` section. |
202 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
203 | pub struct EhFrameOffset<T = usize>(pub T); |
204 | |
205 | impl<T> From<T> for EhFrameOffset<T> { |
206 | #[inline ] |
207 | fn from(o: T) -> Self { |
208 | EhFrameOffset(o) |
209 | } |
210 | } |
211 | |
212 | /// An offset into the `.debug_info` or `.debug_types` sections. |
213 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Hash)] |
214 | pub enum UnitSectionOffset<T = usize> { |
215 | /// An offset into the `.debug_info` section. |
216 | DebugInfoOffset(DebugInfoOffset<T>), |
217 | /// An offset into the `.debug_types` section. |
218 | DebugTypesOffset(DebugTypesOffset<T>), |
219 | } |
220 | |
221 | impl<T> From<DebugInfoOffset<T>> for UnitSectionOffset<T> { |
222 | fn from(offset: DebugInfoOffset<T>) -> Self { |
223 | UnitSectionOffset::DebugInfoOffset(offset) |
224 | } |
225 | } |
226 | |
227 | impl<T> From<DebugTypesOffset<T>> for UnitSectionOffset<T> { |
228 | fn from(offset: DebugTypesOffset<T>) -> Self { |
229 | UnitSectionOffset::DebugTypesOffset(offset) |
230 | } |
231 | } |
232 | |
233 | impl<T> UnitSectionOffset<T> |
234 | where |
235 | T: Clone, |
236 | { |
237 | /// Returns the `DebugInfoOffset` inside, or `None` otherwise. |
238 | pub fn as_debug_info_offset(&self) -> Option<DebugInfoOffset<T>> { |
239 | match self { |
240 | UnitSectionOffset::DebugInfoOffset(offset: &DebugInfoOffset) => Some(offset.clone()), |
241 | UnitSectionOffset::DebugTypesOffset(_) => None, |
242 | } |
243 | } |
244 | /// Returns the `DebugTypesOffset` inside, or `None` otherwise. |
245 | pub fn as_debug_types_offset(&self) -> Option<DebugTypesOffset<T>> { |
246 | match self { |
247 | UnitSectionOffset::DebugInfoOffset(_) => None, |
248 | UnitSectionOffset::DebugTypesOffset(offset: &DebugTypesOffset) => Some(offset.clone()), |
249 | } |
250 | } |
251 | } |
252 | |
253 | /// An identifier for a DWARF section. |
254 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Hash)] |
255 | pub enum SectionId { |
256 | /// The `.debug_abbrev` section. |
257 | DebugAbbrev, |
258 | /// The `.debug_addr` section. |
259 | DebugAddr, |
260 | /// The `.debug_aranges` section. |
261 | DebugAranges, |
262 | /// The `.debug_cu_index` section. |
263 | DebugCuIndex, |
264 | /// The `.debug_frame` section. |
265 | DebugFrame, |
266 | /// The `.eh_frame` section. |
267 | EhFrame, |
268 | /// The `.eh_frame_hdr` section. |
269 | EhFrameHdr, |
270 | /// The `.debug_info` section. |
271 | DebugInfo, |
272 | /// The `.debug_line` section. |
273 | DebugLine, |
274 | /// The `.debug_line_str` section. |
275 | DebugLineStr, |
276 | /// The `.debug_loc` section. |
277 | DebugLoc, |
278 | /// The `.debug_loclists` section. |
279 | DebugLocLists, |
280 | /// The `.debug_macinfo` section. |
281 | DebugMacinfo, |
282 | /// The `.debug_macro` section. |
283 | DebugMacro, |
284 | /// The `.debug_pubnames` section. |
285 | DebugPubNames, |
286 | /// The `.debug_pubtypes` section. |
287 | DebugPubTypes, |
288 | /// The `.debug_ranges` section. |
289 | DebugRanges, |
290 | /// The `.debug_rnglists` section. |
291 | DebugRngLists, |
292 | /// The `.debug_str` section. |
293 | DebugStr, |
294 | /// The `.debug_str_offsets` section. |
295 | DebugStrOffsets, |
296 | /// The `.debug_tu_index` section. |
297 | DebugTuIndex, |
298 | /// The `.debug_types` section. |
299 | DebugTypes, |
300 | } |
301 | |
302 | impl SectionId { |
303 | /// Returns the ELF section name for this kind. |
304 | pub fn name(self) -> &'static str { |
305 | match self { |
306 | SectionId::DebugAbbrev => ".debug_abbrev" , |
307 | SectionId::DebugAddr => ".debug_addr" , |
308 | SectionId::DebugAranges => ".debug_aranges" , |
309 | SectionId::DebugCuIndex => ".debug_cu_index" , |
310 | SectionId::DebugFrame => ".debug_frame" , |
311 | SectionId::EhFrame => ".eh_frame" , |
312 | SectionId::EhFrameHdr => ".eh_frame_hdr" , |
313 | SectionId::DebugInfo => ".debug_info" , |
314 | SectionId::DebugLine => ".debug_line" , |
315 | SectionId::DebugLineStr => ".debug_line_str" , |
316 | SectionId::DebugLoc => ".debug_loc" , |
317 | SectionId::DebugLocLists => ".debug_loclists" , |
318 | SectionId::DebugMacinfo => ".debug_macinfo" , |
319 | SectionId::DebugMacro => ".debug_macro" , |
320 | SectionId::DebugPubNames => ".debug_pubnames" , |
321 | SectionId::DebugPubTypes => ".debug_pubtypes" , |
322 | SectionId::DebugRanges => ".debug_ranges" , |
323 | SectionId::DebugRngLists => ".debug_rnglists" , |
324 | SectionId::DebugStr => ".debug_str" , |
325 | SectionId::DebugStrOffsets => ".debug_str_offsets" , |
326 | SectionId::DebugTuIndex => ".debug_tu_index" , |
327 | SectionId::DebugTypes => ".debug_types" , |
328 | } |
329 | } |
330 | |
331 | /// Returns the ELF section name for this kind, when found in a .dwo or .dwp file. |
332 | pub fn dwo_name(self) -> Option<&'static str> { |
333 | Some(match self { |
334 | SectionId::DebugAbbrev => ".debug_abbrev.dwo" , |
335 | SectionId::DebugCuIndex => ".debug_cu_index" , |
336 | SectionId::DebugInfo => ".debug_info.dwo" , |
337 | SectionId::DebugLine => ".debug_line.dwo" , |
338 | // The debug_loc section can be present in the dwo when using the |
339 | // GNU split-dwarf extension to DWARF4. |
340 | SectionId::DebugLoc => ".debug_loc.dwo" , |
341 | SectionId::DebugLocLists => ".debug_loclists.dwo" , |
342 | SectionId::DebugMacro => ".debug_macro.dwo" , |
343 | SectionId::DebugRngLists => ".debug_rnglists.dwo" , |
344 | SectionId::DebugStr => ".debug_str.dwo" , |
345 | SectionId::DebugStrOffsets => ".debug_str_offsets.dwo" , |
346 | SectionId::DebugTuIndex => ".debug_tu_index" , |
347 | SectionId::DebugTypes => ".debug_types.dwo" , |
348 | _ => return None, |
349 | }) |
350 | } |
351 | |
352 | /// Returns the XCOFF section name for this kind. |
353 | pub fn xcoff_name(self) -> Option<&'static str> { |
354 | Some(match self { |
355 | SectionId::DebugAbbrev => ".dwabrev" , |
356 | SectionId::DebugAranges => ".dwarnge" , |
357 | SectionId::DebugFrame => ".dwframe" , |
358 | SectionId::DebugInfo => ".dwinfo" , |
359 | SectionId::DebugLine => ".dwline" , |
360 | SectionId::DebugLoc => ".dwloc" , |
361 | SectionId::DebugMacinfo => ".dwmac" , |
362 | SectionId::DebugPubNames => ".dwpbnms" , |
363 | SectionId::DebugPubTypes => ".dwpbtyp" , |
364 | SectionId::DebugRanges => ".dwrnges" , |
365 | SectionId::DebugStr => ".dwstr" , |
366 | _ => return None, |
367 | }) |
368 | } |
369 | } |
370 | |
371 | /// An optionally-provided implementation-defined compilation unit ID to enable |
372 | /// split DWARF and linking a split compilation unit back together. |
373 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
374 | pub struct DwoId(pub u64); |
375 | |
376 | /// The "type" of file with DWARF debugging information. This determines, among other things, |
377 | /// which files DWARF sections should be loaded from. |
378 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
379 | pub enum DwarfFileType { |
380 | /// A normal executable or object file. |
381 | Main, |
382 | /// A .dwo split DWARF file. |
383 | Dwo, |
384 | // TODO: Supplementary files, .dwps? |
385 | } |
386 | |
387 | impl Default for DwarfFileType { |
388 | fn default() -> Self { |
389 | DwarfFileType::Main |
390 | } |
391 | } |
392 | |