]> git.lizzy.rs Git - rust.git/blob - src/libpanic_unwind/dwarf/mod.rs
Fix rebase fail
[rust.git] / src / libpanic_unwind / dwarf / mod.rs
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 pub mod eh;
10
11 use core::mem;
12
13 pub struct DwarfReader {
14     pub ptr: *const u8,
15 }
16
17 #[repr(C,packed)]
18 struct Unaligned<T>(T);
19
20 impl DwarfReader {
21     pub fn new(ptr: *const u8) -> DwarfReader {
22         DwarfReader { ptr }
23     }
24
25     // DWARF streams are packed, so e.g., a u32 would not necessarily be aligned
26     // on a 4-byte boundary. This may cause problems on platforms with strict
27     // alignment requirements. By wrapping data in a "packed" struct, we are
28     // telling the backend to generate "misalignment-safe" code.
29     pub unsafe fn read<T: Copy>(&mut self) -> T {
30         let Unaligned(result) = *(self.ptr as *const Unaligned<T>);
31         self.ptr = self.ptr.add(mem::size_of::<T>());
32         result
33     }
34
35     // ULEB128 and SLEB128 encodings are defined in Section 7.6 - "Variable
36     // Length Data".
37     pub unsafe fn read_uleb128(&mut self) -> u64 {
38         let mut shift: usize = 0;
39         let mut result: u64 = 0;
40         let mut byte: u8;
41         loop {
42             byte = self.read::<u8>();
43             result |= ((byte & 0x7F) as u64) << shift;
44             shift += 7;
45             if byte & 0x80 == 0 {
46                 break;
47             }
48         }
49         result
50     }
51
52     pub unsafe fn read_sleb128(&mut self) -> i64 {
53         let mut shift: usize = 0;
54         let mut result: u64 = 0;
55         let mut byte: u8;
56         loop {
57             byte = self.read::<u8>();
58             result |= ((byte & 0x7F) as u64) << shift;
59             shift += 7;
60             if byte & 0x80 == 0 {
61                 break;
62             }
63         }
64         // sign-extend
65         if shift < 8 * mem::size_of::<u64>() && (byte & 0x40) != 0 {
66             result |= (!0 as u64) << shift;
67         }
68         result as i64
69     }
70 }
71
72 #[test]
73 fn dwarf_reader() {
74     let encoded: &[u8] = &[1, 2, 3, 4, 5, 6, 7, 0xE5, 0x8E, 0x26, 0x9B, 0xF1, 0x59, 0xFF, 0xFF];
75
76     let mut reader = DwarfReader::new(encoded.as_ptr());
77
78     unsafe {
79         assert!(reader.read::<u8>() == u8::to_be(1u8));
80         assert!(reader.read::<u16>() == u16::to_be(0x0203));
81         assert!(reader.read::<u32>() == u32::to_be(0x04050607));
82
83         assert!(reader.read_uleb128() == 624485);
84         assert!(reader.read_sleb128() == -624485);
85
86         assert!(reader.read::<i8>() == i8::to_be(-1));
87     }
88 }