1//! Utilities for parsing DWARF-encoded data streams.
2//! See <http://www.dwarfstd.org>,
3//! DWARF-4 standard, Section 7 - "Data Representation"
4
5// This module is used only by x86_64-pc-windows-gnu for now, but we
6// are compiling it everywhere to avoid regressions.
7#![allow(unused)]
8#![forbid(unsafe_op_in_unsafe_fn)]
9
10#[cfg(test)]
11mod tests;
12
13pub mod eh;
14
15pub struct DwarfReader {
16 pub ptr: *const u8,
17}
18
19impl DwarfReader {
20 pub fn new(ptr: *const u8) -> DwarfReader {
21 DwarfReader { ptr }
22 }
23
24 /// Read a type T and then bump the pointer by that amount.
25 ///
26 /// DWARF streams are "packed", so all types must be read at align 1.
27 pub unsafe fn read<T: Copy>(&mut self) -> T {
28 unsafe {
29 let result = self.ptr.cast::<T>().read_unaligned();
30 self.ptr = self.ptr.byte_add(size_of::<T>());
31 result
32 }
33 }
34
35 /// ULEB128 and SLEB128 encodings are defined in Section 7.6 - "Variable Length Data".
36 pub unsafe fn read_uleb128(&mut self) -> u64 {
37 let mut shift: usize = 0;
38 let mut result: u64 = 0;
39 let mut byte: u8;
40 loop {
41 byte = unsafe { self.read::<u8>() };
42 result |= ((byte & 0x7F) as u64) << shift;
43 shift += 7;
44 if byte & 0x80 == 0 {
45 break;
46 }
47 }
48 result
49 }
50
51 pub unsafe fn read_sleb128(&mut self) -> i64 {
52 let mut shift: u32 = 0;
53 let mut result: u64 = 0;
54 let mut byte: u8;
55 loop {
56 byte = unsafe { self.read::<u8>() };
57 result |= ((byte & 0x7F) as u64) << shift;
58 shift += 7;
59 if byte & 0x80 == 0 {
60 break;
61 }
62 }
63 // sign-extend
64 if shift < u64::BITS && (byte & 0x40) != 0 {
65 result |= (!0 as u64) << shift;
66 }
67 result as i64
68 }
69}
70