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
9#[cfg(test)]
10mod tests;
11
12pub mod eh;
13
14use core::mem;
15
16pub struct DwarfReader {
17 pub ptr: *const u8,
18}
19
20#[repr(C, packed)]
21struct Unaligned<T>(T);
22
23impl DwarfReader {
24 pub fn new(ptr: *const u8) -> DwarfReader {
25 DwarfReader { ptr }
26 }
27
28 // DWARF streams are packed, so e.g., a u32 would not necessarily be aligned
29 // on a 4-byte boundary. This may cause problems on platforms with strict
30 // alignment requirements. By wrapping data in a "packed" struct, we are
31 // telling the backend to generate "misalignment-safe" code.
32 pub unsafe fn read<T: Copy>(&mut self) -> T {
33 let Unaligned(result) = *(self.ptr as *const Unaligned<T>);
34 self.ptr = self.ptr.add(mem::size_of::<T>());
35 result
36 }
37
38 // ULEB128 and SLEB128 encodings are defined in Section 7.6 - "Variable
39 // Length Data".
40 pub unsafe fn read_uleb128(&mut self) -> u64 {
41 let mut shift: usize = 0;
42 let mut result: u64 = 0;
43 let mut byte: u8;
44 loop {
45 byte = self.read::<u8>();
46 result |= ((byte & 0x7F) as u64) << shift;
47 shift += 7;
48 if byte & 0x80 == 0 {
49 break;
50 }
51 }
52 result
53 }
54
55 pub unsafe fn read_sleb128(&mut self) -> i64 {
56 let mut shift: u32 = 0;
57 let mut result: u64 = 0;
58 let mut byte: u8;
59 loop {
60 byte = self.read::<u8>();
61 result |= ((byte & 0x7F) as u64) << shift;
62 shift += 7;
63 if byte & 0x80 == 0 {
64 break;
65 }
66 }
67 // sign-extend
68 if shift < u64::BITS && (byte & 0x40) != 0 {
69 result |= (!0 as u64) << shift;
70 }
71 result as i64
72 }
73}
74