[go: up one dir, main page]

gimli/
common.rs

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